/*
  Why Library of Trade — six benefit panels in a 3 × 2 modular grid, second on the page.

  ── What this has to look like ───────────────────────────────────────────────

  One surface divided six ways. Not six cards on a page: six graphite panels with 6px of
  the section's own light ground between them, which is a different object and reads as a
  system rather than as a set. The seams are the whole device — they are what says these
  six belong to each other and were laid out rather than collected.

  Inside a panel: the title top-left, the diagram top-right, the sentence at the bottom,
  and the middle empty on purpose. A reader crossing the section reads six titles across
  two lines of the page; the sentences are there for the one or two they stop on. Which
  is why the panel is 270px tall with 18 words in it — the emptiness is the thing that
  makes the titles scannable, and a panel packed to its edges is a card again.

  ── It has been three sections ──────────────────────────────────────────────

  A 3 × 2 grid of tall cards first, each with a bold claim over two lines of explanation.
  Then six narrow tiles in one row, on the argument that a strip under a hero is crossed
  rather than read — the claim per card went from two sentences to one, the mark from 30px
  to 22, and the block from over a screen to about half of one.

  The row was right about the reading and wrong about the measure: six columns of 150px,
  each holding a four-line sentence, is a summary nobody can scan, because the line is too
  short for the eye to take one at a time. So it is 3 × 2 again, with the sentence kept at
  one line of copy and the panel given the room the row could not.

  ── The surface, inverted ───────────────────────────────────────────────────

  Graphite panels on near-white paper. It was grey panels on near-white paper — the same
  two `--paper-*` values as the category rail above, swapped — and the swap is what the
  two sections' rhythm was built on: photographs standing on a grey ground, then the
  argument set into a light one.

  The panels are now #212426, which is a far bigger step than the fourteen levels the
  swap traded in, and the section is the better for it: six dark blocks on light paper is
  a composition a reader takes in before reading a word, where six grey blocks on
  near-white paper was a texture. What the section gives up is the seam as a hairline.
  Panel-against-ground goes from 1.08:1 to 14.9:1, so the 6px is now a bright line
  between two dark blocks rather than a change of tone — the grid is unchanged and the
  contrast does the dividing the step used to.

  Which is the reason this stylesheet is still short on colour. The panels read
  `--bg-raised`, the titles `--fg`, the sentences `--fg-sub`, and both the section and the
  panel rebind those from the `--paper-*` family — so nothing below states a colour.

  ── Monochrome, by instruction ──────────────────────────────────────────────

  There is no accent in this section at all: no blue, green, yellow, purple, red or
  orange, in the panels or anywhere near them. The palette is five values — the near-white
  ground, the black heading on it, the graphite panel, the off-white title, the muted copy
  — plus six white marks that are raster images nothing here can reach.

  Six coloured corner markers used to live at the bottom of this file, one per panel, on
  the argument that colour outside the padding is available to a reader who looks and
  invisible to one who scans. That argument holds on a light panel and inverts on a dark
  one: an accent on graphite is the highest-contrast thing in the section, and it would be
  read before the titles the whole layout exists to make scannable. They are deleted —
  from here, from build.mjs, and from tokens.css.

  ── Desktop-first ────────────────────────────────────────────────────────────

  Like every other stylesheet here: the wide layout is the base and the narrow ones are
  overrides at the bottom. Three across, then two, then one.
*/

/* ═══ THE SECTION ════════════════════════════════════════════════════════ */

