/* =========================================================================
   web/public/landing-page-valoram/pii-stepper.css (ported from landing-page-bridge-pii2, 2026-08-07)

   The one-field-at-a-time PII stepper, dressed in the LIVE landing page's
   own design language rather than the video-survey demo's navy glass. Every
   value below is either a brand token from ../styles/style.css or a copy of
   the rule the live LP already uses for the same job:

     card frame      <- .ai-v1-quiz-frame  (paper, border-soft, radius-lg,
                        shadow-md, overflow hidden so the bar rounds inside)
     progress bar    <- .ai-v1-progress    (6px track on cream-deep, gold
                        gradient fill, uppercase 0.72rem caption)
     question        <- .ai-card-question   (Cormorant Garamond, navy)
     why-line        <- the bridge arm's override of .ai-card-justification
                        (centered, 0.875rem, muted, no gold left border)
     inputs          <- .ai-field-input / .ai-field-select, used by class so
                        they are literally the live control, not a lookalike
     primary button  <- .ai-form-submit, same
     privacy note    <- .ai-form-privacy, same

   The intent is that this reads as the live funnel having grown a stepper,
   not as the demo having been pasted into the LP.
   ========================================================================= */

/* ---- Frame ---------------------------------------------------------- */

.pii-step-frame {
  margin-top: var(--ai-space-4);
  background: var(--ai-paper);
  border: 1px solid var(--ai-border-soft);
  border-radius: var(--ai-radius-lg);
  box-shadow: var(--ai-shadow-md);
  overflow: hidden;
}

/* Same geometry as .ai-v1-progress so the bar does not visibly jump when the
   survey hands over to the stepper. */
.pii-step-progress {
  display: flex;
  flex-direction: column;
  gap: var(--ai-space-2);
  padding: var(--ai-space-4) var(--ai-space-5) 0;
}
.pii-step-track {
  height: 6px;
  background: var(--ai-cream-deep);
  border-radius: 999px;
  overflow: hidden;
}
.pii-step-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--ai-gold) 0%, var(--ai-gold-deep) 100%);
  border-radius: 999px;
  transition: width 320ms var(--ai-ease-out);
}
/* Caption restored 2026-08-20 (operator, TAI-funnel parity; supersedes the
   2026-08-07 removal). Same treatment as the bridge arm's caption. */
.pii-step-caption {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ai-text-soft);
  text-align: center;
}

.pii-step-body {
  padding: var(--ai-space-5) var(--ai-space-5) var(--ai-space-6);
}

/* Each step animates in with the shared card animation (aiCardSlideIn is
   defined in ../styles/style.css), which is what every survey question on
   this page already does when it advances. */
.pii-step-card {
  animation: aiCardSlideIn 350ms var(--ai-ease-out) both;
}

/* ---- Copy ----------------------------------------------------------- */

/* The live PII screen opens with contact-form.js's congratulations card. It
   is reassurance, not capture, so the stepper keeps it rather than quietly
   dropping it: the arm has to differ from live in ONE thing, and that thing
   is the field-at-a-time pattern. Shown on the first step only, in the live
   arm's own words and the same gold-edged treatment. */
.pii-step-qualify {
  border: 2px solid var(--ai-gold);
  border-radius: var(--ai-radius-md);
  background: var(--ai-cream);
  padding: var(--ai-space-3) var(--ai-space-4);
  margin: 0 0 var(--ai-space-5) 0;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--ai-navy);
  text-align: center;
}

.pii-step-q {
  font-family: var(--ai-font-display);
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  font-weight: 700;
  line-height: 1.25;
  color: var(--ai-navy);
  letter-spacing: -0.01em;
  margin: 0 0 var(--ai-space-3) 0;
}

.pii-step-why {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ai-text-muted);
  text-align: center;
  margin: 0 0 var(--ai-space-5) 0;
}

/* The next-page preview, directly above the final button. Same muted register
   as the why line on purpose, so it reads as a footnote to the tap rather than
   competing with the question for the top of the card. Tighter bottom margin
   because the button follows immediately. */
.pii-step-prebutton {
  margin: var(--ai-space-4) 0 var(--ai-space-3) 0;
}

/* ---- Trust pill, third state ---------------------------------------- */

/* The page-level security pill lives in this arm's index.html and is swapped
   once by body.ai-pii-mode (contact-form.js sets that when the details step
   renders). These rules add a THIRD state for the phone and code steps, driven
   by body.pii-phone-trust from pii-stepper.js.

   They live here rather than in the arm's styles.css so that file stays a
   byte-identical copy of the control's and cannot drift. Load order is what
   makes the override work: index.html loads styles.css and then this file, so
   at equal specificity these win, and only while the body class is present. */
.ai-sec-phone { display: none; }
body.pii-phone-trust .ai-sec-answers,
body.pii-phone-trust .ai-sec-info { display: none; }
body.pii-phone-trust .ai-sec-phone { display: inline; }

