/* STEP•WIZE × HALLOWEEBS — BATTLE ROYAL. EC2A.  (REVISION 02) */

@font-face { font-family: 'Anton'; src: url('assets/fonts/Anton-Regular.ttf') format('truetype'); font-weight: 400; font-display: block; }
@font-face { font-family: 'Space Mono'; src: url('assets/fonts/SpaceMono-Regular.ttf') format('truetype'); font-weight: 400; font-display: block; }
@font-face { font-family: 'Space Mono'; src: url('assets/fonts/SpaceMono-Bold.ttf') format('truetype'); font-weight: 700; font-display: block; }

:root {
  --bg: #030000;
  --red: #ff1b1b;
  --red-deep: #b01010;
  --red-line: rgba(255, 27, 27, 0.55);
  --red-faint: rgba(255, 27, 27, 0.22);
  --red-glow: rgba(255, 27, 27, 0.45);
  --bone: #e8e2d4;
  --bone-dim: rgba(232, 226, 212, 0.74);   /* small labels: lifted slightly for legibility */
  --autofill-bg: #0b0202;                   /* autofilled inputs stay on the palette */
  --track: #170404;
  --mono: 'Space Mono', ui-monospace, Menlo, Consolas, monospace;
  --display: 'Anton', Impact, 'Arial Narrow', sans-serif;

  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);

  /* usable content height = dynamic viewport minus safe areas + shell margins.
     All vertical rhythm derives from this single value, so the layout responds to
     available height (toolbars + safe areas) without double-subtracting. */
  --shell-y: 26px;
  --avail: calc(100vh - var(--sat) - var(--sab) - var(--shell-y));
  --avail: calc(100dvh - var(--sat) - var(--sab) - var(--shell-y));
  --row-h: clamp(38px, calc(var(--avail) * 0.065), 70px);
  --pct-size: clamp(42px, calc(var(--avail) * 0.083), 92px);
  --gauge: clamp(50px, calc(var(--avail) * 0.096), 110px);
  --exec-h: clamp(40px, calc(var(--avail) * 0.058), 58px);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; background: var(--bg); color: var(--bone); }
body { font-family: var(--mono); -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; }
button { font: inherit; color: inherit; }
img { display: block; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* hide everything until fonts are ready — prevents a one-frame fallback-font flash before the FLIP measurement */
body.is-booting .terminal { visibility: hidden; }

/* ---------------------------------------------------------------- app shell */
.app {
  position: relative;
  height: 100vh;
  height: 100dvh;
  padding: calc(14px + var(--sat)) calc(14px + var(--sar)) calc(12px + var(--sab)) calc(14px + var(--sal));
  display: flex;
  align-items: stretch;
  justify-content: center;
}

/* ---------------------------------------------------------------- interference layer (contained in the header) */
/* .head-bg is the red band. In the terminal state it is an absolutely positioned child of .head that
   spans the header (out to the terminal frame) and CLIPS its contents, so the texture is bounded by the
   header's own box — it moves with the header and cannot extend past the divider. The video/static layers
   inside stay viewport-sized and are offset by (--vx, --vy) so the texture reads as a slice of the same
   full-bleed signal; JS keeps those offsets fresh, but they only affect alignment, never containment. */
.head-bg {
  position: absolute; inset: 0 -14px; z-index: -1;
  overflow: hidden; pointer-events: none;
}
.head-bg > * {
  position: absolute;
  left: var(--vx, 0px); top: var(--vy, 0px);
  width: var(--vw, 100vw); height: var(--vh, 100vh);
}
.interference {
  object-fit: cover;
  mix-blend-mode: screen;
  pointer-events: none;
  opacity: 0.16;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,.9), rgba(0,0,0,.9) 60%, transparent);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,.9), rgba(0,0,0,.9) 60%, transparent);
}
/* never a native play glyph over the opening (iOS shows one when autoplay is blocked) */
.interference::-webkit-media-controls,
.interference::-webkit-media-controls-start-playback-button,
.interference::-webkit-media-controls-overlay-play-button,
.interference::-webkit-media-controls-panel { display: none !important; -webkit-appearance: none; opacity: 0 !important; }
/* silhouette video: same treatment — never a native play glyph when autoplay is blocked */
.sil::-webkit-media-controls,
.sil::-webkit-media-controls-start-playback-button,
.sil::-webkit-media-controls-overlay-play-button,
.sil::-webkit-media-controls-panel { display: none !important; -webkit-appearance: none; opacity: 0 !important; }
/* static fallback: CSS texture that stands in for the video when playback is unavailable */
.static {
  pointer-events: none; display: none;
  mix-blend-mode: screen; opacity: 0.16;
  background:
    repeating-linear-gradient(to bottom, rgba(255,27,27,.55) 0 1px, transparent 1px 3px, rgba(255,27,27,.18) 3px 4px, transparent 4px 7px),
    repeating-linear-gradient(to right, rgba(255,27,27,.12) 0 2px, transparent 2px 9px, rgba(255,27,27,.3) 9px 10px, transparent 10px 23px),
    radial-gradient(ellipse at 50% 40%, rgba(255,27,27,.7), rgba(120,8,8,.5) 55%, rgba(3,0,0,0) 100%);
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,.9), rgba(0,0,0,.9) 60%, transparent);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,.9), rgba(0,0,0,.9) 60%, transparent);
}
.app.is-video-fallback .interference { display: none; }
.app.is-video-fallback .static { display: block; }
.app.is-video-fallback.is-intro .static {
  opacity: .3; clip-path: inset(0);
  -webkit-mask-image: linear-gradient(to bottom, transparent, rgba(0,0,0,1) 18%, rgba(0,0,0,1) 82%, transparent);
          mask-image: linear-gradient(to bottom, transparent, rgba(0,0,0,1) 18%, rgba(0,0,0,1) 82%, transparent);
  animation: static-flicker 1.1s steps(2, end) infinite;
}
@keyframes static-flicker { 0% { opacity: .22; } 50% { opacity: .34; } 100% { opacity: .22; } }
.veil {
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 45%, transparent 35%, rgba(3,0,0,.85) 100%);
  opacity: 0;
}

