SCIUI · SLIDERS

Single

One handle. Toggle "Snap to whole numbers" to compare a continuous value against one snapped to a `step` grid — then cycle the accent and container controls to see the fill hold up against every page accent and every real background context.

Snap to whole numbers
Accent
Container
Grind42.0

With no step, the value is an exact float, not snapped to a grid — the same control the "Ticks & format" subpage demos with a fixed step instead of this toggle.

Live demo · sciui Slider, mode="single" (libs/sciui)
Comments & Suggestions
  • The fill accent tracks whatever the <Configurator> accent picker is set to, live — because sciui's Slider reads the page --ac directly (its default is --sci-accent: var(--ac, …)). accentVars() sets only --ac on the wrapper, and the canvas picks it up with no per-Space override. The old cv question — whether the .cv-slider specificity override was still needed — is resolved: it was DELETED 2026-07-16, sciui reads --ac for everyone.
  • First subpage refactored onto the shared <Configurator> (Phase 5 pilot) — accent + container switching is now free chrome instead of something each subpage would have to hand-build; the demo-specific control (the snap toggle) is the only bespoke part.
SCIUI · BETA DIAL

Overview

A whole Beta distribution shaped by its 90% credible interval. Drag the interval's ends to set how sure you are (narrow = many draws, wide = few); slide the band to move the success rate. α and β are solved from the two bounds and stay continuous.

Dial height260
Accent
Container
6
successes
3
fails
9
draws
64%
est. rate

The interval's width is the number of draws: pinch the ends together and the curve pulls tall and narrow; pull them apart and it flattens toward the flat prior (α=β=1). All the Beta math runs in log-space Lanczos log-Γ, so α+β stays exact into the billions.

Live demo · sciui BetaDial (libs/sciui)
Comments & Suggestions
  • Dragging the CI band and reading the CR%/stat readouts stayed in sync in this demo; no feedback-loop glitch observed. Worth a dedicated check of the direct CR% edit path specifically (typing a value rather than dragging), since that surface wasn't exercised by this static writeup and needs a live interaction pass.
  • Now on the shared <Configurator>, so the "side gauges span the full panel height" requirement can be checked directly inside every real container (card/disclosure/tabs panel), not just the plain page — flagging for a browser check across all four, at a couple of the height slider's extremes.
SCIUI · SELECTOR

Single · horizontal

The default mode: one value selected at a time, a sliding pill tracking the active option along a horizontal track.

Compact density
Accent
Container
Roastmedium

Clicking an option, or moving focus with the arrow keys, both drive the same controlled value/onValueChange pair — the pill's position is derived, not stored.

Live demo · sciui Selector, single-select, orientation="horizontal" (libs/sciui)
Comments & Suggestions
No issues found for this mode — the pill measured and repositioned correctly against every accent/container the shared <Configurator> exercises, and the compact-density toggle re-measured the pill correctly too.
SCIUI · TABS

Basic

A plain tab strip with three panels — the active indicator is a single flared-tab shape that welds into the panel below it, so the active tab reads as part of the panel rather than a separate chip.

Accent
Container

Light, medium or dark — the roast level sets the base flavour profile before origin or processing come into play.

Live demo · sciui Tabs, default size (libs/sciui)
Comments & Suggestions
No issues found for this mode — the strip, indicator weld and panel switch all behaved as documented, including nested inside the configurator's own card/disclosure/tabs container modes (tabs-inside-tabs is a real nesting case a reader might actually build).
SCIUI · SWITCH

Standalone

Used on its own as a plain settings toggle — deliberately paired with two labels of very different length ("Off" vs "Enabled") so the no-layout-shift behaviour is visible: the button's width is fixed by the wider label from the start, since both labels are always in the DOM (one just invisible).

Accent
Container
Notifications

Toggling the switch flips between "Off" and "Enabled" — watch the button's own width as the label changes: it should not resize or reflow anything around it.

Live demo · sciui Switch, standalone (libs/sciui)
Comments & Suggestions
No issues found for this mode — the two labels of unequal length render as intended, with the inactive one kept in the DOM (aria-hidden) purely to reserve width.
SCIUI · DISCLOSURE

Basic

