/* ============================================================
   Equanimity Labo — "arcade sky"
   Cream letter tiles tumbling through a violet-to-pink sky with
   confetti, sunny yellow buttons, bright card-suit accents.
   (Deliberately not green + gold: that reads as a casino.)
   Mobile-first, light + dark.
   ============================================================ */

@font-face {
  font-family: "Fredoka";
  src: url("/fonts/Fredoka-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Fredoka";
  src: url("/fonts/Fredoka-SemiBold.ttf") format("truetype");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Mono";
  src: url("/fonts/AtkinsonHyperlegibleMono-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}

:root {
  --paper: #FBF9FF;
  --paper-2: #F1EDFB;
  --card: #FFFFFF;
  --ink: #1E1B3A;
  --ink-2: #5A5680;
  --line: #E3DEF5;

  --sky: #4B3BD1;
  --sky-2: #7046DF;
  --sky-3: #A940BD;
  --sky-ink: #FFFFFF;
  --sky-ink-2: #F3F0FF;
  --sky-gradient: linear-gradient(155deg, var(--sky) 0%, var(--sky-2) 55%, var(--sky-3) 100%);

  --mint: #5EE0C0;
  --bubble: #7FD3FF;

  --tile: #F7EBD3;
  --tile-hi: #FFF7E6;
  --tile-edge: #C9B084;
  --tile-ink: #231F1A;

  --sun: #FFCE3A;
  --sun-edge: #D69E00;
  --heart: #F0506E;
  --heart-text: #D42A4F;
  --spade: #3D7BFF;
  --club: #18B87A;
  --club-text: #0B7A50;

  --store-bg: #1A1714;
  --store-fg: #FFFFFF;
  --store-edge: #000000;
  /* Text on a game's pale tinted panel (game hero). */
  --on-tint: #231F1A;
  --chip-bg: rgb(255 255 255 / 0.6);
  /* How strongly a game's accent glows on its tinted panels. */
  --tint-glow: 22%;
  /* Behind a game while it loads. */
  --frame-bg: #FAF6EE;

  --radius: 20px;
  --shadow: 0 1px 0 rgb(30 27 58 / 0.04), 0 14px 34px -16px rgb(60 40 160 / 0.35);
  --shadow-lift: 0 1px 0 rgb(35 31 26 / 0.04), 0 26px 44px -18px rgb(35 31 26 / 0.45);
  --font-display: "Fredoka", ui-rounded, "Arial Rounded MT Bold", system-ui, sans-serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --font-tile: "Atkinson Mono", ui-monospace, "SFMono-Regular", monospace;

  --accent: var(--sky-2);
  --accent-soft: #EFE9FF;
  --accent-ink: #3A2B9E;

  color-scheme: light dark;
}
:root[data-theme="light"] { color-scheme: light; }

/* Dark: when the device asks for it (unless the visitor picked light), or when
   the visitor picked dark. site.js stores the choice; an inline <head> script
   (src/layout.mjs) sets data-theme before first paint. KEEP THE TWO DARK BLOCKS
   IDENTICAL.

   Game pages override --accent / --accent-soft / --accent-ink inline, so a
   colour derived from them can't be a :root token: it would resolve against
   the root's accent, not the game's. Those spots read optional knobs at the
   point of use (--eyebrow, --chip-ink, --tint-*, --accent-text-*): dark sets
   them, light falls back to the default written there. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #110E22;
    --paper-2: #19152F;
    --card: #211C3D;
    --ink: #F3F0FF;
    --ink-2: #B7B1DA;
    --line: #342C5C;
    --sky: #3A2DB5;
    --sky-2: #6B42D6;
    --sky-3: #9A3DB0;
    --heart-text: #FF7A93;
    --club-text: #6FD19B;
    --store-bg: #F2EADB;
    --store-fg: #1A1714;
    --store-edge: #9E927F;
    --on-tint: var(--ink);
    --chip-bg: rgb(0 0 0 / 0.25);
    --tint-glow: 38%;
    --frame-bg: #111111;
    --shadow: 0 1px 0 rgb(0 0 0 / 0.3), 0 16px 36px -16px rgb(0 0 0 / 0.7);
    --shadow-lift: 0 1px 0 rgb(0 0 0 / 0.3), 0 26px 44px -18px rgb(0 0 0 / 0.8);
    --accent-soft: #2A2257;
    --accent-ink: #CFC4FF;
    --eyebrow: var(--sun);
    --chip-ink: var(--ink);
    --tint-mix: 16%;
    --tint-base: var(--paper);
    --tint-card: var(--card);
    --accent-text-mix: 70%;
    --accent-text-base: #FFFFFF;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #110E22;
  --paper-2: #19152F;
  --card: #211C3D;
  --ink: #F3F0FF;
  --ink-2: #B7B1DA;
  --line: #342C5C;
  --sky: #3A2DB5;
  --sky-2: #6B42D6;
  --sky-3: #9A3DB0;
  --heart-text: #FF7A93;
  --club-text: #6FD19B;
  --store-bg: #F2EADB;
  --store-fg: #1A1714;
  --store-edge: #9E927F;
  --on-tint: var(--ink);
  --chip-bg: rgb(0 0 0 / 0.25);
  --tint-glow: 38%;
  --frame-bg: #111111;
  --shadow: 0 1px 0 rgb(0 0 0 / 0.3), 0 16px 36px -16px rgb(0 0 0 / 0.7);
  --shadow-lift: 0 1px 0 rgb(0 0 0 / 0.3), 0 26px 44px -18px rgb(0 0 0 / 0.8);
  --accent-soft: #2A2257;
  --accent-ink: #CFC4FF;
  --eyebrow: var(--sun);
  --chip-ink: var(--ink);
  --tint-mix: 16%;
  --tint-base: var(--paper);
  --tint-card: var(--card);
  --accent-text-mix: 70%;
  --accent-text-base: #FFFFFF;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }

a { color: inherit; text-underline-offset: 0.18em; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em;
}
h1 { font-size: clamp(2.2rem, 7vw, 4rem); }
h2 { font-size: clamp(1.7rem, 4.5vw, 2.6rem); }
h3 { font-size: 1.25rem; }

p { margin: 0 0 1em; }

:focus-visible {
  outline: 3px solid var(--spade);
  outline-offset: 3px;
  border-radius: 6px;
}

.wrap {
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 16px;
}
@media (min-width: 720px) { .wrap { padding: 0 32px; } }
.narrow { max-width: 760px; }

.skip-link {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 10px;
}
.skip-link:focus { top: 12px; }

.eyebrow {
  font-family: var(--font-tile);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--eyebrow, var(--accent-ink));
  margin-bottom: 0.9em;
}

/* ---------- letter tiles ---------- */

.tile {
  --t: 48px;
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--t);
  height: var(--t);
  border-radius: calc(var(--t) * 0.18);
  background: linear-gradient(160deg, var(--tile-hi), var(--tile) 55%);
  box-shadow:
    0 calc(var(--t) * 0.09) 0 var(--tile-edge),
    0 calc(var(--t) * 0.2) calc(var(--t) * 0.3) rgb(0 0 0 / 0.28);
  color: var(--tile-ink);
  font-family: var(--font-display);
  font-weight: 700;
  user-select: none;
  flex: none;
}
.tile__letter { font-size: calc(var(--t) * 0.56); line-height: 1; transform: translateY(-4%); }
.tile__value {
  position: absolute;
  right: calc(var(--t) * 0.1);
  bottom: calc(var(--t) * 0.05);
  font-family: var(--font-tile);
  font-size: calc(var(--t) * 0.2);
  line-height: 1;
}
.tile--mini { --t: 30px; }
.logo-mark { width: 36px; height: 36px; flex: none; color: var(--ink); }
.site-footer__brand .logo-mark { width: 40px; height: 40px; }
.tile-gap { display: inline-block; width: 12px; }

/* ---------- header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: saturate(1.4) blur(12px);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 60px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}
.brand__name { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; }
.brand__name b { font-weight: 700; color: var(--heart-text); }
.site-nav { display: flex; align-items: center; gap: 4px; }
.site-nav a {
  font-family: var(--font-display);
  font-weight: 600;
  text-decoration: none;
  padding: 8px 12px;
  border-radius: 999px;
}
.site-nav a:hover { background: var(--paper-2); }
.brand__name, .site-nav a { white-space: nowrap; }

/* Light/dark toggle (site.js). Hidden until the script wires it up, so it
   never shows as a dead button. Shows the mode a tap switches to. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-left: 4px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  transition: background 120ms ease, rotate 300ms ease;
}
.theme-toggle[hidden] { display: none; }
.theme-toggle:hover { background: var(--paper-2); rotate: -15deg; }
.theme-toggle svg { width: 20px; height: 20px; }
.theme-toggle__sun { display: none; }
.theme-toggle[aria-pressed="true"] .theme-toggle__sun { display: block; }
.theme-toggle[aria-pressed="true"] .theme-toggle__moon { display: none; }

/* Footer: System / Light / Dark. */
.theme-picker { display: inline-flex; align-items: center; gap: 10px; border: 0; margin: 0; padding: 0; }
.theme-picker[hidden] { display: none; }
.theme-picker legend { float: left; margin-right: 10px; font-weight: 600; color: var(--ink-2); }
.theme-picker__options { display: inline-flex; padding: 3px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); }
.theme-picker button {
  padding: 5px 12px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink-2);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
.theme-picker button:hover { color: var(--ink); }
.theme-picker button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
@media (max-width: 480px) {
  .brand__name { font-size: 1rem; }
  .site-nav a { padding: 8px 10px; font-size: 0.95rem; }
}
/* Small phones: the logo already leads to the games. */
@media (max-width: 400px) {
  .site-nav a[href="/#games"] { display: none; }
}

/* ---------- buttons ---------- */

.btn {
  --btn-bg: var(--ink);
  --btn-fg: var(--paper);
  --btn-edge: #000;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  min-height: 52px;
  padding: 10px 22px;
  border-radius: 16px;
  border: 0;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.15;
  text-decoration: none;
  text-align: center;
  box-shadow: 0 5px 0 var(--btn-edge);
  transform: translateY(0);
  transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease;
  cursor: pointer;
}
.btn:hover { filter: brightness(1.06); transform: translateY(-2px); box-shadow: 0 7px 0 var(--btn-edge); }
.btn:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--btn-edge); }
.btn small { font-family: var(--font-body); font-weight: 500; font-size: 0.7rem; opacity: 0.8; letter-spacing: 0.02em; }

