refactor(ui): migrate all components to Warm Precision token names

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-21 11:49:37 -05:00
parent f7108ba357
commit b39014ef47
118 changed files with 322 additions and 322 deletions

View File

@@ -146,7 +146,7 @@ export function AnsiNfoModal({ open, onOpenChange }: AnsiNfoModalProps) {
}} }}
> >
{/* Retro title bar */} {/* Retro title bar */}
<div className="flex items-center justify-between px-3 pr-10 py-1.5 bg-surface border-b border-border font-mono text-xs"> <div className="flex items-center justify-between px-3 pr-10 py-1.5 bg-panel border-b border-border font-mono text-xs">
<DialogTitle id="ansi-nfo-title" className="text-text-muted text-xs font-normal font-mono"> <DialogTitle id="ansi-nfo-title" className="text-text-muted text-xs font-normal font-mono">
TOD.NFO ACiD View v1.0 TOD.NFO ACiD View v1.0
</DialogTitle> </DialogTitle>

View File

@@ -698,7 +698,7 @@ export function AlertRulesPage() {
No alert rules configured. No alert rules configured.
</p> </p>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{/* Header */} {/* Header */}
<div className="flex items-center gap-3 px-4 py-2 border-b border-border text-xs text-text-muted font-medium"> <div className="flex items-center gap-3 px-4 py-2 border-b border-border text-xs text-text-muted font-medium">
<span className="flex-1">Name</span> <span className="flex-1">Name</span>
@@ -710,7 +710,7 @@ export function AlertRulesPage() {
{rules.map((rule) => ( {rules.map((rule) => (
<div <div
key={rule.id} key={rule.id}
className="flex items-center gap-3 px-4 py-2.5 border-b border-border/50 hover:bg-surface text-sm" className="flex items-center gap-3 px-4 py-2.5 border-b border-border/50 hover:bg-panel text-sm"
> >
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<span className="text-text-primary truncate block"> <span className="text-text-primary truncate block">
@@ -809,7 +809,7 @@ export function AlertRulesPage() {
{channels.map((ch) => ( {channels.map((ch) => (
<div <div
key={ch.id} key={ch.id}
className="rounded-lg border border-border bg-surface p-4 space-y-2" className="rounded-lg border border-border bg-panel p-4 space-y-2"
> >
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">

View File

@@ -89,7 +89,7 @@ function AlertRow({
alert.silenced_until && new Date(alert.silenced_until) > new Date() alert.silenced_until && new Date(alert.silenced_until) > new Date()
return ( return (
<div className="flex items-center gap-3 px-4 py-3 border-b border-border/50 hover:bg-surface transition-colors"> <div className="flex items-center gap-3 px-4 py-3 border-b border-border/50 hover:bg-panel transition-colors">
<StatusIcon status={alert.status} /> <StatusIcon status={alert.status} />
<SeverityBadge severity={alert.severity} /> <SeverityBadge severity={alert.severity} />
@@ -271,7 +271,7 @@ export function AlertsPage() {
description="All clear! No alerts have been triggered." description="All clear! No alerts have been triggered."
/> />
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{alerts.map((alert) => ( {alerts.map((alert) => (
<AlertRow <AlertRow
key={alert.id} key={alert.id}
@@ -302,7 +302,7 @@ export function AlertsPage() {
description="Alert events will appear here as they are triggered and resolved." description="Alert events will appear here as they are triggered and resolved."
/> />
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{/* Table header */} {/* Table header */}
<div className="flex items-center gap-3 px-4 py-2 border-b border-border text-[10px] uppercase tracking-wider text-text-muted font-semibold"> <div className="flex items-center gap-3 px-4 py-2 border-b border-border text-[10px] uppercase tracking-wider text-text-muted font-semibold">
<span className="w-5" /> <span className="w-5" />
@@ -315,7 +315,7 @@ export function AlertsPage() {
{alerts.map((alert) => ( {alerts.map((alert) => (
<div <div
key={alert.id} key={alert.id}
className="flex items-center gap-3 px-4 py-2.5 border-b border-border/50 hover:bg-surface text-sm" className="flex items-center gap-3 px-4 py-2.5 border-b border-border/50 hover:bg-panel text-sm"
> >
<StatusIcon status={alert.status} /> <StatusIcon status={alert.status} />
<span className="w-16"> <span className="w-16">

View File

@@ -143,7 +143,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
value={actionFilter} value={actionFilter}
onChange={(e) => { setActionFilter(e.target.value); setPage(1) }} onChange={(e) => { setActionFilter(e.target.value); setPage(1) }}
aria-label="Filter by action" aria-label="Filter by action"
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
> >
{ACTION_TYPES.map((a) => ( {ACTION_TYPES.map((a) => (
<option key={a.value} value={a.value}> <option key={a.value} value={a.value}>
@@ -160,7 +160,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
value={dateFrom} value={dateFrom}
onChange={(e) => { setDateFrom(e.target.value); setPage(1) }} onChange={(e) => { setDateFrom(e.target.value); setPage(1) }}
aria-label="Filter from date" aria-label="Filter from date"
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
/> />
</div> </div>
@@ -172,7 +172,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
value={dateTo} value={dateTo}
onChange={(e) => { setDateTo(e.target.value); setPage(1) }} onChange={(e) => { setDateTo(e.target.value); setPage(1) }}
aria-label="Filter to date" aria-label="Filter to date"
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
/> />
</div> </div>
@@ -185,7 +185,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
value={userSearch} value={userSearch}
onChange={(e) => setUserSearch(e.target.value)} onChange={(e) => setUserSearch(e.target.value)}
aria-label="Filter by user" aria-label="Filter by user"
className="h-8 rounded-md border border-border bg-surface pl-7 pr-2 text-xs text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-1 focus:ring-accent w-40" className="h-8 rounded-md border border-border bg-panel pl-7 pr-2 text-xs text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-1 focus:ring-accent w-40"
/> />
</div> </div>
@@ -196,7 +196,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
<button <button
onClick={handleExport} onClick={handleExport}
disabled={exporting || !data?.total} disabled={exporting || !data?.total}
className="inline-flex items-center gap-1.5 rounded-md border border-border bg-surface px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-elevated hover:text-text-primary transition-colors disabled:opacity-50 disabled:cursor-not-allowed" className="inline-flex items-center gap-1.5 rounded-md border border-border bg-panel px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-elevated hover:text-text-primary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
> >
<Download className="h-3.5 w-3.5" /> <Download className="h-3.5 w-3.5" />
{exporting ? 'Exporting...' : 'Export CSV'} {exporting ? 'Exporting...' : 'Export CSV'}
@@ -204,7 +204,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
</div> </div>
{/* Table */} {/* Table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{isLoading ? ( {isLoading ? (
<div className="p-8 text-center"> <div className="p-8 text-center">
<div className="inline-block h-6 w-6 animate-spin rounded-full border-2 border-accent border-t-transparent" /> <div className="inline-block h-6 w-6 animate-spin rounded-full border-2 border-accent border-t-transparent" />
@@ -278,7 +278,7 @@ export function AuditLogTable({ tenantId }: AuditLogTableProps) {
setPage(1) setPage(1)
}} }}
aria-label="Rows per page" aria-label="Rows per page"
className="h-7 rounded border border-border bg-surface px-1.5 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-7 rounded border border-border bg-panel px-1.5 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
> >
{PER_PAGE_OPTIONS.map((n) => ( {PER_PAGE_OPTIONS.map((n) => (
<option key={n} value={n}> <option key={n} value={n}>

View File

@@ -220,7 +220,7 @@ export function EmergencyKitDialog({
<div className="flex gap-2"> <div className="flex gap-2">
<button <button
onClick={handleCopy} onClick={handleCopy}
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border bg-surface px-4 py-2.5 text-sm font-medium text-text-primary transition-colors hover:bg-surface-hover" className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border bg-panel px-4 py-2.5 text-sm font-medium text-text-primary transition-colors hover:bg-panel-hover"
> >
{copied ? ( {copied ? (
<> <>
@@ -245,7 +245,7 @@ export function EmergencyKitDialog({
</div> </div>
{/* Instructions */} {/* Instructions */}
<div className="mt-3 rounded-md bg-surface-secondary p-3 text-xs text-text-secondary leading-relaxed"> <div className="mt-3 rounded-md bg-panel-secondary p-3 text-xs text-text-secondary leading-relaxed">
The PDF includes your Secret Key. Print it or save it securely. The PDF includes your Secret Key. Print it or save it securely.
You can also store the key in your password manager. Do NOT store it alongside your password. You can also store the key in your password manager. Do NOT store it alongside your password.
</div> </div>

View File

@@ -134,7 +134,7 @@ export function SrpUpgradeDialog({
</div> </div>
) : ( ) : (
<> <>
<div className="rounded-md bg-surface-secondary p-4 text-sm text-text-secondary leading-relaxed space-y-3"> <div className="rounded-md bg-panel-secondary p-4 text-sm text-text-secondary leading-relaxed space-y-3">
<p> <p>
<strong>What happens:</strong> <strong>What happens:</strong>
</p> </p>

View File

@@ -275,7 +275,7 @@ export function BulkDeployDialog({
'rounded-lg border p-4 text-center', 'rounded-lg border p-4 text-center',
result.failed > 0 result.failed > 0
? 'border-error/30 bg-error/5' ? 'border-error/30 bg-error/5'
: 'border-border bg-surface', : 'border-border bg-panel',
)} )}
> >
<XCircle <XCircle

View File

@@ -76,7 +76,7 @@ export function CAStatusCard({ ca, canWrite: writable, tenantId }: CAStatusCardP
if (!ca) { if (!ca) {
return ( return (
<div className="max-w-lg mx-auto"> <div className="max-w-lg mx-auto">
<div className="rounded-lg border border-border bg-surface p-8 text-center space-y-6"> <div className="rounded-lg border border-border bg-panel p-8 text-center space-y-6">
<div className="mx-auto w-16 h-16 rounded-2xl bg-accent/10 flex items-center justify-center"> <div className="mx-auto w-16 h-16 rounded-2xl bg-accent/10 flex items-center justify-center">
<Shield className="h-8 w-8 text-accent" /> <Shield className="h-8 w-8 text-accent" />
</div> </div>
@@ -118,7 +118,7 @@ export function CAStatusCard({ ca, canWrite: writable, tenantId }: CAStatusCardP
return ( return (
<div <div
className={cn( className={cn(
'rounded-lg border bg-surface p-6 space-y-4', 'rounded-lg border bg-panel p-6 space-y-4',
isExpired ? 'border-error/40' : 'border-success/30', isExpired ? 'border-error/40' : 'border-success/30',
)} )}
> >

View File

@@ -204,7 +204,7 @@ export function CommandPalette() {
const visiblePages = pageCommands.filter((p) => p.visible) const visiblePages = pageCommands.filter((p) => p.visible)
const itemClass = const itemClass =
'flex items-center gap-3 px-2 py-2 rounded-lg text-sm text-text-secondary cursor-pointer data-[selected=true]:bg-accent-muted data-[selected=true]:text-accent' 'flex items-center gap-3 px-2 py-2 rounded-lg text-sm text-text-secondary cursor-pointer data-[selected=true]:bg-accent-soft data-[selected=true]:text-accent'
const groupHeadingClass = const groupHeadingClass =
'[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:text-text-muted [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider' '[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:text-text-muted [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider'
@@ -216,7 +216,7 @@ export function CommandPalette() {
overlayClassName="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm" overlayClassName="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm"
contentClassName="fixed left-1/2 top-[20%] -translate-x-1/2 z-50 w-full max-w-lg" contentClassName="fixed left-1/2 top-[20%] -translate-x-1/2 z-50 w-full max-w-lg"
> >
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center gap-2 px-4 border-b border-border"> <div className="flex items-center gap-2 px-4 border-b border-border">
<Search className="h-4 w-4 text-text-muted flex-shrink-0" /> <Search className="h-4 w-4 text-text-muted flex-shrink-0" />
<Command.Input <Command.Input

View File

@@ -136,7 +136,7 @@ export function CommandExecutor({ tenantId, deviceId, currentPath }: CommandExec
{results.length > 0 && ( {results.length > 0 && (
<div className="max-h-48 overflow-y-auto space-y-2"> <div className="max-h-48 overflow-y-auto space-y-2">
{results.map((r, i) => ( {results.map((r, i) => (
<div key={i} className="bg-surface border-border rounded-md font-mono text-xs p-2 border"> <div key={i} className="bg-panel border-border rounded-md font-mono text-xs p-2 border">
<div className="flex items-center gap-2 mb-1"> <div className="flex items-center gap-2 mb-1">
<span className="text-[10px] text-text-muted">{r.timestamp}</span> <span className="text-[10px] text-text-muted">{r.timestamp}</span>
<span className="text-xs font-mono text-text-secondary">{r.command}</span> <span className="text-xs font-mono text-text-secondary">{r.command}</span>

View File

@@ -325,7 +325,7 @@ export function ConfigEditorPage() {
{/* Delete Confirmation Dialog */} {/* Delete Confirmation Dialog */}
<Dialog open={deleteConfirmOpen} onOpenChange={(o) => !o && setDeleteConfirmOpen(false)}> <Dialog open={deleteConfirmOpen} onOpenChange={(o) => !o && setDeleteConfirmOpen(false)}>
<DialogContent className="max-w-sm bg-surface border-border text-text-primary"> <DialogContent className="max-w-sm bg-panel border-border text-text-primary">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-sm">Confirm Delete</DialogTitle> <DialogTitle className="text-sm">Confirm Delete</DialogTitle>
</DialogHeader> </DialogHeader>

View File

@@ -143,7 +143,7 @@ export function EntryForm({ open, onClose, mode, entry, columns, onSubmit }: Ent
return ( return (
<Dialog open={open} onOpenChange={(o) => !o && onClose()}> <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
<DialogContent className="max-w-lg max-h-[80vh] overflow-y-auto bg-surface border-border text-text-primary"> <DialogContent className="max-w-lg max-h-[80vh] overflow-y-auto bg-panel border-border text-text-primary">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-sm"> <DialogTitle className="text-sm">
{mode === 'add' ? 'Add New Entry' : 'Edit Entry'} {mode === 'add' ? 'Add New Entry' : 'Edit Entry'}

View File

@@ -42,7 +42,7 @@ export function EntryTable({
className={cn( className={cn(
'rounded-lg border p-4 text-sm', 'rounded-lg border p-4 text-sm',
isContainerPath isContainerPath
? 'border-border bg-surface text-text-secondary' ? 'border-border bg-panel text-text-secondary'
: 'border-error/30 bg-error/10 text-error', : 'border-error/30 bg-error/10 text-error',
)} )}
> >
@@ -70,7 +70,7 @@ export function EntryTable({
<div className="h-8 w-24 bg-elevated/50 rounded animate-pulse" /> <div className="h-8 w-24 bg-elevated/50 rounded animate-pulse" />
</div> </div>
{Array.from({ length: 5 }).map((_, i) => ( {Array.from({ length: 5 }).map((_, i) => (
<div key={i} className="h-10 bg-surface rounded animate-pulse" /> <div key={i} className="h-10 bg-panel rounded animate-pulse" />
))} ))}
</div> </div>
) )
@@ -128,7 +128,7 @@ export function EntryTable({
<tr <tr
key={entry['.id'] || i} key={entry['.id'] || i}
className={cn( className={cn(
'border-b border-border/50 hover:bg-surface transition-colors', 'border-b border-border/50 hover:bg-panel transition-colors',
entry['dynamic'] === 'true' && 'text-text-muted', entry['dynamic'] === 'true' && 'text-text-muted',
)} )}
> >

View File

@@ -265,7 +265,7 @@ function TreeItem({
className={cn( className={cn(
'flex items-center gap-1.5 w-full px-2 py-1 text-xs rounded transition-colors', 'flex items-center gap-1.5 w-full px-2 py-1 text-xs rounded transition-colors',
isActive isActive
? 'bg-[hsl(var(--accent-muted))] text-accent' ? 'bg-[hsl(var(--accent-soft))] text-accent'
: 'text-text-secondary hover:text-text-primary hover:bg-elevated/50', : 'text-text-secondary hover:text-text-primary hover:bg-elevated/50',
)} )}
style={{ paddingLeft: `${depth * 12 + 8}px` }} style={{ paddingLeft: `${depth * 12 + 8}px` }}

View File

@@ -145,7 +145,7 @@ export function AddressListPanel({ tenantId, deviceId, active }: ConfigPanelProp
</Button> </Button>
</div> </div>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<List className="h-4 w-4" /> <List className="h-4 w-4" />

View File

@@ -282,7 +282,7 @@ function AddressTable({
return ( return (
<> <>
{/* Table */} {/* Table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Network className="h-4 w-4" /> <Network className="h-4 w-4" />

View File

@@ -193,8 +193,8 @@ export function ArpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
className={cn( className={cn(
'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', 'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
filterTab === tab.key filterTab === tab.key
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-secondary hover:text-text-primary hover:bg-surface/50', : 'text-text-secondary hover:text-text-primary hover:bg-panel/50',
)} )}
> >
{tab.label} {tab.label}
@@ -290,7 +290,7 @@ function ArpTable({
return ( return (
<> <>
{/* Table */} {/* Table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Network className="h-4 w-4" /> <Network className="h-4 w-4" />

View File

@@ -82,7 +82,7 @@ export function BandwidthTestTool({ tenantId, deviceId }: ConfigPanelProps) {
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3"> <div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
<div className="space-y-1 col-span-2 sm:col-span-1"> <div className="space-y-1 col-span-2 sm:col-span-1">
<Label className="text-xs text-text-secondary">Target Address</Label> <Label className="text-xs text-text-secondary">Target Address</Label>
@@ -99,7 +99,7 @@ export function BandwidthTestTool({ tenantId, deviceId }: ConfigPanelProps) {
<select <select
value={direction} value={direction}
onChange={(e) => setDirection(e.target.value)} onChange={(e) => setDirection(e.target.value)}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="both">Both</option> <option value="both">Both</option>
<option value="send">Send</option> <option value="send">Send</option>
@@ -111,7 +111,7 @@ export function BandwidthTestTool({ tenantId, deviceId }: ConfigPanelProps) {
<select <select
value={protocol} value={protocol}
onChange={(e) => setProtocol(e.target.value)} onChange={(e) => setProtocol(e.target.value)}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="tcp">TCP</option> <option value="tcp">TCP</option>
<option value="udp">UDP</option> <option value="udp">UDP</option>
@@ -170,7 +170,7 @@ export function BandwidthTestTool({ tenantId, deviceId }: ConfigPanelProps) {
)} )}
{results.length > 0 && ( {results.length > 0 && (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50 flex items-center gap-2"> <div className="px-4 py-2 border-b border-border/50 flex items-center gap-2">
<Gauge className="h-4 w-4 text-accent" /> <Gauge className="h-4 w-4 text-accent" />
<span className="text-sm font-medium text-text-secondary">Bandwidth Test Results</span> <span className="text-sm font-medium text-text-secondary">Bandwidth Test Results</span>

View File

@@ -184,7 +184,7 @@ function DeviceSelector({
if (devices.length === 0) { if (devices.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-8 text-center"> <div className="rounded-lg border border-border bg-panel p-8 text-center">
<p className="text-text-muted text-sm">No devices found for this tenant.</p> <p className="text-text-muted text-sm">No devices found for this tenant.</p>
</div> </div>
) )
@@ -208,7 +208,7 @@ function DeviceSelector({
</div> </div>
</div> </div>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/50"> <tr className="border-b border-border bg-elevated/50">
@@ -327,7 +327,7 @@ function ChangeDefiner({
</div> </div>
{operationType && ( {operationType && (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
{operationType === 'add-firewall-rule' && ( {operationType === 'add-firewall-rule' && (
<> <>
<h4 className="text-sm font-medium text-text-secondary">Firewall Rule</h4> <h4 className="text-sm font-medium text-text-secondary">Firewall Rule</h4>
@@ -605,7 +605,7 @@ function ExecutionPanel({
return ( return (
<div className="space-y-4"> <div className="space-y-4">
{/* Change description */} {/* Change description */}
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<h4 className="text-sm font-medium text-text-secondary mb-1">Change to Apply</h4> <h4 className="text-sm font-medium text-text-secondary mb-1">Change to Apply</h4>
<p className="text-sm text-text-primary">{change.description}</p> <p className="text-sm text-text-primary">{change.description}</p>
<p className="text-xs text-text-muted mt-1 font-mono"> <p className="text-xs text-text-muted mt-1 font-mono">
@@ -626,7 +626,7 @@ function ExecutionPanel({
{/* Summary */} {/* Summary */}
{isComplete && ( {isComplete && (
<div className="rounded-lg border border-border bg-surface p-4 flex items-center gap-4"> <div className="rounded-lg border border-border bg-panel p-4 flex items-center gap-4">
<div className="flex items-center gap-2 text-success"> <div className="flex items-center gap-2 text-success">
<CheckCircle className="h-5 w-5" /> <CheckCircle className="h-5 w-5" />
<span className="text-sm font-medium">{successCount} succeeded</span> <span className="text-sm font-medium">{successCount} succeeded</span>
@@ -641,7 +641,7 @@ function ExecutionPanel({
)} )}
{/* Device status table */} {/* Device status table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/50"> <tr className="border-b border-border bg-elevated/50">

View File

@@ -138,11 +138,11 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
</div> </div>
{ports.entries.length === 0 ? ( {ports.entries.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-sm text-text-muted">
No bridge ports configured. No bridge ports configured.
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-xs"> <table className="w-full text-xs">
<thead> <thead>
@@ -212,7 +212,7 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['interface'] || ''} value={formData['interface'] || ''}
onChange={(e) => setFormData((f) => ({ ...f, interface: e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, interface: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary font-mono" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary font-mono"
> >
<option value="">Select...</option> <option value="">Select...</option>
{ifaceNames.map((name) => <option key={name} value={name}>{name}</option>)} {ifaceNames.map((name) => <option key={name} value={name}>{name}</option>)}
@@ -223,7 +223,7 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['bridge'] || ''} value={formData['bridge'] || ''}
onChange={(e) => setFormData((f) => ({ ...f, bridge: e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, bridge: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary font-mono" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary font-mono"
> >
{bridgeNames.map((name) => <option key={name} value={name}>{name}</option>)} {bridgeNames.map((name) => <option key={name} value={name}>{name}</option>)}
</select> </select>
@@ -243,7 +243,7 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['frame-types'] || 'admit-all'} value={formData['frame-types'] || 'admit-all'}
onChange={(e) => setFormData((f) => ({ ...f, 'frame-types': e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, 'frame-types': e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
{FRAME_TYPES.map((ft) => <option key={ft} value={ft}>{ft}</option>)} {FRAME_TYPES.map((ft) => <option key={ft} value={ft}>{ft}</option>)}
</select> </select>
@@ -253,7 +253,7 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['ingress-filtering'] || 'no'} value={formData['ingress-filtering'] || 'no'}
onChange={(e) => setFormData((f) => ({ ...f, 'ingress-filtering': e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, 'ingress-filtering': e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="yes">Yes</option> <option value="yes">Yes</option>
<option value="no">No</option> <option value="no">No</option>
@@ -264,7 +264,7 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['hw'] || 'yes'} value={formData['hw'] || 'yes'}
onChange={(e) => setFormData((f) => ({ ...f, hw: e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, hw: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="yes">Yes</option> <option value="yes">Yes</option>
<option value="no">No</option> <option value="no">No</option>
@@ -297,7 +297,7 @@ export function BridgePortPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['edge'] || 'auto'} value={formData['edge'] || 'auto'}
onChange={(e) => setFormData((f) => ({ ...f, edge: e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, edge: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="auto">Auto</option> <option value="auto">Auto</option>
<option value="yes">Yes</option> <option value="yes">Yes</option>

View File

@@ -140,7 +140,7 @@ export function BridgeVlanPanel({ tenantId, deviceId, active }: ConfigPanelProps
{/* VLAN Filtering status per bridge */} {/* VLAN Filtering status per bridge */}
{bridges.entries.length > 0 && ( {bridges.entries.length > 0 && (
<div className="rounded-lg border border-border bg-surface p-3"> <div className="rounded-lg border border-border bg-panel p-3">
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-2">
<Network className="h-4 w-4 text-accent" /> <Network className="h-4 w-4 text-accent" />
<span className="text-sm font-medium text-text-secondary">Bridge VLAN Filtering</span> <span className="text-sm font-medium text-text-secondary">Bridge VLAN Filtering</span>
@@ -170,11 +170,11 @@ export function BridgeVlanPanel({ tenantId, deviceId, active }: ConfigPanelProps
{/* VLAN Table */} {/* VLAN Table */}
{vlans.entries.length === 0 ? ( {vlans.entries.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-sm text-text-muted">
No bridge VLAN entries configured. No bridge VLAN entries configured.
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-xs"> <table className="w-full text-xs">
<thead> <thead>
@@ -247,7 +247,7 @@ export function BridgeVlanPanel({ tenantId, deviceId, active }: ConfigPanelProps
<select <select
value={formData['bridge'] || ''} value={formData['bridge'] || ''}
onChange={(e) => setFormData((f) => ({ ...f, bridge: e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, bridge: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary font-mono" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary font-mono"
> >
{bridgeNames.map((name) => <option key={name} value={name}>{name}</option>)} {bridgeNames.map((name) => <option key={name} value={name}>{name}</option>)}
</select> </select>

View File

@@ -81,9 +81,9 @@ export function ConfigDiffViewer({
const isLoading = loadingOld || loadingNew const isLoading = loadingOld || loadingNew
return ( return (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between px-4 py-2.5 border-b border-border bg-surface"> <div className="flex items-center justify-between px-4 py-2.5 border-b border-border bg-panel">
<div className="flex items-center gap-2 text-xs text-text-muted"> <div className="flex items-center gap-2 text-xs text-text-muted">
{isEncrypted && ( {isEncrypted && (
<span className="inline-flex items-center gap-1 text-info" title="Decrypted from encrypted backup"> <span className="inline-flex items-center gap-1 text-info" title="Decrypted from encrypted backup">

View File

@@ -65,7 +65,7 @@ export function ConfigHistorySection({ tenantId, deviceId, deviceName }: ConfigH
}) })
return ( return (
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="flex items-center gap-2 mb-3"> <div className="flex items-center gap-2 mb-3">
<History className="h-4 w-4 text-text-muted" /> <History className="h-4 w-4 text-text-muted" />
<h3 className="text-sm font-medium text-text-muted">Configuration History</h3> <h3 className="text-sm font-medium text-text-muted">Configuration History</h3>

View File

@@ -162,12 +162,12 @@ export function ConfigTab({
{[0, 1, 2].map((i) => ( {[0, 1, 2].map((i) => (
<div <div
key={i} key={i}
className="h-14 rounded-lg border border-border bg-surface animate-pulse" className="h-14 rounded-lg border border-border bg-panel animate-pulse"
/> />
))} ))}
</div> </div>
) : !backups || backups.length === 0 ? ( ) : !backups || backups.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-sm text-text-muted">
No backups yet. Click &lsquo;Backup Now&rsquo; to create the first backup. No backups yet. Click &lsquo;Backup Now&rsquo; to create the first backup.
</div> </div>
) : ( ) : (
@@ -201,7 +201,7 @@ export function ConfigTab({
} }
/> />
) : ( ) : (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-sm text-text-muted h-full flex items-center justify-center min-h-32"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-sm text-text-muted h-full flex items-center justify-center min-h-32">
{selectedShas.length < 2 {selectedShas.length < 2
? 'Select two backups from the timeline to compare' ? 'Select two backups from the timeline to compare'
: 'Click "Compare selected" to view the diff'} : 'Click "Compare selected" to view the diff'}

View File

@@ -104,7 +104,7 @@ export function ConnTrackPanel({ tenantId, deviceId, active }: ConfigPanelProps)
</div> </div>
{/* Active connections count */} {/* Active connections count */}
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Activity className="h-5 w-5 text-accent" /> <Activity className="h-5 w-5 text-accent" />
<div> <div>
@@ -120,7 +120,7 @@ export function ConnTrackPanel({ tenantId, deviceId, active }: ConfigPanelProps)
</div> </div>
{/* Tracking settings */} {/* Tracking settings */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">Connection Tracking Settings</span> <span className="text-sm font-medium text-text-secondary">Connection Tracking Settings</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleEdit}> <Button size="sm" variant="outline" className="gap-1" onClick={handleEdit}>
@@ -154,7 +154,7 @@ export function ConnTrackPanel({ tenantId, deviceId, active }: ConfigPanelProps)
<select <select
value={formData['enabled'] || 'auto'} value={formData['enabled'] || 'auto'}
onChange={(e) => setFormData((f) => ({ ...f, enabled: e.target.value }))} onChange={(e) => setFormData((f) => ({ ...f, enabled: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="auto">Auto</option> <option value="auto">Auto</option>
<option value="yes">Yes</option> <option value="yes">Yes</option>

View File

@@ -206,7 +206,7 @@ export function DhcpClientPanel({ tenantId, deviceId, active }: ConfigPanelProps
</div> </div>
{/* DHCP Client table */} {/* DHCP Client table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Globe className="h-4 w-4" /> <Globe className="h-4 w-4" />

View File

@@ -240,8 +240,8 @@ export function DhcpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
className={cn( className={cn(
'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', 'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
activeTab === tab.key activeTab === tab.key
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-secondary hover:text-text-primary hover:bg-surface/50', : 'text-text-secondary hover:text-text-primary hover:bg-panel/50',
)} )}
> >
{tab.icon} {tab.icon}
@@ -400,7 +400,7 @@ function ServersTab({
}, [form, editing, panel]) }, [form, editing, panel])
return ( return (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-text-primary">DHCP Servers</h3> <h3 className="text-sm font-medium text-text-primary">DHCP Servers</h3>
<Button variant="outline" size="sm" onClick={handleAdd} className="gap-1.5"> <Button variant="outline" size="sm" onClick={handleAdd} className="gap-1.5">
@@ -651,7 +651,7 @@ function PoolsTab({
}, [form, editing, panel]) }, [form, editing, panel])
return ( return (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-text-primary">Address Pools</h3> <h3 className="text-sm font-medium text-text-primary">Address Pools</h3>
<Button variant="outline" size="sm" onClick={handleAdd} className="gap-1.5"> <Button variant="outline" size="sm" onClick={handleAdd} className="gap-1.5">
@@ -860,7 +860,7 @@ function LeasesTab({
} }
return ( return (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-text-primary">DHCP Leases</h3> <h3 className="text-sm font-medium text-text-primary">DHCP Leases</h3>
<Button variant="outline" size="sm" onClick={handleAddStatic} className="gap-1.5"> <Button variant="outline" size="sm" onClick={handleAddStatic} className="gap-1.5">
@@ -1112,7 +1112,7 @@ function NetworksTab({
}, [form, editing, panel]) }, [form, editing, panel])
return ( return (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-text-primary">DHCP Networks</h3> <h3 className="text-sm font-medium text-text-primary">DHCP Networks</h3>
<Button variant="outline" size="sm" onClick={handleAdd} className="gap-1.5"> <Button variant="outline" size="sm" onClick={handleAdd} className="gap-1.5">

View File

@@ -24,7 +24,7 @@ export function DiffViewer({ tenantId, deviceId, snapshotId, onClose }: DiffView
}) })
return ( return (
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between mb-3"> <div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">

View File

@@ -302,7 +302,7 @@ export function DnsPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
</div> </div>
{/* Section 1: Resolver Settings */} {/* Section 1: Resolver Settings */}
<div className="rounded-lg border border-border bg-surface p-4 space-y-4"> <div className="rounded-lg border border-border bg-panel p-4 space-y-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Server className="h-4 w-4 text-accent" /> <Server className="h-4 w-4 text-accent" />
@@ -393,7 +393,7 @@ export function DnsPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
</div> </div>
{/* Section 2: Static DNS Entries */} {/* Section 2: Static DNS Entries */}
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Globe className="h-4 w-4 text-accent" /> <Globe className="h-4 w-4 text-accent" />

View File

@@ -643,7 +643,7 @@ function FilterRulesTable({
</Button> </Button>
</div> </div>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
@@ -836,7 +836,7 @@ function NatRulesTable({
</Button> </Button>
</div> </div>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>

View File

@@ -233,7 +233,7 @@ export function InterfacesPanel({ tenantId, deviceId, active }: ConfigPanelProps
function TableSkeleton({ rows = 5 }: { rows?: number }) { function TableSkeleton({ rows = 5 }: { rows?: number }) {
return ( return (
<div className="rounded-lg border border-border bg-surface"> <div className="rounded-lg border border-border bg-panel">
<div className="p-3 border-b border-border"> <div className="p-3 border-b border-border">
<Skeleton className="h-4 w-32" /> <Skeleton className="h-4 w-32" />
</div> </div>
@@ -264,14 +264,14 @@ function InterfacesTable({
if (entries.length === 0) { if (entries.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-text-secondary text-sm"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-text-secondary text-sm">
No interfaces found on this device. No interfaces found on this device.
</div> </div>
) )
} }
return ( return (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">
@@ -374,11 +374,11 @@ function IpAddressesTab({ entries, isLoading, interfaceNames, addChange }: IpAdd
</div> </div>
{entries.length === 0 ? ( {entries.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-text-secondary text-sm"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-text-secondary text-sm">
No IP addresses configured. No IP addresses configured.
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">
@@ -633,11 +633,11 @@ function VlansTab({ entries, isLoading, interfaceNames, addChange }: VlansTabPro
</div> </div>
{entries.length === 0 ? ( {entries.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-text-secondary text-sm"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-text-secondary text-sm">
No VLANs configured. No VLANs configured.
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">
@@ -941,11 +941,11 @@ function BridgesTab({
</div> </div>
{bridges.length === 0 ? ( {bridges.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-text-secondary text-sm"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-text-secondary text-sm">
No bridges configured. No bridges configured.
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">
@@ -1015,11 +1015,11 @@ function BridgesTab({
</div> </div>
{bridgePorts.length === 0 ? ( {bridgePorts.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-text-secondary text-sm"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-text-secondary text-sm">
No bridge ports configured. No bridge ports configured.
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">

View File

@@ -87,7 +87,7 @@ export function IpsecPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
{SUB_TABS.map((tab) => ( {SUB_TABS.map((tab) => (
<button key={tab.key} onClick={() => setActiveTab(tab.key)} <button key={tab.key} onClick={() => setActiveTab(tab.key)}
className={cn('flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', className={cn('flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
activeTab === tab.key ? 'bg-surface text-text-primary shadow-sm' : 'text-text-secondary hover:text-text-primary hover:bg-surface/50')}> activeTab === tab.key ? 'bg-panel text-text-primary shadow-sm' : 'text-text-secondary hover:text-text-primary hover:bg-panel/50')}>
{tab.icon}{tab.label} {tab.icon}{tab.label}
</button> </button>
))} ))}
@@ -147,11 +147,11 @@ function PeersTab({ entries, panel }: { entries: PeerEntry[]; panel: PanelHook }
<div className="space-y-1"><Label className="text-xs text-text-secondary">Address</Label><Input value={form.address} onChange={(e) => setForm((f) => ({ ...f, address: e.target.value }))} placeholder="0.0.0.0/0" className="h-8 text-sm font-mono" /></div> <div className="space-y-1"><Label className="text-xs text-text-secondary">Address</Label><Input value={form.address} onChange={(e) => setForm((f) => ({ ...f, address: e.target.value }))} placeholder="0.0.0.0/0" className="h-8 text-sm font-mono" /></div>
<div className="grid grid-cols-2 gap-3"> <div className="grid grid-cols-2 gap-3">
<div className="space-y-1"><Label className="text-xs text-text-secondary">Auth Method</Label> <div className="space-y-1"><Label className="text-xs text-text-secondary">Auth Method</Label>
<select value={form['auth-method']} onChange={(e) => setForm((f) => ({ ...f, 'auth-method': e.target.value }))} className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> <select value={form['auth-method']} onChange={(e) => setForm((f) => ({ ...f, 'auth-method': e.target.value }))} className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
<option value="pre-shared-key">Pre-Shared Key</option><option value="rsa-key">RSA Key</option><option value="rsa-signature">RSA Signature</option> <option value="pre-shared-key">Pre-Shared Key</option><option value="rsa-key">RSA Key</option><option value="rsa-signature">RSA Signature</option>
</select></div> </select></div>
<div className="space-y-1"><Label className="text-xs text-text-secondary">Exchange Mode</Label> <div className="space-y-1"><Label className="text-xs text-text-secondary">Exchange Mode</Label>
<select value={form['exchange-mode']} onChange={(e) => setForm((f) => ({ ...f, 'exchange-mode': e.target.value }))} className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> <select value={form['exchange-mode']} onChange={(e) => setForm((f) => ({ ...f, 'exchange-mode': e.target.value }))} className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
<option value="main">Main</option><option value="aggressive">Aggressive</option><option value="ike2">IKEv2</option> <option value="main">Main</option><option value="aggressive">Aggressive</option><option value="ike2">IKEv2</option>
</select></div> </select></div>
</div> </div>
@@ -208,8 +208,8 @@ function PoliciesTab({ entries, panel }: { entries: PolicyEntry[]; panel: PanelH
<div className="space-y-1"><Label className="text-xs text-text-secondary">Dst Address</Label><Input value={form['dst-address']} onChange={(e) => setForm((f) => ({ ...f, 'dst-address': e.target.value }))} placeholder="10.0.0.0/24" className="h-8 text-sm font-mono" /></div> <div className="space-y-1"><Label className="text-xs text-text-secondary">Dst Address</Label><Input value={form['dst-address']} onChange={(e) => setForm((f) => ({ ...f, 'dst-address': e.target.value }))} placeholder="10.0.0.0/24" className="h-8 text-sm font-mono" /></div>
</div> </div>
<div className="grid grid-cols-3 gap-3"> <div className="grid grid-cols-3 gap-3">
<div className="space-y-1"><Label className="text-xs text-text-secondary">Tunnel</Label><select value={form.tunnel} onChange={(e) => setForm((f) => ({ ...f, tunnel: e.target.value }))} className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"><option value="yes">Yes</option><option value="no">No</option></select></div> <div className="space-y-1"><Label className="text-xs text-text-secondary">Tunnel</Label><select value={form.tunnel} onChange={(e) => setForm((f) => ({ ...f, tunnel: e.target.value }))} className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"><option value="yes">Yes</option><option value="no">No</option></select></div>
<div className="space-y-1"><Label className="text-xs text-text-secondary">Action</Label><select value={form.action} onChange={(e) => setForm((f) => ({ ...f, action: e.target.value }))} className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"><option value="encrypt">Encrypt</option><option value="none">None</option></select></div> <div className="space-y-1"><Label className="text-xs text-text-secondary">Action</Label><select value={form.action} onChange={(e) => setForm((f) => ({ ...f, action: e.target.value }))} className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"><option value="encrypt">Encrypt</option><option value="none">None</option></select></div>
<div className="space-y-1"><Label className="text-xs text-text-secondary">Proposal</Label><Input value={form.proposal} onChange={(e) => setForm((f) => ({ ...f, proposal: e.target.value }))} className="h-8 text-sm" /></div> <div className="space-y-1"><Label className="text-xs text-text-secondary">Proposal</Label><Input value={form.proposal} onChange={(e) => setForm((f) => ({ ...f, proposal: e.target.value }))} className="h-8 text-sm" /></div>
</div> </div>
</div> </div>
@@ -275,7 +275,7 @@ function ProposalsTab({ entries, panel }: { entries: ProposalEntry[]; panel: Pan
function SasTab({ entries }: { entries: SaEntry[] }) { function SasTab({ entries }: { entries: SaEntry[] }) {
return ( return (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50"><span className="text-sm font-medium text-text-secondary">Installed SAs ({entries.length})</span></div> <div className="px-4 py-2 border-b border-border/50"><span className="text-sm font-medium text-text-secondary">Installed SAs ({entries.length})</span></div>
{entries.length === 0 ? <div className="px-4 py-8 text-center text-sm text-text-muted">No active security associations.</div> : ( {entries.length === 0 ? <div className="px-4 py-8 text-center text-sm text-text-muted">No active security associations.</div> : (
<div className="overflow-x-auto"><table className="w-full text-sm"><thead><tr className="border-b border-border/50 text-text-secondary text-xs"> <div className="overflow-x-auto"><table className="w-full text-sm"><thead><tr className="border-b border-border/50 text-text-secondary text-xs">
@@ -301,7 +301,7 @@ function SasTab({ entries }: { entries: SaEntry[] }) {
function TableWrapper({ title, count, onAdd, children }: { title: string; count: number; onAdd: () => void; children: React.ReactNode }) { function TableWrapper({ title, count, onAdd, children }: { title: string; count: number; onAdd: () => void; children: React.ReactNode }) {
return ( return (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">{title} ({count})</span> <span className="text-sm font-medium text-text-secondary">{title} ({count})</span>
<Button size="sm" variant="outline" className="gap-1" onClick={onAdd}><Plus className="h-3.5 w-3.5" />Add</Button> <Button size="sm" variant="outline" className="gap-1" onClick={onAdd}><Plus className="h-3.5 w-3.5" />Add</Button>

View File

@@ -127,7 +127,7 @@ export function ManglePanel({ tenantId, deviceId, active }: ConfigPanelProps) {
onClick={() => setChainFilter(chain)} onClick={() => setChainFilter(chain)}
className={cn( className={cn(
'px-3 py-1.5 rounded-md text-sm font-medium transition-colors capitalize', 'px-3 py-1.5 rounded-md text-sm font-medium transition-colors capitalize',
chainFilter === chain ? 'bg-surface text-text-primary shadow-sm' : 'text-text-secondary hover:text-text-primary hover:bg-surface/50', chainFilter === chain ? 'bg-panel text-text-primary shadow-sm' : 'text-text-secondary hover:text-text-primary hover:bg-panel/50',
)} )}
> >
{chain} {chain}
@@ -193,7 +193,7 @@ function MangleTable({ entries, panel }: { entries: MangleEntry[]; panel: PanelH
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Filter className="h-4 w-4" /> <Filter className="h-4 w-4" />

View File

@@ -90,7 +90,7 @@ export function PingTool({ tenantId, deviceId }: ConfigPanelProps) {
return ( return (
<div className="space-y-4"> <div className="space-y-4">
{/* Input form */} {/* Input form */}
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="grid grid-cols-2 gap-3 sm:grid-cols-4"> <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
<div className="space-y-1 col-span-2"> <div className="space-y-1 col-span-2">
<Label className="text-xs text-text-secondary">Target IP / Hostname</Label> <Label className="text-xs text-text-secondary">Target IP / Hostname</Label>
@@ -166,7 +166,7 @@ export function PingTool({ tenantId, deviceId }: ConfigPanelProps) {
)} )}
{results.length > 0 && ( {results.length > 0 && (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50 flex items-center gap-2"> <div className="px-4 py-2 border-b border-border/50 flex items-center gap-2">
<Activity className="h-4 w-4 text-accent" /> <Activity className="h-4 w-4 text-accent" />
<span className="text-sm font-medium text-text-secondary">Ping Results</span> <span className="text-sm font-medium text-text-secondary">Ping Results</span>
@@ -189,7 +189,7 @@ export function PingTool({ tenantId, deviceId }: ConfigPanelProps) {
{/* Stats summary */} {/* Stats summary */}
{stats && ( {stats && (
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="grid grid-cols-3 sm:grid-cols-6 gap-4 text-center"> <div className="grid grid-cols-3 sm:grid-cols-6 gap-4 text-center">
<StatBox label="Sent" value={String(stats.sent)} /> <StatBox label="Sent" value={String(stats.sent)} />
<StatBox label="Received" value={String(stats.received)} /> <StatBox label="Received" value={String(stats.received)} />

View File

@@ -275,7 +275,7 @@ function PoolTable({
return ( return (
<> <>
{/* Table */} {/* Table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Layers className="h-4 w-4" /> <Layers className="h-4 w-4" />

View File

@@ -98,7 +98,7 @@ export function PppPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
{SUB_TABS.map((tab) => ( {SUB_TABS.map((tab) => (
<button key={tab.key} onClick={() => setActiveTab(tab.key)} <button key={tab.key} onClick={() => setActiveTab(tab.key)}
className={cn('flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', className={cn('flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
activeTab === tab.key ? 'bg-surface text-text-primary shadow-sm' : 'text-text-secondary hover:text-text-primary hover:bg-surface/50')}> activeTab === tab.key ? 'bg-panel text-text-primary shadow-sm' : 'text-text-secondary hover:text-text-primary hover:bg-panel/50')}>
{tab.icon}{tab.label} {tab.icon}{tab.label}
{tab.key === 'active' && activeConns.entries.length > 0 && ( {tab.key === 'active' && activeConns.entries.length > 0 && (
<span className="text-xs bg-accent/20 text-accent px-1 rounded">{activeConns.entries.length}</span> <span className="text-xs bg-accent/20 text-accent px-1 rounded">{activeConns.entries.length}</span>
@@ -146,7 +146,7 @@ function ProfilesTab({ entries, panel }: { entries: ProfileEntry[]; panel: Panel
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">PPP Profiles ({entries.length})</span> <span className="text-sm font-medium text-text-secondary">PPP Profiles ({entries.length})</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleAdd}><Plus className="h-3.5 w-3.5" />Add Profile</Button> <Button size="sm" variant="outline" className="gap-1" onClick={handleAdd}><Plus className="h-3.5 w-3.5" />Add Profile</Button>
@@ -219,7 +219,7 @@ function SecretsTab({ entries, panel, profileNames }: { entries: SecretEntry[];
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">PPP Secrets ({entries.length})</span> <span className="text-sm font-medium text-text-secondary">PPP Secrets ({entries.length})</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleAdd}><Plus className="h-3.5 w-3.5" />Add Secret</Button> <Button size="sm" variant="outline" className="gap-1" onClick={handleAdd}><Plus className="h-3.5 w-3.5" />Add Secret</Button>
@@ -252,7 +252,7 @@ function SecretsTab({ entries, panel, profileNames }: { entries: SecretEntry[];
</div> </div>
<div className="grid grid-cols-2 gap-3"> <div className="grid grid-cols-2 gap-3">
<div className="space-y-1"><Label className="text-xs text-text-secondary">Service</Label> <div className="space-y-1"><Label className="text-xs text-text-secondary">Service</Label>
<select value={form.service} onChange={(e) => setForm((f) => ({ ...f, service: e.target.value }))} className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> <select value={form.service} onChange={(e) => setForm((f) => ({ ...f, service: e.target.value }))} className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
{PPP_SERVICES.map((s) => <option key={s} value={s}>{s}</option>)} {PPP_SERVICES.map((s) => <option key={s} value={s}>{s}</option>)}
</select></div> </select></div>
<div className="space-y-1"><Label className="text-xs text-text-secondary">Profile</Label><Input value={form.profile} onChange={(e) => setForm((f) => ({ ...f, profile: e.target.value }))} placeholder="default" className="h-8 text-sm" list="profile-names" /> <div className="space-y-1"><Label className="text-xs text-text-secondary">Profile</Label><Input value={form.profile} onChange={(e) => setForm((f) => ({ ...f, profile: e.target.value }))} placeholder="default" className="h-8 text-sm" list="profile-names" />
@@ -281,7 +281,7 @@ function ActiveTab({ entries, tenantId, deviceId, refetch }: { entries: ActiveEn
}) })
return ( return (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50"> <div className="px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">Active Connections ({entries.length})</span> <span className="text-sm font-medium text-text-secondary">Active Connections ({entries.length})</span>
</div> </div>

View File

@@ -100,7 +100,7 @@ export function RestorePreview({
)} )}
{/* Summary bar */} {/* Summary bar */}
<div className="rounded-lg border border-border bg-surface-raised p-3 flex items-center justify-between"> <div className="rounded-lg border border-border bg-panel-raised p-3 flex items-center justify-between">
<div className="flex items-center gap-4 text-sm"> <div className="flex items-center gap-4 text-sm">
<span className="text-success font-mono">+{diff.added}</span> <span className="text-success font-mono">+{diff.added}</span>
<span className="text-error font-mono">-{diff.removed}</span> <span className="text-error font-mono">-{diff.removed}</span>
@@ -125,7 +125,7 @@ export function RestorePreview({
{changedCategories.map((cat) => ( {changedCategories.map((cat) => (
<button <button
key={cat.path} key={cat.path}
className="w-full px-3 py-2 flex items-center justify-between hover:bg-surface-raised/50 transition-colors" className="w-full px-3 py-2 flex items-center justify-between hover:bg-panel-raised/50 transition-colors"
onClick={() => togglePath(cat.path)} onClick={() => togglePath(cat.path)}
> >
<div className="flex items-center gap-2 text-sm"> <div className="flex items-center gap-2 text-sm">

View File

@@ -170,8 +170,8 @@ export function RoutesPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
className={cn( className={cn(
'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', 'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
filterTab === tab.key filterTab === tab.key
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-secondary hover:text-text-primary hover:bg-surface/50', : 'text-text-secondary hover:text-text-primary hover:bg-panel/50',
)} )}
> >
{tab.label} {tab.label}
@@ -313,7 +313,7 @@ function RoutesTable({
return ( return (
<> <>
{/* Table */} {/* Table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Route className="h-4 w-4" /> <Route className="h-4 w-4" />

View File

@@ -148,8 +148,8 @@ export function ScriptsPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
className={cn( className={cn(
'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', 'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
activeTab === tab.key activeTab === tab.key
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-secondary hover:text-text-primary hover:bg-surface/50', : 'text-text-secondary hover:text-text-primary hover:bg-panel/50',
)} )}
> >
{tab.icon} {tab.icon}
@@ -275,7 +275,7 @@ function ScriptsTab({
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Code className="h-4 w-4" /> <Code className="h-4 w-4" />
@@ -477,7 +477,7 @@ function SchedulerTab({
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Clock className="h-4 w-4" /> <Clock className="h-4 w-4" />

View File

@@ -230,7 +230,7 @@ function ServiceTable({
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Shield className="h-4 w-4" /> <Shield className="h-4 w-4" />
@@ -337,7 +337,7 @@ function ServiceTable({
<select <select
value={form.disabled} value={form.disabled}
onChange={(e) => setForm((f) => ({ ...f, disabled: e.target.value }))} onChange={(e) => setForm((f) => ({ ...f, disabled: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="false">Enabled</option> <option value="false">Enabled</option>
<option value="true">Disabled</option> <option value="true">Disabled</option>

View File

@@ -158,7 +158,7 @@ export function SnmpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
</div> </div>
{/* SNMP Status + Settings */} {/* SNMP Status + Settings */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Radio className="h-4 w-4 text-accent" /> <Radio className="h-4 w-4 text-accent" />
@@ -192,7 +192,7 @@ export function SnmpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
</div> </div>
{/* Communities */} {/* Communities */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">SNMP Communities</span> <span className="text-sm font-medium text-text-secondary">SNMP Communities</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleAddCommunity}> <Button size="sm" variant="outline" className="gap-1" onClick={handleAddCommunity}>
@@ -279,7 +279,7 @@ export function SnmpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-text-secondary">Trap Version</Label> <Label className="text-xs text-text-secondary">Trap Version</Label>
<select value={settingsForm['trap-version'] || '1'} onChange={(e) => setSettingsForm((f) => ({ ...f, 'trap-version': e.target.value }))} <select value={settingsForm['trap-version'] || '1'} onChange={(e) => setSettingsForm((f) => ({ ...f, 'trap-version': e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
<option value="1">v1</option> <option value="1">v1</option>
<option value="2">v2c</option> <option value="2">v2c</option>
<option value="3">v3</option> <option value="3">v3</option>
@@ -313,7 +313,7 @@ export function SnmpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-text-secondary">Read Access</Label> <Label className="text-xs text-text-secondary">Read Access</Label>
<select value={communityForm['read-access'] || 'yes'} onChange={(e) => setCommunityForm((f) => ({ ...f, 'read-access': e.target.value }))} <select value={communityForm['read-access'] || 'yes'} onChange={(e) => setCommunityForm((f) => ({ ...f, 'read-access': e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
<option value="yes">Yes</option> <option value="yes">Yes</option>
<option value="no">No</option> <option value="no">No</option>
</select> </select>
@@ -321,7 +321,7 @@ export function SnmpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-text-secondary">Write Access</Label> <Label className="text-xs text-text-secondary">Write Access</Label>
<select value={communityForm['write-access'] || 'no'} onChange={(e) => setCommunityForm((f) => ({ ...f, 'write-access': e.target.value }))} <select value={communityForm['write-access'] || 'no'} onChange={(e) => setCommunityForm((f) => ({ ...f, 'write-access': e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
<option value="yes">Yes</option> <option value="yes">Yes</option>
<option value="no">No</option> <option value="no">No</option>
</select> </select>
@@ -329,7 +329,7 @@ export function SnmpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-text-secondary">Security</Label> <Label className="text-xs text-text-secondary">Security</Label>
<select value={communityForm['security'] || 'none'} onChange={(e) => setCommunityForm((f) => ({ ...f, security: e.target.value }))} <select value={communityForm['security'] || 'none'} onChange={(e) => setCommunityForm((f) => ({ ...f, security: e.target.value }))}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary"> className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary">
<option value="none">None</option> <option value="none">None</option>
<option value="authorized">Authorized</option> <option value="authorized">Authorized</option>
<option value="private">Private</option> <option value="private">Private</option>

View File

@@ -134,7 +134,7 @@ export function SwitchPortManager({ tenantId, deviceId, active }: ConfigPanelPro
if (isLoading) { if (isLoading) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{Array.from({ length: 8 }).map((_, i) => ( {Array.from({ length: 8 }).map((_, i) => (
<Skeleton key={i} className="h-20 w-16 rounded-md" /> <Skeleton key={i} className="h-20 w-16 rounded-md" />
@@ -146,7 +146,7 @@ export function SwitchPortManager({ tenantId, deviceId, active }: ConfigPanelPro
if (etherPorts.length === 0) { if (etherPorts.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-text-secondary text-sm"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-text-secondary text-sm">
<Network className="h-8 w-8 mx-auto mb-2 opacity-40" /> <Network className="h-8 w-8 mx-auto mb-2 opacity-40" />
No ethernet ports detected on this device. No ethernet ports detected on this device.
</div> </div>
@@ -156,7 +156,7 @@ export function SwitchPortManager({ tenantId, deviceId, active }: ConfigPanelPro
return ( return (
<div className="space-y-4"> <div className="space-y-4">
{/* Port grid */} {/* Port grid */}
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<h3 className="text-sm font-medium text-text-primary mb-3">Switch Ports</h3> <h3 className="text-sm font-medium text-text-primary mb-3">Switch Ports</h3>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{etherPorts.map((port) => { {etherPorts.map((port) => {
@@ -177,7 +177,7 @@ export function SwitchPortManager({ tenantId, deviceId, active }: ConfigPanelPro
</div> </div>
{/* VLAN Legend */} {/* VLAN Legend */}
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<h3 className="text-sm font-medium text-text-primary mb-2">VLAN Legend</h3> <h3 className="text-sm font-medium text-text-primary mb-2">VLAN Legend</h3>
<div className="flex flex-wrap gap-3"> <div className="flex flex-wrap gap-3">
<LegendItem color={UNASSIGNED_COLOR} label="Unassigned" /> <LegendItem color={UNASSIGNED_COLOR} label="Unassigned" />

View File

@@ -104,8 +104,8 @@ export function SystemPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
className={cn( className={cn(
'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors', 'flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
activeTab === tab.key activeTab === tab.key
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-secondary hover:text-text-primary hover:bg-surface/50', : 'text-text-secondary hover:text-text-primary hover:bg-panel/50',
)} )}
> >
{tab.icon} {tab.icon}
@@ -179,7 +179,7 @@ function IdentityTab({
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">System Identity</span> <span className="text-sm font-medium text-text-secondary">System Identity</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleEdit}> <Button size="sm" variant="outline" className="gap-1" onClick={handleEdit}>
@@ -283,7 +283,7 @@ function ClockTab({
return ( return (
<div className="space-y-4"> <div className="space-y-4">
{/* Clock info */} {/* Clock info */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">Clock Settings</span> <span className="text-sm font-medium text-text-secondary">Clock Settings</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleEditClock}> <Button size="sm" variant="outline" className="gap-1" onClick={handleEditClock}>
@@ -300,7 +300,7 @@ function ClockTab({
</div> </div>
{/* NTP info */} {/* NTP info */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">NTP Client</span> <span className="text-sm font-medium text-text-secondary">NTP Client</span>
<Button size="sm" variant="outline" className="gap-1" onClick={handleEditNtp}> <Button size="sm" variant="outline" className="gap-1" onClick={handleEditNtp}>
@@ -351,7 +351,7 @@ function ClockTab({
<select <select
value={ntpEnabled} value={ntpEnabled}
onChange={(e) => setNtpEnabled(e.target.value)} onChange={(e) => setNtpEnabled(e.target.value)}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="yes">Yes</option> <option value="yes">Yes</option>
<option value="no">No</option> <option value="no">No</option>
@@ -394,7 +394,7 @@ function ResourcesTab({ data }: { data: Record<string, string> }) {
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50"> <div className="px-4 py-2 border-b border-border/50">
<span className="text-sm font-medium text-text-secondary">System Resources</span> <span className="text-sm font-medium text-text-secondary">System Resources</span>
</div> </div>

View File

@@ -106,14 +106,14 @@ export function TorchTool({ tenantId, deviceId, active }: ConfigPanelProps) {
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="grid grid-cols-2 gap-3 sm:grid-cols-5"> <div className="grid grid-cols-2 gap-3 sm:grid-cols-5">
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-text-secondary">Interface</Label> <Label className="text-xs text-text-secondary">Interface</Label>
<select <select
value={iface} value={iface}
onChange={(e) => setIface(e.target.value)} onChange={(e) => setIface(e.target.value)}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary font-mono" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary font-mono"
> >
{ifaceNames.length > 0 {ifaceNames.length > 0
? ifaceNames.map((name) => ( ? ifaceNames.map((name) => (
@@ -190,7 +190,7 @@ export function TorchTool({ tenantId, deviceId, active }: ConfigPanelProps) {
)} )}
{entries.length > 0 && ( {entries.length > 0 && (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50 flex items-center gap-2"> <div className="px-4 py-2 border-b border-border/50 flex items-center gap-2">
<Flame className="h-4 w-4 text-accent" /> <Flame className="h-4 w-4 text-accent" />
<span className="text-sm font-medium text-text-secondary"> <span className="text-sm font-medium text-text-secondary">
@@ -229,7 +229,7 @@ export function TorchTool({ tenantId, deviceId, active }: ConfigPanelProps) {
)} )}
{entries.length === 0 && !torchMutation.isPending && !torchMutation.isIdle && ( {entries.length === 0 && !torchMutation.isPending && !torchMutation.isIdle && (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-sm text-text-muted">
No traffic captured. Try a different interface or remove filters. No traffic captured. Try a different interface or remove filters.
</div> </div>
)} )}

View File

@@ -69,7 +69,7 @@ export function TracerouteTool({ tenantId, deviceId }: ConfigPanelProps) {
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="grid grid-cols-2 gap-3 sm:grid-cols-5"> <div className="grid grid-cols-2 gap-3 sm:grid-cols-5">
<div className="space-y-1 col-span-2"> <div className="space-y-1 col-span-2">
<Label className="text-xs text-text-secondary">Target IP / Hostname</Label> <Label className="text-xs text-text-secondary">Target IP / Hostname</Label>
@@ -108,7 +108,7 @@ export function TracerouteTool({ tenantId, deviceId }: ConfigPanelProps) {
<select <select
value={protocol} value={protocol}
onChange={(e) => setProtocol(e.target.value)} onChange={(e) => setProtocol(e.target.value)}
className="h-8 w-full rounded-md border border-border bg-surface px-3 text-sm text-text-primary" className="h-8 w-full rounded-md border border-border bg-panel px-3 text-sm text-text-primary"
> >
<option value="icmp">ICMP</option> <option value="icmp">ICMP</option>
<option value="udp">UDP</option> <option value="udp">UDP</option>
@@ -137,7 +137,7 @@ export function TracerouteTool({ tenantId, deviceId }: ConfigPanelProps) {
)} )}
{hops.length > 0 && ( {hops.length > 0 && (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50 flex items-center gap-2"> <div className="px-4 py-2 border-b border-border/50 flex items-center gap-2">
<Route className="h-4 w-4 text-accent" /> <Route className="h-4 w-4 text-accent" />
<span className="text-sm font-medium text-text-secondary"> <span className="text-sm font-medium text-text-secondary">

View File

@@ -148,7 +148,7 @@ export function UsersPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
{/* Groups overview */} {/* Groups overview */}
{groups.length > 0 && ( {groups.length > 0 && (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="px-4 py-2 border-b border-border/50 flex items-center gap-2"> <div className="px-4 py-2 border-b border-border/50 flex items-center gap-2">
<Shield className="h-4 w-4 text-text-muted" /> <Shield className="h-4 w-4 text-text-muted" />
<span className="text-sm font-medium text-text-secondary">User Groups</span> <span className="text-sm font-medium text-text-secondary">User Groups</span>
@@ -266,7 +266,7 @@ function UsersTable({
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 border-b border-border/50"> <div className="flex items-center justify-between px-4 py-2 border-b border-border/50">
<div className="flex items-center gap-2 text-sm font-medium text-text-secondary"> <div className="flex items-center gap-2 text-sm font-medium text-text-secondary">
<Users className="h-4 w-4" /> <Users className="h-4 w-4" />

View File

@@ -69,7 +69,7 @@ export function AlertSummary({
})) }))
return ( return (
<Card className="bg-surface border-border"> <Card className="bg-panel border-border">
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-text-secondary"> <CardTitle className="text-sm font-medium text-text-secondary">
Alert Summary Alert Summary

View File

@@ -45,7 +45,7 @@ function BwTooltip({ active, payload }: CustomTooltipProps) {
if (!active || !payload || payload.length === 0) return null if (!active || !payload || payload.length === 0) return null
const item = payload[0] const item = payload[0]
return ( return (
<div className="rounded-md border border-border bg-surface px-3 py-2 text-xs"> <div className="rounded-md border border-border bg-panel px-3 py-2 text-xs">
<p className="font-medium text-text-primary">{item.payload.hostname}</p> <p className="font-medium text-text-primary">{item.payload.hostname}</p>
<p className="text-text-secondary">{formatBw(item.value)}</p> <p className="text-text-secondary">{formatBw(item.value)}</p>
</div> </div>
@@ -56,7 +56,7 @@ export function BandwidthChart({ devices }: BandwidthChartProps) {
const chartHeight = Math.max(200, devices.length * 36) const chartHeight = Math.max(200, devices.length * 36)
return ( return (
<Card className="bg-surface border-border"> <Card className="bg-panel border-border">
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-text-secondary"> <CardTitle className="text-sm font-medium text-text-secondary">
Top Bandwidth Consumers Top Bandwidth Consumers

View File

@@ -115,7 +115,7 @@ export function EventsTimeline({ tenantId, isSuperAdmin }: EventsTimelineProps)
}) })
return ( return (
<Card className="bg-surface border-border"> <Card className="bg-panel border-border">
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
<CardTitle className="text-sm font-medium text-text-secondary"> <CardTitle className="text-sm font-medium text-text-secondary">
@@ -159,7 +159,7 @@ export function EventsTimeline({ tenantId, isSuperAdmin }: EventsTimelineProps)
className="relative flex items-start gap-3 pb-3 pl-4 last:pb-0" className="relative flex items-start gap-3 pb-3 pl-4 last:pb-0"
> >
{/* Icon positioned over the timeline line */} {/* Icon positioned over the timeline line */}
<div className="absolute -left-[9px] top-0.5 flex h-4 w-4 items-center justify-center rounded-full bg-surface"> <div className="absolute -left-[9px] top-0.5 flex h-4 w-4 items-center justify-center rounded-full bg-panel">
<EventIcon event={event} /> <EventIcon event={event} />
</div> </div>

View File

@@ -132,7 +132,7 @@ export function HealthScore({
const dashOffset = CIRCUMFERENCE * (1 - progress) const dashOffset = CIRCUMFERENCE * (1 - progress)
return ( return (
<Card className="bg-surface border-border"> <Card className="bg-panel border-border">
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-text-secondary"> <CardTitle className="text-sm font-medium text-text-secondary">
Network Health Network Health

View File

@@ -72,7 +72,7 @@ export function QuickActions({ tenantId, isSuperAdmin }: QuickActionsProps) {
const actions = getActions(tenantId, isSuperAdmin) const actions = getActions(tenantId, isSuperAdmin)
return ( return (
<Card className="bg-surface border-border"> <Card className="bg-panel border-border">
<CardHeader className="pb-2"> <CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-text-secondary"> <CardTitle className="text-sm font-medium text-text-secondary">
Quick Actions Quick Actions

View File

@@ -25,7 +25,7 @@ export function WirelessIssues({ tenantId }: WirelessIssuesProps) {
}) })
return ( return (
<div className="rounded-lg border border-border bg-surface p-5"> <div className="rounded-lg border border-border bg-panel p-5">
<h3 className="text-sm font-semibold text-text-primary mb-4 flex items-center gap-2"> <h3 className="text-sm font-semibold text-text-primary mb-4 flex items-center gap-2">
<Wifi className="h-4 w-4 text-text-muted" /> <Wifi className="h-4 w-4 text-text-muted" />
APs Needing Attention APs Needing Attention

View File

@@ -50,7 +50,7 @@ function StatCard({
color: string color: string
}) { }) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className={cn('text-2xl font-bold', color)}>{value}</div> <div className={cn('text-2xl font-bold', color)}>{value}</div>
<div className="text-xs text-text-muted mt-1">{label}</div> <div className="text-xs text-text-muted mt-1">{label}</div>
</div> </div>
@@ -184,7 +184,7 @@ function UpgradeDialog({
</div> </div>
)} )}
<div className="rounded border border-border bg-surface p-3 text-xs text-text-secondary"> <div className="rounded border border-border bg-panel p-3 text-xs text-text-secondary">
A mandatory config backup will be taken before upgrading each device. A mandatory config backup will be taken before upgrading each device.
</div> </div>
@@ -254,10 +254,10 @@ function VersionGroupCard({
return ( return (
<> <>
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<button <button
onClick={() => setExpanded((v) => !v)} onClick={() => setExpanded((v) => !v)}
className="flex items-center gap-3 px-4 py-3 w-full text-left hover:bg-surface transition-colors" className="flex items-center gap-3 px-4 py-3 w-full text-left hover:bg-panel transition-colors"
> >
{expanded ? ( {expanded ? (
<ChevronDown className="h-4 w-4 text-text-muted" /> <ChevronDown className="h-4 w-4 text-text-muted" />

View File

@@ -256,7 +256,7 @@ function MassUpgradeProgress({
)} )}
{/* Device list */} {/* Device list */}
<div className="rounded-lg border border-border bg-surface overflow-hidden max-h-48 overflow-y-auto"> <div className="rounded-lg border border-border bg-panel overflow-hidden max-h-48 overflow-y-auto">
{rollout.jobs.map((job) => { {rollout.jobs.map((job) => {
const config = STATUS_CONFIG[job.status] ?? STATUS_CONFIG.pending const config = STATUS_CONFIG[job.status] ?? STATUS_CONFIG.pending
const Icon = config.icon const Icon = config.icon

View File

@@ -231,7 +231,7 @@ export function AdoptionWizard({ tenantId }: AdoptionWizardProps) {
{/* Step 3: Configure Credentials */} {/* Step 3: Configure Credentials */}
{step === 3 && ( {step === 3 && (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Configure Credentials</h3> <h3 className="text-sm font-semibold">Configure Credentials</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -253,7 +253,7 @@ export function AdoptionWizard({ tenantId }: AdoptionWizardProps) {
className={cn( className={cn(
'flex-1 px-3 py-1.5 rounded text-xs font-medium transition-colors', 'flex-1 px-3 py-1.5 rounded text-xs font-medium transition-colors',
credMode === opt.value credMode === opt.value
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-muted hover:text-text-secondary', : 'text-text-muted hover:text-text-secondary',
)} )}
> >
@@ -389,7 +389,7 @@ export function AdoptionWizard({ tenantId }: AdoptionWizardProps) {
{/* Step 4: Assign Groups & Tags */} {/* Step 4: Assign Groups & Tags */}
{step === 4 && ( {step === 4 && (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Assign Groups & Tags</h3> <h3 className="text-sm font-semibold">Assign Groups & Tags</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -584,7 +584,7 @@ function SubnetStep({
} }
return ( return (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Enter Subnet</h3> <h3 className="text-sm font-semibold">Enter Subnet</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -682,7 +682,7 @@ function ScanResultsStep({
).length ).length
return ( return (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<h3 className="text-sm font-semibold">Scan Results</h3> <h3 className="text-sm font-semibold">Scan Results</h3>
@@ -703,7 +703,7 @@ function ScanResultsStep({
<div className="rounded-md border border-border/50 overflow-hidden max-h-72 overflow-y-auto"> <div className="rounded-md border border-border/50 overflow-hidden max-h-72 overflow-y-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="sticky top-0"> <thead className="sticky top-0">
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th className="px-3 py-2 w-8"> <th className="px-3 py-2 w-8">
<Checkbox <Checkbox
checked={allNewSelected} checked={allNewSelected}
@@ -959,7 +959,7 @@ function ImportVerifyStep({
]) ])
return ( return (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Import & Verify</h3> <h3 className="text-sm font-semibold">Import & Verify</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -1013,7 +1013,7 @@ function ImportVerifyStep({
<div className="rounded-md border border-border/50 overflow-hidden"> <div className="rounded-md border border-border/50 overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th className="text-left px-3 py-2 text-xs font-medium text-text-muted"> <th className="text-left px-3 py-2 text-xs font-medium text-text-muted">
Device Device
</th> </th>

View File

@@ -213,7 +213,7 @@ export function FleetDashboard() {
</span> </span>
)} )}
{/* Refresh interval selector */} {/* Refresh interval selector */}
<div className="flex items-center rounded-md border border-border bg-surface"> <div className="flex items-center rounded-md border border-border bg-panel">
{REFRESH_OPTIONS.map((opt) => ( {REFRESH_OPTIONS.map((opt) => (
<button <button
key={opt.label} key={opt.label}

View File

@@ -92,7 +92,7 @@ function SortHeader({ column, label, currentSort, currentDir, onSort, className
function DeviceCard({ device, tenantId }: { device: DeviceResponse; tenantId: string }) { function DeviceCard({ device, tenantId }: { device: DeviceResponse; tenantId: string }) {
return ( return (
<div <div
className="w-full text-left rounded-lg border border-border bg-surface p-3 hover:bg-elevated/50 transition-colors min-h-[44px]" className="w-full text-left rounded-lg border border-border bg-panel p-3 hover:bg-elevated/50 transition-colors min-h-[44px]"
data-testid={`device-card-${device.hostname}`} data-testid={`device-card-${device.hostname}`}
> >
<div className="flex items-start justify-between gap-2"> <div className="flex items-start justify-between gap-2">

View File

@@ -104,7 +104,7 @@ export function ScanResultsList({ tenantId, results, onDone }: Props) {
<div className="rounded-lg border border-border overflow-hidden"> <div className="rounded-lg border border-border overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th className="px-3 py-2 w-8"> <th className="px-3 py-2 w-8">
<Checkbox <Checkbox
checked={allSelected} checked={allSelected}
@@ -121,7 +121,7 @@ export function ScanResultsList({ tenantId, results, onDone }: Props) {
{results.discovered.map((device) => ( {results.discovered.map((device) => (
<tr <tr
key={device.ip_address} key={device.ip_address}
className="border-b border-border/50 hover:bg-surface cursor-pointer" className="border-b border-border/50 hover:bg-panel cursor-pointer"
onClick={() => toggleSelect(device.ip_address)} onClick={() => toggleSelect(device.ip_address)}
> >
<td className="px-3 py-2" onClick={(e) => e.stopPropagation()}> <td className="px-3 py-2" onClick={(e) => e.stopPropagation()}>
@@ -154,7 +154,7 @@ export function ScanResultsList({ tenantId, results, onDone }: Props) {
{/* Credentials */} {/* Credentials */}
{selected.size > 0 && ( {selected.size > 0 && (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<h3 className="text-sm font-medium"> <h3 className="text-sm font-medium">
Credentials for {selected.size} selected device{selected.size !== 1 ? 's' : ''} Credentials for {selected.size} selected device{selected.size !== 1 ? 's' : ''}

View File

@@ -321,7 +321,7 @@ export function Sidebar() {
className={cn( className={cn(
'flex items-center gap-2.5 px-3 py-2 mx-1 rounded-md text-sm transition-colors min-h-[44px]', 'flex items-center gap-2.5 px-3 py-2 mx-1 rounded-md text-sm transition-colors min-h-[44px]',
active active
? 'bg-[hsl(var(--accent-muted))] text-accent rounded-md' ? 'bg-[hsl(var(--accent-soft))] text-accent rounded-md'
: 'text-text-muted hover:text-text-primary hover:bg-elevated/50 rounded-md', : 'text-text-muted hover:text-text-primary hover:bg-elevated/50 rounded-md',
showCollapsed && 'justify-center px-0', showCollapsed && 'justify-center px-0',
)} )}

View File

@@ -103,7 +103,7 @@ export function MaintenanceList({ tenantId }: MaintenanceListProps) {
{[1, 2, 3].map((i) => ( {[1, 2, 3].map((i) => (
<div <div
key={i} key={i}
className="h-20 rounded-lg border border-border bg-surface animate-pulse" className="h-20 rounded-lg border border-border bg-panel animate-pulse"
/> />
))} ))}
</div> </div>
@@ -266,7 +266,7 @@ function WindowCard({
return ( return (
<div <div
className={`rounded-lg border border-border bg-surface p-3 ${ className={`rounded-lg border border-border bg-panel p-3 ${
isPast ? 'opacity-60' : '' isPast ? 'opacity-60' : ''
}`} }`}
> >

View File

@@ -88,7 +88,7 @@ export function MapPage() {
<select <select
value={selectedTenant} value={selectedTenant}
onChange={(e) => setSelectedTenant(e.target.value)} onChange={(e) => setSelectedTenant(e.target.value)}
className="text-xs bg-elevated/50 border border-border text-text-primary rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-border-bright" className="text-xs bg-elevated/50 border border-border text-text-primary rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-border-default"
> >
<option value="all">All Organizations</option> <option value="all">All Organizations</option>
{tenants.map((t) => ( {tenants.map((t) => (

View File

@@ -33,7 +33,7 @@ function CustomTooltip({
}: { active?: boolean; payload?: Array<{ value?: number }>; label?: string; unit: string }) { }: { active?: boolean; payload?: Array<{ value?: number }>; label?: string; unit: string }) {
if (!active || !payload?.length) return null if (!active || !payload?.length) return null
return ( return (
<div className="rounded border border-border bg-surface px-2 py-1.5 text-xs text-text-primary"> <div className="rounded border border-border bg-panel px-2 py-1.5 text-xs text-text-primary">
<div className="mb-1 text-text-muted">{label}</div> <div className="mb-1 text-text-muted">{label}</div>
<div> <div>
{(payload[0].value ?? 0).toFixed(1)} {(payload[0].value ?? 0).toFixed(1)}

View File

@@ -43,16 +43,16 @@ export function HealthTab({ tenantId, deviceId, active = true }: HealthTabProps)
{isLoading ? ( {isLoading ? (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{[0, 1, 2, 3].map((i) => ( {[0, 1, 2, 3].map((i) => (
<div key={i} className="rounded-lg border border-border bg-surface p-4 h-44 animate-pulse" /> <div key={i} className="rounded-lg border border-border bg-panel p-4 h-44 animate-pulse" />
))} ))}
</div> </div>
) : !data || data.length === 0 ? ( ) : !data || data.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-sm text-text-muted">
No health metrics data available for the selected time range. No health metrics data available for the selected time range.
</div> </div>
) : ( ) : (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<HealthChart <HealthChart
data={data} data={data}
metric="avg_cpu" metric="avg_cpu"
@@ -62,7 +62,7 @@ export function HealthTab({ tenantId, deviceId, active = true }: HealthTabProps)
maxY={100} maxY={100}
/> />
</div> </div>
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<HealthChart <HealthChart
data={data} data={data}
metric="avg_mem_pct" metric="avg_mem_pct"
@@ -72,7 +72,7 @@ export function HealthTab({ tenantId, deviceId, active = true }: HealthTabProps)
maxY={100} maxY={100}
/> />
</div> </div>
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<HealthChart <HealthChart
data={data} data={data}
metric="avg_disk_pct" metric="avg_disk_pct"
@@ -82,7 +82,7 @@ export function HealthTab({ tenantId, deviceId, active = true }: HealthTabProps)
maxY={100} maxY={100}
/> />
</div> </div>
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<HealthChart <HealthChart
data={data} data={data}
metric="avg_temp" metric="avg_temp"

View File

@@ -89,11 +89,11 @@ export function InterfacesTab({ tenantId, deviceId, active = true }: InterfacesT
{isLoading ? ( {isLoading ? (
<div className="space-y-4"> <div className="space-y-4">
{[0, 1, 2].map((i) => ( {[0, 1, 2].map((i) => (
<div key={i} className="rounded-lg border border-border bg-surface p-4 h-56 animate-pulse" /> <div key={i} className="rounded-lg border border-border bg-panel p-4 h-56 animate-pulse" />
))} ))}
</div> </div>
) : !trafficData || trafficData.length === 0 ? ( ) : !trafficData || trafficData.length === 0 ? (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-sm text-text-muted">
{interfaces && interfaces.length === 0 {interfaces && interfaces.length === 0
? 'No interfaces discovered for this device.' ? 'No interfaces discovered for this device.'
: 'No traffic data available for the selected time range.'} : 'No traffic data available for the selected time range.'}
@@ -103,7 +103,7 @@ export function InterfacesTab({ tenantId, deviceId, active = true }: InterfacesT
{interfaceNames.map((ifaceName) => { {interfaceNames.map((ifaceName) => {
const ifaceData = byInterface.get(ifaceName) ?? [] const ifaceData = byInterface.get(ifaceName) ?? []
return ( return (
<div key={ifaceName} className="rounded-lg border border-border bg-surface p-4"> <div key={ifaceName} className="rounded-lg border border-border bg-panel p-4">
<TrafficChart data={ifaceData} interfaceName={ifaceName} /> <TrafficChart data={ifaceData} interfaceName={ifaceName} />
</div> </div>
) )

View File

@@ -101,7 +101,7 @@ export function TimeRangeSelector({
className={cn( className={cn(
'px-2.5 py-1 text-xs rounded border transition-colors', 'px-2.5 py-1 text-xs rounded border transition-colors',
value === preset value === preset
? 'bg-elevated border-border-bright text-text-primary' ? 'bg-elevated border-border-default text-text-primary'
: 'bg-transparent border-border/50 text-text-primary/40 hover:text-text-primary/60 hover:border-border', : 'bg-transparent border-border/50 text-text-primary/40 hover:text-text-primary/60 hover:border-border',
)} )}
> >
@@ -113,7 +113,7 @@ export function TimeRangeSelector({
className={cn( className={cn(
'px-2.5 py-1 text-xs rounded border transition-colors', 'px-2.5 py-1 text-xs rounded border transition-colors',
value === 'custom' value === 'custom'
? 'bg-elevated border-border-bright text-text-primary' ? 'bg-elevated border-border-default text-text-primary'
: 'bg-transparent border-border/50 text-text-primary/40 hover:text-text-primary/60 hover:border-border', : 'bg-transparent border-border/50 text-text-primary/40 hover:text-text-primary/60 hover:border-border',
)} )}
> >

View File

@@ -36,7 +36,7 @@ function formatBucket(bucket: string, useDate: boolean): string {
function CustomTooltip({ active, payload, label }: { active?: boolean; payload?: Array<{ value?: number; dataKey?: string; name?: string; color?: string }>; label?: string }) { function CustomTooltip({ active, payload, label }: { active?: boolean; payload?: Array<{ value?: number; dataKey?: string; name?: string; color?: string }>; label?: string }) {
if (!active || !payload?.length) return null if (!active || !payload?.length) return null
return ( return (
<div className="rounded border border-border bg-surface px-2 py-1.5 text-xs text-text-primary"> <div className="rounded border border-border bg-panel px-2 py-1.5 text-xs text-text-primary">
<div className="mb-1 text-text-muted">{label}</div> <div className="mb-1 text-text-muted">{label}</div>
{payload.map((entry) => ( {payload.map((entry) => (
<div key={entry.dataKey} className="flex items-center gap-2"> <div key={entry.dataKey} className="flex items-center gap-2">

View File

@@ -57,7 +57,7 @@ function WirelessInterfaceCard({ section }: { section: WirelessInterfaceSection
const { interfaceName, latest, history } = section const { interfaceName, latest, history } = section
return ( return (
<div className="rounded-lg border border-border bg-surface p-4 space-y-3"> <div className="rounded-lg border border-border bg-panel p-4 space-y-3">
{/* Interface name header */} {/* Interface name header */}
<h3 className="text-sm font-medium text-text-primary">{interfaceName}</h3> <h3 className="text-sm font-medium text-text-primary">{interfaceName}</h3>
@@ -161,11 +161,11 @@ export function WirelessTab({ tenantId, deviceId, active = true }: WirelessTabPr
{isLoading ? ( {isLoading ? (
<div className="space-y-4"> <div className="space-y-4">
{[0, 1].map((i) => ( {[0, 1].map((i) => (
<div key={i} className="rounded-lg border border-border bg-surface p-4 h-48 animate-pulse" /> <div key={i} className="rounded-lg border border-border bg-panel p-4 h-48 animate-pulse" />
))} ))}
</div> </div>
) : hasNoWireless ? ( ) : hasNoWireless ? (
<div className="rounded-lg border border-border bg-surface p-8 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-8 text-center text-sm text-text-muted">
No wireless interfaces detected on this device. No wireless interfaces detected on this device.
</div> </div>
) : ( ) : (

View File

@@ -246,7 +246,7 @@ export function ClientsTab({ tenantId, deviceId, active }: ClientsTabProps) {
<div className="overflow-x-auto rounded-lg border border-border"> <div className="overflow-x-auto rounded-lg border border-border">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="bg-surface text-text-secondary text-left"> <tr className="bg-panel text-text-secondary text-left">
{/* Expand chevron column */} {/* Expand chevron column */}
<th className="w-8 px-3 py-2.5" /> <th className="w-8 px-3 py-2.5" />

View File

@@ -103,7 +103,7 @@ export function InterfaceGauges({ tenantId, deviceId, active }: InterfaceGaugesP
return ( return (
<div className="space-y-3"> <div className="space-y-3">
{[0, 1, 2].map((i) => ( {[0, 1, 2].map((i) => (
<div key={i} className="rounded-lg border border-border bg-surface p-3"> <div key={i} className="rounded-lg border border-border bg-panel p-3">
<Skeleton className="h-4 w-24 mb-2" /> <Skeleton className="h-4 w-24 mb-2" />
<Skeleton className="h-3 w-full mb-1" /> <Skeleton className="h-3 w-full mb-1" />
<Skeleton className="h-3 w-full" /> <Skeleton className="h-3 w-full" />
@@ -115,7 +115,7 @@ export function InterfaceGauges({ tenantId, deviceId, active }: InterfaceGaugesP
if (!interfaces || interfaces.length === 0) { if (!interfaces || interfaces.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-6 text-center text-sm text-text-muted"> <div className="rounded-lg border border-border bg-panel p-6 text-center text-sm text-text-muted">
No interface data available. No interface data available.
</div> </div>
) )
@@ -149,7 +149,7 @@ export function InterfaceGauges({ tenantId, deviceId, active }: InterfaceGaugesP
const values = latestByIface.get(ifaceName) ?? { rx: 0, tx: 0 } const values = latestByIface.get(ifaceName) ?? { rx: 0, tx: 0 }
return ( return (
<div key={ifaceName} className="rounded-lg border border-border bg-surface p-3"> <div key={ifaceName} className="rounded-lg border border-border bg-panel p-3">
<div className="flex items-center justify-between mb-1.5"> <div className="flex items-center justify-between mb-1.5">
<span className="text-sm font-medium text-text-primary">{ifaceName}</span> <span className="text-sm font-medium text-text-primary">{ifaceName}</span>
<span className="text-[10px] text-text-muted"> <span className="text-[10px] text-text-muted">

View File

@@ -187,7 +187,7 @@ export function LogsTab({ tenantId, deviceId, active }: LogsTabProps) {
</div> </div>
{/* Log table */} {/* Log table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{isLoading ? ( {isLoading ? (
<TableSkeleton /> <TableSkeleton />
) : error ? ( ) : error ? (

View File

@@ -99,7 +99,7 @@ function DeviceNode({ data }: NodeProps<DeviceNodeData>) {
return ( return (
<div <div
className={cn( className={cn(
'rounded-lg border bg-surface px-3 py-2 min-w-[180px]', 'rounded-lg border bg-panel px-3 py-2 min-w-[180px]',
'transition-colors', 'transition-colors',
isOnline ? 'border-border' : 'border-error/30', isOnline ? 'border-border' : 'border-error/30',
)} )}
@@ -339,7 +339,7 @@ export function TopologyMap({ tenantId }: TopologyMapProps) {
> >
<Background color="hsl(var(--muted))" gap={20} size={1} /> <Background color="hsl(var(--muted))" gap={20} size={1} />
<Controls <Controls
className="!bg-surface !border-border [&>button]:!bg-surface [&>button]:!border-border [&>button]:!text-text-secondary [&>button:hover]:!bg-elevated" className="!bg-panel !border-border [&>button]:!bg-panel [&>button]:!border-border [&>button]:!text-text-secondary [&>button:hover]:!bg-elevated"
/> />
<MiniMap <MiniMap
nodeColor={(node) => { nodeColor={(node) => {
@@ -349,7 +349,7 @@ export function TopologyMap({ tenantId }: TopologyMapProps) {
: 'hsl(var(--error))' : 'hsl(var(--error))'
}} }}
maskColor="hsl(var(--background) / 0.7)" maskColor="hsl(var(--background) / 0.7)"
className="!bg-surface !border-border" className="!bg-panel !border-border"
/> />
</ReactFlow> </ReactFlow>
@@ -357,7 +357,7 @@ export function TopologyMap({ tenantId }: TopologyMapProps) {
{tooltip && <NodeTooltip data={tooltip} onClose={() => setTooltip(null)} />} {tooltip && <NodeTooltip data={tooltip} onClose={() => setTooltip(null)} />}
{/* Legend */} {/* Legend */}
<div className="absolute bottom-4 left-4 rounded-lg border border-border bg-surface/90 backdrop-blur-sm px-3 py-2 text-xs text-text-muted"> <div className="absolute bottom-4 left-4 rounded-lg border border-border bg-panel/90 backdrop-blur-sm px-3 py-2 text-xs text-text-muted">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<span className="flex items-center gap-1.5"> <span className="flex items-center gap-1.5">
<span className="h-2 w-2 rounded-full bg-success" /> Online <span className="h-2 w-2 rounded-full bg-success" /> Online

View File

@@ -112,7 +112,7 @@ export function VpnTab({ tenantId, deviceId, active }: VpnTabProps) {
if (error) { if (error) {
return ( return (
<div className="mt-4 rounded-lg border border-border bg-surface p-6 text-center text-sm text-error"> <div className="mt-4 rounded-lg border border-border bg-panel p-6 text-center text-sm text-error">
Failed to load VPN tunnels. The device may not support this feature. Failed to load VPN tunnels. The device may not support this feature.
</div> </div>
) )
@@ -120,7 +120,7 @@ export function VpnTab({ tenantId, deviceId, active }: VpnTabProps) {
if (!data || data.tunnels.length === 0) { if (!data || data.tunnels.length === 0) {
return ( return (
<div className="mt-4 rounded-lg border border-border bg-surface p-8 text-center"> <div className="mt-4 rounded-lg border border-border bg-panel p-8 text-center">
<Shield className="w-10 h-10 mx-auto mb-3 text-text-muted opacity-40" /> <Shield className="w-10 h-10 mx-auto mb-3 text-text-muted opacity-40" />
<p className="text-sm font-medium text-text-primary mb-1"> <p className="text-sm font-medium text-text-primary mb-1">
No active VPN tunnels No active VPN tunnels
@@ -134,7 +134,7 @@ export function VpnTab({ tenantId, deviceId, active }: VpnTabProps) {
} }
return ( return (
<div className="mt-4 rounded-lg border border-border bg-surface overflow-hidden"> <div className="mt-4 rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-left"> <table className="w-full text-left">
<thead> <thead>
<tr className="border-b border-border bg-elevated/50"> <tr className="border-b border-border bg-elevated/50">

View File

@@ -251,7 +251,7 @@ export function BulkCommandWizard({ tenantId }: BulkCommandWizardProps) {
{/* Step 2: Enter Command */} {/* Step 2: Enter Command */}
{step === 2 && ( {step === 2 && (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Enter RouterOS Command</h3> <h3 className="text-sm font-semibold">Enter RouterOS Command</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -294,7 +294,7 @@ export function BulkCommandWizard({ tenantId }: BulkCommandWizardProps) {
{/* Step 3: Review & Execute */} {/* Step 3: Review & Execute */}
{step === 3 && ( {step === 3 && (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Review & Execute</h3> <h3 className="text-sm font-semibold">Review & Execute</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -336,7 +336,7 @@ export function BulkCommandWizard({ tenantId }: BulkCommandWizardProps) {
<div className="rounded-lg border border-border overflow-hidden"> <div className="rounded-lg border border-border overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th className="text-left px-3 py-2 text-xs font-medium text-text-muted"> <th className="text-left px-3 py-2 text-xs font-medium text-text-muted">
Device Device
</th> </th>
@@ -615,7 +615,7 @@ function DeviceSelectionStep({
} }
return ( return (
<div className="rounded-lg border border-border bg-surface p-6 space-y-4"> <div className="rounded-lg border border-border bg-panel p-6 space-y-4">
<div> <div>
<h3 className="text-sm font-semibold">Select Target Devices</h3> <h3 className="text-sm font-semibold">Select Target Devices</h3>
<p className="text-xs text-text-muted mt-0.5"> <p className="text-xs text-text-muted mt-0.5">
@@ -641,7 +641,7 @@ function DeviceSelectionStep({
className={cn( className={cn(
'flex-1 px-3 py-1.5 rounded text-xs font-medium transition-colors', 'flex-1 px-3 py-1.5 rounded text-xs font-medium transition-colors',
mode === opt.value mode === opt.value
? 'bg-surface text-text-primary shadow-sm' ? 'bg-panel text-text-primary shadow-sm'
: 'text-text-muted hover:text-text-secondary', : 'text-text-muted hover:text-text-secondary',
)} )}
> >
@@ -699,7 +699,7 @@ function DeviceSelectionStep({
<div className="rounded-md border border-border/50 overflow-hidden max-h-72 overflow-y-auto"> <div className="rounded-md border border-border/50 overflow-hidden max-h-72 overflow-y-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="sticky top-0"> <thead className="sticky top-0">
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th className="px-3 py-2 w-8"> <th className="px-3 py-2 w-8">
<Checkbox <Checkbox
checked={ checked={

View File

@@ -122,8 +122,8 @@ export function ReportsPage({ tenantId }: ReportsPageProps) {
className={cn( className={cn(
'flex items-start gap-3 p-4 rounded-lg border text-left transition-all', 'flex items-start gap-3 p-4 rounded-lg border text-left transition-all',
isSelected isSelected
? 'border-accent bg-accent-muted/30 ring-1 ring-accent' ? 'border-accent bg-accent-soft/30 ring-1 ring-accent'
: 'border-border bg-surface hover:border-text-muted', : 'border-border bg-panel hover:border-text-muted',
)} )}
> >
<div <div
@@ -172,7 +172,7 @@ export function ReportsPage({ tenantId }: ReportsPageProps) {
type="date" type="date"
value={dateFrom} value={dateFrom}
onChange={(e) => setDateFrom(e.target.value)} onChange={(e) => setDateFrom(e.target.value)}
className="w-full h-9 rounded-md border border-border bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="w-full h-9 rounded-md border border-border bg-panel px-3 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
/> />
</div> </div>
<div className="flex-1"> <div className="flex-1">
@@ -187,7 +187,7 @@ export function ReportsPage({ tenantId }: ReportsPageProps) {
type="date" type="date"
value={dateTo} value={dateTo}
onChange={(e) => setDateTo(e.target.value)} onChange={(e) => setDateTo(e.target.value)}
className="w-full h-9 rounded-md border border-border bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="w-full h-9 rounded-md border border-border bg-panel px-3 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
/> />
</div> </div>
</div> </div>

View File

@@ -166,7 +166,7 @@ export function ApiKeysPage({ tenantId }: ApiKeysPageProps) {
action={{ label: 'Create API Key', onClick: () => setShowCreateDialog(true) }} action={{ label: 'Create API Key', onClick: () => setShowCreateDialog(true) }}
/> />
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">
@@ -264,7 +264,7 @@ export function ApiKeysPage({ tenantId }: ApiKeysPageProps) {
</label> </label>
<input <input
type="text" type="text"
className="w-full rounded-md border border-border-bright bg-elevated/50 px-3 py-2 text-sm focus:border-accent focus:outline-none" className="w-full rounded-md border border-border-default bg-elevated/50 px-3 py-2 text-sm focus:border-accent focus:outline-none"
placeholder="e.g. Monitoring Integration" placeholder="e.g. Monitoring Integration"
value={name} value={name}
onChange={(e) => setName(e.target.value)} onChange={(e) => setName(e.target.value)}
@@ -300,7 +300,7 @@ export function ApiKeysPage({ tenantId }: ApiKeysPageProps) {
</label> </label>
<input <input
type="date" type="date"
className="w-full rounded-md border border-border-bright bg-elevated/50 px-3 py-2 text-sm focus:border-accent focus:outline-none" className="w-full rounded-md border border-border-default bg-elevated/50 px-3 py-2 text-sm focus:border-accent focus:outline-none"
value={expiresAt} value={expiresAt}
onChange={(e) => setExpiresAt(e.target.value)} onChange={(e) => setExpiresAt(e.target.value)}
min={new Date().toISOString().split('T')[0]} min={new Date().toISOString().split('T')[0]}

View File

@@ -78,7 +78,7 @@ export function SettingsPage() {
</div> </div>
{/* Account section */} {/* Account section */}
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-1"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-1">
<SectionHeader icon={User} title="Account" /> <SectionHeader icon={User} title="Account" />
<InfoRow label="Email" value={user?.email} /> <InfoRow label="Email" value={user?.email} />
<InfoRow label="Role" value={ <InfoRow label="Role" value={
@@ -94,13 +94,13 @@ export function SettingsPage() {
</div> </div>
{/* Password & Security section */} {/* Password & Security section */}
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-1"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-1">
<SectionHeader icon={Lock} title="Password & Security" /> <SectionHeader icon={Lock} title="Password & Security" />
<ChangePasswordForm /> <ChangePasswordForm />
</div> </div>
{/* Permissions section */} {/* Permissions section */}
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-1"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-1">
<SectionHeader icon={Shield} title="Permissions" /> <SectionHeader icon={Shield} title="Permissions" />
<InfoRow label="Read devices" value="Yes" /> <InfoRow label="Read devices" value="Yes" />
<InfoRow <InfoRow
@@ -118,7 +118,7 @@ export function SettingsPage() {
</div> </div>
{/* System info section */} {/* System info section */}
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-1"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-1">
<SectionHeader icon={Info} title="System" /> <SectionHeader icon={Info} title="System" />
<InfoRow label="API" value={ <InfoRow label="API" value={
<a <a
@@ -135,7 +135,7 @@ export function SettingsPage() {
{/* Quick links */} {/* Quick links */}
{isTenantAdmin(user) && ( {isTenantAdmin(user) && (
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-1"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-1">
<SectionHeader icon={Key} title="Integrations" /> <SectionHeader icon={Key} title="Integrations" />
<Link <Link
to="/settings/api-keys" to="/settings/api-keys"
@@ -152,7 +152,7 @@ export function SettingsPage() {
{/* Maintenance — super_admin only */} {/* Maintenance — super_admin only */}
{isSuperAdmin(user) && ( {isSuperAdmin(user) && (
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-1"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-1">
<SectionHeader icon={Monitor} title="Maintenance" /> <SectionHeader icon={Monitor} title="Maintenance" />
<div className="flex items-center justify-between py-2"> <div className="flex items-center justify-between py-2">
<div> <div>
@@ -182,7 +182,7 @@ export function SettingsPage() {
{isSuperAdmin(user) && <SMTPSettingsSection />} {isSuperAdmin(user) && <SMTPSettingsSection />}
{/* Data & Privacy section */} {/* Data & Privacy section */}
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-3"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-3">
<SectionHeader icon={Shield} title="Data & Privacy" /> <SectionHeader icon={Shield} title="Data & Privacy" />
{/* Export Data */} {/* Export Data */}
@@ -377,7 +377,7 @@ function SMTPSettingsSection() {
if (isLoading) return null if (isLoading) return null
return ( return (
<div className="rounded-lg border border-border bg-surface px-4 py-3 space-y-3"> <div className="rounded-lg border border-border bg-panel px-4 py-3 space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<SectionHeader icon={Mail} title="System Email (SMTP)" /> <SectionHeader icon={Mail} title="System Email (SMTP)" />
<span className={`text-[10px] font-medium px-2 py-0.5 rounded-full ${ <span className={`text-[10px] font-medium px-2 py-0.5 rounded-full ${

View File

@@ -484,7 +484,7 @@ export function SetupWizard() {
<StepIndicator currentStep={step} /> <StepIndicator currentStep={step} />
{/* Card */} {/* Card */}
<div className="bg-surface border border-border rounded-lg p-8"> <div className="bg-panel border border-border rounded-lg p-8">
{step === 1 && ( {step === 1 && (
<CreateTenantStep <CreateTenantStep
onComplete={(tenant) => { onComplete={(tenant) => {

View File

@@ -19,7 +19,7 @@ export function SimpleFormSection({
children, children,
}: SimpleFormSectionProps) { }: SimpleFormSectionProps) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-4 space-y-4"> <div className="rounded-lg border border-border bg-panel p-4 space-y-4">
<div className="flex items-center gap-2.5"> <div className="flex items-center gap-2.5">
<Icon className="h-4.5 w-4.5 text-accent flex-shrink-0" /> <Icon className="h-4.5 w-4.5 text-accent flex-shrink-0" />
<div> <div>

View File

@@ -16,7 +16,7 @@ export function SimpleStatusBanner({ items, isLoading }: SimpleStatusBannerProps
<div key={i} className="flex flex-col"> <div key={i} className="flex flex-col">
<span className="text-xs text-text-muted">{item.label}</span> <span className="text-xs text-text-muted">{item.label}</span>
{isLoading ? ( {isLoading ? (
<div className="h-5 w-24 mt-0.5 rounded bg-elevated animate-shimmer" /> <div className="h-5 w-24 mt-0.5 rounded bg-elevated animate-pulse" />
) : ( ) : (
<span className="text-sm font-medium text-text-primary"> <span className="text-sm font-medium text-text-primary">
{item.value || '\u2014'} {item.value || '\u2014'}

View File

@@ -180,7 +180,7 @@ export function LanDhcpPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
{activeLeases.length === 0 ? ( {activeLeases.length === 0 ? (
<p className="text-xs text-text-muted">No active DHCP leases</p> <p className="text-xs text-text-muted">No active DHCP leases</p>
) : ( ) : (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
<table className="w-full text-xs"> <table className="w-full text-xs">
<thead> <thead>
<tr className="border-b border-border bg-elevated/30"> <tr className="border-b border-border bg-elevated/30">

View File

@@ -126,7 +126,7 @@ export function WifiSimplePanel({ tenantId, deviceId, active, routerosVersion }:
// No wireless hardware // No wireless hardware
if (wireless.entries.length === 0) { if (wireless.entries.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-12 text-center"> <div className="rounded-lg border border-border bg-panel p-12 text-center">
<Wifi className="h-8 w-8 text-text-muted/50 mx-auto mb-3" /> <Wifi className="h-8 w-8 text-text-muted/50 mx-auto mb-3" />
<p className="text-sm font-medium text-text-secondary"> <p className="text-sm font-medium text-text-secondary">
This device does not have wireless hardware This device does not have wireless hardware

View File

@@ -59,7 +59,7 @@ export function SiteHealthGrid({ tenantId, siteId }: SiteHealthGridProps) {
return ( return (
<div className="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-3"> <div className="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-3">
{Array.from({ length: 6 }).map((_, i) => ( {Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="rounded-lg border border-border bg-surface p-4 space-y-3 animate-pulse"> <div key={i} className="rounded-lg border border-border bg-panel p-4 space-y-3 animate-pulse">
<div className="h-4 w-24 bg-elevated rounded" /> <div className="h-4 w-24 bg-elevated rounded" />
<div className="h-1.5 w-full bg-elevated rounded-full" /> <div className="h-1.5 w-full bg-elevated rounded-full" />
<div className="h-1.5 w-full bg-elevated rounded-full" /> <div className="h-1.5 w-full bg-elevated rounded-full" />
@@ -74,7 +74,7 @@ export function SiteHealthGrid({ tenantId, siteId }: SiteHealthGridProps) {
if (devices.length === 0) { if (devices.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-8 text-center"> <div className="rounded-lg border border-border bg-panel p-8 text-center">
<p className="text-sm text-text-muted"> <p className="text-sm text-text-muted">
No devices assigned to this site. Assign devices from the fleet page. No devices assigned to this site. Assign devices from the fleet page.
</p> </p>
@@ -103,7 +103,7 @@ export function SiteHealthGrid({ tenantId, siteId }: SiteHealthGridProps) {
to="/tenants/$tenantId/devices/$deviceId" to="/tenants/$tenantId/devices/$deviceId"
params={{ tenantId, deviceId: device.id }} params={{ tenantId, deviceId: device.id }}
className={cn( className={cn(
'rounded-lg border bg-surface p-4 space-y-2 hover:bg-elevated/50 transition-colors block', 'rounded-lg border bg-panel p-4 space-y-2 hover:bg-elevated/50 transition-colors block',
borderColor(device.status), borderColor(device.status),
)} )}
> >

View File

@@ -153,7 +153,7 @@ export function SiteSectorView({ tenantId, siteId }: SiteSectorViewProps) {
if (sectors.length === 0 && unassignedDevices.length === 0) { if (sectors.length === 0 && unassignedDevices.length === 0) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-8 text-center space-y-3"> <div className="rounded-lg border border-border bg-panel p-8 text-center space-y-3">
<p className="text-sm text-text-muted"> <p className="text-sm text-text-muted">
No sectors defined. Create sectors to organize APs by direction. No sectors defined. Create sectors to organize APs by direction.
</p> </p>
@@ -315,7 +315,7 @@ function SectorSection({
const isUnassigned = !sector const isUnassigned = !sector
return ( return (
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{/* Section header */} {/* Section header */}
<button <button
className="w-full flex items-center gap-2 px-4 py-3 hover:bg-elevated/50 transition-colors text-left" className="w-full flex items-center gap-2 px-4 py-3 hover:bg-elevated/50 transition-colors text-left"

View File

@@ -101,7 +101,7 @@ export function PushProgressPanel({ tenantId, rolloutId, onClose }: PushProgress
return ( return (
<div <div
key={job.device_id} key={job.device_id}
className="flex items-center gap-3 rounded-lg border border-border/50 bg-surface/50 px-3 py-2" className="flex items-center gap-3 rounded-lg border border-border/50 bg-panel/50 px-3 py-2"
> >
<Icon <Icon
className={cn( className={cn(

View File

@@ -164,7 +164,7 @@ export function TemplateEditor({ template, onSave, onCancel }: TemplateEditorPro
onChange={(e) => setDescription(e.target.value)} onChange={(e) => setDescription(e.target.value)}
placeholder="What does this template configure?" placeholder="What does this template configure?"
rows={2} rows={2}
className="w-full px-3 py-2 text-sm rounded-md bg-elevated/50 border border-border text-text-primary placeholder:text-text-muted resize-none focus:outline-none focus:ring-1 focus:ring-border-bright" className="w-full px-3 py-2 text-sm rounded-md bg-elevated/50 border border-border text-text-primary placeholder:text-text-muted resize-none focus:outline-none focus:ring-1 focus:ring-border-default"
/> />
</div> </div>
@@ -176,7 +176,7 @@ export function TemplateEditor({ template, onSave, onCancel }: TemplateEditorPro
onChange={(e) => setContent(e.target.value)} onChange={(e) => setContent(e.target.value)}
placeholder={`# Example: Set system identity\n/system identity set name={{ device.hostname }}-{{ site_name }}\n\n# Add IP address\n/ip address add address={{ mgmt_ip }}/24 interface=ether1`} placeholder={`# Example: Set system identity\n/system identity set name={{ device.hostname }}-{{ site_name }}\n\n# Add IP address\n/ip address add address={{ mgmt_ip }}/24 interface=ether1`}
rows={16} rows={16}
className="w-full px-3 py-2 text-sm rounded-md bg-background border border-border text-success placeholder:text-text-muted font-mono resize-y focus:outline-none focus:ring-1 focus:ring-border-bright leading-relaxed" className="w-full px-3 py-2 text-sm rounded-md bg-background border border-border text-success placeholder:text-text-muted font-mono resize-y focus:outline-none focus:ring-1 focus:ring-border-default leading-relaxed"
/> />
</div> </div>
@@ -247,7 +247,7 @@ export function TemplateEditor({ template, onSave, onCancel }: TemplateEditorPro
<div className="rounded-lg border border-border overflow-hidden"> <div className="rounded-lg border border-border overflow-hidden">
<table className="w-full text-xs"> <table className="w-full text-xs">
<thead> <thead>
<tr className="bg-surface border-b border-border"> <tr className="bg-panel border-b border-border">
<th className="text-left px-3 py-1.5 text-[10px] uppercase tracking-wider font-semibold text-text-muted">Name</th> <th className="text-left px-3 py-1.5 text-[10px] uppercase tracking-wider font-semibold text-text-muted">Name</th>
<th className="text-left px-3 py-1.5 text-[10px] uppercase tracking-wider font-semibold text-text-muted w-28">Type</th> <th className="text-left px-3 py-1.5 text-[10px] uppercase tracking-wider font-semibold text-text-muted w-28">Type</th>
<th className="text-left px-3 py-1.5 text-[10px] uppercase tracking-wider font-semibold text-text-muted">Default</th> <th className="text-left px-3 py-1.5 text-[10px] uppercase tracking-wider font-semibold text-text-muted">Default</th>

View File

@@ -150,7 +150,7 @@ export function TemplatePushWizard({ open, onClose, tenantId, template }: Templa
return ( return (
<Dialog open={open} onOpenChange={(o) => !o && handleClose()}> <Dialog open={open} onOpenChange={(o) => !o && handleClose()}>
<DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto bg-surface border-border text-text-primary"> <DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto bg-panel border-border text-text-primary">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-sm flex items-center gap-2"> <DialogTitle className="text-sm flex items-center gap-2">
Push Template: {template.name} Push Template: {template.name}
@@ -193,7 +193,7 @@ export function TemplatePushWizard({ open, onClose, tenantId, template }: Templa
{devices?.map((device) => ( {devices?.map((device) => (
<label <label
key={device.id} key={device.id}
className="flex items-center gap-3 px-3 py-2 hover:bg-surface cursor-pointer" className="flex items-center gap-3 px-3 py-2 hover:bg-panel cursor-pointer"
> >
<Checkbox <Checkbox
checked={selectedDeviceIds.has(device.id)} checked={selectedDeviceIds.has(device.id)}
@@ -237,7 +237,7 @@ export function TemplatePushWizard({ open, onClose, tenantId, template }: Templa
Provide values for template variables. Built-in device variables are auto-populated per device. Provide values for template variables. Built-in device variables are auto-populated per device.
</div> </div>
<div className="text-[10px] text-text-muted bg-surface rounded px-3 py-2"> <div className="text-[10px] text-text-muted bg-panel rounded px-3 py-2">
Auto-populated: {'{{ device.hostname }}'}, {'{{ device.ip }}'}, {'{{ device.model }}'} Auto-populated: {'{{ device.hostname }}'}, {'{{ device.ip }}'}, {'{{ device.model }}'}
</div> </div>
@@ -321,7 +321,7 @@ export function TemplatePushWizard({ open, onClose, tenantId, template }: Templa
'text-xs px-2 py-1 rounded transition-colors', 'text-xs px-2 py-1 rounded transition-colors',
previewDevice === d.id previewDevice === d.id
? 'bg-elevated text-text-primary' ? 'bg-elevated text-text-primary'
: 'bg-surface text-text-secondary hover:text-text-secondary', : 'bg-panel text-text-secondary hover:text-text-secondary',
)} )}
> >
{d.hostname} {d.hostname}

View File

@@ -229,7 +229,7 @@ export function TemplatesPage() {
{templates.map((template) => ( {templates.map((template) => (
<div <div
key={template.id} key={template.id}
className="rounded-lg border border-border bg-surface/50 p-4 hover:bg-surface transition-colors" className="rounded-lg border border-border bg-panel/50 p-4 hover:bg-panel transition-colors"
> >
<div className="flex items-start justify-between"> <div className="flex items-start justify-between">
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
@@ -313,7 +313,7 @@ export function TemplatesPage() {
open={!!deleteConfirmId} open={!!deleteConfirmId}
onOpenChange={(o) => !o && setDeleteConfirmId(null)} onOpenChange={(o) => !o && setDeleteConfirmId(null)}
> >
<DialogContent className="max-w-sm bg-surface border-border text-text-primary"> <DialogContent className="max-w-sm bg-panel border-border text-text-primary">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-sm">Delete Template</DialogTitle> <DialogTitle className="text-sm">Delete Template</DialogTitle>
</DialogHeader> </DialogHeader>

View File

@@ -60,7 +60,7 @@ export function TenantList() {
<div className="rounded-lg border border-border overflow-hidden"> <div className="rounded-lg border border-border overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th className="text-left px-3 py-2 text-xs font-medium text-text-muted">Name</th> <th className="text-left px-3 py-2 text-xs font-medium text-text-muted">Name</th>
<th className="text-right px-3 py-2 text-xs font-medium text-text-muted">Users</th> <th className="text-right px-3 py-2 text-xs font-medium text-text-muted">Users</th>
<th className="text-right px-3 py-2 text-xs font-medium text-text-muted">Devices</th> <th className="text-right px-3 py-2 text-xs font-medium text-text-muted">Devices</th>
@@ -87,7 +87,7 @@ export function TenantList() {
tenants?.map((tenant) => ( tenants?.map((tenant) => (
<tr <tr
key={tenant.id} key={tenant.id}
className="border-b border-border/50 hover:bg-surface transition-colors" className="border-b border-border/50 hover:bg-panel transition-colors"
> >
<td className="px-3 py-2.5"> <td className="px-3 py-2.5">
<Link <Link

View File

@@ -195,7 +195,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
label="Unique Devices" label="Unique Devices"
value={stats.unique_devices.toLocaleString()} value={stats.unique_devices.toLocaleString()}
/> />
<div className="rounded-lg border border-border bg-surface p-3"> <div className="rounded-lg border border-border bg-panel p-3">
<div className="text-[10px] font-medium uppercase tracking-wider text-text-muted mb-2"> <div className="text-[10px] font-medium uppercase tracking-wider text-text-muted mb-2">
By Justification By Justification
</div> </div>
@@ -228,7 +228,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
setJustificationFilter(e.target.value) setJustificationFilter(e.target.value)
setPage(1) setPage(1)
}} }}
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
> >
{JUSTIFICATION_TYPES.map((j) => ( {JUSTIFICATION_TYPES.map((j) => (
<option key={j.value} value={j.value}> <option key={j.value} value={j.value}>
@@ -244,7 +244,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
setActionFilter(e.target.value) setActionFilter(e.target.value)
setPage(1) setPage(1)
}} }}
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
> >
{ACTION_TYPES.map((a) => ( {ACTION_TYPES.map((a) => (
<option key={a.value} value={a.value}> <option key={a.value} value={a.value}>
@@ -263,7 +263,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
setDateFrom(e.target.value) setDateFrom(e.target.value)
setPage(1) setPage(1)
}} }}
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
/> />
</div> </div>
@@ -277,7 +277,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
setDateTo(e.target.value) setDateTo(e.target.value)
setPage(1) setPage(1)
}} }}
className="h-8 rounded-md border border-border bg-surface px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-8 rounded-md border border-border bg-panel px-2 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
/> />
</div> </div>
@@ -288,7 +288,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
<button <button
onClick={handleExport} onClick={handleExport}
disabled={exporting || !data?.total} disabled={exporting || !data?.total}
className="inline-flex items-center gap-1.5 rounded-md border border-border bg-surface px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-elevated hover:text-text-primary transition-colors disabled:opacity-50 disabled:cursor-not-allowed" className="inline-flex items-center gap-1.5 rounded-md border border-border bg-panel px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-elevated hover:text-text-primary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
> >
<Download className="h-3.5 w-3.5" /> <Download className="h-3.5 w-3.5" />
{exporting ? 'Exporting...' : 'Export CSV'} {exporting ? 'Exporting...' : 'Export CSV'}
@@ -296,7 +296,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
</div> </div>
{/* Table */} {/* Table */}
<div className="rounded-lg border border-border bg-surface overflow-hidden"> <div className="rounded-lg border border-border bg-panel overflow-hidden">
{isLoading ? ( {isLoading ? (
<div className="p-8 text-center"> <div className="p-8 text-center">
<div className="inline-block h-6 w-6 animate-spin rounded-full border-2 border-accent border-t-transparent" /> <div className="inline-block h-6 w-6 animate-spin rounded-full border-2 border-accent border-t-transparent" />
@@ -373,7 +373,7 @@ export function TransparencyLogTable({ tenantId }: TransparencyLogTableProps) {
setPerPage(Number(e.target.value)) setPerPage(Number(e.target.value))
setPage(1) setPage(1)
}} }}
className="h-7 rounded border border-border bg-surface px-1.5 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent" className="h-7 rounded border border-border bg-panel px-1.5 text-xs text-text-primary focus:outline-none focus:ring-1 focus:ring-accent"
> >
{PER_PAGE_OPTIONS.map((n) => ( {PER_PAGE_OPTIONS.map((n) => (
<option key={n} value={n}> <option key={n} value={n}>
@@ -438,7 +438,7 @@ interface StatsCardProps {
function StatsCard({ icon: Icon, label, value }: StatsCardProps) { function StatsCard({ icon: Icon, label, value }: StatsCardProps) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-3"> <div className="rounded-lg border border-border bg-panel p-3">
<div className="flex items-center gap-2 mb-1"> <div className="flex items-center gap-2 mb-1">
<Icon className="h-3.5 w-3.5 text-text-muted" /> <Icon className="h-3.5 w-3.5 text-text-muted" />
<span className="text-[10px] font-medium uppercase tracking-wider text-text-muted"> <span className="text-[10px] font-medium uppercase tracking-wider text-text-muted">

View File

@@ -8,8 +8,8 @@ const buttonVariants = cva(
{ {
variants: { variants: {
variant: { variant: {
default: 'bg-[hsl(var(--accent-muted))] text-accent hover:bg-accent/20', default: 'bg-[hsl(var(--accent-soft))] text-accent hover:bg-accent/20',
solid: 'bg-accent text-white hover:bg-accent-hover', solid: 'bg-accent text-white hover:bg-accent',
destructive: 'bg-error/15 text-error hover:bg-error/20', destructive: 'bg-error/15 text-error hover:bg-error/20',
outline: outline:
'border border-border bg-transparent text-text-secondary hover:bg-elevated hover:text-text-primary', 'border border-border bg-transparent text-text-secondary hover:bg-elevated hover:text-text-primary',

View File

@@ -6,7 +6,7 @@ const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElemen
<div <div
ref={ref} ref={ref}
className={cn( className={cn(
'rounded-lg border border-border bg-surface text-text-primary', 'rounded-lg border border-border bg-panel text-text-primary',
className, className,
)} )}
{...props} {...props}

View File

@@ -32,7 +32,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content <DialogPrimitive.Content
ref={ref} ref={ref}
className={cn( className={cn(
'fixed left-[50%] top-[50%] z-50 translate-x-[-50%] translate-y-[-50%] w-full max-w-lg rounded-lg border border-border bg-surface text-text-primary p-6 duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'fixed left-[50%] top-[50%] z-50 translate-x-[-50%] translate-y-[-50%] w-full max-w-lg rounded-lg border border-border bg-panel text-text-primary p-6 duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
className, className,
)} )}
{...props} {...props}

View File

@@ -38,7 +38,7 @@ const DropdownMenuSubContent = React.forwardRef<
<DropdownMenuPrimitive.SubContent <DropdownMenuPrimitive.SubContent
ref={ref} ref={ref}
className={cn( className={cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-surface p-1 text-text-primary', 'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-panel p-1 text-text-primary',
className, className,
)} )}
{...props} {...props}
@@ -55,7 +55,7 @@ const DropdownMenuContent = React.forwardRef<
ref={ref} ref={ref}
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-surface p-1 text-text-primary data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-panel p-1 text-text-primary data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className, className,
)} )}
{...props} {...props}

View File

@@ -16,7 +16,7 @@ const PopoverContent = React.forwardRef<
align={align} align={align}
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
'z-50 w-72 rounded-lg border border-border bg-surface p-4 text-text-primary outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 w-72 rounded-lg border border-border bg-panel p-4 text-text-primary outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className, className,
)} )}
{...props} {...props}

View File

@@ -63,7 +63,7 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content <SelectPrimitive.Content
ref={ref} ref={ref}
className={cn( className={cn(
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border bg-surface text-text-primary data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border bg-panel text-text-primary data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
position === 'popper' && position === 'popper' &&
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
className, className,

View File

@@ -6,7 +6,7 @@ export function Skeleton({ className, ...props }: SkeletonProps) {
return ( return (
<div <div
className={cn( className={cn(
'animate-shimmer rounded-md bg-elevated bg-shimmer bg-shimmer relative overflow-hidden', 'animate-pulse rounded-md bg-elevated relative overflow-hidden',
className, className,
)} )}
{...props} {...props}

View File

@@ -26,7 +26,7 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitive.Trigger <TabsPrimitive.Trigger
ref={ref} ref={ref}
className={cn( className={cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-[hsl(var(--accent-muted))] data-[state=active]:text-accent data-[state=active]:font-semibold data-[state=inactive]:text-text-muted data-[state=inactive]:hover:text-text-secondary', 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-[hsl(var(--accent-soft))] data-[state=active]:text-accent data-[state=active]:font-semibold data-[state=inactive]:text-text-muted data-[state=inactive]:hover:text-text-secondary',
className, className,
)} )}
{...props} {...props}

View File

@@ -8,7 +8,7 @@ export function Toaster() {
<SonnerToaster <SonnerToaster
position="bottom-right" position="bottom-right"
toastOptions={{ toastOptions={{
className: 'bg-surface border-border text-text-primary', className: 'bg-panel border-border text-text-primary',
descriptionClassName: 'text-text-secondary', descriptionClassName: 'text-text-secondary',
}} }}
theme={theme} theme={theme}

View File

@@ -76,7 +76,7 @@ export function UserList({ tenantId }: Props) {
<div className="rounded-lg border border-border overflow-hidden"> <div className="rounded-lg border border-border overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-border bg-surface"> <tr className="border-b border-border bg-panel">
<th scope="col" className="text-left px-3 py-2 text-xs font-medium text-text-muted">Name</th> <th scope="col" className="text-left px-3 py-2 text-xs font-medium text-text-muted">Name</th>
<th scope="col" className="text-left px-3 py-2 text-xs font-medium text-text-muted">Email</th> <th scope="col" className="text-left px-3 py-2 text-xs font-medium text-text-muted">Email</th>
<th scope="col" className="text-left px-3 py-2 text-xs font-medium text-text-muted">Role</th> <th scope="col" className="text-left px-3 py-2 text-xs font-medium text-text-muted">Role</th>
@@ -104,7 +104,7 @@ export function UserList({ tenantId }: Props) {
users?.map((u) => ( users?.map((u) => (
<tr <tr
key={u.id} key={u.id}
className="border-b border-border/50 hover:bg-surface transition-colors" className="border-b border-border/50 hover:bg-panel transition-colors"
> >
<td className="px-3 py-2.5 font-medium">{u.name}</td> <td className="px-3 py-2.5 font-medium">{u.name}</td>
<td className="px-3 py-2.5 text-text-secondary">{u.email}</td> <td className="px-3 py-2.5 text-text-secondary">{u.email}</td>

View File

@@ -202,7 +202,7 @@ export function VpnPage() {
<div className="p-6 space-y-6"> <div className="p-6 space-y-6">
<h1 className="text-2xl font-bold text-text-primary">VPN</h1> <h1 className="text-2xl font-bold text-text-primary">VPN</h1>
<div className="max-w-lg mx-auto mt-12"> <div className="max-w-lg mx-auto mt-12">
<div className="rounded-lg border border-border bg-surface p-8 text-center space-y-6"> <div className="rounded-lg border border-border bg-panel p-8 text-center space-y-6">
<div className="mx-auto w-16 h-16 rounded-2xl bg-accent/10 flex items-center justify-center"> <div className="mx-auto w-16 h-16 rounded-2xl bg-accent/10 flex items-center justify-center">
<Shield className="h-8 w-8 text-accent" /> <Shield className="h-8 w-8 text-accent" />
</div> </div>
@@ -496,7 +496,7 @@ function InfoCard({
muted?: boolean muted?: boolean
}) { }) {
return ( return (
<div className="rounded-lg border border-border bg-surface p-4"> <div className="rounded-lg border border-border bg-panel p-4">
<div className="flex items-center gap-2 mb-1"> <div className="flex items-center gap-2 mb-1">
<Icon className="h-4 w-4 text-text-muted" /> <Icon className="h-4 w-4 text-text-muted" />
<span className="text-xs text-text-muted uppercase tracking-wider">{label}</span> <span className="text-xs text-text-muted uppercase tracking-wider">{label}</span>

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