Polish UI across all route groups + redesign welcome page

- Welcome: split-panel layout with Sign In always above fold, feature cards, trust badges
- Release Control: dashboard, releases, promotions, approvals — design token alignment
- Security: posture, findings, scan submit, unknowns, reports — compact tables, severity badges
- Operations: ops hub, jobengine, scheduler, doctor, notifications, feeds — consistent styling
- Audit & Evidence: evidence overview, audit log, export center, replay — shimmer loading
- Setup & Admin: topology, integrations, identity, trust, system — hover lift, focus rings
- Shared: buttons, tabs, forms, colors — unified design tokens (btn-primary, tab-active, focus-ring)
- Archive 3 completed sprints (SPRINT_20260317_001/002/003)
- Add QA journey reports and route map

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-18 00:02:25 +02:00
parent b851aa8300
commit 8e6cbeab97
208 changed files with 9012 additions and 2207 deletions

View File

@@ -660,7 +660,7 @@ interface ChannelTypeOption {
.btn-primary {
background: var(--color-status-info-text);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
border: none;
}

View File

@@ -391,7 +391,7 @@ import {
cursor: pointer;
}
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.table-container {

View File

@@ -250,7 +250,7 @@ import {
.section-header p { margin: 0; color: var(--color-text-secondary); font-size: 0.875rem; }
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.75rem; }

View File

@@ -442,7 +442,7 @@ interface ConfigSubTab {
.btn-primary {
background: var(--color-status-info-text);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
border-color: var(--color-status-info-text);
}

View File

@@ -406,7 +406,7 @@ import {
.btn-primary {
background: var(--color-status-info-text);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
border: none;
}

View File

@@ -233,7 +233,7 @@ import { NotifierRule, NotifierRuleStatus, NotifierSeverity } from '../../../cor
.btn-primary {
background: var(--color-status-info-text);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
border: none;
}

View File

@@ -279,7 +279,7 @@ import {
}
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-icon { padding: 0.25rem 0.5rem; background: transparent; border: none; color: var(--color-status-info-text); font-size: 0.75rem; cursor: pointer; }

View File

@@ -327,7 +327,7 @@ import {
.section-header p { margin: 0; color: var(--color-text-secondary); font-size: 0.875rem; }
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.75rem; }
.btn-icon { padding: 0.25rem 0.5rem; background: transparent; border: none; color: var(--color-status-info-text); font-size: 0.75rem; cursor: pointer; }

View File

@@ -231,7 +231,7 @@ import { NotifierQuietHours, NotifierQuietHoursRequest, NotifierQuietWindow } fr
.section-header p { margin: 0; color: var(--color-text-secondary); font-size: 0.875rem; }
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.75rem; }
.btn-icon { padding: 0.25rem 0.5rem; background: transparent; border: none; color: var(--color-status-info-text); font-size: 0.75rem; cursor: pointer; }

View File

@@ -340,7 +340,7 @@ import {
flex: 1;
}
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-secondary:disabled { opacity: 0.6; cursor: not-allowed; }

View File

@@ -345,7 +345,7 @@ import {
cursor: pointer;
}
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.75rem; }

View File

@@ -294,7 +294,7 @@ type ThrottleScope = 'global' | 'channel' | 'rule' | 'event';
.section-header p { margin: 0; color: var(--color-text-secondary); font-size: 0.875rem; }
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-text-heading); border: none; }
.btn-primary { background: var(--color-status-info-text); color: var(--color-btn-primary-text); border: none; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-secondary); }
.btn-icon { padding: 0.25rem 0.5rem; background: transparent; border: none; color: var(--color-status-info-text); font-size: 0.75rem; cursor: pointer; }

View File

@@ -390,11 +390,11 @@ type ViewMode = 'grid' | 'heatmap' | 'table';
}
.btn--primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
&:hover {
background: var(--color-brand-primary-hover);
background: var(--color-btn-primary-bg-hover);
}
}

View File

@@ -527,11 +527,11 @@ type WizardStep = 'environment' | 'configure' | 'install' | 'verify' | 'complete
}
.btn--primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
&:hover:not(:disabled) {
background: var(--color-brand-primary-hover);
background: var(--color-btn-primary-bg-hover);
}
}

View File

@@ -359,11 +359,11 @@ const ACTION_CONFIGS: Record<AgentAction, ActionConfig> = {
}
.btn--primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
&:hover:not(:disabled) {
background: var(--color-brand-primary-hover);
background: var(--color-btn-primary-bg-hover);
}
}

View File

@@ -303,11 +303,11 @@ import { AgentHealthResult } from '../../models/agent.models';
}
.btn--primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
&:hover:not(:disabled) {
background: var(--color-brand-primary-hover);
background: var(--color-btn-primary-bg-hover);
}
}

View File

@@ -334,8 +334,8 @@ import { aocPath } from '../platform/ops/operations-paths';
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -108,7 +108,7 @@ import { aocPath } from '../platform/ops/operations-paths';
.date-range input { padding: 0.5rem; border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); }
.checkbox, .radio { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.format-options { display: flex; gap: 1.5rem; }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; font-size: 1rem; }
.btn-primary { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; font-size: 1rem; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.report-preview { background: var(--color-surface-primary); border-radius: var(--radius-lg); border: 1px solid var(--color-border-primary); overflow: hidden; }
.preview-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.25rem; background: var(--color-surface-elevated); border-bottom: 1px solid var(--color-border-primary); }

View File

@@ -108,7 +108,7 @@ import { aocPath } from '../platform/ops/operations-paths';
.validator-input { display: flex; gap: 0.75rem; margin-bottom: 2rem; }
.validator-input select, .validator-input input { padding: 0.75rem; border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); font-size: 1rem; }
.validator-input input { flex: 1; }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; }
.btn-primary { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.chain-result { background: var(--color-surface-primary); border-radius: var(--radius-lg); border: 1px solid var(--color-border-primary); overflow: hidden; }
.chain-result.complete { border-color: var(--color-status-success); }

View File

@@ -93,12 +93,154 @@ type QueueTab = 'pending' | 'approved' | 'rejected' | 'expiring' | 'my-team';
</section>
`,
styles: [`
.approvals{display:grid;gap:.6rem}.approvals header h1{margin:0}.approvals header p{margin:.2rem 0 0;color:var(--color-text-secondary);font-size:.8rem}
.tabs,.filters{display:flex;gap:.3rem;flex-wrap:wrap}.tabs a{border:1px solid var(--color-border-primary);border-radius:var(--radius-full);padding:.12rem .5rem;font-size:.72rem;color:var(--color-text-secondary);text-decoration:none}
.tabs a.active{border-color:var(--color-brand-primary);color:var(--color-brand-primary)}
.filters select{border:1px solid var(--color-border-primary);border-radius:var(--radius-sm);background:var(--color-surface-primary);padding:.24rem .45rem;font-size:.72rem}
.banner,table{border:1px solid var(--color-border-primary);border-radius:var(--radius-md);background:var(--color-surface-primary)} .banner{padding:.7rem;font-size:.8rem;color:var(--color-text-secondary)} .banner.error{color:var(--color-status-error-text)}
table{width:100%;border-collapse:collapse}th,td{border-bottom:1px solid var(--color-border-primary);padding:.4rem .45rem;font-size:.72rem;text-align:left;vertical-align:top}th{font-size:.66rem;color:var(--color-text-secondary);text-transform:uppercase}tr:last-child td{border-bottom:none}
.approvals {
display: grid;
gap: 1rem;
max-width: 1400px;
}
.approvals header h1 {
margin: 0;
font-size: 1.5rem;
font-weight: var(--font-weight-semibold, 600);
}
.approvals header p {
margin: 0.25rem 0 0;
color: var(--color-text-secondary);
font-size: 0.875rem;
}
/* Tabs */
.tabs {
display: flex;
gap: 0.25rem;
flex-wrap: wrap;
border-bottom: 1px solid var(--color-border-primary);
padding-bottom: 0;
}
.tabs a {
padding: 0.5rem 1rem;
font-size: 0.8125rem;
color: var(--color-tab-inactive-text, var(--color-text-secondary));
text-decoration: none;
border: none;
border-bottom: 2px solid transparent;
border-radius: 0;
transition: color 150ms ease, border-color 150ms ease;
font-weight: 500;
}
.tabs a:hover {
color: var(--color-text-primary);
}
.tabs a.active {
color: var(--color-tab-active-text, var(--color-text-primary));
border-bottom: 2px solid var(--color-tab-active-border, var(--color-brand-primary));
font-weight: 600;
}
/* Filters */
.filters {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
align-items: center;
}
.filters select {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
background: var(--color-surface-primary);
color: var(--color-text-primary);
padding: 0.375rem 0.75rem;
font-size: 0.8125rem;
transition: border-color 150ms ease, box-shadow 150ms ease;
}
.filters select:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
/* Banners */
.banner {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
background: linear-gradient(90deg, var(--color-surface-secondary) 25%, var(--color-surface-primary) 50%, var(--color-surface-secondary) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
padding: 0.75rem 1rem;
font-size: 0.8125rem;
color: var(--color-text-secondary);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.banner.error {
color: var(--color-status-error-text);
background: var(--color-surface-primary);
animation: none;
border-color: var(--color-status-error);
}
/* Table */
table {
width: 100%;
border-collapse: collapse;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
background: var(--color-surface-primary);
overflow: hidden;
}
th, td {
border-bottom: 1px solid var(--color-border-primary);
padding: 0.5rem 0.75rem;
font-size: 0.8125rem;
text-align: left;
vertical-align: top;
}
th {
font-size: 0.6875rem;
font-weight: var(--font-weight-semibold, 600);
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.04em;
background: var(--color-surface-secondary);
position: sticky;
top: 0;
z-index: 1;
}
tbody tr:nth-child(even) {
background: var(--color-surface-secondary);
}
tbody tr:hover {
background: var(--color-nav-hover);
}
tr:last-child td {
border-bottom: none;
}
td a {
color: var(--color-brand-primary);
text-decoration: none;
font-weight: var(--font-weight-medium, 500);
}
td a:hover {
text-decoration: underline;
}
`],
changeDetection: ChangeDetectionStrategy.OnPush,
})

View File

@@ -640,7 +640,7 @@ export interface GateContext {
.btn--primary {
background: var(--color-brand-600);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--primary:hover:not(:disabled) {

View File

@@ -95,7 +95,7 @@ import { AuditAnomalyAlert } from '../../core/api/audit-log.models';
.description { color: var(--color-text-secondary); margin: 0; }
.filter-bar { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; }
.filter-bar button { padding: 0.5rem 1rem; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); cursor: pointer; }
.filter-bar button.active { background: var(--color-brand-primary); color: var(--color-text-heading); border-color: var(--color-brand-primary); }
.filter-bar button.active { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-color: var(--color-btn-primary-bg); }
.alerts-list { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem; }
.alert-card { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 1rem; }
.alert-card.warning { border-left: 4px solid var(--color-status-warning); }
@@ -112,7 +112,7 @@ import { AuditAnomalyAlert } from '../../core/api/audit-log.models';
.alert-meta { display: flex; gap: 1.5rem; font-size: 0.8rem; color: var(--color-text-secondary); margin-bottom: 0.75rem; }
.ack-info { font-size: 0.8rem; color: var(--color-text-secondary); font-style: italic; }
.alert-actions { display: flex; gap: 0.75rem; }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.5rem 1rem; border-radius: var(--radius-sm); cursor: pointer; }
.btn-primary { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border: none; padding: 0.5rem 1rem; border-radius: var(--radius-sm); cursor: pointer; }
.btn-secondary { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); padding: 0.5rem 1rem; border-radius: var(--radius-sm); text-decoration: none; color: inherit; }
.no-alerts { text-align: center; padding: 3rem; color: var(--color-text-secondary); background: var(--color-surface-primary); border-radius: var(--radius-lg); }
.anomaly-types h2 { margin: 0 0 1rem; font-size: 1.1rem; }

View File

@@ -85,7 +85,7 @@ import { AuditEvent } from '../../core/api/audit-log.models';
.description { color: var(--color-text-secondary); margin: 0; }
.tabs { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; }
.tabs button { padding: 0.5rem 1rem; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); cursor: pointer; }
.tabs button.active { background: var(--color-brand-primary); color: var(--color-text-heading); border-color: var(--color-brand-primary); }
.tabs button.active { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-color: var(--color-btn-primary-bg); }
.events-table { width: 100%; border-collapse: collapse; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); }
.events-table th, .events-table td { padding: 0.75rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); }
.events-table th { background: var(--color-surface-elevated); font-weight: var(--font-weight-semibold); font-size: 0.85rem; }

View File

@@ -189,7 +189,7 @@ import { AuditExportRequest, AuditExportResponse, AuditLogFilters, AuditModule,
.options { display: flex; flex-direction: column; gap: 0.5rem; }
.checkbox { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.actions { margin-top: 1.5rem; }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; font-size: 1rem; }
.btn-primary { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; font-size: 1rem; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.exports-list { margin-bottom: 2rem; }
.exports-list h2 { margin: 0 0 1rem; font-size: 1.1rem; }
@@ -202,7 +202,7 @@ import { AuditExportRequest, AuditExportResponse, AuditLogFilters, AuditModule,
.badge.processing { background: var(--color-status-info-bg); color: var(--color-status-info-text); }
.badge.completed { background: var(--color-status-success-bg); color: var(--color-status-success-text); }
.badge.failed { background: var(--color-status-error-bg); color: var(--color-status-error-text); }
.btn-sm { display: inline-block; padding: 0.35rem 0.75rem; background: var(--color-brand-primary); color: var(--color-text-heading); border-radius: var(--radius-sm); text-decoration: none; font-size: 0.8rem; }
.btn-sm { display: inline-block; padding: 0.35rem 0.75rem; background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-radius: var(--radius-sm); text-decoration: none; font-size: 0.8rem; }
.btn-xs { padding: 0.25rem 0.5rem; font-size: 0.75rem; cursor: pointer; background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); }
.compliance-info h2 { margin: 0 0 1rem; font-size: 1.1rem; }
.info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; }

View File

@@ -143,15 +143,31 @@ import { AuditStatsSummary, AuditEvent, AuditAnomalyAlert, AuditModule } from '.
styles: [`
.audit-dashboard { padding: 1.5rem; max-width: 1400px; margin: 0 auto; }
.page-header { margin-bottom: 2rem; }
.page-header h1 { margin: 0 0 0.25rem; }
.description { color: var(--color-text-secondary); margin: 0 0 1rem; }
.page-header h1 { margin: 0 0 0.25rem; font-size: 1.5rem; }
.description { color: var(--color-text-secondary); margin: 0 0 1rem; font-size: 0.9rem; }
.header-actions { display: flex; gap: 0.75rem; }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.5rem 1rem; border-radius: var(--radius-sm); text-decoration: none; }
.btn-secondary { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); padding: 0.5rem 1rem; border-radius: var(--radius-sm); text-decoration: none; color: inherit; }
.btn-primary {
background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text);
border: none; padding: 0.5rem 1rem; border-radius: var(--radius-sm);
text-decoration: none; font-weight: var(--font-weight-medium);
transition: opacity 150ms ease;
}
.btn-primary:hover { opacity: 0.9; }
.btn-secondary {
background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary);
padding: 0.5rem 1rem; border-radius: var(--radius-sm); text-decoration: none; color: inherit;
transition: border-color 150ms ease;
}
.btn-secondary:hover { border-color: var(--color-brand-primary); }
.stats-strip { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 2rem; }
.stat-card { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 1rem 1.5rem; min-width: 120px; text-align: center; }
.stat-value { display: block; font-size: 1.75rem; font-weight: var(--font-weight-bold); }
.stat-label { font-size: 0.8rem; color: var(--color-text-secondary); }
.stat-card {
background: var(--color-surface-primary); border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg); padding: 0.85rem 1.25rem; min-width: 120px; text-align: center;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.stat-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); }
.stat-value { display: block; font-size: 1.5rem; font-weight: var(--font-weight-bold); line-height: 1.2; }
.stat-label { font-size: 0.75rem; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.03em; }
.stat-card.policy { border-left: 4px solid var(--color-status-info); }
.stat-card.authority { border-left: 4px solid var(--color-status-excepted); }
.stat-card.vex { border-left: 4px solid var(--color-status-success); }
@@ -160,7 +176,12 @@ import { AuditStatsSummary, AuditEvent, AuditAnomalyAlert, AuditModule } from '.
.anomaly-alerts { margin-bottom: 2rem; }
.anomaly-alerts h2 { margin: 0 0 1rem; font-size: 1.1rem; }
.alert-list { display: flex; gap: 1rem; flex-wrap: wrap; }
.alert-card { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 1rem; min-width: 280px; flex: 1; }
.alert-card {
background: var(--color-surface-primary); border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg); padding: 1rem; min-width: 280px; flex: 1;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.alert-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); }
.alert-card.warning { border-left: 4px solid var(--color-status-warning); }
.alert-card.error, .alert-card.critical { border-left: 4px solid var(--color-status-error); }
.alert-header { display: flex; justify-content: space-between; margin-bottom: 0.5rem; }
@@ -169,27 +190,47 @@ import { AuditStatsSummary, AuditEvent, AuditAnomalyAlert, AuditModule } from '.
.alert-desc { font-size: 0.85rem; margin: 0 0 0.75rem; color: var(--color-text-secondary); }
.alert-footer { display: flex; justify-content: space-between; align-items: center; }
.affected { font-size: 0.75rem; color: var(--color-text-muted); }
.btn-sm { padding: 0.25rem 0.5rem; font-size: 0.8rem; cursor: pointer; background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); }
.btn-sm {
padding: 0.25rem 0.5rem; font-size: 0.8rem; cursor: pointer;
background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text);
border: none; border-radius: var(--radius-sm);
transition: opacity 150ms ease;
}
.btn-sm:hover { opacity: 0.9; }
.ack { font-size: 0.75rem; color: var(--color-text-muted); }
.quick-access { margin-bottom: 2rem; }
.quick-access h2 { margin: 0 0 1rem; font-size: 1.1rem; }
.access-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.access-card { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 1rem; text-decoration: none; color: inherit; transition: border-color 0.2s; }
.access-card:hover { border-color: var(--color-brand-primary); }
.access-card {
background: var(--color-surface-primary); border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg); padding: 1rem; text-decoration: none; color: inherit;
transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}
.access-card:hover {
border-color: var(--color-brand-primary);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.access-icon { font-size: 1.25rem; display: block; margin-bottom: 0.5rem; }
.access-label { font-weight: var(--font-weight-semibold); display: block; margin-bottom: 0.25rem; }
.access-desc { font-size: 0.8rem; color: var(--color-text-secondary); }
.recent-events { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); overflow: hidden; }
.section-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem; border-bottom: 1px solid var(--color-border-primary); }
.section-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; border-bottom: 1px solid var(--color-border-primary); }
.section-header h2 { margin: 0; font-size: 1rem; }
.link { font-size: 0.85rem; color: var(--color-brand-primary); text-decoration: none; }
.link:hover { text-decoration: underline; }
.events-table { width: 100%; border-collapse: collapse; }
.events-table th, .events-table td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); }
.events-table th { background: var(--color-surface-elevated); font-weight: var(--font-weight-semibold); font-size: 0.85rem; }
.mono { font-family: monospace; font-size: 0.8rem; }
.clickable { cursor: pointer; }
.clickable:hover { background: var(--color-surface-elevated); }
.badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.75rem; text-transform: uppercase; }
.events-table th, .events-table td { padding: 0.5rem 0.75rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); font-size: 0.84rem; }
.events-table th {
background: var(--color-surface-elevated); font-weight: var(--font-weight-semibold);
font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.03em;
position: sticky; top: 0; z-index: 1;
}
.events-table tbody tr:nth-child(even) { background: var(--color-surface-elevated); }
.mono { font-family: monospace; font-size: 0.78rem; }
.clickable { cursor: pointer; transition: background 150ms ease; }
.clickable:hover { background: rgba(59, 130, 246, 0.06); }
.badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 9999px; font-size: 0.7rem; font-weight: var(--font-weight-medium); text-transform: uppercase; letter-spacing: 0.02em; }
.badge.module { background: var(--color-surface-elevated); }
.badge.module.policy { background: var(--color-status-info-bg); color: var(--color-status-info-text); }
.badge.module.authority { background: var(--color-status-excepted-bg); color: var(--color-status-excepted); }

