Files
homelab-topology/src/index.css
Christopher Mayor 0910c966a5 feat: migrate from static config to database and add authentication
- Replaced static hosts.json and staticConfig.ts with SQLite database (Prisma)

- Implemented JWT authentication and Login UI

- Added dynamic API routes for hosts, topology, and settings

- Updated UI components to fetch and manage state dynamically

- Added Settings interface for managing hosts and topology nodes
2026-02-25 14:07:11 -08:00

165 lines
3.7 KiB
CSS

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--bg-primary: #0F172A;
--bg-secondary: #1E293B;
--bg-tertiary: #334155;
--text-primary: #F8FAFC;
--text-secondary: #94A3B8;
--border: #475569;
--accent: #38BDF8;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Inter', system-ui, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
overflow: hidden;
}
#root {
width: 100vw;
height: 100vh;
}
/* ── Custom Scrollbar ────────────────────────────────────── */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.2);
}
/* ── Glassmorphism Utility ───────────────────────────────── */
.glass {
background: rgba(30, 41, 59, 0.7);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.glass-panel {
background: rgba(15, 23, 42, 0.75);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-right: 1px solid rgba(255, 255, 255, 0.05);
border-left: 1px solid rgba(255, 255, 255, 0.05);
}
/* ── Skip link (a11y) ────────────────────────────────────── */
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: var(--accent);
color: #000;
padding: 8px 16px;
z-index: 100;
font-weight: 600;
transition: top 200ms ease-out;
}
.skip-link:focus {
top: 0;
}
/* ── Focus-visible styles (a11y) ─────────────────────────── */
:focus {
outline: none;
}
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
button:focus-visible {
box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.4);
outline: none;
}
/* ── Reduced motion (a11y) ───────────────────────────────── */
@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;
}
.react-flow__node {
transition: none !important;
}
}
/* ── React Flow overrides ────────────────────────────────── */
.react-flow__node {
cursor: pointer;
transition: transform 300ms ease-out;
}
.react-flow__edge-path {
stroke-width: 2;
}
.react-flow__minimap {
background-color: var(--bg-secondary);
}
/* Controls styling */
.react-flow__controls {
background: transparent;
box-shadow: none;
}
.react-flow__controls-button {
background-color: #334155;
border: 1px solid #475569;
color: #94A3B8;
border-bottom: 1px solid #475569;
}
.react-flow__controls-button:hover {
background-color: #475569;
color: #F8FAFC;
}
.react-flow__controls-button:active {
background-color: #1E293B;
}
.react-flow__controls-button svg {
fill: currentColor;
}
/* ── Visually hidden utility (a11y) ──────────────────────── */
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}