/* throwingshapes.app. One stylesheet for every page. The colours are the app's own (ThrowingShapes/UI/TSStyle.swift):
   the wordmark's magenta, the lit tube's paler magenta, the deep violet-black fill behind every control, and Theme's
   paper and ink for the light scheme. The type is the app's, Chakra Petch (SIL OFL, fonts/OFL.txt). */

@font-face {
  font-family: "Chakra Petch";
  src: url("fonts/chakra-petch-regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Chakra Petch";
  src: url("fonts/chakra-petch-semibold.woff") format("woff");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Chakra Petch";
  src: url("fonts/chakra-petch-bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light dark;
  /* Light: Theme's paper and ink (TS.paper, TS.paperInk). */
  --bg: #f2f0f7;
  --bg-raised: #ffffff;
  --ink: #1f1a33;
  --ink-soft: #4a4460;
  --line: #dcd7e8;
  --accent: #a3009f;          /* the wordmark's magenta, darkened to read on paper (7.1:1) */
  --tube: #ff00ff;
  --tube-lit: #ff5cff;
  --night: #080614;           /* TS.fill */
  --placeholder-bg: #fff3c4;
  --placeholder-ink: #5c4400;
  --font: "Chakra Petch", ui-rounded, system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #080614;
    --bg-raised: #120e24;
    --ink: #ffffff;
    --ink-soft: #c9c3dc;
    --line: #2a2342;
    --accent: #ff5cff;        /* TS.litMagenta */
    --placeholder-bg: #3a2f00;
    --placeholder-ink: #ffe38a;
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.6;
  overflow-x: hidden;
}

img, video { max-width: 100%; display: block; }
video[hidden] { display: none; }

a { color: var(--accent); text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--tube-lit);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
}
.skip:focus {
  left: 16px;
  top: 16px;
  z-index: 10;
  background: var(--night);
  color: #fff;
  padding: 0.5rem 1rem;
  border-radius: 999px;
}

h1, h2, h3 {
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.01em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

.wrap {
  width: 100%;
  max-width: 60rem;
  margin: 0 auto;
  padding: 0 16px;
}

/* A marked gap for Sam to fill: visible on purpose, so nothing unconfirmed can go live unnoticed. */
.placeholder {
  background: var(--placeholder-bg);
  color: var(--placeholder-ink);
  border-radius: 4px;
  padding: 0 0.3em;
  font-weight: 600;
}

/* ── The hero: home, as the app draws it ─────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  min-height: 560px;
  display: flex;
  justify-content: center;
  overflow: hidden;
  color: #fff;
  background-color: var(--night);
  background-image: url("media/hero-wide-v2.jpg");
  background-size: cover;
  background-position: center 62%;
  isolation: isolate;
}
@media (min-width: 48rem) {
  .hero { min-height: min(92vh, 50rem); }
}
@media (max-aspect-ratio: 4/5) {
  .hero { background-image: url("media/hero-tall-v2.jpg"); min-height: 100svh; }
}

.hero video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;
  z-index: -1;
}

/* The wordmark sits over the sky, as it does on the app's home screen. */
.hero-inner {
  width: 100%;
  max-width: 44rem;
  padding: clamp(1.5rem, 5vh, 3.5rem) 16px 2.5rem;
  text-align: center;
  display: flex;
  flex-direction: column;
}

/* As on the app's home screen: the wordmark over the sky, the buttons below the ball. A shade at the foot of the
   floor keeps the launch line and the button readable over its bright lines, and leads into the page. */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 40%;
  background: linear-gradient(rgba(8, 6, 20, 0), rgba(8, 6, 20, 0.85));
  z-index: -1;
  pointer-events: none;
}
.hero-actions { margin-top: auto; padding-top: 2rem; }

.hero h1 { margin: 0; }
.hero h1 img {
  width: min(88vw, 26rem);
  height: auto;
  margin: 0 auto;
}

.tagline {
  margin: 0.25rem auto 0;
  font-size: clamp(1.1rem, 3.6vw, 1.35rem);
  font-weight: 600;
  text-shadow: 0 1px 12px rgba(8, 6, 20, 0.9);
}

.launch {
  margin: 0.5rem 0 1.25rem;
  font-size: 1rem;
  color: #e7e2f5;
  text-shadow: 0 1px 10px rgba(8, 6, 20, 0.9);
}

/* The app's main button: a magenta neon tube round a dark, see-through fill (TS "lit"). */
.tube {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0.6rem 1.6rem;
  border-radius: 999px;
  border: 2px solid var(--tube-lit);
  background: rgba(8, 6, 20, 0.72);
  color: #fff;
  font: 600 1.05rem/1.2 var(--font);
  text-decoration: none;
  box-shadow: 0 0 6px var(--tube), 0 0 22px rgba(255, 0, 255, 0.55), inset 0 0 14px rgba(255, 92, 255, 0.35);
}
a.tube:hover { background: rgba(40, 8, 48, 0.8); }

.pause {
  position: absolute;
  right: 16px;
  top: 16px;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.45);
  background: rgba(8, 6, 20, 0.6);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.pause svg { width: 1rem; height: 1rem; fill: currentColor; }
.pause[hidden] { display: none; }

/* ── Sections ────────────────────────────────────────────────────────────────────────────────────────── */

main section { padding: 3.5rem 0; }
main section + section { border-top: 1px solid var(--line); }

/* A section set in a place: a 1.0 look behind it, skies and floors alternating down the page (images/bg/). Each is a
   frame of the game's own world shader (tools/world-shader game-still): a floor in the play camera with its horizon,
   or a sky from a camera on the floor looking up. Unblurred and at full
   resolution: 2880 wide for desktop and 1170 for phones, each at its own section's shape, so cover never upscales it on
   a Retina screen (Sam, 2026-10-18). Not darkened, so the pattern stays unmistakable. A light shade over the whole frame calms it, and the
   text's contrast comes from the dark .panel it sits on, measured at the text (docs/notes-1012/sitesections-1014.md).
   The text colours inside are fixed light ones whatever the colour scheme: the sections stay dark in light mode (Sam,
   2026-10-14). */
.scene {
  --ink: #ffffff;
  --ink-soft: #ddd8ec;
  --accent: #ff9cff;
  --line: rgba(255, 255, 255, 0.2);
  --bg-raised: rgba(8, 6, 20, 0.74);
  --placeholder-bg: #3a2f00;
  --placeholder-ink: #ffe38a;
  --shade: linear-gradient(rgba(8, 6, 20, 0.22), rgba(8, 6, 20, 0.22));
  color: var(--ink);
  background: var(--shade), var(--scene, none) center top / cover no-repeat, var(--night);
  padding: 4.5rem 0;
}
/* A floor keeps its horizon in view (the top of the frame); a sky keeps its horizon too (the foot of the frame). */
.scene-floor { background-position: 0 0, center top; }
.scene-sky { background-position: 0 0, center bottom; }
@media (max-width: 48rem) {
  .scene { background-image: var(--shade), var(--scene-sm, var(--scene, none)); }
}
/* The text's own dark ground: the look shows all round it. */
.panel {
  background: rgba(8, 6, 20, 0.74);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 1.25rem;
  padding: clamp(1rem, 3vw, 1.6rem);
}
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }
.panel-fit { width: fit-content; max-width: 100%; }
.row-head { padding: 0.6rem 1rem; margin-bottom: 0.9rem; }
.row-head p { margin: 0; }
main .scene + .scene { border-top: 0; }

