/* ASH & Partners. One stylesheet.
   Every colour, size and spacing value is a named token from the knowledge file. A value outside
   the system does not exist, and the build fails on a colour literal below the token banner. */

:root {
  /* Palette. Contrast machine checked on paper: ink 15.1:1, ink-soft 7.2:1, oxblood 11.1:1,
     label 5.9:1. Brass is for hairlines and marks only, never text on paper. Green is banned. */
  --paper: #FAF7F0;
  --paper-deep: #F1EBDE;
  --ink: #26201A;
  --ink-soft: #5A5240;
  --oxblood: #63202C;
  --brass: #A07D3B;
  --night: #191410;
  --night-accent: #A84B60;
  --label: #6A5F4B;
  --night-label: #8F8471;

  /* Type. Display weights run 460 to 500 and never heavier. The wordmark is a separately locked
     spec at 520 with 0.14em tracking: it is not display type, so do not pull it into that range. */
  --type-display: clamp(40px, 6.2vw, 84px);
  --leading-display: 1.04;
  --type-h2: clamp(24px, 2.6vw, 36px);
  --type-body: 17.5px;
  --leading-body: 1.62;
  --type-label: 11.5px;
  --tracking-label: 0.08em;
  --tracking-wordmark: 0.14em;
  --weight-display: 470;
  --weight-body: 420;
  --weight-wordmark: 520;

  /* Space. */
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 40px;
  --space-5: 64px;
  --space-6: 104px;

  /* Hairline: 1 px ink at 20 percent, per the knowledge file. Both halves are tokens, so no
     bare length appears below the banner. */
  --rule: color-mix(in srgb, var(--ink) 20%, transparent);
  --hairline: 1px;
  --radius: 2px;

  /* Motion. One entrance per surface, then stillness. */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --enter: 700ms;
  --stagger: 70ms;

  /* ----------------------------------------------------------------------------------------
     Chrome and hero scale, SPEC-002.

     These values are transcribed from brand/ash-hero-proof-v4.html, the surface that was judged
     against the Tink and Dustin slides and survived. That judgement outranks a scale written
     before the judgement rounds, so the proof's measured values are named here rather than
     re-invented. REPORT-002 carries this group as the delta the founder folds into the knowledge
     file's Tokens section at its next regeneration; until then this block and that report are the
     record.

     Transcription is not laundering. Values in the proof that break an explicit law rather than a
     scale number are corrected and reported as defects, not minted here: its 800 ms entrance and
     90 ms stagger against the recorded 700 and 70, its standfirst opacity against palette
     membership, and its focus ring and mark cut. REPORT-002 lists all of them.
     ---------------------------------------------------------------------------------------- */

  /* The masthead lockup and navigation, shared by the masthead so the chrome stays one thing. */
  --type-wordmark: 15px;
  --type-nav: 11px;
  --nav-pad-y: 4px;
  --nav-gap: clamp(14px, 2.2vw, 28px);
  --lockup-gap: 11px;
  --lockup-mark-width: 20px;
  --lockup-mark-height: 27px;
  --bar-pad-bottom: 14px;

  /* The night hero. Its three rows are the masthead, the stage and the edge labels. */
  --hero-pad-top: 20px;
  --hero-pad-x: clamp(18px, 3.6vw, 52px);
  --hero-pad-bottom: 16px;
  --hero-row-gap: 6px;
  --type-hero-display: clamp(34px, min(5.5vw, 8.4svh), 86px);
  --tracking-hero-display: -0.012em;
  --type-hero-standfirst: clamp(14.5px, 1.15vw, 17px);
  --leading-hero-standfirst: 1.55;
  --type-hero-cta: 16.5px;
  --hero-cta-pad-bottom: 5px;
  --type-edge: 10.5px;
  --edge-gap: 14px;
  /* The chrome leading. Body sets 17.5 at 1.62 for reading; the edge labels and the call to action
     are not read that way and the proof leaves them at the initial leading, so the absence is named
     here rather than left to inheritance. */
  --leading-chrome: normal;
  /* The statement measure. The proof caps at 580 px, and that cap is what broke the headline at
     1680: "Compliance advisory" sets 634.2 px at the 75.6 px display size there, so 580 forced a
     third line and left "Compliance" standing alone.

     760 is solved, not chosen. The first line is 8.389 times the display size, the display size in
     this scope tops out at 86 px, so the widest that line can ever be is 721.5 px. 760 clears that
     by five percent, which is the room a browser upgrade needs when it re-rasterises the face.
     Wherever the display size is driven by width rather than height the 48vw term already exceeds
     the first line, 0.4614W against 0.48W, so the cap is the only thing that can bind, and now it
     does not. The laptop scope keeps the proof's 580, because the amendment did not reach it. */
  --hero-copy-max: min(48vw, 760px);
  --hero-copy-pad-bottom: clamp(8px, 2.5svh, 28px);
  --hero-stand-gap: min(3svh, 24px);
  --hero-cta-gap: min(3.4svh, 26px);
  --hero-stand-max: 32em;

  /* The monumental mark. Height drives the cut: see the cut law block far below. */
  --mark-hero-height: min(78svh, 54vw);
  --mark-hero-right: 1vw;
  --mark-hero-margin: 1svh;
  --stroke-monumental: 0.65;
  --stroke-standard: 2.1;

  /* Secondary text on the night canvas. The proof reached it with opacity, which mints a value
     outside the palette; this derives it from two palette members, the same mechanism --rule
     already uses. Measured 12.1:1 on night. Flagged in REPORT-002 for the founder's ruling. */
  --night-soft: color-mix(in srgb, var(--paper) 86%, var(--night));

  /* ----------------------------------------------------------------------------------------
     The Careers strip, redo-1. The single page carries one body strip, so this group is what is
     left of the Home body grid after the retired strips took their tokens with them. Each value
     was already in the system and nothing new is minted.

     The strip's opening line takes the hero headline's own tokens (--type-hero-display,
     --tracking-hero-display), so no display size of its own exists. --measure-body is the 60ch the
     body has always read at. --strip-gap-y is the strip's vertical rhythm, --space-6.
     --type-strip-link is one step, +2px, above body size. */
  --measure-body: 60ch;
  --strip-gap-y: var(--space-6);
  --type-strip-link: 19.5px;
}

