@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Rajdhani:wght@600;700&display=swap');

:root {
  --bg: #0A0A0A;
  --surface: #141414;
  --surface-raised: #1A1A1A;
  --surface-hover: #212121;
  --border: #262626;
  --border-strong: #3A3A3A;

  --text: #F5F5F5;
  --text-muted: #8A8A8A;
  --text-faint: #555555;

  --accent: #E3243B;
  --accent-hover: #B81B2E;

  --success: #22C55E;
  --success-hover: #16A34A;

  --blue-team: #3B82F6;
  --blue-tint: rgba(59, 130, 246, 0.12);

  /* Puzzle board checkerboard. Named by role rather than by hue — this palette
     has changed several times, and neutral names keep the next change confined
     to these two lines. */
  --piece-light: #a3e635;
  --piece-dark: #14210a;

  --danger: #E3243B;
  --warn: #EAB308;

  /* Comparison-table result tiles, all carrying white text. Contrast against that white
     is 4.3:1 on hit and 6.1:1 on miss, but only 2.8:1 on near — amber is a
     bright hue and white sits light on it. If that ever needs fixing, drop
     --tile-near's luminance (a darker amber such as #B87A00) rather than
     reaching for a second text colour, which would break the set apart. */
  --tile-hit: #1F8B4C;
  --tile-near: #D48C00;
  --tile-miss: #AE3A3A;
  --tile-text: #FFFFFF;
  --tile-edge: rgba(0, 0, 0, 0.30);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.6);
  --shadow-lg: 0 24px 56px rgba(0, 0, 0, 0.7);

  /* Motion. Both curves are ease-out: the fast start is what makes a control
     read as having answered the press rather than having thought about it
     first. --dur-press is deliberately shorter than --dur-ui, so the physical
     squash lands ahead of the colour change rather than alongside it. */
  --ease-out: cubic-bezier(0.2, 0, 0, 1);
  --dur-press: 90ms;
  --dur-ui: 160ms;
  /* Content arriving, rather than a control answering a press. Longer than
     both of the above on purpose: those two are acknowledgements and want to
     be over before you notice them, whereas an element entering has to be
     seen to travel or it may as well have been there all along. */
  --dur-enter: 260ms;

  /* Two rings, not one: the inner --bg ring punches a gap so the accent ring
     stays legible against a border it may land directly on top of. */
  --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);

  /* ── Type ──────────────────────────────────────────────────────────────
     A ~1.125 ratio off a 1rem base. This replaces 17 distinct ad-hoc sizes,
     four of which (0.9 / 0.95 / 1 / 1.05) sat inside a 0.15rem span — steps
     too close to read as deliberate hierarchy, but far enough apart to stop
     two labels of the same rank from matching. The large end keeps the
     values that were already there (1.4 / 1.6 / 2) so the scale regularises
     the small text without redrawing the headings.

     rem throughout, never px: the whole scale then moves with the reader's
     browser text-size setting instead of pinning them to ours. */
  --text-2xs: 0.7rem;
  --text-xs: 0.8rem;
  --text-sm: 0.9rem;
  --text-md: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.4rem;
  --text-2xl: 1.6rem;
  --text-3xl: 2rem;

  /* Leading, paired to size rather than set per component. It runs inversely
     to size: display type is tight because its lines are short and its
     descenders are already far apart at that scale, whereas running text
     needs the room to keep two wrapped lines from reading as one block. */
  --leading-none: 1;      /* icons and markers — a glyph in a box, not text */
  --leading-tight: 1.05;  /* display: the h1 */
  --leading-snug: 1.2;    /* controls: buttons, inputs, table cells */
  --leading-normal: 1.5;  /* prose: status line, answer copy, hints */

  /* Tracking, and the reason this is a scale rather than one value: letter
     spacing has to be chosen per size or it is wrong somewhere. Every
     tracked face on this page is Rajdhani set in caps, which inverts the
     usual rule — uppercase has no x-height cues to separate letterforms, so
     it needs *positive* tracking, and needs progressively more of it as the
     type gets smaller. Large caps need almost none; 0.7rem caps fall apart
     without a lot.

     These four bands replace values that had drifted out of step with size:
     0.9rem labels were split between 0.04em and 0.03em, and 0.75rem table
     headers were tracked looser than 1rem buttons. */
  --tracking-caps-xs: 0.12em;  /* <= --text-2xs */
  --tracking-caps-sm: 0.04em;  /* --text-xs .. --text-md */
  --tracking-caps-md: 0.03em;  /* --text-lg */
  --tracking-caps-lg: 0.025em; /* >= --text-xl, and the fluid h1 */

  /* The width of the content column. base.css reads it from here rather than
     carrying the same 1260 twice. */
  --content-max: 1260px;

  --radius-sm: 2px;
  --radius-md: 3px;
  --radius-lg: 4px;
  /* Result tiles only. Deliberately far rounder than the tokens above: the
     tiles are the one element meant to read as separate objects rather than
     part of the page's squared-off frame. */
  --radius-tile: 8px;
}

/* ── Right-to-left ───────────────────────────────────────────────────────
   The four bands above exist to separate uppercase letterforms, and that whole
   argument is Latin. Arabic and Persian are CURSIVE: letters join, and
   letter-spacing forces the joins apart, so tracked Arabic renders as a row of
   disconnected glyphs rather than as words. Hebrew is not cursive but has no
   uppercase either, so the tracking buys nothing there and costs legibility.

   Overriding the four tokens covers all fourteen rules that spend them, which
   is why they are tokens. text-transform: uppercase needs no counterpart —
   none of the three scripts has case, so it is already a no-op.

   Keyed off [dir="rtl"], which tools/i18n-render.js writes onto <html> for
   whichever locales carry `dir` in src/i18n/locales.json. A fourth RTL locale
   needs that field and nothing here. */
[dir="rtl"] {
  --tracking-caps-xs: normal;
  --tracking-caps-sm: normal;
  --tracking-caps-md: normal;
  --tracking-caps-lg: normal;
}
