/* Site developed and built by sitethreesixty.com */

/* ============================================================
   inner-critical.css — System base + inner page Zone 1 (banner)
   Everything needed for first paint on inner pages.

   ⚠️ This file intentionally duplicates home-critical.css's reset,
   Frame, Framework, Zone base, positions, 1000px breakpoint, and both
   FIXTURES (nav + slim footer) verbatim — 00-FOUNDATION.md §4, the one
   scoped exception to "critical CSS must never duplicate another sheet."
   A page loads ONE critical file or the other, never both, so the
   duplication never collides at runtime. Only this file's own Zone 1
   (page banner, below) is genuinely unique.
   ============================================================ */

/* ============================================================
   SHARED BASE
   Everything from here to END SHARED BASE must be BYTE-FOR-BYTE
   IDENTICAL to the same region in the other critical file (Lesson #5).
   Verify with checklist gate B4 before every handover:
     sed -n '/^   SHARED BASE$/,/^   END SHARED BASE$/p' css/home-critical.css  > /tmp/sb1
     sed -n '/^   SHARED BASE$/,/^   END SHARED BASE$/p' css/inner-critical.css > /tmp/sb2
     diff /tmp/sb1 /tmp/sb2 && echo IDENTICAL
   Add to BOTH files or NEITHER. Never one.
   ============================================================ */

/* --- Reset --- */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  line-height: var(--leading-normal);
  color: var(--text-on-light);
  background-color: var(--bg-light);
  overflow-x: hidden;
}

img,
video {
  max-width: 100%;
  display: block;
}

/* No-flash guards for JS-revealed UI (confirmation zone + sources modal).
   These are visibility rules that must hold on first paint before the
   deferred sheet loads (CLS mental model — §CLAUDE.md).
   `!important` is a PLANNER-APPROVED EXCEPTION (Steve, 4 Aug 2026): it
   guards against the site's own display:flex/grid rules winning on
   specificity — the same category as a third-party override. Without it,
   hidden modal content can flash on first paint. */
[hidden] { display: none !important; }
dialog:not([open]) { display: none; }

/* --- Skip link --- */

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  font-size: var(--font-small);
  z-index: var(--z-overlay);
  background-color: var(--chalk);
  color: var(--graphite);
}

.skip-link:focus {
  top: var(--space-sm);
}

/* --- Global focus indicator (WCAG 2.2 AA, 2.4.7 + 2.4.11) ---
   Added 4 Aug 2026 after the 2nd independent inspection found NO global
   focus style: only .skip-link, .cite and two footer links had one, so
   nav, every button, every body link and the CTA were invisible to
   keyboard users. Critical, not deferred — a focus ring that arrives with
   a deferred sheet leaves early keyboard interaction unindicated.
   :focus-visible (not :focus) so it never shows on mouse clicks.
   Torch reads AA on both Graphite and Chalk; the offset keeps it clear of
   the element's own border. */
:focus-visible {
  outline: var(--border-medium) solid var(--torch);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Inputs replace their border-glow with the ring rather than stacking both */
.form-input:focus-visible,
.form-textarea:focus-visible {
  outline: var(--border-medium) solid var(--torch);
  outline-offset: 1px;
}

/* Flex and grid children default to min-width:auto and refuse to shrink
   below their content's intrinsic width — the longest unbreakable word in a
   heading then forces horizontal scroll. Every hero copy column needs
   min-width:0. Extended 4 Aug 2026 after larger (legible) text pushed 320px
   viewports over. Shared-base rule: keep byte-identical across both files. */
.hero-inner,
.hero-copy,
.hero-gauge,
.core-hero-inner,
.core-hero-copy,
.managed-hero .hero-copy,
.pricing-hero .hero-copy {
  min-width: 0;
}

/* --- Frame --- */

.frame {
  width: 100%;
  padding: 0 var(--container-pad);
}

/* --- Framework --- */

.framework {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

/* --- Zone base (subgrid) --- */

.zone {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  padding-block: var(--zone-pad);
}

/* --- Positions (§5 / §6.0 — the ONLY layer a width cap may live on) --- */

.pos-full    { grid-column: 1 / -1; }
.pos-wide    { grid-column: 2 / -2; }
.pos-content { grid-column: 3 / -3; width: 100%; max-width: 1200px; justify-self: center; }
.pos-narrow  { grid-column: 4 / -4; width: 100%; max-width: 900px; justify-self: center; }
.pos-left    { grid-column: 1 / 7; }
.pos-right   { grid-column: 7 / -1; }

/* --- Responsive: single breakpoint at 1000px --- */

@media (max-width: 1000px) {
  /* Build Lesson #13 (fine-line CLAUDE.md): when positions collapse to
     grid-column:1/-1 the content goes edge-to-edge within the subgrid — the
     zone must provide the side gutter. System-level shared-base rule; keep
     this block byte-for-byte identical to inner-critical.css (Lesson #5). */
  .zone {
    padding-inline: var(--container-pad);
  }

  .pos-full,
  .pos-wide,
  .pos-content,
  .pos-narrow,
  .pos-left,
  .pos-right {
    grid-column: 1 / -1;
    max-width: none;
    justify-self: stretch;
  }

}

/* Nav hides over the hero, then slides in solid past it. Every page has a
   dark Zone 1 carrying its own wordmark, and js/fixtures.js adds .nav-hidden
   on all of them — Pricing and Explore Managed were showing a nav over their
   hero (duplicate wordmark) purely because this rule was missing from
   inner-critical.css. Consolidated into the shared base 4 Aug 2026 (Steve).
   Keep byte-identical across both critical files. */
.nav {
  transition: background-color var(--speed-normal) var(--ease-default),
              border-color var(--speed-normal) var(--ease-default),
              padding var(--speed-normal) var(--ease-default),
              transform var(--speed-normal) var(--ease-default),
              opacity var(--speed-normal) var(--ease-default);
}

.nav.nav-hidden {
  transform: translateY(-100%);
  opacity: 0;
  pointer-events: none;
}

/* ============================================================
   END SHARED BASE
   Everything below this line is INNER-PAGE-SPECIFIC.
   ============================================================ */

/* ============================================================
   FIXTURE 1 — Nav (§8a) — verbatim from home-critical.css
   ============================================================ */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-header);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.15rem clamp(1.5rem, 5vw, 4rem);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--speed-normal) var(--ease-default),
              border-color var(--speed-normal) var(--ease-default),
              padding var(--speed-normal) var(--ease-default),
              transform var(--speed-normal) var(--ease-default),
              opacity var(--speed-normal) var(--ease-default);
}

