/* ==========================================================================
   WebAssure5 - app.css
   "The Agreement": the site is set as a numbered instrument. Ruled lines,
   clause numbers, ledger rows. No cards, no rounded corners, no shadows.

   Token mapping from the brand spec:
     surface.base   -> --paper      (the page, white)
     text.tertiary  -> --paper      (type on the dark band)
     text.primary   -> --ink        (#000000, headings and figures)
     text.secondary -> --ink-soft   (#271114, running copy)
     text.inverse   -> --accent     (#cbe644, FILL ONLY, never type on paper)
     surface.strong -> --band-ink   (#1b1f1d, one contrast band per page)

   Contrast rule that shapes everything below: #cbe644 on white is 1.33:1.
   The accent is therefore a block, a rule or a marker, and carries ink on top.
   It is never used as text on paper, and never as a focus ring.
   ========================================================================== */

/* ---------- 1. Fonts ---------- */
@font-face{font-family:Geomanist;src:url("../fonts/Geomanist-Regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Geomanist;src:url("../fonts/Geomanist-Medium.otf")  format("opentype");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:Geomanist;src:url("../fonts/Geomanist-Bold.otf")    format("opentype");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:Geomanist;src:url("../fonts/Geomanist-Black.otf")   format("opentype");font-weight:900;font-style:normal;font-display:swap}

/* ---------- 2. Tokens ---------- */
:root{
  --paper:#ffffff;
  --ink:#000000;
  --ink-soft:#271114;
  --muted:#5f6360;
  --accent:#cbe644;
  --band-ink:#1b1f1d;
  --rule:rgba(0,0,0,.16);
  --rule-strong:rgba(0,0,0,.42);

  --font-stack:Geomanist,"Segoe UI",system-ui,sans-serif;
  --fs-2xs:14.4px; --fs-xs:18px; --fs-sm:19.8px; --fs-md:20px;
  --fs-lg:22.4px;  --fs-xl:41.6px; --fs-2xl:48px; --fs-3xl:64px;
  --lh-tight:1; --lh-snug:1.14; --lh-base:1.4;

  --sp-1:8px; --sp-2:10px; --sp-3:12.8px; --sp-4:16px;
  --sp-5:19.2px; --sp-6:20px; --sp-7:32px;
  --gutter:var(--sp-6);
  --shell:1180px;
  --margin-col:12rem;           /* marginal notes, wide enough to read */

  --dur-instant:400ms; --dur-fast:1000ms;
  --ease:cubic-bezier(.2,.8,.2,1);

  --bar-h:60px;
  color-scheme:light;
}

/* ---------- 3. Reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:calc(var(--bar-h) + var(--sp-7))}
body{
  margin:0;background:var(--paper);color:var(--ink-soft);
  font:400 var(--fs-xs)/var(--lh-base) var(--font-stack);
  -webkit-font-smoothing:antialiased;
}
img,svg{max-width:100%;display:block}
h1,h2,h3,h4,p,ul,ol,figure,dl,fieldset{margin:0}
ul,ol{padding:0;list-style:none}
fieldset{border:0;padding:0;min-width:0}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
:target{scroll-margin-top:calc(var(--bar-h) + var(--sp-7))}
/* Class-level display rules outrank the UA [hidden] rule, so state it louder. */
[hidden]{display:none !important}

/* ---------- 4. Accessibility primitives ---------- */
/* The ring is ink, because the accent cannot clear 3:1 against paper. */
:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
.band--ink :focus-visible,.band--accent :focus-visible{outline-color:var(--paper)}
.band--accent :focus-visible{outline-color:var(--ink)}
.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}
.skip{position:fixed;top:var(--sp-2);left:var(--sp-2);z-index:99;background:var(--accent);color:var(--ink);
  border:1px solid var(--ink);padding:var(--sp-2) var(--sp-4);font-weight:700;transform:translateY(-250%)}
.skip:focus{transform:none}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:1ms !important;animation-iteration-count:1 !important;transition-duration:1ms !important}
}

/* ---------- 5. Type ---------- */
.display{font-size:clamp(var(--fs-2xl),8.6vw,var(--fs-3xl));font-weight:900;line-height:var(--lh-tight);
  letter-spacing:-.04em;color:var(--ink)}
.h1{font-size:clamp(var(--fs-xl),5.4vw,var(--fs-2xl));font-weight:900;line-height:var(--lh-snug);letter-spacing:-.035em;color:var(--ink)}
.h2{font-size:var(--fs-xl);font-weight:900;line-height:var(--lh-snug);letter-spacing:-.03em;color:var(--ink)}
.h3{font-size:var(--fs-lg);font-weight:700;line-height:var(--lh-snug);letter-spacing:-.015em;color:var(--ink)}
/* 54ch was a tight reading measure and it left the paragraphs stopping well
   short of the heading above them, so a clause read as two ragged blocks
   rather than one. 72ch is still inside the comfortable range and lands
   close to the column edge, which is what balances the block. */
.lead{font-size:var(--fs-md);line-height:var(--lh-base);max-width:72ch}
.muted{color:var(--muted)}
.caps{font-size:var(--fs-2xs);font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)}
.fine{font-size:var(--fs-2xs);color:var(--muted);line-height:1.5}
.wrap-54{max-width:54ch}
.wrap-64{max-width:64ch}
.num{font-variant-numeric:tabular-nums;font-weight:700;color:var(--ink)}

/* The marker. One phrase a page, no more. */
.mark-hl{background:linear-gradient(transparent 58%,var(--accent) 58%);padding-inline:.06em}
/* On the dark band the type is white, and a band struck through it reads as a
   deletion rather than an emphasis. Same mark, drawn as a rule under the line. */
