Theme Groundwork
Blocks & themesPreviewGroundwork, a Tome theme for trades, home services and appointment-based local businesses: warm paper grounds, Zilla Slab display numerals, accent-as-punctuation, dark claims and estimate bands. Four palettes (Timber, Brick, Harbor, Field) plus dark, self-hosted OFL fonts, activated by data-tome-theme="groundwork".
Get a registry token from your credentials page. You need a purchase that includes this package, or a Craft Library membership.
Add the registry and your token to the
.npmrcat the root of your project, with your token in place ofYOUR_TOKEN:@wabbit:registry=https://npm.wabbit.com/ //npm.wabbit.com/:_authToken=YOUR_TOKENThen install:
npm install @wabbit/tome-theme-groundwork
Overview
@wabbit/tome-theme-groundwork
Groundwork is a Tome theme for trades, home services and appointment-based local businesses. Its stance is "the phone rings": every section moves a visitor one step closer to a call, a quote or a booking. It sets warm paper grounds, Zilla Slab display numerals, an accent used only as punctuation, and fixed dark claims, process and estimate bands. It ships four palettes (Timber, Brick, Harbor, Field), each in light and dark.
This package is a theme (a ThemeManifest of kind: 'theme'). It owns no blocks. It declares the whole token surface blocks read, self-hosts its two OFL font families, and restyles a handful of blocks and chrome through their public hooks.
Layer: ui · Family / tier: themes / addon · Versioning: independent.
Install
pnpm add @wabbit/tome-theme-groundwork| Peer | Range | Required | |---|---|---| | @wabbit/tome-ui | >=0.17.1 <1.0.0 | yes | | @wabbit/tome-core | >=1.21.1 <2.0.0 | no (optional) |
@wabbit/tome-ui is a CSS-contract peer. Its tokens.css re-declares the var()-aliased Layer 2 under [data-tome-theme] and defines the fixed-band ink family this theme sets, so Groundwork renders correctly on any element, not only <html>. @wabbit/tome-core is needed only for the ./register subpath and the ThemeManifest type. The package imports no React and no Payload.
Usage
Import the stylesheet once at the app root, after tome-ui's tokens, and activate the theme on <html>:
// app/layout.tsx
import '@wabbit/tome-ui/tokens.css'
import '@wabbit/tome-theme-groundwork/styles.css'
import '@wabbit/tome-theme-groundwork/fonts.css'<html data-tome-theme="groundwork"> <!-- Timber, light -->
<html data-tome-theme="groundwork" data-tome-palette="harbor"> <!-- Harbor -->
<html data-tome-theme="groundwork" data-tome-palette="field" data-theme="dark">With no data-tome-palette the theme renders Timber. data-theme="dark" gives a full dark page; that is allowed but not the default. The claims, process and estimate bands are dark in both modes.
To have the admin ThemeSwitcher, createThemeConfig() and other registry readers list it, register it on the server before building the Payload config:
import '@wabbit/tome-theme-groundwork/register'Header: set navTheme: 'light'
Groundwork's hero is a light ground, so it expects the tome-chrome Header global's `navTheme` set to `'light'` (with the recommended Navbar 7, design version '7'). tome-chrome then draws dark ink and the main logo over the transparent, at-rest header, uses logoDark only on dark backgrounds, and writes data-nav-theme="light" on the header frame. The theme forces no header ink. Left on auto, Navbar 7 assumes a dark hero and draws light ink and logoDark over Groundwork's light hero.
The mockup's header has two phone actions. Both are Header global settings (tome-chrome with the v1.1 header batch):
- The Call button on phones: turn on
headerCall(enabled, withphone; without one it falls back tomobileActionBar.phone). Groundwork draws it as a compact primary-ink pill beside the hamburger. Chrome hides it from the navbar's desktop breakpoint up. - The phone number beside the estimate button: add it as a header CTA with
link.appearance: 'inline'. Groundwork sets it as plain semibold text in tabular figures, with the nav links' accent underline on hover.
Footer: use footer 7 with backgroundColor: 'muted'
The mockup's footer sits on the muted surface. tome-chrome paints the Footer global's backgroundColor inline, so set it to `'muted'` (with design version '7'). Chrome resolves 'muted' to the declared --tome-color-surface-muted ground and --tome-color-on-surface-muted ink. This needs tome-chrome with the v1.1 footer fix: earlier versions pointed 'muted' at undeclared names, which Groundwork 0.1 worked around. The muted ink suits the bottom bar, the subline and the column titles. Groundwork sets the brand-and-links row ([data-footer-top]) and the link lists in the full --tome-color-foreground ink, as the mockup does. Left unset, the footer is transparent over the page ground.
Scroll reveal
Groundwork's motion has one reveal: a small rise and fade, played once per block and staggered. It uses tome-ui's opt-in platform scroll reveal (@wabbit/tome-ui/reveal). The theme declares --tome-reveal: on and maps the reveal's timing to its own values: --tome-reveal-rise 12px, --tome-reveal-duration 480ms (--tome-motion-slow), --tome-reveal-stagger 80ms, and --tome-reveal-ease the theme's ease-out. The reveal runs only where the site mounts the controller once in its root layout:
import { TomeReveal } from '@wabbit/tome-ui/reveal'
// inside <body>, once
<TomeReveal />Without the controller, or with a tome-ui that predates the reveal, nothing moves and nothing is hidden. Blocks that animate themselves (the process rail, the dossier and campaign islands) are skipped by the controller. data-tome-reveal="off" on <html>, a region or a block root turns it off there, and overrides the theme.
Fonts
Zilla Slab (500, 600, 700) and Hanken Grotesk (400, 500, 600, 700) ship inside the package as latin-subset woff2, with their SIL OFL 1.1 licences (fonts/OFL-ZillaSlab.md, fonts/OFL-HankenGrotesk.md). There is no third-party font request. Pick one delivery path:
import '@wabbit/tome-theme-groundwork/fonts.css': the bundler resolves the files from this package.- Your own host: copy the files from
@wabbit/tome-theme-groundwork/fonts/*and injectgetGroundworkFontStyles({ src }). next/font/local, using the file list fromgetGroundworkFontFaces().
import { getGroundworkFontPreloads } from '@wabbit/tome-theme-groundwork/fonts'
// in <head>: preload the 600 display and 400 body faces
{getGroundworkFontPreloads({ src: '/fonts/groundwork/' }).map((l) => <link key={l.href} {...l} />)}Every --font-* slot is declared with its paired --tome-type-* alias on the theme selector (amendment A4.1), so the theme's fonts reach blocks even where a site sets its own --tome-type-* at :root.
The measuring-grid effect
There is one opt-in effect: a static, radially masked measuring-grid line field on the estimate band. It is off by default. Turn it on for the estimate band from <html>, or put it on any one element:
<html data-tome-theme="groundwork" data-groundwork-effect="measuring-grid">
<section data-groundwork-effect="measuring-grid">…</section>Sites can also make their own section a fixed dark band with data-groundwork-band="dark", or mark a meta line (dates, licence numbers) with data-groundwork-meta.
Public API
| Export | Subpath | Purpose | |---|---|---| | groundworkThemeManifest (ThemeManifest) | ., ./manifest | The theme's manifest: name groundwork, kind: 'theme', tier addon, four palettes, fonts and one pairing, recommended blocks and chrome (Navbar 7, footer 7), styledBlocks, requires.tomeUi. | | GROUNDWORK_PALETTE_IDS, GroundworkPaletteId | ., ./manifest | ['timber', 'brick', 'harbor', 'field'], the data-tome-palette values. | | GROUNDWORK_STYLED_BLOCKS, GROUNDWORK_RECOMMENDED_BLOCKS | ., ./manifest | The block slugs the theme restyles, and the slugs its demo is composed from. | | ThemeManifest (type) | . | Re-exported from @wabbit/tome-core/registry/theme. | | getGroundworkFontFaces(), getGroundworkFontStyles({ src }), getGroundworkFontPreloads({ src }) | ., ./fonts | Font descriptors, @font-face CSS for a custom host, and preload links. | | GROUNDWORK_FONT_STACKS, GROUNDWORK_FONT_LICENSES, GROUNDWORK_LATIN_UNICODE_RANGE | ., ./fonts | The CSS stacks the tokens use, the licence file per family, and the subset range. | | side effect | ./register | Registers groundworkThemeManifest in tome-core's theme registry. | | stylesheet | ./styles.css | Tokens, treatments and the effect. The file that does everything visual. | | stylesheet | ./fonts.css | The seven @font-face rules. Optional. | | font files | ./fonts/* | The woff2 files and their OFL licences, for self-hosting. |
import { groundworkThemeManifest } from '@wabbit/tome-theme-groundwork/manifest'
groundworkThemeManifest.palettes.map((p) => p.label)
// ['Timber', 'Brick', 'Harbor', 'Field']Tokens
The theme sets Layer 1 (the shadcn names tome-ui's tokens.css reads: --background, --foreground, --card, --primary, --accent, --muted, --border, --input, --ring, the feedback, chart and muted2 names) and lets tome-ui's generated re-resolution derive the aliased Layer 2. It sets these Layer-2 literals directly, because no Layer-1 input sits behind them:
--tome-color-accent-textand the feedback*-textweights- the fixed-band inks:
--tome-color-surface-solid-dark,--tome-color-on-solid-dark,--tome-color-on-solid-dark-muted,--tome-color-accent-on-solid-dark,--tome-color-primary-on-solid-dark,--tome-color-border-inverse, and the light fixed surface--tome-color-surface-inversewith--tome-color-on-inverse,--tome-color-on-inverse-muted,--tome-color-accent-on-inverse,--tome-color-primary-on-inverse - the four
--tome-type-*families, each paired with its--font-*slot
The dark band is each palette's inverse column. The light fixed surface is the palette's card.
Selector ladder (specificity, never load order):
| Selector | Specificity | Holds | |---|---|---| | [data-tome-theme="groundwork"] | 0,1,0 | Timber light, type, radius, rhythm, motion | | [data-tome-theme="groundwork"][data-theme="dark"] | 0,2,0 | Timber dark | | [data-tome-theme="groundwork"][data-tome-palette="p"] | 0,2,0 | palette light | | [data-tome-theme="groundwork"][data-tome-palette="p"][data-theme="dark"] | 0,3,0 | palette dark |
Every palette rule, light and dark, declares the full set: Layer 1, the *-text literals, the band inks and the private --groundwork-accent-halo. The bare rule ties tome-ui's :root at 0,1,0, so import this stylesheet after tome-ui's tokens, the same convention every theme follows. Private tokens use the --groundwork-* prefix: the accent halo, display tracking, numeral sizes, band rhythm, punctuation geometry, the reveal timing (which the theme maps onto tome-ui's --tome-reveal-* tokens), the day time table's columns, elevation and the measuring-grid opacity.
Shape and rhythm. Radius is sm 6px, md 10px, lg 22px and full 999px. The estimate card is the roundest object on the page, and full-bleed bands are square. tome-ui sets the root at 18px, so the mockups' 16px-root sizes are converted by 16/18. The body is 1rem here, which is the brief's 18px.
Contrast
All ratios are WCAG 2.x. Body and small text must reach at least 4.5. Input outlines and non-text accent marks must reach at least 3.
| Pair | Timber | Brick | Harbor | Field | |---|---|---|---|---| | body on ground / card | 15.25 / 16.34 | 13.52 / 14.60 | 14.34 / 15.42 | 13.61 / 14.79 | | muted on ground / card | 6.67 / 7.15 | 6.51 / 7.03 | 6.21 / 6.68 | 6.42 / 6.97 | | accent-text on ground / card | 5.43 / 5.82 | 5.21 / 5.62 | 14.34 / 15.42 | 5.67 / 6.17 | | input outline on card | 3.92 | 3.97 | 3.83 | 3.68 | | accent mark on ground | 3.32 | 5.21 | 1.49, ringed in navy | 3.64 | | focus ring on ground | 5.43 | 5.21 | 14.34 | 5.67 | | band ink / muted / accent on dark band | 15.25 / 8.32 / 4.59 | 13.52 / 7.55 / 4.69 | 14.34 / 7.96 / 9.64 | 13.61 / 7.85 / 7.90 | | estimate card input outline | 4.36 | 3.96 | 4.11 | 3.99 | | dark mode: body on card, muted on card, accent-text on card | 13.73, 7.49, 6.18 | 11.97, 6.68, 5.55 | 12.81, 7.11, 8.61 | 12.02, 6.94, 7.59 | | dark mode: input on card | 3.90 | 3.77 | 4.35 | 4.17 |
Harbor's signal yellow is under 3:1 on its pale grounds. It never carries text there (Harbor's accent-text is the navy ink), and every yellow dot on a light ground carries a navy ring (--groundwork-accent-halo). Field was derived for this package: pale sage #EEF1E7, deep forest #14281C, leaf green #3C8D35, with accent-text #2C6B27.
What it styles
The accent rule applies throughout. The accent marks things (rules, ticks, dots, list markers, underlines, hover) and never fills them. Actions are primary-ink pills that answer hover with an accent underline.
| Hook | Treatment | |---|---| | proposal-stat-strip | The dark claims band ([data-stat-list], [data-stat], [data-stat-label], [data-stat-value], [data-stat-caption], [data-stat-header]): fixed dark ground, an accent rule over each claim, the claim label in the meta voice above a display-type numeral at 600 (the *accent* span read as a muted unit), and the section-header label in the meta voice. | | dated-ledger (columns, rows) | The light Job Log: the section heading at the mockup's 3xl step in display type, and a 600px intro (through the dossier --tome-dossier-heading-size and --tome-house-heading-* tokens, shared with the process band); every dossier section kicker ([data-lane-kicker]) as a 28px accent tick and an accent-text label in the meta voice, display day numerals (via --tome-dossier-ledger-day-size), meta-voice month and job number, a pill neighbourhood chip with an accent dot, a result line hanging off an accent rule, title underline on hover, and an accent-ruled "Read all". | | high-impact-hero quick-ask | Hero headline at the hero size, a 52px pill select (or [role=combobox] trigger) with a 3:1 outline, pill submit and call actions (the call's desktop visibility stays the block's, data-hero-call-desktop), the Next Opening proof line, medium-radius media and a meta-voice caption. In the proof line, the status dot stays in the block's no-wrap [data-hero-proof-start] run with the mockup's gap after it, and the bold lead-in ([data-hero-proof-lead], "Next opening:") reads in the page ink. | | contact estimate | The dark estimate band: the eyebrow ([data-contact-eyebrow]) as the section label, a 28px accent tick then the meta voice in the band's muted ink; the big response-promise numeral under an accent rule, a ghost call pill, tabular hours, area chips, and the form card. The card is a fixed light surface at radius-lg with an accent tab and a display-type heading ([data-contact-card-heading]) over a hairline. With a form note, the hairline runs under the head row ([data-contact-card-head]), and the note ([data-contact-form-note]) sits beside the heading in the meta voice. The card stays light in dark mode. In the [data-form-id] slot, inputs, selects, textareas and [role=combobox] triggers take the field style, and only the submit (button[type=submit], input[type=submit]) is a pill. A composite phone control (a country picker beside a tel input) is one field: the outer control takes the field style and focus ring, and the inner picker and input are borderless. | | phase-ledger rail | The dark process band, with rail track and fill set through --tome-dossier-rail-track / --tome-dossier-rail-fill and the step numbers ([data-phase-num]) in display type. Step dots are hollow until active, then accent. Each step's outcome line ([data-phase-outcome]) is the mockup's step time: upright and semibold through --tome-dossier-phase-outcome-style / -weight, in the meta voice and the band ink. | | info-panel next-step card | [data-panel-card]: a light card at radius-lg with an accent tab, and its label ([data-panel-kicker], "Your next step", and any key-facts label) in the meta voice and the text-safe accent; the foreman ([data-panel-person]) with a 48px initials badge ([data-panel-person-initials]), display-type name and muted role; the [data-panel-media] job thumbnail under a hairline; a full-width primary pill ([data-panel-cta]) and the status dot. The block's own prose spacing and list markers are left alone. | | editorialSpread margin facts | A heavy ink rule opens the facts, a hairline closes each fact, and notes are in the muted body voice. | | editorialSpread day time table | An ordered list in the main column whose items open with a bold time (<li><strong>7:00</strong> Crew arrives…</li>) is set as the mockup's ruled time table: the time hangs in a display-type column with tabular figures, a hairline runs between rows, and the list numbers are hidden. Rich text has no hooks, so the list is recognised by that shape. Ordinary ordered lists, and lists outside editorialSpread, are untouched. Put the time first, in bold, with nothing before it. | | Chrome header ([data-nav-theme="light"]) | An accent underline on link hover and semibold CTAs. The at-rest ink and logo come from chrome's navTheme: 'light'. An inline CTA (a[data-appearance="inline"]) stays plain text in tabular figures, with the links' accent hover. The Call button ([data-header-call]) is a compact primary-ink pill with an accent-underline hover, set through --tome-header-call-*. | | Chrome footers ([data-footer-variant="7"], [data-footer-variant="11"]) | Footer 7 on the muted surface (with backgroundColor: 'muted'), at the mockup's slimmer padding (--tome-footer-pad-block), with the brand top-aligned ([data-footer-top]) beside up to four link columns on one row from 1024px (--tome-footer-nav-cols: 4, a narrower [data-footer-nav] gap). The brand and links read in the foreground ink, the bottom bar in chrome's muted ink. Column titles are small muted meta labels; tabular figures and accent hover throughout. Footer 11 reads the band inks. | | Chrome mobile action bar | Its published --tome-mobile-action-bar-* tokens: card bar, primary-ink CTA, 52px actions. |
Treatments target only public hooks: data-block-type on the block wrapper, data-block-variant on the root, the blocks' documented data-* part attributes, and published component tokens. They never target hashed class names or structural chains such as > div:last-child. data-block-type is matched in its catalog form (high-impact-hero, not the stored highImpactHero), and a test fails any other form.
Server / client posture
The package is pure CSS plus constants. It has no React components and no 'use client' files, so it is inert under React Server Components. It adds nothing to a client bundle beyond the stylesheets the consumer imports. ./register is a server-side import.
Tests
pnpm --filter @wabbit/tome-theme-groundwork testThe vitest suites cover:
- the theme conformance check in theme mode (Layer-1 surface,
*-textliterals, radius and font slots, the full dark redeclaration, palette coverage, scoping, no module class names, font pairing) and in platform mode - manifest validation, its agreement with
package.json, and registration - every palette defining the full required set in both modes
- the A4.1 font pairing, and the self-hosted faces with their licences
- no colour literal outside
src/tokens/, no comment that swallows a rule, no structural selector (the time table'sstrong:first-childcontent test is the one named exception), and every treatment rule scoped to the theme - the v1.1 platform hooks: the reveal switch and timing, no colour-name rebinding in the footer, the new part hooks, the phase outcome through its tokens, and the time table's scope
Exports
@wabbit/tome-theme-groundwork@wabbit/tome-theme-groundwork/manifest@wabbit/tome-theme-groundwork/register@wabbit/tome-theme-groundwork/fonts@wabbit/tome-theme-groundwork/styles.css@wabbit/tome-theme-groundwork/fonts.css@wabbit/tome-theme-groundwork/fonts/*
Changelog
5a84171: Groundwork's band padding now matches the mockups between the clamp ends: the default band is 115px at 1440 (it was 102px). The conversion from the mockups' 16px root to the 18px root scaled the viewport (`vw`) terms of the band clamps too, though a `vw` term does not depend on the root. They are the mockups' own values again; the rem ends, which were converted correctly, are unchanged: `--tome-section-py` `clamp(3.556rem, 8vw, 6.667rem)` (was 7.1vw), `--tome-section-py-sm` and `--groundwork-hero-py` `clamp(1.778rem, 5vw, 4rem)` (were 4.4vw), and `--groundwork-band-py` `clamp(2.667rem, 6vw, 4.444rem)` (was 5.3vw). The type clamps already kept the mockups' `vw` terms.
- 5a84171: Groundwork's band padding now matches the mockups between the clamp ends: the default band is 115px at 1440 (it was 102px). The conversion from the mockups' 16px root to the 18px root scaled the viewport (`vw`) terms of the band clamps too, though a `vw` term does not depend on the root. They are the mockups' own values again; the rem ends, which were converted correctly, are unchanged: `--tome-section-py` `clamp(3.556rem, 8vw, 6.667rem)` (was 7.1vw), `--tome-section-py-sm` and `--groundwork-hero-py` `clamp(1.778rem, 5vw, 4rem)` (were 4.4vw), and `--groundwork-band-py` `clamp(2.667rem, 6vw, 4.444rem)` (was 5.3vw). The type clamps already kept the mockups' `vw` terms.
- e8213a7: The next-step card's "Get my estimate" pill is 52px tall, as in the mockup. Now that the link carries its `data-panel-cta` hook, the theme's pill reaches it, and the block's own vertical padding made it 54px; the theme sets that padding to 0.
b877681: Groundwork now uses the v1.1 platform hooks in place of its workarounds. - **Scroll reveal.** The theme turns on tome-ui's opt-in platform scroll reveal (`--tome-reveal: on`) and maps `--tome-reveal-rise`, `-duration` and `-stagger` to its `--groundwork-reveal-*` values, and `--tome-reveal-ease` to `--tome-motion-ease-out`. It runs only where the site mounts `<TomeReveal />` from `@wabbit/tome-ui/reveal`. Before this, the theme declared reveal tokens that nothing read. - **Footer 7.** The `--tome-color-muted*` rebinding is gone, now that tome-chrome maps `backgroundColor: 'muted'` to the declared `surface-muted` / `on-surface-muted` pair. The brand-and-links row (`[data-footer-top]`, which replaces the `:has(> [data-footer-nav])` selector) and the link lists take `--tome-color-foreground`, as in the mockup. The bottom bar keeps chrome's muted ink. Sites on a tome-chrome without the footer fix get a transparent footer. - **Header.** The phone-width Call button (`[data-header-call]`) is a compact primary-ink pill with an accent-underline hover, set through `--tome-header-call-*`. An inline CTA (`link.appearance: 'inline'`, for a phone number) stays plain text in tabular figures, with the nav links' accent hover, and is no longer given the pill radius. - **Hero.** The proof line's bold lead-in (`[data-hero-proof-lead]`) reads in the page ink, and the status dot keeps the mockup's gap inside the block's no-wrap `[data-hero-proof-start]` run. - **Estimate.** The eyebrow (`[data-contact-eyebrow]`) is the section label: an accent tick, then the meta voice. With a form note, the card's hairline runs under the head row (`[data-contact-card-head]`), and the note (`[data-contact-form-note]`) is set in the meta voice. - **Process.** Each step's outcome line (`[data-phase-outcome]`) reads as the mockup's step time: upright and semibold through `--tome-dossier-phase-outcome-style` / `-weight`, in the meta voice and the band ink. - **Next-step card.** The card label (`[data-panel-kicker]`) is in the meta voice and the text-safe accent. - **Day time table.** In an `editorialSpread`, an ordered list whose items open with a bold time is set as a ruled time table: a display-type time column with tabular figures, hairlines between rows, and no list numbers. Other ordered lists are untouched.
- b877681: Groundwork now uses the v1.1 platform hooks in place of its workarounds. - **Scroll reveal.** The theme turns on tome-ui's opt-in platform scroll reveal (`--tome-reveal: on`) and maps `--tome-reveal-rise`, `-duration` and `-stagger` to its `--groundwork-reveal-*` values, and `--tome-reveal-ease` to `--tome-motion-ease-out`. It runs only where the site mounts `<TomeReveal />` from `@wabbit/tome-ui/reveal`. Before this, the theme declared reveal tokens that nothing read. - **Footer 7.** The `--tome-color-muted*` rebinding is gone, now that tome-chrome maps `backgroundColor: 'muted'` to the declared `surface-muted` / `on-surface-muted` pair. The brand-and-links row (`[data-footer-top]`, which replaces the `:has(> [data-footer-nav])` selector) and the link lists take `--tome-color-foreground`, as in the mockup. The bottom bar keeps chrome's muted ink. Sites on a tome-chrome without the footer fix get a transparent footer. - **Header.** The phone-width Call button (`[data-header-call]`) is a compact primary-ink pill with an accent-underline hover, set through `--tome-header-call-*`. An inline CTA (`link.appearance: 'inline'`, for a phone number) stays plain text in tabular figures, with the nav links' accent hover, and is no longer given the pill radius. - **Hero.** The proof line's bold lead-in (`[data-hero-proof-lead]`) reads in the page ink, and the status dot keeps the mockup's gap inside the block's no-wrap `[data-hero-proof-start]` run. - **Estimate.** The eyebrow (`[data-contact-eyebrow]`) is the section label: an accent tick, then the meta voice. With a form note, the card's hairline runs under the head row (`[data-contact-card-head]`), and the note (`[data-contact-form-note]`) is set in the meta voice. - **Process.** Each step's outcome line (`[data-phase-outcome]`) reads as the mockup's step time: upright and semibold through `--tome-dossier-phase-outcome-style` / `-weight`, in the meta voice and the band ink. - **Next-step card.** The card label (`[data-panel-kicker]`) is in the meta voice and the text-safe accent. - **Day time table.** In an `editorialSpread`, an ordered list whose items open with a bold time is set as a ruled time table: a display-type time column with tabular figures, hairlines between rows, and no list numbers. Other ordered lists are untouched.
b659c3d: Footers now run the full site width on the same edges as the header and page grid. The theme sets chrome's shared container contract (`--tome-chrome-content-max: 100%`, `--tome-chrome-content-inline: clamp(1rem, 4vw, 3rem)`) instead of leaving footers in their default 1200px box.
- b659c3d: Footers now run the full site width on the same edges as the header and page grid. The theme sets chrome's shared container contract (`--tome-chrome-content-max: 100%`, `--tome-chrome-content-inline: clamp(1rem, 4vw, 3rem)`) instead of leaving footers in their default 1200px box.
cbd2d32: New theme: Groundwork, for trades, home services and appointment-based local businesses, activated with `data-tome-theme="groundwork"`. - Four palettes (Timber, the default; Brick; Harbor; Field), each in light and dark, selected with `data-tome-palette`. Every palette sets Layer 1, the `*-text` literals and the fixed-band ink family, contrast-checked (body at least 4.5:1, input outlines and accent marks at least 3:1; Harbor's yellow carries a navy ring on light grounds). - Self-hosted OFL fonts: Zilla Slab (500, 600, 700) and Hanken Grotesk (400 to 700), latin-subset woff2 with their licences, via `./fonts.css`, the `./fonts` descriptors or `./fonts/*` for your own host. Each `--font-*` slot is paired with its `--tome-type-*` alias. - Treatments through public hooks only: the dark claims band (`proposal-stat-strip`), the Job Log (`dated-ledger`), the `quick-ask` hero, the `estimate` contact band and its form card, the `rail` process band, the margin facts, the `info-panel` next-step card, Navbar 7, footers 7 and 11, and the mobile action bar. The accent is used only as punctuation. - One opt-in effect: a measuring-grid texture on the estimate band (`data-groundwork-effect="measuring-grid"`). - `./register` adds the theme to tome-core's theme registry. Requires `@wabbit/tome-ui` 0.17.1 or later; `@wabbit/tome-core` is an optional peer.
- cbd2d32: New theme: Groundwork, for trades, home services and appointment-based local businesses, activated with `data-tome-theme="groundwork"`. - Four palettes (Timber, the default; Brick; Harbor; Field), each in light and dark, selected with `data-tome-palette`. Every palette sets Layer 1, the `*-text` literals and the fixed-band ink family, contrast-checked (body at least 4.5:1, input outlines and accent marks at least 3:1; Harbor's yellow carries a navy ring on light grounds). - Self-hosted OFL fonts: Zilla Slab (500, 600, 700) and Hanken Grotesk (400 to 700), latin-subset woff2 with their licences, via `./fonts.css`, the `./fonts` descriptors or `./fonts/*` for your own host. Each `--font-*` slot is paired with its `--tome-type-*` alias. - Treatments through public hooks only: the dark claims band (`proposal-stat-strip`), the Job Log (`dated-ledger`), the `quick-ask` hero, the `estimate` contact band and its form card, the `rail` process band, the margin facts, the `info-panel` next-step card, Navbar 7, footers 7 and 11, and the mobile action bar. The accent is used only as punctuation. - One opt-in effect: a measuring-grid texture on the estimate band (`data-groundwork-effect="measuring-grid"`). - `./register` adds the theme to tome-core's theme registry. Requires `@wabbit/tome-ui` 0.17.1 or later; `@wabbit/tome-core` is an optional peer.