מערכת ערכות הנושא והטוקנים החדשה
הדף מרכז את כל הידע המעשי על ארכיטקטורת הצבעים, משתני ה‑CSS והבדיקות שנדרשות לשימור חוויית הממשק בכל שמונה הערכות. זהו מקור האמת עבור כל שינוי עתידי ב‑CSS של ה‑WebApp.
רקע ומוטיבציה
בריפקטור האחרון הוסרו צבעים ייחודיים מקבצים כגון
global_search.cssוהופיעו באגים של black/white zebra, איבוד גרדיאנטים ולבן מסנוור ב‑Live Preview.עדכוני Theme נקודתיים בעבר חזרו לצבעים קשיחים (HEX/RGB) ולכן נשברו ב‑Classic/Ocean/Forest שנוספו מאוחר יותר.
מטרת המערכת החדשה: ריכוז כל המשתנים ב‑שלוש שכבות, צמצום FOUC (קביעת
data-themeעוד לפני טעינת ה‑CSS), שימור נגישות וייחודיות, והגדרה ברורה של מה חייב Override בכל Theme.ההנחיות כאן מחליפות קוד קשיח ותלויות מערכת הפעלה (
prefers-color-scheme) ומייצרות תשתית אחת עבור Theme Builder, Split View, Collections, Markdown Viewer ועוד.
שכבות משתנים וטעינת data-theme
Level 1 – Primitives (:root ב‑``variables.css``)
קבועים לכולם ומרוכזים כיום ב‑webapp/static/css/variables.css (הקובץ נטען מתוך base.html בתחילת ה‑<head>). כאן מגדירים צבעי מותג (–primary, –secondary), צבעי מצב (–success וכו«), טוקני סכנה (–danger-bg, –danger-border, –text-on-warning), ערכי markdown (–md-surface, –md-text), הגדרות כפתור ברירת מחדל וערכי גלאס (–glass*). אין להשתמש ב‑HEX מחוץ לקטע זה.
Level 2 – Semantic Tokens per Theme
בלוקים של :root[data-theme="..."] ב‑variables.css קובעים רקעים (–bg-*), טקסט (–text-*), כרטיסים (–card-*), צבעי קוד, כפתורים (–btn-primary-*) וטוקנים ל‑Split View (–split-preview-*). Ocean/Forest/Classic/Dim/Nebula/Rose Pine Dawn/High Contrast משתמשות בכל הטוקנים; Dark/Dim/Nebula גם בעבור קבצי CSS ב־static/css/dark-mode.css שנשענים על אותם ערכים גלובליים.
Level 3 – Component Tokens
נוצר רק כשיש צורכי עיצוב ייחודיים: –search-card-shadow ב‑global_search.css, –bookmarks-panel-bg ב‑bookmarks.css, משפחת –split-* ב‑split-view.css. את ערכי ברירת המחדל מגדירים ברכיב עצמו, אך מומלץ להוסיף הפניה ל‑variables.css (או ל‑:root[data-theme]) כאשר הרכיב חוצה דפים, כדי למנוע חזרה לצבעים קשיחים.
טעינת המערכת
base.html קובע data-theme על <html> מתוך localStorage כבר ב‑<head> כדי למנוע FOUC, ולאחר מכן טוען את webapp/static/css/variables.css וכל שאר קבצי הרכיבים. כך הטוקנים זמינים עוד לפני טעינת dark-mode.css / high-contrast.css / קבצים ייעודיים. Theme Wizard ו‑Theme Builder מזריקים Overrides דינמיים ל‑<style id="user-custom-theme"> (נוצר בעת שמירת Theme מותאם) ומגדירים data-theme=“custom“ או Override ל‑Theme קיים. על כל סקריפט שמשנה Theme לעדכן גם את localStorage באותה צורה.
תרשים זרימת היררכיית טוקנים
graph TD
subgraph "Global Scope (variables.css)"
L1["<b>Level 1: Primitives</b><br/>:root<br/>--primary, --danger, --glass"]
L2["<b>Level 2: Semantic Overrides</b><br/>:root[data-theme='...']<br/>--bg-app, --text-main, --card-bg"]
end
subgraph "Component Scope"
L3_A["<b>Level 3: Global Search</b><br/>--search-highlight-bg"]
L3_B["<b>Level 3: Split View</b><br/>--split-preview-bg"]
L3_C["<b>Level 3: Markdown</b><br/>--md-surface"]
end
L4["<b>User Custom Theme</b><br/>style id='user-custom-theme'<br/>Dynamic User Overrides"]
L1 --> L2
L2 --> L3_A
L2 --> L3_B
L2 --> L3_C
L3_A --> L4
L3_B --> L4
L3_C --> L4
style L1 fill:#f9f9f9,stroke:#333,stroke-width:2px
style L2 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px
style L4 fill:#fff3e0,stroke:#ff9800,stroke-width:2px,stroke-dasharray: 5 5
התרשים ממחיש את שרשרת ההורשה: מתחילים ב‑Primitives, עוברים לטוקנים סמנטיים לפי Theme, ממשיכים לטוקני רכיב ורק לבסוף ל‑Overrides דינמיים עבור Theme מותאם אישית.
טבלת טוקנים עיקריים
הטבלה מציגה את הטוקנים שחובה למלא עבור כל Theme, השכבה האחראית והקובץ שבו מעדכנים.
טוקן |
שכבה |
תיאור |
מיקום / Override חובה |
|---|---|---|---|
|
Level 1 |
צבעי מותג, משמשים גם לגרדיאנטים ו‑focus |
|
|
Level 2 |
רקעים לגוף, למודלים ולכרטיסים |
|
|
Level 2 |
משפחת צבעי טקסט לכל הרכיבים |
|
|
Level 2 |
כרטיסים, מודלים, dropdowns |
|
|
Level 1 |
בסיס ל‑Glassmorphism navbar, badges, מודלים |
|
|
Level 1 |
רוחב פס גלילה גלובלי לפי מכשיר (מובייל שליש, טאבלט/דסקטופ חצי) |
|
|
Level 2 |
כל כפתור ראשי, כולל מצבי hover (–btn-primary-hover-*) |
|
|
Level 1 |
שימשו לטיפול Banner Login, Inline Alerts, Sticky Notes |
|
|
Level 1 + Level 2 |
Split View / Markdown Preview נשאר כהה גם בתמות בהירות |
|
|
Level 3 |
רכיב Split View + Live Preview |
|
|
Level 3 |
UI החיפוש הגלובלי |
|
|
Level 3 |
רכיבי Bookmarks ו‑Glass Badges |
|
|
Level 3 |
טקסט משני בתצוגת Markdown |
|
|
Level 2 |
CodeMirror, כרטיסי קוד, Split View |
|
רשימת הטוקנים המורחבת זמינה בקובץ webapp/FEATURE_SUGGESTIONS/css_refactor_plan.md ובטבלת הפלטות webapp/FEATURE_SUGGESTIONS/webapp_theme_palettes.md.
מפת ערכות הנושא (Theme Reference)
ערכה |
|
בסיס צבע |
הערות / טוקנים ייחודיים |
|---|---|---|---|
Dark |
|
אפור/סגול כהה |
משמש כברירת מחדל עם |
Dim |
|
רך יותר מדארק |
אותם טוקנים כמו Dark עם ניגודיות נמוכה יותר |
Nebula |
|
כחול‑סגול קוסמי |
|
Classic |
|
גרדיאנט סגול‑כחול |
|
Ocean |
|
כחול עמוק |
כל טוקן רקע/טקסט מוגדר ידנית; Split View מקבל |
Rose Pine Dawn |
|
ורוד‑שמנת |
ערכת אור מלאה עם |
High Contrast |
|
שחור/לבן/צהוב |
Overrides מלאים ב‑ |
ערכת Classic מציגה כפתור ראשי לבן, רקע גרדיאנטי וטוקן --md-surface כהה עבור Split View.
ערכת High Contrast משתמשת רק בשחור, לבן וצהוב לפי WCAG 2.1 AA. כל שינוי חייב לשמור על יחס ניגודיות 4.5:1 לטקסט רגיל.
הערה
static/css/high-contrast.css נשאר בקוד כ‑Legacy עבור התאמות Focus/Outline בלבד. כל הטוקנים עצמם חיים ב‑webapp/static/css/variables.css וממומשים דרך :root[data-theme="high-contrast"].
Markdown Viewer ו‑Split View
גם כאשר הערכה בהירה (Classic / Rose Pine Dawn) המקדימה והעורך נשארים כהים עם
--md-surfaceו‑--md-text. לכן אסור לרוקן את הערכים הללו ב‑:root.כפתור ”רקע לבן“ ב‑
md_preview.htmlפשוט מסיר מחלקותbg-sepia/light/medium/dark. השתמשו בטוקנים כשהדבר מתאפשר, אך שמרו על Presets לפי COLORS בסקריפט – אלו חריגים שהוגדרו בכוונה.Live Preview (split-view.css) משתמש ב‑
--split-preview-*. הוספת preset חדש (למשלbg-sepia) מחייבת: 1. הוספת המחלקה בקובץ התבנית. 2. יצירת טוקן חדש ברמת Level 3 (--split-sepia-bg) אם נדרש. 3. בדיקות ניגודיות ב‑High Contrast.theme_preview.htmlו‑Reader modes ב‑md_preview.htmlנשארים Hardcoded לצורכי תצוגת פלטות – אין להמיר אותם ל‑var() כדי לשמור על נאמנות ל‑brand colors.
הנחיות למפתחים (Best Practices)
❌ אין לציין HEX בקבצי רכיבים (למעט חריגים מתועדים). ✅ תמיד להשתמש ב‑
var(--token-name)ולוודא שהטוקן עלה לטבלת הרפרנס.כשצריך פס גלילה צר ברכיב מקומי: - הגדירו
::-webkit-scrollbarעםwidth/heightעל בסיסvar(--scrollbar-width). - הוסיפוscrollbar-width: thinכדי לכסות גם Firefox.כלל אצבע: - צריך צבע שחוזר בכמה קומפוננטות → טוקן סמנטי (Level 2). - צריך גוון שמזוהה עם רכיב מסוים (צלחמת חיפוש, טאב מסוים) → טוקן רכיב (Level 3) + Overrides.
Inline styles ב‑HTML/JS: צרו מחלקה ב‑CSS שמפנה ל‑
var(). אם חייבים Inject דינמי (למשל Sticky Notes) – חשבו צבעים דרך טוקנים קיימים (–text-on-primary, –danger-bg).color-mix() (אופציונלי): עדיף על שקיפות ידנית כאשר צריך לשלב צבעים קיימים.
[data-theme="..."]הוא הסלקטור היחיד לשינוי Theme. אין להשתמש שוב ב‑prefers-color-schemeמלבד בקוד Legacy שכבר קיים ב‑markdown-enhanced.css(TODO לעדכן).
חשוב
Whitelist חיוני לפרסום ערכות ציבוריות (Shared Themes)
בעת פרסום ערכה אישית לציבורית, רק משתנים שנמצאים ב-ALLOWED_VARIABLES_WHITELIST
(ב-services/theme_parser_service.py) יישמרו. משתנים אחרים מסוננים מטעמי אבטחה.
אם מוסיפים טוקן חדש שצריך להישמר בערכות ציבוריות, יש לעדכן גם את ה-whitelist.
דוגמת קוד – לא תקין לעומת תקין
/* ❌ לא תקין – צבעים קשיחים */
.global-search-card {
background: #ffffff;
color: #1c1c1c;
box-shadow: 0 30px 60px rgba(7, 7, 31, 0.35);
}
/* ✅ תקין – מסתמך על טוקנים */
.global-search-card {
background: var(--card-bg);
color: var(--text-primary);
box-shadow: var(--search-card-shadow, 0 20px 40px rgba(0,0,0,0.25));
}
Component Tokens ו‑Theme Builder
הערה
המפרט הרשמי של Theme Builder מתועד ב‑Issue #2097 ובמדריכים שבתיקיית GUIDES/.
חלק ב« מוסיף תמיכה בריבוי ערכות (Multi-Theme) למשתמש מחובר.
מטרות ה‑Builder: - בונה ערכה ב‑
/settings/theme-builderעם Live Preview מבודד שמצרוךvar(--token)בלבד ולא משפיע על שאר ה‑UI עד לשמירה. - מעבר ממבנה ערכה אחת ל‑מערך ערכות:users.custom_themes(עד 10 ערכות למשתמש). - רק ערכה אחת יכולה להיות פעילה בכל רגע (is_active=True). - הזרקה אוטומטית של הערכה הפעילה דרך<style id="user-custom-theme">ב‑base.htmlכאשרdata-theme="custom". - תאימות לאחור: פונקצייתget_custom_themeבודקת קודםcustom_themes(מבנה חדש), ואז fallback ל‑custom_theme(מבנה ישן).API (Multi-Theme): -
GET /api/themes– רשימת הערכות של המשתמש ללאvariablesכבדים -POST /api/themes– יצירת ערכה חדשה (כולל מגבלת 10) -GET /api/themes/<id>– פרטי ערכה כוללvariablesלעריכה -PUT /api/themes/<id>– עדכון ערכה -POST /api/themes/<id>/activate– הפעלת ערכה (מכבה את השאר + מעדכןui_prefs.theme="custom") -POST /api/themes/deactivate– ביטול כל הערכות וחזרה ל‑Classic -DELETE /api/themes/<id>– מחיקת ערכה (אם הייתה פעילה: חוזרים ל‑Classic)UI: - Sidebar ”הערכות שלי“ עם רשימה, אינדיקציה לערכה פעילה/נבחרת, וכפתור ”ערכה חדשה“.
כאשר מוסיפים טוקן חדש: 1. הוסיפו ערך ברירת מחדל ל‑
:rootבתוךwebapp/static/css/variables.css. 2. הוסיפו Overrides בבלוקים של כל Theme שדורש התאמה. 3. אם הטוקן שייך לרכיב ספציפי, הגדירו אותו גם בקובץ הרכיב (למשלsplit-view.css) כדי לא לאבד הקשר.Theme Builder (או Override ידני) נעשה באמצעות
<style id="user-custom-theme">שמוזרק בסוף ה‑<head>. כך ניתן לאפשר Overrides בטוחים:<style id="user-custom-theme"> :root[data-theme="custom"] { --primary: #ff6f61; --bg-primary: #0f1117; --text-primary: #f5f5f5; --btn-primary-bg: rgba(255,255,255,0.92); } </style>
כאשר מבצעים Override לתמה קיימת (בידיים היום או דרך Theme Builder בעתיד), כתבו את הטוקנים בתוך
:root[data-theme="ocean"]באותו <style> כך שהערכים הדינמיים יגברו על ברירת המחדל.טוקנים חובה ל‑Theme מותאם אישית (גם בעתיד כשה‑Builder יהיה פעיל): –primary, –secondary, –bg-primary, –bg-secondary, –text-primary, –text-secondary, –btn-primary-bg, –btn-primary-color, –glass, –md-surface, –md-text.
בדיקות חובה לפני Merge
מעבר ידני על כל 8 הערכות דרך Theme Wizard + בדיקה מהירה של localStorage.
בדיקת Split View + Markdown Preview (כולל לחצן ”רקע לבן“, מצבי Reader).
בדיקת Live Preview / Sticky Notes / Smooth Scroll Debug / Login alert / RTL.
בדיקת Collections, Bookmarks, אוספים משותפים וה‑Glass badges.
בדיקת נגישות ב‑High Contrast (יחס ניגודיות 4.5:1, focus outline, קישורים).
בדיקת שאין HEX קשיחים בקבצים שנגעתם בהם (rg ”#[0-9a-fA-F]{3,6}“ webapp/static/css/<file>.css).
בדיקת WCAG ל‑Markdown Viewer (
bg-sepiaועוד) + ווידוא ש‑–md-surface לא הוחלף בטעות.מעבר בין Themes בזמן Live Preview כדי לוודא שאין FOUC (שימרו על setAttribute מוקדם).
שימושים נוספים וחריגים
אזהרה
⚠️ שים לב: Sticky Notes, Reader Modes (md_preview.html) והקובץ theme_preview.html נשארים Hardcoded בכוונה לצורכי Preset/Brand. אין להמיר אותם ל‑var() עד שתתועד חלופה רשמית, אחרת נשבור תצוגות קיימות.
Collections (webapp/static/css/collections.css) עדיין מכיל צבעים קשיחים ישנים – כל שינוי חייב להמיר ל‑var() לפי טבלת הטוקנים.
Split View ו‑Markdown Enhanced משתמשים ב‑
--split-*ו‑--md-*בהתאמה – הוסיפו טוקן לפני שמוסיפים Class חדש.Sticky Notes, Reader Modes (md_preview.html) וה‑
theme_preview.htmlהם חריגים שנשארים Hardcoded כדי לשמור על תצוגת Preset.global_search.css הינו דוגמה מצוינת לרכיב Component Tokens – כאשר מוסיפים תכונה חדשה (למשל badge נוסף) המשיכו את התבנית שם.
Collections / Split View / Markdown Enhanced מוזכרים בדף זה כדי שמפתחים ידעו להצליב בין הרכיבים ולזהות אילו טוקנים משותפים.
קישורים ונספחים
ראה גם
webapp/FEATURE_SUGGESTIONS/css_refactor_plan.md– רשימות טוקנים מלאות לפי קובץ.FEATURE_SUGGESTIONS/css_refactor_plan.md– תקציר עסקי ובדיקות QA.FEATURE_SUGGESTIONS/theme_matrix.md– טבלת כיסוי טוקנים מקוצרת.webapp/FEATURE_SUGGESTIONS/webapp_theme_palettes.md– פירוט צבעים וערכי Markdown.webapp/static/css/variables.css– מקור כל ה‑Primitives ו‑:root[data-theme]לפני קבצי הרכיבים.webapp/templates/base.html– טעינתvariables.css, קביעתdata-themeמוקדמת וה‑Theme Wizard.webapp/static/css/dark-mode.css– שימוש בטוקנים עבור רכיבי Dark/Dim/Nebula.webapp/static/css/high-contrast.css– Legacy לפוקוס/Outline; הדריסות עצמן ב‑variables.css.webapp/static/css/global_search.css,split-view.css,bookmarks.css,collections.css– דוגמאות מעשיות לטוקנים.Issue #2097 – מפרט Theme Builder (טוקנים במיקוד, UI/Backend/API, נגישות ו‑Reset flow).
לשאלות תיעוד/Testing יש לפנות לערוץ Frontend או לפתוח Issue חדש עם קישור לדף זה. הקפידו לעיין גם ב‑FEATURE_SUGGESTIONS/css_refactor_plan.md לפני שינויים רוחביים בקוד.