/* ===========================================================================
   Municorn design system · 3 · components
   ---------------------------------------------------------------------------
   One block per component, in the order a page uses them. Start states and
   choreography live in motion.css; this file describes each part at rest, so
   the page is complete and correct with motion.css absent.
   =========================================================================== */

/* === hatch ================================================================
   The house texture. Solid is measured; a 45-degree hatch is the value the
   regulator's form supplied because the component was not metered. TWDB
   publishes that split on every filing and nothing else reads it back out, so
   it is the one mark on this site that is ours to draw.

   This is the CSS twin of the SVG <pattern> in src/design/primitives.ts. The
   twin exists because the split bar is two <i> elements rather than a drawing,
   and an element cannot be filled with url(#hatch). The geometry is the same in
   both — 1.5px on a 6px period at 45 degrees — so a hatched <i> beside a hatched
   <svg> reads as one texture and not as two near-misses.

   Unlike the SVG pattern, this one can be restated per ground: --brass is the
   brass for a light slab, --brass-lt the bright brass that survives on ink.

   Not a fill that is merely available. If a quantity does not have a measured
   part and a defaulted part, it does not get the hatch. */
.hatch,.slab--tight::before{background-image:repeating-linear-gradient(45deg,
  var(--brass) 0 1.5px,transparent 1.5px 6px)}
.slab--dark .hatch,.brickwall .hatch,.slab--dark.slab--tight::before{
  background-image:repeating-linear-gradient(45deg,
  var(--brass-lt) 0 1.5px,transparent 1.5px 6px)}

/* === section rule =========================================================
   The line between two sections sharing one ground, where the change of colour
   is not there to mark the boundary. It was a 1px hairline; it is the hatch
   now, at the same visual weight, which is the cheapest place on the site for
   the texture to be introduced before it has to carry a figure.

   3px rather than 1px because a 45-degree hatch shorter than its own period
   reads as a dotted line rather than as a texture. Full-bleed, like the
   hairline it replaces. */
/* === say: the statement ===================================================
   The page's scale. Everything below the hero sat between 11px and 17px, six
   sections deep, and read as one section — there was nothing for a reader to
   stop on. This is the stop.

   Display serif at roughly three times body, one line where the line allows it,
   and a measure short enough that it breaks where the sentence breaks. The line
   under it is the explanation and is deliberately much smaller: the gap between
   the two IS the hierarchy, and closing it would put the page back where it
   was. */
/* THE MEASURE GOES ON THE ELEMENT WHOSE FONT-SIZE IT DESCRIBES. This was
   max-width:24ch on .say, and ch resolves against the element's own font-size —
   .say inherits the body's 16px, so 24ch was about 380px and the 3.6rem heading
   inside it broke across four lines with half the screen empty beside it. The
   heading carries its own measure now, in its own size. */
.say{margin-top:.4rem}
.say__t{font-family:var(--serif);font-weight:300;line-height:1.04;letter-spacing:-.025em;
  font-size:clamp(2.1rem,5.4vw,3.6rem);color:var(--lime-hi);max-width:19ch}
.say__a{margin-top:1.1rem;max-width:46ch;font-size:.95rem;line-height:1.65;color:var(--lime-mute)}
.slab--light .say__t{color:var(--ink)}
.slab--light .say__a{color:var(--ink-soft)}

/* === offers: prose, then a list =========================================
   THE FIRST ATTEMPT WAS FIVE CARDS IN A GRID and it is worth saying why that
   was worse than what it replaced. src/design/primitives.ts has the argument.
   The short version: a uniform card grid with a tracked uppercase micro-label
   on every row is the most recognisable machine-made layout there is, and the
   section that replaced a three-by-three grid had become a one-plus-four one.

   There is no grid here now. A paragraph, a list of four links, and a
   paragraph. The list is set at reading width and its items are whatever
   length their sentence is, which is the point: four items that happen to be
   four different lengths look written, and four that are the same length look
   generated, and they carry the same information either way. */
.ofrs{margin-top:var(--head-gap);max-width:66ch}
.ofrs .ofrs__h{font-size:clamp(1.35rem,2.4vw,1.75rem);font-weight:300;letter-spacing:-.015em;
  margin:0 0 clamp(1rem,2.4vh,1.5rem);color:var(--lime-hi);max-width:30ch}
.ofrs__lead{font-size:clamp(1.05rem,1.5vw,1.2rem);line-height:1.62;color:var(--lime-2);
  margin:0 0 1.6rem}
.ofrs__lead a{color:var(--lime-hi);text-decoration:none;
  border-bottom:1px solid var(--brass);padding-bottom:1px}
.ofrs__lead a:hover{color:var(--brass-lt)}
.ofrs__also{margin:0 0 .5rem;color:var(--lime-faint);font-size:.95rem}
.ofrs__l{list-style:none;margin:0;padding:0}
.ofrs__l li{color:var(--lime-mute);font-size:.98rem;line-height:1.55;
  padding:.42rem 0 .42rem 1.1rem;text-indent:-1.1rem}
.ofrs__l li::before{content:'\2014\00a0';color:var(--lime-faint)}
.ofrs__l a{color:var(--lime-2);text-decoration:none;border-bottom:1px solid var(--hairline-lt)}
.ofrs__l a:hover{color:var(--brass-lt);border-bottom-color:var(--brass)}
.ofrs__b{margin-top:clamp(2.2rem,5vh,3.4rem);padding-top:clamp(1.3rem,2.6vh,1.8rem);
  border-top:1px solid var(--hairline)}
.ofrs .ofrs__bh{font-size:1.08rem;font-weight:400;letter-spacing:-.005em;margin:0 0 .5rem;
  color:var(--lime-2);max-width:40ch}
.ofrs__bl{color:var(--lime-mute);font-size:.95rem;line-height:1.62;margin:0}
.ofrs__bl a{color:var(--lime-2);text-decoration:none;border-bottom:1px solid var(--hairline-lt)}
.ofrs__bl a:hover{color:var(--brass-lt);border-bottom-color:var(--brass)}
.ofrs__more{color:var(--brass-lt);border-bottom-color:var(--brass)}

/* === find: the finder =====================================================
   One input and a listbox under it. Renders and submits with JavaScript off —
   the form GETs the hub with ?q= — so everything here describes a control that
   already works before public/js/search.js reaches it.

   The results panel is absolutely positioned so opening it does not push the
   rest of the section down the page. .is-open is set by search.js; with the
   script absent the panel is empty and stays hidden. */
.find{position:relative;display:grid;gap:.55rem;max-width:34rem;margin-top:var(--head-gap)}
/* The eyebrow is not drawn. The statement above the box says what the box is
   for, and a mono FIND A SYSTEM under a 3.6rem "Find a utility by name" is one
   sentence set twice. The <label> is clipped rather than deleted: the input is
   a combobox, and a combobox with no accessible name announces itself as
   "edit, blank". */
/* Clipped, not display:none. A name that is not rendered is still a name; a
   name that is not in the accessibility tree is nothing. Third use of this
   pattern in the stylesheet, so it is a class now: .find__l and .plan__r below
   both compose it in the same way. */
.vh,.find__l{position:absolute;width:1px;height:1px;margin:0;padding:0;
  clip-path:inset(50%);overflow:hidden;white-space:nowrap}
/* The button after the finder was sitting on the input's bottom border. The
   form is a grid with its own internal gap; what follows it is not in that
   grid and needs its own. */
.find + .btn{margin-top:1.5rem}
.find__in{width:100%;padding:.8rem .95rem;background:var(--card);color:var(--ink);
  border:1px solid var(--rule-2);font-family:var(--sans);font-size:1rem;
  font-weight:300;-webkit-appearance:none;appearance:none}