.band--ink .mark-hl{background:none;padding-inline:0;
  text-decoration:underline;text-decoration-color:var(--accent);
  text-decoration-thickness:2px;text-underline-offset:.22em;
  text-decoration-skip-ink:none}

/* ---------- 6. Layout ---------- */
.shell{width:100%;max-width:var(--shell);margin-inline:auto;padding-inline:var(--gutter)}
.stack > * + *{margin-block-start:var(--sp-4)}
.stack-lg > * + *{margin-block-start:var(--sp-7)}
.btn-row{display:flex;flex-wrap:wrap;gap:var(--sp-4);align-items:center}
.grid{display:grid;gap:var(--sp-6)}
@media (min-width:720px){ .grid--2{grid-template-columns:1fr 1fr} }
@media (min-width:900px){ :root{--gutter:var(--sp-7); --bar-h:76px} }

/* ---------- 7. The clause ---------- */
.clause{padding-block:calc(var(--sp-7) * 1.5);border-block-start:1px solid var(--rule)}
.clause:first-of-type{border-block-start:0}
.clause__head{display:flex;align-items:baseline;gap:var(--sp-4);margin-block-end:var(--sp-7)}
.clause__no{font-size:var(--fs-2xs);font-weight:900;letter-spacing:.1em;color:var(--ink);flex:none;
  font-variant-numeric:tabular-nums}
.clause__rule{flex:1;height:1px;background:var(--ink);opacity:.28}
.clause__label{font-size:var(--fs-2xs);font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink);flex:0 1 auto}

/* Body sits in a measure, with the wide margin the number hangs in */
.clause__body{display:grid;gap:var(--sp-7)}
@media (min-width:900px){
  .clause__body{grid-template-columns:var(--margin-col) 1fr;gap:calc(var(--sp-7) * 1.25)}
  /* The marginalia holds its place while the long column scrolls past it, so
     the left of a tall clause is never a blank strip. It sits under the sticky
     clause head, and only where there is a column to hold. */
  .clause__body{align-items:start}
  .clause__body > .clause__note{grid-column:1;font-size:var(--fs-2xs);color:var(--muted);
    line-height:1.45;position:sticky;top:calc(var(--bar-h) + var(--sp-7) * 1.75)}
  .clause__body > .clause__main{grid-column:2}
  .clause__body--wide{grid-template-columns:1fr}
  .clause__body--wide > .clause__main{grid-column:1}
}
.clause__note{font-size:var(--fs-2xs);color:var(--muted);line-height:1.45}
.clause__split{display:grid;gap:var(--sp-7)}
/* A grid item's automatic minimum is its min-content width, so a nowrap
   table or a long word drags the whole track past the screen instead of
   scrolling inside its own wrapper. Nothing here wants that floor. */
.clause__body > *,.clause__split > *,.grid > *{min-width:0}
@media (min-width:900px){
  .clause__split{grid-template-columns:1fr 1fr;gap:calc(var(--sp-7) * 2)}
  /* The heading half of a split is almost always shorter than the list beside
     it, so it used to end and leave a tall blank column while the list carried
     on. The marginalia already holds its place down the far left; the heading
     does the same now, so it travels with the thing it introduces instead of
     scrolling away and leaving a hole. Sits below the sticky clause head.
     Scoped to a split inside a clause body, so the two column bands, where
     both halves are the same length, are untouched. */
  .clause__body .clause__split > :first-child{
    position:sticky;top:calc(var(--bar-h) + var(--sp-7) * 1.75);align-self:start}
}

/* ---------- 7b. Shapes ----------
   Flat geometric fields, hard edged, cropped by the viewport rather than
   drawn inside it. All decorative, all aria-hidden, none behind body copy. */
.deco{position:absolute;z-index:0;pointer-events:none}
.deco--qc{border-radius:100% 0 0 0}                      /* quarter circle */
.deco--qc-tr{border-radius:0 100% 0 0}
.deco--qc-bl{border-radius:0 0 0 100%}
.deco--wedge{clip-path:polygon(0 0,100% 0,100% 100%)}
.deco--accent{background:var(--accent)}
.deco--ink{background:var(--band-ink)}
.deco--soft{background:var(--ink-soft)}

/* ---------- 7c. Hero ---------- */
.hero{position:relative;isolation:isolate;overflow:hidden;padding-block:calc(var(--sp-7) * 1.5)}
.hero__in{position:relative;z-index:2;display:grid;gap:calc(var(--sp-7) * 1.25)}
.hero__say{max-width:22ch}
.hero__say .lead{max-width:46ch}

/* The angled field the specification sits on. Bleeds off the canvas. */
.hero__spec{position:relative;padding:var(--sp-7) 0 calc(var(--sp-7) * 1.25)}
.hero__spec > *{position:relative;z-index:1}
.hero__spec::before{
  content:"";position:absolute;z-index:0;background:var(--accent);
  inset-block:0 calc(var(--sp-7) * -2);
  inset-inline:calc(var(--gutter) * -1) calc(var(--gutter) * -1);
  clip-path:polygon(0 5%,100% 0,100% 100%,0 100%);
}
/* Mobile: the price is the point, so tighten everything above it, and pin the
   diagonal to a fixed slope so it cannot climb into the SPECIFICATION label
   when the block grows taller. */