.btn--primary { --btn-bg: var(--sun); --btn-fg: #2A1D05; --btn-edge: var(--sun-edge); }
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--sky-ink);
  --btn-edge: transparent;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--sky-ink) 55%, transparent);
}
.btn--ghost:hover { box-shadow: inset 0 0 0 2px var(--sky-ink); }
.btn--ghost:active { box-shadow: inset 0 0 0 2px var(--sky-ink); }
.btn--play { --btn-bg: color-mix(in srgb, var(--accent) 80%, black); --btn-fg: #fff; --btn-edge: var(--accent-ink); }
.btn--store { --btn-bg: var(--store-bg); --btn-fg: var(--store-fg); --btn-edge: var(--store-edge); min-width: 150px; }

.store-buttons { display: flex; flex-wrap: wrap; gap: 12px 12px; margin-top: 8px; }
@media (max-width: 480px) { .store-buttons .btn { flex: 1 1 140px; } }

/* ---------- hero: the arcade sky ---------- */

.hero {
  position: relative;
  isolation: isolate;
  background: var(--sky-gradient);
  color: var(--sky-ink);
  overflow: hidden;
}
/* Confetti: a few bright dots and a pink glow, drifting slowly. */
.hero__sky {
  position: absolute;
  inset: -40px 0 0;
  z-index: -1;
  background:
    radial-gradient(circle at 8% 22%, var(--sun) 0 8px, transparent 9px),
    radial-gradient(circle at 18% 78%, var(--bubble) 0 6px, transparent 7px),
    radial-gradient(circle at 44% 12%, #fff 0 4px, transparent 5px),
    radial-gradient(circle at 52% 88%, var(--mint) 0 7px, transparent 8px),
    radial-gradient(circle at 70% 8%, var(--heart) 0 6px, transparent 7px),
    radial-gradient(circle at 92% 30%, var(--mint) 0 10px, transparent 11px),
    radial-gradient(circle at 86% 74%, var(--sun) 0 5px, transparent 6px),
    radial-gradient(circle at 34% 50%, rgb(255 255 255 / 0.5) 0 3px, transparent 4px),
    radial-gradient(70% 60% at 85% 15%, rgb(255 140 200 / 0.45), transparent 70%),
    radial-gradient(60% 70% at 5% 100%, rgb(127 211 255 / 0.35), transparent 70%);
  animation: confetti-drift 14s ease-in-out infinite alternate;
}
/* Soft curved edge into the page, instead of a hard band. */
.hero::after {
  content: "";
  position: absolute;
  left: -5%;
  right: -5%;
  bottom: -1px;
  height: 56px;
  background: var(--paper);
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
}
@keyframes confetti-drift {
  from { transform: translateY(0); }
  to { transform: translateY(24px); }
}
.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 36px;
  padding-top: 36px;
  padding-bottom: 64px;
  align-items: center;
}
@media (min-width: 960px) {
  .hero__inner { grid-template-columns: 1fr 1.05fr; padding-top: 64px; padding-bottom: 92px; }
}
/* Phones: the games come first. The tiles are a desktop flourish. */
@media (max-width: 719px) {
  .page-home .tile-stage { display: none; }
  .page-home .hero__title { font-size: clamp(2rem, 9vw, 2.6rem); }
}
.hero .eyebrow { color: var(--sun); }
.hero__title span { color: var(--sun); }
.hero__lead { color: var(--sky-ink-2); font-size: 1.15rem; max-width: 34em; }

.tile-stage {
  container-type: inline-size;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 8px 0;
}
.tile-row { display: flex; gap: clamp(4px, 1vw, 8px); justify-content: center; }
.tile-row--second { margin-left: clamp(40px, 12vw, 120px); }
.tile--hero {
  /* Ten tiles + gaps fill the stage's width ("EQUANIMITY" is the longest row). */
  --t: min(8.6cqi, 66px);
  cursor: pointer;
  animation: tile-drop 820ms cubic-bezier(0.25, 1.45, 0.45, 1) both;
  animation-delay: calc(var(--i, 0) * 70ms + 150ms);
  transition: translate 180ms ease, rotate 180ms ease;
}
.tile--hero:nth-child(odd) { rotate: -2deg; }
.tile--hero:nth-child(3n) { rotate: 3deg; }
/* `translate`/`rotate` are separate from `transform`, which the animations own. */
.tile--hero:hover { translate: 0 -8px; rotate: -4deg; }
/* site.js marks a tile landed once its drop ends, so a later flip can't replay the drop. */
.tile--hero.is-landed { animation: none; }
.tile--hero.is-landed.is-flipped { animation: tile-flip 700ms ease both; }
.tile--hero.is-flipped .tile__letter { font-size: calc(var(--t) * 0.66); }
.tile--hero[data-suit="♥"] .tile__letter,
.tile--hero[data-suit="♦"] .tile__letter { color: var(--heart); }
.tile-stage__hint {
  margin: 10px 0 0;
  font-family: var(--font-tile);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sky-ink-2);
  opacity: 0.7;
  animation: fade-in 600ms ease 1.6s both;
}
.notfound .tile--hero { --t: 64px; }

