/* =====================================================================
   MoverScan · styles.css
   Clean editorial BLACK & WHITE component system that complements
   Tailwind (loaded via the CDN). Every rule here is ADDITIVE: it pairs
   with the EJS view markup (brand lockup, badges, cards, table rows,
   form fields, hero, scan-credit meter, provenance badge, htmx swap
   states) and never fights the utilities.

   Palette is MONOCHROME ONLY — no colored accents. Primary action and
   emphasis are SOLID BLACK (neutral-900). "New"/highlight is black,
   never green. Values below mirror the Tailwind `neutral` scale so the
   component classes and any inline `neutral-*` utilities stay in sync.

   Exception to "additive": a few deliberately higher-specificity
   normalizers (badge anatomy, focus outlines, readable-ink floor +
   its ink-band exemption, muted-pill ink bump, 16px mobile inputs)
   OUTWEIGH stray per-view utilities — accessibility and
   one-pill-one-anatomy consistency must hold product-wide.
   ===================================================================== */

:root {
  /* surfaces */
  --ms-white:        #ffffff;
  --ms-app-bg:       #fafafa; /* neutral-50  · app shell */
  --ms-fill:         #f5f5f5; /* neutral-100 · muted fill */

  /* ink */
  --ms-ink:          #171717; /* neutral-900 · primary text / "black" */
  --ms-ink-strong:   #404040; /* neutral-700 · hover black / strong text */
  --ms-ink-soft:     #525252; /* neutral-600 */
  --ms-muted:        #737373; /* neutral-500 · secondary text — the MINIMUM ink for
                                 readable text incl. placeholders (4.74:1 on white,
                                 4.55:1 on neutral-50) */
  --ms-faint:        #a3a3a3; /* neutral-400 · DECORATION ONLY (aria-hidden marks,
                                 hover hairlines) — 2.4:1, never meaning-bearing text */

  /* lines */
  --ms-border:       #e5e5e5; /* neutral-200 · hairline */
  --ms-border-strong:#d4d4d4; /* neutral-300 · strong / input border */
}

/* ---------- base polish ---------- */
html {
  scroll-behavior: smooth;
  color-scheme: light; /* keep native form controls light, never inverted */
  /* Every accent-able native control (checkbox, radio, range, and the checked
     option in an open <select>) renders BLACK — never the OS blue. Inherited,
     so it reaches all controls; re-asserted explicitly on the controls below. */
  accent-color: var(--ms-ink);
}

body {
  font-family: 'Inter', ui-sans-serif, system-ui, -apple-system,
    'Segoe UI', Roboto, Helvetica, Arial, 'Apple Color Emoji',
    'Segoe UI Emoji', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-variant-ligatures: contextual;
}

/* black text selection — quiet, premium */
::selection {
  background: var(--ms-ink);
  color: var(--ms-white);
}

/* thin neutral scrollbars */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--ms-border-strong) transparent;
}
*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: var(--ms-border-strong); /* neutral-300 */
  border-radius: 9999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: var(--ms-faint); /* neutral-400 */
  background-clip: content-box;
}

/* keyboard focus ring — crisp black */
:focus-visible {
  outline: 2px solid var(--ms-ink);
  outline-offset: 2px;
  border-radius: 4px;
}

/* The dashboard's two primary keyboard targets carry `focus:outline-none`
   plus a 10–15% ring from the CDN utility sheet — a 1.2–1.4:1 "indicator"
   that fails non-text contrast (needs 3:1). The CDN-injected <style> sits
   AFTER this sheet, so !important is required to restore the crisp ink
   outline. `.field` controls are deliberately excluded: their focus border
   flips to ink (+ soft ring) and already passes. */
.stat-card:focus-visible,
select[name="status"]:not(.field):focus-visible {
  outline: 2px solid var(--ms-ink) !important;
  outline-offset: 2px !important;
}

/* ---------- brand lockup ---------- */
/* camera mark + "MoverScan" wordmark. The SVG uses stroke=currentColor,
   so coloring .brand colors the camera too. Near-black, tight tracking. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ms-ink);
  font-weight: 600;
  letter-spacing: -0.02em;
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease;
}
.brand:hover {
  color: var(--ms-ink-strong);
}

/* the line-art camera (lens = concentric scan reticle). Don't let it
   shrink in a flex row; sit it on the text baseline cleanly. */
