/* ============================================================================
   CODE QUEST — variables.css
   The single source of truth for the whole visual system.

   Theme: Celestial Code World — Chinese-donghua fantasy-tech.
   Deep navy void · cyan energy · soft gold authority · glass panels.

   Nothing anywhere else in the project hardcodes a colour, a radius, a shadow
   or a duration. Change a token here and every page follows.
   ========================================================================== */

:root {
  /* ==========================================================================
     1. GROUND — the void the world sits in
     Four steps, darkest to lightest, so panels can stack and still read.
     ========================================================================== */
  --bg-abyss: #03060f;
  --bg-deep: #050b1a;
  --bg-mid: #0a1428;
  --bg-raise: #0f1d36;
  --bg-lift: #14243f;

  /* Legacy aliases — kept so nothing breaks if a rule still names them. */
  --bg-dark: var(--bg-deep);
  --panel-bg-solid: var(--bg-mid);

  /* ==========================================================================
     2. CYAN — the energy of logic. The primary accent.
     ========================================================================== */
  --cyan-100: #e4f8ff;
  --cyan-200: #b3edff;
  --cyan-300: #7addff;
  --cyan-400: #3fc9f7; /* primary */
  --cyan-500: #17a6da;
  --cyan-600: #0c7da8;
  --cyan-700: #075a7b;
  --cyan-800: #053b52;

  --cyan: var(--cyan-400);
  --cyan-bright: var(--cyan-200);
  --cyan-deep: var(--cyan-600);

  /* ==========================================================================
     3. GOLD — reward, authority, achievement. The secondary accent.
     ========================================================================== */
  --gold-100: #fff6e0;
  --gold-200: #ffe8ad;
  --gold-300: #f9d585;
  --gold-400: #efbd57; /* primary */
  --gold-500: #cf9a33;
  --gold-600: #9a6d1b;
  --gold-700: #6b4a10;

  --gold: var(--gold-400);
  --gold-bright: var(--gold-200);
  --gold-deep: var(--gold-600);

  /* ==========================================================================
     4. SUPPORTING HUES — used sparingly, for variety and meaning
     ========================================================================== */
  --jade-300: #7df0cd;
  --jade-400: #45e3b4;
  --jade-500: #22b88c;

  --violet-300: #c0b4ff;
  --violet-400: #9d8cff;
  --violet-500: #7259e0;

  --rose-300: #ffb4c0;
  --rose-400: #ff7d92;

  --jade: var(--jade-400);
  --violet: var(--violet-400);

  /* ==========================================================================
     5. SEMANTIC — state colours. Each has a soft fill and a solid edge.
     ========================================================================== */
  --success: #46e3a8;
  --success-soft: rgba(70, 227, 168, 0.13);
  --success-edge: rgba(70, 227, 168, 0.55);

  --danger: #ff6f86;
  --danger-soft: rgba(255, 111, 134, 0.13);
  --danger-edge: rgba(255, 111, 134, 0.55);

  --warning: #ffb454;
  --warning-soft: rgba(255, 180, 84, 0.13);
  --warning-edge: rgba(255, 180, 84, 0.5);

  --info: var(--cyan-400);
  --info-soft: rgba(63, 201, 247, 0.13);

  --locked: #5c6f8c;
  --locked-soft: rgba(92, 111, 140, 0.16);
  --locked-edge: rgba(92, 111, 140, 0.45);

  /* ==========================================================================
     6. GLASS — the panel material.
     A frosted pane needs three things to look real: a translucent fill, a
     bright top edge (light catching the lip) and a blur behind it.
     ========================================================================== */
  /* 0.55 was pretty on a dark plate but left the brighter chapter and
     CODE WORLD artwork reading straight through a panel full of small Thai
     text and thin progress bars. 0.72 still shows the world moving behind the
     glass and keeps the contrast the content needs. */
  --glass-fill: rgba(14, 29, 54, 0.72);
  --glass-fill-strong: rgba(16, 33, 60, 0.88);
  --glass-fill-soft: rgba(14, 29, 54, 0.42);
  --glass-edge: rgba(122, 221, 255, 0.16);
  --glass-edge-hi: rgba(146, 232, 255, 0.4);
  --glass-lip: inset 0 1px 0 rgba(255, 255, 255, 0.09);
  --glass-lip-strong: inset 0 1px 0 rgba(255, 255, 255, 0.16);
  --glass-blur: 18px;
  --glass-blur-heavy: 28px;

  /* Legacy aliases */
  --panel-bg: var(--glass-fill);
  --panel-bg-raised: var(--glass-fill-strong);
  --panel-border: var(--glass-edge);
  --panel-border-strong: var(--glass-edge-hi);

  /* ==========================================================================
     7. GLOW — three tiers. This is what makes the UI feel energised.
     Each tier is a hairline ring + a near halo + a far bloom.
     ========================================================================== */
  --glow-cyan-sm:
    0 0 0 1px rgba(63, 201, 247, 0.3),
    0 0 10px rgba(63, 201, 247, 0.22);
  --glow-cyan-md:
    0 0 0 1px rgba(63, 201, 247, 0.45),
    0 0 18px rgba(63, 201, 247, 0.34),
    0 0 48px rgba(63, 201, 247, 0.14);
  --glow-cyan-lg:
    0 0 0 1px rgba(122, 221, 255, 0.6),
    0 0 26px rgba(63, 201, 247, 0.46),
    0 0 72px rgba(63, 201, 247, 0.22),
    0 0 130px rgba(63, 201, 247, 0.1);

  --glow-gold-sm:
    0 0 0 1px rgba(239, 189, 87, 0.32),
    0 0 10px rgba(239, 189, 87, 0.22);
  --glow-gold-md:
    0 0 0 1px rgba(239, 189, 87, 0.48),
    0 0 18px rgba(239, 189, 87, 0.36),
    0 0 48px rgba(239, 189, 87, 0.15);
  --glow-gold-lg:
    0 0 0 1px rgba(255, 232, 173, 0.62),
    0 0 26px rgba(239, 189, 87, 0.48),
    0 0 72px rgba(239, 189, 87, 0.24),
    0 0 130px rgba(239, 189, 87, 0.1);

  --glow-success: 0 0 0 1px var(--success-edge), 0 0 20px rgba(70, 227, 168, 0.3);
  --glow-danger: 0 0 0 1px var(--danger-edge), 0 0 20px rgba(255, 111, 134, 0.3);

  /* No text glows. Letters are drawn flat: no halo, no outline, no stroke.
     Where text sits on artwork, contrast comes from a scrim BEHIND it (see
     .cq-title__plate::before in landing.css and --scrim-* below) rather than
     from an edge around every glyph — a shadow traced around handwriting
     thickens the strokes and is exactly what made the Thai look furry. */

  /* Legacy aliases */
  --cyan-soft: rgba(63, 201, 247, 0.12);
  --gold-soft: rgba(239, 189, 87, 0.12);
  --cyan-glow: var(--glow-cyan-md);
  --cyan-glow-strong: var(--glow-cyan-lg);
  --gold-glow: var(--glow-gold-md);

  /* ==========================================================================
     8. ELEVATION — dark UI needs shadow for depth AND a light lip for form.
     ========================================================================== */
  --elev-1: 0 1px 2px rgba(2, 5, 12, 0.5), 0 2px 8px rgba(2, 5, 12, 0.3);
  --elev-2: 0 2px 6px rgba(2, 5, 12, 0.5), 0 8px 24px rgba(2, 5, 12, 0.36);
  --elev-3: 0 6px 14px rgba(2, 5, 12, 0.5), 0 18px 48px rgba(2, 5, 12, 0.44);
  --elev-4: 0 12px 28px rgba(2, 5, 12, 0.55), 0 32px 80px rgba(2, 5, 12, 0.5);

  /* Legacy aliases */
  --shadow-sm: var(--elev-1);
  --shadow-md: var(--elev-2);
  --shadow-lg: var(--elev-3);

  /* ==========================================================================
     9. SCRIMS & VEILS — how artwork meets text
     ========================================================================== */
  /* The top stop was 0.3, which was enough while every heading carried a text
     shadow. With the shadows gone the page title and the learner's name sit
     directly on open sky in the artwork, so the band they occupy is darker
     now — contrast comes from behind the letters instead of around them. */
  --scrim-page: linear-gradient(
    180deg,
    rgba(3, 6, 15, 0.58) 0%,
    rgba(3, 6, 15, 0.66) 48%,
    rgba(3, 6, 15, 0.93) 100%
  );
  --scrim-stage: linear-gradient(
    180deg,
    rgba(3, 6, 15, 0.06) 0%,
    rgba(3, 6, 15, 0.38) 62%,
    rgba(3, 6, 15, 0.88) 100%
  );
  --scrim-hero: radial-gradient(
      ellipse 120% 80% at 50% 42%,
      rgba(3, 6, 15, 0) 0%,
      rgba(3, 6, 15, 0.45) 58%,
      rgba(3, 6, 15, 0.86) 100%
    );
  --scrim-caption: linear-gradient(
    180deg,
    rgba(3, 6, 15, 0) 0%,
    rgba(3, 6, 15, 0.68) 38%,
    rgba(3, 6, 15, 0.96) 100%
  );
  --overlay-scrim: rgba(3, 6, 15, 0.84);

  /* Legacy alias */
  --scene-scrim: var(--scrim-page);

  /* ==========================================================================
     10. TEXT
     ========================================================================== */
  --text-primary: #eef6ff;
  --text-secondary: #a6bcd8;
  --text-tertiary: #7e94b2;
  --text-muted: #63799a;
  --text-on-light: #071227;
  --text-on-gold: #1b1204;

  --text-cyan: var(--cyan-200);
  --text-gold: var(--gold-200);

  /* ==========================================================================
     11. TYPOGRAPHY
     The project ships ONE font file — assets/fonts/itimDemo.ttf — and it draws
     EVERY character on every screen: Thai, Latin, digits and the "CODE QUEST"
     wordmark alike (see the @font-face after this block).

     It leads both stacks and its face carries no `unicode-range`, so the
     browser does not fall back to a system face for English words. One file,
     one voice — a handwritten Thai sentence next to a grotesque "XP" was the
     thing that made the interface look assembled rather than designed.

     The system names after it are the fallback for a browser that cannot load
     the file at all (a stale cache, a missing file after a copy), so text
     stays readable rather than turning into boxes.

     `--font-mono` is the deliberate exception: literal program code
     (`IF Battery > 20 → Charge`) needs its columns to line up, and this face
     is proportional. Only real code uses it — decorative "mono" labels use
     the body face like everything else.
     ========================================================================== */
  --font-body: "Itim Demo", "Noto Sans Thai", "IBM Plex Sans Thai", "Leelawadee UI",
    "Sarabun", Tahoma, "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-display: "Itim Demo", "Noto Sans Thai", "IBM Plex Sans Thai", "Leelawadee UI",
    Tahoma, "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", "Cascadia Mono", "SF Mono", Consolas,
    "Courier New", ui-monospace, monospace;

  /* Fluid scale — each step interpolates between phone and desktop so no
     breakpoint has to restate a font size. */
  --fs-3xs: 0.75rem;                                    /* 12px  */
  --fs-2xs: 0.8125rem;                                  /* 13px  */
  --fs-xs: clamp(0.84rem, 0.8rem + 0.18vw, 0.9375rem);  /* 13→15 */
  --fs-sm: clamp(0.92rem, 0.88rem + 0.2vw, 1.02rem);    /* 15→16 */
  --fs-base: clamp(0.95rem, 0.9rem + 0.24vw, 1.0625rem);/* 15→17 */
  --fs-md: clamp(1.02rem, 0.96rem + 0.3vw, 1.18rem);    /* 16→19 */
  --fs-lg: clamp(1.14rem, 1.05rem + 0.45vw, 1.4rem);    /* 18→22 */
  --fs-xl: clamp(1.3rem, 1.15rem + 0.75vw, 1.75rem);    /* 21→28 */
  --fs-2xl: clamp(1.5rem, 1.25rem + 1.25vw, 2.25rem);   /* 24→36 */
  --fs-3xl: clamp(1.8rem, 1.35rem + 2.2vw, 3rem);       /* 29→48 */
  --fs-4xl: clamp(2.2rem, 1.4rem + 4vw, 4.25rem);       /* 35→68 */
  --fs-5xl: clamp(2.6rem, 1.4rem + 6vw, 5.5rem);        /* 42→88 */

  /* Thai stacks vowel marks above the letter and below it, so a line box sized
     for Latin clips them. --lh-tight is for HEADINGS and was 1.22, which is a
     fine number for an English display line and wrong for this one: the tone
     mark on "แผนที่" touched the eyebrow above it, and "จุดประสงค์การเรียนรู้"
     dropped its ู into the line below. Every step here now has room for both
     the mark above and the descender beneath. */
  --lh-tight: 1.42;
  --lh-snug: 1.55;
  --lh-normal: 1.68;
  --lh-relaxed: 1.82;
  --lh-thai: 1.95;

  /* Tracking is kept modest on purpose. Thai stacks vowels and tone marks over
     and under the consonant they belong to, so wide letter-spacing pulls a
     cluster apart and the reader has to reassemble the syllable — the single
     biggest cause of "Thai is hard to read here". The wide steps are still
     wide enough for a tracked Latin label. */
  --ls-tight: -0.01em;
  --ls-normal: 0;
  --ls-wide: 0.03em;
  --ls-wider: 0.07em;
  --ls-widest: 0.14em;

  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-black: 800;

  /* ==========================================================================
     12. SPACING — 4px base, named by step not by pixel
     ========================================================================== */
  --sp-0: 0;
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;
  --sp-10: 8rem;

  /* Fluid section rhythm */
  --gap-section: clamp(1.25rem, 0.9rem + 1.6vw, 2.25rem);
  --gap-panel: clamp(1rem, 0.8rem + 0.9vw, 1.5rem);

  /* ==========================================================================
     13. SHAPE
     ========================================================================== */
  --r-xs: 6px;
  --r-sm: 9px;
  --r-md: 13px;
  --r-lg: 18px;
  --r-xl: 26px;
  --r-2xl: 34px;
  --r-pill: 999px;

  /* Legacy aliases */
  --radius-sm: var(--r-sm);
  --radius-md: var(--r-md);
  --radius-lg: var(--r-lg);
  --radius-xl: var(--r-xl);
  --radius-pill: var(--r-pill);

  --border-hair: 1px;
  --border-thin: 1.5px;
  --border-thick: 2px;

  /* ==========================================================================
     14. MOTION
     Expo-out for entrances (fast start, soft landing), back-out for anything
     that should feel springy, soft-in-out for reversible hovers.
     ========================================================================== */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-back: cubic-bezier(0.34, 1.46, 0.64, 1);
  --ease-in-out-soft: cubic-bezier(0.45, 0, 0.55, 1);
  --ease-spring: cubic-bezier(0.22, 1.2, 0.36, 1);

  --dur-instant: 90ms;
  --dur-fast: 150ms;
  --dur-mid: 260ms;
  --dur-slow: 420ms;
  --dur-slower: 680ms;
  --dur-cinematic: 1100ms;

  /* Legacy aliases */
  --ease-out: var(--ease-out-expo);
  --ease-in-out: var(--ease-in-out-soft);

  /* ==========================================================================
     15. LAYOUT
     ========================================================================== */
  --stage-ratio: 16 / 9;
  --content-max: 1240px;
  --content-wide: 1480px;
  --content-narrow: 720px;
  --content-reading: 62ch;

  --hud-h: 60px;
  --hud-height: var(--hud-h); /* legacy alias */

  --gutter: clamp(0.875rem, 0.6rem + 1.4vw, 2rem);
  --page-gutter: var(--gutter); /* legacy alias */

  /* ==========================================================================
     16. FOCUS — one ring, used everywhere, always visible on dark
     ========================================================================== */
  --focus-ring: 0 0 0 2px var(--bg-deep), 0 0 0 4px var(--cyan-300),
    0 0 18px rgba(122, 221, 255, 0.45);

  /* ==========================================================================
     17. AMBIENT FX — tuned in one place so the mood can be dialled up or down
     ========================================================================== */
  --fx-particle-count: 46;
  --fx-aurora-opacity: 0.5;
  --fx-grid-opacity: 0.05;
  --fx-vignette: 0.55;
  --fx-parallax-depth: 14px;

  /* ==========================================================================
     18. Z-INDEX — one ladder, no guessing
     ========================================================================== */
  --z-bg: -3;
  --z-fx: -2;
  --z-scrim: -1;
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 30;
  --z-hud: 40;
  --z-popover: 120;
  --z-modal: 200;
  --z-toast: 300;
  --z-loader: 400;
}

