Core Docs

Design Standards

Design Standards



The standards layer of the UNVRSL Design System provides foundational CSS tokens, a global reset, and utility classes. It is the single dependency of the ui and layouts layers.




Quick start



<link rel="stylesheet" href="/design/standards/v1.css">


For projects using the core.assets CDN:

<link rel="stylesheet" href="https://core.assets.medkronos.com/design/standards/v1.css">





1. Color system



The entire color palette is derived from a single value: --brand-hue. Pick one of the presets, or set any hue you like.

Presets



VariableHuePreview







--brand-hue-blue210°<span style="display:inline-block;width:1.5rem;height:1.5rem;border-radius:4px;background:oklch(0.58 0.16 210deg);vertical-align:middle"></span> Blue (default)
--brand-hue-green150°<span style="display:inline-block;width:1.5rem;height:1.5rem;border-radius:4px;background:oklch(0.58 0.16 150deg);vertical-align:middle"></span> Green
--brand-hue-purple270°<span style="display:inline-block;width:1.5rem;height:1.5rem;border-radius:4px;background:oklch(0.58 0.16 270deg);vertical-align:middle"></span> Purple
--brand-hue-red<span style="display:inline-block;width:1.5rem;height:1.5rem;border-radius:4px;background:oklch(0.58 0.16 0deg);vertical-align:middle"></span> Red
--brand-hue-orange30°<span style="display:inline-block;width:1.5rem;height:1.5rem;border-radius:4px;background:oklch(0.58 0.16 30deg);vertical-align:middle"></span> Orange
--brand-hue-teal180°<span style="display:inline-block;width:1.5rem;height:1.5rem;border-radius:4px;background:oklch(0.58 0.16 180deg);vertical-align:middle"></span> Teal

Choosing a palette



Set the active brand hue in your project CSS:

:root {
--brand-hue: var(--brand-hue-green);
}


To use green across the whole UI:




--brand



--brand-strong



--brand-soft



--brand-faint



--brand:         oklch(0.58 0.16 150deg)
--brand-strong: color-mix(in oklch, var(--brand), black 18%)
--brand-soft: color-mix(in oklch, var(--brand), white 72%)
--brand-faint: color-mix(in oklch, var(--brand), white 92%)


Full token reference




TokenDescription


























--brandBase brand color
--brand-strong18% darker
--brand-soft72% lighter
--brand-faint92% lighter
--complementOpposite hue (brand + 180°)
--complement-softComplement, 70% lighter
--complement-faintComplement, 90% lighter
--bgPage background
--surfaceCard / section background
--surface-2One layer deeper
--surface-3Two layers deeper
--insetSlightly darker for inset areas
--textBody text
--text-strongHigh emphasis text
--text-mutedLower emphasis (labels, hints)
--text-faintLeast emphasis (placeholders)
--text-on-brandText color when placed on brand bg
--borderDefault border
--border-strongEmphasized border
--border-faintSubtle border
--focus-ringFocus ring color
--successGreen semantic
--warningYellow/amber semantic
--dangerRed semantic
--infoBlue semantic

Using surfaces



The surface tokens create visual hierarchy. Here they are rendered side by side:



--bg



--surface



--surface-2



--surface-3



--inset




Dark mode



The standards file includes full dark mode support via prefers-color-scheme: dark. All surface, text, and border tokens invert cleanly while maintaining the same brand hue. No class toggles required.

To simulate how your palette would look in dark mode, the system automatically inverts:

Light mode:  --bg → oklch(0.98 0.01 var(--brand-hue))
Dark mode: --bg → oklch(0.15 0.015 var(--brand-hue))

Light mode: --text → oklch(0.22 0.02 var(--brand-hue))
Dark mode: --text → oklch(0.85 0.015 var(--brand-hue))





2. Size scale



All spacing, typography, and radii follow a consistent 8-step scale.

Space tokens



--space-xxs:  0.125rem  ( 2px)
--space-xs: 0.25rem ( 4px)
--space-s: 0.5rem ( 8px)
--space-m: 1rem (16px)
--space-l: 1.5rem (24px)
--space-xl: 2rem (32px)
--space-xxl: 3rem (48px)
--space-xxxl: 4rem (64px)


Font sizes



--text-xs:    0.75rem
--text-s: 0.875rem
--text-m: 1rem
--text-l: 1.125rem
--text-xl: 1.375rem
--text-xxl: 1.75rem
--text-xxxl: 2.5rem


Radii



--radius-s:    0.25rem
--radius-m: 0.5rem
--radius-l: 0.75rem
--radius-xl: 1rem
--radius-full: 9999px (pill shape)