.ms-camera {
  flex: none;
  vertical-align: middle;
}

/* ---------- status badges (monochrome) ---------- */
/* new = solid black · contacted = outlined · ignored = neutral fill.
   ONE pill, ONE anatomy — canonical spec is the customer-surface pill on
   /account + /app/billing: 12px/600, 2px × 10px padding, 16px line box,
   hairline border → a 22px-tall capsule (optionally with a leading dot). */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem; /* = gap-1.5, matches the dot pills */
  padding: 0.125rem 0.625rem; /* 2px 10px */
  font-size: 0.75rem; /* 12px */
  font-weight: 600;
  line-height: 1rem; /* 16px → 22px pill incl. padding + border */
  letter-spacing: 0.01em;
  text-transform: capitalize;
  white-space: nowrap;
  border-radius: 9999px;
  border: 1px solid transparent;
  user-select: none;
}
/* Every badge in the product is a <span>, so this element-qualified copy
   (specificity 0,1,1) outweighs the ad-hoc size utilities (text-[11px] /
   px-2 / px-2.5 — all 0,1,0) still stamped on older admin markup. Admin
   tables, /admin/plans and /admin/stripe now render the same pill as the
   customer surfaces without per-view re-specification. */
span.badge {
  font-size: 0.75rem;
  line-height: 1rem;
  padding: 0.125rem 0.625rem;
}
/* optional leading dot — sized like h-1.5/w-1.5, takes the pill's ink */
.badge .badge-dot {
  flex: none;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 9999px;
  background: currentColor;
}

.badge-new {
  background: var(--ms-ink); /* solid black */
  color: var(--ms-white);
  border-color: var(--ms-ink);
}
.badge-contacted {
  background: var(--ms-white);
  color: var(--ms-ink-strong); /* neutral-700 */
  border-color: var(--ms-border-strong); /* neutral-300 */
}
.badge-ignored {
  background: var(--ms-fill); /* neutral-100 */
  color: var(--ms-ink-soft); /* neutral-600 — 500-on-100 was 4.35:1, under AA */
  border-color: transparent;
}
/* older admin chips still stamp text-neutral-500 inline — outweigh it */
span.badge-ignored {
  color: var(--ms-ink-soft);
}

/* subscription status — the canonical statusMap treatment shared by
   /account, /app/billing and the admin tables: Active = solid black +
   white dot · Trial = white outline + black dot · Suspended = neutral
   fill. Views can stamp these instead of re-specifying the utility
   string per screen. Suspended ink is neutral-600 on purpose — the
   legacy 500-on-100 pill measured 4.35:1, under AA. */
.badge-active {
  background: var(--ms-ink);
  color: var(--ms-white);
  border-color: var(--ms-ink);
}
.badge-trial {
  background: var(--ms-white);
  color: var(--ms-ink-strong); /* neutral-700 */
  border-color: var(--ms-border-strong); /* neutral-300 */
}
.badge-suspended {
  background: var(--ms-fill); /* neutral-100 */
  color: var(--ms-ink-soft); /* neutral-600 — never 500 on a tinted fill */
  border-color: var(--ms-border); /* neutral-200 */
}

/* AUDIT FIX — muted-pill ink bump. Every chip that pairs text-neutral-500
   with a neutral-100 fill (the statusMap "suspended" pill, settings/admin
   "Not connected"/"Not set" chips, ignored-state quick chips) lands at
   4.35:1 — under AA. Lift the ink to neutral-600 (7.2:1) without touching
   markup: both compound selectors — (0,2,1) and (0,2,0) — outweigh the
   CDN utility (0,1,0) no matter where the CDN <style> is injected. */
span.badge.text-neutral-500,
.bg-neutral-100.text-neutral-500 {
  color: var(--ms-ink-soft);
}

