refactor(ui): token discipline, voice pass, a11y guards, radius normalization#182
Conversation
…ormalization - Replace hardcoded #hex/oklch literals in discord, marketing, app-shell, pwa components with scoped CSS vars or semantic DaisyUI/Nuxt UI tokens - Consume existing gradient-text-hero and nav-panel-glass utilities instead of duplicating in component <style> blocks - Normalize border-radius convention (cards rounded-xl, blocks rounded-lg, avatars/pills rounded-full) across guild, command, and layout components - Add forced-colors outline to skip link focus state (a11y, WCAG 2.2 AA) - Apply design.md terminology canon to user-facing copy only: Sign in/out, Server vs Guild in UI text, WolfStar casing; code identifiers unchanged - Add test/unit/design-tokens/no-hardcoded-colors.test.ts to prevent future regressions; allow-list OgImage/Takumi and Discord brand-fidelity files - Sync .atlas/design.md to actual token values (Inter only, 0.5rem radii, utilities catalog, voice and terminology canon) - Document Design Token Discipline in AGENTS.md
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR establishes design token discipline: a comprehensive Style Reference, Tailwind theme tokens, a Vitest guardrail preventing hardcoded colours, Whitney font utilities, and coordinated component updates switching hardcoded palette values to semantic tokens, standardising radii and fractional sizing, and normalising sign-in/out copy. ChangesDesign Token System & Enforcement
Possibly Related PRs
Suggested Reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #182 +/- ##
=======================================
Coverage 66.83% 66.83%
=======================================
Files 81 81
Lines 2023 2023
Branches 601 601
=======================================
Hits 1352 1352
Misses 534 534
Partials 137 137
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR is a design-system normalization pass for WolfStar.rocks, focused on enforcing semantic design tokens, aligning UI copy with the brand voice canon, and adding an automated guardrail to prevent hardcoded colors from reappearing in Vue SFCs.
Changes:
- Replaced raw Tailwind palette classes / inline gradients with semantic tokens and existing utilities, plus normalized border radii across cards/interactive surfaces.
- Updated user-facing auth/session terminology (“Sign in/Sign out”) to match the canonical voice.
- Added a Vitest guardrail that scans Vue
<template>/<style>blocks for hardcoded color usage, and documented the policy in repo guides.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
test/unit/design-tokens/no-hardcoded-colors.test.ts |
Adds a Vitest-based guardrail to block hardcoded colors / raw palette classes in Vue SFCs. |
app/pages/oauth/guild.vue |
Updates user-facing terminology (“log in” → “sign in”). |
app/pages/oauth/callback.vue |
Updates user-facing terminology (“log in” → “sign in”). |
app/pages/commands.vue |
Normalizes card/container radius to the updated convention. |
app/pages/(marketing)/wolfstar/index.vue |
Replaces inline gradient implementation with the shared gradient-text-hero utility. |
app/pages/(marketing)/wolfstar/@components/FeatureShowcase.client.vue |
Replaces raw palette text color classes with semantic tokens (text-primary). |
app/layouts/default.vue |
Adjusts skip-link focus styling to better support forced-colors/high-contrast modes. |
app/components/UserMenu.vue |
Updates “Log out” terminology to “Sign out”. |
app/components/pwa/InstallPrompt.client.vue |
Replaces raw palette classes with semantic token (text-muted). |
app/components/guild/card.vue |
Normalizes skeleton radius to the updated convention. |
app/components/discord/message.vue |
Moves Discord brand color usage into scoped CSS custom properties. |
app/components/discord/invite.vue |
Replaces bg-green-500 with semantic success token (bg-success). |
app/components/discord/embed.vue |
Replaces hardcoded colors/values with CSS vars and normalized sizing utilities. |
app/components/command/Base.vue |
Normalizes container radius to the updated convention. |
app/components/app/Header.vue |
Updates sign-in labels/aria-labels and refactors navbar styling to token-friendly values. |
app/components/app/Footer.vue |
Replaces raw palette UI styling (bg-green-500) with semantic token (bg-success). |
AGENTS.md |
Documents the new “Design Token Discipline” policy and the guardrail test scope. |
.atlas/design.md |
Expands and synchronizes the style reference (tokens, voice canon, utilities catalog, radius guidance). |
There was a problem hiding this comment.
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)
app/pages/oauth/callback.vue (1)
6-17:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winIncomplete terminology pass —
"Login Required"and"Go to Login"were missed.Line 9 was updated to
"sign in"but two adjacent user-facing strings in the same block still use the prohibited term. Per the brand Terminology table (Sign in/ notLog in, login, connect):
- Line 6:
title="Login Required"→title="Sign-In Required"- Line 13:
"Go to Login"→"Go to Sign In"Note: the route
/loginis exempt (routes retain existing identifiers per the scope note).✏️ Proposed fix
- <UAlert variant="solid" color="warning" title="Login Required" icon="twemoji:warning"> + <UAlert variant="solid" color="warning" title="Sign-In Required" icon="twemoji:warning"> <template `#description`> This page can't be accessed directly. Please <ULink to="/login" class="font-medium underline">sign in</ULink> to continue. </template> <template `#actions`> - <UButton color="neutral" variant="ghost" to="/login" size="sm"> - Go to Login + <UButton color="neutral" variant="ghost" to="/login" size="sm"> + Go to Sign In </UButton> </template> </UAlert>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/pages/oauth/callback.vue` around lines 6 - 17, Change the remaining uses of "login"/"Login" in the UAlert block to the preferred branding "Sign In": update the UAlert title prop value from "Login Required" to "Sign-In Required" and change the UButton label text from "Go to Login" to "Go to Sign In" while leaving the ULink to="/login" route unchanged; locate these strings in the UAlert component render (UAlert title, UButton children) and replace them accordingly.app/components/app/Header.vue (1)
77-86:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd a visible text label to the mobile sign-in button.
The mobile
UButtonis icon-only witharia-label, but this control still needs a persistent visible label. This is a primary action, so it should be unambiguous visually as well as programmatically.Suggested fix
<UButton + label="Sign in" size="md" color="primary" variant="subtle" to="/login" block class="md:hidden" icon="ic:round-discord" aria-label="Sign in with Discord" />As per coding guidelines, “Every interactive element must have a visible label” and “The accessible name of each interactive element must contain the visible label text”.
Also applies to: 85-85
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/app/Header.vue` around lines 77 - 86, The mobile UButton used for Discord sign-in is icon-only and needs a persistent visible label; update the UButton(s) (the components with icon="ic:round-discord" used for the mobile sign-in) to render visible text such as "Sign in with Discord" (either via a default slot or a text prop) and ensure the aria-label matches that visible text so the accessible name contains the same words; keep the icon if desired but do not rely solely on aria-label for identification.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/components/discord/embed.vue`:
- Around line 76-77: The Tailwind utility `h-56.25` used in
app/components/discord/embed.vue will be dropped by the Tailwind scanner; update
the CSS rule that uses `@apply h-56.25` to use the arbitrary value syntax
`@apply h-[225px]` (or replace the class usage `h-56.25` with `h-[225px]`) so
Tailwind generates the correct height utility in the compiled CSS.
In `@test/unit/design-tokens/no-hardcoded-colors.test.ts`:
- Around line 67-82: extractBlocks currently only extracts <template> and
<style> blocks, leaving raw Tailwind class strings inside <script> (e.g.,
<script setup>) untested; add extraction for <script> blocks by introducing a
scriptRe (e.g. /<script(?:\s[^>]*)?>[\\s\\S]*?<\\/script>/gi), iterate
source.matchAll(scriptRe) to collect script contents into a new scripts array,
update the function signature/return type to { templates: string[]; styles:
string[]; scripts: string[] } and adjust any callers/tests that use
extractBlocks (or merge scripts into the existing templates scan where
appropriate) so classes inside <script> are covered by the same checks.
---
Outside diff comments:
In `@app/components/app/Header.vue`:
- Around line 77-86: The mobile UButton used for Discord sign-in is icon-only
and needs a persistent visible label; update the UButton(s) (the components with
icon="ic:round-discord" used for the mobile sign-in) to render visible text such
as "Sign in with Discord" (either via a default slot or a text prop) and ensure
the aria-label matches that visible text so the accessible name contains the
same words; keep the icon if desired but do not rely solely on aria-label for
identification.
In `@app/pages/oauth/callback.vue`:
- Around line 6-17: Change the remaining uses of "login"/"Login" in the UAlert
block to the preferred branding "Sign In": update the UAlert title prop value
from "Login Required" to "Sign-In Required" and change the UButton label text
from "Go to Login" to "Go to Sign In" while leaving the ULink to="/login" route
unchanged; locate these strings in the UAlert component render (UAlert title,
UButton children) and replace them accordingly.
🪄 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.yml
Review profile: CHILL
Plan: Pro
Run ID: 6cfdd473-1b3d-41bd-85a8-6db1ef99274e
📒 Files selected for processing (18)
.atlas/design.mdAGENTS.mdapp/components/UserMenu.vueapp/components/app/Footer.vueapp/components/app/Header.vueapp/components/command/Base.vueapp/components/discord/embed.vueapp/components/discord/invite.vueapp/components/discord/message.vueapp/components/guild/card.vueapp/components/pwa/InstallPrompt.client.vueapp/layouts/default.vueapp/pages/(marketing)/wolfstar/@components/FeatureShowcase.client.vueapp/pages/(marketing)/wolfstar/index.vueapp/pages/commands.vueapp/pages/oauth/callback.vueapp/pages/oauth/guild.vuetest/unit/design-tokens/no-hardcoded-colors.test.ts
24006ea to
8108e09
Compare
b457a10 to
0e8c281
Compare
|
@copilot apply changes based on the comments in this thread |
|
@copilot apply changes based on the comments in this thread |
…k outline Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/8c512cd4-d809-4aac-8225-f4ca187b8a2c Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Applied all requested review-thread fixes in
Screenshot (UI context after this update): Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
Agent-Logs-Url: REDACTED nfig/composer/vendor/bin/git --abbrev-ref HEAD n/git -test/dist/worke--abbrev=0` (dns block)
|
There was a problem hiding this comment.
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 (1)
app/components/app/Header.vue (1)
143-150:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTwo violations in the dropdown
itemsblock contradict the rules this PR establishes.1 — Terminology:
label: "Log Out"should be"Sign out"per the Terminology canon introduced in.atlas/design.md("Sign out | Log out, logout, disconnect").2 — Token discipline:
itemLeadingIcon: "bg-red-500"is a raw Tailwind palette class inside a<script setup>block. The Vitest guardrail only scans<template>and<style>, so this bypasses enforcement. Use the semantic tokenbg-errorinstead.🛠️ Proposed fix
- label: "Log Out", + label: "Sign out", onSelect: logout, ui: { - itemLeadingIcon: "bg-red-500", + itemLeadingIcon: "bg-error", },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/app/Header.vue` around lines 143 - 150, Update the dropdown item in Header.vue that currently uses label "Log Out" and a raw Tailwind class for itemLeadingIcon: change the label to "Sign out" and replace the raw palette class "bg-red-500" with the semantic token "bg-error" so the entry uses approved Terminology and token discipline; locate the dropdown items array (the object with icon "lucide:log-out", label, onSelect: logout, ui) and edit its label and ui.itemLeadingIcon accordingly.
🧹 Nitpick comments (3)
app/themes/header.ts (1)
5-12: 💤 Low valueLGTM — token normalisation and floating-pill pattern look correct.
The
pointer-events-noneonrootwithpointer-events-autorestored oncontainer,content, andoverlayis the standard click-through wrapper technique. Consumingcard-glassandnav-panel-glassutilities instead of inlining equivalent CSS aligns with the PR's semantic token discipline.One minor note: Line 12 uses
border-noneonroot. The more idiomatic Tailwind reset for "no border" isborder-0, since the defaultborder-styleon a<div>is alreadynone.border-noneis harmless here butborder-0is more conventional.Optional: prefer
border-0overborder-none- root: "sticky top-3 z-50 w-full bg-transparent border-none flex justify-center px-4 pointer-events-none", + root: "sticky top-3 z-50 w-full bg-transparent border-0 flex justify-center px-4 pointer-events-none",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/themes/header.ts` around lines 5 - 12, Update the theme tokens to use the Tailwind-conventional utility for removing borders: in app/themes/header.ts replace the "border-none" entry in the root token with "border-0" (the token named root) so the header uses the idiomatic Tailwind reset while keeping all other classes (pointer-events-none, sticky top-3, z-50, etc.) unchanged..atlas/design.md (2)
199-213: ⚡ Quick winAgent Prompt Guide examples teach raw literal usage, which contradicts the token canon.
Examples like
oklch(14% 0.005 285.823)andoklch(58.73% 0.0204 272.13)in the prompt snippets will train authors to hard-code oklch literals in new components rather than reference the defined CSS custom properties (var(--color-neutral),var(--color-secondary), etc.). Replace the inline literals with their token names to model correct usage.✏️ Suggested change (example 1)
-1. Create a hero section with an `Obsidian` background (`oklch(14% 0.005 285.823)`). Headline (Inter, 54px, weight 700, `Canvas White`). Subtext (Inter, 18px, weight 400, `Canvas White`, line-height 1.2). +1. Create a hero section with `background: var(--color-neutral)` (`Obsidian`). Headline: `font-size: var(--text-display)` / `font-weight: var(--font-weight-bold)` / `color: var(--color-base-100)`. Subtext: `font-size: var(--text-subheading)` / `line-height: var(--leading-subheading)` / `color: var(--color-base-100)`.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.atlas/design.md around lines 199 - 213, The Agent Prompt Guide uses hard-coded oklch color literals (e.g., "oklch(14% 0.005 285.823)", "oklch(58.73% 0.0204 272.13)") in the Example Component Prompts which contradicts the token canon; update the examples in the "Agent Prompt Guide" (examples 1–4) to reference the design tokens (e.g., var(--color-neutral), var(--color-secondary), var(--color-accent), var(--color-primary-action)) instead of inline oklch(...) literals so authors learn to use CSS custom properties consistently.
385-455: 💤 Low value
@themeblock is a subset of:root— typography scale and layout tokens are missing.The
:rootblock declares--leading-*,--tracking-*,--font-weight-*,--spacing-unit,--section-gap,--card-padding, and--element-gap, but none of these appear in the@themeblock. In Tailwind v4, tokens absent from@themeare not surfaced as utility classes. If authors needleading-captionortracking-headingutilities, they should be in@themetoo. Either add the missing tokens or add a note clarifying that the@themeblock is intentionally a partial subset.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.atlas/design.md around lines 385 - 455, The `@theme` block is missing many tokens defined in :root (e.g., --leading-caption, --tracking-heading, --font-weight-*, --spacing-unit, --section-gap, --card-padding, --element-gap) which prevents Tailwind v4 from generating corresponding utilities; update the `@theme` block to include these missing variables (copy or map the relevant --leading-*, --tracking-*, --font-weight-*, and spacing tokens from :root into `@theme`) so utilities like leading-caption and tracking-heading are produced, or alternatively add a clear comment in the `@theme` block stating it is intentionally a partial subset and list which tokens are omitted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/unit/design-tokens/no-hardcoded-colors.test.ts`:
- Around line 84-95: The path comparison fails on Windows because relPath is
produced by path.relative(join(ROOT, file)) and contains backslashes while
ALLOW_LIST uses forward slashes; update the relPath computation in the test loop
(where relPath is defined) to normalize separators before checking ALLOW_LIST
(e.g., compute relPath as before then convert backslashes to forward slashes or
use path.posix-style normalization such that ALLOW_LIST.has(normalizedRelPath)
will match on all platforms).
- Around line 100-158: The tests report block-relative line numbers because they
use i+1 from each block's split; change the block representation to include its
starting file-line (e.g., each item in templates and styles becomes an object
with text and startLine or maintain a parallel startLines array) and in the
three test loops ("no raw Tailwind palette classes in <template>" using
templates, "no hex literals in <style>" and "no inline oklch/rgb/rgba in
<style>" using styles) update the expect.fail location string to use
(block.startLine + i + 1) (or startLines[idx] + i + 1) instead of i + 1 so
relPath points to the absolute file line; keep the rest of the checks unchanged.
---
Outside diff comments:
In `@app/components/app/Header.vue`:
- Around line 143-150: Update the dropdown item in Header.vue that currently
uses label "Log Out" and a raw Tailwind class for itemLeadingIcon: change the
label to "Sign out" and replace the raw palette class "bg-red-500" with the
semantic token "bg-error" so the entry uses approved Terminology and token
discipline; locate the dropdown items array (the object with icon
"lucide:log-out", label, onSelect: logout, ui) and edit its label and
ui.itemLeadingIcon accordingly.
---
Nitpick comments:
In @.atlas/design.md:
- Around line 199-213: The Agent Prompt Guide uses hard-coded oklch color
literals (e.g., "oklch(14% 0.005 285.823)", "oklch(58.73% 0.0204 272.13)") in
the Example Component Prompts which contradicts the token canon; update the
examples in the "Agent Prompt Guide" (examples 1–4) to reference the design
tokens (e.g., var(--color-neutral), var(--color-secondary), var(--color-accent),
var(--color-primary-action)) instead of inline oklch(...) literals so authors
learn to use CSS custom properties consistently.
- Around line 385-455: The `@theme` block is missing many tokens defined in :root
(e.g., --leading-caption, --tracking-heading, --font-weight-*, --spacing-unit,
--section-gap, --card-padding, --element-gap) which prevents Tailwind v4 from
generating corresponding utilities; update the `@theme` block to include these
missing variables (copy or map the relevant --leading-*, --tracking-*,
--font-weight-*, and spacing tokens from :root into `@theme`) so utilities like
leading-caption and tracking-heading are produced, or alternatively add a clear
comment in the `@theme` block stating it is intentionally a partial subset and
list which tokens are omitted.
In `@app/themes/header.ts`:
- Around line 5-12: Update the theme tokens to use the Tailwind-conventional
utility for removing borders: in app/themes/header.ts replace the "border-none"
entry in the root token with "border-0" (the token named root) so the header
uses the idiomatic Tailwind reset while keeping all other classes
(pointer-events-none, sticky top-3, z-50, etc.) unchanged.
🪄 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.yml
Review profile: CHILL
Plan: Pro
Run ID: 36b34534-40ed-43e2-85e1-91efe24d0fe3
📒 Files selected for processing (5)
.atlas/design.mdapp/components/app/Header.vueapp/layouts/default.vueapp/themes/header.tstest/unit/design-tokens/no-hardcoded-colors.test.ts
✅ Files skipped from review due to trivial changes (1)
- app/layouts/default.vue
Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/33100415-2666-43d4-ba84-fc003c2a982f Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Applied the review-thread updates in
Screenshot: Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/6142c1d9-574f-40e1-9c93-df09bb4ac5ea Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/6142c1d9-574f-40e1-9c93-df09bb4ac5ea Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/6142c1d9-574f-40e1-9c93-df09bb4ac5ea Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/6142c1d9-574f-40e1-9c93-df09bb4ac5ea Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Applied the thread updates in
Screenshot: Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/assets/css/utilities.css`:
- Line 30: Update the Stylelint configuration to allow Tailwind v4 custom
at-rules by modifying the scss/at-rule-no-unknown rule in .stylelintrc.json: add
an ignoreAtRules array that includes "utility" and "layer" so `@utility` and
`@layer` in app/assets/css/utilities.css are not reported as unknown by
stylelint-config-standard-scss; ensure the rule remains enabled but uses the
ignoreAtRules option to whitelist these two at-rule names.
- Around line 3-31: The CSS uses quoted single-word font family names
("Whitney") which triggers stylelint's font-family-name-quotes rule; update
every occurrence in the shown diff — in each `@font-face` blocks' font-family
declarations and in the `@utility` font-whitney rule — by removing the quotes
around Whitney (e.g., change "Whitney" to Whitney) while leaving fallback
families, commas, font-weight and font-display lines unchanged.
🪄 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.yml
Review profile: CHILL
Plan: Pro
Run ID: a741c02d-b884-4f4a-b0e9-94c5235df73f
📒 Files selected for processing (6)
app/assets/css/utilities.cssapp/components/app/Header.vueapp/components/discord/embed.vueapp/components/discord/messages.vuenuxt.config.tstest/unit/design-tokens/no-hardcoded-colors.test.ts
✅ Files skipped from review due to trivial changes (2)
- app/components/discord/messages.vue
- app/components/discord/embed.vue
🚧 Files skipped from review as they are similar to previous changes (1)
- app/components/app/Header.vue
There was a problem hiding this comment.
♻️ Duplicate comments (2)
app/assets/css/utilities.css (2)
1-3:⚠️ Potential issue | 🟡 MinorQuoted font family name still requires correction.
The issue previously flagged remains:
"Whitney"should be unquoted. Single-word font names that are valid CSS identifiers do not require quotes under thealways-where-recommendedstylelint rule.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/assets/css/utilities.css` around lines 1 - 3, The font-family declaration inside the `@utility` font-whitney rule uses a quoted single-word font name; update the font-family in the font-whitney utility by removing the quotes around Whitney so it reads Whitney, ui-sans-serif, system-ui, sans-serif to comply with the stylelint always-where-recommended rule.
1-3:⚠️ Potential issue | 🟡 MinorStylelint configuration for
@utilitystill required.The
@utilityat-rule continues to triggerscss/at-rule-no-unknown. As previously noted, update.stylelintrc.jsonto include{ "ignoreAtRules": ["utility", "layer"] }for thescss/at-rule-no-unknownrule to support Tailwind v4 custom at-rules.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/assets/css/utilities.css` around lines 1 - 3, Update the Stylelint config so the scss/at-rule-no-unknown rule ignores Tailwind v4 custom at-rules; specifically add "utility" and "layer" to the rule's ignoreAtRules array in .stylelintrc.json (so `@utility` in utilities.css no longer triggers scss/at-rule-no-unknown).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@app/assets/css/utilities.css`:
- Around line 1-3: The font-family declaration inside the `@utility` font-whitney
rule uses a quoted single-word font name; update the font-family in the
font-whitney utility by removing the quotes around Whitney so it reads Whitney,
ui-sans-serif, system-ui, sans-serif to comply with the stylelint
always-where-recommended rule.
- Around line 1-3: Update the Stylelint config so the scss/at-rule-no-unknown
rule ignores Tailwind v4 custom at-rules; specifically add "utility" and "layer"
to the rule's ignoreAtRules array in .stylelintrc.json (so `@utility` in
utilities.css no longer triggers scss/at-rule-no-unknown).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 5e9e94c6-a8b1-4274-a5ba-e2c069e9a8ab
📒 Files selected for processing (2)
app/assets/css/utilities.cssnuxt.config.ts
✅ Files skipped from review due to trivial changes (1)
- nuxt.config.ts
🔗 Linked issue
No issue — this is a proactive normalization pass surfaced by an internal design audit.
🧭 Context
The site had scattered hardcoded color literals, duplicated CSS already present in
utilities.css, inconsistent border-radii across cards, raw Tailwind palette classes (e.g.text-slate-700,bg-green-500) instead of semantic tokens, and user-facing copy that did not match the brand terminology canon in.atlas/design.md. This PR fixes all of that without changing any visual tokens or the DaisyUI theme palette.📚 Description
What changed:
.atlas/design.md— Synchronized to reflect the actual codebase state: Inter-only type stack, corrected radius values (uniform 0.5rem), added Voice & Terminology canon, Utilities Catalog, Copy Patterns, and Do/Don't rules for agents.AGENTS.md— Added Design Token Discipline section documenting the no-hardcoded-colors rule, the allow-list policy, and the new Vitest guardrail.discord/message.vue,discord/embed.vue,discord/invite.vue) — Replaced#5865f2/#1E1F22with scoped CSS custom properties;bg-green-500→bg-success; removed arbitrary[Npx]Tailwind values.wolfstar/index.vue,FeatureShowcase.client.vue) — Replaced inline oklch gradient literals with the existinggradient-text-heroutility;text-purple-500→text-primary.app/Header.vue,app/Footer.vue,pwa/InstallPrompt.client.vue) — Removed duplicated glassmorphism CSS (consumenav-panel-glass);text-slate-700 dark:text-slate-400→text-muted;bg-green-500→bg-success.commands.vue,command/Base.vue,guild/card.vue,UserMenu.vue) — Standardized cards torounded-xl, interactive blocks torounded-lg.layouts/default.vue) — Addedoutline: 2px solid transparentpaired with box-shadow on skip link for forced-colors mode compatibility.oauth/callback.vue,oauth/guild.vue) — "Login with Discord" → "Sign in with Discord" per brand voice canon.test/unit/design-tokens/no-hardcoded-colors.test.ts) — New Vitest test scanning all.vuefiles for hardcoded color literals and raw Tailwind palette classes.What did NOT change:
app/assets/css/main.css— DaisyUI theme palette is frozen.