/*
Theme Name: Yono New App
Theme URI: https://yononewapp.example
Author: Vivek
Description: One page APK download splash for the Yono New App Android package. Dark lacquer green with gold reserved for money, Khand over Hanken Grotesk, every string and figure editable from an ACF options page. Sibling to the yonogame directory theme, deliberately not a copy of it. Strategy in PRODUCT.md, visual system in DESIGN.md, outstanding assets in ASSETS.md, all at the theme root.
Version: 1.0.0
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: yononewapp
Tags: one-column, custom-colors, custom-menu, translation-ready
*/

/* ==========================================================================
   0. Fonts, self hosted
   Google Fonts is not linked at runtime. Two DNS lookups and two round trips
   to a third party is a real cost on one bar of 4G, and the page has to keep
   working on a network that blocks fonts.gstatic.com.

   The rupee sign matters here. U+20B9 is not in the latin subset of either
   family; Google Fonts ships it in devanagari. Khand has a devanagari subset
   and it is loaded for weight 700 only, which is every place a rupee figure is
   set in the display face. Hanken Grotesk has no devanagari subset at all, so
   rupee signs in body copy fall back to the system font. That is exactly what
   already happens when the same families are served from Google, and it looks
   correct on Android, Windows and iOS, all of which ship the glyph.
   ========================================================================== */

@font-face {
  font-family: "Hanken Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/hanken-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Khand";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/khand-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Khand";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/khand-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* The rupee sign, and nothing else that will ever appear on this page. The file
   is 87KB, so the narrow unicode-range matters: the browser fetches it only
   because of the currency glyph, and never on a page without one. */
@font-face {
  font-family: "Khand";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/khand-700-devanagari.woff2") format("woff2");
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0,
    U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}

/* ==========================================================================
   Yono New App - one page download splash
   Tokens and rationale live in DESIGN.md at the project root. Read that first.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   Hex ships first and OKLCH overrides it. A 2019 budget Android running an old
   WebView does not know oklch(), and this page is built for exactly that phone.
   -------------------------------------------------------------------------- */
:root {
  --bg: #0b2a26;
  --surface: #103830;
  --raised: #16473f;
  --line: #1f564e;

  --gold: #edb23a;
  --gold-deep: #c28c2e;
  --saffron: #e07b2a;

  --ink: #f4f8f3;
  --muted: #b4c4bc;
  --faint: #86988f;

  --r-lg: 18px;
  --r-md: 14px;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  --wrap: 1120px;
  --gut: clamp(16px, 4.5vw, 32px);

  --sans: "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: "Khand", "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif;

  /* dropdown 10, sticky header 20, sticky bar 30 */
  --z-header: 20;
  --z-bar: 30;
}

@supports (color: oklch(0.5 0.1 180)) {
  :root {
    --bg: oklch(0.19 0.042 168);
    --surface: oklch(0.245 0.050 168);
    --raised: oklch(0.30 0.055 168);
    --line: oklch(0.36 0.045 168);

    --gold: oklch(0.82 0.145 85);
    --gold-deep: oklch(0.68 0.135 78);
    --saffron: oklch(0.70 0.185 55);

    --ink: oklch(0.97 0.008 130);
    --muted: oklch(0.78 0.020 150);
    --faint: oklch(0.63 0.022 150);
  }
}

/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 15px/1.6 var(--sans);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  text-wrap: balance;
}

/* Ceiling is 3.6rem, not the 4.6rem this started at. Khand is condensed, but a
   46-character headline still broke to three lines in the hero's copy column at
   1440, and the hero headline gets two lines. Mobile is untouched: 10vw at 375px
   is below the 2.4rem floor either way. */
h1 {
  font-size: clamp(2.4rem, 10vw, 3.6rem);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.01em;
}

h2 {
  font-size: clamp(1.7rem, 6vw, 2.6rem);
  line-height: 1.04;
}

h3 {
  font-family: var(--sans);
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.3;
}

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: inherit;
}

ul,
ol,
dl,
dd {
  margin: 0;
  padding: 0;
  list-style: none;
}

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

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.ico {
  width: 1.15em;
  height: 1.15em;
  fill: currentColor;
  flex: none;
}

.sr-only,
.skip-link:not(:focus) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link:focus {
  position: fixed;
  inset: 12px auto auto 12px;
  z-index: 99;
  padding: 10px 16px;
  border-radius: var(--r-md);
  background: var(--gold);
  color: var(--bg);
  font-weight: 700;
  text-decoration: none;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gut);
}

.section {
  padding-block: clamp(56px, 9vw, 96px);
}

