/* The navigation: an iPhone Dynamic Island. js/island.js morphs its surface; this draws it. */

/* THE REAL ISLAND.

   The navigation is the Dynamic Island — the black capsule at the top of an
   iPhone — and it is drawn as that object, not as the site's plate wearing
   its shape. Pure black in both themes, a full capsule at rest, a deep
   rounded panel when it opens, white type in the system face, and the
   system's own colours for the few things that are coloured: yellow for a
   kept part, blue for focus and what the site did for you, red for what did
   not work. The rest of the site keeps its own world; this object is the
   phone's, laid on top of it.

   Nothing here changes with the theme except the rim: on a light page black
   needs no edge, and on the night page a hairline is what keeps a black
   capsule from sinking into a dark ground. */
:root {
  --header-bar-h: 56px;

  --nav-ocean: #000000;        /* the island itself */
  --nav-ink: #000000;          /* ink laid on a filled control */
  --nav-paper: #ffffff;        /* type on the island */
  --nav-muted: #98989f;        /* the second line — 7.1:1 on black */
  --nav-accent: #ffffff;       /* glyphs and figures drawn on the island */
  --nav-blue: #0a84ff;         /* focus, caret, the run of the progress line */
  --nav-brass: #ffd60a;        /* a kept part, a match — the system yellow */
  --nav-brass-hover: #ffe04a;
  --nav-raise: #1c1c1e;        /* a control lifted off the black */
  --nav-raise-hover: #2c2c2e;
  --nav-raise-strong: #3a3a3c; /* the selected segment, the cursor row */
  /* The rim. On the light page there is none: black on paper is its own
     edge. On the night page a fine white line is drawn around the black —
     it is what keeps the island from sinking into a dark ground, and the
     one thing about it that says "dark" at a glance. */
  --nav-edge: #000000;
  --nav-edge-w: 1.5px;
  --nav-shadow: 0 10px 30px rgba(0, 0, 0, 0.26);
  --nav-rule: rgba(255, 255, 255, 0.1);
  --nav-edge-strong: rgba(255, 255, 255, 0.18);
  --nav-cast: rgba(0, 0, 0, 0.28);
  /* The system face. SF on Apple devices, Segoe on Windows, and the site's
     own Cairo wherever neither exists, so Arabic always has a face. */
  --nav-face: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Arabic", "Segoe UI", "Cairo", sans-serif;
  /* Capsule at rest — the radius is half the height, always. */
  --nav-radius: calc(var(--header-bar-h) / 2);
  --nav-radius-open: 32px;
}

/* Scoped to the screen for the same reason variables.css scopes its dark
   block: a printed page has no backlight. */
@media screen {
  [data-theme="dark"] {
    --nav-edge: rgba(255, 255, 255, 0.85);
    --nav-cast: rgba(0, 0, 0, 0.5);
    --nav-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  }
}

