/* Plenty — the page
   A run of rounded panels on a warm ground. Structure, section order and the
   way each block behaves are carried over from the reference the page was
   modelled on; every value in them — face, weight, colour, tracking — comes
   from tokens.css and nowhere else. */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The masthead is fixed, so anything jumped to has to clear it. */
  scroll-padding-top: clamp(78px, 9vh, 104px);
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--size-16);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

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

:where(a, button, summary):focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ═══ Shared type ════════════════════════════════════════════════════════ */

/* Every section heading is this. Two display steps and nothing between them —
   the hierarchy is carried by scale and air, which is the rule a one-weight
   display face forced on the system and which turned out to be right for the
   text face too. */
.h2 {
  margin: 0;
  font-size: var(--display-2);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.h2--center { text-align: center; margin-inline: auto; max-width: 20ch; }

.h3 {
  margin: 0;
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.024em;
}

.h4 {
  margin: 0;
  font-size: clamp(1.125rem, 1.5vw, 1.3rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.018em;
}

/* The one place the display face appears outside the wordmark. Gebuk holds
   nothing under about 32px, so it is allowed here and in the closing heading
   and nowhere else — both clear 40px at every width. Caps, because sentence
   case makes this face read handwritten and that is not the register. */
.hero__title em, .close__title em {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--track-display);
  color: var(--taupe-300);
  /* Gebuk's caps are wider and shorter than Plus Jakarta's lowercase, so the
     accent is stepped down to sit on the same line without lengthening it. */
  font-size: 0.93em;
}

/* The section label. Small, tracked, on a tinted lozenge, centred over the
   heading — it is what tells you a new section has started before you have
   read a word of it. */
.pill {
  display: block;
  width: max-content;
  margin: 0 auto clamp(18px, 2.4vw, 28px);
  padding: 7px 15px;
  background: var(--tint);
  border-radius: var(--r-pill);
  font-size: var(--size-14);
  font-weight: 500;
  line-height: 1;
  color: var(--taupe-300);
}
.pill--onTint { background: var(--paper); margin-inline: 0; }

.caps {
  margin: 0;
  font-size: var(--size-12);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--taupe-200);
}
.caps b { color: var(--ink); font-weight: 600; }
.caps--center { text-align: center; margin-top: clamp(56px, 8vw, 96px); }

.num { font-variant-numeric: var(--figures-data); }

/* An inline text link. The underline is drawn under the arrow too, and the
   arrow is what moves on hover — the rule the whole page follows is that
   motion is a response to a pointer, never an animation. */
.link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--s5);
  color: var(--ink);
  font-size: var(--size-16);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
  padding-bottom: 3px;
  transition: border-color var(--dur-fast) var(--ease);
}
.link:hover { border-color: var(--ink); }
.link__arr { transition: transform var(--dur) var(--ease); }
.link:hover .link__arr { transform: translateX(4px); }

/* ═══ Buttons ════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 48px;
  padding-inline: 22px;
  border: 1px solid transparent;
  border-radius: var(--r-xs);
  font-family: inherit;
  font-size: var(--size-14);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.006em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--ink   { background: var(--ink); color: var(--paper); }
.btn--ink:hover { background: var(--taupe-300); }

.btn--paper { background: var(--paper); color: var(--ink); box-shadow: var(--lift); }
.btn--paper:hover { background: var(--tint); }

.btn--line  { background: transparent; color: var(--ink); border-color: var(--rule-strong); }
.btn--line:hover { background: var(--tint); border-color: transparent; }

.btn--sm    { height: 40px; padding-inline: 17px; }
.btn--wide  { width: 100%; }

.btn__arr { transition: transform var(--dur) var(--ease); }
.btn:hover .btn__arr { transform: translateX(3px); }

/* ═══ Masthead ═══════════════════════════════════════════════════════════ */

/* Fixed, and transparent until the page moves under it. The frosted state is
   the only thing on the site that changes without a pointer, and it is a
   response to scroll rather than an animation — it has no state of its own. */
.mast {
  position: fixed;
  z-index: 60;
  inset: 0 0 auto;
  padding: var(--shell-inset) var(--shell-inset) 0;
  transition: padding var(--dur) var(--ease);
}

