← ARTSABERS

ARTSABERS — Core Block Library · Build Brief

BBAS40 Build Brief ARTSABERS

## Purpose

Design the ARTSABERS treatment for the **whole default Gutenberg block set** — every block an operator can reach from the inserter in a content area — so operator-authored pages look deliberately Kyber Hull rather than like WordPress defaults sitting on a dark background.

This drives a `design_type=component` mockup, **not a page mockup**. It is a specimen sheet: every block, stacked in labelled families in a single scroll, so the operator signs off the entire block library in one review pass.

The live specimen it mirrors is the ARTSABERS Content Guide (page 81285 on artsabers.camcom.dev), which currently exercises 40 distinct block types. That page is the verification surface after conversion; this mockup is the design target.

## Why this brief exists

Six blocks are laid out but not designed — `cover` carries two CSS declarations, `columns` one, `group` one, `media-text` five. Roughly twenty more have none at all. Fifteen style variations are registered in the editor’s Styles panel and render as the plain default. The block set is functional and off-brand, and there is no design to build against.

## THE HARD CONSTRAINT — read before authoring

**Core block markup is fixed by WordPress. You cannot change it, and neither can the theme.**

Every block below ships a `save()` function (or a server-side render) that emits an exact DOM with exact class names. The conversion step that follows this mockup is CSS only — it applies brand styling to the selectors WordPress already generates. It cannot restructure the DOM, rename a class, add a wrapper, or move an element.

So: **author against the pinned markup verbatim.** A treatment that requires a different DOM cannot be built. If a treatment you want genuinely cannot be achieved on the pinned markup, say so explicitly in a comment rather than silently inventing markup that works — a flagged impossibility is useful, a beautiful unbuildable mockup is not.

This is not hypothetical. The closest prior attempt at a block-reference mockup (War Dungeon MWD35) invented `.wp-block-columns–2` and `–3` modifier classes that WordPress never emits, and the CSS written against them could never apply.

Every skeleton below was extracted from the real rendered page, not written from memory or documentation.

## Pinned markup — MUST NOT deviate

Notation is CSS-SELECTOR form, deliberately — `tag.class.class` with children indented, never angle-bracket HTML. This brief is served to you through a plain-text conversion that strips anything shaped like a tag, so an angle-bracket contract arrives blank. Read `tag.class` as an element of that tag carrying those classes. `TEXT` marks a text node. `… repeats` marks sibling repetition collapsed to one exemplar. Layout classes WordPress adds (`is-layout-flow`, `is-layout-constrained`, `is-layout-flex`, `wp-block-{name}-is-layout-{type}`, `wp-container-core-columns-is-layout-{hash}`) are present on many blocks and are omitted below for legibility except where load-bearing — never rely on them for styling, and never remove them.

### Text and prose

**IMPORTANT:** this WordPress version stamps a class on paragraphs and lists. `core/paragraph` emits `p[class=”wp-block-paragraph”]` and `core/list` emits `ul[class=”wp-block-list”]`. Style against those classes, not bare tags.

“`
core/heading h2.wp-block-heading TEXT (h1–h6, same class)
core/paragraph p.wp-block-paragraph TEXT
core/list ul.wp-block-list
li TEXT (li carries NO class)
core/quote blockquote.wp-block-quote
p.wp-block-paragraph TEXT
cite TEXT (cite carries NO class)
core/pullquote figure.wp-block-pullquote
blockquote
p TEXT
cite TEXT
core/code pre.wp-block-code
code TEXT
core/preformatted pre.wp-block-preformatted (newlines are br)
core/verse pre.wp-block-verse (newlines are br)
core/math div.wp-block-math
math > semantics > mrow (real MathML, not an image)
mi/mo/mfrac TEXT
annotation TEXT
“`

Captions across every block use `figcaption.wp-element-caption` — one selector covers image, gallery, columns-image, embed and media captions.

### Media