@media (max-width:899px){
  .hero{padding-block:var(--sp-7) 0}
  .hero__in{row-gap:var(--sp-4)}
  /* display:contents dissolves the wrapper so the price can be ordered between
     the headline and the argument. Reads hook, number, reason, action. Only the
     home hero has a price to weave in; on .hero--plain the same rule dissolved
     the wrapper and left the standfirst, which has no order, sitting above the
     headline. */
  .hero:not(.hero--plain) .hero__say{display:contents}
  .hero__say > .caps{order:1}
  .hero__say > .display{order:2}
  .hero__spec{order:3}
  /* The lime field ends hard here, so the argument needs air under it. The base
     rule bleeds the field 2x --sp-7 BELOW the block, which is right on desktop
     where it runs off the canvas and wrong here where it just floats: the
     paragraph was landing nine pixels inside the green. Stop the paint at the
     block's own edge, then the block's own bottom padding plus this margin is
     the gap you actually see. */
  .hero__spec::before{inset-block-end:0}
  .hero__pitch{order:4;margin-block-start:var(--sp-7)}
  .hero__spec{padding-block:calc(var(--sp-7) * 1.5) calc(var(--sp-7) * 1.25)}
  .hero__spec::before{clip-path:polygon(0 24px,100% 0,100% 100%,0 100%)}
}
@media (min-width:900px){
  .hero{padding-block:calc(var(--sp-7) * 2.5)}
  .hero__in{grid-template-columns:1.05fr .95fr;align-items:center;gap:calc(var(--sp-7) * 2)}
  .hero__say{max-width:none}
  /* The field's left edge sits 6vw outside the box and the cut climbs back to
     it, so 4vw of padding keeps every line clear of the diagonal. */
  .hero__spec{padding:calc(var(--sp-7) * 1.5) var(--sp-7) calc(var(--sp-7) * 1.5) 4vw}
  .hero__spec::before{
    inset-block:calc(var(--sp-7) * -3) calc(var(--sp-7) * -3);
    inset-inline:-6vw -50vw;
    clip-path:polygon(6vw 0,100% 0,100% 100%,0 100%);
  }
}
/* Inner pages: title left, standfirst right, no specification field. */
.hero--plain{padding-block:calc(var(--sp-7) * 1.75) calc(var(--sp-7) * 1.25)}
@media (min-width:900px){
  .hero--plain .hero__in{grid-template-columns:1.15fr .85fr;align-items:end;gap:calc(var(--sp-7) * 2)}
}
.hero--plain .hero__say{max-width:none}

/* One shape, the same one on every inner page. A circle dropped off the top
   right corner, cropped by the canvas, washed lime so the header carries the
   brand colour without the accent ever landing under text. Earlier builds gave
   each page its own shape; the header now repeats, which is the point. */
.hero .deco--head{inset-block-start:-9vw;inset-inline-end:-6vw;width:22vw;height:22vw;
  border-radius:50%;background:color-mix(in srgb, var(--accent) 30%, var(--paper))}
@media (max-width:899px){ .hero .deco--head{width:38vw;height:38vw} }

/* ---------- 7d. Contact, asked one at a time ---------- */
/* Same shape as the brief, which slows a bot down and stops a person
   facing four boxes at once. */
