/* ============================================================
   srday-register — site-specific styles.
   Requires ds/tokens.css + ds/components.css (synced copies).
   Register's identity color: cyan (trust). Gold stays scarce.
   ============================================================ */

main.srd-wrap { padding-bottom: var(--srd-s8); }

/* register background lifted slightly off pure near-black (organizer) — a warmer,
   softer base than --srd-bg #070504 for the stepper/quiz. */
body { background: #14100c; }

.reg-view[hidden] { display: none; }

/* stack of invite cards */
/* minmax(0,…) so the nowrap invite link can't force the column past the viewport */
/* ---------- Holographic gold invite cards (like the camp specimen cards) ---------- */
.reg-invite-card {
  position: relative;
  isolation: isolate;
  border: 1px solid transparent;
  border-radius: var(--srd-radius, 14px);
  /* dark panel fill + a shifting gold foil border */
  background:
    linear-gradient(var(--srd-panel), var(--srd-panel)) padding-box,
    linear-gradient(135deg, #7a4a16, #f0b90b 28%, #ffe9a8 46%, #e8703f 66%, #8a5a1e) border-box;
  transform: perspective(760px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transform-style: preserve-3d;
  transition: transform .2s var(--srd-ease), box-shadow .2s var(--srd-ease);
  box-shadow: 0 6px 22px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,236,190,.10);
  overflow: hidden;
}
.reg-invite-card.is-tilt {
  box-shadow: 0 16px 44px rgba(0,0,0,.6), 0 0 34px rgba(240,169,60,.20), inset 0 1px 0 rgba(255,236,190,.16);
}
/* holographic foil: a slow drifting iridescent wash + a specular hotspot at the cursor */
.reg-invite-card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(130% 90% at var(--mx, 30%) var(--my, 18%), rgba(255,240,205,.30), transparent 58%),
    conic-gradient(from 210deg at 50% 50%,
      rgba(139,125,240,.12), rgba(34,184,207,.12), rgba(240,185,11,.18),
      rgba(232,112,63,.15), rgba(139,125,240,.12));
  background-size: 220% 220%, 190% 190%;
  mix-blend-mode: screen;
  opacity: .75;
  animation: holo-drift 9s linear infinite;
}
@keyframes holo-drift {
  0%   { background-position: 0% 0%,   0% 50%; }
  50%  { background-position: 100% 100%, 100% 50%; }
  100% { background-position: 0% 0%,   0% 50%; }
}
/* keep content above the foil, and float it slightly in 3D */
.reg-invite-card > * { position: relative; z-index: 1; transform: translateZ(18px); }
.reg-invite-card .srd-eyebrow { color: var(--srd-oxide-bright); }
/* Claimed = a solid, minted gold card with DARK legible ink (unclaimed stays a
   dark card with a gold foil border). Foil sheen toned down so text reads. */
.reg-invite-card.srd-card--claimed {
  background:
    linear-gradient(135deg, #f0b90b, #f0a93c 45%, #e8703f) padding-box,
    linear-gradient(135deg, #ffe9a8, #e8703f) border-box;
  color: #2a1305;
}
.reg-invite-card.srd-card--claimed::before { opacity: .28; mix-blend-mode: overlay; }
.reg-invite-card.srd-card--claimed .srd-eyebrow { color: #4a2208; }
.reg-invite-card.srd-card--claimed h4 { color: #1c0d03; }
.reg-invite-card.srd-card--claimed .srd-glyph-collect { color: #2a1305; }
.reg-invite-card.srd-card--ghost { border-style: solid; } /* foil border replaces the dashed ghost */
@media (prefers-reduced-motion: reduce) {
  .reg-invite-card { transform: none; }
  .reg-invite-card::before { animation: none; }
}

.reg-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--srd-s3); margin-top: var(--srd-s4); }
@media (min-width: 720px) { .reg-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* many-invite holders (root ≈ 50): one compact row per invite — code +
   status + copy affordance. Single column at every width; cards degrade. */
.reg-cards--compact { gap: var(--srd-s2); }
@media (min-width: 720px) { .reg-cards--compact { grid-template-columns: minmax(0, 1fr); max-width: 34rem; } }
.reg-row {
  display: flex;
  align-items: center;
  gap: var(--srd-s3);
  min-height: 44px;
  padding: var(--srd-s2) var(--srd-s3);
  border: 1px solid var(--srd-line-soft);
  border-radius: var(--srd-radius-sm);
  background: var(--srd-panel-2);
  min-width: 0;
}
.reg-row--ghost { border-style: dashed; border-color: var(--srd-line-ghost); background: none; }
.reg-row__code {
  font-family: var(--srd-font-mono);
  font-size: 0.75rem;
  color: var(--srd-ink-soft);
  flex: none;
}
.reg-row__who {
  color: var(--srd-ink);
  font-size: 0.875rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1 1 auto;
}
.reg-row__status {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
  flex: none;
  margin-left: auto;
}
.reg-row--claimed .reg-row__status { color: var(--srd-ink-soft); }
.reg-row .srd-btn--small { flex: none; }

.reg-card-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--srd-s3);
  margin-top: var(--srd-s3);
}
.reg-link {
  font-family: var(--srd-font-mono);
  font-size: 0.75rem;
  color: var(--srd-ink-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* ---------- per-invite vouch reason ("why them?") ----------
   Required on every unclaimed invite card; the copy affordance is disabled
   (dashed/locked register) until a reason is written, then attaches the vouch
   and unlocks. */
.reg-why { margin: var(--srd-s3) 0 var(--srd-s2); }
.reg-why__input { resize: vertical; min-height: 3em; line-height: var(--srd-leading-body, 1.5); }
.reg-why__locked { color: var(--srd-ink-mute); }
.reg-why__locked[hidden] { display: none; }
/* disabled copy button reads as locked (no :disabled rule in components.css) */
.srd-btn:disabled { opacity: 0.42; cursor: default; border-style: dashed; }
.srd-btn:disabled:hover { border-color: var(--srd-line); transform: none; }

/* compact holder view (Tina's ~50): the reason stacks under the code row so
   the box + lock/unlock stay usable at 390px and on desktop. */
.reg-row--why { flex-direction: column; align-items: stretch; gap: var(--srd-s2); }
.reg-row--why .reg-row__head { display: flex; align-items: center; gap: var(--srd-s3); min-height: 28px; }
.reg-row--why .reg-row__head .reg-row__status { margin-left: auto; }
.reg-row--why .reg-why__input { font-size: 1rem; }
.reg-row--why .reg-card-row { margin-top: 0; justify-content: space-between; }

/* vouch quote on the landing form */
.reg-vouch { margin-top: var(--srd-s4); }

/* form */
.reg-form { margin-top: var(--srd-s5); max-width: 30rem; }
.reg-form .srd-btn { width: 100%; margin-top: var(--srd-s2); }
.reg-error {
  color: var(--srd-red);
  font-size: 0.8125rem;
  margin-top: var(--srd-s3);
  min-height: 1.2em;
}

/* ---------- claim stepper (UX-ROUND-2 §1: one field per screen) ---------- */
#form-intro .srd-btn { margin-top: var(--srd-s5); }
#form-intro .reg-already { margin-bottom: var(--srd-s2); }

/* one serif line + one button landing (BQ2-1) */
.reg-hero { min-height: 40dvh; display: flex; flex-direction: column; justify-content: center; }
.reg-oneline {
  font-size: var(--srd-text-h1);
  line-height: var(--srd-leading-head);
  text-wrap: balance;
  max-width: 20ch;
}
.reg-oneline--mut { color: var(--srd-ink-mute); }
.reg-vouch-line {
  margin-top: var(--srd-s4);
  color: var(--srd-ink-soft);
  font-family: var(--srd-font-serif);
  font-style: italic;
}
.reg-vouch-line[hidden] { display: none; }

/* designed invite-code + pip progress chrome (BQ2-4) */
.st-chrome {
  display: flex;
  align-items: center;
  gap: var(--srd-s3);
  flex-wrap: wrap;
  margin: var(--srd-s5) 0 var(--srd-s4);
}
.st-chrome[hidden] { display: none; }
.st-chrome__code {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
  flex: none;
}
.st-chrome #form-code { color: var(--srd-cyan); }
.st-pips { display: flex; gap: 6px; flex: 1 1 auto; min-width: 60px; }
.st-pip {
  flex: 1 1 auto;
  max-width: 44px;
  height: 4px;
  border-radius: 2px;
  background: var(--srd-line-soft);
  transition: background var(--srd-dur) var(--srd-ease),
              box-shadow var(--srd-dur) var(--srd-ease);
}
.st-pip--on { background: var(--srd-oxide); }
.st-pip--now { box-shadow: 0 0 9px rgba(199, 90, 52, 0.6); }
.st-chrome__count {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  color: var(--srd-ink-soft);
  font-variant-numeric: tabular-nums;
  flex: none;
}

/* twitter.com/ prefixed handle input (BQ2-4) */
.st-prefix {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--srd-line);
  border-radius: var(--srd-radius-sm);
  background: var(--srd-panel-2);
  overflow: hidden;
  transition: border-color var(--srd-dur-fast) var(--srd-ease);
}
.st-prefix:focus-within { border-color: var(--srd-oxide); }
.st-prefix__tag {
  display: flex;
  align-items: center;
  padding: 0 2px 0 14px;
  font-family: var(--srd-font-mono);
  font-size: 1.125rem;
  color: var(--srd-ink-mute);
  white-space: nowrap;
  user-select: none;
}
.st-prefix .st-prefix__input {
  border: 0;
  background: transparent;
  border-radius: 0;
  padding-left: 2px;
  min-width: 0;
}
.st-prefix .st-prefix__input:focus { border: 0; outline: none; }

/* the juicy candy submit (BQ2-4/5): filled oxide, 3D pressable lip, gloss
   sweep, springy pop. oxide-once discipline flexes for this moment. */
.srd-btn--candy {
  position: relative;
  background: linear-gradient(180deg, var(--srd-oxide-bright), var(--srd-oxide));
  border: none;
  color: var(--srd-scene);
  box-shadow: 0 5px 0 rgba(120, 42, 20, 0.95), 0 9px 18px rgba(10, 6, 3, 0.5);
  overflow: hidden;
  transition: transform var(--srd-dur-fast) var(--srd-ease),
              box-shadow var(--srd-dur-fast) var(--srd-ease),
              filter var(--srd-dur-fast) var(--srd-ease);
}
.srd-btn--candy::after { /* gloss sweep across the top */
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 52%;
  background: linear-gradient(180deg, rgba(255, 244, 230, 0.42), rgba(255, 244, 230, 0));
  pointer-events: none;
}
.srd-btn--candy:hover {
  border: none;
  filter: brightness(1.05);
  box-shadow: 0 5px 0 rgba(120, 42, 20, 0.95), 0 12px 24px rgba(10, 6, 3, 0.55);
}
.srd-btn--candy:active {
  transform: translateY(4px);
  box-shadow: 0 1px 0 rgba(120, 42, 20, 0.95), 0 3px 8px rgba(10, 6, 3, 0.5);
}
.srd-btn--candy.is-pop { animation: srd-candy-pop 0.34s var(--srd-ease); }
@keyframes srd-candy-pop {
  0%   { transform: translateY(4px) scale(0.98); }
  55%  { transform: translateY(-2px) scale(1.03); }
  100% { transform: translateY(0) scale(1); }
}

/* ============================================================
   Active stepper = a FIXED, single-viewport frame.
   Three stable bands that land in the same place on every step and
   every viewport (390 / 768 / 1440): [ chrome | question-body | controls ].
   - Frame is a grid at min-height:100svh MINUS the sticky nav, so it
     fits on first paint and never page-scrolls a short step.
   - The question column is centered and width-capped, so the prompt sits
     in the same spot at every width.
   - The body band centers a short step and SCROLLS INTERNALLY (no page
     scroll, no top-clip) when a step is taller than the band — the tall
     match-me step stays fully reachable with controls pinned below.
   Scoped to `#view-form.stepper-live` (set by startStepper) so the
   landing / claimed / success / enrolled views stay normal scrolling pages.
   ============================================================ */

/* landing state (button, no stepper yet) keeps its calm top inset */
#view-form:not([hidden]):not(.stepper-live) { padding-top: var(--srd-s5); }

/* `.reg-hero { display:flex }` was overriding the [hidden] attribute, so the
   header/vouch block never actually hid during the stepper. Force it hidden. */
.reg-hero[hidden] { display: none; }
.st-chrome { margin-top: 0; }

.st-stage[hidden] { display: none; }
.st-stage { margin-top: var(--srd-s6); max-width: 32rem; width: 100%; }

/* --- the frame -------------------------------------------------- */
/* --nav-h is refined at runtime (index.js measures the sticky nav);
   this fallback keeps the math close before/without JS. */
:root { --st-nav-h: 56px; --st-col-max: 34rem; }

/* zero the wrap's bottom padding while the frame owns the viewport, else a
   short step page-scrolls by 72px. */
main.srd-wrap:has(#view-form.stepper-live:not([hidden])) { padding-bottom: 0; }

/* [hidden] MUST win over the frame's display:grid (id+class beats .reg-view[hidden]),
   else the form stays framed after claim and the success view renders BELOW it. */
#view-form.stepper-live[hidden] { display: none; }
#view-form.stepper-live {
  display: grid;
  grid-template-rows: auto 1fr;            /* chrome | form(body+footer) */
  box-sizing: border-box;
  width: 100%;
  max-width: var(--st-col-max);            /* consistent question measure */
  margin-inline: auto;                     /* column centered in the wrap */
  padding-top: var(--srd-s5);
  padding-bottom: env(safe-area-inset-bottom);
  /* The frame is LOCKED to the visible viewport height (minus the sticky nav)
     so the PAGE never scrolls — a tall step scrolls the body band instead, and
     the controls stay pinned. --st-frame-h is measured in JS from
     visualViewport (exact on every device, and it shrinks with the on-screen
     keyboard so the controls ride above it). svh is the pre-JS fallback; since
     the stepper only appears after a JS-driven click, JS has always set the
     exact height by the time it shows. */
  height: 100vh;                                        /* oldest fallback */
  height: calc(100svh - var(--st-nav-h));               /* pre-JS fallback */
  height: var(--st-frame-h, calc(100svh - var(--st-nav-h)));
}

/* chrome — row 1, pinned at the top */
#view-form.stepper-live .st-chrome { margin: 0 0 var(--srd-s4); }

/* the form fills row 2 and splits into [ body | footer ] */
#view-form.stepper-live .st-stage {
  min-height: 0;                           /* let the 1fr row shrink to scroll */
  margin: 0;
  max-width: none;
  width: 100%;
  display: grid;
  grid-template-rows: 1fr auto;            /* body | footer(error+controls) */
}

/* body band — centers a short step, scrolls a tall one with NO top clip.
   flex column + margin-block:auto is the widest-support centering that
   collapses to 0 on overflow (avoids the flex/grid center scroll-trap). */
#view-form.stepper-live .st-body {
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  display: flex;
  flex-direction: column;
  padding-block: var(--srd-s2);
}
#view-form.stepper-live .st-step {
  scroll-margin-top: calc(var(--st-nav-h) + var(--srd-s4));
}
#view-form.stepper-live .st-step.on {
  margin-block: auto;                      /* center on slack, collapse on overflow */
}