/* A bracketed note of what Sam's copy will cover: obviously not copy, so none of it can go live unnoticed. */
.note {
  display: inline-block;
  margin: 0.25rem 0 0.75rem;
  padding: 0.35rem 0.7rem;
  border: 1px dashed var(--placeholder-ink);
  border-radius: 0.5rem;
  background: var(--placeholder-bg);
  color: var(--placeholder-ink);
  font-weight: 600;
}
/* A screenshot still to be confirmed (a candidate, or a stand-in): says so, small, under it. A grid, so the caption spans the shots' own
   columns on a row of its own and never widens the figure (contain keeps its text from setting the width). */
.shots:has(.stand-in) { display: grid; grid-template-columns: auto; justify-content: center; }
.shots.two:has(.stand-in) { grid-template-columns: auto auto; }
.shots .stand-in {
  grid-column: 1 / -1;
  contain: inline-size;
  margin: 0;
  padding: 0.3rem 0.6rem;
  text-align: center;
  font-size: 0.8rem;
  font-weight: 600;
  border: 1px dashed var(--placeholder-ink);
  border-radius: 0.5rem;
  background: var(--placeholder-bg);
  color: var(--placeholder-ink);
}

/* What you get: Free beside the Collector's Edition (Photosynthesis's plans), one column on a phone. The Free card is
   honest and smaller; the Edition's is wider, lit like the app's main button (the TS "lit" tube), with its counts as
   big numbers and a compact checklist. Every item and count is the app's own (index.html's comment; the notes). */
