/* ==========================================================================
   Emad Deen Orthodontics — THE ATTESTATION
   Orthodontics set as a document of record. Every claim carries its issuing
   body and its year. The page cites where the category asserts.

   Rules of the world:
   · Monochrome. The only saturation on any page is clinical photography.
   · Hairlines, never boxes. There are no cards in this system.
   · Extreme type scale: display very large and light, body small.
   · Bands meet with no seam.
   · Labels are attestations — tracked caps that carry a body and a year.
   ========================================================================== */

/* --------------------------------------------------------------- Reset --- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* -------------------------------------------------------------- Tokens --- */
:root {
  --black:  #0a0a0a;   /* the ground */
  --paper:  #fafafa;   /* the sheet */
  --bone:   #eae7e1;   /* the second sheet, for alternation */
  --slate:  #161616;   /* a raised surface on the black ground */
  --grey-d: #8a8a8a;   /* secondary ink ON DARK  — 5.7:1, clears AA */
  --grey-l: #5a5a5a;   /* secondary ink ON LIGHT — 6.4:1, clears AA */
  --line-d: rgba(250, 250, 250, .22);
  --line-l: rgba(10, 10, 10, .17);

  --gold: #f0b429;   /* the review stars, and nothing else */
  --face: Archivo, "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* One spacing rhythm. More space above a heading than below it. */
  --band:  clamp(80px, 11vw, 168px);
  --gap:   clamp(28px, 4vw, 56px);
  --edge:  clamp(20px, 4.5vw, 64px);
  --wide:  1560px;
  --read:  68ch;

  --ease: cubic-bezier(.16, 1, .3, 1);
}

/* ------------------------------------------------------------ Baseline --- */
body {
  font-family: var(--face);
  font-size: 16.5px;
  line-height: 1.68;
  font-weight: 400;
  color: var(--black);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "tnum" 1;   /* dates and citations align */
  overflow-x: hidden;
}

/* The display voice: very large, very light, very tight. Never bold. */
.display {
  font-weight: 200;
  line-height: .92;
  letter-spacing: -.035em;
  font-size: clamp(44px, 9.2vw, 96px);
  text-wrap: balance;
}
.display em { font-style: normal; font-weight: 500; }
.display--xl { font-size: clamp(52px, 13vw, 168px); line-height: .88; letter-spacing: -.042em; }
.display--sm { font-size: clamp(30px, 4.4vw, 54px); letter-spacing: -.028em; }
/* Display leading is set for headlines; a paragraph at this size needs air. */
.display--statement { line-height: 1.14; letter-spacing: -.022em; }
/* The statement is set in secondary ink and only the load-bearing clauses
   carry full paper. Reading it is watching the sentence decide what matters. */
.band--dark .statement, .statement { color: var(--grey-d); }
/* Unarmed - no script, or reduced motion - every phrase is already at full
   paper. The dim state only exists while something is there to lift it. */
.band--dark .statement .ink, .statement .ink { color: var(--paper); }
@media (prefers-reduced-motion: no-preference) {
  .band--dark .statement.is-armed .ink,
  .statement.is-armed .ink {
    color: var(--grey-d);
    transition: color .55s var(--ease);
  }
  .band--dark .statement.is-armed .ink.is-lit,
  .statement.is-armed .ink.is-lit { color: var(--paper); }
}

h1, h2, h3, h4 { font-weight: 400; line-height: 1.1; letter-spacing: -.02em; }
h3 { font-size: clamp(20px, 2.2vw, 27px); font-weight: 400; }
h4 { font-size: 17px; font-weight: 500; letter-spacing: -.01em; }

p { max-width: var(--read); }
.lede { font-size: clamp(18px, 2vw, 23px); line-height: 1.55; font-weight: 300; letter-spacing: -.012em; max-width: 46ch; }
.fine { font-size: 15px; line-height: 1.65; color: var(--grey-l); max-width: 62ch; }

/* ---------------------------------------------------------- Attestation ---
   The signature device. Not a label above a heading — a line of record that
   carries its own information: an issuing body, a year, a source. */
.attest {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .11em;
  text-transform: uppercase;
  line-height: 1.5;
  color: var(--grey-l);
}
.attest--onDark { color: var(--grey-d); }
/* The label leads. It sits above the heading it belongs to, names the section,
   and still carries a body, a year or a source rather than a slogan. */
.attest--lead { display: block; margin-bottom: 14px; }
.attest--lead + .display, .attest--lead + h1, .attest--lead + h2, .attest--lead + h3 { margin-top: 0; }
/* In a stack the gap already sets the spacing; the lead must not double it. */
.stack > .attest--lead, .stack-sm > .attest--lead { margin-bottom: 0; }
/* For record lines that run to a sentence — uppercase past a few words is a
   legibility cost the label style cannot pay. */
.attest--long { font-size: 12.5px; letter-spacing: .04em; text-transform: none; font-weight: 400; }
.attest a { border-bottom: 1px solid currentColor; padding-bottom: 1px; }

/* The attested credential run: each entry names its awarding body. */
.record { display: flex; flex-wrap: wrap; gap: 6px 22px; }
.record li { font-size: 13.5px; font-weight: 500; font-variant-caps: all-small-caps; letter-spacing: .09em; color: var(--grey-d); white-space: nowrap; }
.record li b { font-weight: 500; color: var(--paper); }
.record--onLight li { color: var(--grey-l); }
.record--onLight li b { color: var(--black); }

/* --------------------------------------------------------------- Shell --- */
.band { padding-block: var(--band); position: relative; }
.band--tight { padding-block: clamp(44px, 5.5vw, 78px); }
.band--flush { padding-block: 0; }
.band--dark  { background: var(--black); color: var(--paper); }
.band--paper { background: var(--paper); }
.band--bone  { background: var(--bone); }
.band--dark h1, .band--dark h2, .band--dark h3, .band--dark h4 { color: var(--paper); }
.band--dark .fine { color: var(--grey-d); }
.band--dark p { color: rgba(250, 250, 250, .82); }

.measure { max-width: var(--wide); margin-inline: auto; padding-inline: var(--edge); }
.measure--read { max-width: 1040px; }

/* ---------------------------------------------------------------- Rule ---
   The hairline is this system's only container. It draws itself once. */
.rule { --ink: var(--line-l); height: 1px; width: 100%; position: relative; }
.rule::after {
  content: ""; position: absolute; inset: 0;
  background: var(--ink); transform-origin: left center;
}
.band--dark .rule, .rule--onDark { --ink: var(--line-d); }
.rule--half { width: 50%; }
/* The hero rule carries the whole conferral gesture; it is not a divider. */
.rule--strong { --ink: rgba(250, 250, 250, .55); }

/* The one authored motion moment: every rule draws from its origin. */
@media (prefers-reduced-motion: no-preference) {
  .rule.is-armed::after { transform: scaleX(0); transition: transform .9s var(--ease); }
  .rule.is-armed.is-drawn::after { transform: scaleX(1); }
}

/* --------------------------------------------------------------- Split --- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); align-items: start; }
/* A grid track is sized by its item's min-content unless told otherwise. The
   reviews strip is five panels wide at min-content, which blew the single
   mobile column past the viewport until this line. */
.split > * { min-width: 0; }
.split--wide  { grid-template-columns: 1.35fr 1fr; }
.split--narrow{ grid-template-columns: 1fr 1.6fr; }
.split--mid   { align-items: center; }
/* Details against their form. Declared here rather than inline, because an
   inline grid-template-columns outranks the stacking breakpoint and the two
   columns then sit side by side on a phone. */
.split--contact { grid-template-columns: 1fr 1.3fr; gap: clamp(40px, 5vw, 84px); }

.stack > * + * { margin-top: 20px; }
.stack-lg > * + * { margin-top: 38px; }
.stack-sm > * + * { margin-top: 10px; }

/* ---------------------------------------------------------------- Hero ---
   Full-bleed, seamless, and the portrait runs off the right edge uncropped
   at the top of the head. */
.hero { background: var(--black); color: var(--paper); position: relative; overflow: hidden; }
.hero-grid {
  display: grid; grid-template-columns: 1fr 42%;
  min-height: min(92vh, 860px); align-items: end;
  max-width: var(--wide); margin-inline: auto;
}
.hero-text { padding: clamp(96px, 13vh, 180px) var(--gap) clamp(40px, 6vh, 72px) var(--edge); }
.hero-media { position: relative; align-self: stretch; }
.hero-media img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center top;   /* never crop the forehead */
}
.hero-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--black) 0%, rgba(10,10,10,.55) 22%, transparent 62%);
}

/* The primary action: a rule that fills, not a button. */
.act {
  display: inline-block; position: relative; white-space: nowrap;
  font-size: 12.5px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  padding-bottom: 9px; color: inherit;
}
.act::before, .act::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
}
.act::before { background: currentColor; opacity: .3; }
.act::after  { background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform .6s var(--ease); }
.act:hover::after, .act:focus-visible::after { transform: scaleX(1); }
.act--lg { font-size: 13px; }

