/* ============================================================
   BASE — reset, typography primitives, layout, the rhythm system,
   and the reveal primitive. STRUCTURAL — content-free; copy as-is.
   (Per-section styling lives in sections.css; the swap surface in tokens.css.)
   ============================================================ */

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: auto; }
body {
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  color: var(--text-on-dark);
  background: var(--ink-900);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, picture, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
:focus-visible { outline: 2px solid var(--terracotta); outline-offset: 3px; }
::selection { background: var(--terracotta); color: #fff; }

/* ---- Lenis smooth-scroll hooks ---- */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

/* ---- Typography primitives ---- */
.display {
  font-family: var(--font-display);
  font-weight: 400;
  font-optical-sizing: auto;
  line-height: var(--leading-display);
  letter-spacing: 0;
}
.eyebrow {
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  font-weight: 500;
  color: var(--text-on-dark-muted);
}
.em { font-style: italic; color: var(--terracotta); } /* the single accent emphasis */
.measure { max-width: var(--measure); }

/* ---- Layout ---- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--wide { max-width: var(--maxw-wide); }
.stack > * + * { margin-top: var(--space-m); }

/* ---- The rhythm system: one dominant base, breaths, regrips ----
   Each section declares its family via data-bg. Same-family neighbours share
   the exact canvas, so dark runs read as one continuous surface (seamless).
   This is the COLOR-RHYTHM engine — set each section's data-bg per client. */
.section { position: relative; padding-block: var(--section-pad-y); }
.section[data-bg="ink"]        { background: var(--ink-900); color: var(--text-on-dark); }
.section[data-bg="ink-2"]      { background: var(--ink-850); color: var(--text-on-dark); }
.section[data-bg="marble"]     { background: var(--marble-50); color: var(--text-on-light); }
.section[data-bg="cream"]      { background: var(--cream); color: var(--text-on-light); }
.section[data-bg="terracotta"] { background: var(--terracotta); color: #fff; }

/* ---- Reveal primitive ----
   .js is set inline in <head> (no flash). Elements hide, then the motion
   layer animates them in on scroll. No JS / reduced-motion => fully visible. */
.js [data-reveal] { opacity: 0; transform: translateY(30px); will-change: opacity, transform; }
[data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; will-change: auto; }
  html { scroll-behavior: auto; }
}

/* ============================================================
   SHARED AMBIENT LIFE — tungsten worklight idle (site-wide aliveness contract).
   One shop floor, lit. Cells OPT IN via .tungsten-idle on a warm-glow layer so
   every section breathes at rest (T2.33 — aliveness is site-wide or the page
   reads abandoned). Compositor-cheap: opacity ONLY. Irregular filament curve so
   it reads as a real worklight, not a sine pulse. NEVER dim the honest photos —
   hook this on a separate warm overlay layer, not on content.
     .tungsten-idle        default worklight breath (charcoal sections)
     .tungsten-idle--dim   softened, for the Primer breath (cells 5–6)
     .tungsten-idle--warm  slower hearth, for the family regrip (cell 7)
   ============================================================ */
@keyframes tungsten-idle {
  0%,100% { opacity: .80; }
  8%  { opacity: .87; }
  17% { opacity: .81; }
  23% { opacity: .95; }   /* rare filament flare */
  25% { opacity: .73; }   /* dip */
  41% { opacity: .85; }
  56% { opacity: .79; }
  69% { opacity: .91; }
  83% { opacity: .82; }
}
.tungsten-idle       { animation: tungsten-idle 7.3s ease-in-out infinite; will-change: opacity; }
/* --dim uses filter:opacity (composes multiplicatively with the animated opacity
   track) — a static `opacity` is OVERRIDDEN by the @keyframes opacity and never dims. */
.tungsten-idle--dim  { animation-duration: 8.2s; filter: opacity(0.6); }
.tungsten-idle--warm { animation-duration: 9.4s; }
@media (prefers-reduced-motion: reduce) {
  .tungsten-idle, .tungsten-idle--dim, .tungsten-idle--warm { animation: none; }
}

/* ============================================================
   NAV — persistent chrome (SHARED SHELL). DESIGN.md archetype: slim top bar,
   clean-set wordmark left · condensed-caps links centre · red stamped phone
   plate right. Mobile = overlay + hide-on-scroll-down / reveal-on-scroll-up
   (mobile nav law). State classes toggled in js/main.js:
     .is-scrolled — solidify once the section under the hero is reached
     .is-hidden   — slide the whole bar up (mobile hide-on-scroll-down)
     .is-open     — mobile overlay menu open
   ============================================================ */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  min-height: var(--nav-h);
  display: flex; align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
  will-change: transform;
}
.nav.is-scrolled {
  background: color-mix(in srgb, var(--ink-deep) 92%, transparent);
  border-bottom-color: var(--ink-700);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.nav.is-hidden { transform: translateY(-100%); }
/* scroll-0 nav skin — nav-owned, but feathered past the bar so it does not read
   as a hard rectangle. Keep this much shorter than the old loose sky wash. */
.nav::before {
  content: "";
  position: absolute;
  top: 0; right: 0; left: 0;
  /* David 07.09: the fade's terminal edge IS the nav's bottom edge — never a
     floating line out in the photo. 100% = the bar's own height, always. Top is
     PITCH BLACK and opaque through the upper bar (no see-through at the top),
     then releases to zero exactly at the bar's bottom. */
  height: 100%;
  z-index: 0;
  pointer-events: none;
  /* cosine S-curve — a straight 2-stop fade and any hold/release keyframes both
     produce visible Mach-band "lines" at every slope change. The cosine holds
     darker through the top half, releases through the lower half, and reaches
     zero with a FLAT slope, so there is no perceivable edge anywhere, including
     the terminal one. Ink is the site charcoal (#1a1a1a), not black-black. */
  /* David 07.09 "grab the top-right of the hill and pull it right and slightly
     up": same cosine, midpoint warped from 50% down to ~63% down (exponent 1.5
     on the curve's input). The hill holds longer, the drop starts later, landing
     stays flat — still zero corners. */
  background: linear-gradient(to bottom,
    rgba(26,26,26,1.00) 0%,
    rgba(26,26,26,0.99) 10%,
    rgba(26,26,26,0.95) 20%,
    rgba(26,26,26,0.87) 30%,
    rgba(26,26,26,0.75) 40%,
    rgba(26,26,26,0.60) 50%,
    rgba(26,26,26,0.44) 60%,
    rgba(26,26,26,0.27) 70%,
    rgba(26,26,26,0.13) 80%,
    rgba(26,26,26,0.03) 90%,
    rgba(26,26,26,0.00) 100%);
  transition: opacity var(--dur-fast) var(--ease-out);
}
.nav.is-scrolled::before { opacity: 0; }
/* belt-and-suspenders: soft text-shadow at scroll-0, removed once the nav state changes */
.nav__links a, .nav__wordmark { text-shadow: 0 1px 4px rgba(0,0,0,0.55); }
.nav.is-scrolled .nav__links a, .nav.is-scrolled .nav__wordmark { text-shadow: none; }
.nav__inner {
  display: flex; align-items: center; gap: var(--space-l);
  position: relative; z-index: 1;
  width: 100%;
}

/* wordmark — re-set clean in the display font (NOT the photographic asset) */
.nav__wordmark {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.3rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--breath); white-space: nowrap;
}
.nav__wordmark em { font-style: normal; color: var(--accent); }

/* links — condensed caps, centre */
.nav__links {
  display: flex; align-items: center; gap: var(--space-m);
  margin-inline: auto;
}
.nav__links a {
  font-family: var(--font-display); font-weight: 500; font-size: 0.95rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--breath);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__links a:hover { color: var(--accent); }

/* red stamped phone plate — machined edge, plate-press on hover */
.nav__phone {
  font-family: var(--font-mono); font-size: 0.74rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #fff; background: var(--accent);
  padding: 11px 18px; border-radius: var(--radius);
  box-shadow: 0 3px 0 var(--terracotta-deep);
  white-space: nowrap;
  transition: transform 140ms var(--ease-out), box-shadow 140ms var(--ease-out);
}
@media (hover: hover) {
  .nav__phone:hover { transform: translateY(2px); box-shadow: 0 1px 0 var(--terracotta-deep); }
}

/* mobile toggle — hidden on desktop */
.nav__toggle {
  display: none;
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-on-dark);
  border: 1px solid var(--support); border-radius: var(--radius);
  padding: 9px 14px; box-shadow: 0 2px 0 #4a4d50;
}

