/* VeloSwing. A precise sports instrument: a paper-white wall, then one long dark passage where the light finally shows.
   Nothing here carries a colour. The LED, the real screen and the photographs are the only colour on the page. */
html[data-page=velo]{--off:clamp(26px,5svh,52px);--rule:1px solid var(--w-line)}
html[data-page=velo] .say{height:142svh}
html[data-page=velo] .is-night{background:none}
html.no-gl[data-page=velo] .is-night{background:var(--night)}
/* Without the field the night still comes in and goes out through a soft ramp, never a cut. */
html.no-gl[data-page=velo] .peel{background:linear-gradient(transparent,var(--night) 34svh,var(--night) calc(100% - 34svh),transparent);padding-top:calc(clamp(60px,10svh,120px) + 34svh);padding-bottom:calc(clamp(120px,22svh,220px) + 34svh)}

/* The dark passage opens with the idea itself: a swing on the left turns into a number, and the real device on the right
   answers in its colour. Everything on it is white on the night the field brings up. */
.speed__led{flex:none;width:9px;height:9px;border-radius:50%;background:var(--led,currentColor);box-shadow:0 0 12px 1px var(--led,transparent);transition:background .3s linear,box-shadow .3s linear}

/* #layers: the device rises into the night, then comes apart along its own axis. Each part is named as it goes:
   a name on the dark, a hairline, a dot on the part. */
