Landing foundations
What @sdxc/ui/landing is for, the band, type and motion rules its parts share, and every variable it reads.
Marketing pages built from bands: a hero, proof, feature bands, pricing, an FAQ and a closing call to action, plus the frames, code stages and diagrams that show a product working.
Copy comes in as props and the look comes from a few tokens, so one palette and a handful of variables set the art direction for every band.
See the components assembled into whole sites in the demo gallery.
import "@sdxc/ui/theme.css";
import { … } from "@sdxc/ui/landing";When to reach for it
- A product home, feature, audience, comparison or pricing page.
- A book, course or app landing that sells one thing from top to bottom.
- Any page read top to bottom as a story, where the general components would read as an app screen.
Shared ideas
- Bands
LandingSectionpaints atoneand picks one of fourspacingsteps;inverseandbrandre-point the text tokens so content stays legible. - Container sizingEach band is a container and its tokens are fluid in
cqi, so it tracks its own width, not the viewport. - Heading levelsThe hero owns the one
h1; each band opens aHeadingScopeone level deeper, andsizesets the look apart from the level. - Hairlines and surfacesEdges use
--ui-landing-hairlineand cards sit on--ui-surface-raised; both switch for dark mode andprefers-contrast: more. - MotionEntrances and loops run only under
prefers-reduced-motion: no-preference;MotionLoopadds a pause control. - AccessibilityDecorative visuals are
aria-hidden, and header controls reach--ui-target-size(44px on a coarse pointer).
CSS variables
Every custom property the namespace reads or declares, with its default and what it controls.
Reads the neutral and brand roles, success and danger in a few diagrams, and the raw neutral and brand scales for band fills. The roles are documented on Theming.
Layout and spacing
Declared on :root in theme.css. The spacing steps are fluid in the band's container, so override them with a clamp() rather than a fixed length.
| Variable | Default | What it controls |
|---|---|---|
--ui-landing-measure | 72rem | Widest the centered content column of every band grows. |
--ui-landing-gutter | 1rem | Inline padding at the narrowest step; it grows to 1.5rem and 2rem with the band. |
--ui-landing-section-space | clamp(5rem, 3.86rem + 4.85cqi, 7.5rem) | Block padding of a normal band. |
--ui-landing-section-space-compact | clamp(3rem, 2.32rem + 2.91cqi, 4.5rem) | Block padding of a compact band. |
--ui-landing-section-space-hero | clamp(3.5rem, 1.45rem + 8.73cqi, 8rem) | Block padding of a hero band. |
--ui-landing-section-space-cta | clamp(5rem, 4.09rem + 3.88cqi, 7rem) | Block padding of a closing call-to-action band. |
--ui-landing-header-space | clamp(2.5rem, 1.82rem + 2.91cqi, 4rem) | Gap between a LandingHeader and the band body under it. |
--ui-landing-header-end | --ui-landing-header-space | One header's own gap; bands that lay out their header themselves set it to 0. |
--ui-landing-header-height | 4rem | Height of the sticky site header, which sticky stage content clears. |
--ui-landing-band-radius | 2rem | Corner radius of an inset band's panel. |
Type
Display and chapter titles come from displayHeading() and Heading's display and chapter sizes; leads from landingLead().
| Variable | Default | What it controls |
|---|---|---|
--ui-font-display | var(--ui-font-sans) | Family of display and chapter titles. |
--ui-landing-display-size | clamp(2.625rem, 1.77rem + 3.64cqi, var(--ui-landing-display-max)) | Size of the page's h1; a split hero sets a smaller clamp. |
--ui-landing-display-max | 4.5rem | Top of the fluid display size. |
--ui-landing-display-tracking | -0.035em | Letter spacing of the page's h1. |
--ui-landing-display-weight | 500 | Weight of display and chapter titles. |
--ui-landing-display-leading | min(calc(0.875em + 0.5625rem), calc(0.6em + 1.8rem)) | Line height of the h1, tightening as it grows. |
--ui-landing-chapter-size | clamp(1.75rem, 1.18rem + 2.42cqi, 3rem) | Size of a band's chapter title. |
--ui-landing-chapter-leading | 1.1 | Line height of chapter titles. |
--ui-landing-chapter-tracking | -0.025em | Letter spacing of chapter titles. |
--ui-landing-lead-measure | 40rem | Widest a lead under a title grows. |
--ui-landing-lead-size | 1.125rem | Size of a band's lead. |
--ui-landing-lead-leading | 2rem | Line height of a band's lead. |
--ui-landing-lead-weight | 400 | Weight of a lead. |
--ui-landing-hero-lead-size | clamp(1.0625rem, 0.98rem + 0.4cqi, 1.25rem) | Size of the hero's lead. |
--ui-landing-hero-lead-leading | 1.55 | Line height of the hero's lead. |
--ui-landing-eyebrow-font | var(--ui-font-mono) | Family of the mono eyebrow above a title. |
--ui-landing-eyebrow-weight | 600 | Weight of the eyebrow. |
--ui-landing-eyebrow-transform | uppercase | Letter case of the eyebrow. |
--ui-landing-eyebrow-tracking | 0.1em | Letter spacing of the eyebrow. |
--ui-landing-eyebrow-color | var(--ui-neutral-fg-muted) | Ink of the eyebrow; inverse and brand bands re-point it. |
--ui-landing-accent-color | var(--ui-brand-fg) | Ink of the phrase AccentText stresses inside a title. |
Calls to action and logos
| Variable | Default | What it controls |
|---|---|---|
--ui-landing-cta-radius | 0.5rem | Corner radius of landing calls to action; 9999px makes pills. |
--ui-landing-cta-weight | 600 | Weight of a call to action's label. |
--ui-landing-cta-height | auto | Fixed height of a call to action. |
--ui-landing-logo-height | 1.75rem | Height of a mark in a logo cloud or marquee. |
--ui-landing-logo-height-lg | 2.25rem | Mark height from the lg container width up. |
--ui-landing-logo-tile | 4% of --ui-neutral-fg-emphasis over --ui-bg | Fill behind each mark in a tiled logo cloud. |
--ui-landing-tile-radius | 0.5rem | Corner radius of a logo cloud's tiles. |
Surfaces, edges and radii
theme.css declares the dark values under .dark and prefers-color-scheme: dark, and solid strong borders under prefers-contrast: more.
| Variable | Default | What it controls |
|---|---|---|
--ui-landing-hairline | 6% of --ui-neutral-fg-emphasis; 10% white in dark | The translucent line every landing rule, grid and edge draws with. |
--ui-surface-raised | white; a neutral 900–950 mix in dark | Fill of frames, cards, code stages and the header above a band. |
--ui-shadow-surface | 0 0 0 1px rgb(0 0 0 / 0.06), 0 1px 2px rgb(0 0 0 / 0.05) | Edge of a raised card: a ring and a small drop. |
--ui-shadow-stage | 0 0 0 1px rgb(0 0 0 / 0.06), 0 12px 32px -12px rgb(0 0 0 / 0.18) | Deeper shadow under a staged ProductFrame. |
--ui-shadow-control | a 1px drop with an inset highlight and ring | Edge of calls to action, header controls and the active stage tab. |
--ui-shadow-float | 0 25px 50px -12px rgb(0 0 0 / 0.15) | Shadow of the floating site header. |
--ui-image-outline | rgb(0 0 0 / 0.1); rgb(255 255 255 / 0.1) in dark | Inset line that keeps a photo's edge visible on a same-tone fill. |
--ui-landing-radius-surface | 1rem | Corner radius of staged cards and panels. |
--ui-landing-radius-frame | 0.75rem | Corner radius of product frames, code stages and tabbed stages. |
--ui-landing-card-radius-outer | 1.5rem | Radius of a card grid's corners on its outer edge. |
--ui-landing-card-radius-inner | 0.5rem | Radius of card corners that face a neighbour. |
--ui-landing-plan-radius | 1.5rem | Corner radius of every pricing plan. |
--ui-landing-plan-lift | 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1) | Shadow lifting the featured plan; none flattens it. |
Band fills
Read by landingBandTone(); none is declared in theme.css, so each default is the fallback in the code.
| Variable | Default | What it controls |
|---|---|---|
--ui-landing-band-tint | var(--ui-color-neutral-100) | Fill of a tinted band in light mode. |
--ui-landing-band-tint-dark | var(--ui-neutral-bg-tint) | Fill of a tinted band in dark mode. |
--ui-landing-band-glow | a quiet radial brand glow from the top corner | Image over a tinted band; none drops the glow. |
--ui-landing-brand-band | var(--ui-color-brand-700) | Fill of a brand band. |
--ui-landing-band-gradient | none | Image a gradient band paints; the page supplies it. |
--ui-landing-band-gradient-base | transparent | Color under the gradient band's image. |
--ui-code-stage-inset | 1rem | Inline start of a CodeStage's code; its header lines up with it. |
Set by the components
Written by a component from its props or its content, and read back by its own parts. Leave them unset.
| Variable | Default | What it controls |
|---|---|---|
--ui-landing-cell-padding-block, --ui-landing-cell-padding-inline | set per cell by the card grid | A cell's padding, which its media slot bleeds through. |
--ui-code-stage-gutter | set by CodeStage from its line count | Width of the line-number gutter. |
--ui-sponsor-wall-columns, -cell, -logo, -pad | set per tier by SponsorWall | Columns, cell height, logo height and padding of one sponsor tier. |
--ui-fan-<part>-n, --ui-fan-<part>-w | set per node by FanOutDiagram | Grid placement and bus lines of each node, narrow and wide. |