Facet
The design system this site is built from. Every swatch, size and component below is rendered from the tokens in
src/design/tokens.css, so if a token breaks, it breaks here where somebody will see it.
Check this page in both themes before shipping a visual change.
Color
Color is authored in OKLCH and expressed with light-dark(), so the two themes are one palette at two lightness ranges
rather than two stylesheets. Nothing outside tokens.css
may contain a color literal.
The palette has one hue, 251, and it is the mark's own: #123456, the blue the gazelle is drawn in, measures
oklch(0.3192 0.0725 251). Every surface and every ink is that color at another lightness, and --navy-700 is the
brand value itself to the last decimal.
Surfaces
Ink
Accent and semantics
The project's blue is the only accent, and it is deliberately rare: it marks the one thing on a screen that matters most, and nothing else. If two accent elements compete in a viewport, one of them is wrong.
The accent shares the ink's hue exactly, so it has only chroma to separate itself with: the ink ramp stays under 0.045 and the accent runs 0.11 to 0.15. That gap is what makes an active sidebar item read as active, and it is the reason the ink is kept as gray as it is.
Typography
Three faces, each with one job. Raleway carries display type, Heebo carries reading, and JetBrains Mono does every label on the site, which is what gives the pages their annotated, drawing-like quality.
Space
A 4px grid that opens up as it climbs. Space encodes relatedness: less inside a group, more between groups.
Buttons
Version badge
Written inline in markdown as [since 1.9]. It marks the release a feature first appeared in, and it works inside a
heading without touching the heading's id, the table of contents or the search index. The docs always describe the
latest Gacela release; this badge is the whole of the versioning story between majors.
Cacheable methods Since 1.9
And mid-sentence: a feature Since 1.9 sits on the baseline without growing the line.
Version switcher and archive banner
The header's release pill becomes this dropdown once an archived docs line exists. It is a details element, so it
works without JavaScript, and the pill it opens from is the same .badge the header always carried.
Every page of an archived line opens with this banner, linking to the page's current equivalent:
Callouts
Four kinds, distinguished by the color of the rail and by their label, never by color alone.
Card grid
Routes into a section, for a reader who has arrived without a destination. Cards take a column each while they fit and fall to one when they do not, so the same markup works in the documentation column and on a full-width page.
Index list
The workhorse of the marketing pages. A table of contents rather than a grid of cards, because a framework's feature set is a reference, and a reference should be scannable in one column pass. The arrow appears on hover and on focus; only the title takes the accent.
- An entry One line of summary, long enough to say what the page covers
- A second entry Two columns while they fit, one when they do not
Stat row
A few figures that establish scale before the prose about them starts. Three or four entries is the useful range; past that a table reads better.
Video
A self-hosted poster that links to the video. Nothing loads from YouTube until the reader presses play; then the link becomes a no-cookie player in the same frame. Without JavaScript it opens the video on YouTube.
Play video: Gacela in 60 seconds
Code
A framed block with a mono caption bar rather than a filled slab, so a page of documentation does not become a stack of gray rectangles. The syntax palette is part of the design system, and it deliberately avoids the accent: keywords sit on the navy ramp, strings on teal, functions on violet and constants on amber. A hundred accent-colored keywords on a page would leave nothing for the eight marks that carry real signal.
namespace App\Checkout;
use Gacela\Framework\AbstractFacade;
/**
* @method Factory getFactory()
*/
final class Facade extends AbstractFacade
{
public function placeOrder(Basket $basket): OrderId
{
return $this->getFactory()
->createOrderPlacer()
->place($basket);
}
}A block with no caption shows only its language:
composer require gacela-project/gacelaParallel files become tabs. The tabs are radio inputs and labels, so they switch with no JavaScript at all:
final class Facade extends AbstractFacade
{
}final class Factory extends AbstractFactory
{
}A recorded terminal session uses the same frame. The caption links to the exact source the output came from, the prompt is not selectable, and the pass and warning marks keep their glyphs, so colour only backs them up. A line holding only an ellipsis marks what an excerpt leaves out.
vendor/bin/gacela doctor
…
✓ class filenames
every pillar class matches its filename
⚠ Doctor finished with warnings
Prose
Lists
- Modules interact with each other only via their Facade
- The Factory manages the intra-dependencies of the module
- The Provider resolves the extra-dependencies of the module
- Install the package
- Create the four classes
- Bootstrap Gacela at your entry point
Tables
Hairline rules only. A filled header band would out-shout the headings around it.
| Class | File | Responsibility |
|---|---|---|
| Facade | Facade.php |
The entry point, and the only public surface |
| Factory | Factory.php |
Creates the module's own services |
| Provider | Provider.php |
Resolves dependencies from other modules |
| Config | Config.php |
Reads the project's configuration |
Quotes
The Facade is the entry point of your module.
Documentation furniture
Two components every documentation page carries. The pager closes the page with its neighbours in reading order; the inline table of contents is the same list as the sidebar TOC, folded into a disclosure for the widths where the sidebar is gone.
The disclosure below is therefore only visible under 1180px, which is the point the sidebar TOC takes over. Narrow the window to review it.
On this page
On this page
Links
Internal links such as the Factory sit in the accent color. External links such
as Packagist (opens in a new tab) look the same, but they open in a new tab and say
so: they carry target="_blank",
rel="noreferrer", and a visually hidden "(opens in a new tab)" so the announcement is not left to sighted users alone.