.plans { display: grid; gap: 1rem; margin-top: 1.5rem; align-items: start; }
@media (min-width: 48rem) { .plans { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); } }
.plan {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 1.2rem;
  padding: 1.25rem 1.4rem 1.4rem;
}
.plan h3 { margin: 0 0 0.75rem; font-size: 1.35rem; }
.plan-free { font-size: 0.95rem; }
.plan .note { margin-top: 0.9rem; font-size: 0.85rem; }
.plan-brand {
  border: 2px solid var(--tube-lit);
  background: linear-gradient(160deg, rgba(64, 8, 72, 0.86), rgba(8, 6, 20, 0.86) 55%);
  box-shadow: 0 0 6px var(--tube), 0 0 26px rgba(255, 0, 255, 0.45), inset 0 0 18px rgba(255, 92, 255, 0.22);
}
.plan-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 1rem; }
.plan-brand h3 { font-size: clamp(1.45rem, 4vw, 1.8rem); margin-bottom: 0.25rem; }
.plan-terms { margin: 0; font-weight: 600; color: var(--ink-soft); }
/* The counts: four numbers, one per layer. */
.counts {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.5rem;
  text-align: center;
}
.counts li { color: var(--ink-soft); font-size: 0.85rem; line-height: 1.2; }
.counts b { display: block; color: var(--ink); font-size: 1.6rem; line-height: 1.1; }
.counts.big b {
  font-size: clamp(2.1rem, 7vw, 3rem);
  color: var(--accent);
  text-shadow: 0 0 12px rgba(255, 0, 255, 0.55);
}
.counts-note { margin: 0.35rem 0 0; text-align: center; font-size: 0.85rem; color: var(--ink-soft); }
/* The checklist: a tick in the tube's colour, the app's feature name, then what it means in a few words. */
.checks { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.45rem; align-items: start; }
/* Two columns on the Edition's card from 48rem, flowing top to bottom so a long item never leaves a gap beside it. */
@media (min-width: 48rem) {
  .plan-brand .checks { display: block; columns: 2; column-gap: 1.25rem; }
  .plan-brand .checks li { break-inside: avoid; margin-bottom: 0.45rem; }
}
.checks li { display: grid; grid-template-columns: 1.1rem minmax(0, 1fr); column-gap: 0.5rem; align-content: start; line-height: 1.35; }
.checks svg { width: 1.1rem; height: 1.1rem; margin-top: 0.12rem; color: var(--tube-lit); grid-row: span 2; }
.checks b { font-weight: 700; }
.checks span { grid-column: 2; color: var(--ink-soft); font-size: 0.88em; }
.plan-free .checks svg { color: var(--ink-soft); }

/* FAQ: one question per disclosure, as Photosynthesis's. */
.faq { margin-top: 1rem; display: grid; gap: 0.6rem; max-width: 42rem; }
.faq details {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  padding: 0.8rem 1.1rem;
}
.faq summary { cursor: pointer; font-weight: 600; color: var(--placeholder-ink); }
.faq details .note { margin: 0.75rem 0 0.25rem; }

/* Gallery: phone shots of different combinations of looks, four across from 48rem, two on a phone, each captioned with
   its four looks. (.slot: a marked phone-shaped gap, for a shot still to come.) */
.gallery {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}
@media (min-width: 48rem) { .gallery { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; } }
.gallery figure { margin: 0; }
.gallery img, .gallery .slot {
  width: 100%;
  height: auto;
  aspect-ratio: 675 / 1380;
}
.gallery .slot { border-radius: 1.2rem; }
/* The shots come in an iPhone frame (tools/site-frames, as Photosynthesis's and Chess Peace's sites): the frame is the
   edge, so only a shadow that follows its outline. */
.gallery img { filter: drop-shadow(0 10px 22px rgba(8, 6, 20, 0.45)); }
/* The four looks in each shot, small, on their own dark ground. */
.gal-cap {
  margin-top: 0.4rem;
  padding: 0.3rem 0.55rem;
  border-radius: 0.6rem;
  background: rgba(8, 6, 20, 0.74);
  color: var(--ink-soft);
  font-size: 0.78rem;
  line-height: 1.35;
  text-align: center;
}
.gallery .slot {
  display: grid;
  place-items: center;
  border: 2px dashed var(--placeholder-ink);
  background: var(--placeholder-bg);
  color: var(--placeholder-ink);
  font-weight: 600;
}

.closing { text-align: center; }
.closing .panel { margin: 0 auto; }
.closing h2 { font-size: clamp(1.9rem, 6vw, 2.6rem); }
/* The wordmark above the closing line, bookending the page with the hero's: a size down from the hero's. */
.closing-mark img { display: block; width: min(80vw, 22rem); height: auto; margin: 0 auto 0.5rem; }

