/*
Theme Name: Metalworks
Theme URI: https://innovationfortheblind.org/metal-department
Author: Pixel Nomad / AI Decoded (Seb)
Description: Metal Department — capability-first landing for Innovation for the Blind. The "first room" of the future innovationfortheblind.org rebuild. Big-type, monochrome, industrial. Option B build (custom template + metalworks-motion plugin).
Version: 0.8.0
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.0
Text Domain: metalworks
*/

/* ============ DESIGN TOKENS (D-Design-System/00-design-system.md) ============ */
/* Semantic, theme-aware tokens. Dark is the default (:root); light overrides below.
   "Unified surface" model: section backgrounds all resolve to --bg in a given mode —
   structure comes from hairlines (--line), the red accent, and inset panels/fields. */
:root{
  /* legacy palette aliases — kept so existing inline template styles keep resolving */
  --clr-black:#0A0A0A; --clr-white:#FFFFFF;
  --clr-grey-900:#1A1A1A; --clr-grey-500:#8A8A8A; --clr-grey-200:#E5E5E5;
  --clr-ibmd-red:#C2000B;                 /* provisional — pending Karina CI */

  /* brand accents (constant across themes) */
  --accent:#C2000B; --accent-hover:#A3000A;
  /* Eyebrow labels sit in brand red. #C2000B manages only 3.1:1 on the dark
     theme's #0A0A0A, under the 4.5:1 WCAG 2.2 AA floor for --type-label text,
     so dark uses a lightened same-hue red (5.1:1). Light theme keeps #C2000B
     (6.4:1 on white). */
  --accent-label:#FF1A26;
  --clr-navy:#253c61;          /* secondary brand navy (Seb 17 Jul; was #1C2E4A off the live site) */

  /* ---- Theme: DARK (default) ---- */
  --bg:#0A0A0A;          /* page surface */
  --fg:#FFFFFF;          /* primary text */
  --fg-muted:#9A9A9A;    /* secondary text */
  --line:#2A2A2A;        /* hairlines / dividers */
  --field:#141414;       /* form inputs + subtle insets */
  --panel:#1E1E1E;       /* decorative contrast tiles (dark-ish in both themes) */
  --scrim:rgba(10,10,10,.55);
  --verb-dim:.42;        /* verb-stack hover-image brightness (dark theme) */

  --font-display:"Bebas Neue",Impact,sans-serif;
  --font-body:"Archivo",system-ui,sans-serif;   /* body = TBD placeholder */
  /* type scale raised across the board (low-vision readability, 02 Jul) */
  --type-billboard:clamp(4rem,13vw,12.5rem);
  --type-3xl:clamp(3rem,8.5vw,7.5rem);
  --type-2xl:clamp(2.2rem,5vw,3.8rem);
  --type-xl:clamp(1.4rem,2.4vw,2rem);
  --type-label:1rem;
  --type-body:1.2rem;
  --space-lg:3rem; --space-xl:6rem; --space-2xl:9rem; --space-3xl:12rem;
  --ease-out:cubic-bezier(.16,1,.3,1); --dur-reveal:700ms;
}

/* ---- Theme: LIGHT ---- */
[data-theme="light"]{
  --bg:#FFFFFF;
  --accent-label:var(--accent);   /* #C2000B — 6.4:1 on white */
  --fg:#0A0A0A;
  --fg-muted:#6A6A6A;
  --line:#E5E5E5;
  --field:#F4F4F4;
  --panel:#0A0A0A;       /* dark tiles on white — intentional contrast block */
  --verb-dim:.62;        /* lighter overlay on white — avoids the dark-sweep flash */
  /* --scrim stays dark: the hero video is cinematic in both themes */
}

*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--font-body);font-size:var(--type-body);background:var(--bg);color:var(--fg);
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
.display{font-family:var(--font-display);text-transform:uppercase;line-height:.85;letter-spacing:.01em}
.label{font-size:var(--type-label);text-transform:uppercase;letter-spacing:.14em;font-weight:600}
.wrap{max-width:1600px;margin:0 auto;padding:0 var(--space-lg)}
a{color:inherit}

/* Smooth theme transition on the surfaces that flip (instant under reduced-motion, below) */
body,.sec--light,.sec--dark,.site-footer,.pagehead,.marquee,.spec,.faq details,
.matgrid,.matgrid div,.form input,.form textarea,.form select{
  transition:background-color .35s var(--ease-out),border-color .35s var(--ease-out),color .35s var(--ease-out)}

