/* WeInfer production overrides.
   Loaded last, after the approved-motion3 baseline. The baseline CSS is a
   vendored artifact and stays untouched; every deviation lives here so the
   derivation from the original design stays auditable.
   Layer order: tokens -> base -> components -> pages -> pages-fixed
                -> pages-motion2 -> pages-motion3 -> weinfer */

/* ---------------------------------------------------------------------------
   1. Hero legibility.
   The baseline sized its scrim for a hero whose lower half was covered by a
   docked product window. We removed that window, so the copy now sits over
   open sky and the lede and note lost contrast. Deepen the wash through the
   copy band only; the panorama below stays untouched.
--------------------------------------------------------------------------- */
.hero .hero-wash {
  background:
    linear-gradient(180deg,
      rgba(6, 24, 62, 0.44) 0%,
      rgba(6, 24, 62, 0.30) 26%,
      rgba(6, 24, 62, 0.12) 46%,
      rgba(6, 24, 62, 0) 62%),
    radial-gradient(78% 46% at 50% 4%, rgba(9, 32, 80, 0.30), transparent 64%);
}

.hero .hero-lede {
  color: #fff;
  text-shadow: 0 2px 16px rgba(7, 22, 52, 0.55);
}

/* The stealth note lands on the shoreline, the brightest band in the panorama,
   where no amount of text-shadow holds up. Give it the same glass treatment the
   design already uses for the eyebrow and proof chips. */
.hero .hero-platform {
  color: #fff;
  font-size: var(--text-small);
  max-width: 46ch;
  padding: 7px 15px;
  border-radius: var(--r-pill);
  background: rgba(6, 24, 62, 0.34);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(10px);
  text-shadow: 0 1px 4px rgba(7, 22, 52, 0.6);
}

.hero .hero-proof-row li {
  background: rgba(6, 24, 62, 0.34);
  border-color: rgba(255, 255, 255, 0.28);
  backdrop-filter: blur(10px);
}

/* ---------------------------------------------------------------------------
   2. Hero height: one viewport, no dead band.

   The baseline hero ran about 1260px: a 760px scene plus a ~500px Peine del
   Viento bridge band. That band existed to sit BEHIND the docked product
   window. With the window gone it was half a screen of empty water with a
   sculpture in one corner, and its flat-filled right side was the source of
   the tonal seam this file previously documented as unfixable.

   Dropping the band solves both. The scene now ends at one viewport height,
   and the panorama's own bottom mask (pages-fixed.css fades its last 120px to
   transparent) hands off to the hero's background gradient. That gradient was
   always the designed fallback for exactly this case; pages.css calls it
   "the no-SVG fallback" in its own comment.

   100dvh rather than 100vh so the iOS Safari address bar does not shift it.
--------------------------------------------------------------------------- */
.hero-bridge {
  display: none;
}

