/* ============================================================
   base.css - ERS design system (dark flagship, CWS-grade pass)
   Tokens: #0a0a0a bg with warm radial amber glows - amber ramp
   (300 #fcd34d / 400 #fbbf24 / 500 #F59E0B / 600 #d97706) - pill
   gradient CTAs with DARK text (--on-amber, AA verified) - elevated
   #141414 cards with subtle light borders - signature ease.
   Inter (self-hosted) body - Oswald (SIL OFL 1.1) display headings;
   the Paramount Sans path is licence-gated and off (see below).
   No framework. Plain custom properties.
   ============================================================ */

/* ---------------- self-hosted fonts ---------------- */
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/inter-400.woff2") format("woff2");
}
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/fonts/inter-600.woff2") format("woff2");
}
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 800; font-display: swap;
  src: url("/fonts/inter-800.woff2") format("woff2");
}
/* ---------------------------------------------------------------------------
   DISPLAY TYPEFACE - LICENCE GATE                             (2026-08-26)

   "Paramount Sans" (designer Roman Jokiranta, sold on Creative Market) is a
   PAID typeface. No webfont licence for it exists in this repo or any other
   ERS repo, and a Creative Market *desktop* licence does NOT cover @font-face
   web embedding - that is a separate, separately-priced licence tier. This
   file was served publicly from ersroof.com/fonts/paramount.woff2 as the
   display face for every h1 and h2 on every page.

   The display face therefore defaults to Oswald, which is licensed under the
   SIL Open Font License 1.1 (see /fonts/OFL.txt) and explicitly permits
   webfont embedding. Same choice, same reasoning and the same vendored binary
   as ers-metals-site (claude/legal-fix-copyright, 811a1d2), so the family
   stays visually consistent.

   *** DO NOT enable the Paramount path without a purchased Creative Market
   *** webfont licence covering these domains and their pageview volume.
   To re-enable it after purchase:
     1. restore public/fonts/paramount.woff2 (quarantined 2026-08-26, see
        docs/licenses/fonts.md for where the preserved copy is),
     2. uncomment the @font-face below,
     3. change --font-display to var(--font-display-licensed).
   --------------------------------------------------------------------------- */
@font-face {
  font-family: "Oswald";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/oswald-700.woff2") format("woff2");
}
/* LICENCE-GATED - requires a Creative Market webfont licence before enabling.
@font-face {
  font-family: "Paramount";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/paramount.woff2") format("woff2");
}
*/

:root {
  --bg: #0a0a0a;
  --surface: #141414;
  --surface-2: #1c1c1c;
  --border: #2a2a2a;
  --border-lite: rgba(255, 255, 255, .07);
  --text: #fafafa;
  --muted: #a3a3a3;
  --amber-300: #fcd34d;
  --amber-400: #fbbf24;
  --amber: #F59E0B;
  --amber-600: #d97706;
  --amber-hover: #d97f06;
  /* Dark text on amber: white-on-amber measured 2.15:1 (WCAG fail); #2a1a00 on
     amber-400 is 10.09:1, on amber-500 7.85:1, on amber-600 5.29:1 (all pass AA). */
  --on-amber: #2a1a00;
  --radius: 14px;
  --radius-lg: 22px;
  --wrap: 1160px;
  --gap: clamp(1rem, 3vw, 2rem);
  --ease: cubic-bezier(.16, .84, .44, 1);
  --shadow-md: 0 12px 30px -12px rgba(0, 0, 0, .55);
  --shadow-lg: 0 30px 70px -25px rgba(0, 0, 0, .7);
  --glow-amber: 0 10px 24px -8px rgba(245, 158, 11, .45);
  --glow-amber-lg: 0 16px 34px -8px rgba(245, 158, 11, .55);
  --font-body: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --font-display-safe: "Oswald", "Inter", system-ui, sans-serif;
  --font-display-licensed: "Paramount", "Oswald", "Inter", system-ui, sans-serif;
  /* SAFE by default. Do not point this at --font-display-licensed until a
     Paramount Sans webfont licence is purchased. See the gate above. */
  --font-display: var(--font-display-safe);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }
body {
  margin: 0; background: var(--bg); color: var(--muted);
  font-family: var(--font-body); font-size: 17px; line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--amber); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { color: var(--text); font-family: var(--font-display); line-height: 1.1; letter-spacing: -0.02em; margin: 0 0 .5em; }
h1 { font-size: clamp(2.1rem, 6vw, 3.6rem); font-weight: 700; }
h2 { font-size: clamp(1.7rem, 4vw, 2.6rem); font-weight: 700; letter-spacing: -.028em; }
h3 { font-size: 1.25rem; font-weight: 800; font-family: var(--font-body); }
p { margin: 0 0 1rem; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding-inline: clamp(1rem, 4vw, 2rem); }
.center { text-align: center; }
.eyebrow { text-transform: uppercase; letter-spacing: .16em; font-size: .8rem; font-weight: 800; color: var(--amber); margin: 0 0 .7rem; }
.lede { font-size: clamp(1.05rem, 2.2vw, 1.3rem); color: var(--muted); max-width: 60ch; }

