/* =============================================================================
   processLaunchGateStyles.css — the .process-launch "access key" soft gate
   -----------------------------------------------------------------------------
   The prompt that unfolds beneath a pressed .process-launch control inside
   the process modal's media stack. Same instrument grammar as the shop and
   desktop gates, per visualLanguage.md: a Hornet kicker label, a /> syntax
   prompt, a hairline data-rule with an ambient scanner sweep, and
   brand-color status semantics (blue = info, green = go, red = warn).

   OPEN/CLOSE is a grid-template-rows 0fr→1fr unfold — it animates to the
   content's natural height with no magic pixel value — plus opacity and a
   small settle. AMBIENT motion (the rule's activity register + prompt glow)
   only runs while .is-open; it's paused otherwise, so a folded gate costs
   nothing.

   THE FOLD-SPACING TRICK — this gate lives in a flex column with gaps
     .process-modal-media is display:flex column with gap:--process-gap, so
     even a zero-height folded prompt would contribute a full gap of dead
     whitespace after its button. The wrapper pulls itself up by exactly
     that gap (the same move .process-dark + .process-dark makes in
     processModalStyles.css), so folded it occupies zero net space; the
     inner padding-top provides the visual breathing room when open.
     --process-gap is defined on .process-modal-media and inherits.

   CLASSES
     .process-launch-gate         wrapper / rows animator; .is-open / .is-wrong / .is-correct
     .process-launch-gate-inner   overflow-clipped content column (lets the row hit 0)
     .process-launch-gate-label   Hornet kicker ("// LOCKED.[IPM]")
     .process-launch-gate-field   /> prompt + input row
     .process-launch-gate-prompt  the /> glyph (driven-lamp glow while open)
     .process-launch-gate-input   the password field (native I-beam via cursor:text)
     .process-launch-gate-rule    hairline underline holding the activity register
     .process-launch-gate-scan    the register segment (snaps between authored states)
     .process-launch-gate-status  tiny state readout (rejected / granted)

   COUPLED WITH processLaunchGate.js (emits these classes),
   processModalStyles.css (--process-gap on the media stack), and
   infiniteStyles.css (theme vars + --ease). Fonts per fonts.css.
   ========================================================================== */

.process-launch-gate {
  /* grid-rows unfold: 0fr (collapsed) → 1fr (content height). The inner
     child clips with overflow:hidden so the row can resolve to zero. */
  display: grid;
  grid-template-rows: 0fr;
  width: 100%;
  opacity: 0;
  pointer-events: none;
  /* Cancel the flex gap between the launch button and this wrapper so a
     folded gate is spatially invisible — see THE FOLD-SPACING TRICK. */
  margin-top: calc(-1 * var(--process-gap, 2rem));
  transition: grid-template-rows 0.42s var(--ease),
              opacity           0.30s var(--ease);
}
.process-launch-gate.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
  pointer-events: auto;
}

.process-launch-gate-inner {
  overflow: hidden;
  min-height: 0;               /* lets the 0fr row actually reach zero */
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-top: 0.7rem;         /* breathing room under the launch control */

  /* small settle: content lifts into place as the rows unfold */
  transform: translateY(-4px);
  transition: transform 0.34s var(--ease);
}
.process-launch-gate.is-open .process-launch-gate-inner { transform: none; }

/* --- kicker label ---------------------------------------------------------
   The brand's signature move: a small letter-spaced uppercase readout above
   the field. Hornet Display is the instrument tier; dim by default. */
.process-launch-gate-label {
  font-family: "Hornet Display", sans-serif;
  text-transform: uppercase;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  color: var(--ink-dim);
}

