Apache Grails Website Design System
This document defines the reusable visual system for the guides catalogue. Implementations must place these tokens and components in assets/stylesheets/screen.css rather than introduce one-off styles. Catalogue tokens are scoped to the emitted .guides-page wrapper because the shared document template does not apply page metadata to the <body> element.
1. Atmosphere & Identity
The Apache Grails website is direct, technical, and welcoming. White and off-white reading surfaces keep dense documentation calm, Grails blue establishes structure, and the warm orange accent carries the framework's identity without overpowering the content. The signature is the chalice-led blue header paired with orange-topped white content cards.
2. Color
Palette
| Role | Token | Value | Usage |
|---|
| Brand | --guides-color-brand | #255AA8 | Section headers, version chips, category title links, focus outlines, Kapa modal title |
| Brand hover | --guides-color-brand-hover | #1d4684 | Interactive brand surfaces on hover and focus |
| Brand soft | --guides-color-brand-soft | rgba(37, 90, 168, 0.08) | Featured catalogue atmosphere |
| Accent | --guides-color-accent | #feb672 | Card top borders, hidden launcher text accent, catalogue REST icon, identity details |
| Launcher dark | Kapa widget only | #3F4346 | Ask AI launcher / project chrome background (not a page surface) |
| Legacy tag gold | Existing .tag-cloud scale | #F0C45A | Existing occurrence-scaled tag navigation |
| Accent wash | --guides-color-accent-wash | rgba(254, 182, 114, 0.2) | Featured catalogue highlight |
| Surface | --guides-color-surface | #ffffff | Cards, inputs, panels |
| Page | --guides-color-page | #F5F5F5 | Page ground and quiet dividers |
| Text | --guides-color-text | #666666 | Body and metadata (AA on white/off-white) |
| Strong text | --guides-color-text-strong | #4f4f4f | Guide titles and high-emphasis labels |
| Tag chip text | --guides-color-tag-text | #3d2914 | Dark ink on gold/orange tag chips |
| On brand | --guides-color-on-brand | #ffffff | Text on blue surfaces |
| Quiet border | --guides-color-border | #d8d8d8 | Nonessential dividers and card boundaries |
| Control border | --guides-color-control-border | #767676 | Input and control boundaries (3:1+ on white/off-white) |
Rules
- Grails blue establishes hierarchy; orange is an accent, not a second background system.
- White cards sit on the off-white page ground.
- New solid catalogue colors used for text, backgrounds, borders, or controls must be declared in this table and as scoped CSS custom properties before use. Derived alpha shadows may reuse brand RGB values when their complete shadow value is documented in the depth table.
- Purple gradients and unrelated accent hues do not belong in this design system.
3. Typography
Font stack
| Family | Usage |
|---|
| Roboto, Roboto Light, Roboto Medium | Catalogue UI, guide titles, metadata, navigation |
| Archia Light, Archia Thin, Archia Medium | Marketing display text elsewhere on the site |
| Inter | Long-form rendered guide articles only |
| JetBrains Mono | Code inside rendered guide articles only |
Scale
| Level | Size | Weight | Line height | Usage |
|---|
| Page title | 24px | Medium | 1.2 | Blue header bar |
| Section | 18px | Medium | 28px | .column-header labels |
| Card title | 16px | Medium | 1.35 | Guide and category cards |
| Body | 16px | Regular | 1.5 | Catalogue introductions and controls |
| Metadata | 14px | Regular | 1.4 | Date and category |
| Guide version chip | 12px | Light | 1.2 | Version links inside guide cards |
| Version navigation chip | 16px | Regular | 14px | Legacy version-cloud navigation |
Heading hierarchy (guides catalogue)
| Context | Rank | Notes |
|---|
| Featured / version / catalogue / discovery section titles | h2 | One section label each |
| Category grid card titles | h3 | Nested under catalogue h2 |
| Standalone category or tag page title | h2 | Page-level heading when not nested |
| Latest Guides section | h3 | Nested under discovery h2 |
| Latest guide card titles | h4 | Nested under Latest Guides h3 |
| Featured / version guide card titles | h3 | Nested under their section h2 |
| Search result / no-result titles | h3 | Nested under Find Guides h2 |
Large headings may use balanced wrapping. Body copy should use natural wrapping and remain readable at 200 percent zoom.
4. Spacing & Layout
Spacing tokens
| Token | Value | Usage |
|---|
--guides-space-2 | 8px | Chip gaps and tight relationships |
--guides-space-3 | 12px | Compact list rows |
--guides-space-4 | 16px | Default card and input padding |
--guides-space-5 | 24px | Grid gaps and section rhythm |
--guides-space-6 | 32px | Major section separation |
| Legacy section step | 50px | Existing .column-header and page spacing |
Grid
- Maximum content width is
1141px, inherited from .content. - The existing desktop breakpoint is
961px; the catalogue adds a content-driven tablet breakpoint at 768px. - Catalogue and discovery layouts are one column below
768px. - Category cards use CSS multi-column masonry (
column-count 1 / 2 / 3 at mobile / tablet / desktop) with break-inside: avoid so cards keep natural height instead of stretched equal-height grid rows. - Browser mechanics such as
column-count, percentages, and intrinsic sizing remain raw CSS rather than design tokens.
5. Components
Featured catalogue
- Structure: contained guides header followed by a labelled
section, blue section heading, lightly layered blue-orange atmosphere, introduction, guide-card grid. - Variants: current featured major on the index; selected major on a version page.
- Spacing: section gap 6, card gap 3 or 4, card padding 4.
- States: links expose default, hover, active, visited, and visible focus behavior.
- Accessibility: the heading labels the section; source order places the promoted catalogue before discovery controls.
- Motion: inherited color transitions only; no decorative movement.
Guide card
- Structure: title, metadata, text action inside a list item.
- Variants: featured and version cards use
h3.guides-card-title; latest cards use h4.guides-card-title under the Latest Guides h3. - Spacing: padding 4; title-to-meta and meta-to-action use space 2.
- States: focus within receives a clear brand outline; links retain underline feedback.
- Accessibility: titles remain text, metadata remains legible, and the action stays keyboard reachable.
- Layout: cards flow through the responsive guide-card grid.
Category grid and category card
- Structure: labelled catalogue section (
h2), multi-column masonry container, image-and-title card header (h3 when linked in the grid), guide list. - Variants: full catalogue and selected-major-only catalogue; standalone category pages keep an
h2 title. - Spacing: column gap 5; compact list rows use spaces 3 and 4; cards stack with space 5 between blocks in a column.
- States: category heading links use
--guides-color-brand / hover variant (AA on white). - Accessibility: category images are decorative because the adjacent heading supplies the name.
- Icons: homepage blue surfaces keep shared
restapis.svg (white); catalogue cards use restapis-guides.svg (orange #feb672 on white). - Layout: one column on mobile; two columns from
768px; three columns from 961px; cards never stretch to equal row height.
Discovery
- Structure: labelled section containing search/latest guides and version/tag navigation.
- Variants: index with search and latest cards; version page with navigation only.
- Spacing: section gap 6 and column gap 5 or 6.
- States: search uses an explicit label, native input behavior, and visible
:focus / :focus-visible outline. - Accessibility: a separate visually hidden
#guides-search-status node uses role="status", aria-live="polite", and aria-atomic="true"; JS sets "" on reset, "N guide(s) found" on matches, and "No results found" otherwise. Visible search result headings are h3 under Find Guides. - Layout: one column below desktop; two columns from
961px only when both columns contain content.
Version chip
- Structure: direct
.align-left.guides-version-chip child of .multi-guide, containing the link and hidden search tags. - Guide variant:
12px inherited Roboto Light text, 4px radius, and compact 4px 10px padding. - Version-cloud navigation: legacy
16px inherited Roboto Regular text, 3px radius, and 7px 12px 5px padding. - States: both use blue default, darker blue hover, and the catalogue's visible keyboard outline.
- Accessibility: search indexing uses
classList.contains('align-left') so extra chip classes remain compatible.
Mobile navigation
- Structure:
#show-navigation-link is a visible button that toggles #top-menus.is-open. - States: closed (
Show Navigation, aria-expanded="false") and open (Hide Navigation, aria-expanded="true"). - Color: open mobile panel background is
#666666 with white links (AA); desktop panel stays white. - Behavior:
toggleNavigation() toggles the is-open class only (no inline display); desktop @media (min-width: 961px) keeps #top-menus visible after mobile open/close then resize. Legacy show() remains for other callers.
Kapa Ask AI launcher
- Structure: 44x44 control with 12px bottom/right offsets; accessible DOM text
"Ask AI" with 0 font-size so the control stays icon-only visually. - Colors: hidden launcher text may use accent
#feb672; modal title uses brand blue #255AA8 on white; launcher background uses documented dark #3F4346. - Attributes: documented legacy
data-button-* plus current data-launcher-button-* height/width/background/bottom/right/image/padding/border-radius; data-button-* aliases (text-color, text-font-size, bg-color, position-bottom/right) are used for compatibility. - Layout: catalogue pages reserve bottom safe space; below
961px, footer gets a 68px right exclusion zone so sentences are not covered.
6. Motion & Interaction
| Type | Duration | Easing | Usage |
|---|
| Color feedback | 200ms | ease in-out | Links and interactive surfaces |
| Button press | 100ms | ease | Existing one-pixel pressed translation |
| Card shadow | 300ms | ease | Existing reusable content cards |
- Motion communicates interaction only.
- New animation may use only
transform, opacity, or color changes. prefers-reduced-motion: reduce sets scroll-behavior: auto, disables link/button transitions, and removes button press transform (including the navigation toggle).- Every interactive element needs a visible focus state; hover cannot be the only cue. Search focus uses both
:focus and :focus-visible.
7. Depth & Surface
The catalogue uses a restrained mixed strategy inherited from the site: white surfaces, an orange top rule for identity, and a very soft card shadow. Deeper shadows, glass effects, and heavy borders are not part of this surface.
| Token | Value | Usage |
|---|
--guides-radius | 4px | Cards, chips, inputs |
--guides-shadow-card | Blue-tinted soft elevation plus one-pixel grounding shadow | Guide and category cards |
| Section shadow | 0 8px 18px rgba(37, 90, 168, 0.14) | Section title elevation derived from brand blue |
| Legacy version-navigation radius | 3px | Existing version-cloud chips |
| Accent rule | 2px solid var(--guides-color-accent) | Guide and category card tops |
8. Accessibility Constraints & Accepted Debt
Constraints
- Target WCAG 2.2 AA with at least 4.5:1 contrast for normal text and 3:1 for large text and non-text controls.
- Keyboard users must reach every guide, category, version, and search control with a visible focus indicator.
- Users at 200 percent zoom and users on 375px-wide screens must receive a single readable column without horizontal scrolling of primary content.
- Reduced-motion users receive no non-essential transitions.
- The dense catalogue must lead with the promoted version and clear section labels to reduce memory and wayfinding load.
- Nested headings must not share rank with their parent section label.
Accepted debt
| Item | Location | Why accepted | Owner / Exit |
|---|
| Legacy float layout | Non-guides .two-columns pages | Outside the Grails 8 catalogue scope | Replace when those pages are redesigned |
| Occurrence-scaled tag cloud sizes | .tag1 through .tag50 | Size scale retained; chip text forced to --guides-color-tag-text for AA | Revisit with a dedicated taxonomy UX change |
| Separate article typography | body.guide | Rendered guide reading system is intentionally distinct | Keep unless long-form documentation is redesigned |