/* =====================================================================
   RecruitBot recruitee portal — the candidate's phone.

   THE RULES THIS FILE KEEPS
   * One column, 100% width, nothing horizontal to scroll.
   * Tap targets at least 48px, and 16px type in every input — below
     that iOS zooms the page on focus and the form jumps away.
   * The submit button sits in a bar pinned to the bottom of the screen,
     above the home indicator, so it is reachable one-handed.

   THE LOOK IS personal-details.html's, AND THAT IS A DELIBERATE SPLIT
   FROM THE HR PORTAL.
     tokens.css states a colour rule: red is the frame, never a button,
     so that inside the content red can mean danger and nothing else.
     The HR portal keeps that. This portal does not: at the client's
     direction the candidate-facing screens wear the brand the legacy
     pages already wear — Fraunces headings, Manrope body, a red primary
     button with its hard drop-shadow.

     Red is therefore NOT a danger colour here, and nothing in this
     portal may use it as one. The one red panel, .missing, is the
     legacy .error-banner and is for something that has gone wrong —
     not for an ordinary step somebody is halfway through. Red that
     turns up on a normal screen stops meaning anything by the time it
     is needed.

     The override block is the :root below plus the theme layer at the
     foot of this file, both marked. Delete those two and the portal
     goes back to the shared tokens.

   THE FONTS ARE FETCHED, which this portal otherwise never does.
     index.html loads Fraunces and Manrope from Google, the same way the
     legacy pages do. It is the one third-party origin here, it is
     `display=swap`, and the stacks below fall back to the system font,
     so a blocked or slow fetch costs the display face and nothing else.
     Self-hosting them is a strict improvement whenever somebody can
     download the two woff2 files.
   ===================================================================== */

/* ---- the legacy palette, over the shared tokens ---------------------- */
:root {
  --hl-red:        #D81E1E;
  --hl-red-deep:   #A81515;
  --hl-yellow:     #FDD400;
  --hl-ink:        #1A0F0F;
  --hl-muted:      #6B5757;
  --hl-line:       rgba(26, 15, 15, .10);
  --hl-shadow:     0 2px 0 rgba(26,15,15,.08), 0 8px 24px rgba(26,15,15,.06);
  --hl-shadow-lg:  0 4px 0 var(--hl-red-deep), 0 12px 28px rgba(216,30,30,.25);

  /* The shared names every rule in this file already uses, pointed at
     the legacy values. Nothing below had to change to get the new
     colours; only the components that change SHAPE are restyled. */
  --page:      #FFFFFF;
  --panel:     #FFFFFF;
  --panel-2:   #FCFBFA;
  --shade:     #F2EEEA;
  --ink:       var(--hl-ink);
  --ink-2:     #3A2A2A;
  --muted:     var(--hl-muted);
  --line:      var(--hl-line);
  --brand-600: var(--hl-ink);     /* "primary" in the shared rules      */
  --brand-700: #000000;
  --brand-500: var(--hl-red);     /* focus ring                         */
  --brand-100: #FFF6CC;           /* soft yellow, for info chips        */
  --brand-800: var(--hl-ink);
  --brand-50:  #FBF8F4;
  --brand-200: var(--hl-line);
  --brand-300: rgba(26,15,15,.22);
  --on-brand:  #FFFFFF;
  --accent:    var(--hl-yellow);

  --font-sans: 'Manrope', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;

  --radius:    18px;
  --radius-sm: 12px;
  --scrim:     rgba(26,15,15,.45);
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font: 400 16px/1.55 var(--font-sans, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
  -webkit-text-size-adjust: 100%;
  overscroll-behavior-y: contain;
}

/* ---- the line that says something is happening ---------------------- */
.progress {
  position: fixed; inset: 0 auto auto 0; height: 3px; width: 0;
  background: var(--accent); z-index: 60; transition: width .3s ease, opacity .3s ease;
}
.progress.booting { width: 35%; opacity: 1; animation: creep 6s ease-out forwards; }
.progress.on { width: 85%; opacity: 1; }
@keyframes creep { to { width: 70%; } }

/* ---- app bar: the only red surface ---------------------------------- */
.appbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 10px;
  padding: max(10px, env(safe-area-inset-top)) 16px 10px;
  background: var(--hl-red); color: #fff;
}
.appbar .mark { display: block; width: 34px; height: 34px; }
.appbar .wordmark { font-weight: 800; letter-spacing: .04em; font-size: 1rem; }
.appbar .wordmark b { color: var(--hl-yellow); font-weight: 800; }
.appbar .tag {
  margin-left: auto; font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  border: 1px solid rgba(255,255,255,.55); border-radius: 999px; padding: 3px 10px;
}

