/* ==========================================================================
   DEKALOS — site styles

   Palette is Sarah's three Pantone chips and nothing else:
     Mystic Navy      #13273F   all type, all rules
     Mother of Pearl  #E9D4C3   the single page background, as a pale tint
     Red Inferno      #4E0000   used sparingly, for figures that matter

   Red Inferno is very dark, near-black rather than bright red, so it only ever
   sits on the pale ground. It marks single numbers and the button, nothing else.

   ONE BACKGROUND. Every section is --paper. No alternating bands, no dark
   sections, no panels with their own fill. Structure comes from hairline rules,
   borders and whitespace, which is how print does it.

   Type is Source Serif 4 (display) over Libre Franklin (body, Franklin Gothic
   revival). Both SIL Open Font License, both free.

   Source Serif replaced Bodoni Moda: a didone's hairlines get very thin at
   headline size, which reads fragile rather than expensive. Source Serif holds
   an even stroke at any size, so headings look solid. It also carries an optical
   size axis, which is why headings set weight 600 and stay crisp.

   No shadows, no gradients, no rounded cards. Structure comes from hairline
   rules and whitespace, which is how print does it.
   ========================================================================== */

/* ------------------------------------------------------------------ tokens */
:root {
  --navy:        #13273F;
  --cream:       #E9D4C3;
  --oxblood:     #4E0000;

  /* One background for the entire page. A tint of Mother of Pearl, so the page
     reads warm rather than white. Nothing else is ever a background colour —
     sections are separated by rules and whitespace only. */
  --paper:       #F8F3ED;

  --ink:         var(--navy);
  --ink-soft:    #4F6076;
  --rule:        rgba(19, 39, 63, 0.16);
  --rule-strong: rgba(19, 39, 63, 0.38);

  --display: "Source Serif 4", "Charter", "Iowan Old Style", Georgia, serif;
  --body:    "Libre Franklin", "Helvetica Neue", Arial, sans-serif;

  --measure: 34rem;      /* prose column, roughly 66 characters */
  --wrap:    72rem;
  --gutter:  clamp(1.25rem, 5vw, 4rem);
}

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

/* Anchor jumps glide instead of teleporting, which on a page this long is the
   difference between "where did I land" and reading on. The scroll padding is
   there because the masthead is sticky: without it a nav link would park the
   heading underneath the bar. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  font-weight: 350;
  line-height: 1.65;
  font-feature-settings: "kern" 1, "liga" 1;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, p, dl, dd, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; }

img { max-width: 100%; display: block; }

/* Figures line up in columns everywhere they appear */
.num, .bignum__value, .tier__amount, table { font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------- interactions */
a { color: inherit; }

a:focus-visible,
.skip:focus-visible {
  outline: 2px solid var(--oxblood);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--navy);
  color: var(--cream);
  padding: 0.75rem 1.25rem;
  text-decoration: none;
}
.skip:focus { left: 0; }

/* Anyone who has asked their system for less movement gets none of it. Written
   with !important and listed explicitly rather than trusting cascade order,
   because the failure mode here is content stranded mid-animation and therefore
   invisible. Belt and braces is the right call when the downside is a blank page. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }

  html { scroll-behavior: auto; }

  .hero__body > *,
  .hero__figure,
  .band .eyebrow,
  .band .h2,
  .band .h3,
  .band .prose,
  .band .table-frame,
  .band .spotlight,
  .band .checklist,
  .band .tier,
  .band .pillars li,
  .band .method li {
    opacity: 1 !important;
    transform: none !important;
  }

  .band .table-frame::before,
  .band .checklist::before { transform: scaleX(1) !important; }

  .masthead { border-bottom-color: var(--rule) !important; }
}

/* ---------------------------------------------------------------- scaffold */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band {
  padding-block: clamp(3.5rem, 8vw, 7rem);
  border-top: 1px solid var(--rule);
}

/* No background variants by design — see the note at the top of this file. */

/* ---------------------------------------------------------------- masthead */
/* Stays with the reader down a long page so the section links are always in
   reach. The paper fill is opaque on purpose — no blur, no shadow, no
   transparency. It is a printed header that happens to follow you, and the
   existing hairline is all the separation it needs. */
