Voltage Vet — Design Guide

Version 1.0 · August 2026 · voltagevet.com rebuild (Squarespace → Next.js)

This document defines the visual system for the rebuilt Voltage Vet site and its internal admin. It carries forward the existing brand’s typefaces and palette, and adopts a new layout language adapted from the Colorlib “Hamlet” template. Section 9 contains the token block to paste into the codebase.

1Brand summary

Voltage Vet is a one-person personal electric vehicle repair shop in Brightwood, Washington DC. Blake has completed 250+ repairs across 60+ brands of scooters, e-bikes and unicycles, working out of a home workshop rather than a storefront. The design intent follows from that: utilitarian, confident, workshop-honest. No showroom gloss, no stock-photo optimism. The palette stays near-monochrome — black ink on white paper, gray for structure — with a deep brick red used sparingly enough that it always means something: an action, a link, a section marker. The layout language is editorial and generous, borrowed from Hamlet: full-bleed photography with dark overlays, content panels that offset and overlap those images, small uppercase labels above large headings, and a lot of vertical air between sections. The result should read like a tradesperson’s portfolio, not a marketplace listing.

Sources merged here: the live Squarespace theme (typefaces and the four brand colors, all retained) and the Hamlet template at preview.colorlib.com/#hamlet (structure only — none of its type or color). Page references throughout point at mockups.html, screens 1–7.

2Color system

Four colors carry over unchanged from the existing site. Everything else is derived from them by fixed rules: the accent shades move only in lightness at hue 0, and the tint is a hand-tuned warm neutral in the same hue family.

2.1 Core palette

SpecimenClick a swatch to copy its hex
Ink
#211F1F
Paper
#FFFFFF
Line
#DFDFDF
Accent
#591A1A
Tint
#F4E7E7
Tint line
#EBD9D9
Panel
#F2F2F2
Ink muted
#5C5858
Accent hover
#6E2020
Accent active
#470F0F
Accent on dark
#D9A6A6
Muted on dark
#B5AEAE
Name / tokenHexHSLRole and usage rule
--color-ink#211F1F0, 3.1%, 12.5% All body and heading text on light surfaces. Background of dark sections (stats row, footer, hero overlay base). This is the site’s black — never use #000.
--color-paper#FFFFFF0, 0%, 100% Default page background and card fill. Text color on ink and on accent.
--color-panel#F2F2F20, 0%, 94.9% Neutral panel fill: alternating section backgrounds, table row hover, admin canvas. The quiet alternative to the red tint.
--color-line#DFDFDF0, 0%, 87.5% Borders, hairline rules, table row dividers, input borders, disabled button fill. Too dark to be a large surface fill — use --color-panel for that.
--color-accent#591A1A0, 54.8%, 22.5% The single brand accent. Primary buttons, inline links, active nav, the uppercase section labels, focus rings, the “new” status chip. Reserve it: if more than roughly 5% of a screen is red, cut something.
--color-accent-hover#6E20200, 54.9%, 27.8% Hover state for accent-filled surfaces and accent text. Derived: accent lightness +5.3, hue and saturation held.
--color-accent-active#470F0F0, 65.1%, 16.9% Pressed / active state. Also the underline color for a link that is the current page.
--color-tint#F4E7E70, 37.1%, 93.1% The warm panel. This is our replacement for Hamlet’s #ffdfdf, pulled toward the brand’s brick hue and lightened so black text sits on it comfortably. Used for the offset detail card, testimonial blocks, and callout panels. One per screen, at most two.
--color-tint-line#EBD9D90, 31.0%, 88.6% Rules and dividers drawn inside a tint panel, where #DFDFDF reads cold.
--color-ink-muted#5C58580, 2.2%, 35.3% Secondary text on light surfaces: captions, hints, table headers, timestamps. Passes AA at all sizes (7.02:1 on white).
--color-accent-on-dark#D9A6A60, 40.2%, 75.1% Required substitute for the accent on ink backgrounds. Uppercase labels, stat captions, and footer headers inside dark sections use this, not #591A1A.
--color-on-dark-muted#B5AEAE0, 4.5%, 69.6% Secondary text on ink: footer links at rest, hero subheads, fine print. Warm gray, not blue-gray.

2.2 Form semantics

