/* Sidekick Arcade site styles. Mobile first: the base rules are for phones, wider screens add to them.
   Colors come from docs/architecture.md (Palette). Fonts are self-hosted from /assets/fonts/ (OFL). */

/* ----- fonts ----- */

@font-face {
  font-family: "Fredoka";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/fredoka-latin.woff2?v=27d49d7c83") 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: "Fredoka";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/fredoka-latin-ext.woff2?v=337681f6b8") 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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin.woff2?v=20fc9b6fc6") 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: "Nunito";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-ext.woff2?v=511ce96737") 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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ----- tokens ----- */

:root {
  --sky: #7CC8FF;
  --ink: #1E2A44;
  --cream: #FFF8EC;
  --sun: #FFD23F;
  --pink: #FF6B9A;
  --mint: #4CD98A;
  --violet: #8B6CFF;
  --orange: #FF9F43;
  --felt: #2E9E6A;
  --wood: #C9803F;
  --gold: #E9A21C;
  /* Darker pink and felt for text: the bright ones fail WCAG contrast on cream and white.
     --pink-text passes only at large sizes (the wordmark, 3.6:1); small text uses --error-text (5.1:1). */
  --pink-text: #E8457A;
  --felt-text: #1F7A50;
  --error-text: #C2334F;

  --bg: var(--cream);
  --text: var(--ink);
  --muted: #4A5675;
  --panel: #FFFFFF;
  --rule: rgba(30, 42, 68, 0.14);
  /* Soft fills behind text (notices, your board row, owned items). Dark mode deepens them. */
  --tint-sun: #FFF2BF;
  --tint-mint: #DDF7E8;
  --tint-violet: #F1EDFF;
  --tint-gold: #FFF6D6;
  --tint-red: #FFD9D6;
  --tint-gray: #E8ECF5;
  --code-bg: rgba(30, 42, 68, 0.08);

  --font-display: "Fredoka", "Nunito", ui-rounded, system-ui, sans-serif;
  --font-body: "Nunito", ui-rounded, system-ui, -apple-system, "Segoe UI", sans-serif;

  --gutter: 16px;
  --maxw: 1180px;
  --radius: 18px;
  --radius-sm: 12px;
  --border: 3px solid var(--ink);
  --chunk: 0 4px 0 var(--ink);
  --chunk-lg: 0 6px 0 var(--ink);
  --touch: 44px;
  --header-h: 60px;
  --bar-h: 52px;
  --safe-b: env(safe-area-inset-bottom, 0px);

  color-scheme: light;
}

/* Neighborhood accent colors, used by sections, chips and category heroes. */
[data-color="mint"] { --accent: var(--mint); --accent-soft: #DDF7E8; }
[data-color="violet"] { --accent: var(--violet); --accent-soft: #E9E3FF; }
[data-color="sun"] { --accent: var(--sun); --accent-soft: #FFF2BF; }
[data-color="sky"] { --accent: var(--sky); --accent-soft: #DDF0FF; }
[data-color="felt"] { --accent: var(--felt); --accent-soft: #D6F0E2; }
[data-color="wood"] { --accent: var(--wood); --accent-soft: #F7E6D2; }
[data-color="orange"] { --accent: var(--orange); --accent-soft: #FFE6CC; }
[data-color="pink"] { --accent: var(--pink); --accent-soft: #FFE0EA; }
[data-color="teal"] { --accent: #2EC4B6; --accent-soft: #D5F5F1; }

/* ----- base ----- */

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

[hidden] {
  display: none !important;
}

/* The footer's Big text switch (settings.big): every rem on the site's pages grows by a fifth.
   Games draw on their own canvas and keep their size. */
html.big-text {
  font-size: 118.75%;
}

html.big-text .daily {
  flex-wrap: wrap;
}

html.big-text .daily > * {
  min-width: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 12px);
  /* No rubber-band bounce: on phones it pulled the dark footer away from the page edge. */
  overscroll-behavior-y: none;
  background: var(--bg);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  overflow-wrap: break-word;
  min-height: 100vh;
  position: relative;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection {
  background: rgba(255, 210, 63, 0.6);
  color: var(--ink);
}

body.is-locked {
  overflow: hidden;
}

img,
svg,
canvas,
video {
  max-width: 100%;
}

img {
  height: auto;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  margin: 0 0 0.5em;
  color: var(--text);
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 {
  font-size: clamp(1.8rem, 7vw, 3rem);
}

h2 {
  font-size: clamp(1.3rem, 4.6vw, 1.75rem);
}

h3 {
  font-size: 1.15rem;
}

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

a {
  color: var(--text);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

button {
  font: inherit;
  color: inherit;
}

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

code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: var(--code-bg);
  padding: 0 4px;
  border-radius: 4px;
  overflow-wrap: anywhere;
}

:focus-visible {
  outline: 3px solid var(--violet);
  outline-offset: 3px;
  border-radius: 8px;
}

.i {
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  flex: 0 0 auto;
  vertical-align: -0.22em;
}

.wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

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

main {
  position: relative;
  z-index: 1;
  padding-bottom: 40px;
}

main:focus {
  outline: none;
}

.skip-link {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 100;
  background: var(--sun);
  color: var(--ink);
  border: var(--border);
  border-radius: 12px;
  padding: 10px 16px;
  font-weight: 800;
  text-decoration: none;
  min-height: var(--touch);
  display: inline-flex;
  align-items: center;
}

.skip-link:focus {
  top: 8px;
}

.lede {
  font-size: 1.08rem;
  max-width: 60ch;
}

.small-note {
  font-size: 0.92rem;
  color: var(--muted);
}

.empty-note {
  color: var(--muted);
  font-weight: 700;
}

/* ----- buttons ----- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--touch);
  padding: 0 20px;
  border: var(--border);
  border-radius: 999px;
  background: var(--mint);
  color: var(--ink);
  box-shadow: var(--chunk);
  font: 800 1rem/1 var(--font-body);
  text-decoration: none;
  cursor: pointer;
  transition: transform 90ms ease, box-shadow 90ms ease;
}

.btn:active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--ink);
}

.btn[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn-sun {
  background: var(--sun);
}

.btn-ghost {
  background: var(--panel);
  color: var(--text);
  box-shadow: none;
  min-height: 40px;
  padding: 0 14px;
  border-width: 2px;
  font-size: 0.95rem;
}

.btn-ghost:active {
  transform: translateY(1px);
  box-shadow: none;
}

/* ----- header ----- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  border-bottom: var(--border);
  -webkit-backdrop-filter: saturate(1.4) blur(8px);
  backdrop-filter: saturate(1.4) blur(8px);
}

.header-row {
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--header-h);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--touch);
  color: var(--text);
  text-decoration: none;
  margin-right: auto;
}

.wordmark-mark {
  width: 36px;
  height: 36px;
}

.wordmark-text {
  font: 700 1.45rem/1 var(--font-display);
  letter-spacing: -0.02em;
}

.wordmark-text span {
  color: var(--pink-text);
}

.site-nav {
  display: none;
}

.site-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 4px;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  padding: 0 14px;
  border-radius: 999px;
  font-weight: 800;
  text-decoration: none;
}

@media (hover: hover) {
  .site-nav a:hover {
    background: var(--sun);
  }
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.coin-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 12px 0 6px;
  border: var(--border);
  border-radius: 999px;
  background: var(--panel);
  box-shadow: 0 3px 0 var(--ink);
  font: 800 1.02rem/1 var(--font-body);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

.coin-pill .i {
  width: 26px;
  height: 26px;
}

.coin-pill.is-bump {
  animation: bump 420ms ease;
}

.me-button {
  display: inline-flex;
  width: 44px;
  height: 44px;
  border: var(--border);
  border-radius: 50%;
  background: var(--sky);
  overflow: hidden;
  box-shadow: 0 3px 0 var(--ink);
}

.me-face {
  width: 100%;
  height: 100%;
}

@media (max-width: 359px) {
  :root {
    --gutter: 12px;
  }

  .wordmark-text {
    font-size: 1.2rem;
  }

  .wordmark-mark {
    width: 30px;
    height: 30px;
  }
}

@media (min-width: 900px) {
  .site-nav {
    display: block;
  }

  .wordmark {
    margin-right: 12px;
  }

  .site-nav {
    margin-right: auto;
  }
}

/* ----- homepage hero and town ----- */

.town {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 330px;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}

.town svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: calc(100% + 60px);
  transform: translate3d(0, var(--parallax, 0px), 0);
  will-change: transform;
}

.hero {
  padding: 22px 0 6px;
  display: grid;
  gap: 16px;
}

.hero-kicker {
  display: inline-block;
  margin: 0 0 8px;
  padding: 3px 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--sun);
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}

.hero h1 {
  margin-bottom: 8px;
  max-width: 14ch;
}

.hero .lede {
  margin: 0;
  max-width: 36ch;
}

/* Phones: the hero copy spans the whole width, so the lamps would stand behind the text. */
.town-lamps {
  display: none;
}

@media (min-width: 760px) {
  .town {
    height: 380px;
  }

  .town-lamps {
    display: inline;
  }

  .hero {
    grid-template-columns: minmax(0, 1fr) 340px;
    align-items: end;
    padding: 44px 0 12px;
  }
}

/* ----- daily bonus card ----- */

.daily {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 12px 12px 14px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk);
}

.daily-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border: var(--border);
  border-radius: 14px;
  background: var(--sun);
  color: var(--ink);
}

.daily-icon .i {
  width: 28px;
  height: 28px;
}

.daily.is-ready .daily-icon {
  animation: wiggle 2.2s ease-in-out infinite;
}

.daily-text {
  flex: 1 1 auto;
  min-width: 0;
}

.daily-title {
  display: block;
  text-wrap: balance;
  font: 600 1.08rem/1.2 var(--font-display);
}

.daily-sub {
  display: block;
  font-size: 0.88rem;
  color: var(--muted);
}

.streak {
  display: flex;
  gap: 4px;
  margin-top: 6px;
}

.streak span {
  width: 14px;
  height: 14px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--panel);
}

.streak span.is-on {
  background: var(--sun);
}

.daily .btn {
  flex: 0 0 auto;
  padding: 0 16px;
}

/* ----- finder: search and chips ----- */

.finder {
  position: relative;
  z-index: 2;
  margin-top: 18px;
  padding: 14px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk);
}

.no-js .finder {
  display: none;
}

.search {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--bg);
}

.search .i {
  width: 22px;
  height: 22px;
}

.search input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  border: 0;
  background: transparent;
  font: 700 1rem var(--font-body);
  color: var(--text);
  outline: none;
}

.search:focus-within {
  outline: 3px solid var(--violet);
  outline-offset: 2px;
}

.search input::-webkit-search-cancel-button {
  cursor: pointer;
}

/* Chip rows wrap; the sideways scrollers (.filters, .sort-pills, .move-row) keep one line. */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  padding: 0;
  margin: 0;
}

/* Chips scroll sideways on phones (one line, no wrap), and wrap on wider screens. */
.filters {
  flex-wrap: nowrap;
  margin: 10px -14px -4px;
  padding: 2px 14px 8px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Snap points respect the row's padding, so the first chip lines up with the search box. */
  scroll-padding-inline: 14px;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent 100%);
}

.filters::-webkit-scrollbar {
  display: none;
}

.chip,
.chip-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  color: var(--text);
  font: 800 0.95rem/1 var(--font-body);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  scroll-snap-align: start;
}

.chip .i {
  width: 16px;
  height: 16px;
}

