/* Games by Miki — riso print system.
   Everything is "printed": a key ink (Federal Blue) for type and rules, one signature ink per game (--brand),
   on a grainy paper stock. Ink surfaces carry speckle (imperfect coverage) and a registration offset
   (--reg) that snaps into register when pressed. Dark mode is the same job printed on blue stock. */
:root {
  /* inks */
  --navy: #141e45;
  --pink: #ff48b0;    --pink-text: #c9157a;   --on-pink: var(--navy);
  --orange: #ff6c2f;  --orange-text: #b8430f; --on-orange: var(--navy);
  --teal: #00787e;    --teal-text: #00747a;   --on-teal: #f8f3e8;
  --sun: #ffb511;     --sun-text: #8a6200;    --on-sun: var(--navy);
  --red: #d2342a;     --red-text: #c4281d;    --on-red: #fff;
  --brand: var(--pink); --brand-text: var(--pink-text); --on-brand: var(--on-pink);

  /* stock */
  --paper: #f3ede1; --stock: #fbf8f1; --ink: #26366b; --muted: #5f6689;
  --hair: rgb(38 54 107 / .16); --line: rgb(38 54 107 / .3); --slot: rgb(38 54 107 / .06);
  --dot: rgb(38 54 107 / .22);
  --hl: #fbeac0;                      /* a sunflower tint: the line you're working on */
  --reg: var(--ink);                  /* the second drum, printed slightly out of register */
  --lift: 0 1px 1px rgb(28 42 92 / .06), 0 10px 22px -14px rgb(28 42 92 / .35);
  --float: 0 2px 4px rgb(28 42 92 / .06), 0 36px 70px -28px rgb(28 42 92 / .45);
  --blend: multiply;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .15 0 0 0 0 .21 0 0 0 0 .42 .9 0 0 0 -.42'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --speck: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .98 0 0 0 0 .96 0 0 0 0 .92 2.4 0 0 0 -1.25'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");

  /* Hebrew pages also load Frank Ruhl Libre and Heebo (build.js): Fraunces and Inter have no Hebrew, so those glyphs fall through to them */
  --display: 'Fraunces', 'Frank Ruhl Libre', Georgia, serif;
  --ease: cubic-bezier(.2, .8, .2, 1);
  --r: 14px;
  /* viewport units that hold under the text & tile size zoom (--scale, set by theme.js): use these, not vw/dvh */
  --vw: calc(1vw / var(--scale, 1)); --dvh: calc(1dvh / var(--scale, 1));

  font-family: 'Inter', 'Heebo', system-ui, -apple-system, sans-serif;
  font-feature-settings: 'cv11', 'ss01';
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
}
:root[data-theme="dark"] {
  --pink: #ff5cb8;   --pink-text: #ff7cc6;
  --orange: #ff8a4c; --orange-text: #ff9a63;
  --teal: #3fd0c2;   --teal-text: #5fdccf; --on-teal: var(--navy);
  --sun: #ffd23f;    --sun-text: #ffd23f;
  --red: #ff6b5e;    --red-text: #ff8378; --on-red: var(--navy);
  --paper: #1d2a55; --stock: #24336a; --ink: #f4ecdc; --muted: #a9b0cc;
  --hair: rgb(244 236 220 / .14); --line: rgb(244 236 220 / .28); --slot: rgb(244 236 220 / .06);
  --dot: rgb(244 236 220 / .2);
  --hl: #34467f;
  --reg: #0d1533;
  --lift: 0 1px 1px rgb(0 0 0 / .2), 0 10px 22px -12px rgb(0 0 0 / .5);
  --float: 0 2px 4px rgb(0 0 0 / .2), 0 36px 70px -24px rgb(0 0 0 / .65);
  --blend: screen;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .96 0 0 0 0 .93 0 0 0 0 .86 .6 0 0 0 -.3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --speck: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .11 0 0 0 0 .16 0 0 0 0 .33 2.4 0 0 0 -1.25'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");
  color-scheme: dark;
}

* { box-sizing: border-box; }
/* read by screen readers, not shown */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
[hidden] { display: none !important; }
html { zoom: var(--scale, 1); }
html, body { margin: 0; min-height: calc(100 * var(--dvh)); }
/* no double-tap zoom anywhere on mobile; pinch-zoom still works. On every element, not just html:
   touch-action only carries down to the nearest scroll container, and body (overflow-x: hidden) is one */
* { touch-action: manipulation; }
body { background: var(--grain), var(--paper); overflow-x: hidden; }
button { font: inherit; color: inherit; cursor: pointer; }
svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
::selection { background: var(--brand); color: var(--on-brand); }

.screen {
  max-width: 600px; margin: 0 auto; min-height: calc(100 * var(--dvh));
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center;
  /* every time a screen is shown (display: none -> flex restarts it): the brand drum lands out of register, then snaps in */
  animation: print .32s var(--ease) backwards;
}
.loading .screen { visibility: hidden; animation: none; } /* until the page's scripts have run (theme.js) */
@keyframes print { from { opacity: 0; filter: drop-shadow(-8px 5px 0 var(--brand)); } 50% { opacity: 1; } }
/* hub <-> game page loads: the browser's cross-fade between documents, where supported (theme.js skips it under data-calm) */
@view-transition { navigation: auto; }

/* ---------- type ---------- */
.wordmark, dialog h2, .title b, .pause-cover > b, .daily-btn b, .pack-name, .btn.daily b, .big-score, .subject b {
  font-family: var(--display); font-optical-sizing: auto; font-variation-settings: 'SOFT' 60, 'WONK' 0;
}
.kicker {
  font-size: 11.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}

/* ---------- home ---------- */
/* every game's home lays out the same: content starts below the corner icons, the logo sits at the bottom of a fixed slot,
   so the wordmark lands at the same height in every game */
#home {
  display: grid; grid-template-rows: 140px; align-content: start; justify-items: center; position: relative; max-width: 460px;
  padding-top: calc(max(12px, env(safe-area-inset-top)) + 60px);
}
#home #logo { align-self: end; }
.corner, .corner-start { position: absolute; top: max(12px, env(safe-area-inset-top)); inset-inline-end: 10px; display: flex; gap: 2px; }
.corner-start { inset-inline: 10px auto; color: inherit; }
.corner-start + .corner-start { inset-inline-start: 56px; } /* Settings, beside the back arrow (theme.js) */
.wordmark {
  font-size: clamp(36px, calc(12 * var(--vw)), 68px); font-weight: 600; letter-spacing: -0.035em; line-height: .95;
  margin: 14px 0 0; text-align: center;
  /* the brand drum, printed a hair out of register under the key ink */
  text-shadow: .035em .03em 0 color-mix(in srgb, var(--brand) 55%, transparent);
}
.wordmark span { color: var(--brand-text); text-shadow: none; }
.tagline { color: var(--muted); margin: 12px 0 26px; font-size: 16px; text-align: center; text-wrap: balance; }
.menu { width: 100%; display: flex; flex-direction: column; gap: 12px; }
.row { display: flex; gap: 12px; }
.row > * { flex: 1; }
/* footer links: Levels, How to play */
.links { display: flex; justify-content: center; gap: 4px; margin-top: 10px; }
.foot-link {
  border: 0; background: none; padding: 8px 12px; font-size: 14.5px; font-weight: 500; color: var(--muted);
  text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 4px;
}
.foot-link:hover { color: var(--ink); text-decoration-color: var(--brand); }
/* a link styled as one: centered in its 44px touch target like a button's label (min-height, below) */
a.foot-link { display: inline-flex; align-items: center; }

.btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; padding: 15px 20px; border: 0; border-radius: var(--r); text-align: start;
}
.btn b { font-size: 17px; font-weight: 650; }
.btn small { font-size: 13.5px; }
.btn.center { align-items: center; text-align: center; }
.btn.primary { --fill: var(--brand); --on-fill: var(--on-brand); }
.btn.primary, .btn.daily { background: var(--speck), var(--fill); color: var(--on-fill); box-shadow: 2px 3px 0 var(--reg); transition: transform .14s var(--ease), box-shadow .14s var(--ease); }
.btn.primary:active, .btn.daily:active { transform: translate(2px, 3px); box-shadow: 0 0 0 var(--reg); }
.btn.ghost { background: transparent; box-shadow: inset 0 0 0 1px var(--line); align-items: center; transition: box-shadow .15s, background-color .15s; }
.btn.ghost:hover { box-shadow: inset 0 0 0 1px var(--ink); }
.btn.ghost:active { background: var(--slot); }
.btn.ghost b { font-size: 15.5px; font-weight: 600; }
/* the one-daily games' hero */
.btn.daily { --fill: var(--brand); --on-fill: var(--on-brand); align-items: center; text-align: center; padding: 22px 20px; gap: 4px; }
.btn.daily b { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; }
.btn.daily.done { background: var(--grain), var(--stock); color: var(--ink); box-shadow: inset 0 0 0 1px var(--hair), var(--lift); }
.btn.daily.done small { color: var(--teal-text); opacity: 1; font-weight: 600; }

.icon {
  display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: 50%; border: 0; background: transparent; transition: background-color .15s;
}
.icon:hover { background: var(--slot); }
.fav-tip { inset: max(64px, env(safe-area-inset-top)) 16px auto; margin: 0 auto; max-width: 320px; padding: 12px 16px; border: 1px solid var(--hair); border-radius: 12px; background: var(--stock); color: var(--ink); box-shadow: var(--lift); font-size: 15px; text-align: center; }

/* ---------- game ---------- */
.bar { width: 100%; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--hair); }
.title { display: flex; flex-direction: column; align-items: center; }
.title b { font-size: 21px; font-weight: 600; letter-spacing: -0.01em; }
.title small { color: var(--muted); font-size: 12px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.bar-start { display: flex; gap: 2px; }
.bar-end { display: flex; justify-content: flex-end; align-items: center; gap: 4px; }
.bar-more { display: none; }
#bar-menu { inset: auto; inset-inline-end: 12px; margin: 0; padding: 6px; border: 1px solid var(--hair); border-radius: 14px; background: var(--grain), var(--stock); color: var(--ink); box-shadow: var(--lift); }
#bar-menu .icon { display: flex; gap: 12px; width: 100%; padding-inline: 10px 16px; border-radius: 10px; color: inherit; font: inherit; font-size: 16px; }
#bar-menu .icon::after { content: attr(data-label); }
#timer { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--muted); min-width: 3.5ch; text-align: end; }

.board-wrap { flex: 1; display: grid; place-items: center; width: 100%; padding: 12px 0; }

/* motion: things print in — the drums start out of register and snap together. No overshoot. */
@keyframes enter { from { opacity: 0; transform: translate(5px, 4px); } }
@keyframes pop { 0% { transform: scale(.92); } 100% { transform: none; } }
@keyframes shake { 20%, 60% { transform: translateX(-3px); } 40%, 80% { transform: translateX(3px); } }
@keyframes wave { 40% { transform: translateY(-6px); } }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }
/* a rubber stamp thumping down: big and crooked, a squash on impact, then it settles at --tilt */
@keyframes stamp {
  0% { opacity: 0; transform: scale(1.5) rotate(calc(var(--tilt, -6deg) - 8deg)); }
  60% { opacity: 1; transform: scale(.94) rotate(calc(var(--tilt, -6deg) + 1deg)); }
  100% { opacity: 1; transform: rotate(var(--tilt, -6deg)); }
}

/* ---------- small delights ---------- */
/* theme: the old icon sets below the horizon, the new one rises; the moon brings its stars */
.js-theme { overflow: hidden; }
.js-theme > svg { grid-area: 1 / 1; }
.js-theme .set { animation: sun-set .3s ease-in forwards; }
.js-theme .rise { animation: sun-rise .38s .08s var(--ease) backwards; }
@keyframes sun-set { to { opacity: 0; transform: translateY(60%) scale(.8); } }
@keyframes sun-rise { from { opacity: 0; transform: translateY(60%) scale(.8); } }
.js-theme .star { transform-box: fill-box; transform-origin: center; }
.js-theme .rise .star { animation: pop-in .26s calc(.34s + var(--i) * .09s) cubic-bezier(.3, 1.6, .5, 1) backwards; }
@keyframes pop-in { from { opacity: 0; transform: scale(0); } }
/* the new stock wipes over from the button (theme.js animates the clip): no cross-fade under it */
.paper-swap::view-transition-old(root), .paper-swap::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* letterpress: anything pressed sinks a hair and its shadow goes */
.icon, .btn.ghost, .chip, .lvl { transition-property: background-color, box-shadow, opacity, translate; transition-duration: .15s; }
:is(.icon, .btn.ghost, .chip, .lvl, .foot-link):active:not(:disabled) { translate: 0 1.5px; }
.lvl:active:not(:disabled) { box-shadow: inset 0 0 0 1px var(--hair); }

/* sound: the waves ripple out when it comes on, and are drawn back in when it's muted */
.js-sound .go .w { transform-box: fill-box; transform-origin: left center; }
.js-sound .go.on .w { animation: wave-out .3s calc(var(--i) * .08s) var(--ease) backwards; }
.js-sound .go.off .w { animation: wave-out .2s calc((1 - var(--i)) * .06s) ease-in reverse forwards; }
.js-sound .go.off .x { animation: pop-in .2s .14s var(--ease) backwards; }
@keyframes wave-out { from { opacity: 0; transform: translateX(-3px) scale(.4); } }

/* "Copied ✓": the tick draws itself */
svg.tick { width: 1.1em; height: 1.1em; vertical-align: -.2em; stroke-width: 2.6; }
.tick path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .32s .05s var(--ease) forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* a streak that just grew is stamped in; a milestone (7, 30, 100) runs a lap first */
.tick-n { display: inline-block; font-weight: 700; color: var(--brand-text); animation: stamp .32s .4s both cubic-bezier(.3, 0, .2, 1); }
.tick-n.lap { animation: stamp .32s .4s both cubic-bezier(.3, 0, .2, 1), lap .7s .75s var(--ease); }
@keyframes lap { to { rotate: 1turn; } }

/* idle for a while: the hint button hops, once */
.psst { animation: wave .45s var(--ease); }

.tip { color: var(--muted); text-align: center; min-height: 1.4em; margin: 4px 0 14px; max-width: 420px; font-size: 14.5px; line-height: 1.45; text-wrap: balance; }
.tip b { color: var(--ink); font-weight: 600; }

.tools { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 18px; }
/* quiet on purpose: giving up shouldn't compete with the real controls */
.give-up { border: 0; background: none; padding: 6px 10px; color: var(--muted); font-size: 13.5px; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.tools .give-up { flex-basis: 100%; }
.chip {
  display: flex; align-items: center; gap: 6px; padding-block: 8px; padding-inline: 12px 16px;
  border-radius: 999px; border: 0; background: transparent; box-shadow: inset 0 0 0 1px var(--line);
  font-weight: 600; font-size: 14px; transition: box-shadow .15s, background-color .15s, opacity .2s;
}
.chip svg { width: 17px; height: 17px; }
.chip:hover:not(:disabled) { box-shadow: inset 0 0 0 1px var(--ink); }
.chip:active:not(:disabled) { background: var(--slot); }
.chip:disabled { opacity: .38; cursor: default; }

/* ---------- dialogs ---------- */
dialog {
  border: 0; border-radius: 20px; padding: 30px 28px 26px; width: min(420px, calc(100 * var(--vw) - 32px));
  background: var(--grain), var(--stock); color: var(--ink); box-shadow: inset 0 0 0 1px var(--hair), var(--float); text-align: center;
}
dialog[open] { animation: rise .32s var(--ease); }
/* no backdrop-filter: on Android Chrome it turns the page black under the share sheet the first time it opens (Share result) */
dialog::backdrop { background: rgb(20 28 60 / .45); }
dialog h2 { margin: 0 0 16px; font-size: 32px; font-weight: 600; letter-spacing: -0.025em; line-height: 1.05; }
dialog form { margin-top: 20px; }

/* How to play in pages (core.js): all in one cell, so the dialog takes the tallest page's size; the others hide */
.help-pages { display: grid; align-items: start; }
.help-page { grid-area: 1 / 1; }
.help-page[inert] { visibility: hidden; }
.help-page:not([inert]) { animation: enter .25s var(--ease); }
.help-page > :first-child { margin-top: 0; }
.help-dots { display: flex; justify-content: center; gap: 8px; margin-top: 14px; }
.help-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); transition: background-color .2s, scale .2s; }
.help-dots i.on { background: var(--brand-text); scale: 1.3; }
.help-nav { display: flex; gap: 10px; margin-top: 14px; }
.help-nav .btn { flex: 1; }
.help-nav .btn.ghost { flex: .6; }
.help-nav .btn[hidden] { display: none; }

.rules { text-align: start; padding-inline-start: 22px; line-height: 1.5; margin: 16px 0 8px; font-size: 15px; }
.rules li { margin-bottom: 7px; }
.rules li::marker { font-family: var(--display); color: var(--brand-text); font-weight: 600; }
.rules b { font-weight: 600; }
.muted { color: var(--muted); }
.small { font-size: 13.5px; line-height: 1.5; }
kbd { font: inherit; font-size: 12px; font-weight: 600; padding: 1px 6px; border-radius: 5px; box-shadow: inset 0 0 0 1px var(--line), 0 1px 0 var(--line); }
@media (hover: none) and (pointer: coarse) { .kbd-hint { display: none; } } /* keyboard shortcuts: clutter on touch-only devices */

/* only the level numbers scroll: the grid absorbs any height the viewport can't spare */
#dlg-levels[open] { display: flex; flex-direction: column; overflow: hidden; max-height: calc(100 * var(--dvh) - 32px); }
.level-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; max-height: calc(55 * var(--dvh)); min-height: 0; overflow-y: auto; padding-block: 4px 8px; padding-inline: 4px 6px; }
.lvl {
  aspect-ratio: 1; border: 0; border-radius: 10px; background: var(--stock); box-shadow: inset 0 0 0 1px var(--hair), var(--lift);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
}
.lvl span { font-size: clamp(14px, calc(4.4 * var(--vw)), 18px); font-weight: 600; font-variant-numeric: tabular-nums; }
.lvl small { font-size: 9px; color: var(--brand-text); letter-spacing: 1px; min-height: 12px; }
.lvl.current { background: var(--speck), var(--brand); color: var(--on-brand); box-shadow: 2px 2px 0 var(--reg); }
.lvl.current small { color: inherit; }
.lvl:disabled { cursor: default; box-shadow: none; color: var(--muted); background: radial-gradient(circle, var(--dot) .9px, transparent 1.25px) 0 0 / 5px 5px; }
.lvl:disabled small { color: var(--muted); }

.stars { font-size: 40px; letter-spacing: 8px; color: var(--line); line-height: 1; margin-bottom: 10px; }
.stars span { --tilt: 0deg; display: inline-block; animation: stamp .3s calc(.35s + var(--i) * .16s) both cubic-bezier(.3, 0, .2, 1); }
/* sunflower stars keyed in navy, so they read on cream and on blue stock */
.stars .on { color: var(--sun); -webkit-text-stroke: 1.5px var(--navy); paint-order: stroke fill; text-shadow: 2px 2px 0 color-mix(in srgb, var(--brand) 70%, transparent); }
.stats { color: var(--muted); margin: -4px 0 22px; font-size: 16px; }
.stats b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.win-actions { display: flex; flex-direction: column; gap: 10px; }
#win-daily { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
#win-daily .stats { margin: 4px 0 0; font-size: 14px; font-variant-numeric: tabular-nums; }
.win-try { color: var(--ink); font-weight: 600; }
/* the win dialog's ×: closing it leaves the solved board on view, with #btn-result to bring the dialog back */
.dlg-x { position: absolute; top: 8px; inset-inline-end: 8px; margin: 0; }
/* done (solved or given up): the play controls go, the board stays */
#game.done :is(.tools > :not(#btn-result), .palette, .give-up, #btn-pause) { display: none; }
#btn-result { width: auto; padding: 14px 40px; }

