<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GNexus UI Kit — Vue Adapter Demo</title>
<link rel="stylesheet" href="/assets/fonts/phosphor-icons/src/css/icons.css">
<link rel="stylesheet" href="/assets/libs/highlight/styles/base16/summerfruit-dark.min.css">
<link rel="stylesheet" href="/css/kit.css">
<link rel="stylesheet" href="/css/demo.css">
<style>
body {
margin: 0;
background: #16161E;
color: #C0CAF5;
font-family: "IBM Plex Mono", "Courier New", monospace;
}
</style>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3.5.13/dist/vue.esm-browser.js",
"gnexus-ui-kit/vue": "/vue/index.js"
}
}
</script>
</head>
<body>
<div id="app"></div>
<script type="module">
import { createApp, ref, onMounted } from "vue";
import {
GnButton, GnIconButton, GnCopyButton,
GnBadge, GnAlert,
GnInput, GnSelect, GnTextarea, GnCheckbox, GnSwitch, GnRadioGroup, GnRange, GnCombobox, GnFileUpload,
GnTabs, GnTable, GnCard, GnHorizontalCard, GnLoginCard, GnMetricCard, GnStatusCard, GnActionCard, GnUserCard,
GnModal, GnDrawer, GnConfirmDialog, GnPopover, GnTooltip, GnDropdown,
GnNavList, GnSteps, GnProgress, GnProgressStages, GnTimeline, GnActivityLog,
GnDescriptionList, GnUsageMeter, GnEmptyState, GnSkeleton,
GnAvatar, GnIdentity, GnAvatarStack,
GnList, GnActionList, GnDefinitionList,
GnChip, GnChipGroup,
GnSearchField, GnPagination, GnToolbar,
GnPageHeader, GnToastProvider,
GnAccordion, GnNavigationShell, GnInputGroup
} from "gnexus-ui-kit/vue";
createApp({
components: {
GnButton, GnIconButton, GnCopyButton,
GnBadge, GnAlert,
GnInput, GnSelect, GnTextarea, GnCheckbox, GnSwitch, GnRadioGroup, GnRange, GnCombobox, GnFileUpload,
GnTabs, GnTable, GnCard, GnHorizontalCard, GnLoginCard, GnMetricCard, GnStatusCard, GnActionCard, GnUserCard,
GnModal, GnDrawer, GnConfirmDialog, GnPopover, GnTooltip, GnDropdown,
GnNavList, GnSteps, GnProgress, GnProgressStages, GnTimeline, GnActivityLog,
GnDescriptionList, GnUsageMeter, GnEmptyState, GnSkeleton,
GnAvatar, GnIdentity, GnAvatarStack,
GnList, GnActionList, GnDefinitionList,
GnChip, GnChipGroup,
GnSearchField, GnPagination, GnToolbar,
GnPageHeader, GnToastProvider,
GnAccordion, GnNavigationShell, GnInputGroup
},
setup() {
const toastRef = ref(null);
const showToast = (type, options) => toastRef.value?.[type](options);
const modalOpen = ref(false);
const drawerOpen = ref(false);
const confirmOpen = ref(false);
const name = ref("");
const status = ref("active");
const tab = ref("overview");
const tabCompact = ref("api");
const tabVertical = ref("profile");
const accordionOpen = ref("release-checklist");
const checked = ref(true);
const switched = ref(false);
const mode = ref("auto");
const rollout = ref(64);
const assignee = ref("");
const numberValue = ref(42);
const files = ref([]);
const searchQuery = ref("");
const searchValue = ref("release");
const checkedDisabled = ref(true);
const currentPage = ref(1);
const leftDrawerOpen = ref(false);
const currentSection = ref("Typography");
onMounted(() => {
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
const id = entry.target.id;
const item = navItemsVue.find(i => i.href === `#${id}`);
if (item) currentSection.value = item.label;
}
}
}, { rootMargin: "-58px 0px -80% 0px", threshold: 0 });
document.querySelectorAll(".docs-section").forEach(el => observer.observe(el));
setTimeout(() => {
const container = document.querySelector(".advanced-select-container");
const input = document.querySelector(".advanced-select-input");
if (container && input && typeof advancedSelect !== "undefined") {
container.append(advancedSelect(
input,
{
"name_1": "Joe",
"name_2": "James",
"name_3": "Jack",
"name_4": "Eliza",
"name_5": "Emily",
"name_6": "Eleanor",
"name_7": "Ella",
"name_8": "Ellie",
"name_9": "John",
"name_10": "David"
},
"Nothing found"
));
}
}, 300);
});
const statusOptions = [
{ value: "active", label: "Active" },
{ value: "paused", label: "Paused" },
{ value: "archived", label: "Archived" }
];
const tabs = [
{ id: "overview", label: "Overview", icon: "ph-chart-bar" },
{ id: "activity", label: "Activity", icon: "ph-clock" },
{ id: "settings", label: "Settings", icon: "ph-sliders" }
];
const tabsCompact = [
{ id: "api", label: "API" },
{ id: "webhooks", label: "Webhooks" },
{ id: "billing", label: "Billing", disabled: true }
];
const tabsVertical = [
{ id: "profile", label: "Profile" },
{ id: "access", label: "Access" },
{ id: "notes", label: "Notes" }
];
const tableColumns = [
{ key: "project", label: "Project" },
{ key: "status", label: "Status" },
{ key: "owner", label: "Owner" },
{ key: "updated", label: "Updated" },
{ key: "actions", label: "Actions" }
];
const tableRows = [
{ project: "Website Redesign", status: "Online", owner: "@design", updated: "2 min ago" },
{ project: "Billing API", status: "Degraded", owner: "@backend", updated: "1 hour ago" },
{ project: "Archive Import", status: "Offline", owner: "@ops", updated: "Yesterday" }
];
const modes = [
{ label: "Auto", value: "auto" },
{ label: "Manual", value: "manual" },
{ label: "Locked", value: "locked", disabled: true }
];
const people = [
{ label: "Joe", value: "joe" },
{ label: "James", value: "james" },
{ label: "Jack", value: "jack" },
{ label: "Eliza", value: "eliza" },
{ label: "Emily", value: "emily" },
{ label: "Eleanor", value: "eleanor" },
{ label: "Ella", value: "ella" },
{ label: "Ellie", value: "ellie" },
{ label: "John", value: "john" },
{ label: "David", value: "david" }
];
const steps = [
{ title: "Account", status: "complete", text: "Basic profile data is ready." },
{ title: "Plan", status: "complete", text: "Billing plan is selected." },
{ title: "Confirm", status: "current", text: "Review settings before launch." },
{ title: "Launch", text: "Available after confirmation." }
];
const stepsVertical = [
{ title: "Queued", status: "complete", text: "Job accepted and waiting for worker slot." },
{ title: "Running", status: "current", text: "Current task is processing input data." },
{ title: "Report", text: "Final summary appears after completion." }
];
const stages = [
{ label: "Queued", status: "complete" },
{ label: "Build", status: "complete" },
{ label: "Deploy", status: "current" },
{ label: "Verify" }
];
const details = [
{ key: "project", term: "Project", value: "Website Redesign" },
{ key: "status", term: "Status" },
{ key: "owner", term: "Owner" },
{ key: "updated", term: "Updated", value: "2026-04-11 22:12" }
];
const activity = [
{ key: "created", time: "22:24", title: "Build completed", variant: "success" },
{ key: "synced", time: "22:18", title: "Review requested", variant: "warning" },
{ key: "commit", time: "22:10", title: "Commit pushed", variant: "secondary" }
];
const timeline = [
{ time: "22:24", title: "Build completed", variant: "success", icon: "ph-check-circle", text: "Production bundle finished without warnings.", meta: [
{ label: "Done", variant: "success" },
{ label: "CI" }
]},
{ time: "22:18", title: "Review requested", variant: "warning", icon: "ph-warning", text: "Design tokens changed and need one visual pass before release.", meta: [
{ label: "Review", variant: "warning" }
]},
{ time: "22:10", title: "Commit pushed", icon: "ph-git-commit", text: "Component documentation and demo examples were updated." }
];
const navItems = [
{ label: "Overview", icon: "ph-house", href: "#" },
{ label: "Records", icon: "ph-table", href: "#" },
{ label: "Settings", icon: "ph-gear", href: "#" }
];
const navListItems = [
{ label: "Overview", active: true, href: "#" },
{ label: "Projects", icon: "ph-stack", meta: "12", href: "#" },
{ label: "Logs", href: "#" },
{ label: "Advanced", disabled: true, href: "#" }
];
const navItemsVue = [
{ label: "Typography", icon: "ph-text-aa", href: "#typography" },
{ label: "Palette", icon: "ph-palette", href: "#colors" },
{ label: "Buttons", icon: "ph-hand-pointing", href: "#buttons" },
{ label: "Forms", icon: "ph-textbox", href: "#forms" },
{ label: "Utilities", icon: "ph-ruler", href: "#utilities" },
{ label: "Editable String", icon: "ph-pencil-simple", href: "#editable-string" },
{ label: "Navigation & Overlays", icon: "ph-stack", href: "#navigation-overlays" },
{ label: "Navigation Shell", icon: "ph-sidebar-simple", href: "#navigation-shell" },
{ label: "Lists", icon: "ph-list-bullets", href: "#lists" },
{ label: "Badges", icon: "ph-tag", href: "#badges" },
{ label: "Alerts", icon: "ph-warning", href: "#alerts" },
{ label: "Tables", icon: "ph-table", href: "#tables" },
{ label: "Data Patterns", icon: "ph-chart-bar", href: "#data-patterns" },
{ label: "Page Header", icon: "ph-browser", href: "#page-header" },
{ label: "Key-Value", icon: "ph-list-dashes", href: "#description-list" },
{ label: "Progress", icon: "ph-activity", href: "#progress" },
{ label: "Steps", icon: "ph-list-numbers", href: "#steps" },
{ label: "Chips", icon: "ph-tag", href: "#chips" },
{ label: "Avatar", icon: "ph-user-circle", href: "#avatar" },
{ label: "Timeline", icon: "ph-clock", href: "#timeline" },
{ label: "Accordion", icon: "ph-caret-down", href: "#accordion" },
{ label: "Tabs", icon: "ph-tabs", href: "#tabs" },
{ label: "Drawer", icon: "ph-sidebar", href: "#drawer" },
{ label: "Toasts", icon: "ph-notification", href: "#toasts" },
{ label: "Cards", icon: "ph-squares-four", href: "#cards" },
{ label: "Modals", icon: "ph-browser", href: "#modals" },
{ label: "Confirm Dialog", icon: "ph-warning", href: "#confirm-dialog" }
];
const accordionItems = [
{ id: "release-checklist", label: "Release checklist", icon: "ph-list-checks", content: "Check component states, copy examples, keyboard focus, and responsive layout before release." },
{ id: "documentation-notes", label: "Documentation notes", icon: "ph-article", content: "Keep component copy short and include code examples for the smallest useful markup." },
{ id: "runtime-behavior", label: "Runtime behavior", icon: "ph-activity", content: "Use native disclosure behavior when the component does not need custom animation or async content." }
];
const listItems = [
{ label: "Dashboard" },
{ label: "Projects" },
{ label: "Reports" },
{ label: "Automations" },
{ label: "Settings" }
];
const actionListItems = [
{ title: "Release Plan", status: "success", ip: "192.168.2.21", btn1: "Open", btn2: "Toggle", btn2Variant: "accent" },
{ title: "Analytics Sync", status: "success", ip: "192.168.2.34", btn1: "Open", btn2: "Restart", btn2Variant: "danger", btn2Icon: "ph-arrow-clockwise" },
{ title: "Archive Job", muted: true, status: "warning", ip: "Offline", btn1: "Open", btn1Disabled: true, btn2: "Toggle", btn2Variant: "accent", btn2Disabled: true }
];
const definitionItems = [
{ term: "Item", description: "Базовая сущность интерфейса" },
{ term: "Group", description: "Логическая группа элементов" },
{ term: "Flow", description: "Набор действий, выполняемых последовательно" }
];
const dropdownItems = [
{ label: "Edit", icon: "ph-pencil-simple" },
{ label: "Duplicate", icon: "ph-copy" },
{ label: "Delete", icon: "ph-trash", danger: true }
];
function save() {
showToast('success', { title: "Saved", text: name.value || "Changes applied" });
modalOpen.value = false;
}
function confirmAction() {
showToast('success', { title: "Confirmed", text: "Action was confirmed" });
confirmOpen.value = false;
}
return {
modalOpen, drawerOpen, confirmOpen, leftDrawerOpen,
name, status, tab, tabCompact, tabVertical, accordionOpen, checked, checkedDisabled, switched, mode, rollout, assignee, files, searchQuery, searchValue, numberValue, currentPage, currentSection,
statusOptions, tabs, tabsCompact, tabsVertical, tableColumns, tableRows, modes, people, steps, stepsVertical, stages,
details, activity, timeline, navItems, navItemsVue, navListItems, listItems, actionListItems, definitionItems, accordionItems, dropdownItems,
save, confirmAction, showToast, toastRef
};
},
template: `
<GnToastProvider ref="toastRef">
<GnNavigationShell :items="navItemsVue" brand="GNexus UI Kit" title="Sections" subtitle="Component library" :current="currentSection">
<template #content>
<main class="container docs-page">
<header class="section docs-intro">
<h1 class="contrast">GNexus UI Kit</h1>
<p>Набор базовых элементов интерфейса.</p>
</header>
<div class="docs-layout">
<div class="docs-content">
<section class="section docs-section" id="typography">
<h2 class="section-title">Typography</h2>
<p class="docs-section-description">Базовая типографика задаёт размеры заголовков, текстовые состояния и моноширинный код. Используй семантические теги, а служебные классы добавляй для вариаций текста.</p>
<div class="block">
<h1>Heading H1</h1>
<h2>Heading H2</h2>
<h3>Heading H3</h3>
<h4>Heading H4</h4>
<h5>Heading H5</h5>
<h6>Heading H6</h6>
</div>
<div class="block">
<span class="eyebrow">System label</span>
<p class="text-lead">Lead text выделяет вводный абзац, описание страницы или важный контекст перед набором действий.</p>
<p class="text-primary">Основной текст интерфейса. Используется для контента.</p>
<p class="text-secondary">Вторичный текст, комментарии, подписи.</p>
<p class="text-muted">Приглушённый текст, подсказки.</p>
<p class="caption">Caption text для технических подписей, footnote и compact metadata.</p>
</div>
<div class="block">
<p>Состояния текста: <span class="text-success">success</span>, <span class="text-warning">warning</span>, <span class="text-danger">danger</span>, <span class="text-info">info</span>.</p>
<p>Inline code <code class="code">npm run build</code> и keyboard hint <span class="kbd">esc</span>.</p>
</div>
<div class="block">
<blockquote class="quote">Интерфейс должен оставаться читаемым даже в плотных технических сценариях.<cite>GNexus UI Kit</cite></blockquote>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Typography HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><h1 class="contrast">Dashboard</h1>
<span class="eyebrow">System label</span>
<p class="text-lead">Вводный текст страницы.</p>
<p class="text-primary">Основной текст интерфейса.</p>
<p class="text-muted">Приглушённая подсказка.</p>
<code class="code">npm run build</code>
<span class="kbd">esc</span></code></pre>
</div>
</section>
<section class="section docs-section" id="colors">
<h2 class="section-title">Color Palette</h2>
<p class="docs-section-description">Палитра построена вокруг тёмной базы, светлого primary-текста и ярких статусных цветов. Классы bg-* нужны для быстрых цветовых маркеров и демонстрации токенов.</p>
<div class="palette">
<div class="color"><div class="color-box bg-primary"></div><span>Primary</span></div>
<div class="color"><div class="color-box bg-secondary"></div><span>Secondary</span></div>
<div class="color"><div class="color-box bg-accent"></div><span>Accent</span></div>
<div class="color"><div class="color-box bg-info"></div><span>Info</span></div>
<div class="color"><div class="color-box bg-success"></div><span>Success</span></div>
<div class="color"><div class="color-box bg-warning"></div><span>Warning</span></div>
<div class="color"><div class="color-box bg-error"></div><span>Error</span></div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Palette HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="color-box bg-primary"></div>
<div class="color-box bg-secondary"></div>
<div class="color-box bg-success"></div>
<div class="color-box bg-warning"></div>
<div class="color-box bg-error"></div></code></pre>
</div>
</section>
<section class="section docs-section" id="buttons">
<h2 class="section-title">Buttons</h2>
<p class="docs-section-description">Кнопки собираются из базового класса .btn, цветового модификатора и опционального размера. Для иконок добавляй .with-icon, а состояние загрузки помечай .loading-state.</p>
<div class="block demo-actions">
<GnButton variant="primary">Primary</GnButton>
<GnButton variant="primary" icon="ph-house">Primary</GnButton>
<GnButton variant="secondary" icon="ph-code">Secondary</GnButton>
<GnButton variant="accent" icon="ph-envelope-simple">Accent</GnButton>
<GnButton variant="info" icon="ph-question">Info</GnButton>
<GnButton variant="danger" icon="ph-brackets-curly">Danger</GnButton>
<GnButton variant="warning" icon="ph-warning">Warning</GnButton>
<GnButton variant="success" icon="ph-codepen-logo">Success</GnButton>
</div>
<div class="block demo-actions">
<GnButton variant="primary" size="sm">Small</GnButton>
<GnButton variant="primary" size="sm" icon="ph-warning">Small</GnButton>
<GnButton variant="warning" size="sm" icon="ph-warning">Small</GnButton>
<GnButton variant="primary">Normal</GnButton>
<GnButton variant="primary" size="lg">Large</GnButton>
</div>
<div class="block demo-actions">
<GnButton variant="primary" disabled>Disabled</GnButton>
<GnButton variant="primary" disabled icon="ph-warning">Disabled</GnButton>
<GnButton variant="success" size="sm" icon="ph-bold ph-spinner" loading>Loading</GnButton>
<GnButton variant="warning" icon="ph-bold ph-spinner" loading>Loading</GnButton>
</div>
<h3 class="section-subtitle">Copy button</h3>
<p class="docs-section-description">Кнопка копирования на основе .btn-icon. В Vue-адаптере используй GnCopyButton.</p>
<div class="block demo-actions">
<GnCopyButton text="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7" />
<GnCopyButton text="compact-secret" size="sm" />
<GnCopyButton text="disabled" disabled />
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Buttons HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary with-icon">
<i class="ph ph-code"></i>
Secondary
</button>
<button class="btn btn-warning btn-small">Small</button>
<button class="btn btn-success with-icon loading-state" disabled>
<i class="ph-bold ph-spinner"></i>
Loading
</button></code></pre>
</div>
</section>
<section class="section docs-section" id="forms">
<h2 class="section-title">Forms</h2>
<p class="docs-section-description">Формы используют .form-group, .label и .input. Ошибки задаются на label через .error, а пояснение выводится соседним .input-info.</p>
<div class="block form-group">
<label class="label">
Text input
<input type="text" class="input" placeholder="Введите текст">
</label>
</div>
<div class="block form-group">
<label class="label error">
Text input
<i class="ph ph-user"></i>
<input type="text" class="input" placeholder="Введите текст">
</label>
<div class="input-info"><i class="ph ph-warning-circle"></i> Field cannot be empty</div>
</div>
<div class="block form-group">
<label class="label">
Password
<input type="password" class="input" placeholder="••••••">
</label>
</div>
<div class="block form-grid">
<div class="form-group">
<label class="label success">
Validated
<input type="text" class="input" value="Release Plan">
</label>
<div class="input-info"><i class="ph ph-check-circle"></i> Looks good</div>
</div>
<div class="form-group">
<label class="label warning">
Needs review
<input type="text" class="input" value="Draft">
</label>
<div class="input-info"><i class="ph ph-warning-circle"></i> Check before publishing</div>
</div>
<div class="form-group">
<label class="label">
Readonly
<input type="text" class="input" value="run_1048" readonly>
</label>
</div>
<div class="form-group">
<label class="label">
Disabled
<input type="text" class="input" value="Locked" disabled>
</label>
</div>
</div>
<div class="block form-grid">
<div class="form-group">
<label class="label">
Search
<i class="ph ph-magnifying-glass"></i>
<input type="search" class="input" value="release" placeholder="Search">
</label>
</div>
<div class="form-group">
<label class="label">
Number
<input type="number" class="input" value="42" min="0" max="100">
</label>
</div>
</div>
<div class="block">
<fieldset class="fieldset">
<legend class="legend">Date & Time</legend>
<div class="form-grid">
<div class="form-group">
<label class="label">Date<i class="ph ph-calendar-blank"></i><input type="date" class="input input-date" value="2026-04-23"></label>
</div>
<div class="form-group">
<label class="label">Time<i class="ph ph-clock"></i><input type="time" class="input input-time" value="14:30"></label>
</div>
<div class="form-group">
<label class="label">Date & time<i class="ph ph-calendar-dots"></i><input type="datetime-local" class="input input-datetime" value="2026-04-23T14:30"></label>
</div>
<div class="form-group">
<label class="label">Month<i class="ph ph-calendar"></i><input type="month" class="input input-month" value="2026-04"></label>
</div>
</div>
</fieldset>
</div>
<div class="block form-group">
<label class="label">
Text Area
<i class="ph ph-text-aa"></i>
<textarea class="input" placeholder="Введите текст"></textarea>
</label>
</div>
<div class="block">
<fieldset class="fieldset">
<legend class="legend">Fieldset</legend>
<div class="form-grid">
<div class="form-group">
<label class="label">
First name
<input type="text" class="input" value="Ada">
</label>
</div>
<div class="form-group">
<label class="label">
Last name
<input type="text" class="input" value="Lovelace">
</label>
</div>
</div>
</fieldset>
</div>
<div class="block">
<label class="file-upload">
<i class="ph ph-upload-simple"></i>
Upload file
<input type="file">
</label>
</div>
<div class="block">
<div class="file-upload-panel">
<form class="file-upload-form" action="#" method="post" enctype="multipart/form-data">
<div class="file-upload-header">
<div class="file-upload-heading">
<h3 class="file-upload-title">Upload files</h3>
<p class="file-upload-description">Attach documents, archives, screenshots or product images for review.</p>
</div>
<span class="badge badge-info">Max 12 MB</span>
</div>
<label class="file-upload-dropzone">
<span class="file-upload-icon" aria-hidden="true">
<i class="ph ph-cloud-arrow-up"></i>
</span>
<span class="file-upload-body">
<span class="file-upload-primary">Choose files</span>
<span class="file-upload-secondary">Images get thumbnails, other files show their type</span>
</span>
<input type="file" name="files" multiple data-file-upload-input>
</label>
<div class="file-upload-preview" data-file-upload-preview hidden></div>
<div class="file-upload-actions">
<button class="btn btn-secondary btn-small" type="reset">Reset</button>
<button class="btn btn-accent btn-small with-icon" type="submit">
<i class="ph ph-upload-simple"></i>
Upload
</button>
</div>
</form>
</div>
</div>
<div class="block range">
<label class="label">
Range
<input type="range" min="0" max="100" value="64">
</label>
</div>
<div class="block form-group">
<label class="label">
Select
<div class="select-wrap">
<select class="input select">
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</label>
</div>
<div class="block form-group">
<label class="label">
Select
<i class="ph ph-selection-all"></i>
<div class="select-wrap">
<select class="input select">
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</label>
</div>
<div class="block form-group">
<label class="label error">
Advanced Select
<i class="ph ph-user"></i>
<input type="text" class="input advanced-select-input" placeholder="Search">
</label>
<div class="advanced-select-container"></div>
<div class="input-info"><i class="ph ph-warning-circle"></i> Field cannot be empty</div>
</div>
<div class="block form-group">
<label class="checkbox">
<input type="checkbox">
<span class="checkbox-control" aria-hidden="true"></span>
<span class="checkbox-label">Checkbox 1</span>
</label>
<label class="checkbox mt-3">
<input type="checkbox">
<span class="checkbox-control" aria-hidden="true"></span>
<span class="checkbox-label">Checkbox 2</span>
</label>
<label class="checkbox mt-3">
<input type="checkbox" disabled>
<span class="checkbox-control" aria-hidden="true"></span>
<span class="checkbox-label">Disabled</span>
</label>
<label class="checkbox mt-3">
<input type="checkbox" disabled checked>
<span class="checkbox-control" aria-hidden="true"></span>
<span class="checkbox-label">Disabled & Checked</span>
</label>
</div>
<div class="block form-group">
<label class="radio">
<input type="radio" name="radio-demo">
<span class="radio-control" aria-hidden="true"></span>
<span class="radio-label">Radio 1</span>
</label>
<label class="radio ml-2">
<input type="radio" name="radio-demo">
<span class="radio-control" aria-hidden="true"></span>
<span class="radio-label">Radio 2</span>
</label>
<label class="radio ml-2">
<input type="radio" name="radio-demo" disabled>
<span class="radio-control" aria-hidden="true"></span>
<span class="radio-label">Radio 3</span>
</label>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Forms HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="form-group">
<label class="label error">
Project name
<i class="ph ph-user"></i>
<input class="input" type="text" placeholder="Launch Plan">
</label>
<div class="input-info">
<i class="ph ph-warning-circle"></i>
Field cannot be empty
</div>
</div>
<fieldset class="fieldset">
<legend class="legend">Fieldset</legend>
<label class="label success">
Validated
<input class="input" type="text" value="Release Plan">
</label>
</fieldset>
<label class="file-upload">
Upload file
<input type="file">
</label>
<fieldset class="fieldset">
<legend class="legend">Date & Time</legend>
<div class="form-grid">
<label class="label">
Date
<i class="ph ph-calendar-blank"></i>
<input class="input input-date" type="date" value="2026-04-23" data-date-picker>
</label>
<label class="label">
Time
<i class="ph ph-clock"></i>
<input class="input input-time" type="time" value="14:30" data-date-picker>
</label>
<label class="label">
Date & time
<i class="ph ph-calendar-dots"></i>
<input class="input input-datetime" type="datetime-local" value="2026-04-23T14:30" data-date-picker>
</label>
</div>
</fieldset>
<div class="file-upload-panel">
<form class="file-upload-form" enctype="multipart/form-data">
<div class="file-upload-header">
<div class="file-upload-heading">
<h3 class="file-upload-title">Upload files</h3>
<p class="file-upload-description">Attach documents, archives or images.</p>
</div>
<span class="badge badge-info">Max 12 MB</span>
</div>
<label class="file-upload-dropzone">
<span class="file-upload-icon" aria-hidden="true">
<i class="ph ph-cloud-arrow-up"></i>
</span>
<span class="file-upload-body">
<span class="file-upload-primary">Choose files</span>
<span class="file-upload-secondary">Images get thumbnails, other files show their type</span>
</span>
<input type="file" name="files" multiple data-file-upload-input>
</label>
<div class="file-upload-preview" data-file-upload-preview hidden></div>
<div class="file-upload-actions">
<button class="btn btn-secondary btn-small" type="reset">Reset</button>
<button class="btn btn-accent btn-small" type="submit">Upload</button>
</div>
</form>
</div></code></pre>
</div>
</section>
<section class="section docs-section" id="utilities">
<h2 class="section-title">Utilities</h2>
<p class="docs-section-description">Utilities дают предсказуемую систему отступов, размеров, раскладки и текстовых правок без создания новых компонентов. Spacing scale используется и в SCSS-переменных, и в utility-классах.</p>
<div class="block">
<h3 class="block-title">Spacing scale</h3>
<div class="table-wrapper">
<table class="table table-compact">
<caption class="table-caption">Spacing tokens</caption>
<thead class="table-head"><tr class="table-row"><th>Token</th><th>Value</th><th>Alias</th><th>Utility examples</th></tr></thead>
<tbody class="table-body">
<tr class="table-row"><td><code class="code">$space-0</code></td><td>0</td><td>-</td><td><code class="code">m-0</code> <code class="code">p-0</code> <code class="code">g-0</code></td></tr>
<tr class="table-row"><td><code class="code">$space-1</code></td><td>5px</td><td><code class="code">$space-xs</code></td><td><code class="code">mt-1</code> <code class="code">px-1</code></td></tr>
<tr class="table-row"><td><code class="code">$space-2</code></td><td>8px</td><td><code class="code">$space-sm</code></td><td><code class="code">mb-2</code> <code class="code">g-2</code></td></tr>
<tr class="table-row"><td><code class="code">$space-3</code></td><td>12px</td><td>-</td><td><code class="code">p-3</code> <code class="code">gy-3</code></td></tr>
<tr class="table-row"><td><code class="code">$space-4</code></td><td>15px</td><td><code class="code">$space-md</code></td><td><code class="code">mx-4</code> <code class="code">gx-4</code></td></tr>
<tr class="table-row"><td><code class="code">$space-5</code></td><td>18px</td><td>-</td><td><code class="code">pt-5</code> <code class="code">pb-5</code></td></tr>
<tr class="table-row"><td><code class="code">$space-6</code></td><td>22px</td><td><code class="code">$space-lg</code></td><td><code class="code">my-6</code> <code class="code">g-6</code></td></tr>
<tr class="table-row"><td><code class="code">$space-8</code></td><td>34px</td><td><code class="code">$space-xl</code></td><td><code class="code">mt-8</code> <code class="code">p-8</code></td></tr>
<tr class="table-row"><td><code class="code">$space-10</code></td><td>48px</td><td><code class="code">$space-xxl</code></td><td><code class="code">mb-10</code> <code class="code">py-10</code></td></tr>
<tr class="table-row"><td><code class="code">$space-12</code></td><td>80px</td><td>-</td><td><code class="code">mt-12</code> <code class="code">pb-12</code></td></tr>
</tbody>
</table>
</div>
</div>
<div class="block">
<h3 class="block-title">Utility groups</h3>
<dl class="description-list">
<div class="description-list-row"><dt class="description-list-term">Margin</dt><dd class="description-list-value"><code class="code">m-*</code> <code class="code">mt-*</code> <code class="code">mr-*</code> <code class="code">mb-*</code> <code class="code">ml-*</code> <code class="code">mx-*</code> <code class="code">my-*</code></dd></div>
<div class="description-list-row"><dt class="description-list-term">Padding</dt><dd class="description-list-value"><code class="code">p-*</code> <code class="code">pt-*</code> <code class="code">pr-*</code> <code class="code">pb-*</code> <code class="code">pl-*</code> <code class="code">px-*</code> <code class="code">py-*</code></dd></div>
<div class="description-list-row"><dt class="description-list-term">Gap</dt><dd class="description-list-value"><code class="code">g-*</code> <code class="code">gx-*</code> <code class="code">gy-*</code></dd></div>
<div class="description-list-row"><dt class="description-list-term">Layout</dt><dd class="description-list-value"><code class="code">row</code> <code class="code">column</code> <code class="code">f-grid</code> <code class="code">grid</code> <code class="code">grid-2</code> <code class="code">grid-3</code></dd></div>
<div class="description-list-row"><dt class="description-list-term">Alignment</dt><dd class="description-list-value"><code class="code">items-center</code> <code class="code">justify-between</code> <code class="code">justify-end</code></dd></div>
<div class="description-list-row"><dt class="description-list-term">Text</dt><dd class="description-list-value"><code class="code">fs-sm</code> <code class="code">text-center</code> <code class="code">text-uppercase</code> <code class="code">text-nowrap</code></dd></div>
</dl>
</div>
<div class="block">
<h3 class="block-title">Spacing preview</h3>
<div class="grid-3 g-4">
<div class="alert alert-secondary m-0">g-4</div>
<div class="alert alert-primary m-0 p-5">p-5</div>
<div class="alert alert-warning m-0 px-6 py-3">px-6 py-3</div>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Utilities HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="grid-2 g-4 items-center">
<div class="p-5">Panel</div>
<div class="px-6 py-3 text-right">Actions</div>
</div></code></pre>
</div>
</section>
<section class="section docs-section" id="editable-string">
<h2 class="section-title">Editable String</h2>
<p class="docs-section-description">Editable String превращает обычный контейнер с текстом в inline-редактор. Компонент возвращает DOM-элемент с API editableString.</p>
<div class="block">
<div class="editable-example fs-lg">Hello world</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Editable String HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="editable-example">Hello world</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Editable String JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">const editor = editableString(document.querySelector(".editable-example"));
editor.editableString.onChange(component => {
console.log(component.value);
});</code></pre>
</div>
</section>
<section class="section docs-section" id="navigation-overlays">
<h2 class="section-title">Navigation & Overlays</h2>
<p class="docs-section-description">Tabs переключают близкие представления, dropdown подходит для коротких action-menu, tooltip дает компактную подсказку, popover раскрывает небольшой контекстный блок.</p>
<div class="block">
<div class="tabs" role="tablist" aria-label="View mode">
<button class="tab tab-active" type="button" role="tab" aria-selected="true">Overview</button>
<button class="tab" type="button" role="tab" aria-selected="false">Activity</button>
<button class="tab" type="button" role="tab" aria-selected="false">Settings</button>
</div>
<div class="demo-actions">
<div class="dropdown">
<button class="btn btn-secondary with-icon" type="button" data-dropdown-toggle aria-expanded="false">
<i class="ph ph-dots-three-outline"></i>
Actions
</button>
<div class="dropdown-menu" role="menu">
<button class="dropdown-item" type="button" role="menuitem">
<i class="ph ph-pencil-simple"></i>
Edit
</button>
<button class="dropdown-item" type="button" role="menuitem">
<i class="ph ph-copy"></i>
Duplicate
</button>
<button class="dropdown-item dropdown-item-danger" type="button" role="menuitem">
<i class="ph ph-trash"></i>
Delete
</button>
</div>
</div>
<span class="tooltip">
<button class="btn btn-primary with-icon" type="button" data-tooltip-toggle>
<i class="ph ph-question"></i>
Help
</button>
<span class="tooltip-panel" role="tooltip">
Short contextual hint for compact controls.
</span>
</span>
<div class="popover">
<button class="btn btn-accent with-icon" type="button" data-popover-toggle aria-expanded="false">
<i class="ph ph-info"></i>
Details
</button>
<div class="popover-panel">
<h3 class="popover-title">Context</h3>
<p class="popover-text">
Use popover for short forms, metadata, previews, and low-risk contextual actions.
</p>
</div>
</div>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Tabs HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="tabs" role="tablist" aria-label="View mode">
<button class="tab tab-active" type="button" role="tab" aria-selected="true">Overview</button>
<button class="tab" type="button" role="tab" aria-selected="false">Activity</button>
<button class="tab" type="button" role="tab" aria-selected="false">Settings</button>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Dropdown HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="dropdown">
<button class="btn btn-secondary with-icon" type="button" data-dropdown-toggle aria-expanded="false">
<i class="ph ph-dots-three-outline"></i>
Actions
</button>
<div class="dropdown-menu" role="menu">
<button class="dropdown-item" type="button" role="menuitem">Edit</button>
<button class="dropdown-item" type="button" role="menuitem">Duplicate</button>
<button class="dropdown-item dropdown-item-danger" type="button" role="menuitem">Delete</button>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Tooltip HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><span class="tooltip">
<button class="btn btn-primary with-icon" type="button" data-tooltip-toggle>
<i class="ph ph-question"></i>
Help
</button>
<span class="tooltip-panel" role="tooltip">
Short contextual hint for compact controls.
</span>
</span></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Popover HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="popover">
<button class="btn btn-accent with-icon" type="button" data-popover-toggle aria-expanded="false">
<i class="ph ph-info"></i>
Details
</button>
<div class="popover-panel">
<h3 class="popover-title">Context</h3>
<p class="popover-text">Use popover for short forms, metadata, previews, and low-risk contextual actions.</p>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Overlays JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-js">Overlays.init();
// Available on the global namespace too:
GNexusUIKit.Overlays.closeAll();</code></pre>
</div>
</section>
<section class="section docs-section" id="navigation-shell">
<h2 class="section-title">Navigation Shell</h2>
<p class="docs-section-description">Navigation Shell объединяет верхнюю панель, кнопку меню, left drawer и footer. Компонент подходит для docs, dashboards и внутренних инструментов с длинной навигацией.</p>
<div class="block">
<div class="nav-shell-preview">
<header class="nav-topbar nav-shell-preview-topbar">
<button class="nav-topbar-toggle" type="button" aria-expanded="false">
<i class="ph ph-sidebar-simple"></i>
<span>Menu</span>
</button>
<div class="nav-topbar-brand">
<img src="/assets/imgs/gnexus-mark.svg" alt="" aria-hidden="true">
<span>Product Console</span>
</div>
<div class="nav-topbar-current">Overview</div>
</header>
<div class="nav-shell-preview-body">
<aside class="nav-drawer nav-shell-preview-drawer">
<header class="nav-drawer-header">
<div>
<div class="nav-drawer-title">Navi</div>
<div class="nav-drawer-subtitle">Workspace</div>
</div>
<button class="nav-drawer-close" type="button" aria-label="Close navigation">
<i class="ph ph-x"></i>
</button>
</header>
<nav class="nav-drawer-body">
<ul class="list list-nav">
<li class="list-item list-item-active">
<a class="list-action" href="#navigation-shell">
<span class="list-label"><i class="ph ph-house"></i> Overview</span>
</a>
</li>
<li class="list-item">
<a class="list-action" href="#navigation-shell">
<span class="list-label"><i class="ph ph-table"></i> Records</span>
</a>
</li>
<li class="list-item">
<a class="list-action" href="#navigation-shell">
<span class="list-label"><i class="ph ph-gear"></i> Settings</span>
</a>
</li>
</ul>
</nav>
<footer class="nav-drawer-footer">
<span>GNexus UI Kit v0.3</span>
<span>© GNexus</span>
</footer>
</aside>
<div class="nav-shell-preview-content">
<h3>Shell content</h3>
<p>Topbar stays visible. Drawer opens from the left and keeps its footer pinned.</p>
</div>
</div>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Navigation Shell HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><header class="nav-topbar">
<button class="nav-topbar-toggle" type="button" data-navigation-toggle
aria-controls="app-navigation" aria-expanded="false">
<i class="ph ph-sidebar-simple"></i>
<span>Menu</span>
</button>
<div class="nav-topbar-brand">
<img src="/assets/imgs/gnexus-mark.svg" alt="" aria-hidden="true">
<span>Product Console</span>
</div>
<div class="nav-topbar-current">Overview</div>
</header>
<div class="nav-drawer-backdrop" data-navigation-close></div>
<aside class="nav-drawer" id="app-navigation" data-navigation-drawer
aria-label="Main navigation" aria-hidden="true" inert>
<header class="nav-drawer-header">
<div>
<div class="nav-drawer-title">Navi</div>
<div class="nav-drawer-subtitle">Workspace</div>
</div>
<button class="nav-drawer-close" type="button" data-navigation-close aria-label="Close navigation">
<i class="ph ph-x"></i>
</button>
</header>
<nav class="nav-drawer-body">
<ul class="list list-nav">
<li class="list-item list-item-active">
<a class="list-action" href="/overview" data-navigation-link>
<span class="list-label"><i class="ph ph-house"></i> Overview</span>
</a>
</li>
</ul>
</nav>
<footer class="nav-drawer-footer">
<span>Version 0.2</span>
<span>© GNexus</span>
</footer>
</aside></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Navigation Shell JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-js">NavigationShell.init();
// Available on the global namespace too:
GNexusUIKit.NavigationShell.init();</code></pre>
</div>
<div class="block mt-6">
<h3 class="block-title">Navigation Shell with Profile</h3>
<div class="nav-shell-preview">
<header class="nav-topbar nav-shell-preview-topbar">
<button class="nav-topbar-toggle" type="button" aria-expanded="false">
<i class="ph ph-sidebar-simple"></i>
<span>Menu</span>
</button>
<div class="nav-topbar-brand">
<img src="/assets/imgs/gnexus-mark.svg" alt="" aria-hidden="true">
<span>Product Console</span>
</div>
<div class="nav-topbar-current">Overview</div>
</header>
<div class="nav-shell-preview-body">
<aside class="nav-drawer nav-shell-preview-drawer">
<header class="nav-drawer-header">
<div>
<div class="nav-drawer-title">Navi</div>
<div class="nav-drawer-subtitle">Workspace</div>
</div>
<button class="nav-drawer-close" type="button" aria-label="Close navigation">
<i class="ph ph-x"></i>
</button>
</header>
<nav class="nav-drawer-body">
<ul class="list list-nav">
<li class="list-item list-item-active">
<a class="list-action" href="#navigation-shell">
<span class="list-label"><i class="ph ph-house"></i> Overview</span>
</a>
</li>
<li class="list-item">
<a class="list-action" href="#navigation-shell">
<span class="list-label"><i class="ph ph-table"></i> Records</span>
</a>
</li>
<li class="list-item">
<a class="list-action" href="#navigation-shell">
<span class="list-label"><i class="ph ph-gear"></i> Settings</span>
</a>
</li>
</ul>
</nav>
<footer class="nav-drawer-footer">
<a class="profile-identity" href="#" target="_blank" rel="noopener noreferrer">
<span class="identity">
<span class="avatar avatar-primary avatar-sm is-online">
<img src="https://auth.gnexus.space/storage/avatars/1/181513cf-3e1b-4b72-bc9d-a1825c736560/original.jpg" alt="">
</span>
<span class="identity-content">
<span class="identity-title">Eugene Sukhodolskiy</span>
<span class="identity-meta">goldmikki@gmail.com</span>
</span>
</span>
</a>
<button class="btn-icon" type="button" aria-label="Edit profile"><i class="ph ph-pencil-simple" aria-hidden="true"></i></button>
<button class="btn-icon" type="button" aria-label="Logout"><i class="ph ph-sign-out" aria-hidden="true"></i></button>
</footer>
</aside>
<div class="nav-shell-preview-content">
<h3>Shell content</h3>
<p>Topbar stays visible. Drawer opens from the left and keeps its footer pinned.</p>
</div>
</div>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Navigation Shell Profile Footer HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><footer class="nav-drawer-footer">
<a class="profile-identity" href="#" target="_blank" rel="noopener noreferrer">
<span class="identity">
<span class="avatar avatar-primary avatar-sm is-online">
<img src="..." alt="">
</span>
<span class="identity-content">
<span class="identity-title">Name</span>
<span class="identity-meta">email@example.com</span>
</span>
</span>
</a>
<button class="btn-icon" aria-label="Edit profile">
<i class="ph ph-pencil-simple"></i>
</button>
<button class="btn-icon" aria-label="Logout">
<i class="ph ph-sign-out"></i>
</button>
</footer></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Vue: Navigation Shell Profile Footer</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><GnNavigationShell :items="navItems" brand="Product Console" ...>
<template #footer>
<a class="profile-identity" href="/profile" target="_blank">
<GnIdentity
title="Eugene Sukhodolskiy"
meta="goldmikki@gmail.com"
:avatar="{ src: '...', status: 'online', size: 'sm' }"
/>
</a>
<GnIconButton icon="ph-pencil-simple" label="Edit profile" />
<GnIconButton icon="ph-sign-out" label="Logout" />
</template>
</GnNavigationShell></code></pre>
</div>
</section>
<section class="section docs-section" id="lists">
<h2 class="section-title">Lists</h2>
<p class="docs-section-description">Списки покрывают обычные перечни, навигацию, definition list и строки с действиями. Для интерактивных пунктов используй `.list-nav`, `.list-action`, `.list-label` и `.list-meta`.</p>
<div class="block">
<h3 class="block-title">Unordered list</h3>
<ul class="list">
<li class="list-item">Dashboard</li>
<li class="list-item">Projects</li>
<li class="list-item">Reports</li>
<li class="list-item">Automations</li>
<li class="list-item">Settings</li>
</ul>
</div>
<div class="block">
<h3 class="block-title">Ordered list</h3>
<ol class="list list-ordered">
<li class="list-item">Create workspace</li>
<li class="list-item">Invite team</li>
<li class="list-item">Configure permissions</li>
<li class="list-item">Verify status</li>
</ol>
</div>
<div class="block">
<h3 class="block-title">List with icons</h3>
<ul class="list with-icons">
<li class="list-item"><i class="ph ph-bathtub"></i> Bathroom</li>
<li class="list-item"><i class="ph ph-toilet"></i> Toilet</li>
<li class="list-item"><i class="ph ph-planet"></i> Workspace</li>
</ul>
</div>
<div class="block">
<h3 class="block-title">Definition list</h3>
<dl class="list list-definition">
<div class="list-row">
<dt class="list-term">Item</dt>
<dd class="list-desc">Базовая сущность интерфейса</dd>
</div>
<div class="list-row">
<dt class="list-term">Group</dt>
<dd class="list-desc">Логическая группа элементов</dd>
</div>
<div class="list-row">
<dt class="list-term">Flow</dt>
<dd class="list-desc">Набор действий, выполняемых последовательно</dd>
</div>
</dl>
</div>
<div class="block">
<h3 class="block-title">Navigation / interactive list</h3>
<ul class="list list-nav">
<li class="list-item list-item-active">
<button class="list-action" type="button">
<span class="list-label">Overview</span>
</button>
</li>
<li class="list-item">
<button class="list-action" type="button">
<span class="list-label"><i class="ph ph-stack"></i> Projects</span>
<span class="list-meta">12</span>
</button>
</li>
<li class="list-item">
<button class="list-action" type="button">
<span class="list-label">Logs</span>
</button>
</li>
<li class="list-item list-item-disabled">
<button class="list-action" type="button" disabled>
<span class="list-label">Advanced</span>
</button>
</li>
</ul>
</div>
<div class="block">
<h3 class="block-title">List with actions</h3>
<ul class="list list-actions">
<li class="list-item">
<div class="list-content">
<div class="list-title">Release Plan</div>
<div class="list-subtitle">
<span class="text-color-success">•</span>
192.168.2.21
</div>
</div>
<div class="list-controls">
<button class="btn btn-small btn-secondary" type="button">Open</button>
<button class="btn btn-small btn-accent" type="button">Toggle</button>
</div>
</li>
<li class="list-item">
<div class="list-content">
<div class="list-title">Analytics Sync</div>
<div class="list-subtitle">
<span class="text-color-success">•</span>
192.168.2.34
</div>
</div>
<div class="list-controls">
<button class="btn btn-small btn-secondary" type="button">Open</button>
<button class="btn btn-small btn-danger with-icon" type="button">
<i class="ph ph-arrow-clockwise"></i>
Restart
</button>
</div>
</li>
<li class="list-item list-item-muted">
<div class="list-content">
<div class="list-title">Archive Job</div>
<div class="list-subtitle">
<span class="text-color-warning">•</span> Offline
</div>
</div>
<div class="list-controls">
<button class="btn btn-small btn-secondary" type="button" disabled>Open</button>
<button class="btn btn-small btn-accent" type="button" disabled>Toggle</button>
</div>
</li>
</ul>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Navigation List HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><ul class="list list-nav">
<li class="list-item list-item-active">
<button class="list-action" type="button">
<span class="list-label">
<i class="ph ph-lightbulb"></i>
Projects
</span>
<span class="list-meta">12</span>
</button>
</li>
</ul></code></pre>
</div>
</section>
<section class="section docs-section" id="badges">
<h2 class="section-title">Badges & Status</h2>
<p class="docs-section-description">Badges используются для коротких статусов, счётчиков и меток состояния. Цветовой модификатор выбирается по смыслу: success, warning, error, info и так далее.</p>
<div class="block">
<GnBadge variant="primary">Primary</GnBadge>
<GnBadge variant="secondary">Secondary</GnBadge>
<GnBadge variant="success">Success</GnBadge>
<GnBadge variant="warning">Warning</GnBadge>
<GnBadge variant="error">Error</GnBadge>
<GnBadge variant="info">Info</GnBadge>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Badges HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><span class="badge badge-success">Online</span>
<span class="badge badge-warning">Degraded</span>
<span class="badge badge-error">Offline</span>
<span class="badge badge-info">Info</span></code></pre>
</div>
</section>
<section class="section docs-section" id="alerts">
<h2 class="section-title">Alerts</h2>
<p class="docs-section-description">Alerts подходят для заметных системных сообщений внутри контента. Используй alert и один цветовой модификатор.</p>
<GnAlert variant="primary">This is a primary alert—check it out!</GnAlert>
<GnAlert variant="success">This is a success alert—check it out!</GnAlert>
<GnAlert variant="secondary">This is a secondary alert—check it out!</GnAlert>
<GnAlert variant="info">This is a info alert—check it out!</GnAlert>
<GnAlert variant="warning">This is a warning alert—check it out!</GnAlert>
<GnAlert variant="danger">This is a error/danger alert—check it out!</GnAlert>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Alerts HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="alert alert-primary">Primary message</div>
<div class="alert alert-success">Operation completed</div>
<div class="alert alert-warning">Check settings</div>
<div class="alert alert-error">Action failed</div></code></pre>
</div>
</section>
<section class="section docs-section" id="tables">
<h2 class="section-title">Tables</h2>
<p class="docs-section-description">Таблицы используют базовый класс .table, semantic table markup и дополнительные элементы: .table-caption, .table-head, .table-body, .table-foot.</p>
<div class="block">
<h3 class="block-title">Basic table</h3>
<table class="table">
<caption class="table-caption">Projects list</caption>
<thead class="table-head">
<tr class="table-row">
<th scope="col">Project</th>
<th scope="col">Status</th>
<th scope="col">Owner</th>
<th scope="col">Updated</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row">
<td>Website Redesign</td>
<td><span class="badge badge-success">Online</span></td>
<td><code class="code">@design</code></td>
<td>2 min ago</td>
<td>
<button class="btn btn-secondary btn-small" type="button">Open</button>
<button class="btn btn-accent btn-small" type="button">Toggle</button>
</td>
</tr>
<tr class="table-row">
<td>Billing API</td>
<td><span class="badge badge-warning">Degraded</span></td>
<td><code class="code">@backend</code></td>
<td>1 hour ago</td>
<td>
<button class="btn btn-secondary btn-small" type="button">Open</button>
<button class="btn btn-danger btn-small" type="button">Restart</button>
</td>
</tr>
<tr class="table-row table-row-muted">
<td>Archive Import</td>
<td><span class="badge badge-error">Offline</span></td>
<td><code class="code">@ops</code></td>
<td>Yesterday</td>
<td>
<button class="btn btn-secondary btn-small" type="button" disabled>Open</button>
<button class="btn btn-accent btn-small" type="button" disabled>Toggle</button>
</td>
</tr>
</tbody>
<tfoot class="table-foot">
<tr class="table-row">
<td colspan="5"><span class="table-meta">Total: 3 projects</span></td>
</tr>
</tfoot>
</table>
</div>
<div class="block mt-6">
<h3 class="block-title">Compact table</h3>
<GnTable :columns="[{ key: 'job', label: 'Job' }, { key: 'state', label: 'State' }, { key: 'runtime', label: 'Runtime' }, { key: 'runId', label: 'Run ID' }, { key: 'actions', label: 'Actions' }]" :rows="[{ job: 'Sync catalog', state: 'Done', runtime: '18s', runId: 'run_1048' }, { job: 'Import archive', state: 'Running', runtime: '2m 14s', runId: 'run_1047' }, { job: 'Export report', state: 'Failed', runtime: '4s', runId: 'run_1046' }]" caption="Recent jobs" class="table-compact">
<template #cell-state="{ value }"><GnBadge :variant="value === 'Done' ? 'success' : value === 'Running' ? 'warning' : 'error'">{{ value }}</GnBadge></template>
<template #cell-runId="{ value }"><code class="code">{{ value }}</code></template>
<template #cell-actions="{ row }">
<GnButton variant="secondary" size="sm">{{ row.state === 'Running' ? 'Stop' : 'Logs' }}</GnButton>
<GnButton :variant="row.state === 'Failed' ? 'accent' : 'danger'" size="sm">{{ row.state === 'Failed' ? 'Retry' : 'Stop' }}</GnButton>
</template>
</GnTable>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Tables HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><table class="table">
<caption class="table-caption">Projects list</caption>
<thead class="table-head">
<tr class="table-row">
<th scope="col">Project</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row">
<td>Website Redesign</td>
<td><span class="badge badge-success">Online</span></td>
</tr>
</tbody>
</table></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Compact Table HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><table class="table table-compact">
<caption class="table-caption">Recent jobs</caption>
<thead class="table-head">
<tr class="table-row">
<th scope="col">Job</th>
<th scope="col">State</th>
<th scope="col">Run ID</th>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row">
<td>Sync catalog</td>
<td><span class="badge badge-success">Done</span></td>
<td class="table-cell-mono">run_1048</td>
</tr>
</tbody>
</table></code></pre>
</div>
</section>
<section class="section docs-section" id="data-patterns">
<h2 class="section-title">Data Patterns</h2>
<p class="docs-section-description">Toolbar, search field, pagination, empty state и skeleton закрывают типовые состояния таблиц, списков и страниц с данными.</p>
<div class="block">
<div class="toolbar">
<div class="toolbar-group">
<div>
<h3 class="toolbar-title">Projects</h3>
<span class="toolbar-meta">24 items</span>
</div>
</div>
<div class="toolbar-group">
<div class="input-group input-group-compact search-field">
<span class="input-group-addon">
<i class="ph ph-magnifying-glass"></i>
</span>
<input class="input-group-input" type="search" value="release" placeholder="Search">
<button class="input-group-action" type="button" data-input-clear aria-label="Clear search">
<i class="ph ph-x"></i>
</button>
</div>
<button class="btn btn-primary btn-small with-icon" type="button">
<i class="ph ph-funnel"></i>
Filter
</button>
<button class="btn btn-accent btn-small with-icon" type="button">
<i class="ph ph-plus"></i>
Create
</button>
</div>
</div>
</div>
<div class="block">
<div class="input-group">
<span class="input-group-addon">https://</span>
<input class="input-group-input" type="text" value="example.gnexus.local" placeholder="Domain">
<button class="input-group-action" type="button">Save</button>
</div>
</div>
<div class="block">
<nav class="pagination" aria-label="Pagination">
<button class="pagination-item" type="button" disabled>
<i class="ph ph-arrow-left"></i>
</button>
<button class="pagination-item pagination-item-active" type="button" aria-current="page">1</button>
<button class="pagination-item" type="button">2</button>
<button class="pagination-item" type="button">3</button>
<span class="pagination-ellipsis">...</span>
<button class="pagination-item" type="button">12</button>
<button class="pagination-item" type="button">
<i class="ph ph-arrow-right"></i>
</button>
</nav>
</div>
<div class="block">
<GnEmptyState title="No results" text="Nothing matched the current filters. Reset the query or create a new item.">
<template #actions>
<GnButton variant="secondary" size="sm">Reset</GnButton>
<GnButton variant="accent" size="sm">Create</GnButton>
</template>
</GnEmptyState>
</div>
<div class="block">
<div class="skeleton-stack" aria-label="Loading preview">
<span class="skeleton skeleton-title"></span>
<span class="skeleton skeleton-line"></span>
<span class="skeleton skeleton-line" style="width: 84%"></span>
<span class="skeleton skeleton-line" style="width: 68%"></span>
<span class="skeleton skeleton-block"></span>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Toolbar HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="toolbar">
<div class="toolbar-group">
<div>
<h3 class="toolbar-title">Projects</h3>
<span class="toolbar-meta">24 items</span>
</div>
</div>
<div class="toolbar-group">
<div class="input-group input-group-compact search-field">
<span class="input-group-addon"><i class="ph ph-magnifying-glass"></i></span>
<input class="input-group-input" type="search" placeholder="Search">
<button class="input-group-action" type="button" data-input-clear aria-label="Clear search">
<i class="ph ph-x"></i>
</button>
</div>
<button class="btn btn-accent btn-small">Create</button>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Input Group HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="input-group">
<span class="input-group-addon">https://</span>
<input class="input-group-input" type="text" placeholder="Domain">
<button class="input-group-action" type="button">Save</button>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Pagination HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><nav class="pagination" aria-label="Pagination">
<button class="pagination-item" type="button" disabled>Prev</button>
<button class="pagination-item pagination-item-active" type="button" aria-current="page">1</button>
<button class="pagination-item" type="button">2</button>
<span class="pagination-ellipsis">...</span>
<button class="pagination-item" type="button">12</button>
<button class="pagination-item" type="button">Next</button>
</nav></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Empty State HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="empty-state">
<div class="empty-state-icon"><i class="ph ph-package"></i></div>
<h3 class="empty-state-title">No results</h3>
<p class="empty-state-text">Nothing matched the current filters.</p>
<div class="empty-state-actions">
<button class="btn btn-secondary btn-small">Reset</button>
<button class="btn btn-accent btn-small">Create</button>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Skeleton HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="skeleton-stack" aria-label="Loading preview">
<span class="skeleton skeleton-title"></span>
<span class="skeleton skeleton-line"></span>
<span class="skeleton skeleton-line" style="width: 84%"></span>
<span class="skeleton skeleton-block"></span>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Input Patterns JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-js">InputPatterns.init();
// Available on the global namespace too:
GNexusUIKit.InputPatterns.init();</code></pre>
</div>
</section>
<section class="section docs-section" id="page-header">
<h2 class="section-title">Page Header</h2>
<p class="docs-section-description">Page Header собирает заголовок экрана, короткое описание, статусные метки и основные действия.</p>
<div class="block">
<header class="page-header">
<div class="page-header-content">
<span class="page-header-kicker">Workspace</span>
<h3 class="page-header-title">Projects overview</h3>
<p class="page-header-subtitle">
Track active work, review critical states, and open the next action without leaving the page.
</p>
<div class="page-header-meta">
<span class="badge badge-success">Healthy</span>
<span>Updated 2 min ago</span>
</div>
</div>
<div class="page-header-actions">
<button class="btn btn-secondary btn-small" type="button">Export</button>
<button class="btn btn-accent btn-small with-icon" type="button">
<i class="ph ph-plus"></i>
Create
</button>
</div>
</header>
</div>
<div class="block">
<header class="page-header page-header-compact page-header-accent">
<div class="page-header-content">
<h3 class="page-header-title">Billing settings</h3>
<div class="page-header-meta">
<span class="badge badge-warning">Pending</span>
<span>3 changes waiting</span>
</div>
</div>
<div class="page-header-actions">
<button class="btn btn-primary btn-small" type="button">Review</button>
<button class="btn btn-danger btn-small" type="button">Discard</button>
</div>
</header>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Page Header HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><header class="page-header">
<div class="page-header-content">
<span class="page-header-kicker">Workspace</span>
<h1 class="page-header-title">Projects overview</h1>
<p class="page-header-subtitle">
Track active work and open the next action without leaving the page.
</p>
<div class="page-header-meta">
<span class="badge badge-success">Healthy</span>
<span>Updated 2 min ago</span>
</div>
</div>
<div class="page-header-actions">
<button class="btn btn-secondary btn-small" type="button">Export</button>
<button class="btn btn-accent btn-small" type="button">Create</button>
</div>
</header></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Compact Header HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><header class="page-header page-header-compact page-header-accent">
<div class="page-header-content">
<h2 class="page-header-title">Billing settings</h2>
<div class="page-header-meta">
<span class="badge badge-warning">Pending</span>
<span>3 changes waiting</span>
</div>
</div>
<div class="page-header-actions">
<button class="btn btn-primary btn-small" type="button">Review</button>
<button class="btn btn-danger btn-small" type="button">Discard</button>
</div>
</header></code></pre>
</div>
</section>
<section class="section docs-section" id="description-list">
<h2 class="section-title">Key-Value</h2>
<p class="docs-section-description">Description List подходит для read-only деталей сущности: ID, владельцы, статусы, даты и короткие metadata values.</p>
<div class="block">
<GnDescriptionList :items="details">
<template #status="{ item }">
<span class="badge badge-success">Online</span>
<span class="description-list-value-muted">All checks passed</span>
</template>
<template #owner="{ item }">
<code class="code">@design</code>
</template>
</GnDescriptionList>
</div>
<div class="block">
<dl class="description-list description-list-compact">
<div class="description-list-row"><dt class="description-list-term">Run ID</dt><dd class="description-list-value"><code class="code">run_1048</code></dd></div>
<div class="description-list-row"><dt class="description-list-term">Runtime</dt><dd class="description-list-value">18s</dd></div>
<div class="description-list-row"><dt class="description-list-term">Result</dt><dd class="description-list-value"><span class="badge badge-secondary">Queued</span></dd></div>
</dl>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Description List HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><dl class="description-list">
<div class="description-list-row">
<dt class="description-list-term">Project</dt>
<dd class="description-list-value">Website Redesign</dd>
</div>
<div class="description-list-row">
<dt class="description-list-term">Status</dt>
<dd class="description-list-value">
<span class="badge badge-success">Online</span>
<span class="description-list-value-muted">All checks passed</span>
</dd>
</div>
</dl></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Compact List HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><dl class="description-list description-list-compact">
<div class="description-list-row">
<dt class="description-list-term">Run ID</dt>
<dd class="description-list-value"><code class="code">run_1048</code></dd>
</div>
<div class="description-list-row">
<dt class="description-list-term">Runtime</dt>
<dd class="description-list-value">18s</dd>
</div>
</dl></code></pre>
</div>
</section>
<section class="section docs-section" id="progress">
<h2 class="section-title">Progress</h2>
<p class="docs-section-description">Progress закрывает загрузку, usage meters и staged progress для операций с понятным состоянием выполнения.</p>
<div class="block">
<h3 class="block-title">Bars</h3>
<GnProgress label="Build" :value="64" />
</div>
<div class="block">
<GnProgress label="Sync" :value="42" variant="warning" animated />
</div>
<div class="block">
<GnUsageMeter title="Storage" :value="78" meta="312 GB used from 400 GB limit." />
</div>
<div class="block">
<GnProgressStages :items="stages" />
</div>
<div class="block">
<div class="circle-loader" aria-label="Loading"><i class="ph ph-spinner"></i><span>Loading state</span></div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Progress Bar HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="progress" role="progressbar" aria-label="Build progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="64" style="--progress-value: 64%">
<div class="progress-header">
<span>Build</span>
<span class="progress-value">64%</span>
</div>
<div class="progress-track">
<span class="progress-bar"></span>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Usage Meter HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="usage-meter">
<h3 class="usage-meter-title">
Storage
<span class="usage-meter-value">78%</span>
</h3>
<div class="progress progress-success" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="78" style="--progress-value: 78%">
<div class="progress-track">
<span class="progress-bar"></span>
</div>
</div>
<p class="usage-meter-meta">312 GB used from 400 GB limit.</p>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Staged Progress HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="progress-stages" aria-label="Deploy stages">
<span class="progress-stage progress-stage-complete">Queued</span>
<span class="progress-stage progress-stage-complete">Build</span>
<span class="progress-stage progress-stage-current">Deploy</span>
<span class="progress-stage">Verify</span>
</div></code></pre>
</div>
</section>
<section class="section docs-section" id="steps">
<h2 class="section-title">Steps</h2>
<p class="docs-section-description">Steps описывает wizard-flow, onboarding и последовательные процессы с текущим, завершенным и недоступным шагом.</p>
<div class="block">
<GnSteps :items="steps" />
</div>
<div class="block">
<GnSteps :items="stepsVertical" vertical />
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Steps HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><ol class="steps">
<li class="step step-complete">
<span class="step-marker"><i class="ph ph-check"></i></span>
<h3 class="step-title">Account</h3>
<p class="step-text">Basic profile data is ready.</p>
</li>
<li class="step step-current" aria-current="step">
<span class="step-marker">2</span>
<h3 class="step-title">Confirm</h3>
<p class="step-text">Review settings before launch.</p>
</li>
<li class="step step-disabled">
<span class="step-marker">3</span>
<h3 class="step-title">Launch</h3>
<p class="step-text">Available after confirmation.</p>
</li>
</ol></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Vertical Steps HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><ol class="steps steps-vertical">
<li class="step step-complete">
<span class="step-marker"><i class="ph ph-check"></i></span>
<h3 class="step-title">Queued</h3>
<p class="step-text">Job accepted and waiting for worker slot.</p>
</li>
<li class="step step-current" aria-current="step">
<span class="step-marker">2</span>
<h3 class="step-title">Running</h3>
<p class="step-text">Current task is processing input data.</p>
</li>
</ol></code></pre>
</div>
</section>
<section class="section docs-section" id="chips">
<h2 class="section-title">Chips</h2>
<p class="docs-section-description">Chips используются для фильтров, коротких labels, selectable states и removable tokens.</p>
<div class="block">
<h3 class="block-title">Static chips</h3>
<GnChipGroup>
<GnChip variant="primary">Primary</GnChip>
<GnChip variant="secondary">Secondary</GnChip>
<GnChip variant="success">Success</GnChip>
<GnChip variant="warning">Warning</GnChip>
<GnChip variant="danger">Error</GnChip>
<GnChip variant="secondary" icon="ph-funnel">Filtered</GnChip>
</GnChipGroup>
</div>
<div class="block">
<h3 class="block-title">Selectable chips</h3>
<GnChipGroup>
<GnChip selected>Active</GnChip>
<GnChip>Queued</GnChip>
<GnChip>Failed</GnChip>
<GnChip disabled>Archived</GnChip>
</GnChipGroup>
</div>
<div class="block">
<h3 class="block-title">Removable chips</h3>
<GnChipGroup>
<GnChip removable>Frontend</GnChip>
<GnChip variant="success" removable>Design</GnChip>
<GnChip variant="warning" removable>Review</GnChip>
</GnChipGroup>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Static Chips HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="chip-group">
<span class="chip chip-primary">Primary</span>
<span class="chip chip-secondary">Secondary</span>
<span class="chip chip-success">Success</span>
<span class="chip">
<i class="ph ph-funnel"></i>
Filtered
</span>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Selectable Chips HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="chip-group" aria-label="Filter chips">
<button class="chip chip-selected" type="button" aria-pressed="true">Active</button>
<button class="chip" type="button" aria-pressed="false">Queued</button>
<button class="chip" type="button" aria-pressed="false">Failed</button>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Removable Chips HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><span class="chip">
Frontend
<button class="chip-remove" type="button" aria-label="Remove Frontend">
<i class="ph ph-x"></i>
</button>
</span></code></pre>
</div>
</section>
<section class="section docs-section" id="avatar">
<h2 class="section-title">Avatar</h2>
<p class="docs-section-description">Avatar и Identity показывают пользователя, команду, сервис или объект с initials, icon, image и status marker.</p>
<div class="block">
<h3 class="block-title">Avatar variants</h3>
<div class="chip-group">
<GnAvatar initials="AV" size="sm" />
<GnAvatar initials="GN" />
<GnAvatar initials="UI" variant="secondary" size="lg" />
<GnAvatar icon="ph-user" outline />
<GnAvatar icon="ph-check" variant="success" status="online" />
<GnAvatar src="/assets/imgs/gnexus-mark.svg" />
</div>
</div>
<div class="block">
<h3 class="block-title">Identity row</h3>
<GnIdentity title="Alex Kim" meta="Product Designer" :avatar="{ initials: 'AK', variant: 'secondary', status: 'online' }" />
</div>
<div class="block">
<h3 class="block-title">Avatar stack</h3>
<GnAvatarStack :items="[{ initials: 'AK', size: 'sm' }, { initials: 'JS', size: 'sm', variant: 'secondary' }, { initials: 'MR', size: 'sm', variant: 'warning' }]" count="4" />
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Avatar HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><span class="avatar avatar-secondary is-online">
AK
<span class="avatar-status"></span>
</span>
<span class="avatar avatar-outline">
<i class="ph ph-user"></i>
</span>
<span class="avatar">
<img src="/assets/imgs/gnexus-mark.svg" alt="GNexus mark">
</span></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Identity HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="identity">
<span class="avatar avatar-secondary is-online">
AK
<span class="avatar-status"></span>
</span>
<span class="identity-content">
<span class="identity-title">Alex Kim</span>
<span class="identity-meta">Product Designer</span>
</span>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Avatar Stack HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="avatar-stack" aria-label="Assigned users">
<span class="avatar avatar-sm">AK</span>
<span class="avatar avatar-sm avatar-secondary">JS</span>
<span class="avatar avatar-sm avatar-warning">MR</span>
<span class="avatar-stack-count">+4</span>
</div></code></pre>
</div>
</section>
<section class="section docs-section" id="timeline">
<h2 class="section-title">Timeline</h2>
<p class="docs-section-description">Timeline и Activity Log показывают историю событий, audit trail, job updates и системные изменения.</p>
<div class="block">
<ol class="timeline">
<li class="timeline-item timeline-item-success">
<span class="timeline-marker"><i class="ph ph-check-circle"></i></span>
<div class="timeline-content">
<article class="timeline-card">
<div class="timeline-header">
<h3 class="timeline-title">Build completed</h3>
<time class="timeline-time" datetime="2026-04-11T22:24:00">22:24</time>
</div>
<p class="timeline-text">Production bundle finished without warnings.</p>
<div class="timeline-meta">
<span class="chip chip-success">Done</span>
<span class="chip">CI</span>
</div>
</article>
</div>
</li>
<li class="timeline-item timeline-item-warning">
<span class="timeline-marker"><i class="ph ph-warning"></i></span>
<div class="timeline-content">
<article class="timeline-card">
<div class="timeline-header">
<h3 class="timeline-title">Review requested</h3>
<time class="timeline-time" datetime="2026-04-11T22:18:00">22:18</time>
</div>
<p class="timeline-text">Design tokens changed and need one visual pass before release.</p>
<div class="timeline-meta">
<span class="chip chip-warning">Review</span>
</div>
</article>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><i class="ph ph-git-commit"></i></span>
<div class="timeline-content">
<article class="timeline-card">
<div class="timeline-header">
<h3 class="timeline-title">Commit pushed</h3>
<time class="timeline-time" datetime="2026-04-11T22:10:00">22:10</time>
</div>
<p class="timeline-text">Component documentation and demo examples were updated.</p>
</article>
</div>
</li>
</ol>
</div>
<div class="block">
<div class="activity-log">
<div class="activity-log-row">
<time class="activity-log-time" datetime="2026-04-11T22:24:00">22:24</time>
<span class="activity-log-title">Build completed</span>
<span class="badge badge-success">Done</span>
</div>
<div class="activity-log-row">
<time class="activity-log-time" datetime="2026-04-11T22:18:00">22:18</time>
<span class="activity-log-title">Review requested</span>
<span class="badge badge-warning">Pending</span>
</div>
<div class="activity-log-row">
<time class="activity-log-time" datetime="2026-04-11T22:10:00">22:10</time>
<span class="activity-log-title">Commit pushed</span>
<span class="badge badge-secondary">Info</span>
</div>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Timeline HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><ol class="timeline">
<li class="timeline-item timeline-item-success">
<span class="timeline-marker"><i class="ph ph-check-circle"></i></span>
<div class="timeline-content">
<article class="timeline-card">
<div class="timeline-header">
<h3 class="timeline-title">Build completed</h3>
<time class="timeline-time" datetime="2026-04-11T22:24:00">22:24</time>
</div>
<p class="timeline-text">Production bundle finished without warnings.</p>
</article>
</div>
</li>
</ol></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Activity Log HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="activity-log">
<div class="activity-log-row">
<time class="activity-log-time" datetime="2026-04-11T22:24:00">22:24</time>
<span class="activity-log-title">Build completed</span>
<span class="badge badge-success">Done</span>
</div>
</div></code></pre>
</div>
</section>
<section class="section docs-section" id="accordion">
<h2 class="section-title">Accordion</h2>
<p class="docs-section-description">Accordion и Disclosure используют native <code class="code"><details></code> / <code class="code"><summary></code>, а раскрытие анимируется через <code class="code">Accordion.init()</code>.</p>
<div class="block">
<div class="accordion">
<details class="accordion-item" open>
<summary class="accordion-summary">
<span class="accordion-summary-content">
<i class="ph ph-list-checks"></i>
Release checklist
</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Check component states, copy examples, keyboard focus, and responsive layout before release.</p>
</div>
</details>
<details class="accordion-item">
<summary class="accordion-summary">
<span class="accordion-summary-content">
<i class="ph ph-article"></i>
Documentation notes
</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Keep component copy short and include code examples for the smallest useful markup.</p>
</div>
</details>
<details class="accordion-item">
<summary class="accordion-summary">
<span class="accordion-summary-content">
<i class="ph ph-activity"></i>
Runtime behavior
</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Use native disclosure behavior when the component does not need custom animation or async content.</p>
</div>
</details>
</div>
</div>
<div class="block">
<details class="disclosure">
<summary class="accordion-summary">
<span class="accordion-summary-content">Compact disclosure</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Use this variant for a single expandable group inside forms or metadata blocks.</p>
</div>
</details>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Accordion HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="accordion">
<details class="accordion-item" open>
<summary class="accordion-summary">
<span class="accordion-summary-content">
<i class="ph ph-list-checks"></i>
Release checklist
</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Check component states, copy examples, keyboard focus, and responsive layout.</p>
</div>
</details>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Disclosure HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><details class="disclosure">
<summary class="accordion-summary">
<span class="accordion-summary-content">Compact disclosure</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Use this variant for a single expandable group.</p>
</div>
</details></code></pre>
</div>
</section>
<section class="section docs-section" id="tabs">
<h2 class="section-title">Tabs</h2>
<p class="docs-section-description">Tabs переключают связанные панели внутри одного контекста. Компонент поддерживает click, keyboard navigation и ARIA state через <code class="code">Tabs.init()</code>.</p>
<div class="block">
<GnTabs v-model="tab" :items="tabs">
<template #overview><p>Overview keeps the primary status, totals, and next actions visible without leaving the current screen.</p></template>
<template #activity><p>Activity contains the latest events, audit notes, and handoff messages for the same record.</p></template>
<template #settings><p>Settings groups secondary options that affect this context but do not need full page navigation.</p></template>
</GnTabs>
</div>
<div class="block">
<GnTabs v-model="tabCompact" :items="tabsCompact" compact>
<template #api><p>Use compact tabs in dense panels, settings pages, and narrow metadata blocks.</p></template>
<template #webhooks><p>Disabled tabs can stay visible when a feature is unavailable for the current object.</p></template>
<template #billing><p>Billing content is disabled in this example.</p></template>
</GnTabs>
</div>
<div class="block">
<GnTabs v-model="tabVertical" :items="tabsVertical" vertical>
<template #profile><p>Vertical tabs work well when labels are longer or the panel needs a stable left rail.</p></template>
<template #access><p>Use them for account details, admin records, or focused configuration groups.</p></template>
<template #notes><p>On smaller screens the tab rail becomes a horizontal scrollable list.</p></template>
</GnTabs>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Tabs HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="tabs" data-tabs>
<div class="tabs-list" aria-label="Project sections">
<button class="tab tab-active" type="button" aria-controls="panel-overview">Overview</button>
<button class="tab" type="button" aria-controls="panel-activity">Activity</button>
</div>
<div class="tabs-panels">
<div class="tab-panel tab-panel-active" id="panel-overview">Overview content</div>
<div class="tab-panel" id="panel-activity">Activity content</div>
</div>
</div></code></pre>
</div>
</section>
<section class="section docs-section" id="drawer">
<h2 class="section-title">Drawer</h2>
<p class="docs-section-description">Drawer подходит для контекстных деталей, quick edit и длинных вторичных сценариев без ухода со страницы. По API он близок к Modal, но панель закреплена у края экрана.</p>
<div class="block">
<h3 class="block-title">Examples</h3>
<div class="drawer-preview">
<div class="drawer-preview-content">
<p class="text">
Используй Drawer, когда нужно сохранить контекст основного экрана и раскрыть боковую область с формой,
метаданными или журналом.
</p>
<div class="demo-actions">
<button class="btn btn-secondary with-icon" type="button" @click="drawerOpen = true">
<i class="ph ph-sidebar"></i>
Open drawer
</button>
<button class="btn btn-primary with-icon" type="button" @click="leftDrawerOpen = true">
<i class="ph ph-sidebar-simple"></i>
Left drawer
</button>
</div>
</div>
<div class="drawer-preview-panel" aria-hidden="true">
<h3 class="drawer-preview-title">Panel shape</h3>
<p class="drawer-preview-text">Fixed edge, hard border, focused action footer.</p>
<span class="chip chip-secondary">Context</span>
</div>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Drawer JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">Drawer.create("details-drawer", {
title: "Details",
bodyHtml: `
<p class="text">Context content, forms, logs, metadata.</p>
`,
actions: drawer => {
const close = document.createElement("button");
close.className = "btn btn-primary";
close.textContent = "Close";
close.addEventListener("click", () => drawer.close());
return [close];
}
}).show();</code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Left Position</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">Drawer.create("navigation-drawer", {
title: "Navigation",
position: "left",
bodyText: "Left drawer content"
}).show();</code></pre>
</div>
</section>
<section class="section docs-section" id="toasts">
<h2 class="section-title">Toasts</h2>
<p class="docs-section-description">Toasts создаются из JS и добавляются в `body` вызовом `.show()`. Для коротких уведомлений доступны методы `createInfo`, `createSuccess`, `createWarning`, `createDanger`.</p>
<div class="block demo-actions">
<h3 class="block-title">Triggers (demo buttons)</h3>
<button class="btn btn-primary" type="button" @click="showToast('info', { title: 'Title', text: 'Произошла ошибка. Повтори позже.' })">Show info (default)</button>
<button class="btn btn-success" type="button" @click="showToast('success', { title: 'Success', text: 'Всё отлично, всё работает, это успех тостера' })">Show success</button>
<button class="btn btn-warning" type="button" @click="showToast('warning', { title: 'Warning', text: 'Произошла ошибка. Повтори позже.' })">Show warning</button>
<button class="btn btn-danger" type="button" @click="showToast('error', { title: 'Danger', text: 'Произошла ошибка. Повтори позже.' })">Show danger</button>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Toasts JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">Toasts.createSuccess(
"Success",
"Операция выполнена успешно",
{ lifetime: 4000, alone: true }
).show();
Toasts.createDanger("Error", "Произошла ошибка").show();</code></pre>
</div>
</section>
<section class="section docs-section" id="cards">
<h2 class="section-title">Cards</h2>
<p class="docs-section-description">Card подходит для компактных виджетов и контентных блоков. Цветовые состояния карточек задаются модификаторами `card-success`, `card-warning`, `card-error`, `card-info`.</p>
<div class="cards">
<div class="card">
<h3 class="card-title">Card title</h3>
<div class="card-content">
<img src="/assets/imgs/gnexus-mark.svg" alt="" class="card-thumb">
<p>Карточка для контента, виджетов, статусов.</p>
</div>
<div class="card-footer">
<button class="btn btn-accent" type="button">Action</button>
</div>
</div>
</div>
<div class="block mt-6">
<div class="row g-4">
<div class="card status-card card-success">
<span class="card-title">Status title</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-check-circle"></i> OK
</div>
</div>
<p class="status-name">Primary status card with a short description.</p>
</div>
</div>
<div class="card status-card card-primary">
<span class="card-title">Default</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-stack"></i>
</div>
</div>
<p class="status-name">Neutral card for a module, widget, or section.</p>
</div>
</div>
<div class="card status-card card-warning">
<span class="card-title">Pending</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-warning"></i>
</div>
</div>
<p class="status-name">Warning state for items that need attention.</p>
</div>
</div>
<div class="card status-card card-error">
<span class="card-title">Failed</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-warning-octagon"></i>
</div>
</div>
<p class="status-name">Error state for failed actions or blocked flows.</p>
</div>
</div>
<div class="card status-card card-info">
<span class="card-title">Info</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-info"></i>
</div>
</div>
<p class="status-name">Informational card for contextual metadata.</p>
</div>
</div>
<div class="card status-card card-secondary">
<span class="card-title">Queued</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-clock"></i>
</div>
</div>
<p class="status-name">Secondary state for queued or background work.</p>
</div>
</div>
</div>
</div>
<div class="block mt-6">
<GnMetricCard label="Monthly usage" value="84.2%" icon="ph-chart-line-up" delta="+12.8%" meta="vs previous period" />
</div>
<div class="block mt-6">
<GnActionCard kicker="Quick action" title="Create workflow" text="Use action cards for primary next steps, onboarding prompts, and compact empty state actions.">
<template #actions>
<GnButton variant="secondary" size="sm">Preview</GnButton>
<GnButton variant="accent" size="sm">Create</GnButton>
</template>
</GnActionCard>
</div>
<div class="block mt-6">
<h3 class="block-title">Horizontal Card</h3>
<GnHorizontalCard image="/assets/imgs/gnexus-mark.svg" title="Project Alpha" title-href="#">
<p>Compact horizontal layout for content listings, search results, and entity rows.</p>
<template #footer>
<span>Updated 2h ago</span>
<GnBadge variant="success">Active</GnBadge>
</template>
</GnHorizontalCard>
</div>
<div class="block mt-6">
<h3 class="block-title">Login Card</h3>
<GnLoginCard title="Sign in" username-label="Username" password-label="Password" submit-text="Sign in" forgot-href="#" signup-href="#" @submit="showToast('success', { title: 'Login', text: 'Form submitted' })" />
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Cards HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="card status-card card-success">
<span class="card-title">Status title</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-check-circle"></i>
OK
</div>
</div>
<p class="status-name">Primary status card.</p>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Metric Card HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="card metric-card">
<div class="card-content">
<div class="metric-card-header">
<p class="metric-card-label">Monthly usage</p>
<span class="metric-card-icon"><i class="ph ph-chart-line-up"></i></span>
</div>
<p class="metric-card-value">84.2%</p>
<div class="metric-card-meta">
<span class="metric-card-delta">+12.8%</span>
<span>vs previous period</span>
</div>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Action Card HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="card action-card">
<div class="card-content">
<span class="action-card-kicker">Quick action</span>
<h3 class="action-card-title">Create workflow</h3>
<p class="action-card-text">
Use action cards for primary next steps and compact empty state actions.
</p>
<div class="action-card-actions">
<button class="btn btn-secondary btn-small">Preview</button>
<button class="btn btn-accent btn-small">Create</button>
</div>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Horizontal Card HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><div class="card card-horizontal">
<div class="card-media">
<img src="/assets/imgs/cover.png" alt="">
</div>
<div class="card-body">
<h3 class="card-title">
<a href="/projects/alpha">Project Alpha</a>
</h3>
<div class="card-content">
<p>Description text.</p>
</div>
<div class="card-footer">
<span>Updated 2h ago</span>
<span class="badge badge-success">Active</span>
</div>
</div>
</div></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Vue: GnHorizontalCard</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><GnHorizontalCard
image="/assets/imgs/cover.png"
title="Project Alpha"
title-href="/projects/alpha"
icon="ph-arrow-right">
<p>Description text.</p>
<template #footer>
<span>Updated 2h ago</span>
<GnBadge variant="success">Active</GnBadge>
</template>
</GnHorizontalCard></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Vue: GnLoginCard</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><GnLoginCard
title="Sign in"
username-label="Username"
password-label="Password"
submit-text="Sign in"
remember-me
forgot-href="/forgot"
signup-href="/signup"
@submit="handleLogin"
/></code></pre>
</div>
<div class="block mt-6">
<h3 class="block-title">User Card — Compact</h3>
<GnUserCard
name="Eugene Sukhodolskiy"
email="goldmikki@gmail.com"
:avatar="{ src: 'https://auth.gnexus.space/storage/avatars/1/181513cf-3e1b-4b72-bc9d-a1825c736560/original.jpg', status: 'online' }"
href="https://auth.gnexus.space/account/profile"
compact
:actions="[
{ icon: 'ph-pencil-simple', label: 'Edit profile' },
{ icon: 'ph-sign-out', label: 'Logout' }
]"
/>
</div>
<div class="block mt-6">
<h3 class="block-title">User Card — Full</h3>
<GnUserCard
name="Eugene Sukhodolskiy"
email="goldmikki@gmail.com"
role="Lead Frontend Engineer"
:avatar="{ src: 'https://auth.gnexus.space/storage/avatars/1/181513cf-3e1b-4b72-bc9d-a1825c736560/original.jpg', status: 'online' }"
href="https://auth.gnexus.space/account/profile"
:actions="[
{ icon: 'ph-user', label: 'View profile', variant: 'primary' },
{ icon: 'ph-chat-circle', label: 'Message', variant: 'accent' }
]"
/>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">User Card Compact HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><article class="card user-card user-card-compact">
<div class="user-card-body">
<a class="profile-identity" href="#">
<span class="identity">
<span class="avatar avatar-primary avatar-sm is-online">
<img src="..." alt="">
</span>
<span class="identity-content">
<span class="identity-title">Name</span>
<span class="identity-meta">email@example.com</span>
</span>
</span>
</a>
<div class="user-card-actions">
<button class="btn-icon" aria-label="Edit">
<i class="ph ph-pencil-simple"></i>
</button>
</div>
</div>
</article></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">User Card Full HTML</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><article class="card user-card">
<div class="user-card-body">
<span class="identity">
<span class="avatar avatar-primary is-online">
<img src="..." alt="">
</span>
<span class="identity-content">
<span class="identity-title">Name</span>
<span class="identity-meta">email@example.com</span>
</span>
</span>
<span class="user-card-role">Role</span>
<div class="user-card-actions">
<button class="btn btn-primary btn-small">View profile</button>
<button class="btn btn-accent btn-small">Message</button>
</div>
</div>
</article></code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Vue: GnUserCard</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-html"><GnUserCard
name="Eugene Sukhodolskiy"
email="goldmikki@gmail.com"
role="Lead Frontend Engineer"
:avatar="{ src: '...', status: 'online' }"
href="/profile"
:actions="[
{ icon: 'ph-user', label: 'View profile', variant: 'primary' },
{ icon: 'ph-chat-circle', label: 'Message', variant: 'accent' }
]"
/>
<GnUserCard
name="Eugene Sukhodolskiy"
email="goldmikki@gmail.com"
:avatar="{ src: '...', status: 'online' }"
href="/profile"
compact
:actions="[
{ icon: 'ph-pencil-simple', label: 'Edit profile' },
{ icon: 'ph-sign-out', label: 'Logout' }
]"
/></code></pre>
</div>
</section>
<section class="section docs-section" id="modals">
<h2 class="section-title">Modals</h2>
<p class="docs-section-description">Modal создаётся из JS через Modals.create. Для обычного текста используй bodyText; HTML-контент передавай явно через bodyHtml или DOM-элемент.</p>
<div class="block">
<h3 class="block-title">Open triggers</h3>
<GnButton variant="primary" @click="modalOpen = true">Open modal</GnButton>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Modals JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">Modals.create("demo-modal", {
title: "Demo modal",
bodyText: "Modal content",
actions: modal => {
const close = document.createElement("button");
close.className = "btn btn-primary";
close.textContent = "Close";
close.addEventListener("click", () => modal.close());
return [close];
}
}).show();</code></pre>
</div>
</section>
<section class="section docs-section" id="confirm-dialog">
<h2 class="section-title">Confirm Dialog</h2>
<p class="docs-section-description">Confirm Dialog использует существующий confirmPopup поверх Modal. Он нужен для коротких подтверждений перед опасными или необратимыми действиями.</p>
<div class="block">
<h3 class="block-title">Trigger</h3>
<div class="demo-actions">
<GnButton variant="warning" icon="ph-warning" @click="confirmOpen = true">Open confirm</GnButton>
</div>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Confirm JS</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">confirmPopup(
"This action cannot be undone.",
() => Toasts.createSuccess("Confirmed", "Action accepted").show(),
() => Toasts.createInfo("Canceled", "Action skipped").show()
);</code></pre>
</div>
<div class="code-example">
<div class="code-example-header">
<span class="code-example-title">Global Namespace</span>
<button class="btn-icon btn-icon-sm" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
</div>
<pre><code class="language-javascript">GNexusUIKit.confirmPopup(
"Apply this change?",
() => console.log("confirmed"),
() => console.log("canceled")
);</code></pre>
</div>
</section>
<GnModal v-model:open="modalOpen" title="Demo modal window">
<p class="text">Любой контент: текст, формы, списки.</p>
<GnInput v-model="name" label="Project name" placeholder="Launch Plan" />
<GnTextarea v-model="name" label="Description" placeholder="Optional" />
<template #actions>
<GnButton variant="primary" @click="modalOpen = false">Cancel</GnButton>
<GnButton variant="success" @click="save">Apply</GnButton>
</template>
</GnModal>
<GnDrawer v-model:open="drawerOpen" title="Details" position="right">
<p class="text">Context panel for quick edits, metadata, and secondary flows.</p>
<GnDescriptionList :items="[{ term: 'Status', value: 'Active' }, { term: 'Owner', value: 'Design System' }, { term: 'Updated', value: 'Today' }]" />
</GnDrawer>
<GnDrawer v-model:open="leftDrawerOpen" title="Navigation" position="left">
<ul class="list-menu">
<li class="list-item"><button class="list-action" type="button"><span class="list-label">Overview</span></button></li>
<li class="list-item"><button class="list-action" type="button"><span class="list-label">Activity</span></button></li>
<li class="list-item"><button class="list-action" type="button"><span class="list-label">Settings</span></button></li>
</ul>
</GnDrawer>
<GnConfirmDialog
v-model:open="confirmOpen"
title="Apply this change?"
message="This action requires confirmation."
confirm-variant="success"
@confirm="confirmAction"
/>
</div>
</div>
</main>
</template>
</GnNavigationShell>
</GnToastProvider>
`
}).mount("#app");
</script>
<script>
document.addEventListener("DOMContentLoaded", () => {
setTimeout(() => {
const edstr = editableString(document.querySelector(".editable-example"));
if (edstr && edstr.editableString) {
edstr.editableString.onSwitch(component => console.log("SWITCH", component));
edstr.editableString.onChange(component => console.log("onChange", component.value));
}
}, 100);
});
</script>
<script src="/js/gnexus-ui-kit.js"></script>
<script src="/assets/libs/highlight/highlight.min.js"></script>
</body>
</html>