Specification is the only source of truth.
A versioned spec with intent, acceptance criteria, and failure modes.
A 2×2 hero grid of the four DoCoDeGo pillars — each tile carries the human role, the principle, and what gets shipped — with cascading entrance and a lift-on-hover affordance.
Four pillars, four human roles, four artefacts that must exist before the next one begins. Skip one and the loop breaks.
Specification is the only source of truth.
A versioned spec with intent, acceptance criteria, and failure modes.
Human owns the architecture; AI implements it.
Reviewed implementation that maps to architecture, not vibes.
Value flows at the speed of validation, not schedules.
A passed acceptance run — proof intent was actually met.
Autonomy without accountability is catastrophe.
An audit trail and a sign-off that someone stands behind.
Show the entire framework in one glance: four pillars, four human roles, four principles, four shipped artefacts. The 2×2 grid asserts that DoCoDeGo is whole — none of the four can be skipped without paying the skip-cost that the framework documents elsewhere.
---
import type { CompendiumMeta } from '../../../data/types';
export const meta: CompendiumMeta = {
id: 103,
slug: 'four-pillars-grid',
name: 'Four Pillars Grid',
category: 'compositions',
subcategory: 'heroes',
description: 'A 2×2 hero grid of the four DoCoDeGo pillars — each tile carries the human role, the principle, and what gets shipped — with cascading entrance and a lift-on-hover affordance.',
spec: `## Intent
Show the entire framework in one glance: four pillars, four human roles, four principles, four shipped artefacts. The 2×2 grid asserts that DoCoDeGo is whole — none of the four can be skipped without paying the skip-cost that the framework documents elsewhere.
## Acceptance Criteria
- [ ] Four large tiles in a 2×2 grid on desktop, stacked on mobile
- [ ] Each tile uses its pillar background with black ink (tokens only)
- [ ] Each tile shows: pillar letters (DO / CO / DE / GO), full name, human role, principle, and one "what gets shipped" example
- [ ] Cascading entrance — tiles reveal in reading order with a brief stagger
- [ ] Hover lift: 3px translate + hard shadow (no rounded corners, no blur)
- [ ] Skip-cost footer strip — one-line reminder that all four pillars are load-bearing
- [ ] Respects prefers-reduced-motion — no movement under reduce
## Constraints
- Pure Astro + Tailwind, no external deps
- Pillar content sourced from the framework canon
- ≤ 250 lines body`,
tags: ['real-content', 'animated', 'reduced-motion', 'card', 'responsive', 'dark-mode-tested'],
status: 'stable',
kind: 'composition',
aspect: 'full',
health: { ics: 100, a11y: 'aa', themed: true, animated: true },
};
const pillars = [
{
short: 'DO',
full: 'DOcument',
role: 'Author',
bg: 'bg-do',
principle: 'Specification is the only source of truth.',
ships: 'A versioned spec with intent, acceptance criteria, and failure modes.',
},
{
short: 'CO',
full: 'COmpose',
role: 'Architect',
bg: 'bg-co',
principle: 'Human owns the architecture; AI implements it.',
ships: 'Reviewed implementation that maps to architecture, not vibes.',
},
{
short: 'DE',
full: 'DEmonstrate',
role: 'Gatekeeper',
bg: 'bg-de',
principle: 'Value flows at the speed of validation, not schedules.',
ships: 'A passed acceptance run — proof intent was actually met.',
},
{
short: 'GO',
full: 'GOvern',
role: 'Governor',
bg: 'bg-go',
principle: 'Autonomy without accountability is catastrophe.',
ships: 'An audit trail and a sign-off that someone stands behind.',
},
];
---
<div data-this-component class="w-full bg-paper text-black border-4 border-black p-5 md:p-8 overflow-hidden">
<header class="mb-6 md:mb-8 max-w-3xl">
<div class="inline-flex items-center gap-2 bg-ink text-paper px-2.5 py-1 border-2 border-black mb-3">
<span class="text-[10px] font-mono uppercase tracking-widest">The Four Pillars</span>
<span class="text-[10px] font-mono uppercase tracking-widest opacity-60">All load-bearing</span>
</div>
<h2 class="reveal text-2xl md:text-3xl lg:text-4xl font-black uppercase tracking-tight leading-[1.05]" style="--reveal-i:0">
Document · Compose · Demonstrate · Govern.
</h2>
<p class="reveal mt-3 max-w-2xl text-sm md:text-base text-black opacity-80 leading-snug" style="--reveal-i:1">
Four pillars, four human roles, four artefacts that must exist before the next one begins.
<span class="font-black">Skip one and the loop breaks.</span>
</p>
</header>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-5">
{pillars.map((p, i) => (
<article
class:list={['reveal pillar-card border-4 border-black flex flex-col', p.bg, 'text-black']}
style={`--reveal-i:${i + 2}`}
>
<header class="flex items-end justify-between px-5 pt-4 pb-3 border-b-4 border-black">
<div>
<div class="text-4xl md:text-5xl lg:text-6xl font-black tracking-tighter leading-none">{p.short}</div>
<div class="mt-1 text-xs md:text-sm font-black uppercase tracking-widest opacity-80">{p.full}</div>
</div>
<div class="text-end">
<div class="text-[9px] font-mono uppercase tracking-widest opacity-70">Human role</div>
<div class="text-sm md:text-base font-black uppercase tracking-wide">{p.role}</div>
</div>
</header>
<div class="px-5 py-4 grow flex flex-col gap-3">
<p class="text-base md:text-lg font-black leading-snug">
{p.principle}
</p>
<div class="mt-auto border-t-2 border-black border-dashed pt-3">
<div class="text-[9px] font-mono uppercase tracking-widest opacity-70 mb-1">What gets shipped</div>
<p class="text-xs md:text-sm leading-snug">{p.ships}</p>
</div>
</div>
<footer class="border-t-4 border-black bg-ink text-paper px-5 py-2 text-[10px] md:text-xs font-mono uppercase tracking-widest">
Pillar {i + 1} / 4
</footer>
</article>
))}
</div>
<footer class="reveal mt-6 md:mt-8 border-t-4 border-black pt-4 text-xs md:text-sm font-mono text-black opacity-70 max-w-3xl" style="--reveal-i:6">
// The pillars are sequential at first, then concurrent — each one earns the next.
</footer>
</div>
<style>
[data-this-component] .reveal {
opacity: 0;
transform: translateY(16px);
animation: cpd-103-reveal 540ms cubic-bezier(0.2, 0, 0.13, 1.2) forwards;
animation-delay: calc(var(--reveal-i, 0) * 110ms);
}
@keyframes cpd-103-reveal {
to { opacity: 1; transform: none; }
}
[data-this-component] .pillar-card {
transition: transform 160ms ease, box-shadow 160ms ease;
}
[data-this-component] .pillar-card:hover {
transform: translate(-3px, -3px);
box-shadow: 6px 6px 0 0 var(--color-ink);
}
@media (prefers-reduced-motion: reduce) {
[data-this-component] .reveal {
animation: none;
opacity: 1;
transform: none;
}
[data-this-component] .pillar-card,
[data-this-component] .pillar-card:hover {
transform: none;
transition: none;
box-shadow: none;
}
}
</style>