summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/config.md68
-rw-r--r--docs/design.typ21
-rw-r--r--docs/helix-keys.md2
-rw-r--r--docs/screenshots/agave-lsp.txt38
-rw-r--r--docs/screenshots/atelier.pngbin0 -> 461005 bytes
-rw-r--r--docs/screenshots/before.pngbin0 -> 369430 bytes
-rw-r--r--docs/screenshots/classic-gallery.json21
-rw-r--r--docs/screenshots/classic-themes.pngbin0 -> 2287763 bytes
-rw-r--r--docs/screenshots/columns-atelier.pngbin0 -> 295421 bytes
-rw-r--r--docs/screenshots/columns-orchard.pngbin0 -> 294658 bytes
-rw-r--r--docs/screenshots/columns-parity.json37
-rw-r--r--docs/screenshots/columns-tag-reveal.pngbin0 -> 296255 bytes
-rw-r--r--docs/screenshots/compact-columns.pngbin0 -> 214695 bytes
-rw-r--r--docs/screenshots/daybreak.pngbin0 -> 455797 bytes
-rw-r--r--docs/screenshots/dusk.pngbin0 -> 459601 bytes
-rw-r--r--docs/screenshots/ink.pngbin0 -> 459899 bytes
-rw-r--r--docs/screenshots/orchard.pngbin0 -> 459125 bytes
-rw-r--r--docs/screenshots/paper.pngbin0 -> 457492 bytes
-rw-r--r--docs/screenshots/parity.json20
-rw-r--r--docs/screenshots/pdf-and-tty-tags.pngbin0 -> 459114 bytes
-rw-r--r--docs/screenshots/pets.pngbin0 -> 24844 bytes
-rw-r--r--docs/screenshots/theme-preferences-forge.pngbin0 -> 229694 bytes
-rw-r--r--docs/screenshots/theme-preferences.pngbin0 -> 3458848 bytes
-rw-r--r--docs/screenshots/theme-selector.pngbin0 -> 253767 bytes
-rw-r--r--docs/tags.md84
-rw-r--r--docs/themes.md124
-rw-r--r--docs/ui-review.md230
27 files changed, 629 insertions, 16 deletions
diff --git a/docs/config.md b/docs/config.md
index 0a6765b8..79a5e631 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -23,7 +23,7 @@ which `Config` reports as `no per-user config path`.
`Config` (`SPC f c`, or the word executed anywhere) opens one refreshable
`+Config` pane. It reports the startup path and every live config-like value:
-theme, colors, wrapping, tag position, debug mode, the requested shell and the
+theme, colors, focus tint, syntax weight, wrapping, tag position, debug mode, the requested shell and the
executable actually resolved at the last spawn, requested/effective GUI font
and size, tagline scale, panel transition,
scene effects, hover delay, platform, native-image support, and (on SDL) whether
@@ -65,7 +65,7 @@ The format is one existing builtin command per line, using the same spelling
and argument parsing as commands executed inside pardes:
```text
-Theme acme
+Theme orchard
Font DejaVuSansMono-Regular
TaglineSize 82
Shell zsh
@@ -83,7 +83,7 @@ everything after the name as the argument. On a native build that is `Theme`,
(`Peek`, `Poke`, `Hexdump` and `Gpio` take one too, but they exist only where
`builtins.Board.enabled` holds, and that build has no config file.)
-`Theme <name>` wants one of the 228 names in the ring. Do not derive the
+`Theme <name>` wants one of the names in the compiled ring. Do not derive the
spelling — read it off `ThemeSel` (`SPC t t`), which lists every one as the
exact `Theme <name>` line that selects it. `slug` in `tools/gen_themes.zig`
lowercases, folds punctuation runs to a single `_` and then TRIMS leading and
@@ -94,6 +94,28 @@ and `ayu_mirage` is helix's `ayu_mirage.toml`. The suffix goes on all of them
rather than only the eight that clash today, so a name cannot move when either
project gains or loses a file. A name that is not in the ring is ignored.
+The fifteen [native Pardes themes](themes.md) lead the ring: `orchard` (the
+default), `dusk`, `ink`, `paper`, `daybreak`, `atelier`, `forge`, `lagoon`,
+`solarium`, `spectrum`, `harvest`, `clay`, `forge_black`, `forge_soft`, and
+`orchard_black`. `ThemeSel` lists them first under Pardes themes, followed by
+a separate legacy/imported section. They add coordinated
+focus, search, diagnostic and terminal colors; `ink` and `daybreak` are high
+contrast dark and light options. The original `helix`, `dark` and `acme`
+themes and all imported names remain available.
+
+`FocusTint` toggles the focused pane and column tag tints; it is on by default.
+Workspace, column and pane command text can be edited directly; see
+[editable tags](tags.md) for naming and saved-workspace behavior.
+`ColumnTags` toggles the column command row in both GUI and TTY; it is on by
+default. Add `ColumnTags` to startup configuration to reclaim that row on a
+compact screen. Hiding it preserves your custom column commands.
+`SyntaxBold` toggles bold syntax keywords; it is off by default. These
+settings are shared by GUI and TTY, and `Config` reports their current
+states. Like `Colors` and `Wrap`, these commands take no argument and invert
+the current value. A `FocusTint` line in a fresh startup configuration disables
+the tint; a `SyntaxBold` line enables the stronger keyword weight. Those two
+appearance controls leave focus, selections and editing behavior unchanged.
+
## Crash records
A panic appends to `crashes` in that same directory, beside `init`, and only
@@ -172,8 +194,14 @@ format, and it is `pardes.Theme` serialised by `std.zon.stringify`: the theme
name, thirteen required RGB roles (`sel_bg`, `sel_fg`, `tag_bg`, `tag_fg`,
`box`, `box_dim`, `kw`, `str`, `num`, `comment`, `lineno`, `scroll_track`,
`scroll_thumb`), nullable `bg`/`fg`, and either a 16-color RGB `palette` or
-`null`. RGB values are three-byte arrays, and hex literals are accepted. There
-is no inheritance or partial override layer.
+`null`. Nine optional nullable RGB roles extend this format:
+`tag_active_bg`, `tag_active_fg`, `border`, `search_bg`, `search_fg`,
+`diagnostic_error`, `diagnostic_warning`, `diagnostic_info`, and
+`diagnostic_hint`. Missing new roles use backward-compatible defaults, so
+previously exported files remain valid. [Theme customization](themes.md)
+describes each role and its fallback. RGB values are three-byte arrays, and
+hex literals are accepted. The original fields remain required; there is no
+inheritance or partial override layer.
`Filter` in a terminal's tag projects that pane's ANSI colors through the
active theme, and does it in two stages. The default foreground and background
@@ -202,8 +230,24 @@ terminal's font belongs to its emulator and a browser's to the page — so a
resolve the name by walking the font directories on every lookup, so a face
installed a moment ago is findable.
+Use `Font <name>:<size>` to change face and size together, for example
+`Font MartianMono-NrRg:18` in the startup file or an editable tag. Fractional
+sizes such as `:18.5` are supported; the accepted range is 8–72 (pixels in SDL,
+points on macOS). `Font <name>` without a suffix preserves the current size.
+Invalid sizes or unknown faces leave the current font unchanged.
+
+The SDL GUI also has a tiny optional workspace-tag companion: `Pet cat`,
+`Pet frog`, or `Pet off` (the default). Its original pixel sprite walks and
+idles in the trailing blank area of the global tag only. It hides while that
+tag is being edited, when the tag is full, or when the font leaves too little
+room; it never replaces text, receives clicks, or appears in pane/column tags.
+Animation runs at ten steps per second, uses theme ink, and requires no image
+assets or shaders. Put `Pet cat` in the startup configuration to keep it;
+`Pet off` disables the companion and its animation. Other hosts ignore the
+startup command. `Config` reports the current choice in SDL.
+
`Font` is asynchronous at the renderer boundary. `Config` therefore keeps
-requested name/path, pending state, and the effective face/point-or-pixel size
+requested name/path/size, pending state, and the effective face/point-or-pixel size
as separate facts; a failed request never gets reported as the face on screen.
Taglines use a distinct face size in both native GUI renderers. Execute
`TaglineSize <percent>` to change it live, for example `TaglineSize 70`; the
@@ -221,7 +265,8 @@ same compiled percentage to its DOM glyphs but has no runtime setter.
Both native GUIs join the reduced-height global and pane tagline bands with
`gui_topbar_pane_border_px` physical pixels. Set it to zero for a direct join.
`gui_topbar_pane_border_rgb` can pin an RGB color; its default `null` follows
-the active theme's scrollbar-track color. With `Tagbottom` enabled, a tagline
+the theme's `border` role in SDL (falling back to `scroll_track` for older
+themes), and `scroll_track` in the macOS shell. With `Tagbottom` enabled, a tagline
on the final grid row is bottom-aligned so the same unused half-band does not
show beneath it. The rule itself lives in the core
(`pardes.taglineBandOffset`), and the macOS shell reaches it over the C ABI
@@ -270,7 +315,14 @@ PanelScramble
PanelType
```
-All panel transitions start off. Slide uses cubic ease-out and zoom uses an
+All panel transitions start off. To disable one, execute its builtin again:
+`PanelDissolve` turns off an active dissolve, and `PanelAscii` turns off an
+active ASCII transition. `Config` shows the active command under
+`Panel transition`. Remove that command from your startup configuration to
+keep it off after restarting. Executing a different transition enables that
+one instead; these commands are toggles, not an unconditional animation-off command.
+
+Slide uses cubic ease-out and zoom uses an
overshooting ease-out-back. Dissolve and ASCII compare the last successfully
presented grid with the new one. Dissolve switches visually changed cells at
stable noise thresholds.
diff --git a/docs/design.typ b/docs/design.typ
index 8a5b9381..88bb49d6 100644
--- a/docs/design.typ
+++ b/docs/design.typ
@@ -1920,17 +1920,24 @@ system clipboard, which is helix's five words — `SPC y/Y/p/P/R`, out via
cannot clobber what the desktop was holding. A paste from an outer terminal
arrives bracketed, as one `paste` event.
-*Tag.* Live prefix (mode indicator, cwd or path) + editable tail with the
-full modal editor. Save leads the tail of every pane holding text of its own:
-`Save New Newtty Del` for a file or an output buffer,
-`Save New Newtty Del Filter` for a terminal, and the plain `New Newtty Del`
-for an image or a PDF, with `*` after an unsaved file's name; an image tag
+*Tag.* Compact name/status prefix + editable command tail. File names support
+staged edits: Enter commits a new buffer save target, Escape cancels, and no
+disk rename or write happens until explicit Save. Terminal cwd and image/PDF
+status stay generated. Save leads the tail of every pane holding text of its own:
+`Save Tty Del Collapse` for a file or an output buffer,
+`Save Tty Del Togglettymode Filter Collapse` for a terminal, and `Tty Del Collapse`
+for an image. PDFs use `Tty Del PdfSections PdfTint Collapse`, without tint status text.
+`Collapse` toggles a pane between its tagline alone and its expanded height;
+hidden body contents and running terminals are retained.
+An unsaved file has `*` after its name; an image tag
reports
`img petscii:<on|off> palette:<commodore|terminal> ascii:<on|off> <path>`
before the ordinary tail (its renderer toggles are builtins under `SPC t
p/l/a`). Topbar:
-`New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill` —
-execute-only (left click inert);
+`Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill` —
+editable by left click, with keyboard command navigation and Exec/Look gestures.
+An additional editable tag in each column supplies local New, Tty, Find,
+Grep and Joincol commands. ColumnTags hides that row when space is tight;
Colors and Crt left it for their leader paths.
*Panes.* Terminal: ghostty-vt, 16 MiB scrollback, OSC 133 prompt semantics,
diff --git a/docs/helix-keys.md b/docs/helix-keys.md
index dcd5b7cb..b999a25c 100644
--- a/docs/helix-keys.md
+++ b/docs/helix-keys.md
@@ -118,7 +118,7 @@ language-backend queries, and the shell pipe.
| `Enter` (normal) | acme **look** chord: EXPLICIT selection, else file-ish word under cursor | pardes-specific, keep (helix normal-mode Enter unbound). Covers helix `gf`. Implicit motion residue falls back to the cursor word | pardes-specific |
| `Tab` (normal) | acme **execute** chord | pardes-specific, keep; explicit-selection rule as Enter | pardes-specific |
| `:` (normal, body) | focuses the pane's OWN tag as a one-line editor in **normal** mode, parked at the first EDITABLE column: motions (`w` `b` `e` `W` `B` `E`, `0` `$` `^`, arrows, `Home`/`End`) walk the whole rendered tag, `y` yanks the selection, `Enter`/`Tab` look/execute it (else the file-ish word under the cursor), `i`/`a`/`I`/`A` enter insert, `Esc` hands the body back. `h`/`j`/`k`/`l` are NOT motion here — a tagline is a place in the LAYOUT, so they run the same `Left`/`Down`/`Up`/`Right` builtins and land on the neighbouring pane's TAGLINE, still in normal mode (nothing that way = stay put, EXCEPT `k` off the topmost tagline — see the next row); the arrows keep the in-tag motion | helix `:` is command mode (section C); pardes' commands are acme words that live in the tag. `tag_col`/`tag_anchor` are columns of the RENDERED tag (prefix ++ tail) — one coordinate space, so the live mode+path prefix is selectable, yankable and executable, while every edit op (typing, `Backspace`, `i`/`a`/`I`/`A`) measures from the first editable column and is inert inside it | pardes-specific |
-| `k` (tag normal, topmost tagline) | focuses the TOPBAR — row 0, the global tagline (`config.topbar_str`, today `New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill`, plus `Restore <path>` once a dump exists). It is its own one-line normal mode: `h`/`l` and the arrows by grapheme (row 0 has no window left or right to walk to), `w`/`b`/`e`/`W`/`B`/`E` and `0`/`$`/`^` by word, `Enter`/`Tab` runs the word under the cursor through the same dispatch a MIDDLE click on it uses, `j` drops back onto the topmost pane's tagline, `Esc` leaves. No insert mode and no selection — the bar is chrome with no tail to own | pardes-specific. The topbar is not a pane, so `focusDir` can never reach it: this is a fallback on the `.Up` branch of the tagline hop, from a TAGLINE only (a body's `SPC w k`/`Ctrl-w k` keep their pane-to-pane meaning). Its whole state is one global `topbar_col: ?u16` (row 0 has no pane to hang it on), cleared by any mouse press and BEFORE the chord dispatch, because `Kill` up here frees the session the way `Del` frees a pane. The motion vocabulary is literally the tag's — both call `lineMotion` | pardes-specific |
+| `k` (tag normal, topmost tagline) | focuses the column tag, then another `k` reaches the workspace tag at row 0 (`Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill`, plus `Restore <path>` once a dump exists). With `ColumnTags` disabled it goes directly to the workspace. `j` walks back down. Header arrows and `h`/`l` move by grapheme; word motions and `0`/`$`/`^` work too. In normal mode `Enter`/`Tab` executes; `i`/`a`/`I`/`A` enter editing, where Enter is Look and Tab is Exec. Left-click, drag selection, typing, and paste edit either header; Esc leaves | Column commands target that column's active pane, or its first pane when coming from elsewhere. Workspace and column text are independently editable and persist in dumps. See [editable tags](tags.md) | pardes-specific |
| `Ctrl-w` + `h/j/k/l`/arrows | directional pane focus prefix — normal/tty modes only | pardes' own window handling (helix window mode skipped, section C). Runs the SAME `Left`/`Down`/`Up`/`Right` builtins `SPC w h/j/k/l` runs; kept alongside the leader because a pane in raw **tty** mode never sees `SPC` (the shell owns it), so this is the only keyboard way out of one. Insert mode owns `Ctrl-w` = delete-word-back, so a tag being TYPED into swallows it; from a tag in normal mode (`:`) it moves focus to the neighbour's BODY, while the bare letters `h/j/k/l` there move to its TAGLINE (next row) | pardes-specific |
| `Alt-n` | new terminal below (any mode) | shadows helix `Alt-n` TS sibling-select — skipped anyway (tree-sitter) | pardes-specific |
| `Alt-c` | move active terminal to a fresh column (any mode) | helix `Alt-c` is change-noyank; the pardes window op wins (do-not-touch contract). `Alt-d` + `i` covers the behavior | waived (`alt-c-window-op`) |
diff --git a/docs/screenshots/agave-lsp.txt b/docs/screenshots/agave-lsp.txt
new file mode 100644
index 00000000..9a46b911
--- /dev/null
+++ b/docs/screenshots/agave-lsp.txt
@@ -0,0 +1,38 @@
+backend: zls-inproc+lsp-client
+zls: 0.16.1-dev+3e0d0820 (compiled in — no server process, no JSON-RPC)
+zig lib dir: /usr/lib/zig [OK]
+offsets: utf-8 walk caps: 512 files, 2000 rows
+
+dependency imports gd can follow (8):
+ zls /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/zls-0.16.1-dev-rmm5ftfOJgAzIdWUGVB08ycFbud2O3viKnGF1HZgfKZJ/src/zls.zig
+ tree-sitter /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/tree_sitter-0.26.0-8heIf3CaAQB4SSumoGzq3gLSz2rkvXxcKFyskRWqDGBz/src/root.zig
+ zstbi /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/zstbi-0.11.0-dev-L0Ea_3GWBwAh7m54XX055vwLKPTPij5hyqyeq92MXPE2/src/zstbi.zig
+ mvzr /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/mvzr-0.3.9-ZSOky6t2AQCA7efmm5EYbPb5sOdbXa4EFsUgYbQ6hZv9/src/mvzr.zig
+ mupdf /home/goblin/00-projects/0x4200.cafe/02-pardes-code/src/pdf.zig
+ ghostty-vt /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/ghostty-1.3.2-dev-5UdBCzeJJQXw_vG5Hsfx0DYUmF7Exs_9yctijqOIfp7W/src/lib_vt.zig
+ vaxis /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/vaxis-0.6.0-BWNV_CrbCQCscGpzsAlR402rYQ_tV3aAl081c2iRRkka/src/main.zig
+ uucode /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/uucode-0.2.0-ZZjBPlK5VADj7fdoq7G8LIHzD5o6FSkcBXXrRWr4jnrA/src/root.zig
+asked from: /home/goblin/00-projects/00-solana/agave/02-upstream/gossip/src/crds_value.rs
+
+answers: definition, declaration, type_definition, implementation, references, hover, document_symbols, workspace_symbols, diagnostics, workspace_diagnostics, rename, code_action, format, select_refs, completion
+refuses: incoming_calls, outgoing_calls, supertypes, subtypes
+
+last queries (0 total, keeping 24):
+ (none yet — press gd somewhere, then ask again)
+
+protocol servers (lsp-client):
+ rust-analyzer ready root /home/goblin/00-projects/00-solana/agave/02-upstream utf8 pull-diags call-hier docs 1 diag-files 0 [PARDES_LSP_RS=/home/goblin/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rust-analyzer]
+ .rs
+ clangd off [PARDES_LSP_C=(disabled)]
+ .c .h .cc .cpp .hpp .cxx .hxx
+ gopls off [PARDES_LSP_GO=(disabled)]
+ .go
+ typescript-language-server off [PARDES_LSP_TS=(disabled)]
+ .ts .tsx .js .jsx .mjs .cjs
+ pyright off [PARDES_LSP_PY=(disabled)]
+ .py
+
+client queries (3 total, keeping 24):
+ document_symbols rust-analyzer crds_value.rs 52 row(s)
+ hover rust-analyzer crds_value.rs 0 row(s)
+ definition rust-analyzer crds_value.rs 1 row(s)
diff --git a/docs/screenshots/atelier.png b/docs/screenshots/atelier.png
new file mode 100644
index 00000000..f889647a
--- /dev/null
+++ b/docs/screenshots/atelier.png
Binary files differ
diff --git a/docs/screenshots/before.png b/docs/screenshots/before.png
new file mode 100644
index 00000000..f2e3d506
--- /dev/null
+++ b/docs/screenshots/before.png
Binary files differ
diff --git a/docs/screenshots/classic-gallery.json b/docs/screenshots/classic-gallery.json
new file mode 100644
index 00000000..0b1092dd
--- /dev/null
+++ b/docs/screenshots/classic-gallery.json
@@ -0,0 +1,21 @@
+{
+ "themes": [
+ "forge",
+ "lagoon",
+ "solarium",
+ "spectrum",
+ "harvest",
+ "clay"
+ ],
+ "pets": [
+ "cat",
+ "frog",
+ "off"
+ ],
+ "os_windows": [
+ "20971567"
+ ],
+ "font_effective_pixels": 18,
+ "tagline_percent": 80,
+ "source_unchanged": true
+} \ No newline at end of file
diff --git a/docs/screenshots/classic-themes.png b/docs/screenshots/classic-themes.png
new file mode 100644
index 00000000..f0fe4089
--- /dev/null
+++ b/docs/screenshots/classic-themes.png
Binary files differ
diff --git a/docs/screenshots/columns-atelier.png b/docs/screenshots/columns-atelier.png
new file mode 100644
index 00000000..2727df2f
--- /dev/null
+++ b/docs/screenshots/columns-atelier.png
Binary files differ
diff --git a/docs/screenshots/columns-orchard.png b/docs/screenshots/columns-orchard.png
new file mode 100644
index 00000000..0fa179a5
--- /dev/null
+++ b/docs/screenshots/columns-orchard.png
Binary files differ
diff --git a/docs/screenshots/columns-parity.json b/docs/screenshots/columns-parity.json
new file mode 100644
index 00000000..9e18f2d4
--- /dev/null
+++ b/docs/screenshots/columns-parity.json
@@ -0,0 +1,37 @@
+{
+ "commands": [
+ "python3 -B test/column_tags.py zig-out/column-review/bin/pardes-gui /home/goblin/.cache/ct-sdl --project /home/goblin/00-projects/00-solana/agave/02-upstream",
+ "python3 -B test/column_tags.py zig-out/column-review/bin/pardes /home/goblin/.cache/ct-tty --project /home/goblin/00-projects/00-solana/agave/02-upstream --tty"
+ ],
+ "checks_per_host": 11,
+ "input": "Real keyboard and SGR mouse bytes through each host PTY parser; 9P state observation",
+ "comparison": "Core grid text and foreground/background colors; owned output directory names normalized ct-sdl/ct-tty to ct-run",
+ "limitations": [
+ "SDL captures are native GPU PNGs; TTY captures are core grids, not independent terminal-emulator screenshots.",
+ "This helper does not automate SDL pixel-coordinate mouse events.",
+ "Unicode editing and persistence are verified separately; presentation tags use ASCII because selected font lacks CJK glyph coverage."
+ ],
+ "frames": {
+ "columns-orchard": {
+ "cols": 150, "rows": 48,
+ "matching_color_cells": 7200, "total_cells": 7200,
+ "matching_text_rows": 48,
+ "cursor_sdl": {"x": 82, "y": 3, "bar": false},
+ "cursor_tty": {"x": 82, "y": 3, "bar": false}
+ },
+ "columns-atelier": {
+ "cols": 150, "rows": 48,
+ "matching_color_cells": 7200, "total_cells": 7200,
+ "matching_text_rows": 48,
+ "cursor_sdl": {"x": 82, "y": 3, "bar": false},
+ "cursor_tty": {"x": 82, "y": 3, "bar": false}
+ },
+ "columns-tag-reveal": {
+ "cols": 150, "rows": 48,
+ "matching_color_cells": 7200, "total_cells": 7200,
+ "matching_text_rows": 48,
+ "cursor_sdl": {"x": 74, "y": 2, "bar": true},
+ "cursor_tty": {"x": 74, "y": 2, "bar": true}
+ }
+ }
+}
diff --git a/docs/screenshots/columns-tag-reveal.png b/docs/screenshots/columns-tag-reveal.png
new file mode 100644
index 00000000..ce55adbc
--- /dev/null
+++ b/docs/screenshots/columns-tag-reveal.png
Binary files differ
diff --git a/docs/screenshots/compact-columns.png b/docs/screenshots/compact-columns.png
new file mode 100644
index 00000000..61b07ad7
--- /dev/null
+++ b/docs/screenshots/compact-columns.png
Binary files differ
diff --git a/docs/screenshots/daybreak.png b/docs/screenshots/daybreak.png
new file mode 100644
index 00000000..09cba567
--- /dev/null
+++ b/docs/screenshots/daybreak.png
Binary files differ
diff --git a/docs/screenshots/dusk.png b/docs/screenshots/dusk.png
new file mode 100644
index 00000000..53c55313
--- /dev/null
+++ b/docs/screenshots/dusk.png
Binary files differ
diff --git a/docs/screenshots/ink.png b/docs/screenshots/ink.png
new file mode 100644
index 00000000..171c6427
--- /dev/null
+++ b/docs/screenshots/ink.png
Binary files differ
diff --git a/docs/screenshots/orchard.png b/docs/screenshots/orchard.png
new file mode 100644
index 00000000..66057fa5
--- /dev/null
+++ b/docs/screenshots/orchard.png
Binary files differ
diff --git a/docs/screenshots/paper.png b/docs/screenshots/paper.png
new file mode 100644
index 00000000..7294869f
--- /dev/null
+++ b/docs/screenshots/paper.png
Binary files differ
diff --git a/docs/screenshots/parity.json b/docs/screenshots/parity.json
new file mode 100644
index 00000000..c2e636e3
--- /dev/null
+++ b/docs/screenshots/parity.json
@@ -0,0 +1,20 @@
+{
+ "comparison": "Every row-major cell resolved to (grapheme, foreground color, background color), using each capture's own style table; indices are not compared.",
+ "gui_artifacts": "/home/goblin/.cache/pardes-ui-review-final",
+ "tty_artifacts": "/home/goblin/.cache/pardes-ui-review-final-tty",
+ "capture_files": "theme-<name>.json",
+ "gui_command": "python3 -B test/ui_review.py zig-out/ui-review/bin/pardes-gui /home/goblin/.cache/pardes-ui-review-final --project /home/goblin/00-projects/00-solana/agave/02-upstream --skip-lsp --theme orchard --themes orchard dusk ink paper daybreak atelier",
+ "tty_command": "python3 -B test/ui_review.py zig-out/ui-review/bin/pardes /home/goblin/.cache/pardes-ui-review-final-tty --project /home/goblin/00-projects/00-solana/agave/02-upstream --tty --skip-lsp --theme orchard --themes orchard dusk ink paper daybreak atelier",
+ "themes": [
+ {"name": "orchard", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200},
+ {"name": "dusk", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200},
+ {"name": "ink", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200},
+ {"name": "paper", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200},
+ {"name": "daybreak", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200},
+ {"name": "atelier", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200}
+ ],
+ "limitations": [
+ "TTY evidence is the real core grid and styles, not an independently rendered emulator screenshot.",
+ "Comparisons exclude SDL pixel decorations, rasterization, font-role metadata and terminal-emulator rendering."
+ ]
+}
diff --git a/docs/screenshots/pdf-and-tty-tags.png b/docs/screenshots/pdf-and-tty-tags.png
new file mode 100644
index 00000000..66c3a008
--- /dev/null
+++ b/docs/screenshots/pdf-and-tty-tags.png
Binary files differ
diff --git a/docs/screenshots/pets.png b/docs/screenshots/pets.png
new file mode 100644
index 00000000..b9a83d66
--- /dev/null
+++ b/docs/screenshots/pets.png
Binary files differ
diff --git a/docs/screenshots/theme-preferences-forge.png b/docs/screenshots/theme-preferences-forge.png
new file mode 100644
index 00000000..3497c291
--- /dev/null
+++ b/docs/screenshots/theme-preferences-forge.png
Binary files differ
diff --git a/docs/screenshots/theme-preferences.png b/docs/screenshots/theme-preferences.png
new file mode 100644
index 00000000..48bb0d57
--- /dev/null
+++ b/docs/screenshots/theme-preferences.png
Binary files differ
diff --git a/docs/screenshots/theme-selector.png b/docs/screenshots/theme-selector.png
new file mode 100644
index 00000000..883a2801
--- /dev/null
+++ b/docs/screenshots/theme-selector.png
Binary files differ
diff --git a/docs/tags.md b/docs/tags.md
new file mode 100644
index 00000000..87cee2ff
--- /dev/null
+++ b/docs/tags.md
@@ -0,0 +1,84 @@
+# Editable tags
+
+Pardes has three levels of command text: the workspace tag, one tag per
+column, and each pane's tag. Column commands run in that column's active
+pane (or its first pane when focus comes from another column). This makes
+`New`, `Tty`, `Find`, and `Grep` available beside the work they act on.
+`New` appears only in the column tag by default; pane tags keep their own
+save, terminal, close, and collapse commands. `Tty` opens a new embedded terminal.
+Column command text starts flush with the column's left edge, just like the
+workspace tag; pane bodies retain their scrollbars and line-number gutters.
+
+When Look opens the first document and its source column is too narrow for
+a new column, it splits below the originating pane, just like `Tty`, instead
+of inserting at the top of the leftmost column. The originating terminal is
+kept. As with `Tty`, a tagline-only source uses a roomier split parent.
+
+`Collapse` reduces a pane to just its tagline, giving all its body space to
+the nearest expanded pane above, or below if none is above. Other panes keep
+their heights. Execute it again to reclaim its former height from that one
+neighbor, as far as available space allows. If every pane is collapsed, the
+unused area stays blank.
+Its text and terminal process are kept;
+the command stays available in the visible tag. Every default pane tag includes
+`Collapse`, including file, terminal, image, and PDF panes.
+
+Left-click a tag to place its caret; drag to select text, then type to
+replace it. Arrow keys, Home, End, Backspace and Delete edit the line.
+Tags reveal the caret horizontally when text is wider than their column.
+Escape returns to the body, keeping command-text edits. The existing Exec
+and Look gestures still apply; the workspace tag is no longer an inert
+left-click target. Pasted text goes to the focused tag, not to the file or
+embedded shell beneath it.
+
+Normal tag navigation now visits pane, column, and workspace tags in order:
+from the top pane's `:` tag, `k` reaches the column and another `k` reaches
+the workspace; `j` walks back down. Enter or Tab on a header command in
+normal mode executes it, as before. `i`/`a`/`I`/`A` switch to editing the
+header. In insert mode, Enter is Look and Tab is Exec, as in pane tags.
+
+Pane filenames and commands now have a single separator space rather than
+generated right-alignment padding. Intentionally customized spacing is kept.
+
+## File names
+
+Editing a file pane's name creates a draft. Enter confirms the new buffer
+name; Escape or leaving the tag cancels the draft. Confirmation changes the
+buffer's save target and marks it unsaved. It does **not** rename, create or
+overwrite a disk file. A subsequent explicit `Save` writes the buffer to its
+committed name. Executing a pane-tag command confirms a valid name draft
+first, so a visible draft cannot silently save to the previous name.
+
+Terminal working directories and generated image/PDF status remain managed
+by their corresponding commands. Their command tails are editable just like
+file command tails.
+
+PDF tags follow the same filename-first layout: `manual.pdf [1/12] Tty Del
+PdfSections PdfTint Collapse`. Sections and tint commands remain in the editable
+tail, without displaying the current tint state. `PdfFit` (`SPC t z`) remains
+available, as do the shortcuts for `PdfTint` (`SPC t i`) and `PdfSections`
+(`SPC t s`, or `f` on a PDF).
+
+Terminal tags include `Togglettymode`, which toggles between normal editor mode and raw
+terminal input using the same transition as Ctrl-B. It also works while editing
+the tag: the command leaves tag editing and toggles the parked body mode.
+Executing it on a non-terminal pane does nothing.
+
+## Saved workspaces
+
+`Dump` and `Restore` preserve customized workspace and column tags, including
+intentionally empty tags. New columns start with the standard column tag.
+Closing a column keeps surviving columns' tags; `Joincol` keeps the destination
+column's tag. Old dumps without these optional fields retain the defaults.
+The automatic `Restore` shortcut does not overwrite a customized workspace
+tag.
+
+The column row stays above panes with `TagBottom` enabled. On screens shorter
+than three rows it is omitted so a pane still has room. SDL and TTY share the
+same tag text, editing and layout; SDL additionally uses compact font sizing
+and subtle pixel separators.
+
+`ColumnTags` toggles the column row (on by default) without deleting its text.
+`FocusTint` controls active-column and active-pane emphasis. SDL also honors
+the shared bold, underline, and strikethrough attributes, including diagnostic
+underlines and the optional `SyntaxBold` keyword weight.
diff --git a/docs/themes.md b/docs/themes.md
new file mode 100644
index 00000000..7d71d0dd
--- /dev/null
+++ b/docs/themes.md
@@ -0,0 +1,124 @@
+# Pardes themes
+
+Pardes ships fifteen native palettes: six originals, six classic-inspired
+adaptations and three contrast variants, designed for tags, text, search, diagnostics and embedded
+terminals together. `orchard` is the initial theme.
+Execute `Theme <name>` anywhere, or open `ThemeSel` with `SPC t t` and select
+a theme's command. Put the same command in your [startup configuration](config.md)
+to keep a preference. `NextColor` cycles through the native themes first,
+then the retained `helix`, `dark` and `acme` themes and imported palettes.
+`ThemeSel` groups the new palettes under `Pardes themes`, followed by
+`Legacy and imported themes`; its navigation skips the section headings.
+See the [Agave visual review](ui-review.md) for the original six-palette gallery.
+
+| Theme | Character | Page | Accent |
+| --- | --- | --- | --- |
+| `orchard` | Near-black evergreen; bright leaf comments and plum syntax | `#0d1410` | `#adcc91` |
+| `dusk` | Soft plum charcoal; copper comments and gentle text | `#39323b` | `#e4b39b` |
+| `ink` | Pure black; bright, distinct signals and ice-blue comments | `#000000` | `#86d8ff` |
+| `paper` | Neutral uncoated paper; graphite and teal | `#f5f3ed` | `#3c6b56` |
+| `daybreak` | High contrast light; white and deep blue ink | `#ffffff` | `#075f91` |
+| `atelier` | Acme homage; butter-yellow paper and blue-green tags | `#fffdeb` | `#3e7a68` |
+| `forge` | Dark Plus-inspired near-black, blue and peach; slate-blue tags | `#0c0c0e` | `#a5c4ee` |
+| `lagoon` | Softer Material-inspired slate; vivid sea-glass comments | `#34464c` | `#89c7b4` |
+| `solarium` | Softer Solarized-inspired blue-green; golden comments and teal tags | `#173e45` | `#d5bc72` |
+| `spectrum` | Monokai-inspired near-black and candy colors; golden comments | `#100e11` | `#ffd866` |
+| `harvest` | Autumn-inspired near-black earth, ember and leaf green | `#100e0b` | `#cfba8b` |
+| `clay` | Gruvbox-inspired near-black and earthy brights; amber comments | `#10100e` | `#8ec07c` |
+| `forge_black` | Pure-black Forge; luminous text and cool slate tags | `#000000` | `#a5c4ee` |
+| `forge_soft` | Neutral-slate Forge; gentler text, still vivid blue comments | `#35383e` | `#a5c4ee` |
+| `orchard_black` | Pure-black Orchard; luminous garden ink and bright leaf comments | `#000000` | `#adcc91` |
+
+The six adaptations retain recognizable classic syntax identities, but are
+not exact ports. Their Acme influence is deliberate: quiet command strips,
+thin boundaries, and a search surface
+distinct from selection. Forge uses cool-neutral chrome instead of green
+tints. Active pane and column tags use a restrained tone-on-tone shift, not
+a light/dark inversion: dark palettes keep dark tags, and light palettes
+keep light tags. A slight text lift and the focus marker retain the cue
+without turning the entire command strip into a highlight.
+Comments are colorful first-class text, while line numbers stay quiet;
+the current line number gets a small color emphasis and bold weight, never a bright tag-colored
+block. These are appearance changes only;
+tag editing, commands and terminal interaction are unchanged.
+
+Dark backgrounds make an explicit choice: near-black with bright text, or
+the gentler slate/plum/blue-green of `forge_soft`, `dusk`, `lagoon` and
+`solarium`. The softer group keeps body text around 5.5–6.7:1 contrast; the
+near-black group exceeds 14:1. Try `Theme forge_black` and `Theme forge_soft`
+back-to-back to compare the extremes without changing the syntax identity.
+Light paper and the Acme homage remain available.
+
+Their local references are `vendor/themes/dark_plus.toml`,
+`material_oceanic.toml` (and its `material_deep_ocean.toml` parent),
+`solarized_dark.toml`, `monokai_pro.toml`, `autumn.toml`, and the Gruvbox Dark
+entry in `gruvbox.json`. The original imported themes remain selectable under
+their existing names; the adaptations have distinct Pardes names and do not
+claim upstream affiliation. Existing vendor provenance and licenses remain
+with those sources.
+
+All fifteen palettes specify their own ANSI colors, so indexed terminal output
+belongs to the same palette as the editor. Explicit true-color output can
+still carry an application's own colors; the existing terminal `Filter`
+command projects those colors through the theme. The older `dark` palette
+continues to inherit the surrounding terminal's default background and text.
+
+The native palettes keep normal text, syntax colors, comments,
+diagnostics and ANSI foregrounds at a calculated sRGB contrast ratio of at
+least 4.5:1 against the page. `ink` and `daybreak` raise that floor to 7:1.
+Comments additionally stay above 5:1. Decorative line numbers sit between
+2.5:1 and 4:1, with current numbers capped at 4.5:1; they deliberately do not
+compete with source text. ANSI bright black is independent of the comment
+color, so making comments vivid does not recolor gray terminal output.
+Tag, active-tag, selection and search text are checked against their respective
+surfaces at the same thresholds. Active/inactive tag backgrounds differ by
+no more than 1.6:1, keeping focus changes quiet. ANSI black is exempt because applications
+also use it as a background. These are palette checks, not a guarantee about
+arbitrary terminal escape sequences, reversed colors or shader effects.
+
+## Make a theme your own
+
+Run `DumpThemes` to export complete `.zon` files below the configuration
+directory's `themes/builtin/`. Copy a native file to `themes/mine.zon`, change
+its `.name`, and run:
+
+```text
+ThemeFile themes/mine.zon
+```
+
+On hosts with live document reload, saving a valid theme file updates it
+immediately. An incomplete save keeps the last valid version. Selecting a
+built-in theme stops the custom theme watch.
+
+Pardes roles extend the original editor palette with independent choices
+for its UI. Each value is an RGB triple, for example
+`.search_bg = .{ 0x57, 0x47, 0x2a }`. New roles are optional and accept `null`,
+so existing exported themes remain valid.
+
+| Optional role | Purpose | When absent |
+| --- | --- | --- |
+| `tag_active_bg`, `tag_active_fg` | Focused pane tag surface and text | `tag_bg`, `tag_fg` |
+| `border` | Quiet separators | `scroll_track` |
+| `lineno_active` | Restrained current line number foreground | `lineno` |
+| `search_bg`, `search_fg` | Search matches, independent of selection | `sel_bg`, `sel_fg` |
+| `diagnostic_error` | Error text | `fg`, or `tag_fg` for an inherited foreground |
+| `diagnostic_warning` | Warning text | Same foreground fallback |
+| `diagnostic_info` | Informational diagnostic text | Same foreground fallback |
+| `diagnostic_hint` | Hint text | Same foreground fallback |
+
+These colors are shared by the GUI and TTY. Tags and their active tint retain
+the same text, command execution, drag targets and focus behavior. Selection
+and search have separate palette roles because they communicate different
+states. Theme changes use the existing chrome transition; body and terminal
+colors switch directly so syntax and ANSI content stay coherent.
+
+`FocusTint` toggles the focused pane's tag tint, which is on by default.
+`SyntaxBold` toggles bold syntax keywords, which are off by default. Both
+commands take no argument, work in GUI and TTY, and report their states in
+`Config`. Use them in the startup configuration to reverse the defaults.
+
+The original required roles remain unchanged: nullable `bg` and `fg`,
+`sel_bg`, `sel_fg`, `tag_bg`, `tag_fg`, `box`, `box_dim`, `kw`, `str`, `num`,
+`comment`, `lineno`, `scroll_track`, `scroll_thumb`, and a nullable 16-entry
+`palette`. `ThemeFile` loads a complete theme, with no inheritance or partial
+override syntax. The exported native files are the easiest starting point.
diff --git a/docs/ui-review.md b/docs/ui-review.md
new file mode 100644
index 00000000..e43ef9b7
--- /dev/null
+++ b/docs/ui-review.md
@@ -0,0 +1,230 @@
+# Visual review
+
+## Contrast choices and local collapse
+
+The fifteen native palettes now give comments vivid color and keep line
+numbers subdued. The current number uses muted ink and bold weight instead
+of a tag-colored background block, in SDL and TTY. Active pane and column
+tags use a small tonal shift without reversing their light/dark polarity.
+Column tag text starts at the column edge without the former two-cell inset.
+Forge has neutral coal
+and silver-blue chrome. `forge_black` and `orchard_black` use pure black;
+`forge_soft` joins `dusk`, `lagoon` and `solarium` as deliberately softer
+alternatives. Light and Acme-inspired choices remain available.
+
+`ThemeSel` opens with the native collection, followed by a separate legacy
+and imported section. Keyboard navigation skips both section headings.
+
+`Collapse` now transfers all released rows to one expanded pane, preferring
+the nearest one above and falling back below. Unrelated pane heights stay
+unchanged. Expansion borrows from one neighbor too, limited by its available
+body space. Tests cover exact unchanged sibling rectangles, repeated inverse
+toggles, already-folded neighbors, tiny resizes, drag expansion and Dump/Restore.
+
+The refreshed builds pass 791 TTY and 822 SDL unit tests, with one skipped
+in each suite, plus all 98 interaction snapshots. Snapshot review found only
+the intended style changes, the expanded grouped theme picker, and flush-left
+column text/carets (including newly visible text in one- and two-cell columns).
+
+The isolated 9P harness `test/collapse_layout.py` passes seven collapse/expand
+pairs on each host, checking rendered tag boundaries and unchanged contents.
+The live OS gallery checks all fifteen native themes for bold current-line
+numbers, unchanged gutter backgrounds and no active-tag polarity inversion.
+Both hosts pass all twelve column input checks, including first-cell execution,
+editing and caret reveal. Agave source bytes stay unchanged and no input is
+sent to the user's session.
+
+- [Six contrast studies, OS screenshot crops](screenshots/theme-preferences.png)
+- [Neutral Forge, full workspace](screenshots/theme-preferences-forge.png)
+- [Native-first ThemeSel, full workspace](screenshots/theme-selector.png)
+
+## Compact rails, classic palettes and workspace pets
+
+`New` now belongs to column tags only. Pane tags keep their local save,
+terminal and close actions: `Tty` opens a terminal, and `Togglettymode`
+switches editor/raw input using the same transition as Ctrl-B. Historical
+default pane tails upgrade during Restore; explicitly customized text remains
+owned by the user.
+
+SDL paints adjacent tag backgrounds to their full row height, leaving only
+the thin separator. Square scroll markers share the column's left edge, and
+a one-pixel continuous line joins its column tag, pane tags and bodies.
+Pointer targets and the TTY grid are unchanged.
+
+`Font MartianMono-NrRg:18` now applies both face and size. The isolated
+`test/font_size.py` checks startup sizing, fractional sizing, retaining the
+size when omitted, and rejecting invalid requests without partial changes.
+
+Six [classic-inspired themes](themes.md) add `forge`, `lagoon`, `solarium`,
+`spectrum`, `harvest` and `clay`. ANSI colors retain their terminal meanings
+instead of borrowing a similarly positioned syntax color. Optional SDL
+`Pet cat` and `Pet frog` companions walk, idle and reverse in the unused
+workspace tag; `Pet off` is the default. Editing that tag hides the pet.
+The original pixel sprites use no external assets or input handlers.
+
+`test/appearance_gallery.py` recreates a two-column Agave review with stacked
+right-hand panes, an embedded terminal, Font 18 and TaglineSize 80. It checks
+all six new themes, font and pet reports, changing pet frames, and unchanged
+Agave source bytes. Its `--live-window` mode captures the owned SDL window
+through the OS, identified by its child PID. It never resizes or sends input
+to the user's existing Pardes window.
+
+- [Compact columns, native OS capture](screenshots/compact-columns.png)
+- [Six classic adaptations, screenshot contact sheet](screenshots/classic-themes.png)
+- [Cat and frog, enlarged nearest-neighbor screenshot crops](screenshots/pets.png)
+- [Gallery checks](screenshots/classic-gallery.json)
+
+The full suites passed 807 SDL and 776 TTY tests, with one skipped in each;
+all 97 interaction snapshots passed. A private mount namespace redirected
+test-only `/tmp` writes after the host's temporary-file quota was exhausted,
+without deleting files or changing the user's `/tmp`. These counts include
+the pet/geometry/font/command changes; palette corrections additionally pass
+the native contrast tests.
+
+## PDF and terminal tag cleanup
+
+PDFs now use `filename.pdf [page/total] Tty Del PdfSections PdfTint Collapse`,
+keeping sections and tint commands visible without the long generated
+control/status prefix. Terminal tags add `Togglettymode`, sharing Ctrl-B's actual mode
+transition, including when invoked from an edited tag.
+
+`test/tag_cleanup.py` verifies the compact PDF tag, middle-click `Togglettymode`, Ctrl-B,
+and tag-edit/Tab execution through real host input and 9P observations on both
+SDL and TTY. The PDF source stays unchanged. The full unit suites pass 773 TTY
+tests and 797 SDL tests; SDL image/PDF and Kitty PDF rendering harnesses pass.
+
+[Native PDF and terminal screenshot](screenshots/pdf-and-tty-tags.png).
+
+## Column and editable-tag follow-up
+
+The follow-up adds editable workspace and column command rows, compact pane
+tags, staged buffer-name edits, caret reveal for long tags, and `ColumnTags`
+to reclaim the extra row when needed. See [editable tags](tags.md) for the
+exact interaction and save-target rules.
+
+`test/column_tags.py` exercises isolated SDL and TTY sessions against the same
+Agave source. It sends actual host input bytes while observing through 9P:
+header typing and selection replacement, UTF-8 deletion, inactive-column
+`New`/`Tty`, pane-tail edits, filename cancellation, terminal input, and
+custom-tag Dump/Restore. Source bytes remain unchanged. Input goes through
+the host PTY parser; compact SDL pixel coordinates are covered separately by
+round-trip mapping tests, not claimed as physical SDL mouse automation.
+All 11 live checks passed on each frontend. All 7,200 foreground/background
+cells and 48 text rows matched for the three final frames after normalizing
+only the isolated `ct-sdl`/`ct-tty` directory names.
+
+The screenshots below are native GPU captures, after removing test-only
+Unicode markers through normal tag editing. The tested CJK text has correct
+grid/editing behavior, but the selected font lacks its glyph; this is not
+claimed as complete font-fallback coverage.
+
+- [Two-column Orchard workspace](screenshots/columns-orchard.png)
+- [Two-column Atelier workspace](screenshots/columns-atelier.png)
+- [Long tag revealing its actions and caret](screenshots/columns-tag-reveal.png)
+- [Final SDL/TTY parity evidence](screenshots/columns-parity.json)
+
+The final unit suites passed 771 TTY tests and 795 SDL tests. Native image and PDF harnesses
+passed, including continuous PDF layout and reload. The PDF fixture gains one
+screen row to preserve its original document area; its pixel assertions are
+unchanged.
+
+Existing terminal snapshots were migrated by adding one screen row and moving
+pane mouse coordinates down one row, preserving their original body area.
+Raw SGR mouse sequences were migrated too. The tag-padding/name/navigation
+fixtures were explicitly rewritten for the new behavior. Review found 86
+fixtures with identical text tokens after removing the new column row and
+normalizing spacing; the remaining differences were reviewed for tag edits,
+nested editor chrome, resize handles, and debug overlays. All 97 scripts
+passed both when regenerating the reviewed goldens and in a subsequent
+independent run with retries disabled.
+
+## Initial palette pass
+
+The UI pass was exercised against Agave's real `gossip/src/crds_value.rs`,
+using isolated named Pardes sessions and the existing Python 9P client.
+The workflow opened Find and Grep results, ran harmless commands in an
+embedded terminal, requested Rust document symbols and hover, and sent `gd`
+through the host's actual terminal input parser. Agave source bytes were
+checked unchanged after the session.
+
+Native SDL screenshots use the GPU capture path. TTY captures contain the
+real core grid and its styles; they are not screenshots of an independent
+terminal emulator. Resolving cells to their grapheme, foreground and
+background yielded **7,200 of 7,200 matching cells** at 150 × 48 for each of
+`orchard`, `dusk`, `ink`, `paper`, `daybreak`, and `atelier`.
+
+Rust-analyzer returned 52 document-symbol rows and one definition result.
+The initial baseline hover timed out; the updated run returned no hover
+text for the declaration. No hover popup is claimed as verified. Agave's
+gossip crate is feature-gated, and workspace loading was still substantial;
+the exact cause of that empty result was not established.
+
+## Reproduce
+
+Run from the Pardes checkout, using an existing SDL binary and an Agave
+checkout. The output directory is private and also holds isolated startup
+configuration. ImageMagick and an X11 display are required for PNG captures;
+the LSP pass additionally needs rust-analyzer (located through rustup unless
+`--rust-analyzer` is supplied).
+
+```sh
+python3 -B test/ui_review.py zig-out/ui-review/bin/pardes-gui \
+ /tmp/pardes-ui-review --project /path/to/agave \
+ --theme orchard --themes orchard dusk ink paper daybreak atelier
+```
+
+For subsequent palette captures, add `--skip-lsp`. To repeat LSP work without
+rebuilding dependencies, use `--cargo-target /path/to/previous/cargo-target`.
+Cargo runs offline and stores build output in that isolated directory.
+For the TTY pass, use the TTY binary and add `--tty`. The script requires
+Find/Grep results and observed terminal output, fails missing or malformed
+SDL captures, and writes `report.json` with the actual outcomes. LSP absence
+or failure is recorded separately rather than passing as a successful popup.
+
+Review artifacts from this pass:
+
+- [Baseline workspace](screenshots/before.png)
+- [Orchard: mild dark](screenshots/orchard.png)
+- [Dusk: warm dark](screenshots/dusk.png)
+- [Ink: high contrast dark](screenshots/ink.png)
+- [Paper: mild light](screenshots/paper.png)
+- [Daybreak: high contrast light](screenshots/daybreak.png)
+- [Atelier: Acme homage](screenshots/atelier.png)
+- [Cell parity evidence](screenshots/parity.json)
+- [Actual Rust LSP responses](screenshots/agave-lsp.txt)
+
+![Orchard with Agave source, terminal and search](screenshots/orchard.png)
+
+## Regression checks
+
+Both native binaries built in ReleaseFast. The full TTY and SDL unit suites
+passed with the inherited nesting variables `PARDES_FORWARD_LOOK`, `PARDES_9P`
+and `PARDES_PANE` removed from the test process. Those variables exposed an
+existing environment-ownership issue in native subprocess tests: libc's
+environment was changed while the Zig test I/O retained the old slice. This
+pass does not change that environment code or skip the affected tests.
+
+The appearance checks cover native palette contrast, old ThemeFile documents,
+wrapped search matches, selection precedence, immediate body colors during
+theme fades, light-theme carets and both quiet and bold syntax preferences.
+The 9P walkthrough also verifies `FocusTint` and `SyntaxBold` through `Config`.
+
+All 97 terminal snapshot scripts passed without retries after reviewing and
+refreshing 32 appearance goldens. Of those, 27 preserve identical visible text,
+cursor positions and grid geometry; the remaining five contain the new default
+theme name or the expanded theme list. SDL image and PDF harnesses also passed,
+including continuous PDF layout and idle document reload. The PDF color fixture
+explicitly selects legacy `helix` to preserve its fixed pixel expectations.
+
+## Possible interaction follow-ups
+
+These were not needed for the appearance pass:
+
+- A way to reveal an abbreviated pane path on demand could recover title
+ space in deep workspaces. The full path should remain selectable and
+ available to Look; replacing it outright would weaken an existing workflow.
+- Show a query's busy state until its response arrives, and distinguish an
+ empty answer from a timeout. The first full-workspace Rust hover provided
+ little visible feedback while indexing; explicit status would tell users
+ whether to wait or change their selection. This needs clear cancellation
+ and stale-response behavior before changing the interaction.