/* onboarding.css: welcome, mic check, stages, readiness — extracted from test.html and reskinned to the staging brand (crimson/navy/Poppins).
   Component library / page styles. Loaded via app.css. */


    *{box-sizing:border-box}

  .mic-btn svg{flex:0 0 auto}


  /* ===================== ONBOARDING (full screen, gated) ===================== */
  .ob{display:grid;grid-template-columns:0.92fr 1.08fr;min-height:100vh}

  .ob .left{position:relative;min-width:0;overflow-wrap:break-word;background:linear-gradient(160deg,#4A0710,#7E0C1E 52%,#B01029);color:#fff;padding:54px 50px;display:flex;flex-direction:column;justify-content:center;gap:24px;overflow:hidden}

  .ob .left::after{content:"";position:absolute;inset:0;background:radial-gradient(600px 380px at 80% 12%, rgba(255,255,255,.14), transparent 60%);pointer-events:none}

  .brand{display:flex;align-items:center;gap:11px;font-weight:600;letter-spacing:-.01em;position:relative;z-index:1}

  .brand .mk{width:34px;height:34px;border-radius:9px;background:rgba(255,255,255,.16);display:grid;place-items:center}

  .left .pitch{position:relative;z-index:1}

  .left .pitch h2{font-family:var(--display);font-weight:600;font-size:34px;line-height:1.14;margin:0 0 14px;letter-spacing:-.01em}

  .left .pitch p{color:rgba(255,255,255,.82);font-size:15px;line-height:1.6;max-width:46ch;margin:0}

  .left .pitch .trust{font-size:12.5px;color:rgba(255,255,255,.64);margin-top:13px;max-width:48ch;border-top:1px solid rgba(255,255,255,.15);padding-top:13px}

  /* On wide windows the maroon panel is far wider than the content wants to be, so left-anchored
     content dumps all the empty space on the right and reads as "jammed left". Cap the content to a
     reading column and centre THAT column in the panel: text stays left-aligned, gutters stay even.
     Only kicks in above the phone row-header breakpoint; on narrow panels the cap is a no-op. */
  

  .left .lead{display:flex;flex-direction:column;gap:26px;min-width:0}

  .portrait{position:relative;z-index:1;align-self:flex-start;margin:0}

  .portrait .frame{width:230px;height:230px;border-radius:28px;overflow:hidden;border:1px solid rgba(255,255,255,.28);box-shadow:0 24px 60px rgba(0,0,0,.3);background:#e2e8f0}

  .portrait .frame img{width:100%;height:100%;object-fit:cover;object-position:center top;display:block}

  /* While the photo downloads, show a quiet shimmer in its place. The frame already has a solid
     background, so the alternative was a flat grey square that read as a broken image. `is-loading`
     is removed by examiner-ui.js on the img's load event (or on error, after the illustrated
     placeholder is swapped in), so a cached photo never shows the skeleton at all. */
  .portrait .frame.is-loading{background:linear-gradient(100deg,#e2e8f0 30%,#eef2f7 50%,#e2e8f0 70%);background-size:220% 100%;animation:skeleton 1.2s ease-in-out infinite}

  .portrait .frame.is-loading img{opacity:0}

  .portrait .frame img{transition:opacity .35s ease}

  .portrait .frame{display:grid;place-items:center}

  .portrait .frame .examiner-ic{width:46%;height:46%;color:var(--burgundy)}

  .portrait .cap{margin-top:14px;text-align:left}

  .portrait .cap b{font-weight:600}

  .portrait .cap span{display:block;color:rgba(255,255,255,.72);font-size:13px;margin-top:3px}


  .ob .right{padding:54px 56px;display:flex;flex-direction:column;justify-content:center}

  .ob .right>.progress,.ob .right>.stage{width:100%;max-width:580px;margin-inline:auto}

  /* Named stages. The bar is the track; ::after is the fill, so the label can live in the same cell. */
  .progress{display:flex;align-items:flex-start;gap:8px;margin-bottom:34px}

  .progress .p{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px}

  .progress .p>span{display:block;height:5px;border-radius:999px;background:var(--rose-soft);overflow:hidden}

  .progress .p>span::after{content:"";display:block;height:100%;width:0;background:linear-gradient(90deg,var(--rose),var(--burgundy));transition:width .4s ease}

  .progress .p.done>span::after,.progress .p.active>span::after{width:100%}

  .progress .p em{font-style:normal;font-size:11px;font-weight:600;letter-spacing:.03em;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

  .progress .p.done em,.progress .p.active em{color:var(--burgundy)}

  /* Full stage names have room on desktop; phones get the short form rather than an ellipsis. */
  .progress em i{font-style:normal}

  .progress em .sm{display:none}

  

  /* Trust flow (B6): Former Examiner -> Trained the AI -> 14-min test -> Instant band, rendered as a
     credential timeline that sits directly beneath Daniel's profile. Each item owns a dot in a left
     gutter; a hairline rail connects consecutive dots. Spacing is per-item padding (not gap) so the
     rail can run edge-to-edge between nodes. */
  .trustflow{list-style:none;margin:0;padding:0;min-width:0;display:flex;flex-direction:column}

  .trustflow li{position:relative;padding:0 0 20px 28px;font-size:13px;font-weight:600;line-height:1.25;color:#fff;opacity:.96}

  .trustflow li:last-child{padding-bottom:0}

  .trustflow li::before{content:"";position:absolute;left:3px;top:2px;width:11px;height:11px;border-radius:50%;background:var(--rose);box-shadow:0 0 0 4px rgba(255,255,255,.12)}

  .trustflow li:not(:last-child)::after{content:"";position:absolute;left:8px;top:14px;bottom:1px;width:2px;background:rgba(255,255,255,.26)}

  .reassure{margin:12px 0 0;font-size:13px;color:var(--muted);line-height:1.55}

  .stage{display:none;animation:fade .4s ease both}

  .stage.on{display:block}

  .kicker{font-size:12px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--burgundy)}

  .stage h3{font-family:var(--display);font-weight:600;font-size:28px;margin:10px 0 8px;letter-spacing:-.01em}

  .stage .sub{color:var(--muted);font-size:15px;line-height:1.55;margin:0 0 24px}

  /* CTA button row is centered on every onboarding step (Step 1 fully centered; later steps keep
     their left-aligned copy/forms but the buttons sit centered for a balanced, consistent look). */
  .navrow{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:30px}

  .stage[data-stage="0"]{text-align:center}

  /* checklist: a tidy centered column (rows stay left-aligned, the BLOCK is centered). Capping the
     width is what actually centers it — without it the long first line spans full width and it reads
     as left-aligned. */
  .stage[data-stage="0"] .ticks{max-width:380px;margin-inline:auto;text-align:left}


  .ticks{display:grid;gap:12px;margin:6px 0 0}

  .tick{display:flex;align-items:center;gap:11px;font-size:15px}

  .tick .ic{width:26px;height:26px;border-radius:8px;background:var(--rose-soft);display:grid;place-items:center;flex:0 0 auto}


  .mic-panel{border:1px solid var(--line);border-radius:18px;padding:22px;background:var(--rose-mist)}

  .mic-visual{display:flex;align-items:center;justify-content:center;gap:5px;height:54px;margin-bottom:14px}

  /* Bars are driven by the real (smoothed) mic level from JS, with a short transition to glide between
     frames. The old canned `bar` keyframe fought the JS transform on the same property every frame,
     which is what flickered. No CSS animation here now. */
  .mic-visual i{width:5px;height:14px;border-radius:4px;background:var(--rose);transform-origin:center;transition:transform .12s ease-out}

  .mic-result{display:none;align-items:center;gap:9px;color:var(--go);font-weight:600;font-size:14px;justify-content:center}

  .mic-panel.passed .mic-result{display:flex}

  /* Once the check has passed the tick says it all; the faded pulsing waveform under it just read
     as weird blinking. Hide it in every viewport (not only mobile). */
  .mic-panel.passed .mic-visual{display:none}

  /* Four states Dan asked for: idle, recording, playback, success. The waveform only exists once we listen. */
  /* gap, not a plain space: as a flex container the whitespace between "Press" and <b>Test my mic</b>
     is stripped, and it rendered as "PressTest my mic". */
  .mic-idle{display:flex;align-items:center;justify-content:center;gap:5px;height:54px;margin-bottom:14px;color:var(--muted);font-size:14px}

  .mic-idle b{color:var(--ink);font-weight:600}

  .mic-panel.testing .mic-idle,.mic-panel.playback .mic-idle,.mic-panel.passed .mic-idle,.mic-panel.failed .mic-idle{display:none}

  /* A failed check must not leave a green "Test Again" button reading like a success. */
  .mic-panel.failed ~ .navrow .btn.mic-btn{background:linear-gradient(180deg,#fff,var(--rose-mist));border-color:var(--rose);color:var(--burgundy)}

  .mic-panel.failed ~ .navrow .btn.mic-btn:hover{border-color:var(--burgundy);box-shadow:0 10px 24px rgba(196,18,48,.16)}

  .mic-panel .mic-visual{display:none}

  .mic-panel.testing .mic-visual,.mic-panel.playback .mic-visual{display:flex}

  .mic-play{display:flex;width:max-content;margin:10px auto 0}

  .mic-play[hidden]{display:none}

  .mic-note{text-align:center;font-size:13px;color:var(--muted);margin:10px 0 0}


  .opt-grid{display:grid;gap:12px}

  .field-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:18px}

  .prep-cue-title{font-family:var(--display);font-weight:600;font-size:18px;line-height:1.3;margin-bottom:8px}

  .prep-cue-intro{font-size:12px;color:var(--muted);margin-bottom:6px}

  .prep-cue-bullets{margin:0;padding-left:18px;display:grid;gap:5px;font-size:14px}


  /* ===================== READY ===================== */
  .ready-wrap{height:100dvh;display:grid;grid-template-rows:minmax(0,1fr);justify-items:center;padding:clamp(10px,2.2vh,32px) 16px;overflow:hidden;background:radial-gradient(900px 520px at 50% -8%, var(--rose-mist), transparent 62%), var(--paper)}

  .ready-card{align-self:center;width:min(1080px,100%);max-height:100%;min-width:0;display:flex;flex-direction:column;background:var(--paper);border:1px solid var(--line);border-radius:24px;box-shadow:var(--shadow);animation:fade .4s ease both;overflow:hidden;overflow-wrap:break-word}

  .ready-head{flex:none;text-align:center;padding:clamp(14px,2.6vh,30px) 24px clamp(10px,1.6vh,18px)}

  .ready-head h3{font-family:var(--display);font-weight:600;font-size:clamp(20px,2.8vh,28px);margin:4px 0 0;color:var(--ink)}

  .ready-head p{color:var(--muted);font-size:14px;line-height:1.45;max-width:520px;margin:6px auto 0}

  .ready-cols{flex:1 1 auto;min-height:0;overflow-y:auto;display:grid;grid-template-columns:minmax(0,1fr);align-items:stretch;gap:14px;padding:2px clamp(14px,3vw,32px) 16px}

  .nextup,.envtips{text-align:left;border:1px solid var(--rose-soft);border-radius:16px;padding:16px;background:#fff}

  .nu-h,.env-h{display:flex;align-items:center;gap:8px;font-size:11.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--burgundy);margin-bottom:12px}

  .h-ic{flex:none;display:inline-grid;place-items:center;width:16px;height:16px}

  .h-ic svg{width:16px;height:16px}

  .nu-total,.env-count{margin-left:auto;font-size:12px;font-weight:600;letter-spacing:.01em;text-transform:none;color:var(--muted)}

  .nu-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(72px,1fr));align-items:stretch;gap:8px}

  .nu{min-width:0;display:flex;flex-direction:column;gap:2px;text-align:center;padding:9px 4px;border-radius:12px;background:var(--rose-mist);border:1px solid var(--rose-soft);animation:nuin .5s ease both}

  .nu:nth-child(2){animation-delay:.06s}
  .nu:nth-child(3){animation-delay:.12s}
  .nu:nth-child(4){animation-delay:.18s}

  .nu b{font-size:13px;font-weight:600;color:var(--burgundy)}

  .nu em{font-style:normal;font-size:12px;color:var(--ink)}

  .nu span{font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}

  .during{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:10px}

  .during li{display:flex;align-items:center;gap:10px;font-size:13px;line-height:1.45;color:var(--muted)}

  .d-ic{flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;color:var(--burgundy);background:var(--rose-mist)}

  .d-ic svg{width:16px;height:16px}

  .tips{margin-top:14px;border-top:1px solid var(--rose-soft);padding-top:8px}

  .tips summary{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;font-weight:600;color:var(--burgundy);list-style:none;min-height:32px}

  .tips summary::-webkit-details-marker{display:none}

  .tips summary::after{content:"";margin-left:auto;margin-right:4px;width:7px;height:7px;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translateY(-2px);transition:transform .2s ease}

  .tips[open] summary::after{transform:rotate(-135deg) translateY(-2px)}

  .tips-body{font-size:12.5px;line-height:1.55;color:var(--muted)}

  .tips-body p{margin:8px 0 0}

  .tips-body ul{margin:5px 0 0;padding-left:16px;list-style:disc}

  .tips-body li{margin-top:3px}

  .tips-body b{color:var(--ink)}

  .env-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}

  .env{display:flex;align-items:center;gap:12px;width:100%;margin:0;padding:10px 12px;border:1px solid var(--line);border-radius:12px;background:#fff;font:inherit;text-align:left;cursor:pointer;transition:border-color .2s ease,background .2s ease,box-shadow .2s ease}

  .env:hover{border-color:var(--rose-soft);box-shadow:var(--shadow-sm)}

  .env.checked{border-color:#bfe3d0;background:#f1faf5}

  .env-ic{flex:none;width:34px;height:34px;border-radius:10px;display:grid;place-items:center;color:var(--go);background:rgba(20,150,90,.1)}

  .env-ic svg{width:18px;height:18px}

  .env-tx{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;font-size:12.5px;line-height:1.35;color:var(--muted)}

  .env-tx b{font-size:13.5px;font-weight:600;color:var(--ink);margin-bottom:1px}

  .env-ck{flex:none;width:22px;height:22px;border-radius:50%;border:2px solid var(--line);display:grid;place-items:center;color:transparent;transition:background .18s ease,border-color .18s ease,color .18s ease}

  .env-ck svg{width:12px;height:12px}

  .env.checked .env-ck{background:var(--go);border-color:var(--go);color:#fff}

  .ready-foot{flex:none;display:grid;gap:10px;padding:12px clamp(14px,3vw,32px) clamp(14px,2.2vh,24px);border-top:1px solid var(--line);background:var(--paper)}

  .readycheck{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;text-align:left}

  .rc-row{display:flex;align-items:center;gap:10px;min-width:0;padding:8px 12px;border:1px solid var(--line);border-radius:12px;background:#fff;transition:border-color .3s ease,background .3s ease}

  .rc-row.done{border-color:#bfe3d0;background:#f1faf5}

  .rc-ic{flex:none;width:28px;height:28px;border-radius:8px;display:grid;place-items:center;color:var(--burgundy);background:var(--rose-mist)}

  .rc-ic svg{width:16px;height:16px}

  .rc-row.done .rc-ic{color:var(--go);background:rgba(20,150,90,.12)}

  .rc-tx{min-width:0;font-size:13px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

  .rc-meter{margin-left:auto;display:flex;align-items:center;gap:3px;height:20px}

  .rc-meter i{width:3px;height:5px;border-radius:2px;background:#bfe3d0;transform:scaleY(1);transform-origin:center;transition:transform .08s ease-out,background .3s ease}

  .rc-row.done .rc-meter i{background:var(--go)}

  .rc-st{flex:none;width:18px;height:18px;border-radius:50%;border:2px solid var(--rose);animation:softpulse 1.8s ease-in-out infinite}

  .rc-row:not([data-rc="mic"]) .rc-st{margin-left:auto}

  .rc-row.done .rc-st{border:none;background:var(--go);animation:none;position:relative}

  .rc-row.done .rc-st::after{content:"";position:absolute;left:6px;top:2.5px;width:4.5px;height:8.5px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(42deg)}

  .rc-row.blocked{border-color:#f0c6c2;background:#fdf3f2}

  .rc-row.blocked .rc-ic{color:#b3261e;background:rgba(179,38,30,.12)}

  .rc-row.blocked .rc-tx{color:#b3261e}

  .rc-row.blocked .rc-st{border:none;background:#b3261e;animation:none;position:relative}

  .rc-row.blocked .rc-st::after{content:"!";position:absolute;inset:0;display:grid;place-items:center;color:#fff;font-size:12px;font-weight:800}

  .rc-row.blocked .rc-meter{display:none}

  #beginBtn{min-height:52px;margin:0}

  .micblock{display:flex;align-items:center;gap:12px;text-align:left;margin:0;border:1px solid #f0c6c2;background:#fdf3f2;border-radius:14px;padding:13px 15px}

  .micblock[hidden]{display:none}

  .micblock .mb-ic{flex:0 0 auto;width:36px;height:36px;border-radius:10px;display:grid;place-items:center;color:#b3261e;background:rgba(179,38,30,.1)}


  .micblock .mb-tx{display:flex;flex-direction:column;font-size:12.5px;line-height:1.4;color:var(--muted)}

  .micblock .mb-tx b{font-size:13.5px;font-weight:600;color:var(--ink,#0F172A)}

  .micblock .btn{flex:0 0 auto;white-space:nowrap;margin-left:auto}

  /* guided mic-permission help popup */
  .michelp{position:fixed;inset:0;z-index:60;display:grid;place-items:center;background:rgba(15,23,42,.5);backdrop-filter:blur(3px);padding:20px}

  .michelp[hidden]{display:none}

  .michelp-card{width:min(440px,94vw);max-height:88dvh;overflow:auto;background:#fff;border-radius:20px;padding:28px 30px;box-shadow:0 30px 80px rgba(15,23,42,.4);text-align:center;animation:fade .3s ease both}

  .michelp-card .mh-ic{width:48px;height:48px;margin:0 auto 12px;border-radius:14px;display:grid;place-items:center;color:var(--burgundy);background:var(--rose-soft)}

  .michelp-card h3{font-family:var(--display);font-weight:600;font-size:22px;margin:0 0 6px}

  .michelp-card>p{color:var(--muted);font-size:14px;line-height:1.55;margin:0 0 16px}

  .mh-steps{text-align:left;margin:0 0 20px;padding-left:22px;display:grid;gap:10px}

  .mh-steps li{font-size:14.5px;line-height:1.5;color:var(--ink,#0F172A);padding-left:4px}

  .mh-steps li::marker{color:var(--burgundy);font-weight:700}

  .mh-steps[hidden]{display:none}

  /* The OS-level escape hatch: macOS/Windows can withhold the mic from the BROWSER, in which case no
     in-page toggle helps. Quieter than a step because most people won't need it. */
  .mh-note{text-align:left;margin:-6px 0 18px;padding:10px 12px;border-radius:10px;background:var(--rose-soft);color:var(--muted);font-size:12.5px;line-height:1.5}

  .mh-note[hidden]{display:none}

  /* Live "waiting / granted" line. The watcher drives this, so the modal confirms success by itself. */
  .mh-status{margin:0 0 16px;font-size:13px;font-weight:600;color:var(--muted)}

  .mh-status[hidden]{display:none}

  .mh-status.ok{color:var(--go)}

  .mh-actions{display:flex;gap:10px;justify-content:center}

  #beginBtn[data-connecting]{opacity:.7}

  #beginBtn[disabled]{pointer-events:none;cursor:default}

  /* Was an infinite pulse that never settled. Pulse twice to draw the eye, then hold still. */
  #beginBtn:not([data-connecting]):not([disabled]){animation:beginpulse 1.8s ease-in-out 2}

  #beginBtn .bdots{display:inline-flex;gap:5px;margin-left:9px;vertical-align:middle}

  #beginBtn .bdots i{width:6px;height:6px;border-radius:50%;background:#fff;opacity:.4;animation:blink2 1.2s infinite}

  #beginBtn .bdots i:nth-child(2){animation-delay:.2s}
#beginBtn .bdots i:nth-child(3){animation-delay:.4s}


  /* first-turn coachmark */
  .coachmark{margin-top:10px;font-size:13px;color:var(--go);font-weight:600;animation:fade .4s ease both}

  .coachmark[hidden]{display:none}

  /* "Take your time" think-window countdown. Deliberately quieter than the answer ring: this is a
     promise the examiner will not interrupt, not a clock the candidate is racing. */
  .thinkcd{margin-top:8px;font-size:13px;color:var(--muted,#8a8a8a);font-weight:500;animation:fade .4s ease both}
  .thinkcd b{font-variant-numeric:tabular-nums;font-weight:700;color:var(--go)}
  .thinkcd[hidden]{display:none}


  /* Dan (C7): the results page must fit one to one and a half screens. Stacked in a 640px column on a
     laptop it ran 1.5+ and read as a long strip of unrelated bands. Two columns: the band and its
     unlock on the left (the only thing they came back for), the upgrade and the follow-ups on the
     right. The order in the DOM is unchanged, so the phone still stacks band -> upgrade -> email. */
  /* Short laptop: the same two-column results card, just less air, so it stays inside Dan's 1.5. */
  

  /* social proof */
  /* Dan (C7): "one to one and a half screen heights". On a 393px phone this card ran 1.8 screens.
     The cuts are all rhythm and padding, never content: the four "discover" bullets (C9) and the
     upgrade card (C5) stay exactly as they are. */
  


  /* Laptop windows are wide but short (a 1000x570 viewport once Chrome's chrome is subtracted).
     The onboarding kept its full-height typography there, so the burgundy panel grew to ~974px, the
     page scrolled, and the right column centred itself against that height instead of lining up with
     the left. Scale the panel to the viewport it actually has. */
  /* Two columns of very different natural heights. Rather than cut Daniel's biography (B4) or the
     trust flow (B6) to make the hero fit a short laptop, let the hero scroll and pin the column that
     holds the call to action, so "Continue" is never below the fold. */
  


  


  


  /* Tighten the vertical rhythm so the CTA never lands below the fold. Keyed on HEIGHT as well as
     width: a 1000x570 laptop window is short for the same reason a phone is, and gating this on
     max-width alone left "Continue" and "Test my mic" off-screen on every laptop. */
  

  /* phones: compact onboarding header + right-sized exam room */
  
