/* Playbakk design system v2: tokens (design/tokens.json is the cross-app source of truth; research QLAAS_LANGUAGE,
   ADDENDUM §1–§2). Loaded before themes.css and app.css. Screen CSS uses only these tokens: no hard-coded colour
   outside this file.
   - Light first: the default palette (bare :root, before JS and without it) is Paper, the Ink theme's light twin.
   - Palettes: one block per palette, applied by html[data-theme][data-scheme] (set by web/theme.ts), by a per-chat
     tone of the same polarity (.conv[data-tone="<theme>"], local only), and by the call surface, which always takes
     the DARK twin of the current theme (.call-surface or [data-call]).
   - Every value below is proven by research/tools/themes.py and test/a11y-contrast.test.ts: text ≥ 4.5:1 (Contrast
     ≥ 7:1) on bg, s1, s2, solid, their bubble, the tonal bubble, the motif and worst-case glass (the tab-bar
     island included); my text on my bubble; marker, control line ≥ 3:1. No gradients, no shadows anywhere. */

:root {
  /* type: Sora (variable, web/fonts/sora.woff2); sizes in rem so the text-size dial (html font-size) scales them.
     Light weights, large and open: display 40–56 / 250, list titles 28–32 / 300 (clamp: adapted to the screen). */
  --font: "Sora", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --fs-display: clamp(2.5rem, 2rem + 2.2vw, 3.5rem); --lh-display: 1.08; --tr-display: -.04em;
  --fs-title: clamp(1.75rem, 1.65rem + .45vw, 2rem); --lh-title: 1.2; --tr-title: -.03em;
  --fs-heading: 1.125rem; --lh-heading: 1.5rem; --tr-heading: -.015em;
  --fs-lead: 1.0625rem; --lh-lead: 1.625rem;
  --fs-body: .9375rem; --lh-body: 1.375rem; --tr-body: -.006em;
  --fs-body-s: .8125rem; --lh-body-s: 1.25rem; --tr-body-s: -.004em;
  --fs-label: .6875rem; --lh-label: 1rem; --tr-label: .16em;
  --fs-btn: .75rem; --tr-btn: .14em; --tt-label: uppercase;
  --fs-micro: .6875rem; --lh-micro: .875rem;
  --fs-mono: .75rem; --lh-mono: 1rem;
  --w-plus: 0;
  /* space: 4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 / 96 */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-6: 24px; --sp-8: 32px; --sp-12: 48px; --sp-16: 64px; --sp-24: 96px;
  --gutter: 24px; --card-pad: 24px;
  /* shape: one curvature. Every control is a pill; cards 28 (32 from 760); panes and sheet tops clamp(24, 3vw, 40);
     rows and inner tiles 20; bubbles 22 with 8 px joins (themes.css: the corner dial varies these, never sharp).
     corner-shape: superellipse(1.25) wherever a radius below the pill is used (app.css, @supports). */
  --r-pill: 999px; --r-card: 28px; --r-pane: clamp(24px, 3vw, 40px); --r-row: 20px; --r-in: 16px; --r-field: 28px;
  --q-shape: superellipse(1.25);
  /* controls */
  --tap: 48px; --tap-primary: 56px; --tap-min: 44px;
  /* motion: colour and background 240 ms ease-soft; sheets and panes enter 480 ms ease-settle (opacity + 12 px) and
     leave in 240 ms; nothing else moves. No springs, no scale, no looping animation. */
  --ease-soft: cubic-bezier(.4, 0, .2, 1); --ease-settle: cubic-bezier(.22, 1, .36, 1);
  --d0: 0ms; --d1: 120ms; --d2: 240ms; --d3: 480ms;
  --tint: background-color var(--d2) var(--ease-soft), color var(--d2) var(--ease-soft);
  --blur: blur(24px) saturate(0);
  --scrim: rgb(0 0 0 / .4);
}
@media (min-width: 760px) { :root { --r-card: 32px; --card-pad: 32px; } }
/* scripts without case, or where tracking breaks joining (Arabic, Persian, Urdu, Hebrew, Hindi): no forced tracking */
:root:is(:lang(ar), :lang(fa), :lang(ur), :lang(he), :lang(hi)) { --tr-label: 0em; --tr-btn: 0em; --tr-display: 0em; --tr-title: 0em; --tr-heading: 0em; --tr-body: 0em; --tr-body-s: 0em; }

