/* SF26 Scanner — self-contained styling.

   Deliberately NOT importing merkvex_core.css / mx_ds.css / mx_shell.
   This surface has one job and no navigation; pulling the sitewide sheets
   would pull the dock, the nav and 200KB of rules for chrome that must not
   exist here. Tokens below are copied values from mx_tokens.css, not a new
   palette — the scanner must look like Merkvex, it just does not use the
   Merkvex shell. Any token drift is cosmetic only and cannot reach a price.

   App-shell rule (AGENTS.md 9b): locked shell, no body scroll, 44px taps. */
:root {
  --void: #060810;
  --ink: #EAF0FF;
  --ink-2: #9AA3AF;
  --ink-3: #6b7280;
  --aurora: #7CFFB2;
  --aurora-dim: #5FDC96;
  --teal: #3BE0C8;
  --gold: #E7C27D;
  --down: #9AA3AF;
  --line: rgba(255, 255, 255, .12);
  --panel: #0a101d;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100dvh;
  overflow: hidden;
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.45;
  overscroll-behavior: none;
}

/* ── THE APP SHELL ────────────────────────────────────────────────────────
   OPT OUT OF THE SITEWIDE NAV OFFSET. merkvex_core.css (injected by
   merkvex_core.min.js, which this page needs for the valuation engine) sets
   `body { padding-top: calc(var(--mx-nav-h,64px) + env(safe-area-inset-top)) }`
   for a fixed nav that does not exist here. `body.sf-page` outranks the bare
   `body` selector on specificity, so it wins regardless of injection order —
   the same lever body.bz-page and body.mx-skin already pull. */
body.sf-page { padding: 0; }

/* And the structural guard, because this has now bitten twice: taking the
   shell OUT OF BODY FLOW means no future sitewide body padding, margin or
   injected banner can ever push the shutter off the bottom again.
   height uses dvh, not vh — on Android and iOS `100vh` is the tallest the
   viewport ever gets, so a vh-sized shell hides its own bottom edge behind
   the browser's URL bar for as long as that bar is showing. */
.sf-screen {
  position: fixed;
  top: 0; left: 0; right: 0;
  display: flex; flex-direction: column;
  height: 100vh;      /* floor for anything without dvh */
  height: 100dvh;
  max-height: 100dvh;
}
/* min-height:0 for the same reason as .sf-vf — without it the result list
   refuses to shrink below its content and pushes "Scan another card" out. */
.sf-feed { flex: 1 1 0%; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 20px 18px calc(20px + env(safe-area-inset-bottom)); }
.sf-top { flex: none; padding: calc(14px + env(safe-area-inset-top)) 18px 10px; display: flex; align-items: center; gap: 10px; }

.sf-mark { width: 26px; height: 26px; flex: none; }
.sf-wordmark { font-weight: 600; letter-spacing: .01em; font-size: 15px; }
.sf-wordmark span { color: var(--ink-3); font-weight: 400; }

h1 { font-size: 25px; line-height: 1.2; margin: 6px 0 8px; font-weight: 650; letter-spacing: -.01em; }
h2 { font-size: 15px; margin: 0 0 8px; font-weight: 600; }
p { margin: 0 0 14px; color: var(--ink-2); }
p.lede { color: var(--ink); }
b, strong { color: var(--ink); font-weight: 600; }

.sf-card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 16px; margin: 0 0 14px; }