/*
  The paper's second page, and the lighter of its two tones. No rule at either edge. The
  family has two surfaces 14 levels apart, this section is the light one between two grey
  ones, and the same step draws both boundaries on its own — see the note in tokens.css.
  Process below used to keep a hairline on the argument that its edge was the smaller of
  the two; it is the identical step in the other direction, so it went.

  ── One viewport, and the padding is where it came from ─────────────────────

  The whole section — label, heading, both rows, bottom edge — has to be visible at
  1440 × 900 without scrolling inside it. That is a hard budget, and everything in this
  stylesheet is set from it downwards: 63px of padding above, 55 below, 14 to the
  heading, 37 to the grid, and two 216px rows. It lands at about 680px, which clears the
  826px a 900px window has under the top bar with room to spare.

  It used to be 116px of padding at each end and 288px rows, which read as premium and
  measured as 860px — a section a reader had to scroll through to finish. Air is not what
  makes this section good; the alignment is. So the padding is the low end of the page's
  range rather than the high end, and the room went back to the grid.

  ── The surface ─────────────────────────────────────────────────────────────

  `--bg-raised` is the panel, and on this ground the panel is much darker than what it
  stands on. That is the inversion, and it is the one place in the page where raised means
  down: near-white paper with graphite blocks set into it.

  The ground stays `--paper-white` #FAFAF8 and is not touched. The brief asked for #F5F5F2
  and #FAFAF8 is five levels off it — inside the brief's own "or keep your existing
  off-white if it is very close" — and it is the value the page's black → grey → near-white
  alternation is built out of, shared with the cards on the category rail above. Moving it
  to satisfy a number nobody can see would move two sections to fix neither.

  `--bg-raised` is where the section changed. It was `--paper-grey`, then `--paper-panel`
  at #F1F1EF, both a handful of levels below the canvas; `--paper-panel` is now graphite,
  and it is still a re-point of that one token rather than a hex stated here, because the
  token's only consumer is this section and the rail above still wants the grey one. What
  the step gains and what the seam loses are measured in tokens.css.

  `--fg-sub` stays the light family's grey. It is read on this ground — by the eyebrow —
  and not on the panel; the panel rebinds both `--fg` and `--fg-sub` for itself below,
  because nothing in the light family is legible on #212426.
*/
.adv {
  padding-block: clamp(48px, 4.4vw, 64px) clamp(40px, 3.8vw, 56px);
  --bg: var(--paper-white);
  --bg-raised: var(--paper-panel);
  --line: var(--paper-line);
  --line-strong: var(--paper-line-strong);
  --fg-sub: var(--paper-sub);
}

/*
  Full width, like the process strip below it and the configurator below that. The grid
  ran at the page's 1240px measure and left 460px of empty paper down the right at 1728,
  which on a section whose whole argument is that six panels were laid out rather than
  collected is the one flaw a reader notices: the layout stopped before the page did.

  Now it runs gutter to gutter — `--gutter` is clamp(22px, 5vw, 64px), so the outer space
  is 64px each side at any desktop width and equal by construction rather than by
  arithmetic.

  Capped at 1800 rather than uncapped. Three panels sharing 2400px of a wide monitor are
  810px each with eighteen words in them, and a measure that wide stops being a panel and
  becomes a page. The process strip below takes the same cap for the same reason and at
  the same number, so the two sections' outer edges agree at every width. The
  configurator further down stays uncapped: a map is a drawing, not a measure.
*/
.adv > .shell {
  max-width: 1800px;
}

/* ═══ THE HEAD ═══════════════════════════════════════════════════════════ */

/*
  A label and a heading, stacked left, with nothing under them.

  Two parts, in that order, because the label is the section's name and the heading is
  its argument — and the section's name is not worth the largest type on the site. It was
  the other way round: `Why Library of Trade` set at `--t-h2` with a line of support
  beneath it. That spent the head introducing the head. Now the name is a 12px mono label
  and the heading is `Lower costs. Better suppliers. Less work.`, which is the only line
  in the section every reader takes in.

  And no lead. The rule that used to be here is gone rather than emptied: the three
  claims in the heading are the three claims the paragraph was making, and the six panels
  below say the rest. Nothing in the section wants a `.lead` any more, so nothing in here
  styles one.

  37px to the grid at 1440. It was 60, on the argument that a two-line head needs a gap
  sized like a three-part one; that argument was wrong in the direction that cost the
  section its fold. A tight band between a heading and the thing it introduces reads as
  one composition, and a wide one reads as two — which is the opposite of what 60px was
  bought for.
*/
.adv-head {
  margin-bottom: clamp(28px, 2.6vw, 38px);
}

/*
  The label sits close to the heading it belongs to: 16px at 1440, inside the 14–18 the
  brief asks for, and closer than the mono line's own leading would suggest. A gap wider
  than this and the two stop being one object.

  No accent on it. An orange label was offered and the hero already spends the page's one
  orange on a button two screens up; a second orange word, in the smallest type on the
  section, is decoration rather than signal. `--fg-sub` is #686864 on this near-white
  paper — 5.4:1, and a clear step under the heading without being faint.
*/
.adv-head .eyebrow {
  margin-bottom: clamp(12px, 1vw, 14px);
}

