/* =============================================================================
   Florida Fence — site styles.

   Read DESIGN.md before changing anything here. v1 (Ethan, 2026-09-06): a plain
   white page — Trello, Basecamp, Linear light mode — system font at 14px, 1px
   #dfe1e6 borders, flat fills, no webfonts, no hero, no all-caps, no dark mode.
   v2 (Ethan, same day, later): "WAY too bland, make it more modern" and "the
   quoting engine boxed in and the center of attention". So: ONE saturated brand
   hue used on shapes — the primary button, links, the focus ring, the
   3px top border of THE featured box, the small line icons, the slideshow
   progress — and its pale tint as the section background the featured
   box sits on. Fence Works (2026-09-08) re-hues this to "Cedar & Iron"
   (#8a4a2c / #f3e3d8) — same rule, different tenant's brand color. Radius up to 8px on cards, 6px on buttons; shadows no larger than
   0 1px 3px; 150ms hover/focus transitions and the slideshow crossfade are the
   only motion. Largest text is the 28px page title; the featured heading is
   24px. Every colour below is a DESIGN.md palette token.

   `color-scheme: light` is declared on purpose: there is no dark mode, and form
   controls must render light against the white page.
   ========================================================================== */

:root {
  color-scheme: light;

  --bg: #ffffff;
  --bg-alt: #f4f5f7;
  --panel: #ebecf0;
  --card: #ffffff;
  --border: #dfe1e6;
  --text: #172b4d;
  --muted: #5e6c84;

  /* v2 §1: the brand hue, its tint, and a hover shade. `--accent` is kept as an
     alias so the v1 rules (links, the Home control, the focus ring) read the
     brand without every selector being rewritten. */
  /* Fence Works — "Cedar & Iron" (Ethan, 2026-09-08). Cedar-brown accent,
     matching brand kit https://claude.ai/code/artifact/c705bc05-cea4-4332-a277-4db1582e038d */
  --brand: #8a4a2c;
  --brand-tint: #f3e3d8;
  --brand-hover: #6f3a21;
  --accent: var(--brand);
  --accent-hover: var(--brand-hover);

  --ok: #216e4e;      --ok-bg: #dcfff1;
  --warn: #974f0c;    --warn-bg: #fff7d6;
  --danger: #ae2a19;  --danger-bg: #ffedeb;

  --font: system-ui, -apple-system, "Segoe UI", Inter, sans-serif;
  --radius: 6px;          /* buttons, inputs, photos, small blocks */
  --radius-card: 8px;     /* cards and the featured box */
  --radius-tag: 4px;      /* tiny tags / chips */
  --shadow-card: 0 1px 2px rgba(9, 30, 66, .08);
  --shadow-featured: 0 1px 3px rgba(9, 30, 66, .12);
  --ease: 150ms ease;
  --nav-h: 56px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
}

/* v2 §3 — the whole type scale: 14 body, 16 lead, 20 section heading, 24 the
   featured-box heading, 28 the one page title. Weight 600, line-height 1.2. */
h1, h2, h3 { font-weight: 600; line-height: 1.2; color: var(--text); margin: 0; }
h1 { font-size: 28px; }
h2 { font-size: 20px; }
h3 { font-size: 16px; }
p { margin: 0 0 .6rem; }

a { color: var(--accent); transition: color var(--ease); }
a:hover { color: var(--accent-hover); }
img { max-width: 100%; height: auto; display: block; }
strong { font-weight: 600; }

/* Line icons (v2 §6): 20px, single colour, inherit from the parent. */
.icon {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
}

/* =========================================================================
   Top bar — white, 56px, business name 18px/600 left, phone (with its icon)
   and one link right, 1px bottom border (v2 §9). This is also Chris's "home
   button": on every sub-page a labelled Home link sits at the right.
   ========================================================================= */
