docs: add JetBrains icon skill

This commit is contained in:
kirillk
2026-07-30 14:33:38 -04:00
parent 2ef92e2e32
commit ce8781cae4
3 changed files with 437 additions and 0 deletions
+143
View File
@@ -0,0 +1,143 @@
---
name: icon-jetbrains
description: Create or review IntelliJ New UI SVG icons, theme variants, sizes, and palette.
---
# IntelliJ Platform New UI Icons
Guidance for authoring SVG icons for the New UI.
Background: the IDE maintains Classic UI and New UI in parallel. Code branches with `ExperimentalUI.isNewUI()`; icons follow the same split. Old icons stay in their original resource folders for Classic-UI compatibility. New-UI icons live under `expui/` folders and are substituted for the old ones at runtime by icon mappers.
## Golden rules
1. **Always ship two SVGs** — one for the light theme (e.g. `addFile.svg`) and one for the dark theme with the `_dark` suffix (`addFile_dark.svg`). Geometry must be identical between them; only the palette swaps.
- **Tool-window icons ship as a quartet, not a pair.** When a tool window has both a 16×16 base (`name.svg` / `name_dark.svg`) and a 20×20 New-UI stripe variant (`name@20x20.svg` / `name@20x20_dark.svg`), they must share the same metaphor. The stripe is only one surface — the 16×16 base also appears in **Search Everywhere**, **Find Action**, context menus, the Services tool window, recent locations, and the View ▸ Tool Windows menu. Changing only the @20x20 leaves users seeing two different icons for the same tool window depending on where they encounter it. Always update all four files together (and the same applies to plugin-local icons like `toolWindowChat.svg` + `toolWindowChat@20x20.svg`).
2. **Only use colors from the canonical palette.** See [palette.md](./palette.md). Picking a one-off color breaks theming and contrast.
3. **One canvas size per icon role.** See [Icon roles](#icon-roles). Do not invent new sizes or pad with empty space — IntelliJ scales the canvas as a single unit.
4. **No raster, no gradients, no filters, no embedded fonts.** Path geometry only (`<path>`, `<rect>`, `<circle>`, `<line>`, `<polyline>`, `<polygon>`). Text must be converted to outlines.
5. **Use `fill="none"` on the root `<svg>`** and set `fill` / `stroke` explicitly per shape — never rely on CSS or `currentColor`.
6. **Strokes use `stroke-width="1"`, `stroke-linecap="round"`, `stroke-linejoin="round"`** (or `stroke-miterlimit="10"` for hard joins). Heavier strokes are reserved for hero glyphs inside a circle badge (e.g. status checkmarks) and use `stroke-width="1.5"` or `"2"`.
7. **Pixel-grid align**: keep stroke axes on half-pixel centers (`x.5`) and fills on whole pixels so the icon stays crisp at 1× rendering.
8. **Preserve the Apache 2.0 copyright comment** as line 1. Match the year of contribution.
9. **File names use camelCase** matching the action/node ID and stay ASCII-only.
## Icon roles
| Role | Canvas | Filename pattern | Reference dir |
|---|---|---|---|
| Action icons (menus, popups, toolbars) | **16×16** | `name.svg` + `name_dark.svg` | `expui/actions/`, `expui/general/` |
| Tree node icons (PSI, structure view) | **16×16** | `name.svg` + `name_dark.svg` | `expui/nodes/` |
| Tool-window stripe icons (legacy/16) | **16×16** | `name.svg` + `name_dark.svg` | `expui/toolwindows/` |
| Tool-window stripe icons (New UI) | **20×20** | `name@20x20.svg` + `name@20x20_dark.svg` | `expui/toolwindows/` |
| Main toolbar (New UI) | **20×20** | `name@20x20.svg` + `name@20x20_dark.svg` | `expui/general/`, `expui/run/`, `expui/toolbar/` |
| Editor gutter icons | **14×14** (small marks **12×12**, **9×9**) | `name.svg` + `name_dark.svg` | `expui/gutter/` |
| Status bar / inline status | **16×16** | `name.svg` + `name_dark.svg` | `expui/status/`, `expui/inline/` |
| Breakpoint marks | **14×14** (12×12 for sub-marks) | `name.svg` + `name_dark.svg` | `expui/breakpoints/` |
| Run-config tags & disclosure chevrons | **16×16** (`chevron*.svg` may be 9×9 to 16×16) | `name.svg` + `name_dark.svg` | `expui/run/`, `expui/general/` |
| Welcome/onboarding & logos (system) | **16, 20, 28, 48** (per surface) | `name.svg` + `name_dark.svg` | `expui/ide/`, `expui/welcome/` |
When in doubt, find a sibling icon in the same folder and copy its `width` / `height` / `viewBox`.
## Where the SVGs live
Two placements exist and both are valid — pick based on whether a Classic-UI icon already exists:
- **Only New UI needed** → put the SVG (and its `_dark` sibling) under an `expui/<role>/` resource root. Callers reference it directly through the plugin's generated `<Plugin>Icons` class.
- **Replacing an existing Classic-UI icon** → keep the Classic file at its old path, put the New UI SVG under the matching `expui/<role>/` path, and add a mapping entry to the nearest `*IconMappings.json`. At runtime, when `ExperimentalUI.isNewUI()` is true, the mapper substitutes the New UI file for the Classic one so no caller has to change its icon reference.
Mapping-file shape (excerpt from `community/platform/icons/src/PlatformIconMappings.json`):
```json
{
"expui": {
"actions": {
"addFile.svg": "actions/addFile.svg",
"checked.svg": ["actions/checked.svg", "actions/setDefault.svg"]
}
}
}
```
Key = path relative to the `expui/` root (the New UI file). Value = the Classic path(s) that should resolve to it. A single New UI icon may back multiple Classic paths.
## SVG skeleton
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- shapes, ordered back-to-front -->
</svg>
```
The dark variant is the same file with light-palette colors swapped for their dark-theme partner — see [palette.md](./palette.md). Never change geometry between the two.
## Composition rules
- **One semantic meaning per icon.** A status badge, an accent dot, or a "+" overlay is fine; two unrelated glyphs in one icon is not.
- **Optical centering, not geometric.** Plus/arrow/refresh glyphs sit slightly above center; round badges (class, method, status) are centered on `(cx=8, cy=8)` for 16×16 and `(cx=10, cy=10)` for 20×20.
- **Outer keep-out**: leave at least **1 px** of empty padding on each side of a 16×16 icon (so meaningful geometry lives within `1..15`). For 20×20 use **2 px** of padding. Stripe icons must stay visually balanced inside their 20×20 cell.
- **Stroke + fill pairing for node-style icons** (e.g. `nodes/class.svg`): a light-tinted fill at radius 6.5 with a stroke in the accent color, plus a glyph filled with the same accent.
- Light: `<circle cx="8" cy="8" r="6.5" fill="<accent-bg-light>" stroke="<accent-light>"/>` then glyph `fill="<accent-light>"`.
- Dark: same circle with `fill="<accent-bg-dark>" stroke="<accent-dark>"` and glyph filled with `<accent-dark>`.
- **Stroke-only icons** (chevrons, refresh, edit pencil): a single-color path using the neutral stroke (`#6C707E` light / `#CED0D6` dark) at `stroke-width="1"`. Use `#818594` (light) / `#6F737A` (dark) for "secondary" stroke glyphs like dropdown chevrons.
- **Status badges** (error/warning/success/info) follow this template:
- Light: filled circle/triangle in the *accent* color, glyph painted in `white`.
- Dark: filled circle/triangle in the *dark accent* color, glyph painted in the matching *muted dark fill* (e.g. `#5E4D33` inside `#F2C55C` warning) — never plain white.
- **Two-tone action icons** (e.g. `actions/addFile.svg`): the base glyph uses the neutral gray, and the small "modifier" (`+`, ✕, ↻, gear) uses the primary blue accent. Light gray + blue accent → dark gray + blue accent in the dark variant.
- **Disabled / stroke-only variants** (e.g. `*_stroke.svg`): outline-only, same neutral stroke color, no fills.
## Palette quick reference
The full lookup is in [palette.md](./palette.md). Most icons only need:
| Role | Light | Dark |
|---|---|---|
| Primary stroke / fill | `#6C707E` | `#CED0D6` |
| Secondary stroke | `#818594` | `#6F737A` |
| Disabled / faint fill | `#EBECF0` | `#43454A` |
| Accent — Blue | `#3574F0` | `#548AF7` |
| Accent — Blue (bg) | `#EDF3FF` / `#E7EFFD` | `#25324D` |
| Accent — Red | `#DB3B4B` | `#DB5C5C` |
| Accent — Red (bg) | `#FFF7F7` | `#402929` |
| Status — Error fill | `#E55765` | `#DB5C5C` |
| Status — Warning fill | `#FFAF0F` | `#F2C55C` |
| Status — Success fill | `#55A76A` | `#57965C` |
| Accent — Green | `#208A3C` | `#57965C` |
| Accent — Green (bg) | `#F2FCF3` | `#253627` |
| Accent — Orange | `#E66D17` | `#C77D55` |
| Accent — Orange (bg) | `#FFF4EB` | `#45322B` |
| Accent — Yellow/Gold | `#FFAF0F` / `#C27D04` | `#F2C55C` / `#D6AE58` |
| Accent — Purple | `#834DF0` | `#B589EC` |
| Accent — Purple (bg) | `#FAF5FF` | `#2F2936` |
| White on dark badge | `white` | matching muted-dark fill (e.g. `#5E4D33`) |
Do not use plain `#000000` or off-the-palette grays.
## Generation workflow
1. **Pick the role and canvas size** from the table above. Find at least two visually similar siblings under `community/platform/icons/src/expui/<role>/` and read their SVG sources. Mirror their stroke/fill mix.
2. **Lay out geometry on the pixel grid** (whole-pixel fills, half-pixel stroke centers). Optical-center the glyph.
3. **Apply the canonical light palette** from [palette.md](./palette.md). Never invent colors.
4. **Save the light SVG** with the Apache 2.0 header, `width`/`height`/`viewBox` matching the role, and `fill="none"` on `<svg>`.
5. **Duplicate to the `_dark` filename** and swap each color for its dark-theme partner from the palette mapping. Keep paths byte-identical otherwise.
6. **Place and wire the file**:
- **Fresh New UI icon** → drop into the matching `expui/<role>/` resource folder; reference it from the plugin's `<Plugin>Icons` class.
- **Replacement for a Classic icon** → keep the Classic file untouched, add the New UI file under `expui/<role>/`, add a mapping entry to the nearest `*IconMappings.json`. Callers keep referencing the old path.
7. **Verify visually** in both themes via the image preview in the IDE, or run the IDE and toggle *View ▸ Appearance ▸ New UI* to compare. Check selection states for stripe icons.
## Common mistakes
- Off-palette colors (e.g. importing from Figma without remapping). They will not theme correctly and reviewers will reject the PR.
- Different geometry between light and dark variants — selection animations and HiDPI overlays will glitch.
- A 16-px glyph saved into a 20×20 canvas without re-balancing. Tool-window/main-toolbar icons need geometry tuned for 20×20, not a 16×16 reused with extra whitespace.
- Using `currentColor`, CSS, or `<style>` blocks. The IntelliJ icon loader requires explicit colors on every shape so it can do palette-based recoloring.
- Forgetting the `_dark` variant. The icon will look fine in Light theme then turn invisible in Dark.
- Pure-black (`#000`) or pure-white (`#FFF`) fills outside the status-badge glyph pattern. They break under accent recoloring.
- Adding a New UI SVG without a `*IconMappings.json` entry when replacing a Classic icon — the Classic icon will keep showing in New UI mode.
## References
- [palette.md](./palette.md) — full color palette with light↔dark mapping.
- [examples.md](./examples.md) — annotated SVG snippets for each icon role, copied from the live icon set.
- Canonical example tree: `community/platform/icons/src/expui/` — when reviewing, diff your new icon against a sibling there.
- Repo-level `Icons guidelines.svg` is a design sheet (visual reference only; not machine-readable). When it disagrees with the folder, trust the folder.
+176
View File
@@ -0,0 +1,176 @@
# Annotated New UI Icon Examples
Each example below is copied from `community/platform/icons/src/expui/`, paired with the dark variant and a short note on the pattern it represents. Use these as templates when generating new icons.
---
## 1. Single-color action (16×16) — primary gray stroke + filled glyph
`expui/general/add.svg` — the most common action icon shape.
**Light:**
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 1C7.77614 1 8 1.22386 8 1.5V7H13.5C13.7761 7 14 7.22386 14 7.5C14 7.77614 13.7761 8 13.5 8H8V13.5C8 13.7761 7.77614 14 7.5 14C7.22386 14 7 13.7761 7 13.5V8H1.5C1.22386 8 1 7.77614 1 7.5C1 7.22386 1.22386 7 1.5 7H7V1.5C7 1.22386 7.22386 1 7.5 1Z" fill="#6C707E"/>
</svg>
```
**Dark:** swap `#6C707E``#CED0D6`.
Why it works: one filled path, primary gray. Drop in any glyph and you have a complete action icon.
---
## 2. Two-tone action (16×16) — neutral base + blue accent modifier
`expui/actions/addFile.svg` — base glyph in neutral gray, "+" sticker in primary blue.
**Light:**
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5 9C12.7761 9 13 9.22386 13 9.5V12H15.5C15.7761 12 16 12.2239 16 12.5C16 12.7761 15.7761 13 15.5 13H13V15.5C13 15.7761 12.7761 16 12.5 16C12.2239 16 12 15.7761 12 15.5V13H9.5C9.22386 13 9 12.7761 9 12.5C9 12.2239 9.22386 12 9.5 12H12V9.5C12 9.22386 12.2239 9 12.5 9Z" fill="#3574F0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 13V5.82843C3 5.29799 3.21071 4.78929 3.58579 4.41421L6.41421 1.58579C6.78929 1.21071 7.29799 1 7.82843 1H11C12.1046 1 13 1.89543 13 3V8H12V3C12 2.44772 11.5523 2 11 2H8V4C8 5.10457 7.10457 6 6 6H4V13C4 13.5523 4.44772 14 5 14H8V15H5C3.89543 15 3 14.1046 3 13ZM4.41421 5L7 2.41421V4C7 4.55228 6.55228 5 6 5H4.41421Z" fill="#6C707E"/>
</svg>
```
**Dark:** `#3574F0``#548AF7`, `#6C707E``#CED0D6`.
Pattern: stick the small modifier glyph in the bottom-right of the canvas (`(9..15, 9..15)` for 16×16) and let the base glyph occupy the top-left two-thirds.
---
## 3. Stroke-only action (16×16) — chevrons, refresh, edit
`expui/general/refresh.svg` — multiple stroked sub-paths sharing one color.
**Light:**
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.5 9V8C2.5 4.96243 4.96243 2.5 8 2.5C9.10679 2.5 10.1372 2.82692 11 3.38947" stroke="#6C707E" stroke-linecap="round"/>
<path d="M5 12.6105C5.86278 13.1731 6.89321 13.5 8 13.5C11.0376 13.5 13.5 11.0376 13.5 8V7" stroke="#6C707E" stroke-linecap="round"/>
<path d="M0.49997 7.50027L2.5 9.5L4.49998 7.50023" stroke="#6C707E" stroke-linecap="round"/>
<path d="M11.5 8.49982L13.5 6.5L15.5 8.49982" stroke="#6C707E" stroke-linecap="round"/>
</svg>
```
`stroke-width` defaults to `1`. `stroke-linecap="round"` softens path ends; pair it with `stroke-linejoin="round"` whenever paths bend.
For secondary glyphs (chevrons in popups, dropdown arrows) use `#818594` light / `#6F737A` dark instead of the primary gray.
---
## 4. Node icon (16×16) — tinted circle with stroke + glyph
`expui/nodes/class.svg` and `expui/nodes/method.svg` — the canonical PSI-node shape.
**Light (class — blue):**
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="6.5" fill="#E7EFFD" stroke="#3574F0"/>
<path d="M8.13295 11.5C9.61223 11.5 …" fill="#3574F0"/>
</svg>
```
**Dark (class):**
```svg
<circle cx="8" cy="8" r="6.5" fill="#25324D" stroke="#548AF7"/>
<path d="…" fill="#548AF7"/>
```
**Method (red) follows the same template** with `#FFF7F7`/`#DB3B4B` (light) → `#402929`/`#DB5C5C` (dark).
Rules:
- Circle is always `cx="8" cy="8" r="6.5"` (so the 1-px stroke is centered between pixels 1 and 15).
- Fill = soft background pair, stroke = accent.
- Glyph inside uses the same accent color filled — never stroked.
---
## 5. Status badge (16×16) — circle/triangle with white glyph
`expui/status/error.svg`:
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="7" fill="#E55765"/>
<path d="M9 5C9 4.44772 8.55228 4 8 4C7.44772 4 7 4.44772 7 5V7.5C…" fill="white"/>
<path d="M8 12C8.55228 12 9 11.5523 9 11C9 10.4477 8.55228 10 8 10C7.44772 10 7 10.4477 7 11C7 11.5523 7.44772 12 8 12Z" fill="white"/>
</svg>
```
`expui/status/warning.svg` is the same idea but with a rounded triangle filled `#FFAF0F` (light) / `#F2C55C` (dark). In the dark theme, the glyph inside the warning triangle uses `#5E4D33` instead of `white` (white on warm yellow is unreadable).
`expui/status/success.svg` uses a 2-px stroked checkmark inside a `#55A76A` (light) / `#57965C` (dark) circle — `stroke="white"` and `stroke-width="2"`.
---
## 6. Tool window stripe (20×20) — single-tone glyph on a larger canvas
`expui/toolwindows/build@20x20.svg` (excerpt):
```svg
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.25 1C4.44891 1 …" fill="#6C707E"/>
</svg>
```
Notes:
- 20×20 canvas with **at least 2 px** breathing room on each edge (geometry lives in `2..18`).
- Re-balance vs. a 16×16 sibling — do not just paste a 16×16 path into a 20×20 viewBox.
- For the 16×16 stripe (legacy / compact mode), keep a sibling `build.svg`; New UI uses the `@20x20` variant by default.
---
## 7. Main toolbar action (20×20) — same template as tool window
`expui/general/add@20x20.svg`:
```svg
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.75586 17.25C9.34165 17.25 9.00586 16.9142 9.00586 16.5V10.5059H3C…" fill="#6C707E"/>
</svg>
```
Main-toolbar icons reuse the 20×20 conventions of tool window stripes — the canvas size and stroke weights are identical, only the visual semantics differ.
---
## 8. Gutter icon (14×14) — thin stroke, no padding
`expui/gutter/javadocEdit.svg`:
```svg
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5973 6.65471L12.6882 4.56049C…" stroke="#6C707E" stroke-miterlimit="10"/>
</svg>
```
Gutter icons:
- Canvas is 14×14 (not 16×16). Glyph extends to the edge — there is *no* outer padding margin in the gutter.
- Prefer `stroke-miterlimit="10"` for hard-pointed glyphs (pencil tip), `stroke-linecap="round"` for chevrons / arrows.
- Compound gutter glyphs (e.g. implemented + override marker) layer two badges; keep each badge ≤ 9 px so the composition stays legible.
---
## 9. Breakpoint mark (14×14) — solid filled circle
`expui/breakpoints/breakpoint.svg`:
```svg
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 13C10.3137 13 13 10.3137 13 7C13 3.68629 10.3137 1 7 1C3.68629 1 1 3.68629 1 7C1 10.3137 3.68629 13 7 13Z" fill="#E55765"/>
</svg>
```
Breakpoint marks read at a glance — a single solid fill in the status-error red. Variants (disabled, conditional, log) layer a small overlay in the bottom-right corner.
---
## 10. Dark-variant gotcha — white-on-warm vs. muted-dark
`expui/status/warning_dark.svg` shows the only common case where a literal find-and-replace from the light SVG would produce a broken icon:
```svg
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.27603 10.8634L6.3028 1.98903C7.04977 0.670323 8.94893 0.670326 9.69589 1.98903L14.7227 10.8634C15.516 12.2639 14.5047 14 12.8956 14H3.10308C1.494 14 0.482737 12.2639 1.27603 10.8634Z" fill="#F2C55C"/>
<path d="…" fill="#5E4D33"/>
<path d="…" fill="#5E4D33"/>
</svg>
```
`white``#5E4D33` inside the warning triangle. Apply the same swap whenever a light icon paints a glyph as `white` over a warm fill (`#FFAF0F`, `#E66D17`, etc.). For cool fills (`#3574F0`, `#208A3C`, `#DB3B4B`), the dark-theme glyph stays `white` because contrast is still sufficient.
+118
View File
@@ -0,0 +1,118 @@
# New UI Icon Palette
Canonical color palette used by New UI icons. Empirically derived from a full scan of `community/platform/icons/src/expui/` (~2000 light + ~2000 dark SVGs). When picking colors, always pull from this table; the IntelliJ icon engine recolors by exact-string match, so a one-off hue will fail to theme.
## How to read the mapping
- **Light** column is the color used in the default (light) SVG file: `foo.svg`.
- **Dark** column is its replacement in the `_dark` partner: `foo_dark.svg`.
- Always swap **all** light colors at once when generating the dark variant. Do not mix-and-match — the palette pairs are tuned for contrast.
## Neutrals (most icons need only these)
| Role | Light | Dark |
|---|---|---|
| **Primary stroke / fill** (main glyph) | `#6C707E` | `#CED0D6` |
| Secondary stroke (chevrons, faint glyph) | `#818594` | `#6F737A` |
| Tertiary stroke (very faint) | `#A8ADBD` | `#9DA0A8` |
| Disabled / inert fill background | `#EBECF0` | `#43454A` |
| Background plate (rare) | `#F0F1F2` | `#5A5D63` / `#1E1F22` |
| Plain white (status glyph only) | `white` | per-status muted (see below) |
`#6C707E``#CED0D6` is the single most-used pair across the entire icon set. If you only remember one pair, remember this one.
## Accent — Blue (primary action, info, default node)
| Role | Light | Dark |
|---|---|---|
| Stroke / fill | `#3574F0` | `#548AF7` |
| Soft background fill (node circle) | `#E7EFFD` | `#25324D` |
| Tinted-panel fill | `#EDF3FF` | `#25324D` |
| Alt blue (rare) | `#4682FA` | `#5F93FF` |
## Accent — Red (delete, error nodes, breakpoints)
| Role | Light | Dark |
|---|---|---|
| Stroke / fill | `#DB3B4B` | `#DB5C5C` |
| Soft background fill | `#FFF7F7` | `#402929` |
| Status badge fill (error circle) | `#E55765` | `#DB5C5C` |
The slightly different `#DB3B4B` (line / accent) vs `#E55765` (badge fill) split is intentional — the filled status circle is a touch more saturated than the line accent.
## Accent — Green (run, success, version-control add)
| Role | Light | Dark |
|---|---|---|
| Stroke / fill | `#208A3C` | `#57965C` |
| Soft background fill | `#F2FCF3` | `#253627` |
| Status badge fill (success circle) | `#55A76A` | `#57965C` |
| Alt green (rare) | `#369650` | `#5FAD65` |
## Accent — Orange / Yellow (warning, modified, bookmark)
| Role | Light | Dark |
|---|---|---|
| Orange stroke / fill | `#E66D17` | `#C77D55` |
| Orange soft fill | `#FFF4EB` | `#45322B` |
| Warning yellow (status triangle) | `#FFAF0F` | `#F2C55C` |
| Warning soft fill | `#FFFAEB` / `#F7E4CD` | `#3D3223` |
| Brown / gold deep | `#C27D04` | `#D6AE58` |
| Muted dark glyph inside warning fill | n/a (uses `white`) | `#5E4D33` |
The "white on yellow" combination is illegible in Dark theme; that's why the dark warning glyph uses `#5E4D33` (a deep brown). Apply the same idea — muted-dark glyph inside the warm fill — for any other warm-color badge in the dark theme.
## Accent — Purple (annotations, special / preview)
| Role | Light | Dark |
|---|---|---|
| Stroke / fill | `#834DF0` | `#B589EC` |
| Soft background fill | `#FAF5FF` | `#2F2936` |
| Alt purple (rare) | n/a | `#A571E6` |
## Reserved / utility
| Role | Light/Dark |
|---|---|
| Inside-circle glyph (light status) | `white` |
| Empty / placeholder | `#231F20` (avoid) |
| Tool window panel base (very rare) | `#1E1F22` (dark) |
| Other repository-specific tints | only when a sibling icon already uses them |
If your icon needs a color that is not in this table, find a sibling icon that uses something similar and reuse its exact hex string. If no sibling uses it, change your design — do not introduce a new color.
## Algorithmic light→dark swap (for scripted generation)
```text
#6C707E -> #CED0D6 primary stroke/fill
#818594 -> #6F737A secondary stroke
#A8ADBD -> #9DA0A8 tertiary stroke
#EBECF0 -> #43454A disabled fill
#3574F0 -> #548AF7 blue
#EDF3FF -> #25324D blue soft
#E7EFFD -> #25324D blue node fill
#DB3B4B -> #DB5C5C red
#FFF7F7 -> #402929 red soft
#E55765 -> #DB5C5C error badge fill
#208A3C -> #57965C green
#55A76A -> #57965C success badge fill
#F2FCF3 -> #253627 green soft
#369650 -> #5FAD65 alt green
#E66D17 -> #C77D55 orange
#FFF4EB -> #45322B orange soft
#FFAF0F -> #F2C55C warning yellow
#FFFAEB -> #3D3223 warning soft
#F7E4CD -> #3D3223 warning soft alt
#C27D04 -> #D6AE58 gold
#834DF0 -> #B589EC purple
#FAF5FF -> #2F2936 purple soft
white -> (status-glyph specific muted dark — see Orange/Yellow section)
```
A script can do a literal find-and-replace using this map to produce a `_dark.svg` from a light SVG; review the result manually for any white-on-warm cases that need the muted-dark glyph treatment.