/* NAV */
.nav{position:fixed;top:0;left:0;right:0;z-index:50;display:flex;align-items:center;
  justify-content:space-between;padding:1.1rem var(--space-lg);mix-blend-mode:difference;color:#fff}
.nav__brand{font-family:var(--font-display);font-size:1.4rem;letter-spacing:.04em;text-decoration:none}
.nav__menu{display:flex;gap:2rem;font-size:1.15rem}
.nav__menu a{color:inherit;text-decoration:none}
.nav__menu a:hover{opacity:.6}

/* NAV — mobile: hamburger + full-screen overlay (menu previously vanished ≤760px) */
.nav-burger{display:none;background:none;border:0;color:inherit;cursor:pointer;padding:.3rem;margin-left:1.2rem;line-height:0}
.nav-burger svg{width:22px;height:22px;display:block;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.nav-burger .icon-close{display:none}
.nav.menu-open .nav-burger .icon-open{display:none}
.nav.menu-open .nav-burger .icon-close{display:block}
@media(max-width:760px){
  .nav-burger{display:inline-flex}
  .nav__menu{display:none}
  /* blend-safe: while the overlay is up, the bar drops mix-blend-difference and sits on the surface */
  .nav.menu-open{mix-blend-mode:normal;background:var(--bg);color:var(--fg)}
  .nav.menu-open .nav__menu{display:flex;position:fixed;inset:0;z-index:-1;flex-direction:column;
    justify-content:center;gap:1.8rem;padding:var(--space-lg);background:var(--bg);color:var(--fg)}
  .nav.menu-open .nav__menu a{font-family:var(--font-display);text-transform:uppercase;font-size:var(--type-2xl);line-height:1}
}

/* THEME TOGGLE (lives outside .nav__menu so it stays visible on mobile) */
.theme-toggle{background:none;border:0;color:inherit;cursor:pointer;padding:.3rem;margin-left:1.5rem;
  display:inline-flex;align-items:center;justify-content:center;line-height:0}
.theme-toggle svg{width:20px;height:20px;display:block;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.theme-toggle .icon-moon{display:none}
[data-theme="light"] .theme-toggle .icon-sun{display:none}
[data-theme="light"] .theme-toggle .icon-moon{display:block}
.theme-toggle:focus-visible{outline:2px solid currentColor;outline-offset:3px}

/* ① HERO (cinematic in both themes — video + dark scrim + light title) */
.hero{position:relative;height:100vh;min-height:640px;display:flex;align-items:flex-end;overflow:hidden}
.hero__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.15) brightness(.9);opacity:1;transition:opacity .9s linear}
.hero__video--b{opacity:0}
.hero__scrim{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(10,10,10,.35) 0%,rgba(10,10,10,.15) 40%,rgba(10,10,10,.85) 100%)}
.hero__content{position:relative;z-index:2;width:100%;padding-bottom:var(--space-xl)}
.hero__title{font-size:var(--type-billboard);color:#fff}
.hero__strap{font-size:var(--type-xl);font-weight:500;margin-top:.4rem;max-width:34ch;color:#fff}
.hero__row{display:flex;align-items:center;gap:2rem;flex-wrap:wrap;margin-top:2.2rem}
.hero__proof{display:inline-flex;gap:.6rem;align-items:center;color:#fff;margin-bottom:2.2rem;
  font-size:clamp(1rem,1.6vw,1.45rem)}  /* scales with the title so the stat line never runs wider than "Department" */
.hero__proof .dot{width:10px;height:10px;border-radius:50%;background:var(--accent)}
.scrollcue{position:absolute;left:var(--space-lg);bottom:1.5rem;z-index:2;display:flex;align-items:center;gap:.6rem;opacity:.85;color:#fff}
.scrollcue__line{width:1px;height:34px;background:#fff;transform-origin:top;animation:cue 1.8s var(--ease-out) infinite}
@keyframes cue{0%{transform:scaleY(0)}40%{transform:scaleY(1)}100%{transform:scaleY(0);transform-origin:bottom}}

/* HERO entrance — plays on load. Title lines rise up out of a clip; strap, CTA row
   and scroll-cue fade-rise in sequence. Same gentle vocabulary as the process band. */
.hero__line{display:block;overflow:hidden;padding-block:.12em;margin-block:-.12em}  /* clip mask w/ breathing room so caps aren't shaved */
.hero__line>span{display:block;transform:translateY(115%);animation:heroRise 1.1s var(--ease-out) both}
.hero__line:nth-child(1)>span{animation-delay:.25s}
.hero__line:nth-child(2)>span{animation-delay:.45s}
.hero__proof,.hero__strap,.hero__row,.hero .scrollcue{animation:heroFade 1.1s var(--ease-out) both}
.hero__proof{animation-delay:.1s}
.hero__strap{animation-delay:.85s}
.hero__row{animation-delay:1.15s}
.hero .scrollcue{animation-delay:1.6s}
@keyframes heroRise{from{transform:translateY(115%)}to{transform:translateY(0)}}
@keyframes heroFade{from{opacity:0;transform:translateY(18px);filter:blur(8px)}to{opacity:1;transform:translateY(0);filter:blur(0)}}

/* ── HERO "curtain lift" reveal ───────────────────────────────────────────
   .liftcover (hero + marquee) rides on top (z-index 2) and scrolls up to uncover
   the .procsec pinned behind it (sticky, pulled up under the cover). The runway
   holds the uncovered panel a beat; JS arms the column sequence once it's clear. */
.liftstage{position:relative}
.liftcover{position:relative;z-index:2}
.liftcover__end{display:block;height:1px}              /* sentinel: marks the bottom of the cover for the JS trigger */
.liftstage .procsec{position:sticky;top:0;margin-top:-100vh;z-index:1}
.liftstage .verbsec{position:relative;z-index:3}       /* slides up OVER the pinned process line */
.liftrunway{height:200vh}                              /* runway: columns reveal over the first ~1 screen, then the verb section slides over */
@media(prefers-reduced-motion:reduce){
  /* no curtain on reduced-motion: everything in normal flow, nothing pinned/overlapped */
  .liftstage .procsec{position:static;margin-top:0;z-index:auto}
  .liftstage .verbsec{z-index:auto}
  .liftrunway{display:none}
}

/* BUTTON */
.btn{display:inline-block;background:var(--accent);color:#fff;text-decoration:none;
  padding:1rem 1.8rem;font-size:var(--type-label);text-transform:uppercase;letter-spacing:.12em;
  font-weight:700;transition:transform .2s var(--ease-out),background .2s}
.btn:hover{transform:translateY(-2px);background:var(--accent-hover)}
.btn:focus-visible{outline:3px solid var(--fg);outline-offset:3px}

/* SECTIONS — unified surface: both classes resolve to the same bg/fg per theme */
.sec{padding:var(--space-2xl) 0;min-height:100vh;display:flex;flex-direction:column;justify-content:center}
.sec--auto{min-height:0;display:block}              /* exception: proof gallery breathes at natural height */
.sec--light{background:var(--bg);color:var(--fg)}
.sec--dark{background:var(--bg);color:var(--fg)}
.eyebrow{color:var(--accent-label);margin-bottom:1.4rem}

/* ② PROCESS — "how we work": numbered steps + descriptors */
.process{list-style:none;display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-lg);margin-top:var(--space-xl)}
.process__step{display:flex;flex-direction:column;gap:1rem}
/* number row: "01" then a hairline that reaches toward the next step, tipped with an arrowhead */
.process__num{display:flex;align-items:center;gap:1rem;color:var(--fg-muted);font-size:var(--type-xl)}
.process__line{flex:1;height:2px;background:currentColor;opacity:.3;position:relative}
.process__line::after{content:"";position:absolute;right:0;top:50%;transform:translateY(-50%);
  border:6px solid transparent;border-left:8px solid currentColor}
.process__step:last-child .process__line{display:none}   /* no connector off the final step */
.process__name{font-size:var(--type-3xl)}
.process__desc{color:var(--fg);font-size:var(--type-xl);max-width:26ch}
/* supporting paragraph — raised to the xl step for low-vision readability */
.process__body{color:var(--fg-muted);font-size:var(--type-xl);line-height:1.5;max-width:34ch;margin-top:.2rem}
/* ── scroll-driven column reveal ──────────────────────────────────────
   As the user scrolls through the pinned panel, JS adds .is-in to each column
   in turn (paced by scroll, so none are skipped). Within a column the lines
   de-blur top-to-bottom, then the connector draws toward the next column. */
/* base: each line hidden + blurred, transitions ready. JS adds .is-in to a step when the
   user scrolls it into the pinned reveal zone (so columns are never skipped at scroll speed). */
.process__num,.process__name,.process__desc,.process__body{
  opacity:0;filter:blur(12px);transform:translateY(14px);
  transition:opacity .9s var(--ease-out),filter .9s var(--ease-out),transform .9s var(--ease-out)}
.process__line{clip-path:inset(0 100% 0 0);transition:clip-path .9s var(--ease-out)}   /* connector hidden until it draws L→R */

/* within a revealed column: lines de-blur top-to-bottom, then the connector draws */
.process__step.is-in .process__num {opacity:1;filter:none;transform:none;transition-delay:0s}
.process__step.is-in .process__name{opacity:1;filter:none;transform:none;transition-delay:.18s}
.process__step.is-in .process__desc{opacity:1;filter:none;transform:none;transition-delay:.36s}
.process__step.is-in .process__body{opacity:1;filter:none;transform:none;transition-delay:.54s}
.process__step.is-in .process__line{clip-path:inset(0 0 0 0);transition-delay:.9s}
@media(max-width:760px){
  .process{grid-template-columns:1fr;gap:var(--space-lg)}
  .process__line{display:none}
}

/* ② BACKDROP — drifting technical drawings behind the process band */
.procsec{position:relative;overflow:hidden}
.procsec>.wrap{position:relative;z-index:2}              /* text sits above the drawings */
.proc-bg{position:absolute;inset:0;z-index:0;pointer-events:none}
.proc-bg__item{position:absolute;background-repeat:no-repeat;background-size:contain;
  background-position:center;opacity:.16;will-change:transform}
/* WHITE drawings by default (dark theme) */
.proc-bg .d1{background-image:url('img/drawings/d1w.png')}
.proc-bg .d2{background-image:url('img/drawings/d2w.png')}
.proc-bg .d3{background-image:url('img/drawings/d3w.png')}
.proc-bg .d4{background-image:url('img/drawings/d4w.png')}
.proc-bg .d5{background-image:url('img/drawings/d5w.png')}
/* BLACK drawings on the light theme — stronger; black-on-white reads fainter than white-on-black */
[data-theme="light"] .proc-bg__item{opacity:.26}
[data-theme="light"] .proc-bg .d5{opacity:.14}   /* keep the centre one restrained behind the text */
[data-theme="light"] .proc-bg .d1{background-image:url('img/drawings/d1.png')}
[data-theme="light"] .proc-bg .d2{background-image:url('img/drawings/d2.png')}
[data-theme="light"] .proc-bg .d3{background-image:url('img/drawings/d3.png')}
[data-theme="light"] .proc-bg .d4{background-image:url('img/drawings/d4.png')}
[data-theme="light"] .proc-bg .d5{background-image:url('img/drawings/d5.png')}
/* placement + size (aspect-ratio matches each source file) + individual drift loops */
.proc-bg .d1{top:7%;left:7%;width:8vw;aspect-ratio:312/443;animation:driftA 32s ease-in-out infinite}
.proc-bg .d2{top:11%;right:6%;width:15vw;aspect-ratio:536/320;animation:driftB 44s ease-in-out -6s infinite}
.proc-bg .d3{bottom:5%;left:5%;width:11vw;aspect-ratio:484/629;animation:driftC 38s ease-in-out -14s infinite}
.proc-bg .d4{bottom:9%;right:11%;width:9vw;aspect-ratio:380/373;animation:driftA 46s ease-in-out infinite reverse}
.proc-bg .d5{top:54%;left:49%;width:7vw;aspect-ratio:321/403;opacity:.09;animation:driftB 28s ease-in-out -10s infinite}
@keyframes driftA{0%,100%{transform:translate(0,0) rotate(0)}50%{transform:translate(3.4vw,-3.6vh) rotate(7deg)}}
@keyframes driftB{0%,100%{transform:translate(0,0) rotate(0)}50%{transform:translate(-4vw,3.4vh) rotate(-8deg)}}
@keyframes driftC{0%,100%{transform:translate(0,0) rotate(0)}50%{transform:translate(2.8vw,4vh) rotate(6deg)}}
@media(max-width:760px){
  .proc-bg .d2,.proc-bg .d5{display:none}
  .proc-bg__item{opacity:.1}
  .proc-bg .d1{width:24vw}.proc-bg .d3{width:30vw}.proc-bg .d4{width:26vw}
}

/* ③ VERBS — hovering a verb fades a process image in behind the list */
.verbsec{position:relative;overflow:hidden}
.verbsec__bg{position:absolute;inset:0;z-index:0;pointer-events:none}
.verbsec__bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;filter:grayscale(1) contrast(1.05) brightness(var(--verb-dim));transition:opacity .4s var(--ease-out)}
.verbsec__bg img.verbsec__bg-base{opacity:1}   /* always-on default image — the section's resting state */
.verbsec .wrap{position:relative;z-index:2}
/* the section always sits on a photo, so text stays light + shadowed in both themes */
.verbsec .eyebrow{color:#fff}   /* photo backdrop — red cannot hold 4.5:1 over it */
.verbs{display:flex;flex-direction:column;gap:.2rem}
.verbs span{font-size:var(--type-billboard);line-height:.92;color:#fff;text-shadow:0 2px 26px rgba(0,0,0,.5);
  transition:padding-left .3s var(--ease-out),color .3s;cursor:default}
.verbs span:hover{padding-left:1.5rem;color:var(--accent)}

/* ⑤ METRICS */
.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-lg)}
/* QC metrics (Capabilities, 20 Aug): 2x2 rather than 4-across. At 4-up the widest
   metric ("100%", 1.829em) already filled its column at --type-3xl, so there was no
   headroom to grow. Halving the column count roughly doubles the available width. */
.metrics--4{grid-template-columns:repeat(2,1fr);gap:var(--space-xl) var(--space-lg)}
.metrics--4 .metric__num{font-size:clamp(4.5rem,13vw,15rem)}
.metrics--4 .metric__lbl{font-size:var(--type-xl);margin-top:1rem}
/* Content-sized columns with one even gap (equal 1fr tracks read as uneven gaps) */
.metrics--flush{grid-template-columns:repeat(3,max-content);column-gap:var(--space-2xl)}
@media(max-width:1100px){.metrics--flush{column-gap:var(--space-lg)}}
@media(max-width:760px){.metrics--flush{grid-template-columns:1fr}}
.metric__num{font-size:var(--type-3xl);line-height:1}
.metric__num em{color:var(--accent);font-style:normal}
.metric__lbl{color:var(--fg-muted);margin-top:.6rem}
@media(max-width:760px){.metrics,.metrics--4{grid-template-columns:1fr}}

/* ④ GALLERY — pinwheel: offset row seams (7:3:7) so all four images hug the centre;
   stacks balance exactly: 7-col 16:10 + 5-col 4:5 = same total height either side */
.gallery{display:grid;grid-template-columns:repeat(12,1fr);grid-template-rows:7fr 3fr 7fr;gap:1.2rem;aspect-ratio:96/85}
.gallery figure{overflow:hidden;background:var(--field);position:relative}
/* vignette — soft darkened edges over every proof image (sits above the img, under nothing clickable) */
.gallery figure::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse at center,transparent 52%,rgba(0,0,0,.18) 74%,rgba(0,0,0,.5) 100%)}
.gallery img{width:100%;height:100%;object-fit:cover;filter:grayscale(1) contrast(1.1);transition:transform .6s var(--ease-out),filter .35s;display:block}
.gallery figure:hover img,.gallery figure:focus-within img{transform:scale(1.04);filter:grayscale(0) contrast(1.05)}
.gallery .g1{grid-area:1/1/2/8}
.gallery .g2{grid-area:1/8/3/13}
.gallery .g3{grid-area:2/1/4/6}
.gallery .g4{grid-area:3/6/4/13}
.gallery figcaption{font-size:var(--type-label);color:var(--fg-muted);margin-top:.5rem;text-transform:uppercase;letter-spacing:.08em}
@media(max-width:760px){
  .gallery{grid-template-rows:none;aspect-ratio:auto}
  .gallery>*{grid-area:auto;grid-column:1/-1}
  .gallery .g1,.gallery .g4{aspect-ratio:16/10}
  .gallery .g2,.gallery .g3{aspect-ratio:4/5}
}

