Skip to content

fix(ui): bring the composer Skill surface onto Astryx primitives and the product palette #1912

Description

@Astro-Han

What happens

Two defects on the same surface, from the same cause.

The Skill panel has no surface. Opening + → Skills mounts a fully transparent panel with no shadow, so its header, rows and status text overlap the composer placeholder and the transcript behind it. The panel is unreadable and its bounds are invisible.

Skill chips are an off-palette purple. The staged-Skill chips in the context drawer render as <Token color="purple"> (packages/ui/src/composer.tsx).

Why they are one problem

Everything else the composer floats or tints is owned by a system. The + menu is an Astryx DropdownMenu; the / Skill list is an Astryx trigger menu — both take surface, elevation, placement and dismissal from upstream. Colour is governed by DESIGN.md: Maka blue is the single product accent, and "don't introduce another accent" is on its Don't list.

The Skill surface sits outside both. ComposerSkillPicker is a 238-line hand-rolled <div> overlay that imports exactly one Astryx component (IconButton) and paints its own popover surface; purple comes straight from Astryx's stock Token palette, which makaTheme.ts maps nothing onto. Because the surface is product-owned, it is the only composer float that can silently lose its background — and it did.

Root cause of the transparency

packages/ui/src/styles.css:211 builds the panel's surface from three custom properties that are never defined anywhere in the repo:

.maka-composer-skill-panel { z-index: var(--z-overlay); border-radius: var(--radius-surface); color: var(--popover-foreground); background: var(--popover); box-shadow: var(--shadow-maka-panel); }

--popover, --popover-foreground and --shadow-maka-panel have no definition and no var() fallback, so those three declarations are invalid at computed-value time and drop. --z-overlay and --radius-surface do exist, which is why the panel keeps its stacking and its 8px radius while losing its fill.

Measured against the built app through CDP, not inferred from source:

backgroundColor: rgba(0, 0, 0, 0)   boxShadow: none
--popover: ""   --popover-foreground: ""   --shadow-maka-panel: ""
--z-overlay: 300   --radius-surface: 8px

Defining the three missing tokens would restore the fill and leave a second, product-owned popover surface standing beside Astryx's — the same split that let this break. The fix is to stop owning the surface.

Desired outcome

Redesign the Skill surface as one piece:

  • The panel floats on the same Astryx popover primitive as its neighbours, with surface, elevation, placement and dismissal owned upstream rather than by composer-mention.css and styles.css.
  • packages/ui/src/styles.css stops naming undefined tokens.
  • Skill chips draw in the product palette — the neutral Token, or --accent if a staged Skill warrants accent weight — with no hue the design system does not define. The chip is already identified by its label.

Prior art: #1910 fixed the same class of drift on the mode marks, dropping blue / teal / cyan and identifying each mark by its icon under the one accent. The Skill surface was deliberately left alone there to keep that PR to the surface it moved.

Verification

A computed-style contract asserting the panel's resolved background-color is opaque — a screenshot alone would not have caught this, and did not. Extend the composer drawer contract test to assert no composer Token carries an off-palette colour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions