This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/EXTENSION-CSS.md
Jeffrey Smith a7e38bc72a
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-runners (push) Has been skipped
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m51s
CI/CD / test-sqlite (push) Successful in 2m51s
CI/CD / build-and-deploy (push) Successful in 39s
Feat v0.7.4 docs surface work (#58)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-04-02 14:46:54 +00:00

6.1 KiB

Extension CSS Contract

Version: v0.6.13 — Responsive & Spacing

This document defines the CSS contract between the Armature kernel and extension packages. Extensions must follow these rules; the kernel guarantees the listed classes and variables are stable public API.


Naming Rule

All class selectors in extension CSS (packages/{slug}/css/main.css) must start with .ext-{slug}-. The {slug} is the package directory name.

/* Good */
.ext-my-app-sidebar { ... }
.ext-my-app-card { ... }

/* Bad — will be rejected by the linter */
.sidebar { ... }
.my-sidebar { ... }

Compound selectors: Descendant classes scoped under your .ext-{slug} root are allowed to reference kernel classes or state modifiers:

/* Allowed — kernel class scoped under extension namespace */
.ext-my-app .sw-btn { margin-top: 8px; }

/* Allowed — state modifier on an extension element */
.ext-my-app-item.active { ... }

Run bash scripts/lint-package-css.sh to validate. The linter checks that the first class selector in every rule starts with .ext-{slug}.


Stable Kernel Classes

Extensions may reference these classes in compound selectors. They are part of the public API and will not change without a major version bump.

Components (from sw-primitives.css)

Class pattern Component
.sw-btn, .sw-btn--{variant}, .sw-btn--{size} Buttons
.sw-input Text inputs
.sw-field, .sw-field__label, .sw-field__hint Form fields
.sw-dialog, .sw-dialog__header, .sw-dialog__body, .sw-dialog__footer Dialogs
.sw-toast, .sw-toast-container Toast notifications
.sw-menu, .sw-menu-item Context menus
.sw-tabs, .sw-tab-btn Tab strips
.sw-dropdown Custom dropdowns
.sw-spinner Loading spinners
.sw-avatar User avatars
.sw-drawer Slide-out drawers
.sw-banner Banner bars
.sw-tooltip Tooltips

Extension Mount

The extension surface container has a data-ext attribute set to the package slug. Use this for scoping if needed:

[data-ext="my-app"] .ext-my-app-sidebar { ... }

Stable CSS Variables

All variables from variables.css are public API. Extensions should use these instead of hardcoded colors to respect the user's theme.

Colors

Variable Purpose
--bg Page background
--bg-secondary Secondary/darker background
--bg-elevated Elevated surface background
--bg-raised Raised card background
--bg-surface Surface-level background
--bg-hover Hover state background
--bg-active Active/pressed state background
--bg-code Code block background
--text Primary text color
--text-2 Secondary text color
--text-3 Tertiary/muted text color
--text-on-color Text on colored backgrounds
--accent Primary accent color
--accent-dim Dimmed accent for backgrounds
--accent-hover Accent hover state
--accent-light Light accent variant
--border Default border color
--border-light Light border variant
--border-elevated Border for elevated surfaces
--danger Error/destructive color
--danger-dim Dimmed danger background
--danger-light Light danger variant
--success Success/positive color
--success-dim Dimmed success background
--success-light Light success variant
--warning Warning/caution color
--warning-dim Dimmed warning background
--warning-light Light warning variant
--purple Purple accent
--purple-dim Dimmed purple background

Spacing

Use spacing tokens instead of hardcoded values for padding, margin, and gap. For sub-4px values (1px, 2px, 3px) used in borders and fine detail, hardcoded values are acceptable.

Variable Value Computed
--sp-1 0.25rem 4px
--sp-1h 0.375rem 6px
--sp-2 0.5rem 8px
--sp-2h 0.625rem 10px
--sp-3 0.75rem 12px
--sp-4 1rem 16px
--sp-5 1.25rem 20px
--sp-6 1.5rem 24px
--sp-8 2rem 32px
--sp-10 2.5rem 40px
--sp-12 3rem 48px

Example:

.ext-my-app-card {
    padding: var(--sp-3) var(--sp-4);   /* 12px 16px */
    gap: var(--sp-2);                    /* 8px */
    margin-bottom: var(--sp-4);          /* 16px */
}

Layout & Typography

Variable Purpose
--font Primary font family (self-hosted, no external requests)
--mono Monospace font family (self-hosted)
--radius-sm Small border-radius (4px) — badges, inline controls
--radius Default border-radius (8px) — buttons, inputs, cards
--radius-lg Large border-radius (12px) — modals, dialogs, large cards
--transition Default transition timing
--shadow-lg Large elevation shadow
--overlay Modal overlay color
--glass Glassmorphism backdrop
--input-bg Form input background
--sidebar-w Sidebar width

Responsive Breakpoints

The kernel uses these standard breakpoints. Extensions should use the same values for consistency.

Name Media Query Use Case
Mobile @media (max-width: 768px) Phone-sized, single column
Tablet @media (max-width: 1024px) Tablet/small laptop, narrower sidebars
Desktop Default (no query) Full layout

CSS custom properties cannot be used in @media queries — use the pixel values directly.


What Is Internal

Everything not listed above is internal kernel CSS and may change between minor versions. Extensions must not depend on:

  • Kernel layout classes (.admin-*, .surface-*, .sidebar, etc.)
  • Kernel CSS file load order
  • Specific HTML structure of the shell or topbar
  • Undocumented CSS variables

Enforcement

The linter script scripts/lint-package-css.sh runs against all packages/*/css/main.css files. It exits non-zero if any rule's first class selector does not start with .ext-{slug}.