@keyframes tile-drop {
  0% { transform: translateY(-120vh) rotate(-24deg); opacity: 0; }
  60% { opacity: 1; }
  100% { transform: translateY(0) rotate(0); opacity: 1; }
}
@keyframes tile-flip {
  0% { transform: rotateY(0) translateY(0); }
  50% { transform: rotateY(90deg) translateY(-14px); }
  100% { transform: rotateY(0) translateY(0); }
}
@keyframes fade-in { from { opacity: 0; } }

/* ---------- sections ---------- */

.section { padding: 72px 0; }
.section--tight { padding: 36px 0; }
@media (min-width: 720px) { .section { padding: 104px 0; } }
.section__head { max-width: 680px; margin-bottom: 40px; }
.section__lead { color: var(--ink-2); font-size: 1.1rem; }

/* ---------- game cards ---------- */

.game-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr));
}
.game-card {
  --rx: 0deg;
  --ry: 0deg;
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 18px 18px 20px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform 220ms ease, box-shadow 220ms ease;
  will-change: transform;
}
.game-card:hover { box-shadow: var(--shadow-lift); }
.game-card__link { position: absolute; inset: 0; z-index: 2; border-radius: inherit; }
.game-card__top {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  height: 128px;
  margin: -18px -18px 16px;
  padding: 0 18px 0;
  background:
    radial-gradient(circle at 85% 30%, color-mix(in srgb, var(--accent) var(--tint-glow), transparent), transparent 58%),
    color-mix(in srgb, var(--accent) var(--tint-mix, 0%), var(--tint-card, var(--accent-soft)));
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}
.game-card__icon {
  width: 96px;
  height: 96px;
  border-radius: 22px;
  margin-bottom: -26px;
  box-shadow: 0 10px 22px -8px rgb(0 0 0 / 0.45);
  transition: transform 260ms cubic-bezier(0.3, 1.6, 0.5, 1);
}
.game-card:hover .game-card__icon { transform: translateY(-6px) rotate(-4deg) scale(1.04); }
.game-card__suit {
  align-self: flex-start;
  margin-top: 12px;
  font-size: 2.6rem;
  line-height: 1;
  color: var(--accent);
  opacity: 0.35;
}
.game-card__name { margin: 26px 0 2px; font-size: 1.45rem; }
.game-card__tagline { color: var(--ink-2); margin-bottom: 14px; }
/* ▶ Play sits above the card's full-size link, so one tap starts the game. */
.game-card__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: auto 0 0;
  padding-top: 16px;
}
.game-card__play { position: relative; z-index: 3; }
.game-card__more {
  margin-left: auto;
  font-family: var(--font-display);
  font-weight: 700;
  color: color-mix(in srgb, var(--accent) var(--accent-text-mix, 0%), var(--accent-text-base, var(--accent-ink)));
}
.game-card--soon .game-card__icon { filter: saturate(0.6); }
.game-card__soon {
  font-family: var(--font-tile);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1.5px dashed var(--line);
  color: var(--ink-2);
}