/* Derived per palette scope (custom properties resolve where they are declared, so every scope that swaps a
   palette re-declares them, previews and theme tiles included): glass = bg at 90 %; the island (the floating tab
   bar) = the raised tone s2 at 94 %; the motif ink = t1 at 3.5 % (the mark at 3 %) on the dark twins and 6 % (mark 5 %)
   on the light twins (ceilings 4 % dark, 6 % light; amended 6 Oct 2026); focus = t1; the field
   underline = the control line (≥ 3:1); weights (Contrast adds --w-plus = 50 to each). --rec/--rec-t/--hi alias
   the v1 names older modules still use. */
:root, [data-theme], [data-tone], .call-surface, [data-call] {
  --w-display: calc(250 + var(--w-plus)); --w-title: calc(300 + var(--w-plus)); --w-heading: calc(400 + var(--w-plus));
  --w-body: calc(350 + var(--w-plus)); --w-label: calc(500 + var(--w-plus)); --w-strong: calc(550 + var(--w-plus));
  --glass: color-mix(in srgb, var(--bg) 90%, transparent);
  --pattern: color-mix(in srgb, var(--t1) 3.5%, transparent);
  --pattern-mark: color-mix(in srgb, var(--t1) 3%, transparent);
  --island: color-mix(in srgb, var(--s2) 94%, transparent);
  --focus: var(--t1); --field-line: var(--ctl);
  --rec: var(--danger); --rec-t: var(--danger); --hi: transparent;
  /* panes (knock cards, intent cards, spec sheets, the door row): the raised tone, and the tone a control inside a
     pane stands on. Dark twins keep the half step (s1, controls s2: Qlaas ink-2 on ink). Light twins take the stone
     step like Qlaas's panes (s2, measured 1.17:1 on paper; s1 is 1.08:1 and read as a stain rather than a pane), and
     controls inside them stand on the solid tone (paper on stone). Both are proven text grounds (themes.py). */
  --card: var(--s1); --on-card: var(--s2);
}
/* light twins: the motif at 6 % (mark 5 %), the light ceiling; at the dark values it did not register on paper. The
   call twins inside a light page stay dark and keep the derived 3.5 % (they never carry a thread motif). */
[data-scheme="light"], [data-scheme="light"] [data-tone] {
  --pattern: color-mix(in srgb, var(--t1) 6%, transparent);
  --pattern-mark: color-mix(in srgb, var(--t1) 5%, transparent);
}
[data-scheme="light"], [data-scheme="light"] [data-tone] { --card: var(--s2); --on-card: var(--solid); }
[data-scheme="light"] :is(.call-surface, [data-call]) { --card: var(--s1); --on-card: var(--s2); }