.hero {
  --hero-h: 100dvh;
  /* Sky above the panorama only. The image now runs to the hero's bottom edge,
     so nothing below it needs painting. */
  background: linear-gradient(180deg, #0F83D8 0%, #178ADC 60%);
}

.hero-scene {
  min-height: var(--hero-h);
}

/* The frame was locked to aspect-ratio 2/1 and anchored to the bottom, which
   made sense when the bridge band sat below it. Now that the hero is one
   viewport, a fixed aspect leaves a sliver of bare gradient at some window
   sizes. Let it fill the hero and let object-fit do the cropping, which holds
   at any viewport. object-position keeps the bay anchored low, so the crop
   comes off the sky rather than the water. */
.scene-frame {
  inset: 0;
  aspect-ratio: auto;
}

/* The baseline faded the panorama's last 110px to transparent so it could
   crossfade into the bridge illustration's sea. With the bridge gone there is
   nothing underneath to fade into, and the fade only washed out the bottom of
   the bay. Keep the top fade, which blends into the sky gradient, and let the
   image meet the section below on a clean edge. */
.scene-frame img.hero-base {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 150px, #000 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 150px, #000 100%);
}

/* Narrow screens: the panorama is a wide crop, so a full viewport of it leaves
   the copy floating. Give the scene a little less and let content set the rest. */
@media (max-width: 640px) {
  .hero {
    --hero-h: 92dvh;
  }
  .hero-scene {
    min-height: var(--hero-h);
    padding-bottom: 40px;
  }
}
/* The section that follows the hero previously carried a negative top margin to
   claw back the dead space the bridge band left behind. The bridge is gone and
   the hero is now exactly one viewport, so that lift would drag this section's
   background up over the bottom of the panorama. It stays flush. */
.hero + .section,
.hero + .section-tight {
  padding-top: clamp(56px, 6vw, 96px);
  position: relative;
  z-index: 1;
  background: var(--bg-page);
}

/* ---------------------------------------------------------------------------
   3. Closing card.
   Its display heading sits directly on the photographic backdrop. Strengthen
   the existing overlay so the line reads at every viewport width.
--------------------------------------------------------------------------- */
/* The baseline's `.closing > *` rule gives .closing-art z-index 1, which paints
   the photograph ABOVE the ::after scrim, so the scrim has no visible effect.
   Drop the art back to the base layer; ::after then darkens it, and the copy
   (still z-index 1) stays above both. */
.closing .closing-art {
  z-index: 0;
  opacity: 0.78;
}

.closing::after {
  background:
    radial-gradient(72% 58% at 50% 56%, rgba(6, 22, 60, 0.55), transparent 78%),
    linear-gradient(180deg, rgba(10, 30, 74, 0.58), rgba(8, 26, 66, 0.68));
}

.closing h2 {
  text-shadow: 0 2px 6px rgba(6, 20, 52, 0.7), 0 4px 26px rgba(6, 20, 52, 0.5);
}

/* The lead line under the heading sits on the brightest part of the sunset. */
.closing h2 + p {
  color: #fff !important;
  font-size: var(--text-body);
  text-shadow: 0 1px 4px rgba(6, 20, 52, 0.85), 0 2px 14px rgba(6, 20, 52, 0.6);
}

/* ---------------------------------------------------------------------------
   2b. Scene elements that no longer match the artwork.

   The boat and the sun overlays were positioned in CSS percentages against the
   old 2:1 bottom-anchored frame. Now that the panorama fills the hero and
   crops with object-fit, those coordinates no longer land where the artwork
   expects: the boat sat on the promenade rather than the water, and the sun's
   rays radiated from a point offset from the painted disc.

   The markup copies are deleted from index.html. This hides the sailboat that
   the runtime injects from la-concha-overlay-*.svg, which cannot be deleted
   from markup. The sun that remains is the one painted into the panorama,
   which carries its own glow and is aligned with itself by construction.
--------------------------------------------------------------------------- */
.hero-art .scene-overlay #sailboat {
  display: none;
}

/* ---------------------------------------------------------------------------
   3a. Reveal safety.

   base.css sets `.reveal { opacity: 0 }` and only site.js ever adds `.is-in`.
   If that script fails to load, 404s, or throws, every revealed element stays
   invisible and the page renders blank. The head sets `html.js` inline before
   any of this, so the hidden state now applies only when scripting is alive.
   No JS means no animation and fully visible content, which is the correct
   failure direction for a page whose job is to exist when someone checks us.
--------------------------------------------------------------------------- */
html:not(.js) .reveal {
  opacity: 1;
  transform: none;
}

/* ---------------------------------------------------------------------------
   3b. Design-intent section.

   Replaces a three-equal-card grid, which taste-skill 9.C bans outright as the
   generic AI feature row. Cards are also wrong here on 4.4 grounds: elevation
   communicated no real hierarchy, since all four commitments rank equally.
   Grouped with hairlines and negative space instead.

   Layout is an asymmetric two-column row (term left, definition right) rather
   than a symmetric grid, which suits DESIGN_VARIANCE 6 and reads as a technical
   document, which is what this audience trusts. Single hairline between rows,
   never top-and-bottom on each (9.F).
--------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   3b-0. The argument section.

   A manifesto beat sitting between the full-bleed hero and the asymmetric
   commitments grid. Centred on purpose: taste-skill's anti-centre bias carves
   out editorial and manifesto sections, and a measured centred column here
   gives the page a third distinct layout family rather than repeating either
   neighbour. It is the only centred block on the page.
--------------------------------------------------------------------------- */
.shift {
  max-width: 66ch;
  margin: 0 auto;
  text-align: center;
}

