/* * SysDeck — shared sysdeck.css * * Base styles for every SysDeck Cockpit plugin. Loaded via * from each * plugin's index.html. * * The class names below (.sysdeck-card, .sysdeck-table, etc.) are the * canonical v0.0.20 names. For backward compatibility with the v0.0.19 * module JS (which still uses .suite-* class names), we alias every * .suite-* name to its .sysdeck-* equivalent at the bottom of this file. * v0.0.21 can rename the classes inside the module JS and drop the aliases. */ :root { --sysdeck-bg: #1e1e1e; --sysdeck-fg: #e0e0e0; --sysdeck-muted: #888; --sysdeck-accent: #06c; --sysdeck-accent-success: #3c9; --sysdeck-accent-warn: #f0ad4e; --sysdeck-accent-danger: #d9534f; --sysdeck-border: #444; --sysdeck-card-bg: #2a2a2a; } body { background: var(--sysdeck-bg); color: var(--sysdeck-fg); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size: 14px; margin: 0; } .sysdeck-page { padding: 1.5rem; max-width: 1200px; margin: 0 auto; } .sysdeck-loading { color: var(--sysdeck-muted); padding: 2rem; text-align: center; } .sysdeck-card { background: var(--sysdeck-card-bg); border: 1px solid var(--sysdeck-border); border-radius: 6px; padding: 1rem; margin-bottom: 1rem; } .sysdeck-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; } .sysdeck-card-title { margin: 0; font-size: 1.05rem; font-weight: 600; } .sysdeck-card-body { color: var(--sysdeck-fg); line-height: 1.5; } .sysdeck-panel-title { margin: 0 0 0.25rem 0; font-size: 1.4rem; font-weight: 600; } .sysdeck-panel-subtitle { margin: 0 0 1rem 0; color: var(--sysdeck-muted); font-size: 0.9rem; } .sysdeck-muted { color: var(--sysdeck-muted); } .sysdeck-mono, .sysdeck-table-mono { font-family: "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Cascadia Code", monospace; font-size: 0.85rem; } .sysdeck-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; } .sysdeck-table th, .sysdeck-table td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--sysdeck-border); } .sysdeck-table th { color: var(--sysdeck-muted); font-weight: 500; text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.05em; } .sysdeck-table tr:hover td { background: rgba(255, 255, 255, 0.03); } .sysdeck-badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 3px; font-size: 0.75rem; font-weight: 500; background: rgba(255, 255, 255, 0.1); } .sysdeck-badge.success { background: var(--sysdeck-accent-success); color: #000; } .sysdeck-badge.warn { background: var(--sysdeck-accent-warn); color: #000; } .sysdeck-badge.danger { background: var(--sysdeck-accent-danger); color: #fff; } .sysdeck-btn { display: inline-block; padding: 0.35rem 0.75rem; border: 1px solid var(--sysdeck-border); background: transparent; color: var(--sysdeck-fg); border-radius: 4px; cursor: pointer; font-size: 0.85rem; font-family: inherit; } .sysdeck-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.05); } .sysdeck-btn:disabled { opacity: 0.5; cursor: not-allowed; } .sysdeck-btn-ghost { background: transparent; border-color: transparent; color: var(--sysdeck-muted); } .sysdeck-btn-ghost:hover:not(:disabled) { color: var(--sysdeck-fg); background: rgba(255, 255, 255, 0.05); } .sysdeck-skeleton { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem 0; } .sysdeck-skeleton-line { height: 0.85rem; background: linear-gradient(90deg, var(--sysdeck-border) 0%, rgba(255,255,255,0.05) 50%, var(--sysdeck-border) 100%); background-size: 200% 100%; animation: sysdeck-skeleton-pulse 1.5s ease-in-out infinite; border-radius: 3px; } .sysdeck-skeleton-line.w-1\/3 { width: 33%; } .sysdeck-skeleton-line.w-1\/2 { width: 50%; } .sysdeck-skeleton-line.w-2\/3 { width: 66%; } .sysdeck-skeleton-line.w-3\/4 { width: 75%; } @keyframes sysdeck-skeleton-pulse { 0% { background-position: 0% 50%; } 100% { background-position: -200% 50%; } } /* ── v0.0.19 backward-compatibility aliases ────────────────────────── * Each .suite-* selector below aliases to its .sysdeck-* counterpart * above. This lets the v0.0.19 module JS (which still references * .suite-card, .suite-table, etc.) render correctly without code changes. */ .suite-card { background: var(--sysdeck-card-bg); border: 1px solid var(--sysdeck-border); border-radius: 6px; padding: 1rem; margin-bottom: 1rem; } .suite-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; } .suite-card-title { margin: 0; font-size: 1.05rem; font-weight: 600; } .suite-card-body { color: var(--sysdeck-fg); line-height: 1.5; } .suite-panel-title { margin: 0 0 0.25rem 0; font-size: 1.4rem; font-weight: 600; } .suite-panel-subtitle { margin: 0 0 1rem 0; color: var(--sysdeck-muted); font-size: 0.9rem; } .suite-muted { color: var(--sysdeck-muted); } .suite-mono, .suite-table-mono { font-family: "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Cascadia Code", monospace; font-size: 0.85rem; } .suite-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; } .suite-table th, .suite-table td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--sysdeck-border); } .suite-table th { color: var(--sysdeck-muted); font-weight: 500; text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.05em; } .suite-table tr:hover td { background: rgba(255, 255, 255, 0.03); } .suite-badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 3px; font-size: 0.75rem; font-weight: 500; background: rgba(255, 255, 255, 0.1); } .suite-badge.success { background: var(--sysdeck-accent-success); color: #000; } .suite-badge.warn { background: var(--sysdeck-accent-warn); color: #000; } .suite-badge.danger { background: var(--sysdeck-accent-danger); color: #fff; } .suite-btn { display: inline-block; padding: 0.35rem 0.75rem; border: 1px solid var(--sysdeck-border); background: transparent; color: var(--sysdeck-fg); border-radius: 4px; cursor: pointer; font-size: 0.85rem; font-family: inherit; } .suite-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.05); } .suite-btn:disabled { opacity: 0.5; cursor: not-allowed; } .suite-btn-ghost { background: transparent; border-color: transparent; color: var(--sysdeck-muted); } .suite-btn-ghost:hover:not(:disabled) { color: var(--sysdeck-fg); background: rgba(255, 255, 255, 0.05); } .suite-skeleton { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem 0; } .suite-skeleton-line { height: 0.85rem; background: linear-gradient(90deg, var(--sysdeck-border) 0%, rgba(255,255,255,0.05) 50%, var(--sysdeck-border) 100%); background-size: 200% 100%; animation: sysdeck-skeleton-pulse 1.5s ease-in-out infinite; border-radius: 3px; } .suite-skeleton-line.w-1\/3 { width: 33%; } .suite-skeleton-line.w-1\/2 { width: 50%; } .suite-skeleton-line.w-2\/3 { width: 66%; } .suite-skeleton-line.w-3\/4 { width: 75%; } /* ── v0.0.28 added classes (were missing in v0.0.20-v0.0.27) ─────────── * These were referenced by the v0.0.19-era module JS but never made it * into the shared CSS. Without them: * - .suite-progress / .suite-progress-bar / .suite-progress-fill → * progress bars in glances, fleet, netsec render as 0-height divs * - .suite-stat-value / .suite-stat-label → big numbers in glances and * packages panels render as unstyled text, no size hierarchy * - .suite-row / .suite-row-between → horizontal layouts in auth, * benchmark, glances, integrity, packages collapse to stacked * - .suite-grid / .cols-2 / .cols-3 → multi-column layouts in fleet, * integrity, mining, packages collapse to a single column * - .suite-col-2 / .suite-col-3 → legacy column-width helpers used * alongside .suite-row in glances, packages * - .suite-btn-primary → primary call-to-action buttons in benchmark, * integrity, packages were rendered as plain ghost buttons * - .suite-badge.info → informational badges in benchmark, firewall, * kata, mesh, netsec, integrity were unstyled (no background) * - .suite-input → search box in packages had no border / padding * - .suite-warn → warning modifier on package-update-count numbers * had no color override */ /* Layout primitives */ .suite-row, .sysdeck-row { display: flex; flex-direction: row; gap: 1rem; align-items: flex-start; flex-wrap: wrap; } .suite-row-between, .sysdeck-row-between { display: flex; flex-direction: row; justify-content: space-between; align-items: center; gap: 0.5rem; } .suite-grid, .sysdeck-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; } .suite-grid.cols-2, .sysdeck-grid.cols-2 { grid-template-columns: repeat(2, 1fr); } .suite-grid.cols-3, .sysdeck-grid.cols-3 { grid-template-columns: repeat(3, 1fr); } /* Legacy column-width helpers (used by glances + packages alongside .suite-row) */ .suite-col-2 { flex: 1 1 calc(50% - 0.5rem); min-width: 0; } .suite-col-3 { flex: 1 1 calc(33.333% - 0.667rem); min-width: 0; } /* Buttons */ .suite-btn-primary, .sysdeck-btn-primary { background: var(--sysdeck-accent); color: #fff; border-color: var(--sysdeck-accent); } .suite-btn-primary:hover:not(:disabled), .sysdeck-btn-primary:hover:not(:disabled) { background: var(--sysdeck-accent); filter: brightness(1.15); border-color: var(--sysdeck-accent); color: #fff; } /* Badges */ .suite-badge.info, .sysdeck-badge.info { background: var(--sysdeck-accent); color: #fff; } /* Stat blocks */ .suite-stat-value, .sysdeck-stat-value { font-size: 1.8rem; font-weight: 600; line-height: 1.1; margin: 0.25rem 0; } .suite-stat-value.suite-warn { color: var(--sysdeck-accent-warn); } .suite-stat-label { font-size: 0.8rem; color: var(--sysdeck-muted); margin-bottom: 0.5rem; } /* Progress bars — three classes work together: * .suite-progress outer track (the greyed-out background) * .suite-progress-bar inline-fill bar (sets width:% via style attr) * .suite-progress-fill alt fill variant used by fleet/netsec live bars * Plugins use a mix of the two fill patterns; both render the same. */ .suite-progress { height: 6px; background: rgba(255,255,255,0.08); border-radius: 3px; overflow: hidden; margin-top: 0.5rem; } .suite-progress-bar { height: 100%; background: var(--sysdeck-accent); border-radius: 3px; transition: width 0.3s ease; } .suite-progress-fill { height: 100%; background: var(--sysdeck-accent-success); border-radius: 3px; transition: width 0.3s ease; } /* Form inputs */ .suite-input, .sysdeck-input { background: rgba(255,255,255,0.04); border: 1px solid var(--sysdeck-border); color: var(--sysdeck-fg); padding: 0.4rem 0.6rem; border-radius: 4px; font-family: inherit; font-size: 0.9rem; } .suite-input:focus, .sysdeck-input:focus { outline: none; border-color: var(--sysdeck-accent); } /* Keyboard focus on every button, even without the web-edition skin. */ .suite-btn:focus-visible, .sysdeck-btn:focus-visible { outline: 2px solid var(--sysdeck-accent); outline-offset: 2px; } .suite-input::placeholder, .sysdeck-input::placeholder { color: var(--sysdeck-muted); } /* Narrow viewports: multi-column grids collapse to one column. */ @media (max-width: 720px) { .suite-grid.cols-2, .sysdeck-grid.cols-2, .suite-grid.cols-3, .sysdeck-grid.cols-3 { grid-template-columns: 1fr; } } /* Narrow viewports: multi-column grids collapse to one column. */ @media (max-width: 720px) { .suite-grid.cols-2, .sysdeck-grid.cols-2, .suite-grid.cols-3, .sysdeck-grid.cols-3 { grid-template-columns: 1fr; } } /* Narrow viewports: multi-column grids collapse to one column. */ @media (max-width: 720px) { .suite-grid.cols-2, .sysdeck-grid.cols-2, .suite-grid.cols-3, .sysdeck-grid.cols-3 { grid-template-columns: 1fr; } }