/* ==========================================================================
   WIREFRAME GRAPHITE — shared tokens + components

   NOT AN EXTRACTED SYSTEM. Built from scratch 2026-08-05 against a single
   reference wireframe screenshot supplied by Jarrett, not a live website.
   Phases 1 to 3 of /design-system-extract (crawl, live-DOM probe, CSS sweep)
   do not apply, and two Phase 5 gates are structurally unrunnable here:
   verbatim-audit.py and the source visual diff both need a crawl corpus.
   Every other gate runs. Recorded in brand-spec.md.

   WHAT THIS IS FOR. A lo-fi planning artifact. It exists to align a client on
   page STRUCTURE before any design decision is made, so it is deliberately
   grayscale, deliberately set in placeholder copy, and deliberately shows
   image slots as crossed boxes rather than photographs. It is not a look a
   client site ships in. That is the point: an unfinished-looking wireframe
   never gets mistaken for a design proposal, and a polished one always does.

   EVERY PLACEHOLDER IS DRAWN IN CSS, NOT SHIPPED AS AN IMAGE. The crossed
   image box, the map grid, the portrait circle, the icon square and the logo
   plate are all gradients and borders. Three consequences, all wanted:
   they recolour with the palette at runtime, there is no asset that can
   404 or go stale, and the kit ships with exactly one real file in assets
   (the LOGO plate SVG). asset-audit.py has almost nothing to check because
   there is almost nothing to get wrong.

   THE ACCENT IS A GROUND, NEVER TEXT ON PAPER. --accent measures 5.10:1
   against white and 2.78:1 against --ink, so white type on the accent
   passes AA and ink type on it does not. Buttons carry white. Nothing in
   this kit sets --accent as a text colour on a light ground.

   MONOSPACE IS SCOPED, NOT DECORATIVE. The house rule bans mono-caps label
   devices, and slot labels are the entire point of a wireframe. IBM Plex
   Mono is therefore confined to .kit-note slot labels, dimension
   annotations and doc-chrome pattern ids. It never appears as a label above
   an h2, so the banned-device grep stays clean and the rule's intent holds.
   Jarrett approved this scoping at Gate A.

   PALETTE VARIANTS RE-INK THE WHOLE DRAWING, not just the buttons. Blueprint,
   Redline, Vellum and Greenline each override --line, --line-soft and --fill
   alongside the accent, because a blueprint whose line work stayed gray would
   be a gray wireframe with a blue button. Every variant tone is
   luminance-matched to the canonical it replaces, so border weight and text
   contrast are identical across all five palettes. All four variants override
   the SAME eight tokens: a variant that moved a subset would leave a stale
   tone from whichever palette was active before it.

   ONE SCRIPT BUG FOUND HERE, NOW FIXED UPSTREAM. palette-derive.py inherited
   its saturation from the canonical accent. This accent is pure gray, so
   saturation was zero and the script returned the input colour unchanged for
   every target hue. Four identical palettes would have passed palette-audit.py
   clean and the toggle would have done nothing visible. The first three
   variants were derived by driving the script's own match_luminance() with an
   explicit saturation; the script now takes --sat and refuses an achromatic
   canonical outright, and Greenline was derived with it normally.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500&display=swap');

:root {
  /* TYPE */
  --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* COLOR — ink. Explicit hexes rather than rgba(), so the contrast walker
     resolves them exactly and every ratio below is a measured number.
     --ink 14.17:1 on paper · --ink-soft 8.21:1 · --ink-muted 6.19:1 on paper
     and 4.92:1 on --fill · --ink-quiet 4.54:1. All four clear AA on both
     light grounds, so this kit ships zero justified low-contrast text. */
  --ink: #2b2b2b;
  --ink-soft: #4a4a4a;
  --ink-muted: #616161;
  --ink-quiet: #767676;

  /* COLOR — grounds. --bg is the page ground the wireframe frame sits on,
     --bg-pure is the frame itself. Both names are required: the parent
     mobile-responsive.css builds its nav drawer from var(--bg-pure) and
     var(--bg). --paper and --paper-alt are readable aliases used below. */
  --bg: #f4f4f4;
  --bg-pure: #ffffff;
  --paper: #ffffff;
  --paper-alt: #f4f4f4;

  /* COLOR — line work. --line is every 1px box stroke, --line-soft is the
     short bars that stand in for body copy, --fill is placeholder fill.
     None of the three ever carries text, so none has a contrast floor.
     --bar is the copy-bar colour and gets overridden on dark grounds. */
  --line: #9a9a9a;
  --line-soft: #cfcfcf;
  --fill: #e8e8e8;
  --bar: var(--line-soft);
  --border: #9a9a9a;

  /* COLOR — accent. A ground colour, carrying white type at 5.10:1.
     --accent-deep is the dark band, white on it at 10.86:1. */
  --accent: #6e6e6e;
  --accent-deep: #3d3d3d;
  --accent-hover: #565656;
  --tint: #efefef;
  --accent-soft: rgba(110, 110, 110, .14);

  /* GEOMETRY. Square everywhere. A wireframe that rounds its corners has
     started making design decisions, which is the one thing it must not do.
     The parent mobile layer reads var(--radius, 999px) for the nav CTA, so
     declaring 0 here is what keeps the mobile drawer button square too. */
  --radius: 0px;
  --radius-pill: 999px;   /* .wf-avatar and the palette chips only */

  /* SPACE. These four names are read by the parent mobile-responsive.css,
     which shrinks all of them at 768px. Do not rename them. */
  --gutter: 1.5rem;
  --section: 96px;
  --section-sm: 64px;
  --section-lg: 128px;
  --max: 1140px;
}

/* ==========================================================================
   BASE
   ========================================================================== */

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; }

