Promotes the Forge visual language from the Stacks feature into a global design system used across the app: - app.css: Forge utilities (dot-grid backdrop, eyebrow, ember, display/lede, status pills, stat grid, panels, registration marks, alert, terminal, buttons). CSS variables alias the forge display font to the app's standard sans stack (Inter, now properly self-hosted via @fontsource/inter). - +layout.svelte: reskinned sidebar brand, active nav rail, mobile top bar, global h1/h2 typography overrides, main dot-grid backdrop. - Shared components reskinned: EmptyState (breathing-ember empty mark), StatusBadge (mono pills with pulse), ConfirmDialog (registration marks + forge buttons). - Dashboard (+page.svelte): ForgeHero header, forge-stat-grid, Instrument-style section titles with accent. - New ForgeHero component for reusable hero headers. Stacks feature fully localized (EN + RU): - 80+ keys under stacks.* covering list, new, detail, revisions, logs, errors, status labels, delete/rollback dialogs. - Russian uses forge vocabulary (куются/наковальня/куём/etc). - $t() wired through all three Stacks pages.
This commit is contained in:
@@ -129,13 +129,9 @@
|
||||
{sidebarOpen ? 'translate-x-0' : '-translate-x-full'}"
|
||||
>
|
||||
<!-- Logo -->
|
||||
<div class="flex h-16 items-center gap-2.5 border-b border-[var(--border-primary)] px-5">
|
||||
<div class="flex h-8 w-8 items-center justify-center rounded-lg bg-[var(--color-brand-600)]">
|
||||
<svg class="h-4.5 w-4.5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="text-base font-bold text-[var(--text-primary)]">{$t('app.name')}</span>
|
||||
<div class="brand flex h-16 items-center gap-2.5 border-b border-[var(--border-primary)] px-5">
|
||||
<span class="forge-ember brand-ember"></span>
|
||||
<span class="brand-name">{$t('app.name')}</span>
|
||||
|
||||
<!-- Close sidebar (mobile) -->
|
||||
<button
|
||||
@@ -153,10 +149,8 @@
|
||||
{@const active = isActive(item.href, $page.url.pathname)}
|
||||
<a
|
||||
href={item.href}
|
||||
class="group flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-150
|
||||
{active
|
||||
? 'bg-[var(--color-brand-50)] text-[var(--color-brand-700)] shadow-sm'
|
||||
: 'text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)]'}"
|
||||
class="nav-item group flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-150
|
||||
{active ? 'nav-active' : 'text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)]'}"
|
||||
>
|
||||
{#if item.icon === 'dashboard'}
|
||||
<IconDashboard size={18} class="{active ? 'text-[var(--color-brand-600)]' : 'text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]'} transition-colors duration-150" />
|
||||
@@ -276,12 +270,8 @@
|
||||
>
|
||||
<IconMenu size={22} />
|
||||
</button>
|
||||
<div class="flex h-7 w-7 items-center justify-center rounded-lg bg-[var(--color-brand-600)]">
|
||||
<svg class="h-3.5 w-3.5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="text-sm font-bold text-[var(--text-primary)]">{$t('app.name')}</span>
|
||||
<span class="forge-ember"></span>
|
||||
<span class="brand-name">{$t('app.name')}</span>
|
||||
</header>
|
||||
|
||||
<!-- Page content -->
|
||||
@@ -295,3 +285,72 @@
|
||||
{/if}
|
||||
|
||||
<Toast />
|
||||
|
||||
<style>
|
||||
/* ── Forge-themed layout shell ─────────────────────────────────── */
|
||||
/* Page titles — larger + tighter tracking, but using the app's sans stack */
|
||||
:global(main h1) {
|
||||
font-family: var(--font-family-sans) !important;
|
||||
font-weight: 700 !important;
|
||||
letter-spacing: -0.02em !important;
|
||||
font-size: clamp(1.875rem, 4vw, 2.5rem) !important;
|
||||
line-height: 1.1 !important;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
:global(main h2) {
|
||||
font-family: var(--font-family-sans);
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
:global(main code) {
|
||||
font-family: var(--forge-mono, 'JetBrains Mono', monospace);
|
||||
}
|
||||
|
||||
.brand {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.brand-ember {
|
||||
width: 10px; height: 10px;
|
||||
}
|
||||
.brand-name {
|
||||
font-family: var(--font-family-sans);
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.02em;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.nav-item :global(svg) { flex-shrink: 0; }
|
||||
.nav-active {
|
||||
background: var(--surface-card-hover);
|
||||
color: var(--text-primary) !important;
|
||||
position: relative;
|
||||
}
|
||||
.nav-active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -12px; top: 20%; bottom: 20%;
|
||||
width: 3px;
|
||||
background: var(--color-brand-600);
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
/* Apply dot-grid backdrop to main content */
|
||||
:global(main) {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
}
|
||||
:global(main)::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; height: 480px;
|
||||
background-image: radial-gradient(var(--border-primary) 1px, transparent 1px);
|
||||
background-size: 22px 22px;
|
||||
-webkit-mask-image: radial-gradient(ellipse at 20% 0%, #000 0%, transparent 70%);
|
||||
mask-image: radial-gradient(ellipse at 20% 0%, #000 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user