.nav {
  position: sticky;
  top: 0;
  /* Leaflet's .leaflet-top / .leaflet-bottom control containers are z-index 1000
     (vendor/leaflet/leaflet.css). An equal z-index is resolved by DOM order and
     <main> comes after <nav>, so the map's +/- control would paint OVER the bar.
     Anything here must stay strictly above 1000. */
  z-index: 1001;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.nav-inner {
  max-width: 1200px;
  margin: 0 auto;
  min-height: var(--nav-h);
  padding: 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}
.nav-brand {
  color: var(--text);
  text-decoration: none;
  font-size: 18px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
}
.nav-brand svg { flex: 0 0 auto; }
.nav-brand:hover { color: var(--text); }
.nav-right { margin-left: auto; display: flex; align-items: center; gap: 1.25rem; flex: 0 0 auto; }
.nav-link { white-space: nowrap; font-weight: 500; text-decoration: none; }
.nav-link:hover { text-decoration: underline; }
.nav-home {
  color: var(--accent);
  text-decoration: underline;
  white-space: nowrap;
  font-weight: 500;
}
.nav-home:hover, .nav-home:focus-visible { color: var(--accent-hover); }
.nav-call {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
  white-space: nowrap;
}
.nav-call .icon { color: var(--brand); }
.nav-call:hover { color: var(--brand); }

@media (max-width: 480px) {
  .nav-link { display: none; }
  .nav-inner { gap: .6rem; padding: 0 1rem; }
}

/* =========================================================================
   Buttons — the primary button is the brand hue; 6px radius; 150ms.
   ========================================================================= */
button, .btn {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: .5rem .9rem;
  background: var(--brand);
  color: #fff;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  white-space: nowrap;
  line-height: 1.4;
  transition: background-color var(--ease), color var(--ease), border-color var(--ease), box-shadow var(--ease);
}
button:hover, .btn:hover { background: var(--brand-hover); color: #fff; }
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-hover); }
button.secondary, .btn-secondary {
  background: var(--card);
  color: var(--text);
  border-color: var(--border);
  box-shadow: var(--shadow-card);
}
button.secondary:hover, .btn-secondary:hover { background: var(--bg-alt); color: var(--text); }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* =========================================================================
   Layout — 32–48px between sections on desktop, 24px on mobile (v2 §8).
   ========================================================================= */
.wrap { max-width: 720px; margin: 0 auto; padding: 1.5rem 1rem 0; }

/* Landing-page columns (Ethan, 2026-09-06: "the instant quote engine on the left
   side, a gallery that auto slides on the right", desktop only). One DOM: below
   960px .cols is the single column the page always was — tool, then photos.
   From 960px the landing wrapper widens to 1200px and .cols-two splits 58/42,
   the photo column sticking below the top bar while the tool scrolls. A page
   with no photos never gets .cols-two, so the tool keeps the full width. */
.cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
@media (min-width: 960px) {
  .wrap-wide { max-width: 1200px; }
  .wrap { padding: 2.5rem 1.25rem 0; }
  .cols-two { grid-template-columns: minmax(0, 58fr) minmax(0, 42fr); gap: 1.25rem; align-items: start; }
  .col-gallery { position: sticky; top: calc(var(--nav-h) + 1px + 1rem); }
  .stage { padding: 1.25rem; }
  .featured { padding: 24px; }
  .trust { gap: 1rem 2.5rem; }
}

/* The one page title and its lead paragraph. */
.page-title { margin: 0 0 .5rem; }
.lede { margin: 0; font-size: 16px; line-height: 1.5; color: var(--muted); max-width: 62ch; }

/* v2 §1/§2: the pale-tint section the featured box (and, on the landing page,
   the gallery beside it) sits on. Inside the page width, never a full-bleed band. */
.stage {
  background: var(--brand-tint);
  border-radius: var(--radius-card);
  padding: .75rem;
  margin: 1.5rem 0 0;
}

/* THE featured box (v2 §2): the only element on any page with the 3px brand top
   border, the deeper shadow and a 24px heading. The instant-quote tool — address,
   map open on load, tracer, side picker, footage band, lead form — lives
   inside it, on both / and /quote. */
