/* =============================================================================
   Storadar design system — the base stylesheet every server-rendered page uses.

   Source of truth: design/explorations/04-spreadsheet-motif.html (chosen by
   Paulo 2026-07-22) — "the Google Sheet as the database, made literal": a
   fresh sheets-green palette, ink-on-paper surfaces, one sharp coral accent,
   serif headings over a monospace data voice, hairline grid motifs.

   Structure:
     1. Design tokens (light) + dark-theme overrides
     2. Reset + document/base
     3. Typography (one shared margin rhythm for H1-6 + P)
     4. Layout primitives (.wrap, landmarks)
     5. Components (nav, buttons, chips, flash, sheet/cell card)
   Overrides against the strong defaults are the exception and each carries a
   comment saying why it earns its place.
   ============================================================================= */

/* 1 -------------------------------------------------------------- TOKENS ---- */
:root {
  /* Surfaces + ink, ported from the exploration. */
  --paper: #f7f6f1;
  --paper-2: #fffefb;
  --card: #ffffff;
  --ink: #16201c;
  --ink-2: #3d4b45;
  --ink-3: #6b7a72;
  --ink-4: #9aa79f;

  /* Sheets green identity + the single coral accent. */
  --green: #1a7f5a;
  --green-2: #16a06b;
  --green-3: #e6f4ec; /* tint fill   */
  --green-4: #d3ebde; /* tint border */
  --grid: #e4e2d8; /* hairline           */
  --grid-2: #d7d5c9; /* stronger hairline  */
  --accent: #e8593a;
  --accent-2: #fbe7e1;
  --amber: #c98a1a;
  --amber-2: #fbf1dc;

  /* Feedback surfaces reuse the status-chip hues. */
  --ok: var(--green);
  --ok-bg: var(--green-3);
  --ok-border: var(--green-4);
  --err: var(--accent);
  --err-bg: var(--accent-2);
  --err-border: #f4cfc4;
  --info: var(--amber);
  --info-bg: var(--amber-2);
  --info-border: #f0dfb6;

  /* Type families. */
  --serif: "Hoefler Text", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace;

  /* Type scale (fluid where it earns it). */
  --step--1: 0.82rem;
  --step-0: 1rem;
  --step-1: 1.18rem;
  --step-2: clamp(1.4rem, 2.4vw, 1.7rem);
  --step-3: clamp(1.9rem, 3.8vw, 2.7rem);
  --step-4: clamp(2.3rem, 5.4vw, 3.5rem);

  /* Spacing + rhythm. --flow is the shared vertical gap between flow elements. */
  --flow: 0.9rem;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;

  /* Radii, hairline grid cell size, shadows. */
  --radius: 14px;
  --radius-sm: 10px;
  --cell: 34px; /* spreadsheet background grid pitch */
  --shadow: 0 24px 60px -30px rgba(22, 32, 28, 0.35), 0 6px 18px -10px rgba(22, 32, 28, 0.18);
  --shadow-sm: 0 10px 26px -16px rgba(22, 32, 28, 0.3);

  /* Grid-line paint used by the sheet background (token so dark mode can dim it). */
  --grid-line: var(--grid);

  color-scheme: light;
}

/* Dark theme: the exploration is light-only, so this is a faithful inversion —
   same green identity and coral accent, ink and paper swapped, grid dimmed so
   the sheet motif reads as texture rather than noise. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0f1310;
    --paper-2: #141813;
    --card: #181d17;
    --ink: #eef2ec;
    --ink-2: #c6d0c6;
    --ink-3: #93a096;
    --ink-4: #6c7970;

    --green: #34b784; /* lifted for contrast on dark surfaces */
    --green-2: #48c795;
    --green-3: #16281e;
    --green-4: #234233;
    --grid: #23291f;
    --grid-2: #2c3327;
    --accent: #f2795c;
    --accent-2: #2c1a15;
    --amber: #e0a94a;
    --amber-2: #2a2113;

    --err-border: #4a2a20;
    --info-border: #43371c;

    --shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.6), 0 6px 18px -10px rgba(0, 0, 0, 0.5);
    --shadow-sm: 0 10px 26px -16px rgba(0, 0, 0, 0.55);
    --grid-line: #1b2016;

    color-scheme: dark;
  }
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--sans);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink-2);
  background-color: var(--paper);
  /* The literal spreadsheet: a faint hairline grid behind every page. */
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--cell) var(--cell), var(--cell) var(--cell);
  background-position: -1px -1px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg,
