/* Field — phone-first shell.
 *
 * Every colour here resolves through a --lh-* primitive from @lighthill/tokens,
 * so the light theme is a token-layer change (:root[data-theme="light"]) and not
 * a second copy of this stylesheet. The --f-* vars below are the app's own
 * semantic layer: they exist so a rule reads "card background" rather than
 * "panel-2", and so anything genuinely Field-specific (tap-target sizing, the
 * outdoor-legibility bumps) has one place to live.
 *
 * Sizing rule for this app: nothing interactive is smaller than 44px in either
 * dimension. It is used one-handed, outdoors, often with gloves on.
 */

:root {
  --f-bg: var(--lh-bg);
  --f-card: var(--lh-panel);
  --f-card-2: var(--lh-panel-2);
  --f-card-hover: var(--lh-panel-hover);
  --f-border: var(--lh-border);
  --f-border-soft: var(--lh-border-soft);
  --f-text: var(--lh-text);
  --f-muted: var(--lh-text-muted);
  --f-dim: var(--lh-text-dim);
  --f-accent: var(--lh-accent);
  --f-accent-soft: var(--lh-accent-soft);
  --f-accent-line: var(--lh-accent-line);
  --f-good: var(--lh-good);
  --f-warn: var(--lh-warn);
  --f-bad: var(--lh-bad);

  --f-tap: 44px;
  --f-radius: var(--lh-radius);
  --f-shadow: var(--lh-shadow);
}

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

html {
  /* Stop iOS Safari inflating text in landscape — it breaks the card layout. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--f-bg);
  color: var(--f-text);
  font-family: var(--lh-font-body);
  font-size: 16px; /* < 16px makes iOS zoom on input focus */
  line-height: 1.45;
  min-height: 100dvh;
  /* Bottom tab bar + home indicator. */
  padding-bottom: calc(64px + env(safe-area-inset-bottom));
  overscroll-behavior-y: contain;
}

/* Hidden until /auth/me resolves, so a signed-out visitor never sees app chrome
 * flash before the redirect. `.booted` is set by the auth gate in index.html. */
body:not(.booted) .app-shell { visibility: hidden; }

/* ─── Auth gate ─────────────────────────────────────────────────────────── */

.gate {
  position: fixed; inset: 0; z-index: 400;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: var(--lh-space-4);
  padding: var(--lh-space-5);
  background: var(--f-bg);
  text-align: center;
}
.gate.hidden { display: none; }
.gate h1 { margin: 0; font-family: var(--lh-font-display); font-size: 34px; letter-spacing: 0.02em; }
.gate p { margin: 0; max-width: 30ch; color: var(--f-muted); }

/* ─── Layout ────────────────────────────────────────────────────────────── */

.app-shell { max-width: 720px; margin: 0 auto; padding: 0 var(--lh-space-4); }

.search-bar {
  position: sticky; top: 0; z-index: 20;
  margin: 0 calc(var(--lh-space-4) * -1);
  padding: var(--lh-space-3) var(--lh-space-4);
  background: var(--f-bg);
  border-bottom: 1px solid var(--f-border-soft);
}

.search-input {
  width: 100%;
  min-height: 52px;
  padding: 0 var(--lh-space-4);
  font: inherit;
  font-size: 17px;
  color: var(--f-text);
  background: var(--f-card);
  border: 1px solid var(--f-border);
  border-radius: var(--lh-radius-pill);
  outline: none;
}
.search-input::placeholder { color: var(--f-dim); }
.search-input:focus { border-color: var(--f-accent); box-shadow: 0 0 0 3px var(--f-accent-soft); }

/* What the parser understood, echoed back so a wrong guess is obvious before
 * the user blames the data. */
.parse-chips { display: flex; flex-wrap: wrap; gap: var(--lh-space-2); margin-top: var(--lh-space-3); }
.parse-chips:empty { display: none; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  font-size: 13px; font-weight: 600;
  color: var(--f-accent);
  background: var(--f-accent-soft);
  border: 1px solid var(--f-accent-line);
  border-radius: var(--lh-radius-pill);
  white-space: nowrap;
}
.chip.neutral { color: var(--f-muted); background: transparent; border-color: var(--f-border); }
.chip.dropped { color: var(--f-dim); background: transparent; border-color: var(--f-border-soft); text-decoration: line-through; }

/* ─── Vendor cards ──────────────────────────────────────────────────────── */

.results { display: flex; flex-direction: column; gap: var(--lh-space-3); padding: var(--lh-space-4) 0; }

.vendor-card {
  background: var(--f-card);
  border: 1px solid var(--f-border);
  border-radius: var(--f-radius);
  overflow: hidden;
}

/* The head is a <button> when there are contacts to reveal, a <div> when there
 * are not — so it looks and behaves inert unless it actually does something. */