.featured {
  background: var(--card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-featured);
  padding: 20px;
}
.featured-title { font-size: 24px; margin: 0 0 .25rem; }
.featured-sub { color: var(--muted); margin: 0 0 1rem; }

/* The three steps of the quote flow, a small row at the top of the box. */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .75rem;
}
.step { display: flex; align-items: flex-start; gap: .5rem; font-size: 13px; color: var(--muted); line-height: 1.4; }
.step .icon { color: var(--brand); margin-top: .05rem; }
.step strong { display: block; color: var(--text); font-size: 14px; }

/* Blocks inside the featured box are separated by a single 1px rule, not by
   nested cards: one box, several steps. */
.featured > .tool-step,
.featured > .next-step,
.featured > .lead-card,
.featured > .estimate-card { border-top: 1px solid var(--border); padding-top: 1rem; margin-top: 1rem; }
.tool-step h3, .next-step h3, .lead-card h3, .estimate-card h3 { margin: 0 0 .35rem; }

/* Ordinary cards: 1px border, 8px radius, the small shadow. */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1rem;
  margin-bottom: 1rem;
}
.card h2 { margin: 0 0 .35rem; }
.muted { color: var(--muted); font-size: 13px; }
.tiny { font-size: 12px; line-height: 1.45; }
.prose h2 { margin-top: 1rem; }
#your-home { scroll-margin-top: calc(var(--nav-h) + 8px); }

/* The trust line — three quiet items with line icons under the featured
   section, behind the single 1px rule v2 §8 asks for. Not a hero. */
.trust {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1.5rem;
  margin: 2rem 0 0;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--border);
  color: var(--muted);
}
.trust li { display: inline-flex; align-items: center; gap: .5rem; }
.trust .icon { color: var(--brand); }

/* The example-house note that sits above the seeded tool on the landing page.
   It is load-bearing copy, not decoration: a visitor must never mistake the
   worked example for a quote on their own home. */
.demo-note {
  margin: 1rem 0 0;
  padding: .5rem .75rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius);
  background: var(--bg-alt);
  color: var(--text);
}

.next-step .btn { margin-top: .25rem; }

@media (max-width: 600px) {
  .wrap { padding-top: 1.25rem; }
  .stage { padding: .5rem; margin-top: 1.25rem; }
  .featured { padding: 1rem; }
  .steps { grid-template-columns: minmax(0, 1fr); gap: .5rem; }
  .trust { margin-top: 1.5rem; padding-top: 1.25rem; }
}

/* =========================================================================
   Form controls
   ========================================================================= */
.controls, .row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-top: .5rem; }
.pickers { align-items: flex-end; }
/* The single-product line that stands where the pickers would be. Plain text,
   body size, no colour: it is a statement, not a control. */
.product-line { margin: 0 .5rem 0 0; font-size: 14px; color: var(--text); }
label { display: flex; flex-direction: column; font-size: 13px; color: var(--muted); gap: .2rem; }
input, select {
  font-family: var(--font);
  font-size: 14px;
  padding: .5rem .6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--text);
  width: 100%;
  transition: border-color var(--ease), box-shadow var(--ease);
}
input:focus, select:focus { border-color: var(--brand); outline: 2px solid var(--brand); outline-offset: 0; }
input::placeholder { color: var(--muted); }
.address-row { display: flex; gap: .5rem; margin-top: .5rem; }
.address-row input { flex: 1; }
.perimeter { margin-left: auto; white-space: nowrap; color: var(--muted); }

/* =========================================================================
   Map — the satellite imagery inside is content; the frame is plain. It is
   OPEN on load (v2 §2): there is no toggle and nothing hides it.
   ========================================================================= */