/* ⑥ MARQUEE */
.marquee{overflow:hidden;background:var(--clr-navy);color:#fff;padding:1.4rem 0;white-space:nowrap}
.marquee__track{display:inline-block;animation:scroll 28s linear infinite}
.marquee span{font-family:var(--font-display);font-size:var(--type-3xl);margin:0 1.8rem;letter-spacing:.03em}
.marquee .dot{color:var(--accent)}
@keyframes scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ⑥b FILM — embedded produced film (poster + controls, EN/AF caption tracks) */
.film{width:100%;margin-top:var(--space-lg)}
.film video{width:100%;display:block;background:#000;aspect-ratio:16/9}
.film figcaption{font-size:var(--type-label);color:var(--fg-muted);margin-top:.7rem;
  text-transform:uppercase;letter-spacing:.08em}

/* ⑦b STORIES — three human profiles ("dignity in action") */
.pull{font-family:var(--font-display);text-transform:uppercase;line-height:.95;
  font-size:var(--type-2xl);max-width:26ch;border:0;margin:0 0 var(--space-lg)}
.pull em{color:var(--accent);font-style:normal}
.stories{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:1.2rem}   /* adapts to card count: 2 now, 3 again when the Skea story lands (319) */
.story{background:var(--field);margin:0}
.story img{width:100%;aspect-ratio:4/5;object-fit:cover;display:block;
  filter:grayscale(1) contrast(1.08);transition:filter .6s}
.story:hover img{filter:grayscale(0) contrast(1.02)}
.story figcaption{padding:1.6rem}
.story__name{font-size:var(--type-2xl)}
.story__role{color:var(--accent);margin-top:.3rem}
.story figcaption p{color:var(--fg-muted);margin-top:.8rem;line-height:1.6;font-size:var(--type-body)}
/* Full case-study text folded into the card (client copy, tracker 2.17) */
.story__more{margin-top:1rem}
.story__more summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:.6rem;color:var(--accent);font-weight:600;font-size:var(--type-body)}
.story__more summary::-webkit-details-marker{display:none}
.story__more summary::after{content:"+";flex-shrink:0;font-size:1.3rem;line-height:1}
.story__more[open] summary::after{content:"\2013"}
.story__quote{font-style:italic;color:var(--fg);border-left:3px solid var(--accent);padding-left:.8rem}
@media(max-width:760px){.stories{grid-template-columns:1fr}}

/* ⑦c IMPACT AT A GLANCE — client copy list under the metrics row (Partner page) */
.impactlist{list-style:none;padding:0;margin:0;max-width:64ch}
.impactlist li{padding:.9rem 0;border-bottom:1px solid var(--line);color:var(--fg-muted);font-size:var(--type-xl);line-height:1.5;transition:color .25s}
.impactlist li:hover{color:var(--accent)}
.impactlist li:last-child{border-bottom:0}

/* IMAGE BAND — full-width contextual photo between sections (inner pages) */
.imgband{width:100%;overflow:hidden;margin:0}
.imgband img{width:100%;height:64vh;min-height:340px;object-fit:cover;display:block;
  filter:grayscale(1) contrast(1.08);transition:filter .6s}
.imgband:hover img{filter:grayscale(0) contrast(1.02)}   /* same colour-on-hover as the story cards */
/* Cross-reveal band: a second photo fades in over the base on hover, full colour */
.imgband--swap{position:relative}
.imgband--swap .imgband__hover{position:absolute;top:0;left:0;opacity:0;filter:none;transition:opacity .6s}   /* keeps the base img's 64vh sizing; absolute so it stacks over it, not the caption */
.imgband--swap:hover .imgband__hover{opacity:1}
/* Sticky band: a near-viewport window that clips a viewport-fixed photo, so the page
   scrolls over the pinned image (background-attachment:fixed effect, mobile-safe).
   clip-path on the frame clips the fixed imgs to the window; both layers of a --swap
   band pin identically so the hover cross-reveal stays registered. */
.imgband__frame{position:relative;overflow:hidden}
.imgband--sticky .imgband__frame{height:92vh;min-height:340px;clip-path:inset(0)}
.imgband--sticky .imgband__frame img{position:fixed;top:0;left:0;width:100%;height:100vh}
/* A transformed/filtered ancestor would become the fixed imgs' containing block and
   re-anchor them mid-scroll (the .reveal slide-in did exactly that) — never combine. */
.imgband--sticky{transform:none!important;filter:none!important}
.imgband figcaption{font-size:var(--type-label);color:var(--fg-muted);padding:.7rem var(--space-lg) 0;
  text-transform:uppercase;letter-spacing:.08em;max-width:1600px;margin:0 auto}
/* Group-photo band: keep the photo's own 16:9 (no crop on most screens) instead of the
   fixed 64vh window, which decapitates the group on wide monitors. If max-height does
   trim (short/wide viewports), the slight top bias sheds floor before it sheds hands. */
.imgband--headroom img{height:auto;aspect-ratio:16/9;max-height:88vh;object-position:50% 18%}

/* ⑧ FAQ */
.faq details{border-bottom:1px solid var(--line);padding:1.4rem 0}
.faq summary{font-size:var(--type-2xl);cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:1rem;font-weight:600;line-height:1.15}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--accent);font-size:2.4rem;line-height:1;flex-shrink:0}
.faq details[open] summary::after{content:"–"}
.faq p{margin-top:1rem;color:var(--fg-muted);font-size:var(--type-xl);line-height:1.5;max-width:60ch}