@media (hover: hover) {
  .chip:hover,
  .chip-links a:hover {
    background: var(--accent-soft, #FFF2BF);
  }
}

.chip[aria-pressed="true"] {
  background: var(--accent, var(--sun));
  box-shadow: 0 3px 0 var(--ink);
}

.chip-live[aria-pressed="false"] {
  background: var(--tint-mint);
}

.chip-small {
  min-height: 36px;
  padding: 0 12px;
  font-size: 0.88rem;
}

.chip-links {
  flex-wrap: wrap;
}

.chip-links a::before {
  content: "";
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border: 2px solid var(--ink);
  border-radius: 3px;
  background: var(--accent, var(--sun));
}

@media (min-width: 760px) {
  .finder {
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr);
    gap: 12px;
    align-items: center;
  }

  .filters {
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* The homepage's search button: looks like a search box, opens the search sheet. */
.search-button {
  width: 100%;
  cursor: pointer;
  font: 700 1rem var(--font-body);
  color: var(--muted);
  text-align: left;
}

.search-button .search-label {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-hint {
  flex: 0 0 auto;
  white-space: nowrap;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--sun);
  color: var(--ink);
  font-size: 0.78rem;
  font-weight: 800;
}

/* Narrow phones: "209 games" alone, so "Search games" keeps room. */
@media (max-width: 359px) {
  .search-hint-more {
    display: none;
  }
}

@media (hover: hover) {
  .search-button:hover {
    background: var(--tint-sun);
  }
}

/* ----- the search sheet ----- */

.search-overlay {
  position: fixed;
  inset: 0;
  z-index: 65;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background: var(--bg);
  animation: sheet-in 220ms ease;
}

.search-top {
  position: sticky;
  top: 0;
  z-index: 2;
  padding-top: env(safe-area-inset-top, 0px);
  background: color-mix(in srgb, var(--bg) 96%, transparent);
  border-bottom: var(--border);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.search-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 68px;
}

.search-bar .search {
  flex: 1 1 auto;
  background: var(--panel);
}

.search-bar .pbtn-light {
  width: 48px;
  height: 48px;
  border: var(--border);
  border-radius: 50%;
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 3px 0 var(--ink);
}

@media (hover: hover) {
  .search-bar .pbtn-light:hover {
    background: var(--sun);
  }
}

.search-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  padding-top: 14px;
  padding-bottom: calc(40px + var(--safe-b));
}

.search-body > * {
  min-width: 0;
}

.filter-group {
  margin: 0 0 6px;
}

.filter-title {
  margin: 0 0 6px;
  font: 800 0.85rem/1.2 var(--font-body);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.filter-row {
  margin: 0 calc(-1 * var(--gutter));
  padding: 2px var(--gutter) 6px;
  overflow-x: auto;
  scrollbar-width: none;
}

.filter-row::-webkit-scrollbar {
  display: none;
}

.chip-filter {
  min-height: 40px;
  padding: 0 6px 0 14px;
  gap: 8px;
}

.chip-count {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--bg);
  border: 2px solid var(--ink);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.chip-filter[aria-pressed="true"] {
  background: var(--sun);
  box-shadow: 0 3px 0 var(--ink);
}

.chip-filter[aria-pressed="true"] .chip-count {
  background: var(--ink);
  color: var(--cream);
}

.chip-filter:disabled {
  opacity: 0.4;
  cursor: default;
}

.results-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin: 8px 0 10px;
}

.results-count {
  margin: 0;
  font: 600 1.35rem/1.2 var(--font-display);
}

.sort-pills {
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
}

.chip-sort[aria-checked="true"] {
  background: var(--ink);
  color: var(--cream);
}

.active-filters {
  flex-wrap: wrap;
  margin: 0 0 14px;
}

.chip-active {
  background: var(--sun);
  gap: 6px;
}

.chip-active .i {
  width: 14px;
  height: 14px;
}

.chip-clear {
  border-style: dashed;
}

.results-empty {
  display: grid;
  justify-items: center;
  gap: 10px;
  padding: 28px 16px;
  border: 3px dashed var(--ink);
  border-radius: var(--radius);
  background: var(--panel);
  text-align: center;
}

.results-empty p {
  margin: 0;
}

.empty-face {
  width: 80px;
  height: 80px;
  border: var(--border);
  border-radius: 50%;
  background: var(--sky);
}

@media (min-width: 900px) {
  .search-body {
    grid-template-columns: 290px minmax(0, 1fr);
    gap: 28px;
    align-items: start;
  }

  .search-filters {
    position: sticky;
    top: 90px;
    padding: 16px;
    border: var(--border);
    border-radius: var(--radius);
    background: var(--panel);
    box-shadow: var(--chunk);
  }

  .filter-row {
    flex-wrap: wrap;
    margin: 0;
    padding: 0 0 4px;
    overflow: visible;
  }

  .search-results .tile-grid {
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  }
}

.fact-tag a {
  color: var(--text);
}

/* ----- rows and neighborhoods ----- */

.row {
  margin: 28px 0 0;
}

.row-title {
  font-size: 1.3rem;
  margin-bottom: 12px;
}

.hood {
  margin: 34px 0 0;
}

.hood-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.hood-head h2 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}

.hood h2::before {
  content: "";
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border: 3px solid var(--ink);
  border-radius: 5px;
  background: var(--accent, var(--sun));
  transform: rotate(8deg);
}

.hood-count {
  margin: 2px 0 0;
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--muted);
}

.see-all {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  min-height: var(--touch);
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}

.see-all .i {
  width: 18px;
  height: 18px;
}

@media (hover: hover) {
  .see-all:hover {
    text-decoration: underline;
  }
}

/* A row of tiles: a side-scrolling shelf on phones, a grid on wider screens. */
.tile-row {
  list-style: none;
  margin: 0 calc(-1 * var(--gutter));
  padding: 4px var(--gutter) 14px;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(150px, 42%);
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 var(--gutter);
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.tile-row::-webkit-scrollbar {
  display: none;
}

.tile-row > .tile {
  scroll-snap-align: start;
}

.tile-row-feature {
  grid-auto-columns: minmax(240px, 78%);
}

.tile-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 12px;
}

@media (min-width: 600px) {
  .tile-row {
    grid-auto-columns: minmax(170px, 30%);
  }

  .tile-row-feature {
    grid-auto-columns: minmax(260px, 46%);
  }

  .tile-grid {
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 18px 16px;
  }
}

@media (min-width: 1024px) {
  .tile-row {
    margin: 0;
    padding: 4px 0 6px;
    grid-auto-flow: row;
    grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
    grid-auto-columns: auto;
    overflow: visible;
    gap: 20px 16px;
  }

  .tile-row-feature {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  }
}

/* ----- tiles ----- */

.tile {
  position: relative;
  min-width: 0;
}

.tile-link {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--panel);
  border: var(--border);
  border-radius: var(--radius);
  box-shadow: var(--chunk);
  overflow: hidden;
  color: var(--text);
  text-decoration: none;
  transition: transform 140ms ease, box-shadow 140ms ease;
}

/* Hover lift only with a real hover: on touch, the lift stuck to the last tile tapped. */
@media (hover: hover) {
  a.tile-link:hover {
    transform: translateY(-3px);
    box-shadow: var(--chunk-lg);
  }
}

a.tile-link:active {
  transform: translateY(2px);
  box-shadow: 0 2px 0 var(--ink);
}

a.tile-link:focus-visible {
  outline-offset: 4px;
  border-radius: var(--radius);
}

.tile-art {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  background: var(--sky);
  border-bottom: var(--border);
  overflow: hidden;
}

.tile-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.badge {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 2px 9px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  font: 800 0.72rem/1.4 var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.badge-new {
  background: var(--sun);
}

.badge-soon {
  background: var(--panel);
}

.tile-spark {
  position: absolute;
  top: 6px;
  right: 6px;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--sun);
  color: var(--ink);
}

.tile-spark .i {
  width: 16px;
  height: 16px;
  animation: twinkle 1.8s ease-in-out infinite;
}

.tile-body {
  display: block;
  padding: 9px 11px 11px;
}

.tile-title {
  display: block;
  font: 600 1.06rem/1.2 var(--font-display);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tile-meta {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 3px;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
}

.tile-meta .i {
  width: 16px;
  height: 16px;
}

.tile.is-soon .tile-link {
  box-shadow: 0 4px 0 rgba(30, 42, 68, 0.35);
  border-color: rgba(30, 42, 68, 0.55);
  cursor: default;
}

.tile.is-soon .tile-art img {
  filter: saturate(0.75);
  opacity: 0.88;
}

.tile.is-soon .tile-title {
  color: #39466A;
}

.tile-feature .tile-title {
  font-size: 1.3rem;
}

.tile-feature .tile-body {
  padding: 12px 14px 14px;
}

.tile-more .tile-link {
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 160px;
  background: var(--accent-soft, var(--cream));
  border-style: dashed;
  box-shadow: none;
}

.more-count {
  font: 700 2rem/1 var(--font-display);
}

.more-label {
  font-weight: 800;
}

/* Keep playing: small cards with the best score. */
.recent-row {
  list-style: none;
  margin: 0 calc(-1 * var(--gutter));
  padding: 2px var(--gutter) 10px;
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scrollbar-width: none;
}

.recent-row::-webkit-scrollbar {
  display: none;
}

/* Every card the same size: a fixed width, and each stretches to the tallest in the row (a long
   name like Brick Breaker wraps to two lines). */
.recent-row li {
  display: flex;
  flex: 0 0 auto;
}

.recent-row a {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 210px;
  padding: 6px 14px 6px 6px;
  border: var(--border);
  border-radius: 16px;
  background: var(--panel);
  box-shadow: 0 3px 0 var(--ink);
  text-decoration: none;
}

.recent-row img {
  width: 64px;
  height: 40px;
  border-radius: 9px;
  border: 2px solid var(--ink);
  object-fit: cover;
}

.recent-name {
  display: block;
  font: 600 1rem/1.2 var(--font-display);
}

.recent-best {
  display: block;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--muted);
}

.search-results {
  margin-top: 24px;
}

.coming-soon {
  margin: 0;
  padding: 18px 20px;
  border: 3px dashed var(--ink);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--panel) 70%, transparent);
  font-weight: 700;
}

/* ----- ad slots: every size is fixed in CSS so the layout never shifts ----- */

/* An ad-free plan (plan.js): no ad slot shows anywhere. */
.ad-free .ad-wrap,
.ad-free .billboard {
  display: none !important;
}

.ad-wrap {
  margin: 28px auto;
  width: fit-content;
  max-width: 100%;
}

.ad-label {
  display: block;
  margin-bottom: 4px;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.ad-slot {
  position: relative;
  display: block;
  max-width: 100%;
  border: var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: linear-gradient(100deg, var(--sun) 0%, var(--orange) 60%, var(--pink) 100%);
  color: var(--ink);
}

.ad-slot[data-size="728x90"] {
  width: 320px;
  aspect-ratio: 320 / 50;
}

.ad-slot[data-size="300x250"] {
  width: 300px;
  aspect-ratio: 300 / 250;
}

.ad-slot a.ad-link {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 100%;
  padding: 0 14px;
  color: var(--ink);
  text-decoration: none;
}

.ad-slot .ad-icon {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
}

.ad-slot .ad-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.ad-slot .ad-title {
  font: 600 1rem/1.15 var(--font-display);
}

.ad-slot .ad-copy {
  display: block;
  font-size: 0.74rem;
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ad-slot[data-size="728x90"] .ad-title {
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ad-slot .ad-cta {
  display: none;
}

.ad-slot[data-size="300x250"] a.ad-link {
  flex-direction: column;
  justify-content: center;
  text-align: center;
  padding: 18px;
  gap: 8px;
}

.ad-slot[data-size="300x250"] .ad-text {
  align-items: center;
}

.ad-slot[data-size="300x250"] .ad-title {
  font-size: 1.5rem;
}

.ad-slot[data-size="300x250"] .ad-copy,
.ad-slot[data-size="300x250"] .ad-cta {
  display: block;
}

.ad-slot[data-size="300x250"] .ad-icon {
  width: 72px;
  height: 72px;
}

.ad-slot .ad-cta {
  margin-top: 6px;
  padding: 6px 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  font-weight: 800;
  font-size: 0.85rem;
}

.billboard {
  margin: 34px 0 0;
  padding: 6px 0 2px;
  border-top: 2px dashed var(--rule);
  border-bottom: 2px dashed var(--rule);
}

.billboard .ad-wrap {
  margin: 16px auto;
}

@media (min-width: 760px) {
  .ad-slot[data-size="728x90"] {
    width: 728px;
    aspect-ratio: 728 / 90;
  }

  .ad-slot[data-size="728x90"] .ad-copy {
    font-size: 0.92rem;
  }

  .ad-slot[data-size="728x90"] .ad-icon {
    width: 34px;
    height: 34px;
  }

  .ad-slot[data-size="728x90"] .ad-title {
    font-size: 1.25rem;
  }

  .ad-slot[data-size="728x90"] .ad-cta {
    display: block;
    margin: 0 0 0 auto;
  }
}

/* ----- category pages ----- */

.cat-hero {
  background: var(--accent-soft, var(--cream));
  border-bottom: var(--border);
  padding: 4px 0 18px;
}

.cat-hero h1 {
  margin-top: 8px;
}

.cat-count {
  display: inline-block;
  margin: 0;
  padding: 4px 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  font-weight: 800;
  font-size: 0.88rem;
}

/* ----- breadcrumbs ----- */

.crumbs {
  font-size: 0.9rem;
  margin: 12px 0 0;
}

.crumbs ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 2px 8px;
}

.crumbs li + li::before {
  content: "/";
  margin-right: 8px;
  opacity: 0.5;
}

.crumbs a {
  font-weight: 700;
}

/* ----- game page: the theater ----- */

/* The game owns the screen. A full-width dark band holds the player: the console bar on top and the
   stage under it. On phones the site header is hidden and the theater fills the viewport; the page
   copy sits below, one tap (the info button) away. The engine letterboxes inside the canvas. */

.theater {
  position: relative;
  z-index: 3;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(139, 108, 255, 0.35), transparent 60%),
    var(--ink);
  border-bottom: var(--border);
}

.player {
  margin: 0 auto;
  width: 100%;
  height: 100svh;
  display: flex;
  flex-direction: column;
  color: var(--cream);
}

.player-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  height: var(--bar-h);
  padding: 0 8px;
  flex: 0 0 auto;
}

