/* Guess the Key — page styles. */

/* ── Layout shell ────────────────────────────────────────────────────── */
.gk-page {
  position: relative;
  max-width: 820px;
  margin: 0 auto;
  padding: 0 24px 80px;
  min-height: calc(100vh - 120px);
  display: grid;
  gap: 24px;
  justify-items: center;
  align-content: center;
  /* Random hue picked per round; the frame edge pulses in this colour. */
  --pulse-hue: 220;
}

/* Background pulse — a faint radial halo that breathes during playback. */
.gk-bgpulse {
  position: absolute;
  inset: -120px 0 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse 70% 50% at 50% 28%,
    rgba(var(--glow-rgb), 0.10),
    transparent 70%
  );
  opacity: 0;
  transition: opacity 0.4s var(--ease-out);
}
.gk-page[data-uistate="playing"] .gk-bgpulse {
  opacity: 1;
  animation: gk-bgpulse var(--gk-pulse-duration, 0.6s) ease-in-out infinite alternate;
}
@keyframes gk-bgpulse {
  from { transform: scale(1);    opacity: 0.55; }
  to   { transform: scale(1.06); opacity: 1.00; }
}

/* ── Hero ────────────────────────────────────────────────────────────── */
.gk-intro {
  text-align: center;
  justify-self: center;
  padding: 4px 8px 0;
  max-width: 390px;
  transition: opacity 0.5s var(--ease-out),
              max-height 0.5s var(--ease-out),
              padding 0.45s var(--ease-out),
              transform 0.5s var(--ease-out),
              margin 0.45s var(--ease-out);
  overflow: visible;
  max-height: 240px;
  position: relative;
  z-index: 1;
}
.gk-page[data-uistate="playing"]  .gk-intro,
.gk-page[data-uistate="guessing"] .gk-intro,
.gk-page[data-uistate="reveal"]   .gk-intro {
  opacity: 0;
  max-height: 0;
  padding: 0;
  margin: 0;
  pointer-events: none;
  transform: translateY(-8px);
}
.gk-hero-inner { position: relative; z-index: 2; }
.gk-hero-title {
  /* Century Gothic Bold per Timur. The custom font stack already lists
     Century Gothic first; we bump weight to 700. */
  font: 700 clamp(44px, 8vw, 72px)/0.95 var(--font);
  letter-spacing: 0;
  margin: 0 0 12px;
}
.gk-hero-sub {
  color: var(--ink-dim);
  font: 600 14px/1.35 var(--font);
  margin: 0 auto;
  max-width: 340px;
}

/* (Circle-of-fifths styles removed — feature was cut.) */

/* ── Centered square game frame ─────────────────────────────────────── */
.gk-frame {
  position: relative;
  z-index: 1;
  width: 560px;
  max-width: min(560px, 92vw);
  aspect-ratio: 1 / 1;
  margin: 0 auto;
  padding: 32px 28px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 24px;
  box-shadow: var(--shadow-card);
  display: grid;
  gap: 20px;
  justify-items: center;
  align-content: start;
  transition: box-shadow 0.4s var(--ease-out),
              transform 0.4s var(--ease-out);
}

/* Volumetric fog — soft coloured radial gradients drifting inside the frame
   while audio plays. NOT a rim/border (would read as "selected"). Instead,
   three layered radials orbit slowly around the frame's interior, giving the
   sense of fog moving through the room. Hue rotates from --pulse-hue per
   round so no single colour gives anything away. */
