Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Custom themes are CSS-first. Partial overrides inherit the remaining defaults. A

- Surfaces: `--bits-surface`, `--bits-panel`, `--bits-raised`, `--bits-muted`.
- Borders: `--bits-line`, `--bits-line-strong`.
- Foreground: `--bits-ink`, `--bits-text`, `--bits-text-soft`, `--bits-text-muted`, `--bits-text-faint`.
- Foreground: `--bits-ink`, `--bits-text`, `--bits-text-soft`, `--bits-text-dim`, `--bits-text-muted`, `--bits-text-faint`.
- Brand: `--bits-primary`, `--bits-primary-soft`, `--bits-primary-shadow`.
- Status: `--bits-amber`, `--bits-success`, `--bits-danger`, `--bits-danger-soft`, `--bits-danger-shadow`.
- Effects: `--bits-shadow`, `--bits-backdrop`.
Expand Down Expand Up @@ -188,11 +188,12 @@ Use block `Code` for preformatted machine text and inline `Code` for short ident

### Typography

Use `Heading` with levels 1–6 and `Text` with sizes `body`, `small`, `caption`, or `label`. Text tones are `default`, `soft`, `muted`, and `faint`.
Use `Heading` with levels 1–6 and `Text` with sizes `body`, `small`, `caption`, or `label`. Text tones are `default`, `soft`, `dim`, `muted`, and `faint`.

- Choose heading levels by document structure, not desired visual size.
- Use `label` for compact metadata and control labels, not paragraphs.
- Use `muted` and `faint` only for genuinely secondary content.
- Use `dim` for readable subordinate interface text such as inactive navigation.
- Use `muted` for metadata and placeholders, and `faint` only for nonessential decorative text.
- Do not apply display typography to long body copy.

