Two convoy seeds opened as follow-ups to the 2026-06-04 design pass (#116 corner-border-light → #117 site-wide sweep → #118 card vibrancy reduction). Both were called out in #117's PR body as deferred and are now formally tracked. ## unify-glass-panel-surfaces Migrates remaining panel-shaped surfaces to the gradient-border corner-light treatment so the app shares one surface vocabulary. The audit's key insight: `<GlassSurface>` (`components/ui/GlassSurface.js`) predates the corner-light pattern. Because `<Modal>`, `<StatCard>`, and the landing-page feature/collection cards all delegate to it, upgrading the primitive cascades to ~10 visible surfaces at once. 7 briefs, multitask-parallel after Brief 1 lands: 1. `<GlassSurface>` primitive upgrade — BLOCKING for 3, 4 2. Auth form cards (login.js, signup.js) 3. Floating popovers (mobile drawer, sidebar profile dropdown, UserMenu dropdown) 4. BulkSelectionToolbar (currently `bg-white border-gray-200` — invisible in dark mode) 5. `.card`-class consumers (4 pages); decision to ratify whether to retire `.card` entirely or keep as documented opaque fallback 6. Landing nav bar — wrong pattern; should use existing `.page-header-glass` class 7. `forbidden-bespoke-glass-surface` CI grep gate — prevents regression after the migration ships ## cleanup-card-item-list-and-share-modal-palette Targeted palette cleanup for two files whose interiors weren't addressed in #117: 1. `CardItem.js` list-mode (L183–284) — entirely hardcoded Tailwind palette (`bg-purple-50`, `border-gray-200`, `text-gray-{500-900}`, `bg-blue-100 text-blue-800` etc.); unreadable / off-brand in dark mode. 2. `ShareModal.js` interior rows — purple avatar circles, gray-50 permission row (invisible in dark mode), blue-600 Copy-link button, gray text labels. Token-only swap. 2 parallel briefs, no architect / IA / UX needed (no design decisions — palette to design tokens). ## Sequencing note The two convoys are independent and can run in parallel. The audit agent's recommended sequencing (Brief 1 of `unify-glass-panel-surfaces` first) is encoded in the multitask `slice_dependencies` blocks. Co-authored-by: Cursor <cursoragent@cursor.com>
7.7 KiB
| name | classification | success_metric | skip | status | created | depends_on | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| cleanup-card-item-list-and-share-modal-palette | feature | No hardcoded Tailwind palette classes (`bg-purple-*`, `bg-blue-*`, `bg-gray-*` 100-900 range, `text-gray-{500,600,700,900}`, `bg-white`, `border-gray-200`, etc.) remain in the interior of `components/CardItem.js` list-mode or `components/ShareModal.js`. Both render correctly in dark theme. Verified by visual diff and a targeted lint sweep. |
|
open | 2026-06-04 |
|
Convoy: cleanup-card-item-list-and-share-modal-palette
Targeted palette cleanup. Parallel companion to
unify-glass-panel-surfaces — that convoy migrates panel surfaces;
this one cleans up the interior content (rows, badges, text,
buttons) of two specific files whose interiors were not addressed
by PR #117 because they're not panel surfaces — they're nested
content inside surfaces that were already on the system.
Why
Two files left over after the 2026-06-04 design sweep:
-
components/CardItem.jslist-mode (L183–284) — the list-view layout (whenviewMode === 'list') is entirely hardcoded Tailwind palette. The grid-mode (L290+) was already migrated; list-mode wasn't.border-gray-200,bg-purple-50,text-gray-900,text-gray-600,text-green-600,bg-blue-100 text-blue-800— none of these have dark-mode variants. In dark theme, the list view renders unreadable (light text on light backgrounds) or off-brand (purple/blue badges in an ember palette app). -
components/ShareModal.jsinterior — the modal SURFACE is correct (delegates to<Modal>→<GlassSurface>), and the user-search dropdown + email-invite card were updated in PR #117. But the interior rows still have:bg-purple-600avatar circles for current user (L194, L240).bg-gray-50current-user permission row (L238) — invisible in dark mode.bg-gray-100 roundedpermission badge (L272) — light-only.bg-gray-50 border-gray-300 text-gray-600share-link input (L287) — invisible in dark mode.bg-blue-600 hover:bg-blue-700Copy-link button (L294) — off-palette (should be ember).text-gray-{500,700,900}text colors throughout — light-only.
Note ShareModal is the primary collaboration entry point; the permission rows and Copy-link button are visited every time a user invites a collaborator.
Both files are token-only swaps. No structural changes, no component swaps, no glass-panel migration.
Scope
In scope
Brief 1 — CardItem.js list-mode token sweep
Replace every hardcoded color in lines ~183–284 with the
appropriate var(--*) token via inline style. Categories:
- Background fills:
bg-purple-50(selected row),bg-white→var(--bg-secondary)orvar(--bg-tertiary)per role; selected state usesvar(--accent-ember)+ low alpha as background. - Borders:
border-gray-200/border-gray-300→var(--border). Selected state borderborder-purple-600→var(--accent-ember). - Text:
text-gray-900→var(--text-primary),text-gray-600/text-gray-500→var(--text-secondary),text-green-600(positive value indicators) →var(--accent-flame)or keep#16a34aif semantic green matters more than brand. - Badges (
bg-blue-100 text-blue-800etc.): convert tovar(--bg-tertiary)+var(--text-primary)orvar(--accent-ember)per badge role (game, rarity, type). - Buttons / icons:
text-purple-600(selection indicator) →var(--accent-ember).
Acceptance: visually inspect CardItem list-mode in BOTH themes.
All text must be legible, all interactive states (hover, selected)
must have a visible delta against the row background.
Files: components/CardItem.js.
Risk: LOW — purely cosmetic token swaps; no layout changes.
Brief 2 — ShareModal.js interior token sweep
Lines roughly 230–310. Targets:
- Avatar circles (L194, L240):
bg-purple-600→linear-gradient(135deg, var(--accent-ember), var(--accent-flame))(matches the UserMenu avatar gradient style fromcomponents/ui/TopSearchBar.js). - Current-user row container (L238):
bg-gray-50 rounded-lg→var(--bg-secondary)+rounded-xl, orvar(--bg-tertiary)for slightly more contrast. - Permission badge (L272):
bg-gray-100 rounded→var(--bg-tertiary)+rounded-xl+var(--text-secondary). - Share-link readonly input (L283–288):
bg-gray-50 border-gray-300 text-gray-600→ tokenize againstvar(--bg-secondary),var(--border),var(--text-primary); alternatively use the.input-fieldclass (already inglobals.css). - Copy-link button (L290–298):
bg-blue-600 text-white hover:bg-blue-700→ replace with the<Button variant="primary">primitive. The success state currently isbg-green-100 text-green-800 border border-green-200; keep the semantic green but use a non-Tailwind path:style={{ backgroundColor: 'var(--bg-secondary)', color: 'var(--accent-flame)' }}+ an ember border, or commit to a custom.btn-success-flashutility. - Text labels (L201, L222, L231, L246, L266, L267): all
text-gray-{500,700,900}→ tokens.
Acceptance: ShareModal opens in dark theme and every row is legible; Copy-link button is on the ember palette; permission badges read as ember-system, not Tailwind-default-gray.
Files: components/ShareModal.js.
Risk: LOW.
Out of scope
- Any change to the modal surface (handled by
unify-glass-panel-surfacesBrief 1, which upgrades<GlassSurface>and therefore<Modal>). - Any structural change (new component, new layout).
- The user-search-dropdown + email-invite-card areas of
ShareModal.js— those were already cleaned up in PR #117.
Roles invoked
role-implementer— Briefs 1 and 2 are parallel-safe; can run independently.role-design-system-auditor— single sign-off after both briefs land (token-only sweep; design audit is a sanity check).role-reviewer— one review per brief.
(No architect needed — token swaps with no design decisions. No IA, no UX — content/structure unchanged. The Design-system auditor catches any palette regressions.)
Todos
- Brief 1 —
CardItem.jslist-mode token sweep - Brief 2 —
ShareModal.jsinterior token sweep - Design-system auditor sign-off
- Post-PR review per brief
Acceptance criteria
rg -e "bg-(purple|blue|gray|red)-[0-9]" -e "text-(purple|blue|gray|red)-[0-9]" -e "border-gray-[0-9]"overcomponents/CardItem.jsandcomponents/ShareModal.jsreturns no matches (excluding lines that are deliberately semantic — e.g.bg-red-500on a destructive Delete button, which architect ratifies per-line during review).- Both files render correctly in both themes — visible text, visible interactive states.
- Build + lint + 113/113 vitest pass.
CI impact
| Workflow / job | Behavior |
|---|---|
preview-smoke.yml |
Fires. |
visual-diff.yml |
Fires — expected diff in CardItem list-view and ShareModal rows. Baseline refresh required. |
lint |
Fires. |
test: (vitest) |
Fires. |
Known constraints
CardItemis in many places —pages/cards.js(grid default),pages/my-cards.js,pages/collection/[id].js, etc. Brief 1 must NOT touch the grid-mode (L290+), only the list-mode branch.
Multitask dispatch
slice_dependencies:
- brief: 1
depends_on: []
files:
- components/CardItem.js
- brief: 2
depends_on: []
files:
- components/ShareModal.js
Briefs 1 and 2 are fully parallel — disjoint files, no shared dependencies.