/* ---------------------------------------------------------------------------
   /members/ - THE MEMBER HUB

   The landing a member arrives at when they sign in. Everything else in the
   member area is a page about one thing; this is the page that answers the
   questions and points at the rest, so it is the only member page with a
   layout of its own.

   WHERE THE REST OF IT LIVES. The bands, the cards, the panels, the callout and
   the agenda rows are all components already drawn in css/interior-b.css §9,
   and the pattern reuses them by name. Nothing here re-draws any of that. This
   file holds four things and no more:

     1. the two-column top band, which is this page's only new shape
     2. the surface rhythm, because the bands are in a different order now
     3. the route cards becoming targets you can hit rather than links you have
        to aim at
     4. the notice moving to the top and losing the margin it had when it sat
        inside a list

   WHY IT IS A FILE AND NOT A BLOCK IN interior-b.css. `member-*.css` is the
   only prefix functions.php scopes to the member area (see the enqueue comment
   there): interior-b.css ships to every visitor on the site, and a layout that
   only ever renders behind a login has no business in it. Being named correctly
   is the whole of the scoping - there is no list to update.

   Scoped on `body.page-members` per css/README.md. That is the /members/
   landing and nothing else: its six children are `page-give`, `page-calendar`
   and so on, and none of them carries these classes anyway.
   --------------------------------------------------------------------------- */


/* ===========================================================================
   1. THE STANDING NOTICE

   First thing under the greeting, because it is the only thing on the page
   that might be urgent. It reuses the `.tcf-mb-lede` band, so
   `.tcf-mb-greeting:has(+ .tcf-mb-lede)` in interior-b.css already tightens the
   greeting to 18px above it and the notice reads as attached to the name at
   the top rather than as a section of its own.

   The callout inside is §2i's aside treatment - paper-alt with a 2px brick
   edge - and it carries a 30px top margin there because it follows a document
   list. Here it is the first thing in its band, so the margin is the band's
   job and the callout gives it up.
   =========================================================================== */
body.page-members .tcf-hub-notice .tcf-mb-callout {
  margin-top: 0;
}


/* ===========================================================================
   2. THE TOP BAND: WHAT IS ON NEXT, AND THE LATEST TEACHING

   Two questions, side by side, because they are the two a member opens this
   page for and stacking them put the second below the fold on a laptop - which
   is the same as not surfacing it at all.

   THE ASIDE WIDTH IS SOLVED, NOT PICKED. Jay, 2026-08-10: "the most recent
   teaching card is a bit squished." It was, and 380px is why. The card is
   `88px artwork + 16px gap + 1fr` inside 16px of padding and a 1px border, so a
   380px column leaves the text 242px - and the card's meta line
   ("Jeff Owens · 1 August 2026 · 21 min") measures 251.11px at max-content. Nine
   pixels short, so every teaching wraps its own byline onto a second line and
   the card is 165.84px tall where it wants to be 141.34px. The old comment
   here derived 380 from the TITLE's wrapping and never checked the line below
   it.

   Two floors, both measured on the rendered page rather than reasoned about:

     400px  the meta on one line   (251.11 + 104 artwork/gap + 32 padding + 2 border = 389)
     417px  the aside HEADING on one line at the section step's 40px maximum
            ("The most recent teaching" is 416.77px at 40px Newsreader 400)

   The clamp takes the second floor where there is room for it and the first
   where there is not, and stops at 440 because past that the main column starts
   losing the agenda row's date block, title and right-hand time from one line
   (measured: the row title wraps below a ~560px main column).

   The 1fr/track split is deliberately NOT a fraction pair. The aside is a
   component with an intrinsic size; the main column is a list that takes what
   is left. A fraction would let a wide screen stretch the card and a narrow one
   crush it, which is the failure this replaces.

   `align-items: start` so a short teaching card does not stretch to the height
   of three agenda rows. Ruled again 2026-08-10 and kept - see §3 for the
   argument and for what it does NOT excuse.
   =========================================================================== */