video {
  max-width: 100%;
  height: auto;
}

a {
  color: var(--green);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* Keyboard focus is always visible; pointer focus stays quiet. */
:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
  border-radius: 3px;
}

/* 3 ---------------------------------------------------------- TYPOGRAPHY ---- */
/* One shared margin rhythm for every heading and paragraph: no top margin
   (flow spacing is owned by the owl rule below), a single --flow gap beneath.
   Overrides elsewhere must justify why they diverge from this. */
h1,
h2,
h3,
h4,
h5,
h6,
p {
  margin: 0 0 var(--flow);
}

/* Vertical rhythm: consecutive flow siblings get one --flow gap. This is the
   single source of top spacing, keeping headings and paragraphs consistent. */
:where(main, .flow) > * + * {
  margin-top: var(--flow);
}

h1,
h2,
h3,
h4 {
  font-family: var(--serif);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-wrap: balance;
}

h1 {
  font-size: var(--step-4);
}

h2 {
  font-size: var(--step-3);
}

h3 {
  font-size: var(--step-2);
}

h4 {
  font-size: var(--step-1);
}

/* h5/h6 step down into the mono "label" voice rather than the serif display
   voice — they name things (columns, fields) instead of announcing sections. */
h5,
h6 {
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

p {
  max-width: 68ch; /* keep measure readable; long lines tire the eye */
}

small {
  font-size: var(--step--1);
  color: var(--ink-3);
}

code,
kbd,
samp {
  font-family: var(--mono);
  font-size: 0.92em;
}

/* 4 ------------------------------------------------------------- LAYOUT ---- */
.wrap {
  width: min(1180px, 92vw);
  margin-inline: auto;
}

/* Landmarks: header + footer are full-bleed bands, main grows to fill. */
.site-header {
  border-bottom: 1px solid var(--grid);
  background: color-mix(in srgb, var(--paper-2) 88%, transparent);
  backdrop-filter: saturate(1.1) blur(6px);
}

main {
  flex: 1 0 auto;
  width: 100%;
}

.site-footer {
  border-top: 1px solid var(--grid);
  padding-block: var(--space-4);
  color: var(--ink-4);
  font-size: var(--step--1);
}

.foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* The footer descriptor is muted body text, not a paragraph in the reading
   column — reset the shared measure/margin so it sits inline with the mark. */
.foot p {
  margin: 0;
  max-width: none;
  color: var(--ink-4);
}

/* Skip link for keyboard users; visible only when focused. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 10px 16px;
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}

.skip-link:focus {
  left: 12px;
  top: 12px;
}

/* 5 --------------------------------------------------------- COMPONENTS ---- */

/* --- Nav ------------------------------------------------------------------ */
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-2);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--serif);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
}

.brand:hover {
  text-decoration: none; /* the wordmark is not a "link-looking" link */
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 8px;
  background: var(--green);
  color: #fff;
  box-shadow: var(--shadow-sm);
}

/* The icon size is driven here rather than on the SVG element so the mark stays
   in proportion to its container across both header (30px) and footer uses. */
.brand-mark svg {
  width: 18px;
  height: 18px;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.nav-links a {
  color: var(--ink-3);
  font-size: 0.92rem;
}

.nav-links a:hover {
  color: var(--ink);
  text-decoration: none;
}

/* Admin chrome reads as a denser, working surface: mono section labels. */
.nav[data-variant="admin"] .nav-links a {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
}

@media (max-width: 760px) {
  /* On narrow screens keep only actionable links (buttons); collapse the rest.
     Full responsive nav lands with the real console (later task). */
  .nav-links a:not(.btn) {
    display: none;
  }
}

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-weight: 600;
  font-size: 0.92rem;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.2s, background 0.2s, border-color 0.2s;
}

.btn:hover {
  text-decoration: none;
}

.btn-primary {
  background: var(--green);
  color: #fff;
  box-shadow: 0 10px 24px -12px color-mix(in srgb, var(--green) 70%, transparent);
}

