"use client"; import { X } from "lucide-react"; import { useEffect, useRef } from "react"; import { groupWindowTransitions, houseTableToNorthIndianChart, rectificationBoardPeekCopy, workingRectificationTime, type RectificationBoardDiff, } from "@/lib/rectification-board-model"; import { engineMeaningToDisplayCopy } from "@/lib/rectification-agentic/user-copy"; import { workingRectificationHouseTable, type RectificationCandidateResult, } from "@/lib/rectification-candidate-result"; import { windowScanLayerLabel, type WindowScanLayer, } from "@/lib/rectification-agentic/v9/refinement-packet"; import { rectificationBoardEmptyCopy } from "@/lib/rectification-surface-state"; import { VedicChartSvg } from "@/components/personal-report/vedic-chart-svg"; import { RectificationHouseTableView } from "./rectification-house-table"; import { ConfirmationGateDisclosure, TechniqueAuditDisclosure } from "./technique-audit-disclosure"; function LayerChips({ layers }: Readonly<{ layers: readonly WindowScanLayer[] }>) { if (layers.length === 0) return null; return ( ); } function RectificationBoardBody({ result, declaredTime, birthTimeSource, savedStatus, diff, compact, titleId, onClose, }: Readonly<{ result: RectificationCandidateResult | null; declaredTime: string | null; birthTimeSource?: string | null; savedStatus: "accepted" | "confirmed" | null; diff: RectificationBoardDiff; compact: boolean; titleId: string; onClose: () => void; }>) { const table = result ? workingRectificationHouseTable(result) : null; const workingTime = workingRectificationTime(result); const emptyCopy = rectificationBoardEmptyCopy(declaredTime, birthTimeSource); const grouped = result ? groupWindowTransitions(result.windowTransitions) : []; const scoringMinutes = grouped.filter((row) => row.scoringLayers.length > 0); const displayMinutes = grouped.filter((row) => row.displayLayers.length > 0); const changedHouses = new Set(diff.houseNumbers); const changedMinutes = new Set(diff.transitionMinutes); const stage = result?.precisionStage?.user_meaning ?? result?.natalRecast?.user_meaning ?? null; const ledger = result?.eventDashaLedger ?? []; const contrast = result?.lagnaContrast ?? null; const agreement = result?.dashaAgreement ?? null; const nakshatra = result?.nakshatraBoundary ?? null; // Two sections, not five (D10). Nothing was dropped in the regrouping — the // minutes moved under 候选分钟, and the house table, the confirmation gate, // the technique audit, the two-lagna split, the event/dasha ledger with its // dual-track agreement line and the nakshatra note all moved under 参数与口径. // Each block keeps the render condition it had, so a state that showed // nothing before still shows nothing: the gate and the audit stay behind // `table`, exactly as when they sat inside `.rectification-snapshot`. const hasMinuteDetail = scoringMinutes.length > 0 || displayMinutes.length > 0; const hasParameterDetail = Boolean( table || contrast || ledger.length > 0 || (nakshatra?.near_boundary && nakshatra.user_meaning), ); return ( <> {compact ?