body.page-members .tcf-hub-split {
  /* 440px, pinned. Local to this layout; nothing else should adopt it, because
     nothing else has this card in a column beside a list.

     It was `clamp(25rem, 34.5%, 27.5rem)` - a 400px floor under a 440px cap -
     while section headings were pinned to 36px. Removing that pin (see
     style.css, 2026-08-10) restored the fluid 28->40 step and took the aside
     heading to 40px, where "The most recent teaching" needs 417px to stay on one
     line. The percentage does not deliver that on its own: with the collapse now
     at 1279 the narrowest two-column case is a ~1200px content width, where
     34.5% is 414px - three pixels short, and the heading wrapped.

     Kept in clamp form rather than written as a bare `440px` so the shape of the
     decision survives: if the heading ever gets shorter, the floor is the number
     to lower, and the cap is still the reason it does not grow (past 440 the
     main column drops under ~560px and the agenda row's date, title and time
     stop sharing a line). */
  --tcf-hub-aside: clamp(27.5rem, 34.5%, 27.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--tcf-hub-aside);
  gap: var(--tcf-space-8);
  align-items: start;
}
/* min-width: 0 on both, or a long teaching title or event name refuses to wrap
   and pushes the grid wider than its container. The rest of the site's grids
   say `minmax(0, 1fr)` for the same reason; a fixed track needs it stated. */
body.page-members .tcf-hub-split__main,
body.page-members .tcf-hub-split__aside {
  min-width: 0;
}

/* TWO controls beside the heading, not one.
   `.tcf-mb-sec__head > p` (interior-b.css) holds one and expects one. The
   second is the jump to the subscription panel at the foot of the page, and it
   is here rather than only down there because the whole value of subscribing is
   that it is done once and then never thought about again - a member who never
   scrolls to the bottom never finds out it exists. Wrapping, right-aligned, so
   the pair drops to two lines rather than crowding the heading when the column
   narrows. */
body.page-members .tcf-hub-head__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  /* Was a 6px row gap, which is on no scale. `--tcf-space-2` is 8px and is the
     step the 4px grid actually offers here. */
  gap: var(--tcf-space-2) var(--tcf-space-5);
}
body.page-members .tcf-hub-head__links > a {
  /* The same 4px the member area gives every standalone control, so a 17px
     line box clears WCAG 2.5.8's 24px. */
  display: inline-block;
  padding-block: 4px;
}

/* THE ASIDE HEADING IS NOW THE SAME COMPONENT AS THE ONE BESIDE IT, and there
   is no CSS here at all any more. The pattern wraps it in `.tcf-mb-sec__head`
   with `is-style-section`, exactly like "Coming up" - one head with a pair of
   controls in it, one without.

   What was here: a hand-drawn heading at `--tcf-text-card` with a 22px bottom
   margin, justified on the grounds that "at the section step it would be 40px
   in a 380px column, which is three lines." Measured, it is two lines at 40px
   and ONE line at 36px, which is what the sibling actually renders at while
   `.is-style-section` is pinned (see the note at the foot of this file). So the
   cost the step-down was avoiding did not exist, and what it cost instead was
   real: 30px in a 380px column is byte-identical to `.tcf-mb-panel__title` and
   `.tcf-subscribe__heading` in the closing band, so an `h2` and two `h3`s were
   the same size on one page and the document rank was not legible in the type.

   Two things fall out of sharing the component rather than copying its values:

     - the columns line up. Same font-size, same 1.15 leading, same 30px head
       margin, so the first agenda row and the top of the teaching card start at
       the same y (measured -1.00px, which is the agenda list's own 1px top
       rule). It was 13.80px.
     - they cannot drift apart later. There is no second copy of the numbers to
       forget to update.

   The block's own eyebrow is still suppressed in the pattern (`heading: ""`) so
   this is the only label on the card. An eyebrow carries no document structure
   (§1.2), and a column of the page needs a heading a screen reader can find. */

/* The band is paper-alt (interior-b.css §6), so the teaching card - which is
   drawn on `--tcf-page` for the archive - keeps its own paper background and
   reads as a card sitting on the band rather than dissolving into it. That is
   already what `.tcf-teaching-card` sets; stated here only so the next person
   to change the band's surface knows the card is relying on it.

   The card's hover is a border-colour change and nothing else (§1.4), which is
   inherited untouched. */
