Commit Graph

23 Commits

Author SHA1 Message Date
jared d651cfbe2c audit pass 15: type=button on JS createElement and innerHTML buttons
- Toast close button: set closeEl.type = 'button' on createElement
- Combobox tag remove button: add type="button" to innerHTML string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:24:10 -04:00
jared bdf3ad085f audit pass 14: type=button on JS-generated button HTML strings
Add type="button" to all buttons created via innerHTML in JS:
- Lightbox close/prev/next buttons (3 instances)
- Pagination prev/page/ellipsis/next buttons (7 instances)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:22:11 -04:00
jared 5caaf38e9a audit pass 13: context menu arrow key navigation
Add ArrowUp/ArrowDown/Home/End keyboard navigation between context
menu items per WAI-ARIA menu widget specification. Focus wraps at
top and bottom boundaries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:18:17 -04:00
jared 7630da8abd fix: boot sequence lines appearing twice
Two init paths both called runBoot() before sessionStorage was set
(the key was only written on completion, ~1.1s later):
- Private init() at DOMContentLoaded → runBoot()
- lt.init() HTML call on DOMContentLoaded → ltInit() → runBoot()

Both found no session key and started simultaneous setInterval loops
on the same <pre>, each appending the same message → every line twice.

Fix: set the sessionStorage key immediately at the start of runBoot()
so any concurrent second call exits early.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:12:05 -04:00
jared 45b968b77d audit pass 12: type=button, focus restore, :focus-visible on links
HTML:
- Add type="button" to all remaining buttons (nav drawer close, menu
  btn, theme toggle, notif bell, right drawer close, tab buttons,
  sidebar toggle, alert close x4, code copy, tab bar buttons x4,
  detail panel open, modal close x2, keyboard shortcuts close)
- Add aria-label="Search commands" to command palette input
- Notification panel close(true): restore focus to bell on Escape
- Generic dropdowns: add Escape key handler with trigger focus restore

CSS:
- Add a:focus-visible global focus ring
- Add .lt-nav-dropdown-menu li a:focus-visible
- Add .lt-markdown a:focus-visible
- Fix dead .lt-typeahead-option selector → .lt-typeahead-item with
  :hover, .is-focused, :focus-visible for light theme

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 13:49:23 -04:00
jared ca2d6d225e audit pass 10-11: type=button, XSS escaping, focus/ARIA fixes
HTML:
- Add type="button" to all buttons outside forms (22 instances)
- Add aria-label="Add comment" to unlabelled textarea#td-comment

JS:
- Escape alt text and link text in markdown renderer with escHtml()
  to prevent XSS in image alt/link content
- Fix nested modal focus: only restore trigger focus when no other
  modal is still open; add document.contains guard

CSS:
- Add .lt-nav-link:focus-visible focus ring (was missing entirely)
- Fix .lt-typeahead-option (dead selector) → .lt-typeahead-item with
  :hover, .is-focused, and :focus-visible for light theme

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 20:46:31 -04:00
jared 8b54efef61 audit pass 9: XSS fix, focus management, ARIA labels, and :focus-visible gaps
JS:
- Lightbox: remove keydown listener on close (memory leak fix)
- Lightbox: restore focus to trigger on close
- Right drawer: fix aria-hidden="false" anti-pattern to removeAttribute
- Markdown renderer: block javascript:/data: protocol URIs in link and
  image replacements to prevent XSS
- Sidebar submenus: add aria-expanded tracking on toggle; hide decorative
  chevron from screen readers; initialize aria-expanded on mount

CSS:
- Add :focus-visible to .lt-sidebar-toggle (interactive button)
- Add :focus-visible to .lt-dropzone (focusable container)
- Fix .lt-stat-card:focus-visible outline-offset to -2px (clip-path clips it)
- Add light theme override for .lt-nav-drawer-link:focus-visible
- Adjust .lt-split-divider:focus-visible outline-offset to 3px

