/*
 * Shared base styles: reset, typography, and common components (buttons, cards, dialogs,
 * snackbars, top app bar) used across every screen. Mirrors Material3 shapes/spacing used by
 * the Android app (ui/theme/Type.kt, and the various *Screen.kt files).
 */

/*
 * Poppins, self-hosted.
 *
 * This used to be `@import url('https://fonts.googleapis.com/css2?family=Poppins:...')` at the top
 * of this file, which is the slowest possible way to load a font: the browser had to fetch and
 * parse base.css before it even learned fonts.googleapis.com existed, then pay a DNS lookup + TLS
 * handshake there for a stylesheet, then a second DNS lookup + TLS handshake at fonts.gstatic.com
 * for the files themselves — three serialised round trips to two extra hosts before the first
 * glyph could start downloading. Serving the same woff2 files from this origin removes all of
 * that: they are discovered as soon as this stylesheet is parsed, ride the connection the page is
 * already using, and are cached for a year (see WebConfig#addResourceHandlers).
 *
 * Only the four weights the app actually uses are here — the old import also pulled 300, which
 * nothing references. Subsetting matches what Google Fonts serves, and the `unicode-range` guards
 * mean latin-ext is only downloaded when a nickname actually contains one of its characters.
 *
 * `font-display: swap` keeps text readable in the fallback face from the very first paint, so a
 * slow connection never blocks the puzzle behind a font.
 */

/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/poppins-400-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;
}

/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/poppins-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/poppins-500-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;
}

/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/poppins-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/poppins-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;
}

/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/poppins-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/poppins-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;
}

/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/poppins-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  /* Disables the double-tap-to-zoom gesture (and its 300ms tap delay) on touch devices. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}

body {
  /* The emoji faces are part of the stack, not an afterthought: without them a browser whose
     generic sans happens to carry a monochrome glyph draws 🪙 as a grey circle and 👑 as a grey
     outline, which is exactly what the coin costs and leader badges looked like. Naming the
     colour-emoji faces makes every emoji in the app render the way it does on Android. */
  font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial,
    sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Twemoji Mozilla',
    'Android Emoji', EmojiOne Color, 'Segoe UI Symbol';
  background: var(--background);
  color: var(--on-background);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

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

button, input {
  font-family: inherit;
}

button, a, [role="button"] {
  touch-action: manipulation;
}

/* -------------------------------------------------------------------------
 * Layout shells
 * ---------------------------------------------------------------------- */

.app-shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--background);
}

