Dark mode: - body.dark overrides CSS variables (navy→cream reverse) - Persisted in localStorage, applied before paint to avoid flash - Toggle button in nav (moon/sun icon), Shift+D shortcut Keyboard shortcuts: - g h/n/u/t/s/c/w/d/k for page navigation - n for new case, ? for help (Shift+/) - Esc closes any open dialog, blurs focused input - Help modal via showShortcutsHelp() with styled kbd elements SSE tasks stream: - /api/system/tasks/stream pushes snapshots whenever _progress changes - Client uses EventSource instead of 3s polling - Auto-reconnect after 5s on error - 15s heartbeat keeps proxies alive Compare decisions (new #/compare page): - /api/training/compare?a=id&b=id serializes both decisions' metadata, section breakdown from document_chunks, and three buckets of patterns (only in A, only in B, shared) using variant matching - Two-column header with section-length breakdown + patterns count - Three-column diff row (only_a / shared / only_b) Compose with suggestions (new #/compose page): - Large RTL justified textarea with Hebrew display font title input - Sidebar lists all 47 style_patterns grouped by type with filter chips - Click a pattern → inserts at cursor, replacing [placeholders] with ___ - Live section guess (פתיחה / רקע / טענות / דיון / סוף דבר) based on most-recent 400 chars - Auto-save draft to localStorage every second; restore on page load - "העתק טקסט" copies title+body to clipboard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
370 lines
11 KiB
CSS
370 lines
11 KiB
CSS
/* ════════════════════════════════════════════════════════════
|
|
* Ezer Mishpati — Design System
|
|
* Editorial/Judicial aesthetic for a Hebrew RTL judicial tool.
|
|
*
|
|
* Typography: Frank Ruhl Libre (display) + Assistant (body)
|
|
* Palette: Navy #0f172a + Cream #f5f1e8 + Gold #a97d3a
|
|
* ════════════════════════════════════════════════════════════ */
|
|
|
|
@import url('https://fonts.googleapis.com/css2?family=Heebo:wght@300;400;500;600;700;800;900&display=swap');
|
|
|
|
:root {
|
|
/* ── Colors ─────────────────────────────────────────── */
|
|
--color-navy: #0f172a;
|
|
--color-navy-soft: #1e293b;
|
|
--color-navy-dim: #334155;
|
|
|
|
--color-cream: #f5f1e8;
|
|
--color-cream-deep: #ede8d8;
|
|
--color-parchment: #fbf8f0;
|
|
|
|
--color-gold: #a97d3a;
|
|
--color-gold-deep: #8b6428;
|
|
--color-gold-soft: #c89a56;
|
|
--color-gold-wash: #fdf6e8;
|
|
|
|
--color-ink: #1a1a2e;
|
|
--color-ink-soft: #3a3a52;
|
|
--color-ink-muted: #6b7280;
|
|
--color-ink-light: #9ca3af;
|
|
|
|
--color-rule: #e5dfd0; /* cream-toned hairline */
|
|
--color-rule-soft: #f0ead8;
|
|
|
|
--color-surface: #ffffff;
|
|
--color-surface-raised: #fbf8f0;
|
|
--color-bg: var(--color-cream);
|
|
|
|
/* Status colors — tuned to the palette */
|
|
--color-success: #4a7c59;
|
|
--color-success-bg: #e8efe7;
|
|
--color-warn: #b8894a;
|
|
--color-warn-bg: #faf0dc;
|
|
--color-danger: #a54242;
|
|
--color-danger-bg: #f5e6e6;
|
|
--color-info: #4e6a8c;
|
|
--color-info-bg: #e6ecf3;
|
|
|
|
/* ── Typography — Heebo (Google's primary Hebrew font) ─── */
|
|
--font-display: 'Heebo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
--font-body: 'Heebo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
--font-mono: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, monospace;
|
|
|
|
--text-xs: 0.75rem;
|
|
--text-sm: 0.85rem;
|
|
--text-base: 0.95rem;
|
|
--text-md: 1.05rem;
|
|
--text-lg: 1.2rem;
|
|
--text-xl: 1.45rem;
|
|
--text-2xl: 1.8rem;
|
|
--text-3xl: 2.3rem;
|
|
--text-4xl: 2.9rem;
|
|
|
|
--leading-tight: 1.25;
|
|
--leading-snug: 1.4;
|
|
--leading-body: 1.65;
|
|
--leading-prose: 1.8;
|
|
|
|
--weight-light: 300;
|
|
--weight-normal: 400;
|
|
--weight-medium: 500;
|
|
--weight-semi: 600;
|
|
--weight-bold: 700;
|
|
--weight-display: 900;
|
|
|
|
/* ── Spacing scale (8px grid) ───────────────────────── */
|
|
--space-1: 4px;
|
|
--space-2: 8px;
|
|
--space-3: 12px;
|
|
--space-4: 16px;
|
|
--space-5: 20px;
|
|
--space-6: 24px;
|
|
--space-7: 32px;
|
|
--space-8: 40px;
|
|
--space-9: 56px;
|
|
--space-10: 72px;
|
|
|
|
/* ── Radii ──────────────────────────────────────────── */
|
|
--radius-sm: 4px;
|
|
--radius: 6px;
|
|
--radius-md: 8px;
|
|
--radius-lg: 12px;
|
|
--radius-xl: 16px;
|
|
--radius-pill: 999px;
|
|
|
|
/* ── Shadows — soft, editorial ──────────────────────── */
|
|
--shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
|
|
--shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
--shadow: 0 2px 6px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
|
|
--shadow-lg: 0 10px 30px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.05);
|
|
--shadow-gold: 0 0 0 3px var(--color-gold-wash);
|
|
|
|
/* ── Transitions ────────────────────────────────────── */
|
|
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
|
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
|
--t-fast: 120ms var(--ease-out);
|
|
--t: 180ms var(--ease-out);
|
|
--t-slow: 280ms var(--ease-out);
|
|
}
|
|
|
|
/* ── Dark theme overrides ────────────────────────────── */
|
|
body.dark {
|
|
--color-navy: #f5f1e8;
|
|
--color-navy-soft: #e8e0c8;
|
|
--color-navy-dim: #c7bc9a;
|
|
|
|
--color-cream: #0a0f1c;
|
|
--color-cream-deep: #121a2e;
|
|
--color-parchment: #161f36;
|
|
|
|
--color-gold: #d4a55a;
|
|
--color-gold-deep: #e8bc6f;
|
|
--color-gold-soft: #c89a56;
|
|
--color-gold-wash: rgba(212, 165, 90, 0.08);
|
|
|
|
--color-ink: #f5f1e8;
|
|
--color-ink-soft: #d8d2c0;
|
|
--color-ink-muted: #9a9380;
|
|
--color-ink-light: #6a6458;
|
|
|
|
--color-rule: #2a3352;
|
|
--color-rule-soft: #1e2a45;
|
|
|
|
--color-surface: #141b2f;
|
|
--color-surface-raised: #1a2238;
|
|
--color-bg: #0a0f1c;
|
|
|
|
--color-success: #5a9a6a;
|
|
--color-success-bg: rgba(90, 154, 106, 0.12);
|
|
--color-warn: #c79956;
|
|
--color-warn-bg: rgba(199, 153, 86, 0.12);
|
|
--color-danger: #c16565;
|
|
--color-danger-bg: rgba(193, 101, 101, 0.12);
|
|
--color-info: #6d8bab;
|
|
--color-info-bg: rgba(109, 139, 171, 0.12);
|
|
|
|
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.25);
|
|
--shadow: 0 2px 6px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.25);
|
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45), 0 2px 4px rgba(0, 0, 0, 0.25);
|
|
--shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
body.dark header {
|
|
background: #060a18;
|
|
border-bottom-color: var(--color-gold);
|
|
}
|
|
|
|
/* ── Base overrides ──────────────────────────────────── */
|
|
|
|
html { font-size: 16px; }
|
|
|
|
body {
|
|
font-family: var(--font-body);
|
|
font-weight: var(--weight-normal);
|
|
font-size: var(--text-base);
|
|
line-height: var(--leading-body);
|
|
color: var(--color-ink);
|
|
background: var(--color-bg);
|
|
direction: rtl;
|
|
text-align: right;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
font-feature-settings: "kern", "liga", "clig", "calt";
|
|
}
|
|
|
|
/* Display typography — serif for headings */
|
|
h1, h2, h3, h4, h5, h6 {
|
|
font-family: var(--font-display);
|
|
font-weight: var(--weight-bold);
|
|
line-height: var(--leading-tight);
|
|
color: var(--color-navy);
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
h1 { font-size: var(--text-3xl); font-weight: var(--weight-display); }
|
|
h2 { font-size: var(--text-2xl); }
|
|
h3 { font-size: var(--text-xl); }
|
|
h4 { font-size: var(--text-lg); }
|
|
h5 { font-size: var(--text-md); }
|
|
h6 { font-size: var(--text-base); }
|
|
|
|
/* Prose paragraphs — justify both sides for Hebrew legal text */
|
|
p,
|
|
.prose {
|
|
text-align: justify;
|
|
text-justify: inter-word;
|
|
hyphens: auto;
|
|
line-height: var(--leading-body);
|
|
}
|
|
|
|
/* Text that should NOT justify (short labels, meta) */
|
|
.no-justify, .meta, .label, .caption,
|
|
th, td, button, input, select, label, nav {
|
|
text-align: right;
|
|
}
|
|
|
|
/* Links */
|
|
a {
|
|
color: var(--color-gold-deep);
|
|
text-decoration: none;
|
|
transition: color var(--t-fast);
|
|
}
|
|
a:hover { color: var(--color-gold); }
|
|
|
|
/* Focus rings — gold, subtle */
|
|
*:focus-visible {
|
|
outline: 2px solid var(--color-gold);
|
|
outline-offset: 2px;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
/* Selection */
|
|
::selection {
|
|
background: var(--color-gold-wash);
|
|
color: var(--color-navy);
|
|
}
|
|
|
|
/* ── Utility classes ─────────────────────────────────── */
|
|
|
|
.text-display { font-family: var(--font-display); }
|
|
.text-body { font-family: var(--font-body); }
|
|
.text-mono { font-family: var(--font-mono); }
|
|
|
|
.text-xs { font-size: var(--text-xs); }
|
|
.text-sm { font-size: var(--text-sm); }
|
|
.text-base { font-size: var(--text-base); }
|
|
.text-md { font-size: var(--text-md); }
|
|
.text-lg { font-size: var(--text-lg); }
|
|
.text-xl { font-size: var(--text-xl); }
|
|
.text-2xl { font-size: var(--text-2xl); }
|
|
.text-3xl { font-size: var(--text-3xl); }
|
|
|
|
.text-muted { color: var(--color-ink-muted); }
|
|
.text-light { color: var(--color-ink-light); }
|
|
.text-gold { color: var(--color-gold-deep); }
|
|
.text-navy { color: var(--color-navy); }
|
|
|
|
.weight-light { font-weight: var(--weight-light); }
|
|
.weight-normal { font-weight: var(--weight-normal); }
|
|
.weight-medium { font-weight: var(--weight-medium); }
|
|
.weight-bold { font-weight: var(--weight-bold); }
|
|
|
|
.justify { text-align: justify; text-justify: inter-word; }
|
|
.start { text-align: right; } /* RTL start */
|
|
.end { text-align: left; } /* RTL end */
|
|
.center { text-align: center; }
|
|
|
|
.ornament {
|
|
display: block;
|
|
text-align: center;
|
|
color: var(--color-gold);
|
|
font-family: var(--font-display);
|
|
letter-spacing: 0.3em;
|
|
margin: var(--space-6) 0;
|
|
}
|
|
.ornament::before { content: "❦"; font-size: 1.3em; }
|
|
|
|
.divider {
|
|
border: 0;
|
|
height: 1px;
|
|
background: linear-gradient(
|
|
to left,
|
|
transparent 0%,
|
|
var(--color-rule) 20%,
|
|
var(--color-rule) 80%,
|
|
transparent 100%
|
|
);
|
|
margin: var(--space-6) 0;
|
|
}
|
|
|
|
.divider-gold {
|
|
border: 0;
|
|
height: 2px;
|
|
background: linear-gradient(
|
|
to left,
|
|
transparent 0%,
|
|
var(--color-gold) 50%,
|
|
transparent 100%
|
|
);
|
|
margin: var(--space-6) 0;
|
|
}
|
|
|
|
/* ── Loading skeleton ───────────────────────────────── */
|
|
.skeleton {
|
|
background: linear-gradient(
|
|
100deg,
|
|
var(--color-cream-deep) 30%,
|
|
var(--color-parchment) 50%,
|
|
var(--color-cream-deep) 70%
|
|
);
|
|
background-size: 200% 100%;
|
|
animation: skeleton-shimmer 1.4s linear infinite;
|
|
border-radius: var(--radius);
|
|
color: transparent;
|
|
user-select: none;
|
|
}
|
|
@keyframes skeleton-shimmer {
|
|
from { background-position: 100% 0; }
|
|
to { background-position: -100% 0; }
|
|
}
|
|
.skeleton-line {
|
|
height: 0.9em;
|
|
margin: 4px 0;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
.skeleton-line.short { width: 40%; }
|
|
.skeleton-line.medium { width: 70%; }
|
|
|
|
/* ── Print — optimized for Dafna printing the portrait ─ */
|
|
@media print {
|
|
:root {
|
|
--color-bg: #fff;
|
|
--color-surface: #fff;
|
|
--color-navy: #000;
|
|
--color-ink: #000;
|
|
--color-ink-muted: #444;
|
|
}
|
|
body { background: #fff; color: #000; font-size: 11pt; }
|
|
header, .status-bar, .process-panel, .toast, .btn, nav,
|
|
#navDiagnostics, .home-sidebar, .home-hero-actions,
|
|
#processPanel, #trainingAnalysisCard, #trainingTasksCard {
|
|
display: none !important;
|
|
}
|
|
.main { max-width: 100% !important; padding: 0 !important; }
|
|
.page { display: none !important; }
|
|
.page.active { display: block !important; }
|
|
.portrait-card, .card {
|
|
box-shadow: none !important;
|
|
border: 1px solid #ccc !important;
|
|
page-break-inside: avoid;
|
|
margin-bottom: 16px !important;
|
|
}
|
|
.portrait-headline {
|
|
background: #fafafa !important;
|
|
border-right: 3px solid #000 !important;
|
|
color: #000 !important;
|
|
}
|
|
h1, h2, h3 { color: #000 !important; page-break-after: avoid; }
|
|
.growth-curve, .donut, .hero-timeline { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
.phrase-filters, .btn, button { display: none !important; }
|
|
/* Force expand all details */
|
|
details { display: block !important; }
|
|
summary::marker, summary::-webkit-details-marker { display: none; }
|
|
}
|
|
|
|
/* ── Responsive (desktop-first, minimal mobile) ────── */
|
|
@media (max-width: 900px) {
|
|
.main { padding: var(--space-5) var(--space-4); }
|
|
header { padding: 14px 20px; flex-wrap: wrap; gap: 10px; }
|
|
header nav { gap: 2px; }
|
|
header nav a { padding: 6px 10px; font-size: 0.82em; }
|
|
.home-hero-title { font-size: 2em; }
|
|
.style-report-header h1 { font-size: 2em; }
|
|
.portrait-card { padding: var(--space-6) var(--space-5); }
|
|
.portrait-hero .hero-body { grid-template-columns: 1fr; }
|
|
.hero-donut-wrap { justify-content: center; }
|
|
.process-panel { width: 280px; }
|
|
}
|