Welcome — animations for the “Study tools” cell · shipped: AutoCode · Codebooks · Tag · Star & hide

Replacing the static screenshots in the large “Study tools” cell with tiny looping illustrations — themeable, responsive, no baked-in macOS chrome. Same playbook as the science cell: prototype idea + motion + copy here, then decide native-SwiftUI vs webview and build for real. Doing the tools one by one. The four below are shipped in-app; three remain to design (Video clips · Send to Miro · Ingest) and no screenshots long-term — a baked PNG is not an option for any of them.

· As shipped — the in-app wiring these mocks became

The cell previews below now carry the shipped copy and CTA labels verbatim (they used to show the mock's proposals, which lost). Two motion differences are deliberate: standalone loops here vs the WelcomeBaton's one-animation-at-a-time rhythm in-app — the baton owns the tempo, so a cell plays once per turn then holds rather than looping. Enum is WelcomeIllustration (renamed from ScienceIllustration, 2 Aug 2026); each case is rendered by illustrationView in WelcomeHomeView.swift. Tempo (14 Aug 2026): the Turn column below is the authored base — the shipped turn is base × WelcomeTempo stretch (group 60% speed × a local pace; the tool webviews carry ×1.3) plus a 3 s rest on the opening frame and 3 s on the finished frame, so real turns run ~2–2.5× the base. This page's standalone loops still play at authored speed.

Slot (title in-app)CaseViewHeight capTurnIn-app play
AutoCode.autocodeAutoCodeIllustrationView16012 sonce per turn (random quote), then hold
Codebooks.manualTagsManualTagsIllustrationView17613 sone group per turn, alternating across turns
Tag.tagTagIllustrationView16012 sonce per turn, then hold
Star & hide.starHideStarHideIllustrationView19014 sonce per turn (two beats), then hold
Connect an AI agent.agentChatAgentChatIllustrationView16013 sonce per turn, then hold — no mock section (built in-app; bespoke Claude Code chrome, no report CSS to sync). Full-width normal flow since 14 Aug 2026 (was centre-scaled)
Video clips.clipsClipsIllustrationView10014 sloops while holding the baton (Export-menu row clicked → clips land, filenames unit by unit → hold) — native SwiftUI, no mock section
Send to Miro.miroMiroIllustrationView1489 sonce per turn (stickies pop in order), then hold — no mock section (sticky text + hand-set wrapping verbatim from a board capture)
Ingest.ingestIngestIllustrationView19612 sloops while holding the baton (icons blink in, names type out) — native SwiftUI, no mock section

1 · AutoCode — quote streams in → AI tags flash in → accept → solid, real card

Copy: “Let AutoCode propose tags across every quote — you Accept or Deny.” · link AI helps tag →. Sequence: the quote types out (LLM/fast-human) → the Satisfaction sentiment + a proposed code flash in → the [✗ ✓] action pill is offered → accept is clicked, the code goes solid (accept-flash). Tag + card CSS are the shipped classes; the final frame is a real blockquote.quote-card.

Study tools
AutoCode
Let AutoCode propose tags across every quote — you Accept or Deny.
AI helps tag →
Drop a folder
Drag a folder of recordings or transcripts here to add it as a project.
at cell scale · real quote-card type
  • The code arrives; the rest is context. Quote, timecode, p1 · Participant and the Satisfaction sentiment settle first — AutoCode’s contribution is the code, so it flashes in proposed (dashed, pulsing, real .badge-proposed), offers the real [✗ ✓] pill, and on accept solidifies with the real badge-accept-flash.
  • Real quotes, de-branded. 11:30 → visible options; 13:08 → platform convention.
  • Copy edit needed: quote 2 was 37 words → trimmed to ~19 here (≈50%) so it streams + fits. Your final wording goes in QUOTES.
  • Mock vs shipped (deliberate): this page runs the 3-play burst then rest loop (WCAG 2.2.2 — no perpetual motion when a cell is the only thing moving). In-app the WelcomeBaton owns the tempo, so it plays once per turn then holds and the burst loop is unused. Keep the burst here — it's what makes the standalone page legible.
  • Open Qs: should the + pulse when the code lands? Show the deny path occasionally, or always accept? Stream both cards stacked in the big cell vs cycle one?

2 · Manual tags (the Codebooks slot) — the researcher hand-builds groups AI could never originate

The human counterpart to AutoCode. Two groups build by hand — title + description + codes typed via the real + → type → commit flow — one at a time, then slide away. A/B homepage trial = a designed experiment; Switching costs = a commercial dive from the brief (the participant uses a rival). Auto-coding can’t originate either: it wasn’t in the room when the research purpose was set. Group colours are the real codebook OKLCH sets (ux 250 / opp 75).

Study tools
Codebooks
Build a codebook, or start from a ready-made framework.
Code by hand → Research frameworks →
Drop a folder
Drag a folder of recordings or transcripts here to add it as a project.
at cell scale
  • Why two groups. One is a designed A/B experiment, one a commercial investigation from the brief — the two kinds of a-priori intent auto-coding structurally can’t have (it never attended the research-purpose meeting).
  • Real flow, by hand. Title + subtitle + each code typed via + → type → commit → chip (real tag-input + .badge-user), in the group’s real codebook colour.
  • Fit: groups really accumulate into a codebook — shown one at a time here (slides away) for space. Per-group descriptions included as requested.
  • Mock vs shipped (deliberate): this section keeps the standalone two-group accumulate-then-slide sequence because it's the design surface. In-app the cell shows one group per turn and the baton alternates the two across turns — the same way AutoCode alternates its two quotes. The slot is titled Codebooks in-app and this illustration sits under its Code by hand → CTA.
  • Open: final tag wording is placeholder; and whether to also show a code being applied to a quote after creation.

3 · Tag — click a quote → press ⌜t⌟ → your code types itself in

The most basic move in Bristlenose. Sequence: the pointer moves in and clicks to select (the real .bn-selected blue tint + bar) → a raised keycap (t) rises and presses → a code types itself in character-by-character (same typeInto grammar as the Codebooks cell) and commits to a real .badge-user chip. Keycap = skin B “Raised” from design-keycaps.md (faked — the primitive is unbuilt).

Study tools
Tag
Select one or more quotes, and press t to tag them with a code from your codebook.
Manual tagging →
Drop a folder
Drag a folder of recordings or transcripts here to add it as a project.
at cell scale
  • Pointer → click → keycap → action. The shared grammar for the three keyboard tools (Tag / Star / Hide). The pointer arcs in (real hands don’t move in straight lines), clicks the card chrome, the cap presses under the cursor over empty gutter space, and the consequence fires.
  • Reuses the “typed” tag. The code arrives one character at a time via the same flow as the Codebooks cell — it reads as “a human wrote this,” the counterpoint to AutoCode’s AI proposal.
  • Click the chrome, not the words. Clicking the quote text opens trim/edit (crop) mode in the real report (handleQuoteTextClick), so the pointer lands on the card’s left rule, where a plain click focuses + single-selects together (Finder-style, handleCardClick). Colours are the shipped tokens: --bn-selection-bg #eef4fc + a full accent-blue --bn-selection-border (#007aff) + the --bn-focus-shadow lift.

4 · Star & hide — ⌜s⌟ stars what matters · ⌜h⌟ hides the noise, count ticks up

Two keys, one idea: curate. The pointer focuses a quote → s stars it (the star + left rule pick up the starred tint, body weight bumps) → then focuses another → h hides it (the real .bn-hiding collapse) and the hidden count ticks up by one. Star, hide, and hidden-count CSS copied verbatim from atoms/toggle.css, quote-actions.css, hidden-quotes.css.

Study tools
Star & hide
Press s to keep the quotes that matter, h to hide the rest.
Keyboard shortcuts →
Drop a folder
Drag a folder of recordings or transcripts here to add it as a project.
at cell scale
  • The on-state is a whisper, not gold — SETTLED. Shipped --bn-colour-starred is #999 / #ccc — a tint differential (star + left rule + weight), not a gold fill. The old roadmap line “fills gold” was wrong about the code. The open question (match the product, or make the illustration louder than it?) resolved in favour of matching: the in-app cell ships the real differential plus a star-pop, so the illustration never promises a state the product doesn't have.
  • Hide is a real collapse. .bn-hiding animates max-height/opacity/margins to 0 (300ms), then .bn-hidden (display:none); the sibling slides up. The N hidden chip bumps +1 — the quote isn’t gone, it’s parked.
  • Click lands on the gutter, not the text. A plain click on the card chrome focuses + selects (real handleCardClick); clicking the words would open trim/edit instead. s/h then act on that quote; the hide button only appears on focus (real behaviour).
  • Vertical fit — settled at 190, not 172. Two compact single-line cards + the hidden-count strip were designed against a 172px estimate of the φ-major cell; in-app this is the tallest of the five illustrations and ships with a 190 height cap (toolbar + two cards). The two-up won — the sequenced fallback (star card A, then card B slides in to be hidden) was not needed and is not built.

· Full-bleed slot — flush left, equal right, and “as deep as makes”

The cell is a SQUARE that scales with the viewport — that's the constraint everything here has to survive, so resize the window and watch these two panels. Arithmetic from WelcomeHomeView.swift: the spiral is framed width: w, height: w / 1.618, and GoldenSplit(.horizontal) hands the major cell width: (w − 8) × 0.618; its height is the spiral's full height, 0.618w. Both ≈ 0.618w → square, growing linearly with width. (These side-by-side panels are each ~half the page, so slightly smaller than the real cell, which is ~62% of the whole content width — the proportions are faithful, the absolute size is conservative.)

The proposed rule. The illustration shares the cell's content edge — 16pt left, 16pt right (the real welcomeCell(large:) padding, the edge STUDY TOOLS already sits on) — runs the full width, stays leading so that when it hits a max width the slack opens on the right, and grows downwards to fill the depth it's given. The CTA then lands on the bottom instead of floating mid-cell. The φ-geometry does not move — the cell is the same fixed square either way; only the content inside it bends, which is the Parthenon rule working rather than being broken. The fake tool below (Trace a theme) is a fixture, not a roadmap item — it exists to prove the mechanism, and it fills its box by measuring it.

Study tools
Trace a theme
Follow one theme across every session, in the participants’ own words.
See the theme →
Drop a folder
Drag a folder of recordings or transcripts here to add it as a project.
now — a fixed cap in a scaling square, so the slack (hatched) falls below the CTA and grows as you widen the window
Study tools
Trace a theme
Follow one theme across every session, in the participants’ own words.
See the theme →
Drop a folder
Drag a folder of recordings or transcripts here to add it as a project.
proposed — full width, as deep as makes, CTA on the bottom · red = the collision zone

· The tool set — one by one; all drawn as of 14 Aug 2026

Each replaced one screenshot — the last three (Video clips, Send to Miro, Ingest) on 14 Aug 2026, built straight in-app like the agent cell. We locked a shared visual grammar on AutoCode and held the rest to it. Build target was per tool — themed SwiftUI or webview, both used. A screenshot was never the target.

How it plugs in. Each animation replaced the image: screenshot inside its studyTools slot (WelcomeHomeView.swift), rendered by the SlotRotator one item at a time; with the last three drawn (14 Aug 2026) the image: mechanism itself was deleted from SlotItem/slotView. Freezes to a legible still under prefers-reduced-motion. Build target fell per tool, as predicted: native SwiftUI where the system's own glyphs and type are the material (Ingest, Video clips — SF Symbols + SF Pro), webview where bespoke chrome or exact foreign type is (agent terminal, Miro stickies).