.player-title {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.player-name {
  font: 600 1.1rem/1.15 var(--font-display);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.player-best {
  font-size: 0.78rem;
  font-weight: 800;
  color: #C9D3E8;
}

.pbtn {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: 2px solid rgba(255, 248, 236, 0.85);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--cream);
  cursor: pointer;
  padding: 0;
  text-decoration: none;
}

@media (hover: hover) {
  .pbtn:hover {
    background: rgba(255, 255, 255, 0.16);
  }
}

.pbtn:active {
  transform: translateY(1px);
}

.pbtn:focus-visible {
  outline-color: var(--sun);
}

.pbtn .i {
  width: 20px;
  height: 20px;
}

.pbtn .i-down {
  transform: rotate(90deg);
}

.pbtn .i-off {
  display: none;
}

.pbtn[data-action="sound"][aria-pressed="false"] .i-on,
.pbtn[data-action="pause"][aria-pressed="true"] .i-on,
.pbtn[data-action="fullscreen"][aria-pressed="true"] .i-on {
  display: none;
}

.pbtn[data-action="sound"][aria-pressed="false"] .i-off,
.pbtn[data-action="pause"][aria-pressed="true"] .i-off,
.pbtn[data-action="fullscreen"][aria-pressed="true"] .i-off {
  display: block;
}

.pbtn[data-action="pause"][aria-pressed="true"] {
  background: var(--mint);
  border-color: var(--mint);
  color: var(--ink);
}

.coin-pill-bar {
  min-height: 36px;
  padding: 0 10px 0 4px;
  border-width: 2px;
  box-shadow: none;
  font-size: 0.95rem;
}

.coin-pill-bar .i {
  width: 24px;
  height: 24px;
}

.stage-frame {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  /* Cream, like the engine's loading screen, so the game appears without a dark flash. */
  background: var(--bg);
  overflow: hidden;
}

.stage-frame > canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  outline: none;
}

/* The game is the focus; a ring around it only helps keyboard users on wide screens. */
.stage-frame > canvas:focus,
.stage-frame > canvas:focus-visible {
  outline: none;
}

@media (min-width: 760px) and (hover: hover) {
  .stage-frame:has(canvas:focus-visible) {
    border-color: var(--sun);
  }
}

/* Phones, and touch tablets of any width (iPad: no hover, a finger for a pointer): no site
   header on game pages; the theater is the screen. The engine letterboxes the game into the full
   width, so a portrait game on a landscape tablet gets the whole height instead of a small frame.
   The same query is in game-shell.js (TOUCH_THEATER). */
@media (max-width: 759px), (hover: none) and (pointer: coarse) {
  body[data-page="play"] .site-header {
    display: none;
  }

  body[data-page="play"] {
    overscroll-behavior-y: none;
  }

  .player {
    height: 100svh;
    padding-top: env(safe-area-inset-top, 0px);
  }
}

/* iPhone Safari has no element Fullscreen API; on tablets the button stays (it hides the
   browser's toolbars). */
@media (max-width: 759px) {
  .pbtn-fs {
    display: none;
  }
}

@media (max-width: 359px) {
  .coin-pill-bar {
    display: none;
  }
}

/* Wider screens with a mouse or trackpad: the header stays, and the theater holds a framed stage
   as tall as the window. */
@media (min-width: 760px) and (hover: hover), (min-width: 760px) and (pointer: fine) {
  .theater {
    padding: 14px var(--gutter) 22px;
  }

  .pbtn-info {
    display: none;
  }

  .player {
    height: auto;
    max-width: calc((100svh - var(--header-h) - var(--bar-h) - 48px) * 9 / 16);
    min-width: 340px;
  }

  .player.is-landscape {
    max-width: min(100%, calc((100svh - var(--header-h) - var(--bar-h) - 48px) * 16 / 9));
  }

  .player-bar {
    padding: 0 2px 8px;
  }

  .stage-frame {
    flex: none;
    aspect-ratio: 9 / 16;
    border: 3px solid rgba(255, 248, 236, 0.9);
    border-radius: var(--radius);
    box-shadow: 0 8px 0 rgba(0, 0, 0, 0.35);
  }

  .player.is-landscape .stage-frame {
    aspect-ratio: 16 / 9;
  }
}

/* Docking: scrolled down, the player undocks into a mini window in the top corner (top, not
   bottom: phone toolbars move bottom-fixed things around), paused. Tapping it docks it back. */

.theater-hold {
  display: none;
}

.theater.is-holding .theater-hold {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: #C9D3E8;
  font-weight: 800;
}

.theater-hold .i {
  width: 44px;
  height: 44px;
  opacity: 0.6;
}

.dock-button {
  display: none;
}

.player.is-undocked {
  position: fixed;
  z-index: 55;
  top: calc(10px + env(safe-area-inset-top, 0px));
  right: 10px;
  left: auto;
  width: 92px;
  height: auto;
  min-width: 0;
  max-width: none;
  padding: 0;
  border: var(--border);
  border-radius: 16px;
  overflow: hidden;
  background: var(--ink);
  box-shadow: 0 5px 0 var(--ink), 0 12px 26px rgba(30, 42, 68, 0.28);
  animation: undock-in 240ms cubic-bezier(.2, 1.3, .4, 1);
}

.player.is-undocked .player-bar {
  display: none;
}

.player.is-undocked .stage-frame {
  flex: none;
  height: auto;
  aspect-ratio: 9 / 16;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.player.is-landscape.is-undocked {
  width: 170px;
}

.player.is-landscape.is-undocked .stage-frame {
  aspect-ratio: 16 / 9;
}

.player.is-undocked .dock-button {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0 0 8px;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.dock-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--sun);
  color: var(--ink);
  font: 800 0.8rem/1 var(--font-body);
  box-shadow: 0 2px 0 var(--ink);
}

.dock-pill .i {
  width: 12px;
  height: 12px;
}

@media (min-width: 760px) {
  .player.is-undocked {
    right: 20px;
    width: 140px;
  }

  .player.is-landscape.is-undocked {
    width: 260px;
  }
}

@media (min-width: 760px) and (hover: hover), (min-width: 760px) and (pointer: fine) {
  .player.is-undocked {
    top: calc(var(--header-h) + 14px);
  }
}

@keyframes undock-in {
  from { transform: scale(0.6) translateY(-20px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* Full screen (real, or the immersive fallback): the player covers everything. */
.player:fullscreen,
.player.is-immersive {
  position: fixed;
  inset: 0;
  z-index: 60;
  max-width: none;
  width: 100%;
  height: 100%;
  background: var(--ink);
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

.player:-webkit-full-screen {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  background: var(--ink);
}

.player:fullscreen .stage-frame,
.player.is-immersive .stage-frame {
  flex: 1 1 auto;
  aspect-ratio: auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.play-wrap {
  padding-top: 4px;
}

.play-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px 32px;
}

.play-main .ad-wrap {
  margin: 20px auto 8px;
}

.game-info {
  max-width: 68ch;
}

.game-info h1 {
  margin: 6px 0 10px;
}

.game-info h2 {
  margin-top: 1.5em;
}

.game-info .faq-q {
  font-size: 1rem;
  margin: 1.1em 0 0.3em;
}

.game-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 14px;
  padding: 12px 14px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--tint-violet);
  font-weight: 700;
  font-size: 0.92rem;
}

.game-notice p {
  margin: 0;
}

.game-notice .i {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  color: var(--violet);
}

.facts {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.facts li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  font-size: 0.86rem;
  font-weight: 800;
}

.facts a {
  text-decoration: none;
}

.facts .i {
  width: 18px;
  height: 18px;
}

.fact-coins {
  background: var(--tint-sun) !important;
}

.stat-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 16px;
}

.stat {
  padding: 10px 10px 8px;
  border: var(--border);
  border-radius: 14px;
  background: var(--panel);
}

.stat-label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.75rem;
  font-weight: 800;
  color: var(--muted);
  white-space: nowrap;
}

.stat-label .i {
  width: 14px;
  height: 14px;
}

.stat-value {
  display: block;
  font: 600 1.4rem/1.2 var(--font-display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.steps {
  padding-left: 1.4em;
  margin: 0 0 1em;
}

.steps li + li {
  margin-top: 6px;
}

.play-side .ad-wrap[data-for="game-side"] {
  display: none;
}

.related {
  margin-top: 28px;
}

.tile-grid-compact .tile-meta {
  display: none;
}

@media (min-width: 1024px) {
  .play-layout {
    grid-template-columns: minmax(0, 1fr) 300px;
    align-items: start;
    margin-top: 12px;
  }

  .play-side {
    position: sticky;
    top: calc(var(--header-h) + 16px);
  }

  .play-side .ad-wrap[data-for="game-side"] {
    display: block;
    margin: 6px 0 0;
  }

  .related {
    margin-top: 22px;
  }

  .related .tile-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
  }

  .related .tile-title {
    font-size: 0.95rem;
  }
}

/* ----- achievements ----- */

.ach-list {
  list-style: none;
  margin: 0 0 1em;
  padding: 0;
  display: grid;
  gap: 8px;
}

.ach {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--panel);
}

.ach-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: 2px solid var(--ink);
  border-radius: 12px;
  background: var(--tint-gray);
  color: #8A94AD;
}

.ach.is-done .ach-icon {
  background: var(--sun);
  color: var(--ink);
}

.ach-text {
  flex: 1 1 auto;
  min-width: 0;
}

.ach-name {
  display: block;
  font: 600 1rem/1.2 var(--font-display);
}

.ach-desc {
  display: block;
  font-size: 0.88rem;
  color: var(--muted);
}

.ach-unlock {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 3px;
  font-size: 0.78rem;
  font-weight: 800;
  color: #6A4FE0;
}

.ach-unlock .i {
  width: 14px;
  height: 14px;
}

.ach-reward {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.ach.is-done .ach-reward {
  color: var(--felt-text);
}

.ach.is-done .ach-reward .i-coin {
  display: none;
}

/* Tiers: the medal colors, on earned achievements and on the tier labels and chips. */
.ach[data-tier="bronze"].is-done .ach-icon,
.ach[data-tier="bronze"] .ach-tier,
.chip-tier[data-tier="bronze"] .tier-dot {
  background: #F2B58A;
}

.ach[data-tier="silver"].is-done .ach-icon,
.ach[data-tier="silver"] .ach-tier,
.chip-tier[data-tier="silver"] .tier-dot {
  background: #D6DEEC;
}

.ach[data-tier="gold"].is-done .ach-icon,
.ach[data-tier="gold"] .ach-tier,
.chip-tier[data-tier="gold"] .tier-dot {
  background: var(--sun);
}

.ach[data-tier="diamond"].is-done .ach-icon,
.ach[data-tier="diamond"] .ach-tier,
.chip-tier[data-tier="diamond"] .tier-dot {
  background: #A8EEF5;
}

.ach-tier {
  display: inline-block;
  margin-left: 8px;
  padding: 0 7px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  font: 800 0.66rem/1.5 var(--font-body);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: 2px;
}

.ach:not(.is-done) .ach-tier {
  /* Not earned yet: a dashed edge. No fading, which took the text below WCAG contrast. */
  border-style: dashed;
}

/* Progress toward an achievement not yet earned. */
.ach-progress {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 5px;
}

.ach-bar {
  flex: 1 1 auto;
  max-width: 220px;
  height: 8px;
  overflow: hidden;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
}

.ach-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--sun);
}

.ach-count {
  flex: 0 0 auto;
  font-size: 0.78rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.ach-meta {
  display: block;
  margin-top: 3px;
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--muted);
}

.ach-meta a {
  color: inherit;
}

/* ----- avatar studio ----- */

.studio {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  margin-top: 10px;
}

.studio > * {
  min-width: 0;
}

.studio-stage .stage-frame.is-avatar {
  aspect-ratio: 9 / 8;
  max-width: 520px;
  margin: 0 auto;
  border: var(--border);
  border-radius: var(--radius);
  box-shadow: var(--chunk);
  background: var(--sky);
}

.move-row {
  flex-wrap: nowrap;
  margin: 10px calc(-1 * var(--gutter)) 0;
  padding: 2px var(--gutter) 8px;
  overflow-x: auto;
  scrollbar-width: none;
}

.move-row::-webkit-scrollbar {
  display: none;
}

.studio-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.studio-head h1 {
  margin: 0;
  font-size: clamp(1.6rem, 6vw, 2.2rem);
}

.tabs {
  display: flex;
  gap: 6px;
  margin: 12px calc(-1 * var(--gutter)) 0;
  padding: 2px var(--gutter) 10px;
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
  display: none;
}

.tab {
  flex: 0 0 auto;
  min-height: 42px;
  padding: 0 16px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  font-weight: 800;
  cursor: pointer;
}

.tab[aria-selected="true"] {
  background: var(--ink);
  color: var(--cream);
}

.tab-panel {
  padding: 14px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk);
}

.panel-title {
  margin: 0 0 10px;
  font-size: 1rem;
  font-family: var(--font-body);
  font-weight: 800;
}

.option-grid {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

.option {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 6px 4px 8px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--bg);
  cursor: pointer;
  text-align: center;
}

.option canvas {
  width: 72px;
  height: 72px;
}

.option-name {
  font-size: 0.8rem;
  font-weight: 800;
  line-height: 1.15;
}

.option-price {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-top: 3px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--sun);
  font-size: 0.75rem;
  font-weight: 800;
}

.option-price .i {
  width: 14px;
  height: 14px;
}

.option-lock {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-top: 3px;
  font-size: 0.72rem;
  font-weight: 800;
  color: #6A4FE0;
}

.option-lock .i {
  width: 13px;
  height: 13px;
}

.option[aria-pressed="true"] {
  background: var(--tint-mint);
  box-shadow: inset 0 0 0 3px var(--mint);
}

.option[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  top: -7px;
  right: -7px;
  width: 22px;
  height: 22px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--mint) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 12.5 4 4L18 8' fill='none' stroke='%231E2A44' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 16px no-repeat;
}

