themes: generate all 22 from Omarchy, with contrast as a test rather than a taste

The eleven ported themes declared 34 of an 84-token contract. The missing fifty were every surface
(--panel-bg, --card-bg, --glass-bg), every state colour (--success, --warning, --busy, --info), the
header, the scrollbars and the grid — so they fell back to whatever the base stylesheet or the
previously applied theme had left behind. They also carried thirteen tokens nothing in this codebase
reads (--chart-1..5, --sidebar-*), which is the tell: they came from a shadcn template, not from the
contract in the README beside them.

So "highlights mask the content" and "text fades into the background" were not taste. They were
absence, and no amount of re-picking colours would have fixed them.

Generated now, from Omarchy 4's colors.toml, which is genuinely semantic — three background depths,
four foreground weights, accent, selection, muted, mode — and consistent: all 24 keys present in all 22
themes, checked. One mapping in scripts/themes/map.ts means one place to be wrong, one place to fix,
and an Omarchy update becomes a re-run.

Every foreground is driven through ensureContrast against the surface it actually sits on, and the
generator then re-checks sixteen pairs per theme and EXITS NONZERO on a failure. It found four real
bugs in my own mapping, which is the argument for having written it first:

  - `on(fill)` picked the better of two palette extremes without checking either passed; rose-pine's
    tones are all mid and came out between 2.2:1 and 4.2:1
  - ensureContrast chose black or white by a luminance>0.5 test rather than by measuring. rose-pine's
    rose sits at 0.25, so it drove toward white and capped at 3.5:1 where black reaches 6:1 easily
  - --muted-foreground was derived against the raised surface but renders on the high one; everforest
    landed at 4.44:1 and miasma at 4.00 — near-misses that look fine in a screenshot
  - borders were held to 3:1, which would ring every panel in a hard line. A panel edge is decoration;
    what must be discernible is a form field's boundary, so --input is checked and --border is not

35 failures at first run, 0 now.

The registry and the stylesheet imports are written from the same list, because the old port maintained
them by hand and drifted — catppuccin-mocha sat in THEMES after its stylesheet was gone. That file is
now deleted; Omarchy renamed it to catppuccin.

