/* =========================================================================
   Rogue Contractors and Consulting LLC — demo site
   Design target: the working implementation Kevin supplied
   (facts.json → comp_supplied_by_saxon.design_reference.artifact_html).
   Tokens, type system, spacing and structural devices follow it.

   Deliberate departures from the artifact, all for accessibility or policy:
   - Fonts are self-hosted woff2 subsets, not Google Fonts (no external requests).
   - Inter is replaced by a system sans stack to keep the font budget at 3 files.
   - Red TEXT uses --color-accent (#ef4b52, 5.43:1 on the page ground) rather than
     --color-primary (#c21f2c, 3.35:1, which fails AA at the artifact's 0.8rem).
     --color-primary is still used for fills, rules and borders, where it passes.
   - The artifact's --gray-dim (#6d6d70) is 3.87:1 and is not used for any text.
   ========================================================================= */

:root {
  /* --- mandated token contract (precheck parses these) ------------------ */
  --color-bg: #0b0b0c;          /* artifact --black */
  --color-surface: #151517;     /* artifact --charcoal — 15.15:1 with text */
  --color-text: #f2f1ee;        /* 16.96:1 on bg */
  --color-muted: #9a9a9c;       /* 6.92:1 on bg, 6.18:1 on surface */
  --color-primary: #c21f2c;     /* artifact --red — fills, rules, borders */
  --color-on-primary: #ffffff;  /* 5.88:1 on primary */

  /* --- supporting values ------------------------------------------------ */
  --panel: #1c1c1f;
  --line: rgba(255, 255, 255, 0.09);
  --color-accent: #ef4b52;      /* red for TEXT on dark: 5.43:1 on bg */
  --red-dim: #8f1620;

  --font-display: "Anton", "Haettenschweiler", "Arial Narrow Bold", Impact, sans-serif;
  --font-cond: "Barlow Condensed", "Arial Narrow", "Roboto Condensed", sans-serif;
  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
}

/* --- self-hosted faces. No runtime external request is made. -------------
   Anton (SIL OFL 1.1) 18.6KB · Barlow Condensed 600/700 (SIL OFL 1.1)
   22.3KB + 22.4KB. Latin subsets. 63.4KB total for the whole site.        */