.mast__inner {
  display: flex;
  align-items: center;
  gap: var(--s5);
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 11px 12px 11px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.mast.is-stuck .mast__inner {
  background: rgba(254, 254, 254, 0.82);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-color: var(--rule);
  box-shadow: var(--lift);
}

.mast__brand { display: flex; align-items: center; gap: 9px; text-decoration: none; color: var(--ink); }
/* Both are currentColor SVGs — set colour here, never edit the files. */
.mast__glyph { width: 22px; height: 22px; }
.mast__mark  { height: 13px; width: auto; }

.mast__nav { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 26px); margin-left: auto; }
.mast__nav a {
  color: var(--taupe-300);
  font-size: var(--size-14);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
.mast__nav a:hover, .mast__nav a.is-here { color: var(--ink); }

.mast__burger {
  display: none;
  width: 40px; height: 40px;
  padding: 0;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-xs);
  cursor: pointer;
  place-content: center;
  gap: 5px;
}
.mast__burger span {
  display: block;
  width: 16px; height: 1.5px;
  margin-inline: auto;
  background: var(--ink);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.mast__burger[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
.mast__burger[aria-expanded="true"] span:last-child  { transform: translateY(-3.25px) rotate(-45deg); }

.mast__drawer[hidden] { display: none; }
.mast__drawer {
  max-width: var(--page-max);
  margin: 6px auto 0;
  padding: var(--s3);
  display: grid;
  gap: 2px;
  background: rgba(254, 254, 254, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  box-shadow: var(--lift-high);
}
.mast__drawer a {
  padding: 11px 12px;
  border-radius: var(--r-xs);
  color: var(--ink);
  font-size: var(--size-16);
  font-weight: 500;
  text-decoration: none;
}
.mast__drawer a:hover { background: var(--tint); }

/* ═══ Hero ═══════════════════════════════════════════════════════════════ */

/* The field is unchanged: a rank of vertical hairlines climbing left to right
   with a wave through them, thickening under the pointer. What is new is that
   it is a panel now rather than the page — inset on all four sides and
   rounded, so the masthead sits on the ground above it and the first thing
   below the fold is the panel's own bottom edge. */
.hero {
  position: relative;
  margin: var(--shell-inset);
  height: calc(100svh - 2 * var(--shell-inset));
  min-height: 560px;
  overflow: hidden;
  background: var(--paper);
  border-radius: var(--r-lg);
}

.hero__field {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%; height: 100%;
  /* The field with no JavaScript — the same hairlines at the same pitch, flat
     instead of waved. hero.js removes it the moment it has painted, so the two
     are never both on screen. */
  background-image: repeating-linear-gradient(to right,
    rgb(var(--wave-ink) / var(--wave-alpha)) 0 var(--wave-weight),
    transparent var(--wave-weight) var(--wave-pitch));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 38%;
}
.hero__field--painted { background-image: none; }

/* The ground stepping in front of the art so the type can be read on it. It
   runs top to bottom rather than sitting behind the copy as a blob, which is
   what dissolves the tips of the tallest lines into the panel instead of
   stopping them at an edge. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(254, 254, 254, .98) 0%, rgba(254, 254, 254, .74) 18%,
    rgba(254, 254, 254, .34) 32%, rgba(254, 254, 254, 0) 46%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  height: 100%;
  /* Wider than the 1120 column the rest of the page stands in, so the headline
     hangs left of the wordmark above it rather than lining up with it. It is
     the only thing on the page that breaks the column, which is what makes the
     hero read as the panel's own composition instead of as the first row of
     the page grid. Under about 1300px the min() collapses it back to the full
     panel and the 18px is all that is left, so nothing moves on a phone. */
  max-width: min(100%, calc(var(--page-max) + 2 * clamp(0px, 5vw, 76px)));
  margin-inline: auto;
  padding: clamp(104px, 17vh, 190px) 18px clamp(26px, 4vh, 46px);
}

/* A line of type, not a lozenge. The pill this replaces carried a dot, a caps
   setting and a count, and all three of them fought the headline underneath it;
   this reads as the first half of the same sentence, which is what it is. It
   ends on a comma and the headline finishes it. */
.hero__over {
  margin: 0;
  font-size: clamp(1rem, 1.35vw, 1.2rem);
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--taupe-300);
}

.hero__title {
  margin: clamp(10px, 1.4vh, 16px) 0 0;
  /* No ch cap: the line breaks are set in the markup, and a measure here only
     fights them — the display face in the accent is much wider than the text
     face, so a cap that fits one line does not fit the other. */
  font-size: var(--display-1);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.032em;
}

/* ═══ Section frame ══════════════════════════════════════════════════════ */

.band { padding-block: var(--section-gap); }
.band + .band { padding-top: 0; }

.shell {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* The one full-width tinted block on the page. It is inset and rounded like
   the hero, so the page reads as a stack of panels on a ground rather than as
   a document with a coloured stripe through it. */
.band--tint {
  margin: 0 var(--shell-inset);
  padding: clamp(60px, 8vw, 104px) 0 clamp(64px, 8vw, 110px);
  background: var(--tint);
  border-radius: var(--r-xl);
}
.band + .band--tint { margin-top: var(--section-gap); }
.band--tint + .band { padding-top: var(--section-gap); }

/* ═══ Entry ══════════════════════════════════════════════════════════════ */

/* Opacity and a short rise, nothing else, at --dur-slow — the one motion the
   page has that is not a response to a pointer. Under prefers-reduced-motion
   the durations are zero and .is-in is set immediately, so nothing moves and
   nothing is hidden. */
/* Scoped to .js — set inline in <head> — because only the script can take the
   hidden state back off again. Without the scope, no JavaScript means no page. */
.js [data-rise] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  transition-delay: calc(var(--rise-delay, 0) * 80ms);
}
.js [data-rise].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-rise] { opacity: 1; transform: none; }
}

