deckhearth/.convoys/cleanup-card-item-list-and-share-modal-palette.md
Randall Stillwell b195395b82 docs(convoys): seed unify-glass-panel-surfaces + cleanup-card-item-list-and-share-modal-palette
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>
2026-06-04 14:06:53 -05:00

7.7 KiB
Raw Blame History

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.
ia
ux
arch
open 2026-06-04
design-sweep-pass

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:

  1. components/CardItem.js list-mode (L183284) — the list-view layout (when viewMode === '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).

  2. components/ShareModal.js interior — 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-600 avatar circles for current user (L194, L240).
    • bg-gray-50 current-user permission row (L238) — invisible in dark mode.
    • bg-gray-100 rounded permission badge (L272) — light-only.
    • bg-gray-50 border-gray-300 text-gray-600 share-link input (L287) — invisible in dark mode.
    • bg-blue-600 hover:bg-blue-700 Copy-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 ~183284 with the appropriate var(--*) token via inline style. Categories:

  • Background fills: bg-purple-50 (selected row), bg-whitevar(--bg-secondary) or var(--bg-tertiary) per role; selected state uses var(--accent-ember) + low alpha as background.
  • Borders: border-gray-200 / border-gray-300var(--border). Selected state border border-purple-600var(--accent-ember).
  • Text: text-gray-900var(--text-primary), text-gray-600 / text-gray-500var(--text-secondary), text-green-600 (positive value indicators) → var(--accent-flame) or keep #16a34a if semantic green matters more than brand.
  • Badges (bg-blue-100 text-blue-800 etc.): convert to var(--bg-tertiary) + var(--text-primary) or var(--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 230310. Targets:

  • Avatar circles (L194, L240): bg-purple-600linear-gradient(135deg, var(--accent-ember), var(--accent-flame)) (matches the UserMenu avatar gradient style from components/ui/TopSearchBar.js).
  • Current-user row container (L238): bg-gray-50 rounded-lgvar(--bg-secondary) + rounded-xl, or var(--bg-tertiary) for slightly more contrast.
  • Permission badge (L272): bg-gray-100 roundedvar(--bg-tertiary) + rounded-xl + var(--text-secondary).
  • Share-link readonly input (L283288): bg-gray-50 border-gray-300 text-gray-600 → tokenize against var(--bg-secondary), var(--border), var(--text-primary); alternatively use the .input-field class (already in globals.css).
  • Copy-link button (L290298): bg-blue-600 text-white hover:bg-blue-700 → replace with the <Button variant="primary"> primitive. The success state currently is bg-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-flash utility.
  • 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-surfaces Brief 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

  1. role-implementer — Briefs 1 and 2 are parallel-safe; can run independently.
  2. role-design-system-auditor — single sign-off after both briefs land (token-only sweep; design audit is a sanity check).
  3. 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.js list-mode token sweep
  • Brief 2 — ShareModal.js interior token sweep
  • Design-system auditor sign-off
  • Post-PR review per brief

Acceptance criteria

  1. rg -e "bg-(purple|blue|gray|red)-[0-9]" -e "text-(purple|blue|gray|red)-[0-9]" -e "border-gray-[0-9]" over components/CardItem.js and components/ShareModal.js returns no matches (excluding lines that are deliberately semantic — e.g. bg-red-500 on a destructive Delete button, which architect ratifies per-line during review).
  2. Both files render correctly in both themes — visible text, visible interactive states.
  3. 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

  • CardItem is in many placespages/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.