/* footer — row 2 of the form. Lifted ~16% of the screen off the bottom so the
   back/next controls don't sit against the edge (organizer). */
#view-form.stepper-live .st-foot { padding-top: var(--srd-s3); padding-bottom: 16dvh; }
#view-form.stepper-live #st-error { margin-top: 0; }
#view-form.stepper-live .st-controls { margin-top: var(--srd-s2); }
.st-step { display: none; }
.st-step.on {
  display: block;
  animation: srd-recompose-block var(--srd-dur) var(--srd-ease) both;
}
.st-step.leaving { animation: st-decompose var(--srd-dur-fast) var(--srd-ease) both; }
@keyframes st-decompose {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-10px) rotate(1.2deg); }
}

.st-prompt { font-size: var(--srd-text-h2); margin-bottom: var(--srd-s5); text-wrap: balance; }

/* the one input in focus gets bigger type (stays >= 1rem for iOS) */
.st-stage .srd-field__input,
.st-stage .srd-field textarea { font-size: 1.125rem; }
.st-stage .srd-field { margin-bottom: var(--srd-s3); }

/* affiliation: five big tappable rows — picking one advances */
.st-opts { border: 0; padding: 0; margin: 0; display: grid; gap: var(--srd-s2); }
.st-opts legend { padding: 0; margin-bottom: var(--srd-s2); }
.st-opt { position: relative; }
.st-opt input { position: absolute; opacity: 0; pointer-events: none; }
.st-opt span {
  display: flex;
  align-items: center;
  min-height: 52px;
  padding: 0 var(--srd-s4);
  border: 1px solid var(--srd-line-soft);
  border-radius: var(--srd-radius-sm);
  font-size: 1.0625rem;
  color: var(--srd-ink-soft);
  cursor: pointer;
  transition: border-color var(--srd-dur-fast) var(--srd-ease),
              color var(--srd-dur-fast) var(--srd-ease),
              background-color var(--srd-dur-fast) var(--srd-ease);
}
.st-opt span:hover { border-color: var(--srd-line); }
.st-opt input:checked + span {
  border-color: var(--srd-oxide);
  color: var(--srd-ink);
  background: rgba(199, 90, 52, 0.12); /* subtle warm fill under the oxide ring */
}
.st-opt input:focus-visible + span { outline: 2px solid var(--srd-oxide); outline-offset: 2px; }

