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.03emh2:var(--la-text-xl), letter-spacing-0.02emh3:var(--la-text-lg)h4:var(--la-text-md)
Usage notes
- Heading margins come from base.css. Reset them to
0inside component classes when spacing needs to be different. - Only one
h1per page. Useh2for section titles,h3toh4for 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%
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.