/*
  `--t-h2` is clamp(31px, 4.3vw, 54px) — the page's own display size for a section, which
  lands at 54 from about 1260px up. The brief asks for 44–52; 54 is the page's number and
  a section that wants the largest heading on the site should ask for it by name rather
  than restate it two pixels lower. Nothing else on the page sets a size of its own here.

  Wide enough for one line, and the break is set in the words rather than here.

  1010px at the display size, which is a measured number: `Global sourcing power for every
  business` sets 990px wide at 54px, so this is that plus a little. 700px was the first
  number and it held the heading to two lines at every desktop width, which is a ragged
  pair on a section built out of exact alignment. The brief asked for 900 — 900 cannot hold
  this line, and one line was the stated priority, so the measure went to the type rather
  than the type to the measure.

  One line from 768px up. Below that the clamp is still bringing the size down but the
  column has run out faster, and it breaks after `power`: the capability on the first line,
  who gets it on the second, which is the same division the sentence makes. That is the
  browser's own greedy wrap agreeing with the sense for once, so there is no `text-wrap`
  here at all — `balance` would even the two lines by pulling `for` up and leave `every
  business` hanging, which is worse in both directions.

  The one thing that is pinned: `every business` is glued with a non-breaking space in
  content/advantage.js. It is the half of the heading that carries the argument and the
  half a greedy wrap would break first, and `business` alone on a third line at 31px is
  the shape this section exists to avoid.

  1.05 of leading, against the scale's own. At one line it changes nothing; at two on a
  phone it is what keeps the heading a block rather than a pair of lines.
*/
.adv-head h2 {
  max-width: 1010px;
  margin-bottom: 0;
  line-height: 1.05;
}

/* ═══ THE GRID ═══════════════════════════════════════════════════════════ */

/*
  Three across, two down, and 6px between.

  The gap is the design. It is not spacing between cards — it is the section's ground
  showing through a divided surface, and at 6px against graphite it reads as a seam: a
  line with a width, drawn by two edges rather than by a border. Wider and the panels
  come apart into six objects; narrower and the seam closes and the grid becomes one
  dark block with type in it. Either failure is worse than the thing being avoided.

  The dark version raised the stakes on that number rather than changing it. Off-white
  against #F1F1EF was a 1.08:1 seam — a hint of a line, which is why 6px was already the
  floor. Against #212426 it is 14.9:1, so the same 6px now draws at full strength, and
  10px — the width the brief suggests — was rendered side by side with it to be sure. It
  reads as six cards with space around them; 6px reads as one surface divided, which is
  the section this is. 10px also costs two panels a line of copy at 1440. Kept at 6, on
  the brief's own allowance to keep an existing gap that is visually equivalent.

  Which rules out everything a benefits grid usually has. No shadow, no border, no radius
  to speak of, no lift on hover, no number in the corner, no link that goes nowhere. The
  panels are held together by the seam and separated by it, and that has to be the only
  mechanism or it stops being legible as one.

  `1fr` columns and not `auto-fit`, because the count is the design: six benefits laid out
  four-and-two, or five-and-one, is a grid that ran out. `minmax(0, 1fr)` rather than a
  bare `1fr`: a bare one is `minmax(auto, 1fr)`, which lets a column refuse to go below
  its content's intrinsic width — one long word in one sentence, and the three columns are
  no longer identical. Zero as the floor is what guarantees they are.
*/
/*
  `grid-auto-rows: 1fr` is what makes all six the same height rather than all three in a
  row the same height. Without it each row sizes to its own tallest panel, and the two
  rows only match when the longest sentence in each happens to take the same number of
  lines: at 1728 the top row was 227 and the bottom 222, at 1180 it was 228 against 205,
  and on a phone panel two sat 23px shorter than the other five. A 5px step between two
  rows of a six-panel grid is the kind of misalignment a reader feels without locating,
  and a 23px one is visible outright.

  `1fr` and not a fixed height: in a grid with no height of its own, fr rows all take the
  size of the largest, so the row height is still set by the copy and still moves with the
  viewport — it is just one number for both rows instead of two. Every panel then ends its
  sentence on the same baseline, which is the thing the section is asked for and the thing
  `min-height` alone cannot give.
*/
.adv-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: 6px;
  list-style: none;
}

