/* SIO ALAT BERAT! — 3-station operator licence exam — MPA booth family styles */
:root {
  --font-display: "Cabinet Grotesk", "Satoshi", system-ui, sans-serif;
  --font-body: "Satoshi", system-ui, sans-serif;

  --bg: #101318;
  --panel: #1a1f27;
  --panel-2: #222932;
  --border: rgba(232, 234, 237, 0.12);
  --text: #e8eaed;
  --muted: #9aa3af;
  --amber: #f5a623;
  --amber-dark: #b87a12;
  --success: #3dd68c;
  --danger: #f0564a;

  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 16px;
}

* {
  box-sizing: border-box;
}
[hidden] {
  display: none !important;
}
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

/* ---------- shell ---------- */
#app {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 90% at 50% 0%, #171c24 0%, var(--bg) 60%), var(--bg);
}
#stage {
  position: relative;
  aspect-ratio: 375 / 667;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  /* 100vh is the LARGEST possible viewport (address bar hidden) — on a real
     phone, with the address bar showing (the default state right after
     load), the actually-visible area is shorter than that, so a box sized
     to 100vh has its bottom edge sitting behind the browser chrome until
     the user scrolls. 100dvh tracks the real, current visible viewport and
     resizes live as the chrome shows/hides, so nothing ends up hidden.
     Declared after the vh version as a progressive-enhancement override —
     browsers too old to know `dvh` just keep using vh above. */
  height: 100dvh;
  max-height: 100dvh;
  box-shadow:
    0 0 0 1px var(--border),
    0 30px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  background: var(--bg);
  font-size: 16px; /* set by JS so em units scale with the stage */
}
/* The 940px cap + rounded-corner "phone mockup" framing below is meant for
   wide LANDSCAPE desktop browser windows — without it, this mobile-designed
   portrait game would get stretched full-height across a 1080p+ monitor.
   It must NOT apply to a screen that is itself already tall/portrait (a
   vertical kiosk/signage display, e.g. a 2160x3840 totem) — that screen
   already IS the right shape, so the game should fill it like it fills a
   phone, not shrink into a small centered box surrounded by empty space.
   min-aspect-ratio excludes exactly that case: anything narrower than 3:4
   skips this block and keeps the plain height:100dvh rule above instead. */
@media (min-width: 900px) and (min-aspect-ratio: 3 / 4) {
  #stage {
    border-radius: 20px;
    height: min(100vh, 940px);
    height: min(100dvh, 940px);
  }
}

/* ---------- game shell ---------- */
.game-shell {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  padding: 0.55em 0.7em 0.7em;
  gap: 0.4em;
  background: radial-gradient(120% 70% at 50% 0%, #161b23 0%, #0e1116 70%);
}
.hud {
  flex: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)) 2.3em;
  gap: 0.35em;
  align-items: stretch;
}
.hud-cell {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0.35em 0.5em 0.4em;
  min-width: 0;
}
.hud-cell small {
  display: block;
  font-size: 0.4em;
  letter-spacing: 0.1em;
  overflow: hidden;
  text-overflow: clip;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  white-space: nowrap;
}
.hud-cell small span {
  letter-spacing: 0.04em;
  opacity: 0.75;
}
.hud-cell b {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.35em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums lining-nums;
}
.hud-clock b {
  color: var(--text);
}
.hud-clock.warn b {
  color: var(--amber);
}
.hud-clock.crit b {
  color: var(--danger);
  animation: pulse 700ms infinite;
}
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.4;
  }
}
.hud-cell b {
  font-size: 1.2em;
}

