/* ══════════════════════════════════════════════════════════════════════════
   GRE PORTAL — additions on top of base.css (the Direct Walk design system)
   Same palette, same motion language, same component grammar.
   ══════════════════════════════════════════════════════════════════════════ */

:root{
  --amber:#e67e22;
  --blue:#2563eb;
  --r-lg:18px;
}
[data-theme="dark"]{ --amber:#f0a24b; --blue:#5b8def; }

/* wider portal — the audit page carries more content than the walk-in form */
.portal{max-width:clamp(360px,72vw,940px)}
@media(min-width:1400px){.portal{max-width:1020px}}

/* ══ PRELOADER — version stamp ══ */
.pre-ver{letter-spacing:.06em}
.pre-upd{font-size:clamp(.5rem,.72vw,.6rem);font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--c);background:var(--c-lt);border:1px solid var(--border);padding:4px 12px;border-radius:99px;
  margin-top:2px;opacity:0;animation:fUp .5s .5s forwards}

/* ══ STEP BAR — 6 steps, scrolls rather than crushes ══ */
.steps-bar{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
.steps-bar::-webkit-scrollbar{display:none}
.step-lbl{max-width:none}
@media(max-width:820px){ .step-lbl{display:none} .step-item{flex:1} }

/* ══ MASKED FIELD ══════════════════════════════════════════════════════════
   The visible <input> only ever holds the masked string. The true value lives
   in a JS-side store, so a copy out of the field yields the mask, not the
   number. .f-masked is the ghost badge that marks such a field.
   ═══════════════════════════════════════════════════════════════════════════ */
.f-inp.masked{letter-spacing:.06em;font-variant-numeric:tabular-nums}
.mask-badge{position:absolute;right:clamp(56px,7vw,74px);top:50%;transform:translateY(-50%);
  display:flex;align-items:center;gap:4px;font-size:clamp(.48rem,.68vw,.56rem);font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--c);background:var(--c-lt);
  border:1px solid var(--border);padding:2px 7px;border-radius:99px;pointer-events:none;
  opacity:0;transition:opacity .25s}
.mask-badge.show{opacity:1}
.mask-badge svg{width:9px;height:9px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}

/* peek button — hold to reveal, never a persistent unmask */
.f-peek{position:absolute;right:clamp(9px,1.1vw,12px);width:clamp(15px,1.8vw,18px);height:clamp(15px,1.8vw,18px);
  color:var(--text-3);cursor:pointer;background:none;border:none;padding:0;display:flex;
  align-items:center;justify-content:center;transition:color .2s;z-index:2}
.f-peek:hover{color:var(--c)}
.f-peek svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.f-wrap.has-peek .f-tick{right:clamp(30px,3.6vw,38px)}
/* narrow screens: the badge would crowd the value, so drop to the lock alone */
@media(max-width:560px){
  .mask-badge{right:clamp(50px,12vw,60px);padding:2px 5px;font-size:.46rem}
  .mask-badge span{display:none}
}

/* ══ REPEATER — extra mobile numbers / emails ══ */
.rep-list{display:flex;flex-direction:column;gap:clamp(6px,1vh,10px)}
.rep-row{display:flex;align-items:flex-start;gap:8px;animation:fUp .32s}
.rep-row .field{flex:1;min-width:0}
.rep-del{width:clamp(30px,3.6vw,38px);height:clamp(30px,3.6vw,38px);flex-shrink:0;margin-top:22px;
  background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm);color:var(--text-3);
  display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s}
