Documentation for the CSS structure, organization, and conventions.
ui/website/css/
├── styles.css # Main stylesheet (imports all)
├── foundations/ # Base styles
│ ├── normalize.css
│ ├── accessibility.css
│ ├── colors.css
│ ├── typography.css
│ ├── buttons.css
│ ├── forms.css
│ ├── tokens.css # CSS custom properties
│ └── icons.css
├── layout/ # Layout utilities
│ ├── base.css
│ └── utilities.css
├── pages/ # Page-specific styles
│ ├── home/
│ ├── parents/
│ └── careers/
└── shared/ # Reusable components
├── accordion.css
├── tabs.css
├── card.css
├── shapes.css
├── image-gallery.css
├── reveal.css
├── base/ # Header, footer
├── hero/ # Hero components
└── headings/ # Heading components
ui/website/base.html - Base template extended by all pagesui/website/css/styles.css - Main stylesheet (imports all CSS)ui/website/js/script.js - Main JavaScript entry pointui/website/css/foundations/tokens.css - CSS custom properties (tokens)File: ui/website/css/styles.css
Import order matters:
/* 1. Foundations - Base styles */
@import 'foundations/normalize.css';
@import 'foundations/accessibility.css';
@import 'foundations/colors.css';
@import 'foundations/typography.css';
@import 'foundations/buttons.css';
@import 'foundations/forms.css';
@import 'foundations/tokens.css';
@import 'foundations/icons.css';
/* 2. Layout - Structure */
@import 'layout/base.css';
@import 'layout/utilities.css';
/* 3. Shared Components */
@import 'shared/accordion.css';
@import 'shared/tabs.css';
@import 'shared/card.css';
@import 'shared/shapes.css';
@import 'shared/image-gallery.css';
@import 'shared/reveal.css';
/* 4. Shared Hero */
@import 'shared/hero/hero.css';
@import 'shared/hero/hero-title-shimmer.css';
/* 5. Shared Header and Footer */
@import 'shared/base/header.css';
@import 'shared/base/footer.css';
@import 'shared/base/submenus.css';
@import 'shared/base/hamburger.css';
@import 'shared/base/mobile-menu.css';
/* 6. Shared Headings */
@import 'shared/headings/underlined.css';
@import 'shared/headings/tagline.css';
/* 7. Page-specific (imported in page stylesheets) */
Block Element Modifier (BEM) naming:
.block {}
.block__element {}
.block__element--modifier {}
Example:
.card {}
.card__title {}
.card__title--large {}
.card--featured {}
All design tokens are defined in ui/website/css/foundations/tokens.css. Use CSS custom properties for consistent styling:
.my-component {
padding: var(--container-padding);
border-radius: var(--border-radius-medium);
transition: var(--transition-all-normal);
}
Location: ui/website/css/foundations/tokens.css
Full list: See ui/website/css/foundations/tokens.css
Utility classes are defined in ui/website/css/layout/utilities.css for common patterns.
<!-- Centered container with max-width -->
<div class="u-container">Content</div>
<!-- Padding utilities -->
<section class="u-padding-md"> <!-- 4rem vertical padding -->
<section class="u-padding-xl"> <!-- 8rem vertical padding -->
<section class="u-padding-xxl"> <!-- 12rem vertical padding -->
<!-- White background section -->
<section class="u-background-white">Content</section>
<!-- Centered flex container -->
<div class="u-flex-center">Content</div>
<!-- Space between items -->
<div class="u-flex-between">Items</div>
<p class="u-font-weight-medium">Medium weight text</p>
<!-- Show only on mobile/tablet -->
<div class="u-mobile-tablet-only">Visible < 1024px</div>
<!-- Show only on desktop -->
<div class="u-desktop-only">Visible >= 1024px</div>
<!-- Show only on mobile -->
<div class="u-mobile-only">Visible < 768px</div>
<!-- Hide on mobile -->
<div class="u-tablet-desktop-only">Visible >= 768px</div>
When two adjacent sections share the same padding class and background, the top padding is automatically removed on mobile:
<!-- Second section's padding-top is removed on mobile -->
<section class="u-background-white u-padding-xl">Section 1</section>
<section class="u-background-white u-padding-xl">Section 2</section>
Location: ui/website/css/layout/utilities.css
Full list: See ui/website/css/layout/utilities.css
Base styles that apply globally:
Layout and structure:
Reusable component styles:
Page-specific styles. Each page has its own folder:
pages/
├── home/
│ ├── styles.css # Imports all home page styles
│ ├── hero.css
│ ├── packages.css
│ └── ...
├── parents/
│ └── styles.css
└── careers/
└── styles.css
File: ui/website/css/pages/[page]/styles.css
/* Import component styles */
@import 'hero.css';
@import 'overview.css';
@import 'details.css';
{% block pageStyles %}
<link rel="stylesheet" href="{% static 'website/css/pages/[page]/styles.css' %}">
{% endblock %}
/* Mobile only */
@media (width < 768px) { }
/* Tablet and above */
@media (width >= 768px) { }
/* Desktop only */
@media (width >= 1024px) { }
/* Range */
@media (768px <= width <= 1024px) { }
Breakpoints are documented in ui/website/css/foundations/tokens.css:
| Breakpoint | Value | Usage |
|---|---|---|
small-mobile-only |
width < 375px |
Very small devices |
mobile-only |
width < 768px |
Mobile devices |
tablet-up |
width >= 768px |
Tablets and above |
mobile-tablet-only |
width < 1024px |
Mobile and tablets |
desktop-up |
width >= 1024px |
Desktop and above |
ultra-wide-up |
width >= 1750px |
Large screens |
Note: CSS custom properties cannot be used in media query conditions. Use the literal values shown above.
Always use CSS custom properties from tokens.css:
/* Good */
.my-element {
padding: var(--container-padding);
border-radius: var(--border-radius-medium);
}
/* Avoid */
.my-element {
padding: 4rem;
border-radius: 10px;
}
Use BEM consistently (excluding utility classes):
/* Good */
.card {}
.card__title {}
.card__title--large {}
/* Avoid */
.card-title {}
.cardTitle {}
Keep component styles scoped:
/* Component-specific */
.card {
/* Only styles that affect .card */
}
/* Page-specific overrides */
.my-page .card {
/* Overrides only for this page */
}
Use utilities for common patterns:
/* Use utility */
<section class="u-container u-padding-xl">
/* Avoid duplicating */
<section class="my-section">
Write mobile styles first, then enhance:
.element {
font-size: 1rem; /* Mobile */
}
@media (width >= 768px) {
.element {
font-size: 1.25rem; /* Tablet+ */
}
}
.my-section {
max-width: var(--container-width);
margin: 0 auto;
padding-inline: 2rem;
}
Or use utility:
<div class="u-container">Content</div>
.section {
padding-block: 4rem; /* Mobile */
}
@media (width >= 768px) {
.section {
padding-block: 8rem; /* Desktop */
}
}
Or use utility:
<section class="u-padding-xl">Content</section>
.section {
position: relative;
overflow: hidden;
}
.section__wrapper {
position: relative;
z-index: 2;
}
<section class="u-background-white u-padding-xl">
<div class="u-container">
Content
</div>
</section>
<div class="u-container u-flex-center">
Centered content
</div>