.container {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.container.narrow { max-width: 760px; }

/* ==========================================================================
   TYPE. Display sizes are clamp() so they never punch out of a phone column.
   Inter is a normal-width face, so the floors below are safe at 320px; a
   heavier display face would need them measured against min-content.
   ========================================================================== */

h1, h2, h3, h4 { margin: 0 0 .5em; font-weight: 800; line-height: 1.14; letter-spacing: -.015em; color: var(--ink); }

.display, h1, .h1 { font-size: clamp(38px, 5.4vw, 62px); line-height: 1.06; }
h2, .h2 { font-size: clamp(28px, 3.4vw, 42px); }
h3, .h3 { font-size: clamp(20px, 2vw, 26px); }
h4, .h4 { font-size: 18px; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

.lede { font-size: 18px; line-height: 1.6; color: var(--ink-soft); }
.lede-lg { font-size: 20px; line-height: 1.55; color: var(--ink-soft); }
.small { font-size: 14px; color: var(--ink-muted); }

/* Slot labels, dimension annotations and structural notes. The ONLY place
   monospace appears in brand sections. verbatim-audit.py strips .kit-note
   before matching, which is exactly right: this is copy the kit authors
   about itself, not copy transcribed from anywhere. */
.kit-note {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ==========================================================================
   WIREFRAME PRIMITIVES — the vocabulary every pattern is built from.
   ========================================================================== */

/* The crossed image box. Both diagonals are hard-stop gradients: `to top
   right` puts its 50% transition line through the top-left and bottom-right
   corners, `to bottom right` through the other two, so the pair renders a
   true X at ANY aspect ratio without a background image. The solid
   background-color under the gradients is not optional decoration: a
   gradient-only surface reads as unpainted to the contrast walker and
   reports white-on-white for any label sitting on it. */
.wf-slot {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 10px;
  aspect-ratio: 4 / 3;
  background-color: var(--fill);
  border: 1px solid var(--line);
  background-image:
    linear-gradient(to top right, transparent calc(50% - .5px), var(--line) 50%, transparent calc(50% + .5px)),
    linear-gradient(to bottom right, transparent calc(50% - .5px), var(--line) 50%, transparent calc(50% + .5px));
}
.wf-slot.wide { aspect-ratio: 16 / 9; }
.wf-slot.square { aspect-ratio: 1 / 1; }
.wf-slot.portrait { aspect-ratio: 3 / 4; }
.wf-slot.tall { aspect-ratio: 3 / 5; }
.wf-slot.flush { aspect-ratio: auto; height: 100%; min-height: 180px; }

/* Copy bars. These stand in for body text, so they are decorative <span>s
   with no text content and no contrast floor. Widths are deliberate: real
   paragraphs end short, and a stack of equal-length bars reads as a table. */
.wf-bars { display: flex; flex-direction: column; gap: 9px; }
.wf-bar { display: block; height: 8px; background: var(--bar); }
.wf-bar.w-100 { width: 100%; }
.wf-bar.w-90 { width: 90%; }
.wf-bar.w-75 { width: 75%; }
.wf-bar.w-60 { width: 60%; }
.wf-bar.w-40 { width: 40%; }
.wf-bar.tall { height: 12px; }
.wf-bar.head { height: 16px; background: var(--line); }

/* Small square icon slot, crossed like the image box but at icon scale. */
.wf-icon {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  background-color: var(--fill);
  border: 1px solid var(--line);
  background-image:
    linear-gradient(to top right, transparent calc(50% - .5px), var(--line) 50%, transparent calc(50% + .5px)),
    linear-gradient(to bottom right, transparent calc(50% - .5px), var(--line) 50%, transparent calc(50% + .5px));
}
.wf-icon.lg { width: 64px; height: 64px; flex-basis: 64px; }

/* Portrait circle. The one rounded shape in the kit, because an uncrossed
   circle is the universal wireframe convention for a person. */
.wf-avatar {
  width: 72px;
  height: 72px;
  flex: 0 0 72px;
  border-radius: var(--radius-pill);
  background-color: var(--fill);
  border: 1px solid var(--line);
}
.wf-avatar.sm { width: 48px; height: 48px; flex-basis: 48px; }

/* Logo plate. A bordered box with no cross, so a partner-logo row never
   reads as a row of missing photographs. */
.wf-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 8px 12px;
  background-color: var(--fill);
  border: 1px solid var(--line);
}

/* Map placeholder. Two repeating-linear-gradients for the street grid over a
   solid floor, plus a pin drawn from a rotated square and a dot. */
.wf-map {
  position: relative;
  min-height: 260px;
  background-color: var(--fill);
  border: 1px solid var(--line);
  background-image:
    repeating-linear-gradient(0deg, var(--line-soft) 0 1px, transparent 1px 46px),
    repeating-linear-gradient(90deg, var(--line-soft) 0 1px, transparent 1px 58px);
}
.wf-map::before {
  content: '';
  position: absolute;
  top: 46%;
  left: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  background: var(--accent);
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
}
.wf-map::after {
  content: '';
  position: absolute;
  top: 46%;
  left: 50%;
  width: 7px;
  height: 7px;
  margin: -4px 0 0 -4px;
  background: var(--fill);
  border-radius: 50%;
}
.wf-map .kit-note {
  position: absolute;
  bottom: 10px;
  left: 12px;
}

/* ==========================================================================
   BUTTONS. Primary is the accent ground with white type at 5.10:1. Outline
   is the boxed CTA from the reference screenshot's nav.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 26px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease;
}
.btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn-outline {
  background: transparent;
  border-color: var(--line);
  color: var(--ink);
}
.btn-outline:hover { background: var(--fill); border-color: var(--ink); color: var(--ink); }

.btn-sm { padding: 9px 16px; font-size: 12px; }
.btn-lg { padding: 17px 34px; font-size: 15px; }

/* Focus ring. Authored, not borrowed. Every interactive element gets it. */
.btn:focus-visible,
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* ==========================================================================
   SECTIONS + DARK GROUNDS

   A dark ground is not always .on-dark. .cta-band, .footer and .inner-banner
   each paint --accent-deep on themselves, so every rule below names those
   selectors explicitly rather than relying on the class. Without that, an
   outline button inheriting color: var(--ink) renders ink on near-ink.
   ========================================================================== */

.section { padding: var(--section) 0; background: var(--paper); }
.section.alt { background: var(--paper-alt); }
.section.tint { background: var(--tint); }
.section.sm { padding: var(--section-sm) 0; }
.section.lg { padding: var(--section-lg) 0; }

.section.on-dark,
.cta-band,
.footer,
.inner-banner,
.announcement-bar,
.quote-band,
.sticky-cta {
  background: var(--accent-deep);
  color: #fff;
  --bar: rgba(255, 255, 255, .30);
  --line: rgba(255, 255, 255, .42);
  --line-soft: rgba(255, 255, 255, .24);
  --fill: rgba(255, 255, 255, .10);
}

.section.on-dark h1, .section.on-dark h2, .section.on-dark h3, .section.on-dark h4,
.cta-band h1, .cta-band h2, .cta-band h3,
.quote-band h2, .quote-band h3, .sticky-cta h3,
.footer h3, .footer h4,
.inner-banner h1, .inner-banner h2 { color: #fff; }

.section.on-dark .lede, .section.on-dark .lede-lg, .section.on-dark p,
.cta-band .lede, .cta-band p,
.quote-band .lede, .quote-band p, .sticky-cta p,
.announcement-bar p,
.footer p, .footer a,
.inner-banner .lede, .inner-banner p { color: rgba(255, 255, 255, .86); }

.section.on-dark .kit-note,
.cta-band .kit-note,
.quote-band .kit-note,
.sticky-cta .kit-note,
.announcement-bar .kit-note,
.footer .kit-note,
.inner-banner .kit-note { color: rgba(255, 255, 255, .74); }

/* Outline buttons on every dark ground the kit actually has. */
.section.on-dark .btn-outline,
.cta-band .btn-outline,
.quote-band .btn-outline,
.sticky-cta .btn-outline,
.announcement-bar .btn-outline,
.footer .btn-outline,
.inner-banner .btn-outline {
  border-color: rgba(255, 255, 255, .58);
  color: #fff;
}
.section.on-dark .btn-outline:hover,
.cta-band .btn-outline:hover,
.quote-band .btn-outline:hover,
.sticky-cta .btn-outline:hover,
.announcement-bar .btn-outline:hover,
.footer .btn-outline:hover,
.inner-banner .btn-outline:hover {
  background: rgba(255, 255, 255, .12);
  border-color: #fff;
  color: #fff;
}
.section.on-dark .btn,
.cta-band .btn,
.quote-band .btn,
.sticky-cta .btn,
.announcement-bar .btn,
.inner-banner .btn {
  background: #fff;
  border-color: #fff;
  color: var(--accent-deep);
}
.section.on-dark .btn:hover,
.cta-band .btn:hover,
.quote-band .btn:hover,
.sticky-cta .btn:hover,
.announcement-bar .btn:hover,
.inner-banner .btn:hover {
  background: rgba(255, 255, 255, .84);
  border-color: rgba(255, 255, 255, .84);
  color: var(--accent-deep);
}

/* LIGHT-GROUND COMPONENTS INSIDE A DARK SECTION — register every new one here.
   `.section.on-dark p` is (0,2,1) and outranks `.card .quote` (0,2,0), so a
   dark-section colour rule reaches into any descendant that paints its own
   light ground. Fix by re-asserting ink at HIGHER specificity, never by
   weakening the section rule. This kit has three such components. */
.section.on-dark .card,
.cta-band .card,
.section.on-dark .quote-card,
.cta-band .quote-card,
.section.on-dark .price-card,
.cta-band .price-card,
.section.on-dark .stat-card,
.quote-band .stat-card,
.section.on-dark .callout,
.section.on-dark .loc-card {
  background: var(--paper);
  border-color: #9a9a9a;
  --bar: #cfcfcf;
  --line: #9a9a9a;
  --line-soft: #cfcfcf;
  --fill: #e8e8e8;
}
.section.on-dark .card h3, .section.on-dark .card h4, .section.on-dark .card p,
.section.on-dark .card .kit-note,
.cta-band .card h3, .cta-band .card p,
.section.on-dark .quote-card h3, .section.on-dark .quote-card p,
.section.on-dark .quote-card .kit-note,
.section.on-dark .price-card h3, .section.on-dark .price-card p,
.section.on-dark .price-card .kit-note,
.section.on-dark .stat-card h3, .section.on-dark .stat-card p,
.section.on-dark .stat-card .kit-note, .section.on-dark .stat-card .num,
.section.on-dark .callout h4, .section.on-dark .callout p,
.section.on-dark .callout .kit-note,
.section.on-dark .loc-card h3, .section.on-dark .loc-card p,
.section.on-dark .loc-card .kit-note { color: var(--ink); }
.section.on-dark .card p, .section.on-dark .quote-card p, .section.on-dark .price-card p { color: var(--ink-soft); }

.sec-head { max-width: 720px; margin: 0 0 48px; }
.sec-head.center { margin-left: auto; margin-right: auto; text-align: center; }

/* ==========================================================================
   GRIDS. auto-fit with a min() wrapper by default, so a large track minimum
   can never overflow a squeezed container. Grid children carry min-width: 0
   because items default to min-width: auto and inflate the track to their
   min-content, which is how a 1fr column ends up wider than the viewport.
   ========================================================================== */

.grid { display: grid; gap: 28px; }
.grid > * { min-width: 0; }
.grid.g3 { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }
.grid.g4 { grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr)); }
.grid.g6 { grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr)); }
.grid.g2 { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* Fixed tracks. Every one of these gets its collapse written in the same
   edit, never retrofitted. */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.split > * { min-width: 0; }
.split.wide-left { grid-template-columns: 1.35fr 1fr; }
.split.wide-right { grid-template-columns: 1fr 1.35fr; }
.split.narrow-left { grid-template-columns: .8fr 1fr; }

@media (max-width: 880px) {
  .split,
  .split.wide-left,
  .split.wide-right,
  .split.narrow-left { grid-template-columns: 1fr; gap: 32px; }
}

/* ==========================================================================
   NAV — house Pattern D: .nav > .container > .brand-mark + .links + .actions.
   The parent mobile-nav.js injects the burger and mobile-responsive.css turns
   .nav .links into the drawer, so this shape must not drift.
   ========================================================================== */

.nav { background: var(--paper); border-bottom: 1px solid var(--line); }
.nav > .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px var(--gutter);
}
.nav .brand-mark {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .1em;
  color: var(--ink);
  text-decoration: none;
}
.nav .brand-mark .plate {
  display: inline-flex;
  align-items: center;
  padding: 7px 13px;
  border: 1px solid var(--line);
  background: var(--fill);
}
.nav .links { display: flex; align-items: center; gap: 30px; }
.nav .links a {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-decoration: none;
}
.nav .links a:hover { color: var(--ink); }
.nav .actions { display: flex; align-items: center; gap: 12px; }