.topbar {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: 8px 20px;
  position: relative;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.topbar-title {
  flex: 1;
  text-align: center;
  font-weight: 700;
  font-size: 1.1rem;
}

.icon-button {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 1.3rem;
  /* Anchors the unread badge (.notification-dot) to the button rather than the page. */
  position: relative;
}
.icon-button:hover { background: rgba(0,0,0,0.06); }
html[data-theme="dark"] .icon-button:hover { background: rgba(255,255,255,0.08); }

.settings-icon {
  width: 24px;
  height: 24px;
  color: var(--primary);
}

.page-content {
  flex: 1;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 16px 20px 32px;
  display: flex;
  flex-direction: column;
}

.centered-page {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px;
  max-width: 520px;
  margin: 0 auto;
  width: 100%;
}

/* Desktop: give the app a constrained "phone-like" column with generous side gutters,
   so it reads as a native app card rather than a stretched website. */
@media (min-width: 900px) {
  .page-content, .centered-page, .topbar {
    max-width: 560px;
  }
  .app-shell {
    background: var(--background);
  }
}

/* -------------------------------------------------------------------------
 * Typography scale (subset of Material3 type tokens actually used)
 * ---------------------------------------------------------------------- */

h1, h2, h3, p { margin: 0; }

.text-display-large { font-size: 3.25rem; font-weight: 700; line-height: 1.15; }
.text-headline-large { font-size: 2rem; font-weight: 700; line-height: 1.2; }
.text-headline-medium { font-size: 1.75rem; font-weight: 700; line-height: 1.25; }
.text-headline-small { font-size: 1.5rem; font-weight: 700; line-height: 1.3; }
.text-title-large { font-size: 1.375rem; font-weight: 700; line-height: 1.3; }
.text-title-medium { font-size: 1rem; font-weight: 600; line-height: 1.4; }
.text-title-small { font-size: 0.875rem; font-weight: 600; line-height: 1.4; }
.text-body-large { font-size: 1rem; font-weight: 400; line-height: 1.5; letter-spacing: 0.02em; }
.text-body-medium { font-size: 0.875rem; font-weight: 400; line-height: 1.4; }
.text-body-small { font-size: 0.75rem; font-weight: 400; line-height: 1.35; }
.text-label-large { font-size: 0.875rem; font-weight: 600; }
.text-label-medium { font-size: 0.75rem; font-weight: 600; }
.text-label-small { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.06em; }

.text-muted { color: var(--on-surface-variant); }
.text-primary { color: var(--primary); }
.text-secondary { color: var(--secondary); }
.text-error { color: var(--error); }
.text-center { text-align: center; }

/* -------------------------------------------------------------------------
 * Card
 * ---------------------------------------------------------------------- */

.card {
  background: var(--surface);
  border-radius: 20px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}

.card-flat {
  background: var(--surface-container-lowest);
  border-radius: 16px;
  border: 1px solid var(--outline-variant);
}

/* -------------------------------------------------------------------------
 * Buttons (filled / tonal / outlined / text)
 * ---------------------------------------------------------------------- */

.btn {
  appearance: none;
  border: none;
  border-radius: 18px;
  padding: 14px 20px;
  font-size: 1rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-decoration: none;
  transition: opacity 0.15s ease, transform 0.05s ease;
  width: 100%;
  min-height: 52px;
}
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }

.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-secondary { background: var(--secondary); color: var(--on-secondary); }
.btn-outlined {
  background: transparent;
  color: var(--primary);
  border: 1.5px solid var(--outline);
}
.btn-outlined-error {
  background: transparent;
  color: var(--error);
  border: 1.5px solid var(--outline);
}
.btn-text {
  background: transparent;
  color: var(--primary);
  width: auto;
  min-height: auto;
  padding: 10px 14px;
}
.btn-error { background: var(--error); color: var(--on-error); }
/* The buy-box cost badge (Keyboard Themes / Nickname Borders / Profile Icons) reads white
   while affordable, red once the player can't cover the price. */
.cost-unaffordable { color: #ff6b6b !important; }
.btn-small {
  width: auto;
  min-height: 36px;
  padding: 8px 16px;
  font-size: 0.875rem;
  border-radius: 16px;
}

.btn-google {
  background: var(--google-btn-bg);
  color: var(--google-btn-fg);
  border: 1px solid var(--google-btn-border);
}

.btn-play-store {
  background: var(--surface-variant);
  color: var(--on-surface);
  border: 1.5px solid var(--outline);
}
.btn-play-store svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.spinner {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2.5px solid currentColor;
  border-right-color: transparent;
  animation: spin 0.7s linear infinite;
  display: inline-block;
}
.spinner-page {
  width: 36px;
  height: 36px;
  border-width: 3px;
  color: var(--primary);
}
@keyframes spin { to { transform: rotate(360deg); } }

/* -------------------------------------------------------------------------
 * Dialogs
 * ---------------------------------------------------------------------- */

.dialog-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 100;
}
.dialog-backdrop[hidden] { display: none; }

.dialog {
  background: var(--surface-container-high);
  border-radius: 24px;
  padding: 24px;
  max-width: 420px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}

/* Almost-full-window variant, e.g. the game screen's "How to Play" dialog: a tall card with a
 * scrollable body between a fixed header and a fixed footer button, rather than the compact
 * shrink-to-content default above. */