.masthead {
  border-bottom: 1px solid var(--rule);
  padding-block: 1.5rem;
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--paper);
}

.masthead__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
}

.wordmark {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
  /* the letterspacing adds a trailing gap; pull it back so the rule aligns */
  padding-right: 0.2em;
}

.wordmark__rule {
  display: block;
  height: 2px;
  background: var(--oxblood);
  margin-top: 0.5rem;
}

.nav {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.nav a {
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: border-color 140ms ease;
}
.nav a:hover { border-bottom-color: var(--rule-strong); }

.nav__cta {
  color: var(--oxblood);
  font-weight: 600;
  border-bottom: 1px solid var(--oxblood) !important;
}

/* --------------------------------------------------------------- typography */
.display {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(2.5rem, 1.4rem + 4.4vw, 4.25rem);
  line-height: 1.08;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

.h2 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.75rem, 1.2rem + 2.1vw, 2.625rem);
  line-height: 1.16;
  letter-spacing: -0.014em;
  margin-top: 0.75rem;
  max-width: 30ch;
  text-wrap: balance;
}

.h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.625rem);
  line-height: 1.24;
  margin-top: 3.5rem;
  margin-bottom: 1.25rem;
}

.h4 {
  font-family: var(--body);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: 1rem;
}

.eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--oxblood);
  margin: 0;
}

.lede {
  max-width: var(--measure);
  font-size: 1.125rem;
  line-height: 1.6;
  margin-top: 1.5rem;
}

.prose { max-width: var(--measure); }
.prose--wide { max-width: 48rem; margin-top: 1.5rem; }
.prose p + p { margin-top: 1rem; }

.muted     { color: var(--ink-soft); font-weight: 350; }
.microcopy { font-size: 0.8125rem; line-height: 1.5; color: var(--ink-soft); margin-top: 1.25rem; }
.footnote  { font-size: 0.9375rem; color: var(--ink-soft); }

.callout {
  border-left: 2px solid var(--oxblood);
  padding-left: 1.5rem;
  margin-top: 2.5rem;
}

.cols {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  margin-top: 2.5rem;
}
@media (min-width: 48rem) {
  .cols { grid-template-columns: 1fr 1fr; }
}

/* ------------------------------------------------------------------ buttons */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
  margin-top: 2.25rem;
}

.btn {
  display: inline-block;
  background: var(--oxblood);
  color: var(--paper);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 1rem 2rem;
  border: 1px solid var(--oxblood);
  transition: background 140ms ease, color 140ms ease;
}
.btn:hover { background: transparent; color: var(--oxblood); }

.link-quiet {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
  padding-bottom: 2px;
}
.link-quiet:hover { border-bottom-color: var(--oxblood); }

/* --------------------------------------------------------------------- hero */
.hero { padding-block: clamp(3rem, 7vw, 6rem); }

.hero__grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: start;
}
@media (min-width: 62rem) {
  .hero__grid { grid-template-columns: 1.15fr 0.85fr; }
}

/* Sits on the same ground as everything else. It reads as a panel because of the
   border and the heavy oxblood rule on top, not because of a fill. */
.hero__figure {
  padding: clamp(1.75rem, 4vw, 2.5rem);
  border: 1px solid var(--rule-strong);
  border-top: 3px solid var(--oxblood);
}

.bignum { margin-top: 1.75rem; }

.bignum__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1rem;
  border-bottom: 1px solid var(--rule);
}

.bignum dt {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  max-width: 14ch;
  color: var(--ink-soft);
}

.bignum__value {
  font-family: var(--display);
  font-size: clamp(2rem, 1.4rem + 2.2vw, 2.75rem);
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
}
/* Colour never carries the meaning on its own here — the row label says which
   number is the problem. This just draws the eye to it first. */
.bignum__value--bad { color: var(--oxblood); }

.hero__figure-note {
  margin-top: 1.5rem;
  font-size: 0.9375rem;
  line-height: 1.55;
}
.hero__figure-note strong { color: var(--oxblood); }

