/* ============================================================
   Salvis  ·  salvisai.com
   A briefing for small law firms.

   Set in EB Garamond, with IBM Plex Mono for metadata.
   One theme. Bone ground, forest ink, amber accent.

   Shape rule: nothing is rounded. Structure is made of rules.
   Loudness rule: one element at a time is above a whisper.
   The page is a document, not an interface.
   ============================================================ */

/* ---------- faces ----------
   Self-hosted, subset from the upstream EB Garamond (OFL), NOT the Google
   Fonts build. Google's subset strips smcp, c2sc and onum, which would make
   every small cap on this page a browser-synthesised fake. These carry the
   real ones. Self-hosting also means no visitor request reaches a third
   party, which matters for a practice that sells confidentiality.
   ---------------------------------------------------------------- */

@font-face {
  font-family: "EB Garamond";
  src: url("fonts/ebgaramond-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/ebgaramond-400i.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/ebgaramond-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/plexmono-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/plexmono-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ---------- tokens ---------- */

:root {
  --ground:        #EFEAE0;  /* bone */
  --ground-deep:   #E7E1D4;  /* recessed bands */
  --ink:           #101E18;  /* forest */
  --ink-soft:      #3A4640;  /* secondary text, sidenotes */
  --ink-faint:     #556059;  /* metadata. clears AA at 11px on both grounds. */
  --rule:          rgba(16, 30, 24, 0.16);
  --rule-mid:      rgba(16, 30, 24, 0.26);
  --rule-strong:   rgba(16, 30, 24, 0.42);
  --accent:        #7A5E10;  /* dark amber. anything textual. */
  --accent-bright: #D6A93C;  /* NON-TEXT ONLY. ornament, ticks, drop cap. */

  --font-text: "EB Garamond", Georgia, "Times New Roman", serif;
  --font-meta: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --measure: 64ch;
  --margin-col: 236px;   /* the sidenote column */
  --margin-gap: 26px;    /* prose to sidenote */
  --sheet: 1020px;       /* prose + gap + sidenote + padding. no dead right edge. */
  --rail: 58px;              /* the stage scale gutter */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- reset ---------- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 20px;
  line-height: 1.62;
  font-variant-numeric: oldstyle-nums proportional-nums;
  hanging-punctuation: first;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
::selection { background: var(--accent-bright); color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- grain ----------
   Fixed and pointer-events-none so it never repaints on scroll. 2%. */

.grain {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: 0.028;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- layout ---------- */

.sheet {
  max-width: var(--sheet);
  margin-inline: auto;
  padding-inline: clamp(22px, 5vw, 60px);
}

.prose { max-width: var(--measure); }
@media (max-width: 1079px) { .prose { margin-inline: auto; } }

/* Section rhythm. At 82px top and bottom plus a 40px section break on each side,
   consecutive sections sat ~244px apart, which read as a gap rather than a
   break. These bring it to ~188px. */
.band { padding-block: clamp(44px, 5vw, 66px); }
.band-deep {
  background: var(--ground-deep);
  border-block: 1px solid var(--rule);
}
.band-tight { padding-block: clamp(36px, 4.2vw, 56px); }

/* the visible margin rule: makes the sidenote column structural.
   It must hang off .sheet, not the section. The section is full-bleed, so
   positioning against it puts the rule straight through the text column. */
@media (min-width: 1080px) {
  .ruled > .sheet { position: relative; }
  .ruled > .sheet::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(clamp(22px, 5vw, 60px) + var(--measure) + (var(--margin-gap) / 2));
    width: 1px;
    background: var(--rule);
  }
}

/* ---------- masthead + running head ---------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--rule-mid);
}

/* Reading position, drawn along the masthead rule. A document convention
   rather than a landing-page one: it says how much is left, which on a page
   this long is information the reader actually wants.

   Scroll-driven CSS animation, so there is no scroll listener anywhere in
   the project. Hidden outright where the timeline is unsupported, because a
   progress bar frozen at zero reads as broken rather than absent. */
.progress { display: none; }

@supports (animation-timeline: scroll()) {
  .progress {
    display: block;
    position: absolute;
    left: 0;
    bottom: -1px;
    width: 100%;
    height: 1px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left center;
    animation: progress-draw linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes progress-draw { to { transform: scaleX(1); } }
}
@media (prefers-reduced-motion: reduce) { .progress { display: none; } }

.masthead-inner {
  display: flex;
  align-items: baseline;
  gap: 18px;
  padding-block: 17px;
}

/* The rule that fills the span between the running head and the link. Without it
   the bar is two objects marooned at opposite ends of 900px of nothing. A rule
   carrying the eye across is how a masthead is set on paper. */
.masthead-rule {
  flex: 1 1 auto;
  min-width: 24px;
  height: 1px;
  background: var(--rule);
  transform: translateY(-5px);
}
@media (max-width: 700px) { .masthead-rule { flex-basis: 0; min-width: 0; } }

/* The wordmark. Set larger and tighter than a nameplate instinct suggests:
   at 0.22em the letters read as separate objects rather than a word. */
.wordmark {
  font-family: var(--font-text);
  font-size: 30px;
  font-variant-caps: small-caps;  /* real smcp: cap S, small-cap ALVIS */
  letter-spacing: 0.11em;
  font-weight: 500;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  margin-right: -0.11em; /* optical: tracking leaves a trailing gap */
}
.wordmark .stop { color: var(--accent-bright); }

/* the running head: which section you are in, like a printed book */
.running {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-left: 18px;
  border-left: 1px solid var(--rule);
  flex: 0 1 auto;
  transition: opacity 260ms var(--ease);
}
.running.swap { opacity: 0; }

@media (max-width: 700px) { .running { display: none; } }

.masthead-link {
  font-family: var(--font-meta);
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--accent);
  padding-bottom: 3px;
  white-space: nowrap;
}
.masthead-link:hover { color: var(--ink); border-color: var(--ink); }
@media (max-width: 460px) { .masthead-link { font-size: 10px; letter-spacing: 0.1em; } }

/* ---------- typography ---------- */

h1, h2, h3 { font-weight: 500; text-wrap: balance; margin: 0; }

.statement {
  font-size: clamp(33px, 4.8vw, 54px);
  line-height: 1.13;
  letter-spacing: -0.014em;
  max-width: 26ch;   /* 19ch broke a two-sentence statement over five lines */
  margin: 0 0 clamp(26px, 3.5vw, 36px);
}
.statement .second { color: var(--ink-soft); display: block; }

.identity {
  font-size: clamp(19px, 1.9vw, 22px);
  line-height: 1.6;
  max-width: 42ch;
  margin: 0 0 clamp(30px, 4vw, 40px);
}

h2.heading {
  font-size: clamp(27px, 3.2vw, 38px);
  line-height: 1.16;
  letter-spacing: -0.01em;
  max-width: 20ch;
  margin: 0 0 24px;
}

.section-mark {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 20px;
  display: flex;
  align-items: center;
  gap: 14px;
}
.section-mark::after {
  content: "";
  flex: 1;
  max-width: 90px;
  height: 1px;
  background: var(--rule-mid);
}

p { margin: 0 0 1.05em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

/* Scoped to .prose this missed the form note, which then rendered in browser
   default blue. Any text link on the page is amber. */
.prose a,
.form-note a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* Two lines, not three. At three the cap dominates the paragraph and the
   ragged re-entry on line four reads as a layout fault. */
.opens-with-cap::first-letter {
  -webkit-initial-letter: 2;
  initial-letter: 2;
  color: var(--accent-bright);
  font-weight: 500;
  margin-right: 0.07em;
}

/* ---------- hero index ----------
   The four stage names, quiet, foreshadowing the model. */

.hero-index {
  list-style: none;
  margin: clamp(30px, 4vw, 44px) 0 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 0;
}
.hero-index li {
  font-variant-caps: small-caps;
  letter-spacing: 0.09em;
  font-size: 16.5px;
  color: var(--ink-faint);
  padding-right: 14px;
  margin-right: 14px;
  border-right: 1px solid var(--rule);
}
.hero-index li:last-child { border-right: 0; margin-right: 0; padding-right: 0; }

/* ---------- the section break ----------
   The keystone (assets/mark-keystone.svg), inlined so the break costs no
   request and inherits its color. It replaced an asterism composed from
   three of the font's own asterisks: that mark meant "a break in the text",
   which is generic to all printing and said nothing about the practice.
   See BRAND.md → "The mark" for the full reasoning.

   Rendered in --accent-bright, which is the ornament-only amber. It fails
   contrast for text at this value and is correct here precisely because a
   section break carries no information.
   ---------------------------------------------------------------- */

.dinkus {
  display: flex;
  justify-content: center;
  padding-block: clamp(18px, 2.2vw, 28px);
  user-select: none;
}
.dinkus-mark {
  display: block;
  width: 27px;
  height: auto;
  fill: var(--accent-bright);
}

/* ---------- citations: the note opens from its own number ----------

   These were Tufte sidenotes floated into the right margin, which holds only
   while a note is shorter than the passage it annotates. Note 2 runs 855
   characters: in a 236px column it stood 558px tall against a three-line
   paragraph, hung 217px below the bottom of its section, and came to rest
   beside the NEXT section's heading — so the page appeared to cite a claim it
   had not made yet.

   Anchoring each note to its own paragraph keeps a citation inside the section
   that earns it, at whatever length the citation runs to. Because the note is
   positioned rather than in flow, it also never splits the paragraph it hangs
   off — which is what defeated the inline attempt recorded at .floor-note.
   ---------------------------------------------------------------- */

.prose p { position: relative; }

.sn-ref {
  font-family: var(--font-meta);
  font-size: 0.6em;
  vertical-align: super;
  line-height: 0;
  color: var(--accent);
  cursor: pointer;
  padding-inline: 0.15em;
  border-radius: 2px;
  transition: color 160ms var(--ease), background-color 160ms var(--ease);
}
.sn-ref:hover { color: var(--ink); }

/* Clipped rather than display:none. display:none drops the checkbox out of the
   tab order, which would leave every citation on the page keyboard-dead. */
.sn-check {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* An open marker holds its highlight, so the way to close it is self-evident. */
.sn-ref:has(+ .sn-check:checked) {
  color: var(--ink);
  background: rgba(214, 169, 60, 0.34);
}
.sn-ref:has(+ .sn-check:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sn {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 12px);
  z-index: 50;   /* over the masthead at 40, under the grain at 60 */
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  background: var(--ground);
  border: 1px solid var(--rule-mid);
  border-left: 2px solid var(--accent-bright);
  padding: 15px 18px;
  box-shadow: 0 16px 38px rgba(16, 30, 24, 0.15);
}
.sn-check:checked + .sn { display: block; }

@media (max-width: 1079px) {
  .sn {
    top: calc(100% + 9px);
    padding: 13px 15px;
    font-size: 15px;
  }
}

/* ---------- the stage scale ----------
   The one loud element on the page. A vertical scale with a tick at each
   stage; the floor is drawn as a heavy rule crossing it.
   ---------------------------------------------------------------- */

.stages {
  list-style: none;
  margin: clamp(30px, 4vw, 44px) 0 0;
  padding: 0;
  max-width: calc(var(--measure) + var(--rail));
}

.stage {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  position: relative;
  padding-block: clamp(24px, 3vw, 34px);
}

/* the continuous rail */
.stage::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--rule-mid);
}
/* The numeral masks the rail at the top of each stage, so the rail can run
   the full height. The last stage terminates the scale. */
.stage:last-child::before { bottom: auto; height: 3.2em; }

.stage-rail { position: relative; }

/* the tick: a short rule running out from the rail, not a dot.
   Starts AT the rail (11px) so it reads as a graduation mark on a scale. */
.stage-tick {
  position: absolute;
  left: 11px;
  top: 2.15em;
  width: 21px;
  height: 2px;
  background: var(--ink);
  transform-origin: left center;
}

/* The numeral sits ON the rail and masks it, the way a chapter number breaks
   a rule in print. Positioning it at left:0 put "III" straight through the
   line, because the numeral is wider than the rail's 11px offset. */
.stage-numeral {
  position: absolute;
  left: 0;
  top: 0;
  width: 23px;
  text-align: center;
  background: var(--ground);
  padding-block: 2px 6px;
  font-family: var(--font-meta);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.stage-name {
  font-size: clamp(24px, 2.6vw, 31px);
  font-variant-caps: small-caps;
  letter-spacing: 0.08em;
  font-weight: 500;
  line-height: 1.1;
  margin: 0 0 11px;
}

.stage-gloss { font-size: 19px; margin: 0 0 0.85em; max-width: 50ch; }
.stage-body { font-size: 17.5px; color: var(--ink-soft); max-width: 52ch; }

.stage-move {
  font-size: 17px;
  margin-top: 0.95em;
  padding-top: 0.85em;
  border-top: 1px dotted var(--rule-mid);
  max-width: 52ch;
}
.stage-move b {
  font-weight: 500;
  font-variant-caps: small-caps;
  letter-spacing: 0.06em;
  color: var(--accent);
}

/* ---------- self-location ----------
   The scale stops describing and starts answering. Hidden without JS, so
   the page stays a readable document if the script never arrives. */

.stage-pick { display: none; }

.js .stage-pick {
  display: inline-block;
  margin-top: 1.15em;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule-mid);
  padding: 0 0 4px;
  cursor: pointer;
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 160ms var(--ease), border-color 160ms var(--ease);
}
.js .stage-pick:hover { color: var(--accent); border-color: var(--accent); }
.js .stage.picked .stage-pick { color: var(--accent); border-color: var(--accent); }

.stage { transition: opacity 320ms var(--ease); }
.stages.has-pick .stage:not(.picked) { opacity: 0.45; }

.stage.picked .stage-tick { background: var(--accent-bright); height: 3px; }
.stage.picked .stage-numeral { color: var(--accent); }

.stage-mine {
  margin-top: 1.2em;
  padding: 17px 19px;
  border-left: 2px solid var(--accent-bright);
  background: rgba(214, 169, 60, 0.10);
  font-size: 17.5px;
  max-width: 52ch;
}
.stage-mine p { margin: 0 0 0.7em; }
.stage-mine p:last-child { margin: 0; }
.stage-mine .noted {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* the floor: the gate between I and II. the one heavy rule on the page. */
.floor {
  position: relative;
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  margin-block: 6px;
}
.floor::before {
  content: "";
  position: absolute;
  left: 11px; top: 0; bottom: 0;
  width: 1px;
  background: var(--rule-mid);
}

.floor-body {
  border-block: 2px solid var(--ink);
  background: rgba(214, 169, 60, 0.12);
  padding: clamp(20px, 2.6vw, 26px) clamp(18px, 2.2vw, 24px);
  position: relative;
  z-index: 1;
}

/* A note inside a panel belongs at the foot of the panel. Floating it into
   the page margin straddled the panel's right edge; rendering it inline
   split the paragraph in two. So: marker inline, note at the bottom. */
.fn-ref {
  font-family: var(--font-meta);
  font-size: 0.6em;
  vertical-align: super;
  line-height: 0;
  color: var(--accent);
  padding-inline: 0.15em;
}
.floor-note {
  margin: 1.35em 0 0;
  padding-top: 0.9em;
  border-top: 1px solid var(--rule-mid);
  font-size: 14.5px;
  color: var(--ink-soft);
  max-width: 54ch;
}
.floor-note .fn-n {
  font-family: var(--font-meta);
  font-size: 11px;
  color: var(--accent);
  margin-right: 7px;
}

.floor-label {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  display: block;
  margin-bottom: 11px;
}
.floor p { font-size: 17.5px; max-width: 52ch; margin: 0; }
/* Two classes deep so it outranks `.floor p`, which was flattening the gap
   under the lead line and running it into the paragraph below. */
.floor .floor-lead { font-size: 20px; margin: 0 0 0.7em; }

@media (max-width: 620px) {
  .stage, .floor { grid-template-columns: 34px minmax(0, 1fr); }
  .stage::before, .floor::before { left: 6px; }
  .stage-tick { width: 14px; }
  .stage-numeral { font-size: 9.5px; letter-spacing: 0.1em; }
}

/* ---------- accountability ---------- */

/* the sequence: what actually happens. numbered, not railed. */
.sequence {
  list-style: none;
  margin: clamp(28px, 4vw, 40px) 0 0;
  padding: 0;
  max-width: var(--measure);
}
.seq { border-top: 1px solid var(--rule); padding-block: 19px; }
.seq:last-child { border-bottom: 1px solid var(--rule); }
.seq-head { display: flex; align-items: baseline; gap: 15px; margin-bottom: 7px; }
.seq-n {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  color: var(--ink-faint);
}
.seq-title {
  font-size: 21px;
  font-variant-caps: small-caps;
  letter-spacing: 0.07em;
  font-weight: 500;
  margin: 0;
}
.seq p { margin: 0; font-size: 17.5px; color: var(--ink-soft); max-width: 52ch; }

/* No byline, portrait or signature anywhere on this site. The practice
   speaks; the person behind it is established on LinkedIn instead. Rules for
   those elements were deleted rather than left dormant. */

/* ---------- the form ---------- */

.form-wrap { max-width: 46rem; margin-top: clamp(34px, 4.5vw, 52px); }

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px 22px;
  margin-bottom: 26px;
}
.field-full { grid-column: 1 / -1; }
@media (max-width: 620px) { .field-grid { grid-template-columns: 1fr; } }

/* min-width:0 so a grid item can be narrower than its content wants to be */
.field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.field label {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.field label .opt { text-transform: none; letter-spacing: 0.02em; color: var(--ink-faint); }

.field input, .field select {
  font-family: var(--font-text);
  font-size: 18px;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  padding: 9px 2px;
  border-radius: 0;
  appearance: none;
  /* Without this a <select> sizes to its widest <option>. The stage select
     carries a full sentence, so on a phone it pushed the page ~90px wide. */
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.field select { text-overflow: ellipsis; }
.field select {
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
                    linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
  background-position: calc(100% - 13px) 55%, calc(100% - 8px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 26px;
}
.field input:focus, .field select:focus { outline: none; border-bottom-color: var(--accent); }

.hp { position: absolute; left: -9999px; }

.btn {
  font-family: var(--font-meta);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ground);
  background: var(--ink);
  border: 1px solid var(--ink);
  padding: 16px 30px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  border-radius: 0;
  transition: background 180ms var(--ease), color 180ms var(--ease);
}
.btn:hover { background: transparent; color: var(--ink); }
.btn:active { transform: translateY(1px); }

.form-note { font-size: 16px; color: var(--ink-soft); margin-top: 18px; }

/* ---------- footer ---------- */

.site-footer {
  background: var(--ground-deep);
  border-top: 2px solid var(--ink);
  padding-block: clamp(48px, 6vw, 76px) 26px;
}

.footer-top {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  padding-bottom: clamp(34px, 4vw, 48px);
  border-bottom: 1px solid var(--rule-mid);
}
@media (max-width: 820px) {
  .footer-top { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) { .footer-top { grid-template-columns: 1fr; } }

.footer-wordmark {
  font-size: 25px;
  font-variant-caps: small-caps;
  letter-spacing: 0.22em;
  font-weight: 500;
  margin: 0 0 14px;
}
.footer-motto { font-size: 20px; font-style: italic; margin: 0 0 5px; }
.footer-gloss { font-size: 15.5px; color: var(--ink-soft); margin: 0; max-width: 34ch; }

.footer-head {
  font-family: var(--font-meta);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 14px;
}
.footer-list { list-style: none; margin: 0; padding: 0; font-size: 17px; }
.footer-list li { margin-bottom: 7px; }
.footer-list a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--rule); }
.footer-list a:hover { color: var(--ink); border-color: var(--ink); }
.footer-list .muted { color: var(--ink-faint); }

.colophon {
  margin-top: 24px;
  font-family: var(--font-meta);
  font-size: 10.5px;
  line-height: 1.85;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  max-width: 70ch;
}

/* ---------- companion pages (privacy, thanks, 404) ---------- */

.doc { max-width: 62ch; }
.doc h1 {
  font-size: clamp(30px, 4vw, 44px);
  line-height: 1.14;
  letter-spacing: -0.014em;
  margin: 0 0 10px;
}
.doc-date {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 32px;
}
.doc h2 {
  font-size: 22px;
  font-variant-caps: small-caps;
  letter-spacing: 0.07em;
  font-weight: 500;
  margin: 36px 0 10px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
}
.doc p { max-width: 60ch; }
.doc a { color: var(--accent); text-underline-offset: 3px; }
.doc strong { font-weight: 500; }

/* Tables on a document page. Hairline rules only, no fills, no zebra striping:
   the same structural vocabulary as the rest of the system. Scrolls inside its
   own container on a narrow screen so the page body never scrolls sideways. */
.doc-table { overflow-x: auto; margin: 26px 0 30px; }
.doc-table table {
  border-collapse: collapse;
  width: 100%;
  min-width: 30rem;
  font-size: 17px;
}
.doc-table th,
.doc-table td {
  text-align: left;
  padding: 9px 18px 9px 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: baseline;
}
.doc-table th {
  font-family: var(--font-meta);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 400;
  border-bottom-color: var(--ink);
  white-space: nowrap;
}
.doc-table tr:last-child td { border-bottom: 0; }
/* The Texas column is the point of that table, so it carries the emphasis. */
.doc-table .keyed { font-weight: 500; }

/* A stated limit, set apart. Used for the UPL boundary and the
   this-is-not-advice note, which are the two things on the page a reader is
   entitled to see without hunting. */
.doc-bound {
  border-left: 2px solid var(--accent);
  padding: 2px 0 2px 16px;
  margin: 28px 0;
  max-width: 58ch;
}
.doc-bound p { margin-bottom: 10px; }
.doc-bound p:last-child { margin-bottom: 0; }

.back {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-mid);
  padding-bottom: 3px;
}
.back:hover { color: var(--accent); border-color: var(--accent); }

.received {
  font-family: var(--font-meta);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  display: block;
  margin-bottom: 18px;
}

/* ---------- utility ---------- */

.skip {
  position: absolute;
  left: -9999px;
  background: var(--ink);
  color: var(--ground);
  padding: 12px 18px;
  font-family: var(--font-meta);
  font-size: 12px;
  z-index: 80;
}
.skip:focus { left: 12px; top: 12px; }

/* ---------- motion ----------
   Motivated only. Nothing loops, nothing parallaxes, nothing scrubs.
   1. the opening settles in reading order, the way type is set
   2. section rules draw themselves, because structure here IS the rules
   3. the stages arrive in sequence, because the content is sequential
   4. the floor rule draws across, because it is a gate being shown
   5. reading position tracks along the masthead (see .progress)
   Everything below collapses under prefers-reduced-motion.
   ---------------------------------------------------------------- */

.js [data-enter] { opacity: 0; transform: translateY(14px); }
.js [data-enter].seen {
  opacity: 1;
  transform: none;
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}

/* The opening arrives a beat at a time rather than all at once. Reading
   order, not decoration: headline, then who it is, then what to do. */
.js .opening [data-enter]:nth-child(1).seen { transition-delay:   0ms; }
.js .opening [data-enter]:nth-child(2).seen { transition-delay: 120ms; }
.js .opening [data-enter]:nth-child(3).seen { transition-delay: 220ms; }
.js .opening [data-enter]:nth-child(4).seen { transition-delay: 320ms; }
.js .opening [data-enter]:nth-child(5).seen { transition-delay: 410ms; }

.js .stage [data-enter] { transition-delay: 90ms; }

/* The trailing rule on a section mark draws out from the label. */
.js .section-mark::after { transform: scaleX(0); transform-origin: left center; }
.js .section-mark.seen::after {
  transform: scaleX(1);
  transition: transform 620ms var(--ease) 220ms;
}

.js .stage-tick { transform: scaleX(0); }
.js .stage.seen .stage-tick {
  transform: scaleX(1);
  transition: transform 520ms var(--ease);
}

.js .floor-body { clip-path: inset(0 100% 0 0); }
.js .floor.seen .floor-body {
  clip-path: inset(0 0 0 0);
  transition: clip-path 760ms var(--ease);
}

/* Sidenotes follow their paragraph in rather than landing with it, which is
   roughly the order you notice a margin note on paper. */
@media (min-width: 1080px) {
  .js .sn { opacity: 0; transform: translateX(8px); }
  .js .seen .sn,
  .js [data-enter].seen ~ p .sn { opacity: 1; transform: none; }
  .js .prose .sn {
    opacity: 1;
    transform: none;
    transition: opacity 700ms var(--ease) 260ms, transform 700ms var(--ease) 260ms,
                color 200ms var(--ease), border-color 200ms var(--ease);
  }
}

/* ---------- interaction states ---------- */

/* the button gains a rule that runs under it on hover */
.btn { position: relative; overflow: hidden; }
.btn::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--accent-bright);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 320ms var(--ease);
}
.btn:hover::after, .btn:focus-visible::after { transform: scaleX(1); }

/* prose links underline from the left instead of just changing color */
.prose a, .form-note a {
  text-decoration: none;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size 260ms var(--ease), color 160ms var(--ease);
  padding-bottom: 2px;
}
.prose a:hover, .form-note a:hover { color: var(--ink); background-size: 0 1px; }

/* a stage lifts very slightly under the cursor, enough to feel selectable */
.js .stage > div:last-child { transition: transform 260ms var(--ease); }
.js .stage:hover > div:last-child { transform: translateX(3px); }
.js .stage:hover .stage-numeral { color: var(--accent); }
.stage-numeral { transition: color 220ms var(--ease); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-enter],
  .js [data-enter].seen { opacity: 1; transform: none; transition: none; }
  .js .opening [data-enter].seen { transition-delay: 0ms; }
  .js .section-mark::after,
  .js .section-mark.seen::after { transform: scaleX(1); transition: none; }
  .js .stage-tick, .js .stage.seen .stage-tick { transform: scaleX(1); transition: none; }
  .js .floor-body, .js .floor.seen .floor-body { clip-path: none; transition: none; }
  .js .prose .sn { opacity: 1; transform: none; transition: none; }
  .js .stage:hover > div:last-child { transform: none; }
  .btn::after { display: none; }
  .prose a, .form-note a { transition: none; }
  *, *::before, *::after { animation-duration: 0.01ms !important; }
}
