/* ==========================================================================
   Top Performance Electrical Services — azovgroup.com/electric
   Streamlined house design language; brand accent: electric amber (from logo).
   Amber fills ALWAYS carry ink text (never white-on-amber).
   ========================================================================== */

:root {
  /* neutrals (warm) */
  --ink: #0b0b0c;
  --charcoal: #17171a;
  --paper: #ffffff;
  --bone: #f6f3ec;
  --line: #e6e1d7;
  --steel: #6b7280;
  /* accent family — electric amber, three steps + gradient */
  --accent: #edaa12;
  --accent-deep: #c18104;
  --accent-glow: #ffc63a;
  --accent-gradient: linear-gradient(135deg, var(--accent-glow), var(--accent) 50%, var(--accent-deep));
  /* branded shadows */
  --shadow-accent-soft: 0 4px 24px -4px rgba(237, 170, 18, 0.25);
  --shadow-accent-glow: 0 12px 40px -8px rgba(237, 170, 18, 0.45);
  --halo: 0 0 22px 6px rgba(255, 198, 58, 0.55);
  /* type */
  --font-display: "Inter Tight", "Inter", system-ui, sans-serif;
  --font-body: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", monospace;
  /* radii */
  --radius: 10px;
  --radius-card: 16px;
  --radius-tile: 12px;
  --radius-input: 8px;
  /* motion */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-modal: cubic-bezier(0.22, 1, 0.36, 1);
  --t-fast: 150ms;
  --t-med: 300ms;
}

/* ---------- reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* Every page paints dark at both ends (dark hero/header up top, ink footer at
   the bottom). Safari fills the blank frame between page navigations — and the
   rubber-band overscroll areas — with the ROOT background; left unset it is
   white, which reads as a bright flash between our dark pages. Ink kills the
   flash and matches overscroll at both ends. body stays white for content. */
html { background-color: var(--ink); -webkit-text-size-adjust: 100%; }
/* Smooth scrolling only once motion.js arms it (after the load-time #anchor
   jump). A bare `html { scroll-behavior: smooth }` also smooths the browser's
   own fragment jump on page open — Safari lands at the top and then visibly
   glides through the whole page to the anchor. */
html.smooth { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  overflow-x: clip;
  font-feature-settings: "ss01", "cv11";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; transition: color var(--t-fast) var(--ease); }
button { font: inherit; cursor: pointer; }
/* iOS Safari: a quick second tap on a tappable element fires double-tap-to-zoom
   (the "page sporadically zooms" bug). manipulation keeps pinch-zoom intact. */
a, button, label, input, select, textarea, summary { touch-action: manipulation; }
::selection { background: var(--accent); color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
body::-webkit-scrollbar { width: 10px; }
body::-webkit-scrollbar-thumb { background: rgba(107, 114, 128, 0.35); border-radius: 5px; }
body::-webkit-scrollbar-thumb:hover { background: rgba(237, 170, 18, 0.6); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0 0 0.5em;
}

/* viewport-fit=cover (2026-07-18): the page now paints under the iPhone
   status bar and home-indicator, so OUR ink pixels back Safari's translucent
   chrome during page navigations (iOS 26 ignores theme-color; without cover
   the chrome bands sat on Safari's default WHITE canvas and flashed on every
   menu tap). env(safe-area-inset-*) below keeps content out of the notch;
   every env() line follows a plain fallback so old browsers just drop it. */
.container { max-width: 1400px; margin: 0 auto; padding-inline: 20px; }
.container { padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right)); }
@media (min-width: 640px) {
  .container { padding-inline: 32px; }
  .container { padding-inline: max(32px, env(safe-area-inset-left)) max(32px, env(safe-area-inset-right)); }
}
@media (min-width: 1024px) {
  .container { padding-inline: 48px; }
  .container { padding-inline: max(48px, env(safe-area-inset-left)) max(48px, env(safe-area-inset-right)); }
}

/* mono voice */
.mono {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 11px;
  font-weight: 500;
}

/* eyebrow */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-size: 11px;
  font-weight: 500;
  color: #8f6205; /* darker than --accent-deep: 11px text on light needs AA contrast */
  margin-bottom: 20px;
}
.eyebrow::before { content: ""; width: 32px; height: 1px; background: currentColor; flex-shrink: 0; }
.on-dark .eyebrow { color: var(--accent-glow); }