/* ---------------- skip link + a11y ---------------- */
.skip-link { position: absolute; left: -9999px; top: 0; background: var(--amber); color: var(--on-amber); padding: .6rem 1rem; border-radius: var(--radius); z-index: 100; }
.skip-link:focus { left: 1rem; top: 1rem; }
:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
/* Amber ring fails 3:1 on light/amber surfaces - scope a dark ring there. */
.herocard :focus-visible { outline-color: #18181b; }
.tone-amber :focus-visible { outline-color: var(--on-amber); }

/* ---------------- buttons (pill + gradient + glow) ---------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4em;
  font-weight: 700; font-size: 1rem; line-height: 1; white-space: nowrap;
  padding: 1rem 1.6rem; border-radius: 999px; border: 1.5px solid transparent;
  cursor: pointer; text-decoration: none;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), background .2s, border-color .2s, color .2s;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px) scale(.99); }
.btn-primary {
  background: linear-gradient(135deg, var(--amber-400), var(--amber-600));
  color: var(--on-amber); box-shadow: var(--glow-amber);
}
.btn-primary:hover { color: var(--on-amber); transform: translateY(-2px); box-shadow: var(--glow-amber-lg); }
/* NON-TEXT CONTRAST (WCAG 2.2 SC 1.4.11, 3:1 for UI component boundaries).
   The ghost button's fill composites to #1b1b1b, which is 1.15:1 against the
   #0a0a0a page - so the BORDER is the only thing that makes the control
   visible, and it has to carry the 3:1 on its own.
   Border was rgba(255,255,255,.30) -> #545454 -> 2.61:1 vs the page: FAIL.
   Now  rgba(255,255,255,.38) -> #676767 -> 3.50:1 vs the page and 3.05:1 vs
   the button's own fill: PASS on both edges. Do not lower it. */
.btn-ghost { background: rgba(255, 255, 255, .07); color: var(--text); border-color: rgba(255, 255, 255, .38); }
.btn-ghost:hover { background: rgba(255, 255, 255, .15); border-color: rgba(255, 255, 255, .6); color: var(--text); }
.btn-block { width: 100%; }
.cta-row { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 1.4rem; }

/* ---------------- announce bar ---------------- */
.announce {
  background: linear-gradient(90deg, #201603, #0f0d0a 70%);
  color: #d6d3d1; font-size: .86rem; border-bottom: 1px solid var(--border-lite);
}
.announce-inner { display: flex; align-items: center; justify-content: center; gap: .7rem; flex-wrap: wrap; padding-block: .5rem; }
.announce-badge { color: var(--amber-400); font-weight: 700; }
.announce-sep { opacity: .45; }
.announce-call { margin-left: auto; font-weight: 700; color: #fff; }
.announce-call:hover { color: var(--amber-400); text-decoration: none; }
@media (max-width: 680px) { .announce { display: none; } }

/* ---------------- header / nav ---------------- */
.site-header {
  position: sticky; top: 0; z-index: 40;
  background: rgba(10, 10, 10, .82); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border-lite);
  transition: box-shadow .3s var(--ease);
}
.site-header.is-scrolled { box-shadow: 0 14px 34px -14px rgba(0, 0, 0, .75); }
.header-inner { display: flex; align-items: center; justify-content: space-between; min-height: 66px; }
.brand { font-family: var(--font-display); font-weight: 700; font-size: 1.25rem; color: var(--text); letter-spacing: -.02em; }
.brand:hover { text-decoration: none; color: var(--amber); }
.site-nav { display: flex; align-items: center; gap: 1.5rem; }
.site-nav a { color: var(--muted); font-weight: 600; font-size: .98rem; }
.site-nav a:hover { color: var(--text); text-decoration: none; }
.site-nav a:not(.nav-cta) { position: relative; }
.site-nav a:not(.nav-cta)::after {
  content: ""; position: absolute; left: 0; bottom: -5px; width: 0; height: 2px;
  background: var(--amber); border-radius: 2px; transition: width .25s var(--ease);
}
.site-nav a:not(.nav-cta):hover::after { width: 100%; }
.nav-cta { color: var(--on-amber) !important; padding: .7rem 1.25rem; font-size: .92rem; }
.nav-burger { display: none; }

@media (max-width: 820px) {
  /* Solid header on mobile: backdrop-filter would become the containing block
     for the fixed drawer below and pin it to the header's box. */
  .site-header { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(10, 10, 10, .97); }
  .site-header.nav-open { z-index: 60; }
  /* Hamburger is a real <button> - 44x44 tap target (WCAG 2.5.5), keyboard
     focusable, gets the global :focus-visible ring. Morphs into an X when open. */
  .nav-burger {
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    gap: 5px; width: 44px; height: 44px; padding: 0; cursor: pointer;
    background: none; border: 0; color: inherit; position: relative; z-index: 3;
  }
  .nav-burger span { display: block; width: 24px; height: 2px; background: var(--text); border-radius: 2px; transition: transform .25s var(--ease), opacity .2s; }
  .nav-open .nav-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-open .nav-burger span:nth-child(2) { opacity: 0; }
  .nav-open .nav-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  /* Slide-in right drawer (CWS pattern): 78vw dark panel, big links. */
  .site-nav {
    position: fixed; top: 0; right: 0; bottom: 0; left: auto;
    width: min(78vw, 340px); flex-direction: column; align-items: stretch; gap: 0;
    background: #121212; border-left: 1px solid var(--border);
    padding: calc(66px + 1.6rem) 1.5rem 2rem; overflow-y: auto;
    box-shadow: var(--shadow-lg);
    transition: transform .35s var(--ease);
  }
  .site-nav a { padding: .95rem .2rem; font-size: 1.15rem; color: var(--text); border-bottom: 1px solid var(--border-lite); }
  .site-nav a:not(.nav-cta)::after { display: none; }
  .nav-cta { margin: 1.2rem 0 0; text-align: center; border-bottom: 0 !important; font-size: 1rem; padding: 1rem 1.6rem; }
  /* With JS the menu is a disclosure: collapsed AND removed from the tab order
     (visibility:hidden) until the button opens it, so keyboard users don't tab
     onto invisible off-screen links. Without JS (.js absent) the nav stays
     visible/stacked so every link remains reachable. */
  .js .site-nav { transform: translateX(105%); visibility: hidden; }
  .js .site-header.nav-open .site-nav { transform: translateX(0); visibility: visible; }
}

/* ---------------- cinematic full-bleed hero (home) ---------------- */
.hero-cine {
  position: relative; min-height: 92vh; display: flex; align-items: center;
  overflow: hidden; padding: 3.5rem 0 5.5rem;
}
.hero-cine-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hero-cine-bg picture, .hero-cine-bg img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 0; border: 0;
}
/* Slow-zoom Ken Burns on the poster photo under the video. */
.hero-cine-bg img { transform: scale(1.05); animation: slowzoom 20s ease-in-out infinite alternate; }
@keyframes slowzoom { to { transform: scale(1.14); } }
/* Duotone overlay: near-black into warm amber. Copy sits over the dark end.
   AA worst case (pure white frame): left 0-48% is >= .68 black -> #525252;
   every text color used there measures >= 4.6:1 (large-text h1 span >= 3.7). */
.hero-cine-overlay {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(115deg, rgba(0, 0, 0, .84) 0%, rgba(10, 10, 10, .68) 48%, rgba(245, 158, 11, .22) 100%);
}
/* Seamless fade into the page below. */
.hero-cine-overlay::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 72%, rgba(10, 10, 10, .92) 100%);
}
.hero-cine-inner {
  position: relative; z-index: 3; display: grid; gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center; width: 100%;
}
@media (min-width: 920px) { .hero-cine-inner { grid-template-columns: 1.1fr .9fr; } }
.hero-cine .hero-eyebrow { color: var(--amber-300); letter-spacing: .2em; }
.hero-cine h1 {
  color: #fff; font-size: clamp(2.6rem, 6vw, 4.4rem); font-weight: 700;
  letter-spacing: -.035em; text-shadow: 0 4px 30px rgba(0, 0, 0, .35); margin-bottom: .3em;
}
/* Gradient text on the key phrases (amber-300 to amber-500), with a solid
   amber fallback where background-clip:text is unsupported. */
