# Trade-In UI — how to build with this design system

React components from the GenDesign **trade-in** product (real-estate trade-in valuation, RU/ЕКБ). Import everything from `tradein-mvp-frontend` (bound at `window.TradeInUI`). The cards are domain-specific and **prop-driven** — you compose them with data, you don't restyle their internals.

## Setup & wrapping (required for data components)

Most cards take their data as **props** and render standalone. But several read app state through **TanStack Query** hooks (`UserMenu`, `Topbar`, `RouteGuard` → `useMe`; `HouseAnalyticsSection`, `PlacementHistoryCard`, `StreetDealsCard` → estimate sub-queries). Those MUST be rendered inside a `QueryClientProvider` (the app ships one as `Providers`). Without it they throw "No QueryClient set"; with an empty client they render their loading/null state. Prop-only cards (`HeroSummary`, `OfferCard`, `PriceRangeBar`, `DealsCard`, `ListingsCard`, charts…) need no provider.

```tsx
import { Providers, HeroSummary, OfferCard } from "tradein-mvp-frontend";

<Providers>
  <main className="page" style={{ display: "flex", flexDirection: "column", gap: 24 }}>
    <HeroSummary estimate={estimate} input={input} onResubmit={fn} />
    <OfferCard estimate={estimate} brandSlug={null} />
  </main>
</Providers>
```

Load `styles.css` once at the root — it pulls the component CSS + design tokens.

## Styling idiom — global stylesheet + CSS custom properties

This is **not Tailwind and not CSS-in-JS**. Styling is a **global stylesheet** of semantic class names plus **CSS custom-property design tokens**. Two rules:

1. **The components carry their own classes** (`.card`, `.card-head`, `.section-kicker`, `.count-strip`, `.pricebar`, `.source-chip`, `.control`, `.pill`, `.mono`, `.top-nav`, `.meta-grid`…). Don't reach inside them; compose via props. New class names you invent will not exist in the stylesheet.
2. **For your own layout/wrapper glue, use the token vars + inline styles**, on the 4/8/12/16/24/32 spacing scale (tabular-nums for numbers). Color/shape tokens, all defined in the shipped CSS:

| Group | Tokens |
|---|---|
| Surface | `--bg-app` `--bg-card` `--bg-card-alt` `--bg-headline` |
| Text | `--fg-primary` `--fg-secondary` `--fg-tertiary` `--fg-on-dark` |
| Brand/CTA | `--accent` `--accent-hover` `--accent-soft` `--accent-2` |
| Semantic | `--success` `--warn` `--danger` (`*-soft` variants) |
| Border | `--border-soft` `--border-card` `--border-strong` |
| Shape/type | `--radius` `--radius-sm` `--radius-lg` `--shadow-md` `--font-sans` (Manrope) `--font-mono` `--container` |

```tsx
<div style={{ background: "var(--bg-card)", border: "1px solid var(--border-card)",
  borderRadius: "var(--radius)", padding: 16, color: "var(--fg-primary)",
  fontFamily: "var(--font-sans)" }}>
  <b style={{ color: "var(--accent)" }}>9 850 000 ₽</b>
</div>
```

## Where the truth is

- **Styles/tokens:** read the bound `styles.css` and its `@import` `_ds_bundle.css` — the authoritative class + token list.
- **Per component:** `<Name>.d.ts` (props) and `<Name>.prompt.md` (usage). NB: synth-built `.d.ts` props are loose (`[key: string]: unknown`); the `.prompt.md` + preview card show real prop shapes and realistic data.
- Money/area/dates are RU-formatted (`toLocaleString("ru-RU")`, `₽`, `м²`). Keep that idiom.