.gk-frame {
  overflow: hidden;       /* contain the fog */
}
.gk-frame::before {
  content: '';
  position: absolute;
  inset: -20%;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(circle 240px at 30% 35%, hsla(calc(var(--pulse-hue, 220) * 1deg), 75%, 60%, 0.30), transparent 60%),
    radial-gradient(circle 280px at 75% 70%, hsla(calc((var(--pulse-hue, 220) + 80) * 1deg), 75%, 60%, 0.24), transparent 65%),
    radial-gradient(circle 220px at 50% 90%, hsla(calc((var(--pulse-hue, 220) + 200) * 1deg), 75%, 60%, 0.20), transparent 70%);
  filter: blur(36px);
  opacity: 0;
  transition: opacity 0.6s var(--ease-out);
}
.gk-page[data-uistate="playing"]  .gk-frame::before,
.gk-page[data-uistate="guessing"] .gk-frame::before {
  opacity: 1;
  animation: gk-fog-orbit 16s ease-in-out infinite,
             gk-fog-breath var(--gk-pulse-duration, 0.7s) ease-in-out infinite alternate;
}
.gk-frame::after {
  content: '';
  position: absolute;
  inset: 8%;
  z-index: 0;
  pointer-events: none;
  background:
    conic-gradient(
      from 210deg,
      transparent 0 10%,
      hsla(calc(var(--pulse-hue, 220) * 1deg), 82%, 66%, 0.12) 16%,
      transparent 24% 44%,
      hsla(calc((var(--pulse-hue, 220) + 140) * 1deg), 76%, 64%, 0.10) 52%,
      transparent 64% 100%
    );
  border-radius: 50%;
  filter: blur(22px);
  opacity: 0.28;
  animation: gk-ambient-orbit 18s linear infinite;
}
.gk-frame::before,
.gk-frame::after {
  content: none;
}
@keyframes gk-ambient-orbit {
  from { transform: rotate(0deg) scale(0.96); }
  to   { transform: rotate(360deg) scale(0.96); }
}
@keyframes gk-fog-orbit {
  0%   { transform: translate(0%, 0%) rotate(0deg); }
  25%  { transform: translate(8%, -6%) rotate(8deg); }
  50%  { transform: translate(-6%, 6%) rotate(-6deg); }
  75%  { transform: translate(-4%, -4%) rotate(4deg); }
  100% { transform: translate(0%, 0%) rotate(0deg); }
}
@keyframes gk-fog-breath {
  from { opacity: 0.70; filter: blur(36px); }
  to   { opacity: 1.00; filter: blur(48px); }
}
/* Bring every interactive layer above the fog. .gk-playcenter is excluded
   so it can keep its own `position: absolute` for geometric centring. */
.gk-frame > *:not(.gk-frame-bg):not(.gk-playcenter) { position: relative; z-index: 1; }
.gk-frame > .gk-playcenter { z-index: 3; }   /* z-index without overriding position:absolute */
.gk-page[data-uistate="playing"] .gk-frame { box-shadow: var(--shadow-card), var(--glow-soft); }

/* Frame breathes on every state entry — small fade-in/scale-up. The keyframe
   is restarted by the change in state attribute (CSS animations only fire on
   the rule's first application). */
.gk-page[data-uistate="playing"]  .gk-frame,
.gk-page[data-uistate="guessing"] .gk-frame,
.gk-page[data-uistate="reveal"]   .gk-frame {
  animation: gk-frame-breath 0.55s var(--ease-out);
}
.gk-page[data-uistate="guessing"] .gk-frame,
.gk-page[data-uistate="reveal"] .gk-frame {
  aspect-ratio: auto;
  min-height: 560px;
  overflow: visible;
}
@keyframes gk-frame-breath {
  0%   { opacity: 0.55; transform: scale(0.985); }
  100% { opacity: 1;    transform: scale(1); }
}

