/* TableSync design tokens — Adam Analytics Brand Standard v4.0 "Graphite".
   Governing authority: J:\Adam Analytics\aaReference\brand-v4\BRAND-STANDARD.md
   (Sections 3 colour, 4 typography, 5 space, 6 form, 11 the Slop Index, 14 tokens).
   RM41 replaces the RM23 "Adventure Module, After Dark" world, which was itself
   the defect: cyan/magenta-on-dark spot colours (slop C3/C4), 3px/6px radii (DS3),
   a drop shadow (V5) and a system-ui-only stack (T9/DS1).

   Rules that decide most questions here:
     DS2  never hard-code a hex — use the token.
     DS3  every border-radius is 0. The single exception is a combatant token,
          which is a round 28 mm mini base, not a UI corner (req 7.2).
     6.2  depth is value + hairline + space. No shadow, no blur, no glow, no gradient.
     5.1  the accent is spent once per view. In the cockpit that role is the active turn.

   Dark is TableSync's default surface (req 3.2) — the DM operates in a dim room.
   That default is stamped as <html data-theme="dark"> in the three surface documents;
   the light :root block and the prefers-color-scheme block below keep the light
   theme correct and reachable rather than broken. */

/* ---------------------------------------------------------------------------
   Faces — vendored woff2, Latin subset, served locally (req 4.1: offline-first,
   no CDN, no network font fetch). Files live beside this stylesheet in css/fonts/.
   Brand 4.1 assigns each face one job: Spectral reads, Plex Sans operates,
   Plex Mono measures. Archivo Black is retired (req 4.3).
   --------------------------------------------------------------------------- */

/* IBM Plex Sans ships from Google Fonts as a VARIABLE font: one file carrying a
   wght axis (verified with fontTools — axis wght min=100 default=400 max=700,
   7 named instances). Task 1 fetched it once per weight and got three
   byte-identical copies, 45,712 B each. One @font-face with a weight range
   covers 400/500/600 from a single file and saves 91,424 B on an offline-first
   app. Spectral and Plex Mono are static and keep one file per weight. */
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('fonts/IBMPlexSans-Variable.woff2') format('woff2');
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('fonts/IBMPlexMono-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('fonts/IBMPlexMono-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-Light.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* ---------------------------------------------------------------------------
   Graphite v4.0 — brand Section 14.1, VERBATIM. Do not edit these values here;
   they are owned by J:\Adam Analytics\aaReference\brand-v4\BRAND-STANDARD.md.
   This is the definition site, and the only place in TableSync's CSS where a
   colour literal is legitimate (req 3.3).
   --------------------------------------------------------------------------- */

:root {
  /* Ground */
  --aa-ground:        #E9EAE7;
  --aa-sheet:        #FCFCFB;
  --aa-recess:         #DFE1DD;

  /* Ink */
  --aa-ink:          #16191A;
  --aa-ink-body:     #33393B;
  --aa-ink-muted:    #626B6C;
  --aa-hairline:     #CBCEC9;
  --aa-rule:      #A9AEA8;

  /* Accent */
  --aa-accent:       #7A2320;
  --aa-accent-hover: #5C1A17;
  --aa-accent-wash:  rgba(122, 35, 32, 0.06);

  /* Status */
  --aa-ok:   #2F5D4A;
  --aa-warn: #7A6220;

  /* Series */
  --aa-s1: #1F2425;  --aa-s2: #7A2320;  --aa-s3: #2F587B;
  --aa-s4: #8B5E43;  --aa-s5: #4F8771;  --aa-s6: #AA9046;

  /* Type */
  --aa-read:    'Spectral', 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --aa-operate: 'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --aa-measure: 'IBM Plex Mono', 'SF Mono', Consolas, monospace;

  --t-display: 3.25rem;  --t-1: 2.5625rem; --t-2: 2.0625rem;
  --t-3: 1.625rem;       --t-4: 1.3125rem; --t-body: 1.0625rem;
  --t-ui: 0.875rem;      --t-meta: 0.75rem;

  /* Space */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 24px;  --s-6: 40px;  --s-8: 64px;  --s-10: 96px;  --s-12: 144px;

  /* Layout */
  --aa-container: 1180px;
  --aa-prose:     34rem;
  --aa-radius:    0;

  /* Motion */
  --aa-dur-state: 140ms;
  --aa-dur-enter: 220ms;
  --aa-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --aa-ground: #131617;  --aa-sheet: #1B1F20;    --aa-recess: #0E1112;
    --aa-ink: #E8EAE6;    --aa-ink-body: #C2C7C4; --aa-ink-muted: #8A918F;
    --aa-hairline: #2C3234;  --aa-rule: #414749;
    --aa-accent: #C9695F; --aa-accent-hover: #E08A80;
    --aa-accent-wash: rgba(201, 105, 95, 0.10);
    --aa-ok: #6FAE8C; --aa-warn: #C2A159;
    --aa-s1: #DEE1E2; --aa-s2: #D9857B; --aa-s3: #8AAECD;
    --aa-s4: #C79A6E; --aa-s5: #6FAE8C; --aa-s6: #C2A159;
  }
}

