Stage 4a: context menu is pure 7.css; retire the lookalike and the false claim

The menu now renders 7.css's real contract — ul[role=menu] > li[role=menuitem]
> button for actions, input[type=checkbox] + label for the checkable column
toggles, and dividers as .has-divider on the PRECEDING item (7.css draws them
as an ::after bevel, not as a node; the service's separator entries collapse
onto their predecessor at render time). With the markup right, the framework
supplies everything the hand-written version imitated or lacked: the left
gutter stripe, bevelled separators, the gradient selection band, the checked
box, and disabled/submenu styling we previously had none of.

Deleted: the w7-menu lookalike (both the button-slab stripper in `skin` and
the whole hand-authored Aero set in `skinfix`) and its w7-menu/w7-menu-sep
hooks. The "7.css has no menu component" claims in styles.css and
architecture.md were FALSE — dist/gui/menu.css is a full component; the old
markup (div > button) simply matched none of it. Both corrected to state the
real contract and the trap.

Keyboard now follows the platform instead of a highlight class: arrows move
REAL focus between items — 7.css styles :focus-visible identically to :hover,
and keyboard-initiated programmatic focus counts — and Enter/Space activate
buttons natively; only labels need a synthetic click. This also makes the menu
honest to screen readers.

Dark mode: menu.css hardcodes light literals (color:initial, white bevel
halves, the #b3d3f9 checked-box ring); restated in skinfix's dark arm like the
ListView's.

Also fixed, caught BY the harness: the Stage 3 frame sizing rule was keyed on
bare `.window`, forcing 100vh height onto every 7.css window (the harness's
demo windows blew up to full page). It is now keyed on `w7-frame`, a hook only
the three real window roots carry.

Verified zoomed in light and dark against 7.css's reference markup: gutter,
dividers, checkmark box, grey right-aligned accelerator all match; bundle
490.92 kB.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-16 03:20:55 +02:00
co-authored by Claude
parent 1f773261a8
commit 0ae2a62229
7 changed files with 152 additions and 153 deletions
+30 -49
View File
@@ -580,18 +580,6 @@ body {
content: none;
}
/* Context-menu rows are <button>s, so 7.css would paint each one as an Aero
push-button slab. Strip the slab here (revert-layer needs `skin`); the
Win7 menu paint itself is stated in `skinfix` below. */
.win7 .w7-menu button {
background: revert-layer;
border: 0;
box-shadow: none;
}
.win7 .w7-menu button::before,
.win7 .w7-menu button::after {
content: none;
}
}
/* Above `skin`, for rules that must state a value rather than defer to a
@@ -647,8 +635,11 @@ body {
offset+blur+spread = 13px down/right. An undersized gutter hard-clips a
70%-black shadow into a solid dark band around the window ("way too
strong"); matched to the extents it falls off to nothing. h-screen (100vh)
shrinks by the same totals or the gutter produces a scrollbar. */
.win7 .window {
shrinks by the same totals or the gutter produces a scrollbar.
Keyed on `w7-frame` — the app hook the three window ROOTS carry — never on
bare .window: this sizing is "the window that IS the page", and on any
other .window (dialogs, demos) 100vh is nonsense. */
.win7 .window.w7-frame {
margin: 9px 13px 13px 9px;
height: calc(100vh - 22px);
}
@@ -704,43 +695,33 @@ body {
outline-offset: -1px;
}
/* Aero context menu. 7.css has no menu component, so this is hand-authored —
but ONLY out of the existing --w7-* vars, never literal hex, so the
hand-written dark Win7 palette above recolours it for free. Values are
stated (not reverted), hence `skinfix` rather than `skin`.
A real Win7 menu is a square-cornered white slab with a hairline border
and a gradient selection band that spans the full row. */
.win7 .w7-menu {
border-radius: 0;
border: 1px solid var(--w7-el-bd);
background: var(--w7-surface);
/* ---- Menu (context menu) ----
The menu itself is pure 7.css — ul[role=menu] > li[role=menuitem], see
ui/src/app/context-menu.ts for the exact contract. (A previous iteration
claimed "7.css has no menu component" and hand-built a lookalike here;
false — the markup was one level off and its selectors never matched.)
Only menu.css's hardcoded LIGHT literals need restating for the dark
palette, same as the ListView above: the black `color:initial`, the
white bevel halves of the gutter stripe and dividers, and the checked-box
ring (#b3d3f9). */
.win7[data-theme='dark'] ul[role='menu'] {
color: var(--w7-el-c);
font: var(--w7-font);
padding: 2px;
box-shadow: 0 2px 6px #0000004d;
border-color: var(--w7-el-bd-d);
}
.win7 .w7-menu button {
border-radius: 0;
padding: 3px 8px;
.win7[data-theme='dark'] ul[role='menu']:before {
box-shadow:
inset 1px 0 #00000059,
inset -1px 0 #ffffff14;
}
.win7[data-theme='dark'] ul [role='menuitem'].has-divider:after {
box-shadow:
inset 0 1px #00000059,
inset 0 -1px #ffffff14;
}
.win7[data-theme='dark'] ul [role='menuitem'] > input[type] + label:before {
box-shadow: 0 0 0 1px var(--w7-li-bd-hl);
}
.win7[data-theme='dark'] ul [role='menuitem'] > input[type='checkbox']:checked + label:after {
color: var(--w7-el-c);
}
/* Hover AND keyboard highlight share the band — the utility `bg-accent` that
drives the keyboard cursor is overridden here, so both look identical. */
.win7 .w7-menu button:hover,
.win7 .w7-menu button.bg-accent {
background: var(--w7-li-bg-hl);
border: 1px solid var(--w7-li-bd-hl);
/* keep the 1px border from shifting the label */
padding: 2px 7px;
}
.win7 .w7-menu .w7-menu-sep {
border-color: var(--w7-el-bd);
margin: 2px 0;
}
/* Accelerator hints ride the muted colour, like Win7's grey shortcut column.
Keyed on the utility class the accelerator span carries — `:last-child`
would also catch the LABEL on every item that has no accelerator. */
.win7 .w7-menu button > span.text-muted-foreground {
color: var(--w7-el-c-d);
}
}