/* GENERATED by tools/look/build-game-assets.mjs from the approved mock-up of look C - do not edit; edit tools/look/mock/*.css or tools/look/game.css. */
@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 600; font-display: block; src: url(fonts/Fredoka-600-latin.woff2) format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Onest'; font-style: normal; font-weight: 600; font-display: block; src: url(fonts/Onest-600-latin.woff2) format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Onest'; font-style: normal; font-weight: 600; font-display: block; src: url(fonts/Onest-600-cyrillic.woff2) format('woff2'); unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face { font-family: 'Onest'; font-style: normal; font-weight: 700; font-display: block; src: url(fonts/Onest-700-latin.woff2) format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Onest'; font-style: normal; font-weight: 700; font-display: block; src: url(fonts/Onest-700-cyrillic.woff2) format('woff2'); unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
/* ---- tools/look/mock/base.css ---- */
/* 2048 look mock-up: the shared frame of the three variants (stage 2 of docs/plan/GAME_PLAN.md).
   The board and tiles are the owner's direction K of the look stand (decision D9): night paper with fibres, tiles with light,
   a turquoise shimmer under the cells that follows each move and fades. Layout: spec 02 UI-05, UI-24 (banner zones),
   UI-10 (own menu button), UI-11 (sizes). Moving light is a shifted layer (transform / opacity), never box-shadow or
   background-position (pack rule 17 web p. 11). */
:root {
  --banner-h: 60px;
  --g: 10px; --s: 80px; --tr: 10px; --cr: 8px;
  --ui-font: 'Onest', system-ui, sans-serif;
  --title-font: 'Fredoka', 'Onest', sans-serif;
  --digit-font: 'Fredoka', 'Onest', sans-serif; --digit-w: 600; --digit-ls: 0;
  --bg: #150d20; --ink: #f4ecff; --ink-2: #b9a6d9; --teal: #2ff3e0;
  --flow-base: .2; --flow-lit: .42;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink); -webkit-tap-highlight-color: transparent; }
body { font-family: var(--ui-font); font-weight: 600; overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none; }
button { font: inherit; color: inherit; border: 0; background: none; padding: 0; cursor: pointer; }
svg { display: block; }
[hidden] { display: none !important; }

.app { position: relative; height: 100%; display: flex; flex-direction: column; overflow: hidden; }
.zone { flex: 0 0 var(--banner-h); display: grid; place-items: center; position: relative; z-index: 1; }
.zone-cap { width: 320px; max-width: calc(100% - 32px); height: 50px; display: grid; place-items: center; border-radius: 8px;
  border: 1px dashed rgba(255, 255, 255, .10); font-size: 12px; color: rgba(255, 255, 255, .26); letter-spacing: .06em; }
.main { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; position: relative; z-index: 1; }
.side { display: contents; }
.bar { order: 1; flex: 0 0 60px; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; }
.hud { order: 2; display: flex; gap: 10px; padding: 2px 16px 0; }
.play { order: 4; flex: 1 1 auto; min-height: 0; container-type: size; display: grid; place-items: center; }
.actions { order: 5; flex: 0 0 84px; display: flex; gap: 12px; padding: 0 16px; align-items: center; }

.ibtn { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 14px; position: relative; }
.ibtn svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.ibtn-ghost { width: 48px; height: 48px; }
.cap-desk { display: none; }
.title { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.title-main { font-family: var(--title-font); font-weight: 600; font-size: 30px; letter-spacing: .02em; }
.title-sm { font-size: 22px; }
.title-mode { font-size: 12px; color: var(--ink-2); margin-top: 5px; letter-spacing: .1em; text-transform: uppercase; }
.hud > div { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 64px; border-radius: 16px; position: relative; }
.lbl { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }
.val { font-weight: 700; font-size: 25px; margin-top: 3px; font-variant-numeric: tabular-nums; }
.btn { flex: 1; height: 56px; display: flex; align-items: center; justify-content: center; gap: 9px; border-radius: 16px; font-size: 16px; position: relative; }
.btn svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }

/* ---- the board: direction K ---- */
.board { position: relative; width: min(100cqw - 32px, 100cqh - 10px, 560px); aspect-ratio: 1; border-radius: 16px; isolation: isolate;
  background: repeating-linear-gradient(0deg, rgba(255, 255, 255, .025) 0 2px, transparent 2px 5px), radial-gradient(120% 90% at 30% 20%, #3a2852, #221733);
  box-shadow: inset 0 0 0 1px rgba(200, 170, 255, .12), 0 18px 40px rgba(0, 0, 0, .45); }
.board::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: .06; will-change: opacity;
  background: radial-gradient(90% 70% at 50% 40%, rgba(120, 255, 240, .85), rgba(120, 255, 240, 0) 70%); animation: breathe 6s ease-in-out infinite; }