.st-controls { display: flex; gap: var(--srd-s3); align-items: center; margin-top: var(--srd-s6); }
.st-controls #st-next { flex: 1 1 auto; }
.st-controls #st-back { flex: 0 0 auto; }
.st-controls #st-back:disabled { opacity: 0.4; cursor: default; }
#st-error { margin-top: var(--srd-s4); min-height: 1.2em; }

/* login-by-invite-code (form rendered by srd.js mountLogin) */
.srd-login { display: grid; gap: var(--srd-s3); margin-top: var(--srd-s4); text-align: left; }
.srd-login .srd-btn { width: 100%; }
.srd-login [data-login-error] { color: var(--srd-ink-soft); }

/* ---------- match-me: optional post-claim signals ---------- */
/* selected chips ring in rust oxide + a subtle warm fill (organizer override
   2026-07-19: many oxide chips + the oxide claim CTA on one screen is fine —
   the CTA stays the loudest oxide). never dashed (dashed = unclaimed/locked;
   an unchecked option is neither). */
.mm-group { border: 0; padding: 0; margin: var(--srd-s4) 0 0; }
.mm-group legend { padding: 0; margin-bottom: var(--srd-s2); }
.mm-choices { display: flex; flex-wrap: wrap; gap: var(--srd-s2); }
.mm-chip { position: relative; }
.mm-chip input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.mm-chip span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--srd-s4);
  border: 1px solid var(--srd-line-soft);
  border-radius: 999px;
  font-size: 0.875rem;
  color: var(--srd-ink-soft);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.mm-chip span:hover { border-color: var(--srd-line); }