/* section rhythm */
.section { padding-block: 96px; }
@media (min-width: 1024px) { .section { padding-block: 120px; } }
.section-dark { background: var(--ink); color: rgba(255, 255, 255, 0.82); }
.section-bone { background: var(--bone); }
.section-dark h1, .section-dark h2, .section-dark h3 { color: #fff; }

/* dark texture: 56px grid + glow blob */
.tex-grid { position: relative; }
.tex-grid::before {
  content: "";
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 56px 56px;
  pointer-events: none;
}
.tex-grid > * { position: relative; }

/* headings */
.display-xl { font-size: clamp(44px, 7.5vw, 92px); font-weight: 800; letter-spacing: -0.03em; line-height: 0.98; }
.display-md { font-size: clamp(34px, 4.5vw, 56px); font-weight: 700; }
/* NOTE: background-clip:text must live on the SAME element as the text run.
   The word-split wraps words in .w child spans, which breaks clipping on the
   parent — so the gradient is applied per-word too. */
.grad-text,
.grad-text .w {
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border-radius: 9999px;
  font-weight: 600;
  font-size: 15px;
  padding: 14px 26px;
  border: 0;
  transition: transform var(--t-med) var(--ease), box-shadow var(--t-med) var(--ease),
    background-color var(--t-med) var(--ease), border-color var(--t-med) var(--ease),
    color var(--t-fast) var(--ease);
}
.btn:active { transform: scale(0.98); }
.btn-primary {
  background: var(--accent-gradient);
  color: var(--ink);
  box-shadow: var(--shadow-accent-soft);
}
.btn-primary:hover { transform: scale(1.02); box-shadow: var(--shadow-accent-glow); }
.btn-primary:active { transform: scale(0.98); }
.btn-ghost-dark {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
  backdrop-filter: blur(8px);
}
.btn-ghost-dark:hover { border-color: rgba(255, 255, 255, 0.6); background: rgba(255, 255, 255, 0.1); }
.btn-ghost-light {
  background: transparent;
  border: 2px solid rgba(11, 11, 12, 0.2);
  color: var(--ink);
}
.btn-ghost-light:hover { border-color: var(--ink); background: rgba(11, 11, 12, 0.05); }
.btn .arrow { transition: transform var(--t-fast) var(--ease); }
.btn:hover .arrow { transform: translateX(2px); }

/* ---------- navbar ---------- */
.navbar {
  position: sticky;
  top: 0;
  z-index: 60;
  height: 64px;
  /* with viewport-fit=cover the navbar reaches under the status bar: pad its
     content below the clock and let the ::before backdrop fill the whole band */
  height: calc(64px + env(safe-area-inset-top, 0px));
  padding-top: env(safe-area-inset-top, 0px);
  /* real background on the sticky element itself — iOS 26 samples fixed/sticky
     element backgrounds to tint its glass chrome and treats a color that lives
     only on an absolute ::before as transparent (falls through to white) */
  background-color: rgba(11, 11, 12, 0.92);
}
.navbar::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(11, 11, 12, 0.78);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  z-index: -1;
}
html.nav-open .navbar,
body:has(#navtoggle:checked) .navbar { position: fixed; top: 0; left: 0; right: 0; }
/* pinning the navbar removes it from flow — pad the body by its height so the
   document doesn't shrink and clamp scrollY on short pages (contact) */
html.nav-open body,
body:has(#navtoggle:checked) { padding-top: 64px; padding-top: calc(64px + env(safe-area-inset-top, 0px)); }
.nav-inner {
  max-width: 1400px;
  margin: 0 auto;
  padding-inline: 20px;
  padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right));
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
@media (min-width: 640px) { .nav-inner { padding-inline: 32px; } }
@media (min-width: 1024px) { .nav-inner { padding-inline: 48px; } }
.brand { display: flex; align-items: center; gap: 10px; color: #fff; }
.brand .bolt { width: 22px; height: 22px; color: var(--accent-glow); flex-shrink: 0; }
.brand-name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 17px;
  letter-spacing: -0.01em;
  line-height: 1.05;
  white-space: nowrap;
}
.brand-sub {
  display: block;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.24em;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.55);
  text-transform: uppercase;
}
.nav-links { display: none; align-items: center; gap: 4px; }
@media (min-width: 1024px) { .nav-links { display: flex; } }
.nav-links a {
  color: rgba(255, 255, 255, 0.75);
  font-size: 14px;
  font-weight: 500;
  padding: 8px 16px;
  border-radius: 9999px;
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.nav-links a:hover, .nav-links a.active { color: #fff; background: rgba(255, 255, 255, 0.08); }
.nav-cta { display: none; }
@media (min-width: 1024px) { .nav-cta { display: inline-flex; padding: 10px 20px; font-size: 14px; } }

/* mobile burger + sheet */
#navtoggle { position: absolute; opacity: 0; pointer-events: none; }
.burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.3);
  cursor: pointer;
  color: #fff;
}
@media (min-width: 1024px) { .burger { display: none; } }
.burger svg { width: 18px; height: 18px; }
.burger .icon-close { display: none; }
.nav-sheet {
  position: fixed;
  inset: 0;
  top: 64px;
  top: calc(64px + env(safe-area-inset-top, 0px));
  z-index: 55;
  background: var(--ink);
  padding: 32px 20px 40px;
  padding: 32px max(20px, env(safe-area-inset-right)) calc(40px + env(safe-area-inset-bottom, 0px)) max(20px, env(safe-area-inset-left));
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-8px);
  transition: opacity var(--t-med) var(--ease), transform var(--t-med) var(--ease);
}
#navtoggle:checked ~ .nav-sheet,
html.nav-open .nav-sheet {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
/* set by motion.js while a sheet link navigates: close with no animation so
   the page crossfade doesn't snapshot a half-faded menu as an extra step */
html.nav-instant .nav-sheet { transition: none; }
#navtoggle:checked ~ .nav-inner .burger .icon-open, html.nav-open .burger .icon-open { display: none; }
#navtoggle:checked ~ .nav-inner .burger .icon-close, html.nav-open .burger .icon-close { display: block; }
.nav-sheet a.sheet-link {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  color: #fff;
  padding: 18px 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.nav-sheet .btn-primary { margin-top: 28px; width: 100%; }
.nav-sheet .sheet-meta { margin-top: auto; color: rgba(255, 255, 255, 0.4); font-size: 10px; white-space: nowrap; }

/* ---------- hero ---------- */
.hero {
  position: relative;
  background: var(--ink);
  color: #fff;
  min-height: 88svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}
.hero-media { position: absolute; inset: 0; }
.hero-media img, .hero-media video { width: 100%; height: 100%; object-fit: cover; object-position: center 32%; }
.hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(11, 11, 12, 0.95) 8%, rgba(11, 11, 12, 0.72) 45%, rgba(11, 11, 12, 0.48) 100%);
}
.hero-content { position: relative; padding-bottom: 120px; padding-top: 160px; }
.hero-status {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(11, 11, 12, 0.55);
  backdrop-filter: blur(8px);
  margin-bottom: 28px;
  color: rgba(255, 255, 255, 0.85);
}
.hero-sub {
  max-width: 560px;
  font-size: 18px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.75);
  margin: 24px 0 36px;
}
.hero-ctas { display: flex; flex-wrap: wrap; gap: 14px; }