/* ---------- board ---------- */
.board-wrap {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
}
.board-frame {
  position: absolute;
  inset: 0.25em 0 0.25em 0;
}
#board {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: #0b0e13;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
#board.slam {
  animation: slam 140ms ease-out;
}
@keyframes slam {
  0% {
    transform: translateY(0);
  }
  35% {
    transform: translateY(4px);
  }
  70% {
    transform: translateY(-2px);
  }
  100% {
    transform: translateY(0);
  }
}
.zone-hints {
  position: absolute;
  inset: auto 0 0.45em 0;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  pointer-events: none;
  opacity: 0.75;
  transition: opacity 400ms;
}
.zone-hints.fade {
  opacity: 0;
}
.zone-hints span {
  text-align: center;
  font-size: 0.52em;
  letter-spacing: 0.18em;
  font-weight: 800;
  color: rgba(232, 234, 237, 0.5);
}
.board-banner {
  position: absolute;
  left: 0.4em;
  right: 0.4em;
  /* shrink to fit its own text instead of stretching edge-to-edge, then
     re-centre the shrunk box with auto margins — keeps it from covering
     the play area behind it (this was especially bad on station 2) */
  width: max-content;
  max-width: min(78%, 20em);
  margin: 0 auto;
  top: 32%;
  z-index: 6;
  text-align: center;
  border-radius: var(--r-md);
  padding: 0.5em 0.7em;
  background: rgba(16, 19, 24, 0.94);
  border: 1px solid var(--amber);
  box-shadow: 0 0 1.6em rgba(245, 166, 35, 0.28);
  animation: pop 170ms cubic-bezier(0.16, 1, 0.3, 1);
}
.board-banner.big {
  background-image: repeating-linear-gradient(
    45deg,
    rgba(245, 166, 35, 0.28) 0 10px,
    rgba(20, 23, 28, 0.9) 10px 20px
  );
}
.board-banner.over {
  border-color: var(--danger);
  box-shadow: 0 0 1.6em rgba(240, 86, 74, 0.3);
}
.board-banner b {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  /* was 1.25em — the main driver of how wide/tall this box got */
  font-size: 1.05em;
  line-height: 1.1;
  color: var(--amber);
  white-space: nowrap;
}
.board-banner.over b {
  color: var(--danger);
}
.board-banner small {
  display: block;
  font-size: 0.54em;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-top: 0.2em;
}
@keyframes pop {
  from {
    transform: scale(0.8);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* ---------- control hint strip ---------- */
.ctrl-hint {
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--panel);
  padding: 0.5em 0.7em;
  text-align: center;
  min-height: 3.1em;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.ctrl-hint b {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.8em;
  letter-spacing: 0.12em;
  color: var(--amber);
}
.ctrl-hint small {
  display: block;
  font-size: 0.55em;
  color: var(--muted);
  letter-spacing: 0.06em;
  margin-top: 0.2em;
}

/* ---------- station intro card ---------- */
.intro-card {
  width: min(86%, 22em);
  border: 1px solid var(--amber);
  border-radius: var(--r-lg);
  background: var(--panel);
  padding: 1.1em 1em 1em;
  text-align: center;
  box-shadow: 0 0 2.2em rgba(245, 166, 35, 0.18);
  animation: pop 200ms cubic-bezier(0.16, 1, 0.3, 1);
}
.intro-badge {
  font-size: 0.56em;
  letter-spacing: 0.24em;
  font-weight: 800;
  color: var(--muted);
}
.intro-ico {
  display: block;
  height: 4.25em;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  margin: 0.5em auto 0.3em;
}
#screen-intro .intro-card b {
  display: block;
  max-width: 100%;
  overflow-wrap: anywhere;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05em;
  letter-spacing: 0.04em;
}
#screen-intro .intro-card em {
  display: block;
  font-style: normal;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.5em;
  color: var(--amber);
  line-height: 1.1;
  margin-top: 0.1em;
}
.intro-card p {
  margin: 0.6em 0 0;
  font-size: 0.66em;
  line-height: 1.45;
  color: var(--text);
}
.intro-card p.en {
  margin-top: 0.2em;
  color: var(--muted);
  font-size: 0.6em;
}
.intro-go {
  display: block;
  margin-top: 0.75em;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.5em;
  color: var(--success);
  letter-spacing: 0.08em;
}
.intro-skip {
  display: block;
  margin-top: 0.5em;
  font-size: 0.52em;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- licence card (results) ---------- */
.license {
  margin-top: 0.7em;
  border: 1px solid var(--amber);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--panel);
}
.lic-stripe {
  height: 0.5em;
  background-image: repeating-linear-gradient(
    45deg,
    var(--amber) 0 10px,
    #14171c 10px 20px
  );
}
.lic-body {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.6em;
  align-items: center;
  padding: 0.7em 0.8em;
}
.lic-left {
  min-width: 0;
}
.lic-issuer {
  margin: 0;
  font-size: 0.48em;
  letter-spacing: 0.14em;
  color: var(--muted);
  font-weight: 700;
}
.lic-grade {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.02em;
  line-height: 1.1;
  color: var(--amber);
  margin-top: 0.25em;
}
.lic-grade-en {
  display: block;
  font-size: 0.58em;
  color: var(--muted);
  letter-spacing: 0.08em;
  margin-top: 0.1em;
}
.lic-note {
  margin: 0.35em 0 0;
  font-size: 0.56em;
  color: var(--text);
  line-height: 1.4;
}
.lic-right {
  display: grid;
  gap: 0.2em;
  color: var(--muted);
}
.lic-ico {
  height: 1.3em;
  width: auto;
  max-width: 2.9em;
  object-fit: contain;
  display: block;
  margin-left: auto;
}