“`
core/image figure.wp-block-image.size-large
img
figcaption.wp-element-caption TEXT
core/gallery figure.wp-block-gallery.has-nested-images.columns-2.is-cropped
figure.wp-block-image.size-large
img
… repeats
core/embed figure.wp-block-embed.is-type-video.is-provider-youtube.wp-embed-aspect-16-9
div.wp-block-embed__wrapper
iframe
core/media-text div.wp-block-media-text.is-stacked-on-mobile
figure.wp-block-media-text__media
img
div.wp-block-media-text__content
p.wp-block-paragraph TEXT
core/cover div.wp-block-cover
span.wp-block-cover__background.has-background-dim-50.has-background-dim
img.wp-block-cover__image-background
div.wp-block-cover__inner-container
h2.wp-block-heading TEXT
div.wp-block-buttons …
“`

`core/cover`’s dim layer is a `span` sibling of the image, not an overlay pseudo-element — a scrim treatment must work with it or restyle it.

### Layout

“`
core/columns div.wp-block-columns (flex; NO –2 / –3 modifier exists)
div.wp-block-column
… repeats
core/group div.wp-block-group
div.wp-block-group__inner-container (children nest ONE LEVEL DEEPER)
core/separator hr.wp-block-separator.has-alpha-channel-opacity
core/spacer div.wp-block-spacer (inline height style; leave alone)
“`

`core/group` wrapping its children in `.wp-block-group__inner-container` is the single most consequential fact here — any treatment of a group’s interior has to reach through that wrapper.

### Interactive and buttons

“`
core/buttons div.wp-block-buttons
div.wp-block-button
a.wp-block-button__link.wp-element-button TEXT
core/details details.wp-block-details
summary TEXT (summary carries NO class)
p.wp-block-paragraph TEXT
core/accordion div.wp-block-accordion[role=”group”][data-wp-interactive=”core/accordion”]
div.wp-block-accordion-item
h3.wp-block-accordion-heading
button.wp-block-accordion-heading__toggle[data-wp-on–click=”actions.toggle”]
span.wp-block-accordion-heading__toggle-title TEXT
span.wp-block-accordion-heading__toggle-icon TEXT
div.wp-block-accordion-panel[role=”region”]
p.wp-block-paragraph TEXT
… repeats
core/search form.wp-block-search.wp-block-search__button-outside.wp-block-search__text-button[role=”search”]
label.wp-block-search__label TEXT
div.wp-block-search__inside-wrapper
input.wp-block-search__input[type=”search”]
button.wp-block-search__button.wp-element-button[type=”submit”] TEXT
core/file div.wp-block-file
a TEXT
a.wp-block-file__button.wp-element-button TEXT
“`

`core/accordion` is the native block and is **distinct from the existing `.faq-accordion` component** used by the FAQ template. Design it as its own thing; do not assume they should match. Its toggle icon is a `span` with text content, not an SVG.

Note `.wp-element-button` appears on button, search submit and file download — one class, three different jobs. Decide whether they share a treatment or diverge.

### Data-driven widgets

These pull real site content. They are the least designed part of the set and currently inherit prose link styling — ember and underlined — which reads as a wall of links.

“`
core/table figure.wp-block-table
tabletheadtrth TEXT
tbodytrtd TEXT
core/latest-posts ul.wp-block-latest-posts__list.has-dates.wp-block-latest-posts
core/categories ul.wp-block-categories-list.wp-block-categories-taxonomy-product_cat.wp-block-categories
li.cat-item.cat-item-{id}
a TEXT
ul.children (nested hierarchy)
li.cat-item.cat-item-{id}a TEXT
core/tag-cloud p.wp-block-tag-cloud (a p, not a list)
a.tag-cloud-link.tag-link-{id}.tag-link-position-{n} TEXT
(inline font-size per weight — respect or override)
core/archives div.wp-block-archives-list.wp-block-archives
core/page-list ul.wp-block-page-list
li.wp-block-pages-list__item.current-menu-item
a.wp-block-pages-list__item__link TEXT
core/social-links ul.wp-block-social-links
li.wp-social-link.wp-social-link-{service}.wp-block-social-link
a.wp-block-social-link-anchor
svgpath
span.wp-block-social-link-label.screen-reader-text TEXT
core/rss ul.wp-block-rss.has-dates
li.wp-block-rss__item
div.wp-block-rss__item-titlea TEXT
time.wp-block-rss__item-publish-date TEXT
core/breadcrumbs nav.wp-block-breadcrumbs[aria-label=”Breadcrumbs”]
ollia TEXT
“`

