Bristlenose Design System — Style Guide

Layer 0

## Design Tokens

The single source of truth for all visual decisions. Override these CSS custom properties to create a custom theme. Dark mode uses `light-dark()` with the `color-scheme` property — no JS required.

### Colour palette

--bn-colour-bg#ffffff
--bn-colour-text#1a1a1a
--bn-colour-muted#6b7280
--bn-colour-border#e5e7eb
--bn-colour-accent#2563eb
--bn-colour-quote-bg#f9fafb
--bn-colour-badge-bg#f3f4f6
--bn-colour-badge-text#374151

### Sentiment colours (v0.7+ taxonomy)

frustration#ea580c / #fff7ed
confusion#dc2626 / #fef2f2
doubt#7c3aed / #f5f3ff
surprise#d97706 / #fffbeb
satisfaction#16a34a / #f0fdf4
delight#059669 / #ecfdf5
confidence#2563eb / #eff6ff

### Spacing scale

### Border radii

sm 3px
md 6px
lg 8px
pill

### Typography

Body: Inter, Segoe UI, system-ui
Mono: SF Mono, Fira Code, Consolas

File: `tokens.css` — 329 lines, all CSS custom properties.

Layer 1

## Atoms

The smallest, indivisible building blocks. Each atom is a single CSS file in `bristlenose/theme/atoms/`. Atoms never compose other atoms — they only reference design tokens.

narration frustration delight confidence
Badge (sentiment)
atoms/badge.css
.badge .badge-{sentiment}
usability emotion task flow + add tag
Badge (user tags + add)
atoms/badge.css
.badge-user .badge-add
Toolbar button
atoms/button.css
.toolbar-btn .toolbar-btn-toggle
star & pencil
Icon buttons (star, pencil)
atoms/button.css
.star-btn .edit-pencil
Tag input
atoms/input.css
.tag-input-box .tag-input
[02:34] [14:07]
Timecode
atoms/timecode.css
.timecode .timecode-bracket
frustration
12
delight
7
Histogram bar
atoms/bar.css
.sentiment-bar .sentiment-bar-label .sentiment-bar-count
quote extent indicators
Span bar
atoms/span-bar.css
.span-bar
Copied to clipboard
Toast notification
atoms/toast.css
.bn-toast

### Delete tag?

Remove “usability” from all quotes?

Modal + buttons
atoms/modal.css
.bn-modal .bn-btn .bn-btn-primary .bn-btn-danger

Also: `atoms/logo.css` (logo image + logotype), `atoms/footer.css` (footer layout), `atoms/interactive.css` (generic interactive states).

Layer 2

## Molecules

Groups of atoms that act as a single functional unit. Each molecule combines two or more atoms into a reusable component. Files live in `bristlenose/theme/molecules/`.

frustration usability emotion + add
Badge row
molecules/badge-row.css
.badges
[02:34] I couldn't find the settings menu anywhere
— p1
frustration
Quote with actions
molecules/quote-actions.css
.quote-row .quote-text .speaker
Search filter
molecules/search.css
.search-container .search-toggle .search-input
Tag filter dropdown
molecules/tag-filter.css
.tag-filter-menu .tag-filter-item
Sarah Chen ✎
—
Unnamed ✎
Name edit cell
molecules/name-edit.css
.name-cell .name-text .name-pencil .unnamed
Navigation Issues
frustration usability
Transcript annotation
molecules/transcript-annotations.css
.segment-margin .margin-label .margin-tags

Also: `molecules/bar-group.css` (histogram bar group), `molecules/tag-input.css` (tag autocomplete), `molecules/hidden-quotes.css` (hidden quote badge + dropdown), `molecules/help-overlay.css` (keyboard help), `molecules/feedback.css` (feedback form).

Layer 3

## Organisms

Complex components composed of molecules and atoms, forming distinct sections of the interface. Files live in `bristlenose/theme/organisms/`.