/* --- END TOKENS: nothing below this line invents a value --- */

/* Self hosted, from /brand/fonts, per the CLAUDE.md law. No third party request is ever made.
   The url() values are quoted because SourceCodePro[wght].ttf carries square brackets, which are
   not valid in an unquoted CSS url().

   font-display is block, not swap. With swap the hero lays out once on fallback metrics and again
   when the real face lands, so a hero that fits before the swap and overflows after would either
   flake the viewport harness or pass a layout that is broken for real visitors. block gives one
   layout, which is what makes document.fonts.ready a true settle signal. */
@font-face {
  font-family: 'Source Serif 4';
  src: url('/brand/fonts/web/SourceSerif4Variable-Roman.ttf') format('truetype');
  font-weight: 200 900;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: 'Source Serif 4';
  src: url('/brand/fonts/web/SourceSerif4Variable-Italic.ttf') format('truetype');
  font-weight: 200 900;
  font-style: italic;
  font-display: block;
}

@font-face {
  font-family: 'Source Code Pro';
  src: url('/brand/fonts/web/SourceCodePro[wght].ttf') format('truetype');
  font-weight: 200 900;
  font-style: normal;
  font-display: block;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'Source Serif 4', serif;
  font-size: var(--type-body);
  font-weight: var(--weight-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--brass);
  color: var(--paper);
}

:focus-visible {
  outline: var(--radius) solid var(--oxblood);
  outline-offset: var(--space-1);
}

a {
  color: inherit;
  text-decoration: none;
}

/* Hairline underlines that draw in on hover. Micro craft, per the quality bar. */
a.link {
  background-image: linear-gradient(var(--ink), var(--ink));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 var(--hairline);
  transition: background-size var(--enter) var(--ease);
}

