/* ==========================================================================
   Vizora — refinement layer. Loaded last; overrides site.css.
   Each block below exists because the benchmark said so, not because it
   looked nice in isolation.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Colour — one accent, everything else derived.
   Tinted near-black ladder (each step carries a faint warm cast, 3-5 lightness
   units apart), and a SEPARATE border ramp. Borders must never be sampled from
   the background ramp; that is what makes a dark UI look flat.
   -------------------------------------------------------------------------- */
:root{
  --accent: oklch(0.62 0.17 38);            /* ember, in perceptual space */

  --bg-900:#0b0d11;  --bg-800:#101317;  --bg-700:#151920;  --bg-600:#1b2029;

  --line-1: rgb(255 255 255 / .055);        /* structural hairline */
  --line-2: rgb(255 255 255 / .10);         /* card edge */
  --line-3: rgb(255 255 255 / .17);         /* hover / active */

  /* derived interaction states — no hand-picked hover colours */
  --accent-hi:   color-mix(in oklab, var(--accent) 86%, white);
  --accent-lo:   color-mix(in oklab, var(--accent) 86%, black);
  --accent-wash: color-mix(in oklab, var(--accent) 11%, transparent);
  --accent-edge: color-mix(in oklab, var(--accent) 30%, transparent);

  /* radius BY ROLE — a single radius on everything is a template tell */
  --r-chip: 999px;
  --r-sm:   7px;     /* inputs, small tiles */
  --r:      11px;    /* cards */
  --r-lg:   18px;    /* large panels, figures */

  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}

.night, .hero, .site-foot, .cta-band{ background-color: var(--bg-900); }
.night .card, .ui-shell, .zones-read{ background: var(--bg-800); border-color: var(--line-2); }
.night .card:hover{ border-color: var(--line-3); }

/* --------------------------------------------------------------------------
   2. Type — three voices, and a display size that actually commits.
   Award sites run display type to 96-130px; capping at 60px is the difference
   between a headline and a heading.
   -------------------------------------------------------------------------- */
h1{
  font-size: clamp(2.3rem, 1.15rem + 4.6vw, 4.6rem);
  letter-spacing: -.035em;
  line-height: 1.02;
}
h2{ font-size: clamp(1.6rem, 1.12rem + 1.95vw, 2.7rem); letter-spacing:-.028em; line-height:1.08; }

/* text-wrap, site-wide. balance is capped at ~6 lines so it stays off body copy. */
h1, h2, h3, h4, .lede, blockquote, .sec-head p, figcaption{ text-wrap: balance; }
p, li, dd, .card p, .muted{ text-wrap: pretty; }

/* every number, part number, address and unit is mono + tabular.
   This one change is what makes a site read as technical. */
.code, .num, .zone-tag, .mono, .stats .k, .stats .l,
table.data td.n, .ui-tile .val, .ui-row .tm, .pill{
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* --------------------------------------------------------------------------
   3. Masking — no media, rail or panel ends on a hard rectangle edge.
   Eased stops, because a straight two-stop gradient bands visibly.
   -------------------------------------------------------------------------- */
.mask-b{
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0/.985) 46%,
    rgb(0 0 0/.88) 63%, rgb(0 0 0/.55) 79%, rgb(0 0 0/.15) 91%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0/.985) 46%,
    rgb(0 0 0/.88) 63%, rgb(0 0 0/.55) 79%, rgb(0 0 0/.15) 91%, transparent 100%);
}
/* Only fade the edges where the table genuinely scrolls. Above this width it
   fits, and the mask was dimming the first and last column for no reason. */
