02. Foundation: base.css

Base CSS sets the plain HTML defaults for every app. Keep this layer boring. Components belong in their own files, not here.

Use for

Use base.css for box sizing, document background and font, plain link reset, media max-width, form control font inheritance, keyboard focus, selection color, and reduced motion. That is the full list.

Avoid for

  • Button styles
  • Card layouts
  • Form field appearance
  • Table rules
  • Sidebar or any component-level rule

If you are writing a rule that targets a class name, it does not belong in base.css.

Document defaults

html and body both get min-height: 100% and background: var(--la-page) to prevent the background from stopping at a short page. body sets the global font, text color, and line height. Every other element inherits from here unless a component overrides it.

Body text: font, size, line-height, color

This paragraph renders at var(--la-text-md) with var(--la-line-base) line height and var(--la-ink-soft) color. Every element on the page inherits these unless a component class overrides them. The font comes from var(--la-font).

This second paragraph shows the natural block margin behavior. base.css sets none. Components and utilities control spacing between content blocks.

Headings

base.css overrides browser heading sizes so every heading maps to the design token scale. h1 to h2 use --la-weight-strong (700) and negative letter-spacing. h3 to h4 use --la-weight-bold (600). All four use --la-line-title line height.

All four heading levels

Heading one

Heading two

Heading three

Heading four

Token mapping

  • h1 : var(--la-text-2xl), letter-spacing -0.03em
  • h2 : var(--la-text-xl), letter-spacing -0.02em
  • h3 : var(--la-text-lg)
  • h4 : var(--la-text-md)

Usage notes

  • Heading margins come from base.css. Reset them to 0 inside component classes when spacing needs to be different.
  • Only one h1 per page. Use h2 for section titles, h3 to h4 for subsections.
  • Never skip levels for visual size. Use a utility class if you need a different size.

Links

Plain a elements have color: inherit and text-decoration: none. They blend into the surrounding text and have no special treatment until a component class is added. When a link needs to look like a button, use the button classes explicitly.

Plain link in body text

A plain link inherits the text color and has no underline. It looks like normal text until a component styles it. Links that need to stand out should be inside a component or use a utility class like .la-text-link.

Link as button

When a link needs to act as a primary action, add the button classes. The <a> tag is fine for navigation, the .la-btn-[name] class makes it look like a button.

Media

img and svg are set to display: block (removes the inline baseline gap) and max-width: 100% (prevents overflow). No other defaults.

img and svg : block display, max-width 100%

Sample photo

Left: <img> element: right: inline <svg> element. Both render as display: block with no baseline gap beneath them.

Form controls

Browsers do not inherit the page font into form controls by default. Base.css fixes that with font: inherit; color: inherit on button, input, select, and textarea. Every form element uses the same type scale as body text until a component class changes it.

Font inheritance: all controls at the body default

Disabled state: cursor: not-allowed

Focus and selection

:focus-visible removes the browser outline and applies var(--la-focus) as a box-shadow. ::selection uses var(--la-brand-soft) so highlighted text picks up the brand color.

:focus-visible : tab to see the brand focus ring

::selection : select this text to see the brand highlight

Select some of this text with your mouse or keyboard. The highlight uses var(--la-brand-soft) instead of the default blue. Keep the selection color subtle so text stays readable.

Inline code

The code element gets a small background, border, and monospace font. This is the only element-level visual rule in base.css. Everything else is invisible infrastructure.

code : inline code element

Use var(--la-brand) for brand colors, var(--la-text-sm) for small text, and var(--la-radius-md) for medium border radius. Type these token names by hand only when needed. Everything else should come from a component class.

Reduced motion

When a user enables "reduce motion" in their OS settings, base.css collapses all transition durations to 0.01ms and forces animations to a single iteration. This removes visible motion while keeping layout behavior intact.

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

This rule follows the system-level setting, not a class. No extra setup is needed because it is always active in base.css.