/* ═══ About ══════════════════════════════════════════════════════════════ */

.about {
  display: grid;
  grid-template-columns: 1fr 1.1fr 1fr;
  gap: clamp(20px, 2.6vw, 36px);
  align-items: stretch;
  margin-top: clamp(40px, 5vw, 64px);
}

.about__art {
  margin: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--tint);
}
.about__art img { width: 100%; height: 100%; object-fit: cover; }

/* The figure gets --paper because --paper is its own background — sat on the
   tint it would show the seam where the render's ground ends. */
.about__art--figure {
  background: var(--paper);
  border: 1px solid var(--rule);
  display: grid;
  align-items: end;
  overflow: hidden;
}
.about__art--figure img {
  width: 116%;
  height: auto;
  justify-self: center;
  /* The coat already runs off the bottom of its own viewBox, so flush against
     the panel floor the crop the render had just continues. */
  margin-bottom: -2%;
  object-fit: contain;
}

.about__copy { padding: clamp(4px, 1vw, 14px) clamp(6px, 1.4vw, 20px); }
.about__glyph { width: 34px; height: 34px; margin-bottom: var(--s5); color: var(--ink); }
.about__copy p {
  margin: 0 0 var(--s4);
  font-size: var(--size-16);
  line-height: 1.65;
  color: var(--taupe-300);
}
.about__copy p b { color: var(--ink); font-weight: 600; }

/* ═══ Stats + sources ════════════════════════════════════════════════════ */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(10px, 1.2vw, 16px);
  list-style: none;
  margin: clamp(20px, 2.6vw, 36px) 0 0;
  padding: 0;
}
.stat {
  padding: clamp(20px, 2.4vw, 30px) clamp(16px, 2vw, 24px);
  background: var(--tint);
  border-radius: var(--r-md);
  text-align: center;
}
.stat__n {
  display: block;
  font-size: clamp(1.9rem, 3.1vw, 2.75rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
}
.stat__l {
  display: block;
  margin-top: 9px;
  font-size: var(--size-14);
  line-height: 1.4;
  color: var(--taupe-300);
}

/* --- The two marquees --- */

/* Both are the same object: a track twice as wide as its content, translated
   by half of itself. They pause under a pointer, which is the only reason a
   thing that moves on its own is allowed on this page — you can stop it. */
.marquee {
  position: relative;
  overflow: hidden;
  margin-top: clamp(20px, 2.6vw, 32px);
  /* The black here is a mask stop, not ink — it means "keep this pixel" and is
     never painted. It is the one #000 on the site that is not a bug. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}
.marquee__track {
  display: flex;
  width: max-content;
  animation: slide var(--marquee-dur, 46s) linear infinite;
}
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track { animation-play-state: paused; }
@keyframes slide { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
}

.marquee--sources { --marquee-dur: 52s; }
.src {
  display: grid;
  place-items: center;
  flex: none;
  min-width: clamp(150px, 15vw, 200px);
  height: 74px;
  margin-right: 10px;
  padding-inline: 22px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  font-size: var(--size-14);
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--taupe-300);
  white-space: nowrap;
}

/* ═══ What arrives ═══════════════════════════════════════════════════════ */

.feature {
  display: grid;
  grid-template-columns: 0.86fr 1.14fr;
  gap: clamp(24px, 3vw, 48px);
  align-items: stretch;
  margin-top: clamp(40px, 5vw, 64px);
  padding: clamp(26px, 3.2vw, 46px);
  background: var(--tint);
  border-radius: var(--r-lg);
}

/* The column is centred against the specimen beside it rather than spread to
   its corners: with the card grid gone this panel is the whole section, and a
   tag pinned to the top of a 500px column with the action pinned to the foot
   reads as two fragments rather than one block. */
.feature__copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(6px, 1vw, 16px);
}
/* Both are inline-flex, which a column flex parent would otherwise stretch to
   the full width of the column. */
.feature__copy .tag,
.feature__copy .btn { align-self: flex-start; }

.tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 var(--s5);
  padding: 6px 14px 6px 10px;
  background: var(--paper);
  border-radius: var(--r-pill);
  font-size: var(--size-12);
  font-weight: 600;
  line-height: 1;
  color: var(--taupe-300);
}
.tag__dot { width: 6px; height: 6px; border-radius: 2px; background: var(--taupe-200); }