.map-frame { position: relative; margin: .5rem 0 0; }
#map {
  height: clamp(320px, 46vh, 440px);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--panel);
}
.demo-chip {
  position: absolute;
  /* TOP-RIGHT, not top-left: Leaflet's +/- zoom control is anchored top-left and
     sits above this (z-index 1000 vs 500). The worked-example argument rests on
     this label being readable. */
  top: .5rem; right: .5rem;
  z-index: 500;                     /* above tiles, below Leaflet controls */
  margin: 0;
  padding: .15rem .5rem;
  border-radius: var(--radius-tag);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
}
.demo-chip[hidden] { display: none; }

/* =========================================================================
   Provenance banner / candidate picker
   ========================================================================= */
.banner {
  margin: .5rem 0 0;
  padding: .5rem .75rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--muted);
  border-radius: var(--radius);
  background: var(--bg-alt);
  color: var(--text);
}
.banner-ask  { border-left-color: var(--brand); }
.banner-ok   { border-left-color: var(--ok); }
.banner-warn { border-left-color: var(--warn); }

.picker {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .75rem;
  background: var(--bg-alt);
  margin: .5rem 0;
}
.picker-q { margin: 0 0 .5rem; }
.candidate-list { display: grid; gap: .5rem; }
.candidate {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border);
  padding: .5rem .75rem;
  white-space: normal;
  font-weight: 400;
}
.candidate:hover { background: var(--bg-alt); color: var(--text); }
.candidate-primary { border-color: var(--brand); }
.cand-label { display: block; font-weight: 600; }
.cand-meta { display: block; font-size: 12px; color: var(--muted); margin-top: .1rem; }
.linkish {
  background: none;
  border: 0;
  color: var(--accent);
  padding: .4rem 0 0;
  font-weight: 400;
  text-decoration: underline;
}
.linkish:hover { background: none; color: var(--accent-hover); }

/* Draggable corner markers on the map. They sit on satellite imagery next to
   tracer.js's yellow polyline, so they match it; this is content inside the map. */
.vertex-dot {
  background: #ffd54a;
  border: 2px solid #6b5200;
  border-radius: 50%;
  cursor: grab;
}
.vertex-dot:active { cursor: grabbing; }

.extra-building { margin: .5rem 0 0; }
.check { flex-direction: row; align-items: flex-start; gap: .5rem; color: var(--text); font-size: 14px; }
.check input[type="checkbox"] { width: auto; margin-top: .2rem; flex: 0 0 auto; }

/* =========================================================================
   Which sides do you want fenced?

   Not a fixed set of options like a roof shape — the rows are generated by
   tracer.js from the parcel's sides, so the count varies per property (measured
   parcels here reduced 5-41 raw vertices down to 4 sides). The row is a label
   wrapping a checkbox: the whole row is the hit target, which matters on a phone
   held at arm's length in someone's driveway.
   ========================================================================= */
.why { margin-bottom: .75rem; }
.side-picker { display: grid; gap: .375rem; }
.side-opt {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: .5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem .625rem;
  cursor: pointer;
  background: var(--card);
  color: var(--text);
  font-size: 14px;
  transition: border-color var(--ease), background-color var(--ease);
}
.side-opt:hover { background: var(--bg-alt); }
.side-opt input[type="checkbox"] { width: auto; margin: 0; flex: 0 0 auto; accent-color: var(--brand); }
.side-opt:has(input:checked), .side-opt.is-checked {
  border-color: var(--brand);
  background: var(--brand-tint);
}
.side-name { font-weight: 600; }
.side-len { color: var(--muted); font-size: 13px; margin-left: auto; font-variant-numeric: tabular-nums; }
.side-curved { color: var(--muted); font-size: 12px; }
.side-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin-top: .625rem; }
.side-actions[hidden] { display: none; }
.gates-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .75rem; }
.gates-row[hidden] { display: none; }
.gates-row input[type="number"] { width: 4.5rem; }
.legend { margin-top: .5rem; }
.swatch { display: inline-block; width: 14px; height: 4px; border-radius: 2px; vertical-align: middle; margin-right: .2rem; }
.swatch-fenced { background: var(--brand); }
.swatch-unfenced { background: var(--muted); }

