/* ═══════════════════════════════════════════════════════════════════════
 * /setup/setup.css — THE ONE STYLESHEET for the web park setup app
 * (views/setup/app.ejs, web-setup round, Oct 2026).
 *
 * Black and white, easy on the eyes: pure black page, white ink, ~60% white
 * for secondary text, white hairlines, translucent-white fills (~12%). The
 * one "success" colour is still white: a white check in a white ring.
 * Type from /hq and /play: Zalando Sans Expanded (800) for the big step
 * numbers and titles, DM Sans for everything else, tabular numbers.
 *
 * Pages carry NO <style> blocks and NO style="" attributes. JS only sets
 * classes and CSS custom properties. Anything new goes in this file.
 * Sections: tokens · base · header + rail · steps · type · controls ·
 * feedback · scanner · park graphic (.pg-*).
 * ═══════════════════════════════════════════════════════════════════════ */

:root {
  --su-bg: #000000;
  --su-ink: #ffffff;
  --su-ink-2: rgba(255, 255, 255, 0.8);
  --su-ink-3: rgba(255, 255, 255, 0.6);
  --su-ink-4: rgba(255, 255, 255, 0.4);
  --su-line: rgba(255, 255, 255, 0.22);
  --su-line-2: rgba(255, 255, 255, 0.12);
  --su-fill: rgba(255, 255, 255, 0.12);
  --su-fill-2: rgba(255, 255, 255, 0.06);
  --su-fill-3: rgba(255, 255, 255, 0.18);
  --su-gutter: 16px;
  --su-max: 560px;
  --su-tap: 56px;
  --su-radius: 20px;
  --su-display: 'Zalando Sans Expanded', 'DM Sans', system-ui, sans-serif;
  --su-body: 'DM Sans', 'Inter', system-ui, -apple-system, sans-serif;
  --su-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --su-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.2 4.2L19 7' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
@media (min-width: 720px) { :root { --su-max: 600px; } }

/* ── base ──────────────────────────────────────────────────────────── */
html.su-root { background: var(--su-bg); color-scheme: dark; }
body.su {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--su-bg);
  color: var(--su-ink);
  font-family: var(--su-body);
  font-size: 18px;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overflow-x: clip;
}
.su *, .su *::before, .su *::after { box-sizing: border-box; }
.su :where(img, svg) { max-width: 100%; }
.su :where(a) { color: inherit; }
.su :where(button) { font: inherit; color: inherit; }
.su [hidden] { display: none !important; }
.su :focus-visible { outline: 3px solid var(--su-ink); outline-offset: 3px; }
.su [tabindex="-1"]:focus { outline: none; }
.su-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
body.su-scanning { overflow: hidden; }

.su-app {
  width: 100%;
  max-width: var(--su-max);
  margin: 0 auto;
  padding: max(10px, env(safe-area-inset-top)) var(--su-gutter) 48px;
}
body.su-has-bar .su-app { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }

/* ── header + progress rail ────────────────────────────────────────── */
.su-top { display: flex; flex-direction: column; gap: 14px; padding: 8px 0 4px; }
.su-brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; align-self: flex-start; min-height: 44px; }
.su-brand__text { height: 13px; width: auto; display: block; opacity: 0.92; }

/* the progress bar — unlabeled; fills with an eased glide and a soft glow at its leading edge */
.su-progress {
  position: relative; height: 6px; margin: 6px 0 2px;
  border-radius: 999px; background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}
.su-progress__fill {
  --su-p: 0;
  position: absolute; top: 0; bottom: 0; left: 0;
  width: calc(var(--su-p) * 100%);
  border-radius: inherit;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.35);
  transition: width 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* the shimmer: a bright band that glides along the fill, forever, so progress always feels like it's moving */
.su-progress__fill::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0;
  width: 70%; min-width: 48px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.95) 50%, rgba(255, 255, 255, 0) 100%);
  animation: su-shimmer-bar 1.6s linear infinite;
}
@keyframes su-shimmer-bar { from { transform: translateX(-100%); } to { transform: translateX(150%); } }
/* done: one satisfying pulse */
.su-progress.is-full { animation: su-full 700ms var(--su-ease) 700ms both; }
@keyframes su-full { 0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); } 100% { box-shadow: 0 0 0 10px rgba(255, 255, 255, 0); } }
@media (prefers-reduced-motion: reduce) {
  .su-progress__fill { transition: none; }
  .su-progress__fill::after, .su-progress.is-full { animation: none; }
}
@media (min-width: 720px) {
  .su-top { flex-direction: row; align-items: center; justify-content: space-between; gap: 28px; padding-top: 20px; }
  .su-progress { flex: 0 1 380px; margin: 0; }
}
/* the portal's "Add games" (views/setup/app.ejs mode 'games'): the logo, and Cancel where the progress bar goes */
.su-top--games { flex-direction: row; align-items: center; justify-content: space-between; }
.su-cancel {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px 0 14px;
  color: var(--su-ink-2); font: 600 17px/1 var(--su-body); text-decoration: none;
}
.su-cancel:hover, .su-cancel:active { color: var(--su-ink); }

/* ── steps (shell.js slides them) ──────────────────────────────────── */
.su-stage { position: relative; }
.su-step { padding-top: 28px; }
.su-step.is-leaving { position: absolute; top: 0; left: 0; right: 0; pointer-events: none; }
.su-step.is-entering--fwd { animation: su-in 420ms var(--su-ease) both; }
.su-step.is-entering--back { animation: su-in-back 420ms var(--su-ease) both; }
.su-step.is-leaving--fwd { animation: su-out 300ms var(--su-ease) both; }
.su-step.is-leaving--back { animation: su-out-back 300ms var(--su-ease) both; }
@keyframes su-in { from { opacity: 0; transform: translateX(32px); } to { opacity: 1; transform: none; } }
@keyframes su-in-back { from { opacity: 0; transform: translateX(-32px); } to { opacity: 1; transform: none; } }
@keyframes su-out { to { opacity: 0; transform: translateX(-32px); } }
@keyframes su-out-back { to { opacity: 0; transform: translateX(32px); } }
@media (min-width: 720px) { .su-step { padding-top: 56px; } }

.su-head { margin: 0 0 26px; }
.su-num {
  font: 800 76px/0.9 var(--su-display);
  letter-spacing: -0.03em;
  /* Zalando's tabular zero is slashed; the proportional one reads as a plain 0. */
  font-variant-numeric: proportional-nums;
  font-feature-settings: "zero" 0, "tnum" 0;
  color: var(--su-ink);
  margin: 0 0 14px;
}
.su-title {
  margin: 0;
  font: 800 27px/1.12 var(--su-display);
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.su-sub { margin: 12px 0 0; font-size: 18px; color: var(--su-ink-3); text-wrap: pretty; }
@media (max-width: 360px) { .su-num { font-size: 64px; } .su-title { font-size: 24px; } }
@media (min-width: 720px) { .su-num { font-size: 104px; } .su-title { font-size: 36px; } .su-sub { font-size: 19px; } }

.su-skel { background: var(--su-fill-2); border-radius: 12px; animation: su-shimmer 1.4s ease-in-out infinite; }
.su-num.su-skel { width: 140px; height: 70px; }
.su-skel--title { width: 70%; height: 30px; }
@keyframes su-shimmer { 50% { background: var(--su-fill); } }

.su-noscript { padding: 40px 16px; text-align: center; color: var(--su-ink-2); }

/* ── ONE SCREEN PER STEP (Aidan, Oct 25): a step never scrolls on a phone ──
   The app is exactly one screen tall; the step body gets what's left between
   the header and the bottom bar (--su-bar-h, measured by shell.js). A step lays
   itself out inside .su-body (flex column) — big things flex, nothing pushes the
   page. .su-body still scrolls as a last resort so an overfull step stays usable. */
body.su { height: 100vh; height: 100dvh; overflow: hidden; }
.su-app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; padding-bottom: 0; }
body.su-has-bar .su-app { padding-bottom: var(--su-bar-h, 104px); }
.su-top { flex: none; }
.su-stage { flex: 1 1 auto; min-height: 0; }
.su-step { height: 100%; display: flex; flex-direction: column; padding-top: clamp(8px, 2.4dvh, 28px); }
.su-head { flex: none; margin-bottom: clamp(10px, 2.2dvh, 26px); }
.su-num { font-size: clamp(40px, 8.5dvh, 76px); margin-bottom: clamp(2px, 1dvh, 14px); }
.su-title { font-size: clamp(22px, 3.3dvh, 27px); }
.su-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
  /* a scrolling box clips on EVERY side (overflow-y forces overflow-x), so give its content
     room: anything touching the edge (selection rings, lifted tiles, shadows) stays whole. */
  margin: 0 -10px; padding: 6px 10px 4px; }
.su-body::-webkit-scrollbar { display: none; }
@media (min-width: 720px) { .su-step { padding-top: clamp(12px, 4dvh, 56px); } .su-num { font-size: clamp(48px, 10dvh, 104px); } }

/* ── type inside a step ────────────────────────────────────────────── */
.su-body > :first-child { margin-top: 0; }
.su-lede { margin: 0 0 20px; font-size: 19px; line-height: 1.5; color: var(--su-ink-2); text-wrap: pretty; }
.su-lede b, .su-lede strong { color: var(--su-ink); font-weight: 600; }
.su-muted { margin: 12px 0 0; font-size: 15px; color: var(--su-ink-3); text-wrap: pretty; }
.su-h2 { margin: 28px 0 12px; font: 800 18px/1.2 var(--su-display); }
.su-eyebrow { margin: 0 0 8px; font: 600 12px/1 var(--su-body); letter-spacing: 0.14em; text-transform: uppercase; color: var(--su-ink-3); }
.su-big { font: 800 40px/1 var(--su-display); font-variant-numeric: tabular-nums; }

/* ── controls ──────────────────────────────────────────────────────── */
.su-btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: var(--su-tap); padding: 0 28px;
  border: 0; border-radius: 999px; cursor: pointer;
  background: var(--su-ink); color: var(--su-bg);
  font: 600 18px/1 var(--su-body); text-decoration: none; white-space: nowrap;
  transition: transform 140ms var(--su-ease), background 160ms, color 160ms, opacity 160ms;
}
.su-btn:active { transform: scale(0.97); }
.su-btn:disabled { background: var(--su-fill-3); color: var(--su-ink-4); cursor: default; transform: none; }
.su-btn--block { width: 100%; }
.su-btn--ghost { background: transparent; color: var(--su-ink); box-shadow: inset 0 0 0 1.5px var(--su-line); }
.su-btn--ghost:hover { box-shadow: inset 0 0 0 1.5px var(--su-ink-2); }
.su-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.su-btn.is-busy { color: transparent; pointer-events: none; }
.su-btn.is-busy::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 22px; height: 22px; border-radius: 50%;
  border: 2.5px solid rgba(0, 0, 0, 0.25); border-top-color: var(--su-bg);
  animation: su-spin 700ms linear infinite;
}
@keyframes su-spin { to { transform: rotate(360deg); } }
.su-row { display: flex; gap: 12px; flex-wrap: wrap; }
.su-stack { display: flex; flex-direction: column; gap: 12px; }

.su-link {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 12px;
  background: none; border: 0; cursor: pointer;
  color: var(--su-ink-2); font: 600 16px/1.2 var(--su-body);
  text-decoration: underline; text-decoration-color: var(--su-ink-4); text-underline-offset: 4px;
}
.su-link:hover { color: var(--su-ink); text-decoration-color: var(--su-ink); }

/* the bottom bar (DPSetup.actions) */
.su-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  padding: 28px var(--su-gutter) max(16px, env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--su-bg) 62%, rgba(0, 0, 0, 0));
}
.su-bar__inner { max-width: var(--su-max); margin: 0 auto; padding: 0 var(--su-gutter); display: flex; flex-direction: column; align-items: center; gap: 2px; }
.su-bar .su-btn { font-size: 19px; }
@media (max-width: 600px) { .su-bar__inner { padding: 0; } }

/* big selectable cards */
.su-choices { display: flex; flex-direction: column; gap: 12px; margin: 0 0 8px; }
.su-choice {
  position: relative;
  display: flex; align-items: center; gap: 16px;
  width: 100%; min-height: 76px; padding: 16px 62px 16px 18px;
  border: 0; border-radius: var(--su-radius); cursor: pointer;
  background: var(--su-fill-2);
  box-shadow: inset 0 0 0 1.5px var(--su-line-2);
  color: var(--su-ink); text-align: left;
  transition: background 180ms, box-shadow 180ms, transform 140ms var(--su-ease);
}
.su-choice:hover { background: var(--su-fill); }
.su-choice:active { transform: scale(0.985); }
.su-choice::after {
  content: ''; position: absolute; right: 18px; top: 50%;
  width: 28px; height: 28px; margin-top: -14px; border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--su-line);
  background: transparent center / 18px no-repeat;
  transition: background-color 180ms, box-shadow 180ms;
}
.su-choice.is-selected { background: var(--su-fill); box-shadow: inset 0 0 0 2px var(--su-ink); }
.su-choice.is-selected::after { background-color: var(--su-ink); background-image: var(--su-check); box-shadow: none; }
.su-choice__title { display: block; font: 800 19px/1.2 var(--su-display); }
.su-choice__sub { display: block; margin-top: 4px; font-size: 15px; color: var(--su-ink-3); }
.su-choice__art { flex: 0 0 56px; width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; }
.su-choice__art svg { width: 100%; height: 100%; }

.su-card {
  padding: 20px; border-radius: var(--su-radius);
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1px var(--su-line-2);
}
.su-card + .su-card { margin-top: 12px; }

.su-list { list-style: none; margin: 0 0 20px; padding: 0; }
.su-list > li {
  display: flex; align-items: center; gap: 14px;
  min-height: var(--su-tap); padding: 12px 0;
  border-bottom: 1px solid var(--su-line-2);
  font-size: 18px;
}
.su-list > li:last-child { border-bottom: 0; }
.su-list__n {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0 0 1.5px var(--su-line);
  font: 800 13px/1 var(--su-display); color: var(--su-ink-2);
}