/* ⑨ CLOSE + BOOKEND */
.cta-close{text-align:center;padding:var(--space-2xl) 0 var(--space-lg)}
.cta-close h2{font-size:var(--type-3xl);margin-bottom:1.6rem}
.bookend{font-size:var(--type-billboard);text-align:center;line-height:.82;color:var(--clr-navy);padding:var(--space-lg) 0 0;white-space:nowrap;overflow:hidden}

/* SITE FOOTER (shared across all 4 pages) */
.site-footer{background:var(--bg);color:var(--fg-muted)}
.footmeta{display:grid;grid-template-columns:repeat(3,1fr);gap:2rem;padding:var(--space-lg) 0;color:var(--fg-muted);font-size:var(--type-label)}
.footmeta__col{display:flex;flex-direction:column;gap:.5rem}
.footmeta__col a{text-decoration:none;transition:color .2s}
.footmeta__col a:hover{color:var(--fg)}
.footmeta__h{color:var(--fg);margin-bottom:.4rem}
.footmeta__col--legal{align-items:flex-end;text-align:right}
@media(max-width:760px){.footmeta{grid-template-columns:1fr}.footmeta__col--legal{align-items:flex-start;text-align:left}}

/* REVEAL */
.reveal{opacity:0;transform:translateY(28px);transition:opacity var(--dur-reveal) var(--ease-out),transform var(--dur-reveal) var(--ease-out)}
.reveal.in{opacity:1;transform:none}