body.page-members .tcf-hub-split__aside .tcf-latest-teaching {
  margin: 0;
}

/* "All teachings", under the card. It is a route off this page, so it gets the
   same 4px of vertical padding every other standalone control in the member
   area has - a 15px line box is 17px tall, and 4px either side takes it past
   WCAG 2.5.8's 24px. */
body.page-members .tcf-hub-split__aside .tcf-latest-teaching__more > a {
  display: inline-block;
  padding-block: 4px;
}


/* ===========================================================================
   3. THE SURFACE RHYTHM, AND THE GAP JAY SAW

   Jay, 2026-08-10: "there is a large gap between the coming up and everything
   cards."

   WHAT IT WAS. This section used to describe a six-band page:

     greeting        paper      (the template's)
     notice          paper      - continuous with the greeting, on purpose
     what is on      paper-alt
     documents       paper      <- GONE: the empty-documents band left the pattern
     routes          paper-alt
     closing panels  paper

   The documents band is no longer in the pattern, and the standing notice
   renders nothing when its setting is empty (`tcf/member-notice`), so what
   actually ships is four bands - and the paper band that used to sit BETWEEN
   the two paper-alt ones has gone with it:

     greeting        paper
     what is on      paper-alt
     routes          paper-alt  <- the same surface, butting, with no rule
     closing panels  paper

   That join is the gap. Two bands of identical `paper-alt` meet with neither a
   colour change nor a hairline between them - which §1.3 does not permit - and
   each pays a full section break for the privilege: 72px of bottom padding
   against 72px of top padding, so 144px of unbroken paper-alt at 1440 (80px at
   768 and 320) with nothing in it to say why. Measured before this change: the
   last agenda row ended at y=647.73 and "Everything in the member area" opened
   at y=791.73.

   THE RULING. They are one surface, so they pay one section break. A band pays
   for its own top padding when it CHANGES surface (§1.3); this one does not, so
   it does not pay. The join becomes the split band's own 72px bottom padding,
   which is exactly `--tcf-space-8`, the desktop section rhythm - the same
   distance any two sections of one surface are given anywhere else on the site.
   What separates the two sections is then the 36px section heading, which is
   how every other stacked section on this site is separated.

   Deliberately NOT the alternative fixes:

     - repainting the routes band `paper` to restore alternation. It moves the
       identical fault one join down (routes paper against the closing band's
       paper) and costs the route cards the paper-on-paper-alt contrast that
       makes them read as a set of destinations.
     - a `--tcf-rule` hairline at the join. It measures 1.13:1 on paper-alt.
       A separator nobody can see is not a separator, it is a line item.

   The page is now three surfaces and two changes: paper, paper-alt, paper.
   =========================================================================== */
body.page-members .tcf-hub-close {
  padding-top: var(--tcf-space-8);
}

body.page-members .tcf-hub-routes {
  padding-block: var(--tcf-space-8);
  background-color: var(--tcf-surface);
}

/* The join. Stated as "when it follows the agenda band" rather than unqualified,
   because the moment anything paper is put back between them - the documents
   band, most likely, which the pattern promises to restore above the split as
   soon as it has a document in it - the routes band is a change of surface
   again and gets its top padding back on its own. */
body.page-members .tcf-hub-top + .tcf-hub-routes {
  padding-top: 0;
}


/* ===========================================================================
   4. THE ROUTES

   Seven cards to seven pages. They were seven cards before; what they were not
   was aimable. Only the title was a link, so a member had to hit a line of
   text rather than the card they could see, and there was nothing on the card
   that said it went anywhere.

   Three changes, no new component and no JavaScript:

     - the title's link covers the whole card, so the target is the 150-odd
       pixels of card rather than the 26px of heading. This is the standard
       "stretched link": an empty absolutely-positioned pseudo-element on the
       anchor, filling the card. The anchor keeps its own text, so the
       accessible name is still the page's name and nothing is announced twice.

     - an arrow in the corner, in brick, saying the card is a way out. It is
       decoration, so it is pseudo-content with an empty alt string rather than
       markup; a browser too old for the alt syntax drops the whole declaration
       and shows no arrow, which is the right thing to lose.

     - the card sits on paper against the band's paper-alt, so the set reads as
       a block of destinations.

   The border already goes brick on hover and on focus (interior-b.css), and
   with the stretched link that now happens from anywhere on the card.
   =========================================================================== */
