forked from wrenn/wrenn
- C1: Add sync.RWMutex to vm.Manager to protect concurrent vms map access - H1: Fix IP arithmetic overflow in network slot addressing (byte truncation) - H5: Fix MultiplexedChannel.Fork() TOCTOU race (move exited check inside lock) - H8: Remove snapshot overwrite — return template_name_taken conflict instead - H9: Wrap DeleteAccount DB ops in a transaction, make team deletion fatal - H10: Sanitize serviceErrToHTTP to stop leaking internal error messages - H11: Add deleted_at IS NULL to GetUserByEmail/GetUserByID queries - H12: Add id DESC to audit log composite index for cursor pagination - H15: Delete dead AuthModal.svelte component - H17: Move JWT from WebSocket URL query param to first WS message - H18: Fix $derived to $derived.by in FilesTab breadcrumbs
201 lines
5.1 KiB
CSS
201 lines
5.1 KiB
CSS
@import 'tailwindcss';
|
|
|
|
@import '@fontsource-variable/manrope';
|
|
@import '@fontsource/instrument-serif/400.css';
|
|
@import '@fontsource-variable/jetbrains-mono';
|
|
@import '@fontsource/alice/400.css';
|
|
|
|
/*
|
|
* Wrenn Design Tokens
|
|
* Sharp, warm, industrial-confident. Dark-first.
|
|
*/
|
|
|
|
@theme {
|
|
/* Background scale (6 steps, near-black-green) */
|
|
--color-bg-0: #0a0c0b;
|
|
--color-bg-1: #0f1211;
|
|
--color-bg-2: #141817;
|
|
--color-bg-3: #1a1e1c;
|
|
--color-bg-4: #212624;
|
|
--color-bg-5: #2a302d;
|
|
|
|
/* Text hierarchy (5 levels) */
|
|
--color-text-bright: #eae7e2;
|
|
--color-text-primary: #d0cdc6;
|
|
--color-text-secondary: #9b9790;
|
|
--color-text-tertiary: #6b6862;
|
|
--color-text-muted: #454340;
|
|
|
|
/* Sage green brand accent (3 tiers + 2 glows) */
|
|
--color-accent: #5e8c58;
|
|
--color-accent-mid: #89a785;
|
|
--color-accent-bright: #a4c89f;
|
|
--color-accent-glow: rgba(94, 140, 88, 0.07);
|
|
--color-accent-glow-mid: rgba(94, 140, 88, 0.14);
|
|
|
|
/* Borders (2 levels) */
|
|
--color-border: #1f2321;
|
|
--color-border-mid: #2a2f2c;
|
|
|
|
/* Semantic status */
|
|
--color-amber: #d4a73c;
|
|
--color-red: #cf8172;
|
|
--color-blue: #5a9fd4;
|
|
|
|
/* Fonts */
|
|
--font-sans: 'Manrope Variable', system-ui, sans-serif;
|
|
--font-serif: 'Instrument Serif', serif;
|
|
--font-mono: 'JetBrains Mono Variable', monospace;
|
|
--font-brand: 'Alice', serif;
|
|
|
|
/* Type scale — rem-based (root = 87.5%, giving 14px at browser default)
|
|
Heading tokens carry a default line-height; body/UI tokens inherit the global 1.6. */
|
|
--text-display: 2.571rem; /* ~36px — auth/login section headings */
|
|
--text-display--line-height: 1.1;
|
|
--text-page: 2rem; /* ~28px — page h1 titles */
|
|
--text-page--line-height: 1.15;
|
|
--text-heading: 1.429rem; /* ~20px — dialog headings, empty-state */
|
|
--text-heading--line-height: 1.25;
|
|
--text-body: 1rem; /* 14px — primary body, buttons, inputs */
|
|
--text-ui: 0.929rem; /* ~13px — nav labels, table cells, secondary */
|
|
--text-meta: 0.857rem; /* ~12px — key prefixes, minor info */
|
|
--text-label: 0.786rem; /* ~11px — uppercase section labels */
|
|
--text-badge: 0.714rem; /* ~10px — live badges, tiny indicators */
|
|
|
|
/* Radii */
|
|
--radius-card: 8px;
|
|
--radius-input: 5px;
|
|
--radius-button: 5px;
|
|
--radius-avatar: 5px;
|
|
--radius-logo: 6px;
|
|
|
|
/* Shadows */
|
|
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
--shadow-card: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.25);
|
|
--shadow-dialog: 0 16px 48px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.35);
|
|
}
|
|
|
|
/* Base styles */
|
|
html {
|
|
font-family: var(--font-sans);
|
|
font-size: 87.5%; /* 14px at browser default; scales with user text-size preferences */
|
|
line-height: 1.6;
|
|
color: var(--color-text-primary);
|
|
background-color: var(--color-bg-0);
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
text-rendering: optimizeLegibility;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Instrument Serif reads less condensed with a touch of positive tracking */
|
|
.font-serif {
|
|
letter-spacing: 0.015em;
|
|
}
|
|
|
|
/* Tabular figures on all mono text — numbers align in tables and metric displays */
|
|
.font-mono {
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* Selection */
|
|
::selection {
|
|
background: rgba(94, 140, 88, 0.25);
|
|
color: var(--color-text-bright);
|
|
}
|
|
|
|
/* Scrollbar — thin, matches dark theme */
|
|
::-webkit-scrollbar {
|
|
width: 6px;
|
|
height: 6px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: var(--color-bg-4);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: var(--color-bg-5);
|
|
}
|
|
|
|
/* Live status dot pulse animation — opacity-only for GPU compositor, zero paint cost */
|
|
@keyframes wrenn-glow {
|
|
0%,
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
opacity: 0.3;
|
|
}
|
|
}
|
|
|
|
/* Outward ring ripple — for live/running status dots; more delightful than opacity-only */
|
|
@keyframes status-ping {
|
|
0% {
|
|
transform: scale(1);
|
|
opacity: 0.8;
|
|
}
|
|
80%,
|
|
100% {
|
|
transform: scale(2.8);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
.animate-status-ping {
|
|
animation: status-ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
|
|
will-change: transform, opacity;
|
|
}
|
|
|
|
/* Fade-up entrance animation */
|
|
@keyframes fadeUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(6px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
/* Refresh icon spin — one full rotation */
|
|
@keyframes spin-once {
|
|
from { transform: rotate(0deg); }
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Floating icon — used on empty-state icon containers */
|
|
@keyframes iconFloat {
|
|
0%, 100% { transform: translateY(0); }
|
|
50% { transform: translateY(-6px); }
|
|
}
|
|
|
|
/* CSS containment — isolate paint for independent UI regions.
|
|
Note: `contain: layout` is omitted because it creates a containing block
|
|
that breaks `position: fixed` popups rendered inside <main>. */
|
|
main {
|
|
contain: style;
|
|
}
|
|
|
|
/* Respect user motion preferences — covers both CSS class animations and inline style animations */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|