.find__in::placeholder{color:var(--faint)}
/* Border colour on focus, and the outline deliberately NOT suppressed. Killing
   it is the reflex here and it is wrong: :focus-visible in base.css is the ring
   every other control on the site draws, and an input that opts out is the one
   control a keyboard reader most needs to find. Verified by tabbing the page —
   45 stops, every one of them ringed. */
.find__in:focus{border-color:var(--brass)}
.find__out{display:none;position:absolute;top:100%;left:0;right:0;z-index:20;
  max-height:19rem;overflow-y:auto;background:var(--card);
  border:1px solid var(--rule-2);border-top:0;box-shadow:var(--lift-1)}
.find__out.is-open{display:block}
.find__hit{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  padding:.6rem .95rem;border-top:1px solid var(--rule)}
.find__hit:first-child{border-top:0}
.find__hit a{color:var(--ink);text-decoration:none}
.find__hit.is-sel{background:var(--wash-brick)}
.find__hit.is-sel a{color:var(--brick)}
.find__kind{font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--faint);white-space:nowrap}

/* The same control on a dark slab, if one ever carries it. */
.slab--dark .find__kind{color:var(--lime-faint)}
.slab--dark .find__in,.slab--dark .find__out{background:var(--ink-2);color:var(--lime-hi);
  border-color:var(--hairline-lt)}
.slab--dark .find__in::placeholder{color:var(--lime-faint)}
.slab--dark .find__in:focus{border-color:var(--brass-lt)}
.slab--dark .find__hit{border-top-color:var(--hairline)}
.slab--dark .find__hit a{color:var(--lime-2)}
.slab--dark .find__hit.is-sel{background:var(--wash)}
.slab--dark .find__hit.is-sel a{color:var(--brass-lt)}

/* === rug: the percentile strip ============================================
   Where one system sits among the filings it is being compared to. Drawn by
   rug() in src/design/primitives.ts at build time, inlined, no client script.

   Colour and type live here rather than on the elements so the strip answers to
   the same tokens as everything else. Geometry lives in the primitive, because
   geometry is the claim.

   font-size is in USER UNITS, not rendered pixels: the SVG carries a viewBox
   1000 wide and scales to its column, so 14 units land near 11px in the column
   this renders into. Changing the viewBox changes the type size.

   overflow:visible because the two annotations sit at the top and bottom edges
   of the viewBox and a descender would otherwise be clipped. */
.rug{display:block;width:100%;height:auto;margin-top:1rem;overflow:visible}
/* stroke-width is a presentation ATTRIBUTE on the group and stroke-opacity one
   per band, and neither may be stated here: a CSS declaration beats a
   presentation attribute, so a stroke-width in this rule silently flattens
   every band to a hairline and the distribution disappears. Colour only. */
.rug__peers{stroke:var(--faint)}
.rug__self{stroke:var(--brass);stroke-width:2}
.rug__med{stroke:var(--faint);stroke-width:1;stroke-dasharray:3 4}
.rug__axis,.rug__tick{stroke:var(--rule);stroke-width:1}
.rug__ax,.rug__k{font-family:var(--mono);font-size:14px;letter-spacing:.04em;fill:var(--faint)}
.rug__k--self{fill:var(--brass);font-weight:500}
.slab--dark .rug__peers{stroke:var(--lime-faint)}
.slab--dark .rug__self,.slab--dark .rug__k--self{stroke:var(--brass-lt);fill:var(--brass-lt)}
.slab--dark .rug__ax,.slab--dark .rug__k{fill:var(--lime-faint)}
.slab--dark .rug__axis,.slab--dark .rug__tick{stroke:var(--hairline)}

/* === split: measured against the regulator's default ======================
   The bar the hatch was defined for. Solid is the measured part, hatched is the
   value TWDB's form supplied because the component was not metered.

   Sized to sit inside a headline figure cell rather than to be the page's
   subject: the percentage above it is the figure, and this is what makes the
   percentage a proportion instead of a number. Same border and same overflow
   discipline as .ledger .bar in reference.css, so the two bars on a Texas page
   read as one family.

   The hatched segment takes its ground from the bar rather than setting its
   own, which is why .hatch declares a background-image and never a colour.

   Texas only, and by construction rather than by a flag — see splitBar() in
   src/design/primitives.ts. */
.split{margin-top:.7rem}
.split__bar{display:flex;height:.85rem;border:1px solid var(--ink);overflow:hidden;
  background:var(--card)}
.split__bar i{display:block;height:100%}
.split__bar i:first-child{background:var(--brass)}
.split__key{display:flex;flex-wrap:wrap;gap:.3rem .9rem;margin-top:.45rem;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--faint)}
.split__key i{display:inline-block;width:.7rem;height:.7rem;margin-right:.35rem;
  vertical-align:-1px;border:1px solid var(--ink);background-color:var(--card)}
.split__key span:first-child i{background:var(--brass)}

/* === cite: the source chip ================================================
   One line under a published figure: the archived file, the cell, the date it
   was retrieved. Rendered by sourceChip() in src/design/primitives.ts from the
   object resolveCell() returns, so it cannot be handed a citation somebody
   typed.

   Mono because every part of it is a machine coordinate — a filename, an A1
   address, an ISO date — and mono on this site means "fact about the thing, not
   the thing". It is the one place the rule is unambiguous.

   flex-wrap rather than a grid: the three parts are one line at any width that
   fits them and stack in reading order when they do not, and a filename that is
   long is the common case rather than the exception. The rule above it is the
   same hairline the figure's own cell border uses, so the chip reads as the
   bottom of the figure and not as a row beneath it. */
.cite{font-family:var(--mono);font-weight:400;font-size:.68rem;line-height:1.5;
  letter-spacing:.045em;text-transform:uppercase;color:var(--faint);
  border-top:1px solid var(--rule);margin-top:.55rem;padding-top:.45rem;
  display:flex;flex-wrap:wrap;gap:4px 14px}
.cite a{color:var(--brass);text-decoration:none;border-bottom:1px solid var(--rule);
  word-break:break-all}
/* Our archived extract is a repo path, not a destination. It is named so the
   copy is findable and it is deliberately not a link: data/archive/ is
   committed and not served. The agency's own file is the link beside it. */
.cite__a{word-break:break-all}
.cite a:hover{color:var(--brick);border-bottom-color:currentColor}
.cite time{white-space:nowrap}
.slab--dark .cite{color:var(--lime-faint);border-top-color:var(--hairline)}
.slab--dark .cite a{color:var(--brass-lt);border-bottom-color:var(--hairline)}
/* A director carrying the page into a meeting carries the citation with it. */
@media print{.cite{color:var(--ink-soft)}}

/* === nav ================================================================== */
.nav{position:fixed;top:0;left:0;right:0;z-index:200;display:flex;align-items:center;
  justify-content:space-between;gap:1rem;padding:1.1rem var(--gut);
  transition:background .3s,border-color .3s,padding .3s;border-bottom:1px solid transparent}
/* The bar's own scrim, at rest over the wall.
   ---------------------------------------------------------------------------
   The hero's scrim is .34 to .5 alpha at the top, which is composed for the
   heading sitting in the middle of it and is not enough for 0.67rem uppercase
   letterspaced type sitting on bare masonry. Over a brick face the nav links
   measured 5.4:1 and over a mortar joint 1.8:1 — the same link, failing or
   passing depending on which course it happened to land on, which is the exact
   case SC 1.4.3 is written for.

   0.72 alpha is the floor that carries --lime-soft over --mortar at 4.6:1 and
   --brass-lt at 4.8:1, both clear of AA. It fades out over the bar's own height
   rather than being a band, so nothing reads as a box, and it belongs to the nav
   rather than the hero: darkening the hero gradient enough to fix this would
   have flattened the wall the whole page is built on, to solve a problem that
   exists in the top sixty pixels.

   Hidden under .stuck, which has an opaque ground of its own. */