.flowclip { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.flow { position: absolute; inset: -25%; will-change: transform; }
.flow-in { position: absolute; inset: -40%; opacity: var(--flow-base); will-change: transform, opacity;
  background: conic-gradient(from 0deg at 50% 50%, rgba(47, 243, 224, 0), rgba(140, 110, 255, .45), rgba(47, 243, 224, .7), rgba(0, 229, 212, .55), rgba(120, 90, 255, .3), rgba(47, 243, 224, 0) 75%, rgba(47, 243, 224, 0));
  animation: drift 12s ease-in-out infinite alternate; transition: opacity 1700ms cubic-bezier(.3, .6, .3, 1); }
.flow.lit .flow-in { opacity: var(--flow-lit); transition: opacity 160ms ease-out; }
.flow.surge .flow-in { opacity: .7; transition: opacity 260ms ease-out; }
@keyframes drift { 0% { transform: translate(-9%, -6%) rotate(0deg); } 100% { transform: translate(9%, 7%) rotate(55deg); } }
@keyframes breathe { 0%, 100% { opacity: .06; } 50% { opacity: .2; } }

.cells, .tiles { position: absolute; inset: 0; }
.cell, .tile { position: absolute; left: var(--g); top: var(--g); width: var(--s); height: var(--s);
  transform: translate(calc(var(--c) * (var(--s) + var(--g))), calc(var(--r) * (var(--s) + var(--g)))); }
/* K exactly as on the stand (night-glow + flow-fade, board 248 px, tile 52 px): every length of the tile is that tile's
   proportion, so the 80 px tile of the phone is the stand's tile enlarged, not a flatter, squarer one */
.cell { z-index: 1; background: #231833; border-radius: calc(var(--s) * .154); box-shadow: inset 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(190, 160, 255, .06); }
.tile { z-index: 2; transition: transform 100ms ease-out; will-change: transform;
  --a: #8a63c9; --b: #6a43a8; --base: #3f2766; --glow: rgba(180, 120, 255, .45); --inner: rgba(230, 200, 255, .35); --halo: .31; --in: .27; }
.tile.top { z-index: 4; }
.tile.gone { z-index: 1; }
.tile-in { position: absolute; inset: 0; border-radius: calc(var(--s) * .19); display: grid; place-items: center;
  background: linear-gradient(180deg, var(--a), var(--b));
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .12), inset 0 0 calc(var(--s) * var(--in)) var(--inner), 0 calc(var(--s) * .058) 0 var(--base),
    calc(var(--s) * .02) calc(var(--s) * .096) 0 rgba(0, 0, 0, .28), 0 0 calc(var(--s) * var(--halo)) var(--glow); }
.num { font-family: var(--digit-font); font-weight: var(--digit-w); letter-spacing: var(--digit-ls); color: #fff; line-height: 1;
  font-size: calc(var(--s) * var(--ds, .5)); text-shadow: 0 calc(var(--s) * .03) 0 rgba(50, 15, 80, .42); white-space: nowrap; }
.tile[data-d="2"] { --ds: .45; } .tile[data-d="3"] { --ds: .38; } .tile[data-d="4"] { --ds: .30; } .tile[data-d="5"] { --ds: .25; }
/* value steps: colour AND material by tier (spec 02 UI-02). 2-8 and 16-64 are the stand's own colours; the stand never showed
   more than 8, so 128-512 continue its cool side - lilac to indigo with a stronger halo - and 1024+ is the turquoise of the
   shimmer: violet -> orchid -> indigo -> turquoise, no red */
.tile[data-v="4"] { --a: #9a6bd6; --b: #7448b8; }
.tile[data-v="8"] { --a: #b064d0; --b: #8a3fb0; --base: #552872; --glow: rgba(210, 110, 255, .55); --inner: rgba(255, 200, 255, .4); --halo: .38; --in: .31; }
.tile[data-v="16"], .tile[data-v="32"], .tile[data-v="64"] { --a: #d06ac0; --b: #a63f98; --base: #6e2a64; --glow: rgba(255, 110, 210, .6); --inner: rgba(255, 210, 245, .45); --halo: .46; --in: .35; }
.tile[data-v="32"] { --a: #c766c9; --b: #9c3ca3; --base: #66296c; }
.tile[data-v="64"] { --a: #d872b4; --b: #ad448e; --base: #722c5e; }
.tile[data-v="128"] { --a: #ab8af2; --b: #7a5ad6; --base: #43307a; --glow: rgba(170, 140, 255, .7); --inner: rgba(235, 225, 255, .55); --halo: .5; --in: .36; }
.tile[data-v="256"] { --a: #9a86f7; --b: #6550db; --base: #3a2d80; --glow: rgba(150, 135, 255, .72); --inner: rgba(230, 228, 255, .55); --halo: .52; --in: .36; }
.tile[data-v="512"] { --a: #8691fb; --b: #4f56dd; --base: #2f3184; --glow: rgba(130, 145, 255, .75); --inner: rgba(228, 232, 255, .6); --halo: .55; --in: .38; }
.tile[data-v="1024"] { --a: #45e9dc; --b: #14a3b2; --base: #0d5a66; --glow: rgba(47, 243, 224, .7); --inner: rgba(220, 255, 252, .55); --halo: .55; --in: .38; }
.tile[data-v="2048"] { --a: #74f7ec; --b: #19b6c6; --base: #0d5f6e; --glow: rgba(90, 255, 240, .85); --inner: rgba(235, 255, 253, .65); --halo: .62; --in: .42; }
.tile[data-v="1024"] .num, .tile[data-v="2048"] .num { text-shadow: 0 calc(var(--s) * .03) 0 rgba(6, 70, 80, .5); }

.tile.new .tile-in { animation: appear 120ms cubic-bezier(.2, .9, .3, 1.3) both; }
.tile.merged .tile-in { animation: mergePulse 150ms ease-out; }
.tile.gone .tile-in { opacity: 0; transition: opacity 80ms ease-out 30ms; }
.board.instant .tile { transition: none; }
.board.instant .tile .tile-in { animation: none; transition: none; }
@keyframes appear { from { transform: scale(.3); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes mergePulse { 0% { transform: scale(1); } 45% { transform: scale(1.14); } 100% { transform: scale(1); } }
@keyframes fadeIn { from { opacity: .35; } to { opacity: 1; } }

.ripple { position: absolute; border-radius: 50%; pointer-events: none; z-index: 1;
  background: radial-gradient(circle, rgba(120, 255, 240, .35), rgba(120, 255, 240, 0) 62%);
  animation: glimmerFade 1500ms cubic-bezier(.2, .6, .3, 1) both; will-change: transform, opacity; }
@keyframes glimmerFade { 0% { transform: scale(.8); opacity: 0; } 18% { opacity: .15; } 100% { transform: scale(2); opacity: 0; } }

.pointer { position: absolute; left: 50%; top: 50%; width: 72px; height: 72px; margin: -36px 0 0 -36px; z-index: 5; opacity: 0; pointer-events: none; }
.pointer svg { width: 100%; height: 100%; fill: none; stroke: #8ffcf1; stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round; transform: rotate(var(--rot, 0deg)); filter: drop-shadow(0 0 6px rgba(47, 243, 224, .9)); }

.fx { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; z-index: 8; }
.plus { position: absolute; z-index: 9; pointer-events: none; font-weight: 700; font-size: 22px; color: #bffcf5; text-shadow: 0 0 10px rgba(47, 243, 224, .8); }

/* ---- windows and screens (spec 02 UI-12: dim >= 0.90, panel >= 0.97) ---- */
.overlay { position: absolute; inset: 0; z-index: 10; display: grid; place-items: center; padding: 24px; background: rgba(12, 7, 20, .92); }
.overlay.opening { animation: ovIn 220ms ease-out both; }
.overlay.opening .win-panel { animation: panelIn 220ms cubic-bezier(.2, .9, .3, 1.15) both; }
@keyframes ovIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes panelIn { from { transform: translateY(14px) scale(.94); opacity: 0; } to { transform: none; opacity: 1; } }
.win-panel { position: relative; width: min(100%, 360px); border-radius: 22px; padding: 26px 20px 20px; text-align: center; }
.win-title { margin: 0 0 14px; font-family: var(--title-font); font-weight: 600; font-size: 24px; letter-spacing: .01em; }
.win-text { margin: 0 0 16px; font-size: 15px; line-height: 1.45; color: var(--ink-2); font-weight: 500; }
.win-x { position: absolute; right: 8px; top: 8px; }
.win-row { display: flex; gap: 10px; }
.win-score { display: flex; flex-direction: column; align-items: center; margin: 0 0 18px; }
.menu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mbtn { height: 54px; border-radius: 14px; font-size: 15px; padding: 0 8px; position: relative; }
.mbtn-wide { grid-column: 1 / -1; }
.medal { width: 112px; height: 112px; margin: -4px auto 14px; border-radius: 22px; display: grid; place-items: center; position: relative;
  background: linear-gradient(180deg, #74f7ec, #19b6c6);
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .18), inset 0 0 22px rgba(235, 255, 253, .65), 0 5px 0 #0d5f6e, 0 0 44px rgba(90, 255, 240, .75); }
.medal::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .45) 50%, transparent 65%);
  background-size: 250% 100%; animation: shine 2.4s ease-in-out infinite; }
.medal-num { font-family: var(--digit-font); font-weight: var(--digit-w); letter-spacing: var(--digit-ls); font-size: 25px; color: #fff; text-shadow: 0 2px 0 rgba(6, 70, 80, .5); }
@keyframes shine { 0% { background-position: 120% 0; } 60%, 100% { background-position: -20% 0; } }

.screen { position: absolute; left: 0; right: 0; top: var(--banner-h); bottom: var(--banner-h); z-index: 9; display: flex; flex-direction: column; }
.rounds { flex: 1; overflow: auto; padding: 4px 16px 16px; display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; align-content: start; }
.tier-h { grid-column: 1 / -1; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); margin: 10px 2px 0; }
.rb { aspect-ratio: 1; border-radius: 14px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; position: relative; font-weight: 700; font-size: 18px; }
.rb .stars { display: flex; gap: 1px; }
.rb .stars i { width: 9px; height: 9px; clip-path: polygon(50% 0, 63% 36%, 100% 38%, 70% 60%, 80% 100%, 50% 76%, 20% 100%, 30% 60%, 0 38%, 37% 36%); background: rgba(255, 255, 255, .18); }
.rb .stars i.on { background: #ffd66e; }
.rb.locked { opacity: .55; }
.rb.sel { animation: selPop 280ms cubic-bezier(.2, .9, .3, 1.3); }
.rb.sel::after { content: ""; position: absolute; inset: -4px; border-radius: 17px; border: 2px solid var(--teal); box-shadow: 0 0 14px rgba(47, 243, 224, .6);
  animation: ring 520ms ease-out both; }
@keyframes selPop { 0% { transform: scale(1); } 40% { transform: scale(.9); } 100% { transform: scale(1); } }
@keyframes ring { from { transform: scale(1.25); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* ---- less motion (spec 02 UI-06): no flights or particles, a change is a fade <= 120 ms ---- */
@media (prefers-reduced-motion: reduce) {
  .tile { transition: none; }
  .tile.new .tile-in, .tile.merged .tile-in { animation: fadeIn 120ms ease-out both; }
  .tile.gone .tile-in { transition: none; }
  .flow-in, .board::after, .medal::after { animation: none; }
  .flow-in { transition: none; }
  .overlay.opening { animation: fadeIn 120ms ease-out both; }
  .overlay.opening .win-panel { animation: none; }
  .rb.sel, .rb.sel::after { animation: none; }
}

/* ---- computer (width >= 900): own layout, the board up to 560 px, HUD and buttons in a side panel (UI-05, UI-11) ---- */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  :root { --banner-h: 100px; }
  .zone-bottom { display: none; }
  .zone-cap { width: 728px; height: 90px; font-size: 15px; }
  .main { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 40px; padding: 0 64px 36px; align-items: center; }
  .side { display: flex; flex-direction: column; gap: 18px; grid-column: 2; grid-row: 1; }
  .play { grid-column: 1; grid-row: 1; height: 100%; }
  .board { width: min(100cqw, 100cqh - 8px, 560px); }
  .bar { flex: none; padding: 0; }
  .btn-menu { width: auto; padding: 0 16px 0 12px; display: flex; gap: 8px; font-size: 16px; }
  .cap-desk { display: inline; }
  .title-main { font-size: 40px; }
  .title-mode { font-size: 15px; }
  .hud { padding: 0; }
  .hud > div { height: 84px; }
  .lbl { font-size: 15px; }
  .val { font-size: 32px; }
  .actions { flex: none; padding: 0; flex-direction: column; align-items: stretch; }
  .btn { flex: none; height: 58px; font-size: 17px; }
  .screen { bottom: 0; }
}
.screen .bar { order: 0; flex: 0 0 60px; }

/* ---- tools/look/mock/screens.css ---- */
/* ---- every screen and window of spec 02 (stage 2.3): modes, tutorial, windows, settings, offline, splash, icons ---- */
svg use { pointer-events: none; }
.mbtn { display: flex; align-items: center; justify-content: center; gap: 8px; }
.mbtn svg, .set-row svg, .ico-list svg, .labels svg, .medals svg, .icon-sheet svg, .daily-off svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.mbtn svg { width: 22px; height: 22px; }
/* HUD by mode: Classic - score, best; a round and the board of the day - goal, moves left, stars (UI-03, UI-05) */
.cell-goal, .cell-moves, .cell-stars { display: none !important; }
body.m-round .cell-score, body.m-round .cell-best, body.m-daily .cell-score, body.m-daily .cell-best { display: none !important; }
body.m-round .cell-goal, body.m-round .cell-moves, body.m-round .cell-stars,
body.m-daily .cell-goal, body.m-daily .cell-moves, body.m-daily .cell-stars { display: flex !important; }
.hud .val.goal-v { display: flex; align-items: center; min-height: 30px; font-size: 17px; white-space: nowrap; }
.title-main { white-space: nowrap; }
.mini { display: inline-grid; place-items: center; min-width: 46px; height: 30px; padding: 0 7px; border-radius: 9px; font-family: var(--digit-font); font-weight: 600; font-size: 17px; color: #fff;
  background: linear-gradient(180deg, #ab8af2, #7a5ad6); box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .16), 0 2px 0 #43307a, 0 0 12px rgba(170, 140, 255, .55); text-shadow: 0 1px 0 rgba(50, 15, 80, .45); }
.stars-v { display: flex; gap: 2px; }
.stars-v svg, .big-stars svg, .labels svg.st { fill: rgba(255, 255, 255, .16); stroke: none; }
.stars-v svg { width: 22px; height: 22px; }
.stars-v svg.on, .labels svg.st, .big-stars svg.on { fill: #ffd66e; }
.streak { order: 3; display: none; align-items: center; justify-content: space-between; gap: 10px; margin: 8px 16px 0; padding: 8px 12px; border-radius: 14px; font-size: 13px;
  background: rgba(0, 0, 0, .24); box-shadow: inset 0 0 0 1px rgba(255, 220, 250, .1); }
body.m-daily .streak { display: flex; }
.streak-lbl { color: var(--ink-2); }
.streak-lbl b { color: #fff; }
.dots { display: flex; gap: 6px; align-items: center; }
.dots i { width: 12px; height: 12px; border-radius: 50%; background: rgba(255, 255, 255, .14); }
.dots i.on { background: #2ff3e0; box-shadow: 0 0 8px rgba(47, 243, 224, .6); }
.dots i.cur { background: transparent; box-shadow: inset 0 0 0 2px #ffd66e, 0 0 8px rgba(255, 214, 110, .5); }
.dots i.miss { background: rgba(255, 110, 140, .55); }
.dots.big { justify-content: center; gap: 9px; margin: 0 0 16px; }
.dots.big i { width: 18px; height: 18px; }
.medals { display: flex; align-items: center; gap: 4px; color: #ffd66e; }
.medals svg { width: 20px; height: 20px; }
.medals b { color: #fff; }
.daily-off { width: min(100cqw - 32px, 100cqh - 10px, 560px); aspect-ratio: 1; display: grid; place-content: center; justify-items: center; gap: 12px; text-align: center; padding: 24px; border-radius: 18px;
  background: repeating-linear-gradient(0deg, rgba(255, 255, 255, .02) 0 2px, transparent 2px 5px), radial-gradient(120% 90% at 30% 20%, #3a2852, #221733); box-shadow: inset 0 0 0 1px rgba(200, 170, 255, .12); }
.daily-off svg { width: 54px; height: 54px; color: var(--teal); stroke-width: 1.6; }
.daily-off p { margin: 0; font-size: 17px; }
.daily-off .btn { flex: none; padding: 0 22px; }
/* windows */
.win-col { display: grid; gap: 10px; }
.win-col .btn { flex: none; width: 100%; }
.win-pair { display: flex; gap: 10px; margin-bottom: 18px; }
.win-pair .win-score { flex: 1; margin: 0; }
.win-note { margin: 10px 0 0; font-size: 13px; color: var(--ink-2); font-weight: 500; }
.win-col .win-note { margin: -4px 0 0; }
.big-stars { display: flex; justify-content: center; align-items: flex-end; gap: 4px; margin: -2px 0 12px; }
.big-stars svg { width: 54px; height: 54px; }
.big-stars svg.mid { width: 68px; height: 68px; margin-bottom: 10px; }
.big-stars.dim svg { fill: rgba(255, 255, 255, .12); }
.share-line { margin: 0 0 16px; padding: 10px 12px; border-radius: 12px; background: rgba(0, 0, 0, .28); border: 1px dashed rgba(255, 255, 255, .2); font-size: 14px; color: #fff; }
.btn-danger { width: 100%; flex: none; }
.set-list { display: grid; gap: 8px; margin-bottom: 14px; text-align: left; }
.set-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 14px; border-radius: 14px; background: rgba(0, 0, 0, .24); font-size: 16px; }
.set-row svg { width: 24px; height: 24px; color: var(--ink-2); }
.set-row span { flex: 1; }
.sw { width: 46px; height: 28px; border-radius: 14px; background: rgba(255, 255, 255, .18); position: relative; flex: none; }
.sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, .3); }
.sw.on { background: #2fc8c0; }
.sw.on::after { left: 21px; }
.pill-v { font-size: 14px; padding: 6px 10px; border-radius: 999px; background: rgba(255, 255, 255, .1); font-weight: 600; }
.win-long { max-height: 100%; display: flex; flex-direction: column; }
.help-body { overflow: auto; text-align: left; margin: 0 -6px 14px; padding: 0 6px; min-height: 0; }
.help-body h3 { font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); margin: 14px 0 8px; }
.help-body h3:first-child { margin-top: 0; }
.help-body ul { margin: 0; padding-left: 18px; font-size: 15px; line-height: 1.45; font-weight: 500; }
.help-body ul.ico-list, .help-body ul.labels { list-style: none; padding: 0; display: grid; gap: 8px; }
.ico-list li, .labels li { display: flex; align-items: center; gap: 10px; }
.ico-list svg, .labels svg { width: 24px; height: 24px; }
.labels .k { min-width: 66px; display: flex; justify-content: center; font-weight: 700; font-size: 16px; }
.labels .dots i { width: 10px; height: 10px; }
.screen-center { justify-content: center; align-items: center; padding: 16px; }
.off-card { max-width: 340px; text-align: center; padding: 28px 20px; border-radius: 22px; position: relative;
  background: linear-gradient(180deg, #2c1b42, #22152f); box-shadow: inset 0 0 0 1px rgba(255, 220, 250, .14), 0 7px 0 #170d24, 0 24px 50px rgba(0, 0, 0, .5); }
.off-card .btn { width: 100%; flex: none; }
.off-ic { width: 64px; height: 64px; fill: none; stroke: var(--teal); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; margin: 0 auto 12px; display: block; }
.icon-sheet { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 6px 16px; overflow: auto; align-content: start; }
.icon-sheet figure { margin: 0; display: grid; justify-items: center; gap: 6px; padding: 10px 2px 8px; border-radius: 14px; background: rgba(0, 0, 0, .24); }
.icon-sheet svg { width: 28px; height: 28px; }
.icon-sheet figcaption { font-size: 12px; color: var(--ink-2); text-align: center; line-height: 1.2; }
.fav-row { display: flex; align-items: center; justify-content: center; gap: 18px; padding: 10px 16px 14px; }
#fav64 { width: 64px; height: 64px; }
#fav32 { width: 32px; height: 32px; }
#fav16 { width: 16px; height: 16px; }
/* tutorial (UI-04): the rest of the screen dims, the subject of the step is cut out and ringed */
.tut { position: absolute; inset: 0; z-index: 11; }
.tut-hole { position: absolute; border-radius: 20px; box-shadow: 0 0 0 9999px rgba(10, 5, 18, .8), 0 0 0 3px var(--teal), 0 0 26px rgba(47, 243, 224, .55); }
.tut-card { position: absolute; left: 16px; right: 16px; padding: 14px 16px 16px; border-radius: 18px; text-align: left;
  background: linear-gradient(180deg, #2c1b42, #22152f); box-shadow: inset 0 0 0 1px rgba(47, 243, 224, .35), 0 6px 0 #170d24, 0 20px 40px rgba(0, 0, 0, .5); }
.tut-step { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--teal); }
.tut-card p { margin: 6px 0 12px; font-size: 18px; line-height: 1.35; }
.tut-card .btn { flex: none; width: auto; padding: 0 24px; height: 48px; margin-left: auto; }
/* splash (UI-14) */
.splash { position: absolute; inset: 0; z-index: 12; display: grid; place-content: center; justify-items: center; gap: 26px; }
.splash-title { font-family: var(--title-font); font-weight: 600; font-size: 68px; line-height: 1; }
.splash-tile { width: 124px; height: 124px; border-radius: 26px; display: grid; place-items: center; background: linear-gradient(180deg, #74f7ec, #19b6c6);
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .18), inset 0 0 26px rgba(235, 255, 253, .65), 0 6px 0 #0d5f6e, 0 0 50px rgba(90, 255, 240, .75); }
.splash-tile span { font-family: var(--digit-font); font-weight: 600; font-size: 38px; color: #fff; text-shadow: 0 2px 0 rgba(6, 70, 80, .5); }
/* the idle gesture (UI-20): a finger swipes, no direction meant - not a move hint */
.gesture { position: absolute; left: 50%; top: 50%; width: 0; height: 0; z-index: 5; opacity: 0; pointer-events: none; }
.gesture i { position: absolute; left: -24px; top: -24px; width: 48px; height: 48px; border-radius: 50%; background: rgba(255, 255, 255, .22); box-shadow: 0 0 0 2px rgba(255, 255, 255, .75), 0 0 20px rgba(47, 243, 224, .6); }
.gesture span { position: absolute; left: 0; top: 34px; transform: translateX(-50%); white-space: nowrap; padding: 3px 9px; border-radius: 9px; font-size: 13px; color: #e8fffc; background: rgba(10, 5, 18, .78); }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .streak { margin: 0; }
  body.m-daily .title-main { font-size: 32px; }
  .hud .val.goal-v { font-size: 19px; }
  .rounds { width: 100%; max-width: 760px; margin: 0 auto; }
  .icon-sheet { grid-template-columns: repeat(6, 1fr); max-width: 760px; margin: 0 auto; width: 100%; }
}

/* ---- tools/look/mock/variant-c.css ---- */
/* Variant C "Layers" (the owner's choice, D13): cut-paper hills of violet, plum and orchid at the bottom and the top, a thin
   turquoise edge on one layer; the board sits on a paper mat; the title is stacked paper. Digits: Fredoka 600, as on the stand.
   Round 2 of the screens (owner 2026-11-06: "the ribbon - a rectangle in one style with smoothly cut corners; give everything
   volume, like photos 2 and 3, fitted to our look"): every control is glossy "jelly" - a light bevel rim, a dark outer frame
   with a hairline, a gloss band on top, a bounce of light at the bottom, a depth layer and a soft shadow. The board and the
   tiles stay K 1:1. */
:root { --bg: #170d24; --ink-2: #e2c6f0;
  --j-violet: linear-gradient(180deg, #a16ddf 0%, #7442c4 48%, #4f249a 100%);
  --j-orchid: linear-gradient(180deg, #f08cdb 0%, #c04eb4 48%, #8a2c8c 100%);
  --j-teal: linear-gradient(180deg, #84f6ea 0%, #27b9c4 48%, #0f7488 100%);
  --j-deep: linear-gradient(180deg, #7457dc 0%, #4a2ea8 46%, #2b1772 100%);
  --gloss: linear-gradient(180deg, rgba(255, 255, 255, .62), rgba(255, 255, 255, .08));
  --glitter: radial-gradient(circle at 30% 80%, rgba(255, 255, 255, .55) 0 .8px, transparent 1.4px) 0 0 / 17px 13px,
    radial-gradient(circle at 70% 40%, rgba(255, 225, 255, .4) 0 .7px, transparent 1.3px) 0 0 / 23px 19px;
  --frame: 0 0 0 2.5px #24103a, 0 0 0 3.5px rgba(220, 190, 255, .28);
}
.app, .screen, .splash {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 240' preserveAspectRatio='none'%3E%3Cpath d='M0 92C70 62 130 118 210 88S340 46 400 74V240H0Z' fill='%23281a3d'/%3E%3Cpath d='M0 140C80 112 150 166 232 132S352 104 400 126V240H0Z' fill='%23361d4d'/%3E%3Cpath d='M0 140C80 112 150 166 232 132S352 104 400 126' fill='none' stroke='%232ff3e0' stroke-opacity='.35' stroke-width='1.2'/%3E%3Cpath d='M0 190C74 170 162 210 252 182S362 166 400 180V240H0Z' fill='%23462260'/%3E%3C/svg%3E") bottom / 100% 34% no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 160' preserveAspectRatio='none'%3E%3Cpath d='M0 0H400V70C330 96 260 52 190 78S60 104 0 80Z' fill='%23231633'/%3E%3Cpath d='M0 0H400V34C320 56 250 22 170 44S50 60 0 42Z' fill='%23301c45'/%3E%3C/svg%3E") top / 100% 20% no-repeat,
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .016) 0 2px, transparent 2px 6px),
    radial-gradient(80% 50% at 50% 45%, #241638, #150c22);
}
.board { width: min(100cqw - 44px, 100cqh - 22px, 548px);
  box-shadow: inset 0 0 0 1px rgba(200, 170, 255, .12), 0 0 0 6px #2c1c42, 0 0 0 7px rgba(47, 243, 224, .22), 0 7px 0 7px #1a1029, 0 22px 44px rgba(0, 0, 0, .5); }
.title-main { color: #fff3fd; text-shadow: 0 2px 0 #c45ab3, 0 4px 0 #6b3fa0, 0 6px 0 #2a1840, 0 0 26px rgba(220, 110, 255, .45); }
.title-mode { color: #e3b8ec; margin-top: 9px; }

/* the HUD: one glossy rounded panel (no notched ribbon), cells split by a light and a dark hairline, text kept inside */
.hud { position: relative; isolation: isolate; gap: 0; margin: 8px 18px 10px; padding: 0 4px; border-radius: 18px;
  background: var(--j-deep);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .36), inset 0 -8px 14px rgba(160, 140, 255, .42), inset 0 2px 0 rgba(255, 255, 255, .2), var(--frame),
    0 6px 0 1px #1a0a2c, 0 14px 24px rgba(0, 0, 0, .45), 0 0 22px rgba(130, 100, 255, .25); }
.hud::before { content: ""; position: absolute; left: 8px; right: 8px; top: 3px; height: 44%; border-radius: 15px 15px 50% 50% / 15px 15px 12px 12px;
  background: var(--gloss); opacity: .75; pointer-events: none; z-index: 0; }
.hud > div { position: relative; z-index: 1; min-width: 0; padding: 0 6px; border-radius: 0; background: none;
  border-left: 1px solid rgba(255, 255, 255, .16); box-shadow: -1px 0 0 rgba(20, 5, 40, .4); }
.hud > div:first-child, body.m-round .cell-goal, body.m-daily .cell-goal { border-left: 0; box-shadow: none; }
.lbl { color: #efdcff; white-space: nowrap; }
.val { color: #fff; white-space: nowrap; text-shadow: 0 2px 0 rgba(30, 10, 70, .6), 0 0 12px rgba(220, 200, 255, .4); }

/* round buttons: "satin" 2a (owner 2026-11-06, chat: (owner words: docs/plan/decisions.md); (owner words: docs/plan/decisions.md)) - no separate gloss cap: a soft light from the top left spreads over the ball, the
   edge darkens all round, the colours one tone deeper than the jelly */
:root {
  --s-violet: radial-gradient(circle at 36% 26%, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 52%), linear-gradient(180deg, #8f5fcc, #663aae 50%, #44207f);
  --s-orchid: radial-gradient(circle at 36% 26%, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 52%), linear-gradient(180deg, #d97cc6, #a8449f 50%, #76267a);
  --s-teal: radial-gradient(circle at 36% 26%, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 52%), linear-gradient(180deg, #6fdccf, #22a3ad 50%, #0e6474);
  --s-shade: inset 0 0 0 1px rgba(20, 0, 40, .25), inset 0 0 10px 2px rgba(20, 0, 40, .38), inset 0 -8px 12px rgba(20, 0, 40, .3), inset 0 4px 8px rgba(255, 255, 255, .08);
}
/* the top bar gems (menu, help) keep the jelly gloss of round 2 (owner 2026-11-06, on the stand: the medallions (owner words: docs/plan/decisions.md), the top ones (owner words: docs/plan/decisions.md)) */
.ibtn { border-radius: 50%; color: #fff; background: var(--j-violet);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .42), inset 0 -5px 9px rgba(255, 170, 250, .42), var(--frame), 0 4px 0 1px #1a0a2c, 0 9px 16px rgba(0, 0, 0, .4); }
.ibtn::before { content: ""; position: absolute; left: 20%; right: 20%; top: 7%; height: 40%; border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%; background: var(--gloss); pointer-events: none;
  filter: blur(.75px); }
.ibtn svg, .ibtn .cap { position: relative; z-index: 1; }
.ibtn svg { filter: drop-shadow(0 1px 0 rgba(40, 10, 60, .55)); }

/* the action medallions: jelly spheres with a gloss cap and a caption below */
.actions { flex-basis: 100px; justify-content: space-evenly; gap: 0; }
.btn { flex: 0 0 auto; height: auto; flex-direction: column; gap: 8px; font-size: 14px; color: #fbe6f8; isolation: isolate; padding: 0 6px; border-radius: 0;
  background: none; box-shadow: none; text-shadow: 0 1px 0 rgba(40, 10, 50, .6); }
.btn::before { content: ""; position: absolute; top: 0; left: 50%; width: 60px; height: 60px; margin-left: -30px; border-radius: 50%; z-index: -1;
  background: var(--s-orchid); box-shadow: var(--s-shade), 0 4px 0 #1a0a2c, 0 10px 18px rgba(0, 0, 0, .42); }
.btn::after { content: none; }
.btn svg { width: 60px; height: 60px; padding: 17px; color: #fff; filter: drop-shadow(0 1px 0 rgba(40, 10, 60, .55)); }
.btn-hint::before { background: var(--s-teal); box-shadow: var(--s-shade), 0 4px 0 #0b2a35, 0 10px 18px rgba(0, 0, 0, .42); }

/* windows: the panel has the same bevel and frame; the title band is orchid jelly with a gloss */
.overlay { background: rgba(16, 8, 26, .92); }
.win-panel {
  background: linear-gradient(180deg, rgba(255, 255, 255, .3) 0, rgba(255, 255, 255, .04) 26px, transparent 27px), linear-gradient(180deg, #e27ad2 0, #9b3a9e 56px, transparent 56px),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .018) 0 2px, transparent 2px 5px), linear-gradient(180deg, #2e1c46, #21142f);
  box-shadow: inset 0 0 0 1.5px rgba(255, 220, 250, .32), inset 0 -10px 18px rgba(150, 110, 230, .14), 0 0 0 3px #24103a, 0 0 0 4px rgba(220, 190, 255, .26),
    0 8px 0 2px #1a0a2c, 0 28px 60px rgba(0, 0, 0, .55);
}
.win-title { color: #fff3fd; text-shadow: 0 2px 0 #6b3fa0, 0 0 18px rgba(255, 180, 245, .45); margin-top: -8px; margin-bottom: 26px; }
.win-victory .win-title { margin-top: 0; margin-bottom: 12px; }
.win-score .val { color: #fff; }
/* glossy pills (photo 3): orchid is the main action, deep violet the others, turquoise the ad, wine the reset */
.win-panel .btn, .off-card .btn, .daily-off .btn, .tut-card .btn { flex: 1; height: 54px; flex-direction: row; font-size: 16px; border-radius: 27px; color: #fff;
  background: var(--j-orchid);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .44), inset 0 -7px 11px rgba(255, 170, 250, .5), var(--frame), 0 5px 0 1px #1a0a2c, 0 10px 18px rgba(0, 0, 0, .4); }
.win-panel .btn::before, .off-card .btn::before, .daily-off .btn::before, .tut-card .btn::before { display: none; }
.win-panel .btn::after, .off-card .btn::after, .daily-off .btn::after, .tut-card .btn::after { display: block; content: ""; position: absolute; left: 12px; right: 12px; top: 3px; width: auto;
  height: 46%; margin: 0; border: 0; border-radius: 24px 24px 50% 50% / 24px 24px 12px 12px; background: var(--gloss); z-index: -1; }
.win-panel .btn svg, .off-card .btn svg, .daily-off .btn svg, .tut-card .btn svg { width: 22px; height: 22px; padding: 0; }
.win-panel .btn:not(.btn-primary) { background: var(--j-deep);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .36), inset 0 -7px 11px rgba(160, 140, 255, .45), var(--frame), 0 5px 0 1px #1a0a2c, 0 10px 18px rgba(0, 0, 0, .4); }
.win-panel .btn-ad { background: var(--j-teal);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .44), inset 0 -7px 11px rgba(170, 255, 245, .5), var(--frame), 0 5px 0 1px #0b2a35, 0 10px 18px rgba(0, 0, 0, .4); }
.win-panel .btn-danger { background: linear-gradient(180deg, #7a3566 0%, #57204e 50%, #3a1238 100%); color: #ffd3e0;
  box-shadow: inset 0 0 0 1.5px rgba(255, 170, 200, .55), inset 0 -7px 11px rgba(255, 120, 170, .3), var(--frame), 0 5px 0 1px #1a0a2c, 0 10px 18px rgba(0, 0, 0, .4); }
/* the menu tiles: glossy rounded rectangles */
.mbtn { color: #fff; isolation: isolate; border-radius: 16px; background: var(--j-deep);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .34), inset 0 -6px 10px rgba(160, 140, 255, .42), var(--frame), 0 5px 0 1px #1a0a2c, 0 9px 16px rgba(0, 0, 0, .35); }
.mbtn::after { content: ""; position: absolute; left: 8px; right: 8px; top: 3px; height: 44%; border-radius: 13px 13px 50% 50% / 13px 13px 10px 10px; background: var(--gloss); opacity: .8; z-index: -1; }
.mbtn.is-on { background: var(--j-orchid);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .44), inset 0 -6px 10px rgba(255, 170, 250, .5), var(--frame), 0 5px 0 1px #1a0a2c, 0 0 16px rgba(230, 110, 230, .35); }
/* the rounds map: jelly spheres */
.rb { border-radius: 50%; color: #fff; background: var(--s-violet); box-shadow: var(--s-shade), 0 4px 0 #1a0a2c, 0 9px 16px rgba(0, 0, 0, .4); }
.rb > * { position: relative; z-index: 1; }
.rb.cur { background: var(--s-teal); box-shadow: var(--s-shade), 0 4px 0 #0b2a35, 0 0 16px rgba(47, 243, 224, .35); }
.rb.locked { opacity: .5; }
.rb.sel::after { border-radius: 50%; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .actions { flex-direction: row; justify-content: flex-start; gap: 36px; }
  .btn { height: auto; font-size: 16px; }
  .hud { margin: 0; }
  .btn-menu { border-radius: 24px; }
  .board { width: min(100cqw, 100cqh - 20px, 548px); }
}

/* ---- tools/look/mock/variant-c-screens.css ---- */
/* Variant C, screens of stage 2.3 (round 2 - the glossy volume of D13's look): the streak strip is a slim jelly panel, the
   settings rows are recessed wells with jelly switches, the cards share the window's bevel and frame; the splash title is
   stacked paper. The buttons themselves are styled in variant-c.css. */
.streak { position: relative; isolation: isolate; margin: 2px 18px 0; border-radius: 16px; background: var(--j-deep);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .32), inset 0 -6px 10px rgba(160, 140, 255, .38), var(--frame), 0 5px 0 1px #1a0a2c, 0 10px 18px rgba(0, 0, 0, .35); }
.streak::before { content: ""; position: absolute; left: 8px; right: 8px; top: 2px; height: 44%; border-radius: 13px 13px 50% 50% / 13px 13px 9px 9px; background: var(--gloss); opacity: .6; z-index: -1; }
.streak-lbl { color: #efdcff; white-space: nowrap; }
.set-row { background: linear-gradient(180deg, #1b0e2c, #2a1843);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, .55), inset 0 -1px 0 rgba(255, 255, 255, .08), 0 1px 0 rgba(255, 255, 255, .06); }
.sw { background: linear-gradient(180deg, #1a0d2a, #2c1946); box-shadow: inset 0 2px 4px rgba(0, 0, 0, .6), 0 1px 0 rgba(255, 255, 255, .08); }
.sw.on { background: var(--j-teal); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .35), inset 0 -3px 5px rgba(170, 255, 245, .45), 0 0 10px rgba(47, 243, 224, .35); }
.sw::after { background: radial-gradient(circle at 50% 28%, #ffffff, #efe6ff 55%, #b7a3ea); box-shadow: 0 2px 4px rgba(0, 0, 0, .45), inset 0 -2px 3px rgba(120, 90, 200, .45); }
.pill-v { background: var(--j-deep); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3), inset 0 -3px 6px rgba(160, 140, 255, .4); }
.off-card, .tut-card {
  box-shadow: inset 0 0 0 1.5px rgba(255, 220, 250, .32), inset 0 -10px 18px rgba(150, 110, 230, .14), 0 0 0 3px #24103a, 0 0 0 4px rgba(220, 190, 255, .26),
    0 8px 0 2px #1a0a2c, 0 24px 50px rgba(0, 0, 0, .5); }
.tut-card { box-shadow: inset 0 0 0 1.5px rgba(47, 243, 224, .45), 0 0 0 3px #24103a, 0 0 0 4px rgba(170, 255, 245, .3), 0 8px 0 2px #1a0a2c, 0 20px 40px rgba(0, 0, 0, .5); }
.tut-card .btn { flex: none; width: auto; padding: 0 24px; height: 48px; margin-left: auto; }
.daily-off .btn { flex: none; padding: 0 22px; }
.off-card .btn { width: 100%; flex: none; }
.splash-title { color: #fff3fd; text-shadow: 0 3px 0 #c45ab3, 0 6px 0 #6b3fa0, 0 9px 0 #2a1840, 0 0 30px rgba(220, 110, 255, .45); }
.mbtn svg { color: #fff; filter: drop-shadow(0 1px 0 rgba(40, 10, 60, .55)); }
.mbtn span, .mbtn svg { position: relative; z-index: 1; }
.hud > div { flex: 1 1 0; }
.hud > .cell-goal { flex: 1.4 1 0; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .streak { margin: 0; }
  .hud .val.goal-v { font-size: 17px; }
}

/* ---- tools/look/game.css ---- */
/* The game's own additions over the approved look C (tools/look/mock/*.css stay the look 1:1, decision D13-D20, memory
   "carry the chosen look 1:1"): only what the mock-up did not need - the player's "less motion" setting, the kit's splash
   and score glow, keyboard focus, the language list, a short notice line, the second tutorial button. No new colours or sizes
   for anything the mock-up already draws. Source text is ASCII. */

/* the player's "less motion" = on (settings, UI-17) - the same rules as prefers-reduced-motion of base.css */
html.rm .tile { transition: none; }
html.rm .tile.new .tile-in, html.rm .tile.merged .tile-in { animation: fadeIn 120ms ease-out both; }
html.rm .tile.gone .tile-in { transition: none; }
html.rm .flow-in, html.rm .board::after, html.rm .medal::after { animation: none; }
html.rm .flow-in { transition: none; }
html.rm .overlay.opening { animation: fadeIn 120ms ease-out both; }
html.rm .overlay.opening .win-panel { animation: none; }
html.rm .rb.sel, html.rm .rb.sel::after { animation: none; }
/* the player's "less motion" = off: the system's reduce does not apply (the setting wins, UI-17) */
@media (prefers-reduced-motion: reduce) {
  html.motion .tile { transition: transform 100ms ease-out; }
  html.motion .tile.new .tile-in { animation: appear 120ms cubic-bezier(.2, .9, .3, 1.3) both; }
  html.motion .tile.merged .tile-in { animation: mergePulse 150ms ease-out; }
  html.motion .tile.gone .tile-in { transition: opacity 80ms ease-out 30ms; }
  html.motion .flow-in { animation: drift 12s ease-in-out infinite alternate; transition: opacity 1700ms cubic-bezier(.3, .6, .3, 1); }
  html.motion .board::after { animation: breathe 6s ease-in-out infinite; }
  html.motion .medal::after { animation: shine 2.4s ease-in-out infinite; }
  html.motion .overlay.opening { animation: ovIn 220ms ease-out both; }
  html.motion .overlay.opening .win-panel { animation: panelIn 220ms cubic-bezier(.2, .9, .3, 1.15) both; }
}

/* the kit's splash (kit/web/splash.js) over the ready game: it fades out */
.splash { transition: opacity 180ms ease-out; }
.splash.pk-splash-out { opacity: 0; pointer-events: none; }

/* the kit's score count-up (kit/web/score-fx.js): while the number rolls it is drawn with a thin teal neon outline, not a blurred
   glow (owner 09.11); the once-only grow at the end is the game's (src/game/play.js popScore) */
.hud .cell-score .val { -webkit-text-stroke: 2px rgba(47, 243, 224, 0); paint-order: stroke fill; transition: -webkit-text-stroke-color 140ms ease-out, text-shadow 140ms ease-out; }
.hud .pk-glow .val { -webkit-text-stroke-color: rgba(64, 247, 230, .95); text-shadow: 0 2px 0 rgba(30, 10, 70, .6), 0 0 3px rgba(47, 243, 224, .85), 0 0 8px rgba(47, 243, 224, .35); }

/* keyboard focus is always visible */
button:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }

/* the language list of the settings: the menu tiles in one column */
.lang-list { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; overflow: auto; min-height: 0; margin-bottom: 14px; padding: 2px; }
.lang-list .mbtn { height: 48px; font-size: 15px; }

/* a short notice line over the actions (storage refused, copied, no video) */
.toast { position: absolute; left: 50%; bottom: calc(var(--banner-h) + 96px); transform: translateX(-50%); z-index: 9; max-width: calc(100% - 32px);
  padding: 8px 14px; border-radius: 12px; font-size: 14px; font-weight: 500; text-align: center; color: #fff; background: rgba(10, 5, 18, .88);
  box-shadow: inset 0 0 0 1px rgba(255, 220, 250, .18); pointer-events: none; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .toast { bottom: 36px; } }

/* the tutorial card: a step that waits for no move (4) has Next and Skip */
.tut-row { display: flex; gap: 10px; justify-content: flex-end; align-items: center; }
.tut-row .btn { margin-left: 0; }
.tut-skip { font-size: 14px; color: var(--ink-2); padding: 0 8px; min-height: 48px; }

/* the line under the goal of a lost round */
.goal-line { margin: 0 0 16px; font-size: 15px; color: #fff; }

/* the settings rows are buttons in the game (the mock-up drew them as rows) */
.set-row { width: 100%; text-align: left; color: inherit; }

/* frame vs rule (pack rules/17 web item 6; spec 02 UI-11): on the computer icons >= 28 px and labels >= 15 px - the mock-up drew the
   top icons at 26 px and the streak at 13 px; the game takes the rule's value, the owner is asked (docs/plan/OWNER_QUEUE.md) */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .ibtn svg { width: 28px; height: 28px; }
  .streak { font-size: 15px; }
}

/* a long window fits the screen (spec 02 UI-05): the mock-up's .win-long has max-height 100%, but an auto grid row of the overlay
   grows with its content, so How to play ran 257 px past the phone screen and its button could not be reached. The row takes the
   overlay's height; the window's body scrolls inside (base: .help-body overflow auto). Gate: tools/gates/browser.mjs windows. */
.overlay { grid-template-rows: minmax(0, 1fr); }

/* D26: the plinth of a tile is lit (variant B of the tile-glow mock-up; the owner: "Variant B, but the halo less pronounced"): a thin
   bright seam on the bottom edge in the tier's light (--lamp) and a short glow under it; the halo around the tile is softer than
   K's (its blur x .55). The dark drop shadow of K gives way to the light, as on the mock-up. */
.tile { --lamp: 180, 120, 255; }
.tile[data-v="4"] { --lamp: 190, 130, 255; }
.tile[data-v="8"] { --lamp: 220, 120, 255; }
.tile[data-v="16"], .tile[data-v="32"], .tile[data-v="64"] { --lamp: 255, 120, 215; }
.tile[data-v="128"] { --lamp: 175, 150, 255; }
.tile[data-v="256"] { --lamp: 155, 140, 255; }
.tile[data-v="512"] { --lamp: 135, 150, 255; }
.tile[data-v="1024"] { --lamp: 60, 245, 228; }
.tile[data-v="2048"] { --lamp: 100, 255, 242; }
.tile-in { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .12), inset 0 0 calc(var(--s) * var(--in)) var(--inner),
  0 calc(var(--s) * .058) 0 var(--base), 0 calc(var(--s) * .062) calc(var(--s) * .02) rgba(var(--lamp), .7),
  0 calc(var(--s) * .1) calc(var(--s) * .14) rgba(var(--lamp), .24), 0 0 calc(var(--s) * var(--halo) * .55) var(--glow); }

/* D27: the light of the lower hills - variant C of the wave mock-up (the owner: "let us keep variant C, I looked at it well - that is
   how I imagined this effect"): a long soft band of light slides along the turquoise edge, the edge swells and fades with it; one
   cycle --edge-cycle (PARAMS.ui.edgeLightSec, set by src/game/view/edge-light.js, which also stops it on a hidden page). */
.hills-light { --edge-cycle: 9s; position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 34%; z-index: 0; pointer-events: none; }
.hills-light path { fill: none; vector-effect: non-scaling-stroke; }
.hl-edge { stroke: #2ff3e0; stroke-width: 1.2; stroke-opacity: 0; animation: hl-swell var(--edge-cycle) ease-in-out infinite; }
@keyframes hl-swell { 0%, 100% { stroke-opacity: 0; stroke-width: 1.2; } 50% { stroke-opacity: .28; stroke-width: 1.7; } }
.hl-wave { stroke: url(#hl-sweep); stroke-width: 3; filter: url(#hl-soft); }
.hills-light.still .hl-edge { animation-play-state: paused; }
/* less motion: no light, the hills stand as they were (edge-light.js pauses the band too) */
html.rm .hills-light { display: none; }
@media (prefers-reduced-motion: reduce) { html:not(.motion) .hills-light { display: none; } }

/* D30 (owner 09.11, manual pass): (1) the window panels are glossy jelly like the HUD - its deep violet, its bevel, a gloss cap
   under the title band; the content sits over the gloss (isolation, the cap at z -1). (2) the close button of a window fits the
   title band: 38 px, centred in the 56 px band, the frame and the drop inside the band (it was 48 px at 8 px and hung below the
   band). (4) the menu and help buttons stand on the HUD's edges (the bar's side padding = the HUD's side margin; the frame gate
   holds menu.x and help.right to the HUD as a rule of D30, art/frame-spec.mjs). */
.win-panel { isolation: isolate;
  background: linear-gradient(180deg, rgba(255, 255, 255, .3) 0, rgba(255, 255, 255, .04) 26px, transparent 27px), linear-gradient(180deg, #e27ad2 0, #9b3a9e 56px, transparent 56px),
    linear-gradient(180deg, #5b3dc6 0, #42289c 34%, #2d1876 100%);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .36), inset 0 -10px 18px rgba(160, 140, 255, .42), inset 0 2px 0 rgba(255, 255, 255, .2),
    0 0 0 3px #24103a, 0 0 0 4px rgba(220, 190, 255, .26), 0 8px 0 2px #1a0a2c, 0 28px 60px rgba(0, 0, 0, .55), 0 0 22px rgba(130, 100, 255, .25); }
.win-panel::before { content: ""; position: absolute; left: 1.5px; right: 1.5px; top: 56px; height: 64px; z-index: -1; pointer-events: none;
  border-radius: 0; background: linear-gradient(180deg, rgba(255, 255, 255, .17), rgba(255, 255, 255, .05) 45%, rgba(255, 255, 255, 0)); }
.win-panel .win-x { width: 38px; height: 38px; top: 9px; right: 10px;
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .42), inset 0 -4px 7px rgba(255, 170, 250, .42), var(--frame), 0 3px 0 1px #1a0a2c, 0 6px 10px rgba(0, 0, 0, .35); }
.win-panel .win-x svg { width: 20px; height: 20px; }
@media (max-width: 599px), (max-width: 899px) and (max-aspect-ratio: 5/4) { .bar { padding-left: 18px; padding-right: 18px; } }
/* D30 (3): the hint arrow is a jelly arrow in the hint button's teal - a dark rim, a top-lit body, a gloss on its upper half and a
   drop straight down (on the unturned .pointer, so the drop stays below whatever the arrow's direction) */
.pointer { filter: drop-shadow(0 3px 0 rgba(8, 42, 54, .95)) drop-shadow(0 0 8px rgba(47, 243, 224, .55)); }
.pointer svg { filter: none; stroke: none; }
.pointer .ptr-rim { fill: #0b2a35; stroke: #0b2a35; stroke-width: 4.5; stroke-linejoin: round; }
.pointer .ptr-fill { stroke: rgba(225, 255, 252, .7); stroke-width: 1.2; stroke-linejoin: round; }
.pointer .ptr-shine { transform: scale(.86); transform-origin: 24px 24px; }

/* D31 (owner 09.11, manual pass): (1) the window "Game over" has a red title band, not the orchid one; (2) a label stands centred
   over its number: the label's letter-spacing is put on both sides (it trailed on the right only) and a window's numbers use
   proportional digits (a tabular "1" left a gap on its left); the labels of a window are larger; (3) the score and the record have
   colours of their own wherever they stand as a pair - the score turquoise (the colour of the count-up's neon), the record gold
   (the colour of the stars): the HUD, the window "Game over", the score of the 2048 win, the How-to-play samples. */
#w-over .win-title { text-shadow: 0 2px 0 #74162a, 0 0 18px rgba(255, 140, 150, .45); }
.lbl { padding-left: .1em; }
.win-score .val { font-variant-numeric: proportional-nums; }
.win-score .lbl { font-size: 14px; margin-bottom: 2px; }
.cell-score .lbl, #w-over .win-score:first-child .lbl, #w-win .win-score .lbl { color: #8ff7ee; }
.cell-best .lbl, #w-over .win-score:last-child .lbl { color: #ffd98a; }
.cell-score .val, #w-over .win-score:first-child .val, #w-win .win-score .val, .labels li:nth-child(1) .k-num { color: #f2fffd; text-shadow: 0 2px 0 rgba(6, 60, 72, .6), 0 0 12px rgba(47, 243, 224, .42); }
.cell-best .val, #w-over .win-score:last-child .val, .labels li:nth-child(2) .k-num { color: #fff4da; text-shadow: 0 2px 0 rgba(92, 52, 8, .55), 0 0 12px rgba(255, 196, 90, .42); }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .win-score .lbl { font-size: 16px; } }

/* D32 (owner 09.11): the top paper waves breathe - variant A of the 5-6-7 mock-up ("the breathing fits, only the waves a bit
   wider"): the two waves of the top of the background are drawn by .top-waves (the background keeps its bottom hills, its top layer
   is sized away), 24 % wider than the screen, each swells and sinks on its own slow cycle (transform only - no paint a frame). Still
   with less motion and on a hidden or paused page (.still, src/game/view/edge-light.js). */
.app { background-size: 100% 34%, 0 0, auto, auto; }
.top-waves { position: absolute; left: 0; right: 0; top: 0; height: 20%; z-index: 0; pointer-events: none; }
.tw { position: absolute; inset: 0; transform-origin: 50% 0; }
.tw svg { position: absolute; top: 0; left: -12%; width: 124%; height: 100%; display: block; }
.tw-back { animation: tw-back 8s ease-in-out infinite alternate; }
.tw-front { animation: tw-front 6.3s ease-in-out infinite alternate; }
@keyframes tw-back { from { transform: translateX(-1.2%) scaleY(1); } to { transform: translateX(1.2%) scaleY(1.14); } }
@keyframes tw-front { from { transform: translateX(1%) scaleY(1.03); } to { transform: translateX(-1%) scaleY(1.22); } }
.top-waves.still .tw { animation-play-state: paused; }
html.rm .tw { animation: none; }
@media (prefers-reduced-motion: reduce) { html:not(.motion) .tw { animation: none; } }

/* D33 (owner 09.11): the caption of the idle gesture ("swipe") is a cream plate with dark plum text and larger (it was 13 px light
   text on a dark plate - too small to notice) */
.gesture span { top: 38px; padding: 6px 14px; border-radius: 12px; font-size: 16px; font-weight: 600; color: #3a1b4a; background: #fff1dc;
  box-shadow: inset 0 -2px 0 rgba(150, 100, 60, .18), 0 0 0 1.5px rgba(58, 27, 74, .35), 0 4px 12px rgba(0, 0, 0, .35); }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .gesture span { font-size: 17px; } }

/* D34 (owner 09.11): the title band of a window is a jelly button like the window's own buttons - the bevel rim, the gloss cap with
   its rounded edge, the bounce of light at the bottom - and its text is centred both ways in the band. The band is the title itself
   (it spans the panel's top edge to edge, 56 px high, flex-centred; side padding keeps the text clear of the close button and
   centred). Windows with a medal or stars over the title (.win-victory) keep the band of the panel's background. "Game over" (D31):
   the same jelly in red. */
.win-panel:not(.win-victory):not(.win-stars) .win-title { position: relative; isolation: isolate; box-sizing: border-box; display: flex; align-items: center; justify-content: center;
  min-height: 56px; margin: -26px -20px 22px; padding: 4px 52px; border-radius: 22px 22px 0 0; line-height: 1.15; text-align: center;
  background: var(--j-orchid);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .44), inset 0 -7px 11px rgba(255, 170, 250, .5), inset 0 -1.5px 0 rgba(40, 10, 60, .45); }
.win-panel:not(.win-victory):not(.win-stars) .win-title::before { content: ""; position: absolute; left: 14px; right: 14px; top: 4px; height: 46%; z-index: -1; pointer-events: none;
  border-radius: 18px 18px 50% 50% / 18px 18px 12px 12px; background: var(--gloss); }
#w-over .win-title { background: linear-gradient(180deg, #ff9898 0%, #d8404d 48%, #9c2232 100%);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .44), inset 0 -7px 11px rgba(255, 150, 160, .5), inset 0 -1.5px 0 rgba(60, 10, 20, .45); }

/* D35 (owner 09.11): the numbers of a result window carry an outline in their own colour - the score turquoise, the record gold
   (the stroke is painted under the fill, so the digit keeps its shape; 1.5 px - the owner: 3 px was twice too bold). The HUD keeps its plain digits: its score gets the neon
   outline only while it counts up (D29). */
#w-over .win-score .val, #w-win .win-score .val { paint-order: stroke fill; -webkit-text-stroke: 1.5px rgba(47, 243, 224, .95); }
#w-over .win-score:last-child .val { -webkit-text-stroke-color: rgba(255, 196, 90, .95); }

/* D37 (owner 09.11, variant C of the result-window mock-up): (6) every window has a soft living gradient - a gentle light from the
   top, a turquoise hint at the bottom over the deep violet; the 2048 win keeps its orchid band over it. The windows with stars
   (Round cleared, Round not cleared, Day result) carry them in a deep violet jelly band like the window's buttons: (2) the band
   is the stars row itself, top edge to edge; (1) the stars are gold with a gradient, a rim, a gloss and a glow (symbol star-big, not a line icon of the i-* set),
   the unlit ones dark violet; they light the sides first and the big middle one last (view/stars.js litBig). (3-5) The share line:
   no dashes, no "2048" in the window (the shared line keeps it), its parts apart on thin dividers (daily/share.js shareParts). */
:root { --win-body: radial-gradient(90% 55% at 50% 0%, rgba(150, 120, 255, .22), transparent 70%), radial-gradient(80% 30% at 50% 100%, rgba(47, 243, 224, .09), transparent 70%),
  linear-gradient(180deg, #5338bd 0%, #40269a 50%, #2f1b7c 100%); }
.win-panel, #w-over .win-panel { background: var(--win-body); }
#w-win .win-panel { background: linear-gradient(180deg, rgba(255, 255, 255, .3) 0, rgba(255, 255, 255, .04) 26px, transparent 27px), linear-gradient(180deg, #e27ad2 0, #9b3a9e 56px, transparent 56px), var(--win-body); }
.win-panel.win-stars::before { display: none; }
.win-stars .big-stars { position: relative; isolation: isolate; align-items: flex-end; gap: 6px; min-height: 96px; margin: -26px -20px 16px; padding: 16px 52px 12px;
  border-radius: 22px 22px 0 0; background: var(--j-deep);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .38), inset 0 -8px 13px rgba(160, 140, 255, .45), inset 0 -1.5px 0 rgba(20, 5, 50, .5); }
.win-stars .big-stars::before { content: ""; position: absolute; left: 14px; right: 14px; top: 4px; height: 44%; z-index: -1; pointer-events: none;
  border-radius: 18px 18px 50% 50% / 18px 18px 14px 14px; background: var(--gloss); }
.win-stars .big-stars svg, .win-stars .big-stars.dim svg { width: 52px; height: 52px; overflow: visible; fill: url(#star-off); stroke: rgba(255, 255, 255, .28); --gl: 0;
  filter: drop-shadow(0 2px 0 rgba(20, 5, 40, .45)); }
.win-stars .big-stars svg.mid { width: 66px; height: 66px; margin-bottom: 8px; }
.win-stars .big-stars svg.on { fill: url(#star-gold); stroke: #b0620e; --gl: 1; filter: drop-shadow(0 2px 0 rgba(120, 58, 0, .55)) drop-shadow(0 0 9px rgba(255, 196, 80, .45)); }
.win-stars .win-title { margin-top: 0; margin-bottom: 12px; }
.share-line { display: flex; justify-content: center; align-items: center; flex-wrap: wrap; row-gap: 4px; padding: 4px 0; border: 0; background: none; }
.share-line > span { padding: 0 14px; } .share-line > span + span { border-left: 1px solid rgba(255, 255, 255, .22); }
.share-line .sl-stars { color: #ffd66e; letter-spacing: .12em; text-shadow: 0 0 8px rgba(255, 200, 90, .45); }
.share-line .sl-stars i { font-style: normal; color: rgba(255, 255, 255, .25); text-shadow: none; }

/* D38 (owner 09.11, the Daily's HUD): (1) the number of the day is a block of the HUD (Daily only) - under the title it was barely
   seen; the title stands alone then. (3) The goal is a soft chip of the number, not a tile: a light tint and a hairline, the same
   line box as the other numbers, so the label and the number sit evenly. (5) The numbers of the round and the Daily HUD have one size
   (the goal looked smaller than the moves). (2) The streak bar keeps its parts together around the middle. */
.cell-day { display: none !important; }
body.m-daily .cell-day { display: flex !important; }
.hud > .cell-day { flex: .7 1 0; }
body.m-daily .hud > .cell-goal { border-left: 1px solid rgba(255, 255, 255, .16); box-shadow: -1px 0 0 rgba(20, 5, 40, .4); }
.title-mode:empty { display: none; }
body.m-round .hud .val, body.m-daily .hud .val { font-size: 22px; line-height: 1.15; }
.hud .val.goal-v { min-height: 0; font-size: 22px; line-height: 1.15; }
.hud .goal-v .mini { height: auto; min-width: 0; padding: 0 8px; border-radius: 8px; font-size: 22px; line-height: 1.15; color: #fff;
  background: rgba(255, 255, 255, .1); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22); text-shadow: 0 2px 0 rgba(30, 10, 70, .5); }
.streak { justify-content: center; gap: 18px; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { body.m-round .hud .val, body.m-daily .hud .val, .hud .val.goal-v, .hud .goal-v .mini { font-size: 26px; } }
body.m-daily .hud > .cell-day { border-left: 0; box-shadow: none; }
/* D38: four blocks on the computer - the labels stay >= 15 px (frame rule), so the blocks share the width by their words */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { body.m-daily .hud > .cell-day { flex: .7 1 0; } body.m-daily .hud > .cell-goal { flex: 1 1 0; } body.m-daily .hud > .cell-stars { flex: 1.25 1 0; } body.m-daily .hud .lbl { letter-spacing: .05em; } }

/* D39 (its threshold line removed by the owner, D41): the labels of the round and Daily HUD stand on one line at the top; the number
   or the stars are centred in the room under it */
body.m-round .hud > div, body.m-daily .hud > div { justify-content: flex-start; padding-top: 9px; padding-bottom: 6px; }
body.m-round .hud > div > .val, body.m-daily .hud > div > .val { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; margin-top: 0; }
body.m-round .cell-stars .val, body.m-daily .cell-stars .val { margin-top: 0; }

/* D40 (owner 09.11): the numbers of the round and Daily HUD in one style - the goal's soft chip and the digits of the tiles for the
   moves and the day too */
.hud .num-chip, .hud .goal-v .mini { display: inline-block; padding: 0 8px; border-radius: 8px; font-family: var(--digit-font); font-weight: var(--digit-w);
  letter-spacing: var(--digit-ls); font-size: 22px; line-height: 1.15; color: #fff; background: rgba(255, 255, 255, .1); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
  text-shadow: 0 2px 0 rgba(30, 10, 70, .5); font-variant-numeric: tabular-nums; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .hud .num-chip, .hud .goal-v .mini { font-size: 26px; } }
/* D41 (owner 09.11): no chips under the HUD's numbers - the goal, the moves and the day are bare digits of the tiles' font */
.hud .num-chip, .hud .goal-v .mini { padding: 0; background: none; box-shadow: none; border-radius: 0; }

/* D43 (owner 09.11): the Daily's streak strip is cut into three equal parts - the streak, the week's dots, the medals - each part's
   content centred in it, hairline dividers between the parts (the HUD's divider) */
body.m-daily .streak { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; padding-left: 0; padding-right: 0; }
.streak > * { display: flex; align-items: center; justify-content: center; min-width: 0; align-self: stretch; }
.streak > * + * { border-left: 1px solid rgba(255, 255, 255, .16); box-shadow: -1px 0 0 rgba(20, 5, 40, .4); }
.streak .dots { gap: 4px; }
.streak .dots i { width: 10px; height: 10px; }
.streak-lbl { gap: .3em; }
/* D43 (owner 09.11, the same for the top HUD): every block of the HUD - score/record, the round's goal/moves/stars, the Daily's
   day/goal/moves/stars - takes an equal share of the panel in every mode and width; the content is centred in its block. Overrides
   the shares by words of D38 and the wider goal of variant C (important: those rules are mode- and width-scoped). */
.hud > div { flex: 1 1 0 !important; align-items: center; }
.hud > div > .lbl, .hud > div > .val { text-align: center; }
/* D43, equal shares on the computer (browser gate, 16 languages): the Daily's four blocks are 83 px - the labels lose a little
   tracking and the blocks a little side padding (the label stays 15 px); the streak label may break between its word and its number
   when one third cannot hold both (id) */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { body.m-daily .hud > div { padding-left: 2px; padding-right: 2px; } body.m-daily .hud .lbl { letter-spacing: .02em; } }
.streak-lbl { flex-wrap: wrap; row-gap: 0; text-align: center; }
.streak-lbl > * { white-space: nowrap; }

/* D44 (owner 09.11, mockup "4 columns"): the Daily's streak strip follows the HUD's four columns - its dividers stand under the HUD's:
   the streak under "Day", the week's dots across "Goal" and "Moves", the medals under "Stars"; the side columns break into two lines
   (the streak's word / its days; the medal and its count / "weeks" - one medal = one full week of the streak). The 4 px side padding
   is the HUD's inner inset, measured. */
body.m-daily .streak { grid-template-columns: repeat(4, minmax(0, 1fr)); padding-left: 4px; padding-right: 4px; }
body.m-daily .streak .dots { grid-column: span 2; }
.medals { flex-wrap: wrap; row-gap: 0; column-gap: 4px; text-align: center; }
.medals > * { white-space: nowrap; }
.medals .wk { flex-basis: 100%; color: #efdcff; font-weight: 600; }
.medals.wk-first .wk { order: -1; }
.medals .wk:empty { display: none; }
/* D44: both side columns stand in two lines in every language (the mockup) - the streak's days under its word */
.streak-lbl > b { flex-basis: 100%; }

/* D47: the computer layout is one group in the middle of the screen (the owner on the test address: "center the elements dynamically,
   so that at different screen sizes and zooms they stand even"). The mock-up's first column was 1fr: the board sat in the middle of
   everything left of the side panel, the panel stuck to the right edge, and the gap between them grew with the width (152 px at 1280,
   792 px at 2560). Now the first column is exactly the board: its width is the board's own limit - 548 px or the height left under
   the top zone (100dvh - banner zone - the bottom padding 36 px - the board's 20 px of air) - and the two columns stand centred.
   Gate: tools/gates/browser.mjs (browser.center). */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .main { --bw: min(548px, calc(100dvh - var(--banner-h) - 56px)); grid-template-columns: minmax(0, var(--bw)) 340px; justify-content: center; }
}

/* The buttons of the top bar keep their 48 px on the narrowest phones (320 px): as flex items they shrank to 36-43 px under a long
   title ("Tabellone del giorno"), the title fit (src/game/ui.js fitTitles) measured the shrunken buttons and found room, and the title
   ran over them. Now only the title gives way. Gate: tools/gates/browser.mjs browser.titleNarrow (plant titleNoFit). */
.bar > .ibtn { flex-shrink: 0; }

/* D49: the tiles are frosted glass - option 3.4 of the tile mock-up (https://claude.ai/artifact/TSMoij2Cw5xvJBLnKPsnhE; the owner chose
   B of the neon sheet, then "too acid - put it on our soft style", then frosted glass, then "between 3 and 3.2: 3.2 dimmer by 5-10 %,
   the rim thinner by 15-20 %"). A see-through tint of the value's hue, the HUD's gloss on top, a thin rim in the hue (light above,
   full below), light pooling at the lower edge, a soft halo; the digit white, outlined in the deep shade of the hue. The palette goes
   blue -> violet -> purple -> orchid -> pink -> coral -> peach -> honey -> green apple -> mint -> the game's turquoise (2048 and up).
   Replaces the jelly fill of look C and the lit plinth of D26 (their --a, --b, --lamp stay unused); sizes, motion and digit sizes
   are unchanged. */
.tile { --c1: #8ff7ef; --c2: #35dccf; --d: #0f5d63; }
.tile[data-v="2"] { --c1: #8c8bff; --c2: #6b8cf6; --d: #3a3f9c; } .tile[data-v="4"] { --c1: #ab84ff; --c2: #8576f4; --d: #4a3596; }
.tile[data-v="8"] { --c1: #cf7ff5; --c2: #a36ff0; --d: #5e2f92; } .tile[data-v="16"] { --c1: #ef7fdc; --c2: #c977ec; --d: #7a2a7e; }
.tile[data-v="32"] { --c1: #f985b4; --c2: #ea7bd2; --d: #8a2a64; } .tile[data-v="64"] { --c1: #ff9184; --c2: #f27aa0; --d: #8e3048; }
.tile[data-v="128"] { --c1: #ffab6c; --c2: #fa8679; --d: #91402c; } .tile[data-v="256"] { --c1: #ffd06a; --c2: #fca35c; --d: #8e5a1c; }
.tile[data-v="512"] { --c1: #ade37a; --c2: #62d898; --d: #2f6e3e; } .tile[data-v="1024"] { --c1: #63e5c6; --c2: #5ebef2; --d: #1c5a72; }
.tile-in { overflow: hidden; border: calc(var(--s) * .022) solid transparent;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c1) 27%, #22163a), color-mix(in srgb, var(--c2) 40%, #1e1434)) padding-box,
    linear-gradient(180deg, color-mix(in srgb, color-mix(in srgb, var(--c1) 55%, #fff) 92%, #22163a), color-mix(in srgb, var(--c2) 92%, #22163a)) border-box;
  box-shadow: inset 0 calc(var(--s) * -.15) calc(var(--s) * .2) calc(var(--s) * -.11) color-mix(in srgb, var(--c2) 78%, transparent),
    0 calc(var(--s) * .05) 0 var(--d), 0 0 calc(var(--s) * .15) color-mix(in srgb, var(--c1) 33%, transparent),
    0 calc(var(--s) * .12) calc(var(--s) * .27) calc(var(--s) * -.11) color-mix(in srgb, var(--c2) 50%, transparent); }
.tile-in::before { content: ""; position: absolute; left: 9%; right: 9%; top: 5%; height: 36%; pointer-events: none;
  border-radius: calc(var(--s) * .14) calc(var(--s) * .14) 50% 50% / calc(var(--s) * .14) calc(var(--s) * .14) 30% 30%;
  background: linear-gradient(180deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0)); }
.tile .num, .tile[data-v="1024"] .num, .tile[data-v="2048"] .num { position: relative; paint-order: stroke fill;
  -webkit-text-stroke: calc(var(--s) * .033) var(--d); text-shadow: 0 0 calc(var(--s) * .12) color-mix(in srgb, var(--c1) 40%, transparent); }

/* D50: the glass tiles brighter and further apart (the owner: "the blue 2 and the violet 4 merge, 16 and 32 look alike - make the
   colours a little brighter so the difference shows besides the digits"; "an outline to the digits, a little crisper"). The hues
   now stand apart on the colour wheel - 2 azure, 4 indigo-violet, 8 purple, 16 magenta, 32 rose, 64 coral, 128 orange, 256 gold,
   512 green, 1024 sky-cyan, 2048 the game's turquoise - each a step more saturated; the glass holds more of its colour, the rim
   is less dimmed. The digit: a thicker, darker outline of its hue and a short dark drop instead of the soft glow. */
.tile { --c1: #a6fff7; --c2: #2ff3e0; --d: #0b5357; }
.tile[data-v="2"] { --c1: #74b8ff; --c2: #3f8bff; --d: #17357d; } .tile[data-v="4"] { --c1: #a98aff; --c2: #7a5cff; --d: #33248a; }
.tile[data-v="8"] { --c1: #d685ff; --c2: #a64dff; --d: #4c1a82; } .tile[data-v="16"] { --c1: #f77de8; --c2: #d94ad6; --d: #6e1a6c; }
.tile[data-v="32"] { --c1: #ff86a8; --c2: #f2507e; --d: #7d1840; } .tile[data-v="64"] { --c1: #ffa07e; --c2: #ff6a4f; --d: #82291b; }
.tile[data-v="128"] { --c1: #ffc070; --c2: #ff9135; --d: #82420e; } .tile[data-v="256"] { --c1: #ffe475; --c2: #f2bf2a; --d: #72560c; }
.tile[data-v="512"] { --c1: #aaee72; --c2: #4fd46a; --d: #1b5f2b; } .tile[data-v="1024"] { --c1: #7aeaff; --c2: #28b4f0; --d: #0e4a72; }
.tile-in {
  background: linear-gradient(180deg, color-mix(in srgb, var(--c1) 36%, #22163a), color-mix(in srgb, var(--c2) 52%, #1e1434)) padding-box,
    linear-gradient(180deg, color-mix(in srgb, var(--c1) 70%, #fff), var(--c2)) border-box;
  box-shadow: inset 0 calc(var(--s) * -.15) calc(var(--s) * .2) calc(var(--s) * -.11) color-mix(in srgb, var(--c2) 85%, transparent),
    0 calc(var(--s) * .05) 0 var(--d), 0 0 calc(var(--s) * .15) color-mix(in srgb, var(--c1) 38%, transparent),
    0 calc(var(--s) * .12) calc(var(--s) * .27) calc(var(--s) * -.11) color-mix(in srgb, var(--c2) 55%, transparent); }
.tile .num, .tile[data-v="1024"] .num, .tile[data-v="2048"] .num {
  -webkit-text-stroke: calc(var(--s) * .045) color-mix(in srgb, var(--d) 85%, #0c0418);
  text-shadow: 0 calc(var(--s) * .028) 0 color-mix(in srgb, var(--d) 70%, #0c0418); }

/* D52: the goal of a round in the HUD - one font and one line. A clear goal says its action in the label ("Merge 8+8") and shows
   the merges so far over the count; a score goal the score so far over the target (before: the tile digit in the tile font and
   "0/3" in the label font, a few pixels lower, read as stray numbers). */
.hud .goal-v .gp { font-family: var(--digit-font); font-weight: var(--digit-w); letter-spacing: var(--digit-ls); line-height: 1; white-space: nowrap; }
.hud .goal-v .gp small { font-size: .72em; color: #cdb8ee; }
/* the label of a clear goal is a short phrase, not a word: it takes tighter letters than the other labels, so it fits its cell in
   the 16 languages from a 320 px phone to the computer (gate browser.goal) */
.cell-goal .lbl { letter-spacing: .03em; padding-left: .03em; }

/* D53: the side panel on the computer, as the owner drew it - the mode title on the left, Menu and Help on the right (their outer
   edges on the HUD's), the HUD under it, the streak under that (Daily), Hint at the left edge and Replay / New game mirrored at the
   right edge; the items 26 px apart; the panel 58 px from the board; the whole panel centred on the board's height (as before).
   A long title shrinks into the room left by the buttons (src/game/ui.js fitTitles counts the bar's gaps). Gate: browser.center. */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .main { gap: 58px; }
  .side { gap: 26px; }
  .side .bar { justify-content: flex-start; gap: 10px; padding: 0 10px; } /* the top row 10 px inside the HUD edges on each side (the owner: a little narrower) */
  .side .bar .title { order: 0; margin-right: auto; align-items: flex-start; text-align: left; min-width: 0; }
  .side .bar .btn-menu { order: 1; }
  .side .bar .btn-help { order: 2; }
  .side .actions { justify-content: space-between; gap: 0; }
}

/* the tile's corners follow the cell's (the owner: "the corners are empty - fill them a few pixels"): the glass tile was rounded more
   than the dark cell under it (.19 of the tile against .154), and a sliver of the cell showed at every corner. Same radius now. */
.tile-in { border-radius: calc(var(--s) * .154); }
.tile-in::before { border-radius: calc(var(--s) * .11) calc(var(--s) * .11) 50% 50% / calc(var(--s) * .11) calc(var(--s) * .11) 30% 30%; }

/* D55: the plate of a reached score or clear goal in the win finale - the glass of the 2048 tile, wider, the label over the number */
.win-plate { position: absolute; left: 50%; top: 50%; z-index: 6; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-width: 46%; padding: 14px 26px 16px; border-radius: 20px; pointer-events: none; --c1: #a6fff7; --c2: #2ff3e0; --d: #0b5357;
  border: 2px solid transparent;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c1) 36%, #22163a), color-mix(in srgb, var(--c2) 52%, #1e1434)) padding-box,
    linear-gradient(180deg, color-mix(in srgb, var(--c1) 70%, #fff), var(--c2)) border-box;
  box-shadow: inset 0 -16px 22px -12px color-mix(in srgb, var(--c2) 85%, transparent), 0 5px 0 var(--d), 0 0 34px color-mix(in srgb, var(--c1) 45%, transparent); }
.win-plate .wp-lbl { font-size: 14px; letter-spacing: .1em; text-transform: uppercase; color: #e9fffd; white-space: nowrap; }
.win-plate .wp-val { font-family: var(--digit-font); font-weight: var(--digit-w); font-size: 44px; line-height: 1; color: #fff; white-space: nowrap;
  paint-order: stroke fill; -webkit-text-stroke: 4px var(--d); text-shadow: 0 3px 0 color-mix(in srgb, var(--d) 70%, #0c0418); }

/* D57: the rounds map tells passed, current and locked apart by colour, not only by the stars (owner 2026-11-10: "teal for the
   passed ones, gold B for the current one"): a passed round (`done`, it has a best) - the teal ball without the glow, the current
   one - gold with a warm glow, its stars white (gold on gold is not seen); locked - the violet as before. Gate: browser.mapColors. */
:root { --s-gold: radial-gradient(circle at 36% 26%, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 52%), linear-gradient(180deg, #f3c76a, #d79a2e 50%, #8f5a12); }
.rb.done { background: var(--s-teal); box-shadow: var(--s-shade), 0 4px 0 #0b2a35, 0 9px 16px rgba(0, 0, 0, .4); }
.rb.cur { background: var(--s-gold); box-shadow: var(--s-shade), 0 4px 0 #4a2a06, 0 0 16px rgba(255, 196, 80, .4); }
.rb.cur .stars path { fill: rgba(80, 40, 0, .3); stroke: rgba(90, 45, 0, .45); }
.rb.cur .stars i.on path { fill: #fffaf0; stroke: rgba(120, 66, 0, .8); }
.rb.cur > span:first-child { text-shadow: 0 1px 2px rgba(90, 45, 0, .55); }

/* D58: the rounds map writes the goal of every round under its ball (owner 2026-11-10, after the mock-up of the map: "yes, that is
   better, only capitalise the goals"; on the stand: "the captions are gone; make the digits and stars bigger"). The caption is its own
   grid cell in a row under the five balls (src/game/ui.js roundsMap): a caption of two lines (a narrow phone, a long language) makes
   its row taller instead of running into the next tier; it reaches half the gap past its column on each side. The number and the stars
   of a ball grow with the ball (container units; the computer's balls are twice the phone's). Gate: browser.mapGoals. */
.rb { container-type: inline-size; gap: clamp(3px, 4cqi, 7px); }
.rb > span:first-child { font-size: clamp(18px, 29cqi, 40px); line-height: 1; } /* the owner: "the digits a touch smaller" */
.rb .stars { gap: clamp(1px, 1.5cqi, 3px); }
/* the stars a touch bigger with a very thin outline (the owner): a star is an svg path - its line outside the fill (paint-order) */
.rb .stars i { width: clamp(11px, 14cqi, 20px); height: clamp(11px, 14cqi, 20px); }
.rb .stars i, .rb .stars i.on { clip-path: none; background: none; } /* the box of the old clipped star is gone: the path draws it */
.rb .stars svg { display: block; width: 100%; height: 100%; overflow: visible; }
.rb .stars path { fill: rgba(255, 255, 255, .2); stroke: rgba(16, 6, 36, .45); stroke-width: 1.8; stroke-linejoin: round; paint-order: stroke fill; }
.rb .stars i.on path { fill: #ffd66e; stroke: #8a5608; }
.rounds { container-type: inline-size; } /* the captions grow with the map: 12 px on a phone, 14-15 px on a wide phone view */
.rb-cap { min-width: 0; margin: -4px -5px 0; text-align: center; pointer-events: none; font-family: var(--ui-font); font-weight: 600;
  font-size: clamp(12px, 2.3cqi, 16px); line-height: 1.15; color: #e4d7f8; } /* the words 30 % nearer white than #d9c6f5 (the owner: "less see-through") */
.rb-cap b { font-family: var(--digit-font); font-weight: var(--digit-w); font-size: 1.08em; color: rgba(255, 255, 255, .85); white-space: nowrap; } /* the numbers 15 % see-through (the owner: "too white"); still the eye's first stop - the digits' font, bigger */
.rb-cap.locked { opacity: .45; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .rb-cap { font-size: clamp(15px, 2.3cqi, 17px); margin-top: -2px; } }

/* D59: the rounds screen, the owner on the stand v37: (1) the title "Rounds" larger, in proportion to the balls - 38 px on a phone
   (the computer keeps its 40 px); (2) Back a little bigger (48 -> 54 px) and a touch further right (+8 px);
   (3) the number of a ball outlined like the digit of a tile - a dark line of the ball's hue outside the fill and a short dark drop
   (.06em after the owner's "too thick" on v38); (4) the locked tiers fade with their distance from the open ones: the
   nearest locked tier 60 %, the next 50 %, then 40, 30, 20 % (src/game/ui.js sets data-far); the caption a tone fainter than its
   ball. Gates: browser.mapHead, browser.mapGoals (outline), browser.mapFade. */
@media (max-width: 599px), (max-width: 899px) and (max-aspect-ratio: 5/4) {
  .title-sm { font-size: min(38px, 10.6vw); } /* the owner on v38: "the word Rounds still bigger" (30 -> 38; a long language shrinks to fit - fitTitles) */
  #s-rounds .bar { padding-left: 26px; padding-right: 26px; }
}
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { #s-rounds .bar { padding: 0 16px; } }
#s-rounds .bar > .ibtn, #s-rounds .bar > .ibtn-ghost { width: 54px; height: 54px; }
#s-rounds .bar > .ibtn svg { width: 29px; height: 29px; }
.rb { --rb-d: #2a1650; } .rb.done { --rb-d: #0b5357; } .rb.cur { --rb-d: #72560c; }
/* the number's outline: a soft dark-grey halo, dense at the glyph and fading outwards (the owner on v39: "the black outline is too
   sharp, it cuts the pixels - dark grey, half see-through, fading from the centre to the edge"; v38: .06em stroke, v37: .1em) */
.rb > span:first-child, .rb.cur > span:first-child { -webkit-text-stroke: 0; paint-order: normal;
  text-shadow: 0 0 .03em rgba(40, 40, 48, .7), 0 0 .09em rgba(40, 40, 48, .45), 0 .03em .07em rgba(40, 40, 48, .35); }
.rb.locked { opacity: .6; } .rb.locked[data-far="1"] { opacity: .5; } .rb.locked[data-far="2"] { opacity: .4; }
.rb.locked[data-far="3"] { opacity: .3; } .rb.locked[data-far="4"] { opacity: .2; }
.rb-cap.locked { opacity: .54; } .rb-cap.locked[data-far="1"] { opacity: .45; } .rb-cap.locked[data-far="2"] { opacity: .36; }
.rb-cap.locked[data-far="3"] { opacity: .27; } .rb-cap.locked[data-far="4"] { opacity: .18; }

/* D59: a screen (the rounds map, offline) draws no background of its own: the app's shows through - its breathing top waves
   included - and the game under the screen is hidden. Before, the screen's own copy of the background began 60 px down with a
   straight top edge: a cut dark band over the title (the owner on v39: "a cut glow over the word - a frame of the text?"). */
.screen { background: none; }
.app:has(> .screen:not([hidden])) > .main, .app:has(> .screen:not([hidden])) > .fx { visibility: hidden; }

/* D60: the tiers of the rounds map apart (the owner on v40: "the tiers sit too close to the goal captions - divide them"; variant B
   of the mock-up https://claude.ai/artifact/F5RvR6jmx7Eidotxk188nu, "the word a little bigger, a little more room"): the tier's name
   in the middle of a thin line fading to both edges, 14 px on a phone (16 on the computer - the pack's 15 px floor), 30 px of room
   above a tier. Gate: browser.mapFade (the tier line). */
.tier-h { display: flex; align-items: center; gap: 14px; text-align: center; margin-top: 12px; font-size: 14px; }
.tier-h:not(:first-child) { margin-top: 30px; }
.tier-h::before, .tier-h::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, transparent, rgba(200, 170, 255, .4)); }
.tier-h::after { background: linear-gradient(270deg, transparent, rgba(200, 170, 255, .4)); }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .tier-h { font-size: 16px; } }

/* D61 (the owner on v41): (1) the close cross of every window - a red jelly button, softened on v42 ("too poisonous - less saturation");
   (2) the HUD labels of Daily and Rounds in colours like Classic's (Score teal, Best gold): Day pink, Goal teal, Moves sky, Stars
   gold - each value tinted to its label with the same soft glow; (3) on a phone Menu and Help stand 6 px inside the HUD edges -
   with the HUD's round corners their edges on the HUD's read as sticking out. Gate: browser.hudColors. */
.win-x, .win-panel .win-x { color: #fff; background: linear-gradient(180deg, #ec8a93 0%, #d2475a 50%, #962638 100%); }
.win-panel .win-x { box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .5), inset 0 -4px 7px rgba(255, 150, 165, .45), var(--frame), 0 3px 0 1px #3d0612, 0 6px 10px rgba(0, 0, 0, .35); }
.win-x svg { filter: drop-shadow(0 1px 0 rgba(90, 0, 20, .55)); }
.cell-day .lbl { color: #ffcdee; } /* D68: brighter, was #ffb0e4 - "hard to see" */
.cell-goal .lbl { color: #8ff7ee; }
.cell-moves .lbl { color: #c4dcff; } /* D68: brighter, was #9fc4ff */
.cell-stars .lbl { color: #ffd98a; }
.hud .cell-day .num-chip { color: #fff1fa; text-shadow: 0 2px 0 rgba(90, 20, 70, .55), 0 0 12px rgba(255, 120, 210, .38); }
.hud .goal-v .gp, .hud .goal-v .mini { color: #f2fffd; text-shadow: 0 2px 0 rgba(6, 60, 72, .6), 0 0 12px rgba(47, 243, 224, .4); }
.hud .goal-v .gp small { color: #a9e9e3; }
.hud .cell-moves .num-chip { color: #f0f3ff; text-shadow: 0 2px 0 rgba(20, 30, 90, .55), 0 0 12px rgba(130, 155, 255, .42); }
@media (max-width: 599px), (max-width: 899px) and (max-aspect-ratio: 5/4) { .bar { padding-left: 24px; padding-right: 24px; } }

/* D63 (the owner on v43): (1) the sections of How to play divided like the tiers of the map (D60) - the heading in the middle of a
   thin line fading to both edges; (2) the plate of the idle gesture twice as large and with a capital letter (the l10n texts) - it
   melted into the tiles; a long phrase (German) wraps inside the board instead of running past it. Gate: browser.hudColors. */
/* the headings teal like Score and the active buttons, the lines of the same tone (the owner on v44: variant B of
   https://claude.ai/artifact/GgYzydcwZcxQYubzVYXxsn) */
.help-body h3 { display: flex; align-items: center; gap: 12px; text-align: center; font-size: 14px; margin: 18px 0 10px; color: #8ff7ee; text-shadow: 0 0 10px rgba(47, 243, 224, .35); }
.help-body h3::before, .help-body h3::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, transparent, rgba(47, 243, 224, .55)); }
.help-body h3::after { background: linear-gradient(270deg, transparent, rgba(47, 243, 224, .55)); }
.gesture span { top: 44px; padding: 11px 26px; border-radius: 22px; font-size: clamp(24px, 8vw, 30px); line-height: 1.15; text-align: center; white-space: normal;
  width: max-content; max-width: calc(min(100cqw - 44px, 100cqh - 22px, 548px) - 32px); }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .gesture span { font-size: 32px; } }

/* D64 (the owner on v45): on the computer the side panel spans the board's cells - the top row (title, Menu, Help) on the top edge
   of the top cells, Hint and Replay (with their captions) on the bottom edge of the bottom cells, the blocks between (one HUD, or
   the HUD and the streak of Daily) at equal gaps. The board's cells start --g = 3.2 % of its width inside it (src/game/view/board.js
   fit, which sets --board-w and --cell-g on .app), so the panel is that much shorter than the board, centred on it (D47). Gate:
   browser.center. */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .side { height: calc(var(--board-w, var(--bw)) - 2 * var(--cell-g, 0px)); justify-content: space-between; gap: 0; }
}
/* D64, more compact (the owner on v46: "more compact - the top row by the BOTTOM edge of the top cells, the buttons by the TOP edge of
   the bottom cells"): the top row stands in a box one cell high and sits at its bottom (its bottom on the bottom of the top cells),
   Hint and Replay in a box one cell high at its top (their top on the top of the bottom cells); the HUD and the streak between at
   equal gaps. --cell-s - the cell size from src/game/view/board.js fit. */
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) {
  .side .bar { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-content: end; align-items: center; min-height: var(--cell-s, 0px); }
  .side .bar .title { margin-right: 0; }
  .side .actions { flex: none; min-height: var(--cell-s, 0px); align-items: flex-start; }
}

/* D66, D67: the splash (the owner: "slide in", 160 ms a tile; "for the wow effect"). The tiles of the board 2 ... 2048 (the board's
   classes, glass and colours; 12 % bigger, 15 % less saturated - "too poisonous") slide in to the centre from the left and the right in
   turn, from a short way off it (.68 of a tile), each covering the one before. No title, no trail. Then the 2048 comes in and the camera
   dives into it: --sp-dive long, faster and faster; its glass turns see-through and the splash's own background fades, so the game shows
   through it; the digits melt in the last third. CRISP: the 2048 face is drawn at its final size (11 x the tile) and shown scaled down by
   11 - the dive lifts the scale-down, the browser rasterises it at full size and never stretches a small picture. --sp-step, --sp-last,
   --sp-dive - PARAMS.ui (set by play.js); on screen 2.32 s - the game's own splash (src/game/view/splash.js, D67). Reduced motion
   (.pk-still) - the 2048 at once. Gate: browser.splash. */
.splash { background: none; isolation: isolate; }
.splash::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 240' preserveAspectRatio='none'%3E%3Cpath d='M0 92C70 62 130 118 210 88S340 46 400 74V240H0Z' fill='%23281a3d'/%3E%3Cpath d='M0 140C80 112 150 166 232 132S352 104 400 126V240H0Z' fill='%23361d4d'/%3E%3Cpath d='M0 140C80 112 150 166 232 132S352 104 400 126' fill='none' stroke='%232ff3e0' stroke-opacity='.35' stroke-width='1.2'/%3E%3Cpath d='M0 190C74 170 162 210 252 182S362 166 400 180V240H0Z' fill='%23462260'/%3E%3C/svg%3E") bottom / 100% 34% no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 160' preserveAspectRatio='none'%3E%3Cpath d='M0 0H400V70C330 96 260 52 190 78S60 104 0 80Z' fill='%23231633'/%3E%3Cpath d='M0 0H400V34C320 56 250 22 170 44S50 60 0 42Z' fill='%23301c45'/%3E%3C/svg%3E") top / 100% 20% no-repeat,
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .016) 0 2px, transparent 2px 6px),
    radial-gradient(80% 50% at 50% 45%, #241638, #150c22);
  animation: sp-bg calc(var(--sp-dive) * .7) ease-in forwards; animation-delay: calc(10 * var(--sp-step) + var(--sp-last) + var(--sp-dive) * .25); }
.splash .sp-flip { --sp-s: 126px; --s: var(--sp-s); position: relative; width: var(--s); height: var(--s); filter: saturate(.85); }
.splash .sp-flip .tile { position: absolute; left: 0; top: 0; opacity: 0; transform: none;
  animation: sp-slide calc(var(--sp-step) * .85) cubic-bezier(.2, .8, .3, 1.05) forwards; animation-delay: calc(var(--i) * var(--sp-step)); }
@keyframes sp-slide { from { opacity: 0; transform: translateX(calc(var(--side) * var(--sp-s) * .68)); } 55% { opacity: 1; } to { opacity: 1; transform: translateX(0); } }
/* when the 2048 is in, the tiles under it go (the owner: "after 2048 a 1024 still hangs in the centre" - it showed through the glass) */
.splash .sp-flip .tile:not([data-v="2048"]) { animation: sp-slide calc(var(--sp-step) * .85) cubic-bezier(.2, .8, .3, 1.05) forwards, sp-gone 1ms linear forwards;
  animation-delay: calc(var(--i) * var(--sp-step)), calc(10 * var(--sp-step) + var(--sp-last)); }
@keyframes sp-gone { to { opacity: 0; } }
.splash .sp-flip .tile[data-v="2048"] { --s: calc(var(--sp-s) * 11); left: 50%; top: 50%; margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  animation: sp-last var(--sp-last) cubic-bezier(.2, .8, .3, 1.05) forwards, sp-dive var(--sp-dive) cubic-bezier(.45, 0, .7, .45) forwards, sp-glass var(--sp-dive) ease-in forwards;
  animation-delay: calc(10 * var(--sp-step)), calc(10 * var(--sp-step) + var(--sp-last)), calc(10 * var(--sp-step) + var(--sp-last)); }
.splash .sp-flip .tile[data-v="2048"] .num { animation: sp-melt calc(var(--sp-dive) * .35) ease-in forwards; animation-delay: calc(10 * var(--sp-step) + var(--sp-last) + var(--sp-dive) * .6); }
@keyframes sp-last { from { opacity: 0; transform: translateX(calc(var(--side) * var(--sp-s) * .68)) scale(calc(1 / 11)); } to { opacity: 1; transform: translateX(0) scale(calc(1 / 11)); } }
@keyframes sp-dive { from { transform: scale(calc(1 / 11)); } to { transform: scale(1); } }
@keyframes sp-glass { 0%, 35% { opacity: 1; } 100% { opacity: .18; } }
@keyframes sp-bg { to { opacity: 0; } }
@keyframes sp-melt { to { opacity: 0; } }
.splash.pk-still::before, .splash.pk-still .sp-flip .tile, .splash.pk-still .sp-flip .tile[data-v="2048"] .num { animation: none; }
.splash.pk-still .sp-flip .tile[data-v="2048"] { animation: none; opacity: 1; transform: scale(calc(1 / 11)); }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { .splash .sp-flip { --sp-s: 158px; } }

/* D68 (the owner on the test address 1.0.6, 2026-11-10): (1) the title of the Daily board is flat - the stacked pink and violet layers
   under its letters read as a blurred font, "hard on the eyes"; the 2048 logo and the map's Rounds keep them; (2) Day and Moves of the
   HUD brighter - "hard to see": lifted to the lightness of Goal and Stars (relative luminance ~.70 against .54-.58), the hue kept - the
   colours stand in the D61 block. Gate: browser.hudColors. */
body.m-daily #title-main { text-shadow: none; }

/* D69 (the owner's mock-up https://claude.ai/artifact/U9M3iXHPn1yCHfjAhYUtuc): a dead board - the glass of the tiles cracks from the
   tile the last move brought and falls before the window (src/game/view/shatter.js). A crack is an svg over the tile's glass, under
   its round corners and over its digit; drawn by the dash of each piece (--w its start, --d its length), then fixed without the
   animation (.done - Chrome does not repaint a filtered path under a dash animation). A shard is a copy of the glass clipped to its
   piece. Gate: browser.shatter. */
.crk { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3; pointer-events: none; overflow: visible; }
.crk path { fill: none; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.crk.go path { animation: crk-draw var(--d, 160ms) cubic-bezier(.2, .7, .3, 1) forwards; animation-delay: var(--w, 0ms); }
.crk.done path { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
@keyframes crk-draw { to { stroke-dashoffset: 0; } }
.tile .shard { position: absolute; inset: 0; z-index: 5; will-change: transform, opacity; }
.tile.split > .tile-in { visibility: hidden; }
.tile.hit > .tile-in { animation: crk-hit 220ms ease-out; } /* the glass, not the tile - the tile stands by its transform */
@keyframes crk-hit { 35% { transform: scale(.95); } }
.board.glass-dead .tile { filter: saturate(.78) brightness(.93); transition: filter 600ms ease; }

/* ManyPlay site release 11.11.2026 (D71, no ads): the banner zones of spec 02 UI-24 stay empty, so they shrink to a margin - the
   phone column gave them 120 px of a 390 px frame. The rest of the screens follow (.screen and .toast read the same variable). */
:root { --banner-h: 12px; }
@media (min-width: 900px), (min-width: 600px) and (min-aspect-ratio: 5/4) { :root { --banner-h: 28px; }
  /* the smaller zone lets the board grow by the height, so the D47 group must also fit the width (Codex recheck: 900 x 640 ran 23 px
     past each edge): board + gap 40 + panel 340 + padding 2 x 64 */
  .main { --bw: min(548px, calc(100dvh - var(--banner-h) - 56px), calc(100vw - 508px)); } }
/* a wide low frame between 600 and 899 px takes the computer layout (build-game-assets.mjs DESK_MQ) with tighter margins and a
   narrower side panel (300 px, 260 px under 760 px) */
@media (min-width: 600px) and (max-width: 899.98px) and (min-aspect-ratio: 5/4) {
  .main { --side-w: 300px; --pad: 24px; --gap-w: 24px; gap: var(--gap-w); padding: 0 var(--pad) 20px;
    --bw: min(548px, calc(100dvh - var(--banner-h) - 40px), calc(100vw - 2 * var(--pad) - var(--gap-w) - var(--side-w)));
    grid-template-columns: minmax(0, var(--bw)) var(--side-w); }
}
@media (min-width: 600px) and (max-width: 759.98px) and (min-aspect-ratio: 5/4) {
  .main { --side-w: 280px; --pad: 16px; --gap-w: 16px; padding-bottom: 16px; }
  /* the menu button keeps only its icon, the title and the HUD take the phone's sizes - the panel is 280 px, not 340 */
  .btn-menu { padding: 0; width: 48px; justify-content: center; } .cap-desk { display: none; }
  .title-main { font-size: 30px; } .title-mode { font-size: 13px; }
  .hud > div { height: 70px; } .lbl, .hud .lbl { font-size: 12px; letter-spacing: 0; }
  .val, .hud .val, body.m-round .hud .val, body.m-daily .hud .val, .hud .val.goal-v, .hud .goal-v .mini, .hud .num-chip { font-size: 20px; }
}