.btn-primary:hover {
  transform: translateY(-2px);
  background: color-mix(in srgb, var(--green) 92%, black);
}

.btn-ghost {
  background: var(--card);
  color: var(--ink);
  border-color: var(--grid-2);
}

.btn-ghost:hover {
  border-color: var(--ink-4);
}

/* Destructive action (irreversible-ish: apply mass delete, account deletion).
   Reads as caution via the accent, not the green success tone. */
.btn-danger {
  background: var(--card);
  color: var(--err);
  border-color: var(--err-border);
}

.btn-danger:hover {
  background: var(--err-bg);
  border-color: var(--err);
}

/* HTMX disables the in-flight button (hx-disabled-elt); make that visible so a
   customer sees the click registered rather than wondering if it worked. */
.btn:disabled,
.btn[disabled] {
  opacity: 0.6;
  cursor: progress;
  transform: none;
}

/* A shared horizontal action row (buttons + links). Used by the sheet panel and
   the export/delete pages — one definition, not per-page. */
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  align-items: center;
}

/* --- Status chip (the reused sheet-status motif) -------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid transparent;
  border-radius: 100px;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.chip::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.chip-ok {
  color: var(--ok);
  background: var(--ok-bg);
  border-color: var(--ok-border);
}

.chip-info {
  color: var(--info);
  background: var(--info-bg);
  border-color: var(--info-border);
}

.chip-alert {
  color: var(--err);
  background: var(--err-bg);
  border-color: var(--err-border);
}

/* --- Eyebrow (mono kicker above headings) --------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--green);
}

.eyebrow::before {
  content: "";
  width: 22px;
  height: 1px;
  background: currentColor;
}

/* --- Flash / error region ------------------------------------------------- */
/* Lives directly under the header; announced politely to assistive tech. Never
   swallow a failure silently — errors surface here, visibly. */
.flash {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-block: var(--space-2) 0;
  padding: 12px 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
}

.flash-ok {
  color: var(--ok);
  background: var(--ok-bg);
  border-color: var(--ok-border);
}

.flash-error {
  color: var(--err);
  background: var(--err-bg);
  border-color: var(--err-border);
}

.flash-info {
  color: var(--info);
  background: var(--info-bg);
  border-color: var(--info-border);
}

/* --- Sheet card (content surface carrying the cell/grid motif) ------------ */
.sheet {
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.sheet-pad {
  padding: var(--space-4);
}

/* --- Billing page (task-013) ----------------------------------------------- */
/* De-emphasized helper text (trial/period captions, "unconfigured" notes) -
   one muted tone reused everywhere rather than inventing per-page grays. */
.muted {
  color: var(--ink-3);
  font-size: var(--step--1);
}

.billing-status {
  margin-block-end: var(--space-3);
}

.billing-toggle {
  display: flex;
  gap: var(--space-1);
  margin-block-end: var(--space-3);
}

.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-3);
}

/* Same surface treatment as .sheet.sheet-pad (card + padding), plus its own
   flex layout - kept separate rather than requiring callers to combine three
   classes on every plan card. */
.plan-card {
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.plan-card-current {
  border-color: var(--green-4);
  box-shadow: 0 0 0 2px var(--green-4);
}

.plan-price {
  font-family: var(--mono);
  font-size: var(--step-2);
  color: var(--ink);
}

.plan-features {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-2);
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--ink-2);
}

.plan-features li::before {
  content: "✓ ";
  color: var(--ok);
  font-weight: 700;
}

/* --- Auth pages (task-009) -------------------------------------------------
   Register/login/reset all share one narrow, centered sheet card - the form
   is the entire decision on the page, no competing content. Register is a
   conversion surface (it claims the scrape-preview), so it stays the same
   shape as login rather than a heavier "marketing" layout: the fastest path
   to a live widget is the sell. */
.auth {
  padding-block: var(--space-5);
}

.auth-card {
  max-width: 420px;
  margin-inline: auto;
}

.auth-lede {
  color: var(--ink-2);
  max-width: none; /* already width-constrained by .auth-card */
}

.auth-foot {
  max-width: none;
  text-align: center;
  font-size: 0.9rem;
  color: var(--ink-3);
}

