---
name: redfish-style
description: "The Redfish house style: Pantone 180 on warm paper, Swiss/Harvard-GSD restraint, and a standing rule to avoid the AI-UI look, which is a visual tell exactly as em dashes are a prose tell. Carries the UX doctrine too: direct interaction, action signed on the interface (Norman), design the transitions (Buxton), surface the affordances relevant to this user now (Gibson). Pull BEFORE writing the first line of CSS or laying out any screen."
---

# Skill: redfish-style

**Status:** v0.3.0, initialized 2026-07-20 on Stephen's directive. This is a *developing* style: "develop is something over time as we evolve our own style and taste." Treat this file as the current state of an evolving house taste, not a frozen brand manual. Amend it with a dated entry when taste moves.

> **AMENDMENT v0.3.0 — 2026-07-28 — DE-WARMED TO NEUTRAL (Stephen).** Verbatim: *"i hate brown. i've given you feedback black, shades of gray and pantone red and confirmed your css style."* The v0.1–0.2 tokens carried a **warm cast** — warm paper `#faf9f7`, warm near-black, and a warm-dark `#14130f` ground that **renders as brown**, especially full-bleed on a dark-set OS. **That warm was never instructed:** the init below said `pantone-180, clean harvard-gsd-style with minimalism, conservative use of colour, san serif` — GSD is neutral. An agent warmed the neutrals on its own; it read as an AI-adjacent brown-dashboard and undercut the brand. Fixed in [redfish-style.css](redfish-style.css) v0.3.0: all grays are **equal-RGB neutral**, dark ground is **true near-black `#121212`** (no brown), the **only hue is Pantone 180 `#be3a34`**.
>
> **Two rules this makes explicit (they were the failure modes):**
> 1. **No warm, no brown. Grays are neutral (R=G=B).** The palette is *black, shades of gray, and Pantone 180* — nothing else. If a ground reads brown/tan/cream, it is wrong.
> 2. **Dark mode is not automatic, and it is not the brand.** The house face is the light neutral GSD look. If a page honors `prefers-color-scheme: dark`, the dark ground MUST be neutral near-black and the accent budget still holds — **one live thing per view** (a full-bleed instrument that lights up the path *and* a readout *and* a selected row *and* a toggle *and* a slider in red is five, not one; that compounded the brown-with-red). When in doubt, present the light neutral face to everyone.

> **Stephen, verbatim (2026-07-20):**
> `ask debbie [ make-default avoid-AI-UI-style ; there is a look and feel that is a tell like em-dashes for language / develop redish-default-style ; develop is something over time as we evolve our own style and "taste" / init-redfish-style { UI: pantone-180, clean harvard-gsd-style with minimalism, "conservative use of color", "san serif fonts"; UX: "direct-interaction" ; minimize disconnected menus and buttons, "action signed on the interface" ; norman interface, "design for the transitions" ; buxton, "present the affordances relevant to user" ; gibson sense affordance. much deeper than norman } ]`

**Files:** [`redfish-style.css`](redfish-style.css) (the tokens and element defaults) · [`index.html`](index.html) (the live specimen: read the rendered page, not just this doc).

**Relationship to [sketch-ux](../sketch-ux/SKILL.md):** sketch-ux is the *method* (fan first, then funnel). This is the *material*: what the funnel's output should look and behave like. Sketches may be rough; they should still be rough in this house's idiom rather than someone else's.

---

## 1. Avoid the AI-UI style (the standing default)

Stephen's framing is exact: **there is a look and feel that is a tell, like em dashes are for language.** The em-dash rule in [.ai/conventions.md](https://redfish.acequia.io/.ai/conventions.md) exists because a certain punctuation habit marks text as machine-produced regardless of its quality. The same has happened to interfaces. A generation of generated UI converged on one costume, and wearing it says "nobody chose this" before a reader has read a word.

This is not a claim that those choices are ugly. It is a claim that they are **unchosen**, and unchosen is the thing we are avoiding.

### The tells, and what this house does instead