#fx { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 10; }

/* reduce motion: the system's setting or the Settings switch (theme.js sets data-calm from either) */
:root[data-calm], :root[data-calm] *, :root[data-calm] *::before, :root[data-calm] *::after {
  animation-duration: .01ms !important; animation-delay: 0ms !important; animation-iteration-count: 1 !important; transition: none !important;
}

/* phone in landscape: board left, controls right */
@media (orientation: landscape) and (max-height: 540px) {
  #game {
    max-width: none; display: grid; column-gap: 24px; align-items: center;
    grid-template-columns: 1fr auto; grid-template-rows: auto 1fr auto auto auto 1fr;
  }
  .bar { grid-column: 1 / -1; margin-bottom: 0; }
  .board-wrap { grid-column: 1; grid-row: 2 / -1; height: 100%; padding: 4px 0; }
  .tip { grid-column: 2; grid-row: 3; max-width: 300px; margin: 0 0 10px; font-size: 14px; }
  .palette { grid-column: 2; grid-row: 4; max-width: 300px; }
  .tools { grid-column: 2; grid-row: 5; justify-self: center; margin-top: 12px; }
  #dlg-levels { padding: 12px; }
  #dlg-levels h2 { display: none; }
  #dlg-levels form, #dlg-levels .pager { margin-top: 6px; }
}

/* tablet (iPad and friends): the phone column grows into the screen, with bigger type and targets.
   Touch only: a big desktop window keeps the compact layout. Each game's style.css sizes its own board under the same query. */
@media (pointer: coarse) and (min-width: 700px) and (min-height: 700px) {
  #game { max-width: 960px; padding-inline: 32px; }
  .bar { margin-bottom: 14px; padding-bottom: 12px; }
  .title b { font-size: 25px; }
  .title small { font-size: 13px; }
  #timer { font-size: 18px; }
  .tip { max-width: 560px; font-size: 17px; }
  .tools { gap: 12px; }
  .chip { padding-block: 12px; padding-inline: 16px 20px; font-size: 16px; }
  .chip svg { width: 20px; height: 20px; }
  .give-up { padding: 10px 14px; font-size: 15px; }
}
/* tablet in landscape: the board games put the board left and the controls in a column on the right */
@media (pointer: coarse) and (orientation: landscape) and (min-height: 700px) {
  #game:has(.board-wrap) {
    max-width: 1280px; display: grid; column-gap: 48px; align-items: center;
    grid-template-columns: 1fr auto; grid-template-rows: auto 1fr auto auto auto 1fr;
  }
  #game:has(.board-wrap) .bar { grid-column: 1 / -1; }
  #game:has(.board-wrap) .board-wrap { grid-column: 1; grid-row: 2 / -1; height: 100%; margin: 0; }
  #game:has(.board-wrap) .tip { grid-column: 2; grid-row: 3; max-width: 400px; margin: 0 0 14px; }
  #game:has(.board-wrap) .palette { grid-column: 2; grid-row: 4; max-width: 400px; }
  #game:has(.board-wrap) .tools { grid-column: 2; grid-row: 5; justify-self: center; margin: 18px 0 0; }
}

@media (max-height: 760px) { #home { grid-template-rows: none; } #home #logo { display: none; } .wordmark { margin-top: 0; } .tagline { margin-bottom: 16px; } }

/* ---------- difficulty ---------- */
/* difficulty is marked typographically (pips), so colour stays the game's own */
.tier-E { --pips: '●○○'; } .tier-M { --pips: '●●○'; } .tier-H { --pips: '●●●'; }
:root { --tier: var(--brand); }

.block-head { display: flex; align-items: baseline; justify-content: space-between; margin: 8px 2px 0; padding-bottom: 6px; border-bottom: 1px solid var(--ink); }
.block-head h2 { font-size: 11.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; margin: 0; }
.block-head span { font-size: 13px; color: var(--muted); font-weight: 500; font-variant-numeric: tabular-nums; }

.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 4px; }
.daily-btn {
  --fill: var(--brand); --on-fill: var(--on-brand);
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 0; padding-block: 12px; padding-inline: 14px 12px; min-height: 104px;
  border: 0; border-radius: var(--r); text-align: start;
  background: var(--speck), var(--fill); color: var(--on-fill); box-shadow: 2px 3px 0 var(--reg);
  transition: transform .14s var(--ease), box-shadow .14s var(--ease);
  animation: enter .35s calc(var(--i, 0) * 60ms) both var(--ease);
}
.daily-btn::before { content: var(--pips); font-size: 9px; letter-spacing: 2px; opacity: .8; }
.daily-btn b { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin-top: auto; }
.daily-btn small { font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.daily-btn:active { transform: translate(2px, 3px); box-shadow: 0 0 0 var(--reg); }
.daily-btn.done { background: var(--grain), var(--stock); color: var(--ink); box-shadow: inset 0 0 0 1px var(--hair), var(--lift); }
.daily-btn.done::before { color: var(--brand-text); opacity: 1; }
.daily-btn.done small { color: var(--teal-text); opacity: 1; }

.packs { display: flex; flex-direction: column; }
.pack-btn {
  display: grid; grid-template-columns: 4.6em 1fr auto; align-items: center; gap: 16px;
  padding: 14px 4px; border: 0; border-bottom: 1px solid var(--hair); border-radius: 0; text-align: start;
  background: transparent; transition: background-color .15s, padding .2s var(--ease);
}
.pack-btn:hover { background: var(--slot); padding-inline: 10px; }
.pack-name { font-size: 19px; font-weight: 600; letter-spacing: -0.01em; }
.pack-name::after { content: var(--pips); display: block; font-family: 'Inter', 'Heebo', sans-serif; font-size: 8px; letter-spacing: 2px; color: var(--brand-text); margin-top: 2px; }
.pack-bar { height: 3px; background: var(--hair); overflow: hidden; }
.pack-bar i { display: block; height: 100%; min-width: 3px; background: var(--brand); }
.pack-count { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--muted); }
.pack-count:has(small) { text-align: end; min-width: 6.2em; }
.pack-count small { display: block; font-size: 11.5px; color: var(--brand-text); }