.option.is-locked canvas {
  opacity: 0.55;
  filter: grayscale(0.4);
}

.option[data-rarity="rare"] {
  border-color: #2E6FD8;
}

.option[data-rarity="legendary"] {
  border-color: var(--gold);
  background: var(--tint-gold);
}

.option[data-rarity="signature"] {
  border-color: var(--violet);
  background: var(--tint-violet);
}

.swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.swatch {
  width: 40px;
  height: 40px;
  border: 3px solid var(--ink);
  border-radius: 50%;
  background: var(--swatch);
  cursor: pointer;
  padding: 0;
}

.swatch[aria-pressed="true"] {
  box-shadow: 0 0 0 3px var(--cream), 0 0 0 6px var(--ink);
}

@media (min-width: 520px) {
  .option-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 960px) {
  .studio {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    align-items: start;
    gap: 32px;
  }

  .studio-stage {
    position: sticky;
    top: calc(var(--header-h) + 16px);
  }

  .move-row {
    margin: 12px 0 0;
    padding: 0;
    flex-wrap: wrap;
  }

  .tabs {
    margin: 12px 0 0;
    padding: 0 0 10px;
    flex-wrap: wrap;
  }
}

/* Profile: the account (account-panel.js), coins and achievements. */
.account-panel {
  margin-top: 28px;
}

.account-panel h3 {
  margin: 16px 0 8px;
  font-size: 1rem;
}

.account-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 12px 0;
}

.account-form .field {
  display: grid;
  gap: 6px;
  max-width: 260px;
}

.account-form input[type="date"] {
  min-height: var(--touch);
  padding: 0 12px;
  border: var(--border);
  border-radius: 12px;
  background: var(--panel);
  color: var(--text);
  font: 600 1rem var(--font-body);
}

.account-who {
  margin: 0 0 4px;
  font-size: 1.05rem;
}

.account-error {
  margin: 8px 0 0;
  color: #B3261E;
  font-weight: 700;
}

.passkey-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.passkey {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border: 2px solid var(--ink);
  border-radius: 12px;
}

.passkey-text {
  display: grid;
  min-width: 0;
}

.passkey-name {
  font-weight: 800;
}

.passkey-meta {
  font-size: 0.85rem;
  color: var(--muted);
}

.btn-small {
  min-height: 36px;
  padding: 0 12px;
  font-size: 0.9rem;
}

.btn-danger {
  background: var(--tint-red);
}

.account-danger {
  margin-top: 12px;
}

.account-danger summary {
  cursor: pointer;
  padding: 8px 0;
  font-weight: 700;
  color: var(--muted);
}

.account-danger .btn-danger {
  margin-top: 4px;
}

/* The heading, "Signed in as" and "Passkeys" take focus when a button redraws the panel
   (account-panel.js): a ring for keyboard users, none after a tap or click. */
.account-panel [tabindex="-1"]:focus:not(:focus-visible) {
  outline: none;
}

/* Coins and achievements. */
.profile-grid {
  display: grid;
  gap: 20px;
  margin-top: 28px;
}

.coins-panel,
.trophies,
.account-panel {
  padding: 16px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}

.coins-panel h2,
.trophies h2,
.account-panel h2 {
  display: flex;
  align-items: center;
  gap: 8px;
}

.coins-panel h2 .i,
.trophies h2 .i,
.account-panel h2 .i {
  width: 28px;
  height: 28px;
}

.coin-balance {
  font: 600 2.2rem/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  margin: 0 0 12px;
}

.earn-list {
  margin: 0 0 12px;
  padding-left: 1.2em;
}

.earn-list li + li {
  margin-top: 6px;
}

.coin-log {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}

.coin-log li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px dashed var(--rule);
  font-size: 0.92rem;
}

.coin-log .amt {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.coin-log .amt.is-plus {
  color: var(--felt-text);
}

.coin-log .amt.is-minus {
  color: var(--error-text);
}

.trophy-progress {
  font-weight: 800;
}

.trophy-tools {
  display: grid;
  gap: 10px;
  margin: 0 0 14px;
}

.trophy-tools[hidden] {
  display: none;
}

.trophy-tiers {
  flex-wrap: wrap;
}

.tier-dot {
  width: 14px;
  height: 14px;
  border: 2px solid var(--ink);
  border-radius: 50%;
}

.trophy-selects {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.trophy-field {
  display: grid;
  gap: 4px;
  min-width: 0;
  font-size: 0.85rem;
  font-weight: 800;
  color: var(--muted);
}

.trophy-field select,
.trophy-field input {
  width: 100%;
  min-height: 44px;
  padding: 0 36px 0 12px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 9.5 6 6 6-6' fill='none' stroke='%231E2A44' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 10px center / 16px 16px;
  color: var(--text);
  font: 700 1rem var(--font-body); /* 16px: no zoom on focus in iOS Safari */
  text-overflow: ellipsis;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}

.trophy-field input {
  padding: 0 12px;
  background: var(--bg);
  font-size: 1rem; /* 16px: no zoom on focus in iOS Safari */
  cursor: text;
}

.trophy-field input::placeholder {
  color: var(--muted);
}

.trophy-field select:focus-visible,
.trophy-field input:focus-visible {
  outline: 3px solid var(--violet);
  outline-offset: 2px;
}

.trophy-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  font-weight: 800;
  cursor: pointer;
}

.trophy-toggle input {
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--violet);
}

.trophy-more {
  display: flex;
  margin: 4px auto 0;
}

.trophy-more[hidden] {
  display: none;
}

@media (min-width: 900px) {
  .profile-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
  }
}

/* Buy sheet: slides up from the bottom on phones, a centered dialog on wider screens. */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(30, 42, 68, 0.5);
}

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 71;
  padding: 0 0 var(--safe-b);
  background: var(--bg);
  border-top: var(--border);
  border-radius: 24px 24px 0 0;
  animation: sheet-in 220ms ease;
}

.sheet-body {
  max-width: 480px;
  margin: 0 auto;
  padding: 22px var(--gutter) 22px;
  text-align: center;
}

.sheet-preview {
  width: 120px;
  height: 120px;
  margin: 0 auto 6px;
  display: block;
}

.sheet-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 14px;
}

@media (min-width: 600px) {
  .sheet {
    left: 50%;
    right: auto;
    bottom: auto;
    top: 50%;
    width: 420px;
    transform: translate(-50%, -50%);
    border: var(--border);
    border-radius: 24px;
    box-shadow: var(--chunk-lg);
    animation: none;
  }
}

/* ----- content pages ----- */

.page {
  padding-top: 24px;
  max-width: 70ch;
}

.page h2 {
  margin-top: 1.4em;
}

.page-404 {
  max-width: none;
}

.page-404 .tile-grid {
  max-width: 640px;
  margin-bottom: 20px;
}

/* /offline/ lists every game that works offline: the full-width grid, like the home page. */
.page-offline .tile-grid {
  max-width: none;
}

.draft-note {
  display: inline-block;
  margin: 0 0 16px;
  padding: 8px 14px;
  border: var(--border);
  border-radius: 12px;
  background: var(--sun);
  font-weight: 700;
}

.table-wrap {
  width: 100%;
  overflow-x: auto;
  margin-bottom: 1.2em;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

caption {
  text-align: left;
  font-weight: 800;
  padding: 10px 12px;
}

th,
td {
  text-align: left;
  vertical-align: top;
  padding: 10px 12px;
  border-top: 2px solid var(--rule);
  word-break: break-word;
}

thead th {
  border-top: 0;
  border-bottom: var(--border);
}

/* ----- footer ----- */

.site-footer {
  position: relative;
  z-index: 2;
  background: var(--ink);
  color: var(--cream);
  padding: 28px 0 calc(48px + var(--safe-b));
}

.site-footer a {
  color: var(--cream);
}

.site-footer :focus-visible {
  outline-color: var(--sun);
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 16px;
  margin-bottom: 12px;
}

.wordmark-footer {
  margin-right: 0;
  color: var(--cream);
}

.footer-tag {
  margin: 0;
  font-size: 0.92rem;
  opacity: 0.85;
}

.footer-links ul {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 2px 4px;
}

.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  padding: 0 12px;
  border-radius: 999px;
  font-weight: 700;
}

@media (hover: hover) {
  .footer-links a:hover {
    background: rgba(255, 255, 255, 0.12);
  }
}

.site-footer .pref {
  --pref-fg: var(--cream);
  --pref-knob: var(--cream);
  --pref-track: rgba(255, 255, 255, 0.25);
}

.footer-prefs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

/* A switch button. Ink on light backgrounds; the dark footer turns it cream. */
.pref {
  --pref-fg: var(--ink);
  --pref-knob: #fff;
  --pref-track: rgba(30, 42, 68, 0.22);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 14px;
  border: 2px solid var(--pref-fg);
  border-radius: 999px;
  background: transparent;
  color: var(--pref-fg);
  font-weight: 800;
  cursor: pointer;
}

.pref::before {
  content: "";
  width: 28px;
  height: 16px;
  border-radius: 999px;
  background: var(--pref-track);
  box-shadow: inset 2px 0 0 2px transparent;
  transition: background 150ms ease;
}

.pref[aria-pressed="true"]::before {
  background: var(--mint) radial-gradient(circle at 20px 8px, var(--pref-knob) 5px, transparent 5.5px);
}

.pref[aria-pressed="false"]::before {
  background: var(--pref-track) radial-gradient(circle at 8px 8px, var(--pref-knob) 5px, transparent 5.5px);
}

.footer-note {
  margin: 0;
  font-size: 0.9rem;
  opacity: 0.85;
  max-width: 60ch;
}

/* ----- casino games: never shown to a player who said they are a child ----- */

.age-child [data-casino] {
  display: none !important;
}

/* ----- the update notice: a deploy needs open pages refreshed (core.js) ----- */

.update-banner {
  position: fixed;
  top: calc(10px + env(safe-area-inset-top, 0px));
  left: 50%;
  z-index: 95;
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(calc(100% - 24px), 560px);
  padding: 10px 10px 10px 14px;
  border: var(--border);
  border-radius: 18px;
  background: var(--panel);
  box-shadow: var(--chunk);
  transform: translateX(-50%);
}

.update-banner > .i {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  color: var(--violet);
}

.update-text {
  flex: 1 1 auto;
  margin: 0;
  font-size: 0.92rem;
  font-weight: 700;
}

.update-go {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 14px;
}

.update-later {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.update-later .i {
  width: 16px;
  height: 16px;
}

/* ----- games that cost coins to play ----- */

.tile.is-short .tile-meta,
.fact-coins.is-short {
  color: var(--muted);
}

.coin-gate {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 10px;
  padding: 24px;
  background: rgba(30, 42, 68, 0.94);
  color: var(--cream);
  text-align: center;
}

.coin-gate-icon {
  width: 72px;
  height: 72px;
}

.coin-gate-title {
  margin: 0;
  font: 600 1.6rem/1.2 var(--font-display);
}

.coin-gate-text {
  margin: 0 0 6px;
  max-width: 30ch;
  font-weight: 700;
}

.coin-gate-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

/* ----- share: the button, and the panel shown when a link cannot be copied ----- */

.title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
}

.share-btn .i {
  width: 18px;
  height: 18px;
}

.hero-copy .share-btn {
  margin-top: 14px;
}

.share-panel {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(30, 42, 68, 0.5);
}

.share-card {
  position: relative;
  width: min(100%, 420px);
  padding: 18px;
  border: var(--border);
  border-radius: 22px;
  background: var(--panel);
  box-shadow: var(--chunk);
}

.share-card-title {
  margin: 4px 52px 14px 0;
  font: 600 1.2rem/1.25 var(--font-display);
}

.share-card-close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: var(--border);
  border-radius: 50%;
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 3px 0 var(--ink);
  cursor: pointer;
}

.share-card-close .i {
  width: 18px;
  height: 18px;
}

.share-card-link {
  width: 100%;
  min-height: 46px;
  padding: 8px 12px;
  border: 2px solid var(--ink);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  font: 700 0.95rem var(--font-body);
}

.share-card-note {
  margin: 10px 0 0;
  color: var(--muted);
  font-weight: 700;
  font-size: 0.9rem;
}

/* ----- toasts ----- */

.toasts {
  position: fixed;
  left: 50%;
  bottom: calc(16px + var(--safe-b));
  z-index: 80;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 8px;
  width: min(92vw, 380px);
  transform: translateX(-50%);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 14px;
  border: var(--border);
  border-radius: 16px;
  background: var(--panel);
  box-shadow: var(--chunk);
  font-weight: 800;
  animation: toast-in 260ms cubic-bezier(.2, 1.4, .4, 1);
}

.toast .i {
  width: 28px;
  height: 28px;
}

.toast-sub {
  display: block;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--muted);
}

.toast.is-coins {
  background: var(--tint-gold);
}

.toast.is-trophy {
  background: var(--tint-violet);
}

.toast.is-leaving {
  animation: toast-out 220ms ease forwards;
}

/* While a sheet or the search is open, toasts move to the top so they never cover its buttons. */
body.is-locked .toasts {
  top: calc(12px + env(safe-area-inset-top, 0px));
  bottom: auto;
  flex-direction: column;
}

/* On a game page the toasts sit at the top, clear of the player's thumbs. */
body[data-page="play"] .toasts {
  top: calc(var(--bar-h) + 8px + env(safe-area-inset-top, 0px));
  bottom: auto;
  flex-direction: column;
}