Two additional hues exist only for form and status feedback. The error red is deliberately brighter and slightly warmer than the brand accent so an inline error never reads as a section label. Never signal state by color alone — errors carry an icon and text, success carries text.

TokenHexHSLRole
--color-error#A4231C3, 70.8%, 37.6%Invalid field border, error text and icon. 7.41:1 on paper.
--color-error-surface#FDECEA6, 82.6%, 95.5%Fill for form-level error banners. Error text on it is 5.72:1.
--color-success#14654A160, 66.9%, 23.7%Submission confirmations, “ready for pickup” status. 7.02:1 on paper.
--color-success-surface#E8F3EE153, 31.4%, 93.1%Fill for confirmation banners and the ready chip. 6.18:1.

2.3 Contrast

Ratios computed against WCAG 2.1. Normal text needs 4.5:1, large text (24px, or 18.66px bold) needs 3:1, and UI borders / focus indicators need 3:1.

ForegroundBackgroundRatioVerdict
#211F1F ink#FFFFFF paper16.40:1AAA — default body pair
#591A1A accent#FFFFFF paper13.23:1AAA — links and labels on paper
#591A1A accent#F4E7E7 tint10.98:1AAA — labels inside offset cards
#591A1A accent#DFDFDF line9.93:1AAA
#5C5858 ink muted#FFFFFF paper7.02:1AAA — smallest usable gray on paper
#FFFFFF paper#591A1A accent13.23:1AAA — primary button label
#FFFFFF paper#211F1F ink16.40:1AAA — dark sections
#D9A6A6 accent-on-dark#211F1F ink7.77:1AAA — labels in dark sections
#B5AEAE muted-on-dark#211F1F ink7.52:1AAA — footer links at rest
#591A1A accent#211F1F ink1.24:1Forbidden — invisible. Use #D9A6A6.
#6E2020 accent hover#211F1F ink1.48:1Forbidden — same failure.
#DFDFDF line#FFFFFF paper1.33:1Decoration only. Adequate as a border, never as text.
#F4E7E7 tint#FFFFFF paper1.20:1Decoration only. A tint panel on paper needs its own edge (shadow or 1px #EBD9D9) to be visible.

Put accent red on ink, or ink text on accent red. Both fail.

Introduce a fifth hue. If something needs to stand out and red is taken, use weight, size or space.

Assume any text over a photograph sits on the hero overlay (rgba(33,31,31,.55) or heavier) and is white.

3Typography

Two families, carried over from the existing site, with a hard division of labor.

FamilyWeightsFallback stackScope
Archivo Black400 only 'Arial Black', 'Arial Bold', Gadget, sans-serif Display only: page titles, section headings, card headings, stat numbers, price figures. Never body copy, never a paragraph, never more than about twelve words.
Space Grotesk300–700 variable ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif Everything else: body, lead paragraphs, uppercase labels, buttons, form fields and labels, tables, captions, navigation, the entire admin.

Archivo Black ships one weight and no true italic. Never apply font-weight:bold or font-style:italic to it — the browser will synthesize both and the result smears. Arial Black is wider than Archivo Black by roughly 4%, so headings may gain a line during the font swap; keep display=swap and reserve headline space with min-height on the hero.

3.1 Display scale — Archivo Black

Sentence case throughout. Never all-caps a display heading; the face is already loud and Archivo Black in caps at large sizes loses word shape. Tight leading, negative tracking, and never let a display line exceed about 28 characters before it wraps.

SpecimenRendered at desktop sizes

Display / 68px

Same-week repairs

H1 / 52px

What things cost

H2 / 40px

The repairs I do every week

H3 / 24px

Tires and flats

H4 / 18px

Solid tire swap

Stat / 56px

250+

RoleDesktopMobileLine heightTrackingWhere
Display (hero)68px38px1.02-0.02emHome hero only
H1 (page title)52px34px1.05-0.02emServices, Brands, Request
H2 (section)40px28px1.08-0.015emEvery section heading
H3 (card / sub)24px20px1.15-0.01emService cards, brand blocks
H4 (minor)18px17px1.250Detail-card columns, footer brand line
Stat number56px40px1.00-0.02emCounter row
Price figure36px / 26px28px / 22px1.00-0.02emPricing table, service cards

3.2 Text scale — Space Grotesk

SpecimenRendered at desktop sizes

