/* Round 9 (November 2026): Mike's picks from the x.ai study (website-improvements/xai-reuse-plan/PLAN.md).
   Loaded last on every page by scripts/round9-finalize.mjs, so it wins over v2.css and rounds 4-8.
   1 near-black page and card colours · 2 cards without outlines · 3 calm hovers instead of whole-card underlines ·
   4 one type scale (x.ai's measured steps, in Alluqi's own font) · 5 healthcare: timeline day-card, sticky role steps.
   Older heading rules use !important, so the type rules here do too, and start with :root to outrank
   page-level rules such as .ip h1; drop both in the clean-up step. */

/* 1. Surfaces: near-black page, cards a step lighter, a lift colour for hovers. */
:root{--bg:#0a0a0a;--header-tint:rgba(10,10,10,.8);--surface:#1a1a1a;--surface2:#222;--lift:#252525;--hairline:rgba(255,255,255,.08)}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]){--bg:#fff;--header-tint:rgba(255,255,255,.8);--surface:#f5f5f4;--surface2:#eaeaea;--lift:#ebebea;--hairline:rgba(10,10,10,.08)}}
:root[data-theme=light],[data-theme=light]{--bg:#fff;--header-tint:rgba(255,255,255,.8);--surface:#f5f5f4;--surface2:#eaeaea;--lift:#ebebea;--hairline:rgba(10,10,10,.08)}
:root[data-theme=dark]{--bg:#0a0a0a;--header-tint:rgba(10,10,10,.8);--surface:#1a1a1a;--surface2:#222;--lift:#252525;--hairline:rgba(255,255,255,.08)}

/* 2. Cards without outlines: the card colour separates them from the page. Lines inside cards stay, and so do the
   outlines on menus, the install panel, form fields and the app-window drawings inside tiles. */
:is(.vp-tile,.bx-tile,.sp-team-tile,.mh-engine,.dp-step,.sc-control,.sc-see-card,.bx-get-tile,.cp-make-card,.cp-spec,.cp-reach-card,.cp-row,.case-card,.contact-card,.access-panel,.ip-own-cost,.ip-panels,.ip-gallery-card,.mh-machine,.mh-spec,.sp-day,.dp-ways,.cp-where,.sc-summary,.sp-ask,.mc-panel,.vp-mode,.bx-job-tabs button){border-color:transparent!important}
/* These used the page colour as their fill, so without the outline they need the card colour. */
:is(.mh-machine,.mh-spec,.sp-day,.dp-ways,.cp-where,.sc-summary,.sp-ask){background:var(--surface)}
/* News thumbnails keep a faint hairline, as x.ai's do. */
:is(.news-featured>a,.news-recent article>a:first-child){border-color:var(--hairline)!important}
/* Role tabs: the chosen one is filled; the others fill on hover. */
.bx-job-tabs button[aria-selected=true]{background:var(--surface)}
.bx-job-tabs button[aria-selected=false]:hover{background:color-mix(in srgb,var(--surface) 60%,transparent)}

/* 3. Hovers. A link that wraps a card (a heading, a paragraph or a picture) no longer underlines every line; plain
   text links keep their underline. Linked cards lighten, pictures zoom slowly and arrows nudge, as on x.ai. */
a:has(:is(h2,h3,h4,p,img,picture,div)):hover,a:has(:is(h2,h3,h4,p,img,picture,div)):hover *,a.news-pill:hover{text-decoration:none}
:is(a.cp-make-card,a.cp-row){transition:background-color .2s cubic-bezier(.4,0,.2,1)}
:is(a.cp-make-card,a.cp-row):hover{background:var(--lift)}
.cp-make-art img{transition:transform .5s cubic-bezier(0,0,.2,1)}
a.cp-make-card:hover .cp-make-art img{transform:scale(1.02)}
a.cp-row svg{transition:transform .2s cubic-bezier(.22,1,.36,1)}
a.cp-row:hover svg{transform:translate(3px,-3px)}
/* Secondary buttons ("Contact sales" and the like) are filled pills like x.ai's "View Documentation": no outline, a
   shade lighter on hover in 150 ms. Primary buttons, the header and the cookie banner keep their own styles. */
:root{--button2:#222;--button2-hover:#2c2c2c}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]){--button2:#ebebea;--button2-hover:#e0e0de}}
:root[data-theme=light],[data-theme=light]{--button2:#ebebea;--button2-hover:#e0e0de}
:root[data-theme=dark]{--button2:#222;--button2-hover:#2c2c2c}
:root main .button:not(.primary,.bp-btn--primary,.button--primary){border-color:transparent;background:var(--button2);color:var(--fg);transition:background-color .15s ease}
:root main .button:not(.primary,.bp-btn--primary,.button--primary):hover{background:var(--button2-hover)}
/* x.ai's rule for every button: on hover the white (primary) one dims to 90% brightness and the grey one lightens;
   nothing moves. This applies it to our primary buttons and to the header's "Contact sales" too. */
/* Every primary button in the page is the page's text colour: white in dark, black in light. A lone button, or the
   first of a row, is the primary; any after it are grey (Mike, 2026-11-02). Some pages had their own white that stayed
   white in light, or an outline. */
:root main :is(.button.primary,.button.bp-btn--primary,.button.button--primary){background:var(--fg);border-color:var(--fg);color:var(--bg)}
:is(.button.primary,.bp-btn--primary,.access-split>.button){transition:filter .15s ease}
:is(.button.primary,.bp-btn--primary,.access-split>.button):hover{opacity:1;filter:brightness(.9)}
.nav-sales{background:var(--button2);transition:background-color .15s ease}
.nav-sales:hover{opacity:1;background:var(--button2-hover)}
/* The homepage "New" pill brightens on hover, as x.ai's does: outline, text and arrow chip lighten in 150 ms. */
.news-pill,.news-pill .news-pill-copy,.news-pill .news-pill-arrow{transition:border-color .15s ease,color .15s ease,background-color .15s ease}
.news-pill .news-pill-copy{color:color-mix(in srgb,var(--fg) 85%,transparent)}
.news-pill:hover{border-color:color-mix(in srgb,var(--fg) 30%,transparent)}
.news-pill:hover .news-pill-copy{color:var(--fg)}
.news-pill:hover .news-pill-arrow{background:color-mix(in srgb,var(--fg) 12%,transparent)}
:is(.news-featured>a,.news-recent article>a:first-child){transition:border-color .3s ease}
:is(.news-featured>a,.news-recent article>a:first-child):hover{border-color:color-mix(in srgb,var(--fg) 20%,transparent)!important}
:is(.news-featured>a,.news-recent article>a:first-child) img{transition:transform .7s cubic-bezier(.22,1,.36,1)}
:is(.news-featured>a,.news-recent article>a:first-child):hover img{transform:scale(1.03)}

/* 4. One type scale: 60/48/36/30/24/20 for headings, 18 lede, 14 labels. Headlines step down to 48 below 1024 px
   and 36 below 640 px. Headings are weight 500 (the page headline 450) with -0.01em tracking. */
:root{--t-display:60px;--t-display-lh:60px;--t-large:48px;--t-large-lh:48px;--t-section:36px;--t-section-lh:40px;--t-feature:30px;--t-feature-lh:36px;--t-card:24px;--t-card-lh:32px;--t-step:20px;--t-step-lh:28px}
@media(max-width:1023px){:root{--t-display:48px;--t-display-lh:48px}}
@media(max-width:639px){:root{--t-display:36px;--t-display-lh:40px;--t-large:30px;--t-large-lh:36px;--t-section:30px;--t-section-lh:36px;--t-feature:24px;--t-feature-lh:32px}}
:root main h1{font-size:var(--t-display)!important;line-height:var(--t-display-lh)!important;font-weight:450!important;letter-spacing:-.01em!important;text-wrap:balance}
:root main h2:where(:not(.card-label h2)){font-size:var(--t-section)!important;line-height:var(--t-section-lh)!important;font-weight:500!important;letter-spacing:-.01em!important;text-wrap:balance}
:root main :is(.it-split,.get-started,.closing) h2{font-size:var(--t-large)!important;line-height:var(--t-large-lh)!important}
:root main :is(.access-panel,.mc-panel,.legal-section,.solution-grid) h2,:root main .start-grid h3{font-size:var(--t-feature)!important;line-height:var(--t-feature-lh)!important}
:root main :is(.cp-reach-card,.contact-card,.case-card,.news-empty,.feature) h2,:root main :is(.vp-tile,.sp-team-tile,.bx-get-tile,.mh-engine,.ip-own-cost,.ip-vendor-costs,.news-recent,.news-all) h3{font-size:var(--t-card)!important;line-height:var(--t-card-lh)!important;font-weight:500!important}
:root main :is(.sc-see-card,.sc-control-copy,.dp-step-copy,.cp-make-copy,.cp-runs,.mh-machine,.mh-ladder-head,.mh-part,.mh-choose,.mh-media-engines,.mh-group-head,.bx-principles,.sc-review-grid,.cp-step-list) h3{font-size:var(--t-step)!important;line-height:var(--t-step-lh)!important;font-weight:500!important}
:root main h3{letter-spacing:-.01em!important}
/* /bridge sets its heading line heights with page-level !important rules (bridge-brand.css, round7.css, bridge-page.css). */
:root .bridge-page main h1{line-height:var(--t-display-lh)!important}
:root .bridge-page main h2:where(:not(.card-label h2)){line-height:var(--t-section-lh)!important}
:root main .ip-subhead{font-size:var(--t-feature)!important;line-height:var(--t-feature-lh)!important;letter-spacing:-.01em!important}
/* The line under each page headline is full text colour, as on x.ai and the newer pages (it was grey on the
   homepage and the older pages). */
:root main :is(.ip-lede,.intro,.ap-lede){font-size:18px;line-height:29px;color:var(--fg)}
:root main .eyebrow{font-size:14px;line-height:20px;font-weight:500;letter-spacing:0;text-transform:none}
:root main :is(.news-recent,.news-all) .eyebrow{font-size:12px;line-height:16px;font-weight:400}

/* 5. Solutions pages. Each page's hero day-card has its own look (set per page in scripts/<field>-page-data.mjs).
   Timeline (healthcare): one line down the left, a dot at each time. */
.sp-day--timeline ol{position:relative;padding-left:44px}
.sp-day--timeline ol::before{content:"";position:absolute;top:26px;bottom:26px;left:26px;width:2px;border-radius:2px;background:color-mix(in srgb,var(--bx-accent,#00d4ff) 55%,transparent)}
.sp-day--timeline li{position:relative;border-top:0}
.sp-day--timeline li::before{content:"";position:absolute;top:19px;left:-22px;width:10px;height:10px;border-radius:50%;background:var(--surface);box-shadow:0 0 0 2px var(--bx-accent,#00d4ff)}
/* Stacked cards (legal): each line is its own card with no frame around them, offset left and right on wider screens. */
.sp-day--stack{background:none;overflow:visible}
.sp-day--stack .sp-day-top{border:0;padding-left:4px}
.sp-day--stack ol{gap:8px;padding:0}
.sp-day--stack li,.sp-day--stack li:first-child{padding:16px 18px;border:0;border-radius:16px;background:var(--surface)}
@media(min-width:640px){.sp-day--stack li:nth-child(odd){margin-right:22px}.sp-day--stack li:nth-child(even){margin-left:22px}}
/* Lab notebook (research): a window with Mac buttons; each entry a log line with its time in mono, who ran it as a
   coloured tag, and the file as a code chip. Colours: the routine green, a phone rose, then each person in turn. */
.sp-day [class*="sp-k"]{--k:#00d4ff}
.sp-day .sp-k1{--k:#a78bfa}.sp-day .sp-k2{--k:#fbbf24}.sp-day .sp-k3{--k:#60a5fa}.sp-day .sp-k-routine{--k:#34d399}.sp-day .sp-k-phone{--k:#fb7185}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]) .sp-day [class*="sp-k"]{--k:#0891b2}:root:not([data-theme=dark]) .sp-day .sp-k1{--k:#7c3aed}:root:not([data-theme=dark]) .sp-day .sp-k2{--k:#b45309}:root:not([data-theme=dark]) .sp-day .sp-k3{--k:#2563eb}:root:not([data-theme=dark]) .sp-day .sp-k-routine{--k:#059669}:root:not([data-theme=dark]) .sp-day .sp-k-phone{--k:#e11d48}}
:root[data-theme=light] .sp-day [class*="sp-k"]{--k:#0891b2}:root[data-theme=light] .sp-day .sp-k1{--k:#7c3aed}:root[data-theme=light] .sp-day .sp-k2{--k:#b45309}:root[data-theme=light] .sp-day .sp-k3{--k:#2563eb}:root[data-theme=light] .sp-day .sp-k-routine{--k:#059669}:root[data-theme=light] .sp-day .sp-k-phone{--k:#e11d48}
.sp-day--notebook{background:var(--bg)}
.sp-day--notebook .sp-day-top i{width:9px;height:9px;margin-right:34px;background:#ff5f57;box-shadow:14px 0 #febc2e,28px 0 #28c840}
.sp-day--notebook li{grid-template-columns:62px minmax(0,1fr);border-top:1px dashed var(--line)}
.sp-day--notebook time{font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.sp-day--notebook b{justify-self:start;padding:1px 8px;border-radius:6px;font-size:11.5px;color:var(--k);background:color-mix(in srgb,var(--k) 13%,transparent)}
.sp-day--notebook em{border:0;border-radius:6px;padding:2px 8px;font:11.5px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--fg);background:var(--surface2)}
/* Calendar (personal): the day as blocks down an hour rail, each in its project's colour. */
.sp-day--calendar ol{position:relative;gap:8px;padding:14px 20px 18px 20px;background:repeating-linear-gradient(to bottom,transparent 0 47px,color-mix(in srgb,var(--line) 70%,transparent) 47px 48px)}
.sp-day--calendar li,.sp-day--calendar li:first-child{grid-template-columns:58px minmax(0,1fr);gap:10px;padding:0;border:0}
.sp-day--calendar time{padding-top:10px;font-size:12px}
.sp-day--calendar li div{padding:9px 12px 10px;border-left:3px solid var(--k);border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--k) 11%,var(--bg))}
.sp-day--calendar b{color:var(--k)}
.sp-day--calendar em{margin-top:4px;padding:0;border:0;font-size:11.5px}
/* Register (government): the day as a contract activity log, with column headings, ruled and striped rows, a colour bar
   for who ran each line and its file as the record it went into. */
.sp-day--ledger ol{padding:0 0 6px}
.sp-day--ledger .sp-day-cols{display:grid;grid-template-columns:62px minmax(0,1fr);gap:14px;margin:0;padding:9px 20px 9px 24px;border-bottom:1px solid var(--line);font-size:11px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.sp-day--ledger .sp-day-cols span{color:var(--muted)}
.sp-day--ledger li,.sp-day--ledger li:first-child{position:relative;grid-template-columns:62px minmax(0,1fr);padding:12px 20px 12px 24px;border-top:1px solid var(--line)}
.sp-day--ledger li:first-child{border-top:0}
.sp-day--ledger li:nth-child(even){background:color-mix(in srgb,var(--fg) 3%,transparent)}
.sp-day--ledger li::before{content:"";position:absolute;left:10px;top:14px;bottom:14px;width:3px;border-radius:2px;background:var(--k)}
.sp-day--ledger time{font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.sp-day--ledger b{font-size:11.5px;font-weight:500;letter-spacing:.04em;text-transform:uppercase;color:var(--k)}
.sp-day--ledger em{margin-top:4px;padding:0;border:0;font-size:11.5px;color:var(--muted)}
.sp-day--ledger em::before{content:"Filed to ";color:var(--muted)}
/* Hero day cards (Mike, 2026-11-02): the lines come in one by one once on load and stay, rather than looping like the
   header menu they borrow it from (bridge-menu.css). The loop fades them out at 88.9%, so the one play stops there. */
/* The day card's lines rise in one after another as the hero text does, starting as the headline lands, so the card is
   full about when the text is (Mike, 2026-11-02; it used to take 16 s). Once; still under reduced motion. */
@keyframes sp-day-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
:root .sp-day .bx-menu-line{opacity:0;animation:sp-day-in .38s cubic-bezier(.22,1,.36,1) forwards;animation-delay:calc(700ms + var(--i,0) * 110ms)}
@media(prefers-reduced-motion:reduce){:root .sp-day .bx-menu-line{animation:none;opacity:1;transform:none}}
/* Sticky role steps, desktop only (as x.ai /grok): the roles run down the left, the phone stays pinned, and the role
   in the middle of the screen picks its chat (bridge-page.js). Others dim to 20%. Phones keep the tabs. */
@media(min-width:1024px){
 .bx-jobs--steps{align-items:start}
 .bx-jobs--steps .bx-job-tabs{grid-template-columns:minmax(0,1fr);gap:0;margin-top:12px}
 .bx-jobs--steps .bx-job-tabs button{min-height:44vh;justify-content:center;gap:8px;padding:0;background:none!important;opacity:.2;transition:opacity .5s cubic-bezier(.4,0,.2,1)}
 .bx-jobs--steps .bx-job-tabs button:hover{opacity:.6}
 .bx-jobs--steps .bx-job-tabs button[aria-selected=true]{opacity:1}
 .bx-jobs--steps .bx-job-tabs span{font-size:var(--t-feature);line-height:var(--t-feature-lh);font-weight:500;letter-spacing:-.01em}
 .bx-jobs--steps .bx-job-tabs small{font-size:16px;line-height:26px;color:var(--muted)}
 .bx-jobs--steps .bx-job-note{display:none}
 .bx-jobs--steps .bx-phone{position:sticky;top:max(96px,calc(50vh - 372px))}
}

/* 6. Homepage headline intro, as on x.ai's homepage (measured there): each headline word tilts up in turn (650 ms,
   100 ms + 55 ms per word), then the "New" pill, the line under the headline and the buttons rise into place.
   round9-intro.js turns it on before the page draws, on a first visit or a reload only, never with reduced motion.
   "backwards" fill hands each element back to its own styles when it lands, so the portal's scroll fade still works. */
@keyframes r9-tilt{from{opacity:0;transform:perspective(600px) rotateX(-40deg) translateY(45%)}to{opacity:1;transform:none}}
@keyframes r9-rise{from{opacity:0;transform:translateY(var(--r9-y,8px))}to{opacity:1;transform:none}}
.r9-w{display:inline-block}
.r9-intro .home-rotating-heading :is(.r9-w,.hero-word-slot){transform-origin:50% 100%;animation:r9-tilt .65s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(100ms + var(--w,0) * 55ms)}
.r9-intro .ap-copy .news-pill{--r9-y:8px;animation:r9-rise .32s cubic-bezier(.22,1,.36,1) .32s backwards}
.r9-intro .ap-copy .ap-lede{--r9-y:16px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .58s backwards}
.r9-intro .ap-copy .actions{--r9-y:12px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .7s backwards}

/* 7. Setup terminal (homepage "Local model setup", scripts/setup-terminal.mjs): a macOS terminal that types a
   runtime's start command and prints what it shows, a copy button in the title bar and one pill per runtime. The
   window follows the theme: dark, or in light mode a white macOS-style window with darker syntax colours that stay
   readable on white (all text at least 4.5:1). */
.st{display:grid;gap:14px;align-content:start;min-width:0;--st-bg:#0c0c0d;--st-fg:#e8e8e8;--st-edge:0 0 0 1px rgba(255,255,255,.08),0 28px 60px -28px rgba(0,0,0,.55);--st-bar:#18181a;--st-bar-line:rgba(255,255,255,.06);--st-title:#9b9b9f;--st-strong:#fafafa;--st-prompt:#7d8794;--st-flag:#5fd4ee;--st-arg:#f3c77b;--st-dim:#a1a1a6;--st-ok:#5ee08f;--st-meter:#5fd4ee}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]) .st{--st-bg:#fff;--st-fg:#1d1d1f;--st-edge:0 0 0 1px rgba(0,0,0,.09),0 28px 60px -30px rgba(0,0,0,.22);--st-bar:#f2f2f1;--st-bar-line:rgba(0,0,0,.07);--st-title:#6e6e73;--st-strong:#111;--st-prompt:#6b7280;--st-flag:#0e7490;--st-arg:#b45309;--st-dim:#6e6e73;--st-ok:#15803d;--st-meter:#0891b2}}
:root[data-theme=light] .st,[data-theme=light] .st{--st-bg:#fff;--st-fg:#1d1d1f;--st-edge:0 0 0 1px rgba(0,0,0,.09),0 28px 60px -30px rgba(0,0,0,.22);--st-bar:#f2f2f1;--st-bar-line:rgba(0,0,0,.07);--st-title:#6e6e73;--st-strong:#111;--st-prompt:#6b7280;--st-flag:#0e7490;--st-arg:#b45309;--st-dim:#6e6e73;--st-ok:#15803d;--st-meter:#0891b2}
/* Deployment's copy of the window draws its bar in violet (Mike: "we can change up the color"). */
.st.st--violet{--st-meter:#a78bfa}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]) .st.st--violet{--st-meter:#7c3aed}}
:root[data-theme=light] .st.st--violet,[data-theme=light] .st.st--violet{--st-meter:#7c3aed}
/* As x.ai's developer section, the window side gets a little more room than the text, so the pills fit one row. */
@media(min-width:1101px){.it-split{grid-template-columns:minmax(0,1fr) minmax(0,1.2fr)}}
.st-window{border-radius:12px;background:var(--st-bg);color:var(--st-fg);box-shadow:var(--st-edge);overflow:hidden}
.st-bar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:12px;padding:10px 12px;background:var(--st-bar);border-bottom:1px solid var(--st-bar-line)}
.st-dots{display:flex;gap:7px}
.st-dots i{width:12px;height:12px;border-radius:50%;background:#ff5f57}
.st-dots i:nth-child(2){background:#febc2e}
.st-dots i:nth-child(3){background:#28c840}
.st-title{font-size:12px;line-height:16px;color:var(--st-title);white-space:nowrap}
.st-copy{justify-self:end;display:inline-flex;align-items:center;gap:6px;font-family:inherit;font-weight:400;font-size:13px;line-height:16px;color:var(--st-title);background:none;border:0;border-radius:6px;padding:4px 2px;cursor:pointer;transition:color .15s ease}
.st-copy svg{flex:none}
.st-copy:hover{color:var(--st-strong)}
.st-screen{margin:0;padding:16px 18px 20px;min-height:236px;font:13px/1.75 ui-monospace,"SF Mono",Menlo,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}
.st-line{display:block}
.st-p{color:var(--st-prompt)}
.st-prog{color:var(--st-strong);font-weight:600}
.st-sub{color:var(--st-strong)}
.st-flag{color:var(--st-flag)}
.st-arg{color:var(--st-arg)}
.st-out,.st-dim,.st-pct{color:var(--st-dim)}
.st-ok{color:var(--st-ok)}
.st-meter{color:var(--st-meter)}
.st-caret{display:inline-block;width:.6em;height:1.15em;vertical-align:-.22em;background:var(--st-fg);animation:st-blink 1.1s steps(1) infinite}
@keyframes st-blink{50%{opacity:0}}
.st-runtimes{display:flex;flex-wrap:wrap;gap:2px}
.st-runtimes button{font-family:inherit;font-weight:500;font-size:14px;line-height:20px;color:var(--muted);background:none;border:0;border-radius:999px;padding:7px 11px;cursor:pointer;transition:color .15s ease,background-color .15s ease}
.st-runtimes button:hover{color:var(--fg)}
.st-runtimes button[aria-pressed=true]{color:var(--bg);background:var(--fg)}
.st-sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* 8. Homepage counters and "Latest news" (scripts/home-latest.mjs), sized as x.ai's (measured there): numbers 48/48
   between two thin rules, with dividers that stop short of them; "Latest news" 30/36, "All posts" 14/20, cards four
   across with 20 px gaps, a 12/16 meta line and 16/22 titles. Each post's colour stays inside its panel. */
.hc{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));padding-block:40px;border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin-block:24px 112px}
.hc-cell{display:grid;gap:16px;align-content:start;padding:8px 40px 8px 0}
.hc-cell+.hc-cell{padding-left:40px;border-left:1px solid var(--line)}
.hc-cell b{font-size:var(--t-large);line-height:var(--t-large-lh);font-weight:450;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.hc-cell span{font-size:16px;line-height:26px;color:var(--muted)}
@media(max-width:639px){.hc{grid-template-columns:minmax(0,1fr);padding-block:8px;margin-bottom:72px}.hc-cell{padding:24px 0}.hc-cell+.hc-cell{padding-left:0;border-left:0;border-top:1px solid var(--line)}}
.hn{margin-bottom:96px}
.hn-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:24px}
:root main .hn-head h2{font-size:var(--t-feature)!important;line-height:var(--t-feature-lh)!important}
.hn-all{display:inline-flex;align-items:center;gap:4px;font-size:14px;line-height:20px;font-weight:500}
.hn-all:hover{text-decoration:none}
/* As x.ai's: on hover the chevron grows a stem and becomes an arrow. */
.hn-stem{opacity:0;transition:opacity .15s ease}
.hn-all:hover .hn-stem,a.hn-card:hover .hn-stem{opacity:1}
.hn-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px}
@media(max-width:1023px){.hn-grid{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:32px}}
@media(max-width:639px){.hn-grid{grid-template-columns:minmax(0,1fr)}}
.hn-card{display:grid;gap:8px;align-content:start;color:inherit}
.hn-art{aspect-ratio:1.9;margin-bottom:8px;border-radius:8px;overflow:hidden;box-shadow:0 0 0 1px color-mix(in srgb,var(--fg) 6%,transparent);transition:box-shadow .3s cubic-bezier(.4,0,.2,1)}
.hn-art span{display:grid;place-content:center;justify-items:center;gap:4px;height:100%;color:#fff;text-align:center;transition:transform .7s cubic-bezier(.22,1,.36,1)}
.hn-art small{font-size:12px;line-height:16px;font-weight:500;opacity:.8}
.hn-art b{font-size:clamp(30px,2.6vw,40px);line-height:1;font-weight:450;letter-spacing:-.02em}
a.hn-card:hover .hn-art{box-shadow:0 0 0 1px color-mix(in srgb,var(--fg) 20%,transparent)}
a.hn-card:hover .hn-art span{transform:scale(1.03)}
.hn-art--violet span{background:radial-gradient(120% 100% at 85% 0%,rgba(255,255,255,.2),transparent 55%),#4a3fae}
.hn-art--teal span{background:radial-gradient(120% 100% at 85% 0%,rgba(255,255,255,.18),transparent 55%),#0f5262}
.hn-art--amber span{background:radial-gradient(120% 100% at 85% 0%,rgba(255,255,255,.18),transparent 55%),#94601c}
/* The next release, before its notes exist: a dark panel with a dashed edge, not a link. */
.hn-art--next span{background:#1c1c1f;color:rgba(255,255,255,.62);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);border-radius:8px;background-clip:padding-box;outline:1px dashed rgba(255,255,255,.28);outline-offset:-10px}
.hn-meta{margin:0;font-size:12px;line-height:16px;color:var(--muted)}
.hn-meta b{font-weight:500;color:var(--fg)}
:root main .hn-card h3{margin:0;font-size:16px!important;line-height:22px!important;font-weight:500!important;letter-spacing:-.01em!important}
.hn-card h3 .hn-chevron{display:inline;vertical-align:-1px;margin-left:2px}
.hn-end{white-space:nowrap}

/* 9. One content width, as x.ai's (measured: 1232 px inside a 1280 px container, 104 px side margins at 1440). Older
   pages and the homepage used 1328 px; newer pages and the header already used 1232. Below 1100 px the side margins
   are 16 px, matching the header. Columns with their own narrower limit (articles, legal panels) keep it. */
:root .wrap{width:min(1232px,calc(100% - 48px));margin-inline:auto}
@media(max-width:1100px){:root .wrap{width:calc(100% - 32px)}}
/* The homepage hero places its text with its own padding, so it lines up with the same edges. */
.ap-seq{--ap-pad:max(24px,calc((100% - 1232px)/2))}
@media(max-width:1100px){.ap-seq{--ap-pad:16px}}

/* 10. "Choose how to get started" (homepage) as x.ai's: a rule above the section, a centred 30/36 heading, two cards in
   the card colour (radius 16, padding 40) with a line under the intro, tick lists and full-width buttons; the second
   button is an outline pill there, as x.ai's "Contact Sales" is inside its card. */
.get-started{border-top:1px solid var(--line);padding-block:96px}
:root main .get-started>h2{text-align:center;max-width:none;margin:0 auto 12px;font-size:var(--t-feature)!important;line-height:var(--t-feature-lh)!important}
.get-started>p{text-align:center;margin:0}
.start-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;margin-top:40px}
@media(max-width:767px){.start-grid{grid-template-columns:minmax(0,1fr);gap:16px}}
.start-grid article{display:flex;flex-direction:column;padding:40px;border:0;border-radius:16px;background:var(--surface)}
@media(max-width:639px){.start-grid article{padding:32px 24px}}
:root main .start-grid h3{margin:0;font-size:var(--t-card)!important;line-height:var(--t-card-lh)!important}
.start-grid p{margin:12px 0 0;padding-bottom:24px;border-bottom:1px solid var(--line);color:var(--fg)}
.start-grid ul{list-style:none;display:grid;gap:14px;margin:24px 0 40px;padding:0;font-size:16px;line-height:24px;color:var(--fg)}
.start-grid li{display:grid;grid-template-columns:16px minmax(0,1fr);gap:12px}
.start-grid li::before{content:"";width:16px;height:16px;margin-top:4px;background:var(--muted);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3.5 8.5 3 3 6-7'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3.5 8.5 3 3 6-7'/%3E%3C/svg%3E") center/contain no-repeat}
.start-grid .button{width:100%;margin-top:auto}
:root main .start-grid .button:not(.primary){background:transparent;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg) 18%,transparent)}
:root main .start-grid .button:not(.primary):hover{background:color-mix(in srgb,var(--fg) 6%,transparent)}

/* 11. The line under the homepage's changing word (as x.ai's): it rests grey, and a cyan light zips across it once
   after the intro and each time a new word finishes (round9-intro.js adds .r9-sweep); on a first visit it also grows in
   from the left after the headline lands. Our cyan, not x.ai's rainbow. The old always-on shimmer is turned off. */
:root{--r9-sweep-core:#e5fcff}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]){--r9-sweep-core:#007f9c}}
:root[data-theme=light],[data-theme=light]{--r9-sweep-core:#007f9c}
:root[data-theme=dark]{--r9-sweep-core:#e5fcff}
:root .hero-word-slot::after{height:3px;border-radius:2px;background:linear-gradient(90deg,transparent,var(--hero-accent,#00d4ff) 22%,var(--r9-sweep-core) 50%,var(--hero-accent,#00d4ff) 78%,transparent) no-repeat,color-mix(in srgb,var(--fg) 25%,transparent);background-size:150% 100%,auto;background-position:300% 0,0 0;animation:none}
:root .hero-word-slot.r9-sweep::after{animation:r9-sweep 1.4s cubic-bezier(.4,0,.2,1) both}
/* A light one and a half times the line's length, travelling from off the left end to off the right end. */
@keyframes r9-sweep{from{background-position:300% 0,0 0}to{background-position:-200% 0,0 0}}
.r9-intro .home-rotating-heading .hero-word-slot::after{transform-origin:left;animation:r9-grow .8s cubic-bezier(.16,1,.3,1) .8s backwards}
@keyframes r9-grow{from{opacity:0;transform:scaleX(0)}to{opacity:1;transform:none}}

/* 12. Homepage Chat and Code review tiles, as x.ai's tiles: questions, replies and work chips all sit on one soft grey a step
   lighter than the card, with no outlines. The replies used the page colour, which turned near-black once cards lost
   their borders. Approval chips keep a faint ring so they still read as asking. */
:root{--tile-bubble:color-mix(in srgb,var(--fg) 7%,var(--surface))}
.hc-chat :is(.hc-user,.hc-assistant){background:var(--tile-bubble)}
:is(.hc-chat,.hc-code-session) .session-action{border-color:transparent;background:var(--tile-bubble)}
:is(.hc-chat,.hc-code-session) .session-action[data-action-kind=approval]{border-color:color-mix(in srgb,var(--fg) 25%,transparent)}

/* 13. Header menu, as x.ai's (measured): 13/19.5 text at weight 500, items side by side with 12 px padding and no
   gap, header buttons 36 px tall with weight 500 text. Desktop widths only; the phone menu keeps its own sizes. */
@media(min-width:1101px){
 .header .nav-links{gap:0}
 .header .nav-links>a,.header .nav-links .mega>summary{padding:6px 12px;font-size:13px;line-height:19.5px;font-weight:500}
 .header .nav-sales{padding:8px 16px;font-weight:500;line-height:20px}
 .header .theme-toggle{width:36px;height:36px}
}

/* 14. Homepage product tiles on hover, as x.ai's (measured): a soft diagonal light sweeps across once in 700 ms and
   snaps back when the pointer leaves (the transition is only on hover); the preview zooms 2% in 500 ms; the name and
   "Explore" brighten in 300 ms. Transitions, not animations, so the tile's own demo pause on hover doesn't stop it. */
:root{--sheen-soft:rgba(255,255,255,.06);--sheen:rgba(255,255,255,.1)}
@media(prefers-color-scheme:light){:root:not([data-theme=dark]){--sheen-soft:rgba(255,255,255,.3);--sheen:rgba(255,255,255,.5)}}
:root[data-theme=light],[data-theme=light]{--sheen-soft:rgba(255,255,255,.3);--sheen:rgba(255,255,255,.5)}
:root[data-theme=dark]{--sheen-soft:rgba(255,255,255,.06);--sheen:rgba(255,255,255,.1)}
.home-product-grid .product-card::after{content:"";position:absolute;top:0;left:0;z-index:2;width:200%;height:100%;pointer-events:none;background:linear-gradient(120deg,transparent 40%,var(--sheen-soft) 48%,var(--sheen) 50%,var(--sheen-soft) 52%,transparent 60%);transform:translateX(-100%)}
.home-product-grid .product-card:hover::after{transform:translateX(100%);transition:transform .7s cubic-bezier(0,0,.2,1)}
.home-product-grid .product-card .card-visual{transform-origin:50% 40%;transition:transform .5s cubic-bezier(0,0,.2,1)}
.home-product-grid .product-card:hover .card-visual{transform:scale(1.02)}
.home-product-grid .product-card .card-label :is(h2,span){transition:color .3s cubic-bezier(.4,0,.2,1)}

/* 15. Header line, as x.ai's (measured): no line at the top of the page; a faint 1 px line (about 7% of the text colour)
   once the page scrolls, as wide as x.ai's 1280 px box (the 1232 px content plus 24 px a side), full width below that.
   v2.js adds .scrolled as soon as the page leaves the top. Replaces the old full-width always-on line and the second
   line that scrolling stacked under it. */
:root body .header{border-bottom-color:transparent!important;box-shadow:none!important}
:root body .header::after{content:"";position:absolute;left:50%;bottom:-1px;width:min(1280px,100%);height:1px;transform:translateX(-50%);background:color-mix(in srgb,var(--fg) 7%,transparent);opacity:0;pointer-events:none}
:root body .header.scrolled::after{opacity:1}

/* 16. Images page pill switches, as x.ai's Imagine page (measured): the chosen tab's fill is one pill that slides to the
   next tab (about 0.2 s, fast start, soft landing) instead of jumping. Example tabs: public/product-features.js; the
   Image / Video switch under the prompt: public/images-page.js. Without the scripts the chosen item keeps its own fill.
   Reduced motion: images-page.css turns the slide off. The same white (black in light) sliding fill on the homepage
   runtimes and Deployment platforms (setup-terminal.js) and Models & hardware's Mac / Windows PC (models-hardware.js),
   Mike, 2026-11-02. */
.ip-tabs.has-pill,.ip-mode-toggle.has-pill,.st-runtimes.has-pill{position:relative;isolation:isolate}
.ip-tab-pill{position:absolute;top:0;left:0;z-index:-1;border-radius:999px;background:var(--fg);pointer-events:none;transition:transform .22s cubic-bezier(.32,.72,0,1),width .22s cubic-bezier(.32,.72,0,1),height .22s cubic-bezier(.32,.72,0,1)}
.ip-tabs.has-pill button,.ip-mode-toggle.has-pill button{transition:color .2s ease,background-color .15s ease,border-color .2s ease}
.ip-tabs.has-pill button[aria-selected=true],.ip-tabs.has-pill button[aria-selected=true]:hover,.ip-mode-toggle.has-pill button[aria-checked=true],.ip-mode-toggle.has-pill button[aria-checked=true]:hover{background:transparent;border-color:transparent;color:var(--bg)}
.st-runtimes.has-pill button[aria-pressed=true],.st-runtimes.has-pill button[aria-pressed=true]:hover{background:transparent;color:var(--bg)}
/* Every pill row is sized like the homepage runtimes (Mike, 2026-11-02): Images examples and switch, Models & hardware's
   Mac / Windows PC, Bridge's voice examples. */
:root main :is(.ip-tabs,.ip-mode-toggle,.vp-chat-pills) button{min-height:0;padding:7px 11px;font-size:14px;line-height:20px;font-weight:500}
:root main :is(.ip-tabs,.vp-chat-pills){gap:2px}
/* FAQ and Use cases topic filters: the chosen topic is the white (black in light) pill. The x.ai button pass above had
   turned it grey like the others (Mike, 2026-11-02). */
:root main .topic-filters .button[aria-pressed=true],:root main .topic-filters .button[aria-pressed=true]:hover{background:var(--fg);color:var(--bg)}

/* 17. Voice page motion, as x.ai's Voice page (measured there). On arrival the headline tilts up word by word (as the
   homepage, section 6) and the rest of the hero rises in after it. "The details, at a glance." tilts up as it scrolls
   in and its cards rise 16 px and fade in, 60 ms apart (round9-reveal.js). In the chat demo each said line appears
   word by word with a soft blur, 50 ms apart (voice-page.js). The example row's fill slides like the Images tabs. */
.r9-intro .vp .ip-hero-copy h1 .r9-w{transform-origin:50% 100%;animation:r9-tilt .65s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(100ms + var(--w,0) * 55ms)}
.r9-intro .vp .ip-hero-copy .eyebrow{--r9-y:10px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .2s backwards}
.r9-intro .vp .ip-hero-copy .ip-subhead{--r9-y:14px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .48s backwards}
.r9-intro .vp .ip-hero-copy .ip-lede{--r9-y:14px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .58s backwards}
.r9-intro .vp .ip-hero-copy .ip-actions{--r9-y:12px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .66s backwards}
.r9-intro .vp .ip-hero-copy .ip-specs{--r9-y:10px;animation:r9-rise .4s cubic-bezier(.22,1,.36,1) 1.15s backwards}
@keyframes r9-card{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.r9-wait .r9-w,.r9-wait-card{opacity:0}
.r9-tilt-in .r9-w{transform-origin:50% 100%;animation:r9-tilt .65s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(var(--w,0) * 55ms)}
.r9-rise-in{animation:r9-card .45s cubic-bezier(.23,1,.32,1) backwards;animation-delay:var(--r9-d,0ms)}
/* The three voice orbs beside "Choose a voice" grow in one after another when the graphic comes on screen, as x.ai's
   orbs do (measured: about 0.5 s each, about 0.125 s apart, no fade), then carry on circling. Ours grow as a circle
   opening from the centre rather than a scale: the orbs are drawn live by portal-orbs.js, which fails on an orb whose
   on-screen size changes, and a clip leaves the size alone. They wait invisible and grow once drawn (round9-reveal.js). */
@keyframes r9-pop{from{clip-path:circle(0% at 50% 50%)}to{clip-path:circle(75% at 50% 50%)}}
.r9-wait-pop .vs-sphere{opacity:0}
.r9-pop-in .vs-sphere{animation:r9-pop .5s cubic-bezier(.22,1,.36,1) backwards;animation-delay:var(--r9-d,0ms)}
@keyframes vp-word-fade{from{opacity:0}}
@keyframes vp-word-focus{from{filter:blur(3px)}}
.vp-word{display:inline-block;animation:vp-word-fade .5s cubic-bezier(.22,1,.36,1) backwards,vp-word-focus .275s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(var(--i,0) * 50ms)}
.vp-chat-pills.has-pill{position:relative;isolation:isolate}
.vp-chat-pills.has-pill button[aria-pressed=true]{background:transparent;color:var(--bg)}
/* Phones and tablets, where the hero stacks: its card, phone or photo sits 44 px under the hero text, as on Models &
   hardware and Voice (Mike, 2026-11-02: on Company the buttons touched the card; elsewhere it was 12 px). */
@media(max-width:1023px){:root .ip-hero>.ip-hero-copy>:last-child{margin-bottom:0}:root .ip-hero>.ip-hero-copy+*{margin-top:44px}}
/* The feature list may shrink to the screen: on a 360 px phone Safari sized Voice's column by "Your tools,
   mid-conversation" unwrapped and the page scrolled sideways (Mike, 2026-11-02). */
.ip-features>.ip-feature-list{min-width:0}

/* 18. Header menus, as x.ai's (Mike, 2026-11-02): on wide screens one backing panel (v2.js) carries the menus' fill,
   border and shadow. Opening fades it in with the menu; moving from one menu to the next slides and resizes it under
   the new one (about 0.3 s, fast start, soft landing) while the new menu's links fade in from the side it came from. */
.mega-glide{position:absolute;top:0;left:0;z-index:0;width:0;height:0;opacity:0;pointer-events:none;border:1px solid var(--line);border-radius:16px;background:var(--bg);box-shadow:0 12px 30px #0002;transition:opacity .15s ease}
.mega-glide.is-on{opacity:1}
.mega-glide.is-moving{transition:opacity .15s ease,transform .3s cubic-bezier(.22,1,.36,1),width .3s cubic-bezier(.22,1,.36,1),height .3s cubic-bezier(.22,1,.36,1)}
#nav-links.has-glide>.mega>.mega-panel{z-index:1;background:transparent;border-color:transparent;box-shadow:none}
#nav-links.has-glide>.mega[open]>.mega-panel{animation:mega-in .18s ease both}
#nav-links.has-glide>.mega[open].is-switch>.mega-panel{animation:mega-switch .26s cubic-bezier(.22,1,.36,1) both}
@keyframes mega-in{from{opacity:0}}
@keyframes mega-switch{from{opacity:0;transform:translateX(var(--mega-from,0px))}}
@media(prefers-reduced-motion:reduce){.mega-glide.is-moving{transition:opacity .15s ease}#nav-links.has-glide>.mega[open]>.mega-panel{animation:none}}
@media(prefers-reduced-motion:reduce){.ip-tab-pill{transition:none!important}.vp-word,.r9-tilt-in .r9-w,.r9-rise-in,.r9-pop-in .vs-sphere{animation:none}.r9-wait .r9-w,.r9-wait-card{opacity:1}.r9-wait-pop .vs-sphere{opacity:1}}

/* 18. Voice scroll sequence (Mike, 1 Nov), as x.ai's Voice page: seven steps in one list; on desktop the sticky panel
   shows the picture for the step being read (the voices, the conversations, the interrupt tracks, dictation, your
   tools), fading in over 0.3 s as x.ai's do. On phones each picture sits under its step. Scripts: voice-page.js. */
@media(min-width:1024px){.vp-chat-stage{display:grid;grid-template-rows:minmax(0,1fr)}}
.vp-chat-stage>*{grid-area:1/1;min-width:0;min-height:0}
.vp-chat-stage>[hidden]{display:none!important}
.vp-chat-stage>:not([hidden]){animation:vp-view-in .3s cubic-bezier(0,0,.2,1)}
@keyframes vp-view-in{from{opacity:0}}
.vp-chat-stage>.vp-view{align-self:center}
.vp .vp-features .ip-feature>.vp-view{margin-top:28px}
@media(min-width:1024px){.vp .vp-features .ip-feature>.vp-view{flex:1;margin:0 0 0 40px}}
/* The panel lets go when the list ends, and the last step's text sits a step-height-dependent distance from the panel then
   (sections are 62vh, the panel min(620px,76vh)). Room after the last step keeps the panel still until that text has risen
   just above the panel's centre (24 px), at any window height (Mike: it moved before the text got there). */
@media(min-width:1024px){.vp .vp-features .ip-feature-list{padding-bottom:max(0px,calc(min(310px,38vh) - 31vh + 42px))}}
/* Interrupt: two voice tracks. You ask, Bridge's wave plays, yours cuts in, Bridge stops and answers; lines show as reached. */
.vp-cut{display:grid;gap:24px;width:100%;max-width:560px;margin-inline:auto}
.vp-cut-tracks{position:relative;display:grid;gap:18px;padding:22px 22px 30px;border-radius:20px;background:var(--surface)}
.vp-cut-track{display:grid;grid-template-columns:52px minmax(0,1fr);align-items:center;gap:12px}
.vp-cut-track>span{font-size:13px;color:var(--muted)}
.vp-cut-wave{position:relative;display:flex;align-items:center;justify-content:space-between;height:48px}
.vp-cut-wave i{flex:none;width:3px;height:calc(4px + var(--h) * 44px);border-radius:2px;background:var(--fg);opacity:clamp(.2,calc((var(--p,1) - var(--t)) * 60 + .2),1)}
.vp-cut-track+.vp-cut-track .vp-cut-wave i{background:var(--ip-accent,var(--fg))}
.vp-cut-wave i.is-quiet{opacity:.16}
.vp-cut-head{position:absolute;top:14px;bottom:14px;left:calc(86px + (100% - 108px) * var(--p,1));width:1px;background:var(--fg);opacity:.45;pointer-events:none}
.vp-cut-mark{position:absolute;top:calc(100% + 4px);left:54%;translate:-50% 0;font-style:normal;font-size:11px;line-height:14px;white-space:nowrap;color:var(--muted);opacity:clamp(0,calc((var(--p,1) - .54) * 40),1)}
.vp-cut-lines{display:flex;flex-direction:column;justify-content:flex-end;gap:10px;min-height:270px} /* room for all four lines, so the tracks never move */
@media(max-width:600px){.vp-cut-lines{min-height:320px}}
.vp-cut.is-live .vp-cut-lines .vp-msg:not(.is-on){display:none}
/* Dictation: words land in a new message while the mic listens (the cursor follows the last word), then it waits for
   your review. */
.vp-dict{display:grid;grid-template-columns:minmax(0,1fr);gap:14px;width:100%;max-width:520px;margin-inline:auto}
.vp-dict-card{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;padding:18px 20px 14px;border-radius:20px;background:var(--surface)}
.vp-dict-head{display:flex;justify-content:space-between;align-items:center;font-size:13px;color:var(--muted)}
.vp-dict-head small{font-size:12px}
.vp-dict.is-listening .vp-dict-head small{color:var(--fg)}
.vp-dict-text{margin:0;min-height:2.9em;font-size:20px;line-height:1.45;color:var(--fg)}
.vp-dict-text span{display:none}
.vp-dict-text span.is-on{display:inline;animation:vp-word-fade .5s cubic-bezier(.22,1,.36,1),vp-word-focus .275s cubic-bezier(.22,1,.36,1)}
.vp-dict.is-listening .vp-dict-text::after{content:"";display:inline-block;width:2px;height:1.1em;margin-left:3px;vertical-align:-.18em;background:var(--fg);animation:st-blink 1.1s steps(1) infinite}
.vp-dict-bar{display:flex;align-items:center;gap:12px}
.vp-dict-mic{flex:none;display:grid;place-items:center;width:36px;height:36px;border-radius:50%;background:var(--surface2);color:var(--fg);transition:background-color .2s ease,color .2s ease}
.vp-dict.is-listening .vp-dict-mic{background:var(--fg);color:var(--bg)}
.vp-dict-mic svg{width:18px;height:18px}
.vp-dict-level{flex:1;min-width:0;overflow:hidden;display:flex;align-items:center;justify-content:space-between;gap:2px;height:28px} /* the mic level runs the whole bar, mic to Send */
.vp-dict-level i{flex:none;width:3px;height:calc(3px + var(--l,0) * 25px);border-radius:2px;background:var(--muted)}
.vp-dict-send{flex:none;padding:7px 14px;border-radius:999px;font-size:13px;background:var(--surface2);color:var(--muted);transition:background-color .2s ease,color .2s ease}
.vp-dict:not(.is-listening) .vp-dict-send{background:var(--fg);color:var(--bg)}
.vp .vp-dict-note{justify-self:start;transition:opacity .3s ease}
.vp-dict.is-listening .vp-dict-note{opacity:0}
@media(prefers-reduced-motion:reduce){.vp-chat-stage>:not([hidden]),.vp-dict-text span.is-on{animation:none}.vp-dict.is-listening .vp-dict-text::after{animation:none}}

/* 19. Models & hardware motion (Mike, 2026-11-01), as Voice (section 17): on arrival the headline tilts up word by word
   and the rest of the hero rises in after it; the section headings and cards come in as they scroll on screen
   (round9-reveal.js, marked by round9-finalize.mjs). */
.r9-intro .mh .mh-hero-top h1 .r9-w{transform-origin:50% 100%;animation:r9-tilt .65s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(100ms + var(--w,0) * 55ms)}
.r9-intro .mh .mh-crumbs{--r9-y:10px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .2s backwards}
.r9-intro .mh .mh-hero-top .ip-subhead{--r9-y:14px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .48s backwards}
.r9-intro .mh .mh-hero-top .ip-lede{--r9-y:14px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .58s backwards}
.r9-intro .mh .mh-composer{--r9-y:12px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .66s backwards}
.r9-intro .mh .mh-spec{--r9-y:16px;animation:r9-rise .45s cubic-bezier(.23,1,.32,1) .8s backwards}
.r9-intro .mh .mh-hero-bottom{--r9-y:10px;animation:r9-rise .4s cubic-bezier(.22,1,.36,1) 1.15s backwards}

/* 20. The other marketing pages (Mike, 2026-11-01), as Voice and Models & hardware: on arrival the headline tilts up word
   by word and the rest of the hero rises in after it; anything marked to scroll in that is already on screen comes in
   just after the hero. Further down, headings and cards come in as they scroll on screen (round9-reveal.js). Pages are
   marked [data-r9-motion] by round9-finalize.mjs. */
.r9-intro [data-r9-motion] h1 .r9-w{transform-origin:50% 100%;animation:r9-tilt .65s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(100ms + var(--w,0) * 55ms)}
.r9-intro [data-r9-motion] :is(.ip-hero-copy>.eyebrow,.inner-hero>.eyebrow,.cp-contact-hero>.eyebrow,.bp-eyebrow){--r9-y:10px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .2s backwards}
.r9-intro [data-r9-motion] :is(.ip-hero-copy>.ip-subhead,.bp-subtitle){--r9-y:14px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .48s backwards}
.r9-intro [data-r9-motion] :is(.ip-hero-copy>.ip-lede,.inner-hero>.intro,.cp-contact-hero>.ip-lede){--r9-y:14px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .58s backwards}
.r9-intro [data-r9-motion] :is(.ip-hero-copy>.ip-actions,.ip-hero-copy>.ip-composer,.inner-hero>.actions,.bp-cta-row){--r9-y:12px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .66s backwards}
.r9-intro [data-r9-motion] :is(.ip-hero-copy>.ip-text-link,.bp-platform-note){--r9-y:10px;animation:r9-rise .38s cubic-bezier(.22,1,.36,1) .74s backwards}
.r9-intro [data-r9-motion] .ip-hero-copy+*{--r9-y:16px;animation:r9-rise .45s cubic-bezier(.23,1,.32,1) .8s backwards}
.r9-intro [data-r9-motion] .ip-hero-copy>.ip-specs{--r9-y:10px;animation:r9-rise .4s cubic-bezier(.22,1,.36,1) 1.15s backwards}
.r9-intro [data-r9-motion] [data-r9-tilt]:not(.r9-wait,.r9-tilt-in) .r9-w{transform-origin:50% 100%;animation:r9-tilt .65s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(700ms + var(--w,0) * 55ms)}
.r9-intro [data-r9-motion] [data-r9-rise]>:not(.r9-wait-card,.r9-rise-in){animation:r9-card .45s cubic-bezier(.23,1,.32,1) backwards;animation-delay:calc(750ms + var(--r9-i,0) * 60ms)}
[data-r9-rise]>:nth-child(2){--r9-i:1}[data-r9-rise]>:nth-child(3){--r9-i:2}[data-r9-rise]>:nth-child(4){--r9-i:3}[data-r9-rise]>:nth-child(5){--r9-i:4}[data-r9-rise]>:nth-child(6){--r9-i:5}[data-r9-rise]>:nth-child(n+7){--r9-i:6}
/* Bridge: the dark backing behind the headline (bridge-brand.css) fades in with its words, so no empty box shows first. */
.r9-intro [data-r9-motion] .bp-hero h1{animation:r9-scrim .6s ease .1s backwards}
@keyframes r9-scrim{from{background-color:transparent;box-shadow:0 0 22px 10px transparent}}
/* Images: the hosted-API price bars fill once their card has risen in. */
.r9-rise-in .ip-price-bar>span{transform-origin:0 50%;animation:r9-grow .8s cubic-bezier(.22,1,.36,1) backwards;animation-delay:calc(var(--r9-d,0ms) + 300ms)}

/* 21. Bridge page (Mike, 2026-11-02). Hero: a smaller logo (was up to 420 px) and no scroll arrow, so the words sit
   higher, and the space background fades into the page at the bottom instead of stopping at a hard edge. The page's
   own Bridge styles are inlined after this file, hence html in front. Phones keep their sizes. */
@media(min-width:640px){html .bridge-page .bp-hero{--bridge-logo-size:min(clamp(200px,21vw,320px),calc(100dvh - 420px))}}
.bridge-page .bp-hero-media::after{content:"";position:absolute;inset:auto 0 0;height:min(260px,30%);background:linear-gradient(to bottom,transparent,var(--bg));pointer-events:none}
/* Its Contact sales is a filled grey pill like every other secondary button (and x.ai's), not an outline. */
html .bridge-page .bp-hero .bp-cta-row .button:not(.bp-btn--primary){background:var(--button2);border-color:transparent;color:var(--fg);transition:background-color .15s ease}
html .bridge-page .bp-hero .bp-cta-row .button:not(.bp-btn--primary):hover{background:var(--button2-hover)}
/* 22. Header menus (Mike, 2026-11-02). Resources and Company are plain link lists, so on wide screens they hug their
   links as x.ai's do: 220 px, one column, no heading label, 36 px rows. Products and Solutions keep their previews. */
@media(min-width:801px){
#nav-links>.mega>.mega-panel:not(.visual-menu){width:220px;min-width:220px;grid-template-columns:1fr;gap:0;padding:8px}
#nav-links>.mega>.mega-panel:not(.visual-menu) .menu-column h2{display:none}
#nav-links>.mega>.mega-panel:not(.visual-menu) .menu-column a{min-height:36px;padding:8px 16px;border-radius:8px;font-weight:500}
}
/* Solutions shows the first lines of each field's own hero day card (scripts/round3-menus.mjs), filling a preview box
   as tall as Products' so the backing panel only slides sideways between them. The card is drawn at 86% (a transform,
   since Safari sizes zoom differently) so three lines fit. Off the solution pages the card's base look (solution-page.css) isn't loaded, so it's repeated here inside
   :where(), which keeps each field's own look from section 5 on top. */
.visual-menu--solutions .visual-menu-previews{position:relative;align-self:stretch;align-items:stretch;min-height:429px;padding:0}
.visual-menu--solutions .menu-preview{position:absolute;inset:12px;width:auto;height:auto;display:block;overflow:hidden;border-radius:8px}
.visual-menu--solutions .menu-preview[hidden]{display:none}
.visual-menu--solutions .sp-day{width:calc(100% / .86);height:calc(100% / .86);max-width:none;border-radius:calc(8px / .86);transform:scale(.86);transform-origin:0 0}
/* Off the solution pages the site-wide list width cap would reach the card's lines. */
.visual-menu--solutions .sp-day li{max-width:none}
:where(.visual-menu--solutions .sp-day){border:1px solid var(--line);background:var(--bg);overflow:hidden}
:where(.visual-menu--solutions .sp-day-top){display:flex;align-items:center;gap:8px;margin:0;padding:14px 20px;border-bottom:1px solid var(--line);font-size:13px;color:var(--muted)}
:where(.visual-menu--solutions .sp-day-top i){width:7px;height:7px;border-radius:50%;background:var(--bx-accent,#00d4ff)}
:where(.visual-menu--solutions .sp-day ol){margin:0;padding:6px 20px 12px;list-style:none;display:grid}
:where(.visual-menu--solutions .sp-day li){max-width:none;display:grid;grid-template-columns:64px minmax(0,1fr);gap:14px;padding:14px 0;border-top:1px solid var(--line);font-size:14px;line-height:1.45}
:where(.visual-menu--solutions .sp-day li:first-child){border-top:0}
:where(.visual-menu--solutions .sp-day time){color:var(--muted);font-size:12.5px;font-variant-numeric:tabular-nums;padding-top:1px}
:where(.visual-menu--solutions .sp-day li div){display:grid;gap:2px;min-width:0}
:where(.visual-menu--solutions .sp-day b){font-weight:500;font-size:13px}
:where(.visual-menu--solutions .sp-day span){color:var(--fg)}
:where(.visual-menu--solutions .sp-day em){justify-self:start;margin-top:6px;padding:3px 9px;border:1px solid var(--line);border-radius:999px;font-style:normal;font-size:12px;color:var(--muted)}