A single expand/collapse panel — click the header to reveal its content. Unlike an accordion, one <Disclosure> is exactly one region; a consumer wanting several independent panels composes multiple instances (there is no built-in exclusive-open group behaviour).

Accent
Container
What is this?

This is the panel content. It's revealed by a pure-CSS height transition (grid-template-rows: 0fr → 1fr) — no JavaScript measures the content's height, so there's nothing to keep in sync when the content itself changes shape (e.g. on a language switch elsewhere in the app).

A second, independent panel

Opening this one has no effect on the panel above — each instance owns its own state.

Live demo · the new sciui Disclosure (libs/sciui)
Comments & Suggestions
  • This is a brand-new component built for the playground itself — no prior production usage to compare against. Its chevron/height-transition behavior should be checked in real Firefox as well as Chrome during the verification pass, per the workspace rule that Chrome's corner-shape fallback path is not a reliable proxy for Firefox's clip-path polyfill.
  • As of 2026-07-16 the Disclosure has a SINGLE radius mode — it always uses the plain, undoubled template radius. Radius doubling is reserved for cards without a visible container (FCard, sciui Card); a collapsible block can't animate coherently in the doubled composition, so it no longer has a nested prop.
SCIUI · DIALOG

Conversation interface

A bottom-anchored chat surface: a scrolling history, a status plate of live metrics, and a composer whose input and send button are visually identical to a Selector track and pill.

History
Status plate
Plate position
History background
Accent
Container
Show me revenue by region for last quarter.
Here is Q3 revenue split across the four regions — EMEA leads at 38%, followed by AMER at 34%.
Which region grew fastest year over year?
Context
2 133/ 20 000
Requests / min
3/ 5
resets in 15 s
Session
12
min elapsed
Tokens
84 213
Connectedus-east · 24 ms

Content rendering is external: every child is opaque to the Dialog. DialogMessage is the default text bubble. The status plate takes a segments array — each entry is either a template dict (title, value, optional max → bar, optional message → caption) or any custom node. The plate above shows every combination side by side, ending with a fully custom segment. Turn History off to see the landing state — just the composer, centred — then send a message and watch it glide to the bottom.

Live demo · sciui Dialog (libs/sciui) — composer geometry mirrors Selector exactly
F-ISH · TYPOGRAPHY

Headings & kicker

The three standalone heading elements, then FHeading — the canonical icon/title/kicker block used to build a page's rich rail menu item.

A standalone kicker

A standalone title

A standalone subhead

FHeading combines an optional icon, a title and a kicker into one canonical block:

Combined headingTITLE + KICKER

