Delete directory 'docs/superpowers'
Local Build and Deploy / deploy (push) Successful in 1m11s

This commit is contained in:
Simo committed 2026-07-17 21:26:05 +02:00
1 parent f6871807c9
commit e7a6587b7f
14 files changed
-1045

No files matched your search

@@ -1,94 +0,0 @@
# ACL and Import Backend Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Complete ACL management and activate every existing administration import workflow.
**Architecture:** Use the normalized ACL tables as the single authorization source and map emulator ranks to `rank_<id>` roles. Port the proven import core and services from `habbo-next`, expose them through locale-free API routes guarded server-side, and verify DB plus filesystem outputs.
**Tech Stack:** Next.js 16 route handlers, React 19, TypeScript, Prisma/MariaDB, Vitest, Node filesystem and streams.
## Global Constraints
- Work directly in `E:\Users\simol\Desktop\EpicNext-cms`; no worktree or subagents.
- Preserve and never stage the existing `package.json` modification.
- Pull `main` before publication and never force-push.
- Do not copy generated Prisma files.
- Every import API requires `admin.assets.import`; destructive catalog operations also require `admin.catalog.edit`.
- Import success requires database and required filesystem/FurnitureData outputs.
---
### Task 1: Lock ACL and route coverage with failing contracts
**Files:**
- Create: `src/lib/admin/acl-management-contract.test.ts`
- Create: `src/lib/import-backend-contract.test.ts`
- [ ] Assert that permission mutations use `adminAction` with `PERMS.PERMISSIONS_MANAGE`, write normalized ACL tables, and do not write legacy housekeeping permission tables.
- [ ] Assert that every API referenced by `src/app/admin/import/**` exists and contains a server-side `PERMS.ASSETS_IMPORT` guard.
- [ ] Run both tests and verify they fail on the missing management/API implementation.
- [ ] Commit with `test: define acl and import backend contracts`.
### Task 2: Normalize ACL persistence and management
**Files:**
- Modify: `src/actions/permissions.ts`
- Modify: `src/app/admin/permissions/page.tsx`
- Modify: `src/app/admin/permissions/[id]/page.tsx`
- Modify: `src/app/admin/permissions/[id]/rank-edit-client.tsx`
- Use: `src/lib/services/permission-ranks.ts`
- Create: `prisma/migrations/0014_complete_acl_and_import_permissions.sql`
- [ ] Add focused failing tests for rank service and ACL assignment behavior.
- [ ] Replace legacy writes with emulator rank service and normalized ACL assignments.
- [ ] Seed and migrate roles/permissions idempotently, using `Role` and `User` discriminator casing.
- [ ] Invalidate permission cache, update RCON, and log each mutation.
- [ ] Run ACL tests and migration contract tests; commit with `fix: complete acl management`.
### Task 3: Port shared import core and domain services
**Files:**
- Create: `src/lib/services/import/core/*.ts`
- Create: `src/lib/services/{clone-import,clothing-set-import,effect-import,figure-import,furni-import,nitro-assets,pet-import}.ts`
- Modify: `src/lib/services/furni-asset-dirs.ts`
- Modify: `src/lib/services/furni-data.ts`
- Test: matching `*.test.ts` files
- [ ] Port tests first and verify failures from missing modules.
- [ ] Port reference implementations, adapting Prisma model names and EpicNext settings.
- [ ] Preserve Windows absolute-path handling and live Nitro mirroring.
- [ ] Run all import service tests; commit with `feat: add asset import services`.
### Task 4: Add guarded import route handlers
**Files:**
- Create: `src/app/api/admin/import/**/route.ts`
- Create: `src/app/api/nitro-assets/bundled/furniture/[...path]/route.ts`
- [ ] Add badge, clone, clothing, effects, furni, pets, and repair handlers used by the existing clients.
- [ ] Apply server-side API context plus `PERMS.ASSETS_IMPORT` to every handler.
- [ ] Require `PERMS.CATALOG_EDIT` for deletion, repair, resync, and catalog-mutating operations.
- [ ] Run route contract, API authorization, and service tests; commit with `feat: add guarded asset import api`.
### Task 5: Align pages, actions, and permissions
**Files:**
- Modify: `src/app/admin/import/**/page.tsx`
- Modify: `src/actions/import-badges.ts`
- Modify: `src/actions/import-furni.ts`
- Modify: `src/lib/permission-slugs.ts`
- [ ] Make every import page use `PERMS.ASSETS_IMPORT` consistently.
- [ ] Replace stub cleanup/deletion behavior with guarded service calls.
- [ ] Run contract tests and TypeScript; commit with `fix: connect admin import workflows`.
### Task 6: Complete verification and publish
**Files:**
- Verify all committed files; exclude `package.json`.
- [ ] Run `git diff --check origin/main...HEAD`.
- [ ] Run `pnpm test`, `pnpm typecheck`, and `pnpm build`.
- [ ] Confirm `git status --short` contains only ` M package.json`.
- [ ] Fetch `origin/main`, require it to be an ancestor of `HEAD`, and push `main` without force.
@@ -1,43 +0,0 @@
# Admin Events Polls Banners Prefixes Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Port four complete admin modules from habbo-next into EpicNext with safe schema ownership and ACL enforcement.
**Architecture:** Add CMS-owned tables and Prisma models first, then validators/actions, then locale-free admin routes and navigation. Existing safe-action, audit, admin-list, UI primitives, and semantic theme systems are reused.
**Tech Stack:** Next.js 16, Prisma 7, MariaDB SQL migrations, Zod, React Hook Form, Vitest.
## Global Constraints
- Never modify emulator-owned poll tables.
- Preserve the local `package.json` modification.
- Remove `[locale]` routing assumptions.
- Use EpicNext semantic colors and ACL permission constants.
### Task 1: Schema and ACL
- [ ] Add failing migration/schema contract tests for all CMS tables and permission slugs.
- [ ] Add Prisma models and an idempotent numbered migration.
- [ ] Generate Prisma and run schema/migration tests.
- [ ] Commit with `feat: add schema for admin content modules`.
### Task 2: Validators and actions
- [ ] Port event/poll validators and add invalid-input tests.
- [ ] Port events, polls, banners, and prefixes actions using existing safe-action/audit APIs.
- [ ] Run action import contracts, typecheck, and targeted tests.
- [ ] Commit with `feat: add admin content module actions`.
### Task 3: Routes and UI
- [ ] Port the 24 module files without locale routing and add the missing date-time picker primitive.
- [ ] Add route/import contract tests and adapt query/API differences found by typecheck.
- [ ] Add navigation entries and permission visibility.
- [ ] Run targeted tests and typecheck; commit with `feat: add admin content module pages`.
### Task 4: Verification
- [ ] Run Prisma generation, full test suite, typecheck, and production build.
- [ ] Verify migration idempotency and ensure `package.json` is unstaged.
- [ ] Push the verified commits to `origin/main`.
@@ -1,86 +0,0 @@
# Admin Operations Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add complete moderation, logs, analytics, DevOps, and online-user administration verticals.
**Architecture:** Port each reference vertical independently, adapt its data access to EpicNext's Prisma/schema conventions, and enforce ACL at both route and mutation boundaries. Reuse shared admin components and semantic admin theme tokens.
**Tech Stack:** Next.js 16, React 19, TypeScript, Prisma/MariaDB, Vitest, RCON.
## Global Constraints
- Work directly on `main`; no worktree or subagents.
- Preserve and never stage the local `package.json` change.
- Do not copy generated Prisma code.
- Every page/action/API must use its documented ACL permission.
- Missing optional emulator tables render unavailable states instead of crashing the admin shell.
---
### Task 1: Define route, ACL, and theme contracts
**Files:**
- Create: `src/lib/admin-operations-contract.test.ts`
- [ ] Assert all moderation, log, analytics, DevOps, and online routes exist.
- [ ] Assert mutations and APIs contain the matching `PERMS` guard.
- [ ] Assert new sources contain no forbidden public structural theme tokens.
- [ ] Run the contract and confirm it fails because routes are absent.
- [ ] Commit with `test: define admin operations contracts`.
### Task 2: Moderation and calls for help
**Files:**
- Create: `src/actions/moderation.ts`
- Create: `src/app/admin/moderation/**`
- Modify: `src/app/admin/layout.tsx`
- [ ] Port moderation validation tests and confirm failure.
- [ ] Add dashboard, actions, CFH list/detail, and team pages.
- [ ] Adapt user/ban/CFH queries and protect reads/edits with moderation ACL.
- [ ] Log actions and separate RCON failures from database results.
- [ ] Run contract, moderation tests, and typecheck; commit `feat: add admin moderation operations`.
### Task 3: Detailed administration logs
**Files:**
- Create: `src/app/admin/logs/{audit,chat,commands,trades}/**`
- Modify: `src/app/admin/logs/page.tsx`
- [ ] Add failing route/filter contract coverage.
- [ ] Port paginated read-only tables using EpicNext log models or compatible raw queries.
- [ ] Protect every route with `admin.logs.view` and use semantic admin status colors.
- [ ] Run log tests and typecheck; commit `feat: add detailed admin logs`.
### Task 4: Analytics and export
**Files:**
- Create: `src/app/admin/analytics/**`
- Create: `src/app/api/admin/analytics/export/route.ts`
- [ ] Add failing ACL/export contract checks.
- [ ] Port overview, activity, and economy aggregates.
- [ ] Guard reads with `admin.analytics.view` and export with `admin.analytics.export`.
- [ ] Ensure export excludes secrets and fields absent from the visible tables.
- [ ] Run analytics contracts and typecheck; commit `feat: add admin analytics`.
### Task 5: DevOps health and online users
**Files:**
- Create: `src/app/admin/devops/**`
- Create: `src/app/api/admin/devops/health/route.ts`
- Create: `src/app/admin/online/**`
- [ ] Add failing route, redaction, and ACL checks.
- [ ] Port health/errors/online pages and adapt queries to EpicNext models.
- [ ] Redact credentials, connection strings, environment variables, and stack details from API responses.
- [ ] Guard DevOps with `admin.devops.view/edit` and online users with `admin.users.view`.
- [ ] Run contracts and typecheck; commit `feat: add devops and online operations`.
### Task 6: Verify and publish
- [ ] Run `git diff --check origin/main...HEAD`.
- [ ] Run `pnpm test`, `pnpm typecheck`, and `pnpm build`.
- [ ] Confirm only `package.json` remains modified.
- [ ] Fetch `origin/main`, verify it is an ancestor of `HEAD`, and push `main` without force.
@@ -1,170 +0,0 @@
# Admin Theme Isolation Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make every admin page, including all import workflows, readable in light and dark mode without inheriting unsafe public-theme color combinations.
**Architecture:** Generate a dedicated semantic `--admin-*` palette alongside the existing public variables, scope it to the admin layout, and migrate admin UI chrome to those tokens. A source-contract test prevents public structural tokens and unapproved literal palette colors from returning to `/admin`.
**Tech Stack:** Next.js 16, React 19, TypeScript, Tailwind CSS, CSS custom properties, Vitest.
## Global Constraints
- Work directly in `E:\Users\simol\Desktop\EpicNext-cms`; do not create a worktree.
- Preserve and do not stage the existing local `package.json` modification.
- Cover the complete `src/app/admin` tree, including badge, clone, clothing, effects, furni, pets, and repair imports.
- Preserve literal colors that represent editable data or faithful content previews.
- Do not add runtime dependencies.
---
### Task 1: Enforce the admin color boundary
**Files:**
- Modify: `src/lib/admin-theme-source-audit.test.ts`
**Interfaces:**
- Consumes: source files below `src/app/admin`
- Produces: a failing contract when UI chrome uses forbidden public or literal colors
- [ ] **Step 1: Extend the source audit with explicit forbidden patterns and exception paths**
Add checks for structural `--color-background`, `--color-surface`, `--color-text`, `--color-text-muted`, and palette utilities such as `bg-zinc-400`. Exempt the theme editor, favicon editor, user-editable banner/prefix/event/tag/team values, and faithful preview canvases.
- [ ] **Step 2: Verify the test fails for the current admin sources**
Run: `pnpm vitest run src/lib/admin-theme-source-audit.test.ts`
Expected: FAIL listing current public-token and hard-coded-color violations, including import pages.
- [ ] **Step 3: Commit the failing contract**
Run: `git add src/lib/admin-theme-source-audit.test.ts && git commit -m "test: enforce admin theme isolation"`
### Task 2: Generate the semantic admin palette
**Files:**
- Modify: `src/lib/theme-css.ts`
- Modify: `src/components/theme-vars.tsx`
- Modify: `src/components/theme-vars.test.ts`
- Modify: `src/lib/theme-contrast.test.ts`
**Interfaces:**
- Consumes: `ThemePalette`, `readableColor`, and derived semantic foregrounds
- Produces: `--admin-canvas`, `--admin-surface`, `--admin-surface-elevated`, `--admin-text`, `--admin-text-muted`, `--admin-border`, `--admin-accent`, `--admin-accent-foreground`, status, sidebar, input, overlay, and focus variables
- [ ] **Step 1: Add failing assertions for complete light and dark admin tokens**
Assert that generated CSS contains every admin token and that readable foregrounds are derived rather than copied from unsafe public values.
- [ ] **Step 2: Run focused tests and confirm the missing-token failure**
Run: `pnpm vitest run src/components/theme-vars.test.ts src/lib/theme-contrast.test.ts`
Expected: FAIL because the admin palette has not been generated.
- [ ] **Step 3: Generate the admin tokens using existing contrast helpers**
Keep the public palette unchanged. Use stable neutral structural surfaces for each mode, allow the preset primary color to influence `--admin-accent`, and derive its foreground through `readableColor`.
- [ ] **Step 4: Run focused tests**
Run: `pnpm vitest run src/components/theme-vars.test.ts src/lib/theme-contrast.test.ts`
Expected: PASS.
- [ ] **Step 5: Commit**
Run: `git add src/lib/theme-css.ts src/components/theme-vars.tsx src/components/theme-vars.test.ts src/lib/theme-contrast.test.ts && git commit -m "feat: add semantic admin palette"`
### Task 3: Migrate shared admin styling and layout
**Files:**
- Modify: `src/app/globals.css`
- Modify: `src/app/admin/layout.tsx`
**Interfaces:**
- Consumes: the `--admin-*` palette from Task 2
- Produces: admin layout, cards, tables, forms, navigation, dialogs, and focus states independent from public structural colors
- [ ] **Step 1: Scope admin semantic aliases at the admin root**
Apply the admin canvas/text variables at `.admin-page` and replace shared admin CSS references to public background, surface, text, muted text, border, and primary variables with their semantic admin equivalents.
- [ ] **Step 2: Migrate sidebar and header classes in the admin layout**
Use the sidebar, accent, surface, text, muted, and border admin variables; retain no public structural variable in layout chrome.
- [ ] **Step 3: Run the source audit and CSS/theme tests**
Run: `pnpm vitest run src/lib/admin-theme-source-audit.test.ts src/components/theme-vars.test.ts src/lib/theme-contrast.test.ts`
Expected: remaining failures point only to individual pages.
- [ ] **Step 4: Commit**
Run: `git add src/app/globals.css src/app/admin/layout.tsx && git commit -m "fix: isolate shared admin styling"`
### Task 4: Migrate admin pages and import workflows
**Files:**
- Modify: violating files reported by `src/lib/admin-theme-source-audit.test.ts` below `src/app/admin/**`
**Interfaces:**
- Consumes: semantic admin variables and shared admin styles from Task 3
- Produces: zero unapproved source-audit violations across all admin routes
- [ ] **Step 1: Replace structural public variables page by page**
Map background to `--admin-canvas` or `--admin-surface`, text to `--admin-text`, muted text to `--admin-text-muted`, primary UI accents to `--admin-accent`, and status UI to the matching admin status token.
- [ ] **Step 2: Replace hard-coded palette utilities in ordinary admin pages**
Migrate catalog currency accents, offline indicators, alerts, modal overlays, and decorative gradients. Do not alter stored/user-entered color fields.
- [ ] **Step 3: Migrate every import workflow**
Replace status shadows, selection gradients, tooltips, dialog overlays, labels, and borders in badge, clone, clothing, effects, furni, pets, and repair imports. Preserve asset pixels and intentionally neutral preview canvases.
- [ ] **Step 4: Run the source audit until it passes**
Run: `pnpm vitest run src/lib/admin-theme-source-audit.test.ts`
Expected: PASS with no unapproved violations.
- [ ] **Step 5: Commit**
Run: `git add src/app/admin && git commit -m "fix: use semantic colors across admin pages"`
### Task 5: Verify and publish
**Files:**
- Verify all committed files; do not stage `package.json`
**Interfaces:**
- Consumes: Tasks 1-4
- Produces: verified commits on `main`
- [ ] **Step 1: Run formatting and whitespace checks**
Run: `git diff --check origin/main...HEAD`
Expected: no output and exit code 0.
- [ ] **Step 2: Run complete verification**
Run: `pnpm test && pnpm typecheck && pnpm build`
Expected: all tests pass, TypeScript exits 0, and Next.js production build succeeds.
- [ ] **Step 3: Confirm the dirty-file boundary**
Run: `git status --short`
Expected: only ` M package.json`.
- [ ] **Step 4: Synchronize and publish main safely**
Run: `git fetch origin main --prune`, verify `origin/main` is an ancestor of `HEAD`, then run `git push origin main`.
Expected: push succeeds without force.
@@ -1,87 +0,0 @@
# EpicNext Multitheme Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Give every EpicNext preset complete, coherent light and dark palettes while retaining the visitor mode toggle and rebranding the CMS information popup.
**Architecture:** A canonical theme-key contract defines every persisted/runtime color. Presets provide complete `light` and `dark` palettes; `ThemeVars` emits both scopes and the existing toggle only selects a scope. Admin preset application persists both variants atomically and legacy unqualified settings remain the light-mode compatibility source.
**Tech Stack:** Next.js 16, React 19, TypeScript, CSS custom properties, Prisma website settings, Vitest.
## Global Constraints
- Work directly in `E:\Users\simol\Desktop\EpicNext-cms`; do not create a worktree.
- Preserve the existing uncommitted `package.json` change and never stage it.
- Keep `localStorage.theme` limited to `light` or `dark`.
- Every built-in preset must define every canonical color key in both modes.
- Build, typecheck, and the complete test suite must pass before publication.
---
### Task 1: Canonical complete preset model
**Files:**
- Modify: `src/lib/theme-presets.ts`
- Modify: `src/lib/theme-contrast.test.ts`
**Interfaces:**
- Produces: `ThemeMode`, `ThemeColorKey`, `ThemePalette`, `ThemePreset`, `THEME_COLOR_KEYS`, and `PRESETS` with `{ light, dark }` variants.
- Consumes: existing color names used by `ThemeVars` and the admin editor.
- [ ] Add failing tests that iterate every preset/mode and require exact coverage of `THEME_COLOR_KEYS`, then run `pnpm vitest run src/lib/theme-contrast.test.ts` and confirm missing dark variants fail.
- [ ] Define the canonical keys and typed palette/preset interfaces, convert every preset to complete light/dark variants, and include buttons, links, borders, and gradients.
- [ ] Update contrast tests to evaluate both variants and run the targeted test to green.
- [ ] Commit only `src/lib/theme-presets.ts` and `src/lib/theme-contrast.test.ts` with `feat: add complete light and dark presets`.
### Task 2: Runtime light/dark variables
**Files:**
- Modify: `src/components/theme-vars.tsx`
- Modify: `src/app/globals.css`
- Create: `src/components/theme-vars.test.tsx`
**Interfaces:**
- Consumes: complete `ThemePreset` and mode-qualified website settings.
- Produces: one server-generated style containing `:root{...}` and `html.dark{...}` variables.
- [ ] Add a failing render test that requires separate light/dark variable blocks and different preset-specific background values.
- [ ] Extract palette loading and CSS generation into testable helpers in `theme-vars.tsx`; read legacy keys for light fallback and `<key>_dark` for dark overrides.
- [ ] Remove hardcoded color declarations from `html.dark` while retaining input/table behavioral selectors.
- [ ] Run the new test and existing contrast suite to green.
- [ ] Commit the three files with `feat: generate theme-aware light and dark variables`.
### Task 3: Complete admin persistence
**Files:**
- Modify: `src/actions/admin-theme.ts`
- Modify: `src/app/admin/theme/page.tsx`
- Create: `src/lib/theme-settings.ts`
- Create: `src/lib/theme-settings.test.ts`
**Interfaces:**
- Produces: `settingKey(key: ThemeColorKey, mode: ThemeMode): string` and `presetSettings(preset: ThemePreset): Array<[string, string]>`.
- Consumes: canonical preset model from Task 1.
- [ ] Add failing tests proving `presetSettings` returns every light key plus every `_dark` key with no duplicates.
- [ ] Implement pure setting mapping helpers and use them in `applyPreset` so a preset writes the full pair.
- [ ] Render light and dark color sections in the admin form and update `saveTheme` to persist both sets.
- [ ] Preserve legacy unqualified light keys and use `_dark` suffixes only for dark values.
- [ ] Run mapping, theme, action-contract, typecheck, and relevant UI tests.
- [ ] Commit the four files with `feat: persist complete multitheme palettes`.
### Task 4: EpicNext popup and final verification
**Files:**
- Modify: `src/components/cms-info-popup.tsx`
- Modify: `src/components/cms-info-popup.test.tsx`
**Interfaces:**
- Consumes: semantic runtime CSS variables.
- Produces: EpicNext-branded footer trigger and modal copy.
- [ ] Change the popup test first to require `EpicNext Info`, `EpicNext`, and `Modern Next.js CMS`; run it and confirm it fails on AtomCMS copy.
- [ ] Replace AtomCMS branding and credits without introducing literal theme colors.
- [ ] Run popup and theme tests, then `pnpm typecheck`, `pnpm test`, and `pnpm build`.
- [ ] Inspect `git diff --check` and confirm `package.json` remains unstaged and unchanged by this implementation.
- [ ] Commit popup files with `feat: rebrand CMS information as EpicNext`.
- [ ] Push the completed commits to `origin/main` only after all verification succeeds.
@@ -1,53 +0,0 @@
# Semantic Theme Contrast Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make ordinary public and admin text readable across every EpicNext light/dark preset by replacing concrete palette choices with tested semantic colors.
**Architecture:** Extend the runtime CSS generator with semantic foreground, solid-foreground, subtle-background, and border variables. Central CSS utilities expose those meanings to components. A scoped source audit prevents risky hard-coded admin text colors while allowing explicit graphical preview files.
**Tech Stack:** Next.js 16, TypeScript, CSS custom properties, Tailwind CSS 4, Vitest.
## Global Constraints
- Work directly on `main` in `E:\Users\simol\Desktop\EpicNext-cms`.
- Preserve and never stage the existing `package.json` modification.
- Maintain WCAG AA 4.5:1 for ordinary text.
- Do not recolor favicon, catalog-art, image, or color-picker previews.
- Verify the complete test suite, typecheck, and production build before publication.
---
### Task 1: Semantic contrast generation
**Files:** `src/lib/theme-contrast.ts`, `src/lib/theme-contrast.test.ts`, `src/lib/theme-css.ts`, `src/components/theme-vars.test.ts`
- [ ] Add failing tests for muted/subtle/disabled text, sidebar text, and success/warning/error/info pairs across every preset and mode.
- [ ] Extend `derivePublicForegrounds` and `themePaletteCss` to emit the tested variables.
- [ ] Run the four theme test files and commit with `feat: derive semantic theme contrast tokens`.
### Task 2: Semantic CSS utilities and admin shell
**Files:** `src/app/globals.css`, `src/app/admin/layout.tsx`, `src/components/admin/admin-nav-link.tsx`, `src/lib/admin-theme-source-audit.test.ts`
- [ ] Add a failing source-audit test that rejects risky fixed text colors in the admin shell.
- [ ] Add semantic utilities for text hierarchy, statuses, notices, sidebar, tables, and inputs.
- [ ] Replace the hard-coded admin sidebar and navigation palette with semantic variables.
- [ ] Run the audit and theme tests and commit with `feat: theme admin shell semantically`.
### Task 3: Admin-wide ordinary text migration
**Files:** ordinary UI files under `src/app/admin` and `src/components/admin`; exclude explicit graphical preview files in the audit allowlist.
- [ ] Expand the failing audit to reject `text-gray-400`, `text-gray-500`, `text-white`, and raw text hex colors outside the allowlist.
- [ ] Mechanically replace muted/disabled/status text utilities with semantic utilities and variables.
- [ ] Inspect status badges and notices to ensure their text/background use the same semantic family.
- [ ] Run audit, full test suite, and typecheck; commit with `refactor: use semantic colors across admin`.
### Task 4: Final verification and publication
**Files:** no additional production files.
- [ ] Run `pnpm test`, `pnpm typecheck`, and `pnpm build`.
- [ ] Run `git diff --check` and confirm `package.json` remains unstaged.
- [ ] Review the final diff for graphical preview exclusions and publish to `origin/main` after approval.
@@ -1,78 +0,0 @@
# Admin UX Cleanup Phase 1 — Implementation Plan
> **For agentic workers:** Execute task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Remove double hub headers, wire orphan routes into tabs, dedupe theme/language controls, group Radio tabs, and differentiate Access vs Moderation icons.
**Architecture:** Config-driven hubs in `src/lib/admin-nav.ts`; chrome in `AdminHubChrome` / `AdminSectionTabs`; layout controls in `src/app/admin/layout.tsx`. No new routes — only navigation and presentation.
**Tech Stack:** Next.js App Router, React, Tailwind, Lucide, existing admin CSS tokens.
**Spec:** `docs/superpowers/specs/2026-07-17-admin-ux-cleanup-design.md`
---
## File map
| File | Role |
|------|------|
| `src/lib/admin-nav.ts` | Hub tabs, Radio `group`, icon imports |
| `src/components/admin/admin-section-tabs.tsx` | Optional grouped tab rows |
| `src/components/admin/admin-hub-chrome.tsx` | Pass tabs through (no API change if tabs shape extends) |
| `src/app/admin/layout.tsx` | Theme/lang: sidebar always; topbar `lg:hidden` only |
| `src/app/admin/**/page.tsx` (hub lists) | Strip redundant `h1` + duplicate intro blocks |
---
### Task 1: Extend tab type + Radio groups + orphan tabs + icons
**Files:**
- Modify: `src/lib/admin-nav.ts`
- Modify: `src/components/admin/admin-section-tabs.tsx`
- [ ] Add optional `group?: string` to `AdminHubTab` / `AdminTab`
- [ ] Users: add Multi-accounts tab
- [ ] Engagement: add Event types + Templates tabs
- [ ] Observability: add Chat, Commands, Trades, Activity, Economy, Errors; tighten Logs `match` to exact index only via scorer (href-only is enough if subpaths are longer)
- [ ] Radio: set `group: "primary"` / `group: "tools"` on tabs
- [ ] Moderation nav icon → `Gavel` (or `ShieldAlert`); keep Access as `Ban`
- [ ] Render grouped tabs: if any tab has `group`, render one nav per distinct group (label Primary / Tools only for radio tools group — use human labels from group id: `primary` unlabeled or “Main”, `tools` → “Tools”)
### Task 2: Theme / language placement
**Files:**
- Modify: `src/app/admin/layout.tsx`
- [ ] Keep switchers in sidebar
- [ ] Wrap topbar switchers in `className="flex … lg:hidden"` so desktop shows them once
### Task 3: Strip redundant hub list headers
**Files:** Hub **list/overview** pages that duplicate shell title (not entity detail/create):
Strip the page-level title row (`h1` / icon header duplicating hub), keep filters and action buttons.
**Remove duplicate title on (list/tab pages):**
`banners`, `users`, `users/multi-accounts`, `rooms`, `prefixes`, `sounds`, `tickets`, `tickets/templates`, `polls`, `online`, `moderation`, `moderation/actions`, `moderation/cfh`, `moderation/team`, `logs` (if present), `logs/audit`, `logs/chat`, `logs/commands`, `logs/trades`, `events`, `events/types`, `devops`, `devops/errors`, `analytics`, `analytics/activity`, `analytics/economy`, `catalog` (list chrome only)
**Keep title on:**
`polls/create`, `polls/[id]`, `events/create`, `events/[id]`, `catalog/[id]`, and any `show`/`edit`/`new` entity pages
Also strip duplicate headers on other hub tab roots that use different class patterns (articles, photos, ads, radio overview, settings, etc.) if they repeat hub title — grep for similar patterns.
### Task 4: Verify + commit
- [ ] Spot-check tab active states: `/admin/users` vs `/admin/users/multi-accounts`, `/admin/logs` vs `/admin/logs/chat`, `/admin/events` vs `/admin/events/types`
- [ ] Commit + push
---
## Spec coverage
| Spec item | Task |
|-----------|------|
| 1.1 Single hub header | Task 3 |
| 1.2 Orphan routes | Task 1 |
| 1.3 Theme/lang | Task 2 |
| 1.4 Radio groups | Task 1 |
| 1.5 Icons | Task 1 |
@@ -1,33 +0,0 @@
# ACL and import backend design
## Goal
Complete the administration ACL management and make every existing asset-import page functional end to end.
## ACL architecture
`acl_permissions`, `acl_roles`, `acl_model_permissions`, and `acl_model_roles` are the only CMS authorization source. Emulator ranks remain in `permission_ranks`; each rank maps to the CMS role `rank_<id>`. Legacy `website_permissions` and `website_housekeeping_permissions` may be migrated but are not written by the new management flow.
The permissions screen manages emulator ranks, rank roles, role permission assignments, and direct user roles/permissions. Rank creation, editing, and deletion use the emulator rank service, refresh RCON permissions, invalidate the permission cache, and log staff activity. Every mutation requires `admin.permissions.manage` and fails closed.
## Import authorization
All import pages and every `/api/admin/import/**` handler require `admin.assets.import`. Catalog deletion or repair operations that mutate catalog data additionally require `admin.catalog.edit`. Page-level checks are navigation guards only; API handlers repeat authorization before reading remote sources, writing the database, or writing files.
## Import pipeline
Port the reference import core, services, API routes, and tests for badges, clone, clothing, effects, furni, pets, and repair. Adapt imports to EpicNext's generated Prisma names and locale-free routes. Do not copy generated Prisma files.
The furni success boundary is atomic at the workflow level: verify database rows, repository asset output, configured live Nitro asset output, and `FurnitureData.json`. External Windows paths use the existing cross-platform resolver. Repair/audit reports partial state instead of treating a database insert as success.
## Migration
Add an idempotent migration that seeds `admin.assets.import`, normalizes ACL discriminator casing to `Role` and `User`, creates missing `rank_<id>` roles, migrates compatible legacy permission assignments, and grants the highest rank explicit management/import permissions. Dynamic highest-rank bypass remains an emergency compatibility path, not the persisted assignment model.
## Error handling and verification
Remote download errors, invalid archives/data, filesystem failures, schema mismatches, and partial writes return structured errors and are logged without exposing secrets. Contract tests assert route coverage and server-side ACL guards. Service tests cover path resolution, batch behavior, data reconciliation, and fail-closed authorization. Final verification runs all tests, TypeScript, and the production build.
## Scope boundary
This block does not add moderation, analytics, detailed logs, or DevOps pages. Those remain the next phase after ACL and imports are verified.
@@ -1,46 +0,0 @@
# Admin events, polls, banners, and prefixes design
## Goal
Port the complete events, CMS polls, banners, and user-prefix administration modules from `habbo-next` into EpicNext without duplicating existing features or changing emulator-owned data.
## Compatibility boundary
EpicNext keeps its existing legacy `polls`, `polls_questions`, and `polls_answers` models untouched. The imported module uses independent `website_polls`, `website_poll_questions`, and `website_poll_votes` tables.
Events use dedicated `website_event_*` tables. Banners use `website_banners`. Prefixes use `user_prefixes` plus their configuration/blacklist tables. Every new table is CMS-owned and introduced through an idempotent versioned migration compatible with the existing migration runner.
## Application architecture
Each module is a complete vertical slice:
- Prisma models map the CMS tables and relations.
- Zod validators define action inputs for events and polls.
- Server actions use EpicNext's existing `adminAction`, audit logging, and ACL helpers.
- Pages live under `/admin/events`, `/admin/polls`, `/admin/banners`, and `/admin/prefixes` without `[locale]` routing.
- Components use EpicNext semantic theme variables and existing admin primitives.
- Navigation exposes modules only through the existing staff guard.
No direct copy retains `habbo-next` locale parameters, route prefixes, or repository-specific imports.
## Permissions
The canonical permission list gains view/edit pairs for events, polls, banners, and prefixes. The ACL seed migration inserts the new slugs idempotently. Existing highest-rank super-admin behavior remains unchanged. Administrator fallback grants view permissions only; edit permissions remain explicit except for the dynamic super-admin.
## Migration and deployment
One numbered migration creates the CMS tables, indexes, foreign keys where safe, and ACL permission rows. It never drops or renames emulator tables. Prisma generation runs after migration through the existing deploy workflow.
## Failure behavior
Actions validate input, fail closed on missing permissions, log administrative mutations, and return the existing safe-action result shape. Pages handle missing records with `notFound()` and empty tables with themed empty states.
## Verification
- migration contract and idempotency tests;
- schema contract tests for every new mapped table;
- validator tests for invalid dates, statuses, and poll questions;
- action permission/import contract tests;
- route existence and locale-free import audit;
- targeted module tests, complete test suite, typecheck, Prisma generation, and production build;
- final Git audit excludes the local `package.json` modification.
@@ -1,47 +0,0 @@
# Admin operations design
## Goal
Add complete administration verticals for moderation and calls for help, detailed logs, analytics, DevOps, and online users. Each vertical includes its data source, mutations or API handlers, ACL enforcement, themed UI, and tests.
## Delivery order
1. Moderation dashboard, actions, CFH list/detail, and moderation team.
2. Audit, chat, command, and trade logs.
3. Analytics overview, activity, economy, and export.
4. DevOps overview/errors/health and online users.
Each group must compile and pass its focused contract before the next group begins.
## Data architecture
Use existing emulator and CMS tables where they already contain the required data. Queries must adapt to EpicNext's Prisma model names and live-schema conventions; generated Prisma files are never copied. When a reference page assumes a column absent from EpicNext, use a compatible projection or raw query rather than changing the emulator schema without evidence.
Moderation reads support CFH topics/categories, bans, users, and staff ranks. Mutations validate target identity and duration, call the emulator/RCON only after authorization, and write staff audit activity. Log pages are read-only and paginate/filter server-side. Analytics aggregates database data and exports only fields already visible to the authorized administrator. DevOps health exposes non-secret operational state and never returns credentials, connection strings, or raw environment variables.
## Authorization
Page guards and server-side actions/API handlers use:
- `admin.moderation.view` and `admin.moderation.edit`
- `admin.logs.view`
- `admin.analytics.view` and `admin.analytics.export`
- `admin.devops.view` and `admin.devops.edit`
Online-user administration uses `admin.users.view`; any mutation additionally requires its specific user/moderation permission. Authorization fails closed, and denied or failed privileged operations are logged.
## UI and theme
All new routes are locale-free under `/admin`. Components use the semantic `--admin-*` palette and existing shared admin components. Status colors use semantic admin status tokens; no public structural theme variables or hard-coded palette utilities are introduced.
## Error handling
Missing optional emulator tables produce an explicit unavailable/empty state rather than crashing the entire admin panel. Invalid filters return validation errors. RCON failures are reported separately from successful database changes, and destructive moderation actions never report success when the emulator operation fails.
## Verification
Contract tests assert route presence, ACL guards, and source-theme compliance. Focused tests cover moderation validation, log filters, analytics export authorization, and DevOps response redaction. Final verification runs every test, TypeScript, migration contracts, and the production build.
## Scope boundary
This block does not add public feed, forum, social, finance, betting, album/gallery, staff-login, PIN, or security pages. Those remain later public-facing phases.
@@ -1,31 +0,0 @@
# Admin theme isolation
## Objective
Keep every administration page readable and visually coherent in light and dark mode, independently of the public website palette. The audit covers the whole `/admin` tree, including every `/admin/import/*` workflow.
## Root cause
Administration components currently consume public theme variables such as `--color-primary`, `--color-background`, `--color-text`, and `--color-navbar`. A valid public preset can therefore produce poor contrast in the administration panel. A smaller set of pages also contains literal Tailwind colors, hexadecimal colors, and fixed overlays.
## Design
Define a semantic admin palette under the admin layout using `--admin-*` variables. Derive accessible foregrounds for light and dark surfaces, then migrate administration components and shared admin CSS to these semantic variables. Public pages continue using the existing public palette.
Admin colors represent roles rather than specific hues: canvas, surface, elevated surface, text, muted text, border, accent, accent foreground, success, warning, error, info, sidebar, input, overlay, and focus ring. Presets may influence the admin accent, but may not override readable foregrounds or structural surfaces with unsafe combinations.
## Import pages
The same rules apply to badge, clone, clothing, effects, furni, pets, and repair imports. Status text, selection state, borders, shadows, gradients, tooltips, dialogs, and overlays use admin semantic tokens. Colors that are part of imported content or asset previews remain unchanged because they represent data rather than interface chrome.
## Intentional color values
Literal values remain allowed only for user-editable data and faithful previews, including banner colors, prefix colors, favicon generation, event-type colors, tag/team configuration, and image-preview backdrops where a neutral checker or black canvas is required. Each exception must be explicit in the audit test.
## Verification
Extend the admin source audit so it fails when an administration UI introduces public structural theme variables, unapproved literal colors, or unapproved palette utilities. Run the focused audit test, all tests, TypeScript checking, and the production build. Manually inspect representative light and dark pages, including one dense import workflow and one modal.
## Scope boundary
This change does not port missing routes or alter database behavior. After theme isolation is complete, the next route-porting block is moderation, detailed logs, analytics, and DevOps.
@@ -1,76 +0,0 @@
# EpicNext multitheme design
## Goal
Make every built-in EpicNext preset visually complete in both light and dark mode. The administrator selects the global preset; each visitor may independently choose its light or dark variant without replacing the selected palette with a generic hardcoded theme.
The CMS information popup is rebranded from AtomCMS to EpicNext as part of the same visual consistency update.
## Current problem
The application currently combines two unrelated systems:
- `ThemeVars` injects database-controlled colors into `:root`.
- `html.dark` in `globals.css` replaces many of those colors with one hardcoded dark palette.
Consequently, every preset loses its identity in dark mode. Presets also define only a subset of the colors accepted by the theme editor, so values such as secondary buttons, danger buttons, outline buttons, links, and gradients can leak from the previously selected preset.
## Theme model
Each built-in preset will expose two complete variants:
```ts
type ThemeMode = "light" | "dark";
type ThemePalette = Record<ThemeColorKey, string>;
type ThemePreset = Record<ThemeMode, ThemePalette>;
```
`ThemeColorKey` is the single canonical list shared by presets, the admin form, persistence, runtime CSS generation, and tests. It includes all color values used by the editor and `ThemeVars`, including semantic colors, every button family, links, borders, and gradients.
The administrator-selected preset remains global. The visitor preference stored in `localStorage` remains only `light` or `dark`.
## Runtime flow
1. The administrator applies a preset.
2. Both complete variants are persisted using mode-qualified setting keys.
3. `ThemeVars` reads both variants and emits variables for `:root` and `html.dark`.
4. The pre-paint initialization script applies the visitor's saved mode, or the configured default mode.
5. The browser changes mode by toggling the existing `dark` class. It does not replace the preset.
The hardcoded palette currently declared in `html.dark` will be reduced to non-color behavioral rules. All dark-mode colors will come from the active preset.
## Custom themes
The admin editor will display light and dark sections. Saving updates both variants as one operation. Existing unqualified settings remain the source for the initial light variant so current installations retain their configured appearance.
For installations without dark-specific settings, EpicNext will use the selected preset's dark variant. This provides a deterministic migration path without trying to generate unreliable dark colors at request time.
Applying a preset writes every canonical color key for both modes. This prevents values from an earlier preset leaking into the newly selected one.
## Contrast and fallback behavior
Readable foreground variables continue to be derived independently for each mode. Invalid custom color input is rejected by the existing sanitizer. Missing keys fall back to the corresponding complete built-in palette, never to values from another preset.
## EpicNext popup
The footer trigger and popup copy will use EpicNext branding:
- `EpicNext Info` trigger
- `EpicNext` title
- `Modern Next.js CMS` badge
- EpicNext-focused description and credits
The popup continues to use semantic CSS variables, so it follows both variants of every preset.
## Verification
Automated tests will verify:
- every preset supplies every canonical key in both modes;
- every foreground/background semantic pair meets the existing contrast requirement;
- applying one preset cannot retain keys from another preset;
- runtime CSS contains separate light and dark values;
- the mode toggle only changes mode and preserves the active preset;
- the EpicNext popup renders its new branding.
Build, typecheck, and the complete test suite are required before publication.
@@ -1,46 +0,0 @@
# EpicNext semantic theme contrast design
## Goal
Guarantee readable text and controls across every built-in light/dark preset, including the complete admin panel, without flattening intentional status colors or graphical previews.
## Root cause
EpicNext calculates readable foregrounds for a limited set of theme values, while admin pages still contain hundreds of fixed Tailwind colors and raw hex values. Fixed gray, white, green, red, amber, and blue classes cannot adapt to arbitrary preset surfaces. The result is low-contrast or invisible copy when a preset changes luminosity.
## Semantic token contract
Runtime theme generation will expose adaptive tokens for:
- normal, muted, subtle, and disabled text;
- surface, elevated surface, dropdown, input, and overlay content;
- admin sidebar background, text, muted text, active item, and border;
- success, warning, error, and info foregrounds on page surfaces;
- success, warning, error, and info foregrounds on solid semantic backgrounds;
- subtle semantic backgrounds and borders for badges, notices, and statuses.
Every token is derived independently for light and dark mode from the active complete preset. Readable foregrounds must meet WCAG AA 4.5:1 for normal text. Decorative borders and non-text graphics are not forced to meet text contrast.
## Component migration
Admin components will use semantic utilities instead of palette-specific Tailwind colors. The migration covers layout, navigation, tables, forms, notices, badges, statuses, and action feedback across `src/app/admin` and `src/components/admin`.
Intentional graphical colors remain local in favicon/image previews, catalog artwork, color pickers, and user-authored preview content. These exceptions must be explicit and are not used for ordinary text.
The admin sidebar will stop using a fixed purple/black palette and will consume dedicated sidebar tokens. Public components touched by the audit will use the same semantic text and status tokens.
## CSS architecture
`theme-css.ts` remains the single runtime generator. It will emit semantic variables for each palette. `globals.css` will define reusable semantic classes for text hierarchy, notices, badges, tables, inputs, and admin navigation. Component code will select meaning (`success`, `muted`, `warning`) rather than a concrete color.
No global override of arbitrary Tailwind utility classes will be introduced because that would make third-party and graphical components unpredictable.
## Verification
Automated verification will include:
- contrast tests for every semantic foreground/background pair in every preset and mode;
- contract tests requiring every runtime semantic variable;
- a source audit that rejects new risky hard-coded text/background combinations in admin UI outside an explicit graphical allowlist;
- complete test suite, typecheck, and production build;
- a final diff audit ensuring the existing local `package.json` change is not staged.
@@ -1,155 +0,0 @@
# Admin UX Cleanup — Design Spec
**Date:** 2026-07-17
**Status:** Approved in chat (Phase 1); Phases 2–3 queued after Phase 1 ships
**Scope:** Admin panel (`/admin/*`) — EpicNext-cms
## Context
The admin already has hub chrome (`AdminHubChrome` + `AdminPageShell` + `AdminSectionTabs`), a condensed sidebar, theme/language switchers, and ACL. Remaining pain is inconsistency: double headers, orphan routes, duplicated chrome controls, crowded Radio tabs, and identical icons for Access vs Moderation.
This document covers a **three-phase** program. **Only Phase 1 is in scope for the next implementation plan.**
---
## Goals
1. One clear page hierarchy under each hub (no stacked titles).
2. Every useful admin route reachable from hub tabs (no orphan pages).
3. Theme/language controls in one primary place (no desktop duplicate).
4. Radio hub usable on smaller widths without losing URLs.
5. Access vs Moderation visually distinct in the sidebar.
## Non-goals (Phase 1)
- Full admin i18n (Phase 2).
- Full design-token / shadcn unification (Phase 3).
- New features, new pages, or permission model changes.
- Changing public-site chrome or avatar/imager behavior.
---
## Phase 1 — UX cleanup
### 1.1 Single hub header
**Current:** `AdminHubChrome` renders hub `title` + `subtitle` + tabs; many child pages also render `h1` / intro copy (often `text-3xl font-bold`), producing double titles.
**Rule:**
| Page type | Hub shell title | Page-level `h1` |
|-----------|-----------------|-----------------|
| Hub list / overview (matches a hub tab) | Keep | Remove (or demote to section heading if needed for a11y only when content blocks require it) |
| Nested create / edit / show (`…/new`, `…/[id]`, `…/create`, `…/show/[id]`) | Keep hub title | Keep entity-specific title (e.g. poll name, “Create Event”) |
| Dashboard `/admin` (no hub) | N/A | Keep its own header |
**Implementation approach:**
- Prefer removing redundant page chrome blocks (icon + `h1` + muted description that duplicates hub subtitle).
- Keep action rows (Create buttons, filters, search) that sit next to the old `h1`; restructure to a toolbar without a second page title.
- Do not strip semantic headings inside content cards/tables.
**Acceptance:** Opening any hub tab shows exactly one primary title (from `AdminPageShell`). Detail pages still show the entity/create title below the hub chrome.
### 1.2 Wire orphan routes into hub tabs
Add tabs (English labels for Phase 1; i18n keys in Phase 2):
| Hub | New / adjusted tabs | Hrefs |
|-----|---------------------|-------|
| **Users** | Multi-accounts | `/admin/users/multi-accounts` |
| **Engagement** | Event types, Templates | `/admin/events/types`, `/admin/tickets/templates` |
| **Observability** | Chat, Commands, Trades | `/admin/logs/chat`, `/admin/logs/commands`, `/admin/logs/trades` |
| **Observability** | Activity, Economy (under analytics) | `/admin/analytics/activity`, `/admin/analytics/economy` |
| **Observability** | Errors (under devops) | `/admin/devops/errors` |
**Tab matching notes:**
- Users “Directory” must keep `match` that includes `/admin/users` but **not** steal active state from `/admin/users/multi-accounts` (exact / longest-prefix matching already in `AdminSectionTabs` — verify Directory `match` does not list multi-accounts; multi-accounts gets its own tab with `href` only or explicit `match`).
- Logs “Logs” tab (`/admin/logs`) must not stay active on `/admin/logs/chat` etc. Prefer exact match for the main Logs index, or give sub-log tabs longer prefixes so they win (existing scorer prefers longer / exact — verify).
- Analytics “Analytics” vs Activity/Economy: same longest-match rule.
- Engagement Event types: `/admin/events/types` must win over Events `match: ["/admin/events"]` — longest prefix already favors `/admin/events/types` if that tab is listed.
**Acceptance:** Every orphan page above is one click from its hub tab strip. No new routes required.
### 1.3 Theme / language control placement
**Decision:** Primary controls stay in the **sidebar** (desktop). **Topbar** keeps theme + language only on **mobile** (when the sidebar is not persistently visible), or remove from topbar entirely if `AdminMobileWrapper` already exposes sidebar controls on mobile.
**Preferred behavior:**
- Desktop (`lg+`): switchers **only in sidebar** header row; remove from `Topbar`.
- Mobile: switchers remain reachable via the mobile sidebar drawer (already present). If the drawer is hard to discover, keep a compact pair in the topbar **only below `lg`**.
**Acceptance:** On desktop, theme/language appear once. Mobile users can still change theme and locale without hunting.
### 1.4 Radio hub tab grouping
URLs unchanged. UI presents two rows (or a primary row + overflow “More” row):
**Primary:** Overview, History, Moderation, Monitoring, Settings
**Tools:** Banners, Embed, API keys, Points, Ranks, Auto DJ
**Implementation options (pick one in plan):**
- **A (recommended):** Extend `AdminSectionTabs` / hub definition with optional `group?: "primary" | "tools"` and render two labeled rows for Radio only.
- **B:** Nested “Tools” dropdown tab — less discoverable; avoid unless row A overflows badly.
**Acceptance:** Radio remains fully linked; primary ops are visible without horizontal scroll on a typical laptop width (~1280px).
### 1.5 Distinct Access vs Moderation icons
- **Access & security** sidebar: keep `Ban` (or `Shield`) — already distinct from Users.
- **Moderation** sidebar: change from `Shield` to something like `Gavel` or `ShieldAlert` so it does not match Access.
Hub definition icons for Access vs Moderation should also differ if both appear in chrome.
**Acceptance:** Sidebar icons for Access and Moderation are not the same glyph.
---
## Phase 2 — Admin i18n (queued)
- Move hub `title` / `subtitle` / tab `label` to `labelKey` + `pages.admin.hubs.*` (and tab keys).
- Translate high-traffic pages: Users, Events, Logs, Settings, Moderation.
- i18n theme switcher aria/title strings for `variant="admin"`.
- Do not block Phase 1 on this; Phase 1 may leave English hub strings as today.
## Phase 3 — Design system (queued)
- Standardize list pages on `--admin-*` tokens (`admin-card`, shared empty state, table chrome).
- Optional shared `AdminListToolbar` for actions formerly next to removed `h1`s.
- Gradual migration; no big-bang rewrite of catalog/user detail.
---
## Risks & mitigations
| Risk | Mitigation |
|------|------------|
| Removing `h1` hurts accessibility | Hub shell already exposes one `h1`; detail pages keep entity `h1`. Spot-check with one screen reader pass on Users + Events. |
| Tab active-state regressions | Add/adjust `match` arrays; manually verify Directory vs Multi-accounts, Logs vs Chat. |
| Radio two-row tabs feel heavy | Only Radio uses groups; other hubs stay single row. |
| Mobile loses theme/lang | Keep switchers in sidebar drawer; optional `lg:hidden` topbar pair. |
## Out of scope leftovers
- Calendar under Shop hub (IA smell) — defer unless requested.
- Legacy user route folder split (`show/[id]` vs `[id]`) — defer.
- Avatar `/imaging` proxy — separate track.
## Success criteria (Phase 1)
1. No double hub+page title on representative pages: Articles, Users directory, Events list, Logs index, Radio overview.
2. Orphan routes listed above reachable from tabs.
3. Desktop: single theme/language control location.
4. Radio primary tabs visible without scrolling on 1280px width.
5. Moderation and Access icons differ.
---
## Approval
- Phase 1 approach approved in conversation (2026-07-17).
- Implementation proceeds via a Phase-1 plan under `docs/superpowers/plans/`.