Saving project documentation.

This commit is contained in:
Scott Idem
2026-03-16 14:04:22 -04:00
parent 8db806c6ab
commit 31fe26df9c

View File

@@ -0,0 +1,428 @@
# PROJECT: Aether App — Comprehensive Style Review
**Status:** In Progress
**Priority:** Medium
**Created:** 2026-03-13
**Updated:** 2026-03-13
**Related:** `src/app.css`, `src/routes/+layout.svelte`, `documentation/AE__UI_Component_Patterns.md`
---
## 1. Objective
Audit and unify the visual design system across all Aether modules. The goal is consistent:
- Color token usage (Skeleton `preset-*` / `surface-*` / semantic tokens)
- Button and interactive element styling
- Dark mode handling
- Typography hierarchy
- Layout patterns (cards, lists, tables, modals, banners)
- Icon system (Lucide only)
This review covers all modules and their distinct use cases. Changes must be sequenced to avoid breaking live-production systems (Events Launcher, IDAA).
### Scope of Modules
| Module | Routes | Primary Users | Notes |
|---|---|---|---|
| Core / App Shell | `+layout.svelte`, `e_app_sys_bar.svelte` | All users | Foundation — impacts everything |
| Core Admin | `/core/` | OSIT staff / managers | Manager-only section |
| Journals | `/journals/` | Authenticated users | Canonical/frontier model |
| Events — General | `/events/`, `/events/[id]/` | Event staff, attendees | Hub page |
| Events — Pres Mgmt | `/events/[id]/(pres_mgmt)/` | Event coordinators | Operations tool |
| Events — Launcher | `/events/[id]/(launcher)/` | AV/tech staff (Electron kiosk) | ⚠️ Live production — April 2026 conference |
| Events — Badges | `/events/[id]/(badges)/` | Registration desk staff | On-site kiosk use |
| Events — Leads | `/events/[id]/(leads)/` | Exhibitor booth staff | On-site kiosk use |
| IDAA | `/idaa/` | IDAA members (iframe) | ⚠️ Privacy-critical, iframe context |
---
## 2. Current State: Dual-Generation Problem
The codebase has two parallel style generations that co-exist:
| Era | Pattern | Where Used |
|---|---|---|
| **Modern** | `preset-tonal-*`, `preset-filled-*`, Lucide icons, Svelte 5 runes | `sys_bar`, Journals, IDAA dashboard |
| **Legacy** | `variant-soft-*`, `variant-filled-*`, FontAwesome `fas fa-*` icons | Events routes (most), some Core |
The Journals module is the canonical reference for modern patterns — when in doubt, match it.
---
## 3. Color Token Architecture
Three overlapping systems are in use. The goal is to consolidate to two:
### ✅ System 1: Skeleton Semantic Tokens (keep, expand usage)
Used for colored/semantic elements.
```
primary, secondary, tertiary, success, warning, error, surface
```
Usage: `preset-tonal-primary`, `bg-primary-500/10`, `text-error-500`, `border-warning-500`
### ✅ System 2: Plain Tailwind Grayscale (keep for neutrals)
Used for neutral backgrounds, borders, and text. Predictable across all Skeleton themes.
```
gray-50/100/200/300/400/500/600/700/800/900
```
Usage: `bg-gray-50 dark:bg-gray-900`, `border-gray-200 dark:border-gray-700`
### ❌ System 3: Hardcoded RGB/HSL (eliminate)
```
bg-orange-600/90 — root layout banner
hsla(0, 100%, 50%, .5) — journal entry eye icon
rgb(243 244 246) — form dark mode hacks in <style> blocks
```
These are brittle, not theme-aware, and create maintenance debt.
### Decision Rule
> **Semantic color needed?** → Use Skeleton token (`preset-*`, `text-primary-*`, etc.)
> **Neutral background/border/text?** → Use `gray-*` with `dark:` pair
> **Hardcoded color?** → Replace with token. No exceptions.
---
## 4. Dark Mode Architecture
### Current Setup (already correct in app.css)
```css
@custom-variant dark (&:where(.dark, .dark *)); /* Tailwind v4 class-based dark mode */
html.dark { color-scheme: dark; } /* Native controls follow app theme */
html.light { color-scheme: light; }
```
### Gap: Skeleton Form Classes Lack Dark Mode
Skeleton's `.input`, `.select`, `.textarea` classes do not include dark mode styles. This causes white text on white backgrounds in dark mode. Currently patched with inline `<style>` blocks per-component (see `e_app_sys_bar.svelte` lines 693707).
**Fix:** Global utility in `app.css` (see Phase 1, Step 1). Once added, remove per-component patches.
---
## 5. Button System
### Standard: `preset-*` (Skeleton v4 pattern) ✅
```html
<button class="btn preset-tonal-secondary">Secondary</button>
<button class="btn btn-sm preset-filled-primary">Primary</button>
<button class="btn preset-outlined-surface">Outlined</button>
```
### Legacy: `variant-*` (Skeleton v3 pattern) — migrate away ⚠️
```html
<button class="btn variant-soft-secondary">Legacy</button>
<button class="btn variant-filled-primary">Legacy</button>
<button class="btn variant-ghost-surface">Legacy</button>
```
### Migration Map
| Legacy `variant-*` | Modern `preset-*` |
|---|---|
| `variant-filled-primary` | `preset-filled-primary` |
| `variant-filled-secondary` | `preset-filled-secondary` |
| `variant-soft-primary` | `preset-tonal-primary` |
| `variant-soft-secondary` | `preset-tonal-secondary` |
| `variant-soft-surface` | `preset-tonal-surface` |
| `variant-soft-error` | `preset-tonal-error` |
| `variant-soft-warning` | `preset-tonal-warning` |
| `variant-soft-success` | `preset-tonal-success` |
| `variant-ghost-surface` | `preset-outlined-surface` |
| `variant-ghost-error` | `preset-outlined-error` |
| `variant-ghost-success` | `preset-outlined-success` |
| `variant-outlined-*` | `preset-outlined-*` |
### Custom `ae_btn_*` Classes (app.css)
These exist in `app.css` and wrap the `preset-*` system. They are valid but underused. Consider adopting where button groups need reuse.
---
## 6. Icon System
**Standard:** Lucide (`@lucide/svelte`) — SVG, tree-shakeable, consistent stroke weight
**Legacy:** FontAwesome (`fas fa-*` / `far fa-*`) — CSS class-based, heavier
FontAwesome is still imported (likely via global CSS). Goal: complete removal from all new work; migrate existing usage to Lucide progressively.
### FontAwesome → Lucide Reference Map (events module)
| FontAwesome | Lucide Component | Notes |
|---|---|---|
| `fa-cogs` | `Settings` | Settings/config |
| `fa-chart-line` | `TrendingUp` | Reports/charts |
| `fa-map-marked-alt` | `MapPinned` | Location with map |
| `fa-map-marker-alt` | `MapPin` | Location marker |
| `fa-tools` | `Wrench` | Tools/maintenance |
| `fa-search` | `Search` | Search |
| `fa-chalkboard-teacher` | `PresentationIcon` or `GraduationCap` | Presenter |
| `fa-plane` | `Plane` | Travel/remote |
| `fa-sync-alt fa-spin` | `RefreshCw` + CSS animation | Spinner |
| `fa-arrow-up` | `ArrowUp` | Up arrow |
| `fa-arrow-down` | `ArrowDown` | Down arrow |
| `fa-list-ol` | `ListOrdered` | Ordered list |
| `fa-file-csv` | `FileSpreadsheet` | CSV file |
| `fa-toggle-on` | `ToggleRight` | Toggle |
| `fa-calendar-alt` | `CalendarDays` | Calendar |
| `fa-exclamation-triangle` | `TriangleAlert` | Warning |
| `fa-lock` | `Lock` | Locked |
| `fa-unlock` | `Unlock` | Unlocked |
| `fa-eye` | `Eye` | Visible |
| `fa-eye-slash` | `EyeOff` | Hidden |
| `fa-trash` | `Trash2` | Delete |
| `fa-edit` / `fa-pencil` | `Pencil` | Edit |
| `fa-plus` | `Plus` | Add |
| `fa-times` / `fa-close` | `X` | Close/remove |
| `fa-check` | `Check` | Confirm |
| `fa-ban` | `Ban` | Denied/blocked |
| `fa-user` | `User` | Person |
| `fa-users` | `Users` | Group |
| `fa-tag` | `Tag` | Tag/label |
| `fa-print` | `Printer` | Print |
| `fa-download` | `Download` | Download |
| `fa-upload` | `Upload` | Upload |
| `fa-copy` | `Copy` | Copy |
| `fa-qrcode` | `QrCode` | QR code |
| `fa-id-card` | `IdCard` | Badge/ID |
| `fa-file-alt` | `FileText` | File |
| `fa-compress-arrows-alt` | `Minimize2` | Collapse |
| `fa-expand` | `Maximize2` | Expand |
| `fa-angle-right` | `ChevronRight` | Nav arrow |
| `fa-angle-down` | `ChevronDown` | Accordion |
| `fa-clock` | `Clock` | Time |
### Lucide Usage Pattern
```svelte
<script>
import { Settings, Search, MapPin } from '@lucide/svelte';
</script>
<!-- Decorative icon with adjacent label -->
<Settings size="1em" class="shrink-0" aria-hidden="true" />
<!-- Icon-only button — MUST have aria-label -->
<button aria-label="Settings" class="btn btn-sm preset-tonal-surface">
<Settings size="1.1em" />
</button>
```
---
## 7. Typography
### Standard Hierarchy
```html
<!-- Page title -->
<h1 class="text-3xl sm:text-4xl font-black tracking-tight">Title</h1>
<!-- Section heading -->
<h2 class="text-xl font-bold">Section</h2>
<!-- Card/item heading -->
<h3 class="text-lg font-semibold">Item</h3>
<!-- Label / eyebrow -->
<span class="text-xs font-bold uppercase tracking-wide opacity-40">Label</span>
<!-- Muted secondary text -->
<span class="text-sm opacity-60">Secondary info</span>
<!-- Hint / placeholder text -->
<span class="text-xs opacity-40 italic">Hint</span>
```
### Rule: Opacity Over Fixed Colors for Muted Text
```html
<!-- ✅ Theme-aware muted text -->
<span class="text-sm opacity-60">Note</span>
<!-- ❌ Fixed muted text — breaks in dark mode -->
<span class="text-sm text-gray-500">Note</span>
```
> **Exception:** `text-gray-*` is acceptable in components that intentionally use plain Tailwind grayscale for neutrality (e.g., Journals list cards), as long as `dark:text-gray-*` counterpart is always included.
---
## 8. Card & Layout Patterns
See `documentation/AE__UI_Component_Patterns.md` for the full pattern reference.
Key standard patterns:
- **List item card:** `border border-gray-200 dark:border-gray-700 border-l-4 border-l-primary-500/40` with hover intensification
- **Content card:** `rounded-lg border border-surface-200-800 bg-surface-50-900 px-4 py-3`
- **Glow accent:** `absolute -inset-1 bg-linear-to-r from-primary-500 to-secondary-500 rounded-2xl blur opacity-25 dark:opacity-40 group-hover:opacity-60 transition duration-1000 group-hover:duration-200 pointer-events-none`
- **Empty state:** `preset-tonal-warning p-6 rounded-xl` centered, with icon + heading + description
---
## 9. Accessibility Rules
- **Never remove focus rings.** `focus:ring-0` on text inputs fails WCAG 2.1 AA. Use `focus:ring-2 focus:ring-primary-500` instead.
- **Icon-only buttons must have `aria-label`.** No exceptions.
- **Decorative icons must have `aria-hidden="true"`.** This applies to ALL FontAwesome `<span class="fas ...">` elements too.
- **Color is not the only status indicator.** Pair color with text or icon shape.
- **Form labels must be explicit.** Use `<label for="...">` or `aria-label`.
---
## 10. Module-by-Module Status
### Core / App Shell
| Item | Status | Notes |
|---|---|---|
| Root layout banners (offline, expired) | 🟡 Needs work | Uses `bg-orange-600/90` — replace with `preset-tonal-warning` |
| `e_app_sys_bar.svelte` | ✅ Modern | Best-practice reference component |
| `e_app_theme.svelte` | 🟡 Legacy | Redundant with sys_bar theme section; keep but no new work |
| `core/+layout.svelte` | ✅ Good | Uses `variant-soft-*` — migrate to `preset-*` eventually |
| `core/+page.svelte` | ✅ Good | Excellent card grid template |
### Journals
| Item | Status | Notes |
|---|---|---|
| Overall | ✅ Canonical reference | Use as template for all new work |
| `ae_comp__journal_obj_li.svelte` | ✅ Excellent | Card pattern, icon sizing, hover states |
| `ae_comp__journal_entry_obj_li.svelte` | 🟡 Minor issues | `bg-slate-*` inconsistency (should be `gray-*`); hardcoded HSL eye icon colors |
| `ae_comp__journal_entry_header.svelte` | 🔴 A11y issue | `focus:ring-0` on name input — restore focus ring |
### Events — General
| Item | Status | Notes |
|---|---|---|
| `events/+page.svelte` | 🟡 Legacy | FontAwesome icons; `variant-ghost-surface` button |
| `events/+layout.svelte` | 🟡 Legacy | FontAwesome spinners and arrows |
| `events/ae_comp__events_menu_nav.svelte` | 🟡 Legacy | All icons are FontAwesome |
| `events/[id]/+page.svelte` | 🟡 Mixed | Good card grid, but `variant-soft-warning` and hardcoded dark overrides |
### Events — Pres Mgmt
| Item | Status | Notes |
|---|---|---|
| Overall | 🟡 Legacy | Predates the modern refactor |
| `pres_mgmt/+page.svelte` | 🟡 Legacy | FontAwesome throughout; bare list, no card styling |
| Session/presenter page menus | 🟡 Legacy | FontAwesome icons; `variant-*` buttons |
| Session view | 🟡 Mixed | Some modern patterns mixed with legacy |
### Events — Launcher ⚠️ Live Production
| Item | Status | Notes |
|---|---|---|
| Overall | ⚠️ FREEZE | **April 2026 conference** — no style changes until post-event |
| Icon/button migration | 🔒 Deferred | Schedule for Phase 3 after conference |
### Events — Badges
| Item | Status | Notes |
|---|---|---|
| Overall | 🟡 Mixed | Functional, some `variant-*` patterns |
| `badge_upload_form.svelte` | 🟡 Legacy | `variant-filled-tertiary/primary` buttons |
| `badge_template_form.svelte` | 🟡 Legacy | `variant-filled-*` buttons |
### Events — Leads
| Item | Status | Notes |
|---|---|---|
| Overall | 🟡 Legacy | Heavy `variant-*` usage throughout; otherwise functionally good |
| `ae_comp__exhibit_signin.svelte` | 🟡 Mixed | `variant-filled-primary`, `variant-soft-error` |
| `ae_comp__lead_qr_scanner.svelte` | 🟡 Legacy | All state cards use `variant-soft-*` |
| `ae_tab__add.svelte` | 🟡 Legacy | `variant-filled-secondary`, `variant-ghost-surface` tab buttons |
### IDAA ⚠️ Privacy-Critical
| Item | Status | Notes |
|---|---|---|
| `(idaa)/+page.svelte` | ✅ Modern | Semantic tokens, good access gate |
| Archives | 🟡 Partial | Likely legacy underneath; deferred |
| BB (Posts) | 🟡 Partial | Deferred — most sensitive module |
| Recovery Meetings | 🟡 Partial | Deferred |
| **All IDAA** | ⚠️ Last priority | Review only after non-IDAA modules are complete |
---
## 11. Issues Ranked by Priority
| # | Severity | Issue | Location | Phase |
|---|---|---|---|---|
| 1 | 🔴 A11y | `focus:ring-0` removes focus indicator on journal name input | `ae_comp__journal_entry_header.svelte:108` | 1 |
| 2 | 🔴 Maintenance | No global dark mode form fix — per-component patches scattered | `e_app_sys_bar.svelte` lines 693707; others | 1 |
| 3 | 🟡 Consistency | FontAwesome icons throughout events module | 61 event files | 12 |
| 4 | 🟡 Consistency | `variant-*` buttons used instead of `preset-*` | Events, Badges, Leads routes | 12 |
| 5 | 🟡 Theme | Hardcoded `bg-orange-600/90` on root layout offline banner | `+layout.svelte` | 2 |
| 6 | 🟡 Theme | Hardcoded HSL colors on journal entry eye icon | `ae_comp__journal_entry_obj_li.svelte` | 2 |
| 7 | 🟢 Consistency | `bg-slate-*` used in journal entry instead of `bg-gray-*` | `ae_comp__journal_entry_obj_li.svelte` | 2 |
| 8 | 🟢 Polish | Pres Mgmt pages lack card styling (bare `<ul>` lists) | `pres_mgmt/+page.svelte` and sub-pages | 3 |
| 9 | 🟢 Polish | Root layout banner uses direct `font-semibold text-white` instead of preset | `+layout.svelte` | 2 |
---
## 12. Implementation Plan
### Phase 1: Quick Wins (current)
**Step 1 — Global form dark mode utility** ✅ Target: `src/app.css`
Add a global utility so Skeleton `.input`, `.select`, `.textarea` classes render correctly in dark mode. This eliminates all per-component `<style>` patches.
**Step 2 — FontAwesome → Lucide in events nav/layout files**
Scope: Non-Launcher, non-IDAA files only. Priority order:
1. `src/routes/events/ae_comp__events_menu_nav.svelte` — top-level navigation
2. `src/routes/events/+layout.svelte` — spinner and sort icons
**Step 3 — Standardize `variant-*` → `preset-*` in events**
Scope: `+page.svelte`, `settings/+page.svelte`, `sign_in_out.svelte`
Skip: Launcher files (frozen), IDAA files (deferred)
---
### Phase 2: Consolidation
- Replace hardcoded banner color in root layout (`bg-orange-600/90``preset-tonal-warning`)
- Fix journal entry eye icon hardcoded HSL colors
- Fix `bg-slate-*` inconsistency in journal entry
- Migrate `variant-*` in remaining events files: Pres Mgmt, Badges, Leads
- Remove per-component `<style>` dark mode patches (now covered by global utility)
- Add responsive typography to events hub and pres mgmt pages
---
### Phase 3: Module Refactors (post-April 2026 conference)
- Events Launcher: FontAwesome → Lucide, `variant-*``preset-*`
- Events Pres Mgmt: Card styling for session/presenter lists
- IDAA: Full style review (Archives, BB, Recovery Meetings)
- Create `.prose-journal` utility in app.css to centralize markdown prose overrides
---
## 13. Files to Modify (Phase 1)
| File | Change |
|---|---|
| `src/app.css` | Add global `.dark` form element utility |
| `src/routes/events/ae_comp__events_menu_nav.svelte` | Replace `fas fa-*` with Lucide imports |
| `src/routes/events/+layout.svelte` | Replace `fas fa-sync-alt fa-spin` and arrow icons with Lucide |
| `src/routes/events/+page.svelte` | Replace `variant-ghost-surface``preset-outlined-surface` |
| `src/routes/events/[event_id]/settings/+page.svelte` | Replace `variant-filled-secondary/primary``preset-*` |
| `src/routes/events/[event_id]/sign_in_out.svelte` | Replace `variant-soft-warning``preset-tonal-warning` |
---
## 14. Testing Notes
- Run `npx svelte-check` after every file change
- Test dark mode toggle after form utility added — confirm inputs render correctly in dark
- Test light mode — confirm no regressions
- Events nav: verify all Lucide icons render at correct size and with correct meaning
- Launcher: do not touch — verify no unintended changes via `git diff`
- IDAA: do not touch — verify no unintended changes via `git diff`
---
## 15. What We Are NOT Changing (Phase 1)
- Events Launcher files — frozen until post-April 2026 conference
- All IDAA files — deferred to last phase
- Root layout banner hardcoded color — Phase 2
- Journal entry HSL eye icon colors — Phase 2
- Pres Mgmt card styling — Phase 3