In light mode `--muted-foreground` at oklch(0.552 0.016 285.938) missed the
4.5:1 AA floor on every light surface except pure white. The worst pair was
3.98:1 — nav labels on --sidebar-accent, i.e. the primary navigation in its
hover state. One token backs ~2k `text-muted-foreground` call sites, so the
blast radius is most of the product's secondary text.
Drop lightness to 0.505 and leave hue and chroma alone so the neutral ramp
keeps its cast. Worst case is now 4.88:1. Dark mode already passed at
5.2-7.2:1 and is untouched.
The `.landing-light` block in apps/web re-declares the light palette so
token-driven components stay light under next-themes' `.dark` class; it moves
with the source or it silently drifts.
The new test asserts on the token file rather than on components: the token is
the contract every consumer inherits, and a component test could only prove a
class name is present, not that the pixels are legible.
Co-authored-by: Lambda <lambda@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
The landing tree set `--font-serif` to Instrument Serif, which ships Latin
only, so zh/ja/ko headlines fell out of the stack onto the browser default
sans while the Latin next to them stayed in a high-contrast display serif.
A `Noto_Serif_SC` next/font entry was loaded as `--font-serif-zh` but no
rule ever referenced it, and it requested `subsets: ["latin"]`, so it
downloaded no CJK glyphs either way — remove it.
Compose `--font-serif` for the landing tree in static CSS instead, with a
per-`<html lang>` CJK tail, mirroring the `--font-sans` chain in globals.css:
Chinese before Korean by default, a Mincho-first chain promoted for `ja` so
Kanji do not get Chinese glyph shapes. Platform Songti/Mincho/Myeongjo faces
rather than a multi-megabyte CJK webfont.
The 16 landing surfaces that inlined `font-[family-name:var(--font-serif)]`
now share a `.landing-serif` hook, which gives the per-locale metric reset a
precise target: CJK headings drop the Latin display tracking (down to
-0.038em) and sub-1 leading (0.93) that crowded ideographs and collided the
two lines of a `<br />`-split headline. Korean additionally gets
`word-break: keep-all` so wrapped Hangul breaks at word boundaries.
Scoped to h1/h2 so the Latin-only footer wordmark keeps its tuned tracking.
The English landing hero renders pixel-identical to before.
Co-authored-by: Lambda <lambda@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
Dropdown, context menu, select, and popover surfaces used
--floating-shadow, which is sized for window-level overlays and reads
too heavy on trigger-anchored menus. Introduce a lighter --menu-shadow
tier (surface < menu < floating) and drop the shadow-lg override on
ContextMenuSubContent so submenus match their parent menu. Dialogs and
sheets keep --floating-shadow.
Co-authored-by: Lambda <lambda@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
The priority badge in the issue/project priority picker dropdown used a
parallel `bg-priority` orange color family (with opacity gradient for level
intensity), while the standalone PriorityIcon outside the dropdown used
semantic tokens — destructive for Urgent, warning for High/Medium, info for
Low. The two languages produced an inconsistency users noticed most clearly
on Low: blue in the list, orange in the picker.
Switch the dropdown badges to the same semantic tokens as the icon, and
remove the now-unused `--priority` / `--color-priority` design token from
both `packages/ui/styles/tokens.css` and `apps/web/app/custom.css`.
Closesmultica-ai/multica#2289
Co-authored-by: multica-agent <github@multica.ai>
* fix(landing): scope landing route to always-light palette
The landing page sections use hardcoded light colors (bg-white / #0a0d12),
but shared components rendered inside — notably CloudWaitlistExpand on
/download — use semantic tokens that flip to dark values under next-themes'
`.dark` class, producing a mismatched dark card on an otherwise light page
when the user's OS is in dark mode.
Add a `.landing-light` class on the landing layout wrapper that re-declares
all color tokens to their light values for the subtree, so nested
token-driven components stay in lockstep with the hardcoded palette.
* test(agent): serialize fake-executable writes to avoid ETXTBSY on CI
TestKimiBackendInvokesACPSubcommand (and its Kimi/Codex siblings) write a
shell script to a per-test TempDir and then fork/exec it. With t.Parallel()
enabled across the package, a concurrent goroutine's fork can inherit the
still-open write fd to another test's new executable; Linux then rejects
the subsequent exec with ETXTBSY (seen as
fork/exec /tmp/.../kimi: text file busy
on GitHub Actions).
Introduce writeTestExecutable, which holds syscall.ForkLock.RLock across
OpenFile→Write→Close. Fork (which takes ForkLock.Lock) cannot run while we
hold RLock, so no sibling fork inherits our write fd. Ran the three callers
with -count=10 under -p=1 and the full package with no failures.
- Extract MulticaIcon and ThemeProvider to packages/ui (remove duplication)
- Extract shared CSS (scrollbar, shiki, entrance-spin) to packages/ui/styles/base.css
- Add NavigationAdapter.openInNewTab/getShareableUrl for platform-agnostic navigation
- Fix window.open() / window.location.href in shared views to use NavigationAdapter
- Add resolve.dedupe for React in electron-vite config
- Fix desktop tsconfig (noImplicitAny: true)
- Use catalog: for all desktop dependencies
- Add shadcn + tw-animate-css to desktop dependencies (fix phantom deps)
- Add typecheck scripts to all shared packages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Agent live card now uses the sentinel pattern to detect when it scrolls
out of view. When stuck, it collapses to a compact header bar with brand
styling and backdrop blur, with a ChevronUp button to scroll back.
When scrolled back into view, the card seamlessly expands to full view.
Also adds semantic colors to Sonner toast icons (success/info/warning/
error/loading) and fixes icon-to-text alignment in toasts globally.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix global scrollbar overflow by removing h-svh from html element
- Add h-full overflow-hidden to html/body for proper app-like layout
- Fix default button variant: add shadow-sm and hover:bg-primary/90
- Update sidebar create-issue button to bg-background with shadow
- Add WorkspaceAvatar component and search/new-issue actions to sidebar header
- Improve theme provider with TooltipProvider wrapper
- Polish various page layouts, pickers, modals, and code block styling
- Clean up custom.css unused styles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrate all shadcn components into apps/web/components/ui/ so the web app
is fully independent from packages/ui for its UI layer. Update to the
latest shadcn base-nova style. Add missing semantic color variables
(success, warning, info, canvas), font-mono mapping, scrollbar styling,
and wrap Select items in SelectGroup for proper padding.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>