.mm-chip input:checked + span {
  border-color: var(--srd-oxide);
  color: var(--srd-ink);
  background: rgba(199, 90, 52, 0.12);
}
.mm-chip input:focus-visible + span { outline: 2px solid var(--srd-oxide); outline-offset: 2px; }
.mm-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--srd-s3);
  align-items: center;
  margin-top: var(--srd-s5);
}
#matchme-error { min-height: 0; }

/* ticket */
.reg-ticket-wrap { margin-top: var(--srd-s4); }

/* ---------- the personal figure (ds/shape.js) ----------
   Ticket: a static composed frame behind the QR — the opaque bone QR square
   covers the dense center, only the wireframe rim peeks around it, so the
   scan stays clean and the amber label/name keep their contrast.
   Unsorted (no shapeSeed yet): the cohort default figure, ghosted — the
   figure is absent until the hat speaks (on-lore dashed/absent register). */
/* The ticket centerpiece is the big personal figure (QR removed 2026-07-20). */
.reg-shape-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: var(--srd-s3) auto var(--srd-s2);
  min-height: 260px;
}
.reg-ticket-shape {
  display: block;
  width: 260px;
  height: 260px;
  max-width: 72vw;
  pointer-events: none;
}
.reg-shape--unsorted { opacity: 0.4; }