.rep-del:hover{background:rgba(240,68,56,.10);border-color:var(--red);color:var(--red)}
[data-theme="dark"] .rep-del:hover{background:#3a1d1d}
.rep-del svg{width:46%;height:46%;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

.btn-add{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;
  padding:clamp(6px,1vh,9px) clamp(11px,1.6vw,16px);background:var(--c-lt);color:var(--c);
  font-family:'Plus Jakarta Sans',sans-serif;font-size:clamp(.62rem,.9vw,.72rem);font-weight:700;
  border:1.5px dashed var(--c);border-radius:var(--r-sm);cursor:pointer;transition:all .2s}
.btn-add:hover{background:var(--c);color:#fff;border-style:solid}
.btn-add:disabled{opacity:.4;cursor:not-allowed}
.btn-add:disabled:hover{background:var(--c-lt);color:var(--c);border-style:dashed}
.btn-add svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}

/* ══ OPTION TILES — requirement / source / preference ══ */
.opt-grid{display:grid;gap:clamp(7px,1.2vh,12px)}
.opt-grid.col2{grid-template-columns:repeat(2,1fr)}
.opt-grid.col3{grid-template-columns:repeat(3,1fr)}
.opt-grid.col4{grid-template-columns:repeat(4,1fr)}
/* Five size bands, as one row on the desk screen — the same row the printed
   enquiry form puts them in. Reflows to 3 then 2 rather than shrinking five
   tiles into an unreadable strip on a phone. */
.opt-grid.col5{grid-template-columns:repeat(5,1fr)}
@media(max-width:900px){.opt-grid.col5{grid-template-columns:repeat(3,1fr)}}
@media(max-width:640px){.opt-grid.col4{grid-template-columns:repeat(2,1fr)}
  .opt-grid.col5{grid-template-columns:repeat(2,1fr)}}
/* A 3-up grid reflowed to 2 columns leaves a lone tile on the second row,
   which reads as a mistake. Stack it instead — bigger tap targets too. */
@media(max-width:640px){.opt-grid.col3{grid-template-columns:1fr}}

.opt{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;padding:clamp(10px,1.7vh,16px) clamp(6px,1vw,10px);background:var(--card);
  border:1.5px solid var(--border);border-radius:var(--r-sm);cursor:pointer;text-align:center;
  transition:border-color .2s,background .2s,transform .15s,box-shadow .2s;user-select:none}
.opt:hover{border-color:var(--c);background:var(--c-lt);transform:translateY(-2px)}
.opt.sel{border-color:var(--c);background:var(--c-lt);box-shadow:0 0 0 3px var(--c-glow)}
.opt-ico{width:clamp(20px,2.6vw,26px);height:clamp(20px,2.6vw,26px);color:var(--text-3);transition:color .2s}
.opt-ico svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.opt.sel .opt-ico{color:var(--c)}
.opt-txt{font-size:clamp(.65rem,.92vw,.76rem);font-weight:600;color:var(--text-2);line-height:1.3}
.opt.sel .opt-txt{color:var(--c);font-weight:700}
.opt-sub{font-size:clamp(.5rem,.72vw,.6rem);color:var(--text-3);line-height:1.3}
.opt-check{position:absolute;top:6px;right:6px;width:15px;height:15px;border-radius:50%;background:var(--c);
  display:flex;align-items:center;justify-content:center;opacity:0;transform:scale(.4);transition:all .22s}
.opt.sel .opt-check{opacity:1;transform:scale(1)}
.opt-check svg{width:9px;height:9px;fill:none;stroke:#fff;stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}

/* ══ RANGE — budget ══ */
.range-wrap{display:flex;flex-direction:column;gap:8px}
.range-val{font-size:clamp(1.05rem,2.1vw,1.45rem);font-weight:800;color:var(--c);font-variant-numeric:tabular-nums}
.range-val small{font-size:.55em;font-weight:600;color:var(--text-3);margin-left:4px}
input[type=range].rng{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:99px;
  background:linear-gradient(90deg,var(--c) var(--pct,0%),var(--border) var(--pct,0%));outline:none;cursor:pointer}
input[type=range].rng::-webkit-slider-thumb{-webkit-appearance:none;width:20px;height:20px;border-radius:50%;
  background:var(--c);border:3px solid var(--card);box-shadow:0 2px 8px var(--c-glow);cursor:pointer;transition:transform .15s}
input[type=range].rng::-webkit-slider-thumb:hover{transform:scale(1.15)}
input[type=range].rng::-moz-range-thumb{width:20px;height:20px;border-radius:50%;background:var(--c);
  border:3px solid var(--card);box-shadow:0 2px 8px var(--c-glow);cursor:pointer}
.range-ends{display:flex;justify-content:space-between;font-size:clamp(.52rem,.74vw,.62rem);color:var(--text-3);font-weight:600}

/* ══ AUDIT PANEL ══════════════════════════════════════════════════════════ */
.audit-card{border:1.5px solid var(--border);border-radius:var(--r-sm);overflow:hidden;background:var(--card);animation:fUp .38s}
.audit-hd{display:flex;align-items:center;gap:9px;padding:clamp(9px,1.4vh,13px) clamp(11px,1.6vw,16px);
  background:var(--c-lt);border-bottom:1.5px solid var(--border)}
.audit-hd-ico{width:clamp(24px,3vw,30px);height:clamp(24px,3vw,30px);border-radius:8px;background:var(--c);
  display:flex;align-items:center;justify-content:center;flex-shrink:0}
.audit-hd-ico svg{width:56%;height:56%;fill:none;stroke:#fff;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.audit-hd-txt{flex:1;min-width:0}
.audit-hd-num{font-size:clamp(.76rem,1.1vw,.9rem);font-weight:800;color:var(--text);font-variant-numeric:tabular-nums}
.audit-hd-sub{font-size:clamp(.52rem,.74vw,.62rem);color:var(--text-3);margin-top:1px}

.verdict{display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:99px;
  font-size:clamp(.55rem,.78vw,.65rem);font-weight:800;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0}
.verdict svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.verdict.fresh{background:rgba(18,183,106,.12);color:var(--green);border:1px solid rgba(18,183,106,.3)}
.verdict.exists{background:rgba(230,126,34,.12);color:var(--amber);border:1px solid rgba(230,126,34,.3)}
.verdict.dup{background:rgba(240,68,56,.12);color:var(--red);border:1px solid rgba(240,68,56,.3)}
.verdict.unknown{background:var(--bg);color:var(--text-3);border:1px solid var(--border)}

.audit-body{padding:clamp(10px,1.6vh,15px) clamp(11px,1.6vw,16px);display:flex;flex-direction:column;gap:clamp(8px,1.3vh,13px)}
.audit-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(6px,1vw,10px)}
@media(max-width:640px){.audit-stats{grid-template-columns:repeat(2,1fr)}}
.astat{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);padding:clamp(7px,1.2vh,11px) clamp(7px,1vw,11px)}
.astat-k{font-size:clamp(.48rem,.68vw,.56rem);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-3)}
.astat-v{font-size:clamp(.82rem,1.3vw,1rem);font-weight:800;color:var(--text);margin-top:3px;font-variant-numeric:tabular-nums;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.astat-v.warn{color:var(--amber)}
.astat-v.ok{color:var(--green)}
.astat-v.bad{color:var(--red)}

/* follow-up timeline */
.tl{display:flex;flex-direction:column;gap:0;position:relative;padding-left:20px}
.tl::before{content:'';position:absolute;left:5px;top:6px;bottom:6px;width:2px;background:var(--border);border-radius:2px}
.tl-item{position:relative;padding:6px 0 6px 4px;animation:fUp .3s}
.tl-item::before{content:'';position:absolute;left:-19px;top:11px;width:8px;height:8px;border-radius:50%;
  background:var(--c);border:2px solid var(--card);box-shadow:0 0 0 2px var(--c-glow)}
.tl-when{font-size:clamp(.5rem,.7vw,.58rem);font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-3)}
.tl-what{font-size:clamp(.66rem,.92vw,.76rem);color:var(--text-2);line-height:1.45;margin-top:2px}
.tl-empty{font-size:clamp(.64rem,.9vw,.74rem);color:var(--text-3);font-style:italic;padding:6px 0}

/* audit loading skeleton */
.audit-load{display:flex;align-items:center;gap:10px;padding:clamp(14px,2.2vh,20px);
  border:1.5px dashed var(--border);border-radius:var(--r-sm);color:var(--text-3);
  font-size:clamp(.66rem,.92vw,.76rem);font-weight:600}
.audit-load svg{width:16px;height:16px;animation:spin360 .9s linear infinite;fill:none;stroke:var(--c);
  stroke-width:2.4;stroke-linecap:round}

/* ══ OTP ══════════════════════════════════════════════════════════════════ */
.otp-block{border:1.5px solid var(--border);border-radius:var(--r-sm);padding:clamp(10px,1.6vh,15px) clamp(11px,1.6vw,16px);
  display:flex;flex-direction:column;gap:clamp(8px,1.3vh,12px);background:var(--card)}
.otp-target{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.otp-target-num{font-size:clamp(.72rem,1.05vw,.86rem);font-weight:700;color:var(--text);font-variant-numeric:tabular-nums}
.otp-boxes{display:flex;gap:clamp(7px,1.1vw,11px);justify-content:center}
.otp-in{width:clamp(38px,5vw,52px);height:clamp(44px,6vw,60px);text-align:center;
  font-family:'Plus Jakarta Sans',sans-serif;font-size:clamp(1.1rem,2vw,1.5rem);font-weight:800;
  color:var(--text);background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm);
  outline:none;transition:all .18s;caret-color:var(--c)}
.otp-in:focus{border-color:var(--c);background:var(--card);box-shadow:0 0 0 3px var(--c-glow)}
.otp-in.filled{border-color:var(--c);color:var(--c);background:var(--c-lt)}
.otp-in.err{border-color:var(--red);animation:shake .38s}
.otp-in.ok{border-color:var(--green);color:var(--green);background:rgba(18,183,106,.08)}
.otp-meta{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.otp-timer{font-size:clamp(.56rem,.8vw,.66rem);font-weight:700;color:var(--text-3);font-variant-numeric:tabular-nums}
.otp-timer.low{color:var(--red)}
.btn-link{background:none;border:none;padding:0;font-family:'Plus Jakarta Sans',sans-serif;
  font-size:clamp(.58rem,.82vw,.68rem);font-weight:700;color:var(--c);cursor:pointer;text-decoration:underline;
  text-underline-offset:2px;transition:opacity .2s}
.btn-link:hover{opacity:.7}
.btn-link:disabled{color:var(--text-3);cursor:not-allowed;text-decoration:none}

/* ══ E-SIGN PAD ══════════════════════════════════════════════════════════ */
.sign-wrap{display:flex;flex-direction:column;gap:8px}
.sign-pad{position:relative;width:100%;height:clamp(130px,20vh,180px);background:var(--bg);
  border:1.5px dashed var(--border);border-radius:var(--r-sm);overflow:hidden;touch-action:none;transition:border-color .2s}
.sign-pad.inked{border-style:solid;border-color:var(--c);background:var(--card)}
.sign-pad.err{border-color:var(--red);animation:shake .38s}
.sign-pad canvas{display:block;width:100%;height:100%;cursor:crosshair;touch-action:none}
.sign-hint{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;pointer-events:none;color:var(--text-3);font-size:clamp(.64rem,.9vw,.74rem);font-weight:600;transition:opacity .25s}
.sign-pad.inked .sign-hint{opacity:0}
.sign-hint svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.sign-baseline{position:absolute;left:8%;right:8%;bottom:26%;height:1px;background:var(--border);pointer-events:none}
.sign-actions{display:flex;align-items:center;justify-content:space-between;gap:10px}
.sign-name{font-size:clamp(.56rem,.8vw,.66rem);color:var(--text-3)}
.sign-name b{color:var(--text-2)}

/* ══ ACTION ROWS — rating link, feedback schedule ══ */
.act-row{display:flex;align-items:center;gap:11px;padding:clamp(9px,1.5vh,14px) clamp(11px,1.6vw,16px);
  border:1.5px solid var(--border);border-radius:var(--r-sm);background:var(--card);transition:border-color .2s,background .2s}
.act-row.done{border-color:var(--green);background:rgba(18,183,106,.06)}
.act-row.queued{border-color:var(--amber);background:rgba(230,126,34,.06)}
.act-ico{width:clamp(28px,3.4vw,36px);height:clamp(28px,3.4vw,36px);border-radius:9px;background:var(--c-lt);
  color:var(--c);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .25s}
.act-row.done .act-ico{background:rgba(18,183,106,.15);color:var(--green)}
.act-row.queued .act-ico{background:rgba(230,126,34,.15);color:var(--amber)}
.act-ico svg{width:52%;height:52%;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.act-txt{flex:1;min-width:0}
.act-ttl{font-size:clamp(.68rem,.96vw,.78rem);font-weight:700;color:var(--text)}
.act-sub{font-size:clamp(.52rem,.74vw,.62rem);color:var(--text-3);margin-top:2px;line-height:1.4}
.btn-mini{padding:clamp(6px,1vh,9px) clamp(11px,1.6vw,16px);background:var(--c);color:#fff;
  font-family:'Plus Jakarta Sans',sans-serif;font-size:clamp(.6rem,.85vw,.7rem);font-weight:700;border:none;
  border-radius:var(--r-sm);cursor:pointer;transition:background .2s,transform .15s;white-space:nowrap;flex-shrink:0}
.btn-mini:hover{background:var(--c-dk);transform:translateY(-1px)}
.btn-mini:disabled{background:var(--border);color:var(--text-3);cursor:not-allowed;transform:none}
.btn-mini.ghost{background:var(--bg);color:var(--c);border:1.5px solid var(--c)}
.btn-mini.ghost:hover{background:var(--c-lt)}

/* ══ LOGS TABLE (final page) ══════════════════════════════════════════════ */
.log-wrap{border:1.5px solid var(--border);border-radius:var(--r-sm);overflow:hidden;background:var(--card)}
.log-scroll{overflow-x:auto;max-height:clamp(200px,34vh,340px);overflow-y:auto}
.log-tbl{width:100%;border-collapse:collapse;font-size:clamp(.6rem,.85vw,.7rem);white-space:nowrap}
.log-tbl th{position:sticky;top:0;z-index:1;background:var(--c-lt);color:var(--text-2);text-align:left;
  font-size:clamp(.5rem,.7vw,.58rem);font-weight:800;letter-spacing:.07em;text-transform:uppercase;
  padding:9px 12px;border-bottom:1.5px solid var(--border)}
.log-tbl td{padding:9px 12px;border-bottom:1px solid var(--border);color:var(--text-2);vertical-align:middle}
.log-tbl tr:last-child td{border-bottom:none}
.log-tbl tbody tr{transition:background .15s}
.log-tbl tbody tr:hover{background:var(--bg)}
.log-mask{font-variant-numeric:tabular-nums;letter-spacing:.04em;color:var(--text-3)}
.log-empty{padding:clamp(20px,4vh,36px);text-align:center;color:var(--text-3);font-size:clamp(.66rem,.92vw,.76rem)}
.pill{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:99px;
  font-size:clamp(.48rem,.68vw,.56rem);font-weight:800;letter-spacing:.05em;text-transform:uppercase}
.pill.ok{background:rgba(18,183,106,.12);color:var(--green)}
.pill.warn{background:rgba(230,126,34,.12);color:var(--amber)}
.pill.bad{background:rgba(240,68,56,.12);color:var(--red)}
.pill.info{background:var(--c-lt);color:var(--c)}

/* summary strip above the log table */
.log-sum{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(6px,1vw,10px)}
@media(max-width:640px){.log-sum{grid-template-columns:repeat(2,1fr)}}

/* ══ SHARE LINK BOX ══ */
.link-box{display:flex;align-items:center;gap:8px;padding:clamp(8px,1.3vh,12px) clamp(10px,1.5vw,14px);
  background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm)}
.link-txt{flex:1;min-width:0;font-size:clamp(.6rem,.85vw,.7rem);font-weight:600;color:var(--text-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,'SF Mono',Menlo,monospace}

/* ══ REVIEW LIST (page 5 summary before submit) ══ */
.rev{display:flex;flex-direction:column;border:1.5px solid var(--border);border-radius:var(--r-sm);overflow:hidden}
.rev-row{display:flex;align-items:flex-start;gap:10px;padding:clamp(7px,1.2vh,11px) clamp(11px,1.6vw,15px);
  border-bottom:1px solid var(--border)}
.rev-row:last-child{border-bottom:none}
.rev-row:nth-child(odd){background:var(--bg)}
.rev-k{flex:0 0 clamp(88px,15vw,150px);font-size:clamp(.55rem,.78vw,.64rem);font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);padding-top:1px}
.rev-v{flex:1;min-width:0;font-size:clamp(.68rem,.95vw,.78rem);font-weight:600;color:var(--text);
  line-height:1.45;word-break:break-word}
.rev-v.mask{font-variant-numeric:tabular-nums;letter-spacing:.04em}

/* ══ TOAST ══ */
#toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%,140%);z-index:2000;
  visibility:hidden;opacity:0;pointer-events:none;
  display:flex;align-items:center;gap:9px;padding:11px 18px;border-radius:99px;
  background:var(--text);color:#fff;font-size:clamp(.66rem,.92vw,.76rem);font-weight:600;
  box-shadow:0 10px 34px rgba(0,0,0,.28);max-width:90vw;
  transition:transform .38s cubic-bezier(.34,1.4,.64,1),opacity .25s,visibility .25s}
#toast.show{transform:translate(-50%,0);visibility:visible;opacity:1}
#toast svg{width:15px;height:15px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
#toast.ok{background:var(--green)}
#toast.bad{background:var(--red)}
[data-theme="dark"] #toast{background:var(--card);border:1px solid var(--border)}

/* ══ GRE identity strip in the header ══ */
.h-logo{width:clamp(32px,4.2vw,44px);height:clamp(32px,4.2vw,44px);border-radius:9px;overflow:hidden;
  background:rgba(255,255,255,.18);flex-shrink:0}
.h-logo img{width:100%;height:100%;object-fit:cover;display:block}

/* ══ small helpers ══ */
.stack{display:flex;flex-direction:column;gap:clamp(8px,1.3vh,13px)}
.row-between{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.muted{font-size:clamp(.55rem,.78vw,.65rem);color:var(--text-3);line-height:1.5}
.hidden{display:none !important}

/* ══ LAYOUT OVERRIDE ══════════════════════════════════════════════════════
   base.css sets html,body{height:100%}, which pins the document to exactly
   one viewport. The walk-in form's three short pages fitted; the GRE audit
   page does not, and the overflow was being clipped instead of scrolled.
   Let the document grow and keep the centring.
   ═══════════════════════════════════════════════════════════════════════════ */
html, body{ height:auto; min-height:100%; }
#app{ min-height:100vh; align-items:flex-start; }
.portal{ overflow:visible; border-radius:var(--r); }
.portal-head{ border-radius:var(--r) var(--r) 0 0; }
.portal-foot{ border-radius:0 0 var(--r) var(--r); background:var(--card); }
.page{ background:var(--card); }


/* On a phone the footer button sits where the toast lands, so the toast
   covers the very control it is telling you about. Move it to the top. */
@media(max-width:640px){
  #toast{bottom:auto;top:14px;transform:translate(-50%,-160%)}
  #toast.show{transform:translate(-50%,0)}
}

/* base.css has no disabled state for the primary buttons, so a disabled
   "Send feedback" still looked tappable — the customer presses it and nothing
   happens, which reads as the page being broken. */
.btn-sub:disabled, .btn-next:disabled, .btn-share:disabled{
  background:var(--border); color:var(--text-3); cursor:not-allowed;
  box-shadow:none; transform:none;
}
.btn-sub:disabled::before, .btn-next:disabled::before{display:none}
.btn-sub:disabled:hover, .btn-next:disabled:hover{background:var(--border); transform:none}

/* ══════════════════════════════════════════════════════════════════════════
   v3.0 — brand lockup, dual-channel OTP, investigate, custom budget
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Preloader with the real wordmark ── */
.pre-mark{width:clamp(140px,32vw,260px);max-width:70vw;animation:iPop .65s cubic-bezier(.34,1.56,.64,1) forwards;opacity:0}
.pre-mark img{width:100%;height:auto;display:block}
.pre-copy{font-size:clamp(.5rem,.72vw,.6rem);color:var(--text-3);margin-top:14px;
  opacity:0;animation:fUp .5s .9s forwards;text-align:center}

/* ── Header: the wordmark is wide, not square ── */
.h-logo.wide{width:auto;height:clamp(26px,3.4vw,36px);background:#fff;border-radius:7px;
  padding:5px 9px;display:flex;align-items:center}
.h-logo.wide img{width:auto;height:100%;object-fit:contain}
[data-theme="dark"] .h-logo.wide{background:rgba(255,255,255,.94)}

/* ── Gold accents — sparing, from the logo's accent square ── */
.pre-upd{color:var(--gold-dk);background:var(--gold-lt);border-color:var(--gold)}
.f-req{color:var(--gold-dk)}
[data-theme="dark"] .f-req{color:var(--gold)}
.prog-fill{background:linear-gradient(90deg,var(--c),var(--gold))}
.step-dot.active{box-shadow:0 0 0 3px var(--c-glow)}

/* ── OTP: two channels, one code ── */
.otp-target-mail{font-size:clamp(.58rem,.82vw,.68rem);color:var(--text-3);margin-top:2px;
  font-variant-numeric:tabular-nums}
.otp-channels{display:flex;flex-wrap:wrap;gap:7px}
.chan{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:99px;
  font-size:clamp(.52rem,.74vw,.62rem);font-weight:700;letter-spacing:.05em;
  background:var(--bg);border:1px solid var(--border);color:var(--text-3);transition:all .25s}
.chan::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--border)}
.chan.on{background:rgba(18,183,106,.10);border-color:rgba(18,183,106,.35);color:var(--green)}
.chan.on::before{background:var(--green)}
.chan.off{background:rgba(240,68,56,.10);border-color:rgba(240,68,56,.3);color:var(--red)}
.chan.off::before{background:var(--red)}
.chan.soon{background:var(--gold-lt);border-color:var(--gold);color:var(--gold-dk);font-style:italic}
.chan.soon::before{background:var(--gold)}
[data-theme="dark"] .chan.soon{color:var(--gold)}