.feature__desc {
  margin: var(--s4) 0 clamp(22px, 2.6vw, 32px);
  max-width: 36ch;
  font-size: var(--size-16);
  line-height: 1.6;
  color: var(--taupe-300);
}

/* Set as an email, not as a card: a from-line, a subject, a measure narrower
   than the panel because an email is narrower than a page. */
.mail {
  position: relative;
  margin: 0;
  background: var(--paper);
  border-radius: var(--r-md);
  box-shadow: var(--lift);
  overflow: hidden;
}
.mail__head { padding: clamp(18px, 2vw, 24px) clamp(20px, 2.2vw, 28px) 0; }
.mail__from {
  display: block;
  font-size: var(--size-12);
  font-weight: 500;
  color: var(--taupe-200);
}
.mail__subj {
  display: block;
  margin-top: 6px;
  padding-bottom: clamp(14px, 1.6vw, 18px);
  border-bottom: 1px solid var(--rule);
  font-size: var(--size-18);
  font-weight: 600;
  letter-spacing: -0.018em;
}
.mail__body { padding: clamp(16px, 1.8vw, 22px) clamp(20px, 2.2vw, 28px) clamp(52px, 5vw, 62px); }
.mail__body p {
  margin: 0 0 var(--s3);
  font-size: var(--size-14);
  line-height: 1.62;
  color: var(--taupe-300);
}
.mail__body b { color: var(--ink); font-weight: 600; }
.mail__sig { color: var(--taupe-200); }

/* The reference floats a white bar over the foot of its featured image. Ours
   carries the disclaimer, which is the one place it has to be and the one
   place a reader is looking when they need it. */
.mail__float {
  position: absolute;
  left: 10px; right: 10px; bottom: 10px;
  padding: 11px 15px;
  background: var(--tint);
  border-radius: var(--r-xs);
  font-size: var(--size-12);
  font-style: italic;
  line-height: 1.45;
  color: var(--taupe-300);
}

/* ═══ What I do — the tabbed panel ═══════════════════════════════════════ */

.do__head {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: clamp(24px, 4vw, 72px);
  align-items: end;
  padding-inline: var(--gutter);
  max-width: var(--page-max);
  margin-inline: auto;
}
.band--tint > .shell { padding-inline: 0; }
.band--tint > .shell > .pill { margin-left: var(--gutter); }
.do__sub {
  margin: 0;
  font-size: var(--size-16);
  line-height: 1.6;
  color: var(--taupe-300);
}

.panel {
  display: grid;
  grid-template-columns: 236px 1fr;
  margin: clamp(32px, 4vw, 54px) var(--gutter) 0;
  max-width: calc(var(--page-max) - 2 * var(--gutter));
  margin-inline: auto;
  background: var(--paper);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--lift);
}

.panel__side {
  display: flex;
  flex-direction: column;
  padding: var(--s4) var(--s3);
  background: var(--paper-2);
  border-right: 1px solid var(--rule);
}

.tab {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 11px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-xs);
  font-family: inherit;
  font-size: var(--size-14);
  font-weight: 500;
  color: var(--taupe-300);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tab:hover { background: var(--tint); }