/* ---------- provenance badge ---------- */
/* Tiny "records receipt" chip naming where a lead/scan row came from
   (lead.source — county deeds feed, ATTOM, …). Deliberately NOT a status
   capsule: squared corners + tracked mono-caps read as data provenance,
   pills read as workflow status.
     <span class="provenance-badge">Multnomah County deeds</span>
     <span class="provenance-badge"><svg …></svg> arcgis</span>
   neutral-600 on neutral-50 measures 7.4:1 — AA at any size. */
.provenance-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  max-width: 100%;
  overflow: hidden;
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--ms-border); /* neutral-200 hairline */
  border-radius: 0.375rem;
  background: var(--ms-app-bg); /* neutral-50 */
  color: var(--ms-ink-soft); /* neutral-600 */
  font-size: 0.6875rem; /* 11px */
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.provenance-badge > svg {
  width: 0.75rem;
  height: 0.75rem;
  flex: none;
}

/* status <select> echoes its current status in neutral tones */
select.status-new {
  color: var(--ms-ink);
  font-weight: 600;
}
select.status-contacted {
  color: var(--ms-ink-strong);
}
select.status-ignored {
  color: var(--ms-ink-soft); /* neutral-600 — 500 misses AA on tinted fills */
}
/* The per-row status pill gets its surface from inline utilities (no
   status-* class), pairing neutral-500 ink with a neutral-100 fill when
   "ignored" (4.35:1). Where :has() is available, lift that ink the same
   way; the selector's specificity outweighs the inline text utility. */
select[name="status"]:not(.field):has(option[value="ignored"]:checked) {
  color: var(--ms-ink-soft);
}

/* ---------- cards ---------- */
.card {
  background: var(--ms-white);
  border: 1px solid var(--ms-border); /* neutral-200 */
  border-radius: 0.75rem;
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.04); /* shadow-sm */
  transition:
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}
/* Lift only INTERACTIVE cards — static info panels + the modal stay flat. */
a.card:hover,
button.card:hover,
.card-interactive:hover {
  border-color: var(--ms-border-strong); /* neutral-300 */
  box-shadow: 0 6px 20px -10px rgba(0, 0, 0, 0.12);
}

/* stat tiles are clickable filters — self-contained surface + soft lift */
.stat-card {
  background: var(--ms-white);
  border: 1px solid var(--ms-border);
  border-radius: 0.75rem;
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.04);
  cursor: pointer;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease,
    box-shadow 0.18s ease;
}
.stat-card:hover {
  border-color: var(--ms-border-strong);
  background: var(--ms-app-bg); /* neutral-50 */
  box-shadow: 0 4px 16px -8px rgba(0, 0, 0, 0.10);
}

/* ---------- table rows ---------- */
.lead-row {
  transition: background-color 0.12s ease;
}
.lead-row:hover {
  background: var(--ms-app-bg); /* neutral-50 */
  cursor: pointer;
}

/* tabular figures for money / counts */
.num {
  font-variant-numeric: tabular-nums;
}