main h2 {
  font-size: clamp(1.6rem, 5vw, 2.1rem);
  margin: 0 0 1rem;
}

.lead {
  font-size: 1.2rem;
  color: var(--ink);
  max-width: 38rem;
}

.devices {
  list-style: none;
  padding: 0;
  margin: 1.25rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.devices li {
  border: 1px solid var(--line);
  background: var(--bg-raised);
  border-radius: 999px;
  padding: 0.3rem 0.9rem;
  font-weight: 600;
}

.maker {
  display: flex;
  gap: 1.25rem;
  align-items: center;
}
.maker img {
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 1.1rem;
  flex: none;
}
.maker p { margin: 0; min-width: 0; overflow-wrap: anywhere; }   /* the email address may break below ~365 px, inside its panel */

/* Text beside screenshots: one column on a phone, two from 48rem. */
.split { display: grid; gap: 1.5rem 2.5rem; align-items: center; }
@media (min-width: 48rem) {
  .split { grid-template-columns: minmax(0, 1fr) auto; }
}
.split > div > :last-child { margin-bottom: 0; }
/* Every other text-beside-picture section swaps sides (Sam, 2026-10-20): the picture left, the text right. On a phone
   both stack as before, text first. */
@media (min-width: 48rem) {
  .split.flip { grid-template-columns: auto minmax(0, 1fr); }
  .split.flip > :first-child { order: 2; }
}

/* Phone screenshots, as the game draws them, in an iPhone frame. */
.shots { margin: 0; display: flex; gap: 0.75rem; justify-content: center; }
.shots img {
  width: min(42vw, 14.5rem);
  height: auto;
  filter: drop-shadow(0 12px 26px rgba(8, 6, 20, 0.4));   /* framed: see .gallery img */
}
.shots.one img { width: min(62vw, 16.75rem); }   /* the frame adds 12% round the screen: the screens stay their old size */
/* Until the real screenshot is in: a marked box the size of one, so nothing unfinished can go live unnoticed. */
.shot-todo {
  width: min(42vw, 14.5rem);
  aspect-ratio: 675 / 1380;
  display: grid;
  place-items: center;
  padding: 1rem;
  text-align: center;
  font-weight: 600;
  border-radius: 1.4rem;
  border: 2px dashed var(--placeholder-ink);
  background: var(--placeholder-bg);
  color: var(--placeholder-ink);
}
.shots.one .shot-todo { width: min(62vw, 16.75rem); }

/* The customisations: one row per layer, looping right to left (index.html, "Customisations"). The track holds the
   list twice, the second aria-hidden; each list carries a trailing gap the size of the one between tiles, so moving the
   track by exactly half (one list) lands it where it began: a seamless loop, transform only. Each list must be at least
   as wide as the row (the .wrap's 60rem), or the loop shows a gap: the shortest, Skies, is 7 x 8.75rem = 61.25rem. */
.look-rows { position: relative; }
.look-row { margin-top: 2.25rem; }
.look-row h3 { font-size: 1.3rem; margin: 0 0 0.25rem; color: var(--accent); }
.look-row p { margin: 0 0 0.9rem; color: var(--ink-soft); max-width: 38rem; }
.look-row .row-head p { margin: 0; }
.marquee {
  overflow: hidden;
  border-radius: 0.9rem;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent);
}
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee var(--dur, 40s) linear infinite;
}
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track,
.look-rows.paused .marquee-track { animation-play-state: paused; }
/* The fade at the row's ends is a mask, and a mask clips the focus ring: drop it while the row has keyboard focus (the
   row is paused then anyway). */
