Xandra

Documentation

Everything you need to build with Xandra. ~85 classes. Zero JavaScript. One philosophy: constraint breeds consistency.

Getting Started

Install

npm install xandra

Then import in your HTML, build tool, or framework:

<!-- HTML -->
<link rel="stylesheet" href="node_modules/xandra/dist/xandra.css">

/* CSS / PostCSS / Vite */
@import 'xandra';

/* JavaScript bundler */
import 'xandra';

CDN

<link rel="stylesheet" href="https://unpkg.com/xandra/dist/xandra.min.css">

Minimal page

<!DOCTYPE html>
<html lang="en" class="x-theme-dark">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="xandra.css">
</head>
<body class="x-bg-base x-text-primary">

  <main class="x-block-1 x-stack x-pad-5">
    <h1 class="x-h1">Hello Xandra</h1>
    <p class="x-body">You're up and running.</p>
    <button class="x-btn">Get Started</button>
  </main>

</body>
</html>

Philosophy

Xandra is not a utility framework. It's a standardization contract.

One class = one decision

Each class is a complete visual contract. x-card isn't just "background + border" — it's a self-responsive container with adaptive padding, implicit child styling, and theme integration.

Constraint over freedom

You can't write x-flex or x-justify-center. Xandra gives you compositions (x-row, x-between) not CSS property wrappers. Fewer choices, faster decisions.

Deviation is tracked

When you need something outside the standard, you mark it with [ns]. Every deviation is tracked, audited, and eventually promoted into a new standard class.

Zero JavaScript

CSS custom properties, container queries, and modern selectors handle everything. No runtime. No hydration. No bundle size.

Typography 13 classes

All type classes use clamp() for fluid responsive sizing. One class per element — no stacking type classes.

x-display

clamp(2.5rem, 6vw + 1rem, 4.5rem) / 800

x-h1

clamp(2rem, 5vw + 1rem, 3.5rem) / 700

x-h2

clamp(1.5rem, 3vw + 0.75rem, 2.5rem) / 600

x-h3

clamp(1.25rem, 2vw + 0.5rem, 2rem) / 600

x-h4

clamp(1.125rem, 1vw + 0.5rem, 1.5rem) / 600
x-h5
clamp(1rem, 0.5vw + 0.5rem, 1.25rem) / 500
x-h6
clamp(0.875rem, 0.25vw + 0.5rem, 1rem) / 500

x-lead — Emphasized intro paragraph

color: secondary

x-body — Standard body text

color: secondary

x-small — Fine print, disclaimers

color: muted

x-caption — Captions, metadata

color: muted

x-label — Labels, smallest text

uppercase / wide tracking

x-mono — Monospace content

font-family: mono / 0.9em
<h1 class="x-h1">Page Title</h1>
<p class="x-lead">Intro paragraph with larger text.</p>
<p class="x-body">Standard body content.</p>
<p class="x-caption">Posted on March 28, 2026</p>

Layout 12 classes

Flexbox and grid compositions with container queries. Components adapt to their container, not the viewport.

Flex Layouts

x-stack

Vertical flex column with gap

display: flex
flex-direction: column
gap: var(--x-space-4)
Item 1
Item 2
Item 3

x-row

Horizontal flex with wrap and gap

display: flex
flex-wrap: wrap
align-items: center
gap: var(--x-space-4)
A
B
C

x-between

Space-between, stacks below 400px container width

justify-content: space-between
@container (<400px) → column
Left Right

x-center

Center content on both axes

justify-content: center
align-items: center
Centered

Block System (Grid)

Responsive grids powered by container queries. Columns collapse based on the container's width, not the viewport.

x-block-1 max-width: 1200px, centered
x-block-prose max-width: 65ch, optimized for reading
x-block-wide max-width: 1400px, centered
x-block-full 100% width with inline padding
x-block-2 2-col grid → 1-col below 500px
x-block-3 3-col → 2-col below 768px → 1-col below 500px
x-block-4 4-col → 2-col below 900px → 1-col below 500px
<main class="x-block-1 x-stack x-pad-5">
  <div class="x-block-3">
    <article class="x-card">...</article>
    <article class="x-card">...</article>
    <article class="x-card">...</article>
  </div>
</main>

Visibility

x-hidden display: none
x-sr-only Visually hidden, accessible to screen readers

Spacing 20 classes

All spacing uses CSS custom properties from a 4px base scale. Density modifiers override the entire scale locally.

Scale

1
0.25rem (4px)
2
0.5rem (8px)
3
0.75rem (12px)
4
1rem (16px)
5
1.5rem (24px)
6
2rem (32px)

Padding

All sides. x-pad-1 through x-pad-6

Gap

Flex/grid gap. x-gap-1 through x-gap-6

Margin Top

Vertical rhythm. x-mt-1 through x-mt-6

Margin Bottom

Spacing after. x-mb-1 through x-mb-6

Density System 2 classes

One class on a parent. The entire subtree adapts. No size variants needed.

x-dense and x-spacious override the spacing custom properties locally, so every component inside (buttons, cards, gaps, padding) scales automatically.

