From 7db44640caf99a20d27afe562a5c7535a5501388 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Thu, 19 Feb 2026 09:03:21 -0500 Subject: [PATCH] feat: switch web UI to light theme with larger font sizes Replace dark blueprint theme with a clean light theme for better readability. Bump all font sizes (10px labels to 12px, 13px body text to 14px) and improve text contrast for users with reading glasses. Icon colors now use CSS variables instead of hardcoded hex. Co-Authored-By: Claude Opus 4.6 --- FabWorks.Api/wwwroot/css/styles.css | 182 +++++++++++++------------- FabWorks.Api/wwwroot/js/components.js | 4 +- FabWorks.Api/wwwroot/js/icons.js | 4 +- FabWorks.Api/wwwroot/js/pages.js | 18 +-- 4 files changed, 102 insertions(+), 106 deletions(-) diff --git a/FabWorks.Api/wwwroot/css/styles.css b/FabWorks.Api/wwwroot/css/styles.css index 9dd9643..8586003 100644 --- a/FabWorks.Api/wwwroot/css/styles.css +++ b/FabWorks.Api/wwwroot/css/styles.css @@ -1,21 +1,21 @@ :root { - --bg-deep: #0a0e14; - --bg: #0d1117; - --surface: #151b23; - --surface-raised: #1c2128; - --border: #2a313a; - --border-subtle: #21262d; - --text: #e6edf3; - --text-secondary: #7d8590; - --text-dim: #484f58; - --cyan: #00d4ff; - --cyan-dim: rgba(0, 212, 255, 0.15); - --cyan-glow: rgba(0, 212, 255, 0.3); - --amber: #f0883e; - --amber-dim: rgba(240, 136, 62, 0.15); - --green: #3fb950; - --green-dim: rgba(63, 185, 80, 0.12); - --red: #f85149; + --bg-deep: #f0f1f3; + --bg: #f8f9fa; + --surface: #ffffff; + --surface-raised: #ffffff; + --border: #d0d5dd; + --border-subtle: #e4e7ec; + --text: #1a1a1a; + --text-secondary: #475467; + --text-dim: #667085; + --cyan: #0975b0; + --cyan-dim: rgba(9, 117, 176, 0.1); + --cyan-glow: rgba(9, 117, 176, 0.2); + --amber: #b54708; + --amber-dim: rgba(181, 71, 8, 0.08); + --green: #067647; + --green-dim: rgba(6, 118, 71, 0.08); + --red: #d92d20; --sidebar-w: 64px; --font-display: 'Outfit', sans-serif; --font-body: 'IBM Plex Sans', sans-serif; @@ -33,24 +33,11 @@ body { overflow-x: hidden; } -/* Blueprint grid background */ -body::before { - content: ''; - position: fixed; - inset: 0; - background-image: - linear-gradient(rgba(0, 212, 255, 0.03) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 212, 255, 0.03) 1px, transparent 1px); - background-size: 48px 48px; - pointer-events: none; - z-index: 0; -} - /* ─── Sidebar ─── */ .sidebar { width: var(--sidebar-w); background: var(--bg-deep); - border-right: 1px solid var(--border-subtle); + border-right: 1px solid var(--border); display: flex; flex-direction: column; align-items: center; @@ -81,7 +68,6 @@ body::before { .sidebar-brand svg { width: 26px; height: 26px; color: var(--cyan); - filter: drop-shadow(0 0 6px rgba(0, 212, 255, 0.4)); } .sidebar-nav { @@ -126,7 +112,6 @@ body::before { height: 20px; background: var(--cyan); border-radius: 0 2px 2px 0; - box-shadow: 0 0 8px var(--cyan-glow); } .nav-item svg { width: 20px; height: 20px; } @@ -136,12 +121,12 @@ body::before { left: calc(100% + 12px); top: 50%; transform: translateY(-50%); - background: var(--surface-raised); + background: var(--text); border: 1px solid var(--border); - color: var(--text); + color: #fff; padding: 4px 10px; border-radius: 4px; - font-size: 12px; + font-size: 13px; font-family: var(--font-body); white-space: nowrap; opacity: 0; @@ -164,9 +149,9 @@ body::before { } .topbar { - background: rgba(13, 17, 23, 0.85); + background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(12px); - border-bottom: 1px solid var(--border-subtle); + border-bottom: 1px solid var(--border); padding: 0 32px; height: 56px; display: flex; @@ -185,14 +170,14 @@ body::before { .topbar h2 { font-family: var(--font-display); - font-size: 16px; + font-size: 18px; font-weight: 600; letter-spacing: -0.01em; } .topbar-tag { font-family: var(--font-mono); - font-size: 10px; + font-size: 12px; color: var(--cyan); background: var(--cyan-dim); padding: 2px 8px; @@ -212,11 +197,6 @@ body::before { to { opacity: 1; transform: translateY(0); } } -@keyframes pulseGlow { - 0%, 100% { box-shadow: 0 0 4px var(--cyan-glow); } - 50% { box-shadow: 0 0 12px var(--cyan-glow); } -} - .animate-in { animation: fadeSlideIn 0.3s ease forwards; opacity: 0; @@ -233,6 +213,7 @@ body::before { border: 1px solid var(--border-subtle); border-radius: 6px; overflow: hidden; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); } .card-header { @@ -240,7 +221,7 @@ body::before { border-bottom: 1px solid var(--border-subtle); font-family: var(--font-display); font-weight: 600; - font-size: 13px; + font-size: 14px; letter-spacing: 0.02em; display: flex; align-items: center; @@ -266,20 +247,21 @@ body::before { padding: 18px 20px; position: relative; overflow: hidden; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); } .stat-card::before { content: ''; position: absolute; top: 0; left: 0; - width: 100%; height: 2px; + width: 100%; height: 3px; background: linear-gradient(90deg, var(--cyan), transparent); - opacity: 0.6; + opacity: 0.5; } .stat-label { font-family: var(--font-mono); - font-size: 10px; + font-size: 12px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1.5px; @@ -295,7 +277,7 @@ body::before { } .stat-value.stat-sm { - font-size: 14px; + font-size: 15px; font-weight: 500; font-family: var(--font-mono); } @@ -309,22 +291,22 @@ th { background: var(--bg); border-bottom: 1px solid var(--border); font-family: var(--font-mono); - font-size: 10px; + font-size: 12px; text-transform: uppercase; - letter-spacing: 1.2px; + letter-spacing: 1px; color: var(--text-dim); - font-weight: 500; + font-weight: 600; white-space: nowrap; } td { - padding: 11px 16px; + padding: 12px 16px; border-bottom: 1px solid var(--border-subtle); - font-size: 13px; + font-size: 14px; } tbody tr { transition: background 0.1s; } -tbody tr:hover td { background: rgba(0, 212, 255, 0.03); } +tbody tr:hover td { background: var(--cyan-dim); } tbody tr:last-child td { border-bottom: none; } /* ─── Badges ─── */ @@ -332,21 +314,21 @@ tbody tr:last-child td { border-bottom: none; } display: inline-flex; align-items: center; gap: 4px; - padding: 2px 8px; + padding: 3px 10px; border-radius: 3px; font-family: var(--font-mono); - font-size: 10px; - font-weight: 500; + font-size: 12px; + font-weight: 600; letter-spacing: 0.5px; text-transform: uppercase; } -.badge svg { width: 12px; height: 12px; flex-shrink: 0; } +.badge svg { width: 14px; height: 14px; flex-shrink: 0; } .badge-cyan { background: var(--cyan-dim); color: var(--cyan); } .badge-amber { background: var(--amber-dim); color: var(--amber); } .badge-green { background: var(--green-dim); color: var(--green); } .badge-count { - background: var(--surface-raised); + background: var(--bg); color: var(--text-secondary); border: 1px solid var(--border); } @@ -356,41 +338,53 @@ tbody tr:last-child td { border-bottom: none; } display: inline-flex; align-items: center; gap: 6px; - padding: 6px 12px; + padding: 7px 14px; border-radius: 4px; font-family: var(--font-body); - font-size: 12px; + font-size: 13px; font-weight: 500; cursor: pointer; text-decoration: none; border: 1px solid var(--border); - background: var(--surface-raised); + background: var(--surface); color: var(--text-secondary); transition: all 0.15s; white-space: nowrap; } .btn:hover { - background: var(--surface); + background: var(--bg); color: var(--text); border-color: var(--text-dim); } -.btn svg { width: 13px; height: 13px; } +.btn svg { width: 14px; height: 14px; } .btn-cyan { background: var(--cyan-dim); color: var(--cyan); - border-color: rgba(0, 212, 255, 0.2); + border-color: rgba(9, 117, 176, 0.25); } .btn-cyan:hover { - background: rgba(0, 212, 255, 0.2); - border-color: rgba(0, 212, 255, 0.4); + background: rgba(9, 117, 176, 0.15); + border-color: rgba(9, 117, 176, 0.4); color: var(--cyan); } -.btn-sm { padding: 3px 8px; font-size: 11px; } +.btn-amber { + background: var(--amber-dim); + color: var(--amber); + border-color: rgba(181, 71, 8, 0.25); +} + +.btn-amber:hover { + background: rgba(181, 71, 8, 0.15); + border-color: rgba(181, 71, 8, 0.4); + color: var(--amber); +} + +.btn-sm { padding: 4px 10px; font-size: 12px; } /* ─── Search ─── */ .search-box { @@ -401,18 +395,18 @@ tbody tr:last-child td { border-bottom: none; } border: 1px solid var(--border); border-radius: 4px; padding: 0 12px; - height: 34px; + height: 36px; width: 300px; transition: border-color 0.2s, box-shadow 0.2s; } .search-box:focus-within { border-color: var(--cyan); - box-shadow: 0 0 0 1px var(--cyan-dim); + box-shadow: 0 0 0 2px var(--cyan-dim); } .search-box svg { - width: 14px; height: 14px; + width: 16px; height: 16px; color: var(--text-dim); flex-shrink: 0; } @@ -421,7 +415,7 @@ tbody tr:last-child td { border-bottom: none; } border: none; outline: none; font-family: var(--font-body); - font-size: 13px; + font-size: 14px; width: 100%; background: transparent; color: var(--text); @@ -442,7 +436,7 @@ tbody tr:last-child td { border-bottom: none; } .detail-field label { display: block; font-family: var(--font-mono); - font-size: 10px; + font-size: 12px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text-dim); @@ -450,14 +444,14 @@ tbody tr:last-child td { border-bottom: none; } } .detail-field .value { - font-size: 14px; + font-size: 15px; font-weight: 500; word-break: break-all; } .detail-field .value.mono { font-family: var(--font-mono); - font-size: 12px; + font-size: 13px; color: var(--text-secondary); } @@ -468,7 +462,7 @@ tbody tr:last-child td { border-bottom: none; } gap: 6px; color: var(--text-dim); text-decoration: none; - font-size: 12px; + font-size: 13px; cursor: pointer; margin-bottom: 20px; font-family: var(--font-mono); @@ -488,7 +482,7 @@ tbody tr:last-child td { border-bottom: none; } .bom-expand-content { padding: 16px 16px 16px 48px; - border-left: 2px solid var(--cyan-dim); + border-left: 3px solid var(--cyan-dim); margin-left: 16px; } @@ -499,14 +493,14 @@ tbody tr:last-child td { border-bottom: none; } } .bom-expand-content .info-item { - font-size: 12px; + font-size: 13px; padding: 2px 0; } .bom-expand-content .info-item .lbl { color: var(--text-dim); font-family: var(--font-mono); - font-size: 10px; + font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; margin-right: 6px; @@ -519,7 +513,7 @@ tbody tr:last-child td { border-bottom: none; } .bom-section-title { font-family: var(--font-mono); - font-size: 10px; + font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.5px; @@ -546,7 +540,7 @@ tbody tr:last-child td { border-bottom: none; } align-items: center; gap: 6px; font-family: var(--font-mono); - font-size: 12px; + font-size: 13px; margin-bottom: 16px; flex-wrap: wrap; padding: 8px 14px; @@ -563,7 +557,7 @@ tbody tr:last-child td { border-bottom: none; } } .breadcrumb a:hover { opacity: 0.7; } -.breadcrumb .sep { color: var(--text-dim); font-size: 10px; } +.breadcrumb .sep { color: var(--text-dim); font-size: 11px; } .breadcrumb .current { color: var(--text); font-weight: 500; } .file-name-cell { @@ -588,7 +582,7 @@ tbody tr:last-child td { border-bottom: none; } text-align: center; padding: 60px 24px; color: var(--text-dim); - font-size: 13px; + font-size: 14px; font-family: var(--font-mono); } @@ -638,24 +632,25 @@ tbody tr:last-child td { border-bottom: none; } cursor: pointer; transition: all 0.2s; position: relative; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); } .drawing-card:hover { border-color: var(--cyan); - background: rgba(0, 212, 255, 0.03); - box-shadow: 0 0 0 1px var(--cyan-dim); + background: var(--cyan-dim); + box-shadow: 0 2px 8px rgba(9, 117, 176, 0.1); } .drawing-card-title { font-family: var(--font-display); - font-size: 15px; + font-size: 16px; font-weight: 600; margin-bottom: 2px; } .drawing-card-sub { font-family: var(--font-mono); - font-size: 10px; + font-size: 12px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; @@ -679,21 +674,22 @@ tbody tr:last-child td { border-bottom: none; } cursor: pointer; transition: all 0.15s; user-select: none; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); } -.equip-header:hover { background: rgba(0, 212, 255, 0.03); } +.equip-header:hover { background: var(--cyan-dim); } .equip-header .chevron-toggle { flex-shrink: 0; } .equip-header-title { font-family: var(--font-display); - font-size: 15px; + font-size: 16px; font-weight: 600; } .equip-header-number { font-family: var(--font-mono); - font-size: 13px; + font-size: 15px; color: var(--cyan); font-weight: 600; } @@ -707,7 +703,7 @@ tbody tr:last-child td { border-bottom: none; } .equip-header-stat { font-family: var(--font-mono); - font-size: 11px; + font-size: 13px; color: var(--text-dim); } diff --git a/FabWorks.Api/wwwroot/js/components.js b/FabWorks.Api/wwwroot/js/components.js index de03a79..fac1db5 100644 --- a/FabWorks.Api/wwwroot/js/components.js +++ b/FabWorks.Api/wwwroot/js/components.js @@ -17,7 +17,7 @@ function renderBomDetails(b) { if (ct.contentHash) { html += `
${icons.download} Download DXF - ${esc(displayName)} + ${esc(displayName)}
`; } } @@ -35,7 +35,7 @@ function renderBomDetails(b) {
Upper Tools${esc(fp.upperToolNames) || '\u2014'}
Lower Tools${esc(fp.lowerToolNames) || '\u2014'}
- ${fp.setupNotes ? `
Setup Notes${esc(fp.setupNotes)}
` : ''}`; + ${fp.setupNotes ? `
Setup Notes${esc(fp.setupNotes)}
` : ''}`; } html += ''; diff --git a/FabWorks.Api/wwwroot/js/icons.js b/FabWorks.Api/wwwroot/js/icons.js index 97a1bda..c81c93e 100644 --- a/FabWorks.Api/wwwroot/js/icons.js +++ b/FabWorks.Api/wwwroot/js/icons.js @@ -1,8 +1,8 @@ const icons = { search: ``, - folder: ``, + folder: ``, fileDxf: ``, - filePdf: ``, + filePdf: ``, fileGeneric: ``, download: ``, back: ``, diff --git a/FabWorks.Api/wwwroot/js/pages.js b/FabWorks.Api/wwwroot/js/pages.js index 8cce334..36db5ee 100644 --- a/FabWorks.Api/wwwroot/js/pages.js +++ b/FabWorks.Api/wwwroot/js/pages.js @@ -69,12 +69,12 @@ const pages = { return ` - ${e.id} + ${e.id} ${esc(drawingPart) || '\u2014'} - ${esc(e.title) || ''} + ${esc(e.title) || ''} ${e.bomItemCount} ${esc(e.exportedBy)} - ${fmtDate(e.exportedAt)} + ${fmtDate(e.exportedAt)} `; }).join(''); @@ -137,7 +137,7 @@ const pages = { ${esc(b.itemNo)} ${esc(b.partName)} ${esc(b.description)} - ${esc(b.material)} + ${esc(b.material)} ${b.qty ?? ''} ${b.totalQty ?? ''} @@ -260,7 +260,7 @@ const pages = { ${esc(b.itemNo)} ${esc(b.partName)} ${esc(b.description)} - ${esc(b.material)} + ${esc(b.material)} ${b.qty ?? ''} ${b.totalQty ?? ''} @@ -317,7 +317,7 @@ const pages = { ${icons.search} - @@ -368,9 +368,9 @@ const pages = {
${ext === 'pdf' ? icons.filePdf : icons.fileDxf}${esc(f.fileName)}
${ext.toUpperCase()} ${esc(f.drawingNumber)} - ${f.thickness != null ? f.thickness.toFixed(4) + '"' : '\u2014'} - ${fmtDate(f.createdAt)} - ${esc(hashShort)} + ${f.thickness != null ? f.thickness.toFixed(4) + '"' : '\u2014'} + ${fmtDate(f.createdAt)} + ${esc(hashShort)} ${icons.download}