/* ============================================================================
   Density: tighten the vertical rhythm on short viewports so a lesson still
   fits without the learner scrolling past a screen of padding.
   ========================================================================== */
@media (max-height: 700px) {
  :root {
    --gap-section: 1rem;
    --gap-panel: 0.875rem;
    --hud-h: 52px;
  }
}

/* Fewer particles on small screens — they are decoration, not content. */
@media (max-width: 720px) {
  :root {
    --fx-particle-count: 22;
    --fx-aurora-opacity: 0.38;
    --fx-parallax-depth: 8px;
  }
}

/* Honour the OS setting at the token level: with reduced motion the ambient
   layers are dialled right down rather than merely frozen. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --fx-particle-count: 0;
    --fx-aurora-opacity: 0.22;
    --fx-parallax-depth: 0px;
  }
}

/* ============================================================================
   THE PROJECT'S TYPEFACE — assets/fonts/itimDemo.ttf

   The file's own internal name is "Lmf_itim Demo" (a single 400 weight, built
   with FontCreator). It is declared here under the shorter alias used in the
   stacks above; the alias is a CSS label, not a claim about the file.

   NO `unicode-range` — deliberately. An earlier version restricted the face
   to the Thai block (U+0E01–U+0E5B) so the browser would only reach for it on
   Thai characters and English words kept a system face. That left the game in
   two typefaces at once: handwritten Thai next to a grotesque "CODE QUEST",
   "XP", "Level" and every number. The file covers Latin and digits as well,
   so the restriction is gone and one face now draws every character on every
   screen — which is the whole point of supplying a font.

   The one exception is `--font-mono` above, which real program code still
   uses: `IF Battery > 20 → Charge` has to line up column by column, and a
   handwriting face is proportional. Decorative "mono" labels (mission ids,
   counters, the version string) use the body face like everything else.

   There is only one weight in the file, so a bold heading is synthesised by
   the browser. That is deliberate: adding a second family for bold would need
   a second file, and none was supplied.

   `font-display: swap` means text is readable in the fallback face from the
   first paint and upgrades when the file arrives — never a blank page.
   ========================================================================== */

@font-face {
  font-family: "Itim Demo";
  src: url("../assets/fonts/itimDemo.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;

  /* This face draws small for its em box: at a nominal 15px it read like 12px.
     `size-adjust` scales the face itself, so one number fixes every size in
     the project instead of every rule having to compensate — and now that the
     same face draws Latin too, the whole interface scales together instead of
     Thai chasing a Latin fallback. A browser without support simply shows the
     face at 100%, which is still correct, just small. */
  /* 128%. Itim draws a small body for its em box, so at the old 112% Thai
     sentences still read as one size smaller than the Latin beside them —
     visibly hard to read on a classroom projector. 128% brings the Thai
     x-height up to the Latin faces'; the places that used to overflow at a
     larger face (the HUD bar and the map's test strip) now wrap instead of
     pushing the page wider, so the text no longer has to be the thing that
     gives way. Verified with no horizontal overflow from 320px up. */
  size-adjust: 128%;
}
