/* ============================================================
   CHORD33 · v10 · the homepage that moves across
   The page is one long track that travels left as you scroll. Ink
   black ground, a dark slate and an evergreen as the two coloured
   grounds, a blue slate band as the second material, deep teal as the
   voice. Nothing moves that does not show something true about the
   work: cards are dealt from our hand into yours, a line fills toward
   the step that is yours, a picture comes through the hatch when you
   ask for it.
   ============================================================ */

/* ---------- 0 · Tokens ----------
   The slate palette, chosen 2026-09-14 from ten swatches. Each colour
   has one job and never swaps it:
     ink black          the ground; jet and charcoal are its raised planes
     dark slate         the work panel's ground, and the solid fills
     evergreen          the process panel's ground
     blue slate         the band, the second material
     deep teal          the second voice of a headline, never body text;
                        its two tints point (links) and speak on colour
     dim grey           structure: the rail marker, ticks, the nodes at rest
     taupe grey         the frame around a picture
   The type is a cool off white throughout.
   ---------------------------------------------------------------- */
:root{
  --ink-black:#0D0E14; --jet:#252933; --charcoal:#404556; --taupe:#60515C; --dim-grey:#777076;
  --teal:#597D7C; --blue-slate:#386775; --dark-slate:#20504E; --evergreen:#193D31; --jet-2:#17292B;
  --teal-2:#86B0AE; --teal-3:#A9CBC9;

  --well:    #0D0E14;
  --bg:      #0D0E14;
  --ink:     #17292B;
  --panel:   #252933;
  --panel-2: #404556;

  --line:  rgba(238,241,241,.12);
  --line2: rgba(238,241,241,.28);
  --frame: rgba(96,81,92,.6);

  --text: #EEF1F1;
  --mut:  #C9CBCB;
  --dim:  #9C9A99;

  --act:       #86B0AE;
  --act-solid: #20504E;
  --act-2:     #386775;
  --act-ink:   #EEF1F1;

  --em:      #597D7C;
  --mark:    #777076;
  --mark-2:  #9C9A99;

  /* the two answers on a tier: what a size includes and what it does not.
     Lifted well clear of the blue slate the cards are cut from, and told
     apart by their shape and by the dimmed row as well as by the colour,
     because a card this mid-toned cannot carry a dark red at any weight. */
  --yes: #6FD79A;
  --no:  #F47C68;

  /* data colours, added 2026-09-16 for the dashboard: charts, chips and dots
     only, fixed to what they stand for, never chrome or type. A second hue
     appears nowhere else. Checked against the jet surface for colour
     blindness, chroma and contrast, all passing. */
  --data-1: #2BA8A0;
  --data-2: #C98500;
  --data-3: #3987E5;
  --data-4: #D55181;

  --paper:      #386775;
  --paper-ink:  #EEF1F1;
  --paper-mut:  #D5E0E2;
  --paper-line: rgba(238,241,241,.2);

  /* the process line's colour run, first step to the step that is yours */
  --run-1: #597D7C;
  --run-2: #86B0AE;
  --run-3: #A9CBC9;
  --run-4: #C9CBCB;
  --run-5: #EEF1F1;

  --font-d: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-b: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-m: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --wd: 112%;

  --d1: clamp(44px, 7.6vw, 168px);
  --d2: clamp(34px, 4.6vw, 88px);
  --d3: clamp(22px, 2.3vw, 36px);
  --voice: clamp(19px, 1.45vw, 26px);
  --lede: clamp(16px, 1.15vw, 18.5px);

  --pad: clamp(20px, 4.2vw, 120px);
  --sec: clamp(88px, calc(13 * var(--vhu)), 176px);
  --r: 10px;
  --head: 72px;

  /* three curves and nothing else */
  --ease-out:   cubic-bezier(.19, 1, .22, 1);
  --ease-inout: cubic-bezier(.76, 0, .24, 1);
  --ease-hover: cubic-bezier(.33, 1, .68, 1);
  --t-hover: 200ms;
  --t-leave: 150ms;
  --t-reveal: 700ms;
  --t-move: 1100ms;
}
/* Dark slate and evergreen: two coloured grounds for two panels, so the
   page changes material as it moves, the way the band does. */
.ground-slate{
  background:var(--dark-slate); color:#EEF1F1;
  --bg:var(--dark-slate); --panel:#2A5E5B; --panel-2:#386775; --text:#EEF1F1; --mut:#D0DCDB; --dim:#A9BDBC;
  --line:rgba(238,241,241,.16); --line2:rgba(238,241,241,.34); --frame:rgba(238,241,241,.24);
  --em:#A9CBC9; --act:#EEF1F1; --act-solid:#0D0E14; --act-2:#17292B; --act-ink:#EEF1F1; --mark:#A9CBC9; --mark-2:#D5E0E2;
}
.ground-green{
  background:var(--evergreen); color:#EEF1F1;
  --bg:var(--evergreen); --panel:#224A3D; --panel-2:#20504E; --text:#EEF1F1; --mut:#CDDAD5; --dim:#A6BBB4;
  --line:rgba(238,241,241,.16); --line2:rgba(238,241,241,.34); --frame:rgba(238,241,241,.26);
  --em:#A9CBC9; --act:#EEF1F1; --act-solid:#386775; --act-2:#597D7C; --act-ink:#EEF1F1; --mark:#86B0AE; --mark-2:#A9CBC9;
}
/* The band: every token re-scoped, so anything set on it is right. */
.paper{
  background:var(--paper); color:var(--paper-ink);
  --bg:var(--paper); --well:#20504E; --panel:#42727F; --panel-2:#597D7C;
  --text:var(--paper-ink); --mut:var(--paper-mut); --dim:#D5E0E2;
  --line:var(--paper-line); --line2:rgba(238,241,241,.42); --frame:rgba(238,241,241,.3);
  --em:#A9CBC9; --act:#EEF1F1; --act-solid:#0D0E14; --act-2:#17292B; --act-ink:#EEF1F1;
  --mark:#A9CBC9; --mark-2:#D5E0E2;
}

/* ---------- 1 · Reset and ground ---------- */
*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0; }
html{ scroll-behavior:auto; }
html,body{ background:var(--bg); }
body{
  font-family:var(--font-b); font-size:16px; line-height:1.6; color:var(--text);
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
::selection{ background:var(--act-solid); color:var(--act-ink); }
img,svg,canvas,iframe{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
ul,ol{ list-style:none; }

.skip{ position:fixed; left:-999px; top:14px; z-index:300; background:var(--act-solid); color:var(--act-ink);
  padding:10px 18px; font-family:var(--font-m); font-size:13px; border-radius:999px; }
.skip:focus{ left:14px; }
:focus-visible{ outline:2px solid var(--mark); outline-offset:3px; border-radius:2px; }
.btn:focus-visible{ border-radius:999px; }

/* ---------- 1b · The pointer ----------
   Nothing of ours. The cursor is the operating system's own everywhere,
   which is why there is no art, no hot spot and no switching here. The one
   line kept is the hand on things that can be clicked but are not links,
   because a browser draws its plain arrow over those by default. */
button, summary, [role="button"], .btn, .icon-btn, .slot{ cursor:pointer; }

/* ---------- 2 · Mono instrument voice ---------- */
.m{ font-family:var(--font-m); font-weight:500; font-size:11.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--dim); }
.m b{ color:var(--mut); font-weight:500; }
.m .tick{ color:var(--mark); }
.m a{ color:var(--mut); text-decoration:underline; text-decoration-color:var(--line2); text-underline-offset:3px; }

/* ---------- 3 · Header: a floating bar ----------
   The bar sits inset from the top and between the page's gutters, on a
   low wash over a heavy blur, so it takes the colour of whatever passes
   under it. The mark on the left; on the right the one call to action
   and the menu button. Every link lives behind the menu button at every
   width, in a panel that drops from the bar's right end. Fully round at
   both ends, the same shape the buttons take, and capped in width so a
   wide monitor gets a bar and not a band. The fixed element is
   a transparent rail with pointer events off, so the gutters either side
   of the bar never swallow a click on the page beneath. */
.site-head{ position:fixed; top:0; left:0; right:0; z-index:120; padding:14px var(--pad) 0; pointer-events:none; }
.head-row{ pointer-events:auto; position:relative; display:flex; align-items:center; justify-content:space-between; gap:20px;
  width:100%; max-width:1240px; margin-inline:auto;
  padding:10px 12px 10px 22px; border:1px solid rgba(238,241,241,.1); border-radius:999px; }
/* the bar's own wash and blur, on a layer of its own so the bar does not
   become the root of what the menu hanging below it is able to filter */
.head-row::before{ content:""; position:absolute; z-index:-1; inset:0; border-radius:inherit; pointer-events:none;
  background:color-mix(in srgb, var(--bg) 55%, transparent);
  backdrop-filter:blur(20px) saturate(1.8); -webkit-backdrop-filter:blur(20px) saturate(1.8); }
.mark{ display:flex; align-items:center; gap:12px; }
.mark svg{ width:26px; height:26px; color:var(--text); }
.wordmark{ font-family:var(--font-m); font-weight:600; font-size:14px; letter-spacing:.24em; text-transform:uppercase; color:var(--text); }
.head-actions{ display:flex; align-items:center; gap:8px; }
.nav-cta{ display:inline-flex; align-items:center; gap:10px; height:34px; padding:0 18px; border-radius:999px; white-space:nowrap;
  font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--act); border:1px solid color-mix(in srgb, var(--act) 45%, transparent);
  transition:background var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover), color var(--t-leave) var(--ease-hover); }
.nav-cta .arw{ display:inline-block; transition:translate var(--t-leave) var(--ease-hover); }
.icon-btn{ width:34px; height:34px; flex:none; display:inline-flex; align-items:center; justify-content:center; padding:0;
  border:1px solid var(--line2); border-radius:999px; color:var(--mut);
  transition:color var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover), background var(--t-leave) var(--ease-hover); }
.icon-btn svg{ width:16px; height:16px; display:block; }
.icon-btn[aria-expanded="true"]{ color:var(--text); border-color:var(--mark-2); background:rgba(238,241,241,.06); }

/* ---------- 4 · The menu: a panel under the bar ----------
   The same material as the bar it hangs from: the ground at a little over
   half, a heavy blur behind it and the corners rounded to match. The bar
   wears its own blur on a layer rather than on itself, because an element
   that filters its backdrop becomes the root of what any descendant can
   filter, and this panel hangs outside the bar's box: given the blur
   directly, it would have had nothing of the page left to work on. The
   shadow still does the separating. */
.nav{ position:absolute; top:calc(100% + 8px); right:0; min-width:260px; display:grid; padding:8px;
  background:color-mix(in srgb, var(--bg) 62%, transparent); border:1px solid rgba(238,241,241,.1); border-radius:16px;
  backdrop-filter:blur(20px) saturate(1.8); -webkit-backdrop-filter:blur(20px) saturate(1.8);
  box-shadow:0 20px 44px rgba(0,0,0,.6);
  opacity:0; visibility:hidden; translate:0 -6px;
  transition:opacity var(--t-leave) var(--ease-hover), translate var(--t-leave) var(--ease-hover), visibility 0s linear var(--t-leave); }
.nav.open{ opacity:1; visibility:visible; translate:0 0;
  transition:opacity var(--t-hover) var(--ease-hover), translate var(--t-hover) var(--ease-hover); }
.nav a{ font-size:15px; color:var(--mut); padding:10px 12px; border-radius:10px;
  transition:color var(--t-leave) var(--ease-hover), background var(--t-leave) var(--ease-hover); }
.nav a[aria-current="page"]{ color:var(--text); background:rgba(238,241,241,.03); }

/* ---------- 5 · Type ladder ---------- */
.d1,.d2,.d3{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); text-transform:uppercase; letter-spacing:-.035em; line-height:.92; text-wrap:balance; }
.d1{ font-size:var(--d1); line-height:.88; letter-spacing:-.04em; }
.d2{ font-size:var(--d2); line-height:.94; }
.d3{ font-size:var(--d3); font-weight:700; font-stretch:104%; letter-spacing:-.02em; line-height:1.05; text-transform:none; }
.em{ color:var(--em); }
.lede{ font-size:var(--lede); line-height:1.6; color:var(--mut); max-width:56ch; }
.lede b,.lede strong{ color:var(--text); font-weight:600; }
h3{ font-family:var(--font-d); font-weight:700; font-stretch:106%; font-size:var(--d3); letter-spacing:-.02em; line-height:1.1; }

/* ---------- 6 · Buttons and links ---------- */
.btn{ position:relative; display:inline-flex; align-items:center; gap:12px; font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--text); border:1px solid var(--line2); border-radius:999px; padding:14px 22px; overflow:hidden; isolation:isolate; white-space:nowrap;
  transition:color var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover); }
.btn::before{ content:""; position:absolute; inset:-1px; background:var(--text); border-radius:999px; transform:scaleX(0); transform-origin:left;
  transition:transform var(--t-leave) var(--ease-hover); z-index:-1; }
.btn .arw{ display:inline-block; transition:translate var(--t-leave) var(--ease-hover); }
.btn-act{ background:var(--act-solid); border-color:var(--act-solid); color:var(--act-ink); }
.btn-act::before{ background:var(--act-2); }
.link-line{ position:relative; color:var(--text); font-size:15px; display:inline-block; padding-bottom:2px; }
.link-line::after{ content:""; position:absolute; left:0; bottom:0; width:100%; height:1px; background:var(--act); transform:scaleX(0); transform-origin:right;
  transition:transform var(--t-leave) var(--ease-hover); }
@media (hover:hover){
  .nav-cta:hover{ background:color-mix(in srgb, var(--act) 10%, transparent); border-color:var(--act); color:var(--teal-3); transition-duration:var(--t-hover); }
  .nav-cta:hover .arw{ translate:4px 0; }
  .icon-btn:hover{ color:var(--text); border-color:var(--mark-2); background:rgba(238,241,241,.045); transition-duration:var(--t-hover); }
  .nav a:hover{ color:var(--text); background:rgba(238,241,241,.045); transition-duration:var(--t-hover); }
  .m a:hover{ color:var(--text); text-decoration-color:var(--act); }
  .btn:hover{ color:var(--bg); border-color:var(--text); transition-duration:var(--t-hover); }
  .btn:hover::before{ transform:scaleX(1); transition-duration:var(--t-hover); }
  .btn:hover .arw{ translate:5px 0; transition-duration:var(--t-hover); }
  .btn-act:hover{ color:var(--act-ink); border-color:var(--act-2); }
  .link-line:hover::after{ transform:scaleX(1); transform-origin:left; transition-duration:var(--t-hover); }
}

/* ---------- 7 · The track ----------
   One fixed stage, a flex row of panels inside it, translated by the
   script as you scroll. The spacer gives the document its height so
   the native scroll, the keyboard and the scrollbar position all keep
   working. Below 900 px and under reduced motion the track is a plain
   column and every rule here stands down. */
.stage{ position:relative; }
.track{ display:block; position:relative; }
.panel{ position:relative; padding:calc(var(--head) + calc(6 * var(--vhu))) var(--pad) calc(10 * var(--vhu)); }
.spacer{ height:0; }
.flyers{ display:none; }

html.h{ scrollbar-width:none; }
html.h::-webkit-scrollbar{ display:none; }
html.h body{ overflow-x:hidden; }
/* sticky rather than fixed: the stage holds one screen of height in the flow
   and stays put while the spacer scrolls under it, then leaves with the
   scroller so the footer after it can be reached by scrolling down */
html.h .stage{ position:sticky; top:0; height:calc(100 * var(--vhu)); overflow:hidden; z-index:10; }
html.h .track{ display:flex; height:100%; will-change:transform; }
html.h .panel{ flex:0 0 auto; height:100%; width:100vw; padding-bottom:calc(9 * var(--vhu)); display:flex; flex-direction:column; }
html.h .p-work{ width:100vw; }
html.h .p-ready{ width:120vw; }
html.h .p-ledger{ width:auto; min-width:100vw; }
/* the big heads lag the track a little, so the page has depth as it moves */
html.h .panel .p-head{ translate:calc((0.5 - var(--p, 0.5)) * 5vw) 0; }
html.h .p-hero .p-head{ translate:0 0; }
html.h .flyers{ display:block; position:absolute; inset:0; pointer-events:none; z-index:6; }
html.h .slot img{ visibility:hidden; }

/* The seam. Where two panels of different ground meet, the arriving one
   eats the other rather than butting against a hard edge. The script builds
   one strip for the panel that names a kind with data-seam, straddling the
   boundary and sitting under the incoming panel's content. Every kind runs
   off one number: --w, the front, nought at the right of the screen and one
   at the left, written per frame from the seam's own position.
   Both grounds either side carry light text, so the strip can sit behind
   words without costing legibility.

   Work into Ready is goop: a tide of the incoming ground sliding across,
   its leading edge a chain of overlapping rounds that swell and surge on
   counts of their own. The lobes push out and are drawn back while staying
   joined to the ones above and below, so it stretches and necks. Nothing
   detaches, because goop that breaks into rounds is just spots.
   Nonprofits into Contact is blocks: a grid of uneven cells, each flipping
   outright when the front reaches it, scattered across nearly three columns
   so blocks drop ahead of the front and stragglers hold on behind it. No
   blur there, because the hard cell edge is the whole point. */
.seam{ display:none; }
html.h .panel{ isolation:isolate; }
/* The seam hangs off the end of the panel it leaves, not the start of the
   one it enters. A panel in the run is its own stacking context, so a seam
   held by the incoming panel cannot reach behind the outgoing panel at all;
   held by the outgoing panel it can sit above that panel's words, which is
   what the crossing wants: the arriving ground eats the words along with
   the ground they stand on. The incoming panel, a later panel in the run,
   lays its own words over the strip in turn, so it never eats those.
   It paints its base only past the boundary, where it carries the leaving
   ground out over ink that has none. On its own side the panel's ground is
   already that colour, and painting it again would hide whatever stands
   there before the front had ever arrived. */
html.h .seam{ display:block; position:absolute; top:-14px; bottom:-14px; z-index:1; pointer-events:none;
  left:calc(100% - 0.5 * var(--seamw)); width:var(--seamw);
  background:linear-gradient(to right, transparent 0 50%, var(--ca, transparent) 50% 100%); }

/* One material for both seams: a grid of uneven cells that turn over from
   the ground being left to the ground arriving. The two differ only in the
   order they turn in, which the script writes into each cell's --t, so the
   crossing reads as one idea told twice. */
html.h .seam-cells{ --seamw:clamp(320px, 33vw, 660px);
  display:grid; grid-template-columns:var(--colt); grid-template-rows:var(--rowt); }
/* Every cell and every slat is a pixel bigger than its own track, so it
   laps its neighbour. Tracks are fractions of a height the window decides,
   and on a screen that is scaled, as a Windows desktop usually is, those
   fractions land between device pixels; two that have both turned over then
   leave a hairline of the ground behind showing between them. The lap costs
   nothing, since neighbours that have both arrived are the same colour. */
.seam-cells b{ display:block; background:var(--cb, transparent); margin:0 -1px -1px 0;
  opacity:clamp(0, calc((var(--w, 0) - var(--t, 0)) * 150), 1); }

html.h .seam-goop{ --seamw:clamp(340px, 34vw, 700px); }
/* the body of it: the width of the strip, parked off to the right and slid
   across by the front, so one element carries the whole crossing */
.seam-goop u{ position:absolute; top:-30px; bottom:-30px; left:100%; width:100%;
  background:var(--cb, transparent); translate:calc(var(--w, 0) * -100%) 0; will-change:translate; }
/* the rounds on its leading edge: each overlaps its neighbours well past
   their centres, and each swells and surges on its own count, so the union
   of them stretches and necks instead of holding one shape */
.seam-goop u i{ position:absolute; top:var(--y); border-radius:50%; translate:-50% -50%;
  background:var(--cb, transparent);
  left:calc(var(--dx) + sin(var(--w, 0) * var(--sp) + var(--ph)) * var(--am));
  width:calc(var(--r) + sin(var(--w, 0) * var(--sp2) + var(--ph2)) * var(--sw));
  height:calc(var(--r) + sin(var(--w, 0) * var(--sp2) + var(--ph2)) * var(--sw)); }

/* panel reveals: content rises as the panel arrives from the right */
.rv{ opacity:0; translate:0 22px; transition:opacity var(--t-reveal) var(--ease-out), translate var(--t-reveal) var(--ease-out); transition-delay:var(--rvd, 0ms); }
.panel.is-in .rv{ opacity:1; translate:0 0; }
.js-off .rv{ opacity:1; translate:0 0; }
.rv-words .w{ display:inline-block; overflow:hidden; vertical-align:top; padding-bottom:.08em; margin-bottom:-.08em; }
.rv-words .wi{ display:inline-block; translate:0 110%; rotate:.001deg; transition:translate .9s var(--ease-out); transition-delay:calc(var(--wd, 0) * 1ms); }
.rv-words.is-in .wi, .panel.is-in .rv-words .wi{ translate:0 0; }
.js-off .rv-words .wi{ translate:0 0; }

