Skip to content

feat(admin): migrate admin surfaces onto role tokens - #373

Merged
chiptus merged 18 commits into
mainfrom
claude/implement-367-zrn4kp
Aug 23, 2026
Merged

feat(admin): migrate admin surfaces onto role tokens#373
chiptus merged 18 commits into
mainfrom
claude/implement-367-zrn4kp

Conversation

@chiptus

@chiptus chiptus commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Moves role-token CSS variables from .edition-view scope onto global :root so the whole app shares one token set, instead of admin/portal surfaces silently keeping old shadcn light-theme defaults for the same variable names.
Introduces paper-background/paper-foreground/paper-muted-foreground/paper-border tokens for white-background surfaces (dialogs, toasts, admin tables, inputs, OTP) so they no longer inherit the dark-identity background/foreground/muted-foreground/ring values. Named paper-* rather than surface-* to avoid colliding with the existing surface/surface-raised/surface-active translucent overlay tokens.

Verification

  • Open the login dialog: background is white, title/description text is dark, email input border/focus ring are neutral (not purple).
  • Request an OTP and enter it: the 6-digit slots are legible, active slot shows the purple focus ring, caret is visible.
  • Trigger a toast notification: title/description text is legible on the white toast background.
  • Open the admin Artists table: header text, "Click to add…"/"add image…" placeholders, and cell text are all legible.
  • Confirm voter-facing EditionView pages still render the dark purple identity unchanged.

claude added 2 commits August 23, 2026 06:45
Scopes the admin layout root with EditionViewRoot and migrates the
non-portal hardcoded color sites (text-white, bg-white/10,
border-white/20, bg-purple-600) onto the role tokens from #363, with
no visual change since each token carries today's exact value.
Colors inside Radix Dialog/AlertDialog portals are left as-is since
those portals render outside the edition-view CSS variable scope.
…active

Code review flagged reusing the surface-active fill token as a border
color as crossing the vocabulary doc's role taxonomy, even though the
value matched. No border token covers this exact value yet, so leave
it literal, matching the untouched border-white/10 in the same file.
Copilot AI lite review requested due to automatic review settings August 23, 2026 06:49
@vercel

vercel Bot commented Aug 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
upline Ready Ready Preview Aug 23, 2026 6:30pm

Copilot AI left a comment

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.

🟡 Changes recommended

Moderate token-migration gaps remain in hover and border colors, accent foregrounds, and an in-scope LinkWizard color.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Migrates admin surfaces to edition role tokens under EditionViewRoot while preserving current styling.

Changes:

  • Scopes admin content with EditionViewRoot.
  • Replaces selected hardcoded colors with semantic tokens.
  • Updates analytics, navigation, CTA, and archive styling.
File summaries
File Summary
src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets.tsx Tokenizes the Add Set CTA; hardcoded hover color remains.
src/routes/admin/festivals/$festivalSlug/editions/$editionSlug.tsx Tokenizes the edition sub-navigation surface.
src/routes/admin/analytics.tsx Tokenizes analytics surfaces and text; hardcoded borders remain.
src/routes/admin.tsx Adds edition scope and tokenized tabs; active foreground and LinkWizard colors need updates.
src/pages/admin/festivals/StageManagement/CreateStageDialog.tsx Tokenizes the CTA; hardcoded hover color remains.
src/pages/admin/festivals/FestivalManagementSection.tsx Tokenizes the festival CTA; hardcoded hover color remains.
src/pages/admin/festivals/FestivalEditionManagement.tsx Tokenizes the edition CTA; hardcoded hover color remains.
src/pages/admin/festivals/EditionNavLink.tsx Tokenizes navigation states; active accent foreground needs correction.
src/pages/admin/ArtistsManagement/components/BulkEditorHeader.tsx Tokenizes the artist CTA; hardcoded hover color remains.
src/pages/admin/ArtistsManagement/ArchiveArtistDialog.tsx Updates archive hover text styling.
Review details

Suppressed comments (6)

src/pages/admin/ArtistsManagement/ArchiveArtistDialog.tsx:52

  • This replacement uses the page foreground role for text rendered over the destructive red hover fill. That is only correct while both happen to be white; when the edition theme changes foreground, the destructive action can get the wrong contrast. Use the destructive foreground role for text on this fill (and keep the fill on its semantic destructive token).
      className="border-red-400 text-red-400 hover:bg-red-400 hover:text-foreground"