/* ============ INNER PAGE HELPERS (pages 2–4) ============ */
.pagehead{min-height:78vh;display:flex;flex-direction:column;justify-content:flex-end;
  padding:var(--space-3xl) 0 var(--space-xl);background:var(--bg);color:var(--fg)}
.pagehead__title{font-size:var(--type-billboard)}
.pagehead__title em{color:var(--accent);font-style:normal}
.pagehead__intro{font-size:var(--type-xl);max-width:48ch;margin-top:1.2rem;color:var(--fg-muted)}
/* Eyebrows are red on solid --bg sections, but the photo pageheads put them over
   grayscale imagery that runs from near-black to near-white, where no single red
   holds 4.5:1. Those stay white. */
.pagehead--photo .eyebrow{color:var(--accent-label)}

/* Contact pagehead: the locality map is its own band at the top, with a short fade only at
   its foot; the copy stacks directly beneath it rather than sitting over the map. That keeps
   the IftB marker clear and lets the heading sit on plain page background, so it needs no
   colour overrides and reads at full contrast in both themes. The fade resolves to --bg,
   which is #FFFFFF on light and #0A0A0A on dark. */
.pagehead--map{--map-h:clamp(240px,38vh,440px);
  position:relative;overflow:hidden;justify-content:flex-start;padding-top:0}
