Design overhaul, stats page, internal notes
Design: Onest+Unbounded font pairing (Cyrillic-verified, replacing plain
Golos Text), manual light/dark toggle wired to the data-theme cascade
already built in MVP-1, refreshed palette + new chart-mark tokens
(CVD-validated via the dataviz skill's validator), colored avatar
initials, per-channel colored badges, favicon, nicer empty states.
Stats: /stats page — status/channel breakdown, 14-day ticket volume,
avg first-response time, per-agent open-ticket workload. Colors and
chart forms follow the dataviz skill's procedure (categorical order
re-stepped to clear the CVD adjacency check in both themes).
Internal notes: messages.visibility ("public"/"internal") column.
Agent-only notes never reach customer-facing reads (getTicketForCustomer)
or the customer SSE stream (/api/portal/events, reused by the widget) —
fixed at both the initial-fetch and live-delivery layers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH
This commit is contained in:
1 parent
4efce5f307
commit
9f1413f0b9
23 files changed
+1315
-64
No files matched your search
+98
-11
@@ -2,6 +2,7 @@
|
||||
|
||||
@theme {
|
||||
--font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif;
|
||||
--font-display: var(--font-display), var(--font-sans), ui-sans-serif, sans-serif;
|
||||
--font-mono: var(--font-mono), ui-monospace, monospace;
|
||||
|
||||
--color-bg: var(--bg);
|
||||
@@ -30,25 +31,41 @@
|
||||
--color-success-soft: var(--success-soft);
|
||||
--color-success-soft-text: var(--success-soft-text);
|
||||
|
||||
--color-info: var(--info);
|
||||
--color-info-soft: var(--info-soft);
|
||||
--color-info-soft-text: var(--info-soft-text);
|
||||
|
||||
--color-rose: var(--rose);
|
||||
--color-rose-soft: var(--rose-soft);
|
||||
--color-rose-soft-text: var(--rose-soft-text);
|
||||
|
||||
/* Chart marks — validated categorical set (dataviz skill), distinct from
|
||||
the softer *-soft badge tokens which are too light for dark-mode marks. */
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-muted: var(--chart-muted);
|
||||
|
||||
--radius-sm: var(--radius-sm-val);
|
||||
--radius-md: var(--radius-md-val);
|
||||
--radius-lg: var(--radius-lg-val);
|
||||
}
|
||||
|
||||
:root {
|
||||
--bg: #fafaf9;
|
||||
--bg: #f8f7fb;
|
||||
--surface: #ffffff;
|
||||
--surface-hover: #f6f5ff;
|
||||
--border: #e8e6f5;
|
||||
--border-strong: #d6d1ee;
|
||||
--text: #191524;
|
||||
--text-muted: #6c6685;
|
||||
--text-faint: #a29cc0;
|
||||
--surface-hover: #f2effa;
|
||||
--border: #e5e0f2;
|
||||
--border-strong: #cec4e8;
|
||||
--text: #171325;
|
||||
--text-muted: #635d7a;
|
||||
--text-faint: #9891ad;
|
||||
|
||||
--accent: #7c3aed;
|
||||
--accent-hover: #6d28d9;
|
||||
--accent-soft: #f3edff;
|
||||
--accent-soft-text: #6d28d9;
|
||||
--accent: #6d28d9;
|
||||
--accent-hover: #5b21b6;
|
||||
--accent-soft: #f0e8fe;
|
||||
--accent-soft-text: #5b21b6;
|
||||
|
||||
--danger: #dc2626;
|
||||
--danger-soft: #fef2f2;
|
||||
@@ -62,6 +79,22 @@
|
||||
--success-soft: #ecfdf9;
|
||||
--success-soft-text: #0f766e;
|
||||
|
||||
--info: #2563eb;
|
||||
--info-soft: #eff6ff;
|
||||
--info-soft-text: #1d4ed8;
|
||||
|
||||
--rose: #e11d48;
|
||||
--rose-soft: #fff1f2;
|
||||
--rose-soft-text: #be123c;
|
||||
|
||||
/* Chart marks — fixed categorical order, CVD-validated (accent/success/
|
||||
info/warning); reorder only after re-running the validator. */
|
||||
--chart-1: #6d28d9;
|
||||
--chart-2: #0d9488;
|
||||
--chart-3: #2563eb;
|
||||
--chart-4: #d97706;
|
||||
--chart-muted: var(--border-strong);
|
||||
|
||||
--radius-sm-val: 8px;
|
||||
--radius-md-val: 12px;
|
||||
--radius-lg-val: 18px;
|
||||
@@ -97,6 +130,22 @@
|
||||
--success-soft: #0f2320;
|
||||
--success-soft-text: #5eead4;
|
||||
|
||||
--info: #60a5fa;
|
||||
--info-soft: #12203a;
|
||||
--info-soft-text: #93c5fd;
|
||||
|
||||
--rose: #fb7185;
|
||||
--rose-soft: #2a1420;
|
||||
--rose-soft-text: #fda4af;
|
||||
|
||||
/* Darker/more saturated than the badge tokens above — validated
|
||||
separately for the dark-mode lightness band (L 0.48–0.67). */
|
||||
--chart-1: #8b5cf6;
|
||||
--chart-2: #0d9488;
|
||||
--chart-3: #3b82f6;
|
||||
--chart-4: #d97706;
|
||||
--chart-muted: var(--border-strong);
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
@@ -128,9 +177,46 @@
|
||||
--success-soft: #0f2320;
|
||||
--success-soft-text: #5eead4;
|
||||
|
||||
--info: #60a5fa;
|
||||
--info-soft: #12203a;
|
||||
--info-soft-text: #93c5fd;
|
||||
|
||||
--rose: #fb7185;
|
||||
--rose-soft: #2a1420;
|
||||
--rose-soft-text: #fda4af;
|
||||
|
||||
--chart-1: #8b5cf6;
|
||||
--chart-2: #0d9488;
|
||||
--chart-3: #3b82f6;
|
||||
--chart-4: #d97706;
|
||||
--chart-muted: var(--border-strong);
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Theme-toggle icon: both render always, CSS picks which shows — same
|
||||
data-theme cascade the palette above uses, so it never needs JS state. */
|
||||
.theme-toggle-btn .theme-icon-sun {
|
||||
display: none;
|
||||
}
|
||||
.theme-toggle-btn .theme-icon-moon {
|
||||
display: inline;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme="light"]) .theme-toggle-btn .theme-icon-sun {
|
||||
display: inline;
|
||||
}
|
||||
:root:not([data-theme="light"]) .theme-toggle-btn .theme-icon-moon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
:root[data-theme="dark"] .theme-toggle-btn .theme-icon-sun {
|
||||
display: inline;
|
||||
}
|
||||
:root[data-theme="dark"] .theme-toggle-btn .theme-icon-moon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
* {
|
||||
border-color: var(--border);
|
||||
}
|
||||
@@ -175,6 +261,7 @@ body {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
||||
Reference in new issue
Block a user