Blocks Dossier Pack
Blocks & ThemesCase-file, evidence, and ledger register blocks for proof-heavy sections — dossier grids, spec sheets, exhibit cards, and record ledgers, built on the house field/motion/style primitives.
npm install @wabbit/tome-blocks-dossier-packOverview
@wabbit/tome-blocks-dossier-pack
The case-file / evidence / ledger register of wabbit.com's site-local blocks, promoted into a sellable Tome block pack (family: block-packs, tier: addon). Program B, wave 1 of the Tome Blocks — Storefront Expansion and House Packs spec (2026-09-05).
The pack ships 24 blocks under one bundle descriptor (dossier-pack), built on @wabbit/tome-blocks-core (block/registry/render contracts) and @wabbit/tome-blocks-house (shared field/motion/style primitives ported from wabbit-site-core — see that package's PORT-NOTES.md).
Blocks
| Slug | Name | Variants | |---|---|---| | case-file-grid | Case File Grid | default, field-manual, filmstrip | | case-file-row | Case File Row | — | | evidence-sheet | Evidence Sheet | — | | evidence-plate | Evidence Plate | — | | exhibit-artifact | Exhibit Artifact | — | | proof-plates | Proof Plates | — | | receipts-trio | Receipts Trio | — | | record-roster | Record Roster | — | | spec-sheet | Spec Sheet | — | | spec-plate | Spec Plate | — | | ledger | Ledger | default, compact | | compare-ledger | Compare Ledger | — | | comparison-table | Comparison Table | — | | cost-ledger | Cost Ledger | — | | grants-ledger | Grants Ledger | default, compact | | phase-ledger | Phase Ledger | — | | term-ledger | Term Ledger | shifts, spec | | shift-rows | Shift Rows | default, compact | | wall-rows | Wall Rows | — | | fit-list | Fit List | default, compact | | fit-prose | Fit Prose | — | | lab-notes | Lab Notes | — | | practice-modes | Practice Modes | — | | zone-directory | Zone Directory | — |
Some blocks expose a design choice as a field rather than a registered variant — evidence-sheet's four treatments (table, grid, strip, ledger) and proof-plates' Strip or Situational shell are authored per block instance.
Install into an existing Payload project
npm install @wabbit/tome-blocks-dossier-pack@wabbit/tome-blocks-core and @wabbit/tome-blocks-house are required peers and install automatically (npm 7+/pnpm). Add the blocks you want to an existing blocks field and render them — see @wabbit/tome-blocks-core's "Add Tome blocks to an existing Payload project" for the full walkthrough:
// payload.config.ts
import { ledgerBlock, caseFileGridBlock } from '@wabbit/tome-blocks-dossier-pack'
// blocks: [...existingBlocks, ledgerBlock.block(), caseFileGridBlock.block()]// blockComponents.ts
import { renderers as dossierRenderers } from '@wabbit/tome-blocks-dossier-pack/render/register'
import { adaptRenderersForPayload } from '@wabbit/tome-blocks-core/render'
// blockComponents: { ...adaptRenderersForPayload(dossierRenderers) }@import '@wabbit/tome-blocks-core/styles.css';Registering everything from scratch instead of adding to an existing field:
// payload.config.ts
import { BlockRegistry, BundleRegistry } from '@wabbit/tome-blocks-core/registry'
import { register } from '@wabbit/tome-blocks-dossier-pack'
const blockRegistry = new BlockRegistry()
const bundleRegistry = new BundleRegistry()
register(blockRegistry, bundleRegistry)import { registerRenderers } from '@wabbit/tome-blocks-dossier-pack/render/register'
registerRenderers()| Peer | Range | Required | |---|---|---| | payload | >=3.67.0 | yes | | @payloadcms/richtext-lexical | >=3.67.0 | yes | | react | >=19.0.0 | yes | | react-dom | >=19.0.0 | yes | | @wabbit/tome-blocks-core | >=0.18.0 <1.0.0 | yes | | @wabbit/tome-blocks-house | >=0.3.0 <1.0.0 | yes |
gsap is not a peer of this package at all — it is a real dependency of @wabbit/tome-blocks-house (a required peer above, backing this pack's entrance and ink-fill motion) and installs automatically with it.
Public API
| Export | Subpath | Description | |---|---|---| | One xBlock descriptor per block + register(blockRegistry, bundleRegistry) | . | Payload block configs and bundle registration | | Render components (Ledger, CompareLedger, ComparisonTable, TermLedger, CostLedger, GrantsLedger, ShiftRows, FitList, …) | ./render | Legacy self-registering render barrel | | renderers map + registerRenderers() | ./render/register | Explicit renderer registration | | getDemoProps(blockSlug, variant, ctx?) plus per-block demo functions | ./demo | Demo-props dispatcher feeding the auto-gallery route | | dossierPackBlockMeta | ./meta | Payload-free block metadata for a storefront gallery |
Server / client posture
Five files under src/render/ carry 'use client': four motion islands (CaseFileRowMotion, EvidencePlateMotion, ReceiptsTrioMotion, RecordRosterMotion, each *.client.tsx) plus ProofPlates.tsx. Every other renderer is a static server component, so blocks render from a server tree and hydrate only their motion.
Tokens and motion
Consumes @wabbit/tome-ui tokens exclusively, via @wabbit/tome-blocks-house's reduced field/background vocabulary — no literal hex/hsl/px in any render CSS Module, no hardcoded font-family. Every render component is self-contained and width-agnostic, per the house-pack convention in blocks-house/PORT-NOTES.md. case-file-row, evidence-plate, proof-plates, receipts-trio, and record-roster carry entrance-reveal motion (and, for evidence-plate, a sequential ink-fill pull statement) via @wabbit/tome-blocks-house/motion's animateInView/inkIn/readMotionTokens. Reduced motion is honored with a direct prefers-reduced-motion check, so this pack has no dependency on @wabbit/tome-motion.
Blocks
case-file-grid
A scan strip of case-file/proof tiles — a mono case number, an italic-serif proof numeral (a stat, a result, a status), a one-line brief, and a subject name, with an optional arrow CTA per tile. Three variants (default, field-manual, filmstrip) cover a receipts-band register, a tighter architecture-document register, and an edge-to-edge photographic filmstrip. An optional gold CTA panel can close the row as its final tile.
- A "receipts" or "proof" section presenting several short case results side by side
- A portfolio strip where each entry needs a headline stat plus a one-line context brief
- A closing row that should end on a call-to-action tile rather than a plain link
- landing
- about
- marketing
- portfolio
Author 2-5 tiles: a case number, a proof value, an optional brief, and a subject. Toggle Tile Images on to add a header image per tile — untouched tiles render a bracketed placeholder. Pick a Variant: default (receipts band), field-manual (tighter document register), or filmstrip (full-bleed photographic strip, requires Tile Images on). Set a CTA Panel heading to close the row with a call-to-action tile instead of a plain link.
- evidence-sheet
- exhibit-artifact
- proof-plates
- You need a single full-bleed case study, not a row of short ones — use exhibit-artifact instead
- The entries carry no comparable numeral/stat — use a plain card grid instead
marketing-landing
case-file-row
A single dark band opening with a lane kicker beside a headline, then a bordered row of up to 6 stat cells — each a kicker, a stat, a supporting line, and an optional name + plain link — closing on an anchored see-all link. One cell can be flagged to invert to a light card, useful for calling out the one honest or unusual result in an otherwise uniform set.
- A receipts/results row that needs plain, unstyled outbound links rather than relationship-driven cards
- A "the record" band closing a case-study or evidence section
- A moment that wants exactly one result visually set apart from its peers
- landing
- about
- marketing
- editorial-article
Write a kicker and heading (wrap a phrase in *asterisks* for an accent run). Add up to 6 cells: kicker, stat, line, name, and an optional plain href + link label. Flag exactly one cell to invert it to a light card. Close with a see-all label + URL.
- case-file-grid
- evidence-sheet
- receipts-trio
- Each entry needs a real relationship-driven link with a resolved reference — use case-file-grid or proof-plates instead
- You need more than 6 entries — split into multiple rows or use case-file-grid
marketing-landing
evidence-sheet
A dossier masthead: mono kicker strip, then a set of spec rows (a mono label + a value, with an optional muted note and an emphasis treatment for the standout row), plus two optional chip rows — Scope (outlined pills) and Stack (filled pills). Four treatments reflow the same data: Table (label-left/value-right), Grid (a 3-column cell grid), Strip (one compact hairline row), and Ledger (a tall narrow column, optionally paired with a short Opening Narrative beside it).
- A project/engagement masthead summarizing client, scope, timeline, result
- A compact spec sheet before or after a case study
- A verticalized "at a glance" ledger paired with a short narrative opener
- landing
- about
- marketing
- dossier
Fill in Spec Rows (label + value, optional note, optional emphasis). Add Scope/Stack chips as needed. Pick a Treatment: Table for the default wide spread, Grid for a 3-column reflow, Strip for one compact glance row, or Ledger for a tall narrow column — Ledger unlocks the optional Opening Narrative field group beside it.
- case-file-grid
- exhibit-artifact
- proof-plates
- You need a single narrative paragraph with no label/value structure — use a plain content block
marketing-landing
evidence-plate
An evidence moment: an eyebrow, up to 3 stats (two large serif numerals plus an optional smaller, muted "source" cell), a body paragraph, optional linked source citations, and a closing pull statement whose two runs ink-fill in sequence on scroll.
- A data-backed argument that needs real, citable numbers
- A moment that wants to land a two-part statement with a visual ink-fill reveal
- landing
- about
- marketing
- editorial-article
Add up to 3 stats (numeral + value + label; flag the source cell as Muted). Write a body paragraph and, if citing external data, add Sources (label + URL — each renders as a real link). Fill the Ink-in pull with two runs: the first inks in the body ink color, the second in the accent color.
- case-file-row
- evidence-sheet
- proof-plates
- The numbers are not real/citable — use a plain statement block instead
marketing-landing
exhibit-artifact
A single exhibited document — the "here is the actual artifact" answer to a case study or study section that has no photograph to show. A tag chip labels the exhibit; the inner card carries header rows (e.g. From/To/Re), a subject line, a rich-text body, and a signature; a centered caption sits below.
- A case study with no real photograph to show, but a real communication/document to reproduce
- A moment that benefits from a letter, memo, or transcript-style artifact
- dossier
- about
- landing
Set a Tag (the chip label). Add Header Lines (label/value rows), a Subject Line, a rich-text Body, and a Signature. Add a Caption to describe the artifact below it, and an optional CTA link.
- evidence-sheet
- case-file-grid
- proof-plates
- A real photograph exists for this moment — use a media block instead
marketing-landing
proof-plates
A "what it runs on" or "here is the proof" section: a kick label + heading + intro, then 2-4 proof plates, each with a kicker, title, body, an optional stats line, an optional inline continuation link, and an optional proof-capture image. One plate can be flagged to render as an inverted, emphasized card. Two shells are available: Strip (one joined bordered row) or Situational (separate floating cards with their own border/shadow) — Auto derives the shell from whether any plate carries a kicker.
- Comparing 2-4 concrete deployments, tiers, or outcomes side by side
- A chooser section where each option needs its own floating card
- A closing proof row that wants one option visually flagged as the default/flagship
- landing
- pricing
- marketing
Write a kick label, heading (wrap a phrase in *accent*), and intro. Add 2-4 plates: kicker, title, body (supports **bold** and *em* runs), an optional stats line, and an optional inline link. Flag one plate for emphasis. Choose a Shell, or leave Auto to let the kicker-presence heuristic decide. Add a proof-capture image per plate where a real screenshot exists.
- evidence-sheet
- case-file-grid
- exhibit-artifact
- You have more than 4 comparable items — use a table or a card grid instead
marketing-landing
receipts-trio
A single dark band making the case for showing real results, not just wins: a kicker, a heading (with an optional accented run), a prose paragraph making the honesty argument, and up to 3 quote cards (quote + name + role) — deliberately built to hold an honest, non-flattering result alongside the wins.
- A section arguing for transparency — "here is what actually happened," wins and losses both
- A quote-grid closing a methodology or process section
- landing
- about
- marketing
Write a kicker and heading (wrap a phrase in *asterisks* for an accent run). Write the body paragraph making the honesty case. Add up to 3 quotes — keep any non-flattering one if the source material includes it; the point of this block is not to only show wins.
- case-file-row
- evidence-plate
- Every quote is a straightforward win — a simple testimonial block is a lighter fit
marketing-landing
record-roster
A single "the record" section: a top-ruled kicker, a ledger of rows (an index, a bold value, and a description), a hairline-bordered logo grid, and an optional centered coda line. The logo grid's cell count follows the number of logos actually uploaded — up to 10 — with empty cells (when fewer than the configured maximum are provided) rendering a numbered mono placeholder.
- A social-proof close listing client/partner logos alongside a short ledger of facts
- A "the numbers" section that wants a real logo wall, not a generic grid
- landing
- about
- marketing
Write a kicker. Add ledger rows (index, value, description) — keep numbering real and complete. Add up to 10 logos; the grid sizes itself to however many you add. Add a coda for a short centered closing line.
- case-file-grid
- proof-plates
- You have no real logos to show — an invented or placeholder-only grid is not appropriate here
marketing-landing
compare-ledger
A ruled-out-vs-full-ink comparison: 2-3 columns each with a mono label and a display value (all but one struck through), then a table of paired rows contrasting the same options attribute by attribute, closed by a short anchored statement. Every field is plain text — no catalog or pricing peer required.
- Contrasting the old way against the new way (or a competitor against your own approach) as a single honest display
- A "before you decide" section that shows what changes across 2-3 options, row by row
- Closing an argument with a visual verdict rather than a paragraph of prose
- landing
- marketing
- dossier
Add 2-3 `columns`, each with a label, a display value, and an "emphasis" flag on the one option that should render in full ink (the rest render struck through, muted). Add up to 6 `rows`, each with one cell per column in column order. Optionally close with an anchored `closeText` statement. For an N-column feature matrix with per-cell Yes/No/tone values, use `comparison-table` instead — this block is for a short, opinionated 2-3-way contrast, not an exhaustive feature grid.
- comparison-table
- cost-ledger
- term-ledger
- You need more than 3 columns, or a feature-by-feature grid with many rows — use `comparison-table`
- The comparison is really just one product's price against nothing — use `price-table` instead
dossier
comparison-table
A feature-by-feature comparison table: 2-6 columns (the options), 1-24 rows (the capabilities), and a cell per intersection with an optional value string and tone (default/affirmative/absent). Columns and rows are free text, so this serves plan comparisons, package matrices, spec sheets, or before/after grids equally. Cells are positional — cell N in a row belongs to column N.
- "Which one do I need?" pages comparing 3+ options across many capabilities in a single scan
- A specification sheet where every option needs the same set of attributes checked off
- A feature matrix accompanying a pricing or plan page, distinct from the tiers themselves
- pricing
- landing
- marketing
- docs
Add a headline (required) and optional eyebrow/description. Add 2-6 `columns`, each with a label and an optional highlight flag for the recommended option. Add 1-24 `rows`, each with a label and a `cells` array — cell order follows column order; a missing cell renders blank rather than shifting the table. Give a cell a `tone` of "affirm" (accent, bold) or "absent" (muted) to make a column read as a shape at a glance. For a short 2-3-way opinionated contrast rather than an exhaustive grid, use `compare-ledger` instead.
- price-table
- compare-ledger
- term-ledger
- You are comparing exactly 2-3 options with a handful of contrast points, not an exhaustive feature grid — use `compare-ledger`
- There is only one offer with one price — a plain `price-table` or product CTA is enough
dossier
term-ledger
A ruled list of term + rich-text body pairs — "what changes", "what this covers", a glossary, or a spec sheet read as a ledger rather than a table. Two variants share one row template and differ only in tone: `shifts` (light band, bold display term) and `spec` (dark band, mono accent term). An optional supporting image can sit beside the rows, and an optional anchored line closes the section.
- Listing what changes, what is included, or what a term means, one row per item, with room for a paragraph of explanation per row
- A "how it works" or "under the hood" section that reads better as short labeled rows than as a table
- Pairing a small number of terms with a supporting photo or diagram beside the list
- landing
- marketing
- docs
Set the variant: `shifts` for a light band with a bold display term (the default, everyday case), `spec` for a dark, technical-feeling band with a mono accent term. Add an optional kicker, a heading (`*accent*` runs render italic accent), and intro rich text. Add `rows` — each needs a term and rich-text body. Optionally add a supporting figure (image + a placeholder note for when no image is set yet) that renders beside the rows. Close with an optional anchored statement (`**strong**`/`*em*` runs supported). For a strict 4-column forensic ledger (line/category/cost/what-compounds) use `cost-ledger` instead; for a feature matrix use `comparison-table`.
- cost-ledger
- comparison-table
- compare-ledger
- The content is fundamentally tabular with many columns — use `comparison-table`
- Each row needs a fixed line/category/cost/compounds shape — use `cost-ledger`
dossier
cost-ledger
A forensic-accounting-styled ledger: an optional kicker + heading + intro, a 3-column strip header labeling the row shape (line/category, the debit, what compounds), up to 6 rows each with a line number, category, a plain-language debit, and what it compounds into — with exactly one row markable as "lit" to render as a dark accent plate — closed by a coda kicker + centered statement naming the total cost.
- Making the cost of inaction or a status quo concrete, one line item at a time
- A "here is what this actually costs you" section building toward a single closing statement
- Highlighting one specific cost line as the fact the reader cannot unsee
- landing
- marketing
- dossier
Add an optional kicker, heading (`*accent*` runs render italic accent), and intro paragraph. Set the three column-strip labels (line/category, the debit, what compounds). Add up to 6 `rows`: line (e.g. "L01"), category, the debit in plain language, what compounds, and a "lit" flag — mark exactly one row lit to render it as the dark plate the reader cannot unsee. Close with a codaKicker + codaText naming the total. For a strict term/definition ledger without the lit-row device, use `term-ledger`; for a multi-option comparison, use `compare-ledger` or `comparison-table`.
- term-ledger
- compare-ledger
- comparison-table
- You need more than 6 rows or a general feature matrix — use `comparison-table`
- There is no single "cost" narrative — a plain `term-ledger` fits a neutral list of terms better
dossier
ledger
A four-column ledger table (Line / Category / Cost / What Compounds) built from 2-10 rows, with one optional accent ("emphasis") row for a running total, and an optional closing note rendered on a dark inset band beneath the table. An optional top strip (label + right-aligned section locator) can run above the headline, and an optional CTA link can run below the block. Two variants: default (full ledger with top strip) and compact (denser rows, no top strip).
- Breaking down the hidden or compounding cost of a decision, delay, or status quo into discrete line items
- A "here is what this actually costs" section that needs to read as itemized and audited rather than a single claim
- Closing an argument with one line-item table plus a single summary verdict on an inset band
- landing
- marketing
- about
- dossier
Author 2-10 `rows`, each with a line id, category, cost (debit) string, and an optional "what compounds" note; mark at most one row `emphasis` to accent it (typically a running total). Column header labels are editable and default to LINE / CATEGORY / THE COST (DEBIT) / WHAT COMPOUNDS. Add an optional `closingNote` for a summary verdict rendered on a dark inset band beneath the table, with its own `closingLabel` kicker. Use `compact` when the ledger sits inside a denser section and does not need the top strip.
- shift-rows
- fit-list
- grants-ledger
- fit-list
- There are fewer than 2 comparable line items — a single stat or a short paragraph makes the point faster
- The cost is a single number rather than several compounding factors — use a stat block instead
dossier
grants-ledger
A real <table> feature matrix: an optional lane kicker + heading above it, then columns (one per plan/tier, each with a label) and rows (one per feature/grant, each with one cell per column). Any column can be flagged `zone2` for a fully inverted dark/accent treatment (e.g. an "Agency" or enterprise tier that reads as categorically different, not just pricier); a separate optional `highlightedColumnIndex` marks exactly one column with a lighter "featured" tint, for when a plan should stand out without the full inversion. Any cell can be flagged `conv` for a mono accent treatment (e.g. "By conversation" instead of a plain value).
- Comparing 3+ plans, tiers, or offers feature-by-feature in a real table, not a card grid
- One column needs to read as categorically different from the others (e.g. an enterprise/agency tier reached by conversation, not checkout)
- A single column should be called out as recommended without going all the way to a fully inverted band
- pricing
- landing
- marketing
Author `columns` (one per plan) and `rows` (one per feature); each row's `cells` are positional against `columns` — `cells[i]` belongs to `columns[i]`. Set `zone2: true` on at most one or two columns for the full dark/accent inversion; set `highlightedColumnIndex` to a 0-based column index for a lighter featured tint on a different column. Set `conv: true` on a cell whose value should read as a conversational/mono-accent exception (e.g. "Conversation") rather than a plain value.
- price-table
- ledger
- fit-list
- fit-list
- There are only 1-2 columns to compare — a simple two-column split reads faster than a table
- Every column is equivalent with no tier needing special emphasis — a plain comparison table without the zone/highlight fields is simpler
dossier
shift-rows
A numbered list of 2-6 rows, each a literal before/after transformation: an optional thumbnail + label + short caption, a BEFORE panel (headline + body), an arrow, and an AFTER panel (headline + body) styled as the positive outcome. An optional heading/eyebrow/section-marker runs above the rows and an optional italic footer note and CTA link run below. Reuses copy that is already phrased as a shift rather than a list of features.
- Every item already reads as "X becomes Y" — a timeline compressing, a cost dropping, a process simplifying
- A "here is what changes when you work with us" section built from 3-4 concrete transformations
- Reinforcing a single argument with a repeated visual rhythm (label / before / arrow / after) rather than a paragraph per point
- landing
- marketing
- about
Author 2-6 `rows`; each needs a label, a before headline, and an after headline (body copy and a thumbnail are optional). When any row sets a thumbnail, the thumbnail column activates for every row — rows without one render a blank placeholder frame. Use the shared Image Display controls to set the thumbnail fit/border/alignment. Keep rows to the 3-4 sweet spot; more than that dilutes the rhythm.
- ledger
- fit-list
- grants-ledger
- fit-list
- The benefits are not naturally before/after pairs — a plain feature list or `stat-bar` fits better
- There is only one transformation to show — a single stat or a short paragraph makes the point without the row apparatus
dossier
fit-list
A self-qualification section: an optional kicker + heading, then two ruled columns — a "build" list of conditions where the offer fits, and a muted "skip" list of conditions where it does not — closed by an optional anchored statement. Reads as candor rather than a sales pitch because it names the cases where the reader should walk away.
- Helping a visitor self-select in or out before they contact sales
- Building trust by naming who the offer is NOT for, alongside who it is
- Closing a pitch section with an honest qualifier rather than another benefit claim
- landing
- marketing
- pricing
Author up to 6 `buildItems` and up to 6 `skipItems` (short, single-line conditions each). Add an optional `kicker` + `heading` above the columns and an optional `closeText` anchored statement below — both accept `*em*` runs for an accented span. Keep each item to one line; this block is a scanning aid, not a place for paragraphs.
- ledger
- shift-rows
- grants-ledger
- ledger
- The offer has no real disqualifying cases — a forced "skip" list reads as false modesty
- The comparison needs more than two columns or per-item detail — use `grants-ledger` instead
dossier
fit-prose
A qualifying section written as two facing prose plates — one paragraph for who this is NOT for, one for who it IS for — each carrying its own label, then a single anchored closing statement (e.g. a guarantee or refund line). Plain prose paragraphs, never a checklist.
- A sales or landing page section that pre-qualifies the reader before the pitch continues
- An offer page that wants to repel the wrong buyer as deliberately as it attracts the right one
- A closing statement (guarantee, refund line, commitment) that needs to sit directly beneath a fit judgment rather than float alone
- landing
- marketing
- about
Author an optional kicker + heading (wrap a phrase in *asterisks* for the accent run), then a not-fit label/body and a fit label/body — both plain prose paragraphs. The optional anchored close renders as one statement beneath a rule (also accepts *asterisk* accents). Any missing piece collapses cleanly: the block renders nothing when heading, both bodies, and the close are all empty.
- spec-sheet
- spec-plate
- zone-directory
- The comparison is a checklist of features rather than a spoken paragraph — a bulleted compare block fits better
- There is no honest "not for you" case to state — a one-sided pitch does not need this device
marketing-landing
zone-directory
A directory board splitting one decision into 2-4 named zones — each cell is a whole-cell link carrying an outline numeral, a kicker, a title, a short description, and a go label. One or more cells can flip to an inverted dark register independent of the block's own background, for visually separating a self-serve path from a higher-touch one.
- A page that offers the reader 2-4 distinct next steps or paths and needs each one named and justified before the link
- A "how you work with us" section splitting self-serve vs. guided engagement
- A landing page moment that wants the decision itself to read as the page's own design device
- landing
- marketing
- about
Author an optional eyebrow + heading (wrap a phrase in *asterisks* for the accent run) + description, then 2-4 cells: each takes a number (renders as an outline numeral), a kicker, a title, a description, a go label (type the arrow glyph yourself — the component does not add one), an href, and an optional dark toggle to invert that one cell's register. The board's column count and border layout adapt automatically to however many cells (2, 3, or 4) are authored.
- fit-prose
- spec-sheet
- spec-plate
- There is only one path forward — a single CTA needs no directory
- More than 4 destinations are being compared — this reads as a considered decision, not a menu; use a larger grid block instead
marketing-landing
spec-sheet
A row of up to 4 label/value cells on a bordered strip — the shape of an engagement's or offer's terms at a glance (Duration, Fee, What happens if you proceed, …), with an optional muted note line underneath. Cells with neither a label nor a value are dropped rather than rendered empty.
- Stating the concrete terms of a paid engagement, sprint, or audit directly on the page (duration, price, next step)
- A proposal or process page that needs a scannable terms strip near a CTA
- Any place a handful of short facts belong side by side, not in prose
- landing
- marketing
- about
Author 1-4 cells, each an optional label + value pair; the strip's column count matches however many cells actually have content, so the row fills edge to edge without a phantom empty column. Add an optional note for a single muted qualifying line beneath the row. The block renders nothing if every cell is empty and no note is set.
- spec-plate
- fit-prose
- zone-directory
- There are more than 4 terms to state, or the values need explanation — use `spec-plate`'s larger grid with its heading + lede instead
- The content is really prose, not discrete label/value facts
dossier
spec-plate
The technical buyer's cheat sheet — a heading (with an optional larger display face) and a one-sentence lede explaining why the detail exists, followed by up to 6 label/value cells (framework, hosting, integrations, …) each with an optional small muted note under the value. The 3-column desktop grid degrades to 2 columns on narrower viewports with its own border rewiring, never collapsing to 1.
- Listing the technical stack or specs behind a build for a reader who asks, without making it the pitch
- A "Under the Hood" or "Tech Specs" section on a platform, product, or case-study page
- Launch-detail lists (ownership terms, what's included) that read as facts, not marketing copy
- landing
- marketing
- about
Author an optional heading (wrap a phrase in *asterisks* for the accent run; `headingFace: display` renders it at the larger elevation-page serif size) and lede, then up to 6 cells: each takes a label, a value, and an optional small note line beneath the value. Use `spec-sheet` instead when there is no heading/lede and 4 or fewer plain terms to state — the two blocks are intentionally not merged; this one carries a head and a larger cell cap.
- spec-sheet
- fit-prose
- zone-directory
- There is no heading or lede to frame the cells — `spec-sheet` is the leaner fit
- More than 6 facts need stating — split into two plates rather than cramming the grid
dossier
lab-notes
A candid "here is what we tried and what we learned" disclosure beat, styled as a field-notebook entry: an optional top strip (label + right-aligned locator), an italic-serif headline and subtitle, then 2-8 labeled entries — a mono kicker plus a body line — running down a continuous margin rule, with one entry markable as the emphasis landing. Closes with an optional handoff line: a label, a body sentence, and a link, either in its own cell or glued inline at the end of the sentence.
- A retrospective or "we tried this, and here is what happened" disclosure section
- A sequence of attempt/outcome/lesson entries that reads like lab notes or a changelog narrative
- A closing handoff that sends the reader to a follow-up resource or a next step
- editorial-article
- about
- docs
Author a headline and 2-8 entries (kicker + body; mark one as emphasis for the accent landing). Add an optional italic subtitle under the headline, and an optional closing handoff (label + body + link). Toggle the top strip off via "Show Section Header" without losing its text — useful when this block follows another one closely. Switch spacing to "Spacious" for an airier, larger-type treatment.
- phase-ledger
- practice-modes
- wall-rows
- The content is a forward-looking roadmap rather than a retrospective — use `phase-ledger` instead
- There is only one point to make — a single paragraph beats the notebook conceit
dossier
phase-ledger
A curriculum- or process-ledger section: an optional lane kicker + serif heading + rich-text intro, then 1-9 numbered phase rows under a 2px top rule, each carrying a locator (a phase number and a bordered chip, e.g. "21 lessons"), a title, and a body paragraph with an italic outcome line. Reads as a syllabus or a roadmap made literal — the numbering is meant to be real and complete, not decorative.
- A course or program page listing its phases/modules in order, each with a scope and an outcome
- A step-by-step process or roadmap where each step needs more than a one-line label
- Proving a curriculum is real and complete — the register gate is exactly this: no gaps, no out-of-order phases
- docs
- about
- editorial-article
Author 1-9 phases in strict order, each with a number, an optional chip tag, a title, a body paragraph, and an optional italic outcome line. `*accent*` runs in the heading render as the band-relative accent-italic style. Keep the phase count real — gaps or reordering break the register the block is built to prove.
- lab-notes
- practice-modes
- wall-rows
- There are fewer than 2-3 real steps — a single paragraph or a `stat-bar` communicates it faster
- The steps are interchangeable/parallel rather than sequential — a card grid fits better than a numbered ledger
dossier
practice-modes
A two-mode comparison section for a single practice or approach that comes in exactly two flavors — e.g. "Compressed" vs "Expanded." A kicker-lane heading sits above two ruled, equal-weight prose columns (label + body each), closing with an anchored statement and an optional real link off to the side.
- Explaining that the same practice/method has exactly two usable modes and describing each
- A "how people actually use this" section that needs two contrasting descriptions, not a feature list
- A closing statement that anchors the section with an optional pointer to more detail
- editorial-article
- docs
- about
Author exactly two modes (label + body each). Add an optional kicker and heading above them (`*em*` runs render serif-italic accent). Close with an anchored statement (`*em*` runs render the same way) and, optionally, a real link — leave both close-link fields blank if the beat has no follow-up.
- lab-notes
- phase-ledger
- wall-rows
- There are more than two modes/variants to compare — a card grid or table fits better
- The two things being compared are not equal in weight — an asymmetric layout communicates that better than two even columns
dossier
wall-rows
A "here is who asked and why the answer was no" section: a kick rule + serif heading (with `*accent*` runs) + rich-text intro, then a bordered, rounded ledger of rows — each carrying a who, a need, and a one-word verdict repeated as the row's own anatomy (e.g. "Wall.") — closing with an anchored statement (`**strong**` runs render semibold).
- Listing a set of asks/requests and the same verdict landing on each one, to make a pattern visible
- A "we said no to this, repeatedly" section where the repetition of the verdict word IS the point
- A closing statement that needs a bordered, scannable ledger of examples behind it
- editorial-article
- about
- docs
Author a kick label, a heading (`*accent*` runs render serif-italic accent), and an intro rich-text paragraph. Add any number of wall rows — each with a required "who," an optional "need" body, and an optional verdict word rendered bold and large at the row end. Close with an anchored statement; `**strong**` runs render semibold.
- lab-notes
- phase-ledger
- practice-modes
- Every row has a different verdict — the block's whole point is ONE repeated verdict word; use a table instead if verdicts vary
- There is only one example — a single pull quote communicates it with less furniture
dossier
Exports
@wabbit/tome-blocks-dossier-pack@wabbit/tome-blocks-dossier-pack/render@wabbit/tome-blocks-dossier-pack/render/register@wabbit/tome-blocks-dossier-pack/demo@wabbit/tome-blocks-dossier-pack/meta
Changelog
c3468b0: `register()` is now built with blocks-core's `createPackRegistrar`, and media fields take their `relationTo` from `mediaRelation(config)` instead of a local `as CollectionSlug` cast. Behaviour and signatures are unchanged. The `@wabbit/tome-blocks-core` peer floor goes up to `>=0.18.0` because that is the first version exporting the helpers.
- c3468b0: `register()` is now built with blocks-core's `createPackRegistrar`, and media fields take their `relationTo` from `mediaRelation(config)` instead of a local `as CollectionSlug` cast. Behaviour and signatures are unchanged. The `@wabbit/tome-blocks-core` peer floor goes up to `>=0.18.0` because that is the first version exporting the helpers.
404d325: Tome block packs now install into an existing Payload project the way the README says: one `npm install`, one CSS import, no undocumented steps. Proven by the new fresh-install smoke test (`scripts/blocks-fresh-install-smoke.mjs`) against a brand-new `create-payload-app` website-template site. **Consumers: list `@wabbit/tome-blocks-core` and `@wabbit/tome-ui` in your own `package.json`** if you import from them (npm 7+ and pnpm install required peers automatically, so a fresh `npm install` of a pack already brings them in). - **One shared `blocks-core` per site.** Every pack, `blocks-house` and `blocks-extras` now declare `@wabbit/tome-blocks-core` (and, where used, `-house` / `-extras`) as a required peer with an explicit range instead of a regular dependency, so a site gets exactly one hoisted copy and one adapter registry. - **No more ERESOLVE in plain Payload sites.** `blocks-core` no longer declares `@wabbit/tome-core` or `@wabbit/tome-catalog` (their optional peer graph pulled `better-auth` → `@sveltejs/kit` → `vite@8` against a site's `vite@7`). The `block-bundle` product type still auto-registers when both are installed; new structural types `BlockBundleProductTypeDeps`, `BlockBundleProductTypeRegistryLike`, `RegisterProductTypeHooksLike`. - **Tokens in one line:** `@import '@wabbit/tome-blocks-core/styles.css';` (new export; imports `@wabbit/tome-ui/tokens`). `@wabbit/tome-ui` is now a required peer of `blocks-core`. - **Rich text and images render with no adapter setup.** Built-in defaults render Lexical through `@payloadcms/richtext-lexical/react` and resolve populated Payload uploads; an unpopulated upload id warns once in every environment (previously content vanished silently in production). Registered adapters still win. - **Payload's spread-props convention:** new `adaptRenderersForPayload(renderers)` / `adaptRendererForPayload(Component)` wrap any pack's `renderers` map for a site that renders `<Block {...block} />`. - **Slug collisions with Payload's templates** (`cta`, `banner`, `archive`, `content`, `code`): new `applyBlockSlugOverrides(blocks, overrides)` and `remapRendererSlugs(renderers, overrides)` (`@wabbit/tome-blocks-core/slugOverrides`). Defaults are unchanged; no stored data migrates. - **`blocks-house`** owns `gsap` and `hls.js` as dependencies (previously optional peers that still broke the build when missing), and registers GSAP's `ScrollTrigger` itself before first use. - **Full-bleed bands actually span the grid.** Eight `pinnedBand` blocks (cinema-pack AmbientBand, MediaPanel, PullInterlude, SceneCaption, ScenePlate, ScrubStory, StatementBand; blocks-house FullBleedInterstitial) now declare `grid-column: 1 / -1` at their root as the contract requires. **Visible change:** inside a tome-ui `.grid`, these render edge to edge where they were previously squeezed to content width. - **`@wabbit/tome-ui`:** `.grid` declares `reading-start` / `reading-end` below 768px (aliased to the content column), so blocks placed on the reading column no longer collapse to a sliver on phones. - Every pack README gains an "Install into an existing Payload project" section and a peer table that matches `package.json`; `blocks-core`'s README carries the full walkthrough.
- 404d325: Tome block packs now install into an existing Payload project the way the README says: one `npm install`, one CSS import, no undocumented steps. Proven by the new fresh-install smoke test (`scripts/blocks-fresh-install-smoke.mjs`) against a brand-new `create-payload-app` website-template site. **Consumers: list `@wabbit/tome-blocks-core` and `@wabbit/tome-ui` in your own `package.json`** if you import from them (npm 7+ and pnpm install required peers automatically, so a fresh `npm install` of a pack already brings them in). - **One shared `blocks-core` per site.** Every pack, `blocks-house` and `blocks-extras` now declare `@wabbit/tome-blocks-core` (and, where used, `-house` / `-extras`) as a required peer with an explicit range instead of a regular dependency, so a site gets exactly one hoisted copy and one adapter registry. - **No more ERESOLVE in plain Payload sites.** `blocks-core` no longer declares `@wabbit/tome-core` or `@wabbit/tome-catalog` (their optional peer graph pulled `better-auth` → `@sveltejs/kit` → `vite@8` against a site's `vite@7`). The `block-bundle` product type still auto-registers when both are installed; new structural types `BlockBundleProductTypeDeps`, `BlockBundleProductTypeRegistryLike`, `RegisterProductTypeHooksLike`. - **Tokens in one line:** `@import '@wabbit/tome-blocks-core/styles.css';` (new export; imports `@wabbit/tome-ui/tokens`). `@wabbit/tome-ui` is now a required peer of `blocks-core`. - **Rich text and images render with no adapter setup.** Built-in defaults render Lexical through `@payloadcms/richtext-lexical/react` and resolve populated Payload uploads; an unpopulated upload id warns once in every environment (previously content vanished silently in production). Registered adapters still win. - **Payload's spread-props convention:** new `adaptRenderersForPayload(renderers)` / `adaptRendererForPayload(Component)` wrap any pack's `renderers` map for a site that renders `<Block {...block} />`. - **Slug collisions with Payload's templates** (`cta`, `banner`, `archive`, `content`, `code`): new `applyBlockSlugOverrides(blocks, overrides)` and `remapRendererSlugs(renderers, overrides)` (`@wabbit/tome-blocks-core/slugOverrides`). Defaults are unchanged; no stored data migrates. - **`blocks-house`** owns `gsap` and `hls.js` as dependencies (previously optional peers that still broke the build when missing), and registers GSAP's `ScrollTrigger` itself before first use. - **Full-bleed bands actually span the grid.** Eight `pinnedBand` blocks (cinema-pack AmbientBand, MediaPanel, PullInterlude, SceneCaption, ScenePlate, ScrubStory, StatementBand; blocks-house FullBleedInterstitial) now declare `grid-column: 1 / -1` at their root as the contract requires. **Visible change:** inside a tome-ui `.grid`, these render edge to edge where they were previously squeezed to content width. - **`@wabbit/tome-ui`:** `.grid` declares `reading-start` / `reading-end` below 768px (aliased to the content column), so blocks placed on the reading column no longer collapse to a sliver on phones. - Every pack README gains an "Install into an existing Payload project" section and a peer table that matches `package.json`; `blocks-core`'s README carries the full walkthrough.
Updated dependencies [e044594] - @wabbit/tome-blocks-core@0.16.6
- Updated dependencies [e044594] - @wabbit/tome-blocks-core@0.16.6
Updated dependencies [a2f2dfa] - @wabbit/tome-blocks-house@0.3.0
- Updated dependencies [a2f2dfa] - @wabbit/tome-blocks-house@0.3.0
37fca4e: Text over the solid-dark surface now uses `var(--tome-color-on-solid-dark, var(--tome-color-surface-inverse))` — the tome-ui pairing idiom — so consumers on tome-ui < 0.10 (which lacks `on-solid-dark`) no longer render dark-on-black in light theme (case-file-grid, case-file-row, evidence-sheet, ledger, receipts-trio, zone-directory).
- 37fca4e: Text over the solid-dark surface now uses `var(--tome-color-on-solid-dark, var(--tome-color-surface-inverse))` — the tome-ui pairing idiom — so consumers on tome-ui < 0.10 (which lacks `on-solid-dark`) no longer render dark-on-black in light theme (case-file-grid, case-file-row, evidence-sheet, ledger, receipts-trio, zone-directory).
- Updated dependencies [7850b7a] - @wabbit/tome-blocks-house@0.2.0
b529fa6: Demo content is brand-free: compare-ledger's emphasised column ("The Wabbit way" → "The documented way"), shift-rows' heading (no platform name), and a demo subject renamed away from an internal persona name. Catalog captures are a public surface for anyone licensing Tome; demo fiction must not name Wabbit, Tome, or house personas. Demo props now carry `_variant`, so gallery thumbs for term-ledger, ledger, grants-ledger, shift-rows and fit-list render the requested variant instead of the default.
- b529fa6: Demo content is brand-free: compare-ledger's emphasised column ("The Wabbit way" → "The documented way"), shift-rows' heading (no platform name), and a demo subject renamed away from an internal persona name. Catalog captures are a public surface for anyone licensing Tome; demo fiction must not name Wabbit, Tome, or house personas. Demo props now carry `_variant`, so gallery thumbs for term-ledger, ledger, grants-ledger, shift-rows and fit-list render the requested variant instead of the default.