/* recap-mini — design tokens (DESIGN.md §2).
   Owned by card U0. Nobody else redefines a token; pages add their own
   classes in css/<page>.css and consume the variables below.

   Load order on every page: tokens.css → components.css → <page>.css */

/* ---------------------------------------------------------------- fonts
   Self-hosted (CSP is default-src 'self'; no CDN). Both files are the
   variable builds Google Fonts serves, so one file covers 400–700:
   - Inter, latin subset (47 KB)
   - Noto Sans Myanmar, myanmar subset U+1000–109F (150 KB)
   See static/fonts/LICENSE.txt (OFL 1.1). */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/inter-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Noto Sans Myanmar";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/noto-sans-myanmar-var.woff2") format("woff2");
  unicode-range: U+1000-109F, U+200C-200D, U+25CC, U+A92E, U+A9E0-A9FE,
    U+AA60-AA7F, U+116D0-116E3;
}

/* --------------------------------------------------------------- tokens */
:root {
  color-scheme: dark;

  --bg: #0f1115;
  --surface: #171a21;
  --surface-2: #1f2330;
  --line: #2a2f3d;
  --text: #f2f3f5;
  --text-2: #a9afbd;
  --text-3: #6e7484;
  /* CRIMSON ACCENT (card U, 2026-09-05 — see DESIGN.md §2 "Why this look").
     THREE tokens, not one, because no single red can be both a fill that
     carries white ink at 4.5:1 AND a text colour that clears 4.5:1 on the
     dark ground — a red bright enough for the second is too bright for the
     first. Measured (WCAG 2.x, sRGB):
       --accent      on --bg 4.09:1 · --surface 3.77:1 · --surface-2 3.39:1
                     -> a UI colour (>= 3:1). NEVER `color:` on a dark bg.
       --accent-ink  #fff on --accent 4.62:1, on --accent-2 6.01:1 -> text OK
       --accent-text on --bg 6.86:1 · --surface 6.32:1 · --surface-2 5.69:1
                     -> the ONLY accent allowed as `color:` on a dark bg.
     --accent-2 is the DEEP end of the CTA gradient, not a lighter one:
     TeamAlpha's #d12b3a -> #ef4a57 puts white at 3.6:1 on the light end.
     Running the gradient deep -> bright keeps the same crimson-lit look and
     every point of it clears 4.5:1 for white. */
  --accent: #dd2f3d;
  --accent-2: #bc2834;
  --accent-ink: #ffffff;
  --accent-text: #ff6b78;
  --ok: #3dd68c;
  --warn: #f5a623;
  /* orange-red, not the old pink-red: accent is now red too, and a failure
     must not read as "the brand colour". Colour is never the only signal
     (DESIGN.md §5) — every error component still carries icon + text.
     #ff7a59 on --surface 6.78:1. */
  --danger: #ff7a59;
  --info: #5aa9ff;

  --radius-s: 8px;
  --radius-m: 12px;
  --radius-l: 16px;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.4);
  --shadow-2: 0 8px 24px rgb(0 0 0 / 0.45);

  --font-ui: "Inter", "Noto Sans Myanmar", system-ui, sans-serif;
  --font-my: "Noto Sans Myanmar", "Padauk", "Myanmar Text", system-ui, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;

  /* derived, not in §2: tints of the palette used for soft fills. Kept here
     so no page invents its own alpha values. */
  --accent-soft: rgb(221 47 61 / 0.16);
  --ok-soft: rgb(61 214 140 / 0.14);
  --warn-soft: rgb(245 166 35 / 0.14);
  --danger-soft: rgb(255 122 89 / 0.14);
  --info-soft: rgb(90 169 255 / 0.14);
  --hairline: rgb(255 255 255 / 0.04);

  /* the one CTA gradient, so no card re-invents its angle or its stops */
  --accent-grad: linear-gradient(135deg, var(--accent-2), var(--accent));
  --accent-glow: 0 6px 18px rgb(221 47 61 / 0.34);

  --nav-h: 56px;
  /* 0 since card U: the bottom tab bar is gone and the drawer is the
     navigation at every width. The token stays because studio.css still
     offsets its mobile dock and its toast lift from it. */
  --tabbar-h: 0px;
  --drawer-w: 250px;
  --page-max: 1040px;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ---------------------------------------------------------------- reset */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 22px;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

