/* Thronedex: the theme and the page. Dark "iron" is the default; light "parchment" applies under prefers-color-scheme: light and on any
   element carrying data-theme="light". The tokens below are copied from docs/design/tokens.css (values locked: change them there first, with a
   dated note in docs/design/thronedex-design-spec.md section 9); the components follow docs/design/theme.css and spec-theme.md. Added here, with
   the spec's blessing in spec-cards.md 5.2.1: --tex-hatch (and its -bone, -ink and -size parts). The rest of the file is the page. */

/* Fonts. Round two self-hosts Cinzel (wordmark, tabs, buttons, titles) and Crimson Pro (body, inputs) under the SIL Open Font License; neither was
   downloaded (no permission yet), so the stacks in the tokens fall to Georgia and these faces stay commented out. To switch them on: fetch the five
   files named below into games/thronedex/fonts/ with their OFL texts (spec-theme 3.4), add "!fonts/" to .assetsignore so they deploy, uncomment, and
   compute the fallback metrics (size-adjust, ascent-override, descent-override) from the files.
@font-face { font-family: "Cinzel"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/cinzel-latin-600.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Cinzel"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/cinzel-latin-700.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Crimson Pro"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/crimsonpro-latin-400.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Crimson Pro"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/crimsonpro-latin-600.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Crimson Pro"; font-style: italic; font-weight: 400; font-display: swap; src: url("fonts/crimsonpro-latin-400-italic.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
*/

/* ---- Neutral tokens (same in both themes; they inherit into every frame) ---- */
:root {
  /* Sizes (locked) */
  --tap: 44px;            /* smallest touch target (Apple HIG) */
  --field: 48px;          /* inputs, primary buttons, tabs: --tap + 4 */
  --gutter: 16px;         /* page side padding on a phone */
  --radius: 10px;         /* buttons, inputs, cards */
  --header-h: 112px;      /* the site header's exact height at phone width (not lowered, see spec 3.5) */
  --tabs-h: 48px;         /* the tab row; each tab is at least this tall */

  /* More sizes */
  --radius-sm: 8px;       /* tiles: smaller than a card so a 4-up row keeps its corners */
  --radius-lg: 14px;      /* dialog, sheet, win card: the big surfaces read as thicker */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; /* spacing scale: 4-pt steps, --s4 = --gutter */

  /* Fixed colours (identical in both themes, so a card face or a seal never flips) */
  --ink: #1C1813;         /* dark ink: text on every tile, on gold, on the pennon face */
  --bone: #E9DFC8;        /* light text on the seal and on the blood fill, 6.87:1 on --blood */
  --weirwood: #F4EFE4;    /* the win card's pennon face and the emoji well (art-angle name) */
  --cloth-2: #E4D7B4;     /* the stub sigil's field colour on the pale pennon (the real sprite brings its own tinctures) */
  --seal-deep: #5E0F15;   /* the dark end of the wax seal's radial gradient (art-angle value) */
  --tile-yes: #86B36F;    /* tile: match (godswood green) */
  --tile-part: #D9B347;   /* tile: partly (Lannister gold) */
  --tile-no: #8E877B;     /* tile: no (ash) */
  --tile-ink: #1C1813;    /* text and marks on every tile, both themes (4.96 to 8.82:1) */

  /* Type families (fonts are self-hosted in round two; until then the stacks fall to Georgia) */
  --font-display: "Cinzel", "Trajan Pro", Georgia, "Times New Roman", serif;   /* wordmark, tab labels, headers, buttons */
  --font-body: "Crimson Pro", Georgia, "Times New Roman", serif;               /* body copy at 17 px and up */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; /* tile text at 12 px and under, small print */

  /* Type scale: size, then the leading and the tracking that go with it (tracking falls as size grows) */
  --fs-micro: 11px;  --lh-micro: 1.25;  --tr-micro: .02em;   /* tile label: smallest allowed size, sans needs air */
  --fs-tile: 12px;   --lh-tile: 1.25;   --tr-tile: .01em;    /* tile value and sub line */
  --fs-small: 14px;  --lh-small: 1.45;  --tr-small: 0;       /* captions and the footer, sans */
  --fs-tab: 13px;    --lh-tab: 1.15;    --tr-tab: .06em;     /* tab label: small caps-style Cinzel wants +tracking */
  --fs-chip: 14px;   --lh-chip: 1;      --tr-chip: .04em;    /* era chips */
  --fs-btn: 15px;    --lh-btn: 1.2;     --tr-btn: .05em;     /* button labels */
  --fs-input: 17px;  --lh-input: 1.2;   --tr-input: 0;       /* 17 px: iOS does not zoom a 16 px or larger field */
  --fs-body: 18px;   --lh-body: 1.45;   --tr-body: 0;        /* Crimson Pro runs small, 18 reads like 15.5 px Georgia */
  --fs-title: 20px;  --lh-title: 1.2;   --tr-title: .03em;   /* dialog and card titles */
  --fs-wordmark: 22px; --lh-wordmark: 1; --tr-wordmark: .04em; /* "Throne" + "dex" in the header */
  --fs-win: 28px;    --lh-win: 1.1;     --tr-win: .02em;     /* win card title */
  --fs-glyph: 20px;  /* the "?" glyph and the Statistics bars in the header buttons */
  --fs-seal: 22px;   /* the day number on the wax seal */
  --fs-og: 132px;    --lh-og: 1;        --tr-og: -.01em;     /* social card wordmark: display size tightens */

  /* Effects that are the same in both themes */
  --shadow-press: inset 0 2px 4px rgba(0, 0, 0, .25);   /* a pressed quiet or secondary button sinks */
  --shadow-seal: inset 2px 2px 0 rgba(255, 255, 255, .22), inset -2px -2px 0 rgba(0, 0, 0, .28), 0 3px 6px rgba(0, 0, 0, .35);   /* the seal's 2 px highlight, its 2 px shade, and its drop */
  --sigil-edge-pale: #4A4132;   /* the sprite's light-theme edge, used on the pale pennon in both themes (8.75:1 on weirwood) */

  /* Motion */
  --fast: 120ms;          /* press feedback: answers the pointer-down, never waits for release */
  --unfurl: 400ms;        /* the pennon unfurls from the top (clip-path) */
  --stamp: 180ms;         /* the seal lands after the pennon is down */
  --sheet: 300ms;         /* bottom sheet in and out */
  --ease-out: cubic-bezier(.22, .8, .28, 1);   /* critically damped feel: fast start, no overshoot */

  /* Textures: pre-drawn tiles as data URIs, no filter (a filter re-rasterises on every repaint). Cost in spec 3.4 */
  --tex-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96'%3E%3Ccircle cx='8.2' cy='91.1' r='0.8' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='12.2' cy='81.3' r='0.5' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='53.9' cy='67.5' r='0.8' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='4.3' cy='12.4' r='0.4' fill='%236B4A2B' fill-opacity='.06'/%3E%3Ccircle cx='12.3' cy='9.7' r='1' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='33.5' cy='10.2' r='0.9' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='30.8' cy='87.3' r='0.9' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='31.2' cy='48.2' r='0.9' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='86.8' cy='8.8' r='0.8' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='91.7' cy='12.8' r='0.7' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='50.8' cy='8.5' r='0.7' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='52.9' cy='39.1' r='0.5' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='57.6' cy='22.8' r='0.6' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='88.1' cy='12.4' r='0.4' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='72.3' cy='38.6' r='0.4' fill='%236B4A2B' fill-opacity='.06'/%3E%3Ccircle cx='60.3' cy='22.5' r='1' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='68.7' cy='84.6' r='0.6' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='45.1' cy='87.4' r='0.9' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='74.2' cy='18.2' r='0.4' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='28.2' cy='74.5' r='0.4' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='22.3' cy='43.4' r='0.6' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='69.7' cy='43.1' r='0.6' fill='%236B4A2B' fill-opacity='.05'/%3E%3Ccircle cx='81.8' cy='90.5' r='0.7' fill='%236B4A2B' fill-opacity='.06'/%3E%3Ccircle cx='6.5' cy='63' r='0.5' fill='%236B4A2B' fill-opacity='.06'/%3E%3Ccircle cx='32' cy='18.8' r='0.7' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='36.6' cy='36.1' r='0.4' fill='%236B4A2B' fill-opacity='.06'/%3E%3Ccircle cx='30.5' cy='91.6' r='0.4' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='37.6' cy='81.7' r='0.4' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='92.7' cy='54.6' r='0.6' fill='%236B4A2B' fill-opacity='.04'/%3E%3Ccircle cx='60.5' cy='22.8' r='0.8' fill='%236B4A2B' fill-opacity='.04'/%3E%3Cpath d='M63.8 50Q67.4 48.3 70.9 49.5' fill='none' stroke='%236B4A2B' stroke-opacity='.05' stroke-width='0.6'/%3E%3Cpath d='M31.9 27.4Q34.3 25.1 36.8 24.6' fill='none' stroke='%236B4A2B' stroke-opacity='.05' stroke-width='0.6'/%3E%3Cpath d='M60.7 64.4Q65.1 63.1 69.4 62.6' fill='none' stroke='%236B4A2B' stroke-opacity='.05' stroke-width='0.6'/%3E%3Cpath d='M77.9 67.4Q83.6 68.4 89.3 67.7' fill='none' stroke='%236B4A2B' stroke-opacity='.05' stroke-width='0.6'/%3E%3Cpath d='M42.3 63.7Q46.7 63.8 51.1 65.6' fill='none' stroke='%236B4A2B' stroke-opacity='.05' stroke-width='0.6'/%3E%3Cpath d='M60.1 63Q65.9 65 71.8 64.6' fill='none' stroke='%236B4A2B' stroke-opacity='.04' stroke-width='0.6'/%3E%3Cpath d='M22.8 40.4Q25 39.1 27.2 40.8' fill='none' stroke='%236B4A2B' stroke-opacity='.05' stroke-width='0.6'/%3E%3Cpath d='M81.1 75.3Q86.4 75.2 91.6 77.9' fill='none' stroke='%236B4A2B' stroke-opacity='.06' stroke-width='0.6'/%3E%3Cpath d='M41.7 44.1Q47.3 43.9 52.9 42.5' fill='none' stroke='%236B4A2B' stroke-opacity='.04' stroke-width='0.6'/%3E%3Cpath d='M66.3 22.8Q69.9 21 73.4 19.9' fill='none' stroke='%236B4A2B' stroke-opacity='.04' stroke-width='0.6'/%3E%3C/svg%3E");       /* parchment grain, 96 px tile, 30 umber specks and 10 fibres, alpha .035 to .06 */
  --tex-mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Ccircle cx='0' cy='0' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='10' cy='0' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='20' cy='0' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='0' cy='10' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='10' cy='10' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='20' cy='10' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='0' cy='20' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='10' cy='20' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='20' cy='20' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='5' cy='5' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='15' cy='5' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='5' cy='15' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3Ccircle cx='15' cy='15' r='5' fill='none' stroke='%23E9DFC8' stroke-opacity='.04'/%3E%3C/svg%3E");         /* chainmail, 20 px tile, 10 px rings at 4% bone */
  --tex-barbs-bone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='8'%3E%3Cpath d='M0 8L8 0L16 8' fill='none' stroke='%23E9DFC8' stroke-opacity='.03'/%3E%3C/svg%3E");   /* feather barbs, 16 x 8 px herringbone, 3% bone (dark tab row) */
  --tex-barbs-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='8'%3E%3Cpath d='M0 8L8 0L16 8' fill='none' stroke='%231C1813' stroke-opacity='.03'/%3E%3C/svg%3E");     /* feather barbs, 16 x 8 px herringbone, 3% ink (light tab row) */
  --tex-grain-size: 96px 96px;  /* the grain tile's size */
  --tex-mail-size: 20px 20px;   /* the mail tile's size */
  --tex-barbs-size: 16px 8px;   /* the barbs tile's size */
  --tex-hatch-bone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0M-2 2L2 -2M6 10L10 6' stroke='%23E9DFC8' stroke-opacity='.03' fill='none'/%3E%3Cpath d='M0 0L8 8M-2 6L2 10M6 -2L10 2' stroke='%23E9DFC8' stroke-opacity='.03' fill='none'/%3E%3C/svg%3E");   /* crosshatch of the dashed preview row: two 45-degree hairlines at 3%, bone on iron (spec-cards 5.2.1) */
  --tex-hatch-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0M-2 2L2 -2M6 10L10 6' stroke='%231C1813' stroke-opacity='.03' fill='none'/%3E%3Cpath d='M0 0L8 8M-2 6L2 10M6 -2L10 2' stroke='%231C1813' stroke-opacity='.03' fill='none'/%3E%3C/svg%3E");   /* the same hatch in ink, for parchment */
  --tex-hatch-size: 8px 8px;    /* the hatch tile's size */
}

