/* ===========================================================================
   Human Care Tag, homepage stylesheet, version R. 9 Sep 2026.

   R undoes Q and goes the other way, on his call: section 2's body is ALL
   Karla, one treatment, one measure. The definition is no longer a heading
   pretending to be quiet - it is body copy, same as the line beneath it.

   So the h3 became a p in the markup. That is a real change, not cosmetic:
   an h3 with no heading behaviour was lying to screen readers anyway, and
   the page still has its h1 and h2s, so nothing is lost from the outline.

   Karla 25px / 39px line-height, both paragraphs, one shared measure so the
   two blocks are the same width to the pixel.

   THE HERO: he wants three lines back AND the 90px he called earlier. At 90px
   it naturally sets on two; at 96px it wraps to three but orphans the word
   "treated" on a line of its own. So the break is forced instead, at 90px,
   giving "Treat others like / they want / to be treated". Chosen because it
   puts the weight on "they", which is the whole argument of the sentence.
   =========================================================================== */
/* ===========================================================================
   Human Care Tag, homepage stylesheet, version P. 9 Sep 2026.

   P is a TYPE TEST, his numbers, nothing else changes. O's structure is
   untouched; the why-line stays where O put it.

   The five sizes he called, measured off the live page first rather than
   taken on trust - and his readings were exact:
     hero H1            96.00px  ->  90px
     What is a HCT      86.40px  ->  90px   (now matches the hero)
     hero sub-line      25.92px  ->  25px
     the definition     35.00px  ->  25px
     the why-line       17.92px  ->  25px

   Caps are moved rather than sizes fixed. Every one of these was a clamp,
   and replacing a clamp with a flat px makes the type LARGER on a narrow
   desktop instead of smaller. The ceiling moves; the shrinking stays.
   =========================================================================== */
/* ===========================================================================
   Human Care Tag, homepage stylesheet, version O. 9 Sep 2026.

   O EXISTS TO TEST ONE MOVE, at Martin's request, expecting to flip back:
   the closing sentence from "Who taught you to speak for your needs" is
   lifted up into section 2, under the definition line, set in the body font.

   It is a real move, not a copy: the sentence is REMOVED from the hard part,
   so that section now ends on "you're too much" with no turn after it. That
   is the cost of the experiment and it should be looked at as hard as the gain.

   Everything below this header is style-n.css plus one new rule, .centre__why.
   =========================================================================== */
/* ===========================================================================
   Human Care Tag, homepage stylesheet, version N. 9 Sep 2026.

   N is a COPY-ONLY release. Martin edited the words in Copy v1.7 and nothing
   in the layout moved, so this file is byte-identical to style-m.css below
   this header. It exists as its own file only so n.html and m.html can be
   opened side by side without one changing the other.

   If a rule is added here later, say so at the top so the next person does not
   assume the two are still the same.
   =========================================================================== */
/* Human Care Tag — version F, 1 Sep 2026 (E's base)
   Built to Martin's own copy: Projects/Human Care Tag/Website/Web Copy v1.0.md.
   His structure, his words, his order. Much shorter than B throughout.
   Everything below is inherited from B pass 03 unless marked C.
   Register: sesame.com, as Martin named it.

   THIS PASS, all his calls:
   · LIGHT ONLY. Cream ground, each section its own tint in the cream/pastel family.
     No dark mode — this design deliberately commits to one visual world, so every
     colour is painted explicitly and nothing borrows the host's theme.
     ("We might go hardcore different colours at some point." Not yet.)
   · hero centred.
   · the correction mark redrawn — "they" sat inside "you" and read wrong.
   · blunt literal titles; "what it is not" gets its own section.
   · Personal / Pro announced.
   The red is only ever the correction. */

/* ===========================================================================
   Self-hosted fonts. 10 Sep 2026 — replaces the fonts.googleapis.com /
   fonts.gstatic.com <link>s removed from t.html so visitor IPs stop going to
   Google on every page load (privacy.html says only two companies touch
   visitor data). Every file below is the exact woff2 Google was already
   serving for this page's request:

     fonts.googleapis.com/css2?family=Caveat:wght@600;700
       &family=Fraunces:opsz,wght,SOFT,WONK@9..144,400..600,0..100,0..1
       &family=Karla:wght@200;300;400;500;600
       &family=Newsreader:opsz,wght@6..72,300;6..72,400;6..72,500

   fetched from the live css2 API and downloaded once — not re-encoded, not
   resubset by hand — so the glyphs and the variable axes (Fraunces' opsz,
   SOFT and WONK included) are byte-identical to what shipped before. Only
   latin + latin-ext; the other unicode-range blocks Google also serves
   (cyrillic, greek, vietnamese, etc.) are dropped as unused on this page.
   font-weight is written as a range because one variable file backs every
   weight in it — collapsing Google's several discrete-weight blocks (each
   pointing at the same file) into one does not change which axis value any
   given font-weight resolves to. */

