# Design Language for tsundere.life

## Aesthetics and Tone

tsundere.life is the **personal life-log of an off-duty cyberpunk** — not the chrome-and-neon overload of a Shibuya billboard, but the apartment afterward, when the rain has dimmed the screens to ambient glow and the city outside is just bokeh through fogged glass. The aesthetic is **cyberpunk in cool-gray remission**: the saturation has been pulled out, the magentas have aged into slate-blues, and the only "neon" left is a single thin cyan accent that the user can almost ignore. Think of it as the morning after Blade Runner — same architecture, lower BPM.

The persona is a **tsundere keeping a life-log** — a domain that is technically a personal feed but stylistically refuses to perform. The tone is **conversational, deflecting, and slightly annoyed at being looked at** ("It's not like I'm tracking my caffeine for *you* or anything"). Headlines are written as if the visitor caught the persona mid-sentence; metric labels read like muttered side-comments rather than dashboard chrome. The site never says "Welcome." It says things like *"oh. you're here."* and *"this counter resets when I sleep, which is — irrelevant."*

The mood is contemplative-resentful, not hostile. Like a Murakami protagonist who happens to live in 2087. Slow-paced, punctuated by small data events (a counter ticking, a particle drifting, a number counting itself down) that the visitor watches the way you watch rain hit a window.

## Layout Motifs and Structure

The page is a **card-grid life-log**: a CSS Grid feed of variable-sized cards, each one a single beat in the persona's day. This is *not* a bento dashboard (no analytics gloss, no KPI framing) and *not* a portfolio grid (no thumbnails). It is closer to a **journaling app cross-bred with a station monitor** — cards are scrappy, irregular, and feel like they were assembled grudgingly.

**Grid System:** `grid-template-columns: repeat(12, 1fr)` with cards spanning 3, 4, 6, or 8 columns at varying heights (160px, 240px, 360px). Gap is `clamp(12px, 1.5vw, 20px)` — tight, almost too tight, like the persona is trying to fit too much into a small apartment. On mobile, it collapses to `repeat(2, 1fr)` with strategic full-width breaks for the largest cards.

**The Header Card (spans 12 cols, 360px tall):** Top-left of the grid. Inside: a soft bokeh-light background (cool-gray circles of light at low opacity, simulating an out-of-focus rainy window) with the domain `tsundere.life` set in condensed type, lowercased, almost embarrassed to be there. Below it, a one-line conversational greeting that *changes per visit* ("ugh, fine, you can stay" / "the heater's broken again" / "oh. you're here.").

**Counter Cards (3-col):** Small square cards each holding a single numeric **counter that animates downward** rather than upward — `days since last cried at a vending machine: 4`, `hours of sleep this week: 23 (it's fine)`, `unread messages from him: 12 (i'm not looking)`. The counter visibly *counter-animates* — increments by ticking digits down then settling — as if reluctant to display itself.

**Quote Card (8-col, 240px):** A long-form muttered quote in larger condensed type, e.g. *"i installed three meditation apps and uninstalled them in the same evening. the algorithm thinks i'm stressed. it's wrong. probably."* No author attribution.

**Vitals Strip (12-col, 100px):** A horizontal row of six tiny readouts — heart rate, ambient temperature (apartment), city air-quality, battery, mood (one of four kanji glyphs that rotate), and "last meal." Numbers count themselves down/up in counter-animate style every 8s.

**Bokeh Backdrop Card (6-col, 360px):** A pure visual card — a CSS-rendered bokeh field (12-20 soft blurred radial-gradient circles in cool grays and one muted cyan) that drifts very slowly. No text. Acts as breathing room in the grid.

**Particle Margins:** The negative space *outside* the grid (at viewport edges) hosts a slow particle-effect field — single-pixel cool-gray motes drifting upward at varying speeds, density 0.3 particles/cm². They are not in the cards; they are *around* them, like dust in a sunbeam.

**No nav bar.** A small fixed strip at the bottom-right shows three lowercase links: `now`, `archive`, `messages.` — set in condensed type, separated by middle dots. That is the entire navigation system.

## Typography and Palette

**Typography:**
- **Display (condensed):** "Oswald" (Google Fonts), weight 300 and 500. Used for the domain name, all card headings, and the quote card. Set in **lowercase only** with `letter-spacing: 0.02em`. The 300 weight is for headings — the persona refuses to shout. Display sizes use `clamp(1.6rem, 4vw, 4rem)`.
- **Counters (condensed mono):** "Saira Condensed" (Google Fonts), weight 500, `font-variant-numeric: tabular-nums`. The condensed proportions keep the counter cards dense without becoming a stat-grid; tabular nums prevent the digits from jittering as they animate down.
- **Body (conversational):** "DM Sans" (Google Fonts), weight 400, `0.95rem / 1.55`. Used for muttered quotes, conversational greetings, and the vitals labels. Slightly humanist so the deflecting copy reads like speech, not chrome.
- **Glyph accents:** "Noto Sans JP" (Google Fonts), weight 300. Used only for the four mood kanji on the vitals strip (穏, 倦, 哀, 苛 — calm, listless, melancholy, irritable). One kanji at a time, large enough to be a glyph not a label.

