diff --git a/skills/dafna-decision-template/SKILL.md b/skills/dafna-decision-template/SKILL.md
new file mode 100644
index 0000000..02faa21
--- /dev/null
+++ b/skills/dafna-decision-template/SKILL.md
@@ -0,0 +1,292 @@
+---
+name: dafna-decision-template
+description: >
+ ייצוא מסמכי DOCX עבור ועדת ערר לתכנון ובניה מחוז ירושלים (יו"ר עו"ד דפנה תמיר),
+ באמצעות שימוש בסגנונות המוגדרים בטמפלט Word של דפנה (`טיוטת החלטה.dotx`).
+ הסקיל מחיל את סגנונות הטמפלט (Normal/Heading 1/Heading 2/Quote/List Paragraph)
+ על תוכן שנכתב מתוכנתית — בלי להגדיר פונט/גודל/RTL/שוליים ידנית.
+
+ טריגרים: "ייצוא החלטה", "ייצוא ניתוח משפטי", "DOCX של דפנה",
+ "טמפלט החלטה", "סגנונות החלטה", "Word עם David", "מסמך ועדת ערר",
+ "הורדת החלטה", "פסקה ממוספרת בעברית", "(א) (ב) (ג)",
+ כל בקשה להוציא מסמך Word המבוסס על טמפלט דפנה.
+---
+
+# Dafna Decision Template — ייצוא DOCX מסגנונות טמפלט
+
+## מה זה עושה
+
+סקיל זה הוא **layer דק מעל `python-docx`** שמטעין את הטמפלט של דפנה
+([skills/docx/decision_template.docx](../docx/decision_template.docx) —
+מומר מ-`data/training/טיוטת החלטה.dotx`) וכותב תוכן חדש על בסיסו, **על ידי
+שיוך שמות סגנונות בלבד** (`paragraph.style = "Heading 2"`). העיצוב —
+פונט David, RTL, גדלים, הזחות, מספור אוטומטי — מגיע מה-`styles.xml`
+של הטמפלט.
+
+השירות המעשי נמצא ב-
+[`mcp-server/src/legal_mcp/services/analysis_docx_exporter.py`](../../mcp-server/src/legal_mcp/services/analysis_docx_exporter.py).
+הסקיל מתעד את **הכללים** שה-service מיישם, כך שניתן לשחזר/להרחיב אותם
+בסקריפטים אחרים ללא צורך לגלות הכל מחדש.
+
+---
+
+## 🔴 קריטי — 5 עקרונות שחייבים לזכור
+
+### 1. **לא להגדיר font/size/indent ידנית** — תמיד style
+```python
+# ❌ אל
+run.font.name = "David"; run.font.size = Pt(13)
+paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT
+
+# ✅ כן
+paragraph = doc.add_paragraph(style="Normal") # כל השאר מגיע מהטמפלט
+```
+
+### 2. **RTL חייב דגלים ב-paragraph וב-run — גם אם הסגנון כולל bidi**
+```python
+# ❌ אל — עברית תצא ב-Times New Roman כי Word לא יודע שזה complex-script
+p = doc.add_paragraph(style="Normal")
+p.add_run("טקסט בעברית")
+
+# ✅ כן — מסמנים את ה-run כ-RTL
+p = doc.add_paragraph(style="Normal")
+_mark_paragraph_rtl(p)
+run = p.add_run("טקסט בעברית")
+_mark_run_rtl(run) # ← מוסיף ל-rPr
+```
+בלי הדגל הזה, Word נופל בחזרה ל-`ascii` font (Times New Roman) במקום
+ל-`cs` font (David). זו הסיבה הנפוצה ביותר לתוצאה "עברית ב-Times New Roman".
+
+ראה [references/rtl-runs.md](references/rtl-runs.md) לפרטים מלאים.
+
+### 3. **`.dotx` לא נטען ישירות** — יש להמיר ל-`.docx` פעם אחת
+python-docx פותח רק `.docx`. להמרה: `scripts/convert_decision_template.py`
+(בשורש הפרויקט). יש להסיר:
+- `word/glossary/*` parts
+- Override entries שמצביעים אליהם ב-`[Content_Types].xml`
+- Relationship `glossaryDocument` ב-`word/_rels/document.xml.rels`
+- להחליף content-type מ-`...template.main+xml` ל-`...document.main+xml`
+
+ראה [references/dotx-to-docx.md](references/dotx-to-docx.md).
+
+### 4. **Title לא טוב ככותרת עברית** — השתמש ב-Heading 1
+הסגנון `Title` בטמפלט מפנה ל-theme fonts (`majorFont`). ב-theme1.xml:
+`majorFont.latin = "Aptos Display"`, `majorFont.cs = ""` (ריק).
+לכן עברית תרונדר ב-Latin fallback.
+
+`Heading 1` יורש cs="David" מ-`Normal` — השתמש בו לכותרת ראשית.
+
+### 5. **מספור אוטומטי רק ב-`List Paragraph`** — decimal בלבד
+`List Paragraph` (styleId `a0`) מקושר ל-`numId=1 → numFmt=decimal`.
+כלומר Word יוסיף אוטומטית "1.", "2.", "3." לכל פסקה עם הסגנון הזה.
+
+- שורות שמתחילות ב-`N.` → הסר את המספר מהטקסט, החל `List Paragraph`.
+- שורות שמתחילות ב-`(א)` `(ב)` → השתמש ב-`List Paragraph` **עם הסרת ``**,
+ כי המספור בעברית נכתב בעצמו על ידי המחבר.
+- Bullets (`- `, `• `) → הסר את הסימן, השאר `Normal`.
+
+ראה [references/style-mapping.md](references/style-mapping.md).
+
+---
+
+## הטמפלט — מיפוי סגנונות
+
+מיפוי מלא של הסגנונות בטמפלט ל-content type. זה ה"חוזה" של הסקיל —
+כל שינוי דרך השירות צריך להיצמד אליו.
+
+| תוכן | style name | הערה |
+|------|-----------|------|
+| כותרת מסמך ("ניתוח משפטי וכתיבת עמדה בערר X") | `Heading 1` | יורש cs="David" |
+| כותרת מקטע ראשי (רקע דיוני, פסיקה כללית, סוגיות להכרעה, מסקנות) | `Heading 2` | bold + underline |
+| כותרת משנה בתוך סוגיה (טענה (claim), תשובה, ניתוח, נקודות פתוחות, …) | `Heading 2` | |
+| שם subsection (טענת סף 1, סוגיה 2) | `Normal` + bold run | |
+| פסקת רקע רגילה | `Normal` | David 13pt, justify, RTL |
+| פסקת רשימה ממוספרת (1., 2., 3.) | `List Paragraph` | Word ימספר |
+| פסקת רשימה בעברית ((א), (ב)) | `List Paragraph` + `_strip_numpr()` | המספור נשאר בטקסט |
+| ציטוט פסיקה | `Quote` | bold + הזחה |
+| citation / מקור | `Normal` + italic | |
+
+ראה [references/style-mapping.md](references/style-mapping.md) לטבלה
+מורחבת עם ה-XML של כל סגנון.
+
+---
+
+## תוכן המקור — `analysis-and-research.md`
+
+הקובץ נכתב על ידי `legal-analyst` agent. מבנה מצופה:
+
+```markdown
+# ניתוח משפטי וכתיבת עמדה — ערר {case_number}
+תאריך: DD.MM.YYYY
+
+## רקע דיוני
+{prose content}
+
+## עובדות מוסכמות
+1. ...
+
+## עובדות שנויות במחלוקת
+1. ...
+
+## טענות סף
+### טענה {n}: {title}
+**עמדת המבקשת:** ...
+**עמדת ועדת הערר:** [ימולא ע"י יו"ר הוועדה]
+
+## סוגיות להכרעה
+### סוגיה {n}: {title}
+**ממצאים עובדתיים:**
+...
+**טענה (claim):**
+העורר טוען כי:
+(א) ...
+(ב) ...
+**ניתוח:**
+...
+- **נקודות פתוחות:**
+ 1. ...
+- **הערכה ראשונית:** {prose}
+**עמדת ועדת הערר:** [ימולא ע"י יו"ר הוועדה]
+
+## מסקנות
+...
+```
+
+ה-parser (`research_md.py`) חולק את זה ל-`threshold_claims[]`, `issues[]`,
+prose sections, ו-`conclusions`. חשוב: **שמות sections חייבים להכיל את
+המילים המופתח** (`רקע דיוני`, `טענות סף`, …) — ה-parser עובד לפי matching של
+keywords, לא לפי מספר ה-H2.
+
+---
+
+## זרימת הייצוא
+
+סדר המקטעים ב-DOCX (גם אם סדר ה-H2 ב-MD שונה):
+
+1. **כותרת** (Heading 1) + שורת תאריך
+2. **רקע** (Heading 2) — `represented_party`, `procedural_background`,
+ `agreed_facts`, `disputed_facts` (אם קיימים)
+3. **פסיקה כללית** (Heading 2) — `case_precedents` עם `section_id=NULL`
+4. **טענות סף** (Heading 2) — לכל subsection: title, fields, chair_position, precedents
+5. **סוגיות להכרעה** (Heading 2) — אותה חלוקה
+6. **מסקנות** (Heading 2) — בסוף
+
+הסיבה: בקריאה משפטית נכון להציג תחילה רקע ועובדות, ואז את הדיון. פסיקה
+כללית מופיעה לפני הסוגיות כי היא רוחבית.
+
+---
+
+## עיבוד שורות — `_classify_line()`
+
+ה-service מפרש כל שורה של content לאחת מ-6 קטגוריות:
+
+| kind | דוגמה | מה קורה |
+|------|--------|---------|
+| `label_heading` | `**נקודות פתוחות:**` (שורה שלמה, כולל `- **X:**`) | Heading 2 |
+| `label_heading` (plain) | `העורר טוען כי:` (שורה קצרה שמסתיימת ב-`:`) | Heading 2 |
+| `inline_label` | `**שאלה עקרונית:** מה...` | Normal עם label bold inline |
+| `numbered` | `1. הנספח אינו מחייב` | List Paragraph, המספר מוסר |
+| `bullet` | `- nevo (קלאסי)...` | Normal, הסימן מוסר |
+| `heb_letter` | `(א) הנספח אינו...` | List Paragraph + strip numPr |
+| `plain` | רגיל | Normal |
+
+בנוסף, **inline `**...**`** מעובד בכל ריצה דרך `_add_runs_with_inline_bold`
+— כל `**word**` הופך ל-run נפרד עם `bold=True`.
+
+ראה [references/line-classification.md](references/line-classification.md).
+
+---
+
+## מקפים — מדיניות
+
+המשתמש (דפנה) ביקשה: **"לא רוצה מקפים בכלל"**. הסקיל מסיר:
+
+- `—` (em-dash, U+2014)
+- `–` (en-dash, U+2013)
+
+מכל טקסט שהקוד כותב למסמך (גם תוכן מהמקור). מקפים רגילים (`-`)
+נשמרים. הפונקציה: `_no_dash()`.
+
+---
+
+## שדות ריקים — placeholder
+
+שדה `chair_position` (עמדת ועדת הערר) שמכיל אחד מהסימנים הריקים
+(`[ימולא ע"י יו"ר הוועדה]`, `[טרם מולא]`, וכד') → מוחלף ב-
+`[טרם מולאה עמדת ועדת הערר]` בסגנון italic. זה סימן ויזואלי ברור
+שנשאר עדיין להשלים.
+
+---
+
+## שימוש — API
+
+```python
+from legal_mcp.services.analysis_docx_exporter import build_analysis_docx
+
+path = await build_analysis_docx("8070-25")
+# → data/cases/8070-25/exports/ניתוח-משפטי-v{N}.docx
+```
+
+Endpoint ציבורי: `GET /api/cases/{case_number}/research/analysis/export-docx`
+
+---
+
+## התמודדות עם בעיות נפוצות
+
+### "עברית יוצאת ב-Times New Roman"
+- חסר `` ב-run. הוסף `_mark_run_rtl(run)` אחרי כל `add_run`.
+- בדוק: הסגנון שאתה משתמש בו יש בו `cs="David"` (או יורש מ-Normal שיש לו)?
+
+### "המספור כפול: '1. (א) ...'"
+- אתה משתמש ב-`List Paragraph` על שורה עם `(א)`. צריך `_strip_numpr(para)`.
+
+### "כוכביות `**...**` מופיעות במסמך"
+- הקפד להעביר תוכן דרך `_add_runs_with_inline_bold()`, לא `paragraph.add_run()`.
+
+### "התבנית לא נטענת"
+- הרץ מחדש `python scripts/convert_decision_template.py`. בדוק שה-docx
+ שנוצר פותחיb ב-Word ללא שגיאות.
+
+### "המספור ברשימה השנייה ממשיך מהראשונה (4,5,6 במקום 1,2,3)"
+- ידוע. הפתרון: להוסיף override של `numId` ברמת ה-paragraph הראשון של
+ הרשימה החדשה. עדיין לא מיושם — ראה "שיפורים עתידיים".
+
+---
+
+## שיפורים עתידיים (TODO)
+
+- [ ] Reset של מספור List Paragraph בין רשימות נפרדות (לא רציף).
+- [ ] תמיכה ב-`פיסקת רשימה - ללא מספור` (styleId `-`) לbullets.
+- [ ] עיצוב מותאם לסוג הערר (1xxx/8xxx/9xxx) — כרגע אחיד.
+- [ ] אפשרות להוריד רק מקטעים נבחרים (רק טענות סף, רק מסקנות, וכו').
+
+---
+
+## מבנה קבצים
+
+```
+skills/dafna-decision-template/
+├── SKILL.md ← הקובץ הזה
+└── references/
+ ├── dotx-to-docx.md ← איך ממירים .dotx ל-.docx
+ ├── rtl-runs.md ← למה `` חשוב בכל run
+ ├── style-mapping.md ← מיפוי מלא של סגנונות הטמפלט
+ └── line-classification.md ← לוגיקת _classify_line()
+
+mcp-server/src/legal_mcp/services/
+└── analysis_docx_exporter.py ← המימוש המעשי
+
+scripts/
+└── convert_decision_template.py ← המרת dotx → docx (חד-פעמי)
+
+skills/docx/
+└── decision_template.docx ← הטמפלט המומר (artifact)
+```
+
+---
+
+## היסטוריה
+
+| גרסה | תאריך | שינוי |
+|-------|-------|-------|
+| v1.0 | 2026-04-16 | יצירת הסקיל. מיפוי ראשוני של סגנונות, תמיכה ב-RTL runs, inline bold, (א)(ב), Heading 1/2, מקטעי רקע. |
diff --git a/skills/dafna-decision-template/references/dotx-to-docx.md b/skills/dafna-decision-template/references/dotx-to-docx.md
new file mode 100644
index 0000000..998bc06
--- /dev/null
+++ b/skills/dafna-decision-template/references/dotx-to-docx.md
@@ -0,0 +1,58 @@
+# המרת `.dotx` → `.docx` עבור python-docx
+
+## למה
+
+python-docx **לא יודע לפתוח** קובצי Word Template (`.dotx`). ניסיון לפתיחה
+זורק:
+```
+ValueError: file 'X.dotx' is not a Word file, content type is
+'application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml'
+```
+
+כי `main document part` של `.dotx` מסומן כ-template, לא כ-document.
+
+## הפתרון — המרה חד-פעמית
+
+קובץ `.dotx` הוא ZIP שכולל את אותם parts כמו `.docx` + `word/glossary/`
+(building blocks). להמרה:
+
+1. פתח את ה-ZIP.
+2. **הסר** את כל ה-parts תחת `word/glossary/`.
+3. **תקן** `[Content_Types].xml`:
+ - החלף `template.main+xml` ב-`document.main+xml`
+ - הסר `` entries שמצביעים ל-`/word/glossary/...`
+4. **תקן** `word/_rels/document.xml.rels`:
+ - הסר את ה-`` עם
+ `Type=".../relationships/glossaryDocument"`
+5. שמור מחדש כ-ZIP עם סיומת `.docx`.
+
+## הסקריפט
+
+[`scripts/convert_decision_template.py`](../../../scripts/convert_decision_template.py)
+(בשורש הפרויקט) עושה את זה. הרץ אותו:
+
+- פעם אחת אחרי clone של הפרויקט (אם `skills/docx/decision_template.docx`
+ לא קיים).
+- בכל פעם שדפנה מעדכנת את `data/training/טיוטת החלטה.dotx`.
+
+```bash
+python scripts/convert_decision_template.py
+# → skills/docx/decision_template.docx
+```
+
+הסקריפט כולל verification שבודק שהקובץ שנוצר נטען נקי ב-python-docx
+ושהסגנונות הקריטיים (Normal, Heading 2, Quote, List Paragraph, Title)
+נמצאים בו.
+
+## למה לא `docxtpl`?
+
+`docxtpl` מיועד ל-**placeholder substitution** סגנון Jinja2
+(`{{ variable }}`). הטמפלט שלנו לא מכיל placeholders — אנחנו מרכיבים
+תוכן דינמי. `python-docx` על טמפלט `.docx` נקי מספיק לגמרי.
+
+## הימנע מ-
+
+- **אל תנסה** להוריד את ה-glossary רק מ-`[Content_Types].xml` בלי להסיר
+ את ה-`` שמפנה אליו → תקבל dangling reference.
+- **אל תנסה** להשתמש ב-`.dotx` ישירות דרך `zipfile` + לבנות Document
+ ידנית — חוסך 10 שורות אבל מאבד את כל ה-robustness של python-docx.
diff --git a/skills/dafna-decision-template/references/line-classification.md b/skills/dafna-decision-template/references/line-classification.md
new file mode 100644
index 0000000..6aa04e9
--- /dev/null
+++ b/skills/dafna-decision-template/references/line-classification.md
@@ -0,0 +1,115 @@
+# סיווג שורות — `_classify_line()`
+
+כל שורה של content מה-MD עוברת דרך `_classify_line()` שמחזירה
+`(kind, clean_text)`. הקטגוריה מכתיבה איזה סגנון Word יוחל.
+
+## טבלת הקטגוריות
+
+| kind | regex | clean_text | נמפה ל-style |
+|------|--------|-----------|--------------|
+| `label_heading` | `^\s*\*\*([^\n*]+?):\*\*\s*$` | `"$1"` | `Heading 2` |
+| `label_heading` (plain) | `^\s*([^\n:]{2,40}):\s*$` | `"$1"` | `Heading 2` |
+| `inline_label` | `^\s*\*\*([^\n*]+?):\*\*\s+(.+)$` | `"$1\x00$2"` | `Normal` + bold label + value |
+| `numbered` | `^\s*(\d+)[.)]\s+(.+)$` | `"$2"` | `List Paragraph` |
+| `bullet` | `^\s*[\-\u2022\*\u25CF\u25E6]\s+(.+)$` | `"$1"` | `Normal` (marker stripped) |
+| `heb_letter` | `^\s*\([א-ת]\)\s+` | **full line** (marker kept) | `List Paragraph` + `_strip_numpr()` |
+| `plain` | fallback | line | `Normal` |
+
+## סדר הבדיקות (חשוב!)
+
+```
+1. STANDALONE_LABEL_RE (**X:**)
+2. INLINE_LABEL_RE (**X:** value)
+3. NUMBERED_LINE_RE (1. X)
+4. BULLET_LINE_RE (- X) + re-check inside:
+ 4a. STANDALONE inside → label_heading
+ 4b. INLINE inside → inline_label
+5. HEB_LETTER_LINE_RE ((א) X)
+6. PLAIN_LABEL_RE (X:) — last because it's broad
+7. plain
+```
+
+## דוגמאות מהשטח
+
+### input: `- **נקודות פתוחות:**`
+- `BULLET_LINE_RE` תופס → `inner = "**נקודות פתוחות:**"`
+- `STANDALONE_LABEL_RE` על ה-inner → `label_heading`, text = `"נקודות פתוחות"`
+- יוצא כ-Heading 2.
+
+### input: `- **נקודות פתוחות:** האם המקדם...`
+- `BULLET_LINE_RE` תופס → inner = `"**נקודות פתוחות:** האם..."`
+- `INLINE_LABEL_RE` על ה-inner → `inline_label`
+- יוצא כ-Normal עם label "נקודות פתוחות:" bold + value רגיל.
+
+### input: `1. **שאלה עקרונית:** האם נספח...`
+- `NUMBERED_LINE_RE` תופס → `"**שאלה עקרונית:** האם נספח..."`
+- יוצא כ-List Paragraph. ה-`**...**` בתוכו יעובד על ידי
+ `_add_runs_with_inline_bold()` (bold inline run).
+
+### input: `(א) נספח הבינוי של תכנית...`
+- `HEB_LETTER_LINE_RE` תופס
+- יוצא כ-List Paragraph עם `_strip_numpr()` — כי המחבר כבר כתב "(א)".
+
+### input: `העורר טוען כי:`
+- לא תואם regex ספציפי
+- `PLAIN_LABEL_RE` תופס (23 תווים, מסתיים ב-`:`)
+- יוצא כ-Heading 2.
+
+### input: `פסקה ארוכה: עם עוד תוכן ופסיק, וסוגיה מורכבת.`
+- `PLAIN_LABEL_RE` לא תופס (יותר מ-40 תווים לפני `:`)
+- נשאר `plain` → Normal.
+
+## למה הגבלת `PLAIN_LABEL_RE` ל-`{2,40}`
+
+בלי הגבלה, כל פסקה עם `:` במקום כלשהו הייתה הופכת ל-Heading 2. דוגמה
+שצריך למנוע:
+```
+טענה חשובה כאן: היא שהוועדה שגתה בכל אופן.
+```
+אין כאן כוונה לכותרת — `:` הוא חלק ממשפט. ההגבלה ל-40 תווים מסננת את
+רוב המקרים האלה כי רוב headings אמיתיים הם קצרים.
+
+40 תווים זה ניחוש — אפשר לכוון אם מגלים false positives/negatives.
+
+## inline bold — `_add_runs_with_inline_bold()`
+
+אחרי סיווג, הטקסט עדיין יכול להכיל `**word**` באמצע. הפונקציה מחלקת
+את המחרוזת ל-runs מתחלפים:
+
+```
+"העורר טוען **שהתוצאה** שגויה"
+→ [
+ Run("העורר טוען ", bold=None),
+ Run("שהתוצאה", bold=True),
+ Run(" שגויה", bold=None),
+ ]
+```
+
+כל run מסומן RTL בנפרד. יוצא ב-Word עם הדגש המקומי בלבד על המילה
+`שהתוצאה`.
+
+## השלמת התמונה
+
+```
+md content
+ ↓ splitlines()
+for line in lines:
+ ↓ _classify_line(line)
+ → (kind, clean_text)
+ ↓ _emit_content_line(doc, line)
+ → paragraph with chosen style
+ ↓ _add_runs_with_inline_bold(paragraph, clean_text)
+ → runs with inline **bold** rendered
+ ↓ _mark_run_rtl / _mark_paragraph_rtl
+ → Hebrew renders in David (cs slot)
+```
+
+## הוספת קטגוריה חדשה
+
+אם יש דפוס שלא מזוהה ורצוי למפות אותו:
+
+1. הוסף regex constant (למעלה בקובץ, אחרי הקיימים).
+2. הוסף branch ב-`_classify_line()` לפי הסדר הנכון (ספציפי לפני כללי).
+3. הוסף branch ב-`_emit_content_line()` עם הסגנון המתאים.
+4. הוסף test case ב-references/line-classification.md (כאן).
+5. הרץ על תיק מייצג (למשל 8070-25) וראה שהתוצאה נכונה.
diff --git a/skills/dafna-decision-template/references/rtl-runs.md b/skills/dafna-decision-template/references/rtl-runs.md
new file mode 100644
index 0000000..74dbaac
--- /dev/null
+++ b/skills/dafna-decision-template/references/rtl-runs.md
@@ -0,0 +1,81 @@
+# למה `` חובה בכל run
+
+## הבעיה
+
+כשאתה יוצר `run` ב-python-docx על סגנון עברי מוגדר היטב (למשל Normal עם
+`cs="David"`) — עברית עדיין יוצאת ב-Times New Roman.
+
+## הסיבה
+
+Word משתמש ב-3 font slots בתוך ``:
+- `w:ascii` — תווים לטיניים
+- `w:hAnsi` — אותיות מיוחדות אירופיות
+- `w:cs` (complex script) — עברית, ערבית, תאית
+
+ההחלטה איזה slot להשתמש נעשית **לפי סוג הטקסט ב-run** ולפי **דגל רמת
+הריצה ``**. בלי הדגל, Word יכול להתייחס לטקסט העברי כ-LTR
+(למשל כשהוא מתערבב עם ספרות/לטינית) ולבחור את `ascii` — Times New Roman.
+
+## הפתרון
+
+מסמן כל run עברי כ-complex-script:
+
+```python
+from docx.oxml import OxmlElement
+from docx.oxml.ns import qn
+
+def _mark_run_rtl(run):
+ rPr = run._r.get_or_add_rPr()
+ if rPr.find(qn("w:rtl")) is None:
+ rPr.append(OxmlElement("w:rtl"))
+```
+
+וגם ברמת ה-paragraph (למקרה ש-paragraph mark עצמו משפיע):
+
+```python
+def _mark_paragraph_rtl(paragraph):
+ pPr = paragraph._p.get_or_add_pPr()
+ rPr = pPr.find(qn("w:rPr"))
+ if rPr is None:
+ rPr = OxmlElement("w:rPr"); pPr.append(rPr)
+ if rPr.find(qn("w:rtl")) is None:
+ rPr.append(OxmlElement("w:rtl"))
+```
+
+## תופעות לוואי של חוסר RTL ברמת ה-run
+
+1. **Font fallback ל-Times New Roman** — הסימפטום הנפוץ ביותר.
+2. **BiDi reordering של פיסוק** — נקודתיים, פסיקים, סוגריים עוברים למקום
+ הלא נכון. הסימפטום: `"(א)"` הופך ל-`")א("`.
+3. **מספרים "נוגדים" ברצף עברי** — `"בשנת 2024 פסקנו"` יכול להיראות
+ עם המספר במיקום הלא נכון.
+
+## איך לבדוק שה-RTL חל
+
+```python
+from docx.oxml.ns import qn
+
+for p in doc.paragraphs:
+ for r in p.runs:
+ rPr = r._r.find(qn("w:rPr"))
+ has_rtl = rPr is not None and rPr.find(qn("w:rtl")) is not None
+ if not has_rtl and any('\u0590' <= c <= '\u05FF' for c in r.text):
+ print(f"Missing RTL: {r.text[:40]!r}")
+```
+
+## זה לא מספיק רק ברמת הסגנון
+
+זו תפיסה מוטעית נפוצה: "אם הסגנון כולל `` ב-`rPr`, ירש כל ריצה".
+**לא נכון**. סגנון נותן ברירת מחדל ל-runs שעדיין לא נוצרו ב-Word GUI —
+אבל runs שנוצרו דרך python-docx מקבלים `rPr` ריק, שלא תורש אוטומטית
+את ה-rtl מהסגנון. לכן חייבים להוסיף ידנית.
+
+## הטמפלט של דפנה כדוגמה
+
+בוחנים את `word/document.xml` של הטמפלט המקורי — כל ריצה עברית כוללת:
+
+```xml
+רקע
+```
+
+`` נמצא שם **במפורש**. אנחנו מחקים את זה.
diff --git a/skills/dafna-decision-template/references/style-mapping.md b/skills/dafna-decision-template/references/style-mapping.md
new file mode 100644
index 0000000..3f8216b
--- /dev/null
+++ b/skills/dafna-decision-template/references/style-mapping.md
@@ -0,0 +1,155 @@
+# מיפוי סגנונות — `טיוטת החלטה.dotx`
+
+מבוסס על ניתוח `word/styles.xml` של הטמפלט. כל הגדרות מצוטטות מה-XML
+המקורי.
+
+## סגנונות בסיסיים (Word-idioms)
+
+### `Normal` (styleId: `a1`)
+ברירת המחדל לפסקאות רגילות. **כל שאר הסגנונות יורשים ממנו**
+(`basedOn="a1"`).
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**מה זה אומר לך:**
+- עברית תצא ב-David 13pt (דרך `cs`)
+- לטינית תצא ב-Times New Roman 13pt (דרך `ascii`)
+- יישור justify (דו-צדדי), RTL
+- מרווח 1.5 שורות (`line=360` = 1.5 × 240)
+
+### `Heading 1` (styleId: `10`, name: `heading 1`)
+לכותרת ראשית (כמו "ניתוח משפטי וכתיבת עמדה בערר X").
+```xml
+
+
+```
+Heading 1 **אינו** מציין cs fonts מפורשות, אבל יורש `cs="David"` מ-Normal.
+זה מבדיל אותו מ-`Title`, שמפנה ל-theme ריק.
+
+### `Heading 2` (styleId: `2`)
+לכותרות מקטעים ותת-מקטעים.
+```xml
+
+
+
+```
+
+### `Title` (styleId: `a5`) — ⚠️ הימנע
+```xml
+
+```
+מפנה ל-theme. ב-`theme1.xml`: `majorFont.cs = ""` (ריק). → עברית נופלת
+ל-`majorFont.latin = "Aptos Display"`. **השתמש ב-Heading 1 במקום.**
+
+### `Subtitle` (styleId: `a7`) — ⚠️ אותה בעיה של Title
+לא בשימוש.
+
+## סגנונות תוכן
+
+### `Quote` (styleId: `a9`)
+```xml
+
+
+
+
+```
+לציטוטי פסיקה. הזחה פנימה, bold.
+
+### `List Paragraph` (styleId: `a0`)
+```xml
+
+
+
+
+
+
+
+```
+**numId=1 מפנה ל-abstractNumId=16**, שמוגדר כ-`decimal` עם `lvlText="%1."`.
+כלומר Word יוסיף "1.", "2.", "3." אוטומטית לפני הטקסט.
+
+**חשוב:** `List Paragraph` הוא היחיד בטמפלט עם numbering אוטומטי. אין
+bullet style מוכן. לרשימות עם (א)(ב), **הסר את ה-numPr** ברמת הפסקה:
+
+```python
+from docx.oxml.ns import qn
+
+def _strip_numpr(paragraph):
+ pPr = paragraph._p.get_or_add_pPr()
+ for numPr in pPr.findall(qn("w:numPr")):
+ pPr.remove(numPr)
+```
+
+## סגנונות נוספים בטמפלט (לא בשימוש כרגע)
+
+| styleId | שם | מה |
+|---------|----|----|
+| `P00`, `P11`, `P22` | תבניות מותאמות אישית | ישן, נראה שלא בשימוש פעיל |
+| `12`, `21`, `31` | פיסקת רשימה 1/2/3 | ללא numPr — שימוש ויזואלי בלבד |
+| `-` | פיסקת רשימה - ללא מספור | מיועד ל-bullets ללא מספור |
+| `14` | ציטוט1 | וריאציה ישנה של Quote |
+| `af2` / `af4` | header / footer | לכותרות עליונות/תחתונות |
+
+## theme (`word/theme/theme1.xml`)
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+**ה-cs ריק ב-theme** — זו הסיבה ש-`Title` (שמפנה ל-theme) לא עובד
+לעברית. אל תסמוך על theme; השתמש ב-styles שמגדירים cs מפורש (Normal +
+כל מה שיורש ממנו).
+
+## numbering definitions
+
+`word/numbering.xml` כולל ~22 abstractNum מוגדרים. הרלוונטי לנו:
+
+```
+numId=1 → abstractNumId=16 → numFmt=decimal, lvlText="%1."
+```
+
+יש גם hebrew1 (`numFmt=hebrew1` = א., ב., ג.) ב-`abstractNumId=0, 1`.
+אף סגנון מוכן לא מפנה אליהם. אם תרצה בעתיד רשימה ממוספרת בעברית עם
+Word auto-numbering — יש להזריק `numPr` ידנית עם `numId=29` (שמפנה
+ל-abstractNumId=0).
+
+## גדלים — רפרנס מהיר
+
+| style | ascii | cs (עברית) |
+|-------|-------|-----------|
+| Normal | 13pt | 13pt |
+| Heading 1 | 20pt | 18pt |
+| Heading 2 | 13pt (ירושה) + bold + underline | אותו דבר |
+| Title | 28pt (Aptos Display — לא עברית!) | — |
+| List Paragraph | 14pt (David) | 14pt |
+| Quote | 13pt (ירושה) + bold | 13pt |
+
+## טיפ
+
+כדי לבדוק את כל הסגנונות שבמסמך:
+
+```python
+from docx import Document
+d = Document("skills/docx/decision_template.docx")
+for s in sorted(d.styles, key=lambda x: x.name):
+ print(s.type, s.name, s.style_id)
+```