.enter-stage { opacity:0 }; reduced-motion disables stageRise → orb hiddenopacity:1 + min-height on .stage/#orbCanvas; reduced-motion fallback; refitOrbCanvas (2026-05-25 · proto-b-orb-visible-fix-2026-05-25)margin-top:-100px / margin-bottom:50pxtranslateY(-100px/-50px) transform-only; mic scale(0.9) (2026-05-25 · proto-b-dock-px-lift-100-50-2026-05-25)translateY(-10%) only on .voice-capture-row > .micscale(0.9) on mic; row translateY(-50px); hover scale(0.945) (desktop + mobile) (2026-05-25 · proto-b-mute-scale-90-2026-05-25)proto-b-animation-perf-obsessive-2026-05-25)proto-b-cloud-swoosh-voice-clusters-2026-05-25!phraseListenStarted vs live armed mismatchuserMuted || !armed + SR auto-restart after onend when unmutedpassphrase-hearing + micLevel / state–driven --phrase-progress boostrotate(360deg) glint, particle swirl, pulsing interrupted radialsr̂>0.76 blur halo)ttsEnergy speak boost — zero mouth geometry in particle xy/α (2026-05-25)749d748)d twinkle | d on passphrase-complete / unlock (2026-05-25)--phrase-progressphraseProgressSmoothed) (2026-05-25)translateY(-100px) on .mic-passphrase (desktop + mobile; transform only) (2026-05-25).sub.status-listening-hint “I'm listening” only; title hidden; +3% translateY in hint band (2026-05-25)proto-b-outer-halo-97-blur-2026-05-25 onlyproto-b-d-twinkle-shimmer-listen-2026-05-25 (+ halo marker retained)isCaptureStripLive; CSS bar lerp; stub-only mock reply TTS0:00 + 24 AnalyserNode bars; unmute → record strip; passphrase complete → autosubmit voice note (2026-05-25)submitVoiceCapture({reason:'passphrase'}) in triggerUnlock; Sent flash; silence → securityEndOfUtterance / speakSecurityLine only (2026-05-25)deliverBotTurn / converse clerk mockSECURITY_API client — /api/auth/voice/*, /api/auth/pin/verify, Whisper /v1/audio/*; getApiKey() via build inject or dev localStorage; fallback SECURITY_LINES when offline (2026-05-25 · proto-b-security-backend-endpoints-2026-05-25)fetch when VITE_SECURITY_API_ENABLED + base URL (2026-05-25 · merges proto-b-dumb-security-voice)speakLine open text; gate intro + clerk stubsSECURITY_LINE_TEXT + speakBotReply id-only; five security utterances + PIN deny TTS (2026-05-25 · proto-b-no-tax-speech-2026-05-25)proto-b-animation-perf-obsessive-2026-05-25 latest onlyproto-b-cloud-swoosh-voice-clusters-2026-05-25 (+ perf / polish / autosubmit markers retained).voice-capture-rowtranslateY(-50px) on .voice-capture-row; scale(0.9) on mic (desktop + mobile) (2026-05-25).pin-entry-hint “Enter PIN Instead” above button — Poppins, rgba(233,234,239,0.50); dock order unchanged (2026-05-25 · proto-b-pin-hint-enter-instead-2026-05-25)286px card, 44px keys, blur(34–36px) saturate(180%), bottom sheet anchor; pinSheetSuccess + pinCheckFade (340ms · cubic-bezier(0.22,1,0.36,1)); .unlock-burst.pin-soft for PIN path (2026-05-25 · proto-b-pin-compact-glass-success-2026-05-25)VITE_* injection + deliverBotTurn/converse stubs + MASTER rows 22–25; marker proto-b-security-bidir-validated-2026-05-25 (2026-05-25)--ease-product table; dt 8–48ms; exp cloud/swoosh/cluster/phrase/mouth; single twinkle + unlock; PIN layout flush + one rAF; marker proto-b-obsessive-animation-2026-05-25 (2026-05-25)aria-pressed synced to mute state, passphrase aria-live, PIN focus trap + Escape + labelled keys + Enter PIN keyboard, reduced-motion orb visible, changelog tabindex=-1 (2026-05-25 · proto-b-a11y-restore-2026-05-25)navigatePinGridKey ArrowUp/Down/Left/Right + activatePinKeyFromKeyboard Enter/Space on focused keys; mic :focus-visible (2026-05-25 · proto-b-a11y-functions-recovered-2026-05-25)micPromptDone blocked retry; file:// silent fail; aria-pressed driftscripts/serve-proto-b.sh; PROTO_B_DEBUG logs only (2026-05-25 · proto-b-mic-fix-2026-05-25)onend cleared armed during SR restart; unmuteMic without armed; security-only end-of-utteranceunmuteMic → armed + SR restart; analyser stream kept; local phrase fallback when API off (2026-05-25 · proto-b-mic-verified-2026-05-25)