.tab.is-on {
  background: var(--paper);
  border-color: var(--rule);
  box-shadow: var(--lift);
  color: var(--ink);
  font-weight: 600;
}
.tab__ic { display: grid; place-items: center; width: 18px; height: 18px; flex: none; }
.tab__ic svg { width: 15px; height: 15px; stroke-linecap: round; stroke-linejoin: round; }

 { padding: clamp(22px, 2.6vw, 34px); }

.pane[hidden] { display: none; }
.pane.is-on { animation: fadeUp var(--dur) var(--ease) both; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .pane.is-on { animation: none; } }

.pane__desc {
  margin: 10px 0 0;
  max-width: 56ch;
  font-size: var(--size-14);
  line-height: 1.6;
  color: var(--taupe-300);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  list-style: none;
  margin: clamp(16px, 1.8vw, 22px) 0 0;
  padding: 0;
}
.chips li {
  padding: 6px 12px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-pill);
  font-size: var(--size-12);
  font-weight: 500;
  color: var(--taupe-300);
}

/* The pane's specimen. Rows of real-looking record state, or a short passage —
   whichever the tab is about. Never a diagram. */
.spec {
  margin-top: clamp(18px, 2vw, 26px);
  padding: clamp(14px, 1.6vw, 20px) clamp(16px, 1.8vw, 22px);
  background: var(--tint);
  border-radius: var(--r-sm);
}
.spec__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s4);
  padding: 9px 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--size-14);
}
.spec__row:last-child { border-bottom: 0; padding-bottom: 0; }
.spec__row:first-child { padding-top: 0; }
.spec__k { display: flex; align-items: center; gap: 8px; font-weight: 500; }
.spec__v { color: var(--taupe-200); font-size: var(--size-12); text-align: right; }
.spec__row--stale .spec__v { color: var(--taupe-300); font-weight: 600; }

.ok, .hm {
  display: grid; place-items: center;
  width: 16px; height: 16px;
  flex: none;
  border-radius: 50%;
  font-size: 10px;
  line-height: 1;
  background: var(--taupe-100);
  color: var(--paper);
}
.hm { background: transparent; color: var(--taupe-300); border: 1px solid var(--rule-strong); font-weight: 700; }

.spec--prose p {
  margin: 0 0 10px;
  font-size: var(--size-14);
  line-height: 1.6;
  color: var(--taupe-300);
}
.spec--prose p:last-child { margin-bottom: 0; }
.spec--prose b { color: var(--ink); font-weight: 600; }
/* The marked passage — the thing the reader is meant to check. */
.spec mark {
  background: rgba(184, 166, 148, .38);
  color: var(--ink);
  padding: 1px 3px;
  border-radius: 3px;
}
.spec__flag { font-style: italic; }

/* ═══ How I work — the process ═══════════════════════════════════════════ */

.proc {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 88px);
  margin-top: clamp(44px, 6vw, 76px);
}

.proc__steps { list-style: none; margin: 0; padding: 0; }

/* Each step is a screen tall so the stage beside it has something to hold on
   to while it is the current one. The dim/undim is the whole interaction —
   the panel does not move, the reading position does. */
.pstep {
  padding: clamp(18px, 3vh, 30px) 0 clamp(52px, 16vh, 132px);
  opacity: .34;
  transition: opacity var(--dur-slow) var(--ease);
}
.pstep.is-on { opacity: 1; }
.pstep:last-child { padding-bottom: clamp(18px, 4vh, 40px); }

.pstep__n {
  display: block;
  margin-bottom: var(--s3);
  font-size: var(--size-14);
  font-weight: 600;
  color: var(--taupe-200);
}
.pstep p {
  margin: 10px 0 0;
  max-width: 34ch;
  font-size: var(--size-14);
  line-height: 1.6;
  color: var(--taupe-300);
}

.proc__stage { position: relative; }
.stage {
  position: sticky;
  top: clamp(96px, 16vh, 148px);
  display: grid;
  aspect-ratio: 4 / 3.4;
  background: var(--tint);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.stage__card {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(24px, 3vw, 40px);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  pointer-events: none;
}
.stage__card.is-on { opacity: 1; transform: none; }

/* Gebuk's other job. A step ordinal at this size is read as a mark rather than
   as a sentence, which is where the face's stylisation is an asset — and it
   clears the ~32px floor below which it holds nothing. */
.stage__n {
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 8vw, 6.5rem);
  line-height: .82;
  color: var(--taupe-100);
  margin-bottom: auto;
}
.stage__k {
  margin: 0 0 8px;
  font-size: var(--size-12);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--taupe-200);
}
.stage__v {
  margin: 0;
  max-width: 30ch;
  font-size: clamp(1rem, 1.3vw, 1.125rem);
  line-height: 1.5;
  letter-spacing: -0.012em;
}