src/pages/admin/festivals/FestivalManagementSection.tsx:38

  • This CTA now gets bg-accent, but Button's default variant still supplies text-primary-foreground; no text-accent-foreground is applied. That is near-white today, but the identity flip changes the dark-theme accent to lime with dark accent-foreground while the global primary foreground remains light, making the label fail the intended contrast. Add the paired accent foreground role to this CTA.
              className="bg-accent hover:bg-purple-700"

src/pages/admin/festivals/StageManagement/CreateStageDialog.tsx:42

  • Only the resting background is tokenized here. This Button still inherits text-primary-foreground, and hover:bg-purple-700 remains a literal; the palette flip changes the scoped accent/accent-foreground but not primary-foreground, so this CTA can have the wrong text contrast and revert to purple on hover. Use text-accent-foreground and a role token for the hover state, consistently with the other converted CTAs.
        <Button className="bg-accent hover:bg-purple-700">

src/pages/admin/festivals/StageManagement/CreateStageDialog.tsx:42

  • This CTA now gets bg-accent, but Button's default variant still supplies text-primary-foreground; no text-accent-foreground is applied. That is near-white today, but the identity flip changes the dark-theme accent to lime with dark accent-foreground while the global primary foreground remains light, making the label fail the intended contrast. Add the paired accent foreground role to this CTA.
        <Button className="bg-accent hover:bg-purple-700">

src/routes/admin.tsx:89

  • Applying the .edition-view scope to the entire admin tree also overrides shared variables such as --muted-foreground (purple-200), --border (purple-400/30), and --ring for existing shadcn components. Most admin cards still use the default white bg-card, while many labels and empty states still use text-muted-foreground (for example BulkEditorFooter), so they now become light purple on white and card borders/focus rings change. This contradicts the claimed zero visual change; scope only fully migrated surfaces or update the remaining admin components/variables before applying this wrapper.
    <EditionViewRoot>

src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets.tsx:95

  • This CTA now gets bg-accent, but Button's default variant still supplies text-primary-foreground; no text-accent-foreground is applied. That is near-white today, but the identity flip changes the dark-theme accent to lime with dark accent-foreground while the global primary foreground remains light, making the label fail the intended contrast. Add the paired accent foreground role to this CTA.
              className="bg-accent hover:bg-purple-700"
  • Files reviewed: 10/10 changed files
  • Comments generated: 9
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/pages/admin/ArtistsManagement/components/BulkEditorHeader.tsx Outdated
Comment thread src/pages/admin/festivals/EditionNavLink.tsx Outdated
Comment thread src/pages/admin/festivals/FestivalEditionManagement.tsx Outdated
Comment thread src/pages/admin/festivals/FestivalManagementSection.tsx Outdated
Comment thread src/pages/admin/festivals/StageManagement/CreateStageDialog.tsx Outdated
Comment thread src/routes/admin.tsx Outdated
Comment thread src/routes/admin.tsx Outdated
Comment thread src/routes/admin/analytics.tsx Outdated
Comment thread src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets.tsx Outdated
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Playwright test results

passed  52 passed

Details

stats  52 tests across 15 suites
duration  1 minute, 6 seconds
commit  a5025ca

…t states

Per review feedback: moves the edition-view role tokens from the
.edition-view scope class onto :root so the whole app shares one set
of values instead of admin (or any other unmigrated surface) keeping
stale shadcn defaults for the same variable names — this also fixes
Radix portal content never seeing the override, since :root is the
ultimate ancestor of a portal too. Adds a real accent-hover token
(purple-700) so CTAs stop mixing a token fill with a literal hover
color, pairs every bg-accent use with text-accent-foreground, and
migrates the remaining non-portal literals flagged in review
(analytics.tsx borders via border-foreground/NN, LinkWizardTable via
bg-accent/20) instead of leaving them hardcoded.
Comment thread docs/design/edition-color-vocabulary.md Outdated

Copilot AI left a comment

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.

🟡 Changes recommended

Three moderate findings remain regarding token scope, theme selector alignment, and archive hover color.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (2)

docs/design/edition-color-vocabulary.md:12

  • This new global-token contract conflicts with the canonical identity spec: docs/design/edition-identity-spec.md:5 still limits the identity to voter-facing edition views and explicitly keeps admin, groups/settings, landing, and auth on the old skin, while this line makes the same roles app-global. Update the canonical spec and the zero-change scope together with the implementation, or retain the scoped model.
