/* Template scaffolding — page layout and web-scale sizing only; every color,
   font, radius and shadow comes from design-system.css. The voice is the
   deck's, re-derived for a scrolling page: an engineering document — Barlow
   Condensed titles in uppercase over Barlow text, visible drawn structure
   (1px caption rules; wireframe cells with registration-cross corners for
   the feature cards — the system's own card grammar; a registration-marked
   spec plate for the numbers), the steel accent as the single color,
   photographs duotoned like screen prints.

   THE RHYTHM: a 24px leading unit (16px Barlow body at 1.5 — the system's
   0.85 density runs compact), 12px half-step; line-heights and block
   margins in unit multiples, heads cap-trimmed, ?baselines/B to review.
   The deck's seat-pinning relaxes to per-block discipline on a fluid page.
   The system's own interface components keep their styles.css leading.

   THE LANDING LAWS (shared by all six systems' landing templates):
   #1 display headers break per sentence (.line spans); #2 the landing
   advertises an invented product played straight — industry's is Holdfast,
   a bolt-and-fastener catalog written like the datasheet it is; #3
   spacing is cluster-scoped (display leading ratio-governed ≈1.04 for the
   uppercase condensed — the display-block lattice exemption — tight
   single-unit gaps inside a cluster, the air between sections); #4 no
   hero eyebrow — the nav brand names the product.

   Measured Barlow values carry verbatim from the deck template: optical
   left alignment -0.052em where caps lead a condensed display line, quote
   hang -0.316em (Condensed 600), attribution hang -0.885em (Regular). */
:root {
  --leading: 24px;
  --half: 12px;
  --edge: clamp(20px, 5vw, 72px);
  --measure: 60ch;
}
/* — background art —
   A page supplies its own art inline (style="background-image:url(...)") and
   this sheet decides how it sits, so the two concerns stay separate: choosing
   the picture is editorial, framing it is the system's job.

   Every source in background/ is 1056px wide, narrower than any of these
   blocks on a desktop viewport, and the CSS initial values are background-size:
   auto with background-repeat: repeat — so without this rule the art paints at
   natural size from the top-left and tiles, seaming down the right edge and
   stacking a second copy below on any block taller than the image.

   Matching on the inline declaration rather than naming blocks means a section
   given art later is framed the moment the markup lands, with nothing to
   remember here. If a block ever genuinely wants a repeating texture, override
   background-repeat on that block's own rule — a class beats this in the
   cascade only when it comes later, so put it after this. */