@media (min-width: 760px) {
  body[data-page="play"] .toasts {
    top: calc(var(--header-h) + 12px);
  }
}

@media (min-width: 900px) {
  .toasts {
    left: auto;
    right: 20px;
    transform: none;
  }
}

/* ----- companion (the player's avatar on the homepage, never blocks input) ----- */

.companion-layer {
  position: fixed;
  inset: 0;
  z-index: 15;
  pointer-events: none;
  overflow: hidden;
}

.companion {
  position: absolute;
  left: 0;
  top: 0;
  width: 72px;
  height: 96px;
  transform: translate3d(0, 0, 0);
  will-change: transform;
}

.companion canvas {
  display: block;
  width: 100%;
  height: 100%;
  animation: bob 1.8s ease-in-out infinite;
  transform-origin: 50% 100%;
}

.companion.is-cheer canvas {
  animation: hop 380ms ease-in-out 3;
}

/* On phones the companion perches on the daily bonus card instead of floating: nothing is pinned
   to the bottom of a phone screen, where the browser's toolbar moves things around. */
.daily-wrap {
  position: relative;
}

.daily-wrap > .companion {
  position: absolute;
  left: auto;
  top: -58px;
  right: 26px;
  width: 48px;
  height: 64px;
  transform: none !important;
  z-index: 3;
  pointer-events: none;
}

.companion-layer.is-still .companion canvas,
.daily-wrap > .companion.is-still canvas {
  animation: none;
}

/* ----- motion ----- */

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

@keyframes hop {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  40% { transform: translateY(-14px) scale(0.96, 1.04); }
}

@keyframes bump {
  0% { transform: scale(1); }
  35% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

@keyframes wiggle {
  0%, 80%, 100% { transform: rotate(0); }
  85% { transform: rotate(-10deg); }
  90% { transform: rotate(10deg); }
  95% { transform: rotate(-6deg); }
}

@keyframes twinkle {
  0%, 100% { transform: scale(1) rotate(0); }
  50% { transform: scale(0.75) rotate(20deg); }
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(16px) scale(0.96); }
  to { opacity: 1; transform: none; }
}

@keyframes toast-out {
  to { opacity: 0; transform: translateY(8px); }
}

@keyframes sheet-in {
  from { transform: translateY(100%); }
  to { transform: none; }
}

/* The player's in-site Motion setting (footer) and the system setting both calm things down. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }

  .town svg {
    transform: none;
  }
}

html.calm *,
html.calm *::before,
html.calm *::after {
  animation: none !important;
  transition: none !important;
}

html.calm .town svg {
  transform: none;
}

/* ----- the installed app (PWA pass): footer install row and standalone mode ----- */

.footer-install {
  display: grid;
  gap: 6px;
  justify-items: start;
}

.footer-install[hidden],
.footer-install [hidden] {
  display: none;
}

.btn-install {
  min-height: 44px;
  padding: 8px 18px;
  border: 2px solid currentColor;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

@media (display-mode: standalone), (display-mode: fullscreen) {
  .footer-install {
    display: none !important;
  }
}

/* ----- Contact form (contact.js, /api/contact) ----- */

.contact-form {
  display: grid;
  gap: 14px;
  max-width: 560px;
  margin: 16px 0 8px;
  padding: 18px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk);
}

.contact-note {
  margin: 0;
  color: var(--muted);
  font-weight: 700;
}

.contact-form .field,
.class-page .field,
.plan-box .field {
  display: grid;
  gap: 6px;
  font-weight: 800;
}

.contact-form .field em,
.class-page .field em {
  color: var(--muted);
  font-style: normal;
  font-weight: 600;
}

.contact-form input,
.contact-form select,
.contact-form textarea,
.class-page input[type="text"],
.plan-box input[type="text"] {
  width: 100%;
  min-height: var(--touch);
  padding: 10px 12px;
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  font: 600 1rem/1.4 var(--font-body); /* 16px: no zoom on focus in iOS Safari */
}

.contact-form textarea {
  resize: vertical;
}

.contact-form input:focus-visible,
.contact-form select:focus-visible,
.class-page input:focus-visible,
.plan-box input:focus-visible,
.contact-form textarea:focus-visible {
  outline: 3px solid var(--violet);
  outline-offset: 2px;
}

.contact-form .btn {
  justify-self: start;
}

.contact-form .btn:disabled {
  opacity: 0.6;
  cursor: progress;
}

.contact-status {
  min-height: 1.4em;
  margin: 0;
  font-weight: 700;
}

.contact-status[data-kind="ok"] {
  color: var(--felt-text);
}

.contact-status[data-kind="error"] {
  color: var(--error-text);
}

.contact-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ----- touch tablets (iPad pass) -----
   A tablet held at arm's length with a finger for a pointer: bigger text and bigger targets than
   a laptop at the same width. Matched by the pointer, never the user agent (iPadOS Safari reports
   a Mac). Phones are under 600 px and keep their own sizes. */
/* Phones: chips reach the 44px touch minimum (tablets get 48px below). */
@media (pointer: coarse) {
  .chip,
  .chip-links a {
    min-height: var(--touch);
  }

  .chip-small {
    min-height: 40px;
  }
}

@media (pointer: coarse) and (min-width: 600px) {
  :root {
    --touch: 52px;
    --header-h: 68px;
    --bar-h: 60px;
    --gutter: 24px;
  }

  html {
    font-size: 106.25%;
  }

  .wordmark-mark {
    width: 40px;
    height: 40px;
  }

  .site-nav a {
    padding: 0 16px;
    font-size: 1.05rem;
  }

  .coin-pill {
    min-height: 48px;
    padding: 0 14px 0 7px;
  }

  .coin-pill .i {
    width: 30px;
    height: 30px;
  }

  .me-button {
    width: 52px;
    height: 52px;
  }

  .search,
  .search-button {
    min-height: 56px;
  }

  .search input {
    height: 52px;
  }

  .chip,
  .chip-links a {
    min-height: 48px;
    padding: 0 18px;
  }

  .chip .i {
    width: 18px;
    height: 18px;
  }

  .chip-small {
    min-height: 44px;
  }

  .recent-row {
    gap: 14px;
  }

  .recent-row a {
    width: 252px;
    gap: 12px;
    padding: 8px 16px 8px 8px;
  }

  .recent-row img {
    width: 84px;
    height: 52px;
  }

  .tile-body {
    padding: 11px 14px 13px;
  }

  .tile-title {
    font-size: 1.18rem;
  }

  .tile-meta {
    font-size: 0.86rem;
  }

  .tile-spark {
    width: 32px;
    height: 32px;
  }

  .daily-icon {
    width: 56px;
    height: 56px;
  }

  .pbtn {
    width: 48px;
    height: 48px;
    border-radius: 14px;
  }

  .pbtn .i {
    width: 24px;
    height: 24px;
  }

  .player-bar {
    gap: 8px;
    padding: 0 max(12px, env(safe-area-inset-right, 0px)) 0 max(12px, env(safe-area-inset-left, 0px));
  }

  .player-name {
    font-size: 1.25rem;
  }

  .coin-pill-bar {
    min-height: 44px;
  }
}

/* Touch tablets from 760 px: the bigger chips need the finder's full width, so the search box
   sits above them, and the daily card gets room for its title on one line. */
@media (pointer: coarse) and (min-width: 760px) {
  .finder {
    display: block;
  }

  .filters {
    margin-top: 12px;
  }

  .hero {
    grid-template-columns: minmax(0, 1fr) 384px;
  }
}

/* ----- seasons (tools/build_site.py SEASONS): <html data-season> recolors the town and shows
   that season's decorations. Every sky stays light, so the hero text keeps its contrast. ----- */

:root {
  --town-sky1: #7CC8FF;
  --town-sky2: #CFEBFF;
  --town-sun: #FFD23F;
  --town-back: #8B6CFF;
  --town-back-op: 0.22;
  --town-a: #FF6B9A;
  --town-b: #FF9F43;
  --town-c: #4CD98A;
  --town-d: #FFD23F;
  --town-window: #FFF8EC;
  --town-tree: #4CD98A;
  --town-tree2: #2E9E6A;
  --fx-a: #FF9F43;
  --fx-b: #E9A21C;
}

.town .t-sky1 { stop-color: var(--town-sky1); }
.town .t-sky2 { stop-color: var(--town-sky2); }
.town .t-sun { fill: var(--town-sun); }
.town .t-back { fill: var(--town-back); opacity: var(--town-back-op); }
.town .t-a { fill: var(--town-a); }
.town .t-b { fill: var(--town-b); }
.town .t-c { fill: var(--town-c); }
.town .t-d { fill: var(--town-d); }
.town .t-window { fill: var(--town-window); }
.town .t-tree { fill: var(--town-tree); }
.town .t-tree2 { fill: var(--town-tree2); }

.town .deco,
.season-fx,
.season-note {
  display: none;
}

html[data-season] .deco-trees,
html[data-season="fall"] .season-fx,
html[data-season="harvest"] .season-fx,
html[data-season="holidays"] .season-fx,
html[data-season="winter"] .season-fx,
html[data-season="spring"] .season-fx,
html[data-season="halloween"] .deco-halloween,
html[data-season="halloween"] .deco-moon,
html[data-season="harvest"] .deco-harvest,
html[data-season="holidays"] .deco-snow,
html[data-season="holidays"] .deco-tree-snow,
html[data-season="holidays"] .deco-lights,
html[data-season="winter"] .deco-snow,
html[data-season="winter"] .deco-tree-snow,
html[data-season="spring"] .deco-flowers,
html[data-season="spring"] .deco-birds,
html[data-season="summer"] .deco-bunting {
  display: inline;
}

html[data-season="halloween"] {
  --town-sky1: #C9B8F5;
  --town-sky2: #FFDCC0;
  --town-sun: #FFF3C4;
  --town-back: #4B3A7A;
  --town-back-op: 0.3;
  --town-a: #8B6CFF;
  --town-b: #FF9F43;
  --town-c: #6B5CA5;
  --town-d: #FF8A1F;
  --town-window: #FFD23F;
  --town-tree: #FF9F43;
  --town-tree2: #C9803F;
}

html[data-season="fall"] {
  --town-sky1: #9ED3F5;
  --town-sky2: #FFE6BF;
  --town-sun: #FFC94A;
  --town-back: #C9803F;
  --town-back-op: 0.22;
  --town-a: #E8743B;
  --town-b: #FFD23F;
  --town-c: #C9803F;
  --town-d: #FF9F43;
  --town-tree: #FF9F43;
  --town-tree2: #E9A21C;
}

html[data-season="harvest"] {
  --town-sky1: #FBD3A8;
  --town-sky2: #FFEBD2;
  --town-sun: #FF9F43;
  --town-back: #8A4B2A;
  --town-back-op: 0.18;
  --town-a: #C9803F;
  --town-b: #E8743B;
  --town-c: #E9A21C;
  --town-d: #B5562D;
  --town-tree: #C9803F;
  --town-tree2: #B5562D;
  --fx-a: #C9803F;
  --fx-b: #E8743B;
}

html[data-season="holidays"] {
  --town-sky1: #A9D8F5;
  --town-sky2: #E3F3FF;
  --town-sun: #FFE58A;
  --town-back: #5B7CB8;
  --town-back-op: 0.2;
  --town-a: #E8457A;
  --town-b: #2E9E6A;
  --town-c: #7CC8FF;
  --town-d: #FFD23F;
  --town-window: #FFD23F;
  --town-tree: #2E9E6A;
  --town-tree2: #1F7A50;
}

html[data-season="winter"] {
  --town-sky1: #BFDDF2;
  --town-sky2: #EAF5FF;
  --town-sun: #FFF3C4;
  --town-back: #7C93C2;
  --town-back-op: 0.2;
  --town-a: #7CC8FF;
  --town-b: #8B6CFF;
  --town-c: #A9C6E0;
  --town-d: #FF6B9A;
  --town-tree: #DDEBF5;
  --town-tree2: #C3D7E8;
}

html[data-season="spring"] {
  --town-sky1: #8FD4FF;
  --town-sky2: #DDF7E8;
  --town-back: #4CD98A;
  --town-back-op: 0.18;
  --town-a: #FF9FC0;
  --town-b: #4CD98A;
  --town-c: #FFD23F;
  --town-d: #B9A6F2;
  --town-tree: #FF9FC0;
  --town-tree2: #FFC2D6;
  --fx-a: #FF9FC0;
  --fx-b: #FFFFFF;
}

/* Phones: the hero copy spans the whole crop, so the bunting and birds would sit behind the text. */
@media (max-width: 759px) {
  html[data-season] .deco-bunting,
  html[data-season] .deco-birds {
    display: none;
  }
}

/* The narrowest phones: the ghost would sit on the hero text. */
@media (max-width: 379px) {
  html[data-season] .town .ghost {
    display: none;
  }
}

/* The ghost floats and the bats flap, gently. */
.town .ghost {
  animation: ghost-bob 3.2s ease-in-out infinite alternate;
}

.town .bat path {
  transform-box: fill-box;
  transform-origin: center;
  animation: bat-flap 0.9s ease-in-out infinite alternate;
}

@keyframes ghost-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-10px); }
}