/* halo glow dot */
.glow-dot { position: relative; width: 10px; height: 10px; flex-shrink: 0; }
.glow-dot::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  background: var(--accent-glow);
  animation: ping 1.6s var(--ease) infinite;
}
.glow-dot::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  background: var(--accent-glow);
  box-shadow: var(--halo);
}
@keyframes ping { 0% { transform: scale(1); opacity: 0.9; } 80%, 100% { transform: scale(2.2); opacity: 0; } }

/* ---------- circuit ticker (signature): vertical-bend circuit strip ---------- */
.ticker-strip {
  position: relative;
  background: rgba(11, 11, 12, 0.7);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  overflow: hidden;
}
.ticker-track {
  display: flex;
  flex-shrink: 0;
  width: max-content;
  animation: marquee 42s linear infinite;
}
.ticker-track li {
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 14px 26px 14px 0;
  list-style: none;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.7);
}
.ticker-track { margin: 0; padding: 0; }
.ticker-track .bolt-sep { width: 12px; height: 12px; color: var(--accent); flex-shrink: 0; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---------- stat band (amp ratings) ---------- */
.stat-band { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
@media (min-width: 1024px) { .stat-band { grid-template-columns: repeat(4, 1fr); } }
.section-dark .stat-band { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.12); }
.stat-cell { background: var(--paper); padding: 36px 28px; }
.section-dark .stat-cell { background: var(--ink); }
.stat-num {
  font-family: var(--font-display);
  font-size: clamp(40px, 4.5vw, 58px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ink);
}
.section-dark .stat-num { color: #fff; }
.stat-num .unit { color: var(--accent-deep); }
.section-dark .stat-num .unit { color: var(--accent-glow); }
.stat-label { margin-top: 10px; color: var(--steel); }
.section-dark .stat-label { color: rgba(255, 255, 255, 0.45); }

/* ---------- panel-schedule service list (signature) ---------- */
.panel-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--paper);
  overflow: hidden;
}
.panel-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  border-bottom: 1px solid var(--line);
  background: var(--bone);
}
.panel-row {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 24px;
  border-bottom: 1px solid var(--line);
  transition: background-color var(--t-fast) var(--ease);
}
.panel-row:last-child { border-bottom: 0; }
a.panel-row:hover { background: rgba(237, 170, 18, 0.06); }
a.panel-row:hover .panel-arrow { transform: translate(2px, -2px); color: var(--accent-deep); }
.breaker {
  width: 34px;
  height: 20px;
  border-radius: 4px;
  border: 1px solid var(--line);
  background: var(--bone);
  position: relative;
  flex-shrink: 0;
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.breaker::after {
  content: "";
  position: absolute;
  top: 3px; bottom: 3px; left: 4px;
  width: 10px;
  border-radius: 2px;
  background: var(--steel);
  opacity: 0.5;
  transition: transform var(--t-med) var(--ease), background-color var(--t-med) var(--ease), opacity var(--t-med) var(--ease);
}
a.panel-row:hover .breaker { border-color: var(--accent); background: rgba(237, 170, 18, 0.12); }
a.panel-row:hover .breaker::after { transform: translateX(16px); background: var(--accent); opacity: 1; }
.panel-row-title { font-family: var(--font-display); font-weight: 600; font-size: 18px; }
.panel-row-meta { color: var(--steel); font-size: 14px; }
.panel-arrow { margin-left: auto; color: var(--steel); transition: transform var(--t-fast) var(--ease), color var(--t-fast) var(--ease); flex-shrink: 0; }

/* ---------- cards / media tiles ---------- */
.card {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--paper);
  padding: 28px;
}
.section-dark .card {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
}
a.card, .card.hoverable { transition: transform var(--t-med) var(--ease), box-shadow var(--t-med) var(--ease); }
a.card:hover, .card.hoverable:hover { transform: translateY(-4px); box-shadow: var(--shadow-accent-soft); }