/* ── Investigate ── */
.audit-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.btn-invest{display:inline-flex;align-items:center;gap:6px;
  padding:clamp(6px,1vh,9px) clamp(11px,1.6vw,16px);
  background:var(--gold-lt);color:var(--gold-dk);border:1.5px solid var(--gold);
  border-radius:var(--r-sm);font-family:'Plus Jakarta Sans',sans-serif;
  font-size:clamp(.6rem,.85vw,.7rem);font-weight:800;cursor:pointer;transition:all .2s;white-space:nowrap}
.btn-invest:hover{background:var(--gold);color:#3a2600}
.btn-invest:disabled{opacity:.45;cursor:not-allowed}
.btn-invest svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.3;stroke-linecap:round;stroke-linejoin:round}
[data-theme="dark"] .btn-invest{color:var(--gold)}

.lead-ids{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.lead-id{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:99px;
  background:var(--c-lt);color:var(--c);font-size:clamp(.52rem,.74vw,.62rem);font-weight:700;
  font-variant-numeric:tabular-nums;text-decoration:none;border:1px solid var(--border);transition:all .18s}
.lead-id:hover{background:var(--c);color:#fff;border-color:var(--c)}
.lead-id svg{width:9px;height:9px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}

/* one audit card per number */
.audit-set{display:flex;flex-direction:column;gap:clamp(8px,1.3vh,13px)}
.num-tag{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:99px;
  font-size:clamp(.48rem,.68vw,.56rem);font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  background:var(--bg);border:1px solid var(--border);color:var(--text-3)}
.num-tag.primary{background:var(--c-lt);border-color:var(--c);color:var(--c)}

/* investigate modal */
#investModal{position:fixed;inset:0;z-index:1500;background:rgba(20,23,58,.55);
  display:flex;align-items:center;justify-content:center;padding:18px;
  opacity:0;visibility:hidden;transition:opacity .28s,visibility .28s;backdrop-filter:blur(3px)}
#investModal.open{opacity:1;visibility:visible}
.invest-box{background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);
  width:100%;max-width:520px;max-height:86vh;overflow-y:auto;padding:clamp(18px,3vw,26px);
  transform:translateY(18px) scale(.97);transition:transform .32s cubic-bezier(.34,1.4,.64,1)}
