/* VisaForYou — the customer page, built from the owner-approved mock v2 (launch plan §5b, 2026-10-16).
 *
 * Concept: "the specimen". The applicant's photo sits the way a document photo sits on a form: a
 * hard-edged square on white, a caption under it, and the yellow measuring ruler beside it (the same
 * yellow as the crop guides). Everything else is quiet black type on white.
 * Colour = meaning: pass green, fix red, guide yellow. No cards, no shadows, no tinted boxes. Rounded
 * corners only on things you tap; the photo is square. One family, the system stack: the page makes
 * no request for a font (rule 7). One orchestrated motion (`.revealing`); everything else moves only
 * when tapped, and not at all under reduced motion.
 * State is painted by app.js as `hidden` on the ids of the contract, plus three root classes:
 *   has-photo   a photo is loaded: the upload's own text steps aside, the results show
 *   is-checking the first pass over a new photo is running: the narrated phases cover the photo
 *   revealing   the 1.6 s after that pass lands: ruler, mark, verdict and the rest arrive in order
 */

:root {
  --paper: #ffffff;
  --ink: #000000;
  --graphite: #5c5f66;     /* 6.4:1 on paper */
  --hairline: #e3e5e8;
  --edge: #c9cdd3;         /* the photo's 1 px edge, so a white background still reads as a square */
  --pass: #0a7a47;         /* 5.4:1 */
  --fix: #c42b1c;          /* 5.7:1 */
  --guide: #ffc800;        /* always drawn on an ink casing: yellow on white alone is 1.55:1 */
  --sample: #8b9098;       /* the example's silhouette */
  --sample-head: #9ea3ab;

  --font: system-ui, -apple-system, "SF Arabic", "Segoe UI", "Noto Sans Arabic", "Noto Naskh Arabic", Tahoma, Arial, sans-serif;
  --gutter: 16px;
  --tap: 44px;
  --r-tap: 14px;
  --ruler: 36px;           /* the gutter on the photo's physical right where the ruler stands */

  --fs-cap: 14px;
  --fs-body: 17px;
  --fs-lead: 27px;
  --fs-verdict: 30px;
  --lh-body: 1.75;
  --lh-display: 1.35;
  --ease-reveal: cubic-bezier(.2, .7, .2, 1);
}
:root[dir="ltr"] {
  --lh-body: 1.55;
  --lh-display: 1.2;
  --fs-verdict: 28px;
}

*, ::before, ::after { box-sizing: border-box; }
html { background: var(--paper); overflow-x: clip; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  font: 400 var(--fs-body) / var(--lh-body) var(--font);
  color: var(--ink);
  background: var(--paper);
}
h1, h2, p, figure, ul, ol { margin: 0; }
img, svg, canvas { display: block; max-inline-size: 100%; }
button, input { font: inherit; }
[hidden] { display: none !important; }
.vh {
  position: absolute !important; inline-size: 1px; block-size: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; padding: 0; border: 0;
}
:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.btn.primary:focus-visible { outline-offset: 4px; }

.wrap { max-inline-size: 480px; margin-inline: auto; padding-inline: var(--gutter); }
@media (min-width: 900px) { .wrap { max-inline-size: 640px; } }

/* ---------- header: a wordmark and the language switch, nothing else ---------- */
.site-head { display: flex; align-items: center; gap: 10px; padding-block: 10px; }
.brand-mark { inline-size: 28px; block-size: 28px; flex: none; }
.bm-photo { fill: none; stroke: var(--ink); stroke-width: 2; }
.bm-case { stroke: var(--ink); stroke-width: 5; stroke-linecap: square; }
.bm-ruler { stroke: var(--guide); stroke-width: 2.4; stroke-linecap: square; }
.site-head h1 { font-size: 18px; font-weight: 800; line-height: 1; letter-spacing: -.01em; flex: 1; }
#langBtn {
  min-block-size: var(--tap); padding-inline: 14px;
  border: 1.5px solid var(--ink); border-radius: var(--r-tap);
  background: var(--paper); color: var(--ink);
  font: 700 15px / 1 var(--font); cursor: pointer;
}

main.wrap { padding-block: 4px 8px; }