.marquee:focus-visible { -webkit-mask-image: none; mask-image: none; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.strip {
  list-style: none;
  margin: 0;
  padding: 0 0.75rem 0 0;
  display: flex;
  gap: 0.75rem;
  flex: none;
}
.strip li { flex: none; }
.strip.balls li { width: 5rem; }
.strip.tiles li { width: 8rem; }
/* In the flow, on its own line above the rows, so it never covers a row's text on a phone. */
.rows-pause { position: static; margin: 1.5rem 0 -1rem auto; }
.looks img { width: 100%; height: auto; aspect-ratio: 1; }
.looks.balls img {
  padding: 12%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 40%, #2a2342, var(--night) 75%);
}
.looks.tiles img { border-radius: 0.9rem; object-fit: cover; }
.look-end { margin-top: 2.5rem; }


/* ── Plain pages (support, privacy) ──────────────────────────────────────────────────────────────────── */

.page-top {
  background: var(--night);
  color: #fff;
  padding: 1rem 0;
}
.page-top a {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: #fff;
  text-decoration: none;
  font-weight: 600;
}
.page-top img { width: 2rem; height: 2rem; border-radius: 0.5rem; }

.doc { padding-top: 2.5rem; padding-bottom: 3.5rem; max-width: 42rem; }
.doc h1 { font-size: clamp(2rem, 6vw, 2.6rem); margin: 0 0 0.5rem; }
.doc h2 { font-size: 1.3rem; margin: 2rem 0 0.4rem; }
.doc p, .doc li { color: var(--ink-soft); }
.doc .updated { margin-top: 0; font-size: 0.95rem; }

/* ── Footer ──────────────────────────────────────────────────────────────────────────────────────────── */

footer {
  border-top: 1px solid var(--line);
  padding: 2rem 0 2.5rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin-bottom: 0.75rem;
}
footer p { margin: 0.25rem 0; }

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
  /* The rows of looks stand still and scroll by hand: one copy of each list, no mask, no pause button. */
  .marquee-track { animation: none; }
  .marquee {
    overflow-x: auto;
    -webkit-mask-image: none;
    mask-image: none;
    scroll-snap-type: x proximity;
  }
  .strip { padding-right: 0; }
  .strip li { scroll-snap-align: start; }
  .strip[aria-hidden="true"], .rows-pause { display: none; }
}

/* ── The Collector's Edition section (index.html), copied from the Collector's Edition page (site-ce-1021) ────────── */

/* The app's lockup: the wordmark, the gold ribbon under it (268 of 330 of its width, 10 of 330 below), Sam's line. */
.ce-lockup { width: fit-content; max-width: 100%; margin: 0 auto; text-align: center; }
.ce-lockup .ce-title { margin: 0; display: grid; justify-items: center; }
.ce-lockup .ce-title img { width: min(80vw, 22rem); height: auto; }
.ce-ribbon {
  width: min(65vw, 17.85rem);
  height: auto;
  margin-top: min(2.4vw, 0.67rem);
  overflow: visible;
  filter: drop-shadow(0 0 3px rgba(255, 196, 64, 0.7));
}
.ce-sub { margin: 1rem 0 0; font-size: clamp(1.15rem, 3.8vw, 1.45rem); font-weight: 600; }
/* The Edition's card alone (no Free card): under the lockup on a phone; from 56rem the section splits down the middle,
   the lockup on the left and the card on the right (Sam, 2026-10-20). */
.ce-plans { max-width: 44rem; margin: 1.5rem auto 0; }
@media (min-width: 48rem) { .ce-plans { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 56rem) {
  .ce-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2rem; align-items: center; }
  .ce-split .ce-lockup { margin: 0 auto; }
  .ce-split .ce-plans { margin: 0; max-width: none; }
}
.plan-brand .ce-h { font-size: clamp(1.45rem, 4vw, 1.8rem); margin: 0 0 0.25rem; }
.plan-brand .ce-checks { display: grid; columns: auto; gap: 0.8rem; margin-top: 1.1rem; }
.plan-brand .ce-checks li { margin: 0; }
.ce-checks b { font-size: 1.05em; }
/* Each row's icon as the purchase page draws it (CollectorsEditionContents): the bright magenta in a 32 pt rounded box
   of the same at 16%, 14 pt from the text. The app's are SF Symbols, which Apple licenses for apps on its platforms
   only, so these are their nearest Phosphor icons (MIT). New looks every month has the looks paintbrush
   (paintbrush.pointed.fill, the pause menu's Theme button), not a gift (Sam, 2026-10-20). */
.ce-checks li { grid-template-columns: 2rem minmax(0, 1fr); column-gap: 0.875rem; }
.ce-checks .ce-icon {
  grid-column: 1;
  grid-row: span 2;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 0.5625rem;
  color: var(--tube-lit);
  background: rgba(255, 92, 255, 0.16);
  font-size: 1rem;
}
.ce-checks .ce-icon svg { width: 1.1rem; height: 1.1rem; margin: 0; grid-row: auto; }

/* The App Store badge (Apple's, as Chess Peace's site): 180 x 60, lifting a little on hover. */
.app-store-btn {
  display: inline-block;
  width: 180px;
  height: 60px;
  border-radius: 10px;
  text-decoration: none;
  transition: transform 0.2s, box-shadow 0.2s;
}
.app-store-btn img { display: block; width: 100%; height: 100%; }
.app-store-btn:hover { transform: scale(1.04); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3); }
@media (prefers-reduced-motion: reduce) { .app-store-btn { transition: none; } .app-store-btn:hover { transform: none; } }