#investModal.open .invest-box{transform:none}
.invest-hd{display:flex;align-items:flex-start;gap:11px;margin-bottom:14px}
.invest-ico{width:36px;height:36px;flex-shrink:0;border-radius:10px;background:var(--gold-lt);
  color:var(--gold-dk);display:flex;align-items:center;justify-content:center}
.invest-ico svg{width:52%;height:52%;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.invest-ttl{font-size:clamp(.92rem,1.5vw,1.08rem);font-weight:800;color:var(--text);line-height:1.3}
.invest-sub{font-size:clamp(.6rem,.85vw,.7rem);color:var(--text-3);margin-top:3px;line-height:1.5}
.invest-to{font-size:clamp(.56rem,.8vw,.66rem);color:var(--text-2);background:var(--bg);
  border:1px solid var(--border);border-radius:var(--r-sm);padding:9px 12px;line-height:1.7;margin-bottom:12px}
.invest-to b{color:var(--text)}
.invest-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:14px;flex-wrap:wrap}

/* ── Budget custom ── */
#budgetSlider.hidden{display:none}
.otp-block.err-block{border-color:var(--red);animation:shake .38s}
.otp-block.done{border-color:var(--green);background:rgba(18,183,106,.05)}

/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE — phone / tablet / laptop, portrait AND landscape
   ──────────────────────────────────────────────────────────────────────────
   The base design scales on width alone, which is fine until a phone is
   turned sideways: 390×844 becomes 844×390, the width rules relax back to
   "desktop" and every clamp() picks its large value inside 390px of height.
   The result is a header and a step bar eating half the screen with two
   fields visible below. These rules key off HEIGHT and ORIENTATION as well.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Short viewport: any device in landscape, or a small laptop ─────────── */