.nav.solid {
  background: var(--graphite);
  border-bottom-color: color-mix(in srgb, var(--chalk) 10%, transparent);
  padding-top: .85rem;
  padding-bottom: .85rem;
}

.nav .brand {
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: 1.4rem;
  letter-spacing: var(--tracking-tight);
  color: var(--chalk);
  text-decoration: none;
}

.nav .brand .tsx { color: var(--torch); }
.nav .brand .deg { color: var(--torch); font-size: .78em; vertical-align: .32em; }

.nav .links {
  display: flex;
  align-items: center;
  gap: 2rem;
}

.nav .links a {
  font-family: var(--font-body);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-normal);
  color: var(--chalk);
  text-decoration: none;
  position: relative;
  padding: .25rem 0;
  transition: color var(--speed-fast) var(--ease-default);
}

.nav .links a:hover { color: var(--torch-bright); }
.nav .links a.active { color: var(--torch-bright); }
.nav .links a.active::after {
  content: "\00B0";
  position: absolute;
  right: -.7em;
  top: -.1em;
  color: var(--torch);
  font-size: 1.1em;
  line-height: 1;
}

.nav .cta {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--font-caption);
  color: var(--chalk);
  background: var(--torch-deep);
  padding: .65rem 1.5rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color var(--speed-fast) var(--ease-default);
  letter-spacing: var(--tracking-wide);
  line-height: 1;
  white-space: nowrap;
}

.nav .cta:hover { background: var(--torch-deepest); }

.nav .nav-toggle {
  display: none;
  background: transparent;
  border: none;
  color: var(--chalk);
  cursor: pointer;
  padding: .5rem;
}

@media (max-width: 1000px) {
  .nav .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .nav .links {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(78vw, 320px);
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 2rem;
    padding: 2rem clamp(1.5rem, 8vw, 3rem);
    background: var(--graphite);
    transform: translateX(100%);
    transition: transform var(--speed-normal) var(--ease-default);
  }

  .nav .links.is-open {
    transform: translateX(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav,
  .nav .links {
    transition: none;
  }
}


/* ============================================================
   Hero-top coordinate + breadcrumb pattern (§9) — verbatim
   ============================================================ */

.hero-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  /* Wrap + shrink: at 360px the wordmark and the coordinate readout no
     longer fit on one row now that small text renders at a legible size,
     and the coords overflowed the viewport by 5-21px. flex-wrap lets the
     coords drop; min-width:0 lets them shrink rather than push. */
  flex-wrap: wrap;
  gap: var(--space-sm);
  border-bottom: 1px solid color-mix(in srgb, var(--graphite) 12%, transparent);
  padding-bottom: 1rem;
  margin-bottom: 1.8rem;
}

.brandcol {
  display: flex;
  flex-direction: column;
  gap: .55rem;
}

/* Matches the Home hero wordmark exactly (Steve, 5 Aug) — it is the same
   brand statement doing the same job, on a hero where the nav is hidden.
   Was 1.3rem / weight 500, which also hardcoded a font-size outside the
   clamp scale (D1). */
.wordmark {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: clamp(1.75rem, 3vw, 2.4rem);
  letter-spacing: var(--tracking-tight);
  line-height: 1;
}

.wordmark .tsx { color: var(--torch); }
.wordmark .deg { color: var(--torch); font-size: .72em; vertical-align: .3em; }

.breadcrumb-bearing {
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-mono);
  display: flex;
  gap: .55em;
  align-items: center;
}