Eleven new themes arrive with this: ethereal, flexoki-light, hackerman, last-horizon, lumon, lupine,
miasma, retro-82, solitude, vantablack, white. Duck and Plain are Officer's own and are never generated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 04:18:58 +00:00
co-authored by Claude Opus 5
parent a2cca526f9
commit 4e2db3dc2f
29 changed files with 2567 additions and 474 deletions
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env bun
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { loadPalette } from './themes/palette';
import { mapPalette } from './themes/map';
import { TEXT, UI, contrast } from './themes/contrast';
// Generate Officer themes from Omarchy's, and refuse to write an unreadable one.
//
// bun scripts/generate-themes.ts <path-to-omarchy-checkout> [--check]
//
// `--check` writes nothing and reports what would change, which is what a test runs.
//
// ── Why generated rather than authored ──
//
// Twenty-two themes hand-written against an 84-token contract will disagree, and the previous attempt
// proved it: eleven themes, 34 tokens each, every surface missing. One mapping means one place to be
// wrong and one place to fix — and a palette that Omarchy updates is a re-run rather than a rewrite.
//
// The Duck and Plain themes are NOT generated. They are Officer's own, authored, and this must never
// overwrite them.
const OMARCHY = process.argv[2];
const CHECK = process.argv.includes('--check');
const THEME_DIR = join(import.meta.dir, '..', 'src', 'workspaces', 'theme', 'css', 'themes');
if (!OMARCHY || !existsSync(join(OMARCHY, 'themes'))) {
console.error('usage: bun scripts/generate-themes.ts <path-to-omarchy-checkout> [--check]');
process.exit(1);
}
/** Officer's own. Generated themes may never take these names. */
const AUTHORED = new Set(['duck-light', 'duck-dark', 'plain']);
const title = (id: string): string =>
id
.split('-')
.map((w) => (w.length <= 2 ? w.toUpperCase() : w[0]!.toUpperCase() + w.slice(1)))
.join(' ');
/**
* The pairs that must be readable, checked after mapping rather than trusted.
*
* `ensureContrast` already guarantees most of these — this is the belt to that braces. A mapping change
* that quietly breaks one shows up here as a failure instead of as somebody squinting at a screenshot.
*/
const PAIRS: [string, string, number][] = [
['--foreground', '--background', TEXT],
['--card-foreground', '--card', TEXT],
['--popover-foreground', '--popover', TEXT],
['--muted-foreground', '--muted', TEXT],
['--accent-foreground', '--accent', TEXT],
['--primary-foreground', '--primary', TEXT],
['--secondary-foreground', '--secondary', TEXT],
['--cta-foreground', '--cta', TEXT],
['--success-foreground', '--success', TEXT],
['--warning-foreground', '--warning', TEXT],
['--destructive-foreground', '--destructive', TEXT],
['--info-foreground', '--info', TEXT],
['--busy-foreground', '--busy', TEXT],
['--busy-ink', '--background', TEXT],
// Not `--border` at UI: a panel edge is decoration and 3:1 would ring everything in a hard line. What
// must be visible is a form field's boundary and the focus ring — the two that carry information.
['--input', '--background', 1.35],
['--ring', '--background', UI],
];
let failures = 0;
let written = 0;
const generated: { id: string; name: string; dark: boolean }[] = [];
for (const id of readdirSync(join(OMARCHY, 'themes')).sort()) {
const toml = join(OMARCHY, 'themes', id, 'colors.toml');
if (!existsSync(toml)) continue;
if (AUTHORED.has(id)) {
console.log(` ${id}: SKIPPED — Officer's own theme, never generated`);
continue;
}
const palette = loadPalette(toml);
const tokens = mapPalette(palette);
for (const [fgKey, bgKey, min] of PAIRS) {
const fg = tokens[fgKey]!;
const bg = tokens[bgKey]!;
// Only flat hex pairs are checkable — a translucent surface depends on what is behind it.
if (!fg.startsWith('#') || !bg.startsWith('#')) continue;
const ratio = contrast(fg, bg);
if (ratio < min) {
console.error(` ${id}: ${fgKey} on ${bgKey} is ${ratio.toFixed(2)}:1, needs ${min}:1`);
failures++;
}
}
const body = Object.entries(tokens)
.map(([k, v]) => ` ${k}: ${v};`)
.join('\n');
const css = `/*
${title(id)} — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/${id}/colors.toml (mode: ${palette.mode})
*/
[data-theme='${id}'] {
${body}
}
`;
const path = join(THEME_DIR, `${id}.css`);
const before = existsSync(path) ? readFileSync(path, 'utf8') : '';
if (before !== css) {
if (!CHECK) writeFileSync(path, css);
written++;
}
generated.push({ id, name: title(id), dark: palette.mode === 'dark' });
}
console.log(`\n ${generated.length} themes, ${written} ${CHECK ? 'would change' : 'written'}, ${failures} contrast failures`);
if (!CHECK) {
// The registry and the stylesheet index, rewritten from what was generated so a theme cannot exist as
// a file nobody imports — which is a theme that silently does not work.
const imports = generated.map((t) => `@import './themes/${t.id}.css';`).join('\n');
const indexPath = join(THEME_DIR, '..', 'index.css');
const index = readFileSync(indexPath, 'utf8');
const marker = '/* Palette themes';
const head = index.slice(0, index.indexOf(marker));
writeFileSync(
indexPath,
`${head}/* Palette themes — generated from Omarchy by scripts/generate-themes.ts. Do not edit this block. */\n${imports}\n\n@import './chrome.css';\n`,
);
console.log(` index.css: ${generated.length} imports`);
// The REGISTRY, from the same list. A theme file nothing imports does not work; a theme imported but
// absent from here does not appear in the picker. Both were true of the previous port — catppuccin-mocha
// outlived its stylesheet — so both halves are written from one source rather than maintained by hand.
//
// Display names get a pass for the ones a slug cannot spell.
const NICER: Record<string, string> = {
'rose-pine': 'Rosé Pine',
'retro-82': 'Retro 82',
'tokyo-night': 'Tokyo Night',
'catppuccin': 'Catppuccin Mocha',
'catppuccin-latte': 'Catppuccin Latte',
};
const FAMILY: Record<string, string> = { catppuccin: 'Catppuccin', 'catppuccin-latte': 'Catppuccin' };
const rows = generated
.map((t) => {
const name = NICER[t.id] ?? t.name;
const family = FAMILY[t.id] ?? name;
return ` { id: '${t.id}', name: '${name}', family: '${family}', applyDarkClass: ${t.dark} },`;
})
.join('\n');
const registryPath = join(import.meta.dir, '..', 'src', 'workspaces', 'theme', 'src', 'themes.ts');
const registry = readFileSync(registryPath, 'utf8');
const START = ' /* GENERATED THEMES — start */';
const END = ' /* GENERATED THEMES — end */';
if (!registry.includes(START)) {
console.error(' themes.ts: missing the GENERATED THEMES markers — not touching it');
process.exit(1);
}
const registryHead = registry.slice(0, registry.indexOf(START) + START.length);
const registryTail = registry.slice(registry.indexOf(END));
writeFileSync(registryPath, `${registryHead}\n${rows}\n${registryTail}`);
console.log(` themes.ts: ${generated.length} entries`);
}
process.exit(failures > 0 ? 1 : 0);
+96
View File
@@ -0,0 +1,96 @@
// WCAG contrast, so "is this readable" stops being a matter of taste.
//
// Every complaint about the current themes reduces to one of two failures: a highlight so strong it
// masks the content on it, or text so close to its background it disappears. Both are a contrast ratio,
// and a ratio is checkable. This file is what turns the whole exercise from opinion into a test.
export type Rgb = { r: number; g: number; b: number };
export function parseHex(hex: string): Rgb {
const h = hex.trim().replace('#', '');
const full = h.length === 3 ? h.split('').map((c) => c + c).join('') : h;
return {
r: Number.parseInt(full.slice(0, 2), 16),
g: Number.parseInt(full.slice(2, 4), 16),
b: Number.parseInt(full.slice(4, 6), 16),
};
}
export const toHex = ({ r, g, b }: Rgb): string =>
`#${[r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('')}`;
/** Relative luminance, per WCAG 2.1. */
export function luminance(c: Rgb): number {
const channel = (v: number) => {
const s = v / 255;
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
};
return 0.2126 * channel(c.r) + 0.7152 * channel(c.g) + 0.0722 * channel(c.b);
}
/** 1 (identical) to 21 (black on white). */
export function contrast(a: string, b: string): number {
const [x, y] = [luminance(parseHex(a)), luminance(parseHex(b))];
const [hi, lo] = x > y ? [x, y] : [y, x];
return (hi + 0.05) / (lo + 0.05);
}
/**
* The thresholds, and why these ones.
*
* `TEXT` is WCAG AA for body text. `UI` is AA for large text and non-text contrast — borders, icons, the
* edge of a control. A border at 4.5 would be a hard line around everything, which is a different design
* rather than a more accessible one.
*/
export const TEXT = 4.5;
export const UI = 3;
/**
* Push a foreground away from its background until it is readable.
*
* Moves toward black or white — whichever the background is further from — in small steps, so a colour
* that is nearly readable keeps almost all of its hue and only a hopeless one ends up monochrome. That
* matters: the point is a theme that still looks like Nord, not one that passes and looks like nothing.
*
* Returns the original when it already passes, so a well-chosen palette is untouched.
*/
export function ensureContrast(fg: string, bg: string, min = TEXT): string {
if (contrast(fg, bg) >= min) return fg;
// Whichever extreme is FURTHER from the background, not whichever side of mid-grey it falls on.
// Those differ for a mid-tone fill and the difference is the whole answer: rose-pine's rose is at
// luminance 0.25, so a `> 0.5` test sends this toward white and caps at 3.5:1, while black reaches
// 6:1 easily. Six of its tones were unfixable until this stopped guessing and measured.
const black = '#000000';
const white = '#ffffff';
const target = parseHex(contrast(black, bg) >= contrast(white, bg) ? black : white);
const start = parseHex(fg);
// 40 steps of 2.5% each. Fine enough that the first passing value is close to the original.
for (let i = 1; i <= 40; i++) {
const t = i / 40;
const moved = toHex({
r: start.r + (target.r - start.r) * t,
g: start.g + (target.g - start.g) * t,
b: start.b + (target.b - start.b) * t,
});
if (contrast(moved, bg) >= min) return moved;
}
return toHex(target);
}
/** Blend two colours. `amount` is how much of `b`. */
export function mix(a: string, b: string, amount: number): string {
const [x, y] = [parseHex(a), parseHex(b)];
return toHex({
r: x.r + (y.r - x.r) * amount,
g: x.g + (y.g - x.g) * amount,
b: x.b + (y.b - x.b) * amount,
});
}
/** `#rrggbb` → `r g b` for `rgb(var(--x) / 0.5)`, which is how the surfaces get their opacity. */
export const rgbTriplet = (hex: string): string => {
const { r, g, b } = parseHex(hex);
return `${r} ${g} ${b}`;
};
+193
View File
@@ -0,0 +1,193 @@
import type { Palette } from './palette';
import { UI, contrast, ensureContrast, mix, rgbTriplet } from './contrast';
// Omarchy palette → Officer's 84 declarations.
//
// This file is the whole port. It exists once so that twenty-two themes cannot disagree about what
// "muted" means, and so that improving the mapping improves all of them at once.
//
// ── What went wrong before, and what this fixes ──
//
// The previous port produced 34 declarations per theme against a contract of 84. The missing fifty were
// every surface (`--panel-bg`, `--card-bg`, `--glass-bg`), every state colour (`--success`, `--warning`,
// `--busy`, `--info`), the header, the scrollbars and the grid — so they fell back to whatever the base
// stylesheet or the previous theme left behind. That is why highlights masked content and text faded
// out: not taste, absence. It also shipped thirteen tokens nothing reads (`--chart-1..5`, `--sidebar-*`),
// which is the tell that it came from a shadcn template rather than from this codebase's contract.
//
// ── The rule that makes them readable ──
//
// Every foreground is run through `ensureContrast` against the surface it actually sits on. A palette
// whose colours are already readable is untouched; one that is not gets nudged toward black or white
// until it passes, keeping as much hue as it can. So a theme cannot ship with invisible text, no matter
// what its author chose.
export type Tokens = Record<string, string>;
/** Depth ordering differs by mode: a light theme's "darker" is its raised surface, not its page. */
function surfaces(p: Palette) {
const dark = p.mode === 'dark';
return {
/** The page. The deepest surface in dark, the plainest in light. */
page: dark ? p.darkerBackground : p.background,
/** Panels and cards sit one step up from the page, so a tile reads as a tile. */
raised: dark ? p.background : p.lighterBackground,
/** Hovers, secondary fills, the header. One step up again. */
high: dark ? p.lighterBackground : p.darkBackground,
dark,
};
}
export function mapPalette(p: Palette): Tokens {
const s = surfaces(p);
// Text, checked against the surface each weight actually appears on.
const fg = ensureContrast(p.foreground, s.page);
const fgRaised = ensureContrast(p.foreground, s.raised);
// Checked against `s.high`, not `s.raised`: `--muted-foreground` is the text ON `--muted`, and
// `--muted` is the high surface. Deriving it against the wrong one left everforest at 4.44:1 and
// miasma at 4.00 — close enough to look fine and still fail, which is the kind of near-miss that a
// person eyeballing a screenshot would have shipped.
const fgMuted = ensureContrast(p.lightForeground, s.high);
const fgFaint = ensureContrast(p.darkForeground, s.raised, UI);
/**
* Text for a solid fill of `bg`.
*
* Tries the palette's own extremes first, so a button's label still belongs to the theme, and only
* falls through to `ensureContrast` when neither is readable. Both steps are needed: picking the
* better of two candidates does NOT guarantee either passes — rose-pine's fills are all mid-tone and
* every one came out between 2.2:1 and 4.2:1 until this drove it the rest of the way.
*/
const on = (bg: string): string => {
const light = p.brightForeground;
const dark = p.darkerBackground;
const better = contrast(light, bg) >= contrast(dark, bg) ? light : dark;
return ensureContrast(better, bg);
};
const accent = p.accent;
// Borders are DECORATION, not information, so they are not held to a text ratio — a 3:1 line drawn
// around every panel is a different design, not a more accessible one. What they must be is
// discernible, which `--input` below is checked for: a form field whose boundary you cannot see is a
// real accessibility failure, unlike a subtle panel edge.
const border = mix(s.raised, s.dark ? p.lightForeground : p.darkForeground, 0.28);
return {
// ── Ground ──
'--background': s.page,
'--foreground': fg,
// ── Surfaces ──
'--card': s.raised,
'--card-foreground': fgRaised,
'--popover': s.raised,
'--popover-foreground': fgRaised,
// `muted` is a SURFACE here, not the palette's `muted` colour — that one is a mid-grey meant for
// dimmed text, and using it as a fill is precisely how a highlight ends up masking its content.
'--muted': s.high,
'--muted-foreground': fgMuted,
'--accent': s.high,
'--accent-foreground': fgRaised,
// ── Actions ──
'--primary': accent,
'--primary-foreground': on(accent),
'--secondary': s.high,
'--secondary-foreground': fgRaised,
'--cta': accent,
'--cta-foreground': on(accent),
'--ctahover': mix(accent, s.dark ? '#ffffff' : '#000000', 0.12),
// ── State — five tones, each readable on its own fill ──
'--success': p.green,
'--success-foreground': on(p.green),
'--warning': p.yellow,
'--warning-foreground': on(p.yellow),
'--destructive': p.red,
'--destructive-foreground': on(p.red),
'--info': p.blue,
'--info-foreground': on(p.blue),
'--busy': p.orange,
'--busy-foreground': on(p.orange),
// The odd one, per the contract: a fill bright enough for black text is too light to BE text. So ink
// is the same hue pushed until it reads on the page.
'--busy-ink': ensureContrast(p.orange, s.page),
// ── Lines ──
'--border': border,
'--input': border,
'--ring': accent,
'--radius': '0.625rem',
// ── Data ──
'--chart-primary': accent,
'--chart-secondary': p.magenta,
'--status-success': p.green,
'--status-warning': p.yellow,
'--status-in-progress': p.blue,
// ── Surfaces, as complete CSS values ──
'--page-bg': s.page,
'--page-bg-src': "''",
'--panel-bg': `rgb(${rgbTriplet(s.raised)} / 0.72)`,
'--panel-border': `rgb(${rgbTriplet(border)} / 0.9)`,
'--panel-border-bare': `rgb(${rgbTriplet(border)} / 0.55)`,
// DENSER, not darker — panel chrome is dark text and a heavy fill hides every icon. The contract
// says so; this is the one place a value is chosen to obey a sentence rather than a ratio.
'--panel-raised-bg': `rgb(${rgbTriplet(s.raised)} / 0.95)`,
'--panel-raised-border': `rgb(${rgbTriplet(border)} / 1)`,
'--panel-accent': accent,
'--panel-header-bg': `rgb(${rgbTriplet(s.high)} / 0.6)`,
'--panel-header-fg': fgRaised,
'--panel-radius': '0.75rem',
'--panel-blur': '12px',
'--card-bg': s.raised,
'--glass-bg': `rgb(${rgbTriplet(s.raised)} / 0.55)`,
'--glass-border': `rgb(${rgbTriplet(border)} / 0.7)`,
'--dock-bg': `rgb(${rgbTriplet(s.raised)} / 0.7)`,
'--dock-border': `rgb(${rgbTriplet(border)} / 0.8)`,
'--dock-tooltip-bg': s.high,
'--header-bg': `rgb(${rgbTriplet(s.raised)} / 0.8)`,
'--header-border': `rgb(${rgbTriplet(border)} / 0.9)`,
'--header-fg': fgRaised,
'--header-blur': '12px',
// Grid lines are a texture, not a colour anyone should notice — kept just above the surface.
'--pixel-grid-color': `rgb(${rgbTriplet(fgFaint)} / 0.07)`,
'--card-grid-color': `rgb(${rgbTriplet(fgFaint)} / 0.05)`,
'--panel-grid-color': `rgb(${rgbTriplet(fgFaint)} / 0.06)`,
'--scrollbar-thumb': `rgb(${rgbTriplet(p.muted)} / 0.6)`,
'--scrollbar-thumb-hover': `rgb(${rgbTriplet(p.muted)} / 0.85)`,
'--scrollbar-thin-thumb': `rgb(${rgbTriplet(p.muted)} / 0.45)`,
'--scrollbar-thin-thumb-hover': `rgb(${rgbTriplet(p.muted)} / 0.7)`,
// ── Brand slots ──
//
// A ported theme has no brand of its own, so these follow its accent rather than importing Duck's
// green into somebody else's palette. `--ink` is the app's text colour and is used ~950 times.
'--brand': accent,
'--brand-foreground': on(accent),
'--brand-primary': accent,
'--brand-accent': p.cyan,
'--brand-warm': p.orange,
'--brand-deep': s.dark ? p.darkerBackground : p.darkBackground,
'--brand-muted': p.muted,
'--ink': fg,
'--surface-warm': s.raised,
'--naturegreen': p.green,
'--naturegreen-foreground': on(p.green),
// Legacy aliases the contract keeps until the utility rename lands — `prose.css` and some plugins
// read them directly, so a theme without them has unstyled prose.
'--duck-dark': fg,
'--duck-teal': p.cyan,
'--duck-yellow': p.yellow,
'--duck-orange': p.orange,
'--duck-forest': p.green,
'--duck-beige': mix(s.raised, fg, 0.1),
'--logo-src': "'/officer-logo.svg'",
};
}
+86
View File
@@ -0,0 +1,86 @@
import { readFileSync } from 'node:fs';
// Reading an Omarchy theme's `colors.toml`.
//
// Omarchy 4 ships a genuinely semantic palette rather than sixteen ANSI slots: three background depths,
// four foreground weights, an accent, a selection and a muted, plus the named hues. That is why this port
// can be a mapping at all — the previous one had to guess, and the guessing is what produced themes with
// no surfaces and unreadable highlights.
//
// Verified across all 22 themes in basecamp/omarchy@master: every one declares the 24 keys below.
export type Palette = {
mode: 'dark' | 'light';
accent: string;
selection: string;
muted: string;
background: string;
darkBackground: string;
darkerBackground: string;
lighterBackground: string;
foreground: string;
darkForeground: string;
lightForeground: string;
brightForeground: string;
red: string;
yellow: string;
green: string;
cyan: string;
blue: string;
magenta: string;
/** Not in every theme — 19 of 22. Falls back to yellow-red mid, which is what orange is. */
orange: string;
brightRed: string;
brightYellow: string;
brightGreen: string;
brightCyan: string;
brightBlue: string;
brightMagenta: string;
};
/** A deliberately small TOML reader: this file is flat `key = "value"` and nothing else. */
function readToml(path: string): Record<string, string> {
const out: Record<string, string> = {};
for (const line of readFileSync(path, 'utf8').split('\n')) {
const m = line.match(/^\s*([a-z_0-9]+)\s*=\s*"([^"]*)"/i);
if (m) out[m[1]!] = m[2]!;
}
return out;
}
export function loadPalette(tomlPath: string): Palette {
const t = readToml(tomlPath);
const need = (key: string): string => {
const v = t[key];
if (!v) throw new Error(`${tomlPath}: missing "${key}"`);
return v;
};
return {
mode: t.mode === 'light' ? 'light' : 'dark',
accent: need('accent'),
selection: need('selection'),
muted: need('muted'),
background: need('background'),
darkBackground: need('dark_background'),
darkerBackground: need('darker_background'),
lighterBackground: need('lighter_background'),
foreground: need('foreground'),
darkForeground: need('dark_foreground'),
lightForeground: need('light_foreground'),
brightForeground: need('bright_foreground'),
red: need('red'),
yellow: need('yellow'),
green: need('green'),
cyan: need('cyan'),
blue: need('blue'),
magenta: need('magenta'),
orange: t.orange ?? need('yellow'),
brightRed: need('bright_red'),
brightYellow: need('bright_yellow'),
brightGreen: need('bright_green'),
brightCyan: need('bright_cyan'),
brightBlue: need('bright_blue'),
brightMagenta: need('bright_magenta'),
};
}
+14 -3
View File
@@ -17,17 +17,28 @@
@import './themes/duck-dark.css';
@import './themes/plain.css';
/* Palette themes — 20 standard tokens each, every surface derived. */
@import './themes/tokyo-night.css';
@import './themes/catppuccin-mocha.css';
/* Palette themes — generated from Omarchy by scripts/generate-themes.ts. Do not edit this block. */
@import './themes/catppuccin.css';
@import './themes/catppuccin-latte.css';
@import './themes/ethereal.css';
@import './themes/everforest.css';
@import './themes/flexoki-light.css';
@import './themes/gruvbox.css';
@import './themes/hackerman.css';
@import './themes/kanagawa.css';
@import './themes/last-horizon.css';
@import './themes/lumon.css';
@import './themes/lupine.css';
@import './themes/matte-black.css';
@import './themes/miasma.css';
@import './themes/nord.css';
@import './themes/osaka-jade.css';
@import './themes/retro-82.css';
@import './themes/ristretto.css';
@import './themes/rose-pine.css';
@import './themes/solitude.css';
@import './themes/tokyo-night.css';
@import './themes/vantablack.css';
@import './themes/white.css';
@import './chrome.css';
@@ -1,50 +1,94 @@
/*
CATPPUCCIN LATTE — ported from the published palette, unchanged.
Catppuccin Latte — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/catppuccin-latte/colors.toml (mode: light)
*/
[data-theme='catppuccin-latte'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #eff1f5;
--foreground: #4c4f69;
--card: #e6e9ef;
--card: #dce0e8;
--card-foreground: #4c4f69;
--popover: #e6e9ef;
--popover: #dce0e8;
--popover-foreground: #4c4f69;
--muted: #e3e4e8;
--muted-foreground: #5c5f77;
--accent: #e3e4e8;
--accent-foreground: #4c4f69;
--primary: #1e66f5;
--primary-foreground: #eff1f5;
--secondary: #ccd0da;
--primary-foreground: #f5f5f6;
--secondary: #e3e4e8;
--secondary-foreground: #4c4f69;
--muted: #dce0e8;
--muted-foreground: #6c6f85;
--accent: #04a5e5;
--accent-foreground: #eff1f5;
--cta: #1e66f5;
--cta-foreground: #f5f5f6;
--ctahover: #1a5ad8;
--success: #40a02b;
--success-foreground: #22242f;
--warning: #df8e1d;
--warning-foreground: #333547;
--destructive: #d20f39;
--destructive-foreground: #eff1f5;
--border: #ccd0da;
--input: #ccd0da;
--destructive-foreground: #e9eaec;
--info: #1e66f5;
--info-foreground: #f5f5f6;
--busy: #d84e2b;
--busy-foreground: #101011;
--busy-ink: #bd4426;
--border: #caced8;
--input: #caced8;
--ring: #1e66f5;
--chart-1: #1e66f5;
--chart-2: #df8e1d;
--chart-3: #40a02b;
--chart-4: #179299;
--chart-5: #8839ef;
--sidebar: #e6e9ef;
--sidebar-foreground: #6c6f85;
--sidebar-primary: #1e66f5;
--sidebar-primary-foreground: #eff1f5;
--sidebar-accent: #dce0e8;
--sidebar-accent-foreground: #4c4f69;
--sidebar-border: #ccd0da;
--sidebar-ring: #1e66f5;
--radius: 0.625rem;
--chart-primary: #1e66f5;
--chart-secondary: #ea76cb;
--status-success: #40a02b;
--status-warning: #df8e1d;
--status-in-progress: #1e66f5;
--page-bg: #eff1f5;
--page-bg-src: '';
--panel-bg: rgb(220 224 232 / 0.72);
--panel-border: rgb(202 206 216 / 0.9);
--panel-border-bare: rgb(202 206 216 / 0.55);
--panel-raised-bg: rgb(220 224 232 / 0.95);
--panel-raised-border: rgb(202 206 216 / 1);
--panel-accent: #1e66f5;
--panel-header-bg: rgb(227 228 232 / 0.6);
--panel-header-fg: #4c4f69;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #dce0e8;
--glass-bg: rgb(220 224 232 / 0.55);
--glass-border: rgb(202 206 216 / 0.7);
--dock-bg: rgb(220 224 232 / 0.7);
--dock-border: rgb(202 206 216 / 0.8);
--dock-tooltip-bg: #e3e4e8;
--header-bg: rgb(220 224 232 / 0.8);
--header-border: rgb(202 206 216 / 0.9);
--header-fg: #4c4f69;
--header-blur: 12px;
--pixel-grid-color: rgb(121 124 136 / 0.07);
--card-grid-color: rgb(121 124 136 / 0.05);
--panel-grid-color: rgb(121 124 136 / 0.06);
--scrollbar-thumb: rgb(172 176 190 / 0.6);
--scrollbar-thumb-hover: rgb(172 176 190 / 0.85);
--scrollbar-thin-thumb: rgb(172 176 190 / 0.45);
--scrollbar-thin-thumb-hover: rgb(172 176 190 / 0.7);
--brand: #1e66f5;
--brand-foreground: #f5f5f6;
--brand-primary: #1e66f5;
--brand-accent: #179299;
--brand-warm: #d84e2b;
--brand-deep: #e3e4e8;
--brand-muted: #acb0be;
--ink: #4c4f69;
--surface-warm: #dce0e8;
--naturegreen: #40a02b;
--naturegreen-foreground: #22242f;
--duck-dark: #4c4f69;
--duck-teal: #179299;
--duck-yellow: #df8e1d;
--duck-orange: #d84e2b;
--duck-forest: #40a02b;
--duck-beige: #ced2db;
--logo-src: '/officer-logo.svg';
}
@@ -1,50 +0,0 @@
/*
CATPPUCCIN MOCHA — ported from the published palette, unchanged.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
*/
[data-theme='catppuccin-mocha'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #1e1e2e;
--foreground: #cdd6f4;
--card: #181825;
--card-foreground: #cdd6f4;
--popover: #181825;
--popover-foreground: #cdd6f4;
--primary: #89b4fa;
--primary-foreground: #1e1e2e;
--secondary: #45475a;
--secondary-foreground: #cdd6f4;
--muted: #313244;
--muted-foreground: #7f849c;
--accent: #89dceb;
--accent-foreground: #1e1e2e;
--destructive: #f38ba8;
--destructive-foreground: #1e1e2e;
--border: #45475a;
--input: #45475a;
--ring: #89b4fa;
--chart-1: #89b4fa;
--chart-2: #f9e2af;
--chart-3: #a6e3a1;
--chart-4: #94e2d5;
--chart-5: #cba6f7;
--sidebar: #181825;
--sidebar-foreground: #7f849c;
--sidebar-primary: #89b4fa;
--sidebar-primary-foreground: #1e1e2e;
--sidebar-accent: #313244;
--sidebar-accent-foreground: #cdd6f4;
--sidebar-border: #45475a;
--sidebar-ring: #89b4fa;
}
@@ -0,0 +1,94 @@
/*
Catppuccin — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/catppuccin/colors.toml (mode: dark)
*/
[data-theme='catppuccin'] {
--background: #101019;
--foreground: #cdd6f4;
--card: #1e1e2e;
--card-foreground: #cdd6f4;
--popover: #1e1e2e;
--popover-foreground: #cdd6f4;
--muted: #313244;
--muted-foreground: #bac2de;
--accent: #313244;
--accent-foreground: #cdd6f4;
--primary: #89b4fa;
--primary-foreground: #101019;
--secondary: #313244;
--secondary-foreground: #cdd6f4;
--cta: #89b4fa;
--cta-foreground: #101019;
--ctahover: #97bdfb;
--success: #a6e3a1;
--success-foreground: #101019;
--warning: #f9e2af;
--warning-foreground: #101019;
--destructive: #f38ba8;
--destructive-foreground: #101019;
--info: #89b4fa;
--info-foreground: #101019;
--busy: #f6b6ab;
--busy-foreground: #101019;
--busy-ink: #f6b6ab;
--border: #4a4c5f;
--input: #4a4c5f;
--ring: #89b4fa;
--radius: 0.625rem;
--chart-primary: #89b4fa;
--chart-secondary: #f5c2e7;
--status-success: #a6e3a1;
--status-warning: #f9e2af;
--status-in-progress: #89b4fa;
--page-bg: #101019;
--page-bg-src: '';
--panel-bg: rgb(30 30 46 / 0.72);
--panel-border: rgb(74 76 95 / 0.9);
--panel-border-bare: rgb(74 76 95 / 0.55);
--panel-raised-bg: rgb(30 30 46 / 0.95);
--panel-raised-border: rgb(74 76 95 / 1);
--panel-accent: #89b4fa;
--panel-header-bg: rgb(49 50 68 / 0.6);
--panel-header-fg: #cdd6f4;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #1e1e2e;
--glass-bg: rgb(30 30 46 / 0.55);
--glass-border: rgb(74 76 95 / 0.7);
--dock-bg: rgb(30 30 46 / 0.7);
--dock-border: rgb(74 76 95 / 0.8);
--dock-tooltip-bg: #313244;
--header-bg: rgb(30 30 46 / 0.8);
--header-border: rgb(74 76 95 / 0.9);
--header-fg: #cdd6f4;
--header-blur: 12px;
--pixel-grid-color: rgb(108 112 134 / 0.07);
--card-grid-color: rgb(108 112 134 / 0.05);
--panel-grid-color: rgb(108 112 134 / 0.06);
--scrollbar-thumb: rgb(88 91 112 / 0.6);
--scrollbar-thumb-hover: rgb(88 91 112 / 0.85);
--scrollbar-thin-thumb: rgb(88 91 112 / 0.45);
--scrollbar-thin-thumb-hover: rgb(88 91 112 / 0.7);
--brand: #89b4fa;
--brand-foreground: #101019;
--brand-primary: #89b4fa;
--brand-accent: #94e2d5;
--brand-warm: #f6b6ab;
--brand-deep: #101019;
--brand-muted: #585b70;
--ink: #cdd6f4;
--surface-warm: #1e1e2e;
--naturegreen: #a6e3a1;
--naturegreen-foreground: #101019;
--duck-dark: #cdd6f4;
--duck-teal: #94e2d5;
--duck-yellow: #f9e2af;
--duck-orange: #f6b6ab;
--duck-forest: #a6e3a1;
--duck-beige: #303042;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Ethereal — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/ethereal/colors.toml (mode: dark)
*/
[data-theme='ethereal'] {
--background: #030610;
--foreground: #ffcead;
--card: #060B1E;
--card-foreground: #ffcead;
--popover: #060B1E;
--popover-foreground: #ffcead;
--muted: #131a3a;
--muted-foreground: #c9b8a6;
--accent: #131a3a;
--accent-foreground: #ffcead;
--primary: #7d82d9;
--primary-foreground: #030610;
--secondary: #131a3a;
--secondary-foreground: #ffcead;
--cta: #7d82d9;
--cta-foreground: #030610;
--ctahover: #8d91de;
--success: #92a593;
--success-foreground: #030610;
--warning: #E9BB4F;
--warning-foreground: #030610;
--destructive: #ED5B5A;
--destructive-foreground: #030610;
--info: #7d82d9;
--info-foreground: #030610;
--busy: #eb8b54;
--busy-foreground: #030610;
--busy-ink: #eb8b54;
--border: #3d3b44;
--input: #3d3b44;
--ring: #7d82d9;
--radius: 0.625rem;
--chart-primary: #7d82d9;
--chart-secondary: #c89dc1;
--status-success: #92a593;
--status-warning: #E9BB4F;
--status-in-progress: #7d82d9;
--page-bg: #030610;
--page-bg-src: '';
--panel-bg: rgb(6 11 30 / 0.72);
--panel-border: rgb(61 59 68 / 0.9);
--panel-border-bare: rgb(61 59 68 / 0.55);
--panel-raised-bg: rgb(6 11 30 / 0.95);
--panel-raised-border: rgb(61 59 68 / 1);
--panel-accent: #7d82d9;
--panel-header-bg: rgb(19 26 58 / 0.6);
--panel-header-fg: #ffcead;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #060B1E;
--glass-bg: rgb(6 11 30 / 0.55);
--glass-border: rgb(61 59 68 / 0.7);
--dock-bg: rgb(6 11 30 / 0.7);
--dock-border: rgb(61 59 68 / 0.8);
--dock-tooltip-bg: #131a3a;
--header-bg: rgb(6 11 30 / 0.8);
--header-border: rgb(61 59 68 / 0.9);
--header-fg: #ffcead;
--header-blur: 12px;
--pixel-grid-color: rgb(109 125 182 / 0.07);
--card-grid-color: rgb(109 125 182 / 0.05);
--panel-grid-color: rgb(109 125 182 / 0.06);
--scrollbar-thumb: rgb(109 125 182 / 0.6);
--scrollbar-thumb-hover: rgb(109 125 182 / 0.85);
--scrollbar-thin-thumb: rgb(109 125 182 / 0.45);
--scrollbar-thin-thumb-hover: rgb(109 125 182 / 0.7);
--brand: #7d82d9;
--brand-foreground: #030610;
--brand-primary: #7d82d9;
--brand-accent: #a3bfd1;
--brand-warm: #eb8b54;
--brand-deep: #030610;
--brand-muted: #6d7db6;
--ink: #ffcead;
--surface-warm: #060B1E;
--naturegreen: #92a593;
--naturegreen-foreground: #030610;
--duck-dark: #ffcead;
--duck-teal: #a3bfd1;
--duck-yellow: #E9BB4F;
--duck-orange: #eb8b54;
--duck-forest: #92a593;
--duck-beige: #1f1f2c;
--logo-src: '/officer-logo.svg';
}
+83 -39
View File
@@ -1,50 +1,94 @@
/*
EVERFOREST — ported from the published palette, unchanged.
Everforest — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/everforest/colors.toml (mode: dark)
*/
[data-theme='everforest'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #2d353b;
--background: #181d20;
--foreground: #d3c6aa;
--card: #272e33;
--card: #2d353b;
--card-foreground: #d3c6aa;
--popover: #272e33;
--popover: #2d353b;
--popover-foreground: #d3c6aa;
--primary: #a7c080;
--primary-foreground: #2d353b;
--secondary: #3d484d;
--muted: #343f44;
--muted-foreground: #9faba2;
--accent: #343f44;
--accent-foreground: #d3c6aa;
--primary: #7fbbb3;
--primary-foreground: #181d20;
--secondary: #343f44;
--secondary-foreground: #d3c6aa;
--muted: #374247;
--muted-foreground: #859289;
--accent: #83c092;
--accent-foreground: #2d353b;
--cta: #7fbbb3;
--cta-foreground: #181d20;
--ctahover: #8ec3bc;
--success: #a7c080;
--success-foreground: #181d20;
--warning: #dbbc7f;
--warning-foreground: #181d20;
--destructive: #e67e80;
--destructive-foreground: #d3c6aa;
--border: #3d484d;
--input: #3d484d;
--ring: #a7c080;
--chart-1: #a7c080;
--chart-2: #dbbc7f;
--chart-3: #83c092;
--chart-4: #7fbbb3;
--chart-5: #d699b6;
--sidebar: #272e33;
--sidebar-foreground: #859289;
--sidebar-primary: #a7c080;
--sidebar-primary-foreground: #2d353b;
--sidebar-accent: #374247;
--sidebar-accent-foreground: #d3c6aa;
--sidebar-border: #3d484d;
--sidebar-ring: #a7c080;
--destructive-foreground: #181d20;
--info: #7fbbb3;
--info-foreground: #181d20;
--busy: #e09d7f;
--busy-foreground: #181d20;
--busy-ink: #e09d7f;
--border: #4c5557;
--input: #4c5557;
--ring: #7fbbb3;
--radius: 0.625rem;
--chart-primary: #7fbbb3;
--chart-secondary: #d699b6;
--status-success: #a7c080;
--status-warning: #dbbc7f;
--status-in-progress: #7fbbb3;
--page-bg: #181d20;
--page-bg-src: '';
--panel-bg: rgb(45 53 59 / 0.72);
--panel-border: rgb(76 85 87 / 0.9);
--panel-border-bare: rgb(76 85 87 / 0.55);
--panel-raised-bg: rgb(45 53 59 / 0.95);
--panel-raised-border: rgb(76 85 87 / 1);
--panel-accent: #7fbbb3;
--panel-header-bg: rgb(52 63 68 / 0.6);
--panel-header-fg: #d3c6aa;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #2d353b;
--glass-bg: rgb(45 53 59 / 0.55);
--glass-border: rgb(76 85 87 / 0.7);
--dock-bg: rgb(45 53 59 / 0.7);
--dock-border: rgb(76 85 87 / 0.8);
--dock-tooltip-bg: #343f44;
--header-bg: rgb(45 53 59 / 0.8);
--header-border: rgb(76 85 87 / 0.9);
--header-fg: #d3c6aa;
--header-blur: 12px;
--pixel-grid-color: rgb(119 126 130 / 0.07);
--card-grid-color: rgb(119 126 130 / 0.05);
--panel-grid-color: rgb(119 126 130 / 0.06);
--scrollbar-thumb: rgb(71 82 88 / 0.6);
--scrollbar-thumb-hover: rgb(71 82 88 / 0.85);
--scrollbar-thin-thumb: rgb(71 82 88 / 0.45);
--scrollbar-thin-thumb-hover: rgb(71 82 88 / 0.7);
--brand: #7fbbb3;
--brand-foreground: #181d20;
--brand-primary: #7fbbb3;
--brand-accent: #83c092;
--brand-warm: #e09d7f;
--brand-deep: #181d20;
--brand-muted: #475258;
--ink: #d3c6aa;
--surface-warm: #2d353b;
--naturegreen: #a7c080;
--naturegreen-foreground: #181d20;
--duck-dark: #d3c6aa;
--duck-teal: #83c092;
--duck-yellow: #dbbc7f;
--duck-orange: #e09d7f;
--duck-forest: #a7c080;
--duck-beige: #3e4446;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Flexoki Light — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/flexoki-light/colors.toml (mode: light)
*/
[data-theme='flexoki-light'] {
--background: #FFFCF0;
--foreground: #100F0F;
--card: #E6E4D9;
--card-foreground: #100F0F;
--popover: #E6E4D9;
--popover-foreground: #100F0F;
--muted: #f2efe4;
--muted-foreground: #403E3C;
--accent: #f2efe4;
--accent-foreground: #100F0F;
--primary: #205EA6;
--primary-foreground: #e5e2d8;
--secondary: #f2efe4;
--secondary-foreground: #100F0F;
--cta: #205EA6;
--cta-foreground: #e5e2d8;
--ctahover: #1c5392;
--success: #879A39;
--success-foreground: #100F0F;
--warning: #D0A215;
--warning-foreground: #100F0F;
--destructive: #D14D41;
--destructive-foreground: #0d0c0c;
--info: #205EA6;
--info-foreground: #e5e2d8;
--busy: #d0772b;
--busy-foreground: #100F0F;
--busy-ink: #ac6223;
--border: #cbc9c0;
--input: #cbc9c0;
--ring: #205EA6;
--radius: 0.625rem;
--chart-primary: #205EA6;
--chart-secondary: #CE5D97;
--status-success: #879A39;
--status-warning: #D0A215;
--status-in-progress: #205EA6;
--page-bg: #FFFCF0;
--page-bg-src: '';
--panel-bg: rgb(230 228 217 / 0.72);
--panel-border: rgb(203 201 192 / 0.9);
--panel-border-bare: rgb(203 201 192 / 0.55);
--panel-raised-bg: rgb(230 228 217 / 0.95);
--panel-raised-border: rgb(203 201 192 / 1);
--panel-accent: #205EA6;
--panel-header-bg: rgb(242 239 228 / 0.6);
--panel-header-fg: #100F0F;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #E6E4D9;
--glass-bg: rgb(230 228 217 / 0.55);
--glass-border: rgb(203 201 192 / 0.7);
--dock-bg: rgb(230 228 217 / 0.7);
--dock-border: rgb(203 201 192 / 0.8);
--dock-tooltip-bg: #f2efe4;
--header-bg: rgb(230 228 217 / 0.8);
--header-border: rgb(203 201 192 / 0.9);
--header-fg: #100F0F;
--header-blur: 12px;
--pixel-grid-color: rgb(132 130 125 / 0.07);
--card-grid-color: rgb(132 130 125 / 0.05);
--panel-grid-color: rgb(132 130 125 / 0.06);
--scrollbar-thumb: rgb(183 181 172 / 0.6);
--scrollbar-thumb-hover: rgb(183 181 172 / 0.85);
--scrollbar-thin-thumb: rgb(183 181 172 / 0.45);
--scrollbar-thin-thumb-hover: rgb(183 181 172 / 0.7);
--brand: #205EA6;
--brand-foreground: #e5e2d8;
--brand-primary: #205EA6;
--brand-accent: #3AA99F;
--brand-warm: #d0772b;
--brand-deep: #f2efe4;
--brand-muted: #B7B5AC;
--ink: #100F0F;
--surface-warm: #E6E4D9;
--naturegreen: #879A39;
--naturegreen-foreground: #100F0F;
--duck-dark: #100F0F;
--duck-teal: #3AA99F;
--duck-yellow: #D0A215;
--duck-orange: #d0772b;
--duck-forest: #879A39;
--duck-beige: #d1cfc5;
--logo-src: '/officer-logo.svg';
}
+87 -43
View File
@@ -1,50 +1,94 @@
/*
GRUVBOX — ported from the published palette, unchanged.
Gruvbox — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/gruvbox/colors.toml (mode: dark)
*/
[data-theme='gruvbox'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #282828;
--foreground: #ebdbb2;
--card: #1d2021;
--card-foreground: #ebdbb2;
--popover: #1d2021;
--popover-foreground: #ebdbb2;
--primary: #83a598;
--primary-foreground: #282828;
--secondary: #504945;
--secondary-foreground: #ebdbb2;
--background: #161616;
--foreground: #d4be98;
--card: #282828;
--card-foreground: #d4be98;
--popover: #282828;
--popover-foreground: #d4be98;
--muted: #3c3836;
--muted-foreground: #a89984;
--accent: #8ec07c;
--accent-foreground: #282828;
--destructive: #fb4934;
--destructive-foreground: #ebdbb2;
--border: #504945;
--input: #504945;
--ring: #83a598;
--chart-1: #83a598;
--chart-2: #fabd2f;
--chart-3: #b8bb26;
--chart-4: #8ec07c;
--chart-5: #d3869b;
--sidebar: #1d2021;
--sidebar-foreground: #a89984;
--sidebar-primary: #83a598;
--sidebar-primary-foreground: #282828;
--sidebar-accent: #3c3836;
--sidebar-accent-foreground: #ebdbb2;
--sidebar-border: #504945;
--sidebar-ring: #83a598;
--muted-foreground: #bdae93;
--accent: #3c3836;
--accent-foreground: #d4be98;
--primary: #7daea3;
--primary-foreground: #161616;
--secondary: #3c3836;
--secondary-foreground: #d4be98;
--cta: #7daea3;
--cta-foreground: #161616;
--ctahover: #8db8ae;
--success: #a9b665;
--success-foreground: #161616;
--warning: #d8a657;
--warning-foreground: #161616;
--destructive: #ea6962;
--destructive-foreground: #161616;
--info: #7daea3;
--info-foreground: #161616;
--busy: #e1875c;
--busy-foreground: #161616;
--busy-ink: #e1875c;
--border: #524e46;
--input: #524e46;
--ring: #7daea3;
--radius: 0.625rem;
--chart-primary: #7daea3;
--chart-secondary: #d3869b;
--status-success: #a9b665;
--status-warning: #d8a657;
--status-in-progress: #7daea3;
--page-bg: #161616;
--page-bg-src: '';
--panel-bg: rgb(40 40 40 / 0.72);
--panel-border: rgb(82 78 70 / 0.9);
--panel-border-bare: rgb(82 78 70 / 0.55);
--panel-raised-bg: rgb(40 40 40 / 0.95);
--panel-raised-border: rgb(82 78 70 / 1);
--panel-accent: #7daea3;
--panel-header-bg: rgb(60 56 54 / 0.6);
--panel-header-fg: #d4be98;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #282828;
--glass-bg: rgb(40 40 40 / 0.55);
--glass-border: rgb(82 78 70 / 0.7);
--dock-bg: rgb(40 40 40 / 0.7);
--dock-border: rgb(82 78 70 / 0.8);
--dock-tooltip-bg: #3c3836;
--header-bg: rgb(40 40 40 / 0.8);
--header-border: rgb(82 78 70 / 0.9);
--header-fg: #d4be98;
--header-blur: 12px;
--pixel-grid-color: rgb(124 111 100 / 0.07);
--card-grid-color: rgb(124 111 100 / 0.05);
--panel-grid-color: rgb(124 111 100 / 0.06);
--scrollbar-thumb: rgb(102 92 84 / 0.6);
--scrollbar-thumb-hover: rgb(102 92 84 / 0.85);
--scrollbar-thin-thumb: rgb(102 92 84 / 0.45);
--scrollbar-thin-thumb-hover: rgb(102 92 84 / 0.7);
--brand: #7daea3;
--brand-foreground: #161616;
--brand-primary: #7daea3;
--brand-accent: #89b482;
--brand-warm: #e1875c;
--brand-deep: #161616;
--brand-muted: #665c54;
--ink: #d4be98;
--surface-warm: #282828;
--naturegreen: #a9b665;
--naturegreen-foreground: #161616;
--duck-dark: #d4be98;
--duck-teal: #89b482;
--duck-yellow: #d8a657;
--duck-orange: #e1875c;
--duck-forest: #a9b665;
--duck-beige: #393733;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Hackerman — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/hackerman/colors.toml (mode: dark)
*/
[data-theme='hackerman'] {
--background: #06060c;
--foreground: #ddf7ff;
--card: #0B0C16;
--card-foreground: #ddf7ff;
--popover: #0B0C16;
--popover-foreground: #ddf7ff;
--muted: #151828;
--muted-foreground: #b5c5db;
--accent: #151828;
--accent-foreground: #ddf7ff;
--primary: #82FB9C;
--primary-foreground: #06060c;
--secondary: #151828;
--secondary-foreground: #ddf7ff;
--cta: #82FB9C;
--cta-foreground: #06060c;
--ctahover: #91fba8;
--success: #4fe88f;
--success-foreground: #06060c;
--warning: #50f7d4;
--warning-foreground: #06060c;
--destructive: #50f872;
--destructive-foreground: #06060c;
--info: #829dd4;
--info-foreground: #06060c;
--busy: #50f7a3;
--busy-foreground: #06060c;
--busy-ink: #50f7a3;
--border: #3b404d;
--input: #3b404d;
--ring: #82FB9C;
--radius: 0.625rem;
--chart-primary: #82FB9C;
--chart-secondary: #86a7df;
--status-success: #4fe88f;
--status-warning: #50f7d4;
--status-in-progress: #829dd4;
--page-bg: #06060c;
--page-bg-src: '';
--panel-bg: rgb(11 12 22 / 0.72);
--panel-border: rgb(59 64 77 / 0.9);
--panel-border-bare: rgb(59 64 77 / 0.55);
--panel-raised-bg: rgb(11 12 22 / 0.95);
--panel-raised-border: rgb(59 64 77 / 1);
--panel-accent: #82FB9C;
--panel-header-bg: rgb(21 24 40 / 0.6);
--panel-header-fg: #ddf7ff;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #0B0C16;
--glass-bg: rgb(11 12 22 / 0.55);
--glass-border: rgb(59 64 77 / 0.7);
--dock-bg: rgb(11 12 22 / 0.7);
--dock-border: rgb(59 64 77 / 0.8);
--dock-tooltip-bg: #151828;
--header-bg: rgb(11 12 22 / 0.8);
--header-border: rgb(59 64 77 / 0.9);
--header-fg: #ddf7ff;
--header-blur: 12px;
--pixel-grid-color: rgb(106 110 149 / 0.07);
--card-grid-color: rgb(106 110 149 / 0.05);
--panel-grid-color: rgb(106 110 149 / 0.06);
--scrollbar-thumb: rgb(45 52 80 / 0.6);
--scrollbar-thumb-hover: rgb(45 52 80 / 0.85);
--scrollbar-thin-thumb: rgb(45 52 80 / 0.45);
--scrollbar-thin-thumb-hover: rgb(45 52 80 / 0.7);
--brand: #82FB9C;
--brand-foreground: #06060c;
--brand-primary: #82FB9C;
--brand-accent: #7cf8f7;
--brand-warm: #50f7a3;
--brand-deep: #06060c;
--brand-muted: #2d3450;
--ink: #ddf7ff;
--surface-warm: #0B0C16;
--naturegreen: #4fe88f;
--naturegreen-foreground: #06060c;
--duck-dark: #ddf7ff;
--duck-teal: #7cf8f7;
--duck-yellow: #50f7d4;
--duck-orange: #50f7a3;
--duck-forest: #4fe88f;
--duck-beige: #20242d;
--logo-src: '/officer-logo.svg';
}
+84 -40
View File
@@ -1,50 +1,94 @@
/*
KANAGAWA — ported from the published palette, unchanged.
Kanagawa — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/kanagawa/colors.toml (mode: dark)
*/
[data-theme='kanagawa'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #1f1f28;
--background: #111116;
--foreground: #dcd7ba;
--card: #16161d;
--card: #1f1f28;
--card-foreground: #dcd7ba;
--popover: #16161d;
--popover: #1f1f28;
--popover-foreground: #dcd7ba;
--primary: #7e9cd8;
--primary-foreground: #1f1f28;
--secondary: #2a2a37;
--secondary-foreground: #dcd7ba;
--muted: #223249;
--muted-foreground: #727169;
--accent: #7fb4ca;
--accent-foreground: #1f1f28;
--destructive: #e82424;
--destructive-foreground: #dcd7ba;
--border: #2a2a37;
--input: #2a2a37;
--ring: #7e9cd8;
--chart-1: #7e9cd8;
--chart-2: #ffa066;
--chart-3: #98bb6c;
--chart-4: #7aa89f;
--chart-5: #957fb8;
--sidebar: #16161d;
--sidebar-foreground: #727169;
--sidebar-primary: #7e9cd8;
--sidebar-primary-foreground: #1f1f28;
--sidebar-accent: #223249;
--sidebar-accent-foreground: #dcd7ba;
--sidebar-border: #2a2a37;
--sidebar-ring: #7e9cd8;
--muted-foreground: #c8c093;
--accent: #223249;
--accent-foreground: #dcd7ba;
--primary: #dcd7ba;
--primary-foreground: #111116;
--secondary: #223249;
--secondary-foreground: #dcd7ba;
--cta: #dcd7ba;
--cta-foreground: #111116;
--ctahover: #e0dcc2;
--success: #76946a;
--success-foreground: #111116;
--warning: #c0a36e;
--warning-foreground: #111116;
--destructive: #c34043;
--destructive-foreground: #f3f3f3;
--info: #7e9cd8;
--info-foreground: #111116;
--busy: #c17158;
--busy-foreground: #111116;
--busy-ink: #c17158;
--border: #4e4c46;
--input: #4e4c46;
--ring: #dcd7ba;
--radius: 0.625rem;
--chart-primary: #dcd7ba;
--chart-secondary: #957fb8;
--status-success: #76946a;
--status-warning: #c0a36e;
--status-in-progress: #7e9cd8;
--page-bg: #111116;
--page-bg-src: '';
--panel-bg: rgb(31 31 40 / 0.72);
--panel-border: rgb(78 76 70 / 0.9);
--panel-border-bare: rgb(78 76 70 / 0.55);
--panel-raised-bg: rgb(31 31 40 / 0.95);
--panel-raised-border: rgb(78 76 70 / 1);
--panel-accent: #dcd7ba;
--panel-header-bg: rgb(34 50 73 / 0.6);
--panel-header-fg: #dcd7ba;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #1f1f28;
--glass-bg: rgb(31 31 40 / 0.55);
--glass-border: rgb(78 76 70 / 0.7);
--dock-bg: rgb(31 31 40 / 0.7);
--dock-border: rgb(78 76 70 / 0.8);
--dock-tooltip-bg: #223249;
--header-bg: rgb(31 31 40 / 0.8);
--header-border: rgb(78 76 70 / 0.9);
--header-fg: #dcd7ba;
--header-blur: 12px;
--pixel-grid-color: rgb(114 113 105 / 0.07);
--card-grid-color: rgb(114 113 105 / 0.05);
--panel-grid-color: rgb(114 113 105 / 0.06);
--scrollbar-thumb: rgb(84 84 109 / 0.6);
--scrollbar-thumb-hover: rgb(84 84 109 / 0.85);
--scrollbar-thin-thumb: rgb(84 84 109 / 0.45);
--scrollbar-thin-thumb-hover: rgb(84 84 109 / 0.7);
--brand: #dcd7ba;
--brand-foreground: #111116;
--brand-primary: #dcd7ba;
--brand-accent: #6a9589;
--brand-warm: #c17158;
--brand-deep: #111116;
--brand-muted: #54546D;
--ink: #dcd7ba;
--surface-warm: #1f1f28;
--naturegreen: #76946a;
--naturegreen-foreground: #111116;
--duck-dark: #dcd7ba;
--duck-teal: #6a9589;
--duck-yellow: #c0a36e;
--duck-orange: #c17158;
--duck-forest: #76946a;
--duck-beige: #323137;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Last Horizon — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/last-horizon/colors.toml (mode: dark)
*/
[data-theme='last-horizon'] {
--background: #060606;
--foreground: #FAFCFB;
--card: #0c0b0c;
--card-foreground: #FAFCFB;
--popover: #0c0b0c;
--popover-foreground: #FAFCFB;
--muted: #0c0b0c;
--muted-foreground: #cfd3cd;
--accent: #0c0b0c;
--accent-foreground: #FAFCFB;
--primary: #b59790;
--primary-foreground: #060606;
--secondary: #0c0b0c;
--secondary-foreground: #FAFCFB;
--cta: #b59790;
--cta-foreground: #060606;
--ctahover: #bea39d;
--success: #87a9b0;
--success-foreground: #060606;
--warning: #6B5E73;
--warning-foreground: #e3dedd;
--destructive: #c38b7b;
--destructive-foreground: #060606;
--info: #b59790;
--info-foreground: #060606;
--busy: #6B5E73;
--busy-foreground: #e3dedd;
--busy-ink: #817688;
--border: #434342;
--input: #434342;
--ring: #b59790;
--radius: 0.625rem;
--chart-primary: #b59790;
--chart-secondary: #c4d8e2;
--status-success: #87a9b0;
--status-warning: #6B5E73;
--status-in-progress: #b59790;
--page-bg: #060606;
--page-bg-src: '';
--panel-bg: rgb(12 11 12 / 0.72);
--panel-border: rgb(67 67 66 / 0.9);
--panel-border-bare: rgb(67 67 66 / 0.55);
--panel-raised-bg: rgb(12 11 12 / 0.95);
--panel-raised-border: rgb(67 67 66 / 1);
--panel-accent: #b59790;
--panel-header-bg: rgb(12 11 12 / 0.6);
--panel-header-fg: #FAFCFB;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #0c0b0c;
--glass-bg: rgb(12 11 12 / 0.55);
--glass-border: rgb(67 67 66 / 0.7);
--dock-bg: rgb(12 11 12 / 0.7);
--dock-border: rgb(67 67 66 / 0.8);
--dock-tooltip-bg: #0c0b0c;
--header-bg: rgb(12 11 12 / 0.8);
--header-border: rgb(67 67 66 / 0.9);
--header-fg: #FAFCFB;
--header-blur: 12px;
--pixel-grid-color: rgb(101 91 94 / 0.07);
--card-grid-color: rgb(101 91 94 / 0.05);
--panel-grid-color: rgb(101 91 94 / 0.06);
--scrollbar-thumb: rgb(88 78 81 / 0.6);
--scrollbar-thumb-hover: rgb(88 78 81 / 0.85);
--scrollbar-thin-thumb: rgb(88 78 81 / 0.45);
--scrollbar-thin-thumb-hover: rgb(88 78 81 / 0.7);
--brand: #b59790;
--brand-foreground: #060606;
--brand-primary: #b59790;
--brand-accent: #a5a0b6;
--brand-warm: #6B5E73;
--brand-deep: #060606;
--brand-muted: #584e51;
--ink: #FAFCFB;
--surface-warm: #0c0b0c;
--naturegreen: #87a9b0;
--naturegreen-foreground: #060606;
--duck-dark: #FAFCFB;
--duck-teal: #a5a0b6;
--duck-yellow: #6B5E73;
--duck-orange: #6B5E73;
--duck-forest: #87a9b0;
--duck-beige: #242324;
--logo-src: '/officer-logo.svg';
}
+94
View File
@@ -0,0 +1,94 @@
/*
Lumon — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/lumon/colors.toml (mode: dark)
*/
[data-theme='lumon'] {
--background: #0b1216;
--foreground: #d6e2ee;
--card: #16242d;
--card-foreground: #d6e2ee;
--popover: #16242d;
--popover-foreground: #d6e2ee;
--muted: #1b2d40;
--muted-foreground: #d6e2ee;
--accent: #1b2d40;
--accent-foreground: #d6e2ee;
--primary: #8bc9eb;
--primary-foreground: #0b1216;
--secondary: #1b2d40;
--secondary-foreground: #d6e2ee;
--cta: #8bc9eb;
--cta-foreground: #0b1216;
--ctahover: #99cfed;
--success: #5e95bc;
--success-foreground: #0b1216;
--warning: #6fa4c9;
--warning-foreground: #0b1216;
--destructive: #4d86b0;
--destructive-foreground: #0b1216;
--info: #6fb8e3;
--info-foreground: #0b1216;
--busy: #8bc9eb;
--busy-foreground: #0b1216;
--busy-ink: #8bc9eb;
--border: #4c5963;
--input: #4c5963;
--ring: #8bc9eb;
--radius: 0.625rem;
--chart-primary: #8bc9eb;
--chart-secondary: #8bc9eb;
--status-success: #5e95bc;
--status-warning: #6fa4c9;
--status-in-progress: #6fb8e3;
--page-bg: #0b1216;
--page-bg-src: '';
--panel-bg: rgb(22 36 45 / 0.72);
--panel-border: rgb(76 89 99 / 0.9);
--panel-border-bare: rgb(76 89 99 / 0.55);
--panel-raised-bg: rgb(22 36 45 / 0.95);
--panel-raised-border: rgb(76 89 99 / 1);
--panel-accent: #8bc9eb;
--panel-header-bg: rgb(27 45 64 / 0.6);
--panel-header-fg: #d6e2ee;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #16242d;
--glass-bg: rgb(22 36 45 / 0.55);
--glass-border: rgb(76 89 99 / 0.7);
--dock-bg: rgb(22 36 45 / 0.7);
--dock-border: rgb(76 89 99 / 0.8);
--dock-tooltip-bg: #1b2d40;
--header-bg: rgb(22 36 45 / 0.8);
--header-border: rgb(76 89 99 / 0.9);
--header-fg: #d6e2ee;
--header-blur: 12px;
--pixel-grid-color: rgb(77 134 176 / 0.07);
--card-grid-color: rgb(77 134 176 / 0.05);
--panel-grid-color: rgb(77 134 176 / 0.06);
--scrollbar-thumb: rgb(48 72 96 / 0.6);
--scrollbar-thumb-hover: rgb(48 72 96 / 0.85);
--scrollbar-thin-thumb: rgb(48 72 96 / 0.45);
--scrollbar-thin-thumb-hover: rgb(48 72 96 / 0.7);
--brand: #8bc9eb;
--brand-foreground: #0b1216;
--brand-primary: #8bc9eb;
--brand-accent: #b4e4f6;
--brand-warm: #8bc9eb;
--brand-deep: #0b1216;
--brand-muted: #304860;
--ink: #d6e2ee;
--surface-warm: #16242d;
--naturegreen: #5e95bc;
--naturegreen-foreground: #0b1216;
--duck-dark: #d6e2ee;
--duck-teal: #b4e4f6;
--duck-yellow: #6fa4c9;
--duck-orange: #8bc9eb;
--duck-forest: #5e95bc;
--duck-beige: #293740;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Lupine — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/lupine/colors.toml (mode: light)
*/
[data-theme='lupine'] {
--background: #fafafa;
--foreground: #212121;
--card: #f5f5f5;
--card-foreground: #212121;
--popover: #f5f5f5;
--popover-foreground: #212121;
--muted: #ececec;
--muted-foreground: #424242;
--accent: #ececec;
--accent-foreground: #212121;
--primary: #3264eb;
--primary-foreground: #f2f2f2;
--secondary: #ececec;
--secondary-foreground: #212121;
--cta: #3264eb;
--cta-foreground: #f2f2f2;
--ctahover: #2c58cf;
--success: #4a2fd0;
--success-foreground: #dedede;
--warning: #026fde;
--warning-foreground: #f9f9f9;
--destructive: #c900c4;
--destructive-foreground: #f9f9f9;
--info: #3264eb;
--info-foreground: #f2f2f2;
--busy: #026fde;
--busy-foreground: #f9f9f9;
--busy-ink: #026fde;
--border: #d1d1d1;
--input: #d1d1d1;
--ring: #3264eb;
--radius: 0.625rem;
--chart-primary: #3264eb;
--chart-secondary: #8a4ad7;
--status-success: #4a2fd0;
--status-warning: #026fde;
--status-in-progress: #3264eb;
--page-bg: #fafafa;
--page-bg-src: '';
--panel-bg: rgb(245 245 245 / 0.72);
--panel-border: rgb(209 209 209 / 0.9);
--panel-border-bare: rgb(209 209 209 / 0.55);
--panel-raised-bg: rgb(245 245 245 / 0.95);
--panel-raised-border: rgb(209 209 209 / 1);
--panel-accent: #3264eb;
--panel-header-bg: rgb(236 236 236 / 0.6);
--panel-header-fg: #212121;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #f5f5f5;
--glass-bg: rgb(245 245 245 / 0.55);
--glass-border: rgb(209 209 209 / 0.7);
--dock-bg: rgb(245 245 245 / 0.7);
--dock-border: rgb(209 209 209 / 0.8);
--dock-tooltip-bg: #ececec;
--header-bg: rgb(245 245 245 / 0.8);
--header-border: rgb(209 209 209 / 0.9);
--header-fg: #212121;
--header-blur: 12px;
--pixel-grid-color: rgb(117 117 117 / 0.07);
--card-grid-color: rgb(117 117 117 / 0.05);
--panel-grid-color: rgb(117 117 117 / 0.06);
--scrollbar-thumb: rgb(158 158 158 / 0.6);
--scrollbar-thumb-hover: rgb(158 158 158 / 0.85);
--scrollbar-thin-thumb: rgb(158 158 158 / 0.45);
--scrollbar-thin-thumb-hover: rgb(158 158 158 / 0.7);
--brand: #3264eb;
--brand-foreground: #f2f2f2;
--brand-primary: #3264eb;
--brand-accent: #0c67de;
--brand-warm: #026fde;
--brand-deep: #ececec;
--brand-muted: #9e9e9e;
--ink: #212121;
--surface-warm: #f5f5f5;
--naturegreen: #4a2fd0;
--naturegreen-foreground: #dedede;
--duck-dark: #212121;
--duck-teal: #0c67de;
--duck-yellow: #026fde;
--duck-orange: #026fde;
--duck-forest: #4a2fd0;
--duck-beige: #e0e0e0;
--logo-src: '/officer-logo.svg';
}
+86 -42
View File
@@ -1,50 +1,94 @@
/*
MATTE BLACK — ported from the published palette, unchanged.
Matte Black — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/matte-black/colors.toml (mode: dark)
*/
[data-theme='matte-black'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #0a0a0a;
--foreground: #e0e0e0;
--background: #090909;
--foreground: #bebebe;
--card: #121212;
--card-foreground: #e0e0e0;
--card-foreground: #bebebe;
--popover: #121212;
--popover-foreground: #e0e0e0;
--primary: #ffffff;
--primary-foreground: #0a0a0a;
--secondary: #2a2a2a;
--secondary-foreground: #e0e0e0;
--muted: #1a1a1a;
--muted-foreground: #9a9a9a;
--accent: #d0d0d0;
--accent-foreground: #0a0a0a;
--destructive: #ff4444;
--destructive-foreground: #e0e0e0;
--border: #2a2a2a;
--input: #2a2a2a;
--ring: #ffffff;
--chart-1: #ffffff;
--chart-2: #cccccc;
--chart-3: #999999;
--chart-4: #666666;
--chart-5: #444444;
--sidebar: #121212;
--sidebar-foreground: #9a9a9a;
--sidebar-primary: #ffffff;
--sidebar-primary-foreground: #0a0a0a;
--sidebar-accent: #1a1a1a;
--sidebar-accent-foreground: #e0e0e0;
--sidebar-border: #2a2a2a;
--sidebar-ring: #ffffff;
--popover-foreground: #bebebe;
--muted: #1e1e1e;
--muted-foreground: #8a8a8d;
--accent: #1e1e1e;
--accent-foreground: #bebebe;
--primary: #e68e0d;
--primary-foreground: #090909;
--secondary: #1e1e1e;
--secondary-foreground: #bebebe;
--cta: #e68e0d;
--cta-foreground: #090909;
--ctahover: #e99c2a;
--success: #FFC107;
--success-foreground: #090909;
--warning: #b91c1c;
--warning-foreground: #d8d8d8;
--destructive: #D35F5F;
--destructive-foreground: #090909;
--info: #e68e0d;
--info-foreground: #090909;
--busy: #c63d3d;
--busy-foreground: #f3f3f3;
--busy-ink: #cc5050;
--border: #343434;
--input: #343434;
--ring: #e68e0d;
--radius: 0.625rem;
--chart-primary: #e68e0d;
--chart-secondary: #D35F5F;
--status-success: #FFC107;
--status-warning: #b91c1c;
--status-in-progress: #e68e0d;
--page-bg: #090909;
--page-bg-src: '';
--panel-bg: rgb(18 18 18 / 0.72);
--panel-border: rgb(52 52 52 / 0.9);
--panel-border-bare: rgb(52 52 52 / 0.55);
--panel-raised-bg: rgb(18 18 18 / 0.95);
--panel-raised-border: rgb(52 52 52 / 1);
--panel-accent: #e68e0d;
--panel-header-bg: rgb(30 30 30 / 0.6);
--panel-header-fg: #bebebe;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #121212;
--glass-bg: rgb(18 18 18 / 0.55);
--glass-border: rgb(52 52 52 / 0.7);
--dock-bg: rgb(18 18 18 / 0.7);
--dock-border: rgb(52 52 52 / 0.8);
--dock-tooltip-bg: #1e1e1e;
--header-bg: rgb(18 18 18 / 0.8);
--header-border: rgb(52 52 52 / 0.9);
--header-fg: #bebebe;
--header-blur: 12px;
--pixel-grid-color: rgb(98 98 98 / 0.07);
--card-grid-color: rgb(98 98 98 / 0.05);
--panel-grid-color: rgb(98 98 98 / 0.06);
--scrollbar-thumb: rgb(51 51 51 / 0.6);
--scrollbar-thumb-hover: rgb(51 51 51 / 0.85);
--scrollbar-thin-thumb: rgb(51 51 51 / 0.45);
--scrollbar-thin-thumb-hover: rgb(51 51 51 / 0.7);
--brand: #e68e0d;
--brand-foreground: #090909;
--brand-primary: #e68e0d;
--brand-accent: #bebebe;
--brand-warm: #c63d3d;
--brand-deep: #090909;
--brand-muted: #333333;
--ink: #bebebe;
--surface-warm: #121212;
--naturegreen: #FFC107;
--naturegreen-foreground: #090909;
--duck-dark: #bebebe;
--duck-teal: #bebebe;
--duck-yellow: #b91c1c;
--duck-orange: #c63d3d;
--duck-forest: #FFC107;
--duck-beige: #232323;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Miasma — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/miasma/colors.toml (mode: dark)
*/
[data-theme='miasma'] {
--background: #121212;
--foreground: #c2c2b0;
--card: #222222;
--card-foreground: #c2c2b0;
--popover: #222222;
--popover-foreground: #c2c2b0;
--muted: #2c2c2c;
--muted-foreground: #939388;
--accent: #2c2c2c;
--accent-foreground: #c2c2b0;
--primary: #78824b;
--primary-foreground: #121212;
--secondary: #2c2c2c;
--secondary-foreground: #c2c2b0;
--cta: #78824b;
--cta-foreground: #121212;
--ctahover: #889161;
--success: #5f875f;
--success-foreground: #121212;
--warning: #b36d43;
--warning-foreground: #121212;
--destructive: #685742;
--destructive-foreground: #d3d3c6;
--info: #78824b;
--info-foreground: #121212;
--busy: #8d6242;
--busy-foreground: #ededed;
--busy-ink: #9b765a;
--border: #3f3f3c;
--input: #3f3f3c;
--ring: #78824b;
--radius: 0.625rem;
--chart-primary: #78824b;
--chart-secondary: #bb7744;
--status-success: #5f875f;
--status-warning: #b36d43;
--status-in-progress: #78824b;
--page-bg: #121212;
--page-bg-src: '';
--panel-bg: rgb(34 34 34 / 0.72);
--panel-border: rgb(63 63 60 / 0.9);
--panel-border-bare: rgb(63 63 60 / 0.55);
--panel-raised-bg: rgb(34 34 34 / 0.95);
--panel-raised-border: rgb(63 63 60 / 1);
--panel-accent: #78824b;
--panel-header-bg: rgb(44 44 44 / 0.6);
--panel-header-fg: #c2c2b0;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #222222;
--glass-bg: rgb(34 34 34 / 0.55);
--glass-border: rgb(63 63 60 / 0.7);
--dock-bg: rgb(34 34 34 / 0.7);
--dock-border: rgb(63 63 60 / 0.8);
--dock-tooltip-bg: #2c2c2c;
--header-bg: rgb(34 34 34 / 0.8);
--header-border: rgb(63 63 60 / 0.9);
--header-fg: #c2c2b0;
--header-blur: 12px;
--pixel-grid-color: rgb(111 111 111 / 0.07);
--card-grid-color: rgb(111 111 111 / 0.05);
--panel-grid-color: rgb(111 111 111 / 0.06);
--scrollbar-thumb: rgb(102 102 102 / 0.6);
--scrollbar-thumb-hover: rgb(102 102 102 / 0.85);
--scrollbar-thin-thumb: rgb(102 102 102 / 0.45);
--scrollbar-thin-thumb-hover: rgb(102 102 102 / 0.7);
--brand: #78824b;
--brand-foreground: #121212;
--brand-primary: #78824b;
--brand-accent: #c9a554;
--brand-warm: #8d6242;
--brand-deep: #121212;
--brand-muted: #666666;
--ink: #c2c2b0;
--surface-warm: #222222;
--naturegreen: #5f875f;
--naturegreen-foreground: #121212;
--duck-dark: #c2c2b0;
--duck-teal: #c9a554;
--duck-yellow: #b36d43;
--duck-orange: #8d6242;
--duck-forest: #5f875f;
--duck-beige: #323230;
--logo-src: '/officer-logo.svg';
}
+86 -42
View File
@@ -1,50 +1,94 @@
/*
NORD — ported from the published palette, unchanged.
Nord — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/nord/colors.toml (mode: dark)
*/
[data-theme='nord'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--radius: 0.625rem;
--background: #2e3440;
--foreground: #eceff4;
--card: #3b4252;
--card-foreground: #eceff4;
--popover: #3b4252;
--popover-foreground: #eceff4;
--primary: #88c0d0;
--primary-foreground: #2e3440;
--secondary: #434c5e;
--secondary-foreground: #eceff4;
--background: #191c23;
--foreground: #d8dee9;
--card: #2e3440;
--card-foreground: #d8dee9;
--popover: #2e3440;
--popover-foreground: #d8dee9;
--muted: #3b4252;
--muted-foreground: #d8dee9;
--accent: #8fbcbb;
--accent-foreground: #2e3440;
--muted-foreground: #adb5c4;
--accent: #3b4252;
--accent-foreground: #d8dee9;
--primary: #81a1c1;
--primary-foreground: #191c23;
--secondary: #3b4252;
--secondary-foreground: #d8dee9;
--cta: #81a1c1;
--cta-foreground: #191c23;
--ctahover: #90acc8;
--success: #a3be8c;
--success-foreground: #191c23;
--warning: #ebcb8b;
--warning-foreground: #191c23;
--destructive: #bf616a;
--destructive-foreground: #eceff4;
--border: #434c5e;
--input: #434c5e;
--ring: #88c0d0;
--chart-1: #88c0d0;
--chart-2: #ebcb8b;
--chart-3: #a3be8c;
--chart-4: #8fbcbb;
--chart-5: #b48ead;
--sidebar: #3b4252;
--sidebar-foreground: #d8dee9;
--sidebar-primary: #88c0d0;
--sidebar-primary-foreground: #2e3440;
--sidebar-accent: #434c5e;
--sidebar-accent-foreground: #eceff4;
--sidebar-border: #4c566a;
--sidebar-ring: #88c0d0;
--destructive-foreground: #121419;
--info: #81a1c1;
--info-foreground: #191c23;
--busy: #d5967a;
--busy-foreground: #191c23;
--busy-ink: #d5967a;
--border: #525865;
--input: #525865;
--ring: #81a1c1;
--radius: 0.625rem;
--chart-primary: #81a1c1;
--chart-secondary: #b48ead;
--status-success: #a3be8c;
--status-warning: #ebcb8b;
--status-in-progress: #81a1c1;
--page-bg: #191c23;
--page-bg-src: '';
--panel-bg: rgb(46 52 64 / 0.72);
--panel-border: rgb(82 88 101 / 0.9);
--panel-border-bare: rgb(82 88 101 / 0.55);
--panel-raised-bg: rgb(46 52 64 / 0.95);
--panel-raised-border: rgb(82 88 101 / 1);
--panel-accent: #81a1c1;
--panel-header-bg: rgb(59 66 82 / 0.6);
--panel-header-fg: #d8dee9;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #2e3440;
--glass-bg: rgb(46 52 64 / 0.55);
--glass-border: rgb(82 88 101 / 0.7);
--dock-bg: rgb(46 52 64 / 0.7);
--dock-border: rgb(82 88 101 / 0.8);
--dock-tooltip-bg: #3b4252;
--header-bg: rgb(46 52 64 / 0.8);
--header-border: rgb(82 88 101 / 0.9);
--header-fg: #d8dee9;
--header-blur: 12px;
--pixel-grid-color: rgb(117 126 141 / 0.07);
--card-grid-color: rgb(117 126 141 / 0.05);
--panel-grid-color: rgb(117 126 141 / 0.06);
--scrollbar-thumb: rgb(76 86 106 / 0.6);
--scrollbar-thumb-hover: rgb(76 86 106 / 0.85);
--scrollbar-thin-thumb: rgb(76 86 106 / 0.45);
--scrollbar-thin-thumb-hover: rgb(76 86 106 / 0.7);
--brand: #81a1c1;
--brand-foreground: #191c23;
--brand-primary: #81a1c1;
--brand-accent: #88c0d0;
--brand-warm: #d5967a;
--brand-deep: #191c23;
--brand-muted: #4c566a;
--ink: #d8dee9;
--surface-warm: #2e3440;
--naturegreen: #a3be8c;
--naturegreen-foreground: #191c23;
--duck-dark: #d8dee9;
--duck-teal: #88c0d0;
--duck-yellow: #ebcb8b;
--duck-orange: #d5967a;
--duck-forest: #a3be8c;
--duck-beige: #3f4551;
--logo-src: '/officer-logo.svg';
}
+87 -43
View File
@@ -1,50 +1,94 @@
/*
OSAKA JADE — ported from the published palette, unchanged.
Osaka Jade — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/osaka-jade/colors.toml (mode: dark)
*/
[data-theme='osaka-jade'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--background: #090f0d;
--foreground: #C1C497;
--card: #111c18;
--card-foreground: #C1C497;
--popover: #111c18;
--popover-foreground: #C1C497;
--muted: #23372B;
--muted-foreground: #D6D5BC;
--accent: #23372B;
--accent-foreground: #C1C497;
--primary: #509475;
--primary-foreground: #090f0d;
--secondary: #23372B;
--secondary-foreground: #C1C497;
--cta: #509475;
--cta-foreground: #090f0d;
--ctahover: #65a186;
--success: #549e6a;
--success-foreground: #090f0d;
--warning: #459451;
--warning-foreground: #090f0d;
--destructive: #FF5345;
--destructive-foreground: #090f0d;
--info: #509475;
--info-foreground: #090f0d;
--busy: #a2734b;
--busy-foreground: #090f0d;
--busy-ink: #a2734b;
--border: #485046;
--input: #485046;
--ring: #509475;
--radius: 0.625rem;
--background: #1a1b26;
--foreground: #c5cdd9;
--card: #16161e;
--card-foreground: #c5cdd9;
--popover: #16161e;
--popover-foreground: #c5cdd9;
--primary: #2ac3de;
--primary-foreground: #1a1b26;
--secondary: #292e42;
--secondary-foreground: #c5cdd9;
--muted: #1f2335;
--muted-foreground: #565f89;
--accent: #0db9d7;
--accent-foreground: #1a1b26;
--destructive: #f7768e;
--destructive-foreground: #c5cdd9;
--border: #292e42;
--input: #292e42;
--ring: #2ac3de;
--chart-1: #2ac3de;
--chart-2: #e0af68;
--chart-3: #9ece6a;
--chart-4: #1abc9c;
--chart-5: #bb9af7;
--sidebar: #16161e;
--sidebar-foreground: #565f89;
--sidebar-primary: #2ac3de;
--sidebar-primary-foreground: #1a1b26;
--sidebar-accent: #1f2335;
--sidebar-accent-foreground: #c5cdd9;
--sidebar-border: #292e42;
--sidebar-ring: #2ac3de;
--chart-primary: #509475;
--chart-secondary: #D2689C;
--status-success: #549e6a;
--status-warning: #459451;
--status-in-progress: #509475;
--page-bg: #090f0d;
--page-bg-src: '';
--panel-bg: rgb(17 28 24 / 0.72);
--panel-border: rgb(72 80 70 / 0.9);
--panel-border-bare: rgb(72 80 70 / 0.55);
--panel-raised-bg: rgb(17 28 24 / 0.95);
--panel-raised-border: rgb(72 80 70 / 1);
--panel-accent: #509475;
--panel-header-bg: rgb(35 55 43 / 0.6);
--panel-header-fg: #C1C497;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #111c18;
--glass-bg: rgb(17 28 24 / 0.55);
--glass-border: rgb(72 80 70 / 0.7);
--dock-bg: rgb(17 28 24 / 0.7);
--dock-border: rgb(72 80 70 / 0.8);
--dock-tooltip-bg: #23372B;
--header-bg: rgb(17 28 24 / 0.8);
--header-border: rgb(72 80 70 / 0.9);
--header-fg: #C1C497;
--header-blur: 12px;
--pixel-grid-color: rgb(129 184 168 / 0.07);
--card-grid-color: rgb(129 184 168 / 0.05);
--panel-grid-color: rgb(129 184 168 / 0.06);
--scrollbar-thumb: rgb(83 104 91 / 0.6);
--scrollbar-thumb-hover: rgb(83 104 91 / 0.85);
--scrollbar-thin-thumb: rgb(83 104 91 / 0.45);
--scrollbar-thin-thumb-hover: rgb(83 104 91 / 0.7);
--brand: #509475;
--brand-foreground: #090f0d;
--brand-primary: #509475;
--brand-accent: #2DD5B7;
--brand-warm: #a2734b;
--brand-deep: #090f0d;
--brand-muted: #53685B;
--ink: #C1C497;
--surface-warm: #111c18;
--naturegreen: #549e6a;
--naturegreen-foreground: #090f0d;
--duck-dark: #C1C497;
--duck-teal: #2DD5B7;
--duck-yellow: #459451;
--duck-orange: #a2734b;
--duck-forest: #549e6a;
--duck-beige: #232d25;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Retro 82 — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/retro-82/colors.toml (mode: dark)
*/
[data-theme='retro-82'] {
--background: #020c17;
--foreground: #f6dcac;
--card: #05182e;
--card-foreground: #f6dcac;
--popover: #05182e;
--popover-foreground: #f6dcac;
--muted: #0a2540;
--muted-foreground: #a7c9c6;
--accent: #0a2540;
--accent-foreground: #f6dcac;
--primary: #faa968;
--primary-foreground: #020c17;
--secondary: #0a2540;
--secondary-foreground: #f6dcac;
--cta: #faa968;
--cta-foreground: #020c17;
--ctahover: #fbb37a;
--success: #028391;
--success-foreground: #01060c;
--warning: #e97b3c;
--warning-foreground: #020c17;
--destructive: #f85525;
--destructive-foreground: #020c17;
--info: #3f8f8a;
--info-foreground: #020c17;
--busy: #faa968;
--busy-foreground: #020c17;
--busy-ink: #faa968;
--border: #324a59;
--input: #324a59;
--ring: #faa968;
--radius: 0.625rem;
--chart-primary: #faa968;
--chart-secondary: #3f8f8a;
--status-success: #028391;
--status-warning: #e97b3c;
--status-in-progress: #3f8f8a;
--page-bg: #020c17;
--page-bg-src: '';
--panel-bg: rgb(5 24 46 / 0.72);
--panel-border: rgb(50 74 89 / 0.9);
--panel-border-bare: rgb(50 74 89 / 0.55);
--panel-raised-bg: rgb(5 24 46 / 0.95);
--panel-raised-border: rgb(50 74 89 / 1);
--panel-accent: #faa968;
--panel-header-bg: rgb(10 37 64 / 0.6);
--panel-header-fg: #f6dcac;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #05182e;
--glass-bg: rgb(5 24 46 / 0.55);
--glass-border: rgb(50 74 89 / 0.7);
--dock-bg: rgb(5 24 46 / 0.7);
--dock-border: rgb(50 74 89 / 0.8);
--dock-tooltip-bg: #0a2540;
--header-bg: rgb(5 24 46 / 0.8);
--header-border: rgb(50 74 89 / 0.9);
--header-fg: #f6dcac;
--header-blur: 12px;
--pixel-grid-color: rgb(63 143 138 / 0.07);
--card-grid-color: rgb(63 143 138 / 0.05);
--panel-grid-color: rgb(63 143 138 / 0.06);
--scrollbar-thumb: rgb(42 107 120 / 0.6);
--scrollbar-thumb-hover: rgb(42 107 120 / 0.85);
--scrollbar-thin-thumb: rgb(42 107 120 / 0.45);
--scrollbar-thin-thumb-hover: rgb(42 107 120 / 0.7);
--brand: #faa968;
--brand-foreground: #020c17;
--brand-primary: #faa968;
--brand-accent: #8cbfb8;
--brand-warm: #faa968;
--brand-deep: #020c17;
--brand-muted: #2a6b78;
--ink: #f6dcac;
--surface-warm: #05182e;
--naturegreen: #028391;
--naturegreen-foreground: #01060c;
--duck-dark: #f6dcac;
--duck-teal: #8cbfb8;
--duck-yellow: #e97b3c;
--duck-orange: #faa968;
--duck-forest: #028391;
--duck-beige: #1d2c3b;
--logo-src: '/officer-logo.svg';
}
+87 -43
View File
@@ -1,50 +1,94 @@
/*
RISTRETTO — ported from the published palette, unchanged.
Ristretto — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/ristretto/colors.toml (mode: dark)
*/
[data-theme='ristretto'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--background: #181414;
--foreground: #e6d9db;
--card: #2c2525;
--card-foreground: #e6d9db;
--popover: #2c2525;
--popover-foreground: #e6d9db;
--muted: #3d2f2a;
--muted-foreground: #c3b7b8;
--accent: #3d2f2a;
--accent-foreground: #e6d9db;
--primary: #f38d70;
--primary-foreground: #181414;
--secondary: #3d2f2a;
--secondary-foreground: #e6d9db;
--cta: #f38d70;
--cta-foreground: #181414;
--ctahover: #f49b81;
--success: #adda78;
--success-foreground: #181414;
--warning: #f9cc6c;
--warning-foreground: #181414;
--destructive: #fd6883;
--destructive-foreground: #181414;
--info: #f38d70;
--info-foreground: #181414;
--busy: #fb9a77;
--busy-foreground: #181414;
--busy-ink: #fb9a77;
--border: #564e4e;
--input: #564e4e;
--ring: #f38d70;
--radius: 0.625rem;
--background: #403d39;
--foreground: #ebe5df;
--card: #352f2a;
--card-foreground: #ebe5df;
--popover: #352f2a;
--popover-foreground: #ebe5df;
--primary: #fc9867;
--primary-foreground: #403d39;
--secondary: #5f574f;
--secondary-foreground: #ebe5df;
--muted: #4d4743;
--muted-foreground: #ada49d;
--accent: #fbb360;
--accent-foreground: #403d39;
--destructive: #d76c6c;
--destructive-foreground: #ebe5df;
--border: #5f574f;
--input: #5f574f;
--ring: #fc9867;
--chart-1: #fc9867;
--chart-2: #fbb360;
--chart-3: #8ca589;
--chart-4: #86a3a3;
--chart-5: #a38dac;
--sidebar: #352f2a;
--sidebar-foreground: #ada49d;
--sidebar-primary: #fc9867;
--sidebar-primary-foreground: #403d39;
--sidebar-accent: #4d4743;
--sidebar-accent-foreground: #ebe5df;
--sidebar-border: #5f574f;
--sidebar-ring: #fc9867;
--chart-primary: #f38d70;
--chart-secondary: #a8a9eb;
--status-success: #adda78;
--status-warning: #f9cc6c;
--status-in-progress: #f38d70;
--page-bg: #181414;
--page-bg-src: '';
--panel-bg: rgb(44 37 37 / 0.72);
--panel-border: rgb(86 78 78 / 0.9);
--panel-border-bare: rgb(86 78 78 / 0.55);
--panel-raised-bg: rgb(44 37 37 / 0.95);
--panel-raised-border: rgb(86 78 78 / 1);
--panel-accent: #f38d70;
--panel-header-bg: rgb(61 47 42 / 0.6);
--panel-header-fg: #e6d9db;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #2c2525;
--glass-bg: rgb(44 37 37 / 0.55);
--glass-border: rgb(86 78 78 / 0.7);
--dock-bg: rgb(44 37 37 / 0.7);
--dock-border: rgb(86 78 78 / 0.8);
--dock-tooltip-bg: #3d2f2a;
--header-bg: rgb(44 37 37 / 0.8);
--header-border: rgb(86 78 78 / 0.9);
--header-fg: #e6d9db;
--header-blur: 12px;
--pixel-grid-color: rgb(121 113 113 / 0.07);
--card-grid-color: rgb(121 113 113 / 0.05);
--panel-grid-color: rgb(121 113 113 / 0.06);
--scrollbar-thumb: rgb(114 105 106 / 0.6);
--scrollbar-thumb-hover: rgb(114 105 106 / 0.85);
--scrollbar-thin-thumb: rgb(114 105 106 / 0.45);
--scrollbar-thin-thumb-hover: rgb(114 105 106 / 0.7);
--brand: #f38d70;
--brand-foreground: #181414;
--brand-primary: #f38d70;
--brand-accent: #85dacc;
--brand-warm: #fb9a77;
--brand-deep: #181414;
--brand-muted: #72696a;
--ink: #e6d9db;
--surface-warm: #2c2525;
--naturegreen: #adda78;
--naturegreen-foreground: #181414;
--duck-dark: #e6d9db;
--duck-teal: #85dacc;
--duck-yellow: #f9cc6c;
--duck-orange: #fb9a77;
--duck-forest: #adda78;
--duck-beige: #3f3737;
--logo-src: '/officer-logo.svg';
}
+87 -43
View File
@@ -1,50 +1,94 @@
/*
ROSÉ PINE — ported from the published palette, unchanged.
Rose Pine — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/rose-pine/colors.toml (mode: light)
*/
[data-theme='rose-pine'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--background: #faf4ed;
--foreground: #575279;
--card: #f2e9e1;
--card-foreground: #575279;
--popover: #f2e9e1;
--popover-foreground: #575279;
--muted: #ede7e1;
--muted-foreground: #69657f;
--accent: #ede7e1;
--accent-foreground: #575279;
--primary: #56949f;
--primary-foreground: #222120;
--secondary: #ede7e1;
--secondary-foreground: #575279;
--cta: #56949f;
--cta-foreground: #222120;
--ctahover: #4c828c;
--success: #286983;
--success-foreground: #e3ddd7;
--warning: #ea9d34;
--warning-foreground: #413e5b;
--destructive: #b4637a;
--destructive-foreground: #111010;
--info: #56949f;
--info-foreground: #222120;
--busy: #cf8057;
--busy-foreground: #2c293d;
--busy-ink: #9b6041;
--border: #d9d1d0;
--input: #d9d1d0;
--ring: #56949f;
--radius: 0.625rem;
--background: #191724;
--foreground: #e0def4;
--card: #1f1d2e;
--card-foreground: #e0def4;
--popover: #1f1d2e;
--popover-foreground: #e0def4;
--primary: #c4a7e7;
--primary-foreground: #191724;
--secondary: #26233a;
--secondary-foreground: #e0def4;
--muted: #26233a;
--muted-foreground: #908caa;
--accent: #ebbcba;
--accent-foreground: #191724;
--destructive: #eb6f92;
--destructive-foreground: #e0def4;
--border: #26233a;
--input: #26233a;
--ring: #c4a7e7;
--chart-1: #c4a7e7;
--chart-2: #f6c177;
--chart-3: #9ccfd8;
--chart-4: #31748f;
--chart-5: #eb6f92;
--sidebar: #1f1d2e;
--sidebar-foreground: #908caa;
--sidebar-primary: #c4a7e7;
--sidebar-primary-foreground: #191724;
--sidebar-accent: #26233a;
--sidebar-accent-foreground: #e0def4;
--sidebar-border: #403d52;
--sidebar-ring: #c4a7e7;
--chart-primary: #56949f;
--chart-secondary: #907aa9;
--status-success: #286983;
--status-warning: #ea9d34;
--status-in-progress: #56949f;
--page-bg: #faf4ed;
--page-bg-src: '';
--panel-bg: rgb(242 233 225 / 0.72);
--panel-border: rgb(217 209 208 / 0.9);
--panel-border-bare: rgb(217 209 208 / 0.55);
--panel-raised-bg: rgb(242 233 225 / 0.95);
--panel-raised-border: rgb(217 209 208 / 1);
--panel-accent: #56949f;
--panel-header-bg: rgb(237 231 225 / 0.6);
--panel-header-fg: #575279;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #f2e9e1;
--glass-bg: rgb(242 233 225 / 0.55);
--glass-border: rgb(217 209 208 / 0.7);
--dock-bg: rgb(242 233 225 / 0.7);
--dock-border: rgb(217 209 208 / 0.8);
--dock-tooltip-bg: #ede7e1;
--header-bg: rgb(242 233 225 / 0.8);
--header-border: rgb(217 209 208 / 0.9);
--header-fg: #575279;
--header-blur: 12px;
--pixel-grid-color: rgb(137 132 149 / 0.07);
--card-grid-color: rgb(137 132 149 / 0.05);
--panel-grid-color: rgb(137 132 149 / 0.06);
--scrollbar-thumb: rgb(206 202 205 / 0.6);
--scrollbar-thumb-hover: rgb(206 202 205 / 0.85);
--scrollbar-thin-thumb: rgb(206 202 205 / 0.45);
--scrollbar-thin-thumb-hover: rgb(206 202 205 / 0.7);
--brand: #56949f;
--brand-foreground: #222120;
--brand-primary: #56949f;
--brand-accent: #d7827e;
--brand-warm: #cf8057;
--brand-deep: #ede7e1;
--brand-muted: #cecacd;
--ink: #575279;
--surface-warm: #f2e9e1;
--naturegreen: #286983;
--naturegreen-foreground: #e3ddd7;
--duck-dark: #575279;
--duck-teal: #d7827e;
--duck-yellow: #ea9d34;
--duck-orange: #cf8057;
--duck-forest: #286983;
--duck-beige: #e3dad7;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Solitude — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/solitude/colors.toml (mode: dark)
*/
[data-theme='solitude'] {
--background: #080a0b;
--foreground: #cacccc;
--card: #101315;
--card-foreground: #cacccc;
--popover: #101315;
--popover-foreground: #cacccc;
--muted: #101315;
--muted-foreground: #cbc2be;
--accent: #101315;
--accent-foreground: #cacccc;
--primary: #798186;
--primary-foreground: #080a0b;
--secondary: #101315;
--secondary-foreground: #cacccc;
--cta: #798186;
--cta-foreground: #080a0b;
--ctahover: #899095;
--success: #9fa5a9;
--success-foreground: #080a0b;
--warning: #d9dbdc;
--warning-foreground: #080a0b;
--destructive: #565d60;
--destructive-foreground: #d0d4d8;
--info: #798186;
--info-foreground: #080a0b;
--busy: #d9dbdc;
--busy-foreground: #080a0b;
--busy-ink: #d9dbdc;
--border: #444444;
--input: #444444;
--ring: #798186;
--radius: 0.625rem;
--chart-primary: #798186;
--chart-secondary: #aeaeae;
--status-success: #9fa5a9;
--status-warning: #d9dbdc;
--status-in-progress: #798186;
--page-bg: #080a0b;
--page-bg-src: '';
--panel-bg: rgb(16 19 21 / 0.72);
--panel-border: rgb(68 68 68 / 0.9);
--panel-border-bare: rgb(68 68 68 / 0.55);
--panel-raised-bg: rgb(16 19 21 / 0.95);
--panel-raised-border: rgb(68 68 68 / 1);
--panel-accent: #798186;
--panel-header-bg: rgb(16 19 21 / 0.6);
--panel-header-fg: #cacccc;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #101315;
--glass-bg: rgb(16 19 21 / 0.55);
--glass-border: rgb(68 68 68 / 0.7);
--dock-bg: rgb(16 19 21 / 0.7);
--dock-border: rgb(68 68 68 / 0.8);
--dock-tooltip-bg: #101315;
--header-bg: rgb(16 19 21 / 0.8);
--header-border: rgb(68 68 68 / 0.9);
--header-fg: #cacccc;
--header-blur: 12px;
--pixel-grid-color: rgb(98 100 106 / 0.07);
--card-grid-color: rgb(98 100 106 / 0.05);
--panel-grid-color: rgb(98 100 106 / 0.06);
--scrollbar-thumb: rgb(75 78 85 / 0.6);
--scrollbar-thumb-hover: rgb(75 78 85 / 0.85);
--scrollbar-thin-thumb: rgb(75 78 85 / 0.45);
--scrollbar-thin-thumb-hover: rgb(75 78 85 / 0.7);
--brand: #798186;
--brand-foreground: #080a0b;
--brand-primary: #798186;
--brand-accent: #707070;
--brand-warm: #d9dbdc;
--brand-deep: #080a0b;
--brand-muted: #4b4e55;
--ink: #cacccc;
--surface-warm: #101315;
--naturegreen: #9fa5a9;
--naturegreen-foreground: #080a0b;
--duck-dark: #cacccc;
--duck-teal: #707070;
--duck-yellow: #d9dbdc;
--duck-orange: #d9dbdc;
--duck-forest: #9fa5a9;
--duck-beige: #232627;
--logo-src: '/officer-logo.svg';
}
+87 -43
View File
@@ -1,50 +1,94 @@
/*
TOKYO NIGHT — ported from the published palette, unchanged.
Tokyo Night — generated from Omarchy's palette by scripts/generate-themes.ts.
A PALETTE theme: it supplies the standard tokens and nothing else. Panels, the header, the dock, glass,
grid lines and scrollbars are all derived from these by `base.css`, so this file never mentions them.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
That is the contract working as intended — a theme anyone has already written, dropped in whole. Compare
`duck-*.css`, which additionally declares a texture.
Source: basecamp/omarchy themes/tokyo-night/colors.toml (mode: dark)
*/
[data-theme='tokyo-night'] {
/* The mark. Declared by every theme rather than inherited from a default: a theme that ships a
brand should say so, and a white-labelled build replaces this line rather than hunting for the
default that was quietly supplying it. */
--logo-src: '/officer-logo.svg';
--background: #0e0e14;
--foreground: #a9b1d6;
--card: #1a1b26;
--card-foreground: #a9b1d6;
--popover: #1a1b26;
--popover-foreground: #a9b1d6;
--muted: #24283b;
--muted-foreground: #b4bee6;
--accent: #24283b;
--accent-foreground: #a9b1d6;
--primary: #7aa2f7;
--primary-foreground: #0e0e14;
--secondary: #24283b;
--secondary-foreground: #a9b1d6;
--cta: #7aa2f7;
--cta-foreground: #0e0e14;
--ctahover: #8aadf8;
--success: #9ece6a;
--success-foreground: #0e0e14;
--warning: #e0af68;
--warning-foreground: #0e0e14;
--destructive: #f7768e;
--destructive-foreground: #0e0e14;
--info: #7aa2f7;
--info-foreground: #0e0e14;
--busy: #eb927b;
--busy-foreground: #0e0e14;
--busy-ink: #eb927b;
--border: #45495c;
--input: #45495c;
--ring: #7aa2f7;
--radius: 0.625rem;
--background: #222436;
--foreground: #c8d3f5;
--card: #1e2030;
--card-foreground: #c8d3f5;
--popover: #1e2030;
--popover-foreground: #c8d3f5;
--primary: #82aaff;
--primary-foreground: #1b1d2b;
--secondary: #3b4261;
--secondary-foreground: #c8d3f5;
--muted: #2f334d;
--muted-foreground: #828bb8;
--accent: #86e1fc;
--accent-foreground: #1b1d2b;
--destructive: #c53b53;
--destructive-foreground: #c8d3f5;
--border: #3b4261;
--input: #3b4261;
--ring: #82aaff;
--chart-1: #82aaff;
--chart-2: #ffc777;
--chart-3: #c3e88d;
--chart-4: #4fd6be;
--chart-5: #c099ff;
--sidebar: #1e2030;
--sidebar-foreground: #828bb8;
--sidebar-primary: #82aaff;
--sidebar-primary-foreground: #1b1d2b;
--sidebar-accent: #2f334d;
--sidebar-accent-foreground: #c8d3f5;
--sidebar-border: #3b4261;
--sidebar-ring: #82aaff;
--chart-primary: #7aa2f7;
--chart-secondary: #ad8ee6;
--status-success: #9ece6a;
--status-warning: #e0af68;
--status-in-progress: #7aa2f7;
--page-bg: #0e0e14;
--page-bg-src: '';
--panel-bg: rgb(26 27 38 / 0.72);
--panel-border: rgb(69 73 92 / 0.9);
--panel-border-bare: rgb(69 73 92 / 0.55);
--panel-raised-bg: rgb(26 27 38 / 0.95);
--panel-raised-border: rgb(69 73 92 / 1);
--panel-accent: #7aa2f7;
--panel-header-bg: rgb(36 40 59 / 0.6);
--panel-header-fg: #a9b1d6;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #1a1b26;
--glass-bg: rgb(26 27 38 / 0.55);
--glass-border: rgb(69 73 92 / 0.7);
--dock-bg: rgb(26 27 38 / 0.7);
--dock-border: rgb(69 73 92 / 0.8);
--dock-tooltip-bg: #24283b;
--header-bg: rgb(26 27 38 / 0.8);
--header-border: rgb(69 73 92 / 0.9);
--header-fg: #a9b1d6;
--header-blur: 12px;
--pixel-grid-color: rgb(94 103 143 / 0.07);
--card-grid-color: rgb(94 103 143 / 0.05);
--panel-grid-color: rgb(94 103 143 / 0.06);
--scrollbar-thumb: rgb(65 72 104 / 0.6);
--scrollbar-thumb-hover: rgb(65 72 104 / 0.85);
--scrollbar-thin-thumb: rgb(65 72 104 / 0.45);
--scrollbar-thin-thumb-hover: rgb(65 72 104 / 0.7);
--brand: #7aa2f7;
--brand-foreground: #0e0e14;
--brand-primary: #7aa2f7;
--brand-accent: #449dab;
--brand-warm: #eb927b;
--brand-deep: #0e0e14;
--brand-muted: #414868;
--ink: #a9b1d6;
--surface-warm: #1a1b26;
--naturegreen: #9ece6a;
--naturegreen-foreground: #0e0e14;
--duck-dark: #a9b1d6;
--duck-teal: #449dab;
--duck-yellow: #e0af68;
--duck-orange: #eb927b;
--duck-forest: #9ece6a;
--duck-beige: #282a38;
--logo-src: '/officer-logo.svg';
}
@@ -0,0 +1,94 @@
/*
Vantablack — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/vantablack/colors.toml (mode: dark)
*/
[data-theme='vantablack'] {
--background: #070707;
--foreground: #ffffff;
--card: #000000;
--card-foreground: #ffffff;
--popover: #000000;
--popover-foreground: #ffffff;
--muted: #1a1a1a;
--muted-foreground: #ececec;
--accent: #1a1a1a;
--accent-foreground: #ffffff;
--primary: #8d8d8d;
--primary-foreground: #070707;
--secondary: #1a1a1a;
--secondary-foreground: #ffffff;
--cta: #8d8d8d;
--cta-foreground: #070707;
--ctahover: #9b9b9b;
--success: #b6b6b6;
--success-foreground: #070707;
--warning: #cecece;
--warning-foreground: #070707;
--destructive: #a4a4a4;
--destructive-foreground: #070707;
--info: #8d8d8d;
--info-foreground: #070707;
--busy: #b9b9b9;
--busy-foreground: #070707;
--busy-ink: #b9b9b9;
--border: #424242;
--input: #424242;
--ring: #8d8d8d;
--radius: 0.625rem;
--chart-primary: #8d8d8d;
--chart-secondary: #9b9b9b;
--status-success: #b6b6b6;
--status-warning: #cecece;
--status-in-progress: #8d8d8d;
--page-bg: #070707;
--page-bg-src: '';
--panel-bg: rgb(0 0 0 / 0.72);
--panel-border: rgb(66 66 66 / 0.9);
--panel-border-bare: rgb(66 66 66 / 0.55);
--panel-raised-bg: rgb(0 0 0 / 0.95);
--panel-raised-border: rgb(66 66 66 / 1);
--panel-accent: #8d8d8d;
--panel-header-bg: rgb(26 26 26 / 0.6);
--panel-header-fg: #ffffff;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #000000;
--glass-bg: rgb(0 0 0 / 0.55);
--glass-border: rgb(66 66 66 / 0.7);
--dock-bg: rgb(0 0 0 / 0.7);
--dock-border: rgb(66 66 66 / 0.8);
--dock-tooltip-bg: #1a1a1a;
--header-bg: rgb(0 0 0 / 0.8);
--header-border: rgb(66 66 66 / 0.9);
--header-fg: #ffffff;
--header-blur: 12px;
--pixel-grid-color: rgb(93 93 93 / 0.07);
--card-grid-color: rgb(93 93 93 / 0.05);
--panel-grid-color: rgb(93 93 93 / 0.06);
--scrollbar-thumb: rgb(122 122 122 / 0.6);
--scrollbar-thumb-hover: rgb(122 122 122 / 0.85);
--scrollbar-thin-thumb: rgb(122 122 122 / 0.45);
--scrollbar-thin-thumb-hover: rgb(122 122 122 / 0.7);
--brand: #8d8d8d;
--brand-foreground: #070707;
--brand-primary: #8d8d8d;
--brand-accent: #b0b0b0;
--brand-warm: #b9b9b9;
--brand-deep: #070707;
--brand-muted: #7a7a7a;
--ink: #ffffff;
--surface-warm: #000000;
--naturegreen: #b6b6b6;
--naturegreen-foreground: #070707;
--duck-dark: #ffffff;
--duck-teal: #b0b0b0;
--duck-yellow: #cecece;
--duck-orange: #b9b9b9;
--duck-forest: #b6b6b6;
--duck-beige: #1a1a1a;
--logo-src: '/officer-logo.svg';
}
+94
View File
@@ -0,0 +1,94 @@
/*
White — generated from Omarchy's palette by scripts/generate-themes.ts.
DO NOT EDIT BY HAND. Change the mapping in scripts/themes/map.ts and re-run, so every theme moves
together — the previous port drifted precisely because each file was edited on its own.
Source: basecamp/omarchy themes/white/colors.toml (mode: light)
*/
[data-theme='white'] {
--background: #ffffff;
--foreground: #000000;
--card: #c0c0c0;
--card-foreground: #000000;
--popover: #c0c0c0;
--popover-foreground: #000000;
--muted: #f5f5f5;
--muted-foreground: #000000;
--accent: #f5f5f5;
--accent-foreground: #000000;
--primary: #6e6e6e;
--primary-foreground: #f1f1f1;
--secondary: #f5f5f5;
--secondary-foreground: #000000;
--cta: #6e6e6e;
--cta-foreground: #f1f1f1;
--ctahover: #616161;
--success: #3a3a3a;
--success-foreground: #e8e8e8;
--warning: #4a4a4a;
--warning-foreground: #e8e8e8;
--destructive: #2a2a2a;
--destructive-foreground: #e8e8e8;
--info: #1a1a1a;
--info-foreground: #e8e8e8;
--busy: #4a4a4a;
--busy-foreground: #e8e8e8;
--busy-ink: #4a4a4a;
--border: #c0c0c0;
--input: #c0c0c0;
--ring: #6e6e6e;
--radius: 0.625rem;
--chart-primary: #6e6e6e;
--chart-secondary: #2e2e2e;
--status-success: #3a3a3a;
--status-warning: #4a4a4a;
--status-in-progress: #1a1a1a;
--page-bg: #ffffff;
--page-bg-src: '';
--panel-bg: rgb(192 192 192 / 0.72);
--panel-border: rgb(192 192 192 / 0.9);
--panel-border-bare: rgb(192 192 192 / 0.55);
--panel-raised-bg: rgb(192 192 192 / 0.95);
--panel-raised-border: rgb(192 192 192 / 1);
--panel-accent: #6e6e6e;
--panel-header-bg: rgb(245 245 245 / 0.6);
--panel-header-fg: #000000;
--panel-radius: 0.75rem;
--panel-blur: 12px;
--card-bg: #c0c0c0;
--glass-bg: rgb(192 192 192 / 0.55);
--glass-border: rgb(192 192 192 / 0.7);
--dock-bg: rgb(192 192 192 / 0.7);
--dock-border: rgb(192 192 192 / 0.8);
--dock-tooltip-bg: #f5f5f5;
--header-bg: rgb(192 192 192 / 0.8);
--header-border: rgb(192 192 192 / 0.9);
--header-fg: #000000;
--header-blur: 12px;
--pixel-grid-color: rgb(101 101 101 / 0.07);
--card-grid-color: rgb(101 101 101 / 0.05);
--panel-grid-color: rgb(101 101 101 / 0.06);
--scrollbar-thumb: rgb(128 128 128 / 0.6);
--scrollbar-thumb-hover: rgb(128 128 128 / 0.85);
--scrollbar-thin-thumb: rgb(128 128 128 / 0.45);
--scrollbar-thin-thumb-hover: rgb(128 128 128 / 0.7);
--brand: #6e6e6e;
--brand-foreground: #f1f1f1;
--brand-primary: #6e6e6e;
--brand-accent: #3e3e3e;
--brand-warm: #4a4a4a;
--brand-deep: #f5f5f5;
--brand-muted: #808080;
--ink: #000000;
--surface-warm: #c0c0c0;
--naturegreen: #3a3a3a;
--naturegreen-foreground: #e8e8e8;
--duck-dark: #000000;
--duck-teal: #3e3e3e;
--duck-yellow: #4a4a4a;
--duck-orange: #4a4a4a;
--duck-forest: #3a3a3a;
--duck-beige: #adadad;
--logo-src: '/officer-logo.svg';
}
+24 -7
View File
@@ -38,23 +38,40 @@ export const THEMES: readonly Theme[] = [
},
/*
Palette themes, ported unchanged from published colour schemes. Each supplies only the standard tokens;
`base.css` derives panels, header, dock, glass, grid and scrollbars from them.
Palette themes, generated from Omarchy by `scripts/generate-themes.ts`.
`applyDarkClass` is set for the dark ones so the 396 `dark:` utilities still written into components
resolve. It says nothing about the theme beyond "treat this as a dark ground".
Everything between the markers is rewritten by that script, from the same list that writes the
stylesheet imports. Both halves from one source on purpose: the previous port maintained them by
hand and drifted — `catppuccin-mocha` sat in this list after its stylesheet was gone.
`applyDarkClass` comes from the palette's own `mode`, so it is a fact about the theme rather than a
judgement about it. It says nothing beyond "treat this as a dark ground", which is what the 396
remaining `dark:` utilities need.
*/
{ id: 'tokyo-night', name: 'Tokyo Night', family: 'Tokyo Night', applyDarkClass: true },
{ id: 'catppuccin-mocha', name: 'Catppuccin Mocha', family: 'Catppuccin', applyDarkClass: true },
/* GENERATED THEMES — start */
{ id: 'catppuccin', name: 'Catppuccin Mocha', family: 'Catppuccin', applyDarkClass: true },
{ id: 'catppuccin-latte', name: 'Catppuccin Latte', family: 'Catppuccin', applyDarkClass: false },
{ id: 'ethereal', name: 'Ethereal', family: 'Ethereal', applyDarkClass: true },
{ id: 'everforest', name: 'Everforest', family: 'Everforest', applyDarkClass: true },
{ id: 'flexoki-light', name: 'Flexoki Light', family: 'Flexoki Light', applyDarkClass: false },
{ id: 'gruvbox', name: 'Gruvbox', family: 'Gruvbox', applyDarkClass: true },
{ id: 'hackerman', name: 'Hackerman', family: 'Hackerman', applyDarkClass: true },
{ id: 'kanagawa', name: 'Kanagawa', family: 'Kanagawa', applyDarkClass: true },
{ id: 'last-horizon', name: 'Last Horizon', family: 'Last Horizon', applyDarkClass: true },
{ id: 'lumon', name: 'Lumon', family: 'Lumon', applyDarkClass: true },
{ id: 'lupine', name: 'Lupine', family: 'Lupine', applyDarkClass: false },
{ id: 'matte-black', name: 'Matte Black', family: 'Matte Black', applyDarkClass: true },
{ id: 'miasma', name: 'Miasma', family: 'Miasma', applyDarkClass: true },
{ id: 'nord', name: 'Nord', family: 'Nord', applyDarkClass: true },
{ id: 'osaka-jade', name: 'Osaka Jade', family: 'Osaka Jade', applyDarkClass: true },
{ id: 'retro-82', name: 'Retro 82', family: 'Retro 82', applyDarkClass: true },
{ id: 'ristretto', name: 'Ristretto', family: 'Ristretto', applyDarkClass: true },
{ id: 'rose-pine', name: 'Rosé Pine', family: 'Rosé Pine', applyDarkClass: true },
{ id: 'rose-pine', name: 'Rosé Pine', family: 'Rosé Pine', applyDarkClass: false },
{ id: 'solitude', name: 'Solitude', family: 'Solitude', applyDarkClass: true },
{ id: 'tokyo-night', name: 'Tokyo Night', family: 'Tokyo Night', applyDarkClass: true },
{ id: 'vantablack', name: 'Vantablack', family: 'Vantablack', applyDarkClass: true },
{ id: 'white', name: 'White', family: 'White', applyDarkClass: false },
/* GENERATED THEMES — end */
] as const;
/** What the app wears when nobody has chosen — its appearance before this refactor. */