/* ---------------------------------------------------------------- Ledger --
   The attestation list: a claim, its issuing body, its year. Replaces every
   place the category would have put a card. */
.ledger { border-top: 1px solid var(--line-l); }
.band--dark .ledger { border-color: var(--line-d); }
.ledger-row {
  display: grid; grid-template-columns: 76px 1fr 1.25fr; gap: var(--gap);
  padding: 26px 0; border-bottom: 1px solid var(--line-l);
  align-items: baseline;
}
.band--dark .ledger-row { border-color: var(--line-d); }
.ledger-row > .idx { font-size: 11px; font-weight: 500; letter-spacing: .12em; color: var(--grey-l); }
.band--dark .ledger-row > .idx { color: var(--grey-d); }
.ledger-row > .term { font-size: clamp(19px, 2.1vw, 25px); font-weight: 400; letter-spacing: -.02em; }
.ledger-row > .val { font-size: 15.5px; line-height: 1.62; color: var(--grey-l); max-width: 56ch; }
.band--dark .ledger-row > .val { color: var(--grey-d); }
.ledger-row > .val b { font-weight: 500; color: var(--black); }
.band--dark .ledger-row > .val b { color: var(--paper); }

/* For a ledger inside a column rather than across a band. */
.ledger--narrow .ledger-row { grid-template-columns: 74px 1fr; row-gap: 9px; padding: 22px 0; }
.ledger--narrow .ledger-row > .val { grid-column: 2; max-width: none; }

/* A ledger with no index rail: a term and its value, for details that are
   named rather than numbered. */
.ledger--defs .ledger-row {
  grid-template-columns: clamp(110px, 12vw, 150px) 1fr;
  gap: clamp(16px, 2vw, 30px); padding: 19px 0;
}
.ledger--defs .ledger-row > .term {
  font-size: 12px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
  color: var(--grey-l); line-height: 1.5;
}
.band--dark .ledger--defs .ledger-row > .term { color: var(--grey-d); }
.ledger--defs .ledger-row > .val { font-size: 16px; color: var(--black); max-width: none; }
.band--dark .ledger--defs .ledger-row > .val { color: var(--paper); }

/* A ledger of onward links: no index, and the term stays at reading size
   because it is the thing being clicked, not a field name. */
.ledger--links .ledger-row {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  gap: clamp(20px, 2.5vw, 40px);
}

a.ledger-row { transition: background .45s var(--ease); }
a.ledger-row > * { transition: transform .45s var(--ease); }
a.ledger-row:hover > * { transform: translateX(10px); }
a.ledger-row:hover { background: rgba(10,10,10,.035); }
.band--dark a.ledger-row:hover { background: rgba(250,250,250,.05); }
a.ledger-row .term { transition: none; }

/* ---------------------------------------------------------------- Plate ---
   Clinical photography, held at a fixed frame so the only thing that changes
   between frames is the teeth. Colour survives here and nowhere else. */
.plate { position: relative; overflow: hidden; background: var(--black); }
.plate img { width: 100%; height: 100%; object-fit: cover; display: block; }
.plate--43 { aspect-ratio: 4 / 3; }
.plate--11 { aspect-ratio: 1 / 1; }
.plate--45 { aspect-ratio: 4 / 5; }
.plate--tall { aspect-ratio: 3 / 4; }
.plate-note {
  position: absolute; left: 0; bottom: 0; z-index: 2;
  max-width: 92%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  background: var(--black); color: var(--paper);
  font-size: 11.5px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
  padding: 7px 12px;
}

/* ------------------------------------------------------------ Reviews ----
   The quote leads. The opening mark is set at display scale as an object in
   its own right rather than punctuation inside the sentence. */
.quotes { position: relative; }
.quote-mark {
  font-family: var(--face); font-size: clamp(150px, 17vw, 260px); font-weight: 200;
  line-height: .58; color: var(--paper); opacity: .18; user-select: none;
  display: block; margin-bottom: -.12em;
}
/* The rail takes the height of the longest quote in the set and keeps it.
   Resizing it per page was tried and removed: the quote is a flex item
   stretched to its row, so every way of measuring it either fed back on
   itself or lagged a page behind, and it clipped the two longest reviews.
   A steady frame is worth more than the ~90px it would occasionally save. */
.quote-rail { position: relative; overflow: hidden; }
.quote-strip { display: flex; transition: transform .55s var(--ease); }
@media (prefers-reduced-motion: reduce) { .quote-strip { transition: none; } }
.quote {
  flex: 0 0 100%; min-width: 100%;
  display: flex; flex-direction: column; gap: 28px;
  min-height: 230px;
}
.quote blockquote {
  font-size: clamp(23px, 3.1vw, 40px); font-weight: 200; line-height: 1.3;
  letter-spacing: -.026em; color: var(--paper); max-width: 22ch;
}
.quote figcaption { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.quote figcaption strong { font-size: 17px; font-weight: 500; color: var(--paper); }
/* --gold was referenced here and never declared, so the stars inherited the
   surrounding ink and were grey. Declared on :root below. */
.quote-stars { color: var(--gold); font-size: 27px; line-height: 1; letter-spacing: 3px; }

.quote-nav { display: flex; align-items: center; gap: 12px; margin-top: var(--gap); }
.quote-btn {
  width: 46px; height: 46px; border: 1px solid var(--line-d); background: none;
  color: var(--paper); cursor: pointer; display: grid; place-items: center;
  transition: background .2s ease, border-color .2s ease, transform .12s ease;
}
.quote-btn:hover { background: rgba(250, 250, 250, .08); border-color: var(--paper); }
.quote-btn:active { transform: scale(.94); }
.quote-btn[disabled] { opacity: .3; cursor: default; }
.quote-dots { display: flex; gap: 7px; margin-left: 8px; }
.quote-dot {
  width: 7px; height: 7px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: rgba(250, 250, 250, .28); transition: background .25s ease, transform .25s ease;
}
.quote-dot[aria-current="true"] { background: var(--paper); transform: scale(1.25); }
.quote-count { margin-left: auto; }

/* Two quotes per panel. The strip still moves by whole panels; only how much
   of a panel one quote occupies changes. */
.quotes--pair .quote-strip { gap: clamp(28px, 4vw, 64px); }
.quotes--pair .quote {
  flex: 0 0 calc((100% - clamp(28px, 4vw, 64px)) / 2);
  min-width: calc((100% - clamp(28px, 4vw, 64px)) / 2);
  min-height: 0;
}
.quotes--pair .quote { align-self: flex-start; }
.quotes--pair .quote blockquote { font-size: clamp(16px, 1.45vw, 19px); line-height: 1.55; max-width: none; }
.quotes--pair .quote-mark { font-size: clamp(110px, 11vw, 180px); }
@media (max-width: 820px) {
  .quotes--pair .quote-strip { gap: 0; }
  .quotes--pair .quote { flex-basis: 100%; min-width: 100%; }
}

/* --------------------------------------------------- Treatment strip ---
   A row of appliances, each carrying its own photograph and its numeral.
   Hovering or focusing one gives it the room to speak; the rest stay as
   slivers of image. The numeral is drawn in outline so it reads as a mark on
   the picture rather than as a caption over it.

   Sized with grid-template-columns rather than flex-grow: both animate, but
   the fr track is the one the layout engine is built to interpolate, and it
   keeps every panel's image at a predictable width. */
/* The track list is written by PHP for the row's own length and rewritten by
   script when a panel opens, so a row works with any number of treatments.
   The client can add appliances without the layout going ragged. */
.strip { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 2px; background: var(--black); }
@media (prefers-reduced-motion: no-preference) {
  .strip { transition: grid-template-columns .7s var(--ease); }
}

.panel {
  position: relative; overflow: hidden; min-height: clamp(360px, 42vw, 540px);
  display: flex; flex-direction: column; justify-content: flex-end;
  text-decoration: none; color: var(--paper); background: var(--slate);
}
.panel img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
/* The scrim is what makes a white heading safe on any photograph. */
.panel::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(0deg, rgba(10,10,10,.9) 0%, rgba(10,10,10,.55) 38%, rgba(10,10,10,.1) 78%);
}
.panel-body { position: relative; z-index: 2; padding: clamp(20px, 2.2vw, 34px); }
.panel-body h3 {
  font-size: clamp(19px, 1.9vw, 27px); font-weight: 400;
  line-height: 1.12; letter-spacing: -.024em; color: var(--paper);
}
.panel-copy { margin-top: 11px; font-size: 15px; line-height: 1.55; color: rgba(250,250,250,.8); max-width: 30ch; }
.panel-more {
  display: inline-flex; align-items: center; gap: 9px; margin-top: 18px;
  font-size: 12px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
}
.panel-more::before { content: ""; width: 20px; height: 1px; background: currentColor; transition: width .3s var(--ease); }