.vendor-head {
  display: block; width: 100%;
  padding: var(--lh-space-3) var(--lh-space-4);
  font: inherit; color: inherit; text-align: left;
  background: none; border: 0;
}
button.vendor-head { cursor: pointer; }
button.vendor-head:active { background: var(--f-card-hover); }
button.vendor-head:focus-visible { outline: 2px solid var(--f-accent); outline-offset: -2px; }

.vendor-name-row { display: flex; align-items: baseline; gap: var(--lh-space-2); }
.vendor-name { margin: 0; font-size: 17px; font-weight: 650; line-height: 1.25; flex: 1 1 auto; }
.vendor-contact-count { flex: 0 0 auto; font-size: 12px; font-weight: 600; color: var(--f-dim); white-space: nowrap; }
.vendor-name-row svg {
  flex: 0 0 auto; width: 16px; height: 16px; align-self: center;
  fill: none; stroke: var(--f-dim); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform 0.15s ease;
}
button.vendor-head.open .vendor-name-row svg { transform: rotate(180deg); }

/* ─── Contacts ──────────────────────────────────────────────────────────── */

.contacts { border-top: 1px solid var(--f-border-soft); background: var(--f-card-2); }
.contacts[hidden] { display: none; }

.contact {
  display: flex; align-items: center; gap: var(--lh-space-3);
  padding: var(--lh-space-2) var(--lh-space-2) var(--lh-space-2) var(--lh-space-4);
  border-top: 1px solid var(--f-border-soft);
}
.contact:first-child { border-top: 0; }
.contact-who { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.contact-name { font-size: 15px; font-weight: 600; }
.contact-type {
  padding: 1px 7px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--f-muted); border: 1px solid var(--f-border); border-radius: var(--lh-radius-pill);
  white-space: nowrap;
}

.contact-actions { flex: 0 0 auto; display: flex; gap: 0; }
.contact-action {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: var(--f-tap);
  color: var(--f-accent); background: none; border: 0; border-radius: 50%;
  cursor: pointer;
}
.contact-action:active { background: var(--f-card-hover); }
.contact-action[aria-disabled="true"] { color: var(--f-dim); pointer-events: none; }
.contact-action svg {
  width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.vendor-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--lh-space-2); }
.vendor-note { margin: var(--lh-space-2) 0 0; font-size: 14px; color: var(--f-muted); }

.badge-vetted {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; font-size: 12px; font-weight: 700; letter-spacing: 0.03em;
  color: var(--f-good); border: 1px solid var(--f-good); border-radius: var(--lh-radius-pill);
}

/* Actions are the point of the card: one row, equal thirds, each a full tap
 * target. Disabled means we have no number or email on file — shown, not
 * hidden, so the gap in the data is visible rather than silently absent. */
.vendor-actions { display: flex; border-top: 1px solid var(--f-border-soft); }
.vendor-actions > * {
  flex: 1 1 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: var(--f-tap); padding: var(--lh-space-2) 2px;
  font-size: 11px; font-weight: 600; letter-spacing: -0.01em;
  text-decoration: none; white-space: nowrap;
  color: var(--f-accent); background: none; border: 0;
  border-left: 1px solid var(--f-border-soft);
  cursor: pointer; font-family: inherit;
}
.vendor-actions > *:first-child { border-left: 0; }
.vendor-actions > *:active { background: var(--f-card-hover); }
.vendor-actions > [aria-disabled="true"] { color: var(--f-dim); pointer-events: none; }
.vendor-actions svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.vendor-actions svg.icon-asana { fill: currentColor; stroke: none; }

/* ─── States ────────────────────────────────────────────────────────────── */

.state { padding: var(--lh-space-6) var(--lh-space-4); text-align: center; color: var(--f-muted); }
.state h2 { margin: 0 0 var(--lh-space-2); font-size: 17px; color: var(--f-text); }
.state p { margin: 0 auto; max-width: 34ch; font-size: 14px; }

/* --lh-bg as the foreground is deliberate and works in BOTH themes: dark theme
 * pairs near-black text with a bright yellow, light theme pairs near-white text
 * with a dark amber. Both clear 4.5:1. */
.offline-banner {
  display: none;
  padding: var(--lh-space-2) var(--lh-space-4);
  font-size: 13px; font-weight: 600; text-align: center;
  color: var(--lh-bg); background: var(--f-warn);
}
body.is-offline .offline-banner { display: block; }

.update-bar {
  display: flex; align-items: center; justify-content: center; gap: var(--lh-space-3);
  padding: var(--lh-space-2) var(--lh-space-4);
  font-size: 13px; font-weight: 600;
  color: var(--lh-bg); background: var(--f-accent);
}
.update-bar[hidden] { display: none; }
.update-bar button {
  min-height: 32px; padding: 0 var(--lh-space-3);
  font: inherit; font-weight: 700;
  color: var(--lh-bg); background: none;
  border: 1px solid var(--lh-bg); border-radius: var(--lh-radius-pill);
  cursor: pointer;
}

/* ─── Capture wizard ────────────────────────────────────────────────────── */