/* The last tile on the shelf: what's next. */
.lab-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 22px;
  border-radius: var(--radius);
  border: 2px dashed var(--line);
  background: color-mix(in srgb, var(--paper-2) 60%, transparent);
}
.lab-card h3 { margin-bottom: 0.3em; }
.lab-card p { color: var(--ink-2); }
.lab-card .btn { margin-top: auto; }
.lab-card__suits { font-size: 1.6rem; letter-spacing: 0.3em; color: var(--heart-text); margin-bottom: 0.4em; }
.btn--ghost-ink {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-edge: transparent;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ink) 30%, transparent);
}
.btn--ghost-ink:hover, .btn--ghost-ink:active { box-shadow: inset 0 0 0 2px var(--ink-2); }

/* Phones: the shelf becomes a list, one row per game: icon, name, ▶ Play.
   The whole row still opens the game's page. */
@media (max-width: 559px) {
  .game-grid { gap: 12px; }
  .game-card {
    display: grid;
    grid-template-columns: 64px 1fr auto;
    grid-template-areas: "icon name play" "icon tagline play";
    column-gap: 14px;
    align-items: center;
    padding: 12px 14px 12px 12px;
    background: color-mix(in srgb, var(--accent) var(--tint-mix, 0%), var(--tint-card, var(--accent-soft)));
  }
  .game-card__top { grid-area: icon; height: auto; margin: 0; padding: 0; background: none; border-radius: 0; }
  .game-card__icon,
  .game-grid--compact .game-card__icon { width: 64px; height: 64px; margin: 0; border-radius: 16px; }
  .game-card__suit, .game-card .tags, .game-card__more { display: none; }
  .game-card__name { grid-area: name; align-self: end; margin: 0; font-size: 1.2rem; }
  .game-card__tagline { grid-area: tagline; align-self: start; margin: 0; font-size: 0.92rem; line-height: 1.35; }
  .game-card__actions { grid-area: play; margin: 0; padding: 0; }
  .lab-card { padding: 18px; }
}