.pagehead--map .pagehead__bg,
.pagehead--map .pagehead__fade{position:absolute;top:0;left:0;width:100%;height:var(--map-h)}
/* Two map renders, one per theme. Swapped via background-image rather than a pair of
   <img> tags so only the active one is ever fetched. Bare :root is the dark default. */
.pagehead--map .pagehead__bg{background:url(img/contact-map-dark.jpg) 50% 38%/cover no-repeat}
:root[data-theme="light"] .pagehead--map .pagehead__bg{background-image:url(img/contact-map-light.jpg)}
/* fade confined to the bottom 30% of the band */
.pagehead--map .pagehead__fade{background:linear-gradient(to bottom,
  rgba(0,0,0,0) 0%, rgba(0,0,0,0) 60%, var(--bg) 88%)}
/* copy starts where the fade has resolved to --bg (88%), not at the band foot,
   so it sits tight under the map instead of being pushed a full band down */
.pagehead--map>.wrap{position:relative;z-index:2;margin-top:calc(var(--map-h) * .88)}
@media(max-width:760px){.pagehead--map{--map-h:clamp(190px,28vh,280px)}}
/* Photo pagehead (Capabilities): parts still behind the title, grayscaled like all site
   imagery, dark scrim keeps the billboard type readable in both themes */
