diff --git a/web-ui/src/components/goldset/goldset-panel.tsx b/web-ui/src/components/goldset/goldset-panel.tsx
index aaeb3e5..79f8265 100644
--- a/web-ui/src/components/goldset/goldset-panel.tsx
+++ b/web-ui/src/components/goldset/goldset-panel.tsx
@@ -1,11 +1,12 @@
"use client";
import { useEffect, useMemo, useState } from "react";
-import { Check, X, ChevronDown, ChevronLeft } from "lucide-react";
+import { Check, X, ChevronDown, ChevronLeft, Info } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import {
useGoldset, useGoldsetScore, useTagGoldset, useCreateGoldsetSample,
type GoldsetItem,
@@ -32,7 +33,10 @@ function cleanCitation(s: string | null | undefined): string {
}
function isTagged(it: GoldsetItem): boolean {
- return it.is_holding !== null;
+ // Fully tagged only when ALL THREE answers are set — otherwise, in
+ // "hide tagged" mode, a card would vanish the moment is_holding is clicked,
+ // before correct_type / quote_complete can be set.
+ return it.is_holding !== null && it.quote_complete !== null && !!it.correct_type;
}
// ─── Score panel ──────────────────────────────────────────────────────────────
@@ -86,6 +90,82 @@ function ScorePanel({ batch }: { batch: string }) {
);
}
+// ─── Rule-type help (info popover) ────────────────────────────────────────────
+
+const TYPE_HELP: { label: string; def: string; test: string; example: string }[] = [
+ {
+ label: "מחייבת",
+ def: "העיקרון שהיה הכרחי להכרעה — ה-holding האמיתי. בר-הסתמכות מלא.",
+ test: "מבחן וומבו: הפוך את הכלל — אם התוצאה הייתה משתנה → מחייבת.",
+ example: "נטל ההוכחה בהיטל השבחה מוטל על הוועדה המקומית.",
+ },
+ {
+ label: "פרשני",
+ def: "קביעה שמפרשת הוראת-חוק / מונח / תכנית (מה המשמעות של סעיף X).",
+ test: "עונה ל'מה פירוש הנורמה?' ולא ל'מה הדין?'.",
+ example: "תכלית הפטור לפי ס' 19(ב)(4) היא לעודד פעילות ציבורית.",
+ },
+ {
+ label: "פרוצדורלי",
+ def: "כלל סדר-דין: מועדים, סמכות, זכות-עמידה, מיצוי הליכים, נטל.",
+ test: "עוסק ב'איך' מתנהל ההליך, לא במהות התכנונית.",
+ example: "המועד להגשת ערר הוא 30 יום.",
+ },
+ {
+ label: "משכנע",
+ def: "אסמכתה לא-מחייבת את הערכאה — שכנוע בלבד.",
+ test: "מקור שאינו כובל: ועדת-ערר אחרת, דעת-מיעוט, ספרות.",
+ example: "ועדת ערר ירושלים מסתמכת על החלטת ועדת ערר ממחוז אחר.",
+ },
+ {
+ label: "יישום",
+ def: "החלת כלל על עובדות התיק הספציפי — תלוי-עובדות, לא בר-הכללה (לרוב 'לא הלכה').",
+ test: "מכיל 'במקרה דנן', שמות-צדדים, סכומים, המבנה הקונקרטי.",
+ example: "במקרה דנן ההיתר בטל כי השומה שגתה ב-12,000 ₪.",
+ },
+ {
+ label: "אמרת-אגב",
+ def: "נאמר אגב אורחא, לא הכרחי להכרעה; הערכאה לא הכריעה בו. לא מחייב.",
+ test: "מבחן וומבו הפוך: היפוך הכלל לא משנה את התוצאה. דגלים: 'למעלה מן הצורך', 'מבלי לקבוע מסמרות'.",
+ example: "אף שאיננו נדרשים להכריע, נעיר כי ייתכן ש...",
+ },
+];
+
+function RuleTypeHelp() {
+ return (
+ סוגי ההלכה — במה הם נבדלים
+ כלל-אצבע: סימנת "הלכה" → לרוב מחייבת / פרשני / פרוצדורלי / משכנע. סימנת "לא" → לרוב יישום / אמרת-אגב.
+
+ {TYPE_HELP.map((t) => (
+
+