.shift h2 {
  font-family: var(--font-display);
  font-size: var(--text-display-2);
  letter-spacing: -0.01em;
  color: var(--ink-strong);
  text-wrap: balance;
  margin-bottom: var(--s-6);
}

/* The trade-off figure.

   Single hue by design. Blocked time is the ABSENCE of billed compute, so it is
   encoded as absence against a recessive rail rather than as a second colour.
   The dataviz validator rejected a pale second hue outright: 1.33:1 against the
   surface, below the chroma floor, reads gray. Cobalt alone measures 5.72:1,
   comfortably past the 3:1 a non-text mark needs.

   Both rows are direct-labelled, which is what discharges the contrast warning
   on the rail: identity never rests on colour alone. No axis and no percentages,
   because our own plan bars idle-ratio figures until they are measured. The
   shape carries the argument; the caption says it is illustrative. */
/* The figure breaks out of the 66ch text measure. It is the argument, not an
   illustration beside the argument, so it gets more width than the prose. */
.tradefig {
  margin: clamp(30px, 4vw, 48px) auto 0;
  width: min(100%, 880px);
}

.tradesvg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Third-party evidence. A stealth company has no traction to show, so borrowed
   authority is the only credible proof available: every line here is someone
   else's published figure, carrying its source. Nothing in this block is ours. */
.proof {
  width: min(100%, 880px);
  margin: clamp(30px, 4vw, 46px) auto 0;
  padding-top: clamp(22px, 3vw, 30px);
  border-top: 1px solid rgba(34, 38, 49, 0.11);
  text-align: left;
}

.proof-lead {
  font-weight: 650;
  font-size: var(--text-h3);
  color: var(--ink-strong);
  margin: 0 0 var(--s-5);
}

.proof-list {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 44px);
}

.proof-list dt {
  font-size: var(--text-body);
  color: var(--ink);
  font-weight: 550;
}

/* --ink-faint is 2.39:1 here and fails AA. Attribution has to be readable or it
   is not attribution. --ink-soft is 5.13:1. */
.proof-list dd {
  margin: 6px 0 0;
  font-size: var(--text-micro);
  color: var(--ink-soft);
}

.proof-list a {
  color: var(--ink-soft);
  text-underline-offset: 2px;
}

.proof-list a:hover {
  color: var(--cobalt);
}

@media (max-width: 640px) {
  .proof-list { grid-template-columns: 1fr; }
}

/* Caption hangs from the figure's left edge, not centred under it. */
.tradefig figcaption {
  margin-top: var(--s-5);
  font-size: var(--text-small);
  color: var(--ink-soft);
  text-align: left;
  max-width: 58ch;
}

.shift p:first-of-type {
  color: var(--ink);
}

@media (max-width: 640px) {
  .shift { text-align: left; }
}

/* Asymmetric two-column: the statement holds the left rail and stays put while
   the commitments scroll past it. taste-skill bans the split-header pattern
   when the right column is filler prose, and explicitly allows it when that
   column carries real content. Here it carries the whole substance of the
   section, and the sticky rail keeps the claim in view while you read against
   it. It also puts the previously dead right half of this section to work. */
.intent-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.94fr) minmax(0, 1.06fr);
  gap: clamp(40px, 6vw, 88px);
  align-items: start;
}

/* A hyphenated compound is a legal line-break point, so "request-shaped" split
   across lines in the narrow rail. Keep compounds whole in display type. */
.nowrap {
  white-space: nowrap;
}

.intent-head {
  position: sticky;
  top: clamp(96px, 14vh, 148px);
}

