Frames & surfaces
Frames, corner crosses and half-crosses, control targets, capsules and floating surfaces.
Use framed for a ruled frame, crossed for corner crosses and half-crossed for corner marks, on any element. Three rules cover every layout: a frame draws its own borders; stacked frames in Page or Main drop their bottom rule, so the next frame's top rule is the shared line; a cross erases the line segments around it. No frame needs to know its neighbors.
01Preview
02Frames and corner crosses
Shared geometry defines control targets, border thickness and decorative cross length. Cross clearances and optical adjustments stay with the structural classes or owning component.
| Token | Role | Definition |
|---|---|---|
--control-min-size | Minimum width and height of control targets, independent of their icon size. | 32px |
--border-width | Shared thickness of borders, dividers and structural crosses. | 1px |
--cross-size | Full stroke length of the decorative crosses in .crossed. | 11px |
Control size
Apply --control-min-size to both minimum dimensions of an interactive target. Padding and content can make it larger; the token is a floor, not a fixed square. Drawing dimensions remain independent inside that target, and dependent layout clearance follows the target token.
.control {
min-width: var(--control-min-size);
min-height: var(--control-min-size);
}
--border-width controls borders and structural strokes, including crosses. Frame offsets and cross centering follow the same thickness. Active tab indicators use twice this width. Keyboard focus has an independent stroke; text underlines and icon drawings retain their own dimensions.
--cross-size controls the full stroke length of .crossed marks. --accent supplies their color and --border supplies frame rules. See Classes and Notes for shared lines and cross clearances.
03Capsules
Structural frames, text buttons and native fields remain square. The capsule is the one shared rounded silhouette, used by the theme toggle and pill-shaped badges.
| Token | Role | Definition |
|---|---|---|
--radius-full | Capsule silhouette; not circular icon geometry. | 999px |
Other rounded corners belong to their component: chat messages and the chat composer keep their own radius, 50% circular controls and optical focus corners remain local. Do not add a radius prop to every component.
04Floating surfaces
Use only the shared elevation roles needed by nonmodal surfaces. Native modal dialogs use the browser top layer; a z-index token cannot place an ordinary element above it. Their translucent backdrops share the overlay veil and blur: background: var(--overlay); backdrop-filter: blur(var(--overlay-blur)). Translucent bands over scrolling content reuse the blur alone.
| Token | Role | Definition |
|---|---|---|
--floating-control-shadow | Floating action above page content. | light0 6px 25px oklch(0% 0 0 / 7%)dark0 6px 25px oklch(0% 0 0 / 45%) |
--floating-shadow | Nonmodal floating surface. | light0 12px 55px oklch(0% 0 0 / 12.5%)dark0 12px 55px oklch(0% 0 0 / 60%) |
--floating-control-layer | Floating action above ordinary page content. | 40 |
--floating-layer | Nonmodal surface above floating actions. | 45 |
--skip-link-layer | Visible keyboard shortcut above nonmodal surfaces. | 100 |
--overlay | Translucent veil behind modal surfaces. | lightoklch(0% 0 0 / 32%)darkoklch(0% 0 0 / 60%) |
--overlay-blur | Blur of the page seen through modal backdrops and translucent bands. | 3px |
The dark theme redefines both shadows and the overlay more densely, so floating surfaces and modal backdrops still separate from the near-black page. Local frame strokes and pseudo-elements retain their internal ordering. Shadows do not replace visible borders or meaningful hierarchy, particularly in the dark theme.
05Classes
| Name | Description |
|---|---|
.framed | Draws all four edges; direct children of Page and Main drop the bottom one. Adds no content padding. |
.crossed | Draws crosses at all four corners, independently of the frame. |
.crossed-top | Draws only the top pair. Works without .crossed. |
.crossed-bottom | Draws only the bottom pair. Works without .crossed. |
.half-crossed | Marks the four corners with accent half-crosses drawn as background layers, inside the element. |
06Overrides
| Name | Type | Default | Description |
|---|---|---|---|
--cross-size | CSS length | 11px | Cross stroke length. Color follows --accent; frame lines follow --border. |
border-top | CSS border | var(--border-width) solid var(--border) | Set to none to open the top of a frame, as Header does at the top of the page. |
border-bottom | CSS border | var(--border-width) solid var(--border) | Set to none to open the bottom of a standalone frame; stacked frames already omit it. |
07Notes
- Load
@dg/ui/styles.cssonce in the app layout. These classes add no content padding; the owning element or component supplies it. --border-widthcontrols frame and cross thickness. Apply overrides to their common container so neighboring frames share the same geometry.- Use one cross variant per element.
framed crossed-bottomcombines a frame with the bottom pair. - For page sections, prefer
Section: it already appliesframedand selects crosses through itscrossesprop. Place frames directly inPageorMain. - Direct children of
PageandMaindrop their bottom border: each junction is drawn once, by the top rule of the next frame. The last frame of a page stays open at the bottom, likeFooter. Elsewhere, a frame keeps all four edges and the owning layout handles any spacing. - A cross is centered on the frame lines and erases them for a short length around it, including a neighbor's lines, with the page background. Two frames that cross the same junction paint identical pixels, so both may request it. Erasing affects only lines: content and tinted surfaces inside frames stay intact.
- Keep frames themselves transparent and tint their content instead; the erased line segments show the page background. Keep overflow visible on the crossed element: crosses extend beyond its bounds.
- Cross classes use
::beforefor line erasers and::afterfor strokes; reserve both for their drawing. Do not override internal--_variables. .half-crosseddraws two--cross-sizestrokes of--border-widthat each corner, pointing along the edges, from the border box; a transparent border keeps them on the outer edge. They are background images: abackgroundshorthand, such as a hover fill, removes them, whilebackground-colorkeeps them. Forced-colors mode drops them, so give the element a system border there. The defaultButtonvariant uses them at rest, and text fields and select show the same marks in--focuson focus.
08Usage
<script>
import { Main, Page } from "@dg/ui";
</script>
<Page>
<Main>
<section class="framed crossed">
<h1>Collection</h1>
</section>
<!-- Both frames cross the shared line; their crosses coincide. -->
<section class="framed crossed">
<p>The final section is open at the bottom; its bottom crosses end the side rails.</p>
</section>
</Main>
</Page>
A standalone frame uses the same classes:
<aside class="framed crossed">
<p>A framed note outside Page and Main.</p>
</aside>