/* Once the script is driving the strip, only the open panel speaks. Without
   it, every panel keeps its text and the row simply sits at four equal
   columns - the failure mode is "crowded", never "blank". */
.strip[data-open] .panel-copy,
.strip[data-open] .panel-more { opacity: 0; }
.strip[data-open] .panel-body > h3 { opacity: .001; }
.strip[data-open] .panel.is-open .panel-copy,
.strip[data-open] .panel.is-open .panel-more,
.strip[data-open] .panel.is-open .panel-body > h3 { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .strip[data-open] .panel-body > h3,
  .strip[data-open] .panel-copy,
  .strip[data-open] .panel-more { transition: opacity .38s var(--ease); }
  .strip[data-open] .panel-copy { transition-delay: .06s; }
  .strip[data-open] .panel-more { transition-delay: .12s; }
}
@media (hover: hover) and (pointer: fine) {
  .panel img { transition: transform .8s var(--ease); }
  .panel.is-open img { transform: scale(1.03); }
  .panel:hover .panel-more::before { width: 32px; }
}
.panel:focus-visible { outline: 2px solid var(--paper); outline-offset: -4px; }

/* A phone gets no accordion. Tapping to expand and tapping again to follow is
   a worse deal than simply showing every tile, so the strip becomes a grid of
   two and each appliance keeps its name. */
@media (max-width: 899px) {
  /* A phone ignores the track list entirely and lays the row out as tiles. */
  .strip, .strip[data-open] { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr) !important; transition: none; }
  .panel { min-height: 0; aspect-ratio: 3 / 4; }
  .strip[data-open] .panel-body > h3,
  .strip[data-open] .panel.is-open .panel-body > h3 { opacity: 1; }
  .panel-copy, .panel-more { display: none; }
  .panel-body { padding: 16px; }
  .panel-body h3 { font-size: 19px; line-height: 1.2; }
}

/* The group heading that sits over a strip. */
.strip-label { padding-inline: var(--edge); margin-bottom: 16px; }
.strip-set + .strip-set { margin-top: clamp(30px, 4vw, 54px); }

/* ------------------------------------------------- Registration compare ---
   The signature interaction: two plates on one fixed frame, in register. */
/* 4/2.1 rather than 4/3: 70% of the old height, 15% off the top and 15% off
   the bottom. It also happens to match the supplied photography, which runs
   about 1.9:1 - the old 4/3 frame was cropping 30% of each image's WIDTH away
   to fill a box the photographs were never that tall for. */
.reg { position: relative; --pos: 50%; aspect-ratio: 4 / 2.1; overflow: hidden; background: var(--black); touch-action: none; cursor: ew-resize; user-select: none; }
.reg img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.reg .reg-after { clip-path: inset(0 0 0 var(--pos)); }
.reg-line { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 1px; margin-left: -.5px; background: var(--paper); border: 0; padding: 0; cursor: ew-resize; }
.reg-line::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 34px; height: 34px;
  margin: -17px 0 0 -17px; border: 1px solid var(--paper); border-radius: 50%;
  background: rgba(10,10,10,.35); backdrop-filter: blur(2px);
}
.reg-line:focus-visible { outline: 2px solid var(--paper); outline-offset: 4px; }
.reg-tag {
  position: absolute; bottom: 0; z-index: 2; pointer-events: none;
  max-width: 46%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 11.5px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
  background: var(--black); color: var(--paper); padding: 7px 12px;
}
.reg-tag--a { left: 0; }
.reg-tag--b { right: 0; }

/* --------------------------------------------------------- Case entry ----
   A comparison frame with its record beneath it. The body had no styling at
   all until now - the label and the exit ran together on one line. */
.case-card {
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
  transition: transform .45s var(--ease);
}
.case-card .reg { flex: 0 0 auto; }
.case-card-body {
  flex: 1; display: flex; flex-direction: column;
  padding: clamp(24px, 2.6vw, 34px);
}
.case-card-body > .attest { color: var(--grey-l); margin-bottom: 12px; }
.case-card-body h3 {
  font-size: clamp(21px, 2vw, 26px); font-weight: 400;
  line-height: 1.14; letter-spacing: -.024em; margin-bottom: 12px;
}
.case-card-body p {
  font-size: 15.5px; line-height: 1.6; color: var(--grey-l);
  max-width: none; margin-bottom: clamp(20px, 2.4vw, 30px);
}
/* The exit sits on its own hairline at the foot of the entry, so entries of
   different copy lengths still line their exits up across the row. */
.case-card .more {
  margin-top: auto; padding-top: 17px; border-top: 1px solid var(--line-l);
  font-size: 12px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
  color: var(--black); display: flex; align-items: center; gap: 10px;
}
.case-card .more::after {
  content: "\2192"; font-size: 14px; letter-spacing: 0;
  transition: transform .3s var(--ease);
}

/* A frame that states an absence rather than filling it. */
.pending {
  display: flex; flex-direction: column; justify-content: center; gap: 12px;
  padding: clamp(24px, 3vw, 40px);
  border: 1px solid var(--line-l); background: var(--bone);
}
.band--dark .pending { border-color: var(--line-d); background: var(--slate); }
.pending p { font-size: 15.5px; line-height: 1.62; color: var(--grey-l); max-width: 44ch; }
.band--dark .pending p { color: var(--grey-d); }

/* ------------------------------------------------------------ WhatsApp ---
   A fixed action, deliberately the only saturated colour in the interface
   besides the review stars. It sits clear of the footer on a phone and
   collapses to its mark below 560px, where a label would crowd the thumb. */
.wa {
  position: fixed; z-index: 60; right: clamp(16px, 2.5vw, 30px); bottom: clamp(16px, 2.5vw, 30px);
  display: inline-flex; align-items: center; gap: 10px;
  padding: 11px 17px 11px 13px; border-radius: 999px;
  background: #25d366; color: #0a0a0a; text-decoration: none;
  font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  box-shadow: 0 6px 22px rgba(10, 10, 10, .28);
}
.wa svg { flex: 0 0 auto; }
.wa-dot {
  width: 7px; height: 7px; border-radius: 50%; background: #0a0a0a;
  flex: 0 0 auto; margin-right: -3px;
}
/* The dot is static. It was pulsing, which simulates a liveness nothing here
   actually measures - no one knows whether the practitioner is at his phone.
   A steady marker beside the label is the honest version. */
@media (prefers-reduced-motion: no-preference) {
  .wa { transition: transform .2s ease, box-shadow .2s ease; }
}
@media (hover: hover) and (pointer: fine) {
  .wa:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(10, 10, 10, .34); }
}
.wa:active { transform: scale(.97); }
.wa:focus-visible { outline: 2px solid var(--paper); outline-offset: 3px; }
/* The label stays on a phone: the pill is what makes the action legible, and
   a bare green circle is a guess. Only the scale comes down. */
@media (max-width: 560px) {
  .wa { padding: 13px 17px 13px 14px; gap: 8px; font-size: 11px; }  /* 45px tall: past the 44px tap minimum */
  .wa svg { width: 19px; height: 19px; }
}

/* --------------------------------------------------------------- Posts ---
   An article card: plate, date, title, one line, exit. Same shape as the case
   entry, so the two reading surfaces on the site behave alike. */
.posts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
.post {
  display: flex; flex-direction: column; background: var(--paper);
  text-decoration: none; color: inherit;
  border: 1px solid var(--line-l);
  transition: background .45s var(--ease);
}
.band--bone .post { background: transparent; }
.post-plate { position: relative; overflow: hidden; aspect-ratio: 16 / 10; background: var(--slate); }
.post-plate img { width: 100%; height: 100%; object-fit: cover; display: block; }
.post-body { flex: 1; display: flex; flex-direction: column; padding: clamp(20px, 2.2vw, 30px); }
.post-body > .attest { color: var(--grey-l); margin-bottom: 11px; }
.post-body h3 {
  font-size: clamp(18px, 1.55vw, 21px); font-weight: 400;
  line-height: 1.24; letter-spacing: -.02em; margin-bottom: 10px;
}
/* Clamped so a three-line title cannot shove one card's standfirst out of
   line with its neighbours'. */