@font-face{
  font-family:"Caveat";
  font-style:normal;
  font-weight:600 700;
  font-display:swap;
  src:url("assets/fonts/caveat-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Caveat";
  font-style:normal;
  font-weight:600 700;
  font-display:swap;
  src:url("assets/fonts/caveat-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Fraunces";
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url("assets/fonts/fraunces-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Fraunces";
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url("assets/fonts/fraunces-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Karla";
  font-style:normal;
  font-weight:200 600;
  font-display:swap;
  src:url("assets/fonts/karla-wght200-600-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Karla";
  font-style:normal;
  font-weight:200 600;
  font-display:swap;
  src:url("assets/fonts/karla-wght200-600-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Newsreader";
  font-style:normal;
  font-weight:300 500;
  font-display:swap;
  src:url("assets/fonts/newsreader-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Newsreader";
  font-style:normal;
  font-weight:300 500;
  font-display:swap;
  src:url("assets/fonts/newsreader-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

:root{
  color-scheme:light;

  /* the cream family — one ground per section, all within a whisper of each other */
  --c-hero:#FBF8F1;
  --c-1:#F3EFE4;   /* what it is        — warm oat  */
  --c-2:#EDEFE7;   /* what it is not    — pale sage */
  --c-3:#F6F0E7;   /* contexts          — light sand */
  --c-4:#FBF8F1;   /* the cast          — back to hero cream */
  --c-5:#F1ECEA;   /* personal / pro    — pale clay */
  --c-6:#E9EEEC;   /* the rule          — pale mint */
  --c-7:#F5EDE3;   /* sign up           — deepest cream */

  --card:#FFFDF8;
  --ink:#2B2320;
  --soft:#6E645D;
  --line:#DCD5C8;
  --deep:#2C2023;
  --strike:#C0392B;

  --serif:"Newsreader",Iowan Old Style,Palatino,Georgia,serif;
  --sans:"Karla",ui-sans-serif,system-ui,sans-serif;
  --hand:"Caveat",var(--serif);
  --r:18px;
  --gut:22px;
  --ease:cubic-bezier(.2,.7,.3,1);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;background:var(--c-hero);color:var(--ink);
  font-family:var(--sans);font-size:17px;line-height:1.62;
  -webkit-font-smoothing:antialiased;
}
img{display:block;max-width:100%;height:auto}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.brk{display:none}

h2{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2rem,7vw,2.7rem);
  line-height:1.06;letter-spacing:-.018em;margin:0 0 18px;text-wrap:balance;
}
h3{font-family:var(--serif);font-weight:500;font-size:1.4rem;line-height:1.15;
  letter-spacing:-.012em;margin:0 0 12px}
p{margin:0 0 18px}
p:last-child{margin-bottom:0}
.mute{color:var(--soft)}
.lead{font-size:1.2rem;line-height:1.45}
.fine{font-size:13.5px;color:var(--soft);line-height:1.5}
.kicker{font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--soft);margin:0 0 14px}
.kicker--centre{text-align:center}

/* section grounds */
.band{padding:62px 0}
.band--1{background:var(--c-1)}
.band--2{background:var(--c-2)}
.band--3{background:var(--c-3)}
.band--4{background:var(--c-4)}
.band--5{background:var(--c-5)}
.band--6{background:var(--c-6)}
.band--7{background:var(--c-7)}

/* ---------- nav ---------- */
.nav{display:flex;align-items:center;justify-content:space-between;
  padding:20px var(--gut);max-width:1180px;margin:0 auto}
.logo{font-family:var(--serif);font-size:19px;color:var(--ink);text-decoration:none}
.nav__cta{font-size:14px;color:var(--ink);text-decoration:none;
  border:1px solid var(--line);border-radius:999px;padding:8px 16px;
  transition:background .2s var(--ease)}
.nav__cta:hover{background:var(--c-1)}

/* ---------- hero: centred ---------- */
.hero{background:var(--c-hero);border-bottom:1px solid var(--line)}
.hero__in{padding:46px var(--gut) 66px;max-width:960px;margin:0 auto;text-align:center}
.sentence{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2.5rem,11.4vw,5.4rem);
  line-height:1.2;letter-spacing:-.03em;margin:0 0 30px;
}
/* The correction, redrawn.
   His note: "the 'they' is in the 'you' and it looks a little off."
   It was — the replacement was overlapping the word it replaces. Now "they" sits
   in its own space ABOVE the line, clear of the struck word, the way a real
   proofreading mark does. The struck word stays legible: you have to be able to
   read what was crossed out for the correction to mean anything. */
.fix{
  position:relative;display:inline-block;white-space:nowrap;
  padding-top:.72em;vertical-align:baseline;
}
.fix__out{position:relative;opacity:.5}
.fix__out::after{
  content:"";position:absolute;left:-.1em;right:-.1em;top:52%;
  height:.05em;min-height:3.5px;background:var(--strike);
  border-radius:3px;transform:rotate(-2.2deg);
}
.fix__in{
  position:absolute;top:0;left:50%;
  transform:translateX(-50%) rotate(-4deg);
  font-family:var(--hand);font-weight:700;color:var(--strike);
  font-size:.72em;line-height:1;white-space:nowrap;pointer-events:none;
}
.hero__sub{
  font-size:1.1rem;line-height:1.5;color:var(--soft);
  max-width:44ch;margin:0 auto 28px;
}
.hero__sub b{color:var(--ink);font-weight:600}

.btn{display:inline-block;font-size:15px;color:var(--ink);text-decoration:none;
  border:1px solid var(--line);border-radius:999px;padding:13px 24px;
  transition:background .2s var(--ease),border-color .2s var(--ease)}
.btn:hover{background:var(--c-1);border-color:var(--soft)}
.btn--solid{background:var(--strike);border-color:var(--strike);color:#fff;font-weight:600}
.btn--solid:hover{background:var(--strike);border-color:var(--strike);filter:brightness(.93)}

/* ---------- alternating rows ---------- */
.row{padding:0 var(--gut);display:grid;gap:32px;max-width:1220px;margin:0 auto}
.row__text p{max-width:46ch}
.row__text p:not(.lead):not(.kicker){color:var(--soft)}
.row__art{margin:0}
.row__art img{border-radius:var(--r);width:100%}
.row__art--char{background:var(--card);border-radius:var(--r);
  border:1px solid var(--line);overflow:hidden}
.row__art--char img{border-radius:0}
.row__art--plain{display:grid;place-items:center;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r);padding:52px 20px}

.swap{display:flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:center}
.swap__tag{font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--soft);
  background:var(--c-6);border:1px solid var(--line);
  border-radius:8px 8px 20px 20px;padding:26px 22px 34px}
.swap__arrow{font-size:24px;color:var(--strike)}

/* ---------- what it is not ---------- */
.say{padding:0 var(--gut);max-width:880px;margin:0 auto;text-align:center}
.say__big{font-family:var(--serif);font-weight:400;
  font-size:clamp(1.9rem,6.6vw,2.7rem);
  line-height:1.1;letter-spacing:-.02em;margin:0 0 20px;text-wrap:balance}
.say__small{color:var(--soft);max-width:54ch;margin:0 auto 16px}
.say__small em{font-style:normal;color:var(--ink);font-weight:600}

/* ---------- contexts ---------- */
.cards{padding:0 var(--gut);max-width:1220px;margin:0 auto}
.cards__head{max-width:52ch;margin-bottom:32px}
.cards__head p{color:var(--soft);margin:0}
.grid{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.grid li{background:var(--card);border:1px solid var(--line);
  border-radius:14px;padding:19px 20px}
.grid b{display:block;font-family:var(--serif);font-weight:500;font-size:1.2rem;
  letter-spacing:-.01em;margin-bottom:3px}
.grid span{color:var(--soft);font-size:15px;line-height:1.5}

/* ---------- the cast ---------- */
.cast{padding:0 var(--gut);max-width:1180px;margin:0 auto;text-align:center}
.cast__head{max-width:56ch;margin:0 auto 38px}
.cast__head p{color:var(--soft);margin:0}
.cast__row{display:grid;gap:20px}
.chr{margin:0;background:var(--card);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden}
.chr img{width:100%}
.chr figcaption{padding:4px 20px 24px}
.chr b{display:block;font-family:var(--serif);font-weight:500;font-size:1.35rem;
  margin-bottom:5px}
.chr span{color:var(--soft);font-size:14.5px;line-height:1.5;display:block;
  max-width:30ch;margin:0 auto}
.cast__kick{font-family:var(--serif);font-size:1.4rem;line-height:1.3;
  margin:38px auto 0;max-width:30ch}

/* ---------- personal / pro ---------- */
.two{padding:0 var(--gut);max-width:1180px;margin:0 auto}
.two__head{text-align:center;max-width:26ch;margin:0 auto 34px}
.two__row{display:grid;gap:16px}
.pane{background:var(--card);border:1px solid var(--line);
  border-radius:var(--r);padding:30px 26px}
.pane p{color:var(--soft);max-width:42ch}
.pane__label{
  display:inline-block;font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--soft);border:1px solid var(--line);border-radius:999px;
  padding:5px 13px;margin:0 0 16px;
}
.pane--pro{border-color:var(--strike)}
.pane--pro .pane__label{color:var(--strike);border-color:var(--strike)}

/* ---------- sign up ---------- */
.join__in{padding:0 var(--gut);max-width:640px;margin:0 auto;text-align:center}
.join__in p{color:var(--soft);max-width:44ch;margin-left:auto;margin-right:auto}
.form{display:grid;gap:11px;margin:26px auto 12px;max-width:430px}
.form input{font:inherit;padding:15px 17px;border:1px solid var(--line);
  border-radius:999px;background:var(--card);color:var(--ink);
  min-width:0;text-align:center}
.form input::placeholder{color:var(--soft)}
.form button{font-family:var(--sans);font-weight:600;font-size:15.5px;
  padding:15px 24px;border:0;border-radius:999px;
  background:var(--strike);color:#fff;cursor:pointer;
  transition:filter .2s var(--ease),transform .2s var(--ease)}
.form button:hover{filter:brightness(.94);transform:translateY(-1px)}
:focus-visible{outline:2px solid var(--strike);outline-offset:3px}

/* ---------- footer ---------- */
.foot{background:var(--deep);color:#CFC6BE;border-radius:var(--r) var(--r) 0 0;
  padding:50px var(--gut) 40px}
.foot__logo{font-family:var(--serif);font-size:1.6rem;color:#EDE7E0;margin:0 0 28px}
.foot__cols{display:grid;gap:10px;margin-bottom:32px}
.foot__cols a{display:block;color:#CFC6BE;text-decoration:none;font-size:15px;padding:4px 0}
.foot__cols a:hover{color:#fff;text-decoration:underline}
.foot__fine{font-size:13px;color:#93887F;margin:0 0 7px}

/* ---------- reveal ----------
   Hiding gated behind html.js (set inline in <head>, before the stylesheet
   loads): no JS means no .js class, means this rule never applies, means
   .row etc. render at their normal opacity:1 with no transform. Progressive
   enhancement, not a requirement. */
.js .row,.js .cards,.js .say,.js .join__in,.js .cast,.js .two{opacity:0;transform:translateY(16px);
  transition:opacity .65s var(--ease),transform .65s var(--ease)}
.row.in,.cards.in,.say.in,.join__in.in,.cast.in,.two.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js .row,.js .cards,.js .say,.js .join__in,.js .cast,.js .two{opacity:1;transform:none;transition:none}
  .btn,.form button,.nav__cta{transition:none}
}

/* ================= wider ================= */
@media (min-width:820px){
  :root{--gut:56px;--r:22px}
  body{font-size:18px}
  .brk{display:inline}
  .nav{padding:28px var(--gut)}
  .logo{font-size:22px}
  .hero__in{padding:72px var(--gut) 104px}
  .sentence{font-size:clamp(3.8rem,7.6vw,6rem);margin-bottom:36px}
  .hero__sub{font-size:1.24rem;max-width:52ch}
  h2{font-size:2.9rem}
  h3{font-size:1.6rem}
  .band{padding:104px 0}
  .row{grid-template-columns:1fr 1fr;gap:64px;align-items:center}
  .row--flip .row__text{order:2}
  .row--flip .row__art{order:1}
  .grid{grid-template-columns:repeat(4,1fr);gap:16px}
  .cast__row{grid-template-columns:repeat(3,1fr);gap:24px}
  .cast__kick{font-size:1.8rem;max-width:34ch}
  .two__row{grid-template-columns:1fr 1fr;gap:22px}
  .pane{padding:40px 36px}
  .form{grid-template-columns:1fr auto}
  .form input{text-align:left}
  .foot{padding:72px var(--gut) 52px}
  .foot__cols{grid-template-columns:repeat(3,1fr)}
}


/* ================= C ================= */

/* the centrepiece question */
.centre{padding:0 var(--gut);max-width:1000px;margin:0 auto;text-align:center}
.centre__q{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2.4rem,10vw,4.6rem);
  line-height:1.04;letter-spacing:-.028em;margin:0;text-wrap:balance;
}

/* rows: his copy is short, so the type carries and the measure stays tight */
.row__text h3{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.75rem,6.2vw,2.5rem);
  line-height:1.1;letter-spacing:-.02em;margin:0 0 16px;text-wrap:balance;
}
.row__text p{font-size:1.08rem;max-width:38ch;color:var(--soft)}

/* the contexts, sitting where the image would */
.ctx{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.ctx li{background:var(--card);border:1px solid var(--line);
  border-radius:14px;padding:16px 18px}
.ctx b{display:block;font-family:var(--serif);font-weight:500;font-size:1.18rem;
  letter-spacing:-.01em;margin-bottom:2px}
.ctx span{color:var(--soft);font-size:14.5px;line-height:1.45}

/* garden centre */
.cast__lead{color:var(--soft);max-width:52ch;margin:0 auto 40px;font-size:1.08rem}
.chr figcaption{padding:2px 18px 22px;text-align:center}
.chr span{font-size:14px}
.cast__kick{font-size:1.5rem;max-width:24ch}

/* the whole point */
.point{padding:0 var(--gut);max-width:820px;margin:0 auto;text-align:center}
.point__say{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2.2rem,8.6vw,3.6rem);
  line-height:1.06;letter-spacing:-.024em;margin:0 0 22px;
}
.point__say em{font-style:italic;color:var(--strike)}
.point__body{color:var(--soft);max-width:48ch;margin:0 auto;font-size:1.1rem}
.point__body em{font-style:italic;color:var(--ink)}

/* two tags */
.two__head{text-align:center;max-width:20ch;margin:0 auto 34px}
.pane p{font-size:1.02rem}

/* sign up */
.join{padding:0 var(--gut);max-width:640px;margin:0 auto;text-align:center}
.join p{color:var(--soft);max-width:44ch;margin-left:auto;margin-right:auto}

/* reveal, C's element set — gated behind html.js, see the note above .row */
.js .centre,.js .point,.js .join{opacity:0;transform:translateY(16px);
  transition:opacity .65s var(--ease),transform .65s var(--ease)}
.centre.in,.point.in,.join.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .js .centre,.js .point,.js .join{opacity:1;transform:none;transition:none}
}

@media (min-width:820px){
  .centre__q{font-size:clamp(3.6rem,7.4vw,5.4rem)}
  .row__text h3{font-size:2.7rem}
  .cast__kick{font-size:1.9rem}
  .point__say{font-size:clamp(3rem,6vw,4.2rem)}
  .two__row{grid-template-columns:1fr 1fr;gap:22px}
}


/* ================= D =================
   Hero, per his notes:
   · the sentence is ONE colour. The struck word is not greyed — greying it plus a
     salmon rule plus a red replacement was three signals for one idea.
   · the strike is DRAWN: an SVG stroke with a hand wobble and round caps, angled,
     in the same red as the replacement. A CSS rectangle never reads as a pen.
   · "they" 30% larger.
   · line spacing even. The old build padded line 2 only to make room for "they",
     which is exactly the uneven gap he spotted. The room now comes from the
     sentence's own leading, so every line sits the same distance apart. */

.sentence{line-height:1.62;letter-spacing:-.028em}

.fix{
  position:relative;display:inline-block;white-space:nowrap;
  padding:0;vertical-align:baseline;
  line-height:1;            /* hug the glyphs, not the line box */
}
.fix__out{position:relative;opacity:1;color:inherit}   /* same black as the rest */
.fix__out::after{content:none}                          /* the ruled line is gone */

/* centred on the word it strikes, not on the box */
.fix__line{
  position:absolute;left:-.11em;top:50%;
  width:calc(100% + .22em);height:.42em;
  margin-top:.02em;
  color:var(--strike);overflow:visible;pointer-events:none;
  transform:translateY(-50%) rotate(-3.5deg);
}

/* clear of the word below it, sitting in the interline space */
.fix__in{
  position:absolute;left:50%;bottom:100%;top:auto;   /* the earlier rule set top:0,
     which over-constrained the box and made `bottom` a no-op — that is why the
     replacement kept landing on the word instead of above it */
  margin-bottom:.14em;
  transform:translateX(-50%) rotate(-4.5deg);
  transform-origin:50% 100%;
  font-family:var(--hand);font-weight:700;color:var(--strike);
  font-size:.94em;line-height:.68;   /* Caveat carries a deep descender box */
  white-space:nowrap;pointer-events:none;
}

/* sub-headline up ~25% */
.hero__sub{font-size:1.38rem;line-height:1.42;max-width:38ch}

/* centrepiece answer sits directly under the question */
.centre__a{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.35rem,5vw,1.9rem);
  line-height:1.24;letter-spacing:-.012em;color:var(--soft);
  max-width:26ch;margin:20px auto 0;text-wrap:balance;
}

/* garden centre, now the second thing on the page */
.cast__head{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2.2rem,8.4vw,3.4rem);
  line-height:1.06;letter-spacing:-.024em;margin:0 0 20px;text-wrap:balance;
}
.cast__lead{margin-bottom:44px}

/* contexts: centred head, six underneath */
.ctxwrap{padding:0 var(--gut);max-width:1180px;margin:0 auto;text-align:center}
.ctx__head{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2rem,7.4vw,3rem);
  line-height:1.08;letter-spacing:-.022em;margin:0 0 16px;text-wrap:balance;
}
.ctx__lead{color:var(--soft);margin:0 auto 36px;max-width:40ch}
.ctx{text-align:left}
.js .ctxwrap,.js .cast{opacity:0;transform:translateY(16px);
  transition:opacity .65s var(--ease),transform .65s var(--ease)}
.ctxwrap.in,.cast.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .js .ctxwrap,.js .cast{opacity:1;transform:none;transition:none}
}

@media (min-width:820px){
  .hero__sub{font-size:1.62rem;max-width:44ch}
  .centre__a{font-size:2.05rem;max-width:24ch;margin-top:26px}
  .cast__head{font-size:3.6rem}
  .ctx__head{font-size:3.1rem}
  .ctx{grid-template-columns:repeat(3,1fr);gap:16px}
}


/* ================= E =================
   · hero fills the viewport, with a scroll cue
   · sentence leading tightened ~30%, "they" tucked down into it
   · sub-headline 15% smaller ON MOBILE ONLY (desktop ratio he approved stands)
   · the plant characters are OUT — he judged they'd read as another
     personality-type product, which is the exact thing this page denies
   · garden centre band goes pastel green (first real colour on the page)
   · new section between garden centre and contexts: not a personality type */

/* --- hero fills the screen --- */
.hero{
  min-height:100svh;
  display:flex;flex-direction:column;
  position:relative;
}
/* align-items:center stops the button stretching to the full column width —
   as a flex child it was filling the row, which is why it read as a slab. */
.hero__in{
  flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;
  padding:24px var(--gut) 84px;
}
.hero__in .btn{align-self:center}

/* leading in ~30%, and "they" pulled down to sit inside the tighter gap */
.sentence{line-height:1.175}
.fix__in{margin-bottom:-.155em}

/* scroll cue: the page has ONE ask, so this points down rather than
   competing with it (see note to Martin, 1 Sep) */
.cue{
  position:absolute;left:50%;bottom:22px;transform:translateX(-50%);
  display:inline-flex;flex-direction:column;align-items:center;gap:5px;
  color:var(--soft);text-decoration:none;
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;
}
.cue svg{width:19px;height:19px;animation:nudge 2.6s var(--ease) infinite}
.cue:hover{color:var(--ink)}
@keyframes nudge{0%,72%,100%{transform:translateY(0)}84%{transform:translateY(4px)}}
@media (prefers-reduced-motion:reduce){.cue svg{animation:none}}

/* --- centrepiece answer: two lines, wider measure --- */
.centre__a{max-width:34ch}

/* --- the green band --- */
.band--green{background:#DFEADB}
.band--green .kicker{color:#5A6E57}
.band--green .cast__lead{color:#4C5C4A}
.cast__lead{margin-bottom:0}

/* --- not a personality type --- */
.not{padding:0 var(--gut);max-width:760px;margin:0 auto;text-align:center}
.not__head{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2rem,7.4vw,3rem);
  line-height:1.06;letter-spacing:-.024em;margin:0 0 22px;text-wrap:balance;
}
.not__lead{font-size:1.18rem;line-height:1.45;max-width:44ch;margin:0 auto 22px}
.not p{color:var(--soft);max-width:52ch;margin-left:auto;margin-right:auto}
.not p em{font-style:italic;color:var(--ink)}
.not__kick{
  font-family:var(--serif);font-size:1.35rem;line-height:1.3;
  color:var(--ink)!important;max-width:32ch;margin:30px auto 0;
}
.not{opacity:0;transform:translateY(16px);
  transition:opacity .65s var(--ease),transform .65s var(--ease)}
.not.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.not{opacity:1;transform:none;transition:none}}

/* --- mid-page capture --- */
.band--mid{background:var(--c-7);padding:56px 0}
.join--slim{max-width:560px}
.join__ask{
  font-family:var(--serif);font-weight:400;font-size:1.6rem;line-height:1.2;
  margin:0 0 18px;color:var(--ink);
}

/* --- mobile only: sub-headline down 15% --- */
@media (max-width:819px){
  .hero__sub{font-size:1.17rem}
}

@media (min-width:820px){
  .hero__in{padding:24px var(--gut) 96px}
  .centre__a{max-width:32ch}
  .not__head{font-size:3.1rem}
  .not__kick{font-size:1.7rem}
  .join__ask{font-size:2rem}
}


/* nav: logo hard left, pill hard right. The hero is a flex column now, so the nav
   needs its own width and justification stated rather than inherited. */
.nav{gap:14px;width:100%;justify-content:space-between}
.logo{flex:0 1 auto;min-width:0;line-height:1.1}
.nav__cta{flex:none;white-space:nowrap}
@media (max-width:400px){
  .logo{font-size:16px}
  .nav__cta{font-size:13px;padding:7px 13px}
}


/* Pro is announced, not shipped — so it doesn't get the accent. */
.pane--pro{border-color:var(--line)}
.pane--pro .pane__label{color:var(--soft);border-color:var(--line)}

/* one list, one form, segmented — see note to Martin 1 Sep */
.seg{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:0 0 16px}
/* .seg's own display:flex is equal specificity to the browser default
   [hidden]{display:none} and, being author CSS, wins the cascade over it —
   so hiding the fieldset via the hidden attribute alone does nothing without
   this. Needed once the JS hides it alongside the form on a successful
   submit, so the segment pills don't float above the thank-you message. */
.seg[hidden]{display:none}
.seg input{position:absolute;opacity:0;width:0;height:0}
.seg label{
  font-size:13.5px;color:var(--soft);cursor:pointer;
  border:1px solid var(--line);border-radius:999px;padding:8px 16px;
  background:var(--card);transition:all .18s var(--ease);
}
.seg input:checked + label{
  border-color:var(--strike);color:var(--strike);
  box-shadow:inset 0 0 0 1px var(--strike);
}
.seg input:focus-visible + label{outline:2px solid var(--strike);outline-offset:3px}

/* the segmented form wrapper: fieldset needs its browser chrome stripped, and the
   inner .form keeps the grid it had when it was the form element itself */
.form-wrap{margin:26px auto 12px;max-width:430px}
.form-wrap .form{margin:0}
.seg{border:0;padding:0;margin:0 0 14px}
.join--slim .form{margin:22px auto 0}


/* ================= F =================
   · "they" nudged right so the y's descender falls between the u and "want"
   · first section gets an all-caps eyebrow and longer copy
   · garden centre and not-a-personality-type become split rows, alternating
   · sign-up moved under not-a-personality-type, and simplified — nothing on this
     page can say "send me mine" yet, because there is nothing to send
   · final form takes a name, and the promise line replaces the old one */

/* hero: shift the correction right */
.fix__in{left:calc(50% + .36em)}

/* first section */
.centre__more{
  color:var(--soft);max-width:52ch;margin:22px auto 0;
  font-size:1.02rem;line-height:1.55;
}

/* split rows carry a headline now, not just body copy */
.row__head{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.9rem,6.8vw,2.7rem);
  line-height:1.06;letter-spacing:-.022em;margin:0 0 20px;text-wrap:balance;
}
.row__text p{max-width:46ch;color:var(--soft)}
.row__text p em{font-style:italic;color:var(--ink)}
.band--green .row__text p{color:#4C5C4A}
.band--green .kicker{color:#5A6E57}
.row__art img{border-radius:var(--r)}

/* the mid capture is a plain ask */
.join__ask{margin-bottom:20px}

/* final form: name + email + button */
.fields{display:grid;gap:11px}
.fields input{
  font:inherit;padding:15px 17px;border:1px solid var(--line);border-radius:999px;
  background:var(--card);color:var(--ink);min-width:0;text-align:center;
}
.fields input::placeholder{color:var(--soft)}
.fields button{
  font-family:var(--sans);font-weight:600;font-size:15.5px;
  padding:15px 24px;border:0;border-radius:999px;
  background:var(--strike);color:#fff;cursor:pointer;
  transition:filter .2s var(--ease),transform .2s var(--ease);
}
.fields button:hover{filter:brightness(.94);transform:translateY(-1px)}
.fields button:disabled{opacity:.55;cursor:not-allowed;transform:none}

/* MailerLite wiring, 10 Sep — honeypot hidden off-screen (not display:none,
   so a bot that skips display:none fields still fills it), sink iframe
   hidden outright since it only ever shows about:blank or a MailerLite
   response no one is meant to see. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.ml-sink{display:none}

.promise{
  font-family:var(--serif);font-size:1.05rem;color:var(--ink);
  margin:18px auto 8px;max-width:40ch;
}
.join .fine{max-width:52ch;margin:0 auto}
.join .fine a{color:var(--soft)}
.join .fine a:hover{color:var(--ink)}

@media (min-width:820px){
  .centre__more{font-size:1.08rem;max-width:56ch}
  .row__head{font-size:2.8rem}
  .fields{grid-template-columns:1fr 1fr auto}
  .fields input{text-align:left}
}


/* every small-caps label is the same label — one size, one tracking.
   They had drifted: .kicker 12/.16em, .pane__label 11.5/.18em, .cue 11/.18em. */
.kicker,
.pane__label,
.cue{font-size:12px;letter-spacing:.16em}


/* one sign-up on the page. The mid-page ask points at it rather than repeating it. */
.join--slim .btn{margin-top:4px}

/* the fields want room — roughly double the old measure */
.form-wrap{max-width:860px}
@media (min-width:820px){
  .fields{grid-template-columns:1fr 1.2fr auto;gap:12px}
}


/* ---- the kicker sizes, properly this time ----
   Measured in the browser: "Prior art" and "What it isn't" were rendering at
   17.28px while the other two sat at 12px. Cause was specificity, not a missing
   rule: `.row__text p` (0-1-1) from the C stylesheet outranked `.kicker` (0-1-0),
   so the split-row kickers inherited the body size. Naming the element makes the
   normalising rule win instead of losing quietly. */
p.kicker,
.row__text p.kicker,
.pane__label,
.cue{font-size:12px;letter-spacing:.16em}

/* name and email the same width */
@media (min-width:820px){
  .fields{grid-template-columns:1fr 1fr auto}
}

/* ---- footer wordmark ----
   Huge, ghosted, cropped by the bottom edge. The footer is pulled up so its
   rounded top laps over the section above it. */
.foot{
  position:relative;overflow:hidden;
  margin-top:-34px;
  padding-top:84px;padding-bottom:150px;
}
.foot > *{position:relative;z-index:1}
.foot__brand{
  position:absolute;left:50%;bottom:-.30em;transform:translateX(-50%);
  z-index:0;margin:0;pointer-events:none;user-select:none;
  font-family:var(--serif);font-weight:400;
  font-size:13.4vw;
  line-height:.82;letter-spacing:-.035em;white-space:nowrap;
  color:rgba(255,255,255,.075);
}
@media (min-width:820px){
  .foot{margin-top:-44px;padding-top:104px;padding-bottom:210px}
}


/* caps labels up — he wants them to stand out */
p.kicker,
.row__text p.kicker,
.pane__label,
.cue{font-size:15px;letter-spacing:.15em}

/* "We're launching soon" is a section heading, so it gets section-heading size
   (and is now an h2 in the markup, not a paragraph) */
.join--slim .join__ask{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2rem,7.2vw,2.8rem);
  line-height:1.06;letter-spacing:-.022em;
  margin:0 0 26px;text-wrap:balance;
}
@media (min-width:820px){
  .join--slim .join__ask{font-size:2.9rem}
}


/* .pane p (0-1-1) was beating .pane__label (0-1-0) — the same silent specificity
   loss as the kickers. Measured at 16.32px; named the element to fix it. */
p.pane__label,
.pane p.pane__label{font-size:15px;letter-spacing:.15em}


/* ================= G =================
   Built to Copy v1.2. What changed from F:

   · Section order now follows the copy exactly: what it is (the contexts sentence
     has moved up into it) → garden centre → not another personality type →
     "Send me your tag." → contexts → the hard part → life/work → sign up.
   · New section, "Saying what you need can feel daunting". It reuses .not, the
     centred multi-paragraph block E built and F stopped using when
     not-a-personality-type became a split row. No new CSS: the shape it needed
     already existed, and matching an existing section is the point. It does need
     adding to the reveal script's selector list, because .not starts at opacity:0
     — that is done in g.html.
   · The mid-page "We're launching soon" capture is gone; it isn't in v1.2. Its
     rules (.band--mid, .join--slim, .join__ask) are left here unused rather than
     stripped, so F still reads against G line for line.
   · THE SPLIT ROWS: the art fills its half.

   His note: "make the images full size in the split view... on the desktop it
   being split, exactly as you have it on the left, the text placement looks
   beautiful." So the text column keeps precisely what it had — same measure, same
   rhythm, still vertically centred — and only the art column changes.

   How the fill works, desktop only:

   · The row keeps align-items:center, so the text still centres in its half. The
     figure alone opts out with align-self:stretch, and so runs the full height of
     the row that the text defines.
   · The img is taken out of flow (position:absolute) and covers. Out of flow is
     what stops a tall image dictating the row: the figure then has no intrinsic
     height of its own, so the row is sized by the text and by --art-min, never by
     the picture's own proportions. Drop in a 3000px-tall asset and the crop
     changes; the layout does not move.
   · --art-min is the floor. It only bites when a text column is short enough to
     squash the picture into a letterbox strip.
   · --art-max is the ceiling, and it is the important one. Both photographs are
     16:9, so past a certain height "fill" stops meaning fill and starts meaning
     amputate: measured at an 820px viewport the unbounded version showed 40% of
     the frame and cut the cactus and the flower off the ends of the garden-centre
     shot. The ceiling holds the crop at ~72% of the source width at every desktop
     size. Where the text is shorter than that — 1220px up, which is where the row
     hits its max-width and the columns are a full 522px — nothing is capped and
     the image fills the row edge to edge, which is the case he was looking at.
     Between 820 and 1219 the columns are narrower and the text taller, so the
     image grows as far as the crop budget allows and then centres, still
     substantially bigger than F had it. Flagged to Martin.
   · Both are expressed against --art-w, the width the grid actually gives the
     column, so the crop stays proportional instead of drifting with the viewport.
     Keep --art-w in step with the .row rules above it (max-width, --gut, gap).
   · The radius stays on the img rather than moving to the figure, because when
     the ceiling bites the img is smaller than the figure and a radius on the
     figure would round nothing.
   · .row--flip only reorders the two columns, so it inherits all of this
     unchanged — both alternating rows behave identically. Verified, not assumed.

   MOBILE IS UNTOUCHED. Every rule below sits inside the same min-width:820px
   breakpoint the two-column split itself uses. Under it the row is a single
   column and the images keep the natural aspect ratio they had in F. */

@media (min-width:820px){
  .row__art{
    /* the column width the grid hands this figure — mirrors .row's own numbers */
    --art-w:calc((min(100vw,1220px) - 2 * var(--gut) - 64px) / 2);
    --art-min:calc(var(--art-w) * .62);
    --art-max:calc(var(--art-w) * .78);

    align-self:stretch;
    position:relative;
    min-height:var(--art-min);
  }
  .row__art img{
    position:absolute;top:50%;left:0;
    transform:translateY(-50%);
    width:100%;height:100%;max-height:var(--art-max);
    object-fit:cover;object-position:50% 50%;
    border-radius:var(--r);
  }
}


/* ================= H =================
   Built to Copy v1.4, from his 4 Sep voice note walking the page.
   Everything above this line is G untouched, so g and h diff as pure additions.

   1 · hero sub-line on one line above the 820px breakpoint
   2 · the correction "they" nudged 15px right, desktop only
   3 · hero at 90% of the viewport, so the next section peeks
   4 · EXPERIMENT: section 2 in dark grey — fenced block at the very bottom
   5 · the definition line set at section-H2 size
   6 · the three sentences the copy file sets bold

   Copy, from v1.4 and v1.3: the definition line restored to "Your instructions
   for others about what you need to thrive in different life contexts.", "The
   Human Care Tag" → "Your Human Care Tag", and three sentences set bold. Words
   are his; nothing here shortens, reflows or softens them to make them fit. */


/* --- 1 · the sub-line, one line at desktop -------------------------------
   Measured, not guessed: at 25.92px Karla the first sentence wants 697.1px and
   .hero__sub was capped at 44ch = 676.9px, so it broke by 20px. The cap goes to
   48ch — enough headroom that a font fallback can't quietly reopen the break.
   Nothing else needed widening: .hero__in is fit-content under a 960px cap, and
   697 + 2 x 56px gutter = 809px, so that cap already had 151px spare.
   BELOW 820px this rule does not exist, the <br class="brk"> stays hidden, and
   the two sentences wrap as one paragraph — the behaviour he asked to keep. */
@media (min-width:820px){
  .hero__sub{max-width:48ch}
}


/* --- 2 · the correction, 15px further right ------------------------------
   F set left:calc(50% + .36em). He asked for 15px more while looking at
   desktop, so the nudge is scoped above the breakpoint: a flat 15px against the
   mobile sentence (41px type) would be most of a second nudge again, and mobile
   is meant to stay identical to g. Held in px because px is what he asked for.
   The proportional equivalent at full hero size is .156em, if it should ever
   scale with the type instead. */
@media (min-width:820px){
  .fix__in{left:calc(50% + .36em + 15px)}
}


/* --- 3 · hero at 90% of the viewport -------------------------------------
   "so we can see the next section." Same svh unit E used, so mobile browser
   chrome still behaves. */
.hero{min-height:90svh}


/* --- 5 · the definition line at section-H2 size --------------------------
   "so it stands out, because that's a big one right there." It takes .row__head
   exactly — size, leading, tracking, text-wrap:balance, the type "The garden
   centre worked this out first" is set in — and full ink in place of --soft.

   The measure is the one number that had to be re-chosen rather than copied:
   .row__head carries no cap of its own because the split-row grid caps it, and
   the old 32ch was picked for 32.8px type. Copy v1.4 restored the line to its
   full length, so at 44.8px it is a three-line sentence, and the job is where
   the three lines break. Measured across 820–1920 with balance on, every cap
   from 26ch to 30ch breaks it the same way:

       Your instructions for others  /  about what you need to thrive  /
       in different life contexts.

   which keeps "for others" and "in different life contexts." each whole on a
   line of their own — the two phrases he refused to give up. At 32ch and above
   it flips to two lines and splits "about what / you need" instead, so the cap
   sits at 28ch: same breaks, and 103px of slack before that flip in case a
   fallback font moves the ch. Without balance the same box orphans "contexts."
   onto a line by itself at 768 and 1220. */
.centre__a{
  font-size:clamp(1.9rem,6.8vw,2.7rem);
  line-height:1.06;letter-spacing:-.022em;text-wrap:balance;
  color:var(--ink);max-width:28ch;margin-top:24px;
}
@media (min-width:820px){
  .centre__a{font-size:2.8rem;max-width:28ch;margin-top:30px}
}


/* --- 6 · the bolded sentences --------------------------------------------
   Emphasis on this page has always been full ink at weight 600 (.hero__sub b,
   .row__text p em). <strong> joins that rather than inventing a third look;
   700 would synthesise, since Karla is only loaded to 600. */
strong{font-weight:600;color:var(--ink)}


/* ============ EXPERIMENT · SECTION 2 IN DARK GREY ============================
   His ask, in his words: "should we try make the next section black and white or
   like a dark gray... I just want to see it, maybe that's too much."

   This deliberately breaks the page's standing decision, stated at the top of
   this file: light only, one cream world, no dark. It is here to be looked at.

   DELETE THIS BLOCK TO REVERT. Nothing else in the stylesheet depends on it,
   and --c-1 itself is left alone because .btn:hover and .nav__cta:hover both
   drink from it.

   The grey is one step off the footer's own --deep #2C2023, so it belongs to the
   palette rather than arriving as a raw black, and does not read as a second
   copy of the footer. Text is the cream and the two warm greys the footer
   already uses. Measured contrast on #332C29:
     #FBF8F1 headings, definition line, bold  12.91:1
     #CFC6BE body                              8.14:1
     #A79C93 eyebrow                           5.10:1
   All three clear WCAG AA for normal text (4.5:1); the first two clear AAA. */
:root{
  --c-1-dark:#332C29;
  --on-dark:#FBF8F1;
  --on-dark-soft:#CFC6BE;
  --on-dark-kick:#A79C93;
}
.band--1{background:var(--c-1-dark)}
.band--1 .centre__q,
.band--1 .centre__a,
.band--1 strong{color:var(--on-dark)}
.band--1 .centre__more{color:var(--on-dark-soft)}
.band--1 p.kicker{color:var(--on-dark-kick)}
/* ============ END EXPERIMENT ============================================== */


/* ================= I =================
   Built to Copy v1.5. Everything above this line is H untouched, so h and i
   diff as pure additions.

   What changed from H is almost entirely ORDER, and order lives in the markup:
   section 2 is stripped to the question and the definition line, its old body
   becomes a split row of its own, and "the hard part" is rewritten and becomes
   the split row beneath it. Both take .row / .row--flip exactly as the garden
   centre and not-a-personality-type rows already do, so no layout CSS was
   needed for them at all.

   The one thing that IS new here: the two placeholder pictures. They stand in
   for photography that does not exist yet, so they are drawn rather than
   fetched — inline SVG and grid, no asset, no request, no layout shift. Both
   carry a visible caption saying so.

   MOBILE IS UNTOUCHED. Every selector below is new (.row__art--ph, .sheet*,
   .tagph*, .ph__cap, .sprite); nothing existing is redefined, so the mobile
   rendering of every section that h.html already had is byte-identical. */


/* --- the placeholder card ------------------------------------------------
   It sits in the same .row__art slot the photographs use, so at desktop it
   inherits align-self:stretch and min-height:--art-min from G's fill rules and
   runs the full height of the row. The photographs fill that height by
   cropping; a drawing cannot be cropped, so it centres inside the card
   instead, which is why the box needs to be a centred flex column. The
   absolute-position img rules from G do not reach it — there is no img. */
.row__art--ph{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:14px 14px 12px;
  display:flex;flex-direction:column;justify-content:center;gap:12px;
  /* Below the 820px split these cards are full-column-width, and a drawing does
     not crop the way a photograph does — at 768 the uncapped sheet ran 631px
     tall against the garden-centre photo's 404. The cap is 524px, two pixels
     wider than the 522px column the desktop grid hands out at its maximum, so
     it is a no-op at every width where the row is actually split and only
     bites in the stacked range.
     Stated as width + max-width + justify-self, NOT as auto side margins:
     `margin-inline:auto` on a grid item switches it off stretch sizing, which
     collapsed both cards to their content width and cost the tag card 184px at
     1440. Measured, not assumed. */
  width:100%;max-width:524px;justify-self:center;
}
.ph__cap{
  font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--soft);opacity:.8;text-align:center;margin:0;
}
.sprite{position:absolute;width:0;height:0;overflow:hidden}


/* --- section 3: the contact sheet ----------------------------------------
   Standing in for: one person photographed across a grid of contexts. So the
   placeholder says exactly that — one figure, repeated identically six times,
   and only the ground under them changes. The six grounds are the page's own
   six section tints, which is the whole argument of the section made in
   colour: same human, different rooms.
   Three across at every width, because a contact sheet is three across, and
   because 2-up would make the block twice as tall as the photograph it
   replaces on a phone. */
.sheet{
  list-style:none;margin:0 auto;padding:0;max-width:450px;
  display:grid;grid-template-columns:repeat(3,1fr);gap:8px;
}
.sheet__frame{
  position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:9px;
  display:grid;grid-template-rows:1fr auto;
  justify-items:center;align-items:center;
  padding:0 4px 8px;
  box-shadow:inset 0 0 0 1px rgba(43,35,32,.06);
}
.sheet li:nth-child(1) .sheet__frame{background:var(--c-1)}
.sheet li:nth-child(2) .sheet__frame{background:var(--c-2)}
.sheet li:nth-child(3) .sheet__frame{background:var(--c-3)}
.sheet li:nth-child(4) .sheet__frame{background:var(--c-5)}
.sheet li:nth-child(5) .sheet__frame{background:var(--c-6)}
.sheet li:nth-child(6) .sheet__frame{background:var(--c-7)}
.sheet__fig{display:block;width:46%;aspect-ratio:1;fill:var(--ink);opacity:.2}
.sheet__no{
  position:absolute;top:6px;left:7px;
  font-size:9.5px;letter-spacing:.12em;color:var(--ink);opacity:.34;
}
/* chinagraph on the frame, not under it: the label lives inside the fixed
   aspect box, so a name that wraps to two lines cannot knock the grid out. */
.sheet__cap{
  font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--soft);text-align:center;line-height:1.25;
}


