Mimika for VS Code
Mimika's own palette, as an editor theme. Ember orange (#ff7445) on near-black,
taken from the product rather than approximated: the same hex values the CLI
writes as ANSI escapes and the control UI declares as CSS custom properties.
Three variants, because the product has three grounds:
| Variant |
Editor ground |
Lifted from |
| Mimika Ember (default) |
#0c0d10 |
src/controller/webui/design.css — the control UI, the sheet that calls itself authoritative |
| Mimika Void |
#06060a |
Web/app/globals.css — the marketing site's deeper ground |
| Mimika Ember Light |
#ffffff |
the html[data-theme="light"] overrides in both sheets |
Where the colours come from
| Role |
Value |
Source |
| Brand orange |
#ff7445 |
gradient.zig brand_start · render.zig Ansi.orange · --accent · --c-accent · --brand-500 |
| Orange bright |
#ff9a65 |
Ansi.orange_bright · --brand-400 |
| Amber |
#ffc470 |
gradient.zig brand_end · --brand-300 |
| Ink on orange |
#1b0c04 |
globals.css .btn-primary |
| Cyan |
#00b8ff |
gradient.zig accent_start · Ansi.cyan_bright |
| Violet |
#be91ff |
gradient.zig accent_end · Ansi.purple |
| Green / amber / red |
#4ec78f #f0c15e #f26d84 |
--c-ok --c-warn --c-danger (Void uses the TUI set from gradient.zig) |
| Surfaces |
#0c0d10 #14161b #191c22 #0a0b0e |
--c-base --c-raised --c-overlay --c-sunken |
| Ink |
#eceef2 #9aa1ae #6b7280 |
--c-ink --c-ink-dim --c-ink-faint |
Only three values in the whole theme are not printed somewhere in the product,
and each is a derivation of one that is, computed with the same linear blend
Rgb.lerp uses in gradient.zig:
- Void's lifted popover surface and its two hairlines —
globals.css declares
them as translucent white (--surface-3, --hairline, --hairline-strong),
so they are those tokens composited onto their own backdrop.
- Three light-mode hues darkened toward
--c-ink because the product only ever
draws them on chips and borders, never as body type, and they land just under
4.5:1 on white: --theme-link (4.41 → 6.38), --archived (4.62 → 5.44), and
--c-accent (4.15 → 5.20).
How orange is used
design.css states the rule this theme follows: one accent, used sparingly.
Colour marks state, never decoration. Orange lands on the things that tell you
where you are — cursor, focus ring, the rule above the active tab, the active
activity-bar item, badges, the progress bar, keywords — and on nothing that is
merely present.
Which is why the status bar is a chrome surface with orange type rather than a
solid orange bar. A filled bar is how these themes end up looking cheap. It does
turn solid orange while debugging, because that is a state.
The scrollbar thumb turning orange on hover is not an invention either —
globals.css styles its own scrollbar that way.
Syntax
| Token |
Ember / Void |
Ember Light |
| Keyword, storage, control flow |
#ff7445 |
#8a3512 |
| Function, method |
#ffc470 |
#9b342d |
| String |
#4ec78f / #6ad68c |
#226948 |
| Number, constant, escape |
#be91ff |
#705bb6 |
| Type, class, namespace |
#00b8ff |
#2660a4 |
| Variable |
#eceef2 / #f4f3f7 |
#14161b |
| Parameter, property, punctuation |
#9aa1ae / #a8a5b4 |
#5b626e |
| Comment |
#6b7280 / #6d6a7a, italic |
#868d99, italic |
| Tag / attribute |
#ff9a65 / #ffc470 |
#9b342d / #8b5b10 |
| Invalid |
#f26d84 / #f06868 |
#9a334a |
The sixteen terminal ANSI slots map to the escapes src/ui/render.zig actually
emits, so running mimika in the integrated terminal reads as the same product
as the editor around it. Orange is not an ANSI slot — render.zig writes it as
truecolor, which bypasses the palette entirely.
Contrast
npm run contrast measures every syntax colour against the editor ground it is
drawn on, and every meaningful UI pair against its own surface, compositing
translucent colours down their real stack first. Current result:
459/459 asserted contrast pairs pass across 3 variants
Two asserted tiers and one reported tier:
- 4.5:1 — anything you read. Every syntax colour, every label, every
diagnostic, every ANSI slot. WCAG 2.1 AA 1.4.3.
- 3.0:1 — anything that identifies a component or its state. Focus ring,
cursor, active borders, icons, placeholder text, inactive tabs. WCAG 2.1 AA
1.4.11.
- reported, not asserted — hairlines, the scrollbar thumb, indent guides,
whitespace dots, column rulers, selection washes. Every one is a
--c-line, a
--hairline or a 12% white the product already ships, and they are texture
rather than information. They measure 1.07:1 to 2.59:1. Inventing a threshold
for them would only hide that, so the numbers are printed and the theme keeps
the product's values.
Two honest exceptions inside the asserted set, both stated rather than hidden:
- Comments are held to 3:1 rather than 4.5:1. They use the product's own
--c-ink-faint / --text-dim, measuring 4.02:1 on Ember, 3.85:1 on Void and
3.35:1 on white. Lifting them further would mean either inventing a colour the
product does not have or letting comments compete with code.
- The scrollbar thumb is in the reported tier, including its hovered state at
2.59:1. It is
globals.css's own thumb.
Two other things that are checked
VS Code silently ignores a colour key it does not recognise, so a theme can look
finished while a third of it never applies. npm run keys checks every key the
generator emits against the colour ids in your installed VS Code build — core
bundles, built-in extensions, and the localisation tables, since some ids are
registered from a template string and never reach the JS as literals.
643/643 workbench keys present in the colour registry
That check is what caught scm.historyItem* and
testing.message.error.decorationForeground, both of which were removed upstream
and had been silently doing nothing.
Spelling a TextMate scope plausibly is likewise not the same as matching one.
npm run syntax tokenises real files from the Mimika repository with shiki —
vscode-textmate and vscode-oniguruma, the same engine and grammars VS Code uses —
and reports how much of each file the theme actually colours:
zig 327 tokens · 65% coloured · 7 distinct hues · src/ui/gradient.zig
tsx 167 tokens · 86% coloured · 8 distinct hues · Web/app/components/capabilities.tsx
css 191 tokens · 87% coloured · 7 distinct hues · Web/app/globals.css
json 103 tokens · 100% coloured · 4 distinct hues · models.json
The uncoloured remainder is variables and identifiers, which are meant to sit at
editor.foreground. It also writes preview.html, so the result can be looked at
rather than trusted.
Building
The three JSON files under themes/ are build output. Edit the palette, not
them.
npm run build # palette.mjs -> themes/*.json
npm run keys # every workbench key exists in the colour registry
npm run contrast # WCAG measurement, non-zero exit on failure
npm run syntax # real-grammar tokenisation + preview.html
npm run verify # all four
npm run package # verify, then produce the .vsix
palette.mjs — every product colour, each with the file it came from
variants.mjs — the three role mappings; introduces no colour
theme.mjs — workbench keys, TextMate rules, semantic tokens
scripts/ — the three verifications above
Install a local build with:
code --install-extension mimika-theme-0.1.0.vsix
Then pick Mimika Ember from Preferences: Color Theme.