.nav::before{content:'';position:absolute;inset:-1px 0 auto;height:calc(100% + 1.4rem);
  z-index:-1;pointer-events:none;transition:opacity .3s;
  background:linear-gradient(to bottom,rgb(var(--ink-c)/.82) 38%,rgb(var(--ink-c)/0))}
.nav.stuck::before,.nav--solid::before{opacity:0}
.nav.stuck{background:var(--glass-nav);backdrop-filter:var(--glass-nav-blur);
  border-bottom-color:rgb(var(--lime-c)/.1);padding-block:.7rem}
.mark{display:flex;align-items:center;gap:.55rem;text-decoration:none;color:var(--lime)}
.mark__logo{height:1.6rem;width:auto;display:block;flex-shrink:0}
.mark span{font-family:var(--serif);font-size:1.3rem;letter-spacing:.01em}
.nav__l{display:flex;gap:1.6rem;align-items:center}
/* MEASURED AT 10.7px AND RAISED. Uppercase at .16em tracking reads smaller than
   its own size, and this is the site's primary navigation on every page. .8rem
   is 12.8px; the tracking comes down with it, because the two compound. */
.nav__l a{font-family:var(--sans);font-weight:500;font-size:.8rem;letter-spacing:.11em;
  text-transform:uppercase;text-decoration:none;color:var(--lime-soft)}
.nav__l a:hover{color:var(--lime)}
.nav__l a.em{color:var(--brass-lt);text-transform:none;letter-spacing:.02em;font-size:.88rem;font-weight:400}
@media(max-width:860px){.nav__l a:not(.em){display:none}}

/* A reference page has no hero for the bar to sit over, so it is solid from the
   first frame and sticky rather than fixed — content flows under it instead of
   needing a matching top padding. */
.nav--solid{position:sticky;background:var(--glass-nav);backdrop-filter:var(--glass-nav-blur);
  border-bottom-color:rgb(var(--lime-c)/.1)}

/* Under 860px the section links are hidden, so the panel is the only way to
   reach them. Under 560px the bar cannot hold the address and the button too,
   so the address moves into the panel. */
.nav__btn{display:none;align-items:center;gap:.5rem;background:none;
  border:1px solid rgb(var(--lime-c)/.3);color:var(--lime-soft);padding:.5rem .8rem;cursor:pointer;
  font-family:var(--sans);font-weight:500;font-size:.64rem;letter-spacing:.16em;text-transform:uppercase}
.nav__btn__bars{width:13px;height:8px;border-top:1px solid currentColor;border-bottom:1px solid currentColor}
.nav__panel{position:absolute;top:100%;right:var(--gut);min-width:12rem;
  background:rgb(var(--ink-c)/.97);backdrop-filter:var(--glass-nav-blur);
  border:1px solid var(--hairline-lt);padding:.4rem 0}
.nav__panel[hidden]{display:none}
.nav__panel a{display:block;padding:.7rem 1.1rem;text-decoration:none;color:var(--lime-soft);
  font-family:var(--sans);font-weight:500;font-size:.68rem;letter-spacing:.14em;text-transform:uppercase}
.nav__panel a:hover,.nav__panel a:focus{color:var(--lime);background:var(--wash)}
.nav__panel a.em{color:var(--brass-lt);text-transform:none;letter-spacing:.02em;font-size:.8rem;
  border-top:1px solid rgb(var(--lime-c)/.14);margin-top:.35rem;padding-top:.8rem}
@media(max-width:860px){.nav__btn{display:inline-flex}}
/* The bar's only control below 860px, and it was 30px tall — under every
   published minimum for a touch target, on the one element a phone visitor has
   to hit to reach any section of the site. Padding rather than a height, so the
   label stays vertically centred and the bar's own `padding-block` transition
   on .stuck is untouched. Gated on a coarse pointer: a mouse does not need it
   and the bar is tighter without it. */
@media(pointer:coarse){
  .nav__btn{padding-block:.95rem}
  /* 40px, four short of the same minimum, on the panel those links open into. */
  .nav__panel a{padding-block:.82rem}
}
@media(min-width:861px){.nav__panel{display:none}}
@media(min-width:561px){.nav__panel a.em{display:none}}
@media(max-width:560px){.nav__l a.em{display:none}}

/* === hero ================================================================= */
/* Bottom-pinned, because the wall rises above the type and that is the whole
   composition. The trap in that is a fixed-height box holding content that
   shrinks on its own axis: the heading scales with 12vw, so every pixel the
   heading loses on a narrower window becomes an extra pixel of empty brick
   ABOVE it, and the slack all collects in one place. Measured before the cap
   went on, the gap over the title ran 152px at 1280 and 407px at 768 — a third
   of the screen of nothing, on the width a tablet actually uses.

   min() caps the box against the content rather than against the viewport. The
   second term never binds above about 1100px, so the full-bleed wall on a
   desktop is exactly as it was. */
.hero{--h1:clamp(1.5rem,min(3.4vw,6vh),2.5rem);--h1:clamp(1.5rem,min(3.4vw,6svh),2.5rem);
  position:relative;min-height:92vh;min-height:min(92svh,calc(19rem + 3.3 * var(--h1)));
  display:flex;flex-direction:column;
  justify-content:flex-end;
  /* The cap above stops the band over the title running away on a wide screen.
     This stops it collapsing at the other end: below about 700px the heading
     has bottomed out at 3rem while the description is still gaining lines, so
     the box the cap computes is no longer taller than what is in it and the
     title ends up four pixels under the nav bar. Bottom-pinned content with a
     top padding treats that padding as the floor on the gap, and it only ever
     binds at the small end. */
  padding:clamp(6rem,12vh,10rem) var(--gut) clamp(2.4rem,5vw,4.2rem);overflow:hidden}
.hero__bg{position:absolute;inset:0;z-index:0}
.hero__bg::before{content:'';position:absolute;inset:0;background-color:var(--mortar);
  background-image:var(--brickimg);background-size:var(--bricksize)}
/* the scrim: type sits on it, not on bare brick */
.hero__bg::after{content:'';position:absolute;inset:0;z-index:2;
  background:linear-gradient(to top,var(--ink) 26%,rgb(var(--ink-c)/.86) 56%,
    rgb(var(--ink-c)/.34) 82%,rgb(var(--ink-c)/.5) 100%)}
.hero__in{position:relative;z-index:2;max-width:var(--max);margin:0 auto;width:100%}
/* The cover: the mark and the wordmark at display size.

   THE VERSION IN BETWEEN SET THIS AT 1.1rem and that is the one that failed.
   At 1.1rem it sits sixty pixels under the navigation bar's own wordmark at
   nearly the same size, and two copies of one word that close together read as
   a mistake rather than as a masthead. At 7rem beside the hatched mark it is a
   masthead. The nav mark is 1.6rem and flat; this is the hatched cut, which
   needs the size or it reads as dirt. */
.hero__mark{display:flex;align-items:center;gap:clamp(1.2rem,2.8vw,2rem);
  flex-wrap:wrap;margin:0 0 clamp(1.4rem,3vw,2.4rem)}
.hero__logo{width:clamp(4.5rem,8vw,7rem);height:auto;display:block;flex-shrink:0;
  transform:translateY(-0.08em)}