.bc-page { color: var(--chalk); }
.bc-sep { color: var(--slate); }
.bc-deg { color: var(--torch-bright); }

.coords {
  min-width: 0;
  /* The readout ships with the GREENWICH fallback for a correct first paint
     (zero CLS), then /api/where swaps in the visitor's real city AFTER LCP.
     Without this the text simply flicked from one word to another. The swap
     now cross-fades: JS sets .is-swapping, changes the text, clears it.
     Motion here is a SETTLE, not decoration — the same grammar as the
     instruments (perform once, then rest). */
  transition: opacity var(--speed-slow) var(--ease-default);
  /* Grows to fill its row so text-align:right actually reaches the right edge
     — both when sharing a row with the wordmark and when flex-wrap drops it
     to its own. Without this it is a shrink-to-fit box at the row start. */
  flex: 1 1 auto;
  text-align: right;
  font-family: var(--font-mono);
  line-height: 1.5;
}

.coords.is-swapping { opacity: 0; }

.coords .loc {
  display: block;
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-wide);
}

.coords .loc.live { color: var(--torch-bright); }
.coords .loc.live::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--torch);
  margin-right: 6px;
  vertical-align: middle;
}

.coords .ll {
  display: block;
  /* The coordinate is ONE value — it must not break after "°N". At ~160px in
     mono it fits inside a 360px viewport with room to spare, so nowrap costs
     nothing; without it the string splits across two lines for no reason.
     (.hero-top's flex-wrap still lets the whole block drop below the wordmark
     when it genuinely cannot sit alongside — that is a different wrap.) */
  white-space: nowrap;
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-normal);
  color: var(--slate);
  margin-top: .15rem;
}

/* ============================================================
   Inner Page Zone 1 — Page Banner (light scheme)
   ============================================================ */

/* --- Zone 1 colour scheme --- */

.zone-banner {
  background-color: var(--bg-light);
  color: var(--text-on-light);
}

/* --- Page banner container --- */

.page-banner {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.page-banner h1 {
  font-family: var(--font-heading);
  font-size: var(--font-h1);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

/* --- Breadcrumbs (page-level "Home / About" nav breadcrumb —
   distinct from the .breadcrumb-bearing hero-top pattern above) --- */

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  list-style: none;
  font-size: var(--font-small);
}

.breadcrumb li + li::before {
  content: '/';
  margin-right: var(--space-sm);
}

.breadcrumb a {
  text-decoration: none;
}

.breadcrumb a:hover {
  text-decoration: underline;
}

/* ============================================================
   Pricing — Zone 1 (dark hero, petrol-tank price hook + fuel gauge)
   BLUEPRINTS/01-PRICING.md §2/§3/§6. This page's own Zone 1 is unique
   per §4 — the shared system base above is the only part duplicated
   with home-critical.css. Above-the-fold on /pages/pricing.html (+ the
   /us/ mirror), so everything visible on first paint lives here.
   ============================================================ */

.zone-pricing-hero {
  background-color: var(--bg-dark);
  color: var(--text-on-dark);
}

.pricing-hero {
  display: flex;
  flex-direction: column;
}


.hero-inner {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.pricing-hero h1 {
  font-family: var(--font-heading);
  font-size: clamp(2rem, 4.5vw, 3.2rem);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin: var(--space-md) 0;
}

.pricing-hero h1 .t {
  color: var(--torch);
}

.hero-sub {
  font-size: var(--font-body-size);
  color: var(--chalk);
  max-width: 40ch; /* text-measure, not a layout cap — guardrail §5 */
  margin-bottom: var(--space-md);
}

.hero-note {
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-wide);
  color: var(--slate);
}

/* --- Fuel gauge — RESTING-STATE appearance only (renders on first
   paint before the animation fires). Animation transition properties
   (transform/stroke-dashoffset durations) are deferred — css/pages/pricing.css.
   All instrument tokens consumed here (--instrument-*) are defined in
   tokens.css, never a deferred file (00-FOUNDATION.md §2c). ---*/

.hero-gauge {
  display: flex;
  justify-content: center;
}

.hero-gauge svg {
  height: clamp(300px, 40vw, 400px);
  width: auto;
  color: var(--chalk);
}

.fuel-gauge .track {
  stroke: currentColor;
  stroke-width: var(--instrument-stroke-width);
  opacity: var(--instrument-track-opacity);
  fill: none;
  stroke-linecap: round;
}

.fuel-gauge .fillarc {
  stroke: var(--torch);
  stroke-width: var(--instrument-stroke-width);
  fill: none;
  stroke-linecap: round;
}

.fuel-gauge .emptyarc {
  stroke: currentColor;
  stroke-width: var(--instrument-stroke-width);
  opacity: var(--instrument-empty-opacity);
  fill: none;
  stroke-linecap: round;
}

.fuel-gauge .tick {
  stroke: currentColor;
  stroke-width: 1;
  opacity: var(--instrument-tick-opacity);
}

.fuel-gauge .tick-major {
  stroke: currentColor;
  stroke-width: 1.8;
  opacity: var(--instrument-tick-major-opacity);
}

.fuel-gauge .mark {
  fill: var(--chalk);
  stroke: var(--torch);
  stroke-width: 2;
}

.fuel-gauge .needle {
  stroke: var(--torch);
  stroke-width: var(--instrument-needle-width);
  stroke-linecap: round;
}

.fuel-gauge #needle {
  transform-origin: 120px 210px;
}