.askbar{display:flex;align-items:center;gap:var(--sp-4)}
.askbar__count{font-size:var(--fs-2xs);font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.askbar__rule{flex:1;height:2px;background:var(--rule)}
.askbar__rule span{display:block;height:100%;background:var(--ink);
  transform:scaleX(0);transform-origin:left center;
  transition:transform var(--dur-instant) var(--ease)}
/* A field only a machine fills in. Off-screen rather than display:none,
   because some bots skip anything that is not rendered. */
.trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ---------- 8. Bands, the only colour blocks ---------- */
.band{position:relative;isolation:isolate;overflow:hidden;padding-block:calc(var(--sp-7) * 2)}
.band > .shell{position:relative;z-index:2}
/* The diagonal cut is the signature. It is pulled up 3.5vw so the slope bites
   into the section above, which means that section has to give the room back,
   or its last line ends up sitting on the cut. */
.band--cut{clip-path:polygon(0 0,100% 3.5vw,100% 100%,0 100%);margin-block-start:-3.5vw;
  padding-block:calc(var(--sp-7) * 3.25) calc(var(--sp-7) * 2)}
.hero:has(+ .band--cut),
.shell:has(+ .band--cut),
.band:has(+ .band--cut){padding-block-end:calc(var(--sp-7) * 2.25)}
.band--cut-end{clip-path:polygon(0 0,100% 0,100% calc(100% - 3.5vw),0 100%);
  padding-block-end:calc(var(--sp-7) * 2.5)}
.band--ink{background:var(--band-ink);color:var(--paper)}
.band--ink .h1,.band--ink .h2,.band--ink .h3,.band--ink .display{color:var(--paper)}
.band--ink .caps,.band--ink .fine,.band--ink .muted{color:rgba(255,255,255,.66)}
.band--ink .num{color:var(--accent)}
.band--accent{background:var(--accent);color:var(--ink)}
.band--accent .h1,.band--accent .h2,.band--accent .display{color:var(--ink)}
.band--accent .fine,.band--accent .muted{color:rgba(39,17,20,.72)}

/* ---------- 9. The ledger ---------- */
.ledger{border-block-start:1px solid var(--ink)}
.ledger > li,.ledger > div{
  display:grid;grid-template-columns:1fr auto;gap:var(--sp-4);align-items:baseline;
  padding-block:var(--sp-4);border-block-end:1px solid var(--rule);
}
.ledger--3 > li,.ledger--3 > div{grid-template-columns:1fr auto auto;gap:var(--sp-6)}
.ledger dt,.ledger .term{color:var(--ink-soft)}
/* WCAG 2.2 SC 2.5.8: a ledger link is a standalone target, not prose. It also
   needs to look like one: a ledger row carries no rule when it has no value
   column, so on 404.html the four ways out were black text on white with no
   affordance at all. Underline, the boring answer, at the hairline weight. */
.ledger .term > a,.ledger dt > a{display:inline-block;padding-block:5px;
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.22em;
  text-decoration-color:var(--muted)}
.ledger .term > a:hover,.ledger dt > a:hover{text-decoration-color:var(--ink)}
.ledger dd,.ledger .val{margin:0;font-variant-numeric:tabular-nums;font-weight:700;color:var(--ink);
  text-align:right;white-space:nowrap}
.ledger .rate{font-size:var(--fs-2xs);color:var(--muted);text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.ledger small{display:block;font-size:var(--fs-2xs);color:var(--muted);line-height:1.4;margin-block-start:2px}
.ledger__total{display:grid;grid-template-columns:1fr auto;gap:var(--sp-4);align-items:baseline;
  padding-block:var(--sp-5);border-block-end:3px double var(--ink)}
.ledger__total b{font-size:var(--fs-lg);font-weight:900;font-variant-numeric:tabular-nums;
  letter-spacing:-.02em;text-align:right;color:var(--ink)}
.band--ink .ledger{border-block-start-color:var(--paper)}
.band--ink .ledger > li,.band--ink .ledger > div{border-block-end-color:rgba(255,255,255,.2)}
.band--ink .ledger dt,.band--ink .ledger .term{color:rgba(255,255,255,.82)}
.band--ink .ledger dd,.band--ink .ledger .val{color:var(--paper)}
/* The note under a ledger term is --muted, which is mixed for white paper and
   drops to 2.7:1 on the ink band. Each band restates it against its own ground. */
.band--ink .ledger small{color:rgba(255,255,255,.72)}
.band--accent .ledger small{color:rgba(39,17,20,.74)}
.band--accent .ledger{border-block-start-color:var(--ink)}
.band--accent .ledger > li,.band--accent .ledger > div{border-block-end-color:rgba(39,17,20,.24)}
.band--accent .ledger dd,.band--accent .ledger .val{color:var(--ink)}

/* A rule exists to carry the eye across a gap to a number. Rows that state a
   fact and stop have no gap and no number, so the rule is only texture. The
   marker square already separates them. */
.ledger:not(:has(.val,dd)){border-block-start:0}
.ledger > li:not(:has(.val,dd)){padding-block:var(--sp-2);border-block-end:0}

/* Ledger rows that state inclusion or exclusion carry a block, not an icon */
.ledger .in::before,.ledger .out::before{
  content:"";display:inline-block;width:.62em;height:.62em;margin-inline-end:.6em;
  background:var(--accent);border:1px solid var(--ink);vertical-align:baseline;
}
.ledger .out::before{background:var(--paper)}
.ledger .out{color:var(--muted)}

/* ---------- 10. The figure ---------- */
.figure{font-size:clamp(var(--fs-2xl),13vw,var(--fs-3xl));font-weight:900;letter-spacing:-.05em;
  line-height:.92;font-variant-numeric:tabular-nums;color:var(--ink)}
.figure-row{display:flex;align-items:flex-end;gap:var(--sp-5);flex-wrap:wrap}

/* ---------- 11. Masthead ---------- */
.masthead{display:flex;align-items:center;gap:var(--sp-4);padding-block:var(--sp-5);
  border-block-end:1px solid var(--ink);font-size:var(--fs-2xs);font-weight:700;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink);flex-wrap:wrap}
.masthead span:nth-child(2){flex:1;height:1px;background:var(--ink);opacity:.28;min-width:var(--sp-7)}

/* ---------- 12. App bar ---------- */
.bar{position:sticky;top:0;z-index:60;height:var(--bar-h);background:var(--paper);
  border-block-end:1px solid var(--ink);view-transition-name:appbar}
.bar__in{height:100%;display:flex;align-items:center;gap:var(--sp-6)}
.bar__nav{display:none;gap:var(--sp-6);margin-inline-start:auto;font-size:var(--fs-2xs);font-weight:500}
.bar__nav a{color:var(--muted);transition:color var(--dur-instant) var(--ease)}
.bar__nav a:hover{color:var(--ink)}
/* On mobile the burger carries navigation, so the header CTA would only crowd
   it. The brief is the button inside the menu instead. */
/* .btn sets display later in the sheet, so this needs the extra specificity
   or the button reappears. */
.bar .bar__cta{display:none}
@media (min-width:900px){ .bar .bar__cta{display:inline-flex;margin-inline-start:auto} }
@media (min-width:900px){
  /* The ink nav block is already the bar's edge. A solid ink rule under it is a
     second, louder edge, so the hairline takes over: still enough to part the
     white bar from white copy scrolling under it, quiet enough to disappear at
     rest. Mobile keeps the ink rule, having no nav block to lean on. */
  .bar{border-block-end-color:var(--rule)}
  /* The nav sits in an ink block, so it reads as one control rather than
     five loose links, and it holds the accent for the current page. */
  .bar__nav{display:flex;align-items:center;gap:var(--sp-5);background:var(--band-ink);
    padding:var(--sp-2) var(--sp-5);letter-spacing:.04em}
  .bar__nav a{color:rgba(255,255,255,.7);padding-block:5px}
  .bar__nav a:hover{color:var(--paper)}
  .bar__nav a[aria-current="page"]{color:var(--accent);font-weight:700}
  .bar__cta{margin-inline-start:0}
}

/* Wordmark: ink type, the 5 sits in an accent block and runs slightly larger
   than the name, because the 5 is the product. */
.mark{display:inline-flex;align-items:baseline;font-weight:900;letter-spacing:-.045em;
  font-size:var(--fs-lg);line-height:1;color:var(--ink);view-transition-name:wordmark}
.mark i{font-style:normal;font-size:1.14em;background:var(--accent);color:var(--ink);
  padding-inline:.28em;margin-inline-start:.06em;
  clip-path:polygon(.17em 0,100% 0,calc(100% - .17em) 100%,0 100%)}
.band--ink .mark{color:var(--paper)}
.band--ink .mark i{color:var(--ink)}

/* ---------- 13. Mobile menu ---------- */
/* Two rules that fold into a cross. The lines are the same hairlines the rest
   of the page is drawn with, so the control belongs to the system. */
.burger{position:relative;z-index:60;inline-size:48px;block-size:48px;margin-inline-start:auto;
  display:grid;place-items:center;gap:0;background:none;border:0;cursor:pointer;padding:0;
  color:var(--ink)}
.burger span{display:block;position:absolute;inline-size:26px;block-size:2.5px;
  background:currentColor;transition:transform var(--dur-instant) var(--ease),
  opacity 120ms linear}
.burger span:first-child{transform:translateY(-5px)}
.burger span:last-child{transform:translateY(5px)}
.burger[aria-expanded="true"]{color:var(--paper)}
.burger[aria-expanded="true"] span:first-child{transform:rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:rotate(-45deg)}
@media (min-width:900px){ .burger{display:none} }
/* The bar makes its own stacking context, so a z-index on the button alone can
   never lift it above the panel. The bar itself has to sit higher, and it goes
   transparent while the menu is open so the panel reads as one field. */
body[data-menu-open] .bar{background:transparent;border-block-end-color:transparent}
body[data-menu-open] .bar .mark{color:var(--paper)}
body[data-menu-open] .bar__cta{opacity:0;pointer-events:none}

.menu{position:fixed;inset:0;z-index:55;background:var(--band-ink);color:var(--paper);
  display:flex;flex-direction:column;justify-content:center;
  padding:calc(var(--bar-h) + var(--sp-7)) var(--gutter) var(--sp-7);
  clip-path:inset(0 0 100% 0);transition:clip-path 560ms var(--ease);
  overflow-y:auto;overscroll-behavior:contain}
.menu[data-open]{clip-path:inset(0 0 0 0)}
body[data-menu-open]{overflow:hidden}

.menu__list{display:grid;gap:0;border-block-start:1px solid rgba(255,255,255,.22)}
.menu__list a{display:flex;align-items:baseline;gap:var(--sp-4);
  padding-block:var(--sp-5);border-block-end:1px solid rgba(255,255,255,.22);
  font-size:clamp(var(--fs-lg),6.4vw,var(--fs-xl));font-weight:900;letter-spacing:-.04em;
  line-height:1;color:var(--paper);
  opacity:0;transform:translateY(14px);
  transition:opacity 420ms var(--ease),transform 420ms var(--ease)}
.menu[data-open] .menu__list a{opacity:1;transform:none}
.menu__list a em{font-style:normal;font-size:var(--fs-2xs);font-weight:500;letter-spacing:.1em;
  color:var(--accent);flex:0 0 2.2rem}
.menu__list a[aria-current="page"]{color:var(--accent)}
.menu__list li:nth-child(1) a{transition-delay:120ms}
.menu__list li:nth-child(2) a{transition-delay:180ms}
.menu__list li:nth-child(3) a{transition-delay:240ms}
.menu__list li:nth-child(4) a{transition-delay:300ms}
.menu__list li:nth-child(5) a{transition-delay:360ms}
.menu__list li:nth-child(6) a{transition-delay:420ms}
.menu__list li:nth-child(7) a{transition-delay:480ms}
.menu__foot{display:flex;flex-wrap:wrap;gap:var(--sp-3) var(--sp-6);align-items:baseline;
  margin-block-start:var(--sp-7);opacity:0;transition:opacity 420ms var(--ease) 420ms}
.menu[data-open] .menu__foot{opacity:1}
.menu__foot .btn{font-size:var(--fs-2xs)}
.menu :focus-visible{outline-color:var(--paper)}
@media (prefers-reduced-motion:reduce){
  .menu,.menu__list a,.menu__foot,.burger span{transition-duration:1ms !important;
    transition-delay:0ms !important}
}

/* ---------- 14. Buttons. Rectangles, ruled. ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  min-height:48px;padding:var(--sp-3) var(--sp-6);border-radius:0;
  font-size:var(--fs-2xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  border:1px solid var(--ink);background:none;cursor:pointer;
  transition:background-color var(--dur-instant) var(--ease),color var(--dur-instant) var(--ease),
             box-shadow var(--dur-instant) var(--ease),opacity var(--dur-instant) var(--ease)}
.btn i{font-size:1.15em;text-transform:none}
.btn--primary{background:var(--accent);color:var(--ink)}
.btn--primary:hover{box-shadow:5px 5px 0 var(--ink)}
.btn--primary:active{box-shadow:2px 2px 0 var(--ink);opacity:.9}
.btn--ghost{background:var(--paper);color:var(--ink)}
.btn--ghost:hover{background:var(--accent)}
.btn--quiet{border-color:transparent;padding-inline:0;min-height:40px;color:var(--muted);
  letter-spacing:.04em;text-transform:none;font-size:var(--fs-2xs)}
.btn--quiet:hover{color:var(--ink);box-shadow:inset 0 -2px 0 var(--accent)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.34;cursor:not-allowed;box-shadow:none}
.btn[data-loading]{pointer-events:none;position:relative;color:transparent}
.btn[data-loading]::after{content:"";position:absolute;width:18px;height:18px;border-radius:50%;
  border:2px solid rgba(0,0,0,.25);border-block-start-color:var(--ink);
  animation:spin var(--dur-fast) linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.btn--block{width:100%}
.band--ink .btn{border-color:var(--paper);color:var(--paper)}
.band--ink .btn--primary{background:var(--accent);color:var(--ink);border-color:var(--accent)}
.band--ink .btn--primary:hover{box-shadow:5px 5px 0 var(--paper)}
.band--ink .btn--ghost{background:none}
.band--ink .btn--ghost:hover{background:var(--paper);color:var(--ink)}
.band--accent .btn--ghost{background:none;border-color:var(--ink)}
.band--accent .btn--ghost:hover{background:var(--ink);color:var(--accent)}

/* ---------- 15. Steps, numbered like clauses ---------- */
.steps{counter-reset:step;border-block-start:1px solid var(--ink)}
.steps li{counter-increment:step;display:grid;grid-template-columns:3rem 1fr;gap:var(--sp-5);
  padding-block:var(--sp-6);border-block-end:1px solid var(--rule)}
.steps li::before{content:counter(step,decimal-leading-zero);font-size:var(--fs-2xs);font-weight:900;
  letter-spacing:.08em;color:var(--ink);padding-block-start:6px;font-variant-numeric:tabular-nums}

/* ---------- 16. The term rail ---------- */
.term-rail{display:grid;border-block:1px solid var(--ink)}
.term-rail > li{padding:var(--sp-4) 0;border-block-start:1px solid var(--rule);
  display:flex;align-items:baseline;gap:var(--sp-5)}
.term-rail > li:first-child{border-block-start:0}
/* Five columns only once a cell can hold its label. Below that the rail
   stands up as rows and the dividing rule turns with it. */
@media (min-width:620px){
  .term-rail{grid-template-columns:repeat(5,minmax(0,1fr))}
  .term-rail > li{padding:var(--sp-5) var(--sp-3) var(--sp-6);display:block;
    border-block-start:0;border-inline-start:1px solid var(--rule)}
  .term-rail > li:first-child{border-inline-start:0}
}
.term-rail b{display:block;font-size:var(--fs-xl);font-weight:900;letter-spacing:-.04em;
  line-height:.9;color:var(--ink);font-variant-numeric:tabular-nums}
.term-rail span{display:block;font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted)}
@media (min-width:620px){ .term-rail span{margin-block-start:var(--sp-3)} }
.term-rail li:nth-child(3) b{background:var(--accent);display:inline-block;padding-inline:.1em}