/* The pill's own rule is white-space: nowrap, which is fine for the two short
   lines it was written for and is NOT fine for this one. Caught by the 390px
   walk: the third line is long enough that nowrap pushed the document to 536
   CSS px, so the whole page scrolled sideways on the two steps that matter
   most, and 81% of this arm's paid traffic is an in-app webview. Released only
   while the long line is showing, so the control-copy states keep the single
   line the rule was tuned for. */
body.pii-phone-trust .ai-v1-security-text { white-space: normal; }
body.pii-phone-trust .ai-v1-security-pill { max-width: 100%; }

/* ---- Fields --------------------------------------------------------- */

/* space-4, not space-5: every field already reserves a line for its error
   message (see .pii-step-error's min-height, which is what stops the button
   from jumping when validation fires), so the live form's 24px inter-field
   rhythm reads as ~40px here. */
.pii-step-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--ai-space-4);
  margin-bottom: var(--ai-space-4);
}
.pii-step-single {
  margin-bottom: var(--ai-space-4);
}
/* A field that spans the whole row. Set via `full: true` on the field
   definition. .pii-step-row is 2-up above 480px, so an odd field count would
   otherwise strand the last field at half width in column 1, directly beneath
   the field above it. Below 480px the grid is already single-column, so this
   is a no-op there. */
.pii-step-field--full { grid-column: 1 / -1; }

@media (max-width: 480px) {
  .pii-step-row { grid-template-columns: 1fr; gap: var(--ai-space-3); }
}

.pii-step-label {
  display: block;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ai-navy);
  margin-bottom: var(--ai-space-2);
}

/* The live form's .ai-field.has-error hook keys off a wrapper class this
   stepper does not use, so the error line carries its own visibility. Same
   colour, size and motion as .ai-field-error. */
.pii-step-error {
  display: block;
  margin-top: var(--ai-space-2);
  font-size: 0.85rem;
  color: var(--ai-error);
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 200ms var(--ai-ease-out), transform 200ms var(--ai-ease-out);
  min-height: 1.15em;
}
.pii-step-field.has-error .pii-step-error {
  opacity: 1;
  transform: translateY(0);
}
.pii-step-field.has-error .ai-field-input,
.pii-step-field.has-error .ai-field-select {
  border-color: var(--ai-error);
}

/* ---- OTP step ------------------------------------------------------- */

/* The fifth step does NOT render a code input of its own. It re-parents
   contact-form.js's live .ai-otp-code-block (and .ai-otp-verified block) out
   of the hidden form and into the step card, so the input, the resend button,
   the error span and the 5-fail lockout are all the shipped code paths, and a
   private copy cannot drift away from them.

   Both blocks are already fully styled by ../styles/style.css. The only thing
   they need here is to stop reserving the margin that positioned them under a
   phone field they are no longer under. */
.pii-step-otp-host > .ai-otp-code-block,
.pii-step-otp-host > .ai-otp-verified {
  margin-top: 0;
}
.pii-step-otp-host > .ai-otp-code-block + .ai-otp-verified {
  margin-top: var(--ai-space-3);
}

/* The adopted block ships its own "Enter the 4-digit code" label. The step
   card's question line already asks for the code, so the duplicate is
   suppressed rather than deleted: pii-polish.js and contact-form.js both
   still query it, and removing the node would be a change to their DOM. */
.pii-step-otp-host .ai-otp-code-block > .ai-field-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- Buttons -------------------------------------------------------- */

/* The primary control carries .ai-form-submit as well, so it IS the live
   submit button. This only removes the top margin that rule adds for a
   button sitting under a stack of form fields. */
.pii-step-next {
  margin-top: 0;
}

.pii-step-secondary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--ai-space-4);
  margin-top: var(--ai-space-4);
}
/* No arm-local Resend button: the adopted .ai-otp-code-block carries
   contact-form.js's own, which is wired to the real verify-phone-start call
   and the real 30s cooldown. */
.pii-step-back {
  background: none;
  border: none;
  padding: var(--ai-space-2) var(--ai-space-3);
  font-family: var(--ai-font-body);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ai-text-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  min-height: 44px;
}
.pii-step-back:hover {
  color: var(--ai-navy);
}

/* Primary control while an Edge Function call is in flight (send code). The
   live submit button has no in-flight state of its own because it navigates
   away; this one has to come back if verify-phone-start fails. */
.pii-step-next[disabled] {
  opacity: 0.6;
  cursor: default;
}

/* Handoff / send failures that are OUR bug, not the visitor's mistake. Same
   voice and colour as the live form's own error banner. */
.pii-step-fault {
  margin-top: var(--ai-space-3);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--ai-error);
  text-align: center;
}

.pii-step-privacy {
  margin-top: var(--ai-space-4);
}

/* ---- The real form, present and driven but not shown ---------------- */

/* Not display:none. contact-form.js and pii-polish.js both read layout off
   this subtree, and the stepper dispatches real input events into it; a
   display:none subtree is the kind of thing that quietly changes how a
   browser treats a control. Clipped to a 1px box instead, the way a visually
   hidden live region is done. */
.pii-hidden-form {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}



/* =========================================================================
   PII step: no qualify card (operator call, 2026-08-18)
   -------------------------------------------------------------------------
   Once the visitor is typing their name, the "You qualify" reveal is
   retrospective: it describes a survey that is already over, and on a phone it
   cost most of the first screen and pushed the first input below the fold.

   The PROGRESS BAR STAYS. It is the opposite kind of signal: it says how much
   is left, not what already happened, and it is the only thing on this step
   that tells someone mid-form that the end is close. Removing it was
   considered and reversed the same day.

   Scoped to body.ai-pii-mode so the reveal still does its job at the moment it
   is earned, i.e. between the last question and the form.
   ========================================================================= */
body.ai-pii-mode #reveal-mount { display: none !important; }

/* =========================================================================
   PII composition fork (2026-08-21). Valoram port of the bridge arm's FL-020.
   Card: docs/funnel-lab/cards/FL-020-pii-composition-tight-vs-value.md.
   The state machine is shared; everything below is chrome. Scoping is the
   card-level class pii-step-card gets at render: .pii-comp-tight (control)
   and .pii-comp-value (value-forward).

   Every rule reuses the SAME token names as the bridge arm's block, and
   valoram-theme.css aliases those tokens to Valoram values (--ai-gold is the
   brand orange #F38D3B, --ai-navy the near-black). So this block is a
   near-verbatim port that renders in Valoram branding for free. The one
   deliberate divergence is noted at the CTA rule below.

   NOTE: the retired .pii-step-progress / -track / -fill / -caption rules
   above are now dead on this arm (no bar, no caption on either comp). They
   are left in place rather than deleted because pii-polish.js and the
   unqualified defensive path still reference the frame classes around them,
   and a CSS delete is not worth the risk on a live funnel.
   ========================================================================= */

/* Inside-the-box labels, BOTH comps: the visible label row is gone and the
   placeholder carries the label. The <label> stays for screen readers. */
.pii-step-label--sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Tight comp: one green success badge, contact step only. The green is a
   literal, not a token: it is a SUCCESS signal, not a brand accent, and it
   must read the same on both brands. */
.pii-step-qualify--green {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--ai-space-2);
  border: 0;
  background: #e9f6ef;
  color: #1d7a4d;
  border-radius: 10px;
  padding: var(--ai-space-2) var(--ai-space-3);
  font-weight: 700;
}
.pii-qualify-ck {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #1d7a4d;
  color: #fff;
  font-size: 0.7rem;
  flex: 0 0 auto;
}

/* Tight comp: FINAL STEP pill, phone step only. The pill carries the
   finality so the heading does not repeat it. */
.pii-final-pill {
  display: block;
  width: max-content;
  margin: 0 auto var(--ai-space-2);
  background: var(--ai-gold-soft);
  color: var(--ai-gold-deep);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 5px 12px;
  border-radius: 999px;
}

/* Value comp: the what-happens-next block above the first ask. */
.pii-value-head {
  font-family: var(--ai-font-display, inherit);
  font-size: 1.35rem;
  line-height: 1.25;
  text-align: center;
  color: var(--ai-navy);
  margin: 0 0 var(--ai-space-3);
  text-wrap: balance;
}
.pii-value-checks {
  list-style: none;
  margin: 0 auto var(--ai-space-4);
  padding: 0;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: var(--ai-space-2);
}
.pii-value-checks li {
  display: flex;
  gap: var(--ai-space-2);
  font-size: 0.95rem;
  line-height: 1.4;
  color: var(--ai-navy);
}
.pii-value-ck {
  color: #1d7a4d;
  font-weight: 800;
  flex: 0 0 auto;
}

/* Value comp: soft filled inputs (RetireWizard treatment). */
.pii-comp-value .ai-field-input,
.pii-comp-value .ai-field-select {
  background: #f3f4f6;
  border-color: transparent;
}
.pii-comp-value .ai-field-input:focus,
.pii-comp-value .ai-field-select:focus {
  background: #fff;
}

/* Value comp: brand-accent CTA. DIVERGENCE from the bridge block, which uses
   a gold gradient: --ai-gold is #F38D3B here and white-on-orange fails AA at
   this weight, so the fill is the deep orange that passes on light ground. */
.pii-comp-value .pii-step-next {
  background: linear-gradient(90deg, var(--ai-gold) 0%, var(--ai-gold-deep) 100%);
  color: #fff;
}

/* Trust chrome (value comp) and the quiet why-line (tight comp + value's
   state step). Bottom placement is the point: the why lives in small type
   under the action, never as a paragraph above the fields. */
.pii-trust-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--ai-space-2);
  margin-top: var(--ai-space-3);
  font-size: 0.8rem;
  color: var(--ai-text-soft);
}
.pii-trust-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--ai-gold) 0%, var(--ai-navy) 100%);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  flex: 0 0 auto;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.pii-trust-badges {
  display: flex;
  justify-content: center;
  gap: var(--ai-space-4);
  margin-top: var(--ai-space-2);
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ai-text-soft);
}
.pii-why-line {
  margin-top: var(--ai-space-3);
  text-align: center;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--ai-text-soft);
}