.proc__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s4);
  flex-wrap: wrap;
  margin-top: clamp(36px, 5vw, 60px);
}
.proc__note { font-size: var(--size-14); color: var(--taupe-300); }

/* ═══ Pricing ════════════════════════════════════════════════════════════ */

/* One plan, so the grid is a single centred column rather than a pair. Held
   narrower than the measure: a price list wider than about 460px stops reading
   as a card and starts reading as a table. */
.plans {
  max-width: 460px;
  margin: clamp(28px, 3.4vw, 42px) auto 0;
}

/* Tinted shell, white body — the reference's exact construction, and the
   reason a plan reads as a card with a header rather than as a list. */
.plan {
  padding: 6px;
  background: var(--tint);
  border-radius: var(--r-lg);
}

.plan__head { padding: 16px 20px 20px; }
.plan__head p {
  margin: 5px 0 0;
  font-size: var(--size-14);
  color: var(--taupe-300);
}

.plan__body {
  padding: clamp(20px, 2.4vw, 28px);
  background: var(--paper);
  border-radius: var(--r-md);
}
.plan__price {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin: 0 0 clamp(18px, 2vw, 24px);
  padding-bottom: clamp(18px, 2vw, 24px);
  border-bottom: 1px dashed var(--rule-strong);
}
.plan__amt {
  font-size: clamp(2rem, 3.2vw, 2.75rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.034em;
}
.plan__per { font-size: var(--size-14); color: var(--taupe-300); }

.plan__list { list-style: none; margin: 0 0 clamp(20px, 2.4vw, 28px); padding: 0; }
.plan__list li {
  position: relative;
  padding: 0 0 0 27px;
  margin-bottom: 12px;
  font-size: var(--size-14);
  line-height: 1.45;
  color: var(--taupe-300);
}
.plan__list li::before {
  content: "";
  position: absolute;
  left: 0; top: 2px;
  width: 17px; height: 17px;
  background: no-repeat center / 17px 17px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9.1' fill='none' stroke='%23B8A694' stroke-width='1.3'/%3E%3Cpath d='M5.9 10.2 8.7 13l5.4-5.9' fill='none' stroke='%23968573' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.plan__note {
  margin: clamp(16px, 1.8vw, 20px) 0 0;
  padding-top: clamp(16px, 1.8vw, 20px);
  border-top: 1px dashed var(--rule-strong);
  font-size: var(--size-12);
  text-align: center;
  color: var(--taupe-200);
}

/* ═══ FAQ ════════════════════════════════════════════════════════════════ */

.faq { display: grid; gap: 8px; max-width: 720px; margin: clamp(28px, 3.4vw, 42px) auto 0; }

.q {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  overflow: hidden;
  transition: box-shadow var(--dur) var(--ease);
}
.q[open] { box-shadow: var(--lift); }

.q summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding: 16px 18px;
  font-size: var(--size-16);
  font-weight: 500;
  letter-spacing: -0.012em;
  cursor: pointer;
  list-style: none;
}
.q summary::-webkit-details-marker { display: none; }
.q summary:hover { background: var(--paper-2); }

/* Two rules crossed. The vertical one rotates out on open, so the plus becomes
   a minus — one element, no icon swap, and it inherits the text colour. */
.q__ic { position: relative; width: 15px; height: 15px; flex: none; }
.q__ic::before, .q__ic::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto;
  height: 1.4px;
  background: var(--taupe-300);
  transition: transform var(--dur) var(--ease);
}
.q__ic::after { transform: rotate(90deg); }
.q[open] .q__ic::after { transform: rotate(0deg); }

/* The height is driven by site.js so the panel can open to its own content
   rather than to a guessed max-height. Padding lives on the paragraph, not
   here, or it would still be showing at height zero. */
.q__a { overflow: hidden; transition: height var(--dur) var(--ease); }
.q__a p {
  margin: 0;
  padding: 0 18px 18px;
  max-width: 62ch;
  font-size: var(--size-14);
  line-height: 1.65;
  color: var(--taupe-300);
}
.q__a b { color: var(--ink); font-weight: 600; }