/* --- section 4: the blank label ------------------------------------------
   The quiet one. A single stake label of the kind the garden centre section
   talks about, planted, with nothing written on it yet — which is the point of
   the copy it sits beside. Ruled blank lines rather than invented words, the
   same blankness h.html's own garden-centre photograph is described with.
   The ground goes pale sage so a cream label reads against it; on --card the
   label would be invisible. */
.row__art--tag{background:var(--c-2)}
.tagph{display:block;width:100%;max-width:380px;margin:0 auto}
.tagph__face{fill:var(--card);stroke:var(--line);stroke-width:2}
.tagph__fig{fill:var(--ink);opacity:.2}
.tagph__rule{fill:var(--ink);opacity:.1}
/* one shade under the green band's #DFEADB — at the band's own value the bed
   disappeared into the sage ground and the label read as floating. */
.tagph__soil{fill:#D3E1CE}


@media (max-width:400px){
  .row__art--ph{padding:10px 10px 9px;gap:10px}
  .sheet{gap:6px}
  .sheet__cap{font-size:9px;letter-spacing:.06em}
}
@media (min-width:820px){
  .row__art--ph{padding:18px 18px 15px;gap:15px}
  .sheet{gap:12px}
  .sheet__no{font-size:10.5px}
  .sheet__cap{font-size:11px;letter-spacing:.12em}
  .ph__cap{font-size:12px}
}


/* ================= J =================
   Martin's seven, from his read of i.html. Everything above this line is I
   untouched, so i and j diff as pure additions.

   Five of the seven live in the markup alone (the three-line heading, the two
   sentences whose bold now starts at the beginning, and the two bold sentences
   that break out into paragraphs of their own). Only two need CSS. */


/* --- 1 · the definition line, lighter than the question ------------------
   His words: "I know the other H2 sizes are bold, but this one, it's too much.
   It needs more contrast."

   Measured before touching it: .centre__a was ALREADY font-weight:400, and so
   is .centre__q. Nothing on this section was bold. What reads as weight is
   light-on-dark halation — near-white Newsreader at 44.8px on a near-black
   ground gains apparent weight — plus the fact that question and answer were
   at the identical weight and the identical colour, so the only contrast
   between them was size.

   So "normal weight" was already true and could not deliver what he asked for.
   The contrast he named is what this serves: the answer drops to 300, which is
   a real cut of Newsreader (the font link loads 300;400;500), not a browser
   synthesising a lighter face. Size is untouched, exactly as instructed.

   If he wants more separation still, the next lever is colour, not weight:
   --on-dark-soft #CFC6BE is already defined and would take the answer down to
   8.14:1, still clear of AA. Left alone because he did not ask for it. */
.centre__a{font-weight:300}


/* --- 2 · section 2 takes the footer's ground -----------------------------
   Read from the footer's own rule rather than retyped: .foot{background:var(--deep)}
   so this is var(--deep), and the two can never drift apart.

   The H experiment block introduced --c-1-dark #332C29 for this band and
   measured its contrasts. Those numbers no longer apply, so they are
   re-measured here against --deep #2C2023, which is darker and therefore
   kinder on every one of them:
     #FBF8F1 question, definition line   14.80:1   (was 12.91)
   Clears WCAG AAA for normal text (7:1) with room to spare. Verified in the
   browser from computed styles, not from arithmetic on paper. */
.band--1{background:var(--deep)}


/* --- 3 · "Different contexts. Different needs. Different care tags." -----
   Three lines, one sentence each, at EVERY width. .brk is the page's existing
   break element but it means "break above 820px only" — it is display:none
   below. This is its counterpart and the naming says so. */
.brk--all{display:inline}


/* --- CONTRAST FIX · placeholder micro-text ------------------------------
   Found by an independent axe-core pass on i.html. Both defects are mine,
   both are in the two placeholder pictures, and both have the same cause:
   I dimmed text with `opacity` instead of choosing a colour. Opacity
   composites the glyph toward whatever is behind it, so the contrast is
   whatever the blend happens to land on — which is how 9.5px digits ended up
   at 2.01:1 against a bar of 4.5:1.

   Reproduced independently before touching anything, to be sure I was fixing
   the thing they measured and not something adjacent:
     .sheet__no  ink @ .34   2.01–2.02:1   (they measured 2.00–2.02)
     .ph__cap    soft @ .8   3.68 / 3.36:1 (they measured 3.66 / 3.35)

   The fix is to drop the opacity and name a colour. Both take solid
   var(--soft) — the same treatment .sheet__cap already uses on these exact
   six tints, and which passed their scan, so the frames stay internally
   consistent rather than growing a third grey.

   Size is untouched: he wants the frame numbers small and quiet, and quiet
   here comes from being 9.5px in a corner, not from being unreadable.

   Measured after the fix, worst ground for each:
     .sheet__no  4.91:1 on --c-6 #E9EEEC   (best 5.09 on --c-3)
     .ph__cap    5.67:1 contexts / 4.97:1 the hard part
   The thinnest margin on the page is that 4.91. It is set by --c-6, the
   darkest of the six frame tints — if a tint is ever darkened, re-measure. */
.sheet__no{color:var(--soft);opacity:1}
.ph__cap{color:var(--soft);opacity:1}


/* ================= K =================
   Built to Copy v1.6. Everything above is J untouched, so j and k diff as
   pure additions.

   v1.6 is almost entirely markup: one word cut from the contexts closing
   sentence, and four sections re-broken into shorter paragraphs. His reason,
   his words: "I split up the sentences into even shorter paragraphs to make it
   easy to read, because attention span is on the decline."

   Only the section 2 spacing needs CSS. */


/* --- section 2 · more air under the question ----------------------------
   He gave two numbers that had to be reconciled by measurement, not by
   picking one:
     "a little bit more space… like 20% more"
     "the gap between the hero, between 'treated' and the subheader, that's a
      good distance, whatever that is"

   Measured in j.html, bounding box to bounding box:
     hero  h1 -> sub-line     30px below 820,  36px at 820 and up
     sec 2 question -> answer 24px below 820,  30px at 820 and up
   So matching the hero he named IS +25% on mobile and +20% on desktop. The
   two statements agree; there was nothing to trade off.

   Wired rather than copied. The hero gap and the section 2 gap are now the
   same custom property, and the hero's own margin is restated in terms of it,
   so the two cannot drift apart the next time one of them is tuned. The values
   are exactly what .sentence already computed to at each breakpoint, so the
   hero does not move — verified by measuring j and k side by side. */
:root{--gap-head-sub:30px}
@media (min-width:820px){:root{--gap-head-sub:36px}}
.sentence{margin-bottom:var(--gap-head-sub)}
.centre__a{margin-top:var(--gap-head-sub)}



/* ============================================================
   l · the footer, 7 Sep 2026.

   Two things end the page. The sign-up band above stays exactly where it is
   and is understood as the permanent PRE-footer: there is one form on this
   page and the footer does not repeat it. Then the footer proper.

   Full-bleed ground, content in an 820px column, the ghosted wordmark behind
   it, cropped by the bottom edge. The wordmark is why the footer works and
   nothing here touches it.

   Inside the column, three staggered groups:
     pages + copyright   left
     the three accounts  middle
     the sign-off        right, dropped furthest, so it reads as a signature

   Source order is reading order — sign-off, pages, accounts — and the columns
   are placed with grid rather than by reordering the markup, so keyboard focus
   never disagrees with the eye. Below 820px the three become one stack in that
   same order and the stagger switches off.

   The black colophon bar an earlier version of this block carried is gone,
   markup and CSS. Martin's call. The copyright now sits under Terms.

   ORDER MATTERS IN HERE. The grid placement and the stagger are the LAST thing
   in the block, on purpose: they set margin-top, and any `margin:` shorthand
   written after them silently wins. That is not hypothetical — the first cut of
   this had .foot__strike{margin:0} below the media query and the sign-off's
   84px stagger measured 0 in the browser. Same failure as the F-era
   .foot__fine{margin:0 0 7px}, twenty years of CSS apart. Add new rules ABOVE
   the placement block.
   ============================================================ */


/* --- the knobs -----------------------------------------------------------
   The only numbers in this block that are taste rather than measurement, so
   they sit together where they can be moved without reading the rest of it.

   THE STAGGER. How far each group drops below the top of the footer block.
   The left column is the datum at 0. First pass, expected to move. Desktop
   only: in the stacked layout a stagger is just uneven gaps.

   THE RULE under Terms. --foot-rule-w is "half the length of the terms", taken
   from the rendered word and not from arithmetic: "Terms" measures 41.44px in
   Karla 15px, so the hairline is 21px. Note it is half the WORD, not half the
   link — .foot__cols a is display:block, so the anchor is the full 202px column
   and half of that would be a bar. Flat px, because it is half of one specific
   word rather than a proportion of anything; if the nav type changes size,
   re-measure.

   THE GAP above it is tuned to his "double spacing": the nav's own line pitch
   is 32.3px, and 32px here puts 64.3px between the top of "Terms" and the top
   of the copyright, which is 1.99x that pitch. */
:root{
  --foot-stag-pages:0px;
  --foot-stag-social:36px;
  --foot-stag-strike:84px;

  --foot-rule-w:21px;
  --foot-rule-gap:32px;    /* air above the hairline */
  --foot-rule-drop:15px;   /* air below it, before the copyright */
}


/* --- the inner column ----------------------------------------------------
   The ground stays full width; everything in it sits in an 820px column.
   margin-inline, never a `margin:` shorthand — see the note above. */
.foot > *{max-width:820px;margin-inline:auto}
/* the wordmark is the one child that must NOT be capped: it is deliberately
   wider than the column, and a cap would leave it off centre in its own box */
.foot__brand{max-width:none;margin-inline:0}

/* the stacked rhythm; the grid takes over at 820 */
.foot__cols{gap:34px}


/* --- the three accounts, stacked ---------------------------------------- */
.foot__social{display:grid;justify-items:start}


/* --- the copyright, under Terms -----------------------------------------
   Not a bar across the bottom and not a full-width rule: a short hairline half
   the width of the word above it, then the line. .foot__copy is nested inside
   .foot__pages rather than being a child of .foot, so the shorthand here cannot
   reach `.foot > *`.
   #93887F is the grey the old .foot__fine used, kept so the footer does not
   grow a fourth value. Measured on --deep: 4.54:1. It clears AA for normal
   text, but by 0.04, so it is the thinnest margin in the footer — if --deep is
   ever lightened this is the value that fails first. */
.foot__copy{
  font-size:13px;color:#93887F;line-height:1.5;
  margin:var(--foot-rule-gap) 0 0;
}
.foot__copy::before{
  content:"";display:block;
  width:var(--foot-rule-w);height:1px;
  background:currentColor;
  margin:0 0 var(--foot-rule-drop);
}


/* --- the sign-off --------------------------------------------------------
   The hero's correction once more, quarter size, reusing .fix, .fix__in,
   .fix__out and .fix__line. Only what has to change for a small mark on a dark
   ground is stated here.

   No reveal and no transition, deliberately. It also carries none of the
   classes the observer in l.html watches (.centre .row .ctxwrap .point .two
   .join), so it cannot start at opacity:0 and stay there.

   line-height:1.9 is insurance, not decoration: the handwritten word hangs
   above the word it corrects, so if the sentence wrapped with .fix on the
   second line, "they" would land on the first. At this leading it clears.
   text-wrap:balance is the other half of that — measured, the sentence is
   352.6px and the sign-off column is 362.7px at an 820 viewport, so it holds
   one line across the whole desktop range with 10px to spare; balance is there
   so that if a font fallback ever reopens the break it splits evenly instead of
   orphaning "treated". */
.foot__strike{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.05rem,4.4vw,1.45rem);
  line-height:1.9;letter-spacing:-.018em;text-wrap:balance;
  text-align:left;margin:0;
}

