Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@

# Pageclip API key for contact form
# Get your API key from https://pageclip.co/
VITE_PAGECLIP_API_KEY=your_pageclip_api_key_here
VITE_PAGECLIP_API_KEY=your_pageclip_api_key_here

# Optional: remote JSON base (production builds). Example:
# VITE_REMOTE_DATA_URL=https://data.example.com/data
#
# Optional: bypass localStorage cache for remote JSON (useful for testing).
# Set to "true" to always refetch.
# VITE_REMOTE_DATA_BYPASS_CACHE=true
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/content_update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ body:
attributes:
label: "Affected pages or sections"
description: "List routes, components, or assets that need updates."
placeholder: "Home hero copy, About bio, public/index.html gradient."
placeholder: "Home hero copy, About bio, public/fallback/index.html gradient."
validations:
required: true
- type: textarea
Expand Down
119 changes: 30 additions & 89 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,101 +1,42 @@
# Copilot / AI agent instructions (project-specific)
# Copilot / AI instructions

This file contains focused, actionable rules for automated coding agents working in the KR_Portf repository. Keep guidance short and specific — prefer small, safe edits and follow the project's conventions.
## Architecture

## Quick architecture & big picture
- Vite + React + TypeScript front-end served via Firebase Hosting. Entry points: `src/main.tsx` → `src/App.tsx` → `src/AppRouter.tsx`.
- UI components: `src/components/`; page sections: `src/sections/`; content/data: `src/data/` (e.g., `build.ts`, `projects.ts`).
- Theme and context providers: `src/providers/ThemeProvider.tsx`, `src/providers/theme-context.ts` and hook `src/hooks/useTheme.ts`.
- Tests and visual checks: Playwright + Vitest under `tests/` and `playwright.config.ts`.
- Astro + React + TypeScript portfolio template.
- Astro routes live in `src/pages/` (`index.astro`, `privacy-policy.astro`).
- Main UI and section composition remain in React (`src/App.tsx`, `src/sections/*`).
- Local content lives in `src/data/*` and translations in `src/translations/*`.

## Project-specific conventions (follow these)
- Compose Tailwind utility classes directly in JSX. Use PascalCase for components and camelCase for hooks.
- Visual style: rounded Material-like cards (`rounded-3xl`, `shadow-card`), warm orange/pink accents (`#f97316`, `#ec4899`), and `.font-kiya` for the printed name "Kiya Rose" (font located in `public/fonts`).
- Respect `prefers-reduced-motion`. Framer Motion is used; prefer short fade/slide transitions and provide reduced-motion fallbacks.
- Footer/legal: use `getBuildUpdatedAt()` from `src/data/build.ts` for the "Last updated" date — do not hard-code timestamps.
- Contact form: client-only `mailto:` generation plus copy-to-clipboard CTA (see `src/sections/ContactSection.tsx`).
## Core conventions

## Environment & secrets
- Environment variables use the `VITE_` prefix. Critical: `VITE_TURNSTYLE_SITE` is intentionally misspelled (no second "t"); do not rename it.
- Never commit secrets. Use `.env.local` locally and GitHub Secrets in CI.
- Keep the current visual layout and section order unless explicitly asked to redesign.
- Prefer small, focused edits; preserve accessibility and reduced-motion behavior.
- Use Tailwind utility classes in JSX and keep Material-like rounded card styling.
- Use `.font-kiya` for the display-name accent style.