.p-head{ max-width:34vw; }
.p-head .lede{ margin-top:clamp(16px,calc(2.4 * var(--vhu)),26px); }
.p-head .btn{ margin-top:clamp(20px,calc(3 * var(--vhu)),32px); }

/* ---------- 8 · Hero ---------- */
/* ---------- 8a · The rails behind the line ----------
   Six bands of the work, filling the hero, sitting under the headline. The
   drift belongs to the stylesheet so it runs on the compositor and costs the
   script nothing; the scroll's own push is the one number the script writes,
   on the outer band, so the two never fight over the same property. Each
   band holds its pictures twice over and travels exactly half its own
   length, which is why the loop has no seam in it. Paused outright when the
   hero is not on screen, because a surface that moves while nobody is
   looking is just a machine running hot for nothing. */
.rails{ position:absolute; inset:0; overflow:hidden; z-index:0;
  display:grid; grid-template-rows:repeat(6, 1fr); gap:clamp(6px,calc(1 * var(--vhu)),14px); }
.rail{ overflow:hidden; }
.rail-in{ display:flex; gap:clamp(8px,1vw,18px); height:100%; width:max-content;
  transform:translate3d(calc(var(--sx, 0) * 1px), 0, 0); will-change:transform; }
/* At rest the bands are split, three going each way, which is the thing to
   look at while nothing is happening. The moment the page is moving that
   split stops dead and the scroll's push has all six to itself, so they
   travel as one; when it settles, they part again. */
.rail-run{ display:flex; gap:clamp(8px,1vw,18px); height:100%;
  animation:rail-run var(--dur, 60s) linear infinite; animation-direction:var(--way, normal); }
html.scrolling .rail-run{ animation-play-state:paused; }
/* a set width rather than each picture's own, so eight of them always cover
   the widest screen and the half travelled is always a whole set */
.rail img{ height:100%; width:clamp(150px, 15vw, 340px); display:block; flex:none;
  border-radius:calc(var(--r) - 4px); object-fit:cover; object-position:top; opacity:.5; }
@keyframes rail-run{ from{ transform:translate3d(0, 0, 0); } to{ transform:translate3d(-50%, 0, 0); } }
html:not(.hero-near) .rail-run{ animation-play-state:paused; }
/* the frame the whole thing sits in: dark at every edge and dimmed overall,
   so the line on top of it is read and the work underneath is felt */
.rails::after{ content:""; position:absolute; inset:0; pointer-events:none;
  background:
    /* heaviest under the line itself, which stands on the floor of the hero */
    linear-gradient(to top, var(--bg) 4%, rgba(0,0,0,.88) 26%, rgba(0,0,0,0) 62%),
    radial-gradient(112% 82% at 50% 42%, rgba(0,0,0,0) 18%, rgba(0,0,0,.70) 60%, var(--bg) 100%),
    linear-gradient(to right, var(--bg) 0, rgba(0,0,0,0) 17%, rgba(0,0,0,0) 83%, var(--bg) 100%),
    linear-gradient(to bottom, var(--bg) 0, rgba(0,0,0,0) 14%, rgba(0,0,0,0) 86%, var(--bg) 100%); }

.p-hero{ min-height:calc(100 * var(--vhu)); display:flex; flex-direction:column; position:relative; }
.p-hero .hero-line{ position:relative; z-index:2; }
/* the one line sits on the floor of the hero, under the fan, at the top of
   both of the type's axes: Archivo is loaded to 900 and to 125 wide */
.hero-line{ margin-top:auto; font-weight:900; font-stretch:125%; letter-spacing:-.045em; line-height:.86; }

.hero-cta{ display:flex; gap:12px; flex-wrap:wrap; justify-self:end; }

/* ---------- 9 · Work ---------- */
/* The work on the homepage is the same tile the Work page and the shop are
   built from, two across instead of three. The tile itself is written once,
   in section 20 with the shop; only its size and its ground are set here,
   because the panel is a screen in the track and the ground is slate. */
.slot{ display:block; position:relative; border-radius:var(--r); overflow:hidden; border:1px solid var(--frame); background:var(--panel); }
.slot img{ width:100%; height:100%; object-fit:cover; object-position:top; }
/* The grounds walk the palette by position, and the eight in section 20 are
   written for a tile standing on the near black page. This panel is slate,
   so the first of them would start at the colour of the panel itself and
   the tile would open a hole in the ground rather than sit on it. On slate
   the two tiles take their light from below it: the green the Work page
   gives the client, and Sentinel's own blue slate. */
/* three of them, because the Work page stands three across on this ground
   and a two colour walk would hand the first and the third the same one */
/* The same three on the white band. A tile is a dark object either way, so
   the walk does not change when the run under it does; without this the
   three would fall back to the shop's two colour checkerboard and stop
   being the client's own. */
.ground-slate .work-grid .project:nth-child(3n+1) .project-art,
.paper .work-grid.three .project:nth-child(3n+1) .project-art{ background:radial-gradient(ellipse at 40% 50%, var(--evergreen), var(--jet-2) 72%); }
.ground-slate .work-grid .project:nth-child(3n+2) .project-art,
.paper .work-grid.three .project:nth-child(3n+2) .project-art{ background:radial-gradient(ellipse at 30% 35%, var(--blue-slate), var(--jet-2) 72%); }
.ground-slate .work-grid .project:nth-child(3n+3) .project-art,
.paper .work-grid.three .project:nth-child(3n+3) .project-art{ background:radial-gradient(ellipse at 60% 55%, var(--charcoal), var(--jet) 72%); }
html.h .p-work{ display:grid; grid-template-columns:26vw 1fr; grid-template-rows:1fr; gap:clamp(24px,3vw,56px); align-items:safe center; }
html.h .p-work .p-head{ max-width:none; align-self:center; }
/* in the track a tile is sized by whichever of the two runs out first, the
   width of the column it stands in or the height of the screen it is on */
html.h .work-grid{ margin-top:0; grid-template-columns:repeat(2, min(26vw, calc(52 * var(--vhu)))); grid-template-rows:auto;
  gap:clamp(18px,2.2vw,34px); align-items:start; }
/* a short window: both tiles sized by the height rather than the width. Two
   fifths of a short screen is the most the art can take: the tile carries a
   name and a line under it, and the bar and the bottom rail take theirs
   first, so anything taller runs the words off the foot of the screen. */
@media (max-height:800px){
  html.h .work-grid{ grid-template-columns:repeat(2, min(24vw, calc(40 * var(--vhu)))); }
}

/* ---------- 10 · Ready ---------- */
.ready-row{ display:grid; grid-template-columns:repeat(auto-fill, minmax(140px, 1fr)); gap:clamp(14px,1.8vw,26px); margin-top:clamp(24px,calc(5 * var(--vhu)),56px); }
.ready-row li{ display:grid; gap:10px; }
.ready-row .slot{ aspect-ratio:3/4; }
.rname{ font-family:var(--font-m); font-size:11.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--mut); }
html.h .p-ready{ display:grid; grid-template-columns:30vw 1fr; gap:clamp(24px,3vw,56px); align-items:safe center; }
html.h .p-ready .p-head{ max-width:none; }
/* the tiles divide the column they are given rather than each taking a
   fixed slice of the window, so the row cannot run past the panel when a
   layout is added to it */
html.h .ready-row{ margin-top:0; grid-template-columns:repeat(8, minmax(0,1fr)); gap:1.4vw; align-items:end; }

/* ---------- 11 · What is sold: four offers on one scale ----------
   Four cards in a row, cheapest first, each in a colour of its own, and
   the colour goes on the figure, not into the ground. At the foot of every
   card a well of the same height holds a column on a scale shared by all
   four, $0 at the floor and $10,000 at the top line, so the row reads as
   one chart: a sliver for the fixed page, a third of the way up for a
   site, and quoted work running out through the top, because it has no
   ceiling. The prices stand beside their columns on one line across the
   row. The figures above them are set to be read: sentence case at 14 px
   and up, white on the card. The whole card is the link. The columns rise
   off the panel's reveal class, so they cost no script and arrive with
   the rest of the panel. */
.offers{ display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:16px;
  margin-top:clamp(20px,calc(4 * var(--vhu)),44px); }
.offer{ position:relative; isolation:isolate; display:flex; flex-direction:column; gap:clamp(14px,calc(2 * var(--vhu)),22px);
  padding:clamp(18px,calc(2.6 * var(--vhu)),26px) clamp(18px,1.5vw,24px) clamp(14px,calc(2 * var(--vhu)),20px);
  border:1px solid var(--line); border-radius:18px; overflow:hidden;
  background:linear-gradient(180deg, var(--night-2), var(--night));
  transition:translate var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover); }
/* the card's colour as one low wash from the corner its column stands in */
.offer::before{ content:""; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:.55;
  background:radial-gradient(ellipse 95% 50% at 0% 100%, color-mix(in srgb, var(--c) 24%, transparent), transparent 72%);
  transition:opacity var(--t-leave) var(--ease-hover); }
.offer-kind{ display:block; font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--c-ink); }
.offer-name{ margin:10px 0 0; font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); text-transform:uppercase;
  letter-spacing:-.02em; line-height:1.04; font-size:clamp(20px, min(1.7vw, calc(3 * var(--vhu))), 28px); color:var(--text); }

/* the figures, lifted from the project's own case study band */
.offer-facts{ margin:0 0 clamp(18px,calc(3 * var(--vhu)),30px); display:grid; }
.offer-facts > div{ display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:clamp(6px,calc(1 * var(--vhu)),10px) 0; border-top:1px solid var(--line); }
.offer-facts dt{ font-size:14px; line-height:1.35; color:var(--mut); }
.offer-facts dd{ margin:0; font-size:15px; font-weight:600; line-height:1.35; color:var(--text); text-align:right; }

/* the well: quarter lines up to the $10,000 line at its top. The figures
   above keep a margin clear for quoted work to run out into. */
.offer-well{ --lane:34%; position:relative; margin-top:auto; flex:none;
  height:clamp(120px, calc(19 * var(--vhu)), 210px); border-bottom:1px solid var(--line2); }
/* the lines belong to the column's lane and stop at its edge, so the price
   beside it stands on a clear ground */
.offer-well::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:var(--lane); pointer-events:none;
  background:repeating-linear-gradient(to top, transparent 0 calc(25% - 1px), var(--line2) calc(25% - 1px) 25%); }
.offer-cap{ position:absolute; left:calc(var(--lane) + 10px); top:-7px; font-family:var(--font-m); font-size:11px; letter-spacing:.1em; line-height:14px; color:var(--dim); }
.offer-col{ position:absolute; left:0; bottom:0; width:var(--lane); height:var(--h, 0%); border-radius:6px 6px 0 0;
  background:linear-gradient(to top, color-mix(in srgb, var(--c) 35%, transparent), var(--c));
  box-shadow:0 0 30px -6px color-mix(in srgb, var(--c) 70%, transparent);
  transform-origin:50% 100%; transform:scaleY(0);
  transition:transform var(--t-reveal) var(--ease-out) var(--bd, 0ms), box-shadow var(--t-leave) var(--ease-hover); }
