feat(ui): IA redesign → production · צרור-2 (13 הדפים הנותרים) — ליטוש-ויזואלי בלבד
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s

מעבר מלא על שאר 13 הדפים מול מוקאפי-Claude-Design המאושרים. **UI/className בלבד —
שום hook/query/mutation/טאב/טופס/לוגיקה לא נגע** (אומת: 0 הסרות-hook/import ב-diff).

שונו (פער-ויזואלי אמיתי):
- archive — pill-ספירה ב-gold-wash + breadcrumb (הוסר טקסט-ספירה כפול בכרטיס).
- feedback — CTA "סמן כיושם" gold-filled + תיבת-לקח עם גבול-זהב-לוגי.
- methodology — כותרת קנונית (breadcrumb + h1 text-navy + gradient divider).
- missing-precedents — pill open-count (warn-bg, tabular-nums).
- precedents/[id] — ציטוט-מפתח gold-wash + border-s לוגי; צ'יפי-מטא צבעוניים (domain=info/level=gold/binding=success).
- skills — נקודות-סטטוס צבעוניות בתוך ה-pills.
- scripts — breadcrumb + gradient divider.
- components/precedents: library-search-panel (border לוגי, "קטע"=info, צ'יפ "הלכות מאושרות בלבד"), halacha-meta (binding=success/persuasive=gold-wash).

parity — ללא שינוי (כבר תואמים): graph, training, settings, digests, precedents(shell), cases/[n], operations, compose.

בדיקות: npx tsc --noEmit ✓ · eslint ✓ (לבד מ-learning-panel:109 קיים-מראש).
מסכם את תרגום 17 הדפים לפרודקשן (צרור-1 #211 = approvals+home).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 22:19:16 +00:00
parent 35f656f2b8
commit 1351c77dfd
9 changed files with 96 additions and 37 deletions

View File

@@ -156,14 +156,29 @@ export default function ArchivePage() {
<AppShell>
<section className="space-y-8">
<header className="space-y-1.5">
<div className="text-[0.75rem] uppercase tracking-[0.12em] text-gold-deep">
ארכיון תיקי ערר
<nav className="text-[0.78rem] text-ink-muted mb-1">
<Link href="/" className="hover:text-gold-deep">בית</Link>
<span aria-hidden> · </span>
<span className="text-navy">ארכיון</span>
</nav>
<div className="flex items-end justify-between gap-4 flex-wrap">
<div className="space-y-1">
<div className="text-[0.75rem] uppercase tracking-[0.12em] text-gold-deep">
ארכיון תיקי ערר
</div>
<h1 className="text-navy mb-0">תיקים סגורים</h1>
<p className="text-ink-muted text-base max-w-2xl leading-relaxed">
תיקים שסגרו את הטיפול בהם. שחזור מחזיר את התיק לרשימה הראשית
ופותח מחדש את הפרויקט המקביל ב-Paperclip.
</p>
</div>
<div className="inline-flex items-baseline gap-2 rounded-lg border border-rule bg-gold-wash px-4 py-2.5">
<span className="text-2xl font-semibold text-gold-deep leading-none tabular-nums">
{table.getFilteredRowModel().rows.length}
</span>
<span className="text-[0.85rem] text-ink-soft">תיקים בארכיון</span>
</div>
</div>
<h1 className="text-navy">תיקים סגורים</h1>
<p className="text-ink-muted text-base max-w-2xl leading-relaxed">
תיקים שסגרו את הטיפול בהם. שחזור מחזיר את התיק לרשימה הראשית
ופותח מחדש את הפרויקט המקביל ב-Paperclip.
</p>
</header>
<div className="h-[2px] bg-gradient-to-l from-transparent via-gold to-transparent" />
@@ -178,9 +193,6 @@ export default function ArchivePage() {
className="max-w-sm bg-surface"
dir="rtl"
/>
<span className="text-sm text-ink-muted me-auto">
{table.getFilteredRowModel().rows.length} תיקים בארכיון
</span>
</div>
<div className="rounded-lg border border-rule bg-surface shadow-sm overflow-hidden">

View File

@@ -86,9 +86,9 @@ function FeedbackCard({ fb }: { fb: ChairFeedback }) {
</p>
{fb.lesson_extracted ? (
<div className="rounded-md bg-gold-wash/40 border border-gold/30 px-3 py-2">
<div className="rounded-md bg-gold-wash/40 border-s-[3px] border-gold ps-3 pe-3 py-2">
<div className="text-[0.68rem] text-gold-deep mb-0.5">לקח שהופק</div>
<p className="text-ink-soft text-[0.82rem] leading-relaxed m-0 whitespace-pre-wrap" dir="rtl">
<p className="text-ink-soft text-[0.82rem] leading-relaxed m-0 whitespace-pre-wrap italic" dir="rtl">
{fb.lesson_extracted}
</p>
</div>
@@ -104,7 +104,7 @@ function FeedbackCard({ fb }: { fb: ChairFeedback }) {
size="sm"
onClick={onResolve}
disabled={resolve.isPending}
className="bg-gold text-navy hover:bg-gold-deep"
className="bg-gold text-white hover:bg-gold-deep border-transparent"
>
<Check className="w-3.5 h-3.5 me-1" />
סמן כיושם

View File

@@ -1,5 +1,6 @@
"use client";
import Link from "next/link";
import { AppShell } from "@/components/app-shell";
import { Card, CardContent } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
@@ -12,12 +13,19 @@ export default function MethodologyPage() {
return (
<AppShell>
<section className="space-y-6">
<div>
<h1 className="text-xl font-bold text-navy">מתודולוגיה</h1>
<p className="text-sm text-ink-muted mt-1">
<header>
<nav className="text-[0.78rem] text-ink-muted mb-1">
<Link href="/" className="hover:text-gold-deep">בית</Link>
<span aria-hidden> · </span>
<span className="text-navy">מתודולוגיה</span>
</nav>
<h1 className="text-navy mb-0">מתודולוגיה</h1>
<p className="text-ink-muted text-sm mt-1 max-w-2xl">
הגדרות ניסוח יחסי אורך, כללי דיון, וצ׳קליסטים לפי סוג ערר
</p>
</div>
</header>
<div className="h-[2px] bg-gradient-to-l from-transparent via-gold to-transparent" />
<Card className="bg-surface border-rule shadow-sm">
<CardContent className="px-6 py-5">

View File

@@ -56,12 +56,24 @@ export default function MissingPrecedentsPage() {
<span aria-hidden> · </span>
<span className="text-navy">פסיקה חסרה בקורפוס</span>
</nav>
<h1 className="text-navy mb-0">פסיקה חסרה בקורפוס</h1>
<p className="text-ink-muted text-sm mt-1 max-w-3xl">
פסיקות שצוטטו בכתבי הטענות אך אינן עדיין בקורפוס. סוכן המחקר רושם
פערים אוטומטית; היו&quot;ר סוגר אותם על־ידי העלאת המסמך ניתוב
אוטומטי בין הקורפוס הסמכותי (פסקי דין) להחלטות ועדות ערר.
</p>
<div className="flex items-end justify-between gap-4 flex-wrap">
<div>
<h1 className="text-navy mb-0">פסיקה חסרה בקורפוס</h1>
<p className="text-ink-muted text-sm mt-1 max-w-3xl">
פסיקות שצוטטו בכתבי הטענות אך אינן עדיין בקורפוס. סוכן המחקר רושם
פערים אוטומטית; היו&quot;ר סוגר אותם על־ידי העלאת המסמך ניתוב
אוטומטי בין הקורפוס הסמכותי (פסקי דין) להחלטות ועדות ערר.
</p>
</div>
{byStatus.open ? (
<div className="inline-flex items-baseline gap-2 rounded-lg border border-rule bg-warn-bg px-4 py-2.5">
<span className="text-2xl font-semibold text-warn leading-none tabular-nums">
{byStatus.open}
</span>
<span className="text-[0.85rem] text-ink-soft">פתוחים</span>
</div>
) : null}
</div>
</header>
<div className="h-[2px] bg-gradient-to-l from-transparent via-gold to-transparent" />

View File

@@ -132,7 +132,7 @@ export default function PrecedentDetailPage({
<div className="flex items-center gap-2 flex-wrap">
{data.practice_area ? (
<Badge variant="outline" className="text-[0.7rem]">
<Badge variant="outline" className="text-[0.7rem] bg-info-bg text-info border-transparent">
{PRACTICE_AREA_LABELS[data.practice_area] ?? data.practice_area}
</Badge>
) : null}
@@ -142,14 +142,14 @@ export default function PrecedentDetailPage({
</Badge>
) : null}
{data.precedent_level ? (
<Badge variant="outline" className="text-[0.7rem]">
<Badge variant="outline" className="text-[0.7rem] bg-gold-wash text-gold-deep border-rule">
{data.precedent_level}
</Badge>
) : null}
{data.is_binding ? (
<Badge
variant="outline"
className="text-[0.7rem] bg-gold-wash text-gold-deep border-gold/40"
className="text-[0.7rem] bg-success-bg text-success border-transparent"
>
הלכה מחייבת
</Badge>
@@ -185,7 +185,7 @@ export default function PrecedentDetailPage({
{(data as { key_quote?: string }).key_quote ? (
<div>
<h3 className="text-navy text-sm font-semibold m-0 mb-1">ציטוט מרכזי</h3>
<blockquote className="text-ink-soft text-sm leading-relaxed border-r-2 border-gold pr-3 m-0">
<blockquote className="text-ink-soft text-sm leading-relaxed border-s-[3px] border-gold bg-gold-wash ps-3 pe-4 py-3 rounded-e m-0">
{(data as { key_quote?: string }).key_quote}
</blockquote>
</div>

View File

@@ -1,5 +1,6 @@
"use client";
import Link from "next/link";
import { useQuery } from "@tanstack/react-query";
import { AppShell } from "@/components/app-shell";
@@ -35,7 +36,12 @@ export default function ScriptsPage() {
<section className="space-y-6">
<div className="flex items-end justify-between gap-4">
<div>
<h1 className="text-xl font-bold text-navy">סקריפטים</h1>
<nav className="text-[0.78rem] text-ink-muted mb-1">
<Link href="/" className="hover:text-gold-deep">בית</Link>
<span aria-hidden> · </span>
<span className="text-navy">סקריפטים</span>
</nav>
<h1 className="text-navy mb-0">סקריפטים</h1>
<p className="text-sm text-ink-muted mt-1">
קטלוג כל הסקריפטים בתיקיית{" "}
<code className="rounded bg-rule-soft px-1 py-0.5 font-mono text-[0.78rem]">
@@ -60,6 +66,8 @@ export default function ScriptsPage() {
) : null}
</div>
<div className="h-[2px] bg-gradient-to-l from-transparent via-gold to-transparent" />
<Card className="bg-surface border-rule shadow-sm">
<CardContent className="px-6 py-5">
{isLoading ? (

View File

@@ -15,15 +15,31 @@ function formatSize(bytes: number | null) {
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}
function StatusDot({ tone }: { tone: string }) {
return <span className={`h-1.5 w-1.5 rounded-full ${tone}`} aria-hidden />;
}
function statusBadge(s: Skill) {
if (s.not_in_db) {
return <Badge variant="outline" className="bg-warn-bg text-warn border-warn/40">לא סונכרן</Badge>;
return (
<Badge variant="outline" className="gap-1.5 bg-warn-bg text-warn border-warn/40">
<StatusDot tone="bg-warn" />לא סונכרן
</Badge>
);
}
if (s.db_markdown_chars > 0 && s.disk_exists) {
return <Badge variant="outline" className="bg-success-bg text-success border-success/40">מסונכרן</Badge>;
return (
<Badge variant="outline" className="gap-1.5 bg-success-bg text-success border-success/40">
<StatusDot tone="bg-success" />מסונכרן
</Badge>
);
}
if (s.db_markdown_chars > 0) {
return <Badge variant="outline" className="bg-info-bg text-info border-info/40">DB בלבד</Badge>;
return (
<Badge variant="outline" className="gap-1.5 bg-info-bg text-info border-info/40">
<StatusDot tone="bg-info" />DB בלבד
</Badge>
);
}
return <Badge variant="outline">לא ידוע</Badge>;
}

View File

@@ -44,8 +44,8 @@ export function AuthorityBadge({
title="דרגת-המחייבות נגזרת אוטומטית מזהות הערכאה"
className={
isBinding
? "text-[0.65rem] bg-gold/15 text-navy border-gold/50"
: "text-[0.65rem] bg-muted text-ink-muted border-border"
? "text-[0.65rem] bg-success-bg text-success border-transparent"
: "text-[0.65rem] bg-gold-wash text-gold-deep border-rule"
}
>
{AUTHORITY_LABELS[authority]}

View File

@@ -42,7 +42,7 @@ function HalachaCard({ hit }: { hit: Extract<SearchHit, { type: "halacha" }> })
<p className="text-navy font-medium text-[0.95rem]" dir="rtl">
{hit.rule_statement}
</p>
<blockquote className="text-ink-soft text-sm border-r-2 border-gold pr-3" dir="rtl">
<blockquote className="text-ink-soft text-sm border-s-2 border-gold ps-3" dir="rtl">
&ldquo;{hit.supporting_quote}&rdquo;
{hit.page_reference && <span className="text-ink-muted text-[0.72rem] ms-2">({hit.page_reference})</span>}
</blockquote>
@@ -63,7 +63,7 @@ function PassageCard({ hit }: { hit: Extract<SearchHit, { type: "passage" }> })
return (
<div className="rounded-lg border border-rule bg-surface p-4 space-y-2">
<div className="flex items-center gap-2 text-[0.78rem] text-ink-muted flex-wrap">
<Badge variant="outline" className="bg-rule-soft text-ink-muted">קטע</Badge>
<Badge variant="outline" className="bg-info-bg text-info border-transparent">קטע</Badge>
<span className="font-mono" dir="ltr">{hit.case_number}</span>
{hit.court && <span>· {hit.court}</span>}
{hit.decision_date && <span>· {formatDate(hit.decision_date)}</span>}
@@ -161,8 +161,11 @@ export function LibrarySearchPanel() {
</div>
) : (
<div className="space-y-3">
<p className="text-[0.78rem] text-ink-muted">
{data.count} תוצאות (הלכות מאושרות בלבד)
<p className="text-[0.78rem] text-ink-muted flex items-center gap-2">
<span className="inline-flex items-center rounded-full bg-success-bg text-success text-[0.7rem] font-semibold px-2.5 py-0.5">
הלכות מאושרות בלבד
</span>
<span className="tabular-nums">{data.count} תוצאות</span>
</p>
{data.items.map((hit, i) =>
hit.type === "halacha" ? (