@font-face {
  font-family: "Anton";
  font-style: normal; font-weight: 400; font-display: swap;
  src: url("assets/fonts/anton-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal; font-weight: 600; font-display: swap;
  src: url("assets/fonts/barlow-condensed-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal; font-weight: 700; font-display: swap;
  src: url("assets/fonts/barlow-condensed-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* =========================== reset ====================================== */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; }
ul { list-style: none; }
h1, h2, h3, h4 { font-weight: 400; }

:focus-visible { outline: 3px solid #ff8a8f; outline-offset: 3px; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--color-text); color: var(--color-bg);
  padding: 0.85rem 1.25rem; font-weight: 700;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.vh {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* =========================== primitives ================================= */
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 clamp(20px, 4vw, 48px); }

.display {
  font-family: var(--font-display);
  letter-spacing: 0.5px;
  line-height: 0.98;
  text-transform: uppercase;
  overflow-wrap: break-word;
}

/* the artifact's eyebrow device */
.tag {
  font-family: var(--font-cond);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  font-size: 0.8rem;
}
.tag--muted { color: var(--color-muted); }

section { padding: clamp(56px, 8vw, 96px) 0; }
.section-alt { background: var(--color-surface); }

.kicker { max-width: 640px; }
.kicker .tag { margin-bottom: 12px; display: block; }
.kicker h2 { font-size: clamp(1.9rem, 3.6vw, 2.7rem); }
.lede { color: var(--color-muted); max-width: 600px; margin-top: 18px; line-height: 1.65; font-size: 1.02rem; }
.lede--light { color: var(--color-text); }

/* =========================== buttons ==================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--color-primary); color: var(--color-on-primary);
  font-family: var(--font-cond);
  font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  font-size: 0.92rem;
  min-height: 48px;
  padding: 14px 26px;
  border: 1px solid var(--color-primary);
  border-radius: 0;
  cursor: pointer; text-decoration: none;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.btn:hover { background: #a11723; border-color: #a11723; }
.btn svg { width: 15px; height: 15px; flex: none; }

/* the artifact's ghost button: transparent, hairline rule, white label */
.btn-outline {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.35);
  color: var(--color-text);
}
.btn-outline:hover { background: rgba(255, 255, 255, 0.08); border-color: var(--color-text); }

/* near-black button used on the red band */
.btn-dark { background: var(--color-bg); border-color: var(--color-bg); color: var(--color-text); }
.btn-dark:hover { background: #000; border-color: #000; }

/* Red is never the only signal for a link — the underline is always present. */
.more {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 44px;
  font-family: var(--font-cond);
  font-weight: 700; font-size: 0.78rem; letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px;
}
.more:hover { color: #ff8a8f; text-decoration-thickness: 2px; }
.more svg { width: 13px; height: 13px; }

/* =========================== header ===================================== */
/* Artifact header chrome (sticky, 0.92 ground, blur, 1180 wrap) carrying the
   oversized STACKED wolf lockup the comp shows bleeding below the bar.
   rogue-logo.jpg is 200x200 native and is never rendered larger than that. */
header.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(11, 11, 12, 0.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line);
  overflow: visible;
}
/* Once compacted, the header sits over bright hero photography. At 0.92 the
   photo glows through and the wolf mark's baked near-black square reads a
   shade darker than its surroundings (measured up to 1.14:1). A solid ground
   removes that seam; at 92% already, the visual change is negligible. */
header.site-header.is-scrolled {
  background: rgb(11, 11, 12);
  backdrop-filter: none;
}
/* --header-h is kept in sync with the sticky header's real height by main.js
   (it changes as the wolf mark compacts on scroll), so anchor targets never
   land underneath it. 96px is only the pre-JS fallback. */
:root { --header-h: 96px; }
#home, #what-we-do, #audiences, #contact, #main { scroll-margin-top: var(--header-h); }
.nav-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  max-width: 1180px; margin: 0 auto;
  padding: 12px clamp(20px, 4vw, 48px);
}

/* Wolf mark only — no text wordmark beside it. rogue-logo.jpg already carries
   "ROGUE CONTRACTORS AND CONSULTING" baked into the artwork. 200px at the top
   of the page (its native size — never rendered larger), compacting to 72px
   once the page is scrolled: main.js toggles .is-scrolled on header.site-header
   and keeps --header-h in sync so in-page anchors never land underneath it.
   The logo's baked near-black ground matches the header's own near-black
   background, so no square shows in either state. */
.brand { display: flex; align-items: center; flex: none; text-decoration: none; }
.brand-logo {
  display: block; width: 200px; height: 200px; object-fit: contain;
  transition: width 0.25s ease, height 0.25s ease;
}
@media (prefers-reduced-motion: reduce) { .brand-logo { transition: none; } }
header.site-header.is-scrolled .brand-logo { width: 72px; height: 72px; }

.navlinks { display: flex; align-items: center; gap: clamp(16px, 2.4vw, 34px); margin-left: auto; }
.navlinks a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-cond); font-weight: 600; font-size: 0.86rem;
  letter-spacing: 0.05em;
  color: var(--color-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.navlinks a:hover { color: var(--color-text); border-bottom-color: var(--color-primary); }
.navlinks a[aria-current="page"] { color: var(--color-text); border-bottom-color: var(--color-primary); }

.nav-cta { flex: none; }
.nav-cta .btn { min-height: 44px; padding: 10px 20px; font-size: 0.86rem; }

.burger {
  display: none; align-items: center; justify-content: center;
  width: 46px; height: 46px;
  background: none; border: 1px solid var(--line); color: var(--color-text); cursor: pointer;
}
.burger svg { width: 22px; height: 22px; }
.burger .ic-close { display: none; }
.burger[aria-expanded="true"] .ic-close { display: block; }
.burger[aria-expanded="true"] .ic-open { display: none; }

@media (max-width: 940px) {
  /* flex: none holds the burger at its full 46px; it used to be the only thing
     in the bar that could shrink (43.4px wide at 390px, 24px at 360px and below). */
  .burger { display: inline-flex; flex: none; }
  /* The wolf mark takes whatever room is left beside the CTA and burger (both
     flex: none), up to its native 200px: ~125px at 320, ~195px at 390, the full
     200px from ~415. Sized from the flex item, not 100vw, so a desktop scrollbar
     can never push it past the space it actually has. Compacts to 48px once
     scrolled; no resize transition here, so reduced motion needs no override. */
  .brand { flex: 0 1 200px; min-width: 48px; }
  .brand-logo { width: 100%; height: auto; transition: none; }
  header.site-header.is-scrolled .brand { flex-basis: 48px; }
  header.site-header.is-scrolled .brand-logo { width: 100%; height: auto; }
  .navlinks {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    margin-left: 0;
    background: var(--color-bg);
    border-bottom: 3px solid var(--color-primary);
    padding: 4px clamp(20px, 4vw, 48px) 16px;
    display: none;
  }
  .navlinks[data-open="true"] { display: flex; }
  .navlinks a { min-height: 52px; border-bottom: 1px solid var(--line); }
  .nav-cta { margin-left: auto; }
  .nav-cta .btn { padding: 10px 14px; font-size: 0.8rem; }
}
/* 400px and below. The bar's contents (lockup 178 + Let's talk 88.6 + burger 46
   + two 20px gaps + 20px padding each side) came to 392.6px, so narrower screens
   squeezed the burger and, from 350px down, pushed it past the viewport edge.
   Tighter gaps and padding here; with the burger held at 46px and the lockup
   allowed to compress, the bar fits at 320px. Nothing is hidden. */
@media (max-width: 400px) {
  .nav-bar { gap: 12px; }
  .nav-cta .btn { padding: 10px 12px; }
}

/* =========================== hero ======================================= */
.hero {
  position: relative;
  min-height: 88vh;
  display: flex; align-items: center;
  background: var(--color-bg);
  overflow: hidden;
}
.hero-photo {
  position: absolute; top: 0; right: 0; bottom: 0; width: 48%;
  background-size: cover; background-position: center 40%;
  /* Short feather only — just enough to kill the hard vertical seam where the
     column begins. It used to run to 44%, which blanked roughly the left fifth
     of the viewport's worth of photograph BEFORE the scrim had even been
     applied, darkening the same pixels twice. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 12%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 12%);
}
/* Stops are in PX, not %, deliberately. The copy column is a fixed max-width
   inside a centred 1180px wrap, so the x where glyphs stop is roughly constant
   in pixels but swings wildly as a percentage — 42% of the viewport at 1440px,
   about 70% at 960px. A percentage falloff therefore either leaves text
   unprotected on narrow desktops or blacks out the photo on wide ones.
   Measured: text ends at 610px at 1440px and at most ~680px just above the
   900px breakpoint. The shade holds near-opaque through 700px and then drops
   away fast, so everything right of the copy is open photograph. */
.hero-shade {
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    rgba(11, 11, 12, 1) 0px,
    rgba(11, 11, 12, 0.99) 620px,
    rgba(11, 11, 12, 0.93) 700px,
    rgba(11, 11, 12, 0.35) 860px,
    rgba(11, 11, 12, 0.08) 1000px,
    rgba(11, 11, 12, 0) 1120px);
}
/* Network and About run the photograph full width behind the copy, using the
   artifact's own vertical shade so every pixel under the text is dark. */
.hero--wide { min-height: 74vh; }
.hero--wide .hero-photo { width: 100%; background-position: center 55%; }
/* Dark enough on the left for the RED tag and red h1 line — red is the binding
   constraint, it needs a backdrop no lighter than about rgb(33,33,33) — while
   letting the photograph actually read on the right. */
.hero--wide .hero-shade {
  background:
    linear-gradient(90deg,
      rgba(11, 11, 12, 0.97) 0%,
      rgba(11, 11, 12, 0.95) 44%,
      rgba(11, 11, 12, 0.72) 64%,
      rgba(11, 11, 12, 0.46) 82%,
      rgba(11, 11, 12, 0.36) 100%),
    linear-gradient(180deg, rgba(11, 11, 12, 0.55) 0%, rgba(11, 11, 12, 0) 30%, rgba(11, 11, 12, 0.8) 100%);
}
/* Network only — About keeps the shade above untouched. Px-anchored for the
   same reason as the Home hero: measured text ends at 671px at 1440px. The
   photograph runs the full width here, so the copy sits ON it and the left has
   to stay near-opaque, but everything past the copy is opened right up. */
.hero--pipeline .hero-shade {
  background:
    linear-gradient(90deg,
      rgba(11, 11, 12, 0.98) 0px,
      rgba(11, 11, 12, 0.97) 660px,
      rgba(11, 11, 12, 0.88) 740px,
      rgba(11, 11, 12, 0.45) 920px,
      rgba(11, 11, 12, 0.24) 1150px,
      rgba(11, 11, 12, 0.18) 1500px),
    linear-gradient(180deg, rgba(11, 11, 12, 0.5) 0%, rgba(11, 11, 12, 0.04) 36%, rgba(11, 11, 12, 0.68) 100%);
}
@media (max-width: 900px) {
  .hero--pipeline .hero-shade {
    background: linear-gradient(180deg, rgba(11, 11, 12, 0.93) 0%, rgba(11, 11, 12, 0.84) 55%, rgba(11, 11, 12, 0.96) 100%);
  }
}
@media (max-width: 900px) {
  .hero { min-height: 0; }
  /* No left-edge feather below the breakpoint: the photo is a full-width wash
     here, so a horizontal fade would just darken it unevenly for no reason. */
  .hero-photo { width: 100%; opacity: 0.35; -webkit-mask-image: none; mask-image: none; }
  .hero-shade {
    background: linear-gradient(180deg, rgba(11, 11, 12, 0.9) 0%, rgba(11, 11, 12, 0.7) 55%, rgba(11, 11, 12, 0.95) 100%);
  }
  .hero--wide .hero-photo { opacity: 0.4; }
}

/* .hero-photo--capped was removed in iteration 10. It existed only to stop the
   408x728 Network photograph being asked to cover more than it could carry.
   That photograph was replaced with a 2400x1600 one, so the constraint — and
   the workaround placement it forced — are both gone. */
.hero-inner {
  position: relative; z-index: 2;
  /* width:100% matters — .hero is a flex row, so without it .wrap shrink-wraps
     its content and margin-inline:auto drifts the copy right, over the photo. */
  width: 100%;
  /* Block padding only. The old `padding: 132px 0 90px` shorthand zeroed the
     side padding .wrap gives every other section, so below 1180px hero copy
     touched the viewport edge on all three pages (fixed in iteration 15). */
  padding-block: 132px 90px;
  animation: riseIn 0.9s ease both;
}
@keyframes riseIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .hero-inner { animation: none; } }

.hero h1 { font-size: clamp(2.6rem, 6vw, 4.6rem); max-width: 640px; }
.hero h1 em { font-style: normal; color: var(--color-accent); }
.hero p { margin-top: 22px; max-width: 460px; color: var(--color-muted); font-size: 1.02rem; line-height: 1.6; }
.hero p.lede--light { color: var(--color-text); }
.hero .btn { margin-top: 34px; }
.hero .tag { display: block; margin-bottom: 14px; }
/* Home hero mark: same treatment as the Network header — logo left, headline
   block right, vertically centred; stacked on phones. rogue-logo.jpg is 200x200
   native, so width 200px with max-width 100% can only ever shrink it. Its baked
   near-black ground sits on the scrim's opaque left zone, so no square shows.
   The paragraph and button stay below at the column's left edge, unmoved. */
.home-brand { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 30px); }
.home-logo { width: 200px; max-width: 100%; height: auto; flex: none; display: block; }
.home-title { min-width: 0; }
/* 901-1124px only. With the hero side gutter restored, the headline beside the
   200px logo would otherwise run up to 19px onto the photograph (measured at
   901px). The headline scales with the viewport instead: 10.8vw - 54px keeps its
   widest line about 28px short of where the photo starts, and hands back to the
   normal 6vw size from 1125px. The photo and scrim are untouched. */
@media (min-width: 901px) {
  .hero .home-title h1 { font-size: clamp(2.6rem, min(6vw, 10.8vw - 54px), 4.6rem); }
  /* Same reason, for the paragraph under the logo row: its 460px measure,
     now starting at the gutter, reached 2px past the photo's edge at 901px.
     48vw - 26px keeps it about 26px short; no effect from about 1013px up. */
  .hero .home-brand + p { max-width: min(460px, 48vw - 26px); }
}
@media (max-width: 900px) {
  .br-wide { display: none; }
  /* Below 900px the Home hero ground is the photo wash, lighter (about rgb 17-24)
     than the logo's baked edge (rgb 9), so its square would show. Fade only the
     logo's empty outer margin into the wash. The artwork is 18px or more from
     every edge (top 18, bottom 23, left 31, right 29, measured), so these fades
     never touch it. The photo is not darkened; the logo is not resized. */
  .home-logo {
    -webkit-mask-image:
      linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%),
      linear-gradient(180deg, transparent 0, #000 16px, #000 calc(100% - 20px), transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%),
      linear-gradient(180deg, transparent 0, #000 16px, #000 calc(100% - 20px), transparent 100%);
    mask-composite: intersect;
  }
}
@media (max-width: 640px) { .home-brand { flex-direction: column; align-items: flex-start; } }
.hero-kicker {
  margin-top: 18px;
  font-family: var(--font-cond); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.1em;
  font-size: 1.05rem; color: var(--color-text);
}

/* =========================== hairline grids ============================= */
.grid4, .grid2 {
  margin-top: 52px; display: grid; gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
.grid4 { grid-template-columns: repeat(4, 1fr); }
.grid2 { grid-template-columns: repeat(2, 1fr); }
.cell { background: var(--color-bg); padding: 34px 28px; min-height: 230px; display: flex; flex-direction: column; }
.section-alt .cell { background: var(--color-surface); }
.cell h3 {
  font-family: var(--font-cond); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.02em;
  font-size: 1.08rem; line-height: 1.25; margin-bottom: 14px;
}
.cell .cell-num {
  display: block; font-family: var(--font-display);
  font-size: 0.95rem; color: var(--color-accent); margin-bottom: 10px; letter-spacing: 1px;
}
.cell p { color: var(--color-muted); font-size: 0.92rem; line-height: 1.55; flex: 1; }
.cell ul { color: var(--color-muted); font-size: 0.9rem; line-height: 1.5; flex: 1; }
.cell li { position: relative; padding-left: 16px; margin-bottom: 8px; }
.cell li::before { content: "—"; position: absolute; left: 0; color: var(--color-accent); }
.cell .more { margin-top: 12px; }
@media (max-width: 900px) { .grid4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .grid2 { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .grid4 { grid-template-columns: 1fr; } }

/* =========================== red CTA band =============================== */
.band { background: var(--color-primary); color: var(--color-on-primary); padding: 64px 0; }
.band .wrap { display: flex; align-items: center; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.band h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); max-width: 560px; }
.band p { margin-top: 14px; max-width: 560px; color: var(--color-on-primary); font-size: 0.98rem; line-height: 1.6; }

/* =========================== trio / stat row ============================ */
.trio { margin-top: 54px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; }
.trio .item { border-top: 2px solid var(--color-primary); padding-top: 18px; }
.trio .icon { width: 30px; height: 30px; margin-bottom: 14px; color: var(--color-accent); }
.trio h3 { font-family: var(--font-cond); font-weight: 700; text-transform: uppercase; font-size: 1.02rem; margin-bottom: 8px; letter-spacing: 0.02em; }
.trio p { color: var(--color-muted); font-size: 0.88rem; line-height: 1.55; }
@media (max-width: 900px) { .trio { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .trio { grid-template-columns: 1fr; } }

/* =========================== network banner ============================= */
.network-banner { position: relative; height: clamp(200px, 26vw, 320px); overflow: hidden; }
.network-banner img { width: 100%; height: 100%; object-fit: cover; object-position: center 60%; }
.network-banner .fade {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(21, 21, 23, 0.05) 0%, rgba(21, 21, 23, 0.75) 55%, var(--color-surface) 100%);
}

/* The reintroduction band rules were removed in iteration 11: its content (title,
   tagline, subline, Rogue's capability column) moved into the Network hero. */

/* =========================== contact line =============================== */
.contact-line {
  margin-top: 44px;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 0 clamp(14px, 2.6vw, 30px);
  border-block: 1px solid var(--line);
  padding: 4px 0;
}
.contact-line li { display: flex; align-items: center; }
.contact-line li + li::before {
  content: ""; width: 1px; height: 16px; background: var(--color-primary);
  margin-right: clamp(14px, 2.6vw, 30px);
}
.contact-line a, .contact-line span {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-cond); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.95rem;
  word-break: break-word; text-decoration: none;
}
.contact-line a { text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 1px; }
.contact-line a:hover { color: var(--color-accent); text-decoration-thickness: 2px; }

/* =========================== network header (one-sheet) ================= */
/* Mirrors Saxon's Rogue Network one-sheet: wolf mark left, title block right,
   Rogue's capability column beside it. rogue-logo.jpg is 200x200 native — the
   width below is a hard ceiling, never a fill. Its baked background measures
   rgb(9-10,10,10) against a hero ground of rgb(11,11,12), so it sits directly on
   the dark left of the hero with no tile and no visible seam. */
.net-head {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
  gap: clamp(28px, 4vw, 56px); align-items: center;
}
.net-brand { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 30px); min-width: 0; }
.net-logo { width: 200px; max-width: 200px; height: auto; flex: none; display: block; }
.net-title { min-width: 0; }
.hero .net-title h1 { font-size: clamp(2.3rem, 4.4vw, 4rem); max-width: none; line-height: 0.95; }
/* width: fit-content is load-bearing. With max-width:none the tagline's element
   box took the full title-column width (to 848px at 1440) while its glyphs end
   at 687px — 160px of empty box running out over the lit pipe. Glyph contrast
   was 5.18:1, but that empty box area reads 3.36:1, and anything that measures
   the element's rect (as the iteration-11 review did) sees the failure there.
   Hugging the text puts the box's right edge inside the scrim's protected zone,
   so rect and glyphs agree. No scrim change, no photograph lost. */
.net-tagline {
  width: fit-content;
  margin-top: 12px !important; max-width: none !important;
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.5px;
  font-size: clamp(1.05rem, 1.6vw, 1.4rem) !important; line-height: 1.15 !important;
  color: var(--color-accent) !important;
}
.net-subline {
  margin-top: 8px !important; max-width: 46ch !important;
  font-family: var(--font-cond); font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; font-size: 0.8rem !important; line-height: 1.4 !important;
  color: var(--color-text) !important;
}
/* The capability column sits over the brighter right of the pipeline photo, so
   it carries its own near-opaque panel rather than trusting the scrim there. */
.net-caps {
  background: rgba(11, 11, 12, 0.93); border-left: 3px solid var(--color-primary);
  padding: 20px 22px;
}
.net-caps h2 {
  font-family: var(--font-cond); font-weight: 700; font-size: 0.86rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent);
  margin-bottom: 12px;
}
.net-caps li { position: relative; padding-left: 16px; margin-bottom: 8px; color: var(--color-text); font-size: 0.88rem; line-height: 1.45; }
.net-caps li::before { content: ""; position: absolute; left: 0; top: 0.58em; width: 6px; height: 6px; border-radius: 50%; background: var(--color-accent); }
@media (max-width: 1100px) { .net-head { grid-template-columns: 1fr; } .net-caps { max-width: 560px; } }
@media (max-width: 640px) {
  .net-brand { flex-direction: column; align-items: flex-start; }
  .net-logo { width: min(200px, 46vw); }
}
/* Below 900px the Network hero ground is the photo wash, lighter than the logo's
   baked edge (rgb 9), so its square showed faintly (worst side 1.06:1 at 768px).
   Same treatment as the Home hero logo: fade only the empty outer margin. In
   percentages here because this logo shrinks to 46vw on phones — 12% sides, 8% top,
   10% bottom of 200px is 24 / 16 / 20px, and the artwork sits 31 / 29 px from the
   sides, 18px from the top and 23px from the bottom, so the fade never reaches it
   at any rendered size. 1440px is unchanged. */
@media (max-width: 900px) {
  .net-logo {
    -webkit-mask-image:
      linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%),
      linear-gradient(180deg, transparent 0, #000 8%, #000 90%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%),
      linear-gradient(180deg, transparent 0, #000 8%, #000 90%, transparent 100%);
    mask-composite: intersect;
  }
}

/* =========================== partner grid (one-sheet cards) ============= */
/* Matches the one-sheet: separate dark cards on a gap, red top border, the
   firm's plate centred at the top, a hairline under it, red uppercase category,
   three bullets with red round markers. 3-across on desktop, 2 rows of 3. */
.partners {
  margin-top: 56px; display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
.partner { background: var(--panel); border-top: 3px solid var(--color-primary); }
.partner .logomark {
  height: 96px; display: flex; align-items: center; justify-content: center;
  margin: 0 20px; padding: 14px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}
/* The plate is sized to its content, like the sheet's plate boxes. Each plate's
   background is set to the crop's own sampled edge colour, so the crop sits
   inside it with no seam. */
.partner .plate {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--plate, #0b0b0c); padding: 6px 10px; max-width: 100%;
}
/* Crops from the one-sheet. width/height attributes carry the native crop size
   and there is no width:100%, so max-width can only ever shrink a crop —
   never enlarge it. */
.partner .firm-crop { display: block; max-width: 100%; height: auto; image-rendering: auto; }
.partner .body { padding: 18px 22px 24px; }
.partner .category {
  font-family: var(--font-cond); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; font-size: 0.78rem; color: var(--color-accent); margin-bottom: 12px;
}
.partner ul { color: var(--color-muted); font-size: 0.86rem; line-height: 1.5; }
.partner li { position: relative; padding-left: 16px; margin-bottom: 9px; }
.partner li::before { content: ""; position: absolute; left: 0; top: 0.58em; width: 6px; height: 6px; border-radius: 50%; background: var(--color-accent); }
@media (max-width: 900px) { .partners { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .partners { grid-template-columns: 1fr; } }

/* Home-page teaser variant: the same plates, six across, no body copy. The
   per-firm categories and bullets stay on network.html and are not repeated.
   This block sits AFTER the .partners breakpoints above deliberately — equal
   specificity, so source order is what lets the strip keep its own columns. */
.strip-head {
  margin-top: 44px;
  font-family: var(--font-cond); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  font-size: 0.92rem; color: var(--color-text);
}
.partners--strip { margin-top: 16px; grid-template-columns: repeat(6, 1fr); gap: 10px; }
.partners--strip .logomark { border-bottom: 0; height: 88px; margin: 0; padding: 10px; }
/* Six across leaves ~170px a cell, so the widest crops are shrunk by max-width.
   That is a downscale only; nothing here can enlarge a crop past native. */
@media (max-width: 1040px) { .partners--strip { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .partners--strip { grid-template-columns: repeat(2, 1fr); } }


/* =========================== quote line ================================= */
.quote-line { margin-top: 64px; text-align: center; }
.quote-line p {
  font-family: var(--font-display); font-size: clamp(1.4rem, 2.6vw, 2rem);
  text-transform: uppercase; max-width: 820px; margin: 0 auto; line-height: 1.2;
  letter-spacing: 0.5px;
}
.quote-line .attrib {
  font-family: var(--font-cond); font-weight: 600; font-size: 0.85rem;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--color-muted); margin-top: 16px;
}

/* =========================== founder ==================================== */
.founder {
  background:
    linear-gradient(120deg, rgba(11, 11, 12, 0.95), rgba(11, 11, 12, 0.65)),
    radial-gradient(circle at 85% 20%, #262628, #0b0b0c 70%);
  padding: clamp(64px, 9vw, 110px) 0;
  position: relative;
}
.founder-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: clamp(32px, 5vw, 64px); align-items: start; }
.founder h2 { font-size: clamp(2rem, 3.8vw, 2.9rem); }
.founder .name { margin-top: 30px; font-family: var(--font-cond); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; font-size: 1.1rem; }
.founder .role { color: var(--color-muted); font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.1em; font-family: var(--font-cond); font-weight: 600; }
@media (max-width: 880px) { .founder-grid { grid-template-columns: 1fr; } }

/* The base carries NO aspect-ratio. Each modifier declares its own shape at
   every breakpoint, so one image's responsive rule can never reshape another's
   through source order. That is exactly what went wrong before: a
   `@media (max-width:880px){ .founder-visual{ aspect-ratio:16/9 } }` sat after
   the square modifier at equal specificity and letterboxed the family
   photograph on everything below desktop. */
.founder-visual { position: relative; overflow: hidden; border: 1px solid var(--line); background: var(--panel); }
.founder-visual img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 30%; }

/* Atmospheric landscape, not a portrait position. It fills the column rather
   than sitting at a portrait-sized cap, and the red bottom rule closes the
   frame — the same device the credential cells below use on their left edge. */
.founder-visual--scene {
  aspect-ratio: 3/2;
  border-bottom: 3px solid var(--color-primary);
}
.founder-visual--scene img { object-position: center 55%; }
/* Deliberate, and scoped to this modifier alone: the landscape opens out a
   little on narrow screens, where vertical space is scarcer. */
@media (max-width: 880px) { .founder-visual--scene { aspect-ratio: 16/9; } }

/* Saxon's family photograph: 512x768 native, colour, portrait. max-width is a
   hard ceiling, so the file is shown at 1:1 at most and never enlarged, and the
   2/3 ratio matches the photograph exactly, so nobody is cropped at any
   breakpoint. The same red bottom rule as the landscape above pairs the two.
   No caption, nobody named. */
.founder-visual--portrait {
  aspect-ratio: 2/3;
  max-width: 512px;
  border-bottom: 3px solid var(--color-primary);
}
.founder-visual--portrait img { object-position: center center; }

.founder-facts { margin-top: 36px; display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
.founder-facts .f { border-left: 2px solid var(--color-primary); padding-left: 14px; }
.founder-facts .f h4 { font-family: var(--font-cond); font-weight: 700; text-transform: uppercase; font-size: 0.98rem; color: var(--color-text); margin-bottom: 6px; }
.founder-facts .f p { color: var(--color-muted); font-size: 0.86rem; line-height: 1.5; }
.founder-facts .f .qual { display: block; margin-top: 8px; font-size: 0.8rem; line-height: 1.45; }
@media (max-width: 560px) { .founder-facts { grid-template-columns: 1fr; } }

/* The reserved-photo-slot component (.slot-photo, its red corner brackets,
   hazard stripes and "PHOTOGRAPH RESERVED" tag) was removed in iteration 8.
   Both photograph slots on about.html now hold real images, so nothing used
   it any more. The partner plates carry their own disclosure separately. */

/* =========================== published claim ============================ */
.claim {
  border: 1px solid var(--line); border-left: 4px solid var(--color-primary);
  background: var(--panel); padding: clamp(24px, 4vw, 40px); max-width: 900px;
}
.claim .claim-label { display: block; font-family: var(--font-cond); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 16px; }
.claim .claim-text { font-family: var(--font-display); text-transform: uppercase; font-size: clamp(1.4rem, 2.6vw, 2rem); line-height: 1.12; letter-spacing: 0.5px; }
.claim .claim-text em { font-style: normal; color: var(--color-accent); }
.claim figcaption { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); color: var(--color-muted); font-size: 0.86rem; line-height: 1.55; max-width: 62ch; }

/* =========================== values ===================================== */
/* Single column: "Our Approach" moved into the red band below, so this panel
   now carries only "Our Mission" and no longer needs a two-column grid. */
.values { display: grid; grid-template-columns: 1fr; background: var(--line); border: 1px solid var(--line); }
.values .v { background: var(--color-bg); padding: 38px 30px; }
.values h3 { font-family: var(--font-display); font-size: 1.3rem; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
.values p { color: var(--color-muted); font-size: 0.92rem; line-height: 1.6; }
.values p + p { margin-top: 12px; }

/* =========================== contact ==================================== */
.contact-grid { display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: clamp(28px, 4vw, 56px); align-items: start; margin-top: 46px; }
@media (max-width: 880px) { .contact-grid { grid-template-columns: 1fr; } }

.contact-list { border-top: 2px solid var(--color-primary); }
.contact-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 14px; align-items: start; padding: 16px 0; border-bottom: 1px solid var(--line); }
.contact-list svg { width: 20px; height: 20px; color: var(--color-accent); margin-top: 4px; }
.contact-list .c-label { font-family: var(--font-cond); font-weight: 600; font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--color-muted); }
.contact-list a { display: inline-flex; align-items: center; min-height: 44px; font-family: var(--font-cond); font-weight: 700; font-size: 1.15rem; letter-spacing: 0.03em; text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; word-break: break-word; }
.contact-list a:hover { color: var(--color-accent); }
.contact-list .c-static { font-family: var(--font-cond); font-weight: 700; font-size: 1.15rem; letter-spacing: 0.03em; }

.form-card { background: var(--panel); border: 1px solid var(--line); border-top: 3px solid var(--color-primary); padding: clamp(22px, 3vw, 32px); }
.field { margin-bottom: 16px; }
.field label { display: block; font-family: var(--font-cond); font-weight: 600; font-size: 0.76rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 7px; }
.field input, .field select, .field textarea {
  width: 100%; min-height: 48px; background: var(--color-bg);
  border: 1px solid var(--line); border-radius: 0; color: var(--color-text);
  font: inherit; font-size: 1rem; padding: 12px 14px;
}
.field textarea { min-height: 112px; resize: vertical; }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--color-primary); }
.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
@media (max-width: 560px) { .form-row { grid-template-columns: 1fr; } }
.form-card .btn { width: 100%; margin-top: 6px; }
.form-status { margin-top: 16px; font-size: 0.88rem; line-height: 1.5; border-left: 3px solid var(--color-primary); padding: 12px 14px; background: var(--color-surface); }
.form-status:empty { display: none; }
/* Validation: visible text message + border + inset bar, so red is never the
   only signal. #ff8a8f on the form panel measures 7.5:1. */