.wizard { padding-top: var(--lh-space-4); }
.wz-step { display: flex; flex-direction: column; gap: var(--lh-space-4); }
.wz-title { margin: 0; font-size: 24px; font-weight: 700; line-height: 1.2; }
.wz-sub { margin: 0; color: var(--f-muted); font-size: 14px; }
.wz-hint { color: var(--f-dim); font-size: 13px; }
.wz-note:empty { display: none; }
.wz-note { color: var(--f-bad); font-size: 14px; }

.wz-field { display: flex; flex-direction: column; gap: 6px; }
.wz-label { font-size: 14px; font-weight: 600; }
.wz-input {
  width: 100%; min-height: var(--f-tap); padding: 0 var(--lh-space-3);
  font: inherit; font-size: 16px; /* < 16px makes iOS zoom on focus */
  color: var(--f-text); background: var(--f-card);
  border: 1px solid var(--f-border); border-radius: var(--f-radius);
}
.wz-input:focus { outline: none; border-color: var(--f-accent); box-shadow: 0 0 0 3px var(--f-accent-soft); }
select.wz-input { appearance: none; padding-right: var(--lh-space-5); }

.wz-form { display: flex; flex-direction: column; gap: var(--lh-space-4); }
.wz-actions { display: flex; gap: var(--lh-space-2); }
.wz-actions .btn { flex: 1 1 0; }

/* Photo tiles. The whole tile is the tap target — a small camera icon is not
 * something to aim at with cold hands. */
.wz-shots { display: flex; flex-direction: column; gap: var(--lh-space-3); }
.wz-shot {
  background: var(--f-card); border: 1px solid var(--f-border);
  border-radius: var(--f-radius); overflow: hidden;
}
.wz-shot.has-photo { border-color: var(--f-accent-line); }
.wz-shot.busy { opacity: 0.55; pointer-events: none; }
.wz-shot-hit { display: flex; align-items: center; gap: var(--lh-space-3); padding: var(--lh-space-3); cursor: pointer; }
.wz-shot-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  flex: 0 0 84px; height: 84px;
  font-size: 11px; font-weight: 600; color: var(--f-dim);
  background: var(--f-card-2); border: 1px dashed var(--f-border); border-radius: var(--f-radius);
}
.wz-thumb { flex: 0 0 84px; width: 84px; height: 84px; object-fit: cover; border-radius: var(--f-radius); }
.wz-shot-meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.wz-shot-meta strong { font-size: 15px; }
.wz-shot-meta span { font-size: 13px; color: var(--f-muted); }
.wz-file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

.wz-uncertain {
  padding: var(--lh-space-3) var(--lh-space-4);
  background: var(--f-accent-soft);
  border: 1px solid var(--f-accent-line);
  border-radius: var(--f-radius);
  font-size: 14px;
}
.wz-uncertain ul { margin: var(--lh-space-2) 0 0; padding-left: 1.2em; }
.wz-uncertain li { margin-bottom: 4px; }

.wz-working { align-items: center; text-align: center; padding-top: var(--lh-space-6); }
.spinner {
  width: 32px; height: 32px; border-radius: 50%;
  border: 3px solid var(--f-border); border-top-color: var(--f-accent);
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* The tag, deliberately the loudest thing on the success screen — it is what
 * gets written on a physical label while the tech is still standing there. */
.wz-tag {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: var(--lh-space-5) var(--lh-space-4);
  background: var(--f-accent-soft); border: 1px solid var(--f-accent-line);
  border-radius: var(--f-radius);
}
.wz-tag-label { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--f-muted); }
.wz-tag-value { font-family: var(--lh-font-mono); font-size: 40px; font-weight: 700; letter-spacing: 0.02em; color: var(--f-accent); }

.wz-link { color: var(--f-accent); font-weight: 600; text-decoration: none; }
.wz-pending {
  display: flex; align-items: center; justify-content: space-between; gap: var(--lh-space-3);
  padding: var(--lh-space-3) var(--lh-space-4);
  font-size: 14px;
  background: var(--f-card-2); border: 1px solid var(--f-border); border-radius: var(--f-radius);
}

/* ─── Bottom tabs ───────────────────────────────────────────────────────── */

.tabs {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex;
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--f-card);
  border-top: 1px solid var(--f-border);
}
.tab {
  flex: 1 1 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: 56px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--f-dim); text-decoration: none;
}
.tab[aria-current="page"] { color: var(--f-accent); }
.tab svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; }

/* ─── Buttons ───────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--f-tap); padding: 0 var(--lh-space-5);
  font: inherit; font-weight: 650;
  color: var(--lh-bg); background: var(--f-accent);
  border: 0; border-radius: var(--lh-radius-pill);
  cursor: pointer;
}
.btn.secondary { color: var(--f-text); background: var(--f-card-2); border: 1px solid var(--f-border); }
.btn:disabled { opacity: 0.5; cursor: default; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--f-tap); height: var(--f-tap);
  color: var(--f-muted); background: none; border: 0; border-radius: 50%;
  cursor: pointer;
}
.icon-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
