Surfaces
Surface
The painted container every card and panel is built on: elevation, material (auto, solid, frosted, glass or liquid), tone, variant and radius as independent props.
<script>
import { Surface } from "@codeatlasdev/ui";
</script>
<Surface elevation={2} tone="brand" p="4">…</Surface>
<Surface as="section" elevation={4} tone="info" p="4">…</Surface>
A Surface is one element painted by one CSS rule (.ca-surface). Each prop is a data-* attribute, and each attribute writes different --ca-surface-* variables, so the axes never fight: elevation is depth (shadow and the blur/fill tier), material is what the surface is made of, tone tints it, variant removes the fill or draws an outline, radius rounds it. Nothing is written to style.
material="auto" follows the theme: it reads the tokens that <html data-style> already rewrites, so an app on the default solid style gets opaque surfaces, and the same markup under outlined, tonal, clay, frosted or the liquid recipe takes that style, with no change to the component. Leave material unset unless one surface must differ. The explicit materials ignore data-style: solid is opaque paper, frosted a lighter blur, glass the full blur, and liquid is glass plus the SVG refraction layer, see LiquidGlass. The blurred ones need something behind them to blur, which is why the materials demo sits on a gradient.
When a Surface blurs (glass, frosted, liquid, or auto under a blurred style), the CSS rules apply to you as well when you wrap it: never will-change: transform on it or an ancestor, and never isolation: isolate on a parent of it. Both silently remove the backdrop blur. Under prefers-reduced-transparency translucent fills become opaque, and under forced-colors every surface gets a real CanvasText border, except variant="ghost".
Materials
`auto` follows the theme; the others look the same under every style.
auto
solid
frosted
glass
liquid
Reference #078 · Pick in the gallery
Code
Elevation
Steps 0 to 5: shadow and, for every material but `solid`, the blur and fill tier (0 flat, 3 regular, 5 chrome).
Elevation 0
Elevation 1
Elevation 2
Elevation 3
Elevation 4
Elevation 5
Reference #076 · Pick in the gallery
Code
Tone and variant
Tone tints the fill, or colors the outline of `variant="outlined"`.
neutral
filled
brand
filled
success
filled
warning
filled
error
filled
info
filled
neutral
outlined
brand
outlined
success
outlined
warning
outlined
error
outlined
info
outlined
neutral
ghost
brand
ghost
success
ghost
warning
ghost
error
ghost
info
ghost
Reference #079 · Pick in the gallery
Code
Interactive
`interactive` adds hover, press and a focus-visible ring. Render a real `button` or `a` (`as`), so it is focusable and named.
Reference #077 · Pick in the gallery
Code
Paper grain
`grain` multiplies a noise texture over the surface; `grain="animated"` shifts it and stays still under reduced motion.
grain
grain="animated"
no grain
Reference #543 · Pick in the gallery
Code
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | string | 'div' | Element to render (`section`, `a`, `button`, `li`...). |
elevation | 0 | 1 | 2 | 3 | 4 | 5 | 1 | Depth: drop shadow, and the blur/fill tier of the material. |
material | 'auto' | 'solid' | 'frosted' | 'glass' | 'liquid' | 'auto' | `auto` follows `<html data-style>`; `solid`, `frosted`, `glass` and `liquid` are absolute. `liquid` adds the SVG refraction layer. |
tone | 'neutral' | 'brand' | 'success' | 'warning' | 'error' | 'info' | 'neutral' | Semantic tint over the fill; the outline color of `variant="outlined"`. |
variant | 'filled' | 'outlined' | 'ghost' | 'filled' | `outlined` has an edge and no fill, `ghost` neither. |
radius | 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'pill' | undefined | Corner radius from the radius scale. Omit for the large radius (`--ca-radius-lg`). |
interactive | boolean | false | Hover, press and focus-visible states and a pointer cursor. Render a link or button, or give it a role and a name. |
glow | boolean | false | Brand halo behind the surface (a shadow, so it needs no isolation). It uses `--ca-glow-primary`, which is transparent under the `solid` and `flat` styles, so it only shows under styles that keep a glow (`glass`, `frosted`, `chrome`). |
grain | boolean | 'animated' | false | Paper grain: a multiplied noise overlay clipped to the surface radius. `'animated'` shifts it, and it is still under reduced motion. Strength: `--ca-grain-opacity` (0.08), tile size: `--ca-grain-size` (160px). |
p, px, py | Space | responsive | undefined | Padding as a spacing step (`"4"` = 16px). See [Layout primitives](/docs/layout/layout-primitives/). |
class | string | '' | Extra class names. Other attributes are forwarded to the element. |
children | Snippet | undefined | Content. |
Data attributes
The attributes are part of the public CSS contract, so an app can restyle one axis without touching the component: [data-elevation="0"], [data-material="glass"], [data-tone="error"], [data-variant="ghost"], [data-radius="pill"], [data-interactive], [data-glow], [data-grain].
SurfacePanel
SurfacePanel is a Surface at elevation 2 that renders a <section>. With an accessible name (aria-label or aria-labelledby) it is a region landmark: a filter bar, a settings group, a summary beside a table. It is not the AppShell sidebar Panel.