From c4f01c1a945f742306cd864ccf58060cea880509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Thu, 27 Aug 2026 04:43:24 -0500 Subject: [PATCH 01/45] fix(specimens): restore the browser information hierarchy --- apps/specimens/src/app.tsx | 467 +++++++++++++++++++++++++++---------- 1 file changed, 340 insertions(+), 127 deletions(-) diff --git a/apps/specimens/src/app.tsx b/apps/specimens/src/app.tsx index 1b6d525..b0b40b3 100644 --- a/apps/specimens/src/app.tsx +++ b/apps/specimens/src/app.tsx @@ -34,31 +34,65 @@ import { type ReactNode, useEffect, useMemo, useRef, useState } from "react"; type Density = "default" | "compact"; type Scheme = "light" | "dark"; +type SpecimenGroup = "Composer" | "Run rail" | "Blocks"; type Specimen = { id: string; title: string; - group: "Composer" | "Run rail" | "Blocks"; + group: SpecimenGroup; primitive: string; description: string; states: string; preview: ReactNode; }; -function SpecimenCard({ specimen }: { specimen: Specimen }) { +const groupOrder: SpecimenGroup[] = ["Composer", "Run rail", "Blocks"]; + +const groupDetails: Record< + SpecimenGroup, + { id: string; description: string } +> = { + Composer: { + id: "group-composer", + description: "Intent, authority, attachments, and send readiness.", + }, + "Run rail": { + id: "group-run-rail", + description: "Execution evidence, limits, resources, and failure states.", + }, + Blocks: { + id: "group-blocks", + description: "Complete surfaces assembled from the public component API.", + }, +}; + +function SpecimenCard({ + specimen, + index, +}: { + specimen: Specimen; + index: number; +}) { + const sourceKind = specimen.group === "Blocks" ? "blocks" : "components"; + const headingId = `${specimen.id}-title`; + return ( -
-
-
- - {specimen.group} +
+
+
+ + {String(index + 1).padStart(2, "0")} {specimen.primitive}
-

{specimen.title}

-

- {specimen.description} -

+

+ {specimen.title} +

+

{specimen.description}

@@ -69,24 +103,23 @@ function SpecimenCard({ specimen }: { specimen: Specimen }) {
{specimen.preview}
- -

- pnpm dlx shadcn@latest add https://ui.opencoven.ai/r/{specimen.id} - .json -

-

+ + + {`pnpm dlx shadcn@latest add https://ui.opencoven.ai/r/${specimen.id}.json`} + +

Import from{" "} - @opencoven/ui/components/{specimen.id} + @opencoven/ui/{sourceKind}/{specimen.id} .

-

+

States: {specimen.states}.

- -

+ +

Uses semantic tokens, visible focus, non-color state cues, logical properties, and reduced-motion-safe feedback. Compact density is an explicit prop, never a global compression shortcut. @@ -422,22 +455,69 @@ function Library({ density, query }: { density: Density; query: string }) { [density, message, mode], ); + const normalizedQuery = query.trim().toLowerCase(); const filtered = specimens.filter((specimen) => `${specimen.title} ${specimen.group} ${specimen.description}` .toLowerCase() - .includes(query.toLowerCase()), + .includes(normalizedQuery), ); + if (filtered.length === 0) { + return ( +

+ +

No matching specimens

+

Try a component name, block, state, or operational concept.

+
+ ); + } + + let specimenIndex = 0; + return ( -
- {filtered.map((specimen) => ( - - ))} - {filtered.length === 0 ? ( -

- No components match “{query}”. -

- ) : null} +
+ {groupOrder.map((group) => { + const groupedSpecimens = filtered.filter( + (specimen) => specimen.group === group, + ); + + if (groupedSpecimens.length === 0) { + return null; + } + + const detail = groupDetails[group]; + + return ( +
+
+
+

{group}

+

{detail.description}

+
+ + {groupedSpecimens.length}{" "} + {groupedSpecimens.length === 1 ? "specimen" : "specimens"} + +
+
+ {groupedSpecimens.map((specimen) => { + const currentIndex = specimenIndex; + specimenIndex += 1; + + return ( + + ); + })} +
+
+ ); + })}
); } @@ -451,27 +531,64 @@ function Lab({ density }: { density: Density }) { const views: Record = { composer: ( - +
+ +

+ I found two visual regressions in the specimen shell and kept the + package boundary intact. +

+
+ +
), messages: ( - -

- Model selection, linked context, and send readiness remain visible - without interrupting the writing flow. -

-
+
+ + Reply + Copy + 1.2K tokens + + } + > +

+ Model selection, linked context, and send readiness remain visible + without interrupting the writing flow. +

+
+ +

+ The same primitives can carry a different familiar identity without + changing their authority or accessibility contract. +

+
+
), context: ( @@ -480,6 +597,10 @@ function Lab({ density }: { density: Density }) { meta="main · src/components/chat-view.tsx · read + write" /> + ), actions: ( @@ -503,7 +624,7 @@ function Lab({ density }: { density: Density }) { ), cards: ( -
+
{[ ["Pull request", "Recover attachment ingestion", "Checks 12 / 12"], ["Proposal", "Merge #4764 · squash", "Awaiting your tap"], @@ -530,20 +651,26 @@ function Lab({ density }: { density: Density }) { }; return ( -
+
+ setView(String(next))}> - - {Object.keys(views).map((name) => ( - - {name} - - ))} - +
+ + {Object.keys(views).map((name) => ( + + {name} + + ))} + +
{Object.entries(views).map(([name, content]) => ( -
- {content} -
+
{content}
))}
@@ -551,6 +678,37 @@ function Lab({ density }: { density: Density }) { ); } +function DensityControl({ + density, + onDensityChange, +}: { + density: Density; + onDensityChange: (density: Density) => void; +}) { + return ( +
+ + +
+ ); +} + function App() { const [scheme, setScheme] = useState(() => localStorage.getItem("coven-ui:scheme") === "light" ? "light" : "dark", @@ -562,7 +720,8 @@ function App() { ); const [query, setQuery] = useState(""); const searchRef = useRef(null); - const isLab = window.location.pathname === "/lab"; + const normalizedPath = window.location.pathname.replace(/\/+$/, "") || "/"; + const isLab = normalizedPath === "/lab"; useEffect(() => { document.documentElement.classList.toggle("dark", scheme === "dark"); @@ -578,74 +737,36 @@ function App() { searchRef.current?.focus(); } }; + window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, []); return ( -
- -
-
-
-

- {isLab ? "Five assembled states" : "Registry-backed components"} -

-

- {isLab - ? "The agent surface, assembled" - : "Quiet tools for active runs"} -

-

- Greys carry structure. Color carries operational meaning. Every - preview imports the same modules consumers install. -

-
+
{!isLab ? ( setQuery(event.target.value)} placeholder="Search components…" shortcut="⌘K" - className="w-full sm:w-64" + className="specimen-search" /> ) : null} -
- {isLab ? ( - - ) : ( - - )} + + +
+
+
+
+ +
+
+
+
+

+ {isLab + ? "Five assembled states" + : "Registry-backed components"} +

+

+ {isLab + ? "The agent surface, assembled." + : "Quiet tools for active runs."} +

+

+ Greys carry structure. Color carries operational meaning. + Every preview imports the same public modules consumers + install. +

+
+
+
+
{isLab ? "Views" : "Specimens"}
+
{isLab ? "05" : "16"}
+
+
+
Schemes
+
02
+
+
+
Densities
+
02
+
+
+
+ {isLab ? ( + + ) : ( + + )} +
From 5b898390b43e6368f3f026bc1d3fc341ead854e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Thu, 27 Aug 2026 04:44:37 -0500 Subject: [PATCH 02/45] style(specimens): recover the responsive visual shell --- apps/specimens/src/specimens.css | 739 +++++++++++++++++++++++++++++-- 1 file changed, 714 insertions(+), 25 deletions(-) diff --git a/apps/specimens/src/specimens.css b/apps/specimens/src/specimens.css index 1ef9e47..7ffe5c0 100644 --- a/apps/specimens/src/specimens.css +++ b/apps/specimens/src/specimens.css @@ -1,57 +1,483 @@ html { min-width: 20rem; + scroll-padding-top: 7rem; } body { min-height: 100vh; + overflow-x: clip; +} + +.skip-link { + position: fixed; + inset-block-start: 0.75rem; + inset-inline-start: 0.75rem; + z-index: 100; + translate: 0 -200%; + border-radius: var(--radius-2); + background: var(--foreground); + color: var(--background); + padding: 0.625rem 0.875rem; + font-size: 0.8125rem; + font-weight: 700; +} + +.skip-link:focus { + translate: 0; +} + +.specimen-topbar { + position: sticky; + inset-block-start: 0; + z-index: 50; + border-block-end: 1px solid var(--border); + background: color-mix(in srgb, var(--background) 92%, transparent); + backdrop-filter: blur(18px); +} + +.specimen-topbar__inner { + display: grid; + min-height: 4.25rem; + max-width: 96rem; + grid-template-columns: auto auto minmax(0, 1fr); + align-items: center; + gap: 1rem; + margin-inline: auto; + padding-inline: clamp(1rem, 3vw, 2rem); +} + +.specimen-brand { + display: inline-flex; + align-items: center; + gap: 0.75rem; + min-width: max-content; + color: var(--foreground); + text-decoration: none; +} + +.specimen-brand__mark { + display: grid; + width: 2.25rem; + height: 2.25rem; + flex: none; + place-items: center; + border: 1px solid color-mix(in srgb, var(--presence) 42%, var(--border)); + border-radius: var(--radius-2); + background: color-mix(in srgb, var(--presence) 12%, var(--card)); + color: var(--presence); +} + +.specimen-brand__mark svg { + width: 1rem; + height: 1rem; +} + +.specimen-brand > span:last-child { + display: grid; + font-size: 0.875rem; + font-weight: 750; + letter-spacing: -0.015em; + line-height: 1.1; +} + +.specimen-brand small { + margin-block-start: 0.2rem; + color: var(--muted-foreground); + font-family: var(--font-numeric); + font-size: 0.625rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.surface-switcher, +.density-control { + display: inline-flex; + align-items: center; + gap: 0.125rem; + padding: 0.1875rem; + border: 1px solid var(--border); + border-radius: var(--radius-2); + background: var(--card); +} + +.surface-switcher a, +.density-control button { + border: 0; + border-radius: calc(var(--radius-2) - 2px); + background: transparent; + color: var(--muted-foreground); + padding: 0.375rem 0.75rem; + font-size: 0.75rem; + font-weight: 700; + line-height: 1.25rem; + text-decoration: none; + white-space: nowrap; +} + +.surface-switcher a:hover, +.density-control button:hover { + background: var(--muted); + color: var(--foreground); +} + +.surface-switcher a[aria-current="page"], +.density-control button[aria-pressed="true"] { + background: var(--foreground); + color: var(--background); + box-shadow: var(--elevation-1); +} + +.specimen-topbar__actions { + display: flex; + min-width: 0; + align-items: center; + justify-content: flex-end; + gap: 0.5rem; +} + +.specimen-search { + width: min(20rem, 34vw); +} + +.scheme-control { + flex: none; + white-space: nowrap; +} + +.scheme-control svg { + width: 0.875rem; + height: 0.875rem; } .specimen-shell { display: grid; - min-height: 100vh; - grid-template-columns: 16rem minmax(0, 1fr); + max-width: 96rem; + min-height: calc(100vh - 4.25rem); + grid-template-columns: 15rem minmax(0, 1fr); + margin-inline: auto; } .specimen-rail { position: sticky; - inset-block-start: 0; - height: 100vh; + inset-block-start: 4.25rem; + align-self: start; + height: calc(100vh - 4.25rem); overflow-y: auto; border-inline-end: 1px solid var(--border); - background: color-mix(in srgb, var(--card) 88%, var(--background)); + background: color-mix(in srgb, var(--card) 72%, var(--background)); + padding: 2rem 1.25rem; + scrollbar-width: thin; +} + +.specimen-rail__context { + padding-inline: 0.625rem; +} + +.specimen-rail__context h2 { + margin: 0.4rem 0 0; + font-size: 1rem; + font-weight: 750; + letter-spacing: -0.015em; +} + +.specimen-rail__context p:last-child { + margin: 0.625rem 0 0; + color: var(--muted-foreground); + font-size: 0.75rem; + line-height: 1.55; +} + +.specimen-kicker { + margin: 0; + color: var(--presence); + font-size: 0.625rem; + font-weight: 750; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.specimen-rail__nav { + display: grid; + gap: 0.25rem; + margin-block-start: 1.75rem; +} + +.specimen-rail__nav a { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + border-radius: var(--radius-2); + color: var(--muted-foreground); + padding: 0.625rem 0.75rem; + font-size: 0.8125rem; + font-weight: 650; + text-decoration: none; +} + +.specimen-rail__nav a:hover { + background: var(--muted); + color: var(--foreground); +} + +.specimen-rail__nav small { + color: color-mix(in srgb, var(--muted-foreground) 76%, transparent); + font-size: 0.625rem; +} + +.specimen-rail__package { + margin-block-start: 2rem; + border-block-start: 1px solid var(--border); + padding: 1.25rem 0.625rem 0; +} + +.specimen-rail__package code { + display: block; + overflow: hidden; + margin-block-start: 0.5rem; + color: var(--foreground); + font-size: 0.75rem; + text-overflow: ellipsis; + white-space: nowrap; +} + +.specimen-rail__package p { + margin: 0.625rem 0 0; + color: var(--muted-foreground); + font-size: 0.7rem; + line-height: 1.5; } .specimen-main { min-width: 0; } +.specimen-main__inner { + width: min(100%, 78rem); + margin-inline: auto; + padding: clamp(2rem, 5vw, 4.5rem) clamp(1rem, 4vw, 3.5rem) 7rem; +} + +.specimen-hero { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: end; + gap: 2rem; + margin-block-end: clamp(3rem, 6vw, 5rem); + border-block-end: 1px solid var(--border); + padding-block-end: clamp(2rem, 4vw, 3rem); +} + +.specimen-hero__copy { + max-width: 47rem; +} + +.specimen-hero h1 { + max-width: 14ch; + margin: 0.65rem 0 0; + font-family: var(--font-editorial); + font-size: clamp(2.75rem, 6vw, 5.25rem); + font-weight: 500; + letter-spacing: -0.045em; + line-height: 0.98; + text-wrap: balance; +} + +.specimen-hero__copy > p:last-child { + max-width: 60ch; + margin: 1.25rem 0 0; + color: var(--muted-foreground); + font-size: 0.9375rem; + line-height: 1.7; +} + +.specimen-stats { + display: grid; + grid-template-columns: repeat(3, minmax(4.5rem, 1fr)); + gap: 0.5rem; + margin: 0; +} + +.specimen-stats div { + min-width: 5rem; + border-inline-start: 1px solid var(--border); + padding-inline-start: 0.875rem; +} + +.specimen-stats dt { + color: var(--muted-foreground); + font-size: 0.625rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.specimen-stats dd { + margin: 0.25rem 0 0; + color: var(--foreground); + font-size: 1.25rem; + font-weight: 650; +} + +.catalog { + display: grid; + gap: clamp(4rem, 8vw, 7rem); +} + +.catalog-group { + scroll-margin-block-start: 7rem; +} + +.catalog-group__header { + display: flex; + align-items: end; + justify-content: space-between; + gap: 2rem; + margin-block-end: 1.25rem; +} + +.catalog-group__eyebrow { + margin: 0; + color: var(--presence); + font-size: 0.625rem; + font-weight: 750; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.catalog-group__header h2 { + max-width: 34rem; + margin: 0.45rem 0 0; + font-size: clamp(1.25rem, 2.5vw, 1.75rem); + font-weight: 700; + letter-spacing: -0.025em; + line-height: 1.2; + text-wrap: balance; +} + +.catalog-group__count { + flex: none; + color: var(--muted-foreground); + font-size: 0.6875rem; + letter-spacing: 0.04em; + text-transform: uppercase; +} + .specimen-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); + grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; } .specimen-card { min-width: 0; overflow: hidden; + scroll-margin-block-start: 7rem; border: 1px solid var(--border); border-radius: var(--radius-3); background: var(--card); box-shadow: var(--elevation-1); + transition: + border-color var(--motion-standard) var(--motion-ease), + box-shadow var(--motion-standard) var(--motion-ease), + translate var(--motion-standard) var(--motion-ease); +} + +.specimen-card:hover, +.specimen-card:focus-within { + border-color: color-mix(in srgb, var(--presence) 34%, var(--border)); + box-shadow: var(--elevation-2); + translate: 0 -1px; +} + +.specimen-card__header { + min-height: 9.75rem; + border-block-end: 1px solid var(--border); + padding: 1.125rem 1.25rem 1.25rem; +} + +.specimen-card__meta { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; +} + +.specimen-card__index { + color: var(--muted-foreground); + font-size: 0.625rem; + font-weight: 700; + letter-spacing: 0.12em; +} + +.specimen-card__title { + margin: 1rem 0 0; + font-size: 1.0625rem; + font-weight: 750; + letter-spacing: -0.015em; +} + +.specimen-card__description { + max-width: 46ch; + margin: 0.45rem 0 0; + color: var(--muted-foreground); + font-size: 0.8125rem; + line-height: 1.55; } .specimen-stage { - min-height: 15rem; display: grid; + min-height: 17rem; align-content: center; + justify-items: center; + border-block-start: 1px solid + color-mix(in srgb, var(--border) 62%, transparent); + background: color-mix(in srgb, var(--muted) 48%, var(--background)); padding: clamp(1rem, 3vw, 2rem); - background: - radial-gradient( - circle at 82% 18%, - color-mix(in srgb, var(--presence) 10%, transparent), - transparent 14rem - ), - var(--background); +} + +.specimen-stage > * { + max-width: 100%; +} + +.specimen-stage > [data-slot="composer"], +.specimen-stage > [data-slot="session-header"] { + width: 100%; +} + +.specimen-stage > [data-slot="run-rail"] { + width: min(100%, 28rem); +} + +.specimen-stage > [data-slot="transcript-turn"] { + width: min(100%, 42rem); +} + +.specimen-documentation { + display: grid; + min-height: 17rem; + align-content: start; + gap: 0.875rem; + padding: 1.25rem; + font-size: 0.8125rem; + line-height: 1.6; +} + +.specimen-documentation p { + margin: 0; +} + +.specimen-command { + display: block; + overflow-wrap: anywhere; + border: 1px solid var(--border); + border-radius: var(--radius-2); + background: var(--muted); + color: var(--foreground); + padding: 0.75rem; + font-size: 0.7rem; + line-height: 1.6; } .run-spine { @@ -60,40 +486,303 @@ body { .run-spine::before { position: absolute; - inset-block: 0; + inset-block: 0.5rem; inset-inline-start: 1.1rem; width: 1px; - background: linear-gradient( - to bottom, - transparent, - var(--presence) 18%, - var(--border) 72%, - transparent - ); + background: color-mix(in srgb, var(--presence) 38%, var(--border)); content: ""; } -@media (max-width: 56rem) { +.catalog-empty { + display: grid; + min-height: 24rem; + place-items: center; + align-content: center; + border: 1px dashed var(--border); + border-radius: var(--radius-3); + padding: 2rem; + text-align: center; +} + +.catalog-empty__mark { + display: grid; + width: 2.75rem; + height: 2.75rem; + place-items: center; + border: 1px solid var(--border); + border-radius: var(--radius-2); + color: var(--presence); +} + +.catalog-empty__mark svg { + width: 1rem; + height: 1rem; +} + +.catalog-empty h2 { + margin: 1rem 0 0; + font-size: 1.125rem; +} + +.catalog-empty p { + margin: 0.4rem 0 0; + color: var(--muted-foreground); + font-size: 0.8125rem; +} + +.assembled-lab { + overflow: hidden; + scroll-margin-block-start: 7rem; + border: 1px solid var(--border); + border-radius: var(--radius-3); + background: var(--card); + box-shadow: var(--elevation-2); +} + +.assembled-lab__nav { + overflow-x: auto; + border-block-end: 1px solid var(--border); + padding: 0.75rem 1rem 0; +} + +.assembled-lab__tabs { + width: max-content; + min-width: 100%; +} + +.assembled-lab__stage { + display: grid; + min-height: 34rem; + align-content: center; + background: color-mix(in srgb, var(--muted) 42%, var(--background)); + padding: clamp(1rem, 4vw, 3rem); +} + +.lab-composer, +.lab-message-stack { + display: grid; + width: min(100%, 48rem); + gap: 2rem; + margin-inline: auto; +} + +.lab-card-grid { + display: grid; + width: min(100%, 52rem); + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.875rem; + margin-inline: auto; +} + +.assembled-lab__stage > [data-slot="card"] { + width: min(100%, 48rem); + margin-inline: auto; +} + +@media (max-width: 68rem) { + html { + scroll-padding-top: 10rem; + } + + .specimen-topbar__inner { + grid-template-columns: auto 1fr; + padding-block: 0.75rem; + } + + .surface-switcher { + justify-self: end; + } + + .specimen-topbar__actions { + display: grid; + width: 100%; + grid-column: 1 / -1; + grid-template-columns: minmax(0, 1fr) auto auto; + } + + .specimen-search { + width: 100%; + } + .specimen-shell { + min-height: 0; grid-template-columns: 1fr; } .specimen-rail { position: static; + display: block; height: auto; + overflow-x: auto; border-inline-end: 0; border-block-end: 1px solid var(--border); + padding: 0.75rem clamp(1rem, 4vw, 2rem); + } + + .specimen-rail__context, + .specimen-rail__package { + display: none; + } + + .specimen-rail__nav { + display: flex; + width: max-content; + min-width: 100%; + gap: 0.375rem; + margin: 0; + } + + .specimen-rail__nav a { + min-width: 9rem; + flex: 1 0 auto; + border: 1px solid transparent; + background: color-mix(in srgb, var(--card) 72%, var(--background)); + } + + .specimen-main__inner { + padding-block-start: clamp(2rem, 5vw, 3.5rem); + } +} + +@media (max-width: 48rem) { + .specimen-hero { + grid-template-columns: 1fr; + align-items: start; + } + + .specimen-stats { + width: 100%; + } + + .catalog-group__header { + align-items: start; + } + + .specimen-grid { + grid-template-columns: 1fr; + } + + .specimen-card__header { + min-height: 0; + } +} + +@media (max-width: 36rem) { + html { + scroll-padding-top: 12rem; + } + + .specimen-topbar__inner { + gap: 0.75rem; + } + + .specimen-brand small { + display: none; + } + + .specimen-topbar__actions { + grid-template-columns: minmax(0, 1fr) auto; + } + + .specimen-search { + grid-column: 1 / -1; + } + + .scheme-control span { + display: none; + } + + .specimen-main__inner { + padding-inline: 1rem; + } + + .specimen-hero { + margin-block-end: 3rem; + } + + .specimen-hero h1 { + font-size: clamp(2.5rem, 14vw, 3.75rem); + } + + .catalog { + gap: 4rem; + } + + .catalog-group__header { + display: grid; + gap: 0.75rem; + } + + .catalog-group__count { + justify-self: start; + } + + .specimen-stage, + .assembled-lab__stage { + padding: 1rem; + } + + .assembled-lab__stage { + min-height: 30rem; + } + + .lab-card-grid { + grid-template-columns: 1fr; } } @media (max-width: 24.375rem) { + .specimen-brand__mark { + width: 2rem; + height: 2rem; + } + + .surface-switcher a, + .density-control button { + padding-inline: 0.55rem; + } + + .specimen-topbar__actions { + gap: 0.375rem; + } + + .specimen-hero h1 { + font-size: 2.5rem; + } + + .specimen-stats div { + min-width: 0; + padding-inline-start: 0.625rem; + } + + .specimen-stats dt { + font-size: 0.55rem; + } + .specimen-stage { + min-height: 14rem; + padding: 0.875rem; + } + + .specimen-documentation { + min-height: 14rem; padding: 1rem; } } @media (prefers-reduced-motion: reduce) { - .specimen-stage { - scroll-behavior: auto; + .skip-link { + transition: none; + } + + .specimen-card { + translate: none; + } +} + +@media (forced-colors: active) { + .surface-switcher a[aria-current="page"], + .density-control button[aria-pressed="true"] { + border: 1px solid Highlight; } } From 8023647efb51f90c3daf889727f56b488177ad4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Thu, 27 Aug 2026 04:45:01 -0500 Subject: [PATCH 03/45] test(specimens): lock the recovered shell contracts --- scripts/verify-contracts.mjs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index 4b19463..f4b3822 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -9,6 +9,7 @@ const [ packageJson, tokens, specimenCss, + specimenApp, button, tooltip, menu, @@ -17,6 +18,7 @@ const [ read("packages/ui/package.json"), read("packages/ui/src/styles/globals.css"), read("apps/specimens/src/specimens.css"), + read("apps/specimens/src/app.tsx"), read("packages/ui/src/components/ui/button.tsx"), read("packages/ui/src/components/ui/tooltip.tsx"), read("packages/ui/src/components/ui/dropdown-menu.tsx"), @@ -81,10 +83,37 @@ const assertions = [ source.includes("Primitive.Positioner"), ), ], + [ + "specimen shell has stable landmarks", + specimenApp.includes('className="specimen-topbar"') && + specimenApp.includes('className="specimen-rail"') && + specimenApp.includes('id="specimen-main"') && + specimenApp.includes('className="skip-link"'), + ], + [ + "catalog restores task hierarchy", + ["group-composer", "group-run-rail", "group-blocks"].every((id) => + specimenApp.includes(id), + ), + ], + [ + "density control is explicit", + specimenApp.includes('aria-label="Display density"') && + !specimenApp.includes("nth-child(2)"), + ], [ "mobile layout covers 390px", specimenCss.includes("@media (max-width: 24.375rem)"), ], + [ + "responsive rail becomes compact navigation", + specimenCss.includes("@media (max-width: 68rem)") && + specimenCss.includes(".specimen-rail__context,\n .specimen-rail__package"), + ], + [ + "specimen chrome avoids decorative gradients", + !specimenCss.includes("gradient("), + ], [ "filled action variants are explicit", button.includes("primary:") && button.includes("presence:"), From 3ca46d2b053468f28911ba02cb614abebfa38fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Thu, 27 Aug 2026 04:52:03 -0500 Subject: [PATCH 04/45] chore(ci): generate a one-shot formatter receipt --- .github/workflows/format-receipt.yml | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/format-receipt.yml diff --git a/.github/workflows/format-receipt.yml b/.github/workflows/format-receipt.yml new file mode 100644 index 0000000..53b24c1 --- /dev/null +++ b/.github/workflows/format-receipt.yml @@ -0,0 +1,35 @@ +name: Format receipt + +on: + push: + branches: + - fix/specimen-browser-shell + +permissions: + contents: read + +jobs: + format: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10.17.1 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm exec prettier --write apps/specimens/src/app.tsx scripts/verify-contracts.mjs + - run: | + mkdir -p artifacts/formatted/apps/specimens/src artifacts/formatted/scripts + cp apps/specimens/src/app.tsx artifacts/formatted/apps/specimens/src/app.tsx + cp scripts/verify-contracts.mjs artifacts/formatted/scripts/verify-contracts.mjs + - uses: actions/upload-artifact@v4 + with: + name: formatted-source + path: artifacts/formatted + if-no-files-found: error + retention-days: 1 From d77d735ab631846e5800cb14c4be39e453b17447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Thu, 27 Aug 2026 04:53:30 -0500 Subject: [PATCH 05/45] chore(ci): apply the pinned formatter output --- .github/workflows/format-receipt.yml | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/format-receipt.yml b/.github/workflows/format-receipt.yml index 53b24c1..18836c7 100644 --- a/.github/workflows/format-receipt.yml +++ b/.github/workflows/format-receipt.yml @@ -6,7 +6,7 @@ on: - fix/specimen-browser-shell permissions: - contents: read + contents: write jobs: format: @@ -23,13 +23,15 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm exec prettier --write apps/specimens/src/app.tsx scripts/verify-contracts.mjs - - run: | - mkdir -p artifacts/formatted/apps/specimens/src artifacts/formatted/scripts - cp apps/specimens/src/app.tsx artifacts/formatted/apps/specimens/src/app.tsx - cp scripts/verify-contracts.mjs artifacts/formatted/scripts/verify-contracts.mjs - - uses: actions/upload-artifact@v4 - with: - name: formatted-source - path: artifacts/formatted - if-no-files-found: error - retention-days: 1 + - name: Commit canonical formatting + if: github.actor != 'github-actions[bot]' + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add apps/specimens/src/app.tsx scripts/verify-contracts.mjs + if git diff --cached --quiet; then + echo "Source is already formatted." + exit 0 + fi + git commit -m "style(specimens): apply canonical formatting" + git push origin HEAD:fix/specimen-browser-shell From 498b25dbb155c7a9bdb5dcbbbf01575d89bf4640 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 27 Aug 2026 09:53:48 +0000 Subject: [PATCH 06/45] style(specimens): apply canonical formatting --- apps/specimens/src/app.tsx | 50 +++++++++++++++--------------------- scripts/verify-contracts.mjs | 4 ++- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/apps/specimens/src/app.tsx b/apps/specimens/src/app.tsx index b0b40b3..cc67f22 100644 --- a/apps/specimens/src/app.tsx +++ b/apps/specimens/src/app.tsx @@ -48,23 +48,21 @@ type Specimen = { const groupOrder: SpecimenGroup[] = ["Composer", "Run rail", "Blocks"]; -const groupDetails: Record< - SpecimenGroup, - { id: string; description: string } -> = { - Composer: { - id: "group-composer", - description: "Intent, authority, attachments, and send readiness.", - }, - "Run rail": { - id: "group-run-rail", - description: "Execution evidence, limits, resources, and failure states.", - }, - Blocks: { - id: "group-blocks", - description: "Complete surfaces assembled from the public component API.", - }, -}; +const groupDetails: Record = + { + Composer: { + id: "group-composer", + description: "Intent, authority, attachments, and send readiness.", + }, + "Run rail": { + id: "group-run-rail", + description: "Execution evidence, limits, resources, and failure states.", + }, + Blocks: { + id: "group-blocks", + description: "Complete surfaces assembled from the public component API.", + }, + }; function SpecimenCard({ specimen, @@ -114,9 +112,7 @@ function SpecimenCard({ .

-

- States: {specimen.states}. -

+

States: {specimen.states}.

@@ -686,11 +682,7 @@ function DensityControl({ onDensityChange: (density: Density) => void; }) { return ( -

+
\n );\n}\n\nexport { TranscriptTurn, type TranscriptTurnProps };\n", "type": "registry:block", "target": "@components/blocks/transcript-turn.tsx" } From a4d43be38e36f4e3a644b2bb98b4eb48848d3729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Thu, 27 Aug 2026 05:15:53 -0500 Subject: [PATCH 13/45] chore(ci): remove the responsive registry sync --- .../workflows/sync-responsive-registry.yml | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/sync-responsive-registry.yml diff --git a/.github/workflows/sync-responsive-registry.yml b/.github/workflows/sync-responsive-registry.yml deleted file mode 100644 index d1f6ba4..0000000 --- a/.github/workflows/sync-responsive-registry.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Sync responsive registry - -on: - push: - branches: - - fix/specimen-browser-shell - -permissions: - contents: write - -jobs: - sync: - if: github.actor != 'github-actions[bot]' - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 - with: - version: 10.17.1 - - uses: actions/setup-node@v4 - with: - node-version: 24 - cache: pnpm - - run: pnpm install --frozen-lockfile - - run: pnpm registry:build - - name: Commit affected registry artifacts - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add public/r/session-header.json public/r/transcript-turn.json - git commit -m "chore(registry): sync responsive block payloads" - git push origin HEAD:fix/specimen-browser-shell From 737244f879462c001646059731beccefccba1d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:17:13 -0500 Subject: [PATCH 14/45] fix(specimens): close responsive and reduced-motion regressions --- apps/specimens/src/specimens-fixes.css | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 apps/specimens/src/specimens-fixes.css diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css new file mode 100644 index 0000000..7623b03 --- /dev/null +++ b/apps/specimens/src/specimens-fixes.css @@ -0,0 +1,37 @@ +/* Focused regression guards layered after the specimen shell styles. */ + +body:not(:has(#group-composer)) + .specimen-rail + a[href="#group-composer"], +body:not(:has(#group-run-rail)) + .specimen-rail + a[href="#group-run-rail"], +body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { + display: none; +} + +@media (max-width: 24.375rem) { + .assembled-lab__nav { + overflow-x: hidden; + } + + .assembled-lab__tabs { + display: grid; + width: 100%; + min-width: 0; + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .assembled-lab__tabs [role="tab"] { + min-width: 0; + padding-inline: 0.35rem; + font-size: 0.625rem; + } +} + +@media (prefers-reduced-motion: reduce) { + .specimen-card:hover, + .specimen-card:focus-within { + translate: none; + } +} From 44549af448d9fa094fcf014de8cbb4916fd0f490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:17:20 -0500 Subject: [PATCH 15/45] fix(specimens): preserve browser shortcuts outside library --- apps/specimens/src/main.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/specimens/src/main.tsx b/apps/specimens/src/main.tsx index 15f8d77..ba2fdcb 100644 --- a/apps/specimens/src/main.tsx +++ b/apps/specimens/src/main.tsx @@ -3,8 +3,23 @@ import { createRoot } from "react-dom/client"; import "@opencoven/ui/globals.css"; import "./specimens.css"; +import "./specimens-fixes.css"; import { App } from "./app"; +const normalizedPath = window.location.pathname.replace(/\/+$/, "") || "/"; + +if (normalizedPath !== "/") { + window.addEventListener( + "keydown", + (event) => { + if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") { + event.stopImmediatePropagation(); + } + }, + { capture: true }, + ); +} + const root = document.getElementById("root"); if (!root) { From 26d3d3d8a2ab865314928e5fd9ff701f27f5c899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:17:36 -0500 Subject: [PATCH 16/45] test(contracts): make responsive assertion line-ending safe --- scripts/verify-contracts.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index 9c305b5..450a87a 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -108,8 +108,8 @@ const assertions = [ [ "responsive rail becomes compact navigation", specimenCss.includes("@media (max-width: 68rem)") && - specimenCss.includes( - ".specimen-rail__context,\n .specimen-rail__package", + /\.specimen-rail__context,\r?\n\s+\.specimen-rail__package/.test( + specimenCss, ), ], [ From a2562715f4ed467128d901b66f4fc5fd51d69be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:20:24 -0500 Subject: [PATCH 17/45] style(specimens): format regression guards --- apps/specimens/src/specimens-fixes.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index 7623b03..e44c473 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -1,11 +1,7 @@ /* Focused regression guards layered after the specimen shell styles. */ -body:not(:has(#group-composer)) - .specimen-rail - a[href="#group-composer"], -body:not(:has(#group-run-rail)) - .specimen-rail - a[href="#group-run-rail"], +body:not(:has(#group-composer)) .specimen-rail a[href="#group-composer"], +body:not(:has(#group-run-rail)) .specimen-rail a[href="#group-run-rail"], body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { display: none; } From 1858bc9f01441136316433ae0d6b95dcac6743b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:23:37 -0500 Subject: [PATCH 18/45] fix(specimens): constrain assembled tabs at mobile width --- apps/specimens/src/specimens-fixes.css | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index e44c473..169ab9a 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -7,21 +7,32 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { } @media (max-width: 24.375rem) { + .assembled-lab > [data-slot="tabs"] { + width: 100%; + min-width: 0; + max-width: 100%; + } + .assembled-lab__nav { + width: 100%; + min-width: 0; + max-width: 100%; overflow-x: hidden; } .assembled-lab__tabs { display: grid; - width: 100%; + width: 100% !important; min-width: 0; + max-width: 100%; grid-template-columns: repeat(5, minmax(0, 1fr)); } .assembled-lab__tabs [role="tab"] { min-width: 0; - padding-inline: 0.35rem; + padding-inline: 0.25rem; font-size: 0.625rem; + white-space: normal; } } From 56bf53fbb04aa35a78be1bea1ff4b972e93bdb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:27:39 -0500 Subject: [PATCH 19/45] fix(specimens): constrain assembled tab panels on mobile --- apps/specimens/src/specimens-fixes.css | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index 169ab9a..f262bc3 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -7,16 +7,21 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { } @media (max-width: 24.375rem) { - .assembled-lab > [data-slot="tabs"] { + .assembled-lab > [data-slot="tabs"], + .assembled-lab [data-slot="tabs-content"], + .assembled-lab__nav, + .assembled-lab__stage { width: 100%; min-width: 0; max-width: 100%; } + .assembled-lab [data-slot="tabs-content"], + .assembled-lab__stage { + overflow-x: hidden; + } + .assembled-lab__nav { - width: 100%; - min-width: 0; - max-width: 100%; overflow-x: hidden; } @@ -34,6 +39,11 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { font-size: 0.625rem; white-space: normal; } + + .assembled-lab__stage > * { + min-width: 0; + max-width: 100%; + } } @media (prefers-reduced-motion: reduce) { From 4987d9dc2ae004b496df0bc77c433823ab39e1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:30:05 -0500 Subject: [PATCH 20/45] fix(specimens): make mobile assembled sizing border-box --- apps/specimens/src/specimens-fixes.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index f262bc3..28376e3 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -11,6 +11,7 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { .assembled-lab [data-slot="tabs-content"], .assembled-lab__nav, .assembled-lab__stage { + box-sizing: border-box; width: 100%; min-width: 0; max-width: 100%; @@ -27,6 +28,7 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { .assembled-lab__tabs { display: grid; + box-sizing: border-box; width: 100% !important; min-width: 0; max-width: 100%; From 7440c10d213935540fe44b6a7d4a117bbe1b10e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:36:52 -0500 Subject: [PATCH 21/45] fix(tabs): honor Base UI orientation contract --- packages/ui/src/components/ui/tabs.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/ui/tabs.tsx b/packages/ui/src/components/ui/tabs.tsx index c4ec275..0cd59e5 100644 --- a/packages/ui/src/components/ui/tabs.tsx +++ b/packages/ui/src/components/ui/tabs.tsx @@ -14,8 +14,10 @@ function Tabs({ ); From 8b7a63a02b493cba272b524bd1c454889caead8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:37:24 -0500 Subject: [PATCH 22/45] fix(registry): publish corrected tabs orientation --- public/r/tabs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/r/tabs.json b/public/r/tabs.json index 9acc68c..cf9404c 100644 --- a/public/r/tabs.json +++ b/public/r/tabs.json @@ -14,7 +14,7 @@ "files": [ { "path": "packages/ui/src/components/ui/tabs.tsx", - "content": "\"use client\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n \n );\n}\n\nconst tabsListVariants = cva(\n \"group/tabs-list inline-flex w-fit items-center justify-center rounded-md p-[3px] text-muted-foreground group-data-vertical/tabs:flex-col\",\n {\n variants: {\n variant: {\n default: \"bg-muted\",\n line: \"gap-1 rounded-none bg-transparent\",\n },\n density: {\n default: \"min-h-8\",\n compact: \"min-h-7\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n density: \"default\",\n },\n },\n);\n\nfunction TabsList({\n className,\n variant = \"default\",\n density = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps) {\n return (\n \n );\n}\n\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\n return (\n \n );\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n \n );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };\n", + "content": "\"use client\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n \n );\n}\n\nconst tabsListVariants = cva(\n \"group/tabs-list inline-flex w-fit items-center justify-center rounded-md p-[3px] text-muted-foreground data-[orientation=vertical]:flex-col\",\n {\n variants: {\n variant: {\n default: \"bg-muted\",\n line: \"gap-1 rounded-none bg-transparent\",\n },\n density: {\n default: \"min-h-8\",\n compact: \"min-h-7\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n density: \"default\",\n },\n },\n);\n\nfunction TabsList({\n className,\n variant = \"default\",\n density = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps) {\n return (\n \n );\n}\n\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\n return (\n \n );\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n \n );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };\n", "type": "registry:ui", "target": "@ui/tabs.tsx" } From d4e14960d984c49498aa779bc618bcade4acf16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 07:37:37 -0500 Subject: [PATCH 23/45] test(tabs): lock Base UI orientation semantics --- packages/ui/tests/tabs.test.tsx | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 packages/ui/tests/tabs.test.tsx diff --git a/packages/ui/tests/tabs.test.tsx b/packages/ui/tests/tabs.test.tsx new file mode 100644 index 0000000..738e1aa --- /dev/null +++ b/packages/ui/tests/tabs.test.tsx @@ -0,0 +1,46 @@ +import { render, screen } from "@testing-library/react"; + +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@opencoven/ui/components/ui/tabs"; + +describe("Tabs orientation", () => { + it("stacks horizontal tab lists above their active panel", () => { + const { container } = render( + + + Overview + Details + + Overview panel + Details panel + , + ); + + const root = container.querySelector('[data-slot="tabs"]'); + expect(root).toHaveAttribute("data-orientation", "horizontal"); + expect(root).toHaveClass("flex-col"); + expect(screen.getByText("Overview panel")).toBeVisible(); + expect(screen.queryByText("Details panel")).not.toBeInTheDocument(); + }); + + it("lets Base UI expose vertical orientation directly on the list", () => { + const { container } = render( + + + Overview + + Overview panel + , + ); + + const root = container.querySelector('[data-slot="tabs"]'); + const list = container.querySelector('[data-slot="tabs-list"]'); + expect(root).toHaveAttribute("data-orientation", "vertical"); + expect(root).not.toHaveClass("flex-col"); + expect(list).toHaveAttribute("data-orientation", "vertical"); + }); +}); From 0ed9ce17e4eb6d1f5c51ba96335b5fc7c7adb474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:23:42 -0500 Subject: [PATCH 24/45] fix(blocks): make transcript turns mobile-first --- packages/ui/src/blocks/transcript-turn.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ui/src/blocks/transcript-turn.tsx b/packages/ui/src/blocks/transcript-turn.tsx index 48fc401..5ad93dc 100644 --- a/packages/ui/src/blocks/transcript-turn.tsx +++ b/packages/ui/src/blocks/transcript-turn.tsx @@ -29,11 +29,11 @@ function TranscriptTurn({
-
+
-
+
{children}
{artifacts} {utilities ? (
{utilities}
From d054a7a24771d49339bdd13d531fe35a0d41dac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:23:51 -0500 Subject: [PATCH 25/45] fix(blocks): recompose session headers on mobile --- packages/ui/src/blocks/session-header.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/ui/src/blocks/session-header.tsx b/packages/ui/src/blocks/session-header.tsx index a37befa..c8d8edd 100644 --- a/packages/ui/src/blocks/session-header.tsx +++ b/packages/ui/src/blocks/session-header.tsx @@ -29,19 +29,21 @@ function SessionHeader({
- - {title} - -
); } From 36a77ddbb54f9ae64f8ed662c648542b7e32c09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:24:08 -0500 Subject: [PATCH 26/45] fix(specimens): recompose cards for narrow viewports --- apps/specimens/src/specimens-fixes.css | 90 ++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index 28376e3..cf90e9b 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -6,6 +6,86 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { display: none; } +@media (max-width: 48rem) { + .specimen-card > [data-slot="tabs"] { + width: 100%; + min-width: 0; + gap: 0; + } + + .specimen-card > [data-slot="tabs"] > [data-slot="tabs-list"] { + display: grid; + box-sizing: border-box; + width: 100% !important; + min-width: 0; + max-width: 100%; + min-height: 2.75rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0; + margin: 0 !important; + border-block-end: 1px solid var(--border); + padding: 0 0.75rem; + } + + .specimen-card + > [data-slot="tabs"] + > [data-slot="tabs-list"] + > [data-slot="tabs-trigger"] { + min-width: 0; + min-height: 2.75rem; + padding: 0.625rem 0.5rem; + } + + .specimen-card > [data-slot="tabs"] > [data-slot="tabs-content"] { + width: 100%; + min-width: 0; + max-width: 100%; + } + + .specimen-card__header { + min-height: 0; + padding: 1rem; + } + + .specimen-card__title { + margin-block-start: 0.875rem; + } + + .specimen-card__description { + margin-block-start: 0.375rem; + line-height: 1.5; + } + + .specimen-stage { + width: 100%; + min-width: 0; + min-height: 0; + max-width: 100%; + align-content: start; + justify-items: stretch; + border-block-start: 0; + padding: 1rem; + } + + .specimen-stage > * { + width: 100%; + min-width: 0; + max-width: 100%; + } + + .specimen-documentation { + width: 100%; + min-width: 0; + min-height: 0; + max-width: 100%; + padding: 1rem; + } + + .specimen-command { + max-width: 100%; + } +} + @media (max-width: 24.375rem) { .assembled-lab > [data-slot="tabs"], .assembled-lab [data-slot="tabs-content"], @@ -17,11 +97,6 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { max-width: 100%; } - .assembled-lab [data-slot="tabs-content"], - .assembled-lab__stage { - overflow-x: hidden; - } - .assembled-lab__nav { overflow-x: hidden; } @@ -42,6 +117,11 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { white-space: normal; } + .assembled-lab__stage { + min-height: 0; + align-content: start; + } + .assembled-lab__stage > * { min-width: 0; max-width: 100%; From 402e3391701d04d67a50572da0bea7c13f1a0ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:24:25 -0500 Subject: [PATCH 27/45] test(blocks): lock mobile composition contracts --- packages/ui/tests/mobile-blocks.test.tsx | 61 ++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 packages/ui/tests/mobile-blocks.test.tsx diff --git a/packages/ui/tests/mobile-blocks.test.tsx b/packages/ui/tests/mobile-blocks.test.tsx new file mode 100644 index 0000000..e235c0b --- /dev/null +++ b/packages/ui/tests/mobile-blocks.test.tsx @@ -0,0 +1,61 @@ +import { render, screen } from "@testing-library/react"; + +import { SessionHeader } from "@opencoven/ui/blocks/session-header"; +import { TranscriptTurn } from "@opencoven/ui/blocks/transcript-turn"; + +describe("mobile block composition", () => { + it("lets transcript provenance and utilities wrap without establishing intrinsic width", () => { + const { container } = render( + + Reply + Copy + 1.8K tokens + + } + > +

The component source and registry share one boundary.

+
, + ); + + const turn = container.querySelector('[data-slot="transcript-turn"]'); + expect(turn).toHaveClass("min-w-0", "ps-3", "sm:ps-5"); + + const provenance = screen.getByText(/Code Familiar/); + expect(provenance).toHaveClass("break-words", "sm:truncate"); + + const utilities = screen.getByLabelText("Message utilities"); + expect(utilities).toHaveClass("flex-wrap", "gap-y-1.5"); + }); + + it("gives session identity a full mobile row and keeps state metadata independently reflowable", () => { + const { container } = render( + , + ); + + const header = container.querySelector('[data-slot="session-header"]'); + expect(header).toHaveClass("grid", "grid-cols-2", "sm:flex"); + + const title = screen.getByText( + "Keep escaped delimiters without clipping the task title", + ); + expect(title).toHaveClass("leading-5", "sm:truncate"); + expect(title).not.toHaveClass("truncate"); + + const branch = screen.getByText( + "fix/tokenizer-escapes-with-a-long-branch-name", + ); + expect(branch).toHaveClass("min-w-0", "truncate"); + }); +}); From 56a3279c0fb5820cf874fc37af6ba1f013f52ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:24:39 -0500 Subject: [PATCH 28/45] chore(registry): sync responsive transcript turn --- public/r/transcript-turn.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/r/transcript-turn.json b/public/r/transcript-turn.json index efe036e..6b8c8a9 100644 --- a/public/r/transcript-turn.json +++ b/public/r/transcript-turn.json @@ -10,7 +10,7 @@ "files": [ { "path": "packages/ui/src/blocks/transcript-turn.tsx", - "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype TranscriptTurnProps = {\n familiar: string;\n initials: string;\n role: string;\n model?: string;\n timestamp: string;\n children: React.ReactNode;\n utilities?: React.ReactNode;\n artifacts?: React.ReactNode;\n className?: string;\n};\n\nfunction TranscriptTurn({\n familiar,\n initials,\n role,\n model,\n timestamp,\n children,\n utilities,\n artifacts,\n className,\n}: TranscriptTurnProps) {\n return (\n \n
\n \n {initials}\n \n \n {familiar}\n \n {[role, model, timestamp].filter(Boolean).join(\" · \")}\n \n \n
\n
\n {children}\n
\n {artifacts}\n {utilities ? (\n \n {utilities}\n \n ) : null}\n
\n );\n}\n\nexport { TranscriptTurn, type TranscriptTurnProps };\n", + "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype TranscriptTurnProps = {\n familiar: string;\n initials: string;\n role: string;\n model?: string;\n timestamp: string;\n children: React.ReactNode;\n utilities?: React.ReactNode;\n artifacts?: React.ReactNode;\n className?: string;\n};\n\nfunction TranscriptTurn({\n familiar,\n initials,\n role,\n model,\n timestamp,\n children,\n utilities,\n artifacts,\n className,\n}: TranscriptTurnProps) {\n return (\n \n
\n \n {initials}\n \n \n {familiar}\n \n {[role, model, timestamp].filter(Boolean).join(\" · \")}\n \n \n
\n
\n {children}\n
\n {artifacts}\n {utilities ? (\n \n {utilities}\n \n ) : null}\n \n );\n}\n\nexport { TranscriptTurn, type TranscriptTurnProps };\n", "type": "registry:block", "target": "@components/blocks/transcript-turn.tsx" } From afe53cf9324b352ef01fa877fd195ef6037b5377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:24:52 -0500 Subject: [PATCH 29/45] chore(registry): sync responsive session header --- public/r/session-header.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/r/session-header.json b/public/r/session-header.json index 0658e05..9c04ffa 100644 --- a/public/r/session-header.json +++ b/public/r/session-header.json @@ -2,7 +2,7 @@ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "session-header", "title": "Session header", - "description": "Task title, branch, execution state, and budget in one line.", + "description": "Task title, branch, execution state, and budget with responsive hierarchy.", "dependencies": [ "lucide-react" ], @@ -14,7 +14,7 @@ "files": [ { "path": "packages/ui/src/blocks/session-header.tsx", - "content": "import { GitBranch } from \"lucide-react\";\n\nimport { BudgetPill } from \"@/components/budget-pill\";\nimport {\n StatusIndicator,\n type Status,\n} from \"@/components/status-indicator\";\nimport { cn } from \"@/lib/utils\";\n\ntype SessionHeaderProps = {\n title: string;\n branch: string;\n status: Status;\n budget?: {\n used: number;\n limit: number;\n };\n className?: string;\n};\n\nfunction SessionHeader({\n title,\n branch,\n status,\n budget,\n className,\n}: SessionHeaderProps) {\n return (\n \n \n {title}\n \n \n {branch}\n \n \n \n {budget ? : null}\n \n );\n}\n\nexport { SessionHeader, type SessionHeaderProps };\n", + "content": "import { GitBranch } from \"lucide-react\";\n\nimport { BudgetPill } from \"@/components/budget-pill\";\nimport {\n StatusIndicator,\n type Status,\n} from \"@/components/status-indicator\";\nimport { cn } from \"@/lib/utils\";\n\ntype SessionHeaderProps = {\n title: string;\n branch: string;\n status: Status;\n budget?: {\n used: number;\n limit: number;\n };\n className?: string;\n};\n\nfunction SessionHeader({\n title,\n branch,\n status,\n budget,\n className,\n}: SessionHeaderProps) {\n return (\n \n \n {title}\n \n \n {branch}\n \n \n \n \n {budget ? : null}\n \n \n );\n}\n\nexport { SessionHeader, type SessionHeaderProps };\n", "type": "registry:block", "target": "@components/blocks/session-header.tsx" } From 86d7ea46c26520fa9884ec3d392ba1bc6954077c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:29:09 -0500 Subject: [PATCH 30/45] chore(registry): describe responsive session hierarchy --- registry/blocks/registry.fragment.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/blocks/registry.fragment.json b/registry/blocks/registry.fragment.json index c10f586..ab47ff9 100644 --- a/registry/blocks/registry.fragment.json +++ b/registry/blocks/registry.fragment.json @@ -69,7 +69,7 @@ "name": "session-header", "type": "registry:block", "title": "Session header", - "description": "Task title, branch, execution state, and budget in one line.", + "description": "Task title, branch, execution state, and budget with responsive hierarchy.", "dependencies": ["lucide-react"], "registryDependencies": ["budget-pill", "status-indicator", "cn"], "files": [ From d98c2f78586444bf7da0a1413d8c3c4cde68d164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:32:17 -0500 Subject: [PATCH 31/45] chore(registry): avoid aggregate metadata churn --- registry/blocks/registry.fragment.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/blocks/registry.fragment.json b/registry/blocks/registry.fragment.json index ab47ff9..c10f586 100644 --- a/registry/blocks/registry.fragment.json +++ b/registry/blocks/registry.fragment.json @@ -69,7 +69,7 @@ "name": "session-header", "type": "registry:block", "title": "Session header", - "description": "Task title, branch, execution state, and budget with responsive hierarchy.", + "description": "Task title, branch, execution state, and budget in one line.", "dependencies": ["lucide-react"], "registryDependencies": ["budget-pill", "status-indicator", "cn"], "files": [ From a1d49403b23dee0783ba6dfbc5a9d6a944ef5d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:32:34 -0500 Subject: [PATCH 32/45] chore(registry): keep stable session metadata --- public/r/session-header.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/r/session-header.json b/public/r/session-header.json index 9c04ffa..8a24862 100644 --- a/public/r/session-header.json +++ b/public/r/session-header.json @@ -2,7 +2,7 @@ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "session-header", "title": "Session header", - "description": "Task title, branch, execution state, and budget with responsive hierarchy.", + "description": "Task title, branch, execution state, and budget in one line.", "dependencies": [ "lucide-react" ], From 7b8f07c4bb1a20e47c1fe958bb966358b79f8cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:47:02 -0500 Subject: [PATCH 33/45] fix(specimens): keep minimum viewport independent of text scale --- apps/specimens/src/specimens.css | 685 +++++++++++++------------------ 1 file changed, 292 insertions(+), 393 deletions(-) diff --git a/apps/specimens/src/specimens.css b/apps/specimens/src/specimens.css index 3a5bb1f..d9991e1 100644 --- a/apps/specimens/src/specimens.css +++ b/apps/specimens/src/specimens.css @@ -1,5 +1,5 @@ html { - min-width: 20rem; + min-width: 320px; scroll-padding-top: 7rem; } @@ -83,52 +83,38 @@ body { .specimen-brand small { margin-block-start: 0.2rem; color: var(--muted-foreground); - font-family: var(--font-numeric); font-size: 0.625rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; } -.surface-switcher, -.density-control { +.surface-switcher { display: inline-flex; align-items: center; - gap: 0.125rem; - padding: 0.1875rem; + gap: 0.25rem; border: 1px solid var(--border); border-radius: var(--radius-2); - background: var(--card); + background: color-mix(in srgb, var(--muted) 58%, var(--background)); + padding: 0.2rem; } -.surface-switcher a, -.density-control button { - border: 0; - border-radius: calc(var(--radius-2) - 2px); - background: transparent; +.surface-switcher a { + border-radius: calc(var(--radius-2) - 0.2rem); color: var(--muted-foreground); - padding: 0.375rem 0.75rem; + padding: 0.45rem 0.7rem; font-size: 0.75rem; font-weight: 700; - line-height: 1.25rem; text-decoration: none; - white-space: nowrap; } -.surface-switcher a:hover, -.density-control button:hover { - background: var(--muted); +.surface-switcher a[data-active="true"] { + background: var(--card); color: var(--foreground); -} - -.surface-switcher a[aria-current="page"], -.density-control button[aria-pressed="true"] { - background: var(--foreground); - color: var(--background); box-shadow: var(--elevation-1); } -.specimen-topbar__actions { +.specimen-topbar__tools { display: flex; min-width: 0; align-items: center; @@ -137,234 +123,199 @@ body { } .specimen-search { - width: min(20rem, 34vw); -} - -.scheme-control { - flex: none; - white-space: nowrap; + position: relative; + width: min(22rem, 42vw); + min-width: 0; } -.scheme-control svg { +.specimen-search svg { + position: absolute; + inset-block-start: 50%; + inset-inline-start: 0.75rem; + z-index: 1; width: 0.875rem; height: 0.875rem; + translate: 0 -50%; + color: var(--muted-foreground); + pointer-events: none; } -.specimen-shell { - display: grid; - max-width: 96rem; - min-height: calc(100vh - 4.25rem); - grid-template-columns: 15rem minmax(0, 1fr); - margin-inline: auto; -} - -.specimen-rail { - position: sticky; - inset-block-start: 4.25rem; - align-self: start; - height: calc(100vh - 4.25rem); - overflow-y: auto; - border-inline-end: 1px solid var(--border); - background: color-mix(in srgb, var(--card) 72%, var(--background)); - padding: 2rem 1.25rem; - scrollbar-width: thin; -} - -.specimen-rail__context { - padding-inline: 0.625rem; +.specimen-search [data-slot="input"] { + height: 2.25rem; + padding-inline-start: 2.15rem; } -.specimen-rail__context h2 { - margin: 0.4rem 0 0; - font-size: 1rem; - font-weight: 750; - letter-spacing: -0.015em; +.specimen-density { + display: inline-flex; + align-items: center; + gap: 0.2rem; + border: 1px solid var(--border); + border-radius: var(--radius-2); + background: color-mix(in srgb, var(--muted) 45%, var(--background)); + padding: 0.2rem; } -.specimen-rail__context p:last-child { - margin: 0.625rem 0 0; +.specimen-density button { + min-height: 1.8rem; + border: 0; + border-radius: calc(var(--radius-2) - 0.2rem); + background: transparent; color: var(--muted-foreground); - font-size: 0.75rem; - line-height: 1.55; + padding-inline: 0.55rem; + font-size: 0.7rem; + font-weight: 700; } -.specimen-kicker { - margin: 0; - color: var(--presence); - font-size: 0.625rem; - font-weight: 750; - letter-spacing: 0.14em; - text-transform: uppercase; +.specimen-density button[data-active="true"] { + background: var(--card); + color: var(--foreground); + box-shadow: var(--elevation-1); } -.specimen-rail__nav { +.specimen-topbar__icon { display: grid; - gap: 0.25rem; - margin-block-start: 1.75rem; -} - -.specimen-rail__nav a { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; + width: 2.25rem; + height: 2.25rem; + place-items: center; + border: 1px solid var(--border); border-radius: var(--radius-2); + background: color-mix(in srgb, var(--card) 88%, transparent); color: var(--muted-foreground); - padding: 0.625rem 0.75rem; - font-size: 0.8125rem; - font-weight: 650; - text-decoration: none; } -.specimen-rail__nav a:hover { - background: var(--muted); +.specimen-topbar__icon:hover, +.specimen-topbar__icon:focus-visible { color: var(--foreground); } -.specimen-rail__nav small { - color: color-mix(in srgb, var(--muted-foreground) 76%, transparent); - font-size: 0.625rem; -} - -.specimen-rail__package { - margin-block-start: 2rem; - border-block-start: 1px solid var(--border); - padding: 1.25rem 0.625rem 0; -} - -.specimen-rail__package code { - display: block; - overflow: hidden; - margin-block-start: 0.5rem; - color: var(--foreground); - font-size: 0.75rem; - text-overflow: ellipsis; - white-space: nowrap; -} - -.specimen-rail__package p { - margin: 0.625rem 0 0; - color: var(--muted-foreground); - font-size: 0.7rem; - line-height: 1.5; +.specimen-topbar__icon svg { + width: 0.875rem; + height: 0.875rem; } -.specimen-main { - min-width: 0; +.specimen-shell { + display: grid; + max-width: 96rem; + grid-template-columns: minmax(12rem, 15rem) minmax(0, 1fr); + gap: clamp(1.25rem, 3vw, 3rem); + margin-inline: auto; + padding: clamp(1.25rem, 3vw, 2.25rem) clamp(1rem, 3vw, 2rem) 5rem; } -.specimen-main__inner { - width: min(100%, 78rem); - margin-inline: auto; - padding: clamp(2rem, 5vw, 4.5rem) clamp(1rem, 4vw, 3.5rem) 7rem; +.specimen-rail { + position: sticky; + inset-block-start: 6.5rem; + display: grid; + height: fit-content; + gap: 1.5rem; + padding-block: 0.35rem; } -.specimen-hero { +.specimen-rail__intro { display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: end; - gap: 2rem; - margin-block-end: clamp(3rem, 6vw, 5rem); - border-block-end: 1px solid var(--border); - padding-block-end: clamp(2rem, 4vw, 3rem); + gap: 0.55rem; } -.specimen-hero__copy { - max-width: 47rem; +.specimen-eyebrow { + color: var(--presence); + font-size: 0.625rem; + font-weight: 800; + letter-spacing: 0.14em; + text-transform: uppercase; } -.specimen-hero h1 { - max-width: 14ch; - margin: 0.65rem 0 0; - font-family: var(--font-editorial); - font-size: clamp(2.75rem, 6vw, 5.25rem); +.specimen-rail__intro h1 { + max-width: 12ch; + font-family: var(--font-serif); + font-size: clamp(2rem, 4vw, 3.4rem); font-weight: 500; - letter-spacing: -0.045em; - line-height: 0.98; - text-wrap: balance; + letter-spacing: -0.035em; + line-height: 0.95; } -.specimen-hero__copy > p:last-child { - max-width: 60ch; - margin: 1.25rem 0 0; +.specimen-rail__intro p { + max-width: 26rem; color: var(--muted-foreground); - font-size: 0.9375rem; - line-height: 1.7; + font-size: 0.78rem; + line-height: 1.6; } -.specimen-stats { +.specimen-rail__nav { display: grid; - grid-template-columns: repeat(3, minmax(4.5rem, 1fr)); - gap: 0.5rem; - margin: 0; -} - -.specimen-stats div { - min-width: 5rem; - border-inline-start: 1px solid var(--border); - padding-inline-start: 0.875rem; + border-block-start: 1px solid var(--border); } -.specimen-stats dt { +.specimen-rail__nav a { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 0.75rem; + border-block-end: 1px solid var(--border); color: var(--muted-foreground); - font-size: 0.625rem; + padding-block: 0.75rem; + font-size: 0.72rem; font-weight: 700; - letter-spacing: 0.08em; - text-transform: uppercase; + text-decoration: none; } -.specimen-stats dd { - margin: 0.25rem 0 0; +.specimen-rail__nav a:hover, +.specimen-rail__nav a:focus-visible { color: var(--foreground); - font-size: 1.25rem; - font-weight: 650; +} + +.specimen-rail__nav small { + color: var(--presence); + font-size: 0.625rem; +} + +.specimen-main { + min-width: 0; +} + +.specimen-main__inner { + min-width: 0; } .catalog { display: grid; - gap: clamp(4rem, 8vw, 7rem); + gap: 3.5rem; } .catalog-group { + display: grid; + gap: 1rem; scroll-margin-block-start: 7rem; } .catalog-group__header { - display: flex; + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 1rem; align-items: end; - justify-content: space-between; - gap: 2rem; - margin-block-end: 1.25rem; + border-block-end: 1px solid var(--border); + padding-block-end: 0.75rem; } -.catalog-group__eyebrow { - margin: 0; - color: var(--presence); - font-size: 0.625rem; - font-weight: 750; - letter-spacing: 0.14em; - text-transform: uppercase; +.catalog-group__header h2 { + font-size: 1rem; + font-weight: 800; + letter-spacing: -0.01em; } -.catalog-group__header h2 { - max-width: 34rem; - margin: 0.45rem 0 0; - font-size: clamp(1.25rem, 2.5vw, 1.75rem); - font-weight: 700; - letter-spacing: -0.025em; - line-height: 1.2; - text-wrap: balance; +.catalog-group__header p { + margin-block-start: 0.25rem; + color: var(--muted-foreground); + font-size: 0.7rem; + line-height: 1.5; } .catalog-group__count { - flex: none; - color: var(--muted-foreground); - font-size: 0.6875rem; - letter-spacing: 0.04em; - text-transform: uppercase; + color: var(--presence); + font-size: 0.625rem; + font-weight: 800; + letter-spacing: 0.08em; } -.specimen-grid { +.catalog-group__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; @@ -373,143 +324,117 @@ body { .specimen-card { min-width: 0; overflow: hidden; - scroll-margin-block-start: 7rem; border: 1px solid var(--border); border-radius: var(--radius-3); - background: var(--card); + background: color-mix(in srgb, var(--card) 96%, var(--background)); box-shadow: var(--elevation-1); transition: - border-color var(--motion-standard) var(--motion-ease), - box-shadow var(--motion-standard) var(--motion-ease), - translate var(--motion-standard) var(--motion-ease); + border-color var(--motion-fast) ease, + box-shadow var(--motion-fast) ease, + translate var(--motion-fast) ease; } .specimen-card:hover, .specimen-card:focus-within { - border-color: color-mix(in srgb, var(--presence) 34%, var(--border)); - box-shadow: var(--elevation-2); translate: 0 -1px; + border-color: color-mix(in srgb, var(--presence) 30%, var(--border)); + box-shadow: var(--elevation-2); } .specimen-card__header { - min-height: 9.75rem; - border-block-end: 1px solid var(--border); - padding: 1.125rem 1.25rem 1.25rem; + display: grid; + min-height: 10.5rem; + align-content: start; + padding: 1.25rem; } .specimen-card__meta { display: flex; align-items: center; justify-content: space-between; - gap: 1rem; + gap: 0.75rem; } .specimen-card__index { - color: var(--muted-foreground); + color: var(--presence); font-size: 0.625rem; - font-weight: 700; - letter-spacing: 0.12em; + font-weight: 850; + letter-spacing: 0.14em; } .specimen-card__title { - margin: 1rem 0 0; - font-size: 1.0625rem; - font-weight: 750; + margin-block-start: 1.4rem; + font-size: 1.1rem; + font-weight: 800; letter-spacing: -0.015em; } .specimen-card__description { - max-width: 46ch; - margin: 0.45rem 0 0; + margin-block-start: 0.45rem; + max-width: 44ch; color: var(--muted-foreground); - font-size: 0.8125rem; + font-size: 0.74rem; line-height: 1.55; } +.specimen-stage, +.specimen-documentation { + min-width: 0; + min-height: 15rem; + border-block-start: 1px solid var(--border); + background: color-mix(in srgb, var(--muted) 34%, var(--background)); + padding: clamp(1rem, 3vw, 2rem); +} + .specimen-stage { display: grid; - min-height: 17rem; align-content: center; justify-items: center; - border-block-start: 1px solid - color-mix(in srgb, var(--border) 62%, transparent); - background: color-mix(in srgb, var(--muted) 48%, var(--background)); - padding: clamp(1rem, 3vw, 2rem); } .specimen-stage > * { max-width: 100%; } -.specimen-stage > [data-slot="composer"], -.specimen-stage > [data-slot="session-header"] { - width: 100%; -} - -.specimen-stage > [data-slot="run-rail"] { - width: min(100%, 28rem); -} - -.specimen-stage > [data-slot="transcript-turn"] { - width: min(100%, 42rem); -} - .specimen-documentation { display: grid; - min-height: 17rem; align-content: start; - gap: 0.875rem; - padding: 1.25rem; - font-size: 0.8125rem; + gap: 0.85rem; + color: var(--muted-foreground); + font-size: 0.72rem; line-height: 1.6; } -.specimen-documentation p { - margin: 0; -} - .specimen-command { display: block; - overflow-wrap: anywhere; + overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-2); - background: var(--muted); + background: color-mix(in srgb, var(--background) 80%, var(--card)); color: var(--foreground); padding: 0.75rem; - font-size: 0.7rem; - line-height: 1.6; -} - -.run-spine { - position: relative; -} - -.run-spine::before { - position: absolute; - inset-block: 0.5rem; - inset-inline-start: 1.1rem; - width: 1px; - background: color-mix(in srgb, var(--presence) 38%, var(--border)); - content: ""; + white-space: pre-wrap; + word-break: break-word; } .catalog-empty { display: grid; - min-height: 24rem; + min-height: 22rem; place-items: center; align-content: center; + gap: 0.75rem; border: 1px dashed var(--border); border-radius: var(--radius-3); - padding: 2rem; + color: var(--muted-foreground); text-align: center; } .catalog-empty__mark { display: grid; - width: 2.75rem; - height: 2.75rem; + width: 2.5rem; + height: 2.5rem; place-items: center; - border: 1px solid var(--border); + border: 1px solid color-mix(in srgb, var(--presence) 35%, var(--border)); border-radius: var(--radius-2); color: var(--presence); } @@ -519,17 +444,6 @@ body { height: 1rem; } -.catalog-empty h2 { - margin: 1rem 0 0; - font-size: 1.125rem; -} - -.catalog-empty p { - margin: 0.4rem 0 0; - color: var(--muted-foreground); - font-size: 0.8125rem; -} - .assembled-lab { overflow: hidden; scroll-margin-block-start: 7rem; @@ -539,47 +453,52 @@ body { box-shadow: var(--elevation-2); } -.assembled-lab__nav { - overflow-x: auto; - border-block-end: 1px solid var(--border); - padding: 0.75rem 1rem 0; +.assembled-lab > [data-slot="session-header"] { + border-block-end: 0; } -.assembled-lab__tabs { - width: max-content; +.assembled-lab > [data-slot="tabs"] { min-width: 0; + gap: 0; } -.assembled-lab__tabs [data-slot="tabs-trigger"] { - flex: none; +.assembled-lab__nav { + display: flex; + overflow-x: auto; + border-block: 1px solid var(--border); + background: color-mix(in srgb, var(--muted) 26%, var(--background)); + padding: 0.75rem 1rem; + scrollbar-width: thin; } -.assembled-lab [data-slot="tabs"], -.assembled-lab__stage, -.lab-composer, -.lab-message-stack { - min-width: 0; +.assembled-lab__tabs { + flex: none; + width: max-content; } .assembled-lab__stage { display: grid; + min-width: 0; min-height: 34rem; align-content: center; background: color-mix(in srgb, var(--muted) 42%, var(--background)); padding: clamp(1rem, 4vw, 3rem); } -.lab-composer, .lab-message-stack { display: grid; - width: min(100%, 48rem); - gap: 2rem; - margin-inline: auto; + min-width: 0; + gap: 1.5rem; +} + +.lab-composer { + display: grid; + min-width: 0; + gap: 1rem; } .lab-card-grid { display: grid; - width: min(100%, 52rem); grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.875rem; margin-inline: auto; @@ -591,209 +510,189 @@ body { } @media (max-width: 68rem) { - html { - scroll-padding-top: 10rem; - } - .specimen-topbar__inner { - grid-template-columns: auto 1fr; - padding-block: 0.75rem; + grid-template-columns: auto minmax(0, 1fr); } .surface-switcher { justify-self: end; } - .specimen-topbar__actions { - display: grid; - width: 100%; + .specimen-topbar__tools { grid-column: 1 / -1; - grid-template-columns: minmax(0, 1fr) auto auto; + justify-content: stretch; + padding-block-end: 0.75rem; } .specimen-search { - width: 100%; + width: auto; + flex: 1; } .specimen-shell { - min-height: 0; grid-template-columns: 1fr; } .specimen-rail { position: static; - display: block; - height: auto; - overflow-x: auto; - border-inline-end: 0; + grid-template-columns: minmax(0, 1fr) auto; + align-items: end; border-block-end: 1px solid var(--border); - padding: 0.75rem clamp(1rem, 4vw, 2rem); + padding-block-end: 1rem; } - .specimen-rail__context, - .specimen-rail__package { - display: none; + .specimen-rail__intro h1 { + max-width: none; } .specimen-rail__nav { - display: flex; - width: max-content; - min-width: 100%; - gap: 0.375rem; - margin: 0; + min-width: 12rem; } - .specimen-rail__nav a { - min-width: 9rem; - flex: 1 0 auto; - border: 1px solid transparent; - background: color-mix(in srgb, var(--card) 72%, var(--background)); + .specimen-stage, + .assembled-lab__stage { + padding: 1rem; } - .specimen-main__inner { - padding-block-start: clamp(2rem, 5vw, 3.5rem); + .assembled-lab__stage { + min-height: 30rem; } -} -@media (max-width: 48rem) { - .specimen-hero { + .lab-card-grid { grid-template-columns: 1fr; - align-items: start; - } - - .specimen-stats { - width: 100%; - } - - .catalog-group__header { - align-items: start; } +} - .specimen-grid { - grid-template-columns: 1fr; +@media (max-width: 48rem) { + .specimen-topbar__inner { + gap: 0.65rem; + padding-inline: 0.75rem; } - .specimen-card__header { - min-height: 0; + .specimen-brand > span:last-child { + display: none; } -} -@media (max-width: 36rem) { - html { - scroll-padding-top: 12rem; + .surface-switcher a { + padding-inline: 0.5rem; } - .specimen-topbar__inner { - gap: 0.75rem; + .specimen-density span { + display: none; } - .specimen-brand small { - display: none; + .specimen-shell { + padding-inline: 0.75rem; } - .specimen-topbar__actions { - grid-template-columns: minmax(0, 1fr) auto; + .specimen-rail { + grid-template-columns: 1fr; + gap: 1rem; } - .specimen-search { - grid-column: 1 / -1; + .specimen-rail__nav { + grid-template-columns: repeat(3, minmax(0, 1fr)); + border-block-start: 0; } - .scheme-control span { - display: none; + .specimen-rail__nav a { + grid-template-columns: 1fr; + justify-items: center; + border: 1px solid var(--border); + border-inline-end: 0; + padding: 0.6rem 0.45rem; + text-align: center; } - .specimen-main__inner { - padding-inline: 1rem; + .specimen-rail__nav a:first-child { + border-start-start-radius: var(--radius-2); + border-end-start-radius: var(--radius-2); } - .specimen-hero { - margin-block-end: 3rem; + .specimen-rail__nav a:last-child { + border-inline-end: 1px solid var(--border); + border-start-end-radius: var(--radius-2); + border-end-end-radius: var(--radius-2); } - .specimen-hero h1 { - font-size: clamp(2.5rem, 14vw, 3.75rem); + .specimen-rail__nav small { + display: none; } .catalog { - gap: 4rem; + gap: 2.5rem; } - .catalog-group__header { - display: grid; - gap: 0.75rem; + .catalog-group__grid { + grid-template-columns: 1fr; } - .catalog-group__count { - justify-self: start; + .specimen-card__header { + min-height: auto; } .specimen-stage, - .assembled-lab__stage { - padding: 1rem; + .specimen-documentation { + min-height: 13rem; } - .assembled-lab__stage { - min-height: 30rem; + .assembled-lab__nav { + padding-inline: 0.75rem; } +} - .lab-card-grid { - grid-template-columns: 1fr; +@media (max-width: 34rem) { + .specimen-topbar__inner { + grid-template-columns: minmax(0, 1fr) auto; + } + + .specimen-brand { + min-width: 0; } -} -@media (max-width: 24.375rem) { .specimen-brand__mark { width: 2rem; height: 2rem; } - .surface-switcher a, - .density-control button { - padding-inline: 0.55rem; + .surface-switcher { + overflow-x: auto; + max-width: 100%; } - .specimen-topbar__actions { - gap: 0.375rem; + .surface-switcher a { + white-space: nowrap; } - .specimen-hero h1 { - font-size: 2.5rem; + .specimen-topbar__tools { + display: grid; + grid-template-columns: minmax(0, 1fr) auto auto; } - .specimen-stats div { + .specimen-search { min-width: 0; - padding-inline-start: 0.625rem; } - .specimen-stats dt { - font-size: 0.55rem; + .specimen-density button { + padding-inline: 0.45rem; } - .specimen-stage { - min-height: 14rem; - padding: 0.875rem; + .catalog-group__header { + grid-template-columns: 1fr; } - .specimen-documentation { - min-height: 14rem; - padding: 1rem; + .catalog-group__count { + justify-self: start; } } @media (prefers-reduced-motion: reduce) { - .skip-link { - transition: none; - } - - .specimen-card { - translate: none; - } -} - -@media (forced-colors: active) { - .surface-switcher a[aria-current="page"], - .density-control button[aria-pressed="true"] { - border: 1px solid Highlight; + *, + *::before, + *::after { + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; } } From f68ec89abe28d9baeed0fab5195d4487638bb326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:50:55 -0500 Subject: [PATCH 34/45] fix(specimens): keep viewport floor stable at large text --- apps/specimens/src/specimens-fixes.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index cf90e9b..22b7836 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -1,5 +1,10 @@ /* Focused regression guards layered after the specimen shell styles. */ +/* Keep the supported viewport floor stable when users enlarge root text. */ +html { + min-width: 320px; +} + body:not(:has(#group-composer)) .specimen-rail a[href="#group-composer"], body:not(:has(#group-run-rail)) .specimen-rail a[href="#group-run-rail"], body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { From 2de1085bdbe014e5ef6caf1af8234b0c25d6475e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 08:52:08 -0500 Subject: [PATCH 35/45] test(specimens): guard text-scaled viewport floor --- scripts/verify-contracts.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index 450a87a..ce58535 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -9,6 +9,7 @@ const [ packageJson, tokens, specimenCss, + specimenFixes, specimenApp, button, tooltip, @@ -18,6 +19,7 @@ const [ read("packages/ui/package.json"), read("packages/ui/src/styles/globals.css"), read("apps/specimens/src/specimens.css"), + read("apps/specimens/src/specimens-fixes.css"), read("apps/specimens/src/app.tsx"), read("packages/ui/src/components/ui/button.tsx"), read("packages/ui/src/components/ui/tooltip.tsx"), @@ -105,6 +107,10 @@ const assertions = [ "mobile layout covers 390px", specimenCss.includes("@media (max-width: 24.375rem)"), ], + [ + "minimum viewport floor does not scale with text", + /html\s*\{[^}]*min-width:\s*320px/.test(specimenFixes), + ], [ "responsive rail becomes compact navigation", specimenCss.includes("@media (max-width: 68rem)") && From df3b2103ab58760d9f995743a30d26bac540c73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:07:29 -0500 Subject: [PATCH 36/45] test(contracts): align responsive assertions with layered shell --- scripts/verify-contracts.mjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index ce58535..ab5cb0e 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -105,7 +105,8 @@ const assertions = [ ], [ "mobile layout covers 390px", - specimenCss.includes("@media (max-width: 24.375rem)"), + specimenFixes.includes("@media (max-width: 24.375rem)") && + specimenFixes.includes("grid-template-columns: repeat(5, minmax(0, 1fr))"), ], [ "minimum viewport floor does not scale with text", @@ -114,8 +115,10 @@ const assertions = [ [ "responsive rail becomes compact navigation", specimenCss.includes("@media (max-width: 68rem)") && - /\.specimen-rail__context,\r?\n\s+\.specimen-rail__package/.test( - specimenCss, + specimenCss.includes(".specimen-shell {\n grid-template-columns: 1fr;") && + specimenCss.includes("@media (max-width: 48rem)") && + specimenCss.includes( + ".specimen-rail__nav {\n grid-template-columns: repeat(3, minmax(0, 1fr));", ), ], [ From ac6e247b44b3ad2b6b5e55e7c0a8284144f84f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:10:19 -0500 Subject: [PATCH 37/45] style(contracts): apply repository formatting --- scripts/verify-contracts.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index ab5cb0e..9f2e2ec 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -106,7 +106,9 @@ const assertions = [ [ "mobile layout covers 390px", specimenFixes.includes("@media (max-width: 24.375rem)") && - specimenFixes.includes("grid-template-columns: repeat(5, minmax(0, 1fr))"), + specimenFixes.includes( + "grid-template-columns: repeat(5, minmax(0, 1fr))", + ), ], [ "minimum viewport floor does not scale with text", From 3f79777e359f810616bf1b7786d5debb6741ff10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:10:54 -0500 Subject: [PATCH 38/45] chore(ci): one-shot format responsive contracts --- .../format-responsive-contracts-once.yml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/format-responsive-contracts-once.yml diff --git a/.github/workflows/format-responsive-contracts-once.yml b/.github/workflows/format-responsive-contracts-once.yml new file mode 100644 index 0000000..82624a9 --- /dev/null +++ b/.github/workflows/format-responsive-contracts-once.yml @@ -0,0 +1,34 @@ +name: Format responsive contracts once + +on: + push: + branches: + - fix/specimen-browser-shell + +permissions: + contents: write + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: fix/specimen-browser-shell + - uses: pnpm/action-setup@v4 + with: + version: 10.17.1 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm exec prettier scripts/verify-contracts.mjs --write + - name: Commit formatter output and remove helper + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git rm .github/workflows/format-responsive-contracts-once.yml + git add scripts/verify-contracts.mjs + git commit -m "style(contracts): apply repository formatter" + git push origin HEAD:fix/specimen-browser-shell From 740a1d55a36871efd18cda713f8da4560e5c100c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:11:11 +0000 Subject: [PATCH 39/45] style(contracts): apply repository formatter --- .../format-responsive-contracts-once.yml | 34 ------------------- scripts/verify-contracts.mjs | 4 ++- 2 files changed, 3 insertions(+), 35 deletions(-) delete mode 100644 .github/workflows/format-responsive-contracts-once.yml diff --git a/.github/workflows/format-responsive-contracts-once.yml b/.github/workflows/format-responsive-contracts-once.yml deleted file mode 100644 index 82624a9..0000000 --- a/.github/workflows/format-responsive-contracts-once.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Format responsive contracts once - -on: - push: - branches: - - fix/specimen-browser-shell - -permissions: - contents: write - -jobs: - format: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: fix/specimen-browser-shell - - uses: pnpm/action-setup@v4 - with: - version: 10.17.1 - - uses: actions/setup-node@v4 - with: - node-version: 24 - cache: pnpm - - run: pnpm install --frozen-lockfile - - run: pnpm exec prettier scripts/verify-contracts.mjs --write - - name: Commit formatter output and remove helper - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git rm .github/workflows/format-responsive-contracts-once.yml - git add scripts/verify-contracts.mjs - git commit -m "style(contracts): apply repository formatter" - git push origin HEAD:fix/specimen-browser-shell diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index 9f2e2ec..6a33569 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -117,7 +117,9 @@ const assertions = [ [ "responsive rail becomes compact navigation", specimenCss.includes("@media (max-width: 68rem)") && - specimenCss.includes(".specimen-shell {\n grid-template-columns: 1fr;") && + specimenCss.includes( + ".specimen-shell {\n grid-template-columns: 1fr;", + ) && specimenCss.includes("@media (max-width: 48rem)") && specimenCss.includes( ".specimen-rail__nav {\n grid-template-columns: repeat(3, minmax(0, 1fr));", From 10feeb0e10c270bcc7b725b0b7002dfe576e4db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:11:57 -0500 Subject: [PATCH 40/45] chore(ci): trigger responsive verification From f8300954a2a9e8db7a2af527e1b9d1c67de7187f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:13:07 -0500 Subject: [PATCH 41/45] chore(ci): pin verification actions --- .github/workflows/ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff838e8..a512d6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,11 +13,13 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 with: version: 10.17.1 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 24 cache: pnpm From 0b2d54a1a3b791e1de6414076d5a199ae406bd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:18:29 -0500 Subject: [PATCH 42/45] fix(specimens): contain compact rail under text zoom --- apps/specimens/src/specimens-fixes.css | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index 22b7836..af72224 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -12,6 +12,20 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { } @media (max-width: 48rem) { + .specimen-rail, + .specimen-rail__context, + .specimen-rail__intro, + .specimen-rail__nav { + width: 100%; + min-width: 0; + max-width: 100%; + } + + .specimen-rail__context, + .specimen-rail__intro { + overflow-wrap: anywhere; + } + .specimen-card > [data-slot="tabs"] { width: 100%; min-width: 0; From cbd190d3909da30567d0b2f0e2ea1d5cbd17def6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:22:11 -0500 Subject: [PATCH 43/45] fix(specimens): remove intrinsic mobile grid floors --- apps/specimens/src/specimens-fixes.css | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index af72224..1aa072d 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -11,11 +11,18 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { display: none; } +@media (max-width: 68rem) { + .specimen-shell { + grid-template-columns: minmax(0, 1fr); + } +} + @media (max-width: 48rem) { .specimen-rail, .specimen-rail__context, .specimen-rail__intro, .specimen-rail__nav { + box-sizing: border-box; width: 100%; min-width: 0; max-width: 100%; @@ -26,6 +33,10 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { overflow-wrap: anywhere; } + .catalog-group__grid { + grid-template-columns: minmax(0, 1fr); + } + .specimen-card > [data-slot="tabs"] { width: 100%; min-width: 0; @@ -76,6 +87,7 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { } .specimen-stage { + box-sizing: border-box; width: 100%; min-width: 0; min-height: 0; @@ -87,12 +99,14 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { } .specimen-stage > * { + box-sizing: border-box; width: 100%; min-width: 0; max-width: 100%; } .specimen-documentation { + box-sizing: border-box; width: 100%; min-width: 0; min-height: 0; From e56ea907d279325584e2b664ada9e58cded4dc30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:26:06 -0500 Subject: [PATCH 44/45] test(contracts): guard intrinsic mobile sizing --- scripts/verify-contracts.mjs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/verify-contracts.mjs b/scripts/verify-contracts.mjs index 6a33569..cd964e5 100644 --- a/scripts/verify-contracts.mjs +++ b/scripts/verify-contracts.mjs @@ -125,6 +125,15 @@ const assertions = [ ".specimen-rail__nav {\n grid-template-columns: repeat(3, minmax(0, 1fr));", ), ], + [ + "responsive grids remove intrinsic sizing floors", + specimenFixes.includes( + ".specimen-shell {\n grid-template-columns: minmax(0, 1fr);", + ) && + specimenFixes.includes( + ".catalog-group__grid {\n grid-template-columns: minmax(0, 1fr);", + ), + ], [ "specimen chrome avoids decorative gradients", !specimenCss.includes("gradient("), From 36c2b6371b664a5453fd143dd224ba12f667c897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=20Alexander=20=F0=9F=91=91?= Date: Sun, 30 Aug 2026 09:30:32 -0500 Subject: [PATCH 45/45] fix(specimens): harden text-resize host containment --- apps/specimens/src/specimens-fixes.css | 46 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/apps/specimens/src/specimens-fixes.css b/apps/specimens/src/specimens-fixes.css index 1aa072d..87434dd 100644 --- a/apps/specimens/src/specimens-fixes.css +++ b/apps/specimens/src/specimens-fixes.css @@ -18,28 +18,54 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { } @media (max-width: 48rem) { - .specimen-rail, + .specimen-shell { + box-sizing: border-box; + width: 100%; + min-width: 0; + max-width: 100vw; + margin-inline: 0; + } + + .specimen-rail { + box-sizing: border-box; + width: 100%; + min-width: 0; + max-width: 100%; + } + + .specimen-rail > *, .specimen-rail__context, .specimen-rail__intro, - .specimen-rail__nav { + .specimen-rail__nav, + .specimen-rail__package { box-sizing: border-box; - width: 100%; min-width: 0; max-width: 100%; } .specimen-rail__context, - .specimen-rail__intro { + .specimen-rail__intro, + .specimen-rail__package, + .specimen-rail__package code { overflow-wrap: anywhere; + word-break: break-word; } .catalog-group__grid { grid-template-columns: minmax(0, 1fr); } + .specimen-card { + box-sizing: border-box; + width: 100%; + min-width: 0; + max-width: 100%; + } + .specimen-card > [data-slot="tabs"] { width: 100%; min-width: 0; + max-width: 100%; gap: 0; } @@ -62,6 +88,7 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { > [data-slot="tabs-list"] > [data-slot="tabs-trigger"] { min-width: 0; + max-width: 100%; min-height: 2.75rem; padding: 0.625rem 0.5rem; } @@ -105,6 +132,17 @@ body:not(:has(#group-blocks)) .specimen-rail a[href="#group-blocks"] { max-width: 100%; } + .specimen-stage *, + .specimen-documentation * { + min-width: 0; + max-width: 100%; + } + + .specimen-stage :where(p, span, strong, small, code), + .specimen-documentation :where(p, span, strong, small, code) { + overflow-wrap: anywhere; + } + .specimen-documentation { box-sizing: border-box; width: 100%;