← Jeen.work / Design System
Foundations Components Dashboard

jeen design system — v0.6.4

Components

Live demos, props, usage rules, and when-not-to for every system component.

01

Button

Purpose

Calls to action — page CTAs, form submits, navigation triggers. Two variants cover the two surface contexts: primary for light surfaces, secondary for dark surfaces only. Renders as <a> when href is provided, <button> otherwise.

Props
PropTypeDefaultNotes
variant"primary" | "secondary""primary"Controls appearance and surface context
labelstringButton text content
hrefstringundefinedIf set, renders as <a>
classstringForwarded to the root element
Light surface
variant="primary"
Dark surface
variant="secondary" · dark surface only
As anchor

Renders as <a> when href is provided.

Variant → class map
VariantClassSurfaceBehaviour
primary .hero-cta-primary Light Yellow bg · hard shadow · lifts on hover
secondary .hero-cta-secondary Dark only Glass outline · white text · dark surface only
Usage rules
Rule
Use primary for the main CTA on light backgrounds (hero, playground, about)
Use secondary on --bg-dark surfaces only — hero, footer dark zones
Provide href when the action navigates; omit for form submits and JS-triggered actions
Never use primary on dark surfaces — yellow on black fails the visual hierarchy
Never use secondary on light surfaces — transparent outline with white text is invisible
Never stack two primary buttons side-by-side — one CTA per focal area
02

Badge

Purpose

Decorative label/tag pill for categorising and annotating content. Maps a variant prop to an existing homepage.css class — no new CSS is introduced. Surface context matters: verify contrast before placing a badge variant on a new surface.

Props
PropTypeDefaultNotes
variant"tag" | "diary-tag" | "work-tag" | "skill" | "coming-soon""tag"Maps to a homepage.css class
labelstringundefinedText content; coming-soon renders its own label + dot if omitted
Light surface
AI Product variant="tag"
Design variant="diary-tag"
variant="coming-soon"
Dark surface
Talk variant="work-tag"
Agentic Design variant="skill"
Variant map
VariantClassSurfaceUsed in
tag.play-card-tagLightPlayground experiment cards
diary-tag.diary-tagLightDiary card category labels
work-tag.work-tagDarkWork section row tags
skill.about-skill-tagDarkAbout section skills list
coming-soon.work-coming-soon-badgeDarkWork + Playground coming-soon items
Usage rules
Rule
Pick variant by where the badge appears — dark-surface variants (work-tag, skill) are designed for --bg-dark contexts only
Use coming-soon inline in titles — it renders its own dot + label
Never use a badge as an interactive element — it has no hover or focus state
Never invent new badge variants — extend the token set in homepage.css only if a genuine new context arises
Never use work-tag or skill on light backgrounds — contrast will fail
03

Card

Purpose

Outer container for experiment and diary content blocks. Uses a slot — no internal template is imposed. Renders as <a> when href is provided. Inner content uses existing homepage.css classes.

Props
PropTypeDefaultNotes
variant"default" | "accent" | "diary""default"Controls layout and surface treatment
hrefstringundefinedIf set, renders as <a> with hover lift
classstringForwarded to root element
slotHTMLAll card content goes in the default slot
variant="default" and variant="accent" — play card layout
AI Product

Default card

Light background, border, hard offset shadow. The standard experiment card.

Explore →
variant="default"
Experiment

Accent card

Yellow accent background. Used for highlighted or featured experiments.

Explore →
variant="accent"
variant="diary" — horizontal diary layout
04 MAY

Example diary entry title

Design 3 min read
variant="diary" · horizontal · date block + content + arrow
Variant map
VariantClassLayoutBehaviour
default .play-card Vertical · play card Light bg · border · hard shadow · lifts on hover
accent .play-card.play-card--accent Vertical · play card Yellow bg · same shape as default · featured experiments
diary .diary-card Horizontal · date + content + arrow Light bg · border · diary list rows

All variants render as <a> when href is provided. Hover: translateY(-2px) + shadow-hover.

Usage rules
Rule
Use default for experiment/playground cards in the grid
Use accent sparingly — one featured card per grid at most
Use diary for diary list rows only — it has a fixed horizontal layout
Provide href whenever the card is clickable — it semantically becomes an <a>
Never nest a card inside another card
Never use the diary variant in the experiment grid — layouts are incompatible
05

Icon Button

Purpose

Circular icon-only button. 32×32px, icon at 20×20px. Default state is transparent — no background, icon inherits --fg-primary. Hover and press show --bg-accent-dim (yellow-dim). Use for compact actions — copy, share, bookmark — where a full-width button would be too heavy.

Props
PropTypeRequiredNotes
labelstringBecomes aria-label — required for screen readers
classstringAppended to .icon-btn
slotLucide icon or inline SVGPass at size=20
Default
Copy
Share2
Bookmark
Heart
MoreHorizontal
Usage rules
Rule
Always pass label — it is the only text available to screen readers
Pass the icon at size=20 — this keeps the 6px padding on each side within the 32px circle
Use for single, compact actions near content (copy, bookmark, share, dismiss)
Never use without a label — the button has no visible text
Never pass text into the slot — this component is icon-only
Never use as a primary CTA — use Button with a label instead
06

Input

Planned Input is not yet a system component

There is no src/components/system/Input.astro yet. Input styles exist in design-system.css as demo-only classes (.ds-input, .ds-ask-bar, .ds-ask-input) but these are scoped to the DS documentation page and are not a shipped component.

When Input is promoted to a system component, it will live at src/components/system/Input.astro with props for type, label, placeholder, error, disabled, and variant (default | ask-bar). Tokens and states are already defined — see Foundations → Borders and Colors for relevant values.