@media (max-height: 560px) {
  .portal-head   { padding-top: 8px; padding-bottom: 8px; }
  .h-logo.wide   { height: 22px; padding: 4px 7px; }
  .h-title       { font-size: .84rem; }
  .h-sub         { display: none; }
  .steps-bar     { padding-top: 5px; padding-bottom: 5px; }
  .step-dot      { width: 20px; height: 20px; font-size: .52rem; }
  .portal-body   { padding-top: 10px; padding-bottom: 10px; gap: 8px; }
  .portal-foot   { padding-top: 8px; padding-bottom: 8px; }
  .sec-lbl       { font-size: .55rem; }
  .opt           { padding: 7px 6px; gap: 3px; }
  .opt-ico       { width: 17px; height: 17px; }
  .sign-pad      { height: 96px; }
  .otp-in        { height: 40px; width: 34px; font-size: 1rem; }
  .pre-mark      { width: 150px; }
  .pre-trk       { margin-top: 8px; }
  .pre-copy      { margin-top: 8px; }
}

/* ── Phone in landscape: wide but very short ───────────────────────────── */
@media (orientation: landscape) and (max-height: 460px) {
  #app           { align-items: flex-start; padding: 6px; }
  .portal        { max-width: 100%; }
  /* Two columns of options rather than one tall stack */
  .opt-grid.col3 { grid-template-columns: repeat(3, 1fr); }
  .opt-grid.col4 { grid-template-columns: repeat(4, 1fr); }
  .opt-grid.col5 { grid-template-columns: repeat(5, 1fr); }
  .fgrid         { grid-template-columns: 1fr 1fr; }
  .f-full        { grid-column: 1 / -1; }
  .audit-stats   { grid-template-columns: repeat(4, 1fr); }
  .log-sum       { grid-template-columns: repeat(4, 1fr); }
  .rev-k         { flex-basis: 110px; }
  .steps-bar .step-lbl { display: none; }
  .sign-pad      { height: 84px; }
  #toast         { top: 8px; }
}

/* ── Tablet portrait (iPad ~768–1024) ──────────────────────────────────── */
@media (min-width: 641px) and (max-width: 1024px) and (orientation: portrait) {
  .portal        { max-width: 94vw; }
  .opt-grid.col4 { grid-template-columns: repeat(3, 1fr); }
  .opt-grid.col5 { grid-template-columns: repeat(3, 1fr); }
  .audit-stats   { grid-template-columns: repeat(2, 1fr); }
  .log-sum       { grid-template-columns: repeat(4, 1fr); }
  /* Comfortable touch targets on a tablet held in two hands */
  .btn-next, .btn-back, .btn-sub { padding: 13px 26px; font-size: .88rem; }
  .opt           { min-height: 62px; }
  .bhk-chip      { min-height: 60px; }
}

/* ── Tablet landscape ──────────────────────────────────────────────────── */
@media (min-width: 900px) and (max-width: 1280px) and (orientation: landscape) {
  .portal        { max-width: 88vw; }
  .audit-stats   { grid-template-columns: repeat(4, 1fr); }
}

/* ── Small phones, portrait ────────────────────────────────────────────── */
@media (max-width: 400px) {
  .otp-in        { width: 44px; height: 52px; font-size: 1.15rem; }
  .otp-boxes     { gap: 8px; }
  .rev-row       { flex-direction: column; gap: 2px; }
  .rev-k         { flex-basis: auto; }
  .audit-hd      { flex-wrap: wrap; }
  .verdict       { order: 3; width: 100%; justify-content: center; margin-top: 4px; }
  .invest-box    { padding: 16px 14px; }
  .invest-actions .btn-mini { flex: 1; text-align: center; }
}

