The add-host form is now opened via a "+ Add host" button in the page header. The modal closes on Cancel, backdrop click, × button, or automatically after a successful creation. Adds modal CSS with backdrop blur and entry animation, .btn-primary / .btn-secondary shared button styles, and a .page-header flex layout reusable across list pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1016 lines
22 KiB
CSS
1016 lines
22 KiB
CSS
/* ============================================================
|
|
DESIGN TOKENS
|
|
All visual properties live as CSS custom properties.
|
|
To add a new theme, define a [data-theme="my-theme"] block
|
|
with the same variable set below.
|
|
============================================================ */
|
|
|
|
:root {
|
|
/* --- Shared tokens (identical across all themes) --- */
|
|
--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
|
|
Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
--font-mono: "SF Mono", "Fira Code", "Cascadia Code", "Consolas", monospace;
|
|
|
|
--size-xs: 4px;
|
|
--size-sm: 8px;
|
|
--size-md: 16px;
|
|
--size-lg: 24px;
|
|
--size-xl: 40px;
|
|
--size-2xl: 64px;
|
|
|
|
--radius-sm: 6px;
|
|
--radius-md: 10px;
|
|
--radius-lg: 14px;
|
|
--radius-pill: 999px;
|
|
|
|
--font-xs: 12px;
|
|
--font-sm: 13px;
|
|
--font-base: 15px;
|
|
--font-lg: 17px;
|
|
--font-xl: 22px;
|
|
--font-2xl: 28px;
|
|
--font-3xl: 34px;
|
|
|
|
--transition-fast: 100ms ease;
|
|
--transition-base: 200ms ease;
|
|
|
|
--nav-height: 52px;
|
|
--content-width: 1000px;
|
|
|
|
/* --- Light theme (default) --- */
|
|
--bg: #f5f5f7;
|
|
--bg-surface: #ffffff;
|
|
--bg-surface2: #f9f9fb;
|
|
--bg-hover: rgba(0, 0, 0, 0.04);
|
|
--bg-overlay: rgba(255, 255, 255, 0.8);
|
|
|
|
--border: rgba(0, 0, 0, 0.12);
|
|
--border-focus: #0071e3;
|
|
|
|
--text: #1d1d1f;
|
|
--text-secondary: #6e6e73;
|
|
--text-tertiary: #aeaeb2;
|
|
--text-on-accent: #ffffff;
|
|
|
|
--accent: #0071e3;
|
|
--accent-hover: #0077ed;
|
|
--accent-light: rgba(0, 113, 227, 0.10);
|
|
|
|
--danger: #ff3b30;
|
|
--danger-hover: #ff2d20;
|
|
--danger-light: rgba(255, 59, 48, 0.10);
|
|
|
|
--success: #34c759;
|
|
|
|
--shadow-sm: 0 1px 2px rgba(0,0,0,.06), 0 1px 4px rgba(0,0,0,.04);
|
|
--shadow-md: 0 4px 12px rgba(0,0,0,.08), 0 2px 4px rgba(0,0,0,.04);
|
|
--shadow-lg: 0 8px 24px rgba(0,0,0,.12), 0 4px 8px rgba(0,0,0,.06);
|
|
}
|
|
|
|
/* System dark mode — only applies when no explicit data-theme is set */
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not([data-theme]) {
|
|
--bg: #000000;
|
|
--bg-surface: #1c1c1e;
|
|
--bg-surface2: #2c2c2e;
|
|
--bg-hover: rgba(255, 255, 255, 0.06);
|
|
--bg-overlay: rgba(28, 28, 30, 0.85);
|
|
|
|
--border: rgba(255, 255, 255, 0.12);
|
|
--border-focus: #0a84ff;
|
|
|
|
--text: #f5f5f7;
|
|
--text-secondary: #aeaeb2;
|
|
--text-tertiary: #636366;
|
|
--text-on-accent: #ffffff;
|
|
|
|
--accent: #0a84ff;
|
|
--accent-hover: #409cff;
|
|
--accent-light: rgba(10, 132, 255, 0.15);
|
|
|
|
--danger: #ff453a;
|
|
--danger-hover: #ff6961;
|
|
--danger-light: rgba(255, 69, 58, 0.15);
|
|
|
|
--success: #32d74b;
|
|
|
|
--shadow-sm: 0 1px 2px rgba(0,0,0,.3), 0 1px 4px rgba(0,0,0,.2);
|
|
--shadow-md: 0 4px 12px rgba(0,0,0,.4), 0 2px 4px rgba(0,0,0,.2);
|
|
--shadow-lg: 0 8px 24px rgba(0,0,0,.5), 0 4px 8px rgba(0,0,0,.3);
|
|
}
|
|
}
|
|
|
|
/* Explicit light theme */
|
|
[data-theme="light"] {
|
|
--bg: #f5f5f7;
|
|
--bg-surface: #ffffff;
|
|
--bg-surface2: #f9f9fb;
|
|
--bg-hover: rgba(0, 0, 0, 0.04);
|
|
--bg-overlay: rgba(255, 255, 255, 0.8);
|
|
|
|
--border: rgba(0, 0, 0, 0.12);
|
|
--border-focus: #0071e3;
|
|
|
|
--text: #1d1d1f;
|
|
--text-secondary: #6e6e73;
|
|
--text-tertiary: #aeaeb2;
|
|
--text-on-accent: #ffffff;
|
|
|
|
--accent: #0071e3;
|
|
--accent-hover: #0077ed;
|
|
--accent-light: rgba(0, 113, 227, 0.10);
|
|
|
|
--danger: #ff3b30;
|
|
--danger-hover: #ff2d20;
|
|
--danger-light: rgba(255, 59, 48, 0.10);
|
|
|
|
--success: #34c759;
|
|
|
|
--shadow-sm: 0 1px 2px rgba(0,0,0,.06), 0 1px 4px rgba(0,0,0,.04);
|
|
--shadow-md: 0 4px 12px rgba(0,0,0,.08), 0 2px 4px rgba(0,0,0,.04);
|
|
--shadow-lg: 0 8px 24px rgba(0,0,0,.12), 0 4px 8px rgba(0,0,0,.06);
|
|
}
|
|
|
|
/* Explicit dark theme */
|
|
[data-theme="dark"] {
|
|
--bg: #000000;
|
|
--bg-surface: #1c1c1e;
|
|
--bg-surface2: #2c2c2e;
|
|
--bg-hover: rgba(255, 255, 255, 0.06);
|
|
--bg-overlay: rgba(28, 28, 30, 0.85);
|
|
|
|
--border: rgba(255, 255, 255, 0.12);
|
|
--border-focus: #0a84ff;
|
|
|
|
--text: #f5f5f7;
|
|
--text-secondary: #aeaeb2;
|
|
--text-tertiary: #636366;
|
|
--text-on-accent: #ffffff;
|
|
|
|
--accent: #0a84ff;
|
|
--accent-hover: #409cff;
|
|
--accent-light: rgba(10, 132, 255, 0.15);
|
|
|
|
--danger: #ff453a;
|
|
--danger-hover: #ff6961;
|
|
--danger-light: rgba(255, 69, 58, 0.15);
|
|
|
|
--success: #32d74b;
|
|
|
|
--shadow-sm: 0 1px 2px rgba(0,0,0,.3), 0 1px 4px rgba(0,0,0,.2);
|
|
--shadow-md: 0 4px 12px rgba(0,0,0,.4), 0 2px 4px rgba(0,0,0,.2);
|
|
--shadow-lg: 0 8px 24px rgba(0,0,0,.5), 0 4px 8px rgba(0,0,0,.3);
|
|
}
|
|
|
|
/* ============================================================
|
|
RESET & BASE
|
|
============================================================ */
|
|
|
|
*, *::before, *::after {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
html {
|
|
font-size: var(--font-base);
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
text-rendering: optimizeLegibility;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-sans);
|
|
font-size: var(--font-base);
|
|
line-height: 1.6;
|
|
color: var(--text);
|
|
background: var(--bg);
|
|
min-height: 100vh;
|
|
transition: background var(--transition-base), color var(--transition-base);
|
|
}
|
|
|
|
/* ============================================================
|
|
NAVIGATION
|
|
============================================================ */
|
|
|
|
nav {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
height: var(--nav-height);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--size-sm);
|
|
padding: 0 var(--size-lg);
|
|
background: var(--bg-overlay);
|
|
border-bottom: 1px solid var(--border);
|
|
backdrop-filter: blur(20px) saturate(180%);
|
|
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
}
|
|
|
|
nav a {
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
text-decoration: none;
|
|
padding: var(--size-xs) var(--size-sm);
|
|
border-radius: var(--radius-sm);
|
|
transition: color var(--transition-fast), background var(--transition-fast);
|
|
}
|
|
|
|
nav a:hover {
|
|
color: var(--text);
|
|
background: var(--bg-hover);
|
|
}
|
|
|
|
nav a.active {
|
|
color: var(--accent);
|
|
}
|
|
|
|
/* Spacer pushes theme toggle to the right */
|
|
nav .nav-spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
/* ============================================================
|
|
LAYOUT
|
|
============================================================ */
|
|
|
|
main {
|
|
max-width: var(--content-width);
|
|
margin: 0 auto;
|
|
padding: var(--size-xl) var(--size-lg);
|
|
}
|
|
|
|
/* ============================================================
|
|
TYPOGRAPHY
|
|
============================================================ */
|
|
|
|
h1 {
|
|
font-size: var(--font-3xl);
|
|
font-weight: 700;
|
|
letter-spacing: -0.5px;
|
|
color: var(--text);
|
|
margin-bottom: var(--size-sm);
|
|
}
|
|
|
|
h2 {
|
|
font-size: var(--font-xl);
|
|
font-weight: 600;
|
|
letter-spacing: -0.3px;
|
|
color: var(--text);
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
h3 {
|
|
font-size: var(--font-lg);
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
margin-bottom: var(--size-sm);
|
|
}
|
|
|
|
p {
|
|
color: var(--text-secondary);
|
|
line-height: 1.7;
|
|
}
|
|
|
|
code {
|
|
font-family: var(--font-mono);
|
|
font-size: 0.9em;
|
|
background: var(--bg-surface2);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
padding: 1px 6px;
|
|
}
|
|
|
|
/* ============================================================
|
|
BUTTONS
|
|
============================================================ */
|
|
|
|
button,
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--size-xs);
|
|
font-family: var(--font-sans);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
line-height: 1;
|
|
padding: 8px 16px;
|
|
border-radius: var(--radius-sm);
|
|
border: 1px solid transparent;
|
|
cursor: pointer;
|
|
transition:
|
|
background var(--transition-fast),
|
|
color var(--transition-fast),
|
|
box-shadow var(--transition-fast),
|
|
transform var(--transition-fast);
|
|
text-decoration: none;
|
|
white-space: nowrap;
|
|
user-select: none;
|
|
}
|
|
|
|
button:active,
|
|
.btn:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
/* Primary — filled accent */
|
|
button[type="submit"],
|
|
.btn-primary {
|
|
background: var(--accent);
|
|
color: var(--text-on-accent);
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
button[type="submit"]:hover,
|
|
.btn-primary:hover {
|
|
background: var(--accent-hover);
|
|
border-color: var(--accent-hover);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
/* Secondary — outlined */
|
|
.btn-secondary {
|
|
background: transparent;
|
|
color: var(--text);
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: var(--bg-hover);
|
|
}
|
|
|
|
/* Danger — for delete actions */
|
|
.btn-danger {
|
|
background: transparent;
|
|
color: var(--danger);
|
|
border-color: transparent;
|
|
font-size: var(--font-xs);
|
|
padding: 4px 10px;
|
|
}
|
|
|
|
.btn-danger:hover {
|
|
background: var(--danger-light);
|
|
border-color: var(--danger);
|
|
}
|
|
|
|
/* Theme toggle */
|
|
.theme-toggle {
|
|
background: var(--bg-hover);
|
|
color: var(--text-secondary);
|
|
border: 1px solid var(--border);
|
|
font-size: var(--font-xs);
|
|
font-weight: 600;
|
|
padding: 4px 10px;
|
|
border-radius: var(--radius-pill);
|
|
letter-spacing: 0.3px;
|
|
}
|
|
|
|
.theme-toggle:hover {
|
|
color: var(--text);
|
|
background: var(--bg-surface2);
|
|
border-color: var(--border-focus);
|
|
}
|
|
|
|
/* ============================================================
|
|
FORMS & INPUTS
|
|
============================================================ */
|
|
|
|
.form-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-xs);
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
label {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-xs);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
input[type="text"],
|
|
input[type="email"],
|
|
input[type="number"],
|
|
input[type="password"],
|
|
input[type="search"],
|
|
select,
|
|
textarea {
|
|
font-family: var(--font-sans);
|
|
font-size: var(--font-base);
|
|
color: var(--text);
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
padding: 9px 12px;
|
|
width: 100%;
|
|
transition:
|
|
border-color var(--transition-fast),
|
|
box-shadow var(--transition-fast);
|
|
outline: none;
|
|
-webkit-appearance: none;
|
|
}
|
|
|
|
input::placeholder,
|
|
textarea::placeholder {
|
|
color: var(--text-tertiary);
|
|
}
|
|
|
|
input:focus,
|
|
select:focus,
|
|
textarea:focus {
|
|
border-color: var(--border-focus);
|
|
box-shadow: 0 0 0 3px var(--accent-light);
|
|
}
|
|
|
|
/* Inline form layout (label + input + button on one line) */
|
|
.form-inline {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: var(--size-sm);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.form-inline label {
|
|
flex: 1;
|
|
min-width: 200px;
|
|
}
|
|
|
|
/* ============================================================
|
|
CARDS & SECTIONS
|
|
============================================================ */
|
|
|
|
.card {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: var(--size-lg);
|
|
transition: box-shadow var(--transition-base);
|
|
}
|
|
|
|
.card:hover {
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
/* Section spacing between cards */
|
|
section + section {
|
|
margin-top: var(--size-lg);
|
|
}
|
|
|
|
/* ============================================================
|
|
TABLES
|
|
============================================================ */
|
|
|
|
.table-container {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
overflow: hidden;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: var(--font-sm);
|
|
}
|
|
|
|
thead {
|
|
background: var(--bg-surface2);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
thead th {
|
|
padding: 10px var(--size-md);
|
|
text-align: left;
|
|
font-size: var(--font-xs);
|
|
font-weight: 600;
|
|
letter-spacing: 0.5px;
|
|
text-transform: uppercase;
|
|
color: var(--text-tertiary);
|
|
}
|
|
|
|
tbody tr {
|
|
border-bottom: 1px solid var(--border);
|
|
transition: background var(--transition-fast);
|
|
}
|
|
|
|
tbody tr:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
tbody tr:hover {
|
|
background: var(--bg-hover);
|
|
}
|
|
|
|
tbody td {
|
|
padding: 12px var(--size-md);
|
|
color: var(--text);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* Count columns (Hosts, Applications...) — right-aligned, muted color */
|
|
th.col-count,
|
|
td.col-count {
|
|
text-align: right;
|
|
color: var(--text-secondary);
|
|
font-variant-numeric: tabular-nums;
|
|
width: 120px;
|
|
}
|
|
|
|
th.col-count {
|
|
color: var(--text-tertiary);
|
|
}
|
|
|
|
/* Actions column — right-aligned to match the button position */
|
|
th.col-actions,
|
|
td.col-actions {
|
|
text-align: right;
|
|
width: 100px;
|
|
}
|
|
|
|
/* ============================================================
|
|
STATUS MESSAGES
|
|
============================================================ */
|
|
|
|
.error {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--size-sm);
|
|
font-size: var(--font-sm);
|
|
color: var(--danger);
|
|
background: var(--danger-light);
|
|
border: 1px solid var(--danger);
|
|
border-radius: var(--radius-sm);
|
|
padding: var(--size-sm) var(--size-md);
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
.empty {
|
|
font-size: var(--font-sm);
|
|
color: var(--text-tertiary);
|
|
text-align: center;
|
|
padding: var(--size-xl);
|
|
}
|
|
|
|
/* ============================================================
|
|
HOME PAGE — Dashboard
|
|
============================================================ */
|
|
|
|
.home-page {
|
|
max-width: 860px;
|
|
margin: 0 auto;
|
|
padding-top: var(--size-2xl);
|
|
}
|
|
|
|
.home-header {
|
|
text-align: center;
|
|
margin-bottom: var(--size-2xl);
|
|
}
|
|
|
|
.home-header h1 {
|
|
font-size: var(--font-3xl);
|
|
margin-bottom: var(--size-xs);
|
|
}
|
|
|
|
.home-header p {
|
|
font-size: var(--font-lg);
|
|
color: var(--text-secondary);
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* Summary grid — one card per entity */
|
|
.summary-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: var(--size-md);
|
|
}
|
|
|
|
/* Clickable summary card */
|
|
.summary-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--size-sm);
|
|
padding: var(--size-xl) var(--size-lg);
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
transition:
|
|
box-shadow var(--transition-base),
|
|
border-color var(--transition-base),
|
|
transform var(--transition-base),
|
|
background var(--transition-base);
|
|
}
|
|
|
|
.summary-card:hover {
|
|
box-shadow: var(--shadow-md);
|
|
border-color: var(--accent);
|
|
background: var(--accent-light);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.summary-card:active {
|
|
transform: translateY(0);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.summary-card__count {
|
|
font-size: var(--font-3xl);
|
|
font-weight: 700;
|
|
letter-spacing: -1px;
|
|
color: var(--text);
|
|
line-height: 1;
|
|
/* Animate count changes gracefully */
|
|
transition: color var(--transition-base);
|
|
}
|
|
|
|
.summary-card:hover .summary-card__count {
|
|
color: var(--accent);
|
|
}
|
|
|
|
.summary-card__label {
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
letter-spacing: 0.3px;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
/* ============================================================
|
|
NETWORKS PAGE
|
|
============================================================ */
|
|
|
|
.networks-page h1 {
|
|
margin-bottom: var(--size-lg);
|
|
}
|
|
|
|
.networks-page .add-form {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: var(--size-lg);
|
|
margin-bottom: var(--size-lg);
|
|
}
|
|
|
|
.networks-page .add-form h2 {
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
.networks-page .add-form form {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: var(--size-sm);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.networks-page .add-form label {
|
|
flex: 1;
|
|
min-width: 220px;
|
|
}
|
|
|
|
.networks-page .add-form input {
|
|
margin-top: var(--size-xs);
|
|
}
|
|
|
|
.networks-page .list h2 {
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
.networks-page .list .table-container {
|
|
margin-top: 0;
|
|
}
|
|
|
|
/* Delete button inside table */
|
|
.networks-page td button {
|
|
background: transparent;
|
|
color: var(--danger);
|
|
border: 1px solid transparent;
|
|
font-size: var(--font-xs);
|
|
padding: 3px 10px;
|
|
border-radius: var(--radius-sm);
|
|
cursor: pointer;
|
|
transition: background var(--transition-fast), border-color var(--transition-fast);
|
|
}
|
|
|
|
.networks-page td button:hover {
|
|
background: var(--danger-light);
|
|
border-color: var(--danger);
|
|
}
|
|
|
|
/* ============================================================
|
|
404 PAGE
|
|
============================================================ */
|
|
|
|
.not-found {
|
|
text-align: center;
|
|
padding-top: var(--size-2xl);
|
|
}
|
|
|
|
.not-found h1 {
|
|
font-size: var(--font-2xl);
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
.not-found a {
|
|
color: var(--accent);
|
|
text-decoration: none;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.not-found a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* ============================================================
|
|
TABLE UTILITIES — shared across pages
|
|
============================================================ */
|
|
|
|
/* Clickable link inside a table cell */
|
|
.table-link {
|
|
color: var(--accent);
|
|
text-decoration: none;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.table-link:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Monospace cell (IPs, CIDRs…) */
|
|
.cell-mono {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--font-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* ============================================================
|
|
FILTER BAR
|
|
============================================================ */
|
|
|
|
.filter-bar {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: var(--size-md) var(--size-lg);
|
|
margin-bottom: var(--size-md);
|
|
}
|
|
|
|
.filter-bar__fields {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
gap: var(--size-md);
|
|
align-items: end;
|
|
}
|
|
|
|
.filter-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-xs);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* ============================================================
|
|
PAGINATION BAR
|
|
============================================================ */
|
|
|
|
.pagination-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: var(--size-sm);
|
|
padding: var(--size-sm) 0;
|
|
margin-bottom: var(--size-sm);
|
|
}
|
|
|
|
.pagination-bar__info {
|
|
font-size: var(--font-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.pagination-bar__controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--size-md);
|
|
}
|
|
|
|
.pagination-per-page {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--size-xs);
|
|
font-size: var(--font-sm);
|
|
color: var(--text-secondary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.pagination-per-page select {
|
|
width: auto;
|
|
padding: 4px 8px;
|
|
font-size: var(--font-sm);
|
|
}
|
|
|
|
.pagination-nav {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--size-xs);
|
|
}
|
|
|
|
.pagination-nav button {
|
|
background: var(--bg-surface);
|
|
color: var(--text);
|
|
border: 1px solid var(--border);
|
|
padding: 4px 10px;
|
|
font-size: var(--font-base);
|
|
border-radius: var(--radius-sm);
|
|
min-width: 32px;
|
|
}
|
|
|
|
.pagination-nav button:hover:not(:disabled) {
|
|
background: var(--bg-hover);
|
|
border-color: var(--accent);
|
|
color: var(--accent);
|
|
}
|
|
|
|
.pagination-nav button:disabled {
|
|
opacity: 0.35;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.pagination-nav__label {
|
|
font-size: var(--font-sm);
|
|
color: var(--text-secondary);
|
|
white-space: nowrap;
|
|
padding: 0 var(--size-xs);
|
|
}
|
|
|
|
/* ============================================================
|
|
MODAL
|
|
============================================================ */
|
|
|
|
.modal-backdrop {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, 0.45);
|
|
backdrop-filter: blur(3px);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 200;
|
|
animation: backdrop-in var(--transition-base) both;
|
|
}
|
|
|
|
@keyframes backdrop-in {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
.modal {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-lg);
|
|
padding: var(--size-lg) var(--size-xl);
|
|
width: 90%;
|
|
max-width: 440px;
|
|
animation: modal-in var(--transition-base) both;
|
|
}
|
|
|
|
@keyframes modal-in {
|
|
from { opacity: 0; transform: translateY(-12px) scale(0.97); }
|
|
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
}
|
|
|
|
.modal__header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: var(--size-lg);
|
|
}
|
|
|
|
.modal__header h2 {
|
|
margin: 0;
|
|
font-size: var(--font-lg);
|
|
}
|
|
|
|
.modal__close {
|
|
background: none;
|
|
border: none;
|
|
font-size: 1.4rem;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
color: var(--text-secondary);
|
|
padding: 2px 6px;
|
|
border-radius: var(--radius-sm);
|
|
transition: color var(--transition-fast), background var(--transition-fast);
|
|
}
|
|
|
|
.modal__close:hover {
|
|
color: var(--text);
|
|
background: var(--bg-hover);
|
|
}
|
|
|
|
/* Form fields inside modal — single column stack */
|
|
.modal .add-form__fields {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-md);
|
|
}
|
|
|
|
.modal .add-form__fields label {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-xs);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* Cancel / Submit button row */
|
|
.modal__actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: var(--size-sm);
|
|
margin-top: var(--size-lg);
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: var(--bg-hover);
|
|
color: var(--text);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
padding: 7px var(--size-md);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background var(--transition-fast);
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: var(--bg-surface2);
|
|
}
|
|
|
|
/* ============================================================
|
|
HOSTS PAGE
|
|
============================================================ */
|
|
|
|
/* Header row: title on the left, "Add host" button on the right */
|
|
.page-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: var(--size-lg);
|
|
}
|
|
|
|
.page-header h1 {
|
|
margin: 0;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: var(--accent);
|
|
color: var(--text-on-accent);
|
|
border: none;
|
|
border-radius: var(--radius-sm);
|
|
padding: 8px var(--size-md);
|
|
font-size: var(--font-sm);
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background var(--transition-fast);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: var(--accent-hover);
|
|
}
|
|
|
|
/* Delete button inside hosts table */
|
|
.hosts-page td button {
|
|
background: transparent;
|
|
color: var(--danger);
|
|
border: 1px solid transparent;
|
|
font-size: var(--font-xs);
|
|
padding: 3px 10px;
|
|
border-radius: var(--radius-sm);
|
|
cursor: pointer;
|
|
transition: background var(--transition-fast), border-color var(--transition-fast);
|
|
}
|
|
|
|
.hosts-page td button:hover {
|
|
background: var(--danger-light);
|
|
border-color: var(--danger);
|
|
}
|