[style*="background-image"] {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { margin: 0; text-wrap: pretty; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 var(--edge); }
/* the component demo pads the masthead with its own spacing; on the page the
   masthead's contents take the page gutter and sit on the wrap's text axis
   (padding-only — full-width paint such as a masthead rule is untouched) */
.nav { padding-inline: max(var(--edge), calc((100% - 1200px) / 2 + var(--edge))); }
.nav a { white-space: nowrap; }
.nav a[aria-current='location'] { color: var(--color-accent-700); } /* in-page anchor,
   not a page link — 'location' is the truthful value. The 700 step, not the
   base accent: at 14px this is small text, where the base steel's 3.7:1
   large-text value does not reach (5.8:1 measured — the same call broadsheet's
   round 2 made, and the kickers already make here) */
@media (max-width: 480px) { .nav a { display: none; } } /* phone width: the nav
   keeps brand + the one action (layout-only — the component's look is untouched) */

/* The masthead's two actions are buttons that happen to be links, and
   .nav a { color: inherit } (0,1,1) out-specifies .btn-primary (0,1,0) — so
   without these the Register label inherits the page ink onto its black
   ground, and :hover repaints both to the accent. Stated at 0,3,1 so the
   button owns its own colour in the one place it sits inside a nav.

   Register is the masthead's one action; Sign in is a plain menu link and
   needs nothing here. */
.nav a.btn-primary, .nav a.btn-primary:hover { color: #afc2e0; }

/* — caption rules (the deck's grammar: the label sits ABOVE a drawn 1px
   rule and the content seats below it — structure made visible) — */
.kicker {
  display: block; font-size: 18px; line-height: var(--half);
  letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600;
  color: #123352;
  font-feature-settings: "tnum" 1;
  margin: 0 0 var(--half);
}
.caption-rule { height: 1px; border: 0; margin: 0 0 calc(var(--leading) - var(--half));
  background: var(--color-divider); }

/* — hero — */
.hero { padding: calc(4 * var(--leading)) 0 calc(3 * var(--leading)); }
.display {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: clamp(36px, 5.2vw, 72px);
  line-height: clamp(37px, 5.4vw, 75px); /* law #3: ratio-governed ≈1.04, a
     deliberate step below the lowercase systems' 1.06-1.11 band — uppercase
     condensed carries no descenders to clear; the display-block lattice
     exemption. Scaled down a quarter from the original 48/7vw/96 — every value
     moved together so the ratio, and the optical alignment below that depends
     on it, still hold. */
  letter-spacing: 0.01em; text-transform: uppercase; margin: 0;
  margin-left: -0.052em; /* optical left alignment — the deck's measured Condensed 600 value */
  text-box: trim-both cap alphabetic;
}
.display .line { display: block; } /* law #1 */
.hero .sub { font-size: 16px; line-height: var(--leading); max-width: var(--measure);
  margin: calc(1.5 * var(--leading) - 1cap) 0 0;
  text-box: trim-both cap alphabetic; }
.hero .row { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--leading); }

/* — the spec sheet (this system diverges from the shared stat-band chassis
   here): where the chassis set four display numerals on a steel field,
   Holdfast prints SHEET 01 of its own drawing set — a hairline-framed
   plate with registration crosses (the frame every drawn object in this
   system wears) carrying an engineering title block and the four product
   claims as numbered datasheet rows. For a catalog "written like the
   datasheet it is", tabulated data is the native grammar for numbers.
   The steel ground leaves the page with the band — the deck's dividers
   keep theirs, and the solid accent button returns to being the one
   solid object on the board. Downstream sections number themselves into
   the set with the deck's own kicker grammar ("02 · ").

   Rhythm: the title block is a 2-unit band (24px line + half-step padding
   each side, wrap-safe); header row 1.5 units, data rows 2 units, text
   centered on its band (the documented optical row-centering exception —
   no cap trim inside row bands, so the authored line boxes carry the
   math); the plate's internal rules land on the band seams. Figures in
   the table are COLUMNS and take tabular figures per the deck's figure
   policy — the display-numeral proportional exception retired with the
   stat band. The downstream kickers number into the set with the deck's
   bare "NN · " grammar while only the plate says the word "Sheet" — the
   linkage is deliberately soft; the sections read as numbered notes
   around the one drawn sheet, not as four dressed plates. — */
.sheet { padding: calc(3 * var(--leading)) 0 calc(2.5 * var(--leading)); }
.plate { position: relative; border: 1px solid var(--color-divider); }
.plate > .corner { position: absolute; width: 15px; height: 15px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent); pointer-events: none; }
.plate > .corner::before { content: ""; position: absolute; left: 7px; top: 0; width: 1px; height: 100%; background: currentColor; }
.plate > .corner::after  { content: ""; position: absolute; top: 7px; left: 0; width: 100%; height: 1px; background: currentColor; }
.plate > .corner.tl { top: -8px; left: -8px; }
.plate > .corner.tr { top: -8px; right: -8px; }
.plate > .corner.bl { bottom: -8px; left: -8px; }
.plate > .corner.br { bottom: -8px; right: -8px; }
/* the title block — the drawing's own naming furniture: a flexing title
   cell, then register cells (doc, revision, sheet count) divided by
   hairlines, all at the kicker's scale. The title prints in full text
   ink — it is the section's heading; the register cells take 70% ink,
   5.8:1 measured on this ground, where the system's 55% furniture
   convention is a large-text value (3.6:1) */