.su-figure { margin: 4px 0 24px; }
.su-figure svg { display: block; width: 100%; height: auto; max-height: 58vh; }
.su-figure figcaption { margin-top: 10px; font-size: 15px; color: var(--su-ink-3); text-align: center; }

.su-field { display: block; margin: 0 0 16px; }
.su-field__label { display: block; margin: 0 0 8px; font-size: 15px; font-weight: 600; color: var(--su-ink-2); }
.su-input {
  display: block; width: 100%; height: var(--su-tap); padding: 0 18px;
  border: 0; border-radius: 16px; outline: 0;
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line);
  color: var(--su-ink); font: 500 19px/1 var(--su-body);
  transition: box-shadow 160ms;
}
.su-input::placeholder { color: var(--su-ink-4); }
.su-input:focus { box-shadow: inset 0 0 0 2px var(--su-ink); }

/* ── feedback: the "done, nice" check ──────────────────────────────── */
.su-cele-host { position: relative; }
.su-cele {
  position: absolute; inset: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 240px; padding: 24px;
  background: rgba(0, 0, 0, 0.9);
  opacity: 0; transition: opacity 220ms var(--su-ease);
  text-align: center;
}
.su-cele--screen { position: fixed; z-index: 60; }
.su-cele.is-on { opacity: 1; }
.su-cele.is-out { opacity: 0; transition-duration: 300ms; }
.su-cele__mark { width: 132px; height: 132px; overflow: visible; }
.su-cele.is-on .su-cele__mark { animation: su-pop 520ms var(--su-ease) both; }
.su-cele__ring { fill: var(--su-fill); stroke: var(--su-ink); stroke-width: 4; stroke-dasharray: 252; stroke-dashoffset: 252; transform: rotate(-90deg); transform-box: fill-box; transform-origin: center; }
.su-cele__check { fill: none; stroke: var(--su-ink); stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 60; stroke-dashoffset: 60; }
.su-cele__rays { transform-box: fill-box; transform-origin: center; opacity: 0; }
.su-cele__ray { stroke: var(--su-ink); stroke-width: 3.5; stroke-linecap: round; }
.su-cele.is-on .su-cele__ring { animation: su-draw 460ms var(--su-ease) forwards; }
.su-cele.is-on .su-cele__check { animation: su-draw 320ms var(--su-ease) 300ms forwards; }
.su-cele.is-on .su-cele__rays { animation: su-burst 760ms var(--su-ease) 380ms both; }
.su-cele__text { margin: 18px 0 0; font: 800 24px/1.2 var(--su-display); text-wrap: balance; opacity: 0; }
.su-cele.is-on .su-cele__text { animation: su-rise 420ms var(--su-ease) 420ms both; }
@keyframes su-draw { to { stroke-dashoffset: 0; } }
@keyframes su-pop { 0% { transform: scale(0.6); } 60% { transform: scale(1.06); } 100% { transform: scale(1); } }
@keyframes su-burst { 0% { opacity: 0; transform: scale(0.72); } 30% { opacity: 1; } 100% { opacity: 0; transform: scale(1.32); } }
@keyframes su-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.su-tick {
  flex: 0 0 auto; margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--su-ink); background: var(--su-fill);
  transform: scale(0.4); opacity: 0;
}
.su-tick svg { width: 17px; height: 17px; fill: none; stroke: var(--su-ink); stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 24; stroke-dashoffset: 24; }
.su-tick.is-on { animation: su-pop 420ms var(--su-ease) forwards; opacity: 1; }
.su-tick.is-on svg { animation: su-draw 280ms var(--su-ease) 180ms forwards; }

.su-toast {
  position: fixed; left: 50%; z-index: 70;
  bottom: calc(112px + env(safe-area-inset-bottom));
  /* width: max-content — with left:50% the shrink-to-fit width is only half the screen, which squeezed short
     messages ("Invite sent to (555) 555-0142") into a narrow two-line blob. */
  width: max-content; max-width: calc(100% - 32px); box-sizing: border-box; text-align: center;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px 20px; border-radius: 999px;
  background: var(--su-ink); color: var(--su-bg);
  font: 600 16px/1.3 var(--su-body);
  transform: translate(-50%, 16px); opacity: 0;
  transition: transform 260ms var(--su-ease), opacity 220ms;
}
.su-toast.is-on { transform: translate(-50%, 0); opacity: 1; }
.su-toast.is-error::before {
  content: '!'; flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--su-bg); color: var(--su-ink); font: 800 13px/1 var(--su-display);
}

@media (prefers-reduced-motion: reduce) {
  .su-step.is-entering--fwd, .su-step.is-entering--back, .su-step.is-leaving--fwd, .su-step.is-leaving--back { animation: none; }
  .su-cele.is-on .su-cele__mark, .su-cele.is-on .su-cele__rays, .su-cele.is-on .su-cele__text { animation: none; opacity: 1; }
  .su-cele.is-on .su-cele__rays { opacity: 0; }
  .su-cele.is-on .su-cele__ring, .su-cele.is-on .su-cele__check, .su-tick.is-on svg { animation: none; stroke-dashoffset: 0; }
  .su-tick.is-on { animation: none; transform: none; }
}

/* ── scanner (DPScanner) ───────────────────────────────────────────── */
.su-scan {
  position: fixed; inset: 0; z-index: 100;
  background: var(--su-bg); color: var(--su-ink);
  opacity: 0; transition: opacity 220ms var(--su-ease);
  overflow: hidden;
}
.su-scan.is-on { opacity: 1; }
.su-scan__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 300ms; }
.su-scan.is-live .su-scan__video { opacity: 1; }
.su-scan__frame {
  --su-scan-size: min(72vw, 46vh, 340px);
  position: absolute; left: 50%; top: 44%;
  width: var(--su-scan-size); height: var(--su-scan-size);
  transform: translate(-50%, -50%);
  border-radius: 28px;
  box-shadow: 0 0 0 200vmax rgba(0, 0, 0, 0.58);
  transition: background 200ms;
}
.su-scan__corner { position: absolute; width: 52px; height: 52px; border: 0 solid var(--su-ink); transition: transform 260ms var(--su-ease); }
.su-scan__corner--tl { top: -3px; left: -3px; border-top-width: 6px; border-left-width: 6px; border-top-left-radius: 30px; }
.su-scan__corner--tr { top: -3px; right: -3px; border-top-width: 6px; border-right-width: 6px; border-top-right-radius: 30px; }
.su-scan__corner--bl { bottom: -3px; left: -3px; border-bottom-width: 6px; border-left-width: 6px; border-bottom-left-radius: 30px; }
.su-scan__corner--br { bottom: -3px; right: -3px; border-bottom-width: 6px; border-right-width: 6px; border-bottom-right-radius: 30px; }
.su-scan__sweep {
  position: absolute; left: 14px; right: 14px; top: 14px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0));
  animation: su-sweep 2.2s ease-in-out infinite alternate;
  opacity: 0;
}
.su-scan.is-live .su-scan__sweep { opacity: 1; }
@keyframes su-sweep { from { transform: translateY(0); } to { transform: translateY(calc(var(--su-scan-size) - 30px)); } }
.su-scan.is-found .su-scan__frame { background: rgba(255, 255, 255, 0.22); }
.su-scan.is-found .su-scan__sweep { opacity: 0; }
.su-scan.is-found .su-scan__corner--tl { transform: translate(10px, 10px); }
.su-scan.is-found .su-scan__corner--tr { transform: translate(-10px, 10px); }
.su-scan.is-found .su-scan__corner--bl { transform: translate(10px, -10px); }
.su-scan.is-found .su-scan__corner--br { transform: translate(-10px, -10px); }