@media (max-width: 768px) {
  .nav > .container > .actions { display: none; }
}

/* ==========================================================================
   PATTERN COMPONENTS
   ========================================================================== */

/* hero-centered — the reference screenshot's hero. */
.hero { padding: var(--section-lg) 0; background: var(--paper); text-align: center; }
.hero .container { max-width: 800px; }
.hero .lede { margin: 0 auto 32px; max-width: 560px; }
.hero .actions { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }

/* hero-split — headline left, large slot right. */
.hero-split { padding: var(--section) 0; background: var(--paper); }
.hero-split .actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }

/* inner-banner — page title + breadcrumb for non-home pages. */
.inner-banner { padding: var(--section-sm) 0; }
.inner-banner .crumbs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }

/* card — the services 3-up tile and the blog post card. */
.card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  background: var(--paper);
  border: 1px solid var(--line);
}
.card.flush { padding: 0; }
.card.flush .card-body { padding: 20px; }
.card-body { display: flex; flex-direction: column; gap: 14px; }
.card h3 { margin: 0; }

/* services-list — vertical rows, icon slot beside copy. */
.row-list { display: flex; flex-direction: column; }
.row-item {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  padding: 24px 0;
  border-top: 1px solid var(--line-soft);
}
.row-item:last-child { border-bottom: 1px solid var(--line-soft); }
.row-item .row-copy { flex: 1 1 auto; min-width: 0; }