.media-tile {
  position: relative;
  border-radius: var(--radius-card);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--ink);
  display: block;
}
.media-tile img, .media-tile video { width: 100%; height: 100%; object-fit: cover; transition: transform 700ms var(--ease); }
.media-tile:hover img { transform: scale(1.05); }
.media-tile .scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(11, 11, 12, 0.88) 0%, rgba(11, 11, 12, 0.25) 45%, transparent 70%);
}
.media-tile .tile-badge {
  position: absolute;
  top: 14px; right: 14px;
  padding: 6px 12px;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(6px);
  color: #fff;
}
.media-tile .tile-info { position: absolute; left: 18px; right: 18px; bottom: 16px; color: #fff; }
.media-tile .tile-title { display: block; font-family: var(--font-display); font-weight: 700; font-size: 18px; line-height: 1.2; }
.media-tile .tile-meta { display: block; margin-top: 6px; color: rgba(255, 255, 255, 0.65); }

/* ---------- process (circuit path) ---------- */
.process-grid { display: grid; gap: 28px; position: relative; }
@media (min-width: 1024px) { .process-grid { grid-template-columns: repeat(3, 1fr); } }
.process-step { position: relative; padding: 28px; border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--paper); }
.step-badge {
  width: 44px; height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(237, 170, 18, 0.4);
  box-shadow: var(--shadow-accent-soft);
  color: #8f6205;
  margin-bottom: 18px;
}
/* scroll-scrubbed wire across the three steps: motion.js drives --rail-p (0→1)
   as the section transits the viewport. Default 1 = no-JS and reduced-motion
   visitors see the finished, fully-lit wire. Desktop only. */
.process-rail { display: none; position: absolute; top: -38px; left: 2%; right: 2%; height: 2px; background: var(--line); border-radius: 1px; }
@media (min-width: 1024px) { .process-rail { display: block; } }
.process-rail .rail-fill {
  position: absolute; inset: 0;
  transform-origin: left center;
  transform: scaleX(var(--rail-p, 1));
  background: linear-gradient(90deg, var(--accent-deep), var(--accent) 70%, var(--accent-glow));
}
.process-rail .rail-spark {
  position: absolute; top: 50%; left: calc(var(--rail-p, 1) * 100%);
  width: 10px; height: 10px; margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--accent-glow);
  box-shadow: var(--halo);
  opacity: clamp(0, calc(var(--rail-p, 1) * 20), 1);
}
.process-rail .rail-node {
  position: absolute; top: 50%;
  width: 8px; height: 8px; margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--bone);
  border: 1px solid var(--line);
}
/* each node "energizes" the moment the fill reaches it (--node-at set inline) */
.process-rail .rail-node::after {
  content: "";
  position: absolute; inset: -1px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px rgba(255, 198, 58, 0.75);
  opacity: clamp(0, calc((var(--rail-p, 1) - var(--node-at, 0)) * 12), 1);
}

/* ---------- wire seam (signature): circuit trace with a traveling pulse ----------
   Dark-canvas divider drawn like a schematic run (45° jogs, junction nodes).
   pathLength=100 lets the dash pattern work in percentages at any width. */