.su-scan__top {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; justify-content: space-between; align-items: center;
  padding: max(14px, env(safe-area-inset-top)) var(--su-gutter) 0;
}
.su-scan__icon {
  width: var(--su-tap); height: var(--su-tap); border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; cursor: pointer; padding: 0;
  background: rgba(0, 0, 0, 0.55); box-shadow: inset 0 0 0 1.5px var(--su-line);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.su-scan__icon svg { width: 24px; height: 24px; fill: none; stroke: var(--su-ink); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.su-scan__torch.is-on { background: var(--su-ink); }
.su-scan__torch.is-on svg { stroke: var(--su-bg); }
.su-scan__bottom {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 0 var(--su-gutter) max(28px, env(safe-area-inset-bottom));
  text-align: center;
}
.su-scan__hint { margin: 0; max-width: 340px; font: 800 22px/1.22 var(--su-display); text-wrap: balance; }
.su-scan__status { margin: 0; min-height: 24px; max-width: 360px; font-size: 16px; color: var(--su-ink-2); text-wrap: pretty; }
.su-scan__status:empty { min-height: 0; }
.su-scan__status.is-error { color: var(--su-ink); font-weight: 600; }
.su-scan__retry { margin-top: 10px; min-width: 200px; }
.su-scan__manual { margin-top: 4px; }

/* ── park graphic (DPParkGraphic) ──────────────────────────────────── */
.pg { display: block; width: 100%; height: auto; overflow: visible; }
.pg-rect { fill: var(--su-fill); stroke: none; }
.pg-edge { fill: none; stroke: var(--su-ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
.pg-grid line { stroke: rgba(255, 255, 255, 0.07); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pg-dim line { stroke: var(--su-ink-3); stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.pg-dim-bg { fill: var(--su-bg); }
.pg-dim-bg--pill { stroke: var(--su-line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pg-foot { fill: var(--su-ink); }
.pg-dim-text {
  fill: var(--su-ink); font: 600 15px var(--su-body);
  font-variant-numeric: tabular-nums;
  text-anchor: middle; dominant-baseline: central;
}
.pg-front { fill: var(--su-ink-3); font: 600 11px var(--su-body); letter-spacing: 0.18em; text-anchor: middle; }
/* THE standard QR Portal graphic: white paper disc, the complete black QR inside (park-graphic portalMarkup) */
.pg-portal-disc { fill: #fff; }
.pg-portal-qr { fill: #000; }
.cal-code.is-drag .pg-portal-disc { fill: #e8e8e8; }
.pg-qr { fill: var(--su-ink); }
.pg-qr-eye { fill: var(--su-bg); }
.pg-qr-pupil { fill: var(--su-ink); }
.pg-halo { fill: rgba(255, 255, 255, 0.1); stroke: var(--su-ink-3); stroke-width: 1.25; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.pg-arrow line, .pg-arrow polyline { fill: none; stroke: var(--su-ink); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.pg-person .pg-person__head { fill: var(--su-ink); }
.pg-person__label { fill: var(--su-ink-3); font: 600 10px var(--su-body); letter-spacing: 0.16em; text-anchor: middle; }
.pg-person rect, .pg-person ellipse, .pg-person circle, .pg-person path { fill: rgba(255, 255, 255, 0.2); stroke: var(--su-ink-2); stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.pg-wall { fill: var(--su-fill-2); stroke: var(--su-ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
.pg-edge-line { stroke: var(--su-ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
.pg-edge-line--fade { stroke: var(--su-ink-4); stroke-dasharray: 4 5; }
.pg-guide { stroke: var(--su-ink-4); stroke-width: 1.25; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }

/* ── calibrate tool (DPCalibrate, /setup/calibrate.js; owner: calibrate) ── */
.cal { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.cal-host { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.cal-say { flex: none; margin: 0 0 clamp(8px, 1.6dvh, 18px); }
.cal-say__line { margin: 0; font: 800 clamp(17px, 2.6dvh, 21px)/1.25 var(--su-display); text-wrap: balance; }
.cal-say__line--2 { margin-top: 4px; font: 500 clamp(15px, 2.1dvh, 18px)/1.4 var(--su-body); color: var(--su-ink-2); }
@media (min-width: 720px) { .cal-say__line { font-size: 24px; } }

.cal-skel { flex: 1 1 auto; min-height: 160px; border-radius: var(--su-radius); }
.cal-stage {
  position: relative;
  flex: 1 1 auto; min-height: 150px;
  border-radius: var(--su-radius);
  background: var(--su-fill-2);
  box-shadow: inset 0 0 0 1px var(--su-line-2);
  overflow: hidden;
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  cursor: grab;
  opacity: 0; transition: opacity 260ms var(--su-ease);
}
.cal-stage.is-ready { opacity: 1; }
.cal-stage.is-grabbing { cursor: grabbing; }
.cal-stage:focus-visible { outline: 3px solid var(--su-ink); outline-offset: 3px; }
.cal-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.cal-svg.is-hidden { visibility: hidden; }
.cal-floor line { stroke: rgba(255, 255, 255, 0.055); stroke-width: 1; }
.cal-box__fill { transition: fill 160ms; }
.cal-box.is-drag .cal-box__fill { fill: var(--su-fill-3); }
.cal-box__edge { stroke-width: 2.5; }
.cal-box__front { stroke: var(--su-ink); stroke-width: 5; stroke-linecap: round; }
.cal-box__label { fill: var(--su-ink-3); }
.cal-handle { cursor: grab; }
.cal-handle__hit { fill: transparent; }
.cal-handle__ring { fill: var(--su-bg); stroke: var(--su-ink); stroke-width: 2.5; transition: fill 160ms; }
.cal-handle__icon path, .cal-handle__icon polyline { fill: none; stroke: var(--su-ink); stroke-width: 2.4; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; transition: stroke 160ms; }
.cal-box.is-turn .cal-handle__ring { fill: var(--su-ink); }
.cal-box.is-turn .cal-handle__icon path, .cal-box.is-turn .cal-handle__icon polyline { stroke: var(--su-bg); }
.cal-handle__stem { stroke: var(--su-ink-3); stroke-width: 1.5; stroke-dasharray: 3 4; }
.cal-dims { fill: var(--su-ink-2); font: 700 14px var(--su-body); font-variant-numeric: tabular-nums; text-anchor: middle; dominant-baseline: central; pointer-events: none; }
.cal-code { cursor: move; }
.cal-code__hit { fill: transparent; }
.cal-code__wall { stroke: var(--su-ink-3); stroke-width: 6; stroke-linecap: round; }

.cal-live, .cal-chip {
  position: absolute; top: 12px; z-index: 2;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 0 14px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.72); box-shadow: inset 0 0 0 1px var(--su-line);
  color: var(--su-ink); font: 600 14px/1 var(--su-body);
}
.cal-live { left: 12px; max-width: calc(100% - 140px); pointer-events: none; }
.cal-live__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-live__dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--su-ink-4); }
.cal-live.is-on .cal-live__dot { background: var(--su-ink); animation: cal-pulse 1.6s ease-in-out infinite; }
.cal-live.is-err .cal-live__dot { background: transparent; box-shadow: inset 0 0 0 2px var(--su-ink); }
@keyframes cal-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.55); } 50% { box-shadow: 0 0 0 6px rgba(255, 255, 255, 0); } }
.cal-chip { right: 12px; border: 0; cursor: pointer; transition: background 160ms, opacity 160ms; }
.cal-chip:hover { background: rgba(40, 40, 40, 0.9); }
.cal-chip:disabled { opacity: 0.4; cursor: default; }
.cal-chip svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.cal-angle {
  position: absolute; left: 50%; bottom: 14px; z-index: 2;
  padding: 8px 16px; border-radius: 999px;
  background: var(--su-ink); color: var(--su-bg);
  font: 800 20px/1 var(--su-display);
  font-variant-numeric: proportional-nums; font-feature-settings: "zero" 0, "tnum" 0;
  transform: translate(-50%, 10px); opacity: 0; pointer-events: none;
  transition: opacity 160ms, transform 200ms var(--su-ease);
}
.cal-angle.is-on { opacity: 1; transform: translate(-50%, 0); }

.cal-readout { flex: none; margin: 8px 0 0; min-height: 20px; font-size: 14px; color: var(--su-ink-2); text-align: center; }
.cal-hint { flex: none; margin: 2px 0 10px; font-size: 15px; color: var(--su-ink-3); text-align: center; text-wrap: pretty; }

/* "My QR Portal is on the wall": an explicit checkbox; ticking it reveals the height panel */
.cal-check {
  flex: none;
  position: relative;
  display: flex; align-items: center; gap: 14px;
  min-height: var(--su-tap); padding: 10px 16px;
  border-radius: var(--su-radius);
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line-2);
  cursor: pointer;
  transition: background 180ms, box-shadow 180ms;
}
.cal-check.is-on { background: var(--su-fill); box-shadow: inset 0 0 0 2px var(--su-ink); }
.cal-check__input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.cal-check__box {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  box-shadow: inset 0 0 0 2px var(--su-ink-2);
  transition: background 160ms, box-shadow 160ms;
}
.cal-check__input:checked + .cal-check__box {
  background: var(--su-ink) var(--su-check) center / 22px no-repeat;
  box-shadow: inset 0 0 0 2px var(--su-ink);
}
.cal-check__input:focus-visible + .cal-check__box { outline: 3px solid var(--su-ink); outline-offset: 3px; }
.cal-check__label { flex: 1 1 auto; min-width: 0; font: 700 17px/1.25 var(--su-body); }

/* the height panel (wall portals only): the wall picture + a vertical slider */
.cal-wall {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: stretch; gap: 8px;
  flex: none; grid-template-rows: minmax(0, 1fr);
  height: clamp(170px, 25dvh, 260px);
  margin-top: 8px; padding: 8px 8px 8px 4px;
  border-radius: var(--su-radius);
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1px var(--su-line-2);
  animation: su-rise 260ms var(--su-ease) both;
}
.cal-wall__art { min-width: 0; min-height: 0; height: 100%; overflow: hidden; display: flex; align-items: center; touch-action: none; cursor: ns-resize; }
.cal-wall__art.is-drag { cursor: grabbing; }
.cal-wall__svg { width: 100%; height: 100%; }
.cal-vs__value { display: none; }
.cal-vs__value--unused {
  position: absolute; left: 14px; top: 12px;
  font: 800 24px/1 var(--su-display); letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.cal--wall .cal-hint, .cal--wall .cal-say__line--2, .cal--wall .cal-readout { display: none; }
.cal-vs { display: flex; flex-direction: column; align-items: center; gap: 3px; height: 100%; min-height: 0; padding: 2px 0; }
.cal-vs__cap { font: 600 11px/1 var(--su-body); letter-spacing: 0.12em; text-transform: uppercase; color: var(--su-ink-3); }
.cal-vs__step {
  flex: 0 0 auto; width: 34px; height: 34px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; box-shadow: inset 0 0 0 1.5px var(--su-line); color: var(--su-ink);
}
.cal-vs__step:active { background: var(--su-fill); }
.cal-vs__step svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.cal-vs__track { --cal-h: 0.5; position: relative; flex: 1 1 auto; width: 56px; min-height: 48px; margin: 14px 0; touch-action: none; cursor: ns-resize; }
.cal-vs__track::before { content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 6px; margin-left: -3px; border-radius: 3px; background: var(--su-fill-3); }
.cal-vs__fill { position: absolute; left: 50%; bottom: 0; width: 6px; margin-left: -3px; border-radius: 3px; height: calc(var(--cal-h) * 100%); background: var(--su-ink); }
.cal-vs__thumb {
  position: absolute; left: 50%; bottom: calc(var(--cal-h) * 100%);
  width: 28px; height: 28px; margin: 0 0 -14px -14px; border-radius: 50%;
  background: var(--su-ink); box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.14);
  transition: transform 140ms var(--su-ease);
}
.cal-vs__track.is-drag .cal-vs__thumb { transform: scale(1.12); }
.cal-vs__track:focus-visible { outline: 3px solid var(--su-ink); outline-offset: 4px; border-radius: 12px; }

.cal-finish { flex: none; margin-top: 12px; }

/* ── finish (.10 save · .11 plan · .12 extras · all set) — finish-plan ─ */
.su-fn-pane { animation: su-rise 320ms var(--su-ease) both; }
.su-fn-msg { min-height: 24px; margin: 12px 0 0; font-size: 16px; color: var(--su-ink-2); text-wrap: pretty; }
.su-fn-msg:empty { min-height: 0; margin: 0; }
.su-fn-msg.is-error { color: var(--su-ink); font-weight: 600; }
.su-fn-msg.is-error::before { content: '! '; font: 800 15px/1 var(--su-display); }

.su-fn-account {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px; border-radius: var(--su-radius);
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line-2);
}
.su-fn-account.is-saved { box-shadow: inset 0 0 0 2px var(--su-ink); background: var(--su-fill); }
.su-fn-avatar {
  flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--su-ink); color: var(--su-bg);
  font: 800 20px/1 var(--su-display); text-transform: uppercase;
}
.su-fn-account__text { min-width: 0; flex: 1 1 auto; }
.su-fn-account__name { display: block; font: 800 18px/1.2 var(--su-display); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.su-fn-account__sub { display: block; margin-top: 3px; font-size: 15px; color: var(--su-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.su-fn-code {
  display: block; width: 100%; height: 76px; padding: 0 12px;
  border: 0; border-radius: 18px; outline: 0;
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line);
  color: var(--su-ink); text-align: center;
  font: 800 38px/1 var(--su-display); letter-spacing: 0.32em; text-indent: 0.32em;
  font-variant-numeric: tabular-nums;
  transition: box-shadow 160ms;
}
.su-fn-code::placeholder { color: var(--su-ink-4); letter-spacing: 0.32em; }
.su-fn-code:focus { box-shadow: inset 0 0 0 2px var(--su-ink); }
.su-fn-code.is-wrong { animation: su-fn-shake 360ms var(--su-ease); }
@keyframes su-fn-shake { 20%, 60% { transform: translateX(-8px); } 40%, 80% { transform: translateX(8px); } }
.su-fn-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 12px; margin-top: 10px; }
.su-fn-links .su-link:disabled { opacity: 0.55; cursor: default; text-decoration: none; }
.su-input--date { color-scheme: dark; }

.su-fn-trial {
  display: flex; align-items: center; gap: 14px;
  margin: 0 0 22px; padding: 16px 18px; border-radius: var(--su-radius);
  box-shadow: inset 0 0 0 1.5px var(--su-line);
}
.su-fn-trial__days { flex: 0 0 auto; font: 800 40px/1 var(--su-display); font-variant-numeric: proportional-nums; font-feature-settings: "zero" 0, "tnum" 0; }
.su-fn-trial__text { font-size: 16px; color: var(--su-ink-2); }
.su-fn-trial__text b { display: block; color: var(--su-ink); font: 800 17px/1.25 var(--su-display); }

.su-fn-counter {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 0; border-bottom: 1px solid var(--su-line-2);
}
.su-fn-counter__text { min-width: 0; }
.su-fn-counter__title { display: block; font: 800 18px/1.2 var(--su-display); }
.su-fn-counter__sub { display: block; margin-top: 4px; font-size: 15px; color: var(--su-ink-3); }
.su-fn-stepper { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
.su-fn-stepper__btn {
  width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--su-fill); box-shadow: inset 0 0 0 1.5px var(--su-line);
  transition: background 160ms, transform 120ms var(--su-ease);
}
.su-fn-stepper__btn:active { transform: scale(0.92); }
.su-fn-stepper__btn:disabled { opacity: 0.35; cursor: default; transform: none; }
.su-fn-stepper__btn svg { width: 20px; height: 20px; fill: none; stroke: var(--su-ink); stroke-width: 2.6; stroke-linecap: round; }
.su-fn-stepper__val { min-width: 46px; text-align: center; font: 800 28px/1 var(--su-display); font-variant-numeric: proportional-nums; font-feature-settings: "zero" 0, "tnum" 0; }
.su-fn-stepper__val.is-bump { animation: su-pop 260ms var(--su-ease); }

.su-fn-total { margin: 22px 0 6px; text-align: center; }
.su-fn-total__price { display: block; font: 800 46px/1 var(--su-display); font-variant-numeric: proportional-nums; font-feature-settings: "zero" 0, "tnum" 0; }
.su-fn-total__per { display: block; margin-top: 8px; font-size: 16px; color: var(--su-ink-3); }
.su-fn-total__once { display: block; margin-top: 4px; font-size: 16px; color: var(--su-ink-2); }

.su-fn-switches { list-style: none; margin: 0 0 12px; padding: 0; }
.su-fn-switch {
  display: flex; align-items: center; gap: 16px;
  padding: 18px 0; border-bottom: 1px solid var(--su-line-2);
}
.su-fn-switch:last-child { border-bottom: 0; }
.su-fn-switch__icon { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center; background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line-2); }
.su-fn-switch__icon svg { width: 24px; height: 24px; fill: none; stroke: var(--su-ink); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.su-fn-switch__text { flex: 1 1 auto; min-width: 0; }
.su-fn-switch__title { display: block; font: 800 19px/1.2 var(--su-display); }
.su-fn-switch__sub { display: block; margin-top: 4px; font-size: 15px; line-height: 1.4; color: var(--su-ink-3); text-wrap: pretty; }
.su-fn-toggle {
  position: relative; flex: 0 0 auto;
  width: 68px; height: 40px; padding: 0; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--su-fill); box-shadow: inset 0 0 0 1.5px var(--su-line);
  transition: background 200ms var(--su-ease), box-shadow 200ms;
}
.su-fn-toggle::after {
  content: ''; position: absolute; top: 5px; left: 5px;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--su-ink-3);
  transition: transform 240ms var(--su-ease), background 200ms;
}
.su-fn-toggle[aria-checked="true"] { background: var(--su-ink); box-shadow: none; }
.su-fn-toggle[aria-checked="true"]::after { transform: translateX(28px); background: var(--su-bg) var(--su-check) center / 0 no-repeat; }
.su-fn-toggle.is-saving { opacity: 0.7; }

.su-fn-done { position: relative; min-height: 200px; margin: -16px 0 4px; }
.su-fn-done .su-cele { background: transparent; }
.su-fn-summary > li { justify-content: space-between; min-width: 0; }
.su-fn-summary__label { flex: 0 0 auto; color: var(--su-ink-3); font-size: 16px; }
.su-fn-summary__value { flex: 1 1 auto; min-width: 0; margin-left: auto; text-align: right; font-weight: 600; overflow-wrap: anywhere; }
.su-fn-summary .su-tick { margin-left: 12px; }
@media (prefers-reduced-motion: reduce) {
  .su-fn-pane, .su-fn-code.is-wrong, .su-fn-stepper__val.is-bump { animation: none; }
  .su-fn-toggle::after { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
 * setup-flow screens (.00–.07, .09) — public/setup/steps/*.js  (.sf-*)
 * and the printable QR Portal (views/setup/print.ejs)          (.sp-*)
 * ═══════════════════════════════════════════════════════════════════════ */

/* line icons */
.sf-ico { display: block; width: 100%; height: 100%; fill: none; stroke: var(--su-ink); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.sf-ico .sf-ico__fill { fill: var(--su-ink); stroke: none; }

/* what you'll need / summary rows */
.sf-need { list-style: none; margin: 0 0 12px; padding: 0; display: grid; grid-auto-rows: 1fr; gap: 10px; } /* every row as tall as the tallest (Aidan) */
.sf-need__row {
  display: flex; align-items: center; gap: 16px;
  min-height: 76px; padding: 14px 16px;
  border-radius: var(--su-radius);
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line-2);
}
.sf-need__row > .sf-ico { flex: 0 0 44px; width: 44px; height: 44px; }
.sf-need__text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.sf-need__title { font: 800 18px/1.2 var(--su-display); }
.sf-need__sub { margin-top: 3px; font-size: 15px; line-height: 1.35; color: var(--su-ink-3); }

.sf-tag {
  display: inline-block; margin-left: 10px; padding: 3px 8px; border-radius: 999px; vertical-align: 2px;
  background: var(--su-ink); color: var(--su-bg);
  font: 700 11px/1.2 var(--su-body); letter-spacing: 0.06em; text-transform: uppercase;
}

/* numbered short instructions */
.sf-steps { list-style: none; margin: 0 0 22px; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.sf-steps > li { display: flex; align-items: flex-start; gap: 14px; font-size: 18px; line-height: 1.4; color: var(--su-ink-2); }
.sf-steps > li b { color: var(--su-ink); font-weight: 700; }
.sf-steps .su-list__n { margin-top: -3px; }
.sf-steps--tight { gap: 10px; margin-bottom: 18px; }
.sf-steps--tight > li { font-size: 17px; }
/* the Connect step's "Print QR Portal" link: inline in its line, bold + underlined like the text around it */
.sf-steps__print { color: var(--su-ink); font: inherit; font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }

/* .01 portal: trial card, found card */
.sf-trial, .sf-found {
  position: relative;
  display: flex; align-items: center; gap: 18px;
  padding: 16px; margin: 0 0 22px;
  border-radius: var(--su-radius);
  background: var(--su-fill); box-shadow: inset 0 0 0 2px var(--su-ink);
}
.sf-trial__qr { flex: 0 0 auto; width: 112px; height: 112px; padding: 8px; border-radius: 12px; background: #fff; display: block; }
.sf-trial__text, .sf-found__text { display: flex; flex-direction: column; min-width: 0; }
.sf-trial__id, .sf-found__title { font: 800 22px/1.15 var(--su-display); letter-spacing: 0.01em; }
.sf-trial__sub, .sf-found__sub { margin-top: 6px; font-size: 16px; color: var(--su-ink-2); }
.sf-found { min-height: 96px; padding-right: 16px; }
.sf-found__ico { flex: 0 0 52px; width: 52px; height: 52px; }
.sf-printbtn, .sf-dl { margin: 0 0 8px; }

/* .02 how it works */
.sf-how__art { display: block; width: 100%; height: auto; max-height: 46vh; overflow: visible; }
.sf-how__floor { fill: var(--su-fill); stroke: var(--su-ink); stroke-width: 2; stroke-linejoin: round; }
.sf-how__grid line { stroke: rgba(255, 255, 255, 0.1); stroke-width: 1; }
.sf-how__arrow line, .sf-how__arrow polyline { fill: none; stroke: var(--su-ink); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.sf-how__arrow { animation: sf-nudge 1.8s var(--su-ease) infinite; }
.sf-how__qrbg { fill: var(--su-ink); }
.sf-how__eye { fill: var(--su-bg); }
.sf-how__sight line { stroke: var(--su-ink-3); stroke-width: 1.5; stroke-dasharray: 4 5; animation: sf-dash 1.2s linear infinite; }
.sf-how__set path { fill: var(--su-bg); stroke: var(--su-ink); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.sf-how__label { fill: var(--su-ink-3); font: 600 11px var(--su-body); letter-spacing: 0.2em; text-anchor: middle; }
@keyframes sf-nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes sf-dash { to { stroke-dashoffset: -18; } }

/* .03 play space: "Put the code here" */
.sf-sizes { margin-bottom: 18px; }
.sf-space.is-swap svg { animation: sf-swap 380ms var(--su-ease) both; }
@keyframes sf-swap { from { opacity: 0.2; transform: scale(0.97); } to { opacity: 1; transform: none; } }
.sf-here__ring { fill: none; stroke: var(--su-ink); stroke-width: 2.5; transform-box: fill-box; transform-origin: center; animation: sf-pulse 1.6s var(--su-ease) infinite; }
.sf-here__line { stroke: var(--su-ink); stroke-width: 1.5; }
.sf-here__text { fill: var(--su-ink); font: 800 17px var(--su-body); text-anchor: end; dominant-baseline: middle; }
@keyframes sf-pulse { 0% { transform: scale(0.7); opacity: 1; } 100% { transform: scale(1.7); opacity: 0; } }

.sf-seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 0 0 12px; }
.sf-seg__opt {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  min-height: 100px; padding: 10px 6px 10px; border: 0; border-radius: var(--su-radius); cursor: pointer;
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line-2); color: var(--su-ink);
  transition: background 180ms, box-shadow 180ms, transform 140ms var(--su-ease);
}
.sf-seg__opt:active { transform: scale(0.97); }
.sf-seg__art { width: 46px; height: 46px; display: flex; align-items: flex-end; justify-content: center; }
.sf-seg__art svg { width: 100%; height: 100%; }
.sf-seg__label { font: 800 17px/1.1 var(--su-display); white-space: nowrap; }
.sf-seg__unit { font-size: 13px; color: var(--su-ink-3); }
.sf-seg__opt.is-selected { background: var(--su-ink); color: var(--su-bg); box-shadow: none; }
.sf-seg__opt.is-selected .sf-seg__unit { color: rgba(0, 0, 0, 0.6); }
.sf-seg__opt.is-selected .pg-rect { fill: rgba(0, 0, 0, 0.14); }
.sf-seg__opt.is-selected .pg-edge, .sf-seg__opt.is-selected .pg-arrow line, .sf-seg__opt.is-selected .pg-arrow polyline { stroke: var(--su-bg); }
.sf-seg__opt.is-selected .pg-qr { fill: var(--su-bg); }
.sf-seg__opt.is-selected .pg-qr-eye { fill: var(--su-ink); }
.sf-seg__note { margin: 0 0 6px; min-height: 26px; font-size: 17px; color: var(--su-ink-2); }
.sf-tag--lead { margin: 0 10px 0 0; }
.sf-space svg { max-height: 36vh; }
.sf-space { scroll-margin-bottom: 160px; }

/* .04 games: title cards, black & white until picked */
.sf-games { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 12px; margin: 0 0 8px; }
@media (min-width: 560px) { .sf-games { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.sf-game {
  position: relative; display: block; width: 100%; aspect-ratio: 2 / 3;
  padding: 0; border: 0; border-radius: 18px; cursor: pointer; color: var(--su-ink);
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line);
  text-align: left;
  animation: sf-card-in 420ms var(--su-ease) both; animation-delay: calc(var(--sf-i, 0) * 60ms);
  transition: transform 160ms var(--su-ease), box-shadow 200ms;
}
.sf-game:active { transform: scale(0.97); }
.sf-game__art { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; background: var(--sf-tint, #111); }
.sf-game__art img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: grayscale(1) brightness(0.62) contrast(1.05);
  transition: filter 420ms var(--su-ease), transform 420ms var(--su-ease);
}
.sf-game__art.is-empty { background: var(--su-fill); }
.sf-game__shade { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; background: linear-gradient(to top, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.2) 38%, rgba(0, 0, 0, 0) 60%); }
.sf-game__logo { position: absolute; left: 0; right: 0; margin: 0 auto; bottom: 24%; width: var(--sf-logo-w, 70%); max-height: 34%; object-fit: contain; filter: grayscale(1); transition: filter 420ms; }
.sf-game__tag {
  position: absolute; top: 10px; left: 10px; padding: 4px 9px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.6); box-shadow: inset 0 0 0 1px var(--su-line);
  font: 700 10px/1.2 var(--su-body); letter-spacing: 0.06em; text-transform: uppercase;
}
.sf-game__name { position: absolute; left: 12px; right: 12px; bottom: 12px; font: 800 17px/1.12 var(--su-display); text-wrap: balance; }
.sf-game__check {
  position: absolute; top: 10px; right: 10px; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.45); box-shadow: inset 0 0 0 2px var(--su-ink-2);
  transition: background 200ms, box-shadow 200ms, transform 200ms var(--su-ease);
}
.sf-game__check .sf-ico { width: 20px; height: 20px; stroke-width: 5; opacity: 0; stroke-dasharray: 40; stroke-dashoffset: 40; }
.sf-game.is-picked { box-shadow: none; }
.sf-game::after { content: ''; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 0 var(--su-ink); transition: box-shadow 200ms var(--su-ease); }
.sf-game.is-picked::after { box-shadow: inset 0 0 0 4px var(--su-ink), inset 0 0 0 7px rgba(0, 0, 0, 0.55); }
.sf-game.is-picked .sf-game__art img { filter: none; }
.sf-game.is-picked .sf-game__logo { filter: none; }
.sf-game.is-picked .sf-game__check { background: var(--su-ink); box-shadow: none; animation: su-pop 380ms var(--su-ease) both; }
.sf-game.is-picked .sf-game__check .sf-ico { stroke: var(--su-bg); opacity: 1; animation: su-draw 260ms var(--su-ease) 120ms forwards; }
.sf-game--skel { cursor: default; animation: su-shimmer 1.4s ease-in-out infinite; box-shadow: none; }
.sf-empty { grid-column: 1 / -1; }
@keyframes sf-card-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* .05 headsets: the big counter */
.sf-count {
  margin: 18px 0 0; padding: 22px 16px 18px; border-radius: var(--su-radius); text-align: center;
  background: var(--su-fill-2); box-shadow: inset 0 0 0 1.5px var(--su-line-2);
  opacity: 0.35; pointer-events: none; transition: opacity 260ms var(--su-ease);
}
.sf-count.is-on { opacity: 1; pointer-events: auto; }
.sf-count__q { margin: 0 0 12px; font: 800 19px/1.2 var(--su-display); }
.sf-count__row { display: flex; align-items: center; justify-content: center; gap: 22px; }
.sf-count__btn {
  flex: 0 0 auto; width: 72px; height: 72px; border-radius: 50%; padding: 18px;
  border: 0; cursor: pointer; background: var(--su-fill); box-shadow: inset 0 0 0 2px var(--su-ink);
  transition: transform 120ms var(--su-ease), background 160ms;
}
.sf-count__btn:active { transform: scale(0.92); background: var(--su-fill-3); }
.sf-count__btn:disabled { box-shadow: inset 0 0 0 2px var(--su-line); cursor: default; transform: none; }
.sf-count__btn:disabled .sf-ico { stroke: var(--su-ink-4); }
.sf-count__btn .sf-ico { stroke-width: 4; }
.sf-count__num { min-width: 2.2ch; font: 800 88px/1 var(--su-display); font-variant-numeric: proportional-nums; font-feature-settings: "zero" 0, "tnum" 0; }
.sf-count__num.is-bump { animation: su-pop 280ms var(--su-ease); }
.sf-count__unit { margin: 6px 0 0; font-size: 16px; color: var(--su-ink-3); }

/* .05 play time: how long players get before the game stops — the game, then a huge "20m", − / + and a slider */
.sf-len__game { display: flex; align-items: center; gap: 14px; margin: 0; padding: 10px; border-radius: 18px; background: var(--su-fill-2); box-shadow: inset 0 0 0 1px var(--su-line-2); }
.sf-len__card {
  position: relative; flex: none; width: 48px; aspect-ratio: 2 / 3; overflow: hidden; border-radius: 10px;
  background: var(--sf-tint, var(--su-fill)); box-shadow: inset 0 0 0 1px var(--su-line);
}
.sf-len__card.is-loading { animation: su-shimmer 1.4s ease-in-out infinite; }
.sf-len__card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-len__gtext { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sf-len__name { margin: 0; font: 800 17px/1.15 var(--su-display); text-wrap: balance; }
.sf-len__rec { margin: 0; font-size: 15px; line-height: 1.3; color: var(--su-ink-3); }
.sf-len { margin: 0; display: flex; flex-direction: column; justify-content: center; min-height: 0; padding: 4px 0 0; }
.sf-len__row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sf-len__btn {
  flex: none; width: 60px; height: 60px; padding: 16px; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--su-fill); box-shadow: inset 0 0 0 1.5px var(--su-line); color: var(--su-ink);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
  transition: transform 120ms var(--su-ease), background 160ms;
}
.sf-len__btn:active { transform: scale(0.92); background: var(--su-fill-3); }
.sf-len__btn:disabled { opacity: 0.35; cursor: default; transform: none; }
.sf-len__btn .sf-ico { width: 100%; height: 100%; stroke: currentColor; stroke-width: 4; stroke-linecap: round; fill: none; }
.sf-len__num { flex: 1 1 auto; text-align: center; font: 800 96px/1 var(--su-display); letter-spacing: -0.03em; font-variant-numeric: proportional-nums; }
.sf-len__num.is-bump { animation: su-pop 280ms var(--su-ease); }
.sf-len__hint { margin: 6px 0 0; min-height: 20px; text-align: center; font: 600 15px/20px var(--su-body); color: var(--su-ink-3); }
/* the slider: a thick track filled to the value, a big white thumb, a notch at the recommendation */
.sf-len__track { position: relative; margin: 18px 0 0; height: 44px; --p: 20%; --rec: 20%; }
.sf-len__track::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 10px; transform: translateY(-50%); border-radius: 999px;
  background: linear-gradient(to right, var(--su-ink) 0, var(--su-ink) var(--p), var(--su-fill-3, rgba(255, 255, 255, 0.16)) var(--p)); }
.sf-len__mark { position: absolute; top: 50%; left: calc(14px + (100% - 28px) * var(--rec) / 100%); width: 4px; height: 22px; transform: translate(-50%, -50%); border-radius: 2px; background: var(--su-ink-3); pointer-events: none; }
.sf-len__range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; background: transparent; -webkit-appearance: none; appearance: none; cursor: pointer; touch-action: pan-y; }
.sf-len__range:focus { outline: none; }
.sf-len__range::-webkit-slider-runnable-track { height: 44px; background: transparent; }
.sf-len__range::-moz-range-track { height: 44px; background: transparent; }
.sf-len__range::-webkit-slider-thumb { -webkit-appearance: none; width: 28px; height: 28px; margin-top: 8px; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); }
.sf-len__range::-moz-range-thumb { width: 28px; height: 28px; border: 0; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); }
.sf-len__range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.35); }
.sf-len__ends { display: flex; justify-content: space-between; margin: 2px 2px 0; font: 600 14px/1 var(--su-body); color: var(--su-ink-4); }
/* Waiting for players (DPLengthPicker.mountWait): "1m 30s" is twice as wide as "20m". */
.sf-len__num.is-long { min-width: 0; font-size: clamp(40px, 12.5vw, 60px); white-space: nowrap; letter-spacing: -0.04em; }

/* .06 app */
.sf-tip { margin-bottom: 20px; }
.sf-tip__title { margin: 0 0 6px; font: 800 17px/1.2 var(--su-display); }
.sf-tip__text { margin: 0; font-size: 16px; color: var(--su-ink-2); }

/* .07 connect: live list */
.sf-joined__head { display: flex; align-items: baseline; gap: 10px; margin: 6px 0 10px; }
.sf-joined__of { font-size: 17px; color: var(--su-ink-2); }
.sf-joined { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.sf-joined__row {
  display: flex; align-items: center; gap: 14px; min-height: 72px; padding: 12px 16px;
  border-radius: var(--su-radius); background: var(--su-fill); box-shadow: inset 0 0 0 1.5px var(--su-ink-2);
}
.sf-joined__row > .sf-ico { flex: 0 0 38px; width: 38px; height: 38px; }
.sf-joined__row.is-new { animation: sf-arrive 520ms var(--su-ease) both; }
.sf-joined__text { display: flex; flex-direction: column; min-width: 0; }
.sf-joined__name { font: 800 17px/1.2 var(--su-display); }
.sf-joined__sub { font-size: 14px; color: var(--su-ink-3); }
/* paused download (Oct 28 2026): one line, ellipsized rather than wrapped */
.sf-joined__wait {
  display: flex; align-items: center; gap: 14px; min-height: 72px; padding: 12px 16px;
  border-radius: var(--su-radius); box-shadow: inset 0 0 0 1.5px var(--su-line); border: 0;
  background-image: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0));
  background-size: 200% 100%; animation: sf-sheen 2.4s linear infinite;
  font-size: 17px; color: var(--su-ink-2);
  scroll-margin-bottom: 170px;
}
.sf-dots { flex: 0 0 38px; display: inline-flex; justify-content: center; gap: 5px; }
.sf-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--su-ink); animation: sf-dot 1.2s ease-in-out infinite; }
.sf-dots span:nth-child(2) { animation-delay: 0.15s; }
.sf-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes sf-dot { 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-4px); } }
@keyframes sf-sheen { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@keyframes sf-arrive { 0% { opacity: 0; transform: translateY(16px) scale(0.96); } 60% { transform: translateY(-2px) scale(1.01); } 100% { opacity: 1; transform: none; } }

/* .09 ready */
.sf-ready { display: flex; align-items: center; gap: 16px; margin: -6px 0 18px; }
.sf-ready__ico { flex: 0 0 52px; width: 52px; height: 52px; }
.sf-ready__lede { margin: 0; }
.sf-summary .sf-need__row { animation: sf-card-in 420ms var(--su-ease) both; animation-delay: calc(var(--sf-i, 0) * 90ms); }

@media (prefers-reduced-motion: reduce) {
  .sf-how__arrow, .sf-how__sight line, .sf-here__ring, .sf-space.is-swap svg, .sf-game, .sf-joined__row.is-new,
  .sf-joined__wait, .sf-dots span, .sf-summary .sf-need__row, .sf-count__num.is-bump { animation: none; }
  .sf-game.is-picked .sf-game__check { animation: none; }
  .sf-game.is-picked .sf-game__check .sf-ico { animation: none; stroke-dashoffset: 0; }
}

/* ── the printable QR Portal (views/setup/print.ejs) ───────────────── */
/* The ROUND printout (fit-pass, round 2): a white disc 7.5 in across with the
   code in its middle. The setup app makes body.su one screen tall with no
   scroll; this page is a normal document, so it scrolls again. */
body.su.sp { height: auto; min-height: 100vh; overflow: auto; padding: 0 var(--su-gutter) 40px; }
.sp-bar {
  max-width: 8.5in; margin: 0 auto; padding: 18px 0;
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}
.sp-bar__text { margin: 0; font-size: 16px; color: var(--su-ink-2); }
.sp-page {
  width: 100%; max-width: 8.5in; margin: 0 auto; padding: 0.4in 0.4in 0.35in;
  background: #fff; color: #000; border-radius: 6px;
  display: flex; flex-direction: column; align-items: center;
}
.sp-top { width: 100%; display: flex; align-items: center; gap: 10px; }
.sp-top__logo { width: 26px; height: 26px; }
.sp-top__word { height: 13px; width: auto; }
.sp-top__id { margin-left: auto; font: 700 14px/1 var(--su-body); letter-spacing: 0.08em; text-transform: uppercase; }
.sp-disc { display: block; width: min(7.5in, 100%); height: auto; aspect-ratio: 1; margin: 0.22in 0 0.18in; overflow: visible; }
.sp-disc__edge { fill: #fff; stroke: #000; stroke-width: 0.35; }
.sp-disc__arrow { fill: #000; }
.sp-disc__into { fill: #000; font: 800 4.6px var(--su-display); letter-spacing: -0.01px; text-anchor: middle; }
.sp-disc__small { fill: #000; font: 700 2.3px var(--su-body); letter-spacing: 0.35px; text-anchor: middle; }
.sp-disc__date { fill: #000; font: 800 3px var(--su-body); text-anchor: middle; }
.sp-how { margin: 0 0 0.14in; padding-left: 1.2em; width: 100%; font-size: 15px; line-height: 1.45; color: #000; }
.sp-how li { margin: 2px 0; }
.sp-foot { width: 100%; display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding-top: 0.1in; border-top: 1px solid #000; font-size: 13px; color: #000; }
.sp-foot__url { font-weight: 700; letter-spacing: 0.02em; }
@media (max-width: 600px) {
  .sp-page { padding: 18px 16px; }
  .sp-disc { margin: 14px 0; }
}
/* EXACTLY one sheet, on letter or A4, whichever margins the browser or printer adds (Safari and many print dialogs ignore
   @page margins). The sheet is a fixed-height box that fits inside the printable area at up to 0.6in margins, and the art takes
   whatever the words leave, so nothing can run onto a second page. */
@page { size: letter; margin: 0.25in; }
@media print {
  html.sp-root, body.su.sp { background: #fff !important; padding: 0 !important; margin: 0 !important; min-height: 0 !important; height: auto !important; }
  /* the app's dark color-scheme makes Chrome paint the page margins #121212 */
  html.sp-root { color-scheme: light; }
  .sp-bar { display: none !important; }
  .sp-page { box-sizing: border-box; display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 7.5in; height: 9.7in; margin: 0 auto; padding: 0; border-radius: 0; overflow: hidden; break-inside: avoid; page-break-inside: avoid; break-after: avoid; page-break-after: avoid; }
  .sp-top, .sp-how, .sp-foot { flex: 0 0 auto; }
  .sp-disc, .sp-disc--trial { flex: 1 1 0; min-height: 0; width: 100%; height: auto; aspect-ratio: auto; margin: 0.08in 0; }
  .sp-how { width: 100%; box-sizing: border-box; padding-left: 1.7em; font-size: 11pt; line-height: 1.3; margin: 0 0 0.06in; }
  .sp-foot { font-size: 10pt; padding-top: 0.05in; }
}

/* ═══════════════════════════════════════════════════════════════════════
 * FIT PASS (round 2, fit-pass agent): every step fits ONE phone screen with
 * no page scroll at 393×852 AND 375×667. Rules: the one big thing in a step
 * (graphic, camera, list) flexes and shrinks; text and buttons are flex:none.
 * Only the game grid (.04) scrolls, inside its own box. Below 760px tall the
 * header compacts (brand icon + rail on one row, a smaller step number); on
 * tall screens the step number stays the hero.
 * ═══════════════════════════════════════════════════════════════════════ */

/* body text never below 16px */
.su-choice__sub, .su-muted, .sf-need__sub, .su-field__label, .su-fn-switch__sub,
.su-fn-counter__sub, .su-fn-account__sub, .sf-joined__sub, .cal-hint { font-size: 16px; }

/* ── the one-screen layout primitives ── */
/* zero specificity: any step class that flexes (.cal-host, .sf-games…) wins */
:where(.su-body > *) { flex: none; }
:where(.su-body > .su-fit-grow) { flex: 1 1 auto; min-height: 0; }

/* .02 how it works: the drawing takes what's left */
.sf-how { flex: 1 1 auto; min-height: 110px; margin: 0 0 14px; display: flex; align-items: center; justify-content: center; }
.sf-how__art { width: 100%; height: 100%; max-height: none; }
.sf-how__disc { fill: var(--su-ink); }
.sf-how__qrcode { fill: var(--su-bg); }
.sf-how__qrcode--eye { fill: var(--su-ink); }
.sf-steps { margin-bottom: 4px; }

/* .01 trial portal: the round printout, with its code in the middle */
.sf-trial__qr { width: 104px; height: 104px; padding: 21px; border-radius: 50%; }

/* .03 play space: the drawing flexes */
.sf-space { flex: 1 1 auto; min-height: 120px; display: flex; flex-direction: column; margin: 0; scroll-margin-bottom: 0; }
.sf-space svg { flex: 1 1 auto; min-height: 0; width: 100%; height: 100%; max-height: none; }
.sf-space figcaption { flex: none; margin-top: 6px; }

/* .04 games: the grid scrolls inside its own box (the one allowed inner scroll) */
.sf-games {
  flex: 1 1 auto; min-height: 0; margin: 0; padding: 4px 2px 18px;
  overflow-y: auto; overscroll-behavior: contain; align-content: start;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
}

/* .05 headsets: have / need side by side, the counter below */
[data-step="headsets"] .su-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 0; }
[data-step="headsets"] .su-choice { flex-direction: column; align-items: flex-start; gap: 8px; min-height: 0; padding: 14px 14px 16px; }
[data-step="headsets"] .su-choice::after { top: 14px; right: 14px; margin-top: 0; }
[data-step="headsets"] .su-choice__art { flex: none; width: 40px; height: 40px; }
.sf-count { margin-top: 12px; padding: 16px 12px 14px; }
.sf-count__q { margin-bottom: 8px; }

/* .06 app install */
.sf-tip { margin-bottom: 14px; padding: 14px 16px; }
.sf-dl { margin: 2px 0 6px; }

/* .07 connect: the live list fills the space; once a headset is in, the how-to folds away */
.sf-joined { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 0; padding-bottom: 4px; gap: 8px; }
.sf-connect--live .sf-joined { padding-top: 10px; -webkit-mask-image: linear-gradient(to bottom, transparent, #000 14px); mask-image: linear-gradient(to bottom, transparent, #000 14px); }
.sf-joined__row, .sf-joined__wait { min-height: 60px; padding: 8px 14px; flex: none; }
.sf-joined__row > .sf-ico { flex-basis: 32px; width: 32px; height: 32px; }
.sf-joined__head { margin: 0 0 8px; }
.sf-connect--live .sf-steps { display: none; }

/* .09 ready + welcome rows */
.sf-ready { margin: 0 0 12px; }

/* .11 plan: own / rent side by side, compact counters */
.su-fn-pane { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
[data-step="finish"] .su-body > div, [data-step="plan"] .su-body > div, [data-step="extras"] .su-body > div { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
[data-step="plan"] .su-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 0 0 4px; }
[data-step="plan"] .su-choice { flex-direction: column; align-items: flex-start; min-height: 0; padding: 14px; }
[data-step="plan"] .su-choice__title { padding-right: 30px; }
.su-fn-stepper__btn { width: 56px; height: 56px; }
[data-step="plan"] .su-choice::after { top: 14px; right: 12px; margin-top: 0; }
[data-step="plan"] .su-choice__title { font-size: 17px; }
.su-fn-counter { padding: 10px 0; }
.su-fn-total { margin: 12px 0 2px; }
.su-fn-total__price { font-size: 40px; }
.su-fn-total__per { margin-top: 4px; }
[data-step="plan"] .su-muted { margin-top: 6px; text-align: center; }

/* .12 extras: the whole row is the switch's tap target */
.su-fn-switch { padding: 12px 0; gap: 14px; cursor: pointer; }
.su-fn-switch__sub { margin-top: 2px; line-height: 1.3; }

/* all set */
.su-fn-done { flex: 1 1 auto; min-height: 120px; margin: 0; }
.su-fn-done .su-cele { min-height: 0; }
.su-fn-summary { margin-bottom: 0; }
.su-fn-app {
  display: flex; align-items: center; gap: 14px; margin: 16px 0 0; padding: 14px 14px 14px 14px;
  border-radius: 22px; background: var(--su-fill); box-shadow: inset 0 0 0 1px var(--su-line-2);
  color: var(--su-ink); text-decoration: none; -webkit-tap-highlight-color: transparent;
  transition: transform 160ms var(--su-ease), background 160ms var(--su-ease);
}
.su-fn-app:active { transform: scale(0.98); background: var(--su-fill-2); }
.su-fn-app__icon { flex: none; width: 60px; height: 60px; border-radius: 14px; box-shadow: 0 6px 18px rgba(106, 64, 240, 0.35), inset 0 0 0 1px rgba(255, 255, 255, 0.14); }
.su-fn-app__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.su-fn-app__kicker { font: 600 13px/1.2 var(--su-body); color: var(--su-ink-3); }
.su-fn-app__name { font: 800 19px/1.1 var(--su-display); letter-spacing: -0.01em; }
.su-fn-app__line { font-size: 15px; line-height: 1.3; color: var(--su-ink-3); text-wrap: pretty; }
.su-fn-app__get { flex: none; min-width: 72px; padding: 9px 18px; border-radius: 999px; background: var(--su-ink); color: var(--su-bg); font: 700 16px/1 var(--su-body); text-align: center; }
.su-fn-app__qr { display: none; flex: none; width: 88px; height: 88px; padding: 6px; border-radius: 12px; background: #fff; }
@media (hover: hover) and (pointer: fine) and (min-width: 720px) { .su-fn-app__qr { display: block; } .su-fn-app__get { display: none; } }

/* ── short screens (≤ 760px tall, e.g. 375×667) ── */
@media (max-height: 760px) {
  .su-app { padding-top: max(4px, env(safe-area-inset-top)); }
  .su-top { flex-direction: row; align-items: center; gap: 8px; padding: 2px 0 0; }
  .su-brand { min-height: 36px; flex: none; }
  .su-brand__text { height: 12px; }
  .su-rail { flex: 1 1 auto; min-width: 0; padding: 3px 2px; }
  .su-progress { flex: 1 1 auto; min-width: 0; margin: 0 0 0 6px; }
  .su-rail__item + .su-rail__item::before { min-width: 2px; margin: 0 1px; }
  .su-dot { width: 20px; height: 20px; font-size: 9.5px; border-width: 1.25px; }
  .su-dot svg { width: 12px; height: 12px; }
  .su-step { padding-top: 6px; }
  .su-head { margin-bottom: 12px; }
  .su-num { font-size: clamp(40px, 9.5dvh, 64px); margin-bottom: 2px; }
  .su-title { font-size: clamp(21px, 3.8dvh, 26px); }
  .su-sub { margin-top: 5px; font-size: 16px; line-height: 1.35; }
  .su-bar { padding-top: 12px; padding-bottom: max(10px, env(safe-area-inset-bottom)); }
  .su-bar .su-link { min-height: 44px; }
  .su-lede { font-size: 17px; line-height: 1.4; margin-bottom: 12px; }
  .su-eyebrow { margin-bottom: 6px; }

  .su-choices { gap: 10px; }
  .su-choice { min-height: 64px; padding-top: 12px; padding-bottom: 12px; }
  .sf-need { gap: 8px; margin-bottom: 0; }
  .sf-need__row { min-height: 60px; padding: 14px 14px; gap: 14px; }
  .sf-need__row > .sf-ico { flex-basis: 36px; width: 36px; height: 36px; }
  .sf-need__title { font-size: 17px; }
  .sf-need__sub { line-height: 1.25; }
  .sf-steps { gap: 8px; }
  .sf-steps > li { font-size: 17px; line-height: 1.35; }

  .sf-trial, .sf-found { margin-bottom: 14px; padding: 12px; gap: 14px; }
  .sf-trial__qr { width: 88px; height: 88px; padding: 18px; }

  .sf-seg { gap: 8px; margin-bottom: 8px; }
  .sf-seg__opt { min-height: 0; padding: 8px 4px; gap: 3px; }
  .sf-seg__art { width: 34px; height: 34px; }
  .sf-seg__note { font-size: 16px; margin-bottom: 4px; }

  [data-step="headsets"] .su-choice { padding: 12px 12px 12px; gap: 6px; }
  [data-step="headsets"] .su-choice__art { width: 32px; height: 32px; }
  .sf-count { margin-top: 10px; padding: 12px 10px 10px; }
  .sf-count__q { font-size: 18px; margin-bottom: 4px; }
  .sf-count__num { font-size: 64px; }
  .sf-count__btn { width: 60px; height: 60px; padding: 15px; }
  .sf-count__unit { margin-top: 2px; }
  .sf-len__num { font-size: 76px; }
  .sf-len__btn { width: 54px; height: 54px; padding: 14px; }
  .sf-len__num.is-long { font-size: clamp(40px, 12vw, 52px); }
  .sf-len__track { margin-top: 10px; }

  .sf-tip { margin-bottom: 10px; padding: 12px 14px; }
  .sf-tip__title { font-size: 16px; margin-bottom: 4px; }

  .sf-joined__row, .sf-joined__wait { min-height: 56px; }

  .su-fn-counter__title { font-size: 17px; }
  .su-fn-total__price { font-size: 34px; }
  .su-fn-total { margin: 8px 0 0; }
  .su-fn-counter { padding: 6px 0; }
  [data-step="plan"] .su-choice { padding: 12px; }
  [data-step="plan"] .su-muted { margin-top: 4px; line-height: 1.35; }
  .su-fn-switch { padding: 9px 0; }
  .su-fn-switch__icon { flex-basis: 38px; width: 38px; height: 38px; border-radius: 12px; }
  .su-fn-switch__title { font-size: 17px; }
  .su-fn-code { height: 64px; font-size: 32px; }
  .su-fn-links { margin-top: 4px; }
  .su-fn-done { min-height: 90px; }
  .su-fn-done .su-cele__mark { width: 96px; height: 96px; }
  .su-fn-summary > li { min-height: 48px; padding: 8px 0; }
  .su-fn-stepper__btn { width: 52px; height: 52px; }
  .su-fn-stepper__val { min-width: 38px; }
  /* calibrate (wall mode): a shorter height panel and stage so both fit */
  .cal-stage { min-height: 120px; }
  .cal-wall { height: 170px; margin-top: 6px; }
  .cal-vs { gap: 2px; }
  .cal-vs__track { margin: 6px 0; min-height: 40px; }
  .cal-say__line { font-size: 17px; }
}

/* Headset product images (headset-images agent): DreamPark rental, Meta Quest 3,
 * Meta Quest 3S — 3:2 transparent art from /setup/headsets/, drawn by
 * DPSetupFlow.headsetImg. Width carries the slot; the height follows 3:2. */
.sf-hsimg { display: block; flex: none; aspect-ratio: 3 / 2; }
.sf-hsimg img { display: block; width: 100%; height: 100%; object-fit: contain; }
.sf-need__row > .sf-hsimg { flex: 0 0 56px; width: 56px; margin: 0 -6px; }
.sf-joined__row > .sf-hsimg { flex: 0 0 54px; width: 54px; margin-left: -4px; }
.su-choice__art > .sf-hsimg { width: 100%; }
[data-step="headsets"] .su-choice__art:has(.sf-hsimg) { width: 60px; }
.sf-joined__name { display: flex; align-items: center; gap: 6px 8px; flex-wrap: wrap; }
.sf-joined__tag {
  font: 700 10px/1 var(--su-body, inherit); letter-spacing: .03em; text-transform: uppercase; white-space: nowrap;
  padding: 3px 6px; border-radius: 999px; border: 1px solid var(--su-ink-3); color: var(--su-ink-2);
}
/* iPhone SE in Safari (≈553px tall): the step number and title step down so every step stays one screen. */
@media (max-height: 600px) { .su-num { font-size: 40px; } .su-title { font-size: 21px; } }
@media (max-height: 700px) {
  .sf-need__row > .sf-hsimg { flex-basis: 48px; width: 48px; }
  [data-step="headsets"] .su-choice__art:has(.sf-hsimg) { width: 50px; }
}

/* .01 portal: each choice title stays on ONE line (Aidan), shrinking with the screen */
[data-step="portal"] .su-choice__title { white-space: nowrap; font-size: clamp(14px, 4.3vw, 19px); }

/* .01 trial card: the ACTUAL portal artwork (/setup/print/<id>/portal.svg — disc, arrow, full code) */
.sf-trial__qr { width: 104px; height: 104px; padding: 0; border-radius: 50%; background: transparent; }
@media (max-height: 760px) { .sf-trial__qr { width: 88px; height: 88px; padding: 0; } }
.pg-portal-art { image-rendering: auto; }

/* the TRIAL printout: the code as wide as the page (100 × 122 art), still on one sheet of letter/A4 */
.sp-disc--trial { aspect-ratio: 100 / 122; width: min(7.2in, 100%); }

/* No status pills (Aidan, Oct 26): calibrate's headset status is plain text over the stage — no outline, no dot */
.cal-live { min-height: 0; padding: 4px 2px; background: none; box-shadow: none; color: var(--su-ink-2); font: 600 14px/1.2 var(--su-body); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9); }
.cal-live.is-on { color: var(--su-ink); }
.cal-live__dot { display: none; }

/* .04 games: ways to play (ways-to-play.md §6) — a title with more than one says so on its card,
   and the first pick asks which way it plays first. Plain words, no pills. */
.sf-game--ways .sf-game__name { bottom: 32px; }
.sf-game__ways { position: absolute; left: 12px; right: 12px; bottom: 12px; font: 600 13px/1.2 var(--su-body); color: rgba(255, 255, 255, 0.82); }
.sf-ways { display: flex; flex-direction: column; min-height: 0; }
.sf-ways__q { margin: 2px 0 6px; font: 800 22px/1.15 var(--su-display); text-wrap: balance; }
.sf-ways__sub { margin: 0 0 14px; color: var(--su-ink-3); }
.sf-ways__list { display: flex; flex-direction: column; gap: 10px; overflow-y: auto; overscroll-behavior: contain; padding: 2px 2px 14px; min-height: 0; }
.sf-way {
  display: flex; align-items: center; gap: 14px; width: 100%; padding: 12px; text-align: left; color: inherit; cursor: pointer;
  border: 0; border-radius: 16px; background: transparent; box-shadow: inset 0 0 0 1.5px var(--su-line);
  transition: transform 120ms var(--su-ease), box-shadow 160ms var(--su-ease), background 160ms var(--su-ease);
}
.sf-way:active { transform: scale(0.98); }
.sf-way.is-on { background: var(--su-fill); box-shadow: inset 0 0 0 2.5px var(--su-ink); }
.sf-way__cover { flex: none; width: 64px; height: 64px; border-radius: 12px; overflow: hidden; background: var(--su-fill); display: flex; align-items: center; justify-content: center; }
.sf-way__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-way__initial { font: 800 28px/1 var(--su-display); color: var(--su-ink-2); }
.sf-way__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.sf-way__name { font: 700 17px/1.2 var(--su-body); }
.sf-way__blurb { font-size: 16px; line-height: 1.35; color: var(--su-ink-3); }
.sf-way__check { flex: none; width: 24px; height: 24px; border-radius: 50%; box-shadow: inset 0 0 0 2px var(--su-line); }
.sf-way.is-on .sf-way__check { background: var(--su-ink); box-shadow: inset 0 0 0 7px var(--su-ink), inset 0 0 0 24px var(--su-bg); }
@media (prefers-reduced-motion: reduce) { .sf-way { transition: none; } }
.sf-ways-mode .su-sub { display: none; }

/* .04 games: scrolling down the list folds the description away and slides the Continue bar off
   (games.js toggles body.sf-scrolled; a small scroll up brings both back). Only the games step.
   NOTHING IN THE SCROLLING LIST MOVES WHEN IT FOLDS (Aidan, Oct 26: the old max-height/padding fold pulled the
   grid up under the finger and threw the scroll forward). The fold is paint-only:
   - the description floats over the top of the grid (position: absolute, black behind it) and fades + lifts away;
     the grid's own top padding is exactly the description's height (--sf-sub-h, measured by games.js), so at the
     top nothing is hidden and further down the cards simply scroll up under where it was;
   - the grid always runs to the bottom of the screen, behind the Continue bar (padding-bottom = the bar's height),
     and the bar hides by transform only. .su-app keeps the same padding the whole time on this step. */
.su-step[data-step="games"] { --sf-sub-top: 12px; --sf-head-gap: clamp(10px, 2.2dvh, 26px); }
@media (max-height: 760px) { .su-step[data-step="games"] { --sf-sub-top: 5px; --sf-head-gap: 12px; } }
@media (max-height: 600px) { .su-step[data-step="games"] { --sf-sub-top: 3px; --sf-head-gap: 8px; } }
.su-step[data-step="games"] .su-head { position: relative; z-index: 3; margin-bottom: 0; }
.su-step[data-step="games"] .su-sub {
  position: absolute; left: 0; right: 0; top: 100%;
  margin: 0; padding: var(--sf-sub-top) 0 var(--sf-head-gap);
  background: var(--su-bg);
  transition: opacity 220ms ease, transform 280ms var(--su-ease);
}
/* a short fade under the description, so cards slide under it softly when it comes back mid-list */
.su-step[data-step="games"] .su-sub::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 14px; background: linear-gradient(var(--su-bg), rgba(0, 0, 0, 0)); pointer-events: none; }
body.sf-scrolled .su-step[data-step="games"] .su-sub { opacity: 0; transform: translateY(-10px); pointer-events: none; }
.su-step[data-step="games"] .sf-games {
  padding-top: calc(var(--sf-sub-h, 0px) + 4px);
  padding-bottom: calc(var(--su-bar-h, 104px) + 18px);
  scroll-padding-top: var(--sf-sub-h, 0px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 12px, #000 calc(100% - 22px), transparent);
          mask-image: linear-gradient(to bottom, transparent 0, #000 12px, #000 calc(100% - 22px), transparent);
}
body.su-has-bar.sf-games-step .su-app { padding-bottom: 0; }
.su-bar { transition: transform 280ms var(--su-ease), opacity 200ms ease; }
body.sf-scrolled:not(.sf-at-end) .su-bar { transform: translateY(100%); opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .su-step[data-step="games"] .su-sub, .su-bar { transition: none; }
}

/* iPhone SE in Safari (375 × 553 with the bars): tighten spacing only — the number/title sizes above stay. */
@media (max-height: 600px) {
  .su-step { padding-top: 4px; }
  .su-head { margin-bottom: 8px; }
  .su-sub { margin-top: 3px; line-height: 1.3; }
  .su-eyebrow { margin-bottom: 4px; }
  .su-lede { margin-bottom: 8px; line-height: 1.35; }
  .sf-need { gap: 6px; }
  .sf-need__row { min-height: 52px; padding: 10px 12px; gap: 12px; }
  .sf-need__row > .sf-ico { flex-basis: 32px; width: 32px; height: 32px; }
  .sf-need__sub { margin-top: 1px; line-height: 1.2; }
  .su-choices { gap: 8px; }
  .su-choice { min-height: 56px; padding-top: 9px; padding-bottom: 9px; }
  .sf-steps { gap: 5px; }
  .sf-steps > li { line-height: 1.3; }
  .su-bar { padding-top: 8px; }
}
/* .06 install: on short screens the time note goes (the bar covers it) */
@media (max-height: 700px) { .sf-dl-note { display: none; } }
@media (max-height: 600px) {
  .sf-tip { padding: 9px 12px; margin-bottom: 8px; }
  .sf-tip__title { display: inline; margin: 0 6px 0 0; }
  .sf-tip__text { display: inline; line-height: 1.3; }
  .sf-dl { margin: 0 0 4px; min-height: 52px; }
}
/* SE (375 × 553): calibrate and plan, spacing only */
@media (max-height: 600px) {
  .cal-stage { min-height: 96px; }
  .cal-wall { height: 132px; margin-top: 4px; }
  .cal-check { min-height: 48px; padding-top: 6px; padding-bottom: 6px; }
  .cal-say__line { font-size: 16px; line-height: 1.25; }
  .su-fn-counter { padding: 3px 0; }
  .su-fn-total { margin: 4px 0 0; display: flex; align-items: baseline; justify-content: center; flex-wrap: wrap; gap: 0 8px; }
  .su-fn-total__price { display: inline; font-size: 30px; }
  .su-fn-total__per { display: inline; margin-top: 0; }
  .su-fn-total__once { flex-basis: 100%; margin-top: 2px; }
  [data-step="plan"] .su-choice { min-height: 0; padding-top: 8px; padding-bottom: 8px; }
}
@media (max-height: 600px) {
  .su-fn-stepper__btn { width: 46px; height: 46px; }
  [data-step="plan"] .su-choices { margin-bottom: 2px; }
  [data-step="plan"] .su-choice__title { line-height: 1.12; }
  .cal-wall { height: 132px; }
  .cal-stage { min-height: 88px; }
  [data-step="plan"] .su-fn-counter__sub { margin-top: 1px; line-height: 1.2; }
}

/* ── .08 Line it up, round 2 (Aidan, Oct 26): wall SWITCH above the editor, Overhead | Wall views, live dot ── */
.cal-switch { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 14px; min-height: 44px; margin: 0 0 8px; }
.cal-switch__label { font: 700 17px/1.25 var(--su-body); }
.cal-switch__toggle { flex: none; }
.cal-views { flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; margin: 0 0 8px; border-radius: 14px; background: var(--su-fill-2); }
.cal-views__opt { min-height: 40px; border: 0; border-radius: 10px; background: transparent; color: var(--su-ink-2); font: 700 15px/1 var(--su-body); cursor: pointer; transition: background 160ms, color 160ms; }
.cal-views__opt.is-on { background: var(--su-ink); color: var(--su-bg); }
/* the wall view takes the whole editor space */
.cal--view-wall .cal-wall { flex: 1 1 auto; height: auto; min-height: 150px; margin-top: 0; }
.cal--view-wall .cal-readout { display: none; }
/* live: a small pulsing dot + shimmering words, no pill */
.cal-live { display: inline-flex; align-items: center; gap: 8px; }
.cal-live__dot { display: block; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--su-ink-4); box-shadow: none; }
.cal-live.is-on .cal-live__dot { background: #fff; animation: cal-live-pulse 1.4s ease-in-out infinite; }
.cal-live.is-err .cal-live__dot { background: var(--su-ink-4); }
.cal-live.is-on .cal-live__text {
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.62) 0%, rgba(255, 255, 255, 0.62) 35%, #fff 50%, rgba(255, 255, 255, 0.62) 65%, rgba(255, 255, 255, 0.62) 100%);
  background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: cal-live-shimmer 2.4s linear infinite;
}
@keyframes cal-live-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.6); } 60% { box-shadow: 0 0 0 7px rgba(255, 255, 255, 0); } }
@keyframes cal-live-shimmer { from { background-position: 100% 0; } to { background-position: -150% 0; } }
.cal-wall .cal-live { position: absolute; top: 10px; left: 12px; z-index: 2; }
@media (prefers-reduced-motion: reduce) {
  .cal-live.is-on .cal-live__dot, .cal-live.is-on .cal-live__text { animation: none; }
  .cal-live.is-on .cal-live__text { background: none; color: var(--su-ink); }
}


/* wall view: the live line sits in its own strip above the drawing (never over the wall) */
.cal--view-wall .cal-wall__art { padding-top: 26px; box-sizing: border-box; }
.cal--view-wall .cal-wall .cal-live { top: 8px; }
@media (max-height: 600px) { .cal--view-wall .cal-wall { min-height: 120px; } .cal-views { margin-bottom: 6px; } .cal-switch { margin-bottom: 4px; } }
/* portal settings (a scrolling page, not a one-screen step): the editor gets a real height in both views */
.cal--settings .cal-stage { flex: none; height: clamp(300px, 46vh, 520px); }
.cal--settings.cal--view-wall .cal-wall { flex: none; height: clamp(300px, 46vh, 520px); }

/* No zooming in the setup app (Aidan, Oct 26): no double-tap zoom on fast taps (e.g. the .05 minus button), no pinch.
   touch-action: manipulation removes double-tap zoom in iOS Safari, which ignores user-scalable=no; shell.js blocks the
   pinch (gesturestart). Inputs stay >= 16px so focusing one never zooms. Elements that set touch-action: none keep it. */
html, body { touch-action: manipulation; }
.su input, .su select, .su textarea { font-size: max(16px, 1em); }

/* ── .04 games: "See Details" under each card + the game info view (steps/game-details.js, Oct 26) ── */
.sf-gitem { display: flex; flex-direction: column; min-width: 0; }
.sf-game__more {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 4px;
  min-height: 40px; margin: 2px 0 -6px; padding: 0 8px 0 2px;
  border: 0; background: none; cursor: pointer; color: var(--su-ink-2);
  font: 600 16px/1.2 var(--su-body);
  animation: sf-card-in 420ms var(--su-ease) both; animation-delay: calc(var(--sf-i, 0) * 60ms + 80ms);
}
.sf-game__more::after { content: ''; width: 7px; height: 7px; margin-left: 2px; border-right: 2px solid currentColor; border-top: 2px solid currentColor; transform: rotate(45deg); opacity: 0.7; }
.sf-game__more:active { color: var(--su-ink); }
@media (max-height: 600px) { .sf-game__more { min-height: 36px; } }

/* the sheet: full screen over the setup, its own scroll, a sticky Add button at the bottom */
.sf-gd {
  position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column;
  background: var(--su-bg); color: var(--su-ink);
  transform: translateX(100%); transition: transform 380ms var(--su-ease);
}
.sf-gd.is-on { transform: none; }
.sf-gd__top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 4;
  padding: max(6px, env(safe-area-inset-top)) 8px 6px; pointer-events: none;
}
.sf-gd__top { transition: background 200ms ease; }
.sf-gd.is-scrolled .sf-gd__top { background: linear-gradient(var(--su-bg) 72%, rgba(0, 0, 0, 0)); padding-bottom: 14px; }
.sf-gd.is-scrolled .sf-gd__back { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
.sf-gd__back {
  pointer-events: auto; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 16px 0 12px;
  border: 0; border-radius: 999px; cursor: pointer; color: var(--su-ink);
  background: rgba(0, 0, 0, 0.55); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  font: 600 16px/1 var(--su-body);
}
.sf-gd__back::before { content: ''; width: 9px; height: 9px; border-left: 2.5px solid currentColor; border-bottom: 2.5px solid currentColor; transform: rotate(45deg); margin-left: 4px; }
.sf-gd__scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.sf-gd__scroll::-webkit-scrollbar { display: none; }
.sf-gd__inner { max-width: var(--su-max); margin: 0 auto; padding-bottom: calc(var(--sf-gd-bar, 96px) + 16px); }

/* hero: the trailer (muted, plays itself), else the title card on a soft blur of itself */
.sf-gd__hero { position: relative; width: 100%; aspect-ratio: 16 / 10; max-height: 46dvh; overflow: hidden; background: #0b0b0b; }
.sf-gd__hero--portrait { aspect-ratio: 4 / 5; max-height: 52dvh; }
.sf-gd__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; background: #000; }
.sf-gd__backdrop { position: absolute; inset: -24px; width: calc(100% + 48px); height: calc(100% + 48px); object-fit: cover; filter: blur(22px) brightness(0.42) saturate(1.1); }
.sf-gd__poster { position: absolute; top: 50%; left: 50%; height: 86%; aspect-ratio: 2 / 3; transform: translate(-50%, -46%); object-fit: cover; border-radius: 14px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(255, 255, 255, 0.12); }
.sf-gd__fit { display: flex; align-items: center; gap: 8px; margin: 18px 0 0; font: 600 16px/1.3 var(--su-body); color: var(--su-ink); }
.sf-gd__fit svg { flex: none; width: 20px; height: 20px; }
.sf-gd__hero::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 30%; background: linear-gradient(to top, var(--su-bg), rgba(0, 0, 0, 0)); pointer-events: none; }
.sf-gd__hero.is-skel { animation: su-shimmer 1.4s ease-in-out infinite; }
/* no trailer: the portal page's poster — the title card centered at 2:3, about half the screen tall */
.sf-gd__hero--card { aspect-ratio: auto; max-height: none; background: transparent; overflow: visible; display: flex; justify-content: center; padding: calc(56px + env(safe-area-inset-top)) var(--su-gutter) 6px; }
.sf-gd__hero--card::after { content: none; }
.sf-gd__card { position: relative; height: clamp(240px, 47dvh, 480px); aspect-ratio: 2 / 3; max-width: 100%; border-radius: 20px; overflow: hidden; background: #111; }
.sf-gd__card.is-skel { background: var(--su-fill-2); animation: su-shimmer 1.4s ease-in-out infinite; }
.sf-gd__card-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-gd__card::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0.92) 88%); pointer-events: none; }
.sf-gd__card.is-skel::after { content: none; }
.sf-gd__card-body { position: absolute; left: 12px; right: 12px; bottom: 14px; z-index: 1; display: grid; gap: 4px; justify-items: center; text-align: center; }
.sf-gd__card-logo { width: 84%; max-width: 260px; max-height: 120px; height: auto; object-fit: contain; object-position: center bottom; }
.sf-gd__card-way { margin: 0; font: 600 15px/1.25 var(--su-body); color: var(--su-ink-3); }
.sf-gd__sound {
  position: absolute; right: 12px; bottom: 14px; z-index: 2; width: 44px; height: 44px; border: 0; border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center; color: var(--su-ink);
  background: rgba(0, 0, 0, 0.55); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.sf-gd__sound svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.sf-gd__body { padding: 4px var(--su-gutter) 0; }
.sf-gd__name { margin: 0; font: 800 26px/1.12 var(--su-display); letter-spacing: -0.01em; text-wrap: balance; }
.sf-gd__meta { margin: 8px 0 0; font-size: 16px; color: var(--su-ink-3); }
.sf-gd__rating { margin: 6px 0 0; font-size: 16px; color: var(--su-ink-2); }
.sf-gd__rating b { color: var(--su-ink); font-weight: 700; }
.sf-gd__desc { margin: 16px 0 0; font-size: 17px; line-height: 1.5; color: var(--su-ink-2); text-wrap: pretty; }
.sf-gd__h { margin: 28px 0 10px; font: 800 17px/1.2 var(--su-display); }
.sf-gd__note { margin: -4px 0 10px; font-size: 16px; color: var(--su-ink-3); }
.sf-gd__skel { height: 16px; margin: 12px 0 0; border-radius: 8px; background: var(--su-fill-2); animation: su-shimmer 1.4s ease-in-out infinite; }
.sf-gd__skel--name { width: 64%; height: 28px; margin-top: 0; }
.sf-gd__skel--short { width: 40%; }
.sf-gd__fail { margin: 16px 0 0; font-size: 16px; color: var(--su-ink-3); }

/* ways to play: plain rows, the same look as the picker's way chooser */
.sf-gd__ways { display: flex; flex-direction: column; gap: 10px; }
.sf-gd__way { display: flex; align-items: center; gap: 12px; padding: 10px; border-radius: 14px; box-shadow: inset 0 0 0 1.5px var(--su-line-2); }
.sf-gd__way .sf-way__cover { width: 52px; height: 52px; border-radius: 10px; }
.sf-gd__way .sf-way__name { font-size: 16px; }

/* play spaces: one row per setup size */
.sf-gd__spaces { display: flex; flex-direction: column; border-radius: 14px; box-shadow: inset 0 0 0 1.5px var(--su-line-2); }
.sf-gd__space { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 12px 14px; }
.sf-gd__space + .sf-gd__space { border-top: 1px solid var(--su-line-2); }
.sf-gd__space-size { font: 700 16px/1.3 var(--su-body); white-space: nowrap; }
.sf-gd__space-size span { font-weight: 500; color: var(--su-ink-3); }
.sf-gd__space-how { font-size: 16px; line-height: 1.3; color: var(--su-ink-2); text-align: right; }

/* player clips: a row of 9:16 posters; a tap plays one */
.sf-gd__clips { display: flex; gap: 10px; overflow-x: auto; margin: 0 calc(-1 * var(--su-gutter)); padding: 2px var(--su-gutter) 4px; scroll-snap-type: x mandatory; scroll-padding-inline: var(--su-gutter); scrollbar-width: none; overscroll-behavior-x: contain; }
.sf-gd__clips::-webkit-scrollbar { display: none; }
.sf-gd__clip { position: relative; flex: none; width: 118px; aspect-ratio: 9 / 16; padding: 0; border: 0; border-radius: 12px; overflow: hidden; cursor: pointer; background: var(--su-fill-2); scroll-snap-align: start; }
.sf-gd__clip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-gd__clip::after {
  content: ''; position: absolute; left: 50%; top: 50%; width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.5) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 7l9 5-9 5z' fill='%23fff'/%3E%3C/svg%3E") center / 22px no-repeat;
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.6);
}

/* the sticky Add / Added button */
.sf-gd__bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 24px var(--su-gutter) max(14px, env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--su-bg) 64%, rgba(0, 0, 0, 0));
}
.sf-gd__bar .su-btn { display: flex; width: 100%; max-width: calc(var(--su-max) - 2 * var(--su-gutter)); margin: 0 auto; font-size: 19px; }
.sf-gd__add.is-added { background: transparent; color: var(--su-ink); box-shadow: inset 0 0 0 2px var(--su-ink); }
.sf-gd__add .sf-ico { width: 22px; height: 22px; stroke: currentColor; stroke-width: 5; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* one clip, full screen over the sheet */
.sf-gd-clip { position: fixed; inset: 0; z-index: 55; display: flex; align-items: center; justify-content: center; background: #000; opacity: 0; transition: opacity 220ms ease; }
.sf-gd-clip.is-on { opacity: 1; }
.sf-gd-clip video { width: 100%; height: 100%; object-fit: contain; display: block; }
.sf-gd-clip .sf-gd__back { position: absolute; top: max(8px, env(safe-area-inset-top)); left: 8px; z-index: 2; }
.sf-gd-clip .sf-gd__back::before { display: none; }
@media (prefers-reduced-motion: reduce) { .sf-gd, .sf-gd-clip { transition: none; } .sf-gd__hero.is-skel, .sf-gd__skel { animation: none; } }
@media (max-height: 600px) { .sf-gd__name { font-size: 23px; } .sf-gd__desc { margin-top: 12px; } .sf-gd__h { margin-top: 22px; } }

/* "Live on your headset" is always shown in Line it up: dimmed to 50%, no pulse/shimmer, until a headset has the box (Aidan). */
.cal-live.is-off { opacity: 0.5; }
.cal-live.is-off .cal-live__dot { background: var(--su-ink-4); animation: none; }
.cal-live.is-off .cal-live__text { animation: none; background: none; color: var(--su-ink-2); -webkit-text-fill-color: currentColor; }

/* ═══════════════════════════════════════════════════════════════════════
 * .10 Add it to the map + portal Settings → On the map (Oct 27 2026) — /setup/map-picker.js (.mp-*)
 * The map fills what the step leaves; the two small buttons float over it; the switch sits under it.
 * Map metadata only (contract §8).
 * ═══════════════════════════════════════════════════════════════════════ */
.mp-host { flex: 1 0 auto; display: flex; flex-direction: column; }
.mp-host__map { flex: 1 0 auto; display: flex; flex-direction: column; }
.mp { flex: 1 0 auto; display: flex; flex-direction: column; }
.mp-frame {
  position: relative; flex: 1 0 auto; min-height: 170px; overflow: hidden;
  border-radius: var(--su-radius); background: var(--su-fill-2); box-shadow: inset 0 0 0 1px var(--su-line-2);
}
/* mapbox-gl.css makes .mapboxgl-map position:relative; this must win */
.mp-frame > .mp-map { position: absolute; inset: 0; opacity: 0; transition: opacity 260ms ease; }
.mp.has-map .mp-frame > .mp-map { opacity: 1; }
.mp-map .mapboxgl-ctrl-bottom-right, .mp-map .mapboxgl-ctrl-bottom-left { bottom: 54px; }
.mp-map .mapboxgl-ctrl-attrib { font-size: 10px; }
.mp-map .mapboxgl-ctrl-logo { transform: scale(0.8); transform-origin: left bottom; }
.mp-empty {
  position: absolute; inset: 0 0 52px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 16px 28px; text-align: center; transition: opacity 200ms ease;
}
.mp.has-map .mp-empty, .mp.has-point .mp-empty { opacity: 0; pointer-events: none; }
.mp.is-nomap.has-point .mp-empty { opacity: 1; }
.mp.is-nomap.has-point .mp-empty__text { display: none; }
.mp-empty__ico {
  width: 60px; height: 60px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: var(--su-fill); box-shadow: inset 0 0 0 1.5px var(--su-line);
}
.mp-empty__ico svg { width: 28px; height: 28px; fill: none; stroke: var(--su-ink); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.mp-empty__text { margin: 0; max-width: 240px; font-size: 16px; line-height: 1.45; color: var(--su-ink-2); text-wrap: balance; }
.mp-spot { position: absolute; left: 0; right: 0; top: 50%; margin: 30px 0 0; text-align: center; font: 600 15px/1.3 var(--su-body); color: var(--su-ink-2); }

.mp-pin {
  width: 56px; height: 56px; border-radius: 50%; cursor: grab;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55), 0 4px 14px rgba(0, 0, 0, 0.6);
}
.mp-pin:active { cursor: grabbing; }
.mp-pin__art { display: block; width: 100%; height: 100%; border-radius: 50%; pointer-events: none; -webkit-user-drag: none; }

.mp-tools {
  position: absolute; left: 10px; right: 10px; bottom: 10px; z-index: 3;
  display: flex; justify-content: space-between; gap: 8px; pointer-events: none;
}
.mp-tool {
  pointer-events: auto; flex: none; min-height: 40px; padding: 0 14px; border: 0; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: rgba(0, 0, 0, 0.74); box-shadow: inset 0 0 0 1.5px var(--su-line); color: var(--su-ink);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  font: 700 14px/1.1 var(--su-body); white-space: nowrap;
}
.mp-tool svg { flex: none; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* the setup step's main button asks for the location first */
.mp--loc-after:not(.has-point) .mp-tool--loc { display: none; }
.mp--loc-after:not(.has-point) .mp-tools { justify-content: center; }
.mp-tool.is-on { background: var(--su-ink); color: var(--su-bg); box-shadow: none; }
.mp-tool.is-busy svg { animation: mp-pulse 1s ease-in-out infinite; }
@keyframes mp-pulse { 50% { opacity: 0.3; } }

.mp-status { flex: none; margin: 10px 2px 0; font-size: 15px; line-height: 1.4; color: var(--su-ink-2); text-wrap: pretty; }
.mp-status.is-good::before {
  content: ''; display: inline-block; width: 16px; height: 16px; margin: 0 6px -3px 0; border-radius: 50%;
  background: var(--su-ink) var(--su-check) center / 12px no-repeat;
}
.mp-status.is-warn { color: var(--su-ink); }

.mp-search { position: absolute; left: 10px; right: 10px; top: 10px; z-index: 4; }
.mp.is-searching .mp-tools { display: none; }
.mp-search__row { display: flex; align-items: center; gap: 6px; }
.mp-search__cancel {
  flex: none; min-height: 48px; padding: 0 14px; border: 0; border-radius: 14px; cursor: pointer;
  background: rgba(0, 0, 0, 0.82); color: var(--su-ink); font: 700 15px/1 var(--su-body);
}
.mp-search__input { flex: 1 1 auto; min-width: 0; width: auto; min-height: 48px; background: rgba(0, 0, 0, 0.82); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.mp-results { list-style: none; margin: 6px 0 0; padding: 0 12px; border-radius: 16px; background: rgba(10, 10, 10, 0.94); max-height: 168px; overflow-y: auto; }
.mp-results:empty { display: none; }
.mp-results li:last-child .mp-results__row { border-bottom: 0; }
.mp-results__row {
  display: block; width: 100%; padding: 11px 2px; border: 0; border-bottom: 1px solid var(--su-line-2); background: transparent;
  color: var(--su-ink); text-align: left; font: 500 15px/1.35 var(--su-body); cursor: pointer;
}
.mp-results__note { padding: 10px 4px; font-size: 15px; color: var(--su-ink-3); }

.mp-public { flex: none; display: flex; align-items: center; gap: 14px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--su-line-2); }
.mp-public__text { flex: 1 1 auto; min-width: 0; }
.mp-public__title { display: block; font: 700 16px/1.3 var(--su-body); color: var(--su-ink); text-wrap: pretty; }
.mp-public__note { display: block; margin-top: 3px; font-size: 14px; line-height: 1.35; color: var(--su-ink-3); }
.mp-public__toggle { flex: none; }
.mp-host__switch[hidden] { display: none; }
@media (max-height: 600px) {
  .mp-frame { min-height: 112px; }
  .mp-status { margin-top: 8px; font-size: 14px; }
  .mp-public { margin-top: 8px; padding-top: 8px; }
  .mp-public__title { font-size: 15px; }
  /* the setup step on a short phone: the title says it; the note would push the switch off screen */
  [data-step="map"] .mp-public__note { display: none; }
}
@media (prefers-reduced-motion: reduce) { .mp-tool.is-busy svg { animation: none; } .mp-frame > .mp-map, .mp-empty { transition: none; } }

/* Paused download on a Connect row (Oct 28 2026): one line, ellipsized rather than wrapped, a size
 * down so "Open DreamPark" survives on a 375 px phone. Last in the file so it beats the 16px override. */
.sf-joined__row.is-paused .sf-joined__sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 14px; }

/* ── Your Wi-Fi (rental provisioning round, Oct 30 2026; /setup/steps/wifi.js) ──
   One card per network: name, password (show/hide), hidden-network switch. */
.su-wifi { display: flex; flex-direction: column; }
.su-wifi__list { display: grid; gap: 12px; }
.su-wifi__net { padding: 14px 16px 12px; transition: box-shadow 200ms; }
.su-card.su-wifi__net + .su-card.su-wifi__net { margin-top: 0; }
.su-wifi__net.is-new { animation: su-wifi-in 360ms var(--su-ease) both; }
.su-wifi__net.is-error { box-shadow: inset 0 0 0 2px var(--su-ink); }
.su-wifi__net.is-solo .su-wifi__head { display: none; }
.su-wifi__head { display: flex; align-items: center; justify-content: space-between; min-height: 28px; margin: 0 0 8px; }
.su-wifi__num { font: 800 13px/1 var(--su-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--su-ink-3); }
.su-wifi__remove { width: 32px; height: 32px; margin: -4px -6px -4px 0; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--su-ink-2); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.su-wifi__remove[hidden] { display: none; }
.su-wifi__remove svg, .su-wifi__eye svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.su-wifi__field { margin-bottom: 10px; }
.su-wifi__field .su-field__label { margin-bottom: 6px; font-size: 14px; }
.su-wifi__field .su-input { height: 48px; font-size: 18px; }
@media (max-height: 700px) { .su-wifi__net { padding: 12px 14px 10px; } .su-wifi__field { margin-bottom: 8px; } }
.su-wifi__pw { position: relative; display: block; }
.su-wifi__pwin { padding-right: 56px; }
.su-wifi__eye { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 44px; height: 44px; padding: 0; border: 0; border-radius: 12px; background: transparent; color: var(--su-ink-2); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.su-wifi__hidden { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 2px; }
.su-wifi__hiddent { font-size: 15px; font-weight: 600; color: var(--su-ink-2); }
.su-wifi__hidden .su-fn-toggle { transform: scale(0.82); transform-origin: right center; }
.su-wifi__add { margin-top: 12px; gap: 8px; }
.su-wifi__add svg { width: 20px; height: 20px; }
.su-wifi__note { margin-top: 8px; font-size: 14px; }
@keyframes su-wifi-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .su-wifi__net.is-new { animation: none; } }

/* ── Customize your QR Portal (/portal/portal-design.js) ── */
.su-dsn__stage { display: flex; justify-content: center; margin: 0 0 14px; min-height: 180px; }
.su-dsn__big { display: block; width: min(100%, 300px); height: auto; transition: opacity 0.15s ease; }
.su-dsn__stage.is-busy .su-dsn__big { opacity: 0.55; }
.su-dsn__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; text-align: center; }
.su-dsn__opt { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; padding: 8px 6px; border: 0; border-radius: 14px; background: var(--su-fill); color: var(--su-ink-2); font: inherit; cursor: pointer; }
.su-dsn__opt img { display: block; width: 100%; aspect-ratio: 1; object-fit: contain; }
.su-dsn__opt.is-on { color: var(--su-ink); box-shadow: inset 0 0 0 2px var(--su-ink); }
.su-dsn__name { font-size: 13px; font-weight: 600; line-height: 1.2; overflow-wrap: anywhere; }
.su-dsn__hint { font-size: 11px; line-height: 1.25; color: var(--su-ink-3); }
.su-dsn__tpl { display: inline-block; margin-top: 12px; color: var(--su-ink); font-size: 15px; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.su-dsn__up { justify-content: center; min-height: 96px; box-shadow: inset 0 0 0 1px var(--su-line); }

/* ── Sign the operator agreement (/portal/agreement-step.js) ── */
.su-agr__wait { height: 240px; border-radius: 18px; }
.su-agr__text { max-height: 36dvh; overflow-y: auto; padding: 16px; border-radius: 18px; background: var(--su-fill); box-shadow: inset 0 0 0 1px var(--su-line-2); }
.su-agr__text:focus-visible { outline: 2px solid var(--su-ink); outline-offset: 2px; }
.su-agr__text .oa__title { margin: 0; font: 800 18px/1.2 var(--su-display); }
.su-agr__text .oa__ver { margin: 4px 0 10px; font-size: 13px; color: var(--su-ink-3); }
.su-agr__text .oa__h { margin: 16px 0 6px; font: 800 15px/1.25 var(--su-display); }
.su-agr__text .oa__p { margin: 0 0 8px; font-size: 14px; line-height: 1.45; color: var(--su-ink-2); }
.su-agr__text .oa__p--caps { font-weight: 700; color: var(--su-ink); }
.su-agr__form { display: flex; flex-direction: column; gap: 4px; margin-top: 16px; }
.su-agr__check { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; font-size: 14px; line-height: 1.4; color: var(--su-ink-2); cursor: pointer; }
.su-agr__check input { flex: 0 0 auto; width: 22px; height: 22px; margin: 0; accent-color: #fff; }


/* ── A new portal: the headsets they already have (steps/headsets.js) ── */
.su-fleet { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.su-fleet__lede { margin: 0 0 14px; font-size: 16px; line-height: 1.4; color: var(--su-ink-2); }
.su-fleet__row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 12px; border: 0; border-radius: 16px; background: var(--su-fill); color: var(--su-ink); font: inherit; text-align: left; cursor: pointer; box-shadow: inset 0 0 0 1px var(--su-line-2); }
.su-fleet__row.is-on { box-shadow: inset 0 0 0 2px var(--su-ink); }
.su-fleet__row picture, .su-fleet__row img { flex: 0 0 auto; width: 56px; height: auto; }
.su-fleet__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.su-fleet__name { font-weight: 700; overflow-wrap: anywhere; }
.su-fleet__sub { font-size: 13px; color: var(--su-ink-3); overflow-wrap: anywhere; }
.su-fleet__mark { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; box-shadow: inset 0 0 0 2px var(--su-line); }
.su-fleet__row.is-on .su-fleet__mark { background: var(--su-ink) var(--su-check) center / 16px no-repeat; box-shadow: none; }
.su-fleet__dl { margin: 12px 0; }
.su-fleet__dlrow { display: flex; justify-content: space-between; gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--su-line-2); }
.su-fleet__dlrow dt { color: var(--su-ink-3); }
.su-fleet__dlrow dd { margin: 0; font-weight: 600; text-align: right; }
.su-fleet__ship { display: block; width: 100%; margin: 0 0 8px; }

/* /p/:code for a code we don't know (views/portal-unclaimed.ejs) */
body.su-unknown { min-height: 100dvh; height: auto; overflow: auto; display: flex; align-items: center; justify-content: center; }
.su-unknown__main { width: 100%; max-width: 440px; padding: 24px 20px calc(24px + env(safe-area-inset-bottom)); box-sizing: border-box; }
.su-unknown__main .su-brand { margin-bottom: 28px; }
.su-unknown__go { margin-top: 28px; text-decoration: none; }
.su-unknown__note { margin: 18px 0 0; text-align: center; font-size: 16px; color: var(--su-ink-3); }
.su-unknown__code { margin: 6px 0 0; text-align: center; font-size: 14px; color: var(--su-ink-4); }