.hero__name{font-family:var(--serif);font-weight:300;line-height:1;
  font-size:clamp(3rem,min(10vw,17vh),7.6rem);font-size:clamp(3rem,min(10vw,17svh),7.6rem);
  letter-spacing:-.025em;color:var(--lime)}
/* The width term is the one that sets the size on a normal screen. The height
   term only ever wins on a viewport that is wide and short — a phone held
   sideways, or a laptop window dragged down to half height — where 12vw asks
   for a word taller than a quarter of the screen and the wall behind it gets
   squeezed to nothing. min() picks whichever axis is scarcer. The vh line is
   the fallback for a browser without svh; the hero's min-height is written the
   same way two rules up. */
/* The ceiling came down from 9.5rem. It only ever binds above about 1270px, so
   this is a desktop-only change, and at 152px the word was carrying more of the
   first screen than the sentence underneath it that says what we sell. */
/* The proposition, under the cover. Not a gold italic aside at a third the
   wordmark's size, which is what it was; not the display line itself, which is
   what the wordmark is for. Large enough to read as the point of the page and
   small enough that the cover is still the cover. */
.hero h1{font-size:var(--h1);line-height:1.12;color:var(--lime-2);
  margin:0 0 clamp(1.5rem,3.2vw,2.6rem);
  max-width:26ch;font-weight:300;letter-spacing:-.01em;
  text-shadow:0 0 26px rgb(var(--ink-c)/.85)}
.hero h1 .l{display:block;overflow:hidden}
.hero h1 .l>i{display:inline-block;font-style:normal}
/* EXPLANATION AND ACTION TOGETHER, which is why this is no longer a
   space-between row with the office line floating in the gap. The paragraph is
   what makes somebody press the button, and it was in the other column. */
.hero__low{display:flex;align-items:flex-end;gap:clamp(1.6rem,4vw,3.4rem);flex-wrap:wrap}
.hero__desc{max-width:52ch;color:var(--lime-3);line-height:1.68;
  text-shadow:0 0 20px rgb(var(--ink-c)/.9),0 0 44px rgb(var(--ink-c)/.8)}
.hero__cta{display:flex;flex-direction:column;align-items:flex-start;gap:.65rem}
.hero__where{font-family:var(--mono);font-size:.74rem;letter-spacing:.06em;color:var(--lime-mute);
  text-shadow:0 0 14px rgb(var(--ink-c)/.9)}
@media(max-width:700px){
  .hero__logo{width:3.5rem}
  .hero__mark{gap:.85rem}
  /* A floor under the box, because the cap above goes inert on a phone and
     leaves the composition short.

     The cap is `calc(19rem + 3.3 * var(--h1))`, and --h1 has bottomed out at its
     3rem floor below about 400px — so the cap stops tracking the content and
     computes 462px on a 390x844 screen. The content is 534px, so the cap binds
     nothing, the hero is whatever the type happens to measure, and it ended at
     63% of the screen: a band of brick over a title, then three hundred pixels
     of flat ink under the button before the ticker. The wall is the composition
     and on a phone there was almost none of it.

     max() keeps both ends. Where the content is already tall — a 375px screen
     puts the description on seven lines — the floor is under it and nothing
     moves. Where it is not, the slack goes above the title, which is where the
     wall is and where every other width already puts it.

     88, not 78. At 78 the arithmetic was right and the picture was still short:
     the hero cleared the fold but the band over the title was 145px, and a
     phone shows the wall as a narrow strip rather than as the full-bleed field a
     desktop does, so the same PROPORTION of brick reads as less wall. 88svh puts
     230px over the title — 42% of the hero against the 30% a 1440px window
     gives — and still leaves 101px of the ticker and the section under it in
     view, which is the scroll cue.

     svh and not vh or dvh: svh is the SMALL viewport, measured with the URL bar
     expanded, so the box is sized for the worst case and the hero grows into the
     space when the bar retracts rather than overflowing out of it. */
  .hero{min-height:max(88vh,min(92vh,calc(19rem + 3.3 * var(--h1))));
    min-height:max(88svh,min(92svh,calc(19rem + 3.3 * var(--h1))))}
}

/* === courses: the hero wall =============================================== */
/* One element per brick course, each carrying the same tile as the rest of the
   site at the right vertical offset, so the bricks are the site's bricks and
   only their position is animated. Built by js/wall.js. */
.courses{position:absolute;inset:0;overflow:hidden;z-index:1;pointer-events:none}
.crs{position:absolute;left:-16px;right:-16px;background-image:var(--brickimg);
  background-size:var(--bricksize);background-repeat:repeat}
.crs::after{content:'';position:absolute;inset:0;
  background:linear-gradient(90deg,rgb(var(--brass-lt-c)/0),rgb(var(--brass-lt-c)/.5),
    rgb(var(--brass-lt-c)/0));
  opacity:0}

/* === ticker =============================================================== */
/* Concrete nouns only: protocols, standards, systems. No adjectives, ever. */
.tick{background:var(--ink);color:var(--lime-faint);overflow:hidden;padding:.6rem 0;
  border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline)}
.tick__t{display:flex;width:max-content}
.tick__r{display:flex;gap:2rem;padding-right:2rem;font-family:var(--mono);font-size:.63rem;
  letter-spacing:.13em;text-transform:uppercase;white-space:nowrap}
.tick__r b{font-weight:400}
.tick__r b em{font-style:normal;color:var(--brass);margin-right:.5rem}

/* the line that introduces an exhibit, and the one sample mark for the whole
   section rather than a disclaimer on every card */
.exhibit__lead{margin-top:clamp(2.4rem,5vw,3.4rem);font-family:var(--sans);font-weight:600;
  font-size:.74rem;letter-spacing:.1em;text-transform:uppercase;color:var(--brass-lt)}
.sample{display:inline;font-family:var(--sans);font-weight:400;font-size:.8rem;
  letter-spacing:0;text-transform:none;color:var(--lime-mute);margin-left:.8rem}

/* === exhibits: the screens ================================================
   Three cards, one product surface at three scopes. Each is paper set inside a
   joinery casing, the same assembly the window openings use, so a screen reads
   as installed in the wall rather than pasted onto the slab. The casing is
   also what stops a flat white rectangle from floating on ink.

   The provenance column is not ornament: an answer is worth what its receipts
   are worth, so the file and the minute it landed are on every evidence row
   and never abbreviated away at small sizes. */
.exhibit{margin-top:var(--head-gap)}
.exhibit__head{margin-top:clamp(3rem,6vw,4.5rem)}
.slab--dark .fine{color:var(--lime-faint)}

.tk{background:var(--joinery);border:1px solid var(--joinery-edge);padding:10px;
  max-width:49rem;box-shadow:var(--lift-3),0 2px 0 rgb(var(--lime-c)/.5) inset}
.tk__in{background:var(--card);color:var(--ink);border:1px solid var(--rule);
  border-top:2px solid var(--brass);box-shadow:0 1px 0 rgb(var(--lime-c)/.7) inset}

/* === document headers =====================================================
   Three exhibits, three kinds of document, three headers that do not look
   alike. Same casing and same paper, because they come out of one system; a
   different masthead, because an email, a printed report and a case file are
   not the same object and a reader knows all three on sight.

   This replaces the typed question field. A line typing itself reads as an
   input only while the animation runs — in calm mode, in a screenshot, or to a
   crawler it was a sentence floating over a card — and it framed all three
   documents as chat, which is the most-copied screenshot in software and reads
   to a skeptic as a wrapper. */