.wire-seam { position: relative; line-height: 0; }
.wire-seam svg { width: 100%; height: 56px; display: block; }
.wire-seam .wire-base { fill: none; stroke: rgba(255, 255, 255, 0.16); stroke-width: 1.5; }
.wire-seam .wire-pulse,
.wire-seam .wire-pulse-glow { fill: none; stroke-linecap: round; animation: wirepulse 7s linear infinite; }
.wire-seam .wire-pulse {
  stroke: var(--accent-glow);
  stroke-width: 2;
  stroke-dasharray: 6 94;
  filter: drop-shadow(0 0 4px rgba(255, 198, 58, 0.9));
}
.wire-seam .wire-pulse-glow { stroke: rgba(255, 198, 58, 0.28); stroke-width: 7; stroke-dasharray: 7 93; }
@keyframes wirepulse { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
.wire-seam .wire-node { fill: rgba(255, 255, 255, 0.25); }
.wire-seam .wire-node.lit { fill: var(--accent); filter: drop-shadow(0 0 5px rgba(255, 198, 58, 0.8)); }
/* 404 "open circuit": hollow terminals at the break; the pulse travels the left
   run and dies at the gap (one dash per cycle simply exits the path end) */
.wire-seam .wire-end { fill: var(--ink); stroke: rgba(255, 255, 255, 0.4); stroke-width: 1.5; }

/* ---------- primary-button glint (electric shine sweep on hover) ---------- */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
  content: "";
  position: absolute; top: -4px; bottom: -4px; left: 0; width: 36%;
  background: linear-gradient(100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.55) 50%, rgba(255, 255, 255, 0) 100%);
  transform: translateX(-140%) skewX(-18deg);
  pointer-events: none;
}
.btn-primary:hover::after { animation: glint 700ms var(--ease); }
@keyframes glint { to { transform: translateX(320%) skewX(-18deg); } }

/* ---------- FAQ accordion (native details/summary — no JS) ---------- */
.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: 18px;
  padding: 20px 0;
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq .faq-toggle {
  width: 36px; height: 36px; flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--steel);
  transition: transform var(--t-med) var(--ease), background-color var(--t-med) var(--ease),
    border-color var(--t-med) var(--ease), color var(--t-med) var(--ease);
}
/* the icon is the × symbol pre-rotated 45° (= a plus); opening rotates the
   ring another 45° so the plus becomes an × again */
.faq .faq-toggle svg { width: 14px; height: 14px; transform: rotate(45deg); }
.faq details[open] .faq-toggle {
  transform: rotate(45deg);
  background: var(--accent-gradient);
  border-color: transparent;
  color: var(--ink);
}
.faq details p { color: var(--steel); margin: 0 0 22px; max-width: 62ch; }
.faq details[open] p { animation: faqin 300ms var(--ease) backwards; }
@keyframes faqin { from { opacity: 0; transform: translateY(-4px); } }

/* ---------- quote form ---------- */
.form-label { display: block; margin-bottom: 8px; color: var(--ink); font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.18em; font-size: 12px; font-weight: 500; }
.form-input, .form-select, .form-textarea {
  width: 100%;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-input);
  padding: 12px 16px;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(237, 170, 18, 0.15);
}
.form-row { margin-bottom: 22px; }
.form-grid { display: grid; gap: 22px; }
@media (min-width: 640px) { .form-grid.two { grid-template-columns: 1fr 1fr; } }
.form-hint { font-size: 13px; color: var(--steel); margin-top: 6px; }
.form-honeypot { position: absolute; left: -9999px; opacity: 0; height: 0; overflow: hidden; }
.form-status { margin-top: 16px; font-size: 15px; }
.form-status.ok { color: #15803d; }
.form-status.err { color: #b91c1c; }

/* service-type chips in form */
.chip-group { display: flex; flex-wrap: wrap; gap: 10px; }
.chip-group input { position: absolute; opacity: 0; pointer-events: none; }
.chip-group label {
  padding: 11px 18px; /* 44px min tap target (design-standards mobile rule) */
  border-radius: 9999px;
  border: 1px solid var(--line);
  color: var(--steel);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.chip-group label:hover { border-color: rgba(11, 11, 12, 0.4); color: var(--ink); }
.chip-group input:checked + label {
  background: var(--accent-gradient);
  color: var(--ink);
  border-color: transparent;
  box-shadow: var(--shadow-accent-soft);
}
.chip-group input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- footer ---------- */
/* padding-top moved into .footer-hero (2026-07-19 footer-as-destination) */
.footer { background: var(--ink); color: rgba(255, 255, 255, 0.7); padding-top: 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
.footer-grid { display: grid; gap: 40px; padding-top: 64px; padding-bottom: 56px; }
@media (min-width: 1024px) { .footer-grid { grid-template-columns: 2fr 1fr 1fr 1fr; } }
.footer h4 { color: rgba(255, 255, 255, 0.4); font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.18em; font-size: 11px; font-weight: 500; margin-bottom: 18px; }
.footer a:hover { color: var(--accent-glow); }
.footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }

/* ---------- credential strip (logo art removed 2026-07-19 — the multicolor
   badge fought the ink+amber discipline; the license line is the centerpiece) */
.cred-band { display: flex; justify-content: center; }
.cred-band .badge-row { justify-content: center; }
.footer-legal {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding-block: 22px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.4);
}

/* ---------- reveals ---------- */
html.js [data-reveal] { opacity: 0; transform: translateY(24px); filter: blur(8px); }
html.js [data-reveal].revealed {
  opacity: 1;
  transform: none;
  filter: none;
  transition: opacity 600ms var(--ease), transform 600ms var(--ease), filter 600ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
/* Photo/video reveals get fade+rise ONLY (2026-07-19, flooring lesson): the
   blur(8px)→sharp entrance reads as a progressive image load — each tile looks
   blurry then "finishes loading". Blur stays a text/card effect. .media-tile
   covers every Safari; the :has() twin catches media wrapped in plain divs and
   figures (iOS 15.4+ — older engines just keep the blur, nothing breaks). */
html.js [data-reveal].media-tile { filter: none; }
html.js [data-reveal]:has(img, video) { filter: none; }
html.js [data-words] .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.4em);
  animation: wordin 500ms var(--ease) both;
  animation-delay: calc(var(--wi, 0) * 55ms);
}
@keyframes wordin { to { opacity: 1; transform: none; } }

/* ---------- gallery filter bar ---------- */
.filter-bar {
  position: sticky;
  top: 64px;
  top: calc(64px + env(safe-area-inset-top, 0px));
  z-index: 40;
  background: rgba(246, 243, 236, 0.85);
  backdrop-filter: blur(10px);
  border-block: 1px solid var(--line);
  padding-block: 14px;
}
.filter-inner { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.filter-chip {
  padding: 8px 16px;
  border-radius: 9999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--steel);
  font-size: 14px;
  font-weight: 500;
  transition: all var(--t-fast) var(--ease);
}
.filter-chip:hover { border-color: rgba(11, 11, 12, 0.4); color: var(--ink); }
.filter-chip.active {
  background: var(--accent-gradient);
  color: var(--ink);
  border-color: transparent;
  box-shadow: var(--shadow-accent-soft);
}
.filter-count { margin-left: auto; color: var(--steel); }

.gallery-grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .gallery-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .gallery-grid { grid-template-columns: repeat(3, 1fr); } }