.hero__figure .microcopy {
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
}

/* -------------------------------------------------------------------- table */
.table-frame {
  margin-top: 2.5rem;
  border-top: 2px solid var(--navy);
  overflow-x: auto;
}

.ledger {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.ledger caption {
  caption-side: bottom;
  text-align: left;
  font-size: 0.8125rem;
  color: var(--ink-soft);
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}

.ledger th,
.ledger td {
  text-align: left;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--rule);
  vertical-align: baseline;
}
.ledger th:first-child, .ledger td:first-child { padding-left: 0; }
.ledger th:last-child,  .ledger td:last-child  { padding-right: 0; }

.ledger th[scope="row"] { font-weight: 350; }

.ledger thead th {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-bottom-color: var(--rule-strong);
}

.ledger .num { text-align: right; white-space: nowrap; }

.ledger__total th,
.ledger__total td {
  font-weight: 600;
  color: var(--oxblood);
}
.ledger__total:first-of-type th,
.ledger__total:first-of-type td { border-top: 1px solid var(--rule-strong); }

/* A credit reduces the bill, so it is signed and set apart from the charges it
   offsets. The minus sign carries the meaning; the colour only reinforces it. */
.credit { color: var(--oxblood); }

/* Pointer from a table row to the terms that qualify it. Small, but it has to be
   a real link — the row states a conditional number and the condition is not
   optional reading. */
.fnref {
  display: inline-block;
  margin-left: 0.5rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--oxblood);
  text-decoration: none;
  border-bottom: 1px solid var(--oxblood);
  white-space: nowrap;
}

.ledger--compare tbody tr:last-child th,
.ledger--compare tbody tr:last-child td { font-weight: 600; }

/* -------------------------------------------------------------------- tiers */
.tiers {
  display: grid;
  gap: 1.5rem;
  margin-top: 3rem;
}
@media (min-width: 48rem) {
  .tiers { grid-template-columns: 1fr 1fr; }
}

.tier {
  border: 1px solid var(--rule-strong);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  display: flex;
  flex-direction: column;
}

.tier--lead {
  border-color: var(--oxblood);
  border-top-width: 3px;
}

.tier__flag {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--oxblood);
  margin-bottom: 0.75rem;
}

.tier__name {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.1;
}

.tier__price {
  margin-top: 1rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
}

.tier__amount {
  font-family: var(--display);
  font-size: 2.75rem;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
  margin-right: 0.25rem;
}

.tier__rate {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9375rem;
}

/* --------------------------------------------------------------- spotlight */
/* The referral block. Given real weight because referral-at-finding is the whole
   growth mechanism, not a footnote — but built from the same parts as everything
   else: one background, a border, a heavy oxblood rule on top. */
.spotlight {
  margin-top: 3.5rem;
  border: 1px solid var(--rule-strong);
  border-top: 3px solid var(--oxblood);
  padding: clamp(1.75rem, 4vw, 2.75rem);
}

.spotlight__flag {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--oxblood);
  margin-bottom: 0.75rem;
}

.spotlight__heading {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.125rem);
  line-height: 1.16;
  letter-spacing: -0.012em;
  max-width: 28ch;
}

.spotlight__grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  margin-top: 1.75rem;
  align-items: start;
}
@media (min-width: 52rem) {
  .spotlight__grid { grid-template-columns: 1fr 1fr; }
}

.spotlight__lede {
  font-size: 1.0625rem;
  line-height: 1.6;
  max-width: 40ch;
}
.spotlight__lede strong { color: var(--oxblood); }

.spotlight__maths {
  margin-top: 1.75rem;
  border-top: 1px solid var(--rule);
}

.spotlight__maths > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 0.75rem;
  border-bottom: 1px solid var(--rule);
}

.spotlight__maths dt {
  font-size: 0.875rem;
  color: var(--ink-soft);
}

