@font-face{font-family:'Teneo Sans';src:url('/fonts/teneo-sans.woff2') format('woff2');font-weight:200 900;font-display:block}
/* ONE GLASS (the owner, 2026-09-15: one element, one look, both lanes): the bar, the Back round and the Support round wear these three; the lens is the hover, glass on the glass the open place */
/* ── NOTICE: the one alert piece ── */
/* the two glyphs, drawn from currentColor through a mask: the circle-i of a refusal or a notice, the check of a success */
:root{--glass:rgba(255,255,255,.3);--glass-blur:blur(9px) saturate(1.4);--glass-ring:inset 0 0 0 1px rgba(20,21,58,.1),inset 0 1px 0 rgba(255,255,255,.7),0 12px 36px -10px rgba(4,6,32,.3);--lens:rgba(255,255,255,.5);--lens-ring:inset 0 0 0 1px rgba(20,21,58,.16),inset 0 1px 0 rgba(255,255,255,.95),0 6px 16px -8px rgba(4,6,32,.3);--lens-blur:blur(4px) saturate(1.6) brightness(1.04);--ink:#232467;--ink-soft:#4a4b83;--mute:#6b6c93;--faint:#9a9bb8;--paper:#f6f6fa;--card:#fff;--line:#d7d8e3;--well:#efeff5;--ok:#1b6b4a;--warm:#b3261e;--sky:#4a91e5;--field:linear-gradient(180deg,#25265a 0%,#141539 100%);--sans:'Teneo Sans',system-ui,-apple-system,'Segoe UI',sans-serif;--serif:'Teneo Serif',Georgia,serif;--mono:ui-monospace,'SF Mono',Menlo,monospace;--tab:tabular-nums lining-nums;--isle:rgba(28,29,74,.55);--isle-blur:blur(20px) brightness(.42) saturate(1.4);--isle-line:rgba(255,255,255,.14);--isle-ring:inset 0 0 0 1px rgba(255,255,255,.14),inset 0 1px 0 rgba(255,255,255,.16),0 14px 34px -18px rgba(4,6,32,.7);--rim:rgba(255,255,255,.06);--rim-blur:blur(18px) saturate(1.3);--rim-ring:inset 0 0 0 1px rgba(255,255,255,.14),inset 0 1px 0 rgba(255,255,255,.22);--rim-cast:16px 34px 70px -28px rgba(4,6,32,.75);--card-ring:inset 0 1px 0 #fff,inset 0 0 0 1px rgba(27,28,74,.05);color-scheme:only light;--glyph-i:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 8v5'/%3E%3Cpath d='M12 16.5v.01'/%3E%3C/svg%3E");--glyph-ok:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E")}
*{box-sizing:border-box}
button{font:inherit}
[hidden]{display:none!important}
html,body{height:100%}
body{margin:0;background:#141539 var(--field);color:var(--ink);font:400 15px/22px var(--sans);-webkit-font-smoothing:antialiased}
/* one paint: the page shows once the shell has built the top bar, otty and the bar, so nothing jumps into place; a lost shell script shows the page after 2.5 s regardless */
/* THE RIM PER SCREEN (one set of tokens): the band of glass around the paper, the paper's round, the card's shape and the shell's round; the shell, the card, the account drawer and the chat panel read them (a desk 7/25/32, the fill 4/24/28, a phone 3/23/26) */
.app{--band:7px;--round:25px;--card-r:var(--round);--rim-r:32px;--gut:clamp(20px,3vw,40px)}
.app{height:100dvh;background:var(--field);display:flex;flex-direction:column;overflow:hidden;visibility:hidden;animation:reveal 0s 2.5s forwards}
.app.up,.app.held{visibility:visible;animation:none}
@keyframes reveal{to{visibility:visible}}
/* OTTY STAYS BETWEEN PAGES (the owner, 2026-09-15 20:2x: "let Otty stay continuous as we click through pages and just change the rest"): every page is its own document, so the browser's cross-document transition carries the top bar, him, his words and the pill over the change in place, the rest crossfading; the new page holds the old page's picture (html.hold, set by the shell) until its own reveal, 700 ms at most; reduced motion cuts straight */
@view-transition{navigation:auto}
/* a tap during the change reaches the page, never the transition's picture (the owner, 2026-09-16 01:5x: "buttons need a double click; something blocks the first click"): the pseudo-tree lets pointer events through */
::view-transition{pointer-events:none}
::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation-duration:.12s}
/* ── TOP BAR (frozen) ── */
.top{view-transition-name:top;position:relative;z-index:6;height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;color:#fff;flex:none;background:none}
/* he never moves with the words: his box hangs from the row's top beside the bubble (the owner, 2026-09-15 19:1x: "Otty moves also, which is bad") */
/* no room is reserved for the jump: otty rises over whatever stands above him */
.otty .mount{view-transition-name:otty;align-self:start;grid-area:mount;width:var(--osz);aspect-ratio:1;flex:none;position:relative;margin:0;z-index:3}
/* ── THE SPEECH BUBBLE (the owner, 2026-09-15 16:4x to 17:1x: "an elegant thin glassy speech bubble, shown after the size of the text is known, for the phone and the desk; appear magically"; "the colour doesn't match the theme"; "the triangle has a closed back where it connects"; "the speech and the pill are not aligned") ── */
/* the slot (.say) keeps its place and size; the bubble inside hugs the words and wears the island's navy glass (the theme's box on the field), a tail towards him drawn as one piece (the tail's solid the glass's own composite, its two outer edges ringed, its base over the bubble's ring); it is drawn once the whole line is known (a ghost of the whole line sizes it while the words stream in over it) and rises in once; on a phone its top is the island's top */
.otty .say{view-transition-name:say;grid-area:say;color:#fff;font:400 14px/20px var(--sans);max-width:none;margin:0;min-width:0;min-height:43px;display:flex;align-items:flex-start;justify-content:flex-start;align-self:start}
/* ONE PILL (the owner, 2026-09-15): the same glass as the card's shell (the faint white fill, the white ring, the deep blur, the cast shadow), and the icons follow the ground: white over the navy field, ink where the white box stands under the bar (the fill) */
.bar{view-transition-name:pill;pointer-events:auto;display:flex;align-items:center;gap:2px;max-width:100%;border:0;border-radius:999px;padding:4px;background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);box-shadow:var(--glass-ring)}
html.hold::view-transition-group(*),html.hold::view-transition-old(*),html.hold::view-transition-new(*){animation-play-state:paused}
/* before the reveal nothing moves: every change lands instantly, so no transition or arrival runs on past the first paint */
.app:not(.up) *{transition:none!important;animation:none!important}
.logo{display:flex;align-items:center;min-width:0;text-decoration:none}
.logo img{height:28px;width:auto;display:none}
/* on a phone the wordmark is one T in a glass box, the island's own glass and height */
/* the phone's mark: the same glass, round */
.logo .mark{display:grid;place-items:center;background:var(--isle);backdrop-filter:var(--isle-blur);-webkit-backdrop-filter:var(--isle-blur);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),inset 0 1px 0 rgba(255,255,255,.16);border-radius:50%;width:42px;height:42px}
.logo .mark svg{width:14px;height:auto;display:block;fill:#fff}
.tright{display:flex;align-items:center;gap:16px}
.bell{position:relative;width:24px;height:24px;color:rgba(255,255,255,.9)}
.bell svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.bell.on::after{content:'';position:absolute;top:0;right:1px;width:7px;height:7px;border-radius:50%;background:var(--sky);border:1.5px solid #1a1b40}
/* ONE PILL: the name, the dot when something is unread, the chevron; its sheet holds the notifications, the other door and Sign out */
/* the top island: the same pill as the bottom bar, two segments, the bell with its dot and the name with its chevron */
.me{position:relative}
.isl{display:inline-flex;align-items:center;gap:2px;padding:4px;border-radius:999px;background:var(--isle);backdrop-filter:var(--isle-blur);-webkit-backdrop-filter:var(--isle-blur);box-shadow:var(--isle-ring)}
.isl .seg{display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 12px;border-radius:999px;font:500 13.5px/20px var(--sans);color:rgba(255,255,255,.86);background:none;border:0;cursor:pointer;position:relative;max-width:min(52vw,280px);outline:0}
.isl .seg:focus-visible{box-shadow:0 0 0 2px rgba(255,255,255,.6)}
.isl .seg.ico{width:40px;padding:0;justify-content:center}
.isl .seg svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:none}
.isl .seg .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.isl .seg .chev{width:12px;height:12px;stroke-width:2;color:rgba(255,255,255,.6);transition:transform .3s ease}
.isl .seg .pip{position:absolute;top:7px;right:9px;width:6px;height:6px;border-radius:50%;background:#8ec1ff}
.me.open .isl .seg[aria-expanded="true"]{color:#fff}
.isl .rule{width:1px;height:20px;background:rgba(255,255,255,.14);margin:0 2px}
/* THE DRAWER (the owner, 2026-09-15 23:2x: "grown from the capsule"; 2026-09-16 01:0x: "make the tabbing stay in place; just under it expands, not the actual element"): the island stays as it is, its size, place and spacing untouched; the bell and the name are its two tabs, the open one white and the other muted; the paper pane opens right under it, right-aligned and wider, and the glass is one shape: the pane's top edge meets the capsule's bottom edge, the capsule's bottom corners square at the join, one outline around both (the capsule's ring open at its foot, the pane's open at its head and drawn left of the capsule by its ::before); the chevron turns while open; the rows scroll (16:5x: "these long notifications go out of the screen and don't even scroll") */
.me.open .isl{position:relative;z-index:10;border-radius:22px 22px 0 0;box-shadow:inset 0 1px 0 rgba(255,255,255,.16)}
.me.open .isl::after{content:'';position:absolute;inset:0;border-radius:inherit;border:1px solid var(--isle-line);border-bottom-color:transparent;pointer-events:none}
.me.open #me .chev{transform:rotate(180deg)}
/* the open tab shows by its colour alone (the owner, 01:2x: "don't put a tab line under it"): the open one white, the other muted, the chevron turned */
.me.open .isl .seg{color:rgba(255,255,255,.55)}
.drawer{position:absolute;top:100%;right:0;z-index:9;min-width:100%;width:min(calc(100vw - 32px),360px);max-height:calc(100dvh - 136px - env(safe-area-inset-top));padding:var(--band);border-radius:var(--rim-r) 0 var(--rim-r) var(--rim-r);display:flex;flex-direction:column;background:var(--isle);-webkit-backdrop-filter:var(--isle-blur);backdrop-filter:var(--isle-blur);box-shadow:0 14px 34px -18px rgba(4,6,32,.7)}
.drawer::before{content:'';position:absolute;top:0;left:0;right:var(--cap,0px);height:var(--rim-r);border-top:1px solid var(--isle-line);border-left:1px solid var(--isle-line);border-top-left-radius:var(--rim-r);pointer-events:none}
.drawer::after{content:'';position:absolute;inset:0;border-radius:inherit;border:1px solid var(--isle-line);border-top-color:transparent;pointer-events:none}
.drawer .paper{min-height:0;display:flex;flex-direction:column;padding:8px;border-radius:var(--round);color:var(--ink);background:linear-gradient(180deg,#fff,#f8f8fc);box-shadow:0 0 0 1px rgba(35,36,103,.08),inset 0 1px 0 #fff}
.sheet{display:flex;flex-direction:column;min-height:0}
/* the first-open offer (push.js) keeps the paper-in-the-rim dress on the veil */
.offer .sheet{position:relative;width:min(100%,440px);color:var(--ink);border-radius:25px;padding:22px 22px 18px;z-index:9}
.offer .sheet::before{content:'';position:absolute;inset:-7px;border-radius:32px;background:var(--rim);backdrop-filter:var(--rim-blur);-webkit-backdrop-filter:var(--rim-blur);box-shadow:var(--rim-ring),var(--rim-cast);z-index:-2}
.offer .sheet::after{content:'';position:absolute;inset:0;border-radius:25px;background:linear-gradient(180deg,#fff,#f8f8fc);box-shadow:0 0 0 1px rgba(35,36,103,.08),inset 0 1px 0 #fff;z-index:-1}
.sheet[hidden]{display:none}
.sheet .h{font:500 13px/18px var(--sans);color:var(--mute);padding:10px 14px 6px}
.sheet .n{display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 10px;align-items:start;padding:10px 14px;border-radius:12px;text-decoration:none;color:var(--ink)}
.sheet .n:hover{background:var(--well)}
.sheet .n i{width:8px;height:8px;border-radius:50%;background:var(--sky);margin-top:7px}
.sheet .n i.off{background:var(--line)}
.sheet .n b{display:block;font:500 14px/20px var(--sans)}
.sheet .n small{display:block;font:400 12.5px/17px var(--sans);color:var(--mute)}
.sheet hr{border:0;border-top:1px solid var(--hair);margin:6px 8px}
.sheet .r{display:block;padding:12px 14px;border-radius:12px;font:500 14px/20px var(--sans);color:var(--ink);text-decoration:none}
.sheet .r:hover{background:var(--well)}
/* ── THE STAGE: otty left, the card ── */
.stage{flex:1;min-height:0;overflow:auto;display:grid;grid-template-columns:minmax(0,1fr);gap:0;padding:0 16px 24px;max-width:1760px;width:100%;margin:0 auto;align-content:start;padding-bottom:16px}
.otty{position:sticky;top:0;z-index:4;display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-areas:'mount say';align-items:center;column-gap:12px;margin:0 -16px;padding:6px 16px 12px;background:var(--field);background-size:100% 100dvh;background-position:0 -56px;background-repeat:no-repeat;--osz:72px}
.otty .barwrap{grid-area:bar}
.otty .say b{display:block;font:500 16px/22px var(--sans)}
.otty .say small{display:block;color:rgba(255,255,255,.72);font:400 13.5px/19px var(--sans);margin-top:2px}
.otty .pick{position:absolute;left:50%;bottom:-8px;transform:translateX(-50%);white-space:nowrap;font:500 13px/18px var(--sans);color:rgba(255,255,255,.7);text-decoration:none}
.shell{background:var(--rim);border-radius:var(--rim-r);padding:var(--band);box-shadow:var(--rim-ring),var(--rim-cast);width:min(100%,774px);margin:0 auto;min-width:0}
/* THE STAFF MARK (the owner, 2026-09-16): a slim band on the rim above the card while a staff access link's session stands (claims.staff): who the page is viewed as and until when; nothing else of the page changes */
.shell .staff{font:500 12px/16px var(--sans);letter-spacing:.02em;color:rgba(255,255,255,.88);text-align:center;padding:3px 12px 9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card{background:linear-gradient(180deg,#fff 0%,#f8f8fc 100%);border-radius:var(--card-r);box-shadow:var(--card-ring);padding:clamp(24px,3vw,40px) var(--gut) clamp(24px,3vw,40px);min-width:0}
/* the door card's shape before its words (the owner, 2026-09-15 22:4x: "a placeholder"): the module's paint replaces it */
.card .ske{display:grid;gap:14px;padding:6px 0 0}.card .ske i{display:block;border-radius:10px;background:#ececf4}.card .ske .tabs{height:22px;width:60%}.card .ske .nm{height:26px;width:55%}.card .ske .fld{height:48px;border-radius:12px}.card .ske .go{height:44px;width:40%;border-radius:999px}
/* ── CONTENT: no lines, space and alignment ── */
.who{margin-top:36px}
.who:first-child{margin-top:0}
.who .nm{font:600 23px/28px var(--sans);letter-spacing:-.02em;color:var(--ink)}
.who .fx{font:400 14px/20px var(--sans);color:var(--mute);margin-top:3px}
/* THE RHYTHM (the owner, 2026-09-16 02:1x: "make sure the spacing of items on the parent portal cards is pleasant to the eye on each device"): one 8 px scale on every card and width, one step tighter on a phone (the 599px block sets the three tokens): a row wears --row of padding (12, a phone 10), a kicker stands --kick over its rows' text (20 with its 8 under it, a phone 18 and 6; so 32 between sections, a phone 28), the head stands --head over the first kicker, a sheet's fields, a well or a bare row (24, a phone 20); the two columns' kickers keep their own --kick and the columns' box adds the rest, so a stacked second column keeps the section's gap */
:root{--row:12px;--kick:20px;--head:24px}
.gt{font:500 13px/18px var(--sans);color:var(--mute);margin:var(--kick) 0 8px}
.who > :is(.nm,.fx) + .gt,.ask + .gt{margin-top:var(--head)}
.who > :is(.nm,.fx) + .cols{margin-top:calc(var(--head) - var(--kick))}
.who > :is(.nm,.fx) + .ask{margin-top:var(--head)}
.kv{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;column-gap:20px;padding:var(--row) 0}
.kv .k{font:400 16px/22px var(--sans);color:var(--ink);min-width:0}
.kv .k small{display:block;min-height:18px;font:400 13px/18px var(--sans);color:var(--mute);margin-top:1px}
.kv .v{font:400 16px/22px var(--sans);color:var(--ink);text-align:right;white-space:nowrap}
.kv .v.num{font-family:var(--mono);font-variant-numeric:var(--tab);font-size:15px}
.kv .v .copy{display:inline-grid;place-items:center;width:28px;height:28px;margin-left:6px;border:0;background:none;border-radius:50%;color:var(--mute);cursor:pointer;vertical-align:middle}.kv .v .copy svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}.kv .v .copy:hover{background:rgba(27,28,74,.06);color:var(--ink)}.kv .v .copy.did{color:var(--ok)}.kv .v .copy .ck{display:none}.kv .v .copy.did .cp{display:none}.kv .v .copy.did .ck{display:block}
.kv .v.need{color:var(--warm);font-weight:500}
.kv .v.ok{color:var(--ok);font-weight:500}
.kv .v.mu{color:var(--mute)}
.ask{margin-top:16px;background:var(--well);border-radius:20px;padding:20px 20px 18px;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:16px;row-gap:14px}
.ask .t{font:500 16px/22px var(--sans);color:var(--ink)}
.ask .t small{display:block;font:400 13.5px/19px var(--sans);color:var(--mute);margin-top:3px}
.ask .amt{display:block;font-family:var(--mono);font-variant-numeric:var(--tab);font-size:28px;line-height:34px;letter-spacing:-.02em;color:var(--ink);margin-top:10px}
/* ── ACTS: one shape, the pill ── */
.go{display:inline-flex;align-items:center;gap:12px;background:var(--ink);color:#fff;font:500 15px/1 var(--sans);border-radius:999px;padding:8px 8px 8px 22px;white-space:nowrap;justify-self:end;text-decoration:none;box-shadow:4px 10px 24px -12px rgba(35,36,103,.55);transition:transform .5s cubic-bezier(.32,.72,0,1)}
.go:active{transform:scale(.98)}
.go i{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.14);display:inline-flex;align-items:center;justify-content:center;font-style:normal;font-size:16px}
.go.quiet{background:none;color:var(--ink);box-shadow:none;padding:0;gap:6px}
/* every quiet act's chevron steps right under the pointer, as the pending rows' does (the owner, 2026-09-15 18:5x: "this upload that you hover and its arrow moves, use that in all other places with an arrow") */
.go.quiet i{width:auto;height:auto;background:none;color:var(--mute);font-size:17px;transition:transform .2s ease,color .2s ease}
.go.quiet:hover i{transform:translateX(2px);color:var(--ink)}
/* ── BOTTOM BAR (frozen) ── */
/* the bar is the same light glass pill everywhere (the owner, 2026-09-15: "the same on desktop too, same elements, same colour"): white glass, our icons and words in ink, the open place a soft ink tint, the dot blue */
.barwrap{position:fixed;left:0;right:0;bottom:0;height:calc(76px + env(safe-area-inset-bottom));padding:6px 12px env(safe-area-inset-bottom);display:flex;align-items:center;justify-content:center;container-type:inline-size;z-index:5;background:none}
.bar.full{width:auto}
.bar>.nav{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:2px}
.bar>.sup,.bar>.rule,.bar>.act{flex:0 0 auto}
.sg,.sup{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;height:50px;min-width:0;padding:0 14px;border-radius:999px;font:500 11px/14px var(--sans);letter-spacing:.01em;color:rgba(255,255,255,.72);position:relative;text-align:center;text-decoration:none}
.sg{flex:0 0 auto;min-width:78px}
.sup{width:82px}
.sg svg,.sup svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
/* a place under the pointer: a soft tint rising in, the open one a shade deeper */
/* a place under the pointer is a lens (the owner, 2026-09-15: "the hover more glassy, like a magnifying glass, without much blue"): a lighter, clearer, slightly brighter glass with a fine ring; the same lens on the Back and Support rounds */
.bar .sg,.bar .sup{transition:box-shadow .2s ease,background .25s ease,color .2s ease}
.bar .sg:hover,.bar .sup:hover{background:rgba(20,21,58,.045)}
.bar .sg.on:hover,.bar .sup.open:hover{background:rgba(255,255,255,.7);box-shadow:var(--lens-ring)}
.sg.on,.sup.open{background:rgba(255,255,255,.1);color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}
.sg.on svg{stroke-width:1.8}
.sg>span,.sup>span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pip{position:absolute;top:8px;right:14px;width:6px;height:6px;border-radius:50%;background:#8ec1ff}
.rule{width:1px;height:28px;background:rgba(255,255,255,.18);margin:0 4px}
/* ── THE LEARNER: a wider box, and otty opens the character sheet ── */
/* one split on every page: a third to otty, two thirds to the white box */
.learn .otty .mount{cursor:pointer}
.veil{position:fixed;inset:0;background:rgba(10,11,40,.55);backdrop-filter:blur(6px);z-index:20;display:flex;align-items:flex-end;justify-content:center;padding:0}
.veil[hidden]{display:none}
/* ── THE ENROLMENT FLOW: one page, eight steps, the payment in the middle ── */
/* the white box is a frame: the rail at its head, the body scrolling between, the foot pinned at its bottom */
.flow .card{--pad:clamp(20px,3vw,40px);padding:0;display:flex;flex-direction:column;overflow:clip}
/* the rail: one thin track in eight parts that fills as the enrolment goes, each part named under it (only the open one named where the box is narrow); a filled part is the way back */
.flow .rail{flex:none;align-items:center;gap:6px;position:relative;z-index:2;display:block;padding:calc(var(--pad) - 4px) var(--pad) 8px}
.flow .body:first-child{padding-top:calc(var(--pad) - 4px)}
.flow .body{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--line) transparent;padding:14px var(--pad) 0}
/* the foot: back on the left, the one act on the right */
.flow .foot{flex:none;padding:12px var(--pad) calc(var(--pad) - 8px);position:relative;z-index:2;pointer-events:none;display:flex;justify-content:space-between;align-items:center;gap:16px;margin-top:36px}
.flow .foot>*{pointer-events:auto}
.flow .track{display:flex;gap:6px}
.flow .tk{flex:1;min-width:0;position:relative;display:flex;flex-direction:column;align-items:stretch;gap:9px;border:0;padding:0 0 4px;background:none;cursor:default;font:inherit}
.flow .tk i{display:block;height:4px;border-radius:999px;background:var(--line);position:relative;overflow:hidden}
.flow .tk i::before{content:'';position:absolute;inset:0;border-radius:999px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform .7s cubic-bezier(.2,.8,.2,1)}
.flow .tk.done i::before,.flow .tk.on i::before{transform:scaleX(1)}
/* the names show when every one fits under its own part on one line; otherwise only the open step's name, under its part (the rail's `names` class, measured by the page) */
.flow .tk span{font:400 12px/16px var(--sans);color:var(--faint);text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:none}
.flow .tk.done span{color:var(--ink-soft)}
.flow .tk.on span{color:var(--ink);font-weight:500}
.flow .tk.done{cursor:pointer}
.flow .rail.names .tk span{display:block}
.flow .rail:not(.names) .tk.on span{display:block;overflow:visible;position:absolute;top:13px;left:0}
.flow .rail:not(.names) .tk:nth-child(n+5).on span{left:auto;right:0}
.flow .rail:not(.names) .track{padding-bottom:20px}
/* the foot: the way back as a round, the one act as the pill, the quiet way beside it; on the payment the total stands where the act would, the act is the form's own */
.flow .foot .acts{display:flex;align-items:center;gap:22px;margin-top:0}
.flow .back,.barwrap > .back{width:46px;height:46px;border-radius:50%;border:0;background:#fff;box-shadow:inset 0 0 0 1.5px var(--line);display:grid;place-items:center;color:var(--ink);cursor:pointer;transition:box-shadow .3s}
.flow .back:hover{box-shadow:inset 0 0 0 1.5px var(--ink)}
.flow .back svg,.barwrap > .back svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.flow .paybox{background:var(--well);border-radius:20px;padding:18px 20px 20px;margin-top:20px}
.flow .paybox .fields{margin-top:16px}
.flow .paybox .fld input{box-shadow:none}
.flow .paybox .fld input:focus{box-shadow:inset 0 0 0 1.5px var(--ink)}
.go.wide{width:100%;justify-content:space-between;margin-top:18px;box-sizing:border-box}
.flow .step{margin-top:0;max-width:720px}
.flow .step[hidden]{display:none}
.flow .fx{max-width:56ch;text-wrap:pretty}
/* the learner's course, task and quiz heads carry a fact line, not a lede (the sweep, 2026-09-15): no measure on it */
.app.learn.flow .fx{max-width:none}
.fields{display:grid;grid-template-columns:1fr;gap:14px 16px;margin-top:20px}
/* a field's line: held under the input so the box never grows; the meta tone for a notice, the warm with the circle-i for a refusal, the green when it is right; the field keeps its ring in the warm, focused too */
.fld{display:grid;gap:6px;min-width:0;align-content:start}
.fld>span{font:500 13px/18px var(--sans);color:var(--mute)}
.fld input{height:46px;border:0;border-radius:14px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);padding:0 14px;font:400 16px/22px var(--sans);color:var(--ink);width:100%;font-variant-numeric:var(--tab)}
.fld input:focus{outline:0;box-shadow:inset 0 0 0 1.5px var(--ink)}
.fld input::placeholder{color:var(--faint)}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.chips.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(58px,1fr))}
.chip{height:40px;padding:0 16px;border:0;border-radius:999px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);font:500 14px/1 var(--sans);color:var(--ink);cursor:pointer;white-space:nowrap}
.chips.grid .chip{padding:0}
.chip.usual{box-shadow:inset 0 0 0 1.5px var(--faint)}
.chip.on{box-shadow:inset 0 0 0 1.5px var(--ink)}
.chip:disabled{opacity:.45;cursor:default}
.meta{font:400 13px/18px var(--sans);color:var(--mute);margin:10px 0 0}
.meta.ok{color:var(--ok);font-weight:500}
.flow .opts{display:grid;gap:8px;margin-top:8px}
.flow .opt{display:flex;align-items:flex-start;gap:12px;width:100%;min-width:0;padding:14px 16px;border:0;border-radius:14px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);color:var(--ink);text-align:left;cursor:pointer;font:inherit}
.flow .opt .t{flex:1;min-width:0;display:grid;gap:2px}
.flow .opt .title{font:500 16px/22px var(--sans);display:flex;flex-wrap:wrap;gap:0 8px;align-items:baseline}
.flow .opt .sub{font:400 13px/18px var(--sans);color:var(--mute);text-wrap:pretty}
.flow .opt .num{font:500 15px/22px var(--mono);font-variant-numeric:var(--tab);white-space:nowrap}
.flow .opt .num small{display:block;font:400 12px/16px var(--sans);color:var(--mute);text-align:right}
.flow .ring{flex:none;width:18px;height:18px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--faint);margin-top:2px}
.flow .opt.on{box-shadow:inset 0 0 0 1.5px var(--ink)}
.flow .opt.on .ring{box-shadow:inset 0 0 0 5.5px var(--ink)}
.flow .flag{font:500 11px/16px var(--sans);letter-spacing:.02em;color:var(--sky)}
/* the week cards, as approved on the pages kit (P4), in this design's colours */
.flow .head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:6px 16px;margin:22px 0 10px}
.flow .head .label{font:500 13px/18px var(--sans);color:var(--mute)}
.flow .key{display:flex;gap:14px;font:400 12.5px/18px var(--sans);color:var(--mute);align-items:center}
.flow .key span{display:inline-flex;align-items:center;gap:6px}
.flow .key i{width:10px;height:10px;border-radius:50%;background:var(--ink)}
.flow .key i.rec{background:#fff;box-shadow:inset 0 0 0 1.5px var(--ink)}
.flow .weeks{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}
.flow .wk{position:relative;display:flex;align-items:flex-start;gap:12px;width:100%;min-width:0;padding:12px 14px;border:0;border-radius:14px;background:#fff;color:var(--ink);box-shadow:inset 0 0 0 1px var(--line);text-align:left;cursor:pointer;font:inherit}
.flow .wk .cal{display:grid;grid-template-columns:repeat(5,12px);gap:3px;flex:none;padding-top:2px}
.flow .wk .day{padding-bottom:2px;font:500 9px/12px var(--sans);color:var(--faint);text-align:center}
.flow .wk .cell{width:12px;height:12px;border-radius:999px;background:var(--well)}
.flow .wk .cell.live{background:var(--ink)}
.flow .wk .cell.rec{background:#fff;box-shadow:inset 0 0 0 1.5px var(--ink)}
.flow .wk .t{flex:1;min-width:0;display:grid;gap:2px}
.flow .wk .nm{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 8px}
.flow .wk .name{font:600 16px/24px var(--sans);letter-spacing:-.01em;color:var(--ink)}
.flow .wk .say{font:400 12.5px/17px var(--sans);color:var(--ink-soft);text-wrap:pretty}
.flow .wk .price{margin-top:2px;font:500 12.5px/20px var(--sans);color:var(--ink)}
.flow .wk .price b{font:500 13px/20px var(--mono);font-variant-numeric:var(--tab)}
.flow .wk .r{flex:none;display:grid;justify-items:end;padding-top:3px}
.flow .wk.on{box-shadow:inset 0 0 0 1.5px var(--ink)}
.flow .wk.on .ring{box-shadow:inset 0 0 0 5.5px var(--ink)}
/* the payment */
.flow .lines{margin-top:12px}
.flow .ln{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;column-gap:20px;padding:10px 0}
.flow .ln .k{font:400 16px/22px var(--sans)}
.flow .ln .k small{display:block;font:400 13px/18px var(--sans);color:var(--mute);margin-top:1px}
.flow .ln .num{font:400 15px/22px var(--mono);font-variant-numeric:var(--tab);white-space:nowrap;text-align:right}
.flow .ln.total{margin-top:6px}
.flow .ln.total .k{font-weight:500}
.flow .ln.total .num{font-size:22px;line-height:28px;letter-spacing:-.02em}
.flow .said{display:flex;gap:10px;align-items:baseline;background:var(--well);border-radius:16px;padding:14px 18px;margin-top:20px;font:400 15px/22px var(--sans)}
.flow .said b{font-weight:500;color:var(--ok);white-space:nowrap}
/* ── DOCUMENTS ── */
/* THE DOCUMENTS STEP (the owner, 2026-09-16 00:2x: "tabs like cards with the ID images; opened, they show the captured data"; 18:4x SAST: "I do not understand why half of the screen is not used for this; this needs a better UX ... and better design"): the slots as picture cards (the file's picture or the slot's drawing, the name, the one status word toned: verified in the green, admissions in the sky, resend and needed in the warm, none muted; the picked one ringed in the ink on white); the picked slot's panel: its head (the name, its line), the facts line, the file as a quiet row (the glyph, the name with its kind and size, the download arrow), the read rows as the design's kv rows with the marks as tone glyphs at the value's end and the mark's word under a differing value, the reason as one notice row, the acts at the foot; narrow, the cards in a row and the panel under them with the read folded under its kicker; wide, the 1400px block below */
.dcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin:10px 0 20px}
.dcard{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;padding:10px;border-radius:16px;background:var(--well);border:0;text-align:left;cursor:pointer;font:inherit;color:var(--ink);box-shadow:inset 0 0 0 1.5px transparent;transition:box-shadow .2s,background .2s}
.dcard:hover{background:color-mix(in srgb,var(--ink) 7%,#fff)}.dcard.on{background:#fff;box-shadow:inset 0 0 0 1.5px var(--ink)}
.dcard .pic{aspect-ratio:4/3;border-radius:10px;background:#fff;overflow:hidden;display:grid;place-items:center;box-shadow:inset 0 0 0 1px rgba(27,28,74,.06)}.dcard.on .pic{background:var(--well)}
.dcard .pic img{width:100%;height:100%;object-fit:cover}.dcard .pic img.sample{width:64px;height:auto;object-fit:contain}
.dcard .t{font:500 14px/18px var(--sans);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dcard .s{font:500 13px/18px var(--sans);color:var(--warm)}.dcard .s.ok{color:var(--ok)}.dcard .s.chk{color:var(--sky)}.dcard .s.mu{color:var(--mute)}
.doc{padding:4px 0 0;min-width:0}
.doc .dh .k{display:block;font:500 17px/24px var(--sans);color:var(--ink)}
.doc .dh .k small{display:block;font:400 13px/18px var(--sans);color:var(--mute);margin-top:2px;max-width:60ch;text-wrap:pretty}
.doc .facts{font:400 13px/18px var(--sans);color:var(--mute);margin-top:6px}
.doc .track{height:4px;border-radius:999px;background:var(--well);overflow:hidden;margin-top:14px}
.doc .track i{display:block;height:100%;border-radius:999px;background:var(--ink);transition:width .3s cubic-bezier(.2,.8,.2,1)}
.doc .line{font:400 13px/18px var(--sans);color:var(--mute);text-wrap:pretty;margin-top:14px}
.doc .line.warn{color:var(--warm);font-weight:500}
/* the acts as the wizard's own pills (the owner, 2026-09-16 19:0x SAST: "the buttons are like text links; they are not nice"): the ink pill for the act the slot asks for, the pale one (white, the Back round's ring, the ink ring on hover) for the other choice, at the row's size */
.go.pale{background:#fff;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--line);transition:box-shadow .3s}
.go.pale:hover{box-shadow:inset 0 0 0 1.5px var(--ink)}
.go.pale i{background:var(--well);color:var(--ink)}
.doc .go{cursor:pointer;border:0;height:42px;padding:0 7px 0 18px;font-size:14px}
.doc .go:not(:has(i)){padding:0 18px}
.doc .go i{width:28px;height:28px;font-size:15px}
.doc .taps{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;margin-top:14px}
.doc .taps.end{margin-top:20px}
.who[data-locked] .taps.end{display:flex;flex-wrap:wrap;gap:10px 12px;margin-top:20px}
.doc .taps span{font:400 13px/18px var(--sans);color:var(--mute)}
.doc .fold{cursor:pointer;border:0;background:none;padding:0}
.doc.busy .taps{opacity:.5;pointer-events:none}
.doc .file{display:grid;grid-template-columns:22px minmax(0,1fr) auto;column-gap:12px;align-items:center;padding:8px 0;margin-top:10px;text-decoration:none;color:var(--ink)}
.doc .file .fi{display:grid;place-items:center;color:var(--mute)}.doc .file .fi svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.doc .file .fn{display:flex;align-items:baseline;gap:8px;min-width:0;font:400 15px/20px var(--sans)}
.doc .file .fn b{font-weight:400;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.doc .file .fn small{flex:none;font:400 12.5px/17px var(--sans);color:var(--mute)}
.doc .file .dl{font-style:normal;color:var(--mute);font-size:17px;line-height:22px;transition:transform .2s ease,color .2s ease}
.doc a.file:hover .dl{transform:translateY(2px);color:var(--ink)}
.doc .read .fold{display:flex;align-items:center;gap:6px;width:100%;text-align:left;margin:var(--kick) 0 2px;font:500 13px/18px var(--sans);color:var(--mute)}
.doc .read .fold small{font:inherit;color:inherit}.doc .read .fold small.warm{color:var(--warm)}
.doc .read .fold i{font-style:normal;font-size:17px;line-height:18px;color:var(--mute);transition:transform .2s}
.doc .read[data-open=true] .fold i{transform:rotate(90deg)}
.doc .read[data-open=false] .rows{display:none}
/* a read value may wrap (a school's name): the value's track is a share of the row, never the auto track a wrapping value collapses */
.kv.rd{grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);padding:9px 0;align-items:start}
.kv.rd .v{white-space:normal;overflow-wrap:anywhere}
.kv.rd .v em{font-style:normal;font-weight:600;margin-left:8px;color:var(--mute)}
.kv.rd[data-mark=ok] .v em{color:var(--ok)}
.kv.rd[data-mark=differs] .v em,.kv.rd[data-mark=near] .v em{color:var(--warm)}
.kv.rd[data-mark=differs] .v small,.kv.rd[data-mark=near] .v small{color:var(--warm);font-weight:500}
.doc .read .marks{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:4px 18px;align-items:baseline;padding:9px 0;font:400 15px/20px var(--sans)}
.doc .read .marks b{grid-column:1/-1;font:500 13px/18px var(--sans);color:var(--mute)}
.doc .read .marks span:nth-child(3n){font-variant-numeric:var(--tab);text-align:right}
.doc .read .marks span:nth-child(3n+1){color:var(--mute)}
.doc .notice{margin:14px 0 0}
.doc .notice>span{min-width:0}
/* the subjects */
.flow .list{margin:6px 0 0;padding:0;list-style:none;columns:1}
.flow .list li{display:flex;gap:12px;align-items:baseline;padding:7px 0;font:400 16px/22px var(--sans);break-inside:avoid}
.flow .list li i{font:500 12px/18px var(--mono);color:var(--faint);font-style:normal;min-width:18px}
.flow .check{display:flex;gap:12px;align-items:flex-start;margin-top:20px;cursor:pointer;font:400 15px/22px var(--sans);color:var(--ink)}
.flow .check .box{flex:none;width:22px;height:22px;border-radius:7px;box-shadow:inset 0 0 0 1.5px var(--faint);display:grid;place-items:center;color:#fff;font-size:13px;margin-top:0}
.flow .check.on .box{background:var(--ink);box-shadow:none}
.flow .foot .go.quiet{cursor:pointer;border:0;background:none;font:500 15px/1 var(--sans)}
.flow .foot .go{cursor:pointer;border:0}
.flow .foot .go:disabled{opacity:.4;cursor:default}
.flow .kv .v .go.quiet{cursor:pointer;border:0;background:none;font:500 15px/1 var(--sans)}
.flow .done .kv{padding:12px 0}
.flow button.go{border:0;font:500 15px/1 var(--sans);cursor:pointer}
.flow button.check{border:0;background:none;padding:0;text-align:left;font:400 15px/22px var(--sans);color:var(--ink)}
/* ── THE DOORS: the sign-in card centred in the white box, the ways in on the bar ── */
/* the box keeps one height whatever the way or the moment */
.door .card{justify-content:center;min-height:420px;display:flex;flex-direction:column}
/* the mailed link's landing (auth: Is that you?, Done, an outcome) sizes its card to its content: it changes no way, so it keeps no height (the owner, 2026-09-16: the 1440 card stood at the door's height with an empty band) */
.door.auth .card{min-height:0}.door.auth .card .who{flex:none}
.door .who{width:100%;margin:0 auto;max-width:none}
.door .fields{margin-top:22px}
.door .go.wide{margin-top:16px;border:0;cursor:pointer;font:500 15px/1 var(--sans)}
.door .ways{margin-top:18px}
.door .meta a{color:inherit}
.isl.one{text-decoration:none;color:#fff}
.isl.one .seg{display:inline-flex;align-items:center;gap:6px;padding:0 10px 0 16px;height:36px;font:500 14px/1 var(--sans);color:#fff}
.isl.one .chev{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;opacity:.7}
/* ── ROWS THAT OPEN: an invoice or a receipt, the figure with its state under it, the chevron at the end ── */
.kv.link{text-decoration:none;color:inherit;grid-template-columns:minmax(0,1fr) auto 12px;align-items:start}
.kv.link::after{content:'›';color:var(--faint);font-size:17px;line-height:22px;justify-self:end}
.kv .v small{display:block;font:400 12.5px/17px var(--sans);color:var(--mute);margin-top:1px}
.kv .v small.ok{color:var(--ok);font-weight:500}
.kv .v small.need{color:var(--warm);font-weight:500}
.seg:focus{outline:none}
.seg:focus-visible{outline:2px solid rgba(255,255,255,.7);outline-offset:-2px;border-radius:999px}
/* ── LEARNER TABS: one per learner, only where the family has more than one; the ink slides under the open name ── */
.tabs{position:relative;display:flex;margin:-4px 0 24px}
.tab{flex:1;min-width:0;border:0;background:none;padding:6px 8px 12px;font:500 15px/20px var(--sans);color:var(--faint);cursor:pointer;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .3s}
.tab.on{color:var(--ink)}
.tabs .ink{position:absolute;bottom:0;height:3px;border-radius:999px;background:var(--ink);transition:left .45s cubic-bezier(.2,.8,.2,1),width .45s cubic-bezier(.2,.8,.2,1)}
.who.tabbed{margin-top:0}
.flow .foot a.back{text-decoration:none}
/* an invoice row: what and for whom, the figure with its state, the last column the act — the Pay pill on an open one, the way into the receipt on a paid one; one set of columns for every row */
.kv.inv{grid-template-columns:minmax(0,1fr) auto 92px;column-gap:18px;align-items:center;text-decoration:none;color:inherit;padding:var(--row) 0}
.kv.inv .a{display:flex;justify-content:flex-end;align-items:center;color:var(--faint);font-size:18px;line-height:22px}
.kv.inv .a .go{padding:7px 7px 7px 18px;font-size:14px}
.kv.inv .a .go i{width:28px;height:28px;font-size:15px}
.paybox .kv{padding:8px 0}
.paybox .meta{margin-top:12px}
/* a row that is not yet open: the same row, quiet, no act */
.kv.off .k{color:var(--mute)}
.kv .k small.num{font-family:var(--mono);font-variant-numeric:var(--tab)}
.flow .fields+.meta b{font-weight:500;color:var(--ink)}
/* a row that is an act: the word and its chevron, nothing else */
.kv.act{display:flex;align-items:center;gap:6px;font:500 16px/22px var(--sans);color:var(--ink);text-decoration:none}
.kv.act i{font-style:normal;color:var(--mute);font-size:17px}
/* a phone number always has its country code chosen beside it */
.fld select{height:46px;border:0;border-radius:14px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);padding:0 40px 0 14px;font:400 16px/22px var(--sans);color:var(--ink);width:100%;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6c93' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;background-size:18px}
.fld select:focus{outline:0;box-shadow:inset 0 0 0 1.5px var(--ink)}
/* the way to one more (a learner) is the last tab: a plus, never a row under every tab */
/* the add control is a tab of the row: the plus glyph alone, the tabs' muted ink, no circle, ink on hover */
.tabs.one{justify-content:flex-end}
.tab.plus{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;padding-left:14px;padding-right:14px;text-decoration:none;color:var(--mute);transition:color .2s}
.tab.plus svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round}
.tab.plus:hover{color:var(--ink)}
.marks .ask{margin-top:14px}
.kv.mk{grid-template-columns:minmax(0,1fr) auto;row-gap:8px;padding:11px 0}
.kv.mk .track{grid-column:1/-1;height:4px;border-radius:999px;background:var(--well);overflow:hidden}
.kv.mk .track i{display:block;height:100%;border-radius:999px;background:var(--ink);transition:width .8s cubic-bezier(.2,.8,.2,1)}
.kv.mk .flag{font:500 11px/16px var(--sans);color:var(--sky);margin-left:6px;vertical-align:1px}
/* the week as a table: days across, periods down; today's column lit, the next lesson ringed; wider than a phone inside its own scroll */
.ttwrap{overflow-x:auto;margin:6px 0 0;padding:0 0 6px}
.tt{display:grid;gap:5px;min-width:600px;grid-template-columns:auto repeat(var(--n,5),minmax(104px,1fr))}
.tt .th{font:500 12px/16px var(--sans);color:var(--faint);text-align:center;padding:2px 0 6px}
.tt .th.now{color:var(--ink)}
.tt .tm{font:400 12px/16px var(--mono);font-variant-numeric:var(--tab);color:var(--mute);align-self:start;padding:9px 8px 0 0}
.tt .cell{background:var(--well);border-radius:10px;padding:8px 10px;min-height:52px;display:grid;align-content:start;gap:1px}
.tt .cell b{font:500 13px/17px var(--sans);color:var(--ink)}
/* a lesson's name is its course's door (the owner, 2026-09-15 23:0x: "can these courses link to the corresponding course page?") */
.tt .cell b a{color:inherit;text-decoration:none}.tt .cell b a:hover{text-decoration:underline;text-underline-offset:2px}
.tt .cell small{font:400 11.5px/15px var(--sans);color:var(--mute)}
/* the lesson's hour in every box (the owner, 2026-09-15 17:0x: "add the exact time from and to on each box, elegantly"): one faint tabular line under the name */
.tt .cell .tm{display:block;font:400 11.5px/15px var(--sans);color:var(--faint);font-variant-numeric:tabular-nums;letter-spacing:.01em;margin-top:1px}
.tt .cell.now{background:#e9e9f2}
.tt .cell.next{box-shadow:inset 0 0 0 1.5px rgba(35,36,103,.4)}
.tt .cell.off{background:none;box-shadow:none;border-color:transparent}
/* the lessons by the clock: done ones quiet, the one on now filling as it goes, the ones to come as they are */
/* what is past steps back further (the owner, 2026-09-15 17:2x: "make the current day and future events more distinguished compared to previous ones"): a paler well, the faint ink; today's and what comes keep the well and the ink with a hairline edge */
.tt .cell:not(.past):not(.brk){box-shadow:inset 0 0 0 1px rgba(35,36,103,.07)}
.tt .cell.past{background:#f8f8fb}
.tt .cell.past b{color:var(--faint);font-weight:400}
.tt .cell.past small{color:#b3b4c9}
/* the lesson on now: the cell fades from the top as the lesson goes — the part that has passed lightens toward the done tone, the rest keeps the well; its way in bolder */
.tt .cell.live{position:relative;overflow:hidden;border:1.5px solid var(--ink);padding:6.5px 8.5px}
.tt .cell.live::before{content:'';position:absolute;left:0;right:0;top:0;height:var(--p,0%);background:linear-gradient(180deg,rgba(255,255,255,.75),rgba(255,255,255,.75) calc(100% - 10px),rgba(255,255,255,0));transition:height 1s linear;pointer-events:none}
.tt .cell.live .mini{font-weight:600}
.tt .cell.live b,.tt .cell.live small{position:relative}
/* the lesson's own way in, inside its cell: Watch on a done one, Join on the one now and the next */
.tt .cell .mini{position:relative;margin-top:6px;font:500 12px/16px var(--sans);color:var(--ink);text-decoration:none;display:inline-flex;align-items:center;gap:5px;justify-self:start}
.tt .cell .mini svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linejoin:round;stroke-linecap:round}
.tt .cell.past .mini svg{fill:currentColor;stroke:none}
.tt .cell.past .mini{color:var(--ink-soft)}
/* the work's groups carry their count; overdue and today read warm */
.work .gt .n{font:400 12px/18px var(--mono);color:var(--faint);margin-left:8px}
.work .kv .v.need{color:var(--warm);font-weight:500}
.tt .cell .short{display:none}
/* a course row: name and teacher, the term average as the figure, the way in; the bar is the average */
.kv.course{grid-template-columns:minmax(0,1fr) auto 12px;row-gap:8px;align-items:center;text-decoration:none;color:inherit;padding:11px 0}
.kv.course .a{color:var(--faint);font-size:17px;line-height:22px;justify-self:end}
.kv.course .track{grid-column:1/-1;height:4px;border-radius:999px;background:var(--well);overflow:hidden}
.kv.course .track i{display:block;height:100%;border-radius:999px;background:var(--ink)}
.kv.course .v small{display:block;font:400 11.5px/15px var(--sans);color:var(--mute);text-align:right;margin-top:1px}
.kv.course .flag{font:500 11px/16px var(--sans);color:var(--sky);margin-left:6px;vertical-align:1px}
.gt.need{color:var(--warm)}
/* a question: its words, then the answers as choices */
.q{margin-top:18px}
.q .qt{font:500 16px/22px var(--sans);color:var(--ink);margin-bottom:8px}
.paybox.up{padding:8px 20px 12px}
.paybox.up .kv{padding:10px 0}
/* a course's modules: each one folds; its items are rows with their kind and state */
.mod{margin-top:22px}
.mod summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;user-select:none;-webkit-user-select:none}
.mod summary::-webkit-details-marker{display:none}
/* one chevron, one size (the owner, 2026-09-16 00:3x: "arrows too much and two sizes"): the module's disclosure is the list's small chevron at the row's end, after its track */
.mod summary::after{content:'';flex:0 0 auto;width:6px;height:6px;border-right:1.5px solid var(--mute);border-bottom:1.5px solid var(--mute);transform:rotate(-45deg);margin:0 4px 0 10px;transition:transform .3s}
.mod[open] summary::after{transform:rotate(45deg);margin-top:-3px}
.mod summary .gt{margin:0}
.mod .gt .n{font:400 12px/18px var(--mono);color:var(--faint);margin-left:8px}
.kv.it.later .k{color:var(--mute)}
.kv.it.next .k{font-weight:500}
/* the courses on a wide screen: the list at the left, the open course at the right, one box */
.card.wide .body{padding-top:calc(var(--pad) - 4px)}
.split{display:grid;grid-template-columns:minmax(300px,2fr) minmax(0,3fr);gap:0 48px;align-items:start}
.split .side .kv.course.on{background:var(--well);border-radius:14px;padding:11px 14px;margin:0 -14px}
.split .main .course-page .nm{margin-top:0}
/* a module's items: the kind's glyph before the title, a sub-header as a small label between */
/* the items as tiles (the owner, 2026-09-16 00:0x: "these open, done rows are bare and the page is quite empty; redesign it better"): a soft well each, the kind's glyph in a white disc, the state a chip, the module's progress a track in its head, a lesson's label a kicker on a hairline */
.mod .sub{font:500 11px/16px var(--sans);color:var(--faint);letter-spacing:.06em;text-transform:uppercase;margin:18px 0 4px;padding-top:10px;border-top:1px solid #ececf4}
.mod .kv.it{background:var(--well);border-radius:14px;padding:12px 14px;margin:8px 0 0;border:0;transition:background .2s}
.mod a.kv.it:hover{background:color-mix(in srgb,var(--ink) 7%,#fff)}
.mod .kv.it .k{grid-template-columns:36px minmax(0,1fr);column-gap:12px;align-items:center}
.mod .kv.it .ki{width:36px;height:36px;border-radius:50%;background:#fff;box-shadow:inset 0 0 0 1px rgba(27,28,74,.08);display:grid;place-items:center}
.mod .kv.it .ki svg{width:18px;height:18px}
.mod .kv.it .k small{grid-column:2;margin-top:1px}
.mod .chip{display:inline-flex;align-items:center;height:26px;padding:0 11px;border-radius:999px;font:500 13px/1 var(--sans);white-space:nowrap;background:rgba(27,28,74,.06);color:var(--ink)}
.mod .chip.ok{background:rgba(27,107,74,.1);color:var(--ok)}.mod .chip.mu{color:var(--mute)}.mod .chip.warm{background:rgba(179,38,30,.08);color:var(--warm)}
.mod summary{padding:4px 0}
.mod summary .track{flex:0 0 72px;height:4px;border-radius:999px;background:rgba(27,28,74,.1);overflow:hidden;margin-left:auto}.mod summary .track b{display:block;height:100%;border-radius:999px;background:var(--ink)}
.kv.it .k{display:grid;grid-template-columns:22px minmax(0,1fr);column-gap:10px;align-items:start}
.kv.it .k small{grid-column:2}
.kv.it .ki{display:grid;place-items:center;height:22px}
.kv.it .ki svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;color:var(--mute)}
.kv.it.later .ki svg{color:var(--faint)}
/* a Canvas body on this design: the kicker, the bands, the lead, the numbered hand lines, media and file cards, figures */
/* a course page fills the white box (the owner, 2026-09-15 16:5x: "courses are not taking the whole screen"); the reading cap of 70ch is gone and a table takes the row */
.prose{font:400 15px/23px var(--sans);color:var(--ink);margin-top:18px;max-width:none;overflow-wrap:anywhere;min-width:0}
.prose table{width:100%;border-collapse:collapse;width:100%!important;height:auto!important;table-layout:auto;font:inherit;color:var(--ink)}
.prose>*+*{margin-top:8px}
.prose p{margin:0}
.prose .kicker{font:500 12px/16px var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--mute)}
.prose .band{font:600 18px/24px var(--sans);letter-spacing:-.01em;color:var(--ink);margin-top:24px}
.prose .kicker+.band{margin-top:6px}
.prose .lead{font-weight:500}
.prose .hand{padding-left:22px;text-indent:-22px}
.prose .hand+.hand{margin-top:2px}
.prose figure{margin:12px 0 0}
.prose .media .frame{position:relative;aspect-ratio:16/9;border-radius:16px;background:linear-gradient(180deg,#25265a,#141539);overflow:hidden}
.prose .media .play{position:absolute;inset:0;display:grid;place-items:center}
.prose .media .play::after{content:'';width:64px;height:64px;border-radius:50%;background:rgba(255,255,255,.14);box-shadow:inset 0 0 0 1px rgba(255,255,255,.3);backdrop-filter:blur(8px);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 6.5v11l9-5.5z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:55% 50%;background-size:30px}
.prose .media figcaption{font:400 12.5px/17px var(--sans);color:var(--mute);margin-top:8px;display:flex;flex-wrap:wrap;gap:8px}
.prose a.ccard{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:14px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);text-decoration:none;color:var(--ink);margin-top:10px}
.prose a.ccard .glyph{flex:none;width:22px;height:22px;color:var(--mute)}
.prose a.ccard .glyph svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.prose a.ccard .c-t{flex:1;min-width:0;display:grid}
.prose a.ccard .c-title{font:500 15px/20px var(--sans)}
.prose a.ccard .c-meta{font:400 12.5px/17px var(--sans);color:var(--mute)}
.prose a.ccard .c-word{font:500 14px/20px var(--sans);color:var(--ink)}
.prose a.ccard .c-word::after{content:' ›';color:var(--mute)}
.mod summary:focus{outline:none}
.mod summary:focus-visible{outline:2px solid var(--ink);outline-offset:4px;border-radius:6px}
.split .side .nm{margin-top:0}
/* the door's own moments: the last account as one row with its pill, the wait as a line with the scanning bar */
.lastrow{display:flex;align-items:center;gap:14px;width:100%;margin-top:22px;padding:14px 16px;border:0;border-radius:16px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);cursor:pointer;text-align:left;font:inherit;color:var(--ink)}
.lastrow .who{flex:1;min-width:0;display:grid;grid-template-columns:minmax(0,1fr)}
.lastrow .who b,.lastrow .who small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lastrow .pill{flex:none;white-space:nowrap;font:500 12px/1 var(--sans);color:var(--ink);background:var(--well);border-radius:999px;padding:6px 10px}
.lastrow .who b{font:500 16px/22px var(--sans)}
.lastrow .who small{font:400 13px/18px var(--sans);color:var(--mute)}
.lastrow i{font-style:normal;color:var(--mute);font-size:18px}
.moment{margin-top:22px}
.moment p{margin:0 0 10px;font:400 14px/20px var(--sans);color:var(--mute)}
.scanbar{position:relative;height:4px;border-radius:999px;background:var(--well);overflow:hidden}
.scanbar i{position:absolute;top:0;bottom:0;width:38%;border-radius:999px;background:var(--ink);animation:scan 1.6s cubic-bezier(.4,0,.6,1) infinite alternate}
@keyframes scan{from{left:-38%}to{left:100%}}
.door .fx b{font-weight:500;color:var(--ink)}
.door .go.wide:disabled{opacity:.7;cursor:default}
/* the door as the live door stands: the statement at the left, the box in the middle, otty at the right with his words in the runtime's glass bubble only when he speaks (the OTTY AT THE DOOR block below); no bar */
.door .shell{align-self:center;justify-self:center;width:min(100%,540px)}
.door .statement{color:#fff;align-self:center}
.door .eyebrow{display:block;font:500 12px/16px var(--sans);letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.6)}
.door .statement h1{margin:14px 0 14px;font:600 clamp(30px,3.2vw,42px)/1.12 var(--sans);letter-spacing:-.025em}
.door .statement p{margin:0;font:400 17px/26px var(--sans);color:rgba(255,255,255,.75);max-width:26ch}
.door .card .who{flex:1}
.door .terms{margin:22px 0 0;color:var(--mute)}
.door .terms a{color:var(--mute)}
/* the ways in as the learner tabs: names with the ink under the open one; the box one height whatever the way */
.door .tabs.ways{margin:-4px 0 22px}
.door .tabs.ways .tab{text-decoration:none}
/* the enrol door, laid out as the live door: the statement over the week at the left (three parts of five), the compact card at the right, the terms under it; no otty, the chat bubble instead */
.enroldoor .stage{display:grid;grid-template-columns:minmax(0,1fr) minmax(480px,820px);grid-template-rows:auto 1fr;gap:0 clamp(24px,4vw,56px);align-items:start;align-content:start;overflow:auto;padding-top:16px;padding-bottom:24px}
.enroldoor .statement{grid-column:1;grid-row:1;color:#fff;padding:24px 0 22px}
.enroldoor .eyebrow{display:block;font:500 12px/16px var(--sans);letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.6)}
.enroldoor h1{margin:14px 0 12px;font:600 clamp(30px,3.4vw,44px)/1.1 var(--sans);letter-spacing:-.025em}
.enroldoor .statement p{margin:0;font:400 17px/26px var(--sans);color:rgba(255,255,255,.75)}
.enroldoor .shell{grid-column:2;grid-row:1/3;align-self:start;width:100%;margin:0}
/* the enrol form on one screen: a tighter rhythm, six rows of fields */
.enroldoor .card{display:block;min-height:0;overflow:visible;padding:28px clamp(20px,3vw,36px) 26px}
/* the code piece and the offer at a hand's width inside the wide card (the owner, 2026-09-16 08:0x SAST: "Enter your code on desktop is a bit stretched") */
.enroldoor #code,.enroldoor #offer{max-width:480px}
.enroldoor .card .terms{margin:22px 0 0;color:var(--mute);margin-top:14px}
.enroldoor .card .terms a{color:var(--mute)}
.enroldoor .tabs.ways{margin:-4px 0 22px}
.enroldoor .tabs.ways .tab{text-decoration:none}
.enroldoor .go.wide{margin-top:16px}
.enroldoor .fields{gap:8px 16px;margin-top:8px}
.enroldoor .gt{margin:16px 0 2px}
.enroldoor .fields .fld.code{grid-column:1}
.enroldoor .barwrap{display:none}
.dwm .cel.lv .fw{color:rgba(255,255,255,.8)}
.dwm .facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:14px;padding-top:12px;box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}
.dwm .facts span{display:grid;gap:3px;font:400 12.5px/17px var(--sans);color:#fff;min-width:0}
.dwm .facts b{font:500 9.5px/12px var(--sans);letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.55)}
.isl.two{display:inline-flex}
.isl.two .seg{display:inline-flex;align-items:center;gap:8px;padding:0 14px;height:36px;font:500 14px/1 var(--sans);color:#fff;text-decoration:none}
.isl.two .seg svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
/* the chat bubble: the bar's glass as one round, at the foot of the page where the bar would be */
.chatbubble{position:fixed;right:20px;bottom:calc(20px + env(safe-area-inset-bottom));width:56px;height:56px;border-radius:50%;display:grid;place-items:center;background:var(--isle);backdrop-filter:var(--isle-blur);-webkit-backdrop-filter:var(--isle-blur);box-shadow:var(--isle-ring);color:#fff;z-index:7;transition:transform .5s cubic-bezier(.2,.8,.2,1)}
.chatbubble:hover{transform:translateY(-2px)}
.chatbubble svg{width:26px;height:26px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
/* the enrol door is a page that scrolls, not the fixed frame: the box and the week take their own height, nothing goes under anything */
.app.enroldoor{height:auto;min-height:100dvh;overflow:auto}
.app.enroldoor .stage{flex:none;height:auto;min-height:0;overflow:visible}
.app.enroldoor .shell{min-height:auto;display:block}
.app.enroldoor .card{flex:none;min-height:auto;height:auto;overflow:visible}
/* the week is the door's background: a faint calendar behind the words and the box, a hint of school, nothing to read */
.enroldoor .dwm{position:fixed;left:50%;top:58%;width:max(118vw,1000px);transform:translate(-50%,-50%) rotate(-7deg);z-index:0;pointer-events:none;user-select:none;color:#fff}
.enroldoor .dwm .cap,.enroldoor .dwm .facts,.enroldoor .dwm .sj .short{display:none}
.enroldoor .dwm .g{display:grid;grid-template-columns:auto repeat(5,minmax(0,1fr));gap:12px}
.enroldoor .dwm .hd{font:500 12px/16px var(--sans);letter-spacing:.14em;color:rgba(255,255,255,.09);padding:0 0 4px 14px}
.enroldoor .dwm .pr{font:400 13px/16px var(--mono);color:rgba(255,255,255,.09);padding:16px 14px 0 0;font-variant-numeric:var(--tab)}
.enroldoor .dwm .cel{display:grid;gap:6px;align-content:start;padding:12px 16px;border-radius:16px;background:rgba(255,255,255,.014);box-shadow:inset 0 0 0 1px rgba(255,255,255,.03);min-height:clamp(64px,9vh,92px)}
.enroldoor .dwm .cel.lv{background:rgba(255,255,255,.032)}
.enroldoor .dwm .sj{font:500 clamp(13px,1.1vw,16px)/1.25 var(--sans);color:rgba(255,255,255,.10)}
.enroldoor .dwm .fw{font:500 9.5px/12px var(--sans);letter-spacing:.14em;color:rgba(255,255,255,.10)}
.enroldoor .statement,.enroldoor .shell{position:relative;z-index:1}
/* ══ OTTY AT THE DOOR as the live door draws him (src/styles.scss .dotty and .obubble, src/app/door/door.ts fit): his column is a cell of the door's grid, never a layer over it; his box stands out of the flow at the size the shell writes (--fig, the live door's MAX OTTY by the drawn body: the cell's height, or the cell's width less the desk's gutters at his widest pose, at most 600px), his feet on the cell's foot (52 of the frame's 600 rows under them, so the box drops by that much); the runtime's stage over his words, so the sign-in's jump crosses them ══ */
.door .otty{--band:top;--feet:0.0867;--fig:200px;position:relative;z-index:5;pointer-events:none;display:block;min-height:100px;height:auto;align-self:stretch;justify-self:stretch;margin:0;padding:0;background:none;container-type:normal;overflow:visible}
.door .otty .mount{position:absolute;left:calc(var(--fig) * -0.18);bottom:calc(var(--fig) * var(--feet) * -1);width:var(--fig);height:auto;aspect-ratio:1;margin:0;cursor:default}
.door .otty .mount .otty-stage{z-index:5}
/* his words on the field's own glass, the live door's bubble: the faint white fill, the field blurred 14px behind, the 1px white ring at 18 percent as the blur layer's outline, the tail cut from the same glass and joined open under the edge, the shadow cast by the blur layer with the tail's triangle cut out of it; the runtime writes the words and hides the box when he has nothing to say; over his head from 740px, at his right on a phone */
/* the door's bubble in the app's glass (the owner, 2026-09-15 23:0x: "the speech bubble a bit higher and aligned with the glass design of the other pages; the slip behind him is fine") */
.door .otty .say{position:absolute;left:50%;right:auto;top:auto;bottom:calc(100% + 48px);z-index:4;display:block;width:max-content;max-width:min(360px,90%,var(--room,100vw));min-width:0;min-height:0;transform:translateX(-50%);margin:0;border-radius:18px;padding:14px 18px;font:400 15px/1.5 var(--sans);background:var(--isle);-webkit-backdrop-filter:var(--isle-blur);backdrop-filter:var(--isle-blur);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),inset 0 1px 0 rgba(255,255,255,.16);color:rgba(255,255,255,.92);border:0;--obr:rgba(255,255,255,.18);text-wrap:pretty;overflow:visible;background:rgba(52,54,124,.6);box-shadow:inset 0 0 0 1px rgba(255,255,255,.15),inset 0 1px 0 rgba(255,255,255,.16),0 14px 34px rgba(0,0,0,.32);contain:none}
.door .otty .say::before{display:none}
.door .otty .say::after{content:'';position:absolute;left:50%;right:auto;top:auto;bottom:-7px;z-index:auto;width:12px;height:12px;margin:0 0 0 -6px;background:rgba(28,29,74,.55);-webkit-backdrop-filter:blur(20px) brightness(.42) saturate(1.4);backdrop-filter:blur(20px) brightness(.42) saturate(1.4);border:0;border-radius:0;background:rgba(52,54,124,.6);box-shadow:inset -1px -1px 0 0 rgba(255,255,255,.15);-webkit-backdrop-filter:none;backdrop-filter:none;clip-path:polygon(100% 0,100% 100%,0 100%);transform:rotate(45deg)}
.door .otty .say[hidden]{display:none}
.enroldoor .fld{gap:4px}
.enroldoor .fld input,.enroldoor .fld select{height:44px}
.fld .line{display:flex;gap:6px;align-items:flex-start;min-height:18px;font:400 13px/18px var(--sans);color:var(--mute);text-wrap:pretty}
.fld.warn .line{color:var(--warm);font-weight:500}
.fld.ok .line{color:var(--ok);font-weight:500}
.fld.warn .line:not(:empty)::before{content:'';flex:none;width:16px;height:16px;margin-top:1px;background:currentColor;-webkit-mask:var(--glyph-i) center/16px no-repeat;mask:var(--glyph-i) center/16px no-repeat}
.fld.warn input,.fld.warn select,.fld.warn input:focus,.fld.warn select:focus{box-shadow:inset 0 0 0 1.5px var(--warm)}
/* the card's row: the ask's soft well with the glyph leading the words; attention and info on the well, a refusal in the warm on a faint warm tint, a success in the green on a faint green tint; no border, no fade */
.notice{display:flex;gap:10px;align-items:flex-start;margin:0 0 18px;padding:13px 16px;border-radius:16px;background:var(--well);font:400 14px/20px var(--sans);color:var(--ink);text-wrap:pretty}
.notice::before{content:'';flex:none;width:18px;height:18px;margin-top:1px;background:currentColor;-webkit-mask:var(--glyph-i) center/18px no-repeat;mask:var(--glyph-i) center/18px no-repeat}
.notice.info{color:var(--ink-soft)}
.notice.error{color:var(--warm);font-weight:500;background:color-mix(in srgb,var(--warm) 7%,#fff)}
.notice.success{color:var(--ok);font-weight:500;background:color-mix(in srgb,var(--ok) 8%,#fff)}
.notice.success::before{-webkit-mask-image:var(--glyph-ok);mask-image:var(--glyph-ok)}
/* on a door the row is bare, as the live door's: one line in its tone, no well */
.door .notice{background:none;padding:0;margin:0 0 14px;border-radius:0;font-size:13px;line-height:18px;gap:6px}
.door .notice::before{width:16px;height:16px;-webkit-mask-size:16px;mask-size:16px}
/* the wait stands where the action button stood, the button's 48 px: the words over the scanning bar; in a flow's foot it takes the acts' room */
.moment.busy{margin-top:16px;min-height:48px;padding:7px 0;flex:1;min-width:160px}
.moment.busy p{margin:0 0 10px}
.flow .foot .moment.busy{margin:0}
/* the loading look (page.js boot): the box's own shapes with bones for words until the state lands; one sweep, in phase everywhere */
@keyframes bone-sweep{to{transform:translateX(100%)}}
@keyframes land{from{opacity:.35}}
/* the door while it sends: the tabs, the ways and the last-used row are held; Google's reCAPTCHA badge never shows (its notice is in the terms line) */
.door .held{opacity:.5;pointer-events:none}
.grecaptcha-badge{visibility:hidden}
/* ── ENROL DOOR: facts and the code step ── */
/* the three quiet facts under the statement: the design's small uppercase label over each value, no box, no line */
.enroldoor .glance{display:flex;flex-wrap:wrap;gap:10px 28px;margin-top:20px}
.enroldoor .glance span{display:grid;gap:3px;font:400 14px/20px var(--sans);color:rgba(255,255,255,.85);min-width:0}
.enroldoor .glance b{font:500 9.5px/12px var(--sans);letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.55)}
.enroldoor button.go{border:0;cursor:pointer;font:500 15px/1 var(--sans)}
.enroldoor .go:disabled{opacity:.7;cursor:default}
.enroldoor .go.quiet.wide{justify-content:center;margin-top:12px}
/* the actions under a moment: quiet links in one row, the same on every door */
.acts{display:flex;flex-wrap:wrap;align-items:center;gap:10px 24px;margin-top:14px}
.acts .go.quiet{cursor:pointer;border:0;background:none;font:500 15px/1 var(--sans)}
.code-or{margin:16px 0 0;color:var(--mute)}
/* the one code field: six digits, wide-set and centred, no placeholder; the value is the digits alone so a phone's or a mail's one-time code fills it */
.fld input.otp{font:500 26px/28px var(--mono);letter-spacing:.42em;text-align:center;height:56px;padding-left:calc(14px + .42em);font-variant-numeric:var(--tab)}
.enroldoor .captcha{height:0}
/* ── CHAT: the Desk widget under the design ── */
/* the vendor's launcher never shows: the design's bubble on a door and the bar's Support item are the launchers (chat.js), and its hidden disc still carries the vendor's unread class, which chat.js reads onto them as the design's dot (the bar's pip on Support; a sky disc in the bubble's navy ring on the bubble's edge) */
.woot--bubble-holder{display:none!important}
/* THE PEEK (the owner, 2026-09-16 00:1x: a new Desk message while the panel is closed shows in our own dress, never the vendor's unread bubble): the vendor's unread view is held unseen; the island's glass bubble stands over the pill (over a door's disc) with the sender's name and words; a tap opens the panel, its X or 8 s closes it (chat.js) */
.woot-widget-holder.has-unread-view{visibility:hidden!important;pointer-events:none!important}
/* the panel's paper is opaque under the frame (the owner, 2026-09-16 01:1x: "because it is transparent too it does not look good"): white at the card's round inside the band (chat.js sets --band and --paper off the shell and the card) */
.woot-widget-holder::before{content:'';position:absolute;inset:var(--band,7px);border-radius:var(--paper,25px);background:#fff;z-index:-1}
.peek{position:absolute;left:50%;bottom:calc(100% + 10px);transform:translateX(-50%);z-index:6;pointer-events:auto;width:max-content;max-width:min(360px,calc(100% - 16px));display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:10px;padding:10px 10px 10px 16px;border:0;border-radius:18px;color:#fff;font:400 14px/19px var(--sans);text-align:left;cursor:pointer;background:var(--isle);-webkit-backdrop-filter:var(--isle-blur);backdrop-filter:var(--isle-blur);box-shadow:var(--isle-ring);animation:bub-in .34s cubic-bezier(.2,.7,.2,1)}
.peek small{display:block;color:rgba(255,255,255,.6);font:500 12px/16px var(--sans)}
.peek b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-weight:400}
.peek .x{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.1)}
.peek .x svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
.app > .peek{position:fixed;left:auto;right:20px;bottom:calc(88px + env(safe-area-inset-bottom));transform:none;z-index:7}
.chatbubble.unread::after{content:'';position:absolute;top:2px;right:2px;box-sizing:border-box;width:12px;height:12px;border-radius:50%;border:2px solid #1c1d38;background:#8ec1ff}
.sup.unread::after{content:'';position:absolute;top:8px;right:14px;width:6px;height:6px;border-radius:50%;background:#8ec1ff}
/* ── PAGE: the offline lede and the waiting state ── */
/* the one quiet line while the connection is down (page.js): between the top bar and the stage on the field's own ground, no band, no modal */
.app > .offline{margin:0;padding:0 16px 10px;text-align:center;font:400 13.5px/18px var(--sans);color:rgba(255,255,255,.72)}
/* the card waits for the state: the scanning bar alone, centred in the box */
.card .moment.wait{margin:0;min-height:160px;display:grid;align-content:center}
/* a row whose value holds two acts (a device asks: the quiet decline and Approve): on one line, wrapping on a phone; held while its act runs */
.kv .v.acts{white-space:normal;display:inline-flex;align-items:center;justify-content:flex-end;gap:8px 18px;flex-wrap:wrap}
.kv.held .go{opacity:.5;pointer-events:none}
/* the busy moment standing in a row's value keeps to the row */
.kv .v .moment.busy{margin:0;min-width:120px;text-align:left}
/* ── MONEY ── */
[data-pay]{margin-top:16px;scroll-margin-top:12px}
[data-pay] [data-block]>.fields{margin-top:0}
[data-pay] .kv{padding:8px 0}
[data-pay] .ways{margin-top:14px}
[data-pay] .go.wide{margin-top:16px}
/* THE PROCESSOR'S FRAME IN THE DESIGN'S WELL (the payskin lane, 2026-09-16, the owner: "is payment nice looking on all devices and robust and professional?"): the box is the pay well (the well's tone, 20 px corners, no ring) under the tree's own kicker; the vendor's form stands on the well with its 24 px gutter shown as the well's 20 (a phone 14) and its top at 14 (a phone 10); the SDK's root fills the frame's height (its own document, 334 with the heading blanked, given 358 so one of the vendor's hint lines keeps the Pay button in view, plus the chrome read from the drawn iframe), 640 for a bank's challenge; the box at 440 under the cover, then grown to the frame */
.paycard{position:relative;box-sizing:content-box;margin-top:0;padding-top:14px;background:var(--well);border-radius:20px;overflow:hidden;container-type:inline-size;height:440px;transition:height .45s cubic-bezier(.2,.8,.2,1)}
.paycard .payframe{--sdk-doc:358px;--sdk-form:calc(var(--sdk-doc) + var(--sdk-chrome,37px));height:var(--sdk-form);margin:0 -4px}
.paycard.challenge .payframe{height:max(var(--sdk-form),640px)}
.paycard .payframe iframe{display:block;width:100%;border:0}
.paycard .cover{position:absolute;inset:0;display:grid;align-content:center;gap:10px;padding:0 20px;background:var(--well)}
/* THE VENDOR'S CHROME IN OUR DOCUMENT: the SDK draws three things around its frame in our page, an empty amount-and-cancel row (both hidden by the options), the box holding the frame, and the Secured by Peach Payments line; the row is collapsed and the line wears our small mute face with the padlock in the same ink (important, since the vendor's utilities are important in adopted sheets); the form inside the frame is the vendor's own page on another origin, so only its theme (our ink, our face's name) reaches it */
.payframe [data-testid=checkout-root]>div>[px-gutter]{display:none}
.payframe [data-testid=checkout-secured-by-peach]{font:400 12.5px/17px var(--sans)!important;color:var(--mute)!important;padding:4px 0 16px!important;box-shadow:none!important}
.payframe [data-testid=checkout-secured-by-peach] span{color:var(--ink-soft)!important;font-weight:500!important;margin:0 0 0 4px!important}
.payframe [data-testid=checkout-secured-by-peach] svg{width:12px;height:12px;margin-left:5px}
.payframe [data-testid=checkout-secured-by-peach] svg path{fill:currentColor}
.paycard .cover p{margin:0;min-height:18px}
.paycard.up .cover{display:none}
.paycard:not(.up) .payframe{visibility:hidden}
/* THE PROCESSING MOMENT (the paywait lane, 2026-09-16, the owner: "when you pay it just disappears for minutes or seconds with nothing showing while it is processing, and you never know when done"): from the tap on Pay to the answer the pay box is one moment in its place, the well with the head, the line that changes with time, the door's scan bar and the amount; the vendor's frame stays mounted under it, collapsed (held) while its redirect pages fly and shown under the moment when a bank's page stands (the challenge); the paid well answers with its tick drawn in */
.paywait{display:grid;gap:10px;padding:22px 20px 20px;background:var(--well);border-radius:20px}
.paywait .head{font:500 17px/24px var(--sans);letter-spacing:-.01em;color:var(--ink)}
.paywait .meta{margin:0}
.paywait .scanbar{margin:4px 0 2px}
.paywait .facts{color:var(--ink-soft)}
.paywait + .paycard.challenge{margin-top:10px}
.paycard.held{height:0!important;padding:0;visibility:hidden;transition:none}
.said.paid .tick{flex:none;align-self:flex-start;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--ok);animation:tick-pop .5s cubic-bezier(.2,.8,.2,1) both}
.said.paid .tick svg{width:14px;height:14px;fill:none;stroke:#fff;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:24;animation:tick-draw .45s .2s cubic-bezier(.2,.8,.2,1) both}
@keyframes tick-pop{from{transform:scale(.4);opacity:0}60%{transform:scale(1.12);opacity:1}to{transform:scale(1);opacity:1}}
@keyframes tick-draw{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}
.flow .ln.off .k,.flow .ln.off .num,.flow .ln.sub .k,.flow .ln.sub .num{color:var(--mute)}
.flow .coupon{display:flex;gap:16px;align-items:end;margin-top:12px}
.flow .coupon .fld{flex:1}
.flow .coupon .go.quiet{padding-bottom:12px;cursor:pointer;border:0;background:none;font:500 15px/1 var(--sans)}
.flow [data-fee]>.go.quiet{cursor:pointer;border:0;background:none;font:500 15px/1 var(--sans);margin-top:14px}
.sheet-doc{margin-top:14px;overflow:hidden}
.sheetframe{display:block;width:100%;border:0;background:#fff;border-radius:14px}
.kv.inv.mute .k,.kv.inv.mute .v{color:var(--mute)}
.kv.inv .a:empty{min-height:22px}
.flow .later{margin-top:18px}
/* ── ENROL FLOW ── */
/* a part the lane does not offer is not drawn; the identity line's one tap stands at the row's end; the foot's acts stay on the Back round's line (the doors' .acts rule adds a top margin) */
.flow .tk[hidden]{display:none}
.flow .notice .go.quiet{margin-left:auto;white-space:nowrap}
/* nothing pulls sideways on a phone: the frame and the page clip any stray width and the browser never rubber-bands across */
html,body,.app{overflow-x:hidden;overscroll-behavior-x:none}
/* the terms line under a door's box: one small line; Google's reCAPTCHA notice, where the SMS way needs it, a fainter line under it */
.door .terms,.enroldoor .terms{font-size:11px;line-height:15px;margin-top:14px;color:var(--mute)}
.door .terms a,.enroldoor .terms a{color:inherit}
/* ── SETTINGS ── */
/* the edit sheet's code step: the six digits as the one-time box, the quiet Send again under it */
.flow .fld input.otp{font:500 24px/28px var(--mono);letter-spacing:.16em;text-align:center;height:56px}
.flow .fld input.otp::placeholder{letter-spacing:.1em}
.flow .body .acts{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px}
/* on a phone the due row's Pay stands on its own line under the amount, at the right */
.kv.inv.pay{column-gap:24px}
/* the first-open offer: the shell's sheet glass on the veil, risen from the foot on a phone, centred on a desk */
.veil.offer{align-items:flex-end;padding:0 10px calc(14px + env(safe-area-inset-bottom))}
.offer .gt{margin:0 0 6px}
.offer .nm{font:600 21px/26px var(--sans);letter-spacing:-.02em;color:var(--ink)}
.offer .fx{display:block;margin:6px 0 0;font:400 14px/20px var(--sans);color:var(--mute);text-wrap:pretty}
.offer .why{display:flex;gap:6px;align-items:flex-start;margin:10px 0 0;font:500 13px/18px var(--sans);color:var(--warm);text-wrap:pretty}
.offer .why::before{content:'';flex:none;width:16px;height:16px;margin-top:1px;background:currentColor;-webkit-mask:var(--glyph-i) center/16px no-repeat;mask:var(--glyph-i) center/16px no-repeat}
.offer .foot{display:flex;justify-content:flex-end;align-items:center;gap:18px;margin-top:20px}
.offer button.go,.guide button.go{border:0;cursor:pointer;font:500 15px/1 var(--sans)}
.offer .foot .go i svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
/* the install guide: an iPhone or an iPad in a browser tab installs first; the three steps in the well, under the offer's title or the settings row */
.guide{margin-top:12px;background:var(--well);border-radius:16px;padding:14px 16px}
.guide b{display:block;font:500 15px/20px var(--sans);color:var(--ink)}
.guide .fx{display:block;margin:2px 0 0;font:400 13.5px/19px var(--sans);color:var(--mute)}
.guide ol{margin:10px 0 0;padding:0 0 0 22px;font:400 14px/20px var(--sans);color:var(--ink)}
.guide li+li{margin-top:6px}
.guide .go.quiet{margin-top:12px}
/* the switch: 44 by 26, the knob 20, ink when on, the line tone when off */
.switch{width:44px;height:26px;border:0;border-radius:999px;background:var(--line);position:relative;cursor:pointer;padding:0;vertical-align:middle;transition:background .25s;flex:none}
.switch::after{content:'';position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(20,21,57,.25);transition:transform .25s cubic-bezier(.2,.8,.2,1)}
.switch[aria-checked="true"]{background:var(--ink)}
.switch[aria-checked="true"]::after{transform:translateX(18px)}
.switch:disabled{opacity:.45;cursor:default}
.switch.busy{opacity:.6;pointer-events:none}
.switch:focus-visible{outline:0;box-shadow:0 0 0 3px rgba(35,36,103,.25)}
/* a switch whose state is not known yet holds blank: the track without its knob, never off then on */
.switch:not([aria-checked])::after{visibility:hidden}
.kv:has(>.v>.switch){align-items:center}
.kv .k small.warn{color:var(--warm);font-weight:500}
/* ── MARKS AND REWARDS ── */
/* the marks in a course: the total line as the fixture's Term mark, every result a .kv.mk row with its word under the figure and the thin bar; the count beside the label */
[data-marks] .gt .n{font:400 12px/18px var(--mono);color:var(--faint);margin-left:8px}
[data-marks] .kv.mk .v small{white-space:nowrap}
[data-marks] .kv.mk[data-tone=warm] .track i{background:var(--warm)}
/* THE POINTS DOOR under Otty: one plate on the field's glass at the bar's width, the label and the facts as targets that open the sheet on their cell; none reads its one line; on a phone the plate takes its own line under him and his words */
.otty .door{padding:12px 14px 14px;border-radius:18px;background:var(--isle);backdrop-filter:var(--isle-blur);-webkit-backdrop-filter:var(--isle-blur);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),inset 0 1px 0 rgba(255,255,255,.16);color:#fff}
.door>.k{display:block;font:500 12px/16px var(--sans);letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.6)}
.door .none{display:block;margin-top:8px;font:400 14px/20px var(--sans);color:rgba(255,255,255,.75);text-decoration:none}
/* ── PROSE ── */
/* a Canvas body through the one pass (prose.js): the classes the pass writes that the design's prose rules above do not carry; the tokens are the design's */
.kv .k small .warm,.ask .t small .warm{color:var(--warm);font-weight:500}
.gt .n{font:400 12px/18px var(--mono);color:var(--faint);margin-left:8px}
a.kv.it,.who a.kv{text-decoration:none;color:inherit}
.kv.it.open .k{color:var(--ink)}
.prose>*{min-width:0;max-width:100%}
.prose :is(h1,h2){font:600 20px/26px var(--sans);letter-spacing:-.01em;margin-top:24px}
.prose :is(h3,h4,h5,h6):not(.band){font:600 16px/23px var(--sans);margin-top:20px}
.prose :is(p,td,th,div)>.xl:only-child{font:600 20px/26px var(--sans)}
.prose :is(p,td,th,div)>.lg:only-child{font:600 16px/23px var(--sans)}
.prose :is(p,td,th,div)>.sm:only-child,.prose small,.prose figcaption{font:400 12.5px/17px var(--sans);color:var(--mute)}
.prose :is(strong,b){font-weight:600}
.prose :is(sup,sub){font-size:.75em;line-height:0;position:relative;vertical-align:baseline}
.prose sup{top:-.35em}
.prose sub{top:.2em}
.prose .screenreader-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.prose>:where(.scroll,figure,.media,.steps,pre,blockquote,a.ccard){margin-top:16px}
.prose>:where(.scroll,figure,.media,.steps,pre,blockquote,a.ccard)+*{margin-top:16px}
.prose>:first-child,.prose :is(td,th,li)>:first-child{margin-top:0}
.prose :is(td,th)>*+*{margin-top:4px}
/* the arrangement: the section mark beside the first lines, the levels, the pause */
.prose .mark{float:left;width:28px;margin:10px 10px 0 0;line-height:0}
.prose .mark:has(+ :is(.scroll,figure,.media,.steps,a.ccard)){float:none;margin:0}
.prose .mark img{width:28px;height:auto;border-radius:0}
.prose>:is(.scroll,figure,.media,.steps,hr,pre,blockquote,a.ccard,h1,h2,h3,h4,h5,h6){clear:left}
.prose .in1{padding-left:22px}
.prose .in2{padding-left:44px}
.prose .in3{padding-left:66px}
.prose hr{border:0;border-top:1px solid var(--line);margin:16px 0}
.prose hr.room{border:0;height:24px;margin:0}
.prose :is(ul,ol){padding-left:22px;display:grid;gap:8px;margin:0}
.prose ol{font-variant-numeric:var(--tab)}
.prose li::marker{color:var(--mute)}
.prose li>p{margin:0}
.prose li>:is(ul,ol){margin-top:4px}
/* links: the underline, the outside mark glued to the last word, the Zoom link with its glyph, the gap of a quiz blank */
.prose a:not(.ccard):not(.pic){color:var(--ink);text-decoration:underline;text-decoration-color:var(--faint);text-decoration-thickness:1px;text-underline-offset:3px}
.prose a:not(.ccard):not(.pic):hover{text-decoration-color:currentColor}
.prose a[target='_blank']:not(.ccard):not(.zoom)::after{content:'\2060';display:inline;padding-left:15px;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6M20 4l-9 9M18 13v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5'/%3E%3C/svg%3E") right center/12px 12px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6M20 4l-9 9M18 13v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5'/%3E%3C/svg%3E") right center/12px 12px no-repeat}
.prose a.zoom{display:inline-flex;align-items:center;gap:6px;text-decoration:none;font-weight:500}
.prose a.zoom .i{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.prose .gap{display:inline-block;min-width:6ch;border-bottom:1px solid var(--ink)}
/* pictures: the width attribute the cap, never a stretch; a strip of two or more; the tap */
.prose img{display:block;border-radius:10px;max-width:100%;height:auto}
.prose :is(td,th) img{width:100%!important;height:auto!important}
.prose figure.strip{display:grid;gap:8px}
.prose figcaption{margin-top:4px}
.prose a.pic{display:block;cursor:zoom-in}
/* tables: the quiet list by default, the grid where the teacher drew a border, the key-value table, the steps, the stacked table on a phone; a run with no space breaks */
.prose .scroll{overflow-x:auto;max-width:100%;scrollbar-width:thin;-webkit-overflow-scrolling:touch}
.prose :is(tr,td,th){height:auto!important}
.prose :is(td,th)[width],.prose col[width]{width:auto!important}
.prose :is(td,th){padding:8px 12px 8px 0;vertical-align:top;text-align:left;border:0;border-bottom:1px solid var(--line)}
.prose tr:last-child>:is(td,th){border-bottom:0}
.prose th{font-weight:600}
.prose :is(td,th) :is(h1,h2,h3,h4,h5,h6){font:inherit;font-weight:inherit;margin:0}
.prose table.grid{font:400 13px/18px var(--sans)}
.prose table.grid :is(td,th){border:1px solid var(--line);padding:8px 12px}
.prose table.grid th{background:var(--well)}
.prose table.kvt td:first-child{width:1%;white-space:nowrap;font-weight:600}
.prose .scroll :is(td,th){overflow-wrap:normal;white-space:normal}
.prose .scroll .run{overflow-wrap:anywhere}
.prose .steps{display:grid;grid-template-columns:2.5ch 1fr;gap:4px 12px}
.prose .steps .step-h{grid-column:1/-1;font-weight:600;margin-top:8px}
.prose .steps .step-h:first-child{margin-top:0}
.prose .steps .step-n{font-variant-numeric:var(--tab);color:var(--mute)}
/* code, quotes, maths */
.prose pre{font:13px/20px var(--mono);background:var(--well);border-radius:10px;padding:12px 16px;overflow-x:auto;margin:0}
.prose code{font:.92em/1 var(--mono);background:var(--well);padding:1px 5px;border-radius:4px}
.prose pre code{font:inherit;background:none;padding:0}
.prose blockquote{border-left:2px solid var(--line);padding-left:16px;margin:0;color:var(--ink-soft)}
.prose math{font-size:inherit;max-width:100%;overflow-x:auto;overflow-y:hidden;vertical-align:middle}
.prose math[display='block']{display:block;margin:8px 0;text-align:left}
/* the media card: a frame in its own ratio (the pass writes it), a native player at its own size, the off card with its sentence, the caption with the host and the title */
.prose .media .frame>iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.prose .media .frame:has(>video),.prose .media .frame:has(>audio){aspect-ratio:auto;background:var(--ink)}
.prose .media .frame>video{display:block;width:100%;height:auto;aspect-ratio:auto 16/9}
.prose .media .frame:has(>audio){background:var(--well);padding:12px}
.prose .media .frame>audio{display:block;width:100%}
.prose .media.off .frame{aspect-ratio:auto;min-height:96px;background:var(--well);display:grid;place-items:center;padding:16px;color:var(--ink-soft);font:400 13px/18px var(--sans);text-align:center}
.prose .media figcaption .host{color:var(--ink-soft);font-weight:500}
/* the file card and the link card: the word Open at the right is the design's; a card in a cell tighter, without its glyph */
.prose a.ccard .c-word .link{font:inherit;color:inherit;text-decoration:none}
.prose td a.ccard{min-height:44px;padding:8px 12px}
.prose td a.ccard .glyph{display:none}
/* a file on the page: the paper (a PDF without the browser's toolbar, filling the sheet), a picture, a video, a sentence for the rest */
.prose .paper{display:block;width:100%;border-radius:14px}
.prose object.paper{height:min(78vh,900px);border:1px solid var(--line)}
.prose img.paper{max-width:100%;height:auto}
.flow .said span{text-wrap:pretty}
/* the lightbox: a native dialog, the ink behind, the picture at its own size and at most the viewport, its box sliding when wider than the screen, the alt under it, the close bubble at the top right */
.lightbox{border:0;padding:0;margin:0;width:100vw;height:100dvh;max-width:100vw;max-height:100dvh;background:transparent;color:#fff;display:grid;grid-template-rows:minmax(0,1fr) auto;place-items:center}
.lightbox:not([open]){display:none}
.lightbox::backdrop{background:rgba(35,36,103,.92)}
.lightbox .pane{max-width:100vw;max-height:100%;overflow:auto;touch-action:pan-x pan-y pinch-zoom;scrollbar-width:none}
.lightbox .pane img{display:block;max-height:calc(100dvh - 64px)}
.lightbox .alt{margin:8px 16px 16px;font:400 13px/18px var(--sans);color:rgba(255,255,255,.72);text-align:center;overflow-wrap:anywhere}
.lightbox .close{position:fixed;top:12px;right:12px;width:44px;height:44px;border:0;border-radius:999px;background:rgba(255,255,255,.1);backdrop-filter:blur(14px);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);color:#fff;display:grid;place-items:center;cursor:pointer}
.lightbox .close .i{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
/* ── TIMETABLE ── */
/* the head: the shown range with the term's week beside it, the week's arrows and This week at the row's end (dimmed while the shown week holds today); the columns follow the week (a weekend day only with a lesson) */
.gt.tthead{display:flex;align-items:center;justify-content:space-between;gap:8px 16px;flex-wrap:wrap}
.tthead small{font:400 12px/18px var(--sans);color:var(--faint);margin-left:8px}
.tthead .nav{display:inline-flex;align-items:center;gap:4px}
.tthead .arrow{width:28px;height:28px;border-radius:50%;display:inline-grid;place-items:center;color:var(--ink);background:var(--well)}
.tthead .arrow svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.tthead .word{font:500 13px/18px var(--sans);color:var(--ink);text-decoration:none;padding:0 8px}
.tthead .word.on{color:var(--faint);pointer-events:none}
/* a break is a quiet cell; the refusal row's Try again at its end */
.tt .cell.brk{background:none;box-shadow:inset 0 0 0 1px var(--line)}
.tt .cell.brk b{color:var(--mute);font-weight:400}
.notice .go.quiet{margin-left:auto;font-size:14px}
/* ── TASKS ── */
/* a row that opens (a task, a file, an entry) is the whole link; the nearest task ahead carries its word in ink; a label's count; a written answer's box; a quiet word in a well */
a.kv{text-decoration:none;color:inherit}
.kv.task.next .v small{color:var(--ink);font-weight:600}
.fld textarea{border:0;border-radius:14px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);padding:11px 14px;font:400 16px/22px var(--sans);color:var(--ink);width:100%;resize:vertical;min-height:120px}
.fld textarea:focus{outline:0;box-shadow:inset 0 0 0 1.5px var(--ink)}
.flow .said b.mu{color:var(--mute)}
/* the hand-in well: the phone's code beside its words, the ways as quiet links on one row, a page with its thumb and its acts, a file with its progress, a finished hand-in's thumbs */
.kv.qr{grid-template-columns:auto minmax(0,1fr);align-items:start}
.kv.qr img{width:120px;height:120px;border-radius:10px;background:#fff}
.kv.qr .lnk{display:block;margin-top:4px;font:400 13px/18px var(--mono);color:var(--ink);word-break:break-all}
.ways{display:flex;flex-wrap:wrap;gap:8px 22px;margin-top:8px}
.ways .go.quiet,.paybox .kv .v.acts .go.quiet,.paybox .acts .go.quiet,.kv .v .go.quiet,.paybox .kv .v .go.quiet{cursor:pointer;border:0;background:none;font:500 14px/1 var(--sans)}
.kv.pg{grid-template-columns:auto minmax(0,1fr) auto;align-items:center}
.kv.pg .thumb{width:44px;height:58px;object-fit:cover;border-radius:6px;background:var(--well);display:block}
.kv.pg .thumb.bone{background:var(--line)}
.kv.up{row-gap:8px}
.kv.up .track{grid-column:1/-1;height:4px;border-radius:999px;background:#fff;overflow:hidden}
.kv.up .track i{display:block;height:100%;border-radius:999px;background:var(--ink);transition:width .3s}
.kv .k .thumbs{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.kv .k .thumbs img{width:44px;height:58px;object-fit:cover;border-radius:6px;background:var(--well)}
/* a discussion's entries: the words as prose, a reply one level in, the one aimed at in the well */
.kv.ent{align-items:start}
.kv.ent .k .prose{margin-top:0;max-width:none}
.kv.ent.in1{margin-left:24px}
.kv.ent.on{background:var(--well);border-radius:14px;padding:11px 14px;margin-left:-14px;margin-right:-14px}
.kv.ent.in1.on{margin-left:10px}
/* a question: the number, the words and the saved word with the points on one line, the control under; a gap in the text takes its input or select; a choice as the design's option */
.q .qh{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:0 10px;align-items:baseline}
.q.info .qh{grid-template-columns:minmax(0,1fr)}
.q .qn{font:500 12px/22px var(--mono);color:var(--faint)}
.q .qt.prose{margin-top:0;max-width:none;font:500 16px/22px var(--sans)}
.q .qs{display:grid;justify-items:end;font:400 12.5px/17px var(--sans);color:var(--mute);white-space:nowrap}
.q .qs .st.ok{color:var(--ok);font-weight:500}
.q .qs .st.need{color:var(--warm);font-weight:500}
.q .qa{margin-top:8px}
.q .qa .fields{margin-top:6px}
.q .qa .kv{padding:6px 0}
.q .qa .kv select,.q .gap select{height:40px;border:0;border-radius:12px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);padding:0 32px 0 12px;font:400 15px/22px var(--sans);color:var(--ink);max-width:60vw;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6c93' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;background-size:16px}
.q .gap{display:inline-block;min-width:6ch;border-bottom:1.5px solid var(--line);padding:0 4px;margin:0 2px;font-weight:500}
.q .gap:has(input,select){border-bottom:0;padding:0}
.q .gap input{height:34px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px var(--line);padding:0 8px;font:400 15px/22px var(--sans);color:var(--ink);width:12ch}
.q .gap select{height:34px;border-radius:8px}
.q .gap[data-tone=right]{color:var(--ok);border-color:var(--ok)}
.q .gap[data-tone=wrong]{color:var(--warm);border-color:var(--warm)}
.flow .opt .prose{margin:0;font:inherit;max-width:none}
.flow .opt.tick .ring{border-radius:5px}
/* the last-used row on a phone: its identity shrinks (the door card's .who sections are flex:none; this .who is the row's) */
.door .card .lastrow .who{flex:1 1 0%;min-width:0}
.bar .rule{background:rgba(20,21,58,.14)}
.bar .pip{background:#3d6fdc}
/* THE PILL STANDS ON THE CARD (the owner, 2026-09-15: "keep the pill always in the middle of the card, not under Otty"): the bar lives inside the shell, floating at the card's foot on every size, so it is always over the white and one look does: frosted white glass, the ink ring, our icons in ink */
.app:not(.door):not(.enroldoor) .stage > .shell{position:relative}
/* THE DIM UNDER A SHEET, ONE RULE FOR BOTH (the owner, 2026-09-16 00:1x: "make the chat page dim the rest under a bit so it shows nicer"; 02:1x: "the chatbot darkens the card behind it, but notifications darken everything: unify the experience"): a soft navy veil over the card's paper alone while the chat panel (html.chatopen, chat.js) or the account drawer (html.draweropen, shell.js) stands, under the pill, on every size */
.app:not(.door):not(.enroldoor) .stage > .shell::after{content:'';position:absolute;inset:var(--band);border-radius:var(--card-r);background:rgba(20,21,58,.28);z-index:4;pointer-events:none;opacity:0;transition:opacity .35s ease}
html:is(.chatopen,.draweropen) .app:not(.door):not(.enroldoor) .stage > .shell::after{opacity:1;-webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px)}
/* the pill stands above the panel (the panel ends 8px over it, chat.js), so the launcher and its open state stay in reach */
html.chatopen .app:not(.door):not(.enroldoor) .shell > .barwrap{z-index:2147483001}
/* the pointer pill (shell.js MY.below): the act pill's own dress, arriving as the chat's X does */
.shell > .barwrap > .acts .go.below:not([hidden]){animation:bub-in .26s cubic-bezier(.2,.7,.2,1)}
/* the bar is exactly centred whatever stands at its sides: three columns, the sides in the outer two (equal shares), the bar in the middle */
/* the rounds stand at the row's edges; the row's side padding grows with the card, from 8px where the three just fit (the rounds 6px from the pill) to the bar's own foot inset on a wide card, so the rounds sit the same distance from the side as from the bottom (the owner, 2026-09-15: "keep them this close if needed, but expand wide on larger screens, keeping an elegant padding from the corners"; 2026-09-16 20:0x: "on wider screens these round buttons on both sides should be closer to the corners, so they show a uniform padding on the bottom and the side") */
.app:not(.door):not(.enroldoor) .shell > .barwrap{--bar-edge:14px;position:absolute;left:0;right:0;top:auto;bottom:var(--bar-edge);width:auto;height:auto;padding:0 max(8px,min(var(--bar-edge),(100% - 457px) / 2 - 6px));display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:6px;background:none;pointer-events:none;z-index:5}
.app:not(.door):not(.enroldoor) .shell > .barwrap > .bar{grid-column:2;margin:0;flex:none}
.app:not(.door):not(.enroldoor) .shell > .barwrap > .back{grid-column:1;justify-self:start}
.app:not(.door):not(.enroldoor) .shell > .barwrap > .acts{grid-column:3;justify-self:end}
.app:not(.door):not(.enroldoor) .shell > .barwrap .bar{pointer-events:auto}
.app:not(.door):not(.enroldoor) .card{padding-bottom:calc(92px + env(safe-area-inset-bottom))}
.bar .sg,.bar .sup,.bar>.back{color:var(--ink)}
/* the initials chip is the phone's alone (the owner, 2026-09-15 21:4x: "this NM is not needed on desktop") */
#me .ini{display:none}
/* ── THE SIDES (the owner, 2026-09-15): a flow's Back and its action stand beside the bar on every size, three pieces of one height (58), one rhythm (8px) and one glass: the Back a round of the bar's glass, the action the navy pill with its arrow disc; the bar is never squeezed and never loses a word; under 480px the action is a round with its arrow alone ── */
.foot:empty{display:none}
.shell > .barwrap > .back{position:static;flex:none;width:58px;height:58px;margin:0;pointer-events:auto;background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);box-shadow:var(--glass-ring);color:var(--ink)}
.shell > .barwrap > .acts{position:static;flex:none;margin:0;pointer-events:auto;display:flex;align-items:center;gap:8px}
.shell > .barwrap > .acts .go{margin:0;height:58px;padding:0 7px 0 22px;gap:12px;font-size:15px}
.shell > .barwrap > .acts .go i{width:44px;height:44px}
.go i svg{width:20px;height:20px}
.shell > .barwrap > .acts .go.quiet,.shell > .barwrap > .acts [data-line]{display:none}
.bar .sg:hover,.bar .sup:hover,.shell > .barwrap > .back:hover{background:var(--lens);-webkit-backdrop-filter:var(--lens-blur);backdrop-filter:var(--lens-blur);box-shadow:var(--lens-ring)}
/* the open place is glass on the glass (the owner, 2026-09-15: "the selected state nicer, glass effect"): a lighter frosted lozenge raised by a fine ring, a white top light and a soft cast shadow; the ink ring under the pointer */
.bar .sg.on,.bar .sup.open{color:var(--ink);background:rgba(255,255,255,.62);box-shadow:inset 0 0 0 1px rgba(20,21,58,.08),inset 0 1px 0 rgba(255,255,255,.95),0 6px 16px -8px rgba(4,6,32,.35)}
/* ── UNDER OTTY: the one slot both sides share ── */
/* the place under Otty (the owner, 2026-09-15: "exactly reused, the same general elements, the same sizes on every device; only what stands in it differs"): the shell adds .under to the column on every signed-in page; the learner's Points door (rewards.js) and the guardian's pending acts (pending.js) mount into it; on the desk it is the row under him, as wide as the greeting, in the column's centred group (the greeting, him, the slot); empty, it takes no room; under 1000px it is its own line under the top strip on both sides (the rule in the phone block); his room shrinks by what stands in it (--under, a length each side sets) */
.otty > .under{display:none}
/* the guardian's pending rows (pending.js): at most four in white on the navy, the small line muted, the act's word with a chevron at the end, no box and no lines; the same rows on every size */
.prow{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:14px;height:46px;color:#fff;text-decoration:none;font:400 14px/18px var(--sans)}
.prow .k{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.prow .k small{display:block;color:rgba(255,255,255,.6);font:400 13px/17px var(--sans);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.prow .w{display:inline-flex;align-items:center;gap:4px;color:rgba(255,255,255,.85);font:500 14px/18px var(--sans);white-space:nowrap}
.prow .w i{font-style:normal;color:rgba(255,255,255,.55);transition:transform .2s}
.prow:hover .w{color:#fff}
.prow:hover .w i{transform:translateX(2px)}
.sheet .rows{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.otty .say .bub{position:relative;max-width:100%;padding:11px 15px;border-radius:18px;background:var(--isle);-webkit-backdrop-filter:var(--isle-blur);backdrop-filter:var(--isle-blur);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),inset 0 1px 0 rgba(255,255,255,.16);transform-origin:left center}
.otty .say .bub.words:not(.grown){animation:bub-in .34s cubic-bezier(.2,.7,.2,1)}
.otty .say .bub.grown .live,.otty .say .bub.grown > b,.otty .say .bub.grown > small{animation:bub-fade .4s ease-out .12s both}
@keyframes bub-fade{from{opacity:0}}
.otty .say .bub.think{padding:12px 16px;animation:bub-in .34s cubic-bezier(.2,.7,.2,1)}
.otty .say .bub:empty{display:none}
.otty .say .bub::after{content:'';position:absolute;width:12px;height:12px;left:-5px;top:50%;transform:translateY(-50%) rotate(45deg);background:rgba(28,29,74,.55);-webkit-backdrop-filter:blur(20px) brightness(.42) saturate(1.4);backdrop-filter:blur(20px) brightness(.42) saturate(1.4);box-shadow:inset 1px -1px 0 0 rgba(255,255,255,.14);clip-path:polygon(0 0,0 100%,100% 100%)}
.otty .say .bub .ghost{display:block;visibility:hidden}
.otty .say .bub .live{display:block;position:absolute;left:15px;right:15px;top:11px;margin:0}
.otty .say .bub b{display:block;font:500 16px/22px var(--sans)}
.otty .say .bub small{margin-top:0}
.otty .say .bub b+small{margin-top:2px}
.otty .say .bub .dots{display:flex;gap:5px;align-items:center;height:14px}
.otty .say .bub .dots i{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.75);animation:dot 1.1s ease-in-out infinite}
.otty .say .bub .dots i:nth-child(2){animation-delay:.18s}
.otty .say .bub .dots i:nth-child(3){animation-delay:.36s}
@keyframes dot{0%,80%,100%{opacity:.35;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}
@keyframes bub-in{from{opacity:0;transform:scale(.92)}60%{opacity:1}}
/* ── THE FLOATING BOXES, ONE RULING (the owner, 2026-09-15 17:0x: "where the chatbot box and the notification box dropdowns show, in accordance with the card; one unified ruling, now it is too unorganised") ── */
/* one dress (the paper in the glass rim, drawn once: the widget's own sheet draws the chat panel's, so its holder carries no second dress), one close (an outside tap, Escape, the round X), one at a time; since 2026-09-15 23:2x and 2026-09-16 00:1x the account drawer grows from the island (above) and the chat panel stands on the card's rim (chat.js) */
/* ── THE LEARNER'S SHEET (the owner, 2026-09-15: "this selector on mobile looks terrible and not aligned with theme; the pages that have different shapes and open for leaderboards etc. should be tabs of the same popup that doesn't change size", "light background aligned with theme, items glassy edges"; 18:1x: "they are squeezed in rounds and not looking good, and the word Chosen should go too; the other tabs of the leaderboards are just a data dump"): ONE POPUP for the points, the board, the houses and the buddy, the dropdown sheet's paper in its glass rim (the same rounds per size), one fixed size per device (the desk 560 wide and min(640, the screen less 80) tall; a phone and a tablet the screen less 16px gutters and less 96px tall), centred on the veil, the open tab's panel scrolling inside; the head's title in the ink and one glass round to close (the bar's glass, the lens on hover); the design's tabs with the ink slide alone marking the open one (no browser outline, no underline: "why this double line"); inside, one hero well, .kv rows, the reward rail, the board's discs, the house tiles with their share bars, the buddy's row of standing figures under the ink slide ── */
.veil:has(> .popup){align-items:center;padding:0}
.popup{--rim:7px;position:relative;isolation:isolate;display:flex;flex-direction:column;width:560px;max-width:calc(100vw - 32px - 2 * var(--rim));height:min(640px,calc(100dvh - 80px));color:var(--ink);border-radius:25px;outline:0}
.popup::before{content:'';position:absolute;inset:calc(var(--rim) * -1);border-radius:32px;background:var(--rim);backdrop-filter:var(--rim-blur);-webkit-backdrop-filter:var(--rim-blur);box-shadow:var(--rim-ring),var(--rim-cast);z-index:-2}
.popup::after{content:'';position:absolute;inset:0;border-radius:25px;background:linear-gradient(180deg,#fff,#f8f8fc);box-shadow:0 0 0 1px rgba(35,36,103,.08),inset 0 1px 0 #fff;z-index:-1}
.popup .hd{flex:none;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:20px 22px 0}
.popup .hd .nm{min-width:0;font:500 20px/26px var(--sans);letter-spacing:-.01em;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.popup .orb{flex:none;width:36px;height:36px;padding:0;border:0;border-radius:50%;display:grid;place-items:center;color:var(--ink);cursor:pointer;background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);box-shadow:var(--glass-ring);transition:background .25s}
.popup .orb:hover{background:var(--lens)}
.popup .orb:focus{outline:0}
.popup .orb:focus-visible{box-shadow:var(--glass-ring),0 0 0 3px rgba(35,36,103,.18)}
.popup .orb svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.popup .tabs{flex:none;margin:10px 0 0;padding:0 22px}
.popup .tab:focus{outline:0}
.popup .tab:focus-visible{text-decoration:none}
.popup .panel{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--line) transparent;padding:14px 22px 22px}
.popup .panel > .gt:first-child{margin-top:0}
.popup .go{border:0;cursor:pointer}
.popup .go:disabled{opacity:.6;cursor:default}
.popup .said{padding:12px 2px;font:400 15px/22px var(--sans);color:var(--ink)}
.popup .said b{display:block;font-weight:500}
/* the hero well: the figure first in the mono, the words under it, the state one quiet line, the act pill at its right while the window is open */
.popup .hero{display:grid;grid-template-columns:minmax(0,1fr);align-items:center;gap:16px;padding:18px 20px;border-radius:20px;background:var(--well)}
.popup .hero.act{grid-template-columns:minmax(0,1fr) auto}
.popup .hero .figure{display:block;font-family:var(--mono);font-variant-numeric:var(--tab);font-size:34px;line-height:38px;font-weight:500;letter-spacing:-.02em;color:var(--ink)}
.popup .hero .figure[data-tone=warm]{color:var(--warm)}
.popup .hero .figure[data-tone=ok]{color:var(--ok)}
.popup .hero .hw{display:block;margin-top:2px;font:500 15px/20px var(--sans);color:var(--ink)}
.popup .hero .hm{display:block;font:400 13px/18px var(--sans);color:var(--mute)}
.popup .hero .hs{display:block;margin-top:8px;font:500 13px/18px var(--sans);color:var(--mute)}
.popup .hero .hs[data-tone=ok]{color:var(--ok)}
.popup .hero .hs[data-tone=warm]{color:var(--warm)}
.popup .hero .moment{margin:0;min-width:0}
.popup .kv.sum{margin-top:4px}
.popup .kv.sum .k{font-weight:500}
/* the reward rail: a segment per band, the reached ones inked, the next one ringed, the percent and the points under each */
.popup .ladder{display:flex;gap:6px;margin-top:10px}
.popup .tk{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px}
.popup .tk i{display:block;height:6px;border-radius:999px;background:var(--well);transition:background .5s,box-shadow .5s}
.popup .tk.done i{background:var(--ink)}
.popup .tk.on i{background:#fff;box-shadow:inset 0 0 0 1.5px var(--ink)}
.popup .tk span{font:400 12px/16px var(--sans);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.popup .tk.done span,.popup .tk.on span{color:var(--ink);font-weight:500}
.popup .tk small{font:400 11px/14px var(--mono);font-variant-numeric:var(--tab);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* the board: the top three with their ink discs, the rows around the learner, the gap mark between, the learner's own on the tint */
.popup .board{margin-top:14px}
.popup .kv.row{grid-template-columns:28px minmax(0,1fr) auto;column-gap:12px;align-items:center;padding:8px 0}
.popup .kv.row .rank{font-family:var(--mono);font-variant-numeric:var(--tab);font-size:13px;color:var(--faint);text-align:center}
.popup .kv.row .medal{width:24px;height:24px;border-radius:50%;background:var(--ink);color:#fff;display:grid;place-items:center;font:500 12px/1 var(--sans);justify-self:center}
.popup .kv.row[data-me]{margin:0 -12px;padding:8px 12px;border-radius:14px;background:var(--well)}
.popup .kv.row[data-me] .k,.popup .kv.row[data-me] .rank{font-weight:500;color:var(--ink)}
.popup .gap{height:20px;display:grid;place-items:center;font:400 13px/1 var(--mono);letter-spacing:.2em;color:var(--faint)}
.popup .kv .v.num[data-zero]{color:var(--faint)}
/* the houses: four tiles two by two (the emblem, the place, the name, the kept figure, the thin ink share bar, the share), the learner's own on the tint with Your house */
.popup .houses{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:8px}
.popup .plate{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-areas:'em caps' 'em name' 'fig fig' 'bar bar' 'share share';column-gap:12px;align-content:start;min-width:0;padding:16px 18px 14px;border-radius:18px;background:var(--well);text-align:left}
.popup .plate[data-mine]{background:color-mix(in srgb,var(--ink) 9%,#fff)}
.popup .emblem{display:block;width:40px;height:40px;flex:none;background:var(--ink);-webkit-mask:var(--em) center/contain no-repeat;mask:var(--em) center/contain no-repeat}
.popup .disc{width:40px;height:40px;flex:none;border-radius:50%;display:grid;place-items:center;background:#fff;box-shadow:inset 0 0 0 1px var(--line);font:600 16px/1 var(--sans);color:var(--ink)}
.popup .plate .emblem,.popup .plate .disc{grid-area:em;align-self:center}
.popup .caps{grid-area:caps;align-self:end;font:500 11px/16px var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--mute);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.popup .hname{grid-area:name;align-self:start;font:500 15px/20px var(--sans);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.popup .plate .figure{grid-area:fig;margin-top:12px;font-family:var(--mono);font-variant-numeric:var(--tab);font-size:22px;line-height:28px;color:var(--ink)}
/* the meter, not "bar": the pill owns that class (the owner, 2026-09-15 23:0x: "these bars are empty") */
.popup .plate .meter{grid-area:bar;height:3px;margin-top:8px;border-radius:999px;background:rgba(35,36,103,.12);overflow:hidden}
.popup .plate .meter i{display:block;height:100%;border-radius:999px;background:var(--ink)}
.popup .plate .share{grid-area:share;margin-top:6px;font:400 12px/16px var(--sans);color:var(--mute)}
/* the buddy: the chosen one big with the arrows at its sides and its name under it, the cast as a row of small standing figures that scrolls and snaps, the chosen one under the ink slide; a tap chooses */
.popup .cast{display:flex;flex-direction:column;align-items:center;gap:6px;margin-top:4px}
.popup .big{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;width:100%}
.popup .face{display:block;justify-self:center;width:min(240px,50vw);height:min(240px,50vw);object-fit:contain;object-position:center bottom;filter:drop-shadow(0 14px 16px rgba(20,21,58,.18))}
.popup .arrow{position:static;transform:none}
.popup .named{margin:2px 0 0;text-align:center;font:500 17px/22px var(--sans);color:var(--ink)}
.popup .strip{position:relative;display:flex;gap:8px;box-sizing:border-box;width:calc(100% + 44px);margin:10px -22px 0;padding:4px 22px 9px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scrollbar-width:none}
.popup .strip::-webkit-scrollbar{display:none}
.popup .fig{flex:none;width:72px;height:88px;padding:0 4px;border:0;background:none;border-radius:14px;cursor:pointer;scroll-snap-align:center;display:grid;align-items:end;justify-items:center;transition:transform .25s}
.popup .fig img{display:block;width:64px;height:80px;object-fit:contain;object-position:center bottom;filter:drop-shadow(0 6px 8px rgba(20,21,58,.14))}
.popup .fig:hover{transform:translateY(-2px)}
.popup .fig:focus{outline:0}
.popup .fig:focus-visible{box-shadow:inset 0 0 0 2px rgba(35,36,103,.18)}
.popup .strip .ink{position:absolute;bottom:0;left:0;width:0;height:3px;border-radius:999px;background:var(--ink);transition:left .45s cubic-bezier(.2,.8,.2,1),width .45s cubic-bezier(.2,.8,.2,1)}
/* THE POINTS DOOR (the owner, 2026-09-15: "make this leaderboards box start at the same level on the bottom as the card next to it, upwards, and show more mini stats in the form of mono graphs aligned with the theme, and clickable"; 17:4x: "this leaderboards thing is not looking nice, it's very narrow, needs a better design"; 18:2x: "make the stats box a bit taller, two more rows of stuff that are valuable, maybe about their marks etc, so Otty goes higher and his chat bubble aligns with the top of the white box", "make Otty as big as it gets in this space also"): the stats as tiles, two to a row, the figure large on its own line, the label small under it, the mono graph faint along the tile's foot with the current bar in the sky; a tile is a tap into its tab or its page */
.door .f{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px}
.door .stat{position:relative;display:grid;grid-template-rows:auto auto;align-content:start;gap:1px;min-height:66px;padding:9px 12px 8px;border-radius:14px;background:rgba(255,255,255,.05);box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);color:#fff;text-decoration:none;overflow:hidden;transition:background .25s,box-shadow .25s}
.door .stat:hover{background:rgba(255,255,255,.1);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18)}
.door .stat .num{font-family:var(--mono);font-variant-numeric:var(--tab);font-size:15px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;position:relative;z-index:1}
.door .stat[data-warm] .num{color:#ffb4ad}
.door .stat .sm{min-width:0;font:400 11.5px/15px var(--sans);color:rgba(255,255,255,.7);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;position:relative;z-index:1}
.door .mini{position:absolute;left:12px;bottom:7px;width:calc(100% - 24px);height:12px;opacity:.5}
.door .mini rect{fill:rgba(255,255,255,.7)}
.door .mini .dim{fill:rgba(255,255,255,.25)}
.door .mini .on{fill:var(--sky)}
/* ── THE GUARDIAN'S PAGES ── */
/* the change of grade, curriculum or format (the owner, 2026-09-16 17:4x SAST): the learner card's sheet stands its preview row under the chips */
[data-change-sheet] .notice{margin:16px 0 0}
/* one family (the owner, 2026-09-15 18:5x: "elegance and unity") on the three places and their three flows (the ones with a way back; the enrolment flow is not one): the head's name at 24/500 with its one line, the first row 12 px under it; the well with the figure first (.ask.sum: the mono figure, the words under it, the one-word act); the way to another learner is the tabs' plus alone (the owner, 2026-09-16 01:0x: "too many add-a-learner places") */
[data-side=guardian]:is(:not(.flow),[data-back]) .who .nm{font-weight:500;font-size:24px;line-height:30px}
[data-side=guardian]:is(:not(.flow),[data-back]) .who > :is(.nm,.fx) + .kv{margin-top:calc(var(--head) - var(--row))}
[data-side=guardian].flow .who > :is(.nm,.fx) + .fields{margin-top:var(--head)}
.ask.sum .amt{margin-top:0}
.ask.sum .t small{margin-top:4px}
/* ── THE LEARNER'S BLOCK AS TWO CLEAN COLUMNS (the owner, 2026-09-16 01:0x, after the three wells: "not elegant or aligned with the theme; too many add-a-learner places; revert the tabbing and the plus; next to the plus just 'Add a learner' and the 5 % off label more elegantly, not in green; Now moves under Otty as we have it now; the other two can stay as columns but clean columns like the course side, not wells") ── */
/* the head's one plain line; School and Profile as two plain columns from 740 px (one on a phone), the kickers as the column heads, the rows as they are, no well; the tabs' plus says Add a learner with the sibling figure as quiet muted text beside it */
.who .cols{display:grid;gap:0 48px}
@media (min-width:740px){.who .cols{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.tab.plus{gap:8px}
.tab.plus .chip{display:inline;height:auto;padding:0;border-radius:0;background:none;box-shadow:none;font:400 12.5px/1 var(--sans);color:var(--mute);cursor:inherit;white-space:nowrap}
/* a phone's tab row: the plus keeps its word and drops the figure beside two names, and stands alone beside three or more */
@media (max-width:599px){.tabs:not(.one) .tab.plus .chip,.tabs:has(button.tab:nth-of-type(3)) .tab.plus span{display:none}}
/* THE NEXT YEAR'S ROW (the owner, 2026-09-16 09:1x: re-enrol on every learner card, "the emphasis should be re-enrol and then a smaller, less emphasised 'XYZ is not coming back' button"): the Profile row's right side is the pill with the quiet link under it, the pill at the row pill's size; on a phone the pill takes the column's width and the link stands under it at the row's end */
.kv .v.acts.next{flex-direction:column;align-items:flex-end;gap:10px}
.kv .v.next .go:not(.quiet){padding:7px 7px 7px 18px;font-size:14px}
.kv .v.next .go:not(.quiet) i{width:28px;height:28px;font-size:15px}
.kv .v.next .go.quiet{font-size:13.5px;color:var(--mute)}
.kv .v.next .go.quiet:hover{color:var(--ink)}
@media (max-width:560px){.kv .v.acts.next{justify-self:stretch;align-items:stretch;padding-top:4px}.kv .v.next .go:not(.quiet){justify-content:space-between}.kv .v.next .go.quiet{align-self:flex-end}}
/* ── THE ENROLMENT'S FORM ── */
/* the owner, 2026-09-15 19:2x ("do better on the design and spacing here"): every step is one reading column, 720px at most, at the left of the white box; the step's title at the head's 24/500 with its one-line lead under it; the rows of a form 20px apart and a label 8px over its field; the names on one row (first, the middle when the family has one, surname) and the date of birth alone; a group's label 28px under what stands before it and 8px over its own controls; the chips a wrapped row of 44px pills, never stretched across the box; the helper small and quiet under them; the payment step keeps the pay page's own tree; the rail and the foot unchanged. The rows follow the column's own width (a container), so the door's card and the name sheet lay the names the same way */
.flow .step:not([data-step=fee]),.enroldoor form.who,.flow .who:has(.fields.name){container-type:inline-size}
.flow .step > .nm{font:500 24px/30px var(--sans);letter-spacing:-.02em;color:var(--ink);text-wrap:pretty}
.flow .step > .fx{margin-top:4px;font:400 15px/22px var(--sans)}
.flow .step:not([data-step=fee]) .fields{grid-template-columns:1fr;gap:20px 16px;margin-top:24px}
.flow .step:not([data-step=fee]) .fields + .fields{margin-top:20px}
.flow .step:not([data-step=fee]) .fld{gap:8px}
.fields.name{grid-template-columns:1fr}
@container (min-width:560px){
  .flow .step:not([data-step=fee]) .fields{grid-template-columns:1fr 1fr}
  .fields.name,.flow .step:not([data-step=fee]) .fields.name{grid-template-columns:1fr 1fr 1fr}
}
/* the three names share two rows, the labels in one and the fields in one, so a label that wraps (the middle name's at 1024) never pushes its field down (the owner, 2026-09-15 20:0x: "a nice design still on all devices with this field") */
@container (min-width:560px){
  .fields.name{grid-template-rows:auto auto auto;grid-auto-flow:column;row-gap:8px;align-items:end}
  .fields.name > .fld{display:contents}
  .fields.name > .fld > span{align-self:end;grid-row:1}
  .fields.name > .fld > input{grid-row:2}
  .fields.name > .fld > .line{grid-row:3}
}
.enroldoor .fields.name + .fields{margin-top:14px}
.flow .step .gt{margin:28px 0 8px}
.flow .step > .head{margin:28px 0 8px}
.flow .step > :is(.nm,.fx) + .gt,.flow .step > :is(.nm,.fx,.meta) + :is(.opts,.head){margin-top:24px}
.flow .step .opts,.flow .step > .chips,.flow #groups .chips,.flow .step .list,.flow .step .check{margin-top:0}
.flow .step > .chips,.flow #groups .chips{display:flex;flex-wrap:wrap;gap:8px}
.flow .step > .chips .chip,.flow #groups .chip{height:44px;padding:0 18px;font:500 15px/1 var(--sans)}
.flow .step > .chips.grid .chip{min-width:52px;padding:0 14px}
.flow .step > .meta{margin-top:10px;max-width:56ch;text-wrap:pretty}
.flow .step > .meta + .meta{margin-top:4px}
.flow .step > .go.quiet{margin-top:20px}
.flow .step > .fx + .doc{margin-top:10px}
@media (max-width:1279px){
  /* up to 1280px the week has no room beside the box: the statement, the box across, the week under it across */
  .app.enroldoor .stage{grid-template-columns:1fr;grid-template-rows:auto auto}
  .app.enroldoor .statement{grid-column:1;grid-row:1}
  .app.enroldoor .shell{grid-column:1;grid-row:2;width:min(100%,760px)}
}
@media (max-width:999px){
  .flow .card{overflow:clip}
  .flow .body{overflow:visible;flex:none}
  /* the stage keeps the bar's room as padding, so the foot sticks at that padding's edge, just above the bar */
  .flow .foot{position:sticky;bottom:0}
  /* the enrol door on a phone or tablet: the words, then the form */
  .enroldoor .stage{grid-template-columns:1fr;grid-template-rows:auto auto;padding-top:8px}
  .enroldoor .statement,.enroldoor .shell{grid-column:1}
  .enroldoor .statement{grid-row:1;padding:8px 0 12px}
  .enroldoor .statement h1{font-size:26px;margin:8px 0 6px}
  .enroldoor .statement p{font-size:14px;line-height:20px}
  .enroldoor .statement p br{display:none}
  .enroldoor .shell{grid-row:2}
  .isl.two .seg{padding:0 10px;font-size:13px}
  /* on a phone every control is at least 16px, so iOS never zooms into a field and the person never has to zoom back out */
  input,select,textarea{font-size:max(1em,16px)}
  .enroldoor .glance{gap:8px 20px;margin-top:12px}
  /* ── FILL (the owner, 2026-09-15, a trial on the Learners page for his eye): on a phone and a tablet the white box fills the screen edge to edge and down to the bottom; only its top curve with the glass ring around it stays; the bar floats over the white as light glass with our icons in ink ── */
  html[data-fill=on] .app:not(.door):not(.enroldoor){--band:4px;--round:24px;--card-r:var(--round) var(--round) 0 0;--rim-r:28px;--round-shell:var(--rim-r) var(--rim-r) 0 0}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .stage{display:flex;flex-direction:column;padding:0;overflow:hidden;max-width:none}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .otty{margin:0;--osz:104px;padding:calc(10px + env(safe-area-inset-top)) 14px 12px;column-gap:14px}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .otty .say{margin-right:54px}
  /* THE SLOT ON A PHONE AND A TABLET (the learner test lane's F4, 2026-09-16; the plate comment above: "on a phone the plate takes its own line under him and his words"): the slot is its own line under the top band (him, his words, the capsule) and over the card, at the card's width with the card's side gutters (the rim and the card's padding past the band's own), drawn only when it holds something; the band grows by it and the card stands under it from the first paint, since the learner's tiles and the guardian's rows come with the kept snapshot */
  .otty:has(> .under){grid-template-areas:'mount say' 'under under'}
  /* the learner's points plate is a desk thing (the owner, 2026-09-16 17:1x: "leaderboards is too big, we do not want to see this on mobile and tablet"): hidden under 1180 px; the guardian's pending rows keep their line */
  .learn .otty > .under.door{display:none}
  .learn .otty:has(> .under.door){grid-template-areas:'mount say'}
  .otty > .under{grid-area:under;display:block;margin:10px 0 0}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .otty > .under{margin:10px calc(var(--band) + var(--gut) - 14px) 0}
  .otty > .under:empty:not(.door){display:none;margin:0}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .stage > .shell{flex:1 1 auto;min-height:0;width:100%;margin:0;padding:var(--band) var(--band) 0;border-radius:var(--round-shell,var(--rim-r));display:flex;flex-direction:column;box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 1px 0 0 rgba(255,255,255,.14),inset -1px 0 0 rgba(255,255,255,.14)}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .stage > .shell::after{inset:var(--band) var(--band) 0}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .stage > .shell > .card{flex:1 1 auto;min-height:0;border-radius:var(--card-r);overflow:auto;overscroll-behavior:contain;padding-bottom:calc(100px + env(safe-area-inset-bottom))}
  /* THE TOP ON A PHONE AND A TABLET, a trial (the owner, 2026-09-15 12:3x UTC: "move Otty to the top, no need for the menu bar and the T, fit his message nicely there, so there is more space for the white and Otty can be slightly larger"): the top bar folds to the bell alone at the top right; Otty and his words take the top row, he a little larger; the white box starts higher */
  html[data-fill=on] .top{position:absolute;right:10px;left:auto;width:auto;height:auto;padding:0;z-index:7;top:calc(10px + env(safe-area-inset-top))}
  html[data-fill=on] .top .logo{display:none}
  /* the island stands upright at the top right: the bell over the initials, both round, the account menu on the initials */
  #me .ini{display:none}
  html[data-fill=on] .top .isl{flex-direction:column;padding:3px;gap:2px}
  html[data-fill=on] .top .rule{display:none}
  html[data-fill=on] .top #me .nm,html[data-fill=on] .top #me .chev{display:none}
  html[data-fill=on] .top #me .ini{display:grid;place-items:center;width:38px;height:38px;border-radius:50%;background:rgba(255,255,255,.14);font:600 13px/1 var(--sans);letter-spacing:.02em;color:#fff}
  html[data-fill=on] .top #bell,html[data-fill=on] .top #me{width:44px;height:44px;padding:0;justify-content:center;border-radius:50%}
  /* the drawer on a phone and a tablet: the upright capsule stays as it is, the two as stacked tabs, the pane under it as wide as the screen less the gutters */
  html[data-fill=on] .me.open .isl{border-radius:25px 25px 0 0}
  /* the pane's edges are the card's rim on both sides (the owner, 02:1x: "open on the borders of the card under, aligned"): the island stands 10px in, the shell at the screen's edge, so the pane reaches the edge at the right and the left */
  html[data-fill=on] .drawer{right:-10px;width:100vw;max-height:calc(100dvh - 150px - env(safe-area-inset-top))}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .otty .say b{font-size:17px;line-height:23px}
  html[data-fill=on] .app:not(.door):not(.enroldoor) .otty .say small{font-size:14px;line-height:19px}
  .popup{--rim:4px;width:calc(100vw - 32px - 2 * var(--rim));height:calc(100dvh - 96px);border-radius:24px}
  .popup::before{border-radius:28px}
  .popup::after{border-radius:24px}
}
@media (max-width:739px){
  /* a phone, the live door's band (top): the words at the top, his row taking the room between them and the card, the card under him; nothing pinned */
  .door .stage{grid-template-rows:auto auto auto;align-content:start;padding-bottom:24px}
  .door .statement{display:block;grid-row:1;width:min(100%,540px);margin:0 auto;padding:12px 0 6px}
  /* on a phone the dock takes the foot's Back and act; the foot's line goes with them, so no bare line floats over the words */
  /* ── LEARN UNIFY ── */
  /* a phone: his row hugs his box (the design's close rhythm), so the card stands right under him and he never covers the words above */
  .door .otty{grid-row:2;min-height:calc(var(--fig) + 6px);margin:4px 0 8px}
  .door .shell{grid-row:3}
  .door .statement h1{font-size:30px;margin:10px 0 8px}
  .door .statement h1 br{display:none}
  .door .statement p{font-size:15px;line-height:22px;max-width:none}
  /* the chat disc's clear band at the foot of a phone's enrol door (the sweep, 2026-09-15): the terms line's last link never under it */
  .enroldoor .stage{padding-bottom:96px}
  /* a phone: his row between the words and the card, the box at the left with most of its empty margin off the screen's edge (0.12 of the box, not the 0.18 the base names: at 0.18 his waving hand touched the edge, the learner test lane's F12; at 0.12 it clears it by the page's gutter and his body stands a little right of the words' edge), his words at his right at the row's middle with the tail toward him, capped so they never leave the row */
  .door .otty .mount{left:calc(var(--fig) * -0.12)}
  .door .otty .say{left:calc(84% + 8px);right:auto;bottom:auto;top:36%;transform:translateY(-50%);max-width:calc(var(--room,100vw) - var(--fig) * 0.68 - 8px);font-size:14px;line-height:20px;padding:12px 16px}
  .door .otty .say::after{left:-7px;right:auto;bottom:auto;top:50%;margin:-6px 0 0;transform:rotate(135deg);box-shadow:inset 1px -1px 0 0 rgba(255,255,255,.14)}
  .door .otty .say::before{clip-path:polygon(evenodd,-60px -60px,calc(100% + 60px) -60px,calc(100% + 60px) calc(100% + 60px),-60px calc(100% + 60px),-60px 50%,-10.5px 50%,-2px calc(50% + 8.5px),1px calc(50% + 7.5px),1px calc(50% - 7.5px),-2px calc(50% - 8.5px),-10.5px 50%,-60px 50%)}
}
@media (max-width:666px){
  /* the chat panel on a phone: below the status bar and the notch, so its Back and X are in reach; nothing else changes */
  /* the vendor's full screen under 667px stands on the navy field: the frame's ground is clear on every width (the Desk sheet), so the holder paints the field under it */
  /* on a phone the same paper card in the same band (the owner, 2026-09-15 17:5x: "the mobile full screen version needs to match that too"): the vendor's full screen stands 8px in from the screen's edges with the 7px band around the paper */
  html .woot-widget-holder{top:calc(8px + env(safe-area-inset-top))!important;left:8px!important;right:8px!important;bottom:8px!important;width:auto!important;height:auto!important;max-height:none!important;background:var(--rim);-webkit-backdrop-filter:var(--rim-blur);backdrop-filter:var(--rim-blur);box-shadow:var(--rim-ring)}
}
@media (max-width:600px){
  /* the same table on a phone: five columns of the width there is, the subject on two lines, the teacher left out */
  .ttwrap{overflow:visible;margin:6px 0 0;padding:0}
  .tt{min-width:0;gap:3px;grid-template-columns:auto repeat(var(--n,5),minmax(0,1fr))}
  .tt .th{font-size:11px}
  .tt .tm{font-size:10.5px;padding:7px 4px 0 0}
  .tt .cell{padding:6px 6px 7px;min-height:44px;border-radius:8px}
  .tt .cell b{font-size:11px;line-height:14px;overflow-wrap:normal;hyphens:manual}
  .tt .cell small{display:none}
  .tt .cell .mini{font-size:11px;margin-top:4px}
  .tt .cell .long{display:none}
  .tt .cell .short{display:inline}
}
@media (max-width:599px){
  /* on a phone the frames close up on every page: one narrow gutter, a thin shell, a tighter box and tighter wells, so the width goes to the words and the fields */
  /* the phone, tighter still: the gutter, the shell, the box, the rows and the labels */
  .stage{overflow-x:hidden;padding-left:8px;padding-right:8px}
  .otty{padding:4px 8px 10px;margin-left:-8px;margin-right:-8px}
  .app{--band:3px;--round:23px;--rim-r:26px;--gut:14px}
  .shell{padding:var(--band);border-radius:var(--rim-r)}
  .card{padding:16px var(--gut) 18px;border-radius:var(--card-r)}
  .fields{gap:12px 12px}
  .paybox,.ask,.got,.notice,.well{padding:12px 14px}
  .fld input,.fld select{padding-left:12px;padding-right:12px}
  .fld select{padding-right:36px}
  /* the door on a phone: the words, otty and the box close together, the box hugging its content */
  .door .statement{padding:8px 0 2px}
  .door .statement h1{font-size:27px;margin:8px 0 6px}
  .door .card{min-height:0}
  .door .card .who{flex:none}
  .door .tabs.ways{margin:-2px 0 16px}
  :root{--row:10px;--kick:18px;--head:20px}
  .gt{margin-bottom:6px}
  .tabs{margin-bottom:12px}
  .who .nm{font-size:21px;line-height:26px}
  .who .fx{margin-top:2px}
  /* on a phone every billing row's figures end at the same right edge: the chevron column goes (the whole row is the link) */
  .kv.inv:not(.pay){grid-template-columns:minmax(0,1fr) auto}
  .kv.inv:not(.pay) .a{display:none}
  /* on a phone the box fills the screen to the bar from the first paint (the frame is CSS, never a script): the stage is a column, the shell takes the free space and never less than its content, the card fills it, more scrolls */
  .app:not(.door):not(.enroldoor) .stage{display:flex;flex-direction:column;padding-bottom:0}
  .app:not(.door):not(.enroldoor) .stage > .shell{flex:1 0 auto;display:flex;flex-direction:column}
  .app:not(.door):not(.enroldoor) .stage > .shell > .card{flex:1 1 auto}
  .prose table.stacked,.prose table.stacked :is(tbody,tr,td){display:block;width:100%!important}
  .prose table.stacked tr.head-row{display:none}
  .prose table.stacked tr{border:1px solid var(--line);border-radius:10px;padding:8px 12px;margin-top:8px}
  .prose table.stacked td{border:0;padding:2px 0}
  .prose table.stacked td::before{content:attr(data-th) ' ';color:var(--mute)}
  .prose table.stacked td>:is(p,div):only-child{display:inline}
  /* the white box to the foot of the page on every size: flush on a phone and a tablet (the fill), with its whole frame on the desk (the stage's own padding) */
  /* the sheet's rim is the card's shell at every size: the same width of glass and the same corners (the phone's shell is 3px and 26px round, its card 23px) */
  .offer .sheet{border-radius:23px}
  .offer .sheet::after{border-radius:23px}
  .offer .sheet::before{inset:-3px;border-radius:26px}
  .shell > .barwrap > .acts .go{width:58px;padding:0;justify-content:center;font-size:0;gap:0}
  .shell > .barwrap > .acts .go i{margin:0;background:none;width:24px;height:24px}
  .shell > .barwrap > .acts .go i svg{width:24px;height:24px}
  .popup{--rim:3px;border-radius:23px}
  .popup::before{border-radius:26px}
  .popup::after{border-radius:23px}
  .popup .hd{padding:18px 18px 0}
  .popup .tabs{padding:0 18px;justify-content:space-between}
  .popup .tab{flex:0 1 auto;font-size:14px;padding:6px 4px 12px}
  .popup .panel{padding:12px 18px 18px}
  .popup .hero.act{grid-template-columns:1fr}
  .popup .hero .go{justify-self:start}
  .popup .strip{width:calc(100% + 36px);margin:10px -18px 0;padding:4px 18px 9px}
  [data-side=guardian]:is(:not(.flow),[data-back]) .who .nm{font-size:22px;line-height:28px}
  .flow .step > .nm{font-size:22px;line-height:28px}
}
@media (max-width:560px){
  .ask{grid-template-columns:1fr}
  .ask .go{justify-self:stretch;justify-content:space-between}
  .kv.inv{grid-template-columns:minmax(0,1fr) auto 72px;column-gap:12px}
  .kv.inv .a .go{padding:6px 6px 6px 14px}
  /* on a phone the two acts stand on their own line under the words, at the row's end */
  .kv:has(> .v.acts){grid-template-columns:minmax(0,1fr)}
  .kv .v.acts{justify-self:end;padding-top:8px}
  .paycard{padding-top:10px}
  .paywait{padding:18px 16px 16px}
  .paycard .payframe{margin:0 -10px}
  .kv.inv.pay{grid-template-columns:minmax(0,1fr) auto;row-gap:10px}
  .kv.inv.pay .a{grid-column:1/-1}
  .offer .foot{flex-direction:column-reverse;align-items:stretch;gap:12px}
  .offer .foot .go{justify-content:space-between}
  .offer .foot .go.quiet{justify-content:center}
  .kv.qr{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:484px){
  /* the pill is the same on every size, never squeezed (the owner, 2026-09-15: "never make the pill different, always the same size"). SUPPORT GOES ON A NARROW FLOW (the owner, 16:2x: "reduce the gap between the circles and the pill first to see if the fourth icon can fit; if absolutely not possible just don't show the Support icon on very narrow pages; the circles need padding from the screen corner"): the row holds the whole pill (341) with the two rounds (116) and 4px gaps only from 485px; under that a flow's pill drops Support and its rule (246 wide) and the rounds keep 7 to 16px from the corners, the fr columns taking the slack; under 380px the places narrow to 70 with a 10px word padding so a 360 phone holds the row to the pixel (the words never go). A page without sides keeps the whole pill on every size; on a phone the action is a round with its glyph */
  .app.flow:not(.door):not(.enroldoor) .shell > .barwrap{padding:0 clamp(7px,(100% - 370px) / 2,16px);gap:4px;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr)}
  .app.flow:not(.door):not(.enroldoor) .shell > .barwrap > .bar > .rule,.app.flow:not(.door):not(.enroldoor) .shell > .barwrap > .bar > .sup{display:none}
}
@media (max-width:479px){
  .prose table[data-cols='2']:not(.kvt),.prose table[data-cols='2']:not(.kvt) :is(tbody,tr,td,th){display:block;width:100%!important;white-space:normal}
  .prose table[data-cols='2']:not(.kvt) tr{padding:8px 0;border:0;border-bottom:1px solid var(--line)}
  .prose table[data-cols='2']:not(.kvt) :is(td,th){padding:0;border:0}
  .prose table[data-cols='2']:not(.kvt) :is(td,th):first-child{font:600 13px/20px var(--sans);margin-bottom:2px}
  .prose .in2,.prose .in3{padding-left:22px}
}
@media (max-width:379px){
  .app.flow:not(.door):not(.enroldoor) .shell > .barwrap .sg{min-width:70px;padding:0 10px}
}
@media (min-width:600px){
  .fields{grid-template-columns:1fr 1fr}
  /* the chat panel from 600px slides in from the right (chat.js places it as the card's box, the rule at its place() ; a door keeps its panel on the rim, the 667px rule) */
  .woot-widget-holder.woot--hide{transform:translateX(48px)}
  .fields .wide{grid-column:1/-1}
}
@media (min-width:600px) and (max-width:999px){
  /* a tablet's sheet rim is the tablet's shell: 4px of glass, 28 round, the card 24 */
  .offer .sheet{border-radius:24px}
  .offer .sheet::after{border-radius:24px}
  .offer .sheet::before{inset:-4px;border-radius:28px}
}
@media (min-width:667px){
  /* the panel (the vendor's holder) from 667px floats on the bubble's right line, its foot 16px over the bubble's top (the bubble's 20 and 56; 28 from 1000px), the card's radius and hairline shadow; under 667px the vendor's full screen stands untouched (a right offset there pushes the whole panel off the left edge) */
  /* no cast shadow around the glass (the owner, 2026-09-15 14:1x: "it has a shadow around the glass"): the widget's own sheet draws the rim; the holder is clear so the page shows through the rim */
  /* the panel over the white card wears the pill's own edge (the ink ring and its soft cast), so it reads on white and on the navy alike (the owner, 2026-09-15 16:5x: "now this is impossible to see") */
  /* the chat panel: the card's paper edge at its right, its foot 14px over the bar's row, the card's rim and rounds */
  /* the chat panel wears the dropdown sheet's dress exactly (the owner, 2026-09-15 17:1x and 17:4x: "make the surrounding box of the chat box the same as the notification dropdown"; "still has three borders"): the holder itself is the frosted band (the sheet's ::before: the 6 percent white, the blur, the white ring) around the paper frame at the 25px round; no outer shadow lines; the panel's band lies on the card's own rim exactly as the dropdown's does (the paper's right edge 23px from the screen's, the band over the shell's 7px), so the blur mixes the navy and the white along it (the owner, 17:4x: "the notifications fall on the border of the card under it, that's why it shows a nice mixed colour on its border; do the same for the chat"); the widget's own sheet draws no rim (desk-web) */
  html .woot-widget-holder.woot-elements--right{right:max(16px,calc((100vw - 1760px) / 2 + 16px));bottom:95px;height:min(640px,calc(100dvh - 102px - 88px))!important;max-height:none!important;background:var(--rim);-webkit-backdrop-filter:var(--rim-blur);backdrop-filter:var(--rim-blur);box-shadow:var(--rim-ring)}
  /* the one X over the panel's corner: the bar's glass round, the thin ink cross */
  .chatx{position:fixed;z-index:2147483001;width:36px;height:36px;padding:0;border:0;border-radius:50%;display:grid;place-items:center;cursor:pointer;color:var(--ink);background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);box-shadow:var(--glass-ring);animation:bub-in .26s cubic-bezier(.2,.7,.2,1)}
  .chatx:hover{background:var(--lens);box-shadow:var(--lens-ring)}
  .chatx svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round}
  .chatx[hidden]{display:none}
}
@media (min-width:700px){
  .flow .list{columns:2;column-gap:32px}
}
@media (min-width:740px){
  /* the door stands as a row from 740px, the live door's band (right): otty beside the card in the last column; up to 839px the live door's proportions (the card minmax(360px,1fr), his column the rest, 32px gutters), from 840px the design's columns */
  /* the statement stands above the box and otty spans both rows, so the box keeps its width; from 1280px the three stand in a row */
  .door .stage{grid-template-columns:minmax(360px,1fr) minmax(0,1fr);grid-template-rows:auto auto;gap:8px 32px;align-items:center;align-content:center;justify-content:center;padding-left:32px;padding-right:32px}
  .door .statement{grid-column:1;grid-row:1;align-self:end;padding-bottom:28px}
  .door .statement h1{font-size:34px;margin:12px 0 10px}
  .door .shell{grid-column:1;grid-row:2;display:block}
  /* beside the card: his box hung from the cell's foot at the column's middle (--otty-x), the bubble's foot 8px over 0.09 of the box, so the tail hangs over his drawn head */
  .door .otty{grid-column:2;grid-row:1/3;--band:right;min-height:0}
  .door .card{flex:none;overflow:visible;justify-content:flex-start}
  .door .otty .mount{left:var(--otty-x,50%);bottom:0;margin:0 0 calc(var(--fig) * var(--feet) * -1);transform:translateX(-50%)}
  .door .otty .say{bottom:calc(100% - var(--fig) * 0.09 + 40px)}
}
@media (min-width:768px){
  .flow .opts.two{grid-template-columns:1fr 1fr;gap:12px}
  .veil.offer{align-items:center;padding:24px}
}
@media (min-width:840px){
  /* the three stand as one group in the middle of the page: the statement never on the edge */
  .door .stage{grid-template-columns:minmax(440px,560px) minmax(280px,420px);gap:8px clamp(24px,3.5vw,64px);padding-left:clamp(24px,4vw,80px);padding-right:clamp(24px,4vw,80px)}
}
@media (min-width:840px) and (max-width:1279px){
  /* from 1000 to 1279px the statement stands above the box: one line each, room under it, no forced breaks */
  .door .statement h1 br{display:none}
  .door .statement p{max-width:none}
}
@media (min-width:1000px){
  /* the top bar keeps to the same 1760px box as the stage: logo over the left edge, island over the right */
  .top{height:64px;padding:0 max(clamp(12px,2vw,24px), calc((100% - 1760px) / 2 + clamp(12px,2vw,24px)))}
  .logo img{display:block}
  .logo .mark{display:none}
  .stage{grid-template-columns:minmax(250px,.72fr) minmax(0,2.8fr);grid-template-rows:minmax(0,1fr);gap:clamp(16px,3vw,40px);align-items:stretch;align-content:stretch;overflow:hidden;padding-top:0;padding-left:clamp(12px,2vw,24px);padding-right:clamp(12px,2vw,24px)}
  /* the column is a grid of three rows (the greeting, him, the bar): the middle track is as wide as the bar and never wider than the column (fit-content), the greeting in it adds no width of its own (inline-size containment) so it is as wide as the bar, and he spans the three tracks centred; no script measures; the greeting holds two lines' height */
  /* his box is a true square: as tall as the column leaves him, never wider than the column */
  .otty{position:relative;z-index:auto;height:auto;min-height:0;container-type:size;display:grid;grid-template-columns:1fr auto 1fr;grid-template-rows:auto auto;align-content:center;grid-template-areas:'. say .' 'mount mount mount' '. bar .';margin:0;background:none;padding:28px 0 0;gap:0;--room:calc(100cqh - 28px - 118px - 66px);--osz:min(100cqw,var(--room),560px)}
  /* the greeting's box holds three lines whatever the day's words, so he never moves when the line is longer */
  /* the box holds three lines of the bold line and two of the small (the owner, 2026-09-15: "more gap for the text above Otty, so when it types three lines Otty doesn't have to move or the text go up"): the words start at its top, he stands under it, neither moves */
  .otty .say{padding:0;margin:12px 0 6px;width:min(460px,100cqw);max-width:100%;min-height:118px;overflow:visible;color:rgba(255,255,255,.92);justify-content:center}
  .otty .say b{font-size:20px;line-height:26px}
  .otty .say small{font-size:15px;line-height:21px}
  /* the column stands from its top, the greeting and him centred by the numbers alone (the owner, 2026-09-15 20:5x: "tab to tab it moves"): the pending rows that land under him later take the room below and move nothing above */
  .app:not(.learn) .otty{align-content:start;padding-top:max(0px,calc((100cqh - 136px - var(--osz)) / 2))}
  /* the one difference between the lanes (the owner, 2026-09-15): the learner's white box is wider, so his column is narrower and he is half the guardian's size; every other element is the same one */
  .learn .stage{grid-template-columns:minmax(220px,.42fr) minmax(0,3.2fr)}
  .learn .otty{--osz:min(100cqw,var(--room),420px)}
  .otty .mount{width:var(--osz);height:auto;aspect-ratio:1;align-self:start;justify-self:center;margin:0}
  .otty .barwrap{margin-top:0;justify-self:stretch}
  .otty .pick{position:static;transform:none;justify-self:center;margin-top:-6px}
  .shell{margin:0;width:100%;display:flex;flex-direction:column;min-height:0}
  .card{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
  /* from 1100px the bar lives in otty's column under him */
  /* under him the bar is a plain box (no container: its own width sizes the column's track, so the greeting is as wide as the bar); the icon fold for the narrowest column is the media rule below */
  .barwrap{position:static;width:100%;height:auto;justify-content:center;padding:0;container-type:normal}
  .sg,.sup{min-width:0}
  .sg{min-width:78px}
  .flow .weeks{grid-template-columns:1fr 1fr;gap:16px}
  .chatbubble{right:28px;bottom:28px}
  .app > .peek{right:28px;bottom:96px}
  .otty:has(> .under){grid-template-areas:'. say .' 'mount mount mount' '. under .' '. bar .';--room:calc(100cqh - 28px - 118px - 40px - var(--under,0px))}
  .otty > .under{grid-area:under;display:block;width:min(460px,100cqw);max-width:100%;margin:12px 0 0;justify-self:center}
  .otty > .under:empty:not(.door){display:none;margin:0}
  /* ── PENDING ── */
  /* what needs the guardian, as quiet acts in the slot under Otty on the desk (the owner, 2026-09-15: "under Otty maybe actions? what's pending, but very elegant, minimal, low text, and only there if it exists"): at most four rows in white on the navy, the small line muted, the act's word with a chevron at the end, no box and no lines; nothing at all when nothing waits; his room gives way by the rows' height (--pn, the count pending.js writes on the column) */
  .otty:has(> .under.pending){--under:calc(var(--pn,0) * 46px + min(var(--pn,0),1) * 12px)}
  .otty .say .bub{transform-origin:center bottom}
  .otty .say .bub::after{left:50%;top:auto;bottom:-5px;transform:translateX(-50%) rotate(45deg);box-shadow:inset -1px -1px 0 0 rgba(255,255,255,.14);clip-path:polygon(0 100%,100% 0,100% 100%)}
  html .woot-widget-holder.woot-elements--right{bottom:97px}
  /* the desk column with the door: the bubble's top on the card's paper top (the column's top is the shell's, the greeting's margin its 7px), his box the stretched square of the row between the bubble and the door with 10px of air each side (the width follows the height, capped by the column), the door on the paper's foot; no script measures */
  /* his box stays square: the shell measures the room left between the bubble and the door and sets --osz to the smaller of that and the column's width (a stretched grid item bent him, 2026-09-15 18:5x: "who asked to stretch") */
  /* he is placed by the door alone (the owner, 2026-09-15 22:3x: "here Otty moves based on the speech bubble, how can that be avoided"): the greeting's track is the flexible one, he and the words sit on its foot, so a longer line grows upward into the free room and never moves him */
  .learn .otty:has(> .under.door){padding-top:0;grid-template-areas:'. say .' 'mount mount mount' '. under .' '. bar .';align-content:stretch;grid-template-rows:minmax(0,1fr) auto auto auto}
  .learn .otty:has(> .under.door) .say{margin:7px 0 0;padding-bottom:14px;min-height:0;align-self:end}
  /* he stands on the door, never moving when the bubble grows (the owner, 19:0x: "Otty moves up and down, unify, clean up"; 21:5x: "and the gap" put the free room between him and the door, the 22:3x ruling above puts it over the words): him right under the words with the bubble's tail on his head, the door on the card's foot */
  .learn .otty:has(> .under.door) .mount{width:var(--osz);height:var(--osz);max-width:100%;align-self:end;justify-self:center;margin:0 0 44px}
  .learn .otty:has(> .under.door) > .under.door{margin:0 0 7px}
}
@media (min-width:1000px) and (max-width:1179px){
  .learn .otty > .under.door{display:none}
  .learn .otty:has(> .under.door){grid-template-areas:'. say .' 'mount mount mount' '. bar .';grid-template-rows:auto minmax(0,1fr) auto;align-content:start}
  .learn .otty:has(> .under.door) .say{align-self:start}
  .learn .otty:has(> .under.door) .mount{width:min(100%,var(--osz,300px));height:auto;aspect-ratio:1;align-self:start;margin:12px 0 0}
}
@media (min-width:1180px){
  .door .otty .say{font-size:17px}
}
@media (min-width:1400px){
  /* THE PAY STEP AS TWO COLUMNS ON A WIDE CARD (the owner, 2026-09-16 11:2x SAST, at a wide desk with Card details under the fold: "this pay page hides the card form under; how can it be improved so it is side by side?"): the summary at the left (the head and its line, the rows, Subtotal, the discount, Due now, Add a coupon, the Billing address row, the word and the note) and the pay box at the right from the head's top (the tabs' blocks: the address gate, the processor's frame, the bank slip), the box at its content's height (400 to 480 wide, the summary never under 320; the step's 720px reading cap lifted here alone); the same nodes as the one column, placed by the grid alone (the host's own box dissolved, the box across every row, the last row the flexible one so the rows keep the summary's rhythm), so the processor's frame never remounts across a resize; one column again once the box is gone (paid, closed, the document) */
  .flow .who:has(> .payhost > [data-pay]:not([hidden])){display:grid;grid-template-columns:minmax(320px,1fr) minmax(400px,480px);grid-template-rows:repeat(11,auto) minmax(0,1fr);column-gap:clamp(32px,5%,56px);align-items:start;max-width:none}
  .flow .who:has(> .payhost > [data-pay]:not([hidden])) > .payhost{display:contents}
  .flow .who:has(> .payhost > [data-pay]:not([hidden])) > :not(.payhost),.flow .who:has(> .payhost > [data-pay]:not([hidden])) > .payhost > :not([data-pay]){grid-column:1}
  .flow .who:has(> .payhost > [data-pay]:not([hidden])) > .payhost > [data-pay]{grid-column:2;grid-row:1/-1;margin-top:0}
  /* the box's kicker (Card details) on the head's line: a grid item never folds its child's margin into its own, so the step's 28 px kicker margin is set to the head's cap here alone */
  .flow .who:has(> .payhost > [data-pay]:not([hidden])) > .payhost > [data-pay] [data-block]>.gt{margin-top:5px}
  /* THE DOCUMENTS STEP AS TWO COLUMNS ON A WIDE CARD (the owner, 2026-09-16 18:4x SAST, at a wide desk with the three cards in a row and the panel under them in the 720px column: "I do not understand why half of the screen is not used for this; this needs a better UX"): the same grid as the pay step's: the head and its line, the slots as a column of picture cards (300 to 340 wide, each the picture beside its name and word) and Do this later on the left; the picked slot's panel on the right from the head's top, its read rows open and the fold's tap a kicker (the room is there); the same nodes as the one-column tree placed by the grid alone (the host `.docs` dissolves), so a resize keeps the picker's input and the read's state; the step's 720px reading cap lifted here alone */
  .flow .who:has(> .docs > .dpanel){display:grid;grid-template-columns:minmax(300px,340px) minmax(0,1fr);grid-template-rows:repeat(5,auto) minmax(0,1fr);column-gap:clamp(32px,5%,56px);align-items:start;max-width:none}
  .flow .who:has(> .docs > .dpanel) > .docs{display:contents}
  .flow .who:has(> .docs > .dpanel) > :not(.docs),.flow .who:has(> .docs > .dpanel) > .docs > :not(.dpanel){grid-column:1}
  .flow .who:has(> .docs > .dpanel) > .docs > .dpanel{grid-column:2;grid-row:1/-1;min-width:0}
  .flow .who:has(> .docs > .dpanel) .dcards{grid-template-columns:minmax(0,1fr);gap:8px;margin:var(--head) 0 0}
  .flow .who:has(> .docs > .dpanel) .dcard{grid-template-columns:88px minmax(0,1fr);grid-template-rows:auto auto;column-gap:14px;row-gap:1px;align-content:center;padding:10px 14px 10px 10px;border-radius:14px}
  .flow .who:has(> .docs > .dpanel) .dcard .pic{grid-row:1/3;width:88px}
  .flow .who:has(> .docs > .dpanel) .dcard .pic img.sample{width:48px}
  .flow .who:has(> .docs > .dpanel) .dcard .t{align-self:end;font-size:15px;line-height:20px}
  .flow .who:has(> .docs > .dpanel) .dcard .s{align-self:start}
  .flow .who:has(> .docs > .dpanel) .doc{padding-top:0}
  .flow .who:has(> .docs > .dpanel) .doc .dh .k{font-size:20px;line-height:30px}
  .flow .who:has(> .docs > .dpanel) .doc .read[data-open] .rows{display:block}
  .flow .who:has(> .docs > .dpanel) .doc .read .fold{pointer-events:none}
  .flow .who:has(> .docs > .dpanel) .doc .read .fold i{display:none}
  .flow .who:has(> .docs > .dpanel) .later{margin-top:16px}
}
@media (min-width:1280px){
  /* the guardian's white box a bit wider and his column a bit narrower, still wider than the learner's .42fr (the owner, 2026-09-16 21:1x: "on the guardian portal make the main card a bit wider and Otty's side a bit smaller, but not as much as the learner side") */
  .stage{grid-template-columns:minmax(340px,.85fr) minmax(0,2.15fr)}
  .door .stage{grid-template-columns:minmax(200px,320px) minmax(440px,540px) minmax(280px,420px);grid-template-rows:1fr auto 1fr}
  .door .statement{grid-column:1;grid-row:2;align-self:center;padding-bottom:0}
  .door .statement h1{font-size:clamp(30px,3.2vw,42px)}
  .door .shell{grid-column:2;grid-row:2}
  .door .otty{grid-column:3;grid-row:2}
}
@media (display-mode:standalone){
  /* ── APP: install and notifications ── */
  /* installed on a phone the status bar lies over the page: the app steps down by the top inset, the field's seam with it */
  .app{padding-top:env(safe-area-inset-top)}
  .otty{background-position:0 calc(-56px - env(safe-area-inset-top))}
}
@media (max-height:560px){
  /* a short screen (under 560px tall): his column goes, as at the live door */
  .door .otty{display:none}
}
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}
  .scanbar i{animation:none;left:0;width:100%;opacity:.35}
  .otty .say .bub{animation:none}
}
/* a note with acts (a waiting device): its buttons in a row under its words */
.sheet .n .acts{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin-top:8px}
.sheet .n .go{cursor:pointer;border:0}
/* reduced motion: no page change animation, no breathing, no film; the pages stand still */
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}
