diff --git a/src/lib/components/Composer.svelte b/src/lib/components/Composer.svelte index 48de64bd..7a4afda5 100644 --- a/src/lib/components/Composer.svelte +++ b/src/lib/components/Composer.svelte @@ -61,6 +61,32 @@ let fileInput = $state(); let dragging = $state(false); + // Overflow ("⋯") group: below the composer's own container-width breakpoint the + // trust pill + Prompts + Enhance collapse behind this toggle. The controls exist + // exactly once in the DOM; CSS (a container query, so browser sidebars count) + // decides whether they render inline or inside the popover. + let moreOpen = $state(false); + let moreBtn = $state(); + let morePanel = $state(); + + $effect(() => { + if (!moreOpen) return; + const onDown = (e: MouseEvent) => { + const t = e.target as Node | null; + if (moreBtn?.contains(t) || morePanel?.contains(t)) return; + moreOpen = false; + }; + const onKey = (e: KeyboardEvent) => { + if (e.key === 'Escape') moreOpen = false; + }; + document.addEventListener('mousedown', onDown); + document.addEventListener('keydown', onKey); + return () => { + document.removeEventListener('mousedown', onDown); + document.removeEventListener('keydown', onKey); + }; + }); + onMount(() => { modelStore.load(); }); @@ -110,7 +136,7 @@
{ @@ -223,7 +249,7 @@ class="max-h-48 w-full resize-none bg-transparent font-serif text-mlq-text outline-none placeholder:text-mlq-muted" > -
+
- + +
+ + {#if promptLibrary} + + {/if} + {#if enhance} + {#if enhance.status === 'loading'} + + Enhancing… + + + {:else} + + {/if} + {/if} +
{#if matters} {/if} @@ -255,22 +327,22 @@ aria-checked={sticky.enabled} data-testid="sticky-toggle" onclick={() => sticky.toggle(skillAttach?.names ?? [])} - class="inline-flex items-center gap-1.5 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs {sticky.enabled + class="inline-flex items-center gap-1.5 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs whitespace-nowrap {sticky.enabled ? 'bg-mlq-subtle text-mlq-strong' : 'text-mlq-text'}" title="Keep the skills applied in this chat on for follow-up messages" > - Keep skills on + Skills stay on {#if sticky.enabled && sticky.set.length > 0} · Keeping {sticky.set.length} on· {sticky.set.length} {/if} @@ -298,42 +370,17 @@ {/if} - {#if promptLibrary} - - {/if} - {#if enhance} - {#if enhance.status === 'loading'} - - Enhancing… - - - {:else} - - {/if} - {/if} + {#if streaming} {#if open} diff --git a/src/lib/components/SkillAttach.svelte b/src/lib/components/SkillAttach.svelte index 93a2b1d4..704e8632 100644 --- a/src/lib/components/SkillAttach.svelte +++ b/src/lib/components/SkillAttach.svelte @@ -57,7 +57,7 @@ aria-expanded={open} aria-label="Attach skill" onclick={toggle} - class="inline-flex items-center gap-1 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs text-mlq-text" + class="inline-flex items-center gap-1 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs whitespace-nowrap text-mlq-text" > Skill diff --git a/src/lib/matters/MatterPicker.svelte b/src/lib/matters/MatterPicker.svelte index c1f552c9..b1d04dc8 100644 --- a/src/lib/matters/MatterPicker.svelte +++ b/src/lib/matters/MatterPicker.svelte @@ -45,7 +45,7 @@ aria-expanded={open} aria-label={current ? `Matter: ${current.name}` : 'Choose matter'} onclick={() => (open = !open)} - class="inline-flex max-w-[180px] items-center gap-1 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs {current + class="inline-flex max-w-[180px] items-center gap-1 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs whitespace-nowrap {current ? 'text-mlq-text' : 'text-mlq-muted'}" > diff --git a/src/lib/prompts/PromptPicker.svelte b/src/lib/prompts/PromptPicker.svelte index 0a39f5ba..b25cb056 100644 --- a/src/lib/prompts/PromptPicker.svelte +++ b/src/lib/prompts/PromptPicker.svelte @@ -89,7 +89,7 @@ aria-expanded={open} aria-label="Prompts" onclick={toggle} - class="inline-flex items-center gap-1 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs text-mlq-text" + class="inline-flex items-center gap-1 rounded-mlq-control border border-mlq-subtle px-2.5 py-1 text-xs whitespace-nowrap text-mlq-text" > Prompts diff --git a/src/routes/(app)/about/assistant/+page.svelte b/src/routes/(app)/about/assistant/+page.svelte index beb506d0..7ad62fd5 100644 --- a/src/routes/(app)/about/assistant/+page.svelte +++ b/src/routes/(app)/about/assistant/+page.svelte @@ -74,13 +74,13 @@ to a single message; each is sent alongside your prompt.

-

Keep skills on

+

Skills stay on

- Once you have a skill attached to a message, the Keep skills on toggle in the + Once you have a skill attached to a message, the Skills stay on toggle in the composer toolbar lets you carry that skill — and any others attached — into every follow-up turn - of the same chat without re-attaching. When active, a quiet "Keeping N on" - indicator appears alongside the toggle; hover it to see the skill names that are being carried forward. + of the same chat without re-attaching. When active, a quiet "· N" count appears inside + the toggle; hover it to see the skill names that are being carried forward.