body.page-members .tcf-hub-routes .tcf-mb-nav__card {
  position: relative;
  /* Room for the arrow, so a title can never run under it. The arrow sits 26px
     from the right edge and is about 11px wide at the `ui` step, so 48px is the
     first value that clears it with a gap rather than a near miss. Measured at
     56 first, which at 320px was a fifth of the card's width spent on nothing. */
  padding-right: 48px;
  background-color: var(--tcf-page);
}

body.page-members .tcf-hub-routes .tcf-mb-nav__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

body.page-members .tcf-hub-routes .tcf-mb-nav__card::after {
  /* U+2192 RIGHTWARDS ARROW, with an empty alt string so a screen reader is
     not told "right arrow" after every card title. */
  content: "\2192" / "";
  position: absolute;
  top: 30px;
  right: 26px;
  /* Under the stretched link, not over it: a pseudo-element on the card paints
     after one on a descendant, so without this the arrow would be the one part
     of the card that was not clickable. */
  pointer-events: none;
  font-family: var(--tcf-font-body);
  font-size: var(--tcf-text-ui);
  font-weight: 600;
  line-height: 1;
  color: var(--tcf-accent);
  transition: transform var(--tcf-motion-hover) var(--tcf-ease);
}
/* Motion is a token, so prefers-reduced-motion has already taken it to 0ms by
   the time this runs (style.css). Nothing to repeat here. */
body.page-members .tcf-hub-routes .tcf-mb-nav__card:has(a:hover)::after,
body.page-members .tcf-hub-routes .tcf-mb-nav__card:has(a:focus-visible)::after {
  transform: translateX(3px);
}


/* ===========================================================================
   5. THE CLOSING BAND

   The calendar subscription, which is the one thing on this page worth doing
   once and never again, and the address to write to when something is not
   here.

   The subscribe block gives up its own frame inside a member panel already
   (interior-b.css) - the panel supplies the border, the title and the sentence
   that says what it is.

   THE TWO PANELS ARE NOT PEERS, SO THEY DO NOT GET EQUAL COLUMNS. This is the
   other half of the `align-items: start` question §2 and §3 answer, and it was
   decided by building the alternatives and measuring them rather than by
   reasoning about them.

   `.tcf-mb-panels` is two even columns with `align-items: start`, and on this
   page that put 663.58px of subscribe panel beside 186.98px of "Something
   missing?" at 1440 - 476.59px of empty paper under the short one, and 828.01px
   at 768. `HUB_POLISH_DESIGN_SYSTEM.md` F-7 recorded that and half-ruled it.

   Four treatments, all measured at 1440 on the live page:

     treatment        band height   panels                 ragged bottom
     two even         807.58        626x663.6 / 626x187.0   476.59
     TWO ASYMMETRIC   786.58        761x642.6 / 491x187.0   455.59   <- shipped
     stacked, capped 1001.56        707x642.6 / 707x187.0   214.98
     stacked, wide    974.44       1280x615.5 /1280x187.0   214.98

   `align-items: start` STAYS, on both grids. Stretching does not remove the
   emptiness, it puts a border round it, and an empty bordered box reads as a
   card that failed to load rather than as a panel that is short.

   STACKING WAS BUILT, SHOT AND REJECTED. It halves the ragged bottom on paper
   and is worse to look at: it converts 476.59px of emptiness in one corner into
   572.73px of emptiness running the FULL height of the band down its right
   side, and it makes the closing band the only left-weighted band on a page
   whose other three span the full width. It also costs 214.98px of page height
   on a page two reviews have already called too long.

   So: 1.55fr / 1fr. The ratio is not taste, it is the widest atomic thing in
   the band - the personal calendar address, 628.45px of monospace that must not
   wrap, needing 697px of panel once the 26px padding either side is paid. An
   even split gives the panel 626px and breaks the address over two lines; 1.55
   gives it 761px at 1440 and 712px at 1280 and does not. Below about 1216 it
   wraps whatever we do, which is not made worse here.

   WHAT IS LEFT IS NOT A LAYOUT PROBLEM. 455px of ragged bottom is what it costs
   to put a panel that says the same thing twice beside a panel that says one
   thing once: `.tcf-mb-panel > p` (331 characters) and
   `.tcf-subscribe__lede` (137) make the identical promise - subscribe once, it
   keeps itself right - one after the other, both above the button. Deleting
   either is ~72px and belongs to whoever owns the copy, not to this file.

   SCOPED TO THE HUB. `/members/calendar/` has the same pairing for the same
   reason and the durable fix belongs to the component - see the note at the
   foot of this file.
   =========================================================================== */