:root[data-theme="dark"] {
  --aa-ground: #131617;  --aa-sheet: #1B1F20;    --aa-recess: #0E1112;
  --aa-ink: #E8EAE6;    --aa-ink-body: #C2C7C4; --aa-ink-muted: #8A918F;
  --aa-hairline: #2C3234;  --aa-rule: #414749;
  --aa-accent: #C9695F; --aa-accent-hover: #E08A80;
  --aa-accent-wash: rgba(201, 105, 95, 0.10);
  --aa-ok: #6FAE8C; --aa-warn: #C2A159;
  --aa-s1: #DEE1E2; --aa-s2: #D9857B; --aa-s3: #8AAECD;
  --aa-s4: #C79A6E; --aa-s5: #6FAE8C; --aa-s6: #C2A159;
}

/* ---------------------------------------------------------------------------
   TableSync layer — semantic aliases ONLY. Every value below resolves to a
   brand token. Nothing here introduces a new hex, a new radius, or a shadow.
   If a surface needs a colour that is not reachable from this list, the answer
   is a new alias to an existing brand token, never a literal.
   --------------------------------------------------------------------------- */

:root {
  --tf-board:      var(--aa-recess);        /* the board well behind the canvas */
  --tf-panel:      var(--aa-sheet);         /* panel and card ground */
  --tf-panel-edge: var(--aa-hairline);      /* panel edge — a hairline, never a shadow */
  --tf-now-edge:   var(--aa-rule);          /* the Now zone's boundary band (brand 6.3) */
  --tf-turn:       var(--aa-accent);        /* rubrication: the one accent role (req 1.7, 5.1) */
  --tf-turn-wash:  var(--aa-accent-wash);   /* the active turn's row highlight (brand 3.4) */
}

/* ---------------------------------------------------------------------------
   Browser-surface theming, in brand tokens. Radius 0 throughout (DS3);
   the focus ring is the brand's own: 2px --aa-accent, offset 2px, never removed
   (brand 6.6). The accent appearing here is that mandated ring, not a second
   accent role.
   --------------------------------------------------------------------------- */

::selection {
  background: var(--aa-accent-wash);   /* brand 3.4: the wash is for row highlight and selection */
  color: var(--aa-ink);
}

html, body {
  caret-color: var(--aa-accent);
}

/* thin themed scrollbars */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--aa-rule) var(--aa-recess);
}
*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
*::-webkit-scrollbar-track {
  background: var(--aa-recess);
}
*::-webkit-scrollbar-thumb {
  /* --aa-rule is a step above the recess track: visible at rest, still muted.
     Hover steps up to --aa-ink-muted rather than the accent, because the accent
     is spent once per view and a scrollbar is not that role. */
  background: var(--aa-rule);
  /* Literal 0, not var(--aa-radius). The brand radius scale IS zero and can
     never hold another value, so the indirection buys nothing -- and the
     auditor's DS3 check compares the declared string against '0'/'0px', so a
     token reference flags as a violation while resolving to exactly 0.
     Measured: DS3 reported var(--aa-radius) on index and player. */
  border-radius: 0;
}
*::-webkit-scrollbar-thumb:hover {
  background: var(--aa-ink-muted);
}

:focus-visible {
  outline: 2px solid var(--aa-accent);
  outline-offset: 2px;
}

/* tabular numerals on data/stat tables (brand 4.3) */
/* RM403: .tf-data and [data-tf-data] were in no page - no HTML attribute, no JS string, no
   runtime-built class name. Real tables keep their tabular figures. */
table {
  font-variant-numeric: tabular-nums;
}

/* RM196: prefers-reduced-motion. Nothing in the app honoured it: 140-220 ms
   transitions ran on every surface. The motion tokens drop to effectively zero
   and any literal transition or animation is cut short, for every page that
   loads this sheet (DM, projector, player). */
@media (prefers-reduced-motion: reduce) {
  :root { --aa-dur-state: 1ms; --aa-dur-enter: 1ms; }
  *, *::before, *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}
