/* Paws & Plots (formerly Queens & Cats). HulaGames candy brand: tokens copied from hulagames-portal/src/styles/tokens.css. */
@font-face { font-family: "Fredoka"; font-weight: 700; font-display: swap; src: url("./assets/fonts/fredoka-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Outfit"; font-weight: 400; font-display: swap; src: url("./assets/fonts/outfit-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Outfit"; font-weight: 600; font-display: swap; src: url("./assets/fonts/outfit-latin-600-normal.woff2") format("woff2"); }

:root {
  --lagoon-950: #051b1d; --lagoon-900: #072325; --lagoon-800: #0c3437; --lagoon-700: #13484c;
  --foam: #e9f6f1; --foam-dim: #a9cbc4; --hibiscus: #ff5e6c; --sun: #ffc23d; --sun-hover: #ffd36e;
  --reef: #2fc4b2; --ink-on-sun: #2a1a00; --ink: #13282b;
  --font-display: "Fredoka", "Baloo 2", "Arial Rounded MT Bold", system-ui, sans-serif;
  --font-body: "Outfit", "Segoe UI", system-ui, sans-serif;
  --radius-tile: 16px; --radius-pill: 999px;
  --shadow-lift: 0 10px 30px rgba(0,0,0,.45);
  --ease-pop: cubic-bezier(.2,.9,.3,1.3);
  color-scheme: dark;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh; overflow-x: hidden;
  background: radial-gradient(120% 60% at 50% -10%, #0f4a4c 0%, var(--lagoon-950) 60%) fixed, var(--lagoon-950);
  color: var(--foam); font: 400 16px/1.45 var(--font-body);
  -webkit-tap-highlight-color: transparent;
}
.sprites { position: absolute; width: 0; height: 0; overflow: hidden; }
a { color: var(--reef); }
h1, h2 { font-family: var(--font-display); font-weight: 700; margin: 0; }
.muted { color: var(--foam-dim); }
.small { font-size: .88rem; }
.center { text-align: center; }
button { font: inherit; color: inherit; cursor: pointer; }
button:focus-visible, a:focus-visible { outline: 3px solid var(--reef); outline-offset: 2px; }

.screen { max-width: 560px; margin: 0 auto; padding: 0 16px 32px; }
.screen.game { padding: 0 12px 24px; }

/* ---------- top bar ---------- */
.topbar { display: grid; grid-template-columns: 48px 1fr auto; align-items: center; gap: 8px; min-height: 60px; }
.topbar .title { text-align: center; line-height: 1.15; min-width: 0; }
.topbar .title b { display: block; font-family: var(--font-display); font-size: 1.15rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .title small { color: var(--foam-dim); font-size: .8rem; }
.icon-btn { width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--lagoon-800); display: grid; place-items: center; font-size: 1.8rem; line-height: 1; text-decoration: none; color: var(--foam); padding-bottom: 4px; }
.timer { min-width: 56px; text-align: right; font: 600 1.05rem var(--font-body); font-variant-numeric: tabular-nums; }
.skip { border: 0; background: transparent; color: var(--foam-dim); min-height: 44px; padding: 0 6px; text-decoration: underline; }

/* ---------- mode toggle ---------- */
.modes { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 4px; background: var(--lagoon-900); border-radius: var(--radius-pill); padding: 4px; margin: 4px auto 12px; max-width: 520px; }
.modes button { min-height: 44px; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--foam-dim); font-weight: 600; display: flex; align-items: center; justify-content: center; gap: 4px; }
.modes button[aria-pressed="true"] { background: var(--lagoon-700); color: var(--foam); }
.mini { width: 20px; height: 20px; color: var(--foam); }

/* ---------- board ---------- */
.board-wrap { display: flex; justify-content: center; }
.board {
  --line: rgba(20,30,40,.16); --thick: var(--ink); --tw: 3px;
  display: grid; grid-template-columns: repeat(var(--n), var(--cell));
  border: 3px solid var(--thick); border-radius: 12px; overflow: hidden;
  background: var(--thick); box-shadow: var(--shadow-lift), 0 0 0 4px rgba(233,246,241,.08);
  touch-action: pinch-zoom; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.board.small { --tw: 2.5px; }
.board.dark { --line: rgba(233,246,241,.16); --thick: #e9f6f1; }
.cell {
  position: relative; width: var(--cell); height: var(--cell);
  border-top: 1px solid var(--line); border-left: 1px solid var(--line);
  display: grid; place-items: center; cursor: pointer;
}
.cell.bt { border-top: var(--tw) solid var(--thick); }
.cell.bl { border-left: var(--tw) solid var(--thick); }
.cell::after { content: ""; position: absolute; inset: 0; pointer-events: none; transition: background .15s; }
/* Candy glaze on every square. Code-drawn placeholder; the delivered QC-004 PNG replaces it (html.art-tile). */
.cell::before {
  content: ""; position: absolute; inset: 1px; border-radius: 18%; pointer-events: none;
  background: radial-gradient(120% 70% at 28% 8%, rgba(255,255,255,.5) 0%, rgba(255,255,255,.14) 38%, rgba(255,255,255,0) 55%),
              linear-gradient(180deg, rgba(255,255,255,0) 60%, rgba(0,0,0,.10) 100%);
  box-shadow: inset 1.5px 1.5px 0 rgba(255,255,255,.55), inset -1.5px -2px 0 rgba(0,0,0,.14);
}
.board.dark .cell::before { opacity: .6; }
.art-tile .cell::before { inset: 0; border-radius: 0; box-shadow: none; background: url("./assets/art/tile-gloss.png") center / 100% 100% no-repeat; }
.tok { position: absolute; display: none; pointer-events: none; }
.tok.cat { width: 96%; height: 96%; filter: drop-shadow(0 2px 2px rgba(0,0,0,.25)); }
.tok.x { width: 42%; height: 42%; color: rgba(20,30,40,.62); }
.board.dark .tok.x { color: rgba(240,250,250,.75); }
.has-cat .tok.cat, .has-x .tok.x { display: block; }
.has-x .tok.x { animation: fade .18s ease-out; }
.pop .tok.cat { animation: pop .3s var(--ease-pop); }
.conflict::after { background: rgba(255,40,70,.42); box-shadow: inset 0 0 0 3px #ff2846; }
.wiggle .tok.cat { animation: wiggle .4s ease-in-out; }
.wrong::after { background: rgba(255,40,70,.3); box-shadow: inset 0 0 0 3px #ff2846; }
.hint::after { background: rgba(255,255,255,.28); box-shadow: inset 0 0 0 3px var(--sun); }
.coach-hl::after { box-shadow: inset 0 0 0 4px var(--sun); animation: glow 1.1s ease-in-out infinite; }
.reach::after { background: rgba(10,20,30,.38); }
.reach-src::after { box-shadow: inset 0 0 0 3px #fff; }
.bounce .tok.cat { animation: bounce .55s var(--ease-pop); }
.board.won { box-shadow: var(--shadow-lift), 0 0 0 4px var(--sun), 0 0 40px rgba(255,194,61,.45); transition: box-shadow .4s; }
@keyframes pop { 0% { transform: scale(.3); } 70% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes fade { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: none; } }
@keyframes wiggle { 0%,100% { transform: rotate(0); } 25% { transform: rotate(-12deg); } 75% { transform: rotate(12deg); } }
@keyframes bounce { 0%,100% { transform: translateY(0); } 40% { transform: translateY(-28%) scale(1.08); } }
@keyframes glow { 50% { background: rgba(255,194,61,.35); } }
@media (prefers-reduced-motion: reduce) { .tok, .cell::after, .modal, .modal-back { animation: none !important; transition: none !important; } }

/* ---------- hint bar + controls ---------- */
.hintbar { display: none; max-width: 520px; margin: 12px auto 0; padding: 10px 14px; border-radius: 14px; background: var(--lagoon-800); border-left: 4px solid var(--sun); font-size: .95rem; }
.hintbar.show { display: block; }
.hintbar.bad { border-left-color: var(--hibiscus); }
.hintbar.good { border-left-color: var(--reef); }
.hintbar p { margin: 0; }
.controls { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; max-width: 520px; margin: 12px auto 0; }
.ctl { min-height: 56px; border: 0; border-radius: 14px; background: var(--lagoon-800); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; font-weight: 600; font-size: .85rem; box-shadow: inset 0 -3px 0 rgba(0,0,0,.25); }
.ctl:active { transform: translateY(1px); box-shadow: none; }
.ctl .ic { font-size: 1.2rem; line-height: 1.1; }
.ctl[data-act="hint"] { background: var(--sun); color: var(--ink-on-sun); }

/* ---------- home ---------- */
.brandbar { display: flex; justify-content: center; padding: 14px 0 0; }
.brandbar img { height: 22px; width: auto; opacity: .9; }
.hero { text-align: center; padding: 10px 0 14px; }
.hero-cat { width: 64px; height: 64px; }
.hero h1 { font-size: clamp(2.2rem, 10vw, 3rem); line-height: 1.05; color: var(--sun); text-shadow: 0 3px 0 rgba(0,0,0,.35); }
.logo-art { display: block; width: min(360px, 92vw); height: auto; margin: -8px auto -6px; }
.hero.has-logo .hero-cat { display: none; }
.tag { margin: 6px 0 0; color: var(--foam-dim); }
.card { background: var(--lagoon-800); border-radius: 20px; padding: 16px; margin: 12px 0; box-shadow: 0 1px 0 rgba(255,255,255,.06) inset; }
.card h2 { font-size: 1.35rem; }
.card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 10px; }
.card .small { margin: -4px 0 10px; }
.diff-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.diff {
  min-height: 84px; border-radius: 16px; text-decoration: none; padding: 10px 6px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  background: linear-gradient(180deg, var(--sun-hover), var(--sun)); color: var(--ink-on-sun);
  box-shadow: inset 0 -4px 0 rgba(0,0,0,.18), 0 4px 10px rgba(0,0,0,.25);
}
.diff b { font-family: var(--font-display); font-size: 1.15rem; }
.diff small { opacity: .75; font-size: .8rem; }
.diff .st { font-weight: 600; font-size: .85rem; }
.diff.done { background: linear-gradient(180deg, #43d6c4, var(--reef)); color: #032a26; }
.diff.unl { background: linear-gradient(180deg, #ff8a7a, var(--hibiscus)); color: #2a0006; }
.perfect { margin: 12px 0 0; text-align: center; font-weight: 600; color: var(--sun); }
.countdown { margin: 12px 0 0; text-align: center; font-size: .9rem; }
.cd { font-variant-numeric: tabular-nums; color: var(--foam); font-weight: 600; }
.statrow { display: flex; justify-content: space-around; gap: 8px; flex-wrap: wrap; padding: 12px; border-radius: 16px; background: var(--lagoon-900); color: var(--foam-dim); text-decoration: none; font-size: .9rem; min-height: 48px; align-items: center; }
.statrow b { color: var(--foam); }
.flame.on b { color: var(--sun); }
.links { display: flex; justify-content: center; gap: 4px; margin: 10px 0; }
.links a { min-height: 44px; display: inline-flex; align-items: center; padding: 0 12px; text-decoration: none; font-weight: 600; }
.about { color: var(--foam-dim); font-size: .92rem; border-top: 1px solid var(--lagoon-700); margin-top: 12px; padding-top: 12px; }
.about h2 { font-size: 1.1rem; color: var(--foam); }

/* ---------- pages ---------- */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 8px 0; }
.tile { background: var(--lagoon-800); border-radius: 16px; padding: 14px; text-align: center; }
.tile b { display: block; font-family: var(--font-display); font-size: 1.8rem; color: var(--sun); }
.tile small { color: var(--foam-dim); }
.dist { margin-top: 10px; }
.dist-row { display: grid; grid-template-columns: 70px 1fr 36px; align-items: center; gap: 8px; font-weight: 600; }
.bar { height: 14px; background: var(--lagoon-900); border-radius: 8px; overflow: hidden; }
.bar i { display: block; height: 100%; min-width: 4px; background: linear-gradient(90deg, var(--reef), var(--sun)); border-radius: 8px; }
.dn { text-align: right; }
.dist-sub { margin: 2px 0 12px !important; }
.switch-row { display: flex; width: 100%; justify-content: space-between; align-items: center; gap: 12px; min-height: 64px; border: 0; background: transparent; text-align: left; padding: 6px 0; border-bottom: 1px solid var(--lagoon-700); }
.switch-row:last-child { border-bottom: 0; }
.switch-row b { display: block; }
.switch-row small { display: block; font-size: .85rem; }
.switch { flex: 0 0 52px; height: 30px; border-radius: 15px; background: var(--lagoon-700); position: relative; transition: background .2s; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%; background: var(--foam); transition: transform .2s var(--ease-pop); }
[aria-checked="true"] .switch { background: var(--reef); }
[aria-checked="true"] .switch::after { transform: translateX(22px); }

/* ---------- buttons, modals ---------- */
.btn { display: flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 18px; border-radius: var(--radius-pill); border: 0; background: var(--lagoon-700); color: var(--foam); font-weight: 600; text-decoration: none; width: 100%; }
.btn.primary { background: var(--sun); color: var(--ink-on-sun); }
.btn.ghost { background: transparent; color: var(--foam-dim); }
.btns { display: grid; gap: 8px; margin-top: 16px; }
.modal-back { position: fixed; inset: 0; background: rgba(2,12,13,.7); display: grid; place-items: center; padding: 16px; z-index: 20; opacity: 0; transition: opacity .2s; }
.modal-back.in { opacity: 1; }
.modal { width: 100%; max-width: 400px; max-height: calc(100vh - 32px); overflow: auto; background: var(--lagoon-800); border-radius: 24px; padding: 22px 20px; box-shadow: var(--shadow-lift); transform: translateY(16px) scale(.97); transition: transform .3s var(--ease-pop); }
.modal-back.in .modal { transform: none; }
.win { text-align: center; }
.win-cat { width: 72px; height: 72px; animation: bounce .7s var(--ease-pop) .1s both; }
.win h2 { font-size: 2rem; color: var(--sun); }
.win p { margin: 4px 0 0; }
.win-stats { display: flex; justify-content: center; gap: 10px; margin: 16px 0 0; }
.win-stats div { flex: 1; background: var(--lagoon-900); border-radius: 14px; padding: 10px 4px; }
.win-stats b { display: block; font-family: var(--font-display); font-size: 1.4rem; }
.win-stats small { color: var(--foam-dim); }
.share h2 { font-size: 1.4rem; text-align: center; }
.share-text { background: var(--lagoon-950); border-radius: 14px; padding: 14px; margin: 14px 0 6px; font: 600 1rem/1.5 var(--font-body); white-space: pre-wrap; user-select: text; }
.share-msg { min-height: 1.4em; text-align: center; margin: 10px 0 0; color: var(--reef); }
.confetti { position: fixed; inset: 0; z-index: 30; pointer-events: auto; }

/* ---------- tutorial + loading ---------- */
.coach { min-height: 112px; max-width: 520px; margin: 0 auto 10px; background: var(--lagoon-800); border: 2px solid var(--sun); border-radius: 16px; padding: 12px 14px; }
.coach-text { font-size: .98rem; }
.coach-btns { display: flex; gap: 8px; margin-top: 8px; }
.coach-btns:empty { display: none; }
.small-btn { min-height: 44px; width: auto; flex: 1; }
.coach-btns .btn:first-child { background: var(--sun); color: var(--ink-on-sun); }
.loading { display: grid; place-items: center; min-height: 60vh; text-align: center; }
.spin-cat { width: 56px; height: 56px; animation: bounce .9s ease-in-out infinite; }

/* LAN party R1 fixer A */
/* T7: level-2 hints show the cells the reason talks about (teal, dashed) apart from the target (solid gold). */
.hint-ctx::after { background: rgba(47,196,178,.22); box-shadow: inset 0 0 0 2px rgba(233,246,241,.85); outline: 2px dashed var(--reef); outline-offset: -6px; }
/* T4: every Hint press visibly answers: the target cells pulse and the hint bar pops in. */
.hint-pulse::after { animation: hintpulse .9s ease-out 2; }
@keyframes hintpulse { 0% { background: rgba(255,194,61,.75); transform: scale(1); } 50% { transform: scale(.88); } 100% { transform: scale(1); } }
.hintbar.show { animation: hintpop .35s var(--ease-pop); }
@keyframes hintpop { from { opacity: 0; transform: translateY(-6px) scale(.97); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .hint-pulse::after, .hintbar.show { animation: none !important; } }
/* T3: phone in landscape (wide and short): board on the left sized by height, everything else in a
   column beside it, so nothing scrolls. Must match WIDE_SHORT / SIDE_COL / LANDSCAPE_PAD in boardview.js. */
@media (orientation: landscape) and (max-height: 520px) {
  .screen.game { max-width: none; padding: 8px 12px; display: grid; grid-template-columns: auto minmax(0, 300px);
    grid-template-rows: repeat(5, min-content) 1fr; column-gap: 24px; justify-content: center; align-content: start; }
  .screen.game > * { grid-column: 2; }
  .screen.game > .board-wrap { grid-column: 1; grid-row: 1 / -1; align-self: start; }
  .screen.game .topbar { min-height: 48px; }
  .screen.game .modes { margin: 4px 0 8px; width: 100%; }
  .screen.game .controls { margin-top: 0; width: 100%; }
  .screen.game .ctl { min-height: 48px; }
  .screen.game .hintbar { margin-top: 8px; font-size: .88rem; padding: 8px 12px; }
  .screen.game .coach { min-height: 0; margin: 0 0 8px; padding: 8px 12px; }
  .screen.game .coach-text { font-size: .88rem; }
}

/* LAN party R1 fixer B */
/* T8: Skip is a real, easy-to-see button (>= 44x44). */
.topbar .skip.btn { width: auto; min-width: 64px; min-height: 44px; padding: 0 16px; border: 2px solid var(--foam-dim); background: var(--lagoon-800); color: var(--foam); font-weight: 700; text-decoration: none; }
/* T12: the cells the first cat rules out stay shaded through step 3 (separate from long-press reach). */
.coach-reach::after { background: rgba(10,20,30,.38); }
/* T9: close (x) on the win modal, and the button that brings the result back. */
.modal { position: relative; }
.modal-x { position: absolute; top: 8px; right: 8px; width: 44px; height: 44px; border: 0; border-radius: 50%; background: var(--lagoon-900); color: var(--foam); font-size: 1.6rem; line-height: 1; display: grid; place-items: center; padding-bottom: 3px; }
.result-btn { max-width: 520px; margin: 12px auto 0; }
/* T1: load error screen. */
.load-error { align-content: center; gap: 0; }
.load-error h2 { font-size: 1.3rem; margin: 8px 0 0; }
.load-error p { max-width: 300px; margin: 6px auto 0; }
.load-error .btns { width: min(280px, 100%); margin: 16px auto 0; }
.spin-cat.still { animation: none; opacity: .7; }
/* D-a: reveals line under the hint count. */
.win-stats small.reveals { display: block; color: var(--sun); font-size: .75rem; }
/* D-b: gold flame for a day with a no-hint daily solve. */
.fl { font-style: normal; }
.fl.gold { filter: sepia(1) saturate(5) hue-rotate(5deg) brightness(1.15) drop-shadow(0 0 4px rgba(255,194,61,.8)); }
/* D-d: first-launch card that opens the tutorial. */
.learn-card { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--foam); border: 2px solid var(--sun); }
.learn-card span:nth-child(2) { flex: 1; display: grid; }
.learn-card small { font-size: .85rem; }
.learn-cat { width: 40px; height: 40px; flex: 0 0 40px; }
.learn-go { font-size: 1.8rem; color: var(--sun); }
/* D-e: share legend. */
.share-legend { text-align: center; margin: 0 0 4px; }

/* LAN party R2 fixer D */
/* T19: X marks readable at ~30px cells: bigger on the dense boards, bolder, with a contrast halo on every tile colour. */
.tok.x { color: rgba(10,18,28,.82); filter: drop-shadow(0 0 1.5px rgba(255,255,255,.95)) drop-shadow(0 0 1px rgba(255,255,255,.9)); }
.board.dark .tok.x { color: rgba(255,255,255,.95); filter: drop-shadow(0 0 1.5px rgba(5,15,25,.95)) drop-shadow(0 0 1px rgba(5,15,25,.9)); }
.board.small .tok.x { width: 62%; height: 62%; }
/* T27: the tutorial's first target must be unmistakable: solid gold ring with a white inner edge, a pulsing glow and an expanding ping. */
.coach-hl { z-index: 2; }
.coach-hl::after {
  background: rgba(255,194,61,.28);
  box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 7px var(--sun), 0 0 14px 3px rgba(255,194,61,.9);
  animation: coachglow 1s ease-in-out infinite;
}
@keyframes coachglow {
  0%, 100% { background: rgba(255,194,61,.18); box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 7px var(--sun), 0 0 8px 2px rgba(255,194,61,.7); }
  50% { background: rgba(255,194,61,.5); box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 7px var(--sun), 0 0 22px 8px rgba(255,194,61,1); }
}
/* LAN party R2 fixer E */
/* T18: a clearly visible 48x48 close button; the glyph never takes the tap. */
.modal-x { width: 48px; height: 48px; top: 6px; right: 6px; background: var(--lagoon-700); border: 2px solid var(--foam-dim); font-size: 1.9rem; font-weight: 700; padding: 0 0 4px; z-index: 1; }
.modal-x span { pointer-events: none; }
.modal-x:hover, .modal-x:focus-visible { border-color: var(--sun); color: var(--sun); }
/* T20: the gold flame, explained in words. */
.gold-note { margin: 8px 0 0; text-align: center; font-size: .85rem; color: var(--sun); }
.page .gold-note { margin: 12px 0; }
/* T21: "N hints" on a daily button may wrap on narrow phones. */
.diff .st { text-align: center; line-height: 1.2; }

/* LAN party R3 fixer F */
/* T32: quiet note below the board once a new daily is out; never moves the board. */
.newday { max-width: 520px; margin: 10px auto 0; padding: 8px 12px; border-radius: 12px; background: var(--lagoon-800); color: var(--foam-dim); font-size: .88rem; text-align: center; }
.newday .linkish { border: 0; background: none; padding: 0; color: var(--sun); font: inherit; font-weight: 700; text-decoration: underline; cursor: pointer; }

/* LAN party R4 fixer H */
/* T36: first-play guide under the controls (below the board, so the board never moves). */
.firstplay { max-width: 520px; margin: 12px auto 0; padding: 10px 14px; border-radius: 14px; background: var(--lagoon-800); border-left: 4px solid var(--reef); font-size: .95rem; }
.firstplay p { margin: 0; }
.firstplay .fp-cue { margin-top: 6px; color: var(--sun); font-weight: 600; }
.firstplay .fp-learn { display: inline-flex; align-items: center; min-height: 44px; margin-top: 2px; font-weight: 700; color: var(--reef); }
/* T38: confetti is decoration only; taps go straight to the win modal. */
.confetti { pointer-events: none; }
/* T40: no text under 14px at phone width; the ghost button looks like a button. */
.diff small, .diff .st, .topbar .title small, .win-stats small, .win-stats small.reveals, .tile small,
.gold-note, .switch-row small, .learn-card small, .ctl { font-size: .875rem; }
.btn.ghost { background: transparent; color: var(--foam); border: 2px solid rgba(233,246,241,.45); }
/* T41: phone landscape: a compact win sheet with buttons side by side, so every button fits. */
@media (orientation: landscape) and (max-height: 520px) {
  .modal-back { padding: 8px; }
  .modal { max-width: 560px; max-height: calc(100vh - 16px); padding: 12px 16px; }
  .win-cat { width: 40px; height: 40px; }
  .win h2 { font-size: 1.5rem; }
  .win-stats { margin-top: 8px; }
  .win-stats div { padding: 6px 4px; }
  .win-stats b { font-size: 1.2rem; }
  .win .countdown { margin-top: 6px; }
  .win .btns { grid-template-columns: repeat(3, 1fr); margin-top: 10px; }
  .win .btns .btn { min-height: 44px; padding: 0 10px; }
}

/* Design calls ruled 2026-10-23 (D-n, D-r, D-p, D-u) */
.best-line { margin: 12px 0 0; text-align: center; font-weight: 600; color: var(--sun); }
.session-line { margin: 6px 0 0; text-align: center; font-size: .9rem; }
.yday-card { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--foam); border: 2px solid var(--reef); }
.yday-card > span:first-child { flex: 1; display: grid; }
.yday-card small { font-size: .88rem; }
.pattern-offer { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
.pattern-offer > span { flex: 1; font-weight: 600; }
.pattern-offer .small-btn { flex: 0 0 auto; padding: 0 14px; background: var(--reef); color: #032a26; }
.po-x { flex: 0 0 44px; height: 44px; border: 0; border-radius: 50%; background: transparent; color: var(--foam-dim); font-size: 1.6rem; line-height: 1; }

/* Bug hunt 2026-10-23 */
/* H3-2: with viewport-fit=cover, keep content clear of the notch / status bar and home indicator. */
.screen { padding-top: env(safe-area-inset-top, 0px); padding-bottom: calc(32px + env(safe-area-inset-bottom, 0px)); padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px)); }
.screen.game { padding-left: max(12px, env(safe-area-inset-left, 0px)); padding-right: max(12px, env(safe-area-inset-right, 0px)); padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
.modal-back { padding: max(16px, env(safe-area-inset-top, 0px)) 16px max(16px, env(safe-area-inset-bottom, 0px)); }
/* H3-4: no double-tap zoom on controls (iOS) */
button, a, .modes, .controls { touch-action: manipulation; }

/* Art hooks QC-007..014 (src/art.js adds the html class once a file exists; until then the emoji / glyph /
   token placeholder shows). */
.art-icon-hint .ctl[data-act="hint"] .ic, .art-icon-undo .ctl[data-act="undo"] .ic,
.art-icon-reset .ctl[data-act="reset"] .ic, .art-icon-check .ctl[data-act="check"] .ic {
  display: block; width: 26px; height: 26px; font-size: 0; color: transparent; background: center / contain no-repeat;
}
.art-icon-hint .ctl[data-act="hint"] .ic { background-image: url("./assets/art/icon-hint.png"); }
.art-icon-undo .ctl[data-act="undo"] .ic { background-image: url("./assets/art/icon-undo.png"); }
.art-icon-reset .ctl[data-act="reset"] .ic { background-image: url("./assets/art/icon-reset.png"); }
.art-icon-check .ctl[data-act="check"] .ic { background-image: url("./assets/art/icon-check.png"); }
.art-flame .fl:not(.gold), .art-flame-gold .fl.gold {
  display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.2em; font-size: inherit; color: transparent;
  filter: none; background: center / contain no-repeat; overflow: hidden; text-indent: -9em;
}
.art-flame .fl:not(.gold) { background-image: url("./assets/art/flame.png"); }
.art-flame-gold .fl.gold { background-image: url("./assets/art/flame-gold.png"); }
.art-cat-celebrate .win-cat { background: url("./assets/art/cat-celebrate.png") center / contain no-repeat; }
.art-cat-celebrate .win-cat use { display: none; }
.art-cat-sleepy .spin-cat { background: url("./assets/art/cat-sleepy.png") center / contain no-repeat; animation: none; filter: none; }
.art-cat-sleepy .spin-cat use { display: none; }

/* Finish Cup J2: placing a cat feels like something. A 120ms squash-pop as it lands, a soft gold glow
   sweeping a row / column / territory the moment it is finished, a hop from the cat that finished it,
   and a sideways shake on cats that break a rule (the rule is named in the bar under the board). */
.pop .tok.cat { animation: catpop .26s cubic-bezier(.2,.9,.3,1.25); transform-origin: 50% 85%; }
@keyframes catpop {
  0% { transform: scale(.35, .35); }
  45% { transform: scale(1.18, .84); }    /* 120ms: squash as it lands */
  75% { transform: scale(.94, 1.08); }
  100% { transform: scale(1, 1); }
}
.cell.line-glow::after { animation: lineglow .75s ease-out; }
.cell.line-glow .tok.cat { z-index: 2; }   /* the cat stays bright above its own glow */
@keyframes lineglow {
  0% { background: rgba(255,230,140,0); box-shadow: inset 0 0 0 0 rgba(255,214,90,0); }
  25%, 40% { background: rgba(255,246,196,.66); box-shadow: inset 0 0 0 4px #ffc23d, inset 0 0 14px rgba(255,194,61,.9); }
  100% { background: rgba(255,230,140,0); box-shadow: inset 0 0 0 0 rgba(255,214,90,0); }
}
.cell.shake { animation: cellshake .38s ease-in-out; z-index: 1; }
@keyframes cellshake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-12%); } 40% { transform: translateX(10%); }
  60% { transform: translateX(-7%); } 80% { transform: translateX(4%); }
}
.conflict::after { background: repeating-linear-gradient(-45deg, rgba(255,40,70,.5) 0 6px, rgba(255,40,70,.28) 6px 12px); box-shadow: inset 0 0 0 3px #ff2846; }
.cell.bounce .tok.cat { animation: bounce .55s var(--ease-pop); transform-origin: 50% 85%; }   /* wins over .pop above */
@media (prefers-reduced-motion: reduce) { .cell.shake, .cell.line-glow::after, .pop .tok.cat { animation: none !important; } }

/* Finish Cup: the first-play Goal card fits under the controls at 390x664 (Judge: it was cut off), and
   gives way to the hint bar while a hint or a broken rule is showing. */
.firstplay { display: flex; align-items: center; gap: 10px; margin-top: 10px; padding: 8px 8px 8px 12px; font-size: .9rem; line-height: 1.35; }
.firstplay .fp-text { flex: 1; min-width: 0; }
.firstplay .fp-cue { margin-top: 4px; }
.firstplay .fp-learn { flex: none; margin: 0; padding: 0 14px; border-radius: 12px; background: var(--lagoon-900); white-space: nowrap; text-decoration: none; }
.hintbar.show + .firstplay { display: none; }

/* Finish Cup J3: Unlimited has a goal. The clock glows gold while you are ahead of your best; a new best
   makes the win cat cheer (a bigger jump with a spin) instead of the usual bounce. */
.timer.ahead { color: var(--sun); text-shadow: 0 0 10px rgba(255,194,61,.55); }
.unl-run { color: var(--sun); }
.win-cat.cheer { animation: cheer 1.1s var(--ease-pop) .1s both; }
@keyframes cheer {
  0% { transform: scale(.4); } 30% { transform: translateY(-34%) scale(1.15) rotate(-10deg); }
  55% { transform: translateY(0) scale(1, .9); } 70% { transform: translateY(-14%) rotate(8deg); } 100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) { .win-cat.cheer { animation: none; } }

/* Finish Cup: mode chips read at a glance (Judge: the tiny cat glyph was unclear): bigger icons, plain words. */
.modes .mini { width: 26px; height: 26px; }
.modes button { gap: 6px; font-size: .95rem; }
.modes .arrow { font-size: .8rem; opacity: .8; font-weight: 600; }

/* Paws & Plots wordmark (rename 2026-10-24): candy-gold styled text. It is the fallback when the logo image
   can't load, and tools/render-placeholders.mjs renders the placeholder logo and social image from it. */
.wordmark { font-family: var(--font-display); font-weight: 700; letter-spacing: .01em; white-space: nowrap;
  background: linear-gradient(180deg, #fff1a8 0%, #ffd23f 38%, #ffad1f 72%, #f2861a 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  -webkit-text-stroke: .045em #5b2c00; paint-order: stroke fill;
  filter: drop-shadow(0 .06em 0 #3d1d00) drop-shadow(0 .12em .18em rgba(0,0,0,.35)); }
.wordmark .amp { background: linear-gradient(180deg, #ffb0b8, #ff5e6c 70%, #e2404f); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero h1.wordmark { font-size: clamp(2.7rem, 14vw, 3.8rem); text-shadow: none; color: transparent; }

/* Round 2 note 3: the tap-mode strip reads plainly (white words, 22px glyphs), and on short phones
   (375x553) the header and strip are trimmed so the game screen never scrolls. */
.modes button { color: var(--foam); opacity: .72; font-size: 1rem; font-weight: 700; gap: 5px; }
.modes button[aria-pressed="true"] { opacity: 1; }
.modes .mini { width: 22px; height: 22px; flex: none; }
.modes .arrow { font-size: 1rem; opacity: 1; }
@media (max-height: 600px) and (orientation: portrait) {
  .screen.game .topbar { min-height: 46px; }
  .screen.game .modes { margin: 2px auto 6px; }
  .screen.game .ctl { min-height: 50px; }
}
@media (max-height: 600px) and (orientation: portrait) {
  .screen.game { padding-bottom: max(8px, env(safe-area-inset-bottom)); }
  .screen.game .hintbar, .screen.game .firstplay { font-size: .85rem; line-height: 1.3; padding: 8px 12px; margin-top: 8px; }
  .screen.game .controls { margin-top: 8px; }
}

/* Round 2 note 1: cats react. The other cats squish when a line is finished, clashing cats jump in a
   startle, and the Medium / Hard finale is a bigger cheer, one cat after another. */
.cell.squish .tok.cat { animation: squish .42s cubic-bezier(.3,.9,.3,1.2); transform-origin: 50% 90%; }
@keyframes squish { 0%,100% { transform: none; } 35% { transform: scale(1.12, .82); } 65% { transform: scale(.94, 1.1); } }
.cell.startle .tok.cat { animation: startle .45s cubic-bezier(.2,.9,.3,1.4); transform-origin: 50% 90%; }
@keyframes startle { 0% { transform: none; } 22% { transform: translateY(-22%) scale(1.14) rotate(-8deg); } 48% { transform: translateY(0) scale(.92, 1.06) rotate(6deg); } 72% { transform: rotate(-4deg); } 100% { transform: none; } }
.cell.cheer .tok.cat { animation: cellcheer .7s cubic-bezier(.2,.9,.3,1.3); transform-origin: 50% 90%; z-index: 2; }
@keyframes cellcheer { 0% { transform: none; } 30% { transform: translateY(-40%) scale(1.22) rotate(-10deg); } 55% { transform: translateY(0) scale(1.1, .86); } 75% { transform: translateY(-12%) rotate(6deg); } 100% { transform: none; } }
.best-line .old-best { opacity: .7; text-decoration-thickness: 2px; }
@media (prefers-reduced-motion: reduce) { .cell.squish .tok.cat, .cell.startle .tok.cat, .cell.cheer .tok.cat { animation: none !important; } }
/* B22: in landscape the board is sized by the screen height, so the portrait bottom padding made the page
   scroll 9px on big phones (746x428). */
@media (orientation: landscape) and (max-height: 520px) {
  .screen.game { padding-bottom: max(8px, env(safe-area-inset-bottom)); }
}

/* Standard copy (RULINGS 11): the one main button on Home, and "Up next" on the win screen. */
.play-free { display: flex; align-items: center; justify-content: center; min-height: 56px; margin: 0 0 14px; font-size: 1.25rem; text-decoration: none; }
.up-next { display: inline-flex; align-items: center; min-height: 44px; margin-top: 6px; color: var(--reef); font-weight: 600; text-decoration: none; }
.up-next b { margin-left: 4px; }

/* Leak audit: the streak line on the win card, and "Up next" with the goal first and another game second. */
.streak-note { margin: 4px 0 0; color: var(--sun); font-weight: 600; }
.up-next-goal { margin: 12px 0 0; font-size: 1.05rem; }
.up-next-goal b { color: var(--sun); }
.up-next { font-size: .9rem; font-weight: 500; color: var(--foam-dim); }
.up-next b { color: var(--reef); }

/* Account restore toast (SDK 1.4) and the challenge line on the win card. */
.toast { position: fixed; left: 16px; right: 16px; bottom: max(20px, env(safe-area-inset-bottom)); margin: 0 auto; width: fit-content; z-index: 50; max-width: 420px; text-align: center; padding: 12px 18px; border-radius: 14px; background: var(--lagoon-800); color: var(--foam); box-shadow: var(--shadow-lift); border-left: 4px solid var(--reef); font-weight: 600; transition: opacity .4s; }
.toast.out { opacity: 0; }
.feedback-btn { margin-top: 10px; width: 100%; }