/* ── Status bar ──────────────────────────────────────────────────────── */
.gk-status {
  display: flex;
  justify-content: center;
  gap: 40px;
  align-items: center;
  width: 100%;
  transition: opacity 0.4s var(--ease-out),
              max-height 0.4s var(--ease-out),
              margin 0.4s var(--ease-out);
}
.gk-page[data-uistate="hero"] .gk-status {
  opacity: 0;
  max-height: 0;
  margin: -28px 0 0;
  pointer-events: none;
  overflow: hidden;
}
.gk-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.gk-stat-label {
  font: 500 10px/1 var(--font);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.gk-stat-value {
  font: 400 22px/1 var(--font-mono, 'JetBrains Mono', monospace);
  color: var(--ink);
  font-feature-settings: 'tnum' 1;
}

/* ── Play area ───────────────────────────────────────────────────────── */
.gk-playarea {
  display: grid;
  justify-items: center;
  gap: 14px;
  width: 100%;
}
/* Note button sits at the geometric centre of the frame, anchored absolute
   to the frame regardless of what else is in the playarea. */
.gk-playcenter {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.5s var(--ease-out),
              transform 0.5s var(--ease-spring);
}
.gk-page[data-uistate="reveal"]   .gk-playcenter {
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.7);
}
.gk-play {
  appearance: none;
  background: var(--bg-card);
  border: 1.5px solid var(--ink);
  color: var(--ink);
  width: clamp(78px, 16vw, 96px);
  height: clamp(78px, 16vw, 96px);
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s var(--ease-out),
              color 0.2s var(--ease-out),
              transform 0.22s var(--ease-spring),
              opacity 0.3s var(--ease-out),
              box-shadow 0.25s var(--ease-out),
              width 0.4s var(--ease-spring),
              height 0.4s var(--ease-spring);
  box-shadow:
    0 0 0 0 rgba(var(--glow-rgb), 0),
    0 12px 36px rgba(0, 0, 0, 0.08);
}
/* Once Play has fired, the play button disappears — the audio plays once,
   the user listens and answers. No replays during the round. The button only
   resurfaces in the hero state to kick off the next session. */
