gendesign/.design-sync/conventions.md
bot-backend e70f5da82b
All checks were successful
CI / changes (pull_request) Successful in 7s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
chore(design-sync): sync inputs for claude.ai/design trade-in DS
Imports tradein-mvp/frontend (38 components) to a claude.ai/design
design-system project. Synth-entry build (Next.js app, no dist):
- overrides/source-kit.mjs: process.env shim for browser IIFE
- preview-provider.tsx: seeded TanStack Query provider (mirrors the
  repo's offline ui-preview client) so fetch-coupled + auth-gated cards render
- previews/*.tsx: authored preview compositions (real fixture data)
- conventions.md: README header for the design agent
- config.json + NOTES.md: reproducible re-sync inputs
2026-06-27 14:40:50 +03:00

3.3 KiB

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, RouteGuarduseMe; 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.

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
<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.