body.page-members .tcf-hub-close .tcf-mb-panels {
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
}


/* ===========================================================================
   6. NARROWER THAN 1120, AND NARROWER THAN 768
   =========================================================================== */

/* THE COLLAPSE MOVES UP FROM 1023 TO 1119, which closes the window both earlier
   reviews found and neither could close from inside it.

   Below 1120 the main column is under 590px, and at that width the section head
   cannot keep "Coming up" and its two controls on one line: the links wrap, the
   head grows 33px, the agenda rows drop with it and the two columns stop lining
   up - while the aside is simultaneously at its 400px floor and taking a fifth
   of the row. 1024 was the worst of it: `HUB_POLISH_DESIGN_SYSTEM.md` F-1
   measured the links running 95.75px past their own column and being painted
   over by the teaching card, and the split collapsed at 1023, one pixel too
   late to save it. That overflow is gone (the flex fix at the foot of this
   file), but the crush that produced it is not, and iPad Pro landscape sits
   exactly on the old boundary.

   What is given up: at 1024x768 the teaching card is no longer beside the dates
   and drops just below the fold. That is a real loss and it is the smaller one.
   The split exists because stacking put the teaching below the fold ON A
   LAPTOP, and a laptop is 1280 or 1366 - both still two-column, both still
   aligned. */
@media (max-width: 1279px) {
  body.page-members .tcf-hub-split {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--tcf-space-7);
  }
}

@media (max-width: 767px) {
  body.page-members .tcf-hub-close {
    padding-top: var(--tcf-space-6);
  }
  body.page-members .tcf-hub-routes {
    padding-block: var(--tcf-space-6);
  }
  body.page-members .tcf-hub-split {
    gap: var(--tcf-space-6);
  }
  /* The two head links are the only right-aligned thing on a phone. At <=767
     `.tcf-mb-sec__head` becomes a column with `align-items: flex-start`
     (interior-b.css), so the heading and every date go flush left and these two
     stayed flush right - two ragged-left lines in an otherwise left-aligned
     column. `justify-content` does not inherit alignment, so it has to be said
     again. */
  body.page-members .tcf-hub-head__links {
    justify-content: flex-start;
  }
  /* §5's ratio has to give the single column back, and it has to be said here
     rather than left to `interior-b.css`. `.tcf-mb-panels` collapses at <=767
     with a (0,1,0) selector; §5's is (0,3,0), so it was still winning inside
     the media query and the two panels came out 153px and 99px wide on a phone.
     Measured before this line: the document was 5282px at 320 against 4312 with
     the panels stacked. Every override of a responsive component owes it its
     breakpoint back. */
  body.page-members .tcf-hub-close .tcf-mb-panels {
    grid-template-columns: minmax(0, 1fr);
  }
  /* On a 280px card the arrow is pulled in and the reserved column with it -
     44px rather than 48, and 20px rather than 26 from the edge. A title at the
     card step wraps to two lines here whatever we do; the point is that it
     wraps on its own measure rather than around an empty gutter. */
  body.page-members .tcf-hub-routes .tcf-mb-nav__card {
    padding-right: 44px;
  }
  body.page-members .tcf-hub-routes .tcf-mb-nav__card::after {
    top: 28px;
    right: 20px;
  }
}