/* lightbox — soft open with a PAIRED close (2026-07-19): a full-viewport
   near-black overlay hard-cutting over the light gallery page was the same
   contrast pop the dark-surface rule bans. Always display:flex; the .open
   class drives opacity + a small media settle; visibility's transition delay
   keeps it interactive-hidden until the fade-out finishes. Close = same house
   glide at ~80% of the open duration (exit pairs with entrance). */
.lightbox {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(11, 11, 12, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  padding: max(24px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left));
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 260ms var(--ease-modal), visibility 0s linear 260ms;
}
.lightbox.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 320ms var(--ease-modal), visibility 0s;
}
.lightbox figure { transform: translateY(10px) scale(0.985); transition: transform 260ms var(--ease-modal); }
.lightbox.open figure { transform: none; transition: transform 320ms var(--ease-modal); }
/* hide the navbar while the lightbox is up: its dimmed burger sat almost
   concentric under the lightbox × (double-ring glitch on phones). :has() is
   iOS 15.4+; older Safari just keeps the faint overlap — cosmetic only.
   The visibility flip waits for the overlay to reach opaque (260ms) so the
   bar never pops out in view; leaving the state reverts instantly (base rule
   has no transition), safely behind the fading overlay. */
body:has(.lightbox.open) .navbar { visibility: hidden; transition: visibility 0s linear 260ms; }
.lightbox figure { margin: 0; max-width: min(1100px, 94vw); }
.lightbox img, .lightbox video { max-height: 82vh; width: auto; max-width: 100%; margin: 0 auto; border-radius: var(--radius-tile); }
.lightbox figcaption { color: rgba(255, 255, 255, 0.75); text-align: center; margin-top: 14px; font-size: 14px; }
.lightbox-close {
  position: absolute; top: 20px; right: 20px;
  top: max(20px, env(safe-area-inset-top)); right: max(20px, env(safe-area-inset-right));
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  font-size: 20px;
}
.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  font-size: 18px;
}
.lightbox-nav.prev { left: 16px; left: max(16px, env(safe-area-inset-left)); }
.lightbox-nav.next { right: 16px; right: max(16px, env(safe-area-inset-right)); }

/* ---------- misc ---------- */
.split { display: grid; gap: 40px; }
@media (min-width: 1024px) { .split { grid-template-columns: 4fr 8fr; gap: 64px; } }
/* balanced variant for sections whose left column carries a long two-line headline */
@media (min-width: 1024px) { .split.split-even { grid-template-columns: 1fr 1fr; } }
.lead-copy { font-size: 19px; line-height: 1.65; color: var(--steel); max-width: 640px; }
.section-dark .lead-copy { color: rgba(255, 255, 255, 0.65); }

.callout {
  border-left: 2px solid var(--accent);
  padding-left: 24px;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.35;
}