.dh{padding:.85rem 1.3rem;border-bottom:1px solid var(--rule)}
.dh__t{font-family:var(--serif);font-size:clamp(1.08rem,2.3vw,1.32rem);line-height:1.25}
.dh__s{font-family:var(--mono);font-size:.74rem;letter-spacing:.02em;color:var(--ink-soft);
  margin-top:.32rem;line-height:1.5}
.dh__ref{font-family:var(--mono);font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--brass);margin-bottom:.4rem}

/* a printed report: title, then the city and the date it was run for, then the
   double rule a run-off report has under its masthead */
.dh--brief{border-bottom-width:3px;border-bottom-style:double;border-bottom-color:var(--ink);
  padding-bottom:.7rem}

/* a case file: its reference first, the way a file is pulled */
/* the three figures. Tabular numerals, or the eye cannot compare them. */
/* the fields a billing clerk already works in, in reading order */
/* An odd number of fields leaves the last cell of a two-column grid empty, and
   the gap colour shows through it as a grey panel that reads as a broken tile.
   The last field spans instead. Written against the count rather than against
   this one card, so a three-field record and a five-field one both close. */
/* auto-fit rather than a fixed two, so the track count follows the field count
   and there is never a leftover cell to leave a hole. The last-child span hack
   that used to paper over three-in-two is gone with it: that fixed one count,
   not the mechanism. */
/* the unit rides with the figure. A read with no unit on it is a number
   somebody has to go and confirm. */
/* The note was 9.3px mono in a colour that failed contrast, which made the one
   fact saying HOW LONG something has been stuck the least readable thing on the
   card. Sans, 12.5px, passes AA. */
.tk__sec{padding:1rem 1.3rem;border-bottom:1px solid var(--rule)}
.tk__k{font-family:var(--sans);font-weight:600;font-size:.74rem;letter-spacing:.07em;text-transform:uppercase;
  color:var(--brass);display:flex;justify-content:space-between;gap:1rem;margin-bottom:.5rem}
.tk__k em{font-style:normal;color:var(--closed)}
/* what to do before anyone calls it settled. Set as work, not as fine print:
   a caveat smaller than the claim it qualifies is decoration. */
.tk__next{background:var(--paper)}
.tk__next ul{list-style:none;display:grid;gap:.4rem;margin-bottom:.7rem}
.tk__next li{font-size:.89rem;padding-left:1.15rem;position:relative}
.tk__next li::before{content:'';position:absolute;left:0;top:.62em;width:.55rem;height:1px;
  background:var(--brass)}
.tk__next p{font-size:.85rem;color:var(--ink-soft);max-width:60ch}

/* evidence: the system it came from, and what that system says */
.tk__ev .tk__ev--flag span{color:var(--brick)}
.tk__ev--flag b{color:var(--brick)}

/* the actions a screen offers, which are all drafts: nothing here writes to a
   system of record, and the verbs say so */

/* === the answer ===========================================================
   The first thing inside a screen, above the record it came from. Serif and a
   step larger than the fields beneath it, because the reader asked a question
   and this is the reply; everything under it is the working. Paper rather than
   card, so it reads as the card's own statement rather than another field. */
/* === the quote and its citation ===========================================
   The one element on the commitment card that a manager can check against the
   video in ninety seconds. It is set larger than the fields around it and in
   the serif, because everything else on the card is derived from it. */
/* === the track: where one commitment has got to ===========================
   Four states, always all four. Horizontal on a rail above 560px and stacked
   below it, same markup both ways: a track that dropped a state on a phone
   would tell a manager a different story on the way into the meeting.

   The rail is drawn on the ::before of the list rather than between the items,
   so the line does not depend on how the items happen to wrap. Each dot sits on
   it; the state the item has actually reached is the filled one. */
/* The rail is a connector per state, drawn from its own dot to the next one,
   rather than one line across the whole list. A single line has to know how
   many states there are to know where to stop, and commitBudget permits three
   as well as four: at three, a rail measured in quarters stops in mid air. Each
   connector spans 100% of its own item, which is the distance to the next dot
   whatever the count, and the last state has none. */
/* the state it is actually in: brick, and a ring so it reads at a glance
   without a loop animating it. The class A budget is two ambient loops and the
   wall and the rake have both of them. */
@media(min-width:561px){
  .tr{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;margin-top:1.35rem}
  .tr li{display:block;padding:1.05rem .6rem 0 0}
  .tr i{top:0;left:0;margin-top:-4.5px}
  .tr span{display:block;margin-top:.15rem}
  /* the same connectors, turned: each one runs right from its own dot to the
     next, so the rail still ends at the last state and not past it */
  .tr li::after{left:4px;top:0;width:100%;height:1px}
}

/* === the figure: what it is ==============================================
   Many records converge into one line; the line fans back out into things
   somebody opens. Many to one to many, which is the product.

   Borders, not SVG. The convergence is a rule down the inner edge of each side
   column with a stub from every row out to it, so the figure reflows at any row
   count, needs no viewBox, and has no text inside a stretched drawing. Below
   the three-column breakpoint the rails become a top edge and the same
   statement stacks.
   =========================================================================== */
/* the middle is the one thing here that did not exist before */
/* 1000 is the documented breakpoint for "a grid goes three-column", which is
   exactly what this is. Written at 900 first, which made a fifth breakpoint in
   a system whose token block says a fifth means deleting one. */
@media(min-width:1000px){
  .flow{grid-template-columns:1fr minmax(0,15rem) 1fr;align-items:center;
    column-gap:clamp(2.6rem,5vw,4.5rem)}
  /* the rail each side converges into */
  .flow__side::after{content:'';position:absolute;top:2.1rem;bottom:.3rem;width:1px;
    background:var(--hairline)}
  .flow__side--in::after{right:calc(clamp(2.6rem,5vw,4.5rem) / -2)}
  .flow__side--out::after{left:calc(clamp(2.6rem,5vw,4.5rem) / -2)}
  /* and the stub from each row out to it */
  .flow li{position:relative}
  .flow__side--in li::after,.flow__side--out li::before{content:'';position:absolute;
    top:.62em;height:1px;background:var(--hairline)}
  .flow__side--in li::after{left:100%;width:calc(clamp(2.6rem,5vw,4.5rem) / 2)}
  .flow__side--out li::before{right:100%;width:calc(clamp(2.6rem,5vw,4.5rem) / 2)}
  .flow__side--in{text-align:right}
  .flow__side--in .flow__k{text-align:right}
}

/* === the questions ========================================================
   Native <details>: opens with no JavaScript, keyboard-works for free, and a
   crawler reads every answer whether it is open or not. */
/* === desk two: what comes due ============================================
   Date-led. The date is the only thing on this document a manager acts on, so
   it is the first column and set in the mono that carries every other figure on
   the site; the register a row belongs to is metadata behind it.
   =========================================================================== */
/* when it falls due and what kind of thing it is, together */
/* The figure, and under it the document it was read out of. The source is set
   in the sans at the department's size and colour, because it is the same kind
   of fact as the department: a name, not a number. */
/* the one closing first */
/* === plan: the financial schedule =========================================
   Panel three is a real table because the deliverable is a real table, and the
   way anybody checks one is to divide one column into another. Tabular numerals
   so the digits line up in a column; fixed layout so the columns do not shift
   between rows; monospace figures against a serif masthead, which is the
   contrast the rest of the document language on this site already uses.

   The breached year borrows .due--now's vocabulary rather than inventing one:
   --tint-failed behind the row, --brick on the figures. No new colour token. */
/* The gutter is the card's, not the table's: .dh, .tk__sec and .xc>div are all
   inset 1.3rem, so the year column, the masthead and the caution have to start
   on the same left edge or the card reads as two documents stacked. */
