/* SocioHan design tokens: «Estudi» (ADR 0028; catalogue in docs/design/estudi-stage2.md).
   One file for the app (pages/static/css/tokens.css) and a byte-identical copy for the public
   site (site/assets/tokens.css; `make site-check` compares them). Contrast pairs are checked by
   scripts/check_contrast.py and the chart and class colours by scripts/check_palette.py, in
   light and dark (tests/web/test_design_tokens.py, test_palette.py): change a colour, run them.
   Themes: light by default; dark follows the system unless <html data-theme="light|dark">
   (the person's choice, a cookie read by the server) says otherwise. The dark values are
   written twice (system and chosen); a test keeps both blocks identical. */
:root {
  color-scheme: light dark;

  /* Paper, sheet and ink: warm printed paper, white sheets, near-black ink. */
  --c-paper: #f3f0e8;
  --c-paper-2: #e9e5db;
  --c-sheet: #ffffff;
  --c-ink: #1a1b1f;
  --c-ink-2: #45474f;
  --c-ink-3: #686a72;

  /* Roles (the names every stylesheet uses). */
  --c-bg: #f3f0e8;
  --c-surface: #f3f0e8;
  --c-raised: #ffffff;
  --c-well: #e9e5db;
  --c-text: #1a1b1f;
  --c-text-muted: #5e6068;
  --c-placeholder: #686a72;

  /* Accent: ink. Primary buttons are ink on paper; links are ink, underlined. */
  --c-primary: #1a1b1f;
  --c-primary-hover: #34363d;
  --c-primary-soft: #e9e5db;
  --c-on-primary: #f8f6f1;
  --c-info: #3a5487;
  --c-info-soft: #dde2ec;
  --c-info-text: #34507f;

  /* Semantic: a strong colour (rules, glyphs), a tint and the text on the tint. Never the
     only cue: always a glyph or a word with it. */
  --c-success: #2e6b4e;
  --c-success-soft: #dcebe2;
  --c-success-text: #285e44;
  --c-warning: #7a5a14;
  --c-warning-soft: #f2e7cb;
  --c-warning-text: #6b4f11;
  --c-danger: #a8362c;
  --c-danger-soft: #f3deda;
  --c-danger-text: #96302a;
  --c-on-danger: #ffffff;
  --c-accent-2: #7f4268;
  --c-accent-2-soft: #efe2ea;
  --c-accent-2-text: #733b5e;
  --c-neutral-soft: #e9e5db;
  --c-highlight: #f2e7cb;

  /* Lines, focus, overlay. Hairlines are decoration; a control's boundary is
     --c-border-strong (3:1, WCAG 1.4.11). */
  --c-line: rgb(26 27 31 / .09);
  --c-line-2: rgb(26 27 31 / .16);
  --c-border: #dcd7cc;
  --c-border-strong: #827e74;
  --c-focus: #1a1b1f;
  --c-overlay: rgb(18 19 23 / .32);

  /* Class groups (ADR 0028, 0021; scripts/check_palette.py): muted printed-matter inks in
     fixed order by position in the level, everywhere in the app. 1 terracotta, 2 ink blue,
     3 ochre (the owner's three), then sea green, plum, steel blue, lilac and umber; their
     lightness alternates so neighbours differ in greyscale too. A class group's colour is
     never the only cue: its name is always next to it. */
  --viz-c1: #b9573d; --viz-c2: #3a5487; --viz-c3: #d4a64a; --viz-c4: #5ca99a;
  --viz-c5: #7f4268; --viz-c6: #3d7894; --viz-c7: #a39cd4; --viz-c8: #6f4a06;
  /* The text on a class group's colour (chips, tags), 4.5:1 or more. */
  --viz-ink1: #ffffff; --viz-ink2: #ffffff; --viz-ink3: #1a1b1f; --viz-ink4: #1a1b1f;
  --viz-ink5: #ffffff; --viz-ink6: #ffffff; --viz-ink7: #1a1b1f; --viz-ink8: #ffffff;
  /* Strokes: lines, arrows and glyphs of a class group on paper (3:1 or more). */
  --viz-s1: #a44a31; --viz-s2: #3a5487; --viz-s3: #8a6a1e; --viz-s4: #3c7f72;
  --viz-s5: #7f4268; --viz-s6: #3d7894; --viz-s7: #6a62a3; --viz-s8: #6f4a06;
  /* Tints: header and tab backgrounds of a class group (ink text on them). */
  --viz-t1: #f0ddd4; --viz-t2: #dde2ec; --viz-t3: #f2e7cb; --viz-t4: #deeeeb;
  --viz-t5: #e5d9e1; --viz-t6: #d8e4ea; --viz-t7: #edebf6; --viz-t8: #e2dbcd;
  /* Grade heat «AE»: the class colour at 58 % on the sheet; ink on it 4.5:1+. */
  --viz-h1: #d69e8e; --viz-h2: #8d9cb9; --viz-h3: #e6cb96; --viz-h4: #a0cdc4;
  --viz-h5: #b591a7; --viz-h6: #8eb1c1; --viz-h7: #cac6e6; --viz-h8: #ab966f;
  /* Sociometric status: one warm ink ramp, ordered by attention needed (popular, average,
     controversial, neglected, rejected), and the text on each step. */
  --viz-st1: #b4a99a; --viz-st2: #958a7c; --viz-st3: #776d5f; --viz-st4: #5b5143; --viz-st5: #3a3125;
  --viz-st-ink1: #1a1b1f; --viz-st-ink2: #1a1b1f; --viz-st-ink3: #ffffff; --viz-st-ink4: #ffffff; --viz-st-ink5: #ffffff;
  /* Magnitude (heatmap): one slate ink wash, light to dark, and the text on each step. */
  --viz-seq1: #e2e6ee; --viz-seq2: #b5c2d8; --viz-seq3: #8a96ab; --viz-seq4: #5e697e; --viz-seq5: #333d50;
  --viz-seq-ink1: #1a1b1f; --viz-seq-ink2: #1a1b1f; --viz-seq-ink3: #1a1b1f; --viz-seq-ink4: #ffffff; --viz-seq-ink5: #ffffff;
  /* Recessive chart chrome: gridlines, the baseline, a neutral fill (unclassified). */
  --viz-grid: #e7e3da; --viz-axis: #a7a297; --viz-neutral: #cfc9bd;

  /* Typography (ADR 0028): Bricolage Grotesque for display, Geist for the interface,
     Geist Mono for small uppercase labels and indices; all self-hosted (fonts.css). */
  --font-sans: "Geist", "Geist Fallback", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Bricolage Grotesque", "Bricolage Grotesque Fallback", var(--font-sans);
  --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  /* Scale (px): 10 · 11 · 12.5 · 13.5 · 15 · 17 · 19 · 22 · 28 · 34 · 44 · 64 · 76 · 112. */
  --fs-2xs: .625rem;
  --fs-mono: .6875rem;
  --fs-xs: .78125rem;
  --fs-sm: .84375rem;
  --fs-md: .9375rem;
  --fs-lg: 1.0625rem;
  --fs-xl: 1.1875rem;
  --fs-2xl: 1.375rem;
  --fs-3xl: 1.75rem;
  --fs-4xl: 2.125rem;
  --fs-5xl: 2.75rem;
  --fs-hero: clamp(2.5rem, 1.55rem + 2.9vw, 4.75rem);
  --fs-giant: clamp(3.5rem, 1.5rem + 5.6vw, 7rem);
  /* Display tracking: tight, but letters never touch (the owner's eye, ADR 0028). */
  --track-hero: -.008em;
  --track-display: -.018em;
  --track-mono: .06em;

  /* Spacing (4-based), radii (small and deliberate), shadows (contact + ambient). */
  --sp-1: .25rem;
  --sp-2: .5rem;
  --sp-3: .75rem;
  --sp-4: 1rem;
  --sp-5: 1.375rem;
  --sp-6: 2.125rem;
  --sp-7: 2.75rem;
  --sp-8: 4rem;
  --r-sm: 2px;
  --r-md: 4px;
  --r-lg: 6px;
  --r-xl: 8px;
  /* No pills (ADR 0028): what used to be a pill is a 2 px tag; dots and switches say 50%. */
  --r-pill: 2px;
  --sh-1: 0 1px 0 rgb(26 27 31 / .04), 0 1px 2px rgb(26 27 31 / .05);
  --sh-hover: 0 0 0 1px rgb(26 27 31 / .09), 0 2px 6px -3px rgb(26 27 31 / .18);
  --sh-2: 0 1px 1px rgb(18 19 23 / .06), 0 18px 40px -18px rgb(18 19 23 / .28);
  --sh-3: 0 30px 80px -20px rgb(18 19 23 / .5);

  /* Motion: one spring (k 170, c 15, m 1; a slight overshoot) for entrances, toggles and
     sheets; quick fades for the rest. prefers-reduced-motion turns them off below. */
  --spring: linear(0, .079, .262, .481, .69, .862, .986, 1.064, 1.101, 1.11, 1.098, 1.077, 1.053, 1.031, 1.013, 1, .992, .989, .988, .99, .992, .995, .997, .999, 1);
  --spring-fallback: cubic-bezier(.2, 1.3, .3, 1);
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-draw: cubic-bezier(.3, .7, .2, 1);
  --dur-1: 120ms;
  --dur-2: 200ms;
  --dur-rise: 800ms;

  /* Widths */
  --w-content: 68rem;
  --w-wide: 96rem;
  --w-narrow: 34rem;
  --h-touch: 2.75rem;
}

/* Dark: warm dark paper (not an inversion), lifted sheets, warm light ink; the class groups
   keep their hues, tuned for the dark paper. The system's choice and the person's choice
   share one set of values (tests/web/test_design_tokens.py keeps the two blocks equal). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --c-paper: #1c1b18;
    --c-paper-2: #2c2a25;
    --c-sheet: #262420;
    --c-ink: #eee9df;
    --c-ink-2: #cdc7bb;
    --c-ink-3: #a8a296;
    --c-bg: #1c1b18;
    --c-surface: #1c1b18;
    --c-raised: #262420;
    --c-well: #2c2a25;
    --c-text: #eee9df;
    --c-text-muted: #b3ada1;
    --c-placeholder: #a8a296;
    --c-primary: #eee9df;
    --c-primary-hover: #ffffff;
    --c-primary-soft: #2c2a25;
    --c-on-primary: #1c1b18;
    --c-info: #a9bce2;
    --c-info-soft: #222b3d;
    --c-info-text: #a9bce2;
    --c-success: #8cc4a5;
    --c-success-soft: #1f3329;
    --c-success-text: #8cc4a5;
    --c-warning: #e0be72;
    --c-warning-soft: #362c17;
    --c-warning-text: #e0be72;
    --c-danger: #ee9a8f;
    --c-danger-soft: #3d201c;
    --c-danger-text: #ee9a8f;
    --c-on-danger: #1c1b18;
    --c-accent-2: #d9a8c6;
    --c-accent-2-soft: #36222e;
    --c-accent-2-text: #d9a8c6;
    --c-neutral-soft: #2c2a25;
    --c-highlight: #3d3422;
    --c-line: rgb(238 233 223 / .1);
    --c-line-2: rgb(238 233 223 / .18);
    --c-border: #3a3730;
    --c-border-strong: #86806f;
    --c-focus: #eee9df;
    --c-overlay: rgb(0 0 0 / .55);
    --viz-c1: #b05138; --viz-c2: #6a87c0; --viz-c3: #b68c36; --viz-c4: #2b7b6d;
    --viz-c5: #bb7ca5; --viz-c6: #296886; --viz-c7: #948cc6; --viz-c8: #aa7c41;
    --viz-ink1: #ffffff; --viz-ink2: #1a1b1f; --viz-ink3: #1a1b1f; --viz-ink4: #ffffff;
    --viz-ink5: #1a1b1f; --viz-ink6: #ffffff; --viz-ink7: #1a1b1f; --viz-ink8: #1a1b1f;
    --viz-s1: #c76e55; --viz-s2: #6a87c0; --viz-s3: #b68c36; --viz-s4: #3e8678;
    --viz-s5: #bb7ca5; --viz-s6: #508298; --viz-s7: #948cc6; --viz-s8: #aa7c41;
    --viz-t1: #4d3127; --viz-t2: #393f4e; --viz-t3: #4f4226; --viz-t4: #273c36;
    --viz-t5: #503d46; --viz-t6: #27373d; --viz-t7: #45414e; --viz-t8: #4b3d29;
    --viz-h1: #763e2e; --viz-h2: #4d5d7d; --viz-h3: #7a602d; --viz-h4: #29564d;
    --viz-h5: #7c576d; --viz-h6: #284b5b; --viz-h7: #666080; --viz-h8: #735733;
    --viz-st1: #6f6456; --viz-st2: #8c8173; --viz-st3: #a59a8b; --viz-st4: #c0b4a5; --viz-st5: #e1d6c6;
    --viz-st-ink1: #ffffff; --viz-st-ink2: #1a1b1f; --viz-st-ink3: #1a1b1f; --viz-st-ink4: #1a1b1f; --viz-st-ink5: #1a1b1f;
    --viz-seq1: #232e42; --viz-seq2: #3c485e; --viz-seq3: #5c6981; --viz-seq4: #8593ab; --viz-seq5: #bdcbe5;
    --viz-seq-ink1: #ffffff; --viz-seq-ink2: #ffffff; --viz-seq-ink3: #ffffff; --viz-seq-ink4: #1a1b1f; --viz-seq-ink5: #1a1b1f;
    --viz-grid: #35322c; --viz-axis: #6c665b; --viz-neutral: #57524a;
    --sh-1: 0 1px 0 rgb(0 0 0 / .25), 0 1px 2px rgb(0 0 0 / .3);
    --sh-hover: 0 0 0 1px rgb(238 233 223 / .1), 0 2px 6px -3px rgb(0 0 0 / .5);
    --sh-2: 0 1px 1px rgb(0 0 0 / .3), 0 18px 40px -18px rgb(0 0 0 / .7);
    --sh-3: 0 30px 80px -20px rgb(0 0 0 / .8);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --c-paper: #1c1b18;
  --c-paper-2: #2c2a25;
  --c-sheet: #262420;
  --c-ink: #eee9df;
  --c-ink-2: #cdc7bb;
  --c-ink-3: #a8a296;
  --c-bg: #1c1b18;
  --c-surface: #1c1b18;
  --c-raised: #262420;
  --c-well: #2c2a25;
  --c-text: #eee9df;
  --c-text-muted: #b3ada1;
  --c-placeholder: #a8a296;
  --c-primary: #eee9df;
  --c-primary-hover: #ffffff;
  --c-primary-soft: #2c2a25;
  --c-on-primary: #1c1b18;
  --c-info: #a9bce2;
  --c-info-soft: #222b3d;
  --c-info-text: #a9bce2;
  --c-success: #8cc4a5;
  --c-success-soft: #1f3329;
  --c-success-text: #8cc4a5;
  --c-warning: #e0be72;
  --c-warning-soft: #362c17;
  --c-warning-text: #e0be72;
  --c-danger: #ee9a8f;
  --c-danger-soft: #3d201c;
  --c-danger-text: #ee9a8f;
  --c-on-danger: #1c1b18;
  --c-accent-2: #d9a8c6;
  --c-accent-2-soft: #36222e;
  --c-accent-2-text: #d9a8c6;
  --c-neutral-soft: #2c2a25;
  --c-highlight: #3d3422;
  --c-line: rgb(238 233 223 / .1);
  --c-line-2: rgb(238 233 223 / .18);
  --c-border: #3a3730;
  --c-border-strong: #86806f;
  --c-focus: #eee9df;
  --c-overlay: rgb(0 0 0 / .55);
  --viz-c1: #b05138; --viz-c2: #6a87c0; --viz-c3: #b68c36; --viz-c4: #2b7b6d;
  --viz-c5: #bb7ca5; --viz-c6: #296886; --viz-c7: #948cc6; --viz-c8: #aa7c41;
  --viz-ink1: #ffffff; --viz-ink2: #1a1b1f; --viz-ink3: #1a1b1f; --viz-ink4: #ffffff;
  --viz-ink5: #1a1b1f; --viz-ink6: #ffffff; --viz-ink7: #1a1b1f; --viz-ink8: #1a1b1f;
  --viz-s1: #c76e55; --viz-s2: #6a87c0; --viz-s3: #b68c36; --viz-s4: #3e8678;
  --viz-s5: #bb7ca5; --viz-s6: #508298; --viz-s7: #948cc6; --viz-s8: #aa7c41;
  --viz-t1: #4d3127; --viz-t2: #393f4e; --viz-t3: #4f4226; --viz-t4: #273c36;
  --viz-t5: #503d46; --viz-t6: #27373d; --viz-t7: #45414e; --viz-t8: #4b3d29;
  --viz-h1: #763e2e; --viz-h2: #4d5d7d; --viz-h3: #7a602d; --viz-h4: #29564d;
  --viz-h5: #7c576d; --viz-h6: #284b5b; --viz-h7: #666080; --viz-h8: #735733;
  --viz-st1: #6f6456; --viz-st2: #8c8173; --viz-st3: #a59a8b; --viz-st4: #c0b4a5; --viz-st5: #e1d6c6;
  --viz-st-ink1: #ffffff; --viz-st-ink2: #1a1b1f; --viz-st-ink3: #1a1b1f; --viz-st-ink4: #1a1b1f; --viz-st-ink5: #1a1b1f;
  --viz-seq1: #232e42; --viz-seq2: #3c485e; --viz-seq3: #5c6981; --viz-seq4: #8593ab; --viz-seq5: #bdcbe5;
  --viz-seq-ink1: #ffffff; --viz-seq-ink2: #ffffff; --viz-seq-ink3: #ffffff; --viz-seq-ink4: #1a1b1f; --viz-seq-ink5: #1a1b1f;
  --viz-grid: #35322c; --viz-axis: #6c665b; --viz-neutral: #57524a;
  --sh-1: 0 1px 0 rgb(0 0 0 / .25), 0 1px 2px rgb(0 0 0 / .3);
  --sh-hover: 0 0 0 1px rgb(238 233 223 / .1), 0 2px 6px -3px rgb(0 0 0 / .5);
  --sh-2: 0 1px 1px rgb(0 0 0 / .3), 0 18px 40px -18px rgb(0 0 0 / .7);
  --sh-3: 0 30px 80px -20px rgb(0 0 0 / .8);
}
:root[data-theme="light"] { color-scheme: light; }

/* Dark mode never prints: paper gets the light theme (whatever the person chose). */
@media print {
  :root, :root[data-theme] {
    color-scheme: light;
    --c-paper: #f3f0e8;
    --c-paper-2: #e9e5db;
    --c-sheet: #ffffff;
    --c-ink: #1a1b1f;
    --c-ink-2: #45474f;
    --c-ink-3: #686a72;
    --c-bg: #f3f0e8;
    --c-surface: #f3f0e8;
    --c-raised: #ffffff;
    --c-well: #e9e5db;
    --c-text: #1a1b1f;
    --c-text-muted: #5e6068;
    --c-placeholder: #686a72;
    --c-primary: #1a1b1f;
    --c-primary-hover: #34363d;
    --c-primary-soft: #e9e5db;
    --c-on-primary: #f8f6f1;
    --c-info: #3a5487;
    --c-info-soft: #dde2ec;
    --c-info-text: #34507f;
    --c-success: #2e6b4e;
    --c-success-soft: #dcebe2;
    --c-success-text: #285e44;
    --c-warning: #7a5a14;
    --c-warning-soft: #f2e7cb;
    --c-warning-text: #6b4f11;
    --c-danger: #a8362c;
    --c-danger-soft: #f3deda;
    --c-danger-text: #96302a;
    --c-on-danger: #ffffff;
    --c-accent-2: #7f4268;
    --c-accent-2-soft: #efe2ea;
    --c-accent-2-text: #733b5e;
    --c-neutral-soft: #e9e5db;
    --c-highlight: #f2e7cb;
    --c-line: rgb(26 27 31 / .09);
    --c-line-2: rgb(26 27 31 / .16);
    --c-border: #dcd7cc;
    --c-border-strong: #827e74;
    --c-focus: #1a1b1f;
    --c-overlay: rgb(18 19 23 / .32);
    --viz-c1: #b9573d;
    --viz-c2: #3a5487;
    --viz-c3: #d4a64a;
    --viz-c4: #5ca99a;
    --viz-c5: #7f4268;
    --viz-c6: #3d7894;
    --viz-c7: #a39cd4;
    --viz-c8: #6f4a06;
    --viz-ink1: #ffffff;
    --viz-ink2: #ffffff;
    --viz-ink3: #1a1b1f;
    --viz-ink4: #1a1b1f;
    --viz-ink5: #ffffff;
    --viz-ink6: #ffffff;
    --viz-ink7: #1a1b1f;
    --viz-ink8: #ffffff;
    --viz-s1: #a44a31;
    --viz-s2: #3a5487;
    --viz-s3: #8a6a1e;
    --viz-s4: #3c7f72;
    --viz-s5: #7f4268;
    --viz-s6: #3d7894;
    --viz-s7: #6a62a3;
    --viz-s8: #6f4a06;
    --viz-t1: #f0ddd4;
    --viz-t2: #dde2ec;
    --viz-t3: #f2e7cb;
    --viz-t4: #deeeeb;
    --viz-t5: #e5d9e1;
    --viz-t6: #d8e4ea;
    --viz-t7: #edebf6;
    --viz-t8: #e2dbcd;
    --viz-h1: #d69e8e;
    --viz-h2: #8d9cb9;
    --viz-h3: #e6cb96;
    --viz-h4: #a0cdc4;
    --viz-h5: #b591a7;
    --viz-h6: #8eb1c1;
    --viz-h7: #cac6e6;
    --viz-h8: #ab966f;
    --viz-st1: #b4a99a;
    --viz-st2: #958a7c;
    --viz-st3: #776d5f;
    --viz-st4: #5b5143;
    --viz-st5: #3a3125;
    --viz-st-ink1: #1a1b1f;
    --viz-st-ink2: #1a1b1f;
    --viz-st-ink3: #ffffff;
    --viz-st-ink4: #ffffff;
    --viz-st-ink5: #ffffff;
    --viz-seq1: #e2e6ee;
    --viz-seq2: #b5c2d8;
    --viz-seq3: #8a96ab;
    --viz-seq4: #5e697e;
    --viz-seq5: #333d50;
    --viz-seq-ink1: #1a1b1f;
    --viz-seq-ink2: #1a1b1f;
    --viz-seq-ink3: #1a1b1f;
    --viz-seq-ink4: #ffffff;
    --viz-seq-ink5: #ffffff;
    --viz-grid: #e7e3da;
    --viz-axis: #a7a297;
    --viz-neutral: #cfc9bd;
    --sh-1: none;
    --sh-hover: none;
    --sh-2: none;
    --sh-3: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}