.badge-row { display: flex; flex-wrap: wrap; gap: 12px; }
.cred-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 9999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
}
.section-dark .cred-badge { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.18); color: rgba(255, 255, 255, 0.85); }
.cred-badge .bolt { width: 13px; height: 13px; color: var(--accent-deep); }
.section-dark .cred-badge .bolt { color: var(--accent-glow); }
/* accent text links (review pathway, Google listing rows) */
.link-accent { color: #8f6205; }
.link-accent:hover { color: var(--accent-deep); text-decoration: underline; }
.card p.mono a:hover { color: var(--accent-deep); }
/* badges that are links (Google listing) get the standard hover/press pair */
a.cred-badge { transition: border-color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease), transform var(--t-med) var(--ease); }
a.cred-badge:hover { border-color: var(--accent); background: rgba(237, 170, 18, 0.08); }
a.cred-badge:active { transform: scale(0.98); }
.section-dark a.cred-badge:hover { border-color: var(--accent-glow); background: rgba(255, 255, 255, 0.1); }

/* skip link */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent);
  color: var(--ink);
  padding: 10px 18px;
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .ticker-track { animation: none !important; }
  .glow-dot::before { animation: none !important; }
  /* the traveling pulse is an infinite loop — a .001ms loop strobes, so it's
     removed outright; the base wire + nodes stay as static structure */
  .wire-seam .wire-pulse, .wire-seam .wire-pulse-glow { animation: none !important; opacity: 0; }
  .btn-primary::after { animation: none !important; }
  html.js [data-reveal] { opacity: 1; transform: none; filter: none; }
  /* lightbox: instant show/hide — the global .001ms rule shrinks the durations
     but NOT the visibility transition-delays, which would leave a hidden-but-
     hittable 260ms gap; zero them explicitly */
  .lightbox, .lightbox figure { transition: none !important; }
  .lightbox figure { transform: none !important; }
  body:has(.lightbox.open) .navbar { transition: none !important; }
  html.js [data-words] .w { opacity: 1; transform: none; animation: none !important; }
  /* 2026-07-19 signature layer: final states shipped, nothing animates */
  html.js [data-lines] .line-shift { transform: none !important; transition: none !important; }
  html.js .glow-source { opacity: 1 !important; scale: 1 !important; animation: none !important; transition: none !important; }
  html.js [data-spot]::after { display: none; }
}

/* ---------- scrutiny pass 2026-07-18 ---------- */
/* BEFORE badge on gallery tiles */
.media-tile .tile-badge {
  position: absolute; top: 14px; left: 14px;
  font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.18em;
  padding: 5px 10px; border-radius: 9999px;
  background: rgba(11, 11, 12, 0.72); color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.25);
}
/* current page marker in the mobile sheet */
.nav-sheet a.sheet-link[aria-current="page"] { color: var(--accent); }
.nav-sheet a.sheet-link[aria-current="page"]::before { content: "— "; }
/* phone number must never wrap in the sheet meta */
.nav-sheet .sheet-meta a { white-space: nowrap; }
/* dark seams: hairline bridges instead of hard cuts */
.footer { border-top: 1px solid rgba(255, 255, 255, 0.08); }
.section-dark { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06); }
/* mobile filter bar: one scrollable row instead of a 3-row sticky wall */
@media (max-width: 640px) {
  .filter-inner { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding-bottom: 2px; }
  .filter-inner::-webkit-scrollbar { display: none; }
  .filter-chip { flex-shrink: 0; }
}
/* gallery empty/failure message */
.gallery-empty { grid-column: 1 / -1; padding: 48px 0; color: var(--steel); }
.gallery-empty a { color: #8f6205; text-decoration: underline; }

/* ---------- page changes (2026-07-18) ----------
   The cross-document view-transition crossfade was tried and REMOVED: iOS 26
   Safari re-tints its glass chrome (status-bar + URL-bar bands) from scratch
   on every navigation, and the ~350ms crossfade held the page in a "navigating"
   state long enough to turn that re-tint into an obvious WHITE flash in both
   bands — unfixable from page CSS (theme-color ignored; the bands sit outside
   the page even with viewport-fit=cover in portrait). A plain swap over the
   ink html background keeps the switch dark and shrinks the chrome re-tint to
   an imperceptible moment. Do not re-add @view-transition here. */

/* ---------- photo-backed dark bands (licensed atmosphere imagery, index only;
   images are pre-darkened in the JPEG so text contrast never depends on CSS) */
.band-copper { background: var(--ink) url(../img/bg-copper.jpg) center / cover no-repeat; }
.band-dusk { background: var(--ink) url(../img/bg-dusk-porch.jpg) center 38% / cover no-repeat; }

/* ══════════════════════════════════════════════════════════════════════════
   SIGNATURE LAYER (2026-07-19) — "lights on": an electrician bringing light.
   One warm source swells on as the key section arrives (TECHNIQUES §2.19 as a
   narrative beat, §2.5 view()-timeline behind @supports, IO class fallback),
   echoed once at the footer sign-off. Plus: §2.1 line-mask heading reveals,
   §2.15 cursor spotlight (one dark section, pointer-gated), §2.18 grain.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---------- lights-on glow source ----------
   Default state = fully lit (no-JS, reduced-motion, ancient browsers all see
   the finished scene). JS arms the fallback transition only when it will
   actually drive it; iOS 26+/Chrome run it scroll-linked in pure CSS. */
.glow-host { overflow: clip; }           /* glow never widens the page */
.glow-source {
  /* ORDER MATTERS: `.tex-grid > *` (earlier in this file) sets children
     position:relative at equal specificity — this block must stay AFTER it
     or the glow falls into the flow and shoves section content down */
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 198, 58, 0.15), rgba(255, 198, 58, 0.05) 55%, transparent 75%);
}
.area-glow {
  top: -170px;
  left: 50%;
  transform: translateX(-50%);
  width: min(880px, 96vw);
  aspect-ratio: 1.6;
}
.footer-glow {
  top: -60px;
  left: 50%;
  transform: translateX(-50%);
  width: min(720px, 92vw);
  aspect-ratio: 1.8;
  background: radial-gradient(closest-side, rgba(255, 198, 58, 0.12), rgba(255, 198, 58, 0.04) 55%, transparent 75%);
}
/* fallback path: motion.js adds .glow-armed, then .lit when the section enters
   (scale is the individual transform property — composes with translateX) */
