Files
RenewCMS/docs/design/foundations.md
T

7.7 KiB

Foundations

Tokens only. No raw hex or rgb in any frame. The one exception is the brand mark SVG (#111 and #fff fills). Radius is 0 everywhere (no border-radius is declared in any frame).

New tokens (do not exist in the app yet)

tokens/renewcms.css defines no --rc-* token. The frames use the ones below. They are new. Add them to the app's CSS, light values in :root and dark values in .dark. No --ui-* token is changed.

Name Light Dark Used by
--rc-sand #e8dfd1 #d4c5b0 Selected nav item (parent and child), selected table row and media card, current paginator page, pressed filter card, avatars, account chip, "In this article" tag, drag-drop fill
--rc-on-sand #111111 #111111 Text and icons on --rc-sand. Never use --ui-text-muted or white on sand
--rc-success-soft #eaefea #1f241f Success badge, success alert and toast icon ground
--rc-info-soft #ebeef0 #202428 Info badge, info alert, "variants" badge, duplicate badge
--rc-warning-soft #f0ede6 #2a251e Warning badge and alert, "Unused" badge
--rc-error-soft #f3eae9 #2c201f Error badge and alert, failed-actions card
--rc-overlay rgb(10 10 10 / 0.4) rgb(0 0 0 / 0.6) Dialog, sheet and slide-over scrim; crop mask
--rc-shadow-pop 0 4px 16px rgb(17 17 17 / 0.08), 0 1px 2px rgb(17 17 17 / 0.06) 0 4px 16px rgb(0 0 0 / 0.5) Menus, popovers, toasts. Same as --shadow-popover
--rc-shadow-modal 0 16px 48px rgb(17 17 17 / 0.18) 0 16px 48px rgb(0 0 0 / 0.6) Dialogs, sheets, slide-overs. Same as --shadow-modal
--rc-canvas #ecebe8 #1c1c1c Design boards only. Not for the app

Implementers may alias --rc-shadow-pop and --rc-shadow-modal to the existing --shadow-popover and --shadow-modal. The Nuxt UI UAlert/UBadge soft variants can map to the four -soft tokens.

Contrast (computed, AA: text 4.5:1, UI components 3:1)

Light | dark. Computed with the WCAG relative luminance formula from the token values above and the --ui-* values in the board root.

Pair Light Dark Result
Success, info, warning, error on their -soft ground (badges, alerts) 6.7 / 6.9 / 7.1 / 7.3 8.7 / 8.4 / 8.1 / 8.1 Pass
Neutral badge: --ui-text-toned on --ui-bg-elevated 8.7 10.9 Pass
Chip, selected row, current page: --rc-on-sand on --rc-sand 14.3 11.2 Pass
Neutral chip: --ui-text-highlighted on --ui-bg-accented 14.9 15.2 Pass
Toast title on --ui-bg 18.9 18.1 Pass
Toast body --ui-text-toned / --ui-text-muted on --ui-bg 9.7 / 5.7 11.8 / 6.6 Pass
Banner (offline): --ui-text-inverted on --ui-bg-inverted 18.9 18.1 Pass
Table text --ui-text on --ui-bg; on hover --ui-bg-elevated 15.9; 14.2 14.9; 13.7 Pass
Table header and hover meta: --ui-text-muted on --ui-bg-elevated 5.1 6.1 Pass
Tab selected / unselected / count 18.9 / 9.7 / 5.7 18.1 / 11.8 / 6.6 Pass
Segmented: selected --ui-bg on --ui-primary; unselected --ui-text-toned on --ui-bg 18.9; 9.7 18.1; 11.8 Pass
Placeholder --ui-text-muted on --ui-bg 5.7 6.6 Pass
--ui-text-muted on --rc-sand 4.3 1.7 Fails. Never place muted text on sand. Frames use --rc-on-sand
--ui-text-dimmed on --ui-bg 2.8 3.3 Fails. Not used for text. Allowed for disabled icons and decorative strokes
Disabled controls at 40% opacity (label on --ui-bg) 2.6 3.7 Exempt (inactive component). Never carry information only in a disabled label
Disabled table row at 55% opacity not computed not computed Exempt (inactive)
UI: --ui-border-accented on --ui-bg (input, checkbox, segmented, secondary button borders) 3.6 3.3 Pass (3:1)
UI: focus ring --ui-primary on --ui-bg 18.9 18.1 Pass
UI: --rc-sand fill against --ui-bg 1.3 11.2 Fails in light as the only indicator
UI: --ui-border on --ui-bg 1.3 1.5 Decorative only (card and table lines). Never the only boundary of a control

Fixes applied (token swaps):

  • Current page in the paginator: border changed from --rc-sand to --ui-primary (18.9 / 18.1) so the state does not rely on a 1.3:1 fill.
  • Selected media cards and rows keep --ui-primary outline with the sand fill (already so).
  • Selected nav items still rely on the sand fill plus weight 500 and aria-current="page". The fill alone is 1.3:1 in light; the weight change and the programmatic state carry the information. This is accepted and recorded here, not "fixed".
  • Rule added: --ui-text-muted is never used on --rc-sand. Not computed: hover and active backgrounds of every control against every text colour; the states-matrix uses combinations already listed above.

One value per role (spacing, radius, type, icons)

Sweep of the frames (AppFrame, ActivityFrame, MediaFrame, VariantsFrame, IntegrationPage, IntegrationImages, ApiKeysPage, CodeSnippet, AuthCard). "Found" is what was drawn before pass 2.

Role Found Value now (desktop / mobile)
Page padding 32 px (Home, Users, Settings, Integration, API keys), 24 px (Media, Activity, Variants); mobile 20 16 or 16 24 px / 16 px. Extra bottom padding only to clear a fixed bar (88 or 96 px)
Section gap on a page 20, 28 (Home, Settings), 16 elsewhere 16 px
Card padding 16 px and 20 px 16 px
Card inner gap 8, 12, 14, 16 12 px (6 px between a label and its control, 8 px between buttons)
Banner and alert padding 10 12, 12 14 12 14
Radius none declared 0
Page title 28/36 (Home, Integration, API keys), 24/32 (Variants), 20/28 (rest) 20/28, weight 600, same on mobile
Section heading (reference pages) 18/26 18/26
Card title 14/22, 15/22, 15/24 15/24, weight 600
Sub heading 14/22 14/22
Dialog title 16/24 16/24
Stat figure 28/36 (Home), 24/32 (Activity), 22/36 (Variants mobile) 24/32, mobile 22/32
Error and 404 page title 24/32 24/32 (unchanged)
Editor article title 18/26 18/26 (own role)
Body text 13/20 13/20
Small and meta text 12/18 12/18
Icon in text and buttons 16 (91), 14 (87), 12 (20), 13 (1), 18, 20, 22, 28 16 px. 14 px inside compact controls and badges (12 px in badges). 20 px in the mobile top bar. 18 px in mobile list rows and sheet rows. The 13 px icon became 14. Auth card (22) and the empty-state glyph (28) stay as illustration sizes
Control height (button, input, select) 28, 32, 40 (inputs in API keys, Integration, Images) 32 px / 44 px. Inline row buttons 28 px on desktop, 44 px on mobile. The 40 px inputs became 32 / 44
Dialog top offset 120 and 140, centered (export), padding 20 width 460 (560 wide, 640 crop), 140 px from the top, header 20 24 0, body 20 24 0, footer 20 24
Table row 40, 48, 56 48 px; media rows 56 px (thumbnail); mobile 56 px

Pairings

  • Selected rows use --rc-sand with --rc-on-sand text and icon in both themes. Hover, focus-visible and active on a selected row keep sand. Focus adds a 2 px --ui-primary outline.
  • Child selected: the parent row is not filled. It uses --ui-text-highlighted, weight 500, chevron down.
  • Focus-visible: 2 px --ui-primary, offset 2 px (inset -2 px for tabs, segmented controls and rows).
  • Disabled: 40% opacity (table rows 55%).
  • Hover, active and the rest: board "States matrix: controls" (StatesMatrix.dc.html). Hover and active tokens: primary button hover --ui-text, active --ui-text-toned; secondary and ghost hover --ui-bg-elevated, active --ui-bg-accented; destructive hover opacity 0.85, active 0.75; input hover border --ui-text-muted, focus border --ui-primary.