/* quoted work goes through the top line and fades out above it */
.offer-col.open{ height:calc(100% + clamp(18px,calc(3 * var(--vhu)),30px)); border-radius:0;
  -webkit-mask-image:linear-gradient(to top, #000 72%, transparent);
  mask-image:linear-gradient(to top, #000 72%, transparent); }
.panel.is-in .offer-col, .js-off .offer-col{ transform:none; }
.offer-price{ position:absolute; left:calc(var(--lane) + 14px); right:0; bottom:12px; margin:0; display:grid; gap:6px; }
.offer-pre{ font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--c-ink); }
.offer-amt{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); letter-spacing:-.02em; line-height:1;
  font-size:clamp(22px, min(1.85vw, calc(3.4 * var(--vhu))), 34px); color:var(--text); white-space:nowrap; }

/* the way in: one line at the foot, and the whole card answers to it */
.offer-go{ display:flex; align-items:center; justify-content:space-between; gap:10px;
  font-size:14px; font-weight:600; color:var(--text); }
.offer-go::after{ content:""; position:absolute; inset:0; z-index:2; border-radius:18px; }
.offer-go .arw{ color:var(--c-ink); transition:translate var(--t-leave) var(--ease-hover); }
.offer-go:focus-visible{ outline:none; }
.offer:has(.offer-go:focus-visible){ outline:2px solid var(--mark-2); outline-offset:3px; }
@media (hover:hover){
  .offer:hover{ translate:0 -4px; border-color:color-mix(in srgb, var(--c) 45%, transparent); transition-duration:var(--t-hover); }
  .offer:hover::before{ opacity:1; transition-duration:var(--t-hover); }
  .offer:hover .offer-col{ box-shadow:0 0 44px -4px color-mix(in srgb, var(--c) 95%, transparent); transition-duration:var(--t-reveal), var(--t-hover); }
  .offer:hover .offer-go .arw{ translate:4px 0; transition-duration:var(--t-hover); }
}
@media (hover:hover){
  .slot{ transition:border-color var(--t-leave) var(--ease-hover); }
  .ready-row li:hover .slot{ border-color:var(--act); transition-duration:var(--t-hover); }
}
.ledger-foot{ margin-top:clamp(18px,calc(3 * var(--vhu)),30px); max-width:42ch; font-size:14px; line-height:1.6; color:var(--dim); }
.ledger-foot a{ color:var(--mut); text-decoration:underline; text-decoration-color:var(--line2); text-underline-offset:3px; }
/* in the track the head stands to the left of the row and the note sits
   under it, so all of the panel's height belongs to the four cards. The
   panel is as wide as the row needs (see the widths at the top of the
   track), so a card never drops below what its price and figures want. */
html.h .p-ledger{ display:grid; grid-template-columns:24vw max-content;
  column-gap:clamp(32px,4vw,72px); grid-template-rows:auto auto; align-content:safe center; }
html.h .p-ledger .p-head{ grid-column:1; grid-row:1; max-width:none; align-self:end; }
html.h .offers{ grid-column:2; grid-row:1 / span 2; margin-top:0; align-self:center;
  grid-template-columns:repeat(4, clamp(250px, 19vw, 340px)); }
/* every name holds two lines in the row, so the figures line up across it */
html.h .offer-name{ min-height:2.08em; }
html.h .p-ledger .ledger-foot{ grid-column:1; grid-row:2; align-self:start; }

/* ---------- 12 · The process ----------
   Four steps on one line. The line fills as the panel crosses the
   screen and its head carries a glow in the colour the line has reached.
   Two satellites circle the line in a double helix as it fills, leaving
   their trails in the same colour run: in front of the line on the near
   half of each turn, behind it on the far half, so the line reads as an
   object with depth. Each node bursts as the fill reaches it, and a
   hairline marks where the work becomes yours. The script writes --fill
   and --hc (the head colour) and, once per layout, the helix paths; the
   stylesheet does everything else. */
.run{ position:relative; margin-top:clamp(36px,calc(6 * var(--vhu)),72px); padding-top:56px; }
.orbit{ position:absolute; left:0; right:0; top:-60px; height:120px; pointer-events:none; }
.orbit svg{ position:absolute; left:0; top:0; width:100%; height:100%; overflow:visible; }
.orbit-back{ z-index:1; }
.orbit-front{ z-index:4; }
.trail{ fill:none; stroke:url(#runGrad); stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:var(--L, 0px); stroke-dashoffset:calc(var(--L, 0px) * (1 - var(--fill, 0))); }
.orbit-back .trail{ stroke-width:1.4; opacity:.42; }
.orbit-front .trail{ stroke-width:2.4; }
.orbit-front .trail{ mask:url(#maskF1); }
.trail.glow{ stroke-width:7; opacity:.34; filter:url(#runGlow); }
.orbit-back .trail.glow{ opacity:.16; }
/* The line rises out of the ground. No track is drawn under it, so it
   exists only as far as it has filled, and it holds the ground's own
   colour for its first stretch, so it starts invisible and takes its
   colour as it runs. The trails and the head read the same stops (the
   script reads them back), so the whole helix comes up out of the ground
   together. */
.run-line{ position:absolute; left:0; right:0; top:57px; height:6px; border-radius:3px; z-index:3; }
.run-line i{ position:absolute; left:0; right:0; top:-1px; height:8px; border-radius:4px;
  background:linear-gradient(90deg, var(--bg), var(--bg) 3%, var(--run-1) 45%, var(--run-2) 56%, var(--run-3) 66%, var(--run-4) 78%, var(--run-5) 100%);
  clip-path:inset(-14px calc((1 - var(--fill, 0)) * 100%) -14px 0); }
#runGrad stop:nth-of-type(1), #runGrad stop:nth-of-type(2){ stop-color:var(--bg); }
#runGrad stop:nth-of-type(3){ stop-color:var(--run-1); }
#runGrad stop:nth-of-type(4){ stop-color:var(--run-2); }
#runGrad stop:nth-of-type(5){ stop-color:var(--run-3); }
#runGrad stop:nth-of-type(6){ stop-color:var(--run-4); }
#runGrad stop:nth-of-type(7){ stop-color:var(--run-5); }
.run-line i::after{ content:""; position:absolute; inset:-5px 0; border-radius:8px; background:inherit; filter:blur(8px); opacity:.5; }
.run-head{ position:absolute; top:60px; left:calc(var(--fill, 0) * 100%); width:12px; height:12px; margin:-6px 0 0 -6px; border-radius:50%; display:block; z-index:3;
  background:var(--hc, var(--teal-2)); box-shadow:0 0 16px 4px color-mix(in srgb, var(--hc, var(--teal-2)) 60%, transparent); }
.sat{ position:absolute; left:0; top:0; width:100%; height:100%; display:block; clip-path:var(--cp, none); }
.sat-b{ z-index:2; }
.sat-f{ z-index:5; }
.sat i{ position:absolute; left:0; top:0; display:block; width:9px; height:9px; border-radius:50%; background:var(--hc, var(--teal-2));
  offset-path:var(--op, none); offset-distance:calc(var(--fill, 0) * 100%); offset-rotate:0deg;
  box-shadow:0 0 12px 3px color-mix(in srgb, var(--hc, var(--teal-2)) 65%, transparent); }
.sat-b i{ width:6px; height:6px; opacity:.55; box-shadow:0 0 8px 1px color-mix(in srgb, var(--hc, var(--teal-2)) 40%, transparent); }
.steps{ display:grid; grid-template-columns:repeat(4, 1fr); gap:clamp(16px,2vw,32px); }
.step{ position:relative; padding-right:clamp(8px,1vw,20px); }
.step .node{ position:absolute; left:0; top:-67px; width:22px; height:22px; border-radius:50%; border:2px solid var(--line2); background:var(--bg);
  transition:border-color .28s var(--ease-out), background .28s var(--ease-out), box-shadow .28s var(--ease-out); }
/* the dot appears in its ring the moment the head reaches it, then floats
   down and settles beside the step's name; the ring stays on the bar. Down
   first, then across, so the path is an arc and not a straight drop. It
   lands as the mark: a disc with the hatch cut out of it, lit from the top
   left and turned on two axes under a close perspective, so at this size it
   reads as a solid thing rather than a flat badge. The shape, the lighting
   and the turn all arrive together at the end of the travel. */
.step .node i{ position:absolute; left:4px; top:4px; width:10px; height:10px; border-radius:50%; background:var(--c);
  transform:perspective(44px) scale(0); scale:1; rotate:none;
  mask-size:contain; mask-repeat:no-repeat; mask-position:center; mask-image:none;
  box-shadow:0 0 10px color-mix(in srgb, var(--c) 70%, transparent);
  transition:transform .3s var(--ease-out), top .7s var(--ease-inout) .15s, left .55s var(--ease-inout) .3s,
    scale .26s var(--ease-out) .85s, mask-image 0s .85s, background 0s .85s, border-radius 0s .85s,
    rotate .38s var(--ease-out) .85s, filter .38s var(--ease-out) .85s, box-shadow .3s var(--ease-out) .85s; }
html.h .step.is-on .node i{ left:-21px; top:74px; scale:1.6; border-radius:0; box-shadow:none;
  background:linear-gradient(145deg, #F4F8F8 0%, var(--c) 46%, color-mix(in srgb, var(--c) 38%, #000) 100%);
  mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cdefs%3E%3Cmask id='h'%3E%3Ccircle cx='32' cy='32' r='30' fill='%23fff'/%3E%3Cg stroke='%23000' stroke-width='7' stroke-linecap='round'%3E%3Cline x1='2.88' y1='35.19' x2='46.76' y2='6.69'/%3E%3Cline x1='7.42' y1='47.95' x2='56.58' y2='16.05'/%3E%3Cline x1='17.23' y1='57.31' x2='61.12' y2='28.81'/%3E%3C/g%3E%3C/mask%3E%3C/defs%3E%3Ccircle cx='32' cy='32' r='30' fill='%23fff' mask='url(%23h)'/%3E%3C/svg%3E");
  rotate:1 -1 0 34deg; filter:drop-shadow(0 1.5px 2px rgba(0,0,0,.55)); }
.step .node::after{ content:""; position:absolute; inset:-2px; border-radius:50%; border:1.5px solid var(--c); opacity:0; transform:scale(.7); }
.step.is-on .node{ border-color:var(--c); box-shadow:0 0 14px color-mix(in srgb, var(--c) 70%, transparent), 0 0 2px var(--c); }
/* on the run the rings are never painted: ahead of the head there is no
   track for them to sit on, so a step shows nothing until the line reaches
   it, then only the burst and the marker it lets go. The ring still holds
   the marker, so only its own paint goes. */
html.h .step .node{ border-color:transparent; background:transparent; box-shadow:none; }
.step.is-on .node i{ transform:perspective(44px) scale(1); }
.step.is-on .node::after{ animation:burst .8s var(--ease-out) forwards; }
@keyframes burst{ from{ opacity:.95; transform:scale(.7); } to{ opacity:0; transform:scale(3.4); } }
.js-off .run{ --fill:1; }
.js-off .step .node i{ transform:perspective(44px) scale(1); }
.step h3{ font-size:clamp(20px,1.6vw,26px); }
.step p{ color:var(--mut); font-size:15px; line-height:1.55; margin-top:8px; max-width:30ch; }
.step-yours h3{ color:var(--mark-2); }
html.h .p-process{ justify-content:safe center; }
html.h .p-process .p-head{ max-width:44vw; }

/* ---------- 13 · Paper ---------- */
.paper .lede{ margin-top:clamp(16px,calc(2.4 * var(--vhu)),26px); }
.paper .hero-cta{ justify-self:start; margin-top:clamp(20px,calc(3.4 * var(--vhu)),36px); }
.kv{ display:grid; gap:clamp(14px,calc(2.2 * var(--vhu)),22px); }
.kv .ki{ display:grid; grid-template-columns:20px 1fr; gap:14px; align-items:start; padding-top:clamp(12px,calc(1.8 * var(--vhu)),18px); border-top:1px solid var(--line); }
.kv .kico{ width:18px; height:18px; margin-top:4px; color:var(--mark); }
.kv b{ color:var(--text); }
.kv span{ color:var(--mut); font-size:15px; line-height:1.55; }

/* The four sizes stand on the band. The argument keeps the left column and
   the ladder runs across the rest, so the panel is read the way it is
   scrolled: the reason first, then the four numbers. The panel is held to
   one screen rather than run wide like the Ready row, because a price
   ladder is a comparison and all four have to be in the eye at once. */
html.h .p-paper{ width:100vw; display:grid; grid-template-columns:23vw 1fr;
  gap:clamp(18px,2vw,36px); align-items:safe center; }
.p-paper .tiers{ margin-top:clamp(24px,calc(5 * var(--vhu)),56px); }
/* the row of buttons owns the space above it; each button carrying the
   panel head's own top margin as well drops the second one a whole line
   when it wraps, on the band and on a phone alike */
.p-paper .hero-cta .btn{ margin-top:0; }
html.h .p-paper .p-head{ max-width:none; }
/* the headline gives up a size here: the column is a quarter of the screen
   and the four cards are the thing being looked at */
html.h .p-paper .p-head .d2{ font-size:clamp(26px,2.5vw,42px); }
html.h .p-paper .tiers{ margin-top:0; grid-template-columns:repeat(4, minmax(0,1fr)); gap:.9vw; align-items:stretch; }
/* the band's own cards: a size down from the pricing page, because here
   they are one panel of a page rather than the whole subject of one */
html.h .p-paper .tier{ padding:clamp(16px,1.3vw,24px); gap:11px; }
html.h .p-paper .tier h3{ font-size:clamp(17px,1.35vw,22px); }
/* the four blurbs keep one height at this width, so the prices sit on one
   line across the ladder and the eye can run along them */
html.h .p-paper .tier .blurb{ font-size:13.5px; min-height:3lh; }
html.h .p-paper .tier .amt{ font-size:clamp(24px,2vw,34px); }
html.h .p-paper .tier .alt,
html.h .p-paper .tier .np{ font-size:13px; }
html.h .p-paper .feat li{ padding:6px 0 6px 24px; font-size:13px; }
html.h .p-paper .feat li::before{ top:9px; }

/* ---------- 14 · Contact and footer ---------- */
.p-contact{ display:flex; flex-direction:column; justify-content:space-between; gap:clamp(24px,calc(4.5 * var(--vhu)),72px); }
/* The long telling of the entrance. Same geometry and the same idea as the
   arrival: the mark ends as the O in the word, which is why the word here
   is missing one. Given room it draws itself first, travels into that place
   and lets the letters come up after, so the panel that closes the page
   says the name the long way. Once, when the panel arrives. */
.c33long{ color:var(--text); width:100%; }
.c33long svg{ display:block; margin-inline:auto; height:auto; overflow:visible; width:min(100%, calc(132 * var(--vhu))); }
/* On the run the line and the address stand together in the middle of the
   panel. The svg keeps the panel's width and lets its height follow, capped
   against the window's height so a short window still holds both. The room
   the viewBox keeps above the glyphs is the mark's landing arc and cannot be
   cropped, so the line is drawn down into part of it rather than left
   floating above. */
html.h .p-contact{ padding-top:calc(var(--head) + calc(2 * var(--vhu))); gap:clamp(12px, calc(2 * var(--vhu)), 28px); }
html.h .contact-top{ flex:1; min-height:0; display:grid; grid-template-rows:auto auto; align-content:center; justify-items:center; row-gap:0; }
html.h .c33long svg{ width:min(100%, calc(190 * var(--vhu))); height:auto; }
html.h .lets-build{ margin-bottom:calc(-1 * clamp(16px, calc(3.5 * var(--vhu)), 36px)); }
.cl-mk{ transform:translate(436.2px, 302px) scale(.82); }
.cl-ring{ stroke-dasharray:185; }
.cl-h{ stroke-dasharray:60; }
/* The letters follow the panel's own colour, which is the type colour at
   rest and the red under a pointer. Nothing runs along them. */
.cl-w{ fill:currentColor; font-family:var(--font-m); font-size:76px; font-weight:600; text-anchor:middle; }
/* Where this rests is the address, not the name. The word closed up long
   ago as far as the markup is concerned, so a phone, reduced motion or a
   page whose script never ran shows the thing worth having, and the run is
   only the way it gets there. The close is one scale about the middle of
   the word, written as a translate and a scale because the rest of this
   block works in the same user space with its origin at nought: for a
   centre c and a scale s, translating by c * (1 - s) holds c still.
   Here c is 500,302, the middle of the word, and s is .33. Each letter
   carries the step it takes to its own place in the address, and the mark
   takes one more so it lands on the o of chord33, which it has been
   standing in for since the entrance. */
.cl-all{ transform:translate(335px, 202.34px) scale(.33); }
/* The mark takes one step more than the letters: onto the o of chord33, and
   down to the height a lowercase o stands at, because the capitals give way
   to the case an address is written in as the name closes. Same composition
   again: 436.2,302 at .82 becomes 522.8,310.4 at .739 of that. */
.cl-mk-to{ transform:translate(200.4px, 87.2px) scale(.739); opacity:0; }
.cl-t, .cl-lc{ transform:translate(var(--dx, 0px), 0); }
/* what is left standing once the name has closed: the small case, an
   ordinary o where the mark stood, and no hatches or ring at all */
.cl-cap, .cl-hs{ opacity:0; }
.cl-lc, .cl-o{ opacity:1; }
/* The address answers a pointer, but only once it is actually an address:
   --live is nought for the whole of the telling and one when the run has
   landed, so nothing highlights while the name is still mid sentence and
   the rule cannot be dragged across the screen at full size. The blue is
   the palette's own blue slate brought up until it reads on the ink, not a
   new colour: the slate palette carries no vivid blue by choice. */
/* the colour the address answers a pointer with. --live holds it back
   until the name has landed, so the entrance is never red. */
.c33long{ --mail:var(--act-solid); --live:1; }
html.h:not(.still):not(.ended) .c33long{ --live:0; pointer-events:none; }
html.h:not(.still).ended .c33long{ animation:cl-live .01s linear 4.75s both; }
@keyframes cl-live{ from{ --live:0; pointer-events:none; } to{ --live:1; pointer-events:auto; } }
/* The rule under it is drawn, not underlined, because the address is set as
   shapes; it carries the process line's own colour run and the same soft
   copy beneath, and it draws in from the left the way that line fills. */
#clGrad stop:nth-of-type(1){ stop-color:var(--run-1); }
#clGrad stop:nth-of-type(2){ stop-color:var(--run-2); }
#clGrad stop:nth-of-type(3){ stop-color:var(--run-3); }
#clGrad stop:nth-of-type(4){ stop-color:var(--run-4); }
#clGrad stop:nth-of-type(5){ stop-color:var(--run-5); }
.cl-ul-l{ fill:none; stroke:url(#clGrad); stroke-width:5; stroke-linecap:round;
  stroke-dasharray:729.6; stroke-dashoffset:729.6;
  transition:stroke-dashoffset var(--t-leave) var(--ease-hover); }
.cl-ul-glow{ stroke-width:14; opacity:.5; filter:blur(7px); }
.c33long:focus-visible{ color:color-mix(in oklab, var(--mail) calc(var(--live) * 100%), var(--text)); }
.c33long:focus-visible .cl-ul-l{ stroke-dashoffset:calc((1 - var(--live)) * 729.6); }
@media (hover:hover){
  .c33long{ transition:color var(--t-leave) var(--ease-hover); }
  .c33long:hover{ color:color-mix(in oklab, var(--mail) calc(var(--live) * 100%), var(--text));
    transition-duration:var(--t-hover); }
  .c33long:hover .cl-ul-l{ stroke-dashoffset:calc((1 - var(--live)) * 729.6); transition-duration:var(--t-hover); }
}
/* held at the start until the track has nothing left to give */
html.h:not(.still):not(.ended) .cl-all{ transform:translate(0, 0) scale(1); }
html.h:not(.still):not(.ended) .cl-mk-to{ transform:translate(0, 0) scale(1); opacity:1; }
html.h:not(.still):not(.ended) .cl-t{ transform:translate(0, 0); clip-path:inset(-20% -20% 110% -20%); }
html.h:not(.still):not(.ended) .cl-lc{ transform:translate(0, 0); opacity:0; }
html.h:not(.still):not(.ended) .cl-cap,
html.h:not(.still):not(.ended) .cl-hs{ opacity:1; }
html.h:not(.still):not(.ended) .cl-o,
html.h:not(.still):not(.ended) .cl-pre,
html.h:not(.still):not(.ended) .cl-post{ opacity:0; }
html.h:not(.still):not(.ended) .cl-mk{ transform:translate(500px, 268px) scale(1.2); }
html.h:not(.still):not(.ended) .cl-ring{ stroke-dashoffset:185; }
html.h:not(.still):not(.ended) .cl-h{ stroke-dashoffset:60; }
html.h:not(.still).ended .cl-ring{ animation:cl-draw 1s var(--ease-out) both; }
html.h:not(.still).ended .cl-h1{ animation:cl-draw-h .5s var(--ease-out) .55s both; }
html.h:not(.still).ended .cl-h2{ animation:cl-draw-h .5s var(--ease-out) .75s both; }
html.h:not(.still).ended .cl-h3{ animation:cl-draw-h .5s var(--ease-out) .95s both; }
html.h:not(.still).ended .cl-mk{ animation:cl-land .8s cubic-bezier(.76,0,.24,1) 1.7s both; }
html.h:not(.still).ended .cl-t{ animation:cl-rise .45s cubic-bezier(.19,1,.22,1) calc(2.2s + var(--i) * .13s) both,
  cl-close .9s cubic-bezier(.76,0,.24,1) 3.8s both; }
/* The last letter is up at 3.30s. Half a second on it, the word closes: it
   shrinks about its own middle while every letter walks to its place, and
   the rest of the address arrives around it as it settles. */
html.h:not(.still).ended .cl-all{ animation:cl-close-all .9s cubic-bezier(.76,0,.24,1) 3.8s both; }
/* the hatches go first, then the ring hands the place back to an ordinary
   letter, and the capitals give way to the small case on the way down */
html.h:not(.still).ended .cl-hs{ animation:cl-out .35s linear 3.95s both; }
html.h:not(.still).ended .cl-mk-to{ animation:cl-close-mk .9s cubic-bezier(.76,0,.24,1) 3.8s both,
  cl-out .3s linear 4.34s both; }
html.h:not(.still).ended .cl-o{ animation:cl-in .3s linear 4.34s both; }
html.h:not(.still).ended .cl-lc{ animation:cl-close .9s cubic-bezier(.76,0,.24,1) 3.8s both,
  cl-in .4s linear 4.05s both; }
/* the capitals carry the whole of their own run as well, because naming the
   animation again here would replace the list rather than add to it */
html.h:not(.still).ended .cl-cap{ animation:cl-rise .45s cubic-bezier(.19,1,.22,1) calc(2.2s + var(--i) * .13s) both,
  cl-close .9s cubic-bezier(.76,0,.24,1) 3.8s both,
  cl-out .4s linear 4.05s both; }
html.h:not(.still).ended .cl-pre,
html.h:not(.still).ended .cl-post{ animation:cl-in .45s var(--ease-out) 4.25s both; }
/* the line above the address waits out the whole telling and comes up once
   the name has closed into the address; on a phone it simply stands there */
.lets-build{ margin:0; text-align:center; font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); text-transform:uppercase;
  letter-spacing:-.03em; line-height:1; font-size:clamp(34px, min(4.6vw, calc(8 * var(--vhu))), 84px); color:var(--text); }
/* the first word is the type colour and the second is the red that can be
   read, so the line carries the red without the word disappearing into it */
.lets-build .em{ color:var(--em); }
html:not(.h) .lets-build{ margin-bottom:clamp(10px,calc(2 * var(--vhu)),20px); }
html.h:not(.still) .lets-build{ opacity:0; }
html.h:not(.still).ended .lets-build{ animation:cl-up .7s var(--ease-out) 4.9s both; }
@keyframes cl-up{ from{ opacity:0; translate:0 12px; } to{ opacity:1; translate:0 0; } }
@keyframes cl-draw{ from{ stroke-dashoffset:185; } to{ stroke-dashoffset:0; } }
@keyframes cl-draw-h{ from{ stroke-dashoffset:60; } to{ stroke-dashoffset:0; } }
@keyframes cl-land{ from{ transform:translate(500px,268px) scale(1.2); } to{ transform:translate(436.2px,302px) scale(.82); } }
@keyframes cl-rise{ from{ clip-path:inset(-20% -20% 110% -20%); } to{ clip-path:inset(-20% -20% -20% -20%); } }
@keyframes cl-close-all{ from{ transform:translate(0, 0) scale(1); } to{ transform:translate(335px, 202.34px) scale(.33); } }
@keyframes cl-close-mk{ from{ transform:translate(0, 0) scale(1); } to{ transform:translate(200.4px, 87.2px) scale(.739); } }
@keyframes cl-close{ from{ transform:translate(0, 0); } to{ transform:translate(var(--dx, 0px), 0); } }
@keyframes cl-in{ from{ opacity:0; } to{ opacity:1; } }
@keyframes cl-out{ from{ opacity:1; } to{ opacity:0; } }
.mailto{ display:inline-block; margin-top:clamp(18px,calc(3 * var(--vhu)),40px); font-family:var(--font-d); font-weight:800; font-stretch:var(--wd);
  font-size:clamp(26px,4.2vw,72px); letter-spacing:-.04em; text-transform:lowercase; line-height:1; color:var(--text); position:relative; }
.mailto::after{ content:""; position:absolute; left:0; bottom:-6px; height:2px; width:100%; background:var(--act); transform:scaleX(0); transform-origin:right;
  transition:transform .4s var(--ease-out); }
@media (hover:hover){ .mailto:hover{ color:var(--act); } .mailto:hover::after{ transform:scaleX(1); transform-origin:left; } }
.site-foot{ position:relative; isolation:isolate; border-top:1px solid rgba(255,255,255,.08); padding-top:56px; }
/* on the homepage the footer stands after the track in the flow, so it
   carries its own gutters and the ground behind it */
body > .site-foot{ padding:56px var(--pad) 32px; background:var(--bg); }
/* while the address tells its name the footer gives up its room, so the page
   cannot be carried past the panel by a wheel still turning; the script
   holds the class for the length of the telling and then lets go */
html.lock body > .site-foot{ display:none; }
/* the footer. A thin rule across the top with a bloom of the kit's teal
   breaking over it, then three columns: the lockup with the studio's line
   under it, the pages, and the way to get in touch. A bar at the foot with
   the year on one side and the two other doors on the other, and a small
   pill resting in the corner. Every measure is the piece it was drawn
   from; only the colour of the bloom moved onto ours. */
/* the bloom sits on the rule and breathes downward from it */
.foot-glow{ position:absolute; left:50%; top:0; translate:-50% 0; width:90vw; max-width:1152px; height:224px; z-index:-1; pointer-events:none;
  background:radial-gradient(ellipse at top, var(--glow, rgba(134,176,174,.35)) 0%, transparent 65%); }
/* The glow takes the ground of whatever the footer is standing under, so the
   last run of the page bleeds down over the line instead of every page
   glowing the same teal. Each one is that ground's own raised plane, which
   is the colour it already uses for anything lifted off itself. A page that
   ends on black keeps the teal, because black bleeding into black is
   nothing. Read off the page rather than written into it: the footer sits
   next to main, and main is asked what its last section is standing on. */
main:has(> section:last-of-type.ground-slate) + .site-foot{ --glow:rgba(42,94,91,.85); }
main:has(> section:last-of-type.ground-green) + .site-foot{ --glow:rgba(34,74,61,.9); }
main:has(> section:last-of-type.paper) + .site-foot{ --glow:rgba(66,114,127,.8); }
/* the content holds to 1280px and sits centred, the way the piece does, so
   the four columns keep their measure on any monitor */
.foot-grid{ display:grid; grid-template-columns:1.35fr 1fr 1fr 1.25fr; gap:40px; align-items:start; max-width:1280px; margin:0 auto; }
/* the lockup a step up from the header's, on the brand ratios: wordmark
   0.5625 of the mark, gap a third of it */
.site-foot .mark{ gap:12px; }
.site-foot .mark svg{ width:36px; height:36px; }
.site-foot .mark .wordmark{ font-size:20.25px; }
.foot-note{ margin-top:18px; max-width:30ch; color:var(--mut); font-size:14px; line-height:1.6; }
.foot-grid h4{ font-family:var(--font-d); font-weight:600; font-size:clamp(18px,1.3vw,20px); letter-spacing:-.02em; color:var(--text); }
.foot-links{ display:grid; gap:10px; margin:16px 0 0; padding:0; list-style:none; }
.foot-links a{ color:var(--mut); font-size:14px; transition:color var(--t-leave) var(--ease-hover); }
.foot-mail{ display:block; margin-top:16px; color:var(--text); font-size:16px; letter-spacing:-.01em; transition:color var(--t-leave) var(--ease-hover); }
.foot-cta{ margin-top:16px; }
.foot-small{ margin-top:10px; color:var(--dim); font-size:12px; }
.foot-bar{ display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap; max-width:1280px; margin:40px auto 0; padding:24px 88px 0 0;
  border-top:1px solid rgba(255,255,255,.1); color:var(--dim); font-size:14px; }
.foot-legal{ display:flex; align-items:center; gap:24px; }
.foot-legal a{ color:var(--dim); transition:color var(--t-leave) var(--ease-hover); }
.foot-legal i{ display:inline-block; width:1px; height:16px; background:rgba(255,255,255,.1); }
/* the pill rests at the capped block's corner, or the gutter's when the
   screen is narrower than the cap */
.foot-pill{ position:absolute; right:max(var(--pad), calc(50% - 640px)); bottom:24px; width:64px; height:16px; border-radius:999px;
  border:1px solid rgba(255,255,255,.1); background:rgba(255,255,255,.05); }
@media (hover:hover){
  .foot-links a:hover, .foot-legal a:hover, .foot-mail:hover{ color:var(--act); transition-duration:var(--t-hover); }
}
/* a short window: the process and contact panels close up */
@media (max-height:700px){
  html.h .p-process .run{ margin-top:30px; }
  html.h .step p{ font-size:14px; }
  html.h .mailto{ margin-top:14px; font-size:clamp(26px, min(4.2vw, calc(7 * var(--vhu))), 72px); }
}

/* ---------- 15 · The dealt cards ----------
   Each flyer is a picture that starts in the fan at the right of the
   hero and lands exactly on its slot in the work or Ready panel. The
   script writes the start offset once and the progress per frame; the
   transform is one expression, so only the compositor works. */
.flyer{ position:absolute; border-radius:var(--r); overflow:hidden; border:1px solid var(--frame); background:var(--panel);
  transform:translate3d(0, calc(var(--near, 0) * var(--rise, 0px) * -1), 0)
            translate3d(calc(var(--fx, 0px) * (1 - var(--pc, 1))), calc(var(--fy, 0px) * (1 - var(--pc, 1))), 0)
            rotate(calc(var(--fr, 0deg) * (1 - var(--pc, 1))))
            scale(calc(1 + (var(--fs, 1) - 1) * (1 - var(--pc, 1))))
            scale(calc(1 + var(--near, 0) * .04));
  box-shadow:0 18px 50px rgba(0,0,0,.35); }
.flyer img{ width:100%; height:100%; object-fit:cover; object-position:top; }

/* The crest. The seven Ready cards rest on one line. The script writes each
   card's nearness to the middle of the screen, nought at the ends of the
   reach and one directly under the middle, and the card rises out of the
   line and clears as it passes, so the scroll carries a wave along the row.
   Rise, scale and veil all read that one number, and it is only written
   while the row is crossing, so the cost is a few properties a frame on top
   of the deal's own and nothing at all once the row has gone by. */
.flyer.is-wave{ --rise:clamp(26px, calc(4.2 * var(--vhu)), 52px); }
.flyer.is-wave::after{ content:""; position:absolute; inset:0; background:var(--well);
  opacity:calc((1 - var(--near, 0)) * .34); pointer-events:none; }
html.h .ready-row .rname{ opacity:calc(.45 + var(--near, 0) * .55); }

/* Nothing stands behind a raised card. In the run the slot is still the link
   and still the measure the card is laid on, but it paints nothing, so a card
   that rises shows the ground rather than the box it came out of. The border
   is made clear rather than dropped, so the measure does not move by its
   two pixels and the cards stay exactly where they land. */
html.h .ready-row .slot{ border-color:transparent; background:transparent; }

/* ---------- 17 · Page wipe ----------
   An ink block with the mark centred sweeps across between pages. The
   edge runs at exactly 33 degrees, rising left to right. */
#c33w{ position:fixed; inset:0; z-index:9998; overflow:hidden; pointer-events:none; display:none; }
#c33w.cover{ display:block; }
#c33w .shape{ position:absolute; top:-calc(2 * var(--vhu)); height:calc(104 * var(--vhu)); left:calc(-60vw - calc(84 * var(--vhu))); width:calc(220vw + calc(168 * var(--vhu))); background:var(--ink);
  transform:translateX(var(--wx,-110%)) skewX(-57deg); }
#c33w.cover .shape{ will-change:transform; }
#c33w.cover.in .shape{ animation:c33wIn .6s var(--ease-inout) forwards; }
#c33w.cover.covered .shape{ --wx:0%; }
#c33w.cover.out .shape{ animation:c33wOut .6s var(--ease-inout) forwards; }
@keyframes c33wIn{ from{ transform:translateX(-110%) skewX(-57deg); } to{ transform:translateX(0%) skewX(-57deg); } }
@keyframes c33wOut{ from{ transform:translateX(0%) skewX(-57deg); } to{ transform:translateX(110%) skewX(-57deg); } }
#c33w .wmark{ position:absolute; left:50%; top:50%; width:76px; height:76px; transform:translate(-50%,-50%); color:var(--text); opacity:0; transition:opacity .18s linear .2s; }

/* Screenshot mode: everything lands instantly. */
.still *, .still *::before, .still *::after{ transition-duration:0ms !important; transition-delay:0ms !important; animation-duration:0ms !important; animation-delay:0ms !important; }

/* ---------- 18 · Motion gate ---------- */
@media (prefers-reduced-motion: reduce){
  .rv, .rv-words .wi{ opacity:1 !important; translate:0 0 !important; transition:none !important; }
  .rail-run{ animation:none !important; }
  /* the columns stand at their value instead of rising to it, and a card
     answers the pointer in colour only */
  .offer-col{ transition:none; transform:none; }
  .offer, .offer:hover, .offer:hover .offer-go .arw{ translate:none; }
  .step .node, .step .node i{ transition:none; }
  .step .node::after, .step.is-on .node::after{ animation:none; }
  #c33w{ display:none !important; }
}

/* ---------- 19 · The column, below 900 and where the track stands down ---------- */
@media (max-width:900px){
  .p-head{ max-width:none; }
  /* The hero keeps its screen in the column, and the line keeps the floor.
     It stood to its own height here once, on the reading that the hero was
     the line and nothing else; the fan stayed behind it, so it was not. The
     veil is built to be heaviest at the floor and clear through the middle,
     which only works while the line is on the floor with it. Standing the
     line at the top put it in the one part of the fan the veil keeps clear,
     with another site's words showing between its own two lines. So the
     base rule is left to hold at every width. */
  .hero-cta{ justify-self:start; }
  .ready-row{ grid-template-columns:repeat(2, 1fr); }
  /* two cards across in the column, until a card would be too narrow to
     hold a label and its figure on one line */
  .offers{ grid-template-columns:repeat(2, minmax(0,1fr)); }
  /* headings stand still in the column: a drift of 28 pixels is a fraction
     of a wide screen and most of a phone's gutter. Written with the html
     ancestor because the drift rule itself comes later in this file. */
  html .drift{ translate:none; }
  .steps{ grid-template-columns:1fr 1fr; gap:26px 18px; }
  .orbit{ display:none; }
  .run{ padding-top:0; }
  .step .node{ position:relative; top:auto; margin-bottom:10px; }
}
@media (max-width:640px){
  .hero-line{ font-size:clamp(30px, 8.4vw, 44px); }
  .steps{ grid-template-columns:1fr; }
  .ready-row{ grid-template-columns:repeat(2, 1fr); }
  /* one card per line on a phone: two would put a label and its figure in
     about eighty pixels each */
  .offers{ grid-template-columns:1fr; }
}
/* a narrow bar: the mark alone, the panel across the bar's full width */
@media (max-width:640px){
  .wordmark{ display:none; }
  .head-row{ padding:8px 8px 8px 16px; }
  .nav{ left:0; right:0; min-width:0; }
  .nav-cta{ padding:0 12px; font-size:11px; }
}

/* ---------- 20 · The inner pages ----------
   Vertical pages in the same tokens. The title as big as the page
   allows, ruled lists, raised boxes, a stat band, the tiers on paper,
   the ledger of work, the form. The rail across the bottom rides these
   pages too and names the section under the middle of the screen; it
   darkens when the section under it is paper. `html.page` is set in
   the markup, so the layout is right before any script runs. */
.wrap{ padding-left:var(--pad); padding-right:var(--pad); }
.sec{ padding-top:var(--sec); padding-bottom:var(--sec); }
.sec-tight{ padding-top:calc(var(--sec) * .55); padding-bottom:calc(var(--sec) * .55); }
section.paper{ padding-top:clamp(64px,calc(9 * var(--vhu)),128px); padding-bottom:clamp(64px,calc(9 * var(--vhu)),128px); }
.page-hero{ padding-top:calc(var(--head) + clamp(56px,calc(10 * var(--vhu)),120px)); padding-bottom:clamp(40px,calc(7 * var(--vhu)),80px); }
.page-hero h1{ max-width:16ch; }
.page-hero .lede{ margin-top:clamp(18px,calc(3 * var(--vhu)),30px); }
/* The inner pages as a stack of panels. Every section below the title is
   one panel on one of the homepage's grounds, ink by default, dark slate for
   the work, evergreen for the process, blue slate for the money, so a page
   changes material as it is read the way the homepage does as it moves. The
   ground sits on the section itself, so a panel's words, buttons, marks and
   boxes follow through the ground's tokens and need no rule each. Every
   panel keeps one shape: the name at the left, the lede at the right, one
   rule under both, then the panel's own content. A photograph that opens a
   chapter stands at the top of its panel, on the panel's ground. */
html.page .pv{ padding-top:clamp(56px,calc(9 * var(--vhu)),120px); padding-bottom:clamp(56px,calc(9 * var(--vhu)),120px); }
/* a hero that holds the cards is the whole first screen: black to its
   bottom edge, the title block at the top, the cards at the foot, and the
   next ground only on scroll. On a short window the cards keep their gap. */
.page-hero:has(> .band.float){ min-height:calc(100 * var(--vhu)); display:flex; flex-direction:column; }
.page-hero > .band.float{ margin-top:auto; padding-top:clamp(48px,calc(8 * var(--vhu)),110px); }
/* Panels are grouped into runs of one ground, so a page changes material a
   few times in big blocks rather than at every panel. Two panels inside one
   run are parts of the same section, so the boundary between them takes one
   panel's worth of room and not both; only where the ground actually
   changes does the full gap open. Written once per ground, and once for
   black, which is the ground a panel carries by naming none. */
html.page .pv.ground-slate + .pv.ground-slate,
html.page .pv.ground-green + .pv.ground-green,
html.page .pv.paper + .pv.paper,
html.page .pv:not(.paper):not(.ground-slate):not(.ground-green) + .pv:not(.paper):not(.ground-slate):not(.ground-green){ padding-top:0; }
html.page .pv .p-head{ max-width:none; display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr); gap:clamp(18px,3vw,64px); align-items:end;
  padding-bottom:clamp(18px,calc(3 * var(--vhu)),30px); border-bottom:1px solid var(--line); margin-bottom:clamp(28px,calc(5 * var(--vhu)),60px); }
html.page .pv .p-head .lede{ margin-top:0; max-width:60ch; }
html.page .pv .p-lede .lede + .lede{ margin-top:12px; }
html.page .pv .p-head .btn{ margin-top:clamp(18px,calc(2.6 * var(--vhu)),28px); }
/* a head that stands in the middle: the heading, then its words under it */
html.page .pv .p-head.mid{ grid-template-columns:1fr; justify-items:center; align-items:start; text-align:center; row-gap:0; }
/* one source of space under the heading, rather than the row gap the two
   column head uses sideways and the paragraph's own margin on top of it */
html.page .pv .p-head.mid .lede{ margin-top:clamp(18px,calc(2.6 * var(--vhu)),30px); max-width:62ch; }
/* a centred head in a black box lit red from its top corner, the same
   material as the chosen card, so a section opens the way a card closes.
   Its own tokens, because it stands on the white band as well as on red. */
html.page .pv .p-head.mid.hbox{
  --text:#FFFFFF; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.5);
  --em:rgba(255,255,255,.78); --line:rgba(255,255,255,.12);
  color:var(--text); border:1px solid rgba(112,12,12,.85); border-radius:20px;
  padding:clamp(34px,calc(5 * var(--vhu)),60px) clamp(24px,4vw,56px);
  background:
    radial-gradient(82% 64% at 100% 0%, rgba(112,12,12,.6), transparent 64%),
    linear-gradient(to bottom, rgba(112,12,12,.18), transparent 50%),
    var(--ink-black); }
html.page .pv > .photo{ margin-bottom:clamp(32px,calc(5 * var(--vhu)),64px); }
html.page .pv > .photo:last-child{ margin-bottom:0; margin-top:clamp(32px,calc(5 * var(--vhu)),64px); }
html.page .pv .rd-buy{ margin-top:clamp(20px,calc(3 * var(--vhu)),32px); }
/* The seam on a vertical page. Where a coloured panel meets the ink of the
   page, the boundary is not a ruled edge: a band of blocks at each end
   turns over as that boundary crosses the screen, so the panel opens out of
   the ink and closes back into it. The same material as the crossings on
   the homepage, hard edged, nothing blurred, and driven the same way, off
   one number per band: --w, nought while the boundary is still low on the
   screen and one by the time it has reached the top, written per frame by
   the script from the boundary's own position.

   Both bands carry the same order, and only the direction differs: the ink
   holds longest against the boundary and goes first deepest into the panel,
   so the top band clears from the inside out and the bottom band fills from
   the boundary back. Tracks are uneven, so the blocks come out different
   sizes rather than a tidy grid, and every block laps its neighbour by a
   pixel so two that have both turned leave no hairline between them on a
   scaled desktop. The band sits under the panel's words, and the panel
   isolates so it can. Nothing is built at all under reduced motion. */
.pxf{ position:relative; isolation:isolate; }
/* clipped at its own edge: every block laps its neighbour by a pixel, and
   the last column's lap would otherwise hang a pixel off the page */
.pxseam{ position:absolute; left:0; right:0; height:var(--pxh, clamp(150px, calc(20 * var(--vhu)), 260px)); z-index:-1; pointer-events:none; overflow:hidden;
  display:grid; grid-template-columns:var(--colt); grid-template-rows:var(--rowt); }
.pxseam.is-top{ top:0; }
.pxseam.is-bot{ bottom:0; }
.pxseam b{ display:block; background:var(--pxc, var(--ink-black)); margin:0 -1px -1px 0; }
.pxseam.is-top b{ opacity:clamp(0, calc((var(--t, 0) - var(--w, 0)) * 150), 1); }
.pxseam.is-bot b{ opacity:clamp(0, calc((var(--w, 0) - var(--t, 0)) * 150), 1); }
@media (max-width:900px){
  html.page .pv .p-head{ grid-template-columns:1fr; align-items:start; }
  html.page .pv .p-head .lede{ margin-top:14px; }
}
.split{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(28px,5vw,84px); align-items:start; }
.box{ background:var(--panel); border:1px solid var(--line); border-radius:var(--r); padding:clamp(26px,4vw,56px); }
.lede a{ color:var(--act); text-decoration:underline; text-decoration-color:var(--line2); text-underline-offset:3px;
  transition:color var(--t-leave) var(--ease-hover), text-decoration-color var(--t-leave) var(--ease-hover); }
.rv.is-in{ opacity:1; translate:0 0; }
.drift{ translate:calc(var(--dx, 0) * 1px) 0; }
html.page .site-foot{ padding:56px var(--pad) 32px; }

/* ruled lists */
html.page .kv{ gap:0; }
html.page .kv li{ padding:14px 0; border-top:1px solid var(--line); color:var(--mut); font-size:15px; line-height:1.55; }
html.page .kv li:last-child{ border-bottom:1px solid var(--line); }
html.page .kv .ki{ display:grid; grid-template-columns:20px 1fr; gap:14px; align-items:start; }
html.page .kv b{ color:var(--text); font-weight:600; }
/* A list in a card: the title inside, a rule under it, one row a line, and
   the card's own edge closing the last row, so a run of facts reads as a
   section and not as lines on the ground. Two cards in a split stand the
   same height. On a red run the card is black, the way the price cards
   are, so the two sides of the split weigh the same. */
.lc{ background:var(--panel); border:1px solid var(--line); border-radius:20px; padding:clamp(22px,2.4vw,34px); }
html.page .lc .kv li:last-child, html.page .lc.kv li:last-child{ border-bottom:0; padding-bottom:0; }
html.page .lc.kv li:first-child{ border-top:0; padding-top:0; }
.ground-slate .lc, .ground-green .lc{ background:var(--ink-black); border-color:rgba(255,255,255,.12); }
.split.cards{ align-items:stretch; }
/* a split that stands as one column at every width: the heading, then the
   card under it, so nothing is left standing beside an empty half */
.split.one{ grid-template-columns:1fr; gap:clamp(20px,calc(3 * var(--vhu)),34px); }

/* ---------- the rest of the facts, given shape ----------
   Four ways to hold a list so a page of facts is not lines on a ground,
   and none of them the same card twice. A ladder, for things that come in
   an order: a spine down the left and a light at each rung, the light in
   the ground's action colour so it is white on black and on red and red
   on the white band. A swap, for a give and a get: two cards and the arrow
   between them. A lit card, for the lines that hold: the chosen card's red
   corner on a card of rows, the red being the named red so it is red on
   every ground. And, on the studio page, four positions as black and white
   cards alternating the way the shop's tiles do. Black cards stand on the
   white band the way the price cards already do there. */
html.page .kv.ladder{ position:relative; padding-left:34px; }
html.page .kv.ladder::before{ content:""; position:absolute; left:8px; top:14px; bottom:14px; width:1px; background:var(--line2); }
html.page .kv.ladder li{ position:relative; border-top:0; padding:11px 0; }
html.page .kv.ladder li:last-child{ border-bottom:0; }
html.page .kv.ladder li::before{ content:""; position:absolute; left:-30px; top:19px; width:9px; height:9px; border-radius:50%;
  background:var(--act); box-shadow:0 0 0 4px var(--bg); }

.swap .split{ grid-template-columns:1fr auto 1fr; gap:clamp(14px,1.6vw,24px); align-items:stretch; }
.swap-arrow{ align-self:center; display:grid; place-items:center; width:46px; height:46px; border-radius:50%;
  background:var(--dark-slate); color:#FFFFFF; border:1px solid rgba(255,255,255,.28); font-size:22px; line-height:1; }
@media (max-width:900px){
  .swap .split{ grid-template-columns:1fr; }
  .swap-arrow{ justify-self:center; rotate:90deg; }
}

.lc.lit{
  background:
    radial-gradient(82% 64% at 100% 0%, color-mix(in srgb, var(--dark-slate) 60%, transparent), transparent 64%),
    linear-gradient(to bottom, color-mix(in srgb, var(--dark-slate) 18%, transparent), transparent 50%),
    var(--ink-black);
  border-color:color-mix(in srgb, var(--dark-slate) 80%, transparent);
  --text:#FFFFFF; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.5); --line:rgba(255,255,255,.12); --mark:rgba(255,255,255,.6); color:var(--text); }

.paper .lc{ background:var(--ink-black); border-color:rgba(255,255,255,.1);
  --text:#FFFFFF; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.5); --line:rgba(255,255,255,.12); --mark:rgba(255,255,255,.6); color:var(--text); }
.paper .band.float .cell{ background:var(--ink-black); color:var(--text); --text:#FFFFFF; --dim:rgba(255,255,255,.62); --em:#FFFFFF; --line:rgba(255,255,255,.12); --line2:rgba(255,255,255,.3); }
/* the figure that is the point of the pair is the lit one */
.paper .band.float .cell:has(.n.hi){
  background:
    radial-gradient(82% 64% at 100% 0%, color-mix(in srgb, var(--dark-slate) 60%, transparent), transparent 64%),
    linear-gradient(to bottom, color-mix(in srgb, var(--dark-slate) 18%, transparent), transparent 50%),
    var(--ink-black); }
.band.float.pair{ grid-template-columns:1fr 1fr; }

.svc-card{ border-radius:20px; }
.svc-card:nth-child(odd){ background:var(--ink-black); border-color:rgba(255,255,255,.12); --text:#FFFFFF; --mut:rgba(255,255,255,.72); --line2:rgba(255,255,255,.3); color:var(--text); }
.svc-card:nth-child(even){ background:#FFFFFF; border-color:rgba(0,0,0,.1); --text:#000000; --mut:rgba(0,0,0,.7); --line2:rgba(0,0,0,.3); color:var(--text); }
@media (hover:hover){
  .svc-card:nth-child(odd):hover{ background:var(--ink-black); }
  .svc-card:nth-child(even):hover{ background:#FFFFFF; }
}
/* two across: the checkerboard's parity for two columns, then one */
@media (max-width:1080px){
  .svc-card:nth-child(4n+1), .svc-card:nth-child(4n+4){ background:var(--ink-black); border-color:rgba(255,255,255,.12); --text:#FFFFFF; --mut:rgba(255,255,255,.72); --line2:rgba(255,255,255,.3); }
  .svc-card:nth-child(4n+2), .svc-card:nth-child(4n+3){ background:#FFFFFF; border-color:rgba(0,0,0,.1); --text:#000000; --mut:rgba(0,0,0,.7); --line2:rgba(0,0,0,.3); }
}
@media (max-width:640px){
  .svc-card:nth-child(odd){ background:var(--ink-black); border-color:rgba(255,255,255,.12); --text:#FFFFFF; --mut:rgba(255,255,255,.72); --line2:rgba(255,255,255,.3); }
  .svc-card:nth-child(even){ background:#FFFFFF; border-color:rgba(0,0,0,.1); --text:#000000; --mut:rgba(0,0,0,.7); --line2:rgba(0,0,0,.3); }
}
/* On the white band the checkerboard cannot be black and white, because the
   white half would be the ground it stands on. The light card takes the
   coloured ground instead, so both halves still read as cards and the
   alternation survives the move. Written on the token, so it is the red in
   this palette and the deep teal in the one underneath. The parity is
   restated at each width the grid changes at, the same as above. */
.paper .svc-card:nth-child(even){ background:var(--dark-slate); border-color:rgba(255,255,255,.18); --text:#FFFFFF; --mut:rgba(255,255,255,.78); --line2:rgba(255,255,255,.3); color:var(--text); }
@media (hover:hover){
  .paper .svc-card:nth-child(even):hover{ background:var(--dark-slate); }
}
@media (max-width:1080px){
  .paper .svc-card:nth-child(4n+2), .paper .svc-card:nth-child(4n+3){ background:var(--dark-slate); border-color:rgba(255,255,255,.18); --text:#FFFFFF; --mut:rgba(255,255,255,.78); --line2:rgba(255,255,255,.3); }
}
@media (max-width:640px){
  .paper .svc-card:nth-child(even){ background:var(--dark-slate); border-color:rgba(255,255,255,.18); --text:#FFFFFF; --mut:rgba(255,255,255,.78); --line2:rgba(255,255,255,.3); }
}
.split.cards > .tier > .btn{ margin-top:auto; }

/* the stat band */
.band{ display:grid; grid-template-columns:repeat(4,1fr); border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.band .cell{ padding:clamp(20px,calc(3.2 * var(--vhu)),38px) clamp(14px,1.6vw,28px); border-left:1px solid var(--line); display:grid; gap:8px; align-content:start; }
.band .cell:first-child{ border-left:0; }
.band .n{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); font-size:clamp(24px,2.7vw,42px); letter-spacing:-.03em; text-transform:uppercase; line-height:1; }
.band .n.hi{ color:var(--em); }
.band .k{ font-family:var(--font-m); font-size:11.5px; letter-spacing:.15em; text-transform:uppercase; color:var(--dim); }
/* The strip as four cards. Each cell stands on its own on a shared
   perspective: a rounded plane with a hairline, and under it a shadow in
   the ground's solid colour, because a dark shadow on this ground would not
   show. Under the pointer the card turns toward the hand and lifts, the
   shadow drops away and spreads, and a light crosses the face where the
   pointer is. The two angles and the light's position are set by the
   script. A screen with no pointer keeps the cards still. */
.band.float{ border-top:0; border-bottom:0; gap:clamp(18px,1.8vw,28px); perspective:1100px; padding-bottom:24px; }
.band.float .cell{
  --rx:0deg; --ry:0deg; --tz:0px; --mx:50%; --my:50%;
  position:relative; border:0; border-radius:20px; padding:clamp(24px,calc(3.2 * var(--vhu)),40px) clamp(24px,2.2vw,34px);
  background:var(--panel);
  box-shadow:inset 0 0 0 1px var(--line), 0 14px 34px -16px color-mix(in srgb, var(--act-solid) 55%, transparent);
  transform:rotateX(var(--rx)) rotateY(var(--ry)) translateZ(var(--tz));
  transition:transform var(--t-leave) var(--ease-hover), box-shadow var(--t-leave) var(--ease-hover); }
.band.float .cell > *{ position:relative; z-index:1; }
.band.float .cell::after{ content:""; position:absolute; inset:0; z-index:0; border-radius:inherit; pointer-events:none; opacity:0;
  background:radial-gradient(200px 160px at var(--mx) var(--my), color-mix(in srgb, var(--text) 14%, transparent), transparent 72%);
  transition:opacity var(--t-leave) var(--ease-hover); }
@media (hover:hover){
  .band.float .cell{ will-change:transform; }
  .band.float .cell.is-hot{ --tz:56px; transition-duration:var(--t-hover);
    box-shadow:inset 0 0 0 1px var(--line2), 0 34px 60px -18px color-mix(in srgb, var(--act-solid) 75%, transparent); }
  .band.float .cell.is-hot::after{ opacity:1; transition-duration:var(--t-hover); }
}
@media (prefers-reduced-motion: reduce){
  .band.float{ perspective:none; }
  .band.float .cell{ transform:none !important; transition:none !important; }
  .band.float .cell::after{ display:none; }
}

/* prose and the numbered steps */
.prose h2{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); font-size:clamp(20px,1.9vw,30px); text-transform:uppercase; letter-spacing:-.03em; margin:34px 0 14px; line-height:1; }
.prose h2:first-child{ margin-top:0; }
.prose p{ color:var(--mut); margin-bottom:14px; max-width:66ch; font-size:15.5px; line-height:1.7; }
.prose strong{ color:var(--text); font-weight:600; }
.numbered{ counter-reset:step; display:grid; border-top:1px solid var(--line); }
.numbered li{ counter-increment:step; display:grid; grid-template-columns:minmax(56px,110px) 1fr; gap:clamp(14px,3vw,40px); padding:clamp(22px,calc(3.4 * var(--vhu)),40px) 0; border-bottom:1px solid var(--line); }
.numbered li::before{ content:"0" counter(step); font-family:var(--font-m); font-size:11.5px; letter-spacing:.16em; color:var(--mark); padding-top:8px; }
.numbered h3{ font-weight:800; font-stretch:var(--wd); font-size:clamp(20px,2vw,30px); text-transform:uppercase; letter-spacing:-.03em; line-height:1; }
.numbered p{ color:var(--mut); margin-top:10px; max-width:66ch; font-size:15.5px; }

/* pricing: the tiers, the features, the plans */
/* the four sizes as black cards. Each card is the kit's ink black standing
   on whatever ground the page gives it, lit once from its top right corner,
   with a hairline edge. The chosen one carries the band's own teal: a fade
   down from that same corner, a ring of it, a solid button in it and its
   ticks. The words inside keep the site's colours re-read for a black
   ground, set here as the card's own tokens, so the buttons, the marks and
   the focus ring follow without a rule each. On the pricing page a horizon
   glows behind the row in the kit's teal with one thin line of light along
   it; the homepage band goes without. Every word inside is untouched. */
.tiers{ position:relative; isolation:isolate; display:grid; grid-template-columns:repeat(4,1fr); gap:24px; }
.tiers::before{ content:""; position:absolute; left:0; right:0; bottom:-38%; height:70%; z-index:-1; pointer-events:none;
  background:radial-gradient(70% 100% at 50% 100%, rgba(134,176,174,.34), rgba(134,176,174,.08) 45%, transparent 70%); }
.tiers::after{ content:""; position:absolute; left:6%; right:6%; bottom:-30px; height:1px; z-index:-1; pointer-events:none;
  background:linear-gradient(90deg, transparent, var(--teal-3) 35%, var(--teal-3) 65%, transparent); opacity:.7; }
.p-paper .tiers::before, .p-paper .tiers::after{ display:none; }
.tier{ position:relative; display:flex; flex-direction:column; gap:16px; padding:clamp(20px,2vw,32px);
  border-radius:20px; border:1px solid rgba(238,241,241,.10); color:var(--text);
  --bg:var(--ink-black); --text:#EEF1F1; --mut:rgba(238,241,241,.68); --dim:rgba(238,241,241,.46);
  --line:rgba(238,241,241,.10); --line2:rgba(238,241,241,.28);
  --em:var(--teal-3); --mark:var(--teal-3); --mark-2:#D5E0E2;
  --act-solid:var(--teal-3); --act-2:#D5E0E2; --act-ink:var(--ink-black);
  background:
    radial-gradient(circle at 100% 0%, rgba(238,241,241,.07), transparent 48%),
    var(--ink-black);
  transition:translate var(--t-leave) var(--ease-hover), scale var(--t-leave) var(--ease-hover),
    box-shadow var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover); }
/* the chosen one: the same corner, lit in teal, and a ring of it */
.tier.pick{ border-color:rgba(169,203,201,.40);
  background:
    radial-gradient(82% 64% at 100% 0%, rgba(169,203,201,.24), transparent 64%),
    linear-gradient(to bottom, rgba(169,203,201,.06), transparent 50%),
    var(--ink-black); }
/* The one card the page is steering you to is lit from two corners rather
   than one, so the light runs across it instead of sitting in a top corner.
   Found by the badge it holds, not by .tier.pick, because the Hands off card
   further down the pricing page is a chosen card too and stays on its single
   corner. Both palettes carry this, each in its own colour. */
.tier.pick:has(.idx.pop){
  /* and it stands a step out of the row before a pointer is anywhere near
     it, so the card the page is steering you to is the one that is already
     bigger. The gap between the cards is wide enough to take it. */
  scale:1.03;
  background:
    radial-gradient(82% 64% at 100% 0%, rgba(169,203,201,.24), transparent 64%),
    radial-gradient(82% 64% at 0% 100%, rgba(169,203,201,.24), transparent 64%),
    linear-gradient(to bottom, rgba(169,203,201,.06), transparent 50%),
    var(--ink-black); }
.tier.pick .btn-act{ border-color:transparent; background:linear-gradient(to bottom, var(--teal-3), var(--teal-2));
  box-shadow:0 6px 22px rgba(169,203,201,.24); }
/* the panel that follows the four sizes on the pricing page keeps the glass */
/* the panel that follows the four sizes is the same black card they are, one
   wide instead of four, so the whole run reads as one set rather than four
   cards and a pane of something else. Its own tokens for a black ground, the
   way theirs are, so the words, the figures, the links and the button follow. */
.tiers + .box{ position:relative; border-radius:20px; border:1px solid rgba(238,241,241,.10); color:var(--text);
  --bg:var(--ink-black); --text:#EEF1F1; --mut:rgba(238,241,241,.68); --dim:rgba(238,241,241,.46);
  --line:rgba(238,241,241,.10); --line2:rgba(238,241,241,.28);
  --em:var(--teal-3); --mark:var(--teal-3); --mark-2:#D5E0E2;
  --act:#EEF1F1; --act-solid:var(--teal-3); --act-2:#D5E0E2; --act-ink:var(--ink-black);
  background:
    radial-gradient(circle at 100% 0%, rgba(238,241,241,.07), transparent 48%),
    var(--ink-black); }

/* Sheet glass. A pane of three things, all of them paint done once: a tint of
   the type colour thinning to the well colour at the foot, one hairline edge
   with a brighter line along the top and a dark line at the bottom, and a tile
   of grain. Nothing here is redrawn when the page moves, and there is no
   backdrop filter: a pane over a flat ground has nothing to frost and would
   pay for the blur anyway. It takes its colours from the ground it stands on,
   so the same class works on the page, the panels and the band. The mockup and
   the variants for photographs and light grounds are in STUDIO/parts/glass. */
/* A pane of glass is a tint over whatever stands behind it. On the white
   band nothing stands behind it, so the tint reads as grey, and grey is not
   in this palette. The pane takes the black face the band already gives the
   list cards and the price cards; everything else about it is unchanged,
   because the tint, the lit edge and the grain are all drawn from the type
   colour, and re-tokening that to white brings the whole recipe with it. */
.paper .glass{
  background-color:var(--ink-black);
  --text:#FFFFFF; --well:#000000; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.5);
  --line:rgba(255,255,255,.12); --line2:rgba(255,255,255,.28); --mark:rgba(255,255,255,.6);
  color:var(--text); }
.glass{ position:relative; isolation:isolate; border-radius:var(--glass-r, 20px);
  border:1px solid color-mix(in srgb, var(--text) 12%, transparent);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--text) 9%, transparent),
      color-mix(in srgb, var(--text) 4%, transparent) 46%,
      color-mix(in srgb, var(--well) 16%, transparent));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent),
    inset 0 -1px 0 color-mix(in srgb, var(--well) 40%, transparent); }
/* the light along the top edge: brightest in the middle, gone by the corners */
.glass::before{ content:""; position:absolute; z-index:-1; top:0; left:10%; right:10%; height:1px; pointer-events:none;
  background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 55%, transparent) 35%, color-mix(in srgb, var(--text) 55%, transparent) 65%, transparent); }
/* grain, one tile, laid over the pane at a whisper so the gradient cannot band */
.glass::after{ content:""; position:absolute; z-index:-1; inset:0; border-radius:inherit; pointer-events:none; opacity:.07;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .93 0 0 0 0 .94 0 0 0 0 .94 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0/160px 160px; }
/* the label on a chosen card: a pill in the same teal sitting on the card's
   top edge at the right, out of the flow, so the name under it and every
   line after it stay level with the cards beside it. A name is one word in
   capitals and cannot break, and a quarter of a screen has no room for the
   two on one line. The pill keeps a ground of its own because it straddles
   the edge onto whatever the card stands on. */
.tier .idx{ position:absolute; top:-9px; right:clamp(18px,1.6vw,28px); padding:0 9px; border-radius:999px;
  border:1px solid rgba(169,203,201,.42); background:color-mix(in srgb, var(--teal-3) 18%, var(--ink-black));
  font-family:var(--font-m); font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--teal-3); line-height:15px; white-space:nowrap; }
.tier h3{ font-weight:800; font-stretch:var(--wd); font-size:clamp(20px,1.8vw,28px); text-transform:uppercase; letter-spacing:-.03em; line-height:1; }
.tier .blurb{ color:var(--mut); font-size:14.5px; min-height:3em; }
.tier .amt{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); font-size:clamp(30px,2.6vw,44px); letter-spacing:-.04em; line-height:1; }
/* the word before a floor price, and the plus after an open one, both set
   small so the figure stays the thing the eye lands on */
.tier .amt .from{ display:inline-block; font-size:.4em; font-weight:600; letter-spacing:0; color:var(--mut); vertical-align:.3em; margin-right:.22em; }
.tier .amt .plus{ font-size:.62em; color:var(--em); vertical-align:.14em; margin-left:.04em; }
.tier .pre{ display:block; font-family:var(--font-m); font-size:11.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--dim); margin-top:8px; }
.tier .alt{ color:var(--dim); font-size:14px; }
.tier .np{ color:var(--mut); font-size:14px; }
.tier .np b{ color:var(--mark); font-weight:600; }
.feat{ display:grid; margin-top:4px; }
.feat li{ position:relative; padding:7px 0 7px 26px; color:var(--mut); font-size:14px; }
/* the ticks: muted white on a plain card, the teal on the chosen one; a
   cross stays coral on both, because it says what is not included */
.tier.pick .feat li:not(.nope)::before{ background:var(--teal-3); }
.feat li::before{ content:""; position:absolute; left:1px; top:11px; width:13px; height:13px; background:rgba(238,241,241,.62);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.5 6.5 4.5 9.5 10.5 2.5' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.5 6.5 4.5 9.5 10.5 2.5' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat; }
.feat li.nope{ color:var(--dim); }
.feat li.nope::before{ background:var(--no);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.4 2.4 9.6 9.6 M9.6 2.4 2.4 9.6' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.4 2.4 9.6 9.6 M9.6 2.4 2.4 9.6' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat; }
.tier .btn{ margin-top:auto; justify-content:center; }

/* figures: a chapter opens as it climbs the screen, narrow and grey at
   the bottom edge, full width and colour by the upper third (--cp) */
.photo{ position:relative; overflow:hidden; border:1px solid var(--frame); background:var(--panel); border-radius:var(--r); max-width:1100px; margin-left:auto; margin-right:auto; }
.photo img{ width:100%; height:100%; object-fit:cover; }
.photo::after{ content:""; position:absolute; inset:0; background:linear-gradient(to top, rgba(0,0,0,.45), transparent 38%); }
.photo.empty{ aspect-ratio:16/9; background:linear-gradient(160deg, var(--panel-2), var(--well)); }
.photo.empty::after{ display:none; }
.photo.chapter{ width:calc(64% + 36% * var(--cp, 0)); }
.photo.chapter img{ filter:grayscale(calc(1 - var(--cp, 0))) contrast(calc(1.08 - .08 * var(--cp, 0))); transform:scale(calc(1.12 - .12 * var(--cp, 0))); transform-origin:center 40%; }
.js-off .photo.chapter{ width:100%; }
.js-off .photo.chapter img{ filter:none; transform:none; }
/* a client's own mark in the plate instead of a screenshot. The mark is held
   whole and centred, so nothing crops it, and the grade, the scale and the
   gradient on the lower edge all come off: they read as a photograph being
   handled, and a logo is not a photograph. The plate still widens on scroll. */
.photo.logo{ aspect-ratio:21/10; }
.photo.logo img{ object-fit:contain; padding:clamp(26px,5vw,68px); }
.photo.logo::after{ display:none; }
.photo.logo.chapter img{ filter:none; transform:none; }
/* a letterbox is a shape for a screenshot. On a phone it leaves a mark too
   small to read its own ring, so the plate squares up and the padding drops. */
@media (max-width:640px){
  .photo.logo{ aspect-ratio:4/3; }
  .photo.logo img{ padding:18px; }
}
.mico{ width:22px; height:22px; color:var(--mark); display:block; margin-bottom:clamp(18px,calc(2.6 * var(--vhu)),30px); }

/* the ledger of work */
.work-list{ border-top:1px solid var(--line); margin-top:clamp(26px,calc(4 * var(--vhu)),48px); }
.work-row{ display:grid; grid-template-columns:1fr minmax(250px,330px) auto; gap:clamp(16px,3vw,44px); align-items:center;
  padding:clamp(28px,calc(4.5 * var(--vhu)),52px) 0; border-bottom:1px solid var(--line); position:relative; transition:padding-left var(--t-leave) var(--ease-hover); }
.work-row.no-thumb{ grid-template-columns:1fr auto; }
.work-row::before{ content:""; position:absolute; inset:0 calc(-1 * var(--pad)); background:var(--panel); opacity:0; transition:opacity var(--t-leave) var(--ease-hover); z-index:-1; }
.work-row h3{ font-weight:800; font-stretch:var(--wd); font-size:clamp(28px,4vw,66px); text-transform:uppercase; letter-spacing:-.035em; line-height:.95; transition:color var(--t-leave) var(--ease-hover); }
.work-row .wr-meta{ display:flex; gap:22px; flex-wrap:wrap; margin-top:12px; }
.work-row p{ color:var(--mut); max-width:64ch; margin-top:14px; font-size:15.5px; }
.work-row .go{ font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); white-space:nowrap; display:flex; gap:10px; transition:color var(--t-leave) var(--ease-hover); }
.work-row .go .arw{ display:inline-block; transition:translate var(--t-leave) var(--ease-hover); }
.rd-row{ cursor:default; }
.rd-row h3 a{ color:inherit; }
.wr-thumb{ aspect-ratio:16/10; overflow:hidden; border:1px solid var(--frame); background:var(--panel); position:relative; border-radius:var(--r); }
.wr-thumb img{ width:100%; height:100%; object-fit:cover; object-position:top; transition:scale .6s var(--ease-out); }
/* a 1440 px page in a frame: max-width none, or the global reset caps it
   at the slot width and the layout inside collapses to its phone view */
/* a still of the layout stands in for the live miniature where the
   miniature is not shown: the column, below 1080 */
.rd-live .still{ display:none; }
.wr-thumb.rd-live iframe{ position:absolute; left:0; top:0; width:1440px; height:900px; max-width:none; border:0; transform:scale(.25); transform-origin:0 0; pointer-events:none; background:var(--well); }
.wr-spec{ position:relative; overflow:hidden; aspect-ratio:16/10; border:1px solid var(--frame); background:linear-gradient(160deg, var(--panel-2), var(--well)); border-radius:var(--r);
  display:flex; flex-direction:column; justify-content:center; gap:10px; padding:clamp(14px,1.6vw,24px); }
.wr-spec::before{ content:""; position:absolute; inset:0; pointer-events:none; background:repeating-linear-gradient(33deg, rgba(238,241,241,.055) 0 1px, transparent 1px 26px); }
.wr-spec > *{ position:relative; }
.wr-spec .spec-row{ display:flex; justify-content:space-between; gap:12px; border-top:1px solid var(--line); padding-top:9px; }
.wr-spec .spec-row:first-child{ border-top:0; padding-top:0; }

/* the Ready shelf: a heading, the chips that narrow the grid, and the price
   on every card, since a shop puts the price on the thing itself */
.shop-bar{ display:flex; align-items:flex-end; justify-content:space-between; gap:20px 28px; flex-wrap:wrap;
  margin-bottom:clamp(22px,calc(3 * var(--vhu)),34px); }
.shop-filter{ display:flex; flex-wrap:wrap; gap:8px; }
.js-off .shop-filter{ display:none; }
.chip{ background:none; cursor:pointer; line-height:1.2;
  transition:color var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover), background var(--t-leave) var(--ease-hover); }
.chip .ct{ color:var(--dim); margin-left:8px; }
.chip.is-on{ background:var(--evergreen); border-color:var(--act); color:var(--text); }
.chip.is-on .ct{ color:var(--act); }
.shop-head{ display:flex; align-items:baseline; justify-content:space-between; gap:14px; }
.shop-price{ font-family:var(--font-m); font-size:13px; letter-spacing:.06em; color:var(--act); white-space:nowrap; }
.shop-acts{ display:flex; flex-wrap:wrap; gap:10px; margin-top:auto; padding-top:18px; }
/* one layout's own page: the price and the two actions on one line, and the
   layout itself running at something near its real size */
.wr-meta{ display:flex; gap:16px; flex-wrap:wrap; }
.rd-buy{ display:flex; flex-wrap:wrap; align-items:center; gap:14px 20px; margin-top:clamp(24px,calc(3.5 * var(--vhu)),36px); }
.rd-amt{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); font-size:clamp(30px,2.6vw,44px);
  letter-spacing:-.04em; line-height:1; color:var(--act); }
.rd-big{ --rp:42px; display:block; max-width:1320px; margin-left:auto; margin-right:auto; }

/* the shop. The shelf, the tiles and the count sit in one block that stops
   growing at 1400px, so a tile stays tile sized on any monitor. */
.shop{ max-width:1400px; margin-left:auto; margin-right:auto; }

/* the shop tile: a coloured ground with the page sitting in a small browser
   tilted across it, a label in each corner, and the name and the price on a
   line underneath. Four to a row, all in line: a shop shelf, not a spread. */
.work-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:22px; align-items:start;
  margin-top:clamp(22px,calc(3.5 * var(--vhu)),40px); }
.project{ display:block; color:inherit; transition:translate var(--t-leave) var(--ease-hover); }
.project[hidden]{ display:none; }
.project-art{ position:relative; overflow:hidden; aspect-ratio:1.05; border-radius:14px;
  border:1px solid var(--line); transform:translateZ(0); }
/* the grounds walk the whole palette, one colour a tile, eight tiles, eight
   colours, lit from a different corner each time. Set by position, so the
   pattern is here and nowhere in the markup. Every stop is a kit colour. */
/* The wall of tiles is a checkerboard of two grounds, red and black, so it
   reads as a pattern laid down rather than a walk through eight recipes.
   Which tiles are red depends on how many columns there are, so the base
   is the four across the shop and the layout pages stand at, and each
   width below names its own parity. Everything not named is the black
   one. The Work page and the homepage keep their own grounds, set against
   the run they stand on further up this file. */
.work-grid .project-art{
  --tile-black:radial-gradient(ellipse at 62% 34%, var(--jet), var(--ink-black) 72%);
  --tile-red:radial-gradient(ellipse at 38% 46%, var(--dark-slate), var(--evergreen) 74%);
  background:var(--tile, var(--tile-black)); }
/* four across */
.work-grid .project:nth-child(8n+1) .project-art,
.work-grid .project:nth-child(8n+3) .project-art,
.work-grid .project:nth-child(8n+6) .project-art,
.work-grid .project:nth-child(8n+8) .project-art{ --tile:var(--tile-red); }
/* The small browser is a picture of a screen, not a surface of this page,
   the same argument the title bar makes below. Its face is always the well,
   so everything drawn inside it keeps a screen's own light-on-dark tokens
   whatever ground the tile stands on. Without this the drawn panel on the
   Work page takes the white band's black type and paints it on its own
   black face, which measured 1 to 1 and showed as an empty window. */
.paper .browser-frame{ --text:#FFFFFF; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.55);
  --line:rgba(255,255,255,.12); --line2:rgba(255,255,255,.28); color:var(--text); }
/* the page itself, sitting in a small browser tilted on the ground */
.browser-frame{ position:absolute; top:20%; left:11%; width:89%; height:64%; overflow:hidden;
  border:1px solid var(--line2); border-radius:6px 0 0 6px; background:var(--well);
  box-shadow:0 16px 36px rgba(0,0,0,.7);
  transform:rotate(-5deg); transition:transform var(--t-reveal) var(--ease-out); }
/* The title bar is a picture of a browser, not a surface of this site, so
   it keeps a window's own grey and a window's own three lights whatever
   ground the tile stands on. It is the one place grey and these three
   colours are allowed: they are a depiction, and they are what makes the
   tile read as a real window at a glance. */
.browser-top{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:6px 9px;
  background:#2F3033; color:rgba(255,255,255,.6); border-bottom:1px solid rgba(0,0,0,.45);
  font-family:var(--font-m); font-size:7.5px; letter-spacing:.06em;
  white-space:nowrap; overflow:hidden; }
.browser-top > span:first-child{ display:flex; gap:3.5px; flex:0 0 auto; }
.browser-top i{ display:block; width:4.5px; height:4.5px; border-radius:50%; background:#5A5C60; }
.browser-top i:nth-child(1){ background:#FF5F57; }
.browser-top i:nth-child(2){ background:#FEBC2E; }
.browser-top i:nth-child(3){ background:#28C840; }
.browser-frame img{ display:block; width:100%; height:auto; }
/* The tile holds the window and nothing else. What a piece of work is and
   what it did are words, so they stand with the words under it: the label
   over the name, the line about the work under the description. Nothing is
   printed over the picture any more, and nothing is left to catch a corner
   of it. */
.project-info{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; padding:14px 2px 6px; }
.project-info .eyebrow{ display:block; font-family:var(--font-m); font-size:9.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--dim); margin-bottom:6px; }
.art-caption{ display:block; margin-top:6px; font-size:10.5px; line-height:1.4; color:var(--mut); }
.project-info h3{ font-family:var(--font-d); font-weight:800; font-stretch:var(--wd); font-size:16.5px;
  letter-spacing:-.03em; text-transform:uppercase; margin-bottom:4px;
  transition:color var(--t-leave) var(--ease-hover); }
.project-info p{ font-size:11.5px; line-height:1.45; color:var(--mut); }
.project-type{ flex:0 0 auto; margin-top:1px; padding:5px 9px; border:1px solid var(--line2); border-radius:20px;
  font-family:var(--font-m); font-size:10px; letter-spacing:.1em; color:var(--act); white-space:nowrap; }
/* the same tile three to a row for the client work on the Work page, and two
   to a row for the work on the homepage. A tile a third wide is a size up
   from a quarter, so the words step up with it. */
.work-grid.three{ grid-template-columns:repeat(3,1fr); gap:26px; }
.work-grid.two{ grid-template-columns:repeat(2,1fr); gap:26px; }
.work-grid.three .project-info h3, .work-grid.two .project-info h3{ font-size:19px; }
.work-grid.three .project-info p, .work-grid.two .project-info p{ font-size:12.5px; }
.work-grid.three .art-caption, .work-grid.two .art-caption{ font-size:11.5px; }
.work-grid.three .project-info .eyebrow, .work-grid.two .project-info .eyebrow{ font-size:10px; }
/* a drawn panel stands in for the screenshot on the one project that has
   none: the platform's facts set as rows inside the small browser */
.browser-frame.is-pane{ display:flex; flex-direction:column; }
.spec-pane{ position:relative; flex:1; min-height:0; display:flex; flex-direction:column; justify-content:center; gap:8px; padding:14px 14px 18px;
  background:linear-gradient(160deg, var(--panel-2), var(--well)); }
.spec-pane::before{ content:""; position:absolute; inset:0; pointer-events:none; background:repeating-linear-gradient(33deg, rgba(238,241,241,.055) 0 1px, transparent 1px 26px); }
.spec-pane .spec-row{ position:relative; display:flex; justify-content:space-between; gap:12px; border-top:1px solid var(--line); padding-top:8px;
  font-family:var(--font-m); font-weight:500; font-size:8.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }
.spec-pane .spec-row:first-child{ border-top:0; padding-top:0; }
.spec-pane .spec-row b{ font-weight:500; color:var(--mut); }

/* a layout's own page opens centred, so the name, the price and the frame
   under them all sit on the same middle */
.rd-hero{ text-align:center; }
.rd-hero h1,
.rd-hero .lede{ margin-left:auto; margin-right:auto; }
.rd-hero .wr-meta,
.rd-hero .rd-buy{ justify-content:center; }

/* one layout in a frame you can drive: a bar carrying the address and three
   widths, and the page itself scrolling inside. Changing width re-lays the
   same document out; it is not fetched again. */
.vframe{ max-width:1320px; margin-left:auto; margin-right:auto; overflow:hidden;
  background:var(--well); border:1px solid var(--frame); border-radius:18px; }
/* the live frame is a window too, so its bar takes the same grey and the
   same three lights the tiles carry; the address and the width buttons are
   this frame's own and stay as they are */
.vf-bar{ display:flex; align-items:center; gap:16px; padding:10px 14px;
  background:#2F3033; border-bottom:1px solid rgba(0,0,0,.45); }
.vf-dots{ display:flex; gap:6px; flex:0 0 auto; }
.vf-dots i{ width:9px; height:9px; border-radius:50%; background:#5A5C60; }
.vf-dots i:nth-child(1){ background:#FF5F57; }
.vf-dots i:nth-child(2){ background:#FEBC2E; }
.vf-dots i:nth-child(3){ background:#28C840; }
.vf-url{ flex:1; min-width:0; text-align:center; font-size:10.5px; letter-spacing:.1em; color:var(--dim);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; background:var(--well); border-radius:999px; padding:5px 14px; }
.vf-sizes{ display:flex; gap:4px; flex:0 0 auto; }
.js-off .vf-sizes{ display:none; }
.vf-btn{ display:grid; place-items:center; width:30px; height:26px; padding:0; cursor:pointer;
  background:none; border:1px solid transparent; border-radius:8px; color:var(--dim);
  transition:color var(--t-leave) var(--ease-hover), background var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover); }
.vf-btn svg{ width:16px; height:16px; }
.vf-btn.is-on{ background:var(--well); border-color:var(--line2); color:var(--text); }
.vf-stage{ position:relative; overflow:hidden; height:420px; background:var(--well); }
/* width, height and scale are set by the script. The values here are what a
   browser with no script gets: the layout filling the stage, unscaled. */
.vf-stage iframe{ position:absolute; left:0; top:0; width:100%; height:100%; border:0; max-width:none;
  transform-origin:0 0; background:var(--well); }
@media (max-width:640px){ .vf-url{ display:none; } }

/* the studio's positions, tags, the form, the lost page */
.svc{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-top:clamp(30px,calc(5 * var(--vhu)),56px); }
.svc-card{ background:var(--panel); border:1px solid var(--line); border-radius:var(--r); padding:clamp(22px,2.4vw,36px); min-height:250px; display:flex; flex-direction:column; gap:14px;
  transition:background var(--t-leave) var(--ease-hover), border-color var(--t-leave) var(--ease-hover), translate var(--t-leave) var(--ease-hover); }
.svc-card h3{ font-weight:800; font-stretch:var(--wd); font-size:clamp(19px,1.5vw,24px); text-transform:uppercase; letter-spacing:-.03em; line-height:1; margin-top:auto; }
.svc-card p{ color:var(--mut); font-size:15px; line-height:1.6; }
.tags{ display:flex; flex-wrap:wrap; gap:8px; }
.tag{ font-family:var(--font-m); font-size:11.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--mut); border:1px solid var(--line2); padding:6px 12px; border-radius:999px; }
.form{ display:grid; gap:0; }
.field{ display:grid; gap:10px; padding:20px 0; border-bottom:1px solid var(--line); }
.field:first-child{ border-top:1px solid var(--line); }
.field label{ font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); transition:color var(--t-leave) var(--ease-hover); }
.field input,.field select,.field textarea{ background:transparent; border:0; color:var(--text); font-family:var(--font-b); font-size:17px; padding:2px 0; }
.field select{ appearance:none; cursor:pointer; }
.field select option{ background:var(--panel); color:var(--text); }
.field textarea{ min-height:110px; resize:vertical; }
.field input:focus,.field select:focus,.field textarea:focus{ outline:none; }
.field:focus-within label{ color:var(--act); }
.form .btn{ margin-top:26px; justify-self:start; }

/* the contact card: one panel holding the studio's side on the left and the
   form on the right. Every field is a visible box on the well, not a rule
   under a word, so the places to type read as places to type. */
.ccard{ display:grid; grid-template-columns:minmax(260px,340px) 1fr; gap:clamp(28px,4vw,64px); align-items:start;
  background:var(--panel); border:1px solid var(--line); border-radius:16px; padding:clamp(24px,3.2vw,44px); }
.ccard-side{ display:grid; gap:18px; align-content:start; }
.ccard-tag{ display:inline-flex; align-items:center; gap:8px; justify-self:start; color:var(--act);
  border-color:color-mix(in srgb, var(--act) 35%, transparent); background:color-mix(in srgb, var(--act) 8%, transparent); }
.ccard-tag i{ width:6px; height:6px; border-radius:50%; background:var(--act); box-shadow:0 0 0 3px color-mix(in srgb, var(--act) 18%, transparent); }
.ccard-side .d3{ font-size:clamp(24px,2.2vw,32px); }
.ccard-note{ color:var(--mut); font-size:14.5px; line-height:1.55; max-width:36ch; }
.ccard-kv{ margin-top:6px; gap:12px; }
.ccard-kv .ki{ padding-top:12px; }
.ccard-kv .ki:first-child{ border-top:0; padding-top:0; }
.ccard-kv span{ font-size:14px; line-height:1.5; }
.ccard-mail{ display:inline-flex; align-items:center; gap:10px; margin-top:8px; padding-top:18px; border-top:1px solid var(--line); width:100%;
  font-family:var(--font-d); font-weight:700; font-stretch:106%; font-size:17px; letter-spacing:-.01em; color:var(--text); transition:color var(--t-leave) var(--ease-hover); }
.ccard-mail svg{ width:18px; height:18px; color:var(--act); flex:0 0 auto; }
.ccard-form{ grid-template-columns:1fr 1fr; gap:18px 16px; align-content:start; }
.ccard-form .field{ padding:0; border:0; gap:8px; }
.ccard-form .field.wide, .ccard-form .ccard-foot{ grid-column:1 / -1; }
/* The honeypot. Off the page rather than display:none, because a bot reading
   the markup skips a field it can see is hidden and fills one it cannot.
   aria-hidden and tabindex keep it away from a screen reader and the tab
   order, so nobody using the form ever meets it. */
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.ccard-form .field label{ color:var(--mut); letter-spacing:.12em; }
.ccard-form .field input, .ccard-form .field select, .ccard-form .field textarea{
  width:100%; padding:13px 14px; font-size:15.5px; line-height:1.3; color:var(--text);
  background:rgba(0,0,0,.55); border:1px solid var(--line2); border-radius:8px;
  transition:border-color var(--t-leave) var(--ease-hover), box-shadow var(--t-leave) var(--ease-hover), background var(--t-leave) var(--ease-hover); }
.ccard-form .field input::placeholder, .ccard-form .field textarea::placeholder{ color:var(--dim); opacity:1; }
.ccard-form .field select{ padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239C9A99' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 14px center; background-size:16px; }
.ccard-form .field textarea{ min-height:132px; }
.ccard-form .field input:focus, .ccard-form .field select:focus, .ccard-form .field textarea:focus{
  border-color:var(--act); box-shadow:0 0 0 3px color-mix(in srgb, var(--act) 18%, transparent); background-color:rgba(0,0,0,.75); }
.ccard-foot{ display:flex; align-items:center; justify-content:space-between; gap:16px 24px; flex-wrap:wrap; margin-top:6px; }
.ccard-foot .btn{ margin-top:0; }
.ccard-hint{ color:var(--dim); font-size:13px; line-height:1.5; max-width:44ch; }
/* The hint doubles as the form's one line of feedback. When it carries a
   refusal it comes up to full strength rather than changing colour, because
   on a black ground the red is the ground's own family and would read as
   decoration instead of a warning. */
.ccard-hint.is-bad{ color:var(--text); font-weight:500; }
/* what happens next: the heading, then the three steps across in three
   columns under one rule, the number sitting over each one */
.next{ margin-top:clamp(36px,calc(6 * var(--vhu)),64px); }
.next .d3{ font-size:clamp(24px,2.2vw,32px); }
.next-steps{ margin-top:22px; grid-template-columns:repeat(3,1fr); gap:clamp(20px,2.6vw,40px); border-top:0; }
.next-steps li{ display:block; padding:22px 0 0; border-bottom:0; border-top:1px solid var(--line); }
.next-steps li::before{ display:block; padding:0; margin-bottom:14px; }
.next-steps h3{ font-size:clamp(18px,1.5vw,24px); }
.next-steps p{ font-size:14.5px; margin-top:8px; max-width:40ch; }
/* side by side, the message box takes whatever height the side column has
   left over, so the two columns finish on the same line */
@media (min-width:901px){
  .ccard{ align-items:stretch; }
  .ccard-form{ grid-template-rows:auto auto 1fr auto; }
  .ccard-form .field.grow{ grid-template-rows:auto 1fr; }
  .ccard-form .field.grow textarea{ height:100%; }
}
.lost{ min-height:calc(82 * var(--vhu)); display:flex; flex-direction:column; justify-content:center; padding-top:var(--head); }
.lost .m{ margin-bottom:18px; }

@media (hover:hover){
  .lede a:hover{ color:var(--act-2); text-decoration-color:var(--act-2); transition-duration:var(--t-hover); }
  /* A card answers a pointer by coming up off the row: a lift, a step in
     size, the edge brightening and a halo under it in the card's own action
     colour, because a dark shadow on a black ground shows nothing at all.
     The dark half of the shadow is carried for the white band, where the
     opposite is true, so one rule serves both grounds. */
  .tier:hover{ translate:0 -10px; scale:1.025; border-color:var(--line2);
    box-shadow:0 30px 60px -30px rgba(0,0,0,.85),
      0 20px 54px -28px color-mix(in srgb, var(--act-solid) 34%, transparent);
    transition-duration:var(--t-hover); }
  /* The chosen card is already drifting, and the drift owns `translate`, so
     its pop is the scale alone. The two compose because they are separate
     properties. It starts a step above the row and goes further than its
     neighbours, so it reads as the chosen one at rest and under a pointer. */
  .tier.pick:has(.idx.pop):hover{ scale:1.06; }
  .tier.pick:hover{ border-color:rgba(169,203,201,.62); }
  /* The homepage cards carry the panel reveal as well, and the reveal's
     landed state pins `translate` from `.panel.is-in .rv`, which outweighs a
     plain hover. So the lift arrived on the pricing page, where the cards
     ride the flow instead, and never on the homepage. Naming the two
     containers puts the weight back without touching the reveal. */
  .tiers .tier:hover, .split .tier:hover{ translate:0 -10px; }
  @media (prefers-reduced-motion: reduce){
    .tier:hover, .tiers .tier:hover, .split .tier:hover{ translate:none; scale:none; }
  }
  .svc-card:hover{ background:var(--panel-2); border-color:var(--line2); translate:0 -4px; transition-duration:var(--t-hover); }
  .work-row:hover{ padding-left:14px; transition-duration:var(--t-hover); }
  .work-row:hover::before{ opacity:1; transition-duration:var(--t-hover); }
  .work-row:hover h3, .work-row h3 a:hover{ color:var(--act); transition-duration:var(--t-hover); }
  .work-row:hover .go{ color:var(--act); transition-duration:var(--t-hover); }
  .work-row:hover .go .arw{ translate:6px 0; transition-duration:var(--t-hover); }
  .work-row:hover .wr-thumb img{ scale:1.05; }
  .chip:hover{ color:var(--text); border-color:var(--act); transition-duration:var(--t-hover); }
  .ccard-mail:hover{ color:var(--act); transition-duration:var(--t-hover); }
  .project:hover{ translate:0 -4px; transition-duration:var(--t-hover); }
  .project:hover .browser-frame{ transform:rotate(-2deg) translate(-4px,-10px); }
  .project:hover .project-info h3{ color:var(--act); transition-duration:var(--t-hover); }
}

@media (prefers-reduced-motion: reduce){
  .photo.chapter{ width:100%; }
  .photo.chapter img{ filter:none; transform:none; }
  .drift{ translate:none; }
  .tier, .svc-card, .work-row, .wr-thumb img, .btn, .btn::before, .btn::after, .btn .arw, .project, .browser-frame{ transition:none; }
}

@media (max-width:1080px){
  .work-row{ grid-template-columns:1fr auto; }
  /* the picture keeps its place in the column, under the words and across
     the row; a live miniature gives way to its still here */
  .wr-thumb{ grid-column:1 / -1; max-width:520px; }
  .wr-thumb.rd-live iframe{ display:none; }
  .rd-live .still{ display:block; width:100%; height:100%; object-fit:cover; object-position:top; }
  .work-grid{ grid-template-columns:repeat(3,1fr); gap:18px; }
  /* three across: an odd number of columns makes every other tile the
     checkerboard on its own, so the whole set is restated here */
  .work-grid .project:nth-child(2n) .project-art{ --tile:var(--tile-black); }
  .work-grid .project:nth-child(2n+1) .project-art{ --tile:var(--tile-red); }
  .foot-grid{ grid-template-columns:1fr 1fr; gap:36px; }
  .svc{ grid-template-columns:1fr 1fr; }
  .tiers{ grid-template-columns:1fr 1fr; }
  .split{ grid-template-columns:1fr; }
  .ccard{ grid-template-columns:1fr; }
  .next-steps{ grid-template-columns:1fr; gap:0; }
  .next-steps li{ padding:18px 0; }
  .next-steps p{ max-width:60ch; }
  .band{ grid-template-columns:1fr 1fr; }
  .band .cell:nth-child(odd){ border-left:0; }
  .band .cell{ border-top:1px solid var(--line); }
  .band .cell:nth-child(-n+2){ border-top:0; }
}
@media (max-width:900px){
  .work-grid, .work-grid.three, .work-grid.two{ grid-template-columns:repeat(2,1fr); gap:16px; }
  /* two across */
  .work-grid .project:nth-child(4n+2) .project-art,
  .work-grid .project:nth-child(4n+3) .project-art{ --tile:var(--tile-black); }
  .work-grid .project:nth-child(4n+1) .project-art,
  .work-grid .project:nth-child(4n+4) .project-art{ --tile:var(--tile-red); }
  .foot-pill{ display:none; }
  .foot-bar{ padding-right:0; }
}
@media (max-width:640px){
  .svc,.tiers{ grid-template-columns:1fr; }
  .foot-grid{ grid-template-columns:1fr; gap:32px; }
  .foot-bar{ flex-direction:column; align-items:center; text-align:center; }
  .foot-legal i{ display:none; }
  .work-row{ grid-template-columns:1fr; gap:10px; }
  .work-row .go{ margin-top:8px; }
  .work-grid, .work-grid.three, .work-grid.two{ grid-template-columns:1fr; gap:22px; }
  /* one across: the pattern is every other row */
  .work-grid .project:nth-child(2n) .project-art{ --tile:var(--tile-black); }
  .work-grid .project:nth-child(2n+1) .project-art{ --tile:var(--tile-red); }
  .band{ grid-template-columns:1fr; }
  .band .cell{ border-left:0; }
  .numbered li{ grid-template-columns:34px 1fr; gap:12px; }
  .ccard{ padding:20px 16px; border-radius:12px; }
  .ccard-form{ grid-template-columns:1fr; }
  .ccard-foot .btn{ width:100%; justify-content:center; }
  .photo.chapter{ width:100%; }
}
@media (max-width:560px){
  .box{ padding:20px 16px; }
}

/* ---------- 21 · Print ---------- */
@media print{
  .site-head, .skip, #c33w, .spacer{ display:none !important; }
  html, body{ background:#fff; color:#000; }
  html.h .stage{ position:static; overflow:visible; }
  html.h .track{ display:block; transform:none !important; height:auto; }
  html.h .panel{ width:auto; height:auto; }
  html.h .flyers{ display:none; }
  .pxseam{ display:none; }
  html.h .slot img{ visibility:visible; }
  .rv, .rv-words .wi{ opacity:1 !important; translate:0 0 !important; }
  .photo.chapter{ width:100%; }
  .photo.chapter img{ filter:none; transform:none; }
}

/* ---------- 22 · PALETTE TEST, 2026-09-18 ----------
   Black, red, red and white, laid over the slate tokens above so the
   whole site can be judged in the new scheme before anything is decided.
   Wisper's words, in order: the five swatches, then "use straight black",
   then "instead of grey use just white, entire site". So there is no grey
   below: a dimmed role is white or black at an alpha, and a plane that
   has to lift off a ground is that ground moved a step, named as such.
   To take the test off, delete this block: the slate values above are
   untouched, and dev/v10.css.slate-2026-09-18.bak is the file as it was.
     black      #000000   the ground, straight black
     red        #700C0C   the first coloured ground, the solid button,
                          the voice of a headline on the white band
     deep red   #5A0303   the second coloured ground
     white      #FFFFFF   the type, links, the band, the frame around a
                          picture
   One red in the type, and it is the first one. Wisper, 2026-09-19: any
   word carrying a colour is the dark red. So `--em`, the second voice of a
   headline, is #700C0C on every ground: on the white band it measures 12.02
   to 1, and on black it measures 1.75. **1.75 is under the 3 to 1 the
   guidelines ask of large text, and it is a deliberate choice, made with
   the number in front of him and the two rendered side by side.** It holds
   because the only type that ever carries it is display type: every word
   set in `--em` on a black ground measures between 33 and 109 px at weight
   900, and none is under 24. Do not put `--em` on body copy, where 1.75
   really would disappear. The brighter #D6262B measured 4.17 and was the
   second voice for one day, 2026-09-18 to 09-19; it is gone because
   nothing used it once the dark red took the job.
   Derived: jet #151515 and charcoal #232323 lift off the black; #180A0A
   is the black leaning to the red; #7E1A1A, #8E2828 and #6A1010 lift off
   the two reds. The tile grounds on the Work and Ready pages stay in the
   black and red family: a gradient from white into a dark passes through
   grey on its way, and into a red through pink, and neither is in the
   scheme. White can still enter a tile as a flat white tile with black
   type, if that is wanted; it is not done here.
   ---------------------------------------------------------------- */
:root{
  --ink-black:#000000; --jet:#151515; --charcoal:#232323; --taupe:#232323; --dim-grey:#FFFFFF;
  --teal:#5A0303; --blue-slate:#232323; --dark-slate:#700C0C; --evergreen:#5A0303; --jet-2:#180A0A;
  --teal-2:#FFFFFF; --teal-3:#FFFFFF;

  /* --ink is the page wipe and nothing else. It was #180A0A, the black
     leaning to the red, and over a whole screen that leaned far enough to
     read as red on the way across. Straight black, on his word. */
  --well:#000000; --bg:#000000; --ink:#000000; --panel:#151515; --panel-2:#232323;
  --line:rgba(255,255,255,.12); --line2:rgba(255,255,255,.28); --frame:rgba(255,255,255,.3);
  --text:#FFFFFF; --mut:rgba(255,255,255,.8); --dim:rgba(255,255,255,.62);
  --act:#FFFFFF; --act-solid:#700C0C; --act-2:#5A0303; --act-ink:#FFFFFF;
  --em:#700C0C; --mark:rgba(255,255,255,.5); --mark-2:rgba(255,255,255,.62);

  --paper:#FFFFFF; --paper-ink:#000000; --paper-mut:rgba(0,0,0,.72); --paper-line:rgba(0,0,0,.16);

  --run-1:#5A0303; --run-2:#700C0C; --run-3:#FFFFFF; --run-4:#FFFFFF; --run-5:#FFFFFF;
}
.ground-slate{
  background:var(--dark-slate); color:#FFFFFF;
  --bg:var(--dark-slate); --panel:#7E1A1A; --panel-2:#8E2828; --text:#FFFFFF; --mut:rgba(255,255,255,.84); --dim:rgba(255,255,255,.66);
  --line:rgba(255,255,255,.18); --line2:rgba(255,255,255,.36); --frame:rgba(255,255,255,.26);
  --em:rgba(255,255,255,.78); --act:#FFFFFF; --act-solid:#000000; --act-2:#151515; --act-ink:#FFFFFF; --mark:rgba(255,255,255,.7); --mark-2:#FFFFFF;
}
.ground-green{
  background:var(--evergreen); color:#FFFFFF;
  --bg:var(--evergreen); --panel:#6A1010; --panel-2:#700C0C; --text:#FFFFFF; --mut:rgba(255,255,255,.84); --dim:rgba(255,255,255,.66);
  --line:rgba(255,255,255,.18); --line2:rgba(255,255,255,.36); --frame:rgba(255,255,255,.26);
  --em:rgba(255,255,255,.78); --act:#FFFFFF; --act-solid:#FFFFFF; --act-2:rgba(255,255,255,.85); --act-ink:#000000; --mark:rgba(255,255,255,.7); --mark-2:#FFFFFF;
}
/* the band is white: black type, and red for the voice, the links and the button */
.paper{
  background:var(--paper); color:var(--paper-ink);
  --bg:var(--paper); --well:#000000; --panel:rgba(0,0,0,.05); --panel-2:rgba(0,0,0,.09);
  --text:#000000; --mut:rgba(0,0,0,.72); --dim:rgba(0,0,0,.55);
  --line:rgba(0,0,0,.14); --line2:rgba(0,0,0,.32); --frame:rgba(0,0,0,.22);
  --em:#700C0C; --act:#700C0C; --act-solid:#700C0C; --act-2:#5A0303; --act-ink:#FFFFFF;
  --mark:rgba(0,0,0,.5); --mark-2:rgba(0,0,0,.72);
}
/* a page that ends on black glows red at the foot; the runs below set their own */
.site-foot{ --glow:rgba(112,12,12,.5); }
/* the price cards: black cards with white buttons, the chosen one lit red */
.tiers::before{ background:radial-gradient(70% 100% at 50% 100%, rgba(112,12,12,.5), rgba(112,12,12,.12) 45%, transparent 70%); }
.paper .tiers::after{ background:linear-gradient(90deg, transparent, rgba(0,0,0,.35) 35%, rgba(0,0,0,.35) 65%, transparent); }
.tier, .tiers + .box{
  border-color:rgba(255,255,255,.10);
  --text:#FFFFFF; --mut:rgba(255,255,255,.68); --dim:rgba(255,255,255,.46);
  --line:rgba(255,255,255,.10); --line2:rgba(255,255,255,.28);
  --mark-2:rgba(255,255,255,.8); --act-2:rgba(255,255,255,.85);
  background:radial-gradient(circle at 100% 0%, rgba(255,255,255,.07), transparent 48%), var(--ink-black);
}
.tier.pick{
  border-color:rgba(112,12,12,.8);
  --act-solid:#700C0C; --act-2:#5A0303; --act-ink:#FFFFFF;
  background:
    radial-gradient(82% 64% at 100% 0%, rgba(112,12,12,.6), transparent 64%),
    linear-gradient(to bottom, rgba(112,12,12,.18), transparent 50%),
    var(--ink-black);
}
.tier.pick .btn-act{ background:linear-gradient(to bottom, #700C0C, #5A0303); box-shadow:0 6px 22px rgba(112,12,12,.45); }
/* The chosen card's edge under a pointer. Without this it takes the hover
   border from the palette underneath, which is the slate teal, and a teal
   edge flashes onto a red card the moment the mouse arrives. */
@media (hover:hover){
  .tier.pick:hover{ border-color:rgba(112,12,12,1); }
}
.tier .idx{ border-color:rgba(112,12,12,.9); background:#700C0C; color:#FFFFFF; }
/* The chosen tier's badge is the one label on the page meant to catch an
   eye: a red pill with a white hairline, a ring of the red around that,
   and a shadow under it, drifting a few pixels so it reads as sitting
   above the card rather than printed on its edge. The site's other badge,
   Optional on the Hands off card, keeps the quiet version, which is why
   this hangs off its own class and not off the chosen card. Nothing
   drifts under reduced motion. */
.tier .idx.pop{ top:-11px; padding:0 13px; line-height:20px; font-size:11.5px; letter-spacing:.16em;
  border:1px solid rgba(255,255,255,.58);
  box-shadow:0 0 0 4px rgba(112,12,12,.34), 0 9px 20px -6px rgba(112,12,12,.95); }
/* and the whole card floats, not the label on it: the chosen tier stands
   off the row on a shadow of its own red and drifts slowly, carrying its
   badge with it. Found by the badge it holds, because the Hands off card
   is a chosen card too and must stay still. The drift owns `translate`,
   so this one card does not take the hover lift its neighbours do; its
   border still answers a pointer. The flow in on the pricing page uses
   `transform`, so the two compose instead of fighting. */
.tier.pick:has(.idx.pop){
  box-shadow:0 24px 50px -22px rgba(112,12,12,.95), 0 0 0 1px rgba(112,12,12,.4);
  animation:tier-float 4.6s var(--ease-inout) infinite;
  /* lit from the bottom left as well as the top right, so the red runs
     across the card on a diagonal rather than pooling in one corner */
  background:
    radial-gradient(82% 64% at 100% 0%, rgba(112,12,12,.6), transparent 64%),
    radial-gradient(82% 64% at 0% 100%, rgba(112,12,12,.6), transparent 64%),
    linear-gradient(to bottom, rgba(112,12,12,.18), transparent 50%),
    var(--ink-black); }
@keyframes tier-float{ 0%, 100%{ translate:0 0; } 50%{ translate:0 -8px; } }
@media (prefers-reduced-motion: reduce){
  .tier.pick:has(.idx.pop){ animation:none; }
}
.ccard-tag{ border-color:rgba(255,255,255,.3); background:rgba(255,255,255,.07); }
.ccard-tag i{ box-shadow:0 0 0 3px rgba(255,255,255,.16); }
/* the footer glow follows the run above it, as before, in the new grounds */
main:has(> section:last-of-type.ground-slate) + .site-foot{ --glow:rgba(112,12,12,.7); }
main:has(> section:last-of-type.ground-green) + .site-foot{ --glow:rgba(90,3,3,.85); }
main:has(> section:last-of-type.paper) + .site-foot{ --glow:rgba(255,255,255,.22); }

/* ---------- 23 · The run that flows out ----------
   The boxes of the four sizes run are not in place when the run arrives.
   As it crosses the screen each one rises the last of the way into its
   own place and takes its colour, quickly, one after another rather than
   all together. Nothing travels from anywhere and nothing is measured: a
   box simply arrives where it belongs, which is why this is a flow and
   not the circle it was first built as. The move is a `transform`, so a
   card's own hover lift, which is a `translate`, still composes on top of
   it. Under reduced motion nothing moves; with the script off --p is 1
   and every box stands in its place.
   ---------------------------------------------------------------- */
.flow-stage{ position:relative; }
.flow-item{
  transform:translateY(calc(var(--rise, 54px) * (1 - var(--p, 1)))) scale(calc(0.965 + 0.035 * var(--p, 1)));
  opacity:clamp(0, calc(var(--p, 1) * 1.6), 1); }
@media (prefers-reduced-motion: reduce){
  .flow-item{ transform:none !important; opacity:1 !important; }
}


/* ---------- 24 · Quiet night, 2026-09-29 ----------
   The mockup. Night blue keeps the homepage and the colour still arrives
   as light, but a fraction of it: the first screen carries none, two
   panels carry one bloom each, and nothing else on the page glows. Every
   inner page stands on white, with a cool paper band where the old site
   changed material, night cards where a card is meant to be looked at,
   and a night footer closing every page so the site still reads as one.
   Section 22 underneath is the red palette; the tokens here sit over it.
   ---------------------------------------------------------------- */
:root{
  --night:#0B1122; --night-2:#121B34; --night-3:#1A2645;
  --ink-black:#0B1122; --jet:#121B34; --charcoal:#1A2645; --taupe:#1A2645; --dim-grey:#FFFFFF;
  --teal:#121B34; --blue-slate:#1A2645; --dark-slate:#121B34; --evergreen:#121B34; --jet-2:#121B34;
  --well:#0B1122; --bg:#0B1122; --ink:#0B1122; --panel:#121B34; --panel-2:#1A2645;
  --line:rgba(226,234,255,.12); --line2:rgba(226,234,255,.28); --frame:rgba(226,234,255,.28);
  --text:#FFFFFF; --mut:rgba(226,234,255,.82); --dim:rgba(226,234,255,.7);
  --act:#FFFFFF; --act-solid:#FFFFFF; --act-2:#DCE6FF; --act-ink:#0B1122;
  --em:#9CCBFF; --mark:rgba(156,203,255,.8); --mark-2:#C9E2FF;
  --cobalt:#2F5BD8; --cobalt-2:#1E43B3;
  --paper:#EEF2F8; --paper-ink:#0B1122; --paper-mut:rgba(11,17,34,.72); --paper-line:rgba(11,17,34,.14);
  --run-1:#2DD4BF; --run-2:#38BDF8; --run-3:#6366F1; --run-4:#C084FC; --run-5:#EEF2FF;
}
.ground-slate, .ground-green{
  background:#0D1428; color:#FFFFFF; --bg:#0D1428; --panel:var(--night-2); --panel-2:var(--night-3);
  --text:#FFFFFF; --mut:rgba(226,234,255,.84); --dim:rgba(226,234,255,.7);
  --line:rgba(226,234,255,.14); --line2:rgba(226,234,255,.32); --frame:rgba(226,234,255,.26);
  --em:#9CCBFF; --act:#FFFFFF; --act-solid:#FFFFFF; --act-2:#DCE6FF; --act-ink:#0B1122;
  --mark:rgba(156,203,255,.8); --mark-2:#C9E2FF;
}
/* the band is a cool paper, its voice and links in cobalt */
.paper{
  background:var(--paper); color:var(--paper-ink); --bg:var(--paper); --well:#0B1122;
  --panel:#FFFFFF; --panel-2:#E4E9F3;
  --text:#0B1122; --mut:rgba(11,17,34,.76); --dim:rgba(11,17,34,.62);
  --line:rgba(11,17,34,.12); --line2:rgba(11,17,34,.3); --frame:rgba(11,17,34,.18);
  --em:var(--cobalt); --act:var(--cobalt); --act-solid:#0B1122; --act-2:#1A2645; --act-ink:#FFFFFF;
  --mark:rgba(11,17,34,.5); --mark-2:var(--cobalt);
}

/* ---- the height unit ----
   Every gap, padding and full screen in this file is measured in --vhu, a
   hundredth of the screen's height, rather than in vh. On a desktop it is
   exactly that. On a touch screen the script pins it in pixels once per
   width, because some phone browsers let the viewport height follow the
   address bar as it slides, and a page measured in vh stretches with it.
   The small viewport is the fallback, so a page with no script still holds. */
:root{ --vhu:1svh; }

/* ---- the wash ----
   Colour on a dark ground is a wash, not a dot: a gradient so wide and so
   soft that it has no visible centre, laid in from a corner and gone well
   before the far edge. On an inner page's first screen two of them stand in
   opposite corners and breathe, one against the other, over sixteen and
   twenty seconds: a little brighter, a little larger, and back. Slow
   enough that nobody sees it move and everybody sees that it is alive.
   Plain gradients moved by opacity and transform only, so the compositor
   carries them; no blur, no blend. Still under reduced motion. */
@keyframes wash-a{ from{ opacity:.55; transform:translate3d(0,0,0) scale(1); } to{ opacity:.9; transform:translate3d(2%,1.5%,0) scale(1.05); } }
@keyframes wash-b{ from{ opacity:.9; transform:translate3d(0,0,0) scale(1.05); } to{ opacity:.55; transform:translate3d(-2%,-1.5%,0) scale(1); } }
/* ---- the homepage: the first screen is the rails under their own dark
   frame and no colour, the work panel stands on white, and two panels
   carry one still wash ---- */
section.p-hero, section.p-ready, section.p-ledger, section.p-contact{ background:var(--night); --bg:var(--night); }
section.p-process::before, section.p-contact::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:.55; }
section.p-process::before{ background:radial-gradient(ellipse 64% 60% at 0% 100%, rgba(20,184,166,.5), rgba(19,78,74,.22) 40%, transparent 68%); }
section.p-contact::before{ background:radial-gradient(ellipse 70% 60% at 50% 30%, rgba(29,78,216,.5), rgba(23,37,84,.2) 44%, transparent 72%); }
/* the work panel on white, as the Work page stands: night type, the voice
   in cobalt, pale tiles, and the screens inside keep their own dark face.
   The tile and frame rules are shared with the inner pages further down. */
section.p-work{ background:#FFFFFF; color:var(--text);
  --bg:#FFFFFF; --panel:#FFFFFF; --panel-2:#EEF2F8;
  --line:rgba(11,17,34,.12); --line2:rgba(11,17,34,.3); --frame:rgba(11,17,34,.16);
  --text:#0B1122; --mut:rgba(11,17,34,.74); --dim:rgba(11,17,34,.58);
  --act:var(--cobalt); --act-solid:#0B1122; --act-2:#1A2645; --act-ink:#FFFFFF;
  --em:var(--cobalt); --mark:rgba(11,17,34,.45); --mark-2:var(--cobalt); }

/* a Ready layout still carries its own colour under its tile, held low,
   and brought up only under a pointer */
[href*="orchard"]{ --glow-c:#F59E0B; }
[href*="launch"]{ --glow-c:#EF4444; }
[href*="studio/"], [href="ready-studio.html"]{ --glow-c:#EC4899; }
[href*="ledger"]{ --glow-c:#10B981; }
[href*="hearth"]{ --glow-c:#F97316; }
[href*="sundog"]{ --glow-c:#FACC15; }
[href*="focus"]{ --glow-c:#8B5CF6; }
[href*="counter"]{ --glow-c:#06B6D4; }
.ready-row .slot, .project[href^="ready-"] .project-art{
  box-shadow:0 -12px 52px -22px color-mix(in srgb, var(--glow-c, transparent) 72%, transparent), 0 0 0 1px rgba(226,234,255,.08);
  transition:box-shadow var(--t-hover) var(--ease-hover); }
@media (hover:hover){
  .ready-row .slot:hover, .project[href^="ready-"]:hover .project-art{ box-shadow:0 -18px 68px -18px var(--glow-c, transparent), 0 0 0 1px rgba(226,234,255,.22); }
}
/* On the run the card is dealt onto the slot and rises out of the row as it
   passes the middle of the screen, so the glow rides the card: the slot
   paints none, the card carries its layout's colour (the script copies it
   across) and the glow comes up with the card's nearness to the middle. */
html.h .ready-row .slot{ box-shadow:none; }
.flyer.is-wave{ box-shadow:0 18px 50px rgba(0,0,0,.35),
  0 -12px 56px -20px color-mix(in srgb, var(--glow-c, transparent) calc(60% + var(--near, 0) * 40%), transparent); }

/* the price cards: flat night cards, one hairline each, the chosen one
   washed with cobalt from its top edge and standing a step forward. No
   horizon under the row, no ring, no drift. */
.tiers::before, .tiers::after{ display:none; }
.tier, .tiers + .box{ background:var(--night); border-color:rgba(226,234,255,.12); }
.tier.pick{ border-color:rgba(47,91,216,.7); --act-solid:#FFFFFF; --act-2:#DCE6FF; --act-ink:#0B1122;
  background:linear-gradient(to bottom, rgba(47,91,216,.34), transparent 52%), var(--night); }
.tier.pick .btn-act{ background:#FFFFFF; color:#0B1122; box-shadow:none; }
@media (hover:hover){ .tier.pick:hover{ border-color:rgba(47,91,216,1); } }
.tier .idx{ border-color:var(--cobalt); background:var(--cobalt); color:#FFFFFF; }
.tier .idx.pop{ border-color:rgba(255,255,255,.4); box-shadow:0 8px 18px -8px rgba(11,17,34,.8); }
.tier.pick:has(.idx.pop){ animation:none; background:linear-gradient(to bottom, rgba(47,91,216,.34), transparent 52%), var(--night);
  box-shadow:0 30px 60px -34px rgba(11,17,34,.9), 0 0 0 1px rgba(47,91,216,.35); }

/* a centred head in a box: the box goes, the words stay */
html.page .pv .p-head.mid.hbox{ border:0; padding:0; background:none; color:var(--text);
  --text:#0B1122; --mut:rgba(11,17,34,.76); --dim:rgba(11,17,34,.62); --em:var(--cobalt); --line:rgba(11,17,34,.12); }

/* the menu button: three lines at rest, and while the menu is open the
   three turn through the middle of the ring into a six point star, one
   spoke upright and two across it. Each line turns about its own centre
   and the outer two slide to the middle, on the hover curve. */
.icon-btn svg path{ transform-box:fill-box; transform-origin:center; transition:transform var(--t-hover) var(--ease-hover); }
.icon-btn[aria-expanded="true"] svg path:nth-child(1){ transform:translateY(4px) rotate(30deg); }
.icon-btn[aria-expanded="true"] svg path:nth-child(2){ transform:rotate(90deg); }
.icon-btn[aria-expanded="true"] svg path:nth-child(3){ transform:translateY(-4px) rotate(-30deg); }
@media (prefers-reduced-motion: reduce){ .icon-btn svg path{ transition:none; } }

/* the footer: one bloom over the rule, low */
.site-foot{ --glow:rgba(47,91,216,.28); }
main:has(> section:last-of-type.ground-slate) + .site-foot,
main:has(> section:last-of-type.ground-green) + .site-foot{ --glow:rgba(47,91,216,.34); }
main:has(> section:last-of-type.paper) + .site-foot{ --glow:rgba(47,91,216,.22); }
.ccard-tag{ border-color:rgba(226,234,255,.3); background:rgba(226,234,255,.07); }

/* ---- the inner pages: white ----
   The page is white, the type is night, the voice and the links are
   cobalt, and a button is a night pill. Where the old page changed to the
   paper band it changes to a cool tint instead, so the page still has
   bands to read by. Cards are white on the tint and lift on a soft shadow;
   the price cards and the checkerboard's dark squares stay night, because
   a card meant to be looked at wants the ground's opposite. Screens shown
   inside a tile keep a screen's own dark face. */
html.page{
  --bg:#FFFFFF; --panel:#FFFFFF; --panel-2:#EEF2F8; --well:#0B1122; --ink:#0B1122;
  --line:rgba(11,17,34,.12); --line2:rgba(11,17,34,.3); --frame:rgba(11,17,34,.16);
  --text:#0B1122; --mut:rgba(11,17,34,.74); --dim:rgba(11,17,34,.58);
  --act:var(--cobalt); --act-solid:#0B1122; --act-2:#1A2645; --act-ink:#FFFFFF;
  --em:var(--cobalt); --mark:rgba(11,17,34,.45); --mark-2:var(--cobalt);
  --paper:#F3F5F9; --paper-ink:#0B1122; --paper-mut:rgba(11,17,34,.74); --paper-line:rgba(11,17,34,.12);
  --shadow:0 1px 2px rgba(11,17,34,.04), 0 14px 36px -22px rgba(11,17,34,.22);
}
html.page .paper{ --panel:#FFFFFF; --panel-2:#E4E9F3; --dim:rgba(11,17,34,.6); }

/* the bar frosts to the ground it is standing over: white over the page,
   night over the title screen (the script writes `over-night` on the root
   while the title screen is under the bar) */
html.page .head-row{ border-color:rgba(11,17,34,.1); transition:border-color .35s var(--ease-hover); }
html.page .head-row::before{ background:rgba(255,255,255,.7); transition:background .35s var(--ease-hover); }
html.page .head-row .mark, html.page .head-row .icon-btn, html.page .head-row .nav-cta{ transition:color .35s var(--ease-hover), border-color .35s var(--ease-hover); }
html.page.over-night .head-row{ border-color:rgba(226,234,255,.12);
  --text:#FFFFFF; --mut:rgba(226,234,255,.82); --dim:rgba(226,234,255,.7); --act:#FFFFFF; --line2:rgba(226,234,255,.3); --bg:var(--night); }
html.page.over-night .head-row::before{ background:rgba(11,17,34,.55); }
html.page.over-night .nav{ background:rgba(11,17,34,.88); border-color:rgba(226,234,255,.12); box-shadow:0 20px 44px rgba(0,0,0,.5); }
html.page.over-night .nav a[aria-current="page"]{ background:rgba(226,234,255,.05); }
html.page.over-night .icon-btn[aria-expanded="true"]{ background:rgba(226,234,255,.08); }
@media (hover:hover){
  html.page.over-night .nav-cta:hover{ color:#FFFFFF; background:rgba(255,255,255,.1); border-color:#FFFFFF; }
  html.page.over-night .icon-btn:hover, html.page.over-night .nav a:hover{ background:rgba(226,234,255,.07); }
}
/* the homepage's bar takes its one white panel the same way: the script
   writes `over-white` on the root while the work panel holds the middle of
   the screen under the bar */
html:not(.page) .head-row{ transition:border-color .35s var(--ease-hover); }
html:not(.page) .head-row::before{ transition:background .35s var(--ease-hover); }
html.over-white .head-row{ border-color:rgba(11,17,34,.1);
  --text:#0B1122; --mut:rgba(11,17,34,.74); --dim:rgba(11,17,34,.58); --act:var(--cobalt); --line2:rgba(11,17,34,.3); --mark-2:var(--cobalt); --bg:#FFFFFF; }
html.over-white .head-row::before{ background:rgba(255,255,255,.7); }
html.page .nav, html.over-white .nav{ border-color:rgba(11,17,34,.1); background:rgba(255,255,255,.86); box-shadow:0 20px 44px -10px rgba(11,17,34,.25); }
html.page .nav a[aria-current="page"], html.over-white .nav a[aria-current="page"]{ background:rgba(11,17,34,.04); }
html.page .icon-btn[aria-expanded="true"], html.over-white .icon-btn[aria-expanded="true"]{ background:rgba(11,17,34,.05); }
@media (hover:hover){
  html.page .nav-cta:hover, html.over-white .nav-cta:hover{ color:var(--cobalt-2); background:rgba(47,91,216,.08); border-color:var(--cobalt); }
  html.page .icon-btn:hover, html.page .nav a:hover, html.over-white .icon-btn:hover, html.over-white .nav a:hover{ background:rgba(11,17,34,.05); }
}

/* the title screen stands on night, two washes
   breathing behind it, and the white page begins under it. Its tokens are
   the night ground's, so the title, the lede and any link or card in it
   read as they do on the homepage. */
html.page main > .page-hero{ position:relative; isolation:isolate; overflow:hidden;
  background:var(--night); color:#FFFFFF; --bg:var(--night); --panel:var(--night-2); --panel-2:var(--night-3);
  --text:#FFFFFF; --mut:rgba(226,234,255,.82); --dim:rgba(226,234,255,.7);
  --line:rgba(226,234,255,.12); --line2:rgba(226,234,255,.28); --frame:rgba(226,234,255,.28);
  --act:#FFFFFF; --act-solid:#FFFFFF; --act-2:#DCE6FF; --act-ink:#0B1122;
  --em:#9CCBFF; --mark:rgba(156,203,255,.8); --mark-2:#C9E2FF; }
html.page main > .page-hero::before, html.page main > .page-hero::after{ content:""; position:absolute; inset:0; z-index:-1; pointer-events:none; will-change:opacity, transform; }
html.page main > .page-hero::before{ background:radial-gradient(ellipse 62% 58% at 16% 18%, rgba(31,181,164,.62), rgba(14,116,144,.3) 42%, transparent 72%); animation:wash-a 16s var(--ease-inout) infinite alternate; }
html.page main > .page-hero::after{ background:radial-gradient(ellipse 62% 58% at 86% 86%, rgba(47,91,216,.66), rgba(76,29,149,.28) 42%, transparent 72%); animation:wash-b 20s var(--ease-inout) infinite alternate; }
@media (prefers-reduced-motion: reduce){
  html.page main > .page-hero::before, html.page main > .page-hero::after{ animation:none; }
}
/* a title screen with no cards under it is a band, so it keeps a band's
   depth at the foot */
html.page main > .page-hero:not(:has(.band)){ padding-bottom:clamp(64px,calc(10 * var(--vhu)),128px); }
/* the stat cards on the title screen stay white, so they carry the page's
   white down out of the night */
html.page .pxseam{ display:none; }

/* cards */
html.page .lc, html.page .paper .lc{ background:#FFFFFF; border-color:var(--line); box-shadow:var(--shadow); color:var(--text);
  --text:#0B1122; --mut:rgba(11,17,34,.74); --dim:rgba(11,17,34,.58); --line:rgba(11,17,34,.12); --mark:rgba(11,17,34,.45); }
html.page .lc.lit{ border-color:rgba(47,91,216,.35);
  background:linear-gradient(to bottom, rgba(47,91,216,.07), transparent 55%), #FFFFFF; }
html.page .box{ box-shadow:var(--shadow); }
html.page .glass, html.page .paper .glass{ background:#FFFFFF; background-color:#FFFFFF; border:1px solid var(--line); border-radius:20px; box-shadow:var(--shadow); color:var(--text);
  --text:#0B1122; --mut:rgba(11,17,34,.74); --dim:rgba(11,17,34,.58); --line:rgba(11,17,34,.12); --line2:rgba(11,17,34,.3); --mark:rgba(11,17,34,.45); --well:#0B1122; }
html.page .glass::before, html.page .glass::after{ display:none; }

/* the stat cards: white, lifted, the figure that matters washed cobalt */
/* each card throws its own colour under it, the way a Ready tile does, in
   the header's own colours walked along the row; the glow is the card's
   shadow, so it turns and lifts with the card under a pointer */
html.page .band.float .cell, html.page .paper .band.float .cell{ background:#FFFFFF; color:var(--text);
  --text:#0B1122; --dim:rgba(11,17,34,.58); --em:var(--cobalt); --line:rgba(11,17,34,.12); --line2:rgba(11,17,34,.3);
  box-shadow:inset 0 0 0 1px var(--line), 0 18px 56px -20px color-mix(in srgb, var(--glow-c, var(--cobalt)) 60%, transparent); }
html.page .band.float .cell:nth-child(4n+1){ --glow-c:#1FB5A4; }
html.page .band.float .cell:nth-child(4n+2){ --glow-c:#2F5BD8; }
html.page .band.float .cell:nth-child(4n+3){ --glow-c:#7C3AED; }
html.page .band.float .cell:nth-child(4n+4){ --glow-c:#0EA5E9; }
html.page .paper .band.float .cell:has(.n.hi){ background:linear-gradient(to bottom, rgba(47,91,216,.08), transparent 60%), #FFFFFF; }
@media (hover:hover){
  html.page .band.float .cell.is-hot{ box-shadow:inset 0 0 0 1px var(--line2), 0 34px 76px -20px color-mix(in srgb, var(--glow-c, var(--cobalt)) 95%, transparent); }
}
html.page .band.float .cell::after{ background:radial-gradient(200px 160px at var(--mx) var(--my), rgba(47,91,216,.08), transparent 72%); }

/* the four positions: night and white, alternating, on the tint */
html.page .svc-card:nth-child(odd){ background:var(--night); border-color:rgba(226,234,255,.12); }
html.page .svc-card:nth-child(even), html.page .paper .svc-card:nth-child(even){ background:#FFFFFF; border-color:var(--line);
  --text:#0B1122; --mut:rgba(11,17,34,.74); --line2:rgba(11,17,34,.3); color:var(--text); box-shadow:var(--shadow); }
@media (hover:hover){
  html.page .svc-card:nth-child(odd):hover{ background:var(--night-2); }
  html.page .svc-card:nth-child(even):hover, html.page .paper .svc-card:nth-child(even):hover{ background:#FFFFFF; }
}
@media (max-width:1080px){
  html.page .svc-card:nth-child(4n+1), html.page .svc-card:nth-child(4n+4){ background:var(--night); border-color:rgba(226,234,255,.12); --text:#FFFFFF; --mut:rgba(226,234,255,.82); --line2:rgba(226,234,255,.3); box-shadow:none; }
  html.page .svc-card:nth-child(4n+2), html.page .svc-card:nth-child(4n+3), html.page .paper .svc-card:nth-child(4n+2), html.page .paper .svc-card:nth-child(4n+3){ background:#FFFFFF; border-color:var(--line); --text:#0B1122; --mut:rgba(11,17,34,.74); --line2:rgba(11,17,34,.3); box-shadow:var(--shadow); }
}
@media (max-width:640px){
  html.page .svc-card:nth-child(odd){ background:var(--night); border-color:rgba(226,234,255,.12); --text:#FFFFFF; --mut:rgba(226,234,255,.82); --line2:rgba(226,234,255,.3); box-shadow:none; }
  html.page .svc-card:nth-child(even), html.page .paper .svc-card:nth-child(even){ background:#FFFFFF; border-color:var(--line); --text:#0B1122; --mut:rgba(11,17,34,.74); --line2:rgba(11,17,34,.3); box-shadow:var(--shadow); }
}

/* the tiles: two pale tints in the checkerboard, and the screen inside keeps
   its own dark face */
html.page .work-grid .project-art, section.p-work .work-grid .project-art{ --tile-black:#EEF2F8; --tile-red:#E2E8F3; border-color:var(--line); }
html.page .paper .work-grid.three .project:nth-child(3n+1) .project-art,
html.page .paper .work-grid.three .project:nth-child(3n+3) .project-art{ background:#FFFFFF; }
html.page .paper .work-grid.three .project:nth-child(3n+2) .project-art{ background:#E2E8F3; }
html.page .browser-frame, section.p-work .browser-frame{ --text:#FFFFFF; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.55);
  --line:rgba(255,255,255,.12); --line2:rgba(255,255,255,.28); --panel-2:var(--night-3); color:var(--text);
  border-color:rgba(11,17,34,.2); box-shadow:0 16px 36px -8px rgba(11,17,34,.35); }
html.page .spec-pane, html.page .wr-spec{ background:linear-gradient(160deg, var(--night-3), var(--night)); }
html.page .wr-spec{ --text:#FFFFFF; --mut:rgba(255,255,255,.72); --dim:rgba(255,255,255,.55); --line:rgba(255,255,255,.12); color:var(--text); }
html.page .project[href^="ready-"] .project-art{ box-shadow:0 -12px 52px -20px color-mix(in srgb, var(--glow-c, transparent) 60%, transparent), 0 0 0 1px var(--line); }
@media (hover:hover){
  html.page .project[href^="ready-"]:hover .project-art{ box-shadow:0 -18px 68px -16px color-mix(in srgb, var(--glow-c, transparent) 95%, transparent), 0 0 0 1px var(--line2); }
}
html.page .work-row::before{ background:var(--panel-2); }
html.page .paper .work-row::before{ background:#FFFFFF; }
html.page .chip.is-on{ background:var(--night); border-color:var(--night); color:#FFFFFF; }
html.page .chip.is-on .ct{ color:rgba(226,234,255,.7); }

/* the live frame is a window, so its bar keeps a window's light type */
html.page .vf-url{ color:rgba(255,255,255,.62); }
html.page .vf-btn{ color:rgba(255,255,255,.55); }
html.page .vf-btn.is-on{ color:#FFFFFF; border-color:rgba(255,255,255,.28); }
html.page .photo.empty{ background:linear-gradient(160deg, #E2E8F3, #F3F5F9); }

/* the contact card: white, the fields white boxes with a hairline */
html.page .ccard{ background:#FFFFFF; box-shadow:var(--shadow); }
html.page .ccard-tag{ color:var(--cobalt); border-color:rgba(47,91,216,.35); background:rgba(47,91,216,.07); }
html.page .ccard-tag i{ background:var(--cobalt); box-shadow:0 0 0 3px rgba(47,91,216,.16); }
html.page .ccard-form .field input, html.page .ccard-form .field select, html.page .ccard-form .field textarea{
  background-color:#FFFFFF; border-color:var(--line2); color:var(--text); }
html.page .ccard-form .field input:focus, html.page .ccard-form .field select:focus, html.page .ccard-form .field textarea:focus{
  background-color:#FFFFFF; border-color:var(--cobalt); box-shadow:0 0 0 3px rgba(47,91,216,.16); }
html.page .ccard-form .field select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230B1122' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }
html.page .ccard-hint.is-bad{ color:#B42318; }

/* the footer stands on night on every page, so the site closes the same way
   wherever you are in it */
html.page .site-foot{ background:var(--night); color:#FFFFFF; border-top:0;
  --bg:var(--night); --text:#FFFFFF; --mut:rgba(226,234,255,.82); --dim:rgba(226,234,255,.7);
  --act:#FFFFFF; --act-solid:#FFFFFF; --act-2:#DCE6FF; --act-ink:#0B1122; --line:rgba(226,234,255,.12); --line2:rgba(226,234,255,.28);
  --glow:rgba(47,91,216,.3); }
html.page .site-foot .foot-glow{ top:0; }
html.page .site-foot .mark svg, html.page .site-foot .wordmark{ color:#FFFFFF; }

/* ---------- 25 · The legal pages ----------
   Terms and privacy read as documents. A contents list stands beside the
   text on a wide screen and goes above it on a narrow one; sections and
   clauses are numbered so they can be cited, and the number is part of the
   heading's own text in the heading's own face, not a label over it;
   defined terms are bold where they are defined; the measure is about
   seventy characters and the type is near black, because this is the one
   place on the site that is read line by line. */
.page-hero .lg-date{ margin-top:clamp(14px,calc(2 * var(--vhu)),22px); font-family:var(--font-m); font-size:12px; letter-spacing:.12em; text-transform:uppercase; color:var(--dim); }
.legal{ display:grid; grid-template-columns:minmax(200px,250px) minmax(0,72ch); gap:clamp(32px,6vw,112px); align-items:start;
  padding-top:clamp(48px,calc(8 * var(--vhu)),96px); padding-bottom:clamp(72px,calc(12 * var(--vhu)),140px); }
.lg-toc{ position:sticky; top:calc(var(--head) + 28px); max-height:calc(100 * var(--vhu) - var(--head) - 56px); overflow:auto; }
.lg-toc-h{ margin:0 0 10px; font-family:var(--font-m); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }
.lg-toc ol{ list-style:none; margin:0; padding:0; border-left:1px solid var(--line); }
.lg-toc a{ display:grid; grid-template-columns:2.1em 1fr; padding:6px 0 6px 14px; font-size:14px; line-height:1.4; color:var(--mut);
  transition:color var(--t-leave) var(--ease-hover); }
.lg-toc a span{ color:var(--dim); font-variant-numeric:tabular-nums; }
@media (hover:hover){ .lg-toc a:hover{ color:var(--act); transition-duration:var(--t-hover); } }
.lg-body{ min-width:0; font-size:16px; line-height:1.65; color:rgba(11,17,34,.86); }
.lg-body b{ color:var(--text); font-weight:600; }
.lg-body a{ color:var(--act); text-decoration:underline; text-decoration-color:color-mix(in srgb, var(--act) 40%, transparent); text-underline-offset:3px; }
.lg-brief{ margin-bottom:clamp(8px,calc(2 * var(--vhu)),20px); padding:clamp(20px,2.2vw,30px); border:1px solid var(--line); border-radius:14px; background:var(--paper); }
.lg-brief h2{ margin:0 0 12px; font-family:var(--font-d); font-weight:700; font-stretch:104%; font-size:18px; letter-spacing:-.01em; color:var(--text); }
.lg-brief ul{ margin:0; padding-left:1.15em; list-style:disc; display:grid; gap:8px; }
.lg-brief li{ padding-left:.25em; }
.lg-brief li::marker{ color:var(--dim); }
.lg-brief .note{ margin:14px 0 0; font-size:14px; line-height:1.5; color:var(--dim); }
.lg-sec{ scroll-margin-top:calc(var(--head) + 28px); margin-top:clamp(32px,calc(4.5 * var(--vhu)),48px); padding-top:clamp(28px,calc(4 * var(--vhu)),40px); border-top:1px solid var(--line); }
/* one number column for titles and clauses alike, in rem so a title's
   larger type does not push its words out past the clause text below */
.lg-sec h2{ display:grid; grid-template-columns:2.6rem 1fr; margin:0 0 18px; font-family:var(--font-d); font-weight:700; font-stretch:104%;
  font-size:clamp(20px,1.6vw,24px); line-height:1.25; letter-spacing:-.01em; color:var(--text); }
.cl{ display:grid; grid-template-columns:2.6rem 1fr; margin:0 0 14px; }
.cl-n{ padding-top:.12em; font-size:14px; font-variant-numeric:tabular-nums; color:var(--dim); }
.cl-list{ list-style:none; margin:-4px 0 16px 2.6rem; padding:0; display:grid; gap:10px; }
.cl-list li{ display:grid; grid-template-columns:2.2em 1fr; }
.cl-list li > span:first-child{ color:var(--dim); }
@media (max-width:900px){
  .legal{ grid-template-columns:minmax(0,1fr); gap:clamp(28px,5vw,40px); }
  .lg-toc{ position:static; max-height:none; }
}
@media (max-width:640px){
  .lg-sec h2, .cl{ grid-template-columns:2.4rem 1fr; }
  .cl-list{ margin-left:0; }
  .lg-body{ font-size:15.5px; }
}
@media print{
  .lg-toc{ display:none; }
  .legal{ display:block; padding:0; }
  .lg-body{ color:#000; }
  .lg-sec{ break-inside:auto; }
  .lg-sec h2{ break-after:avoid; }
}
