/* Vetfluence · components.css · v3
   New furniture: the footer bar, sourced statistics, the pricing
   ranges, the colophon spec, the glossary, and the transparency pages.
   Everything here inherits the existing tokens; nothing redefines them. */

/* ---------------------------------------------------------------- footer */
.fbot { flex-wrap: wrap; gap: 14px 24px; }
.fbot__links { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.fbot__links a { white-space: nowrap; }

/* ---------------------------------------------------------------- the real clock
   Sits under the hero lede and names the visitor's own time. */
.localnote {
  display: grid;
  max-width: 54ch;
  margin: -6px 0 0;
  padding: 13px 16px;
  border-left: 3px solid var(--slate);
  background: var(--paper-2);
  border-radius: 0 10px 10px 0;
  font-size: 15.5px;
  line-height: 1.5;
  animation: ln-in .5s var(--ease) both;
}
.localnote b { font-weight: 700; }
.localnote > span { grid-area: 1 / 1; }
.localnote__ghost { visibility: hidden; }
@keyframes ln-in { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .localnote { animation: none; } }

/* ---------------------------------------------------------------- sourced stats
   Every number on this site says whose number it is. An agency that is
   careful with other people's data is easier to believe about its own. */
.statrow {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 2px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  margin: clamp(28px, 4vw, 44px) 0;
}
.stat { background: var(--paper); padding: 26px 24px; display: grid; gap: 8px; align-content: start; }
.sec--ink .stat { background: var(--invert-bg); }
.sec--dim .stat { background: var(--paper-2); }
.stat b {
  font: 800 clamp(34px, 5.2vw, 52px)/1 var(--f-display);
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
}
.stat p { margin: 0; font-size: 15.5px; line-height: 1.45; }
.stat cite {
  font: 500 11.5px/1.4 var(--f-mono);
  font-style: normal;
  letter-spacing: .04em;
  color: var(--ink-soft);
  display: block;
  margin-top: 2px;
}
.sec--ink .stat cite { color: var(--invert-muted); }
.stat cite a { text-decoration: underline; text-underline-offset: 3px; }

.srcnote {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
  border-left: 2px solid var(--line);
  padding-left: 16px;
  max-width: 68ch;
}

/* ---------------------------------------------------------------- pricing */
.priceband {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: 18px;
  margin-bottom: clamp(36px, 5vw, 56px);
}
.price {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px 26px;
  display: grid;
  gap: 12px;
  align-content: start;
  background: var(--paper);
  position: relative;
}
.price--lead { border-color: var(--ink); border-width: 2px; }
.price__tag {
  position: absolute;
  top: -11px;
  left: 22px;
  font: 600 11px/1 var(--f-mono);
  letter-spacing: .09em;
  text-transform: uppercase;
  background: var(--ink);
  color: var(--paper);
  padding: 6px 11px;
  border-radius: 999px;
}
.price h3 { font: 800 21px/1.2 var(--f-display); letter-spacing: -.02em; margin: 0; }
.price__n {
  font: 800 clamp(32px, 4.6vw, 44px)/1 var(--f-display);
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
}
.price__n span { font-size: .5em; font-weight: 600; color: var(--ink-soft); letter-spacing: 0; }
.price > p { margin: 0; font-size: 15.5px; line-height: 1.55; color: var(--ink-soft); }
.price ul { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 8px; font-size: 15px; }
.price li { display: grid; grid-template-columns: 18px 1fr; gap: 9px; align-items: start; line-height: 1.45; }
.price li::before { content: "✓"; color: var(--ok); font-weight: 700; }
.price li.no::before { content: "✕"; color: var(--ink-soft); }

.movers { border-top: 2px solid var(--ink); }
.mover {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) minmax(0, .85fr);
  gap: 22px;
  padding: 22px 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
}
.mover .dir { font: 700 15px/1.3 var(--f-mono); color: var(--slate-deep); padding-top: 2px; }
.mover .dir.up { color: var(--no); }
.mover h3 { font: 700 17px/1.35 var(--f-body); margin: 0 0 4px; }
.mover p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--ink-soft); }
@media (max-width: 720px) {
  .mover { grid-template-columns: 38px 1fr; gap: 14px; }
  .mover > :last-child { grid-column: 2; }
}