View File

@@ -240,33 +240,73 @@ import { AuditEvent, AuditLogFilters, AuditModule, AuditAction, AuditSeverity }
styles: [`
.audit-table-page { padding: 1.5rem; max-width: 1600px; margin: 0 auto; }
.page-header { margin-bottom: 1.5rem; }
.page-header h1 { margin: 0; font-size: 1.5rem; }
.breadcrumb { font-size: 0.85rem; color: var(--color-text-secondary); margin-bottom: 0.5rem; }
.breadcrumb a { color: var(--color-brand-primary); text-decoration: none; }
.page-header h1 { margin: 0; }
.filters-bar { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 1rem; margin-bottom: 1.5rem; }
.filter-row { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
.breadcrumb a:hover { text-decoration: underline; }
.filters-bar { background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 0.85rem 1rem; margin-bottom: 1.5rem; }
.filter-row { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 0.6rem; align-items: flex-end; }
.filter-row:last-child { margin-bottom: 0; }
.filter-group { display: flex; flex-direction: column; gap: 0.25rem; }
.filter-group label { font-size: 0.75rem; color: var(--color-text-secondary); }
.filter-group select, .filter-group input { padding: 0.5rem; border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); font-size: 0.9rem; }
.filter-group select[multiple] { height: 80px; }
.filter-group { display: flex; flex-direction: column; gap: 0.2rem; }
.filter-group label { font-size: 0.7rem; color: var(--color-text-secondary); font-weight: var(--font-weight-medium); text-transform: uppercase; letter-spacing: 0.03em; }
.filter-group select, .filter-group input {
padding: 0.4rem 0.5rem; border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm); font-size: 0.84rem;
transition: border-color 150ms ease, box-shadow 150ms ease;
}
.filter-group select:focus, .filter-group input:focus {
outline: none; border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
.filter-group select[multiple] { height: 72px; }
.search-group { flex: 1; min-width: 200px; flex-direction: row; align-items: flex-end; }
.search-group label { display: none; }
.search-group input { flex: 1; }
.btn-sm { padding: 0.5rem 0.75rem; cursor: pointer; background: var(--color-brand-primary); color: var(--color-text-heading); border: none; border-radius: var(--radius-sm); }
.btn-secondary { padding: 0.5rem 1rem; cursor: pointer; background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); align-self: flex-end; }
.loading { text-align: center; padding: 3rem; color: var(--color-text-secondary); }
.btn-sm {
padding: 0.4rem 0.75rem; cursor: pointer;
background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text);
border: none; border-radius: var(--radius-sm);
font-weight: var(--font-weight-medium); font-size: 0.84rem;
transition: opacity 150ms ease;
}
.btn-sm:hover { opacity: 0.9; }
.btn-secondary {
padding: 0.4rem 0.85rem; cursor: pointer;
background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm); align-self: flex-end; font-size: 0.84rem;
transition: border-color 150ms ease;
}
.btn-secondary:hover { border-color: var(--color-brand-primary); }
/* Loading skeleton */
.loading {
text-align: center; padding: 3rem; color: var(--color-text-secondary);
background: linear-gradient(90deg, var(--color-surface-primary) 25%, var(--color-surface-elevated) 50%, var(--color-surface-primary) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
border-radius: var(--radius-lg);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.events-table { width: 100%; border-collapse: collapse; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); overflow: hidden; }
.events-table th, .events-table td { padding: 0.75rem 0.5rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); font-size: 0.85rem; }
.events-table th { background: var(--color-surface-elevated); font-weight: var(--font-weight-semibold); position: sticky; top: 0; }
.events-table tr { cursor: pointer; }
.events-table tr:hover { background: var(--color-surface-elevated); }
.events-table th, .events-table td { padding: 0.5rem 0.75rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); font-size: 0.84rem; }
.events-table th {
background: var(--color-surface-elevated); font-weight: var(--font-weight-semibold);
position: sticky; top: 0; z-index: 1;
font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em;
}
.events-table tbody tr:nth-child(even) { background: var(--color-surface-elevated); }
.events-table tr { cursor: pointer; transition: background 150ms ease; }
.events-table tr:hover { background: rgba(59, 130, 246, 0.06); }
.events-table tr.selected { background: var(--color-status-info-bg); }
.events-table tr.error { background: var(--color-status-error-bg); }
.events-table tr.critical { background: var(--color-status-error-bg); }
.events-table tr.warning { background: var(--color-status-warning-bg); }
.mono { font-family: monospace; font-size: 0.8rem; }
.badge { display: inline-block; padding: 0.15rem 0.4rem; border-radius: var(--radius-sm); font-size: 0.7rem; text-transform: uppercase; }
.mono { font-family: monospace; font-size: 0.78rem; }
.badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 9999px; font-size: 0.68rem; font-weight: var(--font-weight-medium); text-transform: uppercase; letter-spacing: 0.02em; }
.badge.module { background: var(--color-surface-elevated); }
.badge.module.policy { background: var(--color-status-info-bg); color: var(--color-status-info-text); }
.badge.module.authority { background: var(--color-status-excepted-bg); color: var(--color-status-excepted); }
@@ -287,10 +327,31 @@ import { AuditEvent, AuditLogFilters, AuditModule, AuditAction, AuditSeverity }
.actor-type { font-size: 0.7rem; color: var(--color-text-muted); }
.resource, .description { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.link { color: var(--color-brand-primary); text-decoration: none; font-size: 0.8rem; }
.btn-xs { padding: 0.15rem 0.3rem; font-size: 0.7rem; cursor: pointer; margin-left: 0.5rem; }
.pagination { display: flex; justify-content: center; gap: 1rem; align-items: center; margin-top: 1rem; padding: 1rem; }
.pagination button { padding: 0.5rem 1rem; cursor: pointer; }
.link:hover { text-decoration: underline; }
.btn-xs {
padding: 0.15rem 0.4rem; font-size: 0.7rem; cursor: pointer; margin-left: 0.5rem;
background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm); transition: border-color 150ms ease;
}
.btn-xs:hover { border-color: var(--color-brand-primary); }
.pagination {
display: flex; justify-content: center; gap: 1rem; align-items: center;
margin-top: 1rem; padding: 0.75rem 1rem;
border-top: 1px solid var(--color-border-primary);
}
.pagination button {
padding: 0.45rem 1rem; cursor: pointer; font-size: 0.84rem;
font-weight: var(--font-weight-medium);
border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm);
background: var(--color-surface-primary);
transition: background 150ms ease, border-color 150ms ease;
}
.pagination button:hover:not(:disabled) {
background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text);
border-color: var(--color-btn-primary-bg);
}
.pagination button:disabled { opacity: 0.5; cursor: not-allowed; }
.pagination span { font-size: 0.84rem; color: var(--color-text-secondary); }
.detail-panel { position: fixed; top: 0; right: 0; width: 400px; height: 100vh; background: var(--color-surface-primary); border-left: 1px solid var(--color-border-primary); box-shadow: -4px 0 16px rgba(0,0,0,0.1); overflow-y: auto; z-index: 100; }
.panel-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem; border-bottom: 1px solid var(--color-border-primary); background: var(--color-surface-elevated); }
.panel-header h3 { margin: 0; }
@@ -299,11 +360,17 @@ import { AuditEvent, AuditLogFilters, AuditModule, AuditAction, AuditSeverity }
.detail-row { display: flex; margin-bottom: 0.75rem; }
.detail-row .label { width: 120px; font-weight: var(--font-weight-semibold); font-size: 0.85rem; color: var(--color-text-secondary); }
.detail-row .value { flex: 1; font-size: 0.85rem; word-break: break-all; }
.tag { display: inline-block; background: var(--color-surface-elevated); padding: 0.15rem 0.4rem; border-radius: var(--radius-sm); font-size: 0.75rem; margin-right: 0.25rem; }
.tag { display: inline-block; background: var(--color-surface-elevated); padding: 0.15rem 0.5rem; border-radius: 9999px; font-size: 0.72rem; margin-right: 0.25rem; }
.detail-section { margin-top: 1rem; }
.detail-section h4 { margin: 0 0 0.5rem; font-size: 0.9rem; }
.json-block { background: var(--color-surface-elevated); padding: 0.75rem; border-radius: var(--radius-sm); font-size: 0.75rem; overflow-x: auto; max-height: 200px; }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.5rem 1rem; border-radius: var(--radius-sm); cursor: pointer; margin-top: 1rem; }
.btn-primary {
background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text);
border: none; padding: 0.5rem 1rem; border-radius: var(--radius-sm);
cursor: pointer; margin-top: 1rem; font-weight: var(--font-weight-medium);
transition: opacity 150ms ease;
}
.btn-primary:hover { opacity: 0.9; }
.diff-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 200; }
.diff-modal { background: var(--color-surface-primary); border-radius: var(--radius-lg); width: 90%; max-width: 1000px; max-height: 80vh; overflow: hidden; display: flex; flex-direction: column; }
.modal-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem; border-bottom: 1px solid var(--color-border-primary); }
@@ -317,7 +384,7 @@ import { AuditEvent, AuditLogFilters, AuditModule, AuditAction, AuditSeverity }
.diff-pane.after h4 { background: var(--color-status-success-bg); color: var(--color-status-success-text); }
.diff-pane pre { margin: 0; padding: 0.75rem; font-size: 0.75rem; max-height: 400px; overflow: auto; }
.changed-fields { margin-top: 1rem; font-size: 0.85rem; }
.field-badge { display: inline-block; background: var(--color-status-warning-bg); color: var(--color-status-warning-text); padding: 0.15rem 0.4rem; border-radius: var(--radius-sm); margin-left: 0.5rem; font-size: 0.75rem; }
.field-badge { display: inline-block; background: var(--color-status-warning-bg); color: var(--color-status-warning-text); padding: 0.15rem 0.5rem; border-radius: 9999px; margin-left: 0.5rem; font-size: 0.72rem; }
`]
})
export class AuditLogTableComponent implements OnInit {

View File

@@ -85,7 +85,7 @@ import { AuditEvent } from '../../core/api/audit-log.models';
.description { color: var(--color-text-secondary); margin: 0; }
.event-categories { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; }
.event-categories button { padding: 0.5rem 1rem; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); cursor: pointer; }
.event-categories button.active { background: var(--color-brand-primary); color: var(--color-text-heading); border-color: var(--color-brand-primary); }
.event-categories button.active { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-color: var(--color-btn-primary-bg); }
.events-table { width: 100%; border-collapse: collapse; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); }
.events-table th, .events-table td { padding: 0.75rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); }
.events-table th { background: var(--color-surface-elevated); font-weight: var(--font-weight-semibold); font-size: 0.85rem; }

