# UI

## Philosophy

A developer tool people use daily to browse code and manage repos. Optimise for:

1. **Speed-first** — minimise clicks, maximise information density
2. **Scannable** — find what you need in under a second
3. **Quiet confidence** — premium without flashy; the UI should disappear
4. **Code-centric** — code is the hero, everything else supports it

| Principle | Meaning |
|---|---|
| Readable density | Compact without cramped. Maximise info per viewport. |
| Clear hierarchy | Strong contrast between labels, content, and muted elements |
| Functional spacing | 8px on items, 12–16px on sections. No wasted space. |
| Keyboard-first | Every action reachable without a mouse |
| Dark-mode primary | Developers live in dark mode. Light mode is supported, secondary. |

**Do:** small type (`text-xs` / `text-sm` for most UI), small buttons, monospace for
paths, SHAs, and branch names, opacity modifiers for text hierarchy, tight spacing.

**Don't:** large type outside page titles, shadows in dark mode (use borders), bright
backgrounds, hover animations that move or resize things.

## Where the portfolio framing bites

Steid is portfolio-first, not a Gitea clone. The profile page is the product — repos
are one kind of thing on it, alongside writing and projects. Any layout inherited from
a GitHub-shaped forge needs checking against that before it's copied.

## Stack

Settled in [0005](decisions/0005-tailwind-and-copied-components.md).

| Concern | Choice |
|---|---|
| Styling | Tailwind via Topcoat's build script — no Node |
| Theme | `styles.css` at the package root: design tokens, dark-first |
| Components | `topcoat ui add` for primitives, hand-written for Steid's own |
| Mono | IBM Plex Mono, for paths, hashes, branches, handles |

### Tokens

Defined in `styles.css` on `:root` (light) and `.dark` (dark, the default):

```
background  surface  foreground  muted-foreground
primary     primary-foreground
success     success-foreground      confirmations, git additions
warning     warning-foreground      caution, git modifications
destructive destructive-foreground  errors, git deletions
border      ring      shadow-xs  shadow-sm
```

`surface`, `success` and `warning` are Steid's additions to Topcoat's `neutral` theme;
the rest were retuned to the palette below.

**Components reference tokens, never raw colours.** A hardcoded colour will not follow
a palette change and will not adapt to the colour scheme. This is the convention to
enforce in review.

### Working on it

```bash
topcoat dev              # rebuilds CSS and re-bundles on change
topcoat asset bundle     # manual builds only; a stale bundle serves stale CSS
topcoat ui list          # what the registry offers
topcoat ui add <name>    # copies source into src/components/
```

`components.toml` is the record of what is installed; don't duplicate that list here.

**A registry component can need more than a copy.** `select` draws its chevron with an
Iconify icon, which needs the `icon-iconify` feature on `topcoat` *and* the icon set
staged in `build.rs`:

```rust
topcoat::icon::iconify::BuildConfig::new().icon_set("feather").stage().unwrap();
```

The build fails with a message naming the missing set, so it is discoverable — but the
build.rs edit is easy not to expect from a command that only advertises copying a file.
Icons are embedded at build time; nothing is fetched at runtime.

`topcoat ui add` also rewrites the module list in `src/components.rs` by appending, so
re-alphabetise it afterwards.

## Prior art

Attempt #1 (`steid-backup/AGENTS/UI.md`) has a complete 643-line design system —
OKLCH light/dark palettes with concrete token values, a type scale, spacing scale, and
component markup for sidebar, file tree, commit bar, breadcrumbs, badges, empty
states. It was written for Tailwind + DaisyUI.

Its palette has been mined already — the dark-first OKLCH values at hue 260 are what
`styles.css` was retuned to. Its component markup has not, and comes with two caveats:
it specifies DaisyUI, which is a separate choice from Tailwind and not bundled by
Topcoat; and it was written for a GitHub-shaped forge rather than a portfolio-first
one.

It is also, on its own, longer than every other doc in this directory combined — for
an app that had about nine pages. Take the palette and the principles. Don't
re-specify components before there are components.