/* ---- Dark "iron": the default, also on data-theme="dark" and on any frame that is not pinned light ---- */
:root,
[data-theme="dark"] {
  color-scheme: dark;                 /* native widgets and scrollbars follow the theme */
  --bg: #15171A;                      /* page */
  --panel: #1E2125;                   /* cards, dialogs, header */
  --panel-2: #272B30;                 /* raised: tab row, secondary buttons, chips */
  --line: #3A3F46;                    /* decorative hairline only, 1.69:1 on --bg: never the only boundary of a control */
  --edge: #857C6A;                    /* input borders and any boundary that carries meaning: 4.35 bg, 3.92 panel, 3.45 panel-2 */
  --text: #E9DFC8;                    /* bone */
  --muted: #A9A08C;                   /* secondary text */
  --accent: #D9B347;                  /* gold */
  --accent-ink: #1C1813;              /* text on a gold fill */
  --focus: #9CC7D9;                   /* ice focus ring, 9.91:1 on --bg */
  --ember: #E0832F;                   /* fire and the streak flame, 6.38:1 on --bg */
  --blood: #8C1C24;                   /* fill only: bone text on it 6.87, never text on iron (2.0:1) */
  --danger-text: #F08A80;             /* error text and the alert border, 7.40:1 on --bg */
  --hover: #2F343A;                   /* hover fill under text: muted still 4.84:1 on it */
  --accent-hover: #E3C05E;            /* primary button on hover: lighter, ink 10.06:1 */
  --accent-press: #BE9A33;            /* primary button while pressed: darker, ink 6.61:1 */
  --shadow-1: 0 6px 18px rgba(0, 0, 0, .35);   /* raised card */
  --shadow-sheet: 0 -10px 30px rgba(0, 0, 0, .5); /* bottom sheet: heavier over content so it separates */
  --scrim: rgba(0, 0, 0, .6);         /* behind a dialog or sheet */
  --vignette: none;                   /* no edge vignette on iron */
  --tex-page: none;                   /* the page is plain iron */
  --tex-page-size: auto;
  --tex-header: var(--tex-mail);      /* chainmail behind the header */
  --tex-header-size: var(--tex-mail-size);
  --tex-tabs: var(--tex-barbs-bone);  /* feather barbs behind the tab row */
  --tex-hatch: var(--tex-hatch-bone); /* crosshatch of the dashed preview row */
  --tile-ring: 0px;                   /* no tile outline: the fills sit at 7.43 / 8.97 / 5.05 on the page */
}