.section--shelf { padding: 36px 0 72px; }
@media (min-width: 720px) { .section--shelf { padding: 48px 0 96px; } }
.shelf__title { font-size: 1.6rem; margin-bottom: 18px; }

/* "Continue playing" (site.js fills it from this device's recent games). */
.continue { padding: 28px 0 0; }
.continue[hidden] { display: none; }
.continue__title { font-size: 1.15rem; margin-bottom: 12px; color: var(--ink-2); }
.continue__list { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
.continue-chip {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
  padding: 8px 18px 8px 8px;
  border-radius: 18px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  text-decoration: none;
  transition: transform 160ms ease;
}
.continue-chip[hidden] { display: none; }
.continue-chip:hover { transform: translateY(-2px); }
.continue-chip img { width: 44px; height: 44px; border-radius: 12px; }
.continue-chip span { display: flex; flex-direction: column; line-height: 1.2; }
.continue-chip b { font-family: var(--font-display); font-size: 1.05rem; }
.continue-chip small {
  font-weight: 700;
  font-size: 0.82rem;
  color: color-mix(in srgb, var(--accent) var(--accent-text-mix, 0%), var(--accent-text-base, var(--accent-ink)));
}

.tags { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0; }
.tags li {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--paper-2);
  color: var(--ink-2);
}
.tags .tags__web { background: color-mix(in srgb, var(--club) 16%, transparent); color: var(--club-text); }

.game-grid--compact .game-card__top { height: 104px; }
.game-grid--compact .game-card__icon { width: 76px; height: 76px; border-radius: 18px; }

/* ---------- phone frames (screenshots) ---------- */

.phone {
  margin: 0 auto;
  width: min(270px, 70vw);
  padding: 10px;
  border-radius: 38px;
  background: #151210;
  box-shadow: 0 30px 60px -24px rgb(0 0 0 / 0.55), inset 0 0 0 2px #3A332B;
  rotate: 3deg;
  transition: rotate 300ms ease;
}
.phone:hover { rotate: 0deg; }
.phone img { border-radius: 29px; width: 100%; aspect-ratio: 270 / 584; object-fit: cover; }

/* ---------- principles ---------- */

.principles {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
}
.principle {
  padding: 24px;
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--line);
}
.principle p { color: var(--ink-2); margin: 0; }
.principle__suit { display: block; font-size: 2rem; line-height: 1; margin-bottom: 14px; color: var(--spade); }
.principle:nth-child(2) .principle__suit, .principle:nth-child(3) .principle__suit { color: var(--heart); }
.principle:nth-child(4) .principle__suit { color: var(--club); }

.contact-band { background: var(--sky-gradient); color: var(--sky-ink); text-align: center; }
.contact-band__inner { display: flex; flex-direction: column; align-items: center; }
.contact-band p { color: var(--sky-ink-2); }
.contact-band .btn { margin-top: 8px; word-break: break-all; }

/* ---------- game page ---------- */

.game-hero {
  padding: 28px 0 56px;
  background:
    radial-gradient(80% 120% at 100% 0%, color-mix(in srgb, var(--accent) var(--tint-glow), transparent), transparent 60%),
    color-mix(in srgb, var(--accent) var(--tint-mix, 0%), var(--tint-base, var(--accent-soft)));
  color: var(--on-tint);
}
.game-hero__inner { max-width: 900px; }
.game-hero__head { display: flex; gap: 20px; align-items: center; margin: 22px 0 20px; }
.game-hero__head h1 { margin: 0; }
.game-hero__icon {
  width: clamp(88px, 22vw, 128px);
  height: auto;
  border-radius: 26%;
  box-shadow: 0 16px 30px -12px rgb(0 0 0 / 0.45);
  rotate: -4deg;
}
.game-hero__tagline { font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; margin: 4px 0 10px; }
.game-hero__blurb { font-size: 1.15rem; max-width: 40em; }
.game-hero .tags li { background: var(--chip-bg); color: var(--chip-ink, var(--accent-ink)); }
.back-link {
  font-family: var(--font-display);
  font-weight: 600;
  text-decoration: none;
  opacity: 0.8;
}
.back-link:hover { opacity: 1; text-decoration: underline; }

