/* ============================================================
   THE FLOATING HERO — light gradient panel on a dark page.

   Founder: "i dont like that the hero has the dark bg, i want it to have a
   light color like gradient color we had but i want the hero floating."

   So the ground and the hero swap roles. The PAGE is warm black; the HERO is an
   inset panel carrying the white→mocha gradient from heromocha.css. Two
   consequences worth stating, because they are what make it work rather than
   just look different:

   1. THE PANEL NEEDS A DARK PAGE TO FLOAT ON. A light panel on a light page
      does not float, it just has margins. The dark ground is not decoration —
      it is the thing that makes the inset read as an object lifted off the
      surface. That is also why the page background is the WARM black (#14100E)
      rather than a neutral one: a blue-black behind a mocha gradient makes the
      mocha read pink, which was measured earlier in the session.

   2. THE HEADER MOVES INSIDE THE PANEL. If the hero is an object, its
      navigation belongs to it. A bar above the panel would be page chrome and
      the panel would become "a big card in a section" rather than the hero.
      This is Ploy's move and the reason their nav sits on the artwork.

   ⚠️ THE HEADER HAS TO INVERT. The one the founder kept was built for a dark
   ground — off-white wordmark, translucent white pill group, accent button. All
   three are invisible or wrong on a pale gradient, so each flips to ink while
   keeping the same SHAPE: centred capsule, ghost, filled primary. Shape is what
   he picked; colour is what the ground dictates.
   ============================================================ */

/* FULL WIDTH, NOT FLOATING.  Founder-directed. The panel used to sit inset by
   `--hf-inset` on a contrasting ground with a 22px radius — a card. It now runs
   edge to edge with square corners, so the header inside it reads as the site's
   own header rather than as a bar inside a floating object.
   The token is set ONCE, below, where the comment explaining it lives. It was
   set here as well on the first attempt, and the later declaration simply won:
   two `:root` blocks for one token at equal specificity is not an override, it
   is a coin toss decided by line order — and the hero stayed inset. */
.hf-page { background: var(--paper); padding: var(--hf-inset); }

/* 500px, founder-directed. ⚠️ THE RECORD WINDOW CAME OUT TO GET THERE, and
   that is the whole cost: with it the panel measures 731px (nav 81 + padding 64
   + headline 128 + definition 36 + buttons 48 + window 254 + 120 of margins).
   500 leaves 231px to remove and the window alone is 254, so there is no
   version of this that keeps the artefact AND hits the number.
   731 is the smallest height that keeps one whole log row cropped at the panel
   edge; anything between 500 and 731 slices a row instead of ending on one.

   Still min-height rather than height: a fixed height clips a longer headline
   silently, which is the failure nobody notices until a copy edit ships.
   `--hf-inset` is declared ONCE, here, and used by BOTH the page padding and
   this calc — two places agreeing on a number by coincidence is how the panel
   ends up 3px taller than the viewport and the page scrolls for no reason.
   It is 0 now: the panel is full-bleed, so there is no inset to subtract. */