.gk-page[data-uistate="playing"]  .gk-play {
  pointer-events: none;
  background: var(--ink);
  color: var(--bg);
  border-color: transparent;
  animation: gk-note-sonar var(--gk-pulse-duration, 0.72s) ease-in-out infinite alternate;
}
.gk-page[data-uistate="playing"] .gk-play.is-beat {
  animation: gk-stage-beat 0.22s var(--ease-spring);
}
.gk-page[data-uistate="guessing"] .gk-play,
.gk-page[data-uistate="reveal"]   .gk-play {
  opacity: 0;
  pointer-events: none;
  transform: scale(0.4);
  max-height: 0;
  max-width: 0;
  margin: 0;
}
@keyframes gk-note-sonar {
  from {
    transform: scale(0.92);
    box-shadow:
      0 0 0 0 rgba(var(--glow-rgb), 0.42),
      0 0 26px rgba(var(--glow-rgb), 0.32);
  }
  to {
    transform: scale(1.08);
    box-shadow:
      0 0 0 30px rgba(var(--glow-rgb), 0),
      0 0 48px rgba(var(--glow-rgb), 0.48);
  }
}
@keyframes gk-stage-beat {
  0%   { transform: scale(0.94); box-shadow: 0 0 0 0 rgba(var(--glow-rgb), 0.34); }
  45%  { transform: scale(1.14); box-shadow: 0 0 0 20px rgba(var(--glow-rgb), 0.10), 0 0 42px rgba(var(--glow-rgb), 0.38); }
  100% { transform: scale(1); box-shadow: 0 0 0 30px rgba(var(--glow-rgb), 0); }
}
/* Replay button is removed entirely — re-listening is not allowed. */
.gk-replay { display: none !important; }
/* Countdown overlay — sits on top of the play button while counting. */
.gk-countdown {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(0.6);
  font: 300 96px/1 var(--font);
  color: var(--ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--ease-out);
}
.gk-countdown.is-active { opacity: 1; }
.gk-countdown.is-pop {
  animation: gk-count-pop 0.65s var(--ease-spring);
}
.gk-countdown.is-phrase {
  width: max-content;
  max-width: min(340px, 72vw);
  font: 700 clamp(28px, 6vw, 46px)/1 var(--font);
  letter-spacing: 0;
  text-align: center;
  color: var(--ink);
}
@keyframes gk-count-pop {
  0%   { transform: translate(-50%, -50%) scale(0.4); opacity: 0; filter: blur(6px); }
  25%  { transform: translate(-50%, -50%) scale(1.15); opacity: 1; filter: blur(0); text-shadow: var(--glow-soft); }
  60%  { transform: translate(-50%, -50%) scale(1);    opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(0.95); opacity: 0;  filter: blur(2px); }
}
/* While countdown is on screen, dim the play button so the digit owns the stage. */
.gk-countdown.is-active ~ .gk-play,
.gk-playcenter:has(.gk-countdown.is-active) .gk-play {
  opacity: 0.18;
  transform: scale(0.88);
}
.gk-play:hover:not(:disabled) {
  background: var(--ink);
  color: var(--bg);
  transform: scale(1.05);
  box-shadow: var(--glow-soft);
}
.gk-play:disabled { opacity: 0.4; cursor: not-allowed; }
/* When the user actually fires the opening chord, the note glows for ~1s. */
.gk-play.is-glowing {
  background: var(--ink);
  color: var(--bg);
  box-shadow: var(--glow-strong);
  transform: scale(1.1);
}
.gk-stage-submit {
  position: absolute;
  top: 50%;
  left: 50%;
  min-width: 150px;
  height: 48px;
  transform: translate(-50%, -50%) scale(0.72);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s var(--ease-out),
              transform 0.42s var(--ease-spring),
              background 0.2s var(--ease-out),
              color 0.2s var(--ease-out);
  box-shadow: 0 16px 42px rgba(0, 0, 0, 0.12);
}
.gk-page[data-uistate="guessing"] .gk-stage-submit {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
.gk-page[data-uistate="guessing"] .gk-stage-submit:disabled {
  pointer-events: none;
  opacity: 0.34;
}

.gk-replay {
  appearance: none;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font: 500 12px/1 var(--font);
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: opacity 0.3s var(--ease-out), border-color 0.2s;
}
.gk-replay:disabled { opacity: 0; pointer-events: none; }
.gk-replay:hover:not(:disabled) { border-color: var(--line-bright); }

.gk-playstate {
  text-align: center;
  font: 400 13px/1.4 var(--font);
  color: var(--ink-faint);
  min-height: 1.4em;
}

/* ── Answer surface ──────────────────────────────────────────────────── */
.gk-answer {
  display: grid;
  gap: 24px;
  justify-items: center;
  width: 100%;
  transition: opacity 0.4s var(--ease-out),
              max-height 0.45s var(--ease-out),
              transform 0.4s var(--ease-out);
}
.gk-page[data-uistate="hero"] .gk-answer,
.gk-page[data-uistate="playing"] .gk-answer,
.gk-page[data-uistate="reveal"]   .gk-answer {
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  pointer-events: none;
  transform: translateY(10px);
  margin: 0;
}
.gk-page[data-uistate="guessing"] .gk-wheel,
.gk-page[data-uistate="guessing"] .gk-keyslider,
.gk-page[data-uistate="guessing"] .gk-schemas {
  animation: gk-fade-up 0.45s var(--ease-out) both;
}
.gk-page[data-uistate="guessing"] .gk-keyslider { animation-delay: 0.10s; }
.gk-page[data-uistate="guessing"] .gk-schemas   { animation-delay: 0.20s; }
@keyframes gk-fade-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Section label inside the answer surface */
.gk-slider-label {
  font: 500 10px/1 var(--font);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 6px;
}

/* ── Mode wheel (half-circle dial) ─────────────────────────────────── */
.gk-wheel {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  isolation: isolate;
}
.gk-wheel-prompt {
  font: 400 14px/1.4 var(--font);
  color: var(--ink-dim);
  margin-bottom: 4px;
}
.gk-wheel-current {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-height: 56px;
}
.gk-wheel-currentname {
  font: 400 32px/1 var(--font);
  letter-spacing: -0.01em;
  color: var(--ink);
  text-shadow: var(--glow-soft);
  transition: transform 0.3s var(--ease-spring);
}
.gk-wheel-currentbright {
  font: 400 10px/1 var(--font);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
/* The arc viewport — disc center sits INSIDE the bottom portion of the arc,
   spokes fan upward and slightly to the sides. The mask softens the bottom
   so distant spokes fade rather than hard-clip. */
.gk-wheel-arc {
  position: relative;
  width: 100%;
  max-width: 480px;
  height: 220px;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
  /* Soft bottom fade — the lower half of the wheel melts into the frame so
     only the top semicircle "feels" present. */
  mask: linear-gradient(180deg, #000 0, #000 60%, transparent 100%);
  -webkit-mask: linear-gradient(180deg, #000 0, #000 60%, transparent 100%);
}
.gk-wheel-arc:active { cursor: grabbing; }

/* SVG pie segments — sit behind the spoke labels. Anchored to the disc
   centre (50px above arc bottom). 460x460 display, viewBox 0..400 so the
   wedges scale by 1.15× and reach near the top of the arc. */
.gk-wheel-svg {
  position: absolute;
  left: 50%;
  bottom: 50px;
  width: 460px;
  height: 460px;
  transform: translate(-50%, 50%);
  pointer-events: none;
}
#gk-wheel-segments {
  /* Rotated via SVG `transform` attribute (rotate angle cx cy). CSS transform
     here would conflict — both compete for the same `transform` slot. Skip
     CSS-side animation; the snap-to-position via JS happens instantaneously
     and feels right for a quantized dial. */
}
.gk-wheel-segment {
  stroke: rgba(0, 0, 0, 0.08);
  stroke-width: 1;
  transition: opacity 0.3s var(--ease-out), filter 0.3s var(--ease-out);
}

.gk-wheel-disc {
  position: absolute;
  bottom: 50px;     /* disc centre 50px above arc bottom */
  left: 50%;
  width: 4px;
  height: 4px;
  transform: translateX(-50%);
  z-index: 3;
}
.gk-wheel-spoke {
  position: absolute;
  left: 0;
  top: 0;
  width: 132px;
  height: 42px;
  margin-left: -66px;
  margin-top: -21px;
  pointer-events: auto;
  transition: transform 0.45s var(--ease-spring),
              opacity 0.35s var(--ease-out);
  cursor: pointer;
}
.gk-wheel-spoke-label {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font: 500 var(--spoke-font, 16px)/1 var(--font);
  white-space: nowrap;
  color: var(--ink);
  transition: font-size 0.35s var(--ease-out);
}
.gk-wheel-spoke.is-active .gk-wheel-spoke-label {
  text-shadow: var(--glow-soft);
  font-weight: 500;
}
/* The SVG segments are the visual cue that the wheel is spinnable now — no
   separate guide arc needed. */
.gk-wheel-arc::after { content: none; }
.gk-wheel-caption {
  font: 400 10px/1.2 var(--font);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
/* Hidden range input — keyboard accessibility only. */
.gk-wheel-input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; border: 0;
  clip: rect(0 0 0 0); overflow: hidden;
}

/* ── Key slider (virtual piano) ──────────────────────────────────────── */
.gk-keyslider {
  width: 100%;
  display: grid;
  gap: 8px;
  justify-items: center;
}
.gk-keyslider[hidden] { display: none !important; }
.gk-keyslider-piano {
  width: 100%;
  max-width: 460px;
  height: 90px;
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  --gk-key-pos: 4.166%;
}
/* Active-key marker — a translucent vertical band the scrubber rides on. */
.gk-keyslider-piano::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--gk-key-pos) - 8.33%);
  width: 8.33%;
  background: rgba(var(--glow-rgb), 0.18);
  border-left: 1.5px solid var(--ink);
  border-right: 1.5px solid var(--ink);
  pointer-events: none;
  transition: left 0.35s var(--ease-spring);
  z-index: 1;
}
.gk-key {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 6px;
  font: 500 10px/1 var(--font-mono, 'JetBrains Mono', monospace);
  color: var(--ink-dim);
  cursor: pointer;
  border-right: 1px solid var(--line);
  transition: background 0.18s var(--ease-out), color 0.18s;
}
.gk-key:last-child { border-right: none; }
.gk-key.is-black {
  background: var(--ink);
  color: var(--bg);
}
.gk-key:hover { color: var(--ink); }
.gk-key.is-black:hover { color: var(--bg); filter: brightness(1.2); }
.gk-key.is-active {
  font-weight: 700;
  color: var(--ink);
}
.gk-key.is-black.is-active { color: var(--bg); }