.shots {
  display: flex;
  gap: 22px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 18px 4px 28px;
  margin: 0 -16px;
  padding-left: 16px;
  padding-right: 16px;
}
.shots .phone { flex: none; width: min(250px, 66vw); scroll-snap-align: center; rotate: 0deg; }
.shots .phone:nth-child(odd) { rotate: -1.5deg; }
.shots .phone:nth-child(even) { rotate: 1.5deg; }
@media (min-width: 900px) { .shots { justify-content: center; } }

.feature-list { list-style: none; padding: 0; margin: 0 0 28px; display: grid; gap: 12px; }
.feature-list li {
  display: flex;
  gap: 14px;
  align-items: baseline;
  padding: 16px 18px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  font-size: 1.08rem;
}
.feature-list span { color: var(--accent); font-size: 1.3rem; flex: none; }
.fine-print { color: var(--ink-2); font-size: 0.92rem; }

/* ---------- play page ---------- */

.page-play { height: 100dvh; overflow: hidden; background: #111; }
.page-play main { height: 100%; }
.play { display: flex; flex-direction: column; height: 100%; }
.play__bar {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 46px;
  padding: 6px 14px;
  padding-top: max(6px, env(safe-area-inset-top));
  background: var(--sky);
  color: var(--sky-ink);
  font-size: 0.92rem;
}
.play__title { font-family: var(--font-display); font-weight: 700; margin-right: auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.play__apps { color: var(--sky-ink-2); display: flex; gap: 10px; align-items: center; }
.play__apps a { color: var(--sky-ink); font-weight: 600; white-space: nowrap; }
.play__bar > * { flex-shrink: 0; }
.play__bar > .play__title { flex-shrink: 1; }
.play__bar .back-link { font-size: 1.3rem; line-height: 1; padding: 4px 6px; }
/* Add this game to the home screen (site.js shows it when the browser can). */
.play__install {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-left: -8px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.14);
  color: var(--sky-ink);
  cursor: pointer;
}
.play__install[hidden] { display: none; }
.play__install:hover { background: rgb(255 255 255 / 0.26); }
.play__install svg { width: 18px; height: 18px; }
@media (max-width: 520px) { .play__apps { font-size: 0; gap: 12px; } .play__apps a { font-size: 0.85rem; } }
.play__stage { flex: 1; display: flex; min-height: 0; }
.play__frame { flex: 1; width: 100%; height: 100%; border: 0; background: var(--frame-bg); }
/* Desktop games: a skyscraper column each side, only when the screen is wide
   enough that the game keeps a comfortable width (Calembour rescales to fit). */
.play__rail { display: none; }
@media (min-width: 1280px) and (min-height: 680px) {
  .play__stage--ads .play__rail {
    display: flex;
    flex: 0 0 196px;
    align-items: center;
    justify-content: center;
    background: #1A1714;
    --ad-label: rgb(255 255 255 / 0.4);
    --ad-edge: rgb(255 255 255 / 0.12);
  }
}

/* Portrait games: a phone-width reference column (--pw) scaled uniformly by
   --s (set by site.js from the stage height), like Calembour's desktop scales
   from a fixed reference. The iframe keeps the reference width, so the game
   always lays out as a phone and never stretches; the scale only zooms it. */
.play__stage--portrait {
  --pw: 430;
  --s: 1;
  justify-content: center;
  align-items: stretch;
  gap: clamp(20px, 3vw, 48px);
  padding: 18px 24px;
  background:
    radial-gradient(60% 80% at 15% 20%, color-mix(in srgb, var(--accent) var(--tint-glow), transparent), transparent 70%),
    radial-gradient(50% 70% at 90% 85%, color-mix(in srgb, var(--sky-2) var(--tint-glow), transparent), transparent 70%),
    var(--tint-base, var(--accent-soft));
}
.play__device {
  position: relative;
  flex: none;
  width: calc(var(--pw) * var(--s) * 1px);
  height: 100%;
  border-radius: 30px;
  overflow: hidden;
  background: #111;
  box-shadow:
    0 0 0 8px #151320,
    0 0 0 10px color-mix(in srgb, #fff 12%, #151320),
    0 30px 60px -20px rgb(20 10 60 / 0.55);
}
.play__device .play__frame {
  position: absolute;
  inset: 0 auto auto 0;
  width: calc(var(--pw) * 1px);
  height: calc(100% / var(--s));
  transform: scale(var(--s));
  transform-origin: 0 0;
}
.play__side {
  flex: 0 1 280px;
  min-width: 0;
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
}
@media (min-width: 1080px) { .play__side { display: flex; } }

.side-card {
  padding: 20px 22px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--card) 88%, transparent);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  color: var(--ink);
}
.side-card__title { font-size: 1.15rem; margin: 0 0 12px; }
.side-card p { color: var(--ink-2); font-size: 0.95rem; }
.side-card__icon { width: 72px; height: 72px; border-radius: 18px; margin-bottom: 14px; box-shadow: 0 8px 18px -8px rgb(0 0 0 / 0.45); }
.side-card .store-buttons { flex-direction: column; }
.side-card .btn--store { min-width: 0; width: 100%; }
.controls { margin: 0; display: grid; gap: 10px; }
.controls__row { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: center; }
.controls dt { margin: 0; }
.controls__row--stacked { grid-template-columns: 1fr; gap: 4px; }
.controls dd { margin: 0; font-size: 0.95rem; color: var(--ink-2); }
kbd {
  display: inline-block;
  min-width: 2.2em;
  padding: 4px 8px;
  border-radius: 8px;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 2px 0 var(--line);
  font-family: var(--font-tile);
  font-size: 0.8rem;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  color: var(--ink);
}