/* ---- page ------------------------------------------------------------ */
.wrap {
  max-width: 560px; margin: 0 auto;
  padding: 20px 16px calc(112px + env(safe-area-inset-bottom));
}
h1 { font-size: 1.5rem; line-height: 1.25; margin: 4px 0 8px; letter-spacing: -.01em; }
.lede { color: var(--ink-2); margin: 0 0 20px; }
.eyebrow {
  margin: 0; font-size: .75rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.steprow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.link {
  background: none; border: 0; padding: 0; font: inherit; font-size: .85rem;
  color: var(--brand-600); text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}

/* ---- fields ---------------------------------------------------------- */
.field { margin: 0 0 18px; }
.field.off { opacity: .45; }
.field.hidden { display: none; }
.lbl { display: block; font-weight: 650; margin-bottom: 2px; }
.hint { margin: 0 0 8px; color: var(--muted); font-size: .875rem; }

.input, .select {
  width: 100%; min-height: 52px;
  padding: 13px 14px;
  font-size: 16px;                      /* never smaller: iOS zooms below 16 */
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: 14px;
  appearance: none;
}
.input:focus, .select:focus, .seg:focus-visible, .cta:focus-visible {
  outline: 2px solid var(--brand-500); outline-offset: 2px;
}
.select-wrap { position: relative; }
.select-wrap::after {
  content: ""; position: absolute; right: 16px; top: 50%; width: 9px; height: 9px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: translateY(-70%) rotate(45deg); pointer-events: none;
}
.select:disabled { background: var(--shade); }

.phone { display: grid; grid-template-columns: 8.5rem 1fr; gap: 8px; }
.phone .dial .select { padding-right: 28px; }

.check { display: flex; gap: 12px; align-items: flex-start; margin: 4px 0 8px; }
.check input { width: 24px; height: 24px; margin: 2px 0 0; accent-color: var(--brand-600); }
/* A second line under a consent label, for the one that is optional.
   Block, so it sits under the sentence rather than running on from it. */
.check .hint { display: block; margin: 2px 0 0; }

/* ---- what they can change about us ----------------------------------- */
.prefs { margin-top: 28px; padding-top: 16px; border-top: 1px solid var(--line); }
.prefs-title { margin: 0 0 10px; font-size: .9375rem; font-weight: 600; color: var(--ink-2); }
.prefs .check input:disabled { opacity: .5; }

/* ---- yes / no -------------------------------------------------------- */
.segmented { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.seg {
  min-height: 52px; font: inherit; font-weight: 600;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 14px; cursor: pointer;
}
.seg.on { background: var(--brand-600); border-color: var(--brand-600); color: var(--on-brand); }

/* ---- restaurant chips ------------------------------------------------ */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.chip.pick {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--brand-100); color: var(--brand-800);
  border-radius: 999px; padding: 7px 8px 7px 14px; font-size: .9rem;
}
.chip.pick .x {
  border: 0; background: none; color: inherit; font-size: 1.1rem; line-height: 1;
  width: 24px; height: 24px; border-radius: 999px; cursor: pointer;
}
.options { display: none; margin-top: 8px; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--panel); }
.options.show { display: block; }
.opt {
  display: block; width: 100%; text-align: left; font: inherit;
  padding: 14px; background: var(--panel); border: 0; border-bottom: 1px solid var(--line); cursor: pointer;
}
.opt:last-child { border-bottom: 0; }
.opt.add { color: var(--brand-600); font-weight: 600; }

/* ---- steps ----------------------------------------------------------- */
.steps { list-style: none; margin: 8px 0 0; padding: 0; }
.step {
  display: flex; align-items: center; gap: 12px;
  padding: 14px; margin-bottom: 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
}
.step.tappable { cursor: pointer; border-color: var(--brand-300); }
.step .n {
  flex: none; width: 28px; height: 28px; border-radius: 999px;
  display: grid; place-items: center; font-size: .85rem; font-weight: 700;
  background: var(--shade); color: var(--ink-2);
}
.step.done .n { background: var(--ok-bg); color: var(--ok); }
.step.now  .n { background: var(--brand-600); color: var(--on-brand); }
.step .what { font-weight: 600; }
.step .chip {
  margin-left: auto; font-size: .75rem; font-weight: 700; letter-spacing: .04em;
  padding: 4px 10px; border-radius: 999px; background: var(--shade); color: var(--ink-2);
}
.step .chip.done { background: var(--ok-bg); color: var(--ok); }
.step .chip.now  { background: var(--brand-100); color: var(--brand-800); }
.step .chip.fix  { background: var(--warn-bg); color: var(--warn); }
.step .chip.sent { background: var(--brand-50); color: var(--ink-2); }

/* ---- messages -------------------------------------------------------- */
.missing, .note {
  border-radius: 14px; padding: 12px 14px; margin: 0 0 16px; font-size: .95rem;
}
.missing { background: var(--warn-bg); color: var(--warn); border: 1px solid #f0d9b0; }
.missing ul { margin: 6px 0 0; padding-left: 18px; }
.note { background: var(--brand-50); border: 1px solid var(--brand-200); color: var(--ink); }

.summary {
  display: flex; align-items: center; gap: 10px;
  background: var(--ok-bg); color: var(--ok); font-weight: 600;
  border-radius: 14px; padding: 12px 14px; margin-bottom: 8px;
}
.done .tick {
  width: 64px; height: 64px; border-radius: 999px; margin: 8px 0 16px;
  display: grid; place-items: center; font-size: 2rem;
  background: var(--ok-bg); color: var(--ok);
}

/* "Do it again" on a screen whose whole message is "that is done".
   Below a rule and at the bottom, so it reads as the way out for someone
   who knows theirs went badly — not as a second thing to do. */
.redo {
  margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--line);
  text-align: center;
}
.redo .hint { margin: 0 0 12px; }
.redo .cta { margin: 0 auto; }