/* =========================================================================
   The band — its WIDTH is the message, so the bar must stay legible.
   Every figure in here is LINEAR FEET. No money is rendered on this element.
   ========================================================================= */
.fence-band {
  margin: 0 0 .75rem;
  padding: .75rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-alt);
}
.band-label { margin: 0; font-size: 13px; color: var(--muted); }
.band-figure { margin: 0 0 .4rem; font-size: 20px; font-weight: 600; line-height: 1.3; }
.band-bar { height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.band-fill { height: 100%; border-radius: 3px; transition: width .25s ease; }
.band-tight { background: var(--ok); }
.band-mid   { background: var(--warn); }
.band-wide  { background: var(--danger); }
.band-spread { margin: .3rem 0 .4rem; }
.band-source { margin: .3rem 0 .1rem; font-weight: 600; }
.band-basis { margin: .1rem 0 .2rem; }
.band-assumption { margin: 0; }

/* =========================================================================
   Estimate (money lives here and ONLY here — see app/static/app.js, which does
   the single cents -> dollars conversion at the render boundary)
   ========================================================================= */
#estimate-box { margin-top: .75rem; }
.range { font-size: 20px; font-weight: 600; line-height: 1.3; }
.disclaimer { color: var(--muted); font-size: 13px; margin: .25rem 0 0; }

/* =========================================================================
   Lead form — the last step inside the featured box.
   ========================================================================= */
.lead-form { display: grid; gap: .5rem; margin-top: .5rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.lead-form button { grid-column: 1 / -1; justify-self: start; }
.lead-result { margin-top: .5rem; font-weight: 600; }

/* =========================================================================
   Gallery — renders ONLY when app/static/photos/MANIFEST.json has real entries.
   There is deliberately no empty state here: no dashed boxes, no stock imagery.
   The photos are content and carry the personality (v2 §7): 6px radius,
   captions in the muted grey, the position bar in the brand hue. One slide
   shows at a time; the rest are display:none so their lazy images stay
   unfetched until gallery.js warms the next one. A leaving slide keeps
   .is-shown for the 400 ms crossfade, and both slides share one grid cell so
   nothing jumps.
   ========================================================================= */
.gallery-card { margin-bottom: 0; }
.slides { margin-top: .5rem; border-radius: var(--radius); }
.slide-list { list-style: none; margin: 0; padding: 0; display: grid; }
.slide { grid-area: 1 / 1; display: none; opacity: 0; transition: opacity .4s ease; }
.slide.is-shown { display: block; }
.slide.is-active { display: block; opacity: 1; }
.shot { margin: 0; }
.shot img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius); background: var(--panel); }
.shot figcaption { padding: .5rem 0 0; font-size: 13px; color: var(--muted); min-height: 2.3em; }
.slide-controls { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; }
.slide-counter { margin: 0 auto; }
.slide-progress { height: 3px; margin-top: .75rem; border-radius: 2px; background: var(--border); overflow: hidden; }
.slide-progress-fill { height: 100%; border-radius: 2px; background: var(--brand); transition: width .4s ease; }
@media (prefers-reduced-motion: reduce) {
  .slide, .slide-progress-fill, .band-fill, a, button, .btn, input, select, .side-opt { transition: none; }
}

/* =========================================================================
   Footer — on the light grey, behind its own 1px rule.
   ========================================================================= */
.foot { margin-top: 3rem; border-top: 1px solid var(--border); background: var(--bg-alt); color: var(--muted); }
.foot-inner { max-width: 720px; margin: 0 auto; padding: 1.5rem 1rem 2rem; font-size: 13px; }
.foot p { margin: 0 0 .35rem; }
.foot-name { color: var(--text); font-weight: 600; }
.foot-links { margin-top: .5rem; }
.attrib { margin-top: .75rem; }

/* A secondary button promoted to "the next thing to press" after a rough geocode
   (tracer.js). Same brand hue as primary, no extra colour. */
button.next-step, .btn.next-step { background: var(--brand, #8a4a2c); color: #fff; border-color: var(--brand, #8a4a2c); }