a.link:hover,
a.link:focus-visible {
  background-size: 100% var(--hairline);
}

/* The wordmark, per its locked spec: small capitals, 0.14em, weight 520, and the italic ampersand
   as the single flourish. The ampersand is the flourish, so it carries no tracking of its own. */
.wordmark {
  /* font-variant-caps alone. An explicit font-feature-settings would have to name c2sc as well,
     because the source text is uppercase, and it resolves at a higher priority than the shorthand
     it was meant to support. */
  font-variant-caps: all-small-caps;
  font-weight: var(--weight-wordmark);
  font-size: var(--type-wordmark);
  letter-spacing: var(--tracking-wordmark);
}

.wordmark i {
  font-style: italic;
  letter-spacing: normal;
}

.label {
  font-family: 'Source Code Pro', monospace;
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--label);
}

/* The mark. Inlined by the build from /brand/mark, so its path data is the kit's by construction.
   stroke="currentColor" is what makes the colour law hold without a rule: ink on paper, paper on
   night, because it inherits the canvas's own text colour. */
.mark {
  display: block;
}

.shell {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

/* The fold is the hero box the viewport law measures, and it is the first viewport exactly. The
   shared footer sits below it in normal flow, which is the locked page anatomy: the law protects
   the hero, and the legal footer belongs under it. */
.fold {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  padding: var(--space-3);
  gap: var(--space-4);
}

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  border-bottom: var(--hairline) solid var(--rule);
  padding-bottom: var(--bar-pad-bottom);
}

.lockup {
  display: flex;
  align-items: center;
  gap: var(--lockup-gap);
}

.lockup .mark {
  width: var(--lockup-mark-width);
  height: var(--lockup-mark-height);
}

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--nav-gap);
}

.nav a {
  font-family: 'Source Code Pro', monospace;
  font-size: var(--type-nav);
  letter-spacing: var(--tracking-label);
  color: var(--label);
  padding: var(--nav-pad-y) 0;
}

/* The Careers strip, the single page's one body section: paper canvas by default, since nothing here
   sets one, padded to --hero-pad-x so it spans exactly the content width the hero above it spans.
   No .enter class anywhere below: the fold's entrance is the page's one choreography, and this is
   the still, settled surface under it. No rule or hairline stands anywhere inside it: the roles are
   separated by space alone. The footer's own hairline, the locked footer anatomy, is the only line
   below the hero.

   The head is one column: the label, the display, and the body directly under the display,
   left-aligned with it. The label sits --space-2 above the display, the body --space-3 below it.
   The roles stand --space-6 below the head, the strip's own rhythm. */
.careers {
  display: flex;
  flex-direction: column;
  gap: var(--strip-gap-y);
  padding: var(--strip-gap-y) var(--hero-pad-x);
}

.careers p,
.careers h2,
.careers h3 {
  margin: 0;
}

.careers-intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.careers-intro .label {
  margin-bottom: calc(var(--space-2) - var(--space-3));
}

/* The strip's opening line sets at exactly the hero headline's type: the hero's size, tracking,
   weight and leading, by the hero's own tokens. It stays an h2 in the document. */
.section-display {
  font-size: var(--type-hero-display);
  line-height: var(--leading-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-hero-display);
}

.section-body {
  max-width: var(--measure-body);
}

/* The open roles: five entries of equal weight, none crowned, in a two column grid above 820 and one
   column at 820 and below. Equal columns, --space-5 between them and --space-6 between rows, so five
   roles read as rows of two with the fifth alone in the left column, in the order of the knowledge
   file. minmax(0, 1fr) keeps a long unbroken word from widening its column past its twin. */
.roles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-5);
  row-gap: var(--space-6);
}

/* Each role is one stacked column: title, seat line, first paragraph, second paragraph, apply link,
   gapped at --space-2. The seat line belongs to the title above it, so it is pulled up to --space-1
   under it, the same step the title once held it at. Nothing sits beside the title. */