.fuel-gauge .hub {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

.fuel-gauge .hub2 {
  fill: var(--torch);
}

/* A8 applies to SVG <text> too — `fill` + `opacity` fakes a lighter text
   colour exactly as `color-mix(… transparent)` does. Was .65/.35; the "F"
   measured 3.06:1, below AA. Full strength, hierarchy from weight.
   (4th inspection, 5 Aug — neither contrast-audit.py nor the A8 grep can
   see SVG text, so both reported clean.) */
.fuel-gauge .ef {
  fill: currentColor;
  font-family: var(--font-mono);
  font-size: var(--font-small);
  font-weight: var(--weight-medium);
}

.fuel-gauge .tname {
  fill: currentColor;
  font-family: var(--font-display);
  font-size: var(--font-caption);
  font-weight: var(--weight-medium);
  letter-spacing: -.01em;
}

/* Carries the actual prices (£22/£50/£100) — content, not decoration.
   A8: no opacity on text. It already recedes structurally: mono, caption
   size, and it sits below the tier name in --font-display. */
.fuel-gauge .tprice {
  fill: currentColor;
  font-family: var(--font-mono);
  font-size: var(--font-caption);
}

/* ============================================================
   Explore Managed — Zone 1 (dark hero) + the Level instrument's
   RESTING/SETTLED geometry. BLUEPRINTS/11-EXPLORE-MANAGED §CRITICAL-CSS.
   Above-the-fold on /pages/explore-managed.html (+ the /us/ mirror), so
   everything visible on first paint lives here — including the Level
   bubble's settled centre position (so PSI/reduced-motion see it true)
   and the hero start-offset + settle transition (the @keyframes/transition
   end-state must live in the same file as the property that uses it —
   §keyframes lesson). Scoped .level-* colour/stroke that also appears on
   the below-fold confirmation Level lives in the deferred page CSS; only
   the ABOVE-FOLD hero Level geometry + motion is critical here.
   ============================================================ */

.zone-managed-hero {
  background-color: var(--bg-dark);
  color: var(--text-on-dark);
}

.managed-hero {
  display: flex;
  flex-direction: column;
  position: relative;
}

/* Hero copy block */
.managed-hero .hero-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  position: relative;
  z-index: 1;
}

.managed-hero h1 {
  font-family: var(--font-heading);
  font-size: clamp(2rem, 5vw, 3.6rem);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin: var(--space-sm) 0;
}

.managed-hero h1 .t { color: var(--torch); }



.managed-hero .hero-sub {
  font-size: var(--font-body-size);
  color: var(--chalk);
  max-width: 52ch; /* text-measure, not a layout cap — guardrail §5 */
  line-height: var(--leading-normal);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md) var(--space-lg);
  margin-top: var(--space-sm);
}

.hero-quiet {
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-wide);
  color: var(--chalk);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--chalk) 30%, transparent);
  padding-bottom: 2px;
  transition: color var(--speed-fast) var(--ease-default),
              border-color var(--speed-fast) var(--ease-default);
}

.hero-quiet:hover {
  color: var(--torch-bright);
  border-bottom-color: var(--torch-bright);
}

/* Funnel-page eyebrow in place of the bearing degree figure */
.breadcrumb-bearing .bc-eyebrow { color: var(--torch-bright); }

/* --- Ghost Level (hero) — oversized, one tone off Graphite, behind copy.
   aria-hidden texture. Its bubble settles to true on load. --- */
.hero-level {
  position: absolute;
  left: 50%;
  top: 58%;
  transform: translate(-50%, -50%);
  width: min(70vw, 900px);
  pointer-events: none;
  z-index: 0;
  color: var(--chalk);
}