`core/tag-cloud` sets an inline `font-size` per tag to express weight, and `core/social-links` renders each service’s own SVG. Both are cases where the brand has to decide whether to work with core’s mechanism or replace it.

## Sections (top to bottom)

One section per family, each with a section label, then the specimens with a small label above each. Alternate section grounds per the styleguide’s rhythm rules.

1. **Text and prose** — heading ladder h1–h6, paragraph, list (ordered and unordered, including nested), quote, pullquote, code, preformatted, verse, math.
2. **Media** — image (default, wide, full), caption treatment, gallery, embed, media-text (both media positions), cover.
3. **Layout** — columns (two-up and three-up), group with and without background, separator, spacer.
4. **Interactive** — buttons row, details, accordion (two items, one open), search, file.
5. **Data widgets** — table (with and without header row), latest posts, categories (hierarchical), tag cloud, archives, page list, social links, RSS, breadcrumbs.
6. **Style variations** — the fifteen registered below, each shown against its default so the difference is legible.

## The twelve style variations

Registered in `artsabers_register_core_block_styles()`, all currently rendering as the plain default. Each needs a treatment distinct enough that an operator can tell why it exists.

**Paragraph** (`is-style-{name}`): `eyebrow`, `lead`, `price`, `meta-name`, `meta-value`, `mono-date`.
**Button** (`is-style-{name}` on `.wp-block-button`): `dark`, `ghost-ember`. **Two only.** The set was six until 2026-08-06; MAS101 rendered them together and showed a single-hue palette cannot carry six legibly distinct fills, so `ember`, `ember-glow`, `clear` and `ghost-ember-glow` were retired. The button set is now four TOTAL — the default (ember ombre, no style class), these two, and core’s own `outline`. Do not design or re-add the retired four.
**Image**: `showcase`, `image-tile`.
**Separator**: `wide` (labelled “Hairline rule”).
**Cover**: `category-tile` — a navigational image-with-label tile for category grids.

Separately, seven `ground-*` styles are registered on `core/group`. They carry `style_data` and self-style; they need no CSS and are out of scope here.

## Type — the small step is 14px

The brand’s small-type default is **14px** (`typography.scale.body_sm`), covering captions, nav labels, button text, form hints, table cells and secondary copy. It was enforced across the theme on 2026-08-06, replacing an unnamed 13px literal that had been the de-facto default in 61 files. **13px is retired — do not specify it.** 15px is also wrong: against the 16px body it stops reading as a distinct step.

## Currently thin — needs real design attention

`cover`, `columns`, `group`, `media-text`, `gallery`, `embed`. These render but have no considered treatment. Give them the same attention as a hero band would get.

## Out of scope

`audio` and `video` (no media in the library yet), `icon` (renders nothing until an icon is chosen in the editor), `footnotes` (needs post-meta references), `nextpage` (only valid inside `core/post-content`), `text-columns` (deprecated, hidden from the inserter). Also out: the query, comments and site/template block families — a classic PHP theme’s templates own those, so an operator never places them in content.

## Fidelity to shipped markup

Where the pinned markup cannot carry a treatment you want, **flag it in a comment in the mockup rather than working around it silently**. That flag is a real output of this pass — it tells the conversion step where a custom block or a template change would be needed instead of CSS.