Files
inter-hub/specs/TailwindForInteractionHubs_v0.2.md
tegwick 8b6ce5bbc8 docs: add specification, reference docs, workplan, and agent guidance
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>
2026-03-27 02:07:13 +01:00

290 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 IHPs 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.