Services & pricing

Label / 13px · 500 · 0.12em · uppercase · accent

Most repairs come back to you inside a week. Bring me the scooter, tell me what it’s doing, and you’ll get a quote before anything gets opened up.

Lead / 20px · 400 · 1.55

A flat on a solid tire is a different job from a flat on an air tire, and the difference matters more than most shops explain. Air tires ride better and puncture more. Solid tires never puncture and beat up your wrists on brick. I quote both when the choice is real, with the trade-off written out, because you are the one who has to ride it home over Georgia Avenue.

Body / 17px · 400 · 1.65 · max 66ch

Drop-off is by appointment at a residential address in Brightwood, shared after you accept a quote.

Small / 14px · 400 · 1.5 · ink muted

Photograph: rear hub teardown, Apollo City Pro, March 2026.

Caption / 13px · 400 · 1.45 · ink muted

RoleSizeWeightLine heightTrackingNotes
Lead paragraph20px4001.550One per section maximum, directly under an H2.
Body17px (16px mobile)4001.650Measure capped at 66ch (~640px).
Small14px4001.500Secondary detail, ink muted.
Label13px5001.200.12emUppercase, accent red. Always immediately above an H1/H2, 12px gap.
Caption / hint13px4001.450Ink muted. Photo credits, field hints.
Button15px (13.5px small)5001.000.02emSentence case, never uppercase.
Field label13px6001.300.01emSentence case, above the input.
Input text16px4001.40016px minimum — anything smaller triggers zoom on iOS.
Table header11.5px5001.200.10emUppercase, ink muted.
Table cell15px4001.450font-variant-numeric: tabular-nums on every numeric column.
Chip12px5001.000.02emSentence case.

Pair every H1 and H2 with a label above it. That pairing is the signature of the layout.

Set a paragraph in Archivo Black, or a heading in Space Grotesk on a public page. The split is the identity.

4Layout patterns

Seven patterns, adapted from Hamlet. They compose the entire public site. The mockettes below are rendered at reduced type scale to fit this page; production sizes are in section 3.

4a — Hero

Full-bleed photograph, ink overlay at 55%, content anchored to the bottom-left of a 1140px container. Label, then display headline in white, then one sentence, then two actions. Height is 78vh on desktop with a 560px floor, 62vh on mobile.

Mockette 4aHero

Brightwood, Washington DC

Same-week scooter repair

Two hundred and fifty repairs, sixty-plus brands, one bench. Tell me what it’s doing and you’ll have a quote before anything comes apart.

Used on: Home (screen 1). A shorter variant — 320px tall, H1 instead of display, no photograph, panel background — heads Services & Pricing (2), Brands (3) and Request a Repair (4).

4b — Offset detail card

Hamlet’s signature move. A tint panel pulled up over the bottom edge of the hero image, inset from the container edges, floating on a very long soft shadow. It holds the three facts a visitor needs immediately. This appears exactly once per site, on the home page.

Mockette 4bOffset detail card overlapping the hero

Turnaround

Most jobs back within a week. Rush work when parts are on the shelf.

Quote first

Nothing gets opened up before you’ve seen a price and said yes.

Drop-off

By appointment in Brightwood. Address shared once the quote is accepted.

Used on: Home (screen 1), directly under the hero. Specification: background --color-tint, radius 5px, shadow 73px 73px 78px -70px rgba(33,31,31,.24), overlap -64px desktop / -32px mobile, horizontal inset 44px from the container, padding 40px 48px at production scale. On mobile the three columns stack and the shadow is reduced to --shadow-soft.

4c — Standard section

The workhorse. Label, H2, and a 5/7 split: heading and a short stance on the left, the substance on the right. Vertical padding 96px desktop / 56px mobile. Alternate between paper and panel backgrounds down the page so sections separate without rules.

Mockette 4cSection: label + heading + two columns

How it works

Four steps, no showroom

Send a description and a photo. I’ll ask a couple of questions to work out whether it’s something I can actually fix — a fair number of requests aren’t. If it is, you get a written quote, and only then the drop-off address.

Tire jobs get two quotes: solid and air, with the trade-off spelled out, so the choice is yours rather than mine.

Read the tire explainer

Used on: Home (screen 1) for “Four steps, no showroom” and “Parts sourced, quirks memorized”; Services & Pricing (2) for the solid-vs-air explainer; Brands (3) for the intro.

