Files
imap-copier/DESIGN.md
T
2026-07-03 11:18:40 +07:00

118 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design
Terminal / ops-console visual language for an IMAP migration tool. Near-black,
green-tinted dark surface; a single amber functional accent; monospaced body with
a condensed display face for headings. Dense, instrument-panel layouts where the
system state is always legible. Captured from `web/src/index.css` and
`web/src/app.css` — these tokens are canonical; new work extends them, it does not
replace them.
## Theme
Dark, committed. Not "dark to look cool" — the scene is an operator running a
long-lived migration and watching thousands of counters tick; a dark console
keeps the amber accent and the ok/fail/pending signal colors doing the reading
work with minimal eye strain. Color strategy: **restrained** — tinted neutrals
carry the surface, one amber accent stays under ~10% of the pixels, and the
green/red/yellow/blue roles appear only as status semantics.
Signature textures (keep, don't multiply):
- A faint amber radial glow at the top of the page (`radial-gradient` at 50% -10%).
- A 3px repeating-linear scanline overlay at ~1.2% white — the CRT tell.
- Panels wear a floating uppercase tab label (`.panel-label`) punched through the
border; the log panel mirrors it on the right (`.log-clear`).
## Color
OKLCH is the target space for any new color; existing tokens are hex and stay hex.
### Surfaces (green-tinted neutrals, darkest → raised)
- `--bg` `#0a0d0b` — page base
- `--bg-inset` `#070a08` — insets: inputs, progress track, log pane
- `--bg-panel` `#0f1512` — panels, cards, login card
- `--bg-panel-raised` `#141b17` — topbar, table headers, modal dialog
### Borders
- `--border` `#23342b` — default hairline (1px)
- `--border-bright` `#3a5443` — raised/interactive edges, dashed underlines
### Ink
- `--fg` `#dbe8de` — primary text
- `--fg-dim` `#6f8478` — labels, secondary text, nav idle
- `--fg-faint` `#4a5c50` — hints, empty states, faint indices
### Accent (amber — attention & primary action)
- `--accent` `#ffb238` — primary buttons, active nav, panel labels, progress fill
- `--accent-strong` `#ffd27a` — hover/emphasis
- `--accent-dim` `#7a5a26` — active borders, tinted glows
- Primary-button ink is near-black `#1a1200` on amber, never white.
### Status semantics (color always carries meaning)
- `--ok` `#52e6a0` / `--ok-dim` `#234a37` — success (glowing dot)
- `--fail` `#ff5d5d` / `--fail-dim` `#4a2323` — error
- `--pending` `#f0c419` — waiting/queued
- `--info` `#57c2ff` — in-progress / scan / new-folder marker (pulsing dot)
> Contrast watch: `--fg-dim` on `--bg-panel` is the thinnest pairing — for real
> body copy (not just uppercase micro-labels) prefer `--fg`. Placeholder and
> small print must still clear AA; don't push text below `--fg-faint`.
## Typography
Two families on a real contrast axis (mono vs. condensed display) — never two
similar sans.
- **Body / UI / data:** `--font-mono` = JetBrains Mono (400/500/700), 14px base,
line-height 1.5. Numbers use `font-variant-numeric: tabular-nums`
(`.mono-num`, `.num-cell`, stat values) so columns align.
- **Display / headings / brand:** `--font-display` = Big Shoulders Display
(600/800), uppercase, letter-spacing ~0.30.5px. Page titles 34px, brand 22px,
login brand 30px.
- **Micro-labels:** uppercase, 1012px, letter-spacing 0.080.14em, `--fg-dim`.
This is the workhorse label style (nav, field labels, badges, table headers,
panel tabs). Used as a deliberate system, not a per-section eyebrow.
## Components
- **Panels** (`.panel`): bordered surface, 3px radius, floating uppercase tab
label. The primary content container — used instead of stacked cards.
- **Buttons**: `.btn` (ghost outline, uppercase, 2px radius) · `.btn-primary`
(solid amber, dark ink, amber glow on hover) · `.btn-danger` · `.btn-ghost` ·
`.link-btn` (dashed-underline text button, `.danger` variant).
- **Status badges** (`.badge` + `.badge-ok/-fail/-pending/-info`): dot + uppercase
label, tinted 6%-alpha background, colored dot (glowing/pulsing per state).
- **Tables** (`table.tbl` in `.tbl-wrap`): dense, hairline row borders, raised
uppercase header, right-aligned `.num-cell`, subtle row-hover, `.empty-row` for
empty states. Horizontal scroll lives on `.tbl-wrap`.
- **Forms** (`.field`, `.field-row`): uppercase label above inset input; focus =
amber border + 3px amber-12% ring.
- **Modals** (`.modal-overlay` + `.modal-dialog`, `.modal-md/-lg`): fixed overlay,
backdrop-blur(2px), fade + 6px rise entrance. Folder-mapping grid
(`.map-row`: src → select). z-index scale: topbar 10 → overlay 100.
- **Live progress** (`.acct-progress`, `.pbar`/`.pbar-fill`, `.pmeta`, `.pscan`,
`.acct-error`): thin amber bar + mono meta; scan phase in `--info`; persisted
last-error in `--fail`, ellipsis-truncated.
- **Log pane** (`.log-pane`): reversed-column inset console, tagged lines
(`.tag` amber + `.payload`).
- **Chrome**: sticky `.topbar` with bracketed `.brand`, uppercase `.topnav`
(active = amber), `.session-indicator` with pulsing `.pulse-dot`.
## Layout
- App shell: sticky topbar (56px) over a centered `.main`, `max-width: 1180px`,
padding `32px 24px 64px`.
- Grids: `repeat(auto-fit, minmax(340px, 1fr))` for panel grids — responsive
without breakpoints. Flexbox for 1D rows (`.btn-row`, `.stat-row`, `.upload-row`).
- Radii: tight — 2px (controls) / 3px (surfaces). Nothing pill-shaped.
- Dividers: centered uppercase `.divider-label` with rule lines both sides.
## Motion
Restrained, functional. Ease-out only; no bounce/elastic.
- Entrances: modal fade 0.12s + rise 0.14s.
- Feedback: 0.15s color/border transitions on nav, buttons, inputs.
- Ambient: `pulse` (2.4s) on session/info dots; progress-bar width 0.3s ease-out.
- Amber glow bloom on primary-button hover.
- **Owed:** a `prefers-reduced-motion: reduce` block — the pulsing dots and
progress transitions need a static fallback. Add before shipping motion work.