/* T19: manifesto type system on a dark page, liquid-glass navigation and
   buttons, the real notch material over the guided-onboarding wallpaper, and
   shorter pinned transitions. Loaded last; V19 stays intact underneath so every
   change here can be compared or removed on its own. */

@font-face{font-family:"Inter Variable";src:url('assets/InterVariable.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap}
/* Strength of the rim light under the pointer; registered so it can transition. */
@property --lg-hot{syntax:'<number>';inherits:true;initial-value:0}

html:has(.t19){background:#000;color-scheme:dark}
.t19{
 /* Manifesto type scale. Every T19 font-size references one of these. */
 --t-display:clamp(48px,4.444vw,80px);   /* hero title: 64px at 1440, capped at 80 (owner, 11 Oct) */
 --t-h1:clamp(48px,5.5vw,84px);
 --t-lede:clamp(22px,2.1vw,32px);
 --t-callout:clamp(20px,1.9vw,28px);
 --t-intro:clamp(18px,1.5vw,24px);
 --t-body:18px;
 --t-body-sm:16px;
 --t-small:15px;
 --t-label:12px;
 --t-brand:24px;
 --ls-display:-.045em;
 --ls-tight:-.03em;
 --ls-label:.13em;
 --serif:"Iowan Old Style","Palatino Linotype",Palatino,Baskerville,"Times New Roman",serif;
 --sans:"Inter Variable",Inter,"Helvetica Neue",Helvetica,sans-serif;
 --spring:cubic-bezier(.3,1.25,.4,1);
 /* Dark is the default theme. V19's tokens are re-pointed here, so a light
    theme later is a second set of these four values. */
 --ink:#fff;--paper:#000;--muted:rgba(255,255,255,.62);--line:rgba(255,255,255,.14);
 --display:var(--t-display);--section-title:var(--t-display);--body:var(--t-body-sm);
 font-family:var(--sans);color:var(--ink);
}
@media(max-width:600px){
 .t19{--t-display:clamp(34px,10vw,40px);--section-title:var(--t-display);--t-h1:clamp(34px,10vw,40px);--t-lede:22px;--t-callout:20px;--t-intro:18px;--t-body:17px;--t-brand:20px}
}

/* ---------- Vertical only ----------
   The page scrolls up and down and nowhere else (owner, 11 Oct): nothing can pull it sideways,
   by wheel, trackpad, touch or script, and a sideways swipe does not rubber-band it. */
html,body{overflow-x:clip}
html{overscroll-behavior-x:none}
body{touch-action:pan-y pinch-zoom}
@supports not (overflow:clip){html{overflow-x:hidden}}

/* ---------- Scroll cost ----------
   V19 gives every word of body copy its own compositor layer (will-change:
   opacity) for a word-by-word reveal that it then completes on the first frame.
   That is about 180 idle layers the compositor carries through every scroll. */
.t19 .body-copy .w{will-change:auto}

/* ---------- Dark surfaces ---------- */
.t19 .hero{background:radial-gradient(ellipse 60% 52% at 50% 44%,#0f0f11,#000 78%)}
.t19 .voice,.t19 .meeting,.t19 .context,.t19 .talking-fold,.t19 .talking-stage,.t19 .screen-frame{background:var(--paper)}
.t19 .orb-dive-stage:after{background:var(--paper)}
.t19 .free{background:radial-gradient(ellipse at bottom,#151517,transparent 70%)}
.t19 a:visited{color:currentColor}
.t19 .skip{background:#fff;color:#000}
/* One focus ring everywhere (V19's was green). */
.t19 :focus-visible{outline:2px solid #fff;outline-offset:2px}
.t19 img.icon{filter:invert(1)}
.t19 .feature-copy li,.t19 .dictionary-note,.t19 .connection-groups section,.t19 .privacy-details{border-top-color:var(--line)}
.t19 .privacy-details details{border-bottom-color:var(--line)}
.t19 dialog{background:rgba(22,22,25,.72);-webkit-backdrop-filter:blur(30px) saturate(1.6);backdrop-filter:blur(30px) saturate(1.6);box-shadow:0 24px 70px rgba(0,0,0,.6)}
.t19 dialog::backdrop{background:rgba(0,0,0,.6)}
.t19 .close{background:rgba(255,255,255,.1)}

/* ---------- Hero orb ----------
   The manifesto's orb, above the title. It is the site's existing port
   (source-orb.css/js): same gradients, 18 s rotation and cursor response.
   Only its size and place are set here; it arrives with the rest of the hero. */
.hero-orb{display:grid;place-items:center;margin:0 auto clamp(28px,5vh,56px)}
.hero-orb .source-orb{--source-orb-size:clamp(160px,15vw,220px)}
@media(max-width:600px){.hero-orb .source-orb{--source-orb-size:150px}}

/* ---------- Settle ----------
   The manifesto's first-load fade: lift 22px, clear a 6px blur, 1.5 s, `ease`
   (what the manifesto actually renders). On load the orb, title, line, button and
   nav pill arrive together, one fade at one pace (owner, 11 Oct: the orb used to wake
   last and the rest was staggered).
   Below the hero, t19.js marks each block and plays the same fade as it scrolls
   into view. `backwards` fill only: once settled, a block keeps no leftover
   transform or filter, so hover and glass behave normally. */
@keyframes t19-settle{from{opacity:0;transform:translate3d(0,22px,0);filter:blur(6px)}to{opacity:1;transform:none;filter:blur(0)}}
@keyframes t19-settle-flat{from{opacity:0;filter:blur(6px)}to{opacity:1;filter:blur(0)}}
@media(prefers-reduced-motion:no-preference){
 .hero-orb,.t19 .hero-title-block,.t19 .hero-copy,.t19 .hero .primary{animation:t19-settle 1.5s .2s ease backwards}
 .t19 .island{animation:t19-settle-flat 1.5s .2s ease backwards} /* no lift: the pill is centred with a transform */
 .settle-ready [data-settle=""]{opacity:0;transform:translate3d(0,22px,0);filter:blur(6px)}
 .settle-ready [data-settle=in]{animation:t19-settle 1.5s var(--settle-delay,0s) ease backwards}
 .settle-ready .footer[data-settle=""]{transform:none}
 .settle-ready .footer[data-settle=in]{animation-name:t19-settle-flat}
}


/* ---------- Hero glyphs ----------
   A glass waveform before "talk." and a glass pointer before "action." (owner, 11 Oct).
   Both use one material, the cinematic overview's wave capsule
   (CinematicDictationOverviewGraphic.swift): white at 15% for the glass, a hairline at 32% lying
   inside the edge, and one band of light (8% to 39%) drifting across. They sit beside the white
   words without competing with them.
   Both sit to the right of their word, after the full stop (owner, 11 Oct, "for now").
   The wave is five capsules in a waveform's outline that barely breathe: each gives up a
   twentieth of an em and takes it back over 3.2 s, a quarter second apart (the owner found
   the app's full rise and fall far too strong here). Still under Reduce Motion.
   The pointer is the app's agent cursor (NotchAgentCursorView): Lucide mouse-pointer-2, and every
   1.6 s it reaches 1.5pt of its 16pt box toward its tip, dips to 0.92, lifts and returns. */
@property --hero-light{syntax:'<percentage>';inherits:true;initial-value:50%}
.hero-wave{--bar:.085em;--gap:.07em;--hero-light:50%;display:inline-block;position:relative;width:calc(var(--bar)*5 + var(--gap)*4);height:.58em;margin:0 0 0 .16em;vertical-align:.01em}
.hero-wave i{position:absolute;top:50%;left:calc((var(--bar) + var(--gap))*var(--i));width:var(--bar);height:var(--h);transform:translateY(-50%);border-radius:calc(var(--bar)/2);
 box-shadow:inset 0 0 0 .55px rgba(255,255,255,.323);
 background:linear-gradient(90deg,rgba(255,255,255,.085),rgba(255,255,255,.221) calc(var(--hero-light) - 16%),rgba(255,255,255,.391) var(--hero-light),rgba(255,255,255,.221) calc(var(--hero-light) + 16%),rgba(255,255,255,.085)) calc((var(--bar) + var(--gap))*var(--i)*-1) 0/calc(var(--bar)*5 + var(--gap)*4) 100% no-repeat,rgba(255,255,255,.153)}
.hero-wave i:nth-child(1){--i:0;--h:.24em}.hero-wave i:nth-child(2){--i:1;--h:.4em}.hero-wave i:nth-child(3){--i:2;--h:.56em}.hero-wave i:nth-child(4){--i:3;--h:.4em}.hero-wave i:nth-child(5){--i:4;--h:.24em}
@keyframes hero-wave{0%,100%{height:var(--h)}50%{height:calc(var(--h) - .05em)}}
@keyframes hero-light{0%,100%{--hero-light:36%}50%{--hero-light:64%}}
.hero-cursor{display:inline-block;width:.5em;height:.5em;margin:0 0 0 .16em;vertical-align:.03em}
.hero-cursor svg{display:block;width:100%;height:100%;overflow:visible;transform-origin:14.31% 14.31%}
@keyframes agent-cursor{0%,90%,100%{transform:none}35%,55%{transform:translate(-6.63%,-6.63%)}45%{transform:translate(-6.63%,-6.63%) scale(.92)}}
@media(prefers-reduced-motion:no-preference){
 .hero-wave{animation:hero-light 7s cubic-bezier(.42,0,.58,1) infinite}
 .hero-wave i{animation:hero-wave 3.2s cubic-bezier(.42,0,.58,1) infinite;animation-delay:calc(var(--i)*.25s)}
 .hero-cursor svg{animation:agent-cursor 1.6s cubic-bezier(.42,0,.58,1) infinite}
}

/* The Context eyebrow sat about 12px under the nav pill. */
.t19 .orb-dive .heading-block{top:max(96px,9.6vh)}
/* Footer: one size; the Privacy link stays on this page, so no outbound arrow. */
.t19 .footer p,.t19 .footer a{font-size:var(--t-small)}
@media(min-width:601px){.t19 .footer{display:grid;grid-template-columns:1fr 1fr}.t19 .footer>a:last-child{justify-self:end}}
.t19 .footer .icon{display:none}
/* Waitlist dialog: centred, like the page. */
.t19 #access{text-align:center}
.t19 #access .secondary{margin-inline:auto}

/* ---------- Type ---------- */
.t19 .display,
.t19 h2.display,.t19 .meeting-heading h2.display,.t19 .orb-dive h2.display{font-family:var(--serif);font-weight:400;letter-spacing:var(--ls-display);line-height:1}
.t19 h1.display{letter-spacing:var(--ls-display);line-height:.95}
.t19 .type-echo>span{letter-spacing:var(--ls-tight)}
/* Same size as the button label beneath it (owner, 11 Oct). */
.t19 .hero-copy{font-size:var(--t-body-sm);line-height:1.5;color:var(--ink);max-width:720px}
/* Section subtext is the size of the button and tab labels, as in the hero (owner, 11 Oct);
   the measure narrows with it so lines stay near 62 characters. */
.t19 .body-copy{color:var(--ink);line-height:1.5;max-width:min(100%,34rem);text-wrap:balance}
/* Centred subtext under every centred title (Memory and the phone Voice copy were left-aligned;
   the Context paragraph sat 58px off centre). */
.t19 .heading-block .body-copy,.t19 .voice-copy{text-align:center;margin-inline:auto}

.t19 .heading-block .body-copy{margin-top:32px}
.t19 .eyebrow{font-size:var(--t-label);font-weight:700;line-height:1;letter-spacing:var(--ls-label);text-transform:uppercase}
.t19 .promise{font-family:var(--serif);font-size:var(--t-lede);line-height:1.15;font-weight:400;letter-spacing:-.02em}
/* Under a section title the line is subtext like every other section's: 16px Inter. */
.t19 .heading-promise{margin:32px 0 0;font:400 var(--t-body-sm)/24px var(--sans);letter-spacing:0}
.t19 .dictionary-note h3,.t19 .connection-groups h3{font-family:var(--serif);font-size:var(--t-callout);font-weight:400;letter-spacing:-.02em}
.t19 .feature-copy{font-size:var(--t-body)}
.t19 .privacy-details summary{font-weight:500}
.t19 .wordmark,.t19 .footer .wordmark{font-family:var(--serif);font-size:var(--t-brand);font-weight:400;letter-spacing:-.02em;text-decoration:none}
.t19 #access h2{font-family:var(--serif);font-weight:400;letter-spacing:var(--ls-tight)}

/* ---------- Liquid glass ----------
   Values are the app's own (audited 11 Oct against the Swift source):
   - action buttons follow CinematicStartButton.swift: a 4% white wash over the
     glass, one hairline contour lit unequally (.16 / .015 / .20 from top-left to
     bottom-right), a 100px feathered light and a 64px rim highlight that follow
     the pointer (.12 on hover, .18 pressed), a give of 0.8px in height on hover
     and 0.95 on press, 0.24 s / 0.12 s ease-in-out;
   - other glass surfaces (the nav pill, the toggle, the dialog button) follow
     the overview card (GlassContour.overviewColumn, CinematicOverviewCard): an
     even contour, a 150px spotlight, no rim highlight and no give.
   Only the nav pill blurs what is behind it: it is the one glass surface that
   passes over content. The buttons sit on the flat page, where a backdrop blur
   shows nothing and costs a full re-blur every frame of a scroll.
   t19.js feeds --lg-x/--lg-y with the app's 60 ms pointer smoothing. The arrow
   beside the label is the start button's own; the app turns it on for the
   guided final step, and T19 uses it for "Join waitlist". */
.t19 .lg{isolation:isolate;border:0;color:#fff;background:rgba(255,255,255,.04);
 --lg-x:50%;--lg-y:50%;--lg-hot:0;
 transition:--lg-hot .24s cubic-bezier(.42,0,.58,1),transform .24s cubic-bezier(.42,0,.58,1),width .5s var(--spring),grid-template-rows .5s var(--spring),border-radius .5s var(--spring)}
.t19 .lg::before{content:'';position:absolute;inset:0;z-index:2;border-radius:inherit;padding:1px;pointer-events:none;
 background:linear-gradient(to bottom right,rgba(255,255,255,.2),rgba(255,255,255,.15) 30%,rgba(255,255,255,.14) 68%,rgba(255,255,255,.18));
 -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
.t19 .lg--action::before{background:radial-gradient(64px circle at var(--lg-x) var(--lg-y),rgba(255,255,255,var(--lg-hot)),rgba(255,255,255,calc(var(--lg-hot)*.42)) 38%,transparent 100%),
  linear-gradient(to bottom right,rgba(255,255,255,.16),rgba(255,255,255,.015) 48%,rgba(255,255,255,.2))}
.t19 .lg::after{content:'';position:absolute;inset:0;z-index:1;border-radius:inherit;pointer-events:none;opacity:0;transition:opacity .2s cubic-bezier(.333,0,.667,1);
 background:radial-gradient(150px circle at var(--lg-x) var(--lg-y),rgba(255,255,255,.075),rgba(255,255,255,.06) 15%,rgba(255,255,255,.038) 34%,rgba(255,255,255,.018) 56%,rgba(255,255,255,.005) 78%,transparent 100%)}
.t19 .lg--action::after{transition:opacity .24s cubic-bezier(.42,0,.58,1);
 background:radial-gradient(100px circle at var(--lg-x) var(--lg-y),rgba(255,255,255,.075),rgba(255,255,255,.068) 14%,rgba(255,255,255,.047) 32%,rgba(255,255,255,.023) 54%,rgba(255,255,255,.005) 78%,transparent 100%)}
.t19 .lg--action,.t19 .scene-switch,.t19 .secondary{position:relative}
/* 0.25 s smoothstep, as the app eases the arrow in. */
.lg__content{position:relative;z-index:3;display:inline-flex;align-items:center;transition:transform .25s cubic-bezier(.333,0,.667,1)}
.lg__arrow{position:absolute;left:100%;top:50%;width:16px;height:16px;margin:-8px 0 0 12px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:translateX(8px);transition:opacity .25s cubic-bezier(.333,0,.667,1),transform .25s cubic-bezier(.333,0,.667,1)}
@media(hover:hover){
 .t19 .lg:hover::after{opacity:1}
 .t19 .lg--action:hover{--lg-hot:.12;transform:scale(.982)}
 .t19 .lg--action:hover:active{--lg-hot:.18}
 .t19 .lg--action:hover .lg__content{transform:translateX(-14px)}
 .t19 .lg--action:hover .lg__arrow{opacity:1;transform:none}
}
.t19 .lg--action:active{transform:scale(.95);transition-duration:.12s}
.t19 .lg:disabled{color:rgba(255,255,255,.45);pointer-events:none}
.t19 .lg :focus-visible,.t19 .lg:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media(prefers-reduced-motion:reduce){.t19 .lg,.t19 .lg::after,.lg__content,.lg__arrow{transition:none!important}.t19 .lg--action:hover,.t19 .lg--action:active{transform:none}}
/* Reduce Transparency: the app's opaque body (#303030) plus its 3.5% wash. */
@media(prefers-reduced-transparency:reduce){.t19 .lg{background:#373737;-webkit-backdrop-filter:none;backdrop-filter:none}}

/* One button: glass pill, 44px, Inter 16 regular. */
.t19 .primary{background:rgba(255,255,255,.08);border:0;min-height:44px;padding:10px 32px;font-size:var(--t-body-sm);line-height:1;letter-spacing:-.01em;font-weight:400}
.t19 .primary:hover{background:rgba(255,255,255,.08)}
.t19 .secondary{background:rgba(255,255,255,.04)}
.t19 .scene-switch{background:rgba(255,255,255,.06)}
.t19 .scene-switch button{position:relative;z-index:3;font-size:var(--t-body-sm);color:rgba(255,255,255,.62)}
.t19 .scene-switch button:hover{color:#fff}
.t19 .scene-switch button[aria-pressed=true]{background:rgba(255,255,255,.16);color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
/* The selected capsule travels between tabs as in the app's tab group
   (TabMotion: 0.30 s, cubic-bezier(.2,.8,.2,1), "leaves at once and lands softly");
   the label ink rides the same clock. t19.js places the capsule. */
.scene-switch__thumb{position:absolute;z-index:2;top:4px;left:0;height:calc(100% - 8px);width:var(--thumb-w,0px);transform:translateX(var(--thumb-x,0px));border-radius:24px;background:rgba(255,255,255,.16);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);pointer-events:none}
.scene-switch.is-ready .scene-switch__thumb{transition:transform .3s cubic-bezier(.2,.8,.2,1),width .3s cubic-bezier(.2,.8,.2,1)}
.t19 .scene-switch.has-thumb button{transition:color .3s cubic-bezier(.2,.8,.2,1)}
.t19 .scene-switch.has-thumb button[aria-pressed=true]{background:transparent;box-shadow:none}
@media(prefers-reduced-motion:reduce){.scene-switch.is-ready .scene-switch__thumb,.t19 .scene-switch.has-thumb button{transition:none}}

/* ---------- Island navigation ---------- */
.island{position:fixed;top:12px;left:50%;z-index:40;transform:translateX(-50%);box-sizing:border-box;
 width:var(--island-w);display:grid;grid-template-rows:48px 0fr;overflow:hidden;
 --island-w:330px;--island-w-open:330px;border-radius:25px;box-shadow:0 10px 30px rgba(0,0,0,.35)}
/* A darker tint than the buttons: it carries text over whatever scrolls beneath. */
.t19 .island.lg{background:rgba(12,12,14,.72);-webkit-backdrop-filter:blur(22px) saturate(1.8);backdrop-filter:blur(22px) saturate(1.8)}
.island__bar{position:relative;z-index:3;height:48px;display:flex;align-items:center;gap:6px;padding:0 6px 0 18px}
.island .wordmark{color:#fff!important;font-size:22px;margin-right:auto;line-height:1}
.island__more{width:36px;height:36px;display:grid;place-items:center;padding:0;border:0;border-radius:50%;background:none;color:rgba(255,255,255,.7);cursor:pointer;transition:background .2s,color .2s}
.island__more:hover{background:rgba(255,255,255,.12);color:#fff}
.island__more svg{width:18px;height:18px;display:block}
.island__cta{height:36px;padding:0 30px;border-radius:999px;font:400 var(--t-body-sm)/1 var(--sans);cursor:pointer;white-space:nowrap}
.t19 .island__cta.lg{background:rgba(255,255,255,.1)}
@media(hover:hover){.t19 .island__cta.lg--action:hover{transform:scale(.978)}}
/* Open, the pill grows downward into a vertical list, one row per section with its icon
   (owner, 11 Oct). The width does not change; only the height does. */
.island__links{position:relative;z-index:3;min-height:0;overflow:hidden;display:flex;flex-direction:column;padding:0 8px;opacity:0;visibility:hidden;transition:opacity .18s,visibility 0s .18s}
.island__links a{display:flex;align-items:center;gap:12px;height:40px;flex:none;padding:0 10px;border-radius:12px;color:rgba(255,255,255,.72);font-size:var(--t-body-sm);text-decoration:none;white-space:nowrap;transition:color .2s,background .2s}
.island__links a:first-child{margin-top:2px}
.island__links a:last-child{margin-bottom:8px}
.island__links svg{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.island__links a:hover{color:#fff;background:rgba(255,255,255,.08)}
/* The attribute and :has() rules are separate on purpose: a browser without :has() drops
   a whole selector list that contains it, which would break the tap toggle too. */
.island[data-open=true]{width:var(--island-w-open);grid-template-rows:48px 1fr;border-radius:27px}
.island[data-open=true] .island__links{opacity:1;visibility:visible;transition:opacity .3s .12s,visibility 0s}
.island:has(:focus-visible){width:var(--island-w-open);grid-template-rows:48px 1fr;border-radius:27px}
.island:has(:focus-visible) .island__links{opacity:1;visibility:visible;transition:opacity .3s .12s,visibility 0s}
.island__links a:focus-visible{outline-offset:-2px;border-radius:6px}
@media(hover:hover){
 .island:hover{width:var(--island-w-open);grid-template-rows:48px 1fr;border-radius:27px}
 .island:hover .island__links{opacity:1;visibility:visible;transition:opacity .3s .12s,visibility 0s}
}
@media(max-width:600px){
 .island{--island-w:min(340px,calc(100vw - 24px));--island-w-open:min(340px,calc(100vw - 24px))}
 .island__more{width:44px;height:44px}
 .island__cta{height:40px}
 .t19 .context-inner>.fgrid,.t19 .context-inner>.compatibility-line,.t19 .context-inner>.privacy-details{margin-inline:20px}
 .island__links a{height:44px}
}
@media(prefers-reduced-motion:reduce){.island,.island__links{transition:none!important}}

/* ---------- One screen width ----------
   V19 drew the Mac screen at 1200, 1120 and 1100px in different sections. Every
   screen now takes the page container's width. */
@media(min-width:601px){
 .t19 .context-inner>.product-scene,.t19 .context-inner>.fgrid{width:min(1200px,calc(100% - 96px));margin-inline:auto}
 .t19 .memory-example{max-width:none}
}
@media(min-width:1700px){.t19 .context-inner>.product-scene,.t19 .context-inner>.fgrid{width:min(1400px,calc(100% - 160px))}}
@media(max-width:1000px) and (min-width:601px){.t19 .context-inner>.product-scene,.t19 .context-inner>.fgrid{width:calc(100% - 64px)}}
/* The orb zoom ends on black. The screen rises into the end of that pinned stage, so the
   visitor is not left on an empty viewport before it arrives. Only where the stage pins. */
@media(prefers-reduced-motion:no-preference) and (min-height:621px){html.motion-ready .t19 .context-inner>.product-scene{position:relative;z-index:2;margin-top:-110px}}
/* One rhythm between sections: 224px from the end of one to the next title. */
.t19 .context{padding-top:16px}
/* Voice now flows into a regular meeting chapter. Preserve both chapter edges
   instead of the old zero-padding handoff into a pinned full-height stage. */
.br-phone{display:none}
@media(max-width:600px){.br-phone{display:inline}}

/* ---------- Mac shell: bezel and the guided-onboarding wallpaper ---------- */
.t19 .display-environment{inset:0 0 -24px;border-radius:26px 26px 0 0;background:#000;box-shadow:inset 0 0 0 1px rgba(255,255,255,.2);mask-image:linear-gradient(#000 0%,#000 50%,transparent 100%)}
.t19 .display-environment svg{display:none}
/* Same image the app's guided lessons use (Resources/Wallpapers/macos-dark.jpg), top-aligned. */
.t19 .display-environment:before{content:'';position:absolute;inset:10px 10px 0;border-radius:17px 17px 0 0;background:#0b0b16 url('assets/wallpaper-guided-dark.jpg') 50% 0/cover no-repeat;filter:none;opacity:1;transform:none;mask-image:none}
.t19 .display-environment:after{display:none}
/* The notch is part of the bezel: the same black, and it starts 2px inside it, so no sliver of
   wallpaper can show above it. */
.t19 .screen-frame{padding-top:8px}
@media(max-width:600px){
 .t19 .display-environment{inset:0 0 -12px;border-radius:20px 20px 0 0}
 .t19 .display-environment:before{inset:8px 8px 0;border-radius:13px 13px 0 0;opacity:1}
 .t19 .screen-frame{padding-top:6px}
}
/* On a narrow screen a whole Mac display would be as slim as a phone. Show a close-up instead:
   the display runs past both edges of the window (the page cannot scroll sideways), so only its
   top edge and the wallpaper are in view, and the notch keeps its size. */
@media(max-width:760px){
 .t19 .display-environment{left:-46vw;right:-46vw}
}

/* ---------- Notch ----------
   Rebuilt from the app (audited 11 Oct): NotchSurface.swift, NotchCardChrome.swift,
   NotchVoiceText.swift, NotchTranscriptView.swift, NotchStyle.swift,
   NotchLayoutMetrics.swift, ComponentVariants.swift. The web panel is drawn at
   1.25x the app's points, which keeps its 4pt grid on whole pixels
   (4>5, 8>10, 12>15, 16>20, 24>30, 32>40). Every text role is 15/20px
   (12/16pt) except the card title at 17.5/22.5px (14/18pt).
   Ink: #fff primary, #e8e8e8 request and transcript, #9f9f9f quiet,
   white 72% meta. Colour appears only in app logos and the amber recording mark. */

/* Shell: a 48px opaque camera row, then black thinning to 55% and 10% over the
   glass. The glass itself is the app's native material: a deep blur under a dark tint,
   matched to real screenshots (the body reads near-black whatever is behind it). No rim; a faint edge light
   on the lower half. No filter on the wrapper: a filtered ancestor would cut the
   glass off from the wallpaper. */
.t19 .mobile-product{filter:none;transition:opacity .5s ease}
@media(min-width:601px){.t19 .mobile-product{width:min(668px,80%)}} /* 506pt body + two 14pt shoulders; phones keep the full width */
.t19 .screen-frame[data-screen-motion=ready] .mobile-product{opacity:0} /* the notch arrives with its screen, not before it */
/* Type. The app draws Inter with cv11 and ss03 (single-storey a). Weights are the product's own:
   regular (400) for every text role, medium (500) for titles, buttons and readouts. A heavier
   mapping was tried to mimic AppKit's rendering and the owner rejected it as too thick (11 Oct). */
.t19 .mobile-panel,.t19 .panel-meeting{min-height:0;color:#fff;font-size:15px;line-height:20px;letter-spacing:-.005em;font-weight:400;font-feature-settings:"cv11","ss03","liga"}
.t19 .mobile-surface,.t19 .panel-meeting .mobile-surface{box-sizing:border-box;display:flow-root;min-height:0;padding:0 33px;background:linear-gradient(180deg,#000 0,#000 48px,rgba(0,0,0,.55) calc(50% + 24px),rgba(0,0,0,.1) 100%),rgba(15,14,30,.78)}
.t19 .mobile-surface:before,.t19 .mobile-surface:after{display:none}
.t19 .panel-edge{filter:none;mask-image:linear-gradient(transparent 45%,#000 100%)}
.t19 .panel-edge path{stroke:rgba(255,255,255,.3);stroke-width:.0012}
@media(prefers-contrast:more){.t19 .mobile-surface{background:#0b0b0d}}

/* Camera row: the orb for voice states; a five-bar wave and a readout for live capture. */
.t19 .mobile-surface>.panel-top{position:absolute;top:0;left:calc(var(--notch-side,18px) + 15px);right:calc(var(--notch-side,18px) + 15px);height:48px;margin:0;display:flex;align-items:center;justify-content:space-between;gap:10px;z-index:1}
.t19 .panel-top .tiny-orb.source-orb{--source-orb-size:20px;width:20px;height:20px}
/* At 20px the app's orb is a mid-grey sphere with a soft highlight; the full-contrast material
   swings between flat white and near-black at this size. */
.t19 .panel-top .source-orb__disc::before{filter:blur(7px) contrast(1.2)}
.t19 .panel-top .signal{display:none}
.notch-wave{display:flex;align-items:center;gap:2.5px;height:10px}
.notch-wave i{width:2.5px;height:3.75px;border-radius:1.25px;background:#fff;opacity:.85;animation:notch-wave 1s cubic-bezier(.42,0,.58,1) infinite}
.notch-wave i:nth-child(2){animation-delay:.14s}.notch-wave i:nth-child(3){animation-delay:.28s}.notch-wave i:nth-child(4){animation-delay:.42s}.notch-wave i:nth-child(5){animation-delay:.56s}
@keyframes notch-wave{0%,100%{height:3.75px}50%{height:10px}}
.panel-meeting[data-state=paused] .notch-wave i,.panel-meeting[data-state=ended] .notch-wave i{animation-play-state:paused}
@media(prefers-reduced-motion:reduce){.notch-wave i{animation:none}}
@property --notch-level{syntax:'<number>';inherits:true;initial-value:0}
.notch-wave--level{gap:2.5px;height:15px;--notch-level:.2}
.notch-wave--level i{width:3.75px;border-radius:1.875px;opacity:.92;animation:none;height:calc(3.75px + 11.25px*var(--w)*var(--notch-level))}
.notch-wave--level i:nth-child(1),.notch-wave--level i:nth-child(5){--w:.45}.notch-wave--level i:nth-child(2),.notch-wave--level i:nth-child(4){--w:.75}.notch-wave--level i:nth-child(3){--w:1}
@keyframes notch-level{0%,100%{--notch-level:.12}9%{--notch-level:.85}17%{--notch-level:.4}28%{--notch-level:1}36%{--notch-level:.55}47%{--notch-level:.9}58%{--notch-level:.2}66%{--notch-level:.7}79%{--notch-level:.35}90%{--notch-level:.8}}
@media(prefers-reduced-motion:no-preference){.notch-wave--level{animation:notch-level 2.8s cubic-bezier(.42,0,.58,1) infinite}}
.notch-readout{font-size:15px;line-height:20px;font-weight:500;font-variant-numeric:tabular-nums;letter-spacing:.01em;color:#fff}

/* Content column: 15px between rows. */
.t19 .mobile-surface>.panel-copy{display:flex;flex-direction:column;gap:15px}
.t19 .mobile-surface .panel-copy p{margin:0;font-size:15px;line-height:20px}

/* Request bubble: flush right, hugging its text, at most 78% of the panel. */
.t19 .mobile-surface .notch-bubble{align-self:flex-end;width:fit-content;max-width:78%;margin:0 0 0 auto;padding:5px 15px;border:0;border-radius:15px;background:#303030;box-shadow:none;color:#e8e8e8;font-size:15px;line-height:20px;text-align:right;text-wrap:balance}

/* Card: black 40%, a 1px white 16% outline, 15px radius; a 40px header after a 10px inset. */
.notch-card{background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.16);border-radius:15px;padding:9px 14px 14px;transition:opacity .3s ease}
.notch-card--plain>.notch-sources{margin-top:15px!important}
.notch-card>*+*{margin-top:10px!important}
.notch-card__head{height:40px;display:flex;align-items:center;gap:10px}
.notch-card>.notch-card__head+*{margin-top:5px!important}
.notch-card__head img{width:17.5px;height:17.5px;display:block}
.notch-card__title,.t19 .meeting-title h3{font-size:17.5px;line-height:22.5px;font-weight:500;letter-spacing:-.01em;color:#fff;margin:0}
.notch-row{display:flex;align-items:center;gap:15px;min-height:30px}
.notch-row strong{font-weight:500;color:#fff}
.t19 .mobile-surface .notch-quiet{font-size:15px;line-height:20px;color:#9f9f9f;max-width:none}
.t19 .mobile-surface .notch-body{font-size:15px;line-height:20px;color:#fff;margin:0;min-height:0}
.notch-body sup{font-size:10px;line-height:0;color:#9f9f9f;margin-left:1.25px;vertical-align:6px}
.notch-person{display:inline-flex;align-items:center;gap:7.5px;height:30px;padding:0 10px 0 5px;border-radius:15px;background:rgba(255,255,255,.14);color:#fff;font-weight:500}
.notch-person i{width:20px;height:20px;border-radius:50%;background:#303030;display:grid;place-items:center;font-style:normal;font-size:10px;font-weight:500}
.notch-person svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.notch-person+.notch-btn--add{margin-left:-10px}

/* Source chips: 25px tall, white 12%, the glyph and the number alone (CitationAttachment.swift). */
.notch-sources{display:flex;flex-wrap:wrap;gap:5px}
.notch-chip{display:inline-flex;align-items:center;gap:5px;height:25px;padding:0 7.5px 0 5px;border-radius:12.5px;background:rgba(255,255,255,.12);border:0;color:#dedede;font-size:15px;line-height:20px}
.notch-chip svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.notch-body sup+sup{margin-left:3.5px}

/* Card actions: 30px pills, right-aligned, key hints inside. */
.notch-actions{display:flex;justify-content:flex-end;gap:10px}
.notch-btn{display:inline-flex;align-items:center;gap:10px;height:30px;padding:0 15px;border-radius:15px;border:1px solid rgba(255,255,255,.15);background:transparent;color:#fff;font-size:15px;line-height:20px;font-weight:500;font-feature-settings:normal;white-space:nowrap}
.notch-btn kbd{font:inherit;font-weight:400;color:rgba(255,255,255,.5)}
.notch-btn--primary{background:rgba(255,255,255,.14);border-color:transparent}
.notch-btn--primary kbd{color:rgba(255,255,255,.62)}
.notch-btn--add{padding:0 10px;font-weight:500;color:rgba(255,255,255,.6);border-color:rgba(255,255,255,.18)}
.notch-card>.notch-actions{margin-top:15px!important}
.panel-dictation .notch-btn--primary{min-width:115px;justify-content:center}

/* Footer: status at the left, 40px tool discs at the right. */
.notch-foot{display:flex;align-items:center;justify-content:flex-start;gap:15px;min-height:40px;margin:0;flex-wrap:nowrap}
.notch-tools{display:flex;gap:5px;margin-left:auto}
.notch-tool,.t19 .glass-control{width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:50%;background:rgba(0,0,0,.6);border:1px solid rgba(255,255,255,.1);box-shadow:none;color:#fff;-webkit-backdrop-filter:none;backdrop-filter:none}
.notch-tool svg{width:17.5px;height:17.5px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* Meeting: the header and the transcript share one card; the tools sit beneath it. */
.t19 .meeting-header{display:block;margin:0;padding:10px 15px 5px;background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.16);border-bottom:0;border-radius:15px 15px 0 0}
.t19 .meeting-title{height:40px;gap:10px}
.t19 .calendar-mark{width:17.5px;height:17.5px;filter:none;opacity:1}
.t19 .meeting-subtitle,.t19 .meeting-orb,.t19 .speaker-avatar,.t19 .speaker-time{display:none}
.t19 .panel-meeting .panel-copy{gap:0}
.t19 .transcript-viewport{height:165px;overflow:hidden;overscroll-behavior:auto;margin:0;padding:0 15px 15px;background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.16);border-top:0;border-radius:0 0 15px 15px;mask-image:none;-webkit-mask-image:none}
.t19 .transcript-viewport:focus-visible{box-shadow:inset 0 0 0 1px rgba(255,255,255,.4)}
.t19 .transcript-feed{gap:10px}
.t19 .transcript-row{display:block;border-radius:5px}
.t19 .speaker-line{display:inline;margin:0 7.5px 0 0}
.t19 .mobile-surface .speaker-name{font-size:15px;line-height:20px;font-weight:inherit;letter-spacing:0;color:#a0a0a0}
.t19 .mobile-surface .panel-copy .transcript-text{display:inline;font-size:15px;line-height:20px;color:#e8e8e8;min-height:0}
.t19 .transcript-row[data-highlighted=true]{background:rgba(255,255,255,.1);box-shadow:0 0 0 5px rgba(255,255,255,.1)}
/* A screenshot the meeting holds: its name and clock on a line, then a 130 x 81px tile (NotchTranscriptView.swift). */
.t19 .transcript-attachment{display:flex;flex-direction:column-reverse;align-items:flex-start;gap:5px;width:auto;margin:10px 0 0}
.t19 .transcript-attachment>img{width:130px;height:81px;object-fit:cover;border:0;border-radius:10px;filter:invert(.86) hue-rotate(180deg)} /* a dark-mode screen: a tile a shade above the card, not a white slab */
@media(prefers-reduced-motion:reduce){.t19 .transcript-viewport{height:auto}}
.t19 .transcript-attachment figcaption{display:block;margin:0;font-size:15px;line-height:20px;color:#e8e8e8}
.t19 .transcript-attachment figcaption span{margin-left:7.5px;color:#a0a0a0}
.t19 .meeting-toolbar{margin:15px 0 0;padding:0;border:0;justify-content:flex-end;gap:5px}
.t19 .tool-cluster{gap:5px}
.t19 .glass-control{position:relative;padding:0;cursor:pointer;transition:background .2s}
.t19 .glass-control img{width:17.5px;height:17.5px;filter:invert(1);opacity:1}
.t19 .glass-control:hover{background:rgba(255,255,255,.12);box-shadow:none;transform:none}
.t19 .glass-control:active{background:rgba(255,255,255,.2);transform:scale(.95)}
.t19 .glass-control[aria-pressed=true]{background:rgba(255,255,255,.2);border-color:rgba(255,255,255,.3);box-shadow:none}
.t19 .glass-control:focus-visible{outline:2px solid #fff;outline-offset:2px}
.t19 .glass-control[data-capturing=true]{background:rgba(255,255,255,.3);box-shadow:none}
.t19 .glass-control[data-capturing=true]::after{border-color:rgba(255,255,255,.6)}
/* Screen recording is the one amber mark in the notch. */
.t19 .glass-control[data-meeting-action=screen][aria-pressed=true]::before{content:'';position:absolute;top:5px;right:5px;width:8.75px;height:8.75px;border-radius:50%;background:#cc7526}
/* The product confirms a tool in place; it has no caption line. Kept for screen readers only. */
.t19 .mobile-surface .meeting-feedback{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.t19 .glass-control[data-meeting-action=pause] img,.t19 .glass-control[data-meeting-action=end] img{width:13.75px;height:13.75px}
.t19 .panel-meeting[data-state=ended] .glass-control[data-meeting-action=end] img{width:17.5px;height:17.5px}
/* Paused: the three capture tools leave, "Paused" sits at the left, the clock dims, the wave rests as two bars. */
.t19 .panel-meeting[data-state=paused] .tool-cluster:first-child{display:none}
.t19 .panel-meeting[data-state=paused] .meeting-toolbar::before{content:'Paused';margin-right:auto;color:#9f9f9f;font-size:15px;line-height:20px}
.t19 .panel-meeting[data-state=paused] .notch-readout{color:rgba(255,255,255,.55)}
.panel-meeting[data-state=paused] .notch-wave{gap:3.75px}
.panel-meeting[data-state=paused] .notch-wave i{animation:none;width:3.75px;height:10px;border-radius:1.25px}
.panel-meeting[data-state=paused] .notch-wave i:nth-child(n+3){display:none}
/* Screen recording: an amber dot before the wave, an amber "Recording" pill at the left, the tool on a darker face. */
.t19 .panel-meeting:has([data-meeting-action=screen][aria-pressed=true]):not([data-state=paused]):not([data-state=ended]) .panel-top::before{content:'';order:-1;width:6px;height:6px;border-radius:50%;background:#cc7526;margin-right:-2.5px}
.t19 .panel-meeting:has([data-meeting-action=screen][aria-pressed=true]):not([data-state=paused]):not([data-state=ended]) .notch-readout{margin-left:auto}
.t19 .panel-meeting:has([data-meeting-action=screen][aria-pressed=true]):not([data-state=paused]):not([data-state=ended]) .meeting-toolbar::before{content:'● Recording';margin-right:auto;height:25px;padding:0 10px;display:inline-flex;align-items:center;border-radius:12.5px;background:#cc7526;color:#fff;font-size:15px;line-height:20px;font-weight:500}
.t19 .glass-control[data-meeting-action=screen][aria-pressed=true]{background:rgba(0,0,0,.42);border-color:rgba(255,255,255,.1)}
/* End turns red under the pointer. The glyph is an image the script swaps, so the red copy is a mask. */
@media(hover:hover){
 .t19 .panel-meeting:not([data-state=ended]) .glass-control[data-meeting-action=end]:hover img{opacity:0}
 .t19 .panel-meeting:not([data-state=ended]) .glass-control[data-meeting-action=end]:hover::after{content:'';position:absolute;inset:0;background:#ff6169;-webkit-mask:url('assets/square.svg') center/13.75px no-repeat;mask:url('assets/square.svg') center/13.75px no-repeat}
}
@media(prefers-contrast:more){.t19 .glass-control,.notch-tool{background:#000;border-color:#aaa}}

/* Growth. The notch is only as tall as what it is showing (notch-phases.js picks the state,
   glass-interactions.js springs the height). The screen keeps room for the tallest state, so
   nothing beneath it moves. Without the script every panel simply shows its last state. */
/* The surface has no vertical padding of its own, so it can close to the 48px housing; the
   content column carries the 63px above it (camera row + 15) and the room beneath it. */
.t19 .mobile-product{min-height:var(--notch-max,0px)}
.t19 .mobile-surface>.panel-top+*{margin-top:63px}
.t19 .mobile-surface>.panel-copy{margin-bottom:15px}
.t19 .mobile-panel[data-flow=voice] .mobile-surface>.panel-copy{margin-bottom:70px}
.t19 .mobile-surface>.notch-foot{position:absolute;left:33px;right:33px;bottom:15px;z-index:1}
/* As in the app, the footer is laid out where the notch will come to rest and the moving edge
   uncovers it; it does not ride the spring across the content. */
.t19 .mobile-panel[data-phase] .mobile-surface>.notch-foot{top:calc(var(--notch-target) - 55px);bottom:auto}
.notch-status{order:1}.notch-tools{order:2}
.notch-ready,.notch-progress,.notch-status{display:none}
@keyframes notch-in{from{opacity:0}}
@keyframes notch-sweep{to{background-position:166.7% 0}}
/* Orb Ready: the tab pill, a 70px orb, history at the left of the tools; the camera row is empty. */
.notch-ready{flex-direction:column;align-items:flex-start;gap:30px;padding-bottom:15px}
.notch-tabs{display:inline-flex;align-items:center;gap:5px;height:40px;padding:4px;box-sizing:border-box;border:1px solid rgba(255,255,255,.16);border-radius:20px;color:#9f9f9f;font-weight:500}
.notch-tabs>*{display:inline-flex;align-items:center;height:30px;padding:0 15px;border-radius:15px;font-weight:inherit}
.notch-tabs>b{background:#353535;color:#fff}
.t19 .notch-ready__orb{--source-orb-size:70px;align-self:center}
.t19 .mobile-panel[data-phase=ready] .notch-ready{display:flex}
.t19 .mobile-panel[data-phase=ready] .panel-top .tiny-orb{visibility:hidden}
.t19 .mobile-panel:is([data-phase=ready],[data-phase=listening]) .notch-bubble,
.t19 .mobile-panel:is([data-phase=ready],[data-phase=listening],[data-phase=request],[data-phase=thinking]) .notch-card{display:none}
.t19 .mobile-panel[data-flow=voice][data-sources=false] .notch-sources{display:none}
/* Listening: the status sits where history was; a light passes over it every 1.8s. */
.t19 .mobile-panel:is([data-phase=listening],[data-phase=request]) .notch-status{display:block;font-size:15px;line-height:20px}
.t19 .mobile-panel:is([data-phase=listening],[data-phase=request]) .notch-status,.notch-progress>span.on{color:transparent;background:linear-gradient(90deg,#fff0,#ffffffbf 32%,#fff 50%,#ffffffbf 68%,#fff0) -66.7% 0/40% 100% no-repeat,#9f9f9f;-webkit-background-clip:text;background-clip:text;animation:notch-in .3s ease backwards,notch-sweep 1.8s linear infinite}
/* One progress line while it thinks; the request above it is now all primary. */
.t19 .mobile-panel[data-phase=thinking] .notch-progress{display:block;color:#9f9f9f}
.notch-progress>span{display:none}
.notch-progress>span.on{display:inline}
/* Words join the line as they are spoken; the two newest are quiet until the next arrives. */
.t19 .mobile-panel[data-phase] .sw{display:none;transition:color .3s ease}
.t19 .mobile-panel[data-phase] .sw.in{display:inline;animation:notch-in .24s ease backwards}
.t19 .mobile-panel[data-phase=measure] .sw{display:inline}
.t19 .mobile-panel[data-phase] .sw.tail{color:#9f9f9f}
.t19 .mobile-panel[data-phase=answer] :is(.notch-card,.notch-sources){animation:notch-in .3s ease backwards}
/* Capture: a narrow bar with the wave and a readout, then the card. */
.t19 .mobile-panel[data-phase=bar] :is(.meeting-header,.panel-copy){display:none}
.t19 .mobile-panel:is([data-phase=card],[data-phase=open]) :is(.meeting-header,.panel-copy){animation:notch-in .3s ease backwards}

@media(max-width:600px){
 .t19 .mobile-surface,.t19 .panel-meeting .mobile-surface{padding:0 28px}
 .t19 .mobile-surface>.panel-top{left:calc(var(--notch-side,18px) + 10px);right:calc(var(--notch-side,18px) + 10px)}
 .t19 .mobile-surface>.panel-top+*{margin-top:60px}
 .t19 .mobile-surface>.panel-copy{margin-bottom:12px}
 .t19 .mobile-panel[data-flow=voice] .mobile-surface>.panel-copy{margin-bottom:63px}
 .t19 .mobile-surface>.notch-foot{left:28px;right:28px;bottom:12px}
 .t19 .mobile-panel[data-phase] .mobile-surface>.notch-foot{top:calc(var(--notch-target) - 48px)}
 .notch-ready{gap:24px}
 .t19 .mobile-surface .notch-bubble{max-width:90%;padding:5px 12px}
 .notch-card{padding:7px 11px 11px}
 .t19 .meeting-header{padding:8px 12px 5px}.t19 .transcript-viewport{padding:0 12px 12px;height:170px}
 .notch-tool,.t19 .glass-control{width:36px;height:36px}
 .notch-row{gap:10px}.notch-btn{padding:0 12px}
}

/* ---------- Meeting notes: heading and screen read as one section ----------
   The heading lives in the pinned stage above; the Mac screen is the next
   section. t19.js measures the empty space under the copy and sets
   --meeting-pull, so the screen rises to rest 56px beneath it. */
.t19 .meeting-heading .meeting-intro{margin-top:32px}
.t19 .meeting{position:relative;z-index:1;background:transparent;padding-top:0;margin-top:calc(-1*var(--meeting-pull,0px))}

/* ---------- Feature grid ----------
   One recipe for every list of features (meetings, dictation, privacy, context).
   After reflect.app's grid: no cards, hairlines that fade, one icon and one
   short line per cell, a soft wash on hover. Icons are Lucide at 1.5 stroke,
   monochrome. Cells are centred; rows of 4 or 3 with a centred remainder. */
.fgrid{list-style:none;margin:64px auto 0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;transition:border-color 1.2s ease} /* as wide as the screen above it */
.fgrid>li{position:relative;box-sizing:border-box;flex:0 0 33.333%;padding:28px 20px 32px;text-align:center;text-wrap:balance;font-size:var(--t-body-sm);line-height:24px;color:var(--ink)}
.fgrid--4>li{flex-basis:25%}
/* The grid's own rules arrive with its first cell, not before it. */
.settle-ready .fgrid:has(>li:first-child[data-settle=""]){border-color:transparent}
.fgrid svg{display:block;width:24px;height:24px;margin:0 auto 16px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;opacity:.72;transition:opacity .2s}
/* Full hairlines (owner: the grid must be clearly visible): a line down every inner column edge,
   a line under every row but the last, and a line above and below the whole grid. */
.fgrid{--line:rgba(255,255,255,.2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.fgrid>li::before{content:'';position:absolute;inset:0 0 0 auto;width:1px;background:var(--line)}
.fgrid>li:last-child::before,.fgrid:not(.fgrid--4)>li:nth-child(3n)::before,.fgrid--4>li:nth-child(4n)::before{display:none}
@media(min-width:1000px){.fgrid--rows:not(.fgrid--4)>li:nth-child(-n+3){border-bottom:1px solid var(--line)}}
@media(min-width:1180px){.fgrid--rows.fgrid--4>li:nth-child(-n+4){border-bottom:1px solid var(--line)}}
/* Four columns need 1180px to hold two rows of text a cell; below that the four-column grids go two wide. */
@media(min-width:1000px) and (max-width:1179px){
 .fgrid--4>li{flex-basis:50%}
 .fgrid--4>li::before{display:block!important}
 .fgrid--4>li:nth-child(2n)::before{display:none!important}
 .fgrid--4>li:nth-child(n+3){border-top:1px solid var(--line)}
 .fgrid--4>li br,.fgrid--lead>li br{display:none}
}
.fgrid>li::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(rgba(255,255,255,0),rgba(255,255,255,.05));opacity:0;transition:opacity .45s cubic-bezier(.6,.6,0,1)}
@media(hover:hover){.fgrid>li:hover::after,.fgrid>li:hover svg{opacity:1}}
@media(max-width:999px) and (min-width:601px){
 .fgrid>li,.fgrid--4>li{flex-basis:50%}
 .fgrid>li::before{display:block!important}
 .fgrid>li:nth-child(2n)::before,.fgrid>li:last-child::before{display:none!important}
 .fgrid>li:nth-child(n+3){border-top:1px solid var(--line)}
 .fgrid>li br{display:none}
}
@media(max-width:600px){
 .fgrid{margin-top:40px;border-top:0}
 .fgrid>li br{display:none}
 .fgrid>li,.fgrid--4>li{flex-basis:100%;display:flex;align-items:center;gap:14px;text-align:left;padding:16px 0;border-top:1px solid var(--line);text-wrap:pretty}
 .fgrid>li::before,.fgrid>li::after{display:none!important}
 .fgrid svg{width:20px;height:20px;margin:0;flex:none}
}
/* the meetings list sits in V19's .reading wrapper; let the grid use the full width */
.t19 .meeting-product .reading{display:block;margin-top:0}
.t19 .compatibility-line{margin-top:40px;line-height:24px}
.t19 .meeting-product{padding-bottom:0}

/* ---------- Dictation: one grid with a lead cell ----------
   "Your dictionary builds itself." is the first cell of the grid, two columns wide and two rows
   tall, with the tools it learns from and the explanation beneath it; the four features fill the
   2 x 2 on the right (owner, 11 Oct). Same four columns and hairlines as the meetings grid. */
.t19 .fgrid__lead h3{margin:0;font-family:var(--serif);font-size:var(--t-callout);line-height:1.15;font-weight:400;letter-spacing:-.02em}
.t19 .fgrid__lead .body-copy{margin:28px 0 0;max-width:30rem;text-align:left;text-wrap:pretty}
.fgrid__note{margin:12px 0 0;max-width:30rem;font-size:var(--t-body-sm);line-height:24px;color:var(--muted)}
.fgrid--lead>.fgrid__lead{text-align:left}
.fgrid--lead>.fgrid__lead::after{display:none}
@media(min-width:601px){
 .fgrid--lead{display:grid}
 .fgrid--lead>li{flex:none}
 .fgrid--lead>li:not(.fgrid__lead){display:flex;flex-direction:column;justify-content:center}
 .fgrid--lead>li::before{display:block!important}
}
/* Desktop: the lead is the left half, two rows tall; the features are the 2 x 2 beside it. */
@media(min-width:1180px){
 .fgrid--lead{grid-template-columns:repeat(4,minmax(0,1fr))}
 .fgrid--lead>.fgrid__lead{grid-column:span 2;grid-row:span 2;padding:32px 40px 36px 0}
 .fgrid--lead>li:nth-child(2),.fgrid--lead>li:nth-child(3){border-bottom:1px solid var(--line)}
 .fgrid--lead>li:nth-child(3)::before,.fgrid--lead>li:nth-child(5)::before{display:none!important}
}
/* Tablet: the lead is a full row above the 2 x 2. */
@media(min-width:601px) and (max-width:1179px){
 .fgrid--lead{grid-template-columns:repeat(2,minmax(0,1fr))}
 .fgrid--lead>.fgrid__lead{grid-column:span 2;padding:32px 0 36px;border-bottom:1px solid var(--line)}
 .fgrid--lead>li:nth-child(n+3){border-top:0}
 .fgrid--lead>li:nth-child(4),.fgrid--lead>li:nth-child(5){border-top:1px solid var(--line)}
 .fgrid--lead>li:nth-child(1)::before,.fgrid--lead>li:nth-child(3)::before,.fgrid--lead>li:nth-child(5)::before{display:none!important}
 .fgrid--lead>li:nth-child(2)::before,.fgrid--lead>li:nth-child(4)::before{display:block!important}
}
/* Phone: the lead reads as a short passage, then the features as the same rows as every other grid. */
@media(max-width:600px){
 .fgrid--lead>.fgrid__lead{display:block;padding:8px 0 28px;border-top:0}
}
/* Slack and Gmail in colour, a dot travelling from them, and a word arriving:
   the names and terms already on this page (Priya, Sam, Product review). */
.dict-build{display:flex;align-items:center;gap:12px;height:44px;margin-top:28px}
.dict-build__tile{width:44px;height:44px;flex:none;display:grid;place-items:center;border-radius:12px;background:rgba(255,255,255,.04);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.dict-build__tile img{width:22px;height:22px;display:block}
.dict-build__track{position:relative;flex:none;width:96px;height:1px;background:var(--line)}
.dict-build__track i{position:absolute;left:-3px;top:-2.5px;width:6px;height:6px;border-radius:50%;background:#fff;box-shadow:0 0 8px rgba(255,255,255,.6);opacity:0}
.dict-build__words{display:grid;align-items:center}
.dict-build__words b{grid-area:1/1;justify-self:start;height:28px;padding:0 12px;display:inline-flex;align-items:center;border-radius:14px;background:rgba(255,255,255,.1);font-size:var(--t-small);font-weight:400;white-space:nowrap;opacity:0}
@keyframes dict-tile{0%,20%,100%{transform:none;box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}8%{transform:scale(1.06);box-shadow:inset 0 0 0 1px rgba(255,255,255,.34)}}
@keyframes dict-dot{0%,10%{transform:translateX(0);opacity:0}18%,50%{opacity:1}58%,100%{transform:translateX(96px);opacity:0}}
@keyframes dict-word{0%{opacity:0;transform:translateY(6px);filter:blur(3px)}6%,30%{opacity:1;transform:none;filter:blur(0)}33.3%,100%{opacity:0;transform:translateY(-6px);filter:blur(0)}}
@media(prefers-reduced-motion:no-preference){
 .dict-build.is-live .dict-build__tile{animation:dict-tile 2.4s cubic-bezier(.42,0,.58,1) infinite}
 .dict-build.is-live .dict-build__tile+.dict-build__tile{animation-delay:.3s}
 .dict-build.is-live .dict-build__track i{animation:dict-dot 2.4s ease-in-out infinite}
 .dict-build.is-live .dict-build__words b{animation:dict-word 7.2s linear infinite}
 .dict-build.is-live .dict-build__words b:nth-child(1){animation-delay:1.4s}
 .dict-build.is-live .dict-build__words b:nth-child(2){animation-delay:3.8s}
 .dict-build.is-live .dict-build__words b:nth-child(3){animation-delay:6.2s}
}
/* Still: no dot, all three words shown. */
@media(prefers-reduced-motion:reduce){.dict-build{height:auto;flex-wrap:wrap}.dict-build__track{display:none}.dict-build__words{display:flex;flex-wrap:wrap;gap:6px}.dict-build__words b{opacity:1}}
@media(max-width:600px){.dict-build__track{width:56px}@keyframes dict-dot{0%,10%{transform:translateX(0);opacity:0}18%,50%{opacity:1}58%,100%{transform:translateX(56px);opacity:0}}}

/* ---------- Privacy stage ----------
   The composition of the earlier Olympia build (after reflect.app's security
   section), in monochrome: a field of unreadable text with a ring of light
   sweeping outward from a glass padlock, the heading and one paragraph over a
   soft scrim. The field is random characters made in t19.js. Features and the
   two disclosures follow below. */
.t19 .privacy{padding-top:0}
.privacy-stage{position:relative;display:grid;place-items:center;text-align:center;overflow:hidden;isolation:isolate;min-height:clamp(34rem,64svh,46rem);padding:clamp(4.5rem,7vw,6rem) 4vw;background:#000}
.privacy-cipher{position:absolute;z-index:-1;inset:2% -9%;opacity:.94;contain:paint}
.privacy-cipher canvas{display:block;width:100%;height:100%}
.privacy-stage__inner{position:relative}
/* The emblem is a padlock in the hero glyphs' glass (same fill, light and rim; no ring around it).
   One 5.2 s loop: it hangs open and tilted, shackle free on the right; it turns left to upright,
   the shackle drops and clicks; at the click a light wipes out over the title and through the
   field behind (t19.js reads this animation's clock, so the three stay together); then it opens. */
.privacy-emblem{position:relative;width:60px;height:70px;margin:0 auto 36px}
.privacy-lock{display:block;width:100%;height:100%;overflow:visible;transform-box:view-box;transform-origin:24px 40px}
.privacy-lock__shackle{transform-box:view-box;transform-origin:15px 30px}
@property --privacy-wipe{syntax:'<length>';inherits:true;initial-value:0px}
@property --privacy-lit{syntax:'<number>';inherits:true;initial-value:1}
@keyframes privacy-lock{
 0%,15%{transform:rotate(12deg)}
 26%{transform:rotate(-4deg);animation-timing-function:cubic-bezier(.3,0,.7,1)}
 33.6%{transform:rotate(0deg) translateY(0);animation-timing-function:cubic-bezier(.2,.8,.2,1)}
 35.4%{transform:rotate(0deg) translateY(1.6px) scale(.965)}
 40%,88%{transform:none}
 100%{transform:rotate(12deg)}
}
@keyframes privacy-shackle{
 0%,15%{transform:translateY(-9px) scaleX(.84)}
 27%{transform:translateY(-9px) scaleX(1);animation-timing-function:cubic-bezier(.5,0,.9,.4)}
 33.6%,88%{transform:none;animation-timing-function:cubic-bezier(.2,.9,.3,1.2)}
 94%{transform:translateY(-10px) scaleX(1)}
 100%{transform:translateY(-9px) scaleX(.84)}
}
@keyframes privacy-wipe{
 0%,33.6%{--privacy-wipe:0px;--privacy-lit:1;animation-timing-function:cubic-bezier(.2,.6,.3,1)}
 62%,88%{--privacy-wipe:1100px;--privacy-lit:1}
 99.9%{--privacy-wipe:1100px;--privacy-lit:.5}
 100%{--privacy-wipe:0px;--privacy-lit:.5}
}
@media(prefers-reduced-motion:no-preference){
 .privacy-stage.is-live .privacy-lock{animation:privacy-lock 5.2s cubic-bezier(.42,0,.58,1) infinite}
 .privacy-stage.is-live .privacy-lock__shackle{animation:privacy-shackle 5.2s cubic-bezier(.42,0,.58,1) infinite}
 /* The title is part of it: it rests dim while the lock is open and the wipe turns it white. */
 .privacy-stage.is-live #privacy-title{color:transparent;-webkit-background-clip:text;background-clip:text;background-image:radial-gradient(circle at 50% -71px,rgba(255,255,255,var(--privacy-lit)) calc(var(--privacy-wipe) - 90px),rgba(255,255,255,.5) var(--privacy-wipe));animation:privacy-wipe 5.2s linear infinite}
}
.privacy-copy{position:relative}
.privacy-copy::before{content:'';position:absolute;z-index:-1;inset:-4rem -8rem;filter:blur(.6rem);background:radial-gradient(ellipse at center,#000 55%,rgba(0,0,0,.6) 72%,transparent 88%)}
.t19 .privacy-copy .body-copy{margin:0 auto;max-width:34rem}
.t19 .free .heading-block{margin-bottom:32px}
.t19 .privacy-copy .heading-block{margin-bottom:56px} /* only the title belongs to the lock; the line starts lower */
.t19 .free .primary{margin-top:24px}
.t19 .free .body-copy{margin-bottom:0}
.t19 .privacy .fgrid{margin-top:0}
.t19 .privacy-details{max-width:720px;margin:56px auto 0}
@media(max-width:1000px){.t19 .privacy-details{max-width:none}}
.t19 .privacy-details summary,.t19 .privacy-details p{font-size:var(--t-body-sm);line-height:24px}
.t19 .privacy-details summary::after{transition:transform .3s cubic-bezier(.2,.8,.2,1)}
@media(max-width:600px){.privacy-cipher{inset-inline:-34%;opacity:.66}.privacy-copy::before{inset:-3rem -2rem}}

/* ---------- Pinned transitions: half the scroll distance ---------- */
@media(prefers-reduced-motion:no-preference) and (min-height:621px){
 .motion-ready .t19 .talking-fold{height:215svh}
 .motion-ready .t19 .orb-dive{height:185svh}
}
@media(prefers-reduced-motion:no-preference) and (min-height:621px) and (max-width:600px){
 .motion-ready .t19 .talking-fold{height:200svh}
 .motion-ready .t19 .orb-dive{height:168svh}
}
