Coordinator lesson from the art-deco lane: `field.text` attribute access on a
bare-string seed/settings value errors the whole block to empty (dead band).
eyebrow/headline/subheadline/description now use `|get:"text"|default:` so the
hero accepts {text,...} objects OR bare strings — same fix art-deco shipped in
f2c8b36. cta/logoText object fields are builtin-typed and stay direct.
Also audited per coordinator: no ::icon:: shortcodes in any template/block
(only CSS ::-webkit pseudo-elements); master_pages.json untouched this lane.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Article title no longer rendered twice: seed article pages drop the duplicate
level-1 heading block; the article template's page <h1> is the sole title.
- Home dead gap resolved: landing sections divided by a hard 4px rule. The CMS
wraps each block in its own <div data-block-id>, so the divider adjacency now
targets the block wrappers ([data-block-id]+[data-block-id] .bru-section), not
the (non-sibling) sections; landing section padding reduced 4rem->3rem.
- SVG geometry guard completed: explicit width/height on every <use> icon SVG,
including the 5 testimonial star ratings the earlier regex missed (the ">="
in their class conditional).
- Seed quality: HARDSET site title hardset; article expanded to ~9 hard-edged
paragraphs to kill the below-article void.
- Fresh 2880x1800 light+dark captures for home/about/article; preview = home-light.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The host public CSS is a render-driven JIT (`@import "tailwindcss"
source(none)`); a runtime-installed codeless theme lives in data/plugins,
which is in NO @source glob, so its .ninjatpl utility classes only compile
if a built-in emits the exact string or the class is safelisted. Non-
safelisted families were silently dropping on a fresh provision, causing:
feature-grid rendering full-width instead of 3 columns (lg:grid-cols-3
absent), card/section content crammed against borders (p-* shorthand
absent), and touching grid items (gap-6 absent).
- manifest.yaml: add a "layout guarantee layer" of raw CSS scoped to
.brutalist-page (compiled unconditionally via input_css_append) defining
grid-cols/col-span/columns + all sm/md/lg responsive variants, p-*
shorthand, gap-*, space-y-*, aspect-*, object-*, w/h-full. Deterministic
columns on desktop AND 1-col collapse on mobile via real media queries.
- manifest.yaml: cut excessive .bru-section padding (6rem->4rem desktop,
4rem->2.75rem mobile) to remove the oversized dead bands between sections.
- project_ledger: was a bare <section> with no wrap -> rendered full-bleed
(rows touched the viewport edges). Wrap in bru-section + bru-wrap; add an
optional heading field (parity with changelog/spec_sheet).
- navbar: move mobile drawer + overlay geometry (fixed/top/right/h-full/
w-80/max-w-[85vw]/inset-0/z) into the inline <style> so the non-safelisted
positioning classes can't leave the drawer unpositioned; display stays on
safelisted flex/md:hidden. Neutral rgba scrim.
- image: guard empty src so absent media collapses instead of an empty
bordered box (empty-media graceful state).
Persona (concrete, chunky borders, hard offset shadows, candy accents)
unchanged. No .reveal/scroll-hide pattern in this theme. Version not bumped.
make build, ninja plugin verify, and check-safety all exit 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>