/* The header is sticky, so an in-page anchor lands with its heading tucked
   underneath it. Clear the header height plus a little air. */
[id] {
  scroll-margin-top: 80px;
}

.lede {
  margin-top: 10px;
  max-width: 62ch;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   3. Buttons
   The primary action is gold foil with green ink pressed into it. White on
   saffron measured 2.6:1 and was rejected; this pairing measures about 7.9:1.
   -------------------------------------------------------------------------- */
.btn-primary,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 26px;
  border: 0;
  border-radius: var(--r-md);
  font: 700 1.05rem/1 var(--sans);
  text-decoration: none;
  cursor: pointer;
  transition: transform 140ms var(--ease-out), filter 140ms var(--ease-out);
}

.btn-primary {
  background: linear-gradient(100deg, var(--gold), var(--gold-deep) 55%, var(--saffron));
  color: var(--bg);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.35) inset;
}

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}

.btn-sm {
  min-height: 46px;
  padding: 0 18px;
  font-size: 0.95rem;
}

.btn-primary:active,
.btn-ghost:active,
.btn-app:active,
.link-tg:active,
summary:active {
  transform: scale(0.97);
}

@media (hover: hover) and (pointer: fine) {

  .btn-primary:hover {
    filter: brightness(1.08);
  }

  .btn-ghost:hover {
    background: var(--raised);
    border-color: var(--gold-deep);
  }
}

/* --------------------------------------------------------------------------
   4. Header
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 64px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}

.brand img {
  border-radius: 9px;
}

.brand-name {
  font-family: var(--display);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.link-tg {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none;
  transition: transform 140ms var(--ease-out), color 140ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .link-tg:hover {
    color: var(--ink);
    border-color: var(--gold-deep);
  }
}

/* --------------------------------------------------------------------------
   5. Hero - asymmetric split, art column right
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  padding-block: clamp(40px, 7vw, 88px) clamp(48px, 8vw, 96px);
}

/* Declared gradient 2 of 2: the lacquer wash. */
.hero::before {
  content: "";
  position: absolute;
  inset: -30% 0 0;
  z-index: -1;
  background: radial-gradient(60% 55% at 62% 40%, var(--surface), transparent 70%);
  pointer-events: none;
}

.hero-grid {
  display: grid;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
}

@media (min-width: 900px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  }
}

.hero-lede {
  margin-top: 18px;
  max-width: 46ch;
  font-size: 1.08rem;
  color: var(--muted);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

.hero-note {
  margin-top: 18px;
  max-width: 46ch;
  font-size: 0.88rem;
  color: var(--faint);
}

/* The download card is the hero's asset, not a stack of loose text elements. */
.dl-card {
  padding: clamp(20px, 3.5vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

.dl-head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.dl-icon {
  width: 72px;
  height: 72px;
  border-radius: var(--r-md);
  flex: none;
}

.dl-name {
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.05;
}

.dl-sub {
  margin-top: 2px;
  font-size: 0.85rem;
  color: var(--faint);
}

.dl-bonus {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 20px;
  padding-block: 18px;
  border-block: 1px solid var(--line);
}

.dl-bonus .figure {
  font-family: var(--display);
  font-size: clamp(2.6rem, 12vw, 3.4rem);
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
}

.dl-bonus span {
  font-size: 0.95rem;
  color: var(--muted);
}

.specs {
  margin-top: 18px;
  display: grid;
  gap: 10px;
}

.specs>div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 0.95rem;
}

.specs dt {
  color: var(--faint);
}

.specs dd {
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   6. Trust band - divided row, hairlines, no cards
   -------------------------------------------------------------------------- */
.band {
  border-block: 1px solid var(--line);
  background: var(--surface);
}

.band-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 720px) {
  .band-row {
    grid-template-columns: repeat(4, 1fr);
  }
}

.band-row>div {
  padding: 22px 8px 22px 20px;
  border-left: 1px solid var(--line);
}

/* Dividers sit between items, never before the first one in a row. At 2-up that
   means the odd children, at 4-up only the first. A leading rule reads as a
   stray line hanging off the left edge of the container. */
.band-row>div:nth-child(odd) {
  border-left: 0;
  padding-left: 0;
}

.band-row>div:nth-child(-n+2) {
  border-bottom: 1px solid var(--line);
}

@media (min-width: 720px) {
  .band-row>div:nth-child(odd) {
    border-left: 1px solid var(--line);
    padding-left: 20px;
  }

  .band-row>div:first-child {
    border-left: 0;
    padding-left: 0;
  }

  .band-row>div:nth-child(-n+2) {
    border-bottom: 0;
  }
}

.band-row b {
  display: block;
  font-family: var(--display);
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
}

.band-row span {
  display: block;
  margin-top: 4px;
  font-size: 0.86rem;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   7. App listing - four across
   Eight cards. Two columns below 760px and four above, because both divide
   eight exactly. A three-column step was skipped on purpose: it would leave a
   two-card orphan row.
   -------------------------------------------------------------------------- */
.apps {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(10px, 1.8vw, 18px);
  margin-top: 30px;
}

@media (min-width: 760px) {
  .apps {
    grid-template-columns: repeat(4, 1fr);
  }
}

.app {
  display: flex;
  flex-direction: column;
  padding: clamp(10px, 1.4vw, 14px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  transition: border-color 140ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .app:hover {
    border-color: var(--gold-deep);
  }
}

.app-media {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--raised);
}

.app-media img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

/* The one place saffron appears outside the primary CTA. Green ink, not white:
   white on saffron measures 2.6:1 and fails. */
.app-flag {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--saffron);
  color: var(--bg);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.app-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding-top: 12px;
}

/* Real post titles run long and uneven. Three lines is the cap, and the block is
   reserved at three lines whether or not the title fills it, so the rating rows
   and the buttons line up across the whole row. */
.app h3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(3 * 1.35em);
  font-size: clamp(0.82rem, 1.5vw, 0.95rem);
  line-height: 1.35;
}

.app h3 a {
  text-decoration: none;
}

@media (hover: hover) and (pointer: fine) {
  .app h3 a:hover {
    color: var(--gold);
  }
}

.app-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 10px;
  margin-bottom: 14px;
  font-size: 0.85rem;
}