/* ---------- per-station bars ---------- */
.bars {
  margin-top: 0.7em;
  display: grid;
  gap: 0.38em;
}
.bar-row {
  display: grid;
  grid-template-columns: 5.6em 1fr 2.6em;
  gap: 0.5em;
  align-items: center;
}
.bar-lab {
  font-size: 0.56em;
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1.2;
}
.bar-lab small {
  display: block;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--muted);
  font-size: 0.88em;
}
.bar-track {
  display: block;
  height: 0.62em;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  overflow: hidden;
}
.bar-track i {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--amber-dark), var(--amber));
  transition: width 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.bar-val {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.7em;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* mute button */
.mute-btn {
  position: static;
  z-index: 25;
  width: 100%;
  min-width: 30px;
  height: auto;
  align-self: stretch;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: rgba(20, 23, 28, 0.9);
  color: var(--muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}
.mute-btn svg {
  width: 1em;
  height: 1em;
}
.mute-btn:hover {
  border-color: var(--amber);
  color: var(--amber);
}
/* green = sound on, red = muted — set from game.js alongside the icon swap */
.mute-btn.is-on {
  color: var(--success);
}
.mute-btn.is-off {
  color: var(--danger);
}
/* No focus ring on this one — it's a toggle a player taps repeatedly, not
   a target keyboard users tab through, and the browser's default outline
   read as a stray box next to it. */
.mute-btn:focus {
  outline: none;
}

/* ---------- countdown ---------- */
.countdown {
  position: absolute;
  inset: 0;
  z-index: 28;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3em;
  background: rgba(16, 19, 24, 0.86);
}
.countdown b {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 6em;
  line-height: 1;
  color: var(--amber);
  animation: pop 220ms cubic-bezier(0.16, 1, 0.3, 1);
}
.countdown small {
  font-size: 0.72em;
  letter-spacing: 0.22em;
  color: var(--muted);
  text-transform: uppercase;
}

/* ---------- overlays ---------- */
.overlay {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  padding: 1.1em 1.05em;
  gap: 0.6em;
  background: linear-gradient(
    180deg,
    rgba(16, 19, 24, 0.82) 0%,
    rgba(16, 19, 24, 0.93) 45%,
    rgba(16, 19, 24, 0.96) 100%
  );
  overflow-y: auto;
  overflow-x: hidden;
}
.overlay > * {
  flex: 0 0 auto;
}
/* results must be fully opaque (attract loop keeps running behind the title) */
#screen-results {
  background: linear-gradient(
    180deg,
    rgba(16, 19, 24, 0.99) 0%,
    #101318 40%,
    #101318 100%
  );
  backdrop-filter: blur(6px);
}
#screen-title {
  padding: 0;
}
#attract {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
/* Kiosk devices running a regular Chrome tab (not a kiosk-launcher WebView)
   always keep a minimal address bar on screen by design — no CSS viewport
   unit can account for that, since it's real browser chrome, not page
   content. This lets the kiosk operator hide it for the session with one
   tap before starting. Hidden by default; game.js only reveals it where
   the Fullscreen API actually exists. Invisible on purpose (opacity, not
   display/visibility, so it's still tappable) — a booth operator who
   knows it's here can still tap the corner, but it's not a visible button
   a random visitor would notice and prod. */
.fs-btn {
  position: absolute;
  top: 0.6em;
  right: 0.6em;
  z-index: 5;
  width: 2.4em;
  height: 2.4em;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(20, 23, 28, 0.9);
  color: var(--muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  opacity: 0;
}
.fs-btn svg {
  width: 1.15em;
  height: 1.15em;
}
.fs-btn:hover,
.fs-btn[aria-pressed="true"] {
  border-color: var(--amber);
  color: var(--amber);
}
.title-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0.55em;
  padding: 1.1em 1.05em;
  min-height: 100%;
  /* Dark enough over the brand/title/cards (0-34%) and the CTA/foot-note
     (88-100%) to keep that text readable, but punched through to near-
     transparent across 42-78% — the empty gap where the attract-mode
     vehicles run (see attractGap in game.js) — so they aren't tinted flat. */
  background: linear-gradient(
    180deg,
    rgba(16, 19, 24, 0.92) 0%,
    rgba(16, 19, 24, 0.85) 34%,
    rgba(16, 19, 24, 0.12) 42%,
    rgba(16, 19, 24, 0.08) 60%,
    rgba(16, 19, 24, 0.12) 78%,
    rgba(16, 19, 24, 0.9) 88%,
    rgba(16, 19, 24, 0.93) 100%
  );
}