/* ---- palettes: generated by research/tools/themes.py --css (do not hand-edit; change the script, re-run, re-paste) ---- */
/* paper */
:root,
[data-theme="ink"][data-scheme="light"],
[data-scheme="light"] [data-tone="ink"] {
  color-scheme:light;--bg:#f4f3ef;--s1:#eceae6;--s2:#e4e2dc;--solid:#faf9f7;--line:#d4d4d0;--ctl:#838280;--t1:#121211;--t2:#5e5c57;--t3:#636361;--inv-bg:#121211;--inv-t:#f4f3ef;--inv-t2:#a9a7a1;--bub-me:#121211;--bub-me-t:#f4f3ef;--bub-them:#e9e7e2;--bub-tonal:#d6d4cf;--marker:#7a6236;--danger:#a8341f;
}
/* ink */
[data-theme="ink"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="ink"],
[data-theme="ink"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#121211;--s1:#1b1b19;--s2:#232321;--solid:#2a2a28;--line:#363634;--ctl:#777570;--t1:#f4f3ef;--t2:#a9a7a1;--t3:#94928c;--inv-bg:#f4f3ef;--inv-t:#121211;--inv-t2:#4d4c48;--bub-me:#e4e2dc;--bub-me-t:#121211;--bub-them:#232321;--bub-tonal:#393937;--marker:#b09260;--danger:#ff7a6e;
}
/* ice */
[data-theme="ledger"][data-scheme="light"],
[data-scheme="light"] [data-tone="ledger"] {
  color-scheme:light;--bg:#eff1f2;--s1:#e7eaec;--s2:#dfe3e6;--solid:#f7f8f8;--line:#d0d2d3;--ctl:#808385;--t1:#121518;--t2:#545759;--t3:#626466;--inv-bg:#191c1f;--inv-t:#eff1f2;--inv-t2:#999c9e;--bub-me:#191c1f;--bub-me-t:#eff1f2;--bub-them:#e4e7ea;--bub-tonal:#c8cccf;--marker:#7a6236;--danger:#a8341f;
}
/* graphite */
[data-theme="ledger"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="ledger"],
[data-theme="ledger"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#1a1d20;--s1:#1f2225;--s2:#25292c;--solid:#2b2f33;--line:#31363a;--ctl:#717a80;--t1:#e8ecef;--t2:#aab3b8;--t3:#8e989e;--inv-bg:#e8ecef;--inv-t:#1a1d20;--inv-t2:#4b545a;--bub-me:#dde2e6;--bub-me-t:#1a1d20;--bub-them:#272b2f;--bub-tonal:#3a3e42;--marker:#b09260;--danger:#ff7d72;
}
/* sage */
[data-theme="grove"][data-scheme="light"],
[data-scheme="light"] [data-tone="grove"] {
  color-scheme:light;--bg:#f0f2ed;--s1:#e8ece4;--s2:#e0e5dc;--solid:#f8f8f6;--line:#d1d3ce;--ctl:#80847f;--t1:#111611;--t2:#545853;--t3:#616560;--inv-bg:#181d18;--inv-t:#f0f2ed;--inv-t2:#9a9d98;--bub-me:#181d18;--bub-me-t:#f0f2ed;--bub-them:#e5e9e1;--bub-tonal:#c9cec6;--marker:#76603a;--danger:#a32a22;
}
/* moss */
[data-theme="grove"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="grove"],
[data-theme="grove"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#121a15;--s1:#17201a;--s2:#1d2720;--solid:#232e26;--line:#29352c;--ctl:#68796c;--t1:#e4eae2;--t2:#a6b4a9;--t3:#8a9a8e;--inv-bg:#e4eae2;--inv-t:#121a15;--inv-t2:#465a4b;--bub-me:#d9e1d7;--bub-me-t:#121a15;--bub-them:#1f2922;--bub-tonal:#353e37;--marker:#b09260;--danger:#ff7b6f;
}
/* linen */
[data-theme="studio"][data-scheme="light"],
[data-scheme="light"] [data-tone="studio"] {
  color-scheme:light;--bg:#f5f0ec;--s1:#eee8e2;--s2:#e8dfd9;--solid:#faf8f6;--line:#d7d1ce;--ctl:#888180;--t1:#1c1215;--t2:#5d5556;--t3:#6a6262;--inv-bg:#23191b;--inv-t:#f5f0ec;--inv-t2:#a19a98;--bub-me:#23191b;--bub-me-t:#f5f0ec;--bub-them:#ece4df;--bub-tonal:#d4cbc5;--marker:#7a6236;--danger:#a32a22;
}
/* oxblood */
[data-theme="studio"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="studio"],
[data-theme="studio"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#24151a;--s1:#2a1a1f;--s2:#311f25;--solid:#38252b;--line:#3e2a31;--ctl:#8a7074;--t1:#f1e8e4;--t2:#c4b0ad;--t3:#a8918f;--inv-bg:#f1e8e4;--inv-t:#24151a;--inv-t2:#6b4a4c;--bub-me:#ebe0dc;--bub-me-t:#24151a;--bub-them:#33212a;--bub-tonal:#48373e;--marker:#b09260;--danger:#ff8478;
}
/* night */
[data-theme="night"],
[data-scheme="dark"] [data-tone="night"],
[data-theme="night"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#0b0b0a;--s1:#111110;--s2:#171715;--solid:#1c1c1a;--line:#222220;--ctl:#686a63;--t1:#d6d6ce;--t2:#a1a399;--t3:#85877f;--inv-bg:#d6d6ce;--inv-t:#0b0b0a;--inv-t2:#4a4c45;--bub-me:#262722;--bub-me-t:#d6d6ce;--bub-them:#151513;--bub-tonal:#2e2e2b;--marker:#b09260;--danger:#f07468;
}
/* contrast-light */
[data-theme="contrast"][data-scheme="light"],
[data-scheme="light"] [data-tone="contrast"] {
  color-scheme:light;--bg:#ffffff;--s1:#f4f4f0;--s2:#eaeae4;--solid:#ffffff;--line:#6b6e64;--ctl:#3a3c36;--t1:#000000;--t2:#1d1e1b;--t3:#34362f;--inv-bg:#000000;--inv-t:#ffffff;--inv-t2:#d4d5ce;--bub-me:#000000;--bub-me-t:#ffffff;--bub-them:#eaeae4;--bub-tonal:#ccccc6;--marker:#6e5f3c;--danger:#8f1a14;
}
/* contrast-dark */
[data-theme="contrast"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="contrast"],
[data-theme="contrast"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#000000;--s1:#0d0d0c;--s2:#191917;--solid:#141413;--line:#8a8c83;--ctl:#b6b8ae;--t1:#ffffff;--t2:#edede6;--t3:#cfd0c8;--inv-bg:#ffffff;--inv-t:#000000;--inv-t2:#2e2f2a;--bub-me:#ffffff;--bub-me-t:#000000;--bub-them:#1c1c1a;--bub-tonal:#333331;--marker:#d8cbb0;--danger:#ff9b91;
}
/* slate-dark */
[data-theme="slate"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="slate"],
[data-theme="slate"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#161a20;--s1:#1b2027;--s2:#21272f;--solid:#272e37;--line:#2d343e;--ctl:#6f7a88;--t1:#e9edf2;--t2:#a9b2be;--t3:#8d97a4;--inv-bg:#e9edf2;--inv-t:#161a20;--inv-t2:#4a5563;--bub-me:#dce2e9;--bub-me-t:#161a20;--bub-them:#232a32;--bub-tonal:#373e45;--marker:#b09260;--danger:#ff7d72;
}
/* slate-light */
[data-theme="slate"][data-scheme="light"],
[data-scheme="light"] [data-tone="slate"] {
  color-scheme:light;--bg:#eff1f4;--s1:#e7eaee;--s2:#dfe3e9;--solid:#f7f8fa;--line:#d0d2d6;--ctl:#808488;--t1:#12161c;--t2:#54585d;--t3:#62656a;--inv-bg:#191d22;--inv-t:#eff1f4;--inv-t2:#999ca0;--bub-me:#191d22;--bub-me-t:#eff1f4;--bub-them:#e4e7ec;--bub-tonal:#cbced5;--marker:#7a6236;--danger:#a8341f;
}
/* stone-dark */
[data-theme="stone"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="stone"],
[data-theme="stone"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#1c1a17;--s1:#22201c;--s2:#292622;--solid:#2f2c28;--line:#35322d;--ctl:#7a756c;--t1:#ece8e1;--t2:#b3ada3;--t3:#9c968b;--inv-bg:#ece8e1;--inv-t:#1c1a17;--inv-t2:#57524a;--bub-me:#e2ddd5;--bub-me-t:#1c1a17;--bub-them:#282521;--bub-tonal:#3c3934;--marker:#b09260;--danger:#ff8072;
}
/* stone-light */
[data-theme="stone"][data-scheme="light"],
[data-scheme="light"] [data-tone="stone"] {
  color-scheme:light;--bg:#f3f1ec;--s1:#ece9e2;--s2:#e5e1d9;--solid:#f9f8f6;--line:#d5d3ce;--ctl:#868480;--t1:#1a1814;--t2:#5b5955;--t3:#666460;--inv-bg:#211f1a;--inv-t:#f3f1ec;--inv-t2:#9f9d98;--bub-me:#211f1a;--bub-me-t:#f3f1ec;--bub-them:#e9e6df;--bub-tonal:#d4d0c8;--marker:#7a6236;--danger:#a8341f;
}
/* clay-dark */
[data-theme="clay"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="clay"],
[data-theme="clay"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#1f1714;--s1:#261c18;--s2:#2d221d;--solid:#342823;--line:#3a2d27;--ctl:#87736b;--t1:#f2e9e1;--t2:#c3b3a8;--t3:#a6958a;--inv-bg:#f2e9e1;--inv-t:#1f1714;--inv-t2:#66524a;--bub-me:#eadfd5;--bub-me-t:#1f1714;--bub-them:#2e231e;--bub-tonal:#423732;--marker:#b09260;--danger:#ff8576;
}
/* clay-light */
[data-theme="clay"][data-scheme="light"],
[data-scheme="light"] [data-tone="clay"] {
  color-scheme:light;--bg:#f6f0ea;--s1:#f0e8e0;--s2:#eadfd5;--solid:#faf8f4;--line:#d8d1cb;--ctl:#8a827c;--t1:#1f140e;--t2:#605650;--t3:#6a615b;--inv-bg:#251b15;--inv-t:#f6f0ea;--inv-t2:#a29b95;--bub-me:#251b15;--bub-me-t:#f6f0ea;--bub-them:#eee4db;--bub-tonal:#d7ccc2;--marker:#7a6236;--danger:#a32a22;
}
/* editorial-dark */
[data-theme="editorial"][data-scheme="dark"],
[data-scheme="dark"] [data-tone="editorial"],
[data-theme="editorial"] :is(.call-surface,[data-call]) {
  color-scheme:dark;--bg:#0f0f0e;--s1:#161615;--s2:#1d1d1b;--solid:#222220;--line:#292927;--ctl:#6c6c66;--t1:#f6f5ef;--t2:#b2b1aa;--t3:#95948d;--inv-bg:#f6f5ef;--inv-t:#0f0f0e;--inv-t2:#4c4b46;--bub-me:#ecebe4;--bub-me-t:#0f0f0e;--bub-them:#1d1d1b;--bub-tonal:#333330;--marker:#b09260;--danger:#ff7a6e;
}
/* editorial-light */
[data-theme="editorial"][data-scheme="light"],
[data-scheme="light"] [data-tone="editorial"] {
  color-scheme:light;--bg:#f7f6f1;--s1:#efeee8;--s2:#e7e5de;--solid:#fbfaf8;--line:#d7d6d2;--ctl:#848481;--t1:#121211;--t2:#575654;--t3:#676664;--inv-bg:#191918;--inv-t:#f7f6f1;--inv-t2:#9e9e9a;--bub-me:#191918;--bub-me-t:#f7f6f1;--bub-them:#eceae4;--bub-tonal:#cdccc5;--marker:#7a6236;--danger:#a8341f;
}
/* ---- end of generated palettes ---- */

/* Night and Contrast: glass is always solid and the motif is always off (after the derived and light blocks: same
   specificity, so the last word; the Contrast tone inside a light page is named at the light block's specificity) */
[data-theme="night"], [data-theme="contrast"], [data-tone="night"], [data-tone="contrast"], [data-scheme="light"] [data-tone="contrast"],
:is([data-theme="night"], [data-theme="contrast"]) :is(.call-surface, [data-call]) {
  --glass: var(--bg); --pattern: transparent; --pattern-mark: transparent; --island: var(--s2);
}
[data-theme="contrast"] { --w-plus: 50; }

/* prefers-reduced-transparency: glass becomes the solid ground */
@media (prefers-reduced-transparency: reduce) {
  :root, [data-theme], [data-tone], .call-surface, [data-call] { --glass: var(--bg); --island: var(--s2); }
}
