Migrated from Claude Design

This commit is contained in:
Zachary Levy
2026-07-29 13:49:23 -07:00
parent be12d33fde
commit 96fc643cb7
37 changed files with 3888 additions and 2 deletions
+965
View File
@@ -0,0 +1,965 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Browse the Cybersteel design-system reference gallery.">
<title>Preview Index — Cybersteel</title>
<link rel="stylesheet" href="../styles.css">
<style>
:root {
--gallery-width: 1240px;
--gallery-gutter: clamp(20px, 5vw, 72px);
}
html {
scroll-behavior: smooth;
}
body {
min-width: 320px;
min-height: 100vh;
margin: 0;
background:
var(--gradient-scanline),
radial-gradient(circle at 82% 0%, rgba(250, 189, 47, 0.08), transparent 31rem),
var(--bg-page);
}
a {
color: inherit;
}
.skip-link {
position: fixed;
top: 12px;
left: 12px;
z-index: 100;
padding: 8px 12px;
background: var(--gold-bright);
color: var(--bg-shell);
font-family: var(--font-mono);
font-size: var(--text-xs);
font-weight: var(--weight-semibold);
transform: translateY(-160%);
transition: transform var(--transition-ui);
}
.skip-link:focus {
transform: translateY(0);
}
.shell {
width: min(100%, calc(var(--gallery-width) + (var(--gallery-gutter) * 2)));
margin: 0 auto;
padding-inline: var(--gallery-gutter);
}
.masthead {
background: rgba(29, 32, 33, 0.94);
border-bottom: 1px solid var(--border);
}
.masthead-bar {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 68px;
gap: var(--space-panel);
}
.brand {
display: inline-flex;
align-items: baseline;
gap: var(--space-component);
color: var(--fg-heading);
}
.brand-name {
font-family: var(--font-display);
font-size: var(--text-lg);
font-weight: var(--weight-bold);
letter-spacing: var(--tracking-wider);
text-transform: uppercase;
}
.brand-context {
padding-left: var(--space-component);
border-left: 1px solid var(--gold-dim);
color: var(--fg-muted);
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: var(--tracking-widest);
text-transform: uppercase;
}
.system-state {
display: flex;
align-items: center;
gap: var(--space-element);
font-family: var(--font-mono);
font-size: var(--text-xs);
letter-spacing: var(--tracking-wider);
text-transform: uppercase;
color: var(--fg-caption);
}
.state-light {
width: 7px;
height: 7px;
border-radius: var(--radius-pill);
background: var(--green-bright);
box-shadow: 0 0 0 3px rgba(184, 187, 38, 0.12);
}
.hero {
display: grid;
grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.65fr);
gap: clamp(40px, 8vw, 108px);
align-items: end;
padding-block: clamp(64px, 9vw, 112px) clamp(52px, 7vw, 88px);
}
.eyebrow,
.section-index,
.card-index,
.search-label,
.meta-label {
font-family: var(--font-mono);
text-transform: uppercase;
}
.eyebrow {
display: flex;
align-items: center;
gap: var(--space-component);
margin-bottom: var(--space-cluster);
color: var(--gold-bright);
font-size: var(--text-xs);
letter-spacing: var(--tracking-widest);
}
.eyebrow::before {
content: "";
width: 34px;
height: 1px;
background: var(--gold-dim);
}
.hero h1 {
max-width: 760px;
margin-bottom: var(--space-panel);
font-size: clamp(44px, 7vw, 84px);
line-height: 0.94;
letter-spacing: -0.025em;
}
.hero-copy {
max-width: 680px;
margin: 0;
color: var(--fg-secondary);
font-size: clamp(16px, 2vw, 19px);
line-height: var(--leading-loose);
}
.hero-copy strong {
color: var(--fg-heading);
font-weight: var(--weight-medium);
}
.stats {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
border: 1px solid var(--border);
border-top-color: var(--gold-dim);
background: rgba(60, 56, 54, 0.58);
}
.stat {
min-height: 112px;
padding: var(--space-cluster);
border-right: 1px solid var(--border-subtle);
border-bottom: 1px solid var(--border-subtle);
}
.stat:nth-child(2n) {
border-right: 0;
}
.stat:nth-last-child(-n + 2) {
border-bottom: 0;
}
.stat-value {
display: block;
margin-bottom: var(--space-element);
color: var(--fg-heading);
font-family: var(--font-mono);
font-size: var(--text-2xl);
font-weight: var(--weight-semibold);
line-height: 1;
}
.stat-label {
color: var(--fg-muted);
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: var(--tracking-wider);
line-height: var(--leading-normal);
text-transform: uppercase;
}
.explorer-bar {
position: sticky;
top: 0;
z-index: 20;
background: rgba(29, 32, 33, 0.97);
border-block: 1px solid var(--border);
}
.explorer-controls {
display: grid;
grid-template-columns: minmax(240px, 0.7fr) minmax(0, 1.3fr);
gap: var(--space-panel);
align-items: center;
min-height: 86px;
}
.search-wrap {
position: relative;
}
.search-label {
position: absolute;
top: 50%;
left: var(--space-group);
color: var(--gold-dim);
font-size: 10px;
font-weight: var(--weight-semibold);
letter-spacing: var(--tracking-widest);
transform: translateY(-50%);
pointer-events: none;
}
.search-input {
width: 100%;
min-height: 46px;
padding: 11px 48px 11px 104px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-page);
color: var(--fg-body);
font-family: var(--font-body);
font-size: var(--text-sm);
outline: none;
transition: border-color var(--transition-hover), box-shadow var(--transition-hover);
}
.search-input::placeholder {
color: var(--fg-muted);
}
.search-input:focus {
border-color: var(--gold-bright);
box-shadow: var(--shadow-gold);
}
.search-key {
position: absolute;
top: 50%;
right: var(--space-component);
padding: 2px 6px;
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
color: var(--fg-muted);
font-family: var(--font-mono);
font-size: 9px;
transform: translateY(-50%);
pointer-events: none;
}
.category-nav {
display: flex;
justify-content: flex-end;
gap: var(--space-element);
overflow-x: auto;
scrollbar-width: thin;
}
.category-nav a {
display: inline-flex;
flex: 0 0 auto;
align-items: center;
gap: var(--space-element);
min-height: 38px;
padding: 7px 10px;
border: 1px solid transparent;
border-radius: var(--radius-sm);
color: var(--fg-caption);
font-family: var(--font-mono);
font-size: 10px;
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
transition: color var(--transition-hover), border-color var(--transition-hover), background var(--transition-hover);
}
.category-nav a:hover {
border-color: var(--gold-dim);
background: rgba(215, 153, 33, 0.12);
color: var(--fg-heading);
}
.category-count {
color: var(--gold-bright);
}
main {
padding-block: var(--space-region) var(--space-canvas);
}
.gallery-section {
scroll-margin-top: 116px;
padding-block: 0 var(--space-zone);
}
.gallery-section + .gallery-section {
padding-top: var(--space-region);
border-top: 1px solid var(--border-subtle);
}
.section-heading {
display: grid;
grid-template-columns: 70px minmax(220px, 0.75fr) minmax(280px, 1fr);
gap: var(--space-panel);
align-items: start;
margin-bottom: var(--space-block);
}
.section-index {
padding-top: 6px;
color: var(--gold-dim);
font-size: var(--text-xs);
letter-spacing: var(--tracking-widest);
}
.section-heading h2 {
margin: 0;
font-size: clamp(24px, 3vw, 36px);
letter-spacing: var(--tracking-wide);
}
.section-heading p {
max-width: 610px;
margin: 3px 0 0;
color: var(--fg-caption);
font-size: var(--text-sm);
line-height: var(--leading-loose);
}
.card-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-group);
}
.preview-card {
position: relative;
display: flex;
min-height: 226px;
flex-direction: column;
padding: var(--space-panel);
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background:
linear-gradient(135deg, rgba(250, 189, 47, 0.045), transparent 48%),
var(--bg-surface);
transition:
background var(--transition-hover),
border-color var(--transition-hover),
box-shadow var(--transition-hover),
color var(--transition-hover);
}
.preview-card::after {
content: "";
position: absolute;
right: -64px;
bottom: -86px;
width: 190px;
height: 190px;
border: 1px solid rgba(215, 153, 33, 0.13);
transform: rotate(45deg);
transition: border-color var(--transition-hover), transform var(--transition-hover);
}
.preview-card:hover {
border-color: var(--gold-dim);
box-shadow: 0 0 0 3px rgba(215, 153, 33, 0.2);
}
.preview-card:hover::after {
border-color: rgba(250, 189, 47, 0.42);
transform: rotate(45deg) translate(-4px, -4px);
}
.preview-card:active {
border-color: var(--gold-bright);
background: rgba(215, 153, 33, 0.19);
box-shadow: none;
transition-duration: 55ms;
}
.card-topline {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-component);
margin-bottom: var(--space-block);
}
.card-index {
color: var(--fg-muted);
font-size: 10px;
letter-spacing: var(--tracking-widest);
}
.card-badge {
padding: 3px 7px;
border: 1px solid var(--gold-dim);
border-radius: var(--radius-sm);
color: var(--gold-bright);
font-family: var(--font-mono);
font-size: 8px;
letter-spacing: var(--tracking-wider);
line-height: 1.4;
text-transform: uppercase;
}
.preview-card h3 {
position: relative;
z-index: 1;
margin-bottom: var(--space-component);
color: var(--fg-heading);
font-size: var(--text-xl);
}
.preview-card p {
position: relative;
z-index: 1;
max-width: 520px;
margin-bottom: var(--space-panel);
color: var(--fg-secondary);
font-size: var(--text-sm);
line-height: var(--leading-normal);
}
.card-footer {
position: relative;
z-index: 1;
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: var(--space-group);
margin-top: auto;
}
.card-meta {
display: flex;
flex-wrap: wrap;
gap: var(--space-element);
}
.meta-item {
color: var(--fg-muted);
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
}
.meta-item + .meta-item::before {
content: "◆";
margin-right: var(--space-element);
color: var(--gold-muted);
font-size: 6px;
vertical-align: 1px;
}
.card-arrow {
display: grid;
width: 34px;
height: 34px;
flex: 0 0 auto;
place-items: center;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--gold-bright);
font-family: var(--font-mono);
transition: background var(--transition-hover), border-color var(--transition-hover), color var(--transition-hover);
}
.preview-card:hover .card-arrow {
border-color: var(--gold-bright);
background: var(--gold-bright);
color: var(--bg-shell);
}
.empty-state {
display: none;
padding: var(--space-region) var(--space-panel);
border: 1px solid var(--border);
border-left: 2px solid var(--gold-dim);
background: var(--bg-surface);
}
.empty-state strong {
display: block;
margin-bottom: var(--space-element);
color: var(--fg-heading);
font-family: var(--font-display);
font-size: var(--text-lg);
}
.empty-state span {
color: var(--fg-caption);
font-family: var(--font-mono);
font-size: var(--text-sm);
}
.footer {
border-top: 1px solid var(--border);
background: var(--bg-shell);
}
.footer-inner {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 116px;
gap: var(--space-panel);
}
.footer-note {
margin: 0;
color: var(--fg-caption);
font-family: var(--font-mono);
font-size: var(--text-xs);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
}
.footer-note strong {
color: var(--fg-heading);
font-weight: var(--weight-medium);
}
.to-top {
color: var(--gold-bright);
font-family: var(--font-mono);
font-size: var(--text-xs);
letter-spacing: var(--tracking-wider);
text-transform: uppercase;
}
[hidden] {
display: none !important;
}
@media (max-width: 980px) {
.hero {
grid-template-columns: 1fr;
}
.stats {
max-width: 600px;
}
.explorer-controls {
grid-template-columns: 1fr;
gap: var(--space-component);
padding-block: var(--space-group);
}
.category-nav {
justify-content: flex-start;
padding-bottom: 2px;
}
.section-heading {
grid-template-columns: 50px 1fr;
}
.section-heading p {
grid-column: 2;
}
}
@media (max-width: 720px) {
.shell {
padding-inline: 18px;
}
.system-state {
display: none;
}
.hero h1 {
font-size: clamp(42px, 15vw, 64px);
}
.stats {
width: 100%;
}
.section-heading {
display: block;
}
.section-index {
display: block;
margin-bottom: var(--space-element);
}
.section-heading p {
margin-top: var(--space-component);
}
.card-grid {
grid-template-columns: 1fr;
}
.preview-card {
min-height: 214px;
}
.footer-inner {
align-items: flex-start;
flex-direction: column;
justify-content: center;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
*, *::before, *::after {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
}
}
</style>
</head>
<body id="top">
<a class="skip-link" href="#gallery">Skip to gallery</a>
<header class="masthead">
<div class="shell masthead-bar">
<a class="brand" href="index.html" aria-label="Cybersteel preview index">
<span class="brand-name">Cybersteel</span>
<span class="brand-context">Preview Index</span>
</a>
<div class="system-state" aria-label="Reference gallery status">
<span class="state-light" aria-hidden="true"></span>
Reference set online
</div>
</div>
<div class="shell hero">
<div>
<div class="eyebrow">Design system reference</div>
<h1>Preview<br>Index</h1>
<p class="hero-copy">
Explore the complete visual language through <strong>16 focused references</strong>.
Start with the foundations, inspect the type system, then move through structure,
effects, components, and live interaction states.
</p>
</div>
<div class="stats" aria-label="Gallery summary">
<div class="stat"><span class="stat-value">16</span><span class="stat-label">Reference pages</span></div>
<div class="stat"><span class="stat-value">04</span><span class="stat-label">System groups</span></div>
<div class="stat"><span class="stat-value">07</span><span class="stat-label">Live demos</span></div>
<div class="stat"><span class="stat-value">00</span><span class="stat-label">Remote assets</span></div>
</div>
</div>
</header>
<div class="explorer-bar">
<div class="shell explorer-controls">
<div class="search-wrap">
<label class="search-label" for="preview-search">Search</label>
<input class="search-input" id="preview-search" type="search" placeholder="Color, type, states…" autocomplete="off" spellcheck="false">
<span class="search-key" aria-hidden="true">/</span>
</div>
<nav class="category-nav" aria-label="Preview categories">
<a href="#foundations">Foundations <span class="category-count">03</span></a>
<a href="#typography">Typography <span class="category-count">04</span></a>
<a href="#structure">Structure <span class="category-count">03</span></a>
<a href="#components">Components <span class="category-count">06</span></a>
</nav>
</div>
</div>
<main class="shell" id="gallery">
<section class="gallery-section" id="foundations" data-section>
<div class="section-heading">
<span class="section-index">01 / 04</span>
<h2>Foundations</h2>
<p>Core color primitives. Review the base surfaces, accent ramps, and semantic roles before applying the system.</p>
</div>
<div class="card-grid">
<a class="preview-card" href="colors-base.html" data-card data-search="foundations color base palette background foreground surfaces text pairings gruvbox">
<div class="card-topline"><span class="card-index">REF—01</span></div>
<h3>Base Palette</h3>
<p>Background and foreground ramps, default pairings, contextual text, and surface combinations.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Color</span><span class="meta-item">Surfaces</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="colors-accents.html" data-card data-search="foundations color accent gold red green blue teal orange aqua purple swatches ramps">
<div class="card-topline"><span class="card-index">REF—02</span></div>
<h3>Accent Colors</h3>
<p>Bright, dim, and muted ramps for gold, red, green, blue, orange, aqua, and purple.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Color</span><span class="meta-item">Ramps</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="colors-semantic.html" data-card data-search="foundations semantic color primary success danger warning info disabled buttons text roles">
<div class="card-topline"><span class="card-index">REF—03</span></div>
<h3>Semantic Colors</h3>
<p>Primary, success, danger, warning, info, and disabled roles shown across text and controls.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Color</span><span class="meta-item">Roles</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
</div>
</section>
<section class="gallery-section" id="typography" data-section>
<div class="section-heading">
<span class="section-index">02 / 04</span>
<h2>Typography</h2>
<p>IBM Plex Sans carries the primary hierarchy. IBM Plex Mono handles code, logs, aligned data, and opt-in terminal surfaces.</p>
</div>
<div class="card-grid">
<a class="preview-card" href="type-display.html" data-card data-search="typography display ibm plex sans hero heading subheading hierarchy scale">
<div class="card-topline"><span class="card-index">REF—04</span></div>
<h3>Display Type</h3>
<p>Plex Sans display hierarchy across hero, heading, subheading, body, and light text treatments.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Plex Sans</span><span class="meta-item">Display</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="type-body.html" data-card data-search="typography body ibm plex sans scale prose paragraph labels captions">
<div class="card-topline"><span class="card-index">REF—05</span></div>
<h3>Body Type</h3>
<p>Readable body sizing, weights, labels, captions, and supporting text within the core type scale.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Plex Sans</span><span class="meta-item">Body</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="type-mono.html" data-card data-search="typography mono terminal ibm plex mono code logs data timestamps console">
<div class="card-topline"><span class="card-index">REF—06</span></div>
<h3>Mono / Terminal</h3>
<p>Plex Mono specimens for terminal output, code, logs, timestamps, and aligned operational data.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Plex Mono</span><span class="meta-item">Data</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="type-sans.html" data-card data-search="typography sans mono mode comparison opt-in terminal default hierarchy">
<div class="card-topline"><span class="card-index">REF—07</span></div>
<h3>Sans vs. Mono Mode</h3>
<p>Side-by-side comparison of the default Sans system and the opt-in, fully terminal-styled Mono mode.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Modes</span><span class="meta-item">Comparison</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
</div>
</section>
<section class="gallery-section" id="structure" data-section>
<div class="section-heading">
<span class="section-index">03 / 04</span>
<h2>Structure &amp; Effects</h2>
<p>Layout rhythm and surface construction: the spacing scale, crisp border geometry, radius choices, and flat elevation model.</p>
</div>
<div class="card-grid">
<a class="preview-card" href="spacing-tokens.html" data-card data-search="structure spacing tokens grid rhythm 4px 8px chip element component group panel section">
<div class="card-topline"><span class="card-index">REF—08</span></div>
<h3>Spacing Tokens</h3>
<p>The complete 496px spacing scale, labeled by token and demonstrated in practical layout contexts.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Spacing</span><span class="meta-item">8px Grid</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="borders-radius.html" data-card data-search="structure effects border borders radius radii corners 6px spinner animation shape">
<div class="card-topline"><span class="card-index">REF—09</span><span class="card-badge">Animated</span></div>
<h3>Borders &amp; Radius</h3>
<p>Structural and semantic borders plus the radius scale across buttons, cards, inputs, and a loading spinner.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Borders</span><span class="meta-item">Shape</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="shadows-elevation.html" data-card data-search="structure effects shadows elevation flat surfaces hover press interactive cards border background">
<div class="card-topline"><span class="card-index">REF—10</span><span class="card-badge">Interactive</span></div>
<h3>Shadows &amp; Elevation</h3>
<p>Flat elevation through background and border changes, with interactive card hover and press behavior.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Elevation</span><span class="meta-item">Effects</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
</div>
</section>
<section class="gallery-section" id="components" data-section>
<div class="section-heading">
<span class="section-index">04 / 04</span>
<h2>Components &amp; States</h2>
<p>Reusable interface patterns and their behavior. Hover, focus, press, validation, loading, and disabled states are live where marked.</p>
</div>
<div class="card-grid">
<a class="preview-card" href="components-buttons.html" data-card data-search="components buttons primary secondary danger ghost hover press interactive states controls">
<div class="card-topline"><span class="card-index">REF—11</span><span class="card-badge">Interactive</span></div>
<h3>Buttons</h3>
<p>Primary, secondary, and danger controls with the three-step default, hover, and press treatment.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Controls</span><span class="meta-item">Motion</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="components-inputs.html" data-card data-search="components forms inputs select focus error success validation interactive halo fields">
<div class="card-topline"><span class="card-index">REF—12</span><span class="card-badge">Interactive</span></div>
<h3>Form Inputs</h3>
<p>Text and select controls with focus, error, success, validation, and transition behavior.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Forms</span><span class="meta-item">Validation</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="components-cards.html" data-card data-search="components cards stat deploy alert surface clickable hover halo press interactive">
<div class="card-topline"><span class="card-index">REF—13</span><span class="card-badge">Interactive</span></div>
<h3>Cards</h3>
<p>Static data surfaces and clickable cards, including stat, alert, deploy, hover, and press treatments.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Surfaces</span><span class="meta-item">States</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="components-badges.html" data-card data-search="components badges status online offline degraded error running complete failed labels indicators">
<div class="card-topline"><span class="card-index">REF—14</span></div>
<h3>Badges &amp; Status</h3>
<p>System, process, and neutral indicators for online, degraded, running, complete, failed, and labeled states.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Status</span><span class="meta-item">Labels</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="components-nav.html" data-card data-search="components navigation nav tabs top side hover active divider interactive states">
<div class="card-topline"><span class="card-index">REF—15</span><span class="card-badge">Interactive</span></div>
<h3>Navigation</h3>
<p>Top-tab and side-navigation explorations with active selection, divider, and hover behavior.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">Navigation</span><span class="meta-item">Patterns</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
<a class="preview-card" href="components-states.html" data-card data-search="components states hover focus press release transition spinner loading disabled interactive motion buttons">
<div class="card-topline"><span class="card-index">REF—16</span><span class="card-badge">Interactive</span></div>
<h3>Component States</h3>
<p>Live hover, focus, press, release, disabled, loading, spinner, and timing references in one matrix.</p>
<div class="card-footer">
<div class="card-meta"><span class="meta-item">States</span><span class="meta-item">Motion</span></div>
<span class="card-arrow" aria-hidden="true"></span>
</div>
</a>
</div>
</section>
<div class="empty-state" id="empty-state" role="status" aria-live="polite">
<strong>No matching references.</strong>
<span>Clear the search or use another system term.</span>
</div>
</main>
<footer class="footer">
<div class="shell footer-inner">
<p class="footer-note"><strong>Cybersteel</strong> / Local reference gallery / No remote dependencies</p>
<a class="to-top" href="#top">Return to top ↑</a>
</div>
</footer>
<script>
(function () {
var input = document.getElementById('preview-search');
var cards = Array.prototype.slice.call(document.querySelectorAll('[data-card]'));
var sections = Array.prototype.slice.call(document.querySelectorAll('[data-section]'));
var emptyState = document.getElementById('empty-state');
function filterGallery() {
var query = input.value.trim().toLowerCase();
var visibleCount = 0;
cards.forEach(function (card) {
var matches = !query || card.getAttribute('data-search').indexOf(query) !== -1 || card.textContent.toLowerCase().indexOf(query) !== -1;
card.hidden = !matches;
if (matches) visibleCount += 1;
});
sections.forEach(function (section) {
var hasVisibleCards = section.querySelector('[data-card]:not([hidden])');
section.hidden = !hasVisibleCards;
});
emptyState.style.display = visibleCount ? 'none' : 'block';
}
input.addEventListener('input', filterGallery);
document.addEventListener('keydown', function (event) {
if (event.key === '/' && document.activeElement !== input) {
event.preventDefault();
input.focus();
}
if (event.key === 'Escape' && document.activeElement === input) {
input.value = '';
filterGallery();
input.blur();
}
});
}());
</script>
</body>
</html>