Default

Standard spacing.

x-dense

Everything tightens up.

x-spacious

Extra breathing room.

<!-- Apply to any container -->
<div class="x-card x-stack x-dense">
  <!-- Everything inside is compact -->
</div>

<!-- Or an entire section -->
<section class="x-spacious">
  <!-- All descendants get wider spacing -->
</section>

How it works

Density classes override --x-space-1 through --x-space-6 locally. Since every Xandra component uses these tokens for padding, gap, and margin, the entire subtree adapts.

.x-dense {
  --x-space-1: 0.125rem;  /* 2px instead of 4px */
  --x-space-2: 0.25rem;   /* 4px instead of 8px */
  --x-space-3: 0.5rem;    /* 8px instead of 12px */
  --x-space-4: 0.75rem;   /* 12px instead of 16px */
  --x-space-5: 1rem;      /* 16px instead of 24px */
  --x-space-6: 1.5rem;    /* 24px instead of 32px */
}

Colors 18 classes

Semantic color tokens — every color has a purpose. All theme-aware via CSS custom properties.

Backgrounds

x-bg-base Page background
x-bg-surface Cards, sections
x-bg-elevated Dropdowns, hovers
x-bg-primary Primary actions

Semantic States

x-bg-success Muted green background
x-bg-warning Muted amber background
x-bg-error Muted red background

Text Colors

x-text-primary — Main content text

x-text-secondary — Supporting text

x-text-muted — Dimmed, tertiary text

x-text-inverse — Inverted (on primary bg)

x-accent — Interactive/emphasis color

x-text-success — Success state

x-text-warning — Warning state

x-text-error — Error state

Borders

x-border-subtle
x-border
x-border-strong

Utilities 8 classes

Border Radius

x-round-sm (4px), x-round-md (8px), x-round-lg (12px), x-round-full (pill)

Shadows

sm
md
lg

Theme-aware shadows using --x-shadow-color and --x-shadow-strength

x-overflow-auto overflow: auto — for scrollable containers

Components 12 classes

Buttons

Three variants. Works on <button> and <a> elements.

<button class="x-btn">Primary</button>
<button class="x-btn-ghost">Ghost</button>
<button class="x-btn-outline">Outline</button>
<a class="x-btn" href="/action">Link as button</a>

Card

Self-responsive container. Padding adapts via container queries. Implicit child styling recognizes <header>, <footer>, <p>, and first <img>.

Mountains
Media Card

Image goes edge-to-edge. Header and footer are auto-styled.

Standard Card

Use x-card x-stack for vertical layout with gap.

Stat Card

2,847

+18% this week
<!-- Media card — no classes needed on children -->
<article class="x-card">
  <img src="photo.jpg" alt="...">
  <header>Title</header>
  <p>Description text.</p>
  <footer>
    <button class="x-btn">Save</button>
  </footer>
</article>

<!-- Card with explicit classes override implicit styling -->
<article class="x-card">
  <p class="x-display">1,247</p>  <!-- x-display wins over card's p styling -->
</article>

Implicit child rules

.x-card > header h4 size, border-bottom separator
.x-card > footer caption size, border-top separator, muted color
.x-card > p body size, relaxed line-height, secondary color
.x-card > img:first-child Edge-to-edge, negative margins, cover fit

All implicit rules use :not([class]) — adding any class to a child element overrides the implicit styling.

Navigation

Auto-styled links with aria-current support. No active class needed.

<nav class="x-nav">
  <a href="/dashboard" aria-current="page">Dashboard</a>
  <a href="/analytics">Analytics</a>
  <a href="/reports">Reports</a>
</nav>

Input

Form inputs with focus rings, validation states via HTML5, and autofill theme matching.

<input class="x-input" type="text" placeholder="Your name">
<input class="x-input" type="email" placeholder="you@example.com">

Badge

Default Success Warning Error

Combine with text color classes. Scales inside headings.

Heading Live

Avatar

AC
NS
XC

Override --x-accent for custom colors. Supports text initials or img children.

Link

Read the documentation or check the source.

Underlined, accent colored, with hover and focus states.

Code

Inline x-code and block:

npm install xandra
npx xcc check src/

Divider

A 1px horizontal separator using the subtle border color.

<div class="x-divider"></div>

Themes 4 themes

Apply a theme class to any container. Themes cascade and nest — you can have a light card inside a dark page.

x-theme-dark

Default. Deep backgrounds, bright text.

Badge

x-theme-light

Light backgrounds, dark text.

Badge

x-theme-nvg

Night vision green. Tactical.

Badge

x-theme-high-contrast

Maximum contrast for accessibility.

Badge
<!-- Set page theme -->
<html class="x-theme-dark">

<!-- Nest themes -->
<div class="x-theme-dark x-bg-base">
  <div class="x-theme-light x-bg-base x-card">
    This card is light inside a dark page.
  </div>
</div>

The NS System

NS (Non-Standard) is Xandra's deviation tracking system. When you need something outside the ~85 standard classes, you mark it. Every deviation is tracked, audited, and eventually promoted.