/* The divider between the password form and "Continue with Google" - a
   hairline on each side of the word, matching the sheet's grid motif. */
.auth-divider {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--grid-2);
}

/* --- Form fields (shared by every auth form) ------------------------------ */
.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Mono label voice (see h5/h6) - fields are named like spreadsheet columns. */
.form-field label {
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.form-field input,
.form-field select {
  font: inherit;
  font-size: 0.96rem;
  padding: 11px 14px;
  border: 1px solid var(--grid-2);
  border-radius: var(--radius-sm);
  background: var(--paper-2);
  color: var(--ink);
}

.form-field input::placeholder {
  color: var(--ink-4);
}

/* `<input type=color>` renders its own square swatch - the padding above
   would just add dead space around it, so it earns a narrower override. */
.form-field input[type="color"] {
  padding: 4px;
  width: 72px;
  height: 44px;
}

/* --- Brand page (task-020) ------------------------------------------------- */
.brand-layout {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(240px, 320px);
  gap: var(--space-3);
  align-items: start;
}

@media (max-width: 720px) {
  .brand-layout {
    grid-template-columns: 1fr;
  }
}

.brand-swatches {
  display: flex;
  gap: var(--space-2);
}

.brand-swatch {
  flex: 1;
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  color: #fff;
  font-family: var(--mono);
  font-size: var(--step--1);
  text-align: center;
}

.brand-resets {
  display: flex;
  gap: var(--space-1);
  margin-block-start: var(--space-3);
}

/* Full-width primary/secondary action, used for every auth form's submit and
   the Google button - a form this narrow reads better with one full-bleed CTA
   than a button sized to its own label. */
.btn-block {
  width: 100%;
  justify-content: center;
}

/* --- Landing page (task-017) ----------------------------------------------
   The public conversion surface. Ported from design/explorations/04; every
   value routes through the shared tokens above so it stays on-system. Sections
   own their own `.wrap`; bands (`.band-paper`) provide full-bleed separation. */

/* Section rhythm: generous vertical bands, one shared measure for headings. */
.hero,
main > section {
  padding-block: var(--space-5);
}

.sec-head {
  max-width: 60ch;
  margin-block-end: var(--space-4);
}

/* Alternating paper band to separate sections without hard rules everywhere. */
.band-paper {
  background: var(--paper-2);
  border-block: 1px solid var(--grid);
}

/* --- Hero ------------------------------------------------------------------ */
.hero-grid {
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: var(--space-5);
  align-items: center;
}

@media (max-width: 940px) {
  .hero-grid {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }
}

.hero-accent {
  color: var(--green);
  font-style: italic;
}

.hero .lede,
.preview-hero .lede {
  max-width: 46ch;
  font-size: var(--step-1);
  color: var(--ink-2);
}

.microcopy {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-size: var(--step--1);
  color: var(--ink-3);
}

/* A small check before each microcopy item, in the accent-green voice. */
.microcopy span::before {
  content: "✓";
  color: var(--green);
  font-weight: 700;
  margin-inline-end: 6px;
}

/* --- Paste-URL scrape form ------------------------------------------------- */
.field-label {
  display: block;
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.scrape-input {
  display: flex;
  gap: var(--space-1);
  padding: 6px;
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}

.scrape-input:focus-within {
  border-color: var(--green);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--green) 12%, transparent);
}

.scrape-url {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  font: inherit;
  font-family: var(--mono);
  color: var(--ink);
  padding: 8px 10px;
}

.scrape-url::placeholder {
  color: var(--ink-4);
}

.scrape-input .btn {
  flex: none;
}

/* Attestation checkbox rows — the permission the scrape contract requires. */
.attest {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.9rem;
  color: var(--ink-2);
  cursor: pointer;
}

.attest input {
  margin-top: 3px;
  flex: none;
  accent-color: var(--green);
}

/* In-flight scrape progress block swapped in by HTMX. */
.scrape-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* HTMX request-in-flight: dim the disabled submit so "working" reads honestly. */
.scrape-form button[disabled] {
  opacity: 0.6;
  cursor: progress;
}