.dialog.dialog-fullscreen {
  max-width: 600px;
  height: 90vh;
  display: flex;
  flex-direction: column;
  overflow-y: hidden;
}
.dialog.dialog-fullscreen .rules-list {
  flex: 1;
  overflow-y: auto;
  margin-top: 20px;
}
.dialog.dialog-fullscreen .rules-section + .rules-section { margin-top: 20px; }

.dialog-icon-circle {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--primary-container);
  color: var(--on-primary-container);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  margin: 0 auto 16px;
}

.field {
  width: 100%;
  padding: 14px 14px;
  border-radius: 14px;
  border: 1.5px solid var(--outline-variant);
  background: var(--surface-container-lowest);
  color: var(--on-surface);
  font-size: 1rem;
  margin-bottom: 12px;
}
.field:focus { outline: none; border-color: var(--primary); }

.error-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--error-container);
  color: var(--on-error-container);
  border-radius: 12px;
  padding: 10px 12px;
  font-size: 0.8rem;
  margin-bottom: 12px;
}

/* -------------------------------------------------------------------------
 * Snackbar
 * ---------------------------------------------------------------------- */

.snackbar-host {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 200;
  pointer-events: none;
}
.snackbar {
  background: var(--on-surface);
  color: var(--surface);
  border-radius: 10px;
  padding: 14px 18px;
  font-size: 0.875rem;
  max-width: 560px;
  margin: 0 auto;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  animation: snackbar-in 0.2s ease;
}
@keyframes snackbar-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* -------------------------------------------------------------------------
 * Divider / misc
 * ---------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
 * Coin
 *
 * Drawn rather than typed. The 🪙 emoji is at the mercy of whatever emoji font the browser
 * happens to have: on several it lands on a monochrome glyph and the app's coins turned up as
 * grey circles. This is the same gold token Android shows, on every platform, and it scales with
 * the text around it because it is sized in em.
 * ---------------------------------------------------------------------- */
.coin {
  display: inline-block;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  vertical-align: -0.13em;
  background:
    radial-gradient(circle at 34% 28%, #FFF0B8 0%, #FFD75E 38%, #F2B01F 68%, #C6820D 100%);
  box-shadow:
    inset 0 0 0 0.09em rgba(255, 246, 200, 0.75),
    inset 0 -0.06em 0.12em rgba(140, 90, 0, 0.45);
  flex-shrink: 0;
}

.divider {
  border: none;
  border-top: 1px solid var(--outline-variant);
  margin: 8px 0;
}

/* Background-free mark: rounding it or adding a shadow would frame empty pixels. */
.logo-img {
  display: block;
}

.hidden { display: none !important; }

/* -------------------------------------------------------------------------
 * Notification dot (unread custom scoreboard invitations)
 * ---------------------------------------------------------------------- */

/* The gear button already positions its icon; the dot rides in its top-right corner. */
.icon-button { position: relative; }

.notification-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--error);
  flex-shrink: 0;
  display: inline-block;
}

.icon-button .notification-dot {
  position: absolute;
  top: 8px;
  right: 8px;
  box-shadow: 0 0 0 2px var(--background);
}

/* Anchors an unread dot to a full-width button (Themes on Home, Buy Box on the Themes screen). */
.btn-dot-wrap {
  position: relative;
  display: flex;
  width: 100%;
  min-width: 0;
}
.btn-dot-wrap > .btn { flex: 1; }
.btn-dot-wrap > .notification-dot {
  position: absolute;
  top: 8px;
  right: 10px;
  pointer-events: none;
}

/* -------------------------------------------------------------------------
 * Floating action button
 * ---------------------------------------------------------------------- */

.fab {
  position: fixed;
  right: 20px;
  /* Sits clear of the iOS home indicator and the Android gesture bar. */
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  width: 56px;
  height: 56px;
  border: none;
  border-radius: 18px;
  background: var(--primary);
  color: var(--on-primary);
  font-size: 1.9rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 16px var(--shadow-color);
  z-index: 50;
}
.fab:active { transform: scale(0.96); }

