/* ══════════════════════════════════════════════════════════════════════════
   /tech — READABILITY LAYER (T-1142, 2026-08-14)

   Ethan, on the page as it stood: "the page you cant read any of it,
   sections are too big and too dark."

   Both halves of that are true and they have one cause: every section on
   this page was authored as light type on #0a0a0a, so the whole page is one
   long light-on-dark read, and the sections were sized for a dark poster
   rather than for reading.

   WHAT CHANGES
   ------------
   1. The four PROSE sections get a bone ground and ink type. Reading
      happens on light.
   2. Black stops being the page and becomes SEPARATION: the hero, the
      photograph band, the open expertise panels and the closing CTA. It is
      now used for shading and for the console surfaces, which is what it is
      good at.
   3. Sections get shorter — the hero stops defeating its own height cap,
      the photograph band steps down a size, and the section padding comes
      in about a third.

   HOW IT IS DONE — READ THIS BEFORE EDITING
   -----------------------------------------
   NOT with a global `body` rule. That was tried earlier tonight and it
   broke the desktop layout: the full-bleed section backdrops inherited the
   light ground and the page came apart. It was reverted.

   Instead, each section REDEFINES THE TOKENS IT ALREADY CONSUMES.
   css/tech-expertise.css is disciplined about this — nearly every colour in
   it resolves through --on-black / --tdx-mute / --tdx-dim / --tdx-line /
   --red-text — so flipping a section is a matter of redeclaring six custom
   properties on that section, not of rewriting its selectors. The dark
   values are then re-declared AGAIN inside the open panel, which is a dark
   island sitting in a light section.

   --ink is deliberately NOT redefined. It is the panel/console ground and
   several parts inherit it; redefining it would turn the consoles light
   too. The section's own background is set explicitly instead.

   RED ON BONE. --red-text is #e8455a, tuned for small red type on ink. On
   bone it measures 3.3:1 and fails. The light sections use #b3001b, which
   measures 7.4:1 on #faf8f3. The eyebrows on this page have shipped at
   1.00:1 before — that is the bug this line exists to prevent.

   This file loads LAST on /tech and touches nothing outside it.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · THE FOUR PROSE SECTIONS GO LIGHT ──────────────────────────────── */
.tdx-live,
.tdx-dir,
.tdx-build,
.tdx-handoff {
  background: var(--bone);

  --on-black:       #0a0a0a;
  --on-black-mute:  rgba(10, 10, 10, .74);
  --on-black-faint: rgba(10, 10, 10, .68);
  --tdx-mute:       rgba(10, 10, 10, .76);
  --tdx-dim:        rgba(10, 10, 10, .68);
  --tdx-line:       rgba(10, 10, 10, .17);
  --tdx-line-soft:  rgba(10, 10, 10, .10);
  --red-text:       #b3001b;
}

/* The rule between two light sections would be invisible at the old alpha,
   and the page needs the seam to keep its structure legible. */
.tdx-dir,
.tdx-build,
.tdx-handoff { border-top: 1px solid rgba(10, 10, 10, .14); }

/* ── 2 · SECTIONS GET SHORTER ──────────────────────────────────────────── */

/* Vertical padding came in from 5.2rem to 3.4rem at the top of the clamp.
   Four sections, both ends: ~115px off the page at 1440. */
.tdx-sec { padding: clamp(2.4rem, 4vw, 3.4rem) 0; }
.tdx-dir__head { margin-bottom: clamp(1.3rem, 2.2vw, 1.8rem); }