/* Baked camp-specimen figure (specimen context rule: tickets + small glyphs =
   bakeSpecimen() PNGs). The bake carries the camp's near-black backdrop, so a
   radial mask feathers the square edge into the surface behind it; opacity
   comes from the base classes above, so the opaque bone QR square still wins
   the scan. */
.reg-shape--baked {
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 55%, transparent 74%);
  mask-image: radial-gradient(circle at 50% 50%, #000 55%, transparent 74%);
}
/* On the ticket the bone QR square covers a 208px figure's dense center
   entirely — the baked specimen sizes up so its geometry actually peeks
   around the QR, and runs less ghosted than the wireframe (its own near-black
   backdrop keeps it quiet; the opaque QR square still wins the scan). The
   ticket's label + name lift above the overflowing figure so type stays
   crisp. */
.reg-ticket-shape.reg-shape--baked {
  width: 260px;
  height: 260px;
  max-width: 72vw;
  opacity: 1;
}
.srd-ticket .srd-ticket__label,
.srd-ticket .srd-ticket__name { position: relative; z-index: 1; }

/* Success header: a small figure above the headline (living ghost when
   unsorted; baked camp specimen once sorted). */
.reg-success-shape {
  display: block;
  width: 92px;
  height: 92px;
  margin-bottom: var(--srd-s3);
  pointer-events: none;
}