A Space never places this itself any more — export subtitle from a page's first subpage and the site loader (create-site.ts) builds this exact block for the rail's menu item automatically: title = the page's resolved kicker label, kicker = the subpage's subtitle, icon = the subpage's icon export. No placement flag — subtitle's mere presence is the trigger (the "subtitle-set" menu mode). This very Page does exactly that (see this subpage's own subtitle export) — check the rail: "Typography" now reads as a two-line block, not the plain pill every other Page here uses.

Live demo · f-ish FKicker, FTitle, FSubhead, FHeading (libs/f-ish)
Comments & Suggestions
  • The old heading/menu={false} export + placement-flag mechanism this subpage used to demo is GONE (2026-07-15 header/menu rework) — replaced by the inferred kicker/subtitle/icon resolution described above, and this Page's own menu item now demonstrates the subtitle-set case live (see Squircle for the icon slot, Cards & Stats for a fully custom menu export — between the three, every menu-item mode this template supports has a real, end-to-end example somewhere on this Space).
  • Deliberately NOT moved onto the shared <Configurator> (Phase 5 step 6): these are structural markup elements (kicker/title/subhead/heading), not components with tunable props — there's no real "knob" to expose beyond the text content itself, and this Page's own menu item is a live subtitle-set example that shouldn't be disturbed by wrapping its subpage content in unrelated demo chrome. Flagging this call explicitly rather than forcing it.
F-ISH · ACTIONS

Buttons

FButton — a soft pill: accent fill, crust-dark label. Like every kit element it takes an optional size step (xs·sm·md·lg·xl) via data-fsize.

Size
Accent
Container

Every step is the same component and the same markup — only the size prop changes, which rescales the button (and its label) proportionally via the shared --gt/--g scaling unit.

Live demo · f-ish FButton (libs/f-ish)
Comments & Suggestions
  • FButton has no dedicated variant prop in content.tsx — only the generic size (from the shared Sized type) plus whatever className/native button props are passed through. So the "couple of use cases" the spec asks for are shown here purely as size steps and differing labels/context, not as invented variant props.
F-ISH · CARDS & STATS

Cards

FCard is a surface-toned, soft-cornered block — plain, or in a media chip layout, or broken out to full panel width with wide. The two are independent boolean modifiers, so toggle them together to see whether the media chip layout and the full-width breakout actually compose.

Media
Wide
Accent
Container
Plain card

A default FCard with an FCardBody inside — the baseline shape, no modifiers.

Live demo · f-ish FCard/FCardBody, plain / media / wide (libs/f-ish)
Comments & Suggestions
  • content.tsx documents media and wide as independent boolean props applied as separate class modifiers (fish-card--media and fish-wide), with nothing in the source suggesting they're mutually exclusive — so combining both should just stack the classes. Now on the shared <Configurator> with both as independent toggles, so "media + wide together" is directly reachable (it wasn't in the old three-fixed-card layout) — worth a live check that the full-width breakout and the fixed-width media chip actually compose cleanly rather than assuming it from the source alone.
  • No real media asset exists in this Space yet, so the "media" slot above is a plain colour block labelled as a placeholder rather than a card thumbnail — flagging in case a future pass wants to swap in a real icon/image demo.
  • This subpage's menu export (a hand-rolled metric badge) is this Space's only live demo of fully custom menu content — see this file's own comment above it. "3" counts the card variants the two boolean toggles can reach (plain/media/wide, not counting the media+wide combination as a distinct "style") — a hand-typed number that would silently go stale if a variant is ever added or removed here.
SCIUI · CARD & CARDGRID

CardGrid

A full-width, fluid, self-balancing grid of <Card>s. Children with no expand stay a zero-cost static grid; any child carrying expand turns the whole grid into a hover/tap/focus-activated reveal — the exact mechanism cv's Home focus tiles and Portfolio hub run on.

Plain grid

No expand on any card — no state, no listeners, no measurement.

Foundations

A card is a shape: an optional title band, a body slot, up to four corner decorators.

Pipelines

An href card gets the built-in "go" chevron bottom-right FOR FREE — no decorator prop, no <CardDecorator> child, tinted by this card's own accent automatically, drawn via the built-in <Icon id="arrow" />.

Expand grid — the accent channel

Each card's own accent sets --ac on its root — everything inside inherits it. The expand block below lives OUTSIDE the card in the DOM, so the grid forwards the same card's accent onto its own reveal set. The THIRD card sets no accent at all — open it and its chips take the page's own ambient accent instead, proving the fallback holds.

Column cap — maxCols

Long, multi-paragraph card bodies read too narrow once a wide screen fits 4 columns — the fix is a column CAP the author names directly, not a min-width to guess at. maxCols={2} below never lets more than two columns form, at any viewport width, so these long bodies keep a readable measure instead of squeezing into a fourth of the row.

Data platform strategy

A durable data platform earns trust in stages: first by being correct, then by being fast, and only then by being convenient. Skipping ahead to convenience — nice dashboards over ungoverned, unvalidated pipelines — is the most common way teams end up re-litigating "which number is right" in every planning meeting.

The unglamorous work is schema contracts, tested transformations, and a single source of truth for each metric's definition, published somewhere every stakeholder can actually find it before they build their own spreadsheet version.

Experimentation culture

Running more A/B tests is not the same as learning faster. A team that ships ten underpowered tests a quarter and calls every marginal p-value a win is optimizing for the appearance of rigor, not for decisions that would have gone differently without the data.

The higher-leverage habit is pre-registering what would change your mind, sizing the test to actually detect that effect, and being willing to report a clean null result as a genuine, useful outcome rather than a failure to be quietly shelved.

Onboarding new analysts

The fastest ramp isn't a wiki page, it's a first real ticket paired with someone who already knows where the landmines are — which tables are deprecated but still queried by legacy dashboards, which metric names mean two different things in two different teams, which joins silently fan out rows.

Write that landmine list down as you go, even informally; the second new hire should never have to rediscover the same trap the first one just fell into.