/* ---------- ads ----------
   Side columns only (see src/ads.mjs for the rules). Every unit has a fixed,
   reserved size so nothing moves when it loads; each placement shows only when
   the screen has room to spare for it. */

.ad {
  flex-direction: column;
  align-items: center;
  gap: 6px;
  pointer-events: auto;
}
.ad__label {
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ad-label, var(--ink-2));
  opacity: 0.8;
  line-height: 1;
}
.ad__box {
  width: var(--ad-w);
  height: var(--ad-h);
  overflow: hidden;
  border-radius: 8px;
}
.ad__box ins { display: block; }
/* The label shows only over a real ad: an empty or pending slot stays blank
   (space kept, so nothing jumps when an ad does arrive). */
.ad:not([data-ad-preview]) .ad__label { visibility: hidden; }
.ad:has(ins[data-ad-status="filled"]) .ad__label { visibility: visible; }
/* Unfilled: Google leaves a blank white frame in the slot, and its inner frame
   forces visibility: visible, so hide the whole <ins> (Google's documented
   rule). The .ad__box keeps its fixed size, so nothing moves. */
ins.adsbygoogle[data-ad-status="unfilled"] { display: none !important; }
.ad[data-ad-preview] .ad__box {
  display: grid;
  place-items: center;
  border: 2px dashed var(--ad-edge, var(--line));
  background: color-mix(in srgb, var(--card) 50%, transparent);
  color: var(--ad-label, var(--ink-2));
  font-family: var(--font-tile);
  font-size: 0.8rem;
  text-align: center;
}

/* Home and game pages: fixed in the empty margins beside the 1160px column,
   centered in each margin, below the header. Wide, tall windows only. */
.ad--gutter { display: none; }
@media (min-width: 1560px) and (min-height: 760px) {
  .ad--gutter {
    display: flex;
    position: fixed;
    z-index: 10;
    top: calc(50% + 32px);
    translate: 0 -50%;
  }
  .ad--gutter.ad--left { left: calc((100vw - 1160px) / 4 - var(--ad-w) / 2); }
  .ad--gutter.ad--right { right: calc((100vw - 1160px) / 4 - var(--ad-w) / 2); }
}

/* Phone-shaped games: a square under each side card, when the column has room. */
.ad--side { display: none; }
@media (min-width: 1280px) and (min-height: 860px) {
  .ad--side { display: flex; }
}

@media print { .ad { display: none !important; } }

/* "Email copied" note, for email links on machines with no mail app. */
.copy-toast {
  position: fixed;
  left: 50%;
  bottom: max(24px, env(safe-area-inset-bottom));
  z-index: 100;
  translate: -50% 0;
  max-width: calc(100vw - 32px);
  padding: 12px 18px;
  border-radius: 14px;
  background: var(--ink);
  color: var(--paper);
  font-weight: 600;
  box-shadow: var(--shadow);
  text-align: center;
}

/* "Add to home screen" offer (site.js): a card above the bottom edge, phones
   and tablets only, until dismissed. */
.install-banner {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 520px;
  margin: 0 auto;
  padding: 12px 12px 12px 14px;
  border-radius: 18px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: 0 18px 40px -12px rgb(20 10 60 / 0.45);
  color: var(--ink);
  font-size: 0.92rem;
  line-height: 1.4;
  animation: banner-in 320ms cubic-bezier(0.2, 1.3, 0.4, 1) both;
}
.install-banner__icon { width: 48px; height: 48px; border-radius: 12px; flex: none; }
.install-banner__text { display: flex; flex-direction: column; min-width: 0; }
.install-banner__text > b { font-family: var(--font-display); font-size: 1.02rem; }
.install-banner__text span { color: var(--ink-2); }
.install-banner__share { display: inline-block; width: 1.1em; height: 1.1em; vertical-align: -0.15em; color: var(--spade); }
.install-banner__actions { display: flex; align-items: center; gap: 4px; margin-left: auto; flex: none; }
.install-banner__close {
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink-2);
  font-size: 1rem;
  cursor: pointer;
}
.install-banner__close:hover { background: var(--paper-2); }
.btn--small { min-height: 40px; padding: 6px 16px; font-size: 0.95rem; box-shadow: 0 3px 0 var(--btn-edge); }
@keyframes banner-in { from { transform: translateY(24px); opacity: 0; } }