/* ---------- form fields ---------- */
.field {
  background: var(--ms-white);
  border: 1px solid var(--ms-border-strong); /* neutral-300 */
  color: var(--ms-ink);
  border-radius: 0.5rem;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
.field::placeholder {
  color: var(--ms-muted); /* neutral-500 — 400 measured 2.4:1, illegible */
}
/* the views also stamp `placeholder-neutral-400` inline; these qualified
   copies (0,1,1) outweigh that utility so placeholders meet 4.5:1 */
input.field::placeholder,
textarea.field::placeholder,
select.field::placeholder {
  color: var(--ms-muted);
}
.field:focus {
  outline: none;
  border-color: var(--ms-ink); /* neutral-900 */
  box-shadow: 0 0 0 3px rgba(23, 23, 23, 0.10); /* ring-neutral-900/10 */
}

/* A <select> wearing the .field look: strip the OS chrome and supply a
   tasteful monochrome chevron so dropdowns match text inputs across every
   browser. The right padding reserves room for the chevron — `select.field`
   intentionally outweighs the inline `px-3` utility so option text never
   collides with it. Compact per-row status pills don't use .field, so they
   keep their own shape and are untouched. */
select.field {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23737373' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1.05rem 1.05rem;
  text-overflow: ellipsis;
}
/* chevron deepens to ink on hover/focus — a quiet, premium micro-interaction */
select.field:hover,
select.field:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23171717' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
/* hide the legacy Edge/IE expand arrow so it can't double up with ours */
select.field::-ms-expand {
  display: none;
}

/* ---------- native form controls (monochrome accent) ---------- */
/* Belt-and-suspenders for the html-level accent-color above: pin every
   checkbox / radio / range / progress to BLACK so a checked control can never
   fall back to the OS accent (blue). Mirrors the inline `accent-neutral-900`
   utilities already on the EJS controls — the product stays strictly mono. */
input[type="checkbox"],
input[type="radio"],
input[type="range"],
progress {
  accent-color: var(--ms-ink);
}

/* ---------- readable-ink floor (LIGHT surfaces) ---------- */
/* neutral-400 measures 2.4–2.5:1 on this product's white/neutral-50
   surfaces — half the 4.5:1 required for body-size text. Meaning-bearing
   copy stamped `text-neutral-400` in the views (stat-card micro-labels,
   column headers, "No new", "View app", "recommended", …) is floored to
   neutral-500 here: (0,2,0) outweighs the utility's (0,1,0). aria-hidden
   decoration keeps the lighter tint, and hover:/group-hover: ink shifts
   still win the cascade exactly as before. */
.text-neutral-400:not([aria-hidden="true"]) {
  color: var(--ms-muted);
}

/* AUDIT FIX — ink-band exemption. On solid-ink surfaces (the marketing
   .band--ink and the hand-rolled bg-neutral-900 CTA bands) the floor made
   things WORSE: it forced #737373 onto #171717 — 3.78:1, under AA. There
   the LIGHTER tint is the readable one (neutral-400 on ink ≈ 7.1:1, the
   same step as the band's 60%-white ink ramp), so fine print returns to
   --ms-faint; text-neutral-500 on those bands had the identical defect
   and is lifted the same way. :where() keeps this at the floor's (0,2,0)
   specificity — it wins by order within this sheet, while later-injected
   CDN hover:/group-hover: utilities still win on interaction. */
:is(.band--ink, .bg-neutral-900, .bg-neutral-950, .bg-black)
  :where(.text-neutral-400, .text-neutral-500):not([aria-hidden="true"]) {
  color: var(--ms-faint);
}
/* …and re-anchor the light-surface floor inside any white/neutral chip or
   card NESTED in a dark band (a .card, .notice or white tag sitting on the
   ink band), where faint ink would fail all over again. (0,3,0). */
:is(.band--ink, .bg-neutral-900, .bg-neutral-950, .bg-black)
  :is(.bg-white, .bg-neutral-50, .bg-neutral-100, .card, .stat-card, .price-card, .notice)
  :where(.text-neutral-400, .text-neutral-500):not([aria-hidden="true"]) {
  color: var(--ms-muted);
}

/* ---------- buttons ---------- */
/* Shape / weight / motion only; markup supplies padding & sizing via
   Tailwind utilities (matches this project's additive convention). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  border-radius: 0.5rem;
  font-weight: 600;
  line-height: 1; /* tight box → consistent height whether or not it has an icon */
  white-space: nowrap;
  text-decoration: none; /* .btn is worn by <a> too — never underline it */
  cursor: pointer;
  user-select: none;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease,
    color 0.15s ease,
    opacity 0.15s ease,
    transform 0.12s ease;
}
.btn:active {
  transform: translateY(1px);
}

/* primary = solid black */
.btn-primary {
  background: var(--ms-ink);
  color: var(--ms-white);
  border: 1px solid var(--ms-ink);
}
.btn-primary:hover {
  background: var(--ms-ink-strong); /* neutral-700 */
  border-color: var(--ms-ink-strong);
}
.btn-primary:disabled,
.btn-primary[disabled] {
  opacity: 0.5;
  cursor: wait;
}

/* ghost = white with hairline border */
.btn-ghost {
  background: var(--ms-white);
  color: var(--ms-ink);
  border: 1px solid var(--ms-border-strong); /* neutral-300 */
}
.btn-ghost:hover {
  background: var(--ms-app-bg); /* neutral-50 */
  border-color: var(--ms-faint); /* neutral-400 */
}

