/*
 * Uppy — UI chrome styled after Apple HIG principles.
 * Game canvas (sky / balloon / clouds) intentionally stays playful.
 *
 * Applying:
 *  - SF Pro Rounded font stack (friendly casual context)
 *  - Display text: tight tracking, weight 600–700 (not 800)
 *  - Apple system colors: systemPink, systemGreen, systemBlue tints
 *  - Thick materials: backdrop-filter blur(30px) saturate(180%)
 *  - Flat buttons with scale(0.96) on :active (no "candy press" shadows)
 *  - Standard cubic-bezier(0.32, 0.72, 0, 1) easing
 *  - 4/8/16/24 spacing scale
 *  - 44pt minimum touch targets
 *  - prefers-reduced-motion respected
 */

:root {
  --label:          #1d1d1f;            /* primary label, near-black */
  --label-secondary:rgba(60, 60, 67, 0.60);
  --label-tertiary: rgba(60, 60, 67, 0.30);
  --separator:      rgba(60, 60, 67, 0.18);
  --system-pink:    #ff375f;
  --system-pink-pressed: #e62e51;
  --system-green:   #34c759;
  --system-green-pressed:#2eb350;
  --system-blue:    #0a84ff;
  --material-thick: rgba(255, 255, 255, 0.72);
  --material-regular: rgba(255, 255, 255, 0.55);
  --material-thin:  rgba(255, 255, 255, 0.42);
  --tint-shadow:    0 1px 0 rgba(255,255,255,0.6) inset, 0 0 0 0.5px rgba(0,0,0,0.04);
  --shadow-card:    0 12px 36px rgba(20, 28, 40, 0.18), 0 2px 8px rgba(20,28,40,0.06);
  --ease-standard:  cubic-bezier(0.32, 0.72, 0, 1);
  --ease-spring:    cubic-bezier(0.34, 1.56, 0.64, 1);
  --radius-card:    20px;
  --radius-control: 12px;
  --radius-pill:    999px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Rounded", "SF Pro Display",
               "SF Pro Text", ui-rounded, "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;
  background: linear-gradient(180deg, #cdefff 0%, #a5dff7 60%, #b6e8c5 100%);
  color: var(--label);
  overflow: hidden;
  -webkit-user-select: none;
  user-select: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

canvas#game {
  display: block;
  width: 100vw;
  height: 100vh;
  cursor: default;
  /* Disable browser touch gestures (scroll, pinch/double-tap zoom) so taps go
     straight to the game and don't pan/zoom the page on mobile. */
  touch-action: none;
}
canvas#game.over-balloon { cursor: pointer; }

/* ---------- Rotate-to-landscape gate (mobile) ---------- */
/* Hidden by default; shown only on touch devices held in portrait. Covers
   everything so the game is never played in portrait. */
.rotate-overlay { display: none; }

@media (max-width: 900px) and (orientation: portrait) and (pointer: coarse) {
  .rotate-overlay {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: linear-gradient(180deg, #cdefff 0%, #a5dff7 60%, #b6e8c5 100%);
    text-align: center;
  }
}
.rotate-card {
  max-width: 280px;
  color: var(--label);
}
.rotate-icon {
  font-size: 56px;
  line-height: 1;
  margin-bottom: 16px;
  animation: rotate-hint 2s var(--ease-standard) infinite;
}
.rotate-card p {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.4;
  margin: 0;
}
@keyframes rotate-hint {
  0%, 100% { transform: rotate(0deg); }
  50%      { transform: rotate(90deg); }
}
@media (prefers-reduced-motion: reduce) {
  .rotate-icon { animation: none; }
}

/* ---------- Playfield frame (blank sidebars) ---------- */
/* The game world is a fixed size; on larger screens these opaque panels cover
   the leftover space so the playfield reads as a defined area rather than
   running over into the background. Sized/positioned in main.js. Intentionally
   blank for now — content may live here later. */

.frame-panel {
  position: fixed;
  /* Sky-to-grass gradient matching the playfield: blue at top fading to green
     at the bottom. background-attachment: fixed + a viewport-sized gradient
     makes all four panels sample one continuous wash, so they line up
     seamlessly with each other (and the page background) instead of each panel
     restarting its own gradient. */
  background-image: linear-gradient(180deg, #cdefff 0%, #a5dff7 60%, #b6e8c5 100%);
  background-attachment: fixed;
  background-size: 100vw 100vh;
  background-position: 0 0;
  pointer-events: none;
  z-index: 1;
}
.frame-left  { box-shadow: inset -0.5px 0 0 var(--separator); }
.frame-right { box-shadow: inset 0.5px 0 0 var(--separator); }
.frame-top    { box-shadow: inset 0 -0.5px 0 var(--separator); }
.frame-bottom { box-shadow: inset 0 0.5px 0 var(--separator); }

/* ---------- HUD ---------- */

.hud {
  position: fixed;
  top: 0; left: 0; right: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  padding: max(16px, env(safe-area-inset-top, 0px)) 24px 0;
  pointer-events: none;
  z-index: 5;
}

.hud-left { justify-self: start; }
.hud-right { justify-self: end; display: flex; gap: 8px; align-items: center; }
.hud-center { justify-self: center; text-align: center; }

/* Cog/icon pill — clickable even though the HUD is pointer-events:none.
   Sized to the 44pt minimum touch target documented elsewhere in this file. */
.pill-icon {
  pointer-events: auto;
  min-width: 44px;
  height: 44px;
  padding: 0;
  font-size: 17px;
  text-decoration: none;
  cursor: pointer;
}
.pill-icon:active { transform: scale(0.94); }
/* The profile-silhouette glyph inside the settings/profile buttons (inherits the
   button's `color` via fill:currentColor). */
.pill-icon svg, .overlay-cog svg { width: 22px; height: 22px; display: block; }

/* Settings cog over the join / game-over modals. Body-level (see index.html)
   so position:fixed anchors to the window, and z-index sits above the overlay
   backdrop (10). */
.overlay-cog {
  position: fixed;
  top: max(16px, env(safe-area-inset-top, 0px));
  right: 24px;
  z-index: 12;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  text-decoration: none;
  color: var(--label-secondary);
  border-radius: 50%;
  border: 0.5px solid var(--separator);
  background: var(--material-thick);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  transition: transform .12s var(--ease-spring), color .2s var(--ease-standard);
}
.overlay-cog:hover { color: var(--label); }
.overlay-cog:active { transform: scale(0.92); }
/* The display:flex above would otherwise defeat the `hidden` attribute, leaving
   the cog visible during play (overlapping the HUD). Honor it explicitly. */
.overlay-cog[hidden] { display: none; }

.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 32px;
  padding: 0 14px;
  background: var(--material-thick);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border-radius: var(--radius-pill);
  border: 0.5px solid var(--separator);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--label);
  font-variant-numeric: tabular-nums;
  transition: background-color .25s var(--ease-standard),
              color .25s var(--ease-standard),
              border-color .25s var(--ease-standard);
}
.pill.ready {
  background: var(--system-green);
  color: white;
  border-color: transparent;
}

/* ---------- Player list ---------- */
/* Compact, scrollable roster of everyone in the lobby. Each entry has a color
   dot matching the player's palette color. Capped height so it never crowds the
   playfield; scrolls when the lobby is large. */
.player-list {
  list-style: none;
  margin: 0;
  /* No top padding so the sticky header sits flush; side/bottom padding stays. */
  padding: 0 6px 6px;
  max-width: 160px;
  max-height: min(45vh, 320px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--material-thick);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid var(--separator);
  border-radius: var(--radius-control);
  pointer-events: auto; /* allow scrolling even though .hud is pointer-events:none */
  scrollbar-width: thin;
}
.player-list:empty { display: none; }

/* Sticky count header — pinned to the top of the list while it scrolls. Opaque
   background + z-index so player rows slide underneath it, not over it. */
.player-list .roster-header {
  position: sticky;
  top: 0;
  z-index: 1;
  /* Cancel the container's side padding so the bar spans full width. */
  margin: 0 -6px 2px;
  padding: 7px 14px 5px;
  background: var(--material-thick);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border-bottom: 0.5px solid var(--separator);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--label-secondary);
  font-variant-numeric: tabular-nums;
}
.player-list li {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 8px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--label);
  border-radius: 7px;
  white-space: nowrap;
}
.player-list li .dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.12) inset;
}
.player-list li .name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player-list li.me .name { font-weight: 700; }
/* Player's best score for this lobby, right-aligned in the row. */
.player-list li .roster-best {
  flex: 0 0 auto;
  color: var(--label-secondary);
  font-variant-numeric: tabular-nums;
}