4d — Image-led card grid

Three across on desktop, two at tablet, one on mobile, 24px gaps. Photograph on top at 4:3, then H3, then two lines of copy, then the price range pinned to the bottom of the card above a hairline. Cards are equal height; the price rule aligns across the row.

Mockette 4dServices card grid

Tires & flats

Tube, solid or air swap on most scooter and EUC sizes. Quoted both ways.

$45–$95Typical range

Throttles & displays

Dead screens, ghost throttles, connector corrosion. Bench-tested before return.

$60–$140Typical range

Brake service

Pads, rotors, cable and hydraulic bleeds. Drum brakes on request.

$40–$110Typical range

Used on: Home (screen 1) “The repairs I do every week”; Services & Pricing (2) as the full catalogue; Brands (3) for the four featured brand blocks, where the price range is replaced by a text link.

4e — Stat counter row

Full-bleed ink band, four figures, hairline dividers at 14% white. Numbers in Archivo Black, captions in the accent-on-dark red. Count-up animation is optional and must respect prefers-reduced-motion; the final value is always in the markup so it renders without JavaScript.

Mockette 4eStat counters on ink
250+Repairs completed
60+Brands serviced
7Day average turnaround
1Person on the bench

Used on: Home (screen 1), between the services grid and the testimonials. Optionally repeated at the foot of Brands (3).

4f — Testimonial block

Tint panel, an oversized quotation mark in accent at 50% opacity, the quote in Space Grotesk at 19–22px (not Archivo Black — a customer’s words are not a headline), attribution and the machine serviced separated by a tint rule. Two or three across, or a single centered block at 720px.

Mockette 4fTestimonial
Told me straight that the controller was gone and it wasn’t worth replacing on that model. Charged me nothing for the diagnosis. That’s the whole reason I came back with the next one.
Marcus T.Ninebot Max G30
Two quotes, air and solid, with an actual explanation of which one made sense for my commute. Nobody else bothered to ask where I ride.
Priya R.Apollo City Pro

Used on: Home (screen 1), “What people say afterward”. A single block also sits above the form on Request a Repair (4).

4g — Footer

Ink background, four columns: brand statement, two link columns, and contact. Column headers use the label style in accent-on-dark. Links rest at muted-on-dark and go pure white on hover. A hairline at 14% white separates the fine-print row.

Mockette 4gFooter
Voltage Vet

Personal electric vehicle repair in Brightwood, Washington DC. One bench, one person, no showroom.

© 2026 Voltage VetDrop-off address shared after quote acceptance.

Used on: every public page (screens 1–4). The admin (screens 5–7) has no footer.

5Components

5.1 Buttons

Three levels only. Radius 5px, 1.5px border on every variant so the outline and filled buttons share a bounding box. Padding 15px/26px at default size, 10px/16px small. Transitions at 180ms. The states below are pinned open so they can be read without hovering; live hover and keyboard focus also work.

SpecimenAll states, on paper
VariantRestHoverActiveFocusDisabled
Primary Request a repair Request a repair Request a repair Request a repair Request a repair
Secondary See pricing See pricing See pricing See pricing See pricing
Quiet link Read the explainer Read the explainer Read the explainer Read the explainer Read the explainer
SpecimenInverted, on ink
Request a repair Hover See pricing Hover Focus

On ink, primary inverts to a white fill with ink text; the accent red is unusable there (1.24:1). Focus ring switches to --focus-ring-dark.

StatePrimarySecondaryQuiet
Restbg #591A1A, text white1.5px #211F1F, text ink, transparenttext #591A1A, 1px underline at 5px offset
Hoverbg #6E2020bg #211F1F, text whitetext #6E2020, underline 2px
Activebg #470F0Fbg #470F0F, border sametext #470F0F
Focus visiblebox-shadow: 0 0 0 3px rgba(89,26,26,.30) and no outline suppression on keyboard nav. Never remove focus styling.
Disabledbg #DFDFDF, text #8B8585, cursor:not-allowed, aria-disabled rather than the disabled attribute where the reason needs explaining.

Put two primary buttons in the same view. There is one action per screen that matters.

5.2 Form fields

