Website project
Your next interface
Build a custom component once and let its parent provide the appearance.
Component notes
The card owns the surface. Custom CSS adds content layout and supporting text, without replacing material or focus styling.
LEARN / EXTENDING REVACSS
RevaCSS supplies shared appearance settings. Your application can add its own components using native HTML, documented theme tokens and existing component hooks. A custom component is application code; it does not need to become a framework module.
This contract describes how to extend the current API. The starter is a documentation example, not a new core component or a completed accessibility acceptance record. Browser and device checks for this addition remain deferred.
html or a parent section. Do not install a new palette or repeat the theme on every instance unless that instance needs an explicit exception..card for a card-like component. Keep its surface, border, radius and shadow rules intact to retain supported materials and preference fallbacks..project-summary and --project-summary-title-size. Do not add undocumented data-* options or redefine the framework’s API for one component.| Purpose | Tokens | Usage |
|---|---|---|
| Page and surfaces | --re-bg, --re-surface, --re-surface-alt |
Choose by semantic purpose. Reuse .card when you need material support. |
| Text and links | --re-text, --re-muted, --re-link |
Supporting text uses muted; links use link. Let native links retain their focus styling. |
| Boundaries | --re-line, --re-control-line |
Surface separation and interactive-control boundaries are different roles. |
| Primary action | --re-primary, --re-primary-end, --re-on-primary |
Replace the two fill stops and readable foreground together. Prefer the existing native button styling. |
| Status fills | --re-success, --re-warning, --re-danger |
Pair each fill with its matching --re-on-* foreground; add visible status text. These are not general text colours. |
| Geometry | --re-space, --re-radius, --re-button-radius |
Consume only what the component needs; keep content height intrinsic. |
| Typography | --re-font, --re-font-heading |
Native text already inherits the framework fonts. Heading font falls back to the body font. |
The public token reference lists the full documented set. Tokens such as --re-action-start used inside the framework’s action rules are implementation details, not extension hooks.
The starter extends .card with .project-summary. The card owns background, border, shape, elevation and material. The application stylesheet adds a small content layout and supporting text.
<article class="card stack project-summary" aria-labelledby="project-title">
<p class="project-summary-label">Website project</p>
<h3 id="project-title" class="project-summary-title">Your next interface</h3>
<p>Build a custom component once and inherit its appearance.</p>
<dl class="project-summary-meta">
<div><dt>Status</dt><dd>Ready for review</dd></div>
<div><dt>Owner</dt><dd>Design team</dd></div>
</dl>
<a href="/projects/interface/">Open project</a>
</article>
Replace the example destination with your real route. Make project-title unique for each instance and choose the heading level appropriate to the document. If the component includes form fields, also make label/control IDs unique; use a separate radio-group name for each independent group.
.project-summary > .project-summary-label {
color: var(--re-muted);
font-size: .875em;
}
.project-summary > .project-summary-title {
font-size: var(--project-summary-title-size, 1.4em);
}
Load application CSS after the matching framework files. The complete stylesheet and HTML starter are in examples/custom-components.css and examples/custom-components.html. From a source checkout, run the documented CSS build and open the example. For a downloaded starter, put the HTML and extension CSS beside your dist/ directory as described on the online guide.
The exact colour-mode values are data-theme="light", data-theme="dark" and data-theme="auto". Auto follows the operating-system preference. data-palette selects the colour family; data-accent changes the primary action colours, not the complete palette. Shape, density and materials are separate settings.
<section data-theme="dark" data-palette="default" data-shape="rounded">
<article class="card stack project-summary">
<h3 class="project-summary-title">Inherited dark Default</h3>
<p>Shared settings reach the existing surface and native content.</p>
</article>
<section data-theme="light">
<article class="card stack project-summary">
<h3 class="project-summary-title">Local light Default</h3>
<p>Only the colour mode changes. The palette and shape still inherit.</p>
</article>
</section>
</section>
Override an application property on the instance when needed, for example style="--project-summary-title-size: 1.6em". A local custom property inherits into descendants; choose a distinct component name or explicitly reset it if nested instances should use different values.
For an existing site, use reva.scoped.css instead of the global build and keep the component inside .reva. Put shared configuration and token overrides on that boundary or inside it; the boundary installs its own defaults. Application selectors still need their own boundary if they must not affect matching classes elsewhere. CSS scoping is not Shadow DOM isolation.
Use Customize → Colours → Palette → Custom to define a palette with separate light and dark colours. Export its CSS and load it after RevaCSS. Use the exported data-palette="custom" name, or rename both the stylesheet selector and the HTML value to your brand name.
Keep the exported @layer re.tokens wrapper and the three --re-palette-* aliases for muted text, links and control borders. They allow material and accessibility rules to take priority. An unlayered colour override can outrank those rules. Define both modes and check all relevant foreground/background pairs, including both gradient endpoints. Contrast feedback is guidance; translucent surfaces still need review in their actual surroundings.
data-material styles documented targets. An arbitrary .project-summary element does not automatically acquire Glass, Veil or Soft UI just because it consumes colour tokens. The starter also uses .card, so it receives that hook’s supported surface treatments. Load the corresponding optional stylesheet after the core. Use data-material="solid" for a local reset of an inherited material.
If you design a new surface without an existing hook, you own its material styling and its reduced-transparency, forced-colours, increased-contrast and print fallbacks. Do not copy private material variables into an extension and treat them as a stable API.
Use native controls for disabled, checked, required and disclosure states. Keep state text alongside colour. aria-disabled="true" alone does not stop an action; an application must implement the corresponding behaviour. CSS does not save preferences, add components, fetch records or provide an ARIA widget’s keyboard contract.
The starter adds no animations. If an extension adds motion, respect data-motion="none" and reduced-motion preferences, using the documented motion guidance. If it adds advanced CSS, start with a usable layout and gate optional enhancements with @supports; feature detection does not replace browser verification. RevaCSS’s modern core has its own support boundary, so this is not a promise to support legacy browsers.
Before accepting an extension, review long and translated content, narrow parent containers, RTL, text enlargement, unique IDs across multiple instances, keyboard/focus behaviour and applicable states. Review both modes, chosen palettes/materials and accessibility preferences in the actual application. Follow QUALITY_STANDARD.md and record deferred or unverified checks explicitly.
An application can render or insert a component using this markup and preserve the same appearance contract. It owns component selection, data, permissions, destinations, form submissions and storage of user choices. It can update documented parent attributes when users change settings. Server-rendered preferences can also supply those attributes without browser JavaScript.
The RevaCSS core and this starter remain HTML/CSS-only. The documentation customizer is an optional site tool with its own JavaScript; it is not a runtime dependency for the exported component.
Use Customize to change the page appearance. The application class adds content styling; the existing card surface and native content consume the shared settings.
Website project
Build a custom component once and let its parent provide the appearance.
The card owns the surface. Custom CSS adds content layout and supporting text, without replacing material or focus styling.
Each section overrides only its colour mode. Choose a palette or shape in Customize to see the other settings continue to inherit.
Website project
Build a custom component once and let its parent provide the appearance.
The card owns the surface. Custom CSS adds content layout and supporting text, without replacing material or focus styling.
Website project
Build a custom component once and let its parent provide the appearance.
The card owns the surface. Custom CSS adds content layout and supporting text, without replacing material or focus styling.
The optional Glass stylesheet recognises the existing card hook. Application CSS does not replace its surface, so material preferences and fallbacks remain available.
Website project
Build a custom component once and let its parent provide the appearance.
The card owns the surface. Custom CSS adds content layout and supporting text, without replacing material or focus styling.
Save both files in the same project folder, next to the dist/ directory from your matching RevaCSS distribution. The HTML loads dist/reva.css and dist/reva.glass.css. Other materials need their own optional stylesheets. These starter files are source examples; the published package archives remain unchanged.
Read the complete extension reference in Markdown. For installation and version availability, use Get started.
/* Application extension: load after the matching RevaCSS stylesheets.
.card owns the surface, material, shape and preference fallbacks.
These rules add only project-specific content styling. */
.project-summary {
min-inline-size: 0;
overflow-wrap: anywhere;
}
.project-summary > .project-summary-label {
color: var(--re-muted);
font-size: .875em;
}
.project-summary > .project-summary-title {
font-size: var(--project-summary-title-size, 1.4em);
}
.project-summary > .project-summary-meta {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
gap: var(--re-space);
margin: 0;
}
.project-summary-meta > div {
min-inline-size: 0;
}
.project-summary-meta :where(dt, dd) {
margin: 0;
overflow-wrap: anywhere;
}
.project-summary-meta dt {
font-size: .875em;
}<!doctype html>
<html lang="en" data-theme="auto" data-palette="default" data-shape="rounded">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom component starter · RevaCSS</title>
<link rel="stylesheet" href="dist/reva.css">
<link rel="stylesheet" href="dist/reva.glass.css">
<link rel="stylesheet" href="custom-components.css">
</head>
<body id="page-top">
<a class="skip-link" href="#main">Skip to content</a>
<main id="main" class="container stack">
<h1>One component, shared appearance</h1>
<p>This application component reuses the card surface and native HTML. Change the settings on html to configure the inherited example; the local light and dark examples keep their explicit modes.</p>
<section class="stack" aria-labelledby="inherited-heading">
<h2 id="inherited-heading">Inherited appearance</h2>
<article class="card stack project-summary" aria-labelledby="inherited-title">
<p class="project-summary-label">Website project</p>
<h3 id="inherited-title" class="project-summary-title">Your next interface</h3>
<p>Build a custom component once and let its parent provide the appearance.</p>
<dl class="project-summary-meta">
<div><dt>Status</dt><dd>Ready for review</dd></div>
<div><dt>Owner</dt><dd>Design team</dd></div>
</dl>
<div class="accordion">
<details>
<summary>Component notes</summary>
<p>The card owns the surface. Custom CSS adds content layout and supporting text, without replacing material or focus styling.</p>
</details>
</div>
<a href="#component-notes">Read the extension notes</a>
</article>
</section>
<div class="grid">
<section class="stack" data-theme="light" aria-labelledby="light-heading">
<h2 id="light-heading">Local light mode</h2>
<article class="card stack project-summary" aria-labelledby="light-title">
<p class="project-summary-label">Website project</p>
<h3 id="light-title" class="project-summary-title">Your next interface</h3>
<p>The mode changes here; palette, shape and density still inherit.</p>
<dl class="project-summary-meta">
<div><dt>Status</dt><dd>Ready for review</dd></div>
<div><dt>Owner</dt><dd>Design team</dd></div>
</dl>
<a href="#component-notes">Read the extension notes</a>
</article>
</section>
<section class="stack" data-theme="dark" aria-labelledby="dark-heading">
<h2 id="dark-heading">Local dark mode</h2>
<article class="card stack project-summary" aria-labelledby="dark-title">
<p class="project-summary-label">Website project</p>
<h3 id="dark-title" class="project-summary-title">Your next interface</h3>
<p>The same component and stylesheet work in either mode.</p>
<dl class="project-summary-meta">
<div><dt>Status</dt><dd>Ready for review</dd></div>
<div><dt>Owner</dt><dd>Design team</dd></div>
</dl>
<a href="#component-notes">Read the extension notes</a>
</article>
</section>
</div>
<section class="stack" data-material="glass" aria-labelledby="glass-heading">
<h2 id="glass-heading">Inherited glass material</h2>
<article class="card stack project-summary" aria-labelledby="glass-title">
<p class="project-summary-label">Website project</p>
<h3 id="glass-title" class="project-summary-title">Your next interface</h3>
<p>Glass applies to the existing card hook. Unsupported filtering and accessibility preferences use the material module's fallbacks.</p>
<a href="#component-notes">Read the extension notes</a>
</article>
</section>
<section id="component-notes" class="stack" aria-labelledby="notes-heading">
<h2 id="notes-heading">Extension notes</h2>
<p>Load custom-components.css after RevaCSS. Keep the component's card class to inherit material styling. Use unique heading IDs for every instance and replace these demonstration links with real application destinations.</p>
<p>Change html's data-theme to light, dark or auto. Change data-palette to a documented palette, or load your exported custom palette after the framework. Adding components and saving preferences belong to your application.</p>
<p>This is an HTML/CSS reference example. Browser, device and accessibility acceptance checks for this addition are deferred; a successful build does not establish conformance.</p>
<a href="#page-top">Back to top</a>
</section>
</main>
</body>
</html>This addition has build verification only. Browser, device and accessibility acceptance checks remain deferred.