/* ---- Light "parchment": pinned on any element, and by the OS preference when the page is not pinned dark ---- */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;                /* native widgets and scrollbars follow the theme */
    --bg: #EDE2C4;                      /* page: parchment */
    --panel: #F5EDD8;                   /* cards, dialogs, header */
    --panel-2: #E4D7B4;                 /* raised: tab row, secondary buttons, chips */
    --line: #C9B98F;                    /* decorative hairline only */
    --edge: #7A6E58;                    /* input borders and any boundary that carries meaning: 3.88 bg, 4.28 panel */
    --text: #1C1813;                    /* ink */
    --muted: #5C5344;                   /* secondary text */
    --accent: #6E4F0E;                  /* bronze: gold is never text on parchment (1.55:1) */
    --accent-ink: #F4EFE4;              /* text on a bronze fill */
    --focus: #8C1C24;                   /* blood focus ring, 7.06:1 on --bg */
    --ember: #8A4208;                   /* added: the iron ember is 2.3:1 on parchment, this one is 5.13 to 6.28 */
    --blood: #8C1C24;                   /* fill only: the wax seal */
    --danger-text: #9E1B1B;             /* error text and the alert border, 6.20:1 on --bg */
    --hover: #DACB9F;                   /* hover fill under text: muted 4.69:1, accent 4.67:1 on it */
    --accent-hover: #5C4009;            /* primary button on hover: darker bronze, 8.35:1 with its text */
    --accent-press: #4B3507;            /* primary button while pressed, 10.11:1 with its text */
    --shadow-1: 0 6px 18px rgba(60, 40, 10, .18);        /* raised card */
    --shadow-sheet: 0 -10px 30px rgba(60, 40, 10, .28);  /* bottom sheet */
    --scrim: rgba(28, 24, 19, .55);     /* behind a dialog or sheet */
    --vignette: radial-gradient(ellipse at 50% 40%, rgba(107, 74, 43, 0) 55%, rgba(107, 74, 43, .04) 100%); /* edges of the page darken 4% at most */
    --tex-page: var(--tex-grain);       /* parchment grain on the page */
    --tex-page-size: var(--tex-grain-size);
    --tex-header: var(--tex-grain);     /* the header is parchment too: no chainmail on the light theme */
    --tex-header-size: var(--tex-grain-size);
    --tex-tabs: var(--tex-barbs-ink);   /* feather barbs behind the tab row */
    --tex-hatch: var(--tex-hatch-ink);  /* crosshatch of the dashed preview row */
    --tile-ring: 1px;                   /* every tile gets a 1px --edge outline: the fills sit at 1.87 / 1.55 / 2.76 on parchment */
  }
}
[data-theme="light"] {
  color-scheme: light;                /* native widgets and scrollbars follow the theme */
  --bg: #EDE2C4;                      /* page: parchment */
  --panel: #F5EDD8;                   /* cards, dialogs, header */
  --panel-2: #E4D7B4;                 /* raised: tab row, secondary buttons, chips */
  --line: #C9B98F;                    /* decorative hairline only */
  --edge: #7A6E58;                    /* input borders and any boundary that carries meaning: 3.88 bg, 4.28 panel */
  --text: #1C1813;                    /* ink */
  --muted: #5C5344;                   /* secondary text */
  --accent: #6E4F0E;                  /* bronze: gold is never text on parchment (1.55:1) */
  --accent-ink: #F4EFE4;              /* text on a bronze fill */
  --focus: #8C1C24;                   /* blood focus ring, 7.06:1 on --bg */
  --ember: #8A4208;                   /* added: the iron ember is 2.3:1 on parchment, this one is 5.13 to 6.28 */
  --blood: #8C1C24;                   /* fill only: the wax seal */
  --danger-text: #9E1B1B;             /* error text and the alert border, 6.20:1 on --bg */
  --hover: #DACB9F;                   /* hover fill under text: muted 4.69:1, accent 4.67:1 on it */
  --accent-hover: #5C4009;            /* primary button on hover: darker bronze, 8.35:1 with its text */
  --accent-press: #4B3507;            /* primary button while pressed, 10.11:1 with its text */
  --shadow-1: 0 6px 18px rgba(60, 40, 10, .18);        /* raised card */
  --shadow-sheet: 0 -10px 30px rgba(60, 40, 10, .28);  /* bottom sheet */
  --scrim: rgba(28, 24, 19, .55);     /* behind a dialog or sheet */
  --vignette: radial-gradient(ellipse at 50% 40%, rgba(107, 74, 43, 0) 55%, rgba(107, 74, 43, .04) 100%); /* edges of the page darken 4% at most */
  --tex-page: var(--tex-grain);       /* parchment grain on the page */
  --tex-page-size: var(--tex-grain-size);
  --tex-header: var(--tex-grain);     /* the header is parchment too: no chainmail on the light theme */
  --tex-header-size: var(--tex-grain-size);
  --tex-tabs: var(--tex-barbs-ink);   /* feather barbs behind the tab row */
  --tex-hatch: var(--tex-hatch-ink);  /* crosshatch of the dashed preview row */
  --tile-ring: 1px;                   /* every tile gets a 1px --edge outline: the fills sit at 1.87 / 1.55 / 2.76 on parchment */
}

/* Higher contrast asked for: drop the textures and make the hairline a real boundary */
@media (prefers-contrast: more) {
  :root, :root:not([data-theme="dark"]), [data-theme] {
    --tex-page: none;
    --tex-header: none;
    --tex-tabs: none;
    --tex-hatch: none;
    --vignette: none;
    --line: var(--edge);
  }
}

/* Reduced motion: the pennon is simply there, the seal is simply there, nothing drifts */
@media (prefers-reduced-motion: reduce) {
  :root { --unfurl: 0ms; --stamp: 0ms; --sheet: 0ms; }
}
[data-motion="reduce"] { --unfurl: 0ms; --stamp: 0ms; --sheet: 0ms; }

/* ================================================================================================
   Page variables the script and the card layout read (layout numbers, not design tokens).
   app.js sets --flip, --stagger and --cols on <html> at start-up, and --sug-max on the typeahead.
   ================================================================================================ */
:root {
  --name-col: 150px;
  --col: 112px;
  --cols: 7;        /* attribute columns; app.js sets it from game.js FIELDS */
  --flip: 1000ms;   /* set from game.js REVEAL at start-up */
  --stagger: 550ms;
  --bleed: 8px;     /* on a phone the tiles reach this far past the gutter */
  --sug-max: 320px; /* typeahead height; app.js lowers it to fit above the keyboard */

  /* Marks and glyphs: shapes only (black on transparent), coloured by background-color: currentColor (theme.css) */
  --mask-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.4l2.8 2.8L10 3.2' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --mask-half: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Ccircle cx='6' cy='6' r='4.4' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3Cpath d='M6 1.6a4.4 4.4 0 0 0 0 8.8z' fill='%23000'/%3E%3C/svg%3E");
  --mask-cross: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 3l6 6M9 3l-6 6' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  --mask-ring: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Ccircle cx='6' cy='6' r='4.6' fill='none' stroke='%23000' stroke-width='1.6'/%3E%3C/svg%3E");
  --mask-up: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M6 10.2V2.6M2.8 5.6L6 2.4l3.2 3.2' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --mask-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 3.5l9 9M12.5 3.5l-9 9' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  --mask-alert: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.8L14.6 13.4H1.4Z' fill='none' stroke='%23000' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M8 6.4v3.4' stroke='%23000' stroke-width='1.6' stroke-linecap='round'/%3E%3Ccircle cx='8' cy='11.6' r='.9' fill='%23000'/%3E%3C/svg%3E");
}

/* ---- Page base ---- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  display: flow-root;                 /* WebKit: stops the footer's bottom margin collapsing out of the min-height (30px of extra scroll) */
  padding-bottom: env(safe-area-inset-bottom);
  background-color: var(--bg);        /* explicit, in both themes */
  background-image: var(--vignette), var(--tex-page);
  background-size: 100% 100%, var(--tex-page-size);
  color: var(--text);
  font: 400 var(--fs-body)/var(--lh-body) var(--font-body);
  letter-spacing: var(--tr-body);
  -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }   /* the component rules below set display, which would otherwise beat the hidden attribute */