/* ---- the button, pinned where a thumb reaches ------------------------ */
.cta-wrap {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--page) 72%, transparent);
}
.cta {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; max-width: 528px; margin: 0 auto; min-height: 54px;
  font: inherit; font-weight: 700; font-size: 1.05rem;
  color: var(--on-brand); background: var(--brand-600);
  border: 0; border-radius: 16px; cursor: pointer;
}
.cta:disabled { background: var(--brand-300); cursor: default; }
.cta.ghost { background: var(--panel); color: var(--brand-600); border: 1px solid var(--brand-300); }
.cta .arrow { font-size: 1.1em; }

/* ---- toasts ---------------------------------------------------------- */
.toasts {
  position: fixed; left: 50%; bottom: calc(84px + env(safe-area-inset-bottom));
  transform: translateX(-50%); z-index: 70;
  display: flex; flex-direction: column; gap: 8px; width: min(92vw, 520px);
}
.toast {
  background: var(--chrome-deep); color: #fff; border-radius: 12px;
  padding: 12px 14px; font-size: .95rem; box-shadow: 0 10px 30px rgba(0,0,0,.25);
  transition: opacity .4s ease, transform .4s ease;
}
.toast.bad  { background: var(--danger-deep); }
.toast.warn { background: var(--warn); }
.toast.out  { opacity: 0; transform: translateY(6px); }