.hero-level .level-instrument {
  width: 100%;
  height: auto;
  display: block;
  /* Reserve the box before paint. Without aspect-ratio the SVG has no
     height until layout resolves, and the hero shifted by CLS 0.0497 when
     it appeared (Build Lesson #12 — media in a grid needs aspect-ratio).
     Matches the viewBox: 900 x 200. */
  aspect-ratio: 900 / 200;
}

/* Level fine-line family — 1.5px stroke, currentColor, rounded caps
   (matches compass-rose / globe-graticule). Ghost = very low contrast. */
.hero-level .level-frame,
.hero-level .level-vial,
.hero-level .level-edge,
.hero-level .level-grad {
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: round;
  opacity: .06; /* one tone off Graphite — texture, not content */
}

.hero-level .level-bubble {
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  opacity: .09;
  /* Settled/resting end-state is dead-centre (cx=450 in the SVG). The
     hero starts the bubble off-centre-left and slightly low, then the
     .level-play class transitions it home. transform-box:fill-box so the
     translate is in SVG user units. */
  transform-box: fill-box;
  transform-origin: center;
  transform: translate(-70px, 14px);
  transition: transform 1.6s cubic-bezier(.34, 1.3, .4, 1);
}

.hero-level .level-instrument.level-play .level-bubble {
  transform: translate(0, 0);
}

@media (prefers-reduced-motion: reduce) {
  .hero-level .level-bubble {
    transform: translate(0, 0); /* renders already true, no drift */
    transition: none;
  }
}


/* ============================================================
   EXPLORE CORE — Zone 1 + Core Build-Agent anchor (above-fold).
   Merged from css/explore-core-critical.css 4 Aug 2026 (Steve):
   explore-core.html was loading TWO blocking critical files, and
   12 West allows one per page. These rules are scoped to this
   page's own classes, so they never match on other inner pages —
   bytes only, no render cost.
   ============================================================ */

/* ============================================================
   ZONE 1 — HERO (dark, Graphite). Two-column: copy left, mono
   status panel right. Above the fold — all critical.
   ============================================================ */

.zone-core-hero {
  background-color: var(--bg-dark);
  color: var(--text-on-dark);
}

.core-hero {
  display: flex;
  flex-direction: column;
}

/* Status readout replaces the bearing breadcrumb on this funnel page
   (§1 design call — a build-status line, NOT a bearing). */
.status-line {
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-mono);
  display: flex;
  gap: .55em;
  align-items: center;
  text-transform: uppercase;
}

.status-line .st-label { color: var(--slate); }
.status-line .st-ready { color: var(--torch-bright); }
.status-line .st-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--torch);
}

/* Two-column hero: copy + clock + detail LEFT, the Build-Agent
   instrument RIGHT (Variant B). The instrument column is the wider one so
   the radar has room — the mockup's own .78 / 1.22 proportion. */
.core-hero-inner {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.core-hero-copy .section-label {
  color: var(--torch-bright);
}

.core-hero-copy h1 {
  font-family: var(--font-heading);
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin: var(--space-md) 0;
  color: var(--chalk);
}

.core-hero-copy h1 .t { color: var(--torch); }

.core-hero-sub {
  font-size: var(--font-body-size);
  color: var(--chalk);
  max-width: 48ch; /* text-measure, not a layout cap — guardrail §5 */
  margin-bottom: var(--space-lg);
}

/* NOTE: the clock panel + the "how it works" detail moved OUT of the hero
   into Zone 2 (.zone-core-what) — 2 Aug, hero was over-full. Those styles
   now live in css/pages/explore-core.css (deferred — Zone 2 is below the
   fold). The hero keeps only eyebrow + headline + sub + instrument + CTAs. */

/* Primary CTA — inline-flex + line-height:1 so padding is symmetric
   (§5a padding-bug fix). */
.cta-core {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--font-small);
  color: var(--chalk);
  background: var(--torch-deep);
  padding: .85rem 1.9rem;
  border-radius: var(--radius-md);
  border: var(--border-medium) solid var(--torch-deep);
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  transition: background-color var(--speed-fast) var(--ease-default),
              transform var(--speed-fast) var(--ease-default);
}

.cta-core:hover {
  background: var(--torch-deepest);
  border-color: var(--torch-deepest);
  transform: translateY(-2px);
}

.core-hero-actions {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  align-items: flex-start;
}

.cta-quiet {
  font-family: var(--font-body);
  font-size: var(--font-caption);
  /* Dimmed via colour, not opacity (A8): opacity belongs to scroll-reveal,
     and using it to fade text is forbidden outright. */
  color: var(--chalk);
  text-decoration: none;
  transition: color var(--speed-fast) var(--ease-default);
}

.cta-quiet:hover { color: var(--chalk); }

