@font-face {
  font-family: "Space Grotesk";
  src: url("fonts/space-grotesk.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}

/* The whole skin. A new skin is another set of these variables. */
:root {
  color-scheme: light dark;

  /* Youlius palette (Youlius/brand/source/palette.json) */
  --paper: oklch(0.949 0.007 88.6);
  --paper-2: oklch(0.916 0.010 87.5);
  --white: oklch(1 0 0);
  --lum-100: oklch(0.945 0.028 252.2);
  --lum-200: oklch(0.89 0.055 254.4);
  --lum-300: oklch(0.80 0.10 256.6);
  --lum-400: oklch(0.68 0.16 258.8);
  --lum-500: oklch(0.56 0.20 261);
  --lum-600: oklch(0.45 0.215 263.2);
  --lum-700: oklch(0.38 0.19 265.4);
  --lum-800: oklch(0.31 0.15 267.6);
  --lum-900: oklch(0.24 0.11 269.8);
  --lum-950: oklch(0.17 0.07 272);
  --danger: oklch(0.60 0.19 25);

  /* Roles: light-dark(light theme, dark theme) */
  --bg: light-dark(var(--paper), var(--lum-950));
  --text: light-dark(var(--lum-950), var(--lum-100));
  --muted: light-dark(var(--lum-700), var(--lum-300));
  --line: light-dark(var(--paper-2), var(--lum-900));
  --cell: light-dark(var(--paper-2), var(--lum-800));
  --cell-text: light-dark(var(--lum-900), var(--lum-100));
  --done: light-dark(var(--lum-600), var(--lum-500));
  --done-text: var(--white);
  --wrong: var(--danger);
  --focus: light-dark(var(--lum-600), var(--lum-300));
  --shine: light-dark(var(--lum-300), var(--white));     /* the glint on "tiny" */
  --surface: light-dark(var(--white), var(--lum-900));   /* tiles on the page */
  --inset: light-dark(var(--paper-2), var(--lum-800));   /* things inside a tile */
  --done-hover: light-dark(var(--lum-700), var(--lum-400));
  --key-top: light-dark(oklch(0.985 0.004 91.4), var(--paper-2));         /* logo: numpad keys */
  --key-base: light-dark(oklch(0.835 0.021 84.6), oklch(0.752 0.022 86));
  --key-ink: var(--lum-600);
  --key1-top: var(--lum-500);
  --key1-base: light-dark(var(--lum-700), var(--lum-800));

  /* Type and shape */
  --font: "Space Grotesk", system-ui, sans-serif;
  --font-text: system-ui, sans-serif;
  --r-cell: 8px;
  --r-tile: 16px;
  --gap: 5px;
}

/* The theme switch pins one side of light-dark(); without it the system decides. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

* { box-sizing: border-box; }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.5 var(--font-text);
}

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Game window: always fits the first screen, from ~220 px up to full screen. */
.game {
  --pad: clamp(0px, 5vmin - 10px, 32px);
  --max: 680px;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: var(--pad);
}

.window {
  width: min(100%, (100svh - 2 * var(--pad)) * .85, var(--max));
  padding: var(--gap);
  container-type: inline-size;
  font-family: var(--font);
  font-weight: 500;
}

/* Bar above the board: logo (menu) or back button, name, Next, time, restart (game), theme (menu) */
.topbar {
  display: flex;
  align-items: center;
  gap: .55em;
  padding-bottom: var(--gap);
  font-size: clamp(11px, 4.4cqw, 21px);
  line-height: 1;
  white-space: nowrap;
}
.name { margin-right: auto; font-weight: 600; letter-spacing: -.01em; }
.time { min-width: 4em; text-align: right; font-variant-numeric: tabular-nums; }

.mark, .icon-btn { flex: none; width: 2em; height: 2em; border-radius: var(--r-cell); }
.mark .base { fill: var(--key-base); }
.mark .top { fill: var(--key-top); }
.mark .digit { fill: var(--key-ink); }
.mark .key1 .base { fill: var(--key1-base); }
.mark .key1 .top { fill: var(--key1-top); }
.mark .key1 .digit { fill: var(--white); }

.icon-btn {
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: var(--cell);
  color: var(--cell-text);
  font: inherit;
  cursor: pointer;
  transition: background-color 120ms ease-out, color 120ms ease-out;
}
.icon-btn:hover { background: var(--done); color: var(--done-text); }
.icon-btn.back { background: var(--done); color: var(--done-text); }
.icon-btn.back:hover { background: var(--done-hover); }
.icon-btn svg { width: 1.15em; height: 1.15em; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.window[data-state="home"] :is(.back, .next, .time, #restart) { display: none; }
.window:not([data-state="home"]) :is(.mark, #theme, #popout) { display: none; }
.icon-btn[hidden] { display: none; }
#popout .fill { fill: currentColor; stroke: none; }
.window:is([data-state="done"], [data-state="share"]) :is(#restart, .next, .time) { display: none; } /* the result shows the time */

/* Logo: hovering the logo or the name presses the keys 1 to 4 in turn, like playing a board. */
@keyframes key-press { 0%, 30%, 100% { transform: none; } 10% { transform: translateY(3px); } }
@keyframes key-lit { 0%, 30%, 100% { fill: var(--key-top); } 10% { fill: var(--key1-top); } }
@keyframes key-ink { 0%, 30%, 100% { fill: var(--key-ink); } 10% { fill: var(--white); } }
@keyframes key-hold { 0% { fill: var(--key-top); } 6%, 62% { fill: var(--key1-top); } 70%, 100% { fill: var(--key-top); } }
@keyframes key-hold-ink { 0% { fill: var(--key-ink); } 6%, 62% { fill: var(--white); } 70%, 100% { fill: var(--key-ink); } }
@media (hover: hover) {
  .topbar:has(:is(.mark, .name):hover) .cap { animation: key-press 1.4s calc(var(--k) * 180ms) infinite; }
  .topbar:has(:is(.mark, .name):hover) .key .top { animation: key-lit 1.4s calc(var(--k) * 180ms) infinite; }
  .topbar:has(:is(.mark, .name):hover) .key .digit { animation: key-ink 1.4s calc(var(--k) * 180ms) infinite; }
}

/* Theme switch: in the dark theme the moon slides its shadow away and becomes a sun. */
#theme .core { fill: currentColor; stroke: none; transition: r 450ms ease; }
#theme .bite { transition: cx 450ms cubic-bezier(.34, 1.3, .64, 1), cy 450ms cubic-bezier(.34, 1.3, .64, 1); }
#theme .rays { stroke-width: 2; opacity: 0; transform: scale(.3) rotate(-60deg); transform-origin: 12px 12px; transition: opacity 300ms ease-out, transform 450ms cubic-bezier(.34, 1.4, .64, 1); }
:root[data-theme="dark"] #theme .bite { cx: 30px; cy: -6px; }
:root[data-theme="dark"] #theme .core { r: 5px; }
:root[data-theme="dark"] #theme .rays { opacity: 1; transform: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #theme .bite { cx: 30px; cy: -6px; }
  :root:not([data-theme="light"]) #theme .core { r: 5px; }
  :root:not([data-theme="light"]) #theme .rays { opacity: 1; transform: none; }
}

.muted { color: var(--muted); }

.board { position: relative; }
[data-state="paused"] .board { cursor: pointer; }
.window:not([data-state="play"]) .grid { visibility: hidden; }

.grid {
  --n: 5;
  display: grid;
  grid-template-columns: repeat(var(--n), 1fr);
  grid-template-rows: repeat(var(--n), 1fr);
  gap: var(--gap);
  aspect-ratio: 1;
  user-select: none;
  -webkit-user-select: none;
}

.cell {
  display: grid;
  place-items: center;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-cell);
  background: var(--cell);
  color: var(--cell-text);
  font: inherit;
  font-size: calc(40cqw / var(--n));
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform 80ms ease-out, background-color 160ms ease-out, color 160ms ease-out;
}
.cell:active { transform: scale(.96); }
.cell.done { background: var(--done); color: var(--done-text); cursor: default; }
.cell.done:active { transform: none; }
.cell.wrong { background: var(--wrong); color: var(--white); transition: none; }

/* Menu, result and share screens sit on top of the board square. */
.panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3cqw;
  background: var(--bg);
  text-align: center;
}
.panel[hidden] { display: none; }
.panel p { margin: 0; }
.small { font-size: clamp(11px, 4.6cqw, 20px); }
.r-time { font-size: 15cqw; line-height: 1; }

.card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .8em;
  width: min(100%, 80cqw);
  padding: .85em 1em;
  border: 0;
  border-radius: var(--r-cell);
  background: var(--cell);
  color: var(--cell-text);
  font: inherit;
  font-size: clamp(12px, 5.6cqw, 26px);
  line-height: 1.1;
  text-align: left;
  cursor: pointer;
  transition: color 200ms ease-out 60ms, transform 120ms ease-out;
}
.card.primary { --sweep: light-dark(var(--lum-900), var(--lum-700)); background: var(--done); color: var(--done-text); }
.card:not(.primary) { --sweep: var(--done); }
.card-text { display: flex; flex-direction: column; gap: .35em; min-width: 0; }
.card-sub { overflow: hidden; font-size: .72em; font-variant-numeric: tabular-nums; white-space: nowrap; text-overflow: ellipsis; opacity: .8; }
.card.primary .card-sub, .card.lit .card-sub { opacity: 1; } /* white on blue needs full strength for contrast */
.card:active { transform: scale(.98); }

/* Hover or keyboard focus lights the card (.lit, set in app.js): colour fills it in a wave
   of small tiles while a clock runs in the subtitle, ending in "your turn". */
.card.lit { --lit: 1; }
.card:not(.primary).lit { color: var(--done-text); }
.tiles {
  position: absolute;
  inset: 0;
  z-index: -1;
  display: grid;
  grid-template-columns: repeat(16, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
.tiles span {
  border-radius: 2px;
  background: var(--sweep);
  scale: calc(var(--lit, 0) * 1.08);
  transition: scale 280ms cubic-bezier(.34, 1.56, .64, 1);
  transition-delay: calc(var(--d) * 20ms);
}

.share-img {
  flex: 1 1 0;
  min-height: 0;
  max-width: 100%;
  aspect-ratio: 4 / 5;
  border: 1px solid var(--line);
  border-radius: var(--r-cell);
}

.row { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--gap); }
.btn {
  padding: .55em 1em;
  border: 0;
  border-radius: var(--r-cell);
  background: var(--cell);
  color: var(--cell-text);
  font: inherit;
  font-size: clamp(11px, 4.6cqw, 20px);
  line-height: 1.1;
  cursor: pointer;
}
.btn.primary { background: var(--done); color: var(--done-text); }
.btn:disabled { opacity: .5; cursor: default; }
a.btn { display: inline-block; text-decoration: none; }
/* Size picker: a keycap like the logo's rides a rail and clicks into 3×3, 4×4 or 5×5;
   inside it the blocks reflow into the new board. */
.sizes { --t: 3.2em; display: grid; gap: .45em; width: 12em; font-size: clamp(11px, 4.6cqw, 20px); }
.slider { --pos: 2; position: relative; height: var(--t); cursor: pointer; touch-action: none; }
.rail { position: absolute; left: calc(var(--t) / 2); right: calc(var(--t) / 2); top: calc(50% - .15em); height: .3em; border-radius: .15em; background: var(--cell); }
.notch {
  position: absolute;
  top: calc(50% - .3em);
  left: calc(var(--t) / 2 + var(--k) * (100% - var(--t)) / 2 - .3em);
  width: .6em;
  height: .6em;
  border-radius: 50%;
  background: var(--cell);
}
.thumb {
  position: absolute;
  top: 0;
  left: calc(var(--pos) * (100% - var(--t)) / 2);
  width: var(--t);
  height: var(--t);
  border-radius: .55em;
  background: var(--key1-base);
  pointer-events: none;
  transition: left 500ms cubic-bezier(.34, 1.5, .64, 1);
}
.thumb-top { position: absolute; inset: 0 0 .22em; border-radius: .5em; background: var(--key1-top); transition: translate 120ms ease-out; }
.thumb-board { position: absolute; inset: 20%; }
.thumb-board i {
  position: absolute;
  border-radius: 2px;
  background: var(--white);
  transition: left 450ms cubic-bezier(.34, 1.3, .64, 1), top 450ms cubic-bezier(.34, 1.3, .64, 1),
    width 450ms cubic-bezier(.34, 1.3, .64, 1), height 450ms cubic-bezier(.34, 1.3, .64, 1), opacity 300ms ease-out;
}
.thumb-board i:first-child { background: var(--lum-200); }
@media (hover: hover) { .slider:hover .thumb-top { translate: 0 -.08em; } }
.slider:active .thumb-top { translate: 0 .12em; }
.ticks { display: grid; grid-template-columns: var(--t) 1fr var(--t); }
.ticks .sz { padding: .25em 0; border: 0; border-radius: 6px; background: none; color: var(--muted); font: 600 .62em/1.2 var(--font); opacity: .75; cursor: pointer; transition: opacity 300ms ease-out; }
.ticks .sz[aria-pressed="true"] { color: var(--text); opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .cell, .card { transition: none; }
  .cell:active, .card:active { transform: none; }
  /* Nothing moves: the tile wave fades in instead of growing. */
  .tiles span { scale: 1.08; opacity: var(--lit, 0); transition: opacity 160ms linear; transition-delay: calc(var(--d) * 20ms); }
  .thumb, .thumb-top, .thumb-board i { transition: none; }
  .more svg { animation: none; }
  #theme .core, #theme .bite, #theme .rays { transition: none; }
  .topbar:has(:is(.mark, .name):hover) .cap { animation: none; }
  .topbar:has(:is(.mark, .name):hover) .key .top { animation: key-hold 1.8s calc(var(--k) * 200ms) infinite; }
  .topbar:has(:is(.mark, .name):hover) .key .digit { animation: key-hold-ink 1.8s calc(var(--k) * 200ms) infinite; }
}

/* Page below the game: a small arrow at the bottom of the first screen hints at it. */
.more {
  position: absolute;
  bottom: 10px;
  left: 50%;
  translate: -50% 0;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--muted);
}
.more:hover { color: var(--text); background: var(--cell); }
.more svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; animation: bob 1.8s ease-in-out infinite; }
@keyframes bob { 0%, 100% { transform: none; } 50% { transform: translateY(4px); } }
@media (max-height: 560px) { .more { display: none; } }

a { color: var(--focus); }

.page { max-width: 1040px; margin: 0 auto; padding: clamp(40px, 7vw, 88px) 16px 24px; }
.intro { max-width: 44rem; margin: 0 auto clamp(32px, 5vw, 56px); text-align: center; }
.eyebrow {
  margin: 0 0 .9rem;
  color: var(--muted);
  font: 500 .78rem/1 var(--font);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.intro h1 {
  margin: 0;
  font: 500 clamp(2.2rem, 6.4vw, 4.2rem)/1.02 var(--font);
  letter-spacing: -.035em;
  text-wrap: balance;
}
/* "tiny" catches the light as the page scrolls past it. */
.intro em {
  font-style: normal;
  color: var(--focus);
  background: linear-gradient(100deg, var(--focus) 38%, var(--shine) 50%, var(--focus) 62%) 130% 0 / 300% 100% no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@supports (animation-timeline: view()) {
  .intro em { animation: shine linear both; animation-timeline: view(); animation-range: entry 20% cover 60%; }
  @media (prefers-reduced-motion: reduce) { .intro em { animation-name: glow; } }
}
@keyframes shine { from { background-position: 130% 0; } to { background-position: -30% 0; } }
@keyframes glow { 0%, 100% { -webkit-text-fill-color: var(--focus); } 50% { -webkit-text-fill-color: var(--shine); } }
.lede {
  max-width: 32rem;
  margin: 1.2rem auto 0;
  color: var(--muted);
  font-size: clamp(1rem, 1.7vw, 1.2rem);
  text-wrap: pretty;
}

/* Bento grid of tiles */
.bento { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 12px; }
.tile {
  --cell: var(--inset); /* cells, chips and keys sit one step off the tile */
  grid-column: span 12;
  display: flex;
  flex-direction: column;
  gap: .7rem;
  min-width: 0;
  padding: clamp(18px, 2.6vw, 28px);
  border-radius: var(--r-tile);
  background: var(--surface);
}
.tile h2 { margin: 0; font: 500 1.3rem/1.15 var(--font); letter-spacing: -.01em; }
.tile p, .tile .eyebrow { margin: 0; }
.tile .btn { font-size: .95rem; }
@media (min-width: 820px) {
  .try { grid-column: span 6; grid-row: span 2; }
  .today, .keys { grid-column: span 6; }
}

.mini { --n: 3; width: min(100%, 280px); margin: .4rem auto 0; container-type: inline-size; font: 500 1rem/1 var(--font); }
.mini-status { min-height: 1.4em; text-align: center; color: var(--muted); font: 500 .95rem/1.4 var(--font); }
.try-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.try-head .muted { margin-top: .3rem; }
.try-clock { flex: none; font: 500 clamp(1.6rem, 3vw, 2.2rem)/1 var(--font); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.steps { display: flex; justify-content: center; gap: 4px; margin: .3rem 0 0; padding: 0; list-style: none; }
.steps li {
  display: grid;
  place-items: center;
  flex: 0 1 1.9rem;
  min-width: 0;
  aspect-ratio: 1;
  border-radius: 6px;
  background: var(--cell);
  color: var(--muted);
  font: 500 .8rem/1 var(--font);
  transition: background-color 160ms ease-out, color 160ms ease-out;
}
.steps li.found { background: var(--done); color: var(--done-text); }
.steps li.next { outline: 2px solid var(--focus); outline-offset: -2px; color: var(--text); }
/* A finished board takes a little bow, cell by cell in the order they were found. */
.mini.win .cell { animation: bow 420ms cubic-bezier(.34, 1.8, .64, 1) calc(var(--o) * 45ms) both; }
@keyframes bow { 40% { transform: scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .mini.win .cell { animation: none; } }
.try .row[hidden] { display: none; }

.today h2 { font-size: clamp(2rem, 4vw, 2.8rem); letter-spacing: -.03em; }
.pills { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.pill {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .3em;
  padding: .8em .9em;
  border: 0;
  border-radius: var(--r-cell);
  background: var(--cell);
  color: var(--cell-text);
  font: 500 1rem/1.1 var(--font);
  text-align: left;
  cursor: pointer;
}
.pill small { color: var(--muted); font-size: .82em; }
.pill.done { background: var(--done); color: var(--done-text); }
.pill.done small { color: inherit; opacity: .85; }

.recs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.rec { display: flex; flex-direction: column; gap: .2rem; padding: clamp(12px, 2vw, 18px); border-radius: var(--r-cell); background: var(--cell); }
.rec-icon { display: grid; grid-template-columns: repeat(var(--n), 1fr); gap: 2px; width: 26px; aspect-ratio: 1; margin-bottom: .5rem; }
.rec-icon i { border-radius: 2px; background: var(--muted); opacity: .3; }
.rec-icon i:first-child { background: var(--done); opacity: 1; }
.rec-size { color: var(--muted); font: 500 .9rem/1.2 var(--font); }
.rec-best { font: 500 clamp(1.1rem, 4.6vw, 2.2rem)/1.05 var(--font); letter-spacing: -.02em; white-space: nowrap; }
.rec-games { color: var(--muted); font-size: .85rem; }

.keymap { display: grid; gap: .7rem; margin: 0; padding: 0; list-style: none; }
.keymap li { display: grid; grid-template-columns: 8.6rem minmax(0, 1fr); align-items: center; gap: .4rem .9rem; }
.keymap li > span { display: flex; gap: 4px; }
@media (max-width: 340px) { .keymap li { grid-template-columns: minmax(0, 1fr); } }
kbd {
  display: inline-grid;
  place-items: center;
  min-width: 2.1em;
  height: 2.1em;
  padding: 0 .55em;
  border-radius: 6px;
  background: var(--cell);
  color: var(--text);
  font: 500 .85rem/1 var(--font);
}

.foot { padding: 24px 16px 44px; color: var(--muted); font: 500 .95rem var(--font); text-align: center; }
.foot a { color: var(--text); font-weight: 650; text-decoration: none; }
.foot a:hover { color: var(--focus); }

/* Privacy page */
.doc { max-width: 40rem; margin: 0 auto; padding: clamp(32px, 6vw, 72px) 16px 16px; }
.doc-home { display: inline-flex; align-items: center; gap: .5em; color: var(--text); font: 600 1.05rem/1 var(--font); text-decoration: none; }
.doc h1 { margin: 2rem 0 .6rem; font: 500 clamp(2.2rem, 6vw, 3.2rem)/1.05 var(--font); letter-spacing: -.03em; }
.doc .lede { margin: 0; max-width: none; }
.doc h2 { margin: 2.2rem 0 .4rem; font: 500 1.2rem/1.2 var(--font); }
.doc p, .doc ul { margin: 0 0 .8rem; }
.doc ul { padding-left: 1.2rem; }
.doc li { margin: .2rem 0; }

/* 404 page */
.lost-number { margin: 2.5rem 0 0; color: var(--focus); font: 500 clamp(4rem, 14vw, 7rem)/1 var(--font); letter-spacing: -.04em; }
.lost h1 { margin-top: .6rem; }
.doc .btn { margin-top: 1rem; padding: .75em 1.4em; font-size: 1rem; }

/* While the game is popped out, the page keeps a note where it was. */
.popped { display: grid; justify-items: center; gap: .9rem; text-align: center; color: var(--muted); font: 500 1rem/1.4 var(--font); }
.popped[hidden] { display: none; }
.popped p { margin: 0; }

/* Pop-out window (Document Picture-in-Picture): the game alone, edge to edge. */
.pip { --pad: 0px; --max: 100%; margin: 0; min-height: 100svh; display: grid; place-items: center; }
.pip #popout { display: none; }

.get { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 1.6rem; }
.get .btn { padding: .75em 1.4em; font-size: 1rem; }
.store[hidden] { display: none; }

/* Installed app and pop-out window: just the game, edge to edge */
@media (display-mode: standalone), (display-mode: picture-in-picture) {
  .page, .foot, .more { display: none; }
  .game { --pad: 0px; --max: 100%; }
}
