/* ════════════════════════════════════════════════════════════════════════
   CONTRAST CORRECTIONS ONLY
   ────────────────────────────────────────────────────────────────────────
   This file once also carried a sitewide rail and type scale. Both are
   GONE. They set max-width + margin-inline:auto on a broad set of section
   wrappers, which narrowed every full-width band on the site at once —
   Ethan: "you condensed all the pages", "youre fucking with borders site
   wide youre ruining good sections."

   That was the wrong instrument. Alignment is a per-page judgement about
   which blocks share an edge, not something one selector list can impose
   across twenty pages without wrecking the ones that were already right.

   What stays is the colour work, which fixed 36 unreadable elements and
   touches no geometry: it only ever sets `color` and `background`.
   ════════════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════════════
   THE CONTRAST CORRECTIONS LIVE HERE, NOT IN site.css
   ────────────────────────────────────────────────────────────────────────
   They were written into site.css first and changed nothing: every page
   loads its own stylesheet AFTER site.css, so prod-hero-conform.css,
   tech-proof.css and pricing.css all outranked them at equal specificity.
   The sweep returned an identical 30 before and after, which is the only
   reason it was caught.
   This file is linked last on every page, so corrections belong here.
   ════════════════════════════════════════════════════════════════════════ */
/* ══ THREE COLOUR FAULTS, MEASURED ACROSS EIGHTEEN PAGES ═══════════════
   Ethan: "many pages cant read sections and some colouring issues."
   A contrast sweep — compositing the real painted background down the
   ancestor chain rather than taking the first opaque colour — found 36
   elements under 3:1. They fall into exactly three causes.

   ── A. The light-ground red landed on dark heroes ──────────────────────
   #a4132c is calibrated for bone (6.6:1) and measures 2.55:1 on ink. The
   white-ground rule was recolouring eyebrows inside heroes that are still
   photographic and dark, because those heroes do not all carry .has-photo.
   Named rather than pattern-matched, so a hero that goes light later does
   not silently keep the dark-ground red. */
.stk-hero .eyebrow, .stk-hero [class*="eyebrow"],
.mv-hero  .eyebrow, .mv-hero  [class*="eyebrow"],
.cf-hero  .eyebrow, .cf-hero  [class*="eyebrow"],
.ij-pin   .eyebrow, .ij-pin   [class*="eyebrow"],
.ij-open  .eyebrow, .ij-open  [class*="eyebrow"] {
  color: #e8455a;
}
.stk-hero .eyebrow-rule, .mv-hero .eyebrow-rule,
.cf-hero .eyebrow-rule, .ij-pin .eyebrow-rule, .ij-open .eyebrow-rule {
  background: #e8455a;
}

/* ── B. Ink type on ink panels ─────────────────────────────────────────
   The white-ground rule is specificity 0,3,0 and cascades into dark
   panels that sit inside a light band. /technology's run diagram was the
   worst single case in the sweep: 19 elements at 1.00:1 — every lane and
   every step of "how a change actually reaches production" was black on
   black. These three joined the measured dark-panel list. */
.trun, .csc__chrome, .cs-card__media {
  --on-black: #f5f1e8;
  --on-black-mute: rgba(245,241,232,.58);
  --ink: #0a0a0a;
  --red-text: #e8455a;
  color: var(--on-black);
}
.trun :where(h1,h2,h3,h4,p,li,dt,dd,span,figcaption,code,b,strong),
.csc__chrome :where(h1,h2,h3,h4,p,li,dt,dd,span,figcaption),
.cs-card__media :where(h1,h2,h3,h4,p,li,dt,dd,span,figcaption) {
  color: var(--on-black) !important;
}

/* ── C. Bone type left behind on a ground that turned light ────────────
   Components written for ink whose section has since been converted. They
   keep a hardcoded bone, so they vanish. Corrected at the element rather
   than by another sweeping rule, because each of these is a small, named
   component and a broad selector here is what created cause B. */
.sv-cine--light .sv-duality__link,
.t-light .sv-duality__link { color: rgba(10,10,10,.62); }

