Studycase · Student guide
No screenshots — on purpose. They'd go stale the moment a label or layout changes, and pixel truth is already owned elsewhere (e2e/visual.spec.ts, QA-12, diffs real screenshots on every change). This page describes the cockpit by exact button text, keyboard keys, and data-testids instead. If something here doesn't match what you see, the app changed and this page is behind — that mismatch is more informative than a stale picture would be.
The long-form version of this guide lives at docs/STUDENT-GUIDE.md in the repo; this page mirrors it. See also docs/HEARING-GUIDE.md for full hearing-type behavior and docs/BROWSER-SUPPORT.md for the capture compatibility matrix.
Browser: live capture needs Chrome or Edge — the only browsers that reliably hand back tab/system audio through getDisplayMedia today. An unsupported browser shows a full-screen notice with the compatibility matrix and two ways out: dismiss and continue anyway, or “Try demo mode instead — works everywhere.” Demo mode never calls a capture API, so the gate never even evaluates while ?demo=1 is in the URL.
Quick start: “● Start capture” in the top bar opens capture setup (§9); “▶ Replay…” loads a saved session log instead of starting a new one (§10).
Four surfaces, top to bottom:
Press 1 / 2 / 3 any time to jump keyboard focus to a pane — the same key temporarily widens that pane too (a “focus-expand”); Esc restores the saved widths.
Every shortcut below also appears, searchable, in the ⌘K command palette. Shortcuts are suspended while a text field, a <select>, an open dialog, or the palette itself is focused — typing v (or any bound key) into your notes types the letter, it never fires the action. The palette (⌘K / Ctrl+K) and every action's on-screen button keep working regardless of focus.
Remapping: bindings are fixed in this build — there is no remap setting yet. This table and the palette are the single source of truth for what each key does; if a remap surface ships later, it will live in both.
| Key | Action | Where |
|---|---|---|
| ⌘K / Ctrl+K | Open the command palette | anywhere |
| H | Mark the selected transcript utterance (double-click a row does the same) | Transcript |
| J | Next utterance | Transcript |
| K | Previous utterance | Transcript |
| Shift+J | Next marked utterance only | Transcript |
| Shift+K | Previous marked utterance only | Transcript |
| Y | Copy the selected utterance (or shift-click range) | Transcript |
| 1 | Focus the transcript pane | anywhere |
| 2 | Focus the notes composer | anywhere |
| 3 | Focus the suggestions pane | anywhere |
| / | Focus the free-form chat composer | anywhere |
| M | Drop a ◆ mm:ss moment stamp into your notes at the current stream time | anywhere |
| P | Pin the newest suggestion card | anywhere |
| X | Dismiss the newest suggestion card (5s undo pill follows) | anywhere |
| C | Copy the citation of the focused card | Suggestions |
| Space | Pause / resume the world (transcript, suggestions, clocks all freeze) | anywhere |
| T | Toggle theater mode (translucent panes over the court feed) | anywhere |
| E | Toggle the demeanor read (facial cues — an automated cue, not a fact) | anywhere |
| V | Pop the file-mode video into picture-in-picture (no-op unless a recording with video is loaded) | anywhere |
| ` | Toggle the student terminal drawer | anywhere |
| Esc | Close the palette, or restore panes after a 1/2/3 focus-expand | anywhere |
| Cmd/Ctrl+B | Bold-wrap the selection | Notes textarea |
| Cmd/Ctrl+I | Italic-wrap the selection | Notes textarea |
| Enter | On a “- ” line: continue the list (empty item + Enter exits it) | Notes textarea |
| Enter | Commit the note | Notes composer |
| Shift+Enter | Insert a literal newline | Notes / chat composer |
Each row shows a colored speaker chip (Judge / Counsel P / Counsel R / Witness / Unknown — click it to correct a mislabeled speaker), a timestamp, and the caption text. Objection/ruling language gets a red left border automatically; your marks (H) get an accent-colored left border and a flag icon.
transcript-search) does client-side matching with a match count and ↑/↓ (or Enter/Shift+Enter) stepping.This is Granola-style two-ink notes:
Every AI block's byline shows an “as of” timestamp and clickable ↳ source refs. A block with zero refs never stays silent about it: ordinary analysis shows an amber “⚠ no source” chip (no-source); a prep-kind block instead shows “· from case files”— the protocol's one legitimate refs-less exemption (§11). A re-sent analysis you'd already edited shows a “⚠ differs from re-sent original” chip (conflict-chip) — your edit is kept, the chip just says so.
Composer: Enter commits a note; Shift+Enter inserts a newline. Committed notes render through the same tiny markdown subset the AI blocks use (bold, italic, code, “- ” bullets, #–#### headings) — click a rendered note to re-enter raw-text editing.
The three pull-ask buttons, above the chat box (pull beats push — these fire on demand, not automatically):
| Button | What it asks for |
|---|---|
| Summarize last 2 min | a summary of the last 120s of the record |
| Pending objection? | whether an objection is currently outstanding |
| Draft response | a drafted response to the current line of argument |
All three (and free-form chat, focus with /) share one shape: your question lands as a full-ink block, the streamed answer lands as a muted-ink block right after it, in the same chronological list as everything else.
✨ Enhance (enhance-notes) restructures the session into a clean outline and opens a per-section review (enhance-panel): each section is explicitly Accepted or Rejected; accepted sections land as new gray blocks — your original notes are never touched, only appended to. Accepted sections carry the same “· from case files” badge pre-session case-file material uses — a shared badge for “refs=[] is expected here,” not a claim that an Enhance section specifically came from an uploaded file.
Export ⤓ downloads your notes as markdown. Your ink exports verbatim, unlabeled. Every unedited AI block exports watermarked with the exact wording “AI analysis — verify before relying” plus its sources or an explicit “(no source utterances)” / “(from case files)” line.
Crash recovery (notes-recovery-banner) — an unfinished session (<1h old) with autosaved notes offers Restore or Dismiss. Local IndexedDB insurance only, never a silent restore.
Factor scoreboard— on TRO/PI and Daubert hearings, a chip row appears above your notes as soon as a Winter or Daubert factor is actually argued (never a pre-filled checklist); click a chip's count to jump to the arguing utterances.
Case-law cards surface at natural pauses, never mid-utterance, five at most (shown as “N/5” in the header). Confidence is a coarse label, never a fake percentage: Strong (accent), Relevant (neutral), or Speculative (dashed, muted).
Every card has a “Why now” line (click to jump to the triggering utterance), plus Pin (P pins the newest), Dismiss (X dismisses the newest, 5-second Undo pill follows), and Copy citation (C on the focused card). Dismissed/superseded cards land in the History drawer (toggle in the palette), each restorable.
Genius cards (genius-card) are the flagship — a distinct gold-leaf top-slot card with a speakable line in a quotation frame, a pinpoint citation, the same “why now” provenance row, an optional amber Risk row, and a one-tap “Copy line” button. The clipboard payload is the spoken line, then the pinpoint citation, then — on its own trailing line, never appended to the line itself — the same “AI analysis — verify before relying”caveat the notes export uses (LEGAL-12): the first line has to stay clean because it is meant to be read aloud verbatim. See §11 for what “genius” does and doesn't guarantee.
The chip next to the connection badge (hearing-type-chip, e.g. “appellate ▾”) is a compact select for the 13 real hearing types plus “Other / auto-detect.”Picking a type tunes which moment detectors fire, the AI's writing register, the Enhance output's structure, and (for some types) how often suggestions push. Full type-by-type behavior lives in docs/HEARING-GUIDE.md— read that before relying on any specific hearing type's behavior; it isn't repeated here.
If the gateway's live detector disagrees with your current pick, a banner appears (hearing-switch-banner: “This sounds like Suppression hearing (3 cues) — switch?”) with Switch / Keep current — the type never changes silently.
Tell the coach your plan: theory of the case, goals, lines to protect, doors not to open. Analysis and cards then lean toward your strategy — but reality is never filtered: authority that cuts against you still surfaces, flagged, and the coach warns when the hearing nears a door you flagged shut. Your words ride to the model verbatim and are never rewritten. Update mid-session whenever the strategy shifts (⌘↩ saves). Intent dials in the same dialog set how loud the coach is — every dial maps to a real engine parameter, none are decorative.
The court video usually plays in another browser tab, which this app cannot read the clock of — the bar is honest about that. Two-gesture calibration:
mark-sync) — pins the stream's current time.confirm-anchor, or Enter).Once anchored, any seek request (a moment-stamp chip, or a word click) shows a copyable “→ video mm:ss” chip (seek-target) — this app cannot drive another tab's player and doesn't pretend to. Using “Play a recording” (file playback) instead drives that player directly, no copy step needed.
“● Start capture” opens capture setup, which is per-OS (detected automatically):
onboarding-mac): play the court video in a Chrome tab, choose Chrome Tab in the share picker (macOS Chrome only captures audio from a tab), and make sure “Share tab audio” is on — the step most often missed; a no-audio failure routes back here with that exact step highlighted amber.onboarding-windows): play the video anywhere, choose Entire screen, and enable “Share system audio”.The dialog includes a labeled CSS illustration of the share picker (share-illustration, not a screenshot — “yours may differ slightly,” stated on the illustration itself) and a live level meter confirming audio the moment sharing succeeds.
Recording consent (recording-consent): recording and consent laws vary by jurisdiction, so capture setup includes a notice and an affirmation checkbox — you affirm you have the right to capture the feed (a public hearing, your own practice round, or licensed material). Capture will not start until it's checked; the affirmation lasts for your current session only (a new tab or browser session asks again). Practice mode (mic) shows the same notice in its own small dialog the first time.
Face tracking (experimental, off by default): when enabled, the app can follow faces in the captured video as anonymous, stable tracks — “Face A,” “Face B,” and so on — so you can name each one once (Judge / Counsel P / Counsel R / Witness). All of that analysis runs entirely on your device: no face image, crop, or landmark data is ever sent anywhere, logged, or stored beyond the current tab — the only thing that persists is the plain-text role you pick for a track. Naming a track feeds ≈ match speakers (§12½) — suggested matches apply only when you confirm them.
docs/CAPTURE-GUIDE.md.“▶ Replay…” (replay-load) loads a stored session's event log (a .jsonl file) and rebuilds every pane through the exact same event path a live session uses — a REPLAY badge and the replay bar are the only visible difference. The bar shows a density strip (density-strip: utterance density per bin, plus accent ticks for suggestions and amber ticks for your marks — click to seek), a scrub slider, and elapsed/total time. It says exactly what it can't do: “events only — no audio (S3-3)”— the event record replays, audio storage doesn't exist yet. Exit returns to live.
Every AI-generated block is labeled (the muted-ink treatment, never mixed silently into your own ink), grounded (clickable source refs, or an explicit “no source” / “from case files” chip when there legitimately are none), and yours to verify — the export watermark says so in as many words: “AI analysis — verify before relying.”
Genius lines go through a deterministic six-sigma citation gate before you see them (docs/GENIUS-LINES.md §2.3): every authority cited must resolve against the verified index this build has actually ingested, or the line is discarded and regenerated (up to 2 retries, then it falls back to an ordinary suggestion card). That gate is real and strict — but it is corpus-honesty, not truth-in-the-world: “verified” means “in our index,” not “verified as legally correct for your case.” Treat a genius line like a sharp classmate's cite-check — trustworthy enough to build on, never a substitute for reading the case yourself before you say it out loud.
One way to use the cockpit end to end for a moot-court round:
.jsonl log through ▶ Replay…. Moot court sessions get a moot-court ballot appended to the Enhance artifact — one per arguing channel with ≥3 turns, five coarse axes (knowledge of the record, responsiveness to questions, organization/signposting, use of authority, delivery), each strong/adequate/needs_work with real utterance citations, never a point total. See docs/HEARING-GUIDE.md “The moot-court ballot.”docs/HEARING-GUIDE.md— every hearing type's exact behavior, live auto-detection, the moot-court ballot, and how to add a new type.docs/HEARING-TYPES.md — the taxonomy and research behind those types.docs/BROWSER-SUPPORT.md — the full capture compatibility matrix.docs/GENIUS-LINES.md — the design for role tracking and the genius-line pipeline.