TDesign draws its glyphs on a 24px grid with a 2px stroke and sizes a
component's icon 2px above its text, in whole pixels. The templates had
drifted to 12 one-off sizes, most of them fractional (0.9rem = 14.4px), so
strokes blurred and neighbours never matched: the tab bar's 14.4px cog
beside a 12.8px +, the shortcut rows' 12px + beside an 11.2px reset and
9.6px chip x.
Every <ng-icon> now takes one of --icon-size-sm (14px: beside 11-12px
text, small icon buttons), -md (16px: file rows, window titles, path-bar
buttons), -lg (20px) or -xl (24px: lone spinners and status marks).
--action-icon goes; architecture.md and gotchas.md carry the rule.
Co-Authored-By: Claude <noreply@anthropic.com>
The keymap was scattered over ShortcutsService if-chains, the file panel's
key switch, macOS-only menu accelerators and hand-typed hints in 16
tooltips x 7 locales, and large parts of the app had no keyboard path at
all. src/shared/keymap.ts is now the one table: scopes, per-platform
defaults, exact matching, formatting with localized key names, conflicts,
reserved combos and native-menu accelerators, proven by keymap.spec.ts.
- ShortcutsService resolves against the effective keymap: claim() takes
the key (preventDefault, held keys repeat only movement, never mid-IME),
and from a text field only chords and F-keys fire. The file panel, App,
editor, manager and Settings windows all dispatch through it.
- FileActionsService.run is the one file-command dispatcher for the list
keys, the row menu, the macOS menu bar and the toolbar.
- New keys: the row menu (Shift+F10 / Menu / Ctrl+Return), the source
picker (Mod+K), the path bar (Mod+L), transfers (Mod+J), sorting
(Alt+1-7), Shift+movement selection, close other tabs, move and
disconnect tabs, refresh and edit on Windows/Linux, permissions, copy
path, reveal, trash, open in default app, editor find next/previous.
- Right-click menus: soft shortcut hints, icons on the everyday verbs
(the toolbar's glyphs), section headers, scrolling, item keys while
open, a highlighted first item when opened from the keyboard. The panel
source picker now renders through the same menu.
- Dialogs: role=dialog, a Tab trap via cycleFocus (WKWebView skips
buttons on Tab without Keyboard navigation), initial focus, Esc that
stops propagating; the chmod dialog takes focus and applies on Enter.
- Fixed: Ctrl+Tab also flipped the active panel; Esc in a manager dialog
closed the manager; Ctrl-F/T fired Cmd shortcuts on macOS; shortcuts
fired under dialogs; keys died after any button click on macOS; the
editor's save prompt and find box never got focus; WebView2 reload keys;
a window could save default settings before its first load.
- Settings closes on its own close-window key (new settingsClose request).
Co-Authored-By: Claude <noreply@anthropic.com>
The palette now follows Oxide's design system (docs.oxide.computer): a cool
neutral scale at hue 260 with almost no chroma, opaque strokes, and Oxide's
green as the only accent. The accent-color option is gone: selection, the
cursor row, focus rings and the active-panel line all read green.
The file panel's header strip now steps toward the list, one shade per row
(session strip, path bar, column headers), derived by color-mix so every
theme, AMOLED included, follows on its own.
Everything is square: every rounded utility and the radius tokens are gone,
and checkboxes, radios, selects, number spinners and scrollbars are
restyled to match (square scrollbars are always visible on macOS, the cost
of styling them).
Co-Authored-By: Claude <noreply@anthropic.com>
Swap @ng-icons/mynaui for @ng-icons/tdesign-icons (34.0.0, the release
matching @ng-icons/core), drawn at TDesign's native stroke. Each former
mynaui name maps to one TDesign name everywhere it was used; the unused
ArrowLeftRight is dropped. The options button's ellipsis goes from 1.5rem
to 0.8rem: TDesign's dots span 18 of 24 units against mynaui's 8, so this
keeps today's footprint.
Co-Authored-By: Claude <noreply@anthropic.com>
Both UIs now live side by side. The 18 modern component files come straight
from `git show main:<path>` — recovered, not rewritten, which is possible
because main's tip IS the merge base of this branch. There is no title-bar
among them: that component is win7-only, since the modern skin defers to the
native window frame.
Their imports were rewritten to @core the same way stage 1 did, leaving only
skin-internal relative imports behind. Added skins/shadlike/index.ts exporting
SHAD_ROOTS with the same shape as SEVEN_ROOTS, so main.ts can select a tree
without knowing either skin's internals.
Restored the skin axis in core/platform.ts, deleted in fe028a9 and needed
again by the modern tree: __APP_SKIN on the Window global, APP_SKIN,
IS_WIN7_CHROME, and IS_MAC_CHROME = IS_MAC && !IS_WIN7_CHROME. That last one
is what reserves pl-24 for the macOS traffic lights in the fused hiddenInset
header — and correctly stops reserving it under win7, where titleBarStyle
'hidden' removes the traffic lights entirely.
The tree is not reachable yet; the build is the gate. I checked that the gate
is real rather than assuming it: injecting a type error into an unreferenced
shadlike file does fail `bun run build:ui`, so ngtsc type-checks the whole
program including components nothing imports. Without that check, "the build
passes" would have proven nothing about 18 files no one references.
win7 remains pixel-identical to the pre-refactor baseline.
Co-Authored-By: Claude <noreply@anthropic.com>