You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
683 lines
20 KiB
683 lines
20 KiB
<script lang="ts">
|
|
import { actx } from '@/lib/actx/lib/instance_actx.svelte';
|
|
import './_components/design-system.css';
|
|
|
|
// Test data
|
|
const locales = ['es', 'en', 'de', 'fr', 'it', 'pt'] as const;
|
|
const now = new Date();
|
|
let logEntries = $state(actx.logr.getLogs());
|
|
|
|
// Helpers
|
|
function cycleLocale() {
|
|
const idx = locales.indexOf(actx.locale as any);
|
|
const next = locales[(idx + 1) % locales.length];
|
|
actx.ling.setLocale(next);
|
|
}
|
|
|
|
function fireLog(level: 'debug' | 'info' | 'warn' | 'error') {
|
|
actx.logr[level](
|
|
'test',
|
|
{ es: `Log de nivel ${level}`, en: `${level} level log` },
|
|
{ ts: Date.now() }
|
|
);
|
|
logEntries = actx.logr.getLogs();
|
|
}
|
|
|
|
function onLocaleBadgeKeydown(e: KeyboardEvent) {
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
e.preventDefault();
|
|
cycleLocale();
|
|
}
|
|
}
|
|
|
|
const LOG_COLORS: Record<string, string> = {
|
|
'0': 'var(--color-info)',
|
|
'1': 'var(--color-success)',
|
|
'2': 'var(--color-warning)',
|
|
'3': 'var(--color-error)'
|
|
};
|
|
|
|
// Component groups data
|
|
const compGroups = [
|
|
{
|
|
label: 'Primitivas',
|
|
links: [
|
|
{ name: 'Separator', href: '/test/separator' },
|
|
{ name: 'Label', href: '/test/label' },
|
|
{ name: 'Progress', href: '/test/progress' },
|
|
{ name: 'Meter', href: '/test/meter' },
|
|
{ name: 'Spinner', href: '/test/air/spinner' },
|
|
{ name: 'Air Hub', href: '/test/air' },
|
|
{ name: 'Toggle', href: '/test/toggle' },
|
|
{ name: 'ToggleGroup', href: '/test/toggle-group' },
|
|
{ name: 'Pagination', href: '/test/pagination' },
|
|
{ name: 'Slider', href: '/test/slider' },
|
|
{ name: 'ScrollArea', href: '/test/scroll-area' },
|
|
{ name: 'VirtualList', href: '/test/virtual-list' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Formulario',
|
|
links: [
|
|
{ name: 'Switch', href: '/test/switch' },
|
|
{ name: 'Checkbox', href: '/test/checkbox' },
|
|
{ name: 'RadioGroup', href: '/test/radio-group' },
|
|
{ name: 'RatingGroup', href: '/test/rating-group' },
|
|
{ name: 'Toolbar', href: '/test/toolbar' },
|
|
{ name: 'PinInput', href: '/test/pin-input' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Campos',
|
|
links: [
|
|
{ name: 'Field', href: '/test/field' },
|
|
{ name: 'Editable', href: '/test/editable' },
|
|
{ name: 'NumberField', href: '/test/number-field' },
|
|
{ name: 'DateField', href: '/test/date-picker' },
|
|
{ name: 'TimeField', href: '/test/time-field' },
|
|
{ name: 'TimeRangeField', href: '/test/time-range-field' },
|
|
{ name: 'FileUpload', href: '/test/file-upload' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Compuestos',
|
|
links: [
|
|
{ name: 'Button', href: '/test/button' },
|
|
{ name: 'Avatar', href: '/test/avatar' },
|
|
{ name: 'AspectRatio', href: '/test/aspect-ratio' },
|
|
{ name: 'Collapsible', href: '/test/collapsible' },
|
|
{ name: 'Accordion', href: '/test/accordion' },
|
|
{ name: 'Tabs', href: '/test/tabs' },
|
|
{ name: 'Splitter', href: '/test/splitter' },
|
|
{ name: 'Stepper', href: '/test/stepper' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Selectores',
|
|
links: [
|
|
{ name: 'Select', href: '/test/select' },
|
|
{ name: 'Combobox', href: '/test/combobox' },
|
|
{ name: 'TagsInput', href: '/test/tags-input' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Floating',
|
|
links: [
|
|
{ name: 'Tooltip', href: '/test/tooltip' },
|
|
{ name: 'Popover', href: '/test/popover' },
|
|
{ name: 'DropdownMenu', href: '/test/dropdown-menu' },
|
|
{ name: 'ContextMenu', href: '/test/context-menu' },
|
|
{ name: 'Menubar', href: '/test/air/menubar' },
|
|
{ name: 'Command', href: '/test/air/command' },
|
|
{ name: 'LinkPreview', href: '/test/air/link-preview' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Overlays',
|
|
links: [
|
|
{ name: 'AlertDialog', href: '/test/alert-dialog' },
|
|
{ name: 'Dialog', href: '/test/dialog' },
|
|
{ name: 'Drawer', href: '/test/drawer' },
|
|
{ name: 'Toast', href: '/test/toast' },
|
|
{ name: 'Form', href: '/test/air/form' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Fechas',
|
|
links: [
|
|
{ name: 'Calendar', href: '/test/air/calendar' },
|
|
{ name: 'RangeCalendar', href: '/test/range-calendar' },
|
|
{ name: 'DateRangeField', href: '/test/date-range-field' },
|
|
{ name: 'DateRangePicker', href: '/test/date-range-picker' }
|
|
]
|
|
},
|
|
{
|
|
label: 'Extra',
|
|
links: [
|
|
{ name: 'ColorPicker', href: '/test/air/color-picker' },
|
|
{ name: 'Modal', href: '/test/modal' }
|
|
]
|
|
}
|
|
];
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>Test Hub - Component Tests</title>
|
|
</svelte:head>
|
|
|
|
<div class="test-page test-hub">
|
|
<!-- Header -->
|
|
<header class="test-hub-header">
|
|
<div class="test-hub-header-inner">
|
|
<div class="test-hub-brand">
|
|
<span class="test-hub-logo">ACTX<em>TEST</em></span>
|
|
<a href="/test/terra" class="test-hub-sub">→ Terra Hub</a>
|
|
</div>
|
|
<button class="locale-badge" onclick={cycleLocale} onkeydown={onLocaleBadgeKeydown}>
|
|
{actx.locale.toUpperCase()}
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="test-hub-main">
|
|
<!-- Componentes Section -->
|
|
<section class="test-hub-section">
|
|
<h2 class="test-hub-section-title">Componentes UI</h2>
|
|
<div class="test-hub-groups">
|
|
{#each compGroups as group}
|
|
<div class="test-hub-group">
|
|
<span class="test-hub-group-label">{group.label}</span>
|
|
<div class="test-hub-links">
|
|
{#each group.links as link}
|
|
<a href={link.href} class="test-hub-link">{link.name}</a>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Grid Cards -->
|
|
<div class="test-hub-grid">
|
|
<!-- LING -->
|
|
<section class="test-hub-card test-hub-card--ling">
|
|
<h2>ling</h2>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">t()</span>
|
|
<span class="test-hub-value">{actx.t('common.ok')} / {actx.t('common.cancel')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">ts()</span>
|
|
<span class="test-hub-value"
|
|
>{actx.ts({
|
|
es: 'Hola mundo',
|
|
en: 'Hello world',
|
|
de: 'Hallo Welt',
|
|
fr: 'Bonjour monde',
|
|
it: 'Ciao mondo',
|
|
pt: 'Olá mundo'
|
|
})}</span
|
|
>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">locale</span>
|
|
<span class="test-hub-value test-hub-value--accent">{actx.locale}</span>
|
|
</div>
|
|
<div class="test-hub-locales">
|
|
{#each locales as loc}
|
|
<button
|
|
class="test-hub-loc-btn"
|
|
class:active={actx.locale === loc}
|
|
onclick={() => actx.ling.setLocale(loc)}>{loc}</button
|
|
>
|
|
{/each}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- NUMR -->
|
|
<section class="test-hub-card test-hub-card--numr">
|
|
<h2>numr</h2>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(1234567.891)</span>
|
|
<span class="test-hub-value">{actx.numr.f(1234567.891)}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(0.5, min:2,max:4)</span>
|
|
<span class="test-hub-value">{actx.numr.f(0.5, { minDecimals: 2, maxDecimals: 4 })}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(1000000)</span>
|
|
<span class="test-hub-value">{actx.numr.f(1000000)}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(3.14159)</span>
|
|
<span class="test-hub-value">{actx.numr.f(3.14159, { maxDecimals: 4 })}</span>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- DATI -->
|
|
<section class="test-hub-card test-hub-card--dati">
|
|
<h2>dati</h2>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(now, 'long')</span>
|
|
<span class="test-hub-value">{actx.dati.f(now, 'long')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(now, 'short')</span>
|
|
<span class="test-hub-value">{actx.dati.f(now, 'short')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(now, 'full')</span>
|
|
<span class="test-hub-value test-hub-value--small">{actx.dati.f(now, 'full')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">date+time</span>
|
|
<span class="test-hub-value">{actx.dati.f(now, { date: 'short', time: 'short' })}</span>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- UNIT -->
|
|
<section class="test-hub-card test-hub-card--unit">
|
|
<h2>unit</h2>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">75kg → lb</span>
|
|
<span class="test-hub-value">{actx.unit.weight.fTo(75, 'kg', 'lb')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">100km → mi</span>
|
|
<span class="test-hub-value">{actx.unit.length.fTo(100, 'km', 'mi')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">100°C → °F</span>
|
|
<span class="test-hub-value">{actx.unit.temp.fTo(100, 'c', 'f')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">10L → gal</span>
|
|
<span class="test-hub-value">{actx.unit.volume.fTo(10, 'l', 'gal')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">sistema</span>
|
|
<span class="test-hub-value test-hub-value--accent">{actx.unit.getSystem()}</span>
|
|
</div>
|
|
<div class="test-hub-btn-row">
|
|
<button onclick={() => actx.unit.setSystem('metric')}>metric</button>
|
|
<button onclick={() => actx.unit.setSystem('imperial')}>imperial</button>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- CURR -->
|
|
<section class="test-hub-card test-hub-card--curr">
|
|
<h2>curr</h2>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">moneda activa</span>
|
|
<span class="test-hub-value test-hub-value--accent">{actx.curr.getCurrency()}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(99.99, symbol)</span>
|
|
<span class="test-hub-value">{actx.curr.f(99.99, 'symbol')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">f(99.99, code)</span>
|
|
<span class="test-hub-value">{actx.curr.f(99.99, 'code')}</span>
|
|
</div>
|
|
<div class="test-hub-row">
|
|
<span class="test-hub-label">monedas</span>
|
|
<span class="test-hub-value test-hub-value--muted"
|
|
>{actx.curr.getCurrencies().join(', ') || '(sin definir)'}</span
|
|
>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- LOGR -->
|
|
<section class="test-hub-card test-hub-card--logr">
|
|
<h2>logr</h2>
|
|
<div class="test-hub-btn-row">
|
|
<button onclick={() => fireLog('debug')} class="btn-debug">debug</button>
|
|
<button onclick={() => fireLog('info')} class="btn-info">info</button>
|
|
<button onclick={() => fireLog('warn')} class="btn-warn">warn</button>
|
|
<button onclick={() => fireLog('error')} class="btn-error">error</button>
|
|
</div>
|
|
<button
|
|
class="test-hub-btn-clear"
|
|
onclick={() => {
|
|
actx.logr.clear();
|
|
logEntries = [];
|
|
}}>clear</button
|
|
>
|
|
<div class="test-hub-log-list">
|
|
{#each logEntries.slice(-6).reverse() as entry}
|
|
<div
|
|
class="test-hub-log-entry"
|
|
style="border-left-color: {LOG_COLORS[String(entry.level)]}"
|
|
>
|
|
<span class="test-hub-log-level" style="color: {LOG_COLORS[String(entry.level)]}"
|
|
>{entry.level}</span
|
|
>
|
|
<span class="test-hub-log-msg">{actx.ts(entry.message)}</span>
|
|
</div>
|
|
{/each}
|
|
{#if logEntries.length === 0}
|
|
<span class="test-hub-value--muted">sin logs</span>
|
|
{/if}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<style>
|
|
.test-hub {
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* ── Header ───────────────────────────────────────────────────────────────── */
|
|
.test-hub-header {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
background: var(--color-surface);
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
.test-hub-header-inner {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
padding: var(--spacing-4) var(--spacing-6);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.test-hub-brand {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-4);
|
|
}
|
|
|
|
.test-hub-logo {
|
|
font-size: var(--text-base);
|
|
font-weight: 700;
|
|
letter-spacing: 0.15em;
|
|
text-transform: uppercase;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
.test-hub-logo em {
|
|
color: var(--color-primary);
|
|
font-style: normal;
|
|
}
|
|
|
|
.test-hub-sub {
|
|
font-size: var(--text-xs);
|
|
color: var(--color-text-muted);
|
|
text-decoration: none;
|
|
padding: var(--spacing-1) var(--spacing-3);
|
|
border-radius: var(--radius-full);
|
|
background: var(--color-primary-bg);
|
|
border: 1px solid var(--color-primary-border);
|
|
transition: all var(--transition-fast);
|
|
}
|
|
|
|
.test-hub-sub:hover {
|
|
background: var(--color-primary);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
.locale-badge {
|
|
padding: var(--spacing-1) var(--spacing-3);
|
|
border: 1px solid var(--color-primary);
|
|
border-radius: var(--radius-sm);
|
|
font-size: var(--text-xs);
|
|
font-weight: 700;
|
|
letter-spacing: 0.1em;
|
|
cursor: pointer;
|
|
color: var(--color-primary);
|
|
background: var(--color-primary-bg);
|
|
transition: all var(--transition-fast);
|
|
}
|
|
|
|
.locale-badge:hover {
|
|
background: var(--color-primary);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
/* ── Main ────────────────────────────────────────────────────────────────── */
|
|
.test-hub-main {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
padding: var(--spacing-8) var(--spacing-6);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-8);
|
|
}
|
|
|
|
/* ── Section Componentes ──────────────────────────────────────────────────── */
|
|
.test-hub-section {
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-top: 3px solid var(--color-primary);
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--spacing-6);
|
|
}
|
|
|
|
.test-hub-section-title {
|
|
font-size: var(--text-xs);
|
|
font-weight: 700;
|
|
letter-spacing: 0.2em;
|
|
text-transform: uppercase;
|
|
color: var(--color-text-muted);
|
|
margin: 0 0 var(--spacing-4) 0;
|
|
}
|
|
|
|
.test-hub-groups {
|
|
display: flex;
|
|
gap: var(--spacing-8);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.test-hub-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-3);
|
|
}
|
|
|
|
.test-hub-group-label {
|
|
font-size: var(--text-xs);
|
|
font-weight: 700;
|
|
letter-spacing: 0.15em;
|
|
text-transform: uppercase;
|
|
color: var(--color-text-muted);
|
|
}
|
|
|
|
.test-hub-links {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-1);
|
|
}
|
|
|
|
.test-hub-link {
|
|
font-size: var(--text-sm);
|
|
font-weight: 500;
|
|
color: var(--color-primary);
|
|
text-decoration: none;
|
|
padding: var(--spacing-1) 0;
|
|
transition: opacity var(--transition-fast);
|
|
}
|
|
|
|
.test-hub-link:hover {
|
|
opacity: 0.7;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* ── Grid ────────────────────────────────────────────────────────────────── */
|
|
.test-hub-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
gap: var(--spacing-4);
|
|
}
|
|
|
|
/* ── Cards ───────────────────────────────────────────────────────────────── */
|
|
.test-hub-card {
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--spacing-5);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-4);
|
|
transition: border-color var(--transition-normal);
|
|
}
|
|
|
|
.test-hub-card:hover {
|
|
border-color: var(--color-border-focus);
|
|
}
|
|
|
|
.test-hub-card h2 {
|
|
font-size: var(--text-xs);
|
|
font-weight: 700;
|
|
letter-spacing: 0.2em;
|
|
text-transform: uppercase;
|
|
color: var(--color-text-muted);
|
|
margin: 0;
|
|
padding-bottom: var(--spacing-2);
|
|
border-bottom: 1px solid var(--color-border-muted);
|
|
}
|
|
|
|
/* Card accent borders */
|
|
.test-hub-card--ling {
|
|
border-top: 3px solid var(--color-info);
|
|
}
|
|
.test-hub-card--numr {
|
|
border-top: 3px solid var(--color-success);
|
|
}
|
|
.test-hub-card--dati {
|
|
border-top: 3px solid #3b82f6;
|
|
}
|
|
.test-hub-card--unit {
|
|
border-top: 3px solid var(--color-warning);
|
|
}
|
|
.test-hub-card--curr {
|
|
border-top: 3px solid #ec4899;
|
|
}
|
|
.test-hub-card--logr {
|
|
border-top: 3px solid var(--color-primary);
|
|
}
|
|
|
|
/* ── Rows ────────────────────────────────────────────────────────────────── */
|
|
.test-hub-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: var(--spacing-3);
|
|
font-size: var(--text-sm);
|
|
}
|
|
|
|
.test-hub-label {
|
|
color: var(--color-text-muted);
|
|
font-size: var(--text-xs);
|
|
min-width: 140px;
|
|
flex-shrink: 0;
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.test-hub-value {
|
|
font-weight: 500;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
.test-hub-value--small {
|
|
font-size: var(--text-xs);
|
|
}
|
|
|
|
.test-hub-value--accent {
|
|
color: var(--color-primary);
|
|
font-weight: 700;
|
|
}
|
|
|
|
.test-hub-value--muted {
|
|
color: var(--color-text-dim);
|
|
font-style: italic;
|
|
}
|
|
|
|
/* ── Buttons ─────────────────────────────────────────────────────────────── */
|
|
.test-hub-btn-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--spacing-2);
|
|
}
|
|
|
|
.test-hub-card button {
|
|
padding: var(--spacing-2) var(--spacing-3);
|
|
background: var(--color-background);
|
|
color: var(--color-text);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm);
|
|
font-family: inherit;
|
|
font-size: var(--text-xs);
|
|
font-weight: 600;
|
|
letter-spacing: 0.05em;
|
|
cursor: pointer;
|
|
transition: all var(--transition-fast);
|
|
}
|
|
|
|
.test-hub-card button:hover {
|
|
background: var(--color-surface-elevated);
|
|
border-color: var(--color-border-focus);
|
|
}
|
|
|
|
.btn-debug {
|
|
color: var(--color-info);
|
|
border-color: rgba(96, 165, 250, 0.3);
|
|
}
|
|
.btn-info {
|
|
color: var(--color-success);
|
|
border-color: rgba(74, 222, 128, 0.3);
|
|
}
|
|
.btn-warn {
|
|
color: var(--color-warning);
|
|
border-color: rgba(251, 191, 36, 0.3);
|
|
}
|
|
.btn-error {
|
|
color: var(--color-error);
|
|
border-color: rgba(248, 113, 113, 0.3);
|
|
}
|
|
|
|
.test-hub-btn-clear {
|
|
background: transparent !important;
|
|
border-color: var(--color-border-muted) !important;
|
|
color: var(--color-text-dim) !important;
|
|
font-size: 0.6875rem;
|
|
align-self: flex-start;
|
|
}
|
|
|
|
/* ── Locale Buttons ───────────────────────────────────────────────────────── */
|
|
.test-hub-locales {
|
|
display: flex;
|
|
gap: var(--spacing-2);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.test-hub-loc-btn {
|
|
background: transparent;
|
|
border: 1px solid var(--color-border-muted);
|
|
color: var(--color-text-dim);
|
|
padding: var(--spacing-1) var(--spacing-3);
|
|
font-size: var(--text-xs);
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.test-hub-loc-btn.active {
|
|
background: var(--color-primary-bg);
|
|
border-color: var(--color-primary);
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
/* ── Log List ────────────────────────────────────────────────────────────── */
|
|
.test-hub-log-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-2);
|
|
}
|
|
|
|
.test-hub-log-entry {
|
|
display: flex;
|
|
gap: var(--spacing-3);
|
|
align-items: baseline;
|
|
padding: var(--spacing-2) var(--spacing-3);
|
|
font-size: var(--text-xs);
|
|
background: var(--color-background);
|
|
border-radius: var(--radius-sm);
|
|
border-left: 3px solid var(--color-border-muted);
|
|
}
|
|
|
|
.test-hub-log-level {
|
|
font-weight: 700;
|
|
font-size: 0.6875rem;
|
|
min-width: 2rem;
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.test-hub-log-msg {
|
|
color: var(--color-text-muted);
|
|
}
|
|
</style>
|