/* OrbitLab shared design tokens + global primitives.
   Single source of truth for colours, loaded by the Explore page and every
   learning-portal page. Dark is the default; [data-theme="light"] flips tokens. */

/* ── Browser baseline (normative; mirrors design.md "Browser_Baseline") ──────
   Baseline: iOS Safari 15+ / evergreen Chrome, Firefox, Edge. Below-baseline
   browsers must still render a complete, usable interface via the fallbacks
   noted below. Keep this table in sync with the design document.

   | Capability                     | Baseline support                 | Below-baseline behaviour                                  |
   | ------------------------------ | -------------------------------- | --------------------------------------------------------- |
   | Portal core (layout, JS, JSON) | iOS Safari 15+ / evergreen       | Supported                                                 |
   | 100dvh                         | iOS Safari 15.4+                 | Falls back to the preceding `100vh` declaration           |
   | backdrop-filter blur           | iOS Safari 15+ (`-webkit-` pfx)  | Solid/semi-opaque background, AA contrast preserved       |
   | color-mix(in srgb, ...)          | iOS Safari 16.2+ / Chrome 111+   | Preceding opaque solid-colour fallback on same property   |

   IMPORTANT: color-mix() is unsupported below iOS Safari 16.2 / Chrome 111.
   Every color-mix() declaration (e.g. --ring focus ring, themed tints) MUST be
   immediately preceded by an opaque solid-colour fallback for the same property
   so focus rings and tints remain visible below baseline (see C7 fallbacks). */

:root {
  --bg: #0a0e1a;
  --app-bg: #0a0e1a;
  --panel: #121829;
  --panel-2: #1a2238;
  --border: #263150;
  --text: #e6ecff;
  --text-soft: #cdd7f5;
  --muted: #8a97bd;
  --accent: #4dd0e1;
  --accent-2: #7c9cff;
  --rule: #2a3457;
  --shadow: rgba(0, 0, 0, 0.45);
  --danger: #ff6b6b;
  --good: #5cf2a0;

  /* Islamic-astronomy learning path - brass/gold accent (design B.4). Extends the
     theme; does NOT fork it. `--history-accent` is a FILLED brand gold that always
     carries dark `--history-accent-ink` text, and is also used for decorative tints
     (hotspot dots, panorama glow, certificate seal). Contrast (dark theme):
       • ink #1b1200 on gold #c9a227 ....... 7.7:1  (AAA normal text)
       • gold #c9a227 vs --panel #121829 ... 7.3:1  (>=3:1 non-text / 1.4.11)
     Use `--history-accent-line` for gold shown as foreground text/hairlines on the
     page surface - it is brightened on dark and darkened on light so it clears AA
     against each theme's panels (see the light overrides below). */
  --history-accent: #c9a227;
  --history-accent-ink: #1b1200;
  --history-accent-line: #e6c25a; /* vs --panel #121829 = 10.3:1 (AAA) */

  /* Dedicated keyboard focus-ring colour for new path components (Req 12.7). Kept
     distinct from the gold accent so the indicator never blends into a gold surface;
     matches the previous hotspot fallback (#7c9cff) so nothing shifts on dark. */
  --focus: var(--accent-2);

  /* Elevation: layered shadows give cards real depth instead of a flat border. */
  --elev-1: 0 1px 2px rgba(0,0,0,0.25), 0 1px 3px rgba(0,0,0,0.2);
  --elev-2: 0 4px 12px -2px rgba(0,0,0,0.4), 0 2px 6px -2px rgba(0,0,0,0.3);
  --elev-3: 0 14px 38px -10px rgba(0,0,0,0.55), 0 6px 14px -6px rgba(0,0,0,0.4);
  /* Opaque fallback first: below-baseline browsers ignore the color-mix() line
     below and keep this solid accent ring so focus stays visible (C7). */
  --ring: 0 0 0 3px var(--accent);
  --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 38%, transparent);

  /* Accent gradient used by primary actions, progress and hero flourishes. */
  --grad-accent: linear-gradient(100deg, var(--accent), var(--accent-2));

  /* Radius scale */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;

  /* Motion tokens (one place to tune the feel; honoured app-wide). */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --t-fast: 0.14s;
  --t-med: 0.26s;
  --t-slow: 0.5s;
}