/* stats-row */
.stat { text-align: center; }
.stat .num {
  display: block;
  font-size: clamp(34px, 4.4vw, 52px);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -.03em;
  color: var(--ink);
}
.section.on-dark .stat .num, .cta-band .stat .num { color: #fff; }
.stat .kit-note { margin-top: 8px; }

/* features-alt — alternating image/copy rows. */
.alt-row { padding: 40px 0; }
.alt-row + .alt-row { border-top: 1px solid var(--line-soft); }
@media (min-width: 881px) {
  .alt-row.flip .split > *:first-child { order: 2; }
}

/* testimonial-single + testimonials-3up */
.quote-card {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 26px;
  background: var(--paper);
  border: 1px solid var(--line);
}
/* --ink-muted, not --line. The glyph is decorative and aria-hidden, but it is
   still a character, so the contrast walker measures it as text: at --line it
   reported 2.81:1 on four pages. Darkening it to 6.19:1 is cheaper than
   carrying a justified exception, and the ornament stays quiet enough. */
.quote-mark {
  font-size: 44px;
  font-weight: 800;
  line-height: .7;
  color: var(--ink-muted);
}
.quote-who { display: flex; align-items: center; gap: 14px; }
.quote-who .who-lines { flex: 1 1 auto; min-width: 0; }
.quote-big { padding: 40px; }
.quote-big .wf-bar { height: 14px; }

/* logo-row */
.logo-row { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr)); }
.logo-row > * { min-width: 0; }

/* process-steps */
.step { display: flex; flex-direction: column; gap: 14px; }
.step .step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--line);
  background: var(--fill);
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 500;
  color: var(--ink);
}

/* pricing-3up */
.price-card {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 26px;
  background: var(--paper);
  border: 1px solid var(--line);
}
.price-card.featured { border-width: 3px; border-color: var(--accent); }
.price-card .price-fig {
  font-size: clamp(30px, 3.6vw, 42px);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1;
  color: var(--ink);
}
.price-card ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.price-card li { display: flex; align-items: center; gap: 12px; }
/* Standalone rather than scoped to .price-card, so the kitchen sink can show
   the primitive on its own without it rendering unstyled. */
.tick {
  display: inline-block;
  flex: 0 0 14px;
  width: 14px;
  height: 14px;
  border: 1px solid var(--line);
  background: var(--fill);
}
.price-card .btn { margin-top: auto; }

/* team-grid. align-items: stretch, not flex-start: a flex column with
   flex-start shrinks the portrait slot to its content width and the aspect
   ratio then computes off almost nothing. */
.member { display: flex; flex-direction: column; gap: 14px; align-items: stretch; }