/* Keeps the button beside the app column instead of at the far edge of a wide window.
   The column is `.page-content`: 640px wide with 20px of padding, so its inner right edge sits at
   `50% + 300px` once the window is wider than the column. */
@media (min-width: 680px) {
  .fab {
    right: calc(50% - 300px);
  }
}

/* The "+N starting points" line under a cosmetic collection's unlock count. Muted while the
   bonus is unearned, full strength with a green tick once the collection is complete. */
.collection-bonus { display: flex; align-items: center; gap: 4px; margin-top: 2px; }
.collection-bonus-label { font-size: 0.8125rem; color: var(--on-surface-variant); }
.collection-bonus.complete .collection-bonus-label {
  color: var(--on-surface);
  font-weight: 700;
}
.collection-bonus-tick { color: #4CAF50; font-weight: 700; font-size: 0.875rem; }
.collection-bonus-help {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  margin-left: 2px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--outline);
  background: transparent;
  color: var(--on-surface-variant);
  font-family: inherit;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.collection-bonus-help:hover { background: rgba(0, 0, 0, 0.06); }
html[data-theme="dark"] .collection-bonus-help:hover { background: rgba(255, 255, 255, 0.08); }

/* The tooltip is positioned against this, not the page, so it follows the question mark wherever
   the header lands. */
.collection-bonus-anchor { position: relative; display: inline-flex; align-items: center; }

.collection-bonus-tip {
  position: absolute;
  /* Below the anchor rather than above it: these lines sit near the top of the screen, where
     there is nothing above them to open into. */
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  width: max-content;
  /* Never wider than the viewport's usable width, however long the sentence is. */
  max-width: min(260px, calc(100vw - 32px));
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--inverse-surface);
  color: var(--inverse-on-surface);
  font-size: 0.8125rem;
  line-height: 1.35;
  text-align: left;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
  /* Hidden without display:none so it keeps its size for the transform above. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 120ms ease-out;
}
.collection-bonus-tip.open { opacity: 1; visibility: visible; }

/* The little arrow pointing back at the question mark. */
.collection-bonus-tip::before {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-bottom-color: var(--inverse-surface);
}

/* The Home screen's top row: Replay Tutorial and the Google Play link, half the width each.
   Both are tighter than a normal full-width button so their labels still fit on one line at half
   the column's width on a narrow phone. */
.home-top-actions { display: flex; gap: 10px; width: 100%; }
.home-top-actions > .btn {
  flex: 1;
  min-width: 0;
  padding-left: 12px;
  padding-right: 12px;
  gap: 8px;
  font-size: 0.9375rem;
}

/* -------------------------------------------------------------------------
 * Bottom navigation (spec §2)
 *
 * The four top-level destinations — Home, Events, Themes, Store. Themes and Store used to be two
 * more buttons stacked under the hero card on Home; they are tabs now, so every one of the four is
 * one tap away from any of the others.
 *
 * Rendered by js/bottomNav.js into whatever page carries a `<nav class="bottom-nav">` placeholder.
 * The bar is fixed to the viewport, so each page that shows one also carries `has-bottom-nav` on
 * <body>, which reserves the matching space at the end of the scroll.
 * ---------------------------------------------------------------------- */

:root {
  /* 52px of tap target plus the bar's own padding; the safe-area inset is what an iPhone's home
     indicator needs underneath it. Shared by the bar itself, the space each page reserves at the
     end of its scroll, and anything else that sticks to the bottom of a page carrying one. */
  --bottom-nav-height: calc(64px + env(safe-area-inset-bottom, 0px));
}

.bottom-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  gap: 4px;
  background: var(--surface-container-lowest);
  border-top: 1px solid var(--outline-variant);
  padding: 6px 12px calc(6px + env(safe-area-inset-bottom, 0px));
}

.bottom-nav-inner {
  display: flex;
  width: 100%;
  max-width: 640px;
  gap: 4px;
}

@media (min-width: 900px) {
  .bottom-nav-inner { max-width: 560px; }
}