/* the studio surface: a faint warm glow at the top and a dot grid, so the
   dark background reads as a designed surface rather than flat black. */
body.rm-body {
  background-image:
    radial-gradient(900px 420px at 50% -180px, rgb(221 47 61 / 0.11), transparent 70%),
    radial-gradient(700px 380px at 100% 0, rgb(90 169 255 / 0.05), transparent 70%),
    radial-gradient(rgb(255 255 255 / 0.028) 1px, transparent 1px);
  background-size: auto, auto, 22px 22px;
  background-attachment: fixed, fixed, fixed;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd {
  margin: 0;
}

ul, ol {
  margin: 0;
  padding: 0;
}

img, svg, video, canvas, audio {
  max-width: 100%;
}

img, svg, video, canvas {
  display: block;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

a {
  color: var(--info);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

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

::selection {
  background: var(--accent-soft);
}

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: var(--space-5) 0;
}

/* ------------------------------------------------------------ type scale
   display 28/34 · h1 22/28 · h2 18/24 · body 15/22 · small 13/18 · mono 13 */
.t-display { font-size: 28px; line-height: 34px; font-weight: 700; letter-spacing: -0.02em; }
.t-h1 { font-size: 22px; line-height: 28px; font-weight: 600; letter-spacing: -0.01em; }
.t-h2 { font-size: 18px; line-height: 24px; font-weight: 600; }
.t-body { font-size: 15px; line-height: 22px; font-weight: 400; }
.t-small { font-size: 13px; line-height: 18px; }
.t-mono { font-family: var(--font-mono); font-size: 13px; line-height: 18px; }

.t-2 { color: var(--text-2); }
.t-3 { color: var(--text-3); }
.t-ok { color: var(--ok); }
.t-warn { color: var(--warn); }
.t-danger { color: var(--danger); }
/* --accent is a UI colour (3.77:1 on --surface); text uses --accent-text. */
.t-accent { color: var(--accent-text); }

/* Burmese runs ~15 % taller (DESIGN.md §2). */
[lang="my"] {
  font-family: var(--font-my);
  line-height: 1.7;
}

/* ----------------------------------------------------------- bilingual
   RM.t(key) renders ONE language at a time: <span class="t"><span lang="en">…
   </span></span> or the lang="my" span, matching RM.lang (a toggle in the
   nav/login switches it — see strings.js). Inline by default (buttons,
   chips, table cells); block containers make it a block line instead. */
.t { display: inline; }

.empty .t,
.t-display .t,
.t-h1 .t,
.t-h2 .t,
.field > .label .t,
.banner-body .t,
.toast-body .t,
.errtext .t {
  display: block;
}

/* --------------------------------------------------------------- layout */
.page {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--space-4);
}

.stack > * + * { margin-top: var(--space-4); }
.stack-2 > * + * { margin-top: var(--space-2); }
.stack-3 > * + * { margin-top: var(--space-3); }
.stack-5 > * + * { margin-top: var(--space-5); }

.row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.row-end { margin-left: auto; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (min-width: 900px) {
  .page { padding: var(--space-6) var(--space-5); }
}

/* First-paint guard. ui.js adds .rm-ready to <html> two frames after
   DOMContentLoaded. Until then transitions are off, so state that JS applies
   during boot (a selected tab, a checked toggle, the active step) paints in
   its final form instead of animating in from the default — which is both
   nicer on a slow phone and the only way a headless screenshot with
   --virtual-time-budget captures the real state (virtual time freezes a
   running transition at frame 0). Animations are deliberately NOT disabled:
   the skeleton shimmer must run. */
html:not(.rm-ready) *,
html:not(.rm-ready) *::before,
html:not(.rm-ready) *::after {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