.post-body p {
  font-size: 15px; line-height: 1.55; color: var(--grey-l);
  max-width: none; margin-bottom: 22px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.post .more {
  margin-top: auto; padding-top: 15px; border-top: 1px solid var(--line-l);
  font-size: 12px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
  display: flex; align-items: center; gap: 9px;
}
.post .more::after { content: "\2192"; font-size: 14px; letter-spacing: 0; transition: transform .3s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .post-plate img { transition: transform .8s var(--ease); }
  .post:hover { background: rgba(10, 10, 10, .028); }
  .post:hover .post-plate img { transform: scale(1.04); }
  .post:hover .more::after { transform: translateX(6px); }
}
.post:focus-visible { outline: 2px solid var(--black); outline-offset: -3px; }
@media (max-width: 900px) { .posts { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .posts { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- Prose ---
   Long-form article body. The only place on the site where running headings
   and paragraphs stack for several screens, so it sets its own rhythm. */
.prose > * + * { margin-top: 20px; }
.prose p { font-size: 17px; line-height: 1.72; max-width: 68ch; }
.prose h2 {
  font-size: clamp(24px, 2.6vw, 33px); font-weight: 300; line-height: 1.16;
  letter-spacing: -.024em; margin-top: clamp(38px, 4.4vw, 62px);
}
.prose h3 {
  font-size: clamp(19px, 1.8vw, 23px); font-weight: 500; line-height: 1.25;
  letter-spacing: -.015em; margin-top: clamp(28px, 3vw, 40px);
}
.prose h2 + p, .prose h3 + p { margin-top: 14px; }
.prose ul, .prose ol { padding-left: 0; list-style: none; max-width: 68ch; }
.prose ol { counter-reset: n; }
.prose li { position: relative; padding-left: 26px; font-size: 17px; line-height: 1.62; color: var(--grey-l); }
.prose li + li { margin-top: 10px; }
.prose ul li::before { content: "\2014"; position: absolute; left: 0; color: var(--grey-l); }
.prose ol li { counter-increment: n; }
.prose ol li::before {
  content: counter(n, decimal-leading-zero); position: absolute; left: 0;
  font-size: 11px; font-weight: 500; letter-spacing: .1em; color: var(--grey-l); top: .35em;
}
.prose-figure { margin-top: clamp(30px, 3.4vw, 46px); }
.prose-figure img { width: 100%; height: auto; display: block; }

/* ----------------------------------------------------------- Signature ---
   The practitioner's own hand, replacing the drawn seal. It is the one mark
   on the site that is his rather than the system's, so it is given room and
   nothing else shares the line. */
.signature { display: block; width: clamp(180px, 22vw, 290px); height: auto; opacity: .92; }

/* ---------------------------------------------------------------- Seal ---
   Drawn, not a glyph. The attestation stamp. */
.seal { width: 74px; height: 74px; color: currentColor; opacity: .85; }
.seal circle, .seal path, .seal line { vector-effect: non-scaling-stroke; }

/* ------------------------------------------------------------ Citations --- */
.cite { display: grid; gap: 4px; padding: 22px 0; border-bottom: 1px solid var(--line-l); }
.band--dark .cite { border-color: var(--line-d); }
.cite-src { font-size: 12px; font-weight: 500; letter-spacing: .05em; color: var(--grey-l); }
.band--dark .cite-src { color: var(--grey-d); }
.cite-ttl { font-size: 17px; font-weight: 400; line-height: 1.4; max-width: 74ch; letter-spacing: -.01em; }
.cite-aut { font-size: 14.5px; color: var(--grey-l); }
.band--dark .cite-aut { color: var(--grey-d); }

/* --------------------------------------------------------------- Header --- */
.masthead {
  position: sticky; top: 0; z-index: 60;
  background: var(--black); color: var(--paper);
  border-bottom: 1px solid var(--line-d);
}
.masthead-in {
  max-width: var(--wide); margin-inline: auto; padding: 14px var(--edge);
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.mark { display: flex; align-items: center; gap: 14px; }
.mark img { height: 42px; width: auto; filter: invert(1); }
.mark span { font-size: 12px; font-weight: 400; letter-spacing: .06em; color: var(--grey-d); white-space: nowrap; }

/* Desktop gets a real nav. The full-screen index is the phone's way in, not
   the desktop's — hiding seven destinations behind a button costs a visitor
   who has no reason to go looking. */
.nav { display: flex; align-items: center; gap: clamp(14px, 1.5vw, 26px); }
.nav a {
  font-size: 10px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(250, 250, 250, .74); white-space: nowrap; padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.nav a:hover { color: var(--paper); }
.nav a[aria-current="page"] { color: var(--paper); border-bottom-color: var(--paper); }

.masthead-act { display: flex; align-items: center; gap: clamp(14px, 2.5vw, 34px); flex: 0 0 auto; }
.masthead-act .act { padding-bottom: 7px; }

.burger { display: none; background: none; border: 0; padding: 6px; color: var(--paper); cursor: pointer; line-height: 0; }

/* The booking action is carried by the index on a phone, not the masthead --
   at that width it crowded the logo and left the burger nowhere to sit. */
.index-act { display: none; }
@media (max-width: 720px) {
  .masthead-act .act { display: none; }
  .index-act {
    display: inline-block; margin-bottom: clamp(24px, 5vw, 36px);
    font-size: 13px; font-weight: 500; letter-spacing: .11em; text-transform: uppercase;
    color: var(--paper); text-decoration: none;
    border-bottom: 1px solid var(--paper); padding-bottom: 8px;
  }
}

/* Full-screen index, not a dropdown. */
.index-menu {
  position: fixed; inset: 0; z-index: 70; background: var(--black); color: var(--paper);
  display: none; flex-direction: column; padding: 16px var(--edge) 40px; overflow-y: auto;
}
body.menu-open { overflow: hidden; }
body.menu-open .index-menu { display: flex; }
.index-head { display: flex; align-items: center; justify-content: space-between; padding-bottom: 28px; }
.index-close { background: none; border: 0; color: var(--paper); padding: 6px; cursor: pointer; line-height: 0; }
.index-list { border-top: 1px solid var(--line-d); }
.index-list a {
  display: flex; align-items: baseline; gap: 16px;
  padding: 17px 0; border-bottom: 1px solid var(--line-d);
  font-size: 19px; font-weight: 300; letter-spacing: -.02em;
}
.index-list a .n { font-size: 12px; font-weight: 500; letter-spacing: .1em; color: var(--grey-d); min-width: 26px; }
.index-foot { margin-top: auto; padding-top: 34px; display: grid; gap: 12px; }

/* --------------------------------------------------------------- Footer --- */
.colophon { background: var(--black); color: var(--grey-d); padding-block: clamp(56px, 7vw, 96px) 28px; }
.colophon-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr 1.4fr; gap: var(--gap); padding-bottom: 54px; }
.colophon img.logo { height: 56px; width: auto; filter: invert(1); margin-bottom: 20px; }
.colophon h2 { font-size: 12px; font-weight: 500; letter-spacing: .13em; text-transform: uppercase; color: var(--paper); margin-bottom: 18px; }
.colophon a:hover { color: var(--paper); }
.colophon nav { display: grid; gap: 11px; }
.colophon nav a, .colophon .contact a, .colophon .contact span { font-size: 14.5px; line-height: 1.55; }
.colophon .contact { display: grid; gap: 11px; }
.colophon .contact b { font-weight: 500; color: var(--paper); }
.colophon-base {
  border-top: 1px solid var(--line-d); padding-top: 24px;
  display: flex; justify-content: space-between; gap: 10px 30px; flex-wrap: wrap;
  font-size: 11.5px; font-weight: 400; letter-spacing: .03em;
  color: rgba(250,250,250,.4);
}
.colophon-base a { border-bottom: 1px solid rgba(250,250,250,.3); }
.colophon-base a:hover { color: var(--paper); }

/* ---------------------------------------------------------------- Forms --- */
.form { display: grid; grid-template-columns: 1fr 1fr; gap: 26px var(--gap); }
.field { display: grid; gap: 9px; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: 12px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--grey-d); }
.field input, .field select, .field textarea {
  width: 100%; background: transparent; color: var(--paper);
  border: 0; border-bottom: 1px solid var(--line-d); border-radius: 0;
  padding: 9px 0; font-size: 15px;
  transition: border-color .35s var(--ease);
}
.field textarea { resize: vertical; min-height: 92px; }
.field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--grey-d) 50%), linear-gradient(135deg, var(--grey-d) 50%, transparent 50%); background-position: calc(100% - 9px) 52%, calc(100% - 4px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }
.field select option { background: var(--black); color: var(--paper); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--paper); }
.field input::placeholder, .field textarea::placeholder { color: rgba(250,250,250,.32); }

.form--onLight .field label { color: var(--grey-l); }
.form--onLight .field input, .form--onLight .field select, .form--onLight .field textarea { color: var(--black); border-color: var(--line-l); }
.form--onLight .field input:focus, .form--onLight .field select:focus, .form--onLight .field textarea:focus { border-color: var(--black); }
.form--onLight .field input::placeholder, .form--onLight .field textarea::placeholder { color: rgba(10,10,10,.3); }
.form--onLight .field select option { background: var(--paper); color: var(--black); }

.form-foot { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 22px; flex-wrap: wrap; padding-top: 6px; }
.submit {
  background: none; border: 0; cursor: pointer; padding: 0 0 9px;
  font-size: 12.5px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  position: relative; color: inherit;
}
.submit::before, .submit::after { content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%; }
.submit::before { background: currentColor; opacity: .3; }
.submit::after { background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform .6s var(--ease); }
.submit:hover::after, .submit:focus-visible::after { transform: scaleX(1); }
.submit[disabled] { opacity: .45; cursor: wait; }
.status { grid-column: 1 / -1; font-size: 13px; margin: 0; }
.status--ok { color: var(--paper); }
.status--err { color: #ff8a7a; }
.form--onLight .status--ok { color: var(--black); }
.form--onLight .status--err { color: #b3261e; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* Present to a screen reader, absent to the eye. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* -------------------------------------------------------------- Details --- */
.folio { border-top: 1px solid var(--line-l); }
.band--dark .folio { border-color: var(--line-d); }
.folio details { border-bottom: 1px solid var(--line-l); }
.band--dark .folio details { border-color: var(--line-d); }
.folio summary {
  list-style: none; cursor: pointer; padding: 22px 46px 22px 0; position: relative;
  font-size: clamp(16px, 1.7vw, 19px); font-weight: 400; letter-spacing: -.015em;
}
.folio summary::-webkit-details-marker { display: none; }
.folio summary::after,
.folio summary::before {
  content: ""; position: absolute; right: 6px; top: 50%; background: currentColor;
}
.folio summary::before { width: 13px; height: 1px; margin-top: -.5px; }
.folio summary::after { width: 1px; height: 13px; margin: -6.5px 6px 0 0; transition: transform .4s var(--ease); }
.folio details[open] summary::after { transform: scaleY(0); }
.folio-body { padding: 0 0 28px; max-width: var(--read); font-size: 15.5px; line-height: 1.65; color: var(--grey-l); }
.band--dark .folio-body { color: var(--grey-d); }
.folio-body p + p { margin-top: .85em; }
.folio-body ul { display: grid; gap: 7px; margin-top: 12px; }
.folio-body li { padding-left: 17px; position: relative; }
.folio-body li::before { content: ""; position: absolute; left: 0; top: .72em; width: 7px; height: 1px; background: currentColor; opacity: .55; }

/* ----------------------------------------------------------------- Grid --- */
.cols { display: grid; gap: var(--gap); }
.cols--2 { grid-template-columns: repeat(2, 1fr); }
.cols--3 { grid-template-columns: repeat(3, 1fr); }
.cols--4 { grid-template-columns: repeat(4, 1fr); }
.cols--tight { gap: 1px; }

/* ------------------------------------------------------------- Marquee ---
   The one place the reference's running line survives, rebuilt as a record
   strip rather than a slogan. */
.ticker { overflow: hidden; border-block: 1px solid var(--line-d); background: var(--black); color: var(--paper); }
.ticker-track { display: flex; width: max-content; }
@media (prefers-reduced-motion: no-preference) {
  .ticker-track { animation: run 64s linear infinite; will-change: transform; }
  .ticker:hover .ticker-track { animation-play-state: paused; }
}
@keyframes run { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.ticker::-webkit-scrollbar { display: none; }
.ticker-track > span {
  display: inline-flex; align-items: center; gap: 22px; padding: 15px 22px;
  font-size: 12px; font-weight: 500; letter-spacing: .1em; 
  color: var(--grey-d); white-space: nowrap;
}
.ticker-track > span b { font-weight: 500; color: var(--paper); }

/* ----------------------------------------------------- Browser surfaces ---
   The parts not drawn here still carry the design. */
::selection { background: var(--black); color: var(--paper); }
.band--dark ::selection, .hero ::selection, .colophon ::selection { background: var(--paper); color: var(--black); }
:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
html { scrollbar-color: #3a3a3a var(--black); scrollbar-width: thin; caret-color: currentColor; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--black); }
::-webkit-scrollbar-thumb { background: #333; }
::-webkit-scrollbar-thumb:hover { background: #4a4a4a; }
a[href]:not(.act):not(.ledger-row) { text-underline-offset: .22em; text-decoration-thickness: 1px; }
.link { border-bottom: 1px solid currentColor; padding-bottom: 1px; transition: opacity .3s; }
.link:hover { opacity: .6; }

/* Plates resolve into place — the drawn rule grammar applied to material. */
@media (prefers-reduced-motion: no-preference) {
  img.is-armed {
    opacity: 0; filter: blur(12px); transform: scale(1.025);
    transition: opacity .9s var(--ease), filter .9s var(--ease), transform 1.05s var(--ease);
    will-change: opacity, filter, transform;
  }
  img.is-armed.is-resolved { opacity: 1; filter: blur(0); transform: none; }
}

/* Text settles with the rule: a short rise from an already-legible offset,
   staggered down the group so a ledger reads as a list being filed. */
   The classes are temporary: once the rise has finished script removes them,
   so a lifted element goes back to its own transform and transition (a case
   card keeps its hover lift, a ledger row its hover wash).

   Keyed to [data-lift], which is what the pages actually carry. It was once
   keyed to a .lift class that no page used, so it never ran. */
@media (prefers-reduced-motion: no-preference) {
  [data-lift].is-lift-armed { opacity: 0; transform: translateY(18px); }
  [data-lift].is-lift-armed.is-lifted {
    opacity: 1; transform: none;
    transition: opacity .7s var(--ease), transform .7s var(--ease);
  }
}

/* Between pages: the ground closes over the page as a link is followed and
   opens again on the next one. Record Black, because the masthead is black on
   every page and the veil reads as the masthead extending down. It never takes
   a pointer, and with reduced motion there is none. */
@media (prefers-reduced-motion: no-preference) {
  body::before {
    content: ""; position: fixed; inset: 0; z-index: 9999;
    background: var(--black); pointer-events: none;
    opacity: 0; animation: veil-open .75s var(--ease) both;
  }
  body.is-leaving::before { animation: none; opacity: 1; transition: opacity .3s ease; }
}
@keyframes veil-open { from { opacity: 1; } to { opacity: 0; } }

/* ---------------------------------------------------------- Interaction --
   Under 250ms for anything the visitor drives, ease for hover, ease-out for
   entrances. Hover states are gated on a real pointer so nothing latches on a
   touch screen. */
@media (hover: hover) and (pointer: fine) {
  a.ledger-row:hover { background: rgba(10, 10, 10, .035); }
  .band--dark a.ledger-row:hover { background: rgba(250, 250, 250, .05); }
  a.ledger-row:hover > * { transform: translateX(10px); }
  .case-card:hover .reg img { transform: scale(1.02); }
  .case-card:hover { transform: translateY(-3px); }
  .case-card:hover .more::after { transform: translateX(6px); }
}
a.ledger-row > * { transition: transform .25s ease; }
.case-card .reg img { transition: transform .4s ease; }

/* A pressed control should acknowledge the press. */
.act:active, .submit:active, .quote-btn:active { transform: scale(.97); }
.act, .submit { transition: transform .12s ease; }

/* The seal turns a quarter of a degree per hover — the only ornament that
   moves, and only when pointed at. */
@media (hover: hover) and (pointer: fine) {
  .seal { transition: transform 1.2s var(--ease), opacity .3s ease; }
  .seal:hover { transform: rotate(8deg); opacity: 1; }
}

/* ---------------------------------------------------------- Tap targets ---
   A finger is not a cursor. On a touch device every standalone action grows
   to at least 44px of hittable height, and the padding that buys it is
   cancelled by an equal negative margin so nothing on the page moves.

   Inline links inside running prose are deliberately left alone: expanding
   them would have them stealing taps from the line above and below, and a
   link in a sentence is exempt from the target-size rule for that reason. */
@media (pointer: coarse) {
  /* The primary action. Its two rules are pinned to the bottom edge, which
     padding-top leaves exactly where it was. */
  .act { padding-top: 15px; margin-top: -15px; }

  .colophon nav a,
  .colophon .contact a {
    display: inline-block;
    padding-block: 11px; margin-block: -11px;
  }

  /* A link inside a record line: grown vertically only, so it cannot reach
     across into its neighbours. */
  .attest a { position: relative; }
  .attest a::after { content: ""; position: absolute; inset: -15px 0; }

  /* Form buttons are the end of a long task; they get the full target. */
  .submit { min-height: 44px; }

  /* The index menu's phone and email are the primary way to reach the
     practice on a phone, so they are actions, not inline links. */
  .index-foot .link {
    display: inline-block;
    padding-block: 12px; margin-block: -12px;
  }
}

/* -------------------------------------------------------------- Reveals ---
   Deliberately only the rules move. Content is visible by default. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ============================================================ Breakpoints = */
@media (min-width: 1321px) {
  /* Where the nav occupies this row, the descriptor would squeeze it; the
     nav says what the site contains far better than a tagline does. */
  .mark span { display: none; }
}

@media (max-width: 1320px) {
  .nav { display: none; }
  .burger { display: block; }
}

@media (max-width: 1180px) {
  .colophon-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; min-height: 0; }
  .hero-media { height: 66vw; max-height: 480px; order: -1; }
  .hero-media::after { background: linear-gradient(0deg, var(--black) 0%, rgba(10,10,10,.35) 38%, transparent 72%); }
  .hero-text { padding: var(--gap) var(--edge) clamp(40px, 8vw, 64px); }
  .split, .split--wide, .split--narrow { grid-template-columns: 1fr; }
  /* Once a split stacks, a heading that lives in the SECOND column would land
     underneath the thing it introduces. Send it back to the top, so the order
     stays label -> heading -> content on a phone as well. */
  .split--lead-last > :nth-child(2) { order: -1; }
  .cols--4 { grid-template-columns: repeat(2, 1fr); }
  .ledger-row { grid-template-columns: 54px 1fr; row-gap: 10px; }
  .ledger-row > .val { grid-column: 2; }
  .split--contact { grid-template-columns: 1fr; }
  .form { grid-template-columns: 1fr; }
}

/* A phone has no room for a label column beside its value. Every ledger
   variant stacks: the index or term takes its own line above the entry it
   belongs to. The variants carry (0,2,0) specificity, so they have to be
   named here or they keep their desktop tracks. */
@media (max-width: 680px) {
  .ledger-row,
  .ledger--narrow .ledger-row,
  .ledger--defs .ledger-row,
  .ledger--links .ledger-row { grid-template-columns: 1fr; column-gap: 0; row-gap: 7px; }
  /* .ledger--narrow .ledger-row > .val is (0,3,0) and pins the value to column
     two; left alone it forces an implicit second column back into a grid that
     now has only one track. Every variant has to be named at this weight. */
  .ledger-row > .idx,
  .ledger-row > .term,
  .ledger-row > .val,
  .ledger--narrow .ledger-row > .idx,
  .ledger--narrow .ledger-row > .term,
  .ledger--narrow .ledger-row > .val { grid-column: 1; max-width: none; }
  .ledger--defs .ledger-row { padding: 22px 0; }
}

@media (max-width: 700px) {
  /* The descriptor collided with the action on a phone; the logo carries the
     name on its own at this width. */
  .mark span { display: none; }
}

@media (max-width: 620px) {
  body { font-size: 14.5px; }
  .cols--2, .cols--3, .cols--4 { grid-template-columns: 1fr; }
  .colophon-grid { grid-template-columns: 1fr; }
  .ledger-row { grid-template-columns: 1fr; }
  .ledger-row > .val { grid-column: 1; }
  .record { gap: 5px 16px; }
}

/* =====================================================================
   HOME · THE OPENING
   A white page with his own signature written slowly across it, then his
   name. Scrolling raises the portrait up over it like a curtain: the white
   page stays pinned underneath and recedes as it is covered.

   Script writes three numbers, and the stylesheet does everything else:
     --o  how far the white page has been covered   (0 → 1)
     --q  how far the portrait has risen into place (0 → 1, the same travel)
     --p  how far the portrait has scrolled away     (0 → 1)
   With no script, or with reduced motion, they rest at 0 / 1 / 0 and the two
   sections simply sit one above the other, complete.
   ===================================================================== */
.opening { --mh: 71px; position: relative; }

.intro {
  --o: 0;
  --slow: 1;        /* the signature at its traced timing, about 2.8s */
  --sig-lead: 6.75; /* seconds into the sequence when the signature starts */
  position: sticky; top: var(--mh); z-index: 0;
  /* A full screen: the white page is the whole first view. The arrow at its
     foot is the invitation to scroll. */
  height: calc(100svh - var(--mh));
  min-height: 460px;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper); color: var(--black);
  overflow: hidden;
}
.intro ::selection { background: var(--black); color: var(--paper); }
.intro-in {
  width: 100%; padding-inline: var(--edge);
  display: grid; place-items: center;
  transform: translate3d(0, calc(var(--o) * -8svh), 0) scale(calc(1 - var(--o) * .08));
  opacity: calc(1 - var(--o) * 1.15);
}
/* The phrase and the name occupy the same line, one after the other, so
   the eye never has to move: the phrase clears and the name is built where
   it stood. */
.intro-phrase, .intro-lockup { grid-area: 1 / 1; margin: 0; text-align: center; }
.intro-phrase {
  font-size: clamp(18px, 2.5vw, 42px); font-weight: 300; line-height: 1.35;
  letter-spacing: .24em; text-transform: uppercase; white-space: nowrap;
  display: flex; flex-wrap: wrap; gap: 0 .5em; justify-content: center;
}
.intro-lockup { position: relative; font-weight: 300; line-height: 1.2; }
.intro-name {
  display: flex; justify-content: center; gap: 0 .34em;
  font-size: clamp(28px, 4.2vw, 72px); letter-spacing: .26em; text-transform: uppercase; white-space: nowrap;
}
/* Tracking hangs after the last letter; pull it back so the lockup centres
   on its letters, not on its letters plus one space. */
.intro-name { margin-right: -.26em; }
.intro-phrase { margin-right: -.24em; }
/* On a phone the phrase is set on two lines, NATURAL SMILE / MAKEOVER, so it
   can stay large rather than shrink to fit one; the name tightens a little. */
@media (max-width: 599px) {
  .intro-phrase { font-size: clamp(20px, 6vw, 28px); letter-spacing: .2em; margin-right: -.2em; }
  .intro-phrase > .iw:last-child { flex-basis: 100%; }
  .intro-name { font-size: clamp(24px, 7.2vw, 34px); letter-spacing: .2em; margin-right: -.2em; }
}

/* His signature is written above the name. It is absolutely placed so the
   name sits on the true centre of the screen whether or not the signature
   has been drawn yet. */
.intro-sig {
  position: absolute; left: 50%; bottom: calc(100% + clamp(10px, 1.6vw, 24px));
  width: clamp(300px, 52vw, 900px); transform: translateX(-50%);
}
@media (max-width: 899px) { .intro-sig { width: min(90vw, 560px); } }
.intro .sig-ink { fill: var(--black); }
.sig-draw { display: block; width: 100%; height: auto; overflow: visible; }

/* Word weights: the light words in secondary ink, the built word in black. */
.iw { display: inline-block; position: relative; }
.iw-light { color: var(--grey-l); font-weight: 300; }
.iw-build { color: var(--black); font-weight: 600; }

/* A built letter is two copies stacked: a hairline ghost (weight 200) that
   flashes in first, and the bold letter that settles over it. */
.ib-l { display: inline-block; position: relative; }
.ib-g { position: absolute; left: 0; top: 0; font-weight: 200; color: var(--grey-d); opacity: 0; }
.ib-f { display: inline-block; }
/* The construction lines: a hairline above the capitals and one at the
   baseline, drawn across the word while it is built, then gone. */
.ib-rule {
  position: absolute; left: -.4em; right: -.2em; height: 1px;
  background: rgba(10, 10, 10, .5); transform-origin: left center;
  transform: scaleX(0); opacity: 0; pointer-events: none;
}
.ib-rule--t { top: .02em; }
.ib-rule--b { bottom: .12em; }
/* The caret: a vertical hairline that runs along the letters as they land. */
.ib-caret {
  position: absolute; top: -.3em; bottom: -.3em; left: 0; width: 1px;
  background: var(--black); opacity: 0; pointer-events: none;
}

/* The scroll cue: a drawn arrow inside a drawn ring, 1px like every icon in
   the system. The ring draws itself once, the arrow keeps sinking towards the
   portrait, and a tap takes the visitor there. It stops being there the
   moment the page moves. */
.intro-cue {
  position: absolute; left: 50%; bottom: clamp(22px, 4.5svh, 44px);
  width: 56px; height: 56px; margin-left: -28px;
  color: var(--black); display: block;
  opacity: calc(1 - var(--o) * 4);
}
.intro-cue svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* On a phone the WhatsApp action spans the foot of the screen; the arrow
   stands clear above it. */
@media (max-width: 899px) { .intro-cue { bottom: 96px; } }
.intro-cue-ring { transform: rotate(-90deg); transform-box: fill-box; transform-origin: center; stroke: var(--line-l); }
.intro-cue-arrow { stroke: var(--black); }
@media (hover: hover) and (pointer: fine) {
  .intro-cue-ring { transition: stroke .3s ease; }
  .intro-cue:hover .intro-cue-ring { stroke: var(--black); }
}
.intro-cue:focus-visible { outline: 1px solid var(--black); outline-offset: 6px; border-radius: 50%; }

/* With no script, or with reduced motion, the phrase never shows: the page
   is the finished lockup - signature and name - from the first frame. */
.intro-phrase { visibility: hidden; }

/* ---- the sequence --------------------------------------------------------
   Every delay below is measured from the moment .is-playing is added, so
   removing and re-adding the class replays the whole thing from the start.
     .4s   NATURAL fades in
     1s    SMILE is built between its hairlines, letter by letter
     1.75s MAKEOVER fades in
     3.9s  the phrase clears, left to right
     5.15s DEEN is built where the phrase stood
     5.95s EMAD fades in beside it
     6.75s his signature is written above the name, and stays
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .intro.is-armed .intro-phrase { visibility: visible; }

  .intro.is-armed:not(.is-playing) .iw,
  .intro.is-armed:not(.is-playing) .ib-f { opacity: 0; }
  .intro.is-armed:not(.is-playing) .intro-cue-ring { stroke-dasharray: 1 2; stroke-dashoffset: 1; }
  .intro.is-armed:not(.is-playing) .intro-cue-arrow { opacity: 0; }
  .intro.is-armed:not(.is-playing) .sig-pen { opacity: 0; }

  /* light words: in, and (in the phrase) out again */
  .intro.is-playing .intro-phrase .iw-light {
    animation: iw-in .9s var(--ease) var(--d) both, iw-out .7s ease var(--x) forwards;
  }
  .intro.is-playing .intro-name .iw-light { animation: iw-in 1s var(--ease) var(--d) both; }
  /* built words: the word is present from its start, its letters land one by one */
  .intro.is-playing .intro-phrase .iw-build {
    animation: iw-show 0s linear var(--d) both, iw-out .7s ease var(--x) forwards;
  }
  .intro.is-playing .intro-name .iw-build { animation: iw-show 0s linear var(--d) both; }
  .intro.is-playing .ib-rule { animation: ib-rule 1.3s var(--ease) var(--d) both; }
  .intro.is-playing .ib-rule--b { animation-delay: calc(var(--d) + .08s); }
  .intro.is-playing .ib-caret { animation: ib-caret .95s cubic-bezier(.4, 0, .4, 1) calc(var(--d) + .2s) both; }
  .intro.is-playing .ib-g { animation: ib-ghost .42s ease calc(var(--d) + .16s + var(--i) * .13s) both; }
  .intro.is-playing .ib-f { animation: ib-land .3s var(--ease) calc(var(--d) + .3s + var(--i) * .13s) both; }

  .intro.is-playing .intro-cue-ring { stroke-dasharray: 1 2; animation: intro-ring 1.4s var(--ease) 1.4s both; }
  .intro.is-playing .intro-cue-arrow { animation: intro-sink 2.2s cubic-bezier(.45, 0, .55, 1) 2.2s infinite both; }

  /* Each pen stroke is a path with pathLength 1, so one dash of length 1
     travelling to offset 0 draws it, whatever its real length. The easing is
     a hand's: a quick start and a settle at the end of the stroke. */
  .intro.is-armed .sig-draw:not(.is-signed) .sig-pen { stroke-dasharray: 1 2; stroke-dashoffset: 1; }
  .intro.is-playing .sig-draw:not(.is-signed) .sig-pen {
    animation: sig-pen calc(var(--for) * var(--slow)) cubic-bezier(.5, .05, .3, 1)
               calc(var(--at) * var(--slow) + var(--sig-lead) * 1s) both;
  }
}
@keyframes iw-in   { from { opacity: 0; } to { opacity: 1; } }
@keyframes iw-out  { from { opacity: 1; } to { opacity: 0; } }
@keyframes iw-show { from { opacity: 1; } to { opacity: 1; } }
@keyframes ib-rule {
  0%   { transform: scaleX(0); opacity: 1; }
  35%  { transform: scaleX(1); opacity: 1; }
  75%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}
@keyframes ib-caret {
  0%   { left: 0;    opacity: 0; }
  8%   { opacity: 1; }
  85%  { left: 100%; opacity: 1; }
  100% { left: 100%; opacity: 0; }
}
@keyframes ib-ghost {
  0%   { opacity: 0; }
  30%  { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes ib-land {
  from { opacity: 0; clip-path: inset(0 100% 0 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}
@keyframes intro-ring { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes intro-sink {
  0%   { transform: translateY(-7px); opacity: 0; }
  25%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { transform: translateY(8px); opacity: 0; }
}
@keyframes sig-pen {
  0%   { stroke-dashoffset: 1; opacity: 0; }
  1%   { opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 1; }
}
/* Until it is being written, and once it has been, the signature is the plain
   outline with no mask at all - so what stays on the page is exactly his
   signature, not the traced approximation of it. */
.intro:not(.is-armed) .sig-ink,
.sig-draw.is-signed .sig-ink { mask: none; }

/* ---- the masthead turns to paper while it sits over the white page ---- */
.masthead { transition: background-color .5s var(--ease), color .5s var(--ease), border-color .5s var(--ease); }
.mark img { transition: filter .5s var(--ease); }
.masthead.is-light { background: var(--paper); color: var(--black); border-bottom-color: var(--line-l); }
.masthead.is-light .mark img { filter: none; }
.masthead.is-light .mark span { color: var(--grey-l); }
.masthead.is-light .nav a { color: rgba(10, 10, 10, .72); }
.masthead.is-light .nav a:hover,
.masthead.is-light .nav a[aria-current="page"] { color: var(--black); }
.masthead.is-light .nav a[aria-current="page"] { border-bottom-color: var(--black); }
.masthead.is-light .burger { color: var(--black); }
.masthead.is-light ::selection { background: var(--black); color: var(--paper); }

/* ---- the portrait ------------------------------------------------------ */
.sig-hero {
  --p: 0;
  --q: 1;
  position: relative; z-index: 1; overflow: hidden;
  background: var(--black); color: var(--paper);
  display: grid; grid-template-rows: 1fr auto;
  min-height: clamp(620px, calc(100svh - var(--mh)), 1040px);
}
.sig-hero ::selection { background: var(--paper); color: var(--black); }
.sig-hero-stage { grid-area: 1 / 1 / 3 / 2; position: relative; }

/* The studio backdrop is a dark grey, not our black, so the plate is faded at
   its sides and base until the photograph has no visible edge. The fade is on
   the backdrop, never cut round the figure. It comes up out of an enlargement
   as it rises, and drifts and pushes in as it leaves. */
.sig-hero-portrait {
  position: absolute; left: 50%; bottom: 0; z-index: 1;
  height: 100%; aspect-ratio: 1 / 1;
  transform-origin: 50% 30%;
  transform: translateX(-50%) translate3d(0, calc(var(--p) * 10%), 0)
             scale(calc(1 + var(--p) * .08 + (1 - var(--q)) * .2));
  opacity: calc(.3 + var(--q) * .7 - var(--p) * .6);
}
.sig-hero-portrait img {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 0;
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0%, #000 17%, #000 83%, transparent 100%),
    linear-gradient(180deg, #000 46%, transparent 86%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(90deg, transparent 0%, #000 17%, #000 83%, transparent 100%),
    linear-gradient(180deg, #000 46%, transparent 86%);
          mask-composite: intersect;
}

/* The two words sit at the height of his head, where the figure is at its
   narrowest. They close in from the edges as the portrait rises, and part
   again on the way out. Aligned to the content width, so on a large screen
   they stand on the same margins as the logo. */
.sig-hero-word {
  position: absolute; top: 25%; z-index: 2; margin: 0;
  font-weight: 200; line-height: .9; letter-spacing: -.04em; white-space: nowrap;
  font-size: clamp(44px, min(6.4vw, 11svh), 118px);
  color: var(--paper);
  opacity: calc(var(--q) * 2.2 - 1.2 - var(--p) * 1.5);
}
.sig-hero-word span { display: inline-block; }
.sig-hero-word--l {
  left: max(var(--edge), calc((100% - var(--wide)) / 2 + var(--edge)));
  transform: translate3d(calc((1 - var(--q)) * -24vw - var(--p) * 16vw), 0, 0);
}
.sig-hero-word--r {
  right: max(var(--edge), calc((100% - var(--wide)) / 2 + var(--edge)));
  transform: translate3d(calc((1 - var(--q)) * 24vw + var(--p) * 16vw), 0, 0);
}

.sig-hero-foot {
  grid-area: 2 / 1 / 3 / 2; position: relative; z-index: 4;
  width: 100%; max-width: var(--wide); margin-inline: auto;
  display: flex; justify-content: space-between; align-items: flex-end; gap: var(--gap);
  /* The floating WhatsApp action owns the bottom-right corner; the row sits
     clear above it rather than being covered by it. */
  padding: 0 var(--edge) clamp(96px, 12svh, 118px);
  opacity: calc(var(--q) * 2.5 - 1.5 - var(--p) * 1.3);
  transform: translate3d(0, calc((1 - var(--q)) * 40px), 0);
}
.sig-hero-rating { margin: 0; }

@media (max-width: 899px) {
  .sig-hero { display: block; min-height: 0; padding-bottom: clamp(44px, 10vw, 72px); }
  .sig-hero-stage { display: flex; flex-direction: column; }
  .sig-hero-portrait {
    position: relative; left: auto; bottom: auto; order: 1;
    width: 100%; height: auto; aspect-ratio: 1 / 1; max-height: 70svh;
    transform: translate3d(0, calc(var(--p) * 8%), 0)
               scale(calc(1 + var(--p) * .06 + (1 - var(--q)) * .16));
  }
  .sig-hero-portrait img {
    -webkit-mask-image: linear-gradient(180deg, #000 48%, transparent 92%);
            mask-image: linear-gradient(180deg, #000 48%, transparent 92%);
  }
  .sig-hero-word {
    position: static; order: 3; padding-inline: var(--edge);
    font-size: clamp(46px, 13.2vw, 104px);
  }
  .sig-hero-word--l { margin-top: -.55em; }
  .sig-hero-word--r { order: 4; text-align: right; }
  .sig-hero-foot {
    flex-direction: column-reverse; align-items: flex-start; gap: 22px;
    padding: clamp(30px, 7vw, 48px) var(--edge) 0;
  }
}

/* =====================================================================
   HOME · BEHIND THE SIGNATURE
   Four true things, each with one photograph. On a wide screen the frame
   holds still while the four are read past it, and each new photograph wipes
   up over the last; the chapter being read carries full ink and the others
   drop to secondary. On a phone, or with no script, each chapter simply
   carries its own photograph and nothing is pinned.
   ===================================================================== */
.behind { --mh: 71px; background: var(--paper); color: var(--black); padding-top: var(--band); }
.behind-head { padding-bottom: clamp(44px, 6vw, 96px); }
/* On a wide screen the introduction moves across to the chapter column, so
   it starts on the same line the four chapters will. */
@media (min-width: 900px) {
  .behind-head {
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    column-gap: var(--gap); align-items: end;
  }
  .behind-head > * { grid-column: 1; }
  .behind-head > .behind-intro { grid-column: 2; grid-row: 2; margin: 0 0 .5em; }
}
.behind-head .display { max-width: 11ch; }
.behind-intro {
  margin-top: 24px; max-width: 32ch;
  font-size: clamp(18px, 2vw, 23px); line-height: 1.55; font-weight: 300; letter-spacing: -.012em;
  color: var(--grey-l);
}

.behind-grid { padding-bottom: var(--band); }
.behind-list { list-style: none; margin: 0; padding: 0; }
.behind-ch + .behind-ch { margin-top: clamp(72px, 12vw, 120px); }
.behind-role {
  margin: 0 0 22px;
  font-weight: 200; font-size: clamp(50px, 7.2vw, 116px); line-height: .9; letter-spacing: -.042em;
}
.behind-copy {
  margin: 0; max-width: 36ch;
  font-size: clamp(17px, 1.45vw, 20px); line-height: 1.6; font-weight: 300;
  color: var(--grey-l);
}
.behind-more { margin-top: 44px; }

.behind-plate { aspect-ratio: 4 / 5; max-width: 520px; margin: 0 0 30px; }
.behind-media { display: none; }

/* The Master's record: a page of a diploma, signed. */
.behind-plate--record, .behind-layer--record {
  background: var(--black); color: var(--paper);
  display: flex; align-items: flex-end;
}
.behind-record { width: 100%; padding: clamp(24px, 3.2vw, 46px); }
.behind-record-sig { display: block; width: 62%; height: auto; margin-bottom: clamp(30px, 6vh, 64px); opacity: .92; }
.behind-record ol { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-d); }
.behind-record li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 18px;
  padding: clamp(14px, 1.8vh, 20px) 0; border-bottom: 1px solid var(--line-d);
  font-size: clamp(20px, 1.9vw, 30px); font-weight: 200; line-height: 1.15; letter-spacing: -.022em;
}
.behind-record li b { font-size: 12px; font-weight: 500; letter-spacing: .11em; color: var(--grey-d); }

/* No script on a wide screen: each chapter sits beside its own photograph. */
@media (min-width: 900px) {
  .behind:not(.is-armed) .behind-ch {
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    column-gap: var(--gap); align-items: center;
  }
  .behind:not(.is-armed) .behind-ch > .behind-plate { grid-row: 1 / span 5; margin: 0; }
  .behind:not(.is-armed) .behind-ch > :not(.behind-plate) { grid-column: 2; }

  /* Armed: the frame is pinned beside the list. */
  .behind.is-armed .behind-grid {
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: var(--gap);
  }
  .behind.is-armed .behind-plate { display: none; }
  .behind.is-armed .behind-media {
    display: flex; align-items: center;
    position: sticky; top: var(--mh); height: calc(100svh - var(--mh));
  }
  .behind.is-armed .behind-ch {
    min-height: calc(76svh - var(--mh)); margin: 0;
    display: flex; flex-direction: column; justify-content: center;
  }
  .behind.is-armed .behind-ch:first-child { min-height: calc(62svh - var(--mh)); justify-content: flex-start; }
  .behind.is-armed .behind-ch:last-child  { min-height: calc(92svh - var(--mh)); }
  .behind.is-armed .behind-ch:not(.is-current) .behind-role { color: var(--grey-l); }
}

.behind-frame {
  position: relative;
  height: min(calc(100svh - var(--mh) - 96px), 720px); aspect-ratio: 4 / 5; max-width: 100%;
  background: var(--black);
}
.behind-layer { position: absolute; inset: 0; overflow: hidden; }
.behind-layer img { display: block; width: 100%; height: 100%; object-fit: cover; }
.behind-count { z-index: 6; }
.behind-count b { font-weight: 500; }

/* The progress rule: a hairline beside the frame that fills as the four are
   read, drawn the way every rule on the site is drawn - from its origin. */
.behind-progress {
  position: absolute; top: 0; bottom: 0; right: -22px; width: 1px;
  background: var(--line-l);
}
.behind-progress::after {
  content: ""; position: absolute; inset: 0; background: var(--black);
  transform-origin: top center; transform: scaleY(var(--prog, 0));
}

/* Each photograph wipes up over the one before it, and settles out of a
   slight enlargement as it does. Scrolling back retracts it downwards. */
.behind.is-armed .behind-layer { clip-path: inset(100% 0 0 0); }
.behind.is-armed .behind-layer.is-shown { clip-path: inset(0 0 0 0); }
@media (prefers-reduced-motion: no-preference) {
  .behind.is-armed .behind-layer { transition: clip-path 1.15s var(--ease); }
  .behind.is-armed .behind-layer img { transform: scale(1.14); transition: transform 1.7s var(--ease); }
  .behind.is-armed .behind-layer.is-shown img { transform: none; }
  .behind.is-armed .behind-role { transition: color .6s var(--ease); }
  .behind.is-armed .behind-progress::after { transition: transform .25s linear; }
}

/* ---------------------------------------------------------------- CMS ---
   Additions the dynamic site needs and the static build did not. */

/* A shorter prose rhythm for the intro block on a treatment page, where the
   text sits beside a heading rather than running the width of the page. */
.prose--tight > * + * { margin-top: 14px; }
.prose--tight p { font-size: 15.5px; line-height: 1.62; }

/* A phone number or an email standing on its own is an action, not a link in a
   sentence, so it gets a thumb-sized target. The padding is cancelled by an
   equal negative margin, so nothing on the page moves. */
@media (pointer: coarse) {
  .ledger--defs .val > a.link,
  .stack-sm > p > a.link {
    display: inline-block;
    padding-block: 12px;
    margin-block: -12px;
  }
}

/* ------------------------------------------------------- Cookie choice ---
   The EU consent notice for Google Analytics. It speaks the site's language:
   the black ground, hairlines, the uppercase letter-spaced buttons. It sits
   bottom-left, clear of the WhatsApp button, and above it on a phone. */
.consent {
  position: fixed; z-index: 70;
  left: clamp(16px, 2.5vw, 30px); bottom: clamp(16px, 2.5vw, 30px);
  width: min(390px, calc(100vw - 32px));
  padding: 20px 22px 22px;
  background: var(--black); color: var(--paper);
  border: 1px solid var(--line-d);
  box-shadow: 0 10px 40px rgba(10, 10, 10, .28);
  font-size: 13.5px; line-height: 1.55;
  opacity: 0; transform: translateY(12px);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.consent[hidden] { display: none; }
.consent.is-in { opacity: 1; transform: none; }
.consent p { margin: 0 0 16px; color: rgba(250, 250, 250, .86); }
.consent-act { display: flex; gap: 10px; }
.consent-act button {
  flex: 1; min-height: 44px; padding: 10px 14px; cursor: pointer;
  border: 1px solid var(--line-d); background: transparent; color: var(--paper);
  font: 600 11px/1 var(--face); letter-spacing: .14em; text-transform: uppercase;
}
.consent-act .consent-yes { background: var(--paper); color: var(--black); border-color: var(--paper); }
.consent-act button:focus-visible { outline: 2px solid var(--paper); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .consent-act button { transition: opacity .2s ease; }
  .consent-act button:hover { opacity: .8; }
}
.consent-act button:active { transform: scale(.97); }
@media (max-width: 560px) {
  .consent { left: 16px; right: 16px; width: auto; bottom: 80px; }
}
@media (prefers-reduced-motion: reduce) {
  .consent { transition: none; transform: none; }
}
.colophon-cookies {
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; letter-spacing: inherit; color: inherit;
  border-bottom: 1px solid rgba(250, 250, 250, .3);
}
.colophon-cookies:hover { color: var(--paper); }