/* --- prompt + input row --------------------------------------------------- */
.process-launch-gate-field {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.process-launch-gate-prompt {
  font-family: "Glitched", sans-serif;
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1;
  color: var(--brand-blue);    /* information affordance */
  user-select: none;
}
/* ambient carrier glow, only while open (paused → invisible cost when
   folded). Driven-lamp envelope per visualLanguage.md's carrier rules:
   fast attack, slow decay, floored intensity, ≥1s period. 2.2s is
   incommensurate with the register's 3.2s cycle so the two ambients drift
   against each other like independent live systems — the same phase-lock
   reasoning as the shop gate. */
.process-launch-gate.is-open .process-launch-gate-prompt {
  animation: process-launch-gate-glow 2.2s infinite;
}

.process-launch-gate-input {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  padding: 0;
  /* Native I-beam: any non-none computed cursor suppresses the crosshair and
     shows the UA text cursor — see cursor.js's --cursor protocol notes. */
  cursor: text;
  caret-color: var(--brand-blue);

  font-family: "Glitched", sans-serif;
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: 0.22em;      /* wide tracking makes masked dots read technical */
  color: var(--ink);
}
.process-launch-gate-input::placeholder {
  color: var(--ink-dim);
  letter-spacing: 0.1em;
  opacity: 0.7;
}

/* --- the rule + activity register ------------------------------------------
   A hairline data-rule with a hard-edged brand segment that SNAPS between
   hand-authored positions/widths/colors — an activity register, the
   "instrument is live" ambient. step-end timing means each state holds for
   its interval then jumps: no easing, no glide. Only animates while open;
   paused (and opacity-0 at rest) otherwise. */
.process-launch-gate-rule {
  position: relative;
  height: 1px;
  width: 100%;
  background: var(--line);
  overflow: hidden;
  transition: background 0.2s var(--ease);
}
.process-launch-gate-scan {
  position: absolute;
  top: 0;
  height: 100%;
  /* Base state doubles as the fallback: opacity 0 keeps the segment
     invisible whenever the animation isn't driving it (paused while folded,
     or removed entirely under prefers-reduced-motion). left/width animate
     via step-end — a handful of discrete jumps per second on a 1px strip,
     so the layout cost of not using transforms is nil and the authored
     states stay legible as plain values. */
  left: 2%;
  width: 10%;
  background: var(--brand-blue);
  opacity: 0;
  animation: process-launch-gate-scan 3.2s step-end infinite;
  animation-play-state: paused;             /* idle until open */
}
.process-launch-gate.is-open .process-launch-gate-scan { animation-play-state: running; }

/* --- status readout -------------------------------------------------------
   Reserves a line so nothing jumps. Wording is state-driven via ::before, so
   the JS only toggles classes — the copy lives here with the styling. */
.process-launch-gate-status {
  min-height: 0.7rem;
  font-family: "Hornet Display", sans-serif;
  text-transform: uppercase;
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  opacity: 0;
  transition: opacity 0.18s var(--ease);
}
.process-launch-gate-status::before { content: ""; }
.process-launch-gate.is-wrong   .process-launch-gate-status { opacity: 1; color: var(--brand-red); }
.process-launch-gate.is-wrong   .process-launch-gate-status::before { content: "/ KEY.REJECTED"; }
.process-launch-gate.is-correct .process-launch-gate-status { opacity: 1; color: var(--brand-green); }
.process-launch-gate.is-correct .process-launch-gate-status::before { content: "/ ACCESS.GRANTED"; }

/* --- wrong: warn the rule + prompt red, and shake the field --------------- */
.process-launch-gate.is-wrong .process-launch-gate-rule   { background: var(--brand-red); }
.process-launch-gate.is-wrong .process-launch-gate-scan   { display: none; }  /* clean warn read —
                                          no blue/green ticks over the red */
.process-launch-gate.is-wrong .process-launch-gate-prompt { color: var(--brand-red); animation: none; }
.process-launch-gate.is-wrong .process-launch-gate-field  { animation: process-launch-gate-shake 0.36s var(--ease); }

/* --- correct: go green ---------------------------------------------------- */
.process-launch-gate.is-correct .process-launch-gate-rule   { background: var(--brand-green); }
.process-launch-gate.is-correct .process-launch-gate-scan   { display: none; }  /* register off mid-grant */
.process-launch-gate.is-correct .process-launch-gate-prompt { color: var(--brand-green); animation: none; }

/* --------------------------------------------------------------------------- */
@keyframes process-launch-gate-scan {
  /* Hand-authored states; step-end holds each until the next keyframe, then
     snaps. Holds are deliberately UNEVEN and positions jump back and forth,
     so it reads as live activity rather than a metronome. Two opacity-0
     gaps read as transmission drops. Idle palette is blue (info) with
     green/yellow ticks — red never appears here; it's reserved for the
     is-wrong warn so the semantics stay legible. The cycle starts on a gap
     so a paused-at-frame-0 register shows nothing. Same authored states as
     the shop gate, deliberately — the two instruments are siblings. */
  0%   { opacity: 0; }
  4%   { left: 2%;  width: 10%; background: var(--brand-blue);   opacity: 1; }
  13%  { left: 34%; width: 5%;  background: var(--brand-blue);   opacity: 1; }
  21%  { left: 18%; width: 13%; background: var(--brand-green);  opacity: 1; }
  29%  { opacity: 0; }
  34%  { left: 61%; width: 7%;  background: var(--brand-blue);   opacity: 1; }
  47%  { left: 79%; width: 12%; background: var(--brand-yellow); opacity: 1; }
  56%  { left: 48%; width: 4%;  background: var(--brand-blue);   opacity: 1; }
  64%  { left: 88%; width: 6%;  background: var(--brand-blue);   opacity: 1; }
  72%  { opacity: 0; }
  79%  { left: 8%;  width: 6%;  background: var(--brand-green);  opacity: 1; }
  90%  { left: 26%; width: 9%;  background: var(--brand-blue);   opacity: 1; }
}
@keyframes process-launch-gate-glow {
  /* Fast attack, brief peak, slow release — a driven lamp, not a metronome
     fade. The attack is quick but CONTINUOUS (a hard snap-on would read as
     an information event); the decay's steep-then-flat bezier approximates
     exponential release — drops fast off the peak, long tail into the 0.35
     floor. Never fully off: a blackout would be an information event too. */
  0%   { opacity: 0.35; animation-timing-function: ease-out; }  /* attack ~175ms */
  8%   { opacity: 1;    animation-timing-function: linear;   }  /* peak hold ~110ms */
  13%  { opacity: 1;    animation-timing-function: cubic-bezier(0.2, 0.55, 0.35, 1); } /* release ~1.9s */
  100% { opacity: 0.35; }
}
@keyframes process-launch-gate-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}

/* Motion-reduction: keep the state changes, drop the perpetual motion. */
@media (prefers-reduced-motion: reduce) {
  .process-launch-gate,
  .process-launch-gate-inner { transition: opacity 0.2s var(--ease); }
  .process-launch-gate.is-open .process-launch-gate-prompt,
  .process-launch-gate-scan { animation: none; }
  .process-launch-gate.is-open .process-launch-gate-inner { transform: none; }
}