/* ============================================================
   CORE BUILD-AGENT ANCHOR (dark) — STATIC geometry only.
   Ported from design-mockups/core-agent-anchor/ (SYNC-1): every hex
   repointed to tokens. Variant B (2 Aug): the instrument lives in the
   HERO's right column (above the fold), so ALL its resting geometry is
   critical. The core-sweep / core-transfer / core-live @keyframes + the
   classes that reference them for MOTION live in css/pages/explore-core.css
   so keyframes sit with their animation (§CLS-8); the RESTING appearance
   is here so first paint is correct with zero CLS.
   MODULE:START core-agent-anchor
   ============================================================ */

/* MODULE:START core-agent-anchor */

/* The instrument panel — sits in the hero's right column. Scoped rule-line
   token replaces the mockup's own --rule. */
.core-anchor-instrument {
  /* --rule removed 4 Aug: custom properties may only be defined in
     tokens.css. Value inlined at its 3 usages below. */
  position: relative;
  padding: clamp(18px, 2.5vw, 30px);
  border: 1px solid color-mix(in srgb, var(--chalk) 20%, transparent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--chalk) 1.8%, transparent);
}

.core-anchor-instrument-head,
/* Three mono labels on one row. Below ~330px their intrinsic widths exceed
   the box, so the row MUST be allowed to wrap — nowrap overflowed by 3px.
   Inspection #3, 4 Aug 2026. */
.core-anchor-instrument-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs) var(--space-sm);
  color: var(--slate);
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  line-height: 1.3;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
}

.core-anchor-instrument-head {
  padding-bottom: 13px;
  border-bottom: 1px solid color-mix(in srgb, var(--chalk) 16%, transparent);
}

/* Live dot — static filled dot here; the pulse animation defers. */
.core-anchor-live::before {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 7px;
  border-radius: 50%;
  content: "";
  background: var(--torch);
}

.core-anchor-stage {
  position: relative;
  display: grid;
  min-height: 390px; /* min-height, not a max-width cap — legal (§5) */
  place-items: center;
  overflow: hidden;
}

.core-anchor-stage::before {
  position: absolute;
  inset: 0;
  content: "";
  opacity: .32;
  background-image:
    linear-gradient(color-mix(in srgb, var(--slate) 30%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--slate) 30%, transparent) 1px, transparent 1px);
  background-size: 52px 52px;
  /* Mask stencil — only the alpha channel matters here; Graphite is used
     as the opaque "keep" colour so no pure #000 appears (colour absolutes). */
  -webkit-mask-image: radial-gradient(circle, var(--graphite) 22%, transparent 72%);
  mask-image: radial-gradient(circle, var(--graphite) 22%, transparent 72%);
}

.core-anchor-track {
  position: absolute;
  width: min(390px, 68%);
  aspect-ratio: 1;
  border: 1px solid color-mix(in srgb, var(--chalk) 16%, transparent);
  border-radius: 50%;
}

.core-anchor-track::before,
.core-anchor-track::after {
  position: absolute;
  border-radius: 50%;
  content: "";
}

.core-anchor-track::before {
  inset: 12%;
  border: 1px dashed color-mix(in srgb, var(--chalk) 12%, transparent);
}

.core-anchor-track::after {
  inset: 48%;
  background: var(--torch);
  box-shadow: 0 0 24px color-mix(in srgb, var(--torch) 50%, transparent);
}

.core-anchor-agent {
  position: relative;
  z-index: 3;
  display: grid;
  width: clamp(138px, 18vw, 176px);
  aspect-ratio: 1;
  border: 1px solid var(--torch);
  border-radius: 50%;
  place-items: center;
  background: var(--graphite);
  text-align: center;
}

.core-anchor-agent strong {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  line-height: .9;
  letter-spacing: -.04em;
  color: var(--chalk);
}

.core-anchor-agent strong span { color: var(--torch-bright); }

/* Caption-size on --graphite: raw --torch is 4.32:1 (spec permits it for
   display >=24px only). The `strong span` dot above stays --torch — it IS
   display type at ~2.2rem, which the spec sanctions. */
.core-anchor-agent small {
  display: block;
  margin-top: 10px;
  color: var(--torch-bright);
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  line-height: 1.2;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
}

.core-anchor-marker {
  position: absolute;
  z-index: 4;
  /* Fluid floor, NOT a fixed px one. A flat min-width:116px cannot shrink, so
     on narrow phones the six markers overflowed their stage — the deleted
     580px breakpoint had been masking it by dropping them to 96px. clamp()
     does the same job with no breakpoint (guardrail: ONE at 1000px). */
  min-width: clamp(88px, 24vw, 116px);
  padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--chalk) 16%, transparent);
  border-radius: 3px;
  /* On its own --graphite ground, raw --slate is 2.96:1. --slate-light is
     the dark-ground muted token (6.37:1) — gate A6b. */
  color: var(--slate-light);
  background: var(--graphite);
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  line-height: 1.2;
  letter-spacing: var(--tracking-mono);
  text-align: center;
  text-transform: uppercase;
  /* explicit props only — never transition:all (Deferred Rule 1). This
     lives in critical so the resting marker paints without recalc. */
  transition: border-color 180ms ease, color 180ms ease, transform 180ms ease;
}