/* ---- Mobile: overlay menu + toggle ---- */
@media (max-width: 760px) {
  .nav__inner { gap: var(--space-s); }
  .nav__toggle { display: inline-block; margin-left: auto; }
  .nav__phone { display: none; }
  .nav__links {
    position: fixed; inset: var(--nav-h) 0 auto 0;
    flex-direction: column; align-items: flex-start; gap: 0;
    margin: 0; padding: var(--space-m) var(--gutter) var(--space-l);
    background: color-mix(in srgb, var(--ink-deep) 97%, transparent);
    border-bottom: 1px solid var(--ink-700);
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  }
  .nav__links a {
    width: 100%; padding-block: var(--space-s);
    border-bottom: 1px solid var(--ink-700); font-size: 1.15rem;
  }
  .nav.is-open .nav__links { transform: none; opacity: 1; pointer-events: auto; }
  .nav.is-open .nav__toggle { color: var(--accent); border-color: var(--accent); }
}

/* ============================================================
   FOOTER — persistent chrome (SHARED SHELL, lead-owned). Dark, FLUSH, stamped
   steel. Cell-8 builds Words→Contact ABOVE this; the footer is chrome (nav +
   footer are the only places the wordmark restamps). No gap below it (§4 #8).
   ============================================================ */
.site-footer { background: var(--ink-deep); color: var(--text-on-dark); border-top: 1px solid var(--ink-700); }
.site-footer__inner {
  display: grid; grid-template-columns: 1.5fr 1fr auto; gap: var(--space-l);
  padding-block: var(--space-l) var(--space-m); align-items: start;
}
.site-footer__brand .nav__wordmark { font-size: 1.35rem; margin-bottom: var(--space-s); display: inline-block; color: var(--text-on-dark); text-decoration: none; }
.site-footer__brand .nav__wordmark em { color: var(--accent); font-style: normal; }
.site-footer__line { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em; color: var(--slate-400); line-height: 1.8; text-transform: uppercase; }
.site-footer__nav { display: flex; flex-direction: column; gap: 0.55rem; }
.site-footer__nav a { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.06em; font-size: 0.98rem; color: var(--text-on-dark); text-decoration: none; transition: color var(--dur-fast) var(--ease-out); }
.site-footer__nav a:hover { color: var(--accent); }
.site-footer__contact { text-align: right; }
.site-footer__phone { font-family: var(--font-display); font-weight: 700; font-size: 1.7rem; color: var(--accent); text-decoration: none; letter-spacing: 0.02em; }
.site-footer__addr { font-family: var(--font-mono); font-size: 0.76rem; font-style: normal; color: var(--slate-400); line-height: 1.7; margin-top: 0.5rem; }
.site-footer__bottom {
  display: flex; justify-content: space-between; gap: var(--space-s); flex-wrap: wrap;
  padding-block: var(--space-s); border-top: 1px solid var(--ink-700);
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: #86837d;
}
@media (max-width: 760px) {
  .site-footer__inner { grid-template-columns: 1fr; gap: var(--space-m); }
  .site-footer__contact { text-align: left; }
  .site-footer__bottom { flex-direction: column; gap: 0.4rem; align-items: flex-start; }
}