/* gallery-grid */
.gallery { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.gallery > * { min-width: 0; }

/* faq-accordion. <details> so it works with no JavaScript. */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 0;
  cursor: pointer;
  list-style: none;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .sign {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  position: relative;
  border: 1px solid var(--line);
  background: var(--fill);
}
.faq summary .sign::before,
.faq summary .sign::after {
  content: '';
  position: absolute;
  background: var(--ink);
}
.faq summary .sign::before { top: 50%; left: 5px; right: 5px; height: 1px; margin-top: -.5px; }
.faq summary .sign::after { left: 50%; top: 5px; bottom: 5px; width: 1px; margin-left: -.5px; }
.faq details[open] summary .sign::after { display: none; }
.faq .faq-body { padding: 0 0 22px; }

/* cta-band */
.cta-band { padding: var(--section) 0; text-align: center; }
.cta-band .container { max-width: 760px; }
.cta-band .actions { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; margin-top: 28px; }

/* forms — contact-form-inline and contact-full. Inputs never below 150px. */
.form-inline {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  align-items: center;
}
.form-grid { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }
.form-grid > * { min-width: 0; }
.form-grid .full { grid-column: 1 / -1; }

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

.field { display: flex; flex-direction: column; gap: 7px; }
.field > .kit-note { color: var(--ink-muted); }

input[type="text"], input[type="email"], input[type="tel"], textarea, select {
  width: 100%;
  min-width: 150px;
  padding: 13px 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 15px;
  color: var(--ink);
}
input::placeholder, textarea::placeholder { color: var(--ink-quiet); }
textarea { min-height: 130px; resize: vertical; }
.form-inline input[type="text"], .form-inline input[type="email"] { flex: 1 1 220px; max-width: 320px; }

/* Form fields inside a dark band keep their own light ground and ink. */
.section.on-dark input, .section.on-dark textarea, .section.on-dark select,
.cta-band input, .cta-band textarea, .cta-band select {
  background: var(--paper);
  border-color: #9a9a9a;
  color: var(--ink);
}

/* about-map + contact-full detail lists */
.detail-list { display: flex; flex-direction: column; gap: 18px; margin: 0 0 28px; }
.detail-item { display: flex; align-items: flex-start; gap: 14px; }
.detail-item .detail-copy { flex: 1 1 auto; min-width: 0; }

/* footer */
.footer { padding: var(--section-sm) 0 0; }
.footer .cols { display: grid; gap: 32px; grid-template-columns: 1.4fr 1fr 1fr 1fr; padding-bottom: 40px; }
.footer .cols > * { min-width: 0; }
.footer h4 { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 18px; }
.footer .brand-col .wf-bars { margin-top: 18px; }
.footer .f-links { display: flex; flex-direction: column; gap: 12px; }
.footer .bar {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
  padding: 20px 0;
  border-top: 1px solid rgba(255, 255, 255, .22);
}

@media (max-width: 880px) {
  .footer .cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .footer .cols { grid-template-columns: 1fr; }
}

/* ==========================================================================
   DS CHROME — ds-nav, overview, kitchen sink, catalog, gallery.
   Hierarchy here is type scale and space only. No label devices.
   ========================================================================== */

.ds-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 28px;
  background: var(--ink);
  color: #fff;
}
.ds-nav .lockup-text {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .02em;
  color: #fff;
}
.ds-nav .lockup-text small {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
}
.ds-nav .tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.ds-nav .tab {
  padding: 8px 15px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(255, 255, 255, .82);
  border: 1px solid rgba(255, 255, 255, .30);
}
.ds-nav .tab:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.ds-nav .tab.active { background: #fff; border-color: #fff; color: var(--ink); }

.ds-hero { padding: var(--section-sm) 0; background: var(--paper); border-bottom: 1px solid var(--line); }
.ds-hero .lede { max-width: 720px; }
.meta-strip {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--line-soft);
}
.meta-strip > * { min-width: 0; }
.meta-strip .meta-v { font-size: 15px; font-weight: 600; color: var(--ink); }

.door {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
  background: var(--paper);
  border: 1px solid var(--line);
  text-decoration: none;
  color: var(--ink);
}
.door:hover { border-color: var(--ink); background: var(--tint); }
.door h3 { margin: 0; }
.door p { color: var(--ink-soft); }

.file-list { display: flex; flex-direction: column; }
.file-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line-soft);
}
.file-row .fname { font-family: var(--font-mono); font-size: 13px; color: var(--ink); flex: 0 0 210px; }
.file-row .fwhat { flex: 1 1 260px; min-width: 0; color: var(--ink-soft); font-size: 15px; }

/* kitchen sink */
.swatch-grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); }
.swatch-grid > * { min-width: 0; }
.swatch { border: 1px solid var(--line); background: var(--paper); }
.swatch .chip-color { height: 92px; border-bottom: 1px solid var(--line); }
.swatch .chip-meta { padding: 12px 14px; }
.swatch .chip-meta .n { font-size: 14px; font-weight: 600; }
.swatch .chip-meta .v { font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); }

.type-row { padding: 18px 0; border-bottom: 1px solid var(--line-soft); }
.type-row .kit-note { display: block; margin-bottom: 8px; }

.sink-block { margin-bottom: 52px; }
.pad-top { margin-top: 52px; }
.pad-top-sm { margin-top: 28px; }
.sink-block > h3 { padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* catalog */
.sx-header { padding: var(--section-sm) 0; background: var(--paper); border-bottom: 1px solid var(--line); }
.sx-index { padding: 34px 0; background: var(--paper-alt); border-bottom: 1px solid var(--line); }
.sx-index .grid { gap: 10px 24px; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.sx-index a { font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); text-decoration: none; }
.sx-index a:hover { color: var(--ink); text-decoration: underline; }

.sx-pattern { padding: 40px 28px 64px; border-bottom: 1px solid var(--line); background: var(--paper-alt); }
.pattern-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 40px;
  align-items: flex-start;
  max-width: var(--max);
  margin: 0 auto 22px;
}
.pattern-meta .id {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink);
  flex: 0 0 auto;
}
.pattern-meta .id .num { color: var(--ink-quiet); }
.pattern-meta .id .signature {
  padding: 3px 8px;
  font-size: 10px;
  letter-spacing: .1em;
  background: var(--ink);
  color: #fff;
}
.pattern-meta .name { margin: 0; font-size: 16px; font-weight: 700; }
.pattern-meta .purpose { margin: 4px 0 0; font-size: 14px; color: var(--ink-muted); max-width: 620px; }

.sx-demo {
  position: relative;
  max-width: var(--max);
  margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--line);
}
.sx-demo .demo-label {
  position: absolute;
  top: -1px;
  right: -1px;
  z-index: 2;
  padding: 4px 10px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: var(--ink);
  color: #fff;
}

/* gallery of pages */
.page-card { border: 1px solid var(--line); background: var(--paper); }
.page-card .frame { height: 460px; border-bottom: 1px solid var(--line); overflow: hidden; }
.page-card .frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.page-card .pc-meta { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: baseline; padding: 16px 18px; }
.page-card .pc-meta h3 { margin: 0; font-size: 17px; }
.page-card .pc-meta a { font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); }
.page-card .pc-meta .small { flex: 1 1 100%; margin: 4px 0 0; }

/* ==========================================================================
   RESPONSIVE

   The catalog nests each demo inside .sx-pattern > .sx-demo > .container, a
   third padding layer that leaves a pattern rendering in roughly 197px of a
   305px viewport and manufactures overflow and sub-150px inputs that exist
   nowhere else. Zero the outer two under 600px and give the padding back to
   .pattern-meta alone. The `body` prefix buys the +1 specificity needed to
   beat the parent mobile-responsive.css, which is linked after this file.
   ========================================================================== */