/* ── Very wide desktop: stop the portal from becoming a stretched band ─── */
@media (min-width: 1600px) { .portal { max-width: 1080px; } }

/* ── Touch devices: no hover-lift, bigger hit areas ────────────────────── */
@media (hover: none) {
  .opt:hover, .chip:hover, .exec-card:hover, .bhk-chip:hover { transform: none; }
  .btn-mini, .btn-link { min-height: 34px; }
  .star, .mstar { -webkit-tap-highlight-color: transparent; }
}

/* ── Respect a reduced-motion preference ───────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* Landscape phones hide the on-screen keyboard behind fixed footers; letting
   the page scroll normally is more reliable than trying to out-clever it. */
@media (orientation: landscape) and (max-height: 500px) {
  .portal-foot { position: static; }
}

/* ══ TEST-MODE BANNER ══════════════════════════════════════════════════════
   Deliberately loud. A portal that says "code sent" while dry_run quietly
   swallows every message looks exactly like a broken SMS gateway — this is
   the difference between a five-second diagnosis and a lost afternoon. */
#dryBanner{position:sticky;top:0;z-index:900;display:flex;align-items:center;gap:10px;
  padding:10px clamp(12px,2.5vw,22px);background:var(--gold);color:#3a2600;
  font-size:clamp(.62rem,.9vw,.74rem);font-weight:600;line-height:1.45;
  box-shadow:0 2px 12px rgba(0,0,0,.12)}
#dryBanner svg{width:17px;height:17px;flex-shrink:0;fill:none;stroke:currentColor;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
#dryBanner b{font-weight:800;letter-spacing:.04em}
#dryBanner code{background:rgba(0,0,0,.12);padding:1px 5px;border-radius:4px;
  font-family:ui-monospace,Menlo,monospace;font-size:.94em}
body.dry .portal-head{box-shadow:inset 0 3px 0 var(--gold)}
@media(max-width:560px){#dryBanner{font-size:.6rem;padding:8px 12px}}
/* Missing credentials is a harder failure than test mode — make it red. */
#dryBanner.bad{background:var(--red);color:#fff}
#dryBanner.bad code{background:rgba(0,0,0,.2)}

/* A field that opens the picker. Looks like the inputs beside it, behaves
   like a button — no native dropdown wheel covering the question on a phone. */
.f-pick{
  width:100%;display:flex;align-items:center;gap:10px;
  padding:0 14px;min-height:46px;
  background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm);
  font-family:inherit;font-size:clamp(.72rem,1vw,.84rem);font-weight:600;
  color:var(--text);text-align:left;cursor:pointer;
  transition:border-color .2s,background .2s;
}
.f-pick:hover{border-color:var(--c-mid)}
.f-pick.picked{border-color:var(--green);background:var(--card)}
.f-pick.err{border-color:var(--red)}
.f-pick .f-ico{position:static;transform:none;display:flex;flex-shrink:0}
.f-pick .f-ico svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;color:var(--text-3)}
.f-pick-val{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.f-pick:not(.picked) .f-pick-val{color:var(--text-3);font-weight:500}
.f-pick .f-caret{position:static;display:flex;flex-shrink:0;color:var(--text-3)}
.f-pick .f-caret svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}

/* ══ THE PICKER ════════════════════════════════════════════════════════════
   The "Which platform?" question, floated over the page instead of sitting in
   a dropdown further down it. Same motion and surface as the investigate
   modal so the portal has one overlay language, not two. */
#pickModal{position:fixed;inset:0;z-index:1500;background:rgba(20,23,58,.55);
  display:flex;align-items:center;justify-content:center;padding:18px;
  opacity:0;visibility:hidden;transition:opacity .26s,visibility .26s;backdrop-filter:blur(3px)}
#pickModal.open{opacity:1;visibility:visible}
.src-box{background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);
  width:100%;max-width:460px;max-height:86vh;overflow-y:auto;padding:clamp(18px,3vw,24px);
  transform:translateY(16px) scale(.97);transition:transform .3s cubic-bezier(.34,1.4,.64,1)}
#pickModal.open .src-box{transform:none}
.src-hd{display:flex;align-items:flex-start;gap:11px;margin-bottom:14px}
.src-ico{width:36px;height:36px;flex-shrink:0;border-radius:10px;background:var(--c-lt);
  color:var(--c);display:flex;align-items:center;justify-content:center}
.src-ico svg{width:52%;height:52%;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.src-ttl{font-size:clamp(.92rem,1.5vw,1.06rem);font-weight:800;color:var(--text);line-height:1.3}
.src-sub{font-size:clamp(.6rem,.85vw,.7rem);color:var(--text-3);margin-top:3px;line-height:1.5}
.src-opts{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.src-opts .src-opt{padding:11px 10px;text-align:center}
@media(max-width:420px){.src-opts{grid-template-columns:1fr}}
#pickModal .invest-actions{margin-top:14px}
#pickSave.hidden{display:none}

/* The answer, shown under the source tiles once the popup closes. */
.src-picked{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 14px;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--bg);margin-top:-2px}
.src-picked.hidden{display:none}
.src-picked-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
.src-picked-k{font-size:clamp(.5rem,.7vw,.58rem);font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-3)}
.src-picked-v{font-size:clamp(.7rem,1vw,.82rem);font-weight:700;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* "Optional" next to the secondary mobile label — the field is on screen from
   the start now, so it has to say plainly that it need not be filled. */
.opt-tag{margin-left:6px;padding:1px 6px;border-radius:99px;background:var(--bg);
  border:1px solid var(--border);color:var(--text-3);
  font-size:.82em;font-weight:600;letter-spacing:.03em;text-transform:none}

/* ══ THE VISIT CLOCK ═══════════════════════════════════════════════════════
   Reads as an instrument, not a form field: one large figure that changes on
   its own, so a glance across the desk tells you whether the clock is running.
   The colour carries the state as well as the words — a GRE checking a second
   customer in should not have to read anything to see the first is still open. */
.clock-block{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:14px;padding:clamp(13px,2vh,18px) clamp(14px,2.2vw,20px);
  border:1px solid var(--border);border-radius:var(--r);background:var(--bg);
  transition:border-color .25s,background .25s}
.clock-block.live{border-color:var(--c);background:var(--c-lt)}
.clock-block.done{border-color:var(--green);background:rgba(18,183,106,.06)}
.clock-face{min-width:0}
.clock-state{font-size:clamp(.5rem,.7vw,.58rem);font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-3)}
.clock-block.live .clock-state{color:var(--c)}
.clock-block.done .clock-state{color:var(--green)}
.clock-time{font-size:clamp(1.5rem,3.6vw,2.1rem);font-weight:800;line-height:1.1;
  color:var(--text);font-variant-numeric:tabular-nums;letter-spacing:.02em;margin-top:2px}