.role {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.role .label {
  margin-top: calc(var(--space-1) - var(--space-2));
}

.role-title {
  font-size: var(--type-h2);
  line-height: var(--leading-display);
  font-weight: var(--weight-display);
}

/* The strip link: oxblood on paper at its own size, so it reads as an object in its own right
   rather than running body text that happens to be a link. The underline mechanism is a.link's own
   hairline that draws in on hover; only its colour follows the text here, the same way the night
   canvas already recolours it to brass. */
.strip-link {
  color: var(--oxblood);
  font-size: var(--type-strip-link);
}

.strip-link.link {
  background-image: linear-gradient(var(--oxblood), var(--oxblood));
}

/* At 820 and below the roles stand in one column, the same threshold the hero already turns on. */
@media (width <= 820px) {
  .roles {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The footer, redo-1: the lockup, then the legal block carrying the address, the general address and
   the privacy statement. No navigation row: the site is one page and the masthead's single item is
   the only navigation. No .enter anywhere in it: it is never visible during the fold's own
   entrance, so animating it said nothing a visitor could see. */
.colophon {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  border-top: var(--hairline) solid var(--rule);
  padding: var(--space-4) var(--hero-pad-x);
}

.legal-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.legal-block p {
  margin: 0;
}

/* The privacy statement is a sentence, not a label, so it keeps sentence case and is not set in
   capitals; it shares the labels' face, size and colour so it reads as part of the legal block. */
.legal-block .legal-statement {
  max-width: var(--measure-body);
  padding-top: var(--space-2);
  font-family: 'Source Code Pro', monospace;
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  color: var(--label);
}

/* LinkedIn and X, v1.2: the one named exception to the external-marks law, recorded in CLAUDE.md.
   Monochrome glyphs only, ink at rest so they read as part of the legal block rather than as a
   brand appearance, oxblood on hover and focus to match the strip link's own colour law. Sized to
   the mono label's own type size, so the row reads as part of the legal block's scale rather than
   as a new one. Focus is the sitewide :focus-visible ring; nothing here suppresses or replaces it. */
.social-row {
  display: flex;
  gap: var(--space-2);
}

.social-link {
  display: inline-flex;
  width: var(--type-label);
  height: var(--type-label);
  color: var(--ink);
}

.social-link svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.social-link:hover,
.social-link:focus-visible {
  color: var(--oxblood);
}

/* ============================================================================================
   The night hero. One room per page, per the colour budget. Geometry transcribed from the proof.
   ============================================================================================ */

.fold[data-canvas='night'] {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  padding: var(--hero-pad-top) var(--hero-pad-x) var(--hero-pad-bottom);
  gap: var(--hero-row-gap);
  background: var(--night);
  color: var(--paper);
}

/* Ink at 20 percent is invisible on night, and brass is the rule colour the identity allows. */
.fold[data-canvas='night'] .masthead {
  border-bottom-color: var(--brass);
}

/* Oxblood on night measures 1.55:1, so it cannot serve as a focus indicator there. Brass measures
   4.78:1. Recorded in REPORT-002 as a defect the shipped stylesheet carried into the night canvas. */
.fold[data-canvas='night'] :focus-visible {
  outline-color: var(--brass);
}

/* The edge labels carry their own colour and the navigation carries this one. A .label inside a
   night fold would need it too, and there is none today, so the rule is not written for a case
   that does not exist. REPORT-002 records that --label measures 2.92:1 on night, which is the
   answer the next night surface needs. */
.fold[data-canvas='night'] .nav a {
  color: var(--night-label);
}

.fold[data-canvas='night'] .nav a:hover,
.fold[data-canvas='night'] .nav a:focus-visible {
  color: var(--paper);
}

.fold[data-canvas='night'] a.link {
  background-image: linear-gradient(var(--brass), var(--brass));
}

.stage {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 0;
}

/* The statement is bottom anchored, which is why the corrected headline changes its own height and
   nothing below it: the block grows upward from a fixed baseline. */
.statement {
  position: relative;
  z-index: 2;
  max-width: var(--hero-copy-max);
  padding-bottom: var(--hero-copy-pad-bottom);
}

.hero-display {
  margin: 0;
  font-size: var(--type-hero-display);
  line-height: var(--leading-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-hero-display);
  /* The line breaks are a copy decision, and the copy law forbids putting markup or characters
     inside the locked string to force them. balance is the lever that stays outside the words: it
     evens the lines instead of filling the first one, which is what stops a line ending on "with"
     at 1280, where both greedy wrapping and pretty do. tools/line-breaks.mjs asserts the result at
     every verified width, because a wrap rule is a request and only the measurement is the answer. */
  text-wrap: balance;
  overflow-wrap: break-word;
}

.hero-standfirst {
  margin: var(--hero-stand-gap) 0 0;
  font-size: var(--type-hero-standfirst);
  line-height: var(--leading-hero-standfirst);
  font-weight: var(--weight-body);
  max-width: var(--hero-stand-max);
  /* Measured as a no-op at all three verified widths: identical lines, identical box, so it costs
     criterion 4 nothing. It is here for the widths nobody verifies, where it keeps a single word
     off the last line. */
  text-wrap: pretty;
  color: var(--night-soft);
}

.hero-cta {
  display: inline-block;
  margin-top: var(--hero-cta-gap);
  font-size: var(--type-hero-cta);
  line-height: var(--leading-chrome);
  padding-bottom: var(--hero-cta-pad-bottom);
}

.mark-monumental {
  position: absolute;
  right: var(--mark-hero-right);
  top: 50%;
  transform: translateY(-50%);
  height: var(--mark-hero-height);
  aspect-ratio: 24 / 32;
  z-index: 1;
  pointer-events: none;
}

.edge {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--edge-gap);
  margin: 0;
  font-family: 'Source Code Pro', monospace;
  font-size: var(--type-edge);
  line-height: var(--leading-chrome);
  letter-spacing: var(--tracking-label);
  color: var(--night-label);
}

/* The proof's two breakpoints, redefining the tokens rather than minting variants, which is what
   the proof itself does. A short laptop needs a height aware display size or the hero cannot obey
   the viewport law; that is the mechanism the page scale lacks.

   Written in range syntax, not as max-width 820 against min-width 821. Those two do not tile the
   line: a viewport width is fractional under browser zoom, so 820.8 px falls through both and the
   page would silently take neither regime. */
/* The display size is declared once per regime for the hero and the Careers strip together, because
   the strip's opening line sets at exactly the hero headline's size and the strip sits outside the
   fold, so it would otherwise read the root value in every regime. One declaration, two selectors:
   nothing is copied and nothing new is minted. */
@media (width > 820px) and (height <= 740px) {
  .fold[data-canvas='night'],
  .careers {
    --type-hero-display: min(5vw, 7.6svh);
  }

  .fold[data-canvas='night'] {
    --mark-hero-height: min(72svh, 50vw);
    --hero-stand-gap: 2svh;
    /* The proof's measure, kept. In this scope the display size cannot exceed 56.24 px, so the
       first line cannot exceed 471.8 px and 580 was never the constraint here. */
    --hero-copy-max: min(48vw, 580px);
  }
}

@media (width <= 820px) {
  .fold[data-canvas='night'],
  .careers {
    --type-hero-display: clamp(27px, min(10vw, 4.9svh), 46px);
  }

  .fold[data-canvas='night'] {
    --type-hero-standfirst: 14.5px;
    --hero-stand-gap: 2svh;
    --hero-cta-gap: 2.4svh;
    --type-hero-cta: 15.5px;
    --hero-copy-max: 100%;
    --hero-stand-max: 36em;
    --mark-hero-height: min(30svh, 58vw);
    --nav-gap: 14px;
  }

  .fold[data-canvas='night'] .stage {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
  }

  .fold[data-canvas='night'] .mark-monumental {
    position: static;
    transform: none;
    align-self: center;
    margin: var(--mark-hero-margin) auto;
  }
}

@media (height <= 600px) and (width <= 820px) {
  .fold[data-canvas='night'],
  .careers {
    --type-hero-display: min(9vw, 4.6svh);
  }

  .fold[data-canvas='night'] {
    --mark-hero-height: 24svh;
  }
}

/* --------------------------------------------------------------------------------------------
   The cut law, applied by rendered size rather than by eye.

   The cut follows rendered height: micro 14 to 23 px, standard 24 to 200 px, monumental above
   200 px. The inline mark carries the canonical path data in every case; only the stroke changes,
   because that is what a cut is.

   The three thresholds below are solved from the sizing expressions, not chosen, and each is
   stated to four decimals so the band where the query and the true crossover disagree is far below
   any reachable viewport:

     width <= 820      mark is min(30svh, 58vw); 58vw crosses 200 at 344.8276 px wide,
                       30svh crosses 200 at 666.6667 px tall. Either one below means standard.
                       The 24svh regime under height <= 600 is at most 144 px, always standard,
                       and always inside the second clause.
     width > 820,
       height <= 740   mark is min(72svh, 50vw); 50vw exceeds 410 px here, so only height
                       decides, and 72svh crosses 200 at 277.7778 px tall.
     width > 820,
       height > 740    mark is min(78svh, 54vw); 78svh is already above 577 px, so this regime
                       is monumental everywhere and needs no clause.

   At 360 x 640 the mark renders at 192 px, inside the standard cut, so the standard stroke applies
   there. The judged proof renders the monumental stroke at that size, which is a breach of its own
   law; REPORT-002 records it, and the harness asserts the table at every verified width and at six
   viewports chosen either side of these thresholds, so it cannot recur.
   -------------------------------------------------------------------------------------------- */
.mark-monumental path {
  stroke-width: var(--stroke-monumental);
}

@media (width < 344.8276px),
  (width <= 820px) and (height < 666.6667px),
  (width > 820px) and (height < 277.7778px) {
  .mark-monumental path {
    stroke-width: var(--stroke-standard);
  }
}

/* One entrance per surface, then stillness. The default state, with no JavaScript and no attribute,
   is fully visible and still, so nothing is ever hidden from a visitor whose script did not run. */
[data-entrance='arm'] .enter {
  opacity: 0;
}

[data-entrance='run'] .enter {
  animation: rise var(--enter) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(var(--space-2));
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* The mark's draw in, the one living motion in the identity, and part of the same single entrance.
   The dash offset is set only while the entrance attribute exists, so a visitor with no JavaScript
   sees the mark whole rather than an empty box. pathLength is injected by the build, so 100 is the
   whole of every stroke and one duration draws them all at the same rate. */
[data-entrance] .mark-monumental path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}

[data-entrance='run'] .mark-monumental path {
  animation: draw var(--enter) var(--ease) forwards;
}

[data-entrance='run'] .mark-monumental path:nth-child(1) {
  animation-delay: calc(1 * var(--stagger));
}

[data-entrance='run'] .mark-monumental path:nth-child(2),
[data-entrance='run'] .mark-monumental path:nth-child(3) {
  animation-delay: calc(2 * var(--stagger));
}

[data-entrance='run'] .mark-monumental path:nth-child(4),
[data-entrance='run'] .mark-monumental path:nth-child(5) {
  animation-delay: calc(3 * var(--stagger));
}

[data-entrance='run'] .mark-monumental path:nth-child(6),
[data-entrance='run'] .mark-monumental path:nth-child(7) {
  animation-delay: calc(4 * var(--stagger));
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* The static state, stated plainly: it is the settled composition, and that is a choice rather than
   an accident. The hero is a still surface whose entrance carries no information the settled frame
   does not, so a different static state would be a different design shown to one group of visitors.
   The head script never arms the entrance under reduced motion, so these rules are the second guard
   rather than the only one, and check asserts that the two states are identical. */
@media (prefers-reduced-motion: reduce) {
  [data-entrance] .enter {
    opacity: 1;
    animation: none;
  }

  [data-entrance] .mark-monumental path {
    animation: none;
    stroke-dashoffset: 0;
  }

  a.link {
    transition: none;
  }
}