/* post-claim next-step row */
.reg-next-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--srd-s3);
  align-items: center;
  margin-top: var(--srd-s3);
}

/* ---------- trust graph (indented tree; legible at 390px) ---------- */
.tg { margin-top: var(--srd-s4); }
.tg-meta {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
  margin-bottom: var(--srd-s3);
}
.tg-branch { border-left: 1px solid var(--srd-line-soft); margin-left: 7px; padding-left: 12px; }
.tg-root > .tg-branch, .tg > .tg-branch { border-left: 0; margin-left: 0; padding-left: 0; }
.tg-node {
  display: flex;
  align-items: baseline;
  gap: var(--srd-s2);
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 7px 0;
  cursor: pointer;
  font-family: var(--srd-font-ui);
  font-size: var(--srd-text-body);
  color: var(--srd-ink-soft);
  min-height: 34px;
}
.tg-node:hover .tg-name { color: var(--srd-ink); }
.tg-glyph { color: var(--srd-cyan); font-size: 0.6875rem; flex: none; }
.tg-name { color: var(--srd-ink); }
.tg-aff {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
  flex: none;
}
.tg-detail {
  margin: 0 0 var(--srd-s3);
  padding: var(--srd-s3) var(--srd-s4);
  border-radius: var(--srd-radius-sm);
  background: var(--srd-panel-2);
  border: 1px solid var(--srd-line-soft);
  font-size: 0.875rem;
  color: var(--srd-ink-soft);
}
.tg-detail .srd-testimony { margin-top: var(--srd-s1); }
.tg-empty { color: var(--srd-ink-mute); }

/* ---------- door ---------- */
.door-search { max-width: 30rem; }
.door-list { display: grid; gap: var(--srd-s2); margin-top: var(--srd-s4); }
.door-row {
  display: flex;
  align-items: baseline;
  gap: var(--srd-s3);
  padding: var(--srd-s3) var(--srd-s4);
  border-radius: var(--srd-radius-sm);
  border: 1px solid var(--srd-line-soft);
  background: var(--srd-panel-2);
  cursor: pointer;
}
.door-row:hover { border-color: var(--srd-line); }
.door-row .tg-name { flex: 1 1 auto; min-width: 0; }
.door-status {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-cyan);
  flex: none;
}
.door-big { max-width: 26rem; margin-top: var(--srd-s5); text-align: center; }
.door-big .door-name { font-size: var(--srd-text-h2); color: var(--srd-ink); line-height: var(--srd-leading-head); }
.door-big .srd-glyph-collect { font-size: 1.75rem; display: block; margin-bottom: var(--srd-s3); }
.door-vouch { margin-top: var(--srd-s3); color: var(--srd-ink-mute); font-size: 0.875rem; }

/* ---------- reason-on-click invite card (BQ2-6) ----------
   One "copy link" button; clicking asks for a PRIVATE reason, which posts and
   then reveals + copies the link. The reason is never shown to anyone else. */