.tabs { display: flex; gap: 0; margin-bottom: 14px; border-bottom: 1px solid var(--hair); }
.tab { flex: 1; border: 0; background: transparent; padding: 10px 8px; font-weight: 600; color: var(--muted); box-shadow: inset 0 0 0 var(--brand); transition: box-shadow .2s var(--ease), color .15s; }
.tab:focus-visible { outline-offset: -2px; }
.tab[aria-selected="true"] { color: var(--ink); box-shadow: inset 0 -3px 0 var(--brand); }

.pager { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pager .icon:disabled { opacity: .3; cursor: default; }

/* paused: board and controls hidden (layout kept), cover shown */
.board-wrap { position: relative; }
#game.paused :is(.board, .palette, .tools, .tip, .tray) { visibility: hidden; }
/* Pause turns the board over like a card: it tips away to edge-on, then its back (.pause-cover: a blank sheet the board's size and
   shape, set by setPaused) comes round to face you. Resume turns it back the same way. Each half is .2s; visibility flips at the
   edge-on moment, so the hidden face never takes clicks and the board can't be read while paused. */
:is(.board-wrap, .board-wrap > .zoom) { perspective: 900px; }
#game .board { transition: rotate .22s var(--ease) .2s, visibility 0s .2s; }
#game.paused .board { rotate: x 90deg; transition: rotate .2s ease-in, visibility 0s .2s; }
#game :is(.palette, .tools, .tip, .tray) { transition: opacity .2s .2s, visibility 0s .2s; }
#game.paused :is(.palette, .tools, .tip, .tray) { opacity: 0; transition: opacity .2s, visibility 0s .2s; }
.pause-cover { visibility: hidden; rotate: x -90deg; transition: rotate .2s ease-in, visibility 0s .2s; }
/* under the perspective, the edge-on cover's near edge projects wider than the board area (~1.3x on a tall board), and phones
   widen the whole page to fit it: body's overflow-x: hidden doesn't stop that. Clip it at the screen. */
#game { overflow-x: clip; }
#game.paused .pause-cover { visibility: visible; rotate: none; transition: rotate .22s var(--ease) .2s, visibility 0s .2s; }
.pause-cover::before {
  content: ''; position: absolute; z-index: -1; width: min(var(--sheet-w, 100%), 100%); height: min(var(--sheet-h, 100%), 100%); border-radius: var(--sheet-r, 16px);
  background: var(--grain), var(--stock); box-shadow: inset 0 0 0 1px var(--hair), var(--lift);
}
.pause-cover {
  position: absolute; inset: 0; z-index: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
}
.pause-cover > b { font-size: 40px; font-weight: 500; font-style: italic; letter-spacing: -0.02em; }
.pause-cover .btn { width: auto; padding: 14px 40px; }

/* ---------- right-to-left ---------- */
/* Everything above uses logical sides (inline-start/end), so it mirrors on its own. Arrows that mean back/forward turn with the text. */
[dir="rtl"] :is(.corner-start, #btn-back, .pager .icon) svg { scale: -1 1; }
/* Key caps and math (a translation marks its math dir="ltr") keep their order, and < > don't mirror; math doesn't break across lines */
kbd { direction: ltr; unicode-bidi: isolate; }
span[dir="ltr"] { white-space: nowrap; }
/* Hebrew has no capitals and isn't tracked out: labels set in spaced caps go back to normal spacing. And no fake italics. */
:lang(he) :is(.kicker, .block-head h2, .title small, .p-head p, .issue, .end-label, .subject small, .big-score small), :lang(he) .card::before, :lang(he) .card::after { letter-spacing: normal; }
:lang(he) { font-synthesis-style: none; }

.new-head { margin: 6px 2px -4px; }
#new-row .btn { padding: 12px 8px; }
#new-row .btn b { font-size: 15px; }
#new-row .btn b::before { content: var(--pips); display: block; font-size: 8px; letter-spacing: 2px; color: var(--brand-text); margin-bottom: 3px; }
/* small text controls still get a full-size touch target */
.foot-link, .chip, .give-up { min-height: 44px; }
/* the pips are decoration (the difficulty is in the name): empty alt text keeps screen readers from reading "black circle…" */
@supports (content: "x" / "") {
  .daily-btn::before, .pack-name::after, #new-row .btn b::before { content: var(--pips) / ""; }
}

/* ---------- settings ---------- */
#dlg-settings { max-height: calc(100% - 32px); overflow-y: auto; }
.set-list { text-align: start; margin-top: -4px; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--hair); }
label.set-row { cursor: pointer; }
.set-row:last-child { border-bottom: 0; }
.set-row.col { flex-direction: column; align-items: stretch; gap: 10px; }
.set-row b { display: block; font-weight: 600; }
.set-row small { display: block; color: var(--muted); font-size: 13.5px; line-height: 1.4; margin-top: 2px; }
.set-row .row { gap: 10px; }
.set-row .btn { padding: 11px 16px; }
.set-row .give-up { align-self: center; }
/* a switch: a printed pill, its knob slid across and inked in the game's colour when on */
.switch {
  appearance: none; flex: none; position: relative; width: 46px; height: 28px; margin: 0; border-radius: 999px; cursor: pointer;
  background: var(--slot); box-shadow: inset 0 0 0 1.5px var(--line); transition: background-color .15s, box-shadow .15s;
}
.switch::before { content: ''; position: absolute; top: 4px; inset-inline-start: 4px; width: 20px; height: 20px; border-radius: 50%; background: var(--ink); transition: translate .18s var(--ease), background-color .15s; }
.switch:checked { background: var(--brand); box-shadow: inset 0 0 0 1.5px var(--ink); }
.switch:checked::before { translate: 18px; background: var(--on-brand); }
[dir="rtl"] .switch:checked::before { translate: -18px; }
.seg { display: flex; gap: 4px; padding: 4px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line); }
.seg label { flex: 1; position: relative; padding: 9px 6px; border-radius: 999px; text-align: center; font-weight: 600; font-size: 14px; cursor: pointer; transition: background-color .15s; }
.seg label:hover { background: var(--slot); }
.seg input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.seg label:has(:checked) { background: var(--speck), var(--brand); color: var(--on-brand); }
.seg label:has(:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }

/* high contrast: plain paper. No grain, speckle or misregistration (--reg's offset shadows go clear), darker greys and rules */
:root[data-contrast] {
  --grain: none; --speck: none; --reg: transparent;
  --muted: #3a4166; --hair: rgb(38 54 107 / .4); --line: rgb(38 54 107 / .7); --dot: rgb(38 54 107 / .5);
}
:root[data-contrast][data-theme="dark"] { --muted: #dde1ee; --hair: rgb(244 236 220 / .4); --line: rgb(244 236 220 / .7); --dot: rgb(244 236 220 / .5); }
:root[data-contrast] :is(.wordmark, .big-score, .stars .on) { text-shadow: none; }
:root[data-contrast] [filter] { filter: none; }

/* ---------- print ---------- */
/* #print is the paper version of the puzzle on screen, filled by printable() in core.js just before printing.
   One A4 sheet (plus one for the answer), black ink on white: no grain, no shadows, no motion. Game sheets style their own body in style.css. */
#print { display: none; }
/* phones rarely print and the bar has no room for a third icon there; the browser's own Print still works */
@media (max-width: 459px) { #btn-print, #game .bar-end > :is(.js-help, .js-sound) { display: none; } #game .bar-more { display: grid; } } /* no room: help and sound go in the ⋯ menu */
@media print {
  @page { size: A4; margin: 14mm; }
  :root, :root[data-theme="dark"] {
    --ink: #000; --muted: #444; --paper: #fff; --stock: #fff; --line: #000; --hair: #888;
    color-scheme: light;
  }
  html { --scale: 1 !important; } /* text & tile size is for the screen (theme.js sets it inline): paper keeps its own measures */
  html, body { min-height: 0; }
  body.printing { background: none; }
  body.printing > :not(#print) { display: none !important; }
  body.printing #print { display: flex; }
}
#print { flex-direction: column; align-items: center; gap: 6mm; color: #000; font-size: 11pt; line-height: 1.4; }
#print * { animation: none !important; transition: none !important; box-shadow: none; }
.p-head { width: 100%; display: flex; align-items: baseline; justify-content: space-between; border-bottom: 1.5pt solid #000; padding-bottom: 2mm; }
.p-head h1 { margin: 0; font: 600 26pt/1 var(--display); letter-spacing: -0.03em; }
.p-head p { margin: 0; font-size: 9pt; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
#print .rules { width: 100%; margin: 0; font-size: 10.5pt; }
#print .rules li { margin-bottom: 1mm; }
#print .rules li::marker { color: #000; }
/* the answer: its own page after the puzzle */
.p-answer { width: 100%; break-before: page; display: flex; flex-direction: column; align-items: center; gap: 6mm; }
/* a box to write in */
.p-box { flex: none; display: inline-block; width: 6mm; height: 6mm; border: 1pt solid #000; border-radius: 1mm; vertical-align: middle; }

/* ---------- print-shop ephemera ---------- */
/* The marks a real riso job carries: trim marks, registration targets, the slug, the inspector's stamp. Decoration only:
   high contrast (plain paper) drops them, reduce motion keeps them but still. */

/* every dialog is a trimmed sheet: crop marks just inside its corners (background layers, so no markup) */
dialog {
  --crop: linear-gradient(var(--line), var(--line));
  background:
    var(--crop) 5px 15px / 8px 1px no-repeat, var(--crop) 15px 5px / 1px 8px no-repeat,
    var(--crop) right 5px top 15px / 8px 1px no-repeat, var(--crop) right 15px top 5px / 1px 8px no-repeat,
    var(--crop) left 5px bottom 15px / 8px 1px no-repeat, var(--crop) left 15px bottom 5px / 1px 8px no-repeat,
    var(--crop) right 5px bottom 15px / 8px 1px no-repeat, var(--crop) right 15px bottom 5px / 1px 8px no-repeat,
    var(--grain), var(--stock);
}
:root[data-contrast] dialog, :is(#dlg-win, #dlg-end) { --crop: linear-gradient(transparent, transparent); } /* the win is a ticket: no crop marks */

/* the win: a ticket. A perforated line above its actions, and on close it comes off the pad (tilts away from its top corner and drops).
   An exit transition: display and overlay stay on (allow-discrete) until it's done; browsers without it just close. */
dialog .win-actions { position: relative; padding-top: 22px; }
dialog .win-actions::before {
  content: ''; position: absolute; top: 4px; inset-inline: -28px; height: 4px;
  background: radial-gradient(circle, var(--line) 1.5px, transparent 2px) center / 9px 4px repeat-x;
}
:is(#dlg-win, #dlg-end) {
  --tear: 7deg; transform-origin: 0 0;
  transition: translate .34s ease-in, rotate .34s ease-in, opacity .26s .08s ease-in, display .34s allow-discrete, overlay .34s allow-discrete;
}
[dir="rtl"] :is(#dlg-win, #dlg-end) { --tear: -7deg; transform-origin: 100% 0; }
:is(#dlg-win, #dlg-end):not([open]) { translate: 0 calc(12 * var(--dvh)); rotate: var(--tear); opacity: 0; }
:is(#dlg-win, #dlg-end)::backdrop { transition: opacity .34s, display .34s allow-discrete, overlay .34s allow-discrete; }
:is(#dlg-win, #dlg-end):not([open])::backdrop { opacity: 0; }

/* the inspector's stamp (stamp() in core.js), in the game's ink, overprinted, its coverage patchy like a real one.
   .seal: a daily's round edition seal; .tag: a level's small rectangle */
.stamp {
  --tilt: -11deg; position: absolute; top: 12px; inset-inline-start: 12px; z-index: 1; pointer-events: none;
  color: var(--brand-text); mix-blend-mode: var(--blend); opacity: .88; rotate: var(--tilt);
}
[dir="rtl"] .stamp { --tilt: 11deg; }
/* where the ink missed: the speckle punched out of it (on .ink, so the bleed ring around it isn't clipped by the mask) */
.stamp .ink { mask: var(--speck), linear-gradient(#000, #000); mask-composite: exclude; border-radius: inherit; }
:root[data-contrast] .stamp .ink { mask: none; }
.stamp.fresh { animation: thump .34s .7s both cubic-bezier(.3, 0, .2, 1); }
/* the stamp keyframe's motion, on scale and rotate so the resting tilt (rotate) holds */
@keyframes thump {
  0% { opacity: 0; scale: 1.5; rotate: calc(var(--tilt) - 8deg); }
  60% { opacity: .88; scale: .94; rotate: calc(var(--tilt) + 1deg); }
}
/* the ink squeezed out on impact: a ring that spreads and fades */
.stamp.fresh::before {
  content: ''; position: absolute; inset: 0; border: 2px solid currentColor; border-radius: inherit;
  animation: bleed .5s .9s ease-out both;
}
@keyframes bleed { from { opacity: .5; } to { opacity: 0; scale: 1.28; } }
.seal { width: 84px; height: 84px; border-radius: 50%; }
.seal .ink { height: 100%; }
.seal svg { display: block; width: 100%; height: 100%; fill: currentColor; stroke: none; overflow: visible; }
.seal circle { fill: none; stroke: currentColor; stroke-width: 2.4; }
.seal circle + circle { stroke-width: 1.1; }
.seal text { text-anchor: middle; }
.seal .ring { font: 700 8.2px 'Inter', 'Heebo', sans-serif; text-transform: uppercase; text-anchor: start; direction: ltr; } /* laid from the path's start in every language (RTL would anchor it off the far end) */
.seal .no { font: 600 15px var(--display); letter-spacing: -.02em; }
.seal .val { font: 700 10.5px 'Inter', 'Heebo', sans-serif; font-variant-numeric: tabular-nums; }
.tag { --tilt: -7deg; top: 16px; inset-inline-start: 14px; border-radius: 4px; }
.tag .ink {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 4px 9px 5px; border: 2px solid currentColor; box-shadow: inset 0 0 0 2px var(--stock), inset 0 0 0 3px currentColor;
}
[dir="rtl"] .tag { --tilt: 7deg; }
.tag small { font-size: 8.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; white-space: nowrap; }
.tag b { font: 600 15px/1 var(--display); font-variant-numeric: tabular-nums; white-space: nowrap; }
:lang(he) .tag small, :lang(he) .seal .ring { letter-spacing: normal; }
/* the timed games' result opens on its title, not stars: room above it for the stamp */
#dlg-end:has(> .stamp) { padding-top: 64px; }
:root[data-contrast] .stamp { mix-blend-mode: normal; opacity: 1; }

/* a daily just finished: the menu runs an ink roller over its button, once (rollIn() in core.js) */
.btn.daily.inked { position: relative; }
:is(.daily-btn, .btn.daily).inked { overflow: hidden; }
:is(.daily-btn, .btn.daily).inked::after {
  content: ''; position: absolute; inset-block: -2px; inset-inline-start: 0; width: 42%; border-radius: 8px;
  background: var(--speck), var(--brand); mix-blend-mode: var(--blend); opacity: .6; pointer-events: none;
  translate: -110% 0; animation: roll .9s .55s cubic-bezier(.45, 0, .3, 1) both;
}
@keyframes roll { to { translate: 260% 0; } }
@keyframes roll-rtl { to { translate: -260% 0; } }
[dir="rtl"] :is(.daily-btn, .btn.daily).inked::after { translate: 110% 0; animation-name: roll-rtl; }

/* the slug at the foot of a game's menu: house and issue */
.slug {
  justify-self: center; display: flex; align-items: center; gap: 8px; margin: 26px 0 0; text-align: center;
  font-size: 10.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
}
:lang(he) .slug { letter-spacing: normal; font-size: 12px; }

/* ---------- Impossible Mode (theme.js sets data-impossible; core.js swaps in the Impossible daily) ----------
   The same job printed on scorched stock, in one ink: the pink, now fire. Light or dark theme alike. */
:root[data-impossible] {
  --pink: #ff4fb2; --pink-text: #ff7cc6;
  --orange: #ff8a4c; --orange-text: #ff9a63; --teal: #3fd0c2; --teal-text: #5fdccf; --on-teal: var(--navy);
  --sun: #ffd23f; --sun-text: #ffd23f; --red: #ff6b5e; --red-text: #ff8378; --on-red: var(--navy);
  --brand: var(--pink); --brand-text: var(--pink-text); --on-brand: var(--navy);
  --paper: #140a10; --stock: #21121a; --ink: #f3e6dc; --muted: #b9a0aa;
  --hair: rgb(243 230 220 / .14); --line: rgb(243 230 220 / .3); --slot: rgb(243 230 220 / .06); --dot: rgb(243 230 220 / .2);
  --hl: #42182c; --reg: #000;
  --lift: 0 1px 1px rgb(0 0 0 / .3), 0 10px 22px -12px rgb(0 0 0 / .6);
  --float: 0 2px 4px rgb(0 0 0 / .3), 0 36px 70px -24px rgb(0 0 0 / .75), 0 0 60px -20px rgb(255 79 178 / .35);
  --blend: screen;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .9 0 0 0 0 .5 0 0 0 0 .6 .5 0 0 0 -.28'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --speck: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .08 0 0 0 0 .04 0 0 0 0 .06 2.4 0 0 0 -1.25'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");
  color-scheme: dark;
}
/* the regular tiers, disabled; the Impossible daily across the full row under them */
:is(.daily-btn, .btn.daily):disabled { pointer-events: none; opacity: .4; filter: grayscale(1); box-shadow: none; }
:root[data-impossible] .btn.daily:not(:disabled) { box-shadow: 2px 3px 0 var(--reg), 0 0 34px -8px var(--pink); }
:root[data-impossible] .btn.daily:disabled { padding-block: 12px; margin-bottom: 10px; }
:root[data-impossible] .trio { grid-template-columns: repeat(var(--n, 3), 1fr); }
.daily-btn:disabled { min-height: 58px; }
.daily-btn.tier-I { grid-column: 1 / -1; min-height: 116px; box-shadow: 2px 3px 0 var(--reg), 0 0 34px -8px var(--pink); }
.daily-btn.tier-I.done { box-shadow: inset 0 0 0 1px var(--pink), 0 0 34px -12px var(--pink); }
.tier-I { --pips: '⛧'; }
.daily-btn.tier-I::before { font-size: 16px; letter-spacing: 0; }
:root[data-impossible] :is(#btn-hint, #btn-levels, #new-row, #pack-btns, .block-head:has(+ #pack-btns), #btn-random, .block-head:has(+ #btn-random), #btn-unlimited, .block-head:has(+ #btn-unlimited), .print-hint, a[href$="print.html"]) { display: none !important; }
/* pentagrams for stars (starRow() in core.js) */
.stars .penta { width: .86em; height: .86em; stroke-width: 1.5; vertical-align: -.08em; }
.stars .on .penta { color: var(--pink); filter: drop-shadow(0 0 7px var(--pink)); }
/* "Impossible", stamped across the masthead or wordmark (theme.js) */
.imp-stamp {
  --tilt: -6deg; position: absolute; inset-inline-end: 0; top: calc(100% + 2px); rotate: var(--tilt); padding: .12em .5em .1em; pointer-events: none; white-space: nowrap;
  font: 800 clamp(17px, calc(2.6 * var(--vw)), 26px)/1.25 Inter, Heebo, sans-serif; letter-spacing: .2em; text-transform: uppercase; color: var(--pink);
  background: var(--paper); border: 3px solid currentColor; border-radius: 5px; text-shadow: 0 0 12px rgb(255 79 178 / .6);
  box-shadow: 0 0 18px -4px var(--pink); animation: thump .34s .3s both cubic-bezier(.3, 0, .2, 1);
}
:lang(he) .imp-stamp { letter-spacing: .04em; }
:root[data-impossible] .wordmark > span:last-child { position: relative; }
/* the hub: centred under the whole title, held by the masthead itself */
.masthead .imp-stamp { inset-inline: 0; top: auto; bottom: 2px; width: fit-content; margin-inline: auto; }
:root[data-impossible] .masthead { padding-bottom: 54px !important; }
:root[data-impossible] .wordmark { margin-bottom: 46px; }

/* the peel: a hit area in the bottom-right corner. Its square holds the curled-up flap (top-left half, the paper's back)
   and what the curl uncovers (bottom-right half): fire. --s is the curl's size; nothing shows at 0. */
.peel { --s: 0px; position: fixed; right: 0; bottom: 0; z-index: 60; width: 64px; height: 64px; padding: 0; border: 0; background: none; -webkit-tap-highlight-color: transparent; }
.peel > span { position: absolute; right: 0; bottom: 0; width: var(--s); height: var(--s); transition: width .38s var(--ease), height .38s var(--ease); }
.peel-under { clip-path: polygon(100% 0, 100% 100%, 0 100%); background: #0b0407; overflow: hidden; }
.peel.on .peel-under { background: var(--real-paper); }
.peel-under canvas { position: absolute; right: 0; bottom: 0; width: 150px; height: 150px; }
/* the fire's ink screens stay crisp dots, and miss the paper in spots like every other ink */
.peel-under canvas, .fire-band { image-rendering: pixelated; }
.peel-under canvas { mask: var(--speck), linear-gradient(#000, #000); mask-composite: exclude; }
.peel-under::after { /* the curl's shadow, cast just past the fold onto what it uncovers */
  content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, transparent 50%, rgb(0 0 0 / .35) 51%, rgb(0 0 0 / .12) 57%, transparent 68%);
}
/* the flap (an SVG drawn by theme.js, stretched to the square): the paper's back, its edges and tip curling. Matte, like paper:
   a soft, even fall-off toward the crease (no sheen), the stock's grain on it, a low shadow under it.
   Off: the Impossible side's scorched stock; on: the page's own. */
.peel-flap svg { display: block; width: 100%; height: 100%; overflow: visible; stroke: none; filter: drop-shadow(-1px -1px 1.5px rgb(0 0 0 / .22)) drop-shadow(-4px -4px 7px rgb(0 0 0 / .12)); }
.peel .s1 { stop-color: #23121b; } .peel .s2 { stop-color: #27151e; } .peel .s3 { stop-color: #1e0f17; } .peel .s4 { stop-color: #160a10; }
.peel.on .s1 { stop-color: color-mix(in srgb, var(--real-paper), #000 7%); } .peel.on .s2 { stop-color: color-mix(in srgb, var(--real-paper), #000 4%); }
.peel.on .s3 { stop-color: color-mix(in srgb, var(--real-paper), #000 11%); } .peel.on .s4 { stop-color: color-mix(in srgb, var(--real-paper), #000 20%); }
/* off: lit pink toward the fold by the fire under it, flickering */
.peel .lit { animation: firelight 1.9s ease-in-out infinite; }
.peel.on .lit { display: none; }
@keyframes firelight { 0%, 100% { opacity: .75; } 18% { opacity: 1; } 31% { opacity: .62; } 47% { opacity: .9; } 63% { opacity: .7; } 80% { opacity: .95; } }
:root[data-calm] .peel .lit { animation: none; }
.peel:is(:hover, :focus-visible, .tease) { --s: 74px; }
/* on: a small dog-ear that stays, peeling up to full size when hovered */
.peel.on { --s: 28px; width: 74px; height: 74px; }
.peel.on:is(:hover, :focus-visible) { --s: 74px; }
.peel.drop { --s: 0px !important; }
.peel.roll > span { animation: peel-in .8s .35s both cubic-bezier(.3, 1.3, .5, 1); }
@keyframes peel-in { from { width: 0; height: 0; } }
:root[data-calm] .peel > span { transition: none; animation: none; }
/* the fire along the foot of the menus: tall flames behind the page's content, lower ones in front of it */
.fire-band { position: fixed; left: 0; bottom: 0; z-index: -1; width: 100%; height: 150px; pointer-events: none; mask: linear-gradient(to top, #000 55%, transparent), var(--speck); mask-composite: subtract; }
.fire-band.front { z-index: 50; height: 80px; mask-image: linear-gradient(to top, #000 25%, transparent), var(--speck); }
:root[data-impossible] body { padding-bottom: 70px; }
body:has(#game:not([hidden])) :is(.peel, .fire-band) { display: none; }
@media print { .peel, .fire-band { display: none !important; } }

/* Tutorial: the coach line under the bar, and a pulsing ring on what to touch next. The clock and print have no place in it. */
.coach { width: 100%; padding: 10px 14px; margin-bottom: 4px; border: 1.5px solid var(--brand); border-radius: 14px; background: color-mix(in srgb, var(--brand) 10%, transparent); text-align: start; }
.coach.pop { animation: pop .25s; }
.coach small { display: block; height: 1.5em; line-height: 1.5; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--brand-text); }
.coach p { margin: 2px 0 0; line-height: 1.4; }
.coach-lines { display: grid; }
.coach-lines > p { grid-area: 1 / 1; }
.coach-lines > p:not(.now) { visibility: hidden; }
.tut :is(#timer, #btn-print, #btn-link, #btn-pause, .give-up, #btn-giveup) { visibility: hidden; }
.coach-at { outline: 3px solid var(--brand) !important; outline-offset: 2px !important; animation: coach-ring 1.2s ease-in-out infinite !important; } /* !important: over a game's own selection ring and entrance */
@keyframes coach-ring { 50% { outline-offset: 5px; outline-color: color-mix(in srgb, var(--brand) 40%, transparent); } }
.board .coach-at { outline-offset: -4px !important; animation-name: coach-ring-in !important; } /* inside: a board clips its edges */
@keyframes coach-ring-in { 50% { outline-offset: -8px; outline-color: color-mix(in srgb, var(--brand) 40%, transparent); } }
[data-calm] .coach-at { animation: none !important; }
