import { Meta, Canvas } from '@storybook/addon-docs/blocks';
import * as ButtonStories from '../app/shared/ui/button/button.stories';
import * as FormFieldStories from '../app/shared/ui/form-field/form-field.stories';
import * as PageShellStories from '../app/shared/layout/page-shell/page-shell.stories';
# Atomic design
Every screen in this app is built from a small set of layers, each composed **only from
the layer below it**. Read a screen top-down and you always land on the same handful of
atoms — that is the whole point: fewer things to understand, nothing bespoke per page.
{[
['Templates', 'shared/layout', 'shell, page-shell, wizard-shell — the page skeleton', '#1e3a5f'],
['Organisms', 'shared/ui/upload/document-upload …', 'self-contained sections that own a bit of behaviour', '#2a5a8a'],
['Molecules', 'shared/ui/form-field, async …', 'a label + control + error, grouped', '#3f7cb5'],
['Atoms', 'shared/ui/button, text-input …', 'thin wrappers over Utrecht/RHC CSS classes', '#6aa6d8'],
].map(([name, where, why, bg], i) => (
))}
## The rule, enforced
**Each layer only uses layers below it, and dependencies point inward.** This is not a
convention you have to remember — `eslint.config.mjs` fails the build if `domain/` imports
Angular, or if a context imports "upward". See [the FP-in-the-UI primer](?path=/docs/foundations-fp-in-the-ui--docs)
for how the same discipline shapes state and effects.
## A composition chain, live
Here is one real chain from atom → molecule → template. Each is a published Storybook
story below; click through to the sidebar entries to explore every variant.
### Atom — `button`
A thin wrapper: we own a typed `variant` input, the RHC CSS owns the pixels.