.title-block { display: flex; flex-wrap: wrap; align-items: stretch;
  border-bottom: 1px solid var(--color-divider); }
.title-block > span { padding: var(--half) var(--leading);
  font-size: 13px; line-height: var(--leading); letter-spacing: 0.08em;
  text-transform: uppercase; font-weight: 600; font-feature-settings: "tnum" 1; }
.tb-title { flex: 1; min-width: 16ch; }
.tb-cell { border-left: 1px solid var(--color-divider); white-space: nowrap;
  color: color-mix(in srgb, var(--color-text) 70%, transparent); }
/* the spec table — the system's own .table component at landing scale (the
   deck resizes it the same way). The № column takes the deep accent step,
   the same call as the kickers (5.8:1 at 13px, where the base steel's
   3.7:1 is a large-text value); values set in the condensed face at the
   cell-heading scale, so the numbers stay the section's loudest objects */
.spec { table-layout: fixed; }
.spec col.c-num { width: calc(3 * var(--leading)); }
.spec col.c-prop { width: 30%; }
.spec col.c-val { width: 21%; }
.spec th, .spec td { padding: var(--half) var(--leading) var(--half) 0; vertical-align: middle; }
.spec th:first-child, .spec td:first-child { padding-left: var(--leading); }
.spec th { font-size: 13px; line-height: var(--half); font-weight: 600; /* the
     section's furniture weight — otherwise the UA's default th bold makes
     the header row the sheet's only 700, by accident rather than decision */
  color: color-mix(in srgb, var(--color-text) 70%, transparent); /* the component's
     11px/60% header re-derived for the landing: 13px is still small text,
     where 70% measures 5.8:1 and 60% falls short of 4.5:1 */ }
.spec td { font-size: 15px; line-height: var(--leading); }
.spec .s-num { font-size: 13px; font-weight: 600; letter-spacing: 0.08em;
  color: var(--color-accent-700); font-feature-settings: "tnum" 1; }
.spec .s-val { font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 22px; line-height: var(--leading); letter-spacing: 0.02em;
  font-feature-settings: "tnum" 1; white-space: nowrap; }
.spec .s-rem { color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.spec tbody tr:last-child td { border-bottom: 0; } /* the notes rule closes the
   rows — avoid a doubled line against .sheet-note's divider */
.spec tbody tr:hover { background: none; } /* a printed sheet, not an
   interactive grid */
.sheet-note { margin: 0; padding: var(--half) var(--leading);
  border-top: 1px solid var(--color-divider);
  font-size: 13px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 70%, transparent); /* 5.8:1 — see .spec th */ }

/* — wireframe feature cells (the system's OWN card grammar: square,
   thin-bordered, registration-cross corners, no surface fill) — */
.features { padding: calc(3 * var(--leading)) 0 calc(2.5 * var(--leading)); }
.features > .caption-rule { margin-bottom: calc(var(--leading) + 8px); } /* the cells'
   registration crosses hang 8px above the frame's padding edge (7px of ink
   past the 1px border) — a drawn rule keeps one full unit of air to the
   nearest ink, so the rule clears the cross ink by 25px, not a sliver */
.cells { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 3vw, 48px);
  margin-top: calc(var(--leading) - var(--half)); }
.cell-frame { position: relative; border: 1px solid var(--color-divider);
  background-color: #cddbf1;
  padding: var(--leading); } /* one full unit on every side — the cap-trimmed
     heading seats with the same air above it as the text keeps to the frame's
     left and right */
