28 Commits

Author SHA1 Message Date
mpuchstein 87685a1c88 feat: v2.1 — attention violet→pink, purple sacred form-coded, WCAG AA pass
- Attention channel moves from violet to pink (~340° OKLCH); red stays
  urgent-only, pink takes cursor/search/selection/active border
- Purple = sacred is now its own spine entry, always form-coded (bold or
  fielded), never bare hue; ANSI color5 no longer collides with cursor hex
- Reserved-hue rule rephrased: never *syntax tokens* (interaction state
  may render in-buffer); 16-color ANSI floor exempt
- Aeon WCAG AA pass: punctuation/escape direction bug fixed, deep accent
  band lifted past 4.5:1 on Paper and Surface, bright bank deepened
2026-06-12 21:39:40 +02:00
mpuchstein 24d019a0f5 hyprlang is going to be deprecated for hyprland TODO: create a lua theme 2026-06-12 09:27:39 +02:00
mpuchstein f98e10c648 hyprland: red=urgent, violet=active border (v2 spine fix)
The focused window glowed danger-red while urgent windows had no treatment -
backwards vs the keystone. Wire the existing focus (attention violet) and blue
(structural) channels into the Hyprland template: active border -> focus, new
$border_urgent (red), inactive -> dim cyan, group -> blue, group-locked -> amber,
groupbar active -> blue+cyan info gradient. Retag danger.base as urgent-window
border in src; update apex-neon.md/apex-aeon.md sections 5 + 12 accordingly.
2026-06-04 04:31:12 +02:00
mpuchstein 43dcb71d15 docs: promote apex-neon.md/apex-aeon.md to canonical specs
Rename the v2 spec docs to drop the -v2 suffix and make them the authoritative source of truth. Slim GEMINI.md to a pointer and update CLAUDE.md, AGENTS.md, README.md, INSTALL.md to v2 semantics and the current 15-app target list.
2026-06-03 02:08:47 +02:00
mpuchstein fd3a45761b chore: drop gemini, sherlock, swaync, waybar, wezterm targets
Remove these app targets and their generated artifacts. The four UI apps are not installed for testing; gemini-cli was deprecated by Google.
2026-06-03 02:08:47 +02:00
mpuchstein 5619225ae0 feat: rewrite color system to v2 semantics
Rework src/{neon,aeon}.yaml into a v2-native, scheme-symmetric schema (neutral/focus/danger/signal/syntax/diff/ansi) and re-author all app templates against it.

New semantic spine: red = danger only, violet = attention (cursor/search/pairs/selection), cyan = info/actions, blue = kinds, green = values, amber = UI-warning. Red, violet, and amber never enter a code buffer.
2026-06-03 02:08:47 +02:00
mpuchstein 71ae1c022e docs: add Apex Neon v2 specification 2026-06-02 13:35:54 +02:00
mpuchstein bb6c7923e5 chore: commit nushell dist artifacts 2026-06-02 13:35:17 +02:00
mpuchstein d7182832ee feat: add nushell color_config theme target 2026-05-17 05:35:12 +02:00
mpuchstein db82dac1ac nvim: fix M.lualine scope — move after M.load() so palette is populated 2026-04-09 23:43:34 +02:00
mpuchstein d9c25d55ed nvim: fix M.lualine scope — move after M.load() so palette is populated 2026-04-09 23:41:56 +02:00
mpuchstein afa8245fc0 chore: remove stale tmux dist artifacts 2026-04-09 22:33:16 +02:00
mpuchstein e61f892841 feat: extend nvim plugin highlights + add tmux target
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:24:19 +02:00
mpuchstein 799601134d added claude to this repo 2026-03-11 00:44:29 +01:00
mpuchstein e65eb8f6a4 feat: canonicalize syntax roles + theme zsh plugins
Add authoritative `syntax:` block to both YAML specs mapping keyword,
type, function, string, constant, operator, variable, comment, and
punctuation to their semantic palette colors. Align nvim and Zed
templates to this canonical mapping (keyword=purple, type=amber,
number/bool/constant=cyan, operator=white). Fix nvim Special/SpecialChar/
Tag (were cyan; now purple/amber/blue respectively).

