{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "venly-tokens", "type": "registry:item", "title": "Venly design tokens", "description": "The white-label contract: every colour, radius, type size, density and spacing value the kit reads. A reskin edits this file and nothing else.", "files": [ { "path": "registry/styles/tokens.css", "type": "registry:file", "target": "~/components/venly/styles/tokens.css", "content": "/**\n * Venly UI – the white-label contract.\n *\n * A reskin must be this file and nothing else. Every component in the kit\n * reads exclusively from these custom properties; no component carries a raw\n * hex value at the call site.\n *\n * Acceptance test for any reskin: map every --state-*-fg/-bg pair to greys\n * and confirm status is still legible. The kit guarantees its half of that\n * contract by pairing every state hue with a glyph or word (state is never\n * carried by colour alone); your palette must not break the other half\n * (sufficient contrast between -fg and -bg).\n *\n * Colour budget by design: 3 semantic hues + 1 brand hue + a neutral ramp.\n * Do not add a hue per status – reserve colour for states an operator must\n * act on, and let glyphs discriminate beyond ~4 visible hues.\n */\n:root {\n /* Surfaces: base layer is flat – separation by hairline or one-step\n background change, never shadow. Shadows belong to overlays only. */\n --surface-page: #fafafa;\n --surface-raised: #ffffff;\n --surface-sunken: #f4f4f5;\n\n --border-hairline: rgba(9, 9, 11, 0.1);\n --border-strong: rgba(9, 9, 11, 0.22);\n --hover-tint: rgba(9, 9, 11, 0.03);\n --selected-tint: rgba(9, 9, 11, 0.06);\n\n /* Neutral text ramp: hierarchy at small sizes comes from tone, not size. */\n --text-primary: rgba(9, 9, 11, 0.92);\n --text-secondary: rgba(9, 9, 11, 0.6);\n --text-tertiary: rgba(9, 9, 11, 0.5);\n\n /* Brand: one primary button, active nav, inline links. The default is\n deliberately unbranded near-black; a white-label consumer swaps it. */\n --accent: #18181b;\n --accent-fg: #ffffff;\n\n /* State pairs: pale tint background + text at the dark step of the same\n ramp. Cancelled is grey by design – a neutral terminal, never red. */\n --state-success-fg: #166534;\n --state-success-bg: #ecfdf3;\n --state-pending-fg: #92400e;\n --state-pending-bg: #fef6e7;\n --state-danger-fg: #991b1b;\n --state-danger-bg: #fef1f1;\n --state-neutral-fg: rgba(9, 9, 11, 0.55);\n --state-neutral-bg: rgba(9, 9, 11, 0.05);\n\n /* Radius: pills read as data values, cards stay under 16px so the read\n stays operator-grade rather than consumer. */\n --radius-pill: 4px;\n --radius-control: 6px;\n --radius-card: 12px;\n --radius-modal: 16px;\n\n /* Density: row pitch / body size is the most diagnostic ratio in the\n kit (target 2.4–3.8×). 40px / 14px = 2.86. */\n --row-pitch: 40px;\n --cell-pad-y: 8px;\n --cell-pad-x: 12px;\n\n /* Five sizes do all the work on one screen; the bottom three are nearly\n identical on purpose – tone and weight separate them, not size. The\n hero size is the one exception, reserved for THE emphasised figure on\n a card or panel (2–2.5x its caption, never more). */\n --font-size-title: 30px;\n --font-size-value: 20px;\n --font-size-body: 14px;\n --font-size-label: 12px;\n --font-size-micro: 11px;\n --font-size-hero: 28px;\n\n /* Border weights: hairline for separation, strong for hollow markers,\n emphasis for the current-state ring and the solid past rail. */\n --border-w-hairline: 1px;\n --border-w-strong: 1.5px;\n --border-w-emphasis: 2px;\n\n /* Spacing rhythm. Card padding sits at ~1.1–1.3x the body line-height –\n consumer apps run 1.5–2x, and that difference alone shifts the read. */\n --space-3xs: 2px;\n --space-2xs: 4px;\n --space-xs: 6px;\n --space-sm: 8px;\n --space-md: 12px;\n --space-lg: 16px;\n --space-xl: 20px;\n --space-2xl: 24px;\n --card-pad: 22px;\n --card-max-width: 420px;\n --pill-pad: 2px 6px;\n\n /* Form clamps: in-shell forms hold a readable measure instead of\n stretching across the content column; auth forms are narrower still. */\n --form-max-width: 600px;\n --auth-form-max-width: 360px;\n\n /* Table header band: hairline-only, no fill. */\n --header-pitch: 32px;\n\n /* Section band inside a grouped table: ~60% of a data row, so groups\n read as structure, not content. Empty groups still render at this\n height – \"Pending: 0\" is a state, not a missing feature. */\n --group-header-pitch: 28px;\n\n /* The needs-attention dot and the segmented balance bar: small geometry\n that must survive a reskin without the components hardcoding px. */\n --attention-dot: 6px;\n --bar-height: 6px;\n\n /* Overlay geometry. The side panel is the one base-layer boundary\n allowed elevation; everything else is flat by contract. */\n --panel-width: 28%;\n --panel-min-width: 340px;\n --shadow-overlay: -8px 0 24px rgba(9, 9, 11, 0.06);\n --timeline-node: 16px;\n\n --font-family:\n ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n}\n" } ] }