:root { --hf-inset: 0px; }
.hf { position: relative; overflow: hidden; border-radius: 0;
  min-height: 950px;   /* 900 + 50, founder-directed */
  display: flex; flex-direction: column;
  background: linear-gradient(180deg,
    #FFFFFF 0%, #FCF9F6 30%, #F1E4D8 62%, #DECBB6 100%); }

/* ---- the copy ------------------------------------------------- */
.hf__st { text-align: center; padding: var(--s6) var(--s4) 0; position: relative; z-index: 3;
  flex: 1; display: flex; }
.hf h1 { font-family: var(--display); font-weight: var(--w-display);
  font-size: var(--hf-h1); line-height: 1.03; letter-spacing: -0.02em;
  color: var(--ink); margin-inline: auto; }
/* THE DESCRIPTION'S MEASURE IS DERIVED FROM THE HEADLINE'S, not chosen.

   It was set independently at 56ch and ran WIDER than the headline it sits
   under — 10px at 1440, 8px at 1100, 37px at 390. Two elements with unrelated
   max-widths will disagree at some viewport; the only question is which one.
   `ch` made it worse, because a ch is relative to each element's OWN font size,
   so the same number means different widths on a 62px headline and a 22px line.

   So the headline's size is named once and both measures are computed from it.
   `--hf-h1` is the headline's clamp; `--hf-measure` is 18 of its characters
   ⚠️ 0.54 WAS WRONG AND IT SILENTLY RESIZED THE TITLE. A `ch` in Inter is
   0.66em, not 0.54 — measured by rendering eighteen zeros at the headline's
   own font and reading the box: 736px at 62px, not the 603 the bad factor
   produced. The headline lost 18% of its measure at EVERY width and nothing
   errored; it just wrapped differently. Never approximate a font metric when
   the browser will tell you the real one.

   ⚠️ THE 0.83 IS NOT ARBITRARY AND 0.94 DID NOT WORK. A headline UNDER-FILLS
   its own box — this one breaks at a word boundary at 504px inside a 602px
   allowance — so matching the two max-widths still left the description 36px
   wider than the rendered headline. The ratio has to be solved against what the
   headline actually MEASURES, not what it is allowed:
       1440   headline 504 of 602 allowed   ->  needs <= 0.83
       1100   headline 411 of 492 allowed   ->  needs <= 0.89
        390   headline 260 of 311 allowed   ->  needs <= 0.88
   ⚠️ AND IT HAPPENED. The headline was shortened to "The system that runs the
   business." and its rendered width fell 682 -> 530, so the ratio solved for
   the old copy left the description wider at five widths. Re-solved at 0.70
   against 530/736. This is the third time this value has moved; it is a
   FUNCTION of the headline copy, not a constant. Change the words, re-measure.

   2px down from --t-md as a calc(), not a hardcoded 22px: --t-md is itself a
   clamp that scales — 24px at 1440, 19px at 390 — so "minus 2" has to travel. */
.hf { --hf-h1: clamp(32px, 4.6vw, 62px);
      --hf-measure: calc(18 * 0.66 * var(--hf-h1)); }
.hf h1 { max-width: var(--hf-measure); }
.hf .def { font-size: calc(var(--t-md) - 2px); line-height: 1.5; color: var(--ink-3);
  max-width: calc(var(--hf-measure) * 0.70); margin: var(--s3) auto 0; }
.hf .def b { color: var(--ink); font-weight: 600; }
.hf .acts { display: flex; gap: var(--s5); justify-content: center; align-items: center;
  margin-top: var(--s5); flex-wrap: wrap; }
.hf .cta { display: inline-flex; align-items: center; min-height: 48px; padding: 0 26px;
  border-radius: var(--r-btn); background: var(--ink); color: #fff;
  font-size: var(--t-body); font-weight: 600; }
.hf .cta2 { display: inline-flex; align-items: center; min-height: 44px; gap: 8px;
  font-size: var(--t-body); font-weight: 600; color: var(--ink);
  box-shadow: inset 0 -1px 0 rgba(15,15,15,0.28); }

/* ---- the record, cropped by the panel's own bottom edge --------
   The crop is the PANEL's, not the viewport's — which is the whole reason a
   floating hero is worth the trouble. A full-bleed hero can only be cut by the
   fold, and the fold moves with the browser; a panel cuts at a place you chose. */
/* TWO CARDS FLANKING THE TEXT, CENTRED ON HEIGHT — founder-directed.

   THE CREATIVE MOVE: they are cut by the panel's SIDE edges, not its bottom.
   Every artefact on this site so far has been cropped by a horizontal fold,
   which is the safe cut — everyone does it and it reads as a screenshot ending.
   Cropping left and right instead says the record continues past the frame in
   both directions, and it is the only cut a floating panel can make that a
   full-bleed hero cannot.

   Three things carry it, and each is doing a job rather than decorating:

   1. THEY ROTATE, one against the other. The site's vocabulary is paperwork,
      and paper on a desk is never square to the edge. 2.5deg is deliberately
      under the threshold where it reads as "a tilted card" — it should look
      dropped, not styled.
   2. THEY SIT AT DIFFERENT HEIGHTS. Both centred and level would read as a
      diagram; a 40px offset makes it a pile someone left. The left one rides
      high, the right one low, which also stops the two headers lining up and
      creating an accidental horizontal rule across the hero.
   3. THEY BLEED OUTWARD, so the centre column gets wider — which fixed the
      headline wrapping to three lines as a side effect rather than needing a
      separate override.

   `overflow: hidden` on `.hf` does the cutting. Nothing is positioned
   absolutely: negative margins pull them past the grid, so the layout still
   collapses correctly at every width instead of needing per-breakpoint
   coordinates. */
/* ⚠️ THE COLUMN RATIO IS WHAT SETS THE HEADLINE'S WRAP, not its max-width.
   At 0.8/1.7/0.8 the centre column came out 651px while two lines of this
   headline need 972px — so the title silently went from two lines to three the
   moment the cards moved beside it, and no amount of adjusting `max-width`
   could fix it because the column was the smaller constraint.
   0.42/3.1/0.42 gives the centre ~73% and buys the two lines back. The cards
   lose column width but not apparent size: they are 132% wide with a -30%
   margin, so most of what they show was always outside their column. */
.hf__row { display: grid; grid-template-columns: minmax(0,0.42fr) minmax(0,3.1fr) minmax(0,0.42fr);
  gap: var(--s4); align-items: center; width: 100%; margin-inline: auto; flex: 1; }
.hf__copy { align-self: center; }

/* ---- THE STATUS PILLS.  Phone only — the markup note in index.html says why.
   Above 760 they do not exist: the desktop hero's artefact is the pair of job
   sheets flanking the copy and cut by the panel edges, and that is locked. */
.hf__pills { display: none; }

/* ⚠️ A FLOOR, NOT JUST A PERCENTAGE. Widening the centre column to buy the
   headline its two lines took the card columns from 0.8fr to 0.42fr — roughly
   half — and at 132% of a ~142px column the cards rendered ~190px wide, narrow
   enough that the time / event / by row collapsed and the text overlapped.
   The card's width is now the LARGER of a legible minimum and its share of the
   column, so a future column change cannot squeeze it into illegibility again.
   320px is where the longest row ("Diary checked" + "Levrg") stops wrapping. */
.hf__card { align-self: center; min-width: 0; width: max(320px, 132%);
  border-radius: var(--r-lg); overflow: hidden;
  box-shadow: 0 1px 2px rgba(31,26,22,0.10), 0 34px 70px -28px rgba(31,26,22,0.55);
  transition: transform var(--base) var(--ease); }
.hf__row > .hf__card:first-child  { margin-left: -30%;  transform: rotate(-2.5deg) translateY(-20px); }
.hf__row > .hf__card:last-child   { margin-right: -30%; transform: rotate(2.5deg)  translateY(20px); }
/* they lift a little on hover — the only interaction in the hero, and it is
   the one that says these are objects rather than a background image */
.hf__row > .hf__card:first-child:hover { transform: rotate(-1.5deg) translateY(-28px); }
.hf__row > .hf__card:last-child:hover  { transform: rotate(1.5deg)  translateY(12px); }
@media (prefers-reduced-motion: reduce) { .hf__card { transition: none; }}

.hf__ch { padding: var(--s3) var(--s4); text-align: left; }

/* the live signal — green stays a signal on this site and never a fill, so it
   is a 6px dot and nothing more */
.hf__live { display: inline-flex; align-items: center; gap: 6px; margin-top: 6px;
  font-size: 11px; font-weight: 600; color: var(--brand); }
.hf__live b { width: 6px; height: 6px; border-radius: 99px; background: var(--brand-hot);
  animation: hfping 2.4s var(--ease) infinite; }
@keyframes hfping {
  0%   { box-shadow: 0 0 0 0 rgba(0,168,85,0.5); }
  70%  { box-shadow: 0 0 0 7px rgba(0,168,85,0); }
  100% { box-shadow: 0 0 0 0 rgba(0,168,85,0); }}
@media (prefers-reduced-motion: reduce) { .hf__live b { animation: none; }}
.hf__card .bar { display: flex; align-items: center; gap: 6px; padding: 10px var(--s4);
  background: #EFEAE4; border-bottom: 1px solid var(--line); }
.hf__card .bar i { width: 9px; height: 9px; border-radius: 50%; background: var(--line-2); }
.hf__card .bar span { margin-left: var(--s3); font-family: var(--mono); font-size: 10px;
  color: var(--ink-4); }
.hf__card .sheet { background: #fff; }
.hf__no { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-4); }
.hf__cu { font-size: var(--t-lg); font-weight: 600; color: var(--ink); letter-spacing: -0.02em; }
.hf__me { font-size: var(--t-sm); color: var(--ink-3); margin-top: 4px; }
.hf__r { display: grid; grid-template-columns: 66px minmax(0,1fr) auto; gap: var(--s3);
  padding: 11px var(--s4); border-top: 1px solid var(--line); font-size: var(--t-sm);
  color: var(--ink-2); align-items: baseline; text-align: left; }
.hf__w { font-family: var(--mono); font-size: 12px; color: var(--ink-4); }
.hf__by { font-size: var(--t-xs); font-weight: 600; color: var(--ink-4); text-align: right; }
.hf__by--h { color: var(--ink); }

@media (max-width: 760px) {
  .hf__st { padding: var(--s6) var(--s3) 0; }
  .hf .acts { flex-direction: column; gap: var(--s3); }
  /* ⚠️ NO max-height. It was `max-height: 700px` on a panel with
     `overflow: hidden`, and it ATE THE PRIMARY CTA: at 390 "Book a call" sat
     112px below the cut, at 360 it was 301px below — present in the layout,
     laid out correctly, and never painted. On every phone. It survived because
     nothing that looks at the DOM can see it: the element is there, its rect is
     right, its computed background is #0F0F0F. Only a pixel reading the panel
     shows the button is not on the page.
     A hard cap over hidden overflow is a silent content-eater, and a hero is
     the worst place for one. The 700 is honoured by taking height OUT — tighter
     padding, one card, no tilt — not by cutting the bottom off. If the copy
     grows past it the panel grows too, which is the failure everyone can see
     rather than the one nobody can. */
  .hf { min-height: 0; }
  /* Height comes out of the CONTENT, which is the only way to shorten a panel
     that must not clip. Three sources, measured at 390: the header wrapping to
     two lines (above), the vertical padding, and the record card's fourth row.
     The card stays — it is the artefact the hero is built around — it just
     shows one fewer step. */
  /* ⚠️ MORE AIR ABOVE THE HEADLINE, founder-directed. At --s4 the headline
     started 100px down a 780px screen with the header bar sitting straight on
     top of it, and the panel read as a page that begins immediately rather than
     as a hero. The height the job sheet gave back pays for this several times
     over. */
  .hf__st { padding: var(--s7) var(--s3) var(--s5); }
  .hf__row { gap: var(--s3); }
  .hf__card:first-child .hf__r:nth-of-type(n+4) { display: none; }
  /* one card on a phone — two side by side at 390 gives each ~180px, which is
     narrower than the "Diary checked" row needs. The second is hidden rather
     than stacked: stacking would double the height the 700 cap exists to
     prevent. */
  /* one column on a phone: three at 390 gives the copy ~150px. The cards do
     not stack under it either — that is the height the 700 cap exists to
     prevent — so the second is dropped and the first sits below the copy. */
  .hf__row { grid-template-columns: 1fr; gap: var(--s4); }
  /* ⚠️ BOTH SHEETS COME OFF THE PHONE, founder-directed. The card was 340px of
     a 780px screen for one job, and everything under it started below the fold.
     What replaces it is five pills carrying the SAME rows, so the artefact is
     compressed rather than dropped and the hero still shows the product working
     instead of only claiming it does.
     ⚠️ ONLY HERE. The 761-1000 block stacks a single card under the copy and
     keeps it — a tablet has the height for one, a phone does not. */
  .hf__row > .hf__card { display: none; }

  /* ⚠️ SCATTERED, NOT STACKED. Founder-directed: "across the hero up down left
     right", not an organised row. A centred wrap put all five in one tidy
     cluster under the buttons, which read as a component rather than as the
     system working around the claim.

     THE LAYER IS OUT OF FLOW, and that is what makes the scatter possible AND
     what makes the panel need a height of its own (below): with the pills
     absolute they no longer push the hero taller, so without a min-height the
     panel collapses to the type block and there is nothing to scatter across.

     `pointer-events: none` on the layer, restored on nothing: these are not
     controls, and a decorative pill must never sit between a thumb and "Book a
     call". */
  .hf__pills {
    display: block; position: absolute; inset: 0; z-index: 2;
    pointer-events: none;
  }
  /* ⚠️ NO VIEWPORT UNIT. Founder-directed: "dont use the vh and all those things
     that change height of things depending on viewports on mobile please cause
     when the search bar retracts the sections like hero grow out".

     He is describing the thing mobile browsers do that no unit fully escapes.
     `svh`/`lvh` are meant to be stable and `dvh` is the one that tracks the
     chrome — but the panel is a flex column whose children are laid out against
     it, and the moment the URL bar retracts the layout viewport changes under
     the whole page. A number that cannot be re-resolved cannot do that.

     620px is DERIVED, not chosen: the hero's own content measures 569 at 428,
     602 at 390 and 627 at 320, so 620 is a hair above the middle of that range —
     enough room for the scattered pills at every width, and a `min` so the
     short-viewport case (627 at 320) simply grows past it. Re-measure if the
     headline, the actions or the marquee change; do not nudge it.
     ⚠️ 670 NOW — founder-directed, "+50px". The pills are positioned in PERCENT
     of this panel, so changing it moves all five and the bands they were solved
     against. The collision test is not optional after a change to this number;
     it is the only thing that says the new positions still hold.
     ⚠️ A `min`, NEVER a fixed height and never a `max`. `max-height: 700px` was
     here once and it ATE THE PRIMARY CTA on every phone — "Book a call" laid
     out 112px below the cut at 390 and 301px below at 360, present in the DOM,
     correct in the layout, and never painted. A hard cap over hidden overflow
     is a silent content-eater and a hero is the worst place for one. */
  .hf { min-height: 670px; }
  /* the type centres in whatever height the panel ends up with, instead of
     sitting at the top with the scatter space all below it */
  .hf__st { flex: 1 0 auto; display: grid; align-content: center; }

  /* ⚠️ THE POSITIONS ARE IN PERCENT AND THE BLEEDS ARE IN PX. Percent keeps the
     scatter proportional as the panel's height changes between 620 and a tall
     phone; the horizontal bleed is a fixed overhang because a pill is a fixed
     size and "half off the edge" is a distance, not a fraction.
     Two on each side and one low centre — up, down, left and right, with none
     of them level with another. They are cut by the panel's own `overflow:
     hidden`, which is the same frame that crops the job sheets on desktop. */
  /* ⚠️ THE ARRANGEMENT IS FOUNDER-DIRECTED AND THE NUMBERS ARE MEASURED.
     "bring all the pills in hero mobile down and put the question answered one
     at the top somewhere, some parts off screen".

     So: ONE at the top, the other four in the lower half, and three of the five
     cut by a side edge — the same frame-crop the job sheets use on desktop.

     The bands the type does not occupy, in a 620px panel:
       under the bar     11% .. 29%
       beside the CTA    x0..90 at 320, x0..125 at 390, x0..145 at 430 (mirrored)
       above the marquee 77% .. 92%

     TWO RULES HOLD WHATEVER THE POSITIONS ARE, and both were earned:
     1. NOTHING SITS IN THE ACTION COLUMN. A white rounded rectangle centred
        under two centred buttons reads as a third button — the founder caught
        exactly that on his phone. A pill is a status, the layer is
        `pointer-events: none`, and anything inviting a tap there is a lie.
     2. A CUT PILL MUST STILL READ. An earlier pass cleared the buttons by
        bleeding pills so hard that three of five lost their words. What is cut
        here is the tail of a long label, never the whole of a short one.

     The check is: no pill box may intersect h1, def, cta, cta2, the bar or the
     marquee, AND no pill centre may come within 40px of the action column's
     centre — at 320/360/375/390/414/428/430. Re-run it if the headline length,
     the button width or the panel height move; every one of those is a band. */
  /* ⚠️ A NUDGE, NOT A REDISTRIBUTION. "bring all the pills down" was read as
     "move them into different bands" and the answer came back "i did not mean
     this much down bro, i meant like 10-20px". These are the positions that were
     already working, each moved down about 15px (2.4% of a 620px panel), with
     ONE swap: "Question answered" takes the top slot and "Invoice paid" takes
     the bottom one it vacated. Nothing else changed places.
     ⚠️ THE ROTATION IS PART OF THE BOX. 87% and 21% both measured clear on
     paper and both failed the check — a 2.5deg turn on a 94px pill adds about
     4px to its bounding box at each end, which was enough to put one into the
     marquee and the other into the headline at 320. Leave the margin for it. */
  .hpill { position: absolute; }
  .hpill:nth-child(4) { top: 14%; left: -42px;  transform: rotate(-2.5deg); }
  .hpill:nth-child(3) { top: 19%; right: -30px; transform: rotate(-2deg); }
  .hpill:nth-child(1) { top: 63%; left: 6px;    transform: rotate(-3deg); }
  .hpill:nth-child(5) { top: 74%; right: 2px;   transform: rotate(-1.5deg); }
  .hpill:nth-child(2) { top: 85%; left: 34px;   transform: rotate(2.5deg); }

  /* ⚠️ TWO BLEED STEPS, BECAUSE THE MARGIN IS A SUBTRACTION. "Book a call" is a
     fixed 141px whatever the screen, so the room beside it is (width - 141)/2 —
     125px at 390, 108px at 360, 90px at 320 — while the pills stay 106 and 109.
     Bleeding by the shortfall keeps every label whole at 360 and takes a
     readable sliver at 320. This file already carries a 320px note for the
     header pill; the SE is a width this site is checked at. */
  @media (max-width: 375px) {
    .hpill:nth-child(1) { left: -6px; }
    .hpill:nth-child(5) { right: -16px; }
  }
  @media (max-width: 340px) {
    .hpill:nth-child(1) { left: -22px; }
    .hpill:nth-child(5) { right: -26px; }
  }

  @media (prefers-reduced-motion: reduce) { .hpill { transform: none; } }
  /* ⚠️ SIZED SO FIVE OF THEM FIT IN THREE ROWS AT 360, not chosen by eye. At
     13px/7px/8px they wrapped to four rows on the narrowest phone and the
     cluster was taller than the headline it sat under. The labels are NOT
     shortened to make them fit: content that changes with the viewport is how
     a claim ends up existing at one width and not another. */
  .hpill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 11px; border-radius: var(--r-pill);
    background: var(--white); border: 1px solid var(--line);
    font-size: 12px; font-weight: 500; color: var(--ink-2);
    box-shadow: 0 1px 2px rgba(15,15,15,0.04);
    white-space: nowrap;
  }
  /* the timestamp is the evidence, so it is set in the data face the job sheets
     use rather than in the running one */
  .hpill b { font-family: var(--mono); font-size: 11px; font-weight: 400;
    color: var(--ink-4); font-variant-numeric: tabular-nums; }
  /* the one green thing left in the hero, and it stays a SIGNAL — a dot and a
     word, never a fill */
  .hpill--live { color: var(--brand); font-weight: 600; }
  .hpill--live i { width: 6px; height: 6px; border-radius: 50%;
    background: var(--brand-hot); display: block; }
  /* the bleed and the tilt come off on a phone: at 390 a 132%-wide rotated card
     pushes its own text off the screen edge, and the rotation costs vertical
     space the 700 cap does not have */
  .hf__row > .hf__card:first-child { width: 100%; margin-left: 0; transform: none; }
  /* ⚠️ THE COPY GOES FIRST ON A PHONE. The rule above already says the card
     "sits below the copy" — it did not. DOM order is card, copy, card, and one
     column renders that in order, so the headline started 424px down and
     "Book a call" landed at 700 on an 844 screen: the primary CTA was the last
     thing above the fold and at 360 it was below it.
     Ordered rather than re-ordered in the markup, because the DESKTOP
     composition is cards flanking the copy and that needs the first card to
     come first. */
  .hf__copy { order: -1; }

  /* The 0.83 ratio is solved for desktop, where the headline gets two lines and
     fills 682 of its 736 allowance. On a phone the column squeezes the title to
     THREE lines and it only fills 260 of 380 — so the same ratio leaves the
     description 37px wider than the thing it sits under. A ratio solved at one
     width is not a ratio; 0.66 is the value that holds at 390 and 430. */
  /* 0.56 — re-solved a FOURTH time. "automates" is longer than "runs", so at
     390 the title drops to three lines and renders only 219px, and 0.66 left
     the description at 227. This value tracks the headline COPY and nothing
     else; every wording change has moved it. Do not treat it as settled. */
  /* ⚠️ THE RATIO IS GONE ON A PHONE, and removing it IS the fix rather than a
     fifth value for it. `--hf-measure * 0.56` derives the description's width
     from the HEADLINE's allowance, and the note where that ratio is declared
     says outright it is "a FUNCTION of the headline copy, not a constant.
     Change the words, re-measure." It has moved four times. The current
     headline is longer than the copy 0.56 was solved against, so the
     description sat as a narrow three-line column under a headline running the
     full width — two blocks with visibly different measures, which is what the
     founder pointed at.
     A measure in `ch` of the description's OWN font is about how far an eye
     travels between lines. It does not move when the headline is rewritten,
     which is the only property that matters here. */
  .hf .def { max-width: 32ch; }}

/* ============================================================
   THE MARQUEE, EMBEDDED IN THE PANEL.  Founder-directed: "like the header" —
   the header is a bar across the top INSIDE the panel, so this is its opposite
   number at the bottom.

   IT PAINTS NOTHING. No background, no border-block, no label, no end fades.
   That is the whole point and it is worth stating why, because the standalone
   band outside took three attempts to get right and every one of them failed
   the same way: a gradient paints across the ELEMENT'S OWN box, so a label and
   a band and a fade each render their own complete ramp at their own width and
   can never align. Outside, `background-attachment: fixed` fixes it by putting
   all three in viewport coordinates — safe only because that band's gradient is
   90deg and vertical scrolling does not move a horizontal ramp.

   NONE OF THAT APPLIES IN HERE. The panel's gradient is 180deg, and this band
   sits at one y within it. Any painted copy would be a colour guess that is
   wrong the moment the gradient is edited. So the band paints nothing and lets
   the panel's own gradient be its ground — there is no second surface left to
   match — and the item fade moves into the ALPHA CHANNEL, as a mask on the
   CONTAINER. Masking the container works where masking the track does not: the
   container is the band, stationary and exactly the width the stops assume; the
   track starts at -43px and is three times wider.
   ============================================================ */
.mq--hf { background: linear-gradient(90deg,
    #FFFFFF 0%, #FCF9F6 30%, #F1E4D8 62%, #DECBB6 100%);
  border-block: 0; border-top: 1px solid rgba(15,15,15,0.10);
  margin-top: auto; position: relative; z-index: 3;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%); }
/* the painted fades are the thing being replaced — they would sit on top of the
   mask as two opaque white rectangles */
.mq--hf::after { display: none; }
.mq--hf .mq__t { padding-block: 15px; }
.mq--hf .mq__i { font-size: var(--t-xs); color: var(--ink-3); }

/* dark.css gives every `.mq` the 90deg gradient plus `background-attachment:
   fixed`. That is correct for the band on the dark page and wrong inside a
   panel that already has a gradient — it would lay a second, differently-angled
   ramp over the first. Reset it here, after that file. */
[data-theme="dark"] .mq--hf { background: linear-gradient(90deg,
    #FFFFFF 0%, #FCF9F6 30%, #F1E4D8 62%, #DECBB6 100%);
  /* NOT `background-attachment: fixed`. Outside, three surfaces — band, label
     and two fades — each paint their own copy of this ramp and can only be made
     to agree by putting all of them in viewport coordinates. In here the label
     is gone and the ends are masked, so exactly ONE surface paints it and there
     is nothing to align to. `fixed` would only make the band slide against the
     panel it is sitting in. */
  background-attachment: scroll;
  border-block: 0; border-top: 1px solid rgba(15,15,15,0.10); }
[data-theme="dark"] .mq--hf::after,
[data-theme="dark"] .mq--hf .mq__lab { display: none; }

/* ============================================================
   SECONDARY TEXT ON THE GRADIENT NEEDS ITS OWN GREYS.

   `--ink-3` (#6B6B6B) and `--ink-4` (#6E6E6E) are calibrated against the page
   paper (#F6F7F8), where they clear 4.5:1. The hero panel is not paper — it is
   a ramp that ends at #DECBB6, and it gets darker to the RIGHT, so a single
   grey cannot pass across it. Measured: the hero description at 4.26, the card
   chrome URL at 4.18, and the marquee items sliding 4.26 → 3.83 → 3.53 as they
   travel into the mocha end.

   Fixed by scoping the tokens to the surfaces that have the problem, rather
   than by recolouring the four elements that happened to be caught. #585858 is
   the darkest grey that clears 4.5:1 against the gradient's DARKEST point, so
   it passes everywhere on the panel, not just where it was sampled — and any
   secondary text added here later is correct without anyone re-measuring.

   Repeated under [data-theme="dark"] because dark.css lists `.hf` in its
   light-surface scope and sets these two back; the panel is light in BOTH
   themes, so it has this problem in both. */
.hf, .mq--hf                          { --ink-3: #585858; --ink-4: #5F5F5F; }
[data-theme="dark"] .hf,
[data-theme="dark"] .mq--hf           { --ink-3: #585858; --ink-4: #5F5F5F; }

/* ============================================================
   THE TABLET GAP — where the cards ate the CTA.

   Between 761px (the mobile breakpoint's ceiling) and about 1000px the desktop
   layout applies with none of its room: the cards are `width: max(320px, 132%)`
   pulled in by `margin-inline: -30%`, which is a handsome bleed at 1440 and at
   768 puts the left card straight over the centre column. Measured at 768: the
   card spans x 2–339, the "Book a call" button spans 218–359, and
   `elementFromPoint` at the button's centre returned a row INSIDE the card.
   The primary call to action was covered and not clickable, on every tablet.

   Nothing in the DOM says so — the button's rect is right, its background is
   #0F0F0F, nothing clips it. It took a pixel read of its own box (90% white)
   and then a hit test to see it.

   Raising a z-index is not the fix — the card would still sit on the copy,
   just underneath it.

   THE FIRST FIX WAS NOT ENOUGH, and the measurement says why: the side columns
   are
   `0.42fr` of the row, which is 70px at 768. ANY card wider than 70px bleeds
   into the copy — shrinking it from 320px to 260px moved the overlap from 121px
   to 75px and left the button just as covered. There is no card width that both
   fits a 70px column and is worth showing.
   So this range takes the PHONE's treatment instead: one column, one card,
   stacked under the copy, no bleed and no tilt. It is the same layout the
   mobile block already uses and for the same reason — there is not enough
   horizontal room for a side-by-side hero, at 390 or at 768. */
@media (min-width: 761px) and (max-width: 1000px) {
  .hf__row { grid-template-columns: 1fr; gap: var(--s4); }
  .hf__row > .hf__card:last-child { display: none; }
  .hf__row > .hf__card:first-child {
    width: min(520px, 100%); margin-inline: auto; transform: none; }}