.app-meta .rate {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-weight: 600;
}

.app-meta .rate .ico {
  color: var(--gold);
}

/* Named .app-bonus, not .bonus. The card figure was originally a bare .bonus and
   it matched the bonus band's section rule, inheriting padding-block 96px top and
   bottom. That is 192px of invisible padding inside a 22px line, and it stretched
   every card in the listing by 195px. Same class-collision trap the WordPress
   note at the end of DESIGN.md describes, arrived at from the other direction. */
.app-meta .app-bonus {
  color: var(--gold);
  font-weight: 700;
}

/* Deliberately not the foil gradient. Eight of these next to one primary CTA
   would flatten the page's hierarchy, so the foil stays reserved for the single
   action the page exists for and these read one step quieter. */
.btn-app {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: auto;
  min-height: 42px;
  border: 1px solid var(--gold-deep);
  border-radius: var(--r-md);
  background: var(--raised);
  color: var(--gold);
  font: 700 0.88rem/1 var(--sans);
  text-decoration: none;
  transition: transform 140ms var(--ease-out), background-color 140ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .btn-app:hover {
    background: var(--line);
  }
}

/* Listing pagination.
   Every target is 44px so it is usable with a thumb, which is how this page is
   read. The current page is a filled gold chip rather than a coloured number,
   because a colour difference alone is not enough to tell someone where they
   are. */
.pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin-top: clamp(24px, 4vw, 36px);
}

.pager a,
.pager span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--muted);
  font-size: 0.95rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: transform 140ms var(--ease-out), border-color 140ms var(--ease-out),
    color 140ms var(--ease-out);
}

.pager .current {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--bg);
}

/* The gap marker is not interactive, so it gets no box and no target size. */
.pager .dots {
  min-width: 0;
  padding: 0 2px;
  border: 0;
  color: var(--faint);
}

.pager a:active {
  transform: scale(0.97);
}

@media (hover: hover) and (pointer: fine) {
  .pager a:hover {
    color: var(--ink);
    border-color: var(--gold-deep);
  }
}

/* Four across at 360px leaves each number about 76px of room, which is fine,
   but the Previous and Next words are what push the row to wrap. Shrink the
   padding rather than dropping the labels: arrows alone are a worse target and
   a worse label for a screen reader. */
@media (max-width: 420px) {

  .pager a,
  .pager span {
    padding: 0 9px;
    font-size: 0.88rem;
  }
}

/* --------------------------------------------------------------------------
   8. Bonus band - full bleed single statement
   -------------------------------------------------------------------------- */
.bonus {
  padding-block: clamp(56px, 9vw, 96px);
  border-block: 1px solid var(--gold-deep);
  background: var(--surface);
}

.bonus-inner {
  max-width: 720px;
  text-align: center;
}

/* The foil plate catches light. The sweep runs across the plate, never across
   the type, because gradient text is banned. */
.bonus-figure {
  position: relative;
  display: inline-block;
  overflow: hidden;
  padding: 10px 30px;
  border: 1px solid var(--gold-deep);
  border-radius: var(--r-lg);
  background: var(--raised);
}