/* ---------- 16a2. Work ----------
   A screen with the trade under it. The screenshot is a flat object on the
   canvas, so it takes the ink hairline and one hard offset, same as a swatch,
   and no radius. Two to a row from 760px: the page gains a build at a time and
   a single column only ever gets longer. */
.work{display:grid;gap:calc(var(--sp-7) * 1.6)}
.work > *{min-width:0}
@media (min-width:760px){
  .work{grid-template-columns:1fr 1fr;gap:calc(var(--sp-7) * 1.6) calc(var(--sp-7) * 1.2)}
}
.work__item{display:grid;gap:var(--sp-5);align-content:start}
.work__shot{display:block;width:100%;height:auto;border:1px solid var(--ink);
  box-shadow:10px 10px 0 var(--accent);background:var(--paper)}
.work__where{font-size:var(--fs-2xs);color:var(--muted);letter-spacing:.06em;
  text-transform:uppercase;font-weight:700}
.work__name{margin-block-start:var(--sp-3)}
.work__live{margin-block-start:var(--sp-5)}
/* A build with no address yet is stated, never dressed up as a live link. */
.work__soon{display:inline-block;margin-block-start:var(--sp-5);font-size:var(--fs-2xs);
  font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);
  box-shadow:inset 0 -8px 0 var(--accent)}

