Lime is a fill, never text on a light surface
On light, use --accent-text. On dark, the lime itself reads.
Tokens
Every colour has a light and a dark value under the same name. The swatch follows the theme you are looking at; the two values below it are what each scheme gives. Click a swatch to copy its variable.
Rules
Every text colour reads at 4.5:1 on every surface, in both schemes. npm run check fails the build otherwise. These
are the ratios for the light scheme, computed from the tokens.
On light, use --accent-text. On dark, the lime itself reads.
ink, muted, accent-text and the status colours, on all five surfaces.
on-dark and on-dark-muted stay the same in both schemes.
Tokens
One family, Outfit (SIL OFL), at every weight. Each app ships the font: @fontsource-variable/outfit on the web.
const accent = light.accent // '#b9ff66'
Tokens
Round corners, in four sizes. An app may change its own corners; the colours stay the system's.
In use
How the apps put the tokens together. These are recipes rather than shipped components. Turn on Inspect and point at anything to see which tokens it uses.
.btn-primary {
background: var(--accent);
color: var(--on-accent);
border-radius: var(--r-pill);
}
.btn-primary:active { background: var(--accent-deep); }
:focus-visible { outline: 2px solid var(--focus); }
input {
background: var(--field);
border: 1px solid var(--border);
border-radius: var(--r-md);
color: var(--ink);
}
.hint { color: var(--muted); }
.bar { background: var(--line); }
.bar > span { background: var(--progress); }
Saved to iCloud
Partial: 3 of 5 lists synced
The feed has not updated in 30 days
The feed address returns 404
.status-ok { color: var(--ok); }
.status-info { color: var(--info); } /* neutral, like list's "partial" */
.status-warn { color: var(--warn); }
.status-danger { color: var(--danger); }
New in Myna
Chapters, transcripts and a sleep timer.
The dark band stays dark in both schemes. Lime reads on it as text.
.band {
background: var(--dark);
color: var(--on-dark);
border-radius: var(--r-xl);
}
.band small { color: var(--on-dark-muted); }
.band .kicker { color: var(--accent); }
In your editor
Estuary Light and Estuary Dark for VS Code and Xcode, generated from the same tokens. The code
reads in the system's greys: strings take the accent text colour, numbers ok, attributes info,
comments muted.
1// The player's progress, in the system's colours.
2import IscorDesign
3
4@MainActor
5struct EpisodeRow: View {
6 let title = "Where the river meets the sea"
7 var progress = 0.42
8
9 var body: some View {
10 ProgressView(value: progress)
11 .tint(Estuary.progress.color)
12 }
13}
Get it
One source, tokens/ in the W3C design tokens format. Everything below is generated from it.
@import '@iscor/design/tokens.css';
body {
background: var(--backdrop);
color: var(--ink);
font-family: var(--font);
}
/* A site switched by a .dark class (VitePress): */
@import '@iscor/design/tokens-class.css';
import { light, dark, base } from '@iscor/design'
light.accent // '#b9ff66'
dark.backdrop // '#0e0e14'
.package(url: "https://github.com/iGitScor/design", from: "0.2.0")
import IscorDesign
Text("Bonjour")
.font(Estuary.font(size: 17, weight: .semibold)) // Outfit, bundled
.foregroundStyle(Estuary.ink)
.background(Estuary.card, in: .rect(cornerRadius: Estuary.Radius.lg))
# Estuary Light and Estuary Dark, from the VS Code Marketplace
# (or Open VSX, for Cursor, Windsurf and VSCodium)
code --install-extension igitscor.estuary-theme
# Estuary Light and Estuary Dark, from a clone of the repository
mkdir -p ~/Library/Developer/Xcode/UserData/FontAndColorThemes
cp packages/xcode/*.xccolortheme ~/Library/Developer/Xcode/UserData/FontAndColorThemes/
import json
tokens = json.load(open("node_modules/@iscor/design/dist/tokens.json"))
tokens["light"]["accent"] # '#b9ff66'