html.js .glow-source.glow-armed {
  opacity: 0;
  scale: 0.6;
  transition: opacity 1.6s cubic-bezier(0.19, 1, 0.22, 1), scale 1.6s cubic-bezier(0.19, 1, 0.22, 1);
}
html.js .glow-source.glow-armed.lit { opacity: 1; scale: 1; }
/* scroll-linked path (iOS 26+ / Chrome 115+): the light swells with scroll —
   animation-timeline MUST follow the animation shorthand or it no-ops */
@supports (animation-timeline: view()) {
  html.js .glow-source {
    animation: lights-on linear both;
    animation-timeline: view();
    animation-range: entry 15% cover 55%;
  }
  html.js .glow-source.glow-armed { opacity: 1; scale: 1; transition: none; }
}
@keyframes lights-on {
  from { opacity: 0; scale: 0.6; }
  to { opacity: 1; scale: 1; }
}

/* ---------- line-mask "curtain" heading reveals (TECHNIQUES §2.1) ----------
   motion.js wraps each <br>-separated line as .line > .line-shift; headings
   without the wrappers (no-JS, split failure) simply stay visible.
   The padding/negative-margin pair keeps the clip box tall enough for glyph
   ink (Inter Tight's ink box ≈ 1.21em vs our 0.98–1.05 line-height would
   otherwise shave descenders like y/g/p at rest); the hidden offset clears
   the taller box. */
html.js [data-lines] .line {
  display: block;
  overflow: hidden;
  padding: 0.08em 0 0.16em;
  margin: -0.08em 0 -0.16em;
}
html.js [data-lines] .line-shift { display: block; transform: translateY(calc(112% + 0.24em)); }
html.js [data-lines].revealed .line-shift {
  transform: none;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--li, 0) * 90ms);
}

/* ---------- cursor spotlight (TECHNIQUES §2.15 — ONE dark section) ----------
   Pointer-gated in CSS and JS; purely additive light, content reads without it. */
@media (hover: hover) and (pointer: fine) {
  html.js [data-spot]::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 300ms var(--ease);
    background: radial-gradient(240px circle at var(--sx, 50%) var(--sy, 50%), rgba(255, 198, 58, 0.1), transparent 70%);
  }
  html.js [data-spot].spot-on::after { opacity: 1; }
}

/* ---------- grain overlay (TECHNIQUES §2.18 — static PNG, barely-there) ---- */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 45; /* over content, under nav sheet (55) / navbar (60) / lightbox (90) */
  pointer-events: none;
  background: url(../img/grain.png) repeat;
  background-size: 128px 128px;
  opacity: 0.05;
  /* no mix-blend-mode: a full-viewport fixed blend layer is the classic iOS
     compositor-flicker risk, and at 5% alpha the blend is visually identical */
}

/* ---------- footer as destination (TECHNIQUES §2.22) ---------- */
.footer-hero {
  position: relative;
  overflow: clip;
  padding: 96px 0 72px;
  text-align: center;
}
.footer-hero .container { position: relative; }
.footer-sign {
  font-family: var(--font-display);
  font-size: clamp(52px, 10vw, 124px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 0.98;
  color: #fff;
  margin: 0 0 40px;
}
.footer-hero .hero-ctas { justify-content: center; }
.footer-hero-meta { margin: 30px 0 0; color: rgba(255, 255, 255, 0.45); }
