diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..decdc51 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,188 @@ +# Alexander Sullivan's Portfolio - AI Coding Agent Instructions + +## Architecture Overview + +This is a **Next.js portfolio website** using the **App Router** (not Pages Router), React, TypeScript, and Material-UI with Emotion. The project follows a modular structure with path aliases, comprehensive testing, and Progressive Web App (PWA) capabilities. + +### Key Technologies & Integrations + +- **Framework**: Next.js App Router with React Server Components +- **Styling**: Material-UI (MUI) + Emotion (use `sx` prop, not CSS modules) +- **Testing**: Jest (unit tests), Cypress (E2E tests with accessibility via cypress-axe) +- **Monitoring**: Sentry error tracking, Firebase Analytics/Performance, Vercel Speed Insights +- **PWA**: Service Worker in `public/sw.js`, manifest via `src/app/manifest.ts` + +## Critical Workflows + +### Development Commands + +```bash +npm run dev # Start dev server at localhost:3000 +npm run validate # Full CI check: prettier → eslint → tsc → jest → cypress → build → markdown +npm run test:jest # Unit tests only +npm run test:cypress:e2e # E2E tests headless +npm run build # Production build +``` + +**Always run `npm run validate` before committing.** This is the comprehensive quality gate used in CI/CD. + +### Testing Requirements + +- **Unit tests**: Every component requires a `.test.tsx` file (see `src/components/banner/Banner.test.tsx`) +- **Test setup**: Uses `jest/setup.ts` with jsdom environment +- **E2E tests**: Located in `cypress/e2e/`, include accessibility tests (cypress-axe) +- **Coverage**: Run `npm run test:jest:coverage` for coverage reports + +## Project-Specific Conventions + +### Path Aliases (Critical!) + +Always use TypeScript path aliases defined in `tsconfig.json`: + +```typescript +import Avatar from '@components/banner/Avatar'; +// NOT '../components/banner/Avatar' +import { DELAYS } from '@constants/index'; +// NOT '../../constants' +import { isNetworkFast } from '@util/isNetworkFast'; +``` + +### Component Patterns + +#### Material-UI Styling + +Use `sx` prop for styling, never inline styles or CSS modules: + +```typescript + +``` + +#### SVG Icons Pattern + +SVGs are imported as React components via `@svgr/webpack`. See `src/images/icons.tsx`: + +```typescript +import Icon from './icons/example.svg'; +export const ExampleIcon = (props: SvgIconProps) => + ; +``` + +### Data Management + +Static data lives in `src/data/`: + +- `projects.ts`: Project portfolio with typed interface +- `publications.ts`: Academic publications +- `socials.ts`: Social media links +- `keywords.ts`: SEO keywords array + +### Constants Pattern + +Centralized constants in `src/constants/index.ts` with `as const` for type safety: + +```typescript +DELAYS.PROJECT_HOVER_VIDEO; // 1000ms before video plays on hover +THRESHOLDS.SNEEZE_TRIGGER_INTERVAL; // Easter egg triggers +NETWORK.SLOW_DOWNLINK_THRESHOLD; // Network performance checks +``` + +## Code Style & Quality + +### Linting & Formatting + +- **Indentation**: Tabs (not spaces) - enforced by ESLint +- **Line length**: No hard limit, use Prettier +- **Import sorting**: Handled by `@trivago/prettier-plugin-sort-imports` +- **Unused vars**: Prefix with `_` to ignore (e.g., `_unusedParam`) + +### ESLint Rules (see `eslint.config.js`) + +- Tabs for indentation (indent: ['error', 'tab']) +- Console logs allowed (`no-console: off`) +- Unused vars with `_` prefix ignored +- React hooks exhaustive deps enforced + +### TypeScript + +- **Strict mode**: Enabled in `tsconfig.json` +- **No implicit any**: All types must be explicit +- **React 19**: Uses new `react-jsx` transform +- Run `npm run tsc` to check types (no emit) + +## Next.js App Router Specifics + +### Metadata & SEO + +All metadata configured in `src/app/layout.tsx`: + +```typescript +export const metadata: Metadata = { + title: { template: `%s | ${metadataValues.title}`, default: metadataValues.title }, + keywords: seoKeywords, + openGraph: { ... }, + robots: { index: true, follow: true }, +}; +``` + +### Server Components vs Client Components + +- Default: Server Components (no `'use client'`) +- Client-only: Components with hooks, event handlers, browser APIs +- Example client component: `src/components/ServiceWorkerRegister.tsx` + +### Security Headers + +CSP and security headers configured in `next.config.js` headers() function. Includes: + +- X-Content-Type-Options: nosniff +- X-Frame-Options: DENY +- Strict-Transport-Security (HSTS) +- Content Security Policy for service workers + +## Special Features + +### Network Performance Optimization + +`src/util/isNetworkFast.ts` checks Network Information API to conditionally load heavy assets based on connection speed. + +### Easter Eggs + +- `src/helpers/aaaahhhh.ts`: Fun image replacement logic triggered by avatar interactions +- `src/helpers/ascii.ts`: Console ASCII art + +### Service Worker + +- Lives in `public/sw.js` and served via `src/app/sw.js/` +- Registration in `src/components/ServiceWorkerRegister.tsx` +- Used for PWA offline support + +## Firebase & Analytics + +Initialize Firebase only client-side (see `src/configs/firebase.ts`): + +```typescript +import { init, logAnalyticsEvent } from '@configs/firebase'; + +init(); // Call once on client mount +logAnalyticsEvent('event_name', { params }); +``` + +## Documentation + +Architecture docs in `docs/architecture/`: + +- `index.md`: System overview +- Component-specific docs for Avatar, Projects, Publications, etc. + +## Common Gotchas + +1. **Don't** import from relative paths - use path aliases +2. **Don't** forget to update tests when changing components +3. **Always** run `npm run validate` frequently when making changes diff --git a/.github/prompts/audit-docs.md b/.github/prompts/audit-docs.md deleted file mode 100644 index 9c7d72f..0000000 --- a/.github/prompts/audit-docs.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: 'Audit and Update docs/ Directory' -scope: 'repo' -targets: - - 'docs/' - - 'codebase' -labels: - - 'documentation' - - 'audit' - - 'mermaid' ---- - -**Purpose:** -While reviewing this #activePullRequest #changes, analyze the entire #codebase and ensure the #file:docs directory is accurate, up to date, and fully aligned with the current implementation. - ---- - -## HARD RULES (Do Not Violate) - -1. **No forward-looking or speculative content.** - - Do NOT generate a `roadmap.md`. - - Do NOT document planned features, hypothetical designs, or imagined improvements. - - Document only what exists in the current codebase. - -2. **No invented code.** - - Only reference functions, hooks, classes, types, modules, files, directories, system architecture & design or packages that actually exist. - - Verify existence before describing or linking anything. - -3. **No placeholder text or TODOs.** - - Do not create empty sections or stubs. - - Every sentence must be grounded in verifiable code. - -4. **No unnecessary rewriting of the entire system.** - - Only update documentation that is outdated, incorrect, incomplete, or missing. - ---- - -## Execution Order (IMPORTANT) - -1. **Audit `docs/` first** -2. **Only if `docs/` is already accurate**, then: - - Audit markdown files elsewhere in the repository (root or subdirectories) - - Audit in-code documentation/comments where clarity or accuracy is lacking - -Do **not** skip ahead. - ---- - -## What to Do - -### 1. Audit the `docs/` directory - -- Identify inaccuracies, outdated content, missing explanations, or architectural mismatches. -- Cross-reference source files, comments, directory structure, and actual behavior. - -### 2. Update documentation strictly based on verified code - -- Correct outdated statements. -- Add missing explanations grounded in the current implementation. -- Include **small, accurate code snippets** whenever explaining behavior, usage, or examples. - - Snippets must reference real code that exists within the codebase. - - No invented identifiers. - -### 3. Use **Mermaid diagrams extensively** - -- Proactively identify any section where a diagram would improve clarity. -- Include diagrams for: - - data flows - - module interactions - - component relationships - - lifecycle steps - - architectural overviews - - system interactions -- Use only diagrams that reflect **actual, current code** (no hypothetical structures). -- Prefer `flowchart`, `sequenceDiagram`, `classDiagram`, and `stateDiagram` when appropriate. - -### 4. Reference real files frequently using markdown links - -- Whenever referencing a file or module, **link directly to the file using proper markdown**: `[Description](relative/path/to/file.ts)` -- Confirm the file exists before linking. -- Use file links liberally so readers can immediately navigate to source. - -### 5. Maintain clarity and conciseness - -- Keep explanations self-contained and clear. -- Highlight real architectural decisions, assumptions, and edge cases. -- Avoid verbosity or speculative commentary. - -### 6. Apply changes directly (docs only) - -- Modify existing documentation files. -- Add new markdown files only when supported by real code. -- If creating a **new directory**: - - **a. Always create an `index.md`** - - Must provide an overview of the directory’s purpose and contents. - - **b. Create only files that correspond directly to real, existing code.** -- No speculative or forward-looking directories or files. - ---- - -## Final Step - -After completing all changes, run `npm run validate` from #file:package.json and ensure markdown linting passes cleanly. diff --git a/.github/prompts/audit-docs.prompt.md b/.github/prompts/audit-docs.prompt.md new file mode 100644 index 0000000..04532fd --- /dev/null +++ b/.github/prompts/audit-docs.prompt.md @@ -0,0 +1,176 @@ +--- +title: 'Audit and Update docs/ Directory' +scope: 'repo' +targets: + - 'docs/' + - 'codebase' +labels: + - 'documentation' + - 'audit' + - 'mermaid' +--- + +## Purpose + +While reviewing this #activePullRequest #changes, analyze the entire #codebase and ensure the #file:docs directory is accurate, up to date, and fully aligned with the current implementation. + +Documentation produced by this prompt must serve **two audiences simultaneously**: + +1. **Internal developers / maintainers** + - To understand system internals, architectural decisions, constraints, and design intent + - To preserve _why_ things were implemented the way they are and the _how_ behind the _what_ +2. **New or external developers** + - To understand how to use the system, APIs, and modules as tools + - To quickly navigate from documentation to implementation + +--- + +## HARD RULES (Do Not Violate) + +1. **No forward-looking or speculative content** + - Do NOT generate a `roadmap.md` + - Do NOT document planned features, hypothetical designs, or imagined improvements + - Document only what exists in the current codebase + +2. **No invented code** + - Only reference functions, hooks, classes, types, modules, files, directories, system architecture & design, or packages that actually exist + - Verify existence before describing or linking anything + +3. **No placeholder text or TODOs** + - Do not create empty sections or stubs + - Every sentence must be grounded in verifiable code + +4. **No unnecessary rewriting** + - Only update documentation that is outdated, incorrect, incomplete, or missing + - Preserve accurate documentation as-is + +--- + +## Execution Order (IMPORTANT) + +1. **Audit `docs/` first** +2. **Only if `docs/` is already accurate**, then: + - Audit markdown files elsewhere in the repository (root or subdirectories) + - Audit in-code documentation/comments where clarity or accuracy is lacking + +Do **not** skip ahead. + +--- + +## Documentation Style & Priorities (CRITICAL) + +### Description-first, Code-second + +When documenting behavior, architecture, or usage: + +1. **Start with a succinct natural-language explanation** + - Explain _what the component does_, _why it exists_, and _how it fits into the system_ +2. **Link directly to the implementation** + - Prefer links to real source files over inline code + - Example: + > The request validation logic is centralized in `validateRequest`, which enforces schema constraints before execution. + > See implementation in the corresponding source file (for example under `src/components/` or `src/util/`), and always link to a real file that exists in this repository. +3. **Use inline code blocks sparingly and intentionally** + - Include code snippets **only when they materially improve understanding**, such as: + - Public API usage examples + - Non-obvious control flow + - Critical invariants or edge cases + - Snippets must be: + - Small + - Accurate + - Directly copied or derived from real code + - Avoid restating large sections of implementation inline + +**Inline code should reinforce understanding — not replace navigation to source.** + +--- + +## What to Do + +### 1. Audit the `docs/` directory + +- Identify inaccuracies, outdated content, missing explanations, or architectural mismatches +- Cross-reference: + - Source files + - Directory structure + - In-code comments + - Actual runtime behavior + +--- + +### 2. Update documentation strictly based on verified code + +- Correct outdated or incorrect statements +- Add missing explanations grounded in the current implementation +- Clearly distinguish: + - **Conceptual behavior** (what/why) + - **Implementation details** (how) +- Prefer: + - **Explanation + file link** + - Over large inline code blocks + +--- + +### 3. Use Mermaid diagrams extensively + +Proactively identify any section where a diagram would improve clarity. + +Include diagrams for: + +- Data flows +- Module interactions +- Component relationships +- Lifecycle steps +- Architectural overviews +- System interactions + +Rules: + +- Diagrams must reflect **actual, current code** +- No hypothetical or idealized structures +- Prefer: + - `flowchart` + - `sequenceDiagram` + - `classDiagram` + - `stateDiagram` + +--- + +### 4. Reference real files frequently using markdown links + +- Whenever referencing a file, module, or subsystem: + - Link directly using relative paths + Example: `[Auth middleware](src/middleware/auth.ts)` +- Confirm the file exists before linking +- Use links liberally to encourage source exploration + +--- + +### 5. Maintain clarity and conciseness + +- Keep explanations focused and self-contained +- Explicitly document: + - Architectural decisions (use mermaid diagrams when applicable in addition to text) + - Constraints and limitations + - Trigger conditions + - Expected inputs and outputs + - Notable edge cases +- Avoid verbosity, repetition, or speculative commentary + +--- + +### 6. Apply changes directly (docs only) + +- Modify existing documentation files +- Add new markdown files **only when supported by real code** +- If creating a new directory: + - **Always include an `index.md`** + - Describe the directory’s purpose and contents + - Create files that map directly to existing code artifacts +- No speculative or forward-looking files or directories + +--- + +## Final Step + +After completing all changes, run `npm run validate` from #file:package.json and ensure markdown linting passes cleanly. diff --git a/.github/prompts/audit-quality.md b/.github/prompts/audit-quality.prompt.md similarity index 100% rename from .github/prompts/audit-quality.md rename to .github/prompts/audit-quality.prompt.md diff --git a/docs/architecture/app-directory.md b/docs/architecture/app-directory.md index abedc0b..e20424c 100644 --- a/docs/architecture/app-directory.md +++ b/docs/architecture/app-directory.md @@ -1,6 +1,6 @@ # App Directory (Next.js) -This document explains the Next.js App Router directory structure and implementation in the AlexJSully Portfolio project. +This document explains the Next.js App Router directory structure and implementation in the Alexander Sullivan's Portfolio project. ## Overview diff --git a/docs/architecture/components/index.md b/docs/architecture/components/index.md index 1757c2d..19cad3a 100644 --- a/docs/architecture/components/index.md +++ b/docs/architecture/components/index.md @@ -1,6 +1,6 @@ # Components Documentation -This document describes the internal architecture, relationships, and usage of major UI components in the AlexJSully Portfolio project. Components are modular, reusable, and styled with Material-UI and Emotion. +This document describes the internal architecture, relationships, and usage of major UI components in the Alexander Sullivan's Portfolio project. Components are modular, reusable, and styled with Material-UI and Emotion. ## Component List & Hierarchy diff --git a/docs/architecture/data.md b/docs/architecture/data.md index eea3926..bae2dea 100644 --- a/docs/architecture/data.md +++ b/docs/architecture/data.md @@ -1,85 +1,143 @@ # Data Architecture -This document explains how data is structured, managed, and integrated in the AlexJSully Portfolio project, with technical details and TypeScript interfaces. +This document explains how data is structured, managed, and integrated in the Alexander Sullivan's Portfolio project, with technical details and TypeScript interfaces. -## 📦 Data Sources +## Data Sources -### Static Data +All static data is centralized in [src/data/](../../src/data/) for consistency and maintainability: -- `src/data/projects.ts`: Project details (array of project objects) -- `src/data/publications.ts`: Publication details (array of publication objects) -- `src/data/socials.ts`: Social media links (array of social link objects) -- `src/data/keywords.ts`: SEO keywords (string array) +### Static Data Files + +- [**projects.ts**](../../src/data/projects.ts) — Project portfolio with employment history, personal projects, and showcase details +- [**publications.ts**](../../src/data/publications.ts) — Academic publications with DOIs, abstracts, and authors +- [**socials.ts**](../../src/data/socials.ts) — Social media links and contact information +- [**keywords.ts**](../../src/data/keywords.ts) — SEO keywords for search engine optimization ### Dynamic Data -- Firebase integration for real-time and remote data (see `src/configs/firebase.ts`) +- [Firebase integration](../../src/configs/firebase.ts) for analytics, performance monitoring, and real-time features (if configured) ## Data Flow ```mermaid sequenceDiagram - participant User - participant Page - participant Layout + participant Browser + participant NextJS[Next.js Server] participant Component - participant DataFile - User->>Page: Requests page - Page->>Layout: Loads layout - Layout->>Component: Renders components - Component->>DataFile: Imports data - DataFile-->>Component: Returns data - Component-->>Layout: Passes rendered output - Layout-->>Page: Passes rendered output - Page-->>User: Displays page + participant DataFile[Data Files] + + Browser->>NextJS: Request page + NextJS->>Component: Render component + Component->>DataFile: Import data (static) + DataFile-->>Component: Return typed data + Component->>Browser: Render with data + Component->>Browser: Initialize Firebase (client-side) + Browser->>Browser: Track user events ``` ## Data Usage in the Codebase -- Data files in `src/data/` provide static and dynamic content for components and pages. -- Components import data directly using TypeScript path aliases (e.g., `@data/projects`). -- Layouts and pages aggregate data from multiple sources for rendering. -- Dynamic data (e.g., from Firebase) is fetched in helper functions or via API routes, then passed to components as props. -- TypeScript interfaces ensure type safety and validation for all imported data. -- Data is used for: - - Rendering project lists, publication cards, and social links - - SEO metadata and keywords - - Navigation and page structure - - Analytics and user interaction tracking - -## 🧩 Data Structures & Interfaces - -- Data is exported as arrays/objects and imported into components using TypeScript path aliases. -- TypeScript interfaces define the structure and validation for each data type. - - Example: - - ```ts - // src/data/projects.ts - export interface Project { - id: string; - title: string; - description: string; - url: string; - tags: string[]; - } - export const projects: Project[] = [ ... ]; - ``` - -## 🔗 Integration & Usage - -- Components import data for rendering lists, cards, and details. -- Layouts use data for navigation and page structure. -- Data is tested and validated using TypeScript and Jest. - -## 🛠️ Extending Data - -- Add new data files in `src/data/`. -- Define TypeScript interfaces for new data types. -- Update components to consume new data as needed. - -## 🔗 Related Docs +- **Data Location:** All static data in [src/data/](../../src/data/) is imported directly into components +- **Type Safety:** TypeScript interfaces define strict types for each data structure +- **Path Aliases:** Components use aliases like `@data/projects` for clean imports (no relative paths) +- **No Runtime Validation:** Data is validated at compile time via TypeScript +- **Integration Points:** + - [ProjectsGrid](../../src/components/projects/ProjectsGrid.tsx) imports [projects.ts](../../src/data/projects.ts) + - [Publications](../../src/components/publications/Publications.tsx) imports [publications.ts](../../src/data/publications.ts) + - [Footer](../../src/components/footer/Footer.tsx) imports [socials.ts](../../src/data/socials.ts) + - [Root Layout](../../src/app/layout.tsx) imports [keywords.ts](../../src/data/keywords.ts) for SEO + +## Data Structures & Interfaces + +### Projects Interface + +Location: [src/data/projects.ts](../../src/data/projects.ts) + +```typescript +interface Projects { + name: string; // Project name + id: string; // Unique identifier + description?: string; // Optional description + employer?: string; // Company/organization name + employerURL?: string; // Company website + title: string; // Job/role title + publication?: string; // Publication URL + type?: string; // Employment, Personal Project, etc. + url: string; // Project URL + urls: Array<{ + // Links with icons and tooltips + text: string; + tooltip: string; + icon: (props: SvgIconProps) => React.ReactElement; + url: string; + }>; + color: string; // Hex color for card styling + dates?: { + // Optional date range + startDate: string; // YYYY-MM format + endDate: string; // YYYY-MM format + }; + showcase?: boolean; // Display in featured section + objectFit?: string; // Image fit (cover or contain) + youtubeURL?: string; // Optional YouTube embed +} +``` -- [Component Documentation](./components/index.md) -- [System Architecture](./index.md) +### Publications Interface + +Location: [src/data/publications.ts](../../src/data/publications.ts) + +```typescript +interface Publication { + title: string; // Publication title + authors: string[]; // List of author names + abstract: string; // Publication abstract + doi: string; // Digital Object Identifier + journal: string; // Journal/conference name + date: string; // Publication date (YYYY-MM-DD) + 'related-project'?: string; // Link to related project ID +} +``` + +### Socials Interface + +Location: [src/data/socials.ts](../../src/data/socials.ts) + +```typescript +interface Social { + name: string; // Social platform name + url: string; // Profile URL + icon: (props: SvgIconProps) => React.ReactElement; // Icon component + color: string; // Brand color +} +``` -💡 **Tip:** Use TypeScript interfaces for all data structures to ensure type safety and maintainability. +## Extending Data + +### Adding a New Project + +1. Open [src/data/projects.ts](../../src/data/projects.ts) +2. Add a new object to the `projects` array with required fields +3. Create a thumbnail at `public/images/projects/{project-id}/thumbnail.webp` +4. Ensure the `id` matches the folder name +5. Run `npm run validate` to verify TypeScript types + +### Adding a New Publication + +1. Open [src/data/publications.ts](../../src/data/publications.ts) +2. Add a new object with title, authors, abstract, DOI, and date +3. Optionally link to a related project using the `'related-project'` field +4. Run `npm run validate` to verify types + +### Adding New Keywords + +1. Open [src/data/keywords.ts](../../src/data/keywords.ts) +2. Add relevant SEO keywords to the array +3. Keywords are used in [src/app/layout.tsx](../../src/app/layout.tsx) for metadata + +## Related Docs + +- [Projects Component Documentation](./components/projects.md) +- [Publications Component Documentation](./components/publications.md) +- [System Architecture](./index.md) +- [Component Documentation](./components/index.md) diff --git a/docs/architecture/helpers.md b/docs/architecture/helpers.md index c18d2d3..0db7dd5 100644 --- a/docs/architecture/helpers.md +++ b/docs/architecture/helpers.md @@ -1,6 +1,6 @@ # Helpers Module Documentation -This document describes the purpose, architecture, and usage of helper functions in the AlexJSully Portfolio project, with technical details and integration patterns. +This document describes the purpose, architecture, and usage of helper functions in the Alexander Sullivan's Portfolio project, with technical details and integration patterns. ## Purpose @@ -8,19 +8,22 @@ Helpers provide reusable utility functions for formatting, logic, and data manip ## Structure -- Location: `src/helpers/` -- Example files: - - `ascii.ts`: Generates ASCII art for branding and fun UI elements. - - `aaaahhhh.ts`: Custom logic for playful UI interactions. -- Test files: - - `ascii.test.ts`: Unit tests for ASCII art generation. - - `aaaahhhh.test.ts`: Tests for custom logic. +**Location:** [src/helpers/](../../src/helpers/) + +### Available Helpers + +- [`ascii.ts`](../../src/helpers/ascii.ts) — Generates ASCII art for branding and fun UI elements +- [`aaaahhhh.ts`](../../src/helpers/aaaahhhh.ts) — Custom logic for playful UI interactions (Easter egg) ## Usage Examples ### ASCII Art Helper -```ts +**Location:** [src/helpers/ascii.ts](../../src/helpers/ascii.ts) + +Generates and logs ASCII art to the browser console on page load. + +```typescript import { consoleLogLogo, debounceConsoleLogLogo } from '@helpers/ascii'; // Print ASCII logo once @@ -30,7 +33,9 @@ consoleLogLogo(); debounceConsoleLogLogo(); ``` -The ASCII helper uses constants for timing: +**Implementation Details:** + +The ASCII helper uses constants for timing control: ```typescript import { DELAYS } from '@constants/index'; @@ -39,11 +44,18 @@ import { debounce } from 'lodash'; export const debounceConsoleLogLogo = debounce(consoleLogLogo, DELAYS.CONSOLE_LOGO_DEBOUNCE); ``` +**Integration:** + +- Called in [src/app/page.tsx](../../src/app/page.tsx) during `useEffect` initialization +- Uses `DELAYS.CONSOLE_LOGO_DEBOUNCE` (1000ms) to prevent duplicate logs on navigation + ### AAAAHHHH Easter Egg Helper -The `aaaahhhh` helper provides a playful page transformation triggered after multiple avatar sneezes: +**Location:** [src/helpers/aaaahhhh.ts](../../src/helpers/aaaahhhh.ts) + +The `aaaahhhh` helper provides a playful page transformation triggered after multiple avatar sneezes (6 total). This is the ultimate Easter egg! -```ts +```typescript import { aaaahhhh, convertAAAAHH, imageAAAAHHHH, textAAAAHHHH } from '@helpers/aaaahhhh'; // Trigger full page transformation @@ -63,49 +75,76 @@ imageAAAAHHHH(); ```mermaid flowchart TD - Trigger[aaaahhhh called] --> Text[textAAAAHHHH] - Trigger --> Images[imageAAAAHHHH] - Text --> Convert[convertAAAAHH] - Convert --> FirstHalf[First half → A] - Convert --> SecondHalf[Second half → H] - Images --> ReplaceImg[Replace all img src] - Images --> ReplaceBg[Replace backgrounds] + Trigger["Avatar sneezes
6 times"] --> AaaahhhhCall["aaaahhhh()"] + AaaahhhhCall --> Text["textAAAAHHHH()"] + AaaahhhhCall --> Images["imageAAAAHHHH()"] + + Text --> Convert["convertAAAAHH()"] + Convert --> FirstHalf["First half → A"] + Convert --> SecondHalf["Second half → H"] + + Images --> ReplaceImg["Replace img src"] + Images --> ReplaceBg["Replace bg images"] + + FirstHalf --> TextElements["Apply to: span, p, h1-h3, button"] + SecondHalf --> TextElements + + ReplaceImg --> ImageElements["All img & bg-image elements"] + ReplaceBg --> ImageElements + + TextElements --> Result["Aahh aaaaaahhhh!"] + ImageElements --> Result ``` **Text Conversion Logic:** - First half of word → 'A' (or 'a' if lowercase) - Second half of word → 'H' (or 'h' if lowercase) -- Spaces preserved -- Example: "Alexander" → "Aaaahhhhr", "SULLIVAN" → "AAAAHHHH" +- Spaces and special characters preserved **Image Transformation:** - Replaces all `` src and srcset attributes -- Replaces all background images in style attributes -- Updates the stars background (#sky) with cover image -- Uses `/images/aaaahhhh/aaaahhhh.webp` as replacement +- Replaces all CSS background images in style attributes +- Updates the stars background with cover image +- Uses `/images/aaaahhhh/aaaahhhh.webp` as replacement image **Target Elements:** -- Text: ``, `

`, `

`, `

`, `

`, `