.score {
  font-weight: 700;
  font-size: 44px;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--label);
  font-variant-numeric: tabular-nums;
}
.score-label { margin-top: 6px; }

/* Apple "caption" style — small caps */
.caption {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label-secondary);
}

/* ---------- Overlays + cards (modals) ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 10;
  background: rgba(15, 25, 40, 0.28);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .35s var(--ease-standard);
}
.overlay.hidden { opacity: 0; pointer-events: none; }

.card {
  position: relative;
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(40px) saturate(180%);
  backdrop-filter: blur(40px) saturate(180%);
  border-radius: var(--radius-card);
  padding: 28px 28px 24px;
  width: min(380px, calc(100vw - 32px));
  border: 0.5px solid rgba(255, 255, 255, 0.6);
  box-shadow: var(--shadow-card);
  text-align: center;
  /* Subtle entrance */
  animation: card-in .45s var(--ease-standard) both;
}

@keyframes card-in {
  from { opacity: 0; transform: scale(0.94) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.card h1 {
  margin: 0 0 4px;
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.022em;
  color: var(--label);
}
.tagline {
  margin: 0 0 20px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--label-secondary);
}

.gameover-title {
  margin: 0 0 4px;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--label);
}
.final-score {
  font-weight: 700;
  font-size: 80px;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--system-pink);
  margin: 8px 0 4px;
  font-variant-numeric: tabular-nums;
}
.card .caption { margin-bottom: 20px; }