The repair-request form is the site’s only real conversion surface, so it gets the most careful treatment. Single column, labels above inputs, hints below labels, generous 18px gaps between fields, no placeholder-as-label. Inputs are 16px to prevent iOS zoom on focus.

SpecimenRequest form fields — rest, focus, error, messages
Sounds, smells, when it started, whether it still powers on.
I need the make and model to know whether parts exist for it.
Request received. I’ll reply within a day, usually sooner.
Three fields need attention before this can be sent.

Used on: Request a Repair (screen 4), and the admin quote and payment forms (screens 6–7) at admin density.

StateBorderRing / fillNotes
Rest1px #DFDFDFwhite fillRadius 5px, padding 12px 14px.
Hover1px #BFB9B9Signals interactivity without shouting.
Focus1px #591A1A0 0 0 3px rgba(89,26,26,.18)Ring is 3:1 against white and against the field fill.
Error1px #A4231C0 0 0 3px rgba(164,35,28,.14)Label turns #A4231C; message carries an icon and is linked by aria-describedby.
Disabled1px #DFDFDF#F2F2F2 fillText #8B8585.

5.3 Status chips (admin)

Pill shape, 12px, sentence case. The job pipeline reads left to right; only “New” gets a solid accent fill, because only new requests demand action. Every chip is text-first — the color is reinforcement, not the signal.

SpecimenJob pipeline states
New Triaging Quoted In repair Ready for pickup Closed Out of scope

Used on: Request Queue (screen 5) and Job Detail (screen 6).

5.4 Tables

No zebra striping and no vertical rules. A 1.5px ink rule under the header, 1px line rules between rows, panel fill on row hover. Numeric columns are right-aligned and tabular.

SpecimenPricing table
ServiceNotesTypical range
Solid tire swap, frontIncludes tube removal and rim clean$45 – $75
Air tire swap, rearHub motor removal on most models$70 – $110
Brake servicePads and cable; hydraulic bleed +$25$40 – $85
Controller replacementPart cost quoted separately$90 – $160
Diagnosis onlyWaived if you go ahead with the repair$0 – $35

Used on: Services & Pricing (screen 2); the same table at admin density carries the queue (5) and weekly books (7).

5.5 Price range display

Prices are ranges, never single figures, and the range is the honest part of the brand. Archivo Black for the figure with tabular numerals, an en dash with hair spaces around it, and a small uppercase qualifier underneath so nobody mistakes a range for a quote.

SpecimenTwo sizes
$45–$95Typical range
$70–$110Typical range
$0–$35Waived if you proceed

Used on: Services & Pricing (screen 2), service cards on Home (1). The qualifier line is mandatory; a bare number reads as a fixed price and invites disputes.

5.6 Brand logo strip

Logos sit grayscale at 50% opacity so the strip reads as texture rather than a set of competing brands, and come to full color on hover or focus. Equal-height cells divided by hairlines, five across desktop, two on mobile.

SpecimenThird cell shown in its hover state

Used on: Home (screen 1) under the services grid; Brands (screen 3) above the “60+ other brands serviced” list. Manufacturer marks are third-party trademarks — reproduce them unmodified apart from the grayscale filter, and keep the affiliate disclosure adjacent where a link is monetized.

6Imagery

Photography is the only source of color and texture in an otherwise monochrome system, which makes it load-bearing. Everything should be shot on the actual bench: parts laid out, hands in the work, a scooter mid-teardown, the tidy corner of the workshop. Grease is fine. A person is better than an object.

SpecimenThree treatments

Plain. Cards and galleries. Radius 5px, no shadow, no border.

On the bench

Rear hub teardown

Overlaid. Any time text sits on the image: rgba(33,31,31,.55).

Light subject. Deepen the overlay to .65 before adding text, or move the text out of the image.

Shoot real jobs. Blake’s own workshop, his own hands, actual customer machines with permission.

Use 5px radius on every image, everywhere, with no exceptions. It is the one shape rule in the system.

Apply the ink overlay whenever text or a button sits over a photograph, and verify white text clears 4.5:1 against the lightest region of the image, not the average.

Crop to 4:3 for cards, 3:2 for editorial blocks, and 16:9 or wider for the hero. Serve AVIF/WebP with a JPEG fallback and always set explicit dimensions.

Use stock photography of models on scooters, glossy studio product shots, lens flare, or anything with a color-graded teal-and-orange look.

