Clean successor to V3 (forge: lilith/atlilith). Seeded from local Mac working tree at ~/Code/@projects/@cocottetech/. node_modules and build artifacts excluded via .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
14 KiB
multi-surface-fanout.screen
The fan-out approval centerpiece — one decision, N adapter dispatches across the 24-surface roster (brief O). Pairs with brief H §H4 (multi-surface card pattern) and §H5 (density: H5a accordion · H5b compact · H5c anchor-and-rest · H5d cross-cutting rules · H5e split-card). Voice register: working (00-system-voice.md §V2b); plain on failures and high-stakes elevation. Sibling to approval-card.screen.md (single-surface). Where the single-surface card is one diff, one approve, this is one diff, many surfaces, one approve — and at Quinn's actual roster size, density is the design.
Layout
Four variants rendered below. Picker is automatic per H5 thresholds, never Quinn-toggleable. Approve button stays pinned to card bottom in every variant; internal scroll only inside the body.
Flat (≤5 surfaces) — full ASCII card
┌─────────────────────────────────────────────────┐
│ ┃ ▢ Update about-me on 4 surfaces ⋯ menu │
│ ┃ [profile-copy] · medium · 0.81 │
│ ┃ │
│ ┃ ◉ [Tryst] "Independent escort…" 142c │
│ ┃ ◉ [TS4Rent] "Independent escort,…" 138c │
│ ┃ ◉ [Slixa] "SF-based independent…" 165c │
│ ┃ ◉ [tqftw.com] "Independent escort…" 320c │
│ ┃ │
│ ┃ Why: dropping "corporate" everywhere. │
│ ┃ │
│ ┃ [ Edit ] [ Set aside ] [ Approve 4 ] │
└─────────────────────────────────────────────────┘
Accordion (6–12 surfaces) — H5a, grouped by O categories
Collapsed-default state when total > 8:
┌─────────────────────────────────────────────────┐
│ ┃ ▢ Update about-me on 10 surfaces ⋯ │
│ ┃ [profile-copy] · medium · 0.78 │
│ ┃ │
│ ┃ Escort directories · 8 [6/8 ▾] │
│ ┃ Brand sites · 2 [2/2 ▴] │
│ ┃ ◉ [tqftw.com] "Independent escort…" │
│ ┃ ◉ [a.t.t.com] "Tour-focused…" │
│ ┃ │
│ ┃ Why: dropping "corporate" everywhere. │
│ ┃ │
│ ┃ [ Edit ] [ Set aside ] [ Approve 8 ] │
└─────────────────────────────────────────────────┘
Expanded state of directories group (H5a per-group bulk toggle visible):
│ ┃ Escort directories · 8 [6/8 ▴] │
│ ┃ All on · All off · Custom │
│ ┃ ◉ [Tryst] "Independent escort…" │
│ ┃ ◉ [TS4Rent] "Independent escort,…" │
│ ┃ ◉ [Slixa] "SF-based indep…" │
│ ┃ ◉ [PD] "Indep. companion…" │
│ ┃ ◉ [Seeking] "Independent comp…" │
│ ┃ ◉ [TSEscorts] "Indep. SF escort…" │
│ ┃ ○ [Eros] (blocked — name change) │
│ ┃ ○ [AdultSearch] "Indep. SF escort…" │
Compact rows (≥8 in one group) — H5b, one-line-per-surface
When the directories group alone has ≥8 (the canonical N2 case from brief O):
│ ┃ Escort directories · 12 [10/12 ▴] │
│ ┃ filter surfaces… │
│ ┃ ◉ [Tryst] · 142c · ✓ │
│ ┃ ◉ [TS4Rent] · 138c · ✓ │
│ ┃ ◉ [Slixa] · 165c · ✓ │
│ ┃ ◉ [PD] · 144c · ✓ │
│ ┃ ◉ [Seeking] · 220c · ⓘ longer │
│ ┃ ◉ [TSEscorts] · 158c · ✓ │
│ ┃ ◉ [AdultSearch] · 410c · ✓ │
│ ┃ ◉ [AdultLook] · 488c · ⓘ near cap │
│ ┃ ◉ [EroticMonkey] · 142c · ✓ │
│ ┃ ◉ [SkipTheGames] · 144c · ✓ │
│ ┃ ○ [Eros] · blocked │
│ ┃ ○ [MegaPers] · not started │
Tap a row → that row expands inline (others collapse) to show full preview + inline edit. One row expanded at a time.
Anchor-and-rest (tours per H5c)
┌─────────────────────────────────────────────────┐
│ ┃ ▢ Add Berlin tour · Oct 3–7 ⋯ │
│ ┃ [tour] · medium · 0.84 │
│ ┃ │
│ ┃ Anchors [3/3] │
│ ┃ ◉ [Tryst] "in Berlin Oct 3–7" │
│ ┃ ◉ [TS4Rent] "Berlin · Oct 3–7" │
│ ┃ ◉ [tqftw.com] "tour: Berlin · Oct" │
│ ┃ │
│ ┃ Other directories · 9 [7/9 ▾] │
│ ┃ Brand sites · 1 [1/1 ▾] │
│ ┃ │
│ ┃ Why: anchors always expanded; rest curated. │
│ ┃ │
│ ┃ [ Edit ] [ Set aside ] [ Approve 11 ] │
└─────────────────────────────────────────────────┘
Anchors never collapse. Rest stays collapsed until Quinn taps to curate.
Components
| Component | Notes |
|---|---|
| Stakes color band | 4pt left edge per 00-system-visual-system.md §F1. Aggregate band; escalates per H5d if any row is high-stakes standalone. |
| Header | Verb + N-surfaces count + ⋯ menu (see-full-reasoning · talk-to-{specialist} · split-this-card · report). |
| Chip row | Action-kind chip (profile-copy / tour / availability-policy) · stakes label · aggregate confidence (enabled rows only, per H5d). |
| Group header | Category label + count + aggregate state glyph (✓ N · ⓘ M · ⚠ K · ○ blocked) + per-group bulk-toggle (All on / All off / Custom) + caret. |
| Surface row (full) | Surface chip (F5 iconography) · per-surface preview · checkbox · char count vs cap. |
| Surface row (compact, H5b) | Single line: [chip] name · Nc · status-glyph. Tap-to-expand. |
| Filter input | Appears above accordion when total ≥ 12 (H5d). Filters across groups; never hides approve. |
| "Why" line | Aggregate rationale; tap expands per-surface rationales stacked. |
| Action bar | Edit · Set aside · Approve N. Pinned bottom safe-area. Approve label always shows enabled-row count. |
| Split connector | When H5e applies, a hairline + caption ties two stacked cards together. |
States
Flat
Default for ≤5 surfaces. All rows visible, no accordion chrome. Approve enabled when ≥1 row checked.
Accordion-collapsed
Default for >8 total. Group headers visible; bodies hidden. Per-group counts let Quinn approve without expanding ("6/8 looks right · approve"). Caret ▾ on collapsed, ▴ on expanded.
Accordion-expanded (single group)
Tapping a group caret expands that group only; siblings stay in their current state. Bulk-toggle row appears at top of expanded body. Internal scroll bound to body, not card.
Compact-row-expanded
H5b only. Tapping a compact row expands it inline to a full row (preview + char cap visualization + inline-edit affordance). Tapping another compact row collapses the prior — one-at-a-time.
Search-filtered
H5d. Filter input typed; non-matching rows hide; group counts update to (matching / total). Approve count reflects all enabled rows including hidden — clear caption: "Approve 10 (3 hidden by filter)".
Split-card (H5e + K3i)
When the specialist splits at draft time, two stacked cards appear in chat with a connector:
┌─ routine ───────────────────────────────────┐
│ ▢ Update about-me on 8 surfaces │
│ [ Edit ] [ Set aside ] [ Approve 8 ] │
└─────────────────────────────────────────────┘
│ These 8 go together
│ This 1 wants your eyes
┌─ brand-sensitive ───────────────────────────┐
│ ▢ Update about-me on tqftw.com │
│ (single-surface diff card — H2 shape) │
│ [ Edit ] [ Set aside ] [ Approve ] │
└─────────────────────────────────────────────┘
The split is the specialist's call (brief H5e), surfaced to Quinn as one visual unit.
Dispatch-in-progress (per-row)
Approve tapped → action bar replaced by a progress strip ("Pushing to 10 surfaces · 4 done"). Each enabled row shows its own state: spinner → ✓ or ✗. Failed rows stay in card; succeeded rows fade slightly. Card cannot be dismissed mid-dispatch.
Post-dispatch with 2/8 failed
After all rows resolve, card transforms into a receipt with a per-group failure banner per H5d (one banner per group with failures, not per row):
│ ┃ ✓ 8 surfaces updated · 2 failed │
│ ┃ Escort directories · 6 of 8 ⚠ │
│ ┃ 2 failed — tap to retry │
│ ┃ Brand sites · 2 of 2 ✓ │
│ ┃ │
│ ┃ [ Retry 2 ] [ See details ] [ Dismiss ] │
Tap retry → just the failed rows re-dispatch; tap details → row-by-row in audit drawer (brief I).
Stakes-escalated (all-high)
Per H5d, any single row at high stakes elevates the whole card. Visual: stakes band → rose; Approve button gets a confirm step ("Approve 10 — high stakes"). Voice shifts to plain register: "Ten surfaces. High stakes from Eros's name-change flag. Approve all, or split out Eros?"
Gestures
- Tap group caret → expand/collapse that group only.
- Tap compact row → inline expand; auto-collapses any other expanded compact row.
- Long-press surface row → quick actions (skip · edit just this · open surface settings).
- Long-press group header → bulk action menu (All on · All off · Skip this group).
- Right-swipe card → Approve N (haptic confirm threshold per F §F4); blocked when in dispatch-in-progress or stakes-escalated states.
- Left-swipe card → Set aside (moves to pending-approvals).
- Two-finger swipe down → minimize-to-inbox.
- Pinch-out on group header → expands all groups at once (escape hatch from collapsed-default).
- Tap "Why" → expand per-surface rationales stacked.
In-the-wild copy
Working register throughout except where noted.
H3 tour fan-out (anchor-and-rest header):
Berlin Oct 3–7 ready on 11 surfaces. Anchors set. Eros is off — flip on if you want them included.
H5b compact-row with near-cap notice (ⓘ hover):
AdultLook caps at 500 — this draft lands at 488. Tight but fits.
H5e split-card connector (K3i):
These 8 go together · This 1 wants your eyes.
Post-dispatch 2/8 failed (plain — failure register):
8 surfaces updated. AdultSearch and Eros rejected the push. Retry, or set them aside.
Edge cases
- Single group exceeds compact threshold but total is small (e.g. 9 directories, no brand sites) — H5b activates for that group; the card still feels flat because there's only one group. Acceptable; predictability over polish.
- All surfaces in one group blocked (e.g. all N2 pending verification after a coop-intel mass-flag per brief N) — group header shows ⚠ all-blocked; Approve count drops to 0; action bar reads "Nothing to approve · review blockers".
- Confidence below threshold on enabled-only average — Approve disabled; "ask Cocotte to try again" surfaces beneath action bar (mirrors single-surface card edge case).
- Card stale (>24h) — same gentle warning as single-surface card; re-draft re-runs the per-surface diff pass.
- Filter input typed during dispatch-in-progress — input disabled; tap surfaces a one-line hint ("Pushing — filter unlocks when done").
- VoiceOver order — header → aggregate stakes/confidence → "Why" → group headers (with counts) → expanded rows → action bar. Group counts are critical: a blind user must hear "6 of 8 directories enabled" without expanding.
- Reduced motion — accordion expand/collapse becomes instant; dispatch progress strip skips per-row spinner animation, jumps row-state on settle.
- Dynamic Type XXL — compact rows force-promote to full rows (compact-format unreadable at largest sizes); accordion remains.
- Org-context (brief W) — if active org has a surface subset enabled, disabled-by-org rows render with a tiny lock glyph; tap to see "disabled in {Org} context".
- Kill switch active (brief K) — card greys; action bar replaced by "Auto-actions paused — resume to dispatch".
Related
- brief H §H4 — multi-surface approval-card pattern (anatomy).
- brief H §H5a–e — density rules (accordion / compact / anchor-and-rest / cross-cutting / split-card).
- brief A §approval — chat-surface integration; this card appears inline.
- brief K §K3i — split-card boundary (routine vs brand-sensitive).
- brief O — the 24-surface roster that makes density mandatory.
- brief R §R3 — tour fan-out is this card's H5c anchor-and-rest shape, used by the tours backbone.
approval-card.screen.md— sibling single-surface pattern.- brief I §3 — per-row audit lineage post-dispatch.
00-system-voice.md§V2b + §V2c — working register for body, plain on failures/escalation.