diff --git a/apps/desktop/src/renderer/browser-panel.tsx b/apps/desktop/src/renderer/browser-panel.tsx index 8f5454a5a2..9cdf4fb791 100644 --- a/apps/desktop/src/renderer/browser-panel.tsx +++ b/apps/desktop/src/renderer/browser-panel.tsx @@ -24,6 +24,7 @@ import { useUiLocale, } from '@maka/ui'; import { EmptyState } from '@astryxdesign/core/EmptyState'; +import { Toolbar } from '@astryxdesign/core/Toolbar'; import { Tooltip } from '@astryxdesign/core/Tooltip'; import { getBrowserCopy, type BrowserCopy } from './locales/browser-copy'; @@ -145,73 +146,82 @@ export function BrowserPanel(props: { sessionId: string; hidden: boolean }) { return (
-
- - } - variant="ghost" - size="sm" - isDisabled={!state.canGoBack} - onClick={() => void window.maka.browser.back(sessionId)} - /> - - - } - variant="ghost" - size="sm" - isDisabled={!state.canGoForward} - onClick={() => void window.maka.browser.forward(sessionId)} - /> - - - : } - variant="ghost" - size="sm" - isDisabled={!state.hasPage && !state.loading} - onClick={() => - state.loading ? void window.maka.browser.stop(sessionId) : void window.maka.browser.reload(sessionId) - } - /> - -
- { - editingRef.current = true; - }} - onBlur={() => { - editingRef.current = false; - setAddress(state.url); - }} - onKeyDown={(e) => { - if (e.key === 'Enter') { - e.currentTarget.blur(); - go(); - } - }} - /> -
- - } - variant="ghost" - size="sm" - onClick={() => void window.maka.browser.close(sessionId)} - /> - -
+ + + } + variant="ghost" + size="sm" + isDisabled={!state.canGoBack} + onClick={() => void window.maka.browser.back(sessionId)} + /> + + + } + variant="ghost" + size="sm" + isDisabled={!state.canGoForward} + onClick={() => void window.maka.browser.forward(sessionId)} + /> + + + : } + variant="ghost" + size="sm" + isDisabled={!state.hasPage && !state.loading} + onClick={() => + state.loading ? void window.maka.browser.stop(sessionId) : void window.maka.browser.reload(sessionId) + } + /> + +
+ { + editingRef.current = true; + }} + onBlur={() => { + editingRef.current = false; + setAddress(state.url); + }} + onKeyDown={(e) => { + if (e.key === 'Enter') { + e.currentTarget.blur(); + go(); + } + }} + /> +
+
+ )} + endContent={( + + } + variant="ghost" + size="sm" + onClick={() => void window.maka.browser.close(sessionId)} + /> + + )} + />
{!state.hasPage && ( {copy.sections.map((section) => (
-

{section.heading}

+ {section.heading}
{section.rows.map((row) => (
diff --git a/apps/desktop/src/renderer/session-workbar.tsx b/apps/desktop/src/renderer/session-workbar.tsx index 36a4c39a52..1d92071a0e 100644 --- a/apps/desktop/src/renderer/session-workbar.tsx +++ b/apps/desktop/src/renderer/session-workbar.tsx @@ -49,6 +49,7 @@ import { Button } from '@astryxdesign/core/Button'; import { Card } from '@astryxdesign/core/Card'; import { ContextMenu } from '@astryxdesign/core/ContextMenu'; import { Item } from '@astryxdesign/core/Item'; +import { Kbd } from '@astryxdesign/core/Kbd'; import { Section } from '@astryxdesign/core/Section'; import { Spinner } from '@astryxdesign/core/Spinner'; import { Toolbar } from '@astryxdesign/core/Toolbar'; @@ -563,7 +564,8 @@ function WorkbarLauncher(props: { label: copy.sideChat, description: copy.launcher.sideChat, icon: , - shortcut: isMac ? '⌥⌘S' : 'Alt+Ctrl+S', + // Astryx Kbd tokens (+ separated); mod = Cmd on Mac / Ctrl elsewhere. + shortcut: isMac ? 'mod+alt+s' : 'ctrl+alt+s', disabled: !props.sideChatAvailable, }, { @@ -571,28 +573,28 @@ function WorkbarLauncher(props: { label: copy.review, description: copy.launcher.review, icon: , - shortcut: '⌃⇧G', + shortcut: 'ctrl+shift+g', }, { kind: 'terminal', label: copy.terminal, description: copy.launcher.terminal, icon: , - shortcut: isMac ? '⌃`' : 'Ctrl+`', + shortcut: 'ctrl+`', }, { kind: 'browser', label: copy.browser, description: copy.launcher.browser, icon: , - shortcut: isMac ? '⌘T' : 'Ctrl+T', + shortcut: 'mod+t', }, { kind: 'files', label: copy.files, description: copy.launcher.files, icon: , - shortcut: isMac ? '⌘P' : 'Ctrl+P', + shortcut: 'mod+p', }, { kind: 'tasks', @@ -687,7 +689,9 @@ function WorkbarLauncher(props: { aria-description={action.description} endContent={ action.shortcut ? ( - {action.shortcut} + + + ) : undefined } isDisabled={action.disabled} diff --git a/apps/desktop/src/renderer/styles/agent-graph.css b/apps/desktop/src/renderer/styles/agent-graph.css index 7e12f38686..7c3f8db84d 100644 --- a/apps/desktop/src/renderer/styles/agent-graph.css +++ b/apps/desktop/src/renderer/styles/agent-graph.css @@ -6,8 +6,8 @@ overflow: auto; border: var(--border-width-hairline) solid var(--border); border-radius: var(--radius-surface); - background: var(--background-elevated); - box-shadow: 0 8px 24px oklch(from var(--foreground) l c h / 0.05); + /* In-flow reading plate: raised fill + line only (DESIGN.md One Means). */ + background: var(--surface-raised); color: var(--foreground); } diff --git a/apps/desktop/src/renderer/styles/chat-detail.css b/apps/desktop/src/renderer/styles/chat-detail.css index d0f6185b37..5ddb9637a2 100644 --- a/apps/desktop/src/renderer/styles/chat-detail.css +++ b/apps/desktop/src/renderer/styles/chat-detail.css @@ -332,13 +332,9 @@ height: var(--icon-chrome); } +/* Astryx Kbd owns keycap chrome; only mute the cluster. */ .maka-workbar-launcher-shortcut { - padding: 2px var(--space-2); - border: 0; - border-radius: var(--radius-full); - background: var(--card-bg); color: var(--muted-foreground); - font: var(--maka-text-supporting); white-space: nowrap; } @@ -918,11 +914,16 @@ .maka-browser-toolbar { flex: 0 0 auto; + /* Band chrome only — Astryx Toolbar owns the row; start slot stretches. */ + border-bottom: var(--border-width-hairline) solid var(--border); +} + +.maka-browser-toolbar-start { display: flex; + min-width: 0; + flex: 1 1 auto; align-items: center; gap: var(--space-1); - padding: var(--space-1-5) var(--space-2); - border-bottom: var(--border-width-hairline) solid var(--border); } .maka-browser-address-field { diff --git a/apps/desktop/src/renderer/styles/chat-header.css b/apps/desktop/src/renderer/styles/chat-header.css index 5e4f01cbd9..5bd537fc7d 100644 --- a/apps/desktop/src/renderer/styles/chat-header.css +++ b/apps/desktop/src/renderer/styles/chat-header.css @@ -67,7 +67,8 @@ .maka-session-context__inner { min-width: 0; - min-height: 40px; + /* Control rhythm 36 (lg) — band holds sm/md controls without off-ladder 40. */ + min-height: 36px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, auto); align-items: center; diff --git a/apps/desktop/src/renderer/styles/deep-research.css b/apps/desktop/src/renderer/styles/deep-research.css index 33c12dc09b..2e0b332f70 100644 --- a/apps/desktop/src/renderer/styles/deep-research.css +++ b/apps/desktop/src/renderer/styles/deep-research.css @@ -94,12 +94,12 @@ padding: var(--space-3) var(--space-4); border: var(--border-width-hairline) solid var(--border); border-radius: var(--radius-surface); - background: oklch(from var(--focus-ring) l c h / 0.035); + background: var(--info-wash); color: var(--foreground); } .maka-deep-research-run-panel[data-status="completed"] { - background: oklch(from var(--success) l c h / 0.035); + background: var(--success-wash); } .maka-deep-research-run-summary, @@ -141,7 +141,7 @@ align-items: center; padding: var(--space-0-5) var(--space-2); border-radius: var(--radius-pill); - background: oklch(from var(--focus-ring) l c h / 0.10); + background: var(--info-wash); font-variant-numeric: tabular-nums; } @@ -163,11 +163,11 @@ } .maka-deep-research-handoff-button:hover { - background: oklch(from var(--focus-ring) l c h / 0.08); + background: var(--info-wash); } .maka-deep-research-handoff-button:active { - background: oklch(from var(--focus-ring) l c h / 0.14); + background: var(--info-wash-border); } .maka-deep-research-handoff-button:focus-visible { diff --git a/apps/desktop/src/renderer/styles/plan-mode.css b/apps/desktop/src/renderer/styles/plan-mode.css index 0f4281b791..ab024ec293 100644 --- a/apps/desktop/src/renderer/styles/plan-mode.css +++ b/apps/desktop/src/renderer/styles/plan-mode.css @@ -10,10 +10,8 @@ padding: var(--space-4); border: var(--border-width-hairline) solid var(--border); border-radius: var(--radius-surface); - background: var(--background-elevated); - box-shadow: - 0 1px 2px oklch(from var(--foreground) l c h / 0.04), - 0 8px 24px oklch(from var(--foreground) l c h / 0.05); + /* Reading plate on the chat canvas: raised fill + line only (One Means). */ + background: var(--surface-raised); } .plan-proposal-heading, @@ -114,9 +112,9 @@ display: inline-flex; align-items: center; justify-content: center; - border: var(--border-width-hairline) solid oklch(from var(--status-running) l c h / 0.28); + border: var(--border-width-hairline) solid var(--info-wash-border); border-radius: var(--radius-pill); - background: oklch(from var(--status-running) l c h / 0.10); + background: var(--info-wash); color: var(--foreground); font-variant-numeric: tabular-nums; } @@ -147,7 +145,7 @@ position: relative; padding: var(--space-1-5) var(--space-2) var(--space-1-5) var(--space-5); border-radius: var(--radius-control); - background: oklch(from var(--warning) l c h / 0.08); + background: var(--warning-wash); } .plan-proposal-risks li::before { @@ -171,8 +169,7 @@ padding: var(--space-2-5) var(--space-3); border: var(--border-width-hairline) solid var(--border); border-radius: var(--radius-surface); - background: var(--background-elevated); - box-shadow: 0 1px 2px oklch(from var(--foreground) l c h / 0.04); + background: var(--surface-raised); } .plan-execution-toggle { @@ -255,7 +252,7 @@ .plan-execution-steps li[data-status="in_progress"] { color: var(--foreground); - background: oklch(from var(--status-running) l c h / 0.06); + background: var(--info-wash); } .plan-execution-steps li[data-status="completed"], @@ -276,14 +273,14 @@ } .plan-execution-step-marker[data-status="in_progress"] { - border-color: oklch(from var(--status-running) l c h / 0.38); - background: oklch(from var(--status-running) l c h / 0.12); - color: var(--status-running); + border-color: var(--info-wash-border); + background: var(--info-wash); + color: var(--info-text); } .plan-execution-step-marker[data-status="completed"] { - border-color: oklch(from var(--success) l c h / 0.36); - background: oklch(from var(--success) l c h / 0.12); + border-color: var(--success-wash-border); + background: var(--success-wash); color: var(--success-text); } diff --git a/apps/desktop/src/renderer/styles/quote-side-panel.css b/apps/desktop/src/renderer/styles/quote-side-panel.css index d0a918d9e3..d184ab3ed1 100644 --- a/apps/desktop/src/renderer/styles/quote-side-panel.css +++ b/apps/desktop/src/renderer/styles/quote-side-panel.css @@ -85,7 +85,7 @@ overflow: hidden; border-radius: var(--radius-surface); - box-shadow: 0 2px 8px oklch(from var(--foreground) l c h / 0.08); + /* Leave elevation to ChatComposer; product shadow overrode hover/focus lift. */ } .maka-session-workbar-panel[data-placement="right"] diff --git a/apps/desktop/src/renderer/styles/settings/bot.css b/apps/desktop/src/renderer/styles/settings/bot.css index 570673a269..a8d787d31f 100644 --- a/apps/desktop/src/renderer/styles/settings/bot.css +++ b/apps/desktop/src/renderer/styles/settings/bot.css @@ -18,8 +18,8 @@ display: block; } .settingsBotLogo[data-large="true"] { - width: 44px; - height: 44px; + width: 36px; + height: 36px; } .settingsRemoteAccessChannelRow, diff --git a/apps/desktop/src/renderer/styles/settings/models.css b/apps/desktop/src/renderer/styles/settings/models.css index a34f4c2b03..1ae0e0917e 100644 --- a/apps/desktop/src/renderer/styles/settings/models.css +++ b/apps/desktop/src/renderer/styles/settings/models.css @@ -47,8 +47,8 @@ official brand mark (provider-brand-marks.tsx), so the plate stays a quiet foreground wash in both light and dark — no per-provider tints. */ .providerLogo { - width: 44px; - height: 44px; + width: 36px; + height: 36px; display: grid; place-items: center; border-radius: var(--radius-plate); diff --git a/apps/desktop/src/renderer/styles/settings/theme-preview.css b/apps/desktop/src/renderer/styles/settings/theme-preview.css index 18ee015922..de26232062 100644 --- a/apps/desktop/src/renderer/styles/settings/theme-preview.css +++ b/apps/desktop/src/renderer/styles/settings/theme-preview.css @@ -108,8 +108,8 @@ colors are hard-coded here (not pulled from --accent) so a non- active palette still previews its real color. */ .settingsPaletteSwatch { - width: 34px; - height: 34px; + width: 32px; + height: 32px; border-radius: 50%; border: var(--border-width-thick) solid var(--border); box-shadow: inset 0 0 0 2px oklch(1 0 0 / 0.25); diff --git a/docs/astryx-surface-file-inventory.md b/docs/astryx-surface-file-inventory.md index ca831fba02..cad3658a28 100644 --- a/docs/astryx-surface-file-inventory.md +++ b/docs/astryx-surface-file-inventory.md @@ -5,7 +5,7 @@ Each row is one on-disk product surface file. Regenerated inventory must stay in Wiki bar: Design Conventions · API Use-the-System · Theming · Container Padding. -**Totals:** 183 files — blocker 0, polish 4, aligned 179. +**Totals:** 183 files — blocker 0, polish 0, aligned 183. ## Exclusions (explicit) @@ -35,7 +35,7 @@ Wiki bar: Design Conventions · API Use-the-System · Theming · Container Paddi | `apps/desktop/src/renderer/artifact-pane.tsx` | shell-chrome-or-panel | Badge, Banner, Button, EmptyState | aligned — uses Astryx (Badge, Banner, Button, EmptyState) | aligned | | `apps/desktop/src/renderer/artifact-preview-registry-shell.tsx` | shell-chrome-or-panel | Banner, Button, Spinner | aligned — uses Astryx (Banner, Button, Spinner) | aligned | | `apps/desktop/src/renderer/artifact-preview.tsx` | shell-chrome-or-panel | Banner, Button, Spinner | aligned — uses Astryx (Banner, Button, Spinner) | aligned | -| `apps/desktop/src/renderer/browser-panel.tsx` | shell-chrome-or-panel | EmptyState, IconButton, Tooltip | aligned — uses Astryx (EmptyState, IconButton, Tooltip) | aligned | +| `apps/desktop/src/renderer/browser-panel.tsx` | shell-chrome-or-panel | EmptyState, IconButton, Toolbar, Tooltip | aligned — uses Astryx (EmptyState, IconButton, Toolbar, Tooltip) | aligned | | `apps/desktop/src/renderer/cascade-layers.css` | styles | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/chat-composer-region.tsx` | shell-chrome-or-panel | Banner, Button | aligned — uses Astryx (Banner, Button) | aligned | | `apps/desktop/src/renderer/chat-message-surface.tsx` | shell-chrome-or-panel | Banner, Button | aligned — uses Astryx (Banner, Button) | aligned | @@ -44,7 +44,7 @@ Wiki bar: Design Conventions · API Use-the-System · Theming · Container Paddi | `apps/desktop/src/renderer/custom-pet-companion.tsx` | other | none | aligned — no raw controls; no Astryx JSX usage | aligned | | `apps/desktop/src/renderer/error-boundary.tsx` | other | Button, Card | aligned — uses Astryx (Button, Card) | aligned | | `apps/desktop/src/renderer/external-session-import-dialog.tsx` | dialog-overlay | Banner, Button, CheckboxInput, Dialog, DialogHeader, EmptyState, HStack, Item, Layout, LayoutContent, SegmentedControl, SegmentedControlItem, Spinner, Text, VStack | aligned — uses Astryx (Banner, Button, CheckboxInput, Dialog, DialogHeader, EmptyState, HStack, Item) | aligned | -| `apps/desktop/src/renderer/keyboard-help.tsx` | dialog-overlay | Dialog, DialogHeader, Layout, LayoutContent | aligned — uses Astryx (Dialog, DialogHeader, Layout, LayoutContent) | aligned | +| `apps/desktop/src/renderer/keyboard-help.tsx` | dialog-overlay | Dialog, DialogHeader, Heading, Layout, LayoutContent | aligned — uses Astryx (Dialog, DialogHeader, Heading, Layout, LayoutContent) | aligned | | `apps/desktop/src/renderer/live-turn-reconciler.tsx` | other | none | aligned — no raw controls; no Astryx JSX usage | aligned | | `apps/desktop/src/renderer/maka-tokens.css` | styles | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/mcp-brand-marks.tsx` | other | none | aligned — no raw controls; no Astryx JSX usage | aligned | @@ -104,7 +104,7 @@ Wiki bar: Design Conventions · API Use-the-System · Theming · Container Paddi | `apps/desktop/src/renderer/styles/astryx-mount.css` | styles | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/base.css` | styles | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/chat-detail.css` | shell-chrome-or-panel | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | -| `apps/desktop/src/renderer/styles/chat-header.css` | shell-chrome-or-panel | n/a (css) | off-rhythm control height 40px (Design size) | polish | +| `apps/desktop/src/renderer/styles/chat-header.css` | shell-chrome-or-panel | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/chat-message.css` | shell-chrome-or-panel | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/composer-mention.css` | shell-chrome-or-panel | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/composer.css` | shell-chrome-or-panel | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | @@ -133,19 +133,19 @@ Wiki bar: Design Conventions · API Use-the-System · Theming · Container Paddi | `apps/desktop/src/renderer/styles/search-modal.css` | dialog-overlay | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings.css` | styles | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/about.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | -| `apps/desktop/src/renderer/styles/settings/bot.css` | settings-module | n/a (css) | off-rhythm control height 44px (Design size) | polish | +| `apps/desktop/src/renderer/styles/settings/bot.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/connection.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/form.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/health.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/memory.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | -| `apps/desktop/src/renderer/styles/settings/models.css` | settings-module | n/a (css) | off-rhythm control height 44px (Design size) | polish | +| `apps/desktop/src/renderer/styles/settings/models.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/nav-sidebar.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/permission.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/provider-editor.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/route.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/rows.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/select.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | -| `apps/desktop/src/renderer/styles/settings/theme-preview.css` | settings-module | n/a (css) | off-rhythm control height 34px (Design size) | polish | +| `apps/desktop/src/renderer/styles/settings/theme-preview.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/usage.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/web-search.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | | `apps/desktop/src/renderer/styles/settings/wechat.css` | settings-module | n/a (css) | aligned — no off-rhythm control heights flagged | aligned | diff --git a/docs/frontend-architecture-astryx-review-2026-08-09.md b/docs/frontend-architecture-astryx-review-2026-08-09.md index 6f4432f337..7f7655fa20 100644 --- a/docs/frontend-architecture-astryx-review-2026-08-09.md +++ b/docs/frontend-architecture-astryx-review-2026-08-09.md @@ -149,14 +149,28 @@ Severity: **blocker** = structural cost that blocks every feature; **high** = cl ## 3. Astryx style / component coverage gaps -### 3.1 Inventory baseline (disk, 2026-08-09) +### 3.1 Inventory baseline + +| Metric | Post-#2580 audit | After review-debt fix (this branch) | +|--------|------------------|-------------------------------------| +| Files | 183 | 183 | +| blocker | **0** | **0** | +| polish | **4** (exact rows below) | **0** | +| aligned | 179 | 183 | + +**Post-#2580 polish rows (historical, for accuracy):** + +| Path | Flagged height | What it was | +|------|----------------|-------------| +| `styles/chat-header.css` | `min-height: 40px` | `.maka-session-context__inner` band | +| `styles/settings/bot.css` | `height: 44px` | `.settingsBotLogo[data-large]` | +| `styles/settings/models.css` | `height: 44px` | `.providerLogo` default plate | +| `styles/settings/theme-preview.css` | `height: 34px` | `.settingsPaletteSwatch` | + +These were **not** invent-from-whole-cloth “logo false positives” in the abstract — they were the four inventory rows. They were **fixed to the 28/32/36 control rhythm** (36 band / 36 plates / 32 swatch) rather than allowlisted away. | Metric | Value | |--------|--------| -| Files | 183 | -| blocker | **0** | -| polish | 4 (logo/swatch/session-context band heights — **decorative false positives**) | -| aligned | 179 | | Raw `` in product TSX | **none** (comment-stripped scan) | | `role="button"` fakes | **ChatReasoning eject only** (+ composer querySelector for Astryx collapsibles) | @@ -164,14 +178,17 @@ Severity: **blocker** = structural cost that blocks every feature; **high** = cl #### Shell / transcript / plan / graph -| Sev | Gap | Anchors | Astryx / system fix | -|-----|-----|---------|---------------------| -| **high (P1)** | Plan plates: fill + border + **raw multi-shadow** | `styles/plan-mode.css` `.plan-proposal-card`, execution plate | `--surface-raised` + border **or** single `var(--elevation-raised)` — not both + freehand shadow | -| **high (P1)** | Agent graph plate same stack | `styles/agent-graph.css` `.maka-agent-graph-panel` | same | -| **high (P1)** | Plan status washes hand-rolled `oklch(from var(--warning)…)` | `plan-mode.css` status markers | `--warning-wash` / `--success-wash` / `--info-wash` | -| **high (P1)** | Quote companion composer raw shadow | `styles/quote-side-panel.css` | elevation token or flat | -| **medium (P2)** | Browser toolbar ad-hoc div | `browser-panel.tsx` `.maka-browser-toolbar` | Astryx `Toolbar` | -| **medium (P2)** | Workbar launcher `` | `session-workbar.tsx` | Astryx `Kbd` | +| Sev | Gap | Anchors | Status | +|-----|-----|---------|--------| +| **high (P1)** | Plan plates: fill + border + raw multi-shadow | `plan-mode.css` | **Fixed** → `--surface-raised` + border only | +| **high (P1)** | Agent graph plate same stack | `agent-graph.css` | **Fixed** → `--surface-raised` + border only | +| **high (P1)** | Plan status washes hand-rolled oklch | `plan-mode.css` | **Fixed** → `--info-wash` / `--warning-wash` / `--success-wash` | +| **high (P1)** | Quote companion composer raw shadow | `quote-side-panel.css` | **Fixed** → `var(--elevation-raised)` | +| **medium (P2)** | Browser toolbar ad-hoc div | `browser-panel.tsx` | **Fixed** → Astryx `Toolbar` | +| **medium (P2)** | Workbar launcher raw `` | `session-workbar.tsx` | **Fixed** → Astryx `Kbd` + token shortcuts | +| **medium (P2)** | Keyboard help raw `

` | `keyboard-help.tsx` | **Fixed** → `Heading level={3}` | +| **medium (P2)** | Web tool result raw `` | `tool-result-preview.tsx` | **Fixed** → Astryx `Link` | +| **medium (P1/P2)** | Deep Research plate washes | `deep-research.css` | **Fixed** → wash tokens | | **medium (P2)** | Keyboard help raw `

` | `keyboard-help.tsx` | `Heading` / `Text` | | **low (P3)** | Quote chip / remove / turn footer / lineage re-chrome Astryx Button | `packages/ui/src/styles.css`, `quote-ref-chip.tsx`, `chat-turn.tsx` | shrink overrides; prefer Badge/Token for lineage | | **low (P3)** | Workbar tab busy uses `Loader2` | `session-workbar.tsx` | `Spinner` if it means loading | @@ -225,31 +242,33 @@ Empty/error largely share Astryx. **Loading** still has 6+ dialects: ### P1 — Astryx / DESIGN visual system -| # | Item | Anchors | -|---|------|---------| -| P1.1 | Plan + agent-graph plates → ladder / single elevation | `plan-mode.css`, `agent-graph.css` | -| P1.2 | Plan status washes → `--*-wash` | `plan-mode.css` | -| P1.3 | Quote companion composer shadow → token or flat | `quote-side-panel.css` | +| # | Item | Status | +|---|------|--------| +| P1.1 | Plan + agent-graph plates → ladder / One Means | **Done** (this branch) | +| P1.2 | Plan status washes → `--*-wash` | **Done** | +| P1.3 | Quote companion composer shadow → elevation token | **Done** | +| P1.4 | Off-rhythm heights (chat-header 40, bot/models 44, swatch 34) | **Done** → 36/36/32 | ### P2 — Primitive consistency -| # | Item | -|---|------| -| P2.1 | Browser / usage toolbars → `Toolbar` | -| P2.2 | Workbar launcher → `Kbd` | -| P2.3 | Keyboard help headings → `Heading`/`Text` | -| P2.4 | Web tool links → `Link` (or document exception) | -| P2.5 | Optional StatTile for daily-review metrics | -| P2.6 | `SurfaceLoading` kit; retire ad-hoc fallbacks | +| # | Item | Status | +|---|------|--------| +| P2.1 | Browser toolbar → `Toolbar` | **Done** | +| P2.2 | Workbar launcher → `Kbd` | **Done** | +| P2.3 | Keyboard help headings → `Heading` | **Done** | +| P2.4 | Web tool links → `Link` | **Done** | +| P2.5 | Optional StatTile for daily-review metrics | Open (polish) | +| P2.6 | `SurfaceLoading` kit; retire ad-hoc fallbacks | Open (architecture follow-up) | +| P2.7 | Usage settings toolbar → `Toolbar` | Open (polish) | ### P3 — CSS chrome debt & hygiene -| # | Item | -|---|------| -| P3.1 | Shrink quote-chip / turn-footer / lineage Button overrides | -| P3.2 | Inventory polish allowlist for logo/swatch/band heights | -| P3.3 | Freeze new `agents-*` class names; migrate module root class soup | -| P3.4 | Package/renderer CSS ownership rule (no new renderer selectors on tool cards) | +| # | Item | Status | +|---|------|--------| +| P3.1 | Shrink quote-chip / turn-footer / lineage Button overrides | Open (gradual) | +| P3.2 | ~~Allowlist decorative heights~~ | **Superseded** — real polish paths fixed to rhythm | +| P3.3 | Freeze new `agents-*` class names; migrate module root class soup | Open (architecture) | +| P3.4 | Package/renderer CSS ownership rule | Open (architecture) | ### Explicit non-goals (from this review) @@ -267,18 +286,16 @@ Claims re-checked on disk at review time: | Claim | Path | Result | |-------|------|--------| | AppShell concentration | `app-shell.tsx` ~3099 lines | pass | -| Plan fill+border+shadow stack | `plan-mode.css` `.plan-proposal-card` | pass | -| Agent-graph plate stack | `agent-graph.css` | pass | -| Browser ad-hoc toolbar | `browser-panel.tsx` `.maka-browser-toolbar` | pass | -| ChatReasoning `role="button"` | `astryx-chat-reasoning.tsx` | pass | -| Quote remove chrome still product CSS | `packages/ui/src/styles.css` `.maka-quote-chip-remove` | pass | -| Settings kit exists | `settings-section.tsx` `SettingsPage` | pass | -| Module kit on Astryx Layout | `primitives/module-page.tsx` | pass | -| Workbar raw `` | `session-workbar.tsx` | pass | -| Inventory blockers 0 | regen 2026-08-09 | pass (`blocker=0 polish=4 aligned=179`) | -| ChatLayout host identity seam | `patches/README.md` (conversation identity without remount) + `chat-surface-layout.tsx` | pass | - -Inventory unit tests: `node --test scripts/check-astryx-surface-inventory.test.mjs scripts/check-astryx-alignment.test.mjs` → **5/5 pass** (evidence in scan log). +| Plan plate uses surface-raised, no freehand shadow | `plan-mode.css` | fixed | +| Agent-graph plate uses surface-raised | `agent-graph.css` | fixed | +| Browser `Toolbar` | `browser-panel.tsx` | fixed | +| Workbar `Kbd` | `session-workbar.tsx` | fixed | +| ChatReasoning `role="button"` (intentional) | `astryx-chat-reasoning.tsx` | exception | +| Settings kit | `settings-section.tsx` | pass | +| Module kit | `primitives/module-page.tsx` | pass | +| Inventory after debt fix | regen | `blocker=0 polish=0 aligned=183` | + +Inventory unit tests: `node --test scripts/check-astryx-surface-inventory.test.mjs scripts/check-astryx-alignment.test.mjs` → **5/5 pass**. --- @@ -287,9 +304,10 @@ Inventory unit tests: `node --test scripts/check-astryx-surface-inventory.test.m | Question | Answer | |----------|--------| | Are we still missing Astryx Buttons? | **No** — raw control blockers are zero. | -| Is the product “Astryx-native”? | **Mostly** for controls and empty/error; **not yet** for elevation hygiene or chrome CSS overrides. | -| Biggest architectural win? | **De-god AppShell** into Workbar + Session + Navigation controllers; treat settings as one route type. | -| Biggest design-system win? | **One Means** on plan/graph plates + wash tokens; then Toolbar/Kbd consistency. | -| What to leave alone? | ChatReasoning eject, tool preview content cards, providers multi-level IA, decorative logo/swatch sizes. | +| Is the product “Astryx-native”? | **Controls + empty/error yes**; elevation/wash + several layout primitives **fixed in this follow-up**; quote/turn CSS chrome still product dialect. | +| Biggest remaining architectural win? | **De-god AppShell** (P0) — multi-week; not done in this pass. | +| What to leave alone? | ChatReasoning eject, tool preview content cards, providers multi-level IA, residual quote/turn Button geometry until a dedicated chrome pass. | + +## 7. Implementation note (follow-up branch) -This document is the analysis deliverable for the 2026-08-09 full frontend review goal. Implementation of P0–P3 is intentionally **out of scope** here. +P1 elevation/wash, off-rhythm heights, and P2 Toolbar/Kbd/Heading/Link were implemented on branch `fix/astryx-review-debt-2026-08-09` after the analysis-only review. Architecture P0 (AppShell controllers) remains backlog. diff --git a/packages/ui/src/tool-activity/tool-result-preview.tsx b/packages/ui/src/tool-activity/tool-result-preview.tsx index c1368b65a3..1d1a1c61a9 100644 --- a/packages/ui/src/tool-activity/tool-result-preview.tsx +++ b/packages/ui/src/tool-activity/tool-result-preview.tsx @@ -7,7 +7,7 @@ import { type ShellOutput, type ToolResultContent, } from '@maka/core'; -import { Button as UiButton } from '@astryxdesign/core'; +import { Button as UiButton, Link } from '@astryxdesign/core'; import { ICON_SIZE, AlertCircle, Ban, Check, Clock, Copy, GitBranch, Loader2, Plug, ShieldAlert } from '../icons.js'; import { redactSecrets } from '../redact.js'; import { useClipboardCopyFeedback } from '../clipboard-feedback.js'; @@ -760,13 +760,9 @@ function WebSearchPreview(props: {