# МЕСТО — Design System

> Source of truth for the visual language of mp-llc.ru.
> Reverse-engineered from the live site (`app/`, `components/`, `tailwind.config.ts`, `app/globals.css`) on 2026-05-08.

For brand identity, voice and logo usage rules see [`brandbook.md`](./brandbook.md).
For raw assets see [`logos/`](./logos/) and [`tokens/`](./tokens/).

---

## 1. Foundations

### 1.1 Brand color (primary navy)

| Token | Value | Where it lives | Use |
|---|---|---|---|
| **Brand Navy** | `#071246` · `hsl(229 82% 15%)` | `--primary` in `globals.css`, `app/icon.svg`, `<meta theme-color>`, viewport | Logo glyph, all UI primary surfaces, buttons, links, favicon, mobile chrome, OG |

The brand uses a single source of truth. CSS resolves through `hsl(var(--primary))`, design exports through `#071246`.

### 1.2 Full palette (HSL tokens)

Tokens come from `app/globals.css` (`:root`) and resolve through Tailwind's `hsl(var(--token))` pattern. Hex values are computed for design-tool use.

| Role | Token | HSL | Hex (approx.) | Notes |
|---|---|---|---|---|
| Background | `--background` | `228 33% 99%` | `#FAFBFD` | App bg, near-white cool |
| Foreground | `--foreground` | `226 33% 18%` | `#1F2438` | Body text |
| Card | `--card` | `0 0% 100%` | `#FFFFFF` | Card / header surface |
| Card fg | `--card-foreground` | `226 33% 18%` | `#1F2438` | Text on cards |
| Popover | `--popover` | `0 0% 100%` | `#FFFFFF` | Popover surface |
| **Primary** | `--primary` | `229 82% 15%` | `#071246` | CTA, brand mark |
| Primary fg | `--primary-foreground` | `0 0% 100%` | `#FFFFFF` | Text on primary |
| Secondary | `--secondary` | `227 32% 88%` | `#D8DDE9` | Subtle chip / surface |
| Secondary fg | `--secondary-foreground` | `226 33% 18%` | `#1F2438` | |
| Muted | `--muted` | `225 31% 95%` | `#EDF0F6` | Skeleton, inactive bg |
| Muted fg | `--muted-foreground` | `228 32% 53%` | `#6F7B9C` | Secondary copy |
| Accent | `--accent` | `225 33% 93%` | `#E5E9F2` | Hover / focus surface |
| Accent fg | `--accent-foreground` | `229 82% 15%` | `#071246` | Active nav text |
| Destructive | `--destructive` | `0 82% 65%` | `#EE5959` | Errors, delete |
| Destructive fg | `--destructive-foreground` | `0 0% 100%` | `#FFFFFF` | |
| Border | `--border` | `227 30% 91%` | `#DFE3EE` | Hairlines |
| Input | `--input` | `227 30% 91%` | `#DFE3EE` | Form border |
| Ring (focus) | `--ring` | `229 82% 15%` | `#071246` | Focus outline |

**Charts / data viz** (5-step navy ramp):

| Token | HSL | Hex | Use |
|---|---|---|---|
| `--chart-1` | `229 82% 15%` | `#071246` | Primary series |
| `--chart-2` | `228 82% 28%` | `#0E3382` | Secondary series |
| `--chart-3` | `228 83% 66%` | `#5C7CEA` | Tertiary |
| `--chart-4` | `228 82% 78%` | `#92A6F0` | Highlight |
| `--chart-5` | `226 32% 71%` | `#A0AAC4` | Neutral series |

**Selection color:** `bg: hsl(var(--primary))` = `#071246`, `fg: #FFFFFF`.

### 1.3 Typography

**Two-typeface system** — **Inter Bold (700)** is used **only for the logo** (mark + wordmark) and ships as outlined SVG paths, never loaded as a webfont. **Fira Sans** handles everything else: headlines, body, UI, eyebrows, code. Loaded via `next/font/google` and exposed as CSS var `--font-fira`. Mapped to `font-sans` only. Tailwind's default `font-mono` falls through to the system mono stack (`ui-monospace, SFMono-Regular, Menlo, …`) — used for code blocks in admin and chart tooltips.

| Property | Value |
|---|---|
| Family | `Fira Sans`, `system-ui`, `sans-serif` |
| Subsets | `latin`, `cyrillic` |
| Weights loaded | 400, 500, 600, 700 |
| Italic | not loaded — do not use italic |
| Variable name | `var(--font-fira)` |

**Type scale** (Tailwind, observed in production):

| Role | Class | Size | Weight | Where |
|---|---|---|---|---|
| Display H1 | `text-4xl md:text-5xl lg:text-6xl` | 36 / 48 / 60 px | 600 (semibold) | Hero |
| H2 | `text-2xl md:text-3xl lg:text-4xl` | 24 / 30 / 36 px | 600 | Section heads |
| H3 | `text-lg` | 18 px | 600 | Card titles |
| Body | `text-base` | 16 px | 400 | Paragraphs |
| Body small | `text-sm` | 14 px | 400 | Secondary copy, nav |
| Micro | `text-xs` | 12 px | 600 + uppercase | Eyebrows, footers |
| Brand wordmark | `text-base font-semibold tracking-[0.15em] uppercase` | 16 px / 600 / +0.15em | Header, footer |

Line-height: defaults to Tailwind `leading-relaxed` (1.625) on body, `leading-tight` (1.25) on display.

### 1.4 Spacing & layout

- Container: `max-w-7xl` (= 80rem / 1280 px) with `px-6` (24 px) gutter.
- Vertical rhythm for sections: `py-20 lg:py-28` (80 / 112 px).
- Grid: 12-column logical, but expressed as `md:grid-cols-2`, `lg:grid-cols-3`, `lg:grid-cols-4`.
- Card padding: `p-6` (24 px).
- Header padding: `px-6 py-4` (24 / 16).

### 1.5 Radii

Set via `--radius: 0.375rem` (6 px), exposed as Tailwind `rounded-md`.

| Token | Value | Tailwind |
|---|---|---|
| `--radius` (base) | 6 px | `rounded-md` |
| `+2` derived | 8 px | `rounded-lg` |
| `-2` derived | 4 px | `rounded-sm` |
| Pill | full | `rounded-full` (badges, slider dots) |

### 1.6 Elevation / shadow

Single brand shadow:

```css
shadow-mesto: 0 2px 6px 0 rgba(0, 0, 0, 0.08);
```

Used on header, cards, primary CTAs. On hover cards lift to Tailwind `shadow-lg`.

### 1.7 Motion

- Durations: `300ms` (mobile menu, micro), `500ms` (slider dot), `1000ms` (hero crossfade).
- Easings: default Tailwind (ease in-out).
- Patterns: opacity crossfade for hero images, height transitions for mobile menu, `translate-x-0.5` on link arrow hover.
- No spring physics, no parallax, no scroll-driven animation. Quiet motion language.

---

## 2. Component recipes

The site uses shadcn/ui primitives (Radix + cva) plus a few custom sections. Default the design contract to these recipes:

### 2.1 Button (primary)

```tsx
<Link
  href="/contacts"
  className="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90"
/>
```

Variants from `components/ui/button.tsx`: `default`, `destructive`, `outline`, `secondary`, `ghost`, `link`. Sizes: `sm`, `default`, `lg`, `icon`.

### 2.2 Card (content)

```tsx
<div className="rounded-md border border-border bg-card p-6 shadow-mesto" />
```

Hover variant: `transition-shadow hover:shadow-lg`. Always pair with `border-border` — never borderless.

### 2.3 Step / index card

Numbered card pattern (used in `approach-section`, `focus-section`):

```tsx
<span className="inline-flex h-9 w-9 items-center justify-center rounded-md bg-primary text-sm font-semibold text-primary-foreground">
  01
</span>
```

### 2.4 Header

`fixed top-0` · `bg-card/95` · `backdrop-blur-sm` · `shadow-mesto` · `border-b`. Wordmark left, nav right, primary CTA on far right.

### 2.5 CTA section

Full-bleed `bg-primary` band with `text-primary-foreground`, contrasting `bg-primary-foreground text-primary` button. Used as page closer.

### 2.6 Hero

Full-screen `Image fill object-cover` with `bg-primary/65` overlay, headline in `text-primary-foreground`, slider dots bottom-right.

### 2.7 Form input

```tsx
<input className="h-10 rounded-md border border-input bg-background px-3 text-sm ring-offset-background focus:ring-2 focus:ring-ring" />
```

---

## 3. Iconography

- Library: **Lucide React** (`lucide-react`).
- Sizing: 16 / 18 / 20 px — match adjacent text size.
- Stroke: `1.5` (set explicitly on inline SVGs in the codebase).
- Color: inherit `currentColor`. Never hard-code icon fills.

Inline SVG conventions (from `site-header`, `focus-section`):

```html
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
  <path d="…" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
```

---

## 4. Accessibility & semantics

- `lang="ru"` set on `<html>`. All copy is Russian-first, with `ru-RU` alternate.
- Color contrast: text on `bg-primary` (`#071246` / `#FFFFFF`) ≈ 14:1 — AAA. Muted-foreground on background ≈ 4.6:1 — AA for body, AA-large only for large text.
- Focus: `focus-visible:ring-2 focus-visible:ring-ring` on all interactive primitives.
- Hit area: minimum 36 × 36 (`h-9 w-9` on icon buttons).
- Mobile menu: `aria-expanded`, `aria-label` on toggle.
- Hero slider: dots have `aria-label="Slide N"`.

---

## 5. Image system

- Formats served: `image/avif`, `image/webp` (Next.js `images.formats`).
- Hero crossfade ratio: 16:9-ish, fills viewport `min-h-[600px] lg:min-h-[700px]`.
- Portfolio grid: aspect 4:3, `rounded-md` corners, no border.
- Always provide `alt` — the schema treats empty alt as decorative only.

---

## 6. SEO & meta surfaces

- Title template: `%s — МЕСТО`. Default: `МЕСТО — Pop-Up, выставки, инсталляции и витрины`.
- OG image: 1200 × 630, generated on the fly in `app/opengraph-image.tsx`. See [`logos/og-template.svg`](./logos/og-template.svg) for the editable source.
- Theme color (mobile chrome): `#071246`.
- JSON-LD: `Organization` + `WebSite` injected in root layout.

---

## 7. Tokens — drop-in files

| File | Use |
|---|---|
| [`tokens/colors.json`](./tokens/colors.json) | Style Dictionary / Figma Tokens compatible |
| [`tokens/typography.json`](./tokens/typography.json) | Type scale |
| [`tokens/tokens.css`](./tokens/tokens.css) | CSS custom properties — drop into `globals.css` |

---

## 8. Do / Don't

### Do
- Lead with **navy `#071246`** as the only saturated brand color.
- Stack content on near-white (`#FAFBFD`) cards over the navy.
- Use `tracking-[0.15em] uppercase` only for the wordmark and micro-eyebrows — nowhere else.
- Keep motion under 300 ms outside of hero crossfade.
- Reuse the navy ramp (`chart-1…5`) for all data viz instead of inventing new accent colors.

### Don't
- Don't introduce a third brand color or accent (no orange/green/red CTAs — destructive red is for errors only).
- Don't use italics — Fira Sans italic is not loaded.
- Don't apply `shadow-mesto` to text; it's a surface shadow.
- Don't render the wordmark below 12 px (cyrillic is illegible). Use the monogram instead.
- Don't gradient the navy. The brand is flat.

---

## 9. Production status — applied

- ✅ **Primary color unified** — `--primary` (and dependent `--ring`, `--accent-foreground`, `--chart-1`, `--sidebar-*`) set to `229 82% 15%` (= `#071246`) in `app/globals.css`. `::selection` switched to `hsl(var(--primary))`.
- ✅ **Logo source files added** — canonical SVGs in [`logos/`](./logos/): mark and wordmark in light / reverse / outlined variants. **Mark and wordmark are never combined into a lockup** — pick one or the other.
- ✅ **Font aliases cleaned up** — `font-serif` and `font-mono` removed from `tailwind.config.ts`. `font-mono` now resolves to the system mono stack (correct for code blocks in admin and chart tooltips). `font-serif` is unused.
- ✅ **PNG fallbacks generated** — favicon at `16/32/64/128/192/256/512/1024`, multi-resolution `favicon.ico`, OG `1200×630` (+ `2400×1260` retina), wordmark raster at `480w/960w/1920w`. See [`logos/png/`](./logos/png/) and the [`make-pngs.sh`](./logos/png/make-pngs.sh) regen script. Production app icons (`public/icon-192.png`, `public/icon-512.png`, `app/favicon.ico`) regenerated from canonical sources.