.bonus-figure .shimmer {
  position: relative;
  z-index: 1;
  font-family: var(--display);
  font-size: clamp(3.2rem, 15vw, 5rem);
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
}

.bonus-figure::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
      transparent 42%,
      rgba(255, 255, 255, 0.17) 50%,
      transparent 58%);
  transform: translateX(-100%);
  animation: foil 5s var(--ease-out) infinite;
  pointer-events: none;
}

@keyframes foil {
  0% {
    transform: translateX(-100%);
  }

  55%,
  100% {
    transform: translateX(100%);
  }
}

.bonus h2 {
  margin-top: 26px;
}

.bonus p {
  margin-top: 14px;
  margin-inline: auto;
  max-width: 56ch;
  color: var(--muted);
}

.bonus .btn-primary {
  margin-top: 30px;
}

/* --------------------------------------------------------------------------
   9. Install steps - numbered sequence with a connecting rule
   Numbers appear here and nowhere else on the page, because this section
   genuinely is an ordered sequence.
   -------------------------------------------------------------------------- */
.steps {
  display: grid;
  gap: 0;
  margin-top: 32px;
}

.steps li {
  position: relative;
  padding: 24px 0 24px 62px;
  border-top: 1px solid var(--line);
}

.steps li:last-child {
  border-bottom: 1px solid var(--line);
}

.step-n {
  position: absolute;
  left: 0;
  top: 22px;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--gold-deep);
  border-radius: 999px;
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--gold);
  background: var(--bg);
}

/* The rule that connects the nodes into a sequence. */
.steps li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 21px;
  top: 64px;
  bottom: -4px;
  width: 1px;
  background: var(--line);
}

.steps p {
  margin-top: 8px;
  max-width: 68ch;
  color: var(--muted);
}

@media (min-width: 900px) {
  .steps {
    grid-template-columns: repeat(3, 1fr);
    gap: 0 34px;
  }

  .steps li {
    padding: 26px 0 0;
    border-top: 1px solid var(--line);
    border-bottom: 0;
  }

  .steps li:last-child {
    border-bottom: 0;
  }

  .step-n {
    position: static;
    margin-bottom: 16px;
  }

  .steps li:not(:last-child)::before {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   10. FAQ - native details, works with scripting off
   -------------------------------------------------------------------------- */
.faq-wrap {
  max-width: 800px;
}

.faq-list {
  margin-top: 26px;
  border-top: 1px solid var(--line);
}

.faq-list details {
  border-bottom: 1px solid var(--line);
}

.faq-list summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 20px 2px;
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  transition: transform 140ms var(--ease-out), color 140ms var(--ease-out);
}

.faq-list summary::-webkit-details-marker {
  display: none;
}

.faq-list .caret {
  color: var(--gold);
  transition: transform 200ms var(--ease-out);
}

.faq-list details[open] .caret {
  transform: rotate(180deg);
}

.faq-list p {
  padding: 0 2px 22px;
  max-width: 68ch;
  color: var(--muted);
}

@media (hover: hover) and (pointer: fine) {
  .faq-list summary:hover {
    color: var(--gold);
  }
}

/* --------------------------------------------------------------------------
   11. Footer
   padding-block, never the padding shorthand. A shorthand resets .wrap's
   padding-inline and the footer goes flush to the viewport edge.
   -------------------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--line);
  background: var(--surface);
}

.footer-grid {
  display: grid;
  gap: 26px;
  /* Generous bottom padding clears the fixed download bar, which is about 70px
     tall plus the iOS safe-area inset. */
  padding-block: clamp(36px, 6vw, 56px) 104px;
}

@media (min-width: 760px) {
  .footer-grid {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 40px;
  }
}

.age-block {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 0.9rem;
  color: var(--muted);
}

.age-mark {
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  flex: none;
  border: 2px solid var(--gold);
  border-radius: 999px;
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--gold);
}

.footer-body p {
  max-width: 74ch;
  color: var(--muted);
  font-size: 0.92rem;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin-top: 18px;
}

.footer-links a {
  color: var(--ink);
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .footer-links a:hover {
    border-color: var(--gold);
  }
}

.footer-copy {
  display: block;
  margin-top: 20px;
  font-size: 0.84rem;
  color: var(--faint);
}

/* --------------------------------------------------------------------------
   11b. Inner pages
   Privacy policy, disclaimer, about, contact. Client written prose pasted from
   the block editor, so the styling here has to cope with whatever markup comes
   out of it rather than with a known structure.
   -------------------------------------------------------------------------- */