/* ---------------------------------------------------------------- desktop background (animated imagery behind the terminal) */
.bg-persist {
  position: fixed; inset: 0; z-index: 0;
  display: none; opacity: 0; overflow: hidden; pointer-events: none;
  transition: opacity .7s ease;
}
.bp-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  pointer-events: none;
}
.bp-video::-webkit-media-controls,
.bp-video::-webkit-media-controls-start-playback-button,
.bp-video::-webkit-media-controls-overlay-play-button,
.bp-video::-webkit-media-controls-panel { display: none !important; -webkit-appearance: none; opacity: 0 !important; }
.bp-veil {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 45%, rgba(3,0,0,.3) 0%, rgba(3,0,0,.72) 100%);
}
@media (min-width: 900px) {
  .bg-persist { display: block; }
}
.app.is-persist .bg-persist { opacity: 1; }

/* ---------------------------------------------------- opening scene (blended intro figures)
   .scene is a viewport-sized child of .head-bg (sized by the same rules as the videos) and only
   exists during the opening. It paints BENEATH the interference video, which screen-blends over
   it, so the animated figure motion reads through the signal. --sil-pos is the crop anchor: the
   source is landscape, so portrait viewports anchor on the centre figure (~31% across). */
.scene { display: none; pointer-events: none; overflow: hidden; --sil-pos: 31% 50%; }
.app.is-intro .scene, .app.is-intro-geometry .scene { display: block; }
.sil-wrap {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0;                                   /* revealed by the opening animation */
  will-change: opacity;
}
.sil {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--sil-pos);
  opacity: 0;                                   /* hidden until playback is confirmed (opacity also hides any native play glyph) */
  transition: opacity 0.35s ease;
}
.sil-still {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--sil-pos);
  animation: sil-drift 8s ease-in-out infinite alternate;
}
@keyframes sil-drift {
  from { transform: scale(1); }
  to   { transform: scale(1.08); }
}
.app.is-sil-playing .sil { opacity: 1; }
.app.is-sil-playing .sil-still { opacity: 0; }
/* restrained LOCAL darkening behind the identity so the red HALLOWEEBS wordmark reads on the red field.
   Centred where the identity sits; the rest of the picture keeps its colour. */
.scrim {
  position: absolute; inset: 0; opacity: 0;
  --scrim-pos: 50% 50%;
  background:
    radial-gradient(ellipse 72% 34% at var(--scrim-pos), rgba(3,0,0,.82) 0%, rgba(3,0,0,.66) 38%, rgba(3,0,0,.3) 68%, rgba(3,0,0,0) 100%);
}
@media (min-width: 900px) {
  .scene { --sil-pos: 50% 50%; }
  .scrim { --scrim-pos: 46% 54%; background: radial-gradient(ellipse 36% 38% at var(--scrim-pos), rgba(3,0,0,.82) 0%, rgba(3,0,0,.66) 40%, rgba(3,0,0,.3) 70%, rgba(3,0,0,0) 100%); }
}
@media (prefers-reduced-motion: reduce) {
  .bp-video { display: none; }
  .bg-persist { background: url(assets/intro-silhouette.jpg) center / cover no-repeat; }
}