### Input and Textarea
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,16 @@ The stylesheet bundles Latin JetBrains Mono and Silkscreen font files. CSS custo
--bits-primary-shadow: #15576b;
--bits-surface: #081015;
--bits-panel: #0c1820;
--bits-text-dim: #9ab6c2;
}
```

Built-in themes are `ember` (the warm, orange original) and `ocean` (blue/cyan). Apply one with `data-bits-theme="ocean"` on ordinary HTML, or use `ThemeProvider` when scoped themes and portalled components are needed.

The public variables cover surfaces, borders, text, semantic colors, shadows and backdrops, typography, font sizes, spacing, border width, and focus rings. Every public variable is prefixed with `--bits-`.

Use `--bits-text-dim` for readable subordinate interface text, such as inactive navigation; reserve `--bits-text-muted` for supporting metadata and placeholders.

The theme's bare-element typography and link rules are low-specificity defaults built
with `:where()`. A single application class can therefore override them without selector
duplication or `!important`.
Expand Down
Binary file added docs/evidence/issue-11-text-ramp-ember.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/evidence/issue-11-text-ramp-ocean.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/components/Typography.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,25 @@ export const Scale: Story = {
<Heading level={6}>heading six · label</Heading>
<Text>Body text uses JetBrains Mono with a readable 1.65 line height.</Text>
<Text size="small" tone="soft">Small supporting copy.</Text>
<Text size="small" tone="dim">Readable subordinate interface text.</Text>
<Text size="caption" tone="muted">Caption and metadata copy.</Text>
<Text as="span" size="label" tone="muted">uppercase label</Text>
</div>
)
};

export const ToneRamp: Story = {
render: () => (
<div className="story-stack">
<Text tone="default">Default · primary content</Text>
<Text tone="soft">Soft · secondary readable content</Text>
<Text tone="dim">Dim · subordinate navigation and interface text</Text>
<Text tone="muted">Muted · supporting metadata and placeholders</Text>
<Text tone="faint">Faint · lowest-emphasis decorative text</Text>
</div>
),
};

export const NativeElements: Story = {
render: () => (
<div className="story-stack">
Expand Down
3 changes: 2 additions & 1 deletion src/components/Typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ export function Heading({ level = 2, className, ...props }: HeadingProps) {

export type TextSize = 'body' | 'small' | 'caption' | 'label';
export type TextElement = 'p' | 'span' | 'div' | 'label' | 'code';
export type TextTone = 'default' | 'soft' | 'dim' | 'muted' | 'faint';

export interface TextProps extends ComponentPropsWithoutRef<'p'> {
as?: TextElement;
size?: TextSize;
tone?: 'default' | 'soft' | 'muted' | 'faint';
tone?: TextTone;
children?: ReactNode;
}

Expand Down
7 changes: 5 additions & 2 deletions src/components/components.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ describe('display components', () => {
it('exposes only live Ember and Ocean theme tokens', () => {
expect(builtInThemes).toEqual(['ember', 'ocean']);
expect(colors.primary).toBe('var(--bits-primary)');
expect(colors.textDim).toBe('var(--bits-text-dim)');
expect(stylesheet).toContain('--bits-text-dim: #a9a394');
expect(stylesheet).toContain('--bits-text-dim: #9ab6c2');
});

it('exposes semantic progress values', () => {
Expand All @@ -190,9 +193,9 @@ describe('display components', () => {
});

it('renders semantic typography', () => {
render(<><Heading level={3}>Section</Heading><Text tone="muted">Supporting copy</Text></>);
render(<><Heading level={3}>Section</Heading><Text tone="dim">Subordinate navigation</Text></>);
expect(screen.getByRole('heading', { level: 3 })).toHaveClass('bits-heading--3');
expect(screen.getByText('Supporting copy')).toHaveClass('bits-text--muted');
expect(screen.getByText('Subordinate navigation')).toHaveClass('bits-text--dim');
});

it('keeps a semantic table inside a named keyboard-scrollable region', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/stories/Theme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ complete color theme, define every token in the color table below.

--bits-text: #f4f4ff;
--bits-text-soft: #cccced;
--bits-text-dim: #adadd2;
--bits-text-muted: #9696bd;
--bits-text-faint: #707095;

Expand Down Expand Up @@ -121,6 +122,7 @@ a stable selector or application state value:
<tr><td><code>--bits-danger-shadow</code></td><td>Pressed and dimensional danger shadow</td></tr>
<tr><td><code>--bits-text</code></td><td>Primary text</td></tr>
<tr><td><code>--bits-text-soft</code></td><td>Secondary readable text</td></tr>
<tr><td><code>--bits-text-dim</code></td><td>Readable subordinate navigation and interface text</td></tr>
<tr><td><code>--bits-text-muted</code></td><td>Supporting and placeholder text</td></tr>
<tr><td><code>--bits-text-faint</code></td><td>Lowest-emphasis decorative text</td></tr>
<tr><td><code>--bits-shadow</code></td><td>General component shadow color</td></tr>
Expand Down
1 change: 1 addition & 0 deletions src/stories/story.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ body { margin: 0; background: var(--bits-surface); color: var(--bits-text); }
--bits-primary: #8f8fff;
--bits-primary-soft: #c2c2ff;
--bits-primary-shadow: #35357e;
--bits-text-dim: #adadd2;
}
@media (max-width: 600px) { .story-shell { padding: 16px; } }
3 changes: 3 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
--bits-danger-soft: #ff8b72;
--bits-text: #f2ede1;
--bits-text-soft: #c9c3b4;
--bits-text-dim: #a9a394;
--bits-text-muted: #8f8a7c;
--bits-text-faint: #6f6a5e;
--bits-shadow: rgba(0, 0, 0, .5);
Expand Down Expand Up @@ -83,6 +84,7 @@
--bits-danger-soft: #ff9b9c;
--bits-text: #edfaff;
--bits-text-soft: #bad3dc;
--bits-text-dim: #9ab6c2;
--bits-text-muted: #7fa2b0;
--bits-text-faint: #587783;
}
Expand Down Expand Up @@ -178,6 +180,7 @@
.bits-text--label { font-size: var(--bits-font-size-label); line-height: 1.4; letter-spacing: .18em; text-transform: uppercase; }
.bits-text--default { color: var(--bits-text); }
.bits-text--soft { color: var(--bits-text-soft); }
.bits-text--dim { color: var(--bits-text-dim); }
.bits-text--muted { color: var(--bits-text-muted); }
.bits-text--faint { color: var(--bits-text-faint); }
.bits-theme :where(small) { color: var(--bits-text-muted); font-size: var(--bits-font-size-caption); line-height: 1.5; }
Expand Down
1 change: 1 addition & 0 deletions src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const colors = {
dangerSoft: 'var(--bits-danger-soft)',
text: 'var(--bits-text)',
textSoft: 'var(--bits-text-soft)',
textDim: 'var(--bits-text-dim)',
textMuted: 'var(--bits-text-muted)',
textFaint: 'var(--bits-text-faint)',
} as const;
Expand Down