@media (max-width: 600px) {
  body .sx-pattern { padding: 28px 0 44px; }
  body .sx-demo { border-left: 0; border-right: 0; }
  body .pattern-meta { padding: 0 16px; }
  body .sx-header .container,
  body .sx-index .container { padding: 0 16px; }
}

@media (max-width: 880px) {
  .ds-nav { padding: 14px 18px; }
  .quote-big { padding: 26px; }
  .footer .cols { padding-bottom: 30px; }
}

@media (max-width: 768px) {
  body .hero { padding: var(--section) 0; }
  body .form-inline { flex-direction: column; align-items: stretch; }
  body .form-inline input[type="text"],
  body .form-inline input[type="email"] { max-width: none; flex: 1 1 auto; }
  body .form-inline .btn { width: 100%; }
  body .page-card .frame { height: 340px; }
  body .file-row .fname { flex: 1 1 100%; }
}

/* Long unbreakable runs must never punch a heading out of its column. */
h1, h2, h3, h4, .display { overflow-wrap: break-word; }

/* ==========================================================================
   SECOND WAVE — patterns 25 to 58, added 2026-08-05.

   Same rules as everything above and no exceptions: every fixed grid track
   carries its own collapse in this block, every grid child gets min-width: 0,
   every gradient surface declares a solid background-color floor, and the
   three new dark grounds (.announcement-bar, .quote-band, .sticky-cta) are
   registered by name in the dark-ground selector lists further up rather than
   relying on .on-dark. .stat-card, .callout and .loc-card are registered in
   the light-ground re-assert block for the same reason.
   ========================================================================== */

/* 25 announcement-bar */
.announcement-bar { padding: 11px 0; }
.announcement-bar .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 16px;
}
.announcement-bar .x {
  width: 16px;
  height: 16px;
  position: relative;
  border: 1px solid rgba(255, 255, 255, .5);
  flex: 0 0 16px;
}
.announcement-bar .x::before,
.announcement-bar .x::after {
  content: '';
  position: absolute;
  inset: 3px auto auto 3px;
  width: 8px;
  height: 1px;
  background: #fff;
}
.announcement-bar .x::before { transform: rotate(45deg); transform-origin: left center; }
.announcement-bar .x::after { transform: rotate(-45deg); transform-origin: left center; top: 11px; }

/* 26 mega-menu. Shown open as a static demo: a wireframe has to show the
   panel, and a hover-only device is invisible in a screenshot review. */
.mega { border: 1px solid var(--line); border-top: 0; background: var(--paper); }
.mega .cols { display: grid; gap: 32px; grid-template-columns: repeat(4, 1fr); padding: 30px var(--gutter); }
.mega .cols > * { min-width: 0; }
.mega h4 { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 14px; }
.mega .m-links { display: flex; flex-direction: column; gap: 11px; }
.mega .promo { background: var(--fill); border: 1px solid var(--line); padding: 16px; display: flex; flex-direction: column; gap: 12px; }

@media (max-width: 880px) {
  .mega .cols { grid-template-columns: 1fr 1fr; gap: 24px; }
}
@media (max-width: 560px) {
  .mega .cols { grid-template-columns: 1fr; }
}

/* 27 breadcrumb-bar — the light standalone variant */
.crumb-bar { padding: 13px 0; background: var(--paper-alt); border-bottom: 1px solid var(--line-soft); }
.crumb-bar .container { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* 28 sidebar-nav */
.side-nav { border: 1px solid var(--line); background: var(--paper); }
.side-nav h4 { margin: 0; padding: 16px 18px; border-bottom: 1px solid var(--line); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
.side-nav a {
  display: block;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 15px;
  color: var(--ink-soft);
  text-decoration: none;
}
.side-nav a:last-child { border-bottom: 0; }
.side-nav a:hover { background: var(--fill); color: var(--ink); }
.side-nav a.current { background: var(--fill); color: var(--ink); font-weight: 700; box-shadow: inset 3px 0 0 var(--accent); }

/* 29 pagination */
.pager { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: center; }
.pager a, .pager span.page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink);
  text-decoration: none;
}
.pager a:hover { background: var(--fill); }
.pager .current { background: var(--accent); border-color: var(--accent); color: #fff; }
.pager .gap { border: 0; background: none; min-width: 22px; color: var(--ink-muted); }

/* 30 sticky-cta-bar. Rendered static in the catalog rather than position:
   fixed, because a fixed element inside a pattern demo escapes its box and
   floats over the rest of the page. The kit-note says where it really sits. */
.sticky-cta { padding: 14px 0; border-top: 1px solid rgba(255, 255, 255, .28); }
.sticky-cta .container { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; justify-content: space-between; }
.sticky-cta .sc-copy { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

/* 31 hero-search */
.search-row { display: flex; flex-wrap: wrap; gap: 10px; max-width: 620px; margin: 0 auto; }
.search-row input[type="text"] { flex: 1 1 240px; }

/* 32 hero-form — headline left, boxed form card right */
.form-card { background: var(--paper); border: 1px solid var(--line); padding: 26px; }
.form-card h3 { margin-top: 0; }

/* 33 error-404 */
.err { text-align: center; padding: var(--section-lg) 0; }
/* --ink-quiet, not --line. Same trap as .quote-mark: a huge decorative numeral
   is still text to the contrast walker, and at --line it measured 2.81:1, which
   fails even the 3:1 large-text threshold. --ink-quiet is 4.54:1 and still
   reads as quiet at 132px. */
.err .code {
  font-family: var(--font-mono);
  font-size: clamp(64px, 12vw, 132px);
  font-weight: 500;
  line-height: 1;
  color: var(--ink-quiet);
  letter-spacing: .04em;
}
.err .actions { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; margin-top: 28px; }

/* 34 icon-grid-6up */
.icon-cell { display: flex; gap: 16px; align-items: flex-start; }
.icon-cell .ic-copy { flex: 1 1 auto; min-width: 0; }
.icon-cell h4 { margin: 0 0 10px; }

/* 35 tabs-panel. First tab marked current; no JS in the kit. */
.tabs-strip { display: flex; flex-wrap: wrap; gap: 0; border-bottom: 1px solid var(--line); }
.tabs-strip a {
  padding: 14px 20px;
  border: 1px solid transparent;
  border-bottom: 0;
  margin-bottom: -1px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
  text-decoration: none;
}
.tabs-strip a:hover { color: var(--ink); }
.tabs-strip a.current {
  background: var(--paper);
  border-color: var(--line);
  color: var(--ink);
}
.tab-body { padding: 30px 0 0; }

/* 36 accordion-list — generic disclosure, distinct from .faq */
.acc { display: flex; flex-direction: column; gap: 10px; }
.acc details { border: 1px solid var(--line); background: var(--paper); }
.acc summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 18px;
  cursor: pointer;
  list-style: none;
  font-size: 16px;
  font-weight: 600;
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary .chev {
  flex: 0 0 12px;
  width: 12px;
  height: 12px;
  border-right: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  transform: rotate(45deg);
}
.acc details[open] summary .chev { transform: rotate(-135deg); }
.acc .acc-body { padding: 0 18px 18px; }

/* 37 timeline-vertical */
.tl { display: flex; flex-direction: column; }
.tl-item { display: grid; grid-template-columns: 108px 1fr; gap: 24px; padding: 0 0 32px; position: relative; }
.tl-item > * { min-width: 0; }
.tl-item::before {
  content: '';
  position: absolute;
  left: 121px;
  top: 22px;
  bottom: 0;
  width: 1px;
  background: var(--line-soft);
}
.tl-item:last-child { padding-bottom: 0; }
.tl-item:last-child::before { display: none; }
.tl-item .tl-when { text-align: right; padding-top: 3px; }
.tl-item .tl-what { position: relative; padding-left: 22px; }
.tl-item .tl-what::before {
  content: '';
  position: absolute;
  left: -9px;
  top: 5px;
  width: 13px;
  height: 13px;
  background: var(--paper);
  border: 1px solid var(--line);
}

@media (max-width: 640px) {
  .tl-item { grid-template-columns: 1fr; gap: 8px; }
  .tl-item::before { display: none; }
  .tl-item .tl-when { text-align: left; }
  .tl-item .tl-what { padding-left: 0; }
  .tl-item .tl-what::before { display: none; }
}

/* 38 comparison-table + 39 data-table. One table style, two demos.
   Wrapped in .table-wrap: a table is the one thing that genuinely cannot
   reflow, so it scrolls inside its own box instead of overflowing the page. */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); background: var(--paper); }