Add plugin color variables to zsh template: ZSH_AUTOSUGGEST uses dim
grey for ghost text; HISTORY_SUBSTRING_SEARCH uses cyan for found and
bright-red for not-found, matching the semantic palette signal system.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 00:43:52 +01:00
mpuchstein 6a815f72b3 feat: streamline zsh prompt git state
- parse git status in one call and add untracked/stash/conflict markers
- escape prompt strings and harden timing math
- improve ro/jobs checks and add container intel
2026-01-12 23:46:25 +01:00
mpuchstein 2ac05f469c feat: expand nvim highlights and add audit script 2026-01-12 23:11:24 +01:00
mpuchstein 6b3bb01c2c reworked the nvim theme a bit more 2026-01-12 22:40:55 +01:00
mpuchstein 74cd31a03e reworked the nvim theme a bit 2026-01-12 22:18:47 +01:00
mpuchstein a00cf1f6ff feat(nvim): add transparency for floating UI
Set winblend and pumblend to 20 (80% opaque) for floating windows
and popup menus.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 21:34:04 +01:00
mpuchstein cb0fa9e6f1 feat: add wezterm and ghostty themes 2025-12-31 07:36:00 +01:00
mpuchstein ed658e43b3 chore: track dist outputs 2025-12-31 06:22:01 +01:00
mpuchstein f4566fa638 fix: release meta.yaml newlines 2025-12-31 06:17:21 +01:00
mpuchstein c046821dc9 chore: release apps v1.0.0 2025-12-31 06:15:25 +01:00
mpuchstein aa8bc21d97 fix: normalize new app meta.yaml 2025-12-31 06:14:52 +01:00
mpuchstein 3ea3533139 chore: release apps v1.0.0 2025-12-31 06:11:39 +01:00
mpuchstein b8fffddd1b feat: add spicetify, owlry, and sherlock templates 2025-12-31 06:10:46 +01:00
mpuchstein 1198ae8afd chore: add release automation 2025-12-31 05:07:22 +01:00
72 changed files with 7961 additions and 1127 deletions
-1
View File
@@ -1,4 +1,3 @@
dist/
.venv/
__pycache__/
*.pyc
+2 -1
View File
@@ -29,5 +29,6 @@
- For visual/theme changes, include a brief before/after note or screenshots when possible.
## Theme Rules & Source of Truth
- `GEMINI.md` is the authoritative source for color semantics and rules; update `src/*.yaml` first, then templates if needed.
- `apex-neon.md` and `apex-aeon.md` are the authoritative source for color semantics and rules (`GEMINI.md` is a slim pointer to them); update `src/*.yaml` first, then templates if needed.
- Semantic spine: red = danger only, violet = attention (cursor/search), cyan = info/actions, blue = kinds, green = values, amber = UI warning. Red, violet, and amber never enter a code buffer.
- Avoid introducing ad-hoc colors that violate the semantic palette.
+57
View File
@@ -0,0 +1,57 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Build
```bash
uv run build.py
```
Regenerates all theme files from `src/*.yaml` via Jinja2 templates into `dist/`. There is no watch mode — rerun after any YAML or template change. Python 3.12+ required; dependencies managed via `uv` (`pyproject.toml`).
## Architecture
Apex is a **theme factory** — a build system that generates native theme configs for 15 applications from a single semantic color specification.
**Data flow:**
1. `src/neon.yaml` and `src/aeon.yaml` define the canonical color palette and semantic roles
2. `templates/<app>/*.j2` define per-application output formats (Lua, JSON, TOML, CSS, Conf, etc.)
3. `templates/<app>/meta.yaml` controls the build strategy:
- `strategy: individual` → outputs `apex-neon.<ext>` and `apex-aeon.<ext>` separately
- `strategy: aggregated` → outputs a single file containing both schemes (e.g., `apex.json` for Zed)
4. `build.py` orchestrates rendering; `dist/` holds all generated artifacts (gitignored)
**Adding a new app target:** create `templates/<app>/`, add a `meta.yaml` with strategy, write `.j2` templates using the YAML variables, then run the build.
## Theme Design Rules
`apex-neon.md` and `apex-aeon.md` are the authoritative source of truth for color semantics (`GEMINI.md` is a slim pointer to them). Key axioms (the semantic spine):
- **Red (`#ff0044`) = Danger only** — errors, destructive actions, **urgent** window border (never the merely focused one). **Never a syntax token.**
- **Pink = Attention** — cursor, search, matched pairs, selection, active/focused border. **Never a syntax token.**
- **Cyan = Informational / actions** — links, info state, function calls. Never use for errors or destruction.
- **Blue = Kinds** — types, structures, structural accents (a real channel, distinct from cyan).
- **Green = Values** — strings, numbers, constants, success.
- **Amber = UI warning only** — never inside a code buffer.
- **Purple = Sacred** — reserved for root access and exceptional system states; always form-coded (bold or on a field), never bare hue.
- **Bright ANSI variants (815)** are for escalated/active states only.
- Do not introduce colors without a semantic reason. If it has no signal purpose, remove it.
Before modifying `src/*.yaml`, consult `apex-neon.md` / `apex-aeon.md` to verify that any new or changed role fits the semantic palette.
## Conventions
- Commit style: Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`)
- Template output names: `apex-<scheme>.<ext>` for individual; base name for aggregated
- YAML keys in `src/`: keep consistent with existing semantic roles; add new roles only when truly necessary
- `dist/` is build output — never edit by hand
## Validation
After changes, run `uv run build.py` and inspect relevant files in `dist/`. For Neovim-specific validation, `scripts/nvim-audit.sh` is available.
## Scripts
- `scripts/release.sh` — Per-app versioning and Gitea release automation. Usage: `bash scripts/release.sh <semver>`. Discovers changed apps via git diff, updates `meta.yaml` version fields, builds, and publishes tarballs. Supports `--dry-run`.
- `scripts/nvim-audit.sh` — Validates the built Neovim theme by running headless Neovim. Requires `dist/nvim/colors/apex-neon.lua` to exist first.
+20 -83
View File
@@ -1,89 +1,26 @@
# Apex Theme System: GEMINI Context
# Apex Theme System — Color Source of Truth
This file serves as the persistent brain and Source of Truth for the Apex Theme System (Neon & Aeon). It defines the philosophy, DNA, and rules that must be adhered to in all generated code and configurations.
The canonical color specifications for the Apex Theme System are:
## 1. Project Philosophy
**"State over Decoration."**
Apex is not about pretty colors; it is about signal clarity.
- **Neon** is a high-contrast dark theme for low-light focus.
- **Aeon** is a clinical, high-clarity light theme for daylight precision.
- Both share a unified semantic discipline: color exists only to communicate state.
- **[`apex-neon.md`](apex-neon.md)** — the dark theme specification.
- **[`apex-aeon.md`](apex-aeon.md)** — the light theme specification.
## 2. The Color DNA (Source of Truth)
These two documents are the authoritative source of truth for all color
semantics, the semantic spine, and the rules that every generated theme must
honor. Consult them before changing `src/neon.yaml` or `src/aeon.yaml`.
### Core & Semantics
## The semantic spine (summary)
| Role | Apex Neon (Dark) | Apex Aeon (Light) | Note |
|---|---|---|---|
| **Background** | `#050505` (Void Black) | `#f5f5f5` (Void White) | The Canvas |
| **Foreground** | `#ededed` (Stark White) | `#0a0a0a` (Near Black) | Primary Text |
| **Primary/Error**| `#ff0044` (Razor Red) | `#ff0044` (Razor Red) | Aggressor/Focus |
| **Info/Accent** | `#00eaff` (Electric Cyan)| `#007a88` (Deep Cyan) | Technical/Info |
| **Success** | `#00ff99` | `#00b377` | OK/Pass |
| **Warning** | `#ffb700` | `#d18f00` | Alert/Load |
| **Special** | `#9d00ff` | `#7a3cff` | Root/Admin |
| **Azure** | `#0088cc` | `#005577` | Structural/Functions |
- **Red** = danger only — errors, destructive actions, **urgent** window border.
Never a syntax token.
- **Pink** = attention — cursor, search, matched pairs, selection, active border.
Never a syntax token.
- **Cyan** = information / actions — links, info state, function calls.
- **Blue** = kinds — types, structures, structural accents (distinct from cyan).
- **Green** = values — strings, numbers, constants, success.
- **Amber** = UI warning only — never inside a code buffer.
- **Purple** = sacred — reserved for root access / exceptional system states;
always form-coded (bold or fielded), never bare hue.
### UI Surfaces
| Role | Apex Neon (Dark) | Apex Aeon (Light) |
|---|---|---|
| **Main BG** | `#050505` | `#f5f5f5` |
| **Panel/Soft** | `#141414` | `#e8e8e8` |
| **Border/Muted**| `#262626` | `#737373` |
| **High Surface**| N/A | `#ffffff` |
| **Muted Text** | `#737373` | `#737373` |
| **Stealth** | `#404040` | `#a0a0a0` |
### ANSI Tables (16-Color)
| Slot | Role | Neon Hex | Aeon Hex |
|---|---|---|---|
| 0 | Black/Bg | `#050505` | `#0a0a0a` |
| 1 | Red | `#ff0044` | `#ff0044` |
| 2 | Green | `#00ff99` | `#00b377` |
| 3 | Yellow | `#ffb700` | `#d18f00` |
| 4 | Blue | `#00eaff` | `#007a88` |
| 5 | Magenta | `#9d00ff` | `#7a3cff` |
| 6 | Cyan | `#00eaff` | `#007a88` |
| 7 | White/Fg | `#ededed` | `#f5f5f5` |
| 8 | BrBlack | `#737373` | `#737373` |
| 9 | BrRed | `#ff8899` | `#ff4d6d` |
| 10 | BrGreen | `#2bffb2` | `#33d6a6` |
| 11 | BrYellow | `#ffd24d` | `#ffbf40` |
| 12 | BrBlue | `#5af3ff` | `#33bccc` |
| 13 | BrMagenta| `#c84dff` | `#a680ff` |
| 14 | BrCyan | `#5af3ff` | `#33bccc` |
| 15 | BrWhite | `#ffffff` | `#ffffff` |
## 3. The Axioms (Immutable Rules)
1. **If it's not important, it does not glow.** Reserve high brightness/saturation for active states.
2. **Red is the Predator.** Red (`#ff0044`) is the color of **Active Intent**. It marks the Hunter (Cursor), the Territory (Current Directory), the Target (Selection), and the Threat (Critical Error). It signals "Live Fire." If it's Red, it is either you or a problem you need to kill.
3. **Text turns Black on Red.** When the background is `#ff0044`, the text must be `#050505` (Neon) or `#0a0a0a` (Aeon) for contrast. This is non-negotiable.
4. **Cyan is Informational.** Never use Cyan for errors or destruction.
5. **Purple is Sacred.** Reserved for special modes, root access, or exceptional states.
6. **Bright = Escalation.** Use bright ANSI variants (8-15) only when a state is elevated or active. Use **Bright Red** (`color9`) for errors to distinguish them from the cursor/path.
7. **No Random Accents.** If a color has no semantic reason to be there, remove it.
## 4. Repository Map
/
├── GEMINI.md # This file. Source of Truth.
├── src/ # Raw DNA
│ ├── neon.yaml # Apex Neon definitions
│ └── aeon.yaml # Apex Aeon definitions
├── templates/ # Jinja2 templates for build targets
│ ├── nvim/
│ ├── zed/
│ ├── zsh/
│ ├── kitty/
│ ├── gemini/
│ ├── gtk4/
│ ├── hyprland/
│ ├── fuzzel/
│ ├── waybar/
│ ├── zathura/
│ ├── btop/
│ ├── swaync/
│ └── alacritty/
└── dist/ # Compiled theme files (gitignore this)
"State over Decoration." If a color has no signal purpose, remove it. See the
spec docs above for the full rule system, value tables, and rationale.
+5 -63
View File
@@ -96,27 +96,7 @@ All generated theme files can be found in the `dist/` directory after running `u
---
## 6. Gemini CLI
**Files:**
- `dist/gemini/apex-neon.json`
- `dist/gemini/apex-aeon.json`
**Installation:**
1. Edit your Gemini settings file (usually `~/.config/gemini/settings.json` or via `gemini settings`).
2. Point the `theme` property to the absolute path of the generated file:
```json
{
"ui": {
"theme": "/absolute/path/to/dist/gemini/apex-neon.json"
}
}
```
---
## 7. GTK4 / Libadwaita
## 6. GTK4 / Libadwaita
**Files:**
- `dist/gtk4/gtk.css` (Aggregated: Responsive to System Dark/Light mode)
@@ -133,7 +113,7 @@ All generated theme files can be found in the `dist/` directory after running `u
---
## 8. Hyprland
## 7. Hyprland
**Files:**
- `dist/hyprland/apex-neon-colors.conf`
@@ -152,7 +132,7 @@ All generated theme files can be found in the `dist/` directory after running `u
---
## 9. Fuzzel
## 8. Fuzzel
**Files:**
- `dist/fuzzel/apex-neon-fuzzel.ini`
@@ -167,26 +147,7 @@ All generated theme files can be found in the `dist/` directory after running `u
---
## 10. Waybar
**Files:**
- `dist/waybar/apex-neon-colors.css`
- `dist/waybar/apex-aeon-colors.css`
**Installation:**
1. Copy the desired file to your Waybar config directory:
```bash
cp dist/waybar/apex-neon-colors.css ~/.config/waybar/colors.css
```
2. Import it in your main `style.css`:
```css
@import "colors.css";
```
3. Use the variables in your CSS (e.g., `background-color: @background;`, `color: @foreground;`, `border-color: @accent;`).
---
## 11. Zathura
## 9. Zathura
**Files:**
- `dist/zathura/apex-neon-zathurarc`
@@ -205,7 +166,7 @@ All generated theme files can be found in the `dist/` directory after running `u
---
## 12. Btop
## 10. Btop
**Files:**
- `dist/btop/apex-neon.theme`
@@ -218,22 +179,3 @@ All generated theme files can be found in the `dist/` directory after running `u
cp dist/btop/*.theme ~/.config/btop/themes/
```
2. Select the theme within Btop settings (ESC -> Options -> Color theme).
---
## 13. SwayNC
**Files:**
- `dist/swaync/apex-neon-style.css`
- `dist/swaync/apex-aeon-style.css`
**Installation:**
1. Copy the desired file to your SwayNC config directory:
```bash
mkdir -p ~/.config/swaync
cp dist/swaync/apex-neon-style.css ~/.config/swaync/style.css
```
2. Reload SwayNC:
```bash
swaync-client -rs
```
+24 -8
View File
@@ -16,24 +16,24 @@ The factory currently generates native themes for:
- **Zed** (JSON extension)
- **Alacritty** (TOML)
- **Kitty** (Conf)
- **Ghostty** (Theme)
- **Zsh** (Theme with Radar/AAR)
- **Gemini CLI** (JSON)
- **GTK4 / Libadwaita** (CSS)
- **Hyprland** (Conf)
- **Fuzzel** (INI)
- **Waybar** (CSS variables)
- **Zathura** (Config)
- **Btop** (Theme)
- **SwayNC** (CSS)
## The Apex DNA
Apex is built on a unified semantic discipline where every color has a specific role:
- **Red is the Predator**: Reserved for active intent, the cursor, current location, and critical errors. It signals "Live Fire."
- **Cyan is Informational**: Used for technical data, links, and neutral highlights.
- **Red is Danger**: Reserved for errors, destructive actions, and the active window border. It never enters a code buffer.
- **Violet is Attention**: The cursor, search matches, matched pairs, and selection — the "you are here" channel. It never enters a code buffer.
- **Cyan is Informational**: Used for links, technical data, info state, and function calls.
- **Blue is Kinds**: Types, structures, and structural accents — a real channel, distinct from cyan.
- **Green is Values**: Strings, numbers, constants, and success.
- **Purple is Sacred**: Reserved for root access, special modes, or exceptional system states.
- **Contrast is King**: Non-negotiable rules for readability (e.g., Black text on Red backgrounds).
## Development & Building
@@ -52,14 +52,30 @@ uv run build.py
Artifacts are output to the `dist/` directory, organized by application.
## Releases
Per-app releases are automated via `scripts/release.sh`. The script only bumps
app versions when relevant files changed since the last `<app>-vX.Y.Z` tag,
then rebuilds, creates per-app tarballs, and publishes Gitea releases.
Example:
```bash
./scripts/release.sh 1.0.2 --notes-dir release-notes
```
Notes:
- Use `release-notes/<app>.md` or `release-notes/common.md` for release notes.
- Requires a working `tea` login and push access to the repo.
## Project Structure
- `src/`: Source YAML definitions containing the "DNA" of the themes.
- `templates/`: Jinja2 templates for each supported application.
- `dist/`: Compiled theme files ready for deployment.
- `GEMINI.md`: AI Context & Source of Truth.
- `GEMINI.md`: Slim pointer to the canonical color specs.
- `apex-neon.md` / `apex-aeon.md`: Detailed specifications.
## Authors
- **S0wlz (Owlibou)**
- **S0wlz (Owlibou)**
+301 -60
View File
@@ -1,98 +1,339 @@
# Apex Aeon — Light Theme Specification
Apex Aeon is the daylight translation of Apex Neon: the same semantic discipline, but on a bright canvas. Color still signals **state**, not decoration. The theme is clinical, high-clarity, and intentionally restrained.
Apex Aeon is the **light sibling** of Apex Neon. Same rule system, recomputed for a
bright field. It is not an inversion of Neon's hexes — glow is a dark-theme
mechanism and does not survive on white. Aeon keeps the **grammar** and recomputes
the **values**.
> **Thesis.** The daylight hunt. Where Neon is a glowing HUD on deep black, Aeon is
> tracks in snow — the field is bright, the signal is **ink, not glow**. Figure goes
> *dark* because the ground went *light*. Red = danger, pink = attention; both
> still reserved, still absent from the syntax, still the strongest signals on screen.
---
## 1. Core Colors (DNA)
## 0. Relationship to Neon — the consistency contract
Aeon is a **sibling**, not a mirror. The rules are invariant; ergonomics drive the
values. "Consistent" means *system-consistent*, not *hex-consistent*.
### Invariant across Neon ↔ Aeon (never diverges)
- **Semantic spine** — red = danger, pink = attention, purple = sacred/root
(always form-coded), cyan = info, blue = kinds, green = values/success,
amber = warning.
- **Reserved-hue rule** — red + pink + amber + purple are never static syntax
tokens. Interaction state (pink cursor/search/selection) renders in the buffer
but marks *where you are*, not *what the code is*. The 16-color ANSI floor (§9)
is exempt.
- **Role → family syntax map** — kinds / actions / values / connective / navigation.
- **Figure/ground principle** — one bright/dark figure, one dim field (poles inverted).
- **Saturation budget** — neon/ink is signal; body is near-neutral.
- **Cool tint** — both backgrounds sit slightly cool.
### v2.1 revisions (2026-06-12 audit)
Tracks Neon's v2.1 (see its §0.1): attention moved violet → **pink** (`focus.*`
recomputed, darker = hotter); **purple = sacred** kept its own channel and ANSI
color5 no longer collides with the cursor hex; full WCAG AA pass — punctuation
(was 3.4:1 *and* quieter than comments — the "lifted" direction hadn't been
inverted), escape (same direction bug), warning/diff-change, and the whole deep
accent band (info/success/constant/builtin sat at 4.04.1:1) now clear 4.5:1 on
Paper *and* on the active-line Surface; bright bank deepened in step to keep the
escalation gap legible.
### Sibling-licensed to differ
- **Exact hexes** — recomputed; glow values do not port to light.
- **The carrier channel** — Neon distinguishes roles by *hue + brightness*; Aeon by
*hue + texture* (weight, italic, fill-vs-outline). See §2.
- **One green divergence** (at most) — see §7 / open calibrations.
---
## 1. Why this is not an inversion
- **Neon glow = high-luminance saturated color on near-zero-luminance black.** Put
`#00ff99` or `#ffb700` on white and the luminance contrast collapses — they
vibrate and vanish. The glow *is* the dark background.
- **The signal band inverts and compresses.** On dark, signal pops by going *bright*
with the full luminance ceiling as headroom. On light, signal must go *dark* — and
dark saturated hues **converge** toward muddy ink, where hue discrimination is
weakest. The 5-hue pre-attentive system is under **more** pressure on light, not
less. This is the central design problem; texture (§2) is the answer.
---
## 2. The second channel is structural
Neon used weight/italic as garnish; hue did the work. Aeon **co-carries meaning by
form**, because the compressed dark band cannot separate five hues alone.
- **Fill vs outline** becomes a semantic axis Neon never needed.
- **Figure/ground inverts cleanly:** dark ink figure on a **pale-tint** ground
(snow-track logic) — e.g. error = deep-red text on `#fbe4e9`; search = deep-pink
on `#f9daf1`.
- **Diagnostics lean on texture:** underline / undercurl weight + pale field, because
a dark squiggle on white is quieter than a neon one on black. Texture compensates
for the lost luminance punch.
This is Aeon using light's strength (ink legibility, texture clarity) rather than
faking dark's strength (glow).
---
## 3. Semantic Spine — five hues, zero overlap
Identical to Neon. Note the **survivor asymmetry**: red, pink, and purple are
already low-luminance-capable, so they port with the most identity intact;
cyan/green/amber move hardest. Aeon therefore reads **red-and-pink-forward**
embraced, not fought, because danger and attention *should* be the loudest, and
info *should* be calmer.
| Hue | Meaning | Syntax token? | Survives inversion |
| --- | --- | --- | --- |
| **Red** | Danger — error, critical, destructive | ❌ never | best (already dark) |
| **Pink** | Attention — cursor, search, matched pairs | ❌ never | best |
| **Purple** | Sacred — root (always form-coded) | ❌ never | best |
| **Cyan** | Information / actions | ✅ | moves hard |
| **Blue** | Kinds | ✅ | moderate |
| **Green** | Success / values | ✅ | moves hard (convergence risk) |
| **Amber** | Warning — UI only | ❌ never | moves hard |
---
## 4. Neutrals — the readable 80% (ramp reversed: light → dark)
Background is off-white, **not pure white** (same halation/fatigue logic as Neon's
`#070709`). Faint cool tint mirrors the dark theme.
| Hex | Name | Role |
|---|---|---|
| `#f5f5f5` | Void White | Primary background. The canvas. |
| `#0a0a0a` | Near Black | Primary readable text. Default signal. |
| `#ff0044` | Razor Red | Primary aggressor. Errors, focus, cursor, active borders. |
| `#007a88` | Deep Cyan | Technical accent. Info, links, highlights. |
| --- | --- | --- |
| `#f1f3f7` | Paper | Main background, terminal background |
| `#e7eaf0` | Surface | Inputs, inactive tabs, widgets |
| `#dce0e8` | Panel | Panels, separators, scroll track |
| `#c2c8d4` | Seam | Visible borders, line-highlight background |
| `#c8cdd8` | Stealth | Ignored / suppressed text (sub-threshold **by design**) |
| `#5c6270` | Ghost | Comments, subtitles, muted labels |
| `#16181d` | Ink | Default body text (cool near-black, not pure black) |
| `#000000` | Deep | Extreme emphasis only |
**Rule:** if an element is not important, it does not glow.
**Rule.** Depth comes from contrast, not darkness. Nothing load-bearing sits at
Stealth (its low contrast on Paper is the point).
---
## 2. UI Surfaces & Depth
## 5. Signal Layer — figure / ground (poles inverted)
| Hex | Name | Usage |
|---|---|---|
| `#f5f5f5` | Void White | Main window backgrounds. |
| `#ffffff` | High Surface | Cards/inputs where needed (use sparingly). |
| `#e8e8e8` | Soft Surface | Sub-panels, inactive tabs, grouped regions. |
| `#737373` | Border / Muted | Borders, dividers, secondary labels. |
Recomputed accents — **render-untested**; convergence in the dark band makes these
the riskiest values in the project. Verify hue-separation on a real light buffer.
**Rule:** depth comes from subtle surface stepping, not shadows everywhere.
```
DANGER (red — warm, alarm)
#c8003a Razor Red error figure, destructive, active alarm
#fbe4e9 Ember Field error region background (+ diff-delete background)
#9e0030 Deep Red escalation (DARKER on light — "bright = escalation" inverts)
ATTENTION (pink — hot scanner; underline-shaped; darker = hotter)
#9d1a7e Focus Max cursor — the crosshair (the deepest pink)
#b32b92 Focus Active current search match, matched bracket / pair
#f9daf1 Focus Field other matches, selection background
SACRED (purple — root, exceptional system state)
#6a1fb8 Purple reserved special / root (ANSI color5)
always bold or on a field — never bare hue
INFORMATION
#087193 Electric Cyan info / links
#0a7851 Acid Green success / diff-add
#935d03 Amber warning / diff-change (UI only)
```
**Inversion note.** On Neon, "bright = escalation" meant higher luminance. On light,
signal intensifies by going *darker*, so the escalation red (`#9e0030`) is **darker**
than base danger (`#c8003a`). The rule is preserved; its direction flips.
---
## 3. Interaction States
## 6. Interaction & State
| Hex | Role | Notes |
|---|---|---|
| `#ff0044` | Cursor | Caret in terminals and inputs. |
| `#ff0044` | Selection BG | “Target locked” selection state. |
| `#0a0a0a` | Selection FG | **Hard rule:** text turns Near Black on red. |
| `#ff0044` | Active Border | Focused window/element edge. |
| Element | Color | Form | Notes |
| --- | --- | --- | --- |
| Cursor | `#9d1a7e` Focus Max | **underline** | Sits below a search match's bg+fg. |
| Current search match | `#b32b92` Focus Active | fg | The one match you are on. |
| Other matches | `#2e333d` on `#f9daf1` | field | The set; pale pink ground. |
| Selection | `#2e333d` on `#f9daf1` | field | fg preserved. |
| Matched bracket / pair | `#b32b92` | fg | Attention, not syntax. |
| Active line | bg `#e7eaf0` | — | Line **number** in `#9d1a7e` is the crosshair. |
| Active border | `#9d1a7e` Focus Max | edge | Focused window/element — "you are here", same crosshair hue as the cursor. |
| Urgent border | `#c8003a` | edge | A window **demanding** attention (xdg-activation). The only red on a window. |
---
## 4. Functional Semantics
## 7. Syntax — loud, typed by role (ink, not glow)
| Meaning | Hex |
|---|---|
| Success / OK | `#00b377` |
| Warning / Load | `#d18f00` |
| Error / Critical | `#ff0044` |
| Special / Root | `#7a3cff` |
| Info / Link | `#007a88` |
Same role model: `blue = kinds · cyan = actions · green = values · neutral =
connective · bold/bright = navigation`. Loudness now via depth + weight + style.
### Rust reference map
| Token | Hex | Family / weight |
| --- | --- | --- |
| Comment | `#5c6270` italic | neutral |
| Punctuation / delimiter | `#4f5461` | neutral, lifted (lifted = *darker* on light) |
| Operator | `#5c6270` | neutral |
| Variable / param | `#16181d` | Ink body |
| Property / field | `#2e333d` | dim Ink |
| Type / struct / enum / trait | `#2148c0` | **blue — kinds** |
| Storage / modifier (`pub mut async`) | `#1633a0` bold | blue, heavier |
| Attribute (`#[derive]`) | `#2148c0` italic | **blue — declarative** |
| Function def / call | `#0e6e92` bold | **cyan — actions** |
| Bang-macro (`println!`) | `#0e6e92` bold italic | **cyan — action + ceremony** |
| `self` / builtin | `#2c708e` italic | cyan, dim |
| String | `#00734d` | **green — values** |
| Char / escape | `#006641` | green, escalated (deeper on light) |
| Number / bool / const | `#0a7851` | green, cooler |
### Navigation — split static vs dynamic
| Kind | Examples | Color |
| --- | --- | --- |
| **Static control flow** | `if return break continue match`, `\begin \end`, `goto` | `#1633a0` bold deep-blue |
| **Dynamic pairing** | bracket partner, `\begin``\end`, jump target | `#b32b92` pink — **attention** |
**Green double-duty.** On light, value-green (`#00734d`) and success-green
(`#0a7851`) both deepen toward the same olive band and may converge (ΔE 0.03).
Resolution (sibling-legal): **keep both, split by texture** — success = fill/bold,
value = plain. A teal divergence for values was rejected (would collide with
cyan-info in the crowded dark band). Flagged for render test; most likely failure
point.
---
## 5. Terminal ANSI Table (16-Color Engine)
## 8. Diff / Git (pale grounds, ink figures)
Bright colors represent **escalation**, not decoration, even on a light background.
| State | fg | bg |
| --- | --- | --- |
| Add | `#00734d` | `#e2f3ea` |
| Change | `#935d03` | `#f5ecda` |
| Delete | `#c8003a` | `#fbe4e9` ← reused Ember Field |
---
## 9. Terminal ANSI Table (16-color fallback bank)
Truecolor-first; this bank is the floor. **Bright-bank inversion:** on a light theme
the bright variants are *more saturated/deeper*, not lighter — a lighter variant
would lose contrast against Paper. `color0` stays dark (text), `color15` stays light.
### Normal Bank (07)
| Slot | Name | Hex | Meaning |
|---|---|---|---|
| color0 | Black | `#0a0a0a` | Primary text |
| color1 | Red | `#ff0044` | **The Predator** (Cursor/Path) |
| color2 | Green | `#00b377` | Success |
| color3 | Yellow | `#d18f00` | Warning |
| color4 | Blue | `#007a88` | Info / links |
| color5 | Magenta | `#7a3cff` | Special / root |
| color6 | Cyan | `#007a88` | Info (mapped) |
| color7 | White | `#f5f5f5` | Background |
| --- | --- | --- | --- |
| color0 | Black | `#16181d` | Text / ink |
| color1 | Red | `#c8003a` | Danger / error |
| color2 | Green | `#0a7851` | Success |
| color3 | Yellow | `#935d03` | Warning |
| color4 | Blue | `#2148c0` | Kinds / structural |
| color5 | Magenta | `#6a1fb8` | Sacred / root (purple) |
| color6 | Cyan | `#087193` | Info / actions |
| color7 | White | `#c2c8d4` | Light surface ⚠ 1.5:1 as text on Paper — see §11 |
### Bright Bank (815)
| Slot | Name | Hex | Meaning |
|---|---|---|---|
| color8 | BrBlack | `#737373` | Borders / separators / muted |
| color9 | BrRed | `#ff4d6d` | **Alerts** (Distinguishable from Cursor) |
| color10 | BrGreen | `#33d6a6` | Active success / completion |
| color11 | BrYellow | `#ffbf40` | Urgent warning |
| color12 | BrBlue | `#33bccc` | Active info / focus highlight |
| color13 | BrMagenta | `#a680ff` | Elevated special state |
| color14 | BrCyan | `#33bccc` | Active tech signal |
| color15 | BrWhite | `#ffffff` | Maximum highlight (rare) |
| --- | --- | --- | --- |
| color8 | BrBlack | `#5c6270` | Muted / suggestions |
| color9 | BrRed | `#9e0030` | Escalation (darker = hotter on light) |
| color10 | BrGreen | `#006543` | Active success / values |
| color11 | BrYellow | `#7b4e05` | Urgent warning |
| color12 | BrBlue | `#1633a0` | Active flow nav |
| color13 | BrMagenta | `#8d1071` | Elevated attention (pink) |
| color14 | BrCyan | `#005f80` | Active tech signal / functions |
| color15 | BrWhite | `#f1f3f7` | Lightest highlight |
Background `#f1f3f7`, foreground `#16181d` set separately from the bank.
---
## 6. Usage Guidelines
## 10. Cross-Language Role Mapping
- **Red is the Agent**. It marks where the user *is* (Prompt/Path) and what the user *controls* (Cursor/Selection).
- **Distinguish the Thread.** Since the Prompt is now Red, actual Errors must use **Bright Red** (`#ff4d6d`) or explicit symbols.
- **Deep Cyan is informational.** Never use it for errors or destructive actions.
- **Purple is sacred.** Only for special modes, root, or exceptional states.
- **Bright = escalation.** If nothing changed, dont use a bright variant.
- **Surfaces stay simple.** Let state and typography carry hierarchy.
- **No random accents.** If a color has no semantic reason, its wrong.
Identical to Neon — color follows **roles**, which are language-invariant. The §10
table and per-language judgment calls from `apex-neon.md` apply unchanged; only
the hex values differ (§7). Family-skew, role-ambiguous constructs (`$VAR`,
f-strings, pipelines), and identity pronouns (`self`/`this`/`$`) are resolved the
same way: weight/style tweak onto an existing family, never a new hue.
Apex Aeon is not “light mode.” Its the same system under harsher lighting.
---
## 11. Accessibility Contract
All ratios below are computed (WCAG 2.1 relative luminance), not estimated.
- **Floor: every text-rendering role (syntax, ANSI fg, diff fg) clears WCAG AA
4.5:1 on Paper** — verified by script as of v2.1. Accent roles additionally
clear 4.5:1 on the active-line Surface `#e7eaf0`.
- **Body text** `#16181d` on Paper `#f1f3f7` — 16.0:1, the resting surface.
- **Comments** `#5c6270` on Paper — 5.5:1, AA normal text.
- **Stealth** `#c8cdd8` on Paper — 1.4:1, sub-threshold **by design**; ignored text
only.
- **ANSI color7 exception.** `#c2c8d4` is a *surface* slot (1.5:1 as text on
Paper). TUIs that hardcode white-as-text are unreadable on every light theme;
Aeon follows the standard light-scheme convention and accepts this floor
limitation rather than darkening "white".
- **No ink-on-ink.** Dark signal colors never sit on dark fills; signal always on a
pale or neutral field.
- **Color-vision deficiency (known limitations, simulated at full severity):**
- Deuteranopia compresses red↔green (ΔE 0.05) and red↔amber (ΔE 0.06) in the
dark band — far tighter than on Neon. Danger/success/warning therefore never
rely on hue alone here: error = undercurl + Ember Field, diffs = tinted
grounds, escalation = weight.
- The pink↔blue split survives protanopia (ΔE 0.035→0.10 better than v2.0
violet); cyan↔green converges under tritanopia (rare; accepted).
- **Dark-band separation is the real risk.** Verify the deep accents are mutually
distinguishable on the actual display — this is where light fights you.
Measured worst pair: info `#087193` vs function `#0e6e92`, ΔE 0.009 — effectively
one cyan. Accepted *deliberately*: info is UI-only, function is buffer-only; the
contexts never sit side by side. If they ever do in some app, split by weight.
---
## 12. Rules with Teeth
- **Red is danger. Pink is attention.** Neither is ever a syntax token.
- **The focused window is pink, not red.** Red on a window means *urgent*, never merely *focused*.
- **Purple is sacred.** Root and exceptional system states only — always bold or
on a field, never bare hue.
- **Cyan is information and action. Amber is warning — UI only.**
- **Signal is ink, not glow.** Pop comes from depth + texture, not brightness.
- **Form co-carries meaning.** Weight/italic/fill are semantic, not decorative.
- **Escalation goes darker** (the inverted "bright = escalation") — and is carried
by weight or field, never by the depth step alone.
- **One color, one meaning.** No accent without a reason.
- **Scarcity is the weapon.** A signal carries information only when rare.
Apex Aeon is the same predator at noon. The hunt does not change with the light.
---
## Open calibrations (verify on a real light buffer)
1. **Dark-band hue separation.** The deep accents (`#c8003a #9d1a7e #087193
#0a7851 #935d03`) crowd more than their Neon cousins. Confirm mutual
distinguishability before trusting the role-typing — the single highest risk.
2. **Green convergence.** Value-green `#00734d` vs success-green `#0a7851` may read
as one olive on light (ΔE 0.03 measured). If they collapse, push success toward
fill/bold weight harder, or accept the texture-only split.
3. **Cyan family crowding.** Functions `#0e6e92`, `self` `#2c708e`, and info
`#087193` all occupy a narrow deep-cyan band; info≈function is measured at
ΔE 0.009 and accepted as context-split (§11). Verify `self` vs function
separate; widen by weight if not.
4. **Paper warmth.** `#f1f3f7` is cool-neutral. If it reads clinical/cold under warm
ambient light, a hair of warmth (`#f4f2ee`) is sibling-legal — but breaks the
cool-tint invariant, so decide deliberately.
5. **Pink family on light (new in v2.1).** Attention went pink and *darker = hotter*:
cursor `#9d1a7e` is the deepest. Verify (a) cursor vs current-match read as one
family with clear hierarchy, (b) pale pink Focus Field `#f9daf1` vs Ember Field
`#fbe4e9` stay distinguishable (ΔE 0.031 — same magnitude as the old violet
field, but now hue-adjacent), (c) pink vs danger-red separation (ΔE 0.135,
tighter than Neon's 0.17).
+300 -56
View File
@@ -1,99 +1,343 @@
# Apex Neon — Dark Theme Specification
Apex Neon is a high-contrast dark theme built for terminals, editors, and system UI. Color exists to signal **state**, not to decorate space.
Apex Neon is a high-contrast dark theme for terminals, editors, and system UI.
It is a **rule system**, not a palette. Color carries **meaning**, not decoration.
> **Thesis.** A cold neon HUD on deep black. Hue carries meaning, sparsely.
> **Red = danger. Pink = attention.** Both are absent from the syntax itself, so
> they always strike. The forest (syntax) is loud and typed by grammatical role so
> the hunter navigates fast — but the predator and the crosshair stay the only red
> and pink things in it.
---
## 1. Core Colors (DNA)
## 0. What changed from v1
| v1 problem | v2 fix |
| --- | --- |
| **Red overloaded** — meant *self/cursor* **and** *danger* simultaneously | Hue split: **red = danger only**; attention got its own reserved hue (cursor/search/pairs) |
| `color4 ≡ color6` and `color12 ≡ color14` (cyan/blue collision) | Blue split into a real channel (`#2e6bff` / `#5b8cff`) |
| Comments double-defined (Stealth **and** Muted) | Comments = Ghost; Stealth = *ignored* text only |
| Backwards bright-red (`#ff8899` softer than base — "escalation" read calmer) | `#ff3b3b` — hotter and truer red |
| No diff/git colors | Figure/ground diff tints added |
| No syntax model | Role-typed syntax across all languages |
| `#050505` near-pure black (halation, crushed surfaces) | `#070709` — deep, cool-tinted, halation-safe |
### v2.1 revisions (2026-06-12 audit)
| v2.0 problem | v2.1 fix |
| --- | --- |
| Attention-violet and sacred-violet were the **same hue split by lightness** — exactly what Principle 3 forbids (303° vs 306° OKLCH, ΔE 0.083) | **Attention moved to pink** (~340°); **purple keeps sacred/root** and is always form-coded (bold or fielded, never bare hue) |
| Sacred `#9d00ff` was the least readable color in the theme (3.72:1) | `#a550f9` — 4.90:1 |
| Blue `#2e6bff` sat just under AA (4.47:1) | `#3c75f9` — 4.89:1 |
| Keystone rule was falsifiable as written (cursor/search/selection render *inside* the buffer; ANSI floor puts color1/3/5 into TUI output) | Reworded: reserved hues never appear as **static syntax tokens** (see §1) |
| Side effect of the pink swap: protanopia collapsed attention-violet into syntax-blue (ΔE 0.007 simulated) | Pink vs blue survives protan simulation at ΔE 0.106 (see §11) |
---
## 1. Semantic Spine — reserved vs syntax hues, zero overlap
The core invariant. Every color does exactly one job.
| Hue | Meaning | Syntax token? | Temp |
| --- | --- | --- | --- |
| **Red** | Danger — error, critical, destructive | ❌ never | warm |
| **Pink** | Attention — cursor, search, matched pairs | ❌ never | warm |
| **Purple** | Sacred — root, exceptional system state (always form-coded) | ❌ never | cool-warm |
| **Cyan** | Information / **actions** (functions, bang-macros) | ✅ | cool |
| **Blue** | **Kinds** (types, storage, attributes) | ✅ | cool |
| **Green** | Success / **values** (strings, numbers) | ✅ | cool-warm |
| **Amber** | Warning — UI only | ❌ never | warm |
**Keystone rule.** Red, pink, amber, and purple are never **static syntax tokens**
no keyword, type, string, or operator ever wears them. Interaction state (the pink
cursor, search, selection) does render *inside* the buffer, but it marks *where you
are*, not *what the code is*, and it moves with you. Because the resting syntax
contains none of the reserved hues, an error (red), the crosshair (pink), or a
warning (amber) pops against the field — however loud the syntax is.
*Exemption:* the 16-color ANSI floor (§9). Apps that emit raw `color1/3/5` will put
reserved hues into their output; that floor is a fallback, not a rule violation.
---
## 2. Operating Principles
1. **Saturation budget.** Neon is for *signal*. Body text is near-neutral.
Striking comes from restraint against contrast — not coverage.
2. **Figure / ground.** A bright hue marks the *one* thing (cursor, error text);
a dim hue field marks the *set* (search hits, error region, diff block).
Applied to both red and pink.
3. **Hue rotates for severity.** `info → warn → error → critical` rotates hue;
it never ramps lightness within a single hue (pre-attentively unreadable).
*Carve-out:* the bright ANSI bank (§9) is a within-hue escalation ramp by
construction. It is a fallback channel — escalation that must be *read* is
carried by weight or field, never by the brightness step alone.
4. **Loudness is allocated by grammatical role, not sprayed.** Code can be vivid;
uniform saturation is noise. Each grammatical class owns one hue family.
5. **Pre-attentive bandwidth is ~57 categories.** The limit is the feature:
scarcity is what makes a signal pop. The display is not the constraint; the
visual cortex is.
---
## 3. Neutrals — the readable 80%
Anchored at `#070709`. Faint cool bias (B ≳ R) reinforces the cold scan and makes
warm signals pop by complementary contrast.
| Hex | Name | Role |
|---|---|---|
| `#050505` | Void Black | Absolute background. The canvas. |
| `#ff0044` | Razor Red | Primary aggressor. Errors, focus, cursor, active borders. |
| `#00eaff` | Electric Cyan | Technical accent. Info, links, highlights. |
| `#ededed` | Stark White | Default readable text. |
| --- | --- | --- |
| `#070709` | Void | Main background, terminal background |
| `#101218` | Hull | Inputs, inactive tabs, widgets |
| `#181b22` | Plating | Panels, separators, scroll track |
| `#262a34` | Seam | Visible borders, line-highlight background |
| `#383d49` | Stealth | Ignored / suppressed text (sub-threshold **by design**) |
| `#8b909c` | Ghost | Comments, subtitles, muted labels |
| `#e6e8ec` | Stark | Default body text (not pure white — fatigue / halation) |
| `#ffffff` | Flare | Extreme highlight only |
**Rule:** if a UI element is not important, it does not glow.
**Rule.** Depth comes from contrast, not brightness. Nothing load-bearing ever
sits at Stealth.
---
## 2. UI Surfaces & Depth
## 4. Signal Layer — figure / ground
| Hex | Name | Usage |
|---|---|---|
| `#050505` | Void Deep | Main window backgrounds, terminal background. |
| `#141414` | Dark Surface | Inputs, inactive tabs, widget backgrounds. |
| `#262626` | Light Surface | Separators, scroll tracks, inactive borders. |
| `#404040` | Stealth | Comments, ignored text, suppressed hints. |
| `#737373` | Muted Text | Comments, subtitles, inactive labels. |
```
DANGER (red — warm, alarm)
#ff0044 Razor Red error figure, destructive action, active alarm
#1f0a12 Ember Field error region background (+ diff-delete background)
#ff3b3b Bright Red ANSI color9 / escalation
**Rule:** depth comes from contrast, not brightness.
ATTENTION (pink — hot scanner; underline-shaped)
#f783d4 Focus Max cursor — the crosshair (the single hottest mark)
#e42ab9 Focus Active current search match, matched bracket / pair
#340c29 Focus Field other search matches, selection background
SACRED (purple — root, exceptional system state)
#a550f9 Purple reserved special / root (ANSI color5)
always bold or on a field — never bare hue
INFORMATION
#00eaff Electric Cyan info / links
#00ff99 Acid Green success / diff-add
#ffb700 Amber warning / diff-change (UI only — never in buffer)
```
---
## 3. Interaction States
## 5. Interaction & State
| Hex | Role | Notes |
|---|---|---|
| `#ff0044` | Cursor | Caret in terminals and inputs (Beam shape). |
| `#ff0044` | Selection BG | “Target locked” selection state. |
| `#050505` | Selection FG | **Hard rule:** text turns black on red. |
| `#ff0044` | Active Border | Focused window/element edge. |
| Element | Color | Form | Notes |
| --- | --- | --- | --- |
| Cursor | `#f783d4` Focus Max | **underline** | Sits *below* a search match's bg+fg — all three stay visible. |
| Current search match | `#e42ab9` Focus Active | fg | The one match you are on. |
| Other search matches | `#e6e8ec` on `#340c29` | field | The set; dim pink ground. |
| Selection | `#e6e8ec` on `#340c29` | field | "Region scanned." fg preserved (no black-on-red). |
| Matched bracket / pair | `#e42ab9` | fg | **Attention**, not syntax — same act as search. |
| Active line | neutral bg `#101218` | — | Line **number** in `#f783d4` is the crosshair; near-zero red coverage. |
| Active border | `#f783d4` Focus Max | edge | Focused window/element — "you are here", the same crosshair hue as the cursor. |
| Urgent border | `#ff0044` | edge | A window **demanding** attention (xdg-activation). The only red on a window — the predator. |
**Known overlap.** Cursor underline (pink, straight) and error undercurl (red,
wavy) share the bottom-line layer. On an error token under the cursor they coexist
— distinguishable by shape *and* hue, but visually busy. Accepted, not a surprise.
Pink sits closer to red than the old violet did (ΔE 0.17 vs 0.30) — shape and
luminance carry more of the split; verify on a real buffer (open calibration 4).
---
## 4. Functional Semantics
## 6. Severity Ladder — rotates hue, never a red ramp
| Meaning | Hex |
|---|---|
| Success / OK | `#00ff99` |
| Warning / Load | `#ffb700` |
| Error / Critical | `#ff0044` |
| Special / Root | `#9d00ff` |
| Info / Link | `#00eaff` |
```
info warn error critical
#00eaff → #ffb700 → #ff0044 → figure on ground: #ff0044 on #1f0a12
cyan amber red the whole region lights red
```
Critical does not get a new hue (rotating past red collides with amber or pink).
It escalates via **field** — error-red figure on a dark-red ground. This is the
*only* place red becomes a background. Maximum alarm, maximally rare.
---
## 5. Terminal ANSI Table (16-Color Engine)
## 7. Syntax — loud, typed by grammatical role
Bright colors represent **escalation**, not decoration.
**Model:** `blue = kinds · cyan = actions · green = values · neutral = connective
tissue · bold/bright = navigation`. Roles are language-invariant (see §10).
### Rust reference map
| Token | Hex | Family / weight |
| --- | --- | --- |
| Comment | `#8b909c` italic | neutral — not a target |
| Punctuation / delimiter | `#aab0bc` | neutral, lifted |
| Operator | `#c2c8d4` | neutral |
| Variable / param | `#e6e8ec` | Stark body (everywhere = calm) |
| Property / field | `#cdd4e3` | dim Stark |
| Type / struct / enum / trait | `#7db4ff` | **blue — kinds** |
| Storage / modifier (`pub mut async`) | `#3c75f9` bold | blue, heavier |
| Attribute (`#[derive]`) | `#3c75f9` italic | **blue — declarative** |
| Function def / call | `#5af3ff` bold | **cyan — actions** |
| Bang-macro (`println!`) | `#5af3ff` bold italic | **cyan — action + ceremony** |
| `self` / builtin | `#8fd6ff` italic | cyan, dim |
| String | `#2bffb2` | **green — values** |
| Char / escape | `#7dffd0` | green, brighter |
| Number / bool / const | `#37dba0` | green, cooler |
### Navigation — split static vs dynamic
| Kind | Examples | Color |
| --- | --- | --- |
| **Static control flow** | `if return break continue match`, `\begin \end`, `goto` | `#5b8cff` bold bright-blue — trail markers |
| **Dynamic pairing** | bracket-under-cursor partner, `\begin``\end`, jump target | `#e42ab9` pink — this is **attention**, not syntax |
---
## 8. Diff / Git
Dark tinted **grounds**, neon **figures**. Never full-saturation blocks.
| State | fg | bg |
| --- | --- | --- |
| Add | `#00ff99` | `#0a1f16` |
| Change | `#ffb700` | `#1f1a0a` |
| Delete | `#ff0044` | `#1f0a12` ← reused Ember Field |
---
## 9. Terminal ANSI Table (16-color fallback bank)
Truecolor-first: design in exact hex everywhere the app emits 24-bit. This bank is
the floor for anything emitting raw 16-color codes. Skip the 256-color cube entirely.
### Normal Bank (07)
| Slot | Name | Hex | Meaning |
|---|---|---|---|
| color0 | Black | `#050505` | Background |
| color1 | Red | `#ff0044` | **The Predator** (Cursor/Path/Self) |
| --- | --- | --- | --- |
| color0 | Black | `#070709` | Background |
| color1 | Red | `#ff0044` | Danger / error / destructive |
| color2 | Green | `#00ff99` | Success |
| color3 | Yellow | `#ffb700` | Warning |
| color4 | Blue | `#00eaff` | Info / links |
| color5 | Magenta | `#9d00ff` | Special / root |
| color6 | Cyan | `#00eaff` | Info (mapped) |
| color7 | White | `#ededed` | Default text |
| color4 | Blue | `#3c75f9` | Kinds / structural (real blue) |
| color5 | Magenta | `#a550f9` | Sacred / root (purple) |
| color6 | Cyan | `#00eaff` | Info / actions |
| color7 | White | `#e6e8ec` | Default text |
### Bright Bank (815)
| Slot | Name | Hex | Meaning |
|---|---|---|---|
| color8 | BrBlack | `#737373` | Muted text / suggestions |
| color9 | BrRed | `#ff8899` | **Alerts** (Distinguishable from Cursor) |
| color10 | BrGreen | `#2bffb2` | Active success / completion |
| --- | --- | --- | --- |
| color8 | BrBlack | `#383d49` | Muted / suggestions |
| color9 | BrRed | `#ff3b3b` | Escalation / alert (hotter than base) |
| color10 | BrGreen | `#2bffb2` | Active success / values |
| color11 | BrYellow | `#ffd24d` | Urgent warning |
| color12 | BrBlue | `#5af3ff` | Active info / focus highlight |
| color13 | BrMagenta | `#c84dff` | Elevated special state |
| color14 | BrCyan | `#5af3ff` | Active tech signal |
| color12 | BrBlue | `#5b8cff` | Active flow nav / focus highlight |
| color13 | BrMagenta | `#fe41d0` | Elevated attention state (pink) |
| color14 | BrCyan | `#5af3ff` | Active tech signal / functions |
| color15 | BrWhite | `#ffffff` | Extreme highlight only |
**Multiplexer warning.** tmux silently downsamples truecolor to the 256-cube if
misconfigured — which collapses the figure/ground tints. Assert passthrough:
```tmux
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*:RGB"
```
```bash
# verify the chain carries 24-bit (run inside and outside tmux — should not shift)
printf '\033[38;2;255;0;68mtruecolor\033[0m\n'
```
Neovim additionally requires `vim.o.termguicolors = true`.
---
## 6. Usage Guidelines
## 10. Cross-Language Role Mapping
- **Red is the Agent**. It marks where the user *is* (Prompt/Path) and what the user *controls* (Cursor/Selection).
- **Distinguish the Threat.** Since the Prompt is now Red, actual Errors must use **Bright Red** (`#ff8899`) or explicit symbols to distinguish them from the environment.
- **Cyan is informational.** Never use it for errors or destructive actions.
- **Purple is sacred.** Only for special modes, root, or exceptional states.
- **Bright = escalation.** If nothing changed, dont use a bright variant.
Color follows **roles**, not tokens. Surface syntax differs across languages; the
deep grammar does not. One palette, every grammar — more languages means more
*query mappings to maintain*, not more colors.
| Role → hue | Rust | Python | TypeScript | Go | Java | Bash/sh | Nushell |
| --- | --- | --- | --- | --- | --- | --- | --- |
| **Kinds** (blue) | `struct trait` | class, hints | `interface type` | `struct interface` | `class enum` | — (untyped) | `int record table` |
| **Actions** (cyan) | `fn` / `m!` | `def`, methods | fn, arrow, methods | `func` | methods | commands, `echo` | `def`, commands |
| **Values** (green) | str / num | str / f-str / num | str / template / num | literals | literals | quoted str | literals / records |
| **Declarative** (blue italic) | `#[attr]` | `@decorator` | `@Decorator` | struct tags | `@Override` | — | — |
| **Flow nav** (bold blue) | `if match` | `if for try` | `if switch` | `if for go defer` | `if switch` | `if/fi for/done case` | `if/else for` |
| **Connective** (neutral) | `+ \| ::` | `+ .` | `+ . =>` | `+ . :=` | `+ .` | `\| && $ >` | `\| $ ;` |
### Per-language judgment calls (handle with weight/style, never a new hue)
- **Family skew.** TypeScript is type-saturated (blue-heavy); bash is
command-saturated (cyan-heavy). Resolve with brightness/weight tiers *inside* the
family (e.g. dim built-in types, bright user types).
- **Role-ambiguous constructs.** Bash `$VAR` / `${...}` / `$(...)` expansion,
Python f-strings / TS template literals (green string containing live code),
Nushell pipelines `|` (connective but navigationally load-bearing). Map each onto
an existing family with a weight/style tweak per-language.
- **Identity pronouns.** `self` / `this` / `$` → dim cyan italic everywhere.
---
## 11. Accessibility Contract
All ratios below are computed (WCAG 2.1 relative luminance), not estimated.
- **Floor: every text-rendering role (syntax, ANSI fg, diff fg) clears WCAG AA
4.5:1 on Void** — verified by script as of v2.1.
- **Body text** `#e6e8ec` on Void `#070709` — 16.4:1, well above AAA. The resting
surface.
- **Comments** `#8b909c` on Void — 6.3:1, AA for normal text.
- **Stealth** `#383d49` on Void — 1.9:1, sub-threshold **by design**; ignored text
only, never load-bearing.
- **No neon on neon.** Saturated signal colors are never placed on saturated
backgrounds; signal always sits on a neutral or dim field.
- **Color-vision deficiency (known limitations, simulated at full severity):**
- The pink↔blue split survives protanopia (ΔE 0.106; the v2.0 violet collapsed
to 0.007 — one reason for the pink swap).
- cyan↔green converges under tritanopia (ΔE ≈ 0.03; tritanopia ≈ 0.01 % —
accepted).
- Hue is never the *only* carrier for danger/attention: error = undercurl +
field, cursor = underline, urgent = border. Form survives where hue does not.
- Verify exact ratios per render target; near-black + neon halation is
panel-dependent and only confirmable on the actual display.
---
## 12. Rules with Teeth
- **Red is danger. Pink is attention.** Neither is ever a syntax token.
- **The focused window is pink, not red.** Red on a window means *urgent* (a window
demanding you), never merely *focused*. Cursor, active line, and active border are one pink family.
- **Purple is sacred.** Root and exceptional system states only — and never bare
hue: always bold or on a field, so the rarest signal is also the most readable.
- **Cyan is information and action.** Never errors, never destructive.
- **Amber is warning — UI only.** It never enters a buffer.
- **Bright = escalation — carried by weight or field.** If nothing changed, don't
use a bright variant; if something did, the brightness step alone isn't the signal.
- **Backgrounds stay dark.** Text and state carry the signal.
- **No random accents.** If a color has no semantic reason, its wrong.
- **One color, one meaning.** If a color has no semantic reason, it's wrong.
- **Loud is earned by role.** Vivid syntax is fine; uniform saturation is noise.
- **Scarcity is the weapon.** A signal only carries information when it is rare.
Apex Neon is not a palette. Its a rule system with teeth.
Apex Neon is not a palette. It's a rule system with teeth.
---
## Open calibrations (verify on a real buffer — not on paper)
1. **Cyan budget in dense code.** Functions, bang-macros, `self`, and info/links
all live in cyan. A function-heavy file may read as a cyan wash. If so, drop
functions to mid-cyan and reserve bright `#5af3ff` for sparse use.
2. ~~**Blue vs cyan separability.**~~ **Resolved (measured, 2026-06-12):** blue
family sits at 256265° OKLCH, cyan family at 203235° — ~60° apart, keyword↔type
ΔE 0.116. Splits cleanly on paper; render check passed implicitly since v2.0.
3. **Green double duty.** Values (`#2bffb2`) and success (`#00ff99`) are close
(ΔE 0.033). Low collision risk (success rarely renders inside code), but noted.
4. **Pink vs red proximity (new in v2.1).** Attention pink `#e42ab9` sits ΔE 0.17
from danger red `#ff0044` (the old violet sat at 0.30). Luminance and form carry
the rest of the split — confirm a search match next to an error token reads as
two signals, not one.
+3
View File
@@ -0,0 +1,3 @@
# Release artifacts (tarballs)
releases/
*.tar.gz
+64
View File
@@ -0,0 +1,64 @@
# APEX AEON — Alacritty theme (colors only)
# v2 spine: red = danger · pink = attention · cyan = info
[colors.primary]
background = "#f1f3f7"
foreground = "#16181d"
dim_foreground = "#5c6270"
bright_foreground = "#f1f3f7"
[colors.cursor]
text = "#f1f3f7"
cursor = "#9d1a7e"
[colors.vi_mode_cursor]
text = "#f1f3f7"
cursor = "#b32b92"
[colors.selection]
text = "#16181d"
background = "#f9daf1"
[colors.search.matches]
foreground = "#16181d"
background = "#f9daf1"
[colors.search.focused_match]
foreground = "#f1f3f7"
background = "#b32b92"
[colors.hints.start]
foreground = "#f1f3f7"
background = "#935d03"
[colors.hints.end]
foreground = "#f1f3f7"
background = "#087193"
[colors.line_indicator]
foreground = "None"
background = "None"
[colors.footer_bar]
foreground = "#16181d"
background = "#e7eaf0"
[colors.normal]
black = "#16181d"
red = "#c8003a"
green = "#0a7851"
yellow = "#935d03"
blue = "#2148c0"
magenta = "#6a1fb8"
cyan = "#087193"
white = "#c2c8d4"
[colors.bright]
black = "#5c6270"
red = "#9e0030"
green = "#006543"
yellow = "#7b4e05"
blue = "#1633a0"
magenta = "#8d1071"
cyan = "#005f80"
white = "#f1f3f7"
+64
View File
@@ -0,0 +1,64 @@
# APEX NEON — Alacritty theme (colors only)
# v2 spine: red = danger · pink = attention · cyan = info
[colors.primary]
background = "#070709"
foreground = "#e6e8ec"
dim_foreground = "#8b909c"
bright_foreground = "#ffffff"
[colors.cursor]
text = "#070709"
cursor = "#f783d4"
[colors.vi_mode_cursor]
text = "#070709"
cursor = "#e42ab9"
[colors.selection]
text = "#e6e8ec"
background = "#340c29"
[colors.search.matches]
foreground = "#e6e8ec"
background = "#340c29"
[colors.search.focused_match]
foreground = "#070709"
background = "#e42ab9"
[colors.hints.start]
foreground = "#070709"
background = "#ffb700"
[colors.hints.end]
foreground = "#070709"
background = "#00eaff"
[colors.line_indicator]
foreground = "None"
background = "None"
[colors.footer_bar]
foreground = "#e6e8ec"
background = "#101218"
[colors.normal]
black = "#070709"
red = "#ff0044"
green = "#00ff99"
yellow = "#ffb700"
blue = "#3c75f9"
magenta = "#a550f9"
cyan = "#00eaff"
white = "#e6e8ec"
[colors.bright]
black = "#383d49"
red = "#ff3b3b"
green = "#2bffb2"
yellow = "#ffd24d"
blue = "#5b8cff"
magenta = "#fe41d0"
cyan = "#5af3ff"
white = "#ffffff"
+91
View File
@@ -0,0 +1,91 @@
# Apex Aeon — Btop Theme
# v2 spine: red = danger · pink = attention · cyan = info
# Main background, empty for terminal default, black for dark themes
theme[main_bg]="#f1f3f7"
# Main text color
theme[main_fg]="#16181d"
# Title color for boxes
theme[title]="#16181d"
# Highlight color for keyboard shortcuts — pink attention accent
theme[hi_fg]="#9d1a7e"
# Background color of selected item in processes box — pink field
theme[selected_bg]="#f9daf1"
# Foreground color of selected item in processes box
theme[selected_fg]="#16181d"
# Color of inactive/disabled text
theme[inactive_fg]="#5c6270"
# Color of text appearing on top of graphs, i.e. usage percentage
theme[graph_text]="#5c6270"
# Background color of the percentage meters
theme[meter_bg]="#e7eaf0"
# Misc colors for processes box including mini cpu graphs, used memory percentage, and entries filter
theme[proc_misc]="#087193"
# Cpu box outline color
theme[cpu_box]="#c2c8d4"
# Memory box outline color
theme[mem_box]="#c2c8d4"
# Net box outline color
theme[net_box]="#c2c8d4"
# Processes box outline color
theme[proc_box]="#c2c8d4"
# Box divider line and small boxes line color
theme[div_line]="#c2c8d4"
# Heat gradients follow the severity ladder (spec §6): info -> warning -> danger.
# Purple is sacred (root only) and never a gradient step.
# Temperature graph colors
theme[temp_start]="#087193"
theme[temp_mid]="#935d03"
theme[temp_end]="#c8003a"
# CPU graph colors
theme[cpu_start]="#087193"
theme[cpu_mid]="#935d03"
theme[cpu_end]="#c8003a"
# Mem graph colors
theme[free_start]="#0a7851"
theme[free_mid]="#935d03"
theme[free_end]="#c8003a"
theme[cached_start]="#087193"
theme[cached_mid]="#935d03"
theme[cached_end]="#c8003a"
theme[available_start]="#0a7851"
theme[available_mid]="#935d03"
theme[available_end]="#c8003a"
theme[used_start]="#087193"
theme[used_mid]="#935d03"
theme[used_end]="#c8003a"
# Download graph colors
theme[download_start]="#087193"
theme[download_mid]="#935d03"
theme[download_end]="#c8003a"
# Upload graph colors
theme[upload_start]="#087193"
theme[upload_mid]="#935d03"
theme[upload_end]="#c8003a"
# Process path color
theme[process_start]="#087193"
theme[process_mid]="#935d03"
theme[process_end]="#c8003a"
+91
View File
@@ -0,0 +1,91 @@
# Apex Neon — Btop Theme
# v2 spine: red = danger · pink = attention · cyan = info
# Main background, empty for terminal default, black for dark themes
theme[main_bg]="#070709"
# Main text color
theme[main_fg]="#e6e8ec"
# Title color for boxes
theme[title]="#e6e8ec"
# Highlight color for keyboard shortcuts — pink attention accent
theme[hi_fg]="#f783d4"
# Background color of selected item in processes box — pink field
theme[selected_bg]="#340c29"
# Foreground color of selected item in processes box
theme[selected_fg]="#e6e8ec"
# Color of inactive/disabled text
theme[inactive_fg]="#8b909c"
# Color of text appearing on top of graphs, i.e. usage percentage
theme[graph_text]="#8b909c"
# Background color of the percentage meters
theme[meter_bg]="#101218"
# Misc colors for processes box including mini cpu graphs, used memory percentage, and entries filter
theme[proc_misc]="#00eaff"
# Cpu box outline color
theme[cpu_box]="#262a34"
# Memory box outline color
theme[mem_box]="#262a34"
# Net box outline color
theme[net_box]="#262a34"
# Processes box outline color
theme[proc_box]="#262a34"
# Box divider line and small boxes line color
theme[div_line]="#262a34"
# Heat gradients follow the severity ladder (spec §6): info -> warning -> danger.
# Purple is sacred (root only) and never a gradient step.
# Temperature graph colors
theme[temp_start]="#00eaff"
theme[temp_mid]="#ffb700"
theme[temp_end]="#ff0044"
# CPU graph colors
theme[cpu_start]="#00eaff"
theme[cpu_mid]="#ffb700"
theme[cpu_end]="#ff0044"
# Mem graph colors
theme[free_start]="#00ff99"
theme[free_mid]="#ffb700"
theme[free_end]="#ff0044"
theme[cached_start]="#00eaff"
theme[cached_mid]="#ffb700"
theme[cached_end]="#ff0044"
theme[available_start]="#00ff99"
theme[available_mid]="#ffb700"
theme[available_end]="#ff0044"
theme[used_start]="#00eaff"
theme[used_mid]="#ffb700"
theme[used_end]="#ff0044"
# Download graph colors
theme[download_start]="#00eaff"
theme[download_mid]="#ffb700"
theme[download_end]="#ff0044"
# Upload graph colors
theme[upload_start]="#00eaff"
theme[upload_mid]="#ffb700"
theme[upload_end]="#ff0044"
# Process path color
theme[process_start]="#00eaff"
theme[process_mid]="#ffb700"
theme[process_end]="#ff0044"
+15
View File
@@ -0,0 +1,15 @@
# Apex Aeon — Fuzzel Theme
# v2 spine: red = danger · pink = attention · cyan = info
[colors]
background=f1f3f7ff
text=16181dff
match=087193ff
selection=f9daf1ff
selection-text=16181dff
selection-match=087193ff
border=087193ff
[border]
width=2
radius=0
+15
View File
@@ -0,0 +1,15 @@
# Apex Neon — Fuzzel Theme
# v2 spine: red = danger · pink = attention · cyan = info
[colors]
background=070709ff
text=e6e8ecff
match=00eaffff
selection=340c29ff
selection-text=e6e8ecff
selection-match=00eaffff
border=00eaffff
[border]
width=2
radius=0
+30
View File
@@ -0,0 +1,30 @@
# Apex Aeon - Ghostty theme
# v2 spine: red = danger · pink = attention · cyan = info
background = #f1f3f7
foreground = #16181d
# Cursor: the crosshair — pink
cursor-color = #9d1a7e
cursor-text = #f1f3f7
# Selection: pink field (attention, not danger)
selection-background = #f9daf1
selection-foreground = #16181d
palette = 0=#16181d
palette = 1=#c8003a
palette = 2=#0a7851
palette = 3=#935d03
palette = 4=#2148c0
palette = 5=#6a1fb8
palette = 6=#087193
palette = 7=#c2c8d4
palette = 8=#5c6270
palette = 9=#9e0030
palette = 10=#006543
palette = 11=#7b4e05
palette = 12=#1633a0
palette = 13=#8d1071
palette = 14=#005f80
palette = 15=#f1f3f7
+30
View File
@@ -0,0 +1,30 @@
# Apex Neon - Ghostty theme
# v2 spine: red = danger · pink = attention · cyan = info
background = #070709
foreground = #e6e8ec
# Cursor: the crosshair — pink
cursor-color = #f783d4
cursor-text = #070709
# Selection: pink field (attention, not danger)
selection-background = #340c29
selection-foreground = #e6e8ec
palette = 0=#070709
palette = 1=#ff0044
palette = 2=#00ff99
palette = 3=#ffb700
palette = 4=#3c75f9
palette = 5=#a550f9
palette = 6=#00eaff
palette = 7=#e6e8ec
palette = 8=#383d49
palette = 9=#ff3b3b
palette = 10=#2bffb2
palette = 11=#ffd24d
palette = 12=#5b8cff
palette = 13=#fe41d0
palette = 14=#5af3ff
palette = 15=#ffffff
+131
View File
@@ -0,0 +1,131 @@
/* Apex Theme System — GTK4 / Libadwaita */
/* v2 spine: red = danger · pink = attention · cyan = info */
/* Scheme: Apex Neon (dark) */
@media (prefers-color-scheme: dark) {
:root {
/* Core Surfaces */
@define-color window_bg_color #070709;
@define-color window_fg_color #e6e8ec;
@define-color view_bg_color #070709;
@define-color view_fg_color #e6e8ec;
@define-color headerbar_bg_color #101218;
@define-color headerbar_fg_color #e6e8ec;
@define-color headerbar_border_color #262a34;
@define-color headerbar_backdrop_color @window_bg_color;
@define-color headerbar_shade_color rgba(0, 0, 0, 0.07);
@define-color popover_bg_color #101218;
@define-color popover_fg_color #e6e8ec;
@define-color card_bg_color #101218;
@define-color card_fg_color #e6e8ec;
@define-color card_shade_color rgba(0, 0, 0, 0.07);
@define-color dialog_bg_color #101218;
@define-color dialog_fg_color #e6e8ec;
/* Accents */
@define-color accent_color #00eaff;
@define-color accent_bg_color #00eaff;
@define-color accent_fg_color #070709;
/* Destructive = danger red (spec §5,6) */
@define-color destructive_color #ff0044;
@define-color destructive_bg_color #ff0044;
@define-color destructive_fg_color #070709;
@define-color success_color #00ff99;
@define-color success_bg_color #00ff99;
@define-color success_fg_color #070709;
@define-color warning_color #ffb700;
@define-color warning_bg_color #ffb700;
@define-color warning_fg_color #070709;
@define-color error_color #ff0044;
@define-color error_bg_color #ff0044;
@define-color error_fg_color #070709;
/* UI Elements */
@define-color borders #262a34;
@define-color sidebar_bg_color #101218;
@define-color sidebar_fg_color #e6e8ec;
@define-color sidebar_backdrop_color @window_bg_color;
@define-color sidebar_shade_color rgba(0, 0, 0, 0.07);
/* Custom Apex Palette */
@define-color apex_focus #f783d4;
@define-color apex_void #070709;
@define-color apex_subtle #383d49;
}
}
/* Scheme: Apex Aeon (light) */
@media (prefers-color-scheme: light) {
:root {
/* Core Surfaces */
@define-color window_bg_color #f1f3f7;
@define-color window_fg_color #16181d;
@define-color view_bg_color #f1f3f7;
@define-color view_fg_color #16181d;
@define-color headerbar_bg_color #e7eaf0;
@define-color headerbar_fg_color #16181d;
@define-color headerbar_border_color #c2c8d4;
@define-color headerbar_backdrop_color @window_bg_color;
@define-color headerbar_shade_color rgba(0, 0, 0, 0.07);
@define-color popover_bg_color #e7eaf0;
@define-color popover_fg_color #16181d;
@define-color card_bg_color #e7eaf0;
@define-color card_fg_color #16181d;
@define-color card_shade_color rgba(0, 0, 0, 0.07);
@define-color dialog_bg_color #e7eaf0;
@define-color dialog_fg_color #16181d;
/* Accents */
@define-color accent_color #087193;
@define-color accent_bg_color #087193;
@define-color accent_fg_color #f1f3f7;
/* Destructive = danger red (spec §5,6) */
@define-color destructive_color #c8003a;
@define-color destructive_bg_color #c8003a;
@define-color destructive_fg_color #f1f3f7;
@define-color success_color #0a7851;
@define-color success_bg_color #0a7851;
@define-color success_fg_color #f1f3f7;
@define-color warning_color #935d03;
@define-color warning_bg_color #935d03;
@define-color warning_fg_color #f1f3f7;
@define-color error_color #c8003a;
@define-color error_bg_color #c8003a;
@define-color error_fg_color #f1f3f7;
/* UI Elements */
@define-color borders #c2c8d4;
@define-color sidebar_bg_color #e7eaf0;
@define-color sidebar_fg_color #16181d;
@define-color sidebar_backdrop_color @window_bg_color;
@define-color sidebar_shade_color rgba(0, 0, 0, 0.07);
/* Custom Apex Palette */
@define-color apex_focus #9d1a7e;
@define-color apex_void #f1f3f7;
@define-color apex_subtle #c8cdd8;
}
}
+99
View File
@@ -0,0 +1,99 @@
#############################
### APEX AEON THEME ###
#############################
# v2 spine: red = danger · violet = attention · cyan = info
# Backgrounds — the readable ground
$base = rgb(f1f3f7)
$baseAlpha = f1f3f7
$surface = rgb(e7eaf0)
$surfaceAlpha = e7eaf0
$overlay = rgb(c2c8d4)
$overlayAlpha = c2c8d4
$muted = rgb(c8cdd8)
$mutedAlpha = c8cdd8
$subtle = rgb(c8cdd8)
$subtleAlpha = c8cdd8
# Text
$text = rgb(16181d)
$textAlpha = 16181d
# Accents
# Danger red — urgent window, alerts, destructive (spec §5)
$love = rgb(c8003a)
$loveAlpha = c8003a
# Warning amber
$gold = rgb(a86b00)
$goldAlpha = a86b00
# Success green
$pine = rgb(00875a)
$pineAlpha = 00875a
# Info cyan
$foam = rgb(0080a6)
$foamAlpha = 0080a6
# Special / root violet
$iris = rgb(6a1fb8)
$irisAlpha = 6a1fb8
# Attention violet — "you are here" (active window / active tab / cursor)
$focus = rgb(7c2fd6)
$focusAlpha = 7c2fd6
# Real blue — structural / kinds (window groups)
$blue = rgb(1633a0)
$blueAlpha = 1633a0
# Escalation red (hotter than base)
$rose = rgb(9e0030)
$roseAlpha = 9e0030
# Highlight variants
$highlight_low = rgb(e7eaf0)
$highlight_lowAlpha = e7eaf0
$highlight_med = rgb(c2c8d4)
$highlight_medAlpha = c2c8d4
$highlight_high = rgb(c8cdd8)
$highlight_highAlpha = c8cdd8
# Theme-specific definitions
$splash_text = rgba($textAlphaee)
$dec_shadow = rgba(000000ee) # Hard shadows
# Border configurations — v2 signal vocabulary
# inactive = dim cyan HUD chrome · active = attention violet · urgent = danger red
# group = structural blue · group-locked = warning amber
$border_active = rgba($focusAlphaff) rgba($irisAlphaff) 45deg
$border_inactive = rgba($foamAlpha66) rgba($surfaceAlpha44) 45deg
# Urgent / demands-attention window (consumed by the compositor's urgent handler)
$border_urgent = rgba($loveAlphaff) rgba($roseAlphaff) 45deg
$border_nogroup_active = rgba($focusAlphaff) rgba($irisAlphaff) 45deg
$border_nogroup_inactive = rgba($foamAlpha66) rgba($surfaceAlpha44) 45deg
$border_group_active = rgba($blueAlphaff) rgba($blueAlphaaa) 45deg
$border_group_inactive = rgba($mutedAlpha66) rgba($surfaceAlpha66) 45deg
$border_grouplocked_active = rgba($goldAlphaff) rgba($goldAlphaaa) 45deg
$border_grouplocked_inactive = rgba($goldAlpha66) rgba($surfaceAlpha66) 45deg
# Group bar configurations
# active tab = info gradient: blue "border" frame + cyan interior (the shown member — info, not attention)
# inactive tabs = dim structural blue · locked = amber (border trick via alpha-dimmed ends)
# (attention violet stays scarce — reserved for the active WINDOW border, not the groupbar)
$groupbar_text = rgba($baseAlphaff)
$groupbar_active = rgba($blueAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($blueAlphaff)
$groupbar_inactive = rgba($blueAlpha99) rgba($blueAlpha44)
$groupbar_grouplocked_active = rgba($goldAlpha88) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlpha88)
$groupbar_grouplocked_inactive = rgba($goldAlpha99) rgba($goldAlpha44)
+99
View File
@@ -0,0 +1,99 @@
#############################
### APEX NEON THEME ###
#############################
# v2 spine: red = danger · violet = attention · cyan = info
# Backgrounds — the readable ground
$base = rgb(070709)
$baseAlpha = 070709
$surface = rgb(101218)
$surfaceAlpha = 101218
$overlay = rgb(262a34)
$overlayAlpha = 262a34
$muted = rgb(383d49)
$mutedAlpha = 383d49
$subtle = rgb(383d49)
$subtleAlpha = 383d49
# Text
$text = rgb(e6e8ec)
$textAlpha = e6e8ec
# Accents
# Danger red — urgent window, alerts, destructive (spec §5)
$love = rgb(ff0044)
$loveAlpha = ff0044
# Warning amber
$gold = rgb(ffb700)
$goldAlpha = ffb700
# Success green
$pine = rgb(00ff99)
$pineAlpha = 00ff99
# Info cyan
$foam = rgb(00eaff)
$foamAlpha = 00eaff
# Special / root violet
$iris = rgb(9d00ff)
$irisAlpha = 9d00ff
# Attention violet — "you are here" (active window / active tab / cursor)
$focus = rgb(d68fff)
$focusAlpha = d68fff
# Real blue — structural / kinds (window groups)
$blue = rgb(5b8cff)
$blueAlpha = 5b8cff
# Escalation red (hotter than base)
$rose = rgb(ff3b3b)
$roseAlpha = ff3b3b
# Highlight variants
$highlight_low = rgb(101218)
$highlight_lowAlpha = 101218
$highlight_med = rgb(262a34)
$highlight_medAlpha = 262a34
$highlight_high = rgb(383d49)
$highlight_highAlpha = 383d49
# Theme-specific definitions
$splash_text = rgba($textAlphaee)
$dec_shadow = rgba(000000ee) # Hard shadows
# Border configurations — v2 signal vocabulary
# inactive = dim cyan HUD chrome · active = attention violet · urgent = danger red
# group = structural blue · group-locked = warning amber
$border_active = rgba($focusAlphaff) rgba($irisAlphaff) 45deg
$border_inactive = rgba($foamAlpha66) rgba($surfaceAlpha44) 45deg
# Urgent / demands-attention window (consumed by the compositor's urgent handler)
$border_urgent = rgba($loveAlphaff) rgba($roseAlphaff) 45deg
$border_nogroup_active = rgba($focusAlphaff) rgba($irisAlphaff) 45deg
$border_nogroup_inactive = rgba($foamAlpha66) rgba($surfaceAlpha44) 45deg
$border_group_active = rgba($blueAlphaff) rgba($blueAlphaaa) 45deg
$border_group_inactive = rgba($mutedAlpha66) rgba($surfaceAlpha66) 45deg
$border_grouplocked_active = rgba($goldAlphaff) rgba($goldAlphaaa) 45deg
$border_grouplocked_inactive = rgba($goldAlpha66) rgba($surfaceAlpha66) 45deg
# Group bar configurations
# active tab = info gradient: blue "border" frame + cyan interior (the shown member — info, not attention)
# inactive tabs = dim structural blue · locked = amber (border trick via alpha-dimmed ends)
# (attention violet stays scarce — reserved for the active WINDOW border, not the groupbar)
$groupbar_text = rgba($baseAlphaff)
$groupbar_active = rgba($blueAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($foamAlphaff) rgba($blueAlphaff)
$groupbar_inactive = rgba($blueAlpha99) rgba($blueAlpha44)
$groupbar_grouplocked_active = rgba($goldAlpha88) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlphaff) rgba($goldAlpha88)
$groupbar_grouplocked_inactive = rgba($goldAlpha99) rgba($goldAlpha44)
+67
View File
@@ -0,0 +1,67 @@
## APEX AEON - KITTY THEME ##
## v2 spine: red = danger · pink = attention · cyan = info
# --- Core ---
foreground #16181d
background #f1f3f7
# Selection: pink field (attention, not danger)
selection_background #f9daf1
selection_foreground #16181d
# Cursor: the crosshair — pink
cursor #9d1a7e
cursor_text_color #f1f3f7
cursor_shape beam
# URLs: informational cyan
url_color #087193
# Borders: focused window = pink attention, red only for urgency (spec §5)
active_border_color #9d1a7e
inactive_border_color #c2c8d4
bell_border_color #c8003a
# Visual bell: hot red
visual_bell_color #9e0030
# Spacing
window_padding_width 4
# --- 16-COLOR ANSI TABLE (Apex Aeon spec §9) ---
# Normal bank (07)
# color0: Black (bg)
color0 #16181d
# color1: Red (danger)
color1 #c8003a
# color2: Green (success)
color2 #0a7851
# color3: Yellow (warning)
color3 #935d03
# color4: Blue (kinds / structural)
color4 #2148c0
# color5: Magenta (sacred / root — purple)
color5 #6a1fb8
# color6: Cyan (info / actions)
color6 #087193
# color7: White (text)
color7 #c2c8d4
# Bright bank (815) — escalation / active states only
# color8: Bright black (muted / separators)
color8 #5c6270
# color9: Bright red (escalation)
color9 #9e0030
# color10: Bright green (active success)
color10 #006543
# color11: Bright yellow (urgent warning)
color11 #7b4e05
# color12: Bright blue (active flow)
color12 #1633a0
# color13: Bright magenta (elevated attention)
color13 #8d1071
# color14: Bright cyan (active tech signal)
color14 #005f80
# color15: Bright white (extreme highlight)
color15 #f1f3f7
+67
View File
@@ -0,0 +1,67 @@
## APEX NEON - KITTY THEME ##
## v2 spine: red = danger · pink = attention · cyan = info
# --- Core ---
foreground #e6e8ec
background #070709
# Selection: pink field (attention, not danger)
selection_background #340c29
selection_foreground #e6e8ec
# Cursor: the crosshair — pink
cursor #f783d4
cursor_text_color #070709
cursor_shape beam
# URLs: informational cyan
url_color #00eaff
# Borders: focused window = pink attention, red only for urgency (spec §5)
active_border_color #f783d4
inactive_border_color #262a34
bell_border_color #ff0044
# Visual bell: hot red
visual_bell_color #ff3b3b
# Spacing
window_padding_width 4
# --- 16-COLOR ANSI TABLE (Apex Neon spec §9) ---
# Normal bank (07)
# color0: Black (bg)
color0 #070709
# color1: Red (danger)
color1 #ff0044
# color2: Green (success)
color2 #00ff99
# color3: Yellow (warning)
color3 #ffb700
# color4: Blue (kinds / structural)
color4 #3c75f9
# color5: Magenta (sacred / root — purple)
color5 #a550f9
# color6: Cyan (info / actions)
color6 #00eaff
# color7: White (text)
color7 #e6e8ec
# Bright bank (815) — escalation / active states only
# color8: Bright black (muted / separators)
color8 #383d49
# color9: Bright red (escalation)
color9 #ff3b3b
# color10: Bright green (active success)
color10 #2bffb2
# color11: Bright yellow (urgent warning)
color11 #ffd24d
# color12: Bright blue (active flow)
color12 #5b8cff
# color13: Bright magenta (elevated attention)
color13 #fe41d0
# color14: Bright cyan (active tech signal)
color14 #5af3ff
# color15: Bright white (extreme highlight)
color15 #ffffff
+70
View File
@@ -0,0 +1,70 @@
# Apex Aeon — Nushell color config
# v2 spine: red = danger · pink = attention · cyan = info
# Usage: add `use /path/to/apex-aeon.nu` to config.nu
export-env {
$env.config.color_config = {
# --- Chrome ---
separator: "#5c6270"
leading_trailing_space_bg: { bg: "#c2c8d4" }
header: { fg: "#2148c0" attr: b }
empty: "#5c6270"
row_index: { fg: "#5c6270" attr: b }
hints: "#c8cdd8"
# --- Primitive types ---
string: { fg: "#00734d" }
int: { fg: "#0a7851" }
float: { fg: "#0a7851" }
bool: { fg: "#0a7851" }
filesize: { fg: "#087193" }
duration: { fg: "#087193" }
datetime: { fg: "#087193" }
range: { fg: "#16181d" }
record: { fg: "#16181d" }
list: { fg: "#16181d" }
block: { fg: "#1633a0" }
nothing: { fg: "#5c6270" }
binary: { fg: "#087193" }
# --- Shapes (REPL syntax highlighting) ---
# The REPL line is a code buffer: amber/pink/red stay out (keystone).
shape_string: { fg: "#00734d" }
shape_string_interpolation: { fg: "#00734d" attr: b }
shape_int: { fg: "#0a7851" }
shape_float: { fg: "#0a7851" }
shape_bool: { fg: "#0a7851" }
shape_datetime: { fg: "#087193" }
shape_binary: { fg: "#087193" }
shape_filepath: { fg: "#087193" }
shape_directory: { fg: "#087193" }
shape_globpattern: { fg: "#087193" }
shape_glob_interpolation: { fg: "#087193" }
shape_nothing: { fg: "#5c6270" }
shape_variable: { fg: "#16181d" }
shape_vardecl: { fg: "#16181d" }
shape_operator: { fg: "#5c6270" }
shape_external: { fg: "#0e6e92" }
shape_externalarg: { fg: "#16181d" }
shape_internalcall: { fg: "#0e6e92" attr: b }
shape_signature: { fg: "#0e6e92" }
shape_flag: { fg: "#2148c0" }
shape_pipe: { fg: "#1633a0" attr: b }
shape_redirection: { fg: "#5c6270" }
shape_and: { fg: "#1633a0" attr: b }
shape_or: { fg: "#1633a0" attr: b }
shape_keyword: { fg: "#1633a0" attr: b }
shape_block: { fg: "#1633a0" }
shape_closure: { fg: "#1633a0" }
shape_list: { fg: "#16181d" }
shape_record: { fg: "#16181d" }
shape_table: { fg: "#16181d" }
shape_range: { fg: "#16181d" }
shape_literal: { fg: "#16181d" }
shape_custom: { fg: "#16181d" }
shape_match_pattern: { fg: "#1633a0" }
shape_matching_brackets: { attr: u }
shape_garbage: { fg: "#c8003a" attr: b }
}
}
+70
View File
@@ -0,0 +1,70 @@
# Apex Neon — Nushell color config
# v2 spine: red = danger · pink = attention · cyan = info
# Usage: add `use /path/to/apex-neon.nu` to config.nu
export-env {
$env.config.color_config = {
# --- Chrome ---
separator: "#8b909c"
leading_trailing_space_bg: { bg: "#262a34" }
header: { fg: "#7db4ff" attr: b }
empty: "#8b909c"
row_index: { fg: "#8b909c" attr: b }
hints: "#383d49"
# --- Primitive types ---
string: { fg: "#2bffb2" }
int: { fg: "#37dba0" }
float: { fg: "#37dba0" }
bool: { fg: "#37dba0" }
filesize: { fg: "#00eaff" }
duration: { fg: "#00eaff" }
datetime: { fg: "#00eaff" }
range: { fg: "#e6e8ec" }
record: { fg: "#e6e8ec" }
list: { fg: "#e6e8ec" }
block: { fg: "#5b8cff" }
nothing: { fg: "#8b909c" }
binary: { fg: "#00eaff" }
# --- Shapes (REPL syntax highlighting) ---
# The REPL line is a code buffer: amber/pink/red stay out (keystone).
shape_string: { fg: "#2bffb2" }
shape_string_interpolation: { fg: "#2bffb2" attr: b }
shape_int: { fg: "#37dba0" }
shape_float: { fg: "#37dba0" }
shape_bool: { fg: "#37dba0" }
shape_datetime: { fg: "#00eaff" }
shape_binary: { fg: "#00eaff" }
shape_filepath: { fg: "#00eaff" }
shape_directory: { fg: "#00eaff" }
shape_globpattern: { fg: "#00eaff" }
shape_glob_interpolation: { fg: "#00eaff" }
shape_nothing: { fg: "#8b909c" }
shape_variable: { fg: "#e6e8ec" }
shape_vardecl: { fg: "#e6e8ec" }
shape_operator: { fg: "#c2c8d4" }
shape_external: { fg: "#5af3ff" }
shape_externalarg: { fg: "#e6e8ec" }
shape_internalcall: { fg: "#5af3ff" attr: b }
shape_signature: { fg: "#5af3ff" }
shape_flag: { fg: "#3c75f9" }
shape_pipe: { fg: "#5b8cff" attr: b }
shape_redirection: { fg: "#c2c8d4" }
shape_and: { fg: "#5b8cff" attr: b }
shape_or: { fg: "#5b8cff" attr: b }
shape_keyword: { fg: "#5b8cff" attr: b }
shape_block: { fg: "#5b8cff" }
shape_closure: { fg: "#5b8cff" }
shape_list: { fg: "#e6e8ec" }
shape_record: { fg: "#e6e8ec" }
shape_table: { fg: "#e6e8ec" }
shape_range: { fg: "#e6e8ec" }
shape_literal: { fg: "#e6e8ec" }
shape_custom: { fg: "#e6e8ec" }
shape_match_pattern: { fg: "#5b8cff" }
shape_matching_brackets: { attr: u }
shape_garbage: { fg: "#ff0044" attr: b }
}
}
+803
View File
@@ -0,0 +1,803 @@
-- Apex Aeon: Standalone Theme Engine
-- Philosophy: Signal over decoration. Red = danger. Pink = attention.
-- Neither red nor pink is ever a static syntax token (spec §1, §12).
local M = {}
M.palette = {
-- NEUTRALS — the readable field --------------------------------------------
void = "#f1f3f7", -- Background (also: ink on a bright accent fill)
panel = "#e7eaf0", -- Dark surface (statusline, floats, cursorline)
border = "#c2c8d4", -- Borders, separators
stealth = "#c8cdd8", -- Ignored text only (sub-threshold by design)
dim = "#5c6270", -- Comments, muted labels (ghost)
text = "#16181d", -- Body text (stark / ink)
punct = "#4f5461", -- Punctuation / delimiters (lifted neutral)
op = "#5c6270", -- Operators (neutral)
prop = "#2e333d", -- Fields / properties (dim body)
-- ATTENTION (pink) — cursor, search, matched pairs. NEVER syntax. ----------
focus = "#9d1a7e", -- Cursor — the crosshair (hottest mark)
focus_active = "#b32b92", -- Current match, matched bracket / pair
focus_field = "#f9daf1", -- Search-set / selection background
-- DANGER (red) — error, destructive, alarm. NEVER syntax. ------------------
danger = "#c8003a", -- Error figure, destructive, urgent border
danger_field = "#fbe4e9", -- Error region / delete background
danger_hot = "#9e0030", -- Escalation
-- CODE HUES (buffer-safe) --------------------------------------------------
info = "#087193", -- Cyan — info / links
action = "#0e6e92", -- Cyan — functions / methods
builtin = "#2c708e", -- Cyan, dim — self / builtin
kind = "#2148c0", -- Blue — types / kinds
storage = "#1633a0", -- Blue, heavy — storage / modifier / attribute
flow = "#1633a0", -- Bright-blue — control-flow navigation
value = "#00734d", -- Green — strings / values
escape = "#006641", -- Green, bright — char / escape
const = "#0a7851", -- Green, cool — numbers / const
ok = "#0a7851", -- Green — success state
warn = "#935d03", -- Amber — warning (UI only)
special = "#6a1fb8", -- Purple — sacred / root only (always form-coded)
-- DIFF grounds -------------------------------------------------------------
diff_add = "#e2f3ea",
diff_chg = "#f5ecda",
diff_del = "#fbe4e9",
-- ON-ACCENT INK ------------------------------------------------------------
ink = "#16181d", -- fg on a dim pink field (search / selection)
}
function M.load()
vim.cmd "hi clear"
if vim.fn.exists "syntax_on" then vim.cmd "syntax reset" end
vim.o.background = "light"
vim.g.colors_name = "apex-aeon"
-- Optional transparency: set g:apex_blend or g:apex_transparent to opt in.
local blend = vim.g.apex_blend
if type(blend) == "number" then
vim.o.winblend = blend
vim.o.pumblend = blend
elseif vim.g.apex_transparent == true then
vim.o.winblend = 20
vim.o.pumblend = 20
end
local p = M.palette
local groups = {
-- CANVAS & UI -----------------------------------------------------------
Normal = { fg = p.text, bg = p.void },
NormalNC = { fg = p.dim, bg = p.void }, -- Non-focused windows
SignColumn = { bg = p.void },
FoldColumn = { fg = p.stealth, bg = p.void },
VertSplit = { fg = p.border }, -- Deprecated in nvim 0.10, but good fallback
WinSeparator = { fg = p.border },
EndOfBuffer = { fg = p.void }, -- Hide tildes
NormalFloat = { fg = p.text, bg = p.panel },
FloatBorder = { fg = p.border, bg = p.panel },
MsgArea = { fg = p.text, bg = p.void },
WinBar = { fg = p.text, bg = p.panel },
WinBarNC = { fg = p.dim, bg = p.panel },
-- CURSOR & NAVIGATION ("Attention" — pink) ------------------------------
Cursor = { fg = p.void, bg = p.focus }, -- Pink crosshair
TermCursor = { fg = p.void, bg = p.focus },
CursorLine = { bg = p.panel },
CursorColumn = { bg = p.panel },
ColorColumn = { bg = p.panel },
CursorLineNr = { fg = p.focus, bold = true }, -- Pink line number (you are here)
LineNr = { fg = p.stealth }, -- Other lines fade out
-- SELECTION & SEARCH ("Region scanned" — pink field) --------------------
Visual = { fg = p.ink, bg = p.focus_field }, -- Dim pink field, fg preserved
VisualNOS = { fg = p.ink, bg = p.focus_field },
Search = { fg = p.ink, bg = p.focus_field }, -- Other matches: the set
IncSearch = { fg = p.void, bg = p.focus_active }, -- Acquiring
CurSearch = { fg = p.void, bg = p.focus_active, bold = true }, -- The one you are on
-- STATUS & MESSAGES -----------------------------------------------------
StatusLine = { fg = p.text, bg = p.panel },
StatusLineNC = { fg = p.dim, bg = p.void },
WildMenu = { fg = p.void, bg = p.focus_active },
Pmenu = { fg = p.text, bg = p.panel },
PmenuSel = { fg = p.void, bg = p.focus, bold = true }, -- Pink menu selection
PmenuKind = { fg = p.dim, bg = p.panel },
PmenuKindSel = { fg = p.void, bg = p.focus, bold = true },
PmenuExtra = { fg = p.dim, bg = p.panel },
PmenuExtraSel = { fg = p.void, bg = p.focus, bold = true },
PmenuMatch = { fg = p.info, bg = p.panel, bold = true },
PmenuMatchSel = { fg = p.void, bg = p.focus, bold = true },
PmenuSbar = { bg = p.panel },
PmenuThumb = { bg = p.stealth },
ErrorMsg = { fg = p.danger },
WarningMsg = { fg = p.warn },
MoreMsg = { fg = p.info },
ModeMsg = { fg = p.text },
TabLine = { fg = p.dim, bg = p.panel },
TabLineSel = { fg = p.text, bg = p.void, bold = true },
TabLineFill = { fg = p.panel, bg = p.panel },
QuickFixLine = { fg = p.text, bg = p.panel, bold = true },
-- SYNTAX: typed by grammatical role (spec §7) ---------------------------
-- blue = kinds · cyan = actions · green = values · neutral = connective
Comment = { fg = p.dim, italic = true }, -- Ghost — not a target
Constant = { fg = p.const }, -- Green (cool) — const values
String = { fg = p.value }, -- Green — strings
Character = { fg = p.value },
Number = { fg = p.const },
Boolean = { fg = p.const },
Float = { fg = p.const },
Identifier = { fg = p.text }, -- Variables (calm body)
Property = { fg = p.prop }, -- Fields / properties (dim body)
Function = { fg = p.action }, -- Cyan — actions
Builtin = { fg = p.builtin, italic = true }, -- Cyan dim — self / builtin
Statement = { fg = p.flow, bold = true }, -- Bright-blue — control flow
Conditional = { fg = p.flow, bold = true },
Repeat = { fg = p.flow, bold = true },
Label = { fg = p.flow },
Operator = { fg = p.op }, -- Neutral
Keyword = { fg = p.storage }, -- Blue — storage / modifier
Exception = { fg = p.flow, bold = true }, -- Control flow (NOT danger — never red in code)
PreProc = { fg = p.action }, -- Cyan — preprocessor / macro ceremony
Include = { fg = p.storage }, -- Blue — declarative (use / import)
Define = { fg = p.action },
Macro = { fg = p.action, italic = true }, -- Cyan — bang-macros (action + ceremony)
PreCondit = { fg = p.action },
Type = { fg = p.kind }, -- Blue — kinds
StorageClass = { fg = p.storage, bold = true }, -- Blue heavy
Structure = { fg = p.kind },
Typedef = { fg = p.kind },
Attribute = { fg = p.storage, italic = true }, -- Blue declarative — #[derive], decorators
Special = { fg = p.escape }, -- Green — special tokens (escapes-adjacent)
SpecialChar = { fg = p.escape }, -- Green bright — string escapes / regex
Tag = { fg = p.kind }, -- Blue — structural HTML/XML tags
Delimiter = { fg = p.punct }, -- Neutral, lifted
Debug = { fg = p.special, bold = true }, -- Sacred purple: always form-coded
Underlined = { fg = p.info, underline = true },
Ignore = { fg = p.stealth },
Error = { fg = p.danger },
Todo = { fg = p.void, bg = p.warn, bold = true },
Title = { fg = p.info, bold = true },
MatchParen = { fg = p.focus_active, bold = true }, -- Attention — matched pair (pink)
Whitespace = { fg = p.border },
NonText = { fg = p.border },
SpecialKey = { fg = p.border },
SpellBad = { sp = p.danger, undercurl = true },
SpellCap = { sp = p.warn, undercurl = true },
SpellRare = { sp = p.info, undercurl = true },
SpellLocal = { sp = p.dim, undercurl = true },
LspReferenceText = { bg = p.panel },
LspReferenceRead = { bg = p.panel },
LspReferenceWrite = { bg = p.panel, bold = true },
LspSignatureActiveParameter = { fg = p.void, bg = p.info, bold = true },
LspInlayHint = { fg = p.dim, bg = p.panel },
LspCodeLens = { fg = p.dim },
LspCodeLensSeparator = { fg = p.stealth },
LspInfoBorder = { fg = p.border, bg = p.panel },
LspInfoTitle = { fg = p.dim, bg = p.panel },
-- DIAGNOSTICS -----------------------------------------------------------
DiagnosticError = { fg = p.danger },
DiagnosticWarn = { fg = p.warn },
DiagnosticInfo = { fg = p.info },
DiagnosticHint = { fg = p.dim },
DiagnosticOk = { fg = p.ok },
DiagnosticDeprecated = { fg = p.dim, strikethrough = true },
DiagnosticUnnecessary = { fg = p.dim },
DiagnosticUnderlineError = { undercurl = true, sp = p.danger },
DiagnosticUnderlineWarn = { undercurl = true, sp = p.warn },
DiagnosticUnderlineInfo = { undercurl = true, sp = p.info },
DiagnosticUnderlineHint = { undercurl = true, sp = p.dim },
DiagnosticUnderlineOk = { undercurl = true, sp = p.ok },
DiagnosticVirtualTextError = { fg = p.danger, bg = p.panel },
DiagnosticVirtualTextWarn = { fg = p.warn, bg = p.panel },
DiagnosticVirtualTextInfo = { fg = p.info, bg = p.panel },
DiagnosticVirtualTextHint = { fg = p.dim, bg = p.panel },
DiagnosticVirtualTextOk = { fg = p.ok, bg = p.panel },
DiagnosticVirtualLinesError = { fg = p.danger, bg = p.panel },
DiagnosticVirtualLinesWarn = { fg = p.warn, bg = p.panel },
DiagnosticVirtualLinesInfo = { fg = p.info, bg = p.panel },
DiagnosticVirtualLinesHint = { fg = p.dim, bg = p.panel },
DiagnosticVirtualLinesOk = { fg = p.ok, bg = p.panel },
DiagnosticSignError = { fg = p.danger, bg = p.void },
DiagnosticSignWarn = { fg = p.warn, bg = p.void },
DiagnosticSignInfo = { fg = p.info, bg = p.void },
DiagnosticSignHint = { fg = p.dim, bg = p.void },
DiagnosticSignOk = { fg = p.ok, bg = p.void },
DiagnosticFloatingError = { fg = p.danger, bg = p.panel },
DiagnosticFloatingWarn = { fg = p.warn, bg = p.panel },
DiagnosticFloatingInfo = { fg = p.info, bg = p.panel },
DiagnosticFloatingHint = { fg = p.dim, bg = p.panel },
DiagnosticFloatingOk = { fg = p.ok, bg = p.panel },
ApexMarkupStrong = { bold = true },
ApexMarkupItalic = { italic = true },
ApexMarkupLink = { fg = p.info, underline = true },
-- DIFF (figure / ground — spec §8) --------------------------------------
DiffAdd = { fg = p.ok, bg = p.diff_add },
DiffChange = { fg = p.warn, bg = p.diff_chg },
DiffDelete = { fg = p.danger, bg = p.diff_del },
DiffText = { fg = p.void, bg = p.warn, bold = true },
-- PLUGINS: TELESCOPE ("The HUD") ----------------------------------------
TelescopeNormal = { bg = p.void },
TelescopeBorder = { fg = p.border, bg = p.void },
TelescopePromptNormal = { fg = p.text, bg = p.void },
TelescopePromptBorder = { fg = p.info, bg = p.void }, -- Cyan input border
TelescopePromptTitle = { fg = p.void, bg = p.info }, -- Cyan label
TelescopePreviewTitle = { fg = p.void, bg = p.ok }, -- Green label
TelescopeResultsTitle = { fg = p.dim, bg = p.panel },
TelescopeSelection = { fg = p.text, bg = p.focus_field, bold = true }, -- Pink field
TelescopeMatching = { fg = p.info, bold = true },
-- PLUGINS: NEO-TREE -----------------------------------------------------
NeoTreeNormal = { bg = p.void },
NeoTreeNormalNC = { bg = p.void },
NeoTreeVertSplit = { fg = p.panel, bg = p.void },
NeoTreeWinSeparator = { fg = p.panel, bg = p.void }, -- Fade out tree border
NeoTreeRootName = { fg = p.focus, bold = true }, -- Tree root = location (pink attention)
NeoTreeGitAdded = { fg = p.ok },
NeoTreeGitConflict = { fg = p.warn },
NeoTreeGitDeleted = { fg = p.danger },
NeoTreeGitModified = { fg = p.info },
-- PLUGINS: GITSIGNS -----------------------------------------------------
GitSignsAdd = { fg = p.ok, bg = p.void },
GitSignsChange = { fg = p.warn, bg = p.void },
GitSignsDelete = { fg = p.danger, bg = p.void },
-- PLUGINS: CMP (Completion) ---------------------------------------------
CmpItemAbbrDeprecated = { fg = p.dim, strikethrough = true },
CmpItemAbbrMatch = { fg = p.info, bold = true },
CmpItemAbbrMatchFuzzy = { fg = p.info, bold = true },
CmpItemKindFunction = { fg = p.action },
CmpItemKindMethod = { fg = p.action },
CmpItemKindKeyword = { fg = p.flow },
CmpItemKindVariable = { fg = p.text },
-- PLUGINS: BLINK.CMP (Completion) ----------------------------------------
BlinkCmpMenu = { fg = p.text, bg = p.panel },
BlinkCmpMenuBorder = { fg = p.border, bg = p.panel },
BlinkCmpMenuSelection = { fg = p.void, bg = p.focus, bold = true },
BlinkCmpScrollBarThumb = { bg = p.stealth },
BlinkCmpScrollBarGutter = { bg = p.panel },
BlinkCmpLabel = { fg = p.text },
BlinkCmpLabelDeprecated = { fg = p.dim, strikethrough = true },
BlinkCmpLabelMatch = { fg = p.info, bold = true },
BlinkCmpKindText = { fg = p.text },
BlinkCmpKindMethod = { fg = p.action },
BlinkCmpKindFunction = { fg = p.action },
BlinkCmpKindConstructor = { fg = p.kind },
BlinkCmpKindField = { fg = p.prop },
BlinkCmpKindVariable = { fg = p.text },
BlinkCmpKindClass = { fg = p.kind },
BlinkCmpKindInterface = { fg = p.kind },
BlinkCmpKindModule = { fg = p.kind },
BlinkCmpKindProperty = { fg = p.prop },
BlinkCmpKindUnit = { fg = p.const },
BlinkCmpKindValue = { fg = p.const },
BlinkCmpKindEnum = { fg = p.kind },
BlinkCmpKindKeyword = { fg = p.flow },
BlinkCmpKindSnippet = { fg = p.value },
BlinkCmpKindColor = { fg = p.info },
BlinkCmpKindFile = { fg = p.text },
BlinkCmpKindReference = { fg = p.info },
BlinkCmpKindFolder = { fg = p.info },
BlinkCmpKindEnumMember = { fg = p.const },
BlinkCmpKindConstant = { fg = p.const },
BlinkCmpKindStruct = { fg = p.kind },
BlinkCmpKindEvent = { fg = p.kind },
BlinkCmpKindOperator = { fg = p.op },
BlinkCmpKindTypeParameter = { fg = p.kind },
BlinkCmpGhostText = { fg = p.stealth, italic = true },
BlinkCmpDoc = { fg = p.text, bg = p.panel },
BlinkCmpDocBorder = { fg = p.border, bg = p.panel },
BlinkCmpDocSeparator = { fg = p.border, bg = p.panel },
BlinkCmpDocCursorLine = { bg = p.border },
BlinkCmpSignatureHelp = { fg = p.text, bg = p.panel },
BlinkCmpSignatureHelpBorder = { fg = p.border, bg = p.panel },
BlinkCmpSignatureHelpActiveParameter = { fg = p.void, bg = p.info, bold = true },
BlinkCmpSource = { fg = p.dim },
-- PLUGINS: BUFFERLINE -----------------------------------------------------
BufferLineBackground = { fg = p.dim, bg = p.panel },
BufferLineFill = { bg = p.panel },
BufferLineBuffer = { fg = p.dim, bg = p.panel },
BufferLineBufferSelected = { fg = p.text, bg = p.void, bold = true },
BufferLineBufferVisible = { fg = p.dim, bg = p.panel },
BufferLineTab = { fg = p.dim, bg = p.panel },
BufferLineTabSelected = { fg = p.text, bg = p.void, bold = true },
BufferLineTabClose = { fg = p.dim, bg = p.panel },
BufferLineModified = { fg = p.info, bg = p.panel },
BufferLineModifiedSelected = { fg = p.info, bg = p.void },
BufferLineModifiedVisible = { fg = p.info, bg = p.panel },
BufferLineSeparator = { fg = p.border, bg = p.panel },
BufferLineSeparatorSelected = { fg = p.border, bg = p.void },
BufferLineSeparatorVisible = { fg = p.border, bg = p.panel },
BufferLineIndicatorSelected = { fg = p.focus, bg = p.void }, -- Active = pink
BufferLineCloseButton = { fg = p.dim, bg = p.panel },
BufferLineCloseButtonSelected = { fg = p.focus, bg = p.void },
BufferLineCloseButtonVisible = { fg = p.dim, bg = p.panel },
BufferLineDiagnostic = { fg = p.dim, bg = p.panel },
BufferLineDiagnosticSelected = { fg = p.dim, bg = p.void },
BufferLineError = { fg = p.danger, bg = p.panel },
BufferLineErrorSelected = { fg = p.danger, bg = p.void, bold = true },
BufferLineWarning = { fg = p.warn, bg = p.panel },
BufferLineWarningSelected = { fg = p.warn, bg = p.void, bold = true },
BufferLineInfo = { fg = p.info, bg = p.panel },
BufferLineInfoSelected = { fg = p.info, bg = p.void, bold = true },
BufferLineHint = { fg = p.dim, bg = p.panel },
BufferLineHintSelected = { fg = p.dim, bg = p.void, bold = true },
BufferLinePick = { fg = p.focus, bg = p.panel, bold = true },
BufferLinePickSelected = { fg = p.focus, bg = p.void, bold = true },
BufferLinePickVisible = { fg = p.focus, bg = p.panel, bold = true },
-- PLUGINS: WHICH-KEY ------------------------------------------------------
WhichKey = { fg = p.flow, bold = true }, -- The key trigger = navigation
WhichKeySeparator = { fg = p.stealth },
WhichKeyGroup = { fg = p.info },
WhichKeyDesc = { fg = p.text },
WhichKeyFloat = { bg = p.panel },
WhichKeyBorder = { fg = p.border, bg = p.panel },
WhichKeyTitle = { fg = p.void, bg = p.focus, bold = true },
WhichKeyNormal = { fg = p.text, bg = p.panel },
WhichKeyValue = { fg = p.dim },
WhichKeyIcon = { fg = p.action },
WhichKeyIconAzure = { fg = p.kind },
WhichKeyIconGreen = { fg = p.ok },
WhichKeyIconYellow = { fg = p.warn },
WhichKeyIconRed = { fg = p.danger },
WhichKeyIconPurple = { fg = p.special },
WhichKeyIconCyan = { fg = p.info },
-- PLUGINS: TROUBLE --------------------------------------------------------
TroubleNormal = { fg = p.text, bg = p.void },
TroubleNormalNC = { fg = p.dim, bg = p.void },
TroubleText = { fg = p.text },
TroubleCount = { fg = p.void, bg = p.focus_active, bold = true },
TroubleError = { fg = p.danger },
TroubleWarning = { fg = p.warn },
TroubleHint = { fg = p.dim },
TroubleInfo = { fg = p.info },
TroubleSource = { fg = p.dim },
TroubleCode = { fg = p.stealth },
TroubleLocation = { fg = p.dim },
TroubleFile = { fg = p.info, bold = true },
TroubleIndent = { fg = p.border },
TroublePos = { fg = p.dim },
TroubleSignError = { fg = p.danger },
TroubleSignWarning = { fg = p.warn },
TroubleSignHint = { fg = p.dim },
TroubleSignInfo = { fg = p.info },
TroublePreview = { fg = p.text, bg = p.focus_field },
TroubleFocusText = { fg = p.text, bold = true },
-- PLUGINS: INDENT-BLANKLINE -----------------------------------------------
IblIndent = { fg = p.border },
IblScope = { fg = p.flow }, -- Current scope = structural (blue)
IblWhitespace = { fg = p.border },
-- PLUGINS: NEOGIT ---------------------------------------------------------
NeogitBranch = { fg = p.flow, bold = true }, -- Ref / location
NeogitRemote = { fg = p.info },
NeogitHunkHeader = { fg = p.text, bg = p.panel, bold = true },
NeogitHunkHeaderHighlight = { fg = p.void, bg = p.info, bold = true },
NeogitDiffAdd = { fg = p.ok, bg = p.void },
NeogitDiffDelete = { fg = p.danger, bg = p.void },
NeogitDiffContext = { fg = p.dim, bg = p.void },
NeogitDiffAddHighlight = { fg = p.ok, bg = p.diff_add },
NeogitDiffDeleteHighlight = { fg = p.danger, bg = p.diff_del },
NeogitDiffContextHighlight = { fg = p.text, bg = p.panel },
NeogitCommitViewHeader = { fg = p.void, bg = p.info, bold = true },
NeogitFilePath = { fg = p.info, underline = true },
NeogitDiffHeader = { fg = p.warn, bold = true },
NeogitDiffHeaderHighlight = { fg = p.void, bg = p.warn, bold = true },
NeogitObjectId = { fg = p.dim },
NeogitStashes = { fg = p.dim }, -- Set-aside work is muted (matches zsh prompt), not sacred
NeogitRebaseDone = { fg = p.ok },
NeogitFold = { fg = p.stealth },
-- PLUGINS: AERIAL (Symbols Outline) --------------------------------------
AerialLine = { fg = p.ink, bg = p.focus_field },
AerialLineNC = { fg = p.dim, bg = p.panel },
AerialNormal = { fg = p.text, bg = p.void },
AerialGuide = { fg = p.border },
AerialClass = { fg = p.kind },
AerialClassIcon = { fg = p.kind },
AerialFunction = { fg = p.action },
AerialFunctionIcon = { fg = p.action },
AerialMethod = { fg = p.action },
AerialMethodIcon = { fg = p.action },
AerialConstructor = { fg = p.kind },
AerialField = { fg = p.prop },
AerialVariable = { fg = p.text },
AerialEnum = { fg = p.kind },
AerialEnumIcon = { fg = p.kind },
AerialInterface = { fg = p.kind },
AerialModule = { fg = p.kind },
AerialNamespace = { fg = p.kind },
AerialPackage = { fg = p.kind },
AerialProperty = { fg = p.prop },
AerialStruct = { fg = p.kind },
AerialType = { fg = p.kind },
AerialTypeParameter = { fg = p.kind },
AerialConstant = { fg = p.const },
AerialString = { fg = p.value },
AerialNumber = { fg = p.const },
AerialBoolean = { fg = p.const },
AerialKey = { fg = p.flow },
AerialKeyword = { fg = p.flow },
AerialOperator = { fg = p.op },
AerialNull = { fg = p.dim },
AerialArray = { fg = p.const },
AerialObject = { fg = p.kind },
AerialEvent = { fg = p.kind },
-- PLUGINS: DAP-UI ---------------------------------------------------------
DapUIScope = { fg = p.info, bold = true },
DapUIType = { fg = p.kind },
DapUIDecoration = { fg = p.border },
DapUIThread = { fg = p.ok },
DapUIStoppedThread = { fg = p.danger, bold = true }, -- Halted = alarm
DapUICurrentFrameName = { fg = p.danger, bold = true },
DapUISource = { fg = p.dim },
DapUILineNumber = { fg = p.stealth },
DapUIFloatBorder = { fg = p.border, bg = p.panel },
DapUIFloatNormal = { fg = p.text, bg = p.panel },
DapUIWatchesEmpty = { fg = p.dim },
DapUIWatchesValue = { fg = p.value },
DapUIWatchesError = { fg = p.danger },
DapUIBreakpointsPath = { fg = p.info },
DapUIBreakpointsInfo = { fg = p.dim },
DapUIBreakpointsCurrentLine = { fg = p.danger, bold = true },
DapUIBreakpointsDisabledLine = { fg = p.stealth },
DapUIEndofBuffer = { fg = p.void },
DapUIModifiedValue = { fg = p.warn, bold = true },
DapUIStop = { fg = p.danger },
DapUIStepOver = { fg = p.info },
DapUIStepInto = { fg = p.info },
DapUIStepBack = { fg = p.info },
DapUIStepOut = { fg = p.info },
DapUIRestart = { fg = p.ok },
DapUIUnavailable = { fg = p.stealth },
DapUIPlayPause = { fg = p.ok },
-- PLUGINS: DAP VIRTUAL TEXT -----------------------------------------------
NvimDapVirtualText = { fg = p.dim, italic = true },
NvimDapVirtualTextChanged = { fg = p.warn, italic = true },
NvimDapVirtualTextError = { fg = p.danger, italic = true },
NvimDapVirtualTextInfo = { fg = p.info, italic = true },
-- PLUGINS: NVIM-NOTIFY ----------------------------------------------------
NotifyERRORBorder = { fg = p.danger },
NotifyWARNBorder = { fg = p.warn },
NotifyINFOBorder = { fg = p.info },
NotifyDEBUGBorder = { fg = p.stealth },
NotifyTRACEBorder = { fg = p.dim }, -- Trace is verbose diagnostics, not sacred
NotifyERRORIcon = { fg = p.danger },
NotifyWARNIcon = { fg = p.warn },
NotifyINFOIcon = { fg = p.info },
NotifyDEBUGIcon = { fg = p.stealth },
NotifyTRACEIcon = { fg = p.dim },
NotifyERRORTitle = { fg = p.danger, bold = true },
NotifyWARNTitle = { fg = p.warn, bold = true },
NotifyINFOTitle = { fg = p.info, bold = true },
NotifyDEBUGTitle = { fg = p.stealth, bold = true },
NotifyTRACETitle = { fg = p.dim, bold = true },
NotifyERRORBody = { fg = p.text, bg = p.panel },
NotifyWARNBody = { fg = p.text, bg = p.panel },
NotifyINFOBody = { fg = p.text, bg = p.panel },
NotifyDEBUGBody = { fg = p.dim, bg = p.panel },
NotifyTRACEBody = { fg = p.dim, bg = p.panel },
-- PLUGINS: SATELLITE (Scrollbar) -----------------------------------------
SatelliteBar = { bg = p.panel },
SatelliteCursor = { fg = p.focus }, -- Cursor position = pink
SatellitePosition = { fg = p.dim },
SatelliteError = { fg = p.danger },
SatelliteWarning = { fg = p.warn },
SatelliteHint = { fg = p.dim },
SatelliteInfo = { fg = p.info },
SatelliteSearch = { fg = p.focus_active }, -- Search = pink
SatelliteGit = { fg = p.ok },
SatelliteMark = { fg = p.warn },
-- PLUGINS: OIL.NVIM (File Explorer) --------------------------------------
OilDir = { fg = p.info, bold = true },
OilDirIcon = { fg = p.info },
OilLink = { fg = p.flow, italic = true }, -- Symlink = structural (blue)
OilLinkTarget = { fg = p.flow },
OilCopy = { fg = p.warn, bold = true },
OilMove = { fg = p.warn },
OilChange = { fg = p.info },
OilCreate = { fg = p.ok, bold = true },
OilDelete = { fg = p.danger, bold = true }, -- Destructive = danger
OilPermissionNone = { fg = p.stealth },
OilPermissionRead = { fg = p.info },
OilPermissionWrite = { fg = p.warn },
OilPermissionExecute = { fg = p.ok },
OilTypeDir = { fg = p.info },
OilTypeFile = { fg = p.text },
OilTypeLink = { fg = p.flow },
OilTypeSpecial = { fg = p.special, bold = true }, -- Device/socket files: exceptional system state, form-coded
OilSize = { fg = p.dim },
OilMtime = { fg = p.stealth },
-- PLUGINS: NEOTEST --------------------------------------------------------
NeotestPassed = { fg = p.ok },
NeotestFailed = { fg = p.danger },
NeotestRunning = { fg = p.warn },
NeotestSkipped = { fg = p.dim },
NeotestUnknown = { fg = p.stealth },
NeotestTest = { fg = p.text },
NeotestFile = { fg = p.info },
NeotestDir = { fg = p.info, bold = true },
NeotestNamespace = { fg = p.kind },
NeotestMarked = { fg = p.focus, bold = true }, -- Mark = attention
NeotestTarget = { fg = p.focus },
NeotestAdapterName = { fg = p.info, bold = true },
NeotestWinSelect = { fg = p.info, bold = true },
NeotestFocused = { bold = true },
NeotestIndent = { fg = p.border },
NeotestExpandMarker = { fg = p.dim },
NeotestWatching = { fg = p.warn },
-- PLUGINS: GRUG-FAR (Search & Replace) -----------------------------------
GrugFarResultsHeader = { fg = p.void, bg = p.focus, bold = true }, -- Search = pink
GrugFarResultsMatch = { fg = p.ink, bg = p.focus_field, bold = true },
GrugFarResultsMatchAdded = { fg = p.ok },
GrugFarResultsMatchRemoved = { fg = p.danger },
GrugFarResultsLineNo = { fg = p.dim },
GrugFarResultsPath = { fg = p.info, underline = true },
GrugFarResultsStats = { fg = p.dim },
GrugFarInputLabel = { fg = p.warn, bold = true },
GrugFarInputPlaceholder = { fg = p.stealth },
GrugFarHelpHeader = { fg = p.dim, bold = true },
GrugFarHelpWinHeader = { fg = p.text, bg = p.panel, bold = true },
-- PLUGINS: TWINNY (AI Ghost Text) ----------------------------------------
TwinnyAccept = { fg = p.stealth, italic = true },
TwinnyHint = { fg = p.stealth, italic = true },
-- PLUGINS: GITSIGNS (extended) -------------------------------------------
GitSignsCurrentLineBlame = { fg = p.stealth, italic = true },
GitSignsAddNr = { fg = p.ok },
GitSignsChangeNr = { fg = p.warn },
GitSignsDeleteNr = { fg = p.danger },
GitSignsAddLn = { fg = p.ok, bg = p.diff_add },
GitSignsChangeLn = { fg = p.warn, bg = p.diff_chg },
GitSignsDeleteLn = { fg = p.danger, bg = p.diff_del },
GitSignsAddPreview = { fg = p.ok, bg = p.diff_add },
GitSignsDeletePreview = { fg = p.danger, bg = p.diff_del },
GitSignsAddInline = { fg = p.void, bg = p.ok },
GitSignsDeleteInline = { fg = p.void, bg = p.danger },
GitSignsChangeInline = { fg = p.void, bg = p.warn },
GitSignsUntracked = { fg = p.dim },
-- PLUGINS: RENDER-MARKDOWN ------------------------------------------------
-- Heading ramp avoids red + pink (both reserved); uses code-safe hues only.
RenderMarkdownH1 = { fg = p.info, bold = true },
RenderMarkdownH2 = { fg = p.flow, bold = true },
RenderMarkdownH3 = { fg = p.kind, bold = true },
RenderMarkdownH4 = { fg = p.ok, bold = true },
RenderMarkdownH5 = { fg = p.warn, bold = true },
RenderMarkdownH6 = { fg = p.dim, bold = true },
RenderMarkdownH1Bg = { bg = p.panel },
RenderMarkdownH2Bg = { bg = p.panel },
RenderMarkdownH3Bg = { bg = p.panel },
RenderMarkdownH4Bg = { bg = p.panel },
RenderMarkdownH5Bg = { bg = p.panel },
RenderMarkdownH6Bg = { bg = p.panel },
RenderMarkdownCode = { bg = p.panel },
RenderMarkdownCodeInline = { fg = p.value, bg = p.panel },
RenderMarkdownBullet = { fg = p.info },
RenderMarkdownQuote = { fg = p.dim, italic = true },
RenderMarkdownDash = { fg = p.border },
RenderMarkdownLink = { fg = p.info, underline = true },
RenderMarkdownSign = { bg = p.void },
RenderMarkdownMath = { fg = p.info },
RenderMarkdownTableHead = { fg = p.void, bg = p.info, bold = true },
RenderMarkdownTableRow = { fg = p.text },
RenderMarkdownTableFill = { fg = p.border },
RenderMarkdownTodo = { fg = p.void, bg = p.warn, bold = true },
RenderMarkdownUnchecked = { fg = p.stealth },
RenderMarkdownChecked = { fg = p.ok },
}
for group, highlight in pairs(groups) do
vim.api.nvim_set_hl(0, group, highlight)
end
local links = {
["@annotation"] = "Attribute",
["@attribute"] = "Attribute",
["@character"] = "Character",
["@comment"] = "Comment",
["@constant"] = "Constant",
["@constant.builtin"] = "Constant",
["@constant.macro"] = "Macro",
["@constructor"] = "Type",
["@debug"] = "Debug",
["@define"] = "Define",
["@exception"] = "Exception",
["@field"] = "Property",
["@float"] = "Float",
["@function"] = "Function",
["@function.builtin"] = "Function",
["@function.call"] = "Function",
["@function.macro"] = "Macro",
["@include"] = "Include",
["@keyword"] = "Keyword",
["@keyword.conditional"] = "Conditional",
["@keyword.repeat"] = "Repeat",
["@keyword.return"] = "Statement",
["@keyword.function"] = "Keyword",
["@keyword.operator"] = "Operator",
["@keyword.exception"] = "Exception",
["@label"] = "Label",
["@method"] = "Function",
["@method.call"] = "Function",
["@module"] = "Structure",
["@namespace"] = "Structure",
["@number"] = "Number",
["@operator"] = "Operator",
["@parameter"] = "Identifier",
["@preproc"] = "PreProc",
["@property"] = "Property",
["@punctuation"] = "Delimiter",
["@punctuation.bracket"] = "Delimiter",
["@punctuation.delimiter"] = "Delimiter",
["@punctuation.special"] = "Delimiter",
["@repeat"] = "Repeat",
["@string"] = "String",
["@string.escape"] = "SpecialChar",
["@string.regex"] = "SpecialChar",
["@string.special"] = "SpecialChar",
["@tag"] = "Tag",
["@tag.attribute"] = "Property",
["@tag.delimiter"] = "Delimiter",
["@text"] = "Normal",
["@text.title"] = "Title",
["@markup.heading"] = "Title",
["@markup.heading.1"] = "Title",
["@markup.heading.2"] = "Title",
["@markup.heading.3"] = "Title",
["@markup.heading.4"] = "Title",
["@markup.heading.5"] = "Title",
["@markup.heading.6"] = "Title",
["@markup.link"] = "ApexMarkupLink",
["@markup.link.label"] = "ApexMarkupLink",
["@markup.link.url"] = "ApexMarkupLink",
["@markup.strong"] = "ApexMarkupStrong",
["@markup.italic"] = "ApexMarkupItalic",
["@markup.strikethrough"] = "DiagnosticDeprecated",
["@markup.underline"] = "Underlined",
["@markup.raw"] = "String",
["@markup.raw.block"] = "String",
["@markup.raw.delimiter"] = "Delimiter",
["@markup.quote"] = "Comment",
["@markup.list"] = "Delimiter",
["@markup.list.checked"] = "String",
["@markup.list.unchecked"] = "Comment",
["@markup.math"] = "Constant",
["@markup.environment"] = "Type",
["@markup.environment.name"] = "Type",
["@type"] = "Type",
["@type.builtin"] = "Type",
["@type.definition"] = "Type",
["@type.qualifier"] = "Keyword",
["@variable"] = "Identifier",
["@variable.builtin"] = "Builtin",
["@variable.parameter"] = "Identifier",
["@variable.member"] = "Property",
["@lsp.type.boolean"] = "Boolean",
["@lsp.type.builtinType"] = "Type",
["@lsp.type.class"] = "Type",
["@lsp.type.comment"] = "Comment",
["@lsp.type.decorator"] = "Attribute",
["@lsp.type.enum"] = "Type",
["@lsp.type.enumMember"] = "Constant",
["@lsp.type.event"] = "Type",
["@lsp.type.function"] = "Function",
["@lsp.type.interface"] = "Type",
["@lsp.type.keyword"] = "Keyword",
["@lsp.type.macro"] = "Macro",
["@lsp.type.method"] = "Function",
["@lsp.type.modifier"] = "Keyword",
["@lsp.type.namespace"] = "Structure",
["@lsp.type.number"] = "Number",
["@lsp.type.operator"] = "Operator",
["@lsp.type.parameter"] = "Identifier",
["@lsp.type.property"] = "Property",
["@lsp.type.regexp"] = "SpecialChar",
["@lsp.type.string"] = "String",
["@lsp.type.struct"] = "Structure",
["@lsp.type.type"] = "Type",
["@lsp.type.typeParameter"] = "Type",
["@lsp.type.variable"] = "Identifier",
["@lsp.mod.deprecated"] = "DiagnosticDeprecated",
["@lsp.mod.abstract"] = "Type",
["@lsp.mod.declaration"] = "Keyword",
["@lsp.mod.defaultLibrary"] = "Constant",
["@lsp.mod.definition"] = "Keyword",
["@lsp.mod.documentation"] = "Comment",
["@lsp.mod.modification"] = "Operator",
["@lsp.mod.readonly"] = "Constant",
["@lsp.mod.static"] = "Constant",
["@lsp.mod.async"] = "Keyword",
["@lsp.typemod.function.async"] = "Keyword",
["@lsp.typemod.method.async"] = "Keyword",
["@lsp.typemod.function.deprecated"] = "DiagnosticDeprecated",
["@lsp.typemod.method.deprecated"] = "DiagnosticDeprecated",
["@lsp.typemod.variable.deprecated"] = "DiagnosticDeprecated",
["@lsp.typemod.variable.readonly"] = "Constant",
["@lsp.typemod.parameter.readonly"] = "Constant",
["@lsp.typemod.property.readonly"] = "Constant",
["@lsp.typemod.variable.static"] = "Constant",
["@lsp.typemod.property.static"] = "Constant",
}
for group, target in pairs(links) do
vim.api.nvim_set_hl(0, group, { link = target })
end
end
M.load()
-- PLUGINS: LUALINE --------------------------------------------------------
-- Export lualine theme from palette for use in lualine config.
-- Mode hues stay distinct: normal=pink(attention), insert=green, visual=cyan,
-- replace=amber, command=purple(sacred, as a filled field — form-coded).
-- fg = void for contrast on bright accents.
do
local p = M.palette
M.lualine = {
normal = {
a = { fg = p.void, bg = p.focus, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
insert = {
a = { fg = p.void, bg = p.ok, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
visual = {
a = { fg = p.void, bg = p.info, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
replace = {
a = { fg = p.void, bg = p.warn, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
command = {
a = { fg = p.void, bg = p.special, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
inactive = {
a = { fg = p.dim, bg = p.panel },
b = { fg = p.dim, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
}
end
return M
+803
View File
@@ -0,0 +1,803 @@
-- Apex Neon: Standalone Theme Engine
-- Philosophy: Signal over decoration. Red = danger. Pink = attention.
-- Neither red nor pink is ever a static syntax token (spec §1, §12).
local M = {}
M.palette = {
-- NEUTRALS — the readable field --------------------------------------------
void = "#070709", -- Background (also: ink on a bright accent fill)
panel = "#101218", -- Dark surface (statusline, floats, cursorline)
border = "#262a34", -- Borders, separators
stealth = "#383d49", -- Ignored text only (sub-threshold by design)
dim = "#8b909c", -- Comments, muted labels (ghost)
text = "#e6e8ec", -- Body text (stark / ink)
punct = "#aab0bc", -- Punctuation / delimiters (lifted neutral)
op = "#c2c8d4", -- Operators (neutral)
prop = "#cdd4e3", -- Fields / properties (dim body)
-- ATTENTION (pink) — cursor, search, matched pairs. NEVER syntax. ----------
focus = "#f783d4", -- Cursor — the crosshair (hottest mark)
focus_active = "#e42ab9", -- Current match, matched bracket / pair
focus_field = "#340c29", -- Search-set / selection background
-- DANGER (red) — error, destructive, alarm. NEVER syntax. ------------------
danger = "#ff0044", -- Error figure, destructive, urgent border
danger_field = "#1f0a12", -- Error region / delete background
danger_hot = "#ff3b3b", -- Escalation
-- CODE HUES (buffer-safe) --------------------------------------------------
info = "#00eaff", -- Cyan — info / links
action = "#5af3ff", -- Cyan — functions / methods
builtin = "#8fd6ff", -- Cyan, dim — self / builtin
kind = "#7db4ff", -- Blue — types / kinds
storage = "#3c75f9", -- Blue, heavy — storage / modifier / attribute
flow = "#5b8cff", -- Bright-blue — control-flow navigation
value = "#2bffb2", -- Green — strings / values
escape = "#7dffd0", -- Green, bright — char / escape
const = "#37dba0", -- Green, cool — numbers / const
ok = "#00ff99", -- Green — success state
warn = "#ffb700", -- Amber — warning (UI only)
special = "#a550f9", -- Purple — sacred / root only (always form-coded)
-- DIFF grounds -------------------------------------------------------------
diff_add = "#0a1f16",
diff_chg = "#1f1a0a",
diff_del = "#1f0a12",
-- ON-ACCENT INK ------------------------------------------------------------
ink = "#e6e8ec", -- fg on a dim pink field (search / selection)
}
function M.load()
vim.cmd "hi clear"
if vim.fn.exists "syntax_on" then vim.cmd "syntax reset" end
vim.o.background = "dark"
vim.g.colors_name = "apex-neon"
-- Optional transparency: set g:apex_blend or g:apex_transparent to opt in.
local blend = vim.g.apex_blend
if type(blend) == "number" then
vim.o.winblend = blend
vim.o.pumblend = blend
elseif vim.g.apex_transparent == true then
vim.o.winblend = 20
vim.o.pumblend = 20
end
local p = M.palette
local groups = {
-- CANVAS & UI -----------------------------------------------------------
Normal = { fg = p.text, bg = p.void },
NormalNC = { fg = p.dim, bg = p.void }, -- Non-focused windows
SignColumn = { bg = p.void },
FoldColumn = { fg = p.stealth, bg = p.void },
VertSplit = { fg = p.border }, -- Deprecated in nvim 0.10, but good fallback
WinSeparator = { fg = p.border },
EndOfBuffer = { fg = p.void }, -- Hide tildes
NormalFloat = { fg = p.text, bg = p.panel },
FloatBorder = { fg = p.border, bg = p.panel },
MsgArea = { fg = p.text, bg = p.void },
WinBar = { fg = p.text, bg = p.panel },
WinBarNC = { fg = p.dim, bg = p.panel },
-- CURSOR & NAVIGATION ("Attention" — pink) ------------------------------
Cursor = { fg = p.void, bg = p.focus }, -- Pink crosshair
TermCursor = { fg = p.void, bg = p.focus },
CursorLine = { bg = p.panel },
CursorColumn = { bg = p.panel },
ColorColumn = { bg = p.panel },
CursorLineNr = { fg = p.focus, bold = true }, -- Pink line number (you are here)
LineNr = { fg = p.stealth }, -- Other lines fade out
-- SELECTION & SEARCH ("Region scanned" — pink field) --------------------
Visual = { fg = p.ink, bg = p.focus_field }, -- Dim pink field, fg preserved
VisualNOS = { fg = p.ink, bg = p.focus_field },
Search = { fg = p.ink, bg = p.focus_field }, -- Other matches: the set
IncSearch = { fg = p.void, bg = p.focus_active }, -- Acquiring
CurSearch = { fg = p.void, bg = p.focus_active, bold = true }, -- The one you are on
-- STATUS & MESSAGES -----------------------------------------------------
StatusLine = { fg = p.text, bg = p.panel },
StatusLineNC = { fg = p.dim, bg = p.void },
WildMenu = { fg = p.void, bg = p.focus_active },
Pmenu = { fg = p.text, bg = p.panel },
PmenuSel = { fg = p.void, bg = p.focus, bold = true }, -- Pink menu selection
PmenuKind = { fg = p.dim, bg = p.panel },
PmenuKindSel = { fg = p.void, bg = p.focus, bold = true },
PmenuExtra = { fg = p.dim, bg = p.panel },
PmenuExtraSel = { fg = p.void, bg = p.focus, bold = true },
PmenuMatch = { fg = p.info, bg = p.panel, bold = true },
PmenuMatchSel = { fg = p.void, bg = p.focus, bold = true },
PmenuSbar = { bg = p.panel },
PmenuThumb = { bg = p.stealth },
ErrorMsg = { fg = p.danger },
WarningMsg = { fg = p.warn },
MoreMsg = { fg = p.info },
ModeMsg = { fg = p.text },
TabLine = { fg = p.dim, bg = p.panel },
TabLineSel = { fg = p.text, bg = p.void, bold = true },
TabLineFill = { fg = p.panel, bg = p.panel },
QuickFixLine = { fg = p.text, bg = p.panel, bold = true },
-- SYNTAX: typed by grammatical role (spec §7) ---------------------------
-- blue = kinds · cyan = actions · green = values · neutral = connective
Comment = { fg = p.dim, italic = true }, -- Ghost — not a target
Constant = { fg = p.const }, -- Green (cool) — const values
String = { fg = p.value }, -- Green — strings
Character = { fg = p.value },
Number = { fg = p.const },
Boolean = { fg = p.const },
Float = { fg = p.const },
Identifier = { fg = p.text }, -- Variables (calm body)
Property = { fg = p.prop }, -- Fields / properties (dim body)
Function = { fg = p.action }, -- Cyan — actions
Builtin = { fg = p.builtin, italic = true }, -- Cyan dim — self / builtin
Statement = { fg = p.flow, bold = true }, -- Bright-blue — control flow
Conditional = { fg = p.flow, bold = true },
Repeat = { fg = p.flow, bold = true },
Label = { fg = p.flow },
Operator = { fg = p.op }, -- Neutral
Keyword = { fg = p.storage }, -- Blue — storage / modifier
Exception = { fg = p.flow, bold = true }, -- Control flow (NOT danger — never red in code)
PreProc = { fg = p.action }, -- Cyan — preprocessor / macro ceremony
Include = { fg = p.storage }, -- Blue — declarative (use / import)
Define = { fg = p.action },
Macro = { fg = p.action, italic = true }, -- Cyan — bang-macros (action + ceremony)
PreCondit = { fg = p.action },
Type = { fg = p.kind }, -- Blue — kinds
StorageClass = { fg = p.storage, bold = true }, -- Blue heavy
Structure = { fg = p.kind },
Typedef = { fg = p.kind },
Attribute = { fg = p.storage, italic = true }, -- Blue declarative — #[derive], decorators
Special = { fg = p.escape }, -- Green — special tokens (escapes-adjacent)
SpecialChar = { fg = p.escape }, -- Green bright — string escapes / regex
Tag = { fg = p.kind }, -- Blue — structural HTML/XML tags
Delimiter = { fg = p.punct }, -- Neutral, lifted
Debug = { fg = p.special, bold = true }, -- Sacred purple: always form-coded
Underlined = { fg = p.info, underline = true },
Ignore = { fg = p.stealth },
Error = { fg = p.danger },
Todo = { fg = p.void, bg = p.warn, bold = true },
Title = { fg = p.info, bold = true },
MatchParen = { fg = p.focus_active, bold = true }, -- Attention — matched pair (pink)
Whitespace = { fg = p.border },
NonText = { fg = p.border },
SpecialKey = { fg = p.border },
SpellBad = { sp = p.danger, undercurl = true },
SpellCap = { sp = p.warn, undercurl = true },
SpellRare = { sp = p.info, undercurl = true },
SpellLocal = { sp = p.dim, undercurl = true },
LspReferenceText = { bg = p.panel },
LspReferenceRead = { bg = p.panel },
LspReferenceWrite = { bg = p.panel, bold = true },
LspSignatureActiveParameter = { fg = p.void, bg = p.info, bold = true },
LspInlayHint = { fg = p.dim, bg = p.panel },
LspCodeLens = { fg = p.dim },
LspCodeLensSeparator = { fg = p.stealth },
LspInfoBorder = { fg = p.border, bg = p.panel },
LspInfoTitle = { fg = p.dim, bg = p.panel },
-- DIAGNOSTICS -----------------------------------------------------------
DiagnosticError = { fg = p.danger },
DiagnosticWarn = { fg = p.warn },
DiagnosticInfo = { fg = p.info },
DiagnosticHint = { fg = p.dim },
DiagnosticOk = { fg = p.ok },
DiagnosticDeprecated = { fg = p.dim, strikethrough = true },
DiagnosticUnnecessary = { fg = p.dim },
DiagnosticUnderlineError = { undercurl = true, sp = p.danger },
DiagnosticUnderlineWarn = { undercurl = true, sp = p.warn },
DiagnosticUnderlineInfo = { undercurl = true, sp = p.info },
DiagnosticUnderlineHint = { undercurl = true, sp = p.dim },
DiagnosticUnderlineOk = { undercurl = true, sp = p.ok },
DiagnosticVirtualTextError = { fg = p.danger, bg = p.panel },
DiagnosticVirtualTextWarn = { fg = p.warn, bg = p.panel },
DiagnosticVirtualTextInfo = { fg = p.info, bg = p.panel },
DiagnosticVirtualTextHint = { fg = p.dim, bg = p.panel },
DiagnosticVirtualTextOk = { fg = p.ok, bg = p.panel },
DiagnosticVirtualLinesError = { fg = p.danger, bg = p.panel },
DiagnosticVirtualLinesWarn = { fg = p.warn, bg = p.panel },
DiagnosticVirtualLinesInfo = { fg = p.info, bg = p.panel },
DiagnosticVirtualLinesHint = { fg = p.dim, bg = p.panel },
DiagnosticVirtualLinesOk = { fg = p.ok, bg = p.panel },
DiagnosticSignError = { fg = p.danger, bg = p.void },
DiagnosticSignWarn = { fg = p.warn, bg = p.void },
DiagnosticSignInfo = { fg = p.info, bg = p.void },
DiagnosticSignHint = { fg = p.dim, bg = p.void },
DiagnosticSignOk = { fg = p.ok, bg = p.void },
DiagnosticFloatingError = { fg = p.danger, bg = p.panel },
DiagnosticFloatingWarn = { fg = p.warn, bg = p.panel },
DiagnosticFloatingInfo = { fg = p.info, bg = p.panel },
DiagnosticFloatingHint = { fg = p.dim, bg = p.panel },
DiagnosticFloatingOk = { fg = p.ok, bg = p.panel },
ApexMarkupStrong = { bold = true },
ApexMarkupItalic = { italic = true },
ApexMarkupLink = { fg = p.info, underline = true },
-- DIFF (figure / ground — spec §8) --------------------------------------
DiffAdd = { fg = p.ok, bg = p.diff_add },
DiffChange = { fg = p.warn, bg = p.diff_chg },
DiffDelete = { fg = p.danger, bg = p.diff_del },
DiffText = { fg = p.void, bg = p.warn, bold = true },
-- PLUGINS: TELESCOPE ("The HUD") ----------------------------------------
TelescopeNormal = { bg = p.void },
TelescopeBorder = { fg = p.border, bg = p.void },
TelescopePromptNormal = { fg = p.text, bg = p.void },
TelescopePromptBorder = { fg = p.info, bg = p.void }, -- Cyan input border
TelescopePromptTitle = { fg = p.void, bg = p.info }, -- Cyan label
TelescopePreviewTitle = { fg = p.void, bg = p.ok }, -- Green label
TelescopeResultsTitle = { fg = p.dim, bg = p.panel },
TelescopeSelection = { fg = p.text, bg = p.focus_field, bold = true }, -- Pink field
TelescopeMatching = { fg = p.info, bold = true },
-- PLUGINS: NEO-TREE -----------------------------------------------------
NeoTreeNormal = { bg = p.void },
NeoTreeNormalNC = { bg = p.void },
NeoTreeVertSplit = { fg = p.panel, bg = p.void },
NeoTreeWinSeparator = { fg = p.panel, bg = p.void }, -- Fade out tree border
NeoTreeRootName = { fg = p.focus, bold = true }, -- Tree root = location (pink attention)
NeoTreeGitAdded = { fg = p.ok },
NeoTreeGitConflict = { fg = p.warn },
NeoTreeGitDeleted = { fg = p.danger },
NeoTreeGitModified = { fg = p.info },
-- PLUGINS: GITSIGNS -----------------------------------------------------
GitSignsAdd = { fg = p.ok, bg = p.void },
GitSignsChange = { fg = p.warn, bg = p.void },
GitSignsDelete = { fg = p.danger, bg = p.void },
-- PLUGINS: CMP (Completion) ---------------------------------------------
CmpItemAbbrDeprecated = { fg = p.dim, strikethrough = true },
CmpItemAbbrMatch = { fg = p.info, bold = true },
CmpItemAbbrMatchFuzzy = { fg = p.info, bold = true },
CmpItemKindFunction = { fg = p.action },
CmpItemKindMethod = { fg = p.action },
CmpItemKindKeyword = { fg = p.flow },
CmpItemKindVariable = { fg = p.text },
-- PLUGINS: BLINK.CMP (Completion) ----------------------------------------
BlinkCmpMenu = { fg = p.text, bg = p.panel },
BlinkCmpMenuBorder = { fg = p.border, bg = p.panel },
BlinkCmpMenuSelection = { fg = p.void, bg = p.focus, bold = true },
BlinkCmpScrollBarThumb = { bg = p.stealth },
BlinkCmpScrollBarGutter = { bg = p.panel },
BlinkCmpLabel = { fg = p.text },
BlinkCmpLabelDeprecated = { fg = p.dim, strikethrough = true },
BlinkCmpLabelMatch = { fg = p.info, bold = true },
BlinkCmpKindText = { fg = p.text },
BlinkCmpKindMethod = { fg = p.action },
BlinkCmpKindFunction = { fg = p.action },
BlinkCmpKindConstructor = { fg = p.kind },
BlinkCmpKindField = { fg = p.prop },
BlinkCmpKindVariable = { fg = p.text },
BlinkCmpKindClass = { fg = p.kind },
BlinkCmpKindInterface = { fg = p.kind },
BlinkCmpKindModule = { fg = p.kind },
BlinkCmpKindProperty = { fg = p.prop },
BlinkCmpKindUnit = { fg = p.const },
BlinkCmpKindValue = { fg = p.const },
BlinkCmpKindEnum = { fg = p.kind },
BlinkCmpKindKeyword = { fg = p.flow },
BlinkCmpKindSnippet = { fg = p.value },
BlinkCmpKindColor = { fg = p.info },
BlinkCmpKindFile = { fg = p.text },
BlinkCmpKindReference = { fg = p.info },
BlinkCmpKindFolder = { fg = p.info },
BlinkCmpKindEnumMember = { fg = p.const },
BlinkCmpKindConstant = { fg = p.const },
BlinkCmpKindStruct = { fg = p.kind },
BlinkCmpKindEvent = { fg = p.kind },
BlinkCmpKindOperator = { fg = p.op },
BlinkCmpKindTypeParameter = { fg = p.kind },
BlinkCmpGhostText = { fg = p.stealth, italic = true },
BlinkCmpDoc = { fg = p.text, bg = p.panel },
BlinkCmpDocBorder = { fg = p.border, bg = p.panel },
BlinkCmpDocSeparator = { fg = p.border, bg = p.panel },
BlinkCmpDocCursorLine = { bg = p.border },
BlinkCmpSignatureHelp = { fg = p.text, bg = p.panel },
BlinkCmpSignatureHelpBorder = { fg = p.border, bg = p.panel },
BlinkCmpSignatureHelpActiveParameter = { fg = p.void, bg = p.info, bold = true },
BlinkCmpSource = { fg = p.dim },
-- PLUGINS: BUFFERLINE -----------------------------------------------------
BufferLineBackground = { fg = p.dim, bg = p.panel },
BufferLineFill = { bg = p.panel },
BufferLineBuffer = { fg = p.dim, bg = p.panel },
BufferLineBufferSelected = { fg = p.text, bg = p.void, bold = true },
BufferLineBufferVisible = { fg = p.dim, bg = p.panel },
BufferLineTab = { fg = p.dim, bg = p.panel },
BufferLineTabSelected = { fg = p.text, bg = p.void, bold = true },
BufferLineTabClose = { fg = p.dim, bg = p.panel },
BufferLineModified = { fg = p.info, bg = p.panel },
BufferLineModifiedSelected = { fg = p.info, bg = p.void },
BufferLineModifiedVisible = { fg = p.info, bg = p.panel },
BufferLineSeparator = { fg = p.border, bg = p.panel },
BufferLineSeparatorSelected = { fg = p.border, bg = p.void },
BufferLineSeparatorVisible = { fg = p.border, bg = p.panel },
BufferLineIndicatorSelected = { fg = p.focus, bg = p.void }, -- Active = pink
BufferLineCloseButton = { fg = p.dim, bg = p.panel },
BufferLineCloseButtonSelected = { fg = p.focus, bg = p.void },
BufferLineCloseButtonVisible = { fg = p.dim, bg = p.panel },
BufferLineDiagnostic = { fg = p.dim, bg = p.panel },
BufferLineDiagnosticSelected = { fg = p.dim, bg = p.void },
BufferLineError = { fg = p.danger, bg = p.panel },
BufferLineErrorSelected = { fg = p.danger, bg = p.void, bold = true },
BufferLineWarning = { fg = p.warn, bg = p.panel },
BufferLineWarningSelected = { fg = p.warn, bg = p.void, bold = true },
BufferLineInfo = { fg = p.info, bg = p.panel },
BufferLineInfoSelected = { fg = p.info, bg = p.void, bold = true },
BufferLineHint = { fg = p.dim, bg = p.panel },
BufferLineHintSelected = { fg = p.dim, bg = p.void, bold = true },
BufferLinePick = { fg = p.focus, bg = p.panel, bold = true },
BufferLinePickSelected = { fg = p.focus, bg = p.void, bold = true },
BufferLinePickVisible = { fg = p.focus, bg = p.panel, bold = true },
-- PLUGINS: WHICH-KEY ------------------------------------------------------
WhichKey = { fg = p.flow, bold = true }, -- The key trigger = navigation
WhichKeySeparator = { fg = p.stealth },
WhichKeyGroup = { fg = p.info },
WhichKeyDesc = { fg = p.text },
WhichKeyFloat = { bg = p.panel },
WhichKeyBorder = { fg = p.border, bg = p.panel },
WhichKeyTitle = { fg = p.void, bg = p.focus, bold = true },
WhichKeyNormal = { fg = p.text, bg = p.panel },
WhichKeyValue = { fg = p.dim },
WhichKeyIcon = { fg = p.action },
WhichKeyIconAzure = { fg = p.kind },
WhichKeyIconGreen = { fg = p.ok },
WhichKeyIconYellow = { fg = p.warn },
WhichKeyIconRed = { fg = p.danger },
WhichKeyIconPurple = { fg = p.special },
WhichKeyIconCyan = { fg = p.info },
-- PLUGINS: TROUBLE --------------------------------------------------------
TroubleNormal = { fg = p.text, bg = p.void },
TroubleNormalNC = { fg = p.dim, bg = p.void },
TroubleText = { fg = p.text },
TroubleCount = { fg = p.void, bg = p.focus_active, bold = true },
TroubleError = { fg = p.danger },
TroubleWarning = { fg = p.warn },
TroubleHint = { fg = p.dim },
TroubleInfo = { fg = p.info },
TroubleSource = { fg = p.dim },
TroubleCode = { fg = p.stealth },
TroubleLocation = { fg = p.dim },
TroubleFile = { fg = p.info, bold = true },
TroubleIndent = { fg = p.border },
TroublePos = { fg = p.dim },
TroubleSignError = { fg = p.danger },
TroubleSignWarning = { fg = p.warn },
TroubleSignHint = { fg = p.dim },
TroubleSignInfo = { fg = p.info },
TroublePreview = { fg = p.text, bg = p.focus_field },
TroubleFocusText = { fg = p.text, bold = true },
-- PLUGINS: INDENT-BLANKLINE -----------------------------------------------
IblIndent = { fg = p.border },
IblScope = { fg = p.flow }, -- Current scope = structural (blue)
IblWhitespace = { fg = p.border },
-- PLUGINS: NEOGIT ---------------------------------------------------------
NeogitBranch = { fg = p.flow, bold = true }, -- Ref / location
NeogitRemote = { fg = p.info },
NeogitHunkHeader = { fg = p.text, bg = p.panel, bold = true },
NeogitHunkHeaderHighlight = { fg = p.void, bg = p.info, bold = true },
NeogitDiffAdd = { fg = p.ok, bg = p.void },
NeogitDiffDelete = { fg = p.danger, bg = p.void },
NeogitDiffContext = { fg = p.dim, bg = p.void },
NeogitDiffAddHighlight = { fg = p.ok, bg = p.diff_add },
NeogitDiffDeleteHighlight = { fg = p.danger, bg = p.diff_del },
NeogitDiffContextHighlight = { fg = p.text, bg = p.panel },
NeogitCommitViewHeader = { fg = p.void, bg = p.info, bold = true },
NeogitFilePath = { fg = p.info, underline = true },
NeogitDiffHeader = { fg = p.warn, bold = true },
NeogitDiffHeaderHighlight = { fg = p.void, bg = p.warn, bold = true },
NeogitObjectId = { fg = p.dim },
NeogitStashes = { fg = p.dim }, -- Set-aside work is muted (matches zsh prompt), not sacred
NeogitRebaseDone = { fg = p.ok },
NeogitFold = { fg = p.stealth },
-- PLUGINS: AERIAL (Symbols Outline) --------------------------------------
AerialLine = { fg = p.ink, bg = p.focus_field },
AerialLineNC = { fg = p.dim, bg = p.panel },
AerialNormal = { fg = p.text, bg = p.void },
AerialGuide = { fg = p.border },
AerialClass = { fg = p.kind },
AerialClassIcon = { fg = p.kind },
AerialFunction = { fg = p.action },
AerialFunctionIcon = { fg = p.action },
AerialMethod = { fg = p.action },
AerialMethodIcon = { fg = p.action },
AerialConstructor = { fg = p.kind },
AerialField = { fg = p.prop },
AerialVariable = { fg = p.text },
AerialEnum = { fg = p.kind },
AerialEnumIcon = { fg = p.kind },
AerialInterface = { fg = p.kind },
AerialModule = { fg = p.kind },
AerialNamespace = { fg = p.kind },
AerialPackage = { fg = p.kind },
AerialProperty = { fg = p.prop },
AerialStruct = { fg = p.kind },
AerialType = { fg = p.kind },
AerialTypeParameter = { fg = p.kind },
AerialConstant = { fg = p.const },
AerialString = { fg = p.value },
AerialNumber = { fg = p.const },
AerialBoolean = { fg = p.const },
AerialKey = { fg = p.flow },
AerialKeyword = { fg = p.flow },
AerialOperator = { fg = p.op },
AerialNull = { fg = p.dim },
AerialArray = { fg = p.const },
AerialObject = { fg = p.kind },
AerialEvent = { fg = p.kind },
-- PLUGINS: DAP-UI ---------------------------------------------------------
DapUIScope = { fg = p.info, bold = true },
DapUIType = { fg = p.kind },
DapUIDecoration = { fg = p.border },
DapUIThread = { fg = p.ok },
DapUIStoppedThread = { fg = p.danger, bold = true }, -- Halted = alarm
DapUICurrentFrameName = { fg = p.danger, bold = true },
DapUISource = { fg = p.dim },
DapUILineNumber = { fg = p.stealth },
DapUIFloatBorder = { fg = p.border, bg = p.panel },
DapUIFloatNormal = { fg = p.text, bg = p.panel },
DapUIWatchesEmpty = { fg = p.dim },
DapUIWatchesValue = { fg = p.value },
DapUIWatchesError = { fg = p.danger },
DapUIBreakpointsPath = { fg = p.info },
DapUIBreakpointsInfo = { fg = p.dim },
DapUIBreakpointsCurrentLine = { fg = p.danger, bold = true },
DapUIBreakpointsDisabledLine = { fg = p.stealth },
DapUIEndofBuffer = { fg = p.void },
DapUIModifiedValue = { fg = p.warn, bold = true },
DapUIStop = { fg = p.danger },
DapUIStepOver = { fg = p.info },
DapUIStepInto = { fg = p.info },
DapUIStepBack = { fg = p.info },
DapUIStepOut = { fg = p.info },
DapUIRestart = { fg = p.ok },
DapUIUnavailable = { fg = p.stealth },
DapUIPlayPause = { fg = p.ok },
-- PLUGINS: DAP VIRTUAL TEXT -----------------------------------------------
NvimDapVirtualText = { fg = p.dim, italic = true },
NvimDapVirtualTextChanged = { fg = p.warn, italic = true },
NvimDapVirtualTextError = { fg = p.danger, italic = true },
NvimDapVirtualTextInfo = { fg = p.info, italic = true },
-- PLUGINS: NVIM-NOTIFY ----------------------------------------------------
NotifyERRORBorder = { fg = p.danger },
NotifyWARNBorder = { fg = p.warn },
NotifyINFOBorder = { fg = p.info },
NotifyDEBUGBorder = { fg = p.stealth },
NotifyTRACEBorder = { fg = p.dim }, -- Trace is verbose diagnostics, not sacred
NotifyERRORIcon = { fg = p.danger },
NotifyWARNIcon = { fg = p.warn },
NotifyINFOIcon = { fg = p.info },
NotifyDEBUGIcon = { fg = p.stealth },
NotifyTRACEIcon = { fg = p.dim },
NotifyERRORTitle = { fg = p.danger, bold = true },
NotifyWARNTitle = { fg = p.warn, bold = true },
NotifyINFOTitle = { fg = p.info, bold = true },
NotifyDEBUGTitle = { fg = p.stealth, bold = true },
NotifyTRACETitle = { fg = p.dim, bold = true },
NotifyERRORBody = { fg = p.text, bg = p.panel },
NotifyWARNBody = { fg = p.text, bg = p.panel },
NotifyINFOBody = { fg = p.text, bg = p.panel },
NotifyDEBUGBody = { fg = p.dim, bg = p.panel },
NotifyTRACEBody = { fg = p.dim, bg = p.panel },
-- PLUGINS: SATELLITE (Scrollbar) -----------------------------------------
SatelliteBar = { bg = p.panel },
SatelliteCursor = { fg = p.focus }, -- Cursor position = pink
SatellitePosition = { fg = p.dim },
SatelliteError = { fg = p.danger },
SatelliteWarning = { fg = p.warn },
SatelliteHint = { fg = p.dim },
SatelliteInfo = { fg = p.info },
SatelliteSearch = { fg = p.focus_active }, -- Search = pink
SatelliteGit = { fg = p.ok },
SatelliteMark = { fg = p.warn },
-- PLUGINS: OIL.NVIM (File Explorer) --------------------------------------
OilDir = { fg = p.info, bold = true },
OilDirIcon = { fg = p.info },
OilLink = { fg = p.flow, italic = true }, -- Symlink = structural (blue)
OilLinkTarget = { fg = p.flow },
OilCopy = { fg = p.warn, bold = true },
OilMove = { fg = p.warn },
OilChange = { fg = p.info },
OilCreate = { fg = p.ok, bold = true },
OilDelete = { fg = p.danger, bold = true }, -- Destructive = danger
OilPermissionNone = { fg = p.stealth },
OilPermissionRead = { fg = p.info },
OilPermissionWrite = { fg = p.warn },
OilPermissionExecute = { fg = p.ok },
OilTypeDir = { fg = p.info },
OilTypeFile = { fg = p.text },
OilTypeLink = { fg = p.flow },
OilTypeSpecial = { fg = p.special, bold = true }, -- Device/socket files: exceptional system state, form-coded
OilSize = { fg = p.dim },
OilMtime = { fg = p.stealth },
-- PLUGINS: NEOTEST --------------------------------------------------------
NeotestPassed = { fg = p.ok },
NeotestFailed = { fg = p.danger },
NeotestRunning = { fg = p.warn },
NeotestSkipped = { fg = p.dim },
NeotestUnknown = { fg = p.stealth },
NeotestTest = { fg = p.text },
NeotestFile = { fg = p.info },
NeotestDir = { fg = p.info, bold = true },
NeotestNamespace = { fg = p.kind },
NeotestMarked = { fg = p.focus, bold = true }, -- Mark = attention
NeotestTarget = { fg = p.focus },
NeotestAdapterName = { fg = p.info, bold = true },
NeotestWinSelect = { fg = p.info, bold = true },
NeotestFocused = { bold = true },
NeotestIndent = { fg = p.border },
NeotestExpandMarker = { fg = p.dim },
NeotestWatching = { fg = p.warn },
-- PLUGINS: GRUG-FAR (Search & Replace) -----------------------------------
GrugFarResultsHeader = { fg = p.void, bg = p.focus, bold = true }, -- Search = pink
GrugFarResultsMatch = { fg = p.ink, bg = p.focus_field, bold = true },
GrugFarResultsMatchAdded = { fg = p.ok },
GrugFarResultsMatchRemoved = { fg = p.danger },
GrugFarResultsLineNo = { fg = p.dim },
GrugFarResultsPath = { fg = p.info, underline = true },
GrugFarResultsStats = { fg = p.dim },
GrugFarInputLabel = { fg = p.warn, bold = true },
GrugFarInputPlaceholder = { fg = p.stealth },
GrugFarHelpHeader = { fg = p.dim, bold = true },
GrugFarHelpWinHeader = { fg = p.text, bg = p.panel, bold = true },
-- PLUGINS: TWINNY (AI Ghost Text) ----------------------------------------
TwinnyAccept = { fg = p.stealth, italic = true },
TwinnyHint = { fg = p.stealth, italic = true },
-- PLUGINS: GITSIGNS (extended) -------------------------------------------
GitSignsCurrentLineBlame = { fg = p.stealth, italic = true },
GitSignsAddNr = { fg = p.ok },
GitSignsChangeNr = { fg = p.warn },
GitSignsDeleteNr = { fg = p.danger },
GitSignsAddLn = { fg = p.ok, bg = p.diff_add },
GitSignsChangeLn = { fg = p.warn, bg = p.diff_chg },
GitSignsDeleteLn = { fg = p.danger, bg = p.diff_del },
GitSignsAddPreview = { fg = p.ok, bg = p.diff_add },
GitSignsDeletePreview = { fg = p.danger, bg = p.diff_del },
GitSignsAddInline = { fg = p.void, bg = p.ok },
GitSignsDeleteInline = { fg = p.void, bg = p.danger },
GitSignsChangeInline = { fg = p.void, bg = p.warn },
GitSignsUntracked = { fg = p.dim },
-- PLUGINS: RENDER-MARKDOWN ------------------------------------------------
-- Heading ramp avoids red + pink (both reserved); uses code-safe hues only.
RenderMarkdownH1 = { fg = p.info, bold = true },
RenderMarkdownH2 = { fg = p.flow, bold = true },
RenderMarkdownH3 = { fg = p.kind, bold = true },
RenderMarkdownH4 = { fg = p.ok, bold = true },
RenderMarkdownH5 = { fg = p.warn, bold = true },
RenderMarkdownH6 = { fg = p.dim, bold = true },
RenderMarkdownH1Bg = { bg = p.panel },
RenderMarkdownH2Bg = { bg = p.panel },
RenderMarkdownH3Bg = { bg = p.panel },
RenderMarkdownH4Bg = { bg = p.panel },
RenderMarkdownH5Bg = { bg = p.panel },
RenderMarkdownH6Bg = { bg = p.panel },
RenderMarkdownCode = { bg = p.panel },
RenderMarkdownCodeInline = { fg = p.value, bg = p.panel },
RenderMarkdownBullet = { fg = p.info },
RenderMarkdownQuote = { fg = p.dim, italic = true },
RenderMarkdownDash = { fg = p.border },
RenderMarkdownLink = { fg = p.info, underline = true },
RenderMarkdownSign = { bg = p.void },
RenderMarkdownMath = { fg = p.info },
RenderMarkdownTableHead = { fg = p.void, bg = p.info, bold = true },
RenderMarkdownTableRow = { fg = p.text },
RenderMarkdownTableFill = { fg = p.border },
RenderMarkdownTodo = { fg = p.void, bg = p.warn, bold = true },
RenderMarkdownUnchecked = { fg = p.stealth },
RenderMarkdownChecked = { fg = p.ok },
}
for group, highlight in pairs(groups) do
vim.api.nvim_set_hl(0, group, highlight)
end
local links = {
["@annotation"] = "Attribute",
["@attribute"] = "Attribute",
["@character"] = "Character",
["@comment"] = "Comment",
["@constant"] = "Constant",
["@constant.builtin"] = "Constant",
["@constant.macro"] = "Macro",
["@constructor"] = "Type",
["@debug"] = "Debug",
["@define"] = "Define",
["@exception"] = "Exception",
["@field"] = "Property",
["@float"] = "Float",
["@function"] = "Function",
["@function.builtin"] = "Function",
["@function.call"] = "Function",
["@function.macro"] = "Macro",
["@include"] = "Include",
["@keyword"] = "Keyword",
["@keyword.conditional"] = "Conditional",
["@keyword.repeat"] = "Repeat",
["@keyword.return"] = "Statement",
["@keyword.function"] = "Keyword",
["@keyword.operator"] = "Operator",
["@keyword.exception"] = "Exception",
["@label"] = "Label",
["@method"] = "Function",
["@method.call"] = "Function",
["@module"] = "Structure",
["@namespace"] = "Structure",
["@number"] = "Number",
["@operator"] = "Operator",
["@parameter"] = "Identifier",
["@preproc"] = "PreProc",
["@property"] = "Property",
["@punctuation"] = "Delimiter",
["@punctuation.bracket"] = "Delimiter",
["@punctuation.delimiter"] = "Delimiter",
["@punctuation.special"] = "Delimiter",
["@repeat"] = "Repeat",
["@string"] = "String",
["@string.escape"] = "SpecialChar",
["@string.regex"] = "SpecialChar",
["@string.special"] = "SpecialChar",
["@tag"] = "Tag",
["@tag.attribute"] = "Property",
["@tag.delimiter"] = "Delimiter",
["@text"] = "Normal",
["@text.title"] = "Title",
["@markup.heading"] = "Title",
["@markup.heading.1"] = "Title",
["@markup.heading.2"] = "Title",
["@markup.heading.3"] = "Title",
["@markup.heading.4"] = "Title",
["@markup.heading.5"] = "Title",
["@markup.heading.6"] = "Title",
["@markup.link"] = "ApexMarkupLink",
["@markup.link.label"] = "ApexMarkupLink",
["@markup.link.url"] = "ApexMarkupLink",
["@markup.strong"] = "ApexMarkupStrong",
["@markup.italic"] = "ApexMarkupItalic",
["@markup.strikethrough"] = "DiagnosticDeprecated",
["@markup.underline"] = "Underlined",
["@markup.raw"] = "String",
["@markup.raw.block"] = "String",
["@markup.raw.delimiter"] = "Delimiter",
["@markup.quote"] = "Comment",
["@markup.list"] = "Delimiter",
["@markup.list.checked"] = "String",
["@markup.list.unchecked"] = "Comment",
["@markup.math"] = "Constant",
["@markup.environment"] = "Type",
["@markup.environment.name"] = "Type",
["@type"] = "Type",
["@type.builtin"] = "Type",
["@type.definition"] = "Type",
["@type.qualifier"] = "Keyword",
["@variable"] = "Identifier",
["@variable.builtin"] = "Builtin",
["@variable.parameter"] = "Identifier",
["@variable.member"] = "Property",
["@lsp.type.boolean"] = "Boolean",
["@lsp.type.builtinType"] = "Type",
["@lsp.type.class"] = "Type",
["@lsp.type.comment"] = "Comment",
["@lsp.type.decorator"] = "Attribute",
["@lsp.type.enum"] = "Type",
["@lsp.type.enumMember"] = "Constant",
["@lsp.type.event"] = "Type",
["@lsp.type.function"] = "Function",
["@lsp.type.interface"] = "Type",
["@lsp.type.keyword"] = "Keyword",
["@lsp.type.macro"] = "Macro",
["@lsp.type.method"] = "Function",
["@lsp.type.modifier"] = "Keyword",
["@lsp.type.namespace"] = "Structure",
["@lsp.type.number"] = "Number",
["@lsp.type.operator"] = "Operator",
["@lsp.type.parameter"] = "Identifier",
["@lsp.type.property"] = "Property",
["@lsp.type.regexp"] = "SpecialChar",
["@lsp.type.string"] = "String",
["@lsp.type.struct"] = "Structure",
["@lsp.type.type"] = "Type",
["@lsp.type.typeParameter"] = "Type",
["@lsp.type.variable"] = "Identifier",
["@lsp.mod.deprecated"] = "DiagnosticDeprecated",
["@lsp.mod.abstract"] = "Type",
["@lsp.mod.declaration"] = "Keyword",
["@lsp.mod.defaultLibrary"] = "Constant",
["@lsp.mod.definition"] = "Keyword",
["@lsp.mod.documentation"] = "Comment",
["@lsp.mod.modification"] = "Operator",
["@lsp.mod.readonly"] = "Constant",
["@lsp.mod.static"] = "Constant",
["@lsp.mod.async"] = "Keyword",
["@lsp.typemod.function.async"] = "Keyword",
["@lsp.typemod.method.async"] = "Keyword",
["@lsp.typemod.function.deprecated"] = "DiagnosticDeprecated",
["@lsp.typemod.method.deprecated"] = "DiagnosticDeprecated",
["@lsp.typemod.variable.deprecated"] = "DiagnosticDeprecated",
["@lsp.typemod.variable.readonly"] = "Constant",
["@lsp.typemod.parameter.readonly"] = "Constant",
["@lsp.typemod.property.readonly"] = "Constant",
["@lsp.typemod.variable.static"] = "Constant",
["@lsp.typemod.property.static"] = "Constant",
}
for group, target in pairs(links) do
vim.api.nvim_set_hl(0, group, { link = target })
end
end
M.load()
-- PLUGINS: LUALINE --------------------------------------------------------
-- Export lualine theme from palette for use in lualine config.
-- Mode hues stay distinct: normal=pink(attention), insert=green, visual=cyan,
-- replace=amber, command=purple(sacred, as a filled field — form-coded).
-- fg = void for contrast on bright accents.
do
local p = M.palette
M.lualine = {
normal = {
a = { fg = p.void, bg = p.focus, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
insert = {
a = { fg = p.void, bg = p.ok, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
visual = {
a = { fg = p.void, bg = p.info, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
replace = {
a = { fg = p.void, bg = p.warn, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
command = {
a = { fg = p.void, bg = p.special, gui = "bold" },
b = { fg = p.text, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
inactive = {
a = { fg = p.dim, bg = p.panel },
b = { fg = p.dim, bg = p.panel },
c = { fg = p.dim, bg = p.void },
},
}
end
return M
+171
View File
@@ -0,0 +1,171 @@
/*
* Owlry - Apex Aeon Theme
* v2 spine: red = danger · pink = attention · cyan = info
*
* A high-contrast theme built for focus and clinical clarity.
* Color exists to signal STATE, not to decorate space.
*
* Author: S0wlz (Owlibou)
*
* Usage: Set theme = "apex-aeon" in config
*/
:root {
/* Core surfaces */
--owlry-bg: #f1f3f7;
--owlry-bg-secondary: #e7eaf0;
--owlry-border: #c2c8d4;
--owlry-text: #16181d;
--owlry-text-secondary: #5c6270;
/* Attention - primary accent (caret, selection, focus) is pink */
--owlry-accent: #9d1a7e;
--owlry-accent-bright: #b32b92;
/* Provider badges - mapped to Apex v2 semantics */
--owlry-badge-app: #087193; /* Cyan: apps are informational */
--owlry-badge-bookmark: #935d03; /* Amber: bookmarks need attention */
--owlry-badge-calc: #7b4e05; /* Bright amber: calculator results */
--owlry-badge-clip: #6a1fb8; /* Purple: clipboard is special */
--owlry-badge-cmd: #6a1fb8; /* Purple: commands are elevated */
--owlry-badge-dmenu: #0a7851; /* Green: dmenu is success/pipe */
--owlry-badge-emoji: #2148c0; /* Blue: glyph kinds (bright magenta is attention-pink now — reserved) */
--owlry-badge-file: #005f80; /* Bright cyan: file search is active info */
--owlry-badge-script: #006543; /* Bright green: scripts execute successfully */
--owlry-badge-ssh: #087193; /* Cyan: SSH is technical/info */
--owlry-badge-sys: #c8003a; /* Red: system actions are critical/danger */
--owlry-badge-uuctl: #935d03; /* Amber: uuctl requires attention */
--owlry-badge-web: #087193; /* Cyan: web is informational */
/* Widget badges */
--owlry-badge-media: #1633a0; /* Bright blue: active media flow (off the reserved pink) */
--owlry-badge-weather: #005f80; /* Bright cyan: weather is active info */
--owlry-badge-pomo: #9e0030; /* Alert red: pomodoro alarm */
}
.owlry-main {
background-color: rgba(241, 243, 247, 0.98);
border: 1px solid rgba(194, 200, 212, 0.8);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.8),
0 0 0 1px rgba(157, 26, 126, 0.1);
}
.owlry-search {
background-color: rgba(231, 234, 240, 0.9);
border: 2px solid rgba(194, 200, 212, 0.8);
color: var(--owlry-text);
caret-color: var(--owlry-accent);
}
.owlry-search:focus {
border-color: var(--owlry-accent);
box-shadow: 0 0 0 2px rgba(157, 26, 126, 0.3);
}
.owlry-result-row:hover {
background-color: rgba(231, 234, 240, 0.8);
}
.owlry-result-row:selected {
background-color: rgba(157, 26, 126, 0.15);
border-left: 3px solid var(--owlry-accent);
}
.owlry-result-row:selected .owlry-result-name {
color: var(--owlry-accent-bright);
}
.owlry-result-row:selected .owlry-result-icon {
color: var(--owlry-accent);
}
/* Provider badges - styled per Apex v2 semantics */
.owlry-badge-app {
background-color: rgba(8, 113, 147, 0.15);
color: var(--owlry-badge-app);
}
.owlry-badge-bookmark {
background-color: rgba(147, 93, 3, 0.15);
color: var(--owlry-badge-bookmark);
}
.owlry-badge-calc {
background-color: rgba(123, 78, 5, 0.15);
color: var(--owlry-badge-calc);
}
.owlry-badge-clip {
background-color: rgba(106, 31, 184, 0.15);
color: var(--owlry-badge-clip);
}
.owlry-badge-cmd {
background-color: rgba(106, 31, 184, 0.15);
color: var(--owlry-badge-cmd);
}
.owlry-badge-dmenu {
background-color: rgba(10, 120, 81, 0.15);
color: var(--owlry-badge-dmenu);
}
.owlry-badge-emoji {
background-color: rgba(33, 72, 192, 0.15);
color: var(--owlry-badge-emoji);
}
.owlry-badge-file {
background-color: rgba(0, 95, 128, 0.15);
color: var(--owlry-badge-file);
}
.owlry-badge-script {
background-color: rgba(0, 101, 67, 0.15);
color: var(--owlry-badge-script);
}
.owlry-badge-ssh {
background-color: rgba(8, 113, 147, 0.15);
color: var(--owlry-badge-ssh);
}
.owlry-badge-sys {
background-color: rgba(200, 0, 58, 0.15);
color: var(--owlry-badge-sys);
}
.owlry-badge-uuctl {
background-color: rgba(147, 93, 3, 0.15);
color: var(--owlry-badge-uuctl);
}
.owlry-badge-web {
background-color: rgba(8, 113, 147, 0.15);
color: var(--owlry-badge-web);
}
/* Widget badges */
.owlry-badge-media {
background-color: rgba(22, 51, 160, 0.15);
color: var(--owlry-badge-media);
}
.owlry-badge-weather {
background-color: rgba(0, 95, 128, 0.15);
color: var(--owlry-badge-weather);
}
.owlry-badge-pomo {
background-color: rgba(158, 0, 48, 0.15);
color: var(--owlry-badge-pomo);
}
/* Filter button - default uses the pink attention accent */
.owlry-filter-button:checked {
background-color: rgba(157, 26, 126, 0.2);
color: var(--owlry-accent);
border-color: rgba(157, 26, 126, 0.5);
}
+171
View File
@@ -0,0 +1,171 @@
/*
* Owlry - Apex Neon Theme
* v2 spine: red = danger · pink = attention · cyan = info
*
* A high-contrast theme built for focus and clinical clarity.
* Color exists to signal STATE, not to decorate space.
*
* Author: S0wlz (Owlibou)
*
* Usage: Set theme = "apex-neon" in config
*/
:root {
/* Core surfaces */
--owlry-bg: #070709;
--owlry-bg-secondary: #101218;
--owlry-border: #262a34;
--owlry-text: #e6e8ec;
--owlry-text-secondary: #8b909c;
/* Attention - primary accent (caret, selection, focus) is pink */
--owlry-accent: #f783d4;
--owlry-accent-bright: #e42ab9;
/* Provider badges - mapped to Apex v2 semantics */
--owlry-badge-app: #00eaff; /* Cyan: apps are informational */
--owlry-badge-bookmark: #ffb700; /* Amber: bookmarks need attention */
--owlry-badge-calc: #ffd24d; /* Bright amber: calculator results */
--owlry-badge-clip: #a550f9; /* Purple: clipboard is special */
--owlry-badge-cmd: #a550f9; /* Purple: commands are elevated */
--owlry-badge-dmenu: #00ff99; /* Green: dmenu is success/pipe */
--owlry-badge-emoji: #3c75f9; /* Blue: glyph kinds (bright magenta is attention-pink now — reserved) */
--owlry-badge-file: #5af3ff; /* Bright cyan: file search is active info */
--owlry-badge-script: #2bffb2; /* Bright green: scripts execute successfully */
--owlry-badge-ssh: #00eaff; /* Cyan: SSH is technical/info */
--owlry-badge-sys: #ff0044; /* Red: system actions are critical/danger */
--owlry-badge-uuctl: #ffb700; /* Amber: uuctl requires attention */
--owlry-badge-web: #00eaff; /* Cyan: web is informational */
/* Widget badges */
--owlry-badge-media: #5b8cff; /* Bright blue: active media flow (off the reserved pink) */
--owlry-badge-weather: #5af3ff; /* Bright cyan: weather is active info */
--owlry-badge-pomo: #ff3b3b; /* Alert red: pomodoro alarm */
}
.owlry-main {
background-color: rgba(7, 7, 9, 0.98);
border: 1px solid rgba(38, 42, 52, 0.8);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.8),
0 0 0 1px rgba(247, 131, 212, 0.1);
}
.owlry-search {
background-color: rgba(16, 18, 24, 0.9);
border: 2px solid rgba(38, 42, 52, 0.8);
color: var(--owlry-text);
caret-color: var(--owlry-accent);
}
.owlry-search:focus {
border-color: var(--owlry-accent);
box-shadow: 0 0 0 2px rgba(247, 131, 212, 0.3);
}
.owlry-result-row:hover {
background-color: rgba(16, 18, 24, 0.8);
}
.owlry-result-row:selected {
background-color: rgba(247, 131, 212, 0.15);
border-left: 3px solid var(--owlry-accent);
}
.owlry-result-row:selected .owlry-result-name {
color: var(--owlry-accent-bright);
}
.owlry-result-row:selected .owlry-result-icon {
color: var(--owlry-accent);
}
/* Provider badges - styled per Apex v2 semantics */
.owlry-badge-app {
background-color: rgba(0, 234, 255, 0.15);
color: var(--owlry-badge-app);
}
.owlry-badge-bookmark {
background-color: rgba(255, 183, 0, 0.15);
color: var(--owlry-badge-bookmark);
}
.owlry-badge-calc {
background-color: rgba(255, 210, 77, 0.15);
color: var(--owlry-badge-calc);
}
.owlry-badge-clip {
background-color: rgba(165, 80, 249, 0.15);
color: var(--owlry-badge-clip);
}
.owlry-badge-cmd {
background-color: rgba(165, 80, 249, 0.15);
color: var(--owlry-badge-cmd);
}
.owlry-badge-dmenu {
background-color: rgba(0, 255, 153, 0.15);
color: var(--owlry-badge-dmenu);
}
.owlry-badge-emoji {
background-color: rgba(60, 117, 249, 0.15);
color: var(--owlry-badge-emoji);
}
.owlry-badge-file {
background-color: rgba(90, 243, 255, 0.15);
color: var(--owlry-badge-file);
}
.owlry-badge-script {
background-color: rgba(43, 255, 178, 0.15);
color: var(--owlry-badge-script);
}
.owlry-badge-ssh {
background-color: rgba(0, 234, 255, 0.15);
color: var(--owlry-badge-ssh);
}
.owlry-badge-sys {
background-color: rgba(255, 0, 68, 0.15);
color: var(--owlry-badge-sys);
}
.owlry-badge-uuctl {
background-color: rgba(255, 183, 0, 0.15);
color: var(--owlry-badge-uuctl);
}
.owlry-badge-web {
background-color: rgba(0, 234, 255, 0.15);
color: var(--owlry-badge-web);
}
/* Widget badges */
.owlry-badge-media {
background-color: rgba(91, 140, 255, 0.15);
color: var(--owlry-badge-media);
}
.owlry-badge-weather {
background-color: rgba(90, 243, 255, 0.15);
color: var(--owlry-badge-weather);
}
.owlry-badge-pomo {
background-color: rgba(255, 59, 59, 0.15);
color: var(--owlry-badge-pomo);
}
/* Filter button - default uses the pink attention accent */
.owlry-filter-button:checked {
background-color: rgba(247, 131, 212, 0.2);
color: var(--owlry-accent);
border-color: rgba(247, 131, 212, 0.5);
}
+17
View File
@@ -0,0 +1,17 @@
[apex-aeon]
text = 16181d
subtext = 5c6270
main = f1f3f7
sidebar = f1f3f7
player = f1f3f7
card = e7eaf0
shadow = 000000
selected-row = 087193
button = 087193
button-active = 9d1a7e
button-disabled = c8cdd8
tab-active = c2c8d4
notification = 087193
notification-error = c8003a
misc = 935d03
+1
View File
@@ -0,0 +1 @@
/* Apex Aeon - Spicetify overrides */
+17
View File
@@ -0,0 +1,17 @@
[apex-neon]
text = e6e8ec
subtext = 8b909c
main = 070709
sidebar = 070709
player = 070709
card = 101218
shadow = 000000
selected-row = 00eaff
button = 00eaff
button-active = f783d4
button-disabled = 383d49
tab-active = 262a34
notification = 00eaff
notification-error = ff0044
misc = ffb700
+1
View File
@@ -0,0 +1 @@
/* Apex Neon - Spicetify overrides */
+36
View File
@@ -0,0 +1,36 @@
# Apex Aeon — tmux theme
# Generated by the Apex build system. Do not edit.
# v2 spine: red = danger · pink = attention · cyan = info
# Status bar
set -g status-style "fg=#16181d,bg=#e7eaf0"
# Status left: session name — pink attention accent ("you are here")
set -g status-left "#[fg=#f1f3f7,bg=#9d1a7e,bold] #S #[fg=#e7eaf0,bg=#e7eaf0]"
set -g status-left-length 30
# Status right: date/time in muted
set -g status-right "#[fg=#5c6270,bg=#e7eaf0] %H:%M %d-%b "
set -g status-right-length 30
# Window list
set -g window-status-format "#[fg=#5c6270,bg=#e7eaf0] #I:#W "
set -g window-status-current-format "#[fg=#16181d,bg=#e7eaf0,bold] #I:#W #[fg=#9d1a7e]▏"
# Pane borders — active = pink attention; red would mean urgent (spec §5)
set -g pane-border-style "fg=#c2c8d4"
set -g pane-active-border-style "fg=#9d1a7e"
# Messages
set -g message-style "fg=#087193,bg=#e7eaf0"
set -g message-command-style "fg=#f1f3f7,bg=#9d1a7e"
# Copy mode — pink attention selection
set -g mode-style "fg=#f1f3f7,bg=#b32b92,bold"
# Clock
set -g clock-mode-colour "#087193"
# Misc
set -g status-position bottom
set -g status-justify left
+36
View File
@@ -0,0 +1,36 @@
# Apex Neon — tmux theme
# Generated by the Apex build system. Do not edit.
# v2 spine: red = danger · pink = attention · cyan = info
# Status bar
set -g status-style "fg=#e6e8ec,bg=#101218"
# Status left: session name — pink attention accent ("you are here")
set -g status-left "#[fg=#070709,bg=#f783d4,bold] #S #[fg=#101218,bg=#101218]"
set -g status-left-length 30
# Status right: date/time in muted
set -g status-right "#[fg=#8b909c,bg=#101218] %H:%M %d-%b "
set -g status-right-length 30
# Window list
set -g window-status-format "#[fg=#8b909c,bg=#101218] #I:#W "
set -g window-status-current-format "#[fg=#e6e8ec,bg=#101218,bold] #I:#W #[fg=#f783d4]▏"
# Pane borders — active = pink attention; red would mean urgent (spec §5)
set -g pane-border-style "fg=#262a34"
set -g pane-active-border-style "fg=#f783d4"
# Messages
set -g message-style "fg=#00eaff,bg=#101218"
set -g message-command-style "fg=#070709,bg=#f783d4"
# Copy mode — pink attention selection
set -g mode-style "fg=#070709,bg=#e42ab9,bold"
# Clock
set -g clock-mode-colour "#00eaff"
# Misc
set -g status-position bottom
set -g status-justify left
+46
View File
@@ -0,0 +1,46 @@
# Apex Aeon — Zathura Theme
# v2 spine: red = danger · pink = attention · cyan = info
# Core
set default-bg "#f1f3f7"
set default-fg "#16181d"
# Status Bar
set statusbar-bg "#e7eaf0"
set statusbar-fg "#16181d"
# Input Bar
set inputbar-bg "#e7eaf0"
set inputbar-fg "#16181d"
# Completion
set completion-bg "#e7eaf0"
set completion-fg "#16181d"
set completion-group-bg "#c2c8d4"
set completion-group-fg "#5c6270"
set completion-highlight-bg "#f9daf1"
set completion-highlight-fg "#16181d"
# Notifications
set notification-bg "#e7eaf0"
set notification-fg "#16181d"
set notification-error-bg "#c8003a"
set notification-error-fg "#f1f3f7"
set notification-warning-bg "#935d03"
set notification-warning-fg "#f1f3f7"
# Search highlight — pink attention (current match brighter)
set highlight-color "rgba(b32b92, 0.5)"
set highlight-active-color "rgba(b32b92, 0.8)"
# Recolor (Dark Mode for PDFs)
# In Neon (Dark), we want dark paper (background) and light ink (foreground).
# In Aeon (Light), we want light paper and dark ink (standard).
set recolor-lightcolor "#f1f3f7"
set recolor-darkcolor "#16181d"
# Default recolor state
# Ideally, only true for dark themes, but Zathura config is static.
# Users can toggle with Ctrl+R.
set recolor "false"
set recolor-keephue "true"
+46
View File
@@ -0,0 +1,46 @@
# Apex Neon — Zathura Theme
# v2 spine: red = danger · pink = attention · cyan = info
# Core
set default-bg "#070709"
set default-fg "#e6e8ec"
# Status Bar
set statusbar-bg "#101218"
set statusbar-fg "#e6e8ec"
# Input Bar
set inputbar-bg "#101218"
set inputbar-fg "#e6e8ec"
# Completion
set completion-bg "#101218"
set completion-fg "#e6e8ec"
set completion-group-bg "#262a34"
set completion-group-fg "#8b909c"
set completion-highlight-bg "#340c29"
set completion-highlight-fg "#e6e8ec"
# Notifications
set notification-bg "#101218"
set notification-fg "#e6e8ec"
set notification-error-bg "#ff0044"
set notification-error-fg "#070709"
set notification-warning-bg "#ffb700"
set notification-warning-fg "#070709"
# Search highlight — pink attention (current match brighter)
set highlight-color "rgba(e42ab9, 0.5)"
set highlight-active-color "rgba(e42ab9, 0.8)"
# Recolor (Dark Mode for PDFs)
# In Neon (Dark), we want dark paper (background) and light ink (foreground).
# In Aeon (Light), we want light paper and dark ink (standard).
set recolor-lightcolor "#070709"
set recolor-darkcolor "#e6e8ec"
# Default recolor state
# Ideally, only true for dark themes, but Zathura config is static.
# Users can toggle with Ctrl+R.
set recolor "false"
set recolor-keephue "true"
+632
View File
@@ -0,0 +1,632 @@
{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
"name": "Apex",
"author": "S0wlz (Owlibou)",
"themes": [
{
"name": "Apex Neon",
"appearance": "dark",
"style": {
"background": "#070709",
"background.appearance": "opaque",
"surface.background": "#101218",
"elevated_surface.background": "#101218",
"panel.background": "#101218",
"panel.focused_border": "#f783d4",
"panel.indent_guide": "#262a3466",
"panel.indent_guide_active": "#8b909caa",
"panel.indent_guide_hover": "#8b909ccc",
"tab_bar.background": "#101218",
"tab.inactive_background": "#101218",
"tab.active_background": "#070709",
"title_bar.background": "#070709",
"title_bar.inactive_background": "#101218",
"toolbar.background": "#101218",
"status_bar.background": "#101218",
"border": "#262a34",
"border.variant": "#101218",
"border.focused": "#f783d4",
"border.selected": "#f783d4",
"border.disabled": "#101218",
"border.transparent": "transparent",
"text": "#e6e8ec",
"text.muted": "#8b909c",
"text.placeholder": "#8b909c",
"text.disabled": "#8b909c",
"text.accent": "#00eaff",
"icon": "#e6e8ec",
"icon.muted": "#8b909c",
"icon.placeholder": "#8b909c",
"icon.disabled": "#8b909c",
"icon.accent": "#00eaff",
"accents": [
"#f783d4",
"#00eaff",
"#a550f9",
"#00ff99",
"#ffb700"
],
"element.background": "#101218",
"element.hover": "#262a34",
"element.active": "#262a34",
"element.selected": "#262a34",
"element.disabled": "#101218",
"ghost_element.background": null,
"ghost_element.hover": "#262a3466",
"ghost_element.active": "#262a3488",
"ghost_element.selected": "#262a3466",
"ghost_element.disabled": null,
"drop_target.background": "#00eaff22",
"editor.background": "#070709",
"editor.foreground": "#e6e8ec",
"editor.gutter.background": "#070709",
"editor.subheader.background": "#101218",
"editor.active_line.background": "#101218",
"editor.highlighted_line.background": "#101218",
"editor.line_number": "#8b909c",
"editor.active_line_number": "#f783d4",
"editor.wrap_guide": "#262a34",
"editor.active_wrap_guide": "#8b909c",
"editor.indent_guide": "#262a3466",
"editor.indent_guide_active": "#8b909caa",
"editor.invisible": "#262a3488",
"editor.document_highlight.read_background": "#00eaff22",
"editor.document_highlight.write_background": "#f783d422",
"editor.document_highlight.bracket_background": "#262a3466",
"search.match_background": "#e42ab933",
"scrollbar.track.background": "#070709",
"scrollbar.track.border": "#070709",
"scrollbar.thumb.background": "#262a34aa",
"scrollbar.thumb.hover_background": "#383d49",
"scrollbar.thumb.border": "transparent",
"pane.focused_border": "#f783d4",
"pane_group.border": "#262a34",
"link_text.hover": "#5b8cff",
"success": "#00ff99",
"success.background": "#00ff991a",
"success.border": "#00ff99",
"warning": "#ffb700",
"warning.background": "#ffb7001a",
"warning.border": "#ffb700",
"error": "#ff0044",
"error.background": "#ff00441a",
"error.border": "#ff0044",
"info": "#00eaff",
"info.background": "#00eaff1a",
"info.border": "#00eaff",
"hint": "#3c75f9",
"hint.background": "#3c75f91a",
"hint.border": "#3c75f9",
"predictive": "#8b909c",
"predictive.background": "#8b909c1a",
"predictive.border": "#8b909c",
"unreachable": "#a550f9",
"unreachable.background": "#a550f91a",
"unreachable.border": "#a550f9",
"created": "#00ff99",
"created.background": "#00ff991a",
"created.border": "#00ff99",
"modified": "#ffb700",
"modified.background": "#ffb7001a",
"modified.border": "#ffb700",
"deleted": "#ff0044",
"deleted.background": "#ff00441a",
"deleted.border": "#ff0044",
"renamed": "#00eaff",
"renamed.background": "#00eaff1a",
"renamed.border": "#00eaff",
"conflict": "#ff0044",
"conflict.background": "#ff00441a",
"conflict.border": "#ff0044",
"ignored": "#8b909c",
"ignored.background": "#8b909c1a",
"ignored.border": "#262a34",
"hidden": "#8b909c",
"hidden.background": "#8b909c1a",
"hidden.border": "#262a34",
"terminal.background": "#070709",
"terminal.foreground": "#e6e8ec",
"terminal.bright_foreground": "#ffffff",
"terminal.dim_foreground": "#8b909c",
"terminal.ansi.background": "#070709",
"terminal.ansi.black": "#070709",
"terminal.ansi.red": "#ff0044",
"terminal.ansi.green": "#00ff99",
"terminal.ansi.yellow": "#ffb700",
"terminal.ansi.blue": "#3c75f9",
"terminal.ansi.magenta": "#a550f9",
"terminal.ansi.cyan": "#00eaff",
"terminal.ansi.white": "#e6e8ec",
"terminal.ansi.bright_black": "#383d49",
"terminal.ansi.bright_red": "#ff3b3b",
"terminal.ansi.bright_green": "#2bffb2",
"terminal.ansi.bright_yellow": "#ffd24d",
"terminal.ansi.bright_blue": "#5b8cff",
"terminal.ansi.bright_magenta": "#fe41d0",
"terminal.ansi.bright_cyan": "#5af3ff",
"terminal.ansi.bright_white": "#ffffff",
"terminal.ansi.dim_black": "#070709",
"terminal.ansi.dim_red": "#ff0044",
"terminal.ansi.dim_green": "#00ff99",
"terminal.ansi.dim_yellow": "#ffb700",
"terminal.ansi.dim_blue": "#3c75f9",
"terminal.ansi.dim_magenta": "#a550f9",
"terminal.ansi.dim_cyan": "#00eaff",
"terminal.ansi.dim_white": "#e6e8ec",
"players": [
{
"cursor": "#f783d4",
"background": "#f783d4",
"selection": "#f783d433"
},
{
"cursor": "#00eaff",
"background": "#00eaff",
"selection": "#00eaff33"
},
{
"cursor": "#a550f9",
"background": "#a550f9",
"selection": "#a550f933"
},
{
"cursor": "#00ff99",
"background": "#00ff99",
"selection": "#00ff9933"
},
{
"cursor": "#ffb700",
"background": "#ffb700",
"selection": "#ffb70033"
}
],
"version_control.added": "#00ff99",
"version_control.modified": "#ffb700",
"version_control.deleted": "#ff0044",
"version_control.conflict": "#ff0044",
"version_control.renamed": "#00eaff",
"version_control.ignored": "#8b909c",
"syntax": {
"comment": {
"color": "#8b909c",
"font_style": "italic"
},
"comment.doc": {
"color": "#8b909c",
"font_style": "italic"
},
"keyword": {
"color": "#5b8cff"
},
"keyword.import": {
"color": "#5b8cff"
},
"keyword.storage": {
"color": "#3c75f9"
},
"function": {
"color": "#5af3ff"
},
"function.method": {
"color": "#5af3ff"
},
"function.special.definition": {
"color": "#5af3ff"
},
"type": {
"color": "#7db4ff"
},
"type.builtin": {
"color": "#7db4ff"
},
"string": {
"color": "#2bffb2"
},
"string.escape": {
"color": "#7dffd0"
},
"string.regex": {
"color": "#7dffd0"
},
"number": {
"color": "#37dba0"
},
"boolean": {
"color": "#37dba0"
},
"constant": {
"color": "#37dba0"
},
"constant.builtin": {
"color": "#37dba0"
},
"variable": {
"color": "#e6e8ec"
},
"variable.special": {
"color": "#8fd6ff"
},
"property": {
"color": "#cdd4e3"
},
"attribute": {
"color": "#3c75f9"
},
"tag": {
"color": "#7db4ff"
},
"label": {
"color": "#5b8cff"
},
"operator": {
"color": "#c2c8d4"
},
"punctuation": {
"color": "#aab0bc"
},
"punctuation.bracket": {
"color": "#aab0bc"
},
"punctuation.delimiter": {
"color": "#aab0bc"
},
"punctuation.list_marker": {
"color": "#aab0bc",
"font_weight": 700
},
"link_text": {
"color": "#00eaff"
},
"link_uri": {
"color": "#3c75f9"
},
"emphasis": {
"font_style": "italic"
},
"emphasis.strong": {
"font_weight": 700
},
"title": {
"color": "#e6e8ec",
"font_weight": 700
},
"text.literal": {
"color": "#2bffb2"
},
"preproc": {
"color": "#5af3ff"
},
"constructor": {
"color": "#7db4ff"
},
"enum": {
"color": "#7db4ff"
},
"variant": {
"color": "#37dba0"
},
"hint": {
"color": "#8b909c"
},
"predictive": {
"color": "#8b909c"
}
}
}
},
{
"name": "Apex Aeon",
"appearance": "light",
"style": {
"background": "#f1f3f7",
"background.appearance": "opaque",
"surface.background": "#e7eaf0",
"elevated_surface.background": "#ffffff",
"panel.background": "#e7eaf0",
"panel.focused_border": "#9d1a7e",
"panel.indent_guide": "#c2c8d466",
"panel.indent_guide_active": "#5c6270aa",
"panel.indent_guide_hover": "#5c6270cc",
"tab_bar.background": "#e7eaf0",
"tab.inactive_background": "#e7eaf0",
"tab.active_background": "#f1f3f7",
"title_bar.background": "#f1f3f7",
"title_bar.inactive_background": "#e7eaf0",
"toolbar.background": "#e7eaf0",
"status_bar.background": "#e7eaf0",
"border": "#c2c8d4",
"border.variant": "#c8cdd8",
"border.focused": "#9d1a7e",
"border.selected": "#9d1a7e",
"border.disabled": "#c8cdd8",
"border.transparent": "transparent",
"text": "#16181d",
"text.muted": "#5c6270",
"text.placeholder": "#5c6270",
"text.disabled": "#c8cdd8",
"text.accent": "#087193",
"icon": "#16181d",
"icon.muted": "#5c6270",
"icon.placeholder": "#5c6270",
"icon.disabled": "#c8cdd8",
"icon.accent": "#087193",
"accents": [
"#9d1a7e",
"#087193",
"#6a1fb8",
"#0a7851",
"#935d03"
],
"element.background": "#ffffff",
"element.hover": "#c2c8d4",
"element.active": "#c2c8d4",
"element.selected": "#c2c8d4",
"element.disabled": "#e7eaf0",
"ghost_element.background": null,
"ghost_element.hover": "#c2c8d466",
"ghost_element.active": "#c2c8d488",
"ghost_element.selected": "#c2c8d466",
"ghost_element.disabled": null,
"drop_target.background": "#08719322",
"editor.background": "#f1f3f7",
"editor.foreground": "#16181d",
"editor.gutter.background": "#f1f3f7",
"editor.subheader.background": "#e7eaf0",
"editor.active_line.background": "#e7eaf0",
"editor.highlighted_line.background": "#e7eaf0",
"editor.line_number": "#5c6270",
"editor.active_line_number": "#9d1a7e",
"editor.wrap_guide": "#c2c8d4",
"editor.active_wrap_guide": "#5c6270",
"editor.indent_guide": "#c2c8d466",
"editor.indent_guide_active": "#5c6270aa",
"editor.invisible": "#c2c8d488",
"editor.document_highlight.read_background": "#0871931a",
"editor.document_highlight.write_background": "#9d1a7e1a",
"editor.document_highlight.bracket_background": "#c2c8d466",
"search.match_background": "#b32b9244",
"scrollbar.track.background": "#f1f3f7",
"scrollbar.track.border": "#f1f3f7",
"scrollbar.thumb.background": "#c8cdd8aa",
"scrollbar.thumb.hover_background": "#5c6270",
"scrollbar.thumb.border": "transparent",
"pane.focused_border": "#9d1a7e",
"pane_group.border": "#c8cdd8",
"link_text.hover": "#1633a0",
"success": "#0a7851",
"success.background": "#0a78511a",
"success.border": "#0a7851",
"warning": "#935d03",
"warning.background": "#935d031a",
"warning.border": "#935d03",
"error": "#c8003a",
"error.background": "#c8003a1a",
"error.border": "#c8003a",
"info": "#087193",
"info.background": "#0871931a",
"info.border": "#087193",
"hint": "#2148c0",
"hint.background": "#2148c01a",
"hint.border": "#2148c0",
"predictive": "#5c6270",
"predictive.background": "#5c62701a",
"predictive.border": "#5c6270",
"unreachable": "#6a1fb8",
"unreachable.background": "#6a1fb81a",
"unreachable.border": "#6a1fb8",
"created": "#0a7851",
"created.background": "#0a78511a",
"created.border": "#0a7851",
"modified": "#935d03",
"modified.background": "#935d031a",
"modified.border": "#935d03",
"deleted": "#c8003a",
"deleted.background": "#c8003a1a",
"deleted.border": "#c8003a",
"renamed": "#087193",
"renamed.background": "#0871931a",
"renamed.border": "#087193",
"conflict": "#c8003a",
"conflict.background": "#c8003a1a",
"conflict.border": "#c8003a",
"ignored": "#5c6270",
"ignored.background": "#5c62701a",
"ignored.border": "#c2c8d4",
"hidden": "#5c6270",
"hidden.background": "#5c62701a",
"hidden.border": "#c2c8d4",
"terminal.background": "#f1f3f7",
"terminal.foreground": "#16181d",
"terminal.bright_foreground": "#16181d",
"terminal.dim_foreground": "#5c6270",
"terminal.ansi.background": "#f1f3f7",
"terminal.ansi.black": "#16181d",
"terminal.ansi.red": "#c8003a",
"terminal.ansi.green": "#0a7851",
"terminal.ansi.yellow": "#935d03",
"terminal.ansi.blue": "#2148c0",
"terminal.ansi.magenta": "#6a1fb8",
"terminal.ansi.cyan": "#087193",
"terminal.ansi.white": "#c2c8d4",
"terminal.ansi.bright_black": "#5c6270",
"terminal.ansi.bright_red": "#9e0030",
"terminal.ansi.bright_green": "#006543",
"terminal.ansi.bright_yellow": "#7b4e05",
"terminal.ansi.bright_blue": "#1633a0",
"terminal.ansi.bright_magenta": "#8d1071",
"terminal.ansi.bright_cyan": "#005f80",
"terminal.ansi.bright_white": "#f1f3f7",
"terminal.ansi.dim_black": "#16181d",
"terminal.ansi.dim_red": "#c8003a",
"terminal.ansi.dim_green": "#0a7851",
"terminal.ansi.dim_yellow": "#935d03",
"terminal.ansi.dim_blue": "#2148c0",
"terminal.ansi.dim_magenta": "#6a1fb8",
"terminal.ansi.dim_cyan": "#087193",
"terminal.ansi.dim_white": "#c2c8d4",
"players": [
{
"cursor": "#9d1a7e",
"background": "#9d1a7e",
"selection": "#9d1a7e33"
},
{
"cursor": "#087193",
"background": "#087193",
"selection": "#08719333"
},
{
"cursor": "#6a1fb8",
"background": "#6a1fb8",
"selection": "#6a1fb833"
},
{
"cursor": "#0a7851",
"background": "#0a7851",
"selection": "#0a785133"
},
{
"cursor": "#935d03",
"background": "#935d03",
"selection": "#935d0333"
}
],
"version_control.added": "#0a7851",
"version_control.modified": "#935d03",
"version_control.deleted": "#c8003a",
"version_control.conflict": "#c8003a",
"version_control.renamed": "#087193",
"version_control.ignored": "#5c6270",
"syntax": {
"comment": {
"color": "#5c6270",
"font_style": "italic"
},
"comment.doc": {
"color": "#5c6270",
"font_style": "italic"
},
"keyword": {
"color": "#1633a0"
},
"keyword.import": {
"color": "#1633a0"
},
"keyword.storage": {
"color": "#1633a0"
},
"function": {
"color": "#0e6e92"
},
"function.method": {
"color": "#0e6e92"
},
"function.special.definition": {
"color": "#0e6e92"
},
"type": {
"color": "#2148c0"
},
"type.builtin": {
"color": "#2148c0"
},
"string": {
"color": "#00734d"
},
"string.escape": {
"color": "#006641"
},
"string.regex": {
"color": "#006641"
},
"number": {
"color": "#0a7851"
},
"boolean": {
"color": "#0a7851"
},
"constant": {
"color": "#0a7851"
},
"constant.builtin": {
"color": "#0a7851"
},
"variable": {
"color": "#16181d"
},
"variable.special": {
"color": "#2c708e"
},
"property": {
"color": "#2e333d"
},
"attribute": {
"color": "#2148c0"
},
"tag": {
"color": "#2148c0"
},
"label": {
"color": "#1633a0"
},
"operator": {
"color": "#5c6270"
},
"punctuation": {
"color": "#4f5461"
},
"punctuation.bracket": {
"color": "#4f5461"
},
"punctuation.delimiter": {
"color": "#4f5461"
},
"punctuation.list_marker": {
"color": "#4f5461",
"font_weight": 700
},
"link_text": {
"color": "#087193"
},
"link_uri": {
"color": "#2148c0"
},
"emphasis": {
"font_style": "italic"
},
"emphasis.strong": {
"font_weight": 700
},
"title": {
"color": "#16181d",
"font_weight": 700
},
"text.literal": {
"color": "#00734d"
},
"preproc": {
"color": "#0e6e92"
},
"constructor": {
"color": "#2148c0"
},
"enum": {
"color": "#2148c0"
},
"variant": {
"color": "#0a7851"
},
"hint": {
"color": "#5c6270"
},
"predictive": {
"color": "#5c6270"
}
}
}
}
]
}
+631
View File
@@ -0,0 +1,631 @@
# Apex Aeon — Predator Cockpit (Zsh) — v2
# Two-bus design:
# [precmd radar] -> after-action + context bursts (event-driven)
# [promptline] -> LEFT: identity + territory
# RIGHT: intel + vcs + friction (stable)
setopt prompt_subst
setopt no_beep
zmodload zsh/datetime 2>/dev/null
# -----------------------------------------------------------------------------
# 1) PALETTE (Apex Aeon DNA)
# -----------------------------------------------------------------------------
typeset -gA C
C[VOID]="#f1f3f7"
C[WHITE]="#16181d"
C[MUTED]="#5c6270"
C[FOCUS]="#9d1a7e"
C[CYAN]="#087193"
C[GOLD]="#935d03"
C[OK]="#0a7851"
C[PURPLE]="#6a1fb8"
C[ALERT]="#c8003a"
# -----------------------------------------------------------------------------
# 1b) PLUGIN COLORS
# -----------------------------------------------------------------------------
# zsh-autosuggestions: ghost text from history (subtle, intentionally dim)
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#5c6270"
# zsh-history-substring-search
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND="fg=#087193,bold"
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND="fg=#c8003a,bold"
# -----------------------------------------------------------------------------
# 2) ICONS / GLYPHS (Nerd Font optional)
# -----------------------------------------------------------------------------
typeset -gA I
I[OS]=""
I[SSH]=""
I[ROOT]=""
I[GIT]=""
I[JOBS]=""
I[RADAR]="⌁"
I[RET]="↩"
typeset -gA S
S[PL_L]=""
S[PL_R]=""
S[DOT]="·"
# -----------------------------------------------------------------------------
# 3) CONFIG
# -----------------------------------------------------------------------------
typeset -gA APEX
APEX[SLOW_SOFT_MS]=750
APEX[SLOW_HARD_MS]=2000
APEX[STARTUP_BURST]=1
APEX[SHOW_AAR]=1
APEX[SHOW_CONTEXT_BURST]=1
APEX[SHOW_VCS]=1
APEX[SHOW_INTEL]=1
APEX[SHOW_JOBS]=1
APEX[SHOW_RO]=1
APEX[GIT_AHEAD_BEHIND]=1
# Ops commands (also match wrappers like sudo/doas/command)
APEX[OPS_RE]='^((sudo|doas|command)[[:space:]]+)*((pacman|yay|paru|apt|dnf|brew|systemctl|docker|kubectl|helm|git))([[:space:]]|$)'
# Session-ish commands (spawn a subshell; exit codes are often “not a failure”)
APEX[SESSION_RE]='^((sudo|doas|command)[[:space:]]+)*chezmoi[[:space:]]+cd([[:space:]]|$)'
# -----------------------------------------------------------------------------
# 4) STATE
# -----------------------------------------------------------------------------
typeset -gF apex_cmd_start=0.0
typeset -g apex_last_cmd=""
typeset -g apex_has_run_cmd=0
typeset -g apex_startup_done=0
typeset -g apex_pwd_changed=1
# Sticky intel
typeset -g apex_venv_name=""
typeset -g apex_target_sig=""
typeset -g apex_mode_sig=""
# Git state
typeset -g apex_in_git=0
typeset -g apex_git_branch=""
typeset -g apex_git_dirty_wt=0
typeset -g apex_git_dirty_ix=0
typeset -g apex_git_untracked=0
typeset -g apex_git_conflict=0
typeset -g apex_git_op=""
typeset -g apex_git_up_ok=0
typeset -g apex_git_ahead=0
typeset -g apex_git_behind=0
typeset -g apex_git_stash=0
typeset -g apex_git_root=""
typeset -g apex_git_dir=""
# Radar previous snapshots (transition detection)
typeset -g apex_prev_in_git=-1
typeset -g apex_prev_git_branch=""
typeset -g apex_prev_git_op=""
typeset -g apex_prev_venv_name=""
typeset -g apex_prev_target_sig=""
typeset -g apex_prev_proj_sig=""
# -----------------------------------------------------------------------------
# 5) UTILITIES
# -----------------------------------------------------------------------------
apex__short_cmd() {
local s="$1"
s="${s//$'
'/ }"
s="${s#"${s%%[![:space:]]*}"}" # ltrim
s="${s%"${s##*[![:space:]]}"}" # rtrim
print -r -- "${s[1,90]}"
}
apex__project_sig() {
local s=""
[[ -f package.json ]] && s+="node"
[[ -f pnpm-lock.yaml ]] && s+="+pnpm"
[[ -f bun.lockb ]] && s+="+bun"
[[ -f yarn.lock ]] && s+="+yarn"
[[ -f pyproject.toml || -f requirements.txt ]] && s+="${s:+ }py"
[[ -f uv.lock ]] && s+="+uv"
[[ -f Cargo.toml ]] && s+="${s:+ }rust"
[[ -f go.mod ]] && s+="${s:+ }go"
[[ -n "$s" ]] && print -r -- "$s"
}
apex__escape_prompt() {
local s="$1"
s="${s//\\%/%%}"
print -r -- "$s"
}
apex__now_float() {
if [[ -n "${EPOCHREALTIME:-}" ]]; then
print -r -- "$EPOCHREALTIME"
elif [[ -n "${EPOCHSECONDS:-}" ]]; then
print -r -- "${EPOCHSECONDS}.0"
else
print -r -- "0.0"
fi
}
apex__find_git_root() {
local dir="$PWD"
local git_root=""
local git_dir=""
while [[ -n "$dir" ]]; do
if [[ -d "$dir/.git" ]]; then
git_root="$dir"
git_dir="$dir/.git"
break
elif [[ -f "$dir/.git" ]]; then
local line
line="$(<"$dir/.git")"
if [[ "$line" == gitdir:* ]]; then
git_root="$dir"
git_dir="${line#gitdir: }"
[[ "$git_dir" != /* ]] && git_dir="$dir/$git_dir"
break
fi
fi
[[ "$dir" == "/" ]] && break
dir="${dir:h}"
done
[[ -n "$git_root" ]] && print -r -- "${git_root}|${git_dir}"
}
# -----------------------------------------------------------------------------
# 6) INTEL (sticky; updated each prompt)
# -----------------------------------------------------------------------------
apex_update_intel() {
# Target (cheap env-based; no kubectl calls)
if [[ -n "$AWS_PROFILE" ]]; then
apex_target_sig="aws:${AWS_PROFILE}"
elif [[ -n "$GOOGLE_CLOUD_PROJECT" ]]; then
apex_target_sig="gcp:${GOOGLE_CLOUD_PROJECT}"
elif [[ -n "$KUBE_CONTEXT" ]]; then
apex_target_sig="kube:${KUBE_CONTEXT}"
else
apex_target_sig=""
fi
# Mode
if [[ -n "$IN_NIX_SHELL" ]]; then
apex_mode_sig="nix"
elif [[ -n "$DIRENV_DIR" ]]; then
apex_mode_sig="direnv"
elif [[ -f /run/.containerenv || -f /.dockerenv ]]; then
apex_mode_sig="ctr"
else
apex_mode_sig=""
fi
# Venv
apex_venv_name=""
if [[ -n "$VIRTUAL_ENV" ]]; then
apex_venv_name="$(basename "$VIRTUAL_ENV")"
elif [[ -n "$CONDA_DEFAULT_ENV" ]]; then
apex_venv_name="$CONDA_DEFAULT_ENV"
fi
}
# -----------------------------------------------------------------------------
# 7) GIT
# -----------------------------------------------------------------------------
apex_git_update() {
apex_in_git=0
apex_git_branch=""
apex_git_dirty_wt=0
apex_git_dirty_ix=0
apex_git_untracked=0
apex_git_conflict=0
apex_git_op=""
apex_git_up_ok=0
apex_git_ahead=0
apex_git_behind=0
apex_git_stash=0
local status_out
status_out="$(command git status --porcelain=2 --branch 2>/dev/null)" || {
apex_git_root=""
apex_git_dir=""
return
}
apex_in_git=1
if (( apex_pwd_changed )) || [[ -z "$apex_git_root" ]]; then
local root_info
root_info="$(apex__find_git_root)"
if [[ -n "$root_info" ]]; then
apex_git_root="${root_info%%|*}"
apex_git_dir="${root_info#*|}"
else
apex_git_root=""
apex_git_dir=""
fi
fi
local branch_head="" branch_oid="" upstream=""
local xy="" ix="" wt=""
local line
while IFS= read -r line; do
case "$line" in
\#\ branch.head\ *)
branch_head="${line#\# branch.head }"
;;
\#\ branch.oid\ *)
branch_oid="${line#\# branch.oid }"
;;
\#\ branch.upstream\ *)
upstream="${line#\# branch.upstream }"
;;
\#\ branch.ab\ *)
local ab a b
ab="${line#\# branch.ab }"
IFS=' ' read -r a b <<<"$ab"
a="${a#+}"
b="${b#-}"
apex_git_ahead="${a:-0}"
apex_git_behind="${b:-0}"
;;
1\ *|2\ *)
xy="${line[3,4]}"
ix="${xy[1]}"
wt="${xy[2]}"
[[ "$ix" != "." ]] && apex_git_dirty_ix=1
[[ "$wt" != "." ]] && apex_git_dirty_wt=1
;;
u\ *)
apex_git_conflict=1
apex_git_dirty_ix=1
apex_git_dirty_wt=1
;;
\?\ *)
apex_git_untracked=1
;;
esac
done <<<"$status_out"
if [[ -n "$branch_head" && "$branch_head" != "(detached)" && "$branch_head" != "HEAD" ]]; then
apex_git_branch="$branch_head"
elif [[ -n "$branch_oid" ]]; then
apex_git_branch="${branch_oid[1,7]}"
fi
if [[ -n "$apex_git_dir" ]]; then
[[ -d "$apex_git_dir/rebase-apply" || -d "$apex_git_dir/rebase-merge" ]] && apex_git_op="rebase"
[[ -f "$apex_git_dir/MERGE_HEAD" ]] && apex_git_op="merge"
[[ -f "$apex_git_dir/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick"
[[ -f "$apex_git_dir/BISECT_LOG" ]] && apex_git_op="bisect"
if [[ -f "$apex_git_dir/logs/refs/stash" ]]; then
local -a stash_lines
stash_lines=(${(f)"$(<"$apex_git_dir/logs/refs/stash")"})
apex_git_stash=$#stash_lines
elif [[ -f "$apex_git_dir/refs/stash" ]]; then
apex_git_stash=1
fi
fi
(( apex_git_conflict )) && apex_git_op="conflict"
if [[ -n "$upstream" && "$upstream" != "(gone)" ]]; then
if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 && apex_git_untracked == 0 && apex_git_conflict == 0 && apex_git_stash == 0 )) \
&& [[ -z "$apex_git_op" ]]; then
[[ "$apex_git_behind" == "0" && "$apex_git_ahead" == "0" ]] && apex_git_up_ok=1
fi
fi
}
# -----------------------------------------------------------------------------
# 8) LEFT PROMPTLINE: IDENTITY + TERRITORY
# -----------------------------------------------------------------------------
apex_identity() {
local is_root=0 is_ssh=0 color label
(( EUID == 0 )) && is_root=1
[[ -n "$SSH_CONNECTION$SSH_TTY" ]] && is_ssh=1
if (( is_root )); then
color="${C[PURPLE]}"
if (( is_ssh )); then
label="${I[ROOT]} @%m"
else
label="${I[ROOT]} root"
fi
elif (( is_ssh )); then
color="${C[CYAN]}"
label="${I[SSH]} %n@%m"
else
return 0
fi
print -n "%F{${color}}${S[PL_L]}%f%K{${color}}%F{${C[VOID]}}%B ${label} %b%f%k%F{${color}}${S[PL_R]}%f "
}
apex_territory() {
print -n "%F{${C[FOCUS]}}${S[PL_L]}%f%K{${C[FOCUS]}}%F{${C[VOID]}}%B ${I[OS]}%b %F{${C[WHITE]}}%B%~%b %f%k%F{${C[FOCUS]}}${S[PL_R]}%f"
}
# -----------------------------------------------------------------------------
# 9) RIGHT PROMPT (RPROMPT): INTEL + VCS + FRICTION
# -----------------------------------------------------------------------------
apex_intel_r() {
(( APEX[SHOW_INTEL] )) || return 0
if [[ -n "$apex_target_sig" ]]; then
print -n "%F{${C[CYAN]}}(${apex_target_sig})%f"
elif [[ -n "$apex_mode_sig" ]]; then
print -n "%F{${C[CYAN]}}(${apex_mode_sig})%f"
elif [[ -n "$apex_venv_name" ]]; then
print -n "%F{${C[CYAN]}}(${apex_venv_name})%f"
fi
}
apex_vcs_r() {
(( APEX[SHOW_VCS] )) || return 0
(( apex_in_git )) || return 0
local branch; branch="$(apex__escape_prompt "$apex_git_branch")"
if [[ -n "$apex_git_op" ]]; then
print -n "%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f"
return 0
fi
print -n "%F{${C[CYAN]}}${I[GIT]} ${branch}%f"
local mark=""
(( apex_git_dirty_ix )) && mark+="+"
(( apex_git_dirty_wt )) && mark+="!"
(( apex_git_untracked )) && mark+="?"
[[ -n "$mark" ]] && print -n "%F{${C[GOLD]}} ${mark}%f"
(( apex_git_stash > 0 )) && print -n "%F{${C[MUTED]}} s${apex_git_stash}%f"
(( apex_git_up_ok )) && print -n "%F{${C[OK]}} ✓%f"
if (( APEX[GIT_AHEAD_BEHIND] )); then
(( apex_git_ahead > 0 )) && print -n "%F{${C[MUTED]}} ⇡${apex_git_ahead}%f"
(( apex_git_behind > 0 )) && print -n "%F{${C[MUTED]}} ⇣${apex_git_behind}%f"
fi
}
apex_friction_r() {
if (( APEX[SHOW_RO] )); then
local ro=0
[[ ! -w . ]] && ro=1
if (( apex_in_git )) && [[ -n "$apex_git_root" && ! -w "$apex_git_root" ]]; then
ro=1
fi
if (( ro )); then
print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f"
return 0
fi
fi
if (( APEX[SHOW_JOBS] )); then
local -a job_pids
job_pids=(${(f)"$(jobs -p 2>/dev/null)"})
local jc=$#job_pids
if (( jc > 0 )); then
print -n "%F{${C[MUTED]}}${I[JOBS]} ${jc}%f"
return 0
fi
fi
}
build_rprompt() {
local s out=""
local sep="%F{${C[MUTED]}} ${S[DOT]} %f"
s="$(apex_intel_r)"; [[ -n "$s" ]] && out+="$s"
s="$(apex_vcs_r)"; [[ -n "$s" ]] && out+="${out:+$sep}$s"
s="$(apex_friction_r)"; [[ -n "$s" ]] && out+="${out:+$sep}$s"
[[ -n "$out" ]] && out="%F{${C[MUTED]}}[%f${out}%F{${C[MUTED]}}]%f"
print -n "$out"
}
# -----------------------------------------------------------------------------
# 10) RADAR (precmd)
# -----------------------------------------------------------------------------
apex_radar_aar() {
(( APEX[SHOW_AAR] )) || return 0
local ec=$1 cmd="$2" dur="$3"
local -i ms=${4:-0}
local show=0
(( ec != 0 )) && show=1
[[ -n "$dur" ]] && show=1
[[ "$cmd" =~ ${APEX[OPS_RE]} ]] && show=1
(( show )) || return 0
local short; short="$(apex__short_cmd "$cmd")"
short="$(apex__escape_prompt "$short")"
local dur_color="${C[MUTED]}"
(( ms >= ${APEX[SLOW_HARD_MS]} )) && dur_color="${C[GOLD]}"
local dur_chunk=""
if [[ -n "$dur" ]]; then
if (( ms >= ${APEX[SLOW_HARD_MS]} )); then
dur_chunk=" %F{${dur_color}}%B${dur}%b%f"
else
dur_chunk=" %F{${dur_color}}${dur}%f"
fi
fi
# Session commands: don't scream in red for “rc:1”
if [[ "$cmd" =~ ${APEX[SESSION_RE]} ]]; then
if (( ec == 0 )); then
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[OK]}}${I[RET]}%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
else
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[GOLD]}}${I[RET]}%f %F{${C[WHITE]}}${short}%f %F{${C[MUTED]}}rc:${ec}%f${dur_chunk}"
fi
return 0
fi
if (( ec == 0 )); then
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[OK]}}✓%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
return 0
fi
# Signals: 128 + signal number
case $ec in
130) # SIGINT (Ctrl+C)
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[CYAN]}}^C%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
141) # SIGPIPE
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[MUTED]}}PIPE%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
143) # SIGTERM
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[GOLD]}}TERM%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
*)
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[ALERT]}}✘ ${ec}%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
esac
}
apex_radar_context_burst() {
(( APEX[SHOW_CONTEXT_BURST] )) || return 0
local proj_sig; proj_sig="$(apex__project_sig 2>/dev/null || print -r -- "")"
local emit=0
if (( apex_startup_done == 0 )); then
(( APEX[STARTUP_BURST] )) && emit=1
fi
(( apex_pwd_changed )) && emit=1
[[ "$apex_venv_name" != "$apex_prev_venv_name" ]] && emit=1
[[ "$apex_target_sig" != "$apex_prev_target_sig" ]] && emit=1
(( apex_in_git != apex_prev_in_git )) && emit=1
[[ "$apex_git_branch" != "$apex_prev_git_branch" ]] && emit=1
[[ "$apex_git_op" != "$apex_prev_git_op" ]] && emit=1
[[ "$proj_sig" != "$apex_prev_proj_sig" ]] && emit=1
(( emit )) || return 0
# If nothing to say, say nothing.
if [[ -z "$proj_sig" && -z "$apex_venv_name" && -z "$apex_target_sig" ]] && (( apex_in_git == 0 )); then
apex_pwd_changed=0
apex_startup_done=1
return 0
fi
local out="%F{${C[MUTED]}}${I[RADAR]}%f "
# Git first
if (( apex_in_git )); then
local branch; branch="$(apex__escape_prompt "$apex_git_branch")"
if [[ -n "$apex_git_op" ]]; then
out+="%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f"
else
out+="%F{${C[CYAN]}}${I[GIT]} ${branch}%f"
fi
fi
[[ -n "$proj_sig" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[MUTED]}}${proj_sig}%f"
[[ -n "$apex_venv_name" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[CYAN]}}(${apex_venv_name})%f"
[[ -n "$apex_target_sig" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[CYAN]}}(${apex_target_sig})%f"
print -P "$out"
apex_prev_venv_name="$apex_venv_name"
apex_prev_target_sig="$apex_target_sig"
apex_prev_in_git="$apex_in_git"
apex_prev_git_branch="$apex_git_branch"
apex_prev_git_op="$apex_git_op"
apex_prev_proj_sig="$proj_sig"
apex_pwd_changed=0
apex_startup_done=1
}
# -----------------------------------------------------------------------------
# 11) HOOKS
# -----------------------------------------------------------------------------
apex_preexec_hook() {
apex_has_run_cmd=1
apex_cmd_start="$(apex__now_float)"
apex_last_cmd="$1"
}
apex_chpwd_hook() {
apex_pwd_changed=1
}
apex_precmd_hook() {
local ec=$?
apex_update_intel
apex_git_update
# Did a command actually run since the last prompt?
local ran=0
(( apex_has_run_cmd )) && ran=1
if (( ran )); then
local now; now="$(apex__now_float)"
local -i ms=0
local -F delta=0.0
if [[ -n "$now" ]]; then
delta=$(( now - apex_cmd_start ))
(( delta < 0 )) && delta=0
ms=$(( delta * 1000 ))
fi
# Show time if: slow OR ops OR failed.
local dur=""
if (( ms >= ${APEX[SLOW_SOFT_MS]} )) || [[ "$apex_last_cmd" =~ ${APEX[OPS_RE]} ]] || (( ec != 0 )); then
dur="$(printf "%.2fs" $(( ms / 1000.0 )))"
fi
apex_radar_aar $ec "$apex_last_cmd" "$dur" $ms
apex_has_run_cmd=0
# Spacer between AAR and context burst / prompt.
print -r -- ""
fi
apex_radar_context_burst
}
autoload -Uz add-zsh-hook
add-zsh-hook preexec apex_preexec_hook
add-zsh-hook precmd apex_precmd_hook
add-zsh-hook chpwd apex_chpwd_hook
# -----------------------------------------------------------------------------
# 12) PROMPT BUILD
# -----------------------------------------------------------------------------
build_prompt() {
local ec=$?
# Line 1: identity + territory (left)
print -n "$(apex_identity)"
print -n "$(apex_territory)"
print -n $'
'
# Line 2: trigger posture
if (( EUID == 0 )); then
# Sacred purple is always form-coded: bold, never bare
print -n "%F{${C[PURPLE]}}%B%b%f "
elif (( ec != 0 )); then
print -n "%F{${C[ALERT]}}%f "
else
print -n "%F{${C[CYAN]}}%f "
fi
}
PROMPT='$(build_prompt)'
RPROMPT='$(build_rprompt)'
+631
View File
@@ -0,0 +1,631 @@
# Apex Neon — Predator Cockpit (Zsh) — v2
# Two-bus design:
# [precmd radar] -> after-action + context bursts (event-driven)
# [promptline] -> LEFT: identity + territory
# RIGHT: intel + vcs + friction (stable)
setopt prompt_subst
setopt no_beep
zmodload zsh/datetime 2>/dev/null
# -----------------------------------------------------------------------------
# 1) PALETTE (Apex Neon DNA)
# -----------------------------------------------------------------------------
typeset -gA C
C[VOID]="#070709"
C[WHITE]="#e6e8ec"
C[MUTED]="#8b909c"
C[FOCUS]="#f783d4"
C[CYAN]="#00eaff"
C[GOLD]="#ffb700"
C[OK]="#00ff99"
C[PURPLE]="#a550f9"
C[ALERT]="#ff0044"
# -----------------------------------------------------------------------------
# 1b) PLUGIN COLORS
# -----------------------------------------------------------------------------
# zsh-autosuggestions: ghost text from history (subtle, intentionally dim)
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#8b909c"
# zsh-history-substring-search
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND="fg=#00eaff,bold"
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND="fg=#ff0044,bold"
# -----------------------------------------------------------------------------
# 2) ICONS / GLYPHS (Nerd Font optional)
# -----------------------------------------------------------------------------
typeset -gA I
I[OS]=""
I[SSH]=""
I[ROOT]=""
I[GIT]=""
I[JOBS]=""
I[RADAR]="⌁"
I[RET]="↩"
typeset -gA S
S[PL_L]=""
S[PL_R]=""
S[DOT]="·"
# -----------------------------------------------------------------------------
# 3) CONFIG
# -----------------------------------------------------------------------------
typeset -gA APEX
APEX[SLOW_SOFT_MS]=750
APEX[SLOW_HARD_MS]=2000
APEX[STARTUP_BURST]=1
APEX[SHOW_AAR]=1
APEX[SHOW_CONTEXT_BURST]=1
APEX[SHOW_VCS]=1
APEX[SHOW_INTEL]=1
APEX[SHOW_JOBS]=1
APEX[SHOW_RO]=1
APEX[GIT_AHEAD_BEHIND]=1
# Ops commands (also match wrappers like sudo/doas/command)
APEX[OPS_RE]='^((sudo|doas|command)[[:space:]]+)*((pacman|yay|paru|apt|dnf|brew|systemctl|docker|kubectl|helm|git))([[:space:]]|$)'
# Session-ish commands (spawn a subshell; exit codes are often “not a failure”)
APEX[SESSION_RE]='^((sudo|doas|command)[[:space:]]+)*chezmoi[[:space:]]+cd([[:space:]]|$)'
# -----------------------------------------------------------------------------
# 4) STATE
# -----------------------------------------------------------------------------
typeset -gF apex_cmd_start=0.0
typeset -g apex_last_cmd=""
typeset -g apex_has_run_cmd=0
typeset -g apex_startup_done=0
typeset -g apex_pwd_changed=1
# Sticky intel
typeset -g apex_venv_name=""
typeset -g apex_target_sig=""
typeset -g apex_mode_sig=""
# Git state
typeset -g apex_in_git=0
typeset -g apex_git_branch=""
typeset -g apex_git_dirty_wt=0
typeset -g apex_git_dirty_ix=0
typeset -g apex_git_untracked=0
typeset -g apex_git_conflict=0
typeset -g apex_git_op=""
typeset -g apex_git_up_ok=0
typeset -g apex_git_ahead=0
typeset -g apex_git_behind=0
typeset -g apex_git_stash=0
typeset -g apex_git_root=""
typeset -g apex_git_dir=""
# Radar previous snapshots (transition detection)
typeset -g apex_prev_in_git=-1
typeset -g apex_prev_git_branch=""
typeset -g apex_prev_git_op=""
typeset -g apex_prev_venv_name=""
typeset -g apex_prev_target_sig=""
typeset -g apex_prev_proj_sig=""
# -----------------------------------------------------------------------------
# 5) UTILITIES
# -----------------------------------------------------------------------------
apex__short_cmd() {
local s="$1"
s="${s//$'
'/ }"
s="${s#"${s%%[![:space:]]*}"}" # ltrim
s="${s%"${s##*[![:space:]]}"}" # rtrim
print -r -- "${s[1,90]}"
}
apex__project_sig() {
local s=""
[[ -f package.json ]] && s+="node"
[[ -f pnpm-lock.yaml ]] && s+="+pnpm"
[[ -f bun.lockb ]] && s+="+bun"
[[ -f yarn.lock ]] && s+="+yarn"
[[ -f pyproject.toml || -f requirements.txt ]] && s+="${s:+ }py"
[[ -f uv.lock ]] && s+="+uv"
[[ -f Cargo.toml ]] && s+="${s:+ }rust"
[[ -f go.mod ]] && s+="${s:+ }go"
[[ -n "$s" ]] && print -r -- "$s"
}
apex__escape_prompt() {
local s="$1"
s="${s//\\%/%%}"
print -r -- "$s"
}
apex__now_float() {
if [[ -n "${EPOCHREALTIME:-}" ]]; then
print -r -- "$EPOCHREALTIME"
elif [[ -n "${EPOCHSECONDS:-}" ]]; then
print -r -- "${EPOCHSECONDS}.0"
else
print -r -- "0.0"
fi
}
apex__find_git_root() {
local dir="$PWD"
local git_root=""
local git_dir=""
while [[ -n "$dir" ]]; do
if [[ -d "$dir/.git" ]]; then
git_root="$dir"
git_dir="$dir/.git"
break
elif [[ -f "$dir/.git" ]]; then
local line
line="$(<"$dir/.git")"
if [[ "$line" == gitdir:* ]]; then
git_root="$dir"
git_dir="${line#gitdir: }"
[[ "$git_dir" != /* ]] && git_dir="$dir/$git_dir"
break
fi
fi
[[ "$dir" == "/" ]] && break
dir="${dir:h}"
done
[[ -n "$git_root" ]] && print -r -- "${git_root}|${git_dir}"
}
# -----------------------------------------------------------------------------
# 6) INTEL (sticky; updated each prompt)
# -----------------------------------------------------------------------------
apex_update_intel() {
# Target (cheap env-based; no kubectl calls)
if [[ -n "$AWS_PROFILE" ]]; then
apex_target_sig="aws:${AWS_PROFILE}"
elif [[ -n "$GOOGLE_CLOUD_PROJECT" ]]; then
apex_target_sig="gcp:${GOOGLE_CLOUD_PROJECT}"
elif [[ -n "$KUBE_CONTEXT" ]]; then
apex_target_sig="kube:${KUBE_CONTEXT}"
else
apex_target_sig=""
fi
# Mode
if [[ -n "$IN_NIX_SHELL" ]]; then
apex_mode_sig="nix"
elif [[ -n "$DIRENV_DIR" ]]; then
apex_mode_sig="direnv"
elif [[ -f /run/.containerenv || -f /.dockerenv ]]; then
apex_mode_sig="ctr"
else
apex_mode_sig=""
fi
# Venv
apex_venv_name=""
if [[ -n "$VIRTUAL_ENV" ]]; then
apex_venv_name="$(basename "$VIRTUAL_ENV")"
elif [[ -n "$CONDA_DEFAULT_ENV" ]]; then
apex_venv_name="$CONDA_DEFAULT_ENV"
fi
}
# -----------------------------------------------------------------------------
# 7) GIT
# -----------------------------------------------------------------------------
apex_git_update() {
apex_in_git=0
apex_git_branch=""
apex_git_dirty_wt=0
apex_git_dirty_ix=0
apex_git_untracked=0
apex_git_conflict=0
apex_git_op=""
apex_git_up_ok=0
apex_git_ahead=0
apex_git_behind=0
apex_git_stash=0
local status_out
status_out="$(command git status --porcelain=2 --branch 2>/dev/null)" || {
apex_git_root=""
apex_git_dir=""
return
}
apex_in_git=1
if (( apex_pwd_changed )) || [[ -z "$apex_git_root" ]]; then
local root_info
root_info="$(apex__find_git_root)"
if [[ -n "$root_info" ]]; then
apex_git_root="${root_info%%|*}"
apex_git_dir="${root_info#*|}"
else
apex_git_root=""
apex_git_dir=""
fi
fi
local branch_head="" branch_oid="" upstream=""
local xy="" ix="" wt=""
local line
while IFS= read -r line; do
case "$line" in
\#\ branch.head\ *)
branch_head="${line#\# branch.head }"
;;
\#\ branch.oid\ *)
branch_oid="${line#\# branch.oid }"
;;
\#\ branch.upstream\ *)
upstream="${line#\# branch.upstream }"
;;
\#\ branch.ab\ *)
local ab a b
ab="${line#\# branch.ab }"
IFS=' ' read -r a b <<<"$ab"
a="${a#+}"
b="${b#-}"
apex_git_ahead="${a:-0}"
apex_git_behind="${b:-0}"
;;
1\ *|2\ *)
xy="${line[3,4]}"
ix="${xy[1]}"
wt="${xy[2]}"
[[ "$ix" != "." ]] && apex_git_dirty_ix=1
[[ "$wt" != "." ]] && apex_git_dirty_wt=1
;;
u\ *)
apex_git_conflict=1
apex_git_dirty_ix=1
apex_git_dirty_wt=1
;;
\?\ *)
apex_git_untracked=1
;;
esac
done <<<"$status_out"
if [[ -n "$branch_head" && "$branch_head" != "(detached)" && "$branch_head" != "HEAD" ]]; then
apex_git_branch="$branch_head"
elif [[ -n "$branch_oid" ]]; then
apex_git_branch="${branch_oid[1,7]}"
fi
if [[ -n "$apex_git_dir" ]]; then
[[ -d "$apex_git_dir/rebase-apply" || -d "$apex_git_dir/rebase-merge" ]] && apex_git_op="rebase"
[[ -f "$apex_git_dir/MERGE_HEAD" ]] && apex_git_op="merge"
[[ -f "$apex_git_dir/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick"
[[ -f "$apex_git_dir/BISECT_LOG" ]] && apex_git_op="bisect"
if [[ -f "$apex_git_dir/logs/refs/stash" ]]; then
local -a stash_lines
stash_lines=(${(f)"$(<"$apex_git_dir/logs/refs/stash")"})
apex_git_stash=$#stash_lines
elif [[ -f "$apex_git_dir/refs/stash" ]]; then
apex_git_stash=1
fi
fi
(( apex_git_conflict )) && apex_git_op="conflict"
if [[ -n "$upstream" && "$upstream" != "(gone)" ]]; then
if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 && apex_git_untracked == 0 && apex_git_conflict == 0 && apex_git_stash == 0 )) \
&& [[ -z "$apex_git_op" ]]; then
[[ "$apex_git_behind" == "0" && "$apex_git_ahead" == "0" ]] && apex_git_up_ok=1
fi
fi
}
# -----------------------------------------------------------------------------
# 8) LEFT PROMPTLINE: IDENTITY + TERRITORY
# -----------------------------------------------------------------------------
apex_identity() {
local is_root=0 is_ssh=0 color label
(( EUID == 0 )) && is_root=1
[[ -n "$SSH_CONNECTION$SSH_TTY" ]] && is_ssh=1
if (( is_root )); then
color="${C[PURPLE]}"
if (( is_ssh )); then
label="${I[ROOT]} @%m"
else
label="${I[ROOT]} root"
fi
elif (( is_ssh )); then
color="${C[CYAN]}"
label="${I[SSH]} %n@%m"
else
return 0
fi
print -n "%F{${color}}${S[PL_L]}%f%K{${color}}%F{${C[VOID]}}%B ${label} %b%f%k%F{${color}}${S[PL_R]}%f "
}
apex_territory() {
print -n "%F{${C[FOCUS]}}${S[PL_L]}%f%K{${C[FOCUS]}}%F{${C[VOID]}}%B ${I[OS]}%b %F{${C[WHITE]}}%B%~%b %f%k%F{${C[FOCUS]}}${S[PL_R]}%f"
}
# -----------------------------------------------------------------------------
# 9) RIGHT PROMPT (RPROMPT): INTEL + VCS + FRICTION
# -----------------------------------------------------------------------------
apex_intel_r() {
(( APEX[SHOW_INTEL] )) || return 0
if [[ -n "$apex_target_sig" ]]; then
print -n "%F{${C[CYAN]}}(${apex_target_sig})%f"
elif [[ -n "$apex_mode_sig" ]]; then
print -n "%F{${C[CYAN]}}(${apex_mode_sig})%f"
elif [[ -n "$apex_venv_name" ]]; then
print -n "%F{${C[CYAN]}}(${apex_venv_name})%f"
fi
}
apex_vcs_r() {
(( APEX[SHOW_VCS] )) || return 0
(( apex_in_git )) || return 0
local branch; branch="$(apex__escape_prompt "$apex_git_branch")"
if [[ -n "$apex_git_op" ]]; then
print -n "%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f"
return 0
fi
print -n "%F{${C[CYAN]}}${I[GIT]} ${branch}%f"
local mark=""
(( apex_git_dirty_ix )) && mark+="+"
(( apex_git_dirty_wt )) && mark+="!"
(( apex_git_untracked )) && mark+="?"
[[ -n "$mark" ]] && print -n "%F{${C[GOLD]}} ${mark}%f"
(( apex_git_stash > 0 )) && print -n "%F{${C[MUTED]}} s${apex_git_stash}%f"
(( apex_git_up_ok )) && print -n "%F{${C[OK]}} ✓%f"
if (( APEX[GIT_AHEAD_BEHIND] )); then
(( apex_git_ahead > 0 )) && print -n "%F{${C[MUTED]}} ⇡${apex_git_ahead}%f"
(( apex_git_behind > 0 )) && print -n "%F{${C[MUTED]}} ⇣${apex_git_behind}%f"
fi
}
apex_friction_r() {
if (( APEX[SHOW_RO] )); then
local ro=0
[[ ! -w . ]] && ro=1
if (( apex_in_git )) && [[ -n "$apex_git_root" && ! -w "$apex_git_root" ]]; then
ro=1
fi
if (( ro )); then
print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f"
return 0
fi
fi
if (( APEX[SHOW_JOBS] )); then
local -a job_pids
job_pids=(${(f)"$(jobs -p 2>/dev/null)"})
local jc=$#job_pids
if (( jc > 0 )); then
print -n "%F{${C[MUTED]}}${I[JOBS]} ${jc}%f"
return 0
fi
fi
}
build_rprompt() {
local s out=""
local sep="%F{${C[MUTED]}} ${S[DOT]} %f"
s="$(apex_intel_r)"; [[ -n "$s" ]] && out+="$s"
s="$(apex_vcs_r)"; [[ -n "$s" ]] && out+="${out:+$sep}$s"
s="$(apex_friction_r)"; [[ -n "$s" ]] && out+="${out:+$sep}$s"
[[ -n "$out" ]] && out="%F{${C[MUTED]}}[%f${out}%F{${C[MUTED]}}]%f"
print -n "$out"
}
# -----------------------------------------------------------------------------
# 10) RADAR (precmd)
# -----------------------------------------------------------------------------
apex_radar_aar() {
(( APEX[SHOW_AAR] )) || return 0
local ec=$1 cmd="$2" dur="$3"
local -i ms=${4:-0}
local show=0
(( ec != 0 )) && show=1
[[ -n "$dur" ]] && show=1
[[ "$cmd" =~ ${APEX[OPS_RE]} ]] && show=1
(( show )) || return 0
local short; short="$(apex__short_cmd "$cmd")"
short="$(apex__escape_prompt "$short")"
local dur_color="${C[MUTED]}"
(( ms >= ${APEX[SLOW_HARD_MS]} )) && dur_color="${C[GOLD]}"
local dur_chunk=""
if [[ -n "$dur" ]]; then
if (( ms >= ${APEX[SLOW_HARD_MS]} )); then
dur_chunk=" %F{${dur_color}}%B${dur}%b%f"
else
dur_chunk=" %F{${dur_color}}${dur}%f"
fi
fi
# Session commands: don't scream in red for “rc:1”
if [[ "$cmd" =~ ${APEX[SESSION_RE]} ]]; then
if (( ec == 0 )); then
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[OK]}}${I[RET]}%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
else
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[GOLD]}}${I[RET]}%f %F{${C[WHITE]}}${short}%f %F{${C[MUTED]}}rc:${ec}%f${dur_chunk}"
fi
return 0
fi
if (( ec == 0 )); then
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[OK]}}✓%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
return 0
fi
# Signals: 128 + signal number
case $ec in
130) # SIGINT (Ctrl+C)
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[CYAN]}}^C%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
141) # SIGPIPE
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[MUTED]}}PIPE%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
143) # SIGTERM
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[GOLD]}}TERM%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
*)
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[ALERT]}}✘ ${ec}%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
esac
}
apex_radar_context_burst() {
(( APEX[SHOW_CONTEXT_BURST] )) || return 0
local proj_sig; proj_sig="$(apex__project_sig 2>/dev/null || print -r -- "")"
local emit=0
if (( apex_startup_done == 0 )); then
(( APEX[STARTUP_BURST] )) && emit=1
fi
(( apex_pwd_changed )) && emit=1
[[ "$apex_venv_name" != "$apex_prev_venv_name" ]] && emit=1
[[ "$apex_target_sig" != "$apex_prev_target_sig" ]] && emit=1
(( apex_in_git != apex_prev_in_git )) && emit=1
[[ "$apex_git_branch" != "$apex_prev_git_branch" ]] && emit=1
[[ "$apex_git_op" != "$apex_prev_git_op" ]] && emit=1
[[ "$proj_sig" != "$apex_prev_proj_sig" ]] && emit=1
(( emit )) || return 0
# If nothing to say, say nothing.
if [[ -z "$proj_sig" && -z "$apex_venv_name" && -z "$apex_target_sig" ]] && (( apex_in_git == 0 )); then
apex_pwd_changed=0
apex_startup_done=1
return 0
fi
local out="%F{${C[MUTED]}}${I[RADAR]}%f "
# Git first
if (( apex_in_git )); then
local branch; branch="$(apex__escape_prompt "$apex_git_branch")"
if [[ -n "$apex_git_op" ]]; then
out+="%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f"
else
out+="%F{${C[CYAN]}}${I[GIT]} ${branch}%f"
fi
fi
[[ -n "$proj_sig" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[MUTED]}}${proj_sig}%f"
[[ -n "$apex_venv_name" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[CYAN]}}(${apex_venv_name})%f"
[[ -n "$apex_target_sig" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[CYAN]}}(${apex_target_sig})%f"
print -P "$out"
apex_prev_venv_name="$apex_venv_name"
apex_prev_target_sig="$apex_target_sig"
apex_prev_in_git="$apex_in_git"
apex_prev_git_branch="$apex_git_branch"
apex_prev_git_op="$apex_git_op"
apex_prev_proj_sig="$proj_sig"
apex_pwd_changed=0
apex_startup_done=1
}
# -----------------------------------------------------------------------------
# 11) HOOKS
# -----------------------------------------------------------------------------
apex_preexec_hook() {
apex_has_run_cmd=1
apex_cmd_start="$(apex__now_float)"
apex_last_cmd="$1"
}
apex_chpwd_hook() {
apex_pwd_changed=1
}
apex_precmd_hook() {
local ec=$?
apex_update_intel
apex_git_update
# Did a command actually run since the last prompt?
local ran=0
(( apex_has_run_cmd )) && ran=1
if (( ran )); then
local now; now="$(apex__now_float)"
local -i ms=0
local -F delta=0.0
if [[ -n "$now" ]]; then
delta=$(( now - apex_cmd_start ))
(( delta < 0 )) && delta=0
ms=$(( delta * 1000 ))
fi
# Show time if: slow OR ops OR failed.
local dur=""
if (( ms >= ${APEX[SLOW_SOFT_MS]} )) || [[ "$apex_last_cmd" =~ ${APEX[OPS_RE]} ]] || (( ec != 0 )); then
dur="$(printf "%.2fs" $(( ms / 1000.0 )))"
fi
apex_radar_aar $ec "$apex_last_cmd" "$dur" $ms
apex_has_run_cmd=0
# Spacer between AAR and context burst / prompt.
print -r -- ""
fi
apex_radar_context_burst
}
autoload -Uz add-zsh-hook
add-zsh-hook preexec apex_preexec_hook
add-zsh-hook precmd apex_precmd_hook
add-zsh-hook chpwd apex_chpwd_hook
# -----------------------------------------------------------------------------
# 12) PROMPT BUILD
# -----------------------------------------------------------------------------
build_prompt() {
local ec=$?
# Line 1: identity + territory (left)
print -n "$(apex_identity)"
print -n "$(apex_territory)"
print -n $'
'
# Line 2: trigger posture
if (( EUID == 0 )); then
# Sacred purple is always form-coded: bold, never bare
print -n "%F{${C[PURPLE]}}%B%b%f "
elif (( ec != 0 )); then
print -n "%F{${C[ALERT]}}%f "
else
print -n "%F{${C[CYAN]}}%f "
fi
}
PROMPT='$(build_prompt)'
RPROMPT='$(build_rprompt)'
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
if ! command -v nvim >/dev/null 2>&1; then
echo "error: nvim not found on PATH" >&2
exit 1
fi
if [[ ! -f "${root}/dist/nvim/colors/apex-neon.lua" ]]; then
echo "error: missing dist/nvim/colors/apex-neon.lua; run 'uv run build.py'" >&2
exit 1
fi
cd "$root"
nvim --headless -u NONE -U NONE -c "lua dofile('${root}/scripts/nvim_audit.lua')"
+181
View File
@@ -0,0 +1,181 @@
local function out(msg)
vim.api.nvim_out_write(msg .. "\n")
end
local function err(msg)
vim.api.nvim_err_write(msg .. "\n")
end
if not vim.api.nvim_get_hl then
err("error: nvim_get_hl unavailable; require Neovim 0.9+")
vim.cmd("cquit")
end
local function load_theme()
local theme_path = vim.fn.getcwd() .. "/dist/nvim/colors/apex-neon.lua"
local ok, load_err = pcall(dofile, theme_path)
if not ok then
err("error: failed to load theme: " .. tostring(load_err))
err("hint: run 'uv run build.py' to regenerate dist/")
vim.cmd("cquit")
end
end
local function has_style(hl)
for key, value in pairs(hl) do
if key ~= "link" and key ~= "default" then
if type(value) ~= "boolean" or value then
return true
end
end
end
return false
end
local function get_hl(name)
local ok, hl = pcall(vim.api.nvim_get_hl, 0, { name = name, link = false })
if not ok then
return nil, "error"
end
return hl, nil
end
local function audit(groups)
local issues = {}
local default_links = {
Normal = true,
NONE = true,
}
for _, group in ipairs(groups) do
local hl, api_err = get_hl(group)
if api_err or not hl or next(hl) == nil then
table.insert(issues, "missing: " .. group)
elseif hl.link and default_links[hl.link] then
table.insert(issues, "default-link: " .. group .. " -> " .. hl.link)
elseif not hl.link and not has_style(hl) then
table.insert(issues, "empty: " .. group)
end
end
return issues
end
local groups = {
-- Pmenu
"Pmenu",
"PmenuSel",
"PmenuSbar",
"PmenuThumb",
"WildMenu",
-- LSP UI
"LspReferenceText",
"LspReferenceRead",
"LspReferenceWrite",
"LspSignatureActiveParameter",
"LspInlayHint",
-- Diagnostics (core + variants)
"DiagnosticError",
"DiagnosticWarn",
"DiagnosticInfo",
"DiagnosticHint",
"DiagnosticOk",
"DiagnosticDeprecated",
"DiagnosticUnnecessary",
"DiagnosticUnderlineError",
"DiagnosticUnderlineWarn",
"DiagnosticUnderlineInfo",
"DiagnosticUnderlineHint",
"DiagnosticUnderlineOk",
"DiagnosticVirtualTextError",
"DiagnosticVirtualTextWarn",
"DiagnosticVirtualTextInfo",
"DiagnosticVirtualTextHint",
"DiagnosticVirtualTextOk",
"DiagnosticVirtualLinesError",
"DiagnosticVirtualLinesWarn",
"DiagnosticVirtualLinesInfo",
"DiagnosticVirtualLinesHint",
"DiagnosticVirtualLinesOk",
"DiagnosticSignError",
"DiagnosticSignWarn",
"DiagnosticSignInfo",
"DiagnosticSignHint",
"DiagnosticSignOk",
"DiagnosticFloatingError",
"DiagnosticFloatingWarn",
"DiagnosticFloatingInfo",
"DiagnosticFloatingHint",
"DiagnosticFloatingOk",
-- Markup (Tree-sitter)
"@markup.heading",
"@markup.link",
"@markup.link.url",
"@markup.strong",
"@markup.italic",
"ApexMarkupStrong",
"ApexMarkupItalic",
"ApexMarkupLink",
-- LSP semantic tokens (types)
"@lsp.type.boolean",
"@lsp.type.builtinType",
"@lsp.type.class",
"@lsp.type.comment",
"@lsp.type.decorator",
"@lsp.type.enum",
"@lsp.type.enumMember",
"@lsp.type.event",
"@lsp.type.function",
"@lsp.type.interface",
"@lsp.type.keyword",
"@lsp.type.macro",
"@lsp.type.method",
"@lsp.type.modifier",
"@lsp.type.namespace",
"@lsp.type.number",
"@lsp.type.operator",
"@lsp.type.parameter",
"@lsp.type.property",
"@lsp.type.regexp",
"@lsp.type.string",
"@lsp.type.struct",
"@lsp.type.type",
"@lsp.type.typeParameter",
"@lsp.type.variable",
-- LSP semantic tokens (modifiers)
"@lsp.mod.deprecated",
"@lsp.mod.readonly",
"@lsp.mod.static",
"@lsp.mod.async",
-- LSP semantic tokens (typemods)
"@lsp.typemod.function.async",
"@lsp.typemod.method.async",
"@lsp.typemod.function.deprecated",
"@lsp.typemod.method.deprecated",
"@lsp.typemod.variable.deprecated",
"@lsp.typemod.variable.readonly",
"@lsp.typemod.parameter.readonly",
"@lsp.typemod.property.readonly",
"@lsp.typemod.variable.static",
"@lsp.typemod.property.static",
}
load_theme()
local issues = audit(groups)
if #issues == 0 then
out("nvim audit: ok (" .. tostring(#groups) .. " groups)")
vim.cmd("qa")
end
err("nvim audit: " .. tostring(#issues) .. " issue(s)")
for _, issue in ipairs(issues) do
err(issue)
end
vim.cmd("cquit")
+219
View File
@@ -0,0 +1,219 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
usage() {
cat <<'EOF'
Usage: scripts/release.sh <version> [options]
Options:
--repo <slug> Gitea repo slug (default: auto-detect)
--login <name> tea login name (default: tea default)
--notes <text> Release notes (single line)
--notes-file <file> Release notes file (applies to all apps)
--notes-dir <dir> Per-app notes dir; uses <app>.md or common.md
--no-push Skip git push
--dry-run Print actions without executing
-h, --help Show this help
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi
version="${1:-}"
shift || true
if [[ -z "$version" ]]; then
usage
exit 1
fi
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "error: version must be semver (e.g., 1.2.3)"
exit 1
fi
repo=""
login=""
notes=""
notes_file=""
notes_dir=""
no_push=0
dry_run=0
while [[ $# -gt 0 ]]; do
case "$1" in
--repo)
repo="$2"
shift 2
;;
--login)
login="$2"
shift 2
;;
--notes)
notes="$2"
shift 2
;;
--notes-file)
notes_file="$2"
shift 2
;;
--notes-dir)
notes_dir="$2"
shift 2
;;
--no-push)
no_push=1
shift
;;
--dry-run)
dry_run=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "error: unknown option: $1"
usage
exit 1
;;
esac
done
run() {
if (( dry_run )); then
echo "+ $*"
else
"$@"
fi
}
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "error: not inside a git repository"
exit 1
fi
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "error: working tree not clean; commit or stash first"
exit 1
fi
if ! command -v tea >/dev/null 2>&1; then
echo "error: tea is not installed or not on PATH"
exit 1
fi
mapfile -t apps < <(python - <<'PY'
from pathlib import Path
apps = sorted({p.parent.name for p in Path("templates").rglob("meta.yaml")})
print("\n".join(apps))
PY
)
changed_apps=()
for app in "${apps[@]}"; do
last_tag="$(git tag --list "${app}-v*" --sort=-version:refname | head -n 1)"
if [[ -z "$last_tag" ]]; then
changed_apps+=("$app")
continue
fi
if git diff --name-only "${last_tag}..HEAD" | grep -Eq "^(src/|build.py$|templates/${app}/)"; then
changed_apps+=("$app")
fi
done
if (( ${#changed_apps[@]} == 0 )); then
echo "no app changes detected since last per-app tags; nothing to release"
exit 0
fi
if (( dry_run )); then
echo "+ update meta.yaml for: ${changed_apps[*]}"
else
APP_LIST="$(printf "%s\n" "${changed_apps[@]}")" APP_VERSION="${version}" python - <<'PY'
import os
from pathlib import Path
new_version = os.environ["APP_VERSION"]
targets = set(filter(None, os.environ["APP_LIST"].splitlines()))
for path in Path("templates").rglob("meta.yaml"):
if path.parent.name not in targets:
continue
text = path.read_text()
lines = text.splitlines()
out = []
changed = False
for line in lines:
if line.startswith("version:"):
out.append(f"version: {new_version}")
changed = True
else:
out.append(line)
if changed:
path.write_text("\n".join(out) + "\n")
PY
fi
if ! git diff --quiet; then
run git add templates/*/meta.yaml
run git commit -m "chore: release apps v${version}"
fi
run uv run build.py
run mkdir -p dist/releases
for app in "${changed_apps[@]}"; do
run tar -czf "dist/releases/apex-${app}-v${version}.tar.gz" -C dist "$app"
done
if (( no_push == 0 )); then
run git push origin HEAD
fi
commit="$(git rev-parse HEAD)"
note_args=()
pick_note_args() {
local app="$1"
note_args=()
if [[ -n "$notes_file" ]]; then
note_args=(--note-file "$notes_file")
return
fi
if [[ -n "$notes" ]]; then
note_args=(--note "$notes")
return
fi
if [[ -n "$notes_dir" ]]; then
if [[ -f "$notes_dir/$app.md" ]]; then
note_args=(--note-file "$notes_dir/$app.md")
return
fi
if [[ -f "$notes_dir/common.md" ]]; then
note_args=(--note-file "$notes_dir/common.md")
return
fi
fi
note_args=(--note "Release v${version}")
}
for app in "${changed_apps[@]}"; do
tag="${app}-v${version}"
title="Apex ${app} v${version}"
asset="dist/releases/apex-${app}-v${version}.tar.gz"
args=(tea releases create)
[[ -n "$repo" ]] && args+=(--repo "$repo")
[[ -n "$login" ]] && args+=(--login "$login")
args+=(--tag "$tag" --target "$commit" --title "$title")
pick_note_args "$app"
args+=("${note_args[@]}" --asset "$asset")
run "${args[@]}"
done
+90 -41
View File
@@ -2,48 +2,97 @@ scheme: "Apex Aeon"
author: "S0wlz (Owlibou)"
type: "light"
# Core Semantics (The DNA)
palette:
background: "#f5f5f5" # Void White
foreground: "#0a0a0a" # Near Black
cursor: "#ff0044" # Razor Red (Still the aggressor)
selection: "#ff0044"
selection_fg: "#0a0a0a" # HARD RULE: Near Black on Red
# Functional Roles
error: "#ff0044"
success: "#00b377" # Darker for contrast on light bg
warning: "#d18f00" # Darker for contrast
info: "#007a88" # Deep Cyan (Readable against white)
special: "#7a3cff"
azure: "#005577"
# ============================================================================
# Apex Aeon v2 — the daylight hunt. Tracks in snow: the field is bright, the
# signal is ink, not glow. Figure goes dark because the ground went light.
# Same rule system as Neon, recomputed values. Canonical spec: apex-aeon.md
# Red = danger. Pink = attention. Purple = sacred (root, always form-coded).
# None of them ever appears as a static syntax token.
#
# Key names are symmetric with neon.yaml so shared/aggregated templates work.
# ============================================================================
# UI Surfaces (Depth)
ui:
panel: "#e8e8e8" # Soft Surface
border: "#737373" # Muted/Borders
high: "#ffffff" # High Surface (Cards)
dim: "#737373"
stealth: "#a0a0a0"
# Neutrals — the readable 80% (spec §4). Off-white Paper, faint cool tint.
neutral:
bg: "#f1f3f7" # Main background, terminal background
surface: "#e7eaf0" # Inputs, inactive tabs, widgets, statuslines
panel: "#dce0e8" # Panels, separators, scroll track
border: "#c2c8d4" # Visible borders, line-highlight background
subtle: "#c8cdd8" # Ignored / suppressed text (sub-threshold by design)
muted: "#5c6270" # Comments, subtitles, muted labels
text: "#16181d" # Default body text (cool near-black, not pure black)
bright: "#000000" # Extreme emphasis only
# ANSI Table (Terminal)
# Attention — pink figure/ground (spec §5). Never a syntax token.
# Darker = hotter on light: max (cursor) is the deepest pink.
focus:
max: "#9d1a7e" # Cursor — the crosshair
active: "#b32b92" # Current search match, matched bracket / pair
field: "#f9daf1" # Other search matches, selection background
# Danger — red figure/ground (spec §5,6). Escalation goes DARKER on light.
danger:
base: "#c8003a" # Error figure, destructive action, urgent window border
field: "#fbe4e9" # Error region bg (Ember Field, + diff-delete bg)
bright: "#9e0030" # Escalation (ANSI color9) — darker = hotter on light
# Signal hues — information, state, structure.
signal:
info: "#087193" # Cyan (deep) — information / links
success: "#0a7851" # Green — success / OK
warning: "#935d03" # Amber — warning (UI only, never in buffer)
special: "#6a1fb8" # Purple — sacred / root (always bold or fielded, never bare)
blue: "#2148c0" # Blue — kinds / structural accent
blue_bright: "#1633a0" # Deep-blue — active flow / focus highlight
# Syntax — typed by grammatical role (spec §7). Ink, not glow.
# blue = kinds · cyan = actions · green = values · neutral = connective tissue
syntax:
comment: "#5c6270" # muted, italic
punctuation: "#4f5461" # neutral, lifted (lifted = darker on light)
operator: "#5c6270" # neutral
variable: "#16181d" # body text
property: "#2e333d" # dim body — fields / properties
# kinds — blue
type: "#2148c0" # blue — types / struct / enum / trait
storage: "#1633a0" # blue, heavier — storage / modifier (pub mut async)
attribute: "#2148c0" # blue, declarative — #[derive]
# actions — cyan
function: "#0e6e92" # cyan — function def / call
macro: "#0e6e92" # cyan — bang-macro (action + ceremony)
builtin: "#2c708e" # cyan, dim — self / builtin
# values — green
string: "#00734d" # green — values
escape: "#006641" # green, escalated (deeper on light) — char / escape
constant: "#0a7851" # green, cooler — number / bool / const
# navigation
keyword: "#1633a0" # deep-blue, bold — static control flow
# Diff / Git — pale grounds, ink figures (spec §8)
diff:
add: { fg: "#00734d", bg: "#e2f3ea" }
change: { fg: "#935d03", bg: "#f5ecda" }
delete: { fg: "#c8003a", bg: "#fbe4e9" } # reuses danger.field (Ember Field)
# ANSI Table — 16-color fallback bank (spec §9).
# Bright bank is DEEPER, not lighter (a lighter variant loses contrast on Paper).
ansi:
normal:
black: "#0a0a0a"
red: "#ff0044"
green: "#00b377"
yellow: "#d18f00"
blue: "#007a88"
magenta: "#7a3cff"
cyan: "#007a88"
white: "#f5f5f5"
bright: # Escalation only
black: "#737373"
red: "#ff4d6d"
green: "#33d6a6"
yellow: "#ffbf40"
blue: "#33bccc"
magenta: "#a680ff"
cyan: "#33bccc"
white: "#ffffff"
black: "#16181d" # Text / ink
red: "#c8003a" # Danger / error
green: "#0a7851" # Success
yellow: "#935d03" # Warning
blue: "#2148c0" # Kinds / structural
magenta: "#6a1fb8" # Sacred / root (purple)
cyan: "#087193" # Info / actions
white: "#c2c8d4" # Light surface
bright: # Escalation / active states only — deeper, not lighter
black: "#5c6270" # Muted / suggestions
red: "#9e0030" # Escalation (darker = hotter on light)
green: "#006543" # Active success / values
yellow: "#7b4e05" # Urgent warning
blue: "#1633a0" # Active flow nav
magenta: "#8d1071" # Elevated attention (pink)
cyan: "#005f80" # Active tech signal / functions
white: "#f1f3f7" # Lightest highlight
+86 -40
View File
@@ -2,47 +2,93 @@ scheme: "Apex Neon"
author: "S0wlz (Owlibou)"
type: "dark"
# Core Semantics (The DNA)
palette:
background: "#050505" # Void Black
foreground: "#ededed" # Stark White
cursor: "#ff0044" # Razor Red (Primary Aggressor)
selection: "#ff0044" # Target Locked
selection_fg: "#050505" # HARD RULE: Black text on Red
# Functional Roles
error: "#ff0044"
success: "#00ff99"
warning: "#ffb700"
info: "#00eaff" # Electric Cyan
special: "#9d00ff" # Sacred Purple
azure: "#0088cc" # Structural Blue
# ============================================================================
# Apex Neon v2 — a cold neon HUD on deep black. Hue carries meaning, sparsely.
# Red = danger. Pink = attention. Purple = sacred (root, always form-coded).
# None of them ever appears as a static syntax token. Canonical spec: apex-neon.md
#
# Key names are symmetric with aeon.yaml so shared/aggregated templates work.
# ============================================================================
# UI Surfaces (Depth)
ui:
panel: "#141414" # Inputs/Inactive Tabs
border: "#262626" # Separators
dim: "#737373" # Muted Text
stealth: "#404040" # Comments/Ignored
# Neutrals — the readable 80% (spec §3). Anchored at Void, faint cool bias.
neutral:
bg: "#070709" # Main background, terminal background
surface: "#101218" # Inputs, inactive tabs, widgets, statuslines
panel: "#181b22" # Panels, separators, scroll track
border: "#262a34" # Visible borders, line-highlight background
subtle: "#383d49" # Ignored / suppressed text (sub-threshold by design)
muted: "#8b909c" # Comments, subtitles, muted labels
text: "#e6e8ec" # Default body text (not pure white)
bright: "#ffffff" # Extreme highlight only
# ANSI Table (Terminal)
# Attention — pink figure/ground (spec §4-5). Never a syntax token.
focus:
max: "#f783d4" # Cursor — the single hottest mark
active: "#e42ab9" # Current search match, matched bracket / pair
field: "#340c29" # Other search matches, selection background
# Danger — red figure/ground (spec §4,6). Never inside a code buffer.
danger:
base: "#ff0044" # Error figure, destructive action, urgent window border
field: "#1f0a12" # Error region bg (Ember Field, + diff-delete bg)
bright: "#ff3b3b" # Escalation (ANSI color9) — hotter than base
# Signal hues — information, state, structure.
signal:
info: "#00eaff" # Cyan — information / links
success: "#00ff99" # Green — success / OK
warning: "#ffb700" # Amber — warning (UI only, never in buffer)
special: "#a550f9" # Purple — sacred / root (always bold or fielded, never bare)
blue: "#3c75f9" # Blue — kinds / structural accent
blue_bright: "#5b8cff" # Bright-blue — active flow / focus highlight
# Syntax — typed by grammatical role (spec §7)
# blue = kinds · cyan = actions · green = values · neutral = connective tissue
syntax:
comment: "#8b909c" # muted, italic — not a target
punctuation: "#aab0bc" # neutral, lifted
operator: "#c2c8d4" # neutral
variable: "#e6e8ec" # body text (calm everywhere)
property: "#cdd4e3" # dim body — fields / properties
# kinds — blue
type: "#7db4ff" # blue — types / struct / enum / trait
storage: "#3c75f9" # blue, heavier — storage / modifier (pub mut async)
attribute: "#3c75f9" # blue, declarative — #[derive]
# actions — cyan
function: "#5af3ff" # cyan — function def / call
macro: "#5af3ff" # cyan — bang-macro (action + ceremony)
builtin: "#8fd6ff" # cyan, dim — self / builtin
# values — green
string: "#2bffb2" # green — values
escape: "#7dffd0" # green, brighter — char / escape
constant: "#37dba0" # green, cooler — number / bool / const
# navigation
keyword: "#5b8cff" # bright-blue, bold — static control flow
# Diff / Git — dark tinted grounds, neon figures (spec §8)
diff:
add: { fg: "#00ff99", bg: "#0a1f16" }
change: { fg: "#ffb700", bg: "#1f1a0a" }
delete: { fg: "#ff0044", bg: "#1f0a12" } # reuses danger.field (Ember Field)
# ANSI Table — 16-color fallback bank (spec §9)
ansi:
normal:
black: "#050505"
red: "#ff0044"
green: "#00ff99"
yellow: "#ffb700"
blue: "#00eaff"
magenta: "#9d00ff"
cyan: "#00eaff" # Mapped to Blue/Info
white: "#ededed"
bright: # Escalation only
black: "#737373"
red: "#ff8899"
green: "#2bffb2"
yellow: "#ffd24d"
blue: "#5af3ff"
magenta: "#c84dff"
cyan: "#5af3ff"
white: "#ffffff"
black: "#070709" # Background
red: "#ff0044" # Danger / error / destructive
green: "#00ff99" # Success
yellow: "#ffb700" # Warning
blue: "#3c75f9" # Kinds / structural (real blue)
magenta: "#a550f9" # Sacred / root (purple)
cyan: "#00eaff" # Info / actions
white: "#e6e8ec" # Default text
bright: # Escalation / active states only
black: "#383d49" # Muted / suggestions
red: "#ff3b3b" # Escalation / alert (hotter than base)
green: "#2bffb2" # Active success / values
yellow: "#ffd24d" # Urgent warning
blue: "#5b8cff" # Active flow nav / focus highlight
magenta: "#fe41d0" # Elevated attention state (pink)
cyan: "#5af3ff" # Active tech signal / functions
white: "#ffffff" # Extreme highlight only
+20 -19
View File
@@ -1,46 +1,47 @@
# {{ scheme | upper }} — Alacritty theme (colors only)
# v2 spine: red = danger · pink = attention · cyan = info
[colors.primary]
background = "{{ palette.background }}"
foreground = "{{ palette.foreground }}"
dim_foreground = "{{ ui.dim }}"
background = "{{ neutral.bg }}"
foreground = "{{ neutral.text }}"
dim_foreground = "{{ neutral.muted }}"
bright_foreground = "{{ ansi.bright.white }}"
[colors.cursor]
text = "{{ palette.selection_fg }}"
cursor = "{{ palette.cursor }}"
text = "{{ neutral.bg }}"
cursor = "{{ focus.max }}"
[colors.vi_mode_cursor]
text = "{{ palette.selection_fg }}"
cursor = "{{ palette.info }}"
text = "{{ neutral.bg }}"
cursor = "{{ focus.active }}"
[colors.selection]
text = "{{ palette.selection_fg }}"
background = "{{ palette.selection }}"
text = "{{ neutral.text }}"
background = "{{ focus.field }}"
[colors.search.matches]
foreground = "{{ palette.selection_fg }}"
background = "{{ palette.selection }}"
foreground = "{{ neutral.text }}"
background = "{{ focus.field }}"
[colors.search.focused_match]
foreground = "{{ palette.selection_fg }}"
background = "{{ palette.warning }}"
foreground = "{{ neutral.bg }}"
background = "{{ focus.active }}"
[colors.hints.start]
foreground = "{{ palette.selection_fg }}"
background = "{{ palette.warning }}"
foreground = "{{ neutral.bg }}"
background = "{{ signal.warning }}"
[colors.hints.end]
foreground = "{{ palette.selection_fg }}"
background = "{{ palette.info }}"
foreground = "{{ neutral.bg }}"
background = "{{ signal.info }}"
[colors.line_indicator]
foreground = "None"
background = "None"
[colors.footer_bar]
foreground = "{{ palette.foreground }}"
background = "{{ ui.panel }}"
foreground = "{{ neutral.text }}"
background = "{{ neutral.surface }}"
[colors.normal]
black = "{{ ansi.normal.black }}"
+47 -45
View File
@@ -1,89 +1,91 @@
# {{ scheme }} — Btop Theme
# DNA: State over Decoration
# v2 spine: red = danger · pink = attention · cyan = info
# Main background, empty for terminal default, black for dark themes
theme[main_bg]="{{ palette.background }}"
theme[main_bg]="{{ neutral.bg }}"
# Main text color
theme[main_fg]="{{ palette.foreground }}"
theme[main_fg]="{{ neutral.text }}"
# Title color for boxes
theme[title]="{{ palette.foreground }}"
theme[title]="{{ neutral.text }}"
# Highlight color for keyboard shortcuts
theme[hi_fg]="{{ palette.cursor }}"
# Highlight color for keyboard shortcuts — pink attention accent
theme[hi_fg]="{{ focus.max }}"
# Background color of selected item in processes box
theme[selected_bg]="{{ palette.selection }}"
# Background color of selected item in processes box — pink field
theme[selected_bg]="{{ focus.field }}"
# Foreground color of selected item in processes box
theme[selected_fg]="{{ palette.selection_fg }}"
theme[selected_fg]="{{ neutral.text }}"
# Color of inactive/disabled text
theme[inactive_fg]="{{ ui.dim }}"
theme[inactive_fg]="{{ neutral.muted }}"
# Color of text appearing on top of graphs, i.e. usage percentage
theme[graph_text]="{{ ui.dim }}"
theme[graph_text]="{{ neutral.muted }}"
# Background color of the percentage meters
theme[meter_bg]="{{ ui.panel }}"
theme[meter_bg]="{{ neutral.surface }}"
# Misc colors for processes box including mini cpu graphs, used memory percentage, and entries filter
theme[proc_misc]="{{ palette.info }}"
theme[proc_misc]="{{ signal.info }}"
# Cpu box outline color
theme[cpu_box]="{{ ui.border }}"
theme[cpu_box]="{{ neutral.border }}"
# Memory box outline color
theme[mem_box]="{{ ui.border }}"
theme[mem_box]="{{ neutral.border }}"
# Net box outline color
theme[net_box]="{{ ui.border }}"
theme[net_box]="{{ neutral.border }}"
# Processes box outline color
theme[proc_box]="{{ ui.border }}"
theme[proc_box]="{{ neutral.border }}"
# Box divider line and small boxes line color
theme[div_line]="{{ ui.border }}"
theme[div_line]="{{ neutral.border }}"
# Heat gradients follow the severity ladder (spec §6): info -> warning -> danger.
# Purple is sacred (root only) and never a gradient step.
# Temperature graph colors
theme[temp_start]="{{ palette.info }}"
theme[temp_mid]="{{ palette.special }}"
theme[temp_end]="{{ palette.cursor }}"
theme[temp_start]="{{ signal.info }}"
theme[temp_mid]="{{ signal.warning }}"
theme[temp_end]="{{ danger.base }}"
# CPU graph colors
theme[cpu_start]="{{ palette.info }}"
theme[cpu_mid]="{{ palette.special }}"
theme[cpu_end]="{{ palette.cursor }}"
theme[cpu_start]="{{ signal.info }}"
theme[cpu_mid]="{{ signal.warning }}"
theme[cpu_end]="{{ danger.base }}"
# Mem graph colors
theme[free_start]="{{ palette.success }}"
theme[free_mid]="{{ palette.warning }}"
theme[free_end]="{{ palette.cursor }}"
theme[free_start]="{{ signal.success }}"
theme[free_mid]="{{ signal.warning }}"
theme[free_end]="{{ danger.base }}"
theme[cached_start]="{{ palette.info }}"
theme[cached_mid]="{{ palette.special }}"
theme[cached_end]="{{ palette.cursor }}"
theme[cached_start]="{{ signal.info }}"
theme[cached_mid]="{{ signal.warning }}"
theme[cached_end]="{{ danger.base }}"
theme[available_start]="{{ palette.success }}"
theme[available_mid]="{{ palette.warning }}"
theme[available_end]="{{ palette.cursor }}"
theme[available_start]="{{ signal.success }}"
theme[available_mid]="{{ signal.warning }}"
theme[available_end]="{{ danger.base }}"
theme[used_start]="{{ palette.info }}"
theme[used_mid]="{{ palette.special }}"
theme[used_end]="{{ palette.cursor }}"
theme[used_start]="{{ signal.info }}"
theme[used_mid]="{{ signal.warning }}"
theme[used_end]="{{ danger.base }}"
# Download graph colors
theme[download_start]="{{ palette.info }}"
theme[download_mid]="{{ palette.special }}"
theme[download_end]="{{ palette.cursor }}"
theme[download_start]="{{ signal.info }}"
theme[download_mid]="{{ signal.warning }}"
theme[download_end]="{{ danger.base }}"
# Upload graph colors
theme[upload_start]="{{ palette.info }}"
theme[upload_mid]="{{ palette.special }}"
theme[upload_end]="{{ palette.cursor }}"
theme[upload_start]="{{ signal.info }}"
theme[upload_mid]="{{ signal.warning }}"
theme[upload_end]="{{ danger.base }}"
# Process path color
theme[process_start]="{{ palette.info }}"
theme[process_mid]="{{ palette.special }}"
theme[process_end]="{{ palette.cursor }}"
theme[process_start]="{{ signal.info }}"
theme[process_mid]="{{ signal.warning }}"
theme[process_end]="{{ danger.base }}"
+8 -8
View File
@@ -1,14 +1,14 @@
# {{ scheme }} — Fuzzel Theme
# DNA: State over Decoration
# v2 spine: red = danger · pink = attention · cyan = info
[colors]
background={{ palette.background | replace('#', '') }}ff
text={{ palette.foreground | replace('#', '') }}ff
match={{ palette.info | replace('#', '') }}ff
selection={{ palette.selection | replace('#', '') }}ff
selection-text={{ palette.selection_fg | replace('#', '') }}ff
selection-match={{ palette.info | replace('#', '') }}ff
border={{ palette.info | replace('#', '') }}ff
background={{ neutral.bg | replace('#', '') }}ff
text={{ neutral.text | replace('#', '') }}ff
match={{ signal.info | replace('#', '') }}ff
selection={{ focus.field | replace('#', '') }}ff
selection-text={{ neutral.text | replace('#', '') }}ff
selection-match={{ signal.info | replace('#', '') }}ff
border={{ signal.info | replace('#', '') }}ff
[border]
width=2
-24
View File
@@ -1,24 +0,0 @@
{
"name": "{{ scheme }}",
"type": "custom",
"Background": "{{ palette.background }}",
"Foreground": "{{ palette.foreground }}",
"LightBlue": "{{ ansi.bright.blue }}",
"AccentBlue": "{{ palette.info }}",
"AccentPurple": "{{ palette.special }}",
"AccentCyan": "{{ ansi.bright.cyan }}",
"AccentGreen": "{{ palette.success }}",
"AccentYellow": "{{ palette.warning }}",
"AccentRed": "{{ palette.cursor }}",
"Comment": "{{ ui.dim }}",
"Gray": "{{ ui.stealth }}",
"DiffAdded": "{{ palette.success }}",
"DiffRemoved": "{{ palette.error }}",
"DiffModified": "{{ palette.warning }}",
"text": {
"primary": "{{ palette.foreground }}",
"secondary": "{{ ui.dim }}",
"accent": "{{ palette.info }}",
"response": "{{ palette.foreground }}"
}
}
-4
View File
@@ -1,4 +0,0 @@
author: S0wlz (Owlibou)
description: Gemini CLI custom theme
version: 1.0.1
strategy: individual
+30
View File
@@ -0,0 +1,30 @@
# {{ scheme }} - Ghostty theme
# v2 spine: red = danger · pink = attention · cyan = info
background = {{ neutral.bg }}
foreground = {{ neutral.text }}
# Cursor: the crosshair — pink
cursor-color = {{ focus.max }}
cursor-text = {{ neutral.bg }}
# Selection: pink field (attention, not danger)
selection-background = {{ focus.field }}
selection-foreground = {{ neutral.text }}
palette = 0={{ ansi.normal.black }}
palette = 1={{ ansi.normal.red }}
palette = 2={{ ansi.normal.green }}
palette = 3={{ ansi.normal.yellow }}
palette = 4={{ ansi.normal.blue }}
palette = 5={{ ansi.normal.magenta }}
palette = 6={{ ansi.normal.cyan }}
palette = 7={{ ansi.normal.white }}
palette = 8={{ ansi.bright.black }}
palette = 9={{ ansi.bright.red }}
palette = 10={{ ansi.bright.green }}
palette = 11={{ ansi.bright.yellow }}
palette = 12={{ ansi.bright.blue }}
palette = 13={{ ansi.bright.magenta }}
palette = 14={{ ansi.bright.cyan }}
palette = 15={{ ansi.bright.white }}
+4
View File
@@ -0,0 +1,4 @@
author: S0wlz (Owlibou)
description: Ghostty theme
version: 1.0.0
strategy: individual
+36 -35
View File
@@ -1,5 +1,5 @@
/* Apex Theme System — GTK4 / Libadwaita */
/* Auto-generated from Apex DNA */
/* v2 spine: red = danger · pink = attention · cyan = info */
{% for s in schemes %}
/* Scheme: {{ s.scheme }} ({{ s.type }}) */
@@ -10,60 +10,61 @@
{% endif %}
:root {
/* Core Surfaces */
@define-color window_bg_color {{ s.palette.background }};
@define-color window_fg_color {{ s.palette.foreground }};
@define-color window_bg_color {{ s.neutral.bg }};
@define-color window_fg_color {{ s.neutral.text }};
@define-color view_bg_color {{ s.palette.background }};
@define-color view_fg_color {{ s.palette.foreground }};
@define-color view_bg_color {{ s.neutral.bg }};
@define-color view_fg_color {{ s.neutral.text }};
@define-color headerbar_bg_color {{ s.ui.panel }};
@define-color headerbar_fg_color {{ s.palette.foreground }};
@define-color headerbar_border_color {{ s.ui.border }};
@define-color headerbar_bg_color {{ s.neutral.surface }};
@define-color headerbar_fg_color {{ s.neutral.text }};
@define-color headerbar_border_color {{ s.neutral.border }};
@define-color headerbar_backdrop_color @window_bg_color;
@define-color headerbar_shade_color rgba(0, 0, 0, 0.07);
@define-color popover_bg_color {{ s.ui.panel }};
@define-color popover_fg_color {{ s.palette.foreground }};
@define-color popover_bg_color {{ s.neutral.surface }};
@define-color popover_fg_color {{ s.neutral.text }};
@define-color card_bg_color {{ s.ui.panel }};
@define-color card_fg_color {{ s.palette.foreground }};
@define-color card_bg_color {{ s.neutral.surface }};
@define-color card_fg_color {{ s.neutral.text }};
@define-color card_shade_color rgba(0, 0, 0, 0.07);
@define-color dialog_bg_color {{ s.ui.panel }};
@define-color dialog_fg_color {{ s.palette.foreground }};
@define-color dialog_bg_color {{ s.neutral.surface }};
@define-color dialog_fg_color {{ s.neutral.text }};
/* Accents */
@define-color accent_color {{ s.palette.info }};
@define-color accent_bg_color {{ s.palette.info }};
@define-color accent_fg_color {{ s.palette.background }};
@define-color accent_color {{ s.signal.info }};
@define-color accent_bg_color {{ s.signal.info }};
@define-color accent_fg_color {{ s.neutral.bg }};
@define-color destructive_color {{ s.palette.cursor }};
@define-color destructive_bg_color {{ s.palette.cursor }};
@define-color destructive_fg_color {{ s.palette.background }};
/* Destructive = danger red (spec §5,6) */
@define-color destructive_color {{ s.danger.base }};
@define-color destructive_bg_color {{ s.danger.base }};
@define-color destructive_fg_color {{ s.neutral.bg }};
@define-color success_color {{ s.palette.success }};
@define-color success_bg_color {{ s.palette.success }};
@define-color success_fg_color {{ s.palette.background }};
@define-color success_color {{ s.signal.success }};
@define-color success_bg_color {{ s.signal.success }};
@define-color success_fg_color {{ s.neutral.bg }};
@define-color warning_color {{ s.palette.warning }};
@define-color warning_bg_color {{ s.palette.warning }};
@define-color warning_fg_color {{ s.palette.background }};
@define-color warning_color {{ s.signal.warning }};
@define-color warning_bg_color {{ s.signal.warning }};
@define-color warning_fg_color {{ s.neutral.bg }};
@define-color error_color {{ s.ansi.bright.red }};
@define-color error_bg_color {{ s.ansi.bright.red }};
@define-color error_fg_color {{ s.palette.background }};
@define-color error_color {{ s.danger.base }};
@define-color error_bg_color {{ s.danger.base }};
@define-color error_fg_color {{ s.neutral.bg }};
/* UI Elements */
@define-color borders {{ s.ui.border }};
@define-color sidebar_bg_color {{ s.ui.panel }};
@define-color sidebar_fg_color {{ s.palette.foreground }};
@define-color borders {{ s.neutral.border }};
@define-color sidebar_bg_color {{ s.neutral.surface }};
@define-color sidebar_fg_color {{ s.neutral.text }};
@define-color sidebar_backdrop_color @window_bg_color;
@define-color sidebar_shade_color rgba(0, 0, 0, 0.07);
/* Custom Apex Palette */
@define-color apex_razor {{ s.palette.cursor }};
@define-color apex_void {{ s.palette.background }};
@define-color apex_stealth {{ s.ui.stealth }};
@define-color apex_focus {{ s.focus.max }};
@define-color apex_void {{ s.neutral.bg }};
@define-color apex_subtle {{ s.neutral.subtle }};
}
}
{% endfor %}
-85
View File
@@ -1,85 +0,0 @@
#############################
### {{ scheme | upper }} THEME ###
#############################
# The Void (Backgrounds)
# Pure, unadulterated darkness. None of that "grey-blue" nonsense.
$base = rgb({{ palette.background | replace('#', '') }})
$baseAlpha = {{ palette.background | replace('#', '') }}
$surface = rgb({{ ui.panel | replace('#', '') }})
$surfaceAlpha = {{ ui.panel | replace('#', '') }}
$overlay = rgb({{ ui.border | replace('#', '') }})
$overlayAlpha = {{ ui.border | replace('#', '') }}
$muted = rgb({{ ui.stealth | replace('#', '') }})
$mutedAlpha = {{ ui.stealth | replace('#', '') }}
$subtle = rgb({{ ui.stealth | replace('#', '') }})
$subtleAlpha = {{ ui.stealth | replace('#', '') }}
# The Signal (Text)
# Stark white for maximum readability.
$text = rgb({{ palette.foreground | replace('#', '') }})
$textAlpha = {{ palette.foreground | replace('#', '') }}
# Accents (Aggressive)
# "Razor Red" - For errors or active borders. Blood-like.
$love = rgb({{ palette.cursor | replace('#', '') }})
$loveAlpha = {{ palette.cursor | replace('#', '') }}
# "Warning Gold"
$gold = rgb({{ palette.warning | replace('#', '') }})
$goldAlpha = {{ palette.warning | replace('#', '') }}
# "Toxic Green" - Because nature isn't always nice.
$pine = rgb({{ palette.success | replace('#', '') }})
$pineAlpha = {{ palette.success | replace('#', '') }}
# "Electric Cyan" - Cold, digital logic.
$foam = rgb({{ palette.info | replace('#', '') }})
$foamAlpha = {{ palette.info | replace('#', '') }}
# "Deep Void Purple"
$iris = rgb({{ palette.special | replace('#', '') }})
$irisAlpha = {{ palette.special | replace('#', '') }}
# "Pale Rose" (Mapped to alert color)
$rose = rgb({{ ansi.bright.red | replace('#', '') }})
$roseAlpha = {{ ansi.bright.red | replace('#', '') }}
# Highlight variants
$highlight_low = rgb({{ ui.panel | replace('#', '') }})
$highlight_lowAlpha = {{ ui.panel | replace('#', '') }}
$highlight_med = rgb({{ ui.border | replace('#', '') }})
$highlight_medAlpha = {{ ui.border | replace('#', '') }}
$highlight_high = rgb({{ ui.stealth | replace('#', '') }})
$highlight_highAlpha = {{ ui.stealth | replace('#', '') }}
# Theme-specific definitions
$splash_text = rgba($textAlphaee)
$dec_shadow = rgba(000000ee) # Hard shadows
# Border configurations
# Sharp, thin, and aggressive.
$border_active = rgba($loveAlphaff) rgba($irisAlphaff) 45deg
$border_inactive = rgba($mutedAlpha44) rgba($surfaceAlpha44) 45deg
$border_nogroup_active = rgba($foamAlphaff) rgba($pineAlphaff) 45deg
$border_nogroup_inactive = rgba($mutedAlpha44) rgba($surfaceAlpha44) 45deg
$border_group_active = rgba($goldAlphaff) rgba($loveAlphaff) 45deg
$border_group_inactive = rgba($mutedAlpha66) rgba($surfaceAlpha66) 45deg
$border_grouplocked_active = rgba($foamAlphaff) rgba($irisAlphaff) 45deg
$border_grouplocked_inactive = rgba($foamAlpha66) rgba($irisAlpha66) 45deg
# Group bar configurations
$groupbar_text = rgba($baseAlphaff)
$groupbar_active = rgba($loveAlphaff) rgba($irisAlphaaa)
$groupbar_inactive = rgba($surfaceAlphaee) rgba($mutedAlphaaa)
$groupbar_grouplocked_active = rgba($foamAlphaff) rgba($irisAlphaff)
$groupbar_grouplocked_inactive = rgba($foamAlphaaa) rgba($irisAlphaaa)
-4
View File
@@ -1,4 +0,0 @@
author: S0wlz (Owlibou)
description: Hyprland color variables and border configurations
version: 1.0.1
strategy: individual
+34 -33
View File
@@ -1,66 +1,67 @@
## {{ scheme | upper }} - KITTY THEME ##
## Spec-accurate: color = state, not decoration
## v2 spine: red = danger · pink = attention · cyan = info
# --- Core ---
foreground {{ palette.foreground }}
background {{ palette.background }}
foreground {{ neutral.text }}
background {{ neutral.bg }}
# Selection: "target locked"
selection_background {{ palette.selection }}
selection_foreground {{ palette.selection_fg }}
# Selection: pink field (attention, not danger)
selection_background {{ focus.field }}
selection_foreground {{ neutral.text }}
# Cursor: Razor Red beam
cursor {{ palette.cursor }}
cursor_text_color {{ palette.selection_fg }}
# Cursor: the crosshair — pink
cursor {{ focus.max }}
cursor_text_color {{ neutral.bg }}
cursor_shape beam
# URLs: informational cyan
url_color {{ palette.info }}
url_color {{ signal.info }}
# Borders (optional)
active_border_color {{ palette.cursor }}
inactive_border_color {{ ui.border }}
# Borders: focused window = pink attention, red only for urgency (spec §5)
active_border_color {{ focus.max }}
inactive_border_color {{ neutral.border }}
bell_border_color {{ danger.base }}
# Optional: subtle UI hint for visual bell
visual_bell_color {{ ansi.bright.red }}
# Visual bell: hot red
visual_bell_color {{ danger.bright }}
# Spacing
window_padding_width 4
# --- 16-COLOR ANSI TABLE ({{ scheme }} spec) ---
# --- 16-COLOR ANSI TABLE ({{ scheme }} spec §9) ---
# Normal bank (07)
# color0: Black (Void)
# color0: Black (bg)
color0 {{ ansi.normal.black }}