[data-theme="light"] {
  --bg: #eef2fb;
  --app-bg: #f5f8ff;
  --panel: #ffffff;
  --panel-2: #eef2fb;
  --border: #d3ddf0;
  --text: #16203a;
  --text-soft: #2f3c58;
  --muted: #515d80;
  --accent: #0a7184;
  --accent-2: #344fc2;
  --rule: #dbe3f4;
  --shadow: rgba(40, 60, 110, 0.18);
  --danger: #c0392b;
  --good: #1a8f5a;

  /* Brass/gold, darkened for the light theme so it clears WCAG on white panels.
     Contrast (light theme):
       • ink #1b1200 on gold #a17b12 ......... 4.7:1  (AA normal text)
       • gold #a17b12 vs --panel #ffffff ..... 3.9:1  (>=3:1 non-text / 1.4.11)
       • line #7a5c10 vs --panel #ffffff ..... 5.6:1  (AA normal text) */
  --history-accent: #a17b12;
  --history-accent-ink: #1b1200;
  --history-accent-line: #7a5c10;
  /* --focus resolves to the light --accent-2 (#344fc2) - strong on light surfaces. */

  --elev-1: 0 1px 2px rgba(40,60,110,0.08), 0 1px 3px rgba(40,60,110,0.06);
  --elev-2: 0 6px 16px -4px rgba(40,60,110,0.14), 0 2px 6px -2px rgba(40,60,110,0.1);
  --elev-3: 0 18px 40px -12px rgba(40,60,110,0.22), 0 6px 14px -6px rgba(40,60,110,0.14);
}

/* ---------------- global primitives ---------------- */
.skip-link {
  position: absolute; left: 12px; top: -48px; z-index: 100;
  background: var(--accent); color: #04121a; padding: 8px 14px; border-radius: 8px;
  font-weight: 600; text-decoration: none; transition: top 0.15s ease;
}
.skip-link:focus { top: 12px; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* High-contrast rendering (Req 12.4). When the learner (or their OS) asks for more
   contrast, widen the focus indicator and lift the gold accent / borders toward the
   theme's brightest ink so state stays legible. In Windows forced-colors mode we hand
   colour control to the system palette and pin the focus ring to `Highlight` so the
   keyboard indicator survives the override (WCAG 2.4.7 / 1.4.11). */
@media (prefers-contrast: more) {
  :root {
    --border: #46557f;               /* firmer panel/card edges on dark */
    --muted: #aab6da;                /* lift secondary text toward AA */
    --history-accent-line: #f2d27a;  /* brighter gold text on dark */
  }
  [data-theme="light"] {
    --border: #9fb0d2;
    --muted: #3c476a;
    --history-accent: #7a5c10;       /* darker gold fill/detail on light */
    --history-accent-line: #5e470a;
  }
  /* A thicker, higher-contrast keyboard focus ring in both themes. */
  :focus-visible { outline-width: 3px; outline-offset: 3px; }
}

@media (forced-colors: active) {
  /* Let the system palette drive colour; keep the focus ring on a system colour so
     the keyboard indicator is never removed by the forced-colors override. */
  :focus-visible { outline: 3px solid Highlight; outline-offset: 2px; }
  .skip-link:focus { outline: 3px solid Highlight; }
}

/* Smooth in-page scrolling and tidy text selection (premium polish). */
html { scroll-behavior: smooth; }
::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); color: var(--text); }

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: inherit; font-size: 14.5px; font-weight: 600; cursor: pointer;
  border-radius: var(--r-md); padding: 11px 18px; border: 1px solid transparent;
  text-decoration: none;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-med) var(--ease-out),
              background var(--t-med) ease, border-color var(--t-med) ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px) scale(0.99); }
.btn-primary { background: var(--grad-accent); color: #04121a; box-shadow: var(--elev-1); }
.btn-primary:hover { box-shadow: 0 8px 22px -6px color-mix(in srgb, var(--accent) 60%, transparent); }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn-ghost:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }

.badge {
  display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: 0.4px;
  text-transform: uppercase; padding: 3px 9px; border-radius: 999px;
  background: var(--panel-2); color: var(--accent-2); border: 1px solid var(--border);
}

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; font-size: 15px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 10px; color: var(--text);
  transition: border-color var(--t-med) ease, transform var(--t-fast) var(--ease-out), background var(--t-med) ease;
}
.icon-btn:hover { border-color: var(--accent); transform: translateY(-1px); }
.icon-btn:active { transform: translateY(0) scale(0.94); }

/* Comfortable 44px targets on touch devices (WCAG 2.5.5 / pointer: coarse). */
@media (pointer: coarse) {
  .icon-btn { width: 44px; height: 44px; }
  .lang-select { padding: 9px 10px; }

  /* Grow shared quiz/related controls to a >=44px box via padding + min-height
     (box-sizing: border-box is in effect), centring the label vertically inside
     the enlarged target. Padding - not font growth - does the sizing so labels
     stay within the box. .quiz-choice keeps its left-aligned label; chips centre. */
  .quiz-choice {
    display: flex; align-items: center; justify-content: flex-start;
    min-height: 44px; padding-top: 11px; padding-bottom: 11px;
  }
  .related-chips a {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; padding-top: 11px; padding-bottom: 11px; line-height: 1.2;
  }
}

/* ---------------- inline SVG icons (icons.js) ---------------- */
/* Icons inherit text colour and scale with font-size by default; specific
   contexts (buttons, step dots) set an explicit size below. */