.sf-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: 52px; padding: 12px 18px;
  border-radius: 13px; border: 1px solid rgba(124, 255, 178, .3);
  background: rgba(124, 255, 178, .1); color: var(--aurora);
  font: inherit; font-weight: 650; font-size: 16px;
  cursor: pointer; touch-action: manipulation;
}
.sf-btn:active { transform: scale(.97); }
.sf-btn.solid { background: var(--aurora); color: #04140a; border-color: var(--aurora); }
.sf-btn.ghost { background: none; border-color: var(--line); color: var(--ink-2); font-weight: 500; min-height: 46px; font-size: 14.5px; }

.sf-steps { counter-reset: s; list-style: none; margin: 10px 0 4px; padding: 0; }
.sf-steps li { counter-increment: s; position: relative; padding: 0 0 14px 38px; color: var(--ink-2); }
.sf-steps li::before {
  content: counter(s); position: absolute; left: 0; top: -1px;
  width: 26px; height: 26px; border-radius: 50%;
  background: rgba(124, 255, 178, .12); color: var(--aurora);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700;
}
.sf-ico { display: inline-block; vertical-align: -3px; margin: 0 3px; color: var(--aurora); }

.sf-note { font-size: 12.5px; color: var(--ink-3); margin: 14px 0 0; }
.sf-hide { display: none !important; }

/* ── viewfinder ───────────────────────────────────────────────────────────
   THE RULE FOR THIS SCREEN: the viewfinder gives up height, the shutter
   never moves. Someone is holding a card in one hand and a phone in the
   other with a queue behind them — the control they need must be under
   their thumb without a scroll, at every size.
   `min-height: 0` is what actually enforces it: a column flex item defaults
   to `min-height: auto`, which refuses to shrink below its content and
   shoves later siblings out of the container. */
.sf-vf { position: relative; flex: 1 1 0%; min-height: 0; overflow: hidden; background: #000; }
.sf-vf video, .sf-vf img.freeze { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The guide is sized off the viewfinder's OWN height, not the viewport.
   It was `width: min(70vw,300px)` with a derived height of 419px, which is
   taller than the whole viewfinder in landscape — the frame ran off the
   screen exactly like the shutter did. Driving it from height means it
   shrinks with its container and the 63:88 card ratio is always honoured. */
.sf-guide {
  position: absolute; left: 50%; top: 47%; transform: translate(-50%, -50%);
  height: min(74%, 430px); width: auto; aspect-ratio: 63 / 88;
  border: 2px solid rgba(124, 255, 178, .85); border-radius: 10px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .45); pointer-events: none;
}
.sf-guide.busy { border-color: var(--teal); animation: sfpulse 1.1s ease-in-out infinite; }
@keyframes sfpulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .sf-guide.busy { animation: none; } }

/* clear of the deck's scrim overlap (-38px) so the coaching line is always
   legible against the camera feed rather than fading into the controls */
.sf-status {
  position: absolute; left: 50%; bottom: 46px; transform: translateX(-50%);
  max-width: calc(100vw - 32px); padding: 7px 14px; border-radius: 999px;
  background: rgba(6, 8, 16, .82); border: 1px solid var(--line);
  font-size: 13px; color: var(--ink-2); text-align: center; pointer-events: none;
}
/* The control deck. flex:none + a floor height so it can never be
   compressed away, and it reads as a deliberate camera surface rather than
   a strip of buttons: the viewfinder fades into it instead of stopping at a
   hard line. env() keeps the shutter clear of the iPhone home indicator. */
.sf-bar {
  flex: 0 0 auto;
  position: relative;
  /* THREE COLUMNS, shutter in the middle one — so the shutter is dead
     centre of the SCREEN, not centre of the button group. Flex centring
     put it noticeably right of centre because "Photo" shared the row, and
     the whole point of this control is that a thumb finds it without
     looking. The side columns hold their width whether or not their button
     is showing, so the shutter never shifts as the UI changes. */
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  padding: 14px 18px calc(16px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(6, 8, 16, 0) 0%, var(--void) 42%);
  margin-top: -38px;            /* the scrim overlaps the viewfinder */
  z-index: 4;
}
.sf-bar > .sf-shutter { grid-column: 2; }
.sf-bar > .sf-mini:first-of-type { grid-column: 1; justify-self: center; }
.sf-bar > .sf-mini ~ .sf-mini { grid-column: 3; justify-self: center; }
/* the result deck is one full-width action, not a camera row */
#scResultBar { grid-template-columns: 1fr; }
.sf-shutter {
  width: 74px; height: 74px; border-radius: 50%; flex: none;
  border: 4px solid var(--aurora); background: rgba(124, 255, 178, .16);
  box-shadow: 0 0 0 6px rgba(124, 255, 178, .09), 0 6px 20px rgba(0, 0, 0, .5);
  cursor: pointer; touch-action: manipulation;
  transition: transform .12s ease;
}
.sf-shutter:active { transform: scale(.94); }
.sf-shutter:disabled { opacity: .35; cursor: default; box-shadow: none; }
.sf-mini {
  min-width: 62px; min-height: 44px; border: 0; background: none;
  color: var(--ink-2); font: inherit; font-size: 13.5px; cursor: pointer;
  touch-action: manipulation; border-radius: 10px;
}
.sf-mini:active { transform: scale(.96); }

/* SHORT VIEWPORTS — landscape, and small phones with the URL bar showing.
   The deck gets compact rather than the shutter leaving the screen: that
   is the whole rule of this surface. Still ≥44px on every control. */
@media (max-height: 560px) {
  .sf-bar { gap: 16px; padding: 8px 14px calc(10px + env(safe-area-inset-bottom)); margin-top: -22px; }
  .sf-shutter { width: 56px; height: 56px; border-width: 3px; box-shadow: 0 0 0 4px rgba(124, 255, 178, .09); }
  .sf-guide { height: min(70%, 430px); }
  .sf-status { bottom: 30px; font-size: 12px; padding: 5px 11px; }
  .sf-chip { top: calc(6px + env(safe-area-inset-top)); }
}

/* ── verdict ────────────────────────────────────────────────────────── */
.sf-verdict { border-radius: 14px; border: 1px solid; padding: 14px 16px; margin: 0 0 14px; }
.sf-verdict .vlabel { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; font-weight: 700; }
.sf-verdict .vwhy { font-size: 13.5px; color: var(--ink-2); margin: 5px 0 0; }
.v-yes { border-color: rgba(124, 255, 178, .5); background: rgba(124, 255, 178, .08); }
.v-yes .vlabel { color: var(--aurora); }
.v-mid { border-color: rgba(231, 194, 125, .45); background: rgba(231, 194, 125, .06); }
.v-mid .vlabel { color: var(--gold); }
.v-no { border-color: rgba(154, 163, 175, .45); background: rgba(154, 163, 175, .07); }
.v-no .vlabel { color: var(--down); }
.v-thin { border-color: rgba(59, 224, 200, .3); background: rgba(59, 224, 200, .05); }
.v-thin .vlabel { color: var(--teal); }

.sf-prices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 14px; }
.sf-price { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 13px 14px; }
.sf-price .k { font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.sf-price .v { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 23px; font-weight: 700; margin-top: 3px; }
.sf-price.graded .v { color: var(--aurora); }
.sf-price .sub { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }

.sf-idrow { display: flex; gap: 12px; align-items: center; margin: 0 0 14px; }
.sf-idrow img { width: 58px; border-radius: 6px; flex: none; background: #0d1424; }
.sf-idrow .nm { font-weight: 600; font-size: 16px; }
.sf-idrow .st { font-size: 13px; color: var(--ink-3); }

.sf-alt { display: block; width: 100%; text-align: left; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin: 0 0 8px; color: var(--ink); font: inherit; min-height: 48px; cursor: pointer; }
.sf-alt .st { font-size: 12.5px; color: var(--ink-3); }

/* Type-the-name escape hatch in the not-sure state. 16px font is not a
   style choice: anything smaller makes iOS Safari zoom the whole page on
   focus, which in a locked app shell strands the user at the wrong scale. */
.sf-type {
  width: 100%; min-height: 48px; padding: 12px 14px; margin: 0 0 10px;
  border-radius: 12px; border: 1px solid var(--line);
  background: #0d1424; color: var(--ink);
  font: inherit; font-size: 16px;
}
.sf-type:focus { outline: none; border-color: rgba(124, 255, 178, .5); }
.sf-type::placeholder { color: var(--ink-3); }

.sf-offline { flex: none; background: rgba(231, 194, 125, .1); border-bottom: 1px solid rgba(231, 194, 125, .3); color: var(--gold); font-size: 12.5px; padding: 7px 18px; text-align: center; }

/* ── INSTALL SHEET (sf26_pwa.js) ──────────────────────────────────────────
   Bottom-anchored on purpose: on iPhone the Share control lives in the
   centre of the bottom Safari toolbar, so the sheet sits above it and the
   arrow points down at the real thing. A centred modal would put the
   instruction as far from the control as the screen allows. */
.sfp-scrim {
  position: fixed; inset: 0; z-index: 900;
  background: rgba(2, 4, 10, .72);
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0 10px 0;
  animation: sfpFade .18s ease-out;
}
@keyframes sfpFade { from { opacity: 0 } }

.sfp-sheet {
  position: relative;
  width: min(460px, 100%);
  background: var(--panel);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 20px 20px 0 0;
  padding: 22px 20px calc(18px + env(safe-area-inset-bottom));
  box-shadow: 0 -10px 40px rgba(0, 0, 0, .6);
  animation: sfpUp .24s cubic-bezier(.22, .9, .3, 1);
  /* A short viewport — a small phone in landscape, or an iPhone SE with the
     Safari chrome expanded — must never push "Got it" below the fold. The
     sheet scrolls inside itself rather than the page scrolling behind the
     scrim. Verified at 390x844 and 412x915; this guards anything shorter. */
  max-height: 88dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
@keyframes sfpUp { from { transform: translateY(18px); opacity: .4 } }
@media (prefers-reduced-motion: reduce) {
  .sfp-scrim, .sfp-sheet { animation: none }
}

.sfp-x {
  position: absolute; top: 8px; right: 8px;
  width: 44px; height: 44px;
  background: none; border: 0; color: var(--ink-2);
  font-size: 22px; line-height: 1; cursor: pointer;
  touch-action: manipulation;
}
.sfp-h { font-size: 18px; font-weight: 650; margin: 0 34px 14px 0; line-height: 1.25; }
.sfp-warn {
  margin: 0 0 14px; padding: 10px 12px; border-radius: 11px;
  background: rgba(231, 194, 125, .1); border: 1px solid rgba(231, 194, 125, .3);
  color: var(--gold); font-size: 13.5px;
}

.sfp-steps { list-style: none; margin: 0 0 16px; padding: 0; }
.sfp-step {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 0 0 15px; color: var(--ink-2); font-size: 15px; line-height: 1.45;
}
.sfp-step:last-child { padding-bottom: 0; }
.sfp-n {
  flex: none; width: 27px; height: 27px; border-radius: 50%;
  background: rgba(124, 255, 178, .13); color: var(--aurora);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700;
}
.sfp-step b { color: var(--ink); font-weight: 650; }

/* The glyphs are the actual controls being described — same weight, same
   shape, so the eye can match them to the chrome without reading. */
.sfp-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; vertical-align: -7px; margin: 0 1px;
  border-radius: 7px; background: rgba(124, 255, 178, .1);
  border: 1px solid rgba(124, 255, 178, .22); color: var(--aurora);
}
.sfp-ico svg { width: 15px; height: 15px; }

/* Points down, out of the sheet, at the Safari toolbar. */
.sfp-point {
  display: flex; flex-direction: column; align-items: center;
  gap: 4px; margin: 2px 0 14px; color: var(--aurora);
}
.sfp-point-lbl {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px; letter-spacing: .07em; text-transform: uppercase; opacity: .85;
}
.sfp-arrow {
  width: 2px; height: 26px; background: currentColor; position: relative; opacity: .75;
  animation: sfpNudge 1.6s ease-in-out infinite;
}
.sfp-arrow::after {
  content: ""; position: absolute; left: 50%; bottom: -1px;
  width: 10px; height: 10px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateX(-50%) rotate(45deg);
}
@keyframes sfpNudge { 50% { transform: translateY(5px) } }
@media (prefers-reduced-motion: reduce) { .sfp-arrow { animation: none } }

.sfp-note { font-size: 12.5px; color: var(--ink-3); margin: 0 0 14px; line-height: 1.45; }
.sfp-done {
  display: block; width: 100%; min-height: 50px; padding: 12px;
  border-radius: 13px; border: 1px solid var(--aurora);
  background: var(--aurora); color: #04140a;
  font: inherit; font-weight: 650; font-size: 16px;
  cursor: pointer; touch-action: manipulation;
}
.sfp-done:active { transform: scale(.98); }

/* Install chip on the scanner itself — the surface people actually reach
   from the homepage's "Scan a card now". This page declares the scanner
   manifest, so the tap here is a genuine native install. */
.sf-chip {
  position: absolute; left: 50%; transform: translateX(-50%);
  top: calc(10px + env(safe-area-inset-top));
  z-index: 6; display: flex; align-items: center; gap: 7px;
  min-height: 44px; padding: 10px 15px; border-radius: 999px;   /* 44px tap floor, AGENTS.md 9b */
  background: rgba(6, 8, 16, .86); border: 1px solid rgba(124, 255, 178, .38);
  color: var(--aurora); font: inherit; font-size: 13.5px; font-weight: 600;
  cursor: pointer; touch-action: manipulation;
  backdrop-filter: blur(6px);
}
.sf-chip:active { transform: translateX(-50%) scale(.97); }
.sf-chip svg { width: 15px; height: 15px; }
/* Nothing to install here — the app IS installed and this is it. */
html[data-sf26-mode="installed"] .sf-chip { display: none; }

/* Hero install button + the mode-selected helper line under it. The engine
   stamps html[data-sf26-mode]; CSS picks the one matching sentence, so
   there is a single source of truth for which platform we think we are on
   and no chance of the label and the helper text disagreeing. */
.sf-hero { min-height: 58px; font-size: 17px; margin-bottom: 10px; }
.sf-help { display: none; font-size: 13.5px; color: var(--ink-2); margin: 0; }
html[data-sf26-mode="prompt"]    .sf-help[data-when="prompt"],
html[data-sf26-mode="ios"]       .sf-help[data-when="ios"],
html[data-sf26-mode="ios-other"] .sf-help[data-when="ios-other"],
html[data-sf26-mode="manual"]    .sf-help[data-when="manual"],
html[data-sf26-mode="inapp"]     .sf-help[data-when="inapp"],
html[data-sf26-mode="installed"] .sf-help[data-when="installed"],
html[data-sf26-mode="desktop"]   .sf-help[data-when="desktop"] { display: block; }
/* Before the engine resolves (or with JS dead) show the manual line — it is
   the instruction that is true on the widest range of devices. */
html:not([data-sf26-mode]) .sf-help[data-when="manual"] { display: block; }