/* ---------------------------------------------------------------- colophon */
.spec { display: grid; gap: 0; border-top: 1px solid var(--line); }
.spec__r {
  display: grid;
  grid-template-columns: minmax(150px, 220px) minmax(0, 1fr);
  gap: 18px 28px;
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.spec__r dt {
  font: 600 12px/1.4 var(--f-mono);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.spec__r dd { margin: 0; font-size: 16px; line-height: 1.6; }
.spec__r dd code { font: 500 14px/1 var(--f-mono); background: var(--paper-2); padding: 2px 6px; border-radius: 5px; }
@media (max-width: 620px) { .spec__r { grid-template-columns: 1fr; gap: 4px; padding: 14px 0; } }

/* ---------------------------------------------------------------- glossary */
.gloss-tools { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-bottom: 28px; }
.gloss-search {
  flex: 1 1 260px;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: inherit;
  font: 500 16px/1 var(--f-body);
  padding: 13px 18px;
  min-height: 46px;
}
.gloss-count { font: 500 13px/1 var(--f-mono); color: var(--ink-soft); }
.gloss { display: grid; gap: 0; border-top: 1px solid var(--line); }
.gterm {
  padding: 22px 0;
  border-bottom: 1px solid var(--line);
  display: grid;
  grid-template-columns: minmax(170px, 250px) minmax(0, 1fr);
  gap: 10px 28px;
  align-items: start;
}
.gterm[hidden] { display: none; }
.gterm h3 { margin: 0; font: 800 18px/1.3 var(--f-display); letter-spacing: -.015em; }
.gterm h3 .k { display: block; font: 500 11.5px/1.4 var(--f-mono); letter-spacing: .07em; text-transform: uppercase; color: var(--ink-soft); margin-top: 5px; }
.gterm p { margin: 0 0 10px; font-size: 16px; line-height: 1.62; }
.gterm p:last-child { margin-bottom: 0; }
.gterm .why {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  border-left: 2px solid var(--slate);
  padding-left: 14px;
}
.gloss-empty { padding: 34px 0; color: var(--ink-soft); }
@media (max-width: 680px) { .gterm { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- a11y page */
.a11y-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.a11y-list li { display: grid; grid-template-columns: 26px 1fr; gap: 12px; align-items: start; font-size: 16.5px; line-height: 1.6; }
.a11y-list .y { color: var(--ok); font-weight: 700; }
.a11y-list .w { color: #c98f4f; font-weight: 700; }

/* ---------------------------------------------------------------- offline */
.offline { min-height: 68vh; display: grid; place-items: center; text-align: center; padding: 60px var(--gut); }
.offline__in { max-width: 44ch; display: grid; gap: 18px; justify-items: center; }

/* ---------------------------------------------------------------- shared */
.leadin {
  font: 500 clamp(19px, 2.1vw, 23px)/1.55 var(--f-body);
  max-width: 62ch;
  color: var(--ink-soft);
}
.pagenav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: clamp(30px, 4vw, 44px);
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.pagenav a {
  font: 600 14px/1 var(--f-body);
  padding: 10px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  text-decoration: none;
  transition: border-color .2s, background-color .2s;
}
.pagenav a:hover { border-color: var(--ink); background: var(--paper-2); }

.toc {
  position: sticky;
  top: calc(var(--head-h) + 20px);
  align-self: start;
  display: grid;
  gap: 7px;
  font-size: 14.5px;
  padding-left: 16px;
  border-left: 1px solid var(--line);
}
.toc a { text-decoration: none; color: var(--ink-soft); transition: color .2s; }
.toc a:hover, .toc a.is-here { color: var(--ink); }
.toc a.is-here { font-weight: 700; }
@media (max-width: 980px) { .toc { display: none; } }

/* ---------------------------------------------------------------- teardown */
.tdlist { display: grid; gap: 0; border-top: 2px solid var(--ink); }
.td {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr);
  gap: 24px;
  padding: 24px 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
}
.td__n { display: grid; gap: 8px; justify-items: start; }
.td__n .mono { font: 600 12px/1 var(--f-mono); letter-spacing: .1em; color: var(--ink-soft); }
.td__v {
  font: 600 10.5px/1 var(--f-mono);
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: 5px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  white-space: nowrap;
}
.td[data-state="pass"] .td__v { color: #3d7f64; border-color: #3d7f6455; background: var(--mint-soft); }
.td[data-state="part"] .td__v { color: #96682c; border-color: #96682c44; }
.td[data-state="fail"] .td__v { color: #9c4034; border-color: #9c403444; }
.td[data-state="unknown"] .td__v { color: var(--ink-soft); }
.td__body h3 { margin: 0 0 8px; font: 750 clamp(17px, 1.8vw, 20px)/1.3 var(--f-display); letter-spacing: -.015em; }
.td__found { margin: 0 0 10px; font-size: 16px; line-height: 1.6; color: var(--ink-soft); }
.td__fix {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.58;
  padding: 12px 15px;
  border-left: 3px solid var(--slate);
  background: var(--paper-2);
  border-radius: 0 9px 9px 0;
}
.td__fix code { font: 500 14px/1 var(--f-mono); background: var(--paper-3); padding: 2px 5px; border-radius: 4px; }
@media (max-width: 640px) { .td { grid-template-columns: 1fr; gap: 12px; } .td__n { grid-auto-flow: column; justify-content: start; align-items: center; gap: 12px; } }

.trio { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; counter-reset: t; }
.trio li {
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--paper);
}
.trio__n {
  font: 800 26px/1 var(--f-display);
  letter-spacing: -.03em;
  color: var(--slate);
  font-variant-numeric: tabular-nums;
}
.trio h3 { margin: 0 0 6px; font: 750 18px/1.3 var(--f-display); }
.trio p { margin: 0; font-size: 15.5px; line-height: 1.6; color: var(--ink-soft); }
@media (max-width: 560px) { .trio li { grid-template-columns: 38px 1fr; gap: 14px; padding: 18px; } }

/* ---------------------------------------------------------------- practice types */
.kinds { display: grid; gap: 0; border-top: 2px solid var(--ink); }
.kind {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: 28px;
  padding: 30px 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
}
.kind__head h3 { margin: 0 0 7px; font: 800 clamp(21px, 2.3vw, 27px)/1.18 var(--f-display); letter-spacing: -.025em; }
.kind__sub { margin: 0; font: 500 14.5px/1.5 var(--f-body); color: var(--ink-soft); }
.kind__who { margin: 0 0 16px; font-size: 16.5px; line-height: 1.62; }
.kind__lbl {
  margin: 0 0 10px;
  font: 600 11px/1 var(--f-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate-deep);
}
.kind__body ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.kind__body li {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr);
  gap: 11px;
  font-size: 15.5px;
  line-height: 1.5;
}
.kind__body li::before { content: "\2014"; color: var(--slate); font-weight: 700; }
@media (max-width: 820px) { .kind { grid-template-columns: 1fr; gap: 16px; } }


/* ── the concept site behind each practice type ───────────────── */
.kind__built {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding: 10px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  text-decoration: none;
  color: var(--ink);
  font-size: 13.5px;
  transition: border-color .22s, background .22s, transform .22s var(--ease, ease);
}
.kind__built span { color: var(--ink-soft, #5d6f79); }
.kind__built b { font-weight: 600; }
.kind__built:hover { border-color: var(--slate); background: var(--mint-soft); transform: translateX(2px); }
.kind__built svg { flex: none; color: var(--slate); }

/* ═══ Resource articles ══════════════════════════════════════════
   Everything below belongs to the long-form posts. The motion here
   is all derived from the content — a bar that fills to the figure
   it is describing, a number that counts to the number it is — so
   nothing moves for the sake of moving. */

/* on-page contents, sticky beside the text on wide screens */
.ptoc {
  border-left: 2px solid var(--mint);
  padding: 2px 0 2px 18px;
  margin: 0 0 36px;
}
.ptoc__h {
  margin: 0 0 10px;
  font: 600 11px/1 var(--f-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-soft, #5d6f79);
}
.ptoc ol { margin: 0; padding: 0; list-style: none; counter-reset: toc; display: grid; gap: 7px; }
.ptoc li { counter-increment: toc; }
.ptoc a {
  display: inline-flex;
  gap: 10px;
  text-decoration: none;
  font-size: 15.5px;
  line-height: 1.45;
  color: var(--ink-soft, #5d6f79);
  border-bottom: 1px solid transparent;
  transition: color .2s, border-color .2s;
}
.ptoc a::before {
  content: counter(toc, decimal-leading-zero);
  font: 500 11.5px/1.6 var(--f-mono);
  color: var(--slate);
  flex: none;
}
.ptoc a:hover { color: var(--ink); border-bottom-color: var(--slate); }
.ptoc a[aria-current="true"] { color: var(--ink); font-weight: 600; }
.ptoc a[aria-current="true"]::before { color: var(--mint); }
@media (min-width: 1180px) {
  .ptoc {
    position: sticky;
    top: 92px;
    float: left;
    width: 210px;
    margin: 6px 0 24px -258px;
  }
}

/* numbered and plain runs inside prose */
.prose .numlist { margin: 0 0 22px; padding: 0; list-style: none; counter-reset: n; display: grid; gap: 14px; }
.prose .numlist li { counter-increment: n; position: relative; padding-left: 42px; }
.prose .numlist li::before {
  content: counter(n);
  position: absolute; left: 0; top: 1px;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border: 1.5px solid var(--slate);
  border-radius: 50%;
  font: 600 12.5px/1 var(--f-mono);
  color: var(--slate);
}
.prose .plainlist { margin: 0 0 22px; padding: 0; list-style: none; display: grid; gap: 13px; }
.prose .plainlist li { position: relative; padding-left: 24px; }
.prose .plainlist li::before {
  content: ""; position: absolute; left: 0; top: .72em;
  width: 13px; height: 2px; background: var(--mint);
}

/* a bar that fills to the figure it describes */
.figbar { margin: 26px 0 28px; display: grid; gap: 14px; }
.figbar__row { display: grid; grid-template-columns: minmax(0, 190px) minmax(0, 1fr) auto; gap: 16px; align-items: center; }
.figbar__lb { font-size: 15px; line-height: 1.4; color: var(--ink-soft, #5d6f79); }
.figbar__track { height: 10px; background: var(--mint-soft); border-radius: 2px; overflow: hidden; }
.figbar__fill {
  display: block; height: 100%;
  background: var(--slate);
  width: 0;
  transition: width 1.1s cubic-bezier(.22,.8,.3,1);
}
.figbar__row--alt .figbar__fill { background: var(--mint); }
.figbar.is-in .figbar__fill { width: var(--w, 0%); }
.figbar__v { font: 600 15px/1 var(--f-mono); font-variant-numeric: tabular-nums; min-width: 4.5ch; text-align: right; }
@media (max-width: 680px) {
  .figbar__row { grid-template-columns: 1fr auto; }
  .figbar__track { grid-column: 1 / -1; }
}

/* a figure that counts to itself, once */
.count { font-variant-numeric: tabular-nums; }

/* the questions block, which is also the FAQ schema */
.prose .qa {
  border-top: 1px solid var(--line);
  padding: 0;
  margin: 0;
}
.prose .qa:last-of-type { border-bottom: 1px solid var(--line); margin-bottom: 26px; }
.prose .qa > summary {
  cursor: pointer;
  list-style: none;
  padding: 17px 34px 17px 0;
  position: relative;
  font-weight: 600;
  font-size: 17px;
  line-height: 1.45;
}
.prose .qa > summary::-webkit-details-marker { display: none; }
.prose .qa > summary::after {
  content: ""; position: absolute; right: 6px; top: 50%;
  width: 11px; height: 11px;
  border-right: 2px solid var(--slate); border-bottom: 2px solid var(--slate);
  transform: translateY(-70%) rotate(45deg);
  transition: transform .22s var(--ease, ease);
}
.prose .qa[open] > summary::after { transform: translateY(-30%) rotate(-135deg); }
.prose .qa > p { margin: 0 0 18px; color: var(--ink-soft, #5d6f79); }
.prose .qa > summary:focus-visible { outline: 2px solid var(--slate); outline-offset: 3px; }

/* a pulled line, revealed by its own rule rather than by fading up */
.pull {
  margin: 30px 0;
  padding: 0 0 0 20px;
  position: relative;
  font-family: var(--f-display);
  font-size: clamp(19px, 2.1vw, 25px);
  line-height: 1.35;
  letter-spacing: -.01em;
}
.pull::before {
  content: ""; position: absolute; left: 0; top: .18em; bottom: .18em;
  width: 3px; background: var(--mint);
  transform: scaleY(0); transform-origin: top;
  transition: transform .62s cubic-bezier(.22,.8,.3,1);
}
.pull.is-in::before { transform: scaleY(1); }

@media (prefers-reduced-motion: reduce) {
  .figbar__fill { transition: none; width: var(--w, 0%); }
  .pull::before { transition: none; transform: scaleY(1); }
}

/* ═══ Resource index: image-led tiles ════════════════════════════
   A drawing per guide, specific to that guide's argument. Two things
   move, both tied to the card: the artwork wipes in from the left as
   the row arrives, and on hover the one accent line inside the drawing
   draws itself. Nothing slides up from below. */
.rgroup { padding-block: clamp(34px, 4.2vw, 58px); }
.rgroup + .rgroup { border-top: 1px solid var(--line); }
.rgroup__h { max-width: 62ch; margin-bottom: 28px; }
.rgroup__h h2 { margin: 0 0 6px; font-size: clamp(22px, 2.4vw, 30px); letter-spacing: -.02em; }
.rgroup__h p { margin: 0; color: var(--ink-soft, #5d6f79); font-size: 16px; }

.rgrid { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(20px, 2.4vw, 30px); grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1040px) { .rgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 680px)  { .rgrid { grid-template-columns: 1fr; } }

.rtile > a {
  display: grid;
  grid-template-rows: auto 1fr;
  height: 100%;
  text-decoration: none;
  color: inherit;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  transition: border-color .28s var(--ease), box-shadow .28s var(--ease);
}
.rtile > a:hover { border-color: var(--slate); box-shadow: 0 1px 0 var(--slate); }
.rtile > a:focus-visible { outline: 3px solid var(--slate); outline-offset: 3px; }

.rtile__art {
  display: block;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
/* the drawing arrives by being uncovered, not by sliding — only where a
   script is running to uncover it again */
.js .rtile__art {
  clip-path: inset(0 100% 0 0);
  transition: clip-path .72s cubic-bezier(.3,.08,.2,1);
  transition-delay: var(--d, 0ms);
}
.rtile.is-in .rtile__art { clip-path: inset(0 0 0 0); }
.rtile__art svg { display: block; width: 100%; height: auto; transition: transform .5s var(--ease); }
.rtile > a:hover .rtile__art svg { transform: scale(1.028); }

/* the one accent line in each drawing draws itself on hover */
.js .rtile__art .spark, .js .rtile__art .spark path,
.js .art-fig .spark, .js .art-fig .spark path {
  stroke-dasharray: 900;
  stroke-dashoffset: 900;
  transition: stroke-dashoffset .85s cubic-bezier(.3,.1,.2,1);
}
.rtile > a:hover .spark, .rtile > a:hover .spark path,
.rtile > a:focus-visible .spark, .rtile > a:focus-visible .spark path { stroke-dashoffset: 0; }
.art-fig.is-in .spark, .art-fig.is-in .spark path { stroke-dashoffset: 0; }

.rtile__body { display: grid; align-content: start; gap: 9px; padding: 20px 22px 24px; }
.rtile__m { display: flex; align-items: center; gap: 9px; font: 500 12px/1 var(--f-mono); color: var(--slate); }
.rtile__m i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .6; }
.rtile__t { font: 700 clamp(17px, 1.7vw, 20px)/1.28 var(--f-display); letter-spacing: -.015em; }
.rtile__d { font-size: 15px; line-height: 1.55; color: var(--ink-soft, #5d6f79); }
.rtile__go { display: inline-flex; align-items: center; gap: 7px; margin-top: 4px; font: 600 13.5px/1 var(--f-body); color: var(--slate); }
.rtile__arr { transition: transform .28s var(--ease); }
.rtile > a:hover .rtile__arr { transform: translateX(4px); }

/* the pillar gets the width it deserves */
.rgrid--lead { grid-template-columns: 1fr; }
.rtile--lead > a { grid-template-rows: none; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); align-items: stretch; }
.rtile--lead .rtile__art { border-bottom: 0; border-right: 1px solid var(--line); display: grid; align-content: center; }
.rtile--lead .rtile__body { padding: clamp(24px, 3vw, 40px); align-content: center; gap: 11px; }
.rtile--lead .rtile__t { font-size: clamp(22px, 2.6vw, 32px); }
.rtile--lead .rtile__d { font-size: 16.5px; max-width: 48ch; }
@media (max-width: 820px) {
  .rtile--lead > a { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .rtile--lead .rtile__art { border-right: 0; border-bottom: 1px solid var(--line); }
}

/* the same drawing at the head of the guide itself */
.art-fig {
  margin: clamp(22px, 3vw, 36px) auto clamp(26px, 3.4vw, 44px);
  width: min(100% - 40px, 820px);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: var(--paper-2);
}
.art-fig svg { display: block; width: 100%; height: auto; }

@media (prefers-reduced-motion: reduce) {
  .rtile__art { clip-path: none; transition: none; }
  .rtile__art svg, .rtile__arr { transition: none; }
  .rtile__art .spark, .rtile__art .spark path,
  .art-fig .spark, .art-fig .spark path { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   READING MOTION
   The guides are long. Everything below exists to answer one question a
   visitor asks without words — "is this worth staying for?" — and it
   answers it by showing the argument assemble rather than by decorating
   the page. Seven primitives, composed differently in every drawing.
   Nothing here fades up on scroll, and nothing moves that isn't carrying
   a piece of the content.
   ══════════════════════════════════════════════════════════════════════ */

/* ── the drawings have moving parts ─────────────────────────────────── */
.artv [class*="a-"] { transform-box: fill-box; }

@keyframes a-growx   { from { transform: scaleX(0); }                       to { transform: scaleX(1); } }
@keyframes a-drop    { from { opacity: 0; transform: translateY(-15px); }   to { opacity: 1; transform: translateY(0); } }
@keyframes a-pop     { from { opacity: 0; transform: scale(.72); }          to { opacity: 1; transform: scale(1); } }
@keyframes a-draw    { from { stroke-dashoffset: var(--len, 900); }         to { stroke-dashoffset: 0; } }
@keyframes a-sweep   { from { transform: rotate(-58deg); }                  to { transform: rotate(0deg); } }
@keyframes a-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.04); } }

/* Resting states, and the animations that release them, apply only
   where motion is welcome. Several drawings use opacity to carry
   meaning — a branch that is not the selected one, a profile field
   left blank — so forcing it to 1 under reduced motion would not
   just still the drawing, it would change what the drawing says. */
@media (prefers-reduced-motion: no-preference) {
  /* resting states are applied only when script is present to release them,
     so a visitor without JS sees every drawing complete */
  .js .artv .a-growx { transform: scaleX(0); transform-origin: left center; }
  .js .artv .a-drop  { opacity: 0; }
  .js .artv .a-pop,
  .js .artv .a-ping,
  .js .artv .a-pulse { opacity: 0; transform: scale(.72); transform-origin: center; }
  .js .artv .a-draw  { stroke-dasharray: var(--len, 900); stroke-dashoffset: var(--len, 900); }
  .js .artv .a-sweep { transform: rotate(-58deg); transform-origin: left top; }


  .artv.is-play .a-growx { animation: a-growx .78s cubic-bezier(.3, .05, .2, 1) both; animation-delay: calc(min(var(--i, 0), 12) * 70ms); }
  .artv.is-play .a-drop  { animation: a-drop  .54s cubic-bezier(.26, .9, .32, 1) both; animation-delay: calc(min(var(--i, 0), 12) * 70ms); }
  .artv.is-play .a-pop   { animation: a-pop   .46s cubic-bezier(.2, .85, .28, 1) both; animation-delay: calc(min(var(--i, 0), 12) * 70ms); }
  .artv.is-play .a-ping  { animation: a-pop   .62s cubic-bezier(.18, .9, .3, 1) both; animation-delay: calc(min(var(--i, 0), 12) * 80ms); }
  .artv.is-play .a-draw  { animation: a-draw  1.05s cubic-bezier(.32, .08, .22, 1) both; animation-delay: calc(80ms + min(var(--i, 0), 12) * 70ms); }
  .artv.is-play .a-sweep { animation: a-sweep 1.5s cubic-bezier(.4, .02, .3, 1) both; animation-delay: 260ms; }

  /* the signal keeps radiating: that drawing's whole subject is a search
     going out from one address, so it never settles */
  .artv.is-play .a-pulse {
    animation: a-pop .62s cubic-bezier(.18, .9, .3, 1) both,
               a-breathe 4.4s ease-in-out infinite;
    animation-delay: calc(min(var(--i, 0), 12) * 80ms), calc(700ms + var(--i, 0) * 300ms);
  }

  /* nine and a third seconds is the point of that bar, so it takes its time */
  .artv.is-play .a-growx.a-slow { animation-duration: 2.5s; animation-timing-function: cubic-bezier(.1, .42, .06, 1); }
}

/* the drawing itself is the arrival — the card no longer wipes over it */
.js .rtile__art { clip-path: none; transition: none; }

/* ── the contents list is also the progress spine ─────────────────────
   It already sat beside the text with a mint rule down its left edge and
   a number on every line. Filling that rule, and lighting each marker as
   the reader passes it, turns furniture into the thing that answers "how
   much of this is left" without adding a second device to the page. */
/* no `position` here: the sticky rule above owns it, and a later
   declaration of equal weight would quietly un-stick the list */
.ptoc__p, .ptoc__pc { display: none; }

@media (min-width: 1180px) {
  .js .ptoc { border-left-color: transparent; }
  .js .ptoc::before {
    content: ""; position: absolute; left: -2px; top: 0; width: 2px; height: 100%;
    background: var(--mint, #6da894); opacity: .26;
  }
  .js .ptoc__p {
    display: block; position: absolute; left: -2px; top: 0; width: 2px; height: var(--p, 0%);
    background: var(--mint, #6da894); transition: height .14s linear;
  }
  .js .ptoc li { position: relative; }
  .js .ptoc li::after {
    /* the list's own 18px padding sits between the item and the spine,
       so the marker is pulled back across it to land on the rule */
    content: ""; position: absolute; left: -19px; top: .62em; width: 7px; height: 7px;
    margin: -3.5px 0 0 -3.5px; background: var(--paper);
    border: 1.5px solid var(--mint, #6da894); opacity: .45; transform: rotate(45deg);
    transition: background-color .3s, border-color .3s, opacity .3s, transform .35s var(--ease);
  }
  .js .ptoc li.is-done::after { background: var(--mint, #6da894); opacity: .9; }
  .js .ptoc li.is-now::after {
    background: var(--slate); border-color: var(--slate-deep); opacity: 1;
    transform: rotate(45deg) scale(1.55);
  }
  .js .ptoc__pc {
    display: block; margin: 15px 0 0; font: 600 10.5px/1 var(--f-mono);
    letter-spacing: .08em; text-transform: uppercase; color: var(--slate-deep);
    font-variant-numeric: tabular-nums; transition: opacity .4s;
  }
  .js .ptoc.is-complete .ptoc__pc { opacity: .4; }
}

/* ── the page breathes while you read it ────────────────────────────
   Ruled hairlines that drift sideways across the width of the window,
   and a warm patch of light that travels down it as you read. Painted
   full-bleed on a fixed layer rather than inside the text column, so it
   reads as the page the article sits on instead of a box drawn round
   it. Neither is meant to be noticed on its own. */
/* Both layers are painted once and then only moved (transform), so
   scrolling never repaints the screen. They used to be background
   positions changed every scroll frame, which repainted the whole
   window each frame and stuttered on phones. */
.readbg { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; contain: strict; }
.readbg::before, .readbg::after { content: ""; position: absolute; will-change: transform; }
.readbg::before {
  left: 50%; top: 0; width: 2000px; height: 1280px; margin: -640px 0 0 -1000px;
  background: radial-gradient(1000px 640px at 50% 50%, rgba(109, 168, 148, .17) 0%, rgba(109, 168, 148, 0) 68%);
  transform: translate3d(0, var(--wash-y, 50vh), 0);
}
.readbg::after {
  top: 0; bottom: 0; left: -120px; right: -120px;
  background: linear-gradient(90deg, rgba(22, 21, 19, .055) 1px, transparent 1px) 0 0 / 94px 100%;
  transform: translate3d(var(--drift, 0px), 0, 0);
}
/* a phone holds four of those rules across the text column, which is too
   many to sit behind a paragraph: wider apart and fainter down there */
@media (max-width: 760px) {
  .readbg { opacity: .72; }
  .readbg::after { background-size: 132px 100%; }
}
.readbg--plain::after { display: none; }
/* the content blocks sit above it; the header and footer have their own
   layers already */
.art-hero, .prose, .rel2, .related, .cta-quiet, .site-footer,
.rhero, .rgroup, .rintro { position: relative; z-index: 1; }

/* ── each section arrives ──────────────────────────────────────────────
   A rule draws across, the number lands, the heading rises out from under
   its own baseline. This is the rhythm that tells you a new argument has
   started, and it is why the page stops reading as one flat sheet. */
.prose h2 { position: relative; }
.js .prose h2 { padding-top: 26px; }
.js .prose h2::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: var(--ink); opacity: .22; transform: scaleX(0); transform-origin: left center;
  transition: transform .82s cubic-bezier(.3, .05, .2, 1);
}
.prose h2.is-in::before { transform: scaleX(1); }
.js .prose h2 .h2n {
  position: absolute; top: 9px; left: 0; font: 600 10.5px/1 var(--f-mono);
  letter-spacing: .14em; color: var(--slate-deep); font-style: normal;
  opacity: 0; transform: translateY(-5px);
  transition: opacity .5s .16s, transform .5s .16s var(--ease);
}
.prose h2.is-in .h2n { opacity: 1; transform: none; }
.js .prose h2 .h2w {
  display: inline-block; clip-path: inset(-.26em -.18em 100% -.08em);
  transform: translateY(.3em);
  transition: clip-path .72s cubic-bezier(.24, .08, .2, 1) .1s,
              transform .72s cubic-bezier(.24, .08, .2, 1) .1s;
}
.prose h2.is-in .h2w { clip-path: inset(-.26em -.18em -.26em -.08em); transform: none; }

/* ── runs of items land in order, marker first ─────────────────────── */
.js .prose .numlist li,
.js .prose .plainlist li { opacity: 0; transform: translateX(-9px); }
.js .prose .numlist li::before,
.js .prose .plainlist li::before { transform: scale(.4); opacity: 0; }
.prose .numlist.is-in li,
.prose .plainlist.is-in li {
  opacity: 1; transform: none;
  transition: opacity .46s var(--ease), transform .52s var(--ease);
  transition-delay: calc(40ms + var(--i, 0) * 40ms);
}
.prose .numlist.is-in li::before,
.prose .plainlist.is-in li::before {
  transform: none; opacity: 1;
  transition: transform .42s cubic-bezier(.2, .9, .28, 1), opacity .3s;
  transition-delay: calc(var(--i, 0) * 40ms);
}

/* ── the next read, with its drawing ───────────────────────────────────
   Finishing a guide used to hand you a list of blue links. It now hands
   you two pictures, which is the difference between stopping and going on
   to the next one. */
.rel2 { max-width: 980px; margin: clamp(44px, 6vw, 76px) auto 0; padding-inline: var(--gut) var(--gut-r); }
.rel2__h {
  font: 500 11px/1 var(--f-mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--slate-deep); margin: 0 0 16px;
}
/* the track count comes from the number of cards rather than from
   auto-fit, which was dropping to two columns over a few pixels and
   leaving the third card stranded on a row of its own */
.rel2__g { display: grid; gap: 16px; list-style: none; margin: 0; padding: 0; }
.rel2__g--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rel2__g--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 880px) { .rel2__g--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .rel2__g--3, .rel2__g--2 { grid-template-columns: 1fr; } }
/* the list item stretches to the row; the card has to be told to follow,
   or a longer description leaves one card hanging below the others */
.rel2__g > li { display: grid; }
.rel2__c {
  display: grid; grid-template-rows: auto 1fr; text-decoration: none;
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  background: var(--paper); transition: border-color .3s, transform .4s var(--ease), box-shadow .4s;
}
.rel2__c:hover { border-color: var(--ink); transform: translateY(-3px); box-shadow: 0 18px 34px -24px rgba(22, 21, 19, .5); }
.rel2__art { background: var(--paper-2); border-bottom: 1px solid var(--line); overflow: hidden; }
.rel2__art svg { width: 100%; height: auto; transition: transform .7s var(--ease); }
.rel2__c:hover .rel2__art svg { transform: scale(1.03); }
.rel2__b { padding: 16px 18px 18px; display: grid; gap: 7px; align-content: start; }
.rel2__k { font: 500 10px/1 var(--f-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--slate-deep); }
.rel2__t { font: 750 18.5px/1.25 var(--f-display); letter-spacing: -.012em; margin: 0; }
.rel2__d { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink-soft); }

/* ── reduced motion: everything resolves, nothing travels ───────────── */
@media (prefers-reduced-motion: reduce) {
  .readbg { display: none; }
  .js .prose h2::before { transform: scaleX(1); transition: none; }
  .js .prose h2 .h2n { opacity: 1; transform: none; transition: none; }
  .js .prose h2 .h2w { clip-path: none; transform: none; transition: none; }
  .js .prose .numlist li, .js .prose .plainlist li { opacity: 1; transform: none; transition: none; }
  .js .prose .numlist li::before, .js .prose .plainlist li::before { opacity: 1; transform: none; transition: none; }
  .js .ptoc__p, .js .ptoc li::after { transition: none; }
  .rel2__c, .rel2__art svg { transition: none; }
}

/* a destination of a different kind: a built site rather than a guide */
.rel2__x { margin: 18px 0 0; font-size: 15.5px; }
.rel2__x a {
  text-decoration: none; border-bottom: 1px solid var(--line); padding-bottom: 2px;
  color: var(--slate-deep); font-weight: 600; transition: border-color .25s, color .25s;
}
.rel2__x a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ── the five concept builds on the home page ─────────────────────────
   One lead and four, the same shape the resources index uses, so the
   home page can show all five kinds of practice without turning into a
   second portfolio page. The deep "why it works" reading stays on the
   portfolio itself, which is where somebody who wants it is heading. */
.pflead {
  display: grid; grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
  border: 1.5px solid var(--ink); border-radius: var(--r-lg); overflow: hidden;
  background: var(--paper); text-decoration: none; margin-bottom: 18px;
  transition: box-shadow .45s var(--ease), transform .45s var(--ease);
}
.pflead:hover { transform: translateY(-3px); box-shadow: 0 26px 48px -30px rgba(22, 21, 19, .55); }
.pflead .frame { margin: 14px 0 14px 14px; border-radius: 12px 12px 0 0; }
.pflead__b { padding: clamp(22px, 2.6vw, 34px); display: grid; gap: 11px; align-content: center; border-left: 1.5px solid var(--ink); }
.pflead__t { font: 800 clamp(24px, 2.6vw, 32px)/1.12 var(--f-display); letter-spacing: -.022em; }
.pflead__d { color: var(--ink-soft); font-size: 16px; line-height: 1.55; }

.pf5 { display: grid; gap: 16px; grid-template-columns: repeat(4, minmax(0, 1fr)); list-style: none; margin: 0; padding: 0; }
.pf5__c { display: grid; }
.pf5__c > a {
  display: grid; grid-template-rows: auto 1fr; text-decoration: none;
  border: 1.5px solid var(--ink); border-radius: var(--r-lg); overflow: hidden; background: var(--paper);
  transition: box-shadow .45s var(--ease), transform .45s var(--ease);
}
.pf5__c > a:hover { transform: translateY(-3px); box-shadow: 0 22px 40px -28px rgba(22, 21, 19, .55); }
.pf5__b { padding: 18px 20px 20px; display: grid; gap: 8px; align-content: start; border-top: 1.5px solid var(--ink); }
.pf5__t { font: 750 19px/1.2 var(--f-display); letter-spacing: -.014em; }
.pf5__d { color: var(--ink-soft); font-size: 14.5px; line-height: 1.5; }
.pf5__more { margin: 22px 0 0; font-size: 16px; }
.pf5__more a { font-weight: 700; text-decoration-thickness: 2px; text-underline-offset: 4px; text-decoration-color: var(--slate); }

@media (max-width: 1080px) { .pf5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 860px) {
  .pflead { grid-template-columns: 1fr; }
  .pflead .frame { margin: 14px 14px 0; }
  .pflead__b { border-left: 0; border-top: 1.5px solid var(--ink); }
}
@media (max-width: 560px) { .pf5 { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .pflead, .pf5__c > a { transition: none; } }

/* which clock the slot times are on — answered before anyone wonders */
.slots-tz { margin: 6px 0 12px; font-size: 14px; color: var(--muted-ink, rgba(245, 241, 232, .68)); }

/* two cards answering the same question from opposite starting points */
.starts { display: grid; gap: 18px; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
.starts .card { align-content: start; gap: 13px; }
.starts .card .h3 { margin: 0; }
.starts .card p { margin: 0; color: var(--ink-soft); }
.starts .plainlist { margin: 4px 0 0; padding: 0; list-style: none; display: grid; gap: 13px; }
.starts .plainlist li { position: relative; padding-left: 22px; font-size: 16px; line-height: 1.55; color: var(--ink-soft); }
.starts .plainlist li::before {
  content: ""; position: absolute; left: 0; top: .62em; width: 9px; height: 2px; background: var(--slate);
}
.starts .plainlist strong { color: var(--ink); }
.starts code { font: 500 14px/1 var(--f-mono); background: var(--paper-2); padding: 2px 5px; border-radius: 4px; }
@media (max-width: 880px) { .starts { grid-template-columns: 1fr; } }

/* the caveat that keeps a maintenance plan honest */
.smallnote { font-size: 15px; color: var(--ink-soft); border-left: 2px solid var(--line); padding-left: 14px; }
.leadin--line { border-top: 1px solid var(--line); margin-top: 26px; padding-top: 24px; display: grid; gap: 12px; }

/* ══════════════════════════════════════════════════════════════════════
   PORTFOLIO — one block per practice type
   The argument and the site that proves it are one unit with one number,
   not two numbered things that happen to sit near each other. Everything
   lives inside the wrap, which is what the build card was missing when
   its text ran off the right-hand edge of the page.
   ══════════════════════════════════════════════════════════════════════ */
.ptjump {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 8px;
  margin: 26px 0 0; padding: 0;
}
.ptjump__l {
  font: 500 11px/1 var(--f-mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--slate-deep); margin-right: 4px; flex: none;
}
.ptjump a {
  text-decoration: none; font-size: 14.5px; font-weight: 600; line-height: 1;
  padding: 9px 13px; border: 1.5px solid var(--line); border-radius: 8px;
  background: var(--paper); transition: border-color .25s, background-color .25s;
}
.ptjump a:hover { border-color: var(--ink); background: var(--paper-2); }
.ptnote {
  margin: 22px 0 0; max-width: 72ch; font-size: 15px; color: var(--ink-soft);
  border-left: 2px solid var(--line); padding-left: 16px;
}

.pt { padding-block: clamp(54px, 7vw, 96px); border-top: 1px solid var(--line); }
.pt:nth-of-type(even) { background: var(--paper-2); }

.pt__head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: clamp(16px, 2.4vw, 30px); align-items: start; }
.pt__n {
  font: 600 13px/1 var(--f-mono); letter-spacing: .12em; color: var(--slate-deep);
  padding-top: .55em; flex: none;
}
.pt__h {
  font: 800 clamp(30px, 4vw, 48px)/1.04 var(--f-display); font-stretch: 104%;
  letter-spacing: -.028em; margin: 0; text-wrap: balance;
}
.pt__sub { margin: 10px 0 0; font-size: clamp(17px, 1.5vw, 19px); color: var(--ink-soft); max-width: 48ch; }

/* argument on one side, the site it produced on the other, equal halves */
.pt__body {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(26px, 3.6vw, 56px); align-items: start;
  margin: clamp(26px, 3.4vw, 44px) 0 0;
  padding-left: calc(13px + clamp(16px, 2.4vw, 30px));
}
/* alternate which side the screen sits on, so five blocks in a row do not
   read as five copies of the same slide */
.pt:nth-of-type(even) .pt__site { order: -1; }

.pt__arg { min-width: 0; }
.pt__lbl {
  margin: 0 0 12px; font: 500 11px/1 var(--f-mono); letter-spacing: .14em;
  text-transform: uppercase; color: var(--slate-deep);
}
.pt__lbl--2 { margin-top: 26px; }
.pt__who { margin: 0; font-size: 17px; line-height: 1.6; color: var(--ink-soft); }
.pt__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 11px; }
.pt__list li { position: relative; padding-left: 22px; font-size: 16px; line-height: 1.55; color: var(--ink-soft); }
.pt__list li::before { content: ""; position: absolute; left: 0; top: .66em; width: 10px; height: 2px; background: var(--slate); }

.pt__site { min-width: 0; display: grid; gap: 18px; align-content: start; }
.pt__site .frame { margin: 0; border-radius: 14px; border: 1.5px solid var(--ink); }
.pt__site .frame__view { aspect-ratio: 16 / 10.5; }
.pt__cap { display: grid; gap: 9px; }
.pt__kicker { margin: 0; font: 750 19px/1.25 var(--f-display); letter-spacing: -.014em; color: var(--ink); }
.pt__lede { margin: 0; font-size: 15.5px; line-height: 1.55; color: var(--ink-soft); }
.pt__cta { margin: 4px 0 0; }

@media (max-width: 980px) {
  .pt__body { grid-template-columns: 1fr; padding-left: 0; }
  .pt:nth-of-type(even) .pt__site { order: 0; }
}
@media (max-width: 620px) {
  .pt__head { grid-template-columns: 1fr; gap: 6px; }
  .pt__n { padding-top: 0; }
}
}

/* a drawing that is animating repaints only itself, never the card around it */
.rtile__art, .art-fig, .rel2__art { contain: paint; }

/* card drawings at rest: every part shown, nothing animating until hover */
.artv.is-still [class*="a-"], .artv.is-still .spark, .artv.is-still .spark path {
  animation: none !important; opacity: 1 !important; transform: none !important;
  stroke-dashoffset: 0 !important; clip-path: none !important;
}