.hero-cine h1 .hl { color: var(--amber-400); }
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .hero-cine h1 .hl {
    background: linear-gradient(120deg, var(--amber-300), var(--amber));
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: var(--amber-400);
  }
}
.hero-cine .hero-sub { color: #e5e5e5; font-size: 1.16rem; max-width: 34rem; margin: 0 0 2rem; text-shadow: 0 2px 12px rgba(0, 0, 0, .35); }
.hero-trust { display: flex; gap: clamp(1.4rem, 4vw, 2.4rem); flex-wrap: wrap; }
.hero-trust-item strong { display: block; font-size: clamp(1.6rem, 3vw, 2rem); font-weight: 800; color: var(--amber-400); line-height: 1.05; font-family: var(--font-body); }
.hero-trust-item span { font-size: .85rem; color: #d4d4d4; }
.hero-scroll {
  position: absolute; z-index: 3; bottom: 1.3rem; left: 50%; transform: translateX(-50%);
  color: #fff; font-size: 1rem; font-weight: 600; letter-spacing: .2px;
  animation: bob 2s ease-in-out infinite;
}
.hero-scroll:hover { color: var(--amber-300); text-decoration: none; }
@keyframes bob { 50% { transform: translate(-50%, 8px); } }

/* hero conversion card */
.herocard {
  background: rgba(255, 255, 255, .97); color: #52525b;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: 1.7rem; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  max-width: 30rem; justify-self: end; width: 100%;
}
.herocard-title { color: #18181b; font-family: var(--font-display); font-size: 1.45rem; margin: 0 0 .2rem; letter-spacing: -.02em; }
.herocard-sub { font-size: .95rem; color: #52525b; margin: 0 0 1.2rem; }
.herocard .btn-primary { width: 100%; }
/* Same 1.4.11 fix on the light hero card: the fill is transparent, so the
   border is again the sole boundary. Was rgba(10,10,10,.35) -> #a5a5a5 on the
   #f8f8f8 card -> 2.32:1 FAIL. Now .50 -> #818181 -> 3.67:1 PASS. */
.herocard .btn-ghost { width: 100%; margin-top: .7rem; color: #18181b; border-color: rgba(10, 10, 10, .5); background: transparent; }
.herocard .btn-ghost:hover { background: rgba(10, 10, 10, .06); border-color: rgba(10, 10, 10, .7); color: #18181b; }
.herocard-call { display: block; text-align: center; margin-top: .9rem; font-weight: 700; color: #18181b; }
.herocard-call:hover { color: var(--amber-600); text-decoration: none; }
.herocard-badges { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: 1.1rem; }
.herocard-badges span { background: #e9e9eb; color: #3f3f46; font-size: .74rem; font-weight: 700; padding: .35em .85em; border-radius: 999px; }

/* ---------------- page hero (sub-pages) + sections ---------------- */
.hero {
  position: relative; text-align: center;
  padding: clamp(3.5rem, 9vw, 6.5rem) 0 clamp(2.5rem, 6vw, 4.5rem);
  background:
    radial-gradient(1100px 480px at 50% -20%, rgba(245, 158, 11, .14), transparent 60%),
    var(--bg);
}
.hero .lede { margin-inline: auto; }
.hero .cta-row { justify-content: center; }
.section { padding: clamp(3rem, 8vw, 5.5rem) 0; }
.section-title { max-width: 26ch; margin-inline: auto; text-align: center; }
.section > .wrap > .eyebrow { text-align: center; }
.section-lead { color: var(--muted); font-size: 1.1rem; max-width: 60ch; margin: 0 auto 2.2rem; text-align: center; }
.tone-raise { background: var(--surface); border-block: 1px solid var(--border-lite); }
.tone-cta {
  background:
    radial-gradient(900px 420px at 80% 110%, rgba(245, 158, 11, .12), transparent 60%),
    linear-gradient(180deg, var(--surface), var(--bg));
}
/* Full-bleed amber conversion band: the dark site's "dark gradient band"
   equivalent - maximum contrast moment. Dark text + dark buttons on amber. */
.tone-amber { background: linear-gradient(135deg, var(--amber-400), var(--amber-600)); }
.tone-amber h2, .tone-amber .section-title { color: var(--on-amber); }
.tone-amber p, .tone-amber .lede, .tone-amber .center-lede { color: var(--on-amber); }
.tone-amber .btn-primary { background: #141414; color: #fafafa; box-shadow: 0 14px 30px -10px rgba(42, 26, 0, .5); }
.tone-amber .btn-primary:hover { background: #000; color: #fff; }
/* Same 1.4.11 fix on the amber band. Measured against the DARKER end of the
   gradient (--amber-600 #d97706), which is the worst case: the border was
   rgba(42,26,0,.55) -> 2.29:1 FAIL. Now .75 -> 3.40:1 PASS at both ends. */
.tone-amber .btn-ghost { color: var(--on-amber); border-color: rgba(42, 26, 0, .75); background: rgba(255, 255, 255, .14); }
.tone-amber .btn-ghost:hover { background: rgba(255, 255, 255, .3); color: var(--on-amber); border-color: rgba(42, 26, 0, .9); }
.cta-band { text-align: center; padding: clamp(1.5rem, 5vw, 3rem) 0; }
.cta-band .cta-row { justify-content: center; }

/* ---------------- cards ---------------- */
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--gap); }
.card { background: var(--surface); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.7rem; box-shadow: var(--shadow-md); }

/* ---- card hover POP (lift + scale + shadow elevation) ----
   Applied to every card-like component. Hover-capable pointers get the full
   pop; touch devices get a subtle always-on elevation plus a press effect so
   the sense of depth is not hover-only. Transform animation is disabled under
   prefers-reduced-motion (border/shadow color feedback is kept). */
.card, .brand-card, .post-card, .gallery-item, .flow-step, .team-card, .loc-card {
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
@media (hover: hover) and (pointer: fine) {
  .card:hover, .brand-card:hover, .post-card:hover, .gallery-item:hover,
  .flow-step:hover, .team-card:hover, .loc-card:hover {
    border-color: var(--amber);
    transform: translateY(-5px) scale(1.015);
    box-shadow: 0 18px 38px -14px rgba(0, 0, 0, .65);
  }
}
@media (hover: none) {
  .card, .brand-card, .post-card, .gallery-item, .flow-step, .team-card, .loc-card {
    box-shadow: 0 10px 26px -16px rgba(0, 0, 0, .6);
  }
  .card:active, .brand-card:active, .post-card:active, .gallery-item:active,
  .flow-step:active, .team-card:active, .loc-card:active {
    border-color: var(--amber);
    transform: scale(.985);
  }
}
@media (prefers-reduced-motion: reduce) {
  .card:hover, .brand-card:hover, .post-card:hover, .gallery-item:hover,
  .flow-step:hover, .team-card:hover, .loc-card:hover,
  .card:active, .brand-card:active, .post-card:active, .gallery-item:active,
  .flow-step:active, .team-card:active, .loc-card:active {
    transform: none;
  }
}
.card-icon { font-size: 1.8rem; margin-bottom: .6rem; color: var(--amber); }
.card h3, .card .card-title { color: var(--text); font-family: var(--font-body); font-weight: 800; font-size: 1.25rem; line-height: 1.1; letter-spacing: -0.02em; margin: 0 0 .4rem; }
.card p { color: var(--muted); margin-bottom: .6rem; }
.card-link { font-weight: 600; }
.card-img { border-radius: var(--radius); margin-bottom: 1rem; aspect-ratio: 16/10; object-fit: cover; width: 100%; }
.tag { display: inline-block; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--amber); border: 1px solid var(--border); border-radius: 999px; padding: .2rem .7rem; margin-bottom: .6rem; }
.price-note { color: var(--muted); font-size: .92rem; }
.empty { color: var(--muted); text-align: center; padding: 2rem 0; }

/* ---------------- quotes ---------------- */
.quote-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--gap); }
.quote { margin: 0; background: var(--surface); border: 1px solid var(--border-lite); border-left: 3px solid var(--amber); border-radius: var(--radius); padding: 1.4rem; box-shadow: var(--shadow-md); }
.quote p { color: var(--text); font-size: 1.05rem; }
.quote cite { color: var(--muted); font-style: normal; font-weight: 600; font-size: .9rem; }

/* ---------------- product detail ---------------- */
.product-detail { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap); }
@media (min-width: 780px) { .product-detail { grid-template-columns: 1fr 1.2fr; align-items: start; } }
.product-hero-img { border-radius: var(--radius-lg); border: 1px solid var(--border-lite); }
.product-body :is(h2,h3) { color: var(--text); margin-top: 1.5rem; }
.spec-table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
.spec-table th, .spec-table td { text-align: left; padding: .7rem .8rem; border-bottom: 1px solid var(--border); }
.spec-table th { color: var(--muted); font-weight: 600; width: 45%; }
.spec-table td { color: var(--text); }

/* ---------------- gallery ---------------- */
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--gap); }
.gallery-item { margin: 0; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--border-lite); background: var(--surface); }
.gallery-item img { aspect-ratio: 4/3; object-fit: cover; width: 100%; }
.gallery-item figcaption { padding: .8rem 1rem; color: var(--muted); font-size: .9rem; }

/* ---------------- blog ---------------- */
.post-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--gap); }
.post-card { background: var(--surface); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.4rem; }
.post-card h2 { font-size: 1.3rem; }
.post-meta { color: var(--muted); font-size: .85rem; }
.article { max-width: 760px; padding-block: clamp(2rem, 6vw, 3.5rem); }
.article-cover, .article img { border-radius: var(--radius-lg); margin: 1.2rem 0; }
.article-body { color: #cfcfcf; font-size: 1.08rem; }
.article-body :is(h2,h3) { color: var(--text); margin-top: 1.8rem; }

/* ---------------- forms ---------------- */
.contact-grid { display: grid; gap: var(--gap); }
@media (min-width: 820px) { .contact-grid { grid-template-columns: 1fr 1.4fr; } }
.contact-info { background: var(--surface); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.7rem; box-shadow: var(--shadow-md); }
.contact-info h2 { font-size: 1.3rem; }
.contact-info strong { color: var(--text); }
.lead-form { background: var(--surface); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.7rem; box-shadow: var(--shadow-md); }
.form-heading { font-size: 1.4rem; }
.form-sub { color: var(--muted); }
.lead-form label { display: block; color: var(--muted); font-size: .9rem; font-weight: 600; margin-bottom: 1rem; }
.field-row { display: grid; gap: 0; }
@media (min-width: 560px) { .field-row { grid-template-columns: 1fr 1fr; gap: 1rem; } }
.lead-form input, .lead-form textarea {
  width: 100%; margin-top: .35rem; background: var(--bg); color: var(--text);
  border: 1.5px solid var(--border); border-radius: 12px; padding: .8rem .9rem; font: inherit;
  transition: border-color .2s, box-shadow .2s;
}
.lead-form input:focus, .lead-form textarea:focus {
  border-color: var(--amber); outline: none;
  box-shadow: 0 0 0 3px rgba(245, 158, 11, .22);
}
/* Keyboard users still get a clear focus ring on form fields (:focus-visible wins
   over the outline:none above, which only suppresses the ring for pointer focus). */
.lead-form input:focus-visible, .lead-form textarea:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.lead-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* SMS consent checkbox: a compact row; the checkbox must not inherit the
   full-width 44px text-field styling above. */
.lead-form .consent-check { display: flex; gap: .6rem; align-items: flex-start; font-weight: 500; }
.lead-form .consent-check input[type="checkbox"] {
  width: auto; min-height: 0; margin-top: .3rem; flex: 0 0 auto;
  accent-color: var(--amber);
}
.lead-form .consent-check a { color: inherit; text-decoration: underline; }
.form-status { min-height: 1.2em; margin: .6rem 0 0; font-size: .9rem; }
.form-status.ok { color: #34d399; }
.form-status.err { color: #f87171; }
.notice { padding: 1rem 1.2rem; border-radius: var(--radius); margin-bottom: 1.2rem; border: 1px solid var(--border); }
.notice-ok { border-color: #14532d; background: rgba(34,197,94,.1); color: #86efac; }
.notice-muted { color: var(--muted); background: var(--surface-2); }

/* ---------------- booking ---------------- */
.slot-list { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .6rem; }

/* ---------------- footer ---------------- */
.site-footer { border-top: 1px solid var(--border-lite); background: var(--surface); margin-top: 3rem; padding: clamp(2rem, 5vw, 3.5rem) 0 1.5rem; }
.footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--gap); }
/* The full original Extreme Roofing Solutions lockup. The footer is the one
   place with the vertical room to run it stacked and still read. */
.footer-logo { display: block; width: auto; height: 96px; margin-bottom: .35rem; }
.footer-tagline { color: var(--muted); font-size: .92rem; max-width: 34ch; }
.footer-legal-name { color: var(--muted); font-size: .85rem; }
.footer-col h3, .footer-col .footer-heading { color: var(--text); font-family: var(--font-body); font-weight: 800; font-size: .95rem; line-height: 1.1; letter-spacing: -0.02em; margin: 0 0 .8rem; }
.footer-col p { margin: .3rem 0; font-size: .92rem; }
.footer-links { list-style: none; padding: 0; margin: 0; }
.footer-links li { margin: 0; }
.footer-links a, .footer-col a { color: var(--muted); }
/* Full 44px tap targets for footer link lists (WCAG 2.5.5). */
.footer-links a { display: inline-flex; align-items: center; min-height: 44px; }
.footer-links a:hover, .footer-col a:hover { color: var(--amber); }
.footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .5rem; margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--border-lite); color: var(--muted); font-size: .84rem; }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .hero-cine-bg img { transform: none; }
  .hero-scroll { animation: none !important; }
}

/* ============================================================
   ERS Hub additions (ersroof.com) - flagship umbrella styling
   ============================================================ */