table.wf { width: 100%; min-width: 620px; border-collapse: collapse; font-size: 15px; }
table.wf th, table.wf td { padding: 14px 16px; text-align: left; border-bottom: 1px solid var(--line-soft); }
table.wf thead th {
  background: var(--fill);
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}
table.wf tbody tr:last-child td { border-bottom: 0; }
table.wf td.mid, table.wf th.mid { text-align: center; }
table.wf .num-cell { font-family: var(--font-mono); font-size: 13px; }
.dash { display: inline-block; width: 14px; height: 1px; background: var(--line); vertical-align: middle; }

/* 40 alert-callout */
.callout { display: flex; gap: 14px; padding: 18px; background: var(--paper); border: 1px solid var(--line); border-left-width: 4px; }
.callout .co-body { flex: 1 1 auto; min-width: 0; }
.callout h4 { margin: 0 0 8px; }
.callout.warn { border-left-color: var(--accent); }
.callout.info { border-left-color: var(--ink); }
.callout.quiet { border-left-color: var(--line); }

/* 41 video-embed */
.video {
  position: relative;
  aspect-ratio: 16 / 9;
  background-color: var(--fill);
  border: 1px solid var(--line);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 10px;
  background-image:
    linear-gradient(to top right, transparent calc(50% - .5px), var(--line) 50%, transparent calc(50% + .5px)),
    linear-gradient(to bottom right, transparent calc(50% - .5px), var(--line) 50%, transparent calc(50% + .5px));
}
.video::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  margin: -17px 0 0 -11px;
  border-left: 30px solid var(--accent);
  border-top: 17px solid transparent;
  border-bottom: 17px solid transparent;
}

/* 42 quote-band */
.quote-band { padding: var(--section) 0; text-align: center; }
.quote-band .container { max-width: 820px; }
.quote-band .qb-mark { font-size: 60px; font-weight: 800; line-height: .7; color: rgba(255, 255, 255, .5); }
.quote-band .qb-who { display: flex; align-items: center; gap: 14px; justify-content: center; margin-top: 26px; }

/* 43 stat-cards — the bordered variant of pattern 10 */
.stat-card { padding: 24px; background: var(--paper); border: 1px solid var(--line); }
.stat-card .num {
  display: block;
  font-size: clamp(30px, 3.4vw, 44px);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -.03em;
  color: var(--ink);
}
.stat-card .kit-note { margin-top: 8px; }