/* Four overrides, all of them about scale.

   1 · THE RED. --strike #C0392B measures 2.89:1 on --deep and is unreadable
       there. This is the same hue and saturation (hsl 6, 75%) with lightness
       46% -> 62%, which measures 4.75:1 and clears WCAG AA for normal text. It
       is still the correction red, lit for a dark ground, the same move
       --on-dark makes for the cream.

   2 · THE HORIZONTAL NUDGE. H set .fix__in a flat 15px right above 820px,
       tuned against 96px hero type. At 23px that is most of a word. H's own
       note gives the proportional equivalent, .156em, so the footer takes that
       and the mark stays put at every size.

   3 · THE LIFT. Measured, not nudged. Rasterised at 4x and differenced against
       a render with both halves hidden, so each half's real ink could be
       isolated from its box — .fix__in has line-height:.68, so its border box
       is nothing like the glyphs it paints:

         hero   96px    4.25px clear between "they" and "you"
         footer 23.2px  2.75px clear

       They never actually collide, at either size. Proportional scaling is the
       bug: .1958em of clearance is open space at 96px and a smudge at 23px,
       because antialiasing does not scale down with the type. So the footer
       gets absolute clearance instead of proportional. margin-bottom moves from
       -.155em to -.05em, which lifts the hand .0987em of the parent's size.

   4 · THE STROKE. Same story. At stroke-width 4.2 in a viewBox squashed by
       preserveAspectRatio="none", the line rendered 1.75px thick vertically and
       far thinner horizontally, so the round caps read as blots rather than a
       pen. vector-effect:non-scaling-stroke takes the width out of the squashed
       user space and into CSS pixels, which makes it uniform as well as thin.

   All four are scoped to .foot__strike at 0-2-0, which also beats the 0-1-0
   rules inside H's media query, so the hero is untouched above and below the
   breakpoint. */
