Design system
LoveXposure Design System
Raccoglie colori, font, superfici e pattern visivi di LoveXposure, dal giallo Locarno al rainbow animato.
File
design-systems/lovexposure-design.md
Prompt
๐จ LoveXposure Design System
Version: 3.0 Last Updated: June 9, 2026 Architecture: Scenario C (Unique & Memorable)
Archivio digitale sull'amore, osservatorio sul futuro delle dating app. Italian-language, dadaist-editorial, dark by default, phosphorescent on accent. Used mostly on mobile for quiz and interactive flows; optimised for desktop archive browsing.
This is the single source of truth for every visual decision in LoveXposure. All values are verified against app/globals.css โ that file is the implementation reference; this document describes it. When the two diverge, the code wins.
๐ Typography
LoveXposure uses a curated collection of rare, locally-hosted fonts. All fonts are served from the project's own server, eliminating external CDN dependencies.
Active Font Stack
#### 1. Arthur Official Grotesk โ Primary Heading Font
``css font-family: 'Arthur Official Grotesk', sans-serif; ``
- Role: All headings (h1โh6), hero titles, section headers
- Weight: 400 (single weight; CSS
font-weight: 900renders bold via the typeface itself) - File:
/public/fonts/rare-fonts/Font Arthur Official Grotesk.otf(47 KB) - CSS variable:
var(--font-heading) - Tailwind class:
font-heading(auto-applied to h1โh6 via base layer) - Characteristics: Modern grotesk, strong geometric construction, high presence
#### 2. Barnebok โ Primary Body Text Font
``css font-family: 'Barnebok', sans-serif; ``
- Role: All body text, paragraphs, general content
- Weights: 300 Light / 400 Regular (default) / 500 Medium
- Files:
/public/fonts/rare-fonts/barnebok-font/*.woff(~180 KB total) - CSS variable:
var(--font-body) - Tailwind class:
font-body(auto-applied tobodyvia base layer) - Characteristics: Humanist sans, warm, designed for children's books โ maximum readability
#### 3. Diamond Grotesk โ Navigation & UI Font
``css font-family: 'Diamond Grotesk', sans-serif; ``
- Role: Navigation, breadcrumbs, captions, UI labels
- Weight: 400 (single weight)
- File:
/public/fonts/rare-fonts/diamond-grotesk-font.ttf(57 KB) - CSS variable:
var(--font-navigation) - Tailwind class:
font-navigation - Characteristics: Clean UI font with subtle personality; +0.04em tracking reads as a label
#### 4. RL Madena โ Decorative / Special Font
``css font-family: 'RL Madena', sans-serif; ``
- Role: User names in dashboard, hero elements, animated decorative text
- Weights: 400 Regular + 400 Oblique
- Files:
/public/fonts/rare-fonts/rl-madena-font/*.woff2(34 KB) - CSS variable:
var(--font-special) - Tailwind class:
font-special - Characteristics: Variable font, smooth weight and oblique transitions
#### 5. Lunchtype โ User-Generated Content Font
``css font-family: 'Lunchtype', sans-serif; ``
- Role: Quiz responses, profile answers, all user-submitted content โ signals "this is your answer"
- Weights: 300 Light / 400 Regular / 500 Medium
- Files:
/public/fonts/rare-fonts/lunchtype-font/lunchtype22/*.ttf - CSS variable:
var(--font-ugc)(stack:'Lunchtype', 'Barnebok', sans-serif) - Tailwind classes:
font-ugc,font-lunchtype,font-lunchtype-light,font-lunchtype-medium - Characteristics: Quirky, slightly irregular โ visually distinct from editorial copy
Type Ramp
Dichiarato in app/globals.css nel @layer base:
`` body Barnebok 400, 1rem / 1.55 h1 Arthur 900, clamp(2.5rem, 6vw, 4.5rem), lh 1.1, ls -0.01em h2 Arthur 700, clamp(1.75rem, 4vw, 2.85rem), lh 1.1, ls -0.01em h3 Arthur 700, clamp(1.25rem, 2.5vw, 1.75rem), lh 1.1, ls -0.01em h4 Arthur 700, 1.25rem, lh 1.1, ls -0.01em h5 Arthur 700, 1.05rem, lh 1.1, ls -0.01em h6 Arthur 700, 0.95rem, uppercase, ls 0.08em small/caption Diamond Grotesk 400, 0.8rem, ls 0.04em, color: var(--fg-muted) code/pre SF Mono stack, 0.95em ``
Le classi Tailwind esplicite sui componenti (text-4xl, text-sm, ecc.) hanno precedenza sul base layer โ il ramp รจ il default intelligente, non un override forzato.
Deprecated Font Classes (backwards compat โ kept, remove eventually)
| Old class | Redirects to |
|---|---|
font-space-grotesk | font-heading (Arthur Official Grotesk) |
font-inter | font-body (Barnebok) |
font-dm-sans | font-navigation (Diamond Grotesk) |
font-permanent-marker | font-special (RL Madena) |
File Structure
`` /public/fonts/rare-fonts/ โโโ Font Arthur Official Grotesk.otf (47 KB) โโโ diamond-grotesk-font.ttf (57 KB) โโโ barnebok-font/ โ โโโ BarnebokLight.woff โ โโโ BarnebokRegular.woff โ โโโ BarnebokMedium.woff โโโ rl-madena-font/ โ โโโ RL-Madena.woff2 โ โโโ RL-Madena-Oblique.woff2 โโโ lunchtype-font/lunchtype22/ โโโ Lunchtype22-Light.ttf โโโ Lunchtype22-Regular.ttf โโโ Lunchtype22-Medium.ttf ``
Tailwind / CSS Variable Mapping
Declared in app/globals.css under @theme inline:
``css --font-heading: 'Arthur Official Grotesk', sans-serif; --font-body: 'Barnebok', sans-serif; --font-navigation: 'Diamond Grotesk', sans-serif; --font-special: 'RL Madena', sans-serif; --font-ugc: 'Lunchtype', 'Barnebok', sans-serif; --font-mono: 'SF Mono', 'Monaco', 'Inconsolata', monospace; ``
๐จ Color Palette
Raw Palette Tokens
Declared in app/globals.css under :root:
```css / Brand cornerstones / --yellow-locarno: #f4e500; / signature CTA + archive header / --yellow-locarno-hover: #e6d000; --lime-sunny: #e4f65a; / Pantone Sunny Lime โ surface tints / --lime-accent: #e0ff32; / phosphorescent stroke / text-shadow / --cyan-accent: #00e0ff; / gradient terminal + cool accent / --green-token: #7ed957; / token counter, positive signal /
/ Dark backgrounds / --black-true: #000000; / mobile bg + neo-brutalist borders / --ink: #0a0a0a; / heavy text on light surfaces / --night: #090115; / desktop deep-violet bg base / --night-2: #0a0117; --night-violet: #27063d; --paper: #fff8e2; / warm cream for archive surfaces / --white: #ffffff;
/ Rainbow gradient stops (home + profile bg, also text-clip accents) / --grad-stop-1: #e000b0; / magenta / --grad-stop-2: #b000d0; --grad-stop-3: #8000ff; --grad-stop-4: #6000ff; --grad-stop-5: #4000ff; --grad-stop-6: #00e0ff; / cyan /
/ Editorial reds (Dating Mainstream FlashCard "red" variant) / --red-dada: #cb0b09; --red-deep: #520201; --red-dada-tint: #f3c1bc; ```
Color Roles
#F4E500 โ Locarno Yellow. The signature CTA colour, taken from the Locarno Film Festival. Always paired with 2โ4 px black borders and black text. This is the colour the brain associates with LoveXposure.
#E4F65A โ Pantone Sunny Lime. Surface tints (DADA Airdrop callout). Sits between yellow and white.
#E0FF32 โ Phosphor Lime. Used only as a stroke/text-shadow on the hero tagline and as decorative borders on dark CTA buttons. Never as a flat fill on a large surface.
#00E0FF โ Cyan Accent. Terminal stop of the rainbow gradient; cool counterpoint in the desktop background radials.
#7ED957 โ Green Token. Token counter ("DADA Airdrop"), positive signal states.
#000000 โ Pure Black. Mobile background, neo-brutalist borders (2โ4 px), button text on yellow.
#090115 โ #27063d โ #0a0117 โ Night. Desktop background base; the "interstellar" feel.
Rainbow #E000B0 โ #00E0FF. The home page and profile page always-on animated background. Six-stop gradient at 135ยฐ, cycling four saturated hues every 8 s. Treat it as part of the brand identity, not a visual experiment.
Editorial reds #CB0B09 / #520201 / #F3C1BC. Reserved for Dating Mainstream FlashCards that flag adult/sex-related content.
Semantic Tokens
Declared in app/globals.css under the second :root block:
```css / Surfaces / --bg: var(--black-true); / default page background / --bg-deep: var(--night); / desktop deep-violet / --bg-paper: var(--paper); / warm cream, archive / --surface-1: rgba(8, 8, 9, 0.58); / primary glass card / --surface-2: rgba(8, 8, 9, 0.45); / secondary glass / --surface-3: rgba(8, 8, 9, 0.40); / option chip /
/ Foreground / --fg: var(--white); --fg-muted: rgba(255, 255, 255, 0.72); --fg-faint: rgba(255, 255, 255, 0.45); --fg-on-yellow: var(--black-true);
/ Lines + edges / --border-lx: rgba(255, 255, 255, 0.16); / inside dark surfaces / --border-lx-strong: rgba(255, 255, 255, 0.24); --border-ink: var(--black-true); / neo-brutalist 2โ4 px /
/ Action / --accent-brand: var(--yellow-locarno); --accent-brand-hover: var(--yellow-locarno-hover); --accent-stroke: var(--lime-accent); --accent-secondary: var(--lime-sunny); --on-accent: var(--black-true);
/ Signal / --positive: var(--green-token); --negative: var(--red-dada); --info: var(--cyan-accent); ```
Tailwind Color Utilities
The @theme inline block in globals.css exposes every palette token as a Tailwind utility (bg-yellow-locarno, text-lime-accent, border-cyan-accent, etc.). Use the semantic names when composing new components; reach for raw palette names only for brand-expressive elements.
๐ผ๏ธ Backgrounds & Surfaces
.bg-night โ Desktop Background
Deep violet (#090115) with two soft radial sunbursts and a 135ยฐ linear ramp. Apply to <body> or full-page containers on desktop. On mobile (max-width: 768px) falls back to flat #000000 โ the phone is the canvas; gradients add cost without benefit at small sizes.
``css .bg-night { background-color: var(--night); background-image: radial-gradient(circle at 15% 15%, rgba(224, 255, 50, 0.08), transparent 45%), radial-gradient(circle at 85% 10%, rgba(0, 224, 255, 0.10), transparent 55%), linear-gradient(135deg, var(--night-violet) 0%, var(--night-2) 100%); } ``
.home-gradient โ Animated Rainbow Surface
The six-stop magenta-to-cyan gradient cycling four solid hues over 8 s. Used on the homepage hero container and the profile page. Deliberately always-on; do not add prefers-reduced-motion suppression unless the design explicitly requests it.
``css .home-gradient { animation: color-change-4x 8s ease-in-out infinite; } ``
Keyframes defined in globals.css as color-change-4x: cyan โ magenta โ red โ gold.
.bg-home-gradient โ Static Rainbow Gradient
The same six stops as a non-animated linear-gradient. Used for text clipping (bg-clip-text) and surface accents.
Glass Cards
Floating on dark/rainbow backgrounds: background: rgba(8,8,9,0.58), border: 1px solid rgba(255,255,255,0.16), box-shadow: 0 14px 38px rgba(0,0,0,0.34). The .carnevale-surface class implements the canonical version.
Archive Surface
Yellow header (#F4E500) with a 4 px solid black border, then a white/paper body. The jump from the loud homepage to the "encyclopedia" archive is intentional.
Backdrop Blur
backdrop-blur-md (12 px) under the marquee ticker on dark surfaces (bg-black/30). backdrop-blur-xl (24 px) on the DADA Airdrop callout for a paper feel over the rainbow. Inside dark cards, prefer opaque fills; blur only when the layer sits over the rainbow.
๐ Spacing & Radii
Spacing Conventions
The codebase uses Tailwind's 4 px scale (0.25 rem). Strong preference for gap-3/gap-4 (12โ16 px) inside cards, and mb-10โmb-16 (40โ64 px) between sections.
Radius Tokens
| CSS token | Value | Used for |
|---|---|---|
--radius-xs | 4 px | chips, badges |
--radius-sm (shadcn) | ~6 px | small controls |
--radius-md (shadcn) | ~8 px | inputs, small buttons |
--radius-lg (shadcn) | 10 px | cards, large buttons |
--radius-xl (shadcn) | ~14 px | Carnevale surfaces, hero CTAs |
--radius-2xl | 20 px | quiz answer cards, big content cards |
--radius-full | 9999 px | chips, DADA token pill, avatars |
๐ Shadows
Declared in both :root and @theme inline (Tailwind utility exposure):
``css --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08); --shadow-md: 0 10px 24px rgba(0, 0, 0, 0.34); --shadow-lg: 0 14px 38px rgba(0, 0, 0, 0.34); --shadow-glow: 0 10px 24px rgba(224, 255, 50, 0.20); / lime CTA glow / --shadow-stamp: 4px 4px 0 0 rgba(0, 0, 0, 1), 0 2px 8px rgba(0, 0, 0, 0.15); --shadow-stamp-pressed: 2px 2px 0 0 rgba(0, 0, 0, 1), 0 1px 4px rgba(0, 0, 0, 0.10); ``
The shadow-stamp / shadow-stamp-pressed pair is the most distinctive elevation in the system โ reserved for primary yellow CTAs and the "Chi siamo" pill in the header. Borders on those surfaces are 2โ4 px solid black (--border-ink), never subtle hairlines.
โจ Animation & Motion
Motion Tokens
``css --ease-out: cubic-bezier(0.16, 1, 0.3, 1); --t-fast: 140ms; --t-base: 200ms; --t-slow: 500ms; ``
All easings stay close to ease-out / ease-in-out. There is no bounce, no spring, no playful overshoot. Motion is steady and slightly ceremonial.
Named Animations
| Keyframes | Duration | Easing | Used on |
|---|---|---|---|
color-change-4x | 8 s | ease-in-out infinite | .home-gradient homepage container |
border-color-change-4x | 8 s | ease-in-out infinite | .modal-border-gradient modal borders |
color-change-white-cyan | 8 s | ease-in-out infinite | .profile-dashboard-gradient |
heartbeat | 2 s | ease-in-out infinite | heart logo on homepage |
slideUp | 0.6 s | ease-out forwards | hero block entry |
pulse-red | 2 s | ease-in-out infinite | admin rows needing attention |
prefers-reduced-motion: reduce suppresses transitions inside .carnevale-* classes but the homepage color cycle does not carry a motion guard โ it is intentional brand behaviour.
Hover & Press States
Yellow stamp buttons โ on hover, shadow-stamp tightens to shadow-stamp-pressed and the button translates +2px down/right, simulating a physical press.
Lime "Carnevale" buttons โ scale(0.99) on :active, no hover recolour.
Generic CTAs โ same fill, opacity: 0.9 on hover or scale(1.02) for card lifts. Never a darken-on-hover. Links in the ticker use opacity: 0.7 on hover.
๐งฉ Signature Patterns
Stamp Button
The yellow primary CTA. Neo-brutalist: bg-yellow-locarno border-2 border-black shadow-stamp. On hover: shadow-stamp-pressed translate-x-[2px] translate-y-[2px]. Black text, never white. Currently re-declared in ~6 places โ candidate for a <StampButton> component variant.
Phosphor Tagline (.text-locarno-phosphor)
Black text with a #E0FF32 (phosphor lime) text-shadow stroke, uppercase, tight tracking. Defined in globals.css:
``css .text-locarno-phosphor { color: var(--black-true); font-weight: 900; text-transform: uppercase; letter-spacing: 0.04em; text-shadow: 2px 2px 0 var(--lime-accent), -2px -2px 0 var(--lime-accent), 2px -2px 0 var(--lime-accent), -2px 2px 0 var(--lime-accent); -webkit-text-stroke: 1px var(--lime-accent); filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3)); } ``
Used on the homepage hero tagline. Candidate for a <PhosphorHeadline> component.
Editorial Quote (.editorial-quote)
Italic Barnebok 600 in --ink colour. Used across editorial heroes for aphoristic pull-quotes.
Marquee Ticker
Sits above almost everything at bg-black/30 backdrop-blur-md. The separator between every two slang terms is a pill icon (random from the eight, no adjacent duplicates).
DADA Token Box (.dada-token-box)
The rotated, lime-bordered token counter. Plain CSS in globals.css, intentionally a one-off โ do not generalise.
Carnevale UI (.carnevale-*)
Self-contained event UI with glass surfaces, lime CTA, and ghost secondary button. See the .carnevale-* block in globals.css. Keep as-is; do not normalise into the general component system.
๐ฎ Iconography
Pill Iconography (Signature)
The eight colored pills โ red, blue, black, purple, white, pink, orange, green โ are real-photograph PNG capsules at /colored-pills/*.png (Cloudflare R2). Each maps to a Reddit-rooted worldview:
| Pill | Ideology | Origin |
|---|---|---|
| Red | Manosphere "awakening" โ hypergamy, SMV, frame control | r/TheRedPill |
| Blue | Mainstream-romantic worldview | r/TheBluePill |
| Black | Genetic determinism, "looksmaxxing" | r/BlackPillScience |
| Purple | Synthesis / debate-driven middle ground | r/PurplePillDebate |
| White | Active hope after black-pill | r/whitepillman |
| Pink | Feminine-traditional / RedPillWomen | r/RedPillWomen |
| Orange | Bitcoiner sovereignty | r/Bitcoin |
| Green | Healthy Gamer / compassionate dating | r/Healthygamergg |
Pills appear as: ticker separators, floating elements on /dating-mainstream, and the icon on each pill detail page. Do not invent new pills.
Logo
The heart logo (hp-logo-heart-icon-hd.png) is the universal LoveXposure mark. On the homepage it animates with the heartbeat keyframes. Served from R2.
Functional Icons
- Phosphor Icons via
@phosphor-icons/react(components/ui/phosphor-icon.tsx). Weight:boldorregular, neverthin. This is the primary utility icon system. - Inline SVG for one-off chrome โ chevron arrows, the heart-back on "Academia" link.
Emoji
Used as decorative annotation only: ๐ณ in microcopy, ๐ on gated features, ๐ญ/๐ฒ in admin labels. Never as primary icons in user-facing chrome.
Unicode
โ(U+2551, box-drawing double vertical) inDATING 2030โBRAINWASHEDโ part of the wordmark. Do not replace./slashes as breadcrumb separators.
โ๏ธ Content Fundamentals
Tone
Curious, never preachy. The manifesto declares "LoveXposure non prende posizione, non si schiera." Copy stays documentarian even when the subject is divisive. Ironic and occasionally cynical, but never edgy for its own sake. Most hero copy and ticker items are single aphoristic sentences drawn from the 13,199 Dada enunciati corpus.
Language & Pronouns
Italian by default. "Tu" form throughout โ the product talks to you. English loanwords (Ghosting, Breadcrumbing, Rizz) appear as direct quotes from the subject matter, in Title Case.
Casing Rules
- Sentence case for body copy.
- Title Case for top-level nouns (Quiz, Esperimenti, Archivio, Profilo).
- UPPERCASE for hero stamps (
QUIZ โ), section headers in stamps, and the homepage tagline. - Manosphere terms:
red pill/blue pilllowercase in running prose;Red Pill/Blue Pillas page/card titles.
Style Constraints
- Em-dashes are banned. Replace with comma, period, semicolon, or parenthesis.
- No "non X, ma Y" contrast structures. Write assertively.
- No bounce or spring in motion. Steady
ease-in-outonly. - Never darken on hover. Use opacity shift or position translation.
๐ Performance Notes
- ~318 KB total for all active font weights โ served locally, zero CDN requests.
font-display: swapon all@font-facedeclarations.- Mobile body strips all gradients and background images; flat
#000only. backdrop-blurused only on the marquee ticker and the Airdrop callout โ not on every card.
๐ง Implementation Reference
| Topic | File | Lines |
|---|---|---|
@font-face declarations | app/globals.css | 407โ490 |
Palette tokens (:root) | app/globals.css | 579โ621 |
Semantic tokens (:root) | app/globals.css | 624โ675 |
Tailwind @theme inline | app/globals.css | 712โ794 |
| Base layer auto-apply | app/globals.css | 796โ812 |
| Font utility classes | app/globals.css | 815โ871 |
| Background utilities | app/globals.css | 873โ905 |
| Animation keyframes | app/globals.css | 912โ954 |
| Carnevale UI classes | app/globals.css | 263โ349 |
โ ๏ธ Protected Patterns (Do Not Normalise Away)
These are intentional and must not be removed or generalised:
- The
home-gradientanimated background โ 8 s color cycle, always-on. - Mobile fallback: flat
#000000, no gradients. Performance-motivated. - The
.dada-token-boxstyled in plain CSS โ one-off, that's fine. - The
.carnevale-*classes โ self-contained event UI. - The
font-lunchtype*classes โ all three weight utilities for UGC distinction. - The
โcharacter in the wordmarkDATING 2030โBRAINWASHED.
Maintained by: LoveXposure Team Implementation: app/globals.css Last Review: 2026-06-09