/* ---------------------------------------------------------------------------
   ABOVE THE FOLD
   ---------------------------------------------------------------------------
   Jay, 2026-08-09: "the top of the member hub is wasting a lot of vertical
   screen realestate, we need to bring content up above the fold more."

   Measured at 1366x768, the commonest laptop, before this block: the first event
   row began at 482px - 63% of the viewport spent before a single piece of
   content - and only two of the three dates fitted on screen. On a 390x844 phone
   it was 512px and one date.

   Where it went: a 72px band top padding, an eyebrow with 16px beneath it, a
   52px greeting with 25.6px beneath that, 30px of band bottom padding, and then
   the next band opening with another 72px of its own.

   SCOPED TO `.page-members`, and that matters. Six of the seven member pages put
   their page TITLE in this slot - "Give", "Calendar", "My Profile" - and
   `interior-b.css` sets it at the `page-title` step deliberately, because at the
   smaller canvas figure an h2 below it rendered larger than the h1 above, which
   misstates the page to anyone skimming. The hub is the one page where this slot
   holds a greeting rather than a title, so the hub is the only page that may
   compress it. Nothing here may be lifted out of this selector.

   The greeting itself is kept. It is one line, it carries the sign-out control,
   and a member arriving at a page that opens cold with a list of dates has lost
   something for the sake of 60px. */
.page-members .tcf-mb-greeting {
  padding-block: var(--tcf-space-5) var(--tcf-space-4);
}
.page-members .tcf-mb-greeting__eyebrow { margin-bottom: var(--tcf-space-2); }
.page-members .tcf-mb-greeting h1 { margin-bottom: var(--tcf-space-2); }

/* The band that follows opens tighter too. Its 72px is right between two
   unrelated bands; directly under the greeting it reads as a gap rather than as
   a join, and the greeting's own bottom padding is already doing that work. */
.page-members .tcf-mb-greeting + * { padding-top: var(--tcf-space-5); }

@media (max-width: 767px) {
  .page-members .tcf-mb-greeting { padding-block: var(--tcf-space-4) var(--tcf-space-3); }
  .page-members .tcf-mb-greeting + * { padding-top: var(--tcf-space-4); }
}

/* ---------------------------------------------------------------------------
   TWO FIXES FROM THE DESIGN-SYSTEM REVIEW (docs/reviews/HUB_POLISH_DESIGN_SYSTEM.md)
   ------------------------------------------------------------------------ */

/* The head links were frozen at 456.72px by `flex: 0 0 auto`, so between 1024px
   and 1119px they ran 95.75px past their own column and 23.75px into the
   teaching card - whose opaque fill painted over the text and took the hit test.
   The split collapses at 1023px, one pixel too late to save it. Letting the
   links shrink, and the heading take the slack, closes the window.

   2026-08-10: the heading is now `1 0 auto` rather than `1 1 auto`. It still
   takes the slack, but it no longer gives any: a section's name is what the
   section IS, and a squeeze should wrap the two supplementary links - which
   already carry `flex-wrap: wrap` for exactly that - rather than break "Coming
   up" over two lines beside 800px of unused row, which is what happened at
   1024. Their min-content is one link at ~197px against a main column that is
   never narrower than 584px now, so nothing can overflow. */
body.page-members .tcf-hub-split__main .tcf-mb-sec__head > p.tcf-hub-head__links {
  flex: 0 1 auto;
  min-width: 0;
}
body.page-members .tcf-hub-split__main .tcf-mb-sec__head > h2 { flex: 1 0 auto; }

/* The route card's border was `--tcf-rule`, a decorative hairline - measured
   1.238:1 on the card fill and 1.134:1 against the band, and still 1.717:1 under
   `prefers-contrast: more`. That was defensible while it was decoration. It is
   not, now that the whole 408x168 card is the click target and the border is the
   only thing describing where that target is. `--tcf-button-border` measures
   3.454:1 - the same colour, and the same argument, the system already used to
   overrule the handoff on the secondary button. */
body.page-members .tcf-hub-routes .tcf-mb-nav__card { border-color: var(--tcf-button-border); }