| The tell | Instead |
|---|---|
| Indigo/violet to blue **gradient**, especially `#6366f1 → #a855f7`; gradient text via `background-clip` | One flat accent, [Pantone 180](https://www.pantone.com/) `#BE3A34`, on warm paper. No gradient anywhere, including text |
| **Glassmorphism**: translucent panels, heavy `backdrop-filter`, milky white borders | Opaque ground; a recessed well (`--rf-ground-sunk`) when a figure needs separating |
| **Rounded everything**, 12 to 16px radius on every surface | Square. `--rf-radius: 2px` is the ceiling |
| **Card grid of three features**, each with a circled icon | Rules and space. `.rf-panel` is a hairline and a margin |
| **Emoji as section markers** (🚀 ✨ 🎯) | Words. If a mark is needed, a rule or a number |
| **Dark slate-navy** `#0f172a` + Tailwind slate ramp | **Neutral** near-white `#fafafa` and neutral near-black `#141414`; dark mode is true near-black `#121212`. Grays are equal-RGB — no warm/brown cast, no blue-grey. The single hue is Pantone 180. |
| **Inter / Geist / Plus Jakarta** at default tracking | A neutral grotesque: Helvetica Neue, Helvetica, Arial. Boring on purpose, and Swiss rather than startup |
| **Glow and coloured drop shadows** | No shadows. Depth from rules, ground value, and space |
| **Pill badges** with soft tinted backgrounds | `.rf-label`: small, uppercase, tracked, quiet |
| Centered hero, giant gradient headline, **"Get Started" + "Learn More" pair** | Left-aligned, real title, real first sentence. If there is one action, one control |
| **Everything fades up on scroll**, uniformly | Motion only where a quantity is actually changing (see §3) |
| Neon accent on dark (`#2ee06a` and kin) as "technical" | Accent is Pantone 180 and it marks the live thing, not the mood |

**Honest self-audit, recorded so this rule has teeth.** The [computational-physics page](https://redfish.acequia.io/guerin/apps/computational-physics/) shipped 2026-07-20 (v0.1.0 through v0.4.0) carries several of these tells: slate-navy ground, neon-green accent, rounded panels, tinted left-border callouts. It was built before this skill existed. It is the first candidate for restyling, and it is cited here rather than quietly excluded, because a style rule whose author exempts their own recent work is not a rule.

### The positive statement

**Harvard GSD / Swiss International Typographic**, applied to screens: a real grid, generous margin, hierarchy from type size and weight rather than colour, hairline rules instead of containers, one accent used sparingly, and content forward with ornament absent. The page should look like it was *set* rather than *assembled from components*.

**Conservative use of colour** has a precise operational meaning here: **colour is information, never decoration.** On any given view, the accent marks the one thing that is live, selected, or being argued about. If two things are accented, one of them is wrong. Data visualisation is the single exception, and it draws from `--rf-data-1..6`, never from the chrome palette (see [dataviz](https://redfish.acequia.io/skills/) for the encoding rules that still apply on top of this).

---

## 2. UX doctrine

The four UX directives, in the order Stephen gave them, each with what it actually forbids. These are load-bearing and they are the reason the visual rules above are cheap to follow: a restrained surface leaves room for the interaction to be the design.

### 2a. Direct interaction

> *"minimize disconnected menus and buttons"*

**Act on the thing, not on a panel beside the thing.** A control that lives away from the object it governs forces the user to hold a mapping in their head, and that mapping is the interface's failure showing through. Drag the nest to move the nest. Scrub the trail to change the time. Pull the boundary to move the boundary.

- Prefer manipulating the object; fall back to an adjacent inline control; use a detached panel last and treat it as debt.
- If a slider must exist, put it **against the thing it drives**, and make the thing respond continuously while dragging, not on release.
- A menu of verbs the user must translate into effects is the worst case. Two "Learn More"-shaped buttons under a hero is the same failure in marketing costume.
- Corollary from the [interaction-first layout rule](https://redfish.acequia.io/guerin/.agents/07eb1ef7-0848-478f-b3e9-6cfa5ddec5cc/2026-07-20/notes/04-layout-critique-interaction-first.md) (ratified 2026-07-20): rank the interactions first, then let layout put rank 1 at the strongest position.

### 2b. Action signed on the interface (Norman)

> *"norman interface"*

Every available action carries a **perceptible signifier**, and every performed action produces **immediate visible feedback**. [Norman](https://en.wikipedia.org/wiki/The_Design_of_Everyday_Things)'s point in its sharp form: the interface must *say* what it affords and must *confirm* what it did.

- Anything draggable looks draggable and says so on hover (cursor, a grip, a hairline that lifts).
- Every action changes something visible inside 100 ms. A control that fires with no echo is broken even when the underlying function worked.
- State is legible without clicking: what is on, what is selected, what is running, what is stale.
- No mystery meat. If a reader must click to discover what a control does, the signifier is missing.

### 2c. Design for the transitions (Buxton)

> *"buxton"*

The design lives in the **change between states**, not in the states. [Buxton](https://www.billbuxton.com/) is already the house method in [sketch-ux](../sketch-ux/SKILL.md) ("sketch the transitions, not just the states"); here it becomes a build rule.

- **Morph, never cut** (standing rule, 2026-07-10). A hard swap between views is a context break the user must repair. Interpolate, and give them control of the lerp where feasible.
- Name the transition when you design a screen: before, action, after. If you cannot describe the middle, you have designed two pictures rather than an interaction.
- Durations are `--rf-t-quick/base/slow` (120/200/340 ms). Longer than 340 ms for a UI response is a delay wearing a costume.
- **Every moving pixel is owed to a driven quantity.** Decorative motion is chartjunk with a clock.

### 2d. Present the affordances relevant to the user (Gibson)

> *"gibson sense affordance. much deeper than norman"*

Stephen is right that this is the deeper claim, and the depth is worth stating precisely because the two ideas are routinely collapsed.

[Norman's](https://jnd.org/affordances_and_design/) affordance (properly, his *signifier*) is a **communication** problem: does the interface successfully advertise what can be done? [Gibson's](https://en.wikipedia.org/wiki/Affordance) affordance is an **ontological** one: an affordance is a real relation between an animal and its environment, an action possibility that exists relative to that animal's capabilities whether or not anyone perceives it. A surface affords climbing for a creature with this leg length, carrying this load, with this intention. The affordance is not in the surface and not in the animal but in the pairing.

What that buys us as a build rule, beyond Norman:

- **Affordances are relative to the actor.** The same view offers different real possibilities to a student, a responder, and a researcher. The interface should present the set that is genuinely actionable *for this user*, not a universal superset with the rest greyed out.
- **Affordances are relative to the moment.** They shift as the task state shifts. A control that is meaningless until data loads should not merely be disabled: it should be absent, and it should *arrive* (via a transition, per 2c) at the moment it becomes real.
- **Perception is active and exploratory.** Gibson's perceiver moves in order to pick up information. So reward exploration: hover, drag, and scrub should *reveal* structure rather than merely trigger effects.
- **Design the information the environment offers**, not the labels. Direct perception means the state of the system should be readable off its appearance, so a well-shaped visualization can remove a paragraph of explanation and a row of controls at once.

The practical test: **count the affordances presented against the affordances actually available to this user right now.** A large gap in either direction is the bug. Too many is noise that buries the real one; too few is a capability the user cannot discover. Norman asks "is it advertised?" Gibson asks "is it actually there, for *them*, now?" We owe both answers, and the Gibson one first.

---

## 3. Applying it

1. Link the stylesheet, then write plain semantic HTML. If a page needs a pile of custom CSS to look right, the deviation is the thing to examine.
2. Wrap in `.rf-page`, keep prose inside `.rf-measure`, put canvases in `.rf-figure`.
3. Use `.rf-label` for eyebrows, `.rf-lede` for the opening sentence, `.rf-readout` for live numbers off a simulation (changing values take the accent).
4. Accent budget: **one live thing per view.**
5. Every deployed page carries the provenance footer (`.rf-footer`) with the Source link to the authoring bead, per the [standing devops default](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/about.md).
6. Font floor is hard: 15px body minimum, 14px controls minimum, nothing below 13px.
7. Check `prefers-reduced-motion` and `prefers-color-scheme`; both are handled in the stylesheet, but any JS animation must check the first itself.

## 4. Map-site chrome (standing default, 2026-07-21)

> **Stephen, verbatim (2026-07-21, venice-traffic feedback):** *"html map sites should be full
> viewport by default with ui panels that open and close. any headers at top of page should be
> minimal. include redfish logo … in the standard redfish-style. consider keeping a redish house
> CSS linked to we can reskin all redfish sites. always include a fullscreen toggle button and
> hide UI option"*

Rules, for every Redfish site whose subject is a map (or any full-bleed instrument):

1. **The map IS the page.** Full viewport (`.rf-map-page` + `.rf-map`); no page scroll. Everything
   else is an overlay (`.rf-overlay`) that opens and closes; a panel the user cannot dismiss is a
   header wearing a costume.
2. **Headers are minimal:** a `.rf-logo-chip` (the
   [redfish logo](https://redfish.com/images/redfishLogo_onBlack_128.png), on its ink chip so the
   on-black asset works on both schemes, linking home), a short title, a version — nothing else at
   top-level. Source / Sketches / provenance move into the panel or footer strip.
3. **Always: a fullscreen toggle and a hide-UI control** (`.rf-fab` pair, top-right). Hide-UI
   withdraws everything tagged `.rf-ui` but the restore control stays perceivable
   (`.rf-ui-restore`, quiet until hovered) — Gibson: the way back must remain a real, perceptible
   affordance. Data attribution (e.g. Leaflet's ODbL line) never hides.
4. **The skin is LINKED, the behavior is VENDORED.** Reference this stylesheet at its canonical
   URL (`https://redfish.acequia.io/skills/redfish-style/redfish-style.css`) so one edit here
   reskins every site — reskinnability is the point, so the usual vendor-against-drift rule is
   deliberately inverted for the *skin only*. Components (layer-tree etc.) stay vendored +
   conformance-checked. A site that cannot tolerate a skin hiccup may keep a vendored fallback
   file, but the link comes first.

5. **The timeline is ONE shared web component, docked at the BOTTOM** (Stephen, 2026-07-23:
   *"make timeline a webcomponent shared over web apps with time / put it on the bottom"*). Every
   app with time mounts the same component under the map, not a bespoke canvas. Its design
   converges through the
   [shared-timeline fan](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/2026-07-23/artifacts/sketches/timeline-fan/index.html)
   (window navigation from incident-viewer · drop-assertion records from
   [set-space-time](https://santafe.live/set-space-time/index.html) · layer-mirrored channels +
   collapse-to-heatmap from camera-grid · duration-bar/twirl idioms from the animation-tool
   forage); the existing `<redfish-timeline>` v0.3.0 is the seed, superseded when the fan's
   winner ships. Like the layer panel, the component's canonical home is Debbie's bead
   `web-components/`; consumers vendor it (behavior) while linking the skin.

   **Added 2026-07-24 (incident-viewer feedback, Stephen verbatim: *"timeline should be
   collapsed by default until we want to look at all the selected channels"*): the docked
   timeline is COLLAPSED by default.** It first appears as a slim labeled bar (extent, playhead,
   channel count) and expands only when the user opens it to inspect the selected channels.
   Expansion state is the user's, never the page's: the app may remember the choice within a
   session, and it never re-expands or re-collapses on its own.

6. **Simulation layers are agents with a lifecycle** (Stephen, 2026-07-23). A simulation layer's
   properties window always carries: its **control parameters**, a **Setup (reset)** action, and
   **configurable links to the layers it depends on** (venice-traffic's boat-sim ⟵ Canal network
   is the type case), presented in the NetLogo/bead grammar — **Startup · Setup · Step**. The
   fuller vision — an in-properties code IDE where editing Step hot-swaps the running sim, and
   applied edits become commits against the git-in-bead repo (with permission) or forks to the
   user's own bead (without) — is **deliberately unimplemented**: the properties window presents
   the lifecycle and links to the
   [sim-layer IDE fan](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/2026-07-23/artifacts/sketches/sim-layer-ide-fan/index.html)
   where the design is being decided.
7. **The basemap is a layer** (Stephen, 2026-07-23): it gets **opacity and visibility on/off like
   every other layer** — a first-class row in the layer tree, not chrome-only. The basemap
   *switcher* picks which; the tree row governs whether and how much.

8. **Camera controls are consistent, and navigation is a different scheme from
   editing/calibrating** (Stephen, 2026-07-24, storymap program, verbatim: *"use consistent
   camera controls for nagivation and another for editing/calibrating"*). Every Redfish surface
   uses ONE house scheme for **navigation** (orbit / pan / zoom over a map or 3D viewport, the
   same bindings whether the engine is taos-engine or Leaflet) and a second, visibly distinct
   scheme for **editing/calibrating** (setting camera poses, placing items in space-time,
   through-the-lens calibration). The two must not share ambiguous bindings: a drag that orbits
   in one app must not place a marker in another. Mode is signed on the interface (Norman): the
   surface always shows which scheme is live, and edit-mode controls arrive by transition when
   the mode becomes real (Gibson), rather than sitting disabled. Design converging in the
   [storymap fan](https://redfish.acequia.io/guerin/.agents/019f9544-d64f-70b9-a84f-339a419b0ea9/2026-07-24/artifacts/sketches/storymap-fan/index.html).
9. **Scroll ownership: the wheel belongs to the surface under the pointer** (Stephen,
   2026-07-24, same program, verbatim: *"for story map, scrollwheel should zoom camera when
   mouse is over taos-engine or leaflet viewport. and then scroll wheel the story when over
   that div"*). Over a camera viewport (taos-engine, Leaflet, any WebGL pane) the scrollwheel
   zooms the camera; over a story or prose panel it scrolls that panel's content. Corollaries:
   no page-level scroll hijack (the page does not scroll under a full-viewport instrument, per
   rule 1); no scrolljacking (wheel over the story never drives the camera as a side effect;
   the story advances the camera only through its own step/slide bindings); the boundary is the
   pointer's hover surface, so the split is legible without explanation and costs zero chrome.

10. **Overlay panels carry minimize-tabs** (Stephen, 2026-07-24, incident-viewer feedback,
    verbatim: *"use house-style [hide ui. layer-panel should have a minimize-tab. timeline
    should too."*). Every §4 overlay (layer panel, timeline, story/dossier panels) has a
    persistent slim tab (`.rf-min-tab`) that collapses the panel down to the tab and restores
    it from there; `.rf-collapsed` is the state helper. Minimize is the per-panel form of the
    hide-UI contract in rule 3: hide-UI still withdraws everything except the restore control,
    and a minimized panel's tab remains perceivable at all times (Gibson: the way back is
    always visible). Collapse and restore are designed transitions (§2c), never a hard cut,
    and the JS honors `prefers-reduced-motion`.

11. **Timeline axes label absolute time as UTC date + hour by default** (Stephen, 2026-07-24,
    verbatim: *"i need to see UTC date and hour on the timeline with option to display timezone
    date-time (note issues with daylight savings overlaps whre you may have to repeat and hour
    or 'hide an hour'"*). The default axis reads UTC date plus hour; a user option switches the
    display to a local timezone's date-time. When the chosen zone crosses a DST transition the
    axis stays honest: the fall-back repeated hour is marked explicitly (e.g. "01:00 again")
    and the spring-forward skipped hour is shown as a labeled gap, never silently folded into a
    uniform ruler. An axis that lies about an hour lies about every event inside it.

First application: [venice-traffic v0.4.0](https://redfish.com/venice-traffic/). Conformance debt,
tracked in their beads: stac-workbench, nm-land, viewshed-viewer, camera-grid.
**alert.live conformed 2026-07-24** (site v1.4.0 + /join/ + /incidents/, linked skin, content
frozen; [bead `3ebb74a5` note 10](https://redfish.acequia.io/guerin/.agents/3ebb74a5-fd48-4b8c-8644-82d6a4b28492/2026-07-24/notes/10-redfish-style-conformance-pass.md)) —
a landing page, so §1–3 applied; the §4 map chrome was out of scope.
Rules 8 and 9 first apply to the storymap design
([bead `019f9544-d64f`](https://redfish.acequia.io/guerin/.agents/019f9544-d64f-70b9-a84f-339a419b0ea9/about.md));
the [Chelan story](https://simtable.acequia.io/incidents/2026-WA-Chelan-Hills-Fire-Entrapment/story/)
is the audit target among existing pages.

## 4b. Long-running agent work carries a monitoring dashboard (standing default, 2026-07-27)

**Stephen, verbatim (2026-07-27, inside `ask debbie [ house-style [ … ] ]` during the zoom-room epic):**
> *"for long running tasks like this provide a monitoring agent interactive dashboard. interactive means sketches and questions can be raised to me along the way and i can see discussions between agents. make it visual. you did this once in past. make links for artifacts you build. and allow me to playback logs like you did in the past"*

Any task that dispatches a fleet of agents, or runs long enough that the human is left waiting,
**ships a monitoring dashboard as part of the work, not as an afterthought.** The precedent this
amends into a standing rule is the [construction replay](https://redfish.acequia.io/guerin/.agents/c2ca1e60-1c8c-4bfa-a55d-2f82ef0aa796/2026-07-09/night-session/replay.html)
built for the first glass bead game, and the
[monitor-agents fan](https://redfish.acequia.io/guerin/.agents/45761f53-0f16-4bba-87db-d7edb3a25d0c/2026-07-19/artifacts/sketches/monitor-agents-fan/index.html)
on the agents-dashboard bead. Both were one-offs; from here they are the default.

12. **Provide a monitoring dashboard for fleet or long-running work.** Six requirements, each of
    which failed at least once by being absent:
    - **Visual, not a log tail.** Agents are objects with position and state. A lane, a swimlane, a
      board: something a glance reads. Text-only progress is the failure mode this rule exists to kill.
    - **Discussions between agents are visible.** When one agent's output becomes another's input,
      that edge is drawn and its payload is readable. A fleet the human cannot watch talk to itself
      is a black box wearing a progress bar.
    - **Questions reach the human mid-flight.** An agent that hits a real fork raises it to a queue
      on the dashboard rather than guessing and reporting later. Every question obeys the
      [questions-are-request-forms rule](https://redfish.acequia.io/.ai/conventions.md): multi-select
      checkboxes with an Other/notes affordance, never a single-select radio.
    - **Sketches are raised the same way**, so a design fork is answered while it is still cheap
      (sketch-ux: fan first). A sketch that arrives after the build is a post-mortem.
    - **Every artifact built is linked** from the dashboard, at its canonical URI, runnable per the
      run-vs-edit rule. The dashboard is the index of the run.
    - **Logs play back.** The run is scrubbable after the fact on one timeline, at the granularity of
      per-agent events, because the interesting question is almost always "what happened at the point
      where it went wrong."
    Colour still obeys §1: the accent marks the live agent, and nothing else.

### The corrections (2026-07-27, same day, after Stephen rejected the first build)

Rule 12's first instance shipped with four defects, three of which broke rules already written down.
Stephen's critique, verbatim: *"in a previous sketch critique, i gave you feed back of a timeline
wipe is a waste of interaction. use timeline webcomponent. with collapsing. group the agents. this
is a kind of incident-viewer. also use more grateful dead n-partite transitions. agents working on
concepts in talk, speakers (stephen, manav). map, artifacts, other beads in the hubler network being
deployed. the conversations. the questions"* and *"the text log at bottom is worthless"*. The
failure analysis, including why the earlier critique recurred (it was never written into the
namespace, so it did not exist for the next animator), is
[Debbie's alignment note](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/2026-07-27/notes/01-fleet-monitor-alignment.md).

12a. **No wipes.** A scrub must change what the OTHER panels show. A drag whose only effect is to
     progressively reveal more of the control itself spends the user's most expensive input, a
     sustained aimed gesture, to buy information the screen could already have shown. Nothing is
     learned at T=0.6 that was not visible at T=1.0. That is an animation dressed as a control. If a
     scrub reveals only itself, delete it and show everything.

12b. **Use `<redfish-timeline>`.** Docked bottom, collapsed by default to a slim labelled bar, the
     two-zone grammar (upper band pans, wheel zooms about the cursor, lower band scrubs, needle
     grabbable within 6 px), and `timechange` under process-latest-on-complete. Never hand-roll a
     time axis. The component is [v0.3.0](https://redfish.acequia.io/guerin/.agents/019f71ce-82fe-7239-8659-8cb3cf99180a/2026-07-17/artifacts/viewshed-viewer/lib/redfish-timeline.mjs)
     (upstream `https://redfish.com/track-fabio/redfish-timeline.mjs`); vendor the behaviour per
     §4 rule 4. This restates §4 rule 5 because restating it was cheaper than the rebuild that
     ignoring it cost.

12c. **A fleet monitor is a kind of incident-viewer.** Same shape: a master clock, entities that
     exist over intervals, a layer panel of grouped toggleable layers, and a detail panel bound to
     selection. Agents are grouped into layers the way an incident groups its tracks. Inherit the
     [incident-viewer](https://redfish.acequia.io/guerin/.agents/cbf8b027-e80c-4b9f-8eb3-91d40af072d5/)
     grammar rather than inventing a dashboard idiom.

12d. **Show the graph, not the log.** Inter-agent relations render as an **n-partite graph** over the
     run's real partitions: agents, the concepts they work on, speakers, places, artifacts, the beads
     being written into, conversations, and open questions. The bipartite case was already worked out
     for search in the [orama bead's result-view note](https://redfish.acequia.io/guerin/.agents/6f5044df-cd90-459d-a150-e0250e98039a/2026-06-14/notes/result-view-and-bipartite-graph.md);
     this is that idea with more partitions. **Every edge must be derived from real data**, and a
     partition with nothing in it renders as an empty labelled partition rather than being filled
     with invented nodes. A chronological text tail is not a visualisation of a discussion; it is
     what you write when you have not yet decided what the picture is. It is admissible only inside
     a detail panel, behind a selected node.

12e. **Segue, never cut** (Stephen's phrase: *"grateful dead n-partite transitions"*). The Dead did
     not stop one song and start another; they held a common tone while the material changed around
     it. Changing which partitions are shown **morphs**: nodes present in both arrangements keep
     their identity and travel to their new seats, and only genuinely new material fades in. The
     transition then carries information, because the user can see that the thing they were watching
     is the same thing, now read against a different partition. Same morph-never-cut rule as §2c.

## 4c. What ships and what stays: the deploy is not the workshop (2026-07-27)

**Stephen, verbatim (2026-07-27, `ask debbie [...]`):**
> *"deployed websites should not have design fans or source. those should be in the bead version of the
> app. make redfish house-style / the link to the bead should be in the README.md and links to
> sketches and source can be there. and other processes will descide the beads permissions."*

**Scope first: which origin is this?** (Stephen, same day, correcting the rule below before it
shipped: *"for apps on redfish.acequia.io that is a dev site. different than a customer. its ok and
preferred to have source and sketches on them"*.)

| Origin kind | Examples | Source, sketches, fans on the deploy |
|---|---|---|
| **Dev / working origin** | `redfish.acequia.io`, and the `.agents/` trees generally | **Wanted.** Ship them. The workshop being visible IS the point: a reader lands on the running thing and can walk straight into how it was made. Rule 13 does not apply here. |
| **Customer / public-facing property** | `redfish.com`, `simtable.com`, `anyhazard.live`, `alert.live`, `anyhazard.com`, a client's site | **No.** Rule 13 applies in full. |

Rules 13 to 13c govern the second row only. The distinction is the whole rule: the same directory
listing that is a feature on a dev origin is a liability on a customer's.

13. **On a customer-facing property, a deployed directory contains the running thing and nothing
    else.** The app, its data gates, its vendored libraries, its `README.md`, its access sidecar.
    That is the whole list.

    **Not deployed:** build scripts and generators, sketches and design fans, ballots and their
    results, notes, chat logs, working data the app does not read at runtime, verification harnesses,
    scratch directories, and anything holding a third party's data that the deploy has no business
    republishing. If a file exists to *make* the app rather than to *run* it, it stays in the bead.

13a. **The bead is the workshop and the home of record.** Source, fans, sketches, notes, history and
     the git face live there. A deploy is a **built copy at a serving path**, and the copy is
     regenerable from the bead. This is why the deploy can be thin without losing anything.

13b. **The `README.md` in the deployed directory is the seam.** It already carries the provenance edge
     back to the source bead (devops
     [deployed-app-readme](https://redfish.acequia.io/guerin/.agents/64be6d29-d133-4ade-9dce-f62701003e37/skills/deployed-app-readme/SKILL.md),
     checklist item 3). Ratified here: **the README is also where links to the sketches, the fans and
     the source go.** A reader who wants the design history follows one link; a reader who wants the
     app never trips over it. Nothing is hidden, and nothing ships that need not ship.

13c. **Permissions are decided elsewhere.** The deploy does not reason about who may read the bead.
     Other processes govern that (the access sidecar on the served path, chain tokens and their
     attenuation, the authz mesh). A deploy that starts making access decisions about its own source
     has taken on a job that is not its own.

**Why this is a style rule and not merely hygiene:** a deployed page on a CUSTOMER property that
carries its own design fans is showing that client the workshop floor. It reads as unfinished, it invites the reader to relitigate
decisions already made, and it buries the running thing under its own history. The fan is *for* the
decision; once the decision is cast, the fan's home is the record, reachable by one link and not on
the path. That is the same restraint §1 asks of ornament, applied to process.

**Caught on the day it was written, and then narrowed the same hour.** The rule was drafted absolute
and Stephen corrected its scope before it shipped: the zoom-room deploy targets `guerin/zoom/` on
`redfish.acequia.io`, a **dev origin**, so its source, its `build-board.mjs` and its sketches ship
with it and are wanted there. What still does NOT ship is `face-lab/`, and that exclusion comes from
a different authority: it holds a third party's biometric material, and Stephen's answer to
[question 02](https://redfish.acequia.io/guerin/.agents/019fa560-9c80-7041-b3e9-8560e5413df5/questions/02-manav-biometrics.json)
puts it in the bead pending his conversation with Manav. **Origin kind and data sensitivity are
independent gates, and a file has to clear both.**

## 4d. Camera control: orbit is the house default (2026-07-28)

**Stephen, 2026-07-28**, after driving the [camera-controller fan](https://redfish.acequia.io/guerin/.agents/b28561b2-f9e6-4a2a-88f3-edb06fb262e9/2026-07-28/artifacts/sketches/camera-controller-fan/index.html):
*"i don't like the current camera controller"* → four controllers put on one scene → *"do orbit for now"*.

The reference this ratifies is [`3D-mouse-keyboard-camera-controls` `b28561b2`](https://redfish.acequia.io/guerin/.agents/b28561b2-f9e6-4a2a-88f3-edb06fb262e9/about.md)
(2026-06-17), whose note 07 A.3 named the safe defaults and whose closing line named the failure this
rule exists to stop: **"pick a controller and reuse it, do not let each app invent its own look
button."** It was written six weeks before this amendment and both glass-bead rooms violated it,
each hand-rolling its own azimuth/elevation/radius orbit.

14. **Orbit / Examine is the default camera for any Redfish 3D surface.** The pivot is the thing under
    inspection. Bindings, which are the CAD, DCC and web-viewer consensus:

    | Input | Does |
    |---|---|
    | **left-drag** | orbit the pivot |
    | **wheel** | dolly, **toward the cursor**, not screen centre |
    | **right-drag** | pan the pivot |
    | **F** | frame the scene or the selection |
    | digits · Shift+digit | recall · save a view (the house idiom) |

    Roll stays locked: this is an orbit, not a trackball, so the horizon never tilts.

14a. **Pitch is conventional: drag down looks down.** taos-engine's controller is
     positive-pitch-is-down, so a consumer negates it. **Negate it once, at the controller, and stop
     re-deriving it per app** (note 07 A.4; `taos-recipes` `inverted-pitch-gotcha.md`).

14b. **"For now" is load-bearing, and the real answer is probably a 2x2.** Note 07 A.1 splits the
     space by two questions: *is the user inspecting a thing or inside the scene*, and *is the surface
     flat-ish or fully 3D*. That yields orbit-scene, fly-scene, map-2D, map-2.5D. **Orbit is ratified
     as the default, not as the only mode.** A room the user is meant to stand inside (the SitUnit)
     has a real claim on fly, and anything geographic has a real claim on the map model. An app
     departing from orbit says so and says why; it does not silently invent a third thing.

14c. **One controller, reused.** The binding lives in a shared module, not re-implemented per app.
     Both rooms currently hand-roll it and are the first things to bring onto the shared one.

## 5. Amendment log

- **v0.2.5, 2026-07-27:** sketch-fan house-style ratified — recorded in full in
  [sketch-ux SKILL.md](https://redfish.acequia.io/skills/sketch-ux/SKILL.md) (2026-07-27
  entry) rather than duplicated here, since it's sketch-ux's *method* territory (this file
  stays the *material*): (1) a fan with multiple live sketches lives as **cards on one
  page**, each a readable summary with an `⤢ expand` toggle that pops it to a fixed-overlay
  larger div; (2) answerable-question blocks **clear-on-submit, never reload**; (3) sketches
  under devops version control with a per-version critique-log is **design-only for now**,
  flagged to devops `64be6d29` + domain-manager `c1192f49` for the git-verbs storage side.
  Worked example: [domain-routing-sketches](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/artifacts/domain-routing-sketches/index.html).
- **v0.3.1, 2026-07-28:** §4d added (rule 14: orbit/examine is the house default camera; left-drag
  orbits, wheel dollies to the cursor, right-drag pans, F frames, roll locked; 14a pitch is
  conventional and negated once at the controller; 14b "for now" is load-bearing and the real answer
  is note 07's 2x2; 14c one shared controller, not one per app). From Stephen's *"i don't like the
  current camera controller"* → the [camera-controller fan](https://redfish.acequia.io/guerin/.agents/b28561b2-f9e6-4a2a-88f3-edb06fb262e9/2026-07-28/artifacts/sketches/camera-controller-fan/index.html)
  → *"do orbit for now"*. Ratifies the reference bead
  [`b28561b2`](https://redfish.acequia.io/guerin/.agents/b28561b2-f9e6-4a2a-88f3-edb06fb262e9/about.md),
  whose note 07 said *"do not let each app invent its own look button"* six weeks earlier, and which
  both glass-bead rooms had violated.
- **v0.2.7, 2026-07-27:** §4c added (rule 13: on a **customer-facing** property a deploy carries the
  running thing only, with the README as the seam back to the bead's source, sketches and fans;
  permissions are decided elsewhere). Drafted absolute from Stephen's *"deployed websites should not
  have design fans or source"* and **narrowed by him the same hour**: *"for apps on
  redfish.acequia.io that is a dev site. different than a customer. its ok and preferred to have
  source and sketches on them."* The scope table is therefore the load-bearing part of the rule, and
  the origin-kind gate is independent of the data-sensitivity gate: a file must clear both.
- **v0.2.6, 2026-07-27 (same day, after rejection):** §4b rules 12a-12e added from Stephen's critique
  of the first monitor build. No wipes; use `<redfish-timeline>` collapsed and docked; a fleet monitor
  is a kind of incident-viewer; show the n-partite graph rather than a text log; segue rather than cut.
  The load-bearing lesson is recorded separately in
  [Debbie's alignment note](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/2026-07-27/notes/01-fleet-monitor-alignment.md):
  the wipe critique had been given once before in a sketch review and was never written into the
  namespace, so it recurred. **A design critique that is not written down the same session does not
  exist for the next animator.** New standing practice: critiques land as dated rules before the
  corrected build starts.
- **v0.2.5, 2026-07-27:** §4b added (rule 12: long-running or fleet agent work ships an interactive
  monitoring dashboard — visual, inter-agent discussion visible, questions and sketches raised to the
  human mid-flight as checkbox request-forms, every artifact linked, logs scrubbable). From Stephen's
  `ask debbie [ house-style [ … ] ]` during the zoom-room epic, which named the
  [first-game construction replay](https://redfish.acequia.io/guerin/.agents/c2ca1e60-1c8c-4bfa-a55d-2f82ef0aa796/2026-07-09/night-session/replay.html)
  as the precedent being promoted from one-off to default. First instance built the same day:
  [fleet monitor](https://redfish.acequia.io/guerin/.agents/019fa560-9c80-7041-b3e9-8560e5413df5/repo/zoom-room/monitor/index.html).
- **v0.2.4, 2026-07-24:** §4 rule 5 extended (docked timelines are collapsed by default; a slim
  labeled bar until the user expands it) and rules 10+11 added (overlay panels carry
  minimize-tabs; timeline axes label UTC date + hour by default with a DST-honest local-zone
  option), from Stephen's incident-viewer `house-style` ask. CSS gains `.rf-min-tab` and
  `.rf-collapsed` in the map-chrome block.
- **v0.2.3, 2026-07-24** — §4 rules 8+9 (Stephen's storymap `house-style` ask, the first use of
  the ratified [bead-logo `house-style` verb](https://redfish.acequia.io/guerin/.agents/4c6470f9-b74a-4aba-b436-5e998f469cce/skills/bead-logo/SKILL.md)):
  camera-control consistency with a navigation scheme distinct from editing/calibrating; scroll
  ownership by hover surface (viewport wheel = camera zoom, story wheel = story scroll).
- **v0.2.2, 2026-07-23** — §4 rules 6+7: simulation layers are agents with a lifecycle (params +
  reset + dependency links now; Startup/Setup/Step IDE fan-gated, commit-or-fork ladder); the
  basemap is a layer (opacity + visibility like any other).
- **v0.2.1, 2026-07-23** — §4 rule 5: the timeline is one shared web component, docked bottom;
  design converging in the shared-timeline fan (Stephen's timeline house-rules ask).
- **v0.2.0, 2026-07-21** — map-site chrome added (§4, from Stephen's venice-traffic feedback):
  full-viewport default, `.rf-overlay` panels, `.rf-logo-chip`, `.rf-fab`, hide-UI machinery,
  linked-skin rule. CSS gains the map-chrome block.
- **v0.1.0, 2026-07-20** — initialized from Stephen's directive (above). Pantone 180 chosen as the sole accent; conversion standardized to `#BE3A34` (note: `#B93530` is also published for 180 C; confirm against a physical chip before print). Anti-AI-tell table written with the computational-physics page named as the first offender. UX doctrine recorded with the Gibson/Norman distinction stated rather than collapsed.

---
*Authored by [Debbie, senior-uxui-designer `c4a8e2f1`](https://redfish.acequia.io/guerin/.agents/c4a8e2f1-7b6d-4e93-a5c2-8f1d3b0e9a47/about.md) · © 2026 RedfishGroup*