:root{--strike-on-dark:#E76455}
.foot__strike .fix__in,
.foot__strike .fix__line{color:var(--strike-on-dark)}
.foot__strike .fix__in{left:calc(50% + .36em + .156em);margin-bottom:-.05em}
.foot__strike .fix__line path{vector-effect:non-scaling-stroke;stroke-width:1.4px}


/* --- placement and stagger. KEEP THIS LAST — see the note at the top -----
   .foot__cols keeps its name and its anchor styling from F; only the track
   definition changes. This supersedes the F-era
   `.foot__cols{grid-template-columns:repeat(3,1fr)}` above by source order —
   same specificity, same breakpoint, later rule.
   minmax(0,1fr) rather than 1fr on the sign-off: a bare 1fr floors at the
   content's min-content width, which for a sentence is its longest word, and
   would let it push the two auto columns around. */
@media (min-width:820px){
  .foot__cols{
    grid-template-columns:auto auto minmax(0,1fr);
    align-items:start;
    column-gap:36px;row-gap:0;
  }
  .foot__pages {grid-column:1;grid-row:1;margin-top:var(--foot-stag-pages)}
  .foot__social{grid-column:2;grid-row:1;margin-top:var(--foot-stag-social)}
  .foot__strike{grid-column:3;grid-row:1;margin-top:var(--foot-stag-strike);
                text-align:right}
}


/* --- the definition line, in Karla ---------------------------------------
   His call: Karla, 35px flat, weight 300. Not a clamp — responsive type sizing
   is parked, twice over, so the number he gave is the number that ships at
   every width.

   300 needed the font request widening. l.html was asking Google Fonts for
   Karla wght@400;500;600 only, so font-weight:300 against that would have
   either synthesised a fake light or quietly rendered 400 — the change would
   have looked like it did nothing. The link now requests 200;300;400;500;600.
   200 is in there unused, so trying it is a one-word edit and not another
   network round trip. Verified by rendered width, not by the computed value:
   the computed style reports whatever you asked for whether or not the cut
   exists.

   .centre__a is set in eight places across the era blocks above, two of them
   inside `@media (min-width:820px)`. An unmediated rule at the end of the file
   beats an earlier one of equal specificity whether or not the earlier one sat
   in a media query, so this wins everywhere. Verified by computed style in the
   browser at 390, 820 and 1280 rather than by reading the cascade.

   WHAT IT DOES TO THE MEASURE, unfixed on purpose. H chose max-width:28ch
   against Newsreader at 44.8px, for where the sentence broke. A ch is the width
   of "0" in the current font and Karla's is wider, so 28ch is now 581.6px
   rather than the box H tuned. Measured against the final copy: 4 lines at 820
   and 1280, 6 lines at 390. That is the direct consequence of a flat 35px with
   responsive sizing parked. Left exactly as instructed and flagged, not
   silently corrected. */
.centre__a{
  font-family:var(--sans);
  font-weight:300;
  font-size:35px;
}


/* --- the question, letting the ground through ---------------------------
   opacity:.85 rather than a lighter colour, as asked. The two are not the same
   thing: opacity composites the glyph toward whatever sits behind it, which is
   how the placeholder micro-text in the J block ended up at 2.01:1 without
   anyone choosing that number. Here the ground is known and flat — .band--1 is
   var(--deep) — so the result is predictable and was measured rather than
   assumed. #FBF8F1 at .85 over #2C2023 composites to #DCD8D2. Sampled from the
   rendered pixels, not calculated on paper: 11.06:1, down from 14.80:1 at full
   opacity. The heading sets at 86.4px on desktop and 39px at 390, so it is
   large text either way and its threshold is 3:1; it clears AAA for normal text
   as well. If the band's ground ever changes, this number moves with it. */
.centre__q{opacity:.85}


/* --- 15% more air under the question -------------------------------------
   His ask, on the gap between "What is a Human Care Tag?" and the line under
   it. The gap is --gap-head-sub, set in the K block: 30px below 820, 36px at
   820 and up.

   The variable is NOT bumped, deliberately. K wired it to two things on
   purpose — .sentence{margin-bottom} in the hero and .centre__a{margin-top}
   here — precisely so the two could not drift apart. Raising it would move the
   hero's spacing as well, which nobody asked for and which is exactly the kind
   of change that ships unnoticed. The multiplier is scoped to the one element
   instead, so the hero keeps reading the variable at its own value and the
   relationship K documented stays legible in the source.

   Lands at 34.5px and 41.4px. Measured in the page at 390 and 1280, along with
   the hero's margin-bottom, which is unchanged at 30px and 36px. */
.centre__a{margin-top:calc(var(--gap-head-sub) * 1.15)}


/* ============================================================
   l · hero cue, the question, the definition line. 7 Sep 2026.
   ============================================================ */


/* --- the scroll cue: arrow only, red, and it bounces ---------------------
   The words are out of the markup; the anchor keeps aria-label="Read on", so
   the link still has an accessible name and the cue is still reachable and
   announced. Losing the label with the text would have made it an unnamed link.

   19px -> 22.8px is his 20%, kept as the exact multiple rather than rounded.

   var(--strike) is the hero red. The dark-ground variant does not apply here:
   this sits on --c-hero #FBF8F1, where #C0392B measures 5.13:1. That is an icon
   rather than text, so the bar it has to clear is WCAG 1.4.11 non-text contrast
   at 3:1, and it clears it comfortably.

   BOUNCE, NOT PULSE. The old @keyframes nudge dipped once and eased back, which
   reads as a pulse. This is two descending impacts — 7px, rebound, 2px, settle
   — which is what makes an eye read "bounce". 1.4s against the old 2.6s, so
   nearly twice the frequency. nudge is left above, unused, like every other
   superseded rule in this file.

   THE REDUCED-MOTION RULE HAS TO BE RESTATED HERE. There is already one at line
   459, but it sits ABOVE this block, and a later unmediated `animation:` wins
   over an earlier one inside a media query. Without the repeat below, this
   change would have quietly reintroduced motion for people who asked for none. */
.cue{color:var(--strike)}
.cue:hover{color:var(--strike);filter:brightness(.85)}
.cue svg{width:22.8px;height:22.8px;animation:cue-bounce 1.4s var(--ease) infinite}
@keyframes cue-bounce{
  0%,55%,100%{transform:translateY(0)}
  20%{transform:translateY(7px)}
  38%{transform:translateY(2px)}
}
@media (prefers-reduced-motion:reduce){
  .cue svg{animation:none}
  .cue:hover{filter:none}
}


/* --- the question, more ground through it -------------------------------
   .85 -> .7. #FBF8F1 at .7 over --deep #2C2023 composites to #BDB8B3, sampled
   from the rendered pixels: 7.98:1, down from 11.06:1 at .85 and 14.80:1 at
   full opacity. Still clears AAA for normal text, and the heading is large type
   besides. */
.centre__q{opacity:.7}


/* --- the definition line: white, and leading that belongs ----------------
   COLOUR. Stated as `.band--1 .centre__a` and not as `.centre__a`, because the
   J block sets `.band--1 .centre__a{color:var(--on-dark)}` at 0-2-0. A bare
   .centre__a rule here would be 0-1-0 and would lose silently — the line would
   have stayed #FBF8F1 and the change would have looked like it did nothing.
   Verified by computed style. #fff on --deep is 15.70:1, sampled off the
   rendered glyphs at 15.56:1.

   LEADING. His note: it reads tight against sections that are spacious. It was.
   Measured across the page there are three families and .centre__a was in the
   wrong one:

     Newsreader display heads   1.04 - 1.08   (.centre__q 1.04, .row__head,
                                               .point__say, .two__head 1.06,
                                               .ctx__head 1.08)
     Karla body copy            1.62          (.row__text p, .point__body,
                                               .ctx__lead, .pane p)
     Karla, one large line      1.42          (.hero__sub)

   .centre__a was on 1.06 — a serif display ratio, left behind when the line
   moved to Karla and nobody re-chose it. That is the whole of the problem.

   1.42 is the answer rather than a new number, because .hero__sub is the only
   other large Karla line on the page and this is its sibling. 1.62 would be the
   body value and is too airy at 35px; 1.06 is a 90px-Newsreader value and is
   what he was reacting to. At 35px this computes to 49.7px. */
.band--1 .centre__a{color:#fff}
.centre__a{line-height:1.42}


/* --- the question in gold ------------------------------------------------
   Stated as `.band--1 .centre__q`, not `.centre__q`, for the same reason the
   definition line's colour is: the H experiment block sets
   `.band--1 .centre__q{color:var(--on-dark)}` at 0-2-0, and a bare rule here
   would be 0-1-0 and lose without a sound. Matching specificity, later in
   source. Verified by computed style.

   THE OPACITY IS OFF, and that is the point. .85 was tried, then .7, both while
   the heading was still near-white and the ask was "let the ground through".
   The colour answers that ask directly, so the transparency was doing the same
   job twice and taking the hex with it: at .7 this composited to #9B7A51 on
   screen, measured, which is a duller gold than the one he chose and only
   3.96:1. Both values are left in the file above, superseded rather than
   stripped, so the sequence still reads.

   #CAA066 on --deep #2C2023 measures 6.53:1. The heading is display type, so
   the bar is 3:1 and it clears it twice over; it also clears AA for normal text
   at 4.5:1, which the .7 version did not. It does not reach AAA (7:1), which
   nothing on this page is held to. */
.band--1 .centre__q{color:#CAA066}
.centre__q{opacity:1}


/* ===========================================================================
   M: THE LOGO. The only difference between style-l.css and style-m.css.

   Mark 09 as settled, set as live type rather than a picture of type:
   Fraunces 500, opsz 144, SOFT 40, WONK 1, lowercase, one line,
   tracking -0.024em, word #2C2023, full stop #C0392B.

   Sizes. L set the logo in Newsreader at 19 / 22 / 16 px. Fraunces lowercase
   carries less height per point than Newsreader sentence case does, so those
   three are multiplied by about 1.2 to hold the same presence in the bar:
   23 / 26 / 19. The breakpoints are L's own, repeated here rather than edited
   in place so the diff between the two files stays one block long.

   Everything else in this file is L, untouched.
   =========================================================================== */

.logo{
  font-family:"Fraunces",Georgia,serif;
  font-weight:500;
  font-variation-settings:"opsz" 144,"SOFT" 40,"WONK" 1;
  font-size:23px;
  letter-spacing:-.024em;
  line-height:1;
  white-space:nowrap;
  color:var(--deep);
}
.logo__stop{color:var(--strike)}

@media (min-width:820px){
  .logo{font-size:26px}
}
@media (max-width:400px){
  .logo{font-size:19px}
}


/* ===========================================================================
   M, SECOND BLOCK: THE FOOTER LOGO AND THE GRADIENT

   ---------------------------------------------------------------------------
   THE GRADIENT DID NOT EXIST.

   Worth writing down plainly, because it changes what this block is. There was
   no gradient anywhere in this stylesheet before today: `linear-gradient`
   appeared zero times, .foot was `background:var(--deep)` and .band--1 was the
   same flat colour. Measured in the browser, the footer's left gutter is
   #2C2023 from its top edge to its bottom edge, identical to four decimal
   places.

   What is actually there is .foot__brand: a wordmark at 13.4vw sitting at
   `bottom:-.30em` in rgba(255,255,255,.075). It is centred, and it is huge,
   so it lifts the luminance of the lower middle of the footer by about three
   points and the eye reads that as a gradient. The effect is real. The
   gradient was not.

   So this builds one for the first time, and puts the same treatment on
   section 2, which is what was asked for.

   ---------------------------------------------------------------------------
   WHY IT STAYS FLAT FOR THE FIRST 58 PER CENT.

   Not taste. #93887F on #2C2023 measures 4.54:1, which clears WCAG AA for
   normal text by four hundredths. Lightening the ground under it at all takes
   it below the line: on the proposed #372F31 it is 3.76:1 and .foot__copy
   fails. Rather than introduce a third grey to the footer, which this file has
   already refused once, the lift is held back until below every line of text.

   Measured: all footer text ends by 50 per cent of the footer's height, and
   the last 210px is padding carrying nothing but the ghosted wordmark. The
   lift starts at 58 per cent, so no text ever sits on anything but #2C2023.

   Re-measured on the new bottom colour #372F31, for the things that DO sit
   near it:
     #FBF8F1                12.27:1   (was 14.80 on flat)
     #CFC6BE                 7.73:1
     #CAA066 heading         5.41:1   (was 6.53)
     .centre__q at opacity 1, gold, is display type at a 3:1 bar and clears
     it by a factor of 1.8.
   Nothing on either surface drops below AA.
   =========================================================================== */

.foot{
  background:linear-gradient(180deg,
    var(--deep) 0%,
    var(--deep) 58%,
    #372F31 100%);
}
.band--1{
  background:linear-gradient(180deg,
    var(--deep) 0%,
    var(--deep) 58%,
    #372F31 100%);
}

/* ---------- the footer logo ----------
   Mark 09 as settled, live type. Fraunces 500 at opsz 144, SOFT 40, WONK 1,
   lowercase, tracking -0.024em.

   Contrast is deliberately one step down from the footer's own link colour.
   #BDB2AA measures 6.27:1 on #372F31 and 7.53:1 on #2C2023, so it is legible
   everywhere and still recedes: it blends into the footer rather than
   announcing itself, which is what was asked for. The stop keeps the
   correction red at the same reduced weight so it does not shout across a
   quiet block. */
.foot__logo{
  font-family:"Fraunces",Georgia,serif;
  font-weight:500;
  font-variation-settings:"opsz" 144,"SOFT" 40,"WONK" 1;
  font-size:26px;
  letter-spacing:-.024em;
  line-height:1;
  white-space:nowrap;
  color:#BDB2AA;
  /* Longhands, not `margin:0 0 34px`. The shorthand would set margin-inline
     to 0 and cancel the `margin-inline:auto` that .foot > * uses to centre
     every footer child in the 820px column, which would pin the logo to the
     padding edge while everything else stayed centred. See block three. */
  margin-block-start:0;
  margin-block-end:34px;
}
.foot__logo-stop{color:#B15547}

@media (min-width:820px){
  .foot__logo{font-size:30px;margin-block-end:40px}
}
@media (max-width:400px){
  .foot__logo{font-size:22px;margin-block-end:28px}
}

/* ---------- the ghosted wordmark ----------
   Same element, same position, same opacity as before. Only the typeface and
   the case change, so it is 09 rather than a different serif setting of the
   name. Fraunces lowercase is wider per em than Newsreader sentence case, so
   the size comes down from 13.4vw to 11.6vw to keep it inside the viewport.

   The crop is recomputed rather than carried over. With line-height .82 the
   content box bottom sits 0.0485em above the baseline, so `bottom: -.13em`
   puts the baseline 0.0815em below the footer's edge. Fraunces' x height is
   0.482em, so 83 per cent of the lowercase still shows and what gets eaten is
   the descender of the g and a sliver of the feet. At the -.30em the
   Newsreader version used, a lowercase setting loses half its x height. */
.foot__brand{
  font-family:"Fraunces",Georgia,serif;
  font-weight:500;
  font-variation-settings:"opsz" 144,"SOFT" 40,"WONK" 1;
  font-size:11.6vw;
  letter-spacing:-.024em;
  bottom:-.13em;
}
.foot__brand-stop{color:rgba(192,57,43,.16)}


/* ===========================================================================
   M, THIRD BLOCK: THE FOOTER, HIS FIVE NOTES
   =========================================================================== */

/* --- 1 and 2 · the ghosted wordmark: full bleed, and lifted ---------------

   FULL BLEED. It was never capped: .foot__brand has carried
   `max-width:none;margin-inline:0` since L, and it is position:absolute and
   centred on the footer rather than on the 820px column. The space at the
   sides was the SIZE, not the box. Newsreader sentence case at 13.4vw filled
   the screen; Fraunces lowercase at the same size does not, because lowercase
   is shorter per character.

   So the size is recomputed from the font rather than nudged by eye. Measured
   at opsz 144, wght 500, tracking -0.024em:

     advances, whole string          6.206em
     less the period                 6.011em
     less 14 letter-spaces           5.675em   (period starts here)
     plus the period's right bound   5.839em   (ink ends here)
     less the h's left bearing       5.822em   INK WIDTH

   100 / 5.822 = 17.18vw for ink exactly the width of the viewport. 17.4vw is
   used, which overhangs by 0.65vw a side, so it is edge to edge at every width
   rather than edge to edge at one of them. .foot already has overflow:hidden,
   so the overhang crops instead of scrolling.

   THE LIFT. --brand-lift is a percentage, and percentages on `bottom` resolve
   against the containing block's height, so 3% is literally three per cent of
   the footer. Both of his numbers are here. Swap the two lines to see 5%. */

/* THE LADDER. Measured at 1200px wide, where the mark is 209px and its
   x height is 101px. Each rung is a real render, not arithmetic:

     3%   baseline 3px ABOVE the edge     descender fully cut, flat feet
     2%   4% of the x height gone
     1%   10% gone                        feet clipped, obviously deliberate
     0%   16% gone                        LIVE
    -1%   23% gone
    -2%   28% gone                        the last rung that still reads
    -4%   40% gone                        a, e and c lose their bowls
    -6%   52% gone                        texture, not a word

   Two things worth knowing before pushing it further.

   One: the descender is already gone at 3%. There is no setting below that
   which trims only the tail, because 3% IS that setting. Everything under it
   eats the x height, which is a different kind of cut and a louder one.

   Two: he asked to go from "five" to "two", a three point drop. The live value
   was 3%, not 5%, so following the arithmetic would have landed on 0%. It has
   landed on 0% anyway, by intent rather than by accident: three points down
   from what was actually on screen. Recorded so the next number starts from
   the right place.

   The unit is a percentage of the FOOTER'S height, so the crop is not identical
   at every breakpoint: a stacked mobile footer is taller, and 1% of it is more
   pixels. If that drift ever matters, 1% is about 0.029em at 1200px, so the
   whole thing can move to em and stop depending on the footer at all. */

.foot__brand{
  /* --brand-lift:1%; */
  --brand-lift:0%;
  /* --brand-lift:-2%; */
  /* --brand-lift:-4%; */
  font-size:17.4vw;
  bottom:calc(-.13em + var(--brand-lift));
}

/* --- 3 · the small logo, aligned with Home -------------------------------

   This was my bug and it is the exact trap this file warns about further up:
   "margin-inline, never a `margin:` shorthand". `.foot > *` centres every
   direct child of the footer in an 820px column with `margin-inline:auto`, and
   my `margin:0 0 34px` on .foot__logo reset margin-inline to 0, which pinned
   it to the padding edge while .foot__cols stayed centred. Longhands only from
   here, so the auto margins survive and the logo shares its left edge with
   Home, About, Privacy, Terms. */

/* Fixed at source in block two rather than patched here, so there is one
   .foot__logo margin rule on the page and not two arguing. */

/* --- 4 · the accounts, level with Home -----------------------------------
   The three columns were staggered on purpose: pages 0, accounts 36, sign-off
   84. The sign-off is gone and he wants the accounts level, so the stagger is
   now no stagger. --foot-stag-social is left in place rather than deleted, so
   the original rhythm is one number away. */
:root{--foot-stag-social:0px}

/* --- 5 · the sign-off ----------------------------------------------------
   Out of the markup, still styled. Everything under "the sign-off" above, plus
   the four .foot__strike colour rules and the placement rule inside
   `@media (min-width:820px)`, is now unused CSS. It is deliberately NOT
   deleted: he said "let's see what that looks like", which is a look rather
   than a decision, and restoring it is one paste in m.html.

   The third grid track is left as minmax(0,1fr). With nothing in it, the two
   remaining columns sit left and the slack collects on the right, which is
   what he is asking to see. */


/* ================= N =================
   9 Sep 2026. His note: "I want to see more of the photo. Whatever frame you
   put around that right now, make that ratio bigger. Let the photo stick out a
   little bit on the other side, wider by like 20% in terms of ratio. The height
   can stay the same."

   So the picture gets 20% more WIDTH and keeps its HEIGHT. Under object-fit:
   cover that means 20% more of the frame becomes visible, rather than the same
   crop drawn bigger. Seeing more of the photograph is the thing he asked for,
   and it is not the same request as making the picture larger.

   THE EXTRA WIDTH COMES FROM OUTSIDE THE CONTAINER, never from the text column.
   The figure grows outward toward the page edge and the text keeps the measure
   and rhythm he already signed off in G.

   --art-max is still computed from the ORIGINAL --art-w on purpose, so the
   ceiling does not move and neither does the height. Do not "tidy" it to use
   the new width; that would undo half the note.

   Direction is handled by justify-self, not by negative margins. The figure is
   a grid item wider than its own track, so it overflows to whichever side it is
   NOT aligned to: default start for the rows with art on the right, end for
   .row--flip where the art sits on the left.

   THE BLEED IS CAPPED at the room that actually exists outside the container —
   the gutter, plus whatever margin the viewport gives beyond 1220px. Without
   the cap a 900-1200px viewport pushes the picture off-screen and the whole
   page scrolls sideways.

   Verified by arithmetic over every width from 820 to 2600, not by eyeballing a
   few: worst-case overflow is 0.00px, because the cap is the available room by
   construction. Note the consequence — BELOW ABOUT 1317px THE BLEED IS LESS
   THAN 20%, since 20% of the column is wider than the room that exists out
   there. It takes what is available. Full 20% from 1317 up.
   ==================================== */

@media (min-width:820px){
  .row__art{
    --art-room:calc(var(--gut) + max(0px, (100vw - 1220px) / 2));
    --art-bleed:min(calc(var(--art-w) * .20), var(--art-room));
    width:calc(100% + var(--art-bleed));
  }
  /* art on the left: overflow outward to the left instead */
  .row--flip .row__art{justify-self:end}
}


/* --- O: the why-line under the definition ---------------------------------
   Body font on purpose. The definition above it is the serif voice of the
   page; this is the plain-spoken follow-up, so it must not compete. Set in
   --on-dark-soft rather than full white for the same reason: present, quieter.
   max-width is wider than .centre__a's 26ch because this is a sentence to read
   rather than a line to land. */
.centre__why{
  font-family:var(--sans);font-weight:400;
  font-size:clamp(1rem,2.4vw,1.12rem);
  line-height:1.55;letter-spacing:0;
  color:var(--on-dark-soft);
  max-width:46ch;margin:22px auto 0;text-wrap:balance;
}
@media (min-width:820px){
  .centre__why{margin-top:28px}
}


/* ===================== P: the type test =====================
   Last block in the file on purpose, so these win on source order without
   needing inflated selectors or !important.

   .centre__a keeps its 24ch measure. ch scales with font-size, so the three
   line breaks he liked - "Your instructions for others / on how you want to
   be treated / in different areas of your life." - survive the drop from 35
   to 25. Verified in the browser, not assumed.
   ============================================================ */
@media (min-width:820px){
  .sentence{font-size:clamp(3.8rem,7.6vw,5.625rem)}   /* cap 90px */
  .centre__q{font-size:clamp(3.6rem,7.4vw,5.625rem)}  /* cap 90px, matches the hero */
  .hero__sub{font-size:1.5625rem}                     /* 25px */
  .centre__a{font-size:1.5625rem;max-width:24ch}      /* 25px */
  .centre__why{font-size:1.5625rem;max-width:34ch}    /* 25px */
}


/* ===================== R: section 2 is one voice ==========================
   One measure for both paragraphs, declared once. Change this number and the
   two blocks stay identical to each other, which is the point of the brief. */
@media (min-width:820px){
  .centre{--s2-measure:34ch}
  .centre__a,
  .centre__why{
    font-family:var(--sans);
    font-weight:400;
    font-size:25px;
    line-height:39px;          /* his number, flat px on purpose */
    letter-spacing:0;
    max-width:var(--s2-measure);
    margin-left:auto;margin-right:auto;
  }
  .centre__a{color:var(--on-dark);margin-top:30px}
  .centre__why{color:var(--on-dark-soft);margin-top:26px}
}


/* --- R, second pass ------------------------------------------------------
   His notes: the hero breaks "Treat others / like they want / to be treated",
   the sentence gets a full stop, and the stop is brand red - the same move the
   wordmark makes, so the page and the mark agree.

   Section 2 becomes genuinely ONE piece of writing. Same font, same size, same
   line-height, same measure AND the same colour - the white/grey split was the
   last thing making it read as two things stuck together. The only separation
   left is the gap between paragraphs, which is what he asked for.
   -------------------------------------------------------------------------- */
.stop{color:var(--strike)}

@media (min-width:820px){
  .centre__a,
  .centre__why{
    color:var(--on-dark);
    margin-top:0;
  }
  .centre__a{margin-top:30px}
  .centre__why{margin-top:39px}   /* one line of leading, so the gap is the rhythm */
}


/* One colour, actually. .centre__a was landing on pure #FFF from a rule with
   higher specificity than a bare class, while .centre__why sat on the page's
   own cream. Two whites four points apart is exactly the "different colours"
   he could see and I had called identical. Both are now pinned to --on-dark
   at .band--1 specificity so nothing upstream wins. Checked in the browser,
   not assumed - the last version passed a font check and failed a colour one. */
@media (min-width:820px){
  .band--1 .centre__a,
  .band--1 .centre__why{color:var(--on-dark)}
}


/* --- R, third pass -------------------------------------------------------
   1. Hero to 93svh on load. svh not vh, so mobile browser chrome does not
      make it taller than the screen it is measuring against.

   2. The hero's whole content block moves down 50px - headline, sub-line and
      button together, since they sit in one .hero__in. Padding, not margin,
      so the 93svh box grows with it rather than the content escaping.

   3. Section 2 finally reads as ONE box. The two paragraphs already shared a
      container width to the pixel; what he could see was the TEXT inside them.
      .centre__a had text-wrap:balance, which deliberately shortens lines to
      even them up, so its longest line ran well short of the measure while
      .centre__why filled it. Same box, different-looking block.

      Balance is off here and both now fill the same measure. The cost is real
      and worth stating: the break he liked - "for others / to be treated /
      of your life" - was a product of balancing. It changes.
   -------------------------------------------------------------------------- */
@media (min-width:820px){
  .hero{min-height:93svh}
  .hero__in{padding-top:122px}      /* was 72, +50 */
  .centre__a{text-wrap:initial}
  .centre__why{text-wrap:initial}
}


/* --- R, third pass corrected ---------------------------------------------
   Both of the last two moves were wrong and the browser said so.

   HERO. Adding 50px of padding grew the content past the box, so the hero
   measured 107% of a 763px-tall viewport instead of 93% - the opposite of
   "fits on load". The 50px is now a transform, which moves the block visually
   without adding to its height, so 93svh actually holds.

   SECTION 2. Turning balance off did equalise the line widths (492 against
   503, near enough) but it orphaned the last word: "life." alone on its own
   line at 40px. Balance is back on both.

   The real constraint, stated plainly rather than fudged: these are two
   sentences of very different length - 89 characters against 124 - centred on
   one measure. Equal containers do NOT give equal-looking text blocks, and no
   amount of CSS changes that. The only way to make them the same visual width
   is to force the breaks by hand. Offered, not assumed.
   -------------------------------------------------------------------------- */
@media (min-width:820px){
  .hero__in{padding-top:72px;transform:translateY(50px)}
  .centre__a,
  .centre__why{text-wrap:balance}
}


/* Balance off, orphan solved at the source. With balance off the two blocks
   fill the same measure and finally look like one box. The only thing that was
   wrong with it was the last word landing alone, so the last two words of each
   paragraph are joined with a non-breaking space. The line ends "your life."
   rather than "life." and nothing else has to move. */
@media (min-width:820px){
  .centre__a,
  .centre__why{text-wrap:initial}
}


/* --- R, fourth pass ------------------------------------------------------
   He spotted it from behaviour rather than from the code, and he was right:
   the definition's font GREW as the window narrowed. .centre__a carried
   font-size:clamp(1.35rem,5vw,1.9rem) from the original design, so below the
   820px breakpoint it went back to scaling on its own while the paragraph
   under it stayed put. Two paragraphs, two different responsive curves.

   The fix is his: .centre__a is gone from the markup. Both paragraphs are
   .centre__why now, so there is one class, one curve, one box, at every width.
   Nothing to keep in sync because there is only one thing.

   Measure widened to 46ch so the definition sets on two lines on desktop.

   The hero's 50px shift is removed - too much air on top once he saw it.
   -------------------------------------------------------------------------- */
@media (min-width:820px){
  .hero__in{transform:none}
  .centre{--s2-measure:46ch}
}


/* --- R, fifth pass -------------------------------------------------------
   THE COLOUR CHANGE HE SAW IS MINE. I pinned both paragraphs to --on-dark
   inside @media (min-width:820px). Below that breakpoint the rule stopped
   applying and .centre__why fell back to --on-dark-soft, so the text went
   grey on a phone. The pin belongs OUTSIDE the media query - it is a brand
   decision, not a desktop one. Same mistake in shape as the font-size clamp
   he found: I fixed the desktop and left the small screens on the old path.

   MEASURE. 46ch bought two lines on desktop but spread the column wider than
   the phone version he liked. 38ch is the compromise, and it is a compromise:
   the definition goes back to three lines. Two lines and a narrow column
   cannot both be had at 25px - the sentence is 89 characters and needs about
   45 of them per line to fit on two.
   -------------------------------------------------------------------------- */
.band--1 .centre__why{color:var(--on-dark)}

@media (min-width:820px){
  .centre{--s2-measure:38ch}
}


/* --- R, sixth pass: section 2 matches body text on mobile ------------------
   His note: on a phone the definition sat at a different size and leading to
   the body copy everywhere else. It did.

   Body copy on small screens is .row__text p at 1.08rem (17.28px) inheriting
   the body's 1.62 leading. Section 2 was on clamp(1rem,2.4vw,1.12rem), which
   floors at 16px on a phone, with 1.55 leading. So 16/24.8 against 17.28/28 -
   close enough to look like a mistake rather than a decision, which is exactly
   how he described it.

   Both rules verified as applying at ALL widths before matching to them, so
   this is not another desktop-only fix. Capped at 819px so the desktop
   25px/39px he set is untouched.
   -------------------------------------------------------------------------- */
@media (max-width:819px){
  .centre__why{
    font-size:1.08rem;
    line-height:1.62;
  }
}


/* --- R, seventh pass: the tablet band ------------------------------------
   From his iPad Pro screenshot. Three faults, one cause between them.

   1. "Different contexts. / Different needs. / Different care tags." carries
      forced breaks. In a half-width column each of those three lines ALSO
      wraps, so it came out on five lines with "tags." alone.
   2. The picture touched the right edge with no gutter. That is MY bleed from
      the third pass: the cap is the gutter plus whatever the viewport gives
      beyond 1220px, and below 1220 that is the ENTIRE gutter. On a wide
      desktop it reads as a deliberate bleed; at 1024 it eats all the margin.
   3. The images looked small against a tall column of text.

   All three are the two-column split being asked to work in a width that
   cannot hold it. So the split now starts at 1080px, not 820. Between 820 and
   1079 the rows stack, exactly like the phone layout he said looks excellent -
   the heading gets full width and its forced breaks work again, and the
   picture is full width with a real gutter on both sides.

   The bleed also keeps 24px in reserve now, so it can never take the last of
   the gutter at any width.
   -------------------------------------------------------------------------- */
@media (min-width:820px){
  .row__art{
    --art-bleed:min(calc(var(--art-w) * .20), max(0px, calc(var(--art-room) - 24px)));
  }
}

@media (min-width:550px) and (max-width:979px){
  .row{grid-template-columns:1fr;gap:34px}
  .row--flip .row__text{order:1}
  .row--flip .row__art{order:2;justify-self:auto;margin-left:0}
  .row__art{
    align-self:auto;position:static;min-height:0;
    width:100%;transform:none;
  }
  .row__art img{
    position:static;transform:none;
    width:100%;height:auto;max-height:none;
    border-radius:var(--r);
  }
  .row__text p{max-width:56ch}
}


/* --- R, eighth pass: the stacked band gets a column --------------------------
   Breakpoint to 980, his number.

   Full-width was the wrong answer for the stacked rows: the picture spanned the
   whole page and dominated the text it was supposed to support. Both the text
   and the picture now sit in one 620px column, centred on the page, with the
   words still ranged left inside it. Centred BLOCK, left-aligned TEXT - those
   are different things and only the first one was wanted.

   One --stack-col variable for both, so they share an edge exactly and stay
   sharing it if the number changes.
   -------------------------------------------------------------------------- */
@media (min-width:550px) and (max-width:979px){
  .row{--stack-col:550px}
  .row__text,
  .row__art{
    width:100%;
    max-width:var(--stack-col);
    margin-inline:auto;
  }
  .row__text{text-align:left}
  .row__text p{max-width:none}
}


/* --- R, ninth pass: the flipped rows were the off-centre ones ---------------
   He saw it immediately: images 1 and 3 aligned, 2 and 4 sat left. Those two
   are the .row--flip rows, and the cause is specificity, not layout.

   The seventh pass reset the flipped art with `.row--flip .row__art{margin-left:0}`
   at 0-2-0. The eighth pass then centred everything with `.row__art{margin-inline:auto}`
   at 0-1-0. Lower specificity, so margin-left:0 kept winning on exactly those
   two rows and they hugged the left edge while the others centred.

   Fixed at matching specificity rather than by deleting the earlier rule, so
   the flip reset still does its job in the horizontal layout.

   Column to 550, his number.
   -------------------------------------------------------------------------- */
@media (min-width:550px) and (max-width:979px){
  .row--flip .row__art,
  .row--flip .row__text{
    margin-inline:auto;
    justify-self:auto;
  }
}


/* --- R, tenth pass: the stacked band starts at 550, not 820 -----------------
   His note, and he is right: 980 down to 820 looked excellent, then at 820 it
   changed again and the picture stretched out for the whole run down to about
   550. That gap existed because the stacked rules were written to start at the
   old two-column breakpoint rather than at the width where they stop being
   needed.

   The band is now 550 to 979 throughout, so the 550px column and its padding
   hold across the whole tablet and large-phone range. Below 550 the phone
   layout takes over, which is the one he said looks excellent.

   No rule inside the band needed changing to move its floor: everything in it
   either undoes a desktop rule that does not apply down there anyway, or sets
   a width that is now simply reached sooner.
   -------------------------------------------------------------------------- */


/* --- R, eleventh pass: the heading, answered rather than just changed --------
   His question: the two paragraphs are a fixed size and the heading scales,
   should the heading be fixed too? The word he was reaching for is FLUID type -
   sizes set in vw, usually inside clamp().

   My answer is no, keep it fluid, but fix the two things that made it look
   wrong. Fixed px on display type is the wrong trade: it either overflows a
   narrow phone or sits marooned on a wide desktop. Body copy is different, it
   has a comfortable reading size and should hold it.

   1. THE JUMP AT 820 IS A REAL FAULT, not a preference. There were two separate
      clamps either side of that breakpoint - clamp(2.4rem,10vw,4.6rem) below and
      clamp(3.6rem,7.4vw,5.625rem) above - so the size stepped discontinuously as
      the window crossed it. One clamp across all widths now, so it grows
      smoothly and never jumps.

   2. THE LINE COUNT WAS NOT MONOTONIC, which is why it looked erratic: fluid
      type inside a fixed container means a NARROWER window can put the heading
      on FEWER lines, because the type shrank faster than the box did. That is
      why it was two lines wide, one line at 1022, then changed again at 820.
      The break is forced in the markup now, so it is two lines at every width
      and the size is the only thing that moves.
   -------------------------------------------------------------------------- */
.centre__q{font-size:clamp(2.4rem,6.2vw,5.625rem)}
@media (min-width:820px){
  .centre__q{font-size:clamp(2.4rem,6.2vw,5.625rem)}
}


/* --- R, twelfth pass: the heading holds its proportion to the body ---------
   His eye again, and the numbers agree with it: section 2 looked fine wide and
   collapsed as the window narrowed. Measured before touching anything -

     .centre__q / .centre__why    3.60 at 1452+   2.98 at 1200   2.73 at 1100
                                  2.48 at 1000    2.03 at 820
     .sentence  / .hero__sub      3.60 at 1200+   3.34 at 1100   2.74 at 900
                                  2.49 at 820

   THE CAUSE. Above 820 the body copy is flat 25px (his number, untouched) and
   the headings were on a steep vw curve that only reached its 90px cap at 1452
   and 1184. A moving heading against a fixed body is a moving ratio, so the
   proportion nearly halved across the desktop band. The heading was never the
   thing that looked wrong; the RELATIONSHIP was.

   THE FIX. A fixed body wants a near-fixed heading. One shallow curve, shared
   by both headings so they cannot drift apart, running 86px at 820 to 90px at
   900 and flat from there:

     clamp(86px, 5vw + 45px, 90px)   ->  ratio 3.44 at 820, 3.60 from 900 up

   Kept as a curve rather than a flat 90px on purpose, and the reason is
   clearance, not fit. A flat 90px DOES fit at 820: "Human Care Tag?" measures
   688.06px in Chromium and 690.6px in WebKit against 708px of column. But that
   is 17-20px, about 2.5%, on a string that carries non-breaking spaces and so
   cannot wrap - if it ever runs out of room it overflows the page rather than
   taking another line. 86px measures 657.48px and leaves 48-50px, about 7%.
   Four pixels of type buys that, and the curve leaves the size somewhere to go
   if the copy or the gutter changes.

   The scrollbar case was checked rather than assumed, because the two things
   disagree: @media matches clientWidth, which EXCLUDES a classic scrollbar,
   while vw resolves against the full window, which INCLUDES it. So the tightest
   in-band moment is clientWidth exactly 820 with vw reading 835 or 837 - the
   font inflates to 86.75/86.85px against an unchanged 708px column. Measured
   clearance there: 44.0px. Still comfortable.

   The step at 820 is deliberate and it is NOT the fault the eleventh pass
   fixed. That one was the heading moving while the body stayed put. Here the
   body steps too (17.28px to 25px) and so does the gutter (22 to 56), so the
   whole section changes gear at once, which is what a breakpoint is. A constant
   ratio above 820 against a body that steps AT 820 is only possible if the
   heading steps with it.

   The hero gains from the same rule: .sentence was on its own curve that read
   86.40px at 819 and 62.32px at 820, a 28% drop for one pixel of window. That
   discontinuity is gone.

   Nothing below 820 changes - 375/600/700/819 measure identical either side of
   this block.

   VERIFIED, from getComputedStyle and getClientRects in headless Chromium 145
   at 375/600/700/819/820/850/880/900/950/1000/1100/1200/1280/1350/1452/1500/
   1600/1920, and in WebKit 26 at 375/819/820/850/900/1000/1100/1200/1280/1452/
   1600: ratio never below 3.44, .centre__q holds two lines and .sentence three
   at every width, no line exceeds its column, documentElement.scrollWidth never
   exceeds clientWidth. Also checked with the webfont blocked (the Iowan/Georgia
   fallback sets NARROWER, 644.8px at 86px) and with a 15px and 17px scrollbar.

   TWO CORRECTIONS TO THIS ENTRY, made by the thirteenth pass. Both were mine,
   and both were wrong in the direction that flatters the change, so they are
   restated here rather than left standing. This block is a log; a wrong line
   in it is worse than no line, because someone will trust it later.

   1. UNITS. This rule shipped as clamp(5.375rem, 5vw + 2.8125rem, 5.625rem).
      Every term but the vw one was rem, and rem tracks the browser's font-size
      setting while the column it has to fit inside (--gut:56px, .centre
      max-width:1000px) does not. So the heading grew and its box did not. At
      Chrome's "Large" (root 20px) the page scrolled sideways 58px at vw 820; at
      "Very Large" (root 24px), 222px at vw 820 and 142px at vw 900. The rule
      this replaced never did that, because its 2.4rem floor was never the
      operative term - mine is floor-dominated across most of the band, which is
      what made rem load-bearing. Restated in px below. The page already sets
      body copy at a flat 25px/39px, so px is the consistent choice here, not a
      concession.

   2. THE FOLD. This entry claimed the hero already overflowed at 1024x768 and
      1280x720 and that the pass "newly breaks 820x760". Measured against 93svh
      rather than against the window, which is the wrong yardstick for whether
      something fits on screen. Against the window, before -> after:

        1280x720   OVER -50.2 -> OVER -50.2   pre-existing, unchanged. Correct.
        1024x768   fits +40.7 -> OVER  -2.2   THIS PASS BROKE IT.
         820x760   fits +53.2 -> fits  +3.9   NOT broken. Margin lost, not fit.
         820x700   fits +27.4 -> OVER -56.1   this pass broke it too.
         900x760   fits +53.2 -> OVER -10.2   ditto, and 1000 and 1100 with it.
        1184x760   OVER -10.1 -> OVER -10.2   already over.

      So the real regression is roughly 820 to 1150 wide at about 760 tall, and
      1024x768 with it. Still not fixed here - that is Martin's call, and
      .hero__in's 96px of bottom padding is the lever - but it is this pass's
      doing and is recorded as such.
   -------------------------------------------------------------------------- */
@media (min-width:820px){
  :root{--display-size:clamp(86px, 5vw + 45px, 90px)}   /* px, see correction 1 */
  .centre__q,
  .sentence{font-size:var(--display-size)}
}


/* --- R, thirteenth pass: the small end of both curves ----------------------
   Three things from Martin, looking at the twelfth pass on the live page, plus
   one unit bug a second reviewer found in it. The unit bug is corrected in the
   twelfth-pass entry above, where the mistake was made; the curves are here.

   1. THE STEP AT 820 WAS TOO BIG. He read it off the screen without seeing the
      code: "jumps from 90 to 50". It was 50.78px at 819 to 86.00px at 820, a
      69% step, because only the top side of the breakpoint was rebuilt last
      pass and the bottom was left on the eleventh pass's 6.2vw. He does not
      want the step gone - the body copy and the gutter both step there too -
      he wants it about 65px on the 819 side. It is now 65.00 -> 86.00, 32%.

   2. THE HERO SAT ON ITS CAP DOING NOTHING. clamp(2.5rem,11.4vw,5.4rem) hit
      its 86.4px ceiling at 758px of viewport, so 758 to 819 was one flat plate
      of type - "it stays big for a long time and it doesn't even need to". The
      new curve's ceiling is not reached until 820.65, so it is still moving at
      every width in the band. Measured at every test width: no two adjacent
      widths above the floor return the same size.

   3. HERO FLOOR TO 45px, his number, up from 40px.

   THE CURVES, in px for the reason given in correction 1 above - a rem-driven
   heading inside a px column is what caused the sideways scroll:

     .centre__q   clamp(38.4px, 5.5vw + 20px, 65px)      65.00 at 819
     .sentence    clamp(45px,   9.2vw + 10.5px, 86px)    85.85 at 819

   Both derived against a measured headroom sweep rather than solved on paper:
   at each width the largest size that still holds the forced break AND fits the
   column was measured first, and the curve kept under it everywhere. Tightest
   points are .centre__q at 700 (58.5 used of 85.5 available) and .sentence at
   414 (48.6 of 67).

   .sentence leaves 819 at 85.85 against 86.00 at 820, so the hero now crosses
   the breakpoint with a 0.15px change. It used to cross at 86.40 -> 62.32.

   FLOORS AND WHERE THEY BIND. .centre__q floors at 38.4px below 334px of
   viewport; .sentence floors at 45px below 375px. A plateau at the bottom is
   what a floor IS - the plateau he objected to was at the top, and that one is
   gone.

   A BUG THIS FIXES WITHOUT BEING ASKED TO. The sub-820 rule it replaces floored
   at 2.4rem, which is the same fault as correction 1 above and it was there
   before the twelfth pass ever ran. At Chrome's "Large" the floor became 48px
   against a 276px column at vw 320; at "Very Large", 57.6px, and 375 went with
   it. Measured on all three stylesheets, same markup, same timing, only the CSS
   swapped, at root 16/20/24 and vw 320/375/600/819/820/900/1100/1920:

     eleventh   8a4039f   root20 vw320 +51   root24 vw320 +130, vw375 +75
     twelfth    32c3870   all of the above, plus root20 vw820 +58 and
                          root24 vw820 +222, vw900 +142
     thirteenth           clean at every root size and every width

   THE 320px KNIFE EDGE, stated because it is real and I am not fixing it. At
   320 the column is 276px and "Human Care Tag?" at the 38.4px floor measures
   273.9px in Chromium and 274.9px in WebKit. That is 2.1px and 1.1px of
   clearance. It is exactly what the page does today - the floor is unchanged in
   size, so 320 renders identically before and after - but it is one bad glyph
   width from wrapping, and it cannot wrap, because the line is nbsp-locked. The
   largest size that fits there at all is 38.5px. If that margin is ever wanted
   the floor has to come down to about 36px, which changes the phone rendering
   he has already approved. Not a call to make quietly inside a type pass.

   The eleventh-pass pair further up this tail -
   `.centre__q{font-size:clamp(2.4rem,6.2vw,5.625rem)}` bare, and the identical
   copy inside @media (min-width:820px) - is now DEAD, both halves. The bare one
   is overridden below 820 by this block and above 820 by the twelfth pass; the
   media-query copy was already overridden by the twelfth pass. Not asserted from
   reading the cascade: both rules were deleted at runtime and every element on
   the page compared before and after - x, y, width, height and computed
   font-size - at 320/375/500/600/700/760/819/820/900/1100/1452/1920. Zero
   elements differ. (With animation on, two do: the .cue arrow is mid-keyframe
   and moves between snapshots. Run with prefers-reduced-motion to see it go.)
   Left in place because this file is an append-only log and removing lines
   breaks the record, but it is dead and should not be edited expecting effect.

   819.98 rather than 819 so there is no width that matches neither block. At a
   fractional viewport - zoom, or a hidpi window - max-width:819px and
   min-width:820px both miss, and the type would drop to whatever it inherits.

   VERIFIED, from getComputedStyle and Range.getClientRects, never screenshots.
   Chromium 145 at 320/360/375/414/500/550/600/700/760/800/819/820/850/880/900/
   1000/1100/1200/1280/1452/1600/1920, WebKit 26 at fourteen of those, and both
   engines agreeing on every size to 0.01px:

     819 -> 820        .centre__q 65.00 -> 86.00 (+32%, was +69%)
                       .sentence  85.85 -> 86.00 (+0.2%, was -28%)
     line counts       .centre__q 2 and .sentence 3 at every width, by both
                       methods - text-node ranges clustered by top edge, and
                       height / line-height
     widest line       inside its column everywhere; tightest are .centre__q at
                       320 (2.1px, see above) and .sentence at 700 (26.5px)
     ratio above 820   3.44 to 3.60 for both pairs, unchanged by this pass
     .sentence         no two adjacent test widths return the same size between
                       the 375 floor and 819
     overflow          scrollWidth never exceeds clientWidth, at root font-size
                       16, 20 and 24px
     below the fold    no width x height combination below 820 that fitted
                       before stops fitting; 320x568 loses margin, 517 to 535
                       in a 568 window, and still clears by 33px
   -------------------------------------------------------------------------- */
@media (max-width:819.98px){
  .centre__q{font-size:clamp(38.4px, 5.5vw + 20px, 65px)}
  .sentence {font-size:clamp(45px, 9.2vw + 10.5px, 86px)}
}


/* --- R, fourteenth pass: the heading can wrap now --------------------------
   A live bug from his screenshot, not a refinement. At a very narrow window the
   section 2 heading ran off the right edge with the "g?" of "Tag?" cut off. He
   was testing around 280 to 300.

   MEASURED ON THE PREVIOUS COMMIT, at the 38.4px floor:

     vw 280   ink reaches 295.9px   page scrolls sideways 16px
     vw 290   ink reaches 295.9px   page scrolls sideways  6px
     vw 300   line 273.9 in a 256px column, 17.9px over, eats the gutter
     vw 310   line 273.9 in a 266px column,  7.9px over, eats the gutter
     vw 320   line 273.9 in a 276px column,  2.1px clear - the knife edge the
              thirteenth pass wrote up, and he is already the wrong side of it

   THE CAUSE was in the markup, not the type. "Human&nbsp;Care&nbsp;Tag?" is one
   unbreakable token, so when it stopped fitting it had nowhere to go and left
   the page instead. A floor can only ever postpone that; it cannot fix it,
   because there is always a narrower screen. His own diagnosis from looking at
   it: the hero wraps, the heading refuses to, make the heading behave like the
   hero. The non-breaking spaces are out.

   The <br> after "What is a" stays. That is the approved shape and it still
   produces exactly two lines everywhere two lines fit. Below that it becomes
   three, which is what wrapping means.

   FLOOR TO 42px, his number. It is only safe BECAUSE the line can wrap now: at
   42px that line sets 301.8px in Chromium and 303.5px in WebKit, wider than the
   276px column at vw 320, so with the nbsp still in it would have overflowed
   harder than the screenshot he sent. Wrapping first, bigger floor second - in
   that order, or the floor is a bug.

   THE COST, stated plainly because it is a real change to the phone rendering.
   Raising the floor moves the two-to-three line transition UP, to 346 in
   Chromium and 347 in WebKit, found by bisection rather than estimated. So 320
   and 336 - iPhone SE and the small Android sizes - now set the heading on
   three lines where they used to manage two. That follows directly from his two
   instructions and cannot be avoided while both hold; the only lever is the
   floor. Kept at 38.4px the transition sits at 320 instead, which is exactly
   where it was overflowing, so the old floor bought two lines by breaking the
   page.

   THE TWO ENGINES BREAK IT DIFFERENTLY below the transition, and both are
   correct - this is text-wrap:balance, which is deliberately not
   pixel-identical across implementations:

     Chromium   "What is a" / "Human Care" / "Tag?"       "Tag?" alone, 78.8px
     WebKit     "What is a" / "Human" / "Care Tag?"       evener, no orphan

   Chromium leaving "Tag?" on its own line is the one cosmetic wart in this
   pass. It does not overflow and it is not a bug, but it is visible on a small
   Android or an SE, and the fix would be a hand-placed break, which reintroduces
   exactly the rigidity this pass removed. Flagged, not fixed.

   VERIFIED in Chromium 145 and WebKit 26, from getComputedStyle and
   Range.getClientRects, at 280/300/320/340/344/346/360/375/414/500/550/600/700/
   800/819/820/850/900/1000/1100/1200/1280/1452/1600/1920, plus a 4px sweep of
   the whole 280-360 band:

     no horizontal overflow at any width in either engine, at any point in the
     sweep - scrollWidth equals clientWidth throughout
     two lines from 347 up in both engines, and at every width above 820
     three lines from 345 down in both, where two physically cannot fit
     346 is the one width where they disagree: two lines in Chromium, three in
     WebKit
     both line-count methods agree at every width - text-node ranges clustered
     by top edge, and height / line-height
     nothing at 820 and above moves. Checked head to head rather than by
     comparing two runs: the thirteenth and fourteenth builds served side by
     side, every element on the page compared for x, y, width, height and
     computed font-size at 820/900/1100/1452/1920. Zero differ.
     below 820 the change is contained. At 320 and 375, across all 181
     elements: no element changes WIDTH at all, font-size changes on exactly
     two nodes (.centre__q and the <br> inheriting from it), height changes only
     on the heading's own section and its four ancestors, and the remaining 136
     differences are y - everything under the heading moving down by 51px at
     320, where it gains a line, and 2.8px at 375, where it only gains size
   -------------------------------------------------------------------------- */
@media (max-width:819.98px){
  .centre__q{font-size:clamp(42px, 5.5vw + 20px, 65px)}
}


/* --- R, fifteenth pass: the split-row headings, floor to 35px --------------
   His experiment, his words: "right now it collapses down to 30, let's try it
   at 35, let's see what it looks like." So this is a number to look at, not a
   settled one.

   1.9rem -> 2.1875rem, which is 30.4px -> 35px at a 16px root. STAYS IN REM,
   deliberately: .row__head is rem and its body copy .row__text p is 1.08rem, so
   the pair holds its ratio at any browser font-size setting. Putting a px floor
   on the heading while the body stayed rem would rebuild, in this section, the
   exact fault the twelfth pass shipped and the thirteenth had to undo. Same
   unit as the thing it is measured against, always.

   Scoped below 820 so the flat 2.8rem desktop size is untouched, and written as
   819.98 for the reason given in the thirteenth pass - at a fractional viewport
   max-width:819px and min-width:820px both miss.

   The floor now binds up to 515px of viewport, where it used to bind to 447.

   MEASURED, both engines, all four headings, widest rendered line against its
   .row__text column. Clearance at 280, the narrowest he tests:

     "Different contexts. / needs. / care tags."      221.9 in 236    +14.1
     "Who taught you to speak for your needs?"        210.7 in 236    +25.3
     "The garden centre worked this out first"        197.5 in 236    +38.5
     "Not another personality type"                   224.1 in 236    +11.9  <- tightest

   No overflow at any width in either engine, at a default root font-size.
   scrollWidth equals clientWidth at 280/300/320/360/375/414/500/550/600/700/
   819/820/900/1200/1600. Head to head against the fourteenth pass, every
   element compared: ZERO differ at 820/900/1200/1600/1920, so the flat 2.8rem
   desktop size is genuinely untouched. Below 820, font-size changes on exactly
   six nodes - the four .row__head and the two <br class="brk--all"> that
   inherit from one - no element changes width, and the rest is vertical reflow.

   Head-to-body ratio is 2.03 (35 against .row__text p at 17.28px) and it stays
   2.03 at root 16, 20 and 24, which is what keeping both sides in rem buys.

   BUT: AT A RAISED BROWSER FONT-SIZE THIS FLOOR OVERFLOWS THE PAGE, and the
   cause is a non-breaking space, not the floor. "Not another
   personality&nbsp;type" in r.html is one unbreakable token, exactly the fault
   the fourteenth pass removed from .centre__q an hour earlier. rem grows the
   heading with the browser setting; the column is px and does not follow.
   A/B'd against the fourteenth pass:

     root 16   clean at every width, before and after. This is what he will see.
     root 20   280 +27, 300 +7      both NEW, this pass caused them
     root 24   280 +90, 300 +70     already overflowed at +40 and +20, now worse
               320 +50, 360 +10     both NEW, this pass caused them

   Left as 35px because he asked to see 35px and picking a different number
   quietly is not an answer. The fix is not the floor, it is the nbsp on line
   145 of r.html, and "your&nbsp;needs?" on line 109 is the same shape waiting
   to bite. Both are one-line changes, both are the change he already approved
   for the section 2 heading, and neither is mine to make unasked.
   -------------------------------------------------------------------------- */
@media (max-width:819.98px){
  .row__head{font-size:clamp(2.1875rem, 6.8vw, 2.7rem)}   /* 35px floor, was 30.4px */
}


/* --- R, sixteenth pass: the hero fits on load again ------------------------
   Open since the twelfth pass, which grew .sentence and pushed the hero past
   the bottom of short windows. His design intent is on the record and this
   honours it rather than inventing anything: the hero FITS ON LOAD. An earlier
   attempt at the same intent added padding, grew the box, and measured the hero
   at 107% of the viewport, which is the opposite of the intent.

   WHERE THE HEIGHT ACTUALLY IS, measured rather than assumed:

     nav              96.7   (28px padding top and bottom)
     hero__in        672.5   = 72 top padding
                             + 317.3 h1 (three lines at 90px)
                             +  36   --gap-head-sub
                             +  71   .hero__sub (two lines)
                             +  28   sub margin
                             +  52.3 button
                             +  96   bottom padding
     border            1.0
     ------------------------
     hero            770.2   at 900px wide and up; 756.1 between 820 and 899,
                             where .sentence is 86 to 90px rather than a flat 90

   So a window shorter than 770 cannot hold it, and 1280x720 was 50.2px over.

   THE LEVER IS PADDING, ON SHORT WINDOWS ONLY. 48px off the top and 32px off
   the bottom, 80px in total, which is comfortably more than the 56.1px worst
   case in the band. No type moves - those sizes are settled and he approved
   them tonight - and no margin he tuned is touched, so --gap-head-sub and the
   sub-line's 28px are exactly as they were.

   MAX-HEIGHT 769, NOT A ROUND NUMBER, and chosen from the measurement above:
   the hero needs 770 to fit, so 769 is the last height at which it does not.
   Anything with 770px or more of window is untouched by construction, which is
   how 1440x900 and 1512x982 stay byte-identical - the rule cannot apply to
   them. Gated on min-width:820 as well, because below that the hero already
   fits at every height tested and has its own padding.

   TOP TAKES MORE THAN THE BOTTOM ON PURPOSE. Trimming the bottom pulls the
   hero's edge up towards the button and squeezes the .cue arrow, which sits at
   bottom:22px. 64px of bottom padding leaves the cue 19.2px of clear air below
   the button. Trimming the top just moves the whole block up and costs nothing.

   A SIDE EFFECT WORTH HAVING: at 1280x720 the scroll cue currently renders at
   y=724.4 in a 720px window, so it is below the fold and invisible on exactly
   the screens that most need a scroll hint. After this it sits at 645.4.

   VERIFIED, hero height against the real window height, not against 93svh:

      820x700   OVER -56.1  ->  fits +23.9
      900x760   OVER -10.2  ->  fits +53.2
     1000x760   OVER -10.2  ->  fits +53.2
     1024x768   OVER  -2.2  ->  fits +53.8
     1100x760   OVER -10.2  ->  fits +53.2
     1280x720   OVER -50.2  ->  fits +29.8

   Untouched, and not by inspection - all 181 elements compared for x, y, width,
   height and computed font-size, before against after. ZERO differ at 1440x900,
   1512x982, 1280x800, 1180x820, 1920x1080, 820x1180, 375x812 and 320x568.

   The cue clears the button by 19.2px at worst, and is on screen at every
   viewport in the band, which it was not before.

   THE NEW FLOOR: the hero now fits down to a 691px window, and 677px at 820
   wide, where it used to need 770 and 756. Below that it still overflows. That
   is a smaller window than any laptop sold, but it is not "never".

   ONE HONEST EXCEPTION to "nothing that already fits may change". The rule
   keys on height alone, and between 820 and 899 wide the hero is shorter than
   it is above 900, because .sentence is 86 to 90px rather than a flat 90. So a
   narrow band already fitted at heights the rule still catches. Bisected:

     820 wide   heights 757-769 change though they already fitted
     840 wide   heights 760-769
     860 wide   heights 764-769
     880 wide   heights 767-769
     900 wide   none, and none above

   Those viewports get MORE room, not less - at 820x760 the hero goes from
   fitting by 3.9px to fitting by 53.2px - so nothing there breaks. But it is a
   change to something that was already correct, and it is recorded rather than
   rounded off. Removing it would need the rule to key on width and height
   together, which is more machinery than a 13px band of a rare window size is
   worth.

   CORRECTION, added after a blind review on another model. Every number above
   is Chromium. WebKit sets the natural hero at 766.0px, not 770.2 - 4.2px
   shorter - so in WebKit the hero already fits at heights 766 to 769 at EVERY
   width from 900 up, not only between 820 and 899. The exception band above is
   therefore wider than it says, and the bisection table is Chromium's, not the
   page's.

   1440x900 and 1512x982 do still stay byte-identical, in both engines: 900 and
   982 are both above 769, so the rule genuinely cannot apply to them. That part
   of the claim holds. What was wrong was the SCOPE of the exception, stated
   from one engine and written as though it were the page.

   Nothing breaks either way - the rule only ever adds room - and a 775-point
   grid of 31 widths by 25 heights found zero visible regressions in either
   engine. Recorded because a measurement in this file that is true of one
   browser and written as if true of both is the kind of entry that gets trusted
   later.
   -------------------------------------------------------------------------- */
@media (min-width:820px) and (max-height:769px){
  .hero__in{padding-top:24px;padding-bottom:64px}
}


/* ===========================================================================
   T: homepage build t, 10 Sep 2026. Martin is iterating visually; this file is
   a superset of r.html/style-r.css — everything above is R untouched, so r and
   t diff as pure additions below this line. Four changes:

   1 · the nav logo, 10% bigger
   2 · an "About" link beside the CTA
   3 · alternating section backgrounds, peach/off-white
   4 · all five split rows flipped
   =========================================================================== */


/* --- 1 · logo, 10% bigger --------------------------------------------------
   M's three sizes (23 / 26 / 19px, base / >=820 / <=400) times 1.10, flat:
   25.3 / 28.6 / 20.9. A real 10% at every breakpoint, not a rounded one.
   Placed last in the file so it wins over M's own rules at equal (0,1,0)
   specificity by source order. */
.logo{font-size:25.3px}
@media (min-width:820px){
  .logo{font-size:28.6px}
}
@media (max-width:400px){
  .logo{font-size:20.9px}
}


/* --- 2 · "About", beside the CTA -------------------------------------------
   One link, no menu — the burger/slide-in nav is explicitly out of scope and
   not started here. .nav__right wraps About + the CTA so .nav's own
   justify-content:space-between still just sees two children (logo, the new
   wrapper) and nothing about the existing nav layout has to change.

   About is plain text, --soft, no border/pill — the CTA keeps its solid pill
   as the only thing on the bar that reads as an action. Font-size matches
   .nav__cta's own 14/13px steps so the two sit at the same weight instead of
   About looking like an afterthought. */
.nav__right{display:flex;align-items:center;gap:18px}
.nav__about{
  font-size:14px;color:var(--soft);text-decoration:none;
  white-space:nowrap;
  transition:color .2s var(--ease);
}
.nav__about:hover{color:var(--ink)}
@media (max-width:400px){
  .nav__right{gap:11px}
  .nav__about{font-size:13px}
}


/* --- 3 · alternating section backgrounds -----------------------------------
   Peach #F5EDE3 is his hex — already --c-7, the signup band's own tone.
   Off-white #FBF8F1 is already --c-4 / --c-hero, the hero's own cream — "use
   whatever the page already uses" landed on a colour already live on the page,
   not a new one.

   Nine sections, off-white starting at section 3, strict alternation:
   3 off-white · 4 peach · 5 off-white · 6 peach · 7 off-white · 8 peach ·
   9 off-white · 10 peach · 11 (signup) off-white BY THE ALTERNATION.

   His two asks conflict: off-white at 3 AND peach kept at signup (11), which
   is already --c-7. Strict alternation from 3 cannot deliver both — built his
   stated way (off-white at 3, strict from there, signup stays peach), so the
   doubling lands at the bottom: sections 10 and 11 are BOTH peach, back to
   back. The two clean alternatives, not picked for him:
     a) start peach at 3 instead — the bottom then lands peach on its own,
        no doubling anywhere.
     b) keep off-white at 3 and break the alternation once somewhere less
        visible than the last two sections, e.g. two off-whites adjacent
        higher up the page instead.

   Declared last, so one class beats every earlier .band--N rule at equal
   specificity regardless of which legacy band colour class a section still
   carries — .band--3 and .band--5 are each reused twice on this page for two
   DIFFERENT new colours, and this is what lets that work without splitting
   either class in two. */
.band--offwhite{background:#FBF8F1}
.band--warm{background:#FFF5E9}


/* --- 4 · every split row flipped -------------------------------------------
   His reason: "when I scroll down I'm looking at the image because my eye
   goes to the right, I'd rather have the text there." All five rows inverted
   from r.html — .row <-> .row--flip swapped in the markup, nothing here. The
   image-bleed (N block) and tablet-stack (R block) rules already key off
   .row--flip itself rather than section identity, so both follow the flip
   automatically; verified in the render, not assumed. */

/* --- 2 · "The whole point" on the dark ground -------------------------------
   Same colour as the footer and the "What is a Human Care Tag?" band, on his
   mark. band--1's light-text rules only target .centre__* classes, so this
   section's own .point__* classes need their own overrides or the text stays
   dark on dark and is unreadable. */
.band--deep{background:var(--deep)}
.band--deep .point__say,
.band--deep .point__say em,
.band--deep strong{color:var(--on-dark)}
.band--deep .point__body{color:var(--on-dark-soft)}
.band--deep .point__body em{color:var(--on-dark)}
.band--deep .kicker{color:var(--on-dark-kick)}

/* --- 3 · "tag." in red, on the dark ground ---------------------------------
   His mark. The site's own red is --strike:#C0392B (the hero strikethrough),
   but on --deep it measures 2.89:1 — under even the 3:1 large-text floor, so
   it would be a decorative colour nobody could read. #E74C3C is the same red
   lightened for this ground: 4.11:1, clears AA for large text, and still
   reads as the same accent rather than a new colour. */
.say__hot{color:#E74C3C;font-style:italic}
/* 0-3-0, because .band--deep .point__say em is 0-2-1 and was winning:
   the full stop (a span) went red and "tag" (an em) stayed cream. */
.band--deep .point__say .say__hot{color:#E74C3C}


/* ===========================================================================
   T: mobile burger + slide-in drawer, built 10 Sep. His ask: "a burger that
   turns into an X... dark, black, black with white navigation items."
   Breakpoint matches the nav's own existing split (max-width:819px /
   min-width:820px, see the T block above and R's own nav rules) rather than
   a new one. Colours are var(--deep) / var(--on-dark), both already defined
   above — no new colours introduced.

   .nav__right (About + the CTA pill) is hidden below 820px: the burger
   takes over that job there, so showing both would be redundant on a small
   screen. Above 820px this whole block is display:none — the desktop nav
   is untouched.

   Declared last, same reason as every other T block: wins at equal
   specificity by source order, nothing above needs editing. =============== */

@media (max-width:819px){
  .nav__right{display:none}
}

/* --- burger button -----------------------------------------------------
   display:none until its own script (third <script> block in t.html) adds
   .nav__burger--ready as its very last line, after every listener is wired.
   Gating on that instead of on html.js: html.js is set synchronously in
   <head>, before this script even runs, so it only proves JS is on, not
   that THIS control works — gating on it alone would let a throw partway
   through the script leave a dead button on the page. This way a throw
   anywhere in that script leaves the burger exactly as absent as it is
   with JS off. 36px hit area, comfortably clears the 24px WCAG minimum,
   without the visual box growing to match. */
.nav__burger{
  display:none;position:relative;z-index:1001;
  width:36px;height:36px;padding:0;margin:0;align-items:center;justify-content:center;
  background:none;border:0;flex:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
@media (max-width:819px){
  .nav__burger.nav__burger--ready{display:flex}
}
.nav__burger-box{position:relative;display:block;width:22px;height:16px}
.nav__burger-bar{
  position:absolute;left:0;width:100%;height:2px;border-radius:2px;
  background:var(--ink);
  transition:transform .25s var(--ease),opacity .2s var(--ease),background-color .2s var(--ease);
}
.nav__burger-bar:nth-child(1){top:0}
.nav__burger-bar:nth-child(2){top:7px}
.nav__burger-bar:nth-child(3){top:14px}

/* burger -> X, CSS transform on the bars, no icon swap. Bars also switch to
   --on-dark once open: the drawer sliding in behind the (still-visible,
   z-index:1001) button would otherwise leave a dark X on a dark ground. */
.nav__burger[aria-expanded="true"] .nav__burger-bar{background:var(--on-dark)}
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-child(1){top:7px;transform:rotate(45deg)}
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-child(2){opacity:0}
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-child(3){top:7px;transform:rotate(-45deg)}

/* --- scrim + drawer ------------------------------------------------------
   Both start [hidden] in the markup (display:none, out of the tab order),
   which is what keeps the drawer unreachable by keyboard while closed. The
   script removes [hidden] on open and restores it once the close
   transition ends (or immediately, under reduced motion — see the JS). */
.nav__scrim{
  position:fixed;inset:0;z-index:999;
  background:color-mix(in srgb, var(--deep) 55%, transparent);
  opacity:0;transition:opacity .32s var(--ease);
}
.nav__scrim[hidden]{display:none}
.nav__scrim.is-open{opacity:1}

.nav__drawer{
  position:fixed;top:0;right:0;bottom:0;z-index:1000;
  width:min(320px,82vw);
  background:var(--deep);color:var(--on-dark);
  display:flex;flex-direction:column;justify-content:center;align-items:stretch;
  gap:4px;padding:32px var(--gut);
  transform:translateX(100%);
  transition:transform .32s var(--ease);
  box-shadow:-12px 0 40px rgba(0,0,0,.25);
}
.nav__drawer[hidden]{display:none}
.nav__drawer.is-open{transform:translateX(0)}

.nav__drawer-link{
  display:block;padding:14px 4px;
  font-family:var(--serif);font-size:1.5rem;
  color:var(--on-dark);text-decoration:none;
  border-bottom:1px solid rgba(251,248,241,.14);
}
.nav__drawer-link:last-child{border-bottom:0}

@media (min-width:820px){
  .nav__burger,.nav__scrim,.nav__drawer{display:none!important}
}

@media (prefers-reduced-motion:reduce){
  .nav__burger-bar,.nav__scrim,.nav__drawer{transition:none}
}

/* ============================================================
   MOBILE TYPE SCALE — 11 September 2026, launch day
   ============================================================
   Martin, reading the live site on an iPhone 12 and a 15 Pro Max:
   "make them 10% bigger, let's see what it looks like, we might even go up
   one more from that. My eyesight isn't the bestest but I want it to be
   easy enough to read on mobile."

   ONE KNOB. To go bigger, change --m below and nothing else.
     1.10 = +10%   1.15 = +15%   1.00 = back to where we started

   Why every size is written out rather than scaling the root: this
   stylesheet mixes rem, em and hard px (see .sentence and .centre__q, both
   clamped in px), so scaling html would have moved some text and left the
   rest behind. Every number here was MEASURED at 390px in a constrained
   iframe, not read off the rules above — the file settles several earlier
   cascade fights with appended overrides, so reading the declarations gives
   the wrong answer.

   Deliberately NOT listed: the inline spans (.stop, .say__hot, .fix__in,
   .logo__stop, the -stop pair) and the bare a/p/span/strong/em. They size
   in em off their parent or inherit from body, so they scale on their own.
   Pinning them would freeze relationships the design depends on.

   Mobile only. Desktop is untouched and he was happy with it there.
   ============================================================ */
@media (max-width:819.98px){
  :root{--m:1.10}

  body{font-size:calc(17px * var(--m))}
  h2{font-size:calc(32px * var(--m))}

  .sentence{font-size:calc(46.38px * var(--m))}
  .centre__q{font-size:calc(42px * var(--m))}
  .point__say{font-size:calc(35.2px * var(--m))}
  .row__head{font-size:calc(35px * var(--m))}
  .ctx__head{font-size:calc(32px * var(--m))}
  .two__head{font-size:calc(32px * var(--m))}

  .hero__sub{font-size:calc(18.72px * var(--m))}
  .point__body{font-size:calc(17.6px * var(--m))}
  .centre__why{font-size:calc(17.28px * var(--m))}
  .ctx__lead{font-size:calc(17px * var(--m))}
  .promise{font-size:calc(16.8px * var(--m))}
  .fine{font-size:calc(13.5px * var(--m))}
  .kicker{font-size:calc(15px * var(--m))}
  .pane__label{font-size:calc(15px * var(--m))}

  .btn{font-size:calc(15px * var(--m))}
  .fields button{font-size:calc(15.5px * var(--m))}
  .seg label{font-size:calc(13.5px * var(--m))}

  .logo{font-size:calc(20.9px * var(--m))}
  .nav__about{font-size:calc(13px * var(--m))}
  .nav__cta{font-size:calc(13px * var(--m))}
  .nav__drawer-link{font-size:calc(24px * var(--m))}

  .foot__brand{font-size:calc(67.86px * var(--m))}
  .foot__logo{font-size:calc(22px * var(--m))}
  .foot__copy{font-size:calc(13px * var(--m))}
}

/* --- stragglers -------------------------------------------------------
   Six sizes did not move on the first pass, all for the same reason: a
   compound selector earlier in the file outranks a single class, whatever
   the source order. Found by measuring the result rather than assuming the
   block above had worked — the ratios made them obvious at a glance.
   Same --m knob; these just need the specificity matched.
   --------------------------------------------------------------------- */
@media (max-width:819.98px){
  .row__text p{font-size:calc(17.28px * var(--m))}
  .pane p{font-size:calc(16.32px * var(--m))}
  p.kicker,
  .row__text p.kicker,
  .pane__label,
  .cue{font-size:calc(15px * var(--m))}
  /* .pane p.pane__label is (0-2-1). The comment at the rule itself records
     this same trap biting twice before; this is the third time. */
  p.pane__label,
  .pane p.pane__label{font-size:calc(15px * var(--m))}
  .chr span{font-size:calc(14.5px * var(--m))}
  .ctx span{font-size:calc(14.5px * var(--m))}
}


/* ===========================================================================
   U · HIS TWO NOTES FROM THE IPHONE SCREENSHOTS — 11 September 2026
   ===========================================================================
   "The hero text box wants to be a tad narrower, a little more padding left
   and right." And: "the bug is back where at certain screen sizes the two
   paragraphs render at different widths."

   Mobile only, both of them. Desktop is measured and approved and is not
   touched by either rule.
   =========================================================================== */


/* --- 1 · the hero block, a little narrower -------------------------------
   THE HEADLINE HAS HARD BREAKS, so narrowing the box does not shrink the type
   - it risks rewrapping a line and losing the three-line shape he approved.
   Measured before choosing a number, at .sentence's flat mobile 51.018px:

     "Treat others"     251.52 Chromium   251.55 WebKit
     "like they want"   272.50            273.72   <- the binding line
     "to be treated."   268.06            268.10

   The strike SVG and the handwritten "they" are both absolutely positioned
   and both land INSIDE that 273.72, so they cost nothing. WebKit is the
   number that matters, because he is reading this in Safari on a phone.

   THERE IS NO ROOM AT 320px. Content there is 320 - 2 x 22 = 276px, which
   clears the widest line by 2.28px in WebKit. A flat gutter increase is not
   available at the small end, so the padding is written to grow only out of
   viewport width that actually exists:

     vw 320-340   22px, exactly today's gutter, untouched
     vw 340-364   22 -> 34px, ramping, content held at 296px
     vw 364+      34px, content = vw - 68

   Content width is monotonic in vw. It IS narrower than today's across the
   ramp - at vw 350 it is 296px against today's 306px - so this rule does take
   room away; what it cannot do is take away room the headline needs, because
   the font-size ceiling below reserves exactly the 54px this padding can cost
   at its widest. That is a property of the two rules sharing one constant, not
   of a breakpoint that could be mis-set. Headroom over the widest line once
   the padding engages is 22.28px at worst (vw 340-364) against 12.28px at
   vw 330 today.

   Longhands, not the `padding` shorthand. .hero__in's vertical padding comes
   from TWO places - the unconditioned rule at ~591 (`padding:24px var(--gut)
   84px`) and the mobile override at ~2761 (`padding-top:24px;padding-bottom:
   64px`) - and the shorthand here would silently reset whichever of them won.

   THE COST, measured and bisected a pixel at a time in both engines: the
   .hero__sub line count drops from four to three at vw 389 instead of vw 365,
   so the band 365-388 gains a fourth line. An iPhone SE 3 and a 13 mini are
   375px, so that is a device class, not a gap between them. The hero grows
   29px there and still clears its viewport by 66.7px, and the scroll cue still
   sits 42.1px below the button. Nothing else on the page changes line count at
   any width.

   THE FOURTH LINE IS THE PRICE OF THE PADDING, AND THE &nbsp; IS WHAT MAKES
   IT READ. Four lines ended on "too." alone at 35.3px - the same orphan as
   "life." in section 2, which this file has now fixed twice with a
   non-breaking space. So index.html joins the last two words:

       <b>Soon humans will have them&nbsp;too.</b>

   and the line ends "them too." at 91.5px instead. Measured at 300/320/336/
   360/365/375/384/388/390/414/430 in both engines: 320, 390, 414 and 430 are
   unchanged to the pixel, and 300, 336 and 360 improve too, because that
   orphan was ALREADY there below vw 365 before this pass - the padding widened
   the band it appears in, it did not invent the shape.

   The wider join "have&nbsp;them&nbsp;too." was measured and rejected: it
   gives 281.6 / 267.3 / 173.6 / 142.6 against 281.6 / 267.3 / 224.7 / 91.5,
   which only moves the short line one row up and rags worse.

   It was the sub-line, not the headline, that was touching his margins -
   338.17px of text in a 346px box at vw 390, against the headline's 273.72 in
   the same box - so the sub-line is the element the note was actually about.

   NOTE FOR THE NEXT PASS: t.html still links style-t.css?v=7 and index.html
   now links ?v=10. That is deliberate. t.html is a generation behind on its
   markup, it is not in .deployinclude, and it never ships - so it does not get
   the marker bumps and it does not get this block's markup change. Do not
   "fix" the mismatch; the two files are only comparable as they are.
   ------------------------------------------------------------------------- */
@media (max-width:819.98px){
  .hero__in{
    padding-left:clamp(22px, calc(22px + (100vw - 340px) / 2), 34px);
    padding-right:clamp(22px, calc(22px + (100vw - 340px) / 2), 34px);
  }
}


/* --- 2 · section 2, the two paragraphs at one width ----------------------
   NOT text-wrap:balance, which is where this looked like it was going. The
   three passes above killed balance ABOVE 820px and left the base rule's
   `text-wrap:balance` standing on mobile, so turning it off here looked like
   a free win. Measured, it is not: with balance off, vw 390 and 430 set the
   first paragraph's last line as "your life." alone at 73px, and vw 336 sets
   the second's as "to you." at 56px. That is the exact orphan the third pass
   hit and Martin rejected. The nbsp joins in the markup cannot prevent it -
   they are why the orphan is 73px rather than 40px. Balance stays ON.

   WHAT IT ACTUALLY IS. Balance minimises the longest line for a given line
   count, and the two paragraphs are 89 and 124 characters, so they settle at
   different line counts. Swept every 2px of box width from 270 to 518, both
   engines, longest-line difference between the two paragraphs:

     box <= 292     3 lines vs 5    15.8px apart
     box 294-380    3 lines vs 4    34.0px apart
     box 382-387    3 lines vs 3   123.0px apart   <- THE BUG
     box >= 388     2 lines vs 3     4.5px apart

   The fault is a six-pixel window. box = vw - 44 in this section, so it opens
   at vw 426 (428 in WebKit) and shuts at vw 432 - and an iPhone 15 Pro Max is
   430px. That is his "at certain screen sizes", and it is one device class
   wide, which is why it has survived every sweep done at 320/375/390.

   The cure is to keep the box out of that window. 33ch measures 372.124px
   (Karla's `0` is 0.5935em at 19.008px), so the cap engages from vw 417, not
   424: below that the container is already narrower and nothing changes; from
   vw 417 to 431 the cap holds the box at 372.1px and the pair lands on 34.0px
   apart instead of 123 - 372 sits inside the 294-380 band on the table above,
   which is why the seven widths 417-423 change number without changing shape;
   from vw 432 up the cap is gone and the box reaches 388+ on its own, which
   is the best figure on the table.

   34.0px apart is the bar because 35.6px apart is what DESKTOP does today, at
   a 563.8px measure, and he has approved it there.

   Held in ch rather than px so it tracks --m: at --m 1.15 the cap moves to
   389px and the window moves to 399px, so the margin of safety survives a
   type-scale change, which a flat px cap would not.
   ------------------------------------------------------------------------- */
@media (max-width:431.98px){
  .centre__why{max-width:33ch}
}


/* --- 3 · the headline's floor, restored ----------------------------------
   THIS IS A REGRESSION FROM THIS MORNING, found while measuring note 1, and
   it is not cosmetic: below about 320px the hero headline overflows and the
   whole page scrolls sideways.

   The mobile type scale block above sets .sentence{font-size:calc(46.38px *
   var(--m))} inside @media (max-width:819.98px). The THIRTEENTH pass had set
   .sentence{font-size:clamp(45px, 9.2vw + 10.5px, 86px)} inside the IDENTICAL
   media condition, same selector, same 0-1-0 specificity, earlier in source.
   So the flat value wins everywhere and the fluid curve is dead. 46.38px is
   simply what that clamp evaluated to at the 390px width it was measured at.

   The headline has hard <br>s but its lines can still wrap at their own
   spaces, so the symptom is a collapsing shape rather than a clean overflow:
   measured in both engines, 300px breaks it to FIVE lines and 280px to SIX,
   against the three he approved.

   NOT the sideways scroll, which this rule does not fix and is not the cause
   of. Below a 292px viewport the page scrolls sideways no matter what the
   headline does, and it is the split rows: .row__head carries copy joined
   with &nbsp; ("your&nbsp;preferences?"), which at the mobile 38.5px is a
   270px unbreakable word, and a grid item cannot shrink below its own
   min-content. 270 + 2 x 22px of gutter = 314 wanted against 292 offered, so
   document.scrollWidth pins at 292 at every viewport below it. That is a
   separate fault, it predates today, and undoing it means undoing a copy
   decision, so it is recorded here and left alone.

   THE FIX KEEPS HIS NUMBER AND ADDS A CEILING THE VIEWPORT IMPOSES. min(), so
   the approved size is used wherever it fits and the viewport-derived limit
   only ever takes over below that. The --m knob above still governs the size
   he picks; it deliberately does NOT scale the second term, which is a
   physical limit rather than a preference. The crossover moves on its own if
   --m changes, because min() has no breakpoint to get out of step.

   WHERE 5.3651 COMES FROM. The widest rendered line is "like they want",
   measured at 16 sizes from 36 to 90px in both engines with the real
   stylesheet. Per px of font-size it costs:

                       Chromium   WebKit
       at 36px           5.1853   5.2066
       at 45px           5.2792   5.3014
       at 51.018px       5.3413   5.3651
       at 54px           5.3736   5.3964
       at 72px and up    5.5618   5.5859   (opsz axis clamps at 72)

   NOT a constant, because font-optical-sizing defaults to auto and Newsreader
   carries an opsz axis with HVAR, so the glyphs get NARROWER per em as the
   size drops. Using WebKit's figure at 51.018px - the largest that can apply,
   in the engine he is actually reading in - therefore overestimates the width
   at every size where this term binds, so the guard errs toward fitting.

   The 54px is (100vw - 44px of gutter - 10px of headroom). 44px is right
   because this term can only bind below vw 327.72, where rule 1 above leaves
   the padding at exactly 22px a side. Above that the flat value wins and the
   content box is never narrower than 296px, against the 283.72px that
   51.018px needs.

   No max() floor on purpose. A floor is what broke this: the dead clamp's own
   45px floor overflowed a 280px viewport by 2.6px. Type that keeps shrinking
   is readable; type that runs off the screen is not.

     vw 280  42.12px    vw 320  49.58px    vw 328+  51.018px, untouched
     vw 300  45.85px    vw 327  50.88px

   Three lines in both engines at every width from 260 to 819 after this, and
   the clearance never drops below 10.08px. At 320x568 the hero also gets
   5.1px SHORTER, which is the one viewport where it does not fit the screen,
   and the scroll cue comes back on screen in Chromium.
   ------------------------------------------------------------------------- */
@media (max-width:819.98px){
  .sentence{font-size:min(calc(46.38px * var(--m)), calc((100vw - 54px) / 5.3651))}
}


/* --- 11 Sep 2026: <picture> around the five section photographs ------------
   The photographs became <picture> + <source type="image/webp"> + <img>. That
   inserts one element between .row__art and its image, and this is the whole
   CSS consequence of it.

   .row__art img still matches -- it is a descendant selector, and <picture>
   sets no position, so the desktop rule's position:absolute still resolves
   against .row__art's position:relative. Nothing about the crop, the bleed,
   the --art-min/--art-max ceiling or the radius changes.

   WHAT DOES NEED SAYING is display. <picture> is inline by default, and an
   inline box holding a display:block <img> plus the whitespace either side of
   it generates line boxes: the classic few-pixels-under-the-image gap, which
   below 980px would have added it to the bottom of all five figures. Made a
   block, its only in-flow child is the block <img>, whitespace-only text
   between block children is discarded, and the figure measures exactly what it
   measured before. On desktop the <img> is out of flow, so the block is zero
   height and .row__art's min-height governs as it already did.

   display:contents would also work and was not used: it is one unsupported
   browser away from falling back to inline and reopening the gap, and a block
   costs nothing here.
   ------------------------------------------------------------------------- */
.row__art picture{display:block}