Shadows



--shadow-sm:  0 1px 2px   rgba(0,0,0,0.06)
--shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.04)
--shadow-lg: 0 10px 15px rgba(0,0,0,0.08), 0 4px 6px rgba(0,0,0,0.04)
--shadow-xl: 0 20px 25px rgba(0,0,0,0.10), 0 10px 10px rgba(0,0,0,0.04)




sm



md



lg



xl




Transition & opacity tokens



--opacity-muted:   0.65
--opacity-faint: 0.40
--opacity-hidden: 0

--ease-out: cubic-bezier(0.16, 1, 0.3, 1)
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1)
--duration-fast: 150ms
--duration-normal: 250ms
--duration-slow: 400ms





3. Z-index system




TokenValueUsed for














--z-base0Normal document flow
--z-below-1Behind all content
--z-dropdown100Dropdown menus
--z-sticky200Sticky headers / navs
--z-nav300Fixed navigation bars
--z-overlay400Semi-transparent page overlays
--z-modal500Modal dialog boxes
--z-popover600Popovers & contextual menus
--z-tooltip700Tooltips
--z-toast800Toast notifications
--z-notification900Notification banners
--z-banner950Emergency alert banners
--z-emergency1000Critical system alerts

Rule: Always use these custom properties instead of raw numbers:

/* 👍 Good */
.modal { z-index: var(--z-modal); }
/* 👎 Bad */
.modal { z-index: 999999; }





4. CSS reset



The reset normalises behaviour across browsers and establishes consistent defaults.

*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
min-height: 100dvh;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, ...;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}

img, picture, video, canvas, svg {
display: block;
max-width: 100%;
}

a {
color: var(--brand);
text-decoration: none;
}
a:hover {
color: var(--brand-strong);
text-decoration: underline;
}

button {
cursor: pointer;
border: none;
background: none;
font: inherit;
}

:focus-visible {
outline: 2px solid var(--focus-ring);
outline-offset: 2px;
}

::selection {
background: var(--brand-soft);
color: var(--text-strong);
}


A custom scrollbar is also applied on WebKit browsers.




5. Utility classes



Utility classes allow rapid prototyping without writing custom CSS. They are grouped by category:

Spacing



.gap-xxs  .gap-xs  .gap-s  .gap-m  .gap-l  .gap-xl  .gap-xxl  .gap-xxxl
.p-xxs .p-xs .p-s .p-m .p-l .p-xl .p-xxl .p-xxxl
.m-xxs .m-xs .m-s .m-m .m-l .m-xl .m-xxl .m-xxxl


Flex & Grid



.flex .flex-col .flex-wrap .flex-1
.items-center .items-start
.justify-center .justify-between
.grid .grid-cols-2 .grid-cols-3 .grid-cols-4


Text



.text-center .text-muted .text-faint
.text-xs .text-s .text-m .text-l .text-xl .text-xxl .text-xxxl
.weight-bold .weight-medium .truncate


Surfaces & Borders



.surface .surface-2 .surface-3 .inset
.border .border-strong .border-faint
.radius-s .radius-m .radius-l .radius-full
.shadow-sm .shadow-md .shadow-lg .shadow-xl


Accessibility



.sr-only   — visually hidden, available to screen readers


Container



.container {
width: 100%;
max-width: 1200px;
margin-inline: auto;
padding-inline: var(--space-m);
}
/* Responsive: padding increases on larger screens */





Putting it all together



A minimal page using only standards (no UI layer):



Welcome


Standards only

This page uses only the reset, tokens, and utility classes from standards/v1.css — no UI components loaded.




Card one


Built with tokens only.




Card two


Using --surface-2.






```html
<div class="container" style="padding: 2rem">
<div class="flex items-center justify-between" style="margin-bottom: 2rem">
<h1 style="font-size: var(--text-xxl)">Welcome</h1>
<span class="badge badge--brand">Standards only</span>
</div>
<p style="color: var(--text-muted)">
This page uses only tokens and utilities.
</p>
<div style="display: flex; gap: 1rem; flex-wrap: wrap">
<div class="surface" style="padding: 1.5rem; border-radius: var(--radius-m); box-shadow: var(--shadow-sm); border: 1px solid var(--border)">
<h3>Card one</h3>
<p>Built with tokens only.</p>
</div>
<div class="surface-2" style="padding: 1.5rem; border-radius: var(--radius-m); box-shadow: var(--shadow-sm); border: 1px solid var(--border)">
<h3>Card two</h3>
<p>Using --surface-2.</p>
</div>
</div>
</div>