[02:34]
I kept clicking on the logo expecting it to take me home but nothing happened
— p1
frustration navigation + add
Blockquote (full quote card)
organisms/blockquote.css
.blockquote .star-btn .edit-pencil .badges .badge-add
Toolbar (report page)
organisms/toolbar.css
.toolbar .search-toggle .view-switcher-btn .toolbar-btn
frustration
12 confusion
7 doubt
4
Sentiment chart
organisms/sentiment-chart.css
.sentiment-chart .sentiment-row
UX Issues
navigation usability discoverability
Codebook group card
organisms/codebook-panel.css
.codebook-group .group-header .tag-row

Also: `organisms/coverage.css` (transcript coverage details), `organisms/toc.css` (table of contents navigation).

Layer 4

## Templates

Page-level layout that places organisms, molecules, and atoms into a structure. Templates define the skeleton — where things go, not what they contain. Files live in `bristlenose/theme/templates/`.

File | Page | Key layout decisions
--- | --- | ---
`templates/report.css` | Main report | Max-width constraint (52rem), article centering, header with logo + metadata, section spacing, blockquote grid
`templates/transcript.css` | Per-session transcript | Segment layout with speaker codes, right-margin annotation column (absolute on wide ≥ 1100px, inline on narrow), anchor-highlight animation, moderator de-emphasis
`templates/print.css` | Print / PDF export | Forces light colour-scheme, hides toolbar/footer/navigation, adjusts page margins

Layer 5

## Pages

Specific instances of templates filled with real content. These are the three HTML pages Bristlenose generates, each with its own JS module set.

Page | File | JS modules | Description
--- | --- | --- | ---
Report | `bristlenose-{slug}-report.html` | 18 modules (storage → main) | Main research report with extracted quotes, themes, sentiment histograms, search, tag filter, view switcher, inline editing, keyboard navigation
Transcript | `sessions/transcript_s{n}.html` | 5 modules (storage → transcript-annotations) | Per-session transcript with timecoded segments, speaker codes, right-margin annotations with span bars, deep-linking
Codebook | `codebook.html` | 4 modules (storage → codebook) | Standalone tag taxonomy page with drag-drop organisation, colour-coded groups, inline editing, cross-window sync

Reference

## Complete file map

Layer | File | Primary components
--- | --- | ---
Tokens | `tokens.css` | All CSS custom properties (colours, spacing, radii, transitions, dark mode)
Atoms | `atoms/badge.css` | Badge base, sentiment variants, user tags, AI tags, add-tag, animations
`atoms/button.css` | Toolbar buttons, star, pencil, restore, toggle variant
`atoms/input.css` | Tag input box, ghost completion layer, sizer
`atoms/bar.css` | Histogram bars, counts, labels, delete button
`atoms/timecode.css` | Timecode links, brackets
`atoms/span-bar.css` | Vertical extent indicator bars
`atoms/modal.css` | Overlay, modal card, action buttons
`atoms/toast.css` | Clipboard feedback toast
`atoms/logo.css` | Logo image, logotype text
`atoms/footer.css` | Footer layout, links
`atoms/interactive.css` | Generic interactive element states
Molecules | `molecules/badge-row.css` | Flex row of badges
`molecules/bar-group.css` | Histogram bar group (`display: contents`)
`molecules/quote-actions.css` | Quote text, speaker, edited states
`molecules/tag-input.css` | Tag input with autocomplete dropdown
`molecules/name-edit.css` | Participant name cells with pencil-on-hover
`molecules/search.css` | Expanding search field with clear button
`molecules/tag-filter.css` | Tag filter dropdown with checkboxes
`molecules/hidden-quotes.css` | Hidden quote badge, dropdown preview
`molecules/help-overlay.css` | Keyboard shortcut help modal
`molecules/feedback.css` | Feedback form (sentiment + textarea)
`molecules/transcript-annotations.css` | Right-margin annotations, span bars
Organisms | `organisms/blockquote.css` | Full quote card with all actions
`organisms/toolbar.css` | Report toolbar layout, view switcher
`organisms/sentiment-chart.css` | Side-by-side histogram layout
`organisms/coverage.css` | Transcript coverage details
`organisms/toc.css` | Table of contents navigation
`organisms/codebook-panel.css` | Codebook group grid, drag-drop, inline edit
Templates | `templates/report.css` | Report page layout
`templates/transcript.css` | Transcript page layout
`templates/print.css` | Print overrides