/* Scanner PWA theme — dark barista UI (SaaS chrome, our teal system). Tokens from
   docs/00-product-visual-walkthrough.html. WCAG 2.2 AA contrast was computed per
   combination (review): teal #00695C on #0d0d10 FAILS 3:1 (2.93), so every teal control/
   border/focus on the DARK surface uses teal-mid #4daca4 (7.16:1); the result card is a
   LIGHT surface so its teal Stamp button (white-on-teal 6.61:1) and gold Redeem button
   (#5c4400 on #ffd43b 6.46:1) pass; the reward-ready chip uses #7a5c00 on #fff3bf (~5:1),
   not the failing #997404. ≥44px targets (action buttons 64px). Reduced motion honored. */

:root {
  --bg: #0d0d10;
  --surface: #16181d;
  --surface-2: #1f2229;
  --line: #2a2e37; /* DECORATIVE dividers only (1.17:1 — too low for an interactive boundary) */
  --field-border: #6e7480; /* form-control border — 1.4.11 ≥3:1 vs the field fill + page (3.25 / 4.1:1) */
  --text: #f1f3f5; /* light on dark — high contrast */
  --muted: #aeb4bd; /* muted light on dark — ≥4.5:1 */

  --teal: #00695c;
  --teal-mid: #4daca4; /* on-dark accent / reticle / focus ring (7.16:1 on #0d0d10) */
  --teal-light: #e6f3f2;
  --gold: #ffd43b;
  --gold-text: #5c4400;
  --green: #51cf66;
  --amber: #ffa94d;
  --red: #ff6b6b;

  --card: #ffffff;
  --card-text: #212529;
  --card-muted: #495057;

  --radius: 8px;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.35);

  font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  padding: 0;
}
body {
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  line-height: 1.5;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom)
    env(safe-area-inset-left);
}

/* Top chrome: location + online/offline pill. */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  background: var(--bg);
}
.loc {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 6px 10px;
  border-radius: 100px;
  border: 1px solid var(--line);
  color: var(--muted);
}
.pill .led {
  width: 8px;
  height: 8px;
  border-radius: 100px;
  background: var(--muted);
}
.pill.online .led {
  background: var(--green);
}
.pill.online {
  color: var(--green);
}
.pill.offline .led {
  background: var(--amber);
}
.pill.offline {
  color: var(--amber);
}

main {
  flex: 1;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Camera viewport SHELL (decoder is Phase 2) + reticle. */
.viewport {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.reticle {
  position: relative;
  z-index: 1;
  width: 58%;
  aspect-ratio: 1;
  border: 3px solid var(--teal-mid);
  border-radius: 16px;
  opacity: 0.9;
}
/* Live camera fills the viewport behind the reticle (decorative; state via #cam-hint). */
.cam {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}

/* Typed-code fallback (Phase 1 primary input). */
.code-form {
  display: flex;
  gap: 10px;
}
.code-form input {
  flex: 1;
  min-height: 52px;
  font-size: 16px; /* ≥16px → no iOS zoom on focus */
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0 14px;
  border-radius: var(--radius);
  border: 1px solid var(--field-border); /* 1.4.11 non-text contrast (≥3:1) */
  background: var(--surface-2);
  color: var(--text);
}
.code-form input::placeholder {
  color: var(--muted);
  letter-spacing: normal;
  text-transform: none;
}

/* Optional per-staff attribution PIN — sits with the manual controls; ≥44px target. */
.pin-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}
.pin-label {
  color: var(--muted);
  font-size: 0.85rem;
}
.pin-row input {
  flex: 1;
  max-width: 160px;
  min-height: 44px;
  font-size: 16px; /* ≥16px → no iOS zoom on focus */
  letter-spacing: 0.18em;
  padding: 0 14px;
  border-radius: var(--radius);
  border: 1px solid var(--field-border); /* 1.4.11 non-text contrast (≥3:1) */
  background: var(--surface-2);
  color: var(--text);
}
.btn {
  min-height: 52px;
  min-width: 44px;
  padding: 0 18px;
  border-radius: var(--radius);
  font-size: 1rem;
  font-weight: 600;
  border: 1px solid var(--teal-mid);
  background: transparent;
  color: var(--teal-mid);
  cursor: pointer;
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Result card — a LIGHT surface so teal/gold actions meet AA. */
.result {
  background: var(--card);
  color: var(--card-text);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 22px;
  text-align: center;
}
.result .count {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 3rem;
  font-weight: 700;
  line-height: 1.05;
  color: var(--card-text);
}
.result .count .goal {
  color: var(--card-muted);
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 6px 12px;
  border-radius: 100px;
  margin: 10px 0 4px;
}
.chip.progress {
  background: var(--teal-light);
  color: var(--teal);
}
.chip.ready {
  background: #fff3bf;
  color: #7a5c00; /* AA fix (≈5:1) — not the failing #997404 */
}
.chip.offline {
  background: #fff4e6; /* warm amber tint */
  color: #9c4221; /* ≥4.5:1 on the tint */
}
.reward-label {
  color: var(--card-muted);
  font-size: 0.95rem;
  margin: 4px 0 0;
}

.thumb-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 18px;
}
.thumb {
  min-height: 64px;
  border-radius: var(--radius);
  border: none;
  font-size: 1.1rem;
  font-weight: 700;
  cursor: pointer;
}
.thumb.stamp {
  background: var(--teal);
  color: #fff;
}
.thumb.redeem {
  background: var(--gold);
  color: var(--gold-text);
}
.thumb:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Toast (optimistic, reconciled to server truth) + states. */
.toast {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
  color: var(--text);
  font-size: 0.9rem;
  text-align: center;
}
.toast.err {
  border-color: var(--red);
  color: var(--red);
}
.muted {
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}

/* Visible focus on the dark surface — light/teal-mid, ≥3:1. */
:focus-visible {
  outline: 3px solid var(--teal-mid);
  outline-offset: 2px;
}

[hidden] {
  display: none;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Camera control + status. */
.cam-btn {
  width: 100%;
}
.cam-status {
  margin-top: -4px;
}

/* iOS home-screen install hint — an info callout above the scanner. */
.install {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--teal-mid);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: 0.85rem;
}
.install-text {
  margin: 0;
  flex: 1;
}
.btn-ghost {
  min-height: 44px;
  padding: 0 12px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

/* A queued-OFFLINE action: a clear "pending sync" treatment (it must never read as applied
   server truth). The toast says "Saved offline — will sync"; this dashed amber edge echoes it. */
.result.pending {
  outline: 2px dashed var(--amber);
  outline-offset: -2px;
}

/* The scanner uses no scanning animation; any future motion must gate on this. */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    transition-duration: 0.01ms;
  }
}