@keyframes bat-flap {
  to { transform: scaleY(0.6); }
}

/* Falling leaves, snow or petals over the town. */
.season-fx {
  position: absolute;
  inset: 0;
}

.season-fx i {
  position: absolute;
  top: -20px;
  left: calc(var(--x) * 1%);
  width: 12px;
  height: 12px;
  border: 1.5px solid rgba(30, 42, 68, 0.55);
  border-radius: 0 100% 0 100%;
  background: var(--fx-a);
  opacity: 0.85;
  animation: season-fall var(--d, 9s) linear infinite;
  animation-delay: calc(var(--delay) * -1s);
}

.season-fx i:nth-child(even) { background: var(--fx-b); }

html[data-season="holidays"] .season-fx i,
html[data-season="winter"] .season-fx i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border-color: rgba(30, 42, 68, 0.2);
  background: #FFFFFF;
}

html[data-season="spring"] .season-fx i {
  width: 9px;
  height: 9px;
  border-color: rgba(30, 42, 68, 0.3);
}

.season-fx i:nth-child(1)  { --x: 4;  --d: 9s;  --delay: 1; }
.season-fx i:nth-child(2)  { --x: 11; --d: 12s; --delay: 6; }
.season-fx i:nth-child(3)  { --x: 19; --d: 10s; --delay: 3; }
.season-fx i:nth-child(4)  { --x: 26; --d: 13s; --delay: 9; }
.season-fx i:nth-child(5)  { --x: 33; --d: 8s;  --delay: 4; }
.season-fx i:nth-child(6)  { --x: 41; --d: 11s; --delay: 7; }
.season-fx i:nth-child(7)  { --x: 48; --d: 9s;  --delay: 2; }
.season-fx i:nth-child(8)  { --x: 55; --d: 12s; --delay: 10; }
.season-fx i:nth-child(9)  { --x: 62; --d: 10s; --delay: 5; }
.season-fx i:nth-child(10) { --x: 70; --d: 13s; --delay: 8; }
.season-fx i:nth-child(11) { --x: 77; --d: 9s;  --delay: 0; }
.season-fx i:nth-child(12) { --x: 84; --d: 11s; --delay: 6; }
.season-fx i:nth-child(13) { --x: 91; --d: 10s; --delay: 3; }
.season-fx i:nth-child(14) { --x: 97; --d: 12s; --delay: 9; }

@keyframes season-fall {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  25%  { transform: translate3d(14px, 95px, 0) rotate(90deg); }
  50%  { transform: translate3d(-10px, 190px, 0) rotate(180deg); }
  75%  { transform: translate3d(12px, 285px, 0) rotate(270deg); }
  100% { transform: translate3d(0, 400px, 0) rotate(360deg); }
}

/* Calm (the footer's Motion switch or the system setting): nothing falls, nothing moves. */
html.calm .season-fx {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .season-fx {
    display: none !important;
  }
}

/* The hero's seasonal greeting, beside the kicker. */
html[data-season] .season-note {
  display: inline-block;
  margin: 0 0 8px 6px;
  padding: 3px 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  font-weight: 800;
  font-size: 0.85rem;
}

.season-note span {
  display: none;
}

html[data-season="fall"] .season-note [data-for="fall"],
html[data-season="halloween"] .season-note [data-for="halloween"],
html[data-season="harvest"] .season-note [data-for="harvest"],
html[data-season="holidays"] .season-note [data-for="holidays"],
html[data-season="winter"] .season-note [data-for="winter"],
html[data-season="spring"] .season-note [data-for="spring"],
html[data-season="summer"] .season-note [data-for="summer"] {
  display: inline;
}

html[data-season="halloween"] .hero-kicker { background: #FF9F43; }
html[data-season="holidays"] .hero-kicker { background: #4CD98A; }
html[data-season="spring"] .hero-kicker { background: #FFC2D6; }

/* A small seasonal badge on the logo in the header. */
.wordmark {
  position: relative;
}

html[data-season] .site-header .wordmark::after {
  content: "";
  position: absolute;
  left: 22px;
  top: 2px;
  width: 20px;
  height: 20px;
  background: no-repeat center / contain;
  pointer-events: none;
}

html[data-season="halloween"] .site-header .wordmark::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-12 -28 24 30'%3E%3Cpath d='M-1-24c0-3 2-5 4-5' fill='none' stroke='%232E7A4A' stroke-width='3'/%3E%3Cellipse cx='0' cy='-11' rx='11' ry='11' fill='%23FF9F43' stroke='%231E2A44' stroke-width='2'/%3E%3Cpath d='M-5-14l2-4 2 4zM1-14l2-4 2 4z' fill='%231E2A44'/%3E%3Cpath d='M-5-7q5 4 10 0' fill='none' stroke='%231E2A44' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}

html[data-season="fall"] .site-header .wordmark::after,
html[data-season="harvest"] .site-header .wordmark::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 20C4 9 11 4 21 3c-1 10-6 17-17 17z' fill='%23FF9F43' stroke='%231E2A44' stroke-width='2' stroke-linejoin='round'/%3E%3Cpath d='M4 20 15 9' stroke='%231E2A44' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}

html[data-season="holidays"] .site-header .wordmark::after,
html[data-season="winter"] .site-header .wordmark::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='%23FFFFFF' stroke='%231E2A44' stroke-width='2'/%3E%3Cpath d='M12 5v14M6 8.5l12 7M18 8.5l-12 7' stroke='%237CC8FF' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");
}

html[data-season="spring"] .site-header .wordmark::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23FF9FC0' stroke='%231E2A44' stroke-width='1.6'%3E%3Ccircle cx='12' cy='6' r='4.5'/%3E%3Ccircle cx='18' cy='11' r='4.5'/%3E%3Ccircle cx='15.5' cy='18' r='4.5'/%3E%3Ccircle cx='8.5' cy='18' r='4.5'/%3E%3Ccircle cx='6' cy='11' r='4.5'/%3E%3C/g%3E%3Ccircle cx='12' cy='12.5' r='3.4' fill='%23FFD23F' stroke='%231E2A44' stroke-width='1.6'/%3E%3C/svg%3E");
}

html[data-season="summer"] .site-header .wordmark::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg stroke='%231E2A44' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 1.5v3M12 19.5v3M1.5 12h3M19.5 12h3M4.6 4.6l2 2M17.4 17.4l2 2M4.6 19.4l2-2M17.4 6.6l2-2'/%3E%3C/g%3E%3Ccircle cx='12' cy='12' r='5.5' fill='%23FFD23F' stroke='%231E2A44' stroke-width='2'/%3E%3C/svg%3E");
}

/* ----- leaderboards (boards.js): house players, plus your own row ----- */

.board {
  margin: 18px 0 8px;
  padding: 14px 14px 10px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk);
}

.board-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
}

.game-info .board h2,
.board h2 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 1.25rem;
}

.board h2 .i {
  color: var(--gold);
}

.board-tabs {
  display: inline-flex;
  padding: 3px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--bg);
}

.board-tab {
  min-height: var(--touch);
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 800;
  font-size: 0.9rem;
  cursor: pointer;
}

.board-tab[aria-pressed="true"] {
  background: var(--sun);
  box-shadow: inset 0 0 0 2px var(--ink);
}

.board-unit {
  margin: 6px 0 8px;
  font-size: 0.85rem;
  color: var(--muted);
}

.board-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.board-row {
  display: grid;
  grid-template-columns: 2em 32px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 6px 8px;
  border-top: 1px solid var(--rule);
}

.board-row:first-child {
  border-top: 0;
}

.board-rank {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.board-row:nth-child(1) .board-rank { color: var(--gold); }

.board-face {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--tint-violet);
  overflow: hidden;
}

.board-face .i {
  width: 20px;
  height: 20px;
  color: var(--violet);
  vertical-align: 0;
}

.board-face canvas {
  width: 100%;
  height: 100%;
}

.board-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
  min-width: 0;
  line-height: 1.25;
  font-weight: 800;
}