HTML:
- Range input: update aria-valuenow dynamically on input event
- Combobox label: add for="demo-combobox-input" association
- Typeahead label: add for="demo-typeahead-input" association
- Dropzone file input: add aria-label
- Notification items: add descriptive aria-label to all 4 items;
  add aria-hidden="true" to decorative dot spans
- Mark all read button: add type="button" to prevent accidental form submit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 20:16:12 -04:00
jared e8c1197613 audit pass 8: keyboard accessibility and table semantics
CSS:
- Fix light theme input/select/textarea :focus -> :focus-visible

HTML:
- Worker metrics table: convert label <td> to <th scope="row"> for screen readers
- Add aria-label to worker metrics table
- Sticky table: add scope="col" to all column headers
- Keyboard shortcuts modal table: add scope="col" to headers
- Kanban cards: remove tabindex="0" from role="article" (non-interactive)
- Advanced filter: ensure all 3 label/select pairs have for/id associations

JS:
- Lightbox: fix keydown listener leak by storing bound reference for removeEventListener
- Lightbox: save/restore trigger focus on open/close
- Sortable table: add tabindex="0" and Enter/Space keydown handler on sortable <th>
- Split pane: add tabindex="0", role="separator", aria-label, and arrow/Home/End
  keyboard resize support on divider (5% steps)
- Form validation: handle <select multiple> required check via selectedOptions.length

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 20:09:29 -04:00
jared b84d71dd7a audit pass 7: ARIA, focus management, and label fixes
CSS:
- Add :focus-visible to sortable th, breadcrumb links, list links, cmd-item,
  combobox-option, typeahead-item, sidebar-sub-link, split-divider, stat-card
- Fix .lt-skip-link:focus to also include :focus-visible for spec compliance

JS:
- Mobile nav: add focus trap (_trapFocus), save/restore trigger focus, fix
  aria-hidden="false" to removeAttribute pattern, add document.contains guard
- Combobox: add aria-activedescendant on _moveFocus; add unique IDs to options;
  clear aria-activedescendant on close; wrap querySelectorAll in Array.from
- Typeahead: add aria-activedescendant on _moveFocus; add unique IDs to items;
  add aria-busy during async search; clear aria-activedescendant on select;
  wrap querySelectorAll in Array.from
- Command palette: add unique IDs to items; set/clear aria-activedescendant
  on move and mouseenter; clear on close
- Lightbox: add document.contains guard on focus setTimeout
- Stats filter: add Enter/Space keyboard handler for role="button" cards

HTML:
- Stat cards: add role="button" tabindex="0" aria-label (interactive divs)
- Advanced filter selects: add id/for associations to all 3 label+select pairs
- Accordion SVG icons: add aria-hidden="true" (decorative)
- Range input: add aria-label, aria-valuemin/max/now
- Wizard form controls: add id/for to all 4 label+input/select pairs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 20:02:15 -04:00
jared d08007cdd7 audit pass 6: accessibility, ARIA, and keyboard fixes
- JS: fix checkbox/radio required validation using .checked not .value
- JS: guard _cpTrigger.focus() with document.contains() check
- JS: add arrow/Home/End key navigation to tab groups (WCAG 2.1)
- JS: clamp context menu left edge with Math.max(8, ...) to prevent off-screen
- JS: fix wizard _show() to removeAttribute aria-hidden on active step
- HTML: add role="region" + aria-label to notification panel
- HTML: convert Assigned To span+div to label+select with for/id association
- HTML: add role="article" tabindex="0" aria-label to all kanban cards
- HTML: remove aria-hidden="false" anti-pattern from wizard active step
- CSS/HTML/JS: replace aria-hidden="false" show-hook with :not([aria-hidden])
  so open state is represented by absent attribute rather than false value

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 19:51:21 -04:00
jared fdcadad23b fix: accessibility & quality audit pass 4+5
CSS:
- Add :active/:focus-visible to .lt-modal-close, .lt-drawer-right-close,
  .lt-notif-panel-clear, .lt-file-item-remove
- Add :focus-visible to .lt-accordion-header, .lt-tag-remove,
  .lt-combobox-tag-remove
- Add .lt-cmd-input-wrap:focus-within focus indicator (outline:none compensation)
- Add will-change: stroke-dashoffset to .lt-gauge-fill
- Add range slider :focus-visible thumb ring
- Fix .tok-cmt hardcoded #5c8c6a → var(--color-tok-cmt) w/ light-mode override
- Add .lt-skip-link component (visible on focus)
- Fix .lt-filter-group fieldset UA border reset

JS:
- Fix infinite scroll: store throttled handler ref so removeEventListener works
- Fix right drawer: remove close-button listeners in _rdClose (were never removed)
- Fix right drawer: add Tab focus trap (matches modal behaviour)
- Fix _cmdPaletteClose: restore focus to element that opened the palette
- Fix initSortTable: set aria-sort="ascending"/"descending"/"none" on th elements
- Fix switchTab: set aria-selected="true"/"false" on .lt-tab[data-tab] buttons
- Fix copy button timeout: guard with document.contains() before DOM mutation
- Fix combobox: add role=combobox, aria-expanded, aria-controls, role=listbox;
  toggle aria-expanded on open/close

HTML:
- Add skip nav link + id="main-content" on <main>
- Primary tab nav: add role=tablist, role=tab, aria-selected, aria-controls,
  id attrs; tab panels get role=tabpanel + aria-labelledby
- Tab bar demo: same ARIA wiring + aria-controls + role/labelledby on panels
- Sidebar filters: convert div+span to fieldset+legend for proper grouping
- Table sort headers: add aria-sort="none" (JS updates on click)
- Accordion: add aria-controls on headers, IDs on bodies
- Wizard: add aria-current="step" on active step indicator
- Table th: scope="col" on all column headers
- Row checkboxes: aria-label per ticket ID
- Worker metrics table: add <tbody>
- Progress bars: role=progressbar + aria-valuenow/min/max + aria-label
- Export + keyboard shortcuts modals: role=dialog, aria-modal, aria-labelledby

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 18:22:53 -04:00
jared 8585993602 merge: v1.1 feature branch → main
Merges all v1.1 work:
- 26 new components (theme toggle, right drawer, context menu, combobox,
  typeahead, split pane, wizard, sortable, lightbox, infinite scroll,
  countdown/stopwatch, markdown, auth, WebSocket, offline banner,
  avatar, timeline, skeleton variants, empty state, notification badge,
  chart containers, sidebar submenus, cookie utils, toast progress)
- Full mobile/responsive audit (50+ fixes, 8-breakpoint system)
- Complete light mode rebuild (professional, all components covered)
- lt.init() master initializer
- Bug fixes: duplicate function decls, clipboard crash, toast infinite
  recursion, kanban drag-and-drop, pagination module, notification
  dropdown, bulk actions dropdown, ticket detail editable form
- Cross-tab theme sync, color-scheme meta, WCAG table caption

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 00:12:24 -04:00
jared d5dc96178f feat: final production polish — light mode rebuild, lt.init(), cross-tab theme
Light mode — complete rebuild (section 51):
- Full token override for every surface, component, and state
- Desaturated accents: orange #c44e00, cyan #0062b8, green #006d35 etc.
- Glows replaced with subtle drop-shadow rings (no neon on white)
- Covers: toasts, modals, dropdowns, notification panel, context menu,
  right drawer, combobox, typeahead, wizard, timeline, pagination, tabs,
  badges, tables, code blocks, skeleton, avatar, sortable, markdown,
  scrollbars, buttons, nav drawer, WS status — nothing missed
- Dot-grid: neutral gray (was incorrect blue tint)
- Toast background uses var(--bg-overlay) instead of hardcoded dark rgba

Theme system improvements:
- _applyTheme now sets document.documentElement.style.colorScheme
- theme-color meta tag syncs on toggle (browser chrome follows theme)
- Cross-tab sync via storage event (toggle in one tab updates others)

lt.init() master initializer:
- Single call wires accordion, tooltip, alerts, clipboard, sidebar,
  submenus, and boot sequence
- Replaces 6+ individual .init() calls in user code
- demo HTML updated to use lt.init({ bootName: 'MY APP' })

Accessibility:
- Ticket table: add <caption class="lt-sr-only"> for WCAG compliance
- Table gets aria-label attribute

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 00:12:04 -04:00
jared 1d8d274fdd feat: comprehensive mobile/responsive audit fixes
Touch targets:
- All .lt-btn-sm, .lt-menu-btn, .lt-page-btn, .lt-dropdown-trigger,
  .lt-notif-bell-btn now 44px minimum on pointer:coarse devices

Font size floors:
- Nothing below 0.72rem on XS; nav drawer, cmd palette, stats, timeline,
  dropdown items, notification timestamps all bumped to readable sizes

Notification panel:
- width: min(300px,92vw) prevents overflow on 320px screens
- max-height: min(280px,calc(80vh-110px)) for landscape safety
- title: 2-line clamp instead of single-line truncate
- Header/time font sizes increased to 0.75rem/0.7rem

Dropdown panels:
- Advanced filter: clamp(200px,60vw,260px) instead of fixed 240px
- All dropdowns: max-width:90vw + proper alignment on SM/XS
- Dropdown items: 0.78-0.8rem, 36px min-height

Toolbar:
- toolbar-left/right now flex-wrap on SM+XS; search expands full-width
- Result count hidden on XS (.lt-hide-xs) to uncramp narrow toolbars

Drawer:
- Right drawer goes full-width (100vw) on SM with border-top
- Status/Priority 2-col form grid collapses to 1-col (.lt-drawer-form-grid)

Table card mode:
- Breakpoint corrected from rogue 640px → 767px (system breakpoint)
- Row min-height 36px, font bumped to 0.78rem

Kanban:
- Keeps 2-col at SM and XS (was collapsing to 1-col, confusing semantics)

Grids:
- Chart demo, sortable demo: auto-fit minmax so they reflow naturally
- Countdown stat grid: auto-fit minmax(160px,1fr) instead of fixed 3-col
- Grid gap reduced to var(--space-sm) at XS

Split pane:
- Demo height: clamp(160px,30vh,240px) instead of fixed 200px
- Stacks vertically on SM with horizontal divider

Modals:
- max-width: 640px cap prevents 4K-wide modals; overridden on SM/XS

Header:
- Brand title truncated at max-width:110px on XS
- WS status indicator hidden on XS to free header space
- Admin badge hidden on XS
- Safe-area insets applied to header-right and toast container

Landscape phone:
- Modal max-height respects viewport; notif list shrinks

Breakpoint consistency:
- Removed rogue 640px breakpoint; all queries use 479/767/1023/1279px system

Section 78 added with all targeted overrides.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 23:51:21 -04:00
jared 6ee9760168 fix: toast crash, notification dropdown, ticket detail editable, toolbar dropdowns
- Fix duplicate function showToast declaration causing infinite recursion
  (showToast declared twice → function hoisting → _origShowToast === self)
  Progress bar now inlined directly into _displayToast; Module 47 removed
- Notification bell now opens a proper dropdown panel with unread items,
  per-item click-to-read, "Mark all read", close on outside click/Esc
- Ticket detail drawer now has real editable fields (title, status,
  priority, assignee, description textarea, comment box) instead of
  read-only KV pairs; Save Changes and Post Comment buttons functional
- Advanced ▾ filter dropdown: status/priority/assignee selects + Apply/Reset
- Bulk Actions dropdown: Close/Reassign/Export/Delete with toast feedback
- Generic .lt-dropdown-trigger toggle system (works for any future dropdown)
- Add CSS sections 76 (notification panel) and 77 (dropdown widget + .lt-textarea)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 23:36:29 -04:00
jared 3847513594 fix: resolve DOMContentLoaded crash + wire kanban/pagination
- Fix lt.clipboard.init() → initCopyButtons() (crashed init handler
  before context menu, split pane, lightbox, theme btn could register)
- Add lt.pagination module (Module 55) with ellipsis rendering,
  prev/next, onChange callback; wire demo-pagination nav
- Upgrade lt.sortable for cross-list group dragging (shared module-level
  drag state enables kanban card movement between columns)
- Wire kanban columns (open/pending/inprogress/closed) to lt.sortable
  with group:'kanban' for drag-and-drop between columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 23:19:49 -04:00
jared 0c2e136cae Fix: resolve JS SyntaxErrors that crashed entire window.lt namespace
Root cause: two SyntaxErrors prevented the IIFE from completing,
meaning window.lt was never created and all features were broken.

Fixes applied:
1. CRITICAL: Renamed auth's apiFetch redeclaration → _apiFetchAuth
   (duplicate function declaration in strict-mode IIFE = SyntaxError)
2. CRITICAL: Renamed toast queue vars (_toastQueue/_toastActive already
   declared by original showToast in outer scope = SyntaxError)
   Replaced heavy queue wrapper with lightweight progress-bar injector
3. timer.countdown: classList.add(urgentClass) throws on space-separated
   class string — split/filter/forEach now used
4. contextMenu: _ctxItems declared as [] but used as string-keyed object
   — changed to {}
5. Split pane divider: background was border-dim (7% opacity, invisible)
   — raised to border-color (16%), added ::before hit-area expansion,
   hover state uses accent-cyan for clear visual feedback
6. Light theme: html background-image was hardcoded cyan rgba, didn't
   update with data-theme — added explicit html[data-theme="light"] rule
7. Light theme: .lt-header background was hardcoded rgba(3,5,8,0.96)
   — added explicit light-mode override

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 23:04:24 -04:00
jared 6ad4cb2354 v1.1: Complete remaining 8 feature modules + 7 CSS component sections
JS modules added:
- lt.sidebarSubmenus — nested nav groups with expand/collapse, auto-opens active
- lt.infiniteScroll  — IntersectionObserver-based (scroll fallback), loading indicator
- lt.wizard          — multi-step form with indicators, validation hook, getData()
- lt.sortable        — HTML5 drag-to-reorder lists with placeholder ghost + bus event
- lt.timer           — countdown (urgent threshold + onExpire) + stopwatch (pause/reset)
- lt.lightbox        — full-screen image viewer, prev/next, ESC, caption, loop
- lt.auth            — JWT token management: setToken, refresh (auto + manual),
                       401 retry, onExpire hook, patches lt.api with Bearer header
- lt.markdown        — micro-renderer (no deps); auto-delegates to window.marked /
                       markdownit if present; renders headings/bold/italic/code/
                       links/lists/blockquotes/tables/HR

CSS sections added (69–75):
- Infinite scroll sentinel + loading indicator
- Wizard step indicators (connectors, active/complete/error states, nav footer)
- Sortable item dragging + placeholder ghost
- Countdown/timer display + urgency blink animation
- Image lightbox overlay (close/prev/next controls, caption, counter)
- Sidebar submenu groups (chevron, expand/collapse, active sub-link)
- Markdown output styling (.lt-markdown — all block elements themed)

HTML demos for all 8 new components added and wired

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 22:42:16 -04:00
jared 0eb91f1937 v1.1: Add 10 new feature modules + 18 CSS component sections
JS modules added:
- lt.theme    — dark/light toggle, OS preference sync, localStorage persist
- lt.notif    — notification badge (set/inc/clear) on any element
- lt.rightDrawer — right-side detail panel with focus trap + return focus
- lt.contextMenu — right-click custom menu, keyboard nav, danger variant
- lt.offline  — navigator.onLine banner + event hooks
- lt.ws       — WebSocket manager with exponential backoff reconnect
- lt.combobox — multi-select with search, tag chips, keyboard nav
- lt.typeahead — async/sync autocomplete with match highlighting
- lt.cookie   — get/set/del with SameSite/Secure helpers
- lt.splitPane — pointer-events resizable split pane (horizontal/vertical)
- Toast queue: max-stack, progress bar drain animation, auto-drain

CSS sections added (51–68):
- Light theme (html[data-theme="light"]) with full variable overrides
- Theme toggle button (.lt-theme-btn)
- Skeleton loader variants (card, row, text, title, avatar, btn, badge)
- Empty state component (.lt-empty-state, --sm variant)
- Nav notification badge (.lt-notif-wrap / .lt-notif-badge)
- Right-side drawer (.lt-drawer-right + overlay)
- Sticky table header (.lt-table-sticky-wrap)
- Multi-select combobox (.lt-combobox, tags, dropdown)
- Context menu (.lt-context-menu, divider, label, danger)
- Offline banner (.lt-offline-banner)
- Timeline / activity feed (.lt-timeline, color variants)
- Avatar + avatar group + status ring (.lt-avatar)
- Split pane (.lt-split, .lt-split-divider with pointer drag)
- Chart container (.lt-chart-wrap, legend, axis, loading state)
- Toast queue stack + progress drain bar
- Autocomplete / typeahead (.lt-typeahead-dropdown, match highlight)
- WebSocket status indicator (.lt-ws-status, data-state variants)
- Print enhancements (extended @media print rules)

HTML demo sections for all new components added to base.html

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 22:29:55 -04:00
jared db67f0c92b v1.2 → v1.3: responsive overhaul, mobile nav, accessibility & bug fixes
- 8-breakpoint responsive system (xs→4k) replacing 3-breakpoint stub
- Off-canvas mobile nav drawer with swipe gestures and focus trap
- iOS-safe scroll lock for modals (position:fixed pattern + ref count)
- Modal focus trap with Tab cycling and return-focus to trigger
- Z-index stack overhaul: modal > nav drawer, toast above scanlines
- Fixed --border-dim CSS variable undefined across all v1.2 components
- Fixed badge absolute positioning clipping in Component Reference
- Fixed accordion CSS class mismatch (open → is-open)
- Fixed command palette selector/class mismatches
- Select dark mode: color-scheme:dark + option background
- 4K scaling: rem-based overrides for all hardcoded px elements
- Safe area insets for iPhone notch/home bar (viewport-fit:cover)
- Touch targets: 44px min on all interactive elements (pointer:coarse)
- Disabled glitch/pulse animations on coarse/hover:none devices
- Table responsive card mode with data-label attributes
- viewport.is() validation, debounce caching, 350ms orientation debounce
- initMobileNav() guard prevents duplicate listener registration
- cmd palette: input.select() on open, consistent scroll lock

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 18:47:26 -04:00
jared d7eb20cb3c Remove aesthetic_diff.md — convergence complete across all three apps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:49:18 -04:00
jared 997450aaf1 Fix boot sequence alignment, rate limiter memory leak, and docs gaps
- base.js: Fix boot sequence title centering — old formula was off by 1
  char for odd-length app names (PULSE, GANDALF). Remove unused `bar`
  variable. New logic computes left/right padding independently to
  handle both even and odd title lengths correctly.
- node/middleware.js: Prune expired rate-limit entries from Map when
  size exceeds 5000 to prevent unbounded memory growth. Also use
  req.socket?.remoteAddress as fallback for req.ip.
- README.md: Document lt.beep() in the JS API section. Clarify Quick
  Start to distinguish core files from platform-specific helpers.
  Note that tableNav.init() and sortTable.init() require explicit calls.
- aesthetic_diff.md: Correct §8 toast icon format — base.js uses
  bracketed symbols [✓][✗][!][i], not >> prefix as previously stated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:27:31 -04:00
jared 66538f9ad8 Initial commit: LotusGuild Terminal Design System v1.0
Unified CSS, JavaScript utilities, HTML template, and framework skeleton
files for Tinker Tickets (PHP), PULSE (Node.js), and GANDALF (Flask).

Includes aesthetic_diff.md documenting every divergence between the three
apps with prioritised recommendations for convergence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:08:57 -04:00