/* size scale — ONE height per tier so headers / forms / rows stop drifting
   (audit measured 30/34/36/38/40/42px across surfaces). Views opt in per
   button instead of ad-hoc py-*:
     .btn-sm  compact row / pager / inline quick actions
     .btn-md  page-header + toolbar actions
     .btn-lg  form-level submits (login, account, settings, lead detail) */
.btn-sm {
  height: 2rem; /* 32px */
  padding: 0 0.75rem;
  font-size: 0.75rem;
}
.btn-md {
  height: 2.375rem; /* 38px */
  padding: 0 1rem;
  font-size: 0.875rem;
}
.btn-lg {
  height: 2.625rem; /* 42px */
  padding: 0 1.25rem;
  font-size: 0.875rem;
}

/* ---------- links ---------- */
a.ml-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition:
    border-color 0.15s ease,
    color 0.15s ease;
}
a.ml-link:hover {
  color: var(--ms-ink);
  border-bottom-color: currentColor;
}

/* ---------- htmx swap states ---------- */
.htmx-indicator {
  opacity: 0;
  transition: opacity 0.2s ease;
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}
.htmx-request.is-busy {
  opacity: 0.55;
  pointer-events: none;
}

/* gentle fade-in for newly swapped content */
.htmx-added {
  animation: ms-fade 0.25s ease both;
}
@keyframes ms-fade {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ---------- empty state ---------- */
.empty-state {
  background: var(--ms-app-bg); /* neutral-50 */
  border: 1px dashed var(--ms-border-strong); /* neutral-300 */
  border-radius: 0.75rem;
  color: var(--ms-muted); /* neutral-500 */
}

/* ---------- divider ---------- */
.divider {
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    var(--ms-border) 18%,
    var(--ms-border) 82%,
    transparent
  );
}

/* ---------- hero ---------- */
/* Tailwind utilities in the markup carry the visible surface (rounded-3xl,
   border-neutral-200, bg-white, shadow-sm). .hero/.ms-hero just establish
   the stacking/positioning context for the viewfinder corner ticks and
   decorative marks layered inside. */
.hero,
.ms-hero {
  position: relative;
  isolation: isolate;
}

/* ---------- eyebrow pill ---------- */
/* white pill, hairline border, uppercase tracked label. The leading BLACK
   dot is a sibling element in the markup (never green). */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
  border: 1px solid var(--ms-border); /* neutral-200 */
  background: var(--ms-white);
  color: var(--ms-ink-soft); /* neutral-600 */
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.05em; /* tracking-wider */
  white-space: nowrap;
}

/* ---------- hero stat cell ---------- */
/* White cells sit on a bg-neutral-200 grid with gap-px, so the grid shows
   through as perfect 1px hairline separators at both 2-up and 4-up. */
