/* website.css — North State Coatings homepage.
   Retro Americana trade identity: warm cream page, navy shell, brick-red action,
   gold highlight. All color/type/shape values trace to Brand/brand-tokens.css.
   Accent discipline: red = action (one primary CTA per view), gold = highlight.
   Anything marked PROPOSAL is a synthesis decision, not sourced from BRAND.md. */

@import url("brand/north-state/brand-tokens.css");

:root{
  /* Derived working values. The sourced tokens live in brand-tokens.css. */
  --ink:var(--navy);                     /* body text on cream */
  --muted:#5A6478;                       /* PROPOSAL: navy-tinted secondary text */
  --muted-dark:#94A0B8;                  /* PROPOSAL: secondary text on navy */
  --line:rgba(27,42,74,.14);             /* hairline on light surfaces */
  --line-dark:rgba(243,233,214,.16);     /* hairline on navy surfaces */
  --maxw:var(--maxw-site);               /* 1100px, sourced */
  /* One shape for every piece of imagery on the site: a rounded-bevel square.
     No circles, no hard 90-degree corners. BRAND.md specs 12px for content cards;
     media sits slightly softer at 16px so photos, swatches and placeholders all
     read as the same object. Small icon chips scale this down proportionally so
     they stay square-ish instead of collapsing back into circles. */
  --radius-media:16px;
  --radius-icon-lg:14px;
  --radius-icon-sm:6px;
  --shadow-card:0 10px 30px rgba(15,29,56,.10);
  --shadow-lift:0 18px 44px rgba(15,29,56,.18);
  --shadow-deep:0 26px 60px rgba(8,16,32,.45);
}
*{ margin:0; padding:0; box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{ background:var(--cream); color:var(--ink); font-family:var(--font-body); line-height:1.6; -webkit-font-smoothing:antialiased; overflow-x:hidden; }
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
.wrap{ max-width:var(--maxw); margin:0 auto; padding:0 32px; }

/* ---- brand marks -------------------------------------------------------
   Brand Standards v2 governs four marks and assigns each one a surface. On
   this site: the wordmark carries the header, the intro and the footer; the
   monogram carries the favicon; the mascot accompanies the wordmark where
   there is room for it. The crest is a close-range document mark and stays
   off the page chrome, because it may not share a panel with the wordmark
   and the header is fixed, so the wordmark is on screen at all times.
   Files: brand/north-state/v2/. Map: docs/brand-assets.md.

   Marks are sized by width, never by height: the wordmark has screen minimums
   (180px full colour, 120px one colour) and they are width figures. ---- */
.wordmark{ display:block; height:auto; }
/* .nm is no longer a brand lockup. It survives as a plain heading style, used
   by the quote modal header. */
.nm{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase;
  letter-spacing:var(--head-tracking); line-height:var(--head-line-height); color:var(--cream); }
.nm small{ display:block; font-family:var(--font-body); font-style:normal; font-weight:600;
  letter-spacing:.26em; color:var(--gold); }

/* ---- shared bits ---- */
.eyebrow{ font-family:var(--font-body); font-weight:600; text-transform:uppercase; letter-spacing:.24em; font-size:.72rem; color:var(--gold); }
.h-sec{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase;
  font-size:clamp(2.4rem,5vw,4rem); letter-spacing:var(--head-tracking); line-height:var(--head-line-height); color:var(--navy); }
.h-sec .gold{ color:var(--brick-red); }   /* on cream, the accent is red; gold fails contrast here */
.lead{ color:var(--muted); font-size:1.05rem; max-width:60ch; }

/* =====================================================================
   VINTAGE AMERICANA DEVICE KIT
   Per brand/north-state/North-State-Vintage-Direction.md. 1950s Americana:
   confident and spacious, not cluttered. Cream / navy / red / gold only.
   Every device below is CSS or inline SVG so it scales and recolors.
   ===================================================================== */

/* --- 1. Extruded block headlines -------------------------------------
   Solid slab, not a stack of bands. Stops step by 1px with no gaps, so the
   stack fuses into one shape; a 2px step leaves visible banding between
   layers. One color, no blur, total offset 4px.
   Bold on dark, calm on light: the full extrude runs only on the navy
   surfaces (hero, CTA band, anything given .floor). On cream the heading
   stays a clean navy with a single soft offset. */
.extrude, .hero h1, .cta-band h2, .floor .h-sec{
  --x:var(--brick-red);
  text-shadow:1px 1px 0 var(--x), 2px 2px 0 var(--x), 3px 3px 0 var(--x), 4px 4px 0 var(--x); }

/* on cream: one quiet single-tone offset, no extrude */
.h-sec{ text-shadow:2px 2px 0 rgba(27,42,74,.13); }
.h-sec .gold{ text-shadow:2px 2px 0 rgba(27,42,74,.13); }

@media(max-width:680px){
  .extrude, .hero h1, .cta-band h2, .floor .h-sec{
    text-shadow:1px 1px 0 var(--x), 2px 2px 0 var(--x), 3px 3px 0 var(--x); }
}
@media(prefers-contrast:more){
  .h-sec, .h-sec .gold, .hero h1, .cta-band h2, .floor .h-sec, .extrude{ text-shadow:none; }
}

/* --- 4. Engraved line-art icons --------------------------------------
   One weight, one grid, one style across the whole set. Stroked with
   currentColor so an icon takes the color of the block it sits in. */
.vic{ width:30px; height:30px; display:block; fill:none; stroke:currentColor;
  stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.vic-sm{ width:22px; height:22px; }
.vic-lg{ width:42px; height:42px; stroke-width:1.5; }

/* --- 3. Retro seals and emblems --------------------------------------
   Supplied brand art from north-state-brand/Emblems, trimmed to its alpha
   bounding box and re-encoded as transparent webp. Each carries its own
   cream field, so it sits on cream or on navy without a plate behind it.
   Used as accents: sized small, given room, never repeated in a section. */
.emblem-art{ display:block; height:auto; }

/* hero emblem sizing lives with the hero block below */

/* guarantee seal, in the notched promise card */
.ticket .emblem-seal{ width:124px; }
@media(max-width:680px){ .ticket .emblem-seal{ width:104px; } }

/* Mascot, in the footer brand column. Kept under the wordmark's visual weight
   so the primary mark still leads. Gap is 12% of the mascot's width, its clear
   space rule, rounded up. The EST. 2026 stamp was removed from this row on
   2026-09-04; .emblem-est went with it. */
.footer-stamps{ display:flex; align-items:center; gap:14px; margin-top:20px; }
.footer-mascot{ display:block; width:76px; height:auto; }

/* Worker illustration removed 2026-07-28 (Nick). Asset retained in
   brand/north-state/emblems/ for other surfaces. */

/* --- 2. Marker highlight swash ---------------------------------------
   A solid, slightly rotated block behind ONE keyword. Used once per page.
   Cream on brick red measures 4.92:1, so it clears AA at any size. */
.swash{ position:relative; display:inline-block; padding:.02em .17em .07em; }
.swash::before{ content:""; position:absolute; inset:0; background:var(--brick-red);
  border-radius:5px; transform:rotate(-1.8deg); }
.swash > span{ position:relative; color:var(--cream); text-shadow:none; }

/* --- 5. Notched ticket-corner card ------------------------------------
   clip-path cuts the corners; the double rule is drawn by nesting
   red / cream / red / cream layers, since a clipped box drops its border. */
.ticket{ --notch:18px; margin-top:54px; background:var(--brick-red); padding:3px;
  clip-path:polygon(var(--notch) 0,calc(100% - var(--notch)) 0,100% var(--notch),
    100% calc(100% - var(--notch)),calc(100% - var(--notch)) 100%,var(--notch) 100%,
    0 calc(100% - var(--notch)),0 var(--notch)); }
.ticket-gap{ --notch:16px; background:var(--cream); padding:5px; clip-path:inherit; }
.ticket-rule{ --notch:12px; background:var(--brick-red); padding:1px; clip-path:inherit; }
.ticket-body{ --notch:11px; background:var(--white); clip-path:inherit;
  display:grid; grid-template-columns:auto 1fr; gap:30px; align-items:center; padding:30px 34px; }
.ticket-copy .ey{ color:var(--brick-red); margin-bottom:11px; }
.ticket-copy h3{ font-family:var(--font-head); font-weight:900; font-style:italic;
  text-transform:uppercase; letter-spacing:var(--head-tracking); line-height:var(--head-line-height);
  font-size:clamp(1.4rem,2.6vw,1.95rem); color:var(--navy); }
.ticket-copy p{ margin-top:12px; color:var(--muted); font-size:.97rem; max-width:56ch; }
/* Pointer to the contract, set quieter than the warranty scope above it. Kept
   on --muted (not a lighter grey) so it still clears AA on the white field. */
.ticket-copy p.warranty-note{ margin-top:14px; font-size:.86rem; font-weight:600;
  letter-spacing:.01em; color:var(--muted); }
@media(max-width:680px){
  .ticket-body{ grid-template-columns:1fr; justify-items:start; gap:20px; padding:26px 24px; }
}



/* --- 8. Signature accent ----------------------------------------------
   One short signature line, never headlines, body, or buttons.

   Was Pacifico. Brand Standards v2 section 09 retires Pacifico as a live
   typeface: the crest's script is a heavier, more slanted brush hand and the
   two were never seen side by side, so the brand was running two scripts under
   one name. The script now exists inside the crest artwork and nowhere else.
   This line moves to Barlow Condensed 700 italic, held below the 900 weight of
   the heading rule so it still reads as an aside rather than a heading. */
.script-accent{ font-family:var(--font-head); font-weight:700; font-style:italic;
  font-size:clamp(1.25rem,2.6vw,1.7rem); letter-spacing:.005em;
  color:var(--brick-red); line-height:1.35; margin-top:14px; }
.floor .script-accent{ color:var(--gold); }

/* --- 6 + 7. Tone-on-tone motif and sunburst rays ----------------------
   Both are background layers a shade off the surface they sit on, so they
   read as texture rather than content. Kept to two placements on the page. */
.motif{ position:relative; isolation:isolate; }
.motif::before{ content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  opacity:.5;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='150' height='150' viewBox='0 0 150 150'><g fill='none' stroke='%231B2A4A' stroke-opacity='.075' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M34 20 22 40h8l-2 14 12-20h-8z'/><path d='M112 92 100 112h8l-2 14 12-20h-8z'/><rect x='92' y='24' width='22' height='9' rx='4'/><path d='M114 28h5a3 3 0 0 1 3 3v4a3 3 0 0 1-3 3h-15a3 3 0 0 0-3 3v3'/><path d='M28 104h18M31 112h12'/></g></svg>"); }

/* Sanction check against guidelines section 09, run 2026-07-28 before rolling
   this out site-wide. The tile draws the twin lightning bolts and the roller,
   both of which are parts of the badge (gloved fist holding a roller and a
   notched squeegee, bolts either side). Nothing here is an invented icon, so
   the rollout does not multiply a violation. Do not add shapes that are not
   badge parts.

   Navy surfaces deliberately do NOT get this tile. They already carry their
   own texture, the .floor flake-dot field, which is the navy-surface
   equivalent. Stacking the motif on top would be two patterns fighting. That
   is the "different treatment per surface" requirement, resolved by using the
   texture each surface already has rather than recoloring one tile for both.

   Texture, not content: the tile lives on a ::before pseudo-element, so it is
   absent from the accessibility tree and cannot be focused. Effective ink is
   opacity .5 x stroke-opacity .075, about 3.75%, which leaves every
   text/background pair unchanged. If a pair ever fails, lower this opacity
   rather than darkening the text. */
@media (prefers-reduced-data: reduce){
  .motif::before{ display:none; }
}

/* rays behind the price card, one shade lighter than the section ground */
.price-wrap{ position:relative; isolation:isolate; }
.price-wrap::before{ content:""; position:absolute; z-index:-1; pointer-events:none;
  width:640px; height:640px; left:-90px; top:50%; transform:translateY(-50%);
  background:repeating-conic-gradient(from 0deg at 50% 50%,
    rgba(27,42,74,.055) 0deg 6deg, transparent 6deg 15deg);
  -webkit-mask-image:radial-gradient(closest-side, #000 38%, transparent 78%);
  mask-image:radial-gradient(closest-side, #000 38%, transparent 78%); }
@media(max-width:980px){ .price-wrap::before{ width:440px; height:440px; left:-70px; } }


/* buttons: sourced spec is brick-red bg, cream text, Inter 16 semibold, radius 8, 44px */
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:10px;
  font-family:var(--font-body); font-weight:600; font-size:1rem; letter-spacing:.01em;
  height:var(--input-height); padding:0 24px; border-radius:var(--radius-button);
  border:1px solid transparent; cursor:pointer; transition:transform .15s, background .15s, color .15s, border-color .15s; }
.btn-red{ background:var(--brick-red); color:var(--cream); }
.btn-red:hover{ transform:translateY(-2px); background:#9E3028; }
.btn-ghost{ background:transparent; color:var(--navy); border-color:rgba(27,42,74,.32); }
.btn-ghost:hover{ border-color:var(--navy); background:rgba(27,42,74,.06); }
.btn-dark{ background:var(--navy); color:var(--cream); }
.btn-dark:hover{ transform:translateY(-2px); background:var(--deep-navy); }
/* ghost sitting on a navy surface (hero, CTA band, quote page, thank-you) */
.floor .btn-ghost{ color:var(--cream); border-color:rgba(243,233,214,.34); }
.floor .btn-ghost:hover{ border-color:var(--cream); background:rgba(243,233,214,.08); }

/* flake floor texture, rebuilt on deep navy with cream/gold flake */
.floor{ position:relative; background-color:var(--deep-navy); background-image:
    radial-gradient(circle, rgba(224,165,38,.42) 0.9px, transparent 1.4px),
    radial-gradient(circle, rgba(243,233,214,.40) 0.9px, transparent 1.4px),
    radial-gradient(circle, rgba(148,160,184,.34) 1.1px, transparent 1.6px),
    radial-gradient(circle, rgba(180,56,46,.30) 0.7px, transparent 1.2px);
  background-size:15px 15px, 23px 23px, 31px 31px, 19px 19px;
  background-position:0 0, 8px 12px, 17px 5px, 3px 9px; color:var(--cream); }
.floor-gloss::before{ content:""; position:absolute; inset:0; background:linear-gradient(125deg, rgba(255,255,255,.09) 0%, transparent 26%, transparent 70%, rgba(255,255,255,.04) 100%); pointer-events:none; }
.floor-vignette::after{ content:""; position:absolute; inset:0; background:radial-gradient(120% 80% at 50% -10%, rgba(27,42,74,.42), rgba(15,29,56,.90) 78%); pointer-events:none; }
.floor > *{ position:relative; z-index:1; }
.floor .h-sec, .floor .nm{ color:var(--cream); }
.floor .lead{ color:var(--muted-dark); }

/* image placeholder */
.ph{ position:relative; overflow:hidden; border-radius:var(--radius-media); background-image:repeating-linear-gradient(135deg,#E7DAC2 0 12px,#DFD0B4 12px 24px); border:1px solid var(--line); display:flex; align-items:flex-end; }
.ph .tagm{ font-family:var(--font-body); font-size:.66rem; color:var(--muted); background:rgba(243,233,214,.8); padding:5px 9px; border-radius:5px; margin:12px; }

/* reveal — content is VISIBLE by default; .anim plays a one-shot fade-up when
   the observer fires. If JS/IO never runs, content simply shows. */
.reveal.anim{ animation:riseIn .75s cubic-bezier(.2,.7,.2,1) both; }
@keyframes riseIn{ from{ opacity:0; transform:translateY(26px); } to{ opacity:1; transform:none; } }
@media(prefers-reduced-motion:reduce){ .reveal.anim{ animation:none; } }

/* ---- NAV ---- */
/* At rest the bar carries a deep-navy scrim rather than sitting clear over the
   hero photo. Standards section 04: the wordmark is never set on a photograph
   or a texture. The scrim is one of the six brand values fading to nothing, so
   the hero stays full bleed and the mark keeps a brand-colour field. */
.nav{ position:fixed; top:0; left:0; right:0; z-index:60; transition:background .3s, border-color .3s, padding .3s; border-bottom:1px solid transparent;
  background:linear-gradient(180deg, rgba(15,29,56,.92) 0%, rgba(15,29,56,.72) 62%, rgba(15,29,56,0) 100%); }
.nav.scrolled{ background:rgba(15,29,56,.94); backdrop-filter:blur(12px); border-bottom-color:var(--line-dark); }
/* Bar sizing is driven by the badge, not by padding: min-height is set to the
   badge height plus its breathing room so the mark can never be clipped.
   gap:20px and the nowrap/min-width rules below keep the phone number and the
   CTA on one line at the tightest desktop widths. */
.nav .bar{ max-width:var(--maxw); margin:0 auto; padding:10px 32px; min-height:78px; display:flex; align-items:center; gap:20px; transition:padding .3s, min-height .3s; }
.nav.scrolled .bar{ padding:8px 32px; min-height:64px; }
.nav .brand{ display:flex; align-items:center; flex-shrink:0; }

/* ---- Header wordmark ----------------------------------------------------
   Brand Standards v2 section 03 puts the wordmark on the website header, and
   section 04 bars retyping it. This replaces the type-set lockup that stood
   here from 2026-07-28 to 2026-09-03. That lockup was an authorized override
   of the misuse rules, and the reason recorded for it was that v1 shipped no
   wordmark-only cream file to knock out of a navy bar. v2 ships exactly that
   file, so the reason is gone and the override is retired. The measured
   tracking values it carried are gone with it: the artwork sets its own.

   Sized by width. 160px at 375 and 190px from 1200 up, which clears the 120px
   one-colour screen minimum with room to spare. At 3.35:1 that is 57px tall,
   inside the 78px bar; the scrolled range is held under the 64px bar the same
   way. Cream knockout, no shadow: the standards call the red offset shadow mud
   at 2.4:1 against navy. */
.nav .brand.lockup{ align-items:center; text-decoration:none; }
.nav .brand .wordmark{
  width:clamp(160px, calc(146.364px + 3.6364vw), 190px);
  transition:width .3s;
}
.nav.scrolled .brand .wordmark{ width:clamp(140px, calc(131.818px + 2.1818vw), 158px); }
.nav .links{ display:flex; align-items:center; gap:24px; margin-left:auto; min-width:0; }
.nav .phone, .nav .btn.navcta{ white-space:nowrap; flex-shrink:0; }
.nav .links a{ font-family:var(--font-body); font-weight:600; font-size:.84rem; color:var(--cream); opacity:.86; transition:opacity .15s,color .15s; white-space:nowrap; }
.nav .links a:hover{ opacity:1; color:var(--gold); }
.nav .phone{ font-family:var(--font-body); font-weight:700; font-size:.9rem; color:var(--gold); }
.nav .navcta{ height:38px; padding:0 18px; font-size:.88rem; }
.nav .burger{ display:none; flex-direction:column; gap:5px; background:none; border:none; cursor:pointer; padding:6px; margin-left:auto; }
.nav .burger span{ width:24px; height:2px; background:var(--cream); transition:.25s; }
.nav.open .burger span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.nav.open .burger span:nth-child(2){ opacity:0; }
.nav.open .burger span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

.mobile-menu{ position:fixed; inset:0 0 0 auto; width:min(82vw,360px); background:var(--navy); z-index:55; transform:translateX(100%); transition:transform .32s cubic-bezier(.2,.7,.2,1); padding:96px 30px 30px; display:flex; flex-direction:column; gap:6px; border-left:1px solid var(--line-dark); }
.mobile-menu.open{ transform:none; }
.mobile-menu a{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:1.3rem; color:var(--cream); padding:13px 0; border-bottom:1px solid var(--line-dark); }
.mobile-menu a:hover{ color:var(--gold); }
.mobile-menu .phone{ color:var(--gold); font-family:var(--font-body); font-weight:700; font-style:normal; text-transform:none; letter-spacing:0; font-size:1.05rem; }
.mobile-menu .mcta{ margin-top:20px; }
.scrim{ position:fixed; inset:0; background:rgba(8,16,32,.62); z-index:54; opacity:0; pointer-events:none; transition:opacity .3s; }
.scrim.open{ opacity:1; pointer-events:auto; }

/* ---- HERO (full-bleed) ----
   The floor photo is the hero background. It stays an <img> inside
   .hero-media so it keeps fetchpriority and remains the LCP element; a CSS
   background-image would not be preloaded the same way.
   Stacking is explicit: media 0, scrim 1, content 2. The .floor flake-dot
   pattern still paints underneath as the fallback ground while the photo
   decodes, and shows through nothing once it lands. */
.hero{ position:relative; isolation:isolate; min-height:92vh; display:flex;
  flex-direction:column; justify-content:center; padding:150px 0 74px; }
.hero-media{ position:absolute; inset:0; z-index:0; overflow:hidden; }
.hero-media img{ width:100%; height:100%; object-fit:cover; object-position:50% 32%; display:block; }
/* Scrim. Two layers: a horizontal wash that keeps the text column dark, and a
   vertical wash for the nav overlap and the lower edge. Values were set by
   sampling the rendered background under the headline and sub. */
.hero-media::after{ content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(15,29,56,.88) 0%, rgba(15,29,56,.42) 28%, rgba(15,29,56,.32) 66%, rgba(15,29,56,.70) 100%),
    linear-gradient(90deg, rgba(15,29,56,.95) 0%, rgba(15,29,56,.92) 44%, rgba(15,29,56,.60) 70%, rgba(15,29,56,.20) 88%, rgba(15,29,56,.08) 100%); }
.hero .wrap{ position:relative; z-index:2; }
.hero-inner{ max-width:730px; }

/* .hero .ey removed 2026-09-16 with the hero eyebrow itself. The H1 kicker
   below now carries the geography, and two stacked lines both naming Raleigh
   and the Triangle read as one block. .eyebrow and .ey are untouched and are
   still used by every other section. */
.hero h1{ font-family:var(--font-display); font-size:clamp(3rem,6.4vw,5.4rem); line-height:.92; letter-spacing:.005em; color:var(--cream); text-transform:uppercase; }
.hero h1 .gold{ color:var(--gold); }
/* SEO kicker, added 2026-09-16. The <h1> is the strongest on-page signal we
   have and the brand headline contains no search term, so the term rides
   inside the same <h1> as a small line above it. The headline text itself is
   unchanged.

   Barlow Condensed at 700 upright, not Anton: it has to read as subordinate to
   the display headline rather than compete with it for the same line. Cream and
   not gold because .hero .ey directly above it is already gold, and two gold
   lines stacked on a photograph read as one smeared block.

   No text-shadow. Standing owner decision, 2026-09-10: no text-shadow on any
   digital surface. Legibility over the photo comes from the hero scrim, which
   already carries the headline and the subhead. */
.hero h1 .h1-kicker{
  display:block;
  font-family:var(--font-head);
  font-weight:700;
  font-style:normal;
  font-size:clamp(.92rem,1.6vw,1.16rem);
  line-height:1.2;
  letter-spacing:.07em;
  text-transform:uppercase;
  color:var(--cream);
  opacity:.86;
  margin-bottom:14px;
  /* text-shadow inherits. .hero h1 carries the four-step brick-red extrude, and
     without this the kicker picks it up at a size where a 4px offset is wider
     than the stroke. Cleared explicitly rather than relying on the extrude
     being removed later. */
  text-shadow:none;
}
@media(max-width:560px){
  .hero h1 .h1-kicker{ letter-spacing:.05em; margin-bottom:10px; }
}
/* lifted off --muted-dark: that tone was tuned for a flat navy panel and is
   too weak over a photograph, even a scrimmed one */
.hero .sub{ font-family:var(--font-body); font-size:1.16rem; color:#E2E8F2; margin-top:22px; max-width:52ch; }
.hero .sub b{ color:var(--cream); font-weight:600; }
.hero .actions{ display:flex; gap:14px; margin-top:34px; flex-wrap:wrap; }
.hero .trust-row{ display:flex; align-items:center; gap:30px; margin-top:44px; flex-wrap:wrap; }
.hero .trust{ display:flex; gap:32px; flex-wrap:wrap; }
.hero .trust .t .n{ font-family:var(--font-display); font-size:2.1rem; color:var(--cream); line-height:1; }
.hero .trust .t .n .gold{ color:var(--gold); }
.hero .trust .t .l{ font-size:.76rem; color:#C2CADA; text-transform:uppercase; letter-spacing:.1em; margin-top:5px; font-weight:600; }
/* The warranty stat label carries the full locked name, "North State 20-Year
   Workmanship Warranty". The name is never shortened to fit a tile: Hard Rules
   say in full or not at all.

   At 40 characters it needs 333px on one line, against 193px of tile. Without a
   cap the tile grows, the flex row overflows and the warranty stat drops onto a
   second row on its own, which breaks the three-across stat line. This cap
   keeps it in the row and wraps the label instead.

   It wraps to three lines, not two, and that is not fixable by tuning this
   number. Measured at 1440px: the row is 688px, the other two tiles take 242
   and 189 with two 32px gaps, leaving exactly 193. "WORKMANSHIP WARRANTY"
   alone needs 219. Three tiles and a 40-character label do not fit on one row
   at this type size, so the label breaks as NORTH STATE 20-YEAR / WORKMANSHIP /
   WARRANTY. The .nb span below is what stops a fourth break landing on the
   hyphen.

   Scoped to .hero deliberately. On /quote/ the warranty tile already sat on its
   own row before this change, so it has the full column to itself and the cap
   would only make the label wrap more than it needs to. The .nb rule stays
   unscoped because keeping "20-Year" whole is right on every surface. */
.hero .trust .t-warranty .l{ max-width:24ch; }
/* Keeps "20-Year" whole. The label wraps to two lines at this measure, and
   without this the line break lands on the hyphen and reads "NORTH STATE 20-"
   over "YEAR WORKMANSHIP". The hyphen stays an ASCII U+002D; the rule bars en
   and em dashes, not the hyphen, and a non-breaking hyphen would be a
   different character in a locked string. */
/* Utility. Wraps a fragment that must not break across lines. Used on
   "20-Year" inside the warranty name wherever that name appears in running
   text or a label: left alone the break lands on the hyphen and reads
   "North State 20-" over "Year Workmanship Warranty". Promoted from the stat
   tile to a general rule on 2026-09-16 when the name reached the process
   cards too. The hyphen stays an ASCII U+002D. */
.nb{ white-space:nowrap; }
/* .emblem-price (the $8 sunburst) removed 2026-07-28. See index.html hero. */

@media(max-width:980px){
  .hero{ min-height:88vh; padding:132px 0 64px; }
  .hero-media img{ object-position:50% 38%; }
  .hero-media::after{ background:
    linear-gradient(180deg, rgba(15,29,56,.88) 0%, rgba(15,29,56,.46) 30%, rgba(15,29,56,.40) 60%, rgba(15,29,56,.80) 100%),
    linear-gradient(90deg, rgba(15,29,56,.92) 0%, rgba(15,29,56,.78) 55%, rgba(15,29,56,.58) 100%); }
}
@media(max-width:680px){
  /* Three stats across at 375 crushes: flex-wrap left them ragged over two
     rows (242px + 197px + 81px). A 2-up grid with the price spanning the full
     width puts the figure that matters on its own line and pairs the two
     supporting stats underneath on an even column.
     Alternate single-column layout is available via .opt-stack below. */
  .hero .trust-row{ gap:22px; margin-top:32px; }
  /* Flex with natural widths, not an even 2-up grid. A 50/50 grid forces
     "MOISTURE-TESTED INSTALL" to wrap to two lines; letting the columns size
     to their content keeps every label on one line. The price takes the full
     first row on its own. */
  .hero .trust{ display:flex; flex-wrap:wrap; gap:20px 34px; width:100%; }
  .hero .trust .t:first-child{ flex:0 0 100%; }
  .hero .trust .t .n{ font-size:2.35rem; }
}
/* Option A: every stat on its own line. Taller, but each figure gets full
   width. Applied by adding .opt-stack to .trust-row. */
@media(max-width:680px){
  .hero .trust-row.opt-stack .trust{ flex-direction:column; gap:16px; }
  .hero .trust-row.opt-stack .trust .t{ flex:0 0 auto; }
}

/* ---- SECTION SCAFFOLD ---- */
.section{ padding:88px 0; border-top:1px solid var(--line); position:relative; }
.sec-head{ max-width:var(--maxw); margin:0 auto 44px; padding:0 32px; }
.sec-head .ey{ margin-bottom:13px; color:var(--brick-red); }
.sec-head p{ margin-top:16px; }
.floor .sec-head .ey{ color:var(--gold); }

/* process */
.steps{ display:grid; grid-template-columns:repeat(4,1fr); gap:18px; list-style:none; }
.step{ background:var(--white); border:1px solid var(--line); border-radius:var(--radius-card); padding:var(--pad-card); transition:transform .2s, border-color .2s, opacity .35s, box-shadow .35s; }
.step:hover{ transform:translateY(-4px); border-color:rgba(180,56,46,.4); box-shadow:var(--shadow-card); }
.step .n{ font-family:var(--font-display); font-size:1.4rem; color:var(--brick-red); }
/* Engraved icon sits above the gold rule. The rule keeps the width animation
   the pinned/active step used to run on .ic itself. */
.step .ic{ margin:12px 0 16px; color:var(--navy); }
.step .ic::after{ content:""; display:block; height:3px; width:34px; background:var(--gold); margin-top:11px; transition:width .35s; }
.step h3{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:1.2rem; color:var(--navy); }
.step p{ font-size:.9rem; color:var(--muted); margin-top:8px; }

/* process build-up: static fallback by default (no JS / reduced motion) */
.process-stage{ position:relative; border:1px solid var(--line); border-radius:var(--radius-media); overflow:hidden; background:var(--white); margin-bottom:30px; }
.process-stage img, .process-stage video{ display:block; width:100%; height:100%; object-fit:contain; background:var(--white); }
.process-video{ display:none; }            /* no JS: never show a non-scrubbing video */
.process-stage figcaption{ position:absolute; left:0; right:0; bottom:0; padding:15px 18px; font-family:var(--font-body); font-weight:600; font-size:.84rem; color:var(--cream); background:linear-gradient(transparent, rgba(15,29,56,.92)); }

/* enhanced: JS present and motion allowed -> pin + scrub */
html.js .process-scroll{ height:300vh; position:relative; }
html.js .process-pin{ position:sticky; top:0; min-height:100vh; display:grid; grid-template-columns:minmax(0,1.15fr) minmax(260px,.85fr); gap:42px; align-items:center; }
html.js .process-stage{ margin:0; aspect-ratio:1/1; max-height:82vh; width:100%; }
html.js .process-video{ display:block; }
html.js .process-fallback{ display:none; }
html.js .process-pin .steps{ display:flex; flex-direction:column; gap:14px; }
html.js .process-pin .step{ opacity:.45; }
html.js .process-pin .step.lit{ opacity:1; }
html.js .process-pin .step.active{ opacity:1; border-color:rgba(180,56,46,.55); transform:translateX(5px); box-shadow:var(--shadow-lift); }
html.js .process-pin .step.active .ic::after{ width:52px; }
html.js .process-pin .step.active .ic{ color:var(--brick-red); }

@media(max-width:880px){
  html.js .process-pin{ grid-template-columns:1fr; gap:22px; align-content:center; }
  html.js .process-stage{ max-height:56vh; }
  html.js .process-pin .steps{ flex-direction:row; flex-wrap:wrap; }
  html.js .process-pin .step{ flex:1 1 44%; padding:16px; }
}
@media(prefers-reduced-motion:reduce){
  html.js .process-scroll{ height:auto; }
  html.js .process-pin{ position:static; min-height:0; display:block; }
  html.js .process-video{ display:none; }
  html.js .process-fallback{ display:block; }
  html.js .process-stage{ aspect-ratio:auto; max-height:none; margin-bottom:30px; }
  html.js .process-pin .steps{ display:grid; grid-template-columns:repeat(4,1fr); }
  html.js .process-pin .step{ opacity:1; }
}
@media(prefers-reduced-motion:reduce) and (max-width:760px){
  html.js .process-pin .steps{ grid-template-columns:1fr 1fr; }
}

/* pricing */
.price-wrap{ display:grid; grid-template-columns:.9fr 1.1fr; gap:46px; align-items:center; }
.price-card{ background:var(--navy); border:1px solid var(--navy); border-radius:var(--radius-card); padding:40px 34px; text-align:center; box-shadow:var(--shadow-lift); }
.price-card .big{ font-family:var(--font-display); font-size:5.6rem; line-height:.84; color:var(--cream); }
.price-card .big .u{ font-size:1.5rem; color:var(--gold); letter-spacing:.02em; }
.price-card .per{ font-family:var(--font-body); font-weight:600; text-transform:uppercase; letter-spacing:.16em; font-size:.74rem; color:var(--muted-dark); margin-top:10px; }
.price-card .tag2{ margin-top:18px; font-family:var(--font-body); font-weight:600; color:var(--gold); font-size:.95rem; }
.incl{ list-style:none; }
.incl li{ display:flex; align-items:flex-start; gap:13px; padding:13px 0; border-bottom:1px solid var(--line); font-size:.98rem; color:var(--muted); }
.incl li .ck{ flex:0 0 auto; width:21px; height:21px; border-radius:var(--radius-icon-sm); background:rgba(180,56,46,.12); color:var(--brick-red); display:flex; align-items:center; justify-content:center; font-size:.7rem; font-weight:700; margin-top:2px; }
.incl li b{ color:var(--navy); font-weight:600; }

/* what we coat */
.coat-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:16px; }
.coat{ border-radius:var(--radius-media); overflow:hidden; position:relative; aspect-ratio:3/4; border:1px solid var(--line); transition:border-color .3s, transform .3s, box-shadow .3s; }
.coat .ph{ position:absolute; inset:0; }
.coat .cap{ position:absolute; left:0; right:0; bottom:0; z-index:2; padding:18px 20px 20px; background:linear-gradient(transparent, rgba(15,29,56,.55) 38%, rgba(15,29,56,.94)); }
.coat .cap h3{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:1.25rem; line-height:1; color:var(--cream); }
.coat .cap span{ display:block; margin-top:7px; font-size:.8rem; line-height:1.45; color:var(--muted-dark); }
.coat:hover{ border-color:rgba(180,56,46,.45); box-shadow:var(--shadow-lift); }
.coat img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform .6s cubic-bezier(.2,.7,.2,1); }
.coat:hover img{ transform:scale(1.05); }

/* gallery */
.gallery{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; }
.gallery .g{ position:relative; overflow:hidden; border-radius:var(--radius-media); aspect-ratio:4/3; border:1px solid var(--line); }
.gallery .g img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform .6s cubic-bezier(.2,.7,.2,1); }
.gallery .g:hover img{ transform:scale(1.06); }

/* flake colors */
.flake-banner{ position:relative; border-radius:var(--radius-media); overflow:hidden; border:1px solid var(--line); margin-bottom:30px; aspect-ratio:24/7; box-shadow:var(--shadow-card); }
.flake-banner img{ width:100%; height:100%; object-fit:cover; display:block; }
.flake-banner::after{ content:""; position:absolute; inset:0; background:linear-gradient(180deg, rgba(15,29,56,.14), transparent 40%, rgba(15,29,56,.24)); pointer-events:none; }
/* Four across at desktop, three at tablet, two on phones (media queries below).
   Rebuilt 2026-09-21 to the larger, sample-board sized tile: at the 1036px
   content width each swatch is about 245px, double the old six-across tile.
   .sw is a <button> so the tile is keyboard-reachable; clicking opens the
   lightbox in website.js. */
.flakes{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:18px; }
.flake{ text-align:center; }
.flake .sw{ display:block; width:100%; padding:0; background:var(--white); aspect-ratio:1; border-radius:var(--radius-media); border:2px solid var(--line); transition:transform .2s, border-color .2s, box-shadow .2s; overflow:hidden; cursor:zoom-in; }
.flake .sw:hover, .flake .sw:focus-visible{ transform:scale(1.03); border-color:var(--gold); box-shadow:var(--shadow-card); outline:none; }
.flake .sw img{ width:100%; height:100%; object-fit:cover; display:block; }
.flake .nm2{ font-family:var(--font-body); font-weight:600; font-size:.88rem; margin-top:12px; color:var(--navy); }
/* group headings for the standard, stone and quartz tiers. Renamed from
   "premium" 2026-09-16: the Hard Rules bar that word, and these are tier names
   with a price attached rather than a claim about quality. Quartz adds $4 per
   square foot, set by Taylor 2026-09-21. */
.flake-group{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase;
  letter-spacing:var(--head-tracking); line-height:var(--head-line-height); font-size:1.5rem; color:var(--navy);
  margin:34px 0 20px; display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
.flake-group:first-of-type{ margin-top:6px; }
.flake-group span{ font-family:var(--font-body); font-weight:600; font-style:normal; text-transform:uppercase;
  letter-spacing:.12em; font-size:.68rem; color:var(--brick-red); }
/* ---- Swatch lightbox (markup built by website.js) ----
   One dialog for the whole grid: swatch at up to 720px, name, tier line,
   previous / next, close. Deep-navy scrim, same family as .quote-overlay. */
.lightbox{ position:fixed; inset:0; z-index:90; display:none; align-items:center; justify-content:center; padding:24px; background:rgba(15,29,56,.88); backdrop-filter:blur(6px); }
.lightbox.open{ display:flex; }
.lb-fig{ margin:0; width:min(720px, 92vw, calc(100vh - 170px)); text-align:center; }
.lb-img{ width:100%; aspect-ratio:1; object-fit:cover; display:block; border-radius:var(--radius-media); border:2px solid rgba(243,233,214,.22); box-shadow:var(--shadow-deep); background:var(--navy); }
.lb-fig figcaption{ margin-top:16px; color:var(--cream); }
.lb-name{ display:block; font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:1.7rem; line-height:1.1; }
.lb-tier{ display:block; margin-top:5px; font-family:var(--font-body); font-weight:600; text-transform:uppercase; letter-spacing:.12em; font-size:.7rem; color:var(--gold); }
.lightbox button{ position:absolute; background:rgba(15,29,56,.6); border:1px solid var(--line-dark); color:var(--cream); width:46px; height:46px; border-radius:var(--radius-icon-lg); font-size:1.8rem; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; padding:0; }
.lightbox button:hover, .lightbox button:focus-visible{ border-color:var(--gold); color:var(--gold); outline:none; }
.lb-x{ top:18px; right:18px; }
.lb-prev{ left:18px; top:50%; transform:translateY(-50%); }
.lb-next{ right:18px; top:50%; transform:translateY(-50%); }
@media(max-width:680px){ .lb-prev,.lb-next{ top:auto; bottom:18px; transform:none; } }

/* ---- Bolt stripe ----
   The digitized trailer stripe, brand/north-state/bolt-stripe/. The real
   asset as an <img>, never redrawn (AESTHETIC.md section 5). Two placements,
   both from the usage guide's website list: the band above the footer on
   every page, and the bottom edge of the homepage hero. Full width, so at a
   400px phone it is 38px tall, above the 24px floor where the navy gaps close. */
.bolt-stripe{ display:block; line-height:0; background:var(--navy); }
.bolt-stripe img{ display:block; width:100%; height:auto; min-height:24px; object-fit:cover; }

/* reviews */
.reviews{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
.review{ background:var(--white); border:1px solid var(--line); border-radius:var(--radius-card); padding:26px; box-shadow:var(--shadow-card); }
.review .stars{ color:var(--gold); letter-spacing:.18em; font-size:.9rem; }
.review p{ margin:14px 0 18px; color:var(--ink); font-size:1rem; }
.review .who{ font-family:var(--font-body); font-weight:700; font-size:.88rem; color:var(--navy); }
.review .who span{ display:block; color:var(--muted); font-weight:400; font-size:.76rem; text-transform:uppercase; letter-spacing:.08em; margin-top:2px; }

/* meet the team */
.team-grid{ display:grid; grid-template-columns:1fr 1fr; gap:22px; }
.member{ display:grid; grid-template-columns:auto 1fr; gap:22px; align-items:center; background:var(--white); border:1px solid var(--line); border-radius:var(--radius-card); padding:var(--pad-card); transition:border-color .3s, transform .3s, box-shadow .3s; }
.member:hover{ border-color:rgba(180,56,46,.35); transform:translateY(-3px); box-shadow:var(--shadow-lift); }
.team-photo{ position:relative; width:128px; aspect-ratio:4/5; border-radius:var(--radius-media); overflow:hidden; border:1px solid var(--line);
  background:linear-gradient(160deg,#E7DAC2,#D9C9AC);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; }
.team-photo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
/* #4C5568 clears AA against both tones of the cream placeholder gradient (5.42 / 4.60) */
.member .m-body h3{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:1.45rem; color:var(--navy); }
.member .role{ font-family:var(--font-body); font-weight:600; font-size:.74rem; text-transform:uppercase; letter-spacing:.12em; color:var(--brick-red); margin:5px 0 12px; }
.member .m-body p{ font-size:.92rem; color:var(--muted); line-height:1.6; }

/* service area */
.area{ display:grid; grid-template-columns:1fr 1fr; gap:46px; align-items:center; }
.area .towns{ display:flex; flex-wrap:wrap; gap:10px; margin-top:24px; }
/* Chips are <button>: each lights its own pin. Reset the UA button styling so
   they still read as the quiet pills they were. */
.area .town{ font-family:var(--font-body); font-weight:600; font-size:.84rem; color:var(--navy);
  padding:8px 15px; border:1px solid var(--line); border-radius:30px; background:var(--white);
  cursor:pointer; -webkit-appearance:none; appearance:none; line-height:inherit;
  transition:color .2s, border-color .2s, background .2s, transform .2s; }
.area .towns .town:hover{ color:var(--brick-red); border-color:rgba(180,56,46,.45); }
.area .towns .town:focus-visible{ outline:2px solid var(--brick-red); outline-offset:2px; }
/* Active chip. Navy fill with cream type is 11.81:1. Gold is kept for the map,
   where it is a secondary mark, and off the chip, where it would fail on white. */
.area .towns .town.is-active{ color:var(--cream); background:var(--navy); border-color:var(--navy); transform:translateY(-1px); }

.area-map{ aspect-ratio:4/3; border-radius:var(--radius-media); overflow:hidden; border:1px solid var(--line); background:var(--deep-navy); box-shadow:var(--shadow-lift); }
.area-map svg{ width:100%; height:100%; display:block; }

/* ---- coverage map ------------------------------------------------------
   Pin positions are real geography, computed in index.html. Nothing here
   should move a pin; this file only styles them. */
.area-hull{ fill:rgba(224,165,38,.05); stroke:#3A4E75; stroke-width:1.2; stroke-dasharray:3 6; }
.area-map .pin{ cursor:pointer; }
.pin-link{ stroke:var(--gold); stroke-width:.8; opacity:.3; transition:opacity .2s, stroke-width .2s; }
.pin-dot{ fill:var(--gold); transition:r .2s cubic-bezier(.2,.8,.3,1.2); }
.pin-halo{ fill:var(--gold); opacity:0; transition:opacity .2s; }
/* Labels are Barlow Condensed, the brand's label face. Cream on deep navy is
   13.91:1; held back at .62 so the pins lead and the labels support. */
.pin-label{ font-family:var(--font-head); font-size:9.5px; font-weight:600; letter-spacing:.06em;
  fill:var(--cream); opacity:.62; transition:opacity .2s; pointer-events:none; }
.pin-label-hub{ font-size:11px; opacity:1; }

/* Active pin, driven from either the chip or the pin itself. */
.pin.is-active .pin-link{ opacity:.75; stroke-width:1.4; }
.pin.is-active .pin-dot{ r:5; }
.pin.is-active .pin-halo{ opacity:.28; }
.pin.is-active .pin-label{ opacity:1; }
.pin-hub.is-active .pin-dot{ r:7.5; }

/* Reveal-driven build. Reuses the existing .reveal -> .anim observer; no new
   one. Base state is the finished map, so if the script never runs, or the
   observer never fires, the map is simply already drawn.

   The fade is on the .pin GROUP, never on .pin-label itself. A finished
   animation with fill-mode both keeps ownership of the property it animated,
   and animations beat normal declarations, so fading the label directly would
   permanently outrank .pin.is-active .pin-label{opacity:1} and the highlight
   would never show. Group opacity composes with child opacity instead, which
   leaves every .is-active rule free to work. Same reason drawLink touches only
   stroke-dash* and popPin only transform: both stay clear of the properties
   the active state needs. */
.area-map.anim .pin{ animation:fadePin .45s ease-out both; animation-delay:calc(.3s + var(--i)*.055s); }
.area-map.anim .pin-link{ animation:drawLink .65s ease-out both; animation-delay:calc(.12s + var(--i)*.055s); }
.area-map.anim .pin-dot{ animation:popPin .4s cubic-bezier(.2,.8,.3,1.2) both; animation-delay:calc(.26s + var(--i)*.055s); }
@keyframes drawLink{ from{ stroke-dasharray:1; stroke-dashoffset:1; } to{ stroke-dasharray:1; stroke-dashoffset:0; } }
@keyframes popPin{ from{ transform:scale(0); } to{ transform:scale(1); } }
@keyframes fadePin{ from{ opacity:0; } to{ opacity:1; } }
/* transform-box keeps scale() centred on each dot rather than the SVG origin */
.pin-dot{ transform-box:fill-box; transform-origin:center; }
@media(prefers-reduced-motion:reduce){
  .area-map.anim .pin, .area-map.anim .pin-link, .area-map.anim .pin-dot{ animation:none; }
}

/* CTA band */
.cta-band{ text-align:center; padding:96px 0; position:relative; }
.cta-band h2{ font-family:var(--font-display); font-size:clamp(2.6rem,5.6vw,4.6rem); line-height:.94; color:var(--cream); text-transform:uppercase; }
.cta-band h2 .gold{ color:var(--gold); }
.cta-band p{ color:var(--muted-dark); margin:18px auto 30px; font-size:1.08rem; max-width:46ch; }

/* ---- QUOTE MODAL ---- */
.quote-overlay{ position:fixed; inset:0; z-index:80; display:none; align-items:center; justify-content:center; padding:24px; background:rgba(15,29,56,.74); backdrop-filter:blur(6px); }
.quote-overlay.open{ display:flex; }
.quote{ width:min(560px,100%); background:var(--white); border:1px solid var(--line); border-radius:var(--radius-card); overflow:hidden; box-shadow:0 40px 80px rgba(8,16,32,.4); }
.quote .qhead{ display:flex; align-items:center; justify-content:space-between; padding:18px 24px; border-bottom:1px solid var(--line); background:var(--navy); }
.quote .qhead .nm{ font-size:1.2rem; }
.quote .qhead .x{ background:none; border:none; color:var(--muted-dark); font-size:1.5rem; cursor:pointer; line-height:1; }
.quote .qhead .x:hover{ color:var(--cream); }
.qprog{ height:3px; background:rgba(27,42,74,.12); }
.qprog .fill{ height:100%; background:var(--brick-red); width:25%; transition:width .3s; }
.qbody{ padding:32px 30px 30px; }
.qstep{ display:none; } .qstep.active{ display:block; animation:qin .35s ease; }
@keyframes qin{ from{ opacity:0; transform:translateX(14px); } to{ opacity:1; transform:none; } }
.qstep .qey{ font-family:var(--font-body); font-weight:600; text-transform:uppercase; letter-spacing:.16em; font-size:.66rem; color:var(--brick-red); }
.qstep h3{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:2rem; color:var(--navy); margin:6px 0 22px; }
.opts{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.opt{ background:var(--cream); border:1px solid var(--line); border-radius:12px; padding:16px; cursor:pointer; transition:border-color .15s, background .15s; font-family:var(--font-body); font-weight:600; color:var(--navy); }
.opt:hover{ border-color:rgba(180,56,46,.5); }
.opt.sel{ border-color:var(--brick-red); background:rgba(180,56,46,.08); }
.opt .os{ display:block; font-weight:400; font-size:.78rem; color:var(--muted); margin-top:4px; }
.field{ margin-bottom:16px; }
.field label{ font-family:var(--font-body); font-weight:600; text-transform:uppercase; letter-spacing:.1em; font-size:.68rem; color:var(--muted); display:block; margin-bottom:7px; }
.field input, .field select{ width:100%; height:var(--input-height); background:var(--white); border:1px solid rgba(27,42,74,.24); border-radius:9px; padding:0 15px; color:var(--ink); font-family:var(--font-body); font-size:1rem; }
.field select{ -webkit-appearance:none; appearance:none; cursor:pointer; padding-right:38px; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23B4382E' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 15px center; }
.field select option{ background:var(--white); color:var(--ink); }
.field input:focus, .field select:focus{ outline:2px solid rgba(180,56,46,.35); outline-offset:1px; border-color:var(--brick-red); }
/* Timeline presets, step 3 of the quote wizard. Same look as the step-1 .opt
   buttons, but selection is driven by :checked instead of a JS class toggle:
   quote.js binds only to .opts/.opt, which these deliberately are not. Must sit AFTER the .field rules above, which are what the radio
   and the option labels would otherwise inherit input/label styling from. */
.tlopts{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.field input.tlin{ position:absolute; width:0; height:0; opacity:0; margin:0; padding:0; border:0; }
.field .tlopt{ display:block; margin:0; background:var(--cream); border:1px solid var(--line); border-radius:12px; padding:16px; cursor:pointer; transition:border-color .15s, background .15s; font-family:var(--font-body); font-weight:600; font-size:.95rem; text-transform:none; letter-spacing:0; color:var(--navy); }
.field .tlopt:hover{ border-color:rgba(180,56,46,.5); }
.tlin:checked + .tlopt{ border-color:var(--brick-red); background:rgba(180,56,46,.08); }
.tlin:focus-visible + .tlopt{ outline:2px solid rgba(180,56,46,.35); outline-offset:1px; }
/* .sizerow and .estimate (the step 2 slider and forecast range) were removed
   2026-09-21 with the slider itself. See docs/2026-09-21-Quote-Form-Colors-Stripe-Design.md. */
.qnav{ display:flex; justify-content:space-between; gap:12px; margin-top:26px; }
.qnav .btn{ flex:1; }
.qdone{ text-align:center; }
.qdone .big{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:2.2rem; color:var(--navy); }
.qdone .chk{ width:64px; height:64px; border-radius:var(--radius-icon-lg); background:rgba(180,56,46,.12); color:var(--brick-red); display:flex; align-items:center; justify-content:center; font-size:1.8rem; margin:0 auto 18px; }

/* ---- QUOTE PAGE (/quote) ---- */
.quote-page{ min-height:88vh; display:flex; flex-direction:column; justify-content:center; padding:150px 0 90px; }
.qpgrid{ display:grid; grid-template-columns:1fr minmax(0,560px); gap:54px; align-items:center; }
.qpgrid .quote{ width:100%; }
.qpintro .ey{ margin-bottom:18px; }
.qpintro h1{ font-family:var(--font-display); font-size:clamp(2.8rem,5.6vw,4.6rem); line-height:.94; color:var(--cream); text-transform:uppercase; }
.qpintro h1 .gold{ color:var(--gold); }
.qpintro .lead{ margin-top:20px; color:var(--muted-dark); }
.qpintro .trust{ display:flex; gap:30px; margin-top:36px; flex-wrap:wrap; }
.qpintro .trust .n{ font-family:var(--font-display); font-size:2.1rem; color:var(--cream); line-height:1; }
.qpintro .trust .n .gold{ color:var(--gold); }
.qpintro .trust .l{ font-size:.76rem; color:var(--muted-dark); text-transform:uppercase; letter-spacing:.1em; margin-top:5px; font-weight:600; }
@media(max-width:980px){ .qpgrid{ grid-template-columns:1fr; gap:38px; } }

/* ---- THANK YOU PAGE (/thank-you) ---- */
.thanks{ min-height:88vh; display:flex; align-items:center; text-align:center; padding:150px 0 90px; }
.thanks .card{ max-width:660px; margin:0 auto; }
.thanks .chk{ width:64px; height:64px; border-radius:var(--radius-icon-lg); background:rgba(224,165,38,.18); color:var(--gold); display:flex; align-items:center; justify-content:center; font-size:1.8rem; margin:0 auto 24px; }
.thanks h1{ font-family:var(--font-display); font-size:clamp(2.6rem,5.6vw,4.2rem); line-height:.96; color:var(--cream); text-transform:uppercase; }
.thanks h1 .gold{ color:var(--gold); }
.thanks p{ color:var(--muted-dark); margin:18px auto 30px; max-width:52ch; font-size:1.05rem; }
.thanks p b{ color:var(--cream); }
.thanks .actions{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; }

/* ---- FOOTER ---- */
.footer{ border-top:1px solid var(--line-dark); padding:66px 0 28px; background:var(--deep-navy); color:var(--cream); }
.footer .top{ display:grid; grid-template-columns:1.4fr 1fr 1fr 1.2fr; gap:34px; }
/* The wordmark carries the name, so the typeset name that used to sit beside
   the badge here is gone rather than repeated. */
.footer .brand{ display:flex; align-items:center; gap:14px; margin-bottom:18px; }
.footer .brand .wordmark{ width:min(260px,70%); }
.footer .col h4{ font-family:var(--font-body); font-weight:700; text-transform:uppercase; letter-spacing:.14em; font-size:.72rem; color:var(--gold); margin-bottom:15px; }
.footer .col a, .footer .col p{ display:block; color:var(--muted-dark); font-size:.9rem; padding:5px 0; }
.footer .col a:hover{ color:var(--cream); }
.footer .desc{ color:var(--muted-dark); font-size:.9rem; max-width:34ch; }
.phone-soon{ color:var(--muted-dark); font-style:italic; }
.nav .phone.phone-soon{ font-style:normal; opacity:.7; cursor:default; }
.social{ display:flex; gap:12px; margin-top:18px; }
.social a{ display:inline-flex; align-items:center; justify-content:center; width:36px; height:36px; border-radius:var(--radius-icon-lg); border:1px solid var(--line-dark); color:var(--muted-dark); transition:color .2s, border-color .2s, transform .2s; }
.social a:hover{ color:var(--gold); border-color:rgba(224,165,38,.5); transform:translateY(-2px); }
/* #7A87A0 is the dimmest footer-legal tone that still clears WCAG AA (4.63:1) on deep navy */
.footer .bottom{ display:flex; justify-content:space-between; align-items:center; margin-top:48px; padding-top:22px; border-top:1px solid var(--line-dark); color:#7A87A0; font-size:.8rem; flex-wrap:wrap; gap:12px; }
.footer .bottom a:hover{ color:var(--cream); }

/* ---- RESPONSIVE ---- */
@media(max-width:980px){
  .price-wrap,.area{ grid-template-columns:1fr; gap:30px; }
  .steps,.coat-grid{ grid-template-columns:1fr 1fr; }
  .gallery{ grid-template-columns:1fr 1fr; }
  .reviews{ grid-template-columns:1fr; }
  .team-grid{ grid-template-columns:1fr; }
  .flakes{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .footer .top{ grid-template-columns:1fr 1fr; }
}
@media(max-width:480px){
  .member{ grid-template-columns:1fr; justify-items:start; }
}
@media(max-width:680px){
  .nav .links, .nav .phone, .nav .navcta{ display:none; }
  .nav .burger{ display:flex; }
  .wrap,.nav .bar,.sec-head{ padding-left:22px; padding-right:22px; }
  .gallery{ grid-template-columns:1fr; }
  .coat-grid{ grid-template-columns:1fr 1fr; }
  .flakes{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
  .footer .top{ grid-template-columns:1fr; }
  .opts{ grid-template-columns:1fr; }
  .tlopts{ grid-template-columns:1fr; }
  .section{ padding:74px 0; }
  /* The mark sits large at the top of the page, then collapses on scroll. The
     collapse is the point: it has to read as a real transition on a phone,
     where the old 48 -> 44 was too small a change to notice. Both widths clear
     the 120px one-colour screen minimum, and the file is vector, so there is
     no native-resolution ceiling to work against. */
  .nav .bar{ min-height:92px; }
  .nav .brand .wordmark{ width:216px; }
  .nav.scrolled .brand .wordmark{ width:150px; }
}

/* ---- Logo intro overlay ---- */
.intro{ position:fixed; inset:0; z-index:80; background:var(--deep-navy); display:flex; align-items:center; justify-content:center; will-change:opacity; cursor:pointer; }
html:not(.js) .intro{ display:none; }
.intro.done{ display:none; }
.intro-inner{ display:flex; flex-direction:column; align-items:center; text-align:center; will-change:transform; padding:0 24px; }
/* Mascot above, wordmark below. The mascot runs at the standard weight, whose
   screen floor is 160px; min(210px,42vw) holds that to a 380px viewport and
   the simplified file is not needed. Gaps are set from the two clear-space
   rules, in px so they do not resolve against the flex parent's width:
   mascot 12% of 210 = 26px, wordmark 5.66% of 420 = 24px. 34px clears both. */
.intro-mascot{ width:min(210px,42vw); height:auto; margin-bottom:34px; }
.intro-wordmark{ width:min(420px,74vw); height:auto; }
.intro-tag{ margin-top:30px; color:var(--gold); font-family:var(--font-body); font-weight:600; font-size:1rem; letter-spacing:.03em; }
.intro-cue{ position:absolute; bottom:34px; left:50%; transform:translateX(-50%); display:flex; flex-direction:column; align-items:center; gap:10px; }
.intro-cue span{ font-family:var(--font-body); font-weight:600; text-transform:uppercase; letter-spacing:.28em; text-indent:.28em; font-size:.66rem; color:var(--muted-dark); }
.intro-cue i{ width:1px; height:34px; background:linear-gradient(var(--gold),transparent); animation:cueDrop 1.8s ease-in-out infinite; }
@keyframes cueDrop{ 0%{ transform:scaleY(0); transform-origin:top; } 45%{ transform:scaleY(1); transform-origin:top; } 55%{ transform:scaleY(1); transform-origin:bottom; } 100%{ transform:scaleY(0); transform-origin:bottom; } }
@media (prefers-reduced-motion: reduce){ .intro{ display:none; } }

/* ---- Referral program ---- */
.refgrid{ display:grid; grid-template-columns:1fr 1.1fr; gap:44px; align-items:start; }
.refsteps{ display:flex; flex-direction:column; gap:18px; }
.refsteps .step h3{ font-size:1.05rem; margin-bottom:8px; }
.refsteps .step p{ color:var(--muted); font-size:.95rem; }
.refform{ background:var(--white); border:1px solid var(--line); border-radius:var(--radius-card); padding:28px 26px; box-shadow:var(--shadow-card); }
.refcols{ display:grid; grid-template-columns:1fr 1fr; gap:0 22px; }
.refcol-label{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:1.25rem; color:var(--brick-red); margin-bottom:14px; }
.refconfirm{ display:flex; gap:10px; align-items:flex-start; font-size:.8rem; color:var(--muted); line-height:1.5; margin:6px 0 20px; cursor:pointer; }
.refconfirm input{ margin-top:3px; accent-color:var(--brick-red); flex:0 0 auto; }
.refform .btn{ width:100%; }
.refdone{ margin-top:18px; background:rgba(224,165,38,.14); border:1px solid rgba(224,165,38,.45); border-radius:10px; padding:15px 17px; color:var(--navy); font-size:.95rem; }
@media (max-width: 900px){ .refgrid{ grid-template-columns:1fr; } .refcols{ grid-template-columns:1fr; } }
/* Homepage referral block is now a link to /referral, not a form. The .refform,
   .refcols, .refcol-label, .refconfirm and .refdone rules above are still live:
   they style the real form, which moved to /referral. Do not delete them. */
.refcta{ display:flex; justify-content:center; }
.refcta .btn{ min-height:52px; display:inline-flex; align-items:center; padding:0 34px; font-size:1.05rem; }


/* =====================================================================
   GET MY PRICE LANDING (/get-my-price). Added 2026-09-21.
   Focused landing chrome for QR and door-hanger traffic: wordmark, phone,
   one CTA, no site nav. Everything else reuses the shared tokens, .btn,
   .field, .floor and .tlopts. Mobile-first; desktop only widens the spine.
   Design record: docs/2026-09-21-Get-My-Price-Landing-Design.md
   ===================================================================== */
body.lp{ background:var(--cream); }
.lp-head{ background:var(--deep-navy); border-bottom:1px solid var(--line-dark); }
.lp-head .wrap{ display:flex; align-items:center; gap:16px; min-height:74px; }
.lp-head .brand{ display:block; margin-right:auto; }
.lp-head .wordmark{ width:clamp(150px, 32vw, 190px); }
.lp-head .phone{ font-family:var(--font-body); font-weight:600; color:var(--gold); font-size:.95rem; white-space:nowrap; }
.lp-head .btn{ min-height:42px; padding:0 18px; font-size:.92rem; }
@media(max-width:680px){ .lp-head .phone{ display:none; } } /* the number is in the hero and the form */

.lp-hero{ padding:64px 0 72px; }
.lp-hero .ey{ margin-bottom:16px; }
.lp-hero h1{ font-family:var(--font-display); font-size:clamp(2.5rem,7.6vw,4.8rem); line-height:.94; color:var(--cream); text-transform:uppercase; letter-spacing:.005em; }
.lp-hero h1 .gold{ color:var(--gold); }
.lp-hero .lead{ margin-top:20px; color:var(--muted-dark); max-width:56ch; }
.lp-hero .actions{ display:flex; gap:12px; flex-wrap:wrap; margin-top:28px; }

.lp-section{ padding:56px 0; border-top:1px solid var(--line); }
.lp-section .ey{ color:var(--brick-red); margin-bottom:14px; }
.lp-video-sec{ padding-top:44px; }
.lp-video{ margin:0; }
.lp-video video{ display:block; width:100%; aspect-ratio:16/9; background:var(--deep-navy); border-radius:var(--radius-media); border:1px solid var(--line); box-shadow:var(--shadow-card); object-fit:cover; }
.lp-video figcaption{ margin-top:14px; color:var(--muted); font-size:.95rem; max-width:60ch; }

.lp-price .big{ font-family:var(--font-display); font-size:clamp(4.2rem,15vw,7.2rem); line-height:.9; color:var(--navy); }
.lp-price .big .u{ font-size:.34em; color:var(--brick-red); letter-spacing:.02em; margin-left:.06em; }
.lp-price .allin{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; font-size:clamp(1.6rem,5vw,2.4rem); letter-spacing:var(--head-tracking); color:var(--brick-red); margin-top:6px; }
.lp-price .lead{ margin-top:18px; }
.lp-price .fine{ margin-top:14px; color:var(--muted); font-size:.92rem; max-width:60ch; }

.lp-diff .h-sec{ font-size:clamp(2rem,6.2vw,3.2rem); }
.lp-diff .lead{ margin-top:16px; }
.pillars{ list-style:none; margin-top:22px; display:grid; gap:12px; }
.pillars li{ background:var(--white); border:1px solid var(--line); border-left:4px solid var(--brick-red); border-radius:12px; padding:14px 16px; color:var(--muted); font-size:.97rem; line-height:1.55; }
.pillars li b{ color:var(--navy); }

.spine{ list-style:none; display:grid; gap:10px; }
.spine li{ display:flex; align-items:baseline; gap:14px; background:var(--white); border:1px solid var(--line); border-radius:12px; padding:13px 16px; font-family:var(--font-body); font-weight:600; color:var(--navy); line-height:1.4; }
.spine .n{ font-family:var(--font-display); color:var(--brick-red); font-size:1.15rem; min-width:2ch; }
@media(min-width:681px){ .spine{ grid-template-columns:1fr 1fr; } }

.lp-warranty{ border-top:0; }
.lp-warranty .ey{ color:var(--gold); }
.lp-warranty h2{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); line-height:var(--head-line-height); font-size:clamp(1.7rem,5.4vw,2.6rem); color:var(--cream); }
.lp-warranty p{ margin-top:14px; color:var(--muted-dark); max-width:56ch; }

.lp-form{ background:var(--white); border:1px solid var(--line); border-radius:var(--radius-card); padding:28px 22px; box-shadow:var(--shadow-card); max-width:620px; }
.lp-form h2{ font-family:var(--font-head); font-weight:900; font-style:italic; text-transform:uppercase; letter-spacing:var(--head-tracking); font-size:2rem; line-height:1; color:var(--navy); }
.lp-form .sub{ margin:10px 0 22px; color:var(--muted); font-size:.95rem; }
.lp-form .field label .optl{ font-weight:400; letter-spacing:0; text-transform:none; color:var(--muted); margin-left:6px; }
.field textarea{ width:100%; background:var(--white); border:1px solid rgba(27,42,74,.24); border-radius:9px; padding:12px 15px; color:var(--ink); font-family:var(--font-body); font-size:1rem; resize:vertical; min-height:88px; }
.field textarea:focus{ outline:2px solid rgba(180,56,46,.35); outline-offset:1px; border-color:var(--brick-red); }
.lp-form .consent{ display:flex; gap:10px; align-items:flex-start; font-size:.78rem; color:#8b8f94; line-height:1.5; margin:14px 0 18px; cursor:pointer; }
.lp-form .consent input{ margin-top:3px; accent-color:var(--brick-red); flex:0 0 auto; }
.lp-form .consent a{ color:var(--brick-red); }
.lp-form .btn{ width:100%; min-height:52px; font-size:1.05rem; }
.lp-form .alt{ margin-top:14px; text-align:center; color:var(--muted); font-size:.9rem; }
.lp-form .alt a{ color:var(--brick-red); font-weight:600; }

.lp-foot{ background:var(--deep-navy); color:var(--muted-dark); padding:40px 0 28px; font-size:.9rem; }
.lp-foot .wordmark{ width:min(220px,60%); margin-bottom:16px; }
.lp-foot p{ margin-top:8px; }
.lp-foot a{ color:var(--cream); }
.lp-foot .legal{ margin-top:18px; padding-top:16px; border-top:1px solid var(--line-dark); color:#7A87A0; font-size:.8rem; }
