Cosa entra nel briefing
Adesso ti serve una cosa sola: trasformare quello che hai deciso in qualcosa che un agente possa eseguire. Non un altro documento da leggere in riunione — un file che dai a Claude Code e da cui esce l’app.
Il materiale c’è già tutto, e sta in tre pezzi.
- docs/ux-ui.md · Parte 1
- Prodotto, utente, azione principale, MVP, le dieci schermate, le decisioni chiuse, gli stati, i criteri di fine.
- Il progetto che gira · Parte 3
- Next.js e shadcn/ui già montati: l’agente aggiunge componenti dentro un impianto che esiste.
- docs/ui.md · Parte 4
- La direzione estetica in valori: colore, tipografia, forma, profondità, movimento, e la lista di quello che è vietato.
Sono decisioni. Un agente ha bisogno di istruzioni: quello che il briefing non scrive, lo inventa. Quindi i tre pezzi diventano un file solo — il capitolato che daresti a uno studio esterno, con una differenza: uno studio, quando non capisce, telefona.
Qui ci fermiamo a quel file: questa parte lo scrive e te lo consegna. L’app arriva subito dopo, quando glielo dai da eseguire.
Gli otto blocchi del briefing
Il posto è questo: la casella di Claude Code, aperto dentro la cartella del progetto.
Leggi docs/ux-ui.md e docs/ui.md e scrivimi docs/prototipo.md:
il briefing con cui costruiremo il prototipo.
Otto blocchi, in quest'ordine:
1. <role> chi sei, cosa guardi per primo
2. <project> prodotto, lingua, confini chiusi
3. <information-architecture> le schermate e la navigazione
4. <screen-specs> cosa c'è dentro ogni schermata
5. <design-system> colore, forma, movimento, vietato
6. <mock-data> i contenuti finti, elencati
7. <implementation-plan> in che ordine si costruisce
8. <acceptance-criteria> quando è finito
Prima di scrivere, dimmi cosa manca nei documenti. Questa è la forma, ed è fissa: da progetto a progetto cambiano i contenuti, non l’ordine e non i nomi. Blocco per blocco, cosa ci va dentro e da dove esce:
- 1
<role>Chi deve essere, e cosa guarda prima di toccare un file.
La parte 3: stack, versione di Tailwind, componenti installati, token esistenti.
- 2
<project>Cos’è il prodotto, in che lingua parla, cosa non si tocca.
Punti 1-4 e 6 di docs/ux-ui.md. Le decisioni chiuse diventano qui la parola «locked».
- 3
<information-architecture>Quante schermate ci sono e come si passa da una all’altra.
Punto 5 del documento, tradotto in rotte, più la navigazione su telefono e su schermo grande.
- 4
<screen-specs>Cosa c’è dentro ogni schermata, in che ordine, con quali stati.
Sempre il punto 5, espanso: una riga del documento diventa mezza pagina. È il blocco più lungo.
- 5
<design-system>Che aspetto ha, come si comporta, cosa è vietato.
docs/ui.md per intero, più pulsanti, schede, campi, icone, immagini, movimento.
- 6
<mock-data>Con quali contenuti si riempie.
Il punto 8 del documento diventa un elenco: diciotto animali, sei match, quattro conversazioni vere.
- 7
<implementation-plan>In che ordine si costruisce.
Token, pezzi condivisi, poi le schermate nell’ordine in cui il cliente le cliccherà.
- 8
<acceptance-criteria>Quando è finito.
Punto 10 di docs/ux-ui.md, riscritto in caselle che si spuntano guardando lo schermo.
Il prompt che scrive il prompt
La versione lunga di quella riga: stessa richiesta, più le regole con cui riempire gli otto blocchi. Il briefing non si scrive a mano — lo scrive Claude Code, che i tuoi documenti ce li ha già nel progetto.
Il prompt che scrive il briefing Gli otto blocchi più le regole con cui riempirli
Leggi docs/ux-ui.md e docs/ui.md. Sono la fonte: ogni riga che
scriverai deve poter essere ricondotta a loro.
Scrivimi docs/prototipo.md: il briefing unico che darò a un agente perché
costruisca il prototipo navigabile dentro questo progetto. Non è un riassunto
dei due documenti, è la loro espansione in istruzioni eseguibili.
Otto blocchi, in quest'ordine, ognuno dentro il suo tag:
<role> chi deve essere l'agente e cosa deve leggere del progetto PRIMA di
scrivere codice: stack, versione di Tailwind, componenti già installati, token
esistenti. In fondo, l'inquadramento: questo è un prototipo per una demo, non
software di produzione — la qualità visiva conta più della purezza
dell'architettura, e nessuna schermata resta incompiuta solo perché la logica
sotto è finta.
<project> il prodotto in dieci righe, la lingua delle stringhe, il modello dei
dati e i confini marcati come CHIUSI, e i criteri di successo scritti come una
camminata: cosa deve riuscire a fare da solo chi non ha mai visto il prodotto.
<information-architecture> l'elenco completo delle schermate con, per ognuna,
il lavoro che fa; più come si naviga su telefono e su schermo grande.
<screen-specs> una sezione per schermata: cosa contiene, in che ordine, con
quali stati vuoti e di errore. È il blocco più lungo e va scritto come tale.
<design-system> docs/ui.md per intero, più le parti che lì non c'erano: come si
comportano pulsanti, schede, campi ed etichette; il movimento; le icone; le
immagini; e l'elenco esplicito delle cose vietate.
<mock-data> i dati finti, elencati: quanti, con quali campi, con che nomi e con
che tono. Nessuna schermata deve poter nascere vuota.
<implementation-plan> in che ordine si costruisce, dai token alle schermate, e
le schermate nell'ordine in cui verranno mostrate a chi guarda la demo.
<acceptance-criteria> caselle da spuntare guardando lo schermo, non leggendo il
codice.
Regole:
- Espandere sì, contraddire no. Ogni valore di docs/ui.md entra così com'è.
Dove serve un valore che i documenti non fissano, scegline uno coerente e
scrivilo; ma non cambiare mai uno di quelli che ci sono.
- La messa in scena la puoi inventare: composizioni, decorazioni, microcopy,
dettagli di movimento. Il prodotto no: schermate, funzioni, modello dei dati
e cosa resta fuori dall'MVP vengono dai documenti. Se ti serve una decisione
di prodotto che lì non c'è, fermati e chiedimela.
- Niente aggettivi dove può esserci un valore: pixel, codici colore,
millisecondi, nomi di classe. "Moderno" e "pulito" non sono istruzioni.
- Scrivi il briefing in inglese, tranne le stringhe visibili del prodotto, che
restano in italiano anche dentro il briefing.
- Non accorciare per cortesia: se un blocco viene lungo, viene lungo.
Alla fine elencami le decisioni che hai preso al posto mio e le domande a cui i
documenti non rispondono. Il risultato, e il file che l’ha prodotto
Questo è quello che c’era sullo schermo un’ora dopo, dando quel briefing a Claude Code e lasciandolo lavorare.
Il file che l’ha prodotta è questo. Salvalo nel progetto come docs/prototipo.md e daglielo da eseguire.
docs/prototipo.md Otto blocchi, dieci schermate, un design system intero
<role>
You are an expert frontend engineer, UI/UX designer, visual design specialist, and typography expert. Your goal is to help the user turn an existing component-library boilerplate into a high-fidelity, client-presentable product prototype, applying a design system in a way that is visually consistent, maintainable, and idiomatic to the stack.
Before proposing or writing any code, first build a clear mental model of the current system:
- Identify the tech stack (React, Next.js App Router, TypeScript, Tailwind, shadcn/ui, etc.) and the exact Tailwind major version, since token syntax differs between v3 (`tailwind.config.ts`) and v4 (`@theme` in CSS).
- Inventory which shadcn/ui components are already installed and read their `cva` variant definitions before changing them.
- Understand the existing design tokens (colors, spacing, typography, radii, shadows), global styles, and utility patterns.
- Review the current component architecture (atoms/molecules/organisms, layout primitives) and naming conventions.
- Note any constraints (pre-existing CSS, bundle size, which icon library is wired up).
Then confirm scope with the user before writing code. In this project the scope is fixed and stated below, so read it, restate it in one or two sentences, flag any conflict you find between the brief and the design system, and proceed.
Once you understand the context and scope:
- Propose a concise implementation plan that prioritizes centralizing design tokens, reusability and composability of components, minimizing one-off styles, and clear naming.
- Match the user's existing patterns (folder structure, naming, styling approach, component patterns).
- Explain your reasoning briefly as you go, so the user understands *why* you are making each architectural or design choice.
Always aim to:
- Preserve or improve accessibility.
- Maintain visual consistency with the provided design system.
- Leave the codebase in a cleaner, more coherent state than you found it.
- Ensure layouts are responsive and genuinely usable on both mobile and desktop.
- Make deliberate, creative design choices (layout, motion, interaction details, typography) that express the design system's personality instead of producing a generic or boilerplate UI.
**Critical framing for this specific project:** this is a *demo prototype*, not production software. Its single job is to make a client say "wow" within thirty seconds of seeing it. Visual and interaction quality outrank architectural purity, data correctness, and completeness. Never ship an empty state where seeded content could be shown instead. Never leave a screen visually unfinished because the underlying logic is fake — the logic is *supposed* to be fake.
</role>
<project>
# PAWSOUL — "Tinder for dogs and cats"
## What it is
A pet-matching app. An owner registers their dog and/or cat, then swipes as that pet on other nearby pets. A mutual like is a match, which opens a chat where the two owners arrange a meetup. Any pet profile can additionally be flagged **"Disponibile per adozione"**, which surfaces it in an adoption-filtered deck — so one single data model serves both playdates and adoption.
- **Brand**: PAWSOUL
- **Tagline**: *"Trova la sua anima gemella"*
- **Copy language**: **Italian**, for every string in the product — nav, forms, buttons, bios, chat messages, empty states, error text, marketing copy. Only the brand name and a small set of display labels stay English.
## Match model (locked — do not redesign)
Symmetric, pet-to-pet. Everyone who signs up creates at least one pet profile and swipes as that pet. There is **no** shelter role, **no** admin back-office, and **no** asymmetric adopter/lister split. Adoption is a boolean flag on a pet profile plus a deck filter, nothing more.
## Scope (locked)
**UI/UX only.** No backend, no database, no real authentication, no real file uploads, no external API calls at runtime beyond loading remote images.
- Auth is **fake**: any email and any password succeed. Signup routes to onboarding; login routes to the dashboard.
- Session and app state live in React Context, persisted to `localStorage`.
- All content comes from local mock data modules.
- Every screen must be reachable and complete. A client walking through the demo must never hit a dead end, a blank list, or a "coming soon".
## Success criteria
The prototype is successful if a non-technical client, handed a laptop and a phone, can:
1. Land on the marketing page and immediately understand the product.
2. Sign up, complete onboarding for a dog, and see that dog's finished swipe card.
3. Swipe a deck with their finger or mouse, trigger a match, and land in a conversation that already has messages in it.
4. Add a cat as a second pet and switch the active pet.
5. Do all of the above on a phone and on a 1440px laptop without either layout looking like an afterthought.
</project>
<information-architecture>
## Routes (10 — this is the complete list)
| Route | Auth | Job to be done |
|---|---|---|
| `/` | public | Marketing landing. First impression, explains the product, drives signup. |
| `/signup` | public | Create an account (fake). |
| `/login` | public | Return to an account (fake). |
| `/onboarding` | fake-auth | Register a pet. Single route, 7 internal steps, client-side state. |
| `/app` | fake-auth | Dashboard. Orient the user: new matches, activity, stats, active-pet switcher. |
| `/swipe` | fake-auth | **The hero screen.** The card deck. |
| `/matches` | fake-auth | Match list + conversation. Desktop = 3-pane. Mobile = list only. |
| `/matches/[id]` | fake-auth | Single conversation. Mobile route; on desktop it redirects to `/matches` with that thread selected. |
| `/pets/[id]` | fake-auth | Full pet profile. Reached from the deck, from a match, or from the adoption band on the landing page. |
| `/profile` | fake-auth | My pets, add a pet, preferences, settings, logout, demo reset. |
## Navigation pattern
- **Mobile (`< 1024px`)**: fixed bottom tab bar, 4 items — `SCOPRI` (`/swipe`), `MATCH` (`/matches`, with an unread count badge), `HOME` (`/app`), `PROFILO` (`/profile`). Tab bar is `bg-[#FFFDF5] border-t-4 border-black`. The active tab is a filled colored square behind the icon, not a tint. Top of screen gets a compact bordered app bar with the logo and a notification bell.
- **Desktop (`>= 1024px`)**: sticky top nav, `border-b-4 border-black`, logo left, nav center, active-pet avatar + notification bell right. No bottom bar.
- **Public routes** use a different nav: logo left, marketing links center, `ACCEDI` (outline) + `ISCRIVITI` (red, hard shadow) right. Mobile hamburger is a bordered square button opening a full-screen menu of stacked bordered buttons.
- Include a small `RESET DEMO` control in the authenticated nav (or profile page) that clears `localStorage` and re-seeds — so the walkthrough can be re-run live in front of the client.
</information-architecture>
<screen-specs>
## 1. `/` — Landing
Section order, top to bottom. Every section is separated by `border-b-4 border-black` and alternates background color for rhythm.
1. **Public nav** — as described above.
2. **Hero** — asymmetric 60/40 split, not 50/50. Background cream with a halftone dot overlay.
- Left: display headline broken across three lines with mixed treatment — `TROVA LA SUA` in solid black, `ANIMA` in a red bordered box rotated `-rotate-2`, `GEMELLA` rendered as outlined text (`-webkit-text-stroke: 3px #000; color: transparent`). Subhead: *"Cani e gatti che cercano un amico. O una casa."* Two CTAs: `ISCRIVITI GRATIS` (red, `shadow-[8px_8px_0px_0px_#000]`) and `COME FUNZIONA` (outline). Below, a trust row of three bordered stat chips: `12.480 MATCH` · `3.200 ADOZIONI` · `87 CITTÀ`.
- Right: a **live, draggable 3-card mini deck** — the real swipe component, not a static image. The client can swipe it before signing up. Surround it with rotated sticker badges (`BAU!`, `MIAO!`, a violet star) positioned absolutely and overlapping the card edges.
3. **Marquee band** — full-width black strip, white 900 uppercase text scrolling horizontally: `BAU • MIAO • BAU • MIAO •` repeating. Pure texture, high payoff.
4. **Come funziona** — three bordered white cards, each with a giant step number inside a violet circle rotated `rotate-3`, a HugeIcons icon in a bordered red square, a bold title, and two lines of body. Cards stagger vertically on desktop (`lg:translate-y-*`) so the row is not flat.
5. **Cane vs Gatto** — hard 50/50 color block, no gap between halves. Left half `bg-[#FF6B6B]`, right half `bg-[#C4B5FD]`. Each half: a full-color photo in a thick black border, a species wordmark, and a list of species-specific traits with check icons. This section exists specifically to prove the product is built for both species, not a dog app with cats bolted on.
6. **Adozione band** — `bg-[#FFD93D]` with grid-pattern overlay. Headline *"OGNI ZAMPA MERITA UN DIVANO"*. A 4-up grid of adoptable pets, each card carrying a rotated `SOLO ADOZIONE` badge in the corner. CTA `SFOGLIA LE ADOZIONI`.
7. **Testimonianze** — three cards rotated at different angles (`rotate-1`, `-rotate-2`, `rotate-2`) like stickers on a board, each with a circular full-color owner+pet photo, five filled star icons, and a short Italian quote.
8. **Numeri** — black background, halftone overlay, four large metrics each inside a bordered box with a colored fill, numbers at `text-6xl font-black`.
9. **FAQ** — accordion. Closed: white, `border-4 border-black`, `shadow-[6px_6px_0px_0px_#000]`. Open: header turns `bg-[#FF6B6B]` with white text, answer panel is `bg-[#C4B5FD]` with `border-t-4 border-black`. Chevron rotates 180°.
10. **Final CTA** — `bg-[#FFD93D]`, massive outlined display type, large decorative geometric shapes (circle, rotated square) bleeding off the corners, single red CTA button.
11. **Footer** — black, halftone overlay, four link columns, social icon row in bordered squares, language selector, copyright.
## 2. `/signup` and `/login`
Shared split-screen shell. Left 55%: cream form panel. Right 45%: full-bleed color block (`#FF6B6B` for signup, `#C4B5FD` for login) containing a collage of overlapping bordered pet photos at slight rotations, plus one rotated testimonial sticker. On mobile the color block collapses to a short banner above the form.
- **Signup fields**: nome, email, password, città. A bordered checkbox for terms. Submit `CREA ACCOUNT` → `/onboarding`.
- **Login fields**: email, password. Submit `ACCEDI` → `/app`.
- Both: a bordered `O CONTINUA CON` divider and two fake social buttons (Google, Apple) as bordered squares. Both are non-functional but must look identical in quality to the real ones.
- Both: a yellow rotated hint sticker reading `DEMO — QUALSIASI EMAIL FUNZIONA`. This is essential; it tells the client they cannot break it.
- Inputs use the design system's focus treatment: background turns yellow on focus, no soft ring.
## 3. `/onboarding` — 7 steps, one route
Header: `PASSO 3 DI 7` label in `tracking-widest`, plus a **segmented progress bar** — seven separate bordered blocks that fill with red as steps complete. Never a rounded progress bar. Persistent `INDIETRO` / `AVANTI` footer with the primary button on the right.
1. **Proprietario** — nome, città, avatar picker (grid of preset human avatars).
2. **Specie** — the money shot. Two enormous side-by-side tiles filling the viewport, each `border-4 border-black` with a `shadow-[12px_12px_0px_0px_#000]`. `CANE` on red, `GATTO` on violet, each with a huge icon and a full-color photo. On hover they lift; on select they press down and the unselected tile desaturates its background. No dropdown, no radio group.
3. **Base** — nome del pet, età (segmented control: CUCCIOLO / ADULTO / SENIOR), sesso, razza (combobox with Italian breed list filtered by the chosen species).
4. **Carattere — conditional on species.** This step must ask different questions for dogs and cats:
- **Cane**: taglia (piccola/media/grande), livello di energia (1–5 as five bordered blocks), va d'accordo con altri cani, comportamento al guinzaglio, sterilizzato.
- **Gatto**: indoor / outdoor / entrambi, socievolezza (1–5), va d'accordo con bambini, va d'accordo con altri gatti, sterilizzato.
- Plus a shared multi-select chip cloud of personality traits (`GIOCHERELLONE`, `TIMIDO`, `COCCOLONE`, `ENERGICO`, `DORMIGLIONE`, `CURIOSO`, `DOMINANTE`, `TRANQUILLO`). Chips are bordered pills that invert to black on select.
5. **Foto** — a grid of curated preset photos filtered by species; user picks 1–4 and can reorder. Include a `CARICA FOTO` button that opens the *same* preset grid rather than a file dialog, so the demo can never load an unflattering local image. Selected photos show a numbered bordered badge.
6. **Intento** — multi-select bordered cards: `GIOCARE`, `PASSEGGIATE`, `AMICIZIA`, `ACCOPPIAMENTO`, and the distinct one — `DISPONIBILE PER ADOZIONE`, which is visually separated, violet, and shows a short explanatory line when selected.
7. **Reveal** — the payoff. The finished swipe card **assembles itself on screen**: photo block snaps in, border draws, hard shadow drops, info panel slides up from beneath, trait badges pop in one by one with a short stagger. Headline *"ECCO LA CARD DI LUNA"*. CTA `INIZIA A CERCARE` → `/swipe`. This animation is the single highest-value 400ms in the prototype; do not skip it and do not make it a fade.
## 4. `/app` — Dashboard
- Greeting: `CIAO, GIULIA` at `text-5xl font-black uppercase`, with a rotated hand-wave icon sticker.
- **Active pet switcher**: horizontal row of circular bordered pet avatars; the active one has a thick red ring and a `ATTIVO` badge. Tapping switches which pet the user swipes as, and the whole dashboard's numbers update. Include an `+` tile routing to onboarding.
- **Four stat tiles**: `MATCH`, `SÌ RICEVUTI`, `CHAT ATTIVE`, `VISITE AL PROFILO`. Each is a bordered box with a different palette fill and a `text-5xl font-black` number.
- **NUOVI MATCH**: horizontally scrolling row of circular pet photos with red unread dots, each routing to its conversation.
- **CHI TI HA MESSO SÌ**: a 3-up grid of pet photos, deliberately obscured by a violet bordered `SBLOCCA CON PREMIUM` sticker overlay rotated `-rotate-3`. Fake premium teaser — costs nothing, reads as a real business model, and clients love seeing it.
- **Attività recente**: a bordered list of seeded events (*"Milo ti ha messo SÌ"*, *"Nuovo messaggio da Chiara"*, *"Il tuo profilo è stato visto 12 volte"*) each with an icon in a bordered square and a relative timestamp.
- **Big closing CTA**: full-width red bordered block, `VAI A SWIPARE`, with a large arrow icon.
## 5. `/swipe` — The deck
- **Filter bar** (top, sticky, bordered): a segmented control `TUTTI / CANE / GATTO` and a `SOLO ADOZIONE` toggle rendered as a hard bordered switch. Filtering re-seeds the deck immediately. This bar is load-bearing — it is the proof that dogs and cats are equal citizens.
- **Card stack**: three cards visible. Back cards are offset down and rotated (`rotate-2`, `-rotate-1`) so the stack reads as physical layered stickers. Card anatomy:
- Photo block, full color, `border-4 border-black`, sharp corners, fixed aspect ratio.
- **No gradient scrim.** Name, age, breed, distance and trait badges live in a solid `bg-[#FFFDF5]` panel *below* the photo, separated by `border-t-4 border-black`. This is a deliberate departure from Tinder and a deliberate consequence of the design system's ban on gradients — it makes the card read as a printed trading card, which is a stronger look for a pet product.
- Corner badges: species chip, and a rotated violet `ADOZIONE` badge when flagged.
- **Drag interaction**: real pointer drag. Card rotation is bound to horizontal offset. Past the threshold the card flies out and off-screen; below it, it snaps back. Vertical drag up = super-like.
- **Stamps**: appear as a function of drag distance and **snap in by scale, not by fading** — the design system bans transparency. Right = `SÌ!` in yellow, left = `NO` in red, up = `TOP!` in violet. Each is `-rotate-12`, `font-black`, uppercase, with `-webkit-text-stroke` and a hard text shadow.
- **Action row**: four bordered square buttons with hard shadows and the mechanical press-down effect — `INDIETRO` (rewind, white), `NO` (red), `TOP` (violet), `SÌ` (yellow). All keyboard-operable: `←` no, `→` sì, `↑` top, `Backspace` rewind.
- **Match overlay**: full-screen `bg-[#C4B5FD]` with halftone overlay. Two circular bordered photos collide from opposite edges and overlap in the center. `È UN MATCH!` in massive outlined display type. Subline *"A Luna e Milo piacete a vicenda."* Two CTAs: `MANDA UN MESSAGGIO` (red) and `CONTINUA A SWIPARE` (outline). Decorative rotated stars and shapes scattered behind.
- **Empty state**: never blank. *"HAI VISTO TUTTI I PELOSI IN ZONA"* with an illustration built from bordered geometric shapes, a `AMPLIA LA DISTANZA` control, and a `RICARICA IL MAZZO` button that re-seeds the deck.
## 6. `/matches` and `/matches/[id]`
- **Desktop (`>= 1024px`) — three panes**, divided by `border-r-4 border-black`:
- Left rail: match list. Each row is a circular bordered avatar, pet name in 900, last message truncated, relative time, and an unread indicator as a solid red square. Selected row has a yellow fill.
- Center: conversation.
- Right rail: mini pet profile of the current match — photo, key traits, owner name, and a `VEDI PROFILO` button to `/pets/[id]`.
- **Mobile**: `/matches` shows the list only; tapping routes to `/matches/[id]`, which is a full-screen conversation with a bordered back bar.
- **Chat bubbles**: sharp corners, never rounded. Mine = `bg-[#FFD93D]`, `border-4 border-black`, right-aligned, `shadow-[4px_4px_0px_0px_#000]`. Theirs = white, left-aligned, same border and shadow. Timestamps in `tracking-widest` uppercase micro-type below each group.
- **Composer**: bordered input at `h-14`, yellow on focus, plus a red bordered square send button with the press-down effect. Typing input works and appends to local state, so the client can send a message and see it land.
- **Typing indicator**: three solid black squares blinking in sequence. Not dots.
- **Seeded content is mandatory**: ship at least 6 matches, of which 4 have real multi-turn Italian conversations (arranging a park meetup, comparing vaccination records, an adoption inquiry, one just-matched with a single opening line). The client must never open this screen and find it empty.
## 7. `/pets/[id]`
- Photo carousel, `border-4 border-black`, with **square** indicator blocks rather than round dots, and bordered square arrow buttons.
- Identity panel: name at `text-6xl font-black`, age, breed, distance, species chip, verification badge.
- **Compatibilità meter**: a percentage rendered as ten segmented bordered blocks that fill with red. Never a rounded progress bar.
- Bio in a bordered white card with a large opening quote glyph.
- Trait grid: each trait in its own bordered box with an icon, colored fills rotating through the palette.
- Owner card: circular avatar, name, city, "membro da" date.
- **Adoption panel** (only when the pet is flagged): violet bordered block explaining the adoption process in three steps with a `RICHIEDI INFO` CTA.
- Sticky bottom action bar on mobile with the same `NO` / `SÌ` buttons as the deck, so the card can be actioned without going back.
## 8. `/profile`
- Header: owner avatar, name, city, edit button.
- **I MIEI PELOSI**: one card per pet (dog and cat both present in the seed) showing photo, name, completeness meter as segmented blocks, an `ADOZIONE` badge if flagged, and edit/delete controls. Plus an `AGGIUNGI UN PELOSO` card with a large plus icon in a bordered square, routing to onboarding.
- **PREFERENZE DI RICERCA**: species selector, distance as a segmented control (5 / 10 / 25 / 50 km — a segmented control, not a slider, to stay on-system), age range, `mostra solo adozioni` toggle.
- **IMPOSTAZIONI**: a bordered list of rows (notifiche, privacy, account, lingua, aiuto), each with a chevron. Rows are non-functional but must look finished.
- Footer actions: `ESCI` (outline) and `RESET DEMO` (violet) which clears `localStorage` and re-seeds.
</screen-specs>
<design-system>
# Design Style: Neo-brutalism
## 1. Design Philosophy
**Neo-brutalism** is the digital punk rebellion against "Corporate Memphis" and polished "Clean SaaS" aesthetics. Where traditional brutalism was drab and utilitarian, neo-brutalism is vibrant, performative, and intentionally distinct: the raw structural honesty of brutalism combined with the high-saturation energy of Pop Art, the sticker culture of the early internet, and the DIY spirit of zine design.
**Core principles:**
1. **Unapologetic visibility.** Structure is not implied, it is enforced with thick hard-edged black lines. `border-4` is the default. Shadows are not simulated light — they are solid blocks of ink offset at 45°, zero blur. Every element has weight and presence. If it doesn't have a border, it doesn't exist.
2. **Digital tactility.** The screen is a collage board, not a glass surface. Elements are stickers, paper cutouts, printed cards layered over each other. Buttons press down mechanically to cover their own shadow. Cards lift up and their shadow grows. Text blocks are rotated like stickers slapped on at an angle.
3. **Organized chaos.** Planned messiness that looks spontaneous. Slight rotations (`rotate-1`, `-rotate-2`, `rotate-3`) break grid monotony. Elements overlap deliberately. Asymmetry is preferred — 60/40 and 70/30 splits over 50/50, headlines split unevenly across lines with different colors per line. The underlying structure stays rigid so usability never suffers.
4. **Default and raw.** Pure black `#000000` for every border and every piece of text — no grays, ever. High-saturation colors that look like unmixed paint or highlighter marker. Cream `#FFFDF5` background mimicking newsprint, rejecting stark white.
5. **Maximalism as statement.** More borders, more shadows, more uppercase, more texture. Not clutter — density used to create energy.
6. **Mechanical interactivity.** Nothing fades or glows. Things click, snap, and slam. Transitions are fast (100–200ms) and direct, arcade-game responsive.
**Emotional tone:** nostalgic and retro-modern (Y2K, 90s punk zines, rave flyers); energetic and loud — it screams rather than whispers; playful yet functional, using gamified interaction to make utilitarian software feel like a toy; anti-corporate and confident.
**Why it fits PAWSOUL:** every competitor in pet matching (Pinder, Pawmates, Tindog, Psinder) uses the same rounded-corner pastel mush. Neo-brutalism makes this product instantly unmistakable, and it is the rare bold style that stays *warm* — the cream canvas and highlighter palette read playful rather than cold, which is exactly right for animals.
**What it is NOT:** not minimal, not smooth, not subtle, not polished, not corporate.
## 2. Design Token System (The DNA)
Centralize every value below as a token before styling a single component. In Tailwind v4 declare them in `@theme` inside the global stylesheet; in v3 extend `tailwind.config.ts`. No component may hardcode a hex value.
### Colors — single light-mode palette
- `background` / canvas: `#FFFDF5` — warm cream, paper-like. Page backgrounds, card interiors.
- `foreground` / ink: `#000000` — pure black. **All** text, **all** borders, **all** shadows. No `#333`, no `#666`, no grays.
- `accent` / hot red: `#FF6B6B` — primary actions, primary CTAs, `NO` stamp, unread indicators.
- `secondary` / vivid yellow: `#FFD93D` — secondary buttons, `SÌ` stamp, input focus fill, own chat bubbles, footer and alternate sections.
- `muted` / soft violet: `#C4B5FD` — tertiary depth. Card headers, FAQ answer panels, `TOP` stamp, match overlay, premium teaser, adoption accents.
- `white`: `#FFFFFF` — contrast panels, text on black, cards that need to separate from the cream canvas.
**Rules:** never use subtle grays. All text must pass WCAG AA on its background. Sections alternate between cream, yellow, violet, black and white to create rhythm.
**Species color convention** (apply consistently across every screen): **dog = red `#FF6B6B`**, **cat = violet `#C4B5FD`**, **adoption = violet with a black `ADOZIONE` badge**. Once established, the client can read the whole product at a glance.
### Typography
- **Family**: `Space Grotesk` — geometric sans with quirky personality, heavy enough to carry 900 weight. Load `wght@400;500;700;900` with `display=block`.
- **Weights — heavy only.** `font-black` (900) for all headings. `font-bold` (700) for body, labels, buttons. `font-medium` (500) sparingly. 400 is essentially forbidden; lightness breaks the style.
- **Scale**:
- Display: `text-6xl` → `text-8xl` → `text-9xl` (hero headlines)
- H2: `text-4xl` → `text-6xl` → `text-8xl` (section titles)
- H3: `text-3xl` → `text-4xl` → `text-5xl`
- Body large: `text-xl` → `text-2xl`
- Body: `text-lg` → `text-xl`
- Labels / micro: `text-sm` → `text-base`, `uppercase`, `tracking-widest`
- **Techniques**:
- **Text stroke** for display: `-webkit-text-stroke: 2px #000` with `color: transparent` for massive hollow type. Layer a solid copy behind it, offset, for depth.
- Heavy **UPPERCASE** for headings, labels, buttons, badges. Lowercase acceptable for long body copy and chat messages.
- Tracking: `tracking-tighter` on headlines, `tracking-widest` or `tracking-[0.2em]` on labels.
- Line height: `leading-none` or `leading-[0.85]` for display; `leading-snug` to `leading-relaxed` for body.
### Radius and borders
- **Radius default is `0`.** Set `--radius: 0` (or equivalent) globally so every inherited shadcn component loses its rounding at the token level rather than per-component. The **only** exception is `rounded-full`, allowed for pill badges, circular avatars, and decorative circles. `rounded-md`, `rounded-lg`, `rounded-xl` are forbidden — it is sharp or fully round, nothing between.
- **Borders are mandatory on every visual element.** `border-4 border-black` is the signature default. `border-2` only for subtle separators and ghost buttons. `border-8` for major section dividers and hero elements. Always solid, always pure black, never transparent.
### Shadows and effects
- **Hard shadows — zero blur, zero spread, always bottom-right:**
- Small: `shadow-[4px_4px_0px_0px_#000]`
- Medium: `shadow-[8px_8px_0px_0px_#000]`
- Large: `shadow-[12px_12px_0px_0px_#000]`
- Massive: `shadow-[16px_16px_0px_0px_#000]`, or `shadow-[20px_20px_0px_0px_#fff]` for elements sitting on black
- **Text shadows** on colored backgrounds: `text-shadow: 4px 4px 0px #000`.
- **Background textures — never leave a background flat.** Register these as reusable utility classes, not inline repeats:
- Halftone dots: `background-image: radial-gradient(#000 1.5px, transparent 1.5px); background-size: 20px 20px;`
- Graph grid: `background-size: 40px 40px; background-image: linear-gradient(to right, rgba(0,0,0,.1) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,.1) 1px, transparent 1px);`
- Noise: an inline SVG `feTurbulence` fractal-noise data URI.
- Large radial dots: `radial-gradient(circle, #000 2px, transparent 2.5px); background-size: 30px 30px;`
## 3. Component Styling
### Buttons
Sharp corners, `h-12` to `h-14`. Variants: **primary** red, **secondary** yellow, **outline** white, **ghost** `border-2 border-transparent` becoming `border-black` on hover. Typography `font-bold text-sm uppercase tracking-wide`. Shadow `shadow-[4px_4px_0px_0px_#000]` or `6px`. **Critical interaction:** on `:active`, `translate-x-[2px] translate-y-[2px] shadow-none` — the button physically presses down onto its own shadow. Hover darkens the fill or deepens the shadow at `duration-100`.
### Cards / containers
`bg-white`, `border-4 border-black`, `rounded-none`, `shadow-[8px_8px_0px_0px_#000]` to `12px`. Hover lifts and grows: `hover:-translate-y-2 hover:shadow-[16px_16px_0px_0px_#000]`. Headers often carry a colored fill with a `border-b-4 border-black` separator.
### Inputs
`border-4 border-black`, sharp, `bg-white`, `h-14` to `h-20`, `font-bold text-lg`, placeholder `text-black/40`. **Focus changes the background colour instead of drawing a ring:** `focus-visible:bg-[#FFD93D] focus-visible:shadow-[4px_4px_0px_0px_#000] focus-visible:outline-none focus-visible:ring-0`.
### Badges
Pill (`rounded-full`) or square (`border-4`). Colored fill, thick border, hard shadow, `font-black text-sm uppercase tracking-widest`. Frequently positioned absolutely over other elements and rotated (`rotate-3`), rotating further on hover.
### Navigation
Logo in a `border-4 border-black` box with a yellow fill. Links bold and uppercase; on hover they gain a border, a red fill, horizontal padding and a hard shadow, snapping into place. Mobile hamburger is a bordered square with a shadow; the menu is a stack of bordered buttons.
### Segmented controls, toggles and meters
There are **no rounded sliders or rounded progress bars anywhere in this product**. Every quantity is expressed as a row of discrete bordered blocks that fill with color — onboarding progress, energy level, compatibility percentage, profile completeness, distance preference. This is one of the most recognizable signatures of the build; apply it consistently.
## 4. Layout and Spacing
- Container `max-w-7xl` (or `max-w-6xl` for focused content), `mx-auto`.
- Dense 8px grid. Section padding `py-16` to `py-32`. Element gaps `gap-6` to `gap-12`.
- **Sticker rotation**: apply `rotate-1`, `-rotate-2`, `rotate-3` to headline spans, cards, badges and CTAs to break grid monotony.
- **Marquee**: horizontal scrolling text strips as section dividers and trust bands.
- **Overlapping**: absolute positioning for floating decorative shapes, corner badges (`-top-6 -right-6`), and giant low-contrast background numerals or words as texture.
- **Visual chaos zones**: deliberately busy areas (hero right side, match overlay) with stacked shapes, multiple rotated badges, oversized background type.
- **Asymmetry**: 60/40 and 70/30 splits, offset columns, staggered grids. Avoid perfect symmetry.
## 5. Non-Genericness (mandatory bold choices)
1. **Text stroke display typography** — hollow outlined headings, sometimes layered over a solid offset copy.
2. **Sticker layering** — rotated bordered text blocks, badges overlapping content, depth built purely from hard shadows.
3. **Interactive physics** — buttons press down, cards lift up, badges rotate further on hover.
4. **Primitive shape motifs** — stars, arrows, squares and circles as decorative floaters and dividers.
5. **Borders everywhere** — even whitespace gets bordered.
6. **Color blocking** — large sections in solid red, yellow, violet or black for high-contrast rhythm.
7. **Texture overlays** — halftone, grid or noise on every background. Flat backgrounds are a bug.
## 6. Icons and Imagery
### Icons — HugeIcons
Use `@hugeicons/react` with `@hugeicons/core-free-icons`. The package exposes a single component:
```tsx
import { HugeiconsIcon } from '@hugeicons/react';
import { Dog01Icon } from '@hugeicons/core-free-icons';
<HugeiconsIcon icon={Dog01Icon} size={32} color="currentColor" strokeWidth={2.5} />
```
Wrap it in a small local `<Icon />` component so `strokeWidth` and sizing defaults live in exactly one place.
**Known tension and its resolution:** the free HugeIcons pack ships **Stroke Rounded only**, whose soft caps mildly contradict the style's angular bias. Compensate two ways — always render at `strokeWidth={2.5}` or `3` so icons read as heavy rather than delicate, and always mount icons **inside a hard-bordered square container** (`border-4 border-black` with a colored fill), so the container supplies the angularity the glyph cannot. Never place a bare thin icon on a bare background.
Sizes `size={32}` standard, `size={48}` for emphasis. Prefer black or white fills; match the section's contrast, not its accent.
### Imagery
- **Pet photos are always full color.** This is a hard override of any grayscale-by-default treatment. The animal's face is the product; desaturating it destroys the emotional payload, and on mobile there is no hover state to restore it.
- Every photo sits in a `border-4 border-black` frame with sharp corners and a hard shadow.
- **No gradient scrims over photos.** Text never sits on top of an image. It sits in a solid bordered panel adjacent to it, separated by `border-t-4 border-black`.
- Human avatars and match-overlay photos may use `rounded-full`, always with a thick black ring.
- Photo collages use overlapping frames at slight rotations rather than neat grids.
## 7. Responsive Strategy
Mobile-first, scaling up through `sm` 640 / `md` 768 / `lg` 1024 / `xl` 1280.
- Typography scales aggressively: `text-4xl sm:text-6xl lg:text-8xl`.
- Padding reduces on mobile: `p-6 sm:p-10 lg:p-16`.
- Grids collapse to one column.
- **Shadows shrink but never disappear**: `shadow-[6px_6px_0px_0px_#000] sm:shadow-[8px_8px_0px_0px_#000]`.
- Borders stay `border-4` at every breakpoint. Do not thin them on mobile — the style depends on them.
- Buttons go full width on mobile (`w-full sm:w-auto`). Touch targets minimum 44×44px (`h-12`+).
- **The core aesthetic must survive on mobile.** Never fall back to a generic mobile look.
## 8. Animation and Motion
Bouncy, mechanical, arcade-like. Buttons `duration-100`; cards and hovers `duration-200`/`duration-300`. Easing `ease-linear` for mechanical feel or `ease-out` for deceleration — **never `ease-in-out`**.
- Buttons: darken on hover, press down on click.
- Cards: translate up, shadow deepens.
- Links: gain border and fill, snapping into place.
- Looping decorative motion: slow 10s spins on stars, pulses on CTAs, bounces on attention badges.
- **Swipe-specific**: card rotation bound to drag offset; fly-out past threshold; snap-back below it; stamps enter by **scale**, never by opacity fade; the match overlay slams in with two photos colliding.
- Respect `prefers-reduced-motion: reduce` — disable loops, spins, bounces and pulses; keep functional transitions.
## 9. Anti-Patterns — never do these
- No `blur()`, no `backdrop-blur`, no soft blurred `box-shadow`.
- No alpha transparency on backgrounds (low-opacity texture overlays are the sole exception).
- No smooth gradients anywhere — including photo scrims and button fills. Hard color stops or patterns only.
- No mid-range radii (`rounded-md`, `rounded-lg`, `rounded-xl`).
- No subtle grays.
- No `ease-in-out`, no slow transitions.
- No large empty whitespace — fill with texture, pattern or decoration.
- No grayscale pet photography.
- No rounded progress bars or rounded range sliders.
## 10. Accessibility
High contrast is built in; verify every combination passes WCAG AA (4.5:1 body, 3:1 large). Focus states use thick rings (`focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2`) or the yellow background-fill treatment on inputs. All interactive elements keyboard reachable with logical tab order; the swipe deck is fully operable via arrow keys. Semantic HTML throughout (`<button>`, `<nav>`, `<main>`, `<header>`). `aria-label` on every icon-only button. Announce match events to screen readers via a live region.
</design-system>
<mock-data>
All content lives in `lib/mock/`. No network calls other than remote image loading.
- **`pets.ts`** — 18 pets minimum, roughly 11 dogs and 7 cats. Each: `id`, `name`, `species`, `age`, `ageGroup`, `breed`, `gender`, `city`, `distanceKm`, `photos[]` (2–4 remote URLs), `bio` (2–3 warm Italian sentences with personality), `traits[]`, species-specific attributes, `intents[]`, `availableForAdoption`, `owner` (`name`, `avatar`, `memberSince`), `compatibility` (0–100).
- **Italian names and voice throughout** — Luna, Milo, Zeus, Nina, Briciola, Pepe, Mora, Otto, Cleo, Gigio. Bios must sound like a real owner wrote them, never like generated filler. This is cheap and it is a large share of the perceived quality.
- **`matches.ts`** — 6+ matches with `matchedAt`, `unreadCount`.
- **`conversations.ts`** — at least 4 threads with genuine multi-turn Italian dialogue: arranging a park meetup, comparing vaccination records, an adoption enquiry, and one freshly matched with a single opening line. Plus 2 matches with no messages, so the "start a conversation" state is also demonstrable.
- **`user.ts`** — the seeded owner (Giulia, Milano) with **two** pets already registered: one dog and one cat. This is essential — the active-pet switcher and the multi-species story are unprovable with a single pet.
- **`activity.ts`** — 6–8 dashboard feed events with relative timestamps.
- **Photos** — curated remote URLs (stable Unsplash-style permalinks). Choose warm, well-lit, close-up portraits where the animal's face is large in frame. Photo quality carries this prototype more than any other single factor; pick them deliberately rather than grabbing the first result. Configure the framework's image host allowlist accordingly and always set explicit dimensions to prevent layout shift.
- **State**: a single `AppProvider` context holding `user`, `activePetId`, `deck`, `swipeHistory`, `matches`, `conversations`, hydrated from `localStorage` with the seed as the fallback. Expose a `resetDemo()` that clears storage and re-seeds without a page reload.
</mock-data>
<implementation-plan>
Work in this order and explain each step briefly as you go.
1. **Audit** the boilerplate: Tailwind version, installed shadcn components and their `cva` definitions, existing token layer, folder conventions, current icon library. Report what you found before changing anything.
2. **Tokens first.** Replace the palette with the six values above, set `--radius: 0` globally, register the hard-shadow scale as named tokens, wire Space Grotesk, and add the halftone / grid / noise texture utilities. Everything downstream inherits from here — no component should ever hardcode a hex or a shadow.
3. **Restyle shadcn in place, do not fork it.** Extend each component's existing `cva` variants (`Button`, `Card`, `Input`, `Badge`, `Tabs`, `Dialog`, `Sheet`, `Avatar`, `Accordion`, `Switch`, `Progress`) rather than writing parallel components. Where the neo-brutalist treatment is genuinely incompatible with a shadcn primitive — the segmented progress/meter blocks, the swipe card — add a new component beside it instead of contorting the original.
4. **Swap the icon layer** to HugeIcons behind a single local `<Icon />` wrapper so defaults live in one place.
5. **Build shared primitives** that the screens repeatedly need: `PetCard`, `SwipeDeck`, `SegmentedMeter`, `StatTile`, `StickerBadge`, `TextureSection`, `MarqueeBand`, `ChatBubble`, `SpeciesTile`. These are the reuse backbone — resist inlining their styles per screen.
6. **Mock data and context** before screens, so no screen is ever built against an empty state.
7. **Screens in demo-walkthrough order**: `/` → `/signup` → `/onboarding` → `/swipe` → `/matches` → `/app` → `/pets/[id]` → `/profile` → `/login`. Build in the order the client will click, so the highest-value path is finished first if time runs short.
8. **Responsive pass** at 390px, 768px and 1440px on every screen. Then an accessibility pass: contrast, focus, keyboard, `prefers-reduced-motion`, live region on match.
</implementation-plan>
<acceptance-criteria>
The build is done when all of the following are true.
- [ ] Every one of the 10 routes renders complete, populated, and non-broken at 390px, 768px and 1440px.
- [ ] Not one screen shows an empty list or placeholder text on first load.
- [ ] Every string in the interface is Italian.
- [ ] The deck responds to real pointer drag on desktop and touch on mobile, plus arrow keys.
- [ ] Stamps enter by scale. Nothing anywhere fades in via opacity.
- [ ] The match overlay fires, is full-screen, and routes into a conversation.
- [ ] Onboarding asks materially different questions for a dog than for a cat.
- [ ] The step-7 card reveal animates the card assembling itself.
- [ ] The seeded user has both a dog and a cat, and the active-pet switcher visibly changes the dashboard.
- [ ] The species filter on the deck works and re-seeds immediately.
- [ ] At least 4 conversations contain believable multi-turn Italian dialogue.
- [ ] Zero rounded corners anywhere except `rounded-full` on avatars, pills and decorative circles.
- [ ] Zero gradients, zero blurs, zero grays, zero grayscale photos.
- [ ] Every quantity in the product is a segmented bordered meter, never a rounded bar or slider.
- [ ] Every background carries a texture; no flat empty panels.
- [ ] Every button presses down onto its shadow on `:active`.
- [ ] Every card lifts on hover.
- [ ] `RESET DEMO` restores the seed without a reload.
- [ ] No hardcoded hex values or shadow strings outside the token layer.
- [ ] `prefers-reduced-motion` is respected.
</acceptance-criteria>
Nella parte 6 due skill danno all’agente il metro che gli manca su accessibilità e prestazioni: un comando per installarle, tre prompt per lanciarle.