R0: design foundations — reference tokens, motion set, lucide primitives
- globals.css @theme merged with the measured reference system (docs/tokens.css): hover/divider/subtle-fg colors, cream + bubble tokens, squircle/toggle radii, spec-verbatim shadow set (bubble, card, dialog, dock-tile, CTA glow, launcher glow, screen-card ambient, dock capsule), marketing light palette, default 0.25s ease-app transition tokens. Legacy aliases (--color-accent, --spacing-rail/panel-*) retained so existing classes keep working - motion.css: full app-shell choreography (zoom-in/out from tile origin w/ --app-origin-scale, push/pop slides, cross-fade) + messageSlideIn, create-claw step/swatch, device-* set — keyframes verbatim from docs/motion.md - lucide-react installed (ISC). New tested primitives: Button (cream/ coral/ghost/icon/launcher variants per measured states), GradientGlyph (per-instance coral linearGradient stroke, the reference glyph technique), SegmentedTabs, Card + SectionLabel + GroupedRows, SearchPill; Avatar extended (squircle r17, rail/chat/welcome sizes, online-dot overlay) 82 unit tests; functional e2e suite green (visual baselines regenerate in R7). Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
447f7039d8
commit
3ec1d3b829
@@ -0,0 +1,42 @@
|
||||
"use client";
|
||||
|
||||
interface SegmentedTabsProps {
|
||||
tabs: readonly string[];
|
||||
active: string;
|
||||
onChange: (tab: string) => void;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
/* Segmented pill tabs (measured): active = raised filled chip, inactive =
|
||||
muted text; the whole group sits in a rounded container. */
|
||||
export function SegmentedTabs({
|
||||
tabs,
|
||||
active,
|
||||
onChange,
|
||||
label,
|
||||
}: SegmentedTabsProps) {
|
||||
return (
|
||||
<div
|
||||
role="tablist"
|
||||
aria-label={label}
|
||||
className="inline-flex gap-1 rounded-radius-button bg-subtle p-1"
|
||||
>
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={tab === active}
|
||||
onClick={() => onChange(tab)}
|
||||
className={`rounded-radius-button px-3 py-1 text-xs font-medium transition-colors duration-normal ease-app ${
|
||||
tab === active
|
||||
? "bg-surface-warm-muted text-foreground"
|
||||
: "text-muted-foreground hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user