/*
  ── The panel ───────────────────────────────────────────────────────────────

  A flat graphite surface with three things on it and a hole in the middle.

  6px of radius, and the number moved with the colour. It was 2, on the argument that a
  90° corner on a panel this size reads as a screenshot of a table and 2px is the least
  softening that stops it. That was calibrated against a panel one level off its own
  ground, where the corner was barely a shape at all; on graphite against near-white the
  corner is fully drawn, and 2px of it reads as a hard clip. 6 is still well short of a
  card — the rail above is at 8 for a photograph, which is a printed object and wants a
  printed object's corner — but it is enough that the panel looks cut rather than cropped.

  No border. The brief allows `1px solid rgba(255,255,255,0.03)` at most and even that is
  unnecessary: the panel is 14.9:1 against what it stands on, so an edge drawn at 3% white
  would be a line nobody can see doing a job the contrast already did. There is no shadow
  and no glow either.

  ── The height ──────────────────────────────────────────────────────────────

  252px at 1440, 256 at 1728, and the panel is still wide before it is tall: 433px across
  at 1440 now that the grid runs the full page. That proportion is the point — a benefit is
  a title and a sentence, and a panel three fifths as tall as it is wide is a block in a
  band rather than a card in a set.

  It has been 288, then 216, and is now 252, and the last move is the padding's fault
  rather than a change of mind. At 39px of padding a panel holding a four-line sentence is
  223px tall from its contents alone — so at the old 216 `min-height` did nothing, the
  sentence sat directly under the title, and the empty middle this layout is built on
  disappeared. 252 puts about 30px of air back between the two, which is what `margin-top:
  auto` on the copy needs in order to mean anything.

  `min-height` and not `height`, because the row is a grid row: all three panels in a row
  are the height of the tallest, and if a sentence ever takes a fifth line at some width
  the row grows rather than the copy overflowing. At every width the site is built for,
  the number below is what they are.

  The padding is even, at 39px on all four sides at 1440 — the 38–40 the brief asks for,
  reached by clamp rather than stated, so it still tracks the viewport. Even is the point:
  the sentence sits the same distance off the bottom edge as the title sits off the top,
  and the icon the same distance off the right as the title off the left, which is what
  makes one 39px frame around all four sides and the hole in the middle read as intended
  rather than as a paragraph that came up short.

  ── The ink on it ───────────────────────────────────────────────────────────

  Two rebinds and no colour. `--fg` and `--fg-sub` are the light family's black and grey
  three levels up the cascade, and neither survives on #212426 — `--paper-sub` measures
  2.8:1 there. So the panel rebinds both to the two values tokens.css declares for exactly
  this surface, and then `color: var(--fg)` is what the title actually reads: nothing below
  states a colour, `.adv-title` has no `color` of its own, and the copy keeps the
  `var(--fg-sub)` it always had.
*/
.adv-panel {
  display: flex;
  flex-direction: column;
  min-height: clamp(230px, 17.5vw, 256px);
  padding: clamp(28px, 2.7vw, 40px);
  border-radius: 6px;
  background: var(--bg-raised);
  --fg: var(--paper-panel-fg);
  --fg-sub: var(--paper-panel-sub);
  color: var(--fg);
  transition: background-color var(--dur-med) var(--ease);
}

/*
  The whole of the hover: the panel comes up one barely perceptible step, to #272A2C. No
  lift, no shadow, no scale, no border, no glow, and nothing happens to the icon — a panel
  is not a control, there is nothing behind it to go to, and the response has to read as
  "you are looking at this one" rather than as "press this".

  It used to lighten by about a third of the way to the canvas, which on a grey panel one
  level off its ground was a small move and on graphite would be a jump to mid-grey. 3%
  of the title's own off-white is the replacement, and `color-mix` rather than a fifth hex
  for the same reason as before: the value is derived from the two the panel already
  states, so there is nothing here to keep in step by hand.

  Lighter and not darker, because lighter is the direction the section reads in — the panel
  steps very slightly towards the paper it is set into.
*/
.adv-panel:hover {
  background: color-mix(in srgb, var(--bg-raised) 97%, var(--paper-panel-fg));
}

