מערכת ערכות הנושא והטוקנים החדשה

summary:

ארכיטקטורת הצבעים, משתני ה-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 ב‑``webapp/templates/base.html``) קבועים לכולם, ומרוכזים בבלוק ה‑<style> שבתוך webapp/templates/base.html, בכלל ה‑:root הגלובלי — זה שפותח ב‑--primary. (יש בקובץ :root שני, בתוך media query של פס הגלילה, שקובע רק את --scrollbar-width; הוא אינו זה.) כאן מגדירים צבעי מותג (–primary, –secondary), צבעי מצב (–success וכו«), טוקני סכנה (–danger-bg, –danger-border, –text-on-warning), ערכי markdown (–md-surface, –md-text), הגדרות כפתור ברירת מחדל וערכי גלאס (–glass*). אין להשתמש ב‑HEX מחוץ לקטע זה.

הערה

המיקום הזה אינו מה שתוכנן. webapp/FEATURE_SUGGESTIONS/css_refactor_plan.md תכנן לרכז את הטוקנים בקובץ ייעודי בשם variables.css, והמימוש הזריק אותם ישירות לתבנית. הקובץ ההוא אינו קיים בריפו, ואין קוד שמנסה לטעון אותו. העמוד הזה מתאר את מה שקיים בפועל.

Level 2 – Semantic Tokens per Theme בלוקים של :root[data-theme="..."] ב‑webapp/templates/base.html קובעים רקעים (–bg-*), טקסט (–text-*), כרטיסים (–card-*), צבעי קוד, כפתורים (–btn-primary-*) וטוקנים ל‑Split View (–split-preview-*). הבלוקים הקיימים שם הם classic, ocean, rose-pine-dawn, dark, dim, nebula ו‑custom. ל‑High Contrast אין בלוק שם — ראו את הסעיף הייעודי למטה. Dark/Dim/Nebula נשענים גם על static/css/dark-mode.css, שמשתמש באותם ערכים גלובליים.

Level 3 – Component Tokens נוצר רק כשיש צורכי עיצוב ייחודיים: –search-card-shadow ב‑global_search.css, –bookmarks-panel-bg ב‑bookmarks.css, משפחת –split-* ב‑split-view.css. את ערכי ברירת המחדל מגדירים ברכיב עצמו, אך מומלץ להוסיף הפניה לטוקן סמנטי מ‑base.html (או ל‑:root[data-theme]) כאשר הרכיב חוצה דפים, כדי למנוע חזרה לצבעים קשיחים.

טעינת המערכת base.html קובע data-theme על <html> מתוך localStorage כבר ב‑<head> כדי למנוע FOUC, והטוקנים עצמם יושבים בבלוק <style> באותה תבנית. כך הם זמינים מיד, עוד לפני טעינת 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 (base.html)"
        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 חובה

--primary / --secondary

Level 1

צבעי מותג, משמשים גם לגרדיאנטים ו‑focus

webapp/templates/base.html — בלוק ה‑<style>: :root + :root[data-theme]

--bg-primary/secondary/tertiary

Level 2

רקעים לגוף, למודלים ולכרטיסים

webapp/templates/base.html בתוך :root[data-theme]; חובה בכל Theme (Ocean מקבל ערכי כחול ייעודיים)

--text-primary/secondary/muted

Level 2

משפחת צבעי טקסט לכל הרכיבים

webapp/templates/base.html (:root[data-theme]) + בדיקת ניגודיות ב‑High Contrast

--card-bg / --card-border

Level 2

כרטיסים, מודלים, dropdowns

webapp/templates/base.html (:root[data-theme]) + שימוש חוזר ב‑static/css/dark-mode.css

--glass / --glass-border / --glass-hover

Level 1

בסיס ל‑Glassmorphism navbar, badges, מודלים

webapp/templates/base.html (קטע :root) + Overrides ב‑תמות בהירות

--scrollbar-width-base / --scrollbar-width

Level 1

רוחב פס גלילה גלובלי לפי מכשיר (מובייל שליש, טאבלט/דסקטופ חצי)

webapp/templates/base.html (בלוק :root + media query)

--btn-primary-bg / --btn-primary-color / --btn-primary-border / --btn-primary-shadow

Level 2

כל כפתור ראשי, כולל מצבי hover (–btn-primary-hover-*)

webapp/templates/base.html (:root[data-theme]) + הרחבה עבור Classic/Ocean/Rose

--danger-bg / --danger-border / --text-on-warning

Level 1

שימשו לטיפול Banner Login, Inline Alerts, Sticky Notes

webapp/templates/base.html (קטע :root בלבד; אין Overrides לכל Theme)