.clock-block.live .clock-time{color:var(--c)}
.clock-sub{font-size:clamp(.58rem,.82vw,.68rem);color:var(--text-3);margin-top:4px;line-height:1.5}
.clock-actions{display:flex;gap:8px;flex-wrap:wrap}
.clock-actions .btn-mini svg{width:13px;height:13px;margin-right:5px}
.clock-actions .btn-mini:disabled{opacity:.45;cursor:not-allowed}
@media(max-width:520px){
  .clock-block{flex-direction:column;align-items:stretch}
  .clock-actions .btn-mini{flex:1;justify-content:center}
}

/* The verify block only wakes up at check-out. */
.otp-explain{font-size:clamp(.58rem,.82vw,.68rem);color:var(--text-3);line-height:1.55;
  margin:2px 0 10px;max-width:62ch}
.otp-block.armed{border-color:var(--c)}

/* ══ THE GRE SELFIE ════════════════════════════════════════════════════════ */
.selfie-block{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:14px;
  padding:clamp(12px,2vh,16px);border:1px solid var(--border);border-radius:var(--r);
  background:var(--bg);transition:border-color .25s}
.selfie-block.done{border-color:var(--green)}
.selfie-block.busy{opacity:.7;pointer-events:none}
@media(max-width:640px){.selfie-block{grid-template-columns:1fr}}
.selfie-stage{position:relative;aspect-ratio:4/3;border-radius:var(--r-sm);overflow:hidden;
  background:var(--card);border:1px solid var(--border);display:flex;align-items:center;justify-content:center}
.selfie-stage video,.selfie-stage canvas{width:100%;height:100%;object-fit:cover;display:block}
.selfie-stage video[hidden],.selfie-stage canvas[hidden]{display:none}
/* The preview is mirrored so the GRE sees themselves the way a mirror shows
   them; the captured frame is NOT, because a mirrored stamp is unreadable. */
.selfie-stage video{transform:scaleX(-1)}
.selfie-empty{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:9px;text-align:center;padding:16px;
  font-size:clamp(.62rem,.9vw,.74rem);font-weight:600;color:var(--text-3);line-height:1.5}
.selfie-empty svg{width:30px;height:30px;color:var(--text-3);opacity:.75}
.selfie-hint{font-weight:500;font-size:.9em;opacity:.85}
.selfie-side{display:flex;flex-direction:column;gap:10px;justify-content:center}
.selfie-geo{font-family:ui-monospace,Menlo,monospace;font-size:clamp(.56rem,.78vw,.66rem);
  line-height:1.5;color:var(--text-3);background:var(--card);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:9px 11px;word-break:break-word}