/* ---- header brand lockup ---- */
.brand { display: inline-flex; align-items: center; gap: .6rem; }
.brand:hover { text-decoration: none; }
/* The roof chevron lifted from the original Extreme Roofing Solutions mark.
   White artwork on the dark header; the wordmark beside it carries the name. */
.brand-mark { display: block; height: 48px; width: auto; }
@media (max-width: 560px) { .brand-mark { height: 40px; } }
.brand-text { display: flex; flex-direction: column; line-height: 1.05; }
.brand-name { font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; color: var(--text); letter-spacing: -.01em; }
.brand-sub { font-size: .72rem; color: var(--muted); font-weight: 600; }
@media (max-width: 400px) { .brand-sub { display: none; } .brand-name { font-size: .95rem; } }

/* ---- buttons: small variant ---- */
.btn-sm { padding: .65rem 1.1rem; font-size: .92rem; }

/* ---- rotating hero video (decorative, sits inside the cinematic hero bg) ---- */
.hero-video { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.hero-video video { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity .6s ease; }
.hero-video video.hv-on { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .hero-video video { display: none; transition: none; }
}

/* ---- section lead text ---- */
.center-lede { margin-left: auto; margin-right: auto; text-align: center; }

/* ---- brand cards (the heart of the hub): media scrim + tag pill ---- */
.brand-grid { display: grid; gap: var(--gap); grid-template-columns: 1fr; }
@media (min-width: 720px) { .brand-grid { grid-template-columns: repeat(3, 1fr); } }
.brand-card {
  display: flex; flex-direction: column; overflow: hidden; padding: 0;
  background: var(--surface); border: 1px solid var(--border-lite);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
}
.brand-media { position: relative; aspect-ratio: 3/2; overflow: hidden; background: var(--surface-2); }
.brand-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .brand-card:hover .brand-media img { transform: scale(1.06); }
}
.brand-media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(10, 10, 10, .78), transparent 55%); }
.brand-media-tag {
  position: absolute; top: .9rem; left: .9rem; z-index: 2;
  background: rgba(255, 255, 255, .92); color: #18181b;
  font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: .34em .9em; border-radius: 999px;
}
.brand-card-inner { display: flex; flex-direction: column; flex: 1 1 auto; padding: 1.4rem 1.5rem 1.6rem; }
.brand-card-top { display: flex; align-items: center; gap: .9rem; margin-bottom: 1rem; }
.brand-logo { width: 54px; height: 54px; border-radius: 12px; object-fit: contain; background: #fff; padding: 4px; flex: 0 0 auto; }
.brand-card-name { font-size: 1.15rem; margin: 0 0 .15rem; color: var(--text); font-family: var(--font-body); font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; }
.brand-card-tag { font-size: .85rem; color: var(--amber); font-weight: 600; margin: 0; }
.brand-card-body { color: var(--muted); font-size: .95rem; flex: 1 1 auto; }
.chip { display: inline-block; font-size: .74rem; font-weight: 600; color: var(--muted); background: var(--surface-2); border: 1px solid var(--border-lite); border-radius: 999px; padding: .35rem .8rem; margin-bottom: 1.1rem; }
.brand-card-links { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: auto; }

/* ---- flow steps ---- */
.flow-grid { display: grid; gap: var(--gap); grid-template-columns: 1fr; }
@media (min-width: 720px) { .flow-grid { grid-template-columns: repeat(3, 1fr); } }
.flow-step { background: var(--bg); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.7rem; position: relative; box-shadow: var(--shadow-md); }
.flow-num { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 999px; background: linear-gradient(135deg, var(--amber-400), var(--amber-600)); color: var(--on-amber); font-weight: 800; margin-bottom: .8rem; box-shadow: var(--glow-amber); }
.flow-step h3 { margin-bottom: .4rem; }
.flow-step p { color: var(--muted); }

/* ---- team ---- */
.team-grid { display: grid; gap: var(--gap); grid-template-columns: 1fr; }
@media (min-width: 620px) { .team-grid { grid-template-columns: repeat(2, 1fr); } }
.team-card { background: var(--surface); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.7rem; text-align: center; box-shadow: var(--shadow-md); }
.team-avatar { width: 68px; height: 68px; margin: 0 auto .8rem; border-radius: 999px; display: grid; place-items: center; background: linear-gradient(135deg, var(--amber), #b45309); color: #fff; font-family: var(--font-display); font-weight: 700; font-size: 1.4rem; }
.team-name { margin: 0 0 .2rem; font-size: 1.15rem; }
.team-role { color: var(--amber); font-weight: 600; font-size: .9rem; margin: 0 0 .6rem; }
.team-bio { color: var(--muted); font-size: .92rem; margin: 0; }

/* ---- locations ---- */
.loc-grid { display: grid; gap: var(--gap); grid-template-columns: 1fr; margin-bottom: 1.4rem; }
@media (min-width: 620px) { .loc-grid { grid-template-columns: repeat(2, 1fr); } }
.loc-card { background: var(--bg); border: 1px solid var(--border-lite); border-radius: var(--radius-lg); padding: 1.5rem; box-shadow: var(--shadow-md); }
.loc-card h3 { font-size: 1.05rem; margin-bottom: .5rem; }
.loc-card p { color: var(--muted); margin: 0 0 .4rem; }
.loc-meta { font-size: .85rem; color: var(--amber); }

/* ---- appointment types ---- */
.appt-types { margin-bottom: 1.6rem; }
.appt-meta { color: var(--amber); font-size: .85rem; font-weight: 600; margin: 0; }

/* ---- prose (about story) ---- */
.prose { max-width: 68ch; color: #cfcfcf; font-size: 1.08rem; margin-inline: auto; }
.prose p { margin-bottom: 1.1rem; }
.prose strong { color: var(--text); }

/* ---- footer extras ---- */
.footer-contact { margin: .2rem 0; font-size: .92rem; }
.footer-contact a { color: var(--muted); }
.footer-contact a:hover { color: var(--amber); }
.social-row { display: flex; gap: .6rem; margin-top: 1rem; }
.social-link { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border-lite); color: var(--muted); transition: color .2s, border-color .2s, transform .2s var(--ease); }
.social-link:hover { color: var(--amber); border-color: var(--amber); text-decoration: none; transform: translateY(-2px); }
.loc-label { color: var(--text); font-weight: 700; font-size: .85rem; margin: .8rem 0 .1rem; }
.footer-sub-h { margin-top: 1.4rem; }
.footer-areas { font-size: .82rem; line-height: 1.7; }

/* ---- sticky mobile CTA bar: hidden until the hero clears (body.past-hero),
   then slides up over a gradient-to-transparent dark backdrop. ---- */
.mobile-cta { display: none; }
@media (max-width: 820px) {
  .mobile-cta {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    gap: .5rem; padding: .8rem .8rem calc(.7rem + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(to top, rgba(10, 10, 10, .97) 55%, rgba(10, 10, 10, 0));
    transform: translateY(115%); opacity: 0; pointer-events: none;
    transition: transform .28s var(--ease), opacity .28s;
  }
  body.past-hero .mobile-cta { transform: none; opacity: 1; pointer-events: auto; }
  /* Without JS there is no past-hero toggle - keep the bar visible. */
  html:not(.js) .mobile-cta { transform: none; opacity: 1; pointer-events: auto; }
  .mcta { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    min-height: 48px; border-radius: 999px; font-weight: 700; font-size: 1rem; text-decoration: none; }
  .mcta-call { background: rgba(255, 255, 255, .1); color: var(--text); border: 1.5px solid rgba(255, 255, 255, .3); }
  .mcta-book { background: linear-gradient(135deg, var(--amber-400), var(--amber-600)); color: var(--on-amber); box-shadow: var(--glow-amber); }
  .mcta:hover { text-decoration: none; }
  body { padding-bottom: 76px; }
}

/* ---- mobile hero strip (CWS playbook): background + eyebrow + title + cue ---- */
@media (max-width: 760px) {
  .hero-cine { min-height: calc(100svh - 66px); align-items: flex-start; padding: 2.4rem 0 4rem; }
  .hero-cine .hero-sub, .hero-cine .hero-trust, .hero-cine .herocard { display: none; }
  .hero-cine h1 { font-size: clamp(2.2rem, 9vw, 2.8rem); }
  .hero-scroll { display: block; }
}

/* ============================================================
   Family parity with ERS Metals / the shared engine.
   Token shims first: the shared block below is written against
   --accent / --shadow-sm, which the hub's dark palette did not
   name. Amber IS the hub's accent, so these are aliases, not a
   palette change.
   ============================================================ */
:root {
  --accent: #F59E0B;
  --accent-hover: #d97f06;
  --accent-soft: rgba(245, 158, 11, .12);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35), 0 2px 8px rgba(0, 0, 0, .3);
}

/* ============================================================
   Shared system parity - the brand-agnostic half of the ERS
   Metals design pass, expressed only in tokens so the same block
   drops into the engine, ers-hub-site and ers-installations-site
   without touching any site's palette.

   Everything here is either a defect fix or a system rule that
   every ERS site needs. Anything that carries brand identity
   (hero treatment, colour choices, per-site components) stays in
   the site's own section below.
   ============================================================ */

/* ---- vertical rhythm -------------------------------------------------------
   Two tokens, because the two cases are not the same. --section-y is padding
   on a TRANSPARENT section, so two adjacent sections leave 2x of it as
   genuinely empty page. --band-y is padding inside a COLORED band, where the
   space is filled and reads as the band's own breathing room, so it can be
   larger. Both were a single ~5.5rem value, which left ~176px of dead page
   between any two plain sections. */
:root {
  --section-y: clamp(2.5rem, 5vw, 3.5rem);
  --band-y: clamp(3rem, 6vw, 4.5rem);
}
.section { padding: var(--section-y) 0; }
.section:is(.tone-raise, .tone-dark, .tone-cta, .tone-amber) { padding-block: var(--band-y); }
/* A trailing <p>/<ul>/<table> adds its own bottom margin on top of the
   section's padding, which is what pushed the worst gaps past 190px. The
   padding is the spacing contract; nothing inside gets to add to it. The
   second selector reaches one level in for a trailing <table> that sits inside
   .table-scroll and so escapes a direct-child reset. */
.section > .wrap > :last-child,
.section > .wrap > :last-child > :last-child,
.hero > .wrap > :last-child,
.article > :last-child,
.article-body > :last-child { margin-bottom: 0; }
/* A conversion band is rendered as section({tone, body: ctaBand()}), so its own
   padding stacked on the section's. Inside a section the section owns it. */
.section > .wrap > .cta-band { padding-block: 0; }

/* [hidden] must beat the layout display rules below (e.g. the lightbox flex),
   or a JS-toggled element stays on screen. */
[hidden] { display: none !important; }

/* ---- card elevation: two generic hooks -------------------------------------
   The per-component hover list above is a hand-kept allow-list, and plain CSS
   gives us no way to name a selector list once - which is exactly how a card
   family ships dead on hover. For any NEW component do NOT extend that list:
   put `lift` (or `lift-flat` for a wide element or a chip) in the class
   attribute instead. */
.lift, .lift-flat {
  /* colour + background ride along so a component whose hover is purely a
     colour change eases instead of snapping, without a second `transition`
     declaration that would overwrite this one. */
  transition: transform .3s var(--ease), box-shadow .3s var(--ease),
              border-color .3s var(--ease), color .3s var(--ease), background-color .3s var(--ease);
}
@media (hover: hover) {
  .lift:hover { transform: translateY(-6px) scale(1.015); box-shadow: var(--shadow-lg); }
  /* Wide cards and chips lift without scale - scaling a full-width card warps it. */
  .lift-flat:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
}
/* Keyboard parity. Deliberately OUTSIDE @media (hover: hover): a keyboard is
   not a mouse, and a tablet with one attached still needs the cue. Two focus
   pseudos, because there are two shapes of card - the ones that ARE the anchor
   take :focus-visible, the ones whose link is a CHILD take :focus-within. */
.lift:focus-visible, .lift:focus-within { transform: translateY(-6px) scale(1.015); box-shadow: var(--shadow-lg); }
.lift-flat:focus-visible, .lift-flat:focus-within { transform: translateY(-3px); box-shadow: var(--shadow-md); }
@media (hover: none) {
  .lift:active, .lift-flat:active { transform: scale(.985); }
}
/* One ELEMENT list rather than a hover/active pseudo pair: matching the element
   means a newly added :focus-visible or :focus-within lift cannot slip through
   un-neutered. `* { transition: none }` further down only kills the tween; an
   untreated hover transform would still be an instant jump, which is precisely
   what this setting exists to prevent. */
@media (prefers-reduced-motion: reduce) {
  .lift, .lift-flat { transform: none !important; }
}

/* ---- forms -----------------------------------------------------------------
   `font: inherit` picked up the label's .9rem, so fields computed to ~15px.
   iOS Safari zooms the page in on any field under 16px and does NOT zoom back
   out afterwards, which strands mobile visitors mid-form on /contact and /book.
   The label stays .9rem; only the control is pinned to 16px. */
.lead-form input, .lead-form textarea, .lead-form select {
  font-size: 16px;
  min-height: 44px;               /* WCAG 2.5.5 tap target */
}
/* A bare <select> renders as a native control that ignores the field styling
   above on macOS/iOS. Strip the appearance and draw our own caret. */
.lead-form select {
  appearance: none; -webkit-appearance: none;
  padding-right: 2.4rem;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1.15rem top 55%, right .85rem top 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.lead-form textarea { min-height: 7rem; }

/* ---- tap targets -----------------------------------------------------------
   >=44px on every link list (WCAG 2.5.5; roughly two thirds of this traffic is
   mobile). min-width catches one-letter labels like the "X" social link. */
.footer-links a, .footer-meta a, .footer-contact-line a, .card-link {
  display: inline-flex; align-items: center; min-height: 44px; min-width: 44px;
}
/* Gap-separated rather than " · " text: the 44px min-width made the interpuncts
   sit at visibly uneven distances from their labels. */
.footer-meta { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 1.4rem; }

/* ---- small print -----------------------------------------------------------
   Warranty caveats, "confirm at time of order" and the like. Quieter than body
   copy but still meant to be read, so it keeps the muted colour rather than
   dropping below it. */
.note { color: var(--muted); font-size: .92rem; max-width: 68ch; margin-top: 1rem; }

/* ---- chips (filters, categories, tags) ------------------------------------
   Plain links, so filtering keeps working with JavaScript off. */
.chip {
  display: inline-flex; align-items: center; gap: .45rem; min-height: 44px; padding: .6rem 1.1rem;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface);
  color: var(--muted); font-size: .9rem; font-weight: 600;
}
.chip:hover, .chip:focus-visible { color: var(--text); border-color: var(--amber); text-decoration: none; }
.chip[aria-current], .chip-on { background: var(--amber); border-color: var(--amber); color: var(--on-amber); font-weight: 700; }
.chip-count, .chip-on span { font-size: .78rem; opacity: .8; font-variant-numeric: tabular-nums; }

/* ---- pager -----------------------------------------------------------------
   44x44 minimum like every other control on the site. */
.pager { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: .5rem; margin-top: calc(var(--gap) * 1.5); }
.pager-nums { display: flex; flex-wrap: wrap; gap: .35rem; }
.pager-num, .pager-step {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 .8rem;
  border: 1px solid var(--border); border-radius: 999px; color: var(--muted); font-size: .9rem;
}
.pager-num:hover, .pager-step:hover, .pager-num:focus-visible, .pager-step:focus-visible { color: var(--text); border-color: var(--amber); text-decoration: none; }
/* .pager-on is a <span>, not an anchor: the current page is not a target, so it
   gets neither the lift nor this hover. */
.pager-on { background: var(--amber); border-color: var(--amber); color: var(--on-amber); font-weight: 700; }

/* ---- long-form + tables ----------------------------------------------------
   Post bodies are DB-authored, so a bare URL or a long part number can appear
   anywhere. Without this a long unbroken token has no break opportunity and
   scrolls the whole page sideways at 320px. break-word only splits a word that
   cannot fit on its own line, so normal prose is untouched. */
.article-body, .prose, .faq-a { overflow-wrap: break-word; }
.prose { max-width: 68ch; }
.prose p { margin: 0 0 1rem; color: var(--muted); }
.prose p:last-child { margin-bottom: 0; }
/* Let a wide table scroll on its own rather than pushing the page sideways. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.article-body table { width: 100%; border-collapse: collapse; margin: 1.4rem 0; font-size: .95rem; display: block; overflow-x: auto; }
.article-body :is(th, td) { border: 1px solid var(--border); padding: .6rem .8rem; text-align: left; vertical-align: top; }
.article-body th { background: var(--surface-2); color: var(--text); font-weight: 700; }
.article-body blockquote { margin: 1.4rem 0; padding: .2rem 0 .2rem 1.2rem; border-left: 3px solid var(--amber); color: var(--text); font-style: italic; }
/* Anchor jumps must not land the heading under the sticky header. */
.article-body :is(h2, h3)[id] { scroll-margin-top: 6rem; }
.article-lede { font-size: 1.2rem; line-height: 1.55; color: var(--text); margin: 1rem 0 0; }

/* ---- blog cards with cover art --------------------------------------------
   The image has to run edge to edge inside the rounded corner, so padding moves
   off the card and onto the body. Gated on :has() so a post card that has NOT
   been rebuilt around .post-card-body keeps its own padding rather than
   collapsing to zero; a browser without :has() simply keeps the old layout. */
.post-card:has(.post-card-body) { overflow: hidden; display: flex; flex-direction: column; padding: 0; }
.post-card-body { padding: 1.4rem; display: flex; flex-direction: column; flex: 1; }
.post-card-body > :last-child { margin-top: auto; }
.post-card-media { display: block; aspect-ratio: 16 / 9; background: var(--surface-2); }
.post-card-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.post-card-cat { font-size: .74rem; text-transform: uppercase; letter-spacing: .08em; color: var(--amber); font-weight: 700; margin: 0 0 .35rem; }

/* ---- gallery affordance + lightbox ----------------------------------------
   The whole thumbnail is the target; the badge only advertises that. */
.gallery-link { display: block; position: relative; }
.gallery-link:hover { text-decoration: none; }
.gallery-title { display: block; color: var(--text); font-weight: 700; }
.gallery-caption { display: block; }
.gallery-zoom {
  position: absolute; right: .7rem; bottom: .7rem;
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .3);
  background: rgba(20, 17, 13, .82); color: #f8f5f0; font-size: 1.05rem; line-height: 1;
  opacity: 0; transition: opacity .18s var(--ease);
}
.gallery-item:hover .gallery-zoom, .gallery-link:focus-visible .gallery-zoom { opacity: 1; }
/* Touch has no hover state to reveal it, so show the affordance outright. */
@media (hover: none) { .gallery-zoom { opacity: 1; } }

/* Dark band over the page: re-scope the tokens the way the footer does, so
   text, borders and the :focus-visible ring all stay legible on the scrim. */
.lb-open { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  --text: #f8f5f0; --muted: #c0b6a8; --border: #3d352b; --accent: #f5c563; --surface: #221d16;
  color: var(--muted);
}
.lightbox-scrim { position: absolute; inset: 0; background: rgba(14, 12, 9, .95); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.lightbox-figure { position: relative; margin: 0; display: flex; flex-direction: column; gap: 1rem; width: 100%; max-width: min(1100px, 100%); max-height: 100%; }
/* Fill the stage on the long axis of the viewport, whatever the photo's shape.
   No border or fill: object-fit leaves empty box on odd aspect ratios, and the
   scrim should show through it rather than a visible frame. */
.lightbox-img { height: 62vh; width: auto; max-width: 100%; object-fit: contain; margin: 0 auto; border-radius: var(--radius-lg); }
@media (max-aspect-ratio: 1/1) { .lightbox-img { width: 100%; height: auto; max-height: 62vh; } }
.lightbox-meta { text-align: center; color: var(--muted); }
.lightbox-title { color: var(--text); font-size: clamp(1.1rem, 3vw, 1.5rem); margin: 0 0 .2rem; }
.lightbox-caption { margin: 0; }
.lightbox-caption:empty, .lightbox-title:empty { display: none; }
.lightbox-count { margin: .5rem 0 0; font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; }
.lightbox-btn {
  position: absolute; z-index: 1; display: flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text); font-size: 1.6rem; line-height: 1;
  /* Colour only, never transform: .lightbox-prev/.lightbox-next centre
     themselves with translateY(-50%) and any transform here would fight it. */
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.lightbox-btn:hover { border-color: var(--amber); color: var(--amber); text-decoration: none; }
.lightbox-close { top: clamp(.6rem, 2vw, 1.4rem); right: clamp(.6rem, 2vw, 1.4rem); font-size: 1.15rem; }
.lightbox-prev { left: clamp(.4rem, 2vw, 1.4rem); top: 50%; transform: translateY(-50%); }
.lightbox-next { right: clamp(.4rem, 2vw, 1.4rem); top: 50%; transform: translateY(-50%); }

/* Reduced motion: kill every transition AND animation (Ken Burns slow-zoom,
   scroll-cue bob, drawer slide) sitewide; the hero video is hidden separately. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* Keyboard parity for the hub's card families (the hover list above is
   pointer-only, so a keyboard user got no depth cue at all). New components
   should use `lift` / `lift-flat` instead of extending this list. */
.card:focus-within, .brand-card:focus-within, .post-card:focus-within,
.gallery-item:focus-within, .flow-step:focus-within, .team-card:focus-within,
.loc-card:focus-within,
.brand-card:focus-visible, .loc-card:focus-visible {
  border-color: var(--amber);
  transform: translateY(-5px) scale(1.015);
  box-shadow: 0 18px 38px -14px rgba(0, 0, 0, .65);
}
/* The focus ring is amber, which measures 2.15:1 on the amber band and on the
   white hero card - both fail the 3:1 non-text minimum. Match Metals' 3px and
   keep the existing dark-ring overrides for those two surfaces. */
:focus-visible { outline-width: 3px; }

/* Present to screen readers and to the document outline, invisible on screen.
   The lightbox controls carry their accessible names this way; without the
   class those names render as literal text over the photo. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* The hero poster is now a permanent bright aerial rather than a rotating
   video whose frames were mostly dark, so the scroll cue sits on light pixels
   for the whole page life. Same shadow ers-installations-site already uses. */
.hero-scroll { text-shadow: 0 2px 10px rgba(0, 0, 0, .55); }

/* ============================================================
   careers (/careers) - the 1099 outside-sales application
   Same tokens as everything else; no new colours are invented here.
   The one new band tone is .tone-warn, used once, deliberately, for
   the "who this is not for" section - its whole job is to stop the
   wrong applicant before they reach the form.
   ============================================================ */
.careers-hero .lede { margin-inline: auto; }
.careers-hero { text-align: center; }
.careers-hero .cta-row { justify-content: center; }

/* ---- the math ---- */
.math-grid { display: grid; gap: var(--gap); grid-template-columns: 1fr; }
@media (min-width: 900px) { .math-grid { grid-template-columns: repeat(3, 1fr); } }
.math-card {
  background: var(--surface); border: 1px solid var(--border-lite);
  border-radius: var(--radius-lg); padding: 1.6rem; box-shadow: var(--shadow-md);
}
.math-card-lead { border-color: rgba(245, 158, 11, .45); box-shadow: var(--glow-amber); }
.math-card h3 { font-size: 1.35rem; margin-bottom: .4rem; }
.math-card p { margin: 0 0 .8rem; }
.math-card p:last-child { margin-bottom: 0; }
.math-eyebrow {
  text-transform: uppercase; letter-spacing: .16em; font-size: .72rem;
  font-weight: 800; color: var(--amber); margin: 0 0 .5rem !important;
}
.math-big {
  font-family: var(--font-display); font-weight: 700; color: var(--amber);
  font-size: clamp(3rem, 11vw, 4.6rem); line-height: 1; letter-spacing: -.03em;
  margin: 0 0 .6rem !important;
}
.tier-list { list-style: none; margin: 0; padding: 0; }
.tier-list li {
  display: flex; gap: .9rem; align-items: baseline;
  padding: .7rem 0; border-bottom: 1px solid var(--border-lite);
}
.tier-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.tier-pct {
  font-family: var(--font-display); font-weight: 700; color: var(--amber);
  font-size: 1.65rem; line-height: 1; flex: 0 0 3.4rem; font-variant-numeric: tabular-nums;
}
.math-paid { border-top: 1px solid var(--border-lite); padding-top: .9rem; }
.math-paid strong { color: var(--text); }

/* ---- the tool ---- */
.tool-split { max-width: 62ch; margin-inline: auto; }
.tool-copy .lede { margin: 0 0 1rem; }

/* ---- who this is not for ---- */
.tone-warn { background: #16100a; border-block: 1px solid rgba(245, 158, 11, .28); }
.repellent { max-width: 66ch; margin-inline: auto; }
.repellent h2 { font-size: clamp(1.5rem, 3.4vw, 2.1rem); }
.repellent p { margin: 0 0 1rem; }
.repellent-kicker {
  color: var(--text); font-weight: 600; border-left: 3px solid var(--amber);
  padding-left: 1rem; margin-top: 1.4rem !important;
}

/* ---- the application form ---- */
.careers-form {
  background: var(--surface); border: 1px solid var(--border-lite);
  border-radius: var(--radius-lg); padding: clamp(1.1rem, 3vw, 1.9rem);
  box-shadow: var(--shadow-md); max-width: 44rem; margin-inline: auto;
}
.careers-form .form-block { border: 0; margin: 0 0 1.9rem; padding: 0; min-width: 0; }
.careers-form .form-block:last-of-type { margin-bottom: 1.2rem; }
.careers-form .form-block > legend {
  font-family: var(--font-display); color: var(--text); font-size: 1.15rem;
  font-weight: 700; letter-spacing: -.01em; padding: 0 0 .9rem;
  border-bottom: 1px solid var(--border-lite); width: 100%; margin-bottom: 1.1rem;
}
.careers-form label { display: block; color: var(--muted); font-size: .9rem; font-weight: 600; margin-bottom: 1rem; }
.careers-form input, .careers-form textarea, .careers-form select {
  width: 100%; margin-top: .35rem; background: var(--bg); color: var(--text);
  border: 1.5px solid var(--border); border-radius: 12px; padding: .8rem .9rem;
  font: inherit; font-size: 16px; min-height: 44px;   /* 16px: stops iOS zoom-on-focus */
  transition: border-color .2s, box-shadow .2s;
}
.careers-form input:focus, .careers-form textarea:focus, .careers-form select:focus {
  border-color: var(--amber); outline: none; box-shadow: 0 0 0 3px rgba(245, 158, 11, .22);
}
.careers-form input:focus-visible, .careers-form textarea:focus-visible, .careers-form select:focus-visible {
  outline: 2px solid var(--amber); outline-offset: 2px;
}
.careers-form textarea { min-height: 7rem; resize: vertical; }
.careers-form select {
  appearance: none; -webkit-appearance: none; padding-right: 2.4rem;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1.15rem top 60%, right .85rem top 60%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.careers-form [aria-invalid="true"] { border-color: #f87171; }
.careers-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.field-hint { display: block; font-weight: 400; font-size: .82rem; color: var(--muted); margin-top: .3rem; overflow-wrap: anywhere; }
.field-optional { font-weight: 400; opacity: .7; text-transform: lowercase; }
.field-err { color: #f87171; font-size: .85rem; font-weight: 600; margin: .4rem 0 0; }
.char-count { display: block; font-size: .78rem; font-weight: 600; margin-top: .35rem; }
.char-count-short { color: #fbbf24; }
.char-count-ok { color: #34d399; }

/* Yes / no pairs: a radio group, not a select, so the answer is one tap. */
.careers-form .yn-group { border: 0; padding: 0; margin: 0 0 1.3rem; min-width: 0; }
.careers-form .yn-group > legend { color: var(--muted); font-size: .9rem; font-weight: 600; padding: 0; margin-bottom: .55rem; }
.yn-row { display: flex; gap: .7rem; flex-wrap: wrap; }
.careers-form .yn {
  display: inline-flex; align-items: center; gap: .5rem; margin: 0;
  background: var(--bg); border: 1.5px solid var(--border); border-radius: 999px;
  padding: .55rem 1.15rem; min-height: 44px; color: var(--text); cursor: pointer;
  transition: border-color .2s, background .2s;
}
.careers-form .yn:hover { border-color: rgba(245, 158, 11, .5); }
.careers-form .yn input[type="radio"] { width: auto; min-height: 0; margin: 0; accent-color: var(--amber); }
.careers-form .yn:has(input:checked) { border-color: var(--amber); background: rgba(245, 158, 11, .1); }

.form-block-video { background: var(--surface-2); border-radius: var(--radius); padding: 1.2rem !important; }
.form-block-video > legend { margin-left: 0; }
.video-prompt { color: var(--muted); font-size: .95rem; margin: 0 0 1.1rem; }
.video-prompt strong { color: var(--amber); }

.careers-form .consent-check {
  display: flex; gap: .6rem; align-items: flex-start; font-weight: 500;
  font-size: .85rem; line-height: 1.5; margin-bottom: 1.3rem;
}
.careers-form .consent-check input[type="checkbox"] {
  width: auto; min-height: 0; margin-top: .25rem; flex: 0 0 auto; accent-color: var(--amber);
}
.btn-apply { width: 100%; justify-content: center; }
.form-foot { text-align: center; font-size: .85rem; color: var(--muted); margin: .9rem 0 0; }
.notice-err { border-color: #7f1d1d; background: rgba(248, 113, 113, .1); color: #fca5a5; }
.notice-err strong { color: #fecaca; }

/* ---- FAQ ---- */
.faq-list { max-width: 46rem; margin: 0 auto 2rem; }
.faq-item {
  background: var(--surface); border: 1px solid var(--border-lite);
  border-radius: var(--radius); margin-bottom: .7rem; overflow: hidden;
}
.faq-item > summary {
  cursor: pointer; list-style: none; color: var(--text); font-weight: 600;
  padding: 1rem 3rem 1rem 1.2rem; position: relative; min-height: 44px;
  display: flex; align-items: center;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
  content: "+"; position: absolute; right: 1.2rem; top: 50%; transform: translateY(-50%);
  color: var(--amber); font-size: 1.4rem; line-height: 1; font-weight: 400;
}
/* Rotate the "+" into an "x" rather than swapping in a dash glyph. */
.faq-item > summary::after { transition: transform .2s var(--ease); }
.faq-item[open] > summary::after { transform: translateY(-50%) rotate(45deg); }
.faq-item > summary:hover { color: var(--amber); }
.faq-item > summary:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }
.faq-item > p { margin: 0; padding: 0 1.2rem 1.2rem; color: var(--muted); }

/* ============================================================
   careers: contrast lift + the in-page video recorder
   ------------------------------------------------------------
   SCOPED TO .careers-page ON PURPOSE. The sitewide dark palette is
   AA-compliant on short marketing copy, but /careers asks people to
   READ - a three-column commission breakdown, a repellent section, an
   eight-field form, an eight-question FAQ - and #a3a3a3 body text on
   #0a0a0a is tiring at that length. These overrides lift body text,
   separate the card surfaces from the page, and strengthen every
   border. Rolling the same values out sitewide is a separate,
   reviewable change; this does not pre-empt it.
   ============================================================ */
.careers-page {
  --c-text: #f7f7f7;      /* headings                       ~19:1 on --bg */
  --c-body: #dcdcdc;      /* body copy, was #a3a3a3         ~14:1 */
  --c-dim: #b5b5b5;       /* labels, hints, meta            ~10:1 */
  --c-surface: #1b1b1b;   /* cards, up from #141414 so they read as raised */
  --c-surface-2: #242424;
  --c-border: #3a3a3a;    /* up from #2a2a2a */
  color: var(--c-body);
  font-size: 17.5px;
  line-height: 1.68;
}
.careers-page p,
.careers-page li,
.careers-page .lede,
.careers-page .section-lead { color: var(--c-body); }
.careers-page h1, .careers-page h2, .careers-page h3 { color: var(--c-text); }
.careers-page .section-lead { max-width: 68ch; }
.careers-page .tone-raise { background: #131313; border-block-color: var(--c-border); }

.careers-page .math-card,
.careers-page .careers-form,
.careers-page .faq-item,
.careers-page .card {
  background: var(--c-surface);
  border-color: var(--c-border);
}
.careers-page .card p,
.careers-page .math-card p,
.careers-page .faq-item > p { color: var(--c-body); }
.careers-page .card-title,
.careers-page .faq-item > summary { color: var(--c-text); }
.careers-page .tier-list li { border-bottom-color: var(--c-border); }
.careers-page .math-paid { border-top-color: var(--c-border); }
.careers-page .repellent p { color: var(--c-body); }
.careers-page .tone-warn { background: #1b1309; border-block-color: rgba(245, 158, 11, .4); }

/* Form: the label and hint text carried most of the readability complaint. */
.careers-page .careers-form label,
.careers-page .careers-form .yn-group > legend { color: var(--c-dim); font-size: .95rem; }
.careers-page .field-hint { color: var(--c-dim); font-size: .86rem; }
.careers-page .careers-form input,
.careers-page .careers-form textarea,
.careers-page .careers-form select {
  background: #101010; color: var(--c-text); border-color: #454545;
}
.careers-page .careers-form input::placeholder,
.careers-page .careers-form textarea::placeholder { color: #8a8a8a; }
.careers-page .careers-form .form-block > legend { border-bottom-color: var(--c-border); }
.careers-page .careers-form .yn { border-color: #454545; background: #101010; }
.careers-page .consent-check { color: var(--c-body); }
.careers-page .form-foot { color: var(--c-dim); }

/* ---- the recorder ---- */
.vr {
  background: var(--c-surface-2); border: 1px solid var(--c-border);
  border-radius: var(--radius); padding: 1rem; margin-bottom: 1.1rem;
}
.vr-stage { position: relative; margin-bottom: .9rem; }
.vr-video {
  width: 100%; max-width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  background: #000; border-radius: 12px; display: block;
  /* Selfie preview reads correctly only when mirrored, the way every video
     call app does it. The RECORDED file is not mirrored, which is right. */
}
#vr-preview { transform: scaleX(-1); }
.vr-bar-wrap { height: 5px; background: #000; border-radius: 999px; overflow: hidden; margin-top: .6rem; }
.vr-bar { height: 100%; width: 0%; background: var(--amber); transition: width .2s linear; }
.vr-timer {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: .85rem;
  color: var(--amber-300); margin-top: .4rem;
}
.vr-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.vr-actions .btn { min-height: 44px; }
.btn-danger { background: #b91c1c; color: #fff; border-color: #b91c1c; }
.btn-danger:hover { background: #dc2626; color: #fff; }
/* No getUserMedia (in-app browser, older device): the record button would only
   fail, so it is removed and the camera-app path leads instead. */
.vr-nocam .vr-only { display: none; }

.vr-status { font-size: .88rem; color: var(--c-dim); margin: .7rem 0 0; min-height: 1.2em; }
.vr-status.vr-err { color: #fca5a5; }
.vr-status.vr-ok { color: #86efac; }
.vr-status.vr-rec { color: var(--amber-300); font-weight: 600; }
.vr-ok {
  margin: .6rem 0 0; font-size: .88rem; font-weight: 600; color: #86efac;
  background: rgba(34,197,94,.1); border: 1px solid #14532d;
  border-radius: 10px; padding: .6rem .8rem;
}

.vr-or {
  display: block; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .14em; color: #8a8a8a; margin: 1rem 0 .5rem;
}
.vr-file-label { display: block; margin: 0; position: relative; }
.vr-file-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: .55rem 1.15rem; border-radius: 999px;
  background: rgba(255,255,255,.07); border: 1.5px solid rgba(255,255,255,.3);
  color: var(--c-text); font-weight: 600; font-size: .95rem; cursor: pointer;
}
.vr-file-btn:hover { background: rgba(255,255,255,.15); }
/* The real input is hidden but still reachable: clicking the styled span
   activates it because both live inside the <label>.

   The selector is this specific ON PURPOSE. `.careers-page .careers-form input`
   sets width:100%, which is (0,2,1) and beats a bare `.vr-file` (0,1,0) - the
   input then rendered 375px wide inside an absolutely-positioned box and pushed
   the document to 686px, giving the whole page a horizontal scrollbar on a
   phone. Caught by measuring, not by looking. */
.careers-page .careers-form input.vr-file,
.vr input.vr-file {
  position: absolute; left: 0; top: 0;
  width: 1px; min-width: 0; max-width: 1px; height: 1px;
  opacity: 0; pointer-events: none; padding: 0; margin: 0; border: 0; min-height: 0;
}
.vr-file:focus-visible + .vr-file-btn { outline: 2px solid var(--amber); outline-offset: 2px; }
.vr-link-label { display: block; }

/* ---- mobile: most applicants are on a phone ---- */
@media (max-width: 560px) {
  .careers-page { font-size: 17px; }
  .careers-form { padding: 1rem .9rem; }
  .careers-page .careers-hero .cta-row { flex-direction: column; align-items: stretch; }
  .careers-page .careers-hero .cta-row .btn { width: 100%; justify-content: center; }
  .vr { padding: .8rem; }
  .vr-actions { flex-direction: column; }
  .vr-actions .btn { width: 100%; justify-content: center; }
  .vr-file-btn { width: 100%; }
  /* A 16:9 selfie preview is uselessly small held upright. Go portrait. */
  .vr-video { aspect-ratio: 3 / 4; }
  .tier-list li { gap: .6rem; }
  .tier-pct { flex-basis: 3rem; font-size: 1.45rem; }
  .faq-item > summary { padding: .9rem 2.6rem .9rem 1rem; }
  /* The sticky "Call / Book a Demo" bar sits ON TOP of the submit button on
     the last screen of the form. Those are sales CTAs anyway - an applicant
     has no use for them, and they compete with the one action that matters on
     this page - so hide the bar here. :has() covers current browsers; the
     bottom padding is the fallback for anything that lacks it, and is
     harmless whitespace when the bar is gone. */
  .careers-page .careers-form { padding-bottom: 4.5rem; }
}

/* Outside the mobile media query and outside .careers-page, because
   .mobile-cta is a sibling of <main> in the layout, not a descendant. */
body:has(.careers-page) .mobile-cta { display: none; }

/* ---- careers: the open-roles index (only rendered when >1 role is open) ---- */
.role-list { display: grid; gap: 1rem; max-width: 48rem; margin: 0 auto; }
.role-card {
  display: flex; flex-direction: column; gap: .8rem;
  background: var(--c-surface, var(--surface)); border: 1px solid var(--c-border, var(--border));
  border-radius: var(--radius-lg); padding: 1.4rem; text-decoration: none;
  transition: border-color .2s, transform .2s var(--ease);
}
.role-card:hover { border-color: var(--amber); text-decoration: none; transform: translateY(-2px); }
.role-card-title { font-size: clamp(1.15rem, 2.6vw, 1.5rem); margin: 0 0 .4rem; }
.role-card-sum { color: var(--c-body, var(--muted)); margin: 0; }
.role-card-meta { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .2rem; }
.role-card-meta .chip { margin-bottom: 0; text-transform: capitalize; }
.role-card-comp { color: var(--amber-300); font-size: .9rem; font-weight: 600; margin: .2rem 0 0; }
.role-card-go { color: var(--amber); font-weight: 700; font-size: .9rem; }
.role-back { margin: 0 0 .8rem; font-size: .85rem; }
.role-back a { color: var(--c-dim, var(--muted)); }
.role-back a:hover { color: var(--amber); }
@media (max-width: 560px) { .role-card { padding: 1.1rem; } }

/* ---- the candidate's self-booking page ---- */
.iv-wrap { max-width: 46rem; }
.iv-tz { font-size: .85rem; color: var(--c-dim, var(--muted)); margin: .2rem 0 0; }
.iv-days, .bk-days { display: grid; gap: 1.6rem; margin-top: 1.8rem; }
.iv-day-label, .bk-day-label { font-size: 1.05rem; margin: 0 0 .7rem; }
.iv-slots, .bk-slots { display: flex; flex-wrap: wrap; gap: .55rem; }
.iv-slot-form { margin: 0; }
.iv-slot, .bk-slot { min-width: 6.5rem; justify-content: center; }
.iv-done { text-align: center; padding-block: 2rem; }
@media (max-width: 560px) {
  /* Two per row beats a ragged wrap when there are a dozen times in a day. */
  .iv-slots, .bk-slots { display: grid; grid-template-columns: 1fr 1fr; }
  .iv-slot, .iv-slot-form, .bk-slot { width: 100%; }
}

/* ---- /book appointment picker ----
   Shares the slot rules above with the interview page. What is different
   here is the type cards (whole card is the link) and the step chrome. */
.appt-card { display: block; text-decoration: none; transition: border-color .15s ease, transform .15s ease; }
.appt-card:hover, .appt-card:focus-visible { border-color: var(--amber); transform: translateY(-2px); }
.appt-card .card-link { display: inline-block; margin-top: .9rem; color: var(--amber); }
.bk-back { margin: 0 0 1rem; font-size: .9rem; }
.bk-back a { color: var(--muted); text-decoration: none; }
.bk-back a:hover { color: var(--amber); }
.bk-step-title { margin: 0 0 .3rem; }
.bk-when { margin: .2rem 0 .6rem; font-size: 1.05rem; }
.bk-days { margin-bottom: 2.4rem; }

/* ============================================================
   Consent gate (server/views/consent.js)
   Non-essential tags load ONLY after an affirmative decision, so this
   banner is the first and only thing that decides whether analytics
   ever run. Accept and Reject are deliberately the SAME control: same
   size, same weight, same colours, same one click. Making Accept the
   prominent one is a dark pattern and its own finding.
   The banner ships with the `hidden` attribute and is revealed by the
   runtime only when there is no stored decision, so a returning visitor
   never sees it flash.
   ============================================================ */
.consent[hidden] { display: none; }
.consent {
  position: fixed; inset: auto 0 0 0; z-index: 200;
  background: var(--surface); border-top: 1px solid var(--border);
  box-shadow: 0 -10px 30px -18px rgba(0, 0, 0, .8);
  padding: 1rem 0 max(1rem, env(safe-area-inset-bottom));
}
.consent-inner {
  width: min(var(--wrap, 1160px), 100% - 2.4rem); margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.6rem;
  justify-content: space-between;
}
.consent-text { margin: 0; flex: 1 1 22rem; color: var(--muted); font-size: .9rem; line-height: 1.55; }
.consent-text strong { color: var(--text); }
.consent-actions { display: flex; flex-wrap: wrap; gap: .7rem; flex: 0 0 auto; }
.consent-btn {
  /* Identical styling for both choices - no visual hierarchy between
     accepting and rejecting. Change one, change the other.
     Border is rgba(255,255,255,.38) -> 3.50:1 on the #141414 surface,
     the same 1.4.11 floor the ghost buttons now hold. */
  font: inherit; font-weight: 600; font-size: .92rem;
  min-height: 44px; padding: .6rem 1.15rem;
  background: var(--surface-2); color: var(--text);
  border: 1px solid rgba(255, 255, 255, .38); border-radius: var(--radius, 14px);
  cursor: pointer; text-align: center; flex: 1 1 auto; min-width: 11rem;
}
.consent-btn:hover { border-color: var(--text); }
.footer-consent {
  font: inherit; font-size: inherit; color: inherit;
  background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
  display: inline-flex; align-items: center; min-height: 44px;
}
@media (max-width: 560px) {
  .consent-inner { flex-direction: column; align-items: stretch; }
  .consent-actions { width: 100%; }
}


/* Applicant video disclosure (server/views/careers-form.js, content in
   server/careers.js VIDEO_DISCLOSURE). Deliberately styled as a notice the
   applicant reads, not fine print they scroll past: it sits above the record
   button, at body size, with real contrast. --muted on --surface-2 is 6.76:1. */
.video-disclosure {
  background: var(--surface-2); border: 1px solid rgba(255, 255, 255, .38);
  border-radius: var(--radius); padding: 1rem 1.15rem; margin: 0 0 1.1rem;
}
.video-disclosure-h { font-family: var(--font-display); font-size: 1.05rem; margin: 0 0 .55rem; color: var(--text); }
.video-disclosure-list { margin: 0; padding-left: 1.15rem; color: var(--muted); font-size: .92rem; line-height: 1.6; }
.video-disclosure-list li + li { margin-top: .45rem; }