.plan__wrap{padding:1.15rem 1.3rem .3rem}
.plan{width:100%;border-collapse:collapse;table-layout:fixed;
  font-variant-numeric:tabular-nums}
.plan th{font-family:var(--mono);font-weight:400;font-size:.58rem;letter-spacing:.11em;
  text-transform:uppercase;color:var(--brass);text-align:right;vertical-align:bottom;
  padding:0 .6rem .5rem;border-bottom:1px solid var(--rule)}
.plan thead th:first-child{text-align:left}
.plan td{font-family:var(--mono);font-size:.82rem;color:var(--ink-soft);text-align:right;
  padding:.62rem .6rem;border-bottom:1px solid var(--rule);white-space:nowrap}
/* the year is a row header, so it is a th that has to shed the column-head
   treatment rather than a td pretending to be a label */
.plan tbody th{font-family:var(--mono);font-weight:400;font-size:.82rem;letter-spacing:0;
  text-transform:none;color:var(--ink);text-align:left;padding:.62rem .6rem;
  border-bottom:1px solid var(--rule)}
/* the outer columns give their padding back to the gutter, or the first figure
   and the last are inset twice and the table floats inside its own card */
.plan th:first-child,.plan td:first-child{padding-left:0}
.plan th:last-child,.plan td:last-child{padding-right:0}
.plan tbody tr:last-child th,.plan tbody tr:last-child td{border-bottom:0}
/* The tint spans the table and stops at its edges rather than bleeding to the
   card's, which is where a highlighted row stops in a printed schedule: the
   band then lines up with the header rule and every row rule under it. */
/* The consumption panel's last column is a sentence and not a figure. Every
   other .plan column is a number and reads right; the reason column is the one
   the exhibit exists for and it reads left, with the heading over it. */
/* .plan td is white-space:nowrap, which is right for a figure and wrong for a
   sentence: at 49rem the reason ran out through the card's right edge instead
   of wrapping. The reasons are short enough to sit on one line at this width;
   this is the guard for the one that is not, and for a narrow window. */
.plan--why td:last-child,.plan--why th:last-child{text-align:left}
.plan--why td:last-child{white-space:normal;line-height:1.45}
.plan .plan--off th,.plan .plan--off td{background:var(--tint-failed);color:var(--brick)}
.plan .plan--off th{font-weight:500}
.plan__src{font-family:var(--mono);font-size:.68rem;line-height:1.6;color:var(--faint);
  padding-top:.85rem}

/* --- the scenario switch --------------------------------------------------
   Radios and labels, no script. The input is clipped rather than display:none
   so it keeps its place in the tab order: a control a keyboard cannot reach is
   not a control. Sibling selectors do the rest, which is why the inputs are
   emitted before the tabs and the panes.

   The panes are stacked in one grid cell rather than toggled with display, so
   the card does not change height on switch and the swap can cross-fade. Both
   runs carry the same six years, which planBudget insists on, so the two panes
   are the same height and nothing moves. */
.plan__r{position:absolute;width:1px;height:1px;margin:0;padding:0;
  clip-path:inset(50%);overflow:hidden;white-space:nowrap}
.plan__tabs{display:flex;gap:.45rem;margin-bottom:1rem}
.plan__tabs label{position:relative;overflow:hidden;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.11em;
  text-transform:uppercase;color:var(--faint);cursor:pointer;padding:.4rem .75rem;
  border:1px solid var(--rule);
  transition:color .25s var(--ease-reveal),border-color .25s var(--ease-reveal),
    background-color .25s var(--ease-reveal)}
.plan__tabs label:hover{color:var(--brass);border-color:var(--brass)}
.plan__r:nth-of-type(1):checked~.plan__tabs label:nth-child(1),
.plan__r:nth-of-type(2):checked~.plan__tabs label:nth-child(2){
  color:var(--ink);border-color:var(--ink);background:var(--paper)}
/* the focus ring lands on the label, because the input it belongs to is clipped */
.plan__r:nth-of-type(1):focus-visible~.plan__tabs label:nth-child(1),
.plan__r:nth-of-type(2):focus-visible~.plan__tabs label:nth-child(2){
  outline:2px solid var(--brass);outline-offset:2px}
/* Both runs occupy one grid cell so the card does not change height on switch.
   The cost of stacking them is that a plain crossfade draws both at once, and
   because the two tables are the same shape with different figures in it, that
   half second rendered every number on top of its counterpart. It read as a
   fault, not as a transition.

   So the fades are sequenced rather than crossed: the outgoing run is gone in
   160ms and the incoming one does not begin until 180ms. There is no frame in
   which both carry ink. */
.plan__panes{display:grid}
.plan__pane{grid-area:1/1;opacity:0;visibility:hidden;
  transition:opacity .16s var(--ease-reveal),visibility 0s linear .16s}
.plan__r:nth-of-type(1):checked~.plan__panes .plan__pane:nth-child(1),
.plan__r:nth-of-type(2):checked~.plan__panes .plan__pane:nth-child(2){
  opacity:1;visibility:visible;
  transition:opacity .3s var(--ease-reveal) .18s,visibility 0s linear}
@media(max-width:560px){
  .plan__tabs label{font-size:.55rem;padding:.35rem .55rem}
}
@media(max-width:560px){
  .plan__wrap{padding-inline:1rem}
  .plan th{font-size:.5rem;padding-inline:.3rem}
  .plan td,.plan tbody th{font-size:.72rem;padding-inline:.3rem}
  .plan__src{font-size:.64rem}
}

/* The category is one of six and the department is an open-ended name, so they
   do not look alike: the category carries a colour from the verdict palette and
   a swatch, the department is plain text. Two identical badges side by side
   would have said they were the same kind of fact. */
.cat{display:inline-flex;align-items:center;gap:.4rem;margin-top:.4rem;
  font-family:var(--sans);font-size:.74rem;color:var(--ink-soft)}
.cat::before{content:'';width:9px;height:9px;flex-shrink:0}
/* === three answers =======================================================
   One column. A title beside a sentence made a reader parse a label before
   reading a sentence that already contained it. */
/* the outcome where the answer is no */
/* === desk three: the position ============================================
   Five figures, none of them ours. The measure leads because a finance director
   reads down the measures; the value is serif and large because it is the thing
   that goes in the transmittal letter; what it ties to is stated on every row,
   because a figure whose source is not named is a figure he has to go and check.
   =========================================================================== */
@media(max-width:560px){
  .pos li{grid-template-columns:minmax(0,1fr)}
  .pos u{grid-row:auto;text-align:left;white-space:normal}
}

/* === desk one: the weekly exchange ========================================
   Two objects, and the difference between them has to be obvious at a glance:
   one is a message in somebody's inbox, the other is ours.

   THE THREAD is the plainest thing on the page. No joinery casing, no brass
   rule, no section captions. Two stamped messages in sequence, because quoting
   the reply underneath put it where a mail client puts the EARLIER message and
   it read as though the director had written first.

   THE RECORD OF IT sits outside the paper, on the slab, in our type. It was in
   the margin and that was wrong twice over: the readings are the product rather
   than a gloss on it, so small grey text off to the right buried them; and they
   were pinned to the items we sent while being derived from the reply below, so
   every conclusion sat above its own evidence. The numerals are the join.
   =========================================================================== */
.desk{position:relative}
.desk__who{font-family:var(--sans);font-weight:600;font-size:.74rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brass-lt);margin-bottom:.6rem}
.desk__ask{font-family:var(--serif);font-size:clamp(1.3rem,3vw,1.75rem);line-height:1.2;
  color:var(--lime-hi);max-width:26ch;margin-bottom:clamp(1.4rem,3vw,2rem)}