/* ---------- upload ---------- */
.lead {
  font-size: var(--fs-lead); font-weight: 800; line-height: var(--lh-display);
  margin-block: 14px 22px; max-inline-size: 13em; text-wrap: balance;
}
.example { inline-size: 56%; margin-block-end: 24px; }
.ex-paper { fill: var(--paper); }
.ex-body { fill: var(--sample); }
.ex-head { fill: var(--sample-head); }

/* the specimen: a square photo with the ruler's gutter on its physical right, in both languages */
.photo {
  position: relative; aspect-ratio: 1;
  inline-size: calc(100% - var(--ruler)); margin-right: var(--ruler);
  box-shadow: 0 0 0 1px var(--edge);
}
.example-photo, .preview-clip { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; }
.preview-clip { overflow: hidden; background: var(--paper); }
.preview-clip img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
.example-ruler, #measure {
  position: absolute; inset: 0; inline-size: 100%; block-size: 100%;
  overflow: visible; pointer-events: none; direction: ltr;
}
.m-case { fill: none; stroke: var(--ink); stroke-width: 7px; stroke-linecap: square; vector-effect: non-scaling-stroke; }
.m-line { fill: none; stroke: var(--guide); stroke-width: 3.5px; stroke-linecap: square; vector-effect: non-scaling-stroke; }
.m-mark circle { stroke: var(--paper); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.m-mark.ok circle { fill: var(--pass); }
.m-mark.bad circle { fill: var(--fix); }
.m-glyph { fill: none; stroke: var(--paper); stroke-width: 2.5px; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
/* the measurement's words, small and grey under the photo: the frame on the left, the head under the ruler */
.m-label { fill: var(--graphite); font-family: var(--font); font-size: 22px; font-weight: 600; unicode-bidi: isolate; }

.seg {
  border: 0; margin: 0 0 18px; padding: 3px; min-inline-size: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 3px;
  border-radius: var(--r-tap); box-shadow: inset 0 0 0 1.5px var(--ink);
}
.seg input { position: absolute; opacity: 0; inline-size: 1px; block-size: 1px; margin: 0; }
.seg label {
  min-block-size: var(--tap); display: grid; place-items: center; text-align: center;
  padding: 4px 10px; border-radius: 11px; font-size: 16px; font-weight: 700; line-height: 1.25; cursor: pointer;
}
.seg input:checked + label { background: var(--ink); color: var(--paper); }
.seg input:focus-visible + label { outline: 3px solid var(--ink); outline-offset: 3px; }

#offer { font-size: var(--fs-body); font-weight: 700; margin-block-end: 12px; }
.pickers { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.inputs { position: relative; block-size: 0; }
.file-input { position: absolute; inset-block-start: 0; opacity: 0; inline-size: 1px; block-size: 1px; overflow: hidden; }
body:has(#file:focus-visible) label[for="file"], body:has(#camera:focus-visible) label[for="camera"] {
  outline: 3px solid var(--ink); outline-offset: 4px;
}
.err { color: var(--fix); font-weight: 700; margin-block-start: 10px; }
.err.is-busy { color: var(--graphite); font-weight: 400; }

/* ---------- buttons: the only rounded things ---------- */
.btn {
  min-block-size: 54px; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 8px 14px; border: 1.5px solid var(--ink); border-radius: var(--r-tap);
  background: var(--paper); color: var(--ink);
  font: 700 var(--fs-body) / 1.25 var(--font); text-align: center; cursor: pointer;
}
.btn.primary { background: var(--ink); color: var(--paper); }
.btn.wide { inline-size: 100%; }
.btn[disabled] { opacity: .55; cursor: progress; }
.btn:active { transform: scale(.985); }
.ico { inline-size: 22px; block-size: 22px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.textlink {
  display: inline-flex; align-items: center; min-block-size: var(--tap); padding: 0;
  border: 0; background: none; color: var(--ink); cursor: pointer;
  font: 700 16px / 1.3 var(--font); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px;
}

/* ---------- disclosures: one quiet row each ---------- */
.disclosure {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  inline-size: 100%; min-block-size: 48px; padding: 0;
  border: 0; border-block-start: 1px solid var(--hairline); background: none; color: var(--ink);
  font: 700 16px / 1.3 var(--font); text-align: start; cursor: pointer; list-style: none;
}
.disclosure::-webkit-details-marker { display: none; }
.disclosure::after {
  content: ""; flex: none; inline-size: 9px; block-size: 9px; margin-inline-end: 4px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;   /* physical: points down in both languages */
  transform: translateY(-2px) rotate(45deg); transition: transform .2s var(--ease-3, ease);
}
details[open] > .disclosure::after, .disclosure[aria-expanded="true"]::after { transform: translateY(2px) rotate(-135deg); }
.more { margin-block-start: 14px; }
.more-body, .details-panel { display: grid; gap: 8px; padding-block: 2px 14px; font-size: 15px; color: var(--graphite); }
details[open] > :not(summary), .details-panel { animation: open .22s var(--ease-reveal) both; }
@keyframes open { from { opacity: 0; translate: 0 -4px; } }
.limit { font-size: var(--fs-cap); }
.limit.blocked { color: var(--fix); font-weight: 700; }

/* ---------- results: photo, verdict, caption ---------- */
.specimen { margin-block: 4px 30px; }   /* room for the measurement's words under the photo */
#original { opacity: 0; transition: opacity .6s ease; }
#preview { transition: opacity .6s ease, scale .7s var(--ease-reveal); }
.is-checking #original { opacity: 1; }
.is-checking #preview { opacity: 0; scale: .82; }

/* narrated progress over the photo: one live line, six segments that fill only when a phase lands */
.narration {
  position: absolute; inset-inline: 0; inset-block-end: 0;
  padding: 12px 14px; background: var(--paper);
  box-shadow: 0 -1px 0 var(--edge);
  opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s .3s;
}
.is-checking .narration { opacity: 1; visibility: visible; transition: none; }
.phases { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
.phases li { block-size: 4px; border-radius: 2px; background: var(--hairline); font-size: 0; line-height: 0; overflow: hidden; color: transparent; }
.phases li.done { background: var(--ink); }
.phases li.active { background: linear-gradient(to left, var(--ink) 30%, var(--hairline) 30%); }
:root[dir="ltr"] .phases li.active { background: linear-gradient(to right, var(--ink) 30%, var(--hairline) 30%); }
.phases li.failed { background: var(--fix); }
#phaseLine { margin-block-start: 8px; font-weight: 700; font-size: var(--fs-body); line-height: 1.4; }
#phaseLine:empty { display: none; }

.verdict {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: var(--fs-verdict); font-weight: 800; line-height: var(--lh-display);
  margin-block: 0 6px; text-wrap: balance;
}
.verdict:empty { display: none; }
.verdict::before {
  content: ""; flex: none; display: grid; place-items: center;
  inline-size: 28px; block-size: 28px; margin-block-start: calc((1em * var(--lh-display) - 28px) / 2);
  border-radius: 50%; background: var(--graphite); color: var(--paper);
  font-size: 17px; font-weight: 800; line-height: 1;
}
.verdict.is-ok::before { content: "✓"; background: var(--pass); }
.verdict.is-fail::before { content: "✕"; background: var(--fix); }
/* Focus lands on the verdict by script so a screen reader hears it (tabindex -1, never in the tab order):
   it is not a control, so no ring is drawn — the 390 px shots showed one around the heading. */
.verdict:focus, .verdict:focus-visible { outline: none; }
.is-checking .verdict, .is-checking .caption, .is-checking .tests, .is-checking #toggleChecks,
.is-checking #detailsPanel, .is-checking #manual, .is-checking .bar { display: none; }

.caption {
  display: flex; flex-wrap: wrap; gap: 2px 18px; margin-block-end: 6px;
  font-size: var(--fs-cap); color: var(--graphite); font-variant-numeric: tabular-nums;
}
#outMeta { unicode-bidi: isolate; }
#metricsOut { display: inline-flex; flex-wrap: wrap; gap: 2px 18px; }
#metricsOut b { font-weight: 400; display: inline-flex; gap: 6px; }
#metricsOut .bad { color: var(--fix); font-weight: 700; }
#debug { font-size: 12px; line-height: 1.5; color: var(--graphite); overflow-wrap: anywhere; margin-block-end: 6px; }

ul.tests { list-style: none; margin: 4px 0 8px; padding: 0; }
ul.tests:empty { display: none; }
ul.tests li { display: flex; gap: 10px; align-items: flex-start; padding-block: 6px; font-size: 15px; line-height: 1.6; }
ul.tests li.is-fail, ul.tests li.is-warn { font-weight: 600; }
ul.tests li.is-pass, ul.tests li.is-na { display: none; }
ul.tests.show-all li.is-pass, ul.tests.show-all li.is-na { display: flex; color: var(--graphite); font-weight: 400; }
.dot {
  flex: none; inline-size: 20px; block-size: 20px; margin-block-start: 2px; border-radius: 50%;
  display: grid; place-items: center; color: var(--paper); font-size: 12px; font-weight: 800; line-height: 1;
}
.dot.pass { background: var(--pass); }
.dot.fail { background: var(--fix); }
.dot.warn, .dot.na { background: var(--graphite); }

#cropStep { display: grid; gap: 12px; padding-block: 2px 14px; }
.hint { font-size: 15px; color: var(--graphite); }
.hint.inapp { color: var(--ink); font-weight: 700; margin-block: 0 12px; }   /* L129: before the photo step */
#stage { inline-size: 100%; block-size: auto; aspect-ratio: 1; touch-action: none; direction: ltr; box-shadow: 0 0 0 1px var(--edge); }
.nudge {           /* physical by meaning: "← Left" sits on the left in both languages */
  direction: ltr; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
  grid-template-areas: "out up in" "left down right";
}
.nudge [data-nudge="out"] { grid-area: out; }
.nudge [data-nudge="up"] { grid-area: up; }
.nudge [data-nudge="in"] { grid-area: in; }
.nudge [data-nudge="left"] { grid-area: left; }
.nudge [data-nudge="down"] { grid-area: down; }
.nudge [data-nudge="right"] { grid-area: right; }
.nudge button {
  min-block-size: var(--tap); border: 1.5px solid var(--ink); border-radius: var(--r-tap);
  background: var(--paper); color: var(--ink); font: 700 15px / 1.2 var(--font); cursor: pointer;
}
.zoomrow { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 12px; font-size: 15px; font-weight: 700; }
.zoomrow label { min-block-size: var(--tap); min-inline-size: var(--tap); display: flex; align-items: center; }
input[type="range"] { inline-size: 100%; min-block-size: var(--tap); margin: 0; accent-color: var(--ink); }
#bgHardRow { padding-block-end: 14px; }

/* ---------- the pinned bar: the next action for this state, and nothing else ---------- */
.bar {
  position: sticky; inset-block-end: 0; z-index: 2;
  margin: 16px calc(-1 * var(--gutter)) 0;
  padding: 12px var(--gutter) calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--paper); box-shadow: 0 -1px 0 var(--hairline);
  display: grid; gap: 8px;
}
.btn.pay { min-block-size: 56px; }
#payReminder { font-size: var(--fs-cap); line-height: 1.6; color: var(--graphite); }
:root[dir="ltr"] #payReminder { line-height: 1.45; }
.rescue { display: grid; gap: 8px; }
#rescueHint { font-size: var(--fs-cap); line-height: 1.6; color: var(--graphite); }
.rescue .textlink { justify-self: start; }
.pay-secondary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.pay-secondary .btn { flex: 1 1 0; min-block-size: 48px; }
.pay-secondary .btn.primary { flex-basis: 100%; min-block-size: 54px; }
.pay-secondary:not(:has(> :not([hidden]))) { display: none; }
#payStatus { display: flex; gap: 10px; align-items: flex-start; font-weight: 700; line-height: 1.5; }
#payStatus::before {
  content: ""; flex: none; inline-size: 22px; block-size: 22px; margin-block-start: 2px; border-radius: 50%;
  display: grid; place-items: center; color: var(--paper); font-size: 13px; font-weight: 800; line-height: 1;
}
#payStatus:not([data-state])::before { display: none; }
#payStatus[data-state="busy"]::before { border: 2.5px solid var(--hairline); border-block-start-color: var(--ink); animation: spin .8s linear infinite; }
#payStatus[data-state="done"]::before { content: "✓"; background: var(--pass); }
#payStatus[data-state="retry"]::before, #payStatus[data-state="terminal"]::before { content: "✕"; background: var(--fix); }
@keyframes spin { to { rotate: 360deg; } }

/* ---------- the one orchestrated moment: progress → result ---------- */
.revealing #measure .m-ruler { animation: draw .45s .55s var(--ease-reveal) both; }
.revealing #measure .m-mark { animation: pop .28s 1s var(--ease-reveal) both; transform-box: fill-box; transform-origin: center; }
.revealing .verdict { animation: rise .32s .95s ease-out both; }
.revealing .caption, .revealing .tests, .revealing #toggleChecks, .revealing #manual, .revealing .bar { animation: rise .32s 1.15s ease-out both; }
@keyframes draw { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pop { from { opacity: 0; scale: .5; } }
@keyframes rise { from { opacity: 0; translate: 0 6px; } }

/* ---------- with a photo, the upload's own words step aside; the inputs stay for "another photo" ---------- */
.has-photo .intro { display: none; }
.has-photo .start > :not(.inputs):not(.child) { display: none; }   /* CS-U D: the child toggle stays with the photo */

/* ---------- footer ---------- */
.site-foot { padding-block: 28px 20px; font-size: var(--fs-cap); color: var(--graphite); display: grid; gap: 2px; }
.foot-link { display: inline-flex; align-items: center; min-block-size: var(--tap); color: var(--ink); font-weight: 700; text-decoration: underline; text-underline-offset: 4px; }

/* CS-U item D: the child toggle sits under the record switch; pressed = ink, like the switch's chosen half */
.child { display: grid; gap: 8px; margin-block: 12px 0; }
.child:not(:has(> :not([hidden]))) { display: none; }
#childBtn { min-block-size: var(--tap); font-size: 16px; }
#childBtn[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
#childTips { display: grid; gap: 6px; }
#childTips .hint { color: var(--ink); }

/* ---------- CS-U item E: the upload guide (guide/dv-upload.<lang>.html) ----------
   The same specimen as the page: the file drawn as a hard-edged square with the yellow ruler on its full height, its
   four facts beside it, then the steps in order. Quotes from the instructions are small graphite captions with their
   link and date; nothing borrows an authority's look (no seal, no flag colours). */
.site-head .brand {
  flex: 1; display: inline-flex; align-items: center; min-block-size: var(--tap);
  font-size: 18px; font-weight: 800; line-height: 1; letter-spacing: -.01em; color: var(--ink); text-decoration: none;
}
.lang-link {
  min-block-size: var(--tap); padding-inline: 14px; display: inline-flex; align-items: center;
  border: 1.5px solid var(--ink); border-radius: var(--r-tap); color: var(--ink);
  font: 700 15px / 1 var(--font); text-decoration: none;
}
.guide .lead { max-inline-size: 15em; margin-block-end: 12px; }
.g-intro { color: var(--graphite); }
.g-sec { margin-block-start: 26px; padding-block-start: 20px; border-block-start: 1px solid var(--hairline); }
.g-sec h2 { font-size: 20px; font-weight: 800; line-height: var(--lh-display); margin-block-end: 14px; }
.g-file { display: grid; grid-template-columns: minmax(0, 42%) minmax(0, 1fr); gap: 16px; align-items: start; }
.g-specimen { margin: 0; }
.g-facts { margin: 0; display: grid; gap: 10px; }
.g-facts dt { font-size: var(--fs-cap); color: var(--graphite); }
.g-facts dd { margin: 0; font-weight: 700; line-height: 1.4; }
.g-facts div:last-child dd { font-weight: 400; font-size: var(--fs-cap); }
.g-src { font-size: var(--fs-cap); line-height: 1.6; color: var(--graphite); margin-block-start: 12px; overflow-wrap: anywhere; }
.g-src q { display: block; margin-block: 4px; color: var(--ink); quotes: "\201C" "\201D"; }   /* one English quote per block: it never interleaves with Arabic lines */
.g-src time { white-space: nowrap; }
.g-src a, .g-note a { color: var(--ink); text-underline-offset: 3px; }
.g-steps { margin: 0; padding-inline-start: 1.3em; display: grid; gap: 16px; }
.g-steps li::marker { font-weight: 800; }
.g-note { font-size: var(--fs-cap); color: var(--graphite); margin-block-start: 12px; }
.g-back { margin-block: 30px 6px; }
.g-back .btn { text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important;
  }
}
