Make the Brain the Chat's living background; float components on legibility-floored Glass - #64
Make the Brain the Chat's living background; float components on legibility-floored Glass#64kateebonner wants to merge 34 commits into
Conversation
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>
…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>
HITL sign-off checklist — reference-laptop 60fps gate (#63)The one open acceptance criterion on this PR. Run on the reference laptop, battery-powered:
If the gate fails: remove 🤖 Generated with Claude Code |
…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>
# 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>
Live design-tuning batch (Kate, 2026-07-25) — commit 69ebf7eThe design evolved significantly beyond the original slices through a live review session. Landed:
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>
Overnight batch 2 —
|
… 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>
|
Parked 2026-07-26 — converting to draft. Aaron's call: not pursuing this UI direction right now. Everything through |
|
@kateebonner — question before this ages further: is anything here still worth keeping? Asking because ADR 0002, which this implements, is marked superseded on mainline:
and ADR 0003 (
The ADR-0003 replacement has fully landedAll of this is on
So the top-panel + first-class vault surface direction is done and released. What's still unique to this branch
16 added files, 54 modified, 1 deleted. Why I'm asking rather than just closingTwo things in there look potentially valuable independent of the parked background direction:
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, |
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:
Mount the Brain chat-wide and absorb the inline brain strip #59 — Brain mounted chat-wide (session + landing draft), inline brain strip absorbed (one render loop;
TimelineRow.Brainretired; shimmer kept); live event feed extracted to pure, testedderiveBrainEvents.Derive two AA-floored, chat-theme-keyed Glass tint tiers with a contrast test #60 — two-tint AA-floored Glass token system (
data-glass="standard|dense", one 18px constant blur, chat-theme-keyed per-mode tints derived against the per-theme reference frame — dark#fff676/ light#8f8000— with a certified contrast test;@supportsfallback).Float chat components on the two Glass tiers (standard prose/bubbles/composer, dense code/diffs/plots/tools) #61 — everything floats: standard tier on bubbles/prose/composer, dense on code/diffs/run-plots/tool cards; opaque fills removed so the Brain lives in the gaps; muted ink dense-backed by measurement; browser-verified over the live Brain, both themes.
Drive the Brain by session activity: adaptive heartbeat, sparse-seed rest, bounded in-place growth #62 — adaptive heartbeat (
setActive+ shared draw-gate: full tempo working, ~8fps rest), reduced-motion hard-pause (burst-then-still), sparse-seed boot (core alone; grows only from session activity), total-population cap with recency eviction, fixed camera (densify in place). Orphaned skeleton dataset removed at integration.Add the perf governor (ease motion, never blur) and gate 60fps on the reference laptop #63 — perf governor: ease ladder under sustained over-budget p95 (window-scoped, hysteresis dead-band, no oscillation) → terminal hard-pause to a static blurred field; blur/tint pinned untouched by test; DEV
?brainForceActivehook; headless perf-trace proxy (e2e/perf/brain-governor-trace.spec.ts). Issue left open for itshitlacceptance criterion — see the sign-off checklist below.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