/* --- Hero demo (sheet -> pin) ---------------------------------------------- */
.hero-demo {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.demo-topbar,
.demo-map-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 10px 14px;
  border-bottom: 1px solid var(--grid);
  background: var(--paper-2);
}

.demo-title,
.demo-map-label {
  font-family: var(--mono);
  font-size: var(--step--1);
  color: var(--ink-3);
}

.demo-table-scroll {
  overflow-x: auto;
}

.demo-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 0.72rem;
}

.demo-table th,
.demo-table td {
  text-align: left;
  padding: 8px 12px;
  border-bottom: 1px solid var(--grid);
  white-space: nowrap;
  color: var(--ink-2);
}

.demo-table thead th {
  color: var(--green);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--green-3);
  border-bottom: 1px solid var(--green-4);
}

.demo-table tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--paper-2) 60%, transparent);
}

/* The cell landing.js "edits": a coral inset ring while typing, green when synced. */
#demo-edit-cell.is-editing {
  box-shadow: inset 0 0 0 2px var(--accent);
  color: var(--ink);
  font-weight: 700;
}

#demo-edit-cell.is-synced {
  box-shadow: inset 0 0 0 2px var(--green-2);
  color: var(--ink);
}

.demo-map {
  background: var(--green-3);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.demo-map-head {
  background: var(--card);
}

.demo-map-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* The accent pin animates its position; transition drives the sheet->pin move. */
.demo-live-pin {
  transition: transform 0.6s cubic-bezier(0.3, 0.9, 0.3, 1.4);
  transform-box: fill-box;
  transform-origin: center bottom;
}

.demo-live-pin.is-moved {
  transform: translate(96px, -22px);
}

.demo-caption {
  text-align: center;
  font-family: var(--mono);
  font-size: var(--step--1);
  color: var(--ink-3);
  margin: 0;
}

/* --- How it works ---------------------------------------------------------- */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-3);
}

.step {
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
}

.step-num {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--green-3);
  border: 1px solid var(--green-4);
  color: var(--green);
  font-family: var(--mono);
  font-weight: 700;
  margin-block-end: var(--space-2);
}

/* --- Pricing --------------------------------------------------------------- */
.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-3);
  align-items: stretch;
}

.price-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  position: relative;
}

/* The featured tier earns a green frame — the one visual emphasis on the grid. */
.price-card-featured {
  border-color: var(--green);
  box-shadow: 0 24px 60px -30px color-mix(in srgb, var(--green) 45%, transparent);
}

.price-flag {
  position: absolute;
  top: calc(-1 * var(--space-1) - 6px);
  left: var(--space-4);
}

.price-name {
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.price-amount {
  font-family: var(--serif);
  font-size: var(--step-3);
  color: var(--ink);
  line-height: 1;
  margin: 0;
}

.price-per {
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--ink-4);
  font-weight: 500;
}

.price-caption {
  color: var(--ink-2);
  margin-block: var(--space-1) var(--space-2);
}

.price-features {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 9px;
  color: var(--ink-2);
  font-size: 0.9rem;
}

.price-features li::before {
  content: "✓ ";
  color: var(--green-2);
  font-weight: 700;
}

.price-card .btn {
  margin-top: auto;
}

.pricing-note {
  text-align: center;
  margin-block-start: var(--space-3);
  color: var(--ink-3);
  font-size: 0.9rem;
  max-width: none;
}

/* --- Comparison ------------------------------------------------------------ */
.compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow-sm);
}

@media (max-width: 640px) {
  .compare {
    grid-template-columns: 1fr;
  }
}

.compare-col {
  padding: var(--space-4);
}

.compare-them {
  border-right: 1px solid var(--grid);
  background: color-mix(in srgb, var(--paper-2) 70%, transparent);
}

@media (max-width: 640px) {
  .compare-them {
    border-right: 0;
    border-bottom: 1px solid var(--grid);
  }
}

.compare-who {
  display: block;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-block-end: var(--space-2);
}

.compare-them .compare-who {
  color: var(--ink-4);
}

.compare-us .compare-who {
  color: var(--green);
}

.compare-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.compare-them li::before {
  content: "×";
  color: var(--ink-4);
  font-weight: 700;
  margin-inline-end: 8px;
}

.compare-us li::before {
  content: "✓";
  color: var(--green-2);
  font-weight: 700;
  margin-inline-end: 8px;
}