.intent-head h2 {
  font-size: var(--text-display-2);
  font-family: var(--font-display);
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.intent-head p {
  margin-top: var(--s-4);
  font-size: var(--text-body-lg);
  color: var(--ink-soft);
  max-width: 42ch;
}

.commitments {
  margin: 0;
}

.commitment {
  padding: clamp(22px, 2.6vw, 32px) 0;
  border-bottom: 1px solid rgba(34, 38, 49, 0.11);
}

.commitment:first-child {
  padding-top: 0;
}

.commitment:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.commitment dt {
  display: flex;
  align-items: center;
  gap: 12px;
  font-weight: 650;
  font-size: var(--text-h3);
  color: var(--ink-strong);
  letter-spacing: -0.005em;
}

/* Icons come from the design system's own inline symbol sprite, not hand-rolled
   paths. They give the rail texture and a scan anchor without adding cards. */
.commit-ic {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--cobalt-wash);
  color: var(--cobalt);
}

.commit-ic svg {
  width: 16px;
  height: 16px;
}

.commitment dd {
  margin: 8px 0 0 42px;
  font-size: var(--text-body-lg);
  color: var(--ink-soft);
  max-width: 56ch;
}

/* --ink-faint (#9AA3B5) on --bg-page computes to 2.39:1, which fails WCAG AA
   for both body and large text. This line carries the honesty claim, so it is
   the last string on the page that should be hard to read. --ink-soft is 5.1:1. */
.intent-foot {
  margin-top: clamp(24px, 3vw, 36px);
  padding-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid rgba(34, 38, 49, 0.11);
  font-size: var(--text-small);
  color: var(--ink-soft);
  max-width: 42ch;
}

/* Below the split the rail cannot be sticky: it would pin the statement over
   the list it introduces. Stack, and let the icons keep the rhythm. */
@media (max-width: 900px) {
  .intent-grid {
    grid-template-columns: 1fr;
    gap: clamp(32px, 6vw, 52px);
  }
  .intent-head {
    position: static;
  }
  .intent-head p,
  .intent-foot {
    max-width: 60ch;
  }
}

@media (max-width: 640px) {
  .commitment dd {
    margin-left: 0;
  }
}

/* ---------------------------------------------------------------------------
   3c. Tactile feedback on the primary actions (4.5).
--------------------------------------------------------------------------- */
.hero-actions .btn,
.closing .btn,
.nav-cta {
  transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}

.hero-actions .btn:active,
.closing .btn:active,
.nav-cta:active {
  transform: translateY(1px) scale(0.985);
}

@media (prefers-reduced-motion: reduce) {
  .hero-actions .btn,
  .closing .btn,
  .nav-cta,
  .commitment {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
   4. Stealth nav.
   One brand mark, one link. No primary nav, no session zone, no burger.
--------------------------------------------------------------------------- */
.site-nav .nav-row {
  justify-content: space-between;
}

.site-nav .nav-actions {
  gap: var(--s-4);
}

/* ---------------------------------------------------------------------------
   5. Footer.
   Two columns rather than the baseline's five-column product sitemap.
--------------------------------------------------------------------------- */
.site-footer .footer-grid {
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-7);
}

@media (max-width: 640px) {
  .site-footer .footer-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------------------
   The productivity curve.

   The page's central image, and the one beat that has to land in a glance:
   productivity falls as runs get long enough to block you, and only recovers
   once a run is long enough that you leave. Schematic, so no gridlines, no
   tick values and no axis numbers. A single cobalt stroke, a marked present
   position, and three labelled zones under a baseline.
--------------------------------------------------------------------------- */
/* The six-layer stack. A dumbbell: grey marker where the stack sits today,
   cobalt where work that runs unattended needs it, with the gap drawn between.
   Six simultaneous gaps is the argument, and it is faster seen than read. */
@media (max-width: 640px) {
  .stacksvg .saxis, }

/* Price against patience, from Google's published Gemini tiers. Real numbers,
   cited, on the same axis as the productivity curve: how long you will wait. */
@media (max-width: 640px) {
  .pricesvg .pprice, .pricesvg .pfoot, }

/* Placement across silicon pools. The cost lever, and the reason the platform is
   hardware-agnostic above the serving adapter. No figures: none are measured. */
@media (max-width: 640px) {
  .poolsvg .qname, .poolsvg .qkind, }

/* Secondary note. The workspace is an add-on and has to read as one, so it sits
   below the figure at body scale rather than as a beat of its own. */
.aside {
  margin: clamp(26px, 3.5vw, 40px) auto 0;
  max-width: 58ch;
  font-size: var(--text-body);
  color: var(--ink-soft);
  text-align: left;
  padding-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid rgba(34, 38, 49, 0.11);
}

/* Our move at each layer. Deliberately not the same chart as the gap diagram
   above it: that one measures a distance, this one is a list of positions. */
@media (max-width: 640px) {
  .layersvg .lname, }

/* Source credit on a chart built from someone else's published figures. Kept
   recessive so it reads as attribution rather than as copy about a provider. */
.src { color: var(--ink-soft); }   /* --ink-faint is 2.39:1 and fails AA */

/* ---------------------------------------------------------------------------
   Our move at each layer.

   This was an SVG. That was wrong: it is label/value pairs, not a chart, so it
   got no text wrapping and every baseline had to be hand-placed. The baseline
   rule ended up drawn straight through the last row. HTML gives it real
   spacing, real wrapping, and a mobile collapse that does not need arithmetic.
--------------------------------------------------------------------------- */
.layers {
  width: min(100%, 760px);
  margin: clamp(30px, 4vw, 46px) auto 0;
  text-align: left;
}

.layers-head {
  font-size: var(--text-micro);
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 var(--s-4);
}

.layers-list {
  margin: 0;
  border-top: 1px solid rgba(34, 38, 49, 0.11);
}

.lyr {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: var(--s-5);
  align-items: baseline;
  padding: 14px 0;
  border-bottom: 1px solid rgba(34, 38, 49, 0.11);
}

.lyr dt {
  font-weight: 650;
  font-size: var(--text-body);
  color: var(--ink-strong);
}

.lyr dd {
  margin: 0;
  font-size: var(--text-body);
  color: var(--ink-soft);
}

.layers-foot {
  margin: var(--s-5) 0 0;
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--cobalt-deep);
}

.layers-note {
  width: min(100%, 760px);
  margin: clamp(24px, 3vw, 34px) auto 0;
  text-align: left;
  font-size: var(--text-body-lg);
  color: var(--ink-soft);
}

@media (max-width: 640px) {
  .lyr {
    grid-template-columns: 1fr;
    gap: 4px;
    padding: 13px 0;
  }
}

/* ---------------------------------------------------------------------------
   Chart typography, one scale for every figure.

   These labels had grown six hardcoded sizes (12, 12.5, 13, 13.5, 14, 15px)
   and three weights across three charts, set per-chart as each was built. That
   reads as a mix of fonts even though it is one family. Two roles, two sizes,
   two weights, and a single mobile step. SVG text cannot inherit rem sizing
   reliably across scaled viewBoxes, so these stay in px on purpose.
--------------------------------------------------------------------------- */
.tradesvg text {
  font-family: var(--font-ui);
}

/* Role 1: what a row, point or axis IS. */
.tradesvg .vaxis,
.stacksvg .slabel,
.pricesvg .plabel {
  font-size: 13.5px;
  font-weight: 650;
  fill: var(--ink-strong);
}

/* Role 2: everything supporting it. */
.tradesvg .vfoot,
.stacksvg .saxis,
.stacksvg .sfoot,
.pricesvg .pfoot,
.pricesvg .paxis {
  font-size: 12.5px;
  font-weight: 400;
  fill: var(--ink-soft);
}

/* Role 2, carrying the accent: the value the reader is meant to take away. */
.tradesvg .vlabel,
.tradesvg .vnow,
.stacksvg .scob,
.pricesvg .pprice {
  font-size: 12.5px;
  font-weight: 650;
  fill: var(--cobalt-deep);
}

@media (max-width: 640px) {
  .tradesvg .vaxis,
  .stacksvg .slabel,
  .pricesvg .plabel { font-size: 15px; }

  .tradesvg .vfoot,
  .stacksvg .saxis,
  .stacksvg .sfoot,
  .pricesvg .pfoot,
  .pricesvg .paxis,
  .tradesvg .vlabel,
  .tradesvg .vnow,
  .stacksvg .scob,
  .pricesvg .pprice { font-size: 13.5px; }
}