.reg-invite { margin-top: var(--srd-s3); }
.reg-invite__row { display: flex; align-items: center; gap: var(--srd-s3); flex-wrap: wrap; }
.reg-invite__edit {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
}
.reg-invite__edit:hover { color: var(--srd-ink-soft); }
.reg-invite__edit[hidden] { display: none; }
.reg-invite__ask { margin-top: var(--srd-s3); }
.reg-invite__ask[hidden] { display: none; }
.reg-invite__ask .srd-field { margin-bottom: var(--srd-s2); }
.reg-invite__input { resize: vertical; min-height: 3em; line-height: var(--srd-leading-body); }
.reg-invite__ask-row { display: flex; }
.reg-invite__out { margin-top: var(--srd-s3); }
.reg-invite__out[hidden] { display: none; }
.reg-invite__out .reg-link { display: block; }

/* quota-aware "your N invites" label (BQ2-2/5) */
.reg-invites-label {
  font-family: var(--srd-font-serif);
  font-size: var(--srd-text-h3);
  color: var(--srd-ink);
  margin-top: var(--srd-s6);
}

/* fly-in micro-motion on the minted cards (decompose/recompose language) */
.reg-flyin { animation: reg-flyin var(--srd-dur) var(--srd-ease) both; animation-delay: calc(var(--i, 0) * 70ms); }
@keyframes reg-flyin {
  from { opacity: 0; transform: translateY(12px) rotate(-1.4deg); }
  to   { opacity: 1; transform: translateY(0) rotate(0deg); }
}

/* success view: heading -> label -> cards -> one juicy ticket button */
.reg-success-cta { margin-top: var(--srd-s6); }
.reg-success-cta .srd-btn { min-width: 11rem; }

/* ---------- the ticket page (BQ2-9) ---------- */
.reg-ticket-warn {
  margin: var(--srd-s5) 0 0;
  padding: 10px 14px;
  border-radius: var(--srd-radius-sm);
  border: 1px solid var(--srd-line-soft);
  background: var(--srd-panel-2);
  color: var(--srd-ink-soft);
  font-size: 0.875rem;
  max-width: 34rem;
}
.reg-mine-head { padding-top: var(--srd-s5); }

.reg-when { margin-top: var(--srd-s5); max-width: 34rem; display: grid; gap: var(--srd-s3); }
.reg-when[hidden] { display: none; }
.reg-when__row { display: flex; gap: var(--srd-s3); align-items: baseline; }
.reg-when__k {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
  flex: 0 0 3.5rem;
}
.reg-when__v { color: var(--srd-ink); font-size: 0.9375rem; }
.reg-when__map {
  display: inline-block;
  margin-left: var(--srd-s2);
  color: var(--srd-cyan);
  font-size: 0.8125rem;
  text-decoration: none;
  white-space: nowrap;
}
.reg-when__map[hidden] { display: none; }
.reg-when__map:hover { text-decoration: underline; }
.reg-cal { display: flex; flex-wrap: wrap; gap: var(--srd-s2); margin-top: var(--srd-s1); }

/* trust graph section head on the ticket page */
.reg-graph-head { font-size: var(--srd-text-h3); margin-top: var(--srd-s7); }
.reg-graph-sub { margin-top: var(--srd-s2); }

/* transient confetti canvas (juice.js) */
.reg-confetti { position: fixed; inset: 0; pointer-events: none; z-index: 120; }

/* ============================================================
   Enrolled ticket view — the payoff screen fits ONE viewport.
   Same discipline as the stepper frame: the section fills the visible
   viewport MINUS the sticky nav (--mine-frame-h, measured in js/invite.js
   from visualViewport; svh/dvh is the pre-JS fallback), and the tall stack
   is recomposed to sit inside it. Overflow stays VISIBLE (not clipped): the
   only thing that grows past the frame is the reason-on-click textarea, and a
   brief scroll during that interaction is fine.
   Scoped to `.reg-mine--fit`, added by invite.js ONLY for the ≤6-invite
   big-card holder. The ~50-invite compact holder never gets the class, so it
   stays a normal scrolling page.
   ============================================================ */
:root { --mine-nav-h: 56px; }