/* the stamp: who, to whom, when. Plain, small, and never micro-caps — an
   addressing line set as micro-caps is the surest tell of a fake email. */
/* the second way to answer, drawn as the link it is in the real mail. Brass and
   underlined, which is what a link looks like everywhere else on light here. It
   is a <u> and not an <a>: the recipient is invented and so is the form it would
   open, so nothing on this exhibit is clickable. */
/* his reply is a second message, not a quotation of an earlier one */
/* ours. Off the paper, on the slab, keyed by the numerals he answered against. */
/* the one it would not take */
/* === the composition: the whole book in one bar ===========================
   The segments are flex-grown by their own counts, so the bar is the
   arithmetic rather than a drawing of it: a segment cannot be the wrong width
   without the number beside it being wrong too.

   The tones are tokens.css's verdict palette, which already carries these
   meanings elsewhere on the site. Nothing here invents a colour. */
@media(max-width:560px){.mx__key{grid-template-columns:minmax(0,1fr)}}

/* The chart and the block-map blocks lived here. Their only consumer was the
   water utility landing page's high-bill screen, which this page no longer
   renders, and the components went with it in the same commit.
   =========================================================================== */

/* === the short list: rows to look at ====================================== */
/* money drawn to scale under its own row. Values that are not money — a rank,
   a count — get no bar, which is what keeps three screens from being one screen
   three times. */
/* the sum, in the card rather than in the heading: the figure is only worth
   something with the four rows above it, and it says what average it used */

@media(min-width:560px){
  .tk__ev>div{grid-template-columns:9.5rem 1fr;align-items:baseline}
  .xc>div{grid-template-columns:1fr 7rem;align-items:baseline}
  .xc u{grid-row:1 / span 2;grid-column:2;text-align:right}
}
@media(max-width:560px){
  .tk{padding:6px}
  .tk__stats{grid-template-columns:1fr}
  /* Every block inside a card shares the card's gutter, so the masthead, the
     rows, the schedule and the caution start on one left edge. .cm__ans and
     .pos li were missing from this list and sat 5px inside everything above
     them, which is visible as a step on a phone once a card carries four
     blocks rather than two. */
  .dh,.tk__sec,.xc>div,.cm__ans,.pos li{padding-inline:1rem}
  .tk__stats{grid-template-columns:1fr}
}

/* === rake: ambient hex field ============================================== */
/* Class A only, one maximum. Drawn by js/rake.js, paused off-screen, and
   bounded there: a fixed budget of on-screen seconds, then the last frame
   stays.

   pointer-events:none and the z-index below are load-bearing, not tidiness.
   The canvas is an absolutely positioned sibling that precedes the content it
   sits behind, which puts it above that content in the paint order: it was
   taking the text selection and the touch scroll over both exhibits, which are
   the two documents the section exists to let somebody read. Raising the
   following .wrap out of the way costs a stacking context and nothing else. */
.rake{position:absolute;inset:0;width:100%;height:100%;opacity:.55;
  pointer-events:none;z-index:0}
.rake+.wrap{position:relative;z-index:1}

/* === rows: the .r workhorse =============================================== */
/* Serif title + one sentence. Capabilities, deliverables, defect classes, FAQ. */
/* the brass rule that measures itself out along a row as it arrives, then
   fades, leaving the hairline. Invisible at rest. */
@media(min-width:861px){.r{grid-template-columns:17rem 1fr}}

/* === strip: domain cells ================================================== */
/* rules on the cells, nothing painted behind them — see .tk__stats */
@media(min-width:700px){
  .strip{grid-template-columns:repeat(4,1fr)}
  .dm{padding:1.3rem 1.3rem 1.5rem}
  .dm b{font-size:1.2rem}
  .dm p{font-size:.87rem}
}

/* === glass ================================================================ */
/* A panel over brick. Never raw text on brick. */
.glass{position:relative;display:inline-block;max-width:56rem;
  background:var(--glass);backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);
  border:1px solid var(--hairline-lt);
  padding:clamp(1.2rem,2.5vw,1.7rem) clamp(1.2rem,2.5vw,1.9rem);box-shadow:var(--lift-2)}
.glass h2{font-size:clamp(1.7rem,3.8vw,2.7rem);color:var(--lime);max-width:22ch}

/* === wins: window openings ================================================ */
.people::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgb(var(--shadow-c)/.22),rgb(var(--shadow-c)/.06) 32%,
    rgb(var(--shadow-c)/.22))}
.wins{display:grid;gap:clamp(2rem,4vw,3rem);margin-top:clamp(2.2rem,4vw,3.2rem)}
.win{max-width:24rem;width:100%;margin:0 auto}
@media(min-width:700px){.wins{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.wins{grid-template-columns:repeat(3,1fr)}}

/* assembled in the order a mason works: lintel, casing, sash, glass, sill,
   apron, then the nameplate */
.win__lintel{height:30px;background-image:var(--soldier);background-size:72px 34px;
  margin:0 -14px;border:1px solid rgb(var(--shadow-c)/.35);box-shadow:var(--lift-1)}
.win__casing{background:var(--joinery);padding:11px;border:1px solid var(--joinery-edge);
  box-shadow:var(--lift-3),0 2px 0 rgb(var(--lime-c)/.5) inset}
.win__sash{background:var(--joinery-lt);padding:13px 12px 20px;border:1px solid var(--joinery-edge-2);
  box-shadow:0 1px 0 rgb(var(--lime-c)/.7) inset}
.win__glass{position:relative;aspect-ratio:5/6;overflow:hidden;
  background:linear-gradient(165deg,var(--pane-1),var(--pane-2) 60%,var(--pane-3));
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 1px rgb(var(--shadow-c)/.35),inset 0 10px 26px rgb(var(--shadow-c)/.45)}
.win__glass img{width:100%;height:100%;object-fit:cover;display:block;object-position:center top;
  clip-path:inset(calc((1 - var(--fill,1)) * 100%) 0 0 0)}
.win__glass::after{content:'';position:absolute;top:-40%;left:-70%;width:46%;height:200%;
  background:linear-gradient(90deg,rgb(var(--lime-c)/0),rgb(var(--lime-c)/.34),rgb(var(--lime-c)/0));
  transform:rotate(15deg);transition:left .95s ease}
.win:hover .win__glass::after{left:140%}
.win__sill{height:12px;background:linear-gradient(180deg,var(--sill-hi),var(--sill-lo));
  border:1px solid var(--sill-edge);margin:0 -18px;box-shadow:var(--lift-1)}
.win__apron{height:7px;background:var(--apron);border:1px solid var(--sill-edge);
  border-top:0;margin:0 -8px}
.win__link{display:block;text-decoration:none;color:inherit}
.win__link:hover .win__cap b{color:var(--brass-lt)}
.win__cap{margin-top:1.05rem;text-align:center;background:var(--glass);
  backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);
  border:1px solid var(--hairline-lt);padding:1rem 1.1rem 1.15rem;box-shadow:var(--lift-2)}
.win__cap b{display:block;font-family:var(--serif);font-weight:300;font-size:1.34rem;color:var(--lime)}
.win__cap span{display:block;font-family:var(--sans);font-weight:500;font-size:.76rem;letter-spacing:.04em;
  text-transform:uppercase;color:var(--brass-lt);margin-top:.4rem}
.win__cap p{font-size:.86rem;color:var(--lime-3);line-height:1.55;margin-top:.65rem}
@media(max-width:700px){
  .win__lintel{margin:0 -10px}
  .win__sill{margin:0 -12px}
  .win__apron{margin:0 -6px}
}