/* A long name shortens; the House label never does (a house player is always marked). */
.board-who {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.board-house {
  flex: 0 0 auto;
  display: inline-block;
  padding: 0 7px;
  border: 1.5px solid var(--muted);
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  vertical-align: 0.12em;
}

.board-score {
  font-family: var(--font-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.board-row.is-you {
  margin: 2px -4px;
  padding: 6px 12px;
  border: 2px solid var(--ink);
  border-radius: 12px;
  background: var(--tint-sun);
}

.board-row.is-you + .board-row {
  border-top: 0;
}

.board-note {
  margin: 8px 0 4px;
  font-weight: 800;
}

.board .small-note {
  margin: 4px 0 0;
}

/* /leaderboards/ */

.lb-wrap h1 {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lb-wrap h1 .i {
  color: var(--gold);
}

.lb-overall {
  display: grid;
  gap: 16px;
}

@media (min-width: 760px) {
  .lb-overall {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.lb-games {
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  display: grid;
  gap: 10px;
}

@media (min-width: 760px) {
  .lb-games {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .lb-games {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.lb-game a {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--touch);
  padding: 8px 12px 8px 8px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--panel);
  color: var(--text);
  text-decoration: none;
}

.lb-game img {
  flex: 0 0 auto;
  width: 80px;
  height: 50px;
  border-radius: 8px;
  object-fit: cover;
}

.lb-game-text {
  display: grid;
  min-width: 0;
  flex: 1 1 auto;
}

.lb-game-title {
  font-weight: 800;
}

.lb-game-top,
.lb-game-you {
  font-size: 0.85rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lb-game-top .i {
  margin-right: 3px;
  color: var(--violet);
}

.lb-game-you {
  color: var(--text);
  font-weight: 700;
}

@media (hover: hover) and (pointer: fine) {
  .lb-game a:hover {
    box-shadow: var(--chunk);
  }
}

/* ----- popular and "playing now" (live.js): only real numbers, only from 20 players up ----- */

.badge-popular {
  top: auto;
  bottom: 8px;
  background: var(--pink);
  color: #FFFFFF;
}

.tile-live,
.facts .fact-live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--felt-text);
  font-weight: 800;
}

.tile-live::before,
.facts .fact-live::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--mint);
  box-shadow: 0 0 0 2px rgba(76, 217, 138, 0.3);
}

.tile-live {
  margin-left: 6px;
}

.facts .fact-live {
  background: var(--tint-mint);
}

/* ----- dark mode: <html data-theme="dark"> (the head script: the footer's Theme choice, or the
   system setting under Auto). --ink stays dark: it draws outlines, shadows and the text on
   bright fills (sun buttons, chips that are on). Text on panels uses --text. ----- */

.town .t-sky3 { stop-color: var(--bg); }
.town .t-cloud { fill: var(--town-cloud, #FFFFFF); opacity: var(--town-cloud-op, 0.92); }

:root[data-theme="dark"] {
  color-scheme: dark;
  --ink: #0A1122;
  --bg: #141C30;
  --panel: #1F2A44;
  --text: #F3EEE3;
  --muted: #AEB8CE;
  --rule: rgba(243, 238, 227, 0.14);
  --pink-text: #FF8FB1;
  --felt-text: #6BE3A6;
  --error-text: #FF8A9A;
  --tint-sun: #3B3417;
  --tint-mint: #173A2B;
  --tint-violet: #2B2652;
  --tint-gold: #3A3019;
  --tint-red: #4A2229;
  --tint-gray: #2A3552;
  --code-bg: rgba(243, 238, 227, 0.1);

  /* The town at night, whatever the season: dark sky, moon, lit windows. */
  --town-sky1: #0D1633;
  --town-sky2: #2A2C5E;
  --town-sun: #FFF3C4;
  --town-back-op: 0.32;
  --town-window: #FFD23F;
  --town-cloud: #8C93C2;
  --town-cloud-op: 0.25;
}

:root[data-theme="dark"] [data-color] {
  --accent-soft: color-mix(in srgb, var(--accent) 22%, var(--panel));
}

:root[data-theme="dark"] .deco-moon {
  display: inline;
}

/* Bright fills keep dark text in dark mode. */
:root[data-theme="dark"] .chip[aria-pressed="true"],
:root[data-theme="dark"] .board-tab[aria-pressed="true"],
:root[data-theme="dark"] .hero-kicker,
:root[data-theme="dark"] .badge-new {
  color: var(--ink);
}

:root[data-theme="dark"] .wordmark-text {
  color: var(--text);
}

:root[data-theme="dark"] .board-face {
  background: var(--tint-violet);
}

:root[data-theme="dark"] .board-face .i,
:root[data-theme="dark"] .lb-game-top .i {
  color: #B9A6F2;
}

:root[data-theme="dark"] .season-fx i {
  border-color: rgba(10, 17, 34, 0.6);
}

/* The Theme button cycles Auto, Dark, Light: no on/off switch drawn. */
.pref-theme::before {
  display: none;
}

/* /class/: the class game list builder (class.js) and the ad-free code box (plan.js). */
.class-form {
  max-width: 640px;
}

.class-group {
  border: 0;
  margin: 0 0 14px;
  padding: 0;
}

.class-group legend {
  font-weight: 700;
  margin-bottom: 6px;
}

.class-pick {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin: 0 14px 0 0;
}

.class-pick input {
  width: 22px;
  height: 22px;
}

.class-error,
.plan-box .is-bad {
  color: #B4232F;
}

.class-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.class-form .field,
.class-out .field {
  margin-bottom: 14px;
}

.plan-box {
  max-width: 520px;
  margin-bottom: 1em;
}

.plan-box [data-plan-remove] {
  margin-top: 4px;
}

.class-out {
  margin-top: 20px;
}

[data-class-view] .tile-grid {
  margin-bottom: 20px;
}

.plan-box form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
}

.plan-box .field {
  flex: 1 1 220px;
  margin: 0;
}

/* /games/: the list of theme pages. */
.theme-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin: 0 0 32px;
  padding: 0;
  list-style: none;
}

.theme-list a {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 44px;
  padding: 14px 16px;
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--chunk);
}

.theme-list .small-note {
  margin: 0;
}

/* /flash-cards/<id>/: a deck's cards as a table, printable. */
.deck-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.deck-table {
  width: 100%;
  max-width: 640px;
}

@media print {
  .site-header,
  .site-footer,
  .crumbs,
  .deck-actions,
  .ad-wrap,
  .deck-page h2,
  .deck-page h2 + p,
  .deck-page .chip-row {
    display: none !important;
  }
}

/* /daily/: past daily puzzles (docs/seo.md, phase 3). */
.xw-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 32px;
  align-items: flex-start;
  margin-bottom: 16px;
}

.archive-page table.xw-grid {
  width: auto;
  min-width: 0;
  table-layout: fixed;
  border-collapse: collapse;
}

.xw-grid td {
  position: relative;
  width: 52px;
  height: 52px;
  border: 2px solid var(--ink);
  background: #fff;
  text-align: center;
  vertical-align: middle;
  font: 700 1.5rem/1 var(--font-body);
}

.xw-grid .xw-block {
  background: var(--ink);
}

.xw-num {
  position: absolute;
  top: 2px;
  left: 4px;
  font-size: 0.7rem;
}

.xw-clues {
  margin: 0 0 12px;
  padding-left: 1.6em;
}

.xw-answers,
.fl-answer {
  margin: 0 0 16px;
}

.xw-answers summary,
.fl-answer summary {
  min-height: 44px;
  font-weight: 800;
  cursor: pointer;
}

.fl-word {
  font: 800 2rem/1.2 var(--font-display, var(--font-body));
  letter-spacing: 0.2em;
}

.archive-list {
  columns: 2 220px;
  padding-left: 1.2em;
}

/* ----- seasons, part two (seasons.js): visitors that cross the page, a hanger from the header,
   and each season's touches on panels. Panels: the daily card, the finder, boards, notices.
   Never on game pages (seasons.js doesn't run there; the theater has no panels of these). ----- */

.season-layer {
  position: fixed;
  inset: 0;
  z-index: 15;
  overflow: hidden;
  pointer-events: none;
}

.season-visitor {
  position: absolute;
  top: var(--top);
  left: -60px;
  width: var(--size);
  height: var(--size);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  animation: visit-across var(--dur) linear var(--delay) both;
}

.season-visitor.from-right {
  left: auto;
  right: -60px;
  animation-name: visit-across-back;
}

.season-visitor.from-right .season-visitor-art {
  transform: scaleX(-1);
}

.season-visitor.move-gust { animation-name: visit-gust; animation-timing-function: ease-in-out; }
.season-visitor.move-gust.from-right { animation-name: visit-gust-back; }

.season-visitor.move-drift {
  top: -40px;
  left: var(--left);
  right: auto;
  animation-name: visit-drift;
}

.season-visitor.move-rise {
  top: auto;
  bottom: -40px;
  left: var(--left);
  right: auto;
  animation-name: visit-rise;
  animation-timing-function: ease-out;
}

.season-visitor-art,
.season-visitor-art svg {
  display: block;
  width: 100%;
  height: 100%;
}

.season-visitor.is-flap svg { animation: visitor-flap 0.28s ease-in-out infinite alternate; }
.season-visitor.is-flutter .wings { transform-origin: 16px 12px; animation: visitor-flutter 0.22s ease-in-out infinite alternate; }
.season-visitor.is-spin svg { animation: visitor-spin 6s linear infinite; }
.season-visitor.is-roll svg { animation: visitor-spin 1.6s linear infinite; }
.season-visitor.is-float svg { animation: visitor-bob 1.6s ease-in-out infinite alternate; }

.season-visitor.is-caught {
  animation-play-state: paused;
  pointer-events: none;
}

.season-visitor.is-caught .season-visitor-art {
  animation: visitor-pop 0.35s ease-out forwards;
}

@keyframes visit-across {
  0%   { transform: translate3d(0, 0, 0); }
  25%  { transform: translate3d(28vw, calc(var(--sway) * -1), 0); }
  50%  { transform: translate3d(55vw, var(--sway), 0); }
  75%  { transform: translate3d(82vw, calc(var(--sway) * -0.6), 0); }
  100% { transform: translate3d(calc(100vw + 120px), 0, 0); }
}

@keyframes visit-across-back {
  0%   { transform: translate3d(0, 0, 0); }
  25%  { transform: translate3d(-28vw, var(--sway), 0); }
  50%  { transform: translate3d(-55vw, calc(var(--sway) * -1), 0); }
  75%  { transform: translate3d(-82vw, calc(var(--sway) * 0.6), 0); }
  100% { transform: translate3d(calc(-100vw - 120px), 0, 0); }
}

@keyframes visit-gust {
  0%   { transform: translate3d(0, 0, 0) rotate(0); }
  40%  { transform: translate3d(45vw, calc(var(--sway) * 1.4), 0) rotate(200deg); }
  100% { transform: translate3d(calc(100vw + 120px), calc(var(--sway) * 3), 0) rotate(540deg); }
}

@keyframes visit-gust-back {
  0%   { transform: translate3d(0, 0, 0) rotate(0); }
  40%  { transform: translate3d(-45vw, calc(var(--sway) * 1.4), 0) rotate(-200deg); }
  100% { transform: translate3d(calc(-100vw - 120px), calc(var(--sway) * 3), 0) rotate(-540deg); }
}

@keyframes visit-drift {
  0%   { transform: translate3d(0, 0, 0); }
  50%  { transform: translate3d(var(--sway), 30vh, 0); }
  100% { transform: translate3d(calc(var(--sway) * -0.5), 62vh, 0); opacity: 0; }
}

@keyframes visit-rise {
  0%   { transform: translate3d(0, 0, 0); }
  50%  { transform: translate3d(var(--sway), -35vh, 0); }
  100% { transform: translate3d(calc(var(--sway) * -0.4), -62vh, 0); opacity: 0; }
}

@keyframes visitor-flap { to { transform: scaleY(0.55); } }
@keyframes visitor-flutter { to { transform: scaleX(0.35); } }
@keyframes visitor-spin { to { transform: rotate(360deg); } }
@keyframes visitor-bob { to { transform: translateY(-8px); } }
@keyframes visitor-pop {
  40%  { transform: scale(1.4); opacity: 1; }
  100% { transform: scale(0.2); opacity: 0; }
}

/* A spider or a bauble hanging from the header, on the right. A tap tugs it up and lets it fall. */
.season-hanger {
  position: absolute;
  top: 100%;
  right: max(16px, calc((100vw - var(--maxw)) / 2 + 24px));
  display: flex;
  flex-direction: column;
  align-items: center;
  width: var(--touch);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transform-origin: top center;
  animation: hanger-sway 3.4s ease-in-out infinite alternate;
}

.season-hanger-thread {
  width: 1.5px;
  height: 34px;
  background: color-mix(in srgb, var(--text) 45%, transparent);
}

.season-hanger-art,
.season-hanger-art svg {
  display: block;
  width: var(--size);
  height: var(--size);
}

.season-hanger.is-tugged .season-hanger-thread {
  animation: hanger-tug 0.9s ease-in-out;
}

@keyframes hanger-sway {
  from { transform: rotate(-4deg); }
  to { transform: rotate(4deg); }
}

@keyframes hanger-tug {
  35% { height: 4px; }
  70% { height: 46px; }
}

/* Phones: a short thread, so the hanger stays above the hero's first line. */
@media (max-width: 759px) {
  .season-hanger { right: 4px; --size: 22px !important; }
  .season-hanger-thread { height: 3px; }
}

/* Calm: nothing crosses and nothing hangs (seasons.js doesn't add them; this covers a switch). */
html.calm .season-layer,
html.calm .season-hanger {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .season-layer,
  .season-hanger {
    display: none !important;
  }
}

/* ----- touches on panels ----- */

:root {
  --web-color: rgba(30, 42, 68, 0.32);
}

:root[data-theme="dark"] {
  --web-color: rgba(243, 238, 227, 0.35);
}

html[data-season] :is(.daily, .finder, .board, .game-notice) {
  position: relative;
}

/* Halloween: a cobweb in the top-right corner of each panel, and a pumpkin by row titles. */
html[data-season="halloween"] :is(.daily, .finder, .board)::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 46px;
  height: 46px;
  border-top-right-radius: inherit;
  background: var(--web-color);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'%3E%3Cpath d='M80 0L-2.0 0.0 M80 0L4.5 32.0 M80 0L24.1 60.0 M80 0L49.3 76.0 M80 0L77.1 82.0 M66.0 0.0Q69.0 2.2 67.1 5.5Q70.8 6.4 70.5 10.2Q73.9 9.5 74.8 13.0Q77.6 11.1 79.5 14.0 M52.0 0.0Q58.0 4.5 54.2 10.9Q61.6 12.9 60.9 20.5Q67.9 19.0 69.5 26.0Q75.3 22.1 79.0 28.0 M36.0 0.0Q45.4 7.0 39.5 17.2Q51.1 20.2 50.0 32.2Q60.9 29.9 63.5 40.8Q72.6 34.8 78.5 44.0 M20.0 0.0Q32.8 9.6 24.8 23.4Q40.6 27.6 39.1 43.9Q54.0 40.8 57.5 55.6Q69.9 47.4 77.9 60.0 M4.0 0.0Q20.2 12.2 10.0 29.7Q30.1 35.0 28.2 55.6Q47.1 51.7 51.5 70.5Q67.2 60.0 77.3 76.0' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat top right / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'%3E%3Cpath d='M80 0L-2.0 0.0 M80 0L4.5 32.0 M80 0L24.1 60.0 M80 0L49.3 76.0 M80 0L77.1 82.0 M66.0 0.0Q69.0 2.2 67.1 5.5Q70.8 6.4 70.5 10.2Q73.9 9.5 74.8 13.0Q77.6 11.1 79.5 14.0 M52.0 0.0Q58.0 4.5 54.2 10.9Q61.6 12.9 60.9 20.5Q67.9 19.0 69.5 26.0Q75.3 22.1 79.0 28.0 M36.0 0.0Q45.4 7.0 39.5 17.2Q51.1 20.2 50.0 32.2Q60.9 29.9 63.5 40.8Q72.6 34.8 78.5 44.0 M20.0 0.0Q32.8 9.6 24.8 23.4Q40.6 27.6 39.1 43.9Q54.0 40.8 57.5 55.6Q69.9 47.4 77.9 60.0 M4.0 0.0Q20.2 12.2 10.0 29.7Q30.1 35.0 28.2 55.6Q47.1 51.7 51.5 70.5Q67.2 60.0 77.3 76.0' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat top right / contain;
  pointer-events: none;
}

html[data-season="halloween"] .hood-head h2::after,
html[data-season="halloween"] .play-now .hood-head h2::after {
  content: "";
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  margin-left: 0.3em;
  vertical-align: -0.05em;
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-12 -28 24 30'%3E%3Cpath d='M-1-24c0-3 2-5 4-5' fill='none' stroke='%232E7A4A' stroke-width='3'/%3E%3Cellipse cx='0' cy='-11' rx='11' ry='11' fill='%23FF9F43' stroke='%231E2A44' stroke-width='2'/%3E%3Cpath d='M-5-14l2-4 2 4zM1-14l2-4 2 4z' fill='%231E2A44'/%3E%3Cpath d='M-5-7q5 4 10 0' fill='none' stroke='%231E2A44' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* The whole page gets a cobweb in the top corners, under the header. */
html[data-season="halloween"] body:not([data-page="play"])::before,
html[data-season="halloween"] body:not([data-page="play"])::after {
  content: "";
  position: fixed;
  top: var(--header-h);
  z-index: 14;
  width: 110px;
  height: 110px;
  background: var(--web-color);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'%3E%3Cpath d='M80 0L-2.0 0.0 M80 0L4.5 32.0 M80 0L24.1 60.0 M80 0L49.3 76.0 M80 0L77.1 82.0 M66.0 0.0Q69.0 2.2 67.1 5.5Q70.8 6.4 70.5 10.2Q73.9 9.5 74.8 13.0Q77.6 11.1 79.5 14.0 M52.0 0.0Q58.0 4.5 54.2 10.9Q61.6 12.9 60.9 20.5Q67.9 19.0 69.5 26.0Q75.3 22.1 79.0 28.0 M36.0 0.0Q45.4 7.0 39.5 17.2Q51.1 20.2 50.0 32.2Q60.9 29.9 63.5 40.8Q72.6 34.8 78.5 44.0 M20.0 0.0Q32.8 9.6 24.8 23.4Q40.6 27.6 39.1 43.9Q54.0 40.8 57.5 55.6Q69.9 47.4 77.9 60.0 M4.0 0.0Q20.2 12.2 10.0 29.7Q30.1 35.0 28.2 55.6Q47.1 51.7 51.5 70.5Q67.2 60.0 77.3 76.0' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat top right / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'%3E%3Cpath d='M80 0L-2.0 0.0 M80 0L4.5 32.0 M80 0L24.1 60.0 M80 0L49.3 76.0 M80 0L77.1 82.0 M66.0 0.0Q69.0 2.2 67.1 5.5Q70.8 6.4 70.5 10.2Q73.9 9.5 74.8 13.0Q77.6 11.1 79.5 14.0 M52.0 0.0Q58.0 4.5 54.2 10.9Q61.6 12.9 60.9 20.5Q67.9 19.0 69.5 26.0Q75.3 22.1 79.0 28.0 M36.0 0.0Q45.4 7.0 39.5 17.2Q51.1 20.2 50.0 32.2Q60.9 29.9 63.5 40.8Q72.6 34.8 78.5 44.0 M20.0 0.0Q32.8 9.6 24.8 23.4Q40.6 27.6 39.1 43.9Q54.0 40.8 57.5 55.6Q69.9 47.4 77.9 60.0 M4.0 0.0Q20.2 12.2 10.0 29.7Q30.1 35.0 28.2 55.6Q47.1 51.7 51.5 70.5Q67.2 60.0 77.3 76.0' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat top right / contain;
  pointer-events: none;
  opacity: 0.8;
}

html[data-season="halloween"] body:not([data-page="play"])::before {
  left: 0;
  transform: scaleX(-1);
}

html[data-season="halloween"] body:not([data-page="play"])::after {
  right: 0;
}

/* Phones: the hero copy starts at the left edge, so only the right corner gets a web, a small one. */
@media (max-width: 759px) {
  html[data-season="halloween"] body:not([data-page="play"])::before {
    display: none;
  }

  html[data-season="halloween"] body:not([data-page="play"])::after {
    width: 56px;
    height: 56px;
  }
}

/* Fall and harvest: a sprig of leaves on panel corners. */
html:is([data-season="fall"], [data-season="harvest"]) :is(.daily, .finder, .board)::after {
  content: "";
  position: absolute;
  top: -12px;
  right: 10px;
  width: 54px;
  height: 36px;
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'%3E%3Cg stroke='%231E2A44' stroke-width='1.5' stroke-linejoin='round'%3E%3Cpath d='M58 2C48 2 38 10 36 22c12 0 20-8 22-20z' fill='%23FF9F43'/%3E%3Cpath d='M44 6C34 10 28 20 30 32c10-4 16-14 14-26z' fill='%23E9A21C'/%3E%3Cpath d='M30 2C22 6 18 14 20 24c8-4 12-12 10-22z' fill='%23E8743B'/%3E%3C/g%3E%3C/svg%3E");
  pointer-events: none;
}

/* Winter holidays and winter: snow piled on top of panels, with a few drips. */
html:is([data-season="holidays"], [data-season="winter"]) :is(.daily, .finder, .board)::before {
  content: "";
  position: absolute;
  top: -9px;
  left: 10px;
  right: 10px;
  height: 16px;
  border: 2px solid rgba(30, 42, 68, 0.25);
  border-bottom: 0;
  border-radius: 12px 12px 4px 4px;
  background:
    radial-gradient(circle at 18% 100%, #FFFFFF 5px, transparent 5.5px) 0 6px / 100% 12px no-repeat,
    radial-gradient(circle at 62% 100%, #FFFFFF 4px, transparent 4.5px) 0 6px / 100% 12px no-repeat,
    #FFFFFF;
  pointer-events: none;
  z-index: 1;
}

/* Winter holidays: a string of twinkling lights along the bottom of the header. */
html[data-season="holidays"] .site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -9px;
  height: 12px;
  background:
    radial-gradient(circle, #FF6B9A 3.5px, transparent 4px) 0 0 / 48px 12px repeat-x,
    radial-gradient(circle, #FFD23F 3.5px, transparent 4px) 12px 0 / 48px 12px repeat-x,
    radial-gradient(circle, #4CD98A 3.5px, transparent 4px) 24px 0 / 48px 12px repeat-x,
    radial-gradient(circle, #7CC8FF 3.5px, transparent 4px) 36px 0 / 48px 12px repeat-x;
  pointer-events: none;
  animation: lights-twinkle 1.4s steps(2, jump-none) infinite;
}

@keyframes lights-twinkle {
  50% { filter: brightness(1.35) saturate(1.3); opacity: 0.75; }
}

/* Spring: flowers on panel corners. Summer: a shell and a starfish. */
html[data-season="spring"] :is(.daily, .finder, .board)::after,
html[data-season="summer"] :is(.daily, .finder, .board)::after {
  content: "";
  position: absolute;
  top: -12px;
  right: 10px;
  width: 54px;
  height: 36px;
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'%3E%3Cg stroke='%231E2A44' stroke-width='1.4'%3E%3Ccircle cx='50' cy='10' r='6' fill='%23FF9FC0'/%3E%3Ccircle cx='38' cy='18' r='5' fill='%23B9A6F2'/%3E%3Ccircle cx='54' cy='26' r='4.5' fill='%23FFD23F'/%3E%3C/g%3E%3Cg fill='%23FFD23F'%3E%3Ccircle cx='50' cy='10' r='2'/%3E%3Ccircle cx='38' cy='18' r='1.8'/%3E%3C/g%3E%3C/svg%3E");
  pointer-events: none;
}

html[data-season="summer"] :is(.daily, .finder, .board)::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'%3E%3Cpath d='M40 30c0-10 6-18 14-18s6 18-14 18z' fill='%23FFC2D6' stroke='%231E2A44' stroke-width='1.5'/%3E%3Cpath d='M48 4l2.4 5 5.6.6-4.2 3.8 1.2 5.6-5-2.9-5 2.9 1.2-5.6-4.2-3.8 5.6-.6z' fill='%23FF9F43' stroke='%231E2A44' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
}

html.calm[data-season="holidays"] .site-header::after {
  animation: none;
}

/* ----- the phone menu (site.js initMenu): the header's links under a button, below 900 px ----- */

.menu-button {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: var(--border);
  border-radius: 50%;
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 3px 0 var(--ink);
  cursor: pointer;
}

.menu-button .i {
  width: 22px;
  height: 22px;
  vertical-align: 0;
}

.menu-button[aria-expanded="true"] {
  background: var(--sun);
  color: var(--ink);
}

.site-menu {
  position: absolute;
  top: 100%;
  right: var(--gutter);
  left: var(--gutter);
  z-index: 25;
  margin-top: 8px;
  padding: 8px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk-lg);
}

.site-menu ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}

.site-menu a {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0 14px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-weight: 800;
  font-size: 1.05rem;
  text-decoration: none;
}

.site-menu a:active {
  background: var(--tint-sun);
}

@media (hover: hover) and (pointer: fine) {
  .site-menu a:hover {
    background: var(--tint-sun);
  }
}

@media (min-width: 900px) {
  .menu-button,
  .site-menu {
    display: none;
  }
}

/* The narrowest phones: four things in the header. */
@media (max-width: 359px) {
  .header-actions {
    gap: 6px;
  }

  .menu-button,
  .me-button {
    width: 40px;
    height: 40px;
  }
}

/* Phones: with the menu button the header holds four things, so the wordmark gets smaller, and
   on the narrowest phones the logo stands alone (its link keeps the name for screen readers). */
@media (max-width: 899px) {
  .site-header .wordmark-text {
    font-size: 1.2rem;
  }
}

@media (max-width: 374px) {
  .site-header .wordmark-text {
    display: none;
  }
}

/* ----- your profile card and badge case (/avatar/, profile.js) ----- */

.profile-card {
  margin: 20px 0;
  padding: 16px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--chunk);
}

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

.profile-face {
  flex: 0 0 auto;
  width: 72px;
  height: 72px;
  border: var(--border);
  border-radius: 50%;
  background: var(--sky);
}

.profile-who h2 {
  margin: 0 0 4px;
}

.profile-title select {
  min-height: var(--touch);
  padding: 0 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--tint-violet);
  color: var(--text);
  font: inherit;
  font-size: 16px;
  font-weight: 800;
}

.profile-title-none {
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 700;
}

.profile-tops {
  margin: 6px 0 0;
  font-weight: 800;
  color: var(--felt-text);
}

.profile-pins {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 14px 0;
}

.profile-pin {
  display: grid;
  justify-items: center;
  gap: 4px;
  min-height: 72px;
  padding: 8px 6px;
  border: 2px dashed var(--rule);
  border-radius: 14px;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 700;
  text-align: center;
  align-content: center;
}

.profile-pin.is-pinned {
  border: 2px solid var(--ink);
  color: var(--ink);
  background: var(--tint-gold);
}

.profile-pin.is-pinned[data-tier="bronze"] { background: #F2B58A; }
.profile-pin.is-pinned[data-tier="silver"] { background: #D6DEEC; }
.profile-pin.is-pinned[data-tier="gold"] { background: var(--sun); }
.profile-pin.is-pinned[data-tier="diamond"] { background: #A8EEF5; }

.profile-pin .i {
  width: 22px;
  height: 22px;
}

.profile-pin-name {
  overflow-wrap: anywhere;
  line-height: 1.2;
}

.profile-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

@media (min-width: 640px) {
  .profile-stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.profile-stat {
  display: grid;
  padding: 10px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--bg);
}

.profile-stat-value {
  font: 700 1.25rem/1.2 var(--font-display);
  font-variant-numeric: tabular-nums;
}

.profile-stat-label {
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 800;
}

.profile-cols {
  display: grid;
  gap: 4px 24px;
  margin-top: 6px;
}

@media (min-width: 760px) {
  .profile-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.profile-favs,
.profile-ranks {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: grid;
  gap: 6px;
}

.profile-fav a {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--touch);
  color: var(--text);
  text-decoration: none;
}

.profile-fav img {
  width: 64px;
  height: 40px;
  border-radius: 8px;
  object-fit: cover;
}

.profile-fav-text {
  display: grid;
  min-width: 0;
}

.profile-fav-title {
  font-weight: 800;
}

.profile-fav-meta {
  color: var(--muted);
  font-size: 0.85rem;
}

.profile-rank {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
}

.profile-rank a {
  color: var(--text);
  font-weight: 700;
}

.profile-rank-place {
  display: inline-grid;
  place-items: center;
  min-width: 2.6em;
  height: 30px;
  padding: 0 8px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--bg);
  font: 700 0.95rem/1 var(--font-display);
}

.profile-rank.is-top .profile-rank-place {
  background: var(--sun);
  color: var(--ink);
}

.badge-case {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: grid;
  gap: 6px;
}

.badge-row {
  display: grid;
  grid-template-columns: minmax(0, 8em) minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 4px 0;
  border-top: 1px solid var(--rule);
}

.badge-row:first-child {
  border-top: 0;
}

.badge-game {
  overflow: hidden;
  color: var(--text);
  font-weight: 800;
  font-size: 0.9rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.badge-medals {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.medal {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 2px dashed var(--rule);
  border-radius: 50%;
  color: var(--rule);
}

.medal .i {
  width: 12px;
  height: 12px;
  vertical-align: 0;
}

.medal.is-done {
  border: 2px solid var(--ink);
  color: var(--ink);
}

.medal.is-done[data-tier="bronze"] { background: #F2B58A; }
.medal.is-done[data-tier="silver"] { background: #D6DEEC; }
.medal.is-done[data-tier="gold"] { background: var(--sun); }
.medal.is-done[data-tier="diamond"] { background: #A8EEF5; }

.badge-count {
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.pin-button {
  align-self: center;
  min-height: 36px;
  padding: 0 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 800;
  cursor: pointer;
}

.pin-button[aria-pressed="true"] {
  background: var(--sun);
  color: var(--ink);
}

@media (pointer: coarse) {
  .pin-button {
    min-height: var(--touch);
  }
}

/* Phones: the game's name and count on one line, its medals on the next. */
@media (max-width: 559px) {
  .badge-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "game count" "medals medals";
    row-gap: 6px;
    padding: 8px 0;
  }

  .badge-game { grid-area: game; }
  .badge-count { grid-area: count; }
  .badge-medals { grid-area: medals; }
}

/* ----- sign up, for guests (site.js initSignup) ----- */

.signup-pill {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 16px;
  border: var(--border);
  border-radius: 999px;
  background: var(--sun);
  box-shadow: 0 3px 0 var(--ink);
  color: var(--ink);
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}

/* Phones: the header is full, so Sign up lives at the top of the menu instead. */
@media (max-width: 599px) {
  .signup-pill {
    display: none;
  }
}

.site-menu .site-menu-signup {
  margin-bottom: 4px;
  background: var(--sun);
  color: var(--ink);
  border: 2px solid var(--ink);
}

.save-nudge {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px 12px;
  align-items: start;
  margin: 14px 0 0;
  padding: 14px;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--tint-sun);
  box-shadow: var(--chunk);
  position: relative;
  z-index: 2;
}

.save-nudge > .i {
  width: 28px;
  height: 28px;
  color: var(--gold);
}

.save-nudge p {
  margin: 0;
}

.save-nudge-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (min-width: 760px) {
  .save-nudge {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
  }

  .save-nudge-actions {
    grid-column: auto;
  }
}