/* zero the wrap's bottom padding while the fit view owns the viewport, else the
   72px inset page-scrolls a stack that otherwise fits. */
main.srd-wrap:has(#view-mine.reg-mine--fit) { padding-bottom: 0; }

/* MOBILE (default): a tight centered stack — smaller shape, compact spacing,
   the invites in a 3-across row. */
#view-mine.reg-mine--fit {
  box-sizing: border-box;
  min-height: var(--mine-frame-h, calc(100svh - var(--mine-nav-h)));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--srd-s2);
  padding-block: var(--srd-s2);
}
/* collapse the stock section insets — the frame owns the rhythm now */
.reg-mine--fit .reg-ticket-warn { margin: 0; max-width: none; }
.reg-mine--fit .srd-section-head.reg-mine-head { padding: 0; }
.reg-mine--fit .reg-ticket-wrap { margin: 0; }
.reg-mine--fit .reg-when { margin: 0; max-width: none; gap: var(--srd-s2); }
.reg-mine--fit .reg-invites-label { margin: 0; }
.reg-mine--fit .reg-cards { margin-top: 0; }

/* heading held to two tight lines so the stack clears 390x844 */
.reg-mine--fit .srd-section-head h1 { font-size: clamp(1.35rem, 5vw, 1.75rem); }

/* the shape ticket, shrunk — still the centerpiece, just sized to the frame */
.reg-mine--fit .srd-ticket {
  max-width: none;
  padding: var(--srd-s2) var(--srd-s4);
  gap: var(--srd-s1);
}
.reg-mine--fit .reg-shape-stage { min-height: 0; margin: 0 auto; }
.reg-mine--fit .reg-ticket-shape,
.reg-mine--fit .reg-ticket-shape.reg-shape--baked {
  width: 118px;
  height: 118px;
  max-width: 40vw;
}
.reg-mine--fit .srd-ticket__tear { margin: var(--srd-s1) 0; }

/* invites 3-across; the holo card stays, just tightened to the cell */
.reg-mine--fit .reg-cards {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--srd-s2);
}
.reg-mine--fit .reg-invite-card { padding: var(--srd-s3); }
.reg-mine--fit .reg-invites-label { font-size: var(--srd-text-lead); }

/* DESKTOP + tablet: two columns — the ticket stands on the left, the heading,
   event details and invite cards stack on the right, so the tall page becomes a
   balanced screen. */
@media (min-width: 720px) {
  #view-mine.reg-mine--fit {
    display: grid;
    grid-template-columns: minmax(240px, 22rem) minmax(0, 1fr);
    grid-template-rows: auto auto auto auto auto;
    grid-template-areas:
      "warn   warn"
      "ticket head"
      "ticket when"
      "ticket label"
      "ticket cards";
    column-gap: var(--srd-s7);
    row-gap: var(--srd-s4);
    align-content: center;
    justify-content: center;
  }
  .reg-mine--fit .reg-ticket-warn { grid-area: warn; max-width: 46rem; }
  .reg-mine--fit .srd-section-head { grid-area: head; align-self: end; }
  .reg-mine--fit .reg-ticket-wrap { grid-area: ticket; align-self: center; }
  .reg-mine--fit .reg-when { grid-area: when; }
  .reg-mine--fit .reg-invites-label { grid-area: label; }
  .reg-mine--fit .reg-cards { grid-area: cards; align-self: start; }

  .reg-mine--fit .srd-section-head h1 { font-size: var(--srd-text-h2); }
  .reg-mine--fit .reg-ticket-shape,
  .reg-mine--fit .reg-ticket-shape.reg-shape--baked {
    width: 208px;
    height: 208px;
    max-width: 100%;
  }
  .reg-mine--fit .srd-ticket { padding: var(--srd-s5) var(--srd-s5) var(--srd-s4); }
  .reg-mine--fit .reg-invites-label { font-size: var(--srd-text-h3); }
}

/* utility */
.reg-mut { color: var(--srd-ink-mute); }
.reg-asof {
  font-family: var(--srd-font-mono);
  font-size: var(--srd-text-micro);
  letter-spacing: var(--srd-track-label);
  text-transform: uppercase;
  color: var(--srd-ink-mute);
}