@media (max-width: 900px){
  .table-scroll{
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14px calc(100% - 14px), transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 14px calc(100% - 14px), transparent 100%);
  }
}
.cat-tabs{
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 10px calc(100% - 10px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 10px calc(100% - 10px), transparent 100%);
}
.ui-shell, .zones-read{ border-radius: var(--r-lg); }
.hero-viz svg, .zones-fig svg{
  -webkit-mask-image: linear-gradient(to bottom, #000 82%, rgb(0 0 0/.35) 95%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 82%, rgb(0 0 0/.35) 95%, transparent 100%);
}

/* --------------------------------------------------------------------------
   4. Grid — asymmetric splits. A 50/50 two-column is the default nobody chose.
   -------------------------------------------------------------------------- */
.split-37{ display:grid; grid-template-columns:minmax(0,3fr) minmax(0,7fr); gap:clamp(24px,3.4vw,60px); align-items:start; }
.split-73{ display:grid; grid-template-columns:minmax(0,7fr) minmax(0,3fr); gap:clamp(24px,3.4vw,60px); align-items:start; }
.split-52{ display:grid; grid-template-columns:minmax(0,5fr) minmax(0,2fr); gap:clamp(24px,3.4vw,60px); align-items:start; }
@media (max-width:860px){
  .split-37,.split-73,.split-52{ grid-template-columns:1fr; gap:28px; }
}

/* cards in a row share baselines instead of each finding its own height */
@supports (grid-template-rows: subgrid){
  .pgrid{ grid-auto-rows: auto; }
  .pcard{ display:grid; grid-row:span 2; grid-template-rows:subgrid; }
}

/* --------------------------------------------------------------------------
   5. Surface — a dark panel gets layers, never one flat fill.
   -------------------------------------------------------------------------- */
.night .card, .ui-shell, .zones-read, .cta-band{ position:relative; isolation:isolate; }
.night .card::before, .cta-band::before{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background: radial-gradient(120% 86% at 50% 0%, rgb(255 255 255/.045), transparent 64%);
}

/* the ember accent, used once per section rather than everywhere */
.card-rule{ border-left-color: var(--accent); }
.btn-primary{ background: var(--accent); }
.btn-primary:hover{ background: var(--accent-hi); }
.btn-primary:active{ background: var(--accent-lo); }
.pill-ember{ background: var(--accent-wash); color: var(--accent); border:1px solid var(--accent-edge); }

/* --------------------------------------------------------------------------
   6. View transitions — a real multi-page static site gets these for two lines.
   -------------------------------------------------------------------------- */
@view-transition{ navigation: auto; }
@media (prefers-reduced-motion: no-preference){
  ::view-transition-old(root){ animation: vt-out 160ms linear both; }
  ::view-transition-new(root){ animation: vt-in  220ms cubic-bezier(.16,1,.3,1) both; }
}
@keyframes vt-out{ to  { opacity:0 } }
@keyframes vt-in { from{ opacity:0; transform:translateY(6px) } }

/* --------------------------------------------------------------------------
   7. Detail — hairline ticks so the eye has something crisp to land on.
   -------------------------------------------------------------------------- */
.stats{ border-radius: var(--r-lg); }
.stats > div{ position:relative; }
.stats > div::before{
  content:""; position:absolute; top:12px; left:12px; width:5px; height:5px;
  border-left:1px solid var(--line-3); border-top:1px solid var(--line-3);
}
.eyebrow{ letter-spacing:.17em; }


/* --------------------------------------------------------------------------
   8. Reasons list — replaces a row of three identical icon cards, which the
   benchmark names as the single most recognisable generated-layout tell.
   Rules and numerals instead of boxes; the content is a sequence, so it is
   numbered, and the numbering means something.
   -------------------------------------------------------------------------- */
.reasons{ margin:0; counter-reset:r; }
.reasons > div{
  counter-increment:r;
  position:relative;
  padding:26px 0 26px 58px;
  border-top:1px solid var(--line-1);
}
.reasons > div:last-child{ border-bottom:1px solid var(--line-1); }
.reasons > div::before{
  content:counter(r,decimal-leading-zero);
  position:absolute; left:0; top:27px;
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.06em;
  color:var(--accent);
}
.reasons dt{
  font-family:var(--display); font-weight:600; font-size:1.06rem;
  color:#fff; margin-bottom:7px; letter-spacing:-.018em;
}
.reasons dd{ margin:0; color:#9ba5b4; font-size:.94rem; max-width:62ch; }

@media (max-width:560px){
  .reasons > div{ padding-left:44px; }
}


/* --------------------------------------------------------------------------
   9. DARK SURFACES — all of them, not just .night
   .hero, .cta-band and .site-foot are dark too. Scoping the overrides to
   .night alone left .btn-ghost at color:var(--ink) on a near-black ground —
   1.07:1, effectively invisible. One :is() group now covers every dark
   surface so this class of bug cannot recur.
   -------------------------------------------------------------------------- */
:is(.night, .hero, .heroX, .cta-band, .site-foot){ color:#b9c0cc; }
:is(.night, .hero, .heroX, .cta-band, .site-foot) :is(h1,h2,h3,h4){ color:#fff; }
:is(.night, .hero, .heroX, .cta-band, .site-foot) a:not(.btn){ color:#ffb387; }

:is(.night, .hero, .heroX, .cta-band, .site-foot) .btn-ghost{
  color:#fff;
  border-color:rgb(255 255 255 / .22);
  background:transparent;
}
@media (hover:hover) and (pointer:fine){
  :is(.night, .hero, .heroX, .cta-band, .site-foot) .btn-ghost:hover{
    background:rgb(255 255 255 / .07);
    border-color:rgb(255 255 255 / .40);
    color:#fff;
  }
}

:is(.night, .hero, .heroX, .cta-band, .site-foot) :is(.muted, .lede, .sec-head p,
  .card p, .step p, .crumb, .crumb a, .pill-line, table.data td.n){ color:#9ba5b4; }
:is(.night, .hero, .heroX, .cta-band, .site-foot) .pill-line{ border-color:rgb(255 255 255 / .22); }
:is(.night, .hero, .heroX, .cta-band, .site-foot) .eyebrow{ color:var(--ember-2); }
:is(.night, .hero, .heroX, .cta-band, .site-foot) .eyebrow::before{ background:var(--ember-2); }
:is(.night, .hero, .heroX, .cta-band, .site-foot) .card .num{ color:var(--ember-2); }
:is(.night, .hero, .heroX, .cta-band, .site-foot) .notice{
  background:rgb(226 86 29 / .12); color:#f0c3aa; border-left-color:var(--ember-2);
}
:is(.night, .hero, .heroX, .cta-band, .site-foot) .notice strong{ color:#ffd9c6; }
:is(.night, .hero, .heroX, .cta-band, .site-foot) .notice-plain{
  background:rgb(255 255 255 / .05); color:#9ba5b4; border-left-color:rgb(255 255 255 / .22);
}
:is(.night, .hero, .heroX, .cta-band, .site-foot) .notice-plain strong{ color:#fff; }

/* --------------------------------------------------------------------------
   10. BRAND MARKS — optical sizing, not one height for all.
   Teledata's artwork is 189x70 (wide); Vighnaharta's is 115x132 (tall).
   A shared height:40px rendered them 108x40 and 35x40 — which is why one
   looked tiny. Each is now sized to a comparable optical AREA instead.
   -------------------------------------------------------------------------- */
.brands{ gap: clamp(28px, 6vw, 84px); align-items:center; }
.brands a{ display:flex; align-items:center; justify-content:center; }
.brands img{
  width:auto; opacity:.9;
  transition: opacity var(--dur-2, 200ms) var(--ease-out, ease),
              transform var(--dur-2, 200ms) var(--ease-out, ease);
}
.brand-wide{ height: clamp(40px, 5.4vw, 58px); }   /* Teledata — 2.7:1 */
.brand-tall{ height: clamp(62px, 8.2vw, 88px); }   /* Vighnaharta — 0.87:1 */
@media (hover:hover) and (pointer:fine){
  .brands a:hover img{ opacity:1; transform:translateY(-2px); }
}

/* white wordmark on dark — replaces the brightness(0) invert(1) hack, which
   flattens a five-colour pentagon into a white blob */
.foot-brand img{ filter:none; height:34px; opacity:.95; }


/* real photography sits in the same tile as the illustrations — same ratio,
   same padding, same floor line, so a mixed row still reads as one object */
.pshot{
  max-width:100%; max-height:100%; width:auto; object-fit:contain;
  position:relative; z-index:1; padding:2px;
  transition:transform var(--dur-2,200ms) var(--ease-out,ease);
}
@media (hover:hover) and (pointer:fine){
  .pcard:hover .pshot{ transform:translateY(-3px) scale(1.035); }
}


/* --------------------------------------------------------------------------
   11. BRAND PRESENCE
   These two marks are the business. They were rendering at 108x40 and 35x40 —
   postage stamps. Now they sit in a proper band, on their own plate, at a size
   that reads across a room, still optically balanced against each other.
   -------------------------------------------------------------------------- */
.brand-band{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:clamp(18px,2.4vw,32px); align-items:stretch;
}
.brand-plate{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:18px; padding:clamp(28px,3.4vw,44px) clamp(20px,2.6vw,34px);
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg);
  text-decoration:none !important;
  transition:border-color var(--dur-2,200ms) var(--ease-out,ease),
             box-shadow var(--dur-2,200ms) var(--ease-out,ease),
             transform var(--dur-2,200ms) var(--ease-out,ease);
}
@media (hover:hover) and (pointer:fine){
  .brand-plate:hover{ border-color:var(--line-strong); box-shadow:var(--lift-3); transform:translateY(-3px); }
}
.brand-plate img{ width:auto; display:block; }
.brand-plate .bp-wide{ height:clamp(58px, 7vw, 86px); }    /* Teledata 2.7:1 */
.brand-plate .bp-tall{ height:clamp(96px, 11vw, 136px); }  /* Vighnaharta 0.87:1 */
.brand-plate .bp-role{
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-3); text-align:center; line-height:1.5;
}
.brand-plate .bp-role b{ color:var(--ink); font-weight:600; display:block; letter-spacing:.06em; }

/* --------------------------------------------------------------------------
   12. Fixes found by actually looking at the rendered page
   -------------------------------------------------------------------------- */

/* Footer links were inheriting the dark-surface link colour, so every one of
   them rendered ember. The accent must not do that much work. */
.site-foot a{ color:#b9c0cc; }
.site-foot a:hover{ color:#fff; }
.site-foot .foot-bottom a{ color:#8a93a2; }
.site-foot .foot-bottom a:hover{ color:#fff; }
.foot-brand img{ height:44px; }

/* Brand plate caption: constrain the measure so it stops orphaning words */
.brand-plate .bp-role{ max-width:30ch; text-wrap:balance; }
.brand-plate{ gap:22px; min-height:250px; }

/* Section rhythm — one scale, no arbitrary values, and a tighter band between
   a section and the one that continues its thought. */
section{ padding-block: clamp(64px, 4.2vw + 42px, 112px); }
.sec-tight{ padding-block: clamp(44px, 2.8vw + 28px, 72px); }
section + section.bone,
section.bone + section{ padding-block-start: clamp(56px, 3.4vw + 34px, 92px); }

/* The hero was carrying dead space below the stats. */
.hero{ padding-block: clamp(56px, 3.6vw + 34px, 92px) clamp(48px, 3vw + 28px, 76px); }
.hero .stats{ margin-top: clamp(34px, 3.4vw, 56px); }

/* The building is the product — give it room rather than floating it small. */
.hero-split{ grid-template-columns: minmax(0,1fr) minmax(0,1.05fr); gap: clamp(26px,3.2vw,52px); }
/* no transform: scaling from the right edge pushed the basement out of the
   column. The figure simply gets a wider track and fills it. */
.hero-viz{ width:100%; }
.hero-viz svg{
  -webkit-mask-image: linear-gradient(to bottom, #000 90%, rgb(0 0 0/.55) 97%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 90%, rgb(0 0 0/.55) 97%, transparent 100%);
}
@media (max-width: 980px){
  .hero-viz{ transform:none; }
  .hero-split{ grid-template-columns:1fr; }
}

/* CTA band was left-weighted with a large empty right side. */
.cta-band{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:clamp(24px,4vw,64px); align-items:center; }
.cta-band > .eyebrow{ grid-column:1; }
.cta-band h2{ grid-column:1; margin-bottom:.4em; }
.cta-band p{ grid-column:1; }
.cta-band .btn-row{ grid-column:2; grid-row:1 / span 3; margin-top:0; flex-direction:column; align-items:stretch; }
.cta-band .btn{ justify-content:center; }
@media (max-width: 760px){
  .cta-band{ grid-template-columns:1fr; }
  .cta-band .btn-row{ grid-column:1; grid-row:auto; flex-direction:row; margin-top:24px; }
}

/* consistent gutters for the two card-pair sections */
.grid.g-2{ gap: clamp(18px, 2.2vw, 30px); }

/* contact page: the two-column grid was an inline style with no breakpoint,
   so it stayed 2-up below 500px and pushed the page 67px wider than the
   viewport. Now it collapses like every other grid on the site. */
.contact-grid{
  display:grid;
  grid-template-columns:minmax(0,1.25fr) minmax(0,.95fr);
  gap:clamp(24px,3.2vw,46px);
}
@media (max-width:860px){ .contact-grid{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   13. Balance found by looking at the rendered ACMS page
   -------------------------------------------------------------------------- */
/* the drawing was small against a tall readout — give it the larger track and
   let both sides share a height */
.zones{ grid-template-columns:minmax(0,1.25fr) minmax(0,.9fr); align-items:stretch; }
.zones-fig{ display:flex; flex-direction:column; justify-content:center; }
.zones-read{ display:flex; flex-direction:column; }
.zones-list{ flex:1; max-height:none; }
@media (max-width:900px){
  .zones{ grid-template-columns:1fr; }
  /* width:100% is load-bearing. margin-inline:auto cancels a grid item's
     stretch, so without it the figure fell back to the SVG's default
     intrinsic 300px — the drawing rendered at 300px inside a 779px column
     on every tablet and phone, which is what crushed its labels to 6.5px. */
  .zones-fig{ width:100%; max-width:560px; margin-inline:auto; }
}

/* hero button rows: keep two actions on one line wherever they genuinely fit */
.hero .btn-row{ gap:10px; }
.hero .btn{ padding-inline:20px; }
@media (min-width:1100px){
  .hero-copy .btn-row{ flex-wrap:nowrap; }
  .hero-copy .btn{ white-space:nowrap; }
}

/* the figure caption sat too far from its drawing */
.zones-fig .illus-note{ margin-top:10px; }

/* ==========================================================================
   14. Section patterns that replace the repeated three-card row.
   Each is chosen by what the content actually IS — a sequence, a comparison,
   a citation, an annotation — rather than one blanket substitute.
   ========================================================================== */

/* --- A. FLOW: three stages that follow one another ----------------------- */
.flow{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:0; }
.flow > div{ position:relative; padding:0 clamp(16px,2vw,30px); }
.flow > div + div{ border-left:1px solid var(--line-1); }
.flow > div:first-child{ padding-left:0; }
.flow > div:last-child{ padding-right:0; }
.flow .st{
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.14em; text-transform:uppercase;
  color:#8a93a2; display:flex; align-items:center; gap:9px; margin-bottom:14px;
}
.flow .st::before{
  content:""; width:7px; height:7px; border-radius:50%;
  background:var(--line-3); flex:none;
}
.flow > div:last-child .st{ color:var(--ember-2); }
.flow > div:last-child .st::before{ background:var(--ember-2); }
.flow h3{ font-size:1.06rem; margin-bottom:.45em; }
.flow p{ font-size:.93rem; margin:0; }
@media (max-width:820px){
  .flow{ grid-template-columns:1fr; }
  .flow > div{ padding:22px 0; }
  .flow > div + div{ border-left:0; border-top:1px solid var(--line-1); }
}

/* --- B. KEYED NOTES: annotations tied to rows of a table ------------------ */
.keyed{ display:grid; gap:0; }
.keyed > div{
  display:grid; grid-template-columns:132px minmax(0,1fr);
  gap:clamp(16px,2.4vw,38px); align-items:start;
  padding:24px 0; border-top:1px solid var(--line-1);
}
.keyed > div:last-child{ border-bottom:1px solid var(--line-1); }
.keyed .k{
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ember-2); padding-top:3px;
}
.keyed h3{ font-size:1.06rem; margin-bottom:.4em; }
.keyed p{ margin:0; font-size:.94rem; max-width:64ch; }
@media (max-width:640px){
  .keyed > div{ grid-template-columns:1fr; gap:8px; }
}

/* --- C. CITATION STRIP: the legal facts, set like a record ---------------- */
.facts{
  border:1px solid var(--line-1); border-radius:var(--r-lg); overflow:hidden;
}
.facts > div{
  display:grid; grid-template-columns:minmax(150px,.9fr) minmax(0,2.6fr);
  gap:clamp(16px,2.6vw,40px); padding:22px clamp(18px,2.4vw,30px);
}
.facts > div + div{ border-top:1px solid var(--line-1); }
.facts dt{
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.13em; text-transform:uppercase;
  color:#8a93a2;
}
.facts dd{ margin:0; }
.facts dd h3{ font-size:1.04rem; margin-bottom:.35em; }
.facts dd p{ margin:0; font-size:.94rem; }
.facts dd .more{ display:inline-block; margin-top:11px; font-size:.9rem; }
@media (max-width:700px){ .facts > div{ grid-template-columns:1fr; gap:10px; } }

/* --- D. SEQUENCE: a process in order -------------------------------------- */
.seq{ counter-reset:q; display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(20px,2.6vw,38px); }
.seq > div{ counter-increment:q; position:relative; padding-top:46px; }
.seq > div::before{
  content:counter(q,decimal-leading-zero);
  position:absolute; top:0; left:0;
  font-family:var(--mono); font-size:0.78rem; color:var(--ember);
  padding-bottom:12px; border-bottom:2px solid var(--ember); width:34px;
}
.seq > div::after{
  content:""; position:absolute; top:calc(.74rem + 12px); left:34px; right:0; height:2px;
  background:var(--line);
}
.seq > div:last-child::after{ background:transparent; }
.seq h3{ font-size:1.06rem; margin-bottom:.45em; }
.seq p{ margin:0; font-size:.93rem; }
@media (max-width:820px){ .seq{ grid-template-columns:1fr; } .seq > div::after{ display:none; } }

/* --- E. GAS COMPARISON TABLE ---------------------------------------------- */
.gas-cmp th:first-child, .gas-cmp td:first-child{ width:132px; }
.gas-cmp .gname{ font-family:var(--display); font-weight:600; color:var(--ink); font-size:1.02rem; }
.gas-cmp .where{ font-family:var(--mono); font-size:0.78rem; letter-spacing:.06em; color:var(--ember); text-transform:uppercase; }

/* --- F. CHAIN NOTES: properties of the signal chain, read as annotations
       under the drawing rather than as three floating cards ---------------- */
.chain-notes{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,2.6vw,40px); margin-top:clamp(28px,3vw,44px);
  padding-top:clamp(24px,2.6vw,36px); border-top:1px solid var(--line-1);
}
.chain-notes h3{ font-size:1.02rem; margin-bottom:.45em; }
.chain-notes h3::before{
  content:""; display:block; width:26px; height:2px; background:var(--ember);
  margin-bottom:14px;
}
.chain-notes p{ margin:0; font-size:.93rem; }
@media (max-width:860px){ .chain-notes{ grid-template-columns:1fr; gap:26px; } }

/* --- G. PLATFORM POINTS: labelled columns beside the interface ----------- */
.plat{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(18px,2.4vw,34px); margin-top:clamp(30px,3.2vw,46px); }
.plat > div{ padding:22px 0 0; border-top:2px solid var(--line-2); }
.plat > div:first-child{ border-top-color:var(--ember); }
.plat .pk{
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.14em; text-transform:uppercase;
  color:#8a93a2; display:block; margin-bottom:10px;
}
.plat h3{ font-size:1.02rem; margin-bottom:.45em; }
.plat p{ margin:0; font-size:.92rem; }
@media (max-width:860px){ .plat{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   15. Surface-adaptive rules.
   The new section patterns were drawing their dividers with --line-1, which is
   a white alpha — correct on a dark band, invisible on a light one. A single
   --rule token now follows whichever surface the pattern sits on.
   -------------------------------------------------------------------------- */
:root{ --rule: var(--line); --rule-strong: var(--line-strong); }
:is(.night, .hero, .heroX, .cta-band, .site-foot){ --rule: rgb(255 255 255 / .10); --rule-strong: rgb(255 255 255 / .20); }

.facts{ border-color: var(--rule); }
.facts > div + div{ border-top-color: var(--rule); }
.flow > div + div{ border-left-color: var(--rule); }
.keyed > div{ border-top-color: var(--rule); }
.keyed > div:last-child{ border-bottom-color: var(--rule); }
.chain-notes{ border-top-color: var(--rule); }
.plat > div{ border-top-color: var(--rule-strong); }
.plat > div:first-child{ border-top-color: var(--ember); }
.reasons > div{ border-top-color: var(--rule); }
.reasons > div:last-child{ border-bottom-color: var(--rule); }
.seq > div::after{ background: var(--rule); }

/* labels inside these patterns follow the surface too */
.facts dt, .flow .st, .plat .pk{ color: var(--ink-3); }
:is(.night, .hero, .cta-band) :is(.facts dt, .flow .st, .plat .pk){ color:#8a93a2; }
.keyed .k{ color: var(--ember); }
:is(.night, .hero, .cta-band) .keyed .k{ color: var(--ember-2); }
@media (max-width:820px){ .flow > div + div{ border-top-color: var(--rule); } }

/* --------------------------------------------------------------------------
   16. Accessible accent for small text on light surfaces.
   The brand ember (#e2561d) measures 3.76:1 on white — fine for a button fill
   with white text on it, too weak for small type. Small accent text on a light
   ground uses the darker step; large display accents keep the brand value.
   -------------------------------------------------------------------------- */
:root{ --ember-text: #c44712; }   /* 4.93:1 on white */

.keyed .k,
.seq > div::before,
.reasons > div::before,
.card .num,
.pill-ember,
.prose a,
.facts dd .more,
.pcard .code{ color: var(--ember-text); }

.seq > div::before{ border-bottom-color: var(--ember-text); }

/* on dark surfaces the brighter step is correct and already passes */
:is(.night, .hero, .heroX, .cta-band, .site-foot) :is(.keyed .k, .card .num, .pcard .code,
  .facts dd .more, .prose a){ color: var(--ember-2); }


/* --------------------------------------------------------------------------
   17. Larger diagram labels made the zone readout overflow its panel — the
   tenth row was being clipped. The panel now sizes to its content and the two
   columns align at the top instead of being forced to equal height.
   -------------------------------------------------------------------------- */
.zones{ align-items:start; }
.zones-read{ height:auto; }
.zones-list{ max-height:none; overflow:visible; }
@media (min-width:901px){
  .zones-fig{ position:sticky; top:96px; }
}

/* ==========================================================================
   18. Fixes from the visual QA pass
   ========================================================================== */

/* A two-column card that never collapsed. At 390px the text column squeezed to
   ~150px (one word per line) and the nowrap button was pushed off-screen,
   dragging the whole page sideways. */
.split-cta{
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(18px,2.4vw,28px); align-items:center;
}
.split-cta > .btn{ white-space:nowrap; }
@media (max-width:760px){
  .split-cta{ grid-template-columns:1fr; gap:20px; }
  .split-cta > .btn{ white-space:normal; justify-self:start; }
}

/* --- the signal chain, now HTML so the copy wraps instead of clipping --- */
.chain{ margin:0; }
.chain-row{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:14px;
}
.chain-row li{
  position:relative; padding:20px 18px;
  background:var(--bg-800); border:1px solid var(--line-2); border-radius:12px;
}
.chain-row li.is-key{ border-color:var(--ember); }
.chain-row li + li::before{           /* the connector */
  content:""; position:absolute; left:-10px; top:50%; width:6px; height:1px;
  background:var(--line-3);
}
.chain-row .cn{
  font-family:var(--mono); font-size:0.78rem; color:var(--ember-2);
  display:block; margin-bottom:10px;
}
.chain-row h3{ font-size:1rem; margin:0 0 .4em; color:#fff; }
.chain-row p{ margin:0; font-size:.88rem; color:#9ba5b4; }
.chain-cap{
  margin-top:18px; font-family:var(--mono); font-size:0.78rem; letter-spacing:.1em;
  text-transform:uppercase; color:#8a93a2; text-align:center;
}
@media (max-width:1000px){ .chain-row{ grid-template-columns:repeat(2,minmax(0,1fr)); } 
  .chain-row li + li::before{ display:none; } }
@media (max-width:560px){ .chain-row{ grid-template-columns:1fr; } }

/* --- the hero monitored-points list, now HTML ---------------------------- */
.pts{ margin:0; background:var(--bg-800); border:1px solid var(--line-2); border-radius:var(--r-lg); padding:22px; }
.pts-h{
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.12em; text-transform:uppercase;
  color:#8a93a2; margin:0 0 16px;
}
.pts-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:2px; }
.pts-list li{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:12px; align-items:center;
  padding:11px 14px; background:var(--bg-700); border-radius:9px;
  font-size:.9rem; color:#dfe4ec;
}
.pts-list i{ width:9px; height:9px; border-radius:50%; display:block; }
.pts-list b{ font-family:var(--mono); font-size:.8rem; color:#8a93a2; font-weight:400; }
.pts-tot{
  display:flex; justify-content:space-between; align-items:baseline;
  margin:16px 0 0; padding-top:14px; border-top:1px solid var(--line-2);
  font-family:var(--mono); font-size:0.78rem; letter-spacing:.1em; text-transform:uppercase; color:#8a93a2;
}
.pts-tot b{ color:var(--ember-2); font-family:var(--display); font-size:1.05rem; letter-spacing:-.01em; }

/* Product copy was being clamped to 3 lines and cut mid-word ("interlockin…")
   even where there was room. Let it run; the subgrid keeps the row aligned. */
.pcard p{
  -webkit-line-clamp:unset; line-clamp:unset;
  display:block; overflow:visible;
}

/* Wide tables scroll horizontally on a phone, but nothing said so — on the
   applicability page the entire threshold column was off-screen with no hint. */
@media (max-width:900px){
  .table-scroll{ position:relative; }
  .table-scroll::after{
    content:"Scroll \2192";
    position:sticky; left:0; bottom:0; display:block;
    padding:7px 14px; font-family:var(--mono); font-size:0.78rem;
    letter-spacing:.1em; text-transform:uppercase;
    color:var(--ink-3); background:var(--bone); border-top:1px solid var(--line);
  }
  table.data{ min-width:560px; }
}

/* Orphan card: 5 items in a 4-up grid left one alone on row two. */
@media (min-width:901px){
  .g-4:has(> :nth-child(5):last-child){ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

/* The hero stage changed height on every tab click (272 / 363 / 337px). */
@media (min-width:1041px){
  .stage-in{ min-height:330px; display:flex; flex-direction:column; justify-content:center; }
}

/* The primary CTA looked disabled on contact.html because it was the current
   page. A current-page CTA should still read as the primary action. */
.nav .btn-primary[aria-current="page"]{ background:var(--accent); color:#fff; }

/* The footer used the colour logo, whose 'visionary and forward thinking'
   tagline is dark grey and illegible on the near-black footer. */
.foot-brand img{ height:44px; opacity:1; }

/* ==========================================================================
   19. Accessibility fixes from the audit
   ========================================================================== */

/* C4 — the primary CTA failed contrast on all 14 pages. White on the brand
   ember #e2561d is 3.76:1, and on the oklch accent #d8582e it was 3.92:1;
   the label is 15.7px/560, which is not "large text", so 4.5:1 applies.
   The fill darkens to 4.93:1. The brand ember is kept for rules, borders,
   dots and fills that carry no text. */
:root{ --accent: #c44712; --ember-text: #a8410f; }
.btn-primary{ background:var(--accent); color:#fff; }
.btn-primary:hover{ background:#b03f13; }
.btn-primary:active{ background:#98380e; }

/* C5 — the focus ring was #e2561d on a #d8582e button: 1.04:1, invisible.
   A two-tone ring always keeps one half visible on any ground. */
:focus-visible{
  outline:2px solid #fff;
  outline-offset:2px;
  box-shadow:0 0 0 4px #14161a;
  border-radius:4px;
}
:is(.night,.hero,.heroX,.cta-band,.site-foot) :focus-visible{
  outline-color:#14161a;
  box-shadow:0 0 0 4px #fff;
}

/* I9 — --ink-3 was 4.48:1 on the bone ground: 0.02 short of AA. */
:root{ --ink-3:#61697a; }

/* I6 — the filter-tab count was 10.1px at 62% opacity = 3.46:1. */
.cat-tab .n{ font-size:.86em; opacity:1; color:#61697a; }
.cat-tab[aria-selected="true"] .n{ color:rgb(255 255 255/.72); }

/* I5 — dim label greys inside the dark diagrams. */
.zones-hint{ color:#8a93a2; }
.zone-tag{ fill:#8a93a2; }

/* I10 — the scrollable table could not be reached by keyboard. */
.table-scroll:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* I7 — touch targets. None failed AA's 24px floor, but these were under the
   44px design guideline and are the main controls on the site. */
.btn{ padding-block:15px; }
.cat-tab{ padding-block:12px; }
.burger{ width:44px; height:44px; }
.site-foot li a{ display:inline-block; padding-block:6px; }

/* M2 — the breadcrumb separator was 1.97:1; it is decoration, so hide it. */
.crumb span{ color:#61697a; }

/* M7 — view transitions should respect the motion preference. */
@media (prefers-reduced-motion: reduce){
  ::view-transition-old(root), ::view-transition-new(root){ animation:none !important; }
}

/* ==========================================================================
   20. Contrast, round two — measured, not assumed
   ========================================================================== */

/* The header CTA was rendering #3d424b on #c44712: 2.05:1, effectively
   unreadable. `.nav a` is (0,1,1) and `.btn-primary` is (0,1,0), so the nav's
   link colour beat the button's own rule on every page. Raise the button above
   its container instead of hoping source order saves it. */
.nav a.btn-primary,
.nav a.btn-primary:hover,
.nav a.btn-primary:focus,
.site-head a.btn-primary{ color:#fff; }
.nav a.btn-ghost{ color:var(--ink); }

/* --ember #e2561d measures 3.76:1 on white — it is a fill colour, not a text
   colour. Every place it was being used as type now takes --ember-text
   (#a8410f, 6.13:1). The brand value still paints rules, dots, borders and
   button fills, where 3:1 is the bar. */
a{ color:var(--ember-text); }
.eyebrow,
.crumb a:hover,
.gas-cmp .where,
.keyed .k,
.pill-ember,
.sec-head .k,
.stat .v,
.role,
.post .tag{ color:var(--ember-text); }
.eyebrow::before{ background:var(--ember-text); }

/* ...and on dark grounds that same value is invisible, so the dark group takes
   the light ember instead. #f97316 is 6.6:1 on #0b0d11. */
/* Split deliberately. :is() takes the specificity of its MOST specific
   argument, so folding `.keyed .k` in here made the whole selector (0,3,0)
   and it beat the button's own rule — which is how the CTA ended up orange
   text on an orange fill at 1.76:1. Single-class members only. */
:is(.night,.hero,.heroX,.cta-band,.site-foot) :is(a, .eyebrow, .pill-ember,
  .role){ color:var(--ember-2); }
:is(.night,.hero,.heroX,.cta-band,.site-foot) .keyed .k,
:is(.night,.hero,.heroX,.cta-band,.site-foot) .stat .v,
:is(.night,.hero,.heroX,.cta-band,.site-foot) .gas-cmp .where{ color:var(--ember-2); }
:is(.night,.hero,.heroX,.cta-band,.site-foot) a.btn-primary{ color:#fff; }
:is(.night,.hero,.heroX,.cta-band,.site-foot) a.btn-ghost{ color:#fff; }

/* .num was #6d7686 on bone: 4.07:1 */
.num, .seq .num, .step .num{ color:#5a6273; }
:is(.night,.hero,.heroX,.cta-band,.site-foot) :is(.num, .seq .num, .step .num){ color:var(--ember-2); }

/* The button label is white on every ground, full stop. This is the fourth
   time a container's colour has leaked into it; the specificity here is
   deliberately above anything that can wrap it. */
.btn-primary, .btn-primary .arrow,
:is(.night,.hero,.heroX,.cta-band,.site-foot) :is(a, button).btn-primary,
:is(.night,.hero,.heroX,.cta-band,.site-foot) .btn-primary .arrow,
.nav :is(a, button).btn-primary{ color:#fff; }

/* The contact detail blocks moved from h4 to h3 to close a heading-level skip.
   They are labels, not section heads, so the level changed and the size did not. */
.contact-row h3{ font-size:1.02rem; margin:0 0 .2em; }

/* ==========================================================================
   21. Brand plates — the caption was a label pretending to be a sentence
   The measurement said 12.5px and passed. It still read as tiny, because a
   full descriptive sentence was set in uppercase mono at .13em letter-spacing
   inside a ~20-character column, so it broke into five cramped lines in the
   middle of a mostly empty card. Micro-caps are for two-word labels. This is
   a sentence, so it is now set as one.
   ========================================================================== */
.brand-plate{
  min-height:0;
  gap:clamp(20px,2.2vw,30px);
  padding:clamp(32px,3.2vw,44px) clamp(26px,3vw,40px);
}
.brand-plate .bp-role{
  font-family:var(--body, inherit);
  font-size:clamp(.94rem, .9rem + .18vw, 1.02rem);   /* 15 - 16.3px */
  font-weight:400;
  letter-spacing:normal;
  text-transform:none;
  line-height:1.6;
  color:var(--ink-2);
  max-width:38ch;          /* two lines, not five */
  text-wrap:pretty;
}
.brand-plate .bp-role b{
  display:block;
  margin-bottom:7px;
  font-family:var(--display);
  font-size:clamp(1.06rem, 1rem + .34vw, 1.3rem);
  font-weight:600;
  letter-spacing:-.005em;
  color:var(--ink);
}

/* These two names are the business. The Teledata mark is vector and the
   Vighnaharta one is now 591x620 from their own letterhead, so both can
   finally be drawn at a size that reads as a partnership rather than a
   footnote. The old PNG was 115x132 being stretched to 136px tall. */
.brand-plate .bp-wide{ height:clamp(74px, 8.6vw, 112px); }   /* 2.70:1 */
.brand-plate .bp-tall{ height:clamp(116px, 13.2vw, 168px); } /* 0.95:1 */

/* ==========================================================================
   22. Sentences that were wearing label clothes
   All of these measured 12.5px and passed a numeric check, but uppercase
   removes the word-shape cues a reader uses, mono narrows every glyph, and
   heavy tracking pulls the letters apart — so they READ at roughly 8-9px.
   A micro-caps label is for two or three words. Each of these is a sentence,
   an instruction or a heading, so each is now set as one.
   ========================================================================== */

/* "One-way: status flows out of the building. No command flows back in."
   68 characters — this is the safety boundary, the most important sentence
   on the page, and it was the least readable thing on it. */
.chain-cap{
  font-family:var(--body, inherit);
  font-size:clamp(.92rem, .88rem + .16vw, 1rem);
  letter-spacing:normal; text-transform:none;
  line-height:1.6; color:#9ba5b4;
  max-width:56ch; margin-inline:auto; text-wrap:pretty;
}

/* "Illustrative interface — representative layout, example values."
   This is the honesty disclaimer on the screenshots. It has to be legible. */
.illus-note{
  font-family:var(--body, inherit);
  font-size:.88rem; letter-spacing:normal; text-transform:none;
  line-height:1.55;
  color:var(--ink-3);                       /* 5.5:1 on the light grounds */
}
/* It sits on a dark figure on acms.html, where --ink-3 is 3.1:1. Setting one
   flat colour here is what broke it the first time. */
:is(.night,.hero,.heroX,.cta-band,.site-foot) .illus-note,
.zones-fig .illus-note,
.diagram .illus-note{ color:#9ba5b4; }

/* "Choose a level on the drawing" — an instruction. If the reader cannot
   read it, the interactive building looks broken rather than interactive. */
.zones-hint{
  font-family:var(--body, inherit);
  font-size:.92rem; letter-spacing:normal; text-transform:none;
  line-height:1.55; color:#9ba5b4;
}

/* "Seventh Schedule — monitored points" is a heading, not a tag. */
.pts-h{
  font-family:var(--display);
  font-size:clamp(.98rem, .94rem + .2vw, 1.08rem);
  font-weight:600; letter-spacing:-.005em; text-transform:none;
  color:#c9d1dc; margin:0 0 16px;
}

/* The eyebrow genuinely IS a micro-label, so it keeps the treatment — but
   2.12px of tracking on a 12.5px face was pulling it apart. */
.eyebrow{ font-size:.82rem; letter-spacing:.12em; }