/* ---------- Inputs ---------- */

#join-form { display: flex; flex-direction: column; gap: 10px; }
#join-form input {
  font: inherit;
  font-size: 17px;
  padding: 13px 16px;
  height: 48px;
  border-radius: var(--radius-control);
  border: 0.5px solid var(--separator);
  background: rgba(255, 255, 255, 0.7);
  color: var(--label);
  outline: none;
  transition: border-color .2s var(--ease-standard),
              box-shadow .2s var(--ease-standard);
}
#join-form input::placeholder { color: var(--label-tertiary); }
#join-form input:focus {
  border-color: var(--system-blue);
  box-shadow: 0 0 0 4px rgba(10, 132, 255, 0.18);
}

/* ---------- Buttons ---------- */

.btn {
  font: inherit;
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.01em;
  height: 48px;
  padding: 0 20px;
  width: 100%;
  border-radius: var(--radius-control);
  border: 0;
  color: white;
  cursor: pointer;
  /* Center the label and drop the default link underline so an <a class="btn">
     renders identically to a <button class="btn">. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  transition: transform .12s var(--ease-spring),
              background-color .2s var(--ease-standard),
              opacity .2s var(--ease-standard);
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { opacity: 0.92; }
.btn:active { transform: scale(0.96); }
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px rgba(10, 132, 255, 0.25);
}
.btn-primary { background: var(--system-pink); }
.btn-primary:active { background: var(--system-pink-pressed); }
.btn-success { background: var(--system-green); }
.btn-success:active { background: var(--system-green-pressed); }
/* Secondary action: translucent glass, used for the game-over invite button. */
.btn-secondary {
  background: var(--material-thick);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid var(--separator);
  color: var(--label);
}
.btn-secondary:active { background: var(--separator); }
/* Split layout: "Invite a friend" on the left, a subdued segment with the code +
   copy icon on the right. overflow:hidden clips that segment to the btn radius. */
.gameover-invite {
  margin-top: 10px;
  padding: 0;
  gap: 0;
  overflow: hidden;
  justify-content: flex-start; /* label hugs its text, code segment fills the rest */
}
.gameover-invite-label { padding: 0 16px; flex: none; }
/* Code segment takes the remaining width, with the code centered in it. */
.gameover-invite .invite-code-group { flex: 1; }

/* ---------- Invite code chip (bottom-left) ---------- */
/* Shows the lobby code; click copies the lobby URL. Glass pill matching the HUD,
   sitting above the canvas with its own pointer events. */
.invite[hidden] { display: none; } /* explicit display below would defeat `hidden` */
.invite {
  position: fixed;
  left: 24px;
  bottom: max(20px, env(safe-area-inset-bottom, 0px));
  z-index: 6;
  display: inline-flex;
  align-items: center;
  gap: 0;
  height: 36px;
  padding: 0;
  overflow: hidden; /* clip the code segment's background to the pill radius */
  font: inherit;
  cursor: pointer;
  background: var(--material-thick);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid var(--separator);
  border-radius: var(--radius-pill);
  color: var(--label);
  transition: transform .12s var(--ease-spring);
}
.invite:active { transform: scale(0.96); }
.invite-label {
  padding: 0 10px 0 14px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--label-secondary);
}
.invite-code {
  flex: 1; /* take the segment's free space so the code centers and the icon pins right */
  text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* The split "copy" segment shared by the chip and game-over button: a subdued
   fill holding the code and a copy icon, divided from the label by a hairline. */
.invite-code-group {
  display: inline-flex;
  align-items: center;
  align-self: stretch; /* fill the control's height to read as a split segment */
  gap: 6px;
  padding: 0 12px;
  background: rgba(60, 60, 67, 0.10);
  border-left: 0.5px solid var(--separator);
}
.invite-copy-icon {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--label-secondary);
}
/* On the chip, the label hugs its text; give the code segment extra length so
   the centered code has breathing room. */