.peel{position:relative;z-index:2;color:var(--w-ink)}
.peel.is-armed{height:calc(100svh + var(--peel-run))}
.peel.is-armed .peel__pin{position:sticky;top:0;height:100svh;overflow:hidden}
.peel__gl,.gl{position:absolute;inset:0}
.gl canvas{display:block;width:100%!important;height:100%!important}
.peel:not(.is-armed){padding:clamp(60px,10svh,120px) var(--gut) clamp(120px,22svh,220px)}
.peel:not(.is-armed) .peel__gl{display:none}
.peel__poster{margin:0}
.peel__poster img{display:block;width:100%;height:auto}
.peel__t{display:none!important}
.peel.is-armed .peel__poster{display:none}
.peel__list{display:grid;gap:8px;margin-top:clamp(28px,5svh,48px);font-size:var(--cap);color:var(--w-ink)}
.peel__list i{display:none}
.peel__foot{margin-top:clamp(20px,4svh,36px);font-size:var(--cap);color:var(--night-ink2)}
.peel.is-armed .peel__list{position:absolute;inset:0;z-index:2;display:block;margin:0;pointer-events:none;font-size:clamp(17px,1.36vw,24px);line-height:1.2;letter-spacing:-.014em;color:var(--night-ink)}
.peel.is-armed .peel__list li{position:absolute;left:0;top:0;opacity:0}
.peel.is-armed .peel__list span{position:absolute;left:0;top:0;white-space:nowrap;will-change:transform}
.peel.is-armed .peel__list i{display:block;position:absolute;left:0;top:0;width:1px;height:1px;background:var(--night-ink2);transform-origin:0 0;will-change:transform}
.peel.is-armed .peel__list i::after{content:"";position:absolute;left:-2px;top:-2px;width:5px;height:5px;border-radius:50%;background:var(--night-ink)}
.peel.is-armed .peel__foot{position:absolute;left:var(--gut);bottom:var(--off);z-index:2;margin:0;line-height:1.3;letter-spacing:-.008em;opacity:0;transition:opacity .4s linear;pointer-events:none}
.peel.is-armed .peel__foot.is-on{opacity:1}
.is-armed .vers__v figcaption{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* #versions: nine files in one registered view, V1 first. Each is redrawn into the next: the render lets go, its outline
   turns into the next outline, the next render fills it. Every outline left behind stays on the wall as a ghost. */
.vers{position:relative;z-index:1}
.vers.is-armed{height:calc(100svh + var(--vrun) + var(--open))}
.vers:not(.is-armed){padding:clamp(72px,12svh,120px) var(--gut)}
html:not(.no-gl) .vers:not(.is-armed){padding-top:max(58svh,120px)} /* still page, live wall: the heading waits below the tide's band */
.vers__h{font-weight:400;font-size:clamp(28px,3.2vw,56px);line-height:1.04;letter-spacing:-.03em}
.vers:not(.is-armed) .vers__h{margin-bottom:clamp(24px,4svh,44px)}
.vers__stack{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--gut)}
.vers__v{margin:0;min-width:0}
.vers__v img{display:block;width:100%;height:auto} /* all nine in the red the prints were made in (tools/velo-red.mjs) */
.vers__v figcaption{margin-top:8px;font-size:var(--cap);line-height:1.3;color:var(--w-ink2)}
.vers__v figcaption b{font-weight:400;color:var(--w-ink)}
.vers__read,.vers__scrub,.vers__ghost{display:none}
.is-armed .vers__pin{position:sticky;top:0;height:100svh;overflow:hidden;cursor:grab;touch-action:pan-y;-webkit-user-select:none;user-select:none}
.is-armed .vers__pin.is-drag{cursor:grabbing}
.is-gone .vers__pin{opacity:0;pointer-events:none}
.is-armed .vers__h{position:absolute;left:var(--gut);top:clamp(84px,13svh,128px);max-width:8em;pointer-events:none}
.is-armed .vers__stack{position:absolute;left:60%;top:46%;display:block;width:min(86svh,56vw);aspect-ratio:1;transform:translate(-50%,-50%)}
.is-armed .vers__v{position:absolute;inset:0;will-change:opacity}
.is-armed .vers__ghost{display:block;position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.vers__ghost path{fill:none;stroke:var(--w-ink);stroke-width:1;vector-effect:non-scaling-stroke;opacity:0}
.vers__ghost .vg__live{stroke-width:1.5}
/* The light's outline lies over the render: ink on the red body. */
.vers__ghost--l path{stroke:var(--w-ink)}
.is-armed .vers__read{display:block;position:absolute;left:var(--gut);bottom:calc(var(--off) + 78px);max-width:min(24em,34vw);pointer-events:none}
.vers__name{display:flex;align-items:baseline;gap:.5em;font-weight:300;font-size:clamp(30px,3.2vw,56px);line-height:1;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.vers__date{font-weight:400;font-size:var(--cap);letter-spacing:-.008em;color:var(--w-ink2)}
.vers__note{margin-top:.55em;min-height:2.6em;font-size:var(--cap);line-height:1.3;letter-spacing:-.008em;color:var(--w-ink)}
/* The track: nine stops, V1 to V3.5.2, the line filling as the files go by. */
.is-armed .vers__scrub{display:block;position:absolute;left:var(--gut);right:var(--gut);bottom:var(--off);height:50px}
.vers__scrub ol{position:absolute;left:0;right:0;top:0;display:flex;justify-content:space-between;pointer-events:none}
.vers__scrub li{position:relative;width:1px;height:9px;margin-top:8px;background:var(--w-ink2);transition:background .2s linear}
.vers__scrub li.on{background:var(--w-ink)}
.vers__scrub li span{position:absolute;top:20px;left:50%;translate:-50% 0;font-size:var(--cap);line-height:1.2;letter-spacing:-.008em;white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--w-ink2);transition:color .2s linear}
.vers__scrub li:first-child span{left:0;translate:none}
.vers__scrub li:last-child span{left:auto;right:0;translate:none}
.vers__scrub li.is-cur span{color:var(--w-ink)}
.vers__fill{position:absolute;left:0;right:0;top:12px;height:1px;background:var(--w-ink);transform:scaleX(var(--f,0));transform-origin:0 50%;pointer-events:none}
.vers__scrub input{-webkit-appearance:none;appearance:none;position:absolute;inset:0 -5px auto;width:calc(100% + 10px);height:24px;margin:0;background:none;cursor:ew-resize;touch-action:none}
@media (pointer:coarse){.vers__scrub input{height:44px;top:-10px}}
.vers__scrub input::-webkit-slider-runnable-track{height:24px;background:linear-gradient(transparent 11.5px,var(--w-line) 11.5px,var(--w-line) 12.5px,transparent 12.5px)}
.vers__scrub input::-moz-range-track{height:1px;background:var(--w-line)}
.vers__scrub input::-webkit-slider-thumb{-webkit-appearance:none;width:11px;height:24px;border:0;background:linear-gradient(90deg,transparent 5px,var(--w-ink) 5px,var(--w-ink) 6px,transparent 6px)}
.vers__scrub input::-moz-range-thumb{width:11px;height:24px;border:0;border-radius:0;background:linear-gradient(90deg,transparent 5px,var(--w-ink) 5px,var(--w-ink) 6px,transparent 6px)}
.vers__scrub input:focus-visible{outline:none}
.vers__scrub input:focus-visible::-webkit-slider-thumb{outline:2px solid var(--w-ink);outline-offset:1px}
.vers__scrub input:focus-visible::-moz-range-thumb{outline:2px solid var(--w-ink);outline-offset:1px}

/* The real scenes: in through one diffuser, out through the other. Between them the page dips through its own wall, so two people never share a frame. */
.scene{position:relative;z-index:3}
.scene.is-armed{height:calc(100svh + var(--open) + var(--hold1) + var(--tide) + var(--hold2) + var(--shut));margin-top:calc(-100svh - var(--open));pointer-events:none}
.scene__pin{position:relative}
.scene.is-armed .scene__pin{position:sticky;top:0;height:100svh;overflow:hidden}
.scene__win{position:relative}
.scene.is-armed .scene__win{position:absolute;inset:0;visibility:hidden;will-change:clip-path,opacity}
.scene.is-armed.is-on .scene__win{visibility:visible}
.scene__lit{display:none}
.scene.is-armed .scene__lit{display:block;position:absolute;inset:0;visibility:hidden}
.scene figure{margin:0}
.scene img{display:block;width:100%;height:auto}
html.motion .scene img:not(.is-in){opacity:0} /* fades in once decoded (site.js), never lands in one frame */
html.motion .scene img{transition:opacity .35s linear}
.scene.is-armed figure{position:absolute;inset:0}
.scene.is-armed img{height:100%;object-fit:cover}
.scene__a img,.scene__lit--a img{object-position:12% 72%}
.scene__b img,.scene__lit--b img{object-position:80% 70%} /* the racket, the device and the line; the ball when there is room */
.scene.is-armed img{transform-origin:0 0;will-change:transform}

/* #lab: one calm screen. The object on the right, the instrument on the left. A swing answers on the device, never on the page. */
.lab{position:relative;z-index:2;--side:clamp(280px,21vw,360px)}
.lab.is-armed{height:calc(100svh + var(--hold1) + var(--tide) + var(--hold2) + var(--shut) + var(--labhold));margin-top:calc(-100svh - var(--hold1) - var(--tide) - var(--hold2) - var(--shut))}
.lab__pin{position:relative;height:100svh;min-height:600px;overflow:hidden;touch-action:pan-y;cursor:grab;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.lab.is-armed .lab__pin{position:sticky;top:0}
.lab.is-armed:not(.is-up) .lab__pin{opacity:0;pointer-events:none}
.lab.is-armed:not(.is-up){pointer-events:none} /* until it is up it lies over the version slider: taps go to the slider */
.lab__pin.is-drag{cursor:grabbing}
.lab__pin.over-btn{cursor:pointer}
.lab__gl{position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 78%,transparent);mask-image:linear-gradient(#000 78%,transparent)}
.lab__poster{position:absolute;inset:0 var(--gut) 0 calc(var(--gut) + var(--side));pointer-events:none;transition:opacity .6s linear}
.gl-on .lab__poster{opacity:0}
.lab__poster img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
/* The call-out from the screen on the device to its reading. A grey hairline on the wall; over the black print its two pale edges carry it, so it reads all the way to the screen. */
.lab__lead{position:absolute;z-index:2;left:0;top:0;height:1px;width:0;background:var(--w-ink2);box-shadow:0 -1px 0 rgba(255,255,255,.6),0 1px 0 rgba(255,255,255,.6);transform-origin:0 50%;pointer-events:none;opacity:0;transition:opacity .4s linear}
.gl-on .lab__lead{opacity:calc(.5*var(--side-o,1))}
.lab__side{position:absolute;z-index:3;left:var(--gut);top:clamp(84px,13svh,128px);bottom:var(--off);width:var(--side);display:flex;flex-direction:column;cursor:default}
.lab.is-armed .lab__side{opacity:var(--side-o,1)} /* the instrument waits until the closing window has gone, so no edge crosses its words */
.lab.is-armed .lab__gl,html:not(.gl-on) .lab.is-armed .lab__poster{opacity:var(--dev-o,1)} /* and the device comes up only round the light the window leaves */
.lab__head h2{font-weight:400;font-size:clamp(28px,3.2vw,56px);line-height:1.04;letter-spacing:-.03em}
.lab__head p{margin-top:.6em;font-size:var(--cap);line-height:1.3;letter-spacing:-.008em;color:var(--w-ink2)}
.lab__kmh{display:flex;align-items:flex-end;gap:.7em;margin-top:clamp(12px,2.6svh,28px)}
.lab__kmh b{font-weight:200;font-size:clamp(64px,6.6vw,120px);line-height:.84;letter-spacing:-.045em;font-variant-numeric:tabular-nums;margin-left:-.05em}
.lab__u{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.35em .6em;align-items:center;padding-bottom:.2em;font-size:var(--cap);line-height:1.2;letter-spacing:-.008em}
.lab__u em{font-style:normal}
.lab__u>span{grid-column:1/-1;color:var(--w-ink2)}
.lab__u .speed__led{--led:var(--w-ink2);box-shadow:none}
.lab__u .speed__led.is-lit{box-shadow:0 0 10px 1px var(--led)}
/* What to do with the object, said once beside it. It goes as soon as the racket has been touched. */
.lab__cue{position:absolute;z-index:2;left:calc(var(--gut) + var(--side) + (100% - 2*var(--gut) - var(--side))*.5 + clamp(96px,11vw,190px));top:60%;display:flex;flex-direction:column;align-items:center;gap:8px;font-size:var(--cap);line-height:1.2;letter-spacing:-.008em;color:var(--w-ink);pointer-events:none;opacity:0;transition:opacity .5s linear}
.lab__pin.is-cue .lab__cue{opacity:var(--side-o,1)}
.lab__cue svg{display:block;width:64px;height:24px;fill:none;stroke:var(--w-ink);stroke-width:1;stroke-linecap:round;stroke-linejoin:round}
.lab__pin.is-touched .lab__cue,.no-gl .lab__cue{opacity:0}
.scope{position:relative;margin:clamp(18px,3.6svh,40px) 0 0}
.scope canvas{display:block;width:100%;height:auto;aspect-ratio:816/228;background:#000}
.lab__note{margin-top:10px;min-height:2.6em;font-size:var(--cap);line-height:1.3;letter-spacing:-.008em;color:var(--w-ink2)}
.lab__led{display:none;position:absolute;right:6px;top:6px;width:30px;color:#fff}
.no-gl .lab__led{display:block}
.led{display:block;width:100%;height:auto;overflow:visible}
.led__o{fill:none;stroke:currentColor;stroke-width:1;stroke-linejoin:round}
.led circle{fill:#fff;opacity:.14;transition:opacity .06s linear}
.lab__hmi{display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 clamp(20px,2.2vw,34px);align-items:center;margin-top:clamp(14px,3svh,32px);cursor:default}
.hold__b{--held:0;position:relative;flex:none;display:grid;place-items:center;width:clamp(92px,7.6vw,118px);aspect-ratio:1;border-radius:50%;touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;transition:transform .6s var(--ease)}
.hold__b.is-down{transform:scale(.985)}
.hold__b svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;fill:none}
.hold__t{stroke:var(--w-ink2);stroke-width:1;vector-effect:non-scaling-stroke;opacity:.6}
.hold__p{stroke:var(--w-ink);stroke-width:2;vector-effect:non-scaling-stroke;stroke-dasharray:5 5;stroke-dashoffset:calc(5 - var(--held));transform:rotate(-90deg);transform-origin:50% 50%}
.hold__k{stroke:var(--w-ink2);stroke-width:1;vector-effect:non-scaling-stroke}
.hold__l{font-size:var(--cap);line-height:1.1;letter-spacing:-.008em;text-align:center;font-variant-numeric:tabular-nums}
.hold__b.is-nudge{animation:vs-nudge .9s var(--ease)}
@keyframes vs-nudge{0%,100%{opacity:1}30%{opacity:.4}}
.hmi{display:grid}
.hmi .hmi__r{display:flex;justify-content:space-between;gap:12px;width:100%;padding:6px 0;border-top:var(--rule);font-size:var(--cap);line-height:1.25;letter-spacing:-.008em;text-align:left;color:var(--w-ink2);transition:color .25s linear}
.hmi li:last-child .hmi__r{border-bottom:var(--rule)}
.hmi__n{font-weight:400;white-space:nowrap}
.hmi .hmi__r.on,.ctl .hmi__r.on{color:var(--w-ink)}
.hmi__r:focus-visible{outline-offset:2px}
@media (hover:hover){.hmi .hmi__r:hover,.ctl .hmi__r:hover{color:var(--w-ink)}}
.ctl{display:flex;gap:clamp(14px,1.4vw,22px);align-items:flex-end;margin-top:auto}
.f1{position:relative;flex:1;min-width:0;display:flex}
.f1__s{flex:var(--f) 1 0;min-width:0}
.ctl .hmi__r{display:block;width:100%;padding:9px 0 2px;border-top:var(--rule);font-size:var(--cap);line-height:1.2;letter-spacing:-.008em;text-align:left;color:var(--w-ink2);transition:color .25s linear,border-color .25s linear}
.ctl .hmi__r.on{border-top-color:var(--w-ink)}
.ctl b{font-weight:400;white-space:nowrap}
.ctl .hmi__r[aria-disabled=true]{opacity:.5}
.ctl>.f1__up{flex:0 0 18%;width:auto}
.f1__n{position:absolute;top:-5px;left:0;width:1px;height:11px;background:var(--w-ink);opacity:0;transition:left .9s var(--ease),opacity .3s linear}
.f1__n.on{opacity:1}

/* #court and #reads: the proof. Thin numerals, ink on the wall. */
.court,.reads,.wiring{position:relative;z-index:1}
.court{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:clamp(24px,4svh,48px) clamp(16px,2vw,32px);align-items:end;align-content:center;min-height:92svh;padding:clamp(88px,14svh,140px) var(--gut) clamp(40px,8svh,88px)}
.court__big{grid-column:1/6;min-width:0}
.court__h{font-weight:400}
.court__n{display:block;font-weight:200;font-size:clamp(84px,11vw,200px);line-height:.9;letter-spacing:-.045em;margin-left:-.045em;font-variant-numeric:tabular-nums}
.court__t{display:block;margin-top:.7em;font-weight:400;font-size:clamp(20px,1.9vw,32px);line-height:1.1;letter-spacing:-.024em}
.court__v{grid-column:6/-1;margin:0;min-width:0}
.court__v video{display:block;width:100%;height:auto;aspect-ratio:16/9;background:var(--w-ink);filter:grayscale(1) contrast(1.08);transition:filter .6s var(--ease)}
.court__v video:hover,.court__v video:focus-visible{filter:none}
.log{margin-top:clamp(24px,5svh,52px);display:grid;font:400 var(--cap)/1.2 var(--mono)}
.log__r{display:grid;grid-template-columns:7ch 9ch minmax(0,1fr) auto;align-items:center;column-gap:6px;min-height:28px;border-top:1px solid transparent;color:var(--w-ink2);transition:border-color .3s linear}
.log__r.on{border-top-color:var(--w-line)}
html:not(.motion) .log__r{border-top-color:var(--w-line)}
.log__r .un{visibility:hidden}
.log__k{font-weight:400;color:var(--w-ink);text-align:right;font-variant-numeric:tabular-nums}

.reads{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(28px,5svh,56px) clamp(16px,2vw,32px);min-height:86svh;align-content:center;padding:clamp(40px,8svh,88px) var(--gut)}
.reads__a{grid-column:1/4;min-width:0}
.reads__b{grid-column:4/-1;min-width:0}
.reads__h{font-weight:400;font-size:clamp(20px,1.9vw,32px);line-height:1.1;letter-spacing:-.024em}
.over{margin:clamp(16px,3svh,32px) 0 0;min-width:0}
.over__p{position:relative;aspect-ratio:900/340;max-height:36svh;width:100%}
.over__p>svg{display:block;width:100%;height:100%;overflow:visible}
.over path{fill:none;vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round}
path.over__z{stroke:var(--w-ink2);stroke-width:1;opacity:.5}
path.over__i{stroke:var(--w-ink2);stroke-width:1;stroke-dasharray:1 5}
path.over__s{stroke:var(--w-ink);stroke-width:1.5}
path.over__d{stroke:var(--w-ink2);stroke-width:1.5}
path.over__o{stroke:var(--w-ink);stroke-width:1;stroke-dasharray:6 4}
.over__k{position:absolute;left:0;top:0;display:grid;gap:5px;font-size:var(--cap);line-height:1.2;letter-spacing:-.008em;opacity:0;transition:opacity .4s linear}
.over__k li{display:grid;grid-template-columns:26px auto;align-items:center;column-gap:10px}
.over__k i{display:block;height:0;border-top:1.5px solid var(--w-ink)}
.over__l--d i{border-top-color:var(--w-ink2)}
.over__l--o i{border-top:1px dashed var(--w-ink)}
.is-drawn .over__k{opacity:1}
.over__x{display:flex;justify-content:space-between;padding-top:8px;font-size:15px;color:var(--w-ink2)}
.match{margin-top:clamp(16px,3svh,32px);position:relative}
.match__v{font-weight:200;font-size:clamp(60px,7.4vw,132px);line-height:1;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.match__o{display:flex;align-items:center;flex-wrap:wrap;gap:10px 14px;margin:clamp(10px,1.6svh,18px) 0 clamp(28px,5svh,48px)}
.match__o canvas{flex:0 0 auto;width:clamp(200px,16vw,260px);height:auto;aspect-ratio:10/1;background:#000}
.match__o p{flex:1 1 12em;font-size:var(--cap);line-height:1.25;letter-spacing:-.008em;color:var(--w-ink2)}
.match__b{position:relative;height:1px;background:var(--w-line)}
.match__b::before{content:"";position:absolute;left:70%;top:-9px;bottom:-9px;width:1px;background:var(--w-ink)}
.match__w{position:absolute;inset:0;background:linear-gradient(var(--w-ink),var(--w-ink)) 0 0/var(--w) 100% no-repeat}
.match__tick{position:absolute;top:-4px;bottom:-4px;width:1px;background:var(--w-ink2)}
.match__r{display:block;position:relative;height:44px;margin:-22px -5px 0}
.match__r input{-webkit-appearance:none;appearance:none;display:block;width:100%;height:44px;margin:0;background:transparent;cursor:ew-resize;touch-action:pan-y}
.match__r input::-webkit-slider-runnable-track{height:44px;background:transparent}
.match__r input::-moz-range-track{height:44px;background:transparent}
.match__r input::-webkit-slider-thumb{-webkit-appearance:none;width:11px;height:23px;margin-top:10.5px;border:0;background:linear-gradient(90deg,transparent 5px,var(--w-ink) 5px,var(--w-ink) 6px,transparent 6px)}
.match__r input::-moz-range-thumb{width:1px;height:23px;border:0;border-radius:0;background:var(--w-ink)}
.match__r input:focus-visible{outline:none}
.match__r input:focus-visible::-webkit-slider-thumb{outline:2px solid var(--w-ink);outline-offset:1px}
.match__r input:focus-visible::-moz-range-thumb{outline:2px solid var(--w-ink);outline-offset:1px}
.match__k{position:relative;height:20px;margin-top:-6px;font-size:15px;line-height:1;color:var(--w-ink2)}
.match__k span{position:absolute;top:0;left:0}
.match__k span:last-child{left:auto;right:0}
.match__k .match__t{left:70%;transform:translateX(-50%);color:var(--w-ink)}
.tally{grid-column:1/-1;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(20px,3svh,32px) clamp(16px,2vw,32px);padding-top:clamp(16px,3svh,28px);border-top:var(--rule)}
.tally div{display:flex;flex-direction:column;min-width:0}
.tally dd{font-weight:300;font-size:clamp(28px,2.5vw,46px);line-height:1;letter-spacing:-.034em;white-space:nowrap;font-variant-numeric:tabular-nums}
.tally dt{margin-top:8px;font-size:var(--cap);line-height:1.25;letter-spacing:-.008em;color:var(--w-ink2)}

/* #wiring: hairlines on the wall */
.wiring{padding:clamp(72px,12svh,120px) var(--gut) clamp(40px,8svh,80px)}
.wiring__h{font-weight:400;font-size:clamp(28px,3.2vw,56px);line-height:1.04;letter-spacing:-.03em;margin-bottom:clamp(24px,4svh,44px)}

/* The finished object, as a product: in the hand, alone from three sides with its numbers, close, in four colours, then on
   the racket. Each picture is a plate on the wall with its own pale grey sweep. Then the court, and the last line under it. */
.hand,.sides,.mat,.ways,.fin{position:relative;z-index:1;padding:clamp(36px,6svh,72px) var(--gut)}
.hand,.mat,.fin{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:clamp(16px,2vw,32px)}
:is(.hand,.sides,.mat,.ways,.fin) figure{margin:0;min-width:0}
:is(.hand,.sides,.mat,.ways,.fin) img{display:block;width:100%;height:auto;object-fit:cover}
:is(.hand,.sides,.mat,.ways,.fin) figcaption{margin-top:12px;font-size:var(--cap);line-height:1.3;letter-spacing:-.008em;color:var(--w-ink2)}
:is(.hand,.sides,.mat,.ways,.fin) figcaption b{font-weight:400;color:var(--w-ink)}
.hand{align-items:end;padding-top:clamp(88px,14svh,150px)}
.hand__h,.mat__h{font-weight:400;font-size:clamp(28px,3.2vw,56px);line-height:1.04;letter-spacing:-.03em}
.hand__h{grid-column:1/-1;margin-bottom:clamp(24px,4svh,44px)}
.hand__a{grid-column:1/6}
.hand__b{grid-column:6/-1}
.sides__g{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2vw,32px);list-style:none}
.sides figcaption b{display:block}
/* the numbers, set like the tally above: the figure, then what it counts */
.spec{display:grid;grid-template-columns:2fr repeat(5,minmax(0,1fr));gap:clamp(20px,3svh,32px) clamp(16px,2vw,32px);margin-top:clamp(28px,5svh,56px);padding-top:clamp(16px,3svh,28px);border-top:var(--rule)}
.spec div{display:flex;flex-direction:column;min-width:0}
.spec dd{font-weight:300;font-size:clamp(24px,2.1vw,40px);line-height:1;letter-spacing:-.034em;white-space:nowrap;font-variant-numeric:tabular-nums}
.spec dt{margin-top:8px;font-size:var(--cap);line-height:1.25;letter-spacing:-.008em;color:var(--w-ink2)}
.mat{align-items:start}
.mat__p{grid-column:1/8}
.mat__t{grid-column:8/-1}
.mat__h{margin-bottom:clamp(20px,3.4svh,36px)}
.mat__l{font-size:var(--cap);line-height:1.3;letter-spacing:-.008em}
.mat__l div{display:grid;grid-template-columns:minmax(0,7em) minmax(0,1fr);column-gap:16px;padding:clamp(10px,1.6svh,16px) 0;border-top:var(--rule)}
.mat__l div:last-child{border-bottom:var(--rule)}
.mat__l dt{color:var(--w-ink2)}
.mat__l dd{color:var(--w-ink)}
.ways__p--2{display:none}
.fin{align-items:start;padding-bottom:clamp(56px,9svh,110px)}
.fin__b{grid-column:1/7}
.fin__c{grid-column:7/-1}
.fin__b img,.fin__c img{aspect-ratio:3/2}
/* One frame, held twice: the slow light, then the fast one over it once the picture is well on screen. */
.fin__x{position:relative}
.fin__x picture+picture img{position:absolute;inset:0;height:100%;transition:opacity .7s linear}
html.motion .fin__x:not(.is-fast) picture+picture img{opacity:0}
.shut{position:relative;z-index:1;padding-bottom:clamp(48px,9svh,104px)}
.shut__win{margin:0;clip-path:inset(calc((1 - var(--q,1))*6svh) calc((1 - var(--q,1))*var(--gut)))}
.shut__win img{display:block;width:100%;height:auto;aspect-ratio:16/9;max-height:100svh;object-fit:cover}
.shut__say{padding:clamp(28px,5svh,56px) var(--gut) 0;font-size:clamp(22px,2.3vw,40px);line-height:1.12;letter-spacing:-.024em;color:var(--w-ink)}
.shut__say span{display:block}

@media (max-width:760px),(max-aspect-ratio:1/1){
  /* Upright: the number and the swing share the top, the device stands under them. */
  .peel__t{display:block!important;width:min(100%,520px);margin-inline:auto}
  .peel__w{display:none!important}
  .peel.is-armed .peel__list{font-size:16px}
  .is-armed .vers__h{top:clamp(72px,11svh,112px)}
  .is-armed .vers__stack{left:50%;top:43%;width:min(112vw,56svh)}
  .is-armed .vers__read{right:var(--gut);max-width:none;bottom:calc(var(--off) + 40px)}
  .is-armed .vers__scrub{height:24px}
  .vers__scrub li span{display:none}
  .scene__a img,.scene__lit--a img{object-position:0% 62%} /* the hand, the grip and the device, not the curtain */
  .scene__b img,.scene__lit--b img{object-position:81% 50%} /* the throat and the device, with the strings beside them */
  .shut__win img{aspect-ratio:4/3;object-position:74% 50%} /* the racket and the bench stay in the frame */
}
@media (max-width:760px){
  .sides__g{grid-template-columns:minmax(0,1fr);row-gap:clamp(28px,4.6svh,44px)}
  .sides__g li{max-width:min(100%,520px)}
  .spec{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* four across is too small to read on a phone: the same picture is shown as two halves, two colours each */
  .ways__p{overflow:hidden;aspect-ratio:33/28}
  .ways__p img{width:200%;max-width:none;height:100%}
  .ways__p--2{display:block;margin-top:8px}
  .ways__p--2 img{transform:translateX(-50%)}
}
/* A phone or tablet held upright stacks the lab: the device above, the instrument under it. Held sideways it keeps the desktop
   arrangement, so the device and its controls share the screen. */
@media (max-width:960px){
  .lab__lead,.lab__cue{display:none}
}
@media (max-width:960px) and (max-aspect-ratio:1/1){
  .lab{--side:auto}
  .lab__pin{display:flex;flex-direction:column;padding:clamp(56px,8svh,76px) var(--gut) var(--off);min-height:640px}
  .lab__side{position:static;z-index:auto;width:auto;flex:1;min-height:0}
  .lab__gl,.lab__poster{left:0;right:0;top:clamp(128px,17svh,160px);bottom:auto;height:clamp(200px,32svh,400px);inset-inline:0}
  .lab__gl{-webkit-mask-image:linear-gradient(transparent,#000 12%,#000 80%,transparent);mask-image:linear-gradient(transparent,#000 12%,#000 80%,transparent)}
  .lab__head h2{font-size:clamp(28px,8vw,46px)}
  .lab__head p{margin-top:.3em}
  /* the number stands beside the device, which moves over to make room (velo.js frameTwin) */
  .lab__kmh{position:absolute;left:var(--gut);top:calc(clamp(128px,17svh,160px) + clamp(200px,32svh,400px)*.5 - 30px);margin:0;flex-direction:column;align-items:flex-start;gap:8px}
  .lab__kmh b{font-size:clamp(56px,17vw,84px)}
  .scope{margin-top:calc(clamp(200px,32svh,400px) + clamp(128px,17svh,160px) - clamp(56px,8svh,76px) - clamp(62px,8svh,76px))}
  .scope canvas{width:min(100%,300px)}
  .lab__note{min-height:1.3em;margin-top:6px}
  .lab__hmi{margin-top:8px}
  .hold__b{width:84px}
}
@media (max-width:900px){
  .hand,.mat,.fin{grid-template-columns:minmax(0,1fr);row-gap:clamp(28px,4.6svh,44px)}
  .hand__h{margin-bottom:0}
  .hand__a,.hand__b,.mat__p,.mat__t,.fin__b,.fin__c{grid-column:1}
  .hand__a{max-width:min(100%,520px)}
  .spec{grid-template-columns:repeat(3,minmax(0,1fr))}
  .spec div:first-child{grid-column:1/-1}
  .court__big{display:contents}
  .court__h,.court__v,.log{grid-column:1/-1}
  .court{align-items:start;row-gap:0}
  .court__t{margin-top:.5em}
  .court__v{margin-top:clamp(24px,4svh,40px);order:1}
  .log{margin-top:clamp(16px,3svh,28px);min-height:232px;order:2}
  .reads__a,.reads__b{grid-column:1/-1}
  .tally{grid-template-columns:repeat(2,minmax(0,1fr))}
  .over__p{aspect-ratio:4/3;max-height:60svh;margin-top:calc(clamp(84px,12svh,100px) + 12px)} /* a phone held sideways sees the whole chart; the legend starts under the heading */
  .over__k{top:calc(-1*clamp(84px,12svh,100px));opacity:1}
}
/* Touch: every control of the lab is a 44px target. The rows grow to 44px; the tier buttons keep their line and reach past it. */
@media (pointer:coarse){
  .hmi .hmi__r{min-height:44px;padding:0;align-items:center}
  .ctl .hmi__r{position:relative}
  .ctl .hmi__r::after{content:"";position:absolute;left:0;right:0;top:50%;height:44px;margin-top:-22px}
}
@media (max-height:640px) and (min-aspect-ratio:1/1){
  .lab__pin{min-height:0}
  .lab__kmh{margin-top:8px}
  .lab__kmh b{font-size:clamp(44px,9svh,64px)}
  .hold__b{width:76px}
  .hmi .hmi__r{padding:3px 0}
  .scope{margin-top:14px}
}
/* A phone held sideways: one short column beside the device, nothing below the fold. */
@media (max-height:420px) and (min-aspect-ratio:1/1){
  .lab{--side:clamp(220px,32vw,280px)}
  .lab__side{top:clamp(58px,17svh,72px);bottom:clamp(12px,4svh,20px)}
  .lab__head h2{font-size:clamp(24px,7svh,30px)}
  .lab__head p,.lab__kmh{display:none}
  .scope{margin-top:10px}
  .scope canvas{width:min(100%,220px)}
  .lab__note{min-height:1.3em;margin-top:6px}
  .lab__hmi{margin-top:10px;gap:0 16px}
  .hold__b{width:64px}
  .hmi .hmi__r{min-height:0;padding:3px 0}
  .ctl{padding-top:8px}
}
@media (prefers-reduced-motion:reduce){
}

/* The storyboard: drawn sheets on paper white, set onto the wall (multiply takes the paper away). Four scenes two by two,
   then the three hand drawings in one row. */
.sk{position:relative;padding:clamp(56px,10svh,120px) var(--gut) clamp(40px,7svh,88px)}
.sk__g{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(20px,3svh,36px) clamp(16px,2.4vw,40px)}
.sk__g--h{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:clamp(36px,6svh,72px)}
.sk figure{margin:0}
.sk img{width:100%;height:auto;mix-blend-mode:multiply}
.sk figcaption{display:flex;gap:.8em;margin-top:6px;font-size:var(--cap);line-height:1.3;letter-spacing:-.008em;color:var(--w-ink)}
.sk figcaption b{font-weight:400;color:var(--w-ink2);font-variant-numeric:tabular-nums}
@media (max-width:720px){.sk__g,.sk__g--h{grid-template-columns:minmax(0,1fr)}}

/* The product film on the wall: its white sweep becomes the wall (multiply), so the device seems to stand on the page. */
.pfilm{position:relative;padding:clamp(24px,5svh,64px) var(--gut)}
.pfilm__pic{margin:0 auto;width:min(100%,calc(86svh*(var(--ar))));aspect-ratio:var(--ar)}
.pfilm video{width:100%;height:100%;object-fit:cover;mix-blend-mode:multiply;cursor:pointer}
