Skip to main content
Compendium / Pillars & Roles / Loops & Cycles / IRAF Mini Loop
#383

IRAF Mini Loop

A compact one-line variant of the IRAF cycle — Intent · Reasoning · Action · Feedback — for inline badges and headers.

STABLE GO
#svg #real-content #dark-mode-tested #responsive
Live
// iraf · mini LOOP
I INTENT R REASON A ACTION F FEEDBACK cycle returns to intent
Spec

Intent

The full IRAF tile is heavy; this atom collapses the same four steps into a single horizontal strip so it fits inline beside a heading or a card title.

Acceptance Criteria

  • [ ] Four pills in a row, each coloured by its pillar token
  • [ ] Arrows between pills and a closing return arrow underneath
  • [ ] Each pill carries its initial and label
  • [ ] Negative: does NOT require JS

Constraints

  • Pure SVG
  • Theme-aware via tokens
// iraf-mini-loop.astro
---
import type { CompendiumMeta } from '../../../data/types';

export const meta: CompendiumMeta = {
  id: 383,
  slug: 'iraf-mini-loop',
  name: 'IRAF Mini Loop',
  category: 'pillars-roles',
  subcategory: 'loops-cycles',
  pillar: 'go',
  description: 'A compact one-line variant of the IRAF cycle — Intent · Reasoning · Action · Feedback — for inline badges and headers.',
  spec: `## Intent
The full IRAF tile is heavy; this atom collapses the same four steps into a single horizontal strip so it fits inline beside a heading or a card title.

## Acceptance Criteria
- [ ] Four pills in a row, each coloured by its pillar token
- [ ] Arrows between pills and a closing return arrow underneath
- [ ] Each pill carries its initial and label
- [ ] Negative: does NOT require JS

## Constraints
- Pure SVG
- Theme-aware via tokens`,
  tags: ['svg', 'real-content', 'dark-mode-tested', 'responsive'],
  status: 'stable',
  health: { ics: 90, a11y: 'aa', themed: true, animated: false },
};

const stages = [
  { k: 'I', t: 'INTENT',    c: 'var(--color-do)' },
  { k: 'R', t: 'REASON',    c: 'var(--color-co)' },
  { k: 'A', t: 'ACTION',    c: 'var(--color-de)' },
  { k: 'F', t: 'FEEDBACK',  c: 'var(--color-go)' },
];
---

<div data-this-component class="w-full bg-paper text-black border-4 border-black p-3 overflow-hidden">
  <div class="flex items-baseline justify-between mb-2 gap-2">
    <span class="font-mono text-[10px] uppercase tracking-widest opacity-60">// iraf · mini</span>
    <span class="font-mono text-[10px] uppercase tracking-widest">LOOP</span>
  </div>
  <svg viewBox="0 0 280 90" class="w-full block" aria-label="IRAF mini loop" role="img">
    <defs>
      <marker id="iraf-mini-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
        <path d="M 0 0 L 10 5 L 0 10 z" fill="var(--color-ink)" />
      </marker>
    </defs>
    {stages.map((s, i) => {
      const x = 10 + i * 68;
      return (
        <g>
          <rect x={x} y={14} width={52} height={32} fill={s.c} stroke="var(--color-ink)" stroke-width="3" />
          <text x={x + 26} y={30} text-anchor="middle" font-family="Inter, sans-serif" font-weight="900" font-size="13" fill="var(--color-ink)">{s.k}</text>
          <text x={x + 26} y={41} text-anchor="middle" font-family="JetBrains Mono, monospace" font-size="7" letter-spacing="1" fill="var(--color-ink)" opacity="0.8">{s.t}</text>
          {i < stages.length - 1 && (
            <line x1={x + 54} y1={30} x2={x + 64} y2={30} stroke="var(--color-ink)" stroke-width="2.5" marker-end="url(#iraf-mini-arr)" />
          )}
        </g>
      );
    })}
    <path d="M 246 56 C 246 72, 36 72, 36 56" stroke="var(--color-ink)" stroke-width="2.5" fill="none" stroke-dasharray="3 3" marker-end="url(#iraf-mini-arr)" />
    <text x="140" y="82" text-anchor="middle" font-family="JetBrains Mono, monospace" font-size="8" letter-spacing="2" fill="var(--color-ink)" opacity="0.55">cycle returns to intent</text>
  </svg>
</div>