Drop-shadow a photograph. The only long shadow in the system belongs to the offset detail card.

Desaturate photographs. Grayscale is reserved for the brand logo strip so that treatment stays meaningful.

Put a photograph behind body copy. Overlays are for headlines and short lines only.

7Spacing & grid

Base unit is 8px. Every margin, padding and gap is a multiple of it, with 4px available for optical adjustment inside components. Nothing else.

SpecimenSpacing scale, px
MeasureDesktopMobileNotes
Max content width1140px100%Matches Hamlet’s Bootstrap container. Full-bleed backgrounds extend past it; content never does.
Gutter (page edge)24px20pxMinimum breathing room at the viewport edge.
Section padding, vertical96px56pxThe primary rhythm. Two adjacent sections give 192px of separation, which is intentional.
Feature section padding128px72pxHero-adjacent and closing call-to-action sections only.
Grid gap (main columns)32px24pxHamlet’s 30px, rounded onto the 8px grid.
Card gap24px16pxService grids, brand blocks, testimonials.
Card padding24px20pxOffset detail card is the exception at 40px / 48px.
Label → heading12px10pxFixed. The label should feel attached to the heading.
Heading → body20px16px
Body paragraph gap16px14px
Body measuremax 66chAbout 640px at 17px. Hard cap; wide text is the fastest way to look unedited.
Corner radius5px5pxUniversal, from Hamlet. Chips and avatars use a full pill instead.
SpecimenVertical rhythm, desktop
96px section padding

Section label

Section heading and its content

96px section padding
96px section padding

Next section on panel

Alternating background separates it

96px section padding

Bands shown at half scale. Sections separate by background change and space, never by a horizontal rule across the full width.

8Admin note

The internal admin — request queue, job detail, weekly books — runs on the same tokens with three deliberate departures. It is a tool Blake uses weekly on a laptop, not a page anyone is being persuaded by.

  1. Space Grotesk only. Archivo Black appears nowhere below a page title, and arguably not at all: page titles are Space Grotesk 700 at 22px. Display type in a dense table view costs vertical space and buys nothing.
  2. Denser spacing. Section padding drops from 96px to 24px, card padding to 16px, table rows to roughly 40px, controls to a 34px height. Body text steps down to 15px, secondary text to 13px. The 8px base unit still holds.
  3. Same red, used less. The accent stays #591A1A and appears only on the primary action, the active sidebar item, links, and the “New” chip. No tint panels except in alert banners. Canvas is --color-panel, content sits on white cards with --color-line borders and a 4px radius.
MocketteAdmin density

Request queue

27 open · 4 new since yesterday · oldest untouched request is 2 days old

New job Filter 4 new
CustomerMachineStatusAgeQuote
Lena FischerEMOVE CruiserIn repair3d$140
Marcus TerrellNinebot Max G30New2h
Priya RamanApollo City ProQuoted1d$95
Dee OkaforKingSong S18Ready for pickup6d$210

Used on: Request Queue (screen 5), Job Detail (6), Weekly books (7).

9CSS tokens

Drop this into the global stylesheet. Every value in this document resolves to one of these tokens. The @import should become next/font/google with display:'swap' in the Next.js build; the fallback stacks stay as written so the site remains readable if the font request fails.

tokens.css
@import url('https://fonts.googleapis.com/css2?family=Archivo+Black&family=Space+Grotesk:[email protected]&display=swap');

