# creeer Landing Additions — Header + Cómo empezar + Footer — Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add a minimal sticky Header, a new "Cómo empezar" on-ramp section (section 07), and a slim Footer to the existing 7-section `creeer` landing page. **Architecture:** Three additive pieces reusing the existing primitives (`Wordmark`, `CTA`, `Container`), tokens, the `motion` + `motionProps(reduced)` pattern, and the copy-in-`lib/content.ts` convention. Header and Footer are static server components wrapping `
`; `ComoEmpezar` is a client section following the exact pattern of `Mecanismo.tsx`/`Disciplinas.tsx`. Cierre becomes section 08. No backend, no forms — the site stays a static export. **Tech Stack:** Next.js 14 (App Router, `output: export`), React 18, TypeScript, Tailwind CSS 3.4, Framer Motion 11. Tests: Vitest + @testing-library/react. ## Global Constraints (Copied from the spec `docs/superpowers/specs/2026-07-21-creeer-landing-additions-design.md` — apply to every task.) - **Wordmark** always via the `Wordmark` primitive — never re-implemented, never uppercased. - **Paleta (tokens):** `ink #0A1F44` · `gold #B8901f` (accents on LIGHT) · `gold-bright #D4AF37` (accents on DARK) · `base #FBFAF7` (light bg, class `bg-base`) · dark bg class `bg-bg-dark` · `cream` (text on dark) · `muted`/`muted-dark`. - **Tipografía:** Georgia italic (`font-serif italic`) = wordmark + section titles; Inter = body/UI. - **Sin backend, sin formularios** — contacto solo por enlaces directos (WhatsApp/mailto/LinkedIn). - **Un único `

`** en toda la página — vive en el Hero. New pieces use `

`/`

` or no heading. - **Todo el copy** vive en `lib/content.ts` (nuevas claves `header`, `comoEmpezar`, `footer`). - **Voz** en segunda persona, español. - **Reduced motion:** every Framer Motion element gets `{...motionProps(reduced)}` after its `initial`/`whileInView`/`viewport` props (`reduced = usePrefersReducedMotion()`). Header/Footer are static (no motion). - **`tsconfig.json` has no `target`** → avoid ES2018+ regex flags (`s`/dotAll) or `tsc --noEmit` fails. ## File Structure ``` components/ ├── layout/ │ ├── Header.tsx # Task 1 — sticky bar (server component) │ ├── Footer.tsx # Task 3 — slim footer strip (server component) │ └── __tests__/ │ ├── Header.test.tsx # Task 1 │ └── Footer.test.tsx # Task 3 └── sections/ ├── ComoEmpezar.tsx # Task 2 — section 07 (client, motion pattern) └── __tests__/ └── ComoEmpezar.test.tsx # Task 2 lib/content.ts # Tasks 1/2/3 append `header` / `comoEmpezar` / `footer` app/page.tsx # Tasks 1/2/3 wire the pieces; Task 4 anchor offset components/sections/Cierre.tsx # Task 4 — add scroll-mt to the #contacto anchor ``` Each component task also wires itself into `app/page.tsx` (matching the repo's established incremental-compose pattern), so the page stays working after every task. --- ### Task 1: Header (minimal sticky) **Files:** - Create: `components/layout/Header.tsx` - Create: `components/layout/__tests__/Header.test.tsx` - Modify: `lib/content.ts` (append `header`) - Modify: `app/page.tsx` (place `
` before `
`) **Interfaces:** - Consumes: `Wordmark` (`size`, `onDark`), `CTA` (`href`, `label`, `variant`), `Container`, and `header.cta` from content. - Produces: `Header()` at `components/layout/Header.tsx` — no props. Consumed by `app/page.tsx`. - [ ] **Step 1: Append the `header` copy to `lib/content.ts`** Add at the end of `lib/content.ts`: ```ts export const header = { cta: 'Hablemos', // short nav CTA → #contacto (the full CTA lives in Hero/Cierre) }; ``` - [ ] **Step 2: Write the failing test `components/layout/__tests__/Header.test.tsx`** ```tsx import { render, screen } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; import { Header } from '../Header'; describe('
', () => { it('renders the wordmark', () => { const { container } = render(
); expect(container.textContent).toContain('creeer'); }); it('renders a persistent CTA linking to the contact section', () => { render(
); const cta = screen.getByRole('link', { name: /Hablemos/i }); expect(cta).toHaveAttribute('href', '#contacto'); }); }); ``` - [ ] **Step 3: Run the test to verify it fails** Run: `npm test -- Header` Expected: FAIL with "Cannot find module '../Header'". - [ ] **Step 4: Write `components/layout/Header.tsx`** ```tsx import { Wordmark } from '@/components/primitives/Wordmark'; import { CTA } from '@/components/primitives/CTA'; import { Container } from '@/components/primitives/Container'; import { header } from '@/lib/content'; export function Header() { return (
); } ``` Notes: server component (no `'use client'`, no motion — `position: sticky` is pure CSS). `#top` is the special top-of-document fragment (no element with that id is required). The `CTA` primitive appends the `→`, so `header.cta` holds just the word. - [ ] **Step 5: Run the test to verify it passes** Run: `npm test -- Header` Expected: PASS, 2 tests. - [ ] **Step 6: Wire `
` into `app/page.tsx`** Add the import after the existing section imports (top of the file): ```tsx import { Header } from '@/components/layout/Header'; ``` Then insert `
` between the JSON-LD `