## Common developer workflows & commands
- Install deps: `npm ci` or `npm install`.
- Dev server: `npm run dev` (Vite, http://localhost:5173).
- Lint: `npm run lint` (run before PR).
- Build: `npm run build` → `dist/` for Firebase Hosting.
- Local hosting preview: `firebase emulators:start --only hosting` (project has `firebase.json`).
- Run tests: `npm run test` (Playwright tests and other test runners configured in package.json).
## Remote data contract

## Places to inspect for examples and patterns
- Routing & layout: `src/App.tsx`, `src/AppRouter.tsx`.
- Footer/build label: `src/components/SiteFooter.tsx`, `src/data/build.ts` (localStorage prefix behavior).
- Contact flow: `src/sections/ContactSection.tsx` (mailto + clipboard behaviour).
- Theme logic: `src/providers/ThemeProvider.tsx`, `src/hooks/useTheme.ts`.
- Page-level sections: `src/sections/*` — follow their existing patterns for spacing, animation, and accessibility.
- `VITE_REMOTE_DATA_URL` enables remote JSON fetches.
- If no remote URL is set, use local fallback data only.
- On remote fetch failure, show placeholder data (do not silently swap to local fallback).
- Keep this behavior centered in `src/hooks/useRemoteData.ts`.

## Editing guidance for AI agents
- Make smallest useful change. Prefer a focused PR per issue.
- Preserve existing UX and data flows. If you change `src/data/build.ts` or footer code, preserve the localStorage build-label behavior unless explicitly fixing it.
- Avoid global CSS: adhere to Tailwind utility usage in JSX.
- When adding routes: update `src/AppRouter.tsx` and use `src/utils/navigation.ts` helpers.
## Build and test commands

## Tests & quality gates
- Before proposing changes: run `npm run lint` and `npm run build` locally.
- Test files live under `tests/` (e.g. `a11y.spec.ts`, `screenshot.spec.ts`); Playwright is used for integration/visual checks.
- Install: `npm ci`
- Dev: `npm run dev`
- Lint/type check: `npm run lint`
- Unit tests: `npm run test`
- E2E tests: `npm run test:e2e`
- Build: `npm run build`

## Native companion tool
- `$DashCam!/` holds a macOS Swift helper app used by developers to manage dev and playwright codegen tasks. If you modify related scripts, update the DashCam Swift sources under `$DashCam!/Sources/DashboardApp`.
## Deploy targets

## PR checklist for automated changes
- Lint passes (`npm run lint`).
- Build succeeds (`npm run build`).
- No secrets committed.
- Follow naming and Tailwind conventions.
- Cloudflare Pages: output `dist/`, config in `wrangler.toml`, headers in `public/_headers`.
- GitHub Pages: use `npm run build:pages` with `BASE_PATH=/your-repo-name/`.

If any section is unclear or you want more repo file examples, say which area to expand and I will iterate.
# Copilot Instructions
## Security

## Style & Architecture

- Keep the interface sleek and minimal with rounded Material-style cards, soft shadows, and translucent layers when depth is needed.
- Accent colors lean warm orange/pink (`#f97316` / `#ec4899`) in light mode while dark mode stays slate—mirror those tones in new UI or gradients.
- Use rounded Material Symbols for navigation, section headers, and social chips so iconography stays cohesive.
- Compose Tailwind utility classes directly in JSX; components follow PascalCase, hooks use camelCase, and class names remain lowercase-kebab.
- Respect `prefers-reduced-motion`, keeping Framer Motion animations subtle (short fade/slide transitions) and providing fallbacks for reduced motion preferences.
- Maintain the light/dark theme toggle with animated sun/moon icons and ensure contrast targets accessibility best practices.
- Apply the `.font-kiya` (Patrick Hand) accent whenever “Kiya Rose” appears in UI copy.
- Keep the footer’s legal line consistent: dynamic current year, typographic © symbol, `.font-kiya` "Kiya Rose", and the “Crafted with React, Tailwind CSS, and Firebase.” tag.
- Privacy and legal copy should source their “Last updated” value from `getBuildUpdatedAt()` in `src/data/build.ts` so the date reflects the current build—no hard-coded timestamps.
- Everything should be in Canadian English or French English when possible, when there are conflicting versions of a singular term use the more specific one. (For example cheque instead of check)

## Environment Variables

- Secrets use the `VITE_` prefix; note that `VITE_TURNSTYLE_SITE` (missing the second "t") is intentional and should not be renamed to `VITE_TURNSTILE_SITE`.

## Quality Expectations

- Prefer fixes that resolve lint warnings, TypeScript errors, and obvious UX problems rather than adding placeholders.
- When you touch code, scan the surrounding logic for latent bugs or smells and address them when feasible.
- Align fixes with the guidance used by DeepSource, CodeFactor, and SonarQube: eliminate dead code, handle edge cases, simplify complex conditionals, and tighten null/undefined guards.
- Preserve Firebase secrets by loading them from environment configuration—never commit credentials or hard-coded API keys.
- Ensure licensing references match the BSD 3-Clause notice in the project root `LICENSE` (copyright © 2025, Kiya Rose).
- Honor existing lint rules (avoid inline arrow handlers in JSX, limit nesting by extracting helpers, etc.).

## Collaboration Notes

- Favor small, composable helper components over deeply nested JSX trees (see `SiteHeader`/`SiteFooter` in `App.tsx`).
- When making UI changes, consider drag-and-drop persistence, localStorage access, the `mailto:` contact workflow, and other side effects already established in the repo.
- Use the existing `isDeveloping` styling in the Skills section when introducing new abilities (dashed border for in-progress skills).
- Keep the fallback page (`public/index.html`) visually aligned with the main palette when adjusting colors.
- Run `npm run lint` and (when relevant) `npm run build`; clean up generated `dist/` outputs if you run the build locally.
- Keep the build label helper in `src/data/build.ts` intact: it persists a random prefix per build signature in `localStorage`, so only adjust it if that behaviour breaks, and retain the accent tooltip that explains the two segments.
- Keep the macOS Swift companion `DashCam!` in `$DashCam!/`: it manages `npm run dev` and `npx playwright codegen` processes, so update `DashboardViewModel`/`ProcessController` plus the packaged `DashCam.app` or `dashcam_swift.tgz` whenever those workflows change.
- Route-level additions should flow through `src/AppRouter.tsx` with helpers from `src/utils/navigation.ts`; render privacy/legal pages inside React rather than shipping standalone static HTML.
- When you adjust repository guidance, update both `AGENTS.md` and this file so instructions stay in sync.
## Security & ZAP Scanning

- All security headers are centrally configured in `security-headers.config.ts` and deployed via `public/_headers` (Cloudflare Pages), `firebase.json` (Firebase Hosting), and `vite.config.ts` (local preview).
- The ZAP workflow scans `https://your.website` nightly; check `.zap-ignore` for known/accepted alerts.
- When ZAP reports issues, verify headers are in `public/_headers` and deployed properly before adding to `.zap-ignore`.
- Use `safeConsoleWarn()` and `safeConsoleError()` from `src/utils/errorSanitizer.ts` instead of raw console methods to prevent information disclosure.
- Keep security headers centralized in `security-headers.config.ts`.
- Keep parity checks working via `npm run verify:security-headers`.
- Use safe logging helpers in `src/utils/errorSanitizer.ts`.
2 changes: 1 addition & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This directory contains automated workflows for the portfolio project. Workflows
- **`security-headers-parity.yml`** - Security Headers Verification
- Verifies security headers are synchronized across:
- `security-headers.config.ts`
- `vite.config.ts`
- `astro.config.mjs`
- `public/_headers`
- `firebase.json`

Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ jobs:
- 'package-lock.json'
- 'yarn.lock'
- 'pnpm-lock.yaml'
- 'vite.config.ts'
- 'astro.config.mjs'
- 'eslint.config.js'
- 'tailwind.config.js'
- 'postcss.config.js'
- 'tsconfig.json'
- 'tsconfig.app.json'
- 'tsconfig.node.json'
- 'src/**'
- 'public/**'
- 'tests/**'
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/github-pages-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Deploy PR Preview to GitHub Pages

on:
pull_request:
branches: ["main"]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write
pull-requests: write

concurrency:
group: pages-preview-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm clean-install --progress=false

- name: Build
env:
BASE_PATH: /${{ github.event.repository.name }}/
run: npm run build:pages

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: dist

deploy:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages preview
id: deployment
uses: actions/deploy-pages@v4
with:
preview: true
12 changes: 6 additions & 6 deletions .github/workflows/github-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ name: Deploy to GitHub Pages
# If you are using this as a template for your own project you will need to
# update TWO values so that assets load from the correct path:
#
# 1. VITE_BASE_URL (in the Build step below)
# 1. BASE_PATH (in the Build step below)
# Set this to "/<your-repo-name>/" — include both slashes.
# Example: if your repo is "github.com/jane/my-portfolio", use "/my-portfolio/".
# If you are deploying to a root domain (e.g. https://jane.github.io) or a
# custom domain pointed at the repo root, set VITE_BASE_URL to "/" or
# custom domain pointed at the repo root, set BASE_PATH to "/" or
# remove the env block entirely.
#
# 2. The "base" value in vite.config.ts
# Normally this is driven automatically by VITE_BASE_URL above, so you
# 2. The "base" value in astro.config.mjs
# Normally this is driven automatically by BASE_PATH above, so you
# only need to change it if you want to hard-code the path instead of
# using the environment variable.
#
# The router (src/utils/navigation.ts) reads import.meta.env.BASE_URL at
# The navigation helper (src/utils/navigation.ts) reads import.meta.env.BASE_URL at
# runtime and strips the prefix automatically — no other files need changing.
# ---------------------------------------------------------------------------

Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
# TEMPLATE USERS: change /Portf/ below to /<your-repo-name>/ — or
# remove the env block entirely when deploying to a root domain.
env:
VITE_BASE_URL: /Portf/
BASE_PATH: /Portf/
run: npm run build:pages

- name: Upload Pages artifact
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-screenshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:

- name: Run Playwright tests (screenshots & accessibility)
run: |
npx playwright test tests/e2e.spec.ts tests/a11y.spec.ts
npx playwright test tests/screenshot.spec.ts tests/a11y.spec.ts tests/theme-consistency.spec.ts

- name: Upload artifacts
uses: actions/upload-artifact@v4
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/security-headers-parity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- 'security-headers.config.ts'
- 'public/_headers'
- 'firebase.json'
- 'vite.config.ts'
- 'astro.config.mjs'
- '.github/workflows/security-headers-parity.yml'
push:
branches:
Expand All @@ -15,7 +15,7 @@ on:
- 'security-headers.config.ts'
- 'public/_headers'
- 'firebase.json'
- 'vite.config.ts'
- 'astro.config.mjs'

permissions:
contents: read
Expand Down Expand Up @@ -49,7 +49,7 @@ jobs:
'The security headers are not synchronized across configuration files.\n\n' +
'Please ensure that:\n' +
'1. `security-headers.config.ts` contains the master configuration\n' +
'2. `vite.config.ts` imports from the master config\n' +
'2. `security-headers.config.ts` includes all required header keys\n' +
'3. `public/_headers` and `firebase.json` are updated to match\n\n' +
'See the workflow logs for details.'
})
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ coverage
node_modules/
dist/
dist-ssr/
.astro/
public/__remote-data/

# Tooling caches
.npm
Expand Down
3 changes: 1 addition & 2 deletions .lighthouserc.cjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/* eslint-env node */
module.exports = {
ci: {
collect: {
// Use local preview so PRs don’t rely on prod
startServerCommand:
"npm run build && npx vite preview --port 4173 --strictPort",
"npm run build && npm run preview -- --port 4173 --host 0.0.0.0",
url: ["http://localhost:4173/"],
numberOfRuns: 3,
},
Expand Down
Loading
Loading