/* === contact ============================================================== */
.ct__grid{display:grid;gap:1.8rem clamp(1.8rem,5vw,4rem)}
.ct h2{font-size:clamp(1.9rem,4.4vw,3.2rem);max-width:16ch}
.ct h2 em{font-style:italic;color:var(--brick)}
.ct p{color:var(--ink-soft);max-width:44ch;margin-top:.9rem}
.ct__mail{display:inline-block;margin-top:1.2rem;font-family:var(--serif);
  font-size:clamp(1.3rem,2.6vw,1.75rem);text-decoration:none;border-bottom:1px solid var(--brass)}
.ct__mail:hover{color:var(--brick);border-color:var(--brick)}
@media(min-width:861px){.ct__grid{grid-template-columns:1fr 1fr;align-items:start}}

/* === facts ================================================================ */
/* mono dt in brass, sans dd. Closes with a bottom hairline or the list reads
   unresolved. */
.facts dl{border-top:1px solid var(--rule);margin-bottom:1.6rem}
.facts dl>div{display:grid;gap:.15rem .9rem;padding:.7rem 0;border-bottom:1px solid var(--rule)}
.facts dt{font-family:var(--sans);font-weight:600;font-size:.76rem;letter-spacing:.05em;
  color:var(--brass)}
.facts dd{font-size:.92rem;color:var(--ink-soft)}
@media(min-width:560px){.facts dl>div{grid-template-columns:10.5rem 1fr;align-items:baseline}}
.slab--dark .facts dl,.slab--dark .facts dl>div{border-color:var(--hairline)}
.slab--dark .facts dd{color:var(--lime-mute)}

/* === section heading on a dark slab ======================================= */
.slab--dark h2{font-size:clamp(1.7rem,4.2vw,3rem);color:var(--lime-hi);max-width:22ch}

/* === fixture banner ======================================================
   Shown on every page when ALLOW_FIXTURE=1. Impossible to miss, and it says the
   one thing that matters about the page. */
.fixture{background:var(--brick);color:var(--lime);padding:.7rem 1rem;text-align:center;
  font-family:var(--mono);font-size:.7rem;letter-spacing:.08em;text-transform:uppercase}

/* === footer =============================================================== */
.foot{background:var(--ink-2);color:var(--lime-3)}
.foot__in{max-width:var(--max);margin:0 auto;padding:2.2rem var(--gut);display:grid;gap:1.2rem}
.foot__name{font-family:var(--serif);font-size:1.55rem;color:var(--lime-hi);margin-bottom:.25rem}
.foot__in p{font-size:.9rem;color:var(--lime-mute)}
.foot__links{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;align-content:start}
.foot__links a,.foot__motion{font-family:var(--sans);font-weight:500;font-size:.78rem;
  letter-spacing:.14em;text-transform:uppercase;text-decoration:none}
.foot__links a:hover,.foot__motion:hover{color:var(--lime-hi)}
/* Ten links in a wrapping row, each 20px tall with an 8px gutter between rows.
   On a phone that is ten 20px targets with 8px of miss between them, and the
   footer is where the service and methodology pages are reached from. The row
   gap comes down as the padding goes up, so each target clears 44px and the
   block grows by about 12px a row rather than doubling. Coarse pointers only. */
@media(pointer:coarse){
  .foot__links{gap:0 1.5rem}
  .foot__links a,.foot__motion{padding-block:.7rem}
}
.foot__motion{background:none;border:0;padding:0;cursor:pointer;color:inherit}
.foot__bar{border-top:1px solid rgb(var(--lime-c)/.1)}
.foot__bar div{max-width:var(--max);margin:0 auto;padding:.85rem var(--gut);display:flex;
  flex-wrap:wrap;gap:.4rem 1.5rem;justify-content:space-between;font-family:var(--mono);
  font-size:.74rem;letter-spacing:.04em;color:var(--lime-mute)}
@media(min-width:700px){.foot__in{grid-template-columns:1.5fr 2fr}}

/* === aj: how a filing is adjudicated ======================================
   The mechanism as a numbered course, in markup rather than SVG so it reflows,
   is selectable, and is read by anything that reads text. The last beat is the
   refusal and is marked in brick: it is the only state on this figure that a
   competitor cannot copy by re-running the same joins. */
@media(min-width:860px){
  .aj{grid-template-columns:repeat(4,1fr);border-top:0}
  .aj__b{padding:1.4rem 1.3rem 1.6rem 0;border-top:1px solid var(--hairline);border-bottom:0}
  .aj__b--no::before{left:auto;right:0;top:0;bottom:0;width:2px}
}

/* === rf: what is not published ============================================ */
@media(min-width:700px){.rf li{grid-template-columns:13rem 1fr;align-items:baseline}}

/* === hero: the second, quieter path =======================================
   A page offering only a conversation is a page with nothing to show. */
.hero__alt{font-family:var(--sans);font-weight:500;font-size:.72rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--lime-soft);text-decoration:none;
  border-bottom:1px solid var(--hairline-lt);padding-bottom:.2rem}
.hero__alt:hover{color:var(--brass-hi);border-bottom-color:var(--brass)}

/* === sr: what we assemble =================================================
   Four registers side by side, so the breadth is visible before it is
   described. This replaced a strip of counts about the corpus: those aged on
   every ingest, and they described one source spine as though it were the
   whole business. */
.sr{display:grid;gap:0;margin-top:var(--head-gap);
  border-top:1px solid var(--hairline);border-left:1px solid var(--hairline)}
.sr__g{padding:1.2rem 1.1rem 1.4rem;
  border-bottom:1px solid var(--hairline);border-right:1px solid var(--hairline)}
.sr__g h3{font-family:var(--sans);font-weight:500;font-size:.68rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--brass);margin:0 0 .9rem}
.sr__g ul{list-style:none;display:grid;gap:.55rem;margin:0;padding:0}
.sr__g li{font-size:.9rem;line-height:1.45;color:var(--lime-2)}
@media(min-width:560px){.sr{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){
  .sr{grid-template-columns:repeat(4,1fr)}
  .sr__g{padding:1.4rem 1.3rem 1.6rem}
}

/* === jn: the joins ========================================================
   The inputs read as an addition, because that is what a join is, and the
   actor closes each one: a crossing nobody acts on is a diagram. */
/* Two rows, not three. The knowable text spanning two rows left the actor line
   stranded a long way below the name it belongs to; the crossing reads across,
   so the rows have to line up across: inputs beside what they show, name beside
   who acts on it. */
/* Left column carries the scenario: its sources, its title, and who uses it.
   Right column carries the description, aligned to the top.

   "Used by" was in the right column under the description, which put it in the
   row sized by the tall serif title and stranded it a long way beneath the
   sentence it belongs to. */
@media(min-width:860px){
  .jn__i{display:grid;grid-template-columns:minmax(0,20rem) minmax(0,1fr);
    column-gap:clamp(2rem,4vw,3.5rem);row-gap:.75rem;align-items:start}
  .jn__from{grid-column:1;grid-row:1;margin-bottom:0}
  .jn__i h3{grid-column:1;grid-row:2;margin:0}
  .jn__acts{grid-column:1;grid-row:3;margin:0}
  .jn__knows{grid-column:2;grid-row:1/span 3;align-self:start}
}

/* === cp: what compounds ===================================================
   The catch-up line is the point of each card, so it is set apart from the
   body rather than running on from it. */
@media(min-width:860px){
  .cp{grid-template-columns:repeat(3,1fr);border-top:0}
  .cp__i{padding:1.4rem 1.4rem 1.6rem 0;border-top:1px solid var(--hairline);border-bottom:0}
}

/* The record section's one paragraph, on the light slab. */
.rc__body+.btn{margin-top:1.6rem}
