Skip to content

style: Adopt Nothing-inspired design system and fix lint issues#458

Merged
yacosta738 merged 7 commits into
mainfrom
style/nothing
Apr 8, 2026
Merged

style: Adopt Nothing-inspired design system and fix lint issues#458
yacosta738 merged 7 commits into
mainfrom
style/nothing

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

This pull request refactors the CSS architecture for the web clients to fully adopt the Nothing Design System tokens and theme conventions. It updates documentation, dependencies, and the chat app's CSS to consistently use the new --corvus-* custom properties, and removes legacy or ad-hoc color/spacing/font values. The changes also standardize font loading and theme integration across all apps.

Design System & Theming Updates:

  • Updated CSS_ARCHITECTURE.md to document the Nothing Design System token conventions, theme switching logic, Tailwind v4 integration, and Starlight (docs) theming bridge. Added guidance for font loading and token mapping. [1] [2]

Font Management:

  • Switched chat app font dependencies to Space Grotesk, Space Mono, and Doto, removing previous fonts (Manrope, Inter, Syne, JetBrains Mono).

Chat App CSS Refactor:

  • Replaced all legacy or generic CSS custom properties (e.g., --color-bg-primary) with canonical Nothing tokens (e.g., --corvus-color-bg-base) throughout App.vue styles. Updated border radius, color, background, and motion variables to use design tokens. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]

UI Consistency & Minor Improvements:

  • Updated button variants in the chat app from outline to secondary for improved consistency with the design system. [1] [2]
  • Removed unused or redundant animation classes from logo and hero icons. [1] [2]

These changes ensure all web clients use a unified, token-based design system for colors, typography, spacing, and theming, simplifying future maintenance and enabling consistent dark/light mode support.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Migrates web apps to the "Nothing Design System": adds nothing-theme.css/nothing-shell.css/tailwind-bridge.css, replaces legacy token imports, updates Button/Input variants and component styles to --corvus-* tokens, swaps fonts to Space Grotesk/Space Mono/Doto, and adds comprehensive design/spec/task/verify documentation.

Changes

