/* intro.css — the three stages that now come before anything is asked of the applicant.
 *
 * THE OWNER, 2026-08-31: the film plays first with no writing over it; the system signature and the
 * exact network details are taken while it plays; it fades out completely; consent is taken; then a
 * narrated three-dimensional guide with a skip control; then one page the size of a selfie.
 *
 * ⛔ SIZED FOR A PHONE AND A DESKTOP FROM ONE RULE SET, because the owner asked for exactly that
 * and because two rule sets diverge. Everything below is fluid: the film is contained rather than
 * cropped, the consent column is capped in ch units so the line length stays readable at any width,
 * and the selfie stage is a square that takes the smaller of the two viewport axes so it is never
 * taller than the screen it is on.
 */

/* ── the film ─────────────────────────────────────────────────────────────────────────────────── */
#stepV{
  position:fixed; inset:0; z-index:60;
  display:flex; align-items:center; justify-content:center;
  background:#05070c;
  /* ⛔ NO TEXT OVER THE FILM. There is no caption, no title and no skip label here on purpose;
     the only control is an unlabelled speaker glyph, because the owner asked for the clip to play
     with nothing written on it. */
  opacity:1; transition:opacity .9s ease;
}
#stepV.gone{ opacity:0; pointer-events:none; }
#introVid{
  width:100%; height:100%;
  /* contain, not cover: cropping a produced film to fill a phone throws away the composition */
  object-fit:contain; background:#05070c; display:block;
}
#introSnd{
  position:absolute; inset-inline-end:16px; inset-block-end:16px;
  width:44px; height:44px; border-radius:50%;
  border:1px solid rgba(255,255,255,.28); background:rgba(8,12,20,.55);
  color:#e8eef7; font-size:19px; line-height:1; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
}
#introSnd:focus-visible{ outline:2px solid #7fb2ff; outline-offset:2px; }
/* the progress hairline is the only other thing on screen, and it carries no words */
#introBar{
  position:absolute; inset-inline:0; inset-block-end:0; height:2px;
  background:linear-gradient(90deg,#4f8cff,#7fe0c9); width:0; transition:width .2s linear;
}

/* ── the consent ──────────────────────────────────────────────────────────────────────────────── */
#stepC .cst-h{ font-size:clamp(19px,2.2vw,25px); margin:0 0 6px; }
#stepC .cst-lead{ color:#43506a; margin:0 0 18px; }
#stepC .cst-scroll{
  /* ⛔ CAPPED BY VIEWPORT, NOT BY PIXELS. A fixed max-height that fits a laptop leaves a phone with
     a two-line window; svh rather than vh so a mobile browser toolbar cannot cut it off. */
  max-height:min(52svh,520px); overflow-y:auto; overscroll-behavior:contain;
  border:1px solid #dde5f2; border-radius:12px; padding:16px 18px; background:#fbfdff;
}
#stepC .cst-scroll h3{ font-size:15px; margin:16px 0 4px; color:#16233a; }
#stepC .cst-scroll h3:first-child{ margin-top:0; }
#stepC .cst-scroll p{ margin:0 0 2px; color:#3a4760; line-height:1.75;
  /* the clauses are prose in eight scripts; ch keeps every one of them readable */
  max-width:78ch; }
#stepC .cst-agree{ display:flex; gap:10px; align-items:flex-start; margin:16px 0 4px; cursor:pointer; }
#stepC .cst-agree input{ margin-top:3px; width:18px; height:18px; flex:none; }
#stepC .cst-row{ display:flex; gap:10px; flex-wrap:wrap; margin-top:14px; }
#stepC .cst-no{ background:transparent; border:1px solid #cfd8e6; color:#5a6478; }

/* ── the narrated guide ───────────────────────────────────────────────────────────────────────── */
#stepG .g-bar{ display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:14px; }
#stepG .g-skip{ background:transparent; border:1px solid #cfd8e6; color:#5a6478; }
#stepG .g-prog{ flex:1; min-width:120px; height:4px; border-radius:99px; background:#e6ecf6; overflow:hidden; }
#stepG .g-prog i{ display:block; height:100%; width:0; background:linear-gradient(90deg,#4f8cff,#7fe0c9);
  transition:width .3s ease; }

