diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md
index 4a7881a..b782e2a 100644
--- a/.claude/CLAUDE.md
+++ b/.claude/CLAUDE.md
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
This is a **developer portfolio** whose primary audience is **recruiters and hiring managers**. Optimize every decision for demonstrating engineering skill, depth of work, and professional credibility — not for freelance/client conversion.
-**Design direction (APPROVED 2026-06-02, originally validated via a now-removed `mockups/v3` prototype): a design-forward developer portfolio with a signature ~2s monogram arrival animation, mobile-first.** Nima is a **frontend developer with a designer's eye** — positioned as a developer, NOT a designer. The site has designer-grade art direction (near-black + acid-lime `#C6FF3D`, Clash Display / Satoshi / Geist Mono) and a signature ~2-second arrival: an NH monogram strokes on → flies into the nav as the logo → name reveals behind masks → one acid-lime pop (once per session; instant under `prefers-reduced-motion`). Purposeful motion only (Lenis scroll, masked reveals, magnetic CTA). Structure: hero, Selected Work rows → case studies, a live-component Playground (engineering proof), About, contact. **Hard requirements:** beautiful on BOTH mobile and desktop (explicitly verified), full a11y (reduced-motion, keyboard, contrast). See the spec's "FINAL APPROVED DIRECTION" section for the build detail. Adds GSAP + Lenis.
+**Design direction (APPROVED 2026-06-02, originally validated via a now-removed `mockups/v3` prototype): a design-forward developer portfolio with a signature ~2s monogram arrival animation, mobile-first.** Nima is a **developer and AI engineer with a designer's eye** — positioned as a developer, NOT a designer. (Visible copy repositioned from "frontend developer" 2026-08-20; SEO surfaces had led since PR #16.) The site has designer-grade art direction (near-black + acid-lime `#C6FF3D`, Clash Display / Satoshi / Geist Mono) and a signature ~2-second arrival: an NH monogram strokes on → flies into the nav as the logo → name reveals behind masks → one acid-lime pop (once per session; instant under `prefers-reduced-motion`). Purposeful motion only (Lenis scroll, masked reveals, magnetic CTA). Structure: hero, Selected Work rows → case studies, About, contact. (A live-component Playground section existed until 2026-08 and was removed as filler.) **Hard requirements:** beautiful on BOTH mobile and desktop (explicitly verified), full a11y (reduced-motion, keyboard, contrast). See the spec's "FINAL APPROVED DIRECTION" section for the build detail. Adds GSAP + Lenis.
Abandoned explorations (all built + rejected, since deleted — the `mockups/` prototypes no longer exist): refined-minimal multi-page (`variant-a`) & long-scroll (`variant-b`) — too understated; high-craft editorial (`v2`) — too quiet/generic; interactive 3D galaxy (`cosmos`) — felt random/gimmicky. The react-three-fiber/3D direction is dead. The approved direction was the former `v3` prototype, now realized in the live app.
diff --git a/e2e/accent-contrast.spec.ts b/e2e/accent-contrast.spec.ts
index b90adbc..8ad1b5c 100644
--- a/e2e/accent-contrast.spec.ts
+++ b/e2e/accent-contrast.spec.ts
@@ -2,7 +2,7 @@ import { test, expect, type Locator } from '@playwright/test';
import { contrast, maxChannel, parseColorChannels } from './support/color';
// Regression guard for issue #3. The dark-on-lime sites (accent buttons, the
-// nav CTA, the selected segmented-control label) used to get their dark text
+// nav CTA, the work-row "In progress" tag) used to get their dark text
// color from `text-base` — the same utility that caused the invisible-heading
// footgun. The fix renames the color token to `dark`, so these now use
// `text-dark`. If a future edit drops `text-dark`, the text would fall back to
@@ -11,9 +11,8 @@ import { contrast, maxChannel, parseColorChannels } from './support/color';
// against the lime accent it sits on.
// The accent these elements sit on (`accent` in tailwind.config.ts, #C6FF3D).
-// Both targets are placed on it by design — the nav CTA via `bg-accent`, the
-// segmented label via an absolute sibling pill — so we check contrast against
-// this constant rather than walking the DOM for a background.
+// Both targets are placed on it by design via `bg-accent` — so we check
+// contrast against this constant rather than walking the DOM for a background.
const ACCENT = [198, 255, 61];
test.beforeEach(async ({ page }) => {
@@ -62,14 +61,15 @@ async function assertDarkOnLime(el: Locator, label: string) {
// the accent-button case for that component.
test('nav "Let\'s talk" CTA renders dark text on lime', async ({ page }) => {
await page.goto('/');
- await assertDarkOnLime(page.getByRole('link', { name: "Let's talk" }).first(), "nav Let's talk CTA");
+ await assertDarkOnLime(page.getByRole('link', { name: 'Let’s talk' }).first(), "nav Let's talk CTA");
});
-test('selected segmented-control label renders dark text on lime', async ({ page }) => {
+// The playground's segmented control (this spec's original second target) was
+// removed 2026-08; the work list's "In progress" tag is the remaining
+// dark-on-lime pill.
+test('work-row "In progress" tag renders dark text on lime', async ({ page }) => {
await page.goto('/');
- // The dark color lives on the inner text span; the sibling motion span is the
- // (aria-hidden) lime pill background.
- const selectedLabel = page.locator('[role="radio"][aria-checked="true"] span:not([aria-hidden])');
- await expect(selectedLabel).toHaveCount(1);
- await assertDarkOnLime(selectedLabel, 'segmented selected label');
+ const tag = page.getByText('In progress').first();
+ await expect(tag).toBeVisible();
+ await assertDarkOnLime(tag, 'work-row In progress tag');
});
diff --git a/e2e/arrival-motion.spec.ts b/e2e/arrival-motion.spec.ts
index 965704d..44475d8 100644
--- a/e2e/arrival-motion.spec.ts
+++ b/e2e/arrival-motion.spec.ts
@@ -10,7 +10,7 @@ import { test, expect } from '@playwright/test';
* reduced motion the stylesheet hides it before first paint and the unmount
* follows on a microtask.
* - Hero
Leses automatisk hver session, fra git root og cwd · path-spesifikke regler: .github/instructions/*.instructions.md med applyTo-glob · leser også CLAUDE.md
-
@@ -505,7 +490,6 @@
Skills: kunnskap on demand
Samme gate: custom agents (.agent.md, subagent med eget context window og begrensede tools)
-
@@ -549,7 +533,6 @@
Hvorfor hooks, og ikke bare prose?
permissionRequest
-
@@ -597,7 +580,6 @@
Sikkerhet
debug: /env viser lastede hooks · stdout → ~/.copilot/logs/ · lastes ved session-start · Windows: egne bash- og powershell-nøkler
-
@@ -635,7 +617,6 @@
Fra min egen verktøykasse
-
@@ -660,7 +641,6 @@
Sensors fanger opp etter
Dårlig output er ofte en manglende sensor.
-
@@ -676,7 +656,6 @@
Oppsummert
Åpen standard, aug 2026: Agent Plugins 1.0 · AWS · Anysphere · Microsoft · OpenAI · Vercel