/* ---------------------------------------------------------------------------
   THREE THINGS THIS FILE CANNOT REACH
   ---------------------------------------------------------------------------
   Recorded here rather than in a review nobody reopens, because two of them are
   the reason a rule above is written the way it is.

   1. `.is-style-section` IS PINNED TO 36px AND SHOULD NOT BE.
      `style.css` declares it twice: once as `var(--tcf-text-2xl)`, which is
      `--tcf-text-section`, `clamp(28px, 1rem + 3vw, 40px)` - and once, ~3000
      lines later at equal specificity, as a flat `36px`. The later one wins, so
      the documented fluid section step never renders at any width on any page.

      The pin's stated reason is that handoff §1.2 gives `section` as "36-40"
      and both drawings show 36. But the handoff's OWN machine-readable source,
      `docs/handoff/theme.json`, gives `section` as `{min: 28px, max: 40px}` -
      and DESIGN_SYSTEM.md says in as many words that the fluid min/max pairs
      come from that file rather than from a reading of the §1.2 table. The
      drawings are desktop artefacts; theme.json is the statement.

      The measured cost is not academic. At 320 the greeting `h1`
      (`--tcf-text-page`) computes to **34px** and every `h2` on the page
      computes to **36px**: the section headings render LARGER than the page
      title on a phone, which is precisely the failure DESIGN_SYSTEM.md §1.2
      names ("an h2 rendered larger than the h1 above it ... misstates the
      structure of the page to anyone skimming"). With the token it would be
      28px under a 34px h1.

      THE FIX IS ONE LINE IN A FILE THIS ONE MAY NOT EDIT: drop
      `.is-style-section` from the `font-size: 36px` rule near the foot of
      `style.css`, leaving `.tcf-faq__intro > h2` and `.tcf-visit__runs h2`
      pinned if their own drawings want them pinned.

      WHAT IT DOES TO THIS PAGE, stated in advance so it is not a surprise: both
      split headings go to 40px at every width above ~800. "The most recent
      teaching" measures 416.77px at 40px, so the aside must be at least 417px
      for it to stay on one line - which the clamp in §2 gives from about 1290px
      up. Below that it wraps to two lines and the columns offset by ~46px. If
      the pin goes, the aside's floor in §2 should go up from `25rem` to
      `27.5rem` and the collapse in §6 from 1119 to 1279 in the same commit.

   2. `.tcf-mb-panels` PAIRS A SUBSCRIBE PANEL WITH A SENTENCE, ON TWO PAGES.
      §5 re-proportions it here. `/members/calendar/` has the same pairing - it
      is the only other page that puts `.tcf-subscribe` inside a
      `.tcf-mb-panel` - and the durable fix belongs to the component in
      `interior-b.css`, something to the effect of

          .tcf-mb-panels:has(> .tcf-mb-panel .tcf-subscribe) {
            grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
          }

      so the grid re-proportions itself wherever the tall guest turns up, rather
      than each page discovering it separately. `/members/events/` and
      `/members/newsletter/` pair prose with prose - their ragged bottoms measure
      19.20px and 68.80px - and must not be swept up in it.

   3. THE MEMBER AREA'S PROSE MEASURE IS THE LITERAL `720px`, SIX TIMES.
      `interior-b.css` repeats it for the notice, the empty document state, the
      callout, the prose inner and two list variants. It wants a name - a
      `--tcf-measure-member` token equal to 45rem, beside `--tcf-measure` in
      `style.css`'s `:root` - and those six rules are its adopters. (Written
      without a colon on purpose: check_tokens.py reads a name followed by a
      colon out of a comment as a declaration, and a token that exists only in
      prose is exactly the silent failure that checker was built to catch.)

      This came up because §5's first attempt capped the stacked panels at
      `--tcf-measure` (68ch), which resolved to 707.27px on the panel - within
      13px of the 720px literal the member area already uses everywhere else,
      arrived at from a completely different direction. That is two names for
      one decision, and it is worth reconciling deliberately rather than leaving
      them 13px apart by accident. The cap is gone with the stacking, so nothing
      on this page depends on the answer today. */