.core-anchor-marker::before {
  position: absolute;
  top: -4px;
  left: -4px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  content: "";
  background: var(--slate);
}

.core-anchor-marker.is-active {
  border-color: var(--torch-bright);
  color: var(--chalk);
  transform: scale(1.05);
}

.core-anchor-marker.is-active::before { background: var(--torch); }

/* Insets are clamped, not switched at a breakpoint: on a narrow stage the
   markers need to sit closer to the edge or they collide with the track.
   The deleted 580px block did this by swapping 8% -> 1%. */
.core-anchor-marker-intent    { top: 9%; left: clamp(1%, 4vw, 8%); }
.core-anchor-marker-blueprint { top: 9%; right: clamp(1%, 4vw, 8%); }
.core-anchor-marker-build     { top: 44%; right: 1%; }
.core-anchor-marker-review    { right: clamp(1%, 4vw, 8%); bottom: 8%; }
.core-anchor-marker-live      { bottom: 8%; left: clamp(1%, 4vw, 8%); }
.core-anchor-marker-change    { top: 44%; left: 1%; }

.core-anchor-instrument-foot {
  padding-top: 13px;
  border-top: 1px solid color-mix(in srgb, var(--chalk) 16%, transparent);
}

.core-anchor-readout { color: var(--chalk); }
.core-anchor-governed { color: var(--torch-bright); }


/* MODULE:END core-agent-anchor */

/* ============================================================
   TRADE HERO — Zone 1 for the trade lane (BRIEF-B1-TRADE-TEMPLATE.md
   Rev 2, PART 5). Ported from _source/hero/ (planner-staged mockup),
   corrected on port to this site's spec — the mockup was built against
   the Degrees palette, not this one: #192725 -> graphite token,
   #f0642d -> torch-bright token.

   ⛔ REV 2 REPLACES THE REV 1 COMPOSITION. The B1 Rev 1 build shipped a
   "ghost measuring instrument" dashboard (browser/grid/measure SVG) with
   the page title as the hero's own <h1> — an undeclared design decision
   that failed inspection and was reverted 6 Aug 2026 (H1/H2 ruling,
   SESSION_LOG.md). The approved hero is the ANIMATED LOGO LOCKUP only:
   logo SVG, "Complete Website Management", the five verbs. NO page
   title, NO trade word, NO instrument graphic — identical on all 15
   pages (C2). The brand line is a <p>, never a heading; the page's one
   <h1> lives at the top of the article (Zone 2).

   Shared by every trade page the generator produces (T5: template +
   generator, not 15 hand-maintained files) — class names carry the
   trade-hero- prefix (location-specific: this composition is unique to
   the trade lane, C2).
   ============================================================ */

.zone-trade-hero {
  background-color: var(--graphite);
  color: var(--chalk);
  padding-block: 0;
}

.trade-hero {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: min(100svh, 900px);
  padding-block: clamp(18px, 3vw, 36px);
  overflow: hidden;
}

.trade-hero-meta,
.trade-hero-foot {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  color: var(--slate-light);
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
}

.trade-hero-meta {
  padding-bottom: var(--space-md);
  border-bottom: var(--border-thin) solid color-mix(in srgb, var(--chalk) 14%, transparent);
}

.trade-hero-foot {
  padding-top: var(--space-md);
  border-top: var(--border-thin) solid color-mix(in srgb, var(--chalk) 14%, transparent);
}

.trade-hero-foot span:last-child { color: var(--torch-bright); }

/* --- Brand lockup content (logo + descriptor + five verbs) ---
   Pure template: zero per-trade content, identical on all 15 pages. */

.trade-hero-content {
  position: relative;
  z-index: 2;
  display: grid;
  width: min(1400px, 100%);
  margin: auto;
  justify-items: start;
  text-align: left;
}

.trade-hero-logo-wrap {
  width: min(620px, 48vw);
  min-height: clamp(54px, 10vw, 102px);
}

.trade-hero-logo {
  display: block;
  width: 100%;
  height: auto;
  border: 0;
}

.trade-hero-rule {
  position: relative;
  width: min(540px, 72vw);
  height: var(--border-thin);
  margin: clamp(30px, 5vw, 56px) 0 clamp(24px, 4vw, 42px);
  overflow: hidden;
  background-color: color-mix(in srgb, var(--chalk) 14%, transparent);
}

.trade-hero-rule span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  background-color: var(--torch-bright);
}

/* Brand descriptor — NOT a heading (H2 ruling). The page's one <h1> is
   the article title in Zone 2, not this identical-on-every-page line. */
