/* ===== @font-face: generated by tools/subset_fonts.py --css --write, do not edit ===== */
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:300;font-display:swap;
  src:url("fonts/zkgn-300.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:300;font-display:swap;
  src:url("fonts/zkgn-300-cjk.woff2") format("woff2");
  unicode-range:U+3007, U+304D, U+306E, U+308A, U+4E00, U+4E03, U+4E09-4E0A, U+4E2D, U+4E5D, U+4E8C, U+4E94, U+4ECA, U+5148, U+516B, U+516D, U+521D, U+5341, U+53F7, U+5411, U+544A, U+56DB, U+571F, U+5B8C, U+5B9A, U+5E74, U+5E83, U+5EA6, U+623B, U+6570, U+65E5, U+6613, U+6642, U+66DC, U+6708, U+6728, U+691C, U+6A2A, U+6B8B, U+6C34, U+6D88, U+706B, U+72EC, U+751F, U+767B, U+7B2C, U+7D1A, U+8A18, U+8A2D, U+91D1, U+9332, U+9593, U+96E3;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:400;font-display:swap;
  src:url("fonts/zkgn-400.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:400;font-display:swap;
  src:url("fonts/zkgn-400-cjk.woff2") format("woff2");
  unicode-range:U+3007, U+304D, U+306E, U+308A, U+4E00, U+4E03, U+4E09-4E0A, U+4E2D, U+4E5D, U+4E8C, U+4E94, U+4ECA, U+5148, U+516B, U+516D, U+521D, U+5341, U+53F7, U+5411, U+544A, U+56DB, U+571F, U+5B8C, U+5B9A, U+5E74, U+5E83, U+5EA6, U+623B, U+6570, U+65E5, U+6613, U+6642, U+66DC, U+6708, U+6728, U+691C, U+6A2A, U+6B8B, U+6C34, U+6D88, U+706B, U+72EC, U+751F, U+767B, U+7B2C, U+7D1A, U+8A18, U+8A2D, U+91D1, U+9332, U+9593, U+96E3;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:500;font-display:swap;
  src:url("fonts/zkgn-500.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:500;font-display:swap;
  src:url("fonts/zkgn-500-cjk.woff2") format("woff2");
  unicode-range:U+3007, U+304D, U+306E, U+308A, U+4E00, U+4E03, U+4E09-4E0A, U+4E2D, U+4E5D, U+4E8C, U+4E94, U+4ECA, U+5148, U+516B, U+516D, U+521D, U+5341, U+53F7, U+5411, U+544A, U+56DB, U+571F, U+5B8C, U+5B9A, U+5E74, U+5E83, U+5EA6, U+623B, U+6570, U+65E5, U+6613, U+6642, U+66DC, U+6708, U+6728, U+691C, U+6A2A, U+6B8B, U+6C34, U+6D88, U+706B, U+72EC, U+751F, U+767B, U+7B2C, U+7D1A, U+8A18, U+8A2D, U+91D1, U+9332, U+9593, U+96E3;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:700;font-display:swap;
  src:url("fonts/zkgn-700.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
@font-face{font-family:"Zen Kaku Gothic New";font-style:normal;font-weight:700;font-display:swap;
  src:url("fonts/zkgn-700-cjk.woff2") format("woff2");
  unicode-range:U+3007, U+304D, U+306E, U+308A, U+4E00, U+4E03, U+4E09-4E0A, U+4E2D, U+4E5D, U+4E8C, U+4E94, U+4ECA, U+5148, U+516B, U+516D, U+521D, U+5341, U+53F7, U+5411, U+544A, U+56DB, U+571F, U+5B8C, U+5B9A, U+5E74, U+5E83, U+5EA6, U+623B, U+6570, U+65E5, U+6613, U+6642, U+66DC, U+6708, U+6728, U+691C, U+6A2A, U+6B8B, U+6C34, U+6D88, U+706B, U+72EC, U+751F, U+767B, U+7B2C, U+7D1A, U+8A18, U+8A2D, U+91D1, U+9332, U+9593, U+96E3;}
@font-face{font-family:"Shippori Mincho B1";font-style:normal;font-weight:800;font-display:swap;
  src:url("fonts/smb1-800.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
@font-face{font-family:"Shippori Mincho B1";font-style:normal;font-weight:800;font-display:swap;
  src:url("fonts/smb1-800-cjk.woff2") format("woff2");
  unicode-range:U+3007, U+304D, U+306E, U+308A, U+4E00, U+4E03, U+4E09-4E0A, U+4E2D, U+4E5D, U+4E8C, U+4E94, U+4ECA, U+5148, U+516B, U+516D, U+521D, U+5341, U+53F7, U+5411, U+544A, U+56DB, U+571F, U+5B8C, U+5B9A, U+5E74, U+5E83, U+5EA6, U+623B, U+6570, U+65E5, U+6613, U+6642, U+66DC, U+6708, U+6728, U+691C, U+6A2A, U+6B8B, U+6C34, U+6D88, U+706B, U+72EC, U+751F, U+767B, U+7B2C, U+7D1A, U+8A18, U+8A2D, U+91D1, U+9332, U+9593, U+96E3;}
@font-face{font-family:"DM Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url("fonts/dmmono-400.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
@font-face{font-family:"DM Mono";font-style:normal;font-weight:500;font-display:swap;
  src:url("fonts/dmmono-500.woff2") format("woff2");
  unicode-range:U+20-7E, U+A0-FF, U+152-153, U+160-161, U+178, U+17D-17E, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2039-203A, U+20AC;}
/* ===== end @font-face ===== */
/* ===== Tokens: the one place for colours, type and shared sizes =====
   Ink lines (board, frames, rules) are printed through SVG filters (v5); grey hairlines stay
   crisp, like the guide rules of a magazine page (v4). :where() keeps the tokens at zero
   specificity, so a layout block below overrides a size token by order alone.
   Colours: primitives --g-N are greys in OKLCH with chroma 0 (N = lightness %); every semantic
   colour is light-dark(light, dark) of them, so one block serves both themes. The scheme comes
   from the system (color-scheme: light dark) unless <html data-theme> is set (choices.js; kept
   with the settings record). The one accent is --err*: errors and conflicts only; the one other
   colour is --sakura, spring's solve petals (app.js SEASONS). tools/contrast_guard.py checks
   the pairs of tools/contrast_pairs.txt in both themes and writes the PERUSTELUT.md table;
   tools/build_manifest.py writes the manifest colours from --ink and --paper.
   Type: every font-size and font-weight is a --fs-* / --fw-* token (dry_guard checks it);
   --fs-day and --fs-pick are role sizes that the layout blocks reset.
   Two tokens come from the script: --fade (TIME.FADE) and --edge (EDGE.POP). --ad-anchor-h and
   --ad-ph-w are the data-ad sizes of the anchor and the touch phone ad (dry_guard checks that
   they match). */
:where(:root){
  color-scheme:light dark;
  --g-0:oklch(0% 0 0);
  --g-18:oklch(18% 0 0);
  --g-19:oklch(19% 0 0);
  --g-21:oklch(21% 0 0);
  --g-26:oklch(26% 0 0);
  --g-30:oklch(30% 0 0);
  --g-35:oklch(35% 0 0);
  --g-39:oklch(39% 0 0);
  --g-41:oklch(41% 0 0);
  --g-49:oklch(49% 0 0);
  --g-52:oklch(52% 0 0);
  --g-56:oklch(56% 0 0);
  --g-60:oklch(60% 0 0);
  --g-64:oklch(64% 0 0);
  --g-67:oklch(67% 0 0);
  --g-77:oklch(77% 0 0);
  --g-86:oklch(86% 0 0);
  --g-87:oklch(87% 0 0);
  --g-93:oklch(93% 0 0);
  --g-94:oklch(94% 0 0);
  --g-97:oklch(97% 0 0);
  --g-100:oklch(100% 0 0);
  --paper:light-dark(var(--g-97),var(--g-18));
  --surface:light-dark(var(--g-100),var(--g-21));
  --ink:light-dark(var(--g-19),var(--g-94));
  --ink-2:light-dark(var(--g-41),var(--g-77));
  --ink-3:light-dark(var(--g-49),var(--g-67));
  --rule:light-dark(var(--g-64),var(--g-52));  /* thin printed cell lines */
  --muted:var(--rule);      /* off keys: clearly off, still legible (about 3:1, not --hair) */
  --hair:light-dark(var(--g-87),var(--g-30));  /* crisp grey hairlines, decorative */
  --hl:light-dark(var(--g-93),var(--g-26));
  --hl-strong:light-dark(var(--g-86),var(--g-35));
  --entry:light-dark(var(--g-39),var(--g-77)); /* the player's own digits (givens: --ink, print face) */
  --sel-bg:var(--ink);
  --sel-fg:var(--paper);
  --err:light-dark(#AF1C12,#F08A7E);           /* the only accent: errors and conflicts */
  --err-on-sel:light-dark(#FF8F80,#A3271B);
  --err-bg:color-mix(in srgb,var(--err) 12%,transparent);
  --sakura:light-dark(oklch(84% 0.08 355),oklch(93% 0.035 355)); /* the one other colour: spring's solve petals */
  --hatch:color-mix(in srgb,var(--ink) 6%,transparent);
  --focus:var(--ink);       /* the keyboard focus ring (inverse surfaces: --sel-fg) */
  --shadow:light-dark(color-mix(in srgb,var(--g-0) 22%,transparent),color-mix(in srgb,var(--g-0) 60%,transparent));
  --veil:color-mix(in srgb,var(--surface) 82%,transparent);
  /* Wood grain: the old multiply (light) / screen (dark) layer over --surface, as one masked
     colour: multiply(white, 45 % grey) = --g-56 at .38, screen(--g-21, 45 % grey) = --g-60 at .07 */
  --grain:light-dark(color-mix(in srgb,var(--g-56) 38%,transparent),color-mix(in srgb,var(--g-60) 7%,transparent));
  --f-jp:"Zen Kaku Gothic New","Hiragino Kaku Gothic ProN","Yu Gothic",system-ui,sans-serif;
  --f-print:"Shippori Mincho B1","Hiragino Mincho ProN","Yu Mincho",Georgia,serif;
  --f-mono:"DM Mono",ui-monospace,"SFMono-Regular",Menlo,monospace;
  --fs-3xs:10px;            /* type scale */
  --fs-2xs:11px;
  --fs-xs:12px;
  --fs-s:13px;
  --fs-m:14px;
  --fs-base:15px;
  --fs-l:16px;
  --fs-xl:17px;
  --fs-2xl:18px;
  --fs-3xl:20px;
  --fs-4xl:22px;
  --fs-5xl:26px;
  --fs-6xl:28px;
  --fs-day:56px;            /* role sizes: the date numeral (layout blocks reset it) */
  --fs-pick:var(--fs-5xl);  /* difficulty numerals */
  --fs-hanko:82px;          /* 完 in the win stamp (SVG user units) */
  --fs-print:56px;          /* digits of the print sheet boards (SVG user units of the 900 grid) */
  --fs-cell:clamp(18px,6.4cqi,38px);   /* board digits follow the board width */
  --fs-given:clamp(19px,6.8cqi,40px);
  --fs-note:clamp(8px,2.15cqi,12px);
  --fs-note-pair:clamp(10px,2.9cqi,15px); /* Mukautuva: 1–3 candidates as a row, a little larger */
  --note-in:13%;            /* Mukautuva row and Kulmat: inset from the cell edge (box rules and frame cover 12.5 %) */
  --fw-light:300;           /* the weights served in fonts/ */
  --fw-regular:400;
  --fw-medium:500;
  --fw-bold:700;
  --fw-heavy:800;           /* Shippori Mincho B1: the printed face */
  --gutter:16px;            /* page side margin; the landscape layout uses --gutter-l */
  --gutter-l:32px;
  --col-l:280px;            /* side column (the landscape block widens it for the four status buttons) */
  --maxw:600px;
  --tap:44px;               /* minimum touch target */
  --key-h:46px;             /* numerotoast action row */
  --nt:56px;                /* numerotoast key */
  --ad-anchor-h:50px;
  --ad-ph-w:320px;
  --anchor-h:var(--ad-anchor-h);
  --anchor-total:calc(var(--anchor-h) + 2px + env(safe-area-inset-bottom));
  --chrome:364px;           /* everything in a narrow window except the board: 296 px above it, its 8 px frame, the 52 px anchor, 8 px air */
  --bmin:280px;
  --board-cap:100%;
  --board-w:min(100%,var(--board-cap),max(var(--bmin),calc(100svh - var(--chrome))));
  --wrap-t:32px;            /* landscape: board frame top and bottom padding, also the rail's */
  --wrap-b:32px;
  --rail-space:36px;
  --ad-air:12px;            /* landscape: air above and below the ad in the side column */
  --sh-board:88mm;          /* print sheet: board width; 2 boards + --sh-gap fit 190 mm (A4 and Letter, 10 mm margins) */
  --sh-gap:12mm;
  &[data-theme=light]{color-scheme:light} /* the manual theme (choices.js) overrides the system */
  &[data-theme=dark]{color-scheme:dark}
  &[data-layout~=print]{color-scheme:light} /* print: paper colours, black ink, whatever the theme */
}

/* ===== Base ===== */
*,*::before,*::after{box-sizing:border-box}
/* app.js builds the board, keys and ads after the first paint could happen (an external script):
   the page stays invisible until app.js marks <html class="ready">, so nothing shifts (CLS). */
html:not(.ready) body{visibility:hidden}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--f-jp);font-weight:var(--fw-regular);font-size:var(--fs-base);line-height:1.5;
  overflow-x:hidden;
  padding-bottom:calc(var(--anchor-total) + 14px); /* the anchor ad and 16 px of air above its rule */
  -webkit-font-smoothing:antialiased;
}
/* No operating-system UI (owner 2026-11-02, PERUSTELUT "Ei käyttöjärjestelmän elementtejä"): every
   control is drawn here (appearance:none, own switches and segments), the focus ring is --focus,
   the selection and the scrollbars are tokens, no tap highlight; dry_guard "native" checks the markup. */
button{appearance:none;font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation}
a{color:inherit;-webkit-tap-highlight-color:transparent}
:focus:not(:focus-visible){outline:none}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
::selection{background:var(--ink);color:var(--paper)}
html,.settings{scrollbar-width:thin;scrollbar-color:var(--rule) transparent}
::-webkit-scrollbar{width:8px;height:8px;background:transparent}
::-webkit-scrollbar-thumb{background:var(--rule)}
/* Skip link: the first Tab stop, shown only while it has the focus */
.skip{position:absolute;z-index:60;left:var(--gutter);top:8px;padding:8px 14px;background:var(--surface);font-size:var(--fs-m);font-weight:var(--fw-bold);transform:translateY(-200%)}
.skip:focus{transform:none}
.defs{position:absolute;width:0;height:0}
.jp{font-family:var(--f-jp);font-weight:var(--fw-medium);letter-spacing:.08em;font-size:var(--fs-3xs);color:var(--ink-3)}
.mono{font-family:var(--f-mono);font-feature-settings:"tnum"}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.brow{display:contents} /* the board's ARIA rows: the cells stay items of the board grid */
/* The printed face (mincho 800): seal, scale numerals, givens, key kanji, active number, hanko */
.seal,.pick b,.cell.given,.k .kj,.hanko .big{font-family:var(--f-print);font-weight:var(--fw-heavy)}
/* Every printed ink stroke */
.ink line,.ink rect.s,.grid-lines line,.grid-lines rect,.turn-ico .s,.hanko .ring{stroke:var(--ink);fill:none;stroke-linecap:square}
.inked{position:relative}
.ink{position:absolute;left:0;top:0;pointer-events:none;overflow:visible;z-index:2}

/* ===== Header ===== */
.top{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  height:var(--tap);padding:0 var(--gutter);
}
.mark{display:flex;align-items:center;gap:9px;text-decoration:none;min-width:0}
.seal{
  width:22px;height:22px;background:var(--ink);color:var(--paper);flex:none;
  display:grid;place-items:center;font-size:var(--fs-m);line-height:1;
}
.word{font-weight:var(--fw-bold);font-size:var(--fs-xl);letter-spacing:-.01em;white-space:nowrap}
.word span{font-weight:var(--fw-light)}
.word .jp{margin-left:8px;font-size:var(--fs-2xs)}
.login{display:inline-flex;align-items:center;gap:8px;min-height:var(--tap);font-size:var(--fs-s);text-decoration:none;white-space:nowrap}
.login u{text-decoration:none;border-bottom:1px solid var(--ink-3);padding-bottom:1px}
.word .jp,.login .long{display:none}
:where(html[data-layout~=w420]:not([data-layout~=tiny])) :is(.word .jp,.login .long){display:inline}

/* ===== Ads: sizes reserved up front (no CLS) by placeAds() from data-ad =====
   No ad ever sits above the game: every slot is below the board, or beside it. */
.ad{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  margin:0 auto;max-width:100%;flex:none;
  border:1px dashed var(--hair);
  background:repeating-linear-gradient(135deg,var(--hatch) 0 1px,transparent 1px 8px);
  color:var(--ink-3);font-size:var(--fs-2xs);letter-spacing:.04em;
}
.ad b{font-weight:var(--fw-medium);font-family:var(--f-mono)}
/* Offline (LAYOUT "offline", layout.js): the slot keeps its box (no shift) as a neutral empty frame.
   The networked controls (app.js ONLINE_ONLY) are greyed by setOff(): the .off rule of the status row. */
:where(html[data-layout~=offline]) .ad{background:none;& > *{visibility:hidden}}
.slot{display:none;justify-content:center}
.slot .alt{display:none}
/* The ad table: a slot shows only in the layouts listed here, .alt is a slot's second size. */
:where(html[data-layout~=phone]) :is(.ad-anchor,.ad-below),
:where(html:not([data-layout~=land])) .ad-rect,
:where(html[data-layout~=land][data-layout~=w640]) .ad-col,
:where(html[data-layout~=land][data-layout~=w1280]:not([data-layout~=tiny])) .ad-side,
:where(html[data-layout~=w768]:not([data-layout~=touch][data-layout~=tiny])) .ad-wide{display:flex}
:where(html[data-layout~=tiny]) .ad-col,:where(html[data-layout~=w1440]) .ad-side{
  & .ad{display:none}
  & .alt{display:flex}
}
.ad-wide{padding:24px var(--gutter) 0}
.ad-below{padding:16px 0 0}
.ad-rect{padding:16px 0 20px}
.ad-col .ad{margin:0}
.ad-anchor{
  position:fixed;left:0;right:0;bottom:0;z-index:20;
  height:var(--anchor-total);padding:2px 0 env(safe-area-inset-bottom);background:var(--paper);
}
.ad-anchor .ad{border-top:0;border-bottom:0}

/* ===== Layout ===== */
.layout{display:grid;grid-template-columns:minmax(0,1fr);padding:0 var(--gutter);max-width:var(--maxw);margin:0 auto}

/* Intro (v4): date numeral + issue + day's three puzzles */
.intro{padding:10px 0 10px}
.dateline{display:grid;grid-template-columns:auto 1fr;column-gap:14px;align-items:end}
.day{font-weight:var(--fw-light);font-size:var(--fs-day);line-height:.78;letter-spacing:-.04em;font-feature-settings:"tnum";margin:0}
.datemeta{display:flex;flex-direction:column;gap:2px;min-width:0;line-height:1.25}
.datemeta .row{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.weekday{font-size:var(--fs-m);font-weight:var(--fw-medium)}
.fulldate{font-size:var(--fs-s);color:var(--ink-2)}
.issue{font-size:var(--fs-2xs);color:var(--ink-3)}

.levels{margin-top:10px}
.levels-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:5px;line-height:1.3}
.levels-head h2{margin:0;font-size:var(--fs-xs);font-weight:var(--fw-medium);letter-spacing:.02em}

/* Difficulty scale (v5): woodblock numerals in one printed frame */
.picker{display:grid;grid-template-columns:repeat(3,1fr)}
.pick{min-height:var(--tap);display:flex;align-items:center;justify-content:center;gap:8px;padding:4px}
.pick b{font-size:var(--fs-pick);line-height:1}
.pick span{font-size:var(--fs-s);font-weight:var(--fw-bold);letter-spacing:.02em}
.pick:not([aria-pressed="true"]):hover,.seg [aria-checked="false"]:hover{background:var(--hl)}

/* Status, the same on every device: Aika | Jäljellä side by side on the first row, then Kumoa,
   Tarkista, Sensei, Asetukset (the markup order is the Tab order) in a 4-track grid, so every
   button gets exactly the same width whatever its label. Tablet portrait: one row (the tablet
   block); touch landscape under 640 px: the buttons 2 × 2 (the last block). */
.status{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;align-items:stretch;padding-bottom:2px}
.stats{grid-column:1 / -1;display:flex;min-width:0}
.stat{display:flex;flex-direction:column;justify-content:center;min-height:var(--tap);line-height:1.3;min-width:0}
.stat + .stat{margin-left:10px;padding-left:10px;border-left:1px solid var(--hair)}
.stat .l{font-size:var(--fs-2xs);color:var(--ink-3);display:flex;gap:6px;align-items:baseline;white-space:nowrap}
.stat .v{font-size:var(--fs-2xl);font-weight:var(--fw-medium)}
.act{
  align-self:center;min-height:var(--tap);min-width:0;padding:0 8px;
  display:flex;align-items:center;justify-content:center;gap:6px;font-size:var(--fs-s);font-weight:var(--fw-bold);white-space:nowrap;
}
.act:hover:not([aria-expanded="true"]):not(.off):not(.armed){background:var(--hl)}
:is(.act,.login).off{opacity:.4;cursor:default} /* aria-disabled, still a Tab stop (app.js setOff) */
/* Tarkista -> "Käynnistä uudelleen" (2 s) -> "Kumoa" (1 s): the bar shows the time left */
.act.armed{position:relative;font-size:var(--fs-xs);line-height:1.15;white-space:normal;text-align:center;max-width:96px;overflow:hidden}
.act.armed .jp{display:none}
.act.armed::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--surface);opacity:.7;transform-origin:left;animation:drain var(--t) linear .3s forwards}
@keyframes drain{from{transform:scaleX(1)}to{transform:scaleX(0)}}
/* Status kanji: only in the one-row tablet status (the tablet block); the grid tracks have no room */
.act .jp{display:none}
:where(html:not([data-layout~=w360]),html[data-layout~=tiny]) .stat .l .jp{display:none}

/* Board */
.boardwrap{padding:8px 0;position:relative;display:flex;flex-direction:column;align-items:center}
.colnums,.rail{display:none}
.board-frame{position:relative;container-type:inline-size;width:var(--board-w)}
.board{
  position:relative;display:grid;grid-template-columns:repeat(9,minmax(0,1fr));grid-template-rows:repeat(9,minmax(0,1fr));
  width:100%;aspect-ratio:1/1;background:var(--surface);
  user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;touch-action:none;
}
.board::before{ /* wood grain of the printing block */
  content:"";position:absolute;inset:0;pointer-events:none;background:var(--grain);
  mask-size:100% 100%;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.004 .09' numOctaves='3' seed='11'/%3E%3CfeColorMatrix values='0 0 0 0 .45 0 0 0 0 .45 0 0 0 0 .44 0 0 0 1.1 -.5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}
.cell{
  position:relative;display:flex;align-items:center;justify-content:center;min-width:0;min-height:0;
  font-size:var(--fs-cell);font-weight:var(--fw-regular);line-height:1;
  color:var(--entry);font-feature-settings:"tnum";
}
.cell.given{color:var(--ink);font-size:var(--fs-given)}
.cell.peer{background:var(--hl)}
.cell.same{background:var(--hl-strong);font-weight:var(--fw-bold)}
.cell.clash:not(.sel){background:repeating-linear-gradient(135deg,var(--err-bg) 0 3px,transparent 3px 6px)}
.cell.wrong{color:var(--err)}
.cell.wrong::after{content:"";position:absolute;left:30%;right:30%;bottom:13%;height:2px;background:var(--err)}
.cell.sel{background:var(--sel-bg);color:var(--sel-fg)}
.cell.stamp{animation:cellstamp .16s cubic-bezier(.2,.9,.3,1)}
@keyframes cellstamp{from{transform:scale(.94)}to{transform:scale(1)}}
.cell.sel.wrong{color:var(--err-on-sel)}
.cell.sel.wrong::after{background:var(--err-on-sel)}
/* Focus inside a cell or a toast key (the ring would cover the neighbours); on an inverse
   surface (selected cell, pressed or previewed key) the ring is --sel-fg */
:is(.cell,.nt-k):focus-visible{outline-offset:-5px}
:is(.cell.sel,.nt-k.tool[aria-pressed="true"],.nt-k.hot):focus-visible{outline-color:var(--sel-fg)}
/* pointer-events:none: the touch target is always the cell button. render() rewrites the
   notes, and a touch whose target was detached never reached the board's touchend guard,
   so the synthetic click hit the toast under the finger and entered a candidate. */
.notes{
  pointer-events:none;
  position:absolute;inset:7%;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);
  font-family:var(--f-mono);font-size:var(--fs-note);color:var(--ink-2);
}
.notes i{font-style:normal;display:flex;align-items:center;justify-content:center}
.cell.sel .notes{color:var(--sel-fg)}
.notes i.on-same{font-weight:var(--fw-medium);color:var(--ink);text-decoration:underline}
/* Merkintätapa (choices.js: <html data-notes>; render(): data-n = how many, data-k = rank): one
   block per style, the same nine places of the bitmask. Ruudukko (grid) is the rules above. */
:where(html[data-notes=adaptive]) .notes:is([data-n="1"],[data-n="2"],[data-n="3"]){
  display:flex;justify-content:center;align-items:flex-start;font-size:var(--fs-note-pair);line-height:1;
  inset:var(--note-in) var(--note-in) auto; /* the top centre, clear of the thick box rules */
  & i:empty{display:none}
  &[data-n="2"] i[data-k="2"]::before{content:"/"}
}
:where(html[data-notes=corners]) .notes{
  inset:var(--note-in); /* the corners stay clear of the thick box rules */
  & i:empty{display:none}
  & [data-k="1"]{grid-area:1 / 1}
  & [data-k="2"]{grid-area:1 / 3}
  & [data-k="3"]{grid-area:3 / 1}
  & [data-k="4"]{grid-area:3 / 3}
  & [data-k="5"]{grid-area:1 / 2}
  & [data-k="6"]{grid-area:3 / 2}
  & [data-k="7"]{grid-area:2 / 1}
  & [data-k="8"]{grid-area:2 / 3}
  & [data-k="9"]{grid-area:2 / 2}
}
:where(html[data-notes=dots]){
  .notes i{position:relative;color:transparent;text-decoration:none}
  .notes i[data-k]::after{content:"";position:absolute;left:50%;top:50%;width:4px;height:4px;margin:-2px 0 0 -2px;border-radius:50%;background:var(--ink-2)}
  .notes i.on-same::after{background:var(--ink);transform:scale(1.5)}
  .cell.sel .notes i::after{background:var(--sel-fg)}
}
/* Kynä + Pyyhi: the sub-mode "Pyyhi merkintöjä" previews every candidate struck through */
.board.noterase .notes i{text-decoration:line-through;text-decoration-thickness:1.5px}
.grid-lines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;z-index:1}
.grid-lines .thin{stroke:var(--rule)}

/* Transient UI (slip, numerotoast): one fade, timed by transient() in the script */
.fades{transition:opacity var(--fade)}
.fades.fading{opacity:0}

/* The held new-day note (app.js dayNote()): below the board, or in the side column under the
   status row (landscape); never over or above the board. The date line marks the old day. */
.daynote{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;border-top:1px solid var(--hair);font-size:var(--fs-m)}
.daynote[hidden],.past[hidden]{display:none}
.daynote p{margin:0}
.daynote button{min-height:var(--tap);padding:0 16px;font-weight:var(--fw-bold)}
.past{font-size:var(--fs-2xs);font-weight:var(--fw-bold);color:var(--ink-2)}

/* Notice slip over the board */
.slip{
  position:absolute;left:50%;bottom:9%;transform:translateX(-50%);z-index:4;
  width:max-content;max-width:88%;padding:9px 14px;background:var(--surface);
  font-size:var(--fs-m);line-height:1.35;text-align:center;
}
.slip[hidden]{display:none}

/* Win: the hanko (v5) */
.win{position:absolute;inset:0;z-index:5;display:none;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  background:var(--veil)}
.win.on{display:flex}
.hanko{width:56%;max-width:300px;transform:rotate(-7deg)}
.win.on .hanko{animation:stamp .42s cubic-bezier(.2,1.4,.4,1) both}
@keyframes stamp{0%{transform:rotate(-14deg) scale(1.9);opacity:0}60%{opacity:1}100%{transform:rotate(-7deg) scale(1);opacity:1}}
.hanko text{fill:var(--ink);text-anchor:middle}
.hanko .big{font-size:var(--fs-hanko)}
.hanko .cap{font:var(--fw-bold) var(--fs-m) var(--f-jp);letter-spacing:4px}
.hanko .date{font:var(--fw-bold) var(--fs-xs) var(--f-jp);letter-spacing:2px}
.win-msg{margin:0;font-size:var(--fs-base);background:var(--surface);padding:4px 12px}
.win-msg b{font-family:var(--f-mono);font-weight:var(--fw-medium)}
.again{min-height:48px;padding:0 22px;font-weight:var(--fw-bold)}
/* The season's celebration (app.js SEASONS, celebrate()): particles from --x0/--y0 to --x1/--y1,
   transform and opacity only; .win.fx holds the hanko back until they have drifted (TIME.FX). */
.fx{position:absolute;inset:0;overflow:hidden;pointer-events:none}
.fx i{position:absolute;left:0;top:0;width:10px;height:10px;background:var(--fx-c);opacity:0;animation:fx var(--d) ease-in var(--w) both}
.fx-petal i{width:11px;height:8px;border-radius:100% 0}
.fx-spark i{width:4px;height:4px;border-radius:50%;animation-timing-function:cubic-bezier(.1,.8,.3,1)}
.fx-leaf i{width:12px;height:12px;clip-path:polygon(50% 0,62% 30%,95% 25%,72% 52%,90% 85%,55% 70%,50% 100%,45% 70%,10% 85%,28% 52%,5% 25%,38% 30%)}
.fx-flake i{width:6px;height:6px;border-radius:50%}
.fx.still i{animation:none;opacity:1;transform:translate(var(--x0),var(--y0)) rotate(var(--r))}
@keyframes fx{0%{transform:translate(var(--x0),var(--y0)) rotate(0);opacity:0}12%,75%{opacity:1}100%{transform:translate(var(--x1),var(--y1)) rotate(var(--r));opacity:0}}
.win.fx .hanko{animation:none;opacity:0}

/* Keys of the numerotoast (.nt-k): the toast sets the sizes */
.k{position:relative;display:flex;align-items:center;justify-content:center}
.k .d{font-size:var(--fs-key);font-weight:var(--fw-light);line-height:1;font-feature-settings:"tnum"}
.k .kj{position:absolute;top:4px;left:5px;font-size:var(--fs-kj);line-height:1;color:var(--ink-3)}
.k.tool .d{font-size:var(--fs-s);font-weight:var(--fw-bold)}
.k.rm .d{text-decoration:line-through;text-decoration-thickness:2px}
.pen .k.num .d{font-family:var(--f-mono);font-size:var(--fs-2xl);font-weight:var(--fw-regular);transform:translate(var(--k-nx),var(--k-ny))}

/* Numerotoast: 3×3 gesture grid for every pointer and the keyboard (keypad order) + action row */
.ntoast{
  position:fixed;z-index:40;left:0;top:0;
  display:grid;grid-template-columns:repeat(3,var(--nt));grid-template-rows:repeat(3,var(--nt)) var(--key-h);
  background:var(--surface);box-shadow:0 8px 28px var(--shadow);
  touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
  --fs-key:var(--fs-6xl);--fs-kj:var(--fs-3xs);--k-nx:-9px;--k-ny:-9px;
}
.ntoast[hidden]{display:none}
.ntoast.up{grid-template-rows:var(--key-h) repeat(3,var(--nt))}
.ntoast.up .nt-k.tool{order:-1}
/* Switch labels (numerotoast keys, touch status row): the tap feel of a button */
label:is(.nt-k,.act){cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation;-webkit-user-select:none;user-select:none}
.nt-k.start{background:var(--hl)}
/* A candidate of the selected cell (keyState() pressed: aria-pressed, "merkitty"), every mode */
.nt-k.has{background:var(--hl-strong)}
.nt-k.has::after{content:"";position:absolute;right:6px;top:6px;width:5px;height:5px;border-radius:50%;background:var(--ink)}
/* Mouse: hover marks the key under the pointer (zero specificity: pressed, previewed and off win) */
:where(html[data-layout~=mouse] .nt-k:not(.off):hover){background:var(--hl)}

/* Settings: in memory only */
.settings{
  position:fixed;z-index:30;left:0;right:0;margin:0 auto;
  bottom:calc(var(--anchor-total) + 8px);
  width:calc(100% - 2 * var(--gutter));max-width:420px;
  max-height:calc(100svh - 2 * var(--edge));overflow-y:auto; /* short screens: scrolls instead of running off */
  background:var(--surface);padding:16px 16px 14px;
}
.settings[hidden]{display:none}
.settings.pop{right:auto;bottom:auto;margin:0;width:380px;max-width:calc(100vw - 2 * var(--edge))} /* tablet + desktop: anchored to the button by placeSettings() */
.settings h2{margin:0 0 4px;font-size:var(--fs-l);font-weight:var(--fw-bold);display:flex;gap:10px;align-items:baseline}
.settings .lead{margin:0 0 8px;font-size:var(--fs-s);color:var(--ink-2)}
.opt,.opt-act{display:grid;grid-template-columns:1fr auto;gap:12px;align-items:center;width:100%;min-height:var(--nt);padding:8px 0;text-align:left;border-top:1px solid var(--hair)}
.opt-act strong{text-decoration:underline;text-underline-offset:4px} /* an action (Tulosta), not a switch */
.opt-act.off{opacity:.4;cursor:default}
:is(.opt,.opt-act,.choice) strong{display:block;font-size:var(--fs-m);font-weight:var(--fw-bold)}
:is(.opt,.opt-act,.choice) small{display:block;font-size:var(--fs-xs);color:var(--ink-3);line-height:1.35}
.sw{width:var(--tap);height:26px;border:2px solid var(--ink);position:relative;flex:none}
.sw::after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;background:var(--ink);transition:transform .12s}
.opt[aria-checked="true"] .sw{background:var(--ink)}
.opt[aria-checked="true"] .sw::after{background:var(--surface);transform:translateX(18px)}
/* Choices (choices.js: Merkintätapa, Teema): printed segments in one frame like the switches */
.choice{padding:8px 0 12px;border-top:1px solid var(--hair)}
.seg{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);margin-top:8px;border:2px solid var(--ink)}
.seg button{min-height:var(--tap);font-size:var(--fs-s);font-weight:var(--fw-bold)}
.seg button + button{border-left:2px solid var(--ink)}
.set-actions{display:flex;gap:8px;justify-content:space-between;border-top:1px solid var(--hair);padding-top:12px}
.set-actions button{min-height:var(--tap);padding:0 16px;font-weight:var(--fw-bold);font-size:var(--fs-m)}
.set-actions .restart{text-decoration:underline;text-underline-offset:4px;padding-left:0}

/* Inverse print (the hanko look): every pressed, active or primary surface, its kanji at .75 */
.pick[aria-pressed="true"],.act[aria-expanded="true"],.act.armed,.again,.set-actions .done,.daynote button,
.nt-k.tool[aria-pressed="true"],.nt-k.hot,.seg [aria-checked="true"]{
  background:var(--ink);color:var(--surface);
  & :is(.kj,.jp){color:inherit;opacity:.75}
}
/* Off keys (after the inverse rule: an off key never prints inverse) */
.nt-k.off{
  color:var(--muted);cursor:default;
  & .kj{color:var(--muted)}
}

/* Turn overlay (touch in portrait) */
.turn{
  display:none;position:fixed;inset:0;z-index:100;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  padding:24px max(24px,env(safe-area-inset-right)) 24px max(24px,env(safe-area-inset-left));
  background:var(--paper);text-align:center;
}
.turn-ico{width:132px;height:132px;margin-bottom:10px}
.turn-ico .f{fill:var(--ink)}
.turn-phone{transform-origin:60px 60px;animation:turn 2.8s cubic-bezier(.6,0,.3,1) infinite}
@keyframes turn{0%,18%{transform:rotate(0)}52%,82%{transform:rotate(90deg)}100%{transform:rotate(0)}}
.turn-t{margin:0;font-size:var(--fs-3xl);font-weight:var(--fw-bold)}
.turn-s{margin:0;max-width:300px;font-size:var(--fs-s);color:var(--ink-2)}

/* Print sheet (app.js buildSheet(), hidden in the markup): only the "Print" layout block below shows it */
@page{size:auto;margin:10mm}

/* Footer */
.foot{
  max-width:var(--maxw);margin:0 auto;padding:16px var(--gutter) 8px;
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px 16px;font-size:var(--fs-xs);color:var(--ink-3);
}
.foot p{margin:0}

/* ===== Layout modes =====
   The words on <html data-layout> come from LAYOUT in the head script, the only breakpoints.
   One block per mode; :where() keeps each inner rule's own specificity, so the blocks cascade
   by order exactly like media blocks would. */

/* Reduced motion */
:where(html[data-layout~=reduce]){
  .win.on .hanko,.cell.stamp,.act.armed::after,.turn-phone{animation:none}
  .sw::after,.fades{transition:none}
}

/* Tablet and landscape */
:where(html[data-layout~=big]){
  & body{padding-bottom:0}
  .levels{margin-top:14px}
  .colnums{
    display:grid;grid-template-columns:repeat(9,1fr);width:var(--board-w);
    font-size:var(--fs-3xs);line-height:15px;color:var(--ink-3);text-align:center;padding-bottom:4px;
  }
}

/* Tablet portrait: no anchor and no top banner, the wide ad sits below the game. The board
   is sized by the small viewport height (svh = Safari with its address and tab bars showing). */
:where(html[data-layout~=tablet]){
  --chrome:340px;--bmin:360px;--fs-day:88px;
  .top{height:56px}
  .layout{max-width:720px}
  .status{grid-template-columns:minmax(0,1fr);grid-auto-flow:column;grid-auto-columns:auto}
  .stats{grid-column:auto}
  .act .jp{display:inline}
  .intro{padding:18px 0 12px}
  .boardwrap{padding:10px 0 12px}
}
:where(html[data-layout~=w768]) .pick{min-height:48px}

/* Landscape: the board is the core element, everything else is built around it. The board
   is sized first (by the height), the rest goes beside it: intro, status and the ad (in the
   number pad's old place, every device) in a column on the left, the board on the right. The
   ad fills the column below the status row and sits centred in it on both axes; the extra
   bottom padding is the board frame's, so its centre line is the midpoint of status bottom ->
   board bottom. */
:where(html[data-layout~=land]){
  --chrome:147px;--bmin:400px;--board-cap:640px;--maxw:1280px;--col-l:296px;
  --fs-day:120px;--fs-pick:var(--fs-4xl);
  .top{padding:0 var(--gutter-l);height:64px}
  .layout{
    padding:0 var(--gutter-l);column-gap:40px;
    grid-template-columns:var(--col-l) minmax(0,1fr);
    grid-template-areas:"intro board" "status board" "note board" "ad board";
    grid-template-rows:auto auto auto 1fr;align-items:start;
  }
  .intro{grid-area:intro;padding:24px 0 12px}
  .dateline{grid-template-columns:1fr;row-gap:12px}
  .day{line-height:.76}
  .status{grid-area:status;padding:6px 0 12px}
  .daynote{grid-area:note}
  .act{padding:0 4px} /* four buttons in the column: Asetukset (57 px) fits a 68 px button */
  .ad-col{grid-area:ad;align-self:stretch;align-items:center;padding:var(--ad-air) 0 calc(var(--ad-air) + var(--wrap-b))}
  .boardwrap{grid-area:board;padding:var(--wrap-t) 0 var(--wrap-b) var(--rail-space)}
  .rail{
    display:flex;position:absolute;left:0;top:var(--wrap-t);bottom:var(--wrap-b);
    writing-mode:vertical-rl;text-orientation:mixed;
    font-size:var(--fs-2xs);letter-spacing:.3em;color:var(--ink-3);gap:24px;padding-right:8px;width:24px;
  }
  .rail .strong{color:var(--ink);font-weight:var(--fw-medium)}
  .pick{gap:6px;padding:4px 2px}
  .foot{padding:20px var(--gutter-l);margin-top:24px}
}
/* Short landscape (iPad in Safari, 1280×720 laptops): the date turns into one row with a
   smaller thin numeral, and the frames tighten, so the board keeps the height. */
:where(html[data-layout~=short]){
  --chrome:105px;--wrap-t:18px;--wrap-b:16px;--fs-day:72px;
  .top{height:52px}
  .intro{padding:14px 0 10px}
  .dateline{grid-template-columns:auto 1fr;row-gap:0}
  .day{line-height:.78}
  .levels{margin-top:12px}
  .status{padding:4px 0 8px;row-gap:4px}
}
/* Wide landscape: a third column for the side ad, as wide as the ad it shows */
:where(html[data-layout~=land][data-layout~=w1280]){
  .layout{grid-template-columns:var(--col-l) minmax(0,1fr) auto}
  .ad-side{grid-column:3;grid-row:1 / -1;padding-top:32px;position:sticky;top:16px}
}
:where(html[data-layout~=land][data-layout~=w1440]){--maxw:1440px}
/* Landscape only on touch: portrait shows the turn overlay and pauses the game */
:where(html[data-layout~=turn]){
  .turn{display:flex}
  & body{overflow:hidden}
}
/* Tiny landscape (phones, small windows): the header moves into the top of the side column
   so it eats no height. The board takes the full height minus its frame padding, limited by
   the width the side column needs (--col-min: its ad, safe areas included). Touch landscape
   under 640 px (568×320) has no room for the 320 px ad beside a full-height board: the
   column drops the ad and needs only its controls, so the board keeps the full height. */
:where(html[data-layout~=tiny]){
  --anchor-h:0px;--padl:max(12px,env(safe-area-inset-left));--padr:max(12px,env(safe-area-inset-right));
  --wrap-t:8px;--wrap-b:8px;--rail-space:0px;--ad-air:6px;--col-min:var(--ad-ph-w);
  --fs-day:40px;--fs-pick:var(--fs-3xl);
  --board-w:min(calc(100svh - var(--wrap-t) - var(--wrap-b) - env(safe-area-inset-bottom)),calc(100vw - var(--col-min) - var(--gutter) - var(--padl) - var(--padr)));
  & body{
    display:grid;grid-template-columns:minmax(var(--col-min),1fr) auto;grid-template-rows:auto auto auto auto 1fr auto auto;
    column-gap:var(--gutter);align-items:start;
    padding:0 var(--padr) env(safe-area-inset-bottom) var(--padl);
  }
  .layout{display:contents}
  .top{grid-column:1;grid-row:1;height:36px;padding:0}
  .intro{grid-column:1;grid-row:2;padding:6px 0 8px}
  .dateline{column-gap:10px;align-items:center}
  .day{line-height:.8}
  .datemeta{gap:0;line-height:1.2}
  .weekday{font-size:var(--fs-xs)}
  .fulldate,.issue{font-size:var(--fs-2xs)}
  .levels{margin-top:6px}
  .levels-head{margin-bottom:3px}
  .levels-head h2{font-size:var(--fs-2xs)}
  .pick{min-height:40px}
  .status{grid-column:1;grid-row:3;padding:2px 0 4px}
  .stat{min-height:36px}
  .stat .v{font-size:var(--fs-l)}
  .act{min-height:40px}
  .daynote{grid-column:1;grid-row:4}
  .ad-col{grid-area:5 / 1}
  .boardwrap{grid-column:2;grid-row:1 / span 5}
  .colnums,.rail{display:none}
  .ad-wide{grid-column:1 / -1;grid-row:6}
  .foot{grid-column:1 / -1;grid-row:7;max-width:none;width:100%}
}
/* Touch landscape under 640 px: no ad in the column (see the tiny block), only its controls */
:where(html[data-layout~=tiny]:not([data-layout~=w640])){
  --col-min:200px;--fs-pick:var(--fs-xl);
  .top{gap:8px}
  .act{grid-column:span 2}
  .pick{gap:4px;padding:4px 0}
}
/* Print (LAYOUT "print": the print media query or beforeprint / afterprint): only the sheet, 2 × 2
   on the common area of A4 and Letter (210 × 279 mm, 10 mm margins: 190 × 259 mm). Three boards
   of --sh-board, the fourth quadrant: brand, date and the solutions small and upside down.
   Light colours whatever the theme (the token block), plain vector lines (no filter), black ink
   on white: the browser leaves backgrounds out, except the seal (print-color-adjust). */
:where(html[data-layout~=print]){
  & body{display:block;margin:0;padding:0;background:var(--surface);overflow:visible}
  & body > :not(.sheet){display:none}
  .sheet{
    display:grid;grid-template-columns:repeat(2,var(--sh-board));gap:var(--sh-gap);width:max-content;margin:0 auto;
    color:var(--ink);line-height:1.3;
  }
  :is(.sh-q,.sh-s){margin:0;break-inside:avoid}
  :is(.sh-q,.sh-s) figcaption{display:flex;gap:2mm;align-items:baseline;margin-bottom:2mm;font-size:var(--fs-l);font-weight:var(--fw-bold)}
  :is(.sh-q,.sh-s) figcaption b{font-family:var(--f-print);font-weight:var(--fw-heavy)}
  .sh-s figcaption{margin-bottom:1mm;font-size:var(--fs-3xs)}
  .sh-board{position:relative;aspect-ratio:1/1}
  .sh-board text{font-family:var(--f-print);font-weight:var(--fw-heavy);font-size:var(--fs-print);fill:var(--ink);text-anchor:middle;dominant-baseline:central}
  .sh-info{display:flex;flex-direction:column;gap:3mm;padding-top:2mm}
  .sh-mark{display:flex;gap:3mm;align-items:center;margin:0;font-size:var(--fs-2xl)}
  .sh-mark .seal{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .sh-date{margin:0;font-size:var(--fs-l)}
  .sh-sol{margin-top:auto;transform:rotate(180deg)}
  .sh-h{margin:0 0 2mm;font-size:var(--fs-xs);font-weight:var(--fw-bold)}
  .sh-sols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4mm}
}