--md-surface / --md-text

Level 1 + Level 2

Split View / Markdown Preview נשאר כהה גם בתמות בהירות

webapp/templates/base.html (ערך כהה ב‑:root + Overrides ספציפיים ב‑Classic/Ocean)

--split-tabs-selected-color / --split-preview-* / --split-error-*

Level 3

רכיב Split View + Live Preview

webapp/static/css/split-view.css (ברירת מחדל + בלוקים לכל Theme)

--search-card-shadow / --search-highlight-*

Level 3

UI החיפוש הגלובלי

webapp/static/css/global_search.css

--glass-badge / --bookmarks-panel-bg / --bookmark-*

Level 3

רכיבי Bookmarks ו‑Glass Badges

bookmarks.css (כבר במצב מלא, שימרו על הפורמט)

--split-preview-placeholder / --split-preview-meta

Level 3

טקסט משני בתצוגת Markdown

split-view.css + קביעת ניגודיות

--code-bg / --code-text / --code-border

Level 2

CodeMirror, כרטיסי קוד, Split View

webapp/templates/base.html (:root[data-theme]) + קבצי Markdown (markdown-enhanced.css)

--collections-link-override

Level 3

שמות הקבצים בכרטיס אוסף ובשולחן העבודה. ברשימה הלבנה, ובכוונה ללא ערך ברירת מחדל — כך ערכה בודדת דורסת אותו לעצמה בלי להשפיע על אחרות

webapp/static/css/collections.css (וו דריסה לערכות מיובאות)

--search-suggestion-text-override

Level 3

הטקסט בהצעות ההשלמה של החיפוש הגלובלי. אותו מבנה בדיוק: ברשימה הלבנה, ובכוונה ללא ערך ברירת מחדל

webapp/static/css/global_search.css (וו דריסה לערכות מיובאות)

רשימת הטוקנים המורחבת זמינה בקובץ webapp/FEATURE_SUGGESTIONS/css_refactor_plan.md ובטבלת הפלטות webapp/FEATURE_SUGGESTIONS/webapp_theme_palettes.md.

מפת ערכות הנושא (Theme Reference)

ערכה

data-theme

בסיס צבע

הערות / טוקנים ייחודיים

Dark

dark

אפור/סגול כהה

משמש כברירת מחדל עם localStorage; חופף ל‑dark-mode.css

Dim

dim

רך יותר מדארק

אותם טוקנים כמו Dark עם ניגודיות נמוכה יותר

Nebula

nebula

כחול‑סגול קוסמי

--glass סגלגל, --btn-primary משתמש ב‑color-mix

Classic

classic

גרדיאנט סגול‑כחול

--btn-primary-* לבן, --md-surface כהה גם בערכת אור

Ocean

ocean

כחול עמוק

כל טוקן רקע/טקסט מוגדר ידנית; Split View מקבל --split-codehilite כחול

Rose Pine Dawn

rose-pine-dawn

ורוד‑שמנת

ערכת אור מלאה עם color-mix לכפתורים ו‑Split View בגווני חמרה

High Contrast

high-contrast

שחור/לבן/צהוב

אין לה בלוק ב‑base.html. הטוקנים מוגדרים ב‑static/css/high-contrast.css ומושלמים ברמת הרכיב בשישה קבצים נוספים — ראו את ההערה מתחת לטבלה. אין גרדיאנטים

סקיצה של ערכת Classic

ערכת Classic מציגה כפתור ראשי לבן, רקע גרדיאנטי וטוקן --md-surface כהה עבור Split View.

סקיצה של ערכת High Contrast

ערכת High Contrast משתמשת רק בשחור, לבן וצהוב לפי WCAG 2.1 AA. כל שינוי חייב לשמור על יחס ניגודיות 4.5:1 לטקסט רגיל.

הערה

High Contrast מתנהגת אחרת מכל שאר הערכות, וזה משפיע ישירות על כל רכיב חדש.

base.html אינו מגדיר לה טוקנים. static/css/high-contrast.css (נטען גלובלית) מגדיר בבלוק :root[data-theme="high-contrast"] שישה טוקנים בלבד — --primary, --secondary, --glass, --glass-border, --md-surface ו‑--md-text — ואת השאר משלימים ברמת הרכיב: bookmarks.css, collections.css, global_search.css, lang-badge.css, markdown-enhanced.css ו‑split-view.css.