/* THE HERO WAS DEFEATING ITS OWN CAP. site.css caps .stk-hero at
   clamp(360px, 46vw, 560px) — but this hero also carried min-height:72svh,
   and when min-height and max-height conflict CSS resolves in favour of
   min-height. So the cap was dead and the hero measured 648px at a 900px
   window. The cap is not being changed; the min-height is being brought
   under it so the cap can do its job.

   DESKTOP ONLY, and that is not a nicety. The cap's clamp bottoms out at
   360px, which is its value for every phone — 46vw of 390px is 179px. A
   360px hero cannot hold this hero's stacked mobile copy: a three-line
   headline, a three-line lede and two stacked buttons. Lowering min-height
   at 390px let the cap apply for the first time and it clipped every word
   out of the hero, leaving the film and the slab and nothing to read.
   Measured, not reasoned about — the first capture after this change had an
   empty hero.

   So below 940px the hero keeps a content-driven floor, which is what it
   had before tonight. The cap has never been operative at that width. */
@media (min-width: 940px) {
  .stk-hero { min-height: clamp(360px, 44vw, 540px); }
}

/* MOBILE: THE HERO HAD NO WORDS IN IT. Pre-existing, and confirmed against
   the base branch before touching it — at 390px the hero measured 360px in
   both builds, and the eyebrow, the headline, the lede and both buttons were
   all clipped out of it. The film and the slab were the entire hero.

   Cause: the cap's clamp bottoms out at 360px on any phone (46vw of 390px is
   179px), the hero is display:block with min-height:0 at this width, and its
   own content wants about 790px. overflow:hidden did the rest.

   Neither end of that is right. 360px shows nothing; 790px is 94% of an
   iPhone screen, which is the full-viewport hero this site has been pulling
   away from all week. So the cap is lifted at this width ONLY and the
   hero's own padding is brought in instead, which lands it near 480px —
   every word readable, and a little over half the screen. */
@media (max-width: 939px) {
  .stk-hero {
    max-height: none;
    min-height: 0;
    padding: clamp(2.6rem, 9vw, 3.6rem) 0 clamp(2.2rem, 7vw, 3rem);
  }
  /* With the copy restored, the slab was the thing making the hero 88% of
     the screen. 248px -> 168px keeps the object plainly legible (it is seven
     plates, not a detailed thing) and brings the hero to about 70%. */
  .stk-scene { height: 168px; }
}

/* The photograph band steps from --band-lg to --band-md. It is still the
   largest photograph on the page, which is correct — it is the only
   photograph left on the page. */
.tdx-live__figure img { height: var(--band-md); }

/* ── 2b · THE HERO FILM ────────────────────────────────────────────────── */
/* Takes over the slot the desk photograph held, and inherits its treatment
   rather than inventing one: same absolute fill, same right-74% mask on
   desktop so the headline and lede sit on clean ground, same pull-back under
   940px where the film runs full bleed and the scrim carries legibility from
   the bottom up. That combination is already tuned for this copy; the only
   thing changed is what is behind it.

   Opacity runs higher than the photograph's .78 because the film is already
   near-black — it is a dark room, not a lit desk, so it needs less holding
   down to keep the type off it.

   The poster is painted as a CSS background by js/lazy-video.js, so under
   reduced motion and under 768px (where no video bytes are ever fetched)
   this element still shows a frame instead of an empty box. */
.stk-hero__film {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-height: clamp(360px, 46vw, 540px);
  object-fit: cover;
  object-position: 50% 52%;
  z-index: 0;
  opacity: .9;
  pointer-events: none;
  background-color: #0a0a0a;
}
@media (min-width: 940px) {
  .stk-hero__film {
    left: auto; right: 0;
    width: 74%;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.4) 15%, #000 38%);
            mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.4) 15%, #000 38%);
  }
}
@media (max-width: 939px) {
  .stk-hero__film { opacity: .55; }
}

/* ── 3 · THE ROW TRIGGERS, ON LIGHT ────────────────────────────────────── */
/* These three carried hardcoded light values that do not survive the flip:
   a white hover name and a near-white hover wash both vanish on bone. */
