/* EKKO site: the designed pages. Foundation: DESIGN.md. Adopted 2026-10-07 from design-explorations/round-6
   (Sweep, second pass): one grid, one type scale, one spacing rhythm, one list, one plate, one set of buttons.
   Colour is a rounded sheet that slides in over the section before it and sweeps from the words at the left
   to the light at the right; the opening and the close are the two full-width grounds.
   A fully designed page (Home) carries .ek on <body> and loads only this file. A page still being designed
   loads wireframe.css as well and sets .ek on each designed element; class names here therefore never
   reuse a name that wireframe.css styles on its own (mast, btn, brand, lang, hl, ln, row, sm, wrap, grid,
   list, fig, who, quote, foot). */
@font-face{font-family:Archivo;src:url("fonts/archivo-latin.woff2") format("woff2");font-style:normal;font-weight:100 900;font-stretch:62% 125%;font-display:swap}

.ek{
 /* colour: DESIGN.md foundation */
 --paper:#fff;--ink:#0a2540;--ink2:#33475f;--ink3:#5c7089;--cobalt:#1e5eff;--deep:#0f3fcc;--sky:#cfe6ff;--sky2:#eaf3ff;--lime:#d9ff3d;--lime2:#c2ec1a;--rule:rgba(10,37,64,.14);

 /* grid: twelve columns between two gutters. Whatever starts beside something else starts on column 4, 7 or 10 */
 --g:clamp(20px,4.4vw,96px);
 --gap:clamp(12px,1.4vw,28px);
 --si:clamp(8px,calc(var(--g) / 3),32px);   /* a sheet sits this far in from the page edge */
 --sp:calc(var(--g) - var(--si));            /* and is padded by the rest of the gutter, so what is inside it stays on the page's columns */

 /* type: three light sizes for titles, one voice for names, three sizes of text */
 --t-statement:clamp(40px,6.4vw,120px);
 --t-title:clamp(32px,4.4vw,84px);
 --t-heading:clamp(25px,3.2vw,58px);
 --t-name:clamp(19px,1.7vw,29px);
 --t-lead:clamp(17px,1.3vw,22px);
 --t-body:clamp(16px,1.1vw,18px);
 --t-label:clamp(14px,1.05vw,17px);
 --t-small:clamp(13px,.95vw,15px);

 /* space: one distance between sections, one from a head to its object, one from a title to its lead */
 --s-sec:clamp(72px,9vw,176px);
 --s-obj:clamp(36px,4.6vw,88px);
 --s-lead:clamp(18px,1.7vw,30px);
 --s-row:clamp(18px,1.6vw,28px);
 --s-act:clamp(28px,2.6vw,44px);
 --s-lock:clamp(28px,4.5vh,56px);            /* above a head that is locked under the top of the screen */

 /* shape */
 --r-sheet:28px;--r-plate:16px;--r-btn:8px;

 /* the masthead: how high it is, the room from it to a title that sits at the top of a screen, and the two
    together. --mh is the white at the top of the opening field, which lies behind it */
 --nh:clamp(60px,8vh,80px);
 --air:calc(var(--s-lock) * .5);
 --clear:calc(var(--nh) + var(--air));
 --mh:80px;

 /* the sweep: one plain line from ink at the left to light at the right. The last one ends in lime */
 --sweep:linear-gradient(100deg,#0a2540 0%,#0f3fcc 32%,#1e5eff 62%,#cfe6ff 90%,#eaf3ff 100%);
 --sweep-lime:linear-gradient(100deg,#0a2540 0%,#0f3fcc 32%,#1e5eff 58%,#8fb4ff 82%,#d9ff3d 100%);
 --sweep-out:linear-gradient(100deg,#0a2540 0%,#0f3fcc 24%,#1e5eff 46%,#cfe6ff 72%,#eaf3ff 83%,#fff 92%);   /* the sweep on a sheet that is open at the right: 1.3 screens long, sky at the edge of the screen, paper after it */
 --seamless:linear-gradient(180deg,#cfe6ff,#fff);
 --noise:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='260'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='2.4' intercept='-0.7'/><feFuncG type='linear' slope='2.4' intercept='-0.7'/><feFuncB type='linear' slope='2.4' intercept='-0.7'/></feComponentTransfer></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");

 /* lines: hairlines only */
 --rule-list:1px solid var(--rule);

 /* motion: one curve, one length, one step between things that arrive together, one distance to rise */
 --ease:cubic-bezier(.16,1,.3,1);
 --m-in:.9s;
 --m-step:80ms;
 --m-rise:clamp(14px,1.5vw,30px);
}

/* ---- base ---- */
html{-webkit-text-size-adjust:100%}
body.ek{margin:0;background:var(--paper)}
.ek{color:var(--ink);font-family:Archivo,"Helvetica Neue",Arial,sans-serif;font-variation-settings:"wdth" 100;font-feature-settings:"kern","liga","tnum";font-size:var(--t-body);line-height:1.5;-webkit-font-smoothing:antialiased;-webkit-print-color-adjust:exact;print-color-adjust:exact;
 --c-text:var(--ink);--c-text2:var(--ink2);--c-text3:var(--ink3);--c-rule:var(--rule);--c-inv:#fff}
.ek,.ek *,.ek *::before,.ek *::after{box-sizing:border-box}
/* type on colour */
.dark{--c-text:#fff;--c-text2:rgba(255,255,255,.9);--c-text3:rgba(255,255,255,.7);--c-rule:rgba(255,255,255,.3);--c-inv:var(--ink);color:#fff}
.ek a{color:inherit}
.ek h1,.ek h2,.ek p,.ek figure,.ek blockquote{margin:0}
.ek img{display:block;max-width:100%}
.ek :focus-visible{outline:2px solid var(--cobalt);outline-offset:4px}
.ek .dark :focus-visible{outline-color:#fff}
.ek ::selection{background:var(--sky);color:var(--ink)}
.ek .dark ::selection{background:var(--lime);color:var(--ink)}
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

/* ---- type roles ---- */
.statement,.title,.heading{font-weight:300;font-variation-settings:"wdth" 112;letter-spacing:-.015em;text-wrap:balance}
.statement{font-size:var(--t-statement);line-height:.98}
.title{font-size:var(--t-title);line-height:1}
.heading{font-size:var(--t-heading);line-height:1.1;letter-spacing:-.014em}
.name{font-size:var(--t-name);font-weight:500;font-variation-settings:"wdth" 106;letter-spacing:-.02em;line-height:1.15}
.label{font-size:var(--t-label);font-weight:500;font-variation-settings:"wdth" 106;letter-spacing:-.01em;line-height:1.3}
.lead{font-size:var(--t-lead);line-height:1.5;color:var(--c-text2);max-width:52ch;text-wrap:pretty}
.text{font-size:var(--t-body);line-height:1.5;color:var(--c-text2);max-width:52ch}
.small{font-size:var(--t-small);line-height:1.5;color:var(--c-text3)}

/* ---- buttons: a soft rectangle in three heights (masthead, page, the two "plan" moments) ---- */
.button{display:inline-flex;align-items:center;justify-content:center;min-height:52px;padding:0 1.6em;border-radius:var(--r-btn);border:1.5px solid transparent;font-weight:600;font-size:16px;line-height:1.2;text-decoration:none;white-space:nowrap;transition:background-color .18s,color .18s,border-color .18s}
.button:active{transform:translateY(1px)}
.button.ink{background:var(--ink);color:#fff}.button.ink:hover{background:var(--deep)}
.button.lime{background:var(--lime);color:var(--ink)}.button.lime:hover{background:var(--lime2)}
.button.white{background:#fff;color:var(--ink)}.button.white:hover{background:var(--sky2)}
.button.ghost{border-color:currentColor;color:var(--c-text)}.button.ghost:hover{background:var(--c-text);border-color:var(--c-text);color:var(--c-inv)}
.button.compact{min-height:40px;padding:0 1.1em;font-size:13px}
.button.lg{min-height:clamp(56px,4.2vw,64px);padding:0 2em;font-size:clamp(16px,1.2vw,18px)}
/* Menu and Close are real buttons: without this they keep the browser's own grey ground and typeface */
.ek button.button{font-family:inherit;cursor:pointer}
.ek button.button.ghost:not(:hover){background:transparent}

/* ---- masthead: the top margin of the page. A strip of the page's own paper that holds still, in ink, on every
   section (adopted 2026-10-08 from design-explorations/round-7, S Margin). A sheet docks under it instead of
   under the top of the screen, the turn runs in the room below it, and a title that sits at the top of a
   screen sits clear of it (--clear). While something that can be read is passing beneath it a hairline draws
   along its foot, from the left, and leaves to the right when the strip is clear again: .under on <html>,
   kept current by src/lib/masthead.ts; without the script the masthead stands without the hairline.
   On the last ground the strip is that ground (below, "the masthead on the last ground").
   No scroll-padding for the masthead: a view timeline takes it as an inset, and every scroll-driven join on
   the page (the hand-over, the turn, the last ground) would then run short of the screen it is measured against ---- */
@property --btn-bg{syntax:"<color>";inherits:false;initial-value:#0a2540}
@property --btn-fg{syntax:"<color>";inherits:false;initial-value:#fff}
@property --nav-rule{syntax:"<color>";inherits:true;initial-value:rgba(10,37,64,.14)}
@property --nav-focus{syntax:"<color>";inherits:true;initial-value:#1e5eff}
.site-head{position:fixed;left:0;right:0;top:0;z-index:20;display:flex;align-items:center;gap:28px;min-height:var(--nh);padding:calc((var(--nh) - 44px) / 2) var(--g);background:var(--paper)}
.site-head::after{content:"";position:absolute;left:var(--g);right:var(--g);bottom:0;height:1px;background:var(--nav-rule);transform:scaleX(0);transform-origin:100% 50%}
.under .site-head::after{transform:scaleX(1);transform-origin:0 50%}
.site-brand{margin-right:auto;flex-shrink:0;display:block}
/* the links and the action share a wrapper (.site-side), which only counts on a small screen; there a Menu
   button stands in for the links. .head-ground is the last ground once more, behind the masthead */
.site-side{display:contents}
.menu-open,.head-ground{display:none}
/* the action takes its colours, and the hairline and the focus ring theirs, from numbers that turn on the last ground */
.site-head .button.ink{position:relative;isolation:isolate;background:var(--btn-bg);color:var(--btn-fg)}
/* under the pointer a layer fades in over the button's ground (::before, as large as the button with its edge);
   the ground itself does not change. A ground that is read from a number in motion cannot also ease to
   another one: the easing runs between the numbers at rest, ink and deep blue, whatever the ground shows (the
   user, 2026-10-08: on the last ground the button went through several colours before it landed on white) */
.site-head .button.ink::before{content:"";position:absolute;inset:-1.5px;z-index:-1;border-radius:inherit;background:var(--deep);opacity:0;transition:opacity .18s}
.site-head .button.ink:hover::before{opacity:1}
.site-head :focus-visible{outline-color:var(--nav-focus)}
/* the logo is the wordmark alone, one file (assets/logo_ekko_white.svg, drawn in white). It is used as a
   mask over the colour of the text around it, so it is ink in the masthead and white on the last ground. The
   file has air round the letters; the mask is set a little large and centred so the box is the letters
   themselves and the wordmark stands flush on the gutter */
.logo{display:block;width:100px;aspect-ratio:683.52/191.58;background:currentColor;
 -webkit-mask:url("logo_ekko_white.svg") 50.8% 50%/110.88% auto no-repeat;mask:url("logo_ekko_white.svg") 50.8% 50%/110.88% auto no-repeat}
.site-nav{display:flex;gap:26px;font-size:14px}
.site-nav a{text-decoration:none}
/* a link in the masthead or the footer is underlined by a hairline that draws from the left and leaves to the right */
.site-nav a,.site-foot a{position:relative;display:inline-block}
.site-nav a::after,.site-foot a::after{content:"";position:absolute;left:0;right:0;bottom:-4px;height:1px;background:currentColor;transform:scaleX(0);transform-origin:100% 50%}
.site-nav a:hover::after,.site-nav a:focus-visible::after,.site-foot a:hover::after,.site-foot a:focus-visible::after{transform:scaleX(1);transform-origin:0 50%}

/* ---- the menu, where the links do not fit in the masthead: the same four as titles on the paper, under
   hairlines like every list, then the two ways in. A <dialog>, so the browser holds the focus inside it,
   closes it on Escape and gives the focus back ---- */
.ek dialog.menu{position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0 var(--g) 28px;border:0;overflow:auto;flex-direction:column;background:var(--paper);color:var(--ink)}
.ek dialog.menu[open]{display:flex}
.ek dialog.menu::backdrop{background:var(--paper)}
.menu-top{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;min-height:var(--nh)}
.menu-top .logo{width:84px}
.menu-links{display:flex;flex-direction:column;margin-top:var(--s-lead);border-top:var(--rule-list)}
.menu-links a{display:block;padding:var(--s-row) 0;border-bottom:var(--rule-list);text-decoration:none}
.menu-links a:hover{color:var(--cobalt)}
.menu-acts{display:flex;flex-direction:column;gap:12px;margin-top:auto;padding-top:var(--s-act)}
@media (min-width:600px){.menu-acts{flex-direction:row}.menu-acts .button{flex:1 1 0}}

/* ---- hook: the opening field. White under the masthead, darkest at the foot, then a clean cut. How far the
   white falls into the room above the copy is --reach on .sky (1: all the way down to the title) ---- */
#hook{position:relative;isolation:isolate;overflow:hidden;display:flex;flex-direction:column;min-height:100vh;min-height:100dvh;padding:0 0 clamp(64px,15vh,220px);
 background:
  linear-gradient(to bottom,rgba(10,37,64,0) 46%,rgba(10,37,64,.46) 72%,rgba(10,37,64,.9) 92%,#0a2540 100%),
  radial-gradient(42% 40% at 102% 60%,rgba(217,255,61,.78) 0%,rgba(217,255,61,.34) 42%,rgba(217,255,61,0) 74%),
  radial-gradient(44% 40% at 92% 28%,rgba(30,94,255,1) 0%,rgba(30,94,255,0) 68%),
  linear-gradient(168deg,#2f6dff 0%,#1e5eff 34%,#0f3fcc 64%,#0a2540 100%)}
#hook .haze{position:absolute;left:-10%;top:-10%;width:120%;height:120%;max-width:none;object-fit:cover;filter:blur(clamp(48px,4vw,96px)) saturate(1.1);opacity:.4;mix-blend-mode:soft-light;pointer-events:none;z-index:-1}
#hook .sky{flex:1 1 auto;min-height:calc(var(--mh) + 48px + var(--over));margin-bottom:calc(var(--over) * -1);position:relative;z-index:-1;pointer-events:none;
 --top:var(--mh);--over:clamp(32px,7vw,120px);--reach:.74;--rest:calc((100% - var(--over) - var(--top)) * var(--reach));--t:calc(var(--top) + var(--rest));
 background-repeat:no-repeat;
 background-image:
  linear-gradient(to bottom,#fff 0,#fff var(--top),rgba(255,255,255,.76) calc(var(--top) + var(--rest)*.14),rgba(255,255,255,.38) calc(var(--top) + var(--rest)*.36),rgba(255,255,255,.12) calc(var(--top) + var(--rest)*.6),rgba(255,255,255,0) calc(var(--top) + var(--rest)*.84)),
  radial-gradient(48% 100% at 30% 0%,#fff 0%,rgba(255,255,255,.78) 36%,rgba(255,255,255,.3) 68%,rgba(255,255,255,0) 100%),
  radial-gradient(38% 100% at 80% 0%,#fff 0%,rgba(255,255,255,.62) 40%,rgba(255,255,255,0) 100%),
  linear-gradient(to bottom,rgba(207,230,255,.7) 0,rgba(207,230,255,.5) calc(var(--top) + var(--rest)*.3),rgba(207,230,255,.12) var(--t),rgba(207,230,255,0) 100%),
  radial-gradient(48% 50% at 54% 50%,rgba(207,230,255,.8) 0%,rgba(207,230,255,0) 100%);
 background-size:100% 100%,100% calc(var(--t)*1.04),100% calc(var(--t)*.76),100% 100%,100% calc(var(--rest)*1.1);
 background-position:0 0,0 0,0 0,0 0,0 calc(var(--top) - var(--rest)*.1)}
#hook .grain{position:absolute;inset:0;pointer-events:none;opacity:.6;mix-blend-mode:overlay;background-image:var(--noise);z-index:-1}
/* the field through fluted glass: glass.js draws the same field on a canvas and bends it, flute by flute, with
   the flutes on the twelve columns. Screen only; on paper, and wherever the canvas cannot start, the field
   is the one above */
#hook .glass{display:none;position:absolute;inset:0;width:100%;height:100%;z-index:-1;pointer-events:none}
@media screen{
  #hook.glass-on .glass{display:block}
  #hook.glass-on .haze{visibility:hidden}
  #hook.glass-on .sky{background-image:none}
}
#hook .copy{padding-inline:var(--g)}
/* the opening title is a statement like the other two: light, sentence case, the same size */
#hook h1 span{display:block}
/* its first line is lit like selected text: ink on lime, the height of the letters, flush with them at both
   ends. The lime, the ink of the letters it has reached and the white of those it has not are three
   backgrounds (the last two clipped to the letters), so the light can be drawn across the line and each
   letter turns as it is reached. The word digitisation on the AI sheet is lit the same way */
:is(#hook h1,#ai h2) mark{color:transparent;background-color:transparent;
 background-image:linear-gradient(var(--ink),var(--ink)),linear-gradient(#fff,#fff),linear-gradient(var(--lime),var(--lime));
 background-repeat:no-repeat;background-position:0 0,100% 0,0 0;background-size:100% 100%,0% 100%,100% 100%;
 -webkit-background-clip:text,text,padding-box;background-clip:text,text,padding-box}
:is(#hook h1,#ai h2) mark::selection{background:var(--ink);color:var(--lime)}
@media (forced-colors:active){:is(#hook h1,#ai h2) mark{color:inherit;background:none}}
#hook .sub{display:flex;align-items:flex-end;justify-content:space-between;gap:28px 48px;margin-top:var(--s-lead)}
#hook .lead{font-size:var(--t-name);line-height:1.4;color:rgba(255,255,255,.92);max-width:42em;text-wrap:balance}
#hook .button{flex-shrink:0;margin-left:auto}
/* the cue: an arrow to the right of the lead, which says the page goes on below (the user, 2026-10-08: "an arrow
   icon in the hero section so users know they can scroll down", then "on the right of the paragraph text, not
   below" and not to be clicked). A hairline in white, no ground and no ring, a picture and nothing more. It
   stands beside the lead, at the middle of its height; the action keeps the right end of the line. It belongs
   to the copy, so it leaves with it */
.cue{--cue:clamp(36px,3vw,60px);flex:none;align-self:center;display:block;color:#fff}
.cue svg{display:block;height:var(--cue);width:auto;overflow:visible;fill:none;stroke:currentColor;stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}
.cue path{vector-effect:non-scaling-stroke}
@media print{.cue{display:none}}

/* ---- a section on the paper: a title, its lead directly under it, then one object ---- */
.sec{padding:var(--s-sec) var(--g) 0;background:var(--paper)}
.head .title{max-width:18ch}
.head .lead,.head .small{margin-top:var(--s-lead)}
.head .small{max-width:80ch}

/* ---- plates: every picture is one rounded plate. Objects that are not photographs stand on a sky-to-white seamless ---- */
.plate{position:relative;overflow:hidden;margin:0;border-radius:var(--r-plate);background:var(--sky2)}
.plate img{width:100%;height:100%;object-fit:cover}
.seamless{background:var(--seamless);border-radius:var(--r-plate)}

/* recognition: one wide photograph and two tall ones, on columns 1, 7 and 10. The wide one sets the height of all three */
.trio{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));grid-template-rows:auto auto;column-gap:var(--gap)}
.trio figure{margin:0;display:grid;grid-template-rows:subgrid;grid-row:span 2}
.trio figure:nth-child(1){grid-column:1/7}
.trio figure:nth-child(2){grid-column:7/10}
.trio figure:nth-child(3){grid-column:10/13}
.trio .plate img{position:absolute;inset:0}
.trio figure:first-child .plate{aspect-ratio:16/10}
.trio figcaption{margin-top:14px;padding-top:12px;border-top:1px solid var(--c-rule);display:flex;flex-direction:column;gap:4px}
.trio figcaption .small{color:var(--c-text2)}

/* ---- rows: the one list. A name on column 1, its sentence on column 7, a figure flush right ---- */
.rows{list-style:none;margin:0;padding:0;border-top:var(--rule-list)}
.rows li{position:relative;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:baseline;padding:var(--s-row) 0;border-bottom:1px solid var(--c-rule)}
.rows .name{grid-column:1/7}
.rows .text{grid-column:7/11}
.rows .amount{grid-column:11/13;justify-self:end;font-style:normal;font-weight:600;font-size:var(--t-body);font-variant-numeric:tabular-nums;white-space:nowrap}
/* with a figure in front of every row: the thing the row is about, on column 1 (below, "the figures of the rows") */
.rows.objects li{align-items:center}
.rows.objects .glyph{grid-column:1/2}
.rows.objects .name{grid-column:2/7}
.rows.objects .text{grid-column:7/13}
/* in half the page */
.rows.half li{grid-template-columns:repeat(6,minmax(0,1fr))}
.rows.half .name{grid-column:1/4}
.rows.half .text,.rows.half .amount{grid-column:4/7}
.rows.half .amount{justify-self:start;margin-top:6px}

/* the distance from a head to its object, and from an object to its action */
.obj{margin-top:var(--s-obj)}
.act{margin-top:var(--s-act)}

/* ---- sheets: colour as a rounded container, set in from the page edge ---- */
.sheet{position:relative;isolation:isolate;overflow:hidden;border-radius:var(--r-sheet);margin-inline:var(--si);padding:var(--sp)}
.sweep{background:var(--sweep)}
.sheet.dark::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background-image:var(--noise);opacity:.45;mix-blend-mode:overlay}
.slot{display:flex;flex-direction:column;padding:var(--si)}
.slot .sheet{margin:0}
.sheet.full{flex:1 1 auto;min-height:calc(100vh - var(--si)*2);min-height:calc(100dvh - var(--si)*2);display:flex;flex-direction:column;justify-content:center}
/* on a wide screen a sheet docks under the masthead: nothing above it, and the screen less the masthead high */
@media screen and (min-width:861px){
  .slot{padding-top:0}
  .sheet.full{min-height:calc(100vh - var(--nh) - var(--si));min-height:calc(100dvh - var(--nh) - var(--si))}
}

/* the slide-in: the section before a sheet holds still (pinned by its foot, see system.js) while the sheet
   rises over it. Nothing rides along with the sheet: what is behind it stays in view until the sheet
   itself covers it, up to its edge and round its corners */
.stack > .turn,.stack > .rise{position:relative;z-index:1}
.pins .pin-under{position:sticky;top:var(--pin-top,0px)}
/* the sheet after the services list waits: when the foot of the list is on the screen the list holds still for
   a third of a screen of scrolling before the sheet starts to come in (the user, 2026-10-08: the card "appears
   too early"). Only where the list is held; elsewhere it would be an empty stretch of paper */
@media screen and (min-width:861px) and (prefers-reduced-motion:no-preference){
  .pins #in-practice + .rise{margin-top:30vh}
}
#recognition{padding-bottom:var(--s-obj)}
/* on a wide screen recognition is exactly one screen and never scrolls: it stands where it appears until the
   sheet has covered it. Its head sits clear of the masthead like a locked head, the photographs take
   the room that is left (never more than their own 16 to 10), the captions close it. With room to spare the
   whole is centred */
@media screen and (min-width:861px) and (min-height:640px){
  #recognition{display:flex;flex-direction:column;justify-content:center;height:100vh;height:100dvh;padding-block:var(--clear) max(var(--s-lock),var(--si))}
  #recognition .trio{flex:0 1 auto;min-height:0;margin-top:min(var(--s-obj),7vh);grid-template-rows:minmax(120px,calc((50vw - var(--g) - var(--gap) / 2) * .625)) auto}
  #recognition .trio figure:first-child .plate{aspect-ratio:auto}
}
#reassurance .statement{max-width:13ch}
#reassurance .lead{margin-top:var(--s-lead)}

/* how: the title at the top, four tall columns under a line, on columns 1, 4, 7 and 10 */
#how{display:flex;flex-direction:column;padding-bottom:var(--s-obj)}
.strip{list-style:none;margin:var(--s-obj) 0 0;padding:0;position:relative;flex:1 1 auto;min-height:clamp(180px,30vh,340px);display:grid;grid-template-columns:repeat(4,minmax(0,1fr));column-gap:var(--gap);border-top:1px solid var(--c-rule)}
.strip::before{content:"";position:absolute;left:0;right:0;top:-2px;height:3px;background:var(--cobalt);transform-origin:0 50%}
.strip li{position:relative;padding-top:20px;display:flex;flex-direction:column;align-items:flex-start}
.strip .text{margin-block:10px 28px;padding-right:var(--gap)}
.strip li+li::after{content:"";position:absolute;left:calc(var(--gap) / -2);top:0;bottom:0;border-left:1px solid var(--c-rule)}
/* the figures of the steps (round 13, Dots; src/components/home/step-figure.tsx): on the foot of each column,
   the same twenty-five points four times. Scattered, set on a grid, joined into the lines of an outline, and a
   part of that outline selected, lime behind ink. --fig is the side of the square the points take: 220, less
   where the screen is not high or the column not wide enough for that (a step has to fit the one screen of the turn). A line of the outline is as thick as a
   point is wide and has round ends; it is one dash, so it can be drawn from its first point to its last */
#how{--fig:min(220px,24vh)}
.points{flex:none;width:var(--fig);max-width:100%;height:auto;aspect-ratio:1;margin:auto 0 calc(var(--fig) / 10);overflow:visible}
/* what follows draws both these figures and the figures of the rows (.glyph, below): one hand */
:is(.points,.glyph) :is(circle,rect){transform-box:fill-box;transform-origin:50% 50%}
:is(.points,.glyph) .go-sel{transform-origin:0 50%}
:is(.points,.glyph) path{fill:none;stroke-width:4.8;stroke-linecap:round;stroke-dasharray:1 2}
:is(.points,.glyph) .f-ink{fill:var(--ink)}:is(.points,.glyph) .f-cob{fill:var(--cobalt)}:is(.points,.glyph) .f-mid{fill:#8fb4ff}:is(.points,.glyph) .f-lime{fill:var(--lime)}
:is(.points,.glyph) .s-ink{stroke:var(--ink)}:is(.points,.glyph) .s-cob{stroke:var(--cobalt)}
/* the figures of the rows (round 14, Outline; src/components/home/row-figure.tsx): in front of each row of "in
   practice", the thing the row is about. A sheet in a scanner, binders on a shelf, a pencil and its line, three
   steps, a camera: drawn with the line and the points above, one part of each lime behind ink. --glyph is the
   side of its square: 48, on the paper, with no plate. A line here may turn a corner, and the lime behind a
   line that stands up comes in from its foot */
.rows.objects{--glyph:48px}
.glyph{display:block;flex:none;width:var(--glyph,48px);height:auto;aspect-ratio:1;overflow:visible}
.glyph path{stroke-linejoin:round}
.glyph .go-up{transform-origin:50% 100%}

/* the turn: the first sheet is open at the right. It has its rounded edge at the left and runs out of the
   screen at the right, and from it the page travels right into "how", which starts --travel of a screen
   further on, not a whole screen. As the page travels the sweep slides left ahead of it, so its light end
   comes in from the right and turns to paper, and "how" stands on that paper; the sheet's words fade as
   they go. Then the page holds while the four steps arrive under the growing line, and scrolls down again.
   The sheet lies under the whole band (colour where the sweep is, paper after it) and nothing is laid behind
   it: above, below and left of it the section before stays in view, up to its edge and round its corners,
   and once the sheet has docked that section has only its own margins to show there.
   All of it runs in the room below the masthead: the track holds under it, and the timeline is measured from
   its foot (the inset), not from the top of the screen */
@supports (animation-timeline:view()){
@media screen and (min-width:861px) and (prefers-reduced-motion:no-preference){
  .turn{height:360vh;view-timeline-name:--turn;view-timeline-axis:block;view-timeline-inset:var(--nh) 0px}
  .turn-track{position:sticky;top:var(--nh);height:calc(100vh - var(--nh));height:calc(100dvh - var(--nh));overflow:hidden;--travel:.6}
  .turn-band{display:flex;width:calc(100% * (1 + var(--travel)));height:100%;will-change:transform;animation:turn-pan linear both;animation-timeline:--turn;animation-range:contain 9% contain 33%}
  .turn-band > *{min-width:0;height:100%}
  .turn .slot{flex:0 0 100%;padding-right:0}
  .turn .sheet.full{min-height:0;border-radius:var(--r-sheet) 0 0 var(--r-sheet);background:var(--paper)}
  .turn .sheet.full::before{content:"";position:absolute;left:0;top:0;bottom:0;z-index:-2;width:calc(130% / (1 + var(--travel)));background:var(--sweep-out);will-change:transform;animation:turn-sweep linear both;animation-timeline:--turn;animation-range:contain 9% contain 33%}
  .turn .sheet.full > *{animation:turn-out linear both;animation-timeline:--turn;animation-range:contain 9% contain 21%}
  #how{flex:0 0 calc(100% / (1 + var(--travel)));margin-left:calc(-100% / (1 + var(--travel)));position:relative;z-index:1;background:none;padding-block:var(--air) clamp(28px,4vh,56px)}
  /* the line of the steps waits, like the rest of "how", until the page has all but arrived */
  .turn .strip{margin-top:clamp(28px,4vh,56px);animation:turn-in linear both;animation-timeline:--turn;animation-range:contain 27% contain 36%}
  .strip::before{animation:turn-line linear both;animation-timeline:--turn;animation-range:contain 38.5% contain 89%}
  .strip li{animation:turn-step linear both;animation-timeline:--turn}
  .strip li:nth-child(1){animation-range:contain 38.5% contain 46.5%;--t:39%}
  .strip li:nth-child(2){animation-range:contain 51% contain 59%;--t:53.5%}
  .strip li:nth-child(3){animation-range:contain 64% contain 72%;--t:66.5%}
  .strip li:nth-child(4){animation-range:contain 76.5% contain 84.5%;--t:79%}
  /* the figures follow the scroll too. Each starts as the one before it ended and moves into its own order, a
     little after its step starts to arrive (--t, a share of the turn; --d is a part's place in the stagger):
     the points come in from around and settle where they fall; each goes from there to its place on the grid,
     column by column; the grid joins into the lines of the outline, row by row, and the points left over step
     back; the lime is drawn across the selected lines from the first point to the last, as on the opening
     title. Whatever is added to a figure moves only if its class starts with go- */
  .points [class*="go-"]{animation:linear both;animation-timeline:--turn;animation-range:contain calc(var(--t) + var(--d,0) * .8%) contain calc(var(--t) + var(--d,0) * .8% + 5%)}
  .points .go-in{animation-name:points-in}
  .points .go-set{animation-name:points-set}
  .points .go-tint{animation-name:points-tint}
  .points .go-rest{animation-name:points-rest}
  .points .go-draw{animation-name:points-draw}
  .points .go-sel{animation-name:points-sel}
  .points .go-cob{animation-name:points-cob}
  .points .go-ink{animation-name:points-ink}
  .points .go-inkf{animation-name:points-inkf}
  /* the head of "how" comes up as the paper reaches it */
  #how .head > *{animation:turn-in linear both;animation-timeline:--turn;animation-range:contain 20% contain 33%}
  #how .head > .lead{animation-range:contain 23% contain 36%}
  #how .head > .arrive{transform:none}
}}
@keyframes turn-in{from{opacity:0}to{opacity:1}}
@keyframes turn-out{to{color:rgba(255,255,255,0)}}
@keyframes turn-pan{to{transform:translateX(calc(-100% * var(--travel) / (1 + var(--travel))))}}
@keyframes turn-sweep{to{transform:translateX(calc(-100% * (1.32 - var(--travel)) / 1.3))}}
@keyframes turn-line{from{transform:scaleX(0)}}
@keyframes turn-step{from{opacity:0;transform:translateY(20px)}}
@keyframes points-in{from{opacity:0;transform:translate(var(--ox),var(--oy)) scale(.4)}}
@keyframes points-set{from{transform:translate(var(--dx),var(--dy)) scale(var(--s));fill:var(--ink)}}
@keyframes points-tint{from{fill:var(--cobalt)}}
@keyframes points-rest{from{transform:scale(1.714);fill:var(--cobalt)}}
@keyframes points-draw{from{stroke-dashoffset:1;opacity:0}12%{opacity:1}}
@keyframes points-sel{from{transform:scaleX(0)}}
@keyframes points-cob{from{stroke:var(--ink)}}
@keyframes points-ink{from{stroke:var(--cobalt)}}
@keyframes points-inkf{from{fill:#8fb4ff}}

/* ---- the AI sheet (the user chose Sheet from design-explorations/round-12, 2026-10-08, and the line "AI starts
   with digitisation."): what the four steps lead to. A sheet like the first, closed, the line and its lead on
   the ink end of the sweep. The word digitisation is lit like the first line of the opening title, and the
   light is drawn across it once the line has come up.
   It slides in over "how": the turn holds for one screen more (less the masthead) and the sheet is drawn up
   over that last screen, so the four steps and their figures hold still while it rises, and are let go when
   it has docked under the masthead. Nothing is laid behind it: the steps stay in view up to its edge and
   round its corners.
   The turn must not run differently for being taller. So its clock is taken off it: an element inside it
   (.turn-clock, src/components/home/turn.tsx), as tall as the turn was (360vh), carries the timeline --turn,
   and the turn only passes the name on (timeline-scope). Every range of the turn above, the figures' included,
   therefore falls where it fell, and nothing above is rewritten: the three rules that change (.turn, #how and
   the clock) stand here, after the turn's own. Where a browser has scroll timelines but cannot pass a name on,
   the turn runs as it did and the sheet simply follows it ---- */
#ai .statement{max-width:13ch}
#ai .lead{margin-top:var(--s-lead)}
.turn-clock{display:none}
@supports (animation-timeline:view()) and (timeline-scope:--turn){
@media screen and (min-width:861px) and (prefers-reduced-motion:no-preference){
  .turn{height:calc(360vh + 100vh - var(--nh));height:calc(360vh + 100dvh - var(--nh));view-timeline-name:none;timeline-scope:--turn}
  .turn-clock{display:block;position:absolute;left:0;top:0;width:1px;height:360vh;visibility:hidden;pointer-events:none;view-timeline-name:--turn;view-timeline-axis:block;view-timeline-inset:var(--nh) 0px}
  .slot.covers{position:relative;z-index:2;margin-top:calc(var(--nh) - 100vh);margin-top:calc(var(--nh) - 100dvh)}
  /* the foot of "how" stays inside the sheet's own margin, so no hairline of the steps shows under the sheet */
  #how{padding-bottom:max(clamp(28px,4vh,56px),var(--si))}
}}
@media screen and (prefers-reduced-motion:no-preference){
  /* arriving: the light is drawn across the word after the line has risen, from its first letter to its last,
     each letter turning from white to ink as it is reached */
  #ai .statement.arrive mark{background-size:0% 100%,100% 100%,0% 100%}
  #ai .statement.arrive.in mark{background-size:100% 100%,0% 100%,100% 100%;transition:background-size .8s cubic-bezier(.4,0,.2,1) calc(var(--d,0s) + .5s)}
}

/* ---- in practice: the head locks under the masthead while the list runs beneath it; when the last
   row is in view the section holds still for the sheet that slides in over it. The head's foot is the list's top rule.
   The head locks at the top of the screen, behind the masthead, and keeps its title clear of it (--clear) ---- */
.lock{padding-bottom:var(--s-obj)}
.lock .head{padding-bottom:var(--s-obj);border-bottom:var(--rule-list);background:var(--paper)}
.lock .rows{border-top:0}
@media (min-width:861px) and (min-height:640px){
  .lock{padding-top:max(0px,calc(var(--s-sec) - var(--clear)))}
  .lock .head{position:sticky;top:0;z-index:2;padding-top:var(--clear)}
}
/* the list on a screen that is not high. The locked head keeps its place, so on a low screen it left the list
   little room and the rows stood large in it (the user, 2026-10-08, of a screen about 1000 high: the list items
   "too big", "make them proportionally smaller", and less room between the lead and the list). Here the rows
   are measured against the height of the screen as well as its width: the room in a row, the name, the
   sentence and the figure are what they are elsewhere from about 1300 high, and smaller in proportion below
   that. The room under the lead is 5% of the height, less than it was at every size. Wide screens only: on a
   small one the rows are already at their smallest */
@media (min-width:861px){
  #in-practice{--s-row:clamp(14px,min(1.6vw,2.15vh),28px);--t-name:clamp(19px,min(1.7vw,2.25vh),29px);--t-body:clamp(15px,min(1.1vw,1.4vh),18px)}
  #in-practice .rows.objects{--glyph:clamp(32px,3.7vh,48px)}
  #in-practice .head{padding-bottom:max(24px,min(var(--s-obj),5vh))}
}

/* ---- proof: a sheet like the first. The quote on columns 1 to 3, a narrow measure of many short lines, so
   it stays left of the tablet. The Kiekens picture is a cut-out with no
   ground of its own: it stands on the sweep, as high as the sheet and against its right edge, so the figure
   runs out of the sheet at the top, the right and the foot. The grain is on the sweep only: in this sheet it
   lies one layer lower, under the picture ---- */
.proof.sheet{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:center;align-content:center}
.proof .words{grid-column:1/4;display:flex;flex-direction:column;align-items:flex-start;min-width:0}
.proof blockquote{max-width:20em;line-height:1.16;text-wrap:pretty;hanging-punctuation:first}
/* the Kiekens logo opens the column. Its file has empty room above and below the drawing (18% and 20% of its
   height), taken off here so the distances are measured from the drawing itself */
.proof .client{--w:clamp(120px,11vw,200px);width:var(--w);height:auto;margin:calc(var(--w) * -.052) 0 calc(var(--s-act) - var(--w) * .057)}
/* who says it: the portrait, a small plate with the button's corners, and the name over the role beside it */
.proof .by{display:flex;align-items:center;gap:clamp(12px,1vw,16px);margin-top:var(--s-lead);color:var(--c-text2)}
.proof .by b{display:block;color:var(--c-text);font-weight:600}
.proof .face{flex:none;width:clamp(44px,3.9vw,64px);height:auto;aspect-ratio:1;border-radius:var(--r-btn);object-fit:cover}
.proof .button{margin-top:var(--s-act)}
.proof.sheet::after{z-index:-2}
.proof .shot{position:absolute;inset:0;z-index:-1;pointer-events:none}
.proof .shot img{position:absolute;top:0;right:0;width:auto;max-width:none;height:100%}

/* ---- library: the head and three facts on columns 1 to 6, the tablet in front of the one lime plate on 7 to 12.
   The tablet is a front-on picture set at an angle (adopted 2026-10-08 from design-explorations/round-10, with
   the values the user set there): the top and the right side lean away, the whole is turned anticlockwise, and
   it throws a shadow on the plate and the paper. With the pointer on the figure it turns a little about that
   angle, giving way under the pointer, and a light lies on its glass where the pointer is: src/lib/tilt.ts
   writes --mx, --my, --gx and --gy on the figure and marks it .over, the rules here do the rest. Without the
   script it stands at its angle. Its lengths are measured in the width of the figure (cqw), so it is the same
   object at every size ---- */
.duo{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:start}
.duo .side{grid-column:1/7;min-width:0}
.tab{grid-column:7/13;justify-self:end;width:100%;max-width:1118px;position:relative;margin:0;container-type:inline-size;display:flow-root;
 --tilt-x:10deg;--tilt-y:14deg;--tilt-z:-18deg;   /* at rest: the top leans away, the right side leans away, the whole turns anticlockwise */
 --tilt-far:2.7;                                    /* seen from this many figure widths away: the nearer, the stronger the perspective */
 --tilt-limit:10;--tilt-ease:.3s;                   /* the pointer: degrees either way, and how soon the tablet follows */
 --tilt-shadow:.8;--tilt-glare:.3;                  /* the shadow, and the light on the glass */
 --tilt-r:5.21%/6.83%}                              /* the corner of the tablet in the picture */
.tab::before{content:"";position:absolute;left:40%;right:0;top:0;bottom:0;border-radius:var(--r-plate);background:linear-gradient(100deg,var(--lime2),var(--lime))}
/* the room the tablet turns in: it stands a little left of the middle, across the plate's left edge, and its
   far corner comes up to just under the top of the plate. The pointer is read on the figure, which holds
   still, not on the tablet, which moves */
.tab .stand{position:relative;margin:13% 13% 20% 9%;pointer-events:none}
/* the object (the picture, and the glass on it) and the outline that is its shadow, at one angle */
.tab .slab{position:relative;outline:1px solid transparent}
.tab :is(.slab,.cast i){
 transform:perspective(calc(var(--tilt-far) * 100cqw))
  rotateX(calc(var(--tilt-x) * var(--pose,1) + var(--mx,0deg)))
  rotateY(calc(var(--tilt-y) * var(--pose,1) + var(--my,0deg)))
  rotateZ(calc(var(--tilt-z) * var(--pose,1)));
 transition:transform .9s var(--ease)}
.tab.over :is(.slab,.cast i){transition:transform var(--tilt-ease) ease-out}
.tab img{width:100%;height:auto}
/* its glass. At rest the far corner is a shade darker. With the pointer on the figure a light lies where the
   pointer is and the glass darkens away from it: on a bright screen it is the darkening that shows the light */
.tab .sheen{position:absolute;inset:0;border-radius:var(--tilt-r);
 background:linear-gradient(to top right,rgba(10,37,64,0) 40%,rgba(10,37,64,calc(var(--tilt-glare) * .18)))}
.tab .sheen::after{content:"";position:absolute;inset:0;border-radius:inherit;opacity:0;transition:opacity .3s;
 background:
  radial-gradient(circle 98cqw at calc(var(--gx,.5) * 100%) calc(var(--gy,.5) * 100%),rgba(255,255,255,var(--tilt-glare)) 0%,rgba(255,255,255,0) 40%),
  radial-gradient(circle 98cqw at calc(var(--gx,.5) * 100%) calc(var(--gy,.5) * 100%),rgba(10,37,64,0) 24%,rgba(10,37,64,calc(var(--tilt-glare) * .22)) 62%)}
.tab.over .sheen::after{opacity:1}
/* its shadow: the outline of the tablet in ink, out of focus, a little lower; with the pointer on the figure
   it falls a little further off. The one shadow of the page */
.tab .cast{position:absolute;inset:0;translate:1.5% 9%;filter:blur(3cqw);opacity:var(--tilt-shadow);transition:translate .9s var(--ease)}
.tab .cast i{position:absolute;inset:0;border-radius:var(--tilt-r);background:rgba(10,37,64,.55);scale:.95}
.tab.over .cast{translate:2.5% 12%;transition:translate var(--tilt-ease) ease-out}

/* ---- the close and the footer share one ground: the sweep, ending in lime, held to the screen. It has no
   upper edge: it fades in as the page reaches the close, and a veil of ink rises under the footer ---- */
.close{padding-inline:var(--g)}
.close .statement{max-width:16ch}
.close .lead{margin-top:var(--s-lead)}
.acts{display:flex;flex-wrap:wrap;gap:12px;margin-top:var(--s-act)}
.acts .button{min-width:240px}
/* the footer (adopted 2026-10-08 from design-explorations/round-8, X Index): the four pages in the list every
   section uses, a large name on column 1 and a sentence on column 7, the contact details being the sentence of
   Contact; then one line of small print on columns 1, 4, 7 and 10. A page's name is lit like selected text
   while the pointer or the focus is on it, the way the first line of the opening title is: lime drawn from
   its first letter to its last, each letter turning to ink as it is reached (three backgrounds, two of them
   clipped to the letters). It stands on the last ground (Home) or on the paper (a page besides Home) */
.site-foot{padding:0 var(--g) 44px;font-size:var(--t-label);line-height:1.5}
.site-foot a{text-decoration:none}
.site-foot a::after{bottom:-2px}
.site-foot .rows{border-top-color:var(--c-rule)}
.site-foot .rows li{padding-block:clamp(16px,1.5vw,28px)}
.site-foot .rows li > a{grid-column:1/7;justify-self:start;color:transparent;
 background-image:linear-gradient(var(--ink),var(--ink)),linear-gradient(var(--c-text),var(--c-text)),linear-gradient(var(--lime),var(--lime));
 background-repeat:no-repeat;background-position:0 0,100% 0,0 0;background-size:0% 100%,100% 100%,0% 100%;
 -webkit-background-clip:text,text,padding-box;background-clip:text,text,padding-box}
.site-foot .rows li > a:is(:hover,:focus-visible){background-size:100% 100%,0% 100%,100% 100%}
.site-foot .rows li > a::after{content:none}
.site-foot .rows li > a::selection{background:var(--ink);color:var(--lime)}
@media (forced-colors:active){.site-foot .rows li > a{color:inherit;background:none}}
.site-foot .rows .text{grid-column:7/13}
/* a link inside a sentence is underlined where it stands, and the line firms up under the pointer */
.site-foot .text a{display:inline;color:var(--c-text);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.22em;text-decoration-color:var(--c-text3)}
.site-foot .text a:is(:hover,:focus-visible){text-decoration-color:currentColor}
.site-foot .text a::after{content:none}
/* the last line: the wordmark, the notice with Privacy beside it, the line that sums EKKO up, the credential */
.site-foot .legal{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:end;margin-top:var(--s-act);font-size:var(--t-small);color:var(--c-text3)}
.site-foot .legal > *{grid-column:span 3}
.site-foot .home{display:block;width:max-content;color:var(--c-text)}
.site-foot .home::after{content:none}
.site-foot .notice{display:flex;flex-wrap:wrap;gap:.2em 1.4em}
/* the footer as a sheet of paper (round 8, Z Sheet), kept for a page that ends on colour and wants it:
   <SiteFooter variant="sheet" />. A sheet like the others, of paper, with type in ink; no ink rises under it
   and the ground stays open round it. The line that sums EKKO up is its heading, the pages and the contact
   details stand on columns 7 and 10, and its last line (.cols) hangs from a hairline */
.site-foot.paper{padding:0 0 var(--si)}
.site-foot.paper .sheet{padding-block:var(--s-obj) clamp(24px,2.4vw,40px);background:var(--paper);color:var(--ink);
 --c-text:var(--ink);--c-text2:var(--ink2);--c-text3:var(--ink3);--c-rule:var(--rule);--c-inv:#fff}
.ek .dark .site-foot.paper :focus-visible{outline-color:var(--cobalt)}
.site-foot .top{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:start}
.site-foot .top > *{grid-column:span 3}
.site-foot .top > .heading{grid-column:1/7}
.site-foot .top .heading span{display:block}
.site-foot .links{display:flex;flex-direction:column;align-items:flex-start;gap:.5em}
.site-foot .cols{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:end;margin-top:var(--s-obj);padding-top:20px;border-top:1px solid var(--c-rule);font-size:var(--t-small);color:var(--c-text3)}
.site-foot .cols > *{grid-column:span 3}
.site-foot .cols > :first-child{grid-column:1/7}
.ends{position:relative;margin-top:var(--s-sec)}
/* the ink under the footer: all but solid where the footer's first line stands, rising from nothing --rise
   above it, solid a little below. It is measured from the footer, so it is the same under a footer of any
   height. A footer of paper has none */
.ends .site-foot:not(.paper){position:relative;--rise:clamp(280px,56vh,640px)}
.ends .site-foot:not(.paper)::before{content:"";position:absolute;z-index:-1;left:0;right:0;bottom:0;top:calc(var(--rise) * -1);pointer-events:none;
 background:linear-gradient(to bottom,rgba(10,37,64,0) 0,rgba(10,37,64,.62) calc(var(--rise) * .6),rgba(10,37,64,.95) var(--rise),#0a2540 calc(var(--rise) + 120px))}
.ends .ground{position:absolute;inset:0;z-index:-1;pointer-events:none;background:var(--sweep-lime)}
.ends .ground::after{content:"";position:absolute;inset:0;background-image:var(--noise);opacity:.45;mix-blend-mode:overlay}
.ends .close{padding-top:clamp(120px,24vh,340px)}
.ends .site-foot{margin-top:clamp(96px,18vh,240px)}
@supports (animation-timeline:view()){
@media screen and (prefers-reduced-motion:no-preference){
  /* the white before the close is where the ground comes up, so the price list is out of the way by then */
  #investment{background:none;padding-bottom:38vh}
  .ends{margin-top:0;view-timeline-name:--ends;view-timeline-axis:block}
  .ends .ground{position:fixed;animation:ends-in linear both;animation-timeline:--ends;animation-range:entry 18% entry 70%}
}}
@keyframes ends-in{from{opacity:0}}

/* ---- motion: what moves besides the joins above, all of it on one curve.
   The opening plays once when the page loads.
   Arriving: as a thing comes up into the screen its hairline draws from the left and its words rise into
   place, one after the other. Once: the script (site.js) only says when, by setting .arrive on what is still
   below the screen and .in when it comes up, and takes both away again when it has landed.
   Travelling: a photograph settles as it comes in, the tablet drifts in front of its plate and the opening
   copy fades as it leaves. These follow the scroll.
   None of it in print, with reduced motion, or without the script ---- */
@media screen and (prefers-reduced-motion:no-preference){
  .site-nav a::after,.site-foot a::after{transition:transform .4s var(--ease)}
  .site-foot .rows li > a{transition:background-size .5s var(--ease)}
  .site-foot .text a{transition:text-decoration-color .18s}
  .site-head::after{transition:transform .5s var(--ease)}

  /* the menu opens out of the paper: its links rise a step apart, then the two ways in */
  .ek dialog.menu[open]{animation:m-fade .3s var(--ease)}
  .ek dialog.menu[open] :is(.menu-links a,.menu-acts){animation:m-rise var(--m-in) var(--ease) backwards}
  .ek dialog.menu[open] .menu-links a:nth-child(2){animation-delay:var(--m-step)}
  .ek dialog.menu[open] .menu-links a:nth-child(3){animation-delay:calc(var(--m-step) * 2)}
  .ek dialog.menu[open] .menu-links a:nth-child(4){animation-delay:calc(var(--m-step) * 3)}
  .ek dialog.menu[open] .menu-acts{animation-delay:calc(var(--m-step) * 4)}

  /* the opening: the masthead comes up with the page, and stays. The field comes up out of the white page,
     then the title a line at a time, its lead and the action; last, the light is drawn across the first
     line, from its first letter to its last */
  .site-head{animation:m-fade var(--m-in) var(--ease) backwards}
  #hook::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:#fff;animation:m-veil 1.2s cubic-bezier(.4,0,.2,1) both}
  #hook h1 span,#hook .lead,#hook .button{animation:m-rise var(--m-in) var(--ease) .25s backwards}
  #hook h1 span+span{animation-delay:calc(.25s + var(--m-step))}
  #hook .lead{animation-delay:calc(.25s + var(--m-step) * 3)}
  #hook .button{animation-delay:calc(.25s + var(--m-step) * 4)}
  /* the cue comes last, and then dips now and then */
  #hook .cue{animation:m-rise var(--m-in) var(--ease) calc(.25s + var(--m-step) * 5) backwards}
  #hook .cue svg{animation:cue-dip 3.2s ease-in-out 2.4s infinite}
  #hook h1 mark{animation:m-light .8s cubic-bezier(.4,0,.2,1) .95s backwards}

  /* arriving: words and pictures rise into place */
  .arrive{opacity:0;transform:translateY(var(--m-rise))}
  .arrive.in{opacity:1;transform:none;transition:opacity var(--m-in) var(--ease) var(--d,0s),transform var(--m-in) var(--ease) var(--d,0s)}

  /* a thing that hangs from a hairline (a row, a caption, the footer): the line draws, then what hangs from it arrives */
  :is(.rows li,.trio figcaption,.site-foot .cols,.tab).arrive{opacity:1;transform:none;transition:none}
  .rows li.arrive{border-bottom-color:transparent}
  .rows:has(> li.arrive:first-child),:is(.trio figcaption,.site-foot .cols).arrive{border-top-color:transparent}
  :is(.trio figcaption,.site-foot .cols).arrive{position:relative}
  .rows li.arrive::after,:is(.rows li:first-child,.trio figcaption,.site-foot .cols).arrive::before{content:"";position:absolute;left:0;right:0;height:1px;background:var(--c-rule);transform:scaleX(0);transform-origin:0 50%}
  .rows li.arrive::after{bottom:-1px}
  :is(.rows li:first-child,.trio figcaption,.site-foot .cols).arrive::before{top:-1px}
  .lock .rows li.arrive::before{content:none}
  .rows li.arrive.in::after,:is(.rows li:first-child,.trio figcaption,.site-foot .cols).arrive.in::before{transform:scaleX(1);transition:transform 1.2s var(--ease) var(--d,0s)}
  :is(.rows li,.trio figcaption,.site-foot .cols).arrive > *{opacity:0;transform:translateY(calc(var(--m-rise) / 2))}
  :is(.rows li,.trio figcaption,.site-foot .cols).arrive.in > *{opacity:1;transform:none;transition:opacity var(--m-in) var(--ease),transform var(--m-in) var(--ease);transition-delay:calc(var(--d,0s) + var(--m-step))}
  :is(.rows li,.trio figcaption,.site-foot .cols).arrive.in > :nth-child(2){transition-delay:calc(var(--d,0s) + var(--m-step) * 2)}
  :is(.rows li,.trio figcaption,.site-foot .cols).arrive.in > :nth-child(3){transition-delay:calc(var(--d,0s) + var(--m-step) * 3)}
  :is(.rows li,.trio figcaption,.site-foot .cols).arrive.in > :nth-child(4){transition-delay:calc(var(--d,0s) + var(--m-step) * 4)}
  /* the figure of a row is drawn as the row arrives: its lines from their first point to their last, its points
     appearing, the lime last. --i is a part's place in the stagger, --d the wait of its row. All of it is over
     well before the marks are taken away again (src/lib/motion.ts, 2.4 seconds), so nothing jumps then */
  .rows li.arrive .glyph [class*="go-"]{--w:calc(var(--d,0s) + 180ms + var(--i,0) * 45ms)}
  .rows li.arrive:not(.in) .glyph .go-draw{opacity:0;stroke-dashoffset:1}
  .rows li.arrive.in .glyph .go-draw{transition:opacity .12s linear var(--w),stroke-dashoffset .9s var(--ease) var(--w)}
  .rows li.arrive:not(.in) .glyph .go-pop{transform:scale(0)}
  .rows li.arrive.in .glyph .go-pop{transition:transform .6s var(--ease) var(--w)}
  .rows li.arrive:not(.in) .glyph .go-sel{transform:scaleX(0)}
  .rows li.arrive:not(.in) .glyph .go-up{transform:scaleY(0)}
  .rows li.arrive.in .glyph :is(.go-sel,.go-up){transition:transform .7s cubic-bezier(.4,0,.2,1) var(--w)}

  /* the tablet: the lime plate comes up, then the tablet rises in front of it and turns the last of the way
     into its angle */
  .tab.arrive::before{opacity:0}
  .tab.arrive .stand{opacity:0;transform:translateY(calc(var(--m-rise) * 2))}
  .tab.arrive :is(.slab,.cast i){--pose:.45;transition:none}
  .tab.arrive.in::before{opacity:1;transition:opacity var(--m-in) var(--ease) var(--d,0s)}
  .tab.arrive.in .stand{opacity:1;transform:none;transition:opacity var(--m-in) var(--ease),transform 1.2s var(--ease);transition-delay:calc(var(--d,0s) + var(--m-step) * 2)}
  .tab.arrive.in :is(.slab,.cast i){--pose:1;transition:transform 1.6s var(--ease) calc(var(--d,0s) + var(--m-step) * 2)}
}
@supports (animation-timeline:view()){
@media screen and (prefers-reduced-motion:no-preference){
  /* travelling */
  #hook{view-timeline-name:--hook;view-timeline-axis:block}
  #hook .copy{animation:m-leave linear both;animation-timeline:--hook;animation-range:exit 30% exit 78%}
  .trio .plate{view-timeline-name:--plate;view-timeline-axis:block}
  .trio .plate img{animation:m-settle linear both;animation-timeline:--plate;animation-range:entry 0% entry 100%}
  .tab .stand{animation:m-drift linear both;animation-timeline:view();animation-range:cover 0% cover 100%}
}}
@keyframes m-fade{from{opacity:0}}
@keyframes m-veil{from{opacity:1}to{opacity:0}}
@keyframes cue-dip{0%,55%,100%{transform:none}75%{transform:translateY(8px)}}
@keyframes m-rise{from{opacity:0;transform:translateY(var(--m-rise))}}
@keyframes m-light{from{background-size:0% 100%,100% 100%,0% 100%}}
@keyframes m-leave{to{opacity:0;transform:translateY(-6vh)}}
@keyframes m-settle{from{scale:1.12}}
@keyframes m-drift{from{translate:0 5%}to{translate:0 -5%}}

/* ---- the hand-over: the opening does not scroll away, it changes into the section after it. For the first
   screen's worth of scrolling nothing travels: the opening copy fades, lifting a
   little, the white of the field comes down over the whole of it while its colours sink and pale before it
   (--pull, 0 to 1, which glass.js draws), and recognition comes up where it stands, a piece at a time, each
   from a little lower. It then rests a moment, and the sheet slides in over it. Where the white has come
   down the field is cut away (it is paper there, so nothing shows), and the section under it comes up
   through it; --front is how far the solid white has come, the same line glass.js draws. Without the glass
   the field fades to the paper instead. The masthead holds still above all of it.
   Nothing is laid out differently: the opening and the page under it are each held still by
   moving them against the scroll, on the timeline of the opening leaving (--hook, which the page under it
   can see because body shares it: timeline-scope, set with the masthead's own below). Once the opening
   has faded it is let go, above the screen, so it is not in the way of the section under it and
   the glass stops drawing.
   Wide, tall enough screens only; elsewhere the opening scrolls away as before ---- */
@property --pull{syntax:"<number>";inherits:true;initial-value:0}
@supports (animation-timeline:view()) and (timeline-scope:--hook){
@media screen and (min-width:861px) and (min-height:640px) and (prefers-reduced-motion:no-preference){
  #hook{z-index:2;animation:open-hold linear both,open-fade linear both,open-pull cubic-bezier(.45,0,.55,1) both;animation-timeline:--hook;animation-range:exit 0% exit 100%,exit 3% exit 44%,exit 4% exit 44%}
  #hook.glass-on{animation-name:open-hold,none,open-pull;--front:calc(var(--mh) + var(--pull) * (114% - var(--mh)));
   -webkit-mask-image:linear-gradient(to bottom,transparent calc(var(--front) - 10%),#000 var(--front));mask-image:linear-gradient(to bottom,transparent calc(var(--front) - 10%),#000 var(--front))}
  #hook .copy{animation-range:exit 0% exit 22%}
  #hook + .stack{animation:open-wait linear both;animation-timeline:--hook;animation-range:exit 0% exit 100%}
  #recognition :is(.head > *,.trio figure){animation:open-in ease-out both;animation-timeline:--hook;animation-range:exit 28% exit 52%}
  #recognition .head > .lead{animation-range:exit 34% exit 58%}
  /* the three photographs, each with its caption, come one after the other with a pause between: one is there
     before the next begins (the user, 2026-10-08: "longer breaks in between"; they used to start 5% apart and
     run together) */
  #recognition .trio figure:nth-child(1){animation-range:exit 42% exit 53%}
  #recognition .trio figure:nth-child(2){animation-range:exit 58% exit 69%}
  #recognition .trio figure:nth-child(3){animation-range:exit 74% exit 85%}
  /* the photographs settle as they come up, not as they scroll in */
  #recognition .trio .plate img{animation-timeline:--hook;animation-range:exit 42% exit 68%}
  #recognition .trio figure:nth-child(2) .plate img{animation-range:exit 58% exit 84%}
  #recognition .trio figure:nth-child(3) .plate img{animation-range:exit 74% exit 100%}
  /* all of recognition comes up with the hand-over, none of it by arriving */
  #recognition :is(.head > *,.trio .plate).arrive,#recognition .trio figcaption.arrive > *{opacity:1;transform:none;transition:none}
  #recognition .trio figcaption.arrive{border-top-color:var(--c-rule)}
  #recognition .trio figcaption.arrive::before{content:none}
}}
@keyframes open-hold{from{translate:0 0}48%{translate:0 48dvh}48.01%,to{translate:0 -100dvh}}
@keyframes open-fade{to{opacity:0}}
@keyframes open-pull{to{--pull:1}}
@keyframes open-wait{from{translate:0 -100dvh}to{translate:0 0}}
@keyframes open-in{from{opacity:0;translate:0 calc(var(--m-rise) * 1.5)}to{opacity:1;translate:0 0}}

/* ---- the masthead on the last ground (the user, 2026-10-08: the contents of the masthead "smoothly change" to
   white, starting "at the same point where the gradient background begins to fade in"). The last ground is
   held to the screen and fades in; the strip does the same with a copy of it (.head-ground: the same sweep,
   the same grain, the size of the screen, cut to the strip), laid over its paper, so strip and page turn as
   one and what scrolls beneath is still covered. The contents turn on the range of that fade. The button
   turns over in step with it, from the first step to the last: white, with its label in ink. The letters
   cannot turn in step: a letter that pales as fast as its ground darkens is the colour of that ground
   halfway, and cannot be read for most of the way. So each turns, smoothly but in a short stretch, while the
   ground behind it passes the grey at which ink and white read equally (--turn, an easing with that point in
   it): the wordmark first, over the ink end of the sweep, then the links one after the other towards its
   light end.
   The links stand on the light end of the sweep, where white does not read, so on wide screens the ground
   is shaded with its own deep blue along the top of its right half, under them (::before, on the ground and
   on its copy alike).
   Where the ground cannot be held and faded (no scroll timelines, reduced motion) it is a plain block that
   passes under the strip, and the masthead stays as it is ---- */
@supports (animation-timeline:view()) and (timeline-scope:--ends){
@media screen and (prefers-reduced-motion:no-preference){
  /* the two timelines that are followed from outside their own section: the opening leaving (the hand-over,
     above) and the last ground arriving */
  body.ek{timeline-scope:--hook,--ends}
  .site-head{animation:m-fade var(--m-in) var(--ease) backwards,nav-edge linear both;animation-timeline:auto,--ends;animation-range:normal,entry 18% entry 70%}
  .head-ground{display:block;position:absolute;inset:0;z-index:-1;overflow:hidden;isolation:isolate;pointer-events:none;
   background:var(--sweep-lime) 0 0/100% 100vh no-repeat;background-size:100% 100dvh;
   animation:ends-in linear both;animation-timeline:--ends;animation-range:entry 18% entry 70%}
  .head-ground::after{content:"";position:absolute;left:0;top:0;width:100%;height:100vh;height:100dvh;background-image:var(--noise);opacity:.45;mix-blend-mode:overlay}
  :is(.site-brand,.site-nav a,.menu-open){animation:nav-white both;animation-timeline:--ends;animation-range:entry 18% entry 70%;animation-timing-function:var(--turn)}
  /* where each turns, measured on captures at 1440 by 900: the share of the fade at which ink and white read
     equally (about 4 to 1) on the ground behind it. Wordmark 60%, Services 79, Pricing 81, Cases 84.5, Contact 88.5 */
  :is(.site-brand,.menu-open){--turn:linear(0,0 53%,.12 56%,.5 60%,.88 64%,1 67%,1)}
  .site-nav a:nth-child(1){--turn:linear(0,0 72%,.12 75%,.5 79%,.88 83%,1 86%,1)}
  .site-nav a:nth-child(2){--turn:linear(0,0 74%,.12 77%,.5 81%,.88 85%,1 88%,1)}
  .site-nav a:nth-child(3){--turn:linear(0,0 77.5%,.12 80.5%,.5 84.5%,.88 88.5%,1 91.5%,1)}
  .site-nav a:nth-child(4){--turn:linear(0,0 81.5%,.12 84.5%,.5 88.5%,.88 92.5%,1 95.5%,1)}
  /* the button turns over with the fade itself, from its first step to its last; its label changes sides where
     the two read equally on it, at 43% */
  .site-head .button.ink{animation:nav-fill linear both,nav-label both;animation-timeline:--ends;animation-range:entry 18% entry 70%;
   animation-timing-function:linear,linear(0,0 39.5%,1 46.5%,1)}
  .site-head .button.ink::before{animation:nav-over linear both;animation-timeline:--ends;animation-range:entry 18% entry 70%}
}
@media screen and (min-width:861px) and (prefers-reduced-motion:no-preference){
  :is(.ends .ground,.head-ground)::before{content:"";position:absolute;left:0;top:0;width:100%;height:calc(var(--nh) * 2.6);
   background:linear-gradient(to bottom,rgba(15,63,204,.62) 0,rgba(15,63,204,.56) 27%,rgba(15,63,204,0) 100%);
   -webkit-mask-image:linear-gradient(to right,rgba(0,0,0,0) 30%,#000 62%);mask-image:linear-gradient(to right,rgba(0,0,0,0) 30%,#000 62%)}
}
@media screen and (max-width:860px) and (prefers-reduced-motion:no-preference){
  /* a small screen's last ground runs from ink at the top, so everything in the strip turns as the wordmark does */
  .head-ground{background-image:linear-gradient(172deg,#0a2540 0%,#0f3fcc 58%,#1e5eff 100%)}
}}
@keyframes nav-white{to{color:#fff}}
@keyframes nav-fill{to{--btn-bg:#fff}}
@keyframes nav-over{to{background-color:#eaf3ff}}
@keyframes nav-label{to{--btn-fg:#0a2540}}
@keyframes nav-edge{to{--nav-rule:rgba(255,255,255,.3);--nav-focus:#fff}}

/* ---- a page besides Home (Privacy so far; the user chose Short from design-explorations/round-9, 2026-10-08).
   It opens under the masthead, which holds still, and ends with the footer on the paper.
   A page without the last ground has no copy of it behind the masthead either: that copy is shown by an
   animation on the timeline of the last ground, and where there is no such ground it would stand in the
   strip at full strength ---- */
.page > .slot:first-child{padding-top:var(--nh)}
.page + .site-foot{margin-top:var(--s-sec)}
body:not(:has(.ends)) .head-ground{display:none}

/* running text: paragraphs a step apart on a reading measure. A paragraph may open with its subject in ink */
.prose{font-size:var(--t-body);line-height:1.6;color:var(--c-text2);max-width:62ch;text-wrap:pretty}
.prose > * + *{margin-top:.85em}
.prose b{font-weight:600;color:var(--c-text)}
.prose a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.22em;text-decoration-color:var(--c-text3)}
.prose a:hover{color:var(--cobalt);text-decoration-color:currentColor}

/* privacy: the short version first, on a sheet with the sweep docked under the masthead: the statement, one
   line, the date, one action. Its words keep to the left half, where the sweep is ink and cobalt */
.short{padding-block:clamp(56px,7vw,136px)}
.short .statement{max-width:12ch}
.short > :is(.lead,.small){margin-top:var(--s-lead)}
.short .lead{max-width:44ch}
.page > .slot + .sec{padding-top:var(--s-obj)}

/* folds: a row that opens. Its name on column 1, the answer in a sentence on column 7, a plus at the right;
   opened, the full text stands under the sentence, where the text of a row stands. The line is a grid inside
   the summary, not the summary itself, which not every browser lays out as one. The hairline under a fold is
   a ground, not a border, so it can be drawn from the left as the fold arrives */
.folds{border-top:var(--rule-list)}
.fold{padding-bottom:1px;background:linear-gradient(var(--c-rule),var(--c-rule)) 0 100%/100% 1px no-repeat;scroll-margin-top:var(--nh)}
.fold summary{display:block;padding:var(--s-row) 0;cursor:pointer;list-style:none}
.fold summary::-webkit-details-marker{display:none}
.fold .line{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gap);align-items:baseline}
.fold .line .name{grid-column:1/7}
.fold .line .text{grid-column:7/12}
.fold summary:hover .name{color:var(--cobalt)}
/* open and shut: a plus of two hairlines that turns into a minus */
.sign{grid-column:12/13;justify-self:end;align-self:center;position:relative;width:16px;height:16px}
.sign::before,.sign::after{content:"";position:absolute;left:0;right:0;top:50%;height:1.5px;margin-top:-.75px;background:currentColor}
.sign::after{transform:rotate(90deg)}
.fold[open] .sign::after{transform:none}
.fold[open] > summary{padding-bottom:.85em}
.fold > .prose{margin-left:calc(50% + var(--gap) / 2);padding-bottom:calc(var(--s-row) * 1.6)}

/* not design: what still has to be filled in or confirmed before the page goes live is marked in blue */
.ek mark.fill{padding:0 .2em;border-bottom:1px dashed var(--cobalt);border-radius:3px 3px 0 0;background:var(--sky2);color:inherit}

@media screen and (prefers-reduced-motion:no-preference){
  /* the page opens as Home does: the sheet comes up out of the paper, then its words a line at a time */
  .page > .slot:first-child .sheet{animation:m-fade 1.2s cubic-bezier(.4,0,.2,1) backwards}
  .page > .slot:first-child .short > *{animation:m-rise var(--m-in) var(--ease) backwards;animation-delay:calc(.15s + var(--m-step) * var(--n,0))}
  .page > .slot:first-child .short > :nth-child(2){--n:1}
  .page > .slot:first-child .short > :nth-child(3){--n:2}
  .page > .slot:first-child .short > :nth-child(4){--n:3}
  .sign::after{transition:transform .4s var(--ease)}
  .fold[open] > .prose{animation:m-rise var(--m-in) var(--ease)}
  /* a fold arrives like a row: its hairline draws, then its line rises. One that is already open is simply there */
  .fold.arrive{opacity:1;transform:none;transition:none;background-size:0% 1px}
  .fold.arrive.in{background-size:100% 1px;transition:background-size 1.2s var(--ease) var(--d,0s)}
  .fold.arrive > summary{opacity:0;transform:translateY(calc(var(--m-rise) / 2))}
  .fold.arrive.in > summary{opacity:1;transform:none;transition:opacity var(--m-in) var(--ease),transform var(--m-in) var(--ease);transition-delay:calc(var(--d,0s) + var(--m-step))}
  .fold[open].arrive{background-size:100% 1px}
  .fold[open].arrive > summary{opacity:1;transform:none}
}
@media (max-width:860px){
  /* the sweep runs down the sheet here, so its light end is kept clear below the words */
  .short{padding-bottom:38vw}
  .fold .line{grid-template-columns:minmax(0,1fr) auto;row-gap:6px}
  .fold .line .name{grid-column:1;grid-row:1}
  .fold .line .text{grid-column:1/-1;grid-row:2}
  .sign{grid-column:2;grid-row:1}
  .fold > .prose{margin-left:0}
}
@media print{
  /* the text may run over pages, a clause does not break; every clause is open (open-all.tsx) */
  .page > .slot:first-child{padding-top:0}
  .page .sec{break-inside:auto}
  .fold{break-inside:avoid}
  .short .act,.sign{display:none}
}

/* ---- the cookie question (the user chose Strip from design-explorations/round-11, 2026-10-08;
   src/components/cookies). The masthead mirrored: a strip of the page's own paper along the foot of the screen,
   under a hairline, the height of the masthead; one sentence and three answers. The two answers that matter
   are the same button side by side, so refusing is as easy as agreeing, and neither is lime.
   It is the last thing on the page and holds to the foot of the screen from there (sticky), so where the page
   ends it stands under the footer and covers none of it ---- */
.ask{position:sticky;bottom:0;z-index:20;display:flex;flex-wrap:wrap;align-items:center;gap:12px 28px;min-height:var(--nh);padding:calc((var(--nh) - 40px) / 2) var(--g);background:var(--paper);border-top:var(--rule-list)}
.ask-say{flex:1 1 28ch;max-width:62ch;font-size:14px;line-height:1.45;color:var(--c-text2)}
.ask-say b{font-weight:600;color:var(--c-text)}
.ask-say a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.22em}
.ask-acts{display:flex;flex-wrap:wrap;gap:8px;margin-left:auto}

/* the choices: a sheet of paper over the veiled page. What is needed, always on, and a switch for each of the
   others, under hairlines like every list; three answers under them */
.ek dialog.choices{width:min(720px,calc(100% - var(--si) * 2));max-height:calc(100vh - var(--si) * 2);max-height:calc(100dvh - var(--si) * 2);margin:auto;padding:clamp(24px,3.2vw,48px);border:0;border-radius:var(--r-sheet);overflow:auto;background:var(--paper);color:var(--ink)}
.ek dialog.choices::backdrop{background:rgba(10,37,64,.5)}
.choices .lead{margin-top:var(--s-lead)}
.choices-list{list-style:none;margin:var(--s-act) 0 0;padding:0;border-top:var(--rule-list)}
.choices-list li{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--gap);align-items:center;padding:var(--s-row) 0;border-bottom:var(--rule-list)}
.choices-list .name,.choices-list .text{display:block}
.choices-list .text{margin-top:6px}
.choices-list .small{white-space:nowrap}
.choices-foot{display:flex;flex-wrap:wrap;gap:12px;margin-top:var(--s-act)}
.choices-foot .ghost{margin-right:auto}

/* a switch is a soft rectangle like the buttons. Off, an outline; on, lime behind ink, like selected text */
.switch{position:relative;display:inline-flex;align-items:center;min-height:44px;cursor:pointer}
.switch input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.switch i{position:relative;display:block;width:48px;height:28px;border:1.5px solid var(--ink3);border-radius:var(--r-btn)}
.switch i::after{content:"";position:absolute;left:3px;top:3px;width:19px;height:19px;border-radius:5px;background:var(--ink3)}
.switch input:checked + i{background:var(--lime);border-color:var(--ink)}
.switch input:checked + i::after{transform:translateX(20px);background:var(--ink)}
.switch input:focus-visible + i{outline:2px solid var(--cobalt);outline-offset:4px}

@media screen and (prefers-reduced-motion:no-preference){
  /* the strip comes up from the foot once the page has opened, and sinks away when it is answered; the choices
     come up out of the veil */
  .ask{animation:ask-in var(--m-in) var(--ease) 1.4s backwards}
  .ask.leaving{transform:translateY(100%);opacity:0;transition:transform .5s var(--ease),opacity .4s}
  .ek dialog.choices[open]{animation:choices-in .5s cubic-bezier(.16,1,.3,1)}
  .ek dialog.choices[open]::backdrop{animation:m-fade .3s}
  .switch i{transition:background-color .18s,border-color .18s}
  .switch i::after{transition:transform .3s var(--ease),background-color .18s}
}
@keyframes ask-in{from{transform:translateY(100%);opacity:0}}
@keyframes choices-in{from{transform:translateY(var(--m-rise));opacity:0}}
@media (max-width:860px){
  /* the sentence above its answers; the two answers share a line */
  .ask{flex-direction:column;align-items:stretch;gap:12px;padding:16px var(--g) max(16px,env(safe-area-inset-bottom))}
  .ask-say{flex:none;max-width:none}
  .ask-acts{margin-left:0}
  .ask-acts .button{flex:1 1 140px}
  .choices-foot .button{flex:1 1 100%}
  .choices-foot .ghost{margin-right:0}
}
@media print{.ask,.ek dialog.choices{display:none}}

/* ---- small screens: everything in one column, no pinning, no turn ---- */
@media (prefers-reduced-motion:reduce){.pins .pin-under{position:static}}
@media (max-width:1100px){
  .rows .text{grid-column:7/10}
  .rows .amount{grid-column:10/13}
}
@media (max-width:860px){
  .ek{--r-sheet:20px}
  #hook h1 span{display:inline}
  /* the lead with the cue to its right, the action under them */
  #hook .sub{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;justify-items:start;gap:28px 20px}
  #hook .sub .button{grid-column:1/-1;margin-left:0}
  .pins .pin-under{position:static}
  .trio{display:block}
  .trio figure{display:block}
  .trio figure+figure{margin-top:28px}
  .trio .plate,.trio figure:first-child .plate{aspect-ratio:3/2}
  .rows li,.rows.half li{grid-template-columns:minmax(0,1fr);row-gap:6px}
  .rows .name,.rows .text,.rows .amount,.rows.half .name,.rows.half .text,.rows.half .amount{grid-column:1;justify-self:start}
  .rows.objects li{grid-template-columns:var(--glyph) minmax(0,1fr);column-gap:16px;align-items:start}
  .rows.objects .glyph{grid-column:1;grid-row:1/3}
  .rows.objects .name,.rows.objects .text{grid-column:2}
  .sweep{background:linear-gradient(172deg,#0a2540 0%,#0f3fcc 44%,#1e5eff 74%,#cfe6ff 100%)}
  .slot{padding-bottom:0}
  .sheet.full{min-height:0}
  .sheet.full.sweep{padding-block:56px 28vw}
  .strip{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .strip li{padding-bottom:40px}
  .strip li:nth-child(odd)::after{display:none}
  .strip li:nth-child(n+3){border-top:1px solid var(--c-rule)}
  .proof.sheet{display:block}
  .proof.sheet.full{padding-block:48px 0}
  /* the picture under the words, on the light end of the sweep: as wide as the sheet (its empty left margin
     cut off), against the right edge and the foot. Its top is not at the top of the sheet here, so it fades */
  .proof .shot{position:relative;margin:40px calc(var(--sp) * -1) 0}
  .proof .shot img{position:static;width:112%;height:auto;margin-left:-12%;-webkit-mask-image:linear-gradient(to bottom,transparent,#000 14%);mask-image:linear-gradient(to bottom,transparent,#000 14%)}
  .slot.rise{padding-bottom:var(--si)}
  .duo{display:block}
  .tab{margin-top:40px;max-width:520px}
  .ends .ground{background:linear-gradient(172deg,#0a2540 0%,#0f3fcc 58%,#1e5eff 100%)}
  .acts .button{min-width:0;flex:1 1 220px}
  /* the footer in one column: a page's name over its sentence, the small print line by line */
  .ends .site-foot:not(.paper){--rise:320px}
  .site-foot .rows li > :is(a,.text){grid-column:1}
  .site-foot :is(.legal,.cols,.top){display:block}
  .site-foot .legal{margin-top:40px}
  .site-foot :is(.legal,.cols) > * + *{margin-top:6px}
  .site-foot :is(.legal,.cols) > :first-child{margin-bottom:18px}
  .site-foot .top > * + *{margin-top:26px}
  .site-foot .top .heading span{display:inline}
  .site-foot .links{gap:.9em}
  .site-foot nav.links{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:.9em var(--gap);justify-items:start}
  .site-foot.paper .sheet{padding-top:36px}
  .site-foot .cols{margin-top:36px}
}
/* the masthead on a small screen: the wordmark, the action and a Menu button; the four links are in the menu.
   The hairline runs the whole width */
@media screen and (max-width:860px){
  .ek{--nh:56px;--mh:64px}
  .site-head{gap:12px;padding:8px var(--g)}
  .site-head::after{left:0;right:0}
  .site-head .logo{width:84px}
  .site-side{display:flex;align-items:center;gap:8px}
  .site-nav{display:none}
  .menu-open{display:inline-flex}
}
@media screen and (max-width:359px){
  .site-side > .button.ink{display:none}
}
@media print{
  /* on paper the masthead does not hold still: it is the first thing on the first page, and nothing has to
     sit clear of it */
  .ek{--clear:var(--s-lock)}
  .site-head{position:static;min-height:var(--mh);padding-block:18px;background:none}
  .site-head::after{content:none}
  .ek dialog.menu[open]{display:none}
  #hook{min-height:0;padding-bottom:10vh;break-inside:avoid}
  #hook .sky{min-height:30vh;--top:0px;--over:0px}
  .sec{padding-top:14mm;break-inside:avoid}
  .pins .pin-under{position:static}
  .lock .head{position:static}
  .sheet,.sheet.full{min-height:0;break-inside:avoid}
  /* on paper the tablet is front-on, without its light or its shadow */
  .tab .stand{margin-block:8.5%}
  .tab .slab{transform:none}
  .tab :is(.cast,.sheen){display:none}
  .ends{break-inside:avoid}
  .ends .close{padding-top:20vh}
}
@media print and (max-width:860px){
  .site-head{gap:16px}
  .site-nav{gap:14px;font-size:13px}
}