/* ---------------------------------------------------------------- terminal frame */
.terminal {
  position: relative; z-index: 1;
  width: 100%;
  display: flex; flex-direction: column;
  border: 1px solid var(--red);                     /* sharp, thin framing */
  padding: 0 14px;
  background: var(--bg);                            /* opaque: desktop background shows only around it */
}
/* corner ticks, like the reference frame */
.terminal::before, .terminal::after {
  content: ''; position: absolute; width: 9px; height: 9px; pointer-events: none;
  border-color: var(--red); border-style: solid;
}
.terminal::before { top: -1px; left: -1px; border-width: 2px 0 0 2px; }
.terminal::after  { bottom: -1px; right: -1px; border-width: 0 2px 2px 0; }

/* ---------------------------------------------------------------- header (compact identity) */
.head {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 0 8px;
  border-bottom: 1px solid var(--red-line);
  min-height: 50px;
}
/* faint, selective scanlines live on the header band only */
.head::after {
  content: ''; position: absolute; inset: 0 -14px 0 -14px; pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(255,255,255,0.035) 0 1px, transparent 1px 3px);
  opacity: 0.6;
}
.identity { display: flex; align-items: center; gap: 12px; min-width: 0; }
.logos { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; flex: 0 0 auto; }
.logo { height: auto; }
.logo.stepwize  { width: 82px; }
.logo.hallowebs { width: 100px; }
.logos-x { display: none; color: var(--red); font-family: var(--display); font-size: 16px; line-height: 1; }
.event { display: flex; flex-direction: column; align-items: flex-start; line-height: 1; min-width: 0; flex: 1 1 auto; }
.event-title {
  font-family: var(--display); font-weight: 400; text-transform: uppercase;
  font-size: 27px; line-height: 0.92; letter-spacing: 0.01em;
  color: var(--bone); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.event-loc {
  margin-top: 4px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em; text-indent: 0.16em;
  color: var(--red); white-space: nowrap;
}
/* ---------------------------------------------------------------- sponsor credit (BACARDÍ) */
/* intro: text credit, centred under the identity title card (kept as text) */
.sponsor { display: none; }
.app.is-intro .sponsor,
.app.is-intro-geometry .sponsor {
  display: block;
  font-family: var(--mono);
  font-size: clamp(12px, 1.7vh, 16px);
  letter-spacing: 0.32em; text-indent: 0.32em;
  color: var(--bone);
  text-align: center;
}

/* event identity header: Bacardí sponsor mark pinned to the end (far right) */
.bacardi-end { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 0 0 auto; }
.logos-sep { width: 1px; height: 22px; flex-shrink: 0; background: rgba(232, 226, 212, 0.45); }
.logo.bacardi { height: 24px; width: auto; }
.app.is-intro .logo.bacardi,
.app.is-intro-geometry .logo.bacardi,
.app.is-intro .logos-sep,
.app.is-intro-geometry .logos-sep { display: none; }
@media (min-width: 900px) {
  .logos-sep { height: 26px; }
  .logo.bacardi { height: 28px; }
}

/* ---------------------------------------------------------------- stage */
.stage {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  gap: clamp(6px, 1.4vh, 18px);
  padding-top: clamp(6px, 1.4vh, 18px);
  /* if the available height (short phones, Safari toolbars, enlarged text) can't hold
     every section, scroll instead of overlapping the blockers / status panels */
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.panel { position: relative; min-width: 0; }
.panel-blockers { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
.panel-status { margin-top: auto; }

/* system heading — compact system type, does not compete with the event title */
.sys-title {
  font-family: var(--mono); font-weight: 700;
  font-size: 12px; letter-spacing: 0.22em; color: var(--red);
}
.caret { animation: caret 1.1s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
.sys-sub { margin-top: 4px; font-size: 11px; letter-spacing: 0.02em; color: var(--bone-dim); }

/* slots — fixed height, never collapse */
.slots { list-style: none; margin-top: clamp(6px, 1.6vh, 20px); border-top: 1px solid var(--red-line); }
.slot {
  position: relative;
  height: var(--row-h);
  border-bottom: 1px solid var(--red-faint);
}
.slot:last-child { border-bottom-color: var(--red-line); }
.slot-body {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.slot-label {
  font-size: 13px; letter-spacing: 0.04em; color: var(--bone);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.slot-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.del {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--red); background: transparent;
  border: 1px solid var(--red); padding: 0 12px;
  height: 30px; cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.del:hover, .del:focus-visible { background: var(--red); color: var(--bg); outline: none; }
.del-x {
  font-family: var(--mono); font-size: 16px; line-height: 1; color: var(--red);
  background: transparent; border: 1px solid var(--red-line);
  width: 30px; height: 30px; cursor: pointer; padding: 0;
  transition: border-color .12s ease, color .12s ease;
}
.del-x:hover, .del-x:focus-visible { border-color: var(--red); color: var(--bone); outline: none; }

/* cleared trace */
.slot-trace {
  position: absolute; inset: 0;
  display: flex; align-items: center;
  font-size: 10px; letter-spacing: 0.3em; color: var(--red);
  opacity: 0; pointer-events: none;
}
.slot-trace::after {
  content: ''; flex: 1; margin-left: 14px; height: 0;
  border-top: 1px dashed var(--red-faint);
}

/* localised disruption on delete */
.slot.is-clearing .slot-body { animation: slot-glitch .26s steps(1, end) forwards; }
.slot.is-clearing::before {
  content: ''; position: absolute; inset: 0 -14px; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,27,27,.55) 30%, rgba(255,27,27,.2) 60%, transparent);
  animation: slot-band .26s steps(1, end) forwards;
}
@keyframes slot-glitch {
  0%   { transform: translateX(-3px); clip-path: inset(0 0 52% 0); filter: brightness(2.4); }
  25%  { transform: translateX(4px);  clip-path: inset(42% 0 0 0); }
  50%  { transform: translateX(-2px); clip-path: inset(18% 0 34% 0); opacity: .9; }
  75%  { transform: translateX(1px);  clip-path: inset(0 0 0 0); opacity: .35; }
  100% { opacity: 0; visibility: hidden; }
}
@keyframes slot-band {
  0% { opacity: .9; transform: translateX(-40%); }
  40% { opacity: .5; transform: translateX(20%); }
  70% { opacity: .25; transform: translateX(45%); }
  100% { opacity: 0; }
}
.slot.is-cleared .slot-body { visibility: hidden; opacity: 0; }
.slot.is-cleared .slot-trace { opacity: .5; transition: opacity .3s ease .05s; }

/* ---------------------------------------------------------------- status */
.rate-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.rate-label { font-weight: 700; font-size: 12px; letter-spacing: 0.24em; color: var(--red); }
.rate-note { font-size: 10px; letter-spacing: 0.04em; color: var(--bone-dim); }
.rate-how { margin-top: 4px; font-size: 11px; letter-spacing: 0.02em; color: var(--bone-dim); }
.rate { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 4px; }
.rate-num {
  font-family: var(--display); font-weight: 400;
  font-size: var(--pct-size); line-height: 0.95; color: var(--red);
  font-variant-numeric: tabular-nums;
}
.pct-sym { font-size: 0.5em; margin-left: 0.04em; }
.gauge { width: var(--gauge); height: var(--gauge); flex-shrink: 0; }
.gauge-track { fill: none; stroke: var(--track); stroke-width: 20; }
.gauge-fill {
  fill: none; stroke: var(--red); stroke-width: 20; stroke-linecap: butt;
  transform: rotate(-90deg); transform-origin: 60px 60px;
}
.gauge-tick { stroke: var(--bone); stroke-width: 1.5; opacity: .55; }

.exec-wrap { margin-top: clamp(8px, 1.4vh, 16px); }
.state-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.state { display: block; font-size: 10px; letter-spacing: 0.3em; color: var(--red); }
.state-unlocked { color: var(--bone); text-align: right; letter-spacing: .22em; }
.state-unlocked[hidden] { display: none; }
.execute {
  display: block; width: 100%; height: var(--exec-h);
  font-family: var(--mono); font-weight: 700; font-size: 17px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--red); background: transparent;
  border: 1px solid var(--red);
  cursor: pointer;
  transition: background .15s ease, color .15s ease, box-shadow .25s ease, border-color .15s ease;
}
/* inactive: readable, clearly not live */
.execute:disabled {
  cursor: not-allowed;
  color: rgba(255,27,27,.55);
  border-color: rgba(255,27,27,.4);
  border-style: dashed;
}
/* armed: strong, unmistakable active control — glow is reserved for this */
.execute.is-armed:not(:disabled) {
  background: var(--red); color: var(--bg); border-color: var(--red);
  box-shadow: 0 0 22px var(--red-glow);
  animation: arm .6s cubic-bezier(.2,.9,.3,1.2) 1;
}
.execute.is-armed:not(:disabled):hover, .execute.is-armed:not(:disabled):focus-visible {
  background: var(--bone); color: var(--bg); border-color: var(--bone); outline: none;
  box-shadow: 0 0 26px rgba(232,226,212,.35);
}
@keyframes arm { 0% { transform: scale(.98); filter: brightness(2); } 60% { transform: scale(1.015); } 100% { transform: none; filter: none; } }

/* final-deletion payoff */
.app.is-ready .terminal { animation: frame-pulse .7s ease-out 1; }
@keyframes frame-pulse { 0% { box-shadow: 0 0 0 rgba(255,27,27,0); } 30% { box-shadow: 0 0 28px var(--red-glow), inset 0 0 28px rgba(255,27,27,.12); } 100% { box-shadow: 0 0 0 rgba(255,27,27,0); } }
.rate-num.is-hit { animation: num-hit .55s ease-out 1; }
@keyframes num-hit { 0% { color: var(--bone); } 100% { color: var(--red); } }

/* ---------------------------------------------------------------- form (in place) */
.panel-form { flex: 1 1 auto; display: flex; flex-direction: column; }
.panel-form[hidden] { display: none !important; }
.form { margin-top: clamp(10px, 2vh, 18px); display: flex; flex-direction: column; position: relative; }
.form[hidden], .sys-sub[hidden] { display: none; }
.step { border: 0; min-width: 0; display: grid; gap: clamp(10px, 1.8vh, 16px); }
.step-2 { display: none; }
.panel-form.is-step-2 .step-1 { display: none; }
.panel-form.is-step-2 .step-2 { display: grid; }
.field { display: block; }
.field-label { display: block; font-size: 10px; letter-spacing: 0.26em; color: var(--red); margin-bottom: 6px; }
.field input {
  width: 100%; font-family: var(--mono); font-size: 16px;      /* ≥16px: no iOS zoom */
  background: transparent; color: var(--bone);
  border: 1px solid var(--red-line); border-radius: 0;
  padding: 0 12px; height: 44px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field input::placeholder { color: rgba(232,226,212,.48); }
.field input:focus { outline: none; border-color: var(--red); box-shadow: 0 0 12px var(--red-glow); }
.field.has-err input { border-color: var(--red); border-style: dashed; }
/* autofill: Safari/Chrome paint a yellow/blue fill — override to the palette while keeping autofill working */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--bone);
  caret-color: var(--bone);
  -webkit-box-shadow: 0 0 0 1000px var(--autofill-bg) inset;
          box-shadow: 0 0 0 1000px var(--autofill-bg) inset;
  background-clip: content-box;
  border-color: var(--red-line);
  transition: background-color 999999s ease-out 0s;
}
.field input:-webkit-autofill:focus {
  border-color: var(--red);
  -webkit-box-shadow: 0 0 0 1000px var(--autofill-bg) inset, 0 0 12px var(--red-glow);
          box-shadow: 0 0 0 1000px var(--autofill-bg) inset, 0 0 12px var(--red-glow);
}
.field input:autofill { background-color: var(--autofill-bg); color: var(--bone); }
.field select {
  width: 100%; font-family: var(--mono); font-size: 16px;      /* ≥16px: no iOS zoom */
  background: transparent; color: var(--bone);
  border: 1px solid var(--red-line); border-radius: 0;
  padding: 0 12px; height: 44px;
  appearance: none; -webkit-appearance: none;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field select:focus { outline: none; border-color: var(--red); box-shadow: 0 0 12px var(--red-glow); }
.field.has-err select { border-color: var(--red); border-style: dashed; }
.field select:invalid { color: rgba(232,226,212,.48); }
.field select option { background: #030000; color: var(--bone); }
/* honeypot: off-canvas, not display:none (bots check that) */
.hp { position: absolute; left: -9999px; top: 0; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; }
.field-err { display: block; min-height: 14px; margin-top: 4px; font-size: 10px; letter-spacing: .08em; color: var(--red); }
.form-foot { margin-top: clamp(8px, 1.6vh, 14px); }
.form-stepline { display: block; font-size: 10px; letter-spacing: .3em; color: var(--red); margin-bottom: 6px; }
.form-actions { display: flex; gap: 10px; }
.btn-ghost {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em; color: var(--red);
  background: transparent; border: 1px solid var(--red); height: var(--exec-h); padding: 0 16px; cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.btn-ghost:hover, .btn-ghost:focus-visible { background: var(--red); color: var(--bg); outline: none; }
.btn-ghost[hidden] { display: none; }
.execute-submit { flex: 1; font-size: 13px; letter-spacing: .16em; display: none; }
.panel-form.is-step-2 .execute-submit, .panel-form.is-step-2 #formNext { display: block; }
.panel-form.is-step-2 #formNext { display: none; }
.panel-form.is-step-1 #formBack { display: none; }
.panel-form.is-step-1 #formNext { flex: 1; }
.form-notice { min-height: 14px; margin-top: 8px; font-size: 10.5px; letter-spacing: .06em; color: var(--bone-dim); }
.form-notice.is-on { color: var(--bone); }
.form-notice.is-err { color: var(--red); }
.form-privacy { margin-top: 4px; font-size: 10.5px; letter-spacing: .03em; color: var(--bone-dim); }
.execute-submit.is-busy { cursor: progress; color: var(--bone-dim); border-color: var(--red-line); border-style: solid; }
.form-done { margin-top: clamp(14px, 3vh, 26px); }
.form-done[hidden] { display: none; }
.done-title { color: var(--bone); font-size: 15px; letter-spacing: .18em; }
.form-done .sys-sub { margin-top: 8px; }
@media (min-width: 900px) { .done-title { font-size: 18px; } }

/* live index unavailable: honest placeholder, no number */
.rate-num.is-unavailable #pct { color: var(--bone-dim); letter-spacing: .04em; }
.rate-num.is-unavailable .pct-sym { opacity: 0; }
.rate-unavail { display: none; margin-top: 6px; font-size: 10px; letter-spacing: .24em; color: var(--bone-dim); }
.panel-status.is-unavailable .rate-unavail { display: block; }

/* on-screen keyboard open (set from visualViewport): the app fits the visible area so the
   active field and NEXT/BACK/SUBMIT stay reachable; nothing else about the layout changes */
.app.is-kbd { height: var(--vvh, 100dvh); padding-top: calc(8px + var(--sat)); padding-bottom: 8px; }
.app.is-kbd .head { min-height: 48px; padding: 6px 0; }
.app.is-kbd .logo.stepwize { width: 64px; }
.app.is-kbd .logo.hallowebs { width: 82px; }
.app.is-kbd .event-title { font-size: 22px; }
.app.is-kbd .stage { padding-top: 8px; gap: 8px; }
.app.is-kbd .foot, .app.is-kbd .link-back, .app.is-kbd .panel-form .sys-sub { display: none; }
.app.is-kbd .form { margin-top: 8px; }
.app.is-kbd .step { gap: 8px; }
.app.is-kbd .form-foot { margin-top: 8px; }
.app.is-kbd .head-bg { display: none; }
.link-back {
  margin-top: auto; align-self: flex-start; padding: 8px 0 2px;
  background: none; border: 0; cursor: pointer;
  font-size: 10px; letter-spacing: .24em; color: var(--bone-dim);
}
.link-back:hover, .link-back:focus-visible { color: var(--bone); outline: none; }

/* stage swap */
.stage.is-form .panel-blockers, .stage.is-form .panel-status { display: none; }
.panel-form.is-entering { animation: panel-in .32s cubic-bezier(.2,.8,.2,1) both; }
@keyframes panel-in { from { opacity: 0; transform: translateY(8px); clip-path: inset(0 0 40% 0); } to { opacity: 1; transform: none; clip-path: inset(0 0 0 0); } }
.panel.is-leaving { animation: panel-out .22s steps(3, end) forwards; }
@keyframes panel-out { 0% { opacity: 1; transform: translateX(0); } 40% { opacity: .5; transform: translateX(3px); clip-path: inset(30% 0 0 0); } 100% { opacity: 0; transform: translateX(-2px); } }

/* ---------------------------------------------------------------- foot */
.foot {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 6px 0 7px; margin-top: clamp(6px, 1.2vh, 12px);
  border-top: 1px solid var(--red-faint);
  font-size: 9px; letter-spacing: .22em; color: var(--bone-dim);
}
.foot-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.foot-l-long { display: none; }   /* "ACCESS " prefix only where the footer has room */
.foot-r { flex-shrink: 0; font-size: 9px; letter-spacing: .1em; color: var(--bone-dim); white-space: nowrap; }

/* ---------------------------------------------------------------- OPENING STATE */
.app.is-intro .head-bg, .app.is-intro-geometry .head-bg {
  position: fixed; inset: 0; overflow: visible;
}
.app.is-intro .head-bg > *, .app.is-intro-geometry .head-bg > * { left: 0; top: 0; width: 100%; height: 100%; }
.app.is-intro .interference {
  opacity: 0; clip-path: inset(44% 0 48% 0);
  -webkit-mask-image: linear-gradient(to bottom, transparent, rgba(0,0,0,1) 18%, rgba(0,0,0,1) 82%, transparent);
          mask-image: linear-gradient(to bottom, transparent, rgba(0,0,0,1) 18%, rgba(0,0,0,1) 82%, transparent);
}
.app.is-intro .veil { opacity: 1; }
.app.is-intro .terminal { border-color: transparent; }
.app.is-intro .terminal::before, .app.is-intro .terminal::after { opacity: 0; }
.app.is-intro .head { border-bottom-color: transparent; }
.app.is-intro .head::after { opacity: 0; }
.app.is-intro .stage, .app.is-intro .foot { opacity: 0; pointer-events: none; }

/* the identity becomes the full-viewport title card (also held while it flies during the contraction) */
.app.is-intro .identity, .app.is-intro-geometry .identity {
  position: fixed; inset: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(16px, 3vh, 34px);
  padding: 24px 24px calc(32px + var(--sab)) 24px;
  pointer-events: none;
}
.app.is-intro .identity { opacity: 0; }
.app.is-intro .logos, .app.is-intro-geometry .logos { flex-direction: column; align-items: center; gap: clamp(8px, 1.8vh, 18px); }
.app.is-intro .logo.stepwize, .app.is-intro-geometry .logo.stepwize   { width: min(260px, 50vw); }
.app.is-intro .logo.hallowebs, .app.is-intro-geometry .logo.hallowebs { width: min(400px, 78vw); }
.app.is-intro .logo, .app.is-intro-geometry .logo { filter: drop-shadow(0 2px 8px rgba(3,0,0,.75)) drop-shadow(0 0 2px rgba(3,0,0,.6)); }
.app.is-intro .event-title, .app.is-intro-geometry .event-title { text-shadow: 0 2px 12px rgba(3,0,0,.7); }
.app.is-intro .logos-x, .app.is-intro-geometry .logos-x { display: block; font-size: clamp(18px, 3vh, 28px); }
.app.is-intro .event, .app.is-intro-geometry .event { flex-direction: column; align-items: center; gap: 0; padding-left: 0; border-left: 0; }
.app.is-intro .event-title, .app.is-intro-geometry .event-title { font-size: clamp(60px, 15.4vw, 156px); line-height: 0.92; }
.app.is-intro .event-loc, .app.is-intro-geometry .event-loc { margin-top: clamp(10px, 1.8vh, 18px); font-size: clamp(11px, 1.5vh, 14px); letter-spacing: 0.2em; text-indent: 0.2em; color: var(--bone); }

/* while the identity flies, the interface resolves beneath it — timed to land as the identity settles */
.app.is-settling .stage > .panel, .app.is-settling .foot { animation: resolve .5s cubic-bezier(.2,.8,.2,1) both; }
.app.is-settling .panel-blockers .sys { animation: resolve .45s cubic-bezier(.2,.8,.2,1) both; animation-delay: .42s; }
.app.is-settling .slot { animation: resolve .4s cubic-bezier(.2,.8,.2,1) both; }
.app.is-settling .slot:nth-child(1) { animation-delay: .5s; }
.app.is-settling .slot:nth-child(2) { animation-delay: .57s; }
.app.is-settling .slot:nth-child(3) { animation-delay: .64s; }
.app.is-settling .slot:nth-child(4) { animation-delay: .71s; }
.app.is-settling .panel-blockers { animation-delay: .4s; }
.app.is-settling .panel-status { animation-delay: .66s; }
.app.is-settling .foot { animation-delay: .85s; }
.app.is-settling .terminal { animation: frame-in .5s ease .15s both; }
.app.is-settling .head { animation: rule-in .5s ease .35s both; }
@keyframes resolve { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes frame-in { from { border-color: transparent; } to { border-color: var(--red); } }
@keyframes rule-in { from { border-bottom-color: transparent; } to { border-bottom-color: var(--red-line); } }

/* ---------------------------------------------------------------- DESKTOP COMPOSITION */
@media (min-width: 900px) {
  :root {
    --row-h: clamp(56px, 9vh, 74px);
    --pct-size: clamp(84px, 15vh, 148px);
    --gauge: clamp(138px, 21vh, 196px);
    --exec-h: clamp(52px, 7vh, 60px);
  }
  .app { padding: 28px; }
  .terminal { width: min(1200px, 100%); max-height: 820px; margin: auto 0; padding: 0 28px; }
  .head { padding: 14px 0 14px; min-height: 72px; }
  .head::after { inset: 0 -28px; }
  .head-bg { inset: 0 -28px; }
  .rate-how { font-size: 12px; margin-top: 6px; }
  .form-privacy { font-size: 11px; }
  .identity { gap: 22px; }
  .logos { flex-direction: row; align-items: center; gap: 14px; }
  .logo.stepwize  { width: 126px; }
  .logo.hallowebs { width: 124px; }
  .logos-x { display: block; font-family: var(--mono); font-size: 18px; }
  .event { flex-direction: row; align-items: baseline; gap: 14px; padding-left: 22px; border-left: 1px solid var(--red-line); }
  .event-title { font-size: 34px; }
  .event-loc { margin-top: 0; font-size: 11px; }

  .stage {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) 1px minmax(0, .85fr);
    gap: 0;
    padding-top: 0;
  }
  .stage::after {
    content: ''; grid-column: 2; grid-row: 1; background: var(--red-line);
  }
  .panel-blockers { grid-column: 1; grid-row: 1; padding: clamp(18px, 3vh, 30px) 32px clamp(18px, 3vh, 30px) 0; display: flex; flex-direction: column; justify-content: center; }
  .panel-status   { grid-column: 3; grid-row: 1; margin-top: 0; padding: clamp(18px, 3vh, 30px) 0 clamp(18px, 3vh, 30px) 32px; display: flex; flex-direction: column; justify-content: center; }
  .panel-form     { grid-column: 1 / -1; grid-row: 1; padding: clamp(18px, 3vh, 30px) 0; }
  .stage.is-form::after { display: none; }

  .sys-title { font-size: 14px; }
  .sys-sub { font-size: 13px; margin-top: 8px; }
  .slots { margin-top: clamp(14px, 2.6vh, 24px); }
  .slot-label { font-size: 15px; }
  .del { height: 34px; font-size: 12px; padding: 0 16px; }
  .del-x { width: 34px; height: 34px; }

  .rate { margin-top: 10px; justify-content: space-between; }
  .rate-label { font-size: 13px; }
  .rate-note { font-size: 11px; }
  .exec-wrap { margin-top: clamp(14px, 3vh, 28px); }
  .execute { font-size: 20px; }

  /* form: two columns on desktop, single step */
  .form { max-width: 760px; }
  .step-2 { display: grid; }
  .step { grid-template-columns: 1fr 1fr; gap: 18px 24px; }
  .step-1, .step-2 { margin-bottom: 18px; }
  .panel-form.is-step-2 .step-1 { display: grid; }
  #formNext, #formBack { display: none !important; }
  .execute-submit { display: block !important; flex: 0 0 auto; min-width: 360px; font-size: 14px; }
  .form-stepline { display: none; }

  .foot { font-size: 10px; padding: 10px 0 12px; }
  .foot-r { font-size: 10px; }
  .foot-l-long { display: inline; }
}

/* ---------------------------------------------------------------- ACCESSIBLE FALLBACK: very short viewports / heavy zoom → ordinary scrolling document */
@media (max-height: 520px), (max-width: 330px) {
  html, body { height: auto; }
  .app { height: auto; min-height: 100dvh; }
  .terminal { max-height: none; }
  :root { --row-h: 46px; --pct-size: 56px; --gauge: 72px; --exec-h: 46px; }
  .stage { display: flex; flex-direction: column; gap: 16px; padding-top: 16px; }
  .panel-blockers, .panel-status, .panel-form { padding: 0; grid-column: auto; }
  .stage::after { display: none; }
  .head-bg { display: none; }
}

/* ---------------------------------------------------------------- REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  .caret, .slot.is-clearing .slot-body, .slot.is-clearing::before,
  .execute.is-armed, .app.is-ready .terminal, .rate-num.is-hit,
  .panel-form.is-entering, .panel.is-leaving,
  .app.is-settling .stage > .panel, .app.is-settling .foot, .app.is-settling .slot,
  .app.is-settling .panel-blockers .sys, .app.is-settling .terminal, .app.is-settling .head { animation: none !important; }
  .slot.is-clearing .slot-body { opacity: 0; visibility: hidden; transition: opacity .2s ease; }
  .interference, .static { opacity: .1; }
  .app.is-intro .interference, .app.is-video-fallback.is-intro .static { opacity: 0; clip-path: inset(0); animation: none; }
  .app.is-intro .identity { opacity: 1; }
  .app.is-intro .sil, .app.is-intro-geometry .sil { opacity: 1; }
  .app.is-intro .scrim, .app.is-intro-geometry .scrim { opacity: 1; }
  .sil-still { animation: none; }
  * { transition-duration: .15s !important; }
}