h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: 600; }
h2 { font-size: var(--fs-title); line-height: var(--lh-title); letter-spacing: var(--tr-title); }
p { margin: 0 0 var(--s3); }
a { color: var(--accent); text-underline-offset: 3px; }
button { font: inherit; color: inherit; }
.sigil { display: block; flex: none; }
.small { font: 400 var(--fs-small)/var(--lh-small) var(--font-ui); color: var(--muted); }
/* Read by screen readers, not shown. */
.vh, .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---- Focus: one ring for everything you can reach with a keyboard (spec-theme 3.12) ---- */
:where(a, button, input, select, textarea, summary, [role="tab"], [role="radio"], [role="switch"], [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;                /* the gap shows the surface behind, so the ring is measured against it */
}
.tabs > [role="tab"]:focus-visible { outline-offset: -3px; }   /* inside the tab: the row is full-bleed, an outside ring would be cut off */
:where(h1, h2, h3, .dialog-title)[tabindex="-1"]:focus { outline: none; }   /* a dialog title takes focus on open; it is not a control */

/* ---- Site header (spec-theme 3.6): 112 px at phone width, chainmail on iron, grain on parchment ---- */
.site-header {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: var(--tap) minmax(0, 1fr) 34px;
  min-height: var(--header-h);        /* exactly --header-h with a one-line tagline; grows instead of clipping if text is scaled up */
  padding: 6px max(var(--gutter), calc((100% - 1068px) / 2));   /* the page's column is 1100 px less its gutters; the band itself is full width */
  overflow: hidden;
  background-color: var(--panel);
  background-image: var(--tex-header);
  background-size: var(--tex-header-size);
  border-bottom: 1px solid var(--line);
}
.site-header > * { position: relative; z-index: 1; }
.header-row { display: flex; align-items: center; gap: var(--s2); }
.brand { display: flex; flex: 1; min-width: 0; }
.wordmark { flex: 1; min-width: 0; margin: 0; font-size: var(--fs-wordmark); line-height: var(--lh-wordmark); letter-spacing: var(--tr-wordmark); }
.brand-link {
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: var(--tap);
  color: var(--text); text-decoration: none; white-space: nowrap;
}
.brand-link .dex { color: var(--accent); }
.emblem { width: 32px; height: 38px; flex: none; }
.header-actions { display: flex; gap: var(--s1); flex: none; }
.icon-btn {
  display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0;
  border: 1px solid var(--edge); border-radius: var(--radius);
  background: var(--panel-2); color: var(--accent);
  font: 600 var(--fs-glyph)/1 var(--font-display); cursor: pointer;
  transition: background-color var(--fast) linear, transform var(--fast) var(--ease-out);
}
.icon-btn svg { width: var(--fs-glyph); height: var(--fs-glyph); fill: currentColor; }
.icon-btn:active { background: var(--hover); transform: translateY(1px); }
@media (hover: hover) { .icon-btn:not(:disabled):hover { background: var(--hover); } }
.icon-btn:disabled { border-style: dashed; color: var(--muted); cursor: default; transform: none; }   /* a dashed edge and a muted glyph: not only paler */
.tagline {
  align-self: center; margin: 0 calc(var(--s2) - var(--gutter));   /* runs 8 px from each edge so it holds one line at 320 */
  text-align: center; white-space: nowrap;
  color: var(--muted); font: 400 var(--fs-tile)/var(--lh-tile) var(--font-ui); letter-spacing: 0;
}
.houses { display: flex; justify-content: space-between; align-items: center; width: 100%; max-width: 420px; margin: 0 auto; }

/* Ember particles: six dots that rise 36 px from the bottom edge and fade, compositor-only (transform, opacity).
   They stay in the 40 px band that holds only the shield strip, so no text is ever behind one (docs/design/tools/contrast.mjs asserts it). */
.site-header > .embers { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.embers i {
  position: absolute; bottom: -4px; width: 4px; height: 4px; border-radius: 50%;
  background: var(--ember); opacity: 0;
  animation: ember 10s linear infinite;
}
.embers i:nth-child(1) { left: 9%;  animation-duration: 9s;  animation-delay: -2s; }
.embers i:nth-child(2) { left: 27%; animation-duration: 12s; animation-delay: -7s; background: var(--accent); }
.embers i:nth-child(3) { left: 44%; animation-duration: 10s; animation-delay: -4s; }
.embers i:nth-child(4) { left: 61%; animation-duration: 13s; animation-delay: -9s; background: var(--accent); }
.embers i:nth-child(5) { left: 78%; animation-duration: 11s; animation-delay: -1s; }
.embers i:nth-child(6) { left: 92%; animation-duration: 14s; animation-delay: -6s; background: var(--accent); }
@keyframes ember {
  from { transform: translate(0, 0); opacity: 0; }
  20%  { opacity: .3; }
  to   { transform: translate(6px, -36px); opacity: 0; }
}

/* ---- Tabs (spec-theme 3.8): four cells in one 48 px row, icon over label. The selected tab differs in shape, weight and rule, not only colour.
   The second cell is held for the Trial: .tab-slot is a plain span, so it is not a tab, not focusable and not a .mode. ---- */
.tabs {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  height: var(--tabs-h);
  background-color: var(--panel-2);
  background-image: var(--tex-tabs);
  background-size: var(--tex-barbs-size);
  box-shadow: 0 1px 0 var(--line);    /* outside the 48 px so every tab keeps its full height */
}
.tabs > [role="tab"] {
  appearance: none; position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-width: 0; height: var(--tabs-h); margin: 0; padding: 2px 0 0;
  border: 0; border-radius: 0; background: transparent; color: var(--muted); cursor: pointer;
  font: 600 var(--fs-tab)/var(--lh-tab) var(--font-display); letter-spacing: var(--tr-tab);
  transition: background-color var(--fast) linear, color var(--fast) linear;
}
.tabs > [role="tab"] + [role="tab"] { box-shadow: inset 1px 0 0 var(--line); }   /* a divider only between two real tabs, so the held cell shows as plain space */
.tabs > [role="tab"]:disabled { cursor: default; }
.tabs svg { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.tabs > [aria-selected="true"] { background-color: var(--bg); color: var(--accent); font-weight: 700; }
.tabs > [aria-selected="true"]::before {   /* a 3 px lintel across the top: a shape the unselected tabs do not have */
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--accent);
}
.tabs > [aria-selected="true"] svg { stroke-width: 2.4; }
.tabs > [role="tab"]:active { background-color: var(--hover); }
@media (hover: hover) {
  .tabs > [role="tab"]:not([aria-selected="true"]):not(:disabled):hover { background-color: var(--hover); color: var(--text); }
}
@media (min-width: 641px) { .tabs { max-width: 560px; margin: 0 auto; } }   /* on a wide screen the row is a centred strip, not four 360 px cells */

/* ---- Buttons (spec-theme 3.9). Plain .btn is the secondary look; the live script also emits .btn.primary and .btn.quiet ---- */
.btn {
  appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: var(--field); min-width: var(--tap); padding: 0 var(--s4);
  border: 1px solid var(--edge); border-radius: var(--radius);
  background: var(--panel-2); color: var(--text); cursor: pointer; text-decoration: none; white-space: nowrap;
  font: 600 var(--fs-btn)/var(--lh-btn) var(--font-display); letter-spacing: var(--tr-btn);
  transition: background-color var(--fast) linear, color var(--fast) linear, transform var(--fast) var(--ease-out);
}
.btn:active { transform: translateY(1px); }   /* answers the pointer-down, not the release */
.btn--primary, .btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn--quiet, .btn.quiet { background: transparent; border-color: transparent; color: var(--accent); }
@media (hover: hover) {
  .btn:not(:disabled):hover { background: var(--hover); }
  .btn--primary:not(:disabled):hover, .btn.primary:not(:disabled):hover { background: var(--accent-hover); border-color: var(--accent-hover); }
  .btn--quiet:not(:disabled):hover, .btn.quiet:not(:disabled):hover { background: var(--panel-2); }
}
.btn:active { background: var(--hover); box-shadow: var(--shadow-press); }
.btn--primary:active, .btn.primary:active { background: var(--accent-press); border-color: var(--accent-press); box-shadow: none; }
.btn--quiet:active, .btn.quiet:active { background: var(--panel-2); }
.btn:disabled, .btn[aria-disabled="true"] {   /* a dashed edge and a flat fill: not only paler */
  background: var(--panel-2); border: 1px dashed var(--edge); color: var(--muted); cursor: not-allowed; transform: none; box-shadow: none;
}

/* ---- Era chips and the segmented control (spec-theme 3.10): a ring that becomes a check marks the chosen one ---- */
.chip {
  appearance: none; display: inline-flex; align-items: center; gap: 5px;
  min-height: var(--tap); padding: 0 12px 0 8px;
  border: 1px solid var(--edge); border-radius: 999px; background: var(--panel-2); color: var(--text); cursor: pointer; white-space: nowrap;
  font: 600 var(--fs-chip)/var(--lh-chip) var(--font-display); letter-spacing: var(--tr-chip);
  transition: background-color var(--fast) linear, color var(--fast) linear;
}
.chip::before, .segmented > [role="radio"]::before {
  content: ""; width: 14px; height: 14px; flex: none;
  background-color: currentColor;
  -webkit-mask: var(--mask-ring) center / contain no-repeat; mask: var(--mask-ring) center / contain no-repeat;
}
.chip::before { width: 12px; height: 12px; }
.chip[aria-checked="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.chip[aria-checked="true"]::before, .segmented > [aria-checked="true"]::before { -webkit-mask-image: var(--mask-check); mask-image: var(--mask-check); }
.chip:active { transform: translateY(1px); }
@media (hover: hover) { .chip[aria-checked="false"]:hover { background: var(--hover); } }
.segmented { display: flex; padding: 3px; gap: 3px; border: 1px solid var(--edge); border-radius: calc(var(--radius) + 3px); background: var(--panel-2); }
.segmented > [role="radio"] {
  appearance: none; flex: 1 1 0; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: var(--tap); padding: 0 var(--s3); border: 0; border-radius: var(--radius); background: transparent; color: var(--text); cursor: pointer;
  font: 600 var(--fs-chip)/var(--lh-chip) var(--font-display); letter-spacing: var(--tr-chip);
}
.segmented > [role="radio"]::before { visibility: hidden; }          /* the slot is reserved so the label never jumps */
.segmented > [aria-checked="true"] { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.segmented > [aria-checked="true"]::before { visibility: visible; }

/* ---- Text input (spec-theme 3.11): 17 px, 48 px tall, a 1 px --edge border ---- */
.field {
  appearance: none; display: block; width: 100%; height: var(--field); padding: 0 14px;
  border: 1px solid var(--edge); border-radius: var(--radius); background: var(--panel); color: var(--text);
  font: 400 var(--fs-input)/var(--lh-input) var(--font-body); letter-spacing: var(--tr-input);
}
.field::placeholder { color: var(--muted); opacity: 1; }
.field:focus { outline: 3px solid var(--focus); outline-offset: 2px; border-color: var(--focus); }
.field:disabled { background: var(--panel-2); border-style: dashed; color: var(--muted); cursor: not-allowed; }
.field[aria-invalid="true"] { border-color: var(--danger-text); }

/* ---- The first screen under the tabs ---- */
main { max-width: 1100px; margin: 0 auto; padding: 0 var(--gutter); }
.mode-desc, .today { text-align: center; color: var(--muted); font: 400 var(--fs-tile)/1.25 var(--font-ui); }
.mode-desc { margin: 6px 0 0; }
.today { margin: 0; }
.today b { color: var(--text); }

.guess-form { margin: 8px auto 0; max-width: 560px; }
.combo { position: relative; display: flex; gap: var(--s2); align-items: flex-start; }
.guess-input { flex: 1; min-width: 0; }
.guess-btn { flex: none; }
/* The typeahead (spec-cards 5.5): a 1 px --edge list of 44 px rows. A row leads with the character's first House's sigil (the roundel for none), then the name,
   the alias when there is one, and the short House word right-aligned and muted. The sigil is last in the markup so the name stays first; `order` puts it in front. */
.suggestions {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 20; margin: 0; padding: 0; list-style: none;
  background: var(--panel); border: 1px solid var(--edge); border-radius: var(--radius); box-shadow: var(--shadow-1);
  max-height: var(--sug-max); overflow: auto;
}
.suggestions li { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 0 12px; cursor: pointer; font: 400 var(--fs-input)/var(--lh-input) var(--font-body); }
.suggestions li + li { border-top: 1px solid var(--line); }
.suggestions li[aria-selected="true"], .suggestions li:hover { background: var(--hover); }
.suggestions .sigil { order: -1; }
.suggestions .nm { flex: none; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* the name never gives way to the alias */
.suggestions .alias { flex: 0 99 auto; min-width: 0; color: var(--muted); font: 400 var(--fs-small)/1 var(--font-ui); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.suggestions .who { flex: none; margin-left: auto; color: var(--muted); font: 400 var(--fs-small)/1 var(--font-ui); white-space: nowrap; }

/* The line the game talks on (spec-theme 3.14): quiet, and a line's height held when it is empty */
.status { min-height: 1.3em; margin: 2px 0 0; color: var(--muted); font: 400 var(--fs-body)/var(--lh-body) var(--font-body); }

/* The colour key under the input, one line down to 320px: the same fills and marks as the tiles */
.key { display: flex; justify-content: space-between; align-items: center; gap: 4px 8px; margin: 8px 0 0; padding: 0; list-style: none; white-space: nowrap; color: var(--muted); font: 400 var(--fs-tile)/1.5 var(--font-ui); letter-spacing: var(--tr-tile); }
.key li { display: inline-flex; align-items: center; }
.swatch {
  display: inline-grid; place-items: center; width: 20px; height: 18px; margin-right: 5px; flex: none; border-radius: 4px;
  color: var(--tile-ink); box-shadow: inset 0 0 0 var(--tile-ring) var(--edge);
}
.swatch.correct { background: var(--tile-yes); }
.swatch.partial { background: var(--tile-part); }
.swatch.wrong { background: var(--tile-no); }

/* The load error (spec-theme 3.14: .alert, an icon and words) */
.alert {
  display: flex; align-items: flex-start; gap: 10px; margin: 0; padding: var(--s3) 14px;
  border: 1px solid var(--danger-text); border-radius: var(--radius); background: var(--panel); color: var(--text);
}
.alert::before {                        /* the icon is the non-colour cue */
  content: ""; flex: none; width: 20px; height: 20px; margin-top: 3px; background-color: var(--danger-text);
  -webkit-mask: var(--mask-alert) center / contain no-repeat; mask: var(--mask-alert) center / contain no-repeat;
}
.alert > div { min-width: 0; }
.alert h2, .alert strong { color: var(--danger-text); font-family: var(--font-display); font-weight: 600; letter-spacing: var(--tr-chip); }
.alert h2 { font-size: var(--fs-body); line-height: var(--lh-body); }   /* the title is a line of the alert, not a section title */
.alert p { margin: 4px 0 var(--s3); }
.notice { margin: 12px 0; }
.notice h2 { margin: 0 0 4px; }
.notice p { margin: 0 0 var(--s3); }
.notice .btn { min-width: 120px; }
.load-error .key, .load-error .empty { display: none; }

/* ---- The board: wide screens keep one 8-column grid, phones get a card per guess (below) ---- */
.board { margin: 0 calc(-1 * var(--gutter)); }
.grid-scroll { overflow-x: auto; padding: 0 var(--gutter) 8px; scrollbar-width: thin; }
.grid { display: grid; grid-template-columns: minmax(var(--name-col), 1.4fr) repeat(var(--cols), minmax(var(--col), 1fr)); gap: 6px; min-width: 100%; }
.grid .head {
  position: sticky; top: 0; font: 700 var(--fs-micro)/var(--lh-micro) var(--font-ui); text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  padding: 6px 4px; text-align: center; border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.grid .head svg { width: 16px; height: 16px; fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.grid .head.name { text-align: left; align-items: flex-start; justify-content: flex-end; }

/* A tile: dark ink on all three fills, a mark for the status, and on parchment a 1 px --edge outline (spec-theme 3.13).
   .correct, .partial and .wrong are the live script's names; .tile--yes, .tile--part and .tile--no are the theme's. */
.tile {
  min-height: 72px; border-radius: var(--radius-sm); padding: 8px 6px; display: grid; place-items: center; text-align: center;
  font: 400 var(--fs-tile)/var(--lh-tile) var(--font-ui); letter-spacing: var(--tr-tile); overflow-wrap: anywhere;
  background: var(--tile-no); color: var(--tile-ink);
  box-shadow: inset 0 0 0 var(--tile-ring) var(--edge);   /* 0 on iron; a 1 px --edge outline on parchment */
}
.tile.correct, .tile--yes { background: var(--tile-yes); }
.tile.partial, .tile--part { background: var(--tile-part); }
.tile.wrong, .tile--no { background: var(--tile-no); }
.tile.fresh, .miss-row.fresh, .miss-pill.fresh { animation: flip var(--flip) cubic-bezier(0.2, 0.7, 0.2, 1) both; animation-delay: calc(var(--i) * var(--stagger)); backface-visibility: hidden; }
.tile.name { background: var(--panel-2); color: var(--text); box-shadow: none; font: 700 var(--fs-input)/1.25 var(--font-body); letter-spacing: 0; text-align: left; justify-items: start; padding-left: 10px; }
.tile .sub { color: inherit; font-size: var(--fs-tile); }
.name .real { display: block; font: 400 var(--fs-tile)/1.25 var(--font-ui); color: var(--muted); }
.tile.name .score { display: none; } /* shown on phones */
@keyframes flip { from { transform: perspective(600px) rotateY(90deg); opacity: 0; } 40% { opacity: 1; } to { transform: perspective(600px) rotateY(0); opacity: 1; } }

/* A guess is one .guess group: the name, seven tile buttons, a detail line. Wide screens keep the 8-column grid. */
.guess { display: contents; }
button.tile { appearance: none; border: 0; font-family: var(--font-ui); color: var(--tile-ink); cursor: pointer; position: relative; padding-top: 16px; } /* wide screens: room for the mark in the corner, so it never sits on the text */
.tile .lbl { position: absolute; top: 4px; right: 4px; display: flex; }
.tile .lt { display: none; }
.tile .sigil { --sigil-edge: var(--ink); }   /* the sigil's edge on a tile is the tile's ink (spec-sigils 4.5): 4.96 to 7.31:1 on the three fills */
.val--house { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 4px; }
.val--house .hname { min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; overflow-wrap: break-word; hyphens: manual; }
.mk, .ar { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mk .fill { fill: currentColor; stroke: none; }
/* An open tile: a two-tone ring of --edge then --text, outside the tile, 3 px in all. Both tones are 3:1 or better against each other and
   against the page on iron and on parchment, and the whole ring ends inside the 6 px gap between tiles, so the focus ring (3 px out, 3 px wide) starts after it. */
.tile[aria-expanded="true"] { box-shadow: 0 0 0 1px var(--edge), 0 0 0 3px var(--text); }
.detail { grid-column: 1 / -1; margin: 0; padding: 8px 10px; border-radius: var(--radius); background: var(--panel); border: 1px solid var(--line); font: 400 var(--fs-small)/1.4 var(--font-ui); text-align: left; }

/* The card layout, used by the help's example row at every width and by the board on phones */
.guess.example { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 6px; }
.guess.example > .tile { grid-column: span 3; min-height: var(--tap); }
.guess.example > .tile:nth-child(n + 6) { grid-column: span 4; }
.guess.example > .tile:not(.name) { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 2px; padding: 5px 3px 6px; font-size: var(--fs-tile); line-height: var(--lh-tile); text-align: left; }
.guess.example > .tile.name { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; min-height: 0; padding: 0 calc(var(--gutter) - var(--bleed)); background: none; box-shadow: none; color: var(--text); text-align: left; }
.guess.example .name .real { display: inline; }
.guess.example .name .score { display: inline; margin-left: auto; font: 700 var(--fs-small)/1 var(--font-ui); color: var(--muted); }
.guess.example .tile .lbl { position: static; display: flex; align-items: center; justify-content: space-between; gap: 2px; font: 700 var(--fs-micro)/1.2 var(--font-ui); letter-spacing: var(--tr-micro); white-space: nowrap; }
.guess.example .tile .lt { display: inline; }
.guess.example .tile .val { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; line-clamp: 4; overflow: hidden; overflow-wrap: break-word; hyphens: manual; }
.guess.example .tile .sub { display: flex; align-items: center; gap: 4px; }
/* The empty state's preview row: same shape, dashed, never inside #grid. The hatch is spec-cards 5.2.1's texture. */
.guess.ghost > .tile { background-color: transparent; background-image: var(--tex-hatch); background-size: var(--tex-hatch-size); box-shadow: none; border: 1px dashed var(--edge); color: var(--muted); cursor: default; }
.guess.ghost > .tile.name { border: 0; background: none; color: var(--muted); }
.empty { color: var(--muted); padding: 24px var(--gutter); }
.empty p { color: var(--text); }
.empty .guess.ghost { margin-top: var(--s4); }

/* ---- Fallen and Raven (spec-cards 5.6, 5.7). The card comes first, its prompt under it, then the input; the misses and the hints follow the status line.
   The prompt is the card's last child in the markup (the page reads it there) and is drawn under the box: --prompt-h is its line, held as margin so the input does not move. ---- */
.clue { max-width: 560px; margin: 4px auto 0; }   /* the same column as the input */
.clue-more { max-width: 560px; margin: 0 auto 14px; }
.clue-card, .scroll { --prompt-h: 27px; }
.clue-sub.prompt { position: absolute; left: 0; right: 0; top: calc(100% + var(--s3)); margin: 0; color: var(--text); text-align: left; }
.hint-note { margin: var(--s1) 0 0; }
.misses:empty, .miss-list:empty { display: none; }   /* no guesses yet: no empty list holding its top margin, so the hint line stays inside the fold at 320 x 568 (spec-cards 5.3) */

/* Fallen: the crypt's clue card, a chiselled double rule (--edge outside, --line inside), no image */
.crypt.clue-card { position: relative; margin: 0 0 calc(var(--prompt-h) + var(--s3) * 2); padding: var(--s4); text-align: left; border: 1px solid var(--edge); border-radius: var(--radius-lg); background: var(--panel); box-shadow: var(--shadow-1), inset 0 0 0 5px var(--panel), inset 0 0 0 6px var(--line); }
.crypt .spoiler { margin: 0 0 var(--s2); color: var(--muted); }
.crypt .manner { margin: 0 0 var(--s3); font: 600 var(--fs-title)/1.3 var(--font-display); letter-spacing: var(--tr-title); }
.clue-meta { display: grid; gap: var(--s2); margin: 0; }
.clue-meta .fact { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.clue-meta .fact::before { content: attr(data-label); flex: none; width: 4.2em; color: var(--muted); font: 700 var(--fs-micro)/var(--lh-micro) var(--font-ui); letter-spacing: .08em; text-transform: uppercase; }
.badge { display: inline-block; padding: 2px 12px; border: 1px solid var(--edge); border-radius: 999px; background: var(--panel-2); font: 600 var(--fs-chip)/1.4 var(--font-display); letter-spacing: var(--tr-chip); }

/* Raven: a scroll of --weirwood (pale in both themes) with a roll at each end, the raven on top and the wax seal at the bottom with the day's number. Nothing moves. */
.scroll { position: relative; margin: var(--s3) 6px calc(40px + var(--prompt-h) + var(--s3)); padding: 44px 30px 40px; border: 1px solid var(--edge); border-radius: 6px; background: var(--weirwood); color: var(--ink); text-align: center; box-shadow: var(--shadow-1); }
.scroll::before, .scroll::after { content: ""; position: absolute; top: -6px; bottom: -6px; width: 14px; border-radius: 7px; background: var(--cloth-2); box-shadow: inset 0 0 0 1px var(--edge); }
.scroll::before { left: -8px; }
.scroll::after { right: -8px; }
.scroll .raven { position: absolute; top: 6px; left: 50%; width: 36px; height: 36px; margin-left: -18px; }
.scroll .quote { margin: 0; font: italic 400 var(--fs-title)/1.35 var(--font-body); }
.scroll .quote::before { content: "\201C"; }
.scroll .quote::after { content: "\201D"; }
.scroll .clue-sub.prompt { top: calc(100% + 40px); }   /* clear of the seal, which hangs 30 px below the scroll */
.scroll .seal { top: auto; bottom: -30px; left: 50%; margin-left: -30px; animation: none; }   /* the seal belongs to the card, it is not a reveal: it is simply there */
.scroll .emoji { display: flex; justify-content: center; gap: 14px; margin: 0; padding: 8px 12px; border: 1px solid var(--ink); border-radius: var(--radius); background: var(--weirwood); font-size: 40px; line-height: 1.2; }
.scroll--open { margin: 0 6px; padding: 44px 24px 56px; }
.scroll .attrib { display: flex; align-items: center; justify-content: center; gap: var(--s2); margin: var(--s3) 0 0; font: 400 var(--fs-small)/1.3 var(--font-ui); }
.scroll .attrib .sigil { --sigil-edge: var(--sigil-edge-pale); }
.scroll .seal-broken { position: absolute; left: 50%; bottom: -34px; width: 96px; height: 80px; margin-left: -48px; }

/* The misses. Raven: pills with a drawn cross. Fallen: a row each, the name on the left and a tile on the right that says when the guess fell and which way the answer lies. */
.x { flex: none; display: inline-block; width: 12px; height: 12px; overflow: hidden; background-color: var(--danger-text); color: transparent; font-size: 12px; line-height: 12px; -webkit-mask: var(--mask-cross) center / contain no-repeat; mask: var(--mask-cross) center / contain no-repeat; }
.x.ok { background-color: var(--text); -webkit-mask-image: var(--mask-check); mask-image: var(--mask-check); }
.misses { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s3) 0 0; padding: 0; list-style: none; }
.miss-pill { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 12px 0 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); font: 400 var(--fs-small)/1 var(--font-ui); }
.miss-pill.correct { border-color: var(--edge); font-weight: 700; }
.miss-pill .who { overflow-wrap: anywhere; }
.miss-list { margin: var(--s3) calc(var(--bleed) * -1) 0; padding: 0; list-style: none; }
.miss-row { display: grid; grid-template-columns: auto minmax(0, 1fr) 132px; align-items: center; column-gap: var(--s2); padding: 8px var(--bleed); border-top: 1px solid var(--line); }
.miss-row:first-child { border-top: 0; padding-top: 0; }
.miss-row .who { min-width: 0; font: 700 var(--fs-input)/1.25 var(--font-body); overflow-wrap: anywhere; }
.miss-row.correct .who { grid-column: 2 / -1; }
.miss-row .miss-tile { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 2px; min-height: 56px; padding: 5px 4px 6px 5px; text-align: left; place-items: unset; overflow-wrap: break-word; }
.miss-tile .lbl { position: static; display: flex; align-items: center; justify-content: space-between; gap: 2px; font: 700 var(--fs-micro)/1.2 var(--font-ui); letter-spacing: var(--tr-micro); white-space: nowrap; }
.miss-tile .lt { display: inline; }
.miss-tile .died { display: flex; align-items: center; gap: 4px; font: 400 var(--fs-tile)/var(--lh-tile) var(--font-ui); }
.miss-tile .died svg { flex: none; }

/* The hints: a locked one is a line of words (no control, no box), a ready one a 44 px button, a revealed one a bordered row */
.hints { display: grid; gap: var(--s2); margin: var(--s3) 0 0; padding: 0; list-style: none; }
.hints li { margin: 0; }
.hints .locked { display: flex; align-items: baseline; gap: var(--s2); min-height: 28px; padding: 0 4px; color: var(--muted); font: 400 var(--fs-small)/1.45 var(--font-ui); }
.hints .locked b { font-weight: 700; }
.hint-btn { width: 100%; justify-content: flex-start; white-space: normal; text-align: left; }
.hints .revealed { display: flex; align-items: center; gap: var(--s3); padding: var(--s3); border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); font: 400 var(--fs-body)/1.3 var(--font-body); animation: pop 320ms ease both; }
.hints .revealed b { color: var(--muted); font: 700 var(--fs-small)/1 var(--font-ui); }
@keyframes pop { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* The fallen banner (spec-cards 5.6.4): the pennon's cloth lowered and turned, crape across the top, the House's sigil dimmed. The cloth is pale in both themes. */
.banner { display: block; flex: none; --text: var(--ink); --panel-2: var(--cloth-2); --sigil-edge: var(--sigil-edge-pale); }
.banner--hint { margin: -4px 0; }
.miss-tile .mk { width: 12px; height: 12px; }

/* ---- The result: the win card holds it (below). Everything the page says about the answer sits under the title, Share first. ---- */
.result { margin: 18px auto 24px; max-width: 640px; scroll-margin-top: 8px; }
.faster { margin: 0; padding: 8px 12px; border-radius: var(--radius); background: var(--panel-2); border: 1px solid var(--edge); font: 400 var(--fs-small)/1.45 var(--font-ui); }
.faster b { color: var(--accent); }
.result-facts { display: grid; grid-template-columns: 6.2em minmax(0, 1fr); gap: var(--s2) var(--s3); margin: 0; padding-top: var(--s3); border-top: 1px solid var(--line); text-align: left; font: 400 var(--fs-small)/1.35 var(--font-ui); }
.result-facts dt { padding-top: 2px; color: var(--muted); font: 700 var(--fs-micro)/var(--lh-micro) var(--font-ui); text-transform: uppercase; letter-spacing: 0.06em; }
.result-facts dd { margin: 0; overflow-wrap: anywhere; }
.actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 10px; }
.next { margin: 14px 0 0; color: var(--muted); font: 400 var(--fs-small)/var(--lh-small) var(--font-ui); }
.notes { color: var(--muted); font: 400 var(--fs-small)/var(--lh-small) var(--font-ui); }
.reveal { margin: 6px 0 0; padding: var(--s3); text-align: center; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--panel); }

/* ---- Footer (spec-theme 3.14): the credit is the only place besides the tagline that names the show ---- */
.site-footer { max-width: 1100px; margin: 20px auto 30px; padding: 0 var(--gutter); color: var(--muted); font: 400 var(--fs-small)/1.5 var(--font-ui); }
.site-footer p { margin: 0 0 6px; }
.site-footer .dexverse b { color: var(--accent); letter-spacing: 0.02em; }
.site-footer .also a { margin: 0 2px; }
.credit a { display: inline-block; padding: 14px 6px; margin: -14px -6px; }   /* a 44 px target inside running text */

/* ---- Dialog (spec-theme 3.14). A real <dialog>: no display rule here, the browser shows it only while it is open ---- */
.dialog { margin: auto; padding: 0; width: calc(100% - 32px); max-width: min(560px, calc(100vw - 32px)); border: 1px solid var(--edge); border-radius: var(--radius-lg); background: var(--panel); color: var(--text); box-shadow: var(--shadow-1); }
.dialog::backdrop { background: var(--scrim); }
.dialog-body { padding: 20px; }
.dialog-body > :last-child { margin-bottom: 0; }
.dialog h2 { margin: 0 0 10px; }
.dialog-title { font-size: var(--fs-title); line-height: var(--lh-title); letter-spacing: var(--tr-title); }
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; text-align: center; margin: 8px 0 14px; }
.stat-row b { display: block; font: 600 26px/1.2 var(--font-display); }
.stat-row span { font: 400 var(--fs-tile)/1.3 var(--font-ui); color: var(--muted); }
.dialog h3 { margin: 0 0 6px; font-size: var(--fs-chip); letter-spacing: var(--tr-chip); }
.dist { display: grid; gap: 4px; margin-bottom: 14px; }
.dist .bar { display: grid; grid-template-columns: 28px 1fr; align-items: center; gap: 6px; font: 400 var(--fs-tile)/1.3 var(--font-ui); }
.dist .fill { background: var(--tile-no); color: var(--tile-ink); border-radius: 4px; padding: 2px 6px; min-width: 22px; text-align: right; box-shadow: inset 0 0 0 var(--tile-ring) var(--edge); }
.dist .fill.me { background: var(--tile-yes); }

/* ---- Today's board ---- */
.leaderboard { margin: 0 auto 24px; max-width: 640px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 18px; box-shadow: var(--shadow-1); }
.leaderboard h2 { margin: 0 0 4px; }
.leaderboard h3 { margin: 16px 0 6px; font: 700 var(--fs-micro)/1.4 var(--font-ui); text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.leaderboard .fun { color: var(--muted); font: 400 var(--fs-small)/var(--lh-small) var(--font-ui); margin: 0 0 10px; }
.lb-table { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.lb-table li { display: grid; grid-template-columns: 32px 1fr auto auto; gap: 10px; align-items: center; padding: 8px 10px; border-radius: var(--radius); background: var(--panel-2); font: 400 var(--fs-small)/1.45 var(--font-ui); }
.lb-table li.me { background: var(--panel-2); box-shadow: inset 0 0 0 2px var(--accent); font-weight: 700; }
.lb-table .rank { color: var(--muted); font-variant-numeric: tabular-nums; }
.lb-table li.me .rank { color: var(--accent); }
.lb-table .handle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-table .num { font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; }
.lb-table li.me .num { color: var(--text); }
.lb-empty { color: var(--muted); font: 400 var(--fs-small)/var(--lh-small) var(--font-ui); margin: 4px 0; }
.lb-you { margin: 12px 0 0; font: 400 var(--fs-small)/1.6 var(--font-ui); color: var(--muted); }
.lb-you b { color: var(--text); }
.link-btn { border: 0; background: transparent; color: var(--accent); cursor: pointer; font: inherit; text-decoration: underline; text-underline-offset: 3px; }
/* 44px hit area for links in running text: padding out, margin back in */
.link-btn, .notes a { display: inline-block; padding: 14px 6px; margin: -14px -6px; }
.handle-row { display: flex; gap: 8px; margin: 8px 0 6px; }
.handle-row .guess-input { flex: 1; }
.handle-error { color: var(--danger-text); font: 400 var(--fs-tile)/1.4 var(--font-ui); min-height: 1.4em; margin: 0 0 6px; }
.check { display: flex; align-items: center; gap: 8px; min-height: var(--tap); font: 400 var(--fs-small)/1.45 var(--font-ui); margin: 4px 0 10px; color: var(--muted); }
.check input { width: 24px; height: 24px; flex: none; accent-color: var(--accent); }

/* ---- The win card (spec-theme 3.15): a pennon unfurls from a rod, then a wax seal is stamped. Classes ready for the card renderers. ---- */
.win-card {
  position: relative; display: grid; justify-items: center; gap: var(--s3);
  padding: 22px var(--gutter) var(--s5); text-align: center;
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--panel); box-shadow: var(--shadow-1);
}
.win-card::before {                     /* the rod the pennon hangs from: it is there on the first frame */
  content: ""; position: absolute; top: 16px; left: 50%; width: 112px; height: 8px; margin-left: -56px;
  border-radius: 4px; background: var(--accent);
}
.pennon {
  display: block; width: 104px; height: 140px; overflow: hidden;
  --text: var(--ink); --panel-2: var(--cloth-2); --sigil-edge: var(--sigil-edge-pale);   /* the cloth is pale in both themes: a sigil drawn with the page tokens, and the sprite's own edge, take the dark-on-light values */
  animation: unfurl var(--unfurl) var(--ease-out) both;
}
.pennon .cloth { fill: var(--weirwood); stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.pennon .fold { fill: none; stroke: var(--ink); stroke-opacity: .35; stroke-width: 1; stroke-dasharray: 3 3; }
.pennon .shade { fill: var(--ink); fill-opacity: .18; }
.seal {
  position: absolute; top: 118px; left: calc(50% + 24px); width: 60px; height: 60px; display: grid; place-items: center;
  border-radius: 52% 48% 50% 50% / 50% 53% 47% 50%;
  background: radial-gradient(circle at 36% 30%, var(--blood) 0%, var(--blood) 38%, var(--seal-deep) 100%);
  box-shadow: var(--shadow-seal);
  animation: stamp var(--stamp) var(--ease-out) var(--unfurl) both;
}
.seal::after {                          /* the stamped ring */
  content: ""; position: absolute; inset: 6px; border: 1.5px solid var(--bone); border-radius: 50%; opacity: .5;
}
.seal-day { position: relative; z-index: 1; color: var(--bone); font: 600 var(--fs-seal)/1 var(--font-display); letter-spacing: 0; }
.win-card .win-title { margin: var(--s3) 0 0; font-size: var(--fs-win); line-height: var(--lh-win); letter-spacing: var(--tr-win); }
.win-card .win-lead { margin: 0; color: var(--muted); }
/* The rest of the card: a settled card (a reload, a mode switch) has no motion; Fallen hangs a banner and has no seal; Raven opens the scroll inside the card */
.win-card > * { min-width: 0; max-width: 100%; }
.win-card--static .pennon, .win-card--static .seal { animation: none; }
.win-card--fallen::before, .win-card--raven::before { display: none; }
.win-card--fallen { padding-top: var(--s5); }
.win-card .win-title { overflow-wrap: anywhere; }
.win-card .blazon { margin: 0; }
.win-card .actions, .win-card .faster, .win-card .result-facts, .win-card .notes, .win-card .next { justify-self: stretch; margin-top: 0; margin-bottom: 0; }
.win-card .notes, .win-card .next { text-align: left; }
.win-card .actions--share .btn { flex: 1; }
.win-card--raven .scroll { justify-self: stretch; margin-bottom: 36px; }
@keyframes unfurl { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes stamp { from { opacity: 0; transform: scale(1.35) rotate(-8deg); } to { opacity: 1; transform: none; } }

/* ---- Reduced motion (spec-theme 3.16): the pennon and the seal are simply there, the embers stop, transitions only fade ---- */
@media (prefers-reduced-motion: reduce) {
  .tile.fresh, .miss-row.fresh, .miss-pill.fresh, .hints li, .embers i, .pennon, .seal { animation: none; }
  .btn, .chip, .icon-btn, .tabs > [role="tab"] { transition-property: opacity; }
  .btn:active, .chip:active, .icon-btn:active { transform: none; }
}
[data-motion="reduce"] .embers i,
[data-motion="reduce"] .pennon,
[data-motion="reduce"] .seal { animation: none; }
[data-motion="reduce"] :is(.btn, .chip, .icon-btn, .tabs > [role="tab"]) { transition-property: opacity; }

/* ---- Windows high contrast: the drawn marks are backgrounds, which the system would blank. Keep them. ---- */
@media (forced-colors: active) {
  .chip::before, .segmented > [role="radio"]::before, .alert::before { forced-color-adjust: none; background-color: CanvasText; }
  .tabs > [aria-selected="true"]::before { forced-color-adjust: none; background: Highlight; }
  .tile, .swatch, .seal, .pennon, .banner, .scroll, .seal-broken, .chip[aria-checked="true"], .segmented > [aria-checked="true"], .btn--primary, .btn.primary { forced-color-adjust: none; }
  .x { forced-color-adjust: none; background-color: CanvasText; }
}

/* ---- Phones: 640px and narrower, the one breakpoint (app.js reads the same one) ---- */
@media (max-width: 640px) {
  /* Input row, status line, empty state */
  .guess-form { max-width: none; margin: 4px 0 0; scroll-margin-top: 8px; }
  .empty { padding: 0 0 6px; }
  .empty .guess.ghost { margin-top: var(--s2); }
  .empty .guess.ghost > .tile:not(.name) { min-height: 40px; }   /* a preview, not a control: four px shorter than a real tile so the whole row fits the first screen at 320 x 568 */
  .empty > p { margin: 0 var(--bleed) 6px; }   /* the text lines up with the input (16 px), the preview row below keeps the board's 8 px bleed */
  .empty > .btn { margin-left: var(--bleed); }

  /* The board has no sideways scroll: each guess is a card of a name line, 4 tiles, 3 tiles and a detail line */
  .board { margin: 0 calc(var(--bleed) * -1); }
  .grid-scroll { overflow: visible; padding: 0 0 8px; }
  .grid { display: block; min-width: 0; }
  .grid .head { display: none; }
  .grid .guess { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 6px; padding: 10px 0 12px; }
  .grid .guess + .guess { border-top: 1px solid var(--line); }
  .grid .guess:first-of-type { padding-top: 4px; }
  .grid .guess > .tile { grid-column: span 3; min-height: 56px; }   /* spec-cards 5.4.3: every tile is at least 56 px tall */
  .grid .guess > .tile:nth-child(n + 6) { grid-column: span 4; }
  .grid .guess > .tile:not(.name) { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 2px; padding: 5px 3px 6px; font-size: var(--fs-tile); line-height: var(--lh-tile); text-align: left; }
  .grid .guess > .tile.name { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; min-height: 0; padding: 0 calc(var(--gutter) - var(--bleed)); background: none; box-shadow: none; color: var(--text); text-align: left; }
  .grid .guess .name .real { display: inline; }
  .grid .guess .name .score { display: inline; margin-left: auto; font: 700 var(--fs-small)/1 var(--font-ui); color: var(--muted); }
  .grid .guess .tile .lbl { position: static; display: flex; align-items: center; justify-content: space-between; gap: 2px; font: 700 var(--fs-micro)/1.2 var(--font-ui); letter-spacing: var(--tr-micro); white-space: nowrap; }
  .grid .guess .tile .lt { display: inline; }
  .grid .guess .tile .val { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; line-clamp: 4; overflow: hidden; overflow-wrap: break-word; hyphens: manual; }
  .grid .guess .tile .sub { display: flex; align-items: center; gap: 4px; }
  .grid .guess .tile .val { margin-top: auto; }   /* label at the top, value at the bottom (the Debut tile's words and arrow stay under its value) */
  .grid .guess .tile .val.val--house { display: flex; justify-content: flex-start; }

  /* Result, board, dialogs */
  .result { margin: 14px 0 20px; }
  .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .actions .btn { padding: 0 4px; }
  .actions .btn.primary { grid-column: 1 / -1; }
  .leaderboard { margin: 0 0 20px; padding: 16px; }
  .dialog { width: calc(100% - 16px); max-width: 560px; }
  .dialog-body { padding: 16px 12px; }
  .dialog .actions .btn.primary { grid-column: auto; }
  .dialog .guess.example { margin: 0 -6px; }
  .dialog > form > .btn { width: 100%; }
  .handle-row .btn { flex: none; }

  /* Footer: Also-play links are 44px pills; the credit link keeps its place in the sentence */
  .site-footer { margin: 16px 0 24px; }
  .site-footer .dexverse { margin: 0 0 14px; }
  .site-footer .also { display: inline-flex; flex-wrap: wrap; align-items: center; vertical-align: middle; }
  .site-footer .also a { display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); min-width: var(--tap); padding: 0 10px; margin: 0; }
}

/* Wide screens: the first screen's lines sit on the centre line, as the form does */
@media (min-width: 641px) {
  .status, .empty { text-align: center; }
  .key { justify-content: center; gap: 4px 18px; }
  .empty .btn { margin: 0 auto; }
  .empty .guess.ghost { text-align: left; }
}