**Palette (cool-grays with one withheld neon):**
- `#0F1419` — **deep slate** (page background; like a dim apartment at 3am)
- `#1A2129` — **panel slate** (card backgrounds, slightly lifted from page)
- `#2A333D` — **divider gray** (card borders, hairline `1px solid` at 0.6 opacity)
- `#5A6470` — **mid gray** (muted body text, vitals labels)
- `#8B95A1` — **chrome gray** (counter digits at rest, secondary headings)
- `#C8D0D8` — **paper gray** (primary body text — never pure white)
- `#3F4E5C` — **fog blue-gray** (bokeh circles, particle motes)
- `#5DC8D4` — **withheld cyan** (the *only* saturated color — used sparingly: the active counter digit while it's mid-animation, the underline of the current nav link, the persona's heart-rate readout. Never on a CTA, never as a fill of more than 4% of viewport.)

The palette is built so that 96% of the screen is gray, and the cyan only appears in motion or hover — when the eye actually attends to it. This is the cyberpunk gone domestic.

## Imagery and Motifs

**Bokeh as the only "scenery":** The site never uses photographs. The closest it gets to imagery is the **bokeh-background field** rendered entirely in CSS — overlapping `radial-gradient` circles with `filter: blur(18px)` at low opacity, layered in 3 parallax depths. They drift at 0.2px/frame, simulating a rainy apartment window with city lights out of focus. This appears in the header card and the dedicated bokeh card. The bokeh is **explicitly cool-gray** with one cyan circle hidden in the field — an Easter egg of saturation.

**Particle Effects (Margins):** Drifting single-pixel motes in the page margins. Implemented as a `<canvas>` strip 60px wide on the left and right viewport edges (hidden on mobile). 40 particles total, each with random vertical speed (0.1-0.4 px/frame), random horizontal drift (-0.05 to 0.05 px/frame), opacity 0.15-0.35. They feel like dust in light, not sci-fi sparks. **Reduced-motion users get a static field of motes at 0.2 opacity.**

**Counter as a Living Thing:** Every numeric value on the page **counter-animates** rather than appearing instantly. New counter values are reached by *ticking individual digits down* through the wheel (5 → 4 → 3 → ... → target), then settling. The currently-animating digit is the only place the cyan accent appears in steady-state, then it fades back to chrome gray once the number rests. This makes the data feel reluctant, almost reluctantly volunteered.

**The Mood Kanji:** A single Japanese character on the vitals strip rotates between 穏 / 倦 / 哀 / 苛 every 12 seconds, with a soft cross-fade. It is the only time the persona's "feeling" is named, and even then only as a glyph — never translated.

**Hairline Card Borders:** Each card has a `1px solid #2A333D` border with a 1px inset `box-shadow: inset 0 0 0 1px rgba(93,200,212,0.04)` — a near-imperceptible cyan ghost on every card, only visible if you stare. This is the "the neon is still in the walls" detail.

**No icons. No buttons styled as buttons.** Links are underlined text in condensed type. The site looks like a journal that happens to be running on a terminal — not a UI.

## Prompts for Implementation

- Build the page as a **single full-viewport CSS Grid** (`grid-template-columns: repeat(12, 1fr)`, `grid-auto-rows: 80px`, `gap: clamp(12px, 1.5vw, 20px)`) with each card explicitly placed via `grid-column` and `grid-row`. Avoid frameworks; this is a hand-placed feed, not a generic masonry.

- The **header card** is a `<section>` with `grid-column: 1 / -1; grid-row: span 5;`. Inside, layer: (1) a `::before` pseudo-element with the bokeh-field CSS (8 layered `radial-gradient`s with `filter: blur(20px)`); (2) the `tsundere.life` wordmark in Oswald 300 lowercase at `clamp(3rem, 8vw, 7rem)`, color `#C8D0D8`; (3) a one-line greeting in DM Sans 400 at `1rem`, color `#8B95A1`. The greeting is randomized client-side from an array of 8 lines (`"oh. you're here."`, `"the heater's broken again."`, `"i was about to make tea, fine, you can have some."`, `"i don't know why i keep this site up either."`, `"don't read the archive, it's embarrassing."`, `"the rain hasn't stopped in 3 days."`, `"i'm not waiting for anyone."`, `"ugh, fine. stay if you want."`).

- Implement the **counter-animate** effect with a single utility function: given a target number, animate each digit position individually by stepping through 0-9 sequentially with `requestAnimationFrame`, settling at the target digit. Total animation length 800-1200ms with a per-digit offset of 60ms (so the leftmost digit settles first, rightmost last — like a slot machine in reverse). Active digit gets `color: #5DC8D4`, settled digits get `color: #8B95A1`. Re-run the animation every 14 seconds with a slightly mutated value (±1 to ±3) to keep the page alive without ever drawing attention to itself.