/* Notches and the home indicator: the game frame can't see the phone's safe
   areas (env() is zero inside an iframe), so the page keeps the game out of
   them. Matters most in the installed app, which draws edge to edge. */
.play__bar { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); }
.play__stage:not(.play__stage--portrait) {
  padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* Phones and narrow windows: the game simply fills the screen. */
@media (max-width: 699px) {
  .play__stage--portrait {
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    background: #111;
  }
  .play__device { width: 100%; border-radius: 0; box-shadow: none; }
  .play__device .play__frame { width: 100%; height: 100%; transform: none; }
}

/* ---------- legal ---------- */

.legal { padding-top: 32px; padding-bottom: 88px; }
.legal h1 { margin-top: 20px; }
.legal h2 { font-size: 1.45rem; margin-top: 2em; }
.legal h3 { margin-top: 1.4em; }
.legal__updated { color: var(--ink-2); font-family: var(--font-tile); font-size: 0.85rem; }
.legal li { margin-bottom: 0.4em; }
.callout {
  padding: 20px 24px;
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 6px solid var(--sun);
  margin: 24px 0;
}
.callout h2 { margin-top: 0; font-size: 1.2rem; }
.callout ul { margin: 0; padding-left: 1.2em; }
.table-scroll { overflow-x: auto; margin: 0 0 1em; }
.legal table { border-collapse: collapse; width: 100%; min-width: 520px; font-size: 0.95rem; }
.legal th, .legal td { text-align: left; vertical-align: top; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.legal th { font-family: var(--font-display); }

/* ---------- 404 ---------- */

.notfound { padding: 96px 16px; text-align: center; }
.tile-row--center { justify-content: center; margin-bottom: 36px; }

/* ---------- footer ---------- */

.site-footer { background: var(--paper-2); border-top: 1px solid var(--line); padding: 48px 0 40px; }
.site-footer__inner { display: grid; gap: 24px; }
@media (min-width: 820px) { .site-footer__inner { grid-template-columns: 1fr auto; } }
.site-footer__brand { display: flex; gap: 14px; align-items: flex-start; }
.site-footer__name { font-family: var(--font-display); font-weight: 700; margin: 0; }
.site-footer__line { color: var(--ink-2); margin: 0; }
.site-footer__links { display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: center; }
.site-footer__links a { font-weight: 600; text-decoration: none; }
.site-footer__links a:hover { text-decoration: underline; }
.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.link-button:hover { text-decoration: underline; }
.site-footer__legal { grid-column: 1 / -1; color: var(--ink-2); font-size: 0.8rem; margin: 0; }

/* ---------- Play offline switch (game pages) ---------- */

.offline { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin-top: 18px; }
.offline[hidden] { display: none; }
.offline__switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 4px 4px 4px 0;
  border: 0;
  background: none;
  color: inherit;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
}
.offline__switch:disabled { cursor: progress; }
.offline__track {
  position: relative;
  width: 46px;
  height: 28px;
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 22%, transparent);
  transition: background 160ms ease;
}
.offline__knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.3);
  transition: translate 160ms ease;
}
.offline__switch[aria-checked="true"] .offline__track { background: color-mix(in srgb, var(--accent) 80%, black); }
.offline__switch[aria-checked="true"] .offline__knob { translate: 18px 0; }
.offline__status { font-size: 0.92rem; opacity: 0.85; }

/* ---------- about ---------- */

.about h1 { font-size: clamp(2rem, 5.5vw, 3.2rem); }
.principle h2 { font-size: 1.25rem; }
.about__settings h2 { font-size: 1.35rem; }
.about__settings .theme-picker { margin-bottom: 20px; }

/* ---------- installed app ----------
   Opened from the home screen (display-mode: standalone): no browser chrome,
   so the site drops its header and footer for a native-style bottom tab bar. */

.tab-bar { display: none; }
@media (display-mode: standalone) {
  .site-header, .site-footer { display: none; }
  .page-home .hero__inner { padding-top: max(28px, env(safe-area-inset-top)); }
  .tab-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: flex;
    justify-content: space-around;
    padding: 6px max(8px, env(safe-area-inset-right)) max(6px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
    background: color-mix(in srgb, var(--paper) 90%, transparent);
    backdrop-filter: saturate(1.4) blur(14px);
    -webkit-backdrop-filter: saturate(1.4) blur(14px);
    border-top: 1px solid var(--line);
  }
  main { padding-bottom: calc(68px + env(safe-area-inset-bottom)); }
  .page-play main { padding-bottom: 0; }
  .install-banner { display: none; }
}
.tab-bar__tab {
  flex: 1;
  max-width: 120px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 4px;
  border-radius: 14px;
  color: var(--ink-2);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.tab-bar__tab[hidden] { display: none; }
.tab-bar__tab svg { width: 24px; height: 24px; }
.tab-bar__tab[aria-current="page"] { color: var(--ink); }
.tab-bar__tab[aria-current="page"] svg { color: var(--heart-text); }
.tab-bar__tab:active { background: var(--paper-2); }

/* ---------- motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .game-card { transform: none !important; }
}