.ask {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  flex-wrap: wrap;
  max-width: 720px;
  margin: 8px auto 0;
  padding: clamp(18px, 2vw, 22px) clamp(18px, 2.2vw, 24px);
  background: var(--tint);
  border-radius: var(--r-sm);
}
.ask__q { margin: 0; font-size: var(--size-16); font-weight: 600; letter-spacing: -0.012em; }
.ask__s { margin: 3px 0 0; font-size: var(--size-14); color: var(--taupe-300); }

/* ═══ Closing CTA + footer ═══════════════════════════════════════════════ */

/* One tinted panel that runs to the foot of the document, with the closing
   picture bled into its bottom edge — the reference's last move, and the one
   that stops a footer reading as an appendix. */
.close {
  position: relative;
  margin: var(--section-gap) var(--shell-inset) var(--shell-inset);
  padding: clamp(112px, 15vw, 236px) var(--gutter) 0;
  background: var(--tint);
  border-radius: var(--r-xl);
  overflow: hidden;
  isolation: isolate;
}
/* The picture, and the tint dissolving down into it so there is no seam where
   one becomes the other. */
.close::before,
.close::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: -1;
  /* Taller than the block needs, so the picture reaches up under the heading
     and the links rather than sitting below them as a band. */
  height: clamp(340px, 48vw, 660px);
}
.close::before {
  background: url("assets/hero/rower-2400.webp") center bottom / cover no-repeat;
}
/* Exactly as tall as the picture, and opaque for its first few per cent — a
   scrim that starts already fading leaves a hairline where the picture's top
   edge is, which is the one thing this layer exists to prevent. */
.close::after {
  background:
    /* the foot, so the colophon has something to sit on */
    linear-gradient(to top, rgba(18, 15, 10, .58) 0%, rgba(18, 15, 10, 0) 22%),
    /* the head, so there is no seam where the tint becomes the picture */
    /* Held near-solid a long way down, because the block now sits on the
       picture rather than above it and the link columns land in this band. The
       picture opens up only in its last third, which is where the rower and
       the light are. */
    linear-gradient(to bottom,
      var(--tint) 0%, var(--tint) 20%, rgba(239, 234, 227, .92) 42%,
      rgba(239, 234, 227, .66) 60%, rgba(239, 234, 227, .20) 78%,
      rgba(239, 234, 227, 0) 92%);
}

.close__inner { max-width: var(--page-max); margin-inline: auto; text-align: center; }

.close__brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--ink);
  text-decoration: none;
  font-size: var(--size-16);
  font-weight: 600;
  letter-spacing: -0.014em;
}
.close__brand img { width: 24px; height: 24px; }

/* Sits under the lockup and above the heading, at colophon size, so the
   attribution is stated once at the top of the closing block and the line at
   the very foot is only the copyright. */
.close__by {
  margin: 10px 0 0;
  font-size: var(--size-12);
  color: var(--taupe-300);
}
.close__by sup { font-size: .68em; vertical-align: .38em; line-height: 0; margin-right: .06em; }

.close__title {
  margin: clamp(14px, 2vw, 22px) auto 0;
  max-width: 16ch;
  font-size: var(--display-1);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.032em;
  text-wrap: balance;
}

.close__sub {
  margin: clamp(14px, 1.8vw, 20px) auto 0;
  max-width: 46ch;
  font-size: var(--size-16);
  line-height: 1.55;
  color: var(--taupe-300);
}

.close__acts {
  display: flex;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: clamp(24px, 3vw, 34px);
}

/* Four links on one line. Three headed columns were a sitemap for a page with
   seven sections, and at that length the headings carried more weight than the
   links under them. */
.close__links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(20px, 3.4vw, 44px);
  margin-top: clamp(40px, 4.6vw, 62px);
}
.close__links a {
  color: var(--taupe-300);
  font-size: var(--size-14);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px dotted var(--rule-strong);
  padding-bottom: 2px;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.close__links a:hover { color: var(--ink); border-bottom-style: solid; border-color: var(--ink); }

.close__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
  max-width: var(--page-max);
  margin: clamp(96px, 13vw, 190px) auto 0;
  padding: var(--s4) var(--gutter) clamp(18px, 2vw, 24px);
}
.close__bar p {
  margin: 0;
  font-size: var(--size-12);
  /* On the picture, not on the tint — paper at 76% rather than taupe. */
  color: rgba(254, 254, 254, .76);
}
/* Browsers set `vertical-align: super` and `font-size: smaller`, and the two
   together lift the 2 far enough to open the line box. */