.spotlight__maths dd {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* The third row restates the second on purpose — the point is that they match. */
.spotlight__maths > div:last-child dd { color: var(--oxblood); }

.spotlight__note {
  margin-top: 1.5rem;
  font-size: 0.9375rem;
  line-height: 1.6;
}

.spotlight__terms {
  border-top: 2px solid var(--navy);
  padding-top: 1.5rem;
}

/* ------------------------------------------------------------------- lists */
.ticks {
  list-style: none;
  margin-top: 1.5rem;
  display: grid;
  gap: 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.5;
}

.ticks li {
  position: relative;
  padding-left: 1.5rem;
}

.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 0.5rem;
  height: 1px;
  background: var(--oxblood);
}

/* ------------------------------------------------------------------- method */
.method {
  list-style: none;
  counter-reset: step;
  margin-top: 2rem;
  display: grid;
  gap: 0;
}

.method li {
  counter-increment: step;
  display: grid;
  gap: 0.25rem 1.75rem;
  padding-block: 1.75rem;
  border-top: 1px solid var(--rule);
}
.method li:last-child { border-bottom: 1px solid var(--rule); }

@media (min-width: 44rem) {
  .method li { grid-template-columns: 3rem 1fr; }
}

.method li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--display);
  font-size: 1.25rem;
  color: var(--oxblood);
  line-height: 1.4;
}