/*
  One step per panel, so the six arrive as a sweep rather than as a block. 45ms is
  deliberately short: at six steps anything slower turns the last panel's entrance into
  something a reader waits for, and nothing in this section is waited for.

  Scoped to `html[data-js='true']` because that is where the reveal's base state lives —
  see base.css. With the module blocked there is no transition to delay and no delay
  applied.
*/
html[data-js='true'] .adv-panel[data-reveal] {
  transition-delay: calc(var(--i, 0) * 45ms);
}

/* ═══ THE PANEL'S LAYOUT ═════════════════════════════════════════════════ */

/*
  Title and icon on one line, top-aligned, pushed to opposite corners. Not the icon stacked
  over the title, which is what the tile version did and what every feature card does: at
  42px the mark is a second object rather than a caption, and two objects competing for the
  same column is what makes a card look busy. In opposite corners each has a corner, and the
  title has the panel's whole measure to wrap into.

  `gap` is the guarantee. A title of two or three words never comes near the icon at these
  widths, but the flex line is `space-between` and the day a title grows it should wrap
  rather than close on the drawing.
*/
.adv-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}

/*
  And the sentence sits on the floor. `margin-top: auto` rather than a fixed distance from
  the title, because the empty middle is the point: the copy belongs to the bottom edge of
  the panel, not to the bottom of the title, and it has to stay there whether the title
  takes one line or two.
*/
.adv-copy {
  margin-top: auto;
  padding-top: 18px;
}

/* ═══ THE ICON ════════════════════════════════════════════════════════════ */

/*
  A 52px box with 44px of drawing in it, and the box is the load-bearing part.

  Six symbols of six different objects do not balance the same way — a shield's ink is all in
  its upper half, a clock's is symmetrical, a fast clock is a quarter wider than it is tall —
  and the only honest fix is one box every drawing is centred inside, at one size, with the
  empty margin already cropped off in icons.py. The dishonest fixes are a per-icon `top` or
  `right` offset here, and a per-icon `width`, and both are worth naming because they are
  what gets reached for first: the moment one icon is nudged or scaled on its own the other
  five are wrong and there is no way left to tell which. Optical size is settled in the
  artwork or it is not settled.

  So there is not one icon-specific rule in this stylesheet. The wrapper has been 42, 46,
  48 and 50, and 52 is the graphite panel's number: white linework on a dark ground carries
  less optical weight than the same linework in black on a light one, so the marks come up
  four units to hold their old presence beside a 26px title. 4px of slack on each side is
  what is left, and it exists so six different silhouettes have one place to centre in.

  ── Where it sits ───────────────────────────────────────────────────────────

  Top-right, on the panel's own 39px frame, and by nothing more than being the second item
  in `.adv-top`: the flex row is `space-between` inside the padding box, so the icon's right
  edge is 39px off the panel's right edge and its top is 39px off the top — the ~38 the
  brief asks for, without a single absolute coordinate to get out of step with the padding.

  `align-items: flex-start` on that row, and no vertical nudge here at all. The previous
  version pulled the box up 6px to bring its centre nearer the centre of the title's caps,
  which is a real optical gain and costs the thing the brief asks for by name: the icon then
  sits 33px off the top while the title sits at 39, and six panels' worth of that reads as a
  mark floating above its own frame rather than as one square corner. Alignment with the
  frame wins, because the frame is what all six share. `align-items: center` is the other
  wrong answer — the icon would drift to the middle of the block the moment a title wrapped
  to two lines instead of staying with the first.

  ── What is deliberately absent ────────────────────────────────────────────

  No `background`, no `border`, no `border-radius`, no `::before`, no `::after`. There is no
  white circle, plate, badge or square behind the mark and there is nothing here that could
  draw one: the artwork is white on genuine transparency, so what shows behind it is the
  panel's own graphite.
*/
.adv-icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
}

/*
  The supplied image, in the fixed box above, and there is not one colour rule in here.

  One pair of maximums for all six, with `width` and `height` left to the image, is the
  whole mechanism. The six were exported separately and crop to different ratios — 174×176,
  176×156, 156×176, 174×176, 176×174, 176×139 after icons.py — so a 44px cap on each axis
  lets every one of them render at its own proportion inside the same square: the fast clock
  lands 44 × 35, the shield 39 × 44, and none of the six is stretched a pixel. `object-fit`
  is there as the belt to that braces, for the day an asset is replaced by one whose
  intrinsic size disagrees with its box.

  44 against the wrapper's 52. It was 38 in 48, and both numbers moved together so the air
  around the mark is unchanged at 4px a side.

  ── What is deliberately absent ────────────────────────────────────────────

  No `filter`, no `invert`, no `mask`, no `mix-blend-mode`, no `currentColor`, no
  `background`, no `opacity`, no overlay, no `::before` or `::after`, no hover state.
  `color`, `fill` and `stroke` cannot reach into a raster, and they are not declared here
  either — the images are near-white linework on genuine transparency and they are meant to
  render exactly as delivered.

  That list is the point rather than a formality. The six white files replaced six black
  ones at the same paths when the panels went dark, and the one thing that must never
  happen here is the same result reached by inverting the black set: an inverted PNG is a
  different mark — the antialiasing goes the wrong way and any non-black pixel becomes a
  colour nobody chose. There is no `filter` in this section, on the marks or anywhere else.

  This block also replaced three rules and their arguments, further back: `.adv-mark` set
  `stroke: var(--adv-ink)` at 2.2 with round caps and joins, `.adv-mark-accent` painted one
  element of each mark #FF5C35, and `.adv-mark-heavy` was a single 2.6 exception for the
  check inside the shield. All three styled inline SVG this section no longer emits. They
  are gone rather than left in place: a stylesheet that can still colour a mark is a
  stylesheet that will.

  No hover on the mark, and now there is nothing to hover. `.adv-panel:hover` already moves
  the panel's surface, which is the hover a reader notices.
*/
.adv-mark {
  display: block;
  max-width: 44px;
  max-height: 44px;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* ═══ THE TYPE ═══════════════════════════════════════════════════════════ */

/*
  `--t-h3` is clamp(20px, 1.9vw, 26px) — the page's own display size for a section's
  subheads, and at 26px from 1370 up it is the 24–28 the brief asks for. It was 17px in
  the tile version, which is what a two-word label wants in a 196px column; in a 380px
  panel the same title at the same size reads as a caption on an empty rectangle.

  Tighter line height than the scale's default, because the two-word titles that wrap —
  `Vetted suppliers` at the narrow end of two columns — should read as one thing on two
  lines.

  Size, family and weight are the ones this block already had, and the panel going dark did
  not change any of them: `--t-h3`, `--font-display`, 800 from base.css. There is no `color`
  here either — `.adv-panel` sets `color: var(--fg)` and rebinds `--fg` to
  `--paper-panel-fg` #F5F5F2, which is 14.2:1 on the graphite. Off-white and not
  `--pure-white`: #FFFFFF is 15.6:1 and reads as a screen against a page whose whole cast
  is paper.
*/
.adv-title {
  font-size: var(--t-h3);
  line-height: 1.1;
  margin-bottom: 0;
}

/*
  17px and `--fg-sub`, which the panel rebinds — not `--fg-soft`, and not a grey of its
  own. On the old #ECECEA panel `--fg-sub` was #686864 at 4.7:1; on graphite it is
  `--paper-panel-sub`, the title's own off-white at 62%, compositing to #A4A6A4 for 6.4:1.

  One ink diluted rather than a second value, because the two have to stay a step apart
  whatever the panel does. And clearly secondary but never white: the sentences are for the
  one or two panels a reader stops on, and copy at full strength beside a title at full
  strength is six panels shouting the same thing twice.

  The measure is 40 characters, up from 30 and then 38, and the number moved because the
  copy did. 30ch is right for one sentence of a dozen words — two or three comfortable
  lines, and a 40-character line in a 380px panel reads as a paragraph. Three of the six
  now carry a second sentence, and at 30ch the longest of them ran to five lines, which is
  one more than `.adv-panel`'s `min-height` holds: the panel grew, its row grew with it,
  and the section stopped fitting a laptop screen.

  38 fixed that for the copy of the day and 40 fixes it for this one. `Vetted suppliers` is
  152 characters, the longest of the six, and at 38ch it was the only card taking a fifth
  line at 1728 — one card a line taller than the five beside it, in the row a reader looks
  at first. Two characters of measure is 22px of line and it is enough: at 40ch all six
  land in four lines up there. Above about 1700 the column stops being the constraint at
  all — 44ch and 46ch measure the same 461px, because that is the panel minus its padding —
  so 40 is inside the range where the number still does something.

  Below 1440 the column is narrower than the measure and the copy wraps where the box says,
  not where this does. The line counts differ there (four and five at 1440, five and six at
  1180) and the panels do not, because the rows are `1fr`: see `.adv-grid`.

  Widening the measure is the right lever here and shrinking the type is not. 16px for the
  only explanation in the section is under this page's floor, and per-card sizing — the
  other obvious fix — makes the long cards quietly less important than the short ones.

  `pretty` and not `balance` — balance evens the lines of a heading and will spend a whole
  extra line to do it; pretty leaves the line count alone and only refuses to end on one
  word, which is the actual problem in three of these six.
*/
.adv-copy {
  max-width: 40ch;
  font-size: clamp(16px, 1.2vw, 17px);
  line-height: 1.45;
  color: var(--fg-sub);
  margin-bottom: 0;
  text-wrap: pretty;
}

/* ═══ NARROW ═════════════════════════════════════════════════════════════ */

/*
  Two across. Three panels stop having a measure worth reading below about 1080px — the
  copy starts taking four lines in a 300px panel with 29px of padding either side — and
  two columns of three is the same grid with one fewer division. The seam system is
  untouched: it is the gap, and the gap does not care how many columns there are.
*/
@media (max-width: 1080px) {
  .adv-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/*
  One across, and shorter. Six full-height panels stacked is a screen and a half of
  scrolling this early on the page, so the panel loses its empty middle and keeps its
  three parts: title upper left, diagram upper right, sentence below. It is the same
  object at three quarters the height, not a different one — which is why the padding
  comes down a step and nothing else changes. Desktop proportions are not forced down
  here: a phone is one column and the panel is as tall as its contents need.

  The 52px icon box does not come down with the padding, and it does not need to: at 22px
  either side a 390px viewport leaves 302px of content, the two-word titles run 100–150px,
  and the widest mark is still 44px. Nothing overflows and nothing wraps under the icon —
  which is the one thing to check on a phone, because the fast clock is the wide one.
*/
@media (max-width: 620px) {
  .adv-grid {
    grid-template-columns: 1fr;
  }

  .adv-panel {
    min-height: 168px;
    padding: 22px;
  }

  .adv-copy {
    padding-top: 18px;
    /* No competition for the width down here, and a phone reads a full measure. */
    max-width: none;
  }
}

/* ═══ REDUCED MOTION ═════════════════════════════════════════════════════ */

/*
  The stagger goes. base.css already resets the reveal itself — opacity 1, no transform —
  but the delay is set here and would survive it, which on a section that never animates
  means six panels each holding a transition they are not using.
*/
@media (prefers-reduced-motion: reduce) {
  html[data-js='true'] .adv-panel[data-reveal] {
    transition-delay: 0ms;
  }
}

/* ═══ PRINT ══════════════════════════════════════════════════════════════ */

/*
  Three columns and no panels. The graphite surface and the seams are how they separate on
  screen; on paper the white space does it, and six graphite rectangles print as six solid
  blocks of toner.

  Dropping the background is what makes the type reset below mandatory rather than tidy.
  The panel rebinds `--fg` and `--fg-sub` to two off-whites, which is correct on graphite
  and invisible the instant the graphite goes: off-white on white paper prints as nothing
  at all. So the two variables go back to the section's light-family values, and the
  section's own `--fg` is `--ink` — see the `[data-theme='light']` block in tokens.css.
*/
@media print {
  .adv-grid {
    grid-template-columns: repeat(3, 1fr);
    /* Equal rows are for panels. With no panel there is nothing to align to a bottom
       edge, and forcing both rows to the taller one just prints blank paper. */
    grid-auto-rows: auto;
    gap: 26px 30px;
  }

  .adv-panel {
    min-height: 0;
    padding: 0;
    background: none;
    --fg: var(--ink);
    --fg-sub: var(--paper-sub);
  }

  .adv-icon {
    display: none;
  }

  .adv-copy {
    padding-top: 8px;
  }
}