.invite .invite-label { flex: none; }
.invite .invite-code-group { min-width: 96px; }

/* ---------- First-run invite coachmark ---------- */
/* A one-time popover anchored just above the invite chip (bottom-left), with a
   little arrow pointing down to it. Visibility is driven by JS (shown once). */
.invite-tip[hidden] { display: none; }
.invite-tip {
  position: fixed;
  left: 24px;
  /* Sit just above the invite chip: chip bottom offset + chip height + gap. */
  bottom: calc(max(20px, env(safe-area-inset-bottom, 0px)) + 36px + 12px);
  z-index: 7;
  max-width: 220px;
  padding: 10px 14px;
  background: var(--system-pink);
  color: white;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  border-radius: var(--radius-control);
  box-shadow: var(--shadow-card);
  pointer-events: none; /* purely informational; taps fall through to the game */
  animation: invite-tip-in .35s var(--ease-spring) both, invite-tip-bob 2.4s var(--ease-standard) .4s infinite;
}
/* Dissolve out instead of vanishing. Cancel the show/bob animations so their
   `forwards` fill doesn't pin opacity and override this fade. */
.invite-tip.dissolving {
  animation: none;
  opacity: 0;
  transition: opacity .4s var(--ease-standard);
}
/* Downward arrow pointing at the invite chip. */
.invite-tip::after {
  content: "";
  position: absolute;
  left: 28px;
  bottom: -6px;
  width: 12px;
  height: 12px;
  background: var(--system-pink);
  transform: rotate(45deg);
  border-radius: 2px;
}
@keyframes invite-tip-in {
  from { opacity: 0; transform: translateY(6px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes invite-tip-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
  .invite-tip { animation: invite-tip-in .35s var(--ease-spring) both; }
}

/* Version watermark: the deployed commit hash, faint at the bottom of the
   playfield so it's identifiable but unobtrusive. Sits below the overlays. */
.version-watermark {
  position: fixed;
  left: 50%;
  bottom: max(5px, env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 3;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.02em;
  color: rgba(60, 60, 67, 0.35);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}
.version-watermark:empty { display: none; }

/* ---------- Toast ---------- */
/* Brief bottom-center feedback, e.g. "Invite link copied" via showToast(). */

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translate(-50%, 16px);
  background: rgba(20, 28, 40, 0.78);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  color: white;
  padding: 10px 16px;
  border-radius: var(--radius-pill);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: -0.01em;
  opacity: 0;
  transition: opacity .25s var(--ease-standard), transform .25s var(--ease-standard);
  pointer-events: none;
  /* Above the overlays (z-index 10) and the overlay cog (12) so the "link copied"
     toast is visible when triggered from the game-over modal's invite button. */
  z-index: 20;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- Accessibility ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* User-toggled reduced motion (Settings page; complements the media query). */
.reduce-motion *,
.reduce-motion *::before,
.reduce-motion *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
}

/* ---------- Landing / marketing page ---------- */
/* The global body sets overflow:hidden for the game canvas; the landing page is
   a normal scrolling document, so re-enable scroll here. */
.landing-body { overflow: auto; }
.landing {
  max-width: 640px;
  margin: 0 auto;
  padding: max(32px, env(safe-area-inset-top, 0px)) 20px 48px;
}
.landing-hero {
  text-align: center;
  padding: 32px 0 24px;
}
.landing-balloon {
  font-size: 72px;
  line-height: 1;
  animation: landing-bob 3s var(--ease-standard) infinite;
}
@keyframes landing-bob {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-10px) rotate(2deg); }
}
.landing-hero h1 {
  margin: 12px 0 4px;
  font-size: 48px;
  font-weight: 700;
  letter-spacing: -0.03em;
}
.landing-tagline {
  margin: 0 0 24px;
  font-size: 19px;
  color: var(--label-secondary);
}
.landing-play {
  width: auto;
  min-width: 160px;
  padding: 0 32px;
}
.landing-sub {
  margin: 14px 0 0;
  font-size: 13px;
  color: var(--label-tertiary);
}
/* Live "N players in the air" indicator — only revealed when >2 are online. */
.landing-online {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 16px 0 0;
  padding: 5px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
  border: 0.5px solid rgba(255, 255, 255, 0.6);
  box-shadow: var(--shadow-card);
  font-size: 13px;
  font-weight: 600;
  color: var(--label-secondary);
}
.landing-online[hidden] { display: none; }
/* The three description cards: stacked on mobile, in a row on wider screens. */
.landing-cards {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 24px;
}
@media (min-width: 720px) {
  .landing { max-width: 980px; }
  .landing-cards {
    flex-direction: row;
    align-items: stretch;
  }
  .landing-cards .landing-card { flex: 1; }
}
.landing-card {
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid rgba(255, 255, 255, 0.6);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 22px 24px;
}
.landing-card h2 {
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.landing-card p { margin: 0; line-height: 1.55; color: var(--label); }
.landing-steps, .landing-points {
  margin: 0;
  padding-left: 22px;
  line-height: 1.6;
}
.landing-steps li, .landing-points li { margin-bottom: 8px; }
/* ---------- Settings / profile page ---------- */

.settings-body { overflow: auto; }
.settings {
  max-width: 560px;
  margin: 0 auto;
  padding: max(20px, env(safe-area-inset-top, 0px)) 20px 40px;
}
.settings-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 20px;
}
.settings-head h1 { margin: 0; font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }
.settings-back {
  color: var(--system-blue);
  text-decoration: none;
  font-weight: 600;
  font-size: 16px;
}
.settings-card {
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid rgba(255, 255, 255, 0.6);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 18px 20px;
  margin-bottom: 16px;
}
.settings-card h2 {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--label-secondary);
}
.kv { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.kv span:first-child { color: var(--label-secondary); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; }
.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.stat { background: var(--material-thin); border-radius: var(--radius-control); padding: 12px 14px; }
.stat-n { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; }
.stat-l { font-size: 12px; color: var(--label-secondary); margin-top: 4px; }
.recent { list-style: none; margin: 0; padding: 0; }
.recent li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 0.5px solid var(--separator);
}
.recent li:last-child { border-bottom: 0; }
.recent .r-score { font-weight: 700; font-variant-numeric: tabular-nums; }
.recent .r-date { font-size: 12px; }
.muted { color: var(--label-tertiary); }
.toggle { display: flex; align-items: center; gap: 12px; font-size: 16px; font-weight: 600; cursor: pointer; }
.toggle input { width: 20px; height: 20px; accent-color: var(--system-green); }
.btn-danger { background: var(--system-pink); }
.btn-danger:hover { background: var(--system-pink-pressed); }