:root {
  /* ---- Color: carried over from the Squarespace theme ---- */
  --color-ink:              #211F1F;  /* hsl(0 3.1% 12.5%)   text, dark sections */
  --color-paper:            #FFFFFF;  /* page background, card fill            */
  --color-line:             #DFDFDF;  /* hsl(0 0% 87.5%)     borders, rules     */
  --color-accent:           #591A1A;  /* hsl(0 54.8% 22.5%)  the one accent     */

  /* ---- Color: derived ---- */
  --color-ink-muted:        #5C5858;  /* secondary text on light  7.02:1        */
  --color-panel:            #F2F2F2;  /* neutral surface                        */
  --color-tint:             #F4E7E7;  /* warm panel (offset card, testimonials) */
  --color-tint-line:        #EBD9D9;  /* rules inside a tint panel              */
  --color-accent-hover:     #6E2020;
  --color-accent-active:    #470F0F;
  --color-accent-on-dark:   #D9A6A6;  /* accent substitute on ink  7.77:1       */
  --color-on-dark:          #FFFFFF;
  --color-on-dark-muted:    #B5AEAE;  /* secondary text on ink     7.52:1       */

  /* ---- Color: form semantics ---- */
  --color-success:          #14654A;
  --color-success-surface:  #E8F3EE;
  --color-error:            #A4231C;
  --color-error-surface:    #FDECEA;

  /* ---- Overlays ---- */
  --overlay-hero:   rgba(33,31,31,.55);  /* text over photography          */
  --overlay-image:  rgba(33,31,31,.28);  /* mood only, no text on top      */

  /* ---- Type ---- */
  --font-display: 'Archivo Black', 'Arial Black', 'Arial Bold', Gadget, sans-serif;
  --font-sans:    'Space Grotesk', ui-sans-serif, system-ui, -apple-system,
                  'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --fs-display: clamp(2.375rem, 1.05rem + 4.2vw, 4.25rem);  /* 38 -> 68 */
  --fs-h1:      clamp(2.125rem, 1.20rem + 2.9vw, 3.25rem);  /* 34 -> 52 */
  --fs-h2:      clamp(1.75rem,  1.22rem + 1.7vw, 2.5rem);   /* 28 -> 40 */
  --fs-h3:      clamp(1.25rem,  1.11rem + 0.4vw, 1.5rem);   /* 20 -> 24 */
  --fs-h4:      1.125rem;                                   /* 18       */
  --fs-stat:    clamp(2.5rem,   1.79rem + 2.2vw, 3.5rem);   /* 40 -> 56 */
  --fs-lead:    1.25rem;                                    /* 20       */
  --fs-body:    1.0625rem;                                  /* 17       */
  --fs-small:   0.875rem;                                   /* 14       */
  --fs-label:   0.8125rem;                                  /* 13       */
  --fs-input:   1rem;                                       /* 16, iOS  */

  --lh-display: 1.02;  --lh-heading: 1.08;  --lh-tight: 1.25;
  --lh-body:    1.65;  --lh-snug:    1.45;
  --ls-display: -0.02em;  --ls-label: 0.12em;
  --weight-label: 500;  --weight-field: 600;

  /* ---- Space: 8px base ---- */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;  --sp-5: 24px;
  --sp-6: 32px;  --sp-7: 48px;  --sp-8: 64px;  --sp-9: 96px;  --sp-10: 128px;

  --container:   1140px;
  --gutter:      24px;
  --section-y:   96px;
  --section-y-lg:128px;
  --grid-gap:    32px;
  --card-gap:    24px;
  --card-pad:    24px;

  /* ---- Surface ---- */
  --radius:        5px;
  --radius-pill:   999px;
  --shadow-offset: 73px 73px 78px -70px rgba(33,31,31,.24);  /* offset card only */
  --shadow-soft:   0 2px 4px rgba(33,31,31,.05),
                   0 12px 32px -12px rgba(33,31,31,.16);
  --focus-ring:      0 0 0 3px rgba(89,26,26,.30);
  --focus-ring-soft: 0 0 0 3px rgba(89,26,26,.18);   /* inputs           */
  --focus-ring-dark: 0 0 0 3px rgba(255,255,255,.55); /* on ink           */

  --dur: 180ms;
  --ease: cubic-bezier(.2,.7,.3,1);
}

@media (max-width: 768px) {
  :root {
    --gutter: 20px;  --section-y: 56px;  --section-y-lg: 72px;
    --grid-gap: 24px;  --card-gap: 16px;  --card-pad: 20px;
    --fs-body: 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root { --dur: 0ms; }
}

/* Admin: same tokens, denser. Apply to the admin layout root. */
[data-density="admin"] {
  --section-y: 24px;  --card-pad: 16px;  --card-gap: 16px;  --grid-gap: 24px;
  --fs-body: 0.9375rem;  /* 15 */
  --fs-small: 0.8125rem; /* 13 */
  --radius: 4px;
  --row-height: 40px;
  --control-height: 34px;
}

Deliberately absent: a dark mode, a second accent, an elevation scale beyond the two shadows, and any token for a color not listed in section 2. Adding one is a design decision, not an implementation detail.