Skip to content

Make the Brain the Chat's living background; float components on legibility-floored Glass - #64

Draft
kateebonner wants to merge 34 commits into
local/amicodefrom
amico/issue-56-living-chat
Draft

Make the Brain the Chat's living background; float components on legibility-floored Glass#64
kateebonner wants to merge 34 commits into
local/amicodefrom
amico/issue-56-living-chat

Conversation

@kateebonner

@kateebonner kateebonner commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Closes #56

Integration branch for the Living Chat redesign, built slice-by-slice from the sub-issue DAG (#59 #60 #61 #62 #63; design-of-record: ADR 0002, merged via #58).

Landed:

Final gate on this branch: ui 402 pass / 0 fail · app 464 pass / 0 fail · typecheck 23/23 · lint 0 errors.

Honest pre-gate evidence (headless, dev build — NOT the gate): forced full tempo + 11s continuous scroll of a 144-message thread → dark p95 25.4ms / light 25.2ms, mean ≈16.3ms, 11–15 frames >33ms. The tail misses the 16.7ms budget in that proxy environment (dev-mode Solid, headless vsync, sampler riding the measured loop) — which is exactly what the pre-agreed governor valve is for. The real call happens on the reference laptop (checklist below).

Known follow-up candidates (from #61's browser pass, non-blocking): composer placeholder hint and reasoning-part still composite on standard/bare over the Brain.

🤖 Generated with Claude Code

kateebonner and others added 19 commits July 25, 2026 02:26
The full-bleed Brain background component, ported from the old
kate/chat-brain-atmosphere branch and retargeted to the native engine on
this branch: suspend()->pause(), refreshTokens()->setTheme(scheme) read
from data-color-scheme, the requestRender font-ready hook degraded to a
resize() repaint, and the old-engine-only setActive/setReducedMotion
dropped (tempo work is slice #62). Environment plumbing carried over
verbatim: ResizeObserver->resize, theme MutationObserver, document
visibility + IntersectionObserver hard-pause, amicode:brain-hover
glances, and the diff-by-id event flush with a silent first restore.

The live feed is the inline strip's event derivation extracted to a
pure, session-scoped deriveBrainEvents(messages, getParts) so it is
unit-testable headless and shared by the mount: touches in message
order via the tool->brain-ref map, a chart after each completed
assistant turn with >=2 commits, replay=true for completed turns,
ids never repeated.

Tests: new brain-events derivation suite (9 cases) pinning the AC-4
contract; brain-engine suite extended with the background-mount driving
case (derived-stream growth, quiet replay-only first flush with nothing
queued, lossless theme swap over a restored atlas).

Part of #56 (ADR 0002 - the Brain becomes the Chat's background).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
One full-bleed BrainAtmosphere per Chat window, mounted as the first
child of the session pane card (now relative isolate) at -z-10: above
the pane's surface fill, below the conversation timeline, landing, and
composer, pointer-events none. Keyed on the active session id so a
titlebar tab swap remounts to that session's atlas with exactly one
engine/render loop alive; empty on the landing. The standalone
new-session draft page gets the same layer (no events - sparse seed).

The inline brain-strip timeline row is deleted: the Brain member is
dropped from the TimelineRow union, forcing out its key branch, the
timelineRows append, the keepMounted special-case, the render case, and
the framed-row exclusion. The working-indicator shimmer (Thinking row)
is untouched, guarded by a new row-model suite; the strip's
click-to-expand is obviated (the engine has no node hit-testing).

Part of #56 (ADR 0002 - the Brain becomes the Chat's background).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two-tier Glass token system over the Brain background (ADR 0002):
standard (prose/bubbles/composer) and dense (code/diffs/run-plots),
one shared 18px blur, tint carries all contrast. Each tier's alpha is
DERIVED per theme+mode — the least alpha clearing WCAG-AA with a +0.3
safety margin (target 4.8) over that mode's reference frame, read from
the brain engine's own PALETTES (dark: peak-bloom #fff676; light:
#8f8000 — the light brain never paints #fff676). Dense additionally
converges every graphical mark (syntax tokens, diff fills, run-plot
strokes) to within 0.2 of native and holds WCAG 1.4.11's 3:1.

- glass-tokens.ts: WCAG math (ported from the old branch), pure
  deriveGlassTiers(tokens, frame) — no blur argument by design —
  collectMarks, and the generateGlassCss emitter for every bundled
  theme, scoped html[data-theme][data-color-scheme] with a
  @supports-not near-opaque fallback (alpha >= 0.95)
- glass.css: committed generated output, registered in styles index;
  exposes only [data-glass="standard"|"dense"] surfaces — no component
  opts in within this slice, rendered output unchanged
- generate:glass script mirrors generate:tailwind wiring
- brain-engine.ts: export PALETTES (data seam only, no behavior change)
- glass-tokens.test.ts: headless contrast certification for oc-2
  light+dark — body/code text floors + margin, mark rule, strict tier
  ordering, blur-never-a-term guard, keying purity, fallback floor,
  byte-for-byte drift guard, and the muted-grey-rides-dense invariant

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…st cadence) (#62)

One draw-gate honored by both the rAF loop and the manual tick(): full
musical tempo while active / in-flight / unfurling, ~8fps breathing at
rest (REST_FRAME_MS ported from the atmosphere branch engine). touch/
chart/highlight/resize/resume/setTheme beat the throttle via
requestRender so feedback stays immediate. BrainEngineStats gains
active + scale.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Boot is the amico core alone — the vault-skeleton preload, its
force-settle layout, and the demo-trace thought-edges are gone (ADR
0002 rejects the breathing skeleton atlas). The graph grows only from
real touches; two engines share no state (all state closure-local).
The camera is a constant core-centered zoom: no per-frame
fit-to-farthest, no close-up follow, no glance steering — growth
densifies in place. stats().scale exposes the fixed zoom; ambient
ghost picks tolerate an empty edge set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The cap is the whole graph (core + GRAFT_CAP), not just live-* grafts:
eviction picks the least-recently-touched node — recency stamped by a
monotonic touch counter, not the beat clock (which stalls at rest).
Only the current live node and in-flight pulse endpoints are exempt;
atlas keep / charting / replay grant no immunity, so marathon sessions
can never grow the node set or per-frame draw cost without limit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rest (#62)

With prefers-reduced-motion set the engine never breathes at idle: once
the post-event nudge window (NUDGE_MS, rebased onto the frame timebase,
never performance.now()) elapses with nothing in flight, ticks draw
nothing and the rAF chain ends — a touch/chart/highlight/resume re-arms
one bounded burst. This is the accessibility terminal (ADR 0002),
independent of slice #63's frame-time ease. pause() clears any
scheduled frame; the lifecycle suite now pins zero-draws-while-hidden.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#62)

Re-add the `active` output that #59's createBrainEvents dropped:
deriveBrainActive (pure, headless-tested — non-idle means busy or
retrying) feeds a memo that session.tsx passes to <BrainAtmosphere
active>, which plumbs it to engine.setActive. The draft page keeps the
default at-rest Brain (no session, no busy signal). Test helpers
(drive/clears) consolidated at file scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Everything floats over the mounted Brain (ADR 0002): the seven content
archetypes opt into slice #60's tier tokens — STANDARD on the user
bubble, assistant prose (which gains its first card), and the composer;
DENSE on code blocks, diffs, run-plots/run-windows, and tool cards (the
tool-collapsible root, so trigger + expanded output float as one unit
across single tools and context/shell groups). The tier token owns
fill/edge/radius/shadow everywhere — the opaque --surface-base bubble
fill, the composer's layer-01 fill + raised shadow, and the dock band's
background-stronger tiling are gone, so the Brain stays live in the
gaps (session-turn row frames and column wrappers stay transparent).

Muted/secondary ink never composites against the ultra-transparent
standard tint (certified to fail AA by #60): the prose meta, user-
message meta, composer footer controls, prose blockquotes, the child-
session stub, and the bubble's file/agent highlights all ride dense-
backed inline zones styled with --glass-dense-bg — the #60 token, no
new tint/blur literal anywhere. Shiki's inlined theme surface defers
to the dense card; the diff card's sticky header occludes with the
dense token instead of opaque chrome. The ghost-collapsible reset is
scoped :not([data-glass]) so the tier fill survives specificity.

Tests extend #60's certified surface onto the components:
- glass-float.test.ts (ui): the 7-archetype tier map as a table test —
  body→standard ≥4.8 (AA + margin), code/diff→dense ≥4.5, marks→dense
  ≥3:1 (1.4.11) without native drift, muted-role never on standard —
  measured with #60's exported validator math over the running-brain
  reference frame in both oc-2 modes; plus source contracts (tier
  attributes on the real markup, no ad-hoc literals in the restyled
  card rules, repo-wide data-glass allowlist: two tier values only,
  never on Rail/titlebar/Panels chrome).
- glass-float.test.ts (app): composer/diff/child-stub tier contracts,
  gaps-stay-live (no glass, no fill on session-turn + containers), and
  the sticky session-title header's pre-existing chrome blur untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sparse-seed boot (#62) removed the last importer; the latent skeleton
atlas was the superseded design's raw material (flagged by the #62 engineer,
removed at integration).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ver blur (#63)

A frame-time state machine observing the ONE Brain render loop: rolling-p95
over the 16.7ms budget for a sustained ~2s window steps motion down the
tempo ladder (allegro -> andante -> largo) with eased paint-cadence caps,
then to a motion full-stop, then terminally hard-pauses the canvas to a
static blurred field. Dual-guard hysteresis (13ms restore threshold + a ~2x
clear window, one level per window) prevents oscillation; the sample window
resets on every step so a stale regime never cascades an unearned step.

Measurement pauses with the engine (hidden / off-screen / reduced-motion):
stalled gaps are discarded, never fed as phantom over-budget frames. The
governor is independent of the reduced-motion accessibility terminal (#62)
and is bypassed entirely under it. Its only levers are tempo and the
terminal pause — no path writes a glass token, a style, or any CSS; stats()
now emits the discrete motion level. governed:false (the dev
force-full-tempo hook's engine seam) disables it for un-eased worst-case
perf capture.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…isables the governor (#63)

Ported from the old branch's perf-capture hook and extended per the issue:
the param now ALSO disables the perf governor (governed:false), so a gated
run — headless proxy or the reference laptop — measures the un-eased worst
case. DEV-gated, inert in prod. Also DEV-only window.__amicoBrainStats for
the trace harness and the manual gate checklist to read engine stats live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h themes (#63)

Playwright spec over the real app on the e2e mock-server harness: boots the
144-message fixture thread with the dev force-full-tempo hook (Brain pinned
busy, governor disabled — the un-eased worst case), scrolls continuously
for >=11s per theme inside the SAME rAF loop that samples frame intervals,
and emits a p95 / max / frames>33ms report per theme.

Labeled and asserted as the PRE-GATE PROXY only: the spec pins that the
harness runs and reports (shape, duration, theme coverage, forced state) —
it asserts NO numeric frame-time outcome. The release gate stays the manual
sign-off on the pinned reference laptop (issue #63, HITL).

Run: cd packages/app && bunx playwright test e2e/perf/brain-governor-trace.spec.ts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…re-emptively eases (#63)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner

Copy link
Copy Markdown
Contributor Author

HITL sign-off checklist — reference-laptop 60fps gate (#63)

The one open acceptance criterion on this PR. Run on the reference laptop, battery-powered:

  • Pin the machine: model, OS, battery %, VS Code + webview (Chromium) version — write them here.
  • Launch the dev lane: opencode serve --port 4099 + bun --cwd packages/app dev --port 5990 with VITE_OPENCODE_SERVER_PORT=4099 (the force hook is DEV-gated by design).
  • Open the Chat in the VS Code webview on a real thread of ≥40 cards with ?brainForceActive appended; verify in devtools: window.__amicoBrainStats()active: true, motion: "full".
  • Record a ≥10s continuous scroll (devtools Performance panel, or the rAF sampler in Add the perf governor (ease motion, never blur) and gate 60fps on the reference laptop #63's notes ~600 frames).
  • Pass = p95 ≤ 16.7ms AND zero frames > 33ms. Repeat in both themes (flip the chat scheme mid-session — Brain/Glass re-key losslessly).
  • Write the numbers here and sign off.

If the gate fails: remove ?brainForceActive and confirm the governor engages under load — watch __amicoBrainStats().motion step eased-1 → eased-2 → full-stop → hard-paused with the frosted look intact — then decide accept-with-valve vs iterate. (Headless dev-proxy already suggests the tail will need the valve; see PR body.)

🤖 Generated with Claude Code

@kateebonner
kateebonner marked this pull request as ready for review July 25, 2026 16:28
kateebonner and others added 8 commits July 25, 2026 16:30
…sed question dock

Live design-review iteration with Kate (2026-07-25) on the Living Chat:
- Glass is ONE recipe everywhere: blur 8px + per-mode tint (dark: 4% white
  frost + backdrop brightness(0.4); light: 5% near-white). The dark tint's
  direction flips to a frost veil (lighter than ground, classic glass) with
  the brightness term modeled honestly in the contrast derivation.
- The marks law (WCAG 1.4.11 dense certification) is WAIVED by design
  decision; dense==standard. Muted ink is recorded as not-certified.
  Tests rewritten to record the waiver rather than certify the old law.
- Cards no longer span the thread: prose fit-content ≤ min(88%,72ch),
  user bubbles ≤ min(82%,64ch), tool cards ≤ 92%.
- The question dock floats on glass (8th archetype); its muted hint and
  answers summary ride dense-backed zones; opaque fill scoped to
  :not([data-glass]).

Part of #56 (PR #64); supersedes the #60/#61 tier law per Kate's call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cipe

Receipt chip, ask card (+options), run window (hover regression fixed),
inline entity card, entity rail chips, widget-preview shell, entity-view
inner atoms (tier/skeleton/formula/badge/seq/status pills), and the classic
in-chat landing (one standard card; starter buttons on dense-zone fills,
accent-edge instead of a yellow border on light). Semantic error state is a
danger tint over the glass, never an opaque surface. No !important fills.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Permission dock joins the question dock on the unified glass card (dock-prompt
generalized across kinds, permission footer flattened the same way); todo /
followup / revert trays carry the standard hook (opaque tray fill loses to
glass.css by import order); todo scroll-fade rides the glass tint; question
option tiles become dense-zone fills with the accent-soft hover, never an
opaque layer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Opaque bands inside glassed cards defer to the dense-zone token (edit/write/
apply-patch sticky triggers, accordion header+expanded body inside any glassed
card, StickyAccordionHeader, timeline diff expanded view); the task/subagent
card is a dense zone with the accent-soft hover; diagnostics become a critical
tint over the frost; error/retry/assistant-error cards ride glass with a danger
tint; bare-muted-ink rows get their #60 backing (thinking indicator, reasoning
part, tool-loaded-file rows, turn divider label, comment-strip chips); user
attachment chips carry the dense hook; jump-to-bottom converts its hand-rolled
near-glass to the single recipe; the sticky session-title band converts its
chrome gradient/blur literals to the glass vars; inline-code chips ride the
dense token.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cipe

Dialogs (one dialog.css edit covers delete-session/entity/fork/MCP/file/model/
unpaid/usage-exceeded launch sites), ImagePreview lightbox, popovers, dropdown
menus, shared Select menus, slash/@ autocomplete, project picker, model
selector, toast v2 — all ride the glass vars (tint + shared blur/brightness +
edge) with the legacy token as no-theme fallback; item highlights move to the
accent-soft state fill. Tooltips, the markdown code-fence copy tooltip and the
legacy toast keep their deliberate INVERSE ink on a HEAVIER glass (denser
float-token tint + shared blur/edge, never a raw opaque token); the copy
button itself rides the dense token. Drag overlay and the legacy composer
clip-mask stay heavier by function (masking), now token-mix + blur; composer
attachment tiles/pills and the theme-blind bg-black/50 name bar move to token
tints; legacy composer path gets the standard hook; composer loading stub and
review-tab header/diff surfaces convert to the glass tokens; classic landing
metadata gets a dense-zone chip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ll audit

ui: allowlist covers every swept file (+ pre-allowed entries for the parallel
draft-landing rebuild: pages/new-session.tsx, session-new-design-view, and the
work-order's pages/session/new-session.tsx alias); new assertions pin the
AMICO family hooks + no-opaque-layer fills, dock unification across kinds,
question-option dense tiles, no-opaque-band-inside-glass (sticky triggers,
accordion, task card, diagnostics tint, diff view, inline code), muted-ink
backings, floating-chrome recipes (dialog/popover/menu/select/toast-v2/
ImagePreview), heavier inverse glass for tooltip/toast/copy-tooltip, review
surfaces, and error-tint-over-glass replacing the old no-glass error ruling.
app: sticky title band asserted on the glass vars (chrome literals banned),
timeline data-glass census, dock/composer chrome coverage, drag-overlay and
legacy clip-mask pinned as heavier-by-function token mixes.

These fail if any fix is reverted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…st Brain

The empty landing shows the full latent network ("everything amico could
think") as a clustered ellipsoid cloud rotating in 3D, projected inside the
existing canvas engine (new constellation mode; reuses the rAF loop, governor,
pause/resume, theme re-key, reduced-motion). Curated core + seeded procedural
densification → identical constellation every launch. Dim monochrome + whisper
cluster tints, ZERO #fff676 (yellow stays exclusive to live thought). Twinkle +
breath micro-motion; static ¾ tableau under reduced-motion. First prompt →
ignition dissolve → live session graph. Removes the opaque new-session hero
wrapper that was occluding the Brain entirely, and glasses the draft-landing
chips + metadata. DEV knobs: ?constellationSpeed/Density/Tint/Fog.

Design of record: grilled with Kate 2026-07-25 (landing-only; clustered cloud;
canvas projection; mono+cluster-tint; ignition dissolve; twinkle+breath; static
tableau; uniform full-bleed). Part of #56 (PR #64).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kateebonner and others added 2 commits July 25, 2026 17:16
# Conflicts:
#	packages/app/src/components/session/session-new-view.tsx
#	packages/ui/src/amicode/getting-started.tsx
…k composer, typewriter placeholder, 3D constellation in-session

Live design-review iteration with Kate (2026-07-25) on the Living Chat:

Glass
- Max transparency: dark tint derives to fully transparent (backdrop
  brightness 0.4 -> 0.8; less darkening lets the constellation read through).
  AA retained for LIGHT, waived-and-recorded for DARK standard (the landing
  constellation is yellow-free, so it reads there). Tests record the trade.
- The glass tier is now JUST blur + tint + radius — no border outline, no top
  sheen/inset line, no box-shadow (Kate: "no border, no top line, no shadow").

Composer
- One background: dock-surface shell/tray opaque fills scoped to :not([data-glass])
  so the glass wins as one uniform surface; footer inset fill removed (was a
  visible second background).
- Full-bleed bottom dock: full width, stuck to the bottom, ~35% viewport height
  (ui-ux-pro-max: primary CTA without eclipsing the hero), edge-to-edge (radius/
  border/shadow zeroed). Fixed the flex height-chain so it fills to the bottom.
- Removed the model-provider H-mark/AMICODE wordmark and the project/folder
  picker from the landing.

Landing
- Starter chip wall removed (competed with the constellation + composer).
  Discovery now lives in the composer as a rotating TYPEWRITER placeholder that
  types out the real starter prompts letter-by-letter with a blinking caret;
  freezes on focus (Tab accepts the shown one), static under reduced motion.
- Constellation contrast bumped (edge alpha 0.10 -> 0.17, nodes x1.4).

Session parity
- The 3D constellation is now the background EVERYWHERE (session too), not the
  sparse 2D live graph — the launch and session are one surface. (Live-thought
  node pulsing is the next layer.)

Gates: ui 438 / app 473 / typecheck 23/23 / lint 0 errors. Part of #56 (PR #64).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kateebonner

Copy link
Copy Markdown
Contributor Author

Live design-tuning batch (Kate, 2026-07-25) — commit 69ebf7e

The design evolved significantly beyond the original slices through a live review session. Landed:

  • Glass — now purely blur + tint + radius: dark derives to fully transparent (brightness 0.8), no border, no top sheen, no box-shadow. AA kept for light, waived+recorded for dark standard (the landing constellation is yellow-free).
  • Composer — one uniform glass surface (two-tone fixed); full-bleed bottom dock, ~35% viewport height, edge-to-edge; wordmark + project/folder picker removed.
  • Landing — starter-chip wall removed; discovery moved into the composer as a rotating typewriter placeholder (types the real starters letter-by-letter, blinking caret, Tab-to-accept, reduced-motion static). Constellation contrast bumped.
  • Session parity — the 3D constellation is now the background in-session too (not the sparse 2D graph); launch + session are one surface.

Queued (next): live-thought node pulsing over the constellation (data-true layer), card width containment, and folding the effort/variant selector into the model dropdown.

Gates: ui 438 / app 473 / typecheck 23/23 / lint 0 errors.

🤖 Generated with Claude Code

…lass sweep

Overnight batch 2 (Kate 2026-07-25), three asks:

1. Live thought over the constellation — the '+ live thought' half of
   'constellation + live thought': real session touches flare their node
   in css.thought (#fff676 dark / #8f8000 light) over the latent web —
   rise 150ms, ease-out decay ~1.6s, expanding ring, incident-edge
   glints, touched label beside the flare (fg ink + halo). Labels hash
   deterministically into their category lobe with a visible-node walk
   (a flare the user can't see isn't thought). Replays restore silently;
   re-touches refresh instead of stacking; capped at 24; reduced motion
   holds ONE statically lit node. Dev hook window.__amicoBrainTouch
   (mirrors __amicoBrainStats) previews flares without a real turn.
   +7 tests incl. byte-determinism under touches and the color-law
   boundary (latent web ink stays yellow-free with zero touches).

2. Thinking effort folded INTO the model surface — the standalone
   Default/None/High footer Select is gone (both composer paths). New
   ModelVariantRow renders in the paid ModelSelectorPopover AND the
   unpaid dialog (Kate's dev path): chips on --accent-fill-soft /
   --accent-edge, keeps the menu open on pick; the collapsed trigger
   reads 'Model · High' so effort stays visible at rest.

3. Session glass sweep to the launch-composer feel — glass is
   blur+tint+radius ONLY, now enforced in-session: dock-prompt ring +
   permission/question footer border-top scoped off-glass; composer
   focus ring removed; comment chips borderless; dock radius 10px →
   var(--radius-lg). Width containment: tool collapsibles, diffs group,
   reasoning-part, error-card all share the prose measure
   (min(88%, 72ch)) — floating cards on the Brain, never full-width
   bands.

Gate: ui 445 / app 473 / typecheck 23 projects / lint 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner

Copy link
Copy Markdown
Contributor Author

Overnight batch 2 — 05fa001d0

All three queued items from the live-tuning session, plus the new ask (session components on the launch-composer feel):

1. Live thought over the constellation ✨

The "+ live thought" half of constellation + live thought is in. As amico works, each real touch flares its constellation node in the thought color (#fff676 dark / #8f8000 light — the brand law holds per scheme): fast rise, ~1.6s ease-out decay, an expanding ring, glints down the node's incident edges, and the touched label ("session.tsx", "amico-vault") named beside the flare.

  • Labels hash deterministically into their category lobe (file work lights the code lobe, skills the skills lobe…), then walk to a visible node — a flare you can't see isn't thought.
  • History replays silently on mount; re-touches refresh their flare instead of stacking; capped at 24 so a torrent stays a shimmer.
  • Reduced motion: the tableau holds one statically lit node — where amico is now.
  • Dev preview without a real turn: window.__amicoBrainTouch({label:"x.ts", type:"resource"}) in the console (the ?-param pattern doesn't survive the router redirect, so this rides the __amicoBrainStats hook pattern instead).
  • +7 tests: flare paint, light-scheme ink, silent replay, refresh-not-stack, decay-to-rest, reduced-motion tableau, and byte-determinism under touches. The latent-web color law tests still pin zero yellow with zero touches.

2. Thinking effort lives in the model menu

The standalone Default/None/High Select is gone (both composer paths). A ModelVariantRow renders inside the paid popover and the unpaid dialog (the dev/free path — it would otherwise have lost the control entirely): chips on --accent-fill-soft/--accent-edge, picking one keeps the menu open. The collapsed trigger now reads "DeepSeek V4 Fl… · High" so effort stays visible at rest.

3. Session glass sweep — the launch-composer feel everywhere

Glass = blur + tint + radius, nothing else, now enforced in-session too:

  • dock-prompt (permission/question card): 1px ring removed, footer border-top removed (one surface, same law as the composer footer), radius 10px → --radius-lg.
  • In-session composer: focus-within ring removed (the caret carries focus; drag keeps its dashed dropzone).
  • Comment chips: borderless dense tint.
  • Width containment: tool collapsibles ("Explored · 2 searches"), the diffs group, reasoning, and error cards all share the prose measure — min(88%, 72ch) — so the thread reads as floating cards over the Brain, never full-width bands.

Verified live in both themes on real sessions (silent replay ✓, live flare mid-session ✓, permission card ✓).

Gate: ui 445 / app 473 / typecheck / lint 0 errors.

kateebonner and others added 4 commits July 26, 2026 12:38
… session composer = launch dock

Live review with Kate (2026-07-26), three asks:

1. 'I don't see the flares' — thought was landing behind the message
   column's glass. The engine now takes an occlusion set (occlude());
   session.tsx measures the real layout (timeline column band + composer
   dock) and BrainAtmosphere feeds it fresh before every event flush, so
   flares land in the GUTTERS where the Brain is actually visible
   (fallback: merely-visible beats nothing). While the session works,
   the NEWEST flare holds lit as a sustained 'amico is HERE' cursor and
   decays out when the turn ends. +3 tests (gutter avoidance, hold/decay,
   fully-occluded fallback).

2. Cards hug their contents — tool collapsibles and the diffs group are
   width: fit-content up to the prose measure, never a padded-out band.

3. The session composer IS the launch composer — same full-bleed bottom
   dock (~35% of the pane, edge-to-edge one-surface glass) via
   placement='inline'; starter/typewriter suggestions stay gated to the
   EMPTY LANDING (params.id gates on rotation, typing, Tab-accept,
   placeholder). Legacy layout keeps the floating column card.

Gate: ui 448 / app 473 / typecheck / lint 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ttom-stacked flow + full-width header

Live review with Kate (2026-07-26), second batch:

- Thought-tracking camera v2: rotation eases to a stop while flares are
  alive and the view zooms (1.6x) + glides the newest thought to the
  CENTER of the frame (Kate's call — replaces the gutter stage). All 6
  confirmed findings from the adversarial review workflow fixed:
  (1) conPulses is RECENCY-ordered — a re-touch splices to the end, so
  the camera + busy-hold follow the re-fired concept, never a stale
  array-last pulse; (2) ignite() no longer spins the stopped web back up
  mid-dissolve (conRotK frozen during ignite) and the camera fast-eases
  home (tau 200ms) before the live layer co-paints; (3) an OS
  reduced-motion flip mid-track snaps the camera home instantly;
  (4) edges/glints/ring/bloom scale with the zoom — a camera dolly, not
  dots inflating over a hairline web; (5) flare seating is computed in
  AMBIENT space so the zoomed viewport never funnels subsequent flares
  into one slice; (6) the busy-hold is budgeted (~30s) so a wedged
  active signal or ?brainForceActive cannot freeze the camera forever.
  +2 tests (hold budget, seat-vs-camera split); 452 ui tests green.

- Session header: full-width band, bottom padding tight unless the
  entity-chips rail rendered (CSS :has), and the band now lives OUTSIDE
  the scroller, pinned at the pane top.

- Messages: rows span the pane — user messages justify RIGHT, amico's
  justify LEFT (each card keeps its reading measure); the Brain owns the
  middle where the camera stages thought.

- Bottom-stacked flow (messenger law): the SCROLLER's height is
  content-driven up to the space the header leaves and anchors to the
  bottom, so a short thread sits just above the composer; inside it
  scrolling stays classic top-anchored — virtua's geometry is untouched
  (an mt-auto-in-viewport variant starved virtua's visible range and
  was abandoned). startMargin 0, sticky-accordion offsets updated.

Gate: ui 452 / app 473 / typecheck / lint 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Kate 2026-07-26 (component audit): the collapsed 'edit · Failed' chip was
banding across the pane — width: fit-content capped at the prose measure,
matching the width law every timeline card now follows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…erity

Kate 2026-07-26: glass is blur+tint+radius; the 2px Card accent rail read
as a border on the failed/error cards. content:none on the ::before for
tool-error-card and .error-card — the danger tint, icon, and ink alone
mark severity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner marked this pull request as draft July 26, 2026 23:19
@kateebonner

Copy link
Copy Markdown
Contributor Author

Parked 2026-07-26 — converting to draft. Aaron's call: not pursuing this UI direction right now. Everything through 83d070ae4 is on the branch (living-chat glass redesign, thought-tracking camera, bottom-stacked edge-justified flow, effort-in-model-menu, component audit + width law). The branch is the complete archive of the direction if we return to it; the component library artifact documents every surface.

@kateebonner
kateebonner marked this pull request as ready for review July 29, 2026 00:21
@kateebonner
kateebonner marked this pull request as draft July 29, 2026 00:23
@jack-champagne

Copy link
Copy Markdown
Member

@kateebonner — question before this ages further: is anything here still worth keeping?

Asking because ADR 0002, which this implements, is marked superseded on mainline:

Status: Superseded by ADR 0003 (direction parked 2026-07-26; the Brain moved to the context-tree top panel instead of becoming the chat background)

and ADR 0003 (Accepted, 2026-07-27, on Aaron's 2026-07-26 feedback) is explicit:

Supersedes: ADR 0002 (Brain as chat background — direction parked)
… Aaron's feedback reframed what the graph is for: not ambience, but orientationThe graph moves out of the timeline into a pinned top panel … the ambient background direction is parked.

The ADR-0003 replacement has fully landed

All of this is on local/amicode and shipped in v1.17.3-amicode.11:

So the top-panel + first-class vault surface direction is done and released.

What's still unique to this branch

brain-engine.ts and context-tree-engine.ts are already on main — the graph engine itself made it across. What has no counterpart is the presentation layer for the parked direction:

only in #64
glass.css (778 lines), glass-tokens.ts, script/generate-glass.ts
brain-atmosphere.tsx / .css
brain-constellation.ts
brain-perf-governor.test.ts, brain-events.ts, e2e/perf/brain-governor-trace.spec.ts

16 added files, 54 modified, 1 deleted.

Why I'm asking rather than just closing

Two things in there look potentially valuable independent of the parked background direction:

  1. The legibility machineryglass-tokens.ts plus the WCAG-AA-floored tint derivation. ADR 0002 records that the earlier attempt failed exactly one AA check (muted grey on the most translucent tier), so this encodes a real lesson. Worth salvaging if any surface still layers text on translucency — the session header's backdrop-blur comes to mind, given fix(session): header backdrop-blur off while the context-tree band is open #97 just had to switch it off over the context-tree band.
  2. brain-perf-governor + the e2e perf trace — frame-budget governance for the graph. The organic context tree that did land has the same cost profile, so a perf governor may be wanted regardless of where the graph renders.

If neither is worth extracting, this is a clean close — the direction is parked and the replacement is released. If either is, they'd be small standalone PRs rather than resurrecting 71 files.

For context on the state: it is still a draft, CONFLICTING/DIRTY, 72 commits behind mainline, and its checks are all CANCELLED from before #2 fixed the runner labels — so CI has never actually evaluated this branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make the Brain the Chat's living background; float components on legibility-floored Glass

2 participants