.cell-frame > .corner { position: absolute; width: 15px; height: 15px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent); pointer-events: none; }
.cell-frame > .corner::before { content: ""; position: absolute; left: 7px; top: 0; width: 1px; height: 100%; background: currentColor; }
.cell-frame > .corner::after  { content: ""; position: absolute; top: 7px; left: 0; width: 100%; height: 1px; background: currentColor; }
.cell-frame > .corner.tl { top: -8px; left: -8px; }
.cell-frame > .corner.tr { top: -8px; right: -8px; }
.cell-frame > .corner.bl { bottom: -8px; left: -8px; }
.cell-frame > .corner.br { bottom: -8px; right: -8px; }
.cell-frame h2 { font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 22px; line-height: var(--leading); letter-spacing: 0.02em; text-transform: uppercase;
  margin: 0; text-box: trim-both cap alphabetic; }
.cell-frame p { font-size: 15px; line-height: var(--leading); margin: calc(var(--leading) - 1cap) 0 0;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  text-box: trim-both cap alphabetic; }

/* — imagery split (the duotone screen print inside a wireframe frame —
   the figure takes the same marked treatment as every framed object) — */
.split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--leading) clamp(24px, 5vw, 96px); align-items: center;
  padding: calc(2 * var(--leading)) 0 calc(3 * var(--leading)); }
.split-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 32px; line-height: calc(1.5 * var(--leading)); letter-spacing: 0.02em; text-transform: uppercase;
  color: #123352;
  margin: 0; text-box: trim-both cap alphabetic; }
.split-copy .note { font-size: 15px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  margin: calc(var(--leading) - 1cap) 0 0; max-width: 48ch; text-box: trim-both cap alphabetic; }
.split-figure { margin: 0; } /* .blueprint owns the frame: position, the 1px
     border, and — critically — the overflow exemption that lets the
     registration crosses live outside the box (.blueprint.duotone
     { overflow: visible } in styles.css; a bare .duotone clips them) */
.split-figure > .corner { position: absolute; width: 15px; height: 15px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent); pointer-events: none; /* the
     registration crosses overlap the slot by a few px — decorative marks
     must not eat its hover/drop events (image-slot usage contract) */ }
.split-figure > .corner::before { content: ""; position: absolute; left: 7px; top: 0; width: 1px; height: 100%; background: currentColor; }
.split-figure > .corner::after  { content: ""; position: absolute; top: 7px; left: 0; width: 100%; height: 1px; background: currentColor; }
.split-figure > .corner.tl { top: -8px; left: -8px; }
.split-figure > .corner.tr { top: -8px; right: -8px; }
.split-figure > .corner.bl { bottom: -8px; left: -8px; }
.split-figure > .corner.br { bottom: -8px; right: -8px; }
.split-figure { width: 100%; } /* the bundled
   photograph's natural ratio pins the box, so a swapped image cover-crops
   into the same frame (cover framing is the component's own) */

/* — quote (condensed, uppercase-free — the one lowercase condensed moment;
   hangs at the deck's measured advances) — */
.quote { padding: calc(2.5 * var(--leading)) 0 calc(3.5 * var(--leading)); }
/* The art seats flush against the caption rule. The rule carries a 12px bottom
   margin (--leading minus --half) and the wrapper is pulled up through exactly
   that, then gives the space back as padding — so the picture's top edge meets
   the rule while the quote inside stays on the baseline the rhythm put it on.
   Pulling the box up rather than deleting the rule's margin is what keeps those
   two things independent. */
.quote-art {
  margin-top: calc(var(--half) - var(--leading));
  padding-top: calc(var(--leading) - var(--half));
}
.quote blockquote {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: clamp(26px, 2.8vw, 36px); line-height: calc(1.5 * var(--leading));
  letter-spacing: 0; max-width: 36ch; margin: 0;
  text-indent: -0.316em; /* hang the opening “ (the deck's measured advance in the Condensed 600) */
  text-box: trim-both cap alphabetic;
}
.quote figcaption { font-size: 15px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 70%, transparent); /* small-text ink on the
     paper ground: 70% measures 5.8:1 (55% is a large-text value here — 3.6:1) */
  margin: calc(2 * var(--leading) - 1cap) 0 0; /* two grid units below the quote's
     last baseline — one reads as part of the quote block; the attribution needs air */
  text-indent: -0.885em; /* hang the leading em-dash + space (measured in Barlow Regular) */
  text-box: trim-both cap alphabetic; }

@media (max-width: 720px) {
  /* the phone gutter (--edge bottoms out at 20px) is narrower than the hung
     marks' measured advances, so a hung “ or em-dash would press into or past
     the viewport edge — seat the quote flush below this width; the hang
     returns with the wider gutter */
  .quote blockquote, .quote figcaption { text-indent: 0; }
}

/* — close (paper, a caption rule above; the primary is the system's solid
   accent action — everything else stays a line drawing) — */
.close { padding: calc(2.5 * var(--leading)) 0 calc(2 * var(--leading)); }
.close h3 { font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 24px; line-height: var(--leading); letter-spacing: 0.02em; text-transform: uppercase;
  margin: 0; text-box: trim-both cap alphabetic; }
.close .sub { font-size: 15px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  margin: calc(var(--leading) - 1cap) 0 0; max-width: var(--measure); text-box: trim-both cap alphabetic; }
.signup { display: flex; gap: var(--space-3); align-items: stretch; max-width: 480px;
  margin-top: var(--leading); }
.signup .input { flex: 1; }
.signup .input, .signup .btn { min-height: 36px; } /* one control height floor; the row
  stretches, so whichever of the pair is taller sets both and they read as one row */
footer { padding: calc(2 * var(--leading)) 0; font-size: 13px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 70%, transparent); /* 5.8:1 — see .quote figcaption */ }

/* — responsive collapse — */
@media (max-width: 880px) {
  .cells { grid-template-columns: 1fr; gap: calc(var(--leading) + 16px); } /* stacked
     frames: both cells' crosses overhang 7px of ink into the gap, so the
     clamp's 20px floor left 6px cross-to-cross — a 40px gap keeps a full
     unit of air (26px) between the facing crosses */
}
@media (max-width: 720px) {
  .hero { padding-top: calc(2.5 * var(--leading)); }
  /* the sheet re-stacks: the title block drops its register cells to a
     second ruled row, and each table row becomes its own small plate —
     № and property on the register line, the value beneath, the remark
     last. (Linearizing the table trades its grid semantics for reading
     order; the row order is unchanged.) */
  .tb-title { flex-basis: 100%; border-bottom: 1px solid var(--color-divider); }
  .title-block > .tb-cell { padding-inline: var(--half); flex: 1 0 auto; } /* beats the
     base span padding's specificity; the cells flex to close the register
     row against the frame. (All title-block children are spans, so
     :first-of-type can never name a register cell — the sibling selector
     below is the one that works) */
  .tb-title + .tb-cell { border-left: 0; padding-left: var(--leading); } /* first register
     cell: its hairline would double the plate's own left border */
  .spec thead { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; } /* visually hidden, not
     display:none — the stacked rows carry their own register (№ + property),
     so the column heads are redundant on screen, but they stay in the
     accessibility tree for readers that still expose the table semantics */
  .spec, .spec tbody, .spec td { display: block; }
  .spec tr { display: grid; grid-template-columns: max-content 1fr;
    column-gap: var(--half); row-gap: var(--half); align-items: baseline;
    padding: var(--leading);
    border-bottom: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent); }
  .spec tr:last-child { border-bottom: 0; }
  .spec th, .spec td { padding: 0; border: 0; }
  .spec th:first-child, .spec td:first-child { padding-left: 0; } /* matches the
     desktop rule's specificity, or the № keeps its 24px inset and floats
     off the stacked rows' shared axis */
  .spec .s-num { grid-column: 1; }
  .spec .s-prop { grid-column: 2; }
  .spec .s-val, .spec .s-rem { grid-column: 1 / -1; }
  .spec .s-blank { display: none; } /* the desktop table's "no remark" dash
     would dangle as a stray mark in the stacked row */
  .split { grid-template-columns: 1fr; }
  .split-figure { order: -1; }
}
@media (max-width: 360px) {
  /* the narrowest screens: one register row no longer fits, so the title
     block re-forms as its own grid — doc and revision share a ruled row,
     the sheet count takes the next — and a wrap can never leave a cell
     floating without a rule */
  .title-block { display: grid; grid-template-columns: 1fr 1fr; }
  .tb-title { grid-column: 1 / -1; border-bottom: 0; } /* the rules move to the cells' tops */
  .title-block > .tb-cell { border-left: 0; border-top: 1px solid var(--color-divider);
    padding-left: var(--leading); }
  .tb-title + .tb-cell + .tb-cell { border-left: 1px solid var(--color-divider);
    padding-left: var(--half); } /* the revision keeps its divider against the doc cell */
  .tb-cell:last-child { grid-column: 1 / -1; }
}

