What goes into the briefing
Now there’s just one thing left: turn what you’ve decided into something an agent can execute. Not another document to read in a meeting — a file you hand Claude Code, and the app comes out of it.
The material is all there already, and it comes in three pieces.
- docs/ux-ui.md · Part 1
- Product, user, core action, MVP, the ten screens, the decisions made, the states, the completion criteria.
- The running project · Part 3
- Next.js and shadcn/ui already assembled: the agent adds components inside a system that already exists.
- docs/ui.md · Part 4
- The aesthetic direction as values: color, typography, shape, depth, motion, and the list of what’s forbidden.
These are decisions. An agent needs instructions: whatever the briefing doesn’t write down, it invents. So the three pieces become a single file — the spec you’d hand to an outside studio, with one difference: a studio calls you when it doesn’t understand something.
This is where we stop, at that file: this part writes it and hands it to you. The app comes right after, once you give it to Claude Code to run.
The briefing’s eight blocks
This is the place: Claude Code’s box, open inside the project folder.
Read docs/ux-ui.md and docs/ui.md and write me docs/prototipo.md:
the briefing we'll use to build the prototype.
Eight blocks, in this order:
1. <role> who you are, what you look at first
2. <project> product, language, locked boundaries
3. <information-architecture> the screens and the navigation
4. <screen-specs> what's inside each screen
5. <design-system> color, shape, motion, forbidden
6. <mock-data> the fake content, listed
7. <implementation-plan> in what order it gets built
8. <acceptance-criteria> when it's done
Before writing, tell me what's missing from the documents. This is the shape, and it’s fixed: from project to project the content changes, not the order and not the names. Block by block, what goes in it and where it comes from:
- 1
<role>Who it has to be, and what it looks at before touching a file.
Part 3: the stack, Tailwind version, installed components, existing tokens.
- 2
<project>What the product is, what language it speaks, what doesn’t get touched.
Points 1-4 and 6 of docs/ux-ui.md. The decisions made here become the word «locked».
- 3
<information-architecture>How many screens there are and how you move between them.
Point 5 of the document, translated into routes, plus navigation on phone and on large screens.
- 4
<screen-specs>What’s inside each screen, in what order, with which states.
Point 5 again, expanded: one line of the document becomes half a page. It’s the longest block.
- 5
<design-system>What it looks like, how it behaves, what’s forbidden.
The whole of docs/ui.md, plus buttons, cards, fields, icons, images, motion.
- 6
<mock-data>What content it gets filled with.
Point 8 of the document becomes a list: eighteen pets, six matches, four real conversations.
- 7
<implementation-plan>In what order it gets built.
Tokens, shared pieces, then the screens in the order the client will click through them.
- 8
<acceptance-criteria>When it’s done.
Point 10 of docs/ux-ui.md, rewritten as checkboxes you can tick by looking at the screen.
The prompt that writes the prompt
The long version of that one line: same request, plus the rules for filling in the eight blocks. The briefing isn’t written by hand — Claude Code writes it, since it already has your documents in the project.
The prompt that writes the briefing The eight blocks plus the rules for filling them in
Read docs/ux-ui.md and docs/ui.md. They're the source: every line you
write has to trace back to them.
Write me docs/prototipo.md: the single briefing I'll give an agent so it
builds the navigable prototype inside this project. It's not a summary of
the two documents, it's their expansion into executable instructions.
Eight blocks, in this order, each inside its own tag:
<role> who the agent has to be and what it has to read about the project
BEFORE writing any code: the stack, Tailwind version, components already
installed, existing tokens. At the end, the framing: this is a prototype for
a demo, not production software — visual quality matters more than
architectural purity, and no screen stays unfinished just because the logic
underneath is fake.
<project> the product in ten lines, the language of the strings, the data
model, and the boundaries marked as LOCKED, and the success criteria written
as a walkthrough: what someone who's never seen the product has to be able
to do on their own.
<information-architecture> the full list of screens with, for each one, the
job it does; plus how you navigate on phone and on large screens.
<screen-specs> one section per screen: what it contains, in what order, with
which empty and error states. It's the longest block and has to be written
as such.
<design-system> the whole of docs/ui.md, plus the parts that weren't in
there: how buttons, cards, fields, and labels behave; the motion; the icons;
the images; and the explicit list of forbidden things.
<mock-data> the fake data, listed: how many, with which fields, with what
names and what tone. No screen should be able to come up empty.
<implementation-plan> in what order it gets built, from tokens to screens,
and the screens in the order they'll be shown to whoever watches the demo.
<acceptance-criteria> boxes to check by looking at the screen, not by
reading the code.
Rules:
- Expand, yes; contradict, no. Every value from docs/ui.md goes in as is.
Where you need a value the documents don't fix, pick a coherent one and
write it down; but never change one that's already there.
- You can invent the staging: compositions, decorations, microcopy, motion
details. Not the product: screens, features, data model, and what's out of
the MVP come from the documents. If you need a product decision that isn't
there, stop and ask me.
- No adjectives where a value could go instead: pixels, color codes,
milliseconds, class names. "Modern" and "clean" aren't instructions.
- Write the briefing in English, except the product's visible strings, which
stay in Italian even inside the briefing.
- Don't shorten it out of politeness: if a block runs long, let it run long.
At the end, list the decisions you made on my behalf and the questions the
documents don't answer. The result, and the file that produced it
This is what was on screen one hour later, after handing that briefing to Claude Code and letting it work.
This is the file that produced it. Save it in the project as docs/prototipo.md and hand it over to run.
docs/prototipo.md Eight blocks, ten screens, one whole design system
<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>
In part 6, two skills give the agent the measuring stick it’s missing on accessibility and performance: one command to install them, three prompts to run them.