/* --- Final CTA ------------------------------------------------------------- */
.final-card {
  text-align: center;
  background: linear-gradient(180deg, var(--paper-2), var(--card));
  border: 1px solid var(--grid-2);
  border-radius: 22px;
  box-shadow: var(--shadow);
  padding: var(--space-5) var(--space-4);
}

.final-cta-row,
.preview-cta-row {
  display: flex;
  gap: var(--space-2);
  justify-content: center;
  flex-wrap: wrap;
}

.final-note {
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  color: var(--ink-4);
  max-width: none;
}

/* --- Preview page (task-017) ----------------------------------------------- */
.preview-hero {
  padding-block: var(--space-5) var(--space-3);
}

.preview-cta-row {
  justify-content: flex-start;
}

/* The real widget mount — a framed stage so it reads as "your live locator". */
.preview-stage {
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--card);
}

storadar-map {
  display: block;
  width: 100%;
}

.preview-claim {
  margin-block-start: var(--space-4);
  text-align: center;
}

.preview-claim .preview-cta-row {
  justify-content: center;
}

/* Inline monospace snippet (the build command in the dev "assets missing" note). */
.mono-inline {
  font-family: var(--mono);
  font-size: 0.9em;
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--paper);
  border: 1px solid var(--grid-2);
}

/* Reduced motion: honour the OS preference across the whole surface. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Admin console nav: active section (task-037) ------------------------- */
/* The current section reads heavier; in the admin (mono) chrome it also takes
   the green identity so the working surface always says where you are. */
.nav-links a.is-active {
  color: var(--ink);
  font-weight: 600;
}

.nav[data-variant="admin"] .nav-links a.is-active {
  color: var(--green);
}

/* --- Onboarding checklist (task-037) -------------------------------------- */
.checklist-head {
  padding-block-start: var(--space-4);
}

.checklist-lede {
  max-width: 56ch;
  color: var(--ink-2);
  font-size: var(--step-1);
}

/* The steps are an ordered list, but the marker column replaces the numbers. */
.checklist {
  list-style: none;
  padding: 0;
  margin-block: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.checklist-step {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--card);
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

/* The current step is the only call to action, so it earns the accent frame. */
.checklist-step.step-current {
  border-color: var(--green-4);
  box-shadow: 0 0 0 2px var(--green-4);
}

/* Finished and not-yet-reachable steps recede so the eye lands on "now". */
.checklist-step.step-done,
.checklist-step.step-upcoming,
.checklist-step.step-optional {
  box-shadow: none;
}

.checklist-step.step-upcoming {
  opacity: 0.72;
}

/* Round status marker in the left rail. */
.step-marker {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--grid-2);
  color: var(--ink-3);
}

.step-done .step-marker {
  color: #fff;
  background: var(--green);
  border-color: var(--green);
}

.step-current .step-marker {
  border-color: var(--green);
  color: var(--green);
}

.step-marker svg {
  width: 18px;
  height: 18px;
}

.step-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: currentColor;
}

.step-opt {
  font-family: var(--mono);
  font-weight: 600;
}

.step-head {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.step-head h2 {
  font-size: var(--step-1);
  margin: 0;
}

/* A stack of form controls inside a step, on the shared flow rhythm. */
.step-form {
  margin-block-start: var(--space-1);
}

/* Each sheet-connect option is a nested card so the three paths read as peers. */
.connect-option {
  box-shadow: none;
}

.connect-option-title {
  font-size: var(--step-0);
  margin: 0;
}

/* The service-account address is data — render it in the mono voice. */
.sa-email {
  font-family: var(--mono);
  font-size: 0.9em;
  padding: 1px 5px;
  background: var(--green-3);
  border: 1px solid var(--green-4);
  border-radius: 6px;
}

.byo-waiting p,
.byo-error p {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.account-footer {
  margin-block: var(--space-4);
  padding-block-start: var(--space-3);
  border-top: 1px solid var(--grid);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* --- Embed page (task-040) -------------------------------------------------- */
.embed-snippet-card {
  overflow: hidden;
}

.embed-snippet-block {
  position: relative;
}

.embed-snippet {
  margin: 0;
  padding: var(--space-3);
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius);
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.85em;
  line-height: 1.5;
}

.embed-copy-btn {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
}

.embed-center-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.embed-center-helper {
  align-self: flex-start;
}

.embed-rotate {
  border-color: var(--grid-2);

/* --- Mini editor (task-039: inline table + pin-drag map) ------------------- */
.editor-head {
  margin-top: var(--space-3);
}

/* Map beside the table on wide screens; stacked on narrow. The map earns a
   generous min-height so pins are draggable without fighting for space. */
.editor-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  margin-top: var(--space-3);
}

@media (min-width: 960px) {
  .editor-layout {
    grid-template-columns: minmax(320px, 420px) minmax(0, 1fr);
    align-items: start;
  }
}

.editor-map {
  position: relative;
  min-height: 360px;
  height: 52vh;
  border: 1px solid var(--grid-2);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper-2);
}

/* Shown until (or unless) the MapLibre script paints over it. */
.editor-map-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
  text-align: center;
  color: var(--ink-3);
  font-size: var(--step--1);
}

.editor-status:empty {
  display: none;
}

/* Horizontal scroll is contained to the table so the page body never scrolls. */
.editor-table-scroll {
  overflow-x: auto;
  border: 1px solid var(--grid);
  border-radius: var(--radius);
}

.editor-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.94rem;
}

.editor-table thead th {
  text-align: left;
  padding: 10px 12px;
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--grid-2);
  background: var(--paper);
  white-space: nowrap;
}

.editor-row th,
.editor-row td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--grid);
  vertical-align: top;
  text-align: left;
}

.editor-cell-name {
  font-weight: 600;
  color: var(--ink);
}

.editor-pending-note {
  display: block;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--amber);
}

.editor-actions {
  white-space: nowrap;
}

.btn-sm {
  padding: 6px 12px;
  font-size: var(--step--1);
}

/* The expandable detail row: form / confirm / warn / lost states. */
.editor-detail-cell {
  padding: var(--space-2) var(--space-3);
  background: var(--paper);
  border-bottom: 1px solid var(--grid-2);
}

.editor-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-2);
}

.editor-form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  align-items: center;
  margin-top: var(--space-2);
}

.editor-saved {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-2);
}

/* Warn-before-discard + lost-to-sheet read as caution, not success. */
.editor-warn,
.editor-lost {
  border-left: 3px solid var(--accent);
  padding-left: var(--space-2);
}

.editor-lost-head {
  font-weight: 600;
  color: var(--accent);
}

.editor-lost-label {
  font-family: var(--mono);
  font-size: var(--step--1);
  color: var(--ink-3);
}

.editor-empty {
  padding: var(--space-4);
  border: 1px dashed var(--grid-2);
  border-radius: var(--radius);
  text-align: center;
  background: var(--paper);
}

.editor-add {
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--grid);
  border-radius: var(--radius);
  background: var(--paper-2);
}

/* --- Sheet status panel (task-038) ---------------------------------------- */
/* Where an anxious customer lands when sync breaks: chip + headline, then the
   explanation and action cards. Reuses .sheet / .chip / .actions so it stays in
   the same design system rather than fighting it. */
.sheet-status-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* The paused (mass-delete) and re-share cards read as caution via a left rule,
   matching the editor-warn treatment — one caution motif reused, not reinvented. */
.sheet-paused,
.sheet-reshare {
  border-left: 3px solid var(--amber);
}

.sheet-action-form {
  display: inline;
}

/* Copyable service-account address: mono block + copy button on one line. */
.sheet-sa-block {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
}

.sheet-sa-block code {
  padding: 6px 10px;
  border: 1px solid var(--grid-2);
  border-radius: var(--radius-sm);
  background: var(--paper);
  font-family: var(--mono);
  font-size: var(--step--1);
  word-break: break-all;
}

/* Recent activity feed: a plain timeline, newest first. */
.sheet-activity {
  list-style: none;
  padding: 0;
  margin: 0;
}

.sheet-activity li {
  padding-block: 8px;
  border-bottom: 1px solid var(--grid);
  color: var(--ink-2);
  font-size: 0.92rem;
}

.sheet-activity li:last-child {
  border-bottom: none;
}
