From bc4bec5a29afaa6a66015d841188e260be583f95 Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Sun, 12 Jul 2026 18:32:37 -0700 Subject: [PATCH] Turn Live Lab into a UI workbench AI-assisted: OpenAI Codex. --- site/components/LiveUiGallery.astro | 147 +++ site/pages/live-lab/index.astro | 165 ++- site/scripts/live-lab-workbench.js | 73 ++ site/scripts/live-ui-gallery.js | 484 ++++++++ site/styles/live-lab-workbench.css | 542 +++++++++ site/styles/live-ui-gallery.css | 1708 +++++++++++++++++++++++++++ 6 files changed, 3081 insertions(+), 38 deletions(-) create mode 100644 site/components/LiveUiGallery.astro create mode 100644 site/scripts/live-lab-workbench.js create mode 100644 site/scripts/live-ui-gallery.js create mode 100644 site/styles/live-lab-workbench.css create mode 100644 site/styles/live-ui-gallery.css diff --git a/site/components/LiveUiGallery.astro b/site/components/LiveUiGallery.astro new file mode 100644 index 000000000..ccecd531e --- /dev/null +++ b/site/components/LiveUiGallery.astro @@ -0,0 +1,147 @@ +--- +import '../styles/live-ui-gallery.css'; +import { LIVE_COMMANDS } from '../../skill/scripts/live/vocabulary.mjs'; + +const STATE_GROUPS = [ + { + label: 'Global chrome', + states: [ + ['global-ready', 'Ready'], + ['global-disconnected', 'Agent disconnected'], + ['global-tools', 'Detect + DESIGN.md'], + ['steer-expanded', 'Steer composing'], + ['steer-processing', 'Steer processing'], + ], + }, + { + label: 'Selection', + states: [ + ['configure-replace', 'Configure selection'], + ['action-picker', 'Action picker'], + ['configure-listening', 'Voice input'], + ['configure-locked', 'Apply locked'], + ['annotation', 'Annotations'], + ['insert-placeholder', 'Insert placeholder'], + ], + }, + { + label: 'Generation + review', + states: [ + ['generating', 'Generating'], + ['generation-recovery', 'Recovery'], + ['cycling-progressive', 'Variant 1 arrived'], + ['cycling-second', 'Variant 2 arrived'], + ['tune-open', 'Tune panel'], + ['applying', 'Applying variant'], + ['confirmed', 'Variant applied'], + ], + }, + { + label: 'Copy + support', + states: [ + ['edit-copy', 'Edit copy'], + ['copy-pending', 'Copy edits pending'], + ['copy-applying', 'Copy edits applying'], + ['copy-attention', 'Apply needs attention'], + ['design-panel', 'DESIGN.md panel'], + ['toast-error', 'Error toast'], + ], + }, +]; + +const statePayload = STATE_GROUPS.flatMap((group) => + group.states.map(([key, label]) => ({ key, label, group: group.label })), +); +const commandPayload = JSON.stringify(LIVE_COMMANDS).replace(/ + + + diff --git a/site/pages/live-lab/index.astro b/site/pages/live-lab/index.astro index 0095a17c7..d767a95b7 100644 --- a/site/pages/live-lab/index.astro +++ b/site/pages/live-lab/index.astro @@ -1,5 +1,6 @@ --- import Base from '../../layouts/Base.astro'; +import LiveUiGallery from '../../components/LiveUiGallery.astro'; import benchmarkData from '../../data/live-performance.json'; import { currentHarnessProbe, harnessPaths, liveExperiments } from '../../data/live-harnesses'; import { progressiveDeliveryResult } from '../../data/live-progressive-result'; @@ -11,6 +12,7 @@ import { liveCodexWorkerResult } from '../../data/live-codex-worker-result'; import { liveAnnotatedResult } from '../../data/live-annotated-result'; import '../../styles/sub-pages.css'; import '../../styles/live-performance.css'; +import '../../styles/live-lab-workbench.css'; const reports = 'reports' in benchmarkData ? benchmarkData.reports : [benchmarkData]; const plainReports = reports.filter(report => report.benchmark.scenario === 'plain' && report.benchmark.agent === 'fake'); @@ -73,40 +75,88 @@ const providerColumns = [ -
- - - Impeccable - -
- Live Latency Lab - Development benchmark -
-
-
-
-

Live latency lab · optimization result

-

Capture left
the critical path.

+
+ + +
+
+
+

Runtime overview

+

Critical path and interaction latency

+

Model-free product overhead, progressive review, initialization, and the latency simulator.

+
+
+ benchmarks loaded + Open Live +
+
+ +
+
+
+
+

Latest matched run · first usable variant

+

{displayMs(protocolFloor)} product floor

- The same model-free run fell from {displayMs(baselineFloor)} to {displayMs(protocolFloor)}, a{' '} - {(improvement * 100).toFixed(1)}% reduction. Live now starts the generate fetch in {displayMs(browserDispatch)} median. + Down {(improvement * 100).toFixed(1)}% from {displayMs(baselineFloor)} on the same fixture. Generate dispatch now starts in {displayMs(browserDispatch)} median.

+
+
Browser dispatch
{displayMs(browserDispatch)}
+
Server pickup
{displayMs(serverPickup)}
+
Source scaffold
{displayMs(scaffold)}
+
Write + settle
{displayMs(writeAndRender)}
+
{plain.summary.count} warm runs {plain.benchmark.fixture} @@ -115,7 +165,7 @@ const providerColumns = [
-
+

Click → first usable variant

@@ -172,7 +222,7 @@ const providerColumns = [
-
+

Progressive delivery · Codex path

@@ -212,7 +262,7 @@ const providerColumns = [
-
+

Paid provider matrix · five runs per candidate

@@ -255,7 +305,7 @@ const providerColumns = [

-
+

Configured cold initialization

@@ -286,7 +336,7 @@ const providerColumns = [
-
+

Before / after / control

@@ -321,7 +371,7 @@ const providerColumns = [
-
+

Latency simulator

@@ -347,7 +397,11 @@ const providerColumns = [
-
+
+ +
+ +

Harness delivery

@@ -384,7 +438,7 @@ const providerColumns = [
-
+

Evidence-ranked decisions

@@ -409,7 +463,7 @@ const providerColumns = [
-
+

Measurement contract

bun run bench:live boots a real framework fixture and Chromium, drives Pick → Go → Cycle, @@ -418,10 +472,45 @@ const providerColumns = [ The deterministic agent makes Impeccable overhead visible; model-backed runs remain opt-in because they send fixture context to an external provider.

-
+
+ + + + + + diff --git a/site/scripts/live-lab-workbench.js b/site/scripts/live-lab-workbench.js new file mode 100644 index 000000000..045cbd43d --- /dev/null +++ b/site/scripts/live-lab-workbench.js @@ -0,0 +1,73 @@ +const VIEW_COPY = { + overview: { + kicker: 'Runtime overview', + title: 'Critical path and interaction latency', + summary: 'Model-free product overhead, progressive review, initialization, and the latency simulator.', + }, + providers: { + kicker: 'Generation strategy', + title: 'Provider reliability and review latency', + summary: 'Five-run strict gates across full, compact, progressive, and parallel delivery.', + }, + harness: { + kicker: 'Harness architecture', + title: 'Control lanes, worker wake, and tested decisions', + summary: 'Foreground fallback, dedicated Codex worker evidence, and the ideas that survived testing.', + }, + ui: { + kicker: 'Live chrome gallery', + title: 'Every Live UI state without a running session', + summary: 'Trigger and compare the real control states in light and dark mode.', + }, + all: { + kicker: 'Complete evidence', + title: 'All Live measurements and UI fixtures', + summary: 'The full workbench in one scrollable surface.', + }, +}; + +export function initLiveLabWorkbench(root = document) { + const workbench = root.querySelector('[data-live-lab-workbench]'); + if (!workbench || workbench.dataset.initialized === 'true') return; + workbench.dataset.initialized = 'true'; + + const buttons = [...workbench.querySelectorAll('[data-lab-view]')]; + const panels = [...workbench.querySelectorAll('[data-lab-panel]')]; + const kicker = workbench.querySelector('[data-lab-view-kicker]'); + const title = workbench.querySelector('[data-lab-view-title]'); + const summary = workbench.querySelector('[data-lab-view-summary]'); + const scroller = workbench.querySelector('.live-lab-workspace-scroll'); + + const setView = (requested, { updateHash = true } = {}) => { + const view = VIEW_COPY[requested] ? requested : 'overview'; + for (const button of buttons) { + button.setAttribute('aria-pressed', String(button.dataset.labView === view)); + } + for (const panel of panels) { + panel.hidden = view !== 'all' && panel.dataset.labPanel !== view; + } + workbench.dataset.activeView = view; + if (kicker) kicker.textContent = VIEW_COPY[view].kicker; + if (title) title.textContent = VIEW_COPY[view].title; + if (summary) summary.textContent = VIEW_COPY[view].summary; + if (scroller) scroller.scrollTop = 0; + if (updateHash && window.location.hash !== `#${view}`) { + window.history.replaceState(null, '', `#${view}`); + } + }; + + for (const button of buttons) { + button.addEventListener('click', () => setView(button.dataset.labView)); + } + + workbench.querySelector('[data-lab-reset]')?.addEventListener('click', () => { + const slider = workbench.querySelector('[data-model-latency]'); + if (!(slider instanceof HTMLInputElement)) return; + slider.value = '15000'; + slider.dispatchEvent(new Event('input', { bubbles: true })); + setView('overview'); + }); + + window.addEventListener('hashchange', () => setView(window.location.hash.slice(1), { updateHash: false })); + setView(window.location.hash.slice(1) || 'overview', { updateHash: false }); +} diff --git a/site/scripts/live-ui-gallery.js b/site/scripts/live-ui-gallery.js new file mode 100644 index 000000000..658ee0a16 --- /dev/null +++ b/site/scripts/live-ui-gallery.js @@ -0,0 +1,484 @@ +/* + * Dev-only Impeccable Live state gallery. + * + * This is a static state harness, not a second implementation of Live. It + * mirrors the exact chrome vocabulary and state wording from: + * skill/scripts/live-browser.js + * skill/scripts/live/ui-core.mjs + * Command labels/icons are injected by LiveUiGallery.astro from the canonical + * skill/scripts/live/vocabulary.mjs export. + */ + +const ICONS = Object.freeze({ + pick: '', + insert: '', + detect: '', + chat: '', + voice: '', + submit: '', + tune: '', + edit: '', + trash: '', + exit: '', +}); + +function parseJson(root, selector, fallback = []) { + try { + return JSON.parse(root.querySelector(selector)?.textContent || '[]'); + } catch { + return fallback; + } +} + +function escapeHtml(value) { + return String(value ?? '') + .replaceAll('&', '&') + .replaceAll('<', '<') + .replaceAll('>', '>') + .replaceAll('"', '"') + .replaceAll("'", '''); +} + +function brandMark() { + return ''; +} + +function designMark() { + return ''; +} + +function hostPage({ edited = false, insert = false } = {}) { + return ` +
+

Northstar field journal · Edition 08

+
+

${edited ? 'Useful observations, refined.' : 'Useful observations from the long way around.'}

+

Four routes, annotated maps, and practical details for unhurried weekends.

+
+
`; +} + +function selectionOutline() { + return ''; +} + +function dots({ arrived = 0, visible = 0, expected = 3, clickable = false } = {}) { + let html = ''; + for (let index = 1; index <= expected; index += 1) { + const active = index === visible; + const pending = index > arrived; + const className = `lvg-dot${active ? ' is-active' : ''}${pending ? ' is-pending' : ''}`; + if (clickable && !pending) { + const target = index === 1 ? 'cycling-progressive' : 'cycling-second'; + html += ``; + } else { + html += ``; + } + } + return html + ''; +} + +function configureBar({ actionLabel, count, listening = false, locked = false, insert = false, picker = '' } = {}) { + const inputValue = insert + ? 'Add a compact proof strip' + : listening + ? 'Tighten the hierarchy' + : locked + ? '' + : 'Make this feel more confident'; + const actionControl = insert ? '' : ` + `; + return ` +
+
+
+ + +
+
+
+ ${actionControl} + +
+ + +
+
+ ${picker} +
`; +} + +function actionPicker(commands, selectedAction) { + return ` +
+
+ ${commands.map((command) => ` + `).join('')} +
+
`; +} + +function generatingBar(recovery = false, actionLabel = 'Freeform') { + return ` +
+
+ ${escapeHtml(actionLabel)} + ${dots({ expected: 3 })} + ${recovery ? 'Variants ready. Reveal the selected element to resume.' : 'Source ready. Generating...'} +
+
`; +} + +function tuneButton(open) { + return ` + `; +} + +function cyclingBar({ arrived = 1, visible = 1, tune = false } = {}) { + const remaining = 3 - arrived; + return ` +
+
+ + ${dots({ arrived, visible, expected: 3, clickable: true })} + ${visible}/3 + + ${tuneButton(tune)} + + ${remaining > 0 ? `${remaining} more arriving...` : ''} + + +
+ ${tune ? tunePanel() : ''} +
`; +} + +function tunePanel() { + return ` +
+
+
+
Color amount0.60
+ +
+
+
DensitySnug
+
+ + + +
+
+
+
MotionOff
+ +
+
+
`; +} + +function statusBar(kind) { + if (kind === 'confirmed') { + return '
Variant applied
'; + } + return '
Applying variant...
'; +} + +function editBadge(editing = false) { + if (!editing) { + return `
`; + } + return '
'; +} + +function annotationLayer() { + return ` +
+ + +
Keep this line on one row
+
`; +} + +function pendingDock(kind) { + if (kind === 'attention') { + return ` +
+ + + +
`; + } + const applying = kind === 'applying'; + return ` +
+ + +
`; +} + +function designPanel(tab = 'visual') { + const raw = tab === 'raw'; + return ` + `; +} + +function globalBar({ connected = true, active = 'pick', steer = 'collapsed', detectCount = 0, designActive = false } = {}) { + const modeButton = (key, icon, label, target, extra = '') => { + const isActive = active === key || (key === 'design' && designActive); + return ``; + }; + const steerHtml = steer === 'processing' + ? `
${ICONS.chat}
` + : steer === 'expanded' + ? `
${ICONS.chat}
` + : ``; + + return ` +
+ + ${brandMark()}${connected ? '' : ''} + +
+ ${modeButton('pick', ICONS.pick, 'Pick', 'configure-replace')} + ${modeButton('insert', ICONS.insert, 'Insert', 'insert-placeholder')} + ${modeButton('detect', ICONS.detect, 'Detect', 'global-tools', detectCount ? `${detectCount}` : '')} + ${modeButton('design', designMark(), 'DESIGN.md', 'design-panel')} + ${steerHtml} + + +
+
`; +} + +function sceneFor(state, context) { + const actionLabel = context.commands.find((command) => command.value === context.selectedAction)?.label || 'Freeform'; + const commonGlobal = (opts = {}) => globalBar({ active: 'pick', ...opts }); + switch (state) { + case 'global-disconnected': + return hostPage() + '' + commonGlobal({ connected: false }); + case 'global-tools': + return hostPage() + commonGlobal({ active: 'detect', detectCount: 7, designActive: true }); + case 'steer-expanded': + return hostPage() + commonGlobal({ steer: 'expanded' }); + case 'steer-processing': + return hostPage() + commonGlobal({ steer: 'processing' }); + case 'configure-replace': + return hostPage() + selectionOutline() + editBadge(false) + configureBar({ actionLabel, count: context.count }) + commonGlobal(); + case 'action-picker': + return hostPage() + selectionOutline() + editBadge(false) + configureBar({ actionLabel, count: context.count, picker: actionPicker(context.commands, context.selectedAction) }) + commonGlobal(); + case 'configure-listening': + return hostPage() + selectionOutline() + editBadge(false) + configureBar({ actionLabel, count: context.count, listening: true }) + commonGlobal(); + case 'configure-locked': + return hostPage({ edited: true }) + selectionOutline() + editBadge(false) + configureBar({ actionLabel, count: context.count, locked: true }) + pendingDock('applying') + commonGlobal(); + case 'annotation': + return hostPage() + selectionOutline() + annotationLayer() + configureBar({ actionLabel, count: context.count }) + commonGlobal(); + case 'insert-placeholder': + return hostPage({ insert: true }) + '
' + configureBar({ count: context.count, insert: true }) + globalBar({ active: 'insert' }); + case 'generating': + return hostPage() + selectionOutline() + generatingBar(false, actionLabel) + commonGlobal(); + case 'generation-recovery': + return hostPage() + generatingBar(true, actionLabel) + commonGlobal(); + case 'cycling-progressive': + return hostPage() + selectionOutline() + cyclingBar({ arrived: 1, visible: 1 }) + commonGlobal(); + case 'cycling-second': + return hostPage() + selectionOutline() + cyclingBar({ arrived: 2, visible: 2 }) + commonGlobal(); + case 'tune-open': + return hostPage() + selectionOutline() + cyclingBar({ arrived: 3, visible: 2, tune: true }) + commonGlobal(); + case 'applying': + return hostPage() + selectionOutline() + statusBar('applying') + commonGlobal(); + case 'confirmed': + return hostPage({ edited: true }) + statusBar('confirmed') + commonGlobal(); + case 'edit-copy': + return hostPage({ edited: true }) + selectionOutline() + editBadge(true) + configureBar({ actionLabel, count: context.count }) + commonGlobal(); + case 'copy-pending': + return hostPage({ edited: true }) + pendingDock('pending') + commonGlobal(); + case 'copy-applying': + return hostPage({ edited: true }) + pendingDock('applying') + commonGlobal(); + case 'copy-attention': + return hostPage({ edited: true }) + pendingDock('attention') + commonGlobal(); + case 'design-panel': + return hostPage() + designPanel(context.designTab) + globalBar({ active: 'design', designActive: true }); + case 'toast-error': + return hostPage() + '' + commonGlobal(); + case 'global-ready': + default: + return hostPage() + commonGlobal(); + } +} + +function initLiveUiGallery(root) { + if (!root || root.dataset.galleryReady === 'true') return; + root.dataset.galleryReady = 'true'; + + const states = parseJson(root, '[data-live-gallery-states]'); + const commands = parseJson(root, '[data-live-gallery-vocabulary]'); + if (states.length === 0 || commands.length === 0) return; + + const select = root.querySelector('[data-gallery-state]'); + const groupReadout = root.querySelector('[data-gallery-state-group]'); + const labelReadout = root.querySelector('[data-gallery-state-label]'); + const previews = [...root.querySelectorAll('[data-live-gallery-preview]')]; + let selectedAction = 'impeccable'; + let count = 3; + let designTab = 'visual'; + + const stateIndex = (key) => Math.max(0, states.findIndex((state) => state.key === key)); + const currentState = () => select?.value || states[0].key; + + function render(nextState = currentState(), { focusSelect = false } = {}) { + const state = states[stateIndex(nextState)] || states[0]; + if (select) select.value = state.key; + if (groupReadout) groupReadout.textContent = state.group; + if (labelReadout) labelReadout.textContent = state.label; + + root.querySelectorAll('[data-gallery-state-button]').forEach((button) => { + const active = button.dataset.galleryStateButton === state.key; + button.setAttribute('aria-current', active ? 'true' : 'false'); + }); + + for (const preview of previews) { + preview.dataset.galleryState = state.key; + preview.setAttribute('aria-label', `${preview.dataset.liveGalleryPreview} host — ${state.label}`); + preview.innerHTML = sceneFor(state.key, { commands, selectedAction, count, designTab }); + } + if (focusSelect) select?.focus(); + } + + function step(delta) { + const next = (stateIndex(currentState()) + delta + states.length) % states.length; + render(states[next].key, { focusSelect: true }); + } + + select?.addEventListener('change', () => render(select.value)); + + root.addEventListener('click', (event) => { + const stepButton = event.target.closest('[data-gallery-step]'); + if (stepButton) { + step(Number(stepButton.dataset.galleryStep) || 1); + return; + } + + const stateButton = event.target.closest('[data-gallery-state-button]'); + if (stateButton) { + render(stateButton.dataset.galleryStateButton); + return; + } + + const actionButton = event.target.closest('[data-gallery-action]'); + if (actionButton) { + selectedAction = actionButton.dataset.galleryAction || 'impeccable'; + render('configure-replace'); + return; + } + + const countButton = event.target.closest('[data-gallery-count]'); + if (countButton) { + count = count >= 4 ? 1 : count + 1; + render(currentState()); + return; + } + + const densityButton = event.target.closest('[data-gallery-density]'); + if (densityButton) { + const value = densityButton.dataset.galleryDensity; + root.querySelectorAll('[data-gallery-density]').forEach((button) => { + button.setAttribute('aria-pressed', button.dataset.galleryDensity === value ? 'true' : 'false'); + }); + root.querySelectorAll('[data-gallery-density-output]').forEach((output) => { output.textContent = value; }); + return; + } + + const toggleButton = event.target.closest('[data-gallery-param-toggle]'); + if (toggleButton) { + const next = toggleButton.getAttribute('aria-pressed') !== 'true'; + root.querySelectorAll('[data-gallery-param-toggle]').forEach((button) => button.setAttribute('aria-pressed', String(next))); + root.querySelectorAll('[data-gallery-toggle-output]').forEach((output) => { output.textContent = next ? 'On' : 'Off'; }); + return; + } + + const designTabButton = event.target.closest('[data-gallery-design-tab]'); + if (designTabButton) { + designTab = designTabButton.dataset.galleryDesignTab === 'raw' ? 'raw' : 'visual'; + render('design-panel'); + return; + } + + const trigger = event.target.closest('[data-gallery-go]'); + if (trigger && !trigger.disabled) render(trigger.dataset.galleryGo); + }); + + root.addEventListener('input', (event) => { + const range = event.target.closest('[data-gallery-range]'); + if (!range) return; + const value = Number(range.value).toFixed(2); + root.querySelectorAll('[data-gallery-range]').forEach((input) => { if (input !== range) input.value = range.value; }); + root.querySelectorAll('[data-gallery-range-output]').forEach((output) => { output.textContent = value; }); + }); + + root.addEventListener('keydown', (event) => { + if (event.target.matches('[data-gallery-steer-input]') && event.key === 'Enter') { + event.preventDefault(); + render('steer-processing'); + return; + } + const panel = event.target.closest('.live-ui-gallery__control-panel'); + if (!panel || event.target.matches('input')) return; + if (event.key === 'ArrowLeft') { + event.preventDefault(); + step(-1); + } else if (event.key === 'ArrowRight') { + event.preventDefault(); + step(1); + } + }); + + render(states[0].key); +} + +function initLiveUiGalleries() { + document.querySelectorAll('[data-live-ui-gallery]').forEach(initLiveUiGallery); +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initLiveUiGalleries, { once: true }); +} else { + initLiveUiGalleries(); +} + +document.addEventListener('astro:page-load', initLiveUiGalleries); + diff --git a/site/styles/live-lab-workbench.css b/site/styles/live-lab-workbench.css new file mode 100644 index 000000000..16bb2046e --- /dev/null +++ b/site/styles/live-lab-workbench.css @@ -0,0 +1,542 @@ +/* Live Lab workbench: detector-style navigation, active workspace, diagnostics. */ + +.live-lab-page { + overflow: hidden; +} + +.live-lab-main-shell, +.live-lab-workbench, +.live-lab-workspace { + height: 100vh; + min-height: 0; +} + +.live-lab-workbench { + --live-lab-sidebar: 300px; + background: var(--ks-lacquer); +} + +.live-lab-nav { + position: fixed; + inset: 0 auto 0 0; + z-index: 10; + display: flex; + flex-direction: column; + width: var(--live-lab-sidebar); + border-right: 1px solid var(--ks-rule); + background: var(--ks-lacquer-deep); +} + +.live-lab-nav-head { + flex-shrink: 0; + padding: var(--spacing-md); + border-bottom: 1px solid var(--ks-rule); +} + +.live-lab-brand { + color: var(--ks-kinpaku); + text-decoration: none; +} + +.live-lab-brand .ks-mark { width: 30px; height: 30px; } +.live-lab-brand .ks-mark svg { width: 26px; height: 26px; } + +.live-lab-brand .ks-wordmark { + font-size: 1rem; + letter-spacing: 0.16em; +} + +.live-lab-nav-head h1 { + margin: var(--spacing-md) 0 0; + color: var(--ks-champagne); + font-family: var(--ks-font); + font-size: var(--ks-type-title-size); + font-weight: 600; + line-height: 1.15; +} + +.live-lab-nav-head > p { + margin: 6px 0 0; + color: var(--ks-text-muted); + font-size: var(--ks-type-body-size); + line-height: 1.5; +} + +.live-lab-summary-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + margin: var(--spacing-md) 0 0; + border: 1px solid var(--ks-rule); +} + +.live-lab-summary-grid div { + min-width: 0; + padding: 10px; + border-right: 1px solid var(--ks-rule); + border-bottom: 1px solid var(--ks-rule); +} + +.live-lab-summary-grid div:nth-child(2n) { border-right: 0; } +.live-lab-summary-grid div:nth-last-child(-n + 2) { border-bottom: 0; } + +.live-lab-summary-grid dt, +.live-lab-panel-label, +.live-lab-nav-group h2, +.live-lab-diagnostic-panel dt { + color: var(--ks-text-muted); + font-family: var(--ks-mono); + font-size: 0.75rem; + font-weight: 500; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.live-lab-summary-grid dd { + margin: 4px 0 0; + color: var(--ks-champagne); + font-size: 1rem; + font-weight: 600; + line-height: 1.15; +} + +.live-lab-nav-scroll { + min-height: 0; + overflow: auto; + padding-bottom: var(--spacing-md); +} + +.live-lab-nav-group { + padding: var(--spacing-sm); + border-bottom: 1px solid var(--ks-rule); +} + +.live-lab-nav-group h2 { + margin: 0; + color: var(--ks-kinpaku-deep); + letter-spacing: 0.2em; +} + +.live-lab-nav-list, +.live-lab-action-list { + display: grid; + gap: 4px; + margin-top: 10px; +} + +.live-lab-nav-list button, +.live-lab-action-list button, +.live-lab-action-list a { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 12px; + align-items: center; + width: 100%; + min-height: 40px; + padding: 8px 10px; + border: 1px solid transparent; + border-radius: 4px; + background: transparent; + color: var(--ks-text-muted); + font: 500 0.875rem/1.3 var(--ks-font); + text-align: left; + text-decoration: none; + cursor: pointer; +} + +.live-lab-action-list button, +.live-lab-action-list a { + grid-template-columns: 1fr; +} + +.live-lab-nav-list button:hover, +.live-lab-action-list button:hover, +.live-lab-action-list a:hover { + background: var(--ks-graphite); + color: var(--ks-champagne); +} + +.live-lab-nav-list button:focus-visible, +.live-lab-action-list button:focus-visible, +.live-lab-action-list a:focus-visible { + outline: 2px solid var(--ks-kinpaku); + outline-offset: 2px; +} + +.live-lab-nav-list button[aria-pressed='true'] { + border-color: var(--ks-kinpaku); + background: var(--ks-kinpaku); + color: var(--ks-lacquer-deep); +} + +.live-lab-nav-list button span:last-child { + font-family: var(--ks-mono); + font-size: 0.75rem; + opacity: 0.72; +} + +.live-lab-workspace { + display: flex; + flex-direction: column; + min-width: 0; + margin-left: var(--live-lab-sidebar); + overflow: hidden; +} + +.live-lab-toolbar { + position: relative; + z-index: 8; + display: flex; + flex-shrink: 0; + justify-content: space-between; + gap: var(--spacing-md); + align-items: center; + min-height: 80px; + padding: 12px var(--spacing-md); + border-bottom: 1px solid var(--ks-rule); + background: var(--ks-lacquer-deep); +} + +.live-lab-toolbar h2, +.live-lab-diagnostic-panel h2 { + margin: 2px 0 0; + color: var(--ks-champagne); + font: 600 1rem/1.2 var(--ks-font); +} + +.live-lab-toolbar p:not(.live-lab-panel-label) { + margin: 4px 0 0; + color: var(--ks-text-muted); + font-size: var(--ks-type-body-size); + line-height: 1.4; +} + +.live-lab-toolbar-actions { + display: flex; + flex-shrink: 0; + gap: 10px; + align-items: center; +} + +.live-lab-status { + display: inline-flex; + gap: 7px; + align-items: center; + color: var(--ks-text-muted); + font: 0.75rem/1.2 var(--ks-mono); +} + +.live-lab-status i { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--ks-patina); +} + +.live-lab-toolbar-actions a { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 38px; + padding: 0 16px; + border: 1px solid var(--ks-kinpaku); + border-radius: 2px; + background: var(--ks-kinpaku); + color: var(--ks-lacquer-deep); + font-size: var(--ks-type-body-size); + font-weight: 600; + text-decoration: none; +} + +.live-lab-workspace-scroll { + flex: 1 1 auto; + min-height: 0; + overflow: auto; +} + +.live-lab-content-grid { + display: grid; + grid-template-columns: minmax(0, 1fr) 300px; + gap: var(--spacing-sm); + align-items: start; + padding: var(--spacing-sm); +} + +.live-lab-canvas, +.live-lab-diagnostic-panel { + min-width: 0; + border: 1px solid var(--ks-rule); + background: var(--ks-lacquer-raised); +} + +.live-lab-ui-panel { + min-width: 0; + padding: clamp(24px, 4vw, 48px); +} + +.live-lab-canvas { + padding-bottom: 0; +} + +.live-lab-canvas [hidden] { + display: none !important; +} + +.live-lab-canvas .ks-section { + width: auto; + max-width: none; + margin: 0; + padding-right: clamp(20px, 3vw, 40px); + padding-left: clamp(20px, 3vw, 40px); +} + +.live-lab-canvas .live-performance-hero { + padding-top: clamp(32px, 5vw, 56px); + padding-bottom: clamp(32px, 5vw, 56px); +} + +.live-lab-canvas .live-performance-hero::after { + right: 0; + left: 0; +} + +.live-lab-canvas .live-performance-hero h1 { + max-width: 720px; + margin-top: 14px; + font-family: var(--ks-font); + font-size: var(--ks-type-headline-size); + font-weight: 600; + line-height: var(--ks-type-headline-line); +} + +.live-lab-canvas .live-performance-lede { + margin-top: 24px; + font-size: 1rem; + line-height: 1.6; +} + +.live-lab-run-stats { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + margin: 28px 0 0; + border: 1px solid var(--ks-rule); +} + +.live-lab-run-stats div { + min-width: 0; + padding: var(--spacing-sm); + border-right: 1px solid var(--ks-rule); +} + +.live-lab-run-stats div:last-child { border-right: 0; } + +.live-lab-run-stats dt { + color: var(--ks-text-muted); + font: 500 var(--ks-type-eyebrow-size)/1.4 var(--ks-mono); + letter-spacing: var(--ks-type-eyebrow-track); + text-transform: uppercase; +} + +.live-lab-run-stats dd { + margin: 6px 0 0; + color: var(--ks-champagne); + font-size: var(--ks-type-title-size); + font-weight: 600; +} + +.live-lab-canvas .live-performance-meta { + margin-top: 24px; +} + +.live-lab-canvas .live-performance-section { + padding-top: clamp(30px, 4vw, 52px); + padding-bottom: clamp(30px, 4vw, 52px); +} + +.live-lab-canvas .live-performance-section-head { + grid-template-columns: minmax(0, 1fr) minmax(220px, 360px); + gap: 28px; +} + +.live-lab-canvas .live-performance-section-head h2, +.live-lab-canvas .live-performance-method h2 { + margin-top: 8px; + font-size: clamp(1.65rem, 3vw, 2.6rem); +} + +.live-lab-canvas .latency-tape, +.live-lab-canvas .scenario-comparison, +.live-lab-canvas .harness-table-wrap, +.live-lab-canvas .experiment-list, +.live-lab-canvas .live-simulator { + margin-top: 32px; +} + +.live-lab-canvas .live-performance-finding { + margin-top: 28px; +} + +.live-lab-canvas .live-performance-method { + gap: 28px; + padding-top: 36px; + padding-bottom: 36px; + border-bottom: 0; +} + +.live-lab-diagnostics { + position: sticky; + top: 0; + display: grid; + gap: var(--spacing-sm); + max-height: calc(100vh - 106px); + overflow: auto; +} + +.live-lab-diagnostic-panel { + overflow: hidden; +} + +.live-lab-diagnostic-panel header { + padding: var(--spacing-sm); + border-bottom: 1px solid var(--ks-rule); +} + +.live-lab-diagnostic-panel dl { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + margin: 0; +} + +.live-lab-diagnostic-panel dl div { + padding: var(--spacing-sm); + border-right: 1px solid var(--ks-rule); + border-bottom: 1px solid var(--ks-rule); +} + +.live-lab-diagnostic-panel dl div:nth-child(2n) { border-right: 0; } + +.live-lab-diagnostic-panel dd { + margin: 5px 0 0; + color: var(--ks-champagne); + font-size: var(--ks-type-title-size); + font-weight: 600; +} + +.live-lab-diagnostic-panel > p { + margin: 0; + padding: var(--spacing-sm); + color: var(--ks-text-muted); + font-size: var(--ks-type-body-size); + line-height: 1.5; +} + +.live-lab-strategy-list { + margin: 0; + padding: 0; + list-style: none; +} + +.live-lab-strategy-list li { + display: grid; + gap: 3px; + padding: 11px var(--spacing-sm); + border-bottom: 1px solid var(--ks-rule); +} + +.live-lab-strategy-list strong { + color: var(--ks-champagne); + font-size: var(--ks-type-body-size); + font-weight: 500; +} + +.live-lab-strategy-list span { + color: var(--ks-patina); + font: 0.75rem/1.4 var(--ks-mono); +} + +@media (max-width: 1180px) { + .live-lab-workbench { --live-lab-sidebar: 270px; } + .live-lab-content-grid { grid-template-columns: minmax(0, 1fr); } + .live-lab-diagnostics { + position: static; + grid-template-columns: repeat(3, minmax(0, 1fr)); + max-height: none; + overflow: visible; + } +} + +@media (max-width: 860px) { + .live-lab-page { overflow: auto; } + + .live-lab-main-shell, + .live-lab-workbench, + .live-lab-workspace { + height: auto; + min-height: 100vh; + overflow: visible; + } + + .live-lab-nav { + position: static; + width: auto; + border-right: 0; + border-bottom: 1px solid var(--ks-rule); + } + + .live-lab-nav-scroll { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + max-height: none; + } + + .live-lab-workspace { margin-left: 0; } + .live-lab-workspace-scroll { overflow: visible; } + + .live-lab-toolbar { + position: static; + align-items: flex-start; + } + + .live-lab-diagnostics { grid-template-columns: 1fr; } + .live-lab-canvas .live-performance-section-head { grid-template-columns: 1fr; } + .live-lab-run-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } + .live-lab-run-stats div:nth-child(2) { border-right: 0; } + .live-lab-run-stats div:nth-child(-n + 2) { border-bottom: 1px solid var(--ks-rule); } +} + +@media (max-width: 560px) { + .live-lab-summary-grid, + .live-lab-diagnostic-panel dl, + .live-lab-nav-scroll, + .live-lab-run-stats { + grid-template-columns: 1fr; + } + + .live-lab-summary-grid div, + .live-lab-diagnostic-panel dl div, + .live-lab-run-stats div { + border-right: 0; + } + + .live-lab-toolbar { + flex-direction: column; + align-items: stretch; + } + + .live-lab-toolbar-actions { + justify-content: space-between; + } + + .live-lab-content-grid { + padding: 0; + } + + .live-lab-canvas, + .live-lab-diagnostic-panel { + border-right: 0; + border-left: 0; + } +} + +@media (prefers-reduced-motion: reduce) { + .live-lab-status i { animation: none; } +} diff --git a/site/styles/live-ui-gallery.css b/site/styles/live-ui-gallery.css new file mode 100644 index 000000000..4083f108e --- /dev/null +++ b/site/styles/live-ui-gallery.css @@ -0,0 +1,1708 @@ +/* + * Isolated dev gallery for the production Live chrome. + * + * Runtime fidelity anchors: + * - skill/scripts/live-browser.js: C, barPaletteForTheme, initBar, + * buildConfigureRow, buildGeneratingRow, buildCyclingRow, initParamsPanel, + * initGlobalBar, pending-copy dock, annotation overlay, designPanelCss. + * - skill/scripts/live/ui-core.mjs: authoritative surface/state inventory. + * + * The --lvg-live-* values intentionally mirror the standalone injected script + * rather than the surrounding site theme. Live uses this dark chrome on both + * light and dark host pages so its controls stay recognizable everywhere. + */ + +.live-ui-gallery { + --lvg-live-brand: oklch(84% 0.19 80.46); + --lvg-live-brand-hover: oklch(86% 0.07 84); + --lvg-live-brand-soft: oklch(84% 0.19 80.46 / 0.18); + --lvg-live-ink: oklch(4% 0.004 95); + --lvg-live-surface: oklch(15% 0.008 95); + --lvg-live-chat: oklch(22% 0.012 82); + --lvg-live-toggle: oklch(27% 0 0); + --lvg-live-text: oklch(91% 0 0); + --lvg-live-text-dim: oklch(72% 0 0); + --lvg-live-border: oklch(92% 0 0 / 0.13); + --lvg-live-hairline: oklch(92% 0 0 / 0.12); + --lvg-live-patina: oklch(70% 0.12 188); + --lvg-live-patina-pale: oklch(82% 0.07 188); + --lvg-live-patina-soft: oklch(70% 0.12 188 / 0.28); + --lvg-live-warning: oklch(58% 0.15 35); + --lvg-live-success: oklch(45% 0.18 145); + --lvg-live-success-surface: oklch(95% 0.05 145); + --lvg-live-font: system-ui, -apple-system, sans-serif; + --lvg-live-mono: ui-monospace, SFMono-Regular, Menlo, monospace; + --lvg-live-shadow: 0 16px 36px -12px oklch(0% 0 0 / 0.6); + --lvg-live-soft-shadow: 0 4px 20px oklch(0% 0 0 / 0.08), 0 1px 3px oklch(0% 0 0 / 0.06); + --lvg-live-ease: cubic-bezier(0.22, 1, 0.36, 1); + --lvg-fs-9: 0.59375rem; + --lvg-fs-10: 0.625rem; + --lvg-fs-10-5: 0.65625rem; + --lvg-fs-11: 0.6875rem; + --lvg-fs-11-5: 0.71875rem; + --lvg-fs-12: 0.75rem; + --lvg-fs-13: 0.8125rem; + --lvg-fs-14: 0.875rem; + --lvg-fs-15: 0.9375rem; + + color: var(--ks-text); + font-family: var(--ks-font); +} + +.live-ui-gallery *, +.live-ui-gallery *::before, +.live-ui-gallery *::after { + box-sizing: border-box; +} + +.live-ui-gallery button, +.live-ui-gallery input, +.live-ui-gallery select { + font: inherit; +} + +.live-ui-gallery__header { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(17rem, 25rem); + gap: var(--ks-space-xl, 48px); + align-items: end; + padding-bottom: var(--ks-space-lg, 32px); + border-bottom: 1px solid var(--ks-rule); +} + +.live-ui-gallery__intro { + max-width: 44rem; +} + +.live-ui-gallery__eyebrow { + margin: 0 0 10px; + color: var(--ks-patina); + font-family: var(--ks-mono); + font-size: var(--ks-type-eyebrow-size); + font-weight: 600; + letter-spacing: var(--ks-type-eyebrow-track); + text-transform: uppercase; +} + +.live-ui-gallery__intro h2 { + margin: 0; + color: var(--ks-champagne); + font-family: var(--ks-font-display); + font-size: var(--ks-type-headline-size); + font-weight: var(--ks-type-headline-weight); + line-height: var(--ks-type-headline-line); + text-wrap: balance; +} + +.live-ui-gallery__intro > p:last-child { + max-width: 68ch; + margin: 16px 0 0; + color: var(--ks-text-muted); + font-size: var(--ks-type-body-size); + line-height: 1.65; +} + +.live-ui-gallery__control-panel { + padding: 18px; + background: var(--ks-lacquer-raised); + border: 1px solid var(--ks-rule); + border-radius: 4px; +} + +.live-ui-gallery__control-panel > label { + display: block; + margin-bottom: 8px; + color: var(--ks-text-muted); + font-family: var(--ks-mono); + font-size: var(--ks-type-eyebrow-size); + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.live-ui-gallery__select-row { + display: grid; + grid-template-columns: 38px minmax(0, 1fr) 38px; + gap: 6px; +} + +.live-ui-gallery__select-row select, +.live-ui-gallery__step { + min-height: 38px; + color: var(--ks-champagne); + background: var(--ks-lacquer-deep); + border: 1px solid var(--ks-rule); + border-radius: 3px; +} + +.live-ui-gallery__select-row select { + width: 100%; + padding: 0 34px 0 12px; + cursor: pointer; +} + +.live-ui-gallery__step { + padding: 0; + color: var(--ks-kinpaku); + cursor: pointer; +} + +.live-ui-gallery__select-row select:focus-visible, +.live-ui-gallery__step:focus-visible, +.live-ui-gallery__quick-nav button:focus-visible, +.live-ui-gallery [data-live-gallery-preview] button:focus-visible, +.live-ui-gallery [data-live-gallery-preview] input:focus-visible { + outline: 2px solid var(--ks-kinpaku); + outline-offset: 2px; +} + +.live-ui-gallery__shortcut { + margin: 8px 0 0; + color: var(--ks-text-faint); + font-size: var(--lvg-fs-12); + line-height: 1.45; +} + +.live-ui-gallery__quick-nav { + display: grid; + gap: 10px; + padding: 20px 0; + border-bottom: 1px solid var(--ks-rule); +} + +.live-ui-gallery__quick-group { + display: grid; + grid-template-columns: 8rem minmax(0, 1fr); + gap: 14px; + align-items: start; +} + +.live-ui-gallery__quick-group > span { + padding-top: 6px; + color: var(--ks-text-faint); + font-family: var(--ks-mono); + font-size: var(--ks-type-eyebrow-size); + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.live-ui-gallery__quick-group > div { + display: flex; + flex-wrap: wrap; + gap: 5px; +} + +.live-ui-gallery__quick-nav button { + min-height: 28px; + padding: 5px 9px; + color: var(--ks-text-muted); + background: transparent; + border: 1px solid var(--ks-rule); + border-radius: 3px; + font-size: var(--lvg-fs-12); + cursor: pointer; + transition: color 140ms ease, border-color 140ms ease, background 140ms ease; +} + +.live-ui-gallery__quick-nav button:hover { + color: var(--ks-champagne); + border-color: var(--ks-text-faint); +} + +.live-ui-gallery__quick-nav button[aria-current="true"] { + color: var(--ks-lacquer-deep); + background: var(--ks-kinpaku); + border-color: var(--ks-kinpaku); +} + +.live-ui-gallery__state-readout { + display: flex; + gap: 10px; + align-items: baseline; + padding: 24px 0 14px; +} + +.live-ui-gallery__state-readout span { + color: var(--ks-patina); + font-family: var(--ks-mono); + font-size: var(--ks-type-eyebrow-size); + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.live-ui-gallery__state-readout strong { + color: var(--ks-champagne); + font-size: var(--ks-type-title-size); + font-weight: var(--ks-type-title-weight); +} + +.live-ui-gallery__previews { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; +} + +.live-ui-gallery__preview { + min-width: 0; + overflow: hidden; + background: var(--ks-lacquer-deep); + border: 1px solid var(--ks-rule); + border-radius: 4px; +} + +.live-ui-gallery__preview > header { + display: flex; + align-items: center; + gap: 8px; + min-height: 42px; + padding: 0 14px; + color: var(--ks-text-muted); + border-bottom: 1px solid var(--ks-rule); +} + +.live-ui-gallery__preview > header h3 { + margin: 0; + color: var(--ks-champagne); + font-size: var(--lvg-fs-14); + font-weight: 600; +} + +.live-ui-gallery__preview > header code { + margin-left: auto; + padding: 2px 5px; + color: var(--ks-text-faint); + background: var(--ks-graphite); + border-radius: 3px; + font-family: var(--ks-mono); + font-size: var(--lvg-fs-11); +} + +.live-ui-gallery__theme-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--ks-patina); +} + +.live-ui-gallery__preview:first-child .live-ui-gallery__theme-dot { + background: var(--ks-kinpaku); +} + +.live-ui-stage { + position: relative; + min-height: 530px; + overflow: hidden; + isolation: isolate; + font-family: var(--lvg-live-font); +} + +.live-ui-stage.is-light { + color: oklch(20% 0.018 95); + background: oklch(96% 0.012 95); +} + +.live-ui-stage.is-dark { + color: oklch(91% 0 0); + background: oklch(8% 0.008 95); +} + +.lvg-host-page { + position: absolute; + inset: 0; + padding: 34px 28px 86px; + background-image: linear-gradient(to right, currentColor 1px, transparent 1px); + background-size: 42px 100%; + background-position: 28px 0; +} + +.is-light .lvg-host-page { + background-color: oklch(97% 0.012 95); + background-image: linear-gradient(to right, oklch(25% 0.02 95 / 0.055) 1px, transparent 1px); +} + +.is-dark .lvg-host-page { + background-color: oklch(8% 0.008 95); + background-image: linear-gradient(to right, oklch(91% 0 0 / 0.05) 1px, transparent 1px); +} + +.lvg-host-kicker { + margin: 0 0 8px; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-10); + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + opacity: 0.62; +} + +.lvg-host-target { + position: relative; + max-width: 25rem; + min-height: 142px; + padding: 22px 24px; + border-left: 3px solid currentColor; +} + +.is-light .lvg-host-target { + background: oklch(99% 0.008 95); + box-shadow: 0 18px 42px -30px oklch(20% 0.02 95 / 0.38); +} + +.is-dark .lvg-host-target { + background: oklch(12% 0.008 95); + box-shadow: 0 18px 42px -30px oklch(0% 0 0 / 0.8); +} + +.lvg-host-target h4 { + max-width: 15ch; + margin: 0; + font-size: var(--ks-type-title-size); + line-height: 1.08; + letter-spacing: -0.02em; + text-wrap: balance; +} + +.lvg-host-target p { + max-width: 37ch; + margin: 12px 0 0; + font-size: var(--lvg-fs-13); + line-height: 1.55; + opacity: 0.68; +} + +.lvg-host-target[data-edited="true"] h4 { + background: color-mix(in oklch, var(--lvg-live-brand) 24%, transparent); + box-shadow: inset 0 -1px var(--lvg-live-brand); +} + +.lvg-host-page.has-insert .lvg-host-target { + margin-top: 130px; +} + +.lvg-selection-outline { + position: absolute; + top: 70px; + left: 26px; + width: min(25.25rem, calc(100% - 52px)); + height: 150px; + border: 2px solid var(--lvg-live-brand); + pointer-events: none; +} + +.lvg-edit-badge { + position: absolute; + top: 42px; + right: max(26px, calc(100% - 430px)); + z-index: 8; + display: flex; + gap: 8px; +} + +.lvg-edit-badge button { + min-height: 22px; + padding: 2px 8px; + color: var(--lvg-live-text-dim); + background: var(--lvg-live-chat); + border: 1px solid var(--lvg-live-hairline); + border-radius: 6px; + box-shadow: 0 4px 16px oklch(0% 0 0 / 0.16), 0 1px 3px oklch(0% 0 0 / 0.08); + font-family: var(--lvg-live-font); + font-size: var(--lvg-fs-10); + font-weight: 600; + line-height: 1rem; + letter-spacing: 0.06em; + cursor: pointer; +} + +.lvg-edit-badge .is-primary, +.lvg-edit-badge .is-icon { + color: var(--lvg-live-ink); + background: var(--lvg-live-brand); + border-color: var(--lvg-live-brand); +} + +.lvg-edit-badge .is-icon { + display: inline-flex; + width: 22px; + min-width: 22px; + height: 22px; + padding: 4px; + align-items: center; + justify-content: center; +} + +.lvg-live-context { + position: absolute; + top: 230px; + left: 50%; + z-index: 10; + display: block; + width: min(35rem, calc(100% - 24px)); + min-width: 0; + padding: 5px; + overflow: visible; + color: var(--lvg-live-text); + background: var(--lvg-live-ink); + border: 1px solid var(--lvg-live-border); + border-radius: 8px; + box-shadow: var(--lvg-live-soft-shadow); + transform: translateX(-50%); + font-family: var(--lvg-live-font); + font-size: var(--lvg-fs-13); +} + +.lvg-live-context.is-configure { + height: 38px; + padding: 0; + overflow: hidden; + background: var(--lvg-live-surface); +} + +.lvg-live-context.is-configure.has-picker { + overflow: visible; +} + +.lvg-configure-row { + display: flex; + width: 100%; + height: 36px; + align-items: stretch; +} + +.lvg-configure-input-shell { + display: flex; + flex: 1; + min-width: 0; + height: 100%; + padding: 0 6px 0 7px; + align-items: center; + gap: 6px; +} + +.lvg-selection-pill { + display: inline-flex; + min-width: 32px; + height: 22px; + padding: 1px 4px; + align-items: center; + justify-content: center; + color: var(--lvg-live-patina); + background: transparent; + border: 1px solid var(--lvg-live-patina); + border-radius: 7px; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-12); + font-weight: 600; + line-height: 18px; + cursor: pointer; +} + +.lvg-configure-input { + flex: 1; + min-width: 0; + width: 100%; + height: 18px; + padding: 0; + color: oklch(94% 0.02 82); + caret-color: oklch(94% 0.02 82); + background: transparent; + border: 0; + outline: 0; + font-family: var(--lvg-live-font); + font-size: var(--lvg-fs-12); + font-weight: 500; + line-height: 18px; +} + +.lvg-configure-input::placeholder { + color: var(--lvg-live-text-dim); + opacity: 1; +} + +.lvg-configure-trailing { + display: inline-flex; + height: 100%; + flex-shrink: 0; + align-items: stretch; + border-left: 1px solid var(--lvg-live-hairline); +} + +.lvg-configure-modifiers { + display: inline-flex; + height: 100%; + padding: 0 10px; + align-items: center; + gap: 8px; +} + +.lvg-configure-modifier { + height: 18px; + padding: 0; + color: var(--lvg-live-text-dim); + background: transparent; + border: 0; + font-size: var(--lvg-fs-12); + font-weight: 500; + line-height: 18px; + cursor: pointer; + white-space: nowrap; +} + +.lvg-configure-modifier:hover { + color: var(--lvg-live-text); +} + +.lvg-configure-modifier.is-count { + font-family: var(--lvg-live-mono); + font-weight: 600; +} + +.lvg-configure-voice, +.lvg-configure-submit { + display: inline-flex; + width: 36px; + height: 36px; + padding: 0; + flex-shrink: 0; + align-items: center; + justify-content: center; + border: 0; + border-left: 1px solid var(--lvg-live-hairline); + border-radius: 0; + cursor: pointer; +} + +.lvg-configure-voice { + color: var(--lvg-live-text-dim); + background: transparent; +} + +.lvg-configure-voice:hover, +.lvg-configure-voice[aria-pressed="true"] { + color: var(--lvg-live-brand); + background: var(--lvg-live-toggle); +} + +.lvg-configure-voice[aria-pressed="true"] svg { + animation: lvg-voice-pulse 1.1s ease-in-out infinite; +} + +.lvg-configure-submit { + color: var(--lvg-live-ink); + background: var(--lvg-live-brand); +} + +.lvg-live-context[data-locked="true"] { + border-color: var(--lvg-live-patina-soft); +} + +.lvg-live-context[data-locked="true"] :is(input, button) { + cursor: not-allowed; + opacity: 0.58; +} + +.lvg-action-picker { + position: absolute; + top: auto; + right: 0; + bottom: calc(100% + 6px); + z-index: 12; + width: min(25rem, calc(100vw - 56px)); + padding: 6px; + color: var(--lvg-live-text); + background: var(--lvg-live-ink); + border: 1px solid var(--lvg-live-border); + border-radius: 8px; + box-shadow: var(--lvg-live-shadow); +} + +.lvg-action-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 3px; +} + +.lvg-action-chip { + display: flex; + min-width: 0; + padding: 8px 6px; + flex-direction: column; + align-items: center; + gap: 4px; + color: var(--lvg-live-text); + background: transparent; + border: 0; + border-radius: 6px; + font-size: var(--lvg-fs-11); + font-weight: 500; + cursor: pointer; + white-space: nowrap; +} + +.lvg-action-chip:hover, +.lvg-action-chip[aria-pressed="true"] { + color: var(--lvg-live-brand); + background: var(--lvg-live-brand-soft); +} + +.lvg-action-chip span:first-child { + display: flex; + height: 20px; + align-items: center; + justify-content: center; + opacity: 0.9; +} + +.lvg-generation-row, +.lvg-cycling-row, +.lvg-status-row { + display: flex; + align-items: center; +} + +.lvg-generation-row { + gap: 8px; + padding: 2px 4px; +} + +.lvg-generation-label { + flex-shrink: 0; + color: var(--lvg-live-text); + font-size: var(--lvg-fs-12); + font-weight: 600; + white-space: nowrap; +} + +.lvg-generation-status { + margin-left: auto; + color: var(--lvg-live-text-dim); + font-size: var(--lvg-fs-11); + white-space: nowrap; +} + +.lvg-dots { + display: inline-flex; + align-items: center; + gap: 4px; +} + +.lvg-dot { + width: 6px; + height: 6px; + padding: 0; + border: 0; + border-radius: 50%; + background: var(--lvg-live-text-dim); + opacity: 0.6; +} + +button.lvg-dot { + cursor: pointer; +} + +.lvg-dot.is-active { + width: 8px; + height: 8px; + background: var(--lvg-live-brand); + opacity: 1; +} + +.lvg-dot.is-pending { + background: transparent; + border: 1.5px solid var(--lvg-live-hairline); + opacity: 0.4; + transform: scale(0.85); +} + +.lvg-cycling-row { + gap: 6px; + padding: 1px 2px; +} + +.lvg-nav-button { + display: inline-flex; + width: 26px; + height: 26px; + padding: 0; + align-items: center; + justify-content: center; + color: var(--lvg-live-text); + background: transparent; + border: 1px solid var(--lvg-live-hairline); + border-radius: 5px; + font-size: var(--lvg-fs-13); + line-height: 1; + cursor: pointer; +} + +.lvg-nav-button[disabled] { + opacity: 0.3; + cursor: default; +} + +.lvg-variant-counter { + min-width: 24px; + color: var(--lvg-live-text-dim); + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-11); + font-weight: 500; + text-align: center; +} + +.lvg-tune-button { + display: inline-flex; + padding: 4px 10px; + align-items: center; + gap: 6px; + color: var(--lvg-live-text); + background: transparent; + border: 1px solid transparent; + border-radius: 5px; + font-size: var(--lvg-fs-11); + font-weight: 500; + cursor: pointer; + white-space: nowrap; +} + +.lvg-tune-button:hover, +.lvg-tune-button[aria-expanded="true"] { + color: var(--lvg-live-brand); + background: var(--lvg-live-brand-soft); +} + +.lvg-tune-badge { + display: inline-flex; + min-width: 16px; + height: 16px; + padding: 0 4px; + align-items: center; + justify-content: center; + color: inherit; + background: var(--lvg-live-hairline); + border-radius: 999px; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-9); + font-weight: 600; +} + +.lvg-tune-button[aria-expanded="true"] .lvg-tune-badge { + color: oklch(98% 0 0); + background: var(--lvg-live-brand); +} + +.lvg-cycling-spacer { + flex: 1; +} + +.lvg-arrival-progress { + color: var(--lvg-live-text-dim); + font-size: var(--lvg-fs-11); + white-space: nowrap; +} + +.lvg-accept { + padding: 5px 14px; + color: var(--lvg-live-ink); + background: var(--lvg-live-brand); + border: 0; + border-radius: 5px; + font-size: var(--lvg-fs-11); + font-weight: 600; + cursor: pointer; + white-space: nowrap; +} + +.lvg-discard { + padding: 4px 6px; + color: var(--lvg-live-text-dim); + background: transparent; + border: 1px solid var(--lvg-live-hairline); + border-radius: 5px; + font-size: var(--lvg-fs-11); + cursor: pointer; +} + +.lvg-tune-panel { + position: absolute; + top: 36px; + left: -1px; + z-index: -1; + width: calc(100% + 2px); + padding: 20px 18px 14px; + color: var(--lvg-live-text); + background: var(--lvg-live-ink); + border-radius: 0 0 10px 10px; + box-shadow: 0 14px 26px -18px oklch(0% 0 0 / 0.65); +} + +.lvg-tune-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 12px 16px; +} + +.lvg-param { + display: flex; + min-width: 0; + flex-direction: column; + gap: 6px; +} + +.lvg-param-header { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 8px; +} + +.lvg-param-header strong, +.lvg-param-header output { + font-size: var(--lvg-fs-10-5); +} + +.lvg-param-header strong { + color: var(--lvg-live-text); + font-weight: 600; + letter-spacing: 0.03em; +} + +.lvg-param-header output { + color: var(--lvg-live-text-dim); + font-family: var(--lvg-live-mono); +} + +.lvg-param input[type="range"] { + width: 100%; + accent-color: var(--lvg-live-brand); + cursor: pointer; +} + +.lvg-param-steps { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1px; + padding: 2px; + background: var(--lvg-live-hairline); + border-radius: 5px; +} + +.lvg-param-steps button { + padding: 5px 4px; + color: var(--lvg-live-text); + background: transparent; + border: 0; + border-radius: 3px; + font-size: var(--lvg-fs-10-5); + font-weight: 500; + cursor: pointer; +} + +.lvg-param-steps button[aria-pressed="true"] { + color: oklch(98% 0 0); + background: var(--lvg-live-brand); +} + +.lvg-param-toggle { + position: relative; + width: 36px; + height: 20px; + padding: 0; + align-self: flex-start; + background: var(--lvg-live-hairline); + border: 0; + border-radius: 10px; + cursor: pointer; +} + +.lvg-param-toggle::after { + content: ''; + position: absolute; + top: 2px; + left: 2px; + width: 16px; + height: 16px; + background: oklch(98% 0 0); + border-radius: 50%; + box-shadow: 0 1px 2px oklch(0% 0 0 / 0.2); + transition: left 180ms var(--lvg-live-ease); +} + +.lvg-param-toggle[aria-pressed="true"] { + background: var(--lvg-live-brand); +} + +.lvg-param-toggle[aria-pressed="true"]::after { + left: 18px; +} + +.lvg-status-row { + gap: 8px; + padding: 2px 8px; +} + +.lvg-spinner { + width: 14px; + height: 14px; + flex-shrink: 0; + border: 2px solid var(--lvg-live-hairline); + border-top-color: var(--lvg-live-brand); + border-radius: 50%; + animation: lvg-spin 600ms linear infinite; +} + +.lvg-status-row span:last-child { + color: var(--lvg-live-text-dim); + font-size: var(--lvg-fs-12); + font-weight: 500; +} + +.lvg-live-context.is-confirmed { + background: var(--lvg-live-success-surface); + border-color: oklch(75% 0.12 145 / 0.4); +} + +.lvg-live-context.is-confirmed .lvg-status-row span:first-child { + color: var(--lvg-live-success); + font-size: var(--lvg-fs-15); +} + +.lvg-live-context.is-confirmed .lvg-status-row span:last-child { + color: oklch(49% 0.08 188); + font-weight: 600; +} + +.lvg-annotation-layer { + position: absolute; + top: 70px; + left: 26px; + z-index: 7; + width: min(25.25rem, calc(100% - 52px)); + height: 150px; + cursor: crosshair; +} + +.lvg-annotation-layer svg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + overflow: visible; + pointer-events: none; +} + +.lvg-annotation-layer path { + fill: none; + stroke: var(--lvg-live-brand); + stroke-width: 3; + stroke-linecap: round; + stroke-linejoin: round; +} + +.lvg-annotation-clear { + position: absolute; + top: 8px; + right: 8px; + padding: 5px 12px; + color: oklch(99% 0 0); + background: var(--lvg-live-ink); + border: 0; + border-radius: 999px; + box-shadow: 0 1px 3px oklch(0% 0 0 / 0.2); + font-size: var(--lvg-fs-10); + font-weight: 500; + letter-spacing: 0.08em; + text-transform: uppercase; + cursor: pointer; +} + +.lvg-annotation-pin { + position: absolute; + top: 60px; + left: 155px; + display: flex; + align-items: flex-start; + gap: 6px; +} + +.lvg-annotation-pin::before { + content: ''; + width: 14px; + height: 14px; + flex-shrink: 0; + background: var(--lvg-live-brand); + border: 2px solid oklch(99% 0 0); + border-radius: 50%; + box-shadow: 0 1px 3px oklch(0% 0 0 / 0.25); +} + +.lvg-annotation-pin span { + max-width: 220px; + margin-top: -2px; + padding: 4px 8px; + color: oklch(99% 0 0); + background: var(--lvg-live-ink); + border-radius: 3px; + font-size: var(--lvg-fs-12); + line-height: 1.4; +} + +.lvg-insert-placeholder { + position: absolute; + top: 86px; + left: 28px; + width: min(25rem, calc(100% - 56px)); + height: 92px; + background: transparent; + border: 2px dotted var(--lvg-live-brand); +} + +.lvg-insert-placeholder::before, +.lvg-insert-placeholder::after { + content: ''; + position: absolute; + background: var(--lvg-live-brand); +} + +.lvg-insert-placeholder::before { + top: 50%; + left: -5px; + width: 10px; + height: 2px; +} + +.lvg-insert-placeholder::after { + top: -5px; + left: 50%; + width: 2px; + height: 10px; +} + +.lvg-live-global { + position: absolute; + bottom: 14px; + left: 50%; + z-index: 20; + display: flex; + width: max-content; + max-width: calc(100% - 16px); + align-items: stretch; + color: var(--lvg-live-text); + background: var(--lvg-live-ink); + border: 1px solid var(--lvg-live-border); + border-radius: 8px; + box-shadow: var(--lvg-live-shadow); + overflow: hidden; + transform: translateX(-50%); + font-family: var(--lvg-live-font); + font-size: var(--lvg-fs-12); + line-height: 1; +} + +.lvg-live-brand { + position: relative; + display: inline-flex; + padding: 0 6px 0 14px; + align-items: center; + align-self: stretch; + justify-content: center; + color: var(--lvg-live-brand); +} + +.lvg-live-brand[data-connected="false"] { + color: oklch(62% 0 0 / 0.78); +} + +.lvg-agent-dot { + position: absolute; + right: 4px; + bottom: 7px; + width: 6px; + height: 6px; + background: oklch(77% 0.13 82); + border-radius: 50%; + box-shadow: 0 0 0 2px var(--lvg-live-ink); + animation: lvg-agent-dot 1.4s ease-in-out infinite; +} + +.lvg-global-inner { + display: flex; + padding: 4px 5px 4px 2px; + align-items: center; + gap: 2px; +} + +.lvg-global-mode { + display: inline-flex; + min-width: 30px; + padding: 6px 8px; + align-items: center; + justify-content: center; + gap: 6px; + color: var(--lvg-live-text-dim); + background: transparent; + border: 0; + border-radius: 7px; + font-size: var(--lvg-fs-11-5); + font-weight: 500; + cursor: pointer; + white-space: nowrap; +} + +.lvg-global-mode:hover { + color: var(--lvg-live-text); +} + +.lvg-global-mode[data-active="true"] { + color: var(--lvg-live-brand); + background: var(--lvg-live-toggle); +} + +.lvg-global-mode svg { + flex-shrink: 0; +} + +.lvg-design-mark { + display: inline-grid; + width: 14px; + height: 14px; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 1fr; + flex-shrink: 0; + overflow: hidden; + border-radius: 3px; + box-shadow: inset 0 0 0 1px var(--lvg-live-border); +} + +.lvg-design-mark i:nth-child(1) { background: var(--lvg-live-brand); } +.lvg-design-mark i:nth-child(2) { background: var(--lvg-live-patina); } +.lvg-design-mark i:nth-child(3) { background: var(--lvg-live-text); } +.lvg-design-mark i:nth-child(4) { background: oklch(34% 0 0); } + +.lvg-detect-badge { + display: inline-flex; + min-width: 16px; + height: 16px; + padding: 0 5px; + align-items: center; + justify-content: center; + color: var(--lvg-live-ink); + background: var(--lvg-live-brand); + border-radius: 7px; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-10); + font-weight: 600; +} + +.lvg-steer { + display: inline-flex; + width: 104px; + height: 28px; + margin: 0 4px 0 6px; + align-items: center; + flex-shrink: 0; + color: var(--lvg-live-text-dim); + background: var(--lvg-live-chat); + border: 1px solid transparent; + border-radius: 7px; + overflow: hidden; + cursor: pointer; +} + +.lvg-steer[data-expanded="true"] { + width: min(280px, 40vw); +} + +.lvg-steer[data-processing="true"] { + border-color: var(--lvg-live-patina-soft); + animation: lvg-steer-processing 1.6s ease-in-out infinite; +} + +.lvg-steer-icon, +.lvg-steer-voice { + display: inline-flex; + width: 28px; + height: 28px; + padding: 0; + flex-shrink: 0; + align-items: center; + justify-content: center; + color: var(--lvg-live-text-dim); + background: transparent; + border: 0; +} + +.lvg-steer-voice { + cursor: pointer; +} + +.lvg-steer-hint { + flex: 1; + min-width: 0; + font-size: var(--lvg-fs-11-5); + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.lvg-steer input { + flex: 1; + min-width: 0; + padding: 0 6px; + color: var(--lvg-live-text); + caret-color: var(--lvg-live-brand); + background: transparent; + border: 0; + outline: 0; + font-size: var(--lvg-fs-11-5); +} + +.lvg-steer input::placeholder { + color: var(--lvg-live-text-dim); + opacity: 1; +} + +.lvg-steer-dots { + display: inline-flex; + flex: 1; + padding: 0 12px 0 2px; + align-items: center; + justify-content: center; + gap: 5px; +} + +.lvg-steer-dots i { + width: 4px; + height: 4px; + background: var(--lvg-live-patina-pale); + border-radius: 50%; + box-shadow: 0 0 6px var(--lvg-live-patina-soft); + animation: lvg-steer-dot 1.05s ease-in-out infinite; +} + +.lvg-steer-dots i:nth-child(2) { animation-delay: 140ms; } +.lvg-steer-dots i:nth-child(3) { animation-delay: 280ms; } + +.lvg-global-divider { + width: 1px; + height: 18px; + margin: 0 4px 0 2px; + background: var(--lvg-live-hairline); +} + +.lvg-global-exit { + display: inline-flex; + width: 24px; + height: 24px; + padding: 0; + align-items: center; + justify-content: center; + color: var(--lvg-live-text-dim); + background: transparent; + border: 0; + border-radius: 6px; + cursor: pointer; +} + +.lvg-agent-tooltip, +.lvg-live-toast { + position: absolute; + left: 50%; + z-index: 30; + padding: 6px 9px; + color: var(--lvg-live-text); + background: var(--lvg-live-chat); + border: 1px solid var(--lvg-live-hairline); + border-radius: 7px; + box-shadow: var(--lvg-live-shadow); + transform: translateX(-50%); + font-size: var(--lvg-fs-11); + font-weight: 500; + line-height: 1.35; + text-align: center; +} + +.lvg-agent-tooltip { + bottom: 63px; + width: 220px; +} + +.lvg-live-toast { + bottom: 66px; + max-width: min(420px, calc(100% - 32px)); + padding: 8px 16px; + color: oklch(99% 0 0); + background: var(--lvg-live-ink); + border: 0; + font-size: var(--lvg-fs-12); + font-weight: 400; +} + +.lvg-pending-dock { + position: absolute; + bottom: 58px; + left: 50%; + z-index: 25; + display: inline-flex; + align-items: center; + gap: 6px; + transform: translateX(-50%); + font-family: var(--lvg-live-font); +} + +.lvg-pending-pill, +.lvg-pending-decision { + display: inline-flex; + height: 30px; + align-items: center; + justify-content: center; + border-radius: 999px; + font-size: var(--lvg-fs-12); + font-weight: 600; + white-space: nowrap; +} + +.lvg-pending-pill { + gap: 8px; + padding: 7px 12px 7px 14px; + color: var(--lvg-live-ink); + background: var(--lvg-live-brand); + border: 0; + box-shadow: 0 4px 16px oklch(0% 0 0 / 0.16), 0 1px 3px oklch(0% 0 0 / 0.1); + cursor: pointer; +} + +.lvg-pending-pill[aria-busy="true"] { + cursor: wait; + filter: brightness(0.98); +} + +.lvg-pending-count { + display: inline-flex; + min-width: 17px; + height: 17px; + padding: 0 5px; + align-items: center; + justify-content: center; + background: oklch(4% 0.004 95 / 0.18); + border-radius: 999px; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-10); + font-weight: 700; +} + +.lvg-pending-spinner { + width: 12px; + height: 12px; + border: 2px solid currentColor; + border-top-color: transparent; + border-radius: 50%; + animation: lvg-spin 600ms linear infinite; +} + +.lvg-pending-trash { + display: inline-flex; + width: 30px; + height: 30px; + padding: 0; + align-items: center; + justify-content: center; + color: var(--lvg-live-text-dim); + background: var(--lvg-live-chat); + border: 1px solid var(--lvg-live-hairline); + border-radius: 50%; + box-shadow: 0 4px 16px oklch(0% 0 0 / 0.12), 0 1px 3px oklch(0% 0 0 / 0.08); + cursor: pointer; +} + +.lvg-pending-decision { + padding: 0 12px; + color: var(--lvg-live-text-dim); + background: var(--lvg-live-chat); + border: 1px solid var(--lvg-live-hairline); + box-shadow: 0 4px 16px oklch(0% 0 0 / 0.12), 0 1px 3px oklch(0% 0 0 / 0.08); + cursor: pointer; +} + +.lvg-pending-decision.is-primary { + color: var(--lvg-live-ink); + background: var(--lvg-live-brand); + border-color: var(--lvg-live-brand); +} + +.lvg-design-panel { + position: absolute; + top: 12px; + right: 12px; + bottom: 72px; + z-index: 22; + display: flex; + width: min(440px, calc(100% - 24px)); + flex-direction: column; + overflow: hidden; + color: oklch(15% 0 0); + background: var(--lvg-live-ink); + border: 1.5px solid var(--lvg-live-border); + border-radius: 14px; + box-shadow: var(--lvg-live-shadow); +} + +.lvg-design-header { + display: flex; + padding: 10px 10px 10px 14px; + align-items: center; + gap: 10px; + color: var(--lvg-live-text); + border-bottom: 1px solid var(--lvg-live-hairline); +} + +.lvg-design-title { + flex: 1; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-11-5); + font-weight: 600; + letter-spacing: 0.02em; +} + +.lvg-design-tabs { + display: inline-flex; + padding: 2px; + gap: 2px; + background: var(--lvg-live-hairline); + border-radius: 7px; +} + +.lvg-design-tabs button { + padding: 4px 10px; + color: var(--lvg-live-text-dim); + background: transparent; + border: 0; + border-radius: 5px; + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-10); + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + cursor: pointer; +} + +.lvg-design-tabs button[aria-selected="true"] { + color: var(--lvg-live-text); + background: var(--lvg-live-ink); +} + +.lvg-design-close { + display: inline-flex; + width: 26px; + height: 26px; + padding: 0; + align-items: center; + justify-content: center; + color: var(--lvg-live-text-dim); + background: transparent; + border: 0; + border-radius: 7px; + cursor: pointer; +} + +.lvg-design-body { + flex: 1; + padding: 12px 12px 20px; + overflow-y: auto; + background: oklch(94% 0 0); +} + +.lvg-design-tile { + margin: 0 4px 10px; + padding: 16px; + background: oklch(98.5% 0 0); + border-radius: 16px; +} + +.lvg-design-meta { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 10px; + color: oklch(55% 0 0); + font-family: var(--lvg-live-mono); + font-size: var(--lvg-fs-10); + font-weight: 500; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.lvg-design-meta strong { + color: oklch(15% 0 0); + font-family: var(--lvg-live-font); + font-size: var(--lvg-fs-12); + letter-spacing: 0.05em; + text-transform: none; +} + +.lvg-design-swatch { + height: 72px; + margin-top: 10px; + background: linear-gradient(135deg, var(--lvg-live-brand), oklch(61% 0.085 78)); + border-radius: 10px; +} + +.lvg-design-type { + margin: 8px 0 4px; + color: oklch(15% 0 0); + font-family: var(--ks-font-display); + font-size: var(--ks-type-headline-size); + font-weight: 300; + line-height: 0.95; +} + +.lvg-design-copy { + margin: 6px 0 0; + color: oklch(35% 0 0); + font-size: var(--lvg-fs-11-5); + line-height: 1.45; +} + +.live-ui-gallery__fidelity-note { + max-width: 80ch; + margin: 18px 0 0; + color: var(--ks-text-faint); + font-size: var(--lvg-fs-12); + line-height: 1.6; +} + +.live-ui-gallery__fidelity-note code { + padding: var(--ks-code-pad); + color: var(--ks-code-fg); + background: var(--ks-code-bg); + border-radius: var(--ks-code-radius); + font-family: var(--ks-mono); + font-size: var(--ks-type-mono-size); +} + +@keyframes lvg-spin { + to { transform: rotate(360deg); } +} + +@keyframes lvg-voice-pulse { + 0%, 100% { opacity: 0.55; } + 50% { opacity: 1; } +} + +@keyframes lvg-agent-dot { + 0%, 100% { opacity: 0.45; transform: scale(0.9); } + 50% { opacity: 1; transform: scale(1); } +} + +@keyframes lvg-steer-processing { + 0%, 100% { border-color: var(--lvg-live-patina-soft); box-shadow: 0 0 0 0 transparent; } + 50% { border-color: oklch(82% 0.07 188 / 0.55); box-shadow: 0 0 14px oklch(70% 0.12 188 / 0.18); } +} + +@keyframes lvg-steer-dot { + 0%, 70%, 100% { opacity: 0.28; transform: scale(0.82); } + 35% { opacity: 1; transform: scale(1); } +} + +@media (max-width: 1120px) { + .live-ui-gallery__previews { + grid-template-columns: 1fr; + } + + .live-ui-stage { + min-height: 500px; + } +} + +@media (max-width: 760px) { + .live-ui-gallery__header { + grid-template-columns: 1fr; + gap: 24px; + } + + .live-ui-gallery__quick-group { + grid-template-columns: 1fr; + gap: 6px; + } + + .live-ui-gallery__quick-group > span { + padding-top: 0; + } + + .lvg-global-mode span:not(.lvg-design-mark):not(.lvg-detect-badge) { + display: none; + } + + .lvg-live-brand { + padding-left: 9px; + } + + .lvg-steer { + width: 88px; + margin-left: 2px; + } + + .lvg-steer[data-expanded="true"] { + width: min(230px, 42vw); + } + + .lvg-tune-grid { + grid-template-columns: 1fr; + } + + .lvg-arrival-progress { + display: none; + } +} + +@media (max-width: 520px) { + .lvg-host-page { + padding-inline: 18px; + background-position: 18px 0; + } + + .lvg-selection-outline, + .lvg-annotation-layer { + left: 16px; + width: calc(100% - 32px); + } + + .lvg-insert-placeholder { + left: 18px; + width: calc(100% - 36px); + } + + .lvg-configure-modifiers { + padding-inline: 7px; + gap: 6px; + } + + .lvg-configure-modifier:first-child { + max-width: 4.5rem; + overflow: hidden; + text-overflow: ellipsis; + } + + .lvg-cycling-row { + gap: 4px; + } + + .lvg-tune-button span:not(.lvg-tune-badge) { + display: none; + } + + .lvg-accept { + padding-inline: 10px; + } +} + +@media (prefers-reduced-motion: reduce) { + .live-ui-gallery *, + .live-ui-gallery *::before, + .live-ui-gallery *::after { + scroll-behavior: auto !important; + animation-duration: 1ms !important; + animation-iteration-count: 1 !important; + transition-duration: 1ms !important; + } +}