.main-header,
.main-header.is-scrolled { padding-inline: 0; transition: none; pointer-events: none; }
.main-header .island,
.main-header.is-scrolled .island {
  width: min(400px, calc(100% - 24px));
  min-width: 0;
  max-width: none;
  border: 0;
  border-radius: var(--nav-radius);
  background: transparent;
  box-shadow: none;
  overflow: visible;
  backdrop-filter: none;
  /* The island's own two moves — the hop and the shift beside the timer —
     on this selector and not a weaker one: .is-scrolled is the state the
     page is in after the first scroll, and a transition declared only on
     `.main-header .island` lost to it, so the island hopped smoothly in the
     hero and snapped everywhere below it. */
  transition:
    scale 560ms var(--nav-hop),
    translate 640ms cubic-bezier(0.3, 1.15, 0.4, 1);
  pointer-events: auto;
  --text-primary: var(--nav-paper);
  --text-secondary: var(--nav-muted);
  --text-muted: var(--nav-muted);
  --primary: var(--nav-blue);
  --depth-3: var(--nav-accent);
  --depth-1: #48484a;
  --brass-edge: var(--nav-brass);
  --border-color: var(--nav-raise-strong);
  --accent-yellow: var(--nav-blue);
  --accent-blue: var(--nav-blue);
  /* The system face, for every rule inside that names a family token. */
  --font-display: var(--nav-face);
  --font-body: var(--nav-face);
  --font-mono: var(--nav-face);
  font-family: var(--nav-face);
  -webkit-font-smoothing: antialiased;
  --bg-primary: var(--nav-ocean);
  --bg-secondary: var(--nav-ocean);
  --bg-tertiary: var(--nav-raise);
  --border-light: var(--nav-rule);
  --brass-fill: var(--nav-brass);
  --brass-on: var(--nav-ink);
}
.main-header .island[data-context="reader"] { width: min(440px, calc(100% - 24px)); }
.main-header .island[data-drawer]:not([data-drawer=""]) { width: min(520px, calc(100% - 24px)); box-shadow: none; }
/* Pinned to the plate's top edge and centred on it, sized by width and
   height rather than stretched by insets: js/island.js morphs it by animating
   those two numbers, and a box held by all four insets cannot be given a
   size of its own. At rest, 100% of each is exactly the plate. */
.island-surface { position: absolute; top: 0; left: 50%; width: 100%; height: 100%; transform: translateX(-50%); z-index: -1; border: var(--nav-edge-w) solid var(--nav-edge); border-radius: var(--nav-radius); background: var(--nav-ocean); box-shadow: var(--nav-shadow); pointer-events: none; }
/* Open, the capsule becomes the island's deep panel: a rounded slab, not a
   stretched pill — a 400px-tall shape with a 200px radius is a lozenge. */
.island[data-drawer]:not([data-drawer=""]) .island-surface { border-radius: var(--nav-radius-open); }
.island-bar { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 0 8px; height: auto; min-height: var(--header-bar-h); padding: 0 10px; overflow: visible; }
.island-slot-lead { grid-column: 1; grid-row: 1; }
.island-slot-lead:has([hidden]) { display: none; }
.island-slot-body { grid-column: 2; grid-row: 1; height: var(--header-bar-h); }
.island[data-context="home"] .island-slot-body { grid-column: 1 / 3; }
/* The mark on its own, in the lead slot, off the index. Same disc as the one
   in the wordmark so the plate does not appear to change its avatar when a
   lesson opens — only where it is drawn changes. */
.island-mark { grid-column: 1; grid-row: 1; display: inline-flex; align-items: center; justify-content: center; padding: 0; border-radius: var(--radius-full); }
.island-mark-avatar { display: block; width: 32px; height: 32px; border-radius: var(--radius-full); border: 0; object-fit: cover; }
.island-brand { gap: 9px; padding: 0; }
.island-brand-avatar { width: 32px; height: 32px; border: 0; transform: none; }
.island-brand-text { display: flex; gap: 0; line-height: 1.3; }
.island-brand-title { color: var(--nav-paper); font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; }
.island-brand-title span { color: inherit; }
/* The level and department under the name. Its old cap was 1em, which
   cut the Arabic off at the dots and descenders — «ليفل ٣ · داتا ساينس»
   needs a line and a third. Room is taken from the gap above it, not from
   the island: the name and this line fit the same 56px as before. */
.island-brand-place { color: var(--nav-muted); transition: none; font-size: 0.65rem; line-height: 1.4; max-height: 1.4em; margin-block-start: 1px; }
.island-place-label { display: none; }
.island-place-name { font-size: 0.92rem; font-weight: 600; line-height: 1.3; }
.island-place-section { font-size: 0.68rem; line-height: 1.5; }
.island-slot-body > *,
.island.is-turning .island-slot-body > * { animation: none; }
.island.is-turning .island-slot-body { animation: island-context-in 320ms ease both; }
@keyframes island-context-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.island-launcher { grid-column: 4; grid-row: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-width: 36px; min-height: 36px; padding: 0 10px; color: var(--nav-accent); background: var(--nav-raise); border: 0; border-radius: 999px; cursor: pointer; font: 600 0.76rem var(--font-display); }
.island-launcher:hover { background: var(--nav-raise-hover); }
.island-launcher svg { transition: transform 220ms ease; }
.island-launcher[aria-expanded="true"] svg { transform: rotate(90deg); }
.island[data-context="reader"] .island-launcher-caption { display: none; }
.island-readout { grid-column: 3; grid-row: 1; min-height: 36px; padding: 3px 8px; border: 0; justify-content: center; }
.island-readout::before { display: none; }
.island-readout-figures { font-size: 0.86rem; font-weight: 600; line-height: 1.3; color: var(--nav-accent); letter-spacing: 0; }