/* ---------- 16a3. Problem and answer ----------
   A list of failures reads as a wall, and asking the reader to hold five of
   them in their head while a closing paragraph maps each one to its remedy is
   work we should be doing for them. So the mapping is the layout: the failure
   on the left, the thing that answers it on the right, on one ruled line. */
.fixes{border-block-start:1px solid var(--ink)}
.fixes > li{display:grid;gap:var(--sp-4);padding-block:var(--sp-5);
  border-block-end:1px solid var(--rule)}
.fixes > li > *{min-width:0}
@media (min-width:760px){
  .fixes > li{grid-template-columns:1fr 17rem;gap:calc(var(--sp-7) * 1.2);align-items:start}
}
.fixes b{display:block;font-size:var(--fs-sm);font-weight:700;color:var(--ink-soft);
  letter-spacing:-.01em}
.fixes small{display:block;font-size:var(--fs-2xs);color:var(--muted);line-height:1.45;
  margin-block-start:var(--sp-2)}
.fixes__answer{align-self:center}
.fixes__answer span{display:block;font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.fixes__answer b{margin-block-start:var(--sp-2);color:var(--ink);
  box-shadow:inset 0 -8px 0 var(--accent);display:inline-block}

/* ---------- 16b. Rate table, ruled like the ledger ---------- */
.table-wrap{overflow-x:auto}
table{border-collapse:collapse;width:100%;border-block-start:1px solid var(--ink)}
table th,table td{text-align:left;padding:var(--sp-4) var(--sp-4) var(--sp-4) 0;
  border-block-end:1px solid var(--rule);vertical-align:baseline;white-space:nowrap}
table th{font-size:var(--fs-2xs);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
table td{font-size:var(--fs-2xs);color:var(--ink-soft)}
/* The name column needs a floor or it wraps to one word a line beside two
   nowrap money columns. Below 620px it takes the floor and .table-wrap scrolls. */
table td:first-child{white-space:normal;min-width:11rem;padding-inline-end:var(--sp-6)}
@media (min-width:620px){ table td:first-child{min-width:15rem} }
table td b{color:var(--ink);font-size:var(--fs-xs)}
table td:last-child,table th:last-child{text-align:right;padding-inline-end:0;
  font-variant-numeric:tabular-nums;font-weight:700;color:var(--ink)}
table caption{caption-side:bottom;text-align:left;padding-block-start:var(--sp-4);
  font-size:var(--fs-2xs);color:var(--muted)}
table tr[data-group] td{padding-block:var(--sp-6) var(--sp-2);border-block-end:0}
.group-label{font-size:var(--fs-2xs);font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink);box-shadow:inset 0 -8px 0 var(--accent)}

/* ---------- 16c. Portal ---------- */
.meter{height:10px;background:rgba(0,0,0,.1);border:1px solid var(--ink);overflow:hidden}
.meter > span{display:block;height:100%;background:var(--accent)}
.log{border-block-start:1px solid var(--ink)}
.log li{display:grid;grid-template-columns:auto 1fr auto;gap:var(--sp-4);align-items:baseline;
  padding-block:var(--sp-4);border-block-end:1px solid var(--rule);font-size:var(--fs-2xs)}
.log i{font-size:var(--fs-md);color:var(--ink);align-self:center}
.log time{color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.statline{display:grid;gap:var(--sp-1)}
.statline b{font-size:var(--fs-xl);font-weight:900;letter-spacing:-.04em;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--ink)}
.statline span{font-size:var(--fs-2xs);color:var(--muted)}
.grid-4{display:grid;gap:var(--sp-6)}
@media (min-width:620px){ .grid-4{grid-template-columns:repeat(2,1fr)} }
@media (min-width:900px){ .grid-4{grid-template-columns:repeat(4,1fr);gap:var(--sp-7)} }

/* ---------- 17. Forms ---------- */
.field{display:block}
.field > span{display:block;font-size:var(--fs-2xs);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);margin-block-end:var(--sp-2)}
.input{width:100%;min-height:52px;padding:var(--sp-3) 0;background:none;color:var(--ink);
  border:0;border-block-end:2px solid var(--ink);border-radius:0;font-size:var(--fs-md);
  transition:box-shadow var(--dur-instant) var(--ease)}
