Design
System
Spec.
The technical and philosophical foundation behind every Beben Design deliverable. This document defines the decisions — not just the values — so the reasoning travels with the code.
01 // TYPOGRAPHY
Type Logic
A single typeface family — JetBrains Mono — handles all weight classes from 100 to 800. Monospace type is not an aesthetic choice here. It reflects the technical discipline of the studio: precise, structured, and with no ambiguity in letter spacing.
Hero H1
Nav links
Descriptions
Micro copy
Why monospace over a humanist typeface?
Most design studios default to geometric sans-serifs — clean, friendly, forgettable. Monospace forces every character to occupy identical horizontal space, which produces a grid-aligned, technical cadence. It signals precision without saying it.
Business read: clients hiring Beben for HMI, dashboard, or technical product work see a studio that operates in the same visual register as their own engineering tools. Typeface choice is positioning.
Why clamp() for display sizes?
Fluid type scaling eliminates the need for multiple breakpoint overrides. A single clamp(2.5rem, 7vw, 4.5rem) declaration handles every viewport from 320px to 4K. Less code, fewer edge cases, identical visual weight at all sizes.
Business read: fast, maintainable front-end code is part of the product quality promise — the type system is a direct demonstration of that practice.
02 // COLOUR
Palette v2.0
The palette moved away from pure #000000/#ffffff in v2.0. Smokey White and Onyx are warmer, less harsh on extended reading sessions, and carry a material quality that pure web defaults lack. The accent shifted from yellow to red — a deliberate reversal of the studio's earlier identity.
Why Signal Red (#E71D36) replaced Strobe Yellow as the primary accent?
Yellow is high-visibility but carries connotations of caution, construction, and warning systems — useful for HMI work, less useful as a brand action colour. Red (#E71D36) is assertive without being aggressive. It creates a stronger visual hierarchy on both Smokey White and Onyx surfaces, passes WCAG AA contrast requirements, and reads at a distance on marketing materials.
Business read: red is associated with urgency and confidence — appropriate for a studio asking clients to commit budget to a decision. Yellow remains in the system as a secondary accent for labels and tags, where its high-visibility character is an advantage.
Why Smokey White and Onyx instead of #fff and #000?
Pure white (#ffffff) creates maximum contrast that strains the eye over long sessions. #F7F4F3 reduces that harshness by approximately 3% luminance — imperceptible as a change but meaningful over a full page read. Onyx (#141414) does the same from the dark end: not quite black, which gives dark mode surfaces a material warmth rather than a void.
Business read: warmer surfaces are associated with craft and considered production. The detail signals that the studio made an intentional choice, not a default one — which is exactly the positioning Beben Design needs.
Why is the nav always dark (#141414CC) regardless of theme?
A nav that flips with the theme introduces a cognitive context-switch on every page load: the user must re-orient to a differently coloured chrome. A fixed dark nav with consistent --nav-text: #F7F4F3 content provides a stable anchor at the top of every page. The 80% opacity allows the body content to ghost through on scroll, maintaining spatial depth without obscuring readability.
Business read: consistent navigation reduces user uncertainty. In UX terms, predictable chrome is invisible chrome — which is the goal.
03 // SPACING & GRID
Spatial Logic
All spacing derives from an 8px base unit. Section padding runs at 80px vertical. The content column caps at 1100px with 2rem (32px) gutters on each side.
8px / 0.5rem
All spacing values are multiples of 8: 8, 16, 24, 32, 40, 80px. This keeps layout relationships mathematically consistent across breakpoints without requiring a framework.
1100px
Chosen to be wide enough for two-column layouts at desktop scale but narrow enough to prevent line lengths exceeding ~90 characters on body text — the threshold where readability degrades.
80px vertical
Consistent top/bottom padding on every section. Sections are separated by a 1px var(--dot) line, not whitespace alone — creating a document-like structure that reads as systematic rather than decorative.
24px × 24px
Background texture generated entirely in CSS via radial-gradient. Zero asset requests. The 24px pitch aligns to the 8px base unit (24 = 8 × 3), so the grid never conflicts with layout elements positioned on the spacing scale.
Why not use a CSS framework for the grid?
Frameworks add abstraction layers that obscure layout decisions. Writing spacing explicitly in CSS means every value is a deliberate choice, not a side effect of a utility class collision. The output is leaner, faster, and fully auditable.
Business read: clients inheriting a Beben codebase get CSS they can read and maintain. No dependency on a third-party framework that may deprecate or change its API.
04 // MOTION
Interaction Timing
Motion is purposeful or absent. Decorative animation is a performance and maintenance liability. Every transition in the system has a defined purpose, duration, and easing.
| Token | Value | Easing | Usage |
|---|---|---|---|
| Reveal | 0.6s | ease | Sections entering viewport — opacity 0→1, translateY 24px→0 |
| Hover state | 0.2s | ease | Card backgrounds, link colours, button fills |
| Theme switch | 0.3s | ease | background-color and color on body — no flash |
| Underline CTA | 0.25s | ease | width 0→100% on ::after pseudo-element |
| Menu overlay | 0.35s | ease | Mobile nav opacity + visibility — prevents layout flash |
| Toast | 0.3s | ease | opacity + translateY — enters from below, auto-dismisses at 2.5s |
| Hamburger → × | 0.3s | ease | transform on three spans — rotate and scale, no JS class swap on individual spans |
Why visibility + opacity for the mobile overlay instead of display:none toggle?
display:none removes the element from the paint tree instantly — no CSS transition can fire on it. Using visibility: hidden combined with opacity: 0 keeps the element in the paint tree but makes it invisible and non-interactive. The transition fires on both properties, producing a proper fade in/out.
Business read: a mobile nav that flashes open without animation reads as broken to users. It signals low build quality before a single word of content is read.
05 // COMPONENTS
Interaction Patterns
Every interactive component follows a single rule: the hover state must invert or visibly shift — not merely change opacity. A card that goes from Smokey White to Onyx on hover communicates state change unambiguously.
Border-first, Fill-on-hover
Cards use a 1px var(--border) frame with transparent fill at rest. On hover, background fills to var(--text). The inversion is legible in both themes without conditional logic.
Inline + Underline Grow
display: inline ensures the hover target matches only the text width — not the full container width. A ::after pseudo-element grows from 0 to 100% width on hover, replacing the need for a traditional underline.
max-height CSS Transition
Answers expand via max-height: 0 → 300px with overflow: hidden. No JavaScript height calculation. The + rotates 45° to form × via transform: rotate(45deg). One button per item, aria-expanded managed in JS.
Opacity + Transform Pair
Tooltips use opacity: 0 → 1 combined with translateY(4px → 0). Positioned relative to the parent's inline text width — never the container. Disabled on touch devices via @media (max-width: 480px).
Grid + Hover Indent
Two-column grid: fixed 60px number column, fluid content column. On hover, padding-left shifts by 8px — a micro-interaction that implies forward momentum without animation overhead.
Fixed + Auto-dismiss
Fixed position at bottom: 2rem, centred via translateX(-50%). Enters with translateY from below. Auto-dismisses after 2.5s. Uses --text background and --bg text — the inversion of the page itself.
See the system
in production.
Every rule in this document is applied live across beben.design. No gap between the spec and the shipped product — because the spec was written from the product, not before it.
VISIT BEBEN.DESIGN ↗