maxCols is pure CSS — it sets --card-grid-maxcols inline, no JS layout logic, so the mobile single-column mode below the container breakpoint is completely untouched; the cap only ever governs the WIDE-mode column count.

Corner decorators — the Icon system

A <CardDecorator corner="tl|tr|bl|br" icon={…} background={…} /> is a slot CHILD — declared inside a card's own children but never itself rendered; the card reads it off the tree and positions it, radius concentric with its own corner in every case, symmetric at all four. The icon is sized as a FRACTION of the decorator's own box (60%, bold on purpose — never a fixed em/px), and each one below is sciui's own <Icon id="arrow" /> — a Phosphor glyph resolved against the generated registry (see NOTES.md § Icon system); it paints currentColor, so it inherits the decorator's own accent automatically. An href card shows the built-in "go" chevron bottom-right automatically (see the Pipelines card above) — an explicit decorator prop or a corner="br" child, like below, overrides it; none of these four cards has an href, so nothing here is a default, every decorator below was asked for.

Top-left

Inset one gap from the card's own top-left corner.

Top-right

Top-right.

Bottom-left

Bottom-left.

Bottom-right

Bottom-right — where the built-in nav default and the legacy decorator prop both land.

Bare decorators & hover FX

bare renders NO squircle plate at all — icon only, same position, same size box, just no fill at rest or on hover (cv's Home tiles use this for their six meaning-icons). hoverFx picks the hover motion, author-selectable, default 'grow': 'grow' transitions the ICON's own width/height inside its fixed, centred box; 'shift-right' is a ± margin pair sliding the icon rightward (the box itself never resizes); 'none' is static. Both motion variants are compositor-legal — never transform/filter — gated to real pointer hover with prefers-reduced-motion: no-preference. Hover each card below to feel the difference (mouse only — try each on a real pointer device).

Body lists

A plain <ul>/<li> in a card body needs no classes — compact spacing, a marker in the same muted tone as the body text.

What this covers
  • Compact spacing on the card's own flow rhythm — no browser-default oversized gaps.
  • A marker colour that matches the muted body tone, not full-strength ink.
  • The same inline text-inset a body <p> gets, so it aligns identically.

Disabled

disabled renders a plain, non-interactive element regardless of href/onClick — no hover lift, no cursor affordance, and no automatic nav chevron either. cv's Portfolio uses this for demos that exist but aren't public, wearing a static <Icon id="lock" /> decorator instead (see "No motion" above).

Not available

This card fronts nothing reachable — it never lifts, never gets a pointer cursor.

Live demo · sciui Card/CardGrid — accent, corner decorators, bare mode, hover FX, the Icon system, body lists, disabled (libs/sciui)
Comments & Suggestions
  • The four corner-decorator squircle clips (Firefox fallback path) should be checked in real headless Firefox per the workspace's standing rule — Chrome's native corner-shape path can't stand in as a proxy for the clip-path polyfill.
  • The "no accent set" card's expand chips should visibly render TEAL (this page's own accent) — worth confirming live, since it's the one behaviour that's easy to get backwards (accidentally always forwarding SOME colour rather than truly setting nothing).
  • Not demoed here: a card that is BOTH href and disabled (cv's Portfolio never combines them) should show no chevron at all — Card's default-nav check is gated on !disabled, but worth a live confirmation since it's an easy corner to miss.
  • Not wrapped in the shared <Configurator> — this page is several distinct fixed illustrations (plain / expand / decorators / disabled), not one configurable instance, the same call the Chips & Stats page made for its own multi-accent chip row.
F-ISH · SEGMENTED

FSegmented

A self-contained segmented switcher — pass options, a controlled value, and onValueChange; the sliding pill and its settle-recoil come for free.

Accent
Container
Roastmedium

Under the hood FSegmented mounts its own Tabs.Root and hands the bare SegmentedList the activeValue it needs for the recoil — see the "Bare list & shadows" subpage for the same visual composed manually.

Live demo · f-ish FSegmented (libs/f-ish)
Comments & Suggestions
  • No issues found for this mode — options/value/onValueChange is a small, ordinary controlled-component surface, and the pill's settle-recoil direction is derived internally from the value change, so there's nothing for a consumer to get wrong here.
F-ISH · SQUIRCLE

Shapes

FSquircle renders any element (as) with superellipse corners — native corner-shape where supported, a Lamé clip-path polyfill elsewhere. Each box below is filled so the corner curve is visible.

as="div" · squircle=1.5
as="button" · squircle=1.5
as="a" · squircle=3 (boxier)
as="div" · squircle=3

Corner shape depends only on border-radius plus squircle — the polyfill traces the identical curve from those two inputs, so it works on any element the as prop names.

Live demo · f-ish FSquircle (libs/f-ish)
Comments & Suggestions
  • No issues found for this mode — as/squircle are a clean, small surface, and forwarding a ref plus spreading the rest of the props means any native element attribute (like the button's implicit type or the anchor's href) just works without special-casing in FSquircle itself. To check: the exact corner curve at squircle=3 vs 1.5 in real Firefox, per the workspace rule that Chrome's fallback path isn't a reliable proxy for the clip-path polyfill.
  • This subpage's icon export (a tiny FSquircle swatch) is this Space's only live demo of the menu-item icon slot (default rendering) — check the rail: "Squircle" shows the mark instead of its padded page number.
  • Deliberately NOT moved onto the shared <Configurator> (Phase 5 step 6): the point is four DIFFERENT host elements (div/button/a) shown together to prove as genuinely works on any of them — a single-instance picker would still need to render one element at a time, losing the simultaneous cross-element comparison. The "Superellipse support" subpage covers the single-instance, tunable-exponent case instead. Flagging this call explicitly rather than forcing it.
PLAYGROUND · PALETTE LAB

Composition

Pick the page's own accent — including "None," the template's real accent-less mode — then a container and an inner element (each independently accented) to check any nesting/coloring combination the template can produce. "Nested container" as the element reveals a second, inner container + element pair — exactly two levels, no further nesting.

Page accent
Container
Container accent
Element
Element accent

Every container is a real, reusable primitive (FCard, sciui Disclosure, sciui Tabs) — none of this composition logic is a new component; it only decides which existing one to render and how to accent it. The page accent above is the real thing (useFPageAccent()), so "None (plain page)" as the container reads exactly as it would on any real page of that accent.

Live demo · a Space-local composition harness (playground/_container-lab.tsx)
Comments & Suggestions
  • Nesting is fixed at exactly two levels (outer + one inner container/element pair, per the owner's brief) — all controls for both layers live together in the controls panel above the preview, never inside the rendered container itself.
  • The page-accent picker is a genuine template extension, not a Space-local trick: `useFPageAccent()` is exported from `f-ish` itself (`stage.tsx`'s new `FPageAccentContext`, backed by a per-page override registry on the ROOT context, `shell.tsx`), one provider per page, so only this page's accent changes. Choosing an accent (including "None") recolors this page's background AND the rail's own docking indicator — they share the same registry the indicator already read from a page's static configured accent.
  • sciui controls don't pick up the page's --ac accent on their own (they read their own --sci-accent) — this lab's CONTAINER/ELEMENT accent pickers set both together per subtree (`accentVars()`), but the page-accent change above only sets the real `--ac` (matching what a real Page does) and does not also drive `--sci-accent` — so any bare sciui control on this page outside `ContainerLab` (e.g. these picker rows themselves) won't visibly track the page accent. Consistent with how every other Space's sciui usage already works, but worth flagging since this page makes accent-tracking gaps very visible by design.
F-ISH · FLOW

Container-owned rhythm

Kit prose owns no block margins; the CONTAINER spaces its children by one step (--flow), with a few tight exceptions (kicker→title, title→lead, text→note). The same mixed document below reads with identical rhythm in every container — the reading column, a card, a disclosure, a tabs panel — because the container, not the element, owns it.

Default everywhere (Phase 7c) — no .fish-flow wrapper needed; every content container is a rhythm owner.

In the page reading column

DESIGN SYSTEM · RHYTHM

Container-owned spacing

A short standfirst, sized as a lead paragraph — the intro line under the title.

First body paragraph. Prose primitives (FText) and sciui components interleave below so the vertical rhythm between unlike neighbours is directly visible.

A second paragraph, so paragraph-to-paragraph spacing is on show too.

A note annotating the paragraph directly above it — a tight pair.
A Selector between prose

Body copy sitting between two sciui controls — each gets the same gap a paragraph would.

Inside the four containers

The identical document, dropped into each surface — the rhythm does not change with the container.

FCard · .fish-card-body
DESIGN SYSTEM · RHYTHM

Container-owned spacing

A short standfirst, sized as a lead paragraph — the intro line under the title.

First body paragraph. Prose primitives (FText) and sciui components interleave below so the vertical rhythm between unlike neighbours is directly visible.

A second paragraph, so paragraph-to-paragraph spacing is on show too.

A note annotating the paragraph directly above it — a tight pair.
A Selector between prose

Body copy sitting between two sciui controls — each gets the same gap a paragraph would.

Disclosure · .sciui-disclosure-panel-inner
Open the mixed document
DESIGN SYSTEM · RHYTHM

Container-owned spacing

A short standfirst, sized as a lead paragraph — the intro line under the title.

First body paragraph. Prose primitives (FText) and sciui components interleave below so the vertical rhythm between unlike neighbours is directly visible.

A second paragraph, so paragraph-to-paragraph spacing is on show too.

A note annotating the paragraph directly above it — a tight pair.
A Selector between prose

Body copy sitting between two sciui controls — each gets the same gap a paragraph would.

Tabs · .sciui-tabs-content
DESIGN SYSTEM · RHYTHM

Container-owned spacing

A short standfirst, sized as a lead paragraph — the intro line under the title.

First body paragraph. Prose primitives (FText) and sciui components interleave below so the vertical rhythm between unlike neighbours is directly visible.

A second paragraph, so paragraph-to-paragraph spacing is on show too.

A note annotating the paragraph directly above it — a tight pair.
A Selector between prose

Body copy sitting between two sciui controls — each gets the same gap a paragraph would.

Nested FCard · rhythm at depth

An outer card paragraph.

DESIGN SYSTEM · RHYTHM

Container-owned spacing

A short standfirst, sized as a lead paragraph — the intro line under the title.

First body paragraph. Prose primitives (FText) and sciui components interleave below so the vertical rhythm between unlike neighbours is directly visible.

A second paragraph, so paragraph-to-paragraph spacing is on show too.

A note annotating the paragraph directly above it — a tight pair.
A Selector between prose

Body copy sitting between two sciui controls — each gets the same gap a paragraph would.

Each container owns its own rhythm — nesting does not compound the step.

Re-tuning the step on a scope

.fish-flow is an explicit rhythm scope: set --flow on it to retune. Below, the same document runs at a looser step (1.4·--gt) — the tight pairs open up proportionally, because --flow-tight is derived from --flow.

DESIGN SYSTEM · RHYTHM

Container-owned spacing

A short standfirst, sized as a lead paragraph — the intro line under the title.

First body paragraph. Prose primitives (FText) and sciui components interleave below so the vertical rhythm between unlike neighbours is directly visible.

A second paragraph, so paragraph-to-paragraph spacing is on show too.

A note annotating the paragraph directly above it — a tight pair.
A Selector between prose

Body copy sitting between two sciui controls — each gets the same gap a paragraph would.

Live demo · f-ish Flow (libs/f-ish styles/flow.css)
Comments & Suggestions
  • Rhythm owners are the CONTENT wrappers, one per container: .fish-col, .fish-card-body, .sciui-card-body, .sciui-disclosure-panel-inner, .sciui-tabs-content, plus the explicit .fish-flow scope. sciui is styled host-side from f-ish (same direction as --sciui-text-inset) — the sciui repo is untouched.
  • One knob: --flow (base step, ≈ 0.7·--gt); the tight-pair step is --flow / 2, so retuning the base carries the exceptions with it. Tight pairs: kicker→title, title→lead, text→note. Everything else, prose or component, takes the base step.
  • Check in real Firefox as well as Chrome. Watch the flush behaviour at each container edge: Flow zeroes the first child's top margin and the last child's bottom margin, so content sits flush to the container padding.
  • A custom wrapper (a plain <div> the author adds) becomes a rhythm island — only rhythm owners space their children. Add fish-flow to such a wrapper to opt it back into rhythm. Docs (DESIGN.md/NOTES) land in Phase 7d, after the visual pass.