feat: comprehensive design system overhaul

Applied impeccable design critique, audit, harden, layout, distill, and polish across all pages.

DESIGN SYSTEM:
- Created PRODUCT.md (5 design principles, WCAG 2.1 AA target)
- Created DESIGN.md (34 color tokens, 6 radius scale, full component spec)
- Created .impeccable/design.json (sidecar with tonal ramps, shadows, motion)

ACCESSIBILITY:
- 33 aria-labels across 7 pages (was ~13)
- 63 <label> elements (was ~30)
- 6 <main> landmarks + role=navigation on all sidebars
- Esc to close modals on 4 pages
- Keyboard shortcuts (Ctrl+J/K, Ctrl+F) on chat

THEMING:
- 216 hardcoded colors replaced with var() references
- 449 !important removed from dark-mode.css
- Dark mode script unified (was duplicated 9x inline)
- All modals converted to .modal-overlay + .modal design system classes

CHAT:
- Error states for messages (.msg.erro, .msg.enviando)
- Connection status indicator
- Confirmation modal before finalizar
- Input bar reorganized (3 visible actions, + menu)
- Right panel accordions
- Send button disabled when empty
- Touch targets 44px on mobile

CLIENT DETAIL:
- Tabs/badges/sub-tabs use CSS classes instead of inline styles
- 'Iniciar Conversa' button now primary action
- alert() replaced with inline feedback
- Modal converted to design system classes

CLIENT LIST:
- Modal moved inside <body> (was HTML-invalid)
- alert() replaced with inline feedback
- Modal uses .show pattern

SETTINGS:
- 4 modals converted to design system classes
- 14 alert() calls replaced with inline feedback
- fecharModal() uses classList instead of style.display

ROUTES:
- border-radius normalized, hardcoded colors fixed

Score progression:
  Chat:        23 → 32/40
  Client List: 32 → 35/40
  Client Detail: 26 → 30/40
  Settings:     29 → 35/40
  Routes:       37 → 38/40
  Audit (project): 14/20 → 17/20
This commit is contained in:
2026-06-23 16:58:12 +00:00
parent cf720c37a1
commit 12d419de7c
113 changed files with 52423 additions and 951 deletions
+31 -39
View File
@@ -1,44 +1,36 @@
// Dark Mode Controller - Only handles initialization/persistence
// Dark Mode Controller — Unified for all Chatc2 pages
(function() {
if (typeof window.darkModeToggle !== 'function') {
// Ensure function exists (inline script in head should have defined it)
window.darkModeToggle = function() {
var el = document.body;
if (!el) return;
var isDark = localStorage.getItem('chatc2_dark_mode') === 'true';
var enable = !isDark;
el.classList.toggle('dark-mode', enable);
localStorage.setItem('chatc2_dark_mode', enable ? 'true' : 'false');
document.querySelectorAll('.dark-mode-toggle').forEach(function(btn) {
btn.innerHTML = enable ? '☀️ Claro' : '🌙 Escuro';
});
};
window.darkModeApply = function(enable) {
var el = document.body;
if (!el) return;
el.classList.toggle('dark-mode', enable);
localStorage.setItem('chatc2_dark_mode', enable ? 'true' : 'false');
document.querySelectorAll('.dark-mode-toggle').forEach(function(btn) {
btn.innerHTML = enable ? '☀️ Claro' : '🌙 Escuro';
});
};
window.darkModeIsDark = function() { return localStorage.getItem('chatc2_dark_mode') === 'true'; };
// Apply on load immediately (FOUC prevention)
if (localStorage.getItem('chatc2_dark_mode') === 'true') {
document.documentElement.classList.add('dark-mode-pending');
}
// Apply on load
if (localStorage.getItem('chatc2_dark_mode') === 'true') {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
document.body.classList.add('dark-mode');
document.querySelectorAll('.dark-mode-toggle').forEach(function(btn) {
btn.innerHTML = '☀️ Claro';
});
});
} else {
document.body.classList.add('dark-mode');
document.querySelectorAll('.dark-mode-toggle').forEach(function(btn) {
btn.innerHTML = '☀️ Claro';
});
}
function applyTheme(enable) {
document.documentElement.classList.remove('dark-mode-pending');
document.body && document.body.classList.toggle('dark-mode', enable);
localStorage.setItem('chatc2_dark_mode', enable ? 'true' : 'false');
document.querySelectorAll('.dark-mode-toggle').forEach(function(btn) {
btn.innerHTML = enable ? '☀️ Claro' : '🌙 Escuro';
});
}
window.darkModeToggle = function() {
var isDark = localStorage.getItem('chatc2_dark_mode') === 'true';
applyTheme(!isDark);
};
window.darkModeApply = function(enable) { applyTheme(enable); };
window.darkModeIsDark = function() {
return localStorage.getItem('chatc2_dark_mode') === 'true';
};
// Apply stored preference after DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
applyTheme(localStorage.getItem('chatc2_dark_mode') === 'true');
});
} else {
applyTheme(localStorage.getItem('chatc2_dark_mode') === 'true');
}
})();