@import 'tailwindcss'; @import 'tw-animate-css'; /* Google Fonts — Inter / JetBrains Mono / Tektur (handoff spec). * Stage 3.9: @nstart/ui удалён, fonts/theme imports + @source directive * убраны. Tailwind v4 теперь scan'ит только наш src/. */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Tektur:wght@500;600;700&display=swap'); /* === Dark mode trigger === * shadcn использует .dark class по умолчанию. Handoff просит [data-theme="dark"] * на . Custom variant связывает оба пути — компоненты с `dark:` modifier * срабатывают при любом из условий. */ @custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *)); /* === DESIGN TOKENS — Light theme (Earth, default :root) === */ :root { /* Earthy light v3 — neutralized page bg per user preference. * Прошлая версия #fbf8ee (handoff intent) казалась слишком жёлтой; теперь * используем нейтральный warm white #faf9f5. Полную Earth cream версию * можно вернуть через [data-theme="earth-cream"] (opt-in). */ --color-ink: #1a1714; --color-ink-2: #52483d; --color-mute: #8c8276; --color-bg: #faf9f5; --color-surface: #ffffff; --color-surface-2: #f5f3ec; --color-line: #e6e1d4; --color-line-2: #efeae0; --color-navy: #3a2818; --color-accent: #b05a2e; /* Alpha 12% across all themes per DESIGN.md §17 — was 11% (light) / 16% * (dark); drift caused subtle saturation difference в info badges between * themes. Visually negligible diff на light, slightly weaker tint в dark. */ --color-accent-bg: rgb(176 90 46 / 12%); --color-on-accent: #ffffff; --color-green: #4f7038; --color-green-bg: #e4ead0; --color-warn: #a8762a; --color-warn-bg: #f6e8bc; --color-pink: #a64636; --color-pink-bg: #f4d9cd; --color-purple: #7a4a2e; /* Scope tint backgrounds (per ui-kit) — для PUBLIC/INTERNAL/TENANT chips */ --bg-public: rgb(176 90 46 / 13%); --bg-internal: #f6e8bc; --bg-tenant: #f4d9cd; /* Workflow state backgrounds (DRAFT/LIVE/DEPRECATED) */ --bg-draft: var(--color-line-2); --bg-live: #e4ead0; --bg-deprec: #f4d9cd; /* Alert variant tokens (info/warn/err/ok) — bg + border. shadcn Alert * примет эти через variant overrides. */ --al-info-bg: rgb(176 90 46 / 9%); --al-info-bd: rgb(176 90 46 / 28%); --al-warn-bg: #f6e8bc; --al-warn-bd: #e2c982; --al-err-bg: #f4d9cd; --al-err-bd: #dfb29e; --al-ok-bg: #e4ead0; --al-ok-bd: #bcc995; /* Shadow tokens per ui-kit (used by drawer/modal/toast) */ --shadow-l: 0 12px 30px -16px rgba(50, 30, 15, 0.18); --shadow-m: 0 12px 28px -12px rgba(50, 30, 15, 0.22); --shadow-toast: 0 12px 30px -10px rgba(40, 25, 10, 0.38); --shadow-drawer: 0 1px 2px rgba(50, 30, 12, 0.18); /* Toast cap-style header color — orange-cream per handoff line 304 */ --toast-cap: #d4a07a; /* Avatar background tones (success/error scope) */ --avt-pink-bg: #f4d9cd; --avt-green-bg: #e4ead0; /* shadcn semantic tokens — re-mapped onto наши значения */ --background: var(--color-bg); --foreground: var(--color-ink); --card: var(--color-surface); --card-foreground: var(--color-ink); --popover: var(--color-surface); --popover-foreground: var(--color-ink); --primary: var(--color-navy); --primary-foreground: var(--color-on-accent); --secondary: var(--color-surface-2); --secondary-foreground: var(--color-ink); --muted: var(--color-surface-2); --muted-foreground: var(--color-mute); --accent: var(--color-accent); --accent-foreground: var(--color-on-accent); --destructive: var(--color-pink); --destructive-foreground: var(--color-on-accent); --border: var(--color-line); --input: var(--color-line); --ring: var(--color-accent); } /* Claude-light theme — warm cream less saturated. Same accent/navy palette * но bg более нейтральный (для users которые не любят жёлтый Earth). */ [data-theme='claude-light'] { --color-ink: #2c2b27; --color-ink-2: #5a564f; --color-mute: #8a8474; --color-bg: #faf9f5; --color-surface: #ffffff; --color-surface-2: #f5f3ec; --color-line: #e6e1d4; --color-line-2: #efeae0; --color-navy: #d97757; --color-accent: #d97757; --color-accent-bg: rgb(217 119 87 / 12%); --color-on-accent: #ffffff; --color-green: #4a7d4f; --color-green-bg: #dde9da; --color-warn: #b97c2f; --color-warn-bg: #fcecc7; --color-pink: #b34d6a; --color-pink-bg: #f8d8de; --color-purple: #a85d3e; --bg-public: rgb(217 119 87 / 14%); --bg-internal: #fcecc7; --bg-tenant: #f8d8de; --bg-draft: #efeae0; --bg-live: #dde9da; --bg-deprec: #f8d8de; --al-info-bg: rgb(217 119 87 / 10%); --al-info-bd: rgb(217 119 87 / 30%); --al-warn-bg: #fcecc7; --al-warn-bd: #ecd393; --al-err-bg: #f8d8de; --al-err-bd: #ecb6c2; --al-ok-bg: #dde9da; --al-ok-bd: #bdd3b9; --shadow-l: 0 12px 30px -16px rgba(89, 67, 40, 0.22); --shadow-m: 0 12px 28px -12px rgba(89, 67, 40, 0.20); --shadow-toast: 0 14px 36px -10px rgba(89, 67, 40, 0.30); --shadow-drawer: 0 1px 2px rgba(89, 67, 40, 0.18); --toast-cap: #f5c8b3; --avt-pink-bg: #f8d8de; --avt-green-bg: #dde9da; --background: var(--color-bg); --foreground: var(--color-ink); --card: var(--color-surface); --card-foreground: var(--color-ink); --popover: var(--color-surface); --popover-foreground: var(--color-ink); --primary: var(--color-accent); --primary-foreground: var(--color-on-accent); --secondary: var(--color-surface-2); --secondary-foreground: var(--color-ink); --muted: var(--color-surface-2); --muted-foreground: var(--color-mute); --accent: var(--color-accent); --accent-foreground: var(--color-on-accent); --destructive: var(--color-pink); --destructive-foreground: var(--color-on-accent); --border: var(--color-line); --input: var(--color-line); --ring: var(--color-accent); } [data-theme='dark'] { --color-ink: #f0ece4; --color-ink-2: #c8c1b3; --color-mute: #8a8474; --color-bg: #1c1a17; --color-surface: #262421; --color-surface-2: #2e2b27; --color-line: #3a3733; --color-line-2: #2d2a27; --color-navy: #d97757; --color-accent: #d97757; /* Alpha 12% normalized per DESIGN.md §17 — was 16% on dark theme. */ --color-accent-bg: rgb(217 119 87 / 12%); --color-on-accent: #1c1a17; --color-green: #6fa97d; --color-green-bg: rgb(111 169 125 / 18%); --color-warn: #d4a653; --color-warn-bg: rgb(212 166 83 / 18%); --color-pink: #d18272; --color-pink-bg: rgb(209 130 114 / 20%); --color-purple: #a991d4; --bg-public: rgb(217 119 87 / 18%); --bg-internal: rgb(212 166 83 / 18%); --bg-tenant: rgb(209 130 114 / 20%); --bg-draft: #2d2a27; --bg-live: rgb(111 169 125 / 20%); --bg-deprec: rgb(209 130 114 / 20%); --al-info-bg: rgb(217 119 87 / 10%); --al-info-bd: rgb(217 119 87 / 35%); --al-warn-bg: rgb(212 166 83 / 10%); --al-warn-bd: rgb(212 166 83 / 35%); --al-err-bg: rgb(209 130 114 / 10%); --al-err-bd: rgb(209 130 114 / 35%); --al-ok-bg: rgb(111 169 125 / 10%); --al-ok-bd: rgb(111 169 125 / 35%); --shadow-l: 0 12px 30px -16px rgba(0, 0, 0, 0.6); --shadow-m: 0 12px 28px -12px rgba(0, 0, 0, 0.55); --shadow-toast: 0 14px 36px -10px rgba(0, 0, 0, 0.7); --shadow-drawer: 0 1px 2px rgba(0, 0, 0, 0.5); --toast-cap: #f0c3ab; --avt-pink-bg: rgb(209 130 114 / 22%); --avt-green-bg: rgb(111 169 125 / 22%); --background: var(--color-bg); --foreground: var(--color-ink); --card: var(--color-surface); --card-foreground: var(--color-ink); --popover: var(--color-surface); --popover-foreground: var(--color-ink); --primary: var(--color-navy); --primary-foreground: var(--color-on-accent); --secondary: var(--color-surface-2); --secondary-foreground: var(--color-ink); --muted: var(--color-surface-2); --muted-foreground: var(--color-mute); --accent: var(--color-accent); --accent-foreground: var(--color-on-accent); --destructive: var(--color-pink); --destructive-foreground: var(--color-on-accent); --border: var(--color-line); --input: var(--color-line); --ring: var(--color-accent); } /* Tailwind v4 @theme inline — экспонирует CSS vars как utility classes * (`bg-bg`, `text-ink`, `border-line`, `bg-accent` и т.д.). */ @theme inline { --color-bg: var(--color-bg); --color-surface: var(--color-surface); --color-surface-2: var(--color-surface-2); --color-ink: var(--color-ink); --color-ink-2: var(--color-ink-2); --color-mute: var(--color-mute); --color-line: var(--color-line); --color-line-2: var(--color-line-2); --color-navy: var(--color-navy); --color-accent: var(--color-accent); --color-accent-bg: var(--color-accent-bg); --color-on-accent: var(--color-on-accent); --color-green: var(--color-green); --color-green-bg: var(--color-green-bg); --color-warn: var(--color-warn); --color-warn-bg: var(--color-warn-bg); --color-pink: var(--color-pink); --color-pink-bg: var(--color-pink-bg); --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; --font-mono: 'JetBrains Mono', 'SF Mono', monospace; --font-display: 'Tektur', 'Inter', sans-serif; /* Font scale — НЕ переопределяем Tailwind defaults. Все наши места * используют семантические @utility ниже (text-body, text-cell, text-mono, * text-title-*, text-cap). text-sm/text-xs/text-2xs не используются нигде * после Stage 3.9 — @nstart/ui (который требовал --text-sm override) * удалён. */ --radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px; } /* === Semantic typography utilities per design_handoff_ordinis_mdm/README.md === * Type system — 7 ролей, каждая соответствует месту в UI: * * text-title-xl — 22/600 modal title, section header (rare) * text-title-lg — 17/600 page title в editor * text-title-md — 15/600 dictionary card title * text-body — 13/400 workhorse: body, buttons, tabs, inputs * text-cell — 12.5/500 table cell text * text-mono — 11/500 Mono: IDs, dates, FK refs * text-cap — 10.5/600 Tektur UPPERCASE caption / section label * * Color и weight overrides поверх — добавлять отдельными utility classes * (e.g. `text-body font-medium text-ink`). НЕ накладывать font-mono/ * font-display/uppercase/tracking — они baked в соответствующие utility. */ /* font-family: var(--font-sans) explicit — наследование может ломаться когда * титлы используются внутри @nstart/ui Card/PageHeader которые sеtают * font-family: Tektur на parent. После Stage 3.9 (nstart removed) можно * убрать font-family из этих utilities — body inherit будет достаточно. */ @utility text-title-xl { font-family: var(--font-sans); font-size: 22px; font-weight: 600; line-height: 1.2; letter-spacing: -0.01em; } @utility text-title-lg { font-family: var(--font-sans); font-size: 17px; font-weight: 600; line-height: 1.25; letter-spacing: -0.005em; } @utility text-title-md { font-family: var(--font-sans); font-size: 15px; font-weight: 600; line-height: 1.3; } @utility text-body { font-family: var(--font-sans); font-size: 13px; font-weight: 400; line-height: 1.45; } @utility text-cell { font-family: var(--font-sans); font-size: 12.5px; font-weight: 500; line-height: 1.35; } @utility text-mono { font-family: var(--font-mono); font-size: 11px; font-weight: 500; line-height: 1.4; } @utility text-cap { font-family: var(--font-display); font-size: 10.5px; font-weight: 600; line-height: 1; text-transform: uppercase; letter-spacing: 0.10em; } html, body, #root { height: 100%; } body { background: var(--color-bg); color: var(--color-ink); font-family: var(--font-sans); font-feature-settings: 'ss01', 'cv11', 'cv02', 'cv03', 'cv04'; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } /* Tektur uppercase caption helper — handoff .cap class */ .cap { font-family: var(--font-display); font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.10em; color: var(--color-mute); } /* === GlobeLoader keyframes — orbital spinner (src/ui/components/globe-loader.tsx). * Класс .globe-loader на wrapper'е активирует вложенные .globe-* animations * через стандартные CSS animation rules. Transform-only — GPU-композитятся. */ @keyframes ord-globe-spin { to { transform: rotate(360deg); } } @keyframes ord-globe-pulse { 0%, 100% { opacity: 0.18; } 50% { opacity: 0.42; } } /* transform-box default = view-box для SVG elements — transform-origin * считается в SVG user coordinates (viewBox 0 0 200 200). 100px 100px = * центр глобуса. Прошлая версия с transform-box: fill-box ломала орбиты * (origin становился offset bounding-box'а каждой группы — арки летали * вокруг неправильной точки). Прототип HTML использует default — copy. */ .globe-loader .globe-whirl { transform-origin: 100px 100px; animation: ord-globe-spin 3.6s linear infinite; } .globe-loader .globe-whirl-rev { transform-origin: 100px 100px; animation: ord-globe-spin 5.4s linear infinite reverse; } .globe-loader .globe-pulse { transform-origin: 100px 100px; animation: ord-globe-pulse 2.4s ease-in-out infinite; } /* Sphere/land внутри globe-loader rotates через d3 projection (rAF * пересчитывает path d-attr), не через CSS transform — иначе land * distort'илась бы при rotation (no projection math). */ @media (prefers-reduced-motion: reduce) { .globe-loader .globe-whirl, .globe-loader .globe-whirl-rev, .globe-loader .globe-pulse { animation: none; } } /* === Legacy fallback: старые компоненты используют nstart token names * (--color-carbon, --color-ultramarain etc). Маппим их на новые pending * полная миграция. === */ :root, [data-theme='dark'] { --color-carbon: var(--color-ink); --color-ultramarain: var(--color-accent); --color-orbit: var(--color-warn); --color-regolith: var(--color-line); --color-asteroid: var(--color-mute); } /* === Graph edge flow — космо-анимация для активных связей. * stroke-dashoffset animation создаёт ощущение потока частиц от source * к target. Только на highlighted edges (hover state), default edges * статичные dashed pattern. Respects prefers-reduced-motion. === */ @keyframes graph-edge-flow { to { stroke-dashoffset: -28; } } .graph-edge-flow { animation: graph-edge-flow 1.4s linear infinite; } @media (prefers-reduced-motion: reduce) { .graph-edge-flow { animation: none; } } /* === react-day-picker — кастомизация под ordinis design system. * Без этих overrides DayPicker рендерится дефолтными rdp-* стилями * (большие квадратные ячейки, нет hover/selected состояний под наш * accent). Класс `.ord-day-picker` ставится на корень DayPicker'а * в DateRangePicker и PeriodFilter. === */ .ord-day-picker { --rdp-day-width: 2rem; --rdp-day-height: 2rem; --rdp-day_button-width: 2rem; --rdp-day_button-height: 2rem; --rdp-day_button-border-radius: 6px; --rdp-months-gap: 1rem; --rdp-nav_button-height: 1.75rem; --rdp-nav_button-width: 1.75rem; --rdp-weekday-text-transform: lowercase; --rdp-weekday-padding: 0.25rem 0; --rdp-month_caption-font: 600 0.875rem/1.25 'Inter', sans-serif; --rdp-day-font: 400 0.8125rem/1 'JetBrains Mono', monospace; --rdp-weekday-font: 500 0.7rem/1 'Inter', sans-serif; --rdp-accent-color: var(--color-accent); --rdp-accent-background-color: var(--color-accent-bg); font-family: 'Inter', sans-serif; color: var(--color-ink); } /* Multi-month layout (если когда-то нужно): 2 столбца side-by-side * вместо wrap'а вниз. */ .ord-day-picker .rdp-months { flex-wrap: nowrap; } .ord-day-picker .rdp-month_caption { padding: 0 0 0.5rem; color: var(--color-ink); } .ord-day-picker .rdp-weekday { color: var(--color-mute); text-transform: lowercase; font-weight: 500; } .ord-day-picker .rdp-day_button { border-radius: 6px; transition: background-color 120ms, color 120ms; } .ord-day-picker .rdp-day_button:hover:not(:disabled):not([aria-disabled='true']) { background-color: var(--color-surface-2); color: var(--color-ink); } .ord-day-picker .rdp-day.rdp-outside .rdp-day_button { color: var(--color-mute); opacity: 0.55; } .ord-day-picker .rdp-day.rdp-today .rdp-day_button { font-weight: 600; outline: 1px solid var(--color-line-2, var(--color-line)); outline-offset: -2px; } /* Selected range */ .ord-day-picker .rdp-day.rdp-selected .rdp-day_button { background-color: var(--color-accent); color: var(--color-on-accent, white); font-weight: 500; } .ord-day-picker .rdp-day.rdp-range_middle .rdp-day_button { background-color: var(--color-accent-bg); color: var(--color-accent); border-radius: 0; } .ord-day-picker .rdp-day.rdp-range_start .rdp-day_button { border-top-right-radius: 0; border-bottom-right-radius: 0; } .ord-day-picker .rdp-day.rdp-range_end .rdp-day_button { border-top-left-radius: 0; border-bottom-left-radius: 0; } .ord-day-picker .rdp-day.rdp-range_start.rdp-range_end .rdp-day_button { border-radius: 6px; } /* Nav buttons */ .ord-day-picker .rdp-button_previous, .ord-day-picker .rdp-button_next { border-radius: 6px; color: var(--color-accent); transition: background-color 120ms; } .ord-day-picker .rdp-button_previous:hover, .ord-day-picker .rdp-button_next:hover { background-color: var(--color-surface-2); } .ord-day-picker .rdp-button_previous:disabled, .ord-day-picker .rdp-button_next:disabled { opacity: 0.35; cursor: not-allowed; }