.sv-section:not(.has-video):not(.has-photo) > .inner strong,
.sv-section:not(.has-video):not(.has-photo) .btn-cta:not(.btn-cta--red),
.tdx-sec b { color: var(--ink-true, #0a0a0a); }
.sv-section:not(.has-video):not(.has-photo) .btn-cta:not(.btn-cta--red) {
  border-color: rgba(10,10,10,.28);
}

/* Second pass on the sweep. The eyebrow rule above named `.eyebrow`, but
   these heroes use their own class names — .mv-eyebrow, .cf-eyebrow,
   .stk-eyebrow — so the light-ground red stayed on an ink ground at
   2.55:1. Matched on the suffix instead of the exact class. */
[class$="-eyebrow"], [class*="-eyebrow "] { }
.mv-hero [class*="eyebrow"], .cf-hero [class*="eyebrow"],
.stk-hero [class*="eyebrow"], .page-hero [class*="eyebrow"],
.ij-pin [class*="eyebrow"], .ij-open [class*="eyebrow"],
.mv-eyebrow, .cf-eyebrow, .stk-eyebrow { color: #e8455a; }
.mv-hero .eyebrow-rule, .cf-hero .eyebrow-rule, .stk-hero .eyebrow-rule,
.page-hero .eyebrow-rule { background: #e8455a; }

/* .pr-triad__cell measured LIGHT in one sweep and INK in the next, because
   two branches of pricing.css disagree about it. Rather than keep flipping
   the type to chase it, the cell is pinned LIGHT — which is the side the
   rest of the page is on, and the side Ethan has asked for five times. */
.pr-triad__cell {
  background: var(--bone, #faf8f3);
  --ink: #0a0a0a;
  --on-black: #0a0a0a;
}
.pr-triad__cell,
.pr-triad__cell :where(h1,h2,h3,h4,p,li,dt,dd,span,figcaption) {
  color: var(--ink-true, #0a0a0a) !important;
}
.pr-triad__cell .pr-triad__p { color: rgba(10,10,10,.68) !important; }
.pr-triad__cell .pr-triad__num { color: #a4132c !important; }

/* ── Third pass. Specificity, again. ───────────────────────────────────
   The white-ground eyebrow rule is
     main > section:not():not():not() :where(.eyebrow,[class*="eyebrow"])
   which is 0,3,0. The corrections above were 0,2,0 and lost silently —
   the sweep total did not move, which is the only reason it was caught.
   These are written to outrank it rather than to argue with it. */
main .mv-hero [class*="eyebrow"],
main .cf-hero [class*="eyebrow"],
main .stk-hero [class*="eyebrow"],
main .ij-pin [class*="eyebrow"],
main .ij-open [class*="eyebrow"],
main .page-hero [class*="eyebrow"] { color: #e8455a !important; }

main .mv-hero .eyebrow-rule, main .cf-hero .eyebrow-rule,
main .stk-hero .eyebrow-rule, main .page-hero .eyebrow-rule { background: #e8455a !important; }

/* The run diagram on /technology: nineteen elements at 1.00:1 — every lane
   and every step of "how a change actually reaches production" was black on
   black. The ink ground is painted by the SECTION, not by .trun, so keying
   on .trun never reached them. */
/* The section carrying it has NO class — it is #tech-run — so :has(.trun)
   matched nothing and all nineteen elements stayed black on black. */
main #tech-run :where(h1,h2,h3,h4,p,li,dt,dd,span,figcaption,b,strong),
main [class^="trun__"], main [class*=" trun__"] { color: #f5f1e8 !important; }
main #tech-run .trun__step--gate { color: #e8455a !important; }

/* One bold run left bone on a light band. */
/* Scoped away from .tdx-stage: the first cut of this rule put ink on the
   dark instrument slabs and turned 17 readable elements into black on
   black — a bigger fault than the single one it was fixing. */
main .tdx-sec :not(.tdx-stage) > b,
main .tdx-sec :not(.tdx-stage) > strong { color: var(--ink-true, #0a0a0a); }
main .tdx-stage b, main .tdx-stage strong,
main .app__phone b, main .app__phone strong { color: #f5f1e8 !important; }

/* ── /tech's hero film ──────────────────────────────────────────────
   The last section on the estate that would not come onto the rail, and
   it turned out not to be an alignment problem at all.

   tech-readable.css declares `.stk-hero__film { position: absolute;
   inset: 0 }`, which is plainly the intent — its two siblings,
   .stk-hero__ground and .stk-scene, are both absolute backdrops. But
   /tech never loads tech-readable.css. So the <video> stayed in flow as
   a 1160px flex item, took the whole line, and pushed the hero copy to
   x=1300 in a 1440 viewport: the H1, the eyebrow and the lede were all
   off the right-hand edge of the screen. It measured 1480 before this
   file existed, so it is not a regression from the rail — the rail just
   moved it 180px left and made it the last outlier standing.

   Declared here because the rail is loaded on every page and the fix has
   to survive whatever the /tech stylesheets do; tech-stack-hero.css and
   tech-expertise.css both load after it. */
main .stk-hero > video.stk-hero__film {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}

/* ── The staircase in S.01 on /technology ──────────────────────────────
   Took the slot of the drawn location plate. Contained, capped, and cut
   with the same chamfer the plate carried so the section's shape language
   does not change. */
.tp-op__stair { margin: 0; }
.tp-op__stair img {
  display: block;
  width: 100%;
  height: auto;
  max-height: clamp(280px, 34vw, 460px);
  object-fit: cover;
  object-position: center 45%;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 34px), calc(100% - 34px) 100%, 0 100%);
}
.tp-op__stair .tp-op__addr {
  margin: .9rem 0 0;
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sys-mute-light, rgba(10,10,10,.62));
}
@media (max-width: 620px) {
  .tp-op__stair img { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%); }
}

/* ── Citadel's capture must be seen whole ──────────────────────────────
   Ethan: "the displays for citadel arent sized down cant see the
   screenshot properly." The walkthrough pans and scales into a region of
   the capture, which is right when a step is describing one corner of a
   UI — but the two steps here are DARK and LIGHT, which are statements
   about the whole screen. So this instance shows the whole screen. */
#tech-citadel .swk__viewport { aspect-ratio: 1600 / 1025; height: auto; max-height: none; }
#tech-citadel .swk__shot {
  position: absolute; inset: 0;
  width: 100% !important; height: 100% !important;
  max-height: none !important;
  object-fit: contain !important;
  transform: none !important;
}

/* ── /tech's closing handoff, centred ──────────────────────────────────
   Ethan pointed at the two blocks that send you to THE FIRM and to CASE
   STUDIES: "needs to be centred". They were left-set against a rail that
   nothing else at the foot of the page shares, so the page ended on two
   ragged columns hanging off the left edge. */
.tdx-handoff {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.6rem, 4vw, 3.4rem);
  text-align: center;
}
.tdx-handoff .tdx-more {
  flex: 0 1 min(100%, 30rem);
  margin-inline: auto;
  text-align: center;
}
.tdx-handoff .tdx-more p { margin-inline: auto; max-width: 42ch; }

/* ── Fourth pass, after tech-readable.css was re-linked ────────────────
   Re-linking that stylesheet changed which panels are dark, so the
   measured list moved again. .tdx-row__clip is ink once more — 71
   elements at 1.00:1 on /tech, the whole expanded body of every
   capability row. This is why the list is re-measured after every change
   rather than treated as settled. */
.tdx-row__clip,
.tdx-row__clip :where(h1,h2,h3,h4,p,li,dt,dd,span,figcaption,a,b,strong,code) {
  color: #f5f1e8 !important;
}
.tdx-row__clip a { color: #e8455a !important; }
.tdx-row__clip .tdx-proofline { color: rgba(245,241,232,.72) !important; }

/* /technology: the S.03 caption and the device chrome label. */
.tps__cap { color: rgba(245,241,232,.7) !important; background: transparent !important; }
.swk__chrome-title { color: rgba(245,241,232,.62) !important; }

/* The production hero's eyebrow — prod-hero-conform.css loads after this
   file on that page, so it needs to say so. */
.cf-hero .cf-eyebrow, .cf-hero [class*="eyebrow"] { color: #e8455a !important; }

/* ════════════════════════════════════════════════════════════════════════
   S.03 ON /technology — the agent-system section
   ────────────────────────────────────────────────────────────────────────
   Ethan: "no photo is supposed to be in the black, and fix its scale, it's
   distorted and way too large."

   Two faults, one cause. tech-proof.css styles .tps__img and .tps__fig but
   knows nothing about .tps__frame — the wrapper the photograph now sits in
   — so the image had NO width, NO height cap and NO object-fit and rendered
   at whatever the grid column gave it. That is the distortion and the size.

   And .tps declares `background:#0a0a0a` from when this was a dark band, so
   the photograph was sitting on ink. The section goes light: the copy is
   the argument, the photograph is evidence beside it, and neither reads on
   black.
   ════════════════════════════════════════════════════════════════════════ */
.tps {
  background: var(--bone, #faf8f3) !important;
  --ink: #0a0a0a;
  --on-black: #0a0a0a;
  --on-black-mute: rgba(10,10,10,.68);
  --on-black-faint: rgba(10,10,10,.6);
  --red-text: #a4132c;
  align-items: center;
}
.tps .sv-h2, .tps .sv-lede, .tps .tps__spec,
.tps :where(h1,h2,h3,h4,p,li,span) { color: #0a0a0a; }
.tps .sv-lede, .tps .tps__spec li { color: rgba(10,10,10,.68); }
.tps .sv-h2 em { color: #a4132c; }
.tps .eyebrow { color: #a4132c; }
.tps .eyebrow-rule { background: #a4132c; }
.tps .tps__spec li span { color: #0a0a0a; font-weight: 500; }

.tps__fig { margin: 0; min-height: 0; display: block; }

.tps__frame {
  display: block;
  width: min(100%, 560px);
  margin-inline: auto;
  overflow: hidden;
  border: 1px solid rgba(10,10,10,.14);
}
.tps__frame img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  object-position: center 44%;
}

.tps__cap {
  display: block;
  width: min(100%, 560px);
  margin: .85rem auto 0 !important;
  padding: 0 !important;
  background: none !important;
  border: 0 !important;
  font-family: var(--font-mono);
  font-size: .62rem;
  line-height: 1.55;
  letter-spacing: .04em;
  color: rgba(10,10,10,.62) !important;
}

@media (max-width: 900px) {
  .tps__frame, .tps__cap { width: 100%; }
}

/* ── A scrim with nothing left to scrim ────────────────────────────────
   Ethan: "consulting and market entry is covering the section, there's
   some sort of layer over it."

   .section-bg-overlay is the gradient that sits between a section's
   background video and its type. When the sipping-orange video was removed
   from /firm's consulting band and the section became .sv-cine--light, the
   overlay div stayed in the markup — absolutely positioned, z-index 1,
   over a band that no longer has any background media. Confirmed with
   elementsFromPoint on the heading's own centre: the overlay is the
   topmost element, above .sv-h2.

   Hidden wherever the band is light, since a light band has nothing behind
   its type to darken. */
.sv-cine--light > .section-bg-overlay,
.t-light > .section-bg-overlay,
.fs-lite > .section-bg-overlay,
.tp-lite > .section-bg-overlay,
.pr-light > .section-bg-overlay { display: none; }

/* ── /sister's Labs screen was sliced mid-row ──────────────────────────
   site.css caps img[src*="/gallery/systems/"] at
   clamp(280px, 34vw, 440px) with object-fit: cover. That is an attribute
   selector, (0,1,1), so `.lab-proof__shot` (0,1,0) never beat it and the
   support-ticket table was cut through the middle of a row — you could
   read half of "Cannot upload profile picture" and nothing under it.

   The cap is there to stop a bare screenshot dominating a page. This one
   is inside a bordered frame that IS the containment, so the cap is
   restated at two-class specificity and the capture shows whole.

   Same fault, same fix, third place tonight: the attribute selector wins
   against any single class, so a component holding one of these captures
   has to say so explicitly. */
.lab-proof__frame .lab-proof__shot {
  max-height: none;
  height: auto;
  object-fit: contain;
}

/* The eyebrow and the heading were sharing a line and colliding. */
.lab-proof__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .55rem;
}

/* ════════════════════════════════════════════════════════════════════════
   PHOTO CAPTIONS ARE HIDDEN FROM VIEW, NOT DELETED
   ────────────────────────────────────────────────────────────────────────
   Ethan: "remove the description text on all the photos on the site from
   visibility."

   Hidden with clip-path rather than display:none on purpose. The captions
   are the only place several of these photographs are described in words,
   and that description is what a search engine and a screen reader read.
   Deleting them would cost real indexing on a site we are about to run an
   SEO pass over, and would strip the page for anyone using assistive
   technology, to fix a purely visual complaint.

   So they stay in the document, stay in the accessibility tree, and stop
   being painted.

   EXCLUDED, because these are UI labels rather than descriptions of a
   photograph: the walkthrough step captions, which say which screen of an
   application you are looking at, and the device chrome titles.
   ════════════════════════════════════════════════════════════════════════ */
figcaption:not(.swk__cap):not(.csc__cap):not(.apv__cap) {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ════════════════════════════════════════════════════════════════════════
   MOBILE READABILITY FLOOR
   ────────────────────────────────────────────────────────────────────────
   Measured at 390x844 across eighteen pages: no page scrolls sideways, but
   several carry real sentences below 11px — /tech had 51 such elements,
   /pricing 24, /technology 23. Fine on a 27-inch monitor, unreadable on a
   phone held at arm's length.

   So on phones, anything carrying a SENTENCE gets a floor of 15px, and the
   mono labels that are meant to be small get 11px. Applied only under
   640px, so nothing about the desktop layout moves.

   Excluded: the eyebrow/kicker classes and the numeric badges, which are
   typographic marks rather than reading matter.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* :where() is specificity ZERO, so the first cut of this rule lost to
     every component stylesheet and the counts did not move at all. Stated
     with real selectors and !important — a readability floor is exactly the
     case where a leaf override is correct. */
  main p, main li, main dd, main dt, main blockquote {
    font-size: max(0.9375rem, 1em) !important;
    line-height: 1.6;
  }
  main .eyebrow, main [class*="eyebrow"], main [class*="__kind"],
  main [class*="__label"], main [class*="__num"], main [class*="__cap"] {
    font-size: max(0.6875rem, 1em) !important;
  }
  /* Tables and ledgers keep tabular figures legible without reflowing. */
  main .pz__row-l, main .pz__row-v, main .tools-cell__use {
    font-size: max(0.875rem, 1em) !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   MOBILE, SECOND PASS
   ────────────────────────────────────────────────────────────────────────
   Ethan: "mobile technology page is disaster." Screenshotted at 390 and
   looked at. Three faults, and one of them was mine.

   1. MY OWN TYPE FLOOR OVERSHOT. The 15px minimum was written for prose
      and matched every <p> and <li>, including MONOSPACE labels — so
      "HOW A CHANGE ACTUALLY REACHES PRODUCTION" set at 15px mono in caps
      and wrapped to two enormous lines, and every step label in the run
      diagram did the same. Mono is a label face here, not reading matter.
   2. The run diagram is a five-column grid. At 390 each column is ~68px,
      so every label wraps to three lines and the whole thing is a mess.
   3. Photographs still run edge to edge on this page.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* Mono is a label face. Exempt it from the prose floor and give it its
     own, smaller one. */
  main p[class*="__k"], main p[class*="label"], main li[class*="step"],
  main [class*="trun__"], main .tdx-stage__rail, main .swk__num,
  main [style*="var(--font-mono)"] {
    font-size: max(0.72rem, 0.72rem) !important;
    letter-spacing: .06em;
  }

  /* The run diagram stacks: one row per stage instead of five columns. */
  #tech-run .trun__lane { grid-template-columns: 1fr !important; }
  #tech-run .trun__lanes { gap: 1.4rem; }
  #tech-run .trun__step {
    display: flex; align-items: baseline; gap: .6rem;
    padding: .35rem 0;
    border-bottom: 1px solid rgba(245,241,232,.12);
  }
  #tech-run .trun__label { font-size: .72rem !important; letter-spacing: .1em; }

  /* Nothing edge to edge. Ethan's standing rule. */
  main img:not([class*="apv__"]):not([class*="swk__"]):not([class*="lpin"]):not([class*="__shot"]) {
    max-width: calc(100% - 2rem);
    margin-inline: auto;
  }
  main figure:not([class*="apv"]):not([class*="swk"]) > img { max-width: 100%; }
  main .tcw, main .tps__frame, main .u-full, main .u-band { padding-inline: 1rem; }

  /* Terence is a 72px disc on a 390px screen with a shadow past that. */
  #tnaado-chat-btn { transform: scale(.72); transform-origin: bottom right; }
}
