Files
OSIT-AE-App-Svelte/documentation/PROJECT__AE_Style_Review.md
2026-03-16 14:04:22 -04:00

17 KiB
Raw Blame History

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)

@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)

<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 ⚠️

<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

<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

<!-- 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

<!-- ✅ 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/90preset-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-surfacepreset-outlined-surface
src/routes/events/[event_id]/settings/+page.svelte Replace variant-filled-secondary/primarypreset-*
src/routes/events/[event_id]/sign_in_out.svelte Replace variant-soft-warningpreset-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