/* 44 before-after */
.ba-item { display: flex; flex-direction: column; gap: 12px; }
.ba-item .ba-label { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* 45 trust-badges */
.badge-row { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
.badge {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: var(--paper);
  border: 1px solid var(--line);
}

/* 46 review-summary */
.rev-score { text-align: center; }
/* margin: 0 — the default p bottom margin is 1em, which at 72px left a 72px
   hole between the score and its stars. */
.rev-score .big { margin: 0; font-size: clamp(46px, 6vw, 72px); font-weight: 800; line-height: 1; letter-spacing: -.04em; }
.stars { display: inline-flex; gap: 5px; margin: 12px 0 6px; }
.star { width: 16px; height: 16px; background: var(--accent); clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
.star.empty { background: var(--line-soft); }
.rev-dist { display: flex; flex-direction: column; gap: 10px; }
.rev-row { display: grid; grid-template-columns: 46px 1fr 44px; gap: 12px; align-items: center; }
.rev-row > * { min-width: 0; }
.rev-meter { height: 10px; background: var(--fill); border: 1px solid var(--line-soft); position: relative; }
.rev-meter i { position: absolute; inset: 0 auto 0 0; background: var(--accent); display: block; }

/* 47 product-grid */
.prod { display: flex; flex-direction: column; background: var(--paper); border: 1px solid var(--line); }
.prod .p-body { display: flex; flex-direction: column; gap: 10px; padding: 16px; }
.prod .p-price { font-family: var(--font-mono); font-size: 15px; font-weight: 500; color: var(--ink); }
.prod .btn { margin: 0 16px 16px; }

/* 48 product-detail */
.gallery-main { display: flex; flex-direction: column; gap: 12px; }
.thumb-row { display: grid; gap: 12px; grid-template-columns: repeat(4, 1fr); }
.thumb-row > * { min-width: 0; }
.buy-box { display: flex; flex-direction: column; gap: 18px; }
.buy-box .price-fig { font-size: clamp(28px, 3.4vw, 40px); font-weight: 800; letter-spacing: -.03em; line-height: 1; }
.swatch-row { display: flex; flex-wrap: wrap; gap: 10px; }
.opt {
  min-width: 52px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 13px;
  text-align: center;
}
.opt.current { border-width: 2px; border-color: var(--ink); font-weight: 500; }
.qty { display: flex; align-items: stretch; width: 138px; border: 1px solid var(--line); background: var(--paper); }
.qty button {
  width: 42px;
  border: 0;
  background: var(--fill);
  font-size: 18px;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--font-sans);
}
.qty .n { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-size: 15px; }

/* 49 filter-results */
.filter-head { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; justify-content: space-between; margin-bottom: 24px; }
.filter-group { padding: 18px; border-bottom: 1px solid var(--line-soft); }
.filter-group:last-child { border-bottom: 0; }
.filter-group h4 { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 14px; }
.check-list { display: flex; flex-direction: column; gap: 11px; }
.check-row { display: flex; align-items: center; gap: 11px; }

/* 50 cart-summary */
.cart-line { display: grid; grid-template-columns: 84px 1fr auto; gap: 18px; align-items: center; padding: 18px 0; border-bottom: 1px solid var(--line-soft); }
.cart-line > * { min-width: 0; }
.totals { background: var(--paper); border: 1px solid var(--line); padding: 22px; display: flex; flex-direction: column; gap: 14px; }
.total-row { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; }
.total-row.grand { padding-top: 14px; border-top: 1px solid var(--line); font-weight: 800; font-size: 18px; }

@media (max-width: 560px) {
  .cart-line { grid-template-columns: 64px 1fr; }
  .cart-line > *:last-child { grid-column: 1 / -1; }
}

/* 51 article-body. A real prose scaffold, because a blog wireframe that shows
   only bars tells a writer nothing about heading levels or list treatment. */
.prose { max-width: 720px; }
.prose h2 { margin-top: 1.6em; }
.prose h3 { margin-top: 1.4em; }
.prose > p, .prose > ul, .prose > ol { color: var(--ink-soft); }
.prose ul, .prose ol { padding-left: 22px; margin: 0 0 1em; display: flex; flex-direction: column; gap: 9px; }
.prose blockquote {
  margin: 1.6em 0;
  padding: 4px 0 4px 22px;
  border-left: 3px solid var(--accent);
  font-size: 19px;
  color: var(--ink);
}
.prose figure { margin: 1.8em 0; }
.prose figcaption { margin-top: 10px; }
.prose hr { border: 0; border-top: 1px solid var(--line-soft); margin: 2em 0; }

/* 52 toc-sidebar */
.toc { border: 1px solid var(--line); background: var(--paper); padding: 20px; position: sticky; top: 20px; }
.toc h4 { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 14px; }
.toc ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; counter-reset: toc; }
.toc li { display: flex; gap: 10px; font-size: 14px; }
.toc li::before { counter-increment: toc; content: counter(toc, decimal-leading-zero); font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); }
.toc a { color: var(--ink-soft); text-decoration: none; }
.toc a:hover { color: var(--ink); text-decoration: underline; }
.toc .current > a { color: var(--ink); font-weight: 700; }

/* 53 author-bio */
.author { display: flex; gap: 20px; padding: 24px; background: var(--paper-alt); border: 1px solid var(--line); }
.author .a-body { flex: 1 1 auto; min-width: 0; }
.author h4 { margin: 0 0 8px; }
.author .a-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }

@media (max-width: 560px) {
  .author { flex-direction: column; gap: 16px; }
}

/* 55 location-cards */
.loc-card { background: var(--paper); border: 1px solid var(--line); display: flex; flex-direction: column; }
.loc-card .l-body { padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.hours { display: flex; flex-direction: column; gap: 8px; }
.hours-row { display: flex; justify-content: space-between; gap: 14px; font-size: 14px; }
.hours-row .d { color: var(--ink-muted); }

/* 56 job-listings + 57 event-list. One row style, two demos. */
.list-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 14px 24px;
  align-items: center;
  padding: 22px 0;
  border-bottom: 1px solid var(--line-soft);
}
.list-row > * { min-width: 0; }
.list-row:first-child { border-top: 1px solid var(--line); }
.list-row h3 { margin: 0 0 8px; }
.list-row .meta-row { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.list-row .when {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 68px;
  padding: 10px 0;
  border: 1px solid var(--line);
  background: var(--fill);
  flex: 0 0 68px;
}
.list-row .when .d { font-family: var(--font-mono); font-size: 20px; font-weight: 500; line-height: 1; color: var(--ink); }
.event-row { display: grid; grid-template-columns: 68px 1fr auto; gap: 20px; align-items: center; }
.event-row > * { min-width: 0; }

@media (max-width: 640px) {
  .list-row { grid-template-columns: 1fr; }
  .event-row { grid-template-columns: 68px 1fr; }
  .event-row > *:last-child { grid-column: 1 / -1; }
}

/* 58 newsletter-band */
.news-band { padding: var(--section-sm) 0; background: var(--tint); border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.news-band .container { max-width: 760px; text-align: center; }