/* Secondary actions unfold beneath the compact row. */
.island-slot-tools { display: none; grid-row: 2; grid-column: 1 / -1; }
.island[data-drawer]:not([data-drawer=""]) .island-slot-tools { display: flex; gap: 8px; padding: 8px 0; border-top: 1px solid var(--border-light); }
.island-slot-tools .theme-switch { margin-inline-start: auto; }
.island-button { height: 36px; min-width: 36px; color: var(--nav-paper); background: var(--nav-raise); border: 0; border-radius: 999px; box-shadow: none; font-weight: 600; }
.island-button:hover,
.island-button:active { background: var(--nav-raise-hover); box-shadow: none; transform: none; }
/* An open drawer's button is lit white, as a selected control is on the
   system's black; a kept part is the one thing that goes yellow. */
.island-button[aria-expanded="true"] { background: var(--nav-paper); color: var(--nav-ink); }
.island-button.is-on { background: var(--nav-brass); color: var(--nav-ink); }
.island[data-context="home"] .island-slot-tools::before { content: "الإضاءة"; color: var(--nav-muted); font: 600 0.75rem var(--font-body); }
.island .theme-switch { width: 48px; height: 32px; }
.island .theme-switch-track { inset: auto; left: 0; top: 50%; width: 64px; height: 36px; transform: translateY(-50%) scale(.75); transform-origin: left center; }
.island-scale { inset-inline: calc(var(--nav-radius) - 2px); inset-block-end: 3px; height: 2px; overflow: hidden; border-radius: 2px; }
.island[data-drawer]:not([data-drawer=""]) .island-scale { opacity: 0; }
.island-scale-ticks { border: 0; background: var(--nav-rule); mask-image: none; }
.island-scale-ticks::before { background: var(--nav-paper); border: 0; transition: none; }
.island-scale-weight { display: none; }
.island-filter { grid-column: 1 / -1; grid-row: 3; max-width: 100%; margin-bottom: 5px; }
.island-drawer,
.island[data-drawer]:not([data-drawer=""]) .island-drawer { transition: none; background: transparent; border-radius: 0 0 var(--nav-radius-open) var(--nav-radius-open); }
.island-drawer::before { display: none; }
.island[data-drawer]:not([data-drawer=""]) .island-drawer { max-height: min(62dvh, 480px); }
.island-drawer-scroll { max-height: min(48dvh, 380px); padding: 12px; overscroll-behavior: contain; }
.island-panel.is-open { animation: island-context-in 240ms 70ms ease both; }
.island-hub-title { margin: 0 0 8px; font: 700 1.2rem/1.5 var(--font-display); color: var(--nav-paper); }
.island-hub-current { margin: 0 0 14px; font-size: 0.8rem; line-height: 1.6; color: var(--nav-muted); }
.island-hub-actions { display: grid; gap: 6px; }
.island .island-row { border: 1px solid transparent; border-radius: 16px; padding: 12px; color: var(--nav-paper); background: transparent; }
.island .island-row:hover,
.island .island-row:focus-visible,
.island .island-row.is-cursor { background: var(--nav-raise-hover); border-color: var(--nav-edge-strong); }
.island .island-row[aria-current] { background: var(--nav-raise-hover); border-color: transparent; }
.island-row-title { font-size: 0.86rem; line-height: 1.5; }
.island-row-note { font-size: 0.72rem; line-height: 1.6; color: var(--nav-muted); }
.island-row-mark { color: var(--nav-muted); }
.island-hub-actions .lesson-icon { width: 20px; height: 20px; flex: none; color: var(--nav-accent); }
.island .island-resume { margin-bottom: 14px; background: var(--nav-raise); border-color: transparent; }
.island-hub-home { width: calc(100% - 24px); margin: 8px 12px 12px; min-height: 42px; padding: 8px 14px; border: 0; border-radius: 999px; color: #000; background: #fff; font: 600 0.86rem/1.5 var(--font-display); cursor: pointer; }
.island-hub-home:hover { background: #e5e5ea; }
/* The tabs are the system's segmented control: one dark track, the chosen
   segment a lighter pill inside it. */
.island-tabs { margin: 10px 12px 4px; padding: 3px; gap: 2px; background: var(--nav-raise); border: 0; border-radius: 12px; }
.island-tab { padding: 6px 8px; border: 0; border-radius: 9px; line-height: 1.5; color: var(--nav-muted); font-weight: 600; }
.island-tab:hover { color: var(--nav-paper); background: transparent; }
.island-tab[aria-selected="true"] { color: var(--nav-paper); background: var(--nav-raise-strong); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35); border: 0; }
/* The search field, as the system draws one: a filled rounded well. */
.island-search { margin: 12px 12px 4px; padding: 9px 12px; background: var(--nav-raise); border: 0; border-radius: 12px; }
.island-search .lesson-icon { color: var(--nav-muted); }
/* The well is the field; a ring drawn inside it would be a box in a box. */
.island .island-search-input:focus-visible { outline: none; }
.island-key { color: var(--nav-muted); background: var(--nav-raise-strong); border: 0; border-radius: 6px; }
.island-row-meter { border: 0; border-radius: 999px; background: var(--nav-raise-strong); height: 4px; }
.island-row-meter i { background: var(--nav-paper); border-radius: 999px; }
.island-row-keep { color: var(--nav-brass); }
.island-group::after { height: 1px; }
.island-drawer-scroll { scrollbar-color: #48484a transparent; }
.island-drawer-scroll::-webkit-scrollbar-thumb { background: #48484a; border-color: var(--nav-ocean); }
.island-filter { height: 28px; color: var(--nav-paper); background: var(--nav-raise-hover); border: 0; border-radius: 999px; font-weight: 600; }
.island-filter:hover { filter: none; background: var(--nav-raise-strong); }
/* The hub's actions carry their glyph in a disc, as Control Center does. */
.island-hub-actions .lesson-icon { box-sizing: content-box; padding: 8px; color: var(--nav-paper); background: var(--nav-raise-hover); border-radius: 50%; }
.island-search-input { font-size: 16px; color: var(--nav-paper); }
.island-group { color: var(--nav-muted); letter-spacing: 0; text-transform: none; }
.island-empty { color: var(--nav-muted); }
.island-empty strong { color: var(--nav-paper); }
.island :is(a, button, input):focus-visible { outline: 2px solid var(--nav-blue); outline-offset: 2px; }
@media (max-width: 720px) {
  :root { --header-bar-h: 48px; --header-pad-top: 4px; --header-pad-bottom: 4px; --header-h: calc(env(safe-area-inset-top, 0px) + var(--header-pad-top) + var(--header-pad-bottom) + var(--header-bar-h)); --island-dock-h: 0px; }
  body { padding-block-end: 0; }
  .main-header,
  .main-header.is-scrolled { position: sticky; top: 0; inset-block-end: auto; height: var(--header-h); padding: calc(env(safe-area-inset-top, 0px) + var(--header-pad-top)) 0 var(--header-pad-bottom); }
  .main-header .island,
  .main-header.is-scrolled .island,
  .main-header .island[data-context="reader"] { position: absolute; flex-direction: column; width: min(340px, calc(100% - 20px)); margin-inline: auto; }
  .main-header .island[data-drawer]:not([data-drawer=""]) { width: calc(100% - 20px); max-width: 520px; }
  .island-bar { gap: 0 4px; padding-inline: 8px; }
  .island-brand-avatar,
  .island-mark-avatar { width: 28px; height: 28px; }
  .island-brand-title { font-size: .95rem; }
  .island-brand-place { display: none; }
  .island-place-name { font-size: .83rem; }
  .island-launcher { padding-inline: 8px; }
  .island-drawer-scroll { max-height: min(46dvh, 340px); }
  .island[data-context="reader"] .island-place-section { display: none; }
  /* Reserve the compact rail once; the iframe fills the remaining viewport. */
  .lesson-reader-active .main-header,
  html[data-boot-view="reader"] .main-header {
    position: fixed;
    inset-inline: 0;
  }
  .lesson-reader-active .python-lesson-view > .container,
  html[data-boot-view="reader"] .python-lesson-view > .container {
    height: 100dvh;
    padding-block-start: 0;
    padding-block-end: env(safe-area-inset-bottom, 0px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .island *, .island *::before { animation: none !important; transition: none !important; }
}

/* The theme switch, on the island: the sun and the crescent stay (they are
   what says which way the switch goes), but the sky they sit in is the
   island's own dark control fill in both themes, and the cloud — the most
   "website" thing on it — is left off. */
.island .theme-switch { box-shadow: none; }
.island .theme-switch-track { background-color: var(--nav-raise-hover); }
.island .theme-switch-cloud { display: none; }

/* ------------------------------------------------------------- the touch

   The whole island is the button, as it is on a phone: pressing anywhere on
   it opens it (js/island.js), so it answers the finger the way a button does.
   The pointer resting on it lifts it a hair, with a spring that overshoots
   and settles, so it hops rather than grows. A press squeezes it in, fast,
   and the release throws it back out on the same spring. Only the
   collapsed island does this: an open panel is a surface you read, and a
   panel that swells under the pointer is a panel that will not sit still. */
.main-header .island {
  --nav-hop: cubic-bezier(0.3, 1.45, 0.5, 1);
  scale: 1;
  transform-origin: 50% 0;
}

@supports (transition-timing-function: linear(0, 1)) {
  .main-header .island {
    --nav-hop: linear(0, 0.073, 0.25, 0.476, 0.704, 0.903, 1.054, 1.151, 1.198, 1.203, 1.179, 1.138, 1.09, 1.045, 1.007, 0.98, 0.964, 0.958, 0.96, 0.966, 0.975, 0.985, 0.994, 1.001, 1.005, 1.008, 1.009, 1.008, 1.006, 1.004, 1);
  }
}

.main-header .island[data-drawer=""] .island-bar { cursor: pointer; }

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .main-header .island[data-drawer=""]:not(.is-activity):not(.is-pressed):hover { scale: 1.03; }
}

@media (prefers-reduced-motion: no-preference) {
  .main-header .island.is-pressed,
  .main-header.is-scrolled .island.is-pressed {
    scale: 0.96;
    transition: scale 120ms cubic-bezier(0.2, 0, 0, 1);
  }
}

/* Held: a long press opens the list (js/island.js), and the island sinks
   a little further under the finger while it waits, slowly, so the hold is
   felt before it lands. Released into the list, it springs back on the hop. */
@media (prefers-reduced-motion: no-preference) {
  .main-header .island.is-holding,
  .main-header.is-scrolled .island.is-holding {
    scale: 0.93;
    transition: scale 340ms cubic-bezier(0.3, 0, 0.2, 1);
  }
}

/* A held finger on a phone would otherwise select the name or open the
   link's own menu. Only on the closed bar — the open drawer has text a
   student may want to select, and a search field that must take typing. */
.main-header .island[data-drawer=""] .island-bar {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

@media (prefers-reduced-motion: reduce) {
  .main-header .island,
  .main-header.is-scrolled .island { transition: none; }
}