.svg-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.14em; flex-shrink: 0; }
.icon-btn .svg-icon { width: 18px; height: 18px; }
.btn .svg-icon { width: 1.05em; height: 1.05em; vertical-align: -0.18em; }

/* Language switcher (built by i18n.js). Themed so it matches the chrome on every
   page, with explicit option colours so the open dropdown is readable in both themes. */
.lang-switcher { display: inline-flex; }
.lang-select {
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 8px; font-size: 13px; font-family: inherit; cursor: pointer;
}
.lang-select:hover { border-color: var(--accent); }
.lang-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.lang-select option { background: var(--panel); color: var(--text); }

.loading { color: var(--muted); font-size: 14px; }

/* =====================================================================
   Motion & feedback utilities (driven by motion.js, used across pages).
   Everything here degrades to "instantly visible, no animation" when the
   user prefers reduced motion (see the media query at the foot of the file).
   ===================================================================== */

/* Scroll-reveal: motion.js adds .reveal to off-screen elements, then .in. */
.reveal { opacity: 0; transform: translateY(16px); will-change: opacity, transform; }
.reveal.in { opacity: 1; transform: none; transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out); }

/* Page entrance: the main content fades up once on load. */
.page-enter { animation: pageEnter var(--t-slow) var(--ease-out) both; }
@keyframes pageEnter { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* Skeleton loaders: a shimmering placeholder while content hydrates. */
.skeleton {
  position: relative; overflow: hidden;
  background: var(--panel-2); border-radius: var(--r-sm);
}
.skeleton::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 9%, transparent), transparent);
  animation: shimmer 1.3s infinite;
}
@keyframes shimmer { 100% { transform: translateX(100%); } }
.skeleton-card { height: 132px; border-radius: var(--r-md); }
.skeleton-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }

/* Animated circular progress ring (student progress visualisation). */
.ring { display: inline-grid; place-items: center; position: relative; }
.ring svg { transform: rotate(-90deg); display: block; }
.ring .ring-track { stroke: var(--panel-2); }
.ring .ring-fill {
  stroke: var(--accent); stroke-linecap: round;
  transition: stroke-dashoffset 0.9s var(--ease-out);
}
.ring .ring-label { position: absolute; font-size: 13px; font-weight: 700; color: var(--text); }

/* Confetti / celebration canvas (motion.js mounts this full-screen, transient). */
.fx-confetti { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999; }

/* A soft pop used for success states and achievement unlocks. */
.pop { animation: pop var(--t-med) var(--ease-spring) both; }
@keyframes pop { 0% { transform: scale(0.8); opacity: 0; } 60% { transform: scale(1.04); } 100% { transform: scale(1); opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { scroll-behavior: auto !important; }
  .btn, .icon-btn { transition: none; }
  .btn:hover, .icon-btn:hover { transform: none; }
  .reveal { opacity: 1; transform: none; }
  .reveal.in { transition: none; }
  .page-enter { animation: none; }
  .skeleton::after { animation: none; }
  .ring .ring-fill { transition: none; }
  .pop { animation: none; }
}

/* ── Accessibility helper: visually hidden but read by assistive tech ──────── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* ── Dyslexia-friendly reading typography (Req 12.5) ─────────────────────────
   Toggled by portal.js via <html data-font="dyslexic">, persisted and applied
   pre-paint by the inline head script. A self-hosted OFL Latin face is loaded
   (font-display: swap → the readable fallback stack shows immediately and if the
   binary is absent nothing breaks), and letter/word/line spacing are widened - 
   the spacing changes are what most help dyslexic readers. Arabic is a cursive
   script with no dyslexia face, so there we keep the system Arabic font and only
   widen spacing (the button's help text explains this). */
@font-face {
  font-family: "OpenDyslexic";
  src: url("/assets/fonts/OpenDyslexic-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
.font-toggle-glyph { font-weight: 700; font-size: 13px; letter-spacing: 0.02em; }
html[data-font="dyslexic"] body {
  font-family: "OpenDyslexic", "Comic Sans MS", "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  letter-spacing: 0.03em;
  word-spacing: 0.08em;
  line-height: 1.8;
}
/* Arabic: preserve the cursive system font; widen spacing and line-height only.
   Higher specificity ([lang="ar"]) so it wins over the Latin rule above. */
html[lang="ar"][data-font="dyslexic"] body {
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  letter-spacing: normal;
  word-spacing: 0.14em;
  line-height: 2.05;
}

/* ── Themed scrollbars ──────────────────────────────────────────────
   Slim, rounded, token-driven scrollbars so long lists (sky star names, code
   blocks, the page itself) match the theme in both dark and light modes.
   Firefox/new Chromium take the two standard properties; older WebKit falls
   back to the ::-webkit-scrollbar rules (ignored wherever scrollbar-width is
   supported, so the two never fight). */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: padding-box; }
