generated from coulomb/repo-seed
Adds all Phase 0 content that was created but never committed: - CLAUDE.md and SCOPE.md — agent and developer orientation - specs/TailwindForInteractionHubs_v0.2.md — IHF Tailwind coding guide - docs/ — five IHP v1.5 reference guides (overview, data, controllers, realtime, ihf-mapping) - workplans/IHUB-WP-0001 — Phase 1 implementation plan (12 tasks, state-hub synced) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
290 lines
9.3 KiB
Markdown
290 lines
9.3 KiB
Markdown
# Tailwind for Interaction Hubs
|
||
|
||
**Agentic Coding Best-Practice Guide**
|
||
*For building governed, observable, antifragile hub interfaces with Tailwind + IHP*
|
||
|
||
**Version:** 0.2 (Agent-Optimized)
|
||
**Status:** Production-Ready Reference
|
||
**Audience:** Human developers **and** coding agents (LLMs)
|
||
**Framework:** IHP (Integrated Haskell Platform) + Interaction Hub Framework (IHF) layer
|
||
**Date:** March 2026
|
||
|
||
---
|
||
|
||
## 0. Quick-Start for Coding Agents (READ THIS FIRST)
|
||
|
||
When you receive a UI task for an Interaction Hub:
|
||
|
||
1. **Semantic first** — Never start with classes. Ask: “What IHF primitive/widget does this map to?”
|
||
2. **Import hierarchy** — Always `import Web.View.IHF.Primitives`, `Web.View.IHF.Widgets`, `Web.View.IHF.Classes`.
|
||
3. **Use wrappers** — Render via `widgetFrame`, `signalBadge`, `hubActionButton`, etc.
|
||
4. **Token roles only** — Reference `surfaceBase`, `signalSuccess`, `focusRing` (defined in `Theme.hs`).
|
||
5. **No raw soup** — If you see >8 utility classes in one element, extract to a helper.
|
||
6. **Document for reproducibility** — Every new primitive gets Haddock + example HSX.
|
||
|
||
This guide is your single source of truth. Follow it → zero drift.
|
||
|
||
---
|
||
|
||
## 1. Purpose
|
||
|
||
This guide makes **Tailwind the shared visual grammar** for all Interaction Hubs built on IHP + IHF, while keeping the **IHF semantic model** (Widget, Panel, SignalBadge, etc.) as the architectural control point.
|
||
|
||
It guarantees:
|
||
- Perfect visual coherence across hubs
|
||
- Zero CSS entropy
|
||
- Agent-reproducible styling (no folklore)
|
||
- Governed evolution via semantic contracts
|
||
- Full compatibility with IHP’s server-rendered HSX, partial updates, and future islands
|
||
|
||
**Tailwind is the substrate. IHF widgets are the product.**
|
||
|
||
---
|
||
|
||
## 2. Core Principle (Agent Rule #1)
|
||
|
||
```hs
|
||
-- ALWAYS do this
|
||
widgetFrame widget content
|
||
|
||
-- NEVER do this
|
||
<div class="rounded-xl border border-slate-700 bg-slate-900/80 px-4 py-3 shadow-sm ...">
|
||
```
|
||
|
||
**Architecture layers (enforced order):**
|
||
|
||
1. **IHF Semantic Model** (`Widget`, `HubPanel`, `CommentThread`…)
|
||
2. **Visual Primitive Contracts** (`Primitives.hs`)
|
||
3. **Tailwind Token Application** (centralized in `Classes.hs` + `tailwind.config.js`)
|
||
4. **Screen Composition**
|
||
|
||
---
|
||
|
||
## 3. IHP + Tailwind Setup (Mandatory Baseline)
|
||
|
||
Follow the official IHP Tailwind guide, then apply these IHF extensions:
|
||
|
||
### Required Files (exact locations)
|
||
|
||
```text
|
||
Project Root
|
||
├── tailwind/
|
||
│ ├── tailwind.config.js ← extend with IHF tokens
|
||
│ └── app.css
|
||
├── Web/View/IHF/
|
||
│ ├── Theme.hs ← semantic roles
|
||
│ ├── Tokens.hs ← spacing/radius/shadow maps
|
||
│ ├── Classes.hs ← reusable class builders
|
||
│ ├── Primitives.hs ← surface, panel, badge, button…
|
||
│ ├── Widgets.hs ← widgetFrame, inspectorPanel…
|
||
│ ├── Patterns.hs ← triageDashboard, decisionBoard…
|
||
│ ├── AnnotationUI.hs
|
||
│ └── GovernanceUI.hs
|
||
├── Web/View/CustomCSSFramework.hs ← IHP component override (required for JIT)
|
||
└── Config/Config.hs ← option customTailwind
|
||
```
|
||
|
||
**Key tailwind.config.js snippet (add to IHF theme):**
|
||
|
||
```js
|
||
theme: {
|
||
extend: {
|
||
colors: {
|
||
surfaceBase: "hsl(var(--surface-base))",
|
||
signalSuccess: "hsl(var(--signal-success))",
|
||
// … all roles from Theme.hs
|
||
},
|
||
spacing: { /* baseline rhythm */ },
|
||
}
|
||
}
|
||
```
|
||
|
||
**CustomCSSFramework.hs** must expose `customTailwind` with Tailwind classes for all IHP form/button/flash helpers.
|
||
|
||
---
|
||
|
||
## 4. Recommended Layer Model (Agent Reference)
|
||
|
||
| Layer | Name | Lives In | Example Functions | Purpose |
|
||
|-------|-----------------------------|-------------------|---------------------------------------|---------|
|
||
| A | Semantic Interaction | Widgets.hs / Types | `widgetFrame`, `commentRail` | What it *is* |
|
||
| B | Visual Primitive | Primitives.hs | `panel`, `signalBadge`, `actionButton` | Reusable building blocks |
|
||
| C | Tailwind Utility Application| Classes.hs | `panelClasses`, `badgeVariant` | Actual classes |
|
||
| D | Screen Composition | Patterns.hs | `triageDashboard` | Workflow views |
|
||
|
||
---
|
||
|
||
## 5. Golden Rules for Agents
|
||
|
||
- **Rule 1**: Every visual element must have a named Haskell wrapper (no raw `<div class="…">` longer than one line).
|
||
- **Rule 2**: All color/spacing decisions go through `Theme.hs` roles.
|
||
- **Rule 3**: Variant logic must be exhaustive and named (`primary | ghost | danger`).
|
||
- **Rule 4**: Commentability is first-class — every widget primitive exposes `commentable :: Bool`.
|
||
- **Rule 5**: Before writing any new class string, check `Classes.hs`. If missing, add it there with documentation.
|
||
|
||
---
|
||
|
||
## 6. Visual Language & Tokens (Copy-Paste Ready)
|
||
|
||
### 6.1 Color Roles (Theme.hs)
|
||
|
||
```hs
|
||
surfaceBase, surfaceRaised, surfaceMuted,
|
||
borderSubtle, borderStrong,
|
||
textPrimary, textSecondary, textMuted,
|
||
signalInfo, signalSuccess, signalWarning, signalDanger,
|
||
focusRing, commentAccent, policyAccent, outcomeAccent
|
||
```
|
||
|
||
Map these to CSS variables in `tailwind/app.css` `@layer base`.
|
||
|
||
### 6.2 Spacing Rhythm (Tokens.hs)
|
||
|
||
```hs
|
||
space1, space2, space3, space4, space6, space8, space12, space16
|
||
```
|
||
|
||
Use only these. Arbitrary values are forbidden.
|
||
|
||
### 6.3 Radius & Shadow
|
||
|
||
```hs
|
||
roundedPanel = "rounded-xl"
|
||
roundedBadge = "rounded-lg"
|
||
shadowLight = "shadow-sm"
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Core Primitives (Primitives.hs — Starter Template)
|
||
|
||
```hs
|
||
-- Example: panel
|
||
panel :: [Attribute] -> Html -> Html
|
||
panel attrs content = div!
|
||
( [ class_ (panelClasses <> " " <> unwords (map renderAttr attrs))
|
||
, role_ "region"
|
||
] )
|
||
content
|
||
|
||
panelClasses :: Text
|
||
panelClasses = "bg-surfaceBase border border-borderSubtle rounded-xl shadow-sm px-4 py-3"
|
||
|
||
-- Example: signalBadge
|
||
signalBadge :: SignalStatus -> Html
|
||
signalBadge status = span!
|
||
[ class_ (badgeVariant status) ]
|
||
[ text (statusLabel status) ]
|
||
```
|
||
|
||
All primitives follow this exact signature pattern.
|
||
|
||
---
|
||
|
||
## 8. Widget-Centered Rules (IHF Core)
|
||
|
||
Every `Widget` **must** render via `widgetFrame`:
|
||
|
||
```hs
|
||
widgetFrame :: Widget -> (Widget -> Html) -> Html
|
||
widgetFrame w inner = div!
|
||
[ class_ widgetFrameClasses
|
||
, dataAttribute "widget-id" (widgetId w)
|
||
, dataAttribute "commentable" (show $ isCommentable w)
|
||
] $ do
|
||
widgetHeader w
|
||
inner w
|
||
widgetFooter w
|
||
```
|
||
|
||
State cues (inspectable, commentable, in-flight) use **one** consistent visual language (header accent + badge + subtle background shift).
|
||
|
||
---
|
||
|
||
## 9. Agent-Friendly Practices
|
||
|
||
### 9.1 Component Creation Protocol (Mandatory)
|
||
|
||
When creating a new primitive:
|
||
|
||
1. Add to `Primitives.hs` with full Haddock:
|
||
```hs
|
||
{-# LANGUAGE OverloadedStrings #-}
|
||
-- | A governed action button. Variants map to IHF policy levels.
|
||
actionButton :: ActionVariant -> Text -> Html
|
||
```
|
||
2. Define variant type in `Types.hs`.
|
||
3. Implement class builder in `Classes.hs`.
|
||
4. Add example usage in `docs/Examples.hs`.
|
||
5. Update `Short Operational Checklist` (section 26).
|
||
|
||
### 9.2 Prompt Template for Future Agents
|
||
|
||
> “Generate an IHF widget for X using only primitives from Web.View.IHF. Use semantic roles from Theme.hs. No raw Tailwind soup. Include comment affordance.”
|
||
|
||
---
|
||
|
||
## 10. Anti-Patterns (Hard-Coded Agent Rejection Rules)
|
||
|
||
- Utility soup longer than 6 classes
|
||
- Screen-local button/panel/badge reinvention
|
||
- Literal color names in component signatures
|
||
- Mixed density without system-level justification
|
||
- Styling logic inside business controllers
|
||
- Any custom CSS outside `tailwind/app.css` `@layer components`
|
||
|
||
---
|
||
|
||
## 11. Forms, Tables, Annotations, Governance (IHF-Specific)
|
||
|
||
- **Forms**: Use `styledFormGroupClass` from `CustomCSSFramework.hs` + `fieldWithPolicyNote`.
|
||
- **Tables**: Standardized `sortableTable` in `Patterns.hs` with actor/timestamp/state columns.
|
||
- **Annotations**: First-class `annotationThread` + triage variants (`open | reviewed | policySensitive`).
|
||
- **Governance**: `decisionBanner`, `policyScopeBadge`, `traceabilityChain` — all with built-in comment hooks.
|
||
|
||
---
|
||
|
||
## 12. File & Module Organization (Exact)
|
||
|
||
See section 3. All IHF UI lives under `Web/View/IHF/`.
|
||
Import graph is strict: `Patterns.hs` → `Widgets.hs` → `Primitives.hs` → `Classes.hs` → `Theme.hs`.
|
||
|
||
---
|
||
|
||
## 13. Rollout Phases & Minimum Standard
|
||
|
||
**Phase 1 (MVP)**: Theme + Tokens + Primitives (panel, button, badge, widgetFrame)
|
||
**Phase 2**: AnnotationUI + GovernanceUI
|
||
**Phase 3**: Hub-specific accents + adaptive patterns
|
||
|
||
**Every new component** must ship with:
|
||
- Purpose
|
||
- Type signature
|
||
- Allowed variants
|
||
- Accessibility notes
|
||
- Commentability behavior
|
||
- Example HSX
|
||
|
||
---
|
||
|
||
## 14. Short Operational Checklist (Agent + Human Merge Gate)
|
||
|
||
Before any PR/merge:
|
||
- [ ] Semantic name used
|
||
- [ ] Imported only from IHF modules
|
||
- [ ] Classes composed via `Classes.hs`
|
||
- [ ] State signaling matches existing system
|
||
- [ ] Focus + contrast + color+icon rule satisfied
|
||
- [ ] Comment affordance present where applicable
|
||
- [ ] No custom CSS added
|
||
- [ ] Agent reproduction test passed (copy-paste into new context works)
|
||
|
||
---
|
||
|
||
## 15. Motto
|
||
|
||
**“Use Tailwind for expression. Let IHF widgets define meaning.”**
|
||
|
||
This guide is the contract between humans and agents. Follow it and Interaction Hubs stay coherent, evolvable, and antifragile forever.
|
||
|