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
139 changes: 81 additions & 58 deletions README.md

Large diffs are not rendered by default.

28 changes: 21 additions & 7 deletions apps/ui/src/lib/theme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
export type ColorMode = "dark" | "light" | "system";
export type ResolvedTheme = "dark" | "light";
export type Accent = "teal" | "ocean" | "forest" | "slate";
export type Accent =
| "teal"
| "ocean"
| "forest"
| "slate"
| "coral"
| "amber"
| "magenta"
| "citrus";

/** @deprecated Prefer ColorMode; kept for callers that only mean resolved dark/light. */
export type Theme = ResolvedTheme;
Expand All @@ -14,13 +22,19 @@ export const DEFAULT_COLOR_MODE: ColorMode = "system";
export const DEFAULT_ACCENT: Accent = "teal";
export const DEFAULT_THEME: ResolvedTheme = "dark";

export const ACCENTS: Array<{ id: Accent; label: string }> = [
{ id: "teal", label: "Teal" },
{ id: "ocean", label: "Ocean" },
{ id: "forest", label: "Forest" },
{ id: "slate", label: "Slate" },
export const ACCENTS: Array<{ id: Accent; label: string; swatch: string }> = [
{ id: "teal", label: "Teal", swatch: "#14b8a6" },
{ id: "ocean", label: "Ocean", swatch: "#38bdf8" },
{ id: "forest", label: "Forest", swatch: "#4ade80" },
{ id: "slate", label: "Slate", swatch: "#94a3b8" },
{ id: "coral", label: "Coral", swatch: "#ff6b4a" },
{ id: "amber", label: "Amber", swatch: "#f59e0b" },
{ id: "magenta", label: "Magenta", swatch: "#ec4899" },
{ id: "citrus", label: "Citrus", swatch: "#84cc16" },
];

const ACCENT_IDS = new Set(ACCENTS.map((a) => a.id));

export function isColorMode(value: unknown): value is ColorMode {
return value === "dark" || value === "light" || value === "system";
}
Expand All @@ -31,7 +45,7 @@ export function isTheme(value: unknown): value is ColorMode {
}

export function isAccent(value: unknown): value is Accent {
return value === "teal" || value === "ocean" || value === "forest" || value === "slate";
return typeof value === "string" && ACCENT_IDS.has(value as Accent);
}

export function systemPrefersDark(): boolean {
Expand Down
6 changes: 5 additions & 1 deletion apps/ui/src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ export function HomePage() {
useEffect(() => {
api<CycleDTO[]>("/api/cycles").then((c) => {
setCycles(c);
if (c[0]) setCycleId(c[0].id);
const preferred =
c.find((x) => x.status === "manager_open") ||
c.find((x) => x.status !== "closed") ||
c[0];
if (preferred) setCycleId(preferred.id);
});
api<WorkspaceStatus>("/api/workspace/status").then((s) => {
setThinEvidenceCount(s.thinEvidenceCount ?? 0);
Expand Down
16 changes: 2 additions & 14 deletions apps/ui/src/pages/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function SettingsPage({
id="settings-appearance"
title="Appearance"
when="Change color mode or accent whenever the UI feels too bright, too dark, or hard to scan."
how={`Pick a mode and accent below. Preferences stay in this browser; System follows your OS (${resolved} right now).`}
how={`Pick a mode and accent below. Eight accents (Teal, Ocean, Forest, Slate, Coral, Amber, Magenta, Citrus) × dark/light. Preferences stay in this browser; System follows your OS (${resolved} right now).`}
>
<div className="field">
<label htmlFor="theme-select">Color mode</label>
Expand All @@ -160,19 +160,7 @@ export function SettingsPage({
aria-checked={accent === item.id}
onClick={() => setAccent(item.id as Accent)}
>
<span
className="accent-dot"
style={{
["--swatch" as string]:
item.id === "teal"
? "#14b8a6"
: item.id === "ocean"
? "#38bdf8"
: item.id === "forest"
? "#4ade80"
: "#94a3b8",
}}
/>
<span className="accent-dot" style={{ ["--swatch" as string]: item.swatch }} />
{item.label}
</button>
))}
Expand Down
80 changes: 78 additions & 2 deletions apps/ui/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,82 @@
--bg-glow-b: rgba(100, 116, 139, 0.04);
}

[data-theme="dark"][data-accent="coral"] {
--brand: #ff6b4a;
--brand-strong: #ff8f75;
--brand-tint: rgba(255, 107, 74, 0.16);
--brand-ring: rgba(255, 107, 74, 0.36);
--accent: #ffb4a2;
--bg-glow-a: rgba(255, 107, 74, 0.12);
--bg-glow-b: rgba(251, 113, 133, 0.07);
}
[data-theme="light"][data-accent="coral"] {
--brand: #e11d48;
--brand-strong: #be123c;
--brand-tint: #ffe4e6;
--brand-ring: rgba(225, 29, 72, 0.28);
--accent: #f43f5e;
--bg-glow-a: rgba(225, 29, 72, 0.07);
--bg-glow-b: rgba(251, 113, 133, 0.05);
}

[data-theme="dark"][data-accent="amber"] {
--brand: #f59e0b;
--brand-strong: #fbbf24;
--brand-tint: rgba(245, 158, 11, 0.16);
--brand-ring: rgba(245, 158, 11, 0.36);
--accent: #fcd34d;
--bg-glow-a: rgba(245, 158, 11, 0.12);
--bg-glow-b: rgba(251, 191, 36, 0.07);
}
[data-theme="light"][data-accent="amber"] {
--brand: #c2410c;
--brand-strong: #9a3412;
--brand-tint: #ffedd5;
--brand-ring: rgba(194, 65, 12, 0.28);
--accent: #ea580c;
--bg-glow-a: rgba(194, 65, 12, 0.07);
--bg-glow-b: rgba(234, 88, 12, 0.05);
}

[data-theme="dark"][data-accent="magenta"] {
--brand: #ec4899;
--brand-strong: #f472b6;
--brand-tint: rgba(236, 72, 153, 0.16);
--brand-ring: rgba(236, 72, 153, 0.36);
--accent: #f9a8d4;
--bg-glow-a: rgba(236, 72, 153, 0.12);
--bg-glow-b: rgba(217, 70, 239, 0.07);
}
[data-theme="light"][data-accent="magenta"] {
--brand: #db2777;
--brand-strong: #be185d;
--brand-tint: #fce7f3;
--brand-ring: rgba(219, 39, 119, 0.28);
--accent: #ec4899;
--bg-glow-a: rgba(219, 39, 119, 0.07);
--bg-glow-b: rgba(236, 72, 153, 0.05);
}

[data-theme="dark"][data-accent="citrus"] {
--brand: #84cc16;
--brand-strong: #a3e635;
--brand-tint: rgba(132, 204, 22, 0.16);
--brand-ring: rgba(132, 204, 22, 0.36);
--accent: #d9f99d;
--bg-glow-a: rgba(132, 204, 22, 0.12);
--bg-glow-b: rgba(250, 204, 21, 0.06);
}
[data-theme="light"][data-accent="citrus"] {
--brand: #65a30d;
--brand-strong: #4d7c0f;
--brand-tint: #ecfccb;
--brand-ring: rgba(101, 163, 13, 0.28);
--accent: #84cc16;
--bg-glow-a: rgba(101, 163, 13, 0.07);
--bg-glow-b: rgba(132, 204, 22, 0.05);
}

/* Semantic colors (theme-aware, accent-independent) */
:root,
[data-theme="dark"] {
Expand Down Expand Up @@ -1259,13 +1335,13 @@ pre { margin: 0; white-space: pre-wrap; word-break: break-word; }
align-items: center;
gap: var(--space-2);
min-height: var(--touch-min);
padding: 0.4rem 0.75rem;
padding: 0.35rem 0.65rem;
border-radius: 999px;
border: 1px solid var(--line-strong);
background: var(--panel);
color: var(--ink-soft);
cursor: pointer;
font-size: var(--text-sm);
font-size: var(--text-xs);
font-weight: 600;
}
.accent-swatch.on {
Expand Down
Binary file modified docs/screenshots/01-unlock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/02-home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/03-team.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/04-person.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/05-roles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/06-cycles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/07-writing-desk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/08-promotions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/09-promotion-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/10-consistency.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/11-team-performance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/12-backfill.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/13-chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/14-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/15-director-attention.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/16-writing-desk-director.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/17-consistency-director-packs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/18-team-director-briefing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/19-promo-committee.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/20-sprint-pulse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 36 additions & 30 deletions docs/screenshots/README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,45 @@
# Screenshot gallery

PNG captures used in the root [README](../../README.md).
PNG captures used in the root [README](../../README.md) and the [theme matrix](./THEMES.md).

Regenerate (API + UI must be running; unlock password defaults to `workbench`):
Regenerate (API + UI must be running; demo unlock password `workbench`):

```bash
pnpm screenshots
# or: UI_URL=http://localhost:5173 PRM_PASSWORD=workbench pnpm screenshots
```

The script **erases and re-seeds** the local demo workspace so shots stay consistent. Requires system Chrome (`google-chrome-stable`) and root `puppeteer-core`.

Numbering matches the README Screens section (`01` unlock through `14` settings), plus director close-ups and sprint pulse:

| File | Surface |
| --- | --- |
| `01-unlock.png` | Create workbench — empty vs demo |
| `02-home.png` | Command center |
| `03-team.png` | Team roster |
| `04-person.png` | Person dossier |
| `05-roles.png` | Roles |
| `06-cycles.png` | Cycles |
| `07-writing-desk.png` | Writing desk |
| `08-promotions.png` | Promotions list |
| `09-promotion-detail.png` | Promotion packet |
| `10-consistency.png` | Consistency |
| `11-team-performance.png` | Team performance |
| `12-backfill.png` | Backfill |
| `13-chat.png` | AI Chat |
| `14-settings.png` | Settings (sticky section nav + appearance) |
| `15-director-attention.png` | Home — Needs director attention |
| `16-writing-desk-director.png` | Writing desk — Skip-level / Director card |
| `17-consistency-director-packs.png` | Consistency — calib / briefing / bundle |
| `18-team-director-briefing.png` | Team performance — Director briefing |
| `19-promo-committee.png` | Promotion — Promo committee export |
| `20-sprint-pulse.png` | Sprint pulse |

`01-unlock` is the empty-vs-demo create screen. Sticky **On this page** nav appears on Home, Person, Writing desk, Team performance, Consistency, Cycles, Roles, Sprint pulse, Promotion detail, and Settings.
The script **erases and re-seeds** the local demo workspace, then captures:

1. **Theme matrix** — every accent × dark/light × main page under `themes/{mode}-{accent}/`
2. **README tour** — numbered shots at this folder root (accents rotate through the tour)
3. **Home strip** — `themes/{mode}-{accent}-home.png` for the Appearance section

Requires system Chrome (`google-chrome-stable`) and root `puppeteer-core`.

## README tour files

| File | Surface | Theme in tour |
| --- | --- | --- |
| `01-unlock.png` | Create workbench | dark Coral |
| `02-home.png` | Command center | dark Teal |
| `03-team.png` | Team roster | dark Coral |
| `04-person.png` | Person dossier | dark Magenta |
| `05-roles.png` | Roles | light Ocean |
| `06-cycles.png` | Cycles | dark Citrus |
| `07-writing-desk.png` | Writing desk | dark Coral |
| `08-promotions.png` | Promotions list | light Magenta |
| `09-promotion-detail.png` | Promotion packet | dark Ocean |
| `10-consistency.png` | Consistency | dark Forest |
| `11-team-performance.png` | Team performance | light Coral |
| `12-backfill.png` | Backfill | light Citrus |
| `13-chat.png` | AI Chat | dark Ocean |
| `14-settings.png` | Settings (8 accents) | dark Coral |
| `15-director-attention.png` | Home — director attention | dark Amber |
| `16-writing-desk-director.png` | Writing desk — skip-level | dark Amber |
| `17-consistency-director-packs.png` | Consistency — calib packs | dark Forest |
| `18-team-director-briefing.png` | Team performance — briefing | light Amber |
| `19-promo-committee.png` | Promo committee export | dark Ocean |
| `20-sprint-pulse.png` | Sprint pulse | dark Magenta |

Accents available in Settings: Teal, Ocean, Forest, Slate, **Coral**, **Amber**, **Magenta**, **Citrus**.
43 changes: 43 additions & 0 deletions docs/screenshots/THEMES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Theme matrix

Every main page captured in **8 accents × dark/light** (16 combinations).

Accents: Teal, Ocean, Forest, Slate, Coral, Amber, Magenta, Citrus.

Regenerate with `pnpm screenshots` (UI + API running).

## Home strip (all combinations)

### Dark

| Accent | Shot |
|--------|------|
| Teal | ![dark teal](./themes/dark-teal-home.png) |
| Ocean | ![dark ocean](./themes/dark-ocean-home.png) |
| Forest | ![dark forest](./themes/dark-forest-home.png) |
| Slate | ![dark slate](./themes/dark-slate-home.png) |
| Coral | ![dark coral](./themes/dark-coral-home.png) |
| Amber | ![dark amber](./themes/dark-amber-home.png) |
| Magenta | ![dark magenta](./themes/dark-magenta-home.png) |
| Citrus | ![dark citrus](./themes/dark-citrus-home.png) |

### Light

| Accent | Shot |
|--------|------|
| Teal | ![light teal](./themes/light-teal-home.png) |
| Ocean | ![light ocean](./themes/light-ocean-home.png) |
| Forest | ![light forest](./themes/light-forest-home.png) |
| Slate | ![light slate](./themes/light-slate-home.png) |
| Coral | ![light coral](./themes/light-coral-home.png) |
| Amber | ![light amber](./themes/light-amber-home.png) |
| Magenta | ![light magenta](./themes/light-magenta-home.png) |
| Citrus | ![light citrus](./themes/light-citrus-home.png) |

## Full page folders

Each folder under `themes/{mode}-{accent}/` contains:

`home`, `team`, `person`, `roles`, `cycles`, `writing-desk`, `promotions`, `promotion-detail`, `consistency`, `team-performance`, `sprint-pulse`, `backfill`, `chat`, `settings`

Example: [dark Coral writing desk](./themes/dark-coral/writing-desk.png) · [light Magenta settings](./themes/light-magenta/settings.png) · [dark Citrus sprint pulse](./themes/dark-citrus/sprint-pulse.png)
Binary file added docs/screenshots/themes/dark-amber-home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/screenshots/themes/dark-amber/chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/screenshots/themes/dark-amber/cycles.png
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/screenshots/themes/dark-amber/home.png
Binary file added docs/screenshots/themes/dark-amber/person.png
Binary file added docs/screenshots/themes/dark-amber/roles.png
Binary file added docs/screenshots/themes/dark-amber/team.png
Binary file added docs/screenshots/themes/dark-citrus-home.png
Binary file added docs/screenshots/themes/dark-citrus/chat.png
Binary file added docs/screenshots/themes/dark-citrus/home.png
Binary file added docs/screenshots/themes/dark-citrus/roles.png
Binary file added docs/screenshots/themes/dark-citrus/team.png
Binary file added docs/screenshots/themes/dark-coral-home.png
Binary file added docs/screenshots/themes/dark-coral/chat.png
Binary file added docs/screenshots/themes/dark-coral/cycles.png
Binary file added docs/screenshots/themes/dark-coral/home.png
Binary file added docs/screenshots/themes/dark-coral/person.png
Binary file added docs/screenshots/themes/dark-coral/roles.png
Binary file added docs/screenshots/themes/dark-coral/team.png
Binary file added docs/screenshots/themes/dark-forest-home.png
Binary file added docs/screenshots/themes/dark-forest/chat.png
Binary file added docs/screenshots/themes/dark-forest/home.png
Binary file added docs/screenshots/themes/dark-forest/roles.png
Binary file added docs/screenshots/themes/dark-forest/team.png
Binary file added docs/screenshots/themes/dark-magenta-home.png
Binary file added docs/screenshots/themes/dark-magenta/chat.png
Binary file added docs/screenshots/themes/dark-magenta/home.png
Binary file added docs/screenshots/themes/dark-magenta/team.png
Binary file added docs/screenshots/themes/dark-ocean-home.png
Binary file added docs/screenshots/themes/dark-ocean/chat.png
Binary file added docs/screenshots/themes/dark-ocean/cycles.png
Binary file added docs/screenshots/themes/dark-ocean/home.png
Binary file added docs/screenshots/themes/dark-ocean/person.png
Binary file added docs/screenshots/themes/dark-ocean/roles.png
Binary file added docs/screenshots/themes/dark-ocean/team.png
Binary file added docs/screenshots/themes/dark-slate-home.png
Binary file added docs/screenshots/themes/dark-slate/chat.png
Binary file added docs/screenshots/themes/dark-slate/cycles.png
Binary file added docs/screenshots/themes/dark-slate/home.png
Binary file added docs/screenshots/themes/dark-slate/person.png
Binary file added docs/screenshots/themes/dark-slate/roles.png
Binary file added docs/screenshots/themes/dark-slate/team.png
Binary file added docs/screenshots/themes/dark-teal-home.png
Binary file added docs/screenshots/themes/dark-teal/chat.png
Binary file added docs/screenshots/themes/dark-teal/cycles.png
Binary file added docs/screenshots/themes/dark-teal/home.png
Binary file added docs/screenshots/themes/dark-teal/person.png
Binary file added docs/screenshots/themes/dark-teal/roles.png
Binary file added docs/screenshots/themes/dark-teal/team.png
Binary file added docs/screenshots/themes/light-amber-home.png
Binary file added docs/screenshots/themes/light-amber/chat.png
Binary file added docs/screenshots/themes/light-amber/home.png
Binary file added docs/screenshots/themes/light-amber/roles.png
Binary file added docs/screenshots/themes/light-amber/team.png
Binary file added docs/screenshots/themes/light-citrus-home.png
Binary file added docs/screenshots/themes/light-citrus/chat.png
Binary file added docs/screenshots/themes/light-citrus/home.png
Binary file added docs/screenshots/themes/light-citrus/team.png
Binary file added docs/screenshots/themes/light-coral-home.png
Binary file added docs/screenshots/themes/light-coral/chat.png
Binary file added docs/screenshots/themes/light-coral/home.png
Binary file added docs/screenshots/themes/light-coral/roles.png
Binary file added docs/screenshots/themes/light-coral/team.png
Binary file added docs/screenshots/themes/light-forest-home.png
Binary file added docs/screenshots/themes/light-forest/chat.png
Binary file added docs/screenshots/themes/light-forest/home.png
Binary file added docs/screenshots/themes/light-forest/team.png
Binary file added docs/screenshots/themes/light-ocean-home.png
Binary file added docs/screenshots/themes/light-ocean/chat.png
Binary file added docs/screenshots/themes/light-ocean/home.png
Binary file added docs/screenshots/themes/light-ocean/roles.png
Binary file added docs/screenshots/themes/light-ocean/team.png
Binary file added docs/screenshots/themes/light-slate-home.png
Binary file added docs/screenshots/themes/light-slate/chat.png
Binary file added docs/screenshots/themes/light-slate/home.png
Binary file added docs/screenshots/themes/light-slate/roles.png
Binary file added docs/screenshots/themes/light-slate/team.png
Binary file added docs/screenshots/themes/light-teal-home.png
Binary file added docs/screenshots/themes/light-teal/chat.png
Binary file added docs/screenshots/themes/light-teal/cycles.png
Binary file added docs/screenshots/themes/light-teal/home.png
Binary file added docs/screenshots/themes/light-teal/person.png
Binary file added docs/screenshots/themes/light-teal/roles.png
Binary file added docs/screenshots/themes/light-teal/team.png
Loading