- **The tokens live on `:root`, not a scope class (#367).** They used to sit under a `.edition-view` class so only voter-facing pages picked them up, but that meant every other surface (admin included) kept the old shadcn light-theme defaults for the same variable names — so a partial migration elsewhere (like admin's) recolored whatever hadn't been touched yet, and Radix portal content (which renders under `document.body`, outside any wrapper's scope) never picked up the override at all. The whole app renders on the same dark identity today, so there's one set of values for the whole app and no scope class to remember. `EditionViewRoot` still supplies the `bg-app-gradient` ground and is where the flip (#359) will attach `data-edition-theme="light"`.

src/index.css:32

  • Changing --accent at :root also recolors generic shadcn controls outside the migrated surfaces: Button outline/ghost variants and /terms's ghost back button use hover:bg-accent, which was neutral under the old global value but is now purple. The identity spec still says landing/auth/groups/settings keep the old skin, so this violates the zero-visual-change claim and mixes the edition role with the old global meaning. Keep a separate scope/token or update those consumers and the contract before globalizing it.
    --accent: 271.5 81.3% 55.9%; /* purple-600 */
  • Files reviewed: 15/15 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread src/index.css Outdated
Comment thread src/index.css Outdated
Comment thread src/pages/admin/ArtistsManagement/ArchiveArtistDialog.tsx Outdated
Comment thread docs/design/edition-color-vocabulary.md Outdated
EditionViewRoot's only remaining job was bg-app-gradient — the role
tokens live on :root now, so admin doesn't need the wrapper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01546kmFCrpafJ2ykLQKjYvb

Copilot AI left a comment

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.

🟡 Changes recommended

Two unresolved moderate issues in src/index.css affect dialog contrast and future theme selection.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (6)

Previously missed (2) — in code that hasn't changed since the last review.

src/index.css:10

  • Moving --foreground to :root makes it white for every portal, but DialogContent and AlertDialogContent still render bg-background, whose root value remains white (src/components/ui/dialog.tsx:39). Their inherited titles/body text can therefore become white on white, so this is not a zero-visual-change migration for dialogs. Keep these overrides scoped or give the shared portal primitives an explicitly compatible foreground/background before globalizing the tokens.
    --foreground: 0 0% 100%; /* text-white */

src/index.css:118

  • EditionViewRoot renders the future data-edition-theme attribute on its wrapper <div>, but :root[...] matches only the document root (<html>). When #359 adds the attribute to EditionViewRoot as documented in EditionViewRoot.tsx:7, this block will never match and the light palette will not apply. Keep the selector on .edition-view or move the attribute to document.documentElement consistently.
  :root[data-edition-theme="light"] {

src/index.css:33

  • --accent-foreground is pure white, but these five migrated Add/Create buttons did not previously use text-white; Button's default variant supplied text-primary-foreground (210 40% 98%). Adding text-accent-foreground therefore changes their label color instead of preserving it, contrary to the zero-visual-change claim. Keep text-primary-foreground at these call sites or choose a token with the former value.
    --accent-foreground: 0 0% 100%;

src/index.css:16

  • These popover values now apply to every Radix popover/dropdown portal because those contents render under document.body and consume bg-popover text-popover-foreground (for example src/components/ui/popover.tsx:14-20). Before this change the global values were white/dark; they are now gray-800/purple-100, so portal content changes visually despite the PR's stated portal exception and zero-visual-change goal. Keep the edition values scoped or explicitly opt only the intended portals into them.
    --popover: 215 27.9% 16.9%; /* gray-800 */
    --popover-foreground: 268.7 100% 95.5%; /* purple-100 */

src/pages/admin/ArtistsManagement/ArchiveArtistDialog.tsx:52

  • text-destructive-foreground is not equivalent to the replaced text-white: --destructive-foreground is 210 40% 98% (#f1f5f9), while the old class is pure white. This changes the hover text color and breaks the stated zero-visual-change guarantee; use a token whose current value is white or deliberately update the destructive foreground token.
      className="border-red-400 text-red-400 hover:bg-red-400 hover:text-destructive-foreground"

src/routes/admin.tsx:80

  • The PR description says the admin layout is scoped with EditionViewRoot, but both the loading branch and the main branch in this file still return plain div roots (the main one is at lines 88-89). That means admin will not receive the edition-view root where the planned data-edition-theme marker is attached, so the future theme flip will skip this surface. Wrap both branches with EditionViewRoot or apply the same scope/data-theme contract directly.
        <div className="text-foreground text-xl">Loading...</div>
  • Files reviewed: 15/15 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread docs/design/edition-color-vocabulary.md Outdated
…:root token migration

The AuthDialog, toast notifications, and admin Artists table (Bulk Editor
and generic Table primitives) render on white backgrounds but were
picking up the dark edition-view identity's now-global muted-foreground/
foreground values, washing out text, placeholders, and the input focus
ring. Add explicit gray/black overrides at these light-surface call
sites and shared table defaults, without reverting the :root migration.

Also removes the now-vestigial EditionViewRoot wrapper (it had shrunk to
a single div once its token-scoping job moved to :root) and the stale
CSS comment block in index.css.

Copilot AI left a comment

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.

🟡 Changes recommended

Global token changes cause critical light-surface styling regressions, with additional tokenization and documentation issues unresolved.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (8)

Previously missed (1) — in code that hasn't changed since the last review.

src/index.css:32

  • The root token migration still leaves src/pages/admin/festivals/FestivalLogoDialog.tsx:178 on bg-purple-600 hover:bg-purple-700, so the admin Upload Logo CTA is not tokenized and will diverge when --accent/--accent-hover changes. Migrate this remaining admin CTA as well to satisfy the stated admin color-site scope.
    --accent: 271.5 81.3% 55.9%; /* purple-600 */

src/components/ui/table.tsx:76

  • These shared table primitives are being changed from the semantic text-muted-foreground (and inherited cell text) to fixed text-gray-* colors. That bypasses the role tokens introduced here, so table headers/captions/cells will ignore the planned theme flip; the admin-specific neutral override should be applied at the call site instead of changing the shared primitive.
      "h-12 px-4 text-left align-middle font-medium text-gray-500 [&:has([role=checkbox])]:pr-0",

src/components/ui/toaster.tsx:18

  • This only changes the toast root's inherited text color, but ToastClose still explicitly uses text-foreground/50 and hover:text-foreground (src/components/ui/toast.tsx:78). With the new global foreground set to white and the default toast background still bg-background (white), the close control remains white on white and is effectively invisible. Make the close control use the toast's default text color while preserving destructive-toast styling.
          <Toast key={id} className="text-gray-900" {...props}>

src/components/ui/toaster.tsx:24

  • These overrides are unconditional, so they replace the variant colors on destructive toasts. For example, useAddAdminMutation emits variant: "destructive"; text-gray-900 then overrides text-destructive-foreground, and the description's text-gray-500 overrides the inherited destructive color, producing dark text on the red toast. Apply the gray overrides only for the default variant and leave destructive toasts on their variant colors.
          <Toast key={id} className="text-gray-900" {...props}>
            <div className="grid gap-1">
              {title && <ToastTitle>{title}</ToastTitle>}
              {description && (
                <ToastDescription className="text-gray-500">
                  {description}
                </ToastDescription>

src/index.css:25

  • Making --muted-foreground purple-200 global also recolors unchanged admin helper and empty-state text on white cards. For example, FestivalManagementTable and StagesTable still use text-muted-foreground, so their messages become low-contrast purple on white instead of the previous neutral value. Keep the edition value scoped or provide a light-surface/admin override before globalizing it.
    --muted-foreground: 268.6 100% 91.8%; /* purple-200 */

src/index.css:40

  • Moving --border from the old light value to :root recolors every generic border-border consumer, not only the migrated admin literals. Card always renders a border, and admin cards such as FestivalManagementSection use <Card> without a border override, so their outlines change from the previous gray to purple-400/30, contradicting the claimed zero visual change. Keep the role override scoped or preserve the default border outside the intended surfaces.
    --border: 270 95.2% 75.3% / 0.3; /* border-purple-400/30 */

src/index.css:32

  • --accent is also moved to :root with purple-600, but the shared Button primitive's outline and ghost variants use hover:bg-accent/hover:text-accent-foreground (src/components/ui/button.tsx:16-19). Every unconverted admin action button therefore changes from the old neutral hover to purple—for example the table's ghost edit/delete buttons—so this is not zero visual change. Keep this token scoped or update those variants/surfaces as part of the migration.
    --accent: 271.5 81.3% 55.9%; /* purple-600 */

src/pages/admin/ArtistsManagement/ArchiveArtistDialog.tsx:52

  • This replacement is not value-equivalent to the old hover:text-white: --destructive-foreground still resolves to 210 40% 98% (slate-50, approximately #f8fafc), not 0 0% 100%. Either set the role's foreground value to white for this palette or retain the original class if zero visual change is required.
      className="border-red-400 text-red-400 hover:bg-red-400 hover:text-destructive-foreground"
  • Files reviewed: 24/24 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread docs/design/edition-color-vocabulary.md Outdated
Comment thread src/index.css
…l grays

Introduces surface-foreground/surface-muted-foreground/surface-border
tokens for white-background surfaces (dialogs, toasts, admin tables),
replacing the hardcoded gray-900/gray-500/gray-300 classes.

Copilot AI left a comment

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.

🔵 Needs a closer look

Two moderate findings remain involving table borders and low-contrast muted text on white surfaces.

Review details

Suppressed comments (5)

Previously missed (2) — in code that hasn't changed since the last review.

src/components/ui/table.tsx:76

  • This updates table text but leaves the table border path on the generic global --border token: TableRow still supplies only border-b, and the base layer applies border-border. With the new root value this makes the white admin tables use the purple identity border instead of the newly introduced paper-border; the other admin tables do not have the analytics-specific border overrides. Apply the paper border to the shared admin table styling (or to each white table surface).
      "h-12 px-4 text-left align-middle font-medium text-paper-muted-foreground [&:has([role=checkbox])]:pr-0",

src/index.css:25

  • Making --muted-foreground the edition purple-200 value globally leaves unchanged descriptions and placeholders on white paper surfaces with very low contrast. For example, admin dialog helper text and Textarea placeholders still use text-muted-foreground (FestivalDialog.tsx:196, SetFormDialog.tsx:299), while CardDescription retains the same default. Migrate those light-surface consumers to paper-muted-foreground or keep the edition value scoped.
    --muted-foreground: 268.6 100% 91.8%; /* purple-200 */

src/components/ui/dialog.tsx:39

  • Although DialogContent now establishes a paper foreground, the shared Textarea still sets placeholder:text-muted-foreground (src/components/ui/textarea.tsx:12). Multiline fields in the admin/group dialogs therefore show pale purple placeholder text on the white dialog; Input was updated but Textarea was not. Give the textarea a paper placeholder token for these white surfaces.
        "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-paper-border bg-paper-background p-6 text-paper-foreground shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",

src/components/ui/toast.tsx:30

  • The root renders both the Radix Toaster and the Sonner toaster, and useToast uses this Radix variant. Its default still uses the generic border bg-background, so it does not receive the new neutral paper-border/paper-background roles (and currently keeps the global purple border). Use the paper roles here as well.
        default: "border bg-background text-paper-foreground",

src/index.css:10

  • Moving --foreground to :root makes every remaining bg-background surface inherit white text while --background is still white. This leaves existing light UI such as the default Alert (bg-background text-foreground), AlertDialogContent/outline cancel, outline badges in admin tables, and the Radix toast close control (text-foreground/50) effectively white-on-white; the legal routes also inherit this body color over from-background. Migrate these consumers to the paper roles or retain a light-surface override before applying the edition foreground globally.
    --foreground: 0 0% 100%; /* text-white */
  • Files reviewed: 29/29 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Comment thread docs/design/edition-color-vocabulary.md Outdated
Comment thread src/components/AuthDialog/AuthDialog.tsx
Comment thread src/components/AuthDialog/EmailStep.tsx Outdated
DialogTitle/DialogDescription in AuthDialog and the Input override in
EmailStep duplicated styling the Dialog/Input primitives already apply.
Also drops the stale "(new)" marker from the accent-hover doc row.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01546kmFCrpafJ2ykLQKjYvb

Copilot AI left a comment

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.

🟡 Changes recommended

Four moderate styling issues remain in input focus, table borders, muted text contrast, and Link Wizard badges.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (6)

Previously missed (2) — in code that hasn't changed since the last review.

src/components/ui/table.tsx:76

  • The new paper-border token is not used by this shared table. TableHeader/TableRow still derive their borders from global border-border, and BulkEditorTable wraps the table with border, so white admin tables retain the translucent purple --border rather than the neutral paper border introduced for admin tables. Apply the paper border to the white-table wrapper/rows while preserving the explicit identity borders in analytics.
      "h-12 px-4 text-left align-middle font-medium text-paper-muted-foreground [&:has([role=checkbox])]:pr-0",

src/pages/admin/festivals/LinkWizard/LinkWizardTable.tsx:60

  • The selected-row token change does not account for the outline badges rendered in this same white admin table. Badge's outline variant still sets text-foreground, which is now globally white, so the Spotify and SoundCloud labels below render white-on-white and disappear. Give these badges the paper foreground (or provide a white-table-specific outline variant).
              className={cn(artist.id === currentArtistId && "bg-accent/20")}

src/components/ui/toast.tsx:30

  • The Radix toast is one of the white chrome surfaces described by this PR, but its default variant still uses bg-background and the global border. Under the new identity those roles are not the paper background/border, so the toast only happens to be white today and retains the purple identity border. Use the paper background and border here, as the Sonner wrapper already does.
        default: "border bg-background text-paper-foreground",

src/components/ui/toast.tsx:30

  • Changing the default toast text to paper colors leaves ToastClose below on text-foreground/50 and hover:text-foreground. With the root foreground white and the default white toast, the close icon is white-on-white when hover or focus reveals it, so the dismiss control is not perceivable. Switch the default close colors to paper foreground while preserving the destructive overrides.
        default: "border bg-background text-paper-foreground",

src/index.css:10

  • --foreground is now white globally while --background remains white, but several light-surface primitives still consume these global roles. For example, the default Alert/AlertDialogContent use bg-background with text-foreground or inherited title text, and the default active TabsTrigger uses the same pair; admin schedule-import alerts/confirmations and ImageEditDialog tabs therefore become white-on-white. The root-level legal pages and AppFooter have the same base mismatch. Migrate the remaining light surfaces to the paper roles before making this identity global.
    --foreground: 0 0% 100%; /* text-white */

src/index.css:45

  • The new global accent roles are used by the other admin primary actions in this PR, but FestivalLogoDialog still uses bg-purple-600 hover:bg-purple-700 for Upload Logo. Once the accent role changes (the purpose of this migration/theme flip), that admin CTA will be the remaining hardcoded color and diverge from the rest; migrate it to bg-accent text-accent-foreground hover:bg-accent-hover.
    --accent: 271.5 81.3% 55.9%; /* purple-600 */
  • Files reviewed: 27/27 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread src/components/ui/input.tsx Outdated
Comment thread src/index.css
Badge outline variant and the Link Wizard's stage/time/co-performer text
used text-foreground/muted-foreground, which are now white/pale-purple
globally and invisible against the white/slate-50 admin chrome.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01546kmFCrpafJ2ykLQKjYvb
…text

Login email input inherited the purple edition ring; CardDescription and
Textarea inherited the light-purple muted-foreground on white surfaces.
Add a paper-ring token and use paper-muted-foreground for both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01546kmFCrpafJ2ykLQKjYvb
Comment thread src/components/ui/badge.tsx
Comment thread src/components/ui/toast.tsx Outdated
Consistent with the paper-* token pairing already used for the
toast/dialog foreground and border on light chrome.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01546kmFCrpafJ2ykLQKjYvb

Copilot AI left a comment

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.

🟡 Changes recommended

Unresolved findings include a critical white-on-white alert/dialog regression and moderate input ring, toast close-button, and badge test issues.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (4)

src/components/ui/table.tsx:76

  • The paper migration only changes table text; TableRow still has a bare border-b, which resolves through the global purple --border. Since the default table consumers are admin tables and several sit on white cards, their separators remain purple-alpha instead of using the new neutral --paper-border role. Apply a paper border for white tables (or expose a light-table variant), while retaining the explicit dark row colors used by analytics.
      "h-12 px-4 text-left align-middle font-medium text-paper-muted-foreground [&:has([role=checkbox])]:pr-0",

src/index.css:25

  • This makes the light purple muted-foreground value global, but several white-surface consumers still use it directly: CardDescription in src/routes/admin/admins.tsx, remaining admin descriptions, Textarea placeholders, and MultiSelect placeholders (the cookie banner is another global example). Those now render near-white text on white surfaces because only a subset of primitives was migrated to paper-muted-foreground. Migrate all white-surface consumers to the paper role, or keep the identity value scoped.
    --muted-foreground: 268.6 100% 91.8%; /* purple-200 */

src/index.css:47

  • The new accent/accent-hover roles are used by the other migrated admin CTAs, but the upload action in FestivalLogoDialog still hardcodes bg-purple-600 hover:bg-purple-700 (src/pages/admin/festivals/FestivalLogoDialog.tsx:175-179). That admin action will diverge from the role-token palette as soon as the accent changes; migrate it to bg-accent text-accent-foreground hover:bg-accent-hover.

    --accent: 271.5 81.3% 55.9%; /* purple-600 */
    --accent-foreground: 0 0% 100%;

tailwind.config.ts:84

  • The new accent-hover role is used for the other migrated admin CTAs, but src/pages/admin/festivals/FestivalLogoDialog.tsx:178 still uses bg-purple-600 hover:bg-purple-700. That button will bypass the shared accent token and will not follow the same palette/theme behavior as the surrounding admin actions. Migrate this remaining admin CTA to the accent roles as well.
  • Files reviewed: 34/34 changed files
  • Comments generated: 4
  • Review effort level: Lite

Comment thread src/components/ui/badge.tsx
Comment thread src/components/ui/input.tsx Outdated
Comment thread src/components/ui/toast.tsx Outdated
Comment thread src/index.css
@chiptus
chiptus merged commit ddfa3eb into main Aug 23, 2026
9 checks passed
@chiptus
chiptus deleted the claude/implement-367-zrn4kp branch August 23, 2026 18:34

Copilot AI left a comment

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.

🟡 Changes recommended

Four unresolved light-surface readability and focus-state issues remain.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (6)

src/components/ui/table.tsx:76

  • The table migration changes cell text but leaves TableRow below with only border-b. Since the global * { @apply border-border; } now resolves to the purple translucent identity border, ordinary admin table separators remain purple on the white table instead of using the new paper-border role. Add the paper border to the row base (and handle the white table wrapper borders consistently).
      "h-12 px-4 text-left align-middle font-medium text-paper-muted-foreground [&:has([role=checkbox])]:pr-0",

src/components/ui/textarea.tsx:12

  • Unlike Input, this change only recolors the placeholder; the textarea value still inherits global text-foreground (white). A standalone admin editor such as FestivalInfoField renders this control in EditContainer with a light bg-muted/50, so entered descriptions are white on a light background. Give the shared textarea an explicit paper foreground for its value.
          "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-paper-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",

src/components/ui/toast.tsx:30

  • The default Radix toast now uses a paper background but still has only a bare border. Because src/index.css applies border-border globally and --border is now the translucent purple identity border, these white toasts retain a purple border instead of the new neutral paper-border role. Add border-paper-border to this variant.
        default: "border bg-paper-background text-paper-foreground",

src/index.css:10

  • Making --foreground white at :root also affects the unchanged default Alert and AlertDialog primitives. Alert still renders bg-background text-foreground (white on white), while portalled AlertDialogContent has a white bg-background, titles that inherit the white body color, and descriptions using the pale global --muted-foreground; the admin import warnings and confirmation dialogs are therefore unreadable. Update those primitives to the paper-* roles before making this palette global.
    --foreground: 0 0% 100%; /* text-white */

src/index.css:25

  • Changing --muted-foreground to the purple-200 identity value globally leaves explicit admin uses on white surfaces with very low contrast. For example, BulkEditorTableRow still renders its created-at cell with text-muted-foreground (src/pages/admin/ArtistsManagement/components/BulkEditorTableRow.tsx:89), which overrides the new paper color on the white artists table; the table empty states have the same problem. Replace these white-surface admin overrides with text-paper-muted-foreground rather than relying on the global muted role.
    --muted-foreground: 268.6 100% 91.8%; /* purple-200 */

src/index.css:54

  • Although --paper-border is introduced above, the admin table shells and TableHeader/TableRow still use generic border/border-b. After this global change those resolve to --border (purple-400/30), so white admin tables continue to use the dark-identity border instead of the neutral paper border intended by this migration. Update the shared table and white-surface border classes to border-paper-border.
    --border: 270 95.2% 75.3% / 0.3; /* border-purple-400/30 */
  • Files reviewed: 36/36 changed files
  • Comments generated: 4
  • Review effort level: Lite

<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-paper-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
variants: {
variant: {
default: "border bg-background text-foreground",
default: "border bg-paper-background text-paper-foreground",
Comment thread src/index.css
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--foreground: 0 0% 100%; /* text-white */
<MarkdownText content={value} className="prose-sm" />
) : (
<span className="text-muted-foreground italic">
<span className="text-paper-muted-foreground italic">
Copilot AI review requested due to automatic review settings August 23, 2026 18:35

Copilot AI left a comment

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.

🟡 Changes recommended

Four unresolved moderate border-token issues remain in paper-surface components.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (7)

Previously missed (1) — in code that hasn't changed since the last review.

src/components/ui/table.tsx:76

  • The new paper-border token is not applied to the table's own borders. TableRow still emits bare border-b, and the admin table wrappers still emit bare border, so white tables continue to use the global translucent purple --border instead of the neutral paper border. Apply the paper border to the shared row/outer-table styles while preserving analytics' explicit white hairlines.
      "h-12 px-4 text-left align-middle font-medium text-paper-muted-foreground [&:has([role=checkbox])]:pr-0",

docs/design/edition-identity-spec.md:15

  • The scope/token contract now says the document root is the integration point, and this PR deletes the only EditionViewRoot/.edition-view wrapper, but the implementation notes below still require font families to be wired at an edition-view root. There is no such source element left, so that instruction is stale and will misdirect the typography follow-up; update it to the actual route/document-root hook or retain a wrapper.
- Token values are CSS variables on `:root` (#367). Dark values are the default; light values apply under an explicit `data-edition-theme="light"` attribute on the document root.

src/components/ui/sonner.tsx:17

  • The default Sonner toast is now white, but its cancel button still uses text-muted-foreground. With the new global value, a cancel action is rendered in purple-200 on the light bg-muted fill, leaving it low-contrast even though the toast title and description were migrated to paper roles. Keep the fill if desired, but switch the cancel text to text-paper-foreground (or another paper-compatible foreground).
            "group toast group-[.toaster]:bg-paper-background group-[.toaster]:text-paper-foreground group-[.toaster]:border-paper-border group-[.toaster]:shadow-lg",
          description: "group-[.toast]:text-paper-muted-foreground",

src/components/ui/textarea.tsx:12

  • Although Input now uses ring-paper, Textarea still uses the global ring-ring. Focusing a textarea in an admin white card/dialog therefore shows the purple identity ring instead of the neutral paper treatment this PR introduces for white inputs. Use focus-visible:ring-paper-ring here.
          "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-paper-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",

src/index.css:10

  • Making --foreground white globally also changes body (which applies bg-background text-foreground) and existing text-foreground consumers outside the dark-gradient surfaces. For example, /privacy, /terms, and /cookies still use a white bg-background, while DeleteGroupDialog explicitly uses text-foreground on its white dialog, so these become white-on-white. Migrate those white-surface consumers to the paper-* roles before globalizing this token, or keep the identity scope until they are migrated.
    --foreground: 0 0% 100%; /* text-white */

src/index.css:25

  • Globalizing --muted-foreground to the purple-200 identity value leaves ordinary text-muted-foreground content on white surfaces with very low contrast. For example, LinkWizardStep/CandidateCard render inside the default white Card, and CookiePreferencesDialog has white DialogContent, but those consumers still use this role. Migrate all white-surface muted text to text-paper-muted-foreground (or provide a scoped paper role) rather than leaving these admin/auth surfaces on the purple value.
    --muted-foreground: 268.6 100% 91.8%; /* purple-200 */

src/pages/admin/ArtistsManagement/BulkEditor/TextareaCell.tsx:77

  • When value is present this branch renders MarkdownText, whose prose paragraphs/headings use text-foreground; after the root foreground was changed to white, populated descriptions in the white Artists table render white-on-white. The placeholder change only fixes empty cells; give this admin rendering paper-foreground prose styles without changing the dark EditionView MarkdownText defaults.
        <span className="text-paper-muted-foreground italic">
  • Files reviewed: 36/36 changed files
  • Comments generated: 3
  • Review effort level: Lite

ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-paper-background text-paper-foreground p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
variants: {
variant: {
default: "bg-background text-foreground",
default: "bg-paper-background text-paper-foreground",
variants: {
variant: {
default: "border bg-background text-foreground",
default: "border bg-paper-background text-paper-foreground",
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.

3 participants