/* — borrowed-content support —
   Four small additions carrying content ported from the fuller source page.
   Each is built from the sheet's existing vocabulary — the 24px leading unit,
   the hairline divider, the kicker's deep blue — rather than a second style
   language sitting alongside it. */

/* the claim strip: four short guarantees seated on a drawn rule, directly
   beneath the hero rather than inside it. Inside, it made the hero taller than
   the art it carries, so cover scaled the picture up and cropped it — and the
   strip itself read as a squeezed tail on the section. Out here with no top
   margin, its rule lands flush on the hero's bottom edge, where the art ends,
   so it reads as a caption under the picture. */
.strip { display: flex; flex-wrap: wrap; gap: var(--half) calc(2 * var(--leading));
  margin-top: 0; padding-top: var(--half);
  border-top: 1px solid var(--color-divider);
  font-size: 14px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.strip b { font-weight: 600; color: var(--color-text); }

/* the queue comparison: the same four studies in arrival order and in urgency
   order, so the reordering is shown rather than asserted */
.queue { list-style: none; margin: var(--leading) 0 0; padding: 0;
  font-size: 14px; line-height: var(--leading); }
.queue li { display: grid; grid-template-columns: 2.4em 1fr auto;
  gap: 0 var(--half); padding: calc(var(--half) / 2) 0;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent); }
.queue li:last-child { border-bottom: 0; }
.queue .n, .queue .t { font-feature-settings: "tnum" 1; }
.queue .n { font-weight: 600; color: #123352; }
.queue .t { color: color-mix(in srgb, var(--color-text) 70%, transparent); }
.queue .crit { font-weight: 600; }

/* capability and answer lists inside the wireframe cells — dashed off the
   left edge on the half-step, never bulleted; the system draws, it does not
   decorate */
.cell-frame ul { list-style: none; margin: var(--leading) 0 0; padding: 0;
  font-size: 14px; line-height: var(--leading); }
.cell-frame ul li { position: relative; padding-left: var(--leading);
  color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.cell-frame ul li::before { content: ""; position: absolute; left: 0;
  top: calc(var(--leading) / 2); width: var(--half); height: 1px;
  background: var(--color-divider); }

/* the register number on a cell that is one of a numbered set */
.cell-num { display: block; font-size: 13px; font-weight: 600;
  letter-spacing: 0.08em; color: #123352; font-feature-settings: "tnum" 1;
  margin-bottom: var(--half); }
/* a cell's own intro line, above the grid of cells */
.sec-intro { font-size: 15px; line-height: var(--leading); max-width: var(--measure);
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  margin: calc(var(--leading) - 1cap) 0 0; text-box: trim-both cap alphabetic; }

/* two-up cells, for the arrival-order / urgency-order comparison. Declared
   (0,2,0) like .cells-4 so the later responsive .cells rules cannot win it back. */
.cells.cells-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 880px) { .cells.cells-2 { grid-template-columns: 1fr; } }

/* a phase tag sitting above a cell's heading */
.cell-frame .tag { margin-bottom: var(--half); }

/* — sign-in and registration: the same wireframe cell as everything else,
   held to a readable measure rather than running the full grid width — */
.auth { max-width: 520px; margin-top: var(--leading); }
.auth .field + .field { margin-top: var(--leading); }
.auth .btn-block { margin-top: var(--leading); }
.auth .consent { display: flex; gap: var(--space-2); align-items: flex-start;
  margin-top: var(--leading); font-size: 14px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.auth-alt { margin: var(--leading) 0 0; font-size: 14px; line-height: var(--leading);
  color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.auth-note { margin: calc(var(--leading) - 1cap) 0 0; font-size: 13px;
  line-height: var(--leading); max-width: var(--measure);
  color: color-mix(in srgb, var(--color-text) 70%, transparent); }

/* — a top-aligned art band —
   Art that occupies a fixed band at the TOP of a block rather than covering the
   whole of it. Three things have to be true at once and each needs its own
   declaration:

   flush to the rule — the wrapper is pulled up through exactly the 12px the
   caption rule carries as bottom margin, and gives that space back as padding,
   so the band's top edge meets the line while the text below keeps the baseline
   the rhythm gave it;
   a fixed depth — background-size takes an explicit height (--band, 400px by
   default) instead of cover, which would scale the picture to the block's full
   height;
   pinned to the top — background-position: top, so the band sits at the rule
   rather than centring itself down the block.

   This overrides the blanket [style*="background-image"] rule near the top of
   this sheet: same specificity, declared later, so it wins. */
.band-art {
  background-size: 100% var(--band, 400px);
  background-position: top center;
  background-repeat: no-repeat;
}
/* the flush-to-rule pull is a separate opt-in: a band that follows a caption
   rule wants it, a band at the top of a section (the hero) has no rule to
   seat against and must not be pulled up at all.

   The pull has to match the margin the rule actually carries, and that is not
   one number: .caption-rule's own bottom margin is the half-step, but
   .features widens it to --leading + 8px so the cells' registration crosses
   clear the rule. Pulling up by the half-step inside a .features section left
   exactly the difference — 20px — as a gap. --rule-gap names the amount, the
   band pulls up by it and gives it back as padding, and .features restates it. */
.band-flush {
  --rule-gap: calc(var(--leading) - var(--half));
  margin-top: calc(-1 * var(--rule-gap));
  padding-top: var(--rule-gap);
}
.features > .band-flush { --rule-gap: calc(var(--leading) + 8px); }

/* — the dark ground, ported verbatim from the source page for section 05 —
   Everything here is the source's own vocabulary rather than this sheet's: a
   full-bleed dark band, a two-up grid, an SVG flow figure and two animations.
   Kept intact so the section matches the source exactly. */

/* full-bleed: breaks out of .wrap without needing a wrapper element */
.ground {
  background: var(--color-accent-900);
  color: var(--color-neutral-200);
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--edge), calc((100vw - 1200px) / 2 + var(--edge)));
  padding-block: calc(3.5 * var(--leading));
  position: relative; overflow: hidden;
}
.ground::before { /* drafting grid, barely there */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, color-mix(in srgb, #fff 4%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, #fff 4%, transparent) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 30%, transparent 100%);
}
.ground > * { position: relative; }
.ground .kicker { color: var(--color-accent-300); }
.ground .caption-rule { background: color-mix(in srgb, #fff 20%, transparent); }
.ground h2, .ground h3 { color: #fff; }
.ground .corner { color: color-mix(in srgb, #fff 45%, transparent); }

/* the source's heading pair */
.sec-head { max-width: var(--measure); }
.sec-head h2 {
  font-size: clamp(30px, 3.6vw, 46px); line-height: 1.06;
  text-transform: uppercase; letter-spacing: 0.01em;
  margin: 0 0 var(--half); margin-left: -0.04em;
  text-box: trim-both cap alphabetic;
}
.sec-head p { font-size: 16px; line-height: var(--leading); margin: 0;
  color: color-mix(in srgb, currentColor 82%, transparent); }

/* two-up on the dark ground */
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: calc(2.4 * var(--leading));
  align-items: center; }
@media (max-width: 900px) { .duo { grid-template-columns: 1fr; } }

/* figure shell */
.fig { margin-top: calc(2 * var(--leading)); }
.fig svg { display: block; width: 100%; height: auto; }
.fig figcaption { font-size: 13px; line-height: var(--half); margin-top: var(--space-4);
  color: color-mix(in srgb, currentColor 62%, transparent); max-width: var(--measure); }

/* the section rises into view as it is scrolled to. A scroll-driven timeline,
   so where view() is unsupported the shorthand carries no duration, the fill
   applies the end state immediately and the section is simply visible. */
.reveal { animation: rt-rise linear both; animation-timeline: view();
          animation-range: entry 0% entry 55%; }
@keyframes rt-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* the connectors march, so the diagram reads as flow rather than plumbing */
.flow-dash { stroke-dasharray: 5 7; animation: rt-flow 1.1s linear infinite; }
@keyframes rt-flow { to { stroke-dashoffset: -12; } }

/* Not in the source: the marching dashes loop forever, which is exactly what
   a reader who asked the OS for less motion does not want. The diagram keeps
   its dashed connectors, they just stop moving. */
@media (prefers-reduced-motion: reduce) {
  .reveal { animation: none; }
  .flow-dash { animation: none; }
}

/* — print —
   Browsers drop background graphics from print by default; the setting is the
   "Background graphics" checkbox, off unless the reader finds it. Every picture
   on this page is painted as a background — the hero, the deployment plate, the
   clinical portrait — so a default print loses all of them, and the duotone
   grounds go white. print-color-adjust: exact tells the browser to render them
   as authored instead.

   The drawn objects are kept off page seams: a registration-marked frame split
   across two sheets reads as a printing fault rather than a design. */
@media print {
  html {
    -webkit-print-color-adjust: exact;
            print-color-adjust: exact;
  }
  *, *::before, *::after {
    -webkit-print-color-adjust: exact;
            print-color-adjust: exact;
  }
  @page { margin: 12mm; }
  .cell-frame, .plate, .quote-art, .split-figure, .quote figure {
    break-inside: avoid;
  }
  .kicker { break-after: avoid; }      /* a section label never ends a sheet */
  .caption-rule { break-after: avoid; }
}

/* Review aid: the 24px rhythm drawn as hairlines — debug chrome, toggled by
   ?baselines or the B key, never part of the look. */
body[data-baselines] { position: relative; }
body[data-baselines]::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    repeating-linear-gradient(to bottom,
      color-mix(in srgb, var(--color-accent) 35%, transparent) 0 1px,
      transparent 1px var(--leading)),
    repeating-linear-gradient(to bottom,
      transparent 0 var(--half),
      color-mix(in srgb, var(--color-accent) 16%, transparent) var(--half) calc(var(--half) + 1px),
      transparent calc(var(--half) + 1px) var(--leading));
}

/* — landing additions: bio paragraph under the pull quote, footer legal line — */
.quote figure { margin: 0; }
.quote .bio { font-size: 15px; line-height: var(--leading); max-width: var(--measure);
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  margin: calc(1.5 * var(--leading) - 1cap) 0 0; text-box: trim-both cap alphabetic; }
footer .legal { display: block; margin-top: var(--half); max-width: var(--measure); }

/* — 4-up variant of the feature cells (the workflow runs to four steps) —
   .cells.cells-4 (0,2,0) so the base sheet's later @media .cells rules
   (0,1,0) cannot silently win the cascade back. */
.cells.cells-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1080px) { .cells.cells-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 880px)  { .cells.cells-4 { grid-template-columns: 1fr; } }
