Ayu NewrageA dark VS Code theme that puts ayu Mirage syntax colors on Mayukai Mirage chrome. The theme targets VS Code's modern UI. That rendering computes parts of the workbench from theme colors instead of reading them directly, so a palette tuned for the classic chrome can wash out once those formulas run. Ayu Mirage's look survives intact here, with the contrast underneath it raised so both rendering paths stay readable. Tabs under the modern UI covers where that matters most.
Rust in the editor, with the explorer, modern UI tabs and integrated terminal. What comes from whereMayukai Mirage supplies the workbench: editor foreground ayu Mirage supplies everything inside the code:
Deviations from both sourcesOne flat editor surface at
|
| on | ratio | ||
|---|---|---|---|
tab.activeForeground #ffffff |
#191e2a |
16.66:1 | AAA |
tab.inactiveForeground #ffffff |
#1f2430 |
15.52:1 | AAA |
tab.unfocusedActiveForeground #ffffff |
#191e2a |
16.66:1 | AAA |
tab.unfocusedInactiveForeground #ffffff |
#1f2430 |
15.52:1 | AAA |
tab.selectedForeground #ffffff |
#232834 |
14.74:1 | AAA |
The gold top border and the background step from #191e2a to #1f2430 tell
active and inactive tabs apart, rather than a dimmed label. Dimming is what put
Mayukai's inactive tabs below AA to begin with.
Git decorations
ayu and Mayukai both set only modified, deleted and untracked. The other four
decoration slots fell through to VS Code's built-in dark defaults, which are the
stock red/amber/green set and ignore the theme entirely. A and U in the
explorer both landed on a green, because untracked was ayu's #87d96c and added
was the default #81b88b. All seven are explicit now:
on #191e2a |
||
|---|---|---|
modifiedResourceForeground |
#80bfff |
8.58:1 |
stageModifiedResourceForeground |
#80bfff |
8.58:1 |
addedResourceForeground |
#bae67e |
11.67:1 |
untrackedResourceForeground |
#87d96c |
9.66:1 |
renamedResourceForeground |
#93e2c8 |
11.07:1 |
deletedResourceForeground |
#f27983 |
6.22:1 |
stageDeletedResourceForeground |
#f27983 |
6.22:1 |
Added and untracked stay in the green family because both mean new content, but added is ayu's yellow-green against untracked's leaf green, so the two badges read apart. Staged modify and delete match their unstaged counterparts; the badge letter carries the staging, not the hue.
Menus
Mayukai defines no menu.* colors, so menu.foreground inherited
dropdown.foreground at #707a8c, which is 3.41:1 on the menu surface. The full
set is explicit here, with menu.foreground #c2c6cc at 8.59:1.
Remote indicator
statusBarItem.remoteBackground was #ff9940 with no foreground set, so VS Code
defaulted to white at 2.1:1. It is pastel #ffb38a now, with an explicit
#1f2430 foreground at 8.92:1 and a matching hover pair.
Tabs under the modern UI
The table above is what the tab.* tokens ask for, and what the classic tab strip
gives you. With workbench.experimental.modernUI enabled, VS Code ignores most of
them and sets tab labels in CSS with !important, computed from the global
foreground token:
| source | with foreground #adb3be |
ratio | |
|---|---|---|---|
| active label | foreground |
#adb3be |
5.02:1 |
| active fill | color-mix(foreground 22%, editor.background) |
#3a3f4b |
n/a |
| inactive label | foreground at 50% alpha |
#636974 |
3.00:1 |
| selected label | tab.selectedForeground |
#ffffff |
honored |
That formula narrows what a theme can control:
tab.activeForeground,tab.inactiveForegroundand bothunfocused*variants do nothing.tab.selectedForegroundis the one label token still read.- The active tab's fill derives from the same token as its text, so the two move together. Darkening the highlight darkens the label faster than the background, which costs contrast rather than gaining it.
- Inactive labels sit at a fixed 50% alpha and top out near 4.4:1 whatever the
theme does.
foregroundis#adb3behere, matchingsideBar.foreground, so the tabs and the explorer tree read as one surface.
Labels carrying a git decoration are exempt from the override and keep their
decoration color. Setting workbench.experimental.modernUI to false hands every
row in that table back to the tab.* tokens.
Install
From the Marketplace, Ctrl+P and then:
ext install walzengroup.ayu-newrage
Or copy this folder into your extensions directory:
# VS Code
Copy-Item -Recurse . "$env:USERPROFILE\.vscode\extensions\ayu-newrage-1.0.1"
# Cursor
Copy-Item -Recurse . "$env:USERPROFILE\.cursor\extensions\ayu-newrage-1.0.1"
Then Ctrl+Shift+P and Developer: Reload Window, Ctrl+K Ctrl+T, and pick
Ayu Newrage.
To build a .vsix instead:
npx @vscode/vsce package
code --install-extension ayu-newrage-1.0.1.vsix
Publishing
Published to the VS Code Marketplace as WalzenGroup.ayu-newrage. Not on Open
VSX, so VSCodium and Cursor users take the .vsix route above.
One-time setup: create a Personal Access Token at https://dev.azure.com, scoped
to Marketplace > Manage under all accessible organizations, then either
npx @vscode/vsce login walzengroup
or set $env:VSCE_PAT to the token and skip the login. npx @vscode/vsce verify-pat walzengroup checks a token you already have. Azure PATs expire, one
year maximum, so a failed publish is usually just an expired token.
Each release:
# 1. bump version, make the commit and tag locally
npm version patch
# 2. build, then check what actually went in the box
npx @vscode/vsce package
npx @vscode/vsce ls
# 3. upload
npx @vscode/vsce publish
npx @vscode/vsce publish patch collapses steps 1 and 3: it shells out to npm version, which writes the version commit and tag, then uploads. Neither form
pushes anything, so the tag stays local until you push it. --no-git-tag-version
gives you the version bump with no commit.
Marketplace listings take a few minutes to show the new version, and installed copies pick it up on VS Code's own update schedule.
Two things carry the version by hand and need editing at bump time: the folder
names in the Install section above, and the .vsix filename in the same block.