.trade-hero-brand {
  max-width: 18ch;
  margin: 0;
  color: var(--chalk);
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: var(--font-display-size);
  line-height: 0.98;
  letter-spacing: var(--tracking-tight);
}

.trade-hero-verbs {
  display: flex;
  margin: clamp(22px, 4vw, 38px) 0 0;
  flex-wrap: wrap;
  gap: 0.2em 0.38em;
  color: var(--chalk);
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: clamp(1.15rem, 2.4vw, 2.25rem);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.trade-hero-verbs span { display: inline-block; }

.trade-hero-verbs b {
  color: var(--torch-bright);
  font-weight: var(--weight-medium);
}

.trade-hero-replay {
  position: absolute;
  z-index: 4;
  right: clamp(18px, 3vw, 36px);
  bottom: clamp(50px, 6vw, 66px);
  padding: 7px 0;
  border: 0;
  border-bottom: var(--border-thin) solid var(--slate-light);
  color: var(--chalk);
  background-color: transparent;
  font-family: var(--font-mono);
  font-size: var(--font-caption);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  cursor: pointer;
}

.trade-hero-replay:hover,
.trade-hero-replay:focus-visible {
  border-color: var(--torch-bright);
}

/* --- Animation sequence states, driven by js/trade-hero.js ---
   Initial hidden state + @keyframes ship in critical: this is Zone 1,
   above the fold on every trade page, so a deferred file setting the
   initial opacity would flash-then-hide on first paint (CLS rule). */

.trade-hero.is-ready .trade-hero-logo-wrap,
.trade-hero.is-ready .trade-hero-brand,
.trade-hero.is-ready .trade-hero-verbs span {
  opacity: 0;
}

.trade-hero.is-running .trade-hero-logo-wrap {
  animation: trade-hero-logo-stage 2.45s var(--ease-default) both;
}

.trade-hero.is-running .trade-hero-rule span {
  animation: trade-hero-rule-measure 720ms var(--ease-default) 1.95s both;
}

.trade-hero.is-running .trade-hero-brand {
  animation: trade-hero-copy-rise 620ms var(--ease-default) 2.35s both;
}

.trade-hero.is-running .trade-hero-verbs span {
  animation: trade-hero-copy-rise 460ms var(--ease-default) both;
}

.trade-hero.is-running .trade-hero-verbs span:nth-child(1) { animation-delay: 2.95s; }
.trade-hero.is-running .trade-hero-verbs span:nth-child(2) { animation-delay: 3.08s; }
.trade-hero.is-running .trade-hero-verbs span:nth-child(3) { animation-delay: 3.21s; }
.trade-hero.is-running .trade-hero-verbs span:nth-child(4) { animation-delay: 3.34s; }
.trade-hero.is-running .trade-hero-verbs span:nth-child(5) { animation-delay: 3.47s; }

@keyframes trade-hero-logo-stage {
  0% { opacity: 0; transform: translateY(8px); }
  12%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes trade-hero-rule-measure {
  0% { transform: translateX(-101%); }
  48% { transform: translateX(0); }
  100% { transform: translateX(101%); }
}

@keyframes trade-hero-copy-rise {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .trade-hero.is-ready .trade-hero-logo-wrap,
  .trade-hero.is-ready .trade-hero-brand,
  .trade-hero.is-ready .trade-hero-verbs span {
    opacity: 1;
  }

  .trade-hero.is-running .trade-hero-logo-wrap,
  .trade-hero.is-running .trade-hero-rule span,
  .trade-hero.is-running .trade-hero-brand,
  .trade-hero.is-running .trade-hero-verbs span {
    animation: none;
  }

  .trade-hero-rule span { display: none; }
  .trade-hero-replay { display: none; }
}

/* ============================================================
   PAGE-SPECIFIC 1000px COLLAPSE — must be the LAST rule in this file.
   The shared base cannot hold these: it has to come FIRST so pages
   inherit the system, which means every page rule below it wins on
   load order. Same breakpoint value, different position — the collapse
   lives with what it collapses. (Learned three times, 4 Aug 2026.)
   ============================================================ */

@media (max-width: 1000px) {
  .hero-inner,
  .core-hero-inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .hero-gauge {
    order: -1;
  }

  .solari-board-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.75rem;
  }

  /* Trade hero: below 1000px the brand lockup centres, matching the
     mockup's own 980px behaviour (justified, not carried wholesale —
     PART 5). No instrument graphic in the approved Rev 2 hero, so
     nothing to hide here. */
  .trade-hero-content {
    width: 100%;
    justify-items: center;
    text-align: center;
  }

  .trade-hero-logo-wrap {
    width: min(650px, 82vw);
  }

  .trade-hero-verbs {
    justify-content: center;
  }
}

/* https://www.sitethreesixty.com */