.bottom-nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 52px;
  border: none;
  border-radius: 16px;
  background: transparent;
  color: var(--on-surface-variant);
  cursor: pointer;
  text-decoration: none;
  font-size: 0.6875rem;
  font-weight: 600;
  transition: background 120ms ease-out, color 120ms ease-out;
}

.bottom-nav-item svg { width: 24px; height: 24px; fill: currentColor; }
.bottom-nav-item:hover { background: rgba(0, 0, 0, 0.05); }
html[data-theme="dark"] .bottom-nav-item:hover { background: rgba(255, 255, 255, 0.07); }

.bottom-nav-item.active {
  color: var(--primary);
  background: var(--primary-container);
}

/* The bar floats over the page, so the scroll has to end above it rather than under it. */
body.has-bottom-nav .page-content { padding-bottom: calc(var(--bottom-nav-height) + 24px); }

/* A page's own sticky footer — the Themes screen's "Open Box" bar — sticks to the bottom of the
   viewport, which is now where the navigation bar is. Lift it by the bar's height so the two sit
   on top of each other instead of one behind the other. */
body.has-bottom-nav .themes-footer { bottom: var(--bottom-nav-height); }

/* -------------------------------------------------------------------------
 * "About the game" section (.app-seo)
 *
 * Sits below the game on the two /app/ pages a crawler is allowed to fetch —
 * home.html and index.html. Everything above it on those pages is drawn by
 * JavaScript after an API call, so a fetch of the raw HTML used to come back
 * with nothing describing the game at all: the only prose in the document was
 * the text of three hidden dialogs ("Choose a Nickname", "Connection Problem",
 * "You have solved all extra puzzles!"). That is what a search engine and the
 * only text a search engine saw at the game's own URL.
 *
 * It is deliberately real, visible content rather than markup hidden from
 * players and shown only to crawlers: it renders for everyone, sits after the
 * game so it never comes between a player and today's puzzle, and it is the
 * only route from inside the app back to the guide, the archive and the legal
 * pages.
 *
 * On home.html it sits behind a native <details> (.app-seo-details) so its
 * length doesn't push the game down the page — collapsed by default, but for
 * every visitor alike, crawler included. A player who opens it sees the exact
 * same content a crawler already could; that sameness is what keeps this an
 * accordion instead of the cloaking this section exists to avoid.
 * ---------------------------------------------------------------------- */

.app-seo {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 8px 20px 32px;
  color: var(--on-surface-variant);
  font-size: 0.875rem;
  line-height: 1.55;
}

/* The bottom navigation bar is fixed over the page, so this section — which is
   below .page-content and therefore past the padding that clears it — has to
   end above the bar itself. */
body.has-bottom-nav .app-seo { padding-bottom: calc(var(--bottom-nav-height) + 24px); }

/* ...and .page-content no longer has to, when this section follows it: the bar's
   clearance is now the section's job, and leaving it on both opened a bar-height
   gap between the game and the divider below it. */
body.has-bottom-nav .page-content:has(+ .app-seo) { padding-bottom: 24px; }

.app-seo-divider {
  border: 0;
  border-top: 1px solid var(--outline-variant);
  margin: 0 0 20px;
}

/* The <summary> stands in for the old h1 on home.html: same size/weight, plus
   the chevron and the removed native marker below. */
.app-seo-details summary {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--on-surface);
  margin: 0 0 10px;
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.app-seo-details summary::-webkit-details-marker { display: none; }

.app-seo-details summary::after {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--on-surface-variant);
  border-bottom: 2px solid var(--on-surface-variant);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}

.app-seo-details[open] summary::after {
  transform: rotate(-135deg);
}

.app-seo h2 {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--on-surface);
  margin: 18px 0 6px;
}

.app-seo p {
  margin: 0 0 10px;
}

.app-seo ul {
  margin: 0 0 10px;
  padding-left: 20px;
}

.app-seo li {
  margin-bottom: 4px;
}

.app-seo a {
  color: var(--primary);
}

.app-seo-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 16px;
  font-weight: 600;
}