- The **bokeh-background** is pure CSS: stack 12 `radial-gradient(circle at X% Y%, rgba(63,78,92,0.4) 0%, transparent 40%)` declarations as multiple `background-image` values on the same element. Apply `filter: blur(14px)` on a wrapper. Animate the wrapper with a 60-second `transform: translate3d()` loop drifting ±20px in both axes. ONE of the gradients is `rgba(93,200,212,0.18)` — the withheld cyan, hidden in the field.

- The **particle-effects** in viewport margins are a `<canvas>` element absolutely positioned at `left: 0; top: 0; width: 60px; height: 100vh;` (and a mirrored one on the right). Each particle: `{ x, y, vy: random(0.1,0.4), vx: random(-0.05,0.05), size: 1, opacity: random(0.15,0.35) }`. Reset to bottom when y < 0. Honor `prefers-reduced-motion: reduce` by drawing once and not animating.

- The **mood kanji** is a 96px-tall span with `font-family: 'Noto Sans JP'`, `font-weight: 300`, color `#C8D0D8`, opacity 0.7. Cross-fade between 穏 / 倦 / 哀 / 苛 with `setTimeout` every 12s using `opacity` transition over 1.5s.

- Card hover state: the cyan inset shadow rises from 0.04 to 0.18 opacity over 400ms. The card does not lift, scale, or rotate. The persona does not perform.

- **No CTAs. No pricing. No testimonials. No stat-grids.** The site is a feed of small, conversational, life-shaped cards. The "conversion" is the visitor lingering long enough to see a counter tick down.

- Bias toward a **full-screen narrative of small data events** — the user scrolls slowly, watches numbers move, reads muttered quotes, and leaves with the same ambient melancholy they'd have after staring at rain.

- Reduced-motion: counters snap to value, bokeh stops drifting, particles render once and freeze, mood kanji stops rotating. The visual hierarchy must still read at rest.

## Uniqueness Notes

1. **Cyberpunk in cool-gray remission, not neon overload:** Every other cyberpunk design in the batch (12% of designs use this aesthetic) leans into magenta/cyan saturation, glitch effects, or HUD overlays. This one *withholds* the neon — 96% cool-gray, with cyan reserved as a behavioral cue (only on actively-animating counters and hover states). That inverts the genre's core gesture and makes the rare cyan feel earned. Cool-grays palette is at 0% in the batch; this is the first to use it.

2. **Counter-animate as the page's primary motion language:** Every numeric value reaches its display state by ticking digits backward through 0-9 like a reverse slot machine, with 60ms per-digit offset. No other design in the batch uses counter-animate as the central motion principle — most use scroll-driven, hover-lift, or fade-in. Treating data as "reluctantly volunteered" is unique.

3. **Conversational tsundere tone in the actual UI copy:** Tone "conversational" sits at 2% in the batch. Combined with the tsundere persona (deflecting, slightly annoyed copy: "ugh, fine, you can stay"), this turns the site from a portfolio/dashboard into a piece of character-writing. The greeting line is randomized per visit to reinforce this.

4. **Bokeh-background as imagery (instead of photography):** Bokeh-background is at 0% in the batch (vs. photography at 82%). Rendering the only "scenery" as pure CSS bokeh — soft cool-gray circles drifting like rain on glass — replaces the dominant photographic mode entirely with an ambient, abstract field.

5. **Particles in the margins, not in the content:** Particle-effects appear *outside* the grid (in 60px viewport-edge canvases), so they read as ambient dust rather than UI decoration. This is structurally different from particle backgrounds that live behind content.

6. **Card-grid as life-log, not portfolio or dashboard:** The card-grid layout is repurposed away from its usual portfolio/bento-dashboard uses into a journaling format with irregular sizes, conversational headings, and no thumbnails — closer to a paper journal than a webapp.

**Chosen seed:** aesthetic: cyberpunk, layout: card-grid, typography: condensed, palette: cool-grays, patterns: counter-animate, imagery: bokeh-background, motifs: particle-effects, tone: conversational

**Avoided patterns from frequency analysis:** photography (82%, dominant — replaced with CSS bokeh), gradient palette (59%, dominant — replaced with flat cool-grays), hand-drawn aesthetic (65%, dominant — replaced with cyberpunk's geometric restraint), scroll-driven and hover-lift patterns (common — replaced with counter-animate as the primary motion), and the tech/nature motif overuse (replaced with ambient particle motes and a single mood kanji).
<!-- DESIGN STAMP
  timestamp: 2026-05-09T18:29:13
  seed: seed:
  aesthetic: tsundere.life is the **personal life-log of an off-duty cyberpunk** — not the ch...
  content_hash: 69f337e0d32a
-->