.field-error { margin-top: 6px; font-size: 0.84rem; line-height: 1.4; color: #ff8a8f; }
.field [aria-invalid="true"] { border-color: #ff8a8f; box-shadow: inset 3px 0 0 #ff8a8f; }
/* Links in the post-submit line: underlined, and padded to a 44px hit area
   without changing the line box. */
.form-status a { color: var(--color-text); text-decoration: underline; text-underline-offset: 3px; padding-block: 13px; }
.form-status a:hover { color: var(--color-accent); }
/* Delivery states, used only when the form is connected to the form service.
   Text colour never changes (same #f2f1ee on the surface as the hand-off line);
   only the left rule does, and each state says what happened in words. */
.form-status[data-state="sending"] { border-left-color: var(--color-muted); }
.form-status[data-state="success"] { border-left-color: #4fbf85; }
.form-status[data-state="error"] { border-left-color: #ff8a8f; }
.form-status strong { font-weight: 700; color: var(--color-text); }
#enquiry[aria-busy="true"] .btn { cursor: progress; }

/* =========================== final CTA ================================== */
.final {
  text-align: center; padding: clamp(72px, 11vw, 130px) 0;
  background: radial-gradient(ellipse at 50% 0%, #1b1b1d, #0b0b0c 65%);
  border-top: 1px solid var(--line);
}
.final h2 { font-size: clamp(2.1rem, 5vw, 3.6rem); max-width: 820px; margin: 0 auto; }
.final .btn { margin-top: 34px; }

/* Photographic closing band, as the comp has. The scrim is flat rather than
   directional because the copy is centred and can sit over any pixel. */
.final--photo { position: relative; isolation: isolate; overflow: hidden; background: var(--color-bg); }
.final--photo .final-bg {
  position: absolute; inset: 0; z-index: -2;
  background-image: url("assets/range-dusk.jpg");
  background-size: cover; background-position: center 60%;
}
.final--photo .final-scrim { position: absolute; inset: 0; z-index: -1; background: rgba(11, 11, 12, 0.78); }
.final--photo .wrap { position: relative; z-index: 1; }

/* =========================== footer ===================================== */
footer.site-footer { border-top: 1px solid var(--line); padding: 56px 0 34px; background: var(--color-bg); }
.foot-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 40px; flex-wrap: wrap; }
/* Footer mark: wolf logo only, no text wordmark — the artwork already carries
   "ROGUE CONTRACTORS AND CONSULTING". 200px is rogue-logo.jpg's native size, so
   max-width: 100% can only ever shrink it, never enlarge it. */
.foot-brand { display: flex; align-items: center; }
.foot-brand img { display: block; width: 200px; max-width: 100%; height: auto; }
.foot-col h2 { font-family: var(--font-cond); font-weight: 700; font-size: 0.76rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--color-accent); padding-bottom: 8px; border-bottom: 2px solid var(--color-primary); margin-bottom: 8px; }
.foot-col a, .foot-col .f-static {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-cond); font-weight: 600; font-size: 0.9rem; letter-spacing: 0.04em;
  text-decoration: none;
}
.foot-col a { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; text-decoration-color: rgba(255, 255, 255, 0.25); }
.foot-col a:hover { color: var(--color-accent); text-decoration-color: currentColor; }
.foot-col .f-static { color: var(--color-muted); }

.owned-badge {
  display: inline-flex; align-items: center; gap: 10px; margin-top: 16px;
  border: 2px solid var(--color-primary); padding: 9px 14px;
  font-family: var(--font-cond); font-weight: 700; font-size: 0.76rem;
  letter-spacing: 0.16em; text-transform: uppercase;
}
.owned-badge svg { width: 17px; height: 17px; color: var(--color-accent); flex: none; }

.tagline-strip {
  text-align: center; font-family: var(--font-display); letter-spacing: 1px;
  color: var(--color-muted); font-size: 0.85rem; text-transform: uppercase; margin-top: 40px;
}
.foot-bottom {
  margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap;
}
.foot-bottom p { color: var(--color-muted); font-size: 0.8rem; }
.foot-credits { flex-basis: 100%; color: var(--color-muted); font-size: 0.78rem; line-height: 1.55; }

/* =========================== reveal ===================================== */
.js .reveal { opacity: 0; transform: translateY(14px); }
.js .reveal.is-in { opacity: 1; transform: none; transition: opacity 0.4s ease, transform 0.4s ease; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
