Skip to content

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

Main background
Prominent background
Prominent background
Gradient
Gradient
Main background
Half-crossed corners
Capsule surface

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.

TokenRoleDefinition
--control-min-sizeMinimum width and height of control targets, independent of their icon size.32px
--border-widthShared thickness of borders, dividers and structural crosses.1px
--cross-sizeFull 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.

TokenRoleDefinition
--radius-fullCapsule 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.

TokenRoleDefinition
--floating-control-shadowFloating action above page content.light0 6px 25px oklch(0% 0 0 / 7%)dark0 6px 25px oklch(0% 0 0 / 45%)
--floating-shadowNonmodal floating surface.light0 12px 55px oklch(0% 0 0 / 12.5%)dark0 12px 55px oklch(0% 0 0 / 60%)
--floating-control-layerFloating action above ordinary page content.40
--floating-layerNonmodal surface above floating actions.45
Visible keyboard shortcut above nonmodal surfaces.100
--overlayTranslucent veil behind modal surfaces.lightoklch(0% 0 0 / 32%)darkoklch(0% 0 0 / 60%)
--overlay-blurBlur 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

NameDescription
.framedDraws all four edges; direct children of Page and Main drop the bottom one. Adds no content padding.
.crossedDraws crosses at all four corners, independently of the frame.
.crossed-topDraws only the top pair. Works without .crossed.
.crossed-bottomDraws only the bottom pair. Works without .crossed.
.half-crossedMarks the four corners with accent half-crosses drawn as background layers, inside the element.

06Overrides

NameTypeDefaultDescription
--cross-sizeCSS length11pxCross stroke length. Color follows --accent; frame lines follow --border.
border-topCSS bordervar(--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-bottomCSS bordervar(--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.css once in the app layout. These classes add no content padding; the owning element or component supplies it.
  • --border-width controls 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-bottom combines a frame with the bottom pair.
  • For page sections, prefer Section: it already applies framed and selects crosses through its crosses prop. Place frames directly in Page or Main.
  • Direct children of Page and Main drop 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, like Footer. 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 ::before for line erasers and ::after for strokes; reserve both for their drawing. Do not override internal --_ variables.
  • .half-crossed draws two --cross-size strokes of --border-width at each corner, pointing along the edges, from the border box; a transparent border keeps them on the outer edge. They are background images: a background shorthand, such as a hover fill, removes them, while background-color keeps them. Forced-colors mode drops them, so give the element a system border there. The default Button variant uses them at rest, and text fields and select show the same marks in --focus on 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>
distributed·gallery