.pagehead--photo{position:relative;overflow:hidden;color:#fff;min-height:100vh;min-height:100svh;justify-content:center}
.pagehead--photo .pagehead__bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 90%;filter:grayscale(1) contrast(1.05)}
/* Bottom-up scrim: shades the intro zone below centre, fades out before the title */
/* Vision pagehead (Partner With Purpose): the resting photo is grayscale AND blurred —
   the spotlight cuts through to the sharp colour twin. Blindness vs normal vision. */
.pagehead--vision .pagehead__bg{filter:grayscale(1) contrast(1.05) blur(8px)}
/* Radial colour reveal — the colour twin sits over the grayscale bg, masked to a soft
   spotlight that follows the cursor (motion.js sets --mx/--my and .is-lit). */
.pagehead--photo .pagehead__bg--colour{filter:none;opacity:0;transition:opacity .4s;
  -webkit-mask-image:radial-gradient(circle 260px at var(--mx,50%) var(--my,50%),#000 0 55%,transparent 100%);
  mask-image:radial-gradient(circle 260px at var(--mx,50%) var(--my,50%),#000 0 55%,transparent 100%)}
.pagehead--photo.is-lit .pagehead__bg--colour{opacity:1}
/* vignette added 20 Aug — same stops as the proof-gallery .vignette so edges read the same
   across the site. Tonal gradient below is the original. */
.pagehead--photo .pagehead__scrim{position:absolute;inset:0;background:
  radial-gradient(ellipse at center,transparent 52%,rgba(0,0,0,.18) 74%,rgba(0,0,0,.5) 100%),
  linear-gradient(0deg,rgba(0,0,0,.55) 0%,rgba(0,0,0,.32) 28%,rgba(0,0,0,0) 52%)}
/* Capabilities hero: the vignette follows the theme — black on dark, white on light — so the
   hero edges dissolve into the page either way. Scoped to this hero only; Partner With Purpose
   keeps the plain black vignette. */
.pagehead--vignette-theme{--vig-mid:rgba(0,0,0,.18);--vig-edge:rgba(0,0,0,.5)}
:root[data-theme="light"] .pagehead--vignette-theme{--vig-mid:rgba(255,255,255,.38);--vig-edge:rgba(255,255,255,.78)}
.pagehead--vignette-theme .pagehead__scrim{background:
  radial-gradient(ellipse at center,transparent 52%,var(--vig-mid) 74%,var(--vig-edge) 100%),
  linear-gradient(0deg,rgba(0,0,0,.55) 0%,rgba(0,0,0,.32) 28%,rgba(0,0,0,0) 52%)}
.pagehead--photo .wrap{position:relative;z-index:2}
.pagehead--photo .pagehead__title{color:#fff}   /* 20 Aug: was --clr-navy; white reads far better over the grayscale photo */
.pagehead--photo .pagehead__intro{color:#d6d6d6}

/* spec rows (Capabilities) */
.specs{display:flex;flex-direction:column;width:100%}
.spec{display:grid;grid-template-columns:1fr 2fr;gap:2rem;padding:2rem 0;border-top:1px solid var(--line);align-items:baseline}
.spec:last-child{border-bottom:1px solid var(--line)}
.spec__name{font-size:var(--type-2xl);transition:color .25s var(--ease-out)}
.spec:hover .spec__name{color:var(--accent)}   /* red-on-hover accent (22 Jun 26:39) */
.spec__detail{color:var(--fg-muted);font-size:var(--type-xl)}
@media(max-width:760px){.spec{grid-template-columns:1fr;gap:.5rem}}

/* testimonials — "What our clients say about us" (⑤c) */
.quotes{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-lg);width:100%}
.quote{border-top:1px solid var(--line);padding-top:2rem;margin:0;display:flex;flex-direction:column;height:100%}
.quote figcaption{margin-top:auto}   /* attributions sit on a common baseline per row */
.quote blockquote{margin:0;font-size:var(--type-xl);line-height:1.35;max-width:38ch}
.quote blockquote::before{content:"\201C";color:var(--accent)}
.quote blockquote::after{content:"\201D";color:var(--accent)}
.quote figcaption{padding-top:1.6rem;display:flex;flex-direction:column;gap:.35rem}
.quote__name{font-size:var(--type-xl)}
.quote__role{color:var(--fg-muted);font-size:var(--type-label);text-transform:uppercase;letter-spacing:.08em}
@media(max-width:760px){.quotes{grid-template-columns:1fr}}
.quotes--minor{grid-template-columns:repeat(3,1fr);margin-top:var(--space-lg)}
.quotes--minor blockquote{font-size:var(--type-body);max-width:none;color:var(--fg-muted)}
.quotes--minor figcaption{padding-top:1.1rem}
.repeat{margin-top:var(--space-xl);border-top:1px solid var(--line);padding-top:2rem;max-width:56ch}
.repeat__h{font-size:var(--type-xl);margin-bottom:1.2rem}
.repeat p+p{margin-top:.9rem}
.repeat p:not(.repeat__h){color:var(--fg-muted);font-size:var(--type-body);line-height:1.45}
@media(max-width:760px){.quotes--minor{grid-template-columns:1fr}}

/* materials grid */
.matgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line);width:100%}
.matgrid div{background:var(--bg);padding:2.4rem 1.6rem}
.matgrid .display{font-size:var(--type-2xl)}
.matgrid small{display:block;color:var(--fg-muted);margin-top:.4rem;text-transform:uppercase;letter-spacing:.08em;font-size:var(--type-label)}
@media(max-width:760px){.matgrid{grid-template-columns:1fr 1fr}}

/* contact tiles (--panel is dark-ish in both themes → text stays light) */
.contact{display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem;width:100%}
.contact a{background:var(--panel);color:#fff;padding:2.4rem;text-decoration:none;display:flex;flex-direction:column;gap:.5rem;transition:background .2s}
.contact a:hover{background:var(--accent)}
.contact .k{font-size:var(--type-label);text-transform:uppercase;letter-spacing:.12em;color:rgba(255,255,255,.55)}
.contact a:hover .k{color:#fff}
.contact .v{font-size:var(--type-xl);font-weight:600}
@media(max-width:760px){.contact{grid-template-columns:1fr}}

/* quote form */
.form{display:grid;grid-template-columns:1fr 1fr;gap:1.2rem;max-width:780px;width:100%}
.form label{display:flex;flex-direction:column;gap:.4rem;font-size:var(--type-label);text-transform:uppercase;letter-spacing:.1em;color:var(--fg-muted)}
.form .full{grid-column:1/-1}
.form input,.form textarea,.form select{padding:.9rem 1rem;border:1px solid var(--line);font-family:inherit;font-size:var(--type-body);background:var(--field);color:var(--fg)}
.form input:focus,.form textarea:focus,.form select:focus{outline:2px solid var(--accent);outline-offset:1px}
@media(max-width:760px){.form{grid-template-columns:1fr}}

/* big statement block */
.statement{font-size:var(--type-3xl);max-width:18ch}
.statement em{color:var(--accent);font-style:normal}
.statement__sub{font-size:var(--type-xl);max-width:46ch;margin-top:1.4rem;line-height:1.35}

@media(prefers-reduced-motion:reduce){
  *,.scrollcue__line,.marquee__track{animation:none!important;transition:none!important}
  .reveal{opacity:1;transform:none}
  /* orchestrated process items default to hidden — force them visible + sharp when motion is off */
  .process__num,.process__name,.process__desc,.process__body{opacity:1;filter:none;transform:none}
  .process__line{clip-path:none}
  /* hero entrance defaults to hidden/translated — force it home when motion is off */
  .hero__line>span{transform:none}
  .hero__proof,.hero__strap,.hero__row,.hero .scrollcue{opacity:1;filter:none;transform:none}
}

/* ---- ibmd-metal-pages additions ---- */
.form .hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-status{margin-top:1rem;font-size:var(--type-label);color:var(--fg)}
.form-status--error,.form-status--missing{color:var(--clr-ibmd-red)}
.nav__menu .nav__back{padding-left:2rem;border-left:1px solid currentColor;opacity:.7}
.nav__menu .nav__back:hover{opacity:1}
@media (max-width:760px){.nav.menu-open .nav__menu .nav__back{padding-left:0;border-left:0;font-size:var(--type-xl);margin-top:1.5rem}}
