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';
import * as DocumentUploadStories from '../app/shared/ui/upload/document-upload/document-upload.stories';

<Meta title="Foundations/Atomic Design" />

# 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.

<div style={{ display: 'grid', gap: '0.5rem', maxWidth: '32rem', margin: '1.5rem 0' }}>
  {[
    [
      '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 CIBG Huisstijl (Bootstrap) CSS classes',
      '#6aa6d8',
    ],
  ].map(([name, where, why, bg], i) => (
    <div
      key={name}
      style={{
        background: bg,
        color: '#fff',
        padding: '0.75rem 1rem',
        borderRadius: '6px',
        marginLeft: `${i * 1.5}rem`,
      }}
    >
      <strong>{name}</strong> <span style={{ opacity: 0.85 }}>— {why}</span>
      <div
        style={{ fontFamily: 'monospace', fontSize: '0.75rem', opacity: 0.8, marginTop: '0.2rem' }}
      >
        {where}
      </div>
    </div>
  ))}
</div>

## 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 CIBG CSS owns the pixels.

<Canvas of={ButtonStories.Primary} />

### Molecule — `form-field`

Label + control + error text, grouped so the error is announced via `role="alert"`. It
composes atoms; it adds no new visual primitives of its own.

<Canvas of={FormFieldStories.WithError} />

### Organism — `document-upload`

`shared/ui/upload/document-upload` composes molecules (a file input, alert, progress bar,
chips) into a section that owns real upload behaviour.

<Canvas of={DocumentUploadStories.Default} />

### Template — `page-shell`

The page skeleton — title, optional back-link, content slot. Pages drop composed
organisms into it; the template never knows what they are.

<Canvas of={PageShellStories.WithBackLink} />

## Why bother

A new page should be **composition of existing blocks**. Adding a new building block is the
exception, not the reflex — if you reach for one, that is a signal to check whether an
existing atom/molecule already covers it. Fewer primitives → less to test, less to learn,
one place to fix a bug.
