Backend services: - targo-hub: extract deepGetValue to helpers.js, DRY disconnect reasons lookup map, compact CAPABILITIES, consolidate vision.js prompts/schemas, extract dispatch scoring weights, trim section dividers across 9 files - modem-bridge: extract getSession() helper (6 occurrences), resetIdleTimer(), consolidate DM query factory, fix duplicate username fill bug, trim headers (server.js -36%, tplink-session.js -47%, docker-compose.yml -57%) Frontend: - useWifiDiagnostic: extract THRESHOLDS const, split processDiagnostic into 6 focused helpers (processOnlineStatus, processWanIPs, processRadios, processMeshNodes, processClients, checkRadioIssues) - EquipmentDetail: merge duplicate ROLE_LABELS, remove verbose comments Documentation (17 → 13 files, -1,400 lines): - New consolidated README.md (architecture, services, dependencies, auth) - Merge ECOSYSTEM-OVERVIEW into ARCHITECTURE.md - Merge MIGRATION-PLAN + ARCHITECTURE-COMPARE + FIELD-GAP + CHANGELOG → MIGRATION.md - Merge COMPETITIVE-ANALYSIS into PLATFORM-STRATEGY.md - Update ROADMAP.md with current phase status - Delete CONTEXT.md (absorbed into README) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
2.1 KiB
SCSS
104 lines
2.1 KiB
SCSS
// Gigafibre Client Portal — Consumer branding
|
|
|
|
:root {
|
|
--gf-primary: #0ea5e9; // sky-500
|
|
--gf-primary-dark: #0284c7; // sky-600
|
|
--gf-accent: #06b6d4; // cyan-500
|
|
--gf-bg: #f8fafc; // slate-50
|
|
--gf-surface: #ffffff;
|
|
--gf-text: #1e293b; // slate-800
|
|
--gf-text-secondary: #64748b; // slate-500
|
|
--gf-border: #e2e8f0; // slate-200
|
|
--gf-success: #22c55e;
|
|
--gf-warning: #f59e0b;
|
|
--gf-danger: #ef4444;
|
|
}
|
|
|
|
body {
|
|
background: var(--gf-bg);
|
|
color: var(--gf-text);
|
|
font-family: 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
}
|
|
|
|
.q-drawer {
|
|
background: var(--gf-surface) !important;
|
|
border-right: 1px solid var(--gf-border) !important;
|
|
}
|
|
|
|
.portal-card {
|
|
background: var(--gf-surface);
|
|
border: 1px solid var(--gf-border);
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
}
|
|
|
|
.portal-header {
|
|
background: linear-gradient(135deg, var(--gf-primary), var(--gf-accent));
|
|
}
|
|
|
|
// Status chips
|
|
.status-paid, .status-closed, .status-resolved {
|
|
color: var(--gf-success);
|
|
font-weight: 600;
|
|
}
|
|
.status-unpaid, .status-overdue {
|
|
color: var(--gf-danger);
|
|
font-weight: 600;
|
|
}
|
|
.status-open {
|
|
color: var(--gf-primary);
|
|
font-weight: 600;
|
|
}
|
|
|
|
// Summary card number
|
|
.summary-value {
|
|
font-size: 2rem;
|
|
font-weight: 700;
|
|
color: var(--gf-primary);
|
|
}
|
|
|
|
.page-title {
|
|
font-size: 1.5rem;
|
|
font-weight: 600;
|
|
color: var(--gf-text);
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
// Monthly total banner (service locations)
|
|
.monthly-total-banner {
|
|
background: linear-gradient(135deg, #f0f9ff, #e0f2fe);
|
|
border: 1px solid #bae6fd;
|
|
border-radius: 10px;
|
|
padding: 14px 18px;
|
|
}
|
|
|
|
// Location cards
|
|
.location-card {
|
|
background: var(--gf-bg);
|
|
border: 1px solid var(--gf-border);
|
|
border-radius: 10px;
|
|
padding: 14px;
|
|
}
|
|
|
|
.subscription-row {
|
|
padding: 6px 0;
|
|
border-bottom: 1px dashed var(--gf-border);
|
|
&:last-child { border-bottom: none; }
|
|
}
|
|
|
|
.location-subtotal {
|
|
padding-top: 6px;
|
|
border-top: 1px solid var(--gf-border);
|
|
}
|
|
|
|
// Clickable table rows
|
|
.clickable-table {
|
|
.q-table tbody tr {
|
|
cursor: pointer;
|
|
transition: background 0.15s;
|
|
&:hover {
|
|
background: rgba(14, 165, 233, 0.05);
|
|
}
|
|
}
|
|
}
|