View File

@@ -75,7 +75,7 @@ function mapActionToKind(action: string): TimelineEventKind {
.date-filters { display: flex; align-items: center; gap: 0.5rem; }
.date-filters input { padding: 0.5rem; border: 1px solid var(--color-border-primary); border-radius: var(--radius-sm); }
.date-filters span { color: var(--color-text-secondary); }
.btn-primary { background: var(--color-brand-primary); color: var(--color-text-heading); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; }
.btn-primary { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border: none; padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); cursor: pointer; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.event-badges { display: flex; gap: 0.25rem; margin-top: 0.25rem; flex-wrap: wrap; }

View File

@@ -173,7 +173,7 @@ import { readReleaseInvestigationQueryState } from '../release-investigation/rel
.btn-primary {
background: var(--color-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
&:hover:not(:disabled) {
background: var(--color-primary-hover);

View File

@@ -365,7 +365,7 @@ import {
.btn-primary {
background: var(--theme-brand-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn-primary:hover:not(:disabled) {

View File

@@ -604,7 +604,7 @@ import {
.btn-primary {
background: var(--theme-brand-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -198,19 +198,28 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
background: var(--theme-bg-secondary);
border: 1px solid var(--theme-border-primary);
border-radius: var(--radius-lg);
padding: 16px;
padding: 12px 16px;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.stat-label {
font-size: var(--font-size-base);
font-size: 0.75rem;
color: var(--theme-text-secondary);
margin-bottom: 8px;
margin-bottom: 4px;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.stat-value {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-semibold);
color: var(--theme-brand-primary);
line-height: 1.2;
}
.admin-table {
@@ -228,17 +237,25 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
.admin-table th,
.admin-table td {
padding: 12px;
padding: 0.5rem 0.75rem;
text-align: left;
border-bottom: 1px solid var(--theme-border-primary);
font-size: var(--font-size-base);
font-size: 0.84rem;
}
.admin-table th {
font-weight: var(--font-weight-semibold);
font-size: var(--font-size-sm);
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--theme-text-secondary);
position: sticky;
top: 0;
z-index: 1;
}
.admin-table tbody tr:nth-child(even) {
background: var(--theme-bg-tertiary);
}
.admin-table tbody tr:hover {
@@ -253,11 +270,12 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
.event-badge {
display: inline-block;
padding: 4px 8px;
border-radius: var(--radius-sm);
font-size: var(--font-size-xs);
padding: 0.15rem 0.5rem;
border-radius: 9999px;
font-size: 0.7rem;
font-weight: var(--font-weight-medium);
font-family: 'Monaco', 'Courier New', monospace;
letter-spacing: 0.02em;
}
.event-badge.event-create {
@@ -292,12 +310,15 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
display: flex;
justify-content: center;
align-items: center;
gap: 16px;
padding: 16px;
gap: 1rem;
padding: 0.75rem 1rem;
border-top: 1px solid var(--theme-border-primary);
}
.page-info {
font-weight: var(--font-weight-medium);
font-size: 0.84rem;
color: var(--theme-text-secondary);
}
.modal-overlay {
@@ -390,21 +411,23 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
.btn-primary,
.btn-secondary,
.btn-sm {
padding: 8px 16px;
padding: 0.45rem 1rem;
border: none;
border-radius: var(--radius-sm);
font-size: var(--font-size-base);
font-size: 0.84rem;
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: opacity 150ms ease, border-color 150ms ease, background 150ms ease;
}
.btn-secondary {
background: var(--theme-bg-tertiary);
color: var(--theme-text-primary);
border: 1px solid var(--theme-border-primary);
}
.btn-secondary:hover:not(:disabled) {
background: var(--theme-bg-hover);
border-color: var(--color-brand-primary, var(--theme-brand-primary));
}
.btn-secondary:disabled {
@@ -413,14 +436,15 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
}
.btn-sm {
padding: 4px 12px;
font-size: var(--font-size-sm);
background: var(--theme-bg-tertiary);
color: var(--theme-text-primary);
padding: 0.25rem 0.75rem;
font-size: 0.8rem;
background: var(--color-btn-primary-bg, var(--theme-brand-primary));
color: var(--color-btn-primary-text, white);
border: none;
}
.btn-sm:hover {
background: var(--theme-bg-hover);
opacity: 0.9;
}
.alert {
@@ -434,11 +458,27 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../../shared/
color: white;
}
.loading,
.loading {
text-align: center;
padding: 48px;
color: var(--theme-text-secondary);
background: linear-gradient(90deg, var(--theme-bg-secondary, var(--color-surface-primary)) 25%, var(--theme-bg-tertiary, var(--color-surface-elevated)) 50%, var(--theme-bg-secondary, var(--color-surface-primary)) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
border-radius: var(--radius-lg);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.empty-state {
text-align: center;
padding: 48px;
color: var(--theme-text-secondary);
border: 1px dashed var(--theme-border-primary);
border-radius: var(--radius-lg);
}
code {

View File

@@ -246,98 +246,137 @@ interface ThemeToken {
`,
styles: [`
.admin-panel {
padding: 24px;
max-width: 1000px;
}
.admin-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
margin-bottom: var(--space-6, 1.5rem);
}
.admin-header h1 {
margin: 0;
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-semibold);
color: var(--color-text-heading);
}
.header-actions {
display: flex;
gap: 12px;
gap: 0.625rem;
}
.branding-sections {
display: flex;
flex-direction: column;
gap: 24px;
gap: var(--space-5, 1.25rem);
}
.branding-section {
background: var(--theme-bg-secondary);
border: 1px solid var(--theme-border-primary);
background: var(--color-surface-primary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
padding: 24px;
padding: var(--space-5, 1.25rem);
transition: border-color 150ms ease;
}
.branding-section:hover {
border-color: var(--color-border-secondary);
}
.branding-section h2 {
margin: 0 0 16px 0;
font-size: var(--font-size-lg);
margin: 0 0 var(--space-4, 1rem) 0;
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
color: var(--color-text-heading);
padding-bottom: 0.625rem;
border-bottom: 1px solid var(--color-border-primary);
}
.branding-section h3 {
margin: 16px 0 12px 0;
font-size: var(--font-size-md);
margin: var(--space-4, 1rem) 0 0.625rem 0;
font-size: var(--font-size-base);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
}
.section-info {
margin-bottom: 16px;
color: var(--theme-text-secondary);
font-size: var(--font-size-base);
margin-bottom: var(--space-4, 1rem);
color: var(--color-text-secondary);
font-size: var(--font-size-sm, 0.75rem);
line-height: var(--line-height-base, 1.5);
}
.form-group {
margin-bottom: 16px;
margin-bottom: var(--space-4, 1rem);
}
.form-group label {
display: block;
margin-bottom: 6px;
margin-bottom: 0.375rem;
font-size: var(--font-size-sm, 0.75rem);
font-weight: var(--font-weight-medium);
color: var(--color-text-primary);
}
.form-group input {
width: 100%;
padding: 8px 12px;
border: 1px solid var(--theme-border-primary);
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
font-size: var(--font-size-base);
background: var(--color-surface-primary);
color: var(--color-text-primary);
outline: none;
transition:
border-color 150ms ease,
box-shadow 150ms ease;
}
.form-group input:hover:not(:disabled):not(:focus) {
border-color: var(--color-border-secondary);
}
.form-group input:focus {
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.form-hint {
display: block;
margin-top: 4px;
font-size: var(--font-size-sm);
color: var(--theme-text-secondary);
margin-top: 0.25rem;
font-size: var(--font-size-xs, 0.6875rem);
color: var(--color-text-muted);
}
.asset-upload {
margin-bottom: 24px;
margin-bottom: var(--space-5, 1.25rem);
}
.asset-upload > label {
display: block;
margin-bottom: 8px;
margin-bottom: 0.375rem;
font-size: var(--font-size-sm, 0.75rem);
font-weight: var(--font-weight-medium);
color: var(--color-text-primary);
}
.upload-area {
border: 2px dashed var(--theme-border-primary);
border: 2px dashed var(--color-border-primary);
border-radius: var(--radius-lg);
padding: 24px;
padding: var(--space-5, 1.25rem);
text-align: center;
background: var(--color-surface-secondary);
transition:
border-color 200ms ease,
background-color 200ms ease;
}
.upload-area:hover {
border-color: var(--color-brand-primary);
background: var(--color-brand-primary-10, rgba(245, 166, 35, 0.1));
}
.upload-placeholder input[type="file"] {
@@ -346,198 +385,286 @@ interface ThemeToken {
.upload-placeholder small {
display: block;
margin-top: 8px;
color: var(--theme-text-secondary);
margin-top: 0.5rem;
color: var(--color-text-muted);
font-size: var(--font-size-xs, 0.6875rem);
}
.asset-preview {
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
gap: 1rem;
}
.logo-preview {
max-width: 200px;
max-height: 60px;
border-radius: var(--radius-sm);
}
.favicon-preview {
width: 32px;
height: 32px;
border-radius: var(--radius-sm);
}
.theme-category {
margin-bottom: 24px;
margin-bottom: var(--space-5, 1.25rem);
}
.token-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 0.875rem;
}
.token-item {
padding: 0.625rem;
background: var(--color-surface-secondary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
transition: border-color 150ms ease;
}
.token-item:hover {
border-color: var(--color-border-secondary);
}
.token-item label {
display: block;
margin-bottom: 6px;
font-size: var(--font-size-base);
margin-bottom: 0.375rem;
font-size: var(--font-size-xs, 0.6875rem);
font-weight: var(--font-weight-medium);
color: var(--color-text-secondary);
text-transform: capitalize;
}
.token-input-group {
display: flex;
gap: 8px;
gap: 0.375rem;
}
.token-input {
flex: 1;
padding: 8px 12px;
border: 1px solid var(--theme-border-primary);
padding: 0.375rem 0.625rem;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
font-size: var(--font-size-base);
font-family: 'Monaco', 'Courier New', monospace;
font-size: var(--font-size-sm, 0.75rem);
font-family: var(--font-family-mono, monospace);
background: var(--color-surface-primary);
color: var(--color-text-primary);
outline: none;
transition:
border-color 150ms ease,
box-shadow 150ms ease;
}
.token-input:focus {
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.color-picker {
width: 48px;
height: 38px;
border: 1px solid var(--theme-border-primary);
width: 2.25rem;
height: 2rem;
padding: 2px;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
cursor: pointer;
background: var(--color-surface-primary);
transition: border-color 150ms ease;
}
.color-picker:hover {
border-color: var(--color-brand-primary);
}
.add-token-form {
display: flex;
gap: 12px;
gap: 0.5rem;
align-items: center;
padding: 0.75rem;
background: var(--color-surface-secondary);
border: 1px dashed var(--color-border-primary);
border-radius: var(--radius-md);
}
.token-key-input,
.token-value-input {
flex: 1;
padding: 8px 12px;
border: 1px solid var(--theme-border-primary);
padding: 0.375rem 0.625rem;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
font-size: var(--font-size-base);
font-size: var(--font-size-sm, 0.75rem);
background: var(--color-surface-primary);
color: var(--color-text-primary);
outline: none;
transition:
border-color 150ms ease,
box-shadow 150ms ease;
}
.token-key-input:focus,
.token-value-input:focus {
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.preview-panel {
border: 1px solid var(--theme-border-primary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-sm);
}
.preview-header {
padding: 16px 24px;
padding: 0.875rem 1.25rem;
display: flex;
align-items: center;
gap: 16px;
gap: 0.75rem;
}
.preview-logo img {
max-height: 40px;
max-height: 36px;
}
.preview-title {
font-size: var(--font-size-lg);
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
}
.preview-content {
padding: 24px;
padding: 1.25rem;
}
.preview-card {
padding: 20px;
padding: 1rem;
border-radius: var(--radius-lg);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
box-shadow: var(--shadow-sm);
}
.preview-card h4 {
margin: 0 0 12px 0;
font-size: var(--font-size-md);
margin: 0 0 0.625rem 0;
font-size: var(--font-size-base);
font-weight: var(--font-weight-semibold);
}
.preview-card p {
margin: 0 0 16px 0;
font-size: var(--font-size-base);
margin: 0 0 0.875rem 0;
font-size: var(--font-size-sm, 0.75rem);
line-height: var(--line-height-base, 1.5);
}
.preview-button {
padding: 8px 16px;
padding: 0.4375rem 0.875rem;
border: none;
border-radius: var(--radius-sm);
font-size: var(--font-size-sm, 0.75rem);
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: opacity 150ms ease;
}
.preview-button:hover {
opacity: 0.9;
}
.btn-primary,
.btn-secondary,
.btn-sm {
padding: 8px 16px;
padding: 0.4375rem 0.875rem;
border: none;
border-radius: var(--radius-sm);
font-size: var(--font-size-base);
font-size: var(--font-size-sm, 0.75rem);
font-weight: var(--font-weight-medium);
cursor: pointer;
transition:
background-color 150ms ease,
color 150ms ease,
opacity 150ms ease;
}
.btn-primary {
background: var(--theme-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-primary:hover:not(:disabled) {
background: var(--theme-brand-hover);
background: var(--color-brand-primary-hover);
}
.btn-primary:active:not(:disabled) {
transform: translateY(1px);
}
.btn-primary:disabled {
background: var(--theme-bg-tertiary);
color: var(--theme-text-secondary);
background: var(--color-surface-tertiary);
color: var(--color-text-muted);
cursor: not-allowed;
}
.btn-secondary {
background: var(--theme-bg-tertiary);
color: var(--theme-text-primary);
background: var(--color-surface-tertiary);
color: var(--color-text-primary);
border: 1px solid var(--color-border-primary);
}
.btn-secondary:hover:not(:disabled) {
background: var(--theme-bg-hover);
background: var(--color-surface-secondary);
border-color: var(--color-border-secondary);
}
.btn-sm {
padding: 4px 12px;
font-size: var(--font-size-sm);
background: var(--theme-bg-tertiary);
color: var(--theme-text-primary);
padding: 0.25rem 0.625rem;
font-size: var(--font-size-xs, 0.6875rem);
background: var(--color-surface-tertiary);
color: var(--color-text-primary);
border: 1px solid var(--color-border-primary);
}
.btn-sm.btn-danger {
background: var(--theme-status-error);
background: var(--color-status-error-bg);
color: var(--color-status-error-text);
border-color: var(--color-status-error-border);
}
.btn-sm.btn-danger:hover {
background: var(--color-severity-critical);
color: white;
}
.alert {
padding: 12px 16px;
border-radius: var(--radius-sm);
margin-bottom: 16px;
padding: 0.625rem 0.875rem;
border-radius: var(--radius-md);
margin-bottom: var(--space-4, 1rem);
font-size: var(--font-size-sm, 0.75rem);
line-height: var(--line-height-base, 1.5);
}
.alert-info {
background: var(--color-status-info-bg);
color: var(--color-status-info-text);
border: 1px solid var(--color-status-info-border);
}
.alert-error {
background: var(--theme-status-error);
color: white;
background: var(--color-status-error-bg);
color: var(--color-status-error-text);
border: 1px solid var(--color-status-error-border);
}
.alert-success {
background: var(--theme-status-success);
color: white;
background: var(--color-status-success-bg);
color: var(--color-status-success-text);
border: 1px solid var(--color-status-success-border);
}
.loading {
text-align: center;
padding: 48px;
color: var(--theme-text-secondary);
padding: var(--space-12, 3rem);
color: var(--color-text-muted);
font-size: var(--font-size-sm, 0.75rem);
}
`]
})

View File

@@ -379,7 +379,7 @@ import { InlineCodeComponent } from '../../../shared/ui/inline-code/inline-code.
.btn-primary {
background: var(--theme-brand-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn-primary:hover:not(:disabled) {

View File

@@ -495,7 +495,7 @@ interface RoleBundle {
.btn-primary {
background: var(--theme-brand-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn-primary:hover:not(:disabled) {

View File

@@ -291,7 +291,7 @@ import { InlineCodeComponent } from '../../../shared/ui/inline-code/inline-code.
.btn-primary {
background: var(--theme-brand-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn-primary:hover:not(:disabled) {

View File

@@ -104,8 +104,8 @@ import { AuthSessionStore } from '../../core/auth/auth-session.store';
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -480,17 +480,17 @@ interface AdvisoryFeedSummary {
padding: 0.4rem 1rem;
font-size: 0.8rem;
font-weight: var(--font-weight-semibold);
border: 1px solid var(--color-border-primary);
border: none;
border-radius: var(--radius-md);
background: var(--color-surface-elevated);
color: var(--color-text-primary);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
cursor: pointer;
transition: background 0.15s, border-color 0.15s;
transition: opacity 150ms ease, transform 150ms ease;
}
.refresh-btn:hover:not(:disabled) {
background: var(--color-surface-primary);
border-color: var(--color-brand-primary);
opacity: 0.9;
transform: translateY(-1px);
}
.refresh-btn:disabled {
@@ -538,11 +538,13 @@ interface AdvisoryFeedSummary {
text-decoration: none;
color: inherit;
background: var(--color-surface-elevated);
transition: border-color 0.15s;
transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}
.setup-step:hover {
border-color: var(--color-brand-primary);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.step-number {
@@ -595,6 +597,12 @@ interface AdvisoryFeedSummary {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
overflow: hidden;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.posture-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.posture-card-header {
@@ -623,6 +631,16 @@ interface AdvisoryFeedSummary {
margin: 0;
font-size: 0.8rem;
color: var(--color-text-muted);
background: linear-gradient(90deg, var(--color-surface-elevated) 25%, var(--color-surface-primary) 50%, var(--color-surface-elevated) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: var(--radius-sm);
padding: 0.5rem;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.card-empty {
@@ -795,6 +813,12 @@ interface AdvisoryFeedSummary {
display: flex;
flex-direction: column;
gap: 0.15rem;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.summary-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.summary-card.warning {
@@ -861,6 +885,12 @@ interface AdvisoryFeedSummary {
border-radius: var(--radius-md);
overflow: hidden;
background: var(--color-surface-elevated);
transition: transform 150ms ease, box-shadow 150ms ease;
}
.env-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.env-card.healthy { border-top: 3px solid var(--color-status-success); }
@@ -996,6 +1026,10 @@ interface AdvisoryFeedSummary {
letter-spacing: 0.04em;
}
.risk-table__table tbody tr:hover {
background: var(--color-nav-hover);
}
.risk-table__table td a {
color: var(--color-brand-primary);
text-decoration: none;
@@ -1040,12 +1074,14 @@ interface AdvisoryFeedSummary {
color: var(--color-text-primary);
text-decoration: none;
background: var(--color-surface-elevated);
transition: background 0.15s;
transition: background 150ms ease, border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}
.domain-nav-item:hover {
background: var(--color-surface-primary);
border-color: var(--color-brand-primary);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
/* -- Footer: Platform Health Bar ----------------------------------------- */

View File

@@ -432,7 +432,7 @@ import { ContextHeaderComponent } from '../../shared/ui/context-header/context-h
.btn:hover:not(:disabled) { background: var(--color-surface-tertiary); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--color-primary); color: var(--color-text-heading); border-color: var(--color-primary); }
.btn-primary { background: var(--color-primary); color: var(--color-btn-primary-text); border-color: var(--color-primary); }
.btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }
.btn-icon { padding: 0.5rem; }
.spinning { animation: spin 1s linear infinite; }

View File

@@ -399,7 +399,7 @@ import { deadLetterQueuePath, jobEngineJobPath } from '../platform/ops/operation
.btn:hover:not(:disabled) { background: var(--color-surface-tertiary); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--color-primary); color: var(--color-text-heading); border-color: var(--color-primary); }
.btn-primary { background: var(--color-primary); color: var(--color-btn-primary-text); border-color: var(--color-primary); }
.btn-secondary { background: var(--color-surface-secondary); }
.btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }
.btn-close { background: none; border: none; font-size: 1.5rem; cursor: pointer; }

View File

@@ -354,7 +354,7 @@ interface DeploymentArtifact {
.tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--color-border-primary); margin-bottom: 1.5rem; overflow-x: auto; }
.tab { padding: 0.75rem 1rem; background: transparent; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; font-size: 0.875rem; font-weight: var(--font-weight-medium); color: var(--color-text-secondary); cursor: pointer; white-space: nowrap; }
.tab:hover { color: var(--color-text-primary); }
.tab--active { color: var(--color-brand-primary); border-bottom-color: var(--color-brand-primary); }
.tab--active { color: var(--color-tab-active-text, var(--color-text-primary)); border-bottom-color: var(--color-tab-active-border, var(--color-brand-primary)); font-weight: 600; }
/* Panel */
.panel { padding: 1.25rem; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); }
@@ -451,7 +451,7 @@ interface DeploymentArtifact {
.btn--sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }
.btn--secondary { background: var(--color-surface-secondary); border: 1px solid var(--color-border-primary); color: var(--color-text-primary); }
.btn--secondary:hover { background: var(--color-nav-hover); }
.btn--secondary.active { background: var(--color-brand-primary); color: white; border-color: var(--color-brand-primary); }
.btn--secondary.active { background: var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-color: var(--color-btn-primary-bg); }
@media (max-width: 768px) {
.evidence-summary { grid-template-columns: 1fr; }

View File

@@ -129,7 +129,7 @@ interface Deployment {
.deployments-page { max-width: 1400px; margin: 0 auto; }
.page-header { margin-bottom: 1.5rem; }
.page-title { margin: 0 0 0.25rem; font-size: 1.5rem; font-weight: var(--font-weight-semibold); }
.page-subtitle { margin: 0; color: var(--color-text-secondary); }
.page-subtitle { margin: 0; color: var(--color-text-secondary); font-size: 0.875rem; }
.table-container {
background: var(--color-surface-primary);
@@ -139,15 +139,42 @@ interface Deployment {
overflow-y: hidden;
}
.data-table { width: 100%; min-width: 840px; border-collapse: collapse; }
.data-table th, .data-table td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--color-border-primary); }
.data-table th { background: var(--color-surface-secondary); font-size: 0.75rem; font-weight: var(--font-weight-semibold); color: var(--color-text-secondary); text-transform: uppercase; }
.data-table th, .data-table td {
padding: 0.5rem 0.75rem;
text-align: left;
border-bottom: 1px solid var(--color-border-primary);
}
.data-table th {
background: var(--color-surface-secondary);
font-size: 0.6875rem;
font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.04em;
position: sticky;
top: 0;
z-index: 1;
}
.data-table td { font-size: 0.8125rem; }
.data-table tbody tr:nth-child(even) { background: var(--color-surface-secondary); }
.data-table tbody tr:hover { background: var(--color-nav-hover); }
.data-table a { color: var(--color-brand-primary); text-decoration: none; }
.data-table a:hover { text-decoration: underline; }
.deployment-link { font-family: ui-monospace, SFMono-Regular, monospace; font-weight: var(--font-weight-medium); }
.release-version { font-family: ui-monospace, SFMono-Regular, monospace; color: var(--color-text-primary); }
.release-version { font-family: ui-monospace, SFMono-Regular, monospace; color: var(--color-text-primary); font-size: 0.8125rem; }
.status-badge { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.125rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.625rem; font-weight: var(--font-weight-semibold); }
.status-badge {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.125rem 0.625rem;
border-radius: 9999px;
font-size: 0.6875rem;
font-weight: var(--font-weight-semibold);
text-transform: uppercase;
letter-spacing: 0.03em;
}
.status-badge--running { background: var(--color-severity-info-bg); color: var(--color-status-info-text); }
.status-badge--success { background: var(--color-severity-low-bg); color: var(--color-status-success-text); }
.status-badge--failed { background: var(--color-severity-critical-bg); color: var(--color-status-error-text); }
@@ -163,20 +190,43 @@ interface Deployment {
}
@keyframes spin { to { transform: rotate(360deg); } }
.btn { padding: 0.25rem 0.5rem; border-radius: var(--radius-md); font-size: 0.75rem; font-weight: var(--font-weight-medium); text-decoration: none; background: var(--color-surface-secondary); border: 1px solid var(--color-border-primary); color: var(--color-text-primary); }
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.25rem 0.5rem;
border-radius: var(--radius-md);
font-size: 0.75rem;
font-weight: var(--font-weight-medium);
text-decoration: none;
background: var(--color-surface-secondary);
border: 1px solid var(--color-border-primary);
color: var(--color-text-primary);
transition: opacity 150ms ease, transform 150ms ease;
}
.btn:hover {
opacity: 0.85;
transform: translateY(-1px);
}
.deployment-cards {
display: none;
gap: 0.6rem;
gap: 0.75rem;
}
.deployment-card {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
background: var(--color-surface-primary);
padding: 0.7rem;
padding: 0.75rem;
display: grid;
gap: 0.6rem;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.deployment-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.deployment-card__header {
@@ -187,7 +237,7 @@ interface Deployment {
}
.deployment-card__id {
font-size: 0.84rem;
font-size: 0.875rem;
}
.deployment-card__meta {
@@ -204,7 +254,7 @@ interface Deployment {
.deployment-card__meta dt {
margin: 0;
font-size: 0.62rem;
font-size: 0.625rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--color-text-secondary);
@@ -212,7 +262,7 @@ interface Deployment {
.deployment-card__meta dd {
margin: 0;
font-size: 0.84rem;
font-size: 0.8125rem;
color: var(--color-text-primary);
line-height: 1.25;
}
@@ -224,9 +274,9 @@ interface Deployment {
@media (max-width: 768px) {
.deployments-page { max-width: none; }
.page-title { font-size: 2rem; line-height: 1.05; }
.page-subtitle { font-size: 0.95rem; line-height: 1.35; }
.data-table th, .data-table td { padding: 0.625rem 0.75rem; }
.page-title { font-size: 1.75rem; line-height: 1.1; }
.page-subtitle { font-size: 0.875rem; line-height: 1.35; }
.data-table th, .data-table td { padding: 0.5rem 0.75rem; }
.table-container--desktop { display: none; }
.deployment-cards { display: grid; }
.deployment-card__meta { grid-template-columns: 1fr; }

View File

@@ -283,9 +283,9 @@ type ExportFormat = 'json' | 'markdown' | 'text' | 'dsse';
}
.btn-primary {
background: var(--color-brand-primary);
border: 1px solid var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
border: 1px solid var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
&:hover {
background: var(--color-brand-secondary);

View File

@@ -47,7 +47,7 @@
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: all var(--motion-duration-fast) var(--motion-ease-default);
transition: all 150ms ease;
border: 1px solid transparent;
&:disabled {
@@ -55,28 +55,35 @@
cursor: not-allowed;
}
&:active:not(:disabled) {
transform: translateY(1px);
}
.btn-icon {
font-size: var(--font-size-md);
display: inline-flex;
align-items: center;
}
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-inverse);
border-color: var(--color-brand-primary);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-color: var(--color-btn-primary-bg);
&:hover:not(:disabled) {
background: var(--color-brand-primary-hover);
filter: brightness(1.1);
}
}
.btn-secondary {
background: var(--color-status-info);
color: var(--color-text-inverse);
border-color: var(--color-status-info);
background: var(--color-surface-secondary);
color: var(--color-text-primary);
border-color: var(--color-border-primary);
&:hover:not(:disabled) {
filter: brightness(0.9);
border-color: var(--color-brand-primary);
background: var(--color-surface-primary);
}
}
@@ -87,6 +94,7 @@
&:hover:not(:disabled) {
background: var(--color-surface-secondary);
border-color: var(--color-brand-primary);
}
}
@@ -132,9 +140,22 @@
.progress-fill {
height: 100%;
background: var(--color-brand-primary);
background-image: linear-gradient(
90deg,
var(--color-brand-primary) 0%,
rgba(255, 255, 255, 0.2) 50%,
var(--color-brand-primary) 100%
);
background-size: 200% 100%;
animation: shimmer-progress 1.5s infinite ease-in-out;
transition: width 0.3s ease;
}
@keyframes shimmer-progress {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.progress-info {
display: flex;
justify-content: space-between;
@@ -226,6 +247,13 @@
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
padding: var(--space-3);
transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border-color: var(--color-brand-primary);
}
}
.pack-header {
@@ -349,11 +377,12 @@
color: var(--color-text-primary);
cursor: pointer;
min-width: 150px;
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 3px var(--color-brand-light);
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}
}
@@ -402,11 +431,12 @@
font-size: var(--font-size-base);
background: var(--color-surface-primary);
color: var(--color-text-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 3px var(--color-brand-light);
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}
&::placeholder {

View File

@@ -383,7 +383,7 @@ interface GateSummary {
.tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--color-border-primary); margin-bottom: 1.5rem; }
.tab { padding: 0.75rem 1rem; background: transparent; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; font-size: 0.875rem; font-weight: var(--font-weight-medium); color: var(--color-text-secondary); cursor: pointer; }
.tab:hover { color: var(--color-text-primary); }
.tab--active { color: var(--color-brand-primary); border-bottom-color: var(--color-brand-primary); }
.tab--active { color: var(--color-tab-active-text, var(--color-text-primary)); border-bottom-color: var(--color-tab-active-border, var(--color-brand-primary)); font-weight: 600; }
/* Overview Layout */
.overview-layout { display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem; }
@@ -474,8 +474,8 @@ interface GateSummary {
/* Buttons */
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; text-decoration: none; }
.btn--primary { background: var(--color-brand-primary); border: none; color: var(--color-text-heading); }
.btn--primary:hover { background: var(--color-brand-primary); }
.btn--primary { background: var(--color-btn-primary-bg); border: none; color: var(--color-btn-primary-text); }
.btn--primary:hover { background: var(--color-btn-primary-bg-hover); }
.btn--secondary { background: var(--color-surface-secondary); border: 1px solid var(--color-border-primary); color: var(--color-text-primary); }
.btn--secondary:hover { background: var(--color-nav-hover); }
.btn--sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }

View File

@@ -108,7 +108,7 @@ interface Environment {
.drift-badge--unknown { background: var(--color-severity-none-bg); color: var(--color-text-secondary); }
.btn { padding: 0.5rem 1rem; border-radius: var(--radius-md); font-size: 0.875rem; font-weight: var(--font-weight-medium); cursor: pointer; }
.btn--primary { background: var(--color-brand-primary); border: none; color: var(--color-text-heading); }
.btn--primary { background: var(--color-btn-primary-bg); border: none; color: var(--color-btn-primary-text); }
`]
})
export class EnvironmentsListPageComponent {

View File

@@ -315,6 +315,14 @@ type EvidenceHomeMode = 'normal' | 'degraded' | 'empty';
font-size: 0.84rem;
background: var(--color-surface-primary);
color: var(--color-text-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
}
.search-field select:focus,
.lookup-field input:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
.search-actions {
@@ -323,13 +331,19 @@ type EvidenceHomeMode = 'normal' | 'degraded' | 'empty';
}
.search-actions button {
border: 1px solid var(--color-brand-primary);
background: var(--color-brand-primary);
color: var(--color-text-inverse, #fff);
border: none;
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-radius: var(--radius-sm);
padding: 0.45rem 0.8rem;
font-size: 0.82rem;
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: opacity 150ms ease;
}
.search-actions button:hover {
opacity: 0.9;
}
.quick-views-grid {
@@ -346,6 +360,13 @@ type EvidenceHomeMode = 'normal' | 'degraded' | 'empty';
display: flex;
flex-direction: column;
gap: 0.35rem;
transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
}
.quick-view-tile:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border-color: var(--color-brand-primary);
}
.quick-view-header {
@@ -418,19 +439,25 @@ type EvidenceHomeMode = 'normal' | 'degraded' | 'empty';
.stat-item {
display: flex;
flex-direction: column;
gap: 0.25rem;
gap: 0.15rem;
padding: 0.75rem;
border-radius: var(--radius-md);
background: var(--color-surface-primary);
}
.stat-item.warning .stat-value { color: var(--color-status-warning); }
.stat-value {
font-size: 1.75rem;
font-size: 1.5rem;
font-weight: var(--font-weight-bold);
line-height: 1.2;
}
.stat-label {
font-size: 0.8rem;
font-size: 0.75rem;
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.03em;
}
/* Cross Links */
@@ -450,12 +477,14 @@ type EvidenceHomeMode = 'normal' | 'degraded' | 'empty';
background: var(--color-surface-elevated);
text-decoration: none;
color: var(--color-text-primary);
transition: background 0.15s;
transition: background 150ms ease, border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}
.cross-link:hover {
background: var(--color-surface-primary);
border-color: var(--color-brand-primary);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.cross-link-icon {

View File

@@ -397,8 +397,8 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
border: none;
&.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
&.btn-secondary {

View File

@@ -411,15 +411,17 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
border-bottom: 2px solid transparent;
cursor: pointer;
font-weight: var(--font-weight-medium);
color: var(--color-text-secondary);
color: var(--color-tab-inactive-text, var(--color-text-secondary));
transition: color 150ms ease, border-color 150ms ease;
&:hover {
color: var(--color-text-primary);
}
&.active {
color: var(--color-brand-primary);
border-bottom-color: var(--color-brand-primary);
color: var(--color-tab-active-text, var(--color-brand-primary));
border-bottom: 2px solid var(--color-tab-active-border, var(--color-brand-primary));
font-weight: 600;
}
}
@@ -437,11 +439,19 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
.profile-card {
background: var(--color-surface-secondary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border-color: var(--color-brand-primary);
}
.profile-header {
display: flex;
@@ -457,7 +467,7 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
.format-badge {
padding: 0.25rem 0.5rem;
background: var(--color-surface-tertiary);
border-radius: var(--radius-sm);
border-radius: 9999px;
font-size: 0.75rem;
font-weight: var(--font-weight-medium);
text-transform: uppercase;
@@ -487,10 +497,10 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
}
.badge {
padding: 0.125rem 0.375rem;
padding: 0.15rem 0.5rem;
background: var(--color-status-info-bg);
color: var(--color-status-info);
border-radius: 0.125rem;
border-radius: 9999px;
font-size: 0.6875rem;
font-weight: var(--font-weight-medium);
@@ -551,6 +561,13 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
background: var(--color-surface-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
}
}
@@ -596,13 +613,20 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
}
.run-status {
padding: 0.25rem 0.5rem;
border-radius: var(--radius-sm);
font-size: 0.75rem;
padding: 0.25rem 0.6rem;
border-radius: 9999px;
font-size: 0.7rem;
font-weight: var(--font-weight-medium);
text-transform: uppercase;
letter-spacing: 0.02em;
background: var(--color-surface-tertiary);
}
&.status-pending .run-status { background: var(--color-status-warning-bg); color: var(--color-status-warning-text, #92400e); }
&.status-running .run-status { background: var(--color-status-info-bg); color: var(--color-status-info-text, #1d4ed8); }
&.status-completed .run-status { background: var(--color-status-success-bg); color: var(--color-status-success-text, #166534); }
&.status-failed .run-status { background: var(--color-status-error-bg); color: var(--color-status-error-text, #991b1b); }
&.status-cancelled .run-status { background: var(--color-surface-tertiary); color: var(--color-text-secondary); }
}
.run-progress {
@@ -682,8 +706,8 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
}
&.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
&.btn-secondary {
@@ -770,10 +794,12 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
background: var(--color-surface-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
}
@@ -805,9 +831,13 @@ import { ViewModeToggleComponent } from '../../shared/components/view-mode-toggl
padding: 3rem;
color: var(--color-text-secondary);
grid-column: 1 / -1;
border: 1px dashed var(--color-border-primary);
border-radius: var(--radius-lg);
background: var(--color-surface-primary);
p {
margin-bottom: 1rem;
font-size: 0.9rem;
}
}
`],

View File

@@ -366,6 +366,7 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
.replay-request-section {
background: var(--color-surface-secondary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
padding: 1.5rem;
}
@@ -393,10 +394,12 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
background: var(--color-surface-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
}
}
@@ -422,6 +425,13 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
background: var(--color-surface-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
}
.requests-list {
@@ -432,9 +442,13 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
.request-card {
background: var(--color-surface-secondary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
overflow: hidden;
border-left: 4px solid var(--color-border-primary);
transition: box-shadow 150ms ease;
&:hover { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); }
&.status-pending { border-left-color: var(--color-status-warning); }
&.status-running { border-left-color: var(--color-status-info); }
@@ -447,6 +461,7 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
align-items: center;
padding: 1rem 1.5rem;
cursor: pointer;
transition: background 150ms ease;
&:hover {
background: var(--color-nav-hover);
@@ -461,6 +476,7 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
.request-image {
font-weight: var(--font-weight-semibold);
font-family: monospace;
font-size: 0.875rem;
}
.request-id {
@@ -477,16 +493,23 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
}
.request-status {
padding: 0.25rem 0.5rem;
border-radius: var(--radius-sm);
font-size: 0.75rem;
padding: 0.25rem 0.6rem;
border-radius: 9999px;
font-size: 0.7rem;
font-weight: var(--font-weight-medium);
text-transform: uppercase;
letter-spacing: 0.02em;
background: var(--color-surface-tertiary);
}
&.status-pending .request-status { background: var(--color-status-warning-bg); color: var(--color-status-warning-text, #92400e); }
&.status-running .request-status { background: var(--color-status-info-bg); color: var(--color-status-info-text, #1d4ed8); }
&.status-completed .request-status { background: var(--color-status-success-bg); color: var(--color-status-success-text, #166534); }
&.status-failed .request-status { background: var(--color-status-error-bg); color: var(--color-status-error-text, #991b1b); }
.request-date {
color: var(--color-text-secondary);
font-size: 0.8rem;
}
}
@@ -640,14 +663,19 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
}
.severity-badge {
padding: 0.125rem 0.375rem;
border-radius: 0.125rem;
padding: 0.15rem 0.5rem;
border-radius: 9999px;
font-size: 0.625rem;
font-weight: var(--font-weight-semibold);
text-transform: uppercase;
letter-spacing: 0.02em;
background: var(--color-surface-tertiary);
}
&.severity-info .severity-badge { background: var(--color-status-info-bg); color: var(--color-status-info-text, #1d4ed8); }
&.severity-warning .severity-badge { background: var(--color-status-warning-bg); color: var(--color-status-warning-text, #92400e); }
&.severity-error .severity-badge { background: var(--color-status-error-bg); color: var(--color-status-error-text, #991b1b); }
.field-name {
font-weight: var(--font-weight-semibold);
font-size: 0.875rem;
@@ -693,6 +721,7 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
.determinism-section {
background: var(--color-surface-secondary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
padding: 1.5rem;
}
@@ -706,24 +735,30 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
.stat-card {
background: var(--color-surface-tertiary);
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-lg);
padding: 1rem;
text-align: center;
transition: transform 150ms ease, box-shadow 150ms ease;
&.success { background: var(--color-status-success-bg); }
&.warning { background: var(--color-status-warning-bg); }
&:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); }
&.success { background: var(--color-status-success-bg); border-color: var(--color-status-success, #22c55e); }
&.warning { background: var(--color-status-warning-bg); border-color: var(--color-status-warning, #f59e0b); }
.stat-value {
display: block;
font-size: 2rem;
font-size: 1.75rem;
font-weight: var(--font-weight-semibold);
margin-bottom: 0.25rem;
line-height: 1.2;
}
.stat-label {
font-size: 0.75rem;
font-size: 0.7rem;
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.03em;
}
}
@@ -749,8 +784,8 @@ import { QuickVerifyDrawerComponent, VerifyResult } from '../../shared/component
border: none;
&.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
&.btn-secondary {

View File

@@ -203,10 +203,25 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../shared/ui/
animation: spin 0.8s linear infinite;
}
/* Shimmer skeleton loading */
.loading-state p {
margin-top: 1rem;
font-size: 0.85rem;
background: linear-gradient(90deg, var(--color-surface-elevated) 25%, var(--color-surface-primary) 50%, var(--color-surface-elevated) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
-webkit-background-clip: text;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.empty-icon {
width: 48px;
height: 48px;
@@ -233,16 +248,16 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../shared/ui/
padding: 0.5rem 1rem;
font-size: 0.8rem;
font-weight: var(--font-weight-medium);
color: var(--color-brand-primary);
border: 1px solid var(--color-brand-primary);
color: var(--color-btn-primary-text);
background: var(--color-btn-primary-bg);
border: none;
border-radius: var(--radius-sm);
text-decoration: none;
transition: background 0.15s ease, color 0.15s ease;
transition: opacity 150ms ease;
}
.empty-action-link:hover {
background: var(--color-brand-primary);
color: #fff;
opacity: 0.9;
}
.retry-btn {
@@ -267,18 +282,20 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../shared/ui/
border-radius: var(--radius-lg);
background: var(--color-surface-secondary);
cursor: pointer;
transition: all 0.15s ease;
transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
text-align: left;
}
.pack-card:hover {
border-color: var(--color-brand-primary);
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.pack-card.selected {
border-color: var(--color-brand-primary);
background: rgba(59, 130, 246, 0.05);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
.pack-card-header {
@@ -289,10 +306,14 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../shared/ui/
}
.pack-subject-type {
font-size: 0.75rem;
font-size: 0.7rem;
font-weight: var(--font-weight-medium);
text-transform: uppercase;
letter-spacing: 0.02em;
color: var(--color-brand-primary);
background: rgba(59, 130, 246, 0.08);
padding: 0.1rem 0.5rem;
border-radius: 9999px;
}
.pack-date {
@@ -353,7 +374,9 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../shared/ui/
border-radius: var(--radius-sm);
background: var(--color-surface-secondary);
cursor: pointer;
font-size: 0.875rem;
font-size: 0.84rem;
font-weight: var(--font-weight-medium);
transition: background 150ms ease, border-color 150ms ease;
}
.page-btn:disabled {
@@ -362,7 +385,9 @@ import { FilterBarComponent, FilterOption, ActiveFilter } from '../../shared/ui/
}
.page-btn:not(:disabled):hover {
background: var(--color-nav-hover);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-color: var(--color-btn-primary-bg);
}
.page-info {

View File

@@ -333,7 +333,7 @@ import type {
cursor: pointer;
}
.btn--sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }
.btn--primary { background: var(--color-brand-primary); border: none; color: var(--color-text-heading); }
.btn--primary { background: var(--color-btn-primary-bg); border: none; color: var(--color-btn-primary-text); }
.btn--secondary { background: var(--color-surface-secondary); border: 1px solid var(--color-border-primary); color: var(--color-text-primary); }
.verify-panel { display: grid; gap: 1rem; }

View File

@@ -727,7 +727,7 @@ export interface AuditBundleConfig {
.btn--primary {
background: var(--color-status-info-text);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--primary:hover:not(:disabled) {

View File

@@ -108,11 +108,12 @@
font-size: var(--font-size-sm);
background: var(--color-surface-primary);
color: var(--color-text-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px var(--color-brand-light);
box-shadow: 0 0 0 2px var(--color-focus-ring, var(--color-brand-light));
}
&::placeholder {
@@ -184,12 +185,17 @@
}
&.primary {
background: var(--color-brand-primary);
background: var(--color-btn-primary-bg, var(--color-brand-primary));
border-color: var(--color-brand-primary);
color: var(--color-text-inverse);
color: var(--color-btn-primary-text, var(--color-text-inverse));
&:hover {
background: var(--color-brand-primary-hover);
opacity: 0.9;
}
&:focus-visible {
outline: none;
box-shadow: 0 0 0 2px var(--color-focus-ring, rgba(59, 130, 246, 0.25));
}
}
}
@@ -209,13 +215,14 @@
.findings-table th {
position: sticky;
top: 0;
padding: var(--space-3) var(--space-2);
padding: 0.5rem 0.75rem;
background: var(--color-surface-secondary);
border-bottom: 2px solid var(--color-border-primary);
text-align: left;
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
white-space: nowrap;
z-index: 1;
&.sortable {
cursor: pointer;
@@ -228,7 +235,7 @@
}
.findings-table td {
padding: var(--space-3) var(--space-2);
padding: 0.5rem 0.75rem;
border-bottom: 1px solid var(--color-border-primary);
vertical-align: middle;
}
@@ -237,10 +244,14 @@
cursor: pointer;
transition: background-color var(--motion-duration-fast) var(--motion-ease-default);
&:hover {
&:nth-child(even) {
background: var(--color-surface-secondary);
}
&:hover {
background: var(--color-nav-hover, var(--color-surface-tertiary));
}
&.selected {
background: var(--color-status-info-bg);
@@ -358,7 +369,7 @@
.severity-badge {
display: inline-block;
padding: var(--space-0-5) var(--space-2);
border-radius: var(--radius-sm);
border-radius: 9999px;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
text-transform: uppercase;
@@ -393,7 +404,7 @@
.status-badge {
display: inline-block;
padding: var(--space-0-5) var(--space-2);
border-radius: var(--radius-sm);
border-radius: 9999px;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
text-transform: capitalize;

View File

@@ -375,8 +375,8 @@ type IntegrationDetailTab = 'overview' | 'credentials' | 'scopes-rules' | 'event
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border: none;
}

View File

@@ -306,8 +306,8 @@ import {
.btn-primary {
padding: 0.75rem 1.5rem;
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border: none;
border-radius: var(--radius-md);
font-weight: var(--font-weight-medium);

View File

@@ -649,8 +649,8 @@ interface CategoryGroup {
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -1324,8 +1324,8 @@ interface PreflightCheck {
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -790,8 +790,8 @@ function domainStaleness(domain: MirrorDomainResponse): 'fresh' | 'stale' | 'nev
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-sm {
@@ -802,8 +802,8 @@ function domainStaleness(domain: MirrorDomainResponse): 'fresh' | 'stale' | 'nev
}
.btn-sm.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-danger {

View File

@@ -1058,8 +1058,8 @@ interface CategorySummary {
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -228,8 +228,8 @@ import {
}
.btn.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn:disabled {

View File

@@ -283,7 +283,7 @@ interface IssuerDetail {
text-decoration: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--secondary { background: var(--color-text-primary); color: var(--color-border-primary); }
.btn--danger { background: rgba(239, 68, 68, 0.15); color: var(--color-status-error-border); }
.btn--small { padding: 0.375rem 0.75rem; font-size: 0.75rem; }

View File

@@ -156,7 +156,7 @@ import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
cursor: not-allowed;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--secondary { background: var(--color-text-primary); color: var(--color-border-primary); }
`]
})

View File

@@ -234,7 +234,7 @@ interface Issuer {
.btn--primary {
background: var(--color-status-info);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -28,7 +28,7 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
<div class="jobengine-dashboard__actions">
<a class="btn btn--secondary" [routerLink]="OPERATIONS_PATHS.schedulerRuns">Scheduler Runs</a>
<a class="btn btn--secondary" [routerLink]="OPERATIONS_PATHS.deadLetter">Dead-Letter</a>
<button class="btn btn--secondary" type="button" (click)="refresh()" [disabled]="loading()">
<button class="btn btn--primary" type="button" (click)="refresh()" [disabled]="loading()">
Refresh
</button>
</div>
@@ -40,23 +40,31 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
</div>
}
<section class="jobengine-dashboard__kpis">
<article class="kpi">
<span class="kpi__label">Total Jobs</span>
<strong class="kpi__value">{{ jobSummary()?.totalJobs ?? 0 }}</strong>
<span class="kpi__hint">{{ jobSummary()?.leasedJobs ?? 0 }} running</span>
</article>
<article class="kpi">
<span class="kpi__label">Failed Jobs</span>
<strong class="kpi__value">{{ jobSummary()?.failedJobs ?? 0 }}</strong>
<span class="kpi__hint">{{ deadLetterStats()?.totalEntries ?? 0 }} dead-letter entries</span>
</article>
<article class="kpi">
<span class="kpi__label">Quota Policies</span>
<strong class="kpi__value">{{ quotaSummary()?.totalQuotas ?? 0 }}</strong>
<span class="kpi__hint">{{ quotaSummary()?.pausedQuotas ?? 0 }} paused</span>
</article>
</section>
@if (loading()) {
<section class="jobengine-dashboard__kpis">
<article class="kpi"><div class="shimmer shimmer--lg"></div><div class="shimmer shimmer--sm"></div></article>
<article class="kpi"><div class="shimmer shimmer--lg"></div><div class="shimmer shimmer--sm"></div></article>
<article class="kpi"><div class="shimmer shimmer--lg"></div><div class="shimmer shimmer--sm"></div></article>
</section>
} @else {
<section class="jobengine-dashboard__kpis">
<article class="kpi">
<span class="kpi__label">Total Jobs</span>
<strong class="kpi__value">{{ jobSummary()?.totalJobs ?? 0 }}</strong>
<span class="kpi__hint">{{ jobSummary()?.leasedJobs ?? 0 }} running</span>
</article>
<article class="kpi">
<span class="kpi__label">Failed Jobs</span>
<strong class="kpi__value">{{ jobSummary()?.failedJobs ?? 0 }}</strong>
<span class="kpi__hint">{{ deadLetterStats()?.totalEntries ?? 0 }} dead-letter entries</span>
</article>
<article class="kpi">
<span class="kpi__label">Quota Policies</span>
<strong class="kpi__value">{{ quotaSummary()?.totalQuotas ?? 0 }}</strong>
<span class="kpi__hint">{{ quotaSummary()?.pausedQuotas ?? 0 }} paused</span>
</article>
</section>
}
@if (allCountsZero()) {
<p class="jobengine-dashboard__empty-hint">
@@ -188,6 +196,12 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
margin-bottom: 0.65rem;
color: var(--color-status-info);
text-decoration: none;
font-size: 0.85rem;
transition: color 150ms ease;
}
.jobengine-dashboard__back:hover {
filter: brightness(0.85);
}
.jobengine-dashboard__actions {
@@ -219,6 +233,13 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
border-radius: var(--radius-lg);
background: var(--color-surface-primary);
padding: 1.1rem;
transition: transform 150ms ease, box-shadow 150ms ease;
}
.kpi:hover,
a.surface:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.kpi {
@@ -265,6 +286,10 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
gap: 0.85rem;
}
a.surface:hover {
border-color: var(--color-brand-primary);
}
.surface h2 {
margin: 0;
font-size: 1.1rem;
@@ -273,12 +298,19 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
.surface--restricted {
cursor: default;
opacity: 0.85;
}
.surface--restricted:hover {
transform: none;
box-shadow: none;
}
.surface p {
margin: 0;
color: var(--color-text-secondary);
line-height: 1.5;
font-size: 0.88rem;
}
.surface dl {
@@ -291,7 +323,13 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
display: flex;
justify-content: space-between;
gap: 1rem;
font-size: 0.9rem;
font-size: 0.88rem;
padding: 0.35rem 0;
border-bottom: 1px solid var(--color-border-primary);
}
.surface dl div:last-child {
border-bottom: none;
}
.surface dt {
@@ -308,8 +346,11 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.3rem 0.65rem;
border-radius: 9999px;
background: var(--color-status-warning-bg);
color: var(--color-status-warning-border);
font-size: 0.8rem;
font-size: 0.78rem;
font-weight: var(--font-weight-medium);
}
@@ -319,19 +360,72 @@ import { OPERATIONS_PATHS } from '../platform/ops/operations-paths';
color: var(--color-text-secondary);
display: grid;
gap: 0.35rem;
font-size: 0.88rem;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.55rem 0.9rem;
padding: 0.5rem 0.9rem;
border-radius: var(--radius-md);
border: 1px solid var(--color-border-primary);
background: var(--color-surface-secondary);
color: var(--color-text-primary);
text-decoration: none;
cursor: pointer;
font-size: 0.85rem;
font-weight: 500;
transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.btn:hover:not(:disabled) {
background: var(--color-surface-primary);
border-color: var(--color-brand-primary);
}
.btn:active:not(:disabled) {
transform: translateY(1px);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn--primary {
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-color: var(--color-btn-primary-bg);
}
.btn--primary:hover:not(:disabled) {
filter: brightness(1.1);
background: var(--color-btn-primary-bg);
border-color: var(--color-btn-primary-bg);
}
.shimmer {
border-radius: var(--radius-md);
background: linear-gradient(90deg, var(--color-surface-secondary) 25%, var(--color-surface-tertiary, rgba(255,255,255,0.08)) 50%, var(--color-surface-secondary) 75%);
background-size: 200% 100%;
animation: shimmer-move 1.5s infinite ease-in-out;
}
.shimmer--lg {
height: 2rem;
width: 60%;
}
.shimmer--sm {
height: 0.85rem;
width: 80%;
margin-top: 0.5rem;
}
@keyframes shimmer-move {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
@media (max-width: 960px) {

View File

@@ -486,7 +486,7 @@ import { ExportFormat, ExportOptions } from '../../services/lineage-export.servi
.btn-primary {
background: var(--color-status-success);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn-primary:hover:not(:disabled) {

View File

@@ -70,8 +70,8 @@ import { RouterLink } from '@angular/router';
}
.btn-primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn-secondary {

View File

@@ -54,6 +54,12 @@
flex-direction: column;
gap: var(--space-3);
min-height: 100%;
transition: transform 150ms ease, box-shadow 150ms ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
}
.notify-card__header {
@@ -129,13 +135,18 @@
justify-content: space-between;
gap: var(--space-2);
cursor: pointer;
transition: border-color var(--motion-duration-fast) var(--motion-ease-default),
transform var(--motion-duration-fast) var(--motion-ease-default);
transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
&:hover {
border-color: var(--color-brand-primary);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
&.active {
border-color: var(--color-brand-primary);
background: var(--color-brand-light);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
}
@@ -147,14 +158,17 @@
.channel-status {
font-size: var(--font-size-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: var(--space-0-5) var(--space-2);
border-radius: var(--radius-full);
border: 1px solid var(--color-border-primary);
border-radius: 9999px;
background: var(--color-surface-tertiary, rgba(0, 0, 0, 0.05));
color: var(--color-text-secondary);
}
.channel-status--enabled {
border-color: var(--color-status-success);
background: var(--color-status-success-bg, rgba(16, 185, 129, 0.15));
color: var(--color-status-success);
}
@@ -187,10 +201,12 @@ select {
padding: var(--space-2);
font-size: var(--font-size-base);
font-family: inherit;
transition: border-color 150ms ease, box-shadow 150ms ease;
&:focus-visible {
outline: 2px solid var(--color-brand-primary);
outline-offset: 2px;
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}
}
@@ -221,13 +237,18 @@ select {
border-radius: var(--radius-full);
padding: var(--space-1-5) var(--space-4);
font-weight: var(--font-weight-semibold);
font-size: var(--font-size-sm);
cursor: pointer;
background: var(--color-brand-primary);
color: var(--color-text-inverse);
transition: opacity var(--motion-duration-fast) var(--motion-ease-default);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
transition: all 150ms ease;
&:hover:not(:disabled) {
background: var(--color-brand-primary-hover);
filter: brightness(1.1);
}
&:active:not(:disabled) {
transform: translateY(1px);
}
&:disabled {
@@ -239,6 +260,13 @@ select {
.notify-actions .ghost-button {
background: transparent;
color: var(--color-text-primary);
border: 1px solid var(--color-border-primary);
&:hover:not(:disabled) {
border-color: var(--color-brand-primary);
background: var(--color-surface-secondary);
filter: none;
}
}
.channel-health {
@@ -253,25 +281,25 @@ select {
.status-pill {
padding: var(--space-1) var(--space-2-5);
border-radius: var(--radius-full);
border-radius: 9999px;
font-size: var(--font-size-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
border: 1px solid var(--color-border-primary);
letter-spacing: 0.06em;
}
.status-pill--healthy {
border-color: var(--color-status-success);
background: var(--color-status-success-bg, rgba(16, 185, 129, 0.15));
color: var(--color-status-success);
}
.status-pill--warning {
border-color: var(--color-status-warning);
background: var(--color-status-warning-bg, rgba(245, 158, 11, 0.15));
color: var(--color-status-warning);
}
.status-pill--error {
border-color: var(--color-status-error);
background: var(--color-status-error-bg);
color: var(--color-status-error);
}
@@ -320,6 +348,12 @@ select {
}
}
.notify-card--deliveries {
&:hover {
transform: none;
}
}
.deliveries-controls {
display: flex;
justify-content: flex-start;
@@ -343,12 +377,36 @@ table {
thead th {
text-align: left;
font-weight: var(--font-weight-semibold);
padding-bottom: var(--space-2);
padding: 0.5rem 0.75rem;
color: var(--color-text-secondary);
text-transform: uppercase;
font-size: var(--font-size-xs);
letter-spacing: 0.04em;
border-bottom: 2px solid var(--color-border-primary);
position: sticky;
top: 0;
background: var(--color-surface-secondary);
z-index: 1;
}
tbody tr {
transition: background 150ms ease;
&:hover {
background: var(--color-surface-tertiary, rgba(255, 255, 255, 0.03));
}
&:nth-child(even) {
background: rgba(0, 0, 0, 0.02);
&:hover {
background: var(--color-surface-tertiary, rgba(255, 255, 255, 0.03));
}
}
}
tbody td {
padding: var(--space-2) var(--space-1);
padding: 0.5rem 0.75rem;
border-top: 1px solid var(--color-border-primary);
}
@@ -360,25 +418,26 @@ tbody td {
.status-badge {
display: inline-block;
padding: var(--space-0-5) var(--space-2);
border-radius: var(--radius-md);
padding: 0.15rem 0.55rem;
border-radius: 9999px;
font-size: var(--font-size-xs);
font-weight: 600;
text-transform: uppercase;
border: 1px solid var(--color-border-primary);
letter-spacing: 0.03em;
}
.status-badge--sent {
border-color: var(--color-status-success);
background: var(--color-status-success-bg, rgba(16, 185, 129, 0.15));
color: var(--color-status-success);
}
.status-badge--failed {
border-color: var(--color-status-error);
background: var(--color-status-error-bg);
color: var(--color-status-error);
}
.status-badge--throttled {
border-color: var(--color-status-warning);
background: var(--color-status-warning-bg, rgba(245, 158, 11, 0.15));
color: var(--color-status-warning);
}

View File

@@ -612,7 +612,7 @@ interface TrustAnchor {
.btn--primary {
background: var(--color-status-info);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--primary:disabled {

View File

@@ -361,8 +361,8 @@ interface DashboardFeature {
}
.btn--primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -140,7 +140,7 @@ type FeedsAirgapAction = 'import' | 'export' | null;
styles: [`
.feeds-offline {
display: grid;
gap: 0.65rem;
gap: 0.75rem;
}
.feeds-offline__header {
@@ -152,18 +152,20 @@ type FeedsAirgapAction = 'import' | 'export' | null;
.feeds-offline__header h1 {
margin: 0;
font-size: 1.55rem;
}
.feeds-offline__header p {
margin: 0.2rem 0 0;
font-size: 0.8rem;
font-size: 0.82rem;
color: var(--color-text-secondary);
max-width: 68ch;
line-height: 1.5;
}
.feeds-offline__actions {
display: flex;
gap: 0.35rem;
gap: 0.45rem;
flex-wrap: wrap;
}
@@ -171,92 +173,125 @@ type FeedsAirgapAction = 'import' | 'export' | null;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
background: var(--color-surface-primary);
color: var(--color-brand-primary);
color: var(--color-text-primary);
text-decoration: none;
font-size: 0.73rem;
padding: 0.28rem 0.5rem;
font-size: 0.76rem;
font-weight: 500;
padding: 0.38rem 0.65rem;
cursor: pointer;
transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.feeds-offline__actions a:hover {
background: var(--color-surface-secondary);
border-color: var(--color-brand-primary);
}
.feeds-offline__actions a:active {
transform: translateY(1px);
}
.tabs {
display: flex;
gap: 0.35rem;
flex-wrap: wrap;
gap: 0;
border-bottom: 2px solid var(--color-border-primary);
}
.tabs a {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-full);
background: var(--color-surface-primary);
color: var(--color-text-secondary);
padding: 0.15rem 0.6rem;
font-size: 0.72rem;
border: none;
border-bottom: 2px solid transparent;
border-radius: 0;
background: transparent;
color: var(--color-tab-inactive-text, var(--color-text-secondary));
padding: 0.5rem 1rem;
font-size: 0.82rem;
cursor: pointer;
text-decoration: none;
margin-bottom: -2px;
transition: color 150ms ease, border-color 150ms ease;
}
.tabs a:hover {
color: var(--color-text-primary);
}
.tabs a.active {
border-color: var(--color-brand-primary);
color: var(--color-brand-primary);
color: var(--color-tab-active-text, var(--color-brand-primary));
border-bottom: 2px solid var(--color-tab-active-border, var(--color-brand-primary));
font-weight: 600;
}
.summary {
display: flex;
gap: 0.35rem;
gap: 0.4rem;
flex-wrap: wrap;
}
.summary span {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-full);
border-radius: 9999px;
background: var(--color-surface-primary);
color: var(--color-text-secondary);
font-size: 0.7rem;
padding: 0.12rem 0.45rem;
font-size: 0.72rem;
font-weight: 500;
padding: 0.18rem 0.55rem;
}
.status-banner {
border-radius: var(--radius-md);
padding: 0.45rem 0.55rem;
border-radius: var(--radius-lg);
padding: 0.55rem 0.75rem;
display: flex;
gap: 0.35rem;
gap: 0.5rem;
flex-wrap: wrap;
align-items: center;
font-size: 0.73rem;
font-size: 0.78rem;
}
.status-banner--healthy {
border: 1px solid rgba(16, 185, 129, 0.35);
background: rgba(16, 185, 129, 0.12);
background: rgba(16, 185, 129, 0.08);
color: var(--color-status-success-border);
}
.status-banner code {
font-size: 0.68rem;
font-size: 0.72rem;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
background: var(--color-surface-primary);
color: var(--color-text-primary);
padding: 0.05rem 0.3rem;
padding: 0.1rem 0.35rem;
font-family: monospace;
}
.status-banner a {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-sm);
border-radius: var(--radius-md);
background: var(--color-surface-primary);
color: var(--color-brand-primary);
font-size: 0.67rem;
padding: 0.08rem 0.34rem;
font-size: 0.72rem;
font-weight: 500;
padding: 0.18rem 0.5rem;
text-decoration: none;
transition: border-color 150ms ease, background 150ms ease;
}
.status-banner a:hover {
border-color: var(--color-brand-primary);
background: var(--color-surface-secondary);
}
.panel {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
border-radius: var(--radius-lg);
background: var(--color-surface-primary);
padding: 0.6rem;
padding: 0.75rem;
display: grid;
gap: 0.4rem;
gap: 0.5rem;
transition: box-shadow 150ms ease;
}
.panel:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
table {
@@ -264,37 +299,60 @@ type FeedsAirgapAction = 'import' | 'export' | null;
border-collapse: collapse;
}
th,
th {
text-align: left;
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--color-text-secondary);
font-weight: 600;
padding: 0.5rem 0.75rem;
border-bottom: 2px solid var(--color-border-primary);
position: sticky;
top: 0;
background: var(--color-surface-primary);
}
td {
text-align: left;
border-bottom: 1px solid var(--color-border-primary);
padding: 0.4rem;
font-size: 0.74rem;
padding: 0.5rem 0.75rem;
font-size: 0.78rem;
white-space: nowrap;
}
th {
font-size: 0.66rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--color-text-secondary);
tbody tr {
transition: background 150ms ease;
}
tbody tr:hover {
background: rgba(0, 0, 0, 0.03);
}
tbody tr:nth-child(even) {
background: rgba(0, 0, 0, 0.015);
}
tbody tr:nth-child(even):hover {
background: rgba(0, 0, 0, 0.03);
}
.panel p {
margin: 0;
font-size: 0.76rem;
font-size: 0.8rem;
color: var(--color-text-secondary);
line-height: 1.5;
}
.action-banner {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
border-radius: var(--radius-lg);
background: var(--color-surface-secondary);
color: var(--color-text-primary);
padding: 0.5rem 0.6rem;
padding: 0.6rem 0.75rem;
display: grid;
gap: 0.2rem;
font-size: 0.73rem;
gap: 0.25rem;
font-size: 0.78rem;
}
.panel__links {
@@ -303,10 +361,22 @@ type FeedsAirgapAction = 'import' | 'export' | null;
flex-wrap: wrap;
}
.panel a {
font-size: 0.74rem;
.panel a,
.panel__links a {
font-size: 0.78rem;
font-weight: 500;
color: var(--color-brand-primary);
text-decoration: none;
padding: 0.3rem 0.6rem;
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
transition: border-color 150ms ease, background 150ms ease;
}
.panel a:hover,
.panel__links a:hover {
border-color: var(--color-brand-primary);
background: var(--color-surface-secondary);
}
`],
})

View File

@@ -37,7 +37,7 @@
.ops-overview__actions {
display: flex;
gap: 0.4rem;
gap: 0.5rem;
flex-wrap: wrap;
justify-content: flex-end;
}
@@ -57,9 +57,33 @@
border-radius: var(--radius-md);
background: var(--color-surface-primary);
color: var(--color-text-primary);
padding: 0.38rem 0.66rem;
font-size: 0.74rem;
padding: 0.42rem 0.75rem;
font-size: 0.76rem;
font-weight: 500;
cursor: pointer;
transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
&:hover {
background: var(--color-surface-secondary);
border-color: var(--color-brand-primary);
}
&:active {
transform: translateY(1px);
}
}
// Primary action button (Refresh)
.ops-overview__actions button {
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-color: var(--color-btn-primary-bg);
&:hover {
filter: brightness(1.1);
background: var(--color-btn-primary-bg);
border-color: var(--color-btn-primary-bg);
}
}
.ops-overview__submenu {
@@ -91,6 +115,12 @@
padding: 0.85rem;
display: grid;
gap: 0.25rem;
transition: transform 150ms ease, box-shadow 150ms ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
}
.ops-overview__summary strong {
@@ -158,6 +188,13 @@
padding: 0.85rem;
display: grid;
gap: 0.4rem;
transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border-color: var(--color-brand-primary);
}
}
.blocking-card__topline,
@@ -189,10 +226,11 @@
.impact {
width: fit-content;
border-radius: var(--radius-full);
padding: 0.12rem 0.48rem;
border-radius: 9999px;
padding: 0.15rem 0.52rem;
font-size: 0.68rem;
font-weight: var(--font-weight-semibold);
letter-spacing: 0.02em;
}
.impact--blocking {
@@ -221,11 +259,23 @@
.ops-overview__panel li {
display: grid;
gap: 0.16rem;
padding: 0.5rem 0.6rem;
border-radius: var(--radius-md);
transition: background 150ms ease;
&:hover {
background: var(--color-surface-secondary);
}
}
.ops-overview__panel li a,
.ops-overview__boundary-links a {
color: var(--color-brand-primary);
transition: color 150ms ease;
&:hover {
filter: brightness(0.85);
}
}
.ops-overview__panel li strong {
@@ -241,6 +291,20 @@
margin-top: 0.6rem;
}
.ops-overview__boundary-links a {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
padding: 0.35rem 0.65rem;
font-size: 0.76rem;
font-weight: 500;
transition: background 150ms ease, border-color 150ms ease;
&:hover {
background: var(--color-surface-secondary);
border-color: var(--color-brand-primary);
}
}
.ops-overview__note {
margin: 0;
font-size: 0.75rem;

View File

@@ -96,7 +96,22 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
<div class="setup-home__graph" #graphContainer>
@if (loading()) {
<div class="setup-home__loading">Loading topology...</div>
<div class="setup-home__loading">
<div class="setup-home__shimmer-graph">
<div class="setup-home__shimmer-node setup-home__shimmer-node--lg"></div>
<div class="setup-home__shimmer-line"></div>
<div class="setup-home__shimmer-row">
<div class="setup-home__shimmer-node"></div>
<div class="setup-home__shimmer-node"></div>
</div>
<div class="setup-home__shimmer-line"></div>
<div class="setup-home__shimmer-row">
<div class="setup-home__shimmer-node setup-home__shimmer-node--sm"></div>
<div class="setup-home__shimmer-node setup-home__shimmer-node--sm"></div>
<div class="setup-home__shimmer-node setup-home__shimmer-node--sm"></div>
</div>
</div>
</div>
}
</div>
@@ -110,10 +125,10 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
<div class="setup-home__quick-links">
@for (card of quickLinks; track card.route) {
<article class="setup-home__card">
<article class="setup-home__card" [routerLink]="card.route">
<h3>{{ card.title }}</h3>
<p>{{ card.description }}</p>
<a [routerLink]="card.route">Open</a>
<span class="setup-home__card-link">Open <span class="setup-home__card-arrow">&rarr;</span></span>
</article>
}
</div>
@@ -188,7 +203,18 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
background: var(--color-surface-secondary);
color: var(--color-text-primary);
font-size: 0.72rem;
padding: 0.2rem 0.35rem;
padding: 0.22rem 1.4rem 0.22rem 0.35rem;
transition: border-color var(--motion-duration-sm, 140ms) ease;
}
.setup-home__filter select:hover {
border-color: var(--color-border-secondary);
}
.setup-home__filter select:focus {
border-color: var(--color-brand-primary);
outline: none;
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.setup-home__search {
@@ -204,6 +230,18 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
color: var(--color-text-primary);
font-size: 0.76rem;
padding: 0.25rem 0.45rem;
transition: border-color var(--motion-duration-sm, 140ms) ease,
box-shadow var(--motion-duration-sm, 140ms) ease;
}
.setup-home__search input:hover {
border-color: var(--color-border-secondary);
}
.setup-home__search input:focus {
border-color: var(--color-brand-primary);
outline: none;
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.setup-home__search input::placeholder {
@@ -221,9 +259,11 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
background: var(--color-surface-secondary);
color: var(--color-text-primary);
font-size: 0.72rem;
padding: 0.2rem 0.4rem;
padding: 0.22rem 0.45rem;
cursor: pointer;
line-height: 1;
transition: background-color var(--motion-duration-sm, 140ms) ease,
border-color var(--motion-duration-sm, 140ms) ease;
}
.setup-home__zoom-controls button:hover {
@@ -231,6 +271,10 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
border-color: var(--color-border-emphasis);
}
.setup-home__zoom-controls button:active {
background: var(--color-brand-muted);
}
.setup-home__graph {
position: relative;
border: 1px solid var(--color-border-primary);
@@ -256,6 +300,52 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
font-size: 0.82rem;
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.setup-home__shimmer-graph {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
}
.setup-home__shimmer-node {
width: 48px;
height: 48px;
border-radius: 50%;
background: linear-gradient(90deg, var(--color-skeleton-base) 25%, var(--color-skeleton-highlight) 50%, var(--color-skeleton-base) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
}
.setup-home__shimmer-node--lg {
width: 56px;
height: 56px;
border-radius: var(--radius-md);
transform: rotate(45deg);
}
.setup-home__shimmer-node--sm {
width: 36px;
height: 36px;
}
.setup-home__shimmer-line {
width: 2px;
height: 24px;
background: linear-gradient(90deg, var(--color-skeleton-base) 25%, var(--color-skeleton-highlight) 50%, var(--color-skeleton-base) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
}
.setup-home__shimmer-row {
display: flex;
gap: 2rem;
}
.setup-home__legend {
display: flex;
gap: 0.6rem;
@@ -310,35 +400,67 @@ interface TopoLink extends d3.SimulationLinkDatum<TopoNode> {
.setup-home__quick-links {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 0.4rem;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 0.5rem;
}
.setup-home__card {
border: 1px solid var(--color-border-primary);
border-radius: var(--radius-md);
border-radius: var(--radius-lg);
background: var(--color-surface-primary);
padding: 0.55rem;
display: grid;
gap: 0.2rem;
padding: 0.75rem 0.85rem;
display: flex;
flex-direction: column;
gap: 0.3rem;
cursor: pointer;
transition: transform var(--motion-duration-sm, 140ms) var(--motion-ease-standard, ease),
border-color var(--motion-duration-sm, 140ms) var(--motion-ease-standard, ease),
box-shadow var(--motion-duration-sm, 140ms) var(--motion-ease-standard, ease);
}
.setup-home__card:hover {
transform: translateY(-2px);
border-color: var(--color-border-emphasis);
box-shadow: var(--shadow-md);
}
.setup-home__card:active {
transform: translateY(0);
}
.setup-home__card h3 {
margin: 0;
font-size: 0.8rem;
font-size: 0.82rem;
font-weight: var(--font-weight-semibold, 600);
color: var(--color-text-heading);
}
.setup-home__card p {
margin: 0;
font-size: 0.7rem;
font-size: 0.72rem;
color: var(--color-text-secondary);
line-height: 1.45;
flex: 1;
}
.setup-home__card a {
font-size: 0.7rem;
.setup-home__card-link {
font-size: 0.72rem;
font-weight: var(--font-weight-medium, 500);
color: var(--color-brand-primary);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.25rem;
margin-top: 0.15rem;
}
.setup-home__card-arrow {
display: inline-block;
transition: transform var(--motion-duration-sm, 140ms) var(--motion-ease-standard, ease);
}
.setup-home__card:hover .setup-home__card-arrow {
transform: translateX(3px);
}
`],
})

View File

@@ -1369,11 +1369,11 @@ import {
}
.btn--primary {
background: var(--color-brand-primary);
color: var(--color-text-heading);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
&:hover:not(:disabled) {
background: var(--color-brand-primary-hover);
background: var(--color-btn-primary-bg-hover);
}
}

View File

@@ -908,7 +908,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -236,7 +236,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -247,7 +247,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -288,7 +288,7 @@ import {
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -285,7 +285,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
.btn--primary {
background: var(--color-status-info);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--primary:hover:not(:disabled) {

View File

@@ -293,7 +293,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -232,7 +232,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover { background: var(--color-status-info); }
.btn--ghost { background: transparent; color: var(--color-text-muted); }

View File

@@ -359,7 +359,7 @@ interface SchemaSection {
text-decoration: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover { background: var(--color-status-info); }
.btn--secondary { background: var(--color-text-primary); color: var(--color-border-primary); border: 1px solid var(--color-text-primary); }

View File

@@ -321,7 +321,7 @@ import {
gap: 0.5rem;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -459,7 +459,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -301,7 +301,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
border: none;
}
.btn--primary { background: var(--color-status-info); color: var(--color-text-heading); }
.btn--primary { background: var(--color-status-info); color: var(--color-btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

View File

@@ -585,7 +585,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
.btn--primary {
background: var(--color-status-info);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }

View File

@@ -312,7 +312,7 @@ import { injectPolicyGovernanceScopeResolver } from './policy-governance-scope';
.btn--primary {
background: var(--color-status-info);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--primary:hover:not(:disabled) { background: var(--color-status-info); }

View File

@@ -633,7 +633,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-success), var(--color-status-success-text));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -389,7 +389,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-warning), var(--color-status-warning-text));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -303,7 +303,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-success), var(--color-status-success));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -204,7 +204,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-excepted), var(--color-status-excepted));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn:hover:not(:disabled) {

View File

@@ -230,7 +230,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-excepted), var(--color-status-excepted));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -291,7 +291,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-severity-high), var(--color-severity-high));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -288,7 +288,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-success), var(--color-status-success-text));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn:hover:not(:disabled) {

View File

@@ -276,7 +276,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-success), var(--color-status-success-text));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--success {

View File

@@ -426,7 +426,7 @@ import {
.btn--primary {
background: linear-gradient(135deg, var(--color-status-excepted), var(--color-status-excepted));
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
}
.btn--secondary {

View File

@@ -154,7 +154,7 @@ import { PolicyPackStore } from '../services/policy-pack.store';
dd { margin: 0; color: var(--color-text-primary); }
.workspace__banner { background: var(--color-status-warning-bg); border: 1px solid var(--color-status-warning-border); color: var(--color-status-warning-text); padding: 0.75rem 1rem; border-radius: var(--radius-xl); margin: 0.5rem 0 1rem; }
.workspace__footer { margin-top: 0.8rem; }
.workspace__footer button { background: var(--color-brand-primary); border: 1px solid var(--color-brand-primary); color: var(--color-text-inverse); border-radius: var(--radius-lg); padding: 0.45rem 0.8rem; cursor: pointer; }
.workspace__footer button { background: var(--color-btn-primary-bg); border: 1px solid var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-radius: var(--radius-lg); padding: 0.45rem 0.8rem; cursor: pointer; }
.workspace__empty { grid-column: 1 / -1; text-align: center; padding: 3rem 1.5rem; border: 1px dashed var(--color-border-primary); border-radius: var(--radius-xl); background: var(--color-surface-elevated); }
.workspace__empty h3 { margin: 0 0 0.5rem; color: var(--color-text-heading); }
.workspace__empty p { margin: 0 0 1rem; color: var(--color-text-muted); max-width: 480px; margin-inline: auto; }
@@ -165,7 +165,7 @@ import { PolicyPackStore } from '../services/policy-pack.store';
.workspace__create-form label { display: grid; gap: 0.25rem; font-size: 0.85rem; color: var(--color-text-muted); }
.workspace__create-form input { padding: 0.45rem 0.6rem; border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); background: var(--color-surface-primary); color: var(--color-text-primary); font-size: 0.95rem; }
.workspace__create-form input:focus { outline: none; border-color: var(--color-brand-primary); box-shadow: 0 0 0 2px rgba(var(--color-brand-primary-rgb, 99, 102, 241), 0.15); }
.workspace__create-form .btn-primary { background: var(--color-brand-primary); border: 1px solid var(--color-brand-primary); color: var(--color-text-inverse); border-radius: var(--radius-lg); padding: 0.45rem 0.8rem; cursor: pointer; font-size: 0.95rem; }
.workspace__create-form .btn-primary { background: var(--color-btn-primary-bg); border: 1px solid var(--color-btn-primary-bg); color: var(--color-btn-primary-text); border-radius: var(--radius-lg); padding: 0.45rem 0.8rem; cursor: pointer; font-size: 0.95rem; }
.workspace__create-form .btn-primary:hover:not(:disabled) { opacity: 0.9; }
.workspace__create-form .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.workspace__create-form .error-text { margin: 0; color: var(--color-status-error, #ef4444); font-size: 0.85rem; }

View File

@@ -255,6 +255,10 @@ interface PromotionRow {
grid-template-columns: 1fr 200px 220px;
gap: 0.75rem;
margin-bottom: 1rem;
padding: 0.75rem 1rem;
background: var(--color-surface-primary);
border: 1px solid var(--color-border-primary, #e5e7eb);
border-radius: var(--radius-lg, 8px);
}
.filter-field {
@@ -268,20 +272,37 @@ interface PromotionRow {
.filter-field input,
.filter-field select {
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border, #e5e7eb);
border: 1px solid var(--color-border-primary, #e5e7eb);
border-radius: var(--radius-sm, 4px);
font-size: 0.875rem;
background: var(--color-surface-primary);
color: var(--color-text-primary);
transition: border-color 150ms ease, box-shadow 150ms ease;
}
.filter-field input:focus,
.filter-field select:focus {
outline: none;
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.state-block {
padding: 1rem;
background: var(--color-surface-alt, #f9fafb);
border: 1px solid var(--color-border, #e5e7eb);
background: linear-gradient(90deg, var(--color-surface-alt, #f9fafb) 25%, var(--color-surface-primary, #fff) 50%, var(--color-surface-alt, #f9fafb) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border: 1px solid var(--color-border-primary, #e5e7eb);
border-radius: var(--radius-md, 8px);
font-size: 0.875rem;
color: var(--color-text-secondary, #666);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.state-block--error {
background: #fff5f5;
border-color: #fecaca;
@@ -304,25 +325,42 @@ interface PromotionRow {
.promotions-list__table {
width: 100%;
border-collapse: collapse;
font-size: 0.875rem;
font-size: 0.8125rem;
background: var(--color-surface-primary);
border: 1px solid var(--color-border-primary, #e5e7eb);
border-radius: var(--radius-lg, 8px);
overflow: hidden;
}
.promotions-list__table th {
text-align: left;
padding: 0.5rem 0.75rem;
border-bottom: 2px solid var(--color-border, #e5e7eb);
border-bottom: 2px solid var(--color-border-primary, #e5e7eb);
font-weight: 600;
font-size: 0.75rem;
font-size: 0.6875rem;
color: var(--color-text-secondary, #666);
text-transform: uppercase;
letter-spacing: 0.04em;
background: var(--color-surface-secondary, #f9fafb);
position: sticky;
top: 0;
z-index: 1;
}
.promotions-list__table td {
padding: 0.75rem;
border-bottom: 1px solid var(--color-border, #e5e7eb);
padding: 0.5rem 0.75rem;
border-bottom: 1px solid var(--color-border-primary, #e5e7eb);
vertical-align: top;
}
.promotions-list__table tbody tr:nth-child(even) {
background: var(--color-surface-secondary, #f9fafb);
}
.promotions-list__table tbody tr:hover {
background: var(--color-nav-hover);
}
.promotion-identity {
display: grid;
gap: 0.15rem;
@@ -436,18 +474,32 @@ interface PromotionRow {
.link-sm {
font-size: 0.8125rem;
color: var(--color-brand-primary, #4f46e5);
color: var(--color-brand-primary);
text-decoration: none;
font-weight: 500;
}
.link-sm:hover {
text-decoration: underline;
}
.btn-primary {
display: inline-flex;
align-items: center;
padding: 0.5rem 1rem;
background: var(--color-brand-primary, #4f46e5);
color: #fff;
border-radius: var(--radius-sm, 4px);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-radius: var(--radius-md, 6px);
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
font-weight: 600;
border: none;
transition: opacity 150ms ease, transform 150ms ease;
}
.btn-primary:hover {
opacity: 0.9;
transform: translateY(-1px);
}
.sr-only {
@@ -492,11 +544,18 @@ interface PromotionRow {
}
.pipeline-stage {
border: 1px solid var(--color-border, #e5e7eb);
border: 1px solid var(--color-border-primary, #e5e7eb);
border-radius: var(--radius-md, 8px);
padding: 0.75rem;
display: grid;
gap: 0.25rem;
background: var(--color-surface-primary);
transition: transform 150ms ease, box-shadow 150ms ease;
}
.pipeline-stage:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.pipeline-stage strong {

View File

@@ -306,7 +306,7 @@ import { quotasPath } from '../platform/ops/operations-paths';
.btn-primary {
background: var(--color-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
border-color: var(--color-primary);
}

View File

@@ -256,7 +256,7 @@ import { quotasPath } from '../platform/ops/operations-paths';
.btn-primary {
background: var(--color-primary);
color: var(--color-text-heading);
color: var(--color-btn-primary-text);
border-color: var(--color-primary);
}

Some files were not shown because too many files have changed in this diff Show More