/* ---------- brand ---------- */
.brand {
  display: flex;
  align-items: center;
  gap: 0.65em;
  color: var(--amber);
}
.brand-logo {
  /* Height matches the "STI / San Traktor Indonesia" wordmark's own
     two-line box (0.68em*1.25 + 0.68em*0.85em*1.25) so the logo's actual
     mark lines up top-to-bottom with the text next to it — the source
     asset is pre-trimmed to its opaque bounds, so this height isn't padded
     out by transparent margin the way width:2.1em/height:2.1em used to be. */
  height: 1.57em;
  width: auto;
  flex: none;
}
.brand .wordmark {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.68em;
  letter-spacing: 0.14em;
  line-height: 1.25;
  color: var(--text);
  text-transform: uppercase;
}
.brand .wordmark span {
  display: block;
  color: var(--muted);
  font-weight: 500;
  letter-spacing: 0.1em;
  font-size: 0.85em;
}

/* ---------- title ---------- */
.title-wrap {
  text-align: center;
  margin-top: 0.2em;
}
h1.game-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.35em;
  line-height: 0.94;
  margin: 0;
  letter-spacing: -0.02em;
  text-shadow: 0 0.06em 0 var(--amber-dark);
}
h1.game-title em {
  font-style: normal;
  color: var(--amber);
  display: block;
}
.sio-full {
  display: block;
  font-family: var(--font-body);
  font-size: 0.46em;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text);
  margin-bottom: 0.35em;
}
.subtitle {
  font-size: 0.76em;
  letter-spacing: 0.08em;
  color: var(--amber);
  margin: 0.6em 0 0;
  font-weight: 700;
}
.subtitle-en {
  font-size: 0.66em;
  color: var(--muted);
  margin: 0.25em 0 0;
  letter-spacing: 0.04em;
}
.subtitle-urg {
  margin: 0.7em 0 0;
  font-size: 0.62em;
  font-weight: 800;
  letter-spacing: 0.18em;
  color: var(--text);
}
.subtitle-urg span {
  display: block;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-top: 0.25em;
  font-size: 0.92em;
}
.howto {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.42em;
  margin-top: 0.5em;
}
.howto div {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0.6em 0.3em;
  text-align: center;
}
.howto .ico {
  display: block;
  height: 1.6em;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  margin: 0 auto 0.3em;
}
.howto b {
  display: block;
  font-size: 0.62em;
  letter-spacing: 0.06em;
}
.howto small {
  display: block;
  font-size: 0.54em;
  color: var(--muted);
  margin-top: 0.2em;
  line-height: 1.35;
}