Cohort / File(s) Summary
Shared Token & Shell
clients/web/packages/shared/nothing-theme.css, clients/web/packages/shared/nothing-shell.css, clients/web/packages/shared/tailwind-bridge.css, clients/web/packages/shared/base.css, clients/web/packages/shared/package.json, clients/web/packages/shared/README.md
Introduce canonical --corvus-* tokens (dark-first), dual-theme shell, Tailwind v4 @theme bridge, reduced-motion !important, and update package exports/README.
UI Components (shared)
clients/web/packages/ui/src/components/Button.vue, clients/web/packages/ui/src/components/Input.vue
Rename Button variants (primary/secondary/destructive/ghost), restyle button/input to Nothing tokens (spacing/radius/motion/typography), change focus treatment and sizing, add aria-invalid input handling.
Chat App
clients/web/apps/chat/src/*, clients/web/apps/chat/package.json, clients/web/apps/chat/src/main.ts, clients/web/apps/chat/src/style.css
Switch to nothing-shell.css and tailwind-bridge.css, replace font dependencies with Space Grotesk/Space Mono/Doto, migrate scoped component styles to --corvus-* tokens, change several buttons to variant="secondary", and remove pulse-glow animation.
Dashboard App
clients/web/apps/dashboard/src/*, clients/web/apps/dashboard/package.json, clients/web/apps/dashboard/src/main.ts, clients/web/apps/dashboard/src/style.css
Same migration as Chat: fonts, shell/bridge imports, component CSS → --corvus-*, button variant updates, transition/motion and radius token adoption; also contains a merge-conflict block to resolve.
Docs (Starlight)
clients/web/apps/docs/src/styles/custom.css, clients/web/apps/docs/astro.config.mjs, clients/web/apps/docs/package.json
Map --corvus-*--sl-* tokens for Starlight, add self-hosted @fontsource imports, split theme-color meta for light/dark, remove glass/blur effects, adopt Nothing tokens.
Marketing (Astro)
clients/web/apps/marketing/src/styles/global.css, clients/web/apps/marketing/src/layouts/MarketingLayout.astro, clients/web/apps/marketing/package.json
Remove Google Fonts links, add @fontsource packages, switch to nothing-theme.css, and rewrite global styles to Nothing tokens (remove glass/shimmer gradients).
Workspace & Catalog
clients/web/package.json, clients/web/pnpm-workspace.yaml
Remove root font deps, add Space Grotesk/Space Mono/Doto to workspace catalog, and add per-app font dependency updates.
App component CSS updates
clients/web/apps/*/src/components/** (chat, dashboard)
Bulk replace legacy --color-*, color-mix, gradients, glows, and decorative shadows with --corvus-* tokens and motion/radius tokens; standardize transitions and remove decorative effects.
Architecture & Specs
clients/web/CSS_ARCHITECTURE.md, openspec/changes/archive/2026-04-08-nothing-design-system/*, openspec/specs/*
Add full design/proposal/spec/task/verify archives; formalize token naming and theme precedence, Tailwind bridge, Starlight mapping, font strategy, and migration checklist.
Docs/Verification Artifacts
openspec/changes/archive/.../verify*.md, .../report.md, .../state.yaml
Add verification reports, archive report, design/spec/proposal/exploration/tasks, and state tracking files recording migration status and verification outcomes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • yuniel-acosta
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main change: adopting Nothing-inspired design system and fixing lint issues. Follows Conventional Commit style with 'style:' prefix and stays within 72-character limit.
Description check ✅ Passed Description provides comprehensive coverage of all major changes: design system updates, font management, CSS refactoring, and UI consistency improvements. All required sections are present and well-documented with specific references.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch style/nothing

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 26

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/web/apps/chat/src/main.ts`:
- Around line 5-9: The workspace is missing catalog entries for the font
packages imported in main.ts; add `@fontsource-variable/space-grotesk`,
`@fontsource/space-mono`, and `@fontsource/doto` to the catalog: section of
pnpm-workspace.yaml, setting their versions to match the versions declared in
the chat app's package.json (use the exact version strings used by the chat
app), ensure the package names match exactly (including the variable namespace
for space-grotesk), save the file and run pnpm install to verify the
installation.

In `@clients/web/apps/dashboard/src/components/config/TunnelOverview.vue`:
- Around line 126-128: Replace the hardcoded border-radius in TunnelOverview.vue
with the shared CSS token used by SchedulerStatus.vue to keep components
consistent: change the rule that currently sets "border-radius: 10px" (in the
TunnelOverview style for the relevant container/status item) to use
"var(--corvus-radius-input)" instead so both components use the same radius
variable.

In `@clients/web/apps/dashboard/src/style.css`:
- Around line 1-3: The `@import` rules in style.css use url(...) which violates
Stylelint; change each `@import` url("...") to the string form `@import` "..."
(e.g., replace `@import` url("@corvus/shared/nothing-shell.css"); with `@import`
"@corvus/shared/nothing-shell.css"; and do the same for "tailwindcss" and
"@corvus/shared/tailwind-bridge.css") so lint accepts the imports.

In `@clients/web/apps/docs/astro.config.mjs`:
- Around line 69-70: The static meta tag setting name: "theme-color" with
content: "#000000" causes incorrect color in light mode; update the logic that
sets the theme-color meta in astro.config.mjs and the corresponding component in
MarketingLayout.astro to either emit two meta tags (one with
media="(prefers-color-scheme: light)" and one with media="(prefers-color-scheme:
dark)") or update the single meta tag dynamically when the document's data-theme
attribute changes; locate the code that defines the meta entry named
"theme-color" and replace it with per-scheme tags or add a small client-side
script that watches document.documentElement.dataset.theme and updates
document.querySelector('meta[name="theme-color"]').content accordingly so the
address/status bar matches the active theme.

In `@clients/web/apps/docs/package.json`:
- Around line 19-21: Add the three missing catalog entries for the font packages
so pnpm can resolve them: update pnpm-workspace.yaml's catalog section to
include entries for `@fontsource-variable/space-grotesk`, `@fontsource/doto`, and
`@fontsource/space-mono` with their appropriate versions (e.g.
`@fontsource-variable/space-grotesk`: <version>, `@fontsource/doto`: <version>,
`@fontsource/space-mono`: <version>); ensure the package names match exactly
what's declared in clients/web/apps/docs/package.json and commit the updated
pnpm-workspace.yaml.

In `@clients/web/apps/docs/src/styles/custom.css`:
- Around line 8-16: Change all CSS `@import` rules to use string notation instead
of url(), e.g. replace occurrences like `@import`
url("@fontsource-variable/space-grotesk"); and `@import`
url("@corvus/shared/base.css"); with `@import`
"@fontsource-variable/space-grotesk"; and `@import` "@corvus/shared/base.css"; so
every import line in custom.css uses the modern string form to satisfy
Stylelint.

In `@clients/web/apps/marketing/package.json`:
- Around line 22-24: The package.json references three font dependencies with
catalog: resolutions that are missing from the workspace
catalog—@fontsource-variable/space-grotesk, `@fontsource/doto`, and
`@fontsource/space-mono`—causing pnpm install to fail; either add matching entries
for these three package names to the workspace catalog defined in
pnpm-workspace.yaml, or remove the catalog: prefix in
clients/web/apps/marketing/package.json and replace each with an explicit
version (e.g., "@fontsource-variable/space-grotesk": "x.y.z") so pnpm can
resolve them.

In `@clients/web/apps/marketing/src/styles/global.css`:
- Around line 7-15: Replace all `@import` url(...) usages in global.css with the
string-based `@import` "..." syntax to satisfy stylelint; specifically update the
imports for "@corvus/shared/nothing-theme.css", "@corvus/shared/base.css",
"@fontsource-variable/space-grotesk", "@fontsource/space-mono/400.css",
"@fontsource/space-mono/700.css", "@fontsource/doto/400.css", and
"@fontsource/doto/700.css" so they use `@import` "path"; (no url()). Ensure
spacing/quotation matches the project's CSS style conventions.

In `@clients/web/CSS_ARCHITECTURE.md`:
- Around line 100-102: Add a short clarifying note in CSS_ARCHITECTURE.md
explaining that the double-prefix Tailwind v4 utilities (examples: bg-bg-base,
text-text-primary, border-border-visible) occur because the `@theme` variable name
becomes the utility suffix (e.g., CSS custom property --color-bg-base maps to
bg-bg-base), and state that this is intentional; optionally mention the
alternative of renaming canonical token keys (for example using --color-surface
instead of --color-bg-surface) to produce single-prefix utilities like
bg-surface if the team prefers shorter names.

In `@clients/web/packages/shared/nothing-shell.css`:
- Around line 1-2: Change the CSS import notation from url(...) to plain string
form to satisfy Stylelint: update the `@import` rules that reference
"./nothing-theme.css" and "./base.css" (the existing lines using `@import`
url("./nothing-theme.css") and `@import` url("./base.css")) to use `@import`
"./nothing-theme.css"; and `@import` "./base.css"; respectively.

In `@clients/web/packages/shared/nothing-theme.css`:
- Around line 139-153: The html[data-theme="dark"] block duplicates variables
already defined in :root causing maintenance overhead; update
html[data-theme="dark"] to be minimal by removing identical variable
declarations and only include variables that differ from :root (or make it empty
and rely on :root/defaults plus a small override set), leaving :root as the
single source of truth for defaults and keeping html[data-theme="dark"] for true
dark-mode overrides only; refer to the html[data-theme="dark"] selector and the
:root variable declarations when making the change.
- Around line 20-23: The light-mode token --corvus-color-text-disabled currently
fails WCAG AA on the light background; update the light-mode value of
--corvus-color-text-disabled to a darker hex that meets at least 3:1 contrast
against `#f5f5f5` (for example replace with `#767676` which achieves ~3:1), and
verify the change in the stylesheet where --corvus-color-text-disabled is
defined so the new value is used in light-mode components.

In `@clients/web/packages/ui/src/components/Button.vue`:
- Around line 44-45: The base rule setting min-height: 44px prevents the
.btn-size--sm height: 36px from taking effect; remove the global min-height or
move it into the size-specific rules so each size sets its own min-height (e.g.,
set .btn-size--sm { min-height: 36px } and .btn-size--md/.btn-size--lg {
min-height: 44px } or delete the base min-height and add min-height to each
.btn-size--*), and apply the same change to the other occurrences around lines
114-123 to preserve the small-button contract.

In `@clients/web/packages/ui/src/components/Input.vue`:
- Around line 26-54: Padding on .form-input uses var(--corvus-spacing-xs) which
yields only 4px horizontal space; increase the horizontal padding by replacing
var(--corvus-spacing-xs) with a larger spacing token (e.g.,
var(--corvus-spacing-sm) or var(--corvus-spacing-md)) in the .form-input rule so
text isn't cramped, update the padding declaration there and confirm the change
with design if the Nothing Design tightness was intentional.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/design.md`:
- Around line 56-61: Several fenced code blocks in the design doc are missing
language specifiers which breaks syntax highlighting; update each affected block
(e.g., the CSS snippet containing ":root { }", "@media (prefers-color-scheme:
light) { :root { } }", "html[data-theme=\"light\"] { }" and other listed
sections) to include an appropriate language tag (use ```css for CSS snippets,
```text or ```none for plain paths/filenames) so tooling can correctly highlight
and parse them; ensure every fenced block at the flagged ranges is adjusted
consistently.
- Around line 463-505: The markdown in the design.md file has fenced code blocks
for TypeScript, CSS, and HTML examples that are not surrounded by blank lines
(MD031); add a single blank line above and below each fenced code block (the
blocks showing the TypeScript imports, the custom.css CSS block, the
MarketingLayout.astro HTML snippet, and the marketing/src/styles/global.css CSS
block) so every ```typescript, ```css and ```html fence is preceded and followed
by an empty line, preserving the existing fence languages and content.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md`:
- Line 1: The first line currently uses a second-level heading "## Exploration:
Nothing Design System Overhaul" which triggers markdownlint MD041; change that
top line to a first-level heading by replacing the leading "##" with "#" so it
reads "# Exploration: Nothing Design System Overhaul" to satisfy the rule and
keep the existing title text unchanged.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md`:
- Around line 74-87: Update the archived proposal to call out that the token
values shown are preliminary and the canonical source is the implemented theme
file: add a brief note after the token table stating that final token values
live in nothing-theme.css and list the specific differing tokens
(corvus.color.bg.surface, corvus.color.text.primary,
corvus.color.accent.default) so readers know to reference nothing-theme.css for
the authoritative values; no other content changes to the proposal are needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md`:
- Around line 139-145: Scenario text is ambiguous about exact spacing: update
the Label scenario to assert the label uses the design token value rather than a
generic minimum—change the "letter-spacing MUST be at least 0.06em" requirement
to assert letter-spacing MUST equal the token
`--corvus-typography-scale-label-ls` (currently `0.08em` in nothing-theme.css),
or alternatively change the token to `0.06em` if you intend the spec minimum to
be the canonical value; ensure the scenario references
`corvus.typography.scale.label` and the token name
`--corvus-typography-scale-label-ls` so tests validate the token equality.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`:
- Around line 76-95: The spec's Starlight token mapping table is inconsistent
with the actual mapping used in custom.css; update the spec table entries for
`--sl-color-gray-1`, `--sl-color-gray-3`, and `--sl-color-gray-4` to match the
implementation (i.e., map `--sl-color-gray-1` to `--corvus-color-text-primary`,
`--sl-color-gray-3` to `--corvus-color-text-disabled`, and `--sl-color-gray-4`
to `--corvus-color-border-visible`), or alternatively change the `custom.css`
mappings to match the spec—whichever keeps docs and code aligned—and ensure
`--sl-color-gray-2` remains mapped to `--corvus-color-text-secondary`; update
the spec table accordingly so the token names in the table exactly match the
implementation.
- Around line 171-192: The fenced code block that begins with "@theme { ... }"
is missing a language identifier; update the opening triple-backtick to include
a language (use "css") so the block is ```css `@theme` { ... }```—apply this
change to the `@theme` code block in the spec so static analysis MD040 is resolved
and syntax highlighting works.
- Line 187: Design.md defines --corvus-color-interactive without the -default
suffix, which mismatches spec.md and nothing-theme.css; update the token
declaration in Design.md (replace any occurrences of --corvus-color-interactive
in the theming tokens block with --corvus-color-interactive-default) so the
token name aligns with the spec and the actual theme implementation, and verify
any references in the same file use the new --corvus-color-interactive-default
identifier.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/web-styling/spec.md`:
- Line 44: The spec refers to a non-existent motion token
`--corvus-motion-duration-micro`; fix by either replacing all occurrences of
`--corvus-motion-duration-micro` in the spec (lines noted) with the existing
token `--corvus-motion-fast` (or another defined token like
`--corvus-motion-normal`/`--corvus-motion-slow`) or by adding
`--corvus-motion-duration-micro` with a concrete value to the theme CSS
(nothing-theme.css) and to design.md so tokens stay consistent; update every
mention (e.g., in spec.md at the three locations) and ensure design.md and
nothing-theme.css both define the same token name and value.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md`:
- Around line 135-144: Create a follow-up tracking issue titled e.g.
"Browser/runtime verification for design-system theme & bundle delta" that
scopes Playwright visual/regression tests and artifact-size checks: list
explicit acceptance criteria to cover prefers-color-scheme emulation, manual
[data-theme] switching, Tailwind utility resolution under both light/dark,
Starlight theme toggle behavior, and an install/build before/after bundle-size
delta check; include test targets such as HealthIndicator.spec.ts and
SessionFilters.vue to note unrelated TS failures affecting full-green CI,
specify test commands, required fixtures/screenshots, and pass/fail thresholds
for visual diffs and size delta so the work is actionable and triageable.
- Around line 22-57: The fenced code blocks under the "Install", "Build — Docs",
"Build — Marketing", "Build — Chat", and "Build — Dashboard" sections are
missing language specifiers and surrounding blank lines; update each
triple-backtick block in verify-report.md to include an appropriate language tag
(e.g., text or bash) immediately after the opening ``` and ensure there is a
blank line before and after each fenced block so MD031 and MD040 are resolved.

In `@openspec/specs/theming/spec.md`:
- Around line 30-31: Update the spec text "Font loading MUST be centralized to
avoid duplication across apps" to align with the implementation described in
CSS_ARCHITECTURE.md: clarify that font tokens/definitions are centralized (e.g.,
token names, font-family variables) but actual font file imports via `@fontsource`
are performed per-app by each bundler; replace the absolute "MUST be
centralized" requirement with a precise statement such as centralized definition
+ per-app loading, and reference the CSS_ARCHITECTURE.md rationale so readers
understand the per-app import constraint.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 17d03ab9-9062-4b24-a2d5-bf19e48dd3f5

📥 Commits

Reviewing files that changed from the base of the PR and between fa4d07b and 88c11d1.

📒 Files selected for processing (47)
  • clients/web/CSS_ARCHITECTURE.md
  • clients/web/apps/chat/package.json
  • clients/web/apps/chat/src/App.vue
  • clients/web/apps/chat/src/components/ConfigPanel.vue
  • clients/web/apps/chat/src/components/HealthIndicator.vue
  • clients/web/apps/chat/src/components/SessionSidebar.vue
  • clients/web/apps/chat/src/components/chat/ChatMessage.vue
  • clients/web/apps/chat/src/components/chat/ToolApprovalCard.vue
  • clients/web/apps/chat/src/main.ts
  • clients/web/apps/chat/src/style.css
  • clients/web/apps/dashboard/package.json
  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/dashboard/src/main.ts
  • clients/web/apps/dashboard/src/style.css
  • clients/web/apps/docs/astro.config.mjs
  • clients/web/apps/docs/package.json
  • clients/web/apps/docs/src/styles/custom.css
  • clients/web/apps/marketing/package.json
  • clients/web/apps/marketing/src/layouts/MarketingLayout.astro
  • clients/web/apps/marketing/src/styles/global.css
  • clients/web/package.json
  • clients/web/packages/shared/README.md
  • clients/web/packages/shared/base.css
  • clients/web/packages/shared/nothing-shell.css
  • clients/web/packages/shared/nothing-theme.css
  • clients/web/packages/shared/package.json
  • clients/web/packages/shared/tailwind-bridge.css
  • clients/web/packages/ui/src/components/Button.vue
  • clients/web/packages/ui/src/components/Input.vue
  • clients/web/pnpm-workspace.yaml
  • openspec/changes/archive/2026-04-08-nothing-design-system/archive-report.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/design.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/web-styling/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/state.yaml
  • openspec/changes/archive/2026-04-08-nothing-design-system/tasks.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify.md
  • openspec/specs/theming/spec.md
  • openspec/specs/web-styling/spec.md
💤 Files with no reviewable changes (1)
  • clients/web/package.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (3)
**/*

⚙️ CodeRabbit configuration file

**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.

Files:

  • clients/web/apps/dashboard/src/style.css
  • clients/web/apps/dashboard/src/main.ts
  • clients/web/apps/docs/astro.config.mjs
  • clients/web/apps/docs/package.json
  • clients/web/apps/chat/src/components/HealthIndicator.vue
  • clients/web/apps/marketing/src/layouts/MarketingLayout.astro
  • clients/web/apps/chat/src/main.ts
  • openspec/changes/archive/2026-04-08-nothing-design-system/state.yaml
  • clients/web/pnpm-workspace.yaml
  • clients/web/apps/chat/package.json
  • clients/web/apps/dashboard/package.json
  • clients/web/packages/shared/README.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/archive-report.md
  • clients/web/apps/chat/src/components/SessionSidebar.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify.md
  • clients/web/apps/marketing/package.json
  • clients/web/packages/ui/src/components/Input.vue
  • clients/web/packages/shared/nothing-shell.css
  • clients/web/apps/chat/src/components/chat/ToolApprovalCard.vue
  • clients/web/apps/chat/src/style.css
  • clients/web/apps/chat/src/components/chat/ChatMessage.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md
  • clients/web/packages/shared/package.json
  • clients/web/packages/shared/base.css
  • clients/web/apps/chat/src/components/ConfigPanel.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
  • clients/web/packages/shared/nothing-theme.css
  • openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md
  • clients/web/apps/dashboard/src/App.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/tasks.md
  • clients/web/CSS_ARCHITECTURE.md
  • clients/web/apps/marketing/src/styles/global.css
  • openspec/specs/theming/spec.md
  • clients/web/packages/shared/tailwind-bridge.css
  • clients/web/packages/ui/src/components/Button.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/design.md
  • openspec/specs/web-styling/spec.md
  • clients/web/apps/docs/src/styles/custom.css
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/web-styling/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md
  • clients/web/apps/chat/src/App.vue