.gk-keyslider-input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  max-width: 460px;
  height: 22px;
  margin: 0;
  background: transparent;
  cursor: grab;
}
.gk-keyslider-input:active { cursor: grabbing; }
.gk-keyslider-input::-webkit-slider-runnable-track {
  height: 3px;
  background: var(--line);
  border-radius: 2px;
}
.gk-keyslider-input::-moz-range-track {
  height: 3px;
  background: var(--line);
  border-radius: 2px;
}
.gk-keyslider-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  margin-top: -6px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--ink);
  box-shadow: var(--glow-soft);
  cursor: grab;
  transition: transform 0.2s var(--ease-spring);
}
.gk-keyslider-input::-moz-range-thumb {
  border: none;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--ink);
  box-shadow: var(--glow-soft);
  cursor: grab;
}
.gk-keyslider-input:hover::-webkit-slider-thumb { transform: scale(1.15); }

/* ── Schema picker (Hard tier) ───────────────────────────────────────── */
.gk-schemas[hidden] { display: none !important; }
.gk-schemas {
  border: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 8px;
  justify-items: center;
  width: 100%;
}
.gk-legend {
  font: 500 10px/1 var(--font);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0;
  margin: 0 0 4px;
}
.gk-schema-hint {
  font: 400 11px/1.4 var(--font);
  color: var(--ink-faint);
  text-align: center;
}
.gk-schemagrid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}
.gk-schemabtn {
  appearance: none;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  text-align: left;
  min-width: 110px;
  transition: background 0.18s var(--ease-out),
              border-color 0.18s var(--ease-out),
              transform 0.18s var(--ease-spring);
}
.gk-schemabtn:hover { border-color: var(--line-bright); transform: translateY(-1px); }
.gk-schemabtn.is-selected {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
  animation: pulse-glow 2.4s ease-in-out infinite;
}
.gk-schema-roman {
  font: 500 12px/1.1 var(--font-mono, 'JetBrains Mono', monospace);
}
.gk-schema-alt {
  font: 400 10px/1.2 var(--font);
  opacity: 0.7;
}

/* ── Submit ──────────────────────────────────────────────────────────── */
.gk-btn {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--bg-card);
  color: var(--ink);
  font: 500 13px/1 var(--font);
  padding: 12px 26px;
  border-radius: 999px;
  cursor: pointer;
  transition: opacity 0.2s, background 0.2s, color 0.2s, transform 0.18s var(--ease-spring);
}
.gk-btn:hover:not(:disabled) { border-color: var(--line-bright); transform: translateY(-1px); }
.gk-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.gk-btn-primary {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.gk-btn-primary:hover:not(:disabled) { filter: brightness(1.08); }

/* ── Dynamics slider (below the frame, three stops, chunky pill) ─── */
/* Order in the grid: track on top, meta (label + description) UNDER it. As
   the user drags, only the meta text changes — the track stays put. */
.gk-dynamic {
  display: grid;
  grid-template-areas: "track" "meta";
  row-gap: 10px;
  justify-items: center;
  width: 100%;
  max-width: 200px;
  margin-top: 6px;
  transition: opacity 0.4s var(--ease-out),
              max-height 0.5s var(--ease-out),
              transform 0.4s var(--ease-out);
  overflow: hidden;
  max-height: 130px;
}
/* Only the hero state shows the dynamics slider; once Play is pressed it
   collapses out of the way until the user returns to hero (e.g. resets). */
.gk-page[data-uistate="playing"]  .gk-dynamic,
.gk-page[data-uistate="guessing"] .gk-dynamic,
.gk-page[data-uistate="reveal"]   .gk-dynamic {
  opacity: 0;
  max-height: 0;
  margin: 0;
  pointer-events: none;
  transform: translateY(-6px);
}
.gk-dynamic-track {
  grid-area: track;
  position: relative;
  width: 100%;
  height: 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 10px;
  cursor: pointer;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
/* Sliding indicator pill behind the active dynamic — bias-like dial.gg. */
.gk-dynamic-fill {
  position: absolute;
  top: 3px;
  bottom: 3px;
  width: calc((100% - 6px) / 3);
  left: 3px;
  background: var(--ink);
  border-radius: 999px;
  transition: left 0.35s var(--ease-spring);
  pointer-events: none;
}
.gk-dynamic-thumb { display: none; }   /* fill covers the indicator role */
.gk-dynamic-stop {
  appearance: none;
  background: transparent;
  border: none;
  color: var(--ink-dim);
  font: italic 700 14px/1 'Bodoni Moda', 'Bodoni 72', Georgia, serif;
  cursor: pointer;
  flex: 1 1 0;
  text-align: center;
  padding: 4px 0;
  z-index: 1;
  transition: color 0.25s var(--ease-out);
}
.gk-dynamic-stop:hover:not(.is-active) { color: var(--ink); }
.gk-dynamic-stop.is-active { color: var(--bg); }
.gk-dynamic-stop span { font-size: inherit; }
/* Meta sits BELOW the track and updates as the user moves. */
.gk-dynamic-meta {
  grid-area: meta;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
}
.gk-dynamic-name {
  font: italic 600 14px/1 'Bodoni Moda', 'Bodoni 72', Georgia, serif;
  letter-spacing: 0.02em;
  color: var(--ink);
  transition: opacity 0.18s var(--ease-out);
}
.gk-dynamic-desc {
  font: 400 10px/1.2 var(--font);
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  transition: opacity 0.18s var(--ease-out);
}

/* ── Reveal ──────────────────────────────────────────────────────────── */
.gk-reveal[hidden],
.gk-reveal-row[hidden] { display: none !important; }
.gk-reveal {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px 24px;
  display: grid;
  gap: 10px;
  width: 100%;
  animation: gk-fade-up 0.4s var(--ease-out) both;
}
.gk-page[data-uistate="hero"] .gk-reveal,
.gk-page[data-uistate="playing"] .gk-reveal,
.gk-page[data-uistate="guessing"] .gk-reveal { display: none; }
.gk-reveal-verdict {
  font: 500 16px/1 var(--font);
  letter-spacing: 0.02em;
  margin-bottom: 4px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.gk-reveal-verdict[data-verdict="win"]     { color: var(--accent, #4ad); }
.gk-reveal-verdict[data-verdict="partial"] { color: var(--ink); }
.gk-reveal-verdict[data-verdict="miss"]    { color: var(--ink-dim); }
.gk-reveal-row {
  display: flex;
  gap: 16px;
  align-items: baseline;
  font: 400 13px/1.4 var(--font);
}
.gk-reveal-label {
  font: 500 10px/1 var(--font);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  min-width: 76px;
}
.gk-reveal-mono {
  font: 400 12px/1.4 var(--font-mono, 'JetBrains Mono', monospace);
}
.gk-reveal-actions {
  display: flex;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.gk-reveal-link {
  color: var(--ink-dim);
  font: 400 12px/1 var(--font);
  text-decoration: none;
  border-bottom: 1px dashed var(--line-bright);
}
.gk-reveal-link:hover { color: var(--ink); }

/* ── Finale ──────────────────────────────────────────────────────────── */
.gk-finale[hidden] { display: none !important; }
.gk-finale {
  display: grid;
  gap: 16px;
  justify-items: center;
  padding: 24px 0;
  animation: gk-fade-up 0.5s var(--ease-out) both;
}
.gk-finale-title {
  font: 500 11px/1 var(--font);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.gk-finale-score {
  font: 400 56px/1 var(--font-mono, 'JetBrains Mono', monospace);
  color: var(--ink);
  text-shadow: var(--glow-soft);
  font-feature-settings: 'tnum' 1;
}

@media (max-width: 640px) {
  .gk-page {
    padding: 0 16px 56px;
    gap: 18px;
  }
  .gk-intro {
    padding-top: 10px;
  }
  .gk-hero-title {
    font-size: clamp(36px, 12vw, 46px);
  }
  .gk-frame {
    width: min(560px, 94vw);
    padding: 24px 18px;
    border-radius: 20px;
  }
  .gk-status {
    gap: 24px;
  }
  .gk-wheel-currentname {
    font-size: 26px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gk-frame::after,
  .gk-page[data-uistate="playing"] .gk-play,
  .gk-page[data-uistate="playing"] .gk-bgpulse {
    animation: none;
  }
}