/* ---------- buttons ---------- */
.btn {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 1em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #14171c;
  background: var(--amber);
  border: none;
  border-radius: var(--r-md);
  padding: 0.75em 1em;
  min-height: 3em;
  width: 100%;
  /* min-height can end up taller than the label + small subtitle actually
     need — without this, the text just sits at the top padding instead of
     using the extra room, looking off-center. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition:
    transform 140ms cubic-bezier(0.16, 1, 0.3, 1),
    filter 140ms;
  box-shadow: 0 0.25em 0 var(--amber-dark);
}
.btn:hover {
  filter: brightness(1.08);
}
.btn:active {
  transform: translateY(0.2em);
  box-shadow: 0 0.05em 0 var(--amber-dark);
}
.btn:disabled {
  opacity: 0.62;
  cursor: default;
  box-shadow: none;
  transform: none;
}
.btn.sent {
  background: var(--success);
  color: #08130d;
  opacity: 1;
}
.btn.secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: none;
}
.btn.secondary:hover {
  border-color: var(--amber);
  color: var(--amber);
}
.btn small {
  display: block;
  font-size: 0.62em;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: none;
  opacity: 0.72;
  margin-top: 0.15em;
}
.cta-row {
  margin-top: auto;
  padding-top: 0.8em;
  display: grid;
  gap: 0.45em;
}
.foot-note {
  font-size: 0.58em;
  color: var(--muted);
  text-align: center;
  margin: 0.7em 0 0;
  letter-spacing: 0.08em;
}

/* ---------- results ---------- */
.res-head {
  text-align: center;
}
.res-label {
  font-size: 0.64em;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.res-score {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 3.1em;
  line-height: 1;
  color: var(--amber);
  margin: 0.15em 0 0;
  font-variant-numeric: tabular-nums lining-nums;
}
.res-score small {
  font-family: var(--font-body);
  font-size: 0.26em;
  color: var(--muted);
  letter-spacing: 0.2em;
  margin-left: 0.5em;
  font-weight: 700;
}
.grade {
  margin: 0.55em auto 0;
  display: inline-block;
  border: 1px solid var(--amber);
  border-radius: 999px;
  padding: 0.4em 1.1em;
  background: rgba(245, 166, 35, 0.12);
}
.grade b {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.95em;
  letter-spacing: 0.06em;
  color: var(--amber);
}
.grade span {
  display: block;
  font-size: 0.58em;
  color: var(--muted);
  letter-spacing: 0.08em;
}
.res-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.4em;
  margin-top: 0.7em;
}
.res-stats div {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0.5em 0.3em;
  text-align: center;
}
.res-stats b {
  display: block;
  font-size: 1.15em;
  font-family: var(--font-display);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.res-stats small {
  display: block;
  font-size: 0.54em;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 0.15em;
}

form.score-form {
  margin-top: 0.7em;
  display: grid;
  gap: 0.4em;
}
label.field-label {
  display: block;
  font-size: 0.6em;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.25em;
}
label.field-label span {
  text-transform: none;
  letter-spacing: 0.02em;
  opacity: 0.75;
}
input[type="text"],
input[type="tel"],
input[type="password"] {
  width: 100%;
  font-family: var(--font-body);
  font-size: 0.9em;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 0.6em 0.7em;
  min-height: 2.7em;
}
input:focus {
  outline: 2px solid var(--amber);
  outline-offset: 1px;
}
.consent {
  font-size: 0.56em;
  color: var(--muted);
  line-height: 1.5;
  margin: 0.05em 0 0;
}
.form-error {
  font-size: 0.62em;
  color: var(--danger);
  min-height: 1em;
  margin: 0;
}
#shareCard {
  /* the .overlay > * rule above makes every direct child a fixed-size flex
     item by default — override that here so this one grows to fill
     whatever room the label/button/Main-Lagi row above and below it don't
     need, on any screen height, instead of guessing a size up front. `gap`
     (rather than per-element margins) keeps every inter-item space in this
     card identical. */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 1 1 auto;
  min-height: 0;
  gap: 0.6em;
}
.share-label {
  font-size: 0.62em;
  letter-spacing: 0.06em;
  color: var(--muted);
  text-align: center;
  margin: 0;
}
.share-label span {
  display: block;
  opacity: 0.75;
  margin-top: 0.1em;
}
.share-preview-box {
  /* the actual flex-grow target: a plain box with no aspect-ratio/intrinsic
     size of its own, so it reliably fills exactly its leftover share of
     #shareCard's height — growing the <img> directly here left a "phantom"
     gap between it and the button below, because the ratio+max-width
     recalculation that constrains the image's final size happens AFTER
     flex-grow has already reserved space for it, and that leftover
     mismatch isn't reclaimed by its neighbours. Centering the image inside
     this reliably-sized box instead means any slack ends up split evenly
     above and below it — so the gap up to the label and down to the
     button are the same, whatever height this box ends up at. */
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.share-preview {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  border-radius: var(--r-md);
  border: 1px solid var(--amber);
  box-shadow: 0 0.4em 1.2em rgba(0, 0, 0, 0.35);
  background: var(--panel);
}
.share-note {
  font-size: 0.58em;
  color: var(--danger);
  text-align: center;
  min-height: 1em;
  margin: 0;
}
/* "Main Lagi" used its own margin-top:auto (see .cta-row above) to float
   to the very bottom of the screen independently of #shareCard — since
   #shareCard already grows to fill the leftover space itself, that left
   the two looking far apart. Tie Main Lagi's spacing to the same rhythm
   as everything above it instead of letting it float on its own. */
#shareCard + .cta-row {
  margin-top: 0;
  padding-top: 0;
}