**/*.vue

⚙️ CodeRabbit configuration file

**/*.vue: Enforce Vue 3 Composition API with <script setup>.
Ensure accessibility (A11y) and proper use of Tailwind CSS classes.
Check for proper prop validation and emitted events documentation.

Files:

  • clients/web/apps/chat/src/components/HealthIndicator.vue
  • clients/web/apps/chat/src/components/SessionSidebar.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/packages/ui/src/components/Input.vue
  • clients/web/apps/chat/src/components/chat/ToolApprovalCard.vue
  • clients/web/apps/chat/src/components/chat/ChatMessage.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/chat/src/components/ConfigPanel.vue
  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/packages/ui/src/components/Button.vue
  • clients/web/apps/chat/src/App.vue
**/*.{md,mdx}

⚙️ CodeRabbit configuration file

**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes.
For user-facing docs, check EN/ES parity or explicitly note pending translation gaps.

Files:

  • clients/web/packages/shared/README.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/archive-report.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/tasks.md
  • clients/web/CSS_ARCHITECTURE.md
  • openspec/specs/theming/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/design.md
  • openspec/specs/web-styling/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/web-styling/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md
🪛 LanguageTool
openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md

[uncategorized] ~18-~18: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...rple/indigo (#818cf8, #6366f1) with sky blue gradients - Heavy use of gradients, gla...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~182-~182: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...08 lines of custom CSS is essentially a full page redesign. The marketing page has termin...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

clients/web/CSS_ARCHITECTURE.md

[style] ~111-~111: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... rules in packages/shared/base.css. - Put shared app-frame concerns for Vue appli...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md

[grammar] ~6-~6: Use a hyphen to join words.
Context: ....md` exists. This spec defines the theme switching mechanism, font loading strate...

(QB_NEW_EN_HYPHEN)


[grammar] ~6-~6: Use a hyphen to join words.
Context: ...ines the theme switching mechanism, font loading strategy, Tailwind v4 bridge, an...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~64-~64: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...cur within one animation frame - AND no full page reload SHALL occur #### Scenario: Star...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.22.0)
openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


[warning] 53-53: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 59-59: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 63-63: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 69-69: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 75-75: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 124-124: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 126-126: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 126-126: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 135-135: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 137-137: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 147-147: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 150-150: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 156-156: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 162-162: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 164-164: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 175-175: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md

[warning] 23-23: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 23-23: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 34-34: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 34-34: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 40-40: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 40-40: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 50-50: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 50-50: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 55-55: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 55-55: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

openspec/changes/archive/2026-04-08-nothing-design-system/design.md

[warning] 56-56: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 94-94: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 106-106: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 273-273: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 463-463: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 484-484: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 494-494: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 497-497: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 498-498: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 697-697: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 723-723: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 794-794: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 822-822: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md

[warning] 171-171: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 Stylelint (17.6.0)
clients/web/apps/dashboard/src/style.css

[error] 1-1: Expected "url("@corvus/shared/nothing-shell.css")" to be ""@corvus/shared/nothing-shell.css"" (import-notation)

(import-notation)


[error] 2-2: Expected "url("tailwindcss")" to be ""tailwindcss"" (import-notation)

(import-notation)


[error] 3-3: Expected "url("@corvus/shared/tailwind-bridge.css")" to be ""@corvus/shared/tailwind-bridge.css"" (import-notation)

(import-notation)

clients/web/packages/shared/nothing-shell.css

[error] 1-1: Expected "url("./nothing-theme.css")" to be ""./nothing-theme.css"" (import-notation)

(import-notation)


[error] 2-2: Expected "url("./base.css")" to be ""./base.css"" (import-notation)

(import-notation)

clients/web/apps/chat/src/style.css

[error] 1-1: Expected "url("@corvus/shared/nothing-shell.css")" to be ""@corvus/shared/nothing-shell.css"" (import-notation)

(import-notation)


[error] 2-2: Expected "url("tailwindcss")" to be ""tailwindcss"" (import-notation)

(import-notation)


[error] 3-3: Expected "url("@corvus/shared/tailwind-bridge.css")" to be ""@corvus/shared/tailwind-bridge.css"" (import-notation)

(import-notation)

clients/web/apps/marketing/src/styles/global.css

[error] 7-7: Expected "url("@corvus/shared/nothing-theme.css")" to be ""@corvus/shared/nothing-theme.css"" (import-notation)

(import-notation)


[error] 8-8: Expected "url("@corvus/shared/base.css")" to be ""@corvus/shared/base.css"" (import-notation)

(import-notation)


[error] 11-11: Expected "url("@fontsource-variable/space-grotesk")" to be ""@fontsource-variable/space-grotesk"" (import-notation)

(import-notation)


[error] 12-12: Expected "url("@fontsource/space-mono/400.css")" to be ""@fontsource/space-mono/400.css"" (import-notation)

(import-notation)


[error] 13-13: Expected "url("@fontsource/space-mono/700.css")" to be ""@fontsource/space-mono/700.css"" (import-notation)

(import-notation)


[error] 14-14: Expected "url("@fontsource/doto/400.css")" to be ""@fontsource/doto/400.css"" (import-notation)

(import-notation)


[error] 15-15: Expected "url("@fontsource/doto/700.css")" to be ""@fontsource/doto/700.css"" (import-notation)

(import-notation)

clients/web/packages/shared/tailwind-bridge.css

[error] 2-2: Unexpected unknown at-rule "@theme" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

clients/web/apps/docs/src/styles/custom.css

[error] 8-8: Expected "url("@fontsource-variable/space-grotesk")" to be ""@fontsource-variable/space-grotesk"" (import-notation)

(import-notation)


[error] 9-9: Expected "url("@fontsource/space-mono/400.css")" to be ""@fontsource/space-mono/400.css"" (import-notation)

(import-notation)


[error] 10-10: Expected "url("@fontsource/space-mono/700.css")" to be ""@fontsource/space-mono/700.css"" (import-notation)

(import-notation)


[error] 11-11: Expected "url("@fontsource/doto/400.css")" to be ""@fontsource/doto/400.css"" (import-notation)

(import-notation)


[error] 12-12: Expected "url("@fontsource/doto/700.css")" to be ""@fontsource/doto/700.css"" (import-notation)

(import-notation)


[error] 15-15: Expected "url("@corvus/shared/base.css")" to be ""@corvus/shared/base.css"" (import-notation)

(import-notation)


[error] 16-16: Expected "url("@corvus/shared/nothing-theme.css")" to be ""@corvus/shared/nothing-theme.css"" (import-notation)

(import-notation)

🔇 Additional comments (54)
clients/web/packages/ui/src/components/Button.vue (1)

5-17: No stale consumers of removed variants found.

The migration from outline/default variants is complete. A thorough search across the codebase found no remaining references to these old variant values, confirming that all consumers have been updated to use the new variant contract.

clients/web/apps/dashboard/src/main.ts (1)

5-9: Font import migration looks consistent with the tokenized typography stack.
No concerns in this segment.

clients/web/apps/chat/src/components/HealthIndicator.vue (1)

90-90: Good tokenization update for status and muted text colors.
This keeps the component aligned with the shared Nothing theme variables.

Also applies to: 101-101, 105-105

openspec/changes/archive/2026-04-08-nothing-design-system/state.yaml (1)

1-5: Archive state metadata is coherent and complete.
No issues in this segment.

openspec/changes/archive/2026-04-08-nothing-design-system/spec.md (1)

1-29: Spec index structure and requirement roll-up look consistent for the archived change.
No concerns in this segment.

openspec/changes/archive/2026-04-08-nothing-design-system/archive-report.md (1)

1-55: LGTM!

Archive report accurately documents the design system migration, resolved items, and non-blocking warnings. The verification verdict with preserved warnings provides good traceability for future reference.

clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue (1)

113-141: LGTM!

Token migration to --corvus-* variables is consistent with the design system. Semantic tokens (--corvus-color-status-success, --corvus-color-text-disabled) are appropriately used for status indicators.

clients/web/apps/chat/src/components/SessionSidebar.vue (1)

141-275: LGTM!

Comprehensive token migration with consistent use of motion tokens for transitions. Good semantic token usage for text states (disabled, secondary, primary, display).

clients/web/apps/chat/src/components/chat/ToolApprovalCard.vue (1)

50-121: LGTM!

Good semantic token usage with --corvus-color-status-success / --corvus-color-status-error for the approve/reject buttons. Motion tokens ensure consistent animation behavior.

clients/web/packages/shared/nothing-shell.css (1)

9-41: LGTM!

Proper use of 100dvh for modern viewport handling. Token references for typography, colors, and scrollbar styling are consistent with the design system.

clients/web/apps/chat/src/style.css (2)

7-37: LGTM!

Standard animation definitions. Reduced-motion handling is covered in base.css (via the @media (prefers-reduced-motion: reduce) rule).


1-3: The Stylelint rule that flags import notation (function-url-quotes) is explicitly disabled in the project configuration (.stylelintrc.json), so these imports are not violations. The codebase consistently uses @import url(...) notation across all CSS files. No action needed.

clients/web/apps/dashboard/src/components/config/TunnelOverview.vue (1)

138-154: LGTM!

Status indicator and text color tokens are consistent with other dashboard components.

openspec/specs/web-styling/spec.md (1)

1-30: Specification aligns with implementation.

The requirements documented here correctly match the Button variant types (primary, secondary, ghost, destructive) and Input styling approach implemented in the UI components. The 44px minimum touch target meets WCAG 2.2 AAA guidance.

Consider adding explicit WCAG contrast ratio requirements (e.g., "4.5:1 for normal text, 3:1 for large text") under the Accessibility Baseline section—currently "accessible contrast" is subjective.

clients/web/apps/chat/src/components/ConfigPanel.vue (2)

120-122: Button variant change is correct.

The secondary variant is properly defined in the Button component's TypeScript interface and has corresponding CSS styling (transparent background with visible border). This aligns with the design system migration from outline to secondary.


130-252: Scoped CSS token migration looks complete and consistent.

All legacy --color-* variables have been replaced with --corvus-* design tokens. The styling maintains semantic meaning (e.g., --corvus-color-status-success for complete steps, --corvus-color-status-error for blocked steps).

clients/web/apps/chat/src/components/chat/ChatMessage.vue (2)

69-127: Token migration in avatar and bubble styling is consistent.

The CSS correctly uses --corvus-radius-*, --corvus-color-* tokens throughout. The asymmetric border-radius on bubbles (e.g., line 94) creates a nice visual distinction between user and assistant messages.


52-53: Reduced-motion handling is already in place globally.

The fade-in and cursor-blink animations are properly covered by the global @media (prefers-reduced-motion: reduce) rule in base.css, which sets animation-duration: 0.01ms !important on all elements. No component-level changes needed.

openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md (1)

125-133: Inconsistency: Token naming proposal differs from implementation.

The exploration proposes dropping the --corvus- prefix for flat semantic names (e.g., --black, --surface), but the actual implementation retained the --corvus- prefix (e.g., --corvus-color-bg-base). Update this section to reflect the final decision, or note that this proposal was rejected in favor of keeping the namespaced tokens.

clients/web/apps/dashboard/src/App.vue (3)

220-222: Button variant change is correct and consistent with chat app.

The secondary variant is properly supported by the Button component. This change mirrors the same pattern applied in ConfigPanel.vue.


498-499: Good use of motion tokens for transitions.

Using --corvus-motion-duration-micro and --corvus-motion-easing-default for the nav-tab transitions ensures consistent animation timing across the app and respects any global reduced-motion overrides.


443-676: Comprehensive token migration in scoped styles.

The CSS has been thoroughly migrated to use --corvus-* tokens for colors, borders, radii, and motion timing. The semantic token names (e.g., --corvus-color-status-success, --corvus-color-text-disabled) improve maintainability.

clients/web/apps/chat/src/App.vue (4)

365-367: Removal of glow effects aligns with Nothing Design System.

The animate-pulse-glow class has been correctly removed from both the sidebar logo and hero icon, adhering to the Nothing Design System's "no shadows, glows, or gradients" principle.

Also applies to: 470-472


513-527: Button variant changes are consistent.

All three buttons in the gate actions section now use variant="secondary", maintaining visual consistency with the primary action button while providing appropriate visual hierarchy.


810-815: Hero title styling simplified appropriately.

The gradient/clip-based treatment has been replaced with a simple color: var(--corvus-color-text-display). This matches the Nothing Design System's minimal aesthetic.


611-1073: Comprehensive CSS token migration.

The scoped styles have been thoroughly updated to use --corvus-* design tokens for backgrounds, borders, colors, radii, and motion timing. The consistency across all selectors is excellent.

openspec/changes/archive/2026-04-08-nothing-design-system/verify.md (1)

1-30: Verification envelope is thorough and appropriately documented.

The "PASS WITH WARNINGS" status correctly reflects that the design-system migration is complete while acknowledging non-blocking concerns (browser proof, font bundle delta, pre-existing build failures). The explicit listing of verified fixes provides good traceability.

clients/web/packages/shared/package.json (1)

18-20: Export changes are safe; no stale imports of removed paths found.

The removal of ./app-shell.css, ./theme.css, and ./tokens.css exports is a clean breaking change. Verification confirms no consumers in the codebase are still importing the old paths. The new exports (./nothing-theme.css, ./nothing-shell.css, ./tailwind-bridge.css) are already integrated in the docs and marketing apps.

clients/web/packages/shared/nothing-theme.css (2)

9-101: Well-structured token foundation with clear dark-first defaults.

The :root block establishes comprehensive tokens for the Nothing Design System. Token naming follows the canonical --corvus-{category}-{property}-{variant} pattern consistently.


103-121: Light mode system-preference guard is correctly implemented.

The :root:not([data-theme="dark"]) selector correctly prevents system light preference from overriding an explicit manual dark choice. This is the right approach for theme precedence.

openspec/specs/theming/spec.md (1)

1-42: Theming spec is technically accurate and aligns with implementation.

Requirements correctly document:

  • Dark-first default behavior (matches :root in nothing-theme.css)
  • data-theme attribute precedence (matches CSS specificity implementation)
  • No FOUC via CSS custom property reassignment only
  • Tailwind v4 @theme bridge requirement (matches tailwind-bridge.css)
clients/web/packages/shared/tailwind-bridge.css (1)

1-35: Tailwind v4 @theme bridge correctly maps all required tokens.

The stylelint-disable-next-line comment appropriately silences the false positive for @theme — this is valid Tailwind v4 syntax. All referenced --corvus-* tokens are defined in nothing-theme.css.

Note: Radius and motion tokens are excluded from the bridge. If utilities like rounded-card or duration-default are needed, they can be added later.

openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md (1)

1-190: Proposal is comprehensive with clear scope, risks, and rollback strategy.

Well-documented migration plan with:

  • Clear in-scope vs out-of-scope boundaries
  • Realistic risk assessment with mitigations
  • Per-app rollback capability until step 8 (cleanup)
  • Dependency verification items
clients/web/apps/dashboard/src/components/config/CostOverview.vue (3)

266-285: Button variant change from outline to secondary is valid.

The secondary variant is properly defined in Button.vue (context snippet confirms prop type includes "secondary" and CSS styles exist). Both override and reset actions appropriately use the same variant for visual consistency.


313-344: Token migration in styles is consistent with Nothing Design System.

All legacy --color-* references replaced with canonical --corvus-* tokens:

  • Border/background: --corvus-color-border-default, --corvus-color-bg-surface
  • Status indicators: --corvus-color-status-success, --corvus-color-text-disabled
  • Text colors: --corvus-color-text-secondary

386-396: State banner border colors correctly map to status tokens.

The status-based styling (--allowed, --warning, --exceeded) properly uses semantic status tokens from the design system, ensuring consistent visual feedback across the app.

openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md (2)

1-86: Color token catalog is comprehensive with proper dark/light theme coverage.

Token definitions align with nothing-theme.css implementation. The scenarios provide clear validation criteria:

  • All color tokens resolve correctly per theme
  • Accent/status colors are theme-invariant (except accent-subtle and status-info which do vary)
  • Every color token has both dark and light values

247-286: Glass morphism and elevation removal is clearly documented.

The rationale for removing decorative effects aligns with Nothing design principles. Scenarios provide clear negative tests to ensure these tokens don't exist in the final implementation.

clients/web/apps/marketing/src/styles/global.css (2)

692-721: Reduced-motion handling is correctly implemented.

Transitions are wrapped in @media (prefers-reduced-motion: no-preference), ensuring users who prefer reduced motion don't see border-color transitions or the copy-pop animation. This follows the design-tokens spec requirement.


30-37: Body styles correctly use Nothing tokens for foundation.

Background, color, and font-family properly reference canonical --corvus-* tokens, establishing the dark-first default that will automatically switch with theme changes.

clients/web/CSS_ARCHITECTURE.md (3)

8-50: Architecture documentation accurately reflects the Nothing Design System implementation.

Key documentation improvements:

  • Token naming convention table provides clear reference
  • Theme switching precedence is well-documented with the three-tier hierarchy
  • The :not([data-theme="dark"]) guard is explained

51-106: Tailwind v4 @theme bridge documentation is thorough.

Good explanations of:

  • Why the bridge lives in each app's style.css (Tailwind v4 requirement)
  • The double-prefix pattern (bg-bg-*, text-text-*) being standard Tailwind v4 behavior
  • Non-Tailwind apps using direct token references

158-182: Font loading strategy documentation is clear and practical.

The per-app rationale is well-explained: shared package is CSS-only, and bundlers handle @fontsource imports differently. The table format makes it easy to understand which approach applies to each app type.

openspec/changes/archive/2026-04-08-nothing-design-system/design.md (2)

167-170: Verify --corvus-color-interactive value consistency across themes.

The design specifies --corvus-color-interactive: #5B9BF6`` for dark mode (line 179) and #007AFF for light mode (lines 236, 251). Confirm this intentional divergence is documented—iOS system blue (`#007AFF`) vs. a lighter blue (`#5B9BF6`) may affect brand consistency across themes.

Also applies to: 249-252


915-921: Open questions list is valuable for tracking.

The open questions section explicitly calls out risks: Doto font availability, Button variant rename audit, Instrument Serif replacement, and theme toggle UI location. This is good practice for design docs—ensure these are resolved before final merge or tracked in follow-up issues.

openspec/changes/archive/2026-04-08-nothing-design-system/tasks.md (1)

1-47: Task tracking document is complete and well-organized.

All 27 tasks across 6 phases are marked complete. The structure mirrors the design.md migration sequence and provides clear traceability for the design system rollout.

openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md (1)

1-157: Verification report structure and verdict are sound.

The report confirms 27/27 tasks complete with a reasonable "PASS WITH WARNINGS" verdict. Pre-existing TS errors are correctly scoped out of the design-system change.

clients/web/apps/docs/src/styles/custom.css (3)

33-77: Starlight token mapping is well-structured.

The dark and light theme mappings correctly wire --sl-* tokens to --corvus-* tokens, including the new --sl-color-bg-inline-code token. The separation by [data-theme] selector aligns with the design spec's ADR-2.


473-488: Reduced motion implementation is correct.

The prefers-reduced-motion: reduce block properly uses !important flags with biome-ignore comments to guarantee the override. The 0.01ms duration is the standard pattern to effectively disable animations while avoiding browser quirks with 0ms.


167-167: Tokens in custom.css resolve correctly — no action needed.

The motion tokens referenced in custom.css (--corvus-motion-duration-default, --corvus-motion-easing-default) are defined in nothing-theme.css with matching names and will resolve without error. There is no token mismatch between the CSS files.

Note: design.md proposes different token names (--corvus-motion-fast, --corvus-motion-normal, etc.), but the actual implementation in nothing-theme.css uses the names currently referenced in custom.css, so the proposal/implementation divergence does not cause a functional problem here.

			> Likely an incorrect or invalid review comment.
openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md (1)

21-65: Theme switching requirements are well-specified.

The scenarios cover system auto-detection, manual override precedence, FOUC prevention, and Starlight integration. The precedence chain (manual > system > default) is clearly documented.

openspec/changes/archive/2026-04-08-nothing-design-system/specs/web-styling/spec.md (3)

178-199: Contrast ratio table is comprehensive and valuable.

The pre-calculated contrast ratios for all text/background token combinations provide clear guidance for developers. The distinction between AA (4.5:1) and AA-large (3:1) requirements is correctly applied.


275-281: Reduced motion rule is correctly specified.

The universal selector rule with !important flags matches the implementation in custom.css and base.css. The 0.01ms duration is the correct pattern.


284-303: Touch target requirements align with WCAG 2.5.8.

The 44×44px minimum requirement and the inline link exemption with 8px spacing rule are correctly specified per WCAG 2.2 guidance.

Comment thread clients/web/apps/chat/src/main.ts
Comment thread clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
Comment on lines +1 to +3
@import url("@corvus/shared/nothing-shell.css");
@import url("tailwindcss");

body {
background:
radial-gradient(circle at 0 0, rgb(129 140 248 / 12%), transparent 40%),
radial-gradient(circle at 100% 100%, rgb(192 132 252 / 8%), transparent 45%),
var(--color-bg-primary);
}
@import url("@corvus/shared/tailwind-bridge.css");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Stylelint failure: use string import notation, not url(...).
This will fail current lint checks.

Proposed fix
-@import url("@corvus/shared/nothing-shell.css");
+@import "@corvus/shared/nothing-shell.css";
 `@import` url("tailwindcss");
-@import url("@corvus/shared/tailwind-bridge.css");
+@import "tailwindcss";
+@import "@corvus/shared/tailwind-bridge.css";
🧰 Tools
🪛 Stylelint (17.6.0)

[error] 1-1: Expected "url("@corvus/shared/nothing-shell.css")" to be ""@corvus/shared/nothing-shell.css"" (import-notation)

(import-notation)


[error] 2-2: Expected "url("tailwindcss")" to be ""tailwindcss"" (import-notation)

(import-notation)


[error] 3-3: Expected "url("@corvus/shared/tailwind-bridge.css")" to be ""@corvus/shared/tailwind-bridge.css"" (import-notation)

(import-notation)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/dashboard/src/style.css` around lines 1 - 3, The `@import`
rules in style.css use url(...) which violates Stylelint; change each `@import`
url("...") to the string form `@import` "..." (e.g., replace `@import`
url("@corvus/shared/nothing-shell.css"); with `@import`
"@corvus/shared/nothing-shell.css"; and do the same for "tailwindcss" and
"@corvus/shared/tailwind-bridge.css") so lint accepts the imports.

Comment thread clients/web/apps/docs/astro.config.mjs
Comment thread clients/web/apps/docs/package.json
--color-success: var(--corvus-color-status-success);
--color-warning: var(--corvus-color-status-warning);
--color-error: var(--corvus-color-status-error);
--color-interactive: var(--corvus-color-interactive-default);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the actual token name in nothing-theme.css
fd 'nothing-theme.css' --exec cat {} | grep -E 'interactive'

Repository: dallay/corvus

Length of output: 246


🏁 Script executed:

fd 'design.md' --exec wc -l {}

Repository: dallay/corvus

Length of output: 4195


🏁 Script executed:

fd 'spec.md' --exec wc -l {}

Repository: dallay/corvus

Length of output: 8170


🏁 Script executed:

fd 'design.md' --exec sed -n '170,185p' {}

Repository: dallay/corvus

Length of output: 36368


🏁 Script executed:

fd 'spec.md' --exec sed -n '180,195p' {}

Repository: dallay/corvus

Length of output: 41344


Design.md token definition is missing the -default suffix.

Line 187 in spec.md correctly references --corvus-color-interactive-default, but design.md (line 179) defines only --corvus-color-interactive. Update design.md to define the token with the -default suffix to align with the actual theme implementation in nothing-theme.css.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`
at line 187, Design.md defines --corvus-color-interactive without the -default
suffix, which mismatches spec.md and nothing-theme.css; update the token
declaration in Design.md (replace any occurrences of --corvus-color-interactive
in the theming tokens block with --corvus-color-interactive-default) so the
token name aligns with the spec and the actual theme implementation, and verify
any references in the same file use the new --corvus-color-interactive-default
identifier.

- Padding: 12px 24px
- Minimum height: 44px (touch target)
- Minimum width: 44px (touch target for icon-only buttons)
- Transition: `--corvus-motion-duration-micro` with `--corvus-motion-easing-default`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Motion token name inconsistency: --corvus-motion-duration-micro not in design.md.

The spec references --corvus-motion-duration-micro (lines 44, 151, 271), but design.md defines:

  • --corvus-motion-fast: 150ms
  • --corvus-motion-normal: 200ms
  • --corvus-motion-slow: 300ms

There's no duration-micro token. Either update the spec to use --corvus-motion-fast or add the micro duration token to nothing-theme.css.

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

Also applies to: 151-151, 271-271

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/web-styling/spec.md`
at line 44, The spec refers to a non-existent motion token
`--corvus-motion-duration-micro`; fix by either replacing all occurrences of
`--corvus-motion-duration-micro` in the spec (lines noted) with the existing
token `--corvus-motion-fast` (or another defined token like
`--corvus-motion-normal`/`--corvus-motion-slow`) or by adding
`--corvus-motion-duration-micro` with a concrete value to the theme CSS
(nothing-theme.css) and to design.md so tokens stay consistent; update every
mention (e.g., in spec.md at the three locations) and ensure design.md and
nothing-theme.css both define the same token name and value.

Comment thread openspec/specs/theming/spec.md Outdated
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 8, 2026

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: dbaa809
Status: ✅  Deploy successful!
Preview URL: https://dd4e0efb.corvus-42x.pages.dev
Branch Preview URL: https://style-nothing.corvus-42x.pages.dev

View logs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 19

♻️ Duplicate comments (2)
clients/web/apps/docs/astro.config.mjs (1)

65-80: ⚠️ Potential issue | 🟡 Minor

theme-color still follows the OS, not the active docs theme.

The docs app supports explicit html[data-theme] switching, but these two tags only react to prefers-color-scheme. Users who pick the opposite theme still get the wrong browser chrome color. This needs a small runtime update when data-theme changes instead of relying only on media-gated meta tags.

As per coding guidelines, "Look for behavioral regressions, missing tests, and contract breaks across modules."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/docs/astro.config.mjs` around lines 65 - 80, The meta tags
for theme-color in the head only respond to prefers-color-scheme media and not
to explicit html[data-theme] changes; add a small client-side runtime that
locates the meta[name="theme-color"] elements (the two entries created in head)
and updates their content whenever document.documentElement.dataset.theme
(html[data-theme]) changes—implement this by adding a MutationObserver or event
listener that watches attribute changes on document.documentElement, maps
"light"/"dark" (or other theme values) to the appropriate color values
("#f5f5f5" and "#000000"), and sets meta.content accordingly so browser chrome
matches the active docs theme.
openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md (1)

84-85: ⚠️ Potential issue | 🟠 Major

Starlight accent mapping is inconsistent with the documented docs implementation.

Line 84 maps --sl-color-accent to --corvus-color-accent-default, while the docs mapping in this change set uses --corvus-color-text-primary. Align spec and implementation to one mapping to avoid drift.

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`
around lines 84 - 85, Summary: The spec maps `--sl-color-accent` to
`--corvus-color-accent-default` but the docs/implementation map it to
`--corvus-color-text-primary`; pick one and make the spec match the docs. Fix:
update the mapping in the spec so `--sl-color-accent` maps to
`--corvus-color-text-primary` (or if the intended source of truth is the spec,
update the docs/implementation to `--corvus-color-accent-default`) — ensure the
two places reference the same CSS variable name (`--sl-color-accent`,
`--corvus-color-accent-default`, `--corvus-color-text-primary`) so they no
longer diverge.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/web/CSS_ARCHITECTURE.md`:
- Around line 177-179: The paragraph under the "**Why per-app**" heading in
CSS_ARCHITECTURE.md incorrectly states font imports are "JS-level" which
contradicts the table; update the text to use "app-entry-level" or explicitly
split the explanation for Vue (Vite) and Astro cases so the docs align with the
table: edit the sentence that starts "The shared package (`@corvus/shared`) is
CSS-only. Font imports are JS-level (via `@fontsource` CSS entry points)..." to
either replace "JS-level" with "app-entry-level" or expand into two clauses that
state how Vue (Vite) handles fonts vs how Astro (static) handles them, keeping
the reference to `@fontsource` and bundler differences.

In `@clients/web/packages/shared/nothing-theme.css`:
- Around line 107-113: The light-theme border token
--corvus-color-border-visible is too light against --corvus-color-bg-base and
should be darkened to meet a minimum 3:1 non-text contrast; update the value(s)
in the :root:not([data-theme="dark"]) block (and the equivalent block around
lines 126-132) to a darker hex (for example adjust from `#ccc` to something around
`#9e9e9e/`#8b8b8b or another value that passes 3:1) so input underlines and
secondary button borders are perceptible, and ensure you change every occurrence
of --corvus-color-border-visible in that file to the new value.

In `@clients/web/packages/ui/src/components/Button.vue`:
- Around line 101-110: The .btn--destructive CSS variant currently uses
transparent background with border and text in --corvus-color-accent-default
which is low-contrast on dark shells (see nothing-theme.css); update the
.btn--destructive rule (and its :hover:not(:disabled) state) to use a filled
accent treatment with a light foreground (e.g., swap to a bright-on-accent color
variable) or change the text color token to a lighter destructive token so 13px
text meets contrast in both themes; adjust the hover state to preserve contrast
(darker accent background or same filled style) and follow project Tailwind/A11y
conventions when mapping tokens so Button.vue’s destructive variant stays
readable in both light and dark themes.

In `@clients/web/packages/ui/src/components/Input.vue`:
- Around line 40-41: The input CSS removes the native outline causing poor
keyboard discoverability; in Input.vue restore a non-color-only focus indicator
by adding a :focus-visible rule on the input element that preserves the existing
minimal underline transition but also applies a visible ring/outline (e.g., a
2px outline or box-shadow ring using a high-contrast color or CSS variable) so
focus isn’t conveyed by color change alone; update the same treatment for the
other focus rules around the transition/outline lines (the rules near the
existing "transition: border-color..." and "outline: none;") and ensure the new
:focus-visible style is accessible (contrasting and not solely color-based) and
removed on :focus when not :focus-visible.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/design.md`:
- Around line 918-920: Remove or resolve the stale checklist item referencing
"Doto font availability" / `@fontsource/doto` in the design.md checklist: either
delete the unchecked line ("[ ] **Doto font availability**: Does
`@fontsource/doto` exist...") or mark it completed and add a short confirming
note that `@fontsource/doto` was installed/built (or provide the self-hosting
fallback) so the archive reflects the verified state; update the adjacent
checklist context so the design status is no longer ambiguous.
- Around line 215-218: The design doc defines motion tokens as
--corvus-motion-fast/normal/slow and --corvus-motion-easing but other parts of
the doc reference --corvus-motion-duration-micro and
--corvus-motion-easing-default, which breaks the contract; choose a single
canonical token naming (either the duration-prefixed form like
--corvus-motion-duration-micro / --corvus-motion-duration-normal /
--corvus-motion-duration-slow and --corvus-motion-easing-default, or keep the
fast/normal/slow + --corvus-motion-easing) and update all occurrences to match
that choice (update the token definitions at the top of the document and replace
usages of --corvus-motion-fast|normal|slow or --corvus-motion-duration-micro and
--corvus-motion-easing vs --corvus-motion-easing-default throughout the doc,
including examples/tests), ensuring token names in the contract and examples are
identical.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md`:
- Around line 137-148: The example in the `@theme` block uses proposed flat token
names like --surface and --text-primary which don't match the actual
implementation; update the snippet to use the real token names used in
tailwind-bridge.css (e.g., --corvus-color-*/--color-bg-base) so the mapping
reflects actual imports—specifically edit the `@theme` block in exploration.md to
reference the implemented token names (and/or the mapped names such as
--color-bg-base, --color-surface-raised, --color-text-primary) consistent with
tailwind-bridge.css and `@corvus/shared/nothing-theme.css`.
- Around line 125-133: The exploration doc claims tokens will use flat names
(e.g. --black, --text-primary) but the implemented CSS uses namespaced tokens
(e.g. --corvus-color-bg-base, --corvus-color-text-primary,
--corvus-typography-font-body); update the exploration.md entry to explicitly
state that the final implementation retained the --corvus- prefix for
namespacing and to avoid conflicts, and adjust the proposed token list to either
show the actual implemented token names (mapping examples like --black →
--corvus-color-bg-base, --text-primary → --corvus-color-text-primary,
--font-body → --corvus-typography-font-body) or add a short note explaining the
divergence so the doc matches the nothing-theme.css implementation.
- Around line 164-175: The CSS example incorrectly references flat Nothing
tokens (--black, --text-primary, --font-body, --font-mono) instead of the
implemented hierarchical Corvus tokens; update the :root and
:root[data-theme="light"] mappings to use the actual Corvus variables (for
example replace --black with --corvus-black or appropriate
--corvus-*/--corvus-color-* token, --text-primary with --corvus-text-primary,
--font-body with --corvus-font-body, and --font-mono with --corvus-font-mono) so
that the Starlight mapping example matches the implemented design system token
names (adjust any other referenced tokens in this snippet to their --corvus-*
equivalents).
- Around line 53-177: Add missing blank lines before and after all top-level and
subsection headings (e.g., "Shared Infrastructure", "UI Components", "Chat App",
"Token Naming Convention", "Tailwind v4 Integration", "Light Mode Strategy",
etc.) and ensure fenced code blocks in the doc (the token naming block and the
Tailwind `@theme` snippet plus other fenced blocks) are separated by blank lines
above and below; also add a language specifier for the code block currently
missing one (the token-naming example at ~line 126) so it becomes fenced with a
language (e.g., css) for proper markdownlint and syntax highlighting. Ensure you
update the same document content in "exploration.md" where the headings and
fenced blocks appear so the spacing and code fences are consistent throughout.
- Line 3: The heading level is incorrect: change the "### Current State" heading
to use h2 instead of h3 by replacing the leading "###" with "##" for the
"Current State" heading so the document flows from the h1 to h2 correctly.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md`:
- Around line 163-171: The "Full rollback" step is inaccurate:
deleting/reverting shared files (nothing-theme.css, nothing-shell.css) won't
make apps using nothing-shell.css fall back automatically; update the proposal
to state that full rollback requires either reverting each app's per-app import
(e.g., change style.css back from nothing-shell.css to app-shell.css) or keeping
compatibility shims that map nothing-shell.css to the legacy shell until all
apps have been reverted, and also mention reverting font changes in package.json
and main.ts as separate required commits.
- Around line 36-37: The Tailwind utility examples in the proposal use mixed
token names; replace all occurrences of bg-surface, text-primary, and
text-text-primary with the shipped bridge names bg-bg-* and text-text-* so
examples and migration steps match the implemented convention, and audit the
other mentioned sections (the blocks that currently show
bg-surface/text-primary/text-text-primary) to use bg-bg-* / text-text-*
consistently across the document.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md`:
- Around line 222-225: The spec currently mismatches the canonical "slow" motion
duration: update the token so all artifacts use the same value by choosing the
canonical duration (either 300ms or 350ms) and applying it consistently; locate
the token named corvus.motion.duration.slow (CSS variable
--corvus-motion-duration-slow) in this change set and change its value to the
agreed canonical value, then run a quick search to align any other docs/specs
that reference corvus.motion.duration.slow or --corvus-motion-duration-slow to
the same value.
- Around line 240-242: Change the conflicting motion rules so they form one
clear policy: update the rule that currently reads "THEN all transitions MUST be
reduced to 0ms duration or removed entirely" to explicitly target non-opacity
transitions (e.g., "all non-opacity transitions MUST be reduced to 0ms or
removed"), and keep the rule that allows "opacity-only fades MAY be preserved"
but make it normative by adding a capped reduced duration (e.g., "opacity-only
fades MAY be preserved at a reduced duration not exceeding 200ms"); reference
the exact phrases "THEN all transitions MUST be reduced to 0ms duration or
removed entirely" and "AND opacity-only fades MAY be preserved at reduced
duration" when making the edits so the policy is unambiguous.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`:
- Around line 126-127: Update the requirement that currently reads "Astro apps
(docs, marketing) MUST load fonts via `@fontsource` packages imported in their
layout files, NOT via Google Fonts CDN links" so it permits app-boundary CSS
imports instead of mandating layout-file location: reword the rule to require
that Astro apps must load fonts via `@fontsource` packages (imported either in
app-level stylesheets or layout files) and must not use Google Fonts CDN links;
ensure the spec language around the rule (the sentence containing "Astro apps
(docs, marketing) MUST load fonts via `@fontsource`") is replaced to reflect
this broader allowance while keeping the ban on Google CDN links.
- Around line 268-282: The spec incorrectly mandates importing
`@corvus/shared/nothing-theme.css` "instead of `app-shell.css`" for Vue apps;
update the two requirements (the Chat and Dashboard clauses that reference
importing `nothing-theme.css` instead of `app-shell.css`) to require importing
`@corvus/shared/nothing-shell.css` instead of `app-shell.css`, and ensure the
related lines that mention the Tailwind `@theme` bridge and font package rules
remain unchanged (search for the strings `@corvus/shared/nothing-theme.css`,
`app-shell.css`, and the Chat/Dashboard requirement blocks to locate and
replace).

In `@openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md`:
- Around line 12-17: The summary table currently conflates checklist completion
with full verification; update verify-report.md so the top table separates
"Checklist items" from "Verification status" (e.g., keep "Tasks total | 27 /
Tasks complete | 27 / Tasks incomplete | 0" as Checklist items) and add separate
rows or a following short table for "Verification" that lists criteria verified
vs unverified (e.g., "Fully verified criteria | X" and "Unverified criteria |
runtime/browser proof, bundle delta") so the report does not show a false-green
state; make sure the narrative around the existing notes (the runtime/browser
proof and bundle delta mentioned later) references the new "Unverified criteria"
entries so readers can reconcile checklist completion with outstanding
verification.

In `@openspec/specs/theming/spec.md`:
- Around line 16-17: The spec currently allows theme override via a “CSS class
or data attribute” but later mandates html[data-theme=...]; update the normative
requirement to require a data attribute only (data-theme) and remove mention of
CSS class; change the sentence that lists override mechanisms to read only “via
a data attribute (html[data-theme=...])”, and scan/update any other occurrences
(e.g., the html[data-theme=...] reference at lines 24–25 and any other mentions
of CSS class overrides) so the document consistently and exclusively specifies
data-theme as the override mechanism.

---

Duplicate comments:
In `@clients/web/apps/docs/astro.config.mjs`:
- Around line 65-80: The meta tags for theme-color in the head only respond to
prefers-color-scheme media and not to explicit html[data-theme] changes; add a
small client-side runtime that locates the meta[name="theme-color"] elements
(the two entries created in head) and updates their content whenever
document.documentElement.dataset.theme (html[data-theme]) changes—implement this
by adding a MutationObserver or event listener that watches attribute changes on
document.documentElement, maps "light"/"dark" (or other theme values) to the
appropriate color values ("#f5f5f5" and "#000000"), and sets meta.content
accordingly so browser chrome matches the active docs theme.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`:
- Around line 84-85: Summary: The spec maps `--sl-color-accent` to
`--corvus-color-accent-default` but the docs/implementation map it to
`--corvus-color-text-primary`; pick one and make the spec match the docs. Fix:
update the mapping in the spec so `--sl-color-accent` maps to
`--corvus-color-text-primary` (or if the intended source of truth is the spec,
update the docs/implementation to `--corvus-color-accent-default`) — ensure the
two places reference the same CSS variable name (`--sl-color-accent`,
`--corvus-color-accent-default`, `--corvus-color-text-primary`) so they no
longer diverge.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 60d2b9ec-2534-45fb-a52f-92371648a685

📥 Commits

Reviewing files that changed from the base of the PR and between 88c11d1 and 3beb7f7.

⛔ Files ignored due to path filters (1)
  • clients/web/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • clients/web/CSS_ARCHITECTURE.md
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/docs/astro.config.mjs
  • clients/web/apps/marketing/src/layouts/MarketingLayout.astro
  • clients/web/packages/shared/nothing-theme.css
  • clients/web/packages/ui/src/components/Button.vue
  • clients/web/packages/ui/src/components/Input.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/design.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
  • openspec/specs/theming/spec.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: submit-gradle
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (3)
**/*

⚙️ CodeRabbit configuration file

**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.

Files:

  • clients/web/apps/marketing/src/layouts/MarketingLayout.astro
  • clients/web/apps/docs/astro.config.mjs
  • clients/web/packages/ui/src/components/Input.vue
  • clients/web/packages/ui/src/components/Button.vue
  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
  • openspec/specs/theming/spec.md
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/CSS_ARCHITECTURE.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md
  • clients/web/packages/shared/nothing-theme.css
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/design.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md
**/*.vue

⚙️ CodeRabbit configuration file

**/*.vue: Enforce Vue 3 Composition API with <script setup>.
Ensure accessibility (A11y) and proper use of Tailwind CSS classes.
Check for proper prop validation and emitted events documentation.

Files:

  • clients/web/packages/ui/src/components/Input.vue
  • clients/web/packages/ui/src/components/Button.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
**/*.{md,mdx}

⚙️ CodeRabbit configuration file

**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes.
For user-facing docs, check EN/ES parity or explicitly note pending translation gaps.

Files:

  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
  • openspec/specs/theming/spec.md
  • clients/web/CSS_ARCHITECTURE.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/design.md
  • openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md
🧠 Learnings (1)
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why

Applied to files:

  • openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md
🪛 LanguageTool
openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md

[style] ~168-~168: This adverb was used twice in the sentence. Consider removing one of them or replacing them with a synonym.
Context: ...tly - Tailwind bridge utilities resolve correctly in both themes for chat and dashboard -...

(ADVERB_REPETITION_PREMIUM)

clients/web/CSS_ARCHITECTURE.md

[style] ~113-~113: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... rules in packages/shared/base.css. - Put shared app-frame concerns for Vue appli...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md

[uncategorized] ~18-~18: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...rple/indigo (#818cf8, #6366f1) with sky blue gradients - Heavy use of gradients, gla...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~182-~182: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...08 lines of custom CSS is essentially a full page redesign. The marketing page has termin...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md

[grammar] ~6-~6: Use a hyphen to join words.
Context: ....md` exists. This spec defines the theme switching mechanism, font loading strate...

(QB_NEW_EN_HYPHEN)


[grammar] ~6-~6: Use a hyphen to join words.
Context: ...ines the theme switching mechanism, font loading strategy, Tailwind v4 bridge, an...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~64-~64: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...cur within one animation frame - AND no full page reload SHALL occur #### Scenario: Star...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.22.0)
openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md

[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


[warning] 53-53: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 59-59: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 63-63: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 69-69: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 75-75: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 124-124: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 126-126: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 126-126: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 135-135: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 137-137: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 147-147: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 150-150: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 156-156: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 162-162: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 164-164: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 175-175: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

openspec/changes/archive/2026-04-08-nothing-design-system/proposal.md

[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


[warning] 53-53: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 59-59: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 63-63: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 69-69: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 75-75: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 124-124: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 126-126: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 126-126: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 135-135: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 137-137: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 147-147: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 150-150: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 156-156: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 162-162: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 164-164: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 175-175: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🔇 Additional comments (1)
openspec/changes/archive/2026-04-08-nothing-design-system/exploration.md (1)

1-1: Heading level already flagged in prior review.

The first line should use # instead of ## for markdownlint compliance.

Comment on lines +177 to +179
**Why per-app**: The shared package (`@corvus/shared`) is CSS-only. Font imports are JS-level
(via `@fontsource` CSS entry points) and each bundler handles them differently (Vite for Vue,
Astro for static). Centralizing would require a shared JS entry point that doesn't exist.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

The font-loading rationale contradicts the table above.

The table says docs and marketing load fonts from CSS @import, but this paragraph says the imports are JS-level. Reword this as “app-entry-level” or split the Vue and Astro cases; otherwise the architecture note is technically wrong for half of the web surfaces.

As per coding guidelines, "Verify technical accuracy and that docs stay aligned with code changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/CSS_ARCHITECTURE.md` around lines 177 - 179, The paragraph under
the "**Why per-app**" heading in CSS_ARCHITECTURE.md incorrectly states font
imports are "JS-level" which contradicts the table; update the text to use
"app-entry-level" or explicitly split the explanation for Vue (Vite) and Astro
cases so the docs align with the table: edit the sentence that starts "The
shared package (`@corvus/shared`) is CSS-only. Font imports are JS-level (via
`@fontsource` CSS entry points)..." to either replace "JS-level" with
"app-entry-level" or expand into two clauses that state how Vue (Vite) handles
fonts vs how Astro (static) handles them, keeping the reference to `@fontsource`
and bundler differences.

Comment on lines +107 to +113
:root:not([data-theme="dark"]) {
--corvus-color-bg-base: #f5f5f5;
--corvus-color-bg-surface: #fff;
--corvus-color-bg-raised: #f0f0f0;
--corvus-color-border-default: #e8e8e8;
--corvus-color-border-visible: #ccc;
--corvus-color-text-disabled: #767676;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Light-mode border-visible is not actually visible enough.

--corvus-color-border-visible: #ccc against `--corvus-color-bg-base: `#f5f5f5 is only about 1.5:1, so the default input underline and secondary button border are barely perceptible in light mode. Since this token is reused for control boundaries across the UI package, it should be darkened to meet the 3:1 non-text contrast threshold.

As per coding guidelines, "Look for behavioral regressions, missing tests, and contract breaks across modules."

Also applies to: 126-132

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/packages/shared/nothing-theme.css` around lines 107 - 113, The
light-theme border token --corvus-color-border-visible is too light against
--corvus-color-bg-base and should be darkened to meet a minimum 3:1 non-text
contrast; update the value(s) in the :root:not([data-theme="dark"]) block (and
the equivalent block around lines 126-132) to a darker hex (for example adjust
from `#ccc` to something around `#9e9e9e/`#8b8b8b or another value that passes 3:1)
so input underlines and secondary button borders are perceptible, and ensure you
change every occurrence of --corvus-color-border-visible in that file to the new
value.

Comment on lines +101 to 110
/* Destructive: accent red border */
.btn--destructive {
background: transparent;
border: 1px solid var(--color-border);
color: var(--color-text-secondary);
border: 1px solid var(--corvus-color-accent-default);
color: var(--corvus-color-accent-default);
}

.btn--outline:hover:not(:disabled) {
border-color: var(--color-border-hover);
color: var(--color-text-primary);
background: var(--color-surface-glass);
.btn--destructive:hover:not(:disabled) {
background: var(--corvus-color-accent-subtle);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The destructive variant is too low-contrast in dark mode.

This renders 13px button text in --corvus-color-accent-default on the dark shell backgrounds from nothing-theme.css, and the hover state drops contrast further by tinting the background. Use a filled accent treatment with light text, or a lighter destructive text token, so the label stays readable in both themes.

As per coding guidelines, "Ensure accessibility (A11y) and proper use of Tailwind CSS classes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/packages/ui/src/components/Button.vue` around lines 101 - 110,
The .btn--destructive CSS variant currently uses transparent background with
border and text in --corvus-color-accent-default which is low-contrast on dark
shells (see nothing-theme.css); update the .btn--destructive rule (and its
:hover:not(:disabled) state) to use a filled accent treatment with a light
foreground (e.g., swap to a bright-on-accent color variable) or change the text
color token to a lighter destructive token so 13px text meets contrast in both
themes; adjust the hover state to preserve contrast (darker accent background or
same filled style) and follow project Tailwind/A11y conventions when mapping
tokens so Button.vue’s destructive variant stays readable in both light and dark
themes.

Comment on lines +40 to 41
transition: border-color var(--corvus-motion-duration-micro) var(--corvus-motion-easing-default);
outline: none;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Restore a real focus indicator on the input.

The native outline is removed here, so keyboard users only get a 1px bottom-border color change on focus. Keep the minimal underline if you want, but add a non-color-only :focus-visible ring so the field stays discoverable.

Suggested fix
 .form-input {
   display: flex;
   height: 44px;
   width: 100%;
   border-radius: 0;
   border: none;
   border-bottom: 1px solid var(--corvus-color-border-visible);
   background: transparent;
   padding: 0 var(--corvus-spacing-sm);
   font-size: var(--corvus-typography-scale-body-sm-size);
   font-family: var(--corvus-typography-font-mono);
   color: var(--corvus-color-text-primary);
   transition: border-color var(--corvus-motion-duration-micro) var(--corvus-motion-easing-default);
   outline: none;
+  outline-offset: 2px;
 }
@@
 .form-input:focus {
   border-bottom-color: var(--corvus-color-text-primary);
 }
+
+.form-input:focus-visible {
+  outline: 2px solid var(--corvus-color-text-primary);
+}

As per coding guidelines, "Ensure accessibility (A11y) and proper use of Tailwind CSS classes."

Also applies to: 48-50

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/packages/ui/src/components/Input.vue` around lines 40 - 41, The
input CSS removes the native outline causing poor keyboard discoverability; in
Input.vue restore a non-color-only focus indicator by adding a :focus-visible
rule on the input element that preserves the existing minimal underline
transition but also applies a visible ring/outline (e.g., a 2px outline or
box-shadow ring using a high-contrast color or CSS variable) so focus isn’t
conveyed by color change alone; update the same treatment for the other focus
rules around the transition/outline lines (the rules near the existing
"transition: border-color..." and "outline: none;") and ensure the new
:focus-visible style is accessible (contrasting and not solely color-based) and
removed on :focus when not :focus-visible.

Comment on lines +215 to +218
--corvus-motion-fast: 150ms;
--corvus-motion-normal: 200ms;
--corvus-motion-slow: 300ms;
--corvus-motion-easing: cubic-bezier(0.25, 0.1, 0.25, 1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Unify motion token names in the design doc contract.

Line 215–218 defines --corvus-motion-fast|normal|slow and --corvus-motion-easing, but Line 563 and Line 662 use --corvus-motion-duration-micro and --corvus-motion-easing-default. This creates a broken spec contract for implementers/tests.

Proposed doc fix
-  --corvus-motion-fast: 150ms;
-  --corvus-motion-normal: 200ms;
-  --corvus-motion-slow: 300ms;
-  --corvus-motion-easing: cubic-bezier(0.25, 0.1, 0.25, 1);
+  --corvus-motion-duration-micro: 150ms;
+  --corvus-motion-duration-default: 200ms;
+  --corvus-motion-duration-slow: 300ms;
+  --corvus-motion-easing-default: cubic-bezier(0.25, 0.1, 0.25, 1);

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

Also applies to: 563-564, 662-663

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/design.md` around
lines 215 - 218, The design doc defines motion tokens as
--corvus-motion-fast/normal/slow and --corvus-motion-easing but other parts of
the doc reference --corvus-motion-duration-micro and
--corvus-motion-easing-default, which breaks the contract; choose a single
canonical token naming (either the duration-prefixed form like
--corvus-motion-duration-micro / --corvus-motion-duration-normal /
--corvus-motion-duration-slow and --corvus-motion-easing-default, or keep the
fast/normal/slow + --corvus-motion-easing) and update all occurrences to match
that choice (update the token definitions at the top of the document and replace
usages of --corvus-motion-fast|normal|slow or --corvus-motion-duration-micro and
--corvus-motion-easing vs --corvus-motion-easing-default throughout the doc,
including examples/tests), ensuring token names in the contract and examples are
identical.

Comment on lines +240 to +242
- THEN all transitions MUST be reduced to 0ms duration or removed entirely
- AND opacity-only fades MAY be preserved at reduced duration
- AND no element SHALL use positional animation (slide, translate, scale)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Resolve contradictory reduced-motion requirements.

Line 240 requires transitions be 0ms or removed entirely, but Line 241 allows reduced-duration opacity fades. These conflict as normative rules; define a single allowed policy (e.g., 0ms for all non-opacity, capped duration for opacity-only).

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/design-tokens/spec.md`
around lines 240 - 242, Change the conflicting motion rules so they form one
clear policy: update the rule that currently reads "THEN all transitions MUST be
reduced to 0ms duration or removed entirely" to explicitly target non-opacity
transitions (e.g., "all non-opacity transitions MUST be reduced to 0ms or
removed"), and keep the rule that allows "opacity-only fades MAY be preserved"
but make it normative by adding a capped reduced duration (e.g., "opacity-only
fades MAY be preserved at a reduced duration not exceeding 200ms"); reference
the exact phrases "THEN all transitions MUST be reduced to 0ms duration or
removed entirely" and "AND opacity-only fades MAY be preserved at reduced
duration" when making the edits so the policy is unambiguous.

Comment on lines +126 to +127
- Astro apps (docs, marketing) MUST load fonts via `@fontsource` packages imported in their
layout files, NOT via Google Fonts CDN links
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Astro font-loading rule is too narrow and conflicts with current implementation.

Line 126–127 requires Astro apps to load fonts in layout files, but this change set validates CSS-based @fontsource imports in app stylesheets. Spec should allow app-boundary CSS imports (and ban Google CDN links), not mandate layout-file location.

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`
around lines 126 - 127, Update the requirement that currently reads "Astro apps
(docs, marketing) MUST load fonts via `@fontsource` packages imported in their
layout files, NOT via Google Fonts CDN links" so it permits app-boundary CSS
imports instead of mandating layout-file location: reword the rule to require
that Astro apps must load fonts via `@fontsource` packages (imported either in
app-level stylesheets or layout files) and must not use Google Fonts CDN links;
ensure the spec language around the rule (the sentence containing "Astro apps
(docs, marketing) MUST load fonts via `@fontsource`") is replaced to reflect
this broader allowance while keeping the ban on Google CDN links.

Comment on lines +268 to +282
- AND `apps/chat/src/style.css` MUST import `@corvus/shared/nothing-theme.css` instead of
`app-shell.css`
- AND `apps/chat/src/style.css` MUST include the Tailwind `@theme` bridge
- AND the `pulse-glow` animation MUST be removed
- AND `apps/chat/package.json` MUST list Nothing font packages as dependencies
- AND `apps/chat/package.json` MUST NOT list legacy font packages

#### Scenario: Dashboard app migration

- GIVEN the dashboard app is migrated
- WHEN the app is inspected
- THEN `apps/dashboard/src/main.ts` MUST import Nothing font packages only
- AND `apps/dashboard/src/style.css` MUST import `@corvus/shared/nothing-theme.css` instead of
`app-shell.css`
- AND `apps/dashboard/src/style.css` MUST include the Tailwind `@theme` bridge
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Chat/dashboard import requirement points to the wrong shared stylesheet.

Line 268 and Line 280 require nothing-theme.css import “instead of app-shell.css”, but the migration architecture uses nothing-shell.css for Vue apps. This currently specifies the wrong contract.

Proposed doc fix
-- AND `apps/chat/src/style.css` MUST import `@corvus/shared/nothing-theme.css` instead of
-  `app-shell.css`
+- AND `apps/chat/src/style.css` MUST import `@corvus/shared/nothing-shell.css` instead of
+  `app-shell.css`
...
-- AND `apps/dashboard/src/style.css` MUST import `@corvus/shared/nothing-theme.css` instead of
-  `app-shell.css`
+- AND `apps/dashboard/src/style.css` MUST import `@corvus/shared/nothing-shell.css` instead of
+  `app-shell.css`

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-08-nothing-design-system/specs/theming/spec.md`
around lines 268 - 282, The spec incorrectly mandates importing
`@corvus/shared/nothing-theme.css` "instead of `app-shell.css`" for Vue apps;
update the two requirements (the Chat and Dashboard clauses that reference
importing `nothing-theme.css` instead of `app-shell.css`) to require importing
`@corvus/shared/nothing-shell.css` instead of `app-shell.css`, and ensure the
related lines that mention the Tailwind `@theme` bridge and font package rules
remain unchanged (search for the strings `@corvus/shared/nothing-theme.css`,
`app-shell.css`, and the Chat/Dashboard requirement blocks to locate and
replace).

Comment on lines +12 to +17
| Tasks total | 27 |
| Tasks complete | 27 |
| Tasks incomplete | 0 |

All 27 tasks across 6 phases are marked `[x]` complete.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Completeness metrics conflict with stated verification gaps.

Line 12–17 reports Tasks incomplete: 0, but Line 140–145 says runtime/browser proof and bundle delta remain unverified. Please split “completed checklist items” from “fully verified criteria” to avoid a false-green read.

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

Also applies to: 140-145

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/archive/2026-04-08-nothing-design-system/verify-report.md`
around lines 12 - 17, The summary table currently conflates checklist completion
with full verification; update verify-report.md so the top table separates
"Checklist items" from "Verification status" (e.g., keep "Tasks total | 27 /
Tasks complete | 27 / Tasks incomplete | 0" as Checklist items) and add separate
rows or a following short table for "Verification" that lists criteria verified
vs unverified (e.g., "Fully verified criteria | X" and "Unverified criteria |
runtime/browser proof, bundle delta") so the report does not show a false-green
state; make sure the narrative around the existing notes (the runtime/browser
proof and bundle delta mentioned later) references the new "Unverified criteria"
entries so readers can reconcile checklist completion with outstanding
verification.

Comment on lines +16 to +17
The system MUST support automatic theme detection via `prefers-color-scheme` and manual override
via a CSS class or data attribute. Theme switching MUST NOT cause page reloads or FOUC.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Tighten override contract to data-theme only.

Line 17 permits “CSS class or data attribute,” but Line 24–25 mandates html[data-theme=...]. Keep one mechanism in the normative requirement to prevent divergent implementations.

As per coding guidelines: "Verify technical accuracy and that docs stay aligned with code changes."

Also applies to: 24-25

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/specs/theming/spec.md` around lines 16 - 17, The spec currently
allows theme override via a “CSS class or data attribute” but later mandates
html[data-theme=...]; update the normative requirement to require a data
attribute only (data-theme) and remove mention of CSS class; change the sentence
that lists override mechanisms to read only “via a data attribute
(html[data-theme=...])”, and scan/update any other occurrences (e.g., the
html[data-theme=...] reference at lines 24–25 and any other mentions of CSS
class overrides) so the document consistently and exclusively specifies
data-theme as the override mechanism.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

✅ Contributor Report

User: @yacosta738
Status: Passed (12/13 metrics passed)

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 90% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 10 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3084 days >= 30 days
Activity Consistency Regular activity over time 108% >= 0%
Issue Engagement Issues with community engagement 0 >= 0
Code Reviews Code reviews given to others 530 >= 0
Merger Diversity Unique maintainers who merged PRs 2 >= 0
Repo History Merge Rate Merge rate in this repo 91% >= 0%
Repo History Min PRs Previous PRs in this repo 211 >= 0
Profile Completeness Profile richness (bio, followers) 90 >= 0
Suspicious Patterns Spam-like activity detection 1 N/A

Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-04-08 to 2026-04-08

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
clients/web/apps/chat/src/App.vue (2)

534-559: ⚠️ Potential issue | 🔴 Critical

Unresolved merge conflict will break the build.

Git conflict markers (<<<<<<<, =======, >>>>>>>) remain in the template. The Vue compiler will fail to parse this.

Resolution guidance:

  • Use isGatewayReady and canResumeSession (already destructured at lines 52 and 66; Vue auto-unwraps refs in templates)
  • Use variant="secondary" (per Button.vue props, "outline" is not a valid variant)
Proposed fix
           <Button
-<<<<<<< HEAD
-              v-if="gateway.isGatewayReady.value"
-              variant="secondary"
-=======
-              v-if="isGatewayReady"
-              variant="outline"
->>>>>>> origin/main
+              v-if="isGatewayReady"
+              variant="secondary"
               `@click`="startNewSession"
             >
               {{ t("chat.startSession") }}
             </Button>
             <Button
-<<<<<<< HEAD
-              v-if="gateway.isGatewayReady.value"
-              variant="secondary"
-              :disabled="!chat.canResumeSession.value"
-=======
-              v-if="isGatewayReady"
-              variant="outline"
-              :disabled="!canResumeSession"
->>>>>>> origin/main
+              v-if="isGatewayReady"
+              variant="secondary"
+              :disabled="!canResumeSession"
               `@click`="resumeSession"
             >
               {{ t("chat.resumeSession") }}
             </Button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/App.vue` around lines 534 - 559, The template
contains unresolved Git conflict markers that will break the build; remove the
conflict markers and update the two Button usages to use the destructured refs
isGatewayReady and canResumeSession (Vue auto-unwraps refs in template) and set
the prop variant="secondary" (Button expects "secondary", not "outline"),
keeping the existing `@click` handlers startNewSession and resumeSession intact;
ensure no leftover <<<<<<<, =======, >>>>>>> markers remain in the file.

1064-1090: 🧹 Nitpick | 🔵 Trivial

Consider adding a visible focus ring to .send-btn for keyboard accessibility.

The send button has hover and active states but lacks an explicit :focus-visible style. Keyboard users may not see clear focus indication.

Suggested enhancement
 .send-btn:disabled {
   opacity: 0.3;
   cursor: not-allowed;
 }
+
+.send-btn:focus-visible {
+  outline: 2px solid var(--corvus-color-interactive-default);
+  outline-offset: 2px;
+}

As per coding guidelines: "Ensure accessibility (A11y)" for Vue components.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/App.vue` around lines 1064 - 1090, The .send-btn
lacks a visible keyboard focus state; add a :focus-visible (and/or
:focus-visible:not(:disabled)) CSS rule for .send-btn that applies a clear
high-contrast focus ring (e.g., outline or box-shadow) using existing design
tokens (or define a new --corvus-focus-ring token) and ensure it doesn't
conflict with hover/active states and works when the button is enabled; update
the stylesheet near the .send-btn rules and include the focus rule alongside
:hover and :active so keyboard users get a distinct visual indicator.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/web/apps/dashboard/src/App.vue`:
- Around line 685-687: The .helper CSS rule uses the disabled token which
reduces readability; update the .helper selector to use the non-disabled
supporting text token --corvus-color-text-secondary instead of
--corvus-color-text-disabled so onboarding guidance and webhook status copy
match other supporting text and improve accessibility; locate the .helper rule
in App.vue and replace the variable reference accordingly, then run a quick
visual/a11y check to confirm contrast.
- Around line 240-246: Resolve the git conflict by removing the conflict markers
and using the destructured bindings (loading, pairGateway, connectGateway)
rather than config.*, and set the Button variant to an allowed value; replace
the conflict block with two Buttons that use :disabled="loading",
`@click`="pairGateway" and :disabled="loading" variant="secondary"
`@click`="connectGateway" (Button component accepts "secondary" not "outline").

---

Outside diff comments:
In `@clients/web/apps/chat/src/App.vue`:
- Around line 534-559: The template contains unresolved Git conflict markers
that will break the build; remove the conflict markers and update the two Button
usages to use the destructured refs isGatewayReady and canResumeSession (Vue
auto-unwraps refs in template) and set the prop variant="secondary" (Button
expects "secondary", not "outline"), keeping the existing `@click` handlers
startNewSession and resumeSession intact; ensure no leftover <<<<<<<, =======,
>>>>>>> markers remain in the file.
- Around line 1064-1090: The .send-btn lacks a visible keyboard focus state; add
a :focus-visible (and/or :focus-visible:not(:disabled)) CSS rule for .send-btn
that applies a clear high-contrast focus ring (e.g., outline or box-shadow)
using existing design tokens (or define a new --corvus-focus-ring token) and
ensure it doesn't conflict with hover/active states and works when the button is
enabled; update the stylesheet near the .send-btn rules and include the focus
rule alongside :hover and :active so keyboard users get a distinct visual
indicator.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: cfe236ec-f6cf-417e-b09a-59a93a293a9f

📥 Commits

Reviewing files that changed from the base of the PR and between 3beb7f7 and a936abc.

📒 Files selected for processing (2)
  • clients/web/apps/chat/src/App.vue
  • clients/web/apps/dashboard/src/App.vue
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.vue

⚙️ CodeRabbit configuration file

**/*.vue: Enforce Vue 3 Composition API with <script setup>.
Ensure accessibility (A11y) and proper use of Tailwind CSS classes.
Check for proper prop validation and emitted events documentation.

Files:

  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/chat/src/App.vue
**/*

⚙️ CodeRabbit configuration file

**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.

Files:

  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/chat/src/App.vue
🔇 Additional comments (5)
clients/web/apps/chat/src/App.vue (4)

386-388: LGTM!

Removal of animate-pulse-glow aligns with the Nothing design system migration and style.css cleanup.


491-493: LGTM!

Consistent removal of glow animation from hero icon.


613-613: LGTM!

Variant "secondary" is valid per Button component props. Aligns with design system migration.


643-706: CSS token migration looks consistent.

The design token updates from legacy --color-* to --corvus-* are applied uniformly across all style rules. Border radius, motion, and color tokens align with the Nothing design system conventions.

clients/web/apps/dashboard/src/App.vue (1)

480-677: The token migration across the shell/onboarding styles looks consistent.

The --corvus-* replacements for cards, tabs, onboarding states, and status colors are cohesive and remove the remaining page-local styling primitives cleanly.

Also applies to: 689-701

Comment thread clients/web/apps/dashboard/src/App.vue Outdated
Comment thread clients/web/apps/dashboard/src/App.vue
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 3 file(s) based on 2 unresolved review comments.

Files modified:

  • clients/web/apps/dashboard/src/App.vue
  • pnpm-lock.yaml
  • pnpm-workspace.yaml

Commit: b8474d3da0ef9a3ca045d395badcee8d054c6394

The changes have been pushed to the style/nothing branch.

Time taken: 2m 58s

coderabbitai Bot and others added 2 commits April 8, 2026 10:46
Fixed 3 file(s) based on 2 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Apr 8, 2026

@yacosta738 yacosta738 merged commit c62bca5 into main Apr 8, 2026
14 checks passed
@yacosta738 yacosta738 deleted the style/nothing branch April 8, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant