- Migrate landing page and dashboard from Next.js 16 to Astro 5
- Remove Framer Motion dependency (saves ~122KB gzipped)
- Lazy-load Howler.js audio (only on power button click)
- Disable expensive CSS effects on mobile (<768px):
- backdrop-blur replaced with solid backgrounds
- Cloud animations simplified (no blur, static)
- Rain canvas and SpinnerLights skip on mobile
- Avatar filters reduced to grayscale+brightness
- Optimize hydration: client:idle for decorative components
- Combine Google Fonts requests (2 -> 1)
- Remove audio preloading (lazy-loaded instead)
- Fix process.env -> import.meta.env for Astro compatibility
- Update Languages icon from Swift logo to code brackets
- Unified card headers: gap-3, Icon size 20, text-accent color
- PlansCard: collapsible sections, animated expand/collapse
- update-plans-data.ts: export all plans (no limit)
- Replaced all em-dashes with colons or full sentences
- Content text standardized to text-lg across all cards
- FeatureCard, ArchHighlight descriptions adjusted
Add fetchGitHubSocialAccounts() using /users/{login}/social_accounts API
as primary source. Validate Mastodon domains via NodeInfo instead of
blocklists. Add 5s timeouts to all fetch calls. Expand known instances
list. Skip cross-verification for authoritative sources (github, keybase).
Full refresh now clears cache to prevent stale false positives.
Performance & memory:
- HeroTerminal: fix setInterval one-time random (now recursive setTimeout),
reuse single Howl for seeks, track all timers via pendingTimersRef
- RainOverlay: cap at 30fps, skip on prefers-reduced-motion
- SpinnerLights: pre-compute boxShadow at spawn, nextId in useRef
- Remove eager audio preloads from <head> (Howler loads lazily)
- CloudBackground: remove unnecessary 'use client' (now Server Component)
Type safety & correctness:
- Import BootStep/SchoolStep/JoshuaStep/TerminalEntry from terminal-parser
instead of duplicating interfaces; typed terminal-data.ts export
- ThemeProvider: isTheme() type guard replaces unsafe 'as Theme' casts,
instanceof guard for event.target, try/catch on localStorage.setItem
- useCopyToClipboard: cancel previous timer on rapid clicks, try/catch
around clipboard API, cleanup on unmount
- TerminalScreen: use config.initialCursorDelay instead of magic 18000,
type predicate for filter(), track glitch reset timer for cleanup
Accessibility (WCAG):
- prefers-reduced-motion: global CSS rule + JS skip in Rain/Spinner/Glitch
- aria-hidden on decorative elements (Rain, Spinner, Clouds)
- focus-visible ring on ThemeSwitcher, CodePreview, PackageBadge buttons
- aria-pressed on active theme button, nav aria-label, main tabIndex
Code quality:
- Extract useCopyToClipboard hook (CodePreview + PackageBadge)
- bg-frosted-glass CSS utility replaces 3x inline color-mix
- hover:bg-white/* → hover:bg-foreground/* for theme consistency
- Remove dead zoomed prop, stale eslint-disable, move lineRefsRef up
- import type for ReactNode in FeatureCard
- Remove 'as const' from generated terminal-data.ts
- Add type assertion for INTERACTIONS array to fix TypeScript error
- Fixes production build failure with readonly type mismatch
- Create terminal-parser.ts to parse terminal-script.md
- Add build script (generate-terminal-data.ts) to convert markdown to TypeScript
- Refactor TerminalScreen.tsx to use generated data instead of hardcoded arrays
- Add prebuild script to package.json for automatic data generation
- Install tsx and @types/howler dev dependencies
- Fix parser to preserve spacing in COUNTER prefix (Memory Test: )
- Update terminal-script.md documentation with [INLINE] tag explanation
Now terminal content can be edited in markdown without touching TypeScript:
1. Edit terminal-script.md
2. Run: npx tsx scripts/generate-terminal-data.ts
3. Reload browser - changes are live