.selfie-geo.ok{color:var(--green);border-color:rgba(18,183,106,.35)}
.selfie-geo.warn{color:var(--gold-dk);border-color:rgba(244,170,28,.4);font-family:inherit}
.selfie-actions{display:flex;gap:8px;flex-wrap:wrap}
.selfie-actions .btn-mini{flex:1;justify-content:center;min-width:110px}
.selfie-upload{font-size:clamp(.56rem,.78vw,.64rem);color:var(--text-3);text-align:center}
.selfie-upload span{cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.selfie-upload span:hover{color:var(--c)}

/* A class rule with display: beats the browser's own [hidden] rule, so every
   element in these two blocks that is toggled by the hidden attribute needs to
   say so itself. Without this the "take a photo" placeholder stays painted over
   the photo that was just taken. */
.selfie-empty[hidden],
.selfie-block [hidden],
.clock-block [hidden]{display:none!important}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE PASS — v3.3
   The desk works on a phone or a tablet, standing, often one-handed, with a
   customer waiting. Three things follow from that and none of them are about
   how the page looks on a laptop.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Tap targets ───────────────────────────────────────────────────────
   A finger is not a mouse pointer. Apple asks for 44px, Android for 48dp; the
   portal's fields were 34–38px, which is fine to click and fiddly to tap —
   and a mis-tap at this desk means re-typing a mobile number in front of a
   customer. `pointer: coarse` is the honest test: it is true for touch and
   false for a mouse, so nothing changes on the laptop the log is read on. */
@media (pointer: coarse) {
  .f-inp, .f-sel        { min-height: 46px; }
  .f-wrap .f-ico        { top: 50%; transform: translateY(-50%); }
  .btn-mini, .btn-add,
  .btn-back, .btn-next,
  .btn-sub, .btn-link   { min-height: 46px; }
  .btn-link             { padding: 0 10px; }
  .rep-del              { width: 46px; height: 46px; }
  .opt                  { min-height: 56px; }
  .exec-card            { min-height: 60px; }
  .theme-toggle         { width: 42px; height: 42px; }
  .notes-ta             { min-height: 96px; }

  /* ── 2 · iOS zooms into any field whose text is under 16px ───────────────
     Safari ignores user-scalable=no, so a 13px input jumps the whole page to
     200% on focus and leaves the desk scrolling back out of it on every
     field. 16px is the threshold, and it is a threshold, not a preference. */
  .f-inp, .f-sel, .notes-ta, .otp-in,
  input[type="text"], input[type="number"], input[type="email"], textarea, select {
    font-size: 16px;
  }
}

/* ── 3 · Which step am I on? ───────────────────────────────────────────────
   Under 820px the step bar drops its labels and shows four bare circles. The
   numbers alone do not say what step 2 is, so the name goes underneath, where
   it costs one line. */
.step-now{display:none}
@media (max-width: 820px) {
  .step-now{
    display:block;text-align:center;padding:0 16px 9px;
    font-size:clamp(.62rem,2.6vw,.72rem);font-weight:700;letter-spacing:.04em;
    color:var(--c);background:var(--card);
  }
  .step-now span{color:var(--text-3);font-weight:600}
}

/* ── 4 · The visit log becomes cards on a phone ────────────────────────────
   Fifteen columns in a 360px window is a horizontal scrollbar the desk has to
   drag through to read one visit. Below 620px each row folds into a card with
   its own labels — same data, same order, no dragging. The table markup is
   untouched; only its display changes, so the laptop view is unaffected. */
@media (max-width: 620px) {
  .log-scroll{overflow-x:visible;max-height:none}
  .log-tbl, .log-tbl tbody, .log-tbl tr, .log-tbl td{display:block;width:100%}
  .log-tbl thead{display:none}
  .log-tbl{white-space:normal}
  .log-tbl tbody tr{
    border-bottom:1px solid var(--border);padding:10px 12px;
  }
  .log-tbl tbody tr:last-child{border-bottom:none}
  .log-tbl td{
    display:flex;align-items:baseline;justify-content:space-between;gap:12px;
    padding:5px 0;border:none;font-size:.78rem;
  }
  /* The label comes from the cell itself, so a new column cannot silently
     appear here unlabelled. */
  .log-tbl td::before{
    content:attr(data-l);flex:0 0 auto;
    font-size:.62rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
    color:var(--text-3);
  }
  .log-tbl td:empty{display:none}
  .log-tbl td.log-empty{justify-content:center;padding:18px 0}
  .log-tbl td.log-empty::before{content:none}
  /* The reference is the card's heading. */
  .log-tbl td[data-l="Ref"]{
    font-size:.92rem;font-weight:800;color:var(--text);
    border-bottom:1px solid var(--border);padding-bottom:8px;margin-bottom:4px;
  }
}

/* ── 5 · The selfie on a phone ─────────────────────────────────────────────
   One column, a camera preview tall enough to frame a face, and the fallback
   promoted from a footnote to a real button — on a phone it is usually the
   faster path, because it opens the camera app the GRE already knows. */
@media (max-width: 640px) {
  .selfie-stage{aspect-ratio:3/4;max-height:52vh}
  .selfie-actions{flex-direction:column}
  .selfie-actions .btn-mini{width:100%}
  .selfie-upload{
    display:block;border:1.5px dashed var(--border);border-radius:var(--r-sm);
    padding:13px 12px;background:var(--card);
  }
  .selfie-upload span{text-decoration:none;font-weight:700;color:var(--c)}
}

/* ── 6 · The clock, thumb-sized ────────────────────────────────────────────
   Check-out is the one button on this page that sends a message to a
   customer. It gets the full width and it sits below the reading, so a thumb
   reaching for it cannot land on Check in by mistake. */
@media (max-width: 520px) {
  .clock-time{font-size:2rem}
  /* Natural order — Check in on top, Check out beneath it. Reversing them put
     a disabled Check out above the button the GRE actually needs first. */
  .clock-actions{flex-direction:column;width:100%}
  .clock-actions .btn-mini{width:100%}
}

/* ── 7 · The budget slider, on a thumb ─────────────────────────────────────
   The track is 6px tall, which is a comfortable target for a mouse and an
   awkward one for a finger. The visible track stays 6px — the CONTROL grows
   to 44px of transparent grab area around it, and the handle grows with it.
   Nothing moves on screen; there is simply more of it to hit. */
@media (pointer: coarse) {
  input[type=range].rng{
    height:44px;background:none;border-radius:0;
  }
  input[type=range].rng::-webkit-slider-runnable-track{
    height:6px;border-radius:99px;
    background:linear-gradient(90deg,var(--c) 0%,var(--c) var(--pct,30%),var(--border) var(--pct,30%),var(--border) 100%);
  }
  input[type=range].rng::-moz-range-track{
    height:6px;border-radius:99px;background:var(--border);
  }
  input[type=range].rng::-moz-range-progress{height:6px;border-radius:99px;background:var(--c)}
  input[type=range].rng::-webkit-slider-thumb{
    width:26px;height:26px;margin-top:-10px;
  }
  input[type=range].rng::-moz-range-thumb{width:26px;height:26px}
}

/* ── The desk-only banner on step 2 ────────────────────────────────────────
   v3.4 moved the clock and the code entry off the customer's page and onto
   this one. The banner is the instruction that makes that worth doing: a code
   the customer can read off the screen is a code that tells them nothing was
   private. Gold, because it is a prompt to act, not a warning. */
.gre-only{
  display:flex;align-items:flex-start;gap:10px;
  padding:12px 14px;margin-bottom:4px;
  border:1.5px solid #e6c684;border-radius:var(--r-sm);background:var(--gold-lt);
  font-size:clamp(.62rem,.9vw,.73rem);line-height:1.55;color:var(--gold-dk);
}
.gre-only svg{width:18px;height:18px;flex-shrink:0;margin-top:1px}
.gre-only b{font-weight:800}

/* ══════════════════════════════════════════════════════════════════════════
   THE GRE PHOTO — v3.5 proportions
   The first build gave the camera a 4:3 box that stretched to whatever width
   the column had. On a laptop that is a 700px empty white rectangle next to a
   short column of controls, which reads as a broken image rather than a
   camera waiting to be opened. The stage is capped now and the two columns
   are balanced; on a phone it stacks and the preview turns portrait, because
   that is the shape a face actually is.
   ══════════════════════════════════════════════════════════════════════════ */
.selfie-block{
  grid-template-columns:minmax(0,380px) minmax(220px,1fr);
  align-items:start;gap:18px;
}
.selfie-stage{aspect-ratio:4/3;max-height:290px;margin:0}
.selfie-side{gap:12px;justify-content:flex-start;padding-top:2px}

/* What the stamp will say — three short lines, so the GRE knows what is being
   recorded before they press anything rather than after. */
.selfie-will{
  display:grid;gap:5px;font-size:clamp(.58rem,.82vw,.68rem);
  color:var(--text-3);line-height:1.5;
}
.selfie-will b{color:var(--text-2);font-weight:700}
.selfie-will div{display:flex;gap:7px;align-items:flex-start}
.selfie-will span{color:var(--c);flex-shrink:0;font-weight:800}

/* A reading of ±300 m is a wi-fi guess, not a GPS fix. Say so rather than
   printing five decimal places and letting them look precise. */
.selfie-geo.rough{color:var(--gold-dk);border-color:rgba(244,170,28,.4)}
.selfie-acc-note{font-size:.92em;opacity:.85;display:block;margin-top:3px;font-family:inherit}

@media (min-width:1100px){
  .selfie-block{grid-template-columns:minmax(0,420px) minmax(260px,1fr)}
  .selfie-stage{max-height:320px}
}
@media (max-width:900px) and (min-width:641px){
  .selfie-block{grid-template-columns:minmax(0,300px) minmax(200px,1fr)}
  .selfie-stage{max-height:240px}
}
@media (max-width:640px){
  .selfie-block{grid-template-columns:1fr}
  .selfie-stage{aspect-ratio:3/4;max-height:46vh}
  .selfie-side{padding-top:0}
}

/* The Sell.do id in the visit log — a link to the lead, not just a string. */
.lead-chip{
  display:inline-block;font-family:ui-monospace,Menlo,monospace;
  font-size:.9em;font-weight:600;color:var(--c);text-decoration:none;
  background:var(--c-lt);border-radius:5px;padding:2px 7px;
  max-width:16ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;
}
.lead-chip:hover{text-decoration:underline}

/* The picker can carry a dozen options. Inside it they are a list, not a row
   of tiles, so they get list proportions — the 56px tap minimum elsewhere on a
   touch screen would turn twelve occupations into three screens of scrolling. */
#pickModal .src-opt{min-height:48px;padding:10px 12px}
@media (max-width:420px){ #pickModal .src-opts{grid-template-columns:1fr} }
