The mode switch was toggling the `hidden` attribute on elements that each carry
their own `display:` rule. A class selector beats the UA stylesheet's
[hidden]{display:none}, so every one of those toggles silently did nothing —
which is why workspace mode still showed the chat, and why coming back never
restored the saved-chat list. Every affected element was in that state.
CSS now owns both modes from a single body class, in one block, and the JS does
nothing but set that class. No element.hidden juggling remains.
One accent. The assistant used --blue for user bubbles, focus rings, blockquotes
and example pills while citations, cards and the mode switch used --purple, so
the two halves read as two different apps. Purple was already dominant (23 uses
to 6) and is the assistant's identity, so blue is gone entirely. Source cards
pick up the same shape, shadow and hover accent as the workspace cards, and a
targeted citation highlights in the accent instead of a bare border.
Go back is removed from both the topbar and the rail: the Assistant/Workspace
switch is how you leave now, and the dead handler went with it.
Create image no longer takes a full-width gradient row competing with New chat;
it is a square icon button beside it with a tooltip and an aria-label.
Also guards the delegated document listeners against double registration.
initIfNeeded already prevented a second bind in production, but nothing stopped
a stray bindEvents() from double-firing every click — which is exactly what the
test harness hit, activating a tab twice from one click.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WjVc5oaAaYFNbZGLeJp6TX
103 lines
7.3 KiB
HTML
103 lines
7.3 KiB
HTML
<div class="assistant-topbar">
|
|
<button id="btn-assistant-toggle-history" class="assistant-toggle-history" type="button" aria-expanded="true" aria-controls="assistant-history" title="Hide saved chats" aria-label="Hide saved chats"><i class="fas fa-table-columns"></i></button>
|
|
<button id="btn-assistant-mobile-menu" class="btn-sm btn-ghost assistant-mobile-menu" type="button" title="Saved chats"><i class="fas fa-bars"></i></button>
|
|
<div class="assistant-topbar-title">
|
|
<h2><i class="fas fa-brain" style="color:var(--purple);"></i> AI Clinical Assistant</h2>
|
|
</div>
|
|
<div class="assistant-status" id="assistant-status">
|
|
<span class="assistant-dot"></span>
|
|
<span id="assistant-status-text">Ready</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="assistant-layout" id="assistant-layout">
|
|
<div class="assistant-drawer-backdrop" id="assistant-drawer-backdrop"></div>
|
|
<aside class="assistant-history">
|
|
<button id="btn-assistant-drawer-close" class="assistant-drawer-close" type="button" aria-label="Close saved chats"><i class="fas fa-xmark"></i></button>
|
|
<div class="assistant-mode-switch" role="tablist" aria-label="Assistant or workspace">
|
|
<button type="button" role="tab" id="btn-assistant-mode-assistant" class="active" aria-selected="true" data-assistant-mode="assistant"><i class="fas fa-brain"></i> Assistant</button>
|
|
<button type="button" role="tab" id="btn-assistant-mode-workspace" aria-selected="false" data-assistant-mode="workspace"><i class="fas fa-grip"></i> Workspace</button>
|
|
</div>
|
|
<div class="assistant-rail-actions">
|
|
<button id="btn-assistant-clear" class="assistant-new-chat" type="button"><i class="fas fa-plus"></i> <span>New chat</span><kbd class="assistant-kbd">Ctrl+Shift+O</kbd></button>
|
|
<button id="btn-assistant-create-image" class="assistant-create-image" type="button" title="Create image" aria-label="Create image"><i class="fas fa-wand-magic-sparkles"></i></button>
|
|
</div>
|
|
<!-- Rail menu and the card grid are both rendered from the app's real
|
|
.tab-btn list, so neither can drift from the menu it mirrors. -->
|
|
<nav class="assistant-rail-workspace" id="assistant-rail-workspace" aria-label="Workspace" hidden>
|
|
<div id="assistant-workspace-links" class="assistant-rail-links"></div>
|
|
</nav>
|
|
<div class="card">
|
|
<button type="button" class="card-header assistant-chats-header" id="btn-assistant-chats-toggle" aria-expanded="true" aria-controls="assistant-saved-chats">
|
|
<h3><i class="fas fa-bookmark"></i> Saved Chats</h3>
|
|
<i class="fas fa-chevron-down assistant-chats-caret"></i>
|
|
</button>
|
|
<div id="assistant-saved-chats" class="assistant-saved-chats">
|
|
<p class="assistant-muted">Chats save automatically as you go.</p>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<section class="assistant-main card">
|
|
<div id="assistant-workspace-view" class="assistant-workspace-view" hidden>
|
|
<div id="assistant-workspace-cards" class="assistant-workspace-cards"></div>
|
|
</div>
|
|
<div id="assistant-chat-view">
|
|
<div class="assistant-toolbar">
|
|
<div>
|
|
<strong>Clinical Question</strong>
|
|
<span id="assistant-model-label" class="model-tag">Admin model</span>
|
|
</div>
|
|
<div class="assistant-toolbar-actions">
|
|
<button id="btn-assistant-export-pdf" class="btn-sm btn-ghost" type="button"><i class="fas fa-file-pdf"></i> Export PDF</button>
|
|
<button id="btn-assistant-download-chat" class="btn-sm btn-ghost" type="button"><i class="fas fa-download"></i> Download transcript</button>
|
|
<button id="btn-assistant-takehome" class="btn-sm btn-ghost" type="button"><i class="fas fa-heart"></i> Patient take home</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="assistant-messages" class="assistant-messages" aria-live="polite">
|
|
<div class="assistant-empty">
|
|
<h3>Pediatric Clinical Assistant</h3>
|
|
<p class="assistant-empty-badge"><i class="fas fa-book-medical"></i> Answers built only from your indexed library</p>
|
|
<div class="assistant-examples">
|
|
<button type="button" data-assistant-example="In a 4-year-old with acute wheeze, when should magnesium sulfate be considered and what dose is recommended?">Status asthma escalation</button>
|
|
<button type="button" data-assistant-example="What are the red flags for bilious vomiting in neonates, and what immediate workup is recommended?">Bilious vomiting</button>
|
|
<button type="button" data-assistant-example="Compare bronchiolitis and asthma management in infants, citing clinical references.">Bronchiolitis vs asthma</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="assistant-form" class="assistant-composer">
|
|
<label for="assistant-input">Clinical question</label>
|
|
<div class="assistant-model-pill" id="assistant-model-pill">
|
|
<select id="assistant-chat-model-select" class="assistant-model-control" aria-label="Chat model" hidden></select>
|
|
</div>
|
|
<textarea id="assistant-input" rows="1" placeholder="Ask a focused clinical question..." autocomplete="off" aria-describedby="assistant-context-warning"></textarea>
|
|
<div id="assistant-context-warning" role="alert" hidden></div>
|
|
<div id="assistant-attachments" class="assistant-attachments" aria-label="Attached images" hidden></div>
|
|
<div class="assistant-composer-footer">
|
|
<span id="assistant-autosave-state" class="assistant-autosave-state" aria-live="polite"></span>
|
|
<div class="assistant-tools">
|
|
<label class="assistant-attach" for="assistant-attach-input" title="Attach up to 4 images (PNG, JPEG, WebP)"><i class="fas fa-paperclip"></i></label>
|
|
<input type="file" id="assistant-attach-input" accept="image/png,image/jpeg,image/webp" multiple hidden>
|
|
<button id="btn-assistant-voice" class="assistant-voice-btn" type="button" title="Voice conversation"><i class="fas fa-headset"></i></button>
|
|
<button id="btn-assistant-mic" class="assistant-mic" type="button" title="Dictate your question"><i class="fas fa-microphone"></i></button>
|
|
</div>
|
|
<button id="btn-assistant-send" class="btn-send" type="submit"><i class="fas fa-arrow-up"></i></button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
</section>
|
|
|
|
<aside class="assistant-side">
|
|
<div class="card">
|
|
<div class="card-header"><h3><i class="fas fa-quote-right"></i> Sources</h3></div>
|
|
<div id="assistant-sources" class="assistant-sources">
|
|
<p class="assistant-muted">Citations appear here after an answer.</p>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
|
|
<link rel="stylesheet" href="/css/assistant.css">
|