.close__bar sup, .q__a sup {
  font-size: .68em;
  vertical-align: .38em;
  line-height: 0;
  margin-right: .09em;
}

/* ═══ Wide ═══════════════════════════════════════════════════════════════ */

@media (min-width: 1600px) {
  /* The shell stops growing but the inset does not — past this the panels want
     a wider margin or they read as a page with a hairline around it. */
  :root { --shell-inset: 20px; }
}

/* ═══ Tablet ═════════════════════════════════════════════════════════════ */

@media (max-width: 1000px) {
  .about { grid-template-columns: 1fr 1fr; }
  /* The second photograph is the first thing to go: it is atmosphere, and the
     figure beside the copy is the pair that carries the section. */
  .about__art:last-child { display: none; }
  .about__copy { padding: 0; }

  .feature { grid-template-columns: 1fr; }
  .do__head { grid-template-columns: 1fr; align-items: start; gap: var(--s5); }
  .panel { grid-template-columns: 1fr; }

  /* Tabs become a scrolling row above the pane, and the stop paragraph moves
     under the pane where there is width for it. */
  .panel__side {
    flex-direction: row;
    gap: 6px;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--rule);
    scrollbar-width: none;
  }
  .panel__side::-webkit-scrollbar { display: none; }
  .tab { width: auto; white-space: nowrap; }

  /* The two columns become one, and the stage turns through ninety degrees:
     it goes above the steps and sticks to the top of the window instead of to
     the side of them, so it still holds whichever step you are reading. Block
     rather than grid, because a sticky grid item can only stick inside its own
     row — which on one column is its own height. */
  /* Flex, not block: the stage is second in the markup so it needs `order` to
     come first, and a sticky flex item still sticks inside its container. */
  .proc { display: flex; flex-direction: column; }
  /* Pinned at zero with the masthead's height as padding rather than as an
     offset, and the page ground painted behind it — otherwise the step text
     passing underneath shows through the gap between the two. */
  .proc__stage {
    order: -1;
    position: sticky;
    top: 0;
    z-index: 1;
    padding-top: clamp(72px, 10vh, 92px);
    /* The gap under the card is padding, not margin, so the ground paints it —
       a transparent margin lets the next step slide up into the space. */
    padding-bottom: var(--s6);
    background: var(--ground);
  }
  /* Sized by the tallest card rather than by a ratio: at this width the ratio
     was shorter than the copy in it, and the card spilled over the first step. */
  .stage { position: static; aspect-ratio: auto; min-height: 210px; }
  .stage__n { margin-bottom: var(--s5); }
  /* The steps pass behind the card, so the first one needs to start below it
     and none of them may be dimmed — on one column the lit step is often the
     one under the card rather than the one being read. */
  .pstep { padding-bottom: var(--s7); opacity: 1; }
  .pstep p { max-width: var(--measure); }
}

/* ═══ Phone ══════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
  .mast__nav, .mast__cta { display: none; }
  .mast__burger { display: grid; margin-left: auto; }

  .hero { border-radius: var(--r-md); min-height: 520px; }
  .hero__title { max-width: 100%; }
  .about { grid-template-columns: 1fr; }
  .about__art--figure { aspect-ratio: 1 / 1; }
  .about__art--figure img { width: 74%; }

  .stats { grid-template-columns: 1fr 1fr; }
  .close__bar { justify-content: center; text-align: center; }

  .band--tint, .close { border-radius: var(--r-lg); }
  .feature, .about__art, .stage, .plan { border-radius: var(--r-md); }

  /* A shorter wave, so it clears the copy above it without a scrim doing the
     work — hero.js re-reads these on every resize. */
  :root {
    --wave-pitch:  8px;
    --wave-length: 900px;
    --wave-floor:  0.08;
    --wave-ceil:   0.60;
  }
  .hero__scrim { background: none; }
}

@media (max-width: 480px) {
  .stats { grid-template-columns: 1fr; }
  .stat { display: flex; align-items: baseline; gap: 12px; text-align: left; padding: 16px 18px; }
  .stat__l { margin-top: 0; }
  .ask { flex-direction: column; align-items: stretch; }
  .ask .btn { width: 100%; }
}