/* ---- bigger screens: the same one column, just centred --------------- */
@media (min-width: 720px) {
  .wrap { padding-top: 32px; }
  .cta-wrap { position: static; background: none; padding: 8px 0 40px; }
  .wrap { padding-bottom: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---- the application form -------------------------------------------
   Rendered from hr.compiled_form: the styles below are the whole visual
   vocabulary the nine migrated forms need. */

.input.area { min-height: 110px; resize: vertical; line-height: 1.45; }

/* More than two choices stack, so a long option is never squeezed. */
.segmented.many { grid-template-columns: 1fr; }

/* The terms. Scrollable rather than endless, and reachable by keyboard
   (tabindex) so it is not a trap for anyone not using a touchscreen. */
.terms {
  max-height: 46vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 16px; margin-bottom: 8px;
  font-size: .95rem; line-height: 1.5; color: var(--ink-2);
}
.terms p { margin: 0 0 .8em; }
.terms strong { color: var(--ink); }
.terms:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }

/* "We already have this" — sensitive answers the server will not send
   back. Green, because it is reassurance, not a warning. */
.hint.held { color: var(--ok); font-weight: 600; }

/* Back beside Next, both still full-width targets on a phone. */
.cta-row { display: flex; gap: 10px; max-width: 528px; margin: 0 auto; }
.cta-row .cta { flex: 1 1 auto; }
.cta-row .cta.ghost { flex: 0 1 38%; }

/* ---- their own copy of the application, ready to print ---------------
   The same sheet a recruiter prints, without the sensitive answers. On a
   phone "Save as PDF" is the browser's print dialogue, which is where
   people keep documents; there is no PDF library here and no round trip.
   The private answers are not withheld for tidiness — the server never
   sends them to a phone at all. */

.paper {
  display: block;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 16px;
  padding: 18px 16px; margin-bottom: 12px;
}
.paper-head { display: flex; gap: 12px; align-items: flex-start; border-bottom: 2px solid var(--hl-red); padding-bottom: 10px; }
.paper-mark { flex: none; }
.paper-head h2 { margin: 0 0 2px; font-size: 1.1rem; }
.paper-meta { font-size: .82rem; color: var(--ink-2); line-height: 1.5; }

.paper-section { margin-top: 14px; }
.paper-section h3 {
  margin: 0 0 8px; padding: 5px 9px;
  font-size: .72rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--brand-800); background: var(--brand-50);
  border-left: 3px solid var(--hl-red); border-radius: 4px;
}
.paper-field { padding: 5px 0; border-bottom: 1px dotted var(--line); }
.paper-field .k { font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.paper-field .v { font-size: .95rem; white-space: pre-wrap; word-break: break-word; }
.paper-field .v.none { color: var(--muted); font-style: italic; }
.paper-foot { margin: 14px 0 0; font-size: .78rem; color: var(--muted); }

.centre { text-align: center; margin: 4px 0 0; }

@page { size: A4 portrait; margin: 14mm; }

@media print {
  .appbar, .progress, .toasts, .cta-wrap, .no-print, .steprow { display: none !important; }
  html, body { background: #fff !important; }
  .wrap { padding: 0 !important; max-width: none !important; }
  .paper { border: 0; border-radius: 0; padding: 0; }
  .paper-section { break-inside: auto; }
  .paper-section h3 { break-after: avoid; }
  .paper-field { break-inside: avoid; }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
}

/* ---- uploads ---------------------------------------------------------
   One card per document, each with its own state. A single "upload
   everything" control is how people send the wrong file twice. */

/* display:block IS NOT DECORATION HERE.
   A <div> is block already, so this reads like a no-op — and it was,
   until the contract screen put this class on a <label>. A label is
   INLINE, and an inline box containing a block-level child (the .cta
   inside it is display:flex) is split by the browser into fragments:
   a stub above, the child, a stub below. Each stub is painted with this
   border and background, so two 15px rounded rectangles appeared at the
   left edge, overlapping the button. It looked like a layout bug with
   no cause in the markup, because the markup is fine. */
.upload {
  display: block;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 14px; margin-bottom: 12px;
}

/* Picking one file, with no card around it.
   The contract screen used .upload for this, which drew a bordered card
   around a single ghost button that has its own border — the card was
   redundant even once it stopped fragmenting. This is the wrapper that
   a <label> around a button actually needs. */
.filepick { display: block; margin: 0 0 12px; }
.upload.done { border-color: #bfe0cd; }
.upload.fix  { border-color: #f0d9b0; }

.upload-head { display: flex; align-items: flex-start; gap: 10px; }
.upload-head b { display: block; font-weight: 650; }
.upload-head small { color: var(--muted); font-size: .8rem; }
.upload-head .chip {
  margin-left: auto; flex: none;
  font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  padding: 4px 10px; border-radius: 999px; background: var(--shade); color: var(--ink-2);
}
.upload-head .chip.done { background: var(--ok-bg); color: var(--ok); }
.upload-head .chip.fix  { background: var(--warn-bg); color: var(--warn); }
.upload-head .chip.sent { background: var(--brand-50); color: var(--ink-2); }

.upload-note { margin: 8px 0 0; font-size: .9rem; color: var(--ink-2); }
.upload.fix .upload-note { color: var(--warn); }
.upload-note.busy { color: var(--brand-600); font-weight: 600; }

.upload-actions { display: flex; align-items: center; gap: 14px; margin-top: 12px; }
/* The file input is a label, so the whole button opens the camera — an
   <input type=file> styled as a button is smaller than a thumb. */
.cta.small { min-height: 46px; font-size: .95rem; width: auto; padding: 0 18px; margin: 0; }

/* ---- the voice interview ---------------------------------------------
   Two modes, one step. The recorder is a single big target and a timer;
   the live call is a status line and the transcript as it happens. */

.pick { display: grid; gap: 12px; margin-bottom: 16px; }
.pick-card {
  display: grid; grid-template-columns: 44px 1fr; grid-template-rows: auto auto;
  gap: 2px 14px; text-align: left; font: inherit; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 16px;
}
.pick-card:hover, .pick-card:focus-visible { border-color: var(--brand-300); }
.pick-icon { grid-row: 1 / 3; font-size: 1.6rem; line-height: 1; align-self: center; }
.pick-card b { font-size: 1.05rem; }
.pick-card small { color: var(--muted); line-height: 1.4; }

/* ---- the questions, all of them ---------------------------------------
   Grouped under their sections and on screen together, because an
   interview you can see the shape of is a different thing to answer than
   one that arrives a card at a time: you know how many are left, you can
   read ahead while you are thinking, and you can go back to one you
   rushed. The one they are on is marked, not isolated. */

.qlist { margin: 4px 0 18px; }
.qsec + .qsec { margin-top: 18px; }
.qsec-head {
  margin: 0 0 8px; font-size: .75rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.qs { list-style: none; margin: 0; padding: 0; counter-reset: none; }

.q { margin-bottom: 8px; }
.qbtn {
  display: grid; grid-template-columns: 30px 1fr; gap: 12px; align-items: start;
  width: 100%; text-align: left; font: inherit; cursor: pointer;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 14px; padding: 13px 14px;
}
.qn {
  width: 28px; height: 28px; border-radius: 999px; display: grid; place-items: center;
  font-size: .85rem; font-weight: 700; background: var(--shade); color: var(--ink-2);
}
.qt { line-height: 1.4; }

/* The one they are on: a red edge and a little more weight. Loud enough
   to find at a glance, quiet enough that the rest is still readable. */
.q.on .qbtn {
  border-color: var(--brand-400);
  box-shadow: inset 3px 0 0 var(--hl-red);
  background: var(--brand-50);
}
.q.on .qn { background: var(--brand-600); color: var(--on-brand); }
.q.on .qt { font-weight: 600; }

/* Answered: still readable — they may want to go back to one. */
.q.past .qbtn { background: var(--panel); }
.q.past .qt { color: var(--ink-2); }
.q.past .qn { background: var(--ok-bg); color: var(--ok); font-size: 0; }
.q.past .qn::after { content: "\2713"; font-size: .9rem; }

/* The recorder rides in the bottom bar with Send, so Stop is under their
   thumb however far down the list they have scrolled. */
.cta-wrap.tall { padding-top: 10px; }

/* ---- a screen with more than one action ------------------------------
   .cta-wrap is built for a STEP: one primary button, pinned to the
   bottom of the phone where a thumb is. The contract screen has three
   things a candidate can do — read it, sign it, or send back a photo of
   a signed one — and `position: fixed; bottom: 0` on each of them puts
   all three in the same place, where the topmost swallows the taps meant
   for the two underneath.

   Found by tests/contracts_ui.spec.mjs, which could not click "View and
   download" because a DISABLED Sign button was sitting on top of it —
   and since opening the contract is what unlocks signing, that was the
   whole screen deadlocked on a phone. Nothing about it looked wrong in a
   screenshot, which is the argument for the suite. */
.cta-wrap.inline { position: static; background: none; padding: 10px 0 0; }

.recbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  max-width: 528px; margin: 0 auto 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 10px 12px;
}
.recbar-text { flex: 1 1 8rem; min-width: 0; }
.recbar .hint { margin: 2px 0 0; font-size: .82rem; }
.recbar .rectime { margin: 0; }
.recbar .cta.small, .recbar .link { flex: 0 0 auto; }
.recbar.recording { border-color: var(--brand-300); }
/* Room for the taller bar, so the last question is never stuck behind it. */
.wrap.has-recbar { padding-bottom: calc(186px + env(safe-area-inset-bottom)); }

.recbtn {
  flex: 0 0 auto;
  width: 64px; height: 64px; border-radius: 999px; font-size: 1.4rem; line-height: 1;
  color: var(--on-brand); background: var(--brand-600); border: 0; cursor: pointer;
  box-shadow: 0 8px 24px rgba(58, 42, 37, .25);
}
/* Recording is the one place inside the page where red is right: it is
   the universal record colour, and it is not a destructive action. */
.recbtn.on { background: var(--hl-red); animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 50% { box-shadow: 0 8px 30px rgba(212, 35, 41, .55); } }
.rectime { font-size: 1.4rem; font-variant-numeric: tabular-nums; margin: 10px 0 2px; }
.recactions { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 10px; }

/* ---- the live call ---------------------------------------------------
   No transcript on the phone, and no label either. A candidate
   mid-interview should be listening and answering, not reading their own
   words back or watching a caption flip between "speaking" and
   "listening" every few seconds. Who is talking is obvious from the
   voice in their ear; the wave says the line is alive.

   The ribbons are drawn to the REAL audio — an analyser on the
   interviewer's playback and another on the microphone (assets/voice.js)
   — so nothing here is on a timer pretending to listen. */

.stage {
  display: grid; place-items: center; gap: 14px;
  padding: 10px 0 8px; min-height: 48vh; align-content: center;
}

/* Full bleed: the ribbon runs out past the page gutter the way it would
   on a call screen, rather than sitting in a box. */
.wave {
  display: block;
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  height: 180px;
}
@media (min-width: 560px) { .wave { height: 210px; } }

.stage-status { margin: 0; font-weight: 650; font-size: 1.05rem; }
.stage-hint { margin: -8px 0 0; color: var(--muted); text-align: center; max-width: 30ch; }

/* Said, not shown: the running call has no caption on screen, but a
   screen reader still has to be told who is talking. */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* The wave holds still on its own (see STILL in voice.js); it still
   swells with the voice, because that is information, not decoration. */

.cta.danger { background: var(--danger); }

/* ---- deleting their own data -----------------------------------------
   Set apart from the preference above it, and red only on the words that
   do the deleting. Red elsewhere in this portal means danger, so it is
   spent carefully. */
.erase-row { margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--line); }
.erase-row .hint { display: block; margin-top: 2px; }
.link.danger { color: var(--danger-deep); }
.cta.danger { background: var(--danger-deep); color: #fff; }
.cta.danger:disabled { background: var(--line); color: var(--muted); }
.cta-wrap .cta + .cta { margin-top: 8px; }


/* =====================================================================
   Contracts
   =====================================================================

   TOUCH-ACTION: NONE IS THE WHOLE THING. Without it a drag on the pad
   scrolls the page instead of drawing, so the signature works on a
   desktop and silently does nothing on the phone almost every candidate
   is holding. The dotted line is there so an empty pad reads as
   somewhere to sign rather than as a box that failed to load.
   ================================================================== */
.sigpad {
  width: 100%;
  max-width: 100%;
  height: 170px;
  display: block;
  margin: .4rem 0 .2rem;
  border: 1px dashed var(--line, #c9c6c2);
  border-radius: 10px;
  background: #fff;
  touch-action: none;
  cursor: crosshair;
}

/* The status word on a contract in the list. Tones match the chips the
   recruiter sees, so the two screens describe the same thing the same
   colour. */
.step .chip { margin-left: auto; }
.note.bad  { border-left: 3px solid var(--bad, #b3261e); }
.note.warn { border-left: 3px solid var(--warn, #b26b00); }
.note.ok   { border-left: 3px solid var(--ok, #1f7a44); }


/* =====================================================================
   THE THEME LAYER — personal-details.html's shapes
   ---------------------------------------------------------------------
   Everything above this line is the portal's structure, and it kept its
   class names. This block changes how those classes LOOK: the card
   shapes, the display face, the red button with its hard shadow, the
   step list and the sheet.

   It is appended rather than woven in, so it can be read in one piece
   and removed in one piece. Where it repeats a selector from above, it
   wins on source order, not on a specificity trick.
   ===================================================================== */

body { background: #fff; font-family: var(--font-sans); }

h1 {
  font-family: var(--font-display);
  font-weight: 800; font-size: 30px; line-height: 1.1; letter-spacing: -.02em;
  margin: 0 0 8px;
}
h2 { font-family: var(--font-display); font-weight: 800; letter-spacing: -.02em; }
.lede, .subtitle { color: var(--hl-muted); font-size: 15px; }

/* The banner strip the legacy pages open with. An <img> when there is
   one; the gradient is what shows while it loads or if it is missing,
   so the page never opens on a white gap. */
.banner {
  width: calc(100% - 32px); margin: 16px auto 0;
  aspect-ratio: 1668 / 360; border-radius: 14px; overflow: hidden; display: block;
  box-shadow: 0 4px 16px rgba(216,30,30,.12);
  background: linear-gradient(100deg, var(--hl-red) 0%, #b81717 100%);
}
.banner img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- controls: 60px, 2px, 18px, and the two-layer shadow ------------- */
.input, .select {
  min-height: 60px; padding: 0 20px;
  border: 2px solid var(--hl-line); border-radius: var(--radius);
  font-weight: 600; box-shadow: var(--hl-shadow);
}
.input::placeholder { color: #B5A8A8; font-weight: 500; }
.input:focus, .select:focus { border-color: var(--hl-red); outline: none; }
.input.has-value, .select.has-value { border-color: var(--hl-ink); }
textarea.input { padding: 16px 20px; min-height: 120px; }

.lbl {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .08em;
  margin-bottom: 10px; padding-left: 4px;
}
.hint { font-size: 13px; font-weight: 500; margin: -4px 4px 10px; }

.seg {
  min-height: 60px; border: 2px solid var(--hl-line); border-radius: var(--radius);
  box-shadow: var(--hl-shadow); font-weight: 700; font-size: 15px;
}
.seg:active { transform: translateY(1px); }
.seg.on { background: var(--hl-ink); border-color: var(--hl-ink); color: #fff; }
.seg.on::before { content: "\2713"; margin-right: 8px; color: var(--hl-yellow); font-weight: 800; }

/* ---- the red button, and its press ----------------------------------- */
.cta {
  height: 60px; min-height: 60px; border-radius: var(--radius);
  background: var(--hl-red); color: #fff;
  font-weight: 800; font-size: 17px; letter-spacing: .02em;
  box-shadow: var(--hl-shadow-lg); border: 0;
}
.cta:not(:disabled):active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--hl-red-deep), 0 4px 12px rgba(216,30,30,.2);
}
.cta:disabled { background: #D8CFC0; color: #fff; box-shadow: none; }
.cta.ghost {
  background: #fff; color: var(--hl-ink);
  border: 2px solid var(--hl-line); box-shadow: var(--hl-shadow);
}
.cta.ghost:not(:disabled):active { transform: translateY(1px); box-shadow: var(--hl-shadow); }
.cta-wrap { background: linear-gradient(to top, #fff 70%, rgba(255,255,255,0)); }

/* ---- messages -------------------------------------------------------- */
.note, .missing {
  border-radius: var(--radius-sm); padding: 15px 17px; font-size: 14px;
  font-weight: 600; line-height: 1.45;
}
.note { background: rgba(26,15,15,.04); border: 1.5px solid var(--hl-line); color: var(--hl-ink); }
.note b { display: block; margin-bottom: 3px; }
/* The legacy .error-banner. For something that has GONE WRONG — not for
   a step somebody is halfway through. See the note at the top. */
.missing {
  background: rgba(216,30,30,.08); border: 1.5px solid var(--hl-red); color: var(--hl-red-deep);
}

/* =====================================================================
   THE STEP LIST
   Icons, not numbers: with no prerequisite chain the order means
   nothing, so a column of 1..6 would be counting something that is not
   there. The yellow well is the legacy `.field-label .num` grown up.
   ===================================================================== */
.steps { margin: 0; padding: 18px 0 0; }
.step {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  min-height: 76px; padding: 14px 18px; margin-bottom: 12px;
  background: #fff; border: 2px solid var(--hl-line); border-radius: var(--radius);
  box-shadow: var(--hl-shadow); font: inherit; color: var(--hl-ink); cursor: pointer;
  transition: border-color .15s ease, transform .12s ease;
}
.step:active { transform: translateY(1px); }
.step.now { border-color: var(--hl-ink); }
.step.shut { box-shadow: none; background: var(--panel-2); border-style: dashed; cursor: pointer; }

.step .ico {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--hl-yellow); color: var(--hl-ink);
}
.step .ico svg { width: 22px; height: 22px; display: block; }
.step.done .ico { background: var(--hl-ink); color: #fff; }
.step.shut .ico { background: var(--shade); color: #B5A8A8; }

.step .what { flex: 1; min-width: 0; font-weight: inherit; }
.step .what b { display: block; font-weight: 800; font-size: 15.5px; line-height: 1.25; letter-spacing: -.01em; }
.step .what small { display: block; color: var(--hl-muted); font-size: 13px; font-weight: 500; margin-top: 1px; }

.step .chip {
  flex: none; margin-left: 0;
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 6px 10px; border-radius: 100px;
  background: rgba(26,15,15,.06); color: var(--hl-muted); white-space: nowrap;
}
.step .chip.done { background: rgba(26,15,15,.06); color: var(--hl-ink); }
.step .chip.now  { background: rgba(216,30,30,.08); color: var(--hl-red-deep); }
.step .chip.sent { background: rgba(26,15,15,.04); color: var(--hl-muted); }
.step .chip.fix  { background: rgba(216,30,30,.08); color: var(--hl-red-deep); }
.step .chip.shut { background: transparent; color: #B5A8A8; border: 1.5px solid var(--hl-line); }

/* =====================================================================
   THE STEP SHEET — tapping a step brings its detail up from the bottom
   ===================================================================== */
.scrim {
  position: fixed; inset: 0; z-index: 50; background: var(--scrim);
  opacity: 0; pointer-events: none; transition: opacity .22s ease;
}
.scrim.open { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 51;
  max-width: 560px; margin: 0 auto; max-height: 88vh;
  display: flex; flex-direction: column; background: #fff;
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -10px 50px rgba(26,15,15,.28);
  transform: translateY(102%);
  transition: transform .28s cubic-bezier(.22,1,.36,1);
  will-change: transform;
}
.sheet.open { transform: translateY(0); }
.sheet.dragging { transition: none; }

/* [hidden] HAS TO BE SAID OUT LOUD. The UA rule `[hidden]{display:none}`
   is author-beatable and `.sheet` sets `display:flex`, so hiding it did
   nothing: the panel stayed in the layout and the accessibility tree,
   parked off-screen at translateY(102%). It looked closed. */
.sheet[hidden], .scrim[hidden] { display: none; }

/* AND THE SAME TRAP, ONE ROW DOWN. `.step` is display:flex too, so the
   contracts card — which starts `hidden` and is revealed only once a
   contract exists — would otherwise sit in the list fully visible,
   showing an empty chip to every candidate who has none. Exactly the
   bug above, in a second place, which is why it is written here beside
   it rather than left for somebody to rediscover. */
.step[hidden] { display: none; }

.sheet-grab { flex: none; padding: 12px 0 4px; display: grid; place-items: center; touch-action: none; }
.sheet-grab span { display: block; width: 44px; height: 5px; border-radius: 100px; background: rgba(26,15,15,.14); }

.sheet-head {
  flex: none; display: flex; align-items: center; gap: 14px;
  padding: 6px 20px 16px; border-bottom: 2px solid var(--hl-line); touch-action: none;
}
.sheet-head .ico {
  flex: none; width: 48px; height: 48px; border-radius: 50%;
  display: grid; place-items: center; background: var(--hl-yellow); color: var(--hl-ink);
}
.sheet-head .ico svg { width: 24px; height: 24px; display: block; }
.sheet-head.done .ico { background: var(--hl-ink); color: #fff; }
.sheet-head.shut .ico { background: var(--shade); color: #B5A8A8; }
.sheet-head .titles { flex: 1; min-width: 0; }
.sheet-head h2 { font-size: 22px; line-height: 1.15; margin: 0; }
.sheet-head .chip {
  display: inline-block; margin-top: 5px;
  font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 100px;
  background: rgba(26,15,15,.06); color: var(--hl-muted);
}
.sheet-head .chip.done { color: var(--hl-ink); }
.sheet-head .chip.now  { background: rgba(216,30,30,.08); color: var(--hl-red-deep); }
.sheet-head .chip.shut { background: transparent; color: #B5A8A8; border: 1.5px solid var(--hl-line); }
.sheet-close {
  flex: none; align-self: flex-start; background: none; border: 0; padding: 6px;
  font: inherit; font-size: 14px; font-weight: 700; color: var(--hl-muted); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}

.sheet-body { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 18px 20px; }
.sheet-foot {
  flex: none; padding: 14px 20px calc(18px + env(safe-area-inset-bottom));
  border-top: 2px solid var(--hl-line); background: #fff;
}
/* Inside a sheet the action is in the footer, so a .cta-wrap in the body
   must not pin itself to the window. */
.sheet .cta-wrap { position: static; background: none; padding: 14px 0 0; max-width: none; }

.facts { list-style: none; margin: 0; padding: 0; }
.facts li { display: flex; gap: 16px; align-items: baseline; padding: 13px 0; border-bottom: 1.5px solid var(--hl-line); }
.facts li:last-child { border-bottom: 0; }
.facts .k { flex: 0 0 42%; color: var(--hl-muted); font-size: 14px; font-weight: 600; }
.facts .v { flex: 1; font-weight: 700; }

@media (prefers-reduced-motion: reduce) { .sheet, .scrim { transition: none; } }

/* =====================================================================
   PLACING YOUR OWN MARKS ON A CONTRACT (P8d) — assets/sign.js

   A full-height screen rather than a sheet, because the thing being
   read is a multi-page legal document and every pixel spent on chrome
   is a pixel not spent on it. Three bands: the tools at the top, the
   pages scrolling in the middle, the name and Finish pinned at the
   bottom.

   display:flex BEATS THE [hidden] ATTRIBUTE, which is why
   .sign-modal[hidden] is written out below. `hidden` sets
   `display: block` in the UA sheet and a `display: flex` rule in an
   author sheet wins — so a sheet that is laid out with flex and shown
   or hidden with el.hidden stays on screen for ever without it. This
   has bitten this platform twice; the rule is here, not inferred.
   ===================================================================== */

.sign-shell {
  display: flex; flex-direction: column;
  min-height: 100vh; min-height: 100dvh;
  background: var(--shade);
}

.sign-bar {
  flex: none; position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 12px;
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
  background: #fff; border-bottom: 2px solid var(--hl-line);
}
.sign-bar b { flex: 1; min-width: 0; font-size: 15px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.sign-count { flex: none; font-size: 13px; font-weight: 700; color: var(--hl-muted); }

.sign-lede { margin: 14px 16px 0; font-size: 14px; color: var(--ink-2); }

.sign-tools {
  flex: none; position: sticky; top: 52px; z-index: 2;
  display: flex; gap: 8px; padding: 12px 16px;
  background: var(--shade);
}
/* AND display:flex BEATS [hidden] HERE TOO. When the document will not
   open, sign.js hides the tools, the hint and the footer — pressing a
   tool with no pages under it does nothing, and a Finish that can never
   light up is a button somebody keeps pressing. Without this rule the
   tools stay on screen above the error. (.sign-hint and .sign-foot set
   no display of their own, so the UA rule reaches them.) */
.sign-tools[hidden] { display: none; }

.sign-tool {
  flex: 1; min-width: 0; padding: 11px 8px;
  font: inherit; font-size: 14px; font-weight: 700;
  background: #fff; color: var(--ink);
  border: 2px solid var(--hl-line); border-radius: 12px; cursor: pointer;
}
.sign-tool.on { background: var(--hl-ink); border-color: var(--hl-ink); color: #fff; }
.sign-hint { margin: 0 16px; font-size: 13px; color: var(--hl-muted); }

/* The pages. Centred, and each one its own stacking context so the
   mark layer sits over the canvas and nothing else. */
.sign-pages {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 16px;
}
.sign-pages .note { max-width: 420px; }

/* NO max-width AND NO height:auto HERE, deliberately.
   sign.js measures this column and sizes every page to fit it, so the
   width and height on the element are already correct and are a matched
   pair. A `max-width: 100%` would clamp the width and leave the height
   alone — an A4 page 388 wide and 1347 tall, the document squashed into
   a third of its aspect ratio, with every tap landing somewhere it was
   not. It was written that way first; this comment is the receipt. */
.sign-page {
  position: relative; flex: none;
  background: #fff; box-shadow: var(--hl-shadow);
  border-radius: 4px; overflow: hidden;
}
.sign-page canvas { display: block; }
.sign-pageno {
  position: absolute; right: 8px; bottom: 8px; z-index: 2;
  padding: 3px 8px; border-radius: 100px;
  background: rgba(26,15,15,.62); color: #fff;
  font-size: 11px; font-weight: 700; pointer-events: none;
}

/* The layer every tap lands on. It covers the page exactly, so a tap's
   offset inside it IS the position on the page — the conversion to PDF
   points happens once, in sign.js's toPdf(), and nowhere else.

   touch-action: none so dragging a placed mark moves the mark instead
   of scrolling the document underneath it. */
.sign-layer { position: absolute; inset: 0; z-index: 2; touch-action: none; }
/* Under the marks and deaf to the finger. See the note on .sign-hintbox
   and the two-layer comment in sign.js. */
.sign-hints { position: absolute; inset: 0; z-index: 1; pointer-events: none; }

.sign-mark {
  position: absolute; display: grid; place-items: center;
  border: 1.5px dashed transparent; border-radius: 4px;
  cursor: grab; touch-action: none;
}
.sign-mark img { width: 100%; height: 100%; object-fit: contain; display: block; }
.sign-mark span {
  font-size: 13px; font-weight: 600; color: #111;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sign-mark:hover, .sign-mark:focus-within { border-color: var(--hl-red); }
.sign-mark.dragging { border-color: var(--hl-red); cursor: grabbing; opacity: .85; }

.sign-x {
  position: absolute; top: -11px; right: -11px;
  width: 24px; height: 24px; padding: 0;
  display: grid; place-items: center;
  font: inherit; font-size: 15px; line-height: 1;
  background: var(--hl-red); color: #fff;
  border: 2px solid #fff; border-radius: 100px; cursor: pointer;
}

/* The resize handle: bottom-right, opposite the remove button, so a
   thumb reaching for one cannot land on the other.

   24px because it is dragged with a finger — the visible corner is
   smaller than the target, which is the point. `touch-action: none` so
   the drag resizes the mark instead of scrolling the contract under
   it, the same rule .sign-layer needs and for the same reason. */
.sign-size {
  position: absolute; right: -10px; bottom: -10px;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  cursor: nwse-resize; touch-action: none;
}
.sign-size::after {
  content: ""; display: block;
  width: 14px; height: 14px;
  background: #fff;
  border: 2px solid var(--hl-ink);
  border-radius: 3px;
}

/* A HINT IS NOT A TARGET. Drawn thin and pale and, crucially,
   pointer-events: none — a hint that swallowed the tap meant to place a
   mark on it would be a trap rather than a help. */
.sign-hintbox {
  position: absolute; pointer-events: none;
  display: grid; place-items: center;
  border: 1.5px dashed rgba(216,30,30,.55); border-radius: 4px;
  background: rgba(253,212,0,.10);
  font-size: 10px; font-weight: 700; color: var(--hl-red-deep);
  text-transform: uppercase; letter-spacing: .04em;
}

.sign-foot {
  flex: none; position: sticky; bottom: 0; z-index: 3;
  padding: 12px 16px calc(14px + env(safe-area-inset-bottom));
  background: #fff; border-top: 2px solid var(--hl-line);
}
.sign-foot input { margin-bottom: 10px; }
.sign-foot .cta { width: 100%; }
.sign-need { margin: 0 0 8px; font-size: 13px; font-weight: 700; }
.sign-need.warn { color: var(--hl-red-deep); }
.sign-need.ok { color: #1D6B33; }

/* The two dialogs: drawing a signature, and typing a line of text.
   Centred, not a bottom sheet — a signature pad pinned to the bottom of
   a phone is drawn on with the thumb of the hand holding it. */
.sign-modal {
  position: fixed; inset: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(26,15,15,.45);
}
/* See the note at the top of this block. Without this the dialogs never
   close. */
.sign-modal[hidden] { display: none; }
.sign-modal-card {
  width: 100%; max-width: 420px;
  padding: 20px; border-radius: 18px;
  background: #fff; box-shadow: var(--hl-shadow-lg);
}
.sign-modal-card h2 { margin: 0 0 6px; font-size: 20px; }
.sign-modal-card .lede { margin: 0 0 14px; font-size: 14px; }
.sign-modal-card .sigpad { width: 100%; height: 200px; }