.input::placeholder{color:var(--muted);opacity:.62}
.input:hover{box-shadow:inset 0 -2px 0 var(--accent)}
textarea.input{min-height:112px;resize:vertical;line-height:var(--lh-base)}
.input[aria-invalid="true"]{box-shadow:inset 4px 0 0 var(--accent),inset 0 -3px 0 var(--ink);padding-inline-start:var(--sp-4)}
.err{display:block;font-size:var(--fs-2xs);color:var(--ink);font-weight:700;margin-block-start:var(--sp-2)}
.err::before{content:"";display:inline-block;width:.6em;height:.6em;background:var(--accent);
  border:1px solid var(--ink);margin-inline-end:.5em}
.err:empty{display:none}

/* Option rows. Ruled, not boxed. */
.opts{border-block-start:1px solid var(--ink)}
.opt{position:relative;display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-5) var(--sp-4);
  border-block-end:1px solid var(--rule);cursor:pointer;
  transition:background-color var(--dur-instant) var(--ease)}
.opt input{position:absolute;opacity:0;width:1px;height:1px}
.opt:hover{background:rgba(0,0,0,.035)}
.opt__key{display:grid;place-items:center;width:28px;height:28px;flex:none;border:1px solid var(--ink);
  font-size:var(--fs-2xs);font-weight:900;color:var(--ink);background:var(--paper)}
.opt__body{flex:1;min-width:0}
.opt__body b{display:block;font-weight:700;font-size:var(--fs-xs);color:var(--ink)}
.opt__body small{display:block;font-size:var(--fs-2xs);color:var(--muted);margin-block-start:3px;line-height:1.4}
.opt__cost{font-size:var(--fs-2xs);font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;
  flex:none;text-align:right}
.opt__cost small{display:block;font-weight:500;font-size:11px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted);margin-block-start:2px}
.opt:has(input:checked){background:var(--accent)}
.opt:has(input:checked) .opt__body small{color:rgba(39,17,20,.76)}
.opt:has(input:checked) .opt__key{background:var(--ink);color:var(--accent)}
.opt:has(input:focus-visible){outline:3px solid var(--ink);outline-offset:-3px}
.qty{display:flex;align-items:center;gap:var(--sp-3);margin-block-start:var(--sp-4)}
.qty button{width:40px;height:40px;border:1px solid var(--ink);background:var(--paper);cursor:pointer;
  font-size:var(--fs-md);font-weight:700;line-height:1;color:var(--ink)}
.qty button:hover{background:var(--ink);color:var(--accent)}
.qty output{font-size:var(--fs-lg);font-weight:900;font-variant-numeric:tabular-nums;min-width:2ch;
  text-align:center;color:var(--ink)}
.qty small{font-size:var(--fs-2xs);color:var(--muted)}
.qty[hidden]{display:none}

/* ---------- 18. Details ---------- */
details{border-block-end:1px solid var(--rule)}
details:first-of-type{border-block-start:1px solid var(--ink)}
details summary{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-4);
  padding-block:var(--sp-5);cursor:pointer;font-weight:700;font-size:var(--fs-xs);
  list-style:none;color:var(--ink)}
details summary::-webkit-details-marker{display:none}
details summary::after{content:"+";font-weight:900;font-size:var(--fs-md);line-height:1;flex:none}
details[open] summary{background:linear-gradient(transparent 0,transparent 0)}
details[open] summary::after{content:"\2212"}
details .body{padding-block-end:var(--sp-6);max-width:64ch}

