openvibers/openvibe.shared Commits

4.29.2: sc.room() styles in room.css (#162)

OP OpenVibers committed 16 days ago · f9ef34dd10 · 9 files, +75 −120

* 4.29.2: sc.room()'s look moves from showcase.css to room.css (product homes back under their CSS budgets)

* navbar-launcher test waits for the typed list instead of 500 ms (macOS runner)

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex e523d90..a70a058 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -6,6 +6,13 @@ A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
## Unreleased
++## 4.29.2 — 2026-10-28
++
++- **`sc.room()`'s look moves to `room.css`** too: 4.28.0 had put it in `showcase.css`, which every product home loads,
++ and that is what failed 22 sites' CSS budgets (cssRawKB 39.8 > 37 on Help). `showcase.css` is back to its size
++ before the room kit; `room.css` holds the rooms' accents, cards, rails and front door. A room's pages load
++ `kit.css`, `room.css` and `showcase.css`.
++
## 4.29.1 — 2026-10-28
- **`room.css`**: the room kit's cards, rails and room accents leave `kit.css` for a stylesheet of their own.
ddiff --git a/README.md b/README.md
iindex b36744b..0583214 100644
---- a/README.md
++++ b/README.md
@@@ -2,7 +2,7 @@
> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.
--**Status:** alpha, v4.29.1 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
++**Status:** alpha, v4.29.2 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
consumer installs a tagged release and none keeps a vendored copy
([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` names
the tag it pins.
ddiff --git a/STATUS.json b/STATUS.json
iindex 1a0d9e6..0cf19e6 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -4,7 +4,7 @@
"code": true,
"wave": "W2",
"package": "openvibe-shared",
-- "version": "4.29.1",
++ "version": "4.29.2",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"deployed": false,
"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",
ddiff --git a/package.json b/package.json
iindex 9cd353a..6c13a0f 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-shared",
-- "version": "4.29.1",
++ "version": "4.29.2",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"bin": {
ddiff --git a/room.css b/room.css
iindex a7fbd08..406804d 100644
---- a/room.css
++++ b/room.css
@@@ -75,3 +75,63 @@
}
@media (prefers-reduced-motion: reduce) { .ovk-card-media > img, .ovk-card-peek, .ovk-card-video { transition: none; } .ovk-card-badge.is-live::before { animation: none; } }
html[data-ov-motion=reduced] .ovk-card-badge.is-live::before { animation: none; }
++
++/* ── sc.room(): a room's front door (moved from showcase.css in 4.29.2, so product homes that never draw a room do not
++ * load it) ── */
++/* Rooms (4.28.0): sc.room() — a room's hero, live proof, motif and scenes, in the room's accent (.ov-room in kit.css:
++ --room-accent, --room-strong, --room-fill, --room-on). */
++.sc-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
++:where(.sc-room) .ovk-i{width:1.15em;height:1.15em;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
++.sc-room-hero{position:relative;isolation:isolate;display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);gap:clamp(20px,4vw,48px);align-items:center;padding:clamp(20px,5vw,56px) 0 clamp(4px,2vw,16px)}
++.sc-room-hero h1{margin:0;font-size:clamp(2.05rem,5.4vw,3.5rem);font-weight:800;letter-spacing:-.035em;line-height:1.04;text-wrap:balance}
++.sc-room-lede{margin:14px 0 0;max-width:560px;font-size:clamp(1rem,1.6vw,1.13rem);line-height:1.55;color:var(--text-secondary,#96a7c2)}
++.sc-room-box{display:flex;align-items:center;margin-top:22px;max-width:560px;border-radius:999px;background:var(--bg-card,#0f1729);border:1.5px solid color-mix(in srgb,var(--room-accent,#3b82f6) 45%,var(--border,#1f2d47));box-shadow:0 12px 32px -14px color-mix(in srgb,var(--room-accent,#3b82f6) 55%,transparent);transition:border-color .2s,box-shadow .2s}
++.sc-room-box:focus-within{border-color:var(--room-accent,#3b82f6);box-shadow:0 0 0 4px color-mix(in srgb,var(--room-accent,#3b82f6) 22%,transparent),0 12px 32px -14px color-mix(in srgb,var(--room-accent,#3b82f6) 60%,transparent)}
++.sc-room-box input{flex:1;min-width:0;height:56px;padding:0 8px 0 22px;border:0;background:transparent;color:var(--text-primary,#e6edf7);font:inherit;font-size:1.05rem;outline:none}
++.sc-room-box input::placeholder{color:var(--text-muted,#7386a3);opacity:1}
++.sc-room-box input::-webkit-search-cancel-button{display:none}
++.sc-room-box button{flex:none;display:grid;place-items:center;width:44px;height:44px;margin-right:6px;border:0;border-radius:50%;background:var(--room-fill,#3b82f6);color:var(--room-on,#fff);cursor:pointer;font-size:20px;transition:transform .18s}
++.sc-room-box button:hover{transform:translateX(2px)}
++.sc-room-box button:focus-visible{outline:2px solid var(--room-accent,#3b82f6);outline-offset:3px}
++.sc-room-start{background:var(--room-fill,#3b82f6)!important;color:var(--room-on,#fff)!important;border-color:transparent!important}
++.sc-room-chips{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
++.sc-room-chips a{display:inline-flex;align-items:center;min-height:38px;padding:0 15px;border-radius:999px;border:1px solid var(--border,#1f2d47);background:color-mix(in srgb,var(--room-accent,#3b82f6) 7%,var(--bg-card,#0f1729));color:var(--text-primary,#e6edf7);font-size:.9rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:border-color .15s,color .15s}
++.sc-room-chips a:hover,.sc-room-chips a:focus-visible{border-color:var(--room-accent,#3b82f6);color:var(--room-strong,#60a5fa);outline:0}
++.sc-room-proof{list-style:none;display:flex;flex-wrap:wrap;gap:8px 22px;margin:22px 0 0;padding:0;font-size:.92rem;color:var(--text-secondary,#96a7c2)}
++.sc-room-proof li{display:inline-flex;align-items:baseline;gap:6px}
++.sc-room-proof b{color:var(--text-primary,#e6edf7);font-size:1.18rem;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
++.sc-room-proof em{font-style:normal;font-size:.7rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--text-muted,#7386a3)}
++.sc-room-proof .sc-room-live{display:inline-flex;align-items:center;gap:4px;color:var(--room-strong,#60a5fa)}
++.sc-room-live::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;animation:sc-breathe 2s ease-in-out infinite}
++.sc-room-pic{display:flex;justify-content:center;min-width:0}
++.sc-room-motif{position:relative;width:min(100%,340px);aspect-ratio:1;color:var(--room-accent,#3b82f6)}
++.sc-rm-glow{position:absolute;inset:20%;border-radius:50%;background:radial-gradient(closest-side,color-mix(in srgb,var(--room-accent,#3b82f6) 48%,transparent),transparent);filter:blur(10px);animation:sc-breathe 6s ease-in-out infinite}
++.sc-rm-orbit{position:absolute;border-radius:50%;border:1.5px solid color-mix(in srgb,var(--room-accent,#3b82f6) 32%,transparent);animation:sc-spin 26s linear infinite}
++.sc-rm-orbit.o1{inset:15%}
++.sc-rm-orbit.o2{inset:1%;border-style:dashed;animation-duration:52s;animation-direction:reverse;opacity:.7}
++.sc-rm-orbit i{position:absolute;top:-6px;left:calc(50% - 6px);width:12px;height:12px;border-radius:50%;background:currentColor;box-shadow:0 0 18px currentColor}
++.sc-rm-orbit.o2 i:nth-child(2){top:auto;bottom:12%;left:-5px;width:9px;height:9px;opacity:.75}
++.sc-rm-core{position:absolute;inset:33%;display:grid;place-items:center;border-radius:30%;background:color-mix(in srgb,var(--room-accent,#3b82f6) 14%,var(--bg-card,#0f1729));border:1px solid color-mix(in srgb,var(--room-accent,#3b82f6) 42%,transparent);box-shadow:0 22px 52px -18px color-mix(in srgb,var(--room-accent,#3b82f6) 75%,transparent)}
++.sc-rm-core .ovk-i{width:48%;height:48%;stroke-width:1.6}
++.sc-room .ovk-rail{margin-top:clamp(26px,4vw,40px)}
++.sc-room-scenes{display:flex;flex-direction:column;gap:clamp(32px,6vw,76px);margin-top:clamp(40px,6vw,80px)}
++.sc-scene{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(18px,4vw,52px);align-items:center}
++.sc-scene.is-flip .sc-scene-text{order:2}
++.sc-scene-text h2{margin:0 0 8px;font-size:clamp(1.3rem,2.6vw,1.8rem);letter-spacing:-.02em;line-height:1.2;text-wrap:balance}
++.sc-scene-text p{margin:0;color:var(--text-secondary,#96a7c2);line-height:1.6;max-width:460px}
++.sc-scene-go{display:inline-flex;align-items:center;gap:4px;min-height:40px;margin-top:10px;color:var(--room-strong,#60a5fa);font-weight:700;text-decoration:none}
++.sc-scene-go:hover{text-decoration:underline}
++.sc-scene-stage{position:relative;min-width:0;border-radius:20px;padding:clamp(14px,2.4vw,24px);background:radial-gradient(120% 80% at 85% 0%,color-mix(in srgb,var(--room-accent,#3b82f6) 16%,transparent),transparent 62%),var(--bg-card,#0f1729);border:1px solid var(--border,#1f2d47);box-shadow:0 30px 60px -32px rgba(0,0,0,.55);overflow:hidden}
++.sc-room-devlinks{margin:12px 0 0;font-size:.9rem;color:var(--text-muted,#7386a3)}
++.sc-room-devlinks a{color:var(--room-strong,#60a5fa);font-weight:700}
++html.ov-motion [data-ov-reveal]{opacity:0;transform:translateY(18px);transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1)}
++html.ov-motion [data-ov-reveal].is-in{opacity:1;transform:none}
++@media (max-width:759px){
++.sc-room-hero{grid-template-columns:minmax(0,1fr);margin-inline:-16px;padding-inline:16px;overflow-x:clip}
++.sc-room-pic{position:absolute;z-index:-1;top:-4px;right:-30px;width:168px;opacity:.28;pointer-events:none}
++.sc-scene,.sc-scene.is-flip{grid-template-columns:minmax(0,1fr)}.sc-scene.is-flip .sc-scene-text{order:0}
++}
++@media (max-width:599px){.sc-room-chips{flex-wrap:nowrap;overflow-x:auto;margin-inline:-16px;padding:2px 16px;scrollbar-width:none}.sc-room-chips::-webkit-scrollbar{display:none}.sc-room-box input{height:52px;padding-left:18px}}
++@media (prefers-reduced-motion:reduce){.sc-rm-glow,.sc-rm-orbit,.sc-room-live::before{animation:none}html.ov-motion [data-ov-reveal]{opacity:1;transform:none;transition:none}}
++html[data-ov-motion=reduced] .sc-rm-glow,html[data-ov-motion=reduced] .sc-rm-orbit,html[data-ov-motion=reduced] .sc-room-live::before{animation:none}
++html[data-ov-motion=reduced].ov-motion [data-ov-reveal]{opacity:1;transform:none;transition:none}
ddiff --git a/showcase.css b/showcase.css
iindex e6c2a49..2cf407a 100644
---- a/showcase.css
++++ b/showcase.css
@@@ -1,61 +1,4 @@
/* Generated by scripts/build-styles.js from showcase.js and ov-icons.js. Do not edit. */
--/* Rooms (4.28.0): sc.room() — a room's hero, live proof, motif and scenes, in the room's accent (.ov-room in kit.css:
-- --room-accent, --room-strong, --room-fill, --room-on). */
--.sc-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
--:where(.sc-room) .ovk-i{width:1.15em;height:1.15em;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
--.sc-room-hero{position:relative;isolation:isolate;display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);gap:clamp(20px,4vw,48px);align-items:center;padding:clamp(20px,5vw,56px) 0 clamp(4px,2vw,16px)}
--.sc-room-hero h1{margin:0;font-size:clamp(2.05rem,5.4vw,3.5rem);font-weight:800;letter-spacing:-.035em;line-height:1.04;text-wrap:balance}
--.sc-room-lede{margin:14px 0 0;max-width:560px;font-size:clamp(1rem,1.6vw,1.13rem);line-height:1.55;color:var(--text-secondary,#96a7c2)}
--.sc-room-box{display:flex;align-items:center;margin-top:22px;max-width:560px;border-radius:999px;background:var(--bg-card,#0f1729);border:1.5px solid color-mix(in srgb,var(--room-accent,#3b82f6) 45%,var(--border,#1f2d47));box-shadow:0 12px 32px -14px color-mix(in srgb,var(--room-accent,#3b82f6) 55%,transparent);transition:border-color .2s,box-shadow .2s}
--.sc-room-box:focus-within{border-color:var(--room-accent,#3b82f6);box-shadow:0 0 0 4px color-mix(in srgb,var(--room-accent,#3b82f6) 22%,transparent),0 12px 32px -14px color-mix(in srgb,var(--room-accent,#3b82f6) 60%,transparent)}
--.sc-room-box input{flex:1;min-width:0;height:56px;padding:0 8px 0 22px;border:0;background:transparent;color:var(--text-primary,#e6edf7);font:inherit;font-size:1.05rem;outline:none}
--.sc-room-box input::placeholder{color:var(--text-muted,#7386a3);opacity:1}
--.sc-room-box input::-webkit-search-cancel-button{display:none}
--.sc-room-box button{flex:none;display:grid;place-items:center;width:44px;height:44px;margin-right:6px;border:0;border-radius:50%;background:var(--room-fill,#3b82f6);color:var(--room-on,#fff);cursor:pointer;font-size:20px;transition:transform .18s}
--.sc-room-box button:hover{transform:translateX(2px)}
--.sc-room-box button:focus-visible{outline:2px solid var(--room-accent,#3b82f6);outline-offset:3px}
--.sc-room-start{background:var(--room-fill,#3b82f6)!important;color:var(--room-on,#fff)!important;border-color:transparent!important}
--.sc-room-chips{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
--.sc-room-chips a{display:inline-flex;align-items:center;min-height:38px;padding:0 15px;border-radius:999px;border:1px solid var(--border,#1f2d47);background:color-mix(in srgb,var(--room-accent,#3b82f6) 7%,var(--bg-card,#0f1729));color:var(--text-primary,#e6edf7);font-size:.9rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:border-color .15s,color .15s}
--.sc-room-chips a:hover,.sc-room-chips a:focus-visible{border-color:var(--room-accent,#3b82f6);color:var(--room-strong,#60a5fa);outline:0}
--.sc-room-proof{list-style:none;display:flex;flex-wrap:wrap;gap:8px 22px;margin:22px 0 0;padding:0;font-size:.92rem;color:var(--text-secondary,#96a7c2)}
--.sc-room-proof li{display:inline-flex;align-items:baseline;gap:6px}
--.sc-room-proof b{color:var(--text-primary,#e6edf7);font-size:1.18rem;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
--.sc-room-proof em{font-style:normal;font-size:.7rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--text-muted,#7386a3)}
--.sc-room-proof .sc-room-live{display:inline-flex;align-items:center;gap:4px;color:var(--room-strong,#60a5fa)}
--.sc-room-live::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;animation:sc-breathe 2s ease-in-out infinite}
--.sc-room-pic{display:flex;justify-content:center;min-width:0}
--.sc-room-motif{position:relative;width:min(100%,340px);aspect-ratio:1;color:var(--room-accent,#3b82f6)}
--.sc-rm-glow{position:absolute;inset:20%;border-radius:50%;background:radial-gradient(closest-side,color-mix(in srgb,var(--room-accent,#3b82f6) 48%,transparent),transparent);filter:blur(10px);animation:sc-breathe 6s ease-in-out infinite}
--.sc-rm-orbit{position:absolute;border-radius:50%;border:1.5px solid color-mix(in srgb,var(--room-accent,#3b82f6) 32%,transparent);animation:sc-spin 26s linear infinite}
--.sc-rm-orbit.o1{inset:15%}
--.sc-rm-orbit.o2{inset:1%;border-style:dashed;animation-duration:52s;animation-direction:reverse;opacity:.7}
--.sc-rm-orbit i{position:absolute;top:-6px;left:calc(50% - 6px);width:12px;height:12px;border-radius:50%;background:currentColor;box-shadow:0 0 18px currentColor}
--.sc-rm-orbit.o2 i:nth-child(2){top:auto;bottom:12%;left:-5px;width:9px;height:9px;opacity:.75}
--.sc-rm-core{position:absolute;inset:33%;display:grid;place-items:center;border-radius:30%;background:color-mix(in srgb,var(--room-accent,#3b82f6) 14%,var(--bg-card,#0f1729));border:1px solid color-mix(in srgb,var(--room-accent,#3b82f6) 42%,transparent);box-shadow:0 22px 52px -18px color-mix(in srgb,var(--room-accent,#3b82f6) 75%,transparent)}
--.sc-rm-core .ovk-i{width:48%;height:48%;stroke-width:1.6}
--.sc-room .ovk-rail{margin-top:clamp(26px,4vw,40px)}
--.sc-room-scenes{display:flex;flex-direction:column;gap:clamp(32px,6vw,76px);margin-top:clamp(40px,6vw,80px)}
--.sc-scene{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(18px,4vw,52px);align-items:center}
--.sc-scene.is-flip .sc-scene-text{order:2}
--.sc-scene-text h2{margin:0 0 8px;font-size:clamp(1.3rem,2.6vw,1.8rem);letter-spacing:-.02em;line-height:1.2;text-wrap:balance}
--.sc-scene-text p{margin:0;color:var(--text-secondary,#96a7c2);line-height:1.6;max-width:460px}
--.sc-scene-go{display:inline-flex;align-items:center;gap:4px;min-height:40px;margin-top:10px;color:var(--room-strong,#60a5fa);font-weight:700;text-decoration:none}
--.sc-scene-go:hover{text-decoration:underline}
--.sc-scene-stage{position:relative;min-width:0;border-radius:20px;padding:clamp(14px,2.4vw,24px);background:radial-gradient(120% 80% at 85% 0%,color-mix(in srgb,var(--room-accent,#3b82f6) 16%,transparent),transparent 62%),var(--bg-card,#0f1729);border:1px solid var(--border,#1f2d47);box-shadow:0 30px 60px -32px rgba(0,0,0,.55);overflow:hidden}
--.sc-room-devlinks{margin:12px 0 0;font-size:.9rem;color:var(--text-muted,#7386a3)}
--.sc-room-devlinks a{color:var(--room-strong,#60a5fa);font-weight:700}
--html.ov-motion [data-ov-reveal]{opacity:0;transform:translateY(18px);transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1)}
--html.ov-motion [data-ov-reveal].is-in{opacity:1;transform:none}
--@media (max-width:759px){
--.sc-room-hero{grid-template-columns:minmax(0,1fr);margin-inline:-16px;padding-inline:16px;overflow-x:clip}
--.sc-room-pic{position:absolute;z-index:-1;top:-4px;right:-30px;width:168px;opacity:.28;pointer-events:none}
--.sc-scene,.sc-scene.is-flip{grid-template-columns:minmax(0,1fr)}.sc-scene.is-flip .sc-scene-text{order:0}
--}
--@media (max-width:599px){.sc-room-chips{flex-wrap:nowrap;overflow-x:auto;margin-inline:-16px;padding:2px 16px;scrollbar-width:none}.sc-room-chips::-webkit-scrollbar{display:none}.sc-room-box input{height:52px;padding-left:18px}}
--@media (prefers-reduced-motion:reduce){.sc-rm-glow,.sc-rm-orbit,.sc-room-live::before{animation:none}html.ov-motion [data-ov-reveal]{opacity:1;transform:none;transition:none}}
--html[data-ov-motion=reduced] .sc-rm-glow,html[data-ov-motion=reduced] .sc-rm-orbit,html[data-ov-motion=reduced] .sc-room-live::before{animation:none}
--html[data-ov-motion=reduced].ov-motion [data-ov-reveal]{opacity:1;transform:none;transition:none}
/* The hero's visual (4.26.0): the aura (rings, dots, the mark) or an orbit of the site's places. */
.sc-vis{position:relative;width:min(100%,380px);aspect-ratio:1;margin:0 auto;container-type:inline-size}
.sc-aura-glow{position:absolute;inset:28%;border-radius:50%;background:radial-gradient(closest-side,color-mix(in srgb,var(--accent,#3b82f6) 42%,transparent),transparent);filter:blur(8px);animation:sc-breathe 6s ease-in-out infinite}
ddiff --git a/showcase.js b/showcase.js
iindex 88b5e58..2ed9319 100644
---- a/showcase.js
++++ b/showcase.js
@@@ -386,63 +386,6 @@ function room({ room: key, hero: h = {}, proof, rails, scenes, explore, dev, faq
}
const CSS = `
--/* Rooms (4.28.0): sc.room() — a room's hero, live proof, motif and scenes, in the room's accent (.ov-room in kit.css:
-- --room-accent, --room-strong, --room-fill, --room-on). */
--.sc-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
--:where(.sc-room) .ovk-i{width:1.15em;height:1.15em;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
--.sc-room-hero{position:relative;isolation:isolate;display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);gap:clamp(20px,4vw,48px);align-items:center;padding:clamp(20px,5vw,56px) 0 clamp(4px,2vw,16px)}
--.sc-room-hero h1{margin:0;font-size:clamp(2.05rem,5.4vw,3.5rem);font-weight:800;letter-spacing:-.035em;line-height:1.04;text-wrap:balance}
--.sc-room-lede{margin:14px 0 0;max-width:560px;font-size:clamp(1rem,1.6vw,1.13rem);line-height:1.55;color:var(--text-secondary,#96a7c2)}
--.sc-room-box{display:flex;align-items:center;margin-top:22px;max-width:560px;border-radius:999px;background:var(--bg-card,#0f1729);border:1.5px solid color-mix(in srgb,var(--room-accent,#3b82f6) 45%,var(--border,#1f2d47));box-shadow:0 12px 32px -14px color-mix(in srgb,var(--room-accent,#3b82f6) 55%,transparent);transition:border-color .2s,box-shadow .2s}
--.sc-room-box:focus-within{border-color:var(--room-accent,#3b82f6);box-shadow:0 0 0 4px color-mix(in srgb,var(--room-accent,#3b82f6) 22%,transparent),0 12px 32px -14px color-mix(in srgb,var(--room-accent,#3b82f6) 60%,transparent)}
--.sc-room-box input{flex:1;min-width:0;height:56px;padding:0 8px 0 22px;border:0;background:transparent;color:var(--text-primary,#e6edf7);font:inherit;font-size:1.05rem;outline:none}
--.sc-room-box input::placeholder{color:var(--text-muted,#7386a3);opacity:1}
--.sc-room-box input::-webkit-search-cancel-button{display:none}
--.sc-room-box button{flex:none;display:grid;place-items:center;width:44px;height:44px;margin-right:6px;border:0;border-radius:50%;background:var(--room-fill,#3b82f6);color:var(--room-on,#fff);cursor:pointer;font-size:20px;transition:transform .18s}
--.sc-room-box button:hover{transform:translateX(2px)}
--.sc-room-box button:focus-visible{outline:2px solid var(--room-accent,#3b82f6);outline-offset:3px}
--.sc-room-start{background:var(--room-fill,#3b82f6)!important;color:var(--room-on,#fff)!important;border-color:transparent!important}
--.sc-room-chips{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
--.sc-room-chips a{display:inline-flex;align-items:center;min-height:38px;padding:0 15px;border-radius:999px;border:1px solid var(--border,#1f2d47);background:color-mix(in srgb,var(--room-accent,#3b82f6) 7%,var(--bg-card,#0f1729));color:var(--text-primary,#e6edf7);font-size:.9rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:border-color .15s,color .15s}
--.sc-room-chips a:hover,.sc-room-chips a:focus-visible{border-color:var(--room-accent,#3b82f6);color:var(--room-strong,#60a5fa);outline:0}
--.sc-room-proof{list-style:none;display:flex;flex-wrap:wrap;gap:8px 22px;margin:22px 0 0;padding:0;font-size:.92rem;color:var(--text-secondary,#96a7c2)}
--.sc-room-proof li{display:inline-flex;align-items:baseline;gap:6px}
--.sc-room-proof b{color:var(--text-primary,#e6edf7);font-size:1.18rem;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
--.sc-room-proof em{font-style:normal;font-size:.7rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--text-muted,#7386a3)}
--.sc-room-proof .sc-room-live{display:inline-flex;align-items:center;gap:4px;color:var(--room-strong,#60a5fa)}
--.sc-room-live::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;animation:sc-breathe 2s ease-in-out infinite}
--.sc-room-pic{display:flex;justify-content:center;min-width:0}
--.sc-room-motif{position:relative;width:min(100%,340px);aspect-ratio:1;color:var(--room-accent,#3b82f6)}
--.sc-rm-glow{position:absolute;inset:20%;border-radius:50%;background:radial-gradient(closest-side,color-mix(in srgb,var(--room-accent,#3b82f6) 48%,transparent),transparent);filter:blur(10px);animation:sc-breathe 6s ease-in-out infinite}
--.sc-rm-orbit{position:absolute;border-radius:50%;border:1.5px solid color-mix(in srgb,var(--room-accent,#3b82f6) 32%,transparent);animation:sc-spin 26s linear infinite}
--.sc-rm-orbit.o1{inset:15%}
--.sc-rm-orbit.o2{inset:1%;border-style:dashed;animation-duration:52s;animation-direction:reverse;opacity:.7}
--.sc-rm-orbit i{position:absolute;top:-6px;left:calc(50% - 6px);width:12px;height:12px;border-radius:50%;background:currentColor;box-shadow:0 0 18px currentColor}
--.sc-rm-orbit.o2 i:nth-child(2){top:auto;bottom:12%;left:-5px;width:9px;height:9px;opacity:.75}
--.sc-rm-core{position:absolute;inset:33%;display:grid;place-items:center;border-radius:30%;background:color-mix(in srgb,var(--room-accent,#3b82f6) 14%,var(--bg-card,#0f1729));border:1px solid color-mix(in srgb,var(--room-accent,#3b82f6) 42%,transparent);box-shadow:0 22px 52px -18px color-mix(in srgb,var(--room-accent,#3b82f6) 75%,transparent)}
--.sc-rm-core .ovk-i{width:48%;height:48%;stroke-width:1.6}
--.sc-room .ovk-rail{margin-top:clamp(26px,4vw,40px)}
--.sc-room-scenes{display:flex;flex-direction:column;gap:clamp(32px,6vw,76px);margin-top:clamp(40px,6vw,80px)}
--.sc-scene{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(18px,4vw,52px);align-items:center}
--.sc-scene.is-flip .sc-scene-text{order:2}
--.sc-scene-text h2{margin:0 0 8px;font-size:clamp(1.3rem,2.6vw,1.8rem);letter-spacing:-.02em;line-height:1.2;text-wrap:balance}
--.sc-scene-text p{margin:0;color:var(--text-secondary,#96a7c2);line-height:1.6;max-width:460px}
--.sc-scene-go{display:inline-flex;align-items:center;gap:4px;min-height:40px;margin-top:10px;color:var(--room-strong,#60a5fa);font-weight:700;text-decoration:none}
--.sc-scene-go:hover{text-decoration:underline}
--.sc-scene-stage{position:relative;min-width:0;border-radius:20px;padding:clamp(14px,2.4vw,24px);background:radial-gradient(120% 80% at 85% 0%,color-mix(in srgb,var(--room-accent,#3b82f6) 16%,transparent),transparent 62%),var(--bg-card,#0f1729);border:1px solid var(--border,#1f2d47);box-shadow:0 30px 60px -32px rgba(0,0,0,.55);overflow:hidden}
--.sc-room-devlinks{margin:12px 0 0;font-size:.9rem;color:var(--text-muted,#7386a3)}
--.sc-room-devlinks a{color:var(--room-strong,#60a5fa);font-weight:700}
--html.ov-motion [data-ov-reveal]{opacity:0;transform:translateY(18px);transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1)}
--html.ov-motion [data-ov-reveal].is-in{opacity:1;transform:none}
--@media (max-width:759px){
--.sc-room-hero{grid-template-columns:minmax(0,1fr);margin-inline:-16px;padding-inline:16px;overflow-x:clip}
--.sc-room-pic{position:absolute;z-index:-1;top:-4px;right:-30px;width:168px;opacity:.28;pointer-events:none}
--.sc-scene,.sc-scene.is-flip{grid-template-columns:minmax(0,1fr)}.sc-scene.is-flip .sc-scene-text{order:0}
--}
--@media (max-width:599px){.sc-room-chips{flex-wrap:nowrap;overflow-x:auto;margin-inline:-16px;padding:2px 16px;scrollbar-width:none}.sc-room-chips::-webkit-scrollbar{display:none}.sc-room-box input{height:52px;padding-left:18px}}
--@media (prefers-reduced-motion:reduce){.sc-rm-glow,.sc-rm-orbit,.sc-room-live::before{animation:none}html.ov-motion [data-ov-reveal]{opacity:1;transform:none;transition:none}}
--html[data-ov-motion=reduced] .sc-rm-glow,html[data-ov-motion=reduced] .sc-rm-orbit,html[data-ov-motion=reduced] .sc-room-live::before{animation:none}
--html[data-ov-motion=reduced].ov-motion [data-ov-reveal]{opacity:1;transform:none;transition:none}
/* The hero's visual (4.26.0): the aura (rings, dots, the mark) or an orbit of the site's places. */
.sc-vis{position:relative;width:min(100%,380px);aspect-ratio:1;margin:0 auto;container-type:inline-size}
.sc-aura-glow{position:absolute;inset:28%;border-radius:50%;background:radial-gradient(closest-side,color-mix(in srgb,var(--accent,#3b82f6) 42%,transparent),transparent);filter:blur(8px);animation:sc-breathe 6s ease-in-out infinite}
ddiff --git a/test/navbar-launcher.test.js b/test/navbar-launcher.test.js
iindex eff6b33..ea78b77 100644
---- a/test/navbar-launcher.test.js
++++ b/test/navbar-launcher.test.js
@@@ -75,8 +75,9 @@ const server = http.createServer((req, res) => {
assert.strictEqual(r.small, 'Live things', 'taglines without a closing period');
// Typing goes to a site by its name, first.
await p.evaluate(`(() => { const q = document.querySelector('.ovs-input'); q.value = 'pic'; q.dispatchEvent(new Event('input')); return true; })()`);
-- await wait(500);
-- const f = await read();
++ // The list redraws after a short debounce: wait for it (up to 5 s; macOS runners are slower than 500 ms).
++ let f = await read();
++ for (let i = 0; i < 50 && f.heads[0] !== 'Go to'; i++) { await wait(100); f = await read(); }
assert.strictEqual(f.heads[0], 'Go to', JSON.stringify(f));
assert.strictEqual(f.rows[0], 'Pics', 'the site whose name starts so is the first answer');
console.log('navbar-launcher: all checks passed');
ddiff --git a/test/room-kit.test.js b/test/room-kit.test.js
iindex 1232427..403a1db 100644
---- a/test/room-kit.test.js
++++ b/test/room-kit.test.js
@@@ -106,7 +106,8 @@ const sc = require('../showcase');
const files = require('../files');
for (const f of ['motion.js', 'rooms.js', 'room.css']) assert.ok(files.isBrowserFile(f), `${f} is served at /shared/`);
const scss = fs.readFileSync(path.join(__dirname, '..', 'showcase.css'), 'utf8');
-- assert.ok(scss.includes('.sc-room-hero{') && scss.includes('html.ov-motion [data-ov-reveal]'), 'showcase.css is rebuilt (npm run build:styles)');
++ assert.ok(rcss.includes('.sc-room-hero{') && rcss.includes('html.ov-motion [data-ov-reveal]'), 'sc.room()\'s look is in room.css (4.29.2)');
++ assert.ok(!scss.includes('.sc-room-hero{'), 'showcase.css, which every product home loads, does not carry the room front door');
const motion = fs.readFileSync(path.join(__dirname, '..', 'motion.js'), 'utf8');
assert.ok(/el\.textContent = k < 1 \? .* : text;/.test(motion), 'the ticker ends on the server\'s text');
assert.ok(motion.includes("html.getAttribute('data-ov-motion') === 'reduced'"), 'the account\'s reduced motion is honoured');