.method h4 {
  font-family: var(--body);
  font-size: 1.0625rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.method p {
  color: var(--ink-soft);
  max-width: var(--measure);
  font-size: 0.9375rem;
  line-height: 1.6;
}

@media (min-width: 44rem) {
  .method li::before { grid-row: 1 / span 2; }
}

/* ------------------------------------------------------------------ pillars */
.pillars {
  list-style: none;
  display: grid;
  gap: 1px;
  margin-top: 3rem;
  background: var(--rule);
  border: 1px solid var(--rule);
}
@media (min-width: 40rem) { .pillars { grid-template-columns: 1fr 1fr; } }
@media (min-width: 64rem) { .pillars { grid-template-columns: repeat(4, 1fr); } }

.pillars li {
  background: var(--paper);
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
  display: flex;
  flex-direction: column;
}

.pillars h3 {
  font-family: var(--display);
  font-size: 1.1875rem;
  font-weight: 600;
  line-height: 1.15;
  margin-bottom: 0.75rem;
}

.pillars p {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.pillars__status {
  margin-top: auto;
  padding-top: 1.25rem;
  font-size: 0.6875rem !important;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft) !important;
}
.pillars__status--live { color: var(--oxblood) !important; }

/* ------------------------------------------------------------------ contact */
.contact {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  align-items: start;
}
@media (min-width: 56rem) {
  .contact { grid-template-columns: 1.1fr 0.9fr; }
}

.checklist {
  border-top: 2px solid var(--navy);
  padding-top: 1.5rem;
}

/* ------------------------------------------------------------------- footer */
.foot {
  border-top: 2px solid var(--navy);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

.foot__inner {
  display: grid;
  gap: 2rem;
  align-items: start;
}
@media (min-width: 56rem) {
  .foot__inner { grid-template-columns: auto 1fr; gap: 4rem; }
}

.foot__mark {
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1;
}

.foot__legal {
  font-size: 0.8125rem;
  line-height: 1.6;
  max-width: 52rem;
  color: var(--ink-soft);
}
.foot__legal p + p { margin-top: 1rem; }

/* ------------------------------------------------------------ hero entrance

   A plain time-based animation rather than a scroll-driven one, and that is the
   point: it runs in every browser regardless of scroll-timeline support, and the
   hero is the one thing every single visitor sees. The scroll effects below are
   an enhancement; this is the baseline.

   Staggered so the eye is led down the column — label, headline, explanation,
   action — instead of the whole screen arriving at once. 18px of travel, a
   decelerating curve, nothing overshoots or bounces.
   ------------------------------------------------------------------------- */
@keyframes lift-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

.hero__body > *,
.hero__figure {
  animation: lift-in 620ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.hero__body > .eyebrow      { animation-delay: 0ms; }
.hero__body > .display      { animation-delay: 80ms; }
.hero__body > .lede         { animation-delay: 160ms; }
.hero__body > .lede + .lede { animation-delay: 220ms; }
.hero__body > .actions      { animation-delay: 300ms; }
.hero__figure               { animation-delay: 240ms; }

/* ------------------------------------------------------- scroll-linked motion

   Driven by CSS alone. The site is served under a Content Security Policy of
   `default-src 'none'` with no script-src, so every script is blocked by design
   and that is worth keeping — a page asking strangers for financial documents is
   better off unable to execute code at all. `animation-timeline: view()` gives
   the effect with no script, no library and no build step.

   All of it sits inside @supports, so a browser without scroll-driven animation
   renders the page fully visible with the hero entrance above still intact.
   There is no state in which content is stuck invisible.

   Note the property order in every rule below: the `animation` shorthand resets
   `animation-timeline` to auto, so the timeline is always declared after it.
   Getting that backwards silently kills the whole effect.
   ------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {

  @keyframes rise-in {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: none; }
  }

  @keyframes draw-rule {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
  }

  @keyframes masthead-settle {
    from { border-bottom-color: var(--rule); }
    to   { border-bottom-color: var(--rule-strong); }
  }

  /* Block-level reveals. Each element is on its own timeline, so it arrives when
     it personally reaches the viewport — a natural stagger down the page with no
     hard-coded delays to re-tune when the markup changes.

     Containers whose children animate are deliberately absent: .tiers, .pillars
     and .method are not listed, because animating a parent and its children
     multiplies their opacities and the content reads dimmer than either fade
     intends. Nothing in .hero is listed either — it has its own entrance above.
     .foot is left alone; legal copy does not need an entrance. */
  .band .eyebrow,
  .band .h2,
  .band .h3,
  .band .prose,
  .band .table-frame,
  .band .spotlight,
  .band .checklist {
    animation: rise-in cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-timeline: view();
    animation-range: entry 15% entry 85%;
  }

  /* Grid children, staggered. Items sitting side by side share a scroll position,
     so without shifting their ranges they would all arrive together. Nudging each
     one further along the entry phase makes them cascade left to right, and that
     cascade is what reads as considered rather than automatic. */
  .band .tier,
  .band .pillars li,
  .band .method li {
    animation: rise-in cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-timeline: view();
    animation-range: entry 15% entry 85%;
  }

  .band .tier:nth-child(2),
  .band .pillars li:nth-child(2) { animation-range: entry 23% entry 93%; }
  .band .pillars li:nth-child(3) { animation-range: entry 31% entry 100%; }
  .band .pillars li:nth-child(4) { animation-range: entry 39% entry 100%; }

  /* Table rows are pointedly absent. A ledger that animates row by row reads as
     marketing, and the credibility of these figures rests on them looking like
     arithmetic. The table arrives as one block or not at all. */

  /* The print-derived flourish: the heavy navy rule above a table or the contact
     checklist draws itself left to right, echoing that the whole design is built
     out of rules. */
  .band .table-frame,
  .band .checklist {
    position: relative;
    border-top-color: transparent;
  }

  .band .table-frame::before,
  .band .checklist::before {
    content: "";
    position: absolute;
    left: 0;
    /* Drawn just inside the padding box rather than up in the border area.
       .table-frame sets overflow-x: auto, which makes it a scroll container, and
       a scroll container clips anything outside its padding box — a pseudo-element
       offset upward would vanish or force a stray scrollbar. The transparent
       border above keeps the 2px of layout space so nothing shifts. */
    top: 0;
    width: 100%;
    height: 2px;
    background: var(--navy);
    transform-origin: left;
    animation: draw-rule cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-timeline: view();
    animation-range: entry 15% entry 70%;
  }

  /* The masthead earns a firmer rule once the reader has left the top of the
     page, so it reads as a bar of its own rather than as part of the hero. */
  .masthead {
    animation: masthead-settle linear both;
    animation-timeline: scroll(root);
    animation-range: 0 120px;
  }
}

/* -------------------------------------------------------------------- print */
@media print {
  .masthead nav, .actions, .skip { display: none; }
  body { background: #fff; color: #000; }
}