/* ---------- 19. Footer: the signature block ----------
   The wordmark set large, one paragraph of argument, and the three links
   people open a footer looking for. Everything else lives in the menu. */
.foot{background:var(--band-ink);color:var(--paper);padding-block:calc(var(--sp-7) * 2)}
.foot .mark{font-size:clamp(var(--fs-2xl),8vw,var(--fs-3xl));color:var(--paper);padding-block:0}
.foot__top{display:grid;gap:calc(var(--sp-7) * 1.5)}
@media (min-width:900px){ .foot__top{grid-template-columns:1fr auto;gap:calc(var(--sp-7) * 2);align-items:end} }
.foot__say{font-size:var(--fs-md);color:rgba(255,255,255,.72);max-width:34ch;margin-block-start:var(--sp-6)}


/* Three links, not a second copy of the menu. Set large enough to be the
   thing the eye lands on in the right column. */
.foot__go{display:grid;gap:var(--sp-2);justify-items:start}
@media (min-width:900px){ .foot__go{justify-items:end;text-align:right} }
.foot__go a{display:flex;align-items:center;gap:var(--sp-3);
  font-size:clamp(var(--fs-lg),4vw,var(--fs-xl));font-weight:900;letter-spacing:-.035em;
  line-height:1.15;color:var(--paper);padding-block:6px;
  transition:color var(--dur-instant) var(--ease)}
.foot__go a:hover{color:var(--accent)}
.foot__go a i{font-size:.72em;color:var(--accent);transition:transform var(--dur-instant) var(--ease)}
.foot__go a:hover i{transform:translateX(5px)}

.foot__end{display:flex;flex-wrap:wrap;gap:var(--sp-4) var(--sp-7);align-items:baseline;
  margin-block-start:calc(var(--sp-7) * 1.5)}
.foot__end a,.foot__end span{font-size:var(--fs-2xs);color:rgba(255,255,255,.72)}
.foot__end a{padding-block:5px}
.foot__end a:hover{color:var(--accent)}

/* Contact and social read as marks, not as a list of words. */
.foot__social{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-inline-start:-10px;margin-inline-end:auto}
.foot__social a{display:grid;place-items:center;inline-size:44px;block-size:44px;
  color:rgba(255,255,255,.82);font-size:23px;
  transition:color var(--dur-instant) var(--ease),transform var(--dur-instant) var(--ease)}
.foot__social a:hover{color:var(--accent);transform:translateY(-2px)}
.foot__c{font-size:var(--fs-2xs);color:rgba(255,255,255,.55)}
.foot__end .small{flex-basis:100%;color:rgba(255,255,255,.5);line-height:1.5;max-width:70ch}

/* ---------- 20. Scroll behaviour ----------
   Content is never hidden waiting for an animation. Everything here either
   moves an element that is already visible, or moves pure decoration, so a
   browser without scroll-driven animation loses nothing but the flourish. */
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* Rise on arrival. app.js sets the attribute, so the stylesheet can never hide
   anything on its own: no JS, or a reader who asked for less motion, and the
   page arrives whole. Nothing already on screen at load is ever marked, so the
   first paint is still. */
[data-rise]{opacity:0}
[data-rise="in"]{opacity:1;animation:rise var(--dur-instant) var(--ease)}

/* The clause head pins under the app bar while you are inside that clause,
   so the number and label you are reading under stay on screen. */
.clause > .clause__head{position:sticky;top:var(--bar-h);z-index:20;background:var(--paper);
  padding-block:var(--sp-4);margin-block-end:var(--sp-5)}

@media (prefers-reduced-motion:no-preference){
  /* Reading progress, drawn on the underside of the app bar. */
  @supports (animation-timeline:scroll()){
    .bar::after{content:"";position:absolute;inset-inline:0;bottom:-1px;height:3px;
      background:var(--accent);transform:scaleX(0);transform-origin:left center;
      animation:read linear;animation-timeline:scroll(root block)}
    @keyframes read{to{transform:scaleX(1)}}
  }
  @supports (animation-timeline:view()){
    /* Decorative shapes drift against the scroll. */
    .deco{animation:drift linear both;animation-timeline:view();animation-range:cover}
    @keyframes drift{from{transform:translateY(7vh)}to{transform:translateY(-7vh)}}
    /* The rule runs out from the clause number as the clause arrives. */
    .clause__rule{transform-origin:left center;animation:rule-out linear both;
      animation-timeline:view();animation-range:entry 10% cover 22%}
    @keyframes rule-out{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  }
}

/* ---------- 20b. The notice at the foot ----------
   Same object as everything else: hairline ink border, one hard offset, zero
   radius. Fixed to the corner rather than a full width bar, because it is a
   notice and not a gate. */
.notice{position:fixed;z-index:70;inset-inline-start:var(--gutter);inset-block-end:var(--gutter);
  max-width:32rem;background:var(--paper);border:1px solid var(--ink);
  box-shadow:6px 6px 0 var(--accent);padding:var(--sp-5);
  display:flex;flex-wrap:wrap;gap:var(--sp-4) var(--sp-5);align-items:center}
.notice p{flex:1 1 15rem;margin:0;font-size:var(--fs-2xs);line-height:1.5;color:var(--ink-soft)}
.notice a{text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:.22em;text-decoration-color:var(--muted)}
.notice a:hover{text-decoration-color:var(--ink)}
.notice .btn{flex:none}
@media (max-width:620px){ .notice{inset-inline:var(--gutter);max-width:none} }

/* ---------- 21. Cross-document view transitions ---------- */
@view-transition{navigation:auto}