/* ── one page the size of a selfie ────────────────────────────────────────────────────────────── */
/* ⛔ THE OWNER ASKED FOR A PAGE THE SIZE OF A SELFIE, and that is a square bounded by the SHORTER
   viewport axis. Bounding by width alone makes a tall phone scroll and a wide desktop enormous. */
#step3 #camwrap{
  /* ⛔ SIZED BY THE CARD, NOT THE SCREEN. min(92vw,...) measured the viewport while this element
     lives inside a padded card: on a 375px phone that made the wrapper 328px inside a 280px
     content box, so the camera hung 24px out of both sides of its own panel. 100% is the card. */
  width:min(100%,min(72svh,520px));
  height:min(100%,min(72svh,520px));
  aspect-ratio:1/1;
  margin-inline:auto;
}
/* ⛔ AND THE OFFSET MUST GO WITH THE SIZE.
   The base sheet places the video and the mesh at left:19px; top:19px inside a 248px
   wrapper, which is exactly right for the 210px circle it was written for: 19+210+19=248.
   Resizing them to 100% of a fluid wrapper without clearing that offset pushes both 19px
   right and 19px down, so the circle and its analysis overlay hang out of their own frame
   on two sides. Measured on a phone: wrapper 345px at x=15, camera 345px at x=34. */
/* ⛔ ONE GEOMETRY FOR EVERY LAYER IN THE CIRCLE.
   The base sheet places the video, the mesh and the face guide at left:19px; top:19px; 210x210 --
   exactly right for the 210-in-248 design it was written for -- and svg.ring carries hardcoded
   width="248" height="248" presentation attributes. When the wrapper became fluid only #cam and
   #mesh were brought with it, so on a phone the camera measured 328px centred at x=187 while the
   ring measured 234px centred at x=233 and the face guide was still 210px. Four rings, four sizes,
   three centres.
   Every layer now takes the wrapper's own box. CSS width/height also overrides the SVG's
   presentation attributes, which is what makes the ring finally agree with the circle. */
#step3 #cam,
#step3 #mesh,
#step3 .faceguide,
#step3 .ring,
#step3 #faceTarget{
  left:0; top:0; right:auto; bottom:auto;
  width:100%; height:100%;
}
#step3 #cam, #step3 #mesh{ object-fit:cover; }
#step3 .ring{ inset:0; }

/* ── one responsive rule set for the whole flow ───────────────────────────────────────────────── */
@media (max-width:560px){
  #stepC .cst-scroll{ padding:13px 14px; max-height:min(46svh,420px); }
  #stepC .cst-row .btn{ flex:1 1 100%; }
  #introSnd{ inset-inline-end:12px; inset-block-end:12px; }
}
@media (prefers-reduced-motion:reduce){
  #stepV{ transition:none; }
  #introBar{ transition:none; }
  #stepG .g-prog i{ transition:none; }
}

/* ⛔ A MUTED FILM CANNOT EXPLAIN ITSELF IN WORDS - the owner asked for nothing written over the
   clip. So the control pulses while the sound is off and stops the moment it is on: motion the eye
   catches, and not one character of text. */
@keyframes introNudge{
  0%,100%{ transform:scale(1);   box-shadow:0 0 0 0 rgba(127,224,201,.45); }
  50%    { transform:scale(1.08); box-shadow:0 0 0 10px rgba(127,224,201,0); }
}
#introSnd.nudge{ animation:introNudge 2.1s ease-out infinite; }
@media (prefers-reduced-motion:reduce){
  /* ⛔ AND SOMEBODY WHO ASKED FOR NO MOTION STILL HAS TO BE ABLE TO FIND IT, so the pulse becomes a
     steady ring rather than nothing at all. */
  #introSnd.nudge{ animation:none; box-shadow:0 0 0 3px rgba(127,224,201,.35); }
}