@media (hover: hover) and (pointer: fine) {
  .tdx-dir .tdx-row__btn:hover { background-color: rgba(10, 10, 10, .045); }
  .tdx-dir .tdx-row__btn:hover .tdx-row__name { color: #000; }
  .tdx-dir .tdx-row__btn:hover .tdx-row__line { color: rgba(10, 10, 10, .82); }
}

/* ── 4 · THE OPEN PANEL IS A DARK ISLAND ───────────────────────────────── */
/* The five demos are console surfaces — real policy syntax, Stripe statuses,
   migration filenames, a live row table. Code reads correctly on dark and
   this is where black earns its place on the page. The clip wrapper takes
   the ground (it is the element that actually has height when open), and
   the body re-declares the dark token set so every hardcoded
   rgba(245,241,232,…) inside the panel keeps meaning what it meant. */
.tdx-dir .tdx-row__clip { background: var(--ink); }

.tdx-dir .tdx-row__body {
  padding-top: clamp(1.5rem, 2.8vw, 2.2rem);

  --on-black:       #f5f1e8;
  --on-black-mute:  rgba(245, 241, 232, .58);
  --on-black-faint: rgba(245, 241, 232, .52);
  --tdx-mute:       rgba(245, 241, 232, .62);
  --tdx-dim:        rgba(245, 241, 232, .52);
  --tdx-line:       rgba(245, 241, 232, .10);
  --tdx-line-soft:  rgba(245, 241, 232, .06);
  --red-text:       #e8455a;
}

/* The open row's left signal bar sat against ink; on bone it needs to read
   as the seam between the light trigger and the dark panel below it. */
.tdx-dir .tdx-row[data-open="1"] { background: rgba(10, 10, 10, .035); }

/* ── 5 · THE REVIEW GATE (replaces the third laptop photograph) ─────────── */
/* The page carried three separate laptop photographs. The hero's is now the
   film; this section's has been replaced by the object below; the founder
   walking a client through a build survives as the one photograph on the
   page. This is a designed element, not a picture of a screen: the three
   gates every generated change passes before it merges, which is the exact
   claim the three columns above it make. */
.tdx-gate {
  margin: clamp(1.8rem, 3.2vw, 2.6rem) 0 0;
  background: var(--ink);
  border-left: 2px solid var(--red);
  padding: clamp(1.3rem, 2.4vw, 1.8rem) clamp(1.2rem, 2.4vw, 2rem);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.4vw, 2.2rem);
}
.tdx-gate__step { min-width: 0; }
.tdx-gate__k {
  display: block;
  font-family: var(--font-mono);
  font-size: .58rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #e8455a;
  margin: 0 0 .5rem;
}
.tdx-gate__t {
  display: block;
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .02em;
  color: #f5f1e8;
  margin: 0 0 .35rem;
}
.tdx-gate__d {
  margin: 0;
  font-family: var(--font-body);
  font-size: .76rem;
  line-height: 1.55;
  color: rgba(245, 241, 232, .66);
}
@media (max-width: 700px) {
  .tdx-gate { grid-template-columns: 1fr; gap: 1.1rem; }
}

/* ── 6 · HANDOFF, ON LIGHT ─────────────────────────────────────────────── */
/* PRE-EXISTING BUG, fixed here because it is one line and it is the last
   thing on the page before the CTA: `.tdx-more { padding: 1.2rem 0 }` is a
   shorthand, so it resets the padding-inline that `.tdx-sec > *` had set,
   and it wins on source order. Both handoff rows were running flush to the
   viewport edge — the "THE FIRM →" link was touching the right edge of the
   screen. Restores the section gutter without touching the vertical rhythm. */
.tdx-handoff .tdx-more { padding-inline: var(--tdx-gut); }

.tdx-handoff .tdx-more p { color: rgba(10, 10, 10, .8); }
.tdx-handoff .tdx-more p b { color: #0a0a0a; }
.tdx-handoff .tdx-link { color: #0a0a0a; }
.tdx-handoff .tdx-link:hover { color: #b3001b; }