Standard

No marker needed. This is the Xandra way.

<div class="x-card x-stack">
  <h3 class="x-h3">Title</h3>
  <p class="x-body">Content</p>
</div>

Leaf Deviation

Single element needs custom CSS. Mark it and explain why.

<div class="x-card" ns
  data-ns="needs chart.js canvas">
  <canvas id="chart"></canvas>
</div>

Boundary

Third-party widget — everything inside is non-standard.

<div ns data-ns="Stripe Elements"
  data-ns-boundary>
  <!-- All children are implicitly ns -->
  <div id="stripe-card"></div>
</div>

Audit Mode

Visual debugging — highlights all ns elements with reasons.

<!-- Toggle on html or body -->
<html class="x-theme-dark x-audit">

/* Or via JS */
document.documentElement
  .classList.toggle('x-audit');

The Promotion Loop

Deviations aren't permanent. When the same ns reason appears across enough files, xcc suggests promoting it to a standard class.

$ npx xcc audit
NS AUDIT (12 elements across 5 files)
  "needs chart component" — 7 occurrences
  "needs date picker"     — 3 occurrences
  "stripe integration"    — 2 boundaries

$ npx xcc promote
PROMOTION CANDIDATES
  1. x-chart — "needs chart component" (7 times, 4 files)
     Suggested CSS skeleton generated.

Contract Compiler (xcc)

The compiler validates your HTML against the Xandra contract. It catches errors at build time, not in production.

npm install -D xandra-cc

Commands

xcc check [path] Validate HTML against the contract
xcc audit [path] Analyze ns patterns, suggest new classes
xcc audit --tree Tree visualization of ns elements
xcc graph [path] Map parent-child composition patterns
xcc optimize [path] Tree-shake unused classes from CSS
xcc promote [path] Find ns patterns ready to standardize
xcc docs [path] Generate composition documentation
xcc init Create xandra.config.js

Validation Rules

ERROR ns without data-ns reason
ERROR Conflicting classes (x-stack + x-row)
ERROR Invalid composition (nested buttons)
WARNING Redundant classes (x-pad-3 + x-pad-5)
WARNING Unknown x- class
WARNING Double density (x-dense inside x-dense)
WARNING Non-x- class without ns marker
$ npx xcc check src/
xcc v1.1.1 — Xandra Contract Compiler

Scanning 12 files...

ERRORS (1)
  src/pages/dashboard.html:47
    ✕ x-stack + x-row — conflicting layout modes

WARNINGS (2)
  src/pages/dashboard.html:52
    ⚠ x-pad-3 + x-pad-5 — multiple padding values
  src/components/chart.html:18
    ⚠ Non-x- class "chartjs-wrapper" without [ns]

SUMMARY
  12 files scanned
  3 ns elements (3 with reasons)
  1 error, 2 warnings

Design Tokens

Every value in Xandra is a CSS custom property. Override them to customize without touching source files.

Spacing

--x-space-1: 0.25rem   /* 4px */
--x-space-2: 0.5rem    /* 8px */
--x-space-3: 0.75rem   /* 12px */
--x-space-4: 1rem      /* 16px */
--x-space-5: 1.5rem    /* 24px */
--x-space-6: 2rem      /* 32px */

Typography

--x-font-sans: system-ui, ...
--x-font-mono: ui-monospace, ...
--x-text-h1: clamp(2rem, 5vw+1rem, 3.5rem)
--x-text-body: clamp(1rem, 0.5vw+0.75rem, 1.125rem)
--x-text-caption: 0.875rem
--x-text-label: 0.75rem

Borders & Radius

--x-radius-sm: 0.25rem   /* 4px */
--x-radius-md: 0.5rem    /* 8px */
--x-radius-lg: 0.75rem   /* 12px */
--x-radius-full: 9999px

Transitions

--x-transition-fast: 100ms ease
--x-transition-normal: 150ms ease
--x-transition-slow: 300ms ease
/* Override tokens for your brand */
:root {
  --x-font-sans: 'Inter', system-ui, sans-serif;
  --x-radius-md: 0.75rem; /* rounder corners */
}

/* Or override per theme */
.x-theme-dark {
  --x-bg-primary: hsl(262 83% 58%); /* purple accent */
  --x-accent: hsl(262 83% 58%);
}

Ecosystem

xandra

CSS framework. ~85 classes. Zero JS. Zero dependencies.

npm install xandra
xandra-cc

Contract compiler. 7 commands. Validates, audits, graphs, promotes.

npm install -D xandra-cc
vscode-xandra

VSCode extension. Completions, diagnostics, hover docs, ns tracking.

Search "Xandra CSS" in VSCode

Browser Support

Xandra uses modern CSS features. Minimum browser requirements:

Container Queries Chrome 105+, Firefox 110+, Safari 16+
CSS Custom Properties All modern browsers
clamp() Chrome 79+, Firefox 75+, Safari 13.1+
:has(), :where(), :not() Chrome 105+, Firefox 121+, Safari 15.4+