המשמעות המעשית: --card-bg, --card-border ו‑--text-primary אינם מוגדרים בערכה הזו. רכיב שנשען עליהם מקבל את ה‑fallback שלו, ובעמוד שאינו טוען אחד מששת הקבצים לעיל התוצאה עלולה להיות בלתי קריאה — למשל כרטיס לבן עם גבול לבן. רכיב חדש שאמור לעבוד ב‑High Contrast צריך בלוק :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 חיוני לכל ערכה — אישית וציבורית כאחת

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 בתוך בלוק ה‑<style> שב‑webapp/templates/base.html. 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 / Login alert / RTL. הגלילה החלקה כבויה כברירת מחדל (ראו Smooth Scrolling (WebApp) — מדריך תמציתי לסוכני AI); לבדיקה נקודתית שלה מוסיפים ?smooth_debug=1 לכתובת.

  • בדיקת Collections, Bookmarks, אוספים משותפים וה‑Glass badges.

  • בדיקת נגישות ב‑High Contrast (יחס ניגודיות 4.5:1, focus outline, קישורים).

  • עוגנים לטסטי דפדפן: אלמנט שטסט צריך לזהות מקבל data-testid שמתאר את המצב שרונדר (למשל agg-time-not-measured), לא את הניסוח. הטסט נתלה בו ולא במחרוזת UI בעברית — שינוי ניסוח לא מפיל טסט, רינדור של הענף הלא נכון כן. data-testid אינו hook ל‑CSS ואין לעצב לפיו. כשלאלמנט כבר יש חוזה סמנטי יציב (href, id, name) — משתמשים בו ולא מוסיפים data-testid. תקדים: webapp/templates/profiler_dashboard.html.

  • בדיקת שאין 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() לפי טבלת הטוקנים.

  • וו דריסה לערכה בודדת (Collections). שם הקובץ בכרטיס אוסף הוא <a>, ולכן dark-mode.css צובע אותו ב-var(--primary) דרך [data-theme="custom"] a — ספציפיות שגוברת על כלל המחלקה שב-collections.css. כרטיס האוסף נשאר לבן גם בערכה כהה, כך שערכה שה---primary שלה בהיר מקבלת שם קובץ בלתי קריא. הפתרון אינו דריסה גורפת אלא וו בהצטרפות מרצון: שני כללים על .collection-card__link ועל .workspace-card__link — שני המסכים שמציגים שמות קבצים — קוראים var(--collections-link-override, <הערך שנצבע היום>) — --primary במצב רגיל, --primary-dark ב-:hover. הטוקן חייב להישאר ללא ערך ברירת מחדל בשום מקום, אחרת ה-fallback לא נכנס לפעולה וכל ערכה מושפעת. זה בדיוק מה שקרה בניסיון הראשון: ברירת מחדל שנקבעה ב-:root[data-theme-type="custom"] שינתה את ה-:hover גם בערכות שלא הצהירו, והורידה אותן מניגודיות 4.81 ל-1.00. ל-:hover נדרש כלל נפרד כי [data-theme="custom"] a:hover ספציפי יותר. ראו דריסת טוקן שאין לו מקבילה ב-VS Code.

  • וו דריסה לערכה בודדת (הצעות החיפוש הגלובלי). אותו שורש, ברכיב אחר: ההצעות מרונדרות ב-global_search.js כאלמנטי <a>, ורקע התיבה הוא --solid-surface-bg שנשאר לבן בכל ערכה — ולכן [data-theme="custom"] a צובע טקסט בצבע המותג של הערכה על רקע שאינו שלה. נמדד בדפדפן על הדף המרונדר: ערכה שה---primary שלה לבן מקבלת ניגודיות 1.00, כלומר טקסט בלתי נראה עד שמעבירים עליו עכבר. הווו נבנה באותה צורה בדיוק — var(--search-suggestion-text-override, <הערך שנצבע היום>) — אבל כאן שלושה כללים ולא שניים, כי ל-:focus-visible יש ערך משלו: .search-suggestion:focus-visible הוא (0,2,0) ומנצח כבר היום את כלל ה-<a> שהוא (0,1,1), ולכן נצבע ב---suggestions-text ולא ב---primary. סדר הכללים אינו שרירותי: :hover ו-:focus-visible שווים בספציפיות (0,3,0), ולכן כלל ה-:hover נכתב אחרון — כך המצב המשולב נשאר --primary-dark, מה שנצבע שם היום. tests/services/test_theme_variables_search_suggestion_hook.py נועל את הסדר הזה. ראו הצעות ההשלמה בחיפוש הגלובלי.

  • Split View ו‑Markdown Enhanced משתמשים ב‑--split-* ו‑--md-* בהתאמה – הוסיפו טוקן לפני שמוסיפים Class חדש.

  • Sticky Notes, Reader Modes (md_preview.html) וה‑theme_preview.html הם חריגים שנשארים Hardcoded כדי לשמור על תצוגת Preset.

  • הכיוון ההפוך, וזה מה שהסעיף הזה לא אמר עד היום: משטח קשיח לא רק נמנע מ-var()— הוא חייב לספק ערך לכל טוקן שכל רכיב שמוצג בתוכו קורא. האיסור למעלה מכסה את מה שהמשטח עצמו מצהיר, ולא את מה שיושב בתוכו. רכיב משותף שמרונדר על משטח קשיח ממשיך לקרוא טוקני ערכה — והם נבחרו לרקע אחר לגמרי, כלומר צבע שגוי בדיוק במידה שהרקע לא השתנה. קובץ CSS משותף אינו מספיק כאן, וההיסק ”זה אותו קוד ולכן זה נראה אותו דבר“ נכון למבנה ולמידות ושגוי לצבע.

    התקדים: sticky-notes.css מצהיר על --sticky-mark-bg/--sticky-mark-line עבור .sticky-md-mark, ועל ששת הטוקנים של הבלוק המתקפל — --details-bg, --details-border, --details-hover, --summary-bg, --summary-color, --summary-arrow-color — שכולם בבעלות markdown-enhanced.css. ההצהרות יושבות על .sticky-note, וההכרעה היא ירושה ולא ספציפיות: הצהרת הערכה יושבת על <html>, ולכן האב הקרוב מנצח בתת-העץ ואין צורך ב-!important. (‏``.sticky-md-mark`` כן צריך אותו, אבל מסיבה אחרת לגמרי — שם קיימים כללי ערכה שמכוונים ל-mark כאלמנט.)

    ומה שנמדד, כי בלי מדידה זה נראה תקין: לפני התיקון יצא הטקסט בגוף הבלוק בניגוד של 1.09:1 בערכה מיובאת כהה, והחץ 2.09:1 גם בערכה בהירה. ‏``–summary-bg`` הוא גרדיאנט, ולכן הוא נוחת ב-background-image ו-background-color נשאר transparent — כלומר בדיקה שמודדת רק background-color עוברת גם על הקוד השבור. צבע על משטח כזה נמדד בדגימת פיקסל.

  • מלכודת ספציפיות ב-transition, שכל רכיב חדש נתקל בה. dark-mode.css מגדיר transition על [data-theme="dark"] * (וכן dim, nebula, custom ו-shared:). הספציפיות של [attr] * שווה לזו של מחלקה יחידה, והקובץ נטען אחרי בלוק extra_css שבתבנית — ולכן כלל transition שנכתב על מחלקה אחת בקובץ רכיב נדרס בשקט בכל הערכות הכהות, וההנפשה פשוט לא רצה. הכשל שקט לחלוטין: אין שגיאה, ובדיקה בערכה בהירה עוברת. הפתרון שבשימוש ב-toast.css הוא חזרה על שם המחלקה (.ck-toast.ck-toast), שמעלה את הספציפיות בלי !important. אותו טיפול נדרש גם לכלל ה-prefers-reduced-motion של הרכיב, שאחרת נדרס באותה דרך.

  • toast.css מגדיר את משפחת --ck-toast-* (Level 3) ונטען כיום רק מ-settings.html. מרחב השמות שלו נפרד מ-.notification בכוונה: bookmarks.css ו-multi-select.css מגדירים את הסלקטור ההוא בשניהם, עם ערכים סותרים. את ערכי הרקע והטקסט הוא מעתיק מ-bookmarks.css במקום לגזור אותם מ---bg-secondary; הגזירה נבדקה ונפסלה כי ב-Classic היא יורדת מתחת ליחס הניגודיות הנדרש.

  • 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/templates/base.html – בלוק ה‑<style>: מקור כל ה‑Primitives ו‑:root[data-theme], קביעת data-theme מוקדמת, וה‑Theme Wizard.

  • webapp/static/css/dark-mode.css – שימוש בטוקנים עבור רכיבי Dark/Dim/Nebula.

  • webapp/static/css/high-contrast.css – טוקני הבסיס של High Contrast, ובנוסף התאמות פוקוס/Outline. שאר הטוקנים שלה מושלמים ברמת הרכיב.

  • webapp/static/css/global_search.css, split-view.css, bookmarks.css, collections.css, toast.css – דוגמאות מעשיות לטוקנים.

  • Issue #2097 – מפרט Theme Builder (טוקנים במיקוד, UI/Backend/API, נגישות ו‑Reset flow).

לשאלות תיעוד/Testing יש לפנות לערוץ Frontend או לפתוח Issue חדש עם קישור לדף זה. הקפידו לעיין גם ב‑FEATURE_SUGGESTIONS/css_refactor_plan.md לפני שינויים רוחביים בקוד.