.page-head {
  position: relative;
  padding-block: clamp(36px, 6vw, 64px) 0;
}

.page-head::before {
  content: "";
  position: absolute;
  inset: -40% 0 0;
  z-index: -1;
  background: radial-gradient(55% 60% at 50% 30%, var(--surface), transparent 70%);
  pointer-events: none;
}

.page-head h1 {
  max-width: 22ch;
}

.crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
  font-size: 0.88rem;
  color: var(--faint);
}

.crumbs a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}

@media (hover: hover) and (pointer: fine) {
  .crumbs a:hover {
    color: var(--gold);
    border-color: var(--gold-deep);
  }
}

.prose {
  max-width: 68ch;
  padding-block: clamp(28px, 4vw, 40px) clamp(48px, 8vw, 72px);
  color: var(--muted);
}

/* The global reset strips list markers so the app grid and nav can be lists
   without looking like lists. Prose is the one place they have to come back,
   because a privacy policy is mostly lists. */
.prose ul,
.prose ol {
  list-style: revert;
  padding-left: 1.5em;
  margin-block: 1em;
}

.prose li {
  margin-block: 0.4em;
}

.prose li::marker {
  color: var(--gold-deep);
}

.prose p {
  margin-block: 1em;
}

.prose h2 {
  margin-block: 1.8em 0.5em;
  font-size: clamp(1.35rem, 4vw, 1.75rem);
  color: var(--ink);
}

.prose h3 {
  margin-block: 1.5em 0.4em;
  font-size: 1.1rem;
  color: var(--ink);
}

.prose strong,
.prose b {
  color: var(--ink);
  font-weight: 700;
}

/* Underlined, not colour alone. Colour by itself is not enough to mark a link
   for someone who cannot separate gold from off-white. */
.prose a {
  color: var(--gold);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

@media (hover: hover) and (pointer: fine) {
  .prose a:hover {
    color: var(--ink);
  }
}

.prose blockquote {
  margin-block: 1.4em;
  margin-inline: 0;
  padding: 18px 22px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

.prose blockquote> :first-child {
  margin-top: 0;
}

.prose blockquote> :last-child {
  margin-bottom: 0;
}

.prose img {
  border-radius: var(--r-lg);
  margin-block: 1.4em;
}

.prose hr {
  margin-block: 2.2em;
  border: 0;
  border-top: 1px solid var(--line);
}

/* A pasted table is the most likely thing to blow out the page width on a
   phone, so it scrolls inside its own box instead of the body scrolling. */
.prose table {
  display: block;
  overflow-x: auto;
  width: 100%;
  margin-block: 1.4em;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.prose th,
.prose td {
  padding: 10px 14px;
  border: 1px solid var(--line);
  text-align: left;
}

.prose th {
  color: var(--ink);
  background: var(--surface);
  font-weight: 700;
}

.prose code {
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--raised);
  color: var(--ink);
  font-size: 0.9em;
}

.prose> :first-child {
  margin-top: 0;
}

/* --------------------------------------------------------------------------
   12. Sticky download bar
   Keeps the single action reachable through a long page. Revealed by JS once
   the hero CTA leaves the viewport; hidden entirely when scripting is off, so
   it can never sit on top of content it should not cover.
   -------------------------------------------------------------------------- */
.sticky-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: var(--z-bar);
  background: var(--bg);
  border-top: 1px solid var(--line);
  transform: translateY(100%);
  transition: transform 260ms var(--ease-out);
  padding-bottom: env(safe-area-inset-bottom, 0);
}

.sticky-bar.is-in {
  transform: translateY(0);
}

.sticky-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 12px;
}

.sticky-meta {
  font-size: 0.9rem;
  color: var(--muted);
}

.sticky-meta b {
  color: var(--gold);
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   13. Motion
   Entry sequences the read: what is it, what do I get, how do I get it.
   Content is visible by default; JS opts in to the reveal. A transition that
   never fires must never leave a section blank.
   -------------------------------------------------------------------------- */
/*
 * The hero entry is the only load animation on the page. A staggered reveal was
 * built for the game tiles and then removed: the tiles sit below the fold, so
 * almost nobody would have seen it, and gating their visibility on a class the
 * observer adds meant any renderer that skipped the observer shipped an empty
 * section. Motion that nobody sees is not worth a whole failure mode.
 */
@media (prefers-reduced-motion: no-preference) {
  .rise {
    animation: rise 520ms var(--ease-out) both;
    animation-delay: var(--d, 0ms);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {

  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation: none !important;
    transition-duration: 1ms !important;
  }

  .bonus-figure::after {
    display: none;
  }

  .sticky-bar {
    transition: none;
  }
}