.stat {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.25rem 1rem;
  background: var(--ms-white);
}
.stat :is(.stat-value, .num),
.stat [data-stat-value] {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

/* ---------- scan-credit meter ---------- */
/* The metered-plan gauge for the dashboard stats strip, the billing usage
   card and the scan-result footer: ONE segment per scan in the period's
   cap (10 paid / 2 trial), spent = SOLID BLACK — the same ink language as
   .badge-new. The state is declared once on the ROOT so views can never
   drift into ad-hoc color:

     .meter-ok     scans left            → solid-black spent segments
     .meter-low    almost out (1–2 left) → heavier track + bold-ink
                                           "Only N left" label/note
     .meter-empty  0 left                → segments flip to the dashed
                                           .tag--soon "not available"
                                           outline + bold upgrade emphasis
                                           (pair the .btn-primary upgrade
                                           CTA beside .meter-note)

   CONTRACT — the value lives on the root, segments are decoration:
     <div class="meter meter-ok" role="img"
          aria-label="3 of 10 scans used — 7 left this period">
       <div class="meter-track" aria-hidden="true">
         <span class="meter-seg is-used"></span>  ← ×used
         <span class="meter-seg"></span>          ← ×remaining
       </div>
       <p class="meter-label num">3/10 scans used</p>
       <p class="meter-note">Only 2 left</p>      ← meter-low/empty only
     </div> */
.meter {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  /* span the container even inside centered flex parents (the .stat cell)
     — cap with a max-w-* utility in the markup when needed */
  width: 100%;
  min-width: 0;
}
.meter-track {
  display: flex;
  gap: 3px;
  width: 100%;
}
.meter-seg {
  flex: 1 1 0%;
  min-width: 0.25rem;
  height: 0.5rem;
  border-radius: 2px;
  background: var(--ms-fill); /* neutral-100 · unspent cell */
  border: 1px solid var(--ms-border-strong); /* neutral-300 */
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    height 0.18s ease;
}
/* spent = solid black (listed with the explicit .meter-ok state so the
   default and the named state can never disagree) */
.meter-seg.is-used,
.meter-ok .meter-seg.is-used {
  background: var(--ms-ink);
  border-color: var(--ms-ink);
}
.meter-label {
  color: var(--ms-ink-soft); /* neutral-600 */
  font-size: 0.75rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.meter-note {
  color: var(--ms-ink-soft);
  font-size: 0.75rem;
  font-weight: 500;
}

/* low — the track gains weight and the count speaks in bold ink */
.meter-low .meter-seg {
  height: 0.625rem;
}
.meter-low .meter-label,
.meter-low .meter-note {
  color: var(--ms-ink);
  font-weight: 700;
}

/* empty — capacity spent: every cell (spent ones included) flips to the
   dashed hairline outline (the .tag--soon convention for "not available")
   and the label/note carry the upgrade message in bold ink */
.meter-empty .meter-seg,
.meter-empty .meter-seg.is-used {
  background: var(--ms-white);
  border: 1px dashed var(--ms-border-strong);
}
.meter-empty .meter-label,
.meter-empty .meter-note {
  color: var(--ms-ink);
  font-weight: 700;
}

/* compact nav variant — the "7/10" pill beside the app-nav links; wearable
   by an <a> to /app/billing. Takes the SAME state classes on the same
   element:
     <a href="/app/billing" class="meter-pill meter-ok"
        aria-label="7 of 10 scans left this month">
       <span class="num">7</span><span class="meter-pill-cap">/10 scans</span>
     </a> */
.meter-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  height: 1.75rem;
  padding: 0 0.7rem;
  border-radius: 9999px;
  border: 1px solid var(--ms-border-strong); /* neutral-300 */
  background: var(--ms-white);
  color: var(--ms-ink);
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    background-color 0.15s ease;
}
a.meter-pill:hover {
  border-color: var(--ms-ink);
  background: var(--ms-app-bg);
}
.meter-pill .meter-pill-cap {
  color: var(--ms-ink-soft); /* neutral-600 — 500 would sit under AA at 12px */
  font-weight: 500;
}
.meter-pill.meter-low {
  border-color: var(--ms-ink);
  font-weight: 700;
}
.meter-pill.meter-empty {
  border-style: dashed; /* the .tag--soon convention again */
  font-weight: 700;
}
.meter-pill.meter-low .meter-pill-cap,
.meter-pill.meter-empty .meter-pill-cap {
  color: var(--ms-ink);
}

/* ---------- mobile: kill iOS zoom-on-focus ---------- */
/* iOS Safari auto-zooms (and stays zoomed after blur) whenever a focused
   control computes under 16px; every input in the product was 12–14px on
   phones. Element-qualified selectors (0,1,1) outweigh the inline
   text-sm / text-xs utilities without !important. */
@media (max-width: 767px) {
  input.field,
  select.field,
  textarea.field,
  input[type="text"],
  input[type="search"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="tel"],
  input[type="url"],
  select[name="status"]:not(.field) {
    font-size: 16px;
  }
  /* let the per-row status pill outgrow its fixed w-[104px] so the 16px
     "contacted" label isn't clipped; the chevron stays pinned to the
     pill's own right edge (absolutely positioned in its wrapper). */
  select[name="status"]:not(.field) {
    width: auto;
    min-width: 6.5rem;
  }
}

/* ---------- motion preference ---------- */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
