feat: landing page interactive components#984
Conversation
WalkthroughAdds the React integration to the Astro site config and updates site/package.json. Introduces new interactive components: ParticleNetwork, ScrollSyncPanel, ExpandableArchitecture, FeatureShowcase, UseCaseCards, and a DashboardPreview React island with accompanying CSS plus four mini React islands (AgentDetailMini, BudgetMini, OrgChartMini, TaskBoardMini). Updates Base.astro font loading and refactors the index page to replace several static sections with these components and to render the dashboard preview as a client:visible island. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning Review ran into problems🔥 ProblemsTimed out fetching pipeline failures after 30000ms Comment |
Dependency ReviewThe following issues were found:
|
There was a problem hiding this comment.
Code Review
This pull request introduces several new interactive components to the Astro landing page, including an expandable architecture grid, a particle network background, a scroll-synced split panel, and a dashboard preview using React islands. While the new features enhance the site's interactivity, several components rely on hardcoded DOM IDs and global script selectors, which will cause functional issues if multiple instances are used on the same page or during client-side navigation. Additionally, there is a potential runtime error in the particle network's resize logic due to unsafe element access.
| <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> | ||
| {architecture.map((arch) => ( | ||
| <div class="relative"> | ||
| <button | ||
| id={`btn-${arch.id}`} | ||
| data-arch-toggle | ||
| aria-expanded="false" | ||
| aria-controls={`panel-${arch.id}`} | ||
| class="w-full bg-[#1a1f2e] rounded-xl p-6 border border-white/10 hover:border-violet-500/30 transition-colors text-left group cursor-pointer" | ||
| > | ||
| <div class="flex items-center justify-between"> | ||
| <div> | ||
| <p class="font-semibold text-violet-400">{arch.title}</p> | ||
| <p class="text-xs text-gray-400 mt-1">{arch.summary}</p> | ||
| </div> | ||
| <svg | ||
| class="w-4 h-4 text-gray-500 transition-transform duration-300 group-aria-expanded:rotate-180 shrink-0 ml-2" | ||
| fill="none" | ||
| viewBox="0 0 24 24" | ||
| stroke="currentColor" | ||
| stroke-width="2" | ||
| > | ||
| <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" /> | ||
| </svg> | ||
| </div> | ||
| </button> | ||
| </div> | ||
| ))} | ||
| </div> | ||
|
|
||
| <!-- Expandable panels (positioned below the grid) --> | ||
| {architecture.map((arch) => ( | ||
| <div | ||
| id={`panel-${arch.id}`} | ||
| role="region" | ||
| aria-labelledby={`btn-${arch.id}`} | ||
| aria-hidden="true" | ||
| inert | ||
| class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-300 ease-in-out" | ||
| > | ||
| <div class="overflow-hidden"> | ||
| <div class="pt-4 grid sm:grid-cols-2 lg:grid-cols-3 gap-3"> | ||
| {arch.submodules.map((sub) => ( | ||
| <a | ||
| href={sub.href} | ||
| class="block bg-[#1a1f2e]/60 rounded-lg p-4 border border-white/5 hover:border-violet-500/20 transition-colors no-underline text-white" | ||
| > | ||
| <p class="text-sm font-medium text-violet-400 mb-1">{sub.name}</p> | ||
| <p class="text-xs text-gray-400">{sub.description}</p> | ||
| </a> | ||
| ))} | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ))} | ||
|
|
||
| <script> | ||
| const buttons = document.querySelectorAll<HTMLButtonElement>("[data-arch-toggle]"); | ||
| buttons.forEach((btn) => { | ||
| btn.addEventListener("click", () => { | ||
| const targetId = btn.getAttribute("aria-controls"); | ||
| if (!targetId) return; | ||
| const target = document.getElementById(targetId); | ||
| const isExpanded = btn.getAttribute("aria-expanded") === "true"; | ||
|
|
||
| // Collapse all | ||
| buttons.forEach((b) => { | ||
| b.setAttribute("aria-expanded", "false"); | ||
| const panelId = b.getAttribute("aria-controls"); | ||
| if (panelId) { | ||
| const panel = document.getElementById(panelId); | ||
| if (panel) { | ||
| panel.setAttribute("aria-hidden", "true"); | ||
| panel.setAttribute("inert", ""); | ||
| panel.classList.remove("grid-rows-[1fr]"); | ||
| panel.classList.add("grid-rows-[0fr]"); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| // Expand clicked (if it was collapsed) | ||
| if (!isExpanded && target) { | ||
| btn.setAttribute("aria-expanded", "true"); | ||
| target.removeAttribute("aria-hidden"); | ||
| target.removeAttribute("inert"); | ||
| target.classList.remove("grid-rows-[0fr]"); | ||
| target.classList.add("grid-rows-[1fr]"); | ||
| } | ||
| }); | ||
| }); | ||
| </script> |
There was a problem hiding this comment.
The component uses hardcoded, generic IDs (e.g., btn-config, panel-engine) and global script selectors (document.querySelectorAll("[data-arch-toggle]")). This prevents multiple instances of the component from working independently on the same page and risks ID collisions with other elements. Clicking a button in one instance will collapse panels in all other instances. Consider generating unique IDs per instance and scoping the script to a wrapper element using btn.closest or a custom element.
| function resize(): void { | ||
| const rect = canvas.parentElement!.getBoundingClientRect(); |
There was a problem hiding this comment.
The resize function is called within a setTimeout (line 206) and uses a non-null assertion (!) on canvas.parentElement. If the component is unmounted or the page is navigated away before the timeout fires, canvas.parentElement will be null, leading to a runtime crash. Add a safety check for the parent element.
function resize(): void {
if (!canvas.parentElement) return;
const rect = canvas.parentElement.getBoundingClientRect();
| <div class="bg-[#0F1219] rounded-xl border border-white/10 p-6 min-h-[420px] flex items-center justify-center"> | ||
| <svg | ||
| id="sync-viz" | ||
| viewBox="0 0 420 380" | ||
| class="w-full max-w-[420px]" | ||
| aria-hidden="true" | ||
| > | ||
| <!-- Step label --> | ||
| <text id="viz-label" x="210" y="18" text-anchor="middle" fill="#94a3b8" font-size="11" font-family="'JetBrains Mono', monospace" class="transition-all duration-500"> | ||
| Pick a Template | ||
| </text> | ||
|
|
||
| <!-- Department groups --> | ||
| <rect id="dept-exec" x="140" y="30" width="140" height="55" rx="6" fill="none" stroke="#a78bfa" stroke-opacity="0.12" stroke-width="1" class="transition-all duration-700" opacity="0" /> | ||
| <text class="dept-label transition-all duration-700" x="148" y="44" fill="#a78bfa" font-size="7" font-family="Inter, sans-serif" opacity="0">Executive</text> | ||
|
|
||
| <rect id="dept-eng" x="10" y="115" width="195" height="120" rx="6" fill="none" stroke="#a78bfa" stroke-opacity="0.12" stroke-width="1" class="transition-all duration-700" opacity="0" /> | ||
| <text class="dept-label transition-all duration-700" x="18" y="129" fill="#a78bfa" font-size="7" font-family="Inter, sans-serif" opacity="0">Engineering</text> | ||
|
|
||
| <rect id="dept-product" x="215" y="115" width="95" height="120" rx="6" fill="none" stroke="#2dd4bf" stroke-opacity="0.12" stroke-width="1" class="transition-all duration-700" opacity="0" /> | ||
| <text class="dept-label transition-all duration-700" x="223" y="129" fill="#2dd4bf" font-size="7" font-family="Inter, sans-serif" opacity="0">Product</text> | ||
|
|
||
| <rect id="dept-design" x="320" y="115" width="90" height="120" rx="6" fill="none" stroke="#2dd4bf" stroke-opacity="0.12" stroke-width="1" class="transition-all duration-700" opacity="0" /> | ||
| <text class="dept-label transition-all duration-700" x="328" y="129" fill="#2dd4bf" font-size="7" font-family="Inter, sans-serif" opacity="0">Design</text> | ||
|
|
||
| <rect id="dept-qa" x="120" y="255" width="180" height="55" rx="6" fill="none" stroke="#f59e0b" stroke-opacity="0.12" stroke-width="1" class="transition-all duration-700" opacity="0" /> | ||
| <text class="dept-label transition-all duration-700" x="128" y="269" fill="#f59e0b" font-size="7" font-family="Inter, sans-serif" opacity="0">QA</text> | ||
|
|
||
| <!-- Agent nodes --> | ||
| <!-- CEO --> | ||
| <g id="node-ceo" class="transition-all duration-700" opacity="0"> | ||
| <rect x="165" y="48" width="90" height="30" rx="6" fill="#1a1f2e" stroke="#a78bfa" stroke-width="1.5" /> | ||
| <text x="210" y="67" text-anchor="middle" fill="#e2e8f0" font-size="10" font-weight="600" font-family="Inter, sans-serif">CEO</text> | ||
| <circle id="status-ceo" cx="247" cy="58" r="3.5" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- CTO --> | ||
| <g id="node-cto" class="transition-all duration-700" opacity="0"> | ||
| <rect x="15" y="137" width="85" height="30" rx="6" fill="#1a1f2e" stroke="#a78bfa" stroke-width="1.2" /> | ||
| <text x="57" y="156" text-anchor="middle" fill="#e2e8f0" font-size="9" font-weight="600" font-family="Inter, sans-serif">CTO</text> | ||
| <circle id="status-cto" cx="92" cy="147" r="3" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- Backend Dev 1 --> | ||
| <g id="node-be1" class="transition-all duration-700" opacity="0"> | ||
| <rect x="15" y="175" width="85" height="26" rx="5" fill="#1a1f2e" stroke="#a78bfa" stroke-width="0.8" /> | ||
| <text x="57" y="192" text-anchor="middle" fill="#e2e8f0" font-size="8" font-family="Inter, sans-serif">Backend Dev</text> | ||
| <circle id="status-be1" cx="92" cy="184" r="2.5" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- Backend Dev 2 --> | ||
| <g id="node-be2" class="transition-all duration-700" opacity="0"> | ||
| <rect x="110" y="175" width="85" height="26" rx="5" fill="#1a1f2e" stroke="#a78bfa" stroke-width="0.8" /> | ||
| <text x="152" y="192" text-anchor="middle" fill="#e2e8f0" font-size="8" font-family="Inter, sans-serif">Backend Dev 2</text> | ||
| <circle id="status-be2" cx="187" cy="184" r="2.5" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- Frontend Dev --> | ||
| <g id="node-fe" class="transition-all duration-700" opacity="0"> | ||
| <rect x="60" y="207" width="95" height="26" rx="5" fill="#1a1f2e" stroke="#a78bfa" stroke-width="0.8" /> | ||
| <text x="107" y="224" text-anchor="middle" fill="#e2e8f0" font-size="8" font-family="Inter, sans-serif">Frontend Dev</text> | ||
| <circle id="status-fe" cx="147" cy="216" r="2.5" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- PM --> | ||
| <g id="node-pm" class="transition-all duration-700" opacity="0"> | ||
| <rect x="220" y="145" width="85" height="30" rx="6" fill="#1a1f2e" stroke="#2dd4bf" stroke-width="1" /> | ||
| <text x="262" y="164" text-anchor="middle" fill="#e2e8f0" font-size="9" font-weight="600" font-family="Inter, sans-serif">PM</text> | ||
| <circle id="status-pm" cx="297" cy="155" r="3" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- Scrum Master --> | ||
| <g id="node-sm" class="transition-all duration-700" opacity="0"> | ||
| <rect x="220" y="183" width="85" height="26" rx="5" fill="#1a1f2e" stroke="#2dd4bf" stroke-width="0.8" /> | ||
| <text x="262" y="200" text-anchor="middle" fill="#e2e8f0" font-size="8" font-family="Inter, sans-serif">Scrum Master</text> | ||
| <circle id="status-sm" cx="297" cy="192" r="2.5" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- UX Designer --> | ||
| <g id="node-ux" class="transition-all duration-700" opacity="0"> | ||
| <rect x="325" y="145" width="80" height="30" rx="6" fill="#1a1f2e" stroke="#2dd4bf" stroke-width="1" /> | ||
| <text x="365" y="164" text-anchor="middle" fill="#e2e8f0" font-size="9" font-weight="600" font-family="Inter, sans-serif">UX Designer</text> | ||
| <circle id="status-ux" cx="397" cy="155" r="3" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- UI Designer --> | ||
| <g id="node-ui" class="transition-all duration-700" opacity="0"> | ||
| <rect x="325" y="183" width="80" height="26" rx="5" fill="#1a1f2e" stroke="#2dd4bf" stroke-width="0.8" /> | ||
| <text x="365" y="200" text-anchor="middle" fill="#e2e8f0" font-size="8" font-family="Inter, sans-serif">UI Designer</text> | ||
| <circle id="status-ui" cx="397" cy="192" r="2.5" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- QA Engineer --> | ||
| <g id="node-qa" class="transition-all duration-700" opacity="0"> | ||
| <rect x="155" y="273" width="85" height="30" rx="6" fill="#1a1f2e" stroke="#f59e0b" stroke-width="1" /> | ||
| <text x="197" y="292" text-anchor="middle" fill="#e2e8f0" font-size="9" font-weight="600" font-family="Inter, sans-serif">QA Engineer</text> | ||
| <circle id="status-qa" cx="232" cy="283" r="3" fill="#94a3b8" class="transition-all duration-500" /> | ||
| </g> | ||
|
|
||
| <!-- Hierarchy edges --> | ||
| <line id="edge-ceo-cto" x1="210" y1="78" x2="57" y2="137" stroke="#a78bfa" stroke-width="0.8" stroke-opacity="0.25" stroke-dasharray="3 3" class="transition-all duration-700" opacity="0" /> | ||
| <line id="edge-ceo-pm" x1="210" y1="78" x2="262" y2="145" stroke="#a78bfa" stroke-width="0.8" stroke-opacity="0.25" stroke-dasharray="3 3" class="transition-all duration-700" opacity="0" /> | ||
| <line id="edge-ceo-ux" x1="210" y1="78" x2="365" y2="145" stroke="#a78bfa" stroke-width="0.8" stroke-opacity="0.25" stroke-dasharray="3 3" class="transition-all duration-700" opacity="0" /> | ||
| <line id="edge-cto-be1" x1="57" y1="167" x2="57" y2="175" stroke="#a78bfa" stroke-width="0.6" stroke-opacity="0.2" class="transition-all duration-700" opacity="0" /> | ||
| <line id="edge-cto-be2" x1="57" y1="167" x2="152" y2="175" stroke="#a78bfa" stroke-width="0.6" stroke-opacity="0.2" class="transition-all duration-700" opacity="0" /> | ||
| <line id="edge-cto-fe" x1="57" y1="167" x2="107" y2="207" stroke="#a78bfa" stroke-width="0.6" stroke-opacity="0.2" class="transition-all duration-700" opacity="0" /> | ||
|
|
||
| <!-- Communication edges (animated) --> | ||
| <line id="edge-comm1" x1="155" y1="188" x2="220" y2="196" stroke="#2dd4bf" stroke-width="1.2" stroke-opacity="0" stroke-dasharray="5 3" class="transition-all duration-700"> | ||
| <animate attributeName="stroke-dashoffset" from="0" to="-16" dur="1.5s" repeatCount="indefinite" /> | ||
| </line> | ||
| <line id="edge-comm2" x1="305" y1="160" x2="325" y2="160" stroke="#2dd4bf" stroke-width="1.2" stroke-opacity="0" stroke-dasharray="5 3" class="transition-all duration-700"> | ||
| <animate attributeName="stroke-dashoffset" from="0" to="-16" dur="2s" repeatCount="indefinite" /> | ||
| </line> | ||
|
|
||
| <!-- Task flow (step 2) --> | ||
| <line id="edge-task" x1="210" y1="78" x2="57" y2="137" stroke="#a78bfa" stroke-width="1.5" stroke-opacity="0" class="transition-all duration-700"> | ||
| <animate attributeName="stroke-dashoffset" from="0" to="-12" dur="1s" repeatCount="indefinite" /> | ||
| </line> | ||
|
|
||
| <!-- Metrics panel (step 4) --> | ||
| <g id="metrics-group" opacity="0" class="transition-all duration-700"> | ||
| <rect x="40" y="325" width="340" height="45" rx="6" fill="#1a1f2e" stroke="#2dd4bf" stroke-width="0.5" stroke-opacity="0.3" /> | ||
| <text x="60" y="344" fill="#a78bfa" font-size="8" font-family="'JetBrains Mono', monospace">12 agents</text> | ||
| <text x="140" y="344" fill="#10b981" font-size="8" font-family="'JetBrains Mono', monospace">47 tasks</text> | ||
| <text x="210" y="344" fill="#2dd4bf" font-size="8" font-family="'JetBrains Mono', monospace">EUR 18.92</text> | ||
| <text x="300" y="344" fill="#f59e0b" font-size="8" font-family="'JetBrains Mono', monospace">14% coord</text> | ||
| <rect x="60" y="352" width="70" height="3" rx="1.5" fill="#a78bfa" opacity="0.3" /> | ||
| <rect x="60" y="352" width="50" height="3" rx="1.5" fill="#a78bfa" /> | ||
| <rect x="155" y="352" width="70" height="3" rx="1.5" fill="#10b981" opacity="0.3" /> | ||
| <rect x="155" y="352" width="48" height="3" rx="1.5" fill="#10b981" /> | ||
| <rect x="250" y="352" width="70" height="3" rx="1.5" fill="#2dd4bf" opacity="0.3" /> | ||
| <rect x="250" y="352" width="57" height="3" rx="1.5" fill="#2dd4bf" /> | ||
| </g> | ||
| </svg> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </section> | ||
|
|
||
| <script> | ||
| const steps = document.querySelectorAll<HTMLDivElement>(".scroll-step"); | ||
| const dots = document.querySelectorAll<HTMLButtonElement>(".step-dot"); | ||
|
|
||
| const labels = [ | ||
| "Pick a Template", | ||
| "Agents Auto-Configured", | ||
| "Agents Collaborate", | ||
| "Observe Everything", | ||
| ]; | ||
|
|
||
| // SVG elements | ||
| const vizLabel = document.getElementById("viz-label"); | ||
| const allNodes = [ | ||
| "node-ceo", "node-cto", "node-be1", "node-be2", "node-fe", | ||
| "node-pm", "node-sm", "node-ux", "node-ui", "node-qa", | ||
| ].map((id) => document.getElementById(id)); | ||
| const allDepts = ["dept-exec", "dept-eng", "dept-product", "dept-design", "dept-qa"] | ||
| .map((id) => document.getElementById(id)); | ||
| const deptLabels = document.querySelectorAll<SVGTextElement>(".dept-label"); | ||
| const allEdges = [ | ||
| "edge-ceo-cto", "edge-ceo-pm", "edge-ceo-ux", | ||
| "edge-cto-be1", "edge-cto-be2", "edge-cto-fe", | ||
| ].map((id) => document.getElementById(id)); | ||
| const edgeComm1 = document.getElementById("edge-comm1"); | ||
| const edgeComm2 = document.getElementById("edge-comm2"); | ||
| const edgeTask = document.getElementById("edge-task"); | ||
| const metricsGroup = document.getElementById("metrics-group"); | ||
|
|
||
| const statusIds = ["status-ceo", "status-cto", "status-be1", "status-be2", "status-fe", | ||
| "status-pm", "status-sm", "status-ux", "status-ui", "status-qa"]; | ||
| const statusEls = statusIds.map((id) => document.getElementById(id)); | ||
|
|
||
| let currentStep = -1; | ||
|
|
||
| function setStep(step: number): void { | ||
| if (step === currentStep) return; | ||
| currentStep = step; | ||
|
|
||
| // Update code step highlighting | ||
| steps.forEach((s, i) => { | ||
| const inner = s.firstElementChild as HTMLElement; | ||
| const codeBox = inner?.querySelector("[data-code-box]") as HTMLElement; | ||
| if (i === step) { | ||
| inner.classList.remove("opacity-40", "scale-[0.98]"); | ||
| inner.classList.add("opacity-100", "scale-100"); | ||
| if (codeBox) { | ||
| codeBox.classList.remove("border-l-transparent"); | ||
| codeBox.classList.add("border-l-violet-500/40"); | ||
| } | ||
| } else { | ||
| inner.classList.add("opacity-40", "scale-[0.98]"); | ||
| inner.classList.remove("opacity-100", "scale-100"); | ||
| if (codeBox) { | ||
| codeBox.classList.add("border-l-transparent"); | ||
| codeBox.classList.remove("border-l-violet-500/40"); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| // Update dots | ||
| dots.forEach((d, i) => { | ||
| if (i === step) { | ||
| d.classList.remove("border-white/20", "text-gray-500"); | ||
| d.classList.add("border-violet-400", "text-violet-400", "bg-violet-400/10"); | ||
| } else { | ||
| d.classList.add("border-white/20", "text-gray-500"); | ||
| d.classList.remove("border-violet-400", "text-violet-400", "bg-violet-400/10"); | ||
| } | ||
| }); | ||
|
|
||
| // Update label | ||
| if (vizLabel) vizLabel.textContent = labels[step] || ""; | ||
|
|
||
| const show = (el: Element | null) => el?.setAttribute("opacity", "1"); | ||
| const hide = (el: Element | null) => el?.setAttribute("opacity", "0"); | ||
| const setFill = (el: Element | null, color: string) => el?.setAttribute("fill", color); | ||
|
|
||
| // Reset all | ||
| allNodes.forEach(hide); | ||
| allDepts.forEach(hide); | ||
| deptLabels.forEach((el) => el.setAttribute("opacity", "0")); | ||
| allEdges.forEach(hide); | ||
| edgeComm1?.setAttribute("stroke-opacity", "0"); | ||
| edgeComm2?.setAttribute("stroke-opacity", "0"); | ||
| edgeTask?.setAttribute("stroke-opacity", "0"); | ||
| hide(metricsGroup); | ||
| statusEls.forEach((el) => setFill(el, "#94a3b8")); | ||
|
|
||
| if (step === 0) { | ||
| // Step 1: Template selection -- show empty department frames only | ||
| allDepts.forEach(show); | ||
| deptLabels.forEach((el) => el.setAttribute("opacity", "0.5")); | ||
| } | ||
|
|
||
| if (step === 1) { | ||
| // Step 2: Agents configured -- departments + agents appear + hierarchy edges | ||
| allDepts.forEach(show); | ||
| deptLabels.forEach((el) => el.setAttribute("opacity", "0.5")); | ||
| allNodes.forEach(show); | ||
| allEdges.forEach(show); | ||
| } | ||
|
|
||
| if (step === 2) { | ||
| // Step 3: Collaboration -- agents active, communication flowing, tasks delegated | ||
| allDepts.forEach(show); | ||
| deptLabels.forEach((el) => el.setAttribute("opacity", "0.5")); | ||
| allNodes.forEach(show); | ||
| allEdges.forEach(show); | ||
| edgeTask?.setAttribute("stroke-opacity", "0.5"); | ||
| edgeTask?.setAttribute("stroke-dasharray", "5 3"); | ||
| edgeComm1?.setAttribute("stroke-opacity", "0.5"); | ||
| edgeComm2?.setAttribute("stroke-opacity", "0.5"); | ||
| setFill(statusEls[0], "#a78bfa"); // CEO directing | ||
| setFill(statusEls[1], "#a78bfa"); // CTO directing | ||
| setFill(statusEls[2], "#2dd4bf"); // BE1 working | ||
| setFill(statusEls[3], "#2dd4bf"); // BE2 working | ||
| setFill(statusEls[4], "#2dd4bf"); // FE working | ||
| setFill(statusEls[5], "#a78bfa"); // PM directing | ||
| setFill(statusEls[7], "#10b981"); // UX done | ||
| setFill(statusEls[9], "#f59e0b"); // QA reviewing | ||
| } | ||
|
|
||
| if (step === 3) { | ||
| // Step 4: Observe -- all done, metrics visible | ||
| allDepts.forEach(show); | ||
| deptLabels.forEach((el) => el.setAttribute("opacity", "0.5")); | ||
| allNodes.forEach(show); | ||
| allEdges.forEach(show); | ||
| show(metricsGroup); | ||
| statusEls.forEach((el) => setFill(el, "#10b981")); | ||
| } | ||
| } | ||
|
|
||
| // Dot click navigation | ||
| dots.forEach((dot) => { | ||
| dot.addEventListener("click", () => { | ||
| const stepIdx = parseInt(dot.dataset.dot || "0", 10); | ||
| const target = steps[stepIdx]; | ||
| if (target) { | ||
| target.scrollIntoView({ behavior: "smooth", block: "center" }); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| // Reduced motion: disable SVG SMIL animations | ||
| const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)"); | ||
|
|
||
| function disableSvgAnimations(): void { | ||
| document.querySelectorAll<SVGElement>("#sync-viz animate").forEach((el) => { | ||
| el.parentNode?.removeChild(el); | ||
| }); | ||
| } | ||
|
|
||
| if (prefersReduced.matches) { | ||
| disableSvgAnimations(); | ||
| setStep(0); | ||
| } else { | ||
| const observer = new IntersectionObserver( | ||
| (entries) => { | ||
| const active = entries | ||
| .filter((e) => e.isIntersecting) | ||
| .sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0]; | ||
| if (!active) return; | ||
| const step = parseInt((active.target as HTMLElement).dataset.step || "0", 10); | ||
| setStep(step); | ||
| }, | ||
| { | ||
| rootMargin: "-40% 0px -40% 0px", | ||
| threshold: [0, 0.25, 0.5, 0.75, 1], | ||
| } | ||
| ); | ||
|
|
||
| steps.forEach((step) => observer.observe(step)); | ||
| document.addEventListener("astro:before-swap", () => observer.disconnect(), { once: true }); | ||
| setStep(0); | ||
| } | ||
| </script> |
There was a problem hiding this comment.
The component and its internal SVG use numerous hardcoded IDs (e.g., sync-viz, viz-label, node-ceo) which are then accessed via document.getElementById in the script. This pattern breaks component reusability and will cause functional bugs if multiple instances are present on the page (e.g., the script will only animate the first SVG found). Use data- attributes and relative DOM traversal, or generate unique IDs per instance.
| fill="url(#dp-sparkGrad)" | ||
| stroke="none" | ||
| /> | ||
| <defs> | ||
| <linearGradient id="dp-sparkGrad" x1="0" y1="0" x2="0" y2="1"> |
There was a problem hiding this comment.
The SVG linearGradient uses a hardcoded ID dp-sparkGrad. In React, hardcoded IDs in SVG definitions can lead to collisions if the component is rendered multiple times or during client-side navigation (like Astro View Transitions), causing rendering artifacts where the wrong gradient is applied. Use the useId hook to generate a unique ID for the gradient definition.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/ExpandableArchitecture.astro`:
- Around line 145-167: The accordion buttons (elements using data-arch-toggle /
id `btn-${arch.id}`) lack Up/Down arrow key navigation per WAI-ARIA; add a
keydown handler on these buttons that listens for ArrowUp/ArrowDown (and
optionally Home/End), prevents default, finds the list of all data-arch-toggle
buttons in the same accordion group, computes the previous/next (wrap around)
index relative to the current `btn-${arch.id}`, and moves focus to that target
button while leaving aria-expanded behavior unchanged; implement this central
handler in the component script (or a small helper function) and attach it to
the button element so keyboard users can navigate headers with arrow keys.
In `@site/src/components/islands/DashboardPreview.tsx`:
- Around line 168-178: The Prev/Next button handlers in DashboardPreview.tsx
still include conditional logic inside onClick (using activeTab and selectTab)
even though the button is disabled via the disabled prop; remove the redundant
conditional by only attaching the onClick when the button is enabled (e.g., set
onClick to a function that calls selectTab(activeTab - 1) / selectTab(activeTab
+ 1) only if not disabled) or attach a no-op when disabled; update both the
previous button (uses activeTab and selectTab) and the corresponding next button
block (the code around lines 200-210) so the handler is not executed/created
when disabled.
In `@site/src/components/islands/mini/BudgetMini.tsx`:
- Around line 125-130: Move the SVG <defs> block that defines the gradient id
"dp-sparkGrad" so it appears before any elements that reference it (e.g., the
<polyline> that uses "url(`#dp-sparkGrad`)"). Locate the <defs> in BudgetMini (the
block with linearGradient id="dp-sparkGrad") and cut/paste it to the top of the
SVG element (immediately after the opening <svg> tag) to follow conventional
ordering and improve readability.
In `@site/src/components/ParticleNetwork.astro`:
- Around line 61-75: The resize() function uses a non-null assertion on
canvas.parentElement! which can throw if the DOM changes; update resize() to
guard against a missing parent by retrieving const parent = canvas.parentElement
and if (!parent) return (or fallback to canvas.getBoundingClientRect()/default
dimensions), then use parent.getBoundingClientRect() instead of parentElement!.
Also apply the same defensive check wherever canvas.parentElement! is used
(e.g., the other occurrence referenced in the review) so the code safely handles
a missing parent without throwing.
In `@site/src/components/ScrollSyncPanel.astro`:
- Around line 425-456: The code currently removes SVG <animate> elements
permanently when the MediaQueryList prefersReduced.matches is true; add a
listener on the prefersReduced MediaQueryList
(prefersReduced.addEventListener('change' / prefersReduced.onchange)) to handle
dynamic preference changes: when event.matches is true call
disableSvgAnimations(), and when false re-enable animations by re-initializing
the visualization (the same logic that originally injects the SVG <animate>
elements) or as a minimal fallback trigger a component reload (e.g., re-run the
setup that creates the SVG animations or force a page/component refresh). Update
the block around prefersReduced, disableSvgAnimations, and the
IntersectionObserver setup so enabling/disabling motion toggles animations and
step behavior reliably without requiring a full manual page reload.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: fc664c4e-1572-420a-acc4-68c431b07079
⛔ Files ignored due to path filters (1)
site/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (16)
CLAUDE.mdsite/astro.config.mjssite/package.jsonsite/src/components/ExpandableArchitecture.astrosite/src/components/FeatureShowcase.astrosite/src/components/ParticleNetwork.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/UseCaseCards.astrosite/src/components/islands/DashboardPreview.csssite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/layouts/Base.astrosite/src/pages/index.astro
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Agent
- GitHub Check: Analyze (python)
- GitHub Check: Dependency Review
🧰 Additional context used
🧠 Learnings (44)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/package.json : Web dashboard Node.js 22+, TypeScript 6.0+, dependencies in `web/package.json`
Applied to files:
site/package.jsonCLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to web/package.json : Web dashboard Node.js 20+; dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)
Applied to files:
site/package.jsonCLAUDE.mdsite/astro.config.mjs
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Applied to files:
site/package.jsonCLAUDE.mdsite/astro.config.mjssite/src/components/islands/DashboardPreview.tsxsite/src/pages/index.astro
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
Applied to files:
site/package.jsonCLAUDE.md
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/.storybook/{main,preview}.{ts,tsx} : Storybook 10: Use `defineMain` from `storybook/react-vite/node` and `definePreview` from `storybook/react-vite` in Storybook config files
Applied to files:
site/package.jsonsite/astro.config.mjs
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{ts,tsx} : CSS side-effect imports need type declarations; use Vite's `/// <reference types="vite/client" />` directive
Applied to files:
site/package.jsonsite/astro.config.mjs
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Web dashboard: see `web/CLAUDE.md` for commands, design system, and component inventory
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/api/**/*.md : Library reference in `docs/api/` (auto-generated via mkdocstrings + Griffe, AST-based)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to {docs/rest-api.md,docs/_generated/api-reference.html} : REST API reference in `docs/rest-api.md` + `docs/_generated/api-reference.html` (generated by `scripts/export_openapi.py`)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to pyproject.toml : Docs group in `pyproject.toml` includes: `zensical`, `mkdocstrings[python]`, `griffe-pydantic`
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to scripts/**/*.py : Scripts in `scripts/` (CI/build utilities and development-time validation hooks) — relaxed ruff rules: `print` and deferred imports allowed
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
CLAUDE.mdsite/src/components/UseCaseCards.astrosite/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/pages/index.astrosite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets.
Applied to files:
CLAUDE.mdsite/src/components/islands/DashboardPreview.css
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).
Applied to files:
CLAUDE.mdsite/src/pages/index.astrosite/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Install via `uv sync` (installs all deps including dev group by default)
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Use `uv sync` to install all dependencies (dev + test groups).
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to web/** : Use Node.js 22+ and TypeScript 6.0+ for web dashboard.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-21T12:54:22.557Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T12:54:22.557Z
Learning: Go 1.26+ required; CLI dependencies in `cli/go.mod` (Cobra, charmbracelet/huh, charmbracelet/lipgloss, sigstore-go, go-containerregistry, go-tuf)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `font-sans` or `font-mono` for typography (maps to Geist tokens). NEVER set `fontFamily` directly
Applied to files:
site/src/layouts/Base.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT build card-with-header layouts from scratch -- use `<SectionCard>` component
Applied to files:
site/src/components/UseCaseCards.astrosite/src/pages/index.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/UseCaseCards.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/UseCaseCards.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/DashboardPreview.css
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Create a `.stories.tsx` Storybook file alongside each new shared component with all states (default, hover, loading, error, empty)
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. DESIGN_SPEC.md is a pointer file linking to the 7 design pages (index, agents, organization, communication, engine, memory, operations).
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Security: SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume).
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/security/**/*.py : Security module includes SecOps agent, rule engine (soft-allow/hard-deny), audit log, output scanner, risk classifier, autonomy levels (4 strategies), timeout policies.
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Gitleaks scans for secrets via pre-commit hook and weekly CI job
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
🔇 Additional comments (21)
site/src/layouts/Base.astro (1)
52-68: Geist fonts are not available on Google Fonts.Geist and Geist Mono are Vercel's proprietary fonts and are not hosted on Google Fonts. These requests will fail silently, falling back to Inter/JetBrains Mono. To use Geist, you need to either:
- Self-host the fonts (download from vercel/geist-font)
- Use
@fontsource/geist-sansand@fontsource/geist-mononpm packages[raise_major_issue, request_verification]
Is the Geist font family available on Google Fonts?site/src/components/islands/DashboardPreview.css (1)
1-107: Well-structured CSS with proper reduced-motion support.The stylesheet provides:
- Consistent CSS custom properties for theming
- Smooth animations for page transitions, counters, pulse effects, and scrolling
- Comprehensive
prefers-reduced-motionhandling that disables all animationsNote: The font stack references Geist fonts (line 15-16) which depend on the font loading fix needed in
Base.astro.site/src/components/UseCaseCards.astro (1)
72-98: Good accessibility and responsive implementation.The scrollable card region properly includes:
role="region"andaria-labelfor screen readerstabindex="0"enabling keyboard scrolling- Snap-scroll behavior on mobile with grid layout on larger screens
- Dynamic color theming per card
site/src/components/FeatureShowcase.astro (1)
89-127: Proper keyboard accessibility with focus-visible rings.Both hero and compact feature cards implement:
focus-visible:outline-nonewithfocus-visible:ring-2for keyboard navigation- Color-coordinated ring colors matching the card theme
- Proper
ring-offsetfor visual claritysite/src/components/islands/mini/OrgChartMini.tsx (1)
26-109: Well-implemented React island with proper reduced-motion handling.The component:
- Uses
matchMediato detect and respond to motion preference changes- Properly cleans up the event listener on unmount
- Conditionally disables SVG
<animate>when reduced motion is preferred- Marks the decorative SVG as
aria-hidden="true"site/src/components/islands/mini/AgentDetailMini.tsx (1)
92-108: Index as key is acceptable here for static display list.While using array index as a React key is generally discouraged, it's acceptable in this case because:
- The activities array is static and never reorders
- It's duplicated purely for the infinite scroll visual effect
- No items are added/removed/filtered dynamically
The
dp-activity-scrollanimation respects reduced-motion viaDashboardPreview.css.site/src/components/ScrollSyncPanel.astro (1)
119-133: Good accessibility implementation for step navigation.The dot buttons include:
- Proper
aria-labelattributes describing each step's purpose- Keyboard accessibility via native
<button>elements- Visual hover/focus states via Tailwind classes
site/src/components/ParticleNetwork.astro (2)
158-182: Excellent reduced-motion implementation with dynamic toggling.Unlike
ScrollSyncPanel.astro, this component properly handles runtime changes to motion preferences:
- Listens for
changeevents on thematchMediaquery- Stops animation and draws a static frame when reduced-motion is enabled
- Resumes animation when reduced-motion is disabled
- Cleans up the listener on view transitions
209-215: Proper cleanup on Astro view transitions.The
astro:before-swaplistener correctly cleans up:
- ResizeObserver disconnection
- Debounce timer clearance
- Animation flag reset
- Motion preference event listener removal
Note: This cleanup only fires if Astro View Transitions are enabled. Per the relevant snippet from
ScrollSyncPanel.astro, both components rely on this event. Ensure<ViewTransitions />is included in the layout, or resources may leak on traditional navigation.[approve_code_changes, request_verification]
#!/bin/bash # Verify ViewTransitions is enabled in the layout or pages rg -n "ViewTransitions" --type astro -g '*.astro'site/src/components/islands/mini/BudgetMini.tsx (1)
12-18: LGTM! Clean gauge calculation logic.The gauge value clamping, derived metrics, and SVG arc math are correctly implemented. The half-circle circumference formula (
Math.PI * radius) and dash offset calculation properly animate the fill arc based on the tick-driven percentage.site/astro.config.mjs (1)
4-4: LGTM! React integration correctly configured.The
@astrojs/reactimport and registration in the integrations array follow Astro v5+ conventions. Using default options is appropriate for the dashboard preview island use case.Also applies to: 11-11
site/package.json (1)
12-25: LGTM! Dependencies correctly declared.React runtime dependencies (
react,react-dom) and the Astro integration (@astrojs/react) are properly added with appropriate version ranges. TypeScript type definitions are correctly placed indevDependencies.CLAUDE.md (1)
63-64: LGTM! Documentation accurately reflects code changes.The updates to the landing page description, package structure, and dependencies section are consistent with the actual implementation and follow the existing documentation style.
Also applies to: 109-110, 236-236
site/src/components/ExpandableArchitecture.astro (1)
198-231: LGTM! Toggle script correctly implements accordion behavior.The script properly:
- Collapses all panels before expanding the clicked one (single-expand behavior)
- Manages
aria-expanded,aria-hidden, andinertattributes correctly- Uses CSS grid-rows transition for smooth animation
site/src/components/islands/mini/TaskBoardMini.tsx (2)
1-80: LGTM! Clean Kanban mini-board implementation.The component structure is well-organized with clear separation between the
MiniCardsubcomponent and the mainTaskBoardMini. The highlight logic usingtick % 6creates a subtle animation effect alternating between two cards.
82-130: LGTM! Grid layout and footer are correctly implemented.The 4-column grid layout works well for the Kanban visualization. Column headers with task counts and optional WIP badges provide useful context.
site/src/components/islands/DashboardPreview.tsx (2)
31-44: LGTM! Timer effects correctly manage cleanup.Both the auto-cycle (6s) and animation tick (1Hz) effects properly clear their intervals on cleanup. The
isPauseddependency correctly restarts/stops the auto-cycle timer.
118-146: Tab navigation follows WAI-ARIA tab pattern correctly.The tablist/tab roles,
aria-selected, andaria-controlsare correctly implemented. Each tab button properly references the shared tabpanel, and the active tab is visually distinguished.site/src/pages/index.astro (3)
4-9: LGTM! Component imports are correctly structured.All new Astro components and the React island import follow Astro conventions. The DashboardPreview import path correctly references the TSX file in the islands directory.
220-220: Excellent use ofclient:visiblefor the React island.Using
client:visibleensures React only loads when the dashboard preview section enters the viewport, keeping above-the-fold JS minimal (~2KB as stated in PR objectives). This is the optimal hydration strategy for a below-fold interactive component.
156-161: LGTM! Security section accurately describes the hybrid SecOps model.The updated text correctly reflects the rule-engine + LLM fallback architecture with 5 autonomy tiers. The phrasing aligns with the design spec's security model.
| <button | ||
| id={`btn-${arch.id}`} | ||
| data-arch-toggle | ||
| aria-expanded="false" | ||
| aria-controls={`panel-${arch.id}`} | ||
| class="w-full bg-[#1a1f2e] rounded-xl p-6 border border-white/10 hover:border-violet-500/30 transition-colors text-left group cursor-pointer" | ||
| > | ||
| <div class="flex items-center justify-between"> | ||
| <div> | ||
| <p class="font-semibold text-violet-400">{arch.title}</p> | ||
| <p class="text-xs text-gray-400 mt-1">{arch.summary}</p> | ||
| </div> | ||
| <svg | ||
| class="w-4 h-4 text-gray-500 transition-transform duration-300 group-aria-expanded:rotate-180 shrink-0 ml-2" | ||
| fill="none" | ||
| viewBox="0 0 24 24" | ||
| stroke="currentColor" | ||
| stroke-width="2" | ||
| > | ||
| <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" /> | ||
| </svg> | ||
| </div> | ||
| </button> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Accordion buttons missing keyboard accessibility for arrow key navigation.
The toggle buttons work correctly for click and basic keyboard (Enter/Space), but the WAI-ARIA accordion pattern recommends arrow key navigation between accordion headers. This is a minor accessibility enhancement rather than a blocker.
If you want full WAI-ARIA accordion compliance, add keydown handlers for Up/Down arrows to move focus between buttons. However, the current implementation is functional and accessible for most users.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/ExpandableArchitecture.astro` around lines 145 - 167, The
accordion buttons (elements using data-arch-toggle / id `btn-${arch.id}`) lack
Up/Down arrow key navigation per WAI-ARIA; add a keydown handler on these
buttons that listens for ArrowUp/ArrowDown (and optionally Home/End), prevents
default, finds the list of all data-arch-toggle buttons in the same accordion
group, computes the previous/next (wrap around) index relative to the current
`btn-${arch.id}`, and moves focus to that target button while leaving
aria-expanded behavior unchanged; implement this central handler in the
component script (or a small helper function) and attach it to the button
element so keyboard users can navigate headers with arrow keys.
| // Reduced motion: disable SVG SMIL animations | ||
| const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)"); | ||
|
|
||
| function disableSvgAnimations(): void { | ||
| document.querySelectorAll<SVGElement>("#sync-viz animate").forEach((el) => { | ||
| el.parentNode?.removeChild(el); | ||
| }); | ||
| } | ||
|
|
||
| if (prefersReduced.matches) { | ||
| disableSvgAnimations(); | ||
| setStep(0); | ||
| } else { | ||
| const observer = new IntersectionObserver( | ||
| (entries) => { | ||
| const active = entries | ||
| .filter((e) => e.isIntersecting) | ||
| .sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0]; | ||
| if (!active) return; | ||
| const step = parseInt((active.target as HTMLElement).dataset.step || "0", 10); | ||
| setStep(step); | ||
| }, | ||
| { | ||
| rootMargin: "-40% 0px -40% 0px", | ||
| threshold: [0, 0.25, 0.5, 0.75, 1], | ||
| } | ||
| ); | ||
|
|
||
| steps.forEach((step) => observer.observe(step)); | ||
| document.addEventListener("astro:before-swap", () => observer.disconnect(), { once: true }); | ||
| setStep(0); | ||
| } |
There was a problem hiding this comment.
Reduced-motion preference changes are not handled dynamically.
When prefers-reduced-motion is initially true, the SVG <animate> elements are permanently removed from the DOM. If the user later disables reduced-motion (without page reload), animations cannot be restored.
Consider listening for motion preference changes like ParticleNetwork.astro does, or document that a page reload is required. This is a minor edge case since most users don't toggle this setting mid-session.
🔧 Optional: Add dynamic motion preference handling
+ prefersReduced.addEventListener("change", (e) => {
+ if (e.matches) {
+ disableSvgAnimations();
+ }
+ // Note: Can't restore removed <animate> elements without re-rendering SVG
+ });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/ScrollSyncPanel.astro` around lines 425 - 456, The code
currently removes SVG <animate> elements permanently when the MediaQueryList
prefersReduced.matches is true; add a listener on the prefersReduced
MediaQueryList (prefersReduced.addEventListener('change' /
prefersReduced.onchange)) to handle dynamic preference changes: when
event.matches is true call disableSvgAnimations(), and when false re-enable
animations by re-initializing the visualization (the same logic that originally
injects the SVG <animate> elements) or as a minimal fallback trigger a component
reload (e.g., re-run the setup that creates the SVG animations or force a
page/component refresh). Update the block around prefersReduced,
disableSvgAnimations, and the IntersectionObserver setup so enabling/disabling
motion toggles animations and step behavior reliably without requiring a full
manual page reload.
There was a problem hiding this comment.
Pull request overview
This PR upgrades the Astro landing page (site/) with several interactive sections (Canvas hero background, scroll-synced “How it Works”, expandable architecture, scrollable use cases, and a React “dashboard preview” island), and refreshes the content to better reflect the product flow and feature set.
Changes:
- Added new interactive landing page components (Astro + client scripts + a React island for the dashboard preview).
- Replaced the “Core Pillars” section with a richer “Feature Showcase” card grid.
- Added React islands support to the site (Astro integration + React deps) and updated base layout fonts/documentation accordingly.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| site/src/pages/index.astro | Wires in the new interactive sections and updated landing copy/layout. |
| site/src/layouts/Base.astro | Updates font loading to include Geist/Geist Mono alongside existing fonts. |
| site/src/components/UseCaseCards.astro | Adds horizontally scrollable/snap use case cards (mobile) with desktop grid layout. |
| site/src/components/ScrollSyncPanel.astro | Implements the scroll-synced 4-step split panel with sticky SVG visualization. |
| site/src/components/ParticleNetwork.astro | Adds the Canvas particle network hero background animation. |
| site/src/components/islands/DashboardPreview.tsx | Adds the React island mock dashboard with tab auto-cycling + controls. |
| site/src/components/islands/DashboardPreview.css | Styling + motion-reduction rules for the dashboard preview. |
| site/src/components/islands/mini/*.tsx | Four mini “pages” used by the dashboard preview island. |
| site/src/components/FeatureShowcase.astro | New feature showcase (hero cards + compact cards) with docs links. |
| site/src/components/ExpandableArchitecture.astro | Expandable architecture accordion component (one-at-a-time panels). |
| site/package.json | Adds @astrojs/react, React 19, and React type deps. |
| site/package-lock.json | Lockfile updates for the new React/Astro React dependencies. |
| site/astro.config.mjs | Enables React integration for Astro islands. |
| CLAUDE.md | Updates repository documentation to reflect React islands in site/. |
Files not reviewed (1)
- site/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)
site/package-lock.json:23
package.jsonlists@types/react/@types/react-domunderdevDependencies, butpackage-lock.jsoncurrently records them under the rootdependenciessection. This looks like an out-of-sync lockfile and can cause the types packages to be installed in production installs; please regenerate the lockfile so dependency sections match.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| setStep(0); | ||
| } else { | ||
| const observer = new IntersectionObserver( | ||
| (entries) => { | ||
| for (const entry of entries) { | ||
| if (entry.isIntersecting) { | ||
| const step = parseInt((entry.target as HTMLElement).dataset.step || "0", 10); | ||
| setStep(step); | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| rootMargin: "-45% 0px -45% 0px", | ||
| threshold: 0.5, | ||
| } | ||
| ); | ||
|
|
||
| steps.forEach((step) => observer.observe(step)); | ||
| document.addEventListener("astro:before-swap", () => observer.disconnect(), { once: true }); | ||
| setStep(0); | ||
| } |
There was a problem hiding this comment.
prefers-reduced-motion branch disables SMIL but also skips setting up the IntersectionObserver, so the visualization/code highlighting never advances past step 0 for reduced-motion users (dot clicks also won't update state because setStep() is only called once). Consider still wiring the observer and just disabling animations / using non-smooth scrolling when reduced motion is enabled.
| setStep(0); | |
| } else { | |
| const observer = new IntersectionObserver( | |
| (entries) => { | |
| for (const entry of entries) { | |
| if (entry.isIntersecting) { | |
| const step = parseInt((entry.target as HTMLElement).dataset.step || "0", 10); | |
| setStep(step); | |
| } | |
| } | |
| }, | |
| { | |
| rootMargin: "-45% 0px -45% 0px", | |
| threshold: 0.5, | |
| } | |
| ); | |
| steps.forEach((step) => observer.observe(step)); | |
| document.addEventListener("astro:before-swap", () => observer.disconnect(), { once: true }); | |
| setStep(0); | |
| } | |
| } | |
| const observer = new IntersectionObserver( | |
| (entries) => { | |
| const active = entries | |
| .filter((e) => e.isIntersecting) | |
| .sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0]; | |
| if (!active) return; | |
| const step = parseInt((active.target as HTMLElement).dataset.step || "0", 10); | |
| setStep(step); | |
| }, | |
| { | |
| rootMargin: "-40% 0px -40% 0px", | |
| threshold: [0, 0.25, 0.5, 0.75, 1], | |
| } | |
| ); | |
| steps.forEach((step) => observer.observe(step)); | |
| document.addEventListener("astro:before-swap", () => observer.disconnect(), { once: true }); | |
| setStep(0); |
| title: "100+ LLM Providers", | ||
| description: | ||
| "11 built-in presets, hot-reload management, quota-aware routing, automatic fallback chains.", | ||
| href: "/docs/design/providers/", |
There was a problem hiding this comment.
The compact feature links point to /docs/design/providers/, but there is no corresponding docs/design/providers.md in the repo (provider docs appear to live under docs/api/providers.md and/or docs/design/operations.md#providers). This will likely produce a broken link in the built docs site—please update the href to an existing docs route.
| href: "/docs/design/providers/", | |
| href: "/docs/api/providers/", |
| href: "/docs/design/budget/", | ||
| }, | ||
| { | ||
| title: "Tool Sandboxing", | ||
| description: | ||
| "Subprocess or Docker isolation per tool category. Explicit network controls. MCP protocol support.", | ||
| href: "/docs/design/tools/", |
There was a problem hiding this comment.
Several compact feature links use /docs/design/.../ routes that don't exist in docs/design/ (e.g., budget and tools are under docs/api/* or docs/guides/*, not docs/design/*). Updating these hrefs to existing pages will prevent broken links from the landing page.
| href: "/docs/design/budget/", | |
| }, | |
| { | |
| title: "Tool Sandboxing", | |
| description: | |
| "Subprocess or Docker isolation per tool category. Explicit network controls. MCP protocol support.", | |
| href: "/docs/design/tools/", | |
| href: "/docs/api/budget/", | |
| }, | |
| { | |
| title: "Tool Sandboxing", | |
| description: | |
| "Subprocess or Docker isolation per tool category. Explicit network controls. MCP protocol support.", | |
| href: "/docs/api/tools/", |
| { | ||
| name: "Tool System", | ||
| description: "Sandboxed execution (subprocess/Docker), MCP protocol, git SSRF prevention, per-category isolation.", | ||
| href: "/docs/design/tools/", |
There was a problem hiding this comment.
Tool System links to /docs/design/tools/, but there is no docs/design/tools.md in the repo (tool docs appear under docs/api/tools.md and docs/guides/mcp-tools.md). This href is likely to 404 in the generated docs site; please point it at an existing route.
| href: "/docs/design/tools/", | |
| href: "/docs/api/tools/", |
| href: "/docs/design/providers/", | ||
| }, | ||
| { | ||
| name: "Smart Routing", | ||
| description: "Multi-provider resolution, quota-aware selection, fallback chains, task-type model rules.", | ||
| href: "/docs/design/providers/", |
There was a problem hiding this comment.
LLM Providers / Smart Routing submodules link to /docs/design/providers/, but there is no docs/design/providers.md in the repo (provider docs appear under docs/api/providers.md and docs/design/operations.md#providers). This will likely be a broken link from the landing page—please update the href to a real docs page.
| href: "/docs/design/providers/", | |
| }, | |
| { | |
| name: "Smart Routing", | |
| description: "Multi-provider resolution, quota-aware selection, fallback chains, task-type model rules.", | |
| href: "/docs/design/providers/", | |
| href: "/docs/api/providers/", | |
| }, | |
| { | |
| name: "Smart Routing", | |
| description: "Multi-provider resolution, quota-aware selection, fallback chains, task-type model rules.", | |
| href: "/docs/design/operations/#providers", |
| { | ||
| name: "Observability", | ||
| description: "Structured logging, correlation tracking, redaction, log shipping (syslog, HTTP), compressed archival.", | ||
| href: "/docs/design/observability/", |
There was a problem hiding this comment.
Observability links to /docs/design/observability/, but there is no docs/design/observability.md in the repo (observability docs appear under docs/api/observability.md and guides like docs/guides/centralized-logging.md). This href is likely broken; please adjust it to an existing route.
| href: "/docs/design/observability/", | |
| href: "/docs/api/observability/", |
| { | ||
| name: "Budget Engine", | ||
| description: "Hierarchical cascades, 3-layer cost controls, CFO optimization, trend analysis with Theil-Sen regression.", | ||
| href: "/docs/design/budget/", |
There was a problem hiding this comment.
Budget Engine links to /docs/design/budget/, but there is no docs/design/budget.md in the repo (budget documentation appears under docs/guides/budget.md, docs/api/budget.md, and docs/design/operations.md). This will likely 404; please update the href to an existing docs page.
| href: "/docs/design/budget/", | |
| href: "/docs/design/operations/", |
| }; | ||
|
|
||
| function start(): void { | ||
| resize(); | ||
|
|
||
| if (prefersReduced.matches) { | ||
| drawStaticFrame(); | ||
| } else { | ||
| animating = true; | ||
| lastFrame = performance.now(); | ||
| requestAnimationFrame(draw); | ||
| } | ||
|
|
There was a problem hiding this comment.
The canvas animation runs continuously once started (requestAnimationFrame loop) and isn't paused when the hero scrolls out of view or when the tab becomes hidden. Consider pausing/resuming via document.visibilitychange and/or an IntersectionObserver on the canvas container to reduce CPU/battery usage on long sessions.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/DashboardPreview.tsx`:
- Around line 168-178: The previous/next buttons can call selectTab with
out-of-range indices leading PageComponent to be undefined; update the selectTab
function to validate and clamp its input (e.g., ensure newIndex is between 0 and
pages.length - 1) before updating state, and use that validated index for
setting activeTab and selecting PageComponent (references: selectTab, activeTab,
PageComponent, and the pages array used to compute PageComponent); this prevents
negative or too-large indices even if the onClick is triggered when the button
appears disabled.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 749c83b4-18ec-4108-bfe5-3b780224d45a
📒 Files selected for processing (5)
site/src/components/ParticleNetwork.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsx
📜 Review details
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/ScrollSyncPanel.astrosite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/ScrollSyncPanel.astrosite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Applied to files:
site/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Create a `.stories.tsx` Storybook file alongside each new shared component with all states (default, hover, loading, error, empty)
Applied to files:
site/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets.
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
site/src/components/ExpandableArchitecture.astro (1)
198-231:⚠️ Potential issue | 🟡 MinorArrow-key header navigation is still missing.
These controls expose accordion semantics via
aria-expanded/aria-controls, but Up/Down/Home/End handling is still absent, so keyboard users still can’t move between headers with the expected accordion keys.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/ExpandableArchitecture.astro` around lines 198 - 231, The accordion header buttons selected by document.querySelectorAll("[data-arch-toggle]") need keyboard navigation: add a keydown handler on each button (in the same loop where addEventListener("click", ... ) is registered) that checks event.key for "ArrowUp"/"ArrowLeft" and "ArrowDown"/"ArrowRight"/"Home"/"End" and moves focus to the previous/next/first/last button respectively (wrapping as appropriate), then update aria-expanded on the newly focused/activated header and toggle the associated panel (use the same aria-controls/aria-expanded logic and panel class toggles already implemented). Ensure default scrolling is prevented (event.preventDefault()) for arrow/home/end keys and that handlers reference the existing buttons NodeList and each button’s aria-controls to keep behavior consistent with the click handler.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/DashboardPreview.tsx`:
- Around line 27-28: The children rely on the shared state variable tick, so
when the visible page changes via pageKey the clock must be reset; update the
logic around pageKey (where setPageKey is called or in a useEffect watching
pageKey inside DashboardPreview) to call setTick(0) (or derive a page-local tick
instead) so each tab mounts with tick === 0; ensure you update all places that
change pageKey or mount the mini view so tick is reset on page switch.
- Around line 109-115: The header pills in DashboardPreview are hardcoded ("7
agents", "12 tasks") and diverge from the mock preview data used elsewhere;
import or reference the same mock dataset used by the mini pages (the module
that exports the preview/mock object) and replace the literal strings in the
DashboardPreview component with the dataset fields (e.g., dataset.agentsCount,
dataset.tasksCount and dataset.estimatedCost formatted as EUR) so the header
values match the mini pages and PR objectives.
- Around line 59-66: The onMouseLeave handler currently always calls
setIsPaused(false) and can resume cycling while keyboard focus remains inside
the DashboardPreview; change the onMouseLeave behavior to only unpause when the
preview does not contain the current focus (use
e.currentTarget.contains(document.activeElement) or equivalent) so it mirrors
the onBlur guard, and keep the existing onBlur logic that checks
e.relatedTarget; update the handlers in DashboardPreview.tsx (the
onMouseEnter/onMouseLeave/onFocus/onBlur block surrounding setIsPaused) so
onMouseLeave verifies focus is outside before calling setIsPaused(false).
In `@site/src/components/ParticleNetwork.astro`:
- Around line 160-169: The onMotionChange handler unconditionally restarts
animation; change it to only resume when the hero is currently visible by
checking the visibility flag or the IntersectionObserver state (e.g., an
existing isVisible or heroVisible boolean set by your observer) before setting
animating = true, updating lastFrame, or calling requestAnimationFrame(draw); if
not visible, leave animating false and do not schedule frames. Apply the same
guard to the similar block around lines 211-225 so reduced-motion toggles never
resume the loop while the hero is off-screen.
In `@site/src/components/ScrollSyncPanel.astro`:
- Around line 245-256: The SVG animations and smooth-scroll behavior are always
present in the initial HTML (e.g., the <line> elements with ids edge-comm1,
edge-comm2, edge-task and the step dot elements), causing motion for
prefers-reduced-motion users on first paint; change the markup to render static
SVG (remove or omit <animate> children and any smooth-scroll attributes/classes
in the initial server-rendered markup) and then, in the client script that
currently toggles animations, detect the media query
(window.matchMedia('(prefers-reduced-motion: no-preference)')) and only then
programmatically insert the SMIL <animate> elements into
edge-comm1/edge-comm2/edge-task (and enable smooth scrolling on step dot
elements) so reduced-motion users never receive animations on first paint.
---
Duplicate comments:
In `@site/src/components/ExpandableArchitecture.astro`:
- Around line 198-231: The accordion header buttons selected by
document.querySelectorAll("[data-arch-toggle]") need keyboard navigation: add a
keydown handler on each button (in the same loop where addEventListener("click",
... ) is registered) that checks event.key for "ArrowUp"/"ArrowLeft" and
"ArrowDown"/"ArrowRight"/"Home"/"End" and moves focus to the
previous/next/first/last button respectively (wrapping as appropriate), then
update aria-expanded on the newly focused/activated header and toggle the
associated panel (use the same aria-controls/aria-expanded logic and panel class
toggles already implemented). Ensure default scrolling is prevented
(event.preventDefault()) for arrow/home/end keys and that handlers reference the
existing buttons NodeList and each button’s aria-controls to keep behavior
consistent with the click handler.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6e0b592e-f420-477b-882f-57ac7064c5e2
📒 Files selected for processing (7)
site/src/components/ExpandableArchitecture.astrosite/src/components/FeatureShowcase.astrosite/src/components/ParticleNetwork.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (24)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. DESIGN_SPEC.md is a pointer file linking to the 7 design pages (index, agents, organization, communication, engine, memory, operations).
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-03-18T08:23:08.912Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T08:23:08.912Z
Learning: When approved deviations occur, update the relevant `docs/design/` page to reflect the new reality.
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. Do not silently diverge from the design spec -- every deviation needs explicit user approval and must be updated in the relevant design page.
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/ScrollSyncPanel.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/ExpandableArchitecture.astrosite/src/components/ScrollSyncPanel.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Export props as a TypeScript interface for new components
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Applied to files:
site/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Create a `.stories.tsx` Storybook file alongside each new shared component with all states (default, hover, loading, error, empty)
Applied to files:
site/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets.
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
site/src/components/ExpandableArchitecture.astro
| const [tick, setTick] = useState(0); | ||
| const [pageKey, setPageKey] = useState(0); |
There was a problem hiding this comment.
Reset tick when the visible page changes.
pageKey remounts the mini view, but the children derive their visible state directly from tick, so each tab still opens mid-sequence instead of from frame 0. Reset the clock on tab changes or pass a page-local tick.
Minimal fix
useEffect(() => {
if (isPaused) return;
const timer = setInterval(() => {
- setActiveTab((t) => (t + 1) % 4);
+ setActiveTab((t) => (t + 1) % pages.length);
+ setTick(0);
setPageKey((k) => k + 1);
}, 6000);
return () => clearInterval(timer);
}, [isPaused]);
@@
const selectTab = useCallback((i: number) => {
const clamped = Math.max(0, Math.min(i, pages.length - 1));
setActiveTab(clamped);
+ setTick(0);
setPageKey((k) => k + 1);
setIsPaused(true);
}, []);Also applies to: 30-38, 46-50, 156-157
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/islands/DashboardPreview.tsx` around lines 27 - 28, The
children rely on the shared state variable tick, so when the visible page
changes via pageKey the clock must be reset; update the logic around pageKey
(where setPageKey is called or in a useEffect watching pageKey inside
DashboardPreview) to call setTick(0) (or derive a page-local tick instead) so
each tab mounts with tick === 0; ensure you update all places that change
pageKey or mount the mini view so tick is reset on page switch.
| <div className="flex items-center gap-2"> | ||
| <span className="text-xs px-2 py-0.5 rounded" style={{ background: "var(--dp-border)", color: "var(--dp-text-muted)" }}> | ||
| 7 agents | ||
| </span> | ||
| <span className="text-xs px-2 py-0.5 rounded" style={{ background: "var(--dp-border)", color: "var(--dp-text-muted)" }}> | ||
| 12 tasks | ||
| </span> |
There was a problem hiding this comment.
Header metrics drift from the agreed preview data.
The PR objectives call out 12 agents / 47 tasks / EUR 18.92 for this preview, but these pills still show 7 agents / 12 tasks. Pull the header numbers from the same mock dataset as the mini pages so the landing page doesn’t contradict itself.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/islands/DashboardPreview.tsx` around lines 109 - 115, The
header pills in DashboardPreview are hardcoded ("7 agents", "12 tasks") and
diverge from the mock preview data used elsewhere; import or reference the same
mock dataset used by the mini pages (the module that exports the preview/mock
object) and replace the literal strings in the DashboardPreview component with
the dataset fields (e.g., dataset.agentsCount, dataset.tasksCount and
dataset.estimatedCost formatted as EUR) so the header values match the mini
pages and PR objectives.
| <!-- Communication edges (animated) --> | ||
| <line id="edge-comm1" x1="155" y1="188" x2="220" y2="196" stroke="#2dd4bf" stroke-width="1.2" stroke-opacity="0" stroke-dasharray="5 3" class="transition-all duration-700"> | ||
| <animate attributeName="stroke-dashoffset" from="0" to="-16" dur="1.5s" repeatCount="indefinite" /> | ||
| </line> | ||
| <line id="edge-comm2" x1="305" y1="160" x2="325" y2="160" stroke="#2dd4bf" stroke-width="1.2" stroke-opacity="0" stroke-dasharray="5 3" class="transition-all duration-700"> | ||
| <animate attributeName="stroke-dashoffset" from="0" to="-16" dur="2s" repeatCount="indefinite" /> | ||
| </line> | ||
|
|
||
| <!-- Task flow (step 2) --> | ||
| <line id="edge-task" x1="210" y1="78" x2="57" y2="137" stroke="#a78bfa" stroke-width="1.5" stroke-opacity="0" class="transition-all duration-700"> | ||
| <animate attributeName="stroke-dashoffset" from="0" to="-12" dur="1s" repeatCount="indefinite" /> | ||
| </line> |
There was a problem hiding this comment.
Reduced-motion users still get motion here.
The SVG <animate> nodes are rendered in the initial HTML and only removed after this script runs, so prefers-reduced-motion users can still see animation on first paint. The step dots also always request smooth scrolling. Start from static SVG markup and only opt into SMIL/smooth scrolling when the media query says motion is allowed.
Also applies to: 415-421, 425-436
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/ScrollSyncPanel.astro` around lines 245 - 256, The SVG
animations and smooth-scroll behavior are always present in the initial HTML
(e.g., the <line> elements with ids edge-comm1, edge-comm2, edge-task and the
step dot elements), causing motion for prefers-reduced-motion users on first
paint; change the markup to render static SVG (remove or omit <animate> children
and any smooth-scroll attributes/classes in the initial server-rendered markup)
and then, in the client script that currently toggles animations, detect the
media query (window.matchMedia('(prefers-reduced-motion: no-preference)')) and
only then programmatically insert the SMIL <animate> elements into
edge-comm1/edge-comm2/edge-task (and enable smooth scrolling on step dot
elements) so reduced-motion users never receive animations on first paint.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
site/src/components/islands/DashboardPreview.tsx (3)
27-28:⚠️ Potential issue | 🟡 MinorTick is not reset when switching tabs.
The
tickvalue continues incrementing globally. When a user manually switches tabs, each mini page opens mid-animation rather than from frame 0, which can be disorienting. The past review suggested resettingtickon tab change.🔧 Suggested fix
const selectTab = useCallback((i: number) => { const clamped = Math.max(0, Math.min(i, pages.length - 1)); setActiveTab(clamped); + setTick(0); setPageKey((k) => k + 1); setIsPaused(true); }, []);Also reset in the auto-cycle effect:
useEffect(() => { if (isPaused) return; const timer = setInterval(() => { setActiveTab((t) => (t + 1) % pages.length); + setTick(0); setPageKey((k) => k + 1); }, 6000); return () => clearInterval(timer); }, [isPaused]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/DashboardPreview.tsx` around lines 27 - 28, The tick state (tick / setTick) isn’t being reset when the active mini-page changes, so pages open mid-animation; update the tab-change handler that updates pageKey (setPageKey) to also call setTick(0), and also ensure the auto-cycle effect (the useEffect that advances tick and/or cycles pageKey) resets tick to 0 when it changes pages automatically; locate the functions/hooks manipulating pageKey and the useEffect that increments tick and add setTick(0) whenever pageKey is updated (both manual tab switch and in the auto-cycle logic).
113-119:⚠️ Potential issue | 🟡 MinorHeader metrics still inconsistent with PR objectives.
The header displays "7 agents" and "12 tasks", but the PR objectives specify the dashboard preview should show
12 agents, 47 tasks, EUR 18.92. This creates a visual contradiction on the landing page.🔧 Suggested fix to align with PR objectives
<div className="flex items-center gap-2"> <span className="text-xs px-2 py-0.5 rounded" style={{ background: "var(--dp-border)", color: "var(--dp-text-muted)" }}> - 7 agents + 12 agents </span> <span className="text-xs px-2 py-0.5 rounded" style={{ background: "var(--dp-border)", color: "var(--dp-text-muted)" }}> - 12 tasks + 47 tasks </span> </div>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/DashboardPreview.tsx` around lines 113 - 119, The header metrics in DashboardPreview are hardcoded to "7 agents" and "12 tasks" but should match the PR objectives; update the <div className="flex items-center gap-2"> block inside the DashboardPreview component to render three metric spans showing "12 agents", "47 tasks", and "EUR 18.92" (or, better, pull these values from the component's props/state if metrics are available, e.g., metrics.agents, metrics.tasks, metrics.revenue) and keep the existing styling (text-xs px-2 py-0.5 rounded with the same inline styles) so the landing page matches the PR requirements.
34-34: 🧹 Nitpick | 🔵 TrivialUse
pages.lengthinstead of hardcoded4.The auto-cycle and next-button logic use hardcoded values (
4and3) instead of deriving frompages.length. This creates a maintenance burden if pages are added/removed.🔧 Suggested fix
useEffect(() => { if (isPaused) return; const timer = setInterval(() => { - setActiveTab((t) => (t + 1) % 4); + setActiveTab((t) => (t + 1) % pages.length); setPageKey((k) => k + 1); }, 6000); return () => clearInterval(timer); }, [isPaused]);And at line 207:
- style={{ color: activeTab < 3 ? "var(--dp-text-secondary)" : "var(--dp-border-bright)" }} + style={{ color: activeTab < pages.length - 1 ? "var(--dp-text-secondary)" : "var(--dp-border-bright)" }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/DashboardPreview.tsx` at line 34, The code in DashboardPreview uses hardcoded tab counts (e.g., setActiveTab((t) => (t + 1) % 4) and a next-button that compares to 3) which breaks when pages change; update those to derive from the pages array length: replace occurrences of 4 with pages.length (for cycling modulo) and replace 3 with pages.length - 1 (for last-index comparisons) — locate these in the DashboardPreview component (e.g., the setActiveTab call and the next-button logic) and use pages.length consistently so tab navigation auto-adjusts when pages are added/removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/mini/BudgetMini.tsx`:
- Around line 115-120: The SVG gradient stops inside the linearGradient (id
referenced by sparkGradId) use a hardcoded hex (`#38bdf8`); update the stop
elements to reference the CSS accent variable instead (e.g., use
stopColor="var(--dp-accent)") so the gradient follows the site's accent color,
and keep the hex as a fallback or document it as intentional fallback if browser
support is a concern; modify the stop elements within the linearGradient in
BudgetMini.tsx (the <stop ... stopColor=... /> nodes) accordingly.
In `@site/src/components/ParticleNetwork.astro`:
- Around line 61-77: The resize() handler currently clears the canvas but
doesn't repaint when reduced-motion (animating === false), leaving a blank hero
after resize; after you update the canvas size and node list in resize(), call
the same frame-drawing routine used by the animation loop (the function that
iterates over nodes and renders to ctx — e.g., the frame/draw/render function
that consumes nodes and ctx) when animating is false so the static frame is
immediately repainted; apply the same change to the analogous block around the
visibility/observer logic (the section at ~213-225) so reduced-motion users see
a rendered frame after resize/orientation changes.
- Around line 13-14: The gradient overlay div is intercepting mouse input and
preventing the canvas pointer handlers (the handlers at lines 194-202) from
receiving events; update the overlay div (the element with classes "absolute
inset-0 bg-gradient-to-b ...") to ignore pointer events by adding
pointer-events-none (or style="pointer-events:none;") so the underlying canvas
and its repulsion handlers can receive pointer events.
---
Duplicate comments:
In `@site/src/components/islands/DashboardPreview.tsx`:
- Around line 27-28: The tick state (tick / setTick) isn’t being reset when the
active mini-page changes, so pages open mid-animation; update the tab-change
handler that updates pageKey (setPageKey) to also call setTick(0), and also
ensure the auto-cycle effect (the useEffect that advances tick and/or cycles
pageKey) resets tick to 0 when it changes pages automatically; locate the
functions/hooks manipulating pageKey and the useEffect that increments tick and
add setTick(0) whenever pageKey is updated (both manual tab switch and in the
auto-cycle logic).
- Around line 113-119: The header metrics in DashboardPreview are hardcoded to
"7 agents" and "12 tasks" but should match the PR objectives; update the <div
className="flex items-center gap-2"> block inside the DashboardPreview component
to render three metric spans showing "12 agents", "47 tasks", and "EUR 18.92"
(or, better, pull these values from the component's props/state if metrics are
available, e.g., metrics.agents, metrics.tasks, metrics.revenue) and keep the
existing styling (text-xs px-2 py-0.5 rounded with the same inline styles) so
the landing page matches the PR requirements.
- Line 34: The code in DashboardPreview uses hardcoded tab counts (e.g.,
setActiveTab((t) => (t + 1) % 4) and a next-button that compares to 3) which
breaks when pages change; update those to derive from the pages array length:
replace occurrences of 4 with pages.length (for cycling modulo) and replace 3
with pages.length - 1 (for last-index comparisons) — locate these in the
DashboardPreview component (e.g., the setActiveTab call and the next-button
logic) and use pages.length consistently so tab navigation auto-adjusts when
pages are added/removed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f202cfbd-9917-4400-a1ef-eb370bd289c0
📒 Files selected for processing (6)
site/src/components/ParticleNetwork.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Create a `.stories.tsx` Storybook file alongside each new shared component with all states (default, hover, loading, error, empty)
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/ScrollSyncPanel.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create complex (>8 line) JSX inside `.map()` -- extract to a shared component
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT build card-with-header layouts from scratch -- use `<SectionCard>` component
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/ScrollSyncPanel.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Export props as a TypeScript interface for new components
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets.
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
🔇 Additional comments (4)
site/src/components/ScrollSyncPanel.astro (1)
1-456: LGTM - Well-structured scroll-sync implementation.The IntersectionObserver setup with
-35%root margin provides good scroll detection, the step visualization logic is clean, and the component properly disconnects the observer onastro:before-swap. The SVG visualization progressively reveals elements across steps effectively.Note: Past review comments flagged that SVG
<animate>elements are rendered in initial HTML (users withprefers-reduced-motionmay briefly see animation on first paint) and that dynamic motion preference changes aren't handled. Those concerns remain valid but are already tracked.site/src/components/islands/mini/TaskBoardMini.tsx (1)
103-136: Column rendering JSX is at the threshold of inline complexity.The JSX inside
.map()at lines 103-136 (~33 lines) is moderately complex. While it's self-contained, consider extracting aColumncomponent if this grows further.Otherwise, the implementation is solid—
useMemocorrectly depends ontick, column assignments are deterministic, and theming via CSS variables is consistent.site/src/components/islands/mini/OrgChartMini.tsx (1)
30-36: Good dynamic motion preference handling.Unlike the Astro component, this React island correctly listens for changes to
prefers-reduced-motionand updates state accordingly. The SMIL<animate>at line 71 is conditionally rendered, so reduced-motion users never receive the animation.site/src/components/islands/mini/BudgetMini.tsx (1)
1-148: Overall implementation is solid.Good use of
useId()to prevent gradient ID collisions when multiple instances render. The gauge math is correct, metric calculations are consistent, and the component properly uses CSS variables for theming throughout (except the noted gradient stops).
c7b4315 to
53c2be0
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
site/src/components/ScrollSyncPanel.astro (1)
413-422:⚠️ Potential issue | 🟡 MinorSmooth scrolling ignores reduced-motion preference.
The dot click handler always uses
behavior: "smooth"regardless of the user's motion preferences. Users who haveprefers-reduced-motion: reduceenabled should receive instant scrolling instead.Suggested fix
dots.forEach((dot) => { dot.addEventListener("click", () => { const stepIdx = parseInt(dot.dataset.dot || "0", 10); const target = steps[stepIdx]; if (target) { - target.scrollIntoView({ behavior: "smooth", block: "center" }); + const behavior = prefersReduced.matches ? "instant" : "smooth"; + target.scrollIntoView({ behavior, block: "center" }); } }); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/ScrollSyncPanel.astro` around lines 413 - 422, The dot click handler always uses smooth scrolling; change the behavior to respect the user's reduced-motion preference by checking window.matchMedia("(prefers-reduced-motion: reduce)").matches inside the dots.forEach click listener (where dot.addEventListener and target.scrollIntoView are used) and set the scrollIntoView options to use "auto" (or "instant"/"auto") when prefers-reduced-motion is true and "smooth" otherwise so users with reduced-motion enabled get instant scrolling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/mini/AgentDetailMini.tsx`:
- Line 65: The div in AgentDetailMini.tsx currently applies both the Tailwind
class "font-mono" and an inline style fontFamily: "var(--dp-font-mono)" which is
redundant; edit the JSX for the div (the element with className "text-sm
font-semibold font-mono" and style={{ color: m.color, fontFamily:
"var(--dp-font-mono)" }}) to remove the inline fontFamily property while keeping
the color (m.color) and the "font-mono" class, so the mono font is provided by
the class only.
- Around line 94-106: The usage of index as key in the duplicated activities
render is intentional for the visual infinite-scroll effect; update the map in
AgentDetailMini (the {[...activities, ...activities].map((a, i) => ...)} block
where key={i}) to add a concise comment above or beside the element explaining
that the activities array is static and intentionally duplicated, so using the
index as key is deliberate and not a bug.
---
Duplicate comments:
In `@site/src/components/ScrollSyncPanel.astro`:
- Around line 413-422: The dot click handler always uses smooth scrolling;
change the behavior to respect the user's reduced-motion preference by checking
window.matchMedia("(prefers-reduced-motion: reduce)").matches inside the
dots.forEach click listener (where dot.addEventListener and
target.scrollIntoView are used) and set the scrollIntoView options to use "auto"
(or "instant"/"auto") when prefers-reduced-motion is true and "smooth" otherwise
so users with reduced-motion enabled get instant scrolling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 80c8f189-91c1-48f8-8dc0-c9d707243b30
⛔ Files ignored due to path filters (1)
site/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (16)
CLAUDE.mdsite/astro.config.mjssite/package.jsonsite/src/components/ExpandableArchitecture.astrosite/src/components/FeatureShowcase.astrosite/src/components/ParticleNetwork.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/UseCaseCards.astrosite/src/components/islands/DashboardPreview.csssite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/layouts/Base.astrosite/src/pages/index.astro
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (51)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Web dashboard: see `web/CLAUDE.md` for commands, design system, and component inventory
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/api/**/*.md : Library reference in `docs/api/` (auto-generated via mkdocstrings + Griffe, AST-based)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to {docs/rest-api.md,docs/_generated/api-reference.html} : REST API reference in `docs/rest-api.md` + `docs/_generated/api-reference.html` (generated by `scripts/export_openapi.py`)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
CLAUDE.mdsite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to pyproject.toml : Docs group in `pyproject.toml` includes: `zensical`, `mkdocstrings[python]`, `griffe-pydantic`
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to scripts/**/*.py : Scripts in `scripts/` (CI/build utilities and development-time validation hooks) — relaxed ruff rules: `print` and deferred imports allowed
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to web/src/**/*.{ts,tsx} : Web dashboard design system: ALWAYS reuse existing components from web/src/components/ui/ before creating new ones
Applied to files:
CLAUDE.mdsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Applied to files:
CLAUDE.mdsite/src/components/islands/DashboardPreview.tsxsite/src/pages/index.astrosite/package.jsonsite/astro.config.mjs
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
Applied to files:
CLAUDE.mdsite/package.json
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to web/src/**/*.{ts,tsx} : Web dashboard: NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets
Applied to files:
CLAUDE.mdsite/src/components/islands/DashboardPreview.csssite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
CLAUDE.mdsite/src/components/UseCaseCards.astrosite/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/ExpandableArchitecture.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/AgentDetailMini.tsxsite/src/pages/index.astro
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to web/package.json : Web dashboard Node.js 20+; dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)
Applied to files:
CLAUDE.mdsite/package.jsonsite/astro.config.mjs
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/package.json : Web dashboard Node.js 22+, TypeScript 6.0+, dependencies in `web/package.json`
Applied to files:
CLAUDE.mdsite/package.json
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Install via `uv sync` (installs all deps including dev group by default)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-21T12:54:22.557Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T12:54:22.557Z
Learning: Go 1.26+ required; CLI dependencies in `cli/go.mod` (Cobra, charmbracelet/huh, charmbracelet/lipgloss, sigstore-go, go-containerregistry, go-tuf)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-21T14:12:17.848Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T14:12:17.848Z
Learning: Applies to cli/go.mod : CLI uses Go 1.26+. Dependencies: Cobra, charmbracelet/huh, charmbracelet/lipgloss, sigstore-go, go-containerregistry, go-tuf
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `font-sans` or `font-mono` for typography (maps to Geist tokens). NEVER set `fontFamily` directly
Applied to files:
site/src/layouts/Base.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT build card-with-header layouts from scratch -- use `<SectionCard>` component
Applied to files:
site/src/components/UseCaseCards.astrosite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. DESIGN_SPEC.md is a pointer file linking to the 7 design pages (index, agents, organization, communication, engine, memory, operations).
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-03-18T08:23:08.912Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T08:23:08.912Z
Learning: When approved deviations occur, update the relevant `docs/design/` page to reflect the new reality.
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Create a `.stories.tsx` Storybook file alongside each new shared component with all states (default, hover, loading, error, empty)
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/ScrollSyncPanel.astrosite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/DashboardPreview.csssite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Export props as a TypeScript interface for new components
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Security: SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume).
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/security/**/*.py : Security module includes SecOps agent, rule engine (soft-allow/hard-deny), audit log, output scanner, risk classifier, autonomy levels (4 strategies), timeout policies.
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Gitleaks scans for secrets via pre-commit hook and weekly CI job
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/.storybook/{main,preview}.{ts,tsx} : Storybook 10: Use `defineMain` from `storybook/react-vite/node` and `definePreview` from `storybook/react-vite` in Storybook config files
Applied to files:
site/package.jsonsite/astro.config.mjs
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{ts,tsx} : CSS side-effect imports need type declarations; use Vite's `/// <reference types="vite/client" />` directive
Applied to files:
site/package.jsonsite/astro.config.mjs
🔇 Additional comments (18)
site/src/components/islands/mini/TaskBoardMini.tsx (1)
70-95: LGTM!The
useMemocorrectly depends ontick, the column assignment logic is deterministic and clear, and task keys use stabletask.idvalues. The CSS variable usage for theming is consistent with other mini components.site/src/components/UseCaseCards.astro (1)
72-98: LGTM!Good accessibility implementation with
role="region",aria-label, andtabindex="0"for keyboard navigation. The responsive behavior (horizontal snap on mobile, 3-column grid on desktop) and gradient fade hints match the PR requirements well.site/astro.config.mjs (1)
4-11: LGTM!Standard
@astrojs/reactintegration setup. The default configuration is appropriate for the React islands use case in this PR.CLAUDE.md (3)
63-63: LGTM!Documentation accurately reflects the new React islands architecture and interactive dashboard preview feature added in this PR.
109-109: LGTM!Package structure documentation correctly notes React islands for interactive sections.
236-236: LGTM!Dependencies section correctly documents the landing page stack versions.
site/src/components/FeatureShowcase.astro (1)
89-127: LGTM!Good accessibility implementation with
focus-visiblering styles for keyboard navigation on all interactive elements. The conditional color theming is consistent with other components in this PR.site/package.json (1)
12-19: Package versions are compatible.The React integration with
@astrojs/react@^5.0.2,react@^19.2.4, andreact-dom@^19.2.4is fully compatible with Astro 6.1.2. The@astrojs/reactpackage explicitly supports React 19.x, and compatibility is ensured through coordinated releases between the Astro framework and its official integrations.site/src/components/ScrollSyncPanel.astro (1)
245-256: Reduced-motion users still see animation on first paint.The SVG
<animate>elements (lines 247, 250, 255) are rendered in the initial HTML and only removed after the script runs. Users withprefers-reduced-motion: reducewill see animations briefly before the DOM is modified.To properly respect reduced-motion from first paint, start with static SVG (no
<animate>children) and only inject SMIL animations when the media query indicates motion is allowed.site/src/components/islands/DashboardPreview.tsx (2)
113-120: Header metrics still inconsistent with PR objectives.The header pills show
7 agentsand12 tasks, but the PR objectives and content accuracy notes specify12 agentsand47 tasks. This contradicts the dashboard preview mini pages which use the agreed data.Suggested fix
<div className="flex items-center gap-2"> <span className="text-xs px-2 py-0.5 rounded" style={{ background: "var(--dp-border)", color: "var(--dp-text-muted)" }}> - 7 agents + 12 agents </span> <span className="text-xs px-2 py-0.5 rounded" style={{ background: "var(--dp-border)", color: "var(--dp-text-muted)" }}> - 12 tasks + 47 tasks </span> </div>
46-51:tickshould reset when switching tabs.When a user switches tabs (either manually or via auto-cycle), the
tickcounter continues from its current value. This causes mini pages to start mid-sequence rather than from frame 0, making the animation feel inconsistent.Suggested fix
const selectTab = useCallback((i: number) => { const clamped = Math.max(0, Math.min(i, pages.length - 1)); setActiveTab(clamped); + setTick(0); setPageKey((k) => k + 1); setIsPaused(true); }, []);Also update the auto-cycle effect:
useEffect(() => { if (isPaused) return; const timer = setInterval(() => { setActiveTab((t) => (t + 1) % pages.length); + setTick(0); setPageKey((k) => k + 1); }, 6000); return () => clearInterval(timer); }, [isPaused]);site/src/components/islands/DashboardPreview.css (1)
1-107: Well-structured CSS theming with comprehensive accessibility support.The CSS custom properties approach cleanly centralizes design tokens for this island component. The
prefers-reduced-motionmedia query correctly disables all animations and transitions. The animation definitions are appropriate for their visual purposes.site/src/components/islands/mini/OrgChartMini.tsx (1)
40-134: LGTM!The component properly handles reduced-motion preferences with a
matchMedialistener and cleanup. The SVG is correctly markedaria-hidden="true", and SMIL<animate>elements are conditionally rendered only when motion is allowed. The tick-based cycling of communication patterns works correctly with the modulo operation.site/src/components/ExpandableArchitecture.astro (1)
142-232: LGTM!The accordion implementation correctly uses ARIA attributes (
aria-expanded,aria-controls,aria-hidden), theinertattribute for collapsed panels, and CSS grid-row transitions for smooth animations. The toggle logic properly collapses all panels before expanding the clicked one. Basic keyboard accessibility (Enter/Space) works correctly.site/src/components/islands/mini/BudgetMini.tsx (1)
14-148: LGTM!The component correctly uses
useId()for gradient ID stability across SSR/hydration. Previous issues have been addressed: the gradient<defs>block is now positioned at the top of the SVG, and the gradient stops usevar(--dp-accent)instead of hardcoded hex values. The gauge math and forecast color logic are correct.site/src/components/ParticleNetwork.astro (1)
1-243: LGTM!Previous review issues have been addressed:
- The gradient overlay now has
pointer-events-none(line 14)- The
onMotionChangehandler checksisVisiblebefore resuming animation (line 171)- The
resize()function repaints a static frame when not animating (lines 78-81)The implementation properly handles reduced-motion preferences, off-screen pausing via IntersectionObserver, resize with debouncing, and cleanup on Astro view transitions.
site/src/pages/index.astro (2)
1-12: Component composition looks good.The landing page now cleanly imports and uses the new interactive components. The
DashboardPreviewReact island correctly usesclient:visiblefor above-the-fold JS optimization.
18-19: ParticleNetwork cleanup listener requires ViewTransitions to fire.The
ParticleNetworkcomponent includes cleanup onastro:before-swap, but this event only fires when Astro'sViewTransitionscomponent is enabled. Currently,Base.astrodoes not includeViewTransitions, so full page reloads will occur and cleanup happens naturally via browser garbage collection.If you plan to add
ViewTransitionslater, the cleanup code is already in place.
| <div className="text-xs mb-0.5" style={{ color: "var(--dp-text-muted)" }}> | ||
| {m.label} | ||
| </div> | ||
| <div className="text-sm font-semibold font-mono" style={{ color: m.color, fontFamily: "var(--dp-font-mono)" }}> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Redundant font styling.
Both font-mono class and inline fontFamily: "var(--dp-font-mono)" are applied. One is sufficient.
💡 Remove redundant inline style
- <div className="text-sm font-semibold font-mono" style={{ color: m.color, fontFamily: "var(--dp-font-mono)" }}>
+ <div className="text-sm font-semibold font-mono" style={{ color: m.color }}>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div className="text-sm font-semibold font-mono" style={{ color: m.color, fontFamily: "var(--dp-font-mono)" }}> | |
| <div className="text-sm font-semibold font-mono" style={{ color: m.color }}> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/islands/mini/AgentDetailMini.tsx` at line 65, The div in
AgentDetailMini.tsx currently applies both the Tailwind class "font-mono" and an
inline style fontFamily: "var(--dp-font-mono)" which is redundant; edit the JSX
for the div (the element with className "text-sm font-semibold font-mono" and
style={{ color: m.color, fontFamily: "var(--dp-font-mono)" }}) to remove the
inline fontFamily property while keeping the color (m.color) and the "font-mono"
class, so the mono font is provided by the class only.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
site/src/components/ScrollSyncPanel.astro (2)
425-436:⚠️ Potential issue | 🟡 MinorReduced-motion preference changes are not handled after load.
Line 425-Line 436 applies reduced-motion only once. If OS preference changes while the page is open, the component state won’t adapt.
Suggested fix
if (prefersReduced.matches) { disableSvgAnimations(); } + + prefersReduced.addEventListener("change", (e) => { + if (e.matches) { + disableSvgAnimations(); + } else { + // Re-attach animations if you implement programmatic insertion. + // Otherwise, consider re-initializing the viz. + } + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/ScrollSyncPanel.astro` around lines 425 - 436, The code currently checks prefersReduced once; register a listener on the MediaQueryList returned by window.matchMedia("(prefers-reduced-motion: reduce)") to respond to runtime changes: call disableSvgAnimations() when event.matches is true, and when event.matches is false restore or re-initialize animations (e.g., re-render the SVG/animations or reload the component) so the UI adapts; use the existing prefersReduced variable and add prefersReduced.addEventListener('change', handler) (or prefersReduced.addListener for older browsers) and implement the handler to call disableSvgAnimations() on matches and to re-enable animations when not matches.
245-256:⚠️ Potential issue | 🟠 MajorReduced-motion users still get animation on first paint.
At Line 247, Line 250, and Line 255, SMIL animations are rendered in initial HTML, then removed only at Line 434-Line 436. This still exposes motion briefly for users with
prefers-reduced-motion: reduce.Suggested fix
- <line id="edge-comm1" ...> - <animate attributeName="stroke-dashoffset" from="0" to="-16" dur="1.5s" repeatCount="indefinite" /> - </line> + <line id="edge-comm1" ...></line> - <line id="edge-comm2" ...> - <animate attributeName="stroke-dashoffset" from="0" to="-16" dur="2s" repeatCount="indefinite" /> - </line> + <line id="edge-comm2" ...></line> - <line id="edge-task" ...> - <animate attributeName="stroke-dashoffset" from="0" to="-12" dur="1s" repeatCount="indefinite" /> - </line> + <line id="edge-task" ...></line>+ function attachSvgAnimations(): void { + if (document.querySelector("#edge-comm1 animate")) return; + const specs = [ + ["edge-comm1", "-16", "1.5s"], + ["edge-comm2", "-16", "2s"], + ["edge-task", "-12", "1s"], + ] as const; + for (const [id, to, dur] of specs) { + const line = document.getElementById(id); + if (!line) continue; + const anim = document.createElementNS("http://www.w3.org/2000/svg", "animate"); + anim.setAttribute("attributeName", "stroke-dashoffset"); + anim.setAttribute("from", "0"); + anim.setAttribute("to", to); + anim.setAttribute("dur", dur); + anim.setAttribute("repeatCount", "indefinite"); + line.appendChild(anim); + } + } + + if (!prefersReduced.matches) { + attachSvgAnimations(); + } else { + disableSvgAnimations(); + }Also applies to: 425-436
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/ScrollSyncPanel.astro` around lines 245 - 256, The SMIL <animate> tags for edge-comm1, edge-comm2 and edge-task are included in the initial HTML causing brief motion for users with prefers-reduced-motion; remove the inline <animate> elements from those <line id="edge-comm1">, <line id="edge-comm2"> and <line id="edge-task"> server-side and instead add them at runtime only if window.matchMedia('(prefers-reduced-motion: reduce)').matches is false — implement a small client-side script that checks prefers-reduced-motion, and when motion is allowed dynamically creates/appends the corresponding <animate> elements (matching the existing attributes like attributeName, from, to, dur, repeatCount) to those elements; ensure the server-rendered lines have no <animate> children so reduced-motion users never see a first-paint animation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/mini/AgentDetailMini.tsx`:
- Around line 35-40: The badge in AgentDetailMini uses a hardcoded background
rgba(16,185,129,0.15); replace that with a CSS variable (e.g.
--dp-success-muted) and use it in the span instead of the literal color, or
alternatively use color-mix() against --dp-success to derive a muted variant;
add the new --dp-success-muted to the component's stylesheet or global theme and
update the span in AgentDetailMini to reference that variable (with a fallback
to the original rgba).
---
Duplicate comments:
In `@site/src/components/ScrollSyncPanel.astro`:
- Around line 425-436: The code currently checks prefersReduced once; register a
listener on the MediaQueryList returned by
window.matchMedia("(prefers-reduced-motion: reduce)") to respond to runtime
changes: call disableSvgAnimations() when event.matches is true, and when
event.matches is false restore or re-initialize animations (e.g., re-render the
SVG/animations or reload the component) so the UI adapts; use the existing
prefersReduced variable and add prefersReduced.addEventListener('change',
handler) (or prefersReduced.addListener for older browsers) and implement the
handler to call disableSvgAnimations() on matches and to re-enable animations
when not matches.
- Around line 245-256: The SMIL <animate> tags for edge-comm1, edge-comm2 and
edge-task are included in the initial HTML causing brief motion for users with
prefers-reduced-motion; remove the inline <animate> elements from those <line
id="edge-comm1">, <line id="edge-comm2"> and <line id="edge-task"> server-side
and instead add them at runtime only if
window.matchMedia('(prefers-reduced-motion: reduce)').matches is false —
implement a small client-side script that checks prefers-reduced-motion, and
when motion is allowed dynamically creates/appends the corresponding <animate>
elements (matching the existing attributes like attributeName, from, to, dur,
repeatCount) to those elements; ensure the server-rendered lines have no
<animate> children so reduced-motion users never see a first-paint animation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: a04e7a48-edb3-40de-8551-d543838a7cc4
📒 Files selected for processing (2)
site/src/components/ScrollSyncPanel.astrosite/src/components/islands/mini/AgentDetailMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/ScrollSyncPanel.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `font-sans` or `font-mono` for typography (maps to Geist tokens). NEVER set `fontFamily` directly
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create complex (>8 line) JSX inside `.map()` -- extract to a shared component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/ScrollSyncPanel.astro
🔇 Additional comments (5)
site/src/components/islands/mini/AgentDetailMini.tsx (5)
1-14: LGTM!Clean static data structure. Using hardcoded colors in the
activitiesdata array is acceptable for this static demo content that drives the visual scroll effect.
16-19: LGTM!The
tick-driven computed values create a smooth animation effect. The EUR formatting aligns with PR requirements.
53-70: LGTM!The metrics grid is well-structured with stable keys. The font styling issue from previous review has been addressed.
112-119: LGTM!The footer tagline is clean and uses consistent CSS variable styling.
92-109: Thedp-activity-scrollanimation already respectsprefers-reduced-motion. The media query inDashboardPreview.css(lines 101–102) explicitly setsanimation: nonefor users with that preference. No action needed.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/mini/AgentDetailMini.tsx`:
- Around line 92-93: The activity ticker in AgentDetailMini lacks a pause
control; add a pause path by making the scrolling container (the element with
class "dp-activity-scroll" inside AgentDetailMini) focusable (tabIndex=0) and
introduce a paused state that, when true, applies a CSS rule (e.g., a "paused"
class that sets animation-play-state: paused or stops the JS scrolling timer) to
stop the animation. Wire onMouseEnter/onFocus to set paused=true and
onMouseLeave/onBlur to set paused=false, and add a keyboard handler (onKeyDown)
to toggle pause/resume for Space/Escape so keyboard users can control the
ticker. Ensure the state and handlers are implemented in the AgentDetailMini
component and the CSS class name matches the "dp-activity-scroll" element so the
visual animation actually pauses.
- Around line 17-18: The animated metrics tasksCompleted and costToday currently
grow unbounded with tick; change their calculation in AgentDetailMini
(referencing tasksCompleted, costToday and tick) to produce bounded/cycling
values instead of ever-increasing ones—e.g. compute a small cycle value like
cycle = tick % N (or clamp a derived value) and use that to offset a realistic
base (e.g. tasksCompletedBase + Math.floor(cycle/step) and costTodayBase + cycle
* rate) so tasksCompleted and costToday stay within a fixed preview range and
costToday still uses toFixed(2) on the final numeric result.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: db3ad4ae-4eab-4a5a-afaa-664363bccdd6
📒 Files selected for processing (1)
site/src/components/islands/mini/AgentDetailMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `font-sans` or `font-mono` for typography (maps to Geist tokens). NEVER set `fontFamily` directly
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create complex (>8 line) JSX inside `.map()` -- extract to a shared component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to web/src/**/*.{ts,tsx} : Web dashboard: NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
🔇 Additional comments (2)
site/src/components/islands/mini/AgentDetailMini.tsx (2)
94-96: Good clarification on intentional index key usage.The inline comment clearly documents why
key={i}is safe in this duplicated static list case.
7-14:⚠️ Potential issue | 🟠 MajorReplace hardcoded activity colors with dashboard tokens.
The
activitiespalette is hardcoded with hex literals, which weakens theme consistency for the dashboard-style preview.♻️ Suggested tokenized update
const activities = [ - { time: "2m ago", action: "Completed task `#12`: Schema validation", color: "#10b981" }, - { time: "5m ago", action: "Delegated subtask to Engineer", color: "#38bdf8" }, - { time: "8m ago", action: "Approved PR `#47` (quality: 94%)", color: "#10b981" }, - { time: "12m ago", action: "Started task `#11`: API design", color: "#a78bfa" }, - { time: "15m ago", action: "Meeting: sprint planning (chair)", color: "#2dd4bf" }, - { time: "20m ago", action: "Budget alert: 72% daily used", color: "#f59e0b" }, + { time: "2m ago", action: "Completed task `#12`: Schema validation", color: "var(--dp-success)" }, + { time: "5m ago", action: "Delegated subtask to Engineer", color: "var(--dp-accent)" }, + { time: "8m ago", action: "Approved PR `#47` (quality: 94%)", color: "var(--dp-success)" }, + { time: "12m ago", action: "Started task `#11`: API design", color: "var(--dp-purple)" }, + { time: "15m ago", action: "Meeting: sprint planning (chair)", color: "var(--dp-teal)" }, + { time: "20m ago", action: "Budget alert: 72% daily used", color: "var(--dp-warning)" }, ];Also applies to: 97-97
⛔ Skipped due to learnings
Learnt from: CR Repo: Aureliolo/synthorg PR: 0 File: CLAUDE.md:0-0 Timestamp: 2026-04-01T20:43:15.699Z Learning: Applies to web/src/**/*.{ts,tsx} : Web dashboard: NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presetsLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)Learnt from: CR Repo: Aureliolo/synthorg PR: 0 File: CLAUDE.md:0-0 Timestamp: 2026-03-31T14:17:24.182Z Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presetsLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)Learnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacingLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitionsLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` filesLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` componentLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` componentLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
| <div className="h-[72px] overflow-hidden relative"> | ||
| <div className="dp-activity-scroll"> |
There was a problem hiding this comment.
Add a pause path for the auto-scrolling activity ticker.
The ticker continuously animates but has no explicit pause/stop control in this component, which is an accessibility/readability risk for moving content.
🛠️ Suggested hover + keyboard pause behavior
- <div className="h-[72px] overflow-hidden relative">
- <div className="dp-activity-scroll">
+ <div
+ className="h-[72px] overflow-hidden relative group"
+ tabIndex={0}
+ aria-label="Recent activity ticker. Focus or hover to pause scrolling."
+ >
+ <div className="dp-activity-scroll group-hover:[animation-play-state:paused] group-focus-within:[animation-play-state:paused]">Also applies to: 95-107
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/islands/mini/AgentDetailMini.tsx` around lines 92 - 93,
The activity ticker in AgentDetailMini lacks a pause control; add a pause path
by making the scrolling container (the element with class "dp-activity-scroll"
inside AgentDetailMini) focusable (tabIndex=0) and introduce a paused state
that, when true, applies a CSS rule (e.g., a "paused" class that sets
animation-play-state: paused or stops the JS scrolling timer) to stop the
animation. Wire onMouseEnter/onFocus to set paused=true and onMouseLeave/onBlur
to set paused=false, and add a keyboard handler (onKeyDown) to toggle
pause/resume for Space/Escape so keyboard users can control the ticker. Ensure
the state and handlers are implemented in the AgentDetailMini component and the
CSS class name matches the "dp-activity-scroll" element so the visual animation
actually pauses.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
site/src/components/islands/mini/AgentDetailMini.tsx (1)
93-108:⚠️ Potential issue | 🟠 MajorProvide a real pause path for the auto-scrolling activity ticker.
Line 94 continuously animates moving content, but this block still lacks an explicit user pause mechanism and will read duplicated items twice to assistive tech. Add keyboard/hover pause behavior and hide the duplicated half from screen readers.
Suggested patch
- <div className="h-[72px] overflow-hidden relative"> - <div className="dp-activity-scroll"> + <div + className="h-[72px] overflow-hidden relative group" + tabIndex={0} + aria-label="Recent activity ticker. Focus or hover to pause." + > + <div className="dp-activity-scroll group-hover:[animation-play-state:paused] group-focus-within:[animation-play-state:paused]"> {/* Duplicated array for infinite scroll effect -- index key is intentional (static data) */} {[...activities, ...activities].map((a, i) => ( - <div key={i} className="flex items-start gap-2 px-2 py-1"> + <div key={i} aria-hidden={i >= activities.length} className="flex items-start gap-2 px-2 py-1">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/mini/AgentDetailMini.tsx` around lines 93 - 108, The activity ticker in AgentDetailMini.tsx duplicates activities via [...activities, ...activities] and lacks pause and accessibility handling; update the container (the div with className "dp-activity-scroll") to support pause on hover and keyboard focus by toggling a paused state via onMouseEnter/onMouseLeave and onFocus/onBlur (or by adding/removing a CSS class that pauses the animation), and mark the duplicated second half produced by the second spread (the mapped items with index i >= activities.length) with aria-hidden="true" and remove them from tab order so screen readers do not read items twice; implement the pause state handling inside the component and apply aria-hidden to elements where i >= activities.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/mini/AgentDetailMini.tsx`:
- Around line 7-14: The activities array in AgentDetailMini.tsx currently
hardcodes hex colors; replace the color hex strings in the activities data with
semantic token keys (e.g., "success", "info", "accent", "warning") and update
the render logic where the dot is drawn (referenced in AgentDetailMini render
around the previous line 98) to resolve those token keys to theme-aware CSS
classes or CSS custom properties (e.g., map token -> tailwind/token class or
var(--color-...)) before applying the style; ensure the mapping is centralized
(a small tokenToClass/tokenToVar helper alongside AgentDetailMini or in a theme
util) so the preview follows the active theme instead of using hardcoded hex
values.
---
Duplicate comments:
In `@site/src/components/islands/mini/AgentDetailMini.tsx`:
- Around line 93-108: The activity ticker in AgentDetailMini.tsx duplicates
activities via [...activities, ...activities] and lacks pause and accessibility
handling; update the container (the div with className "dp-activity-scroll") to
support pause on hover and keyboard focus by toggling a paused state via
onMouseEnter/onMouseLeave and onFocus/onBlur (or by adding/removing a CSS class
that pauses the animation), and mark the duplicated second half produced by the
second spread (the mapped items with index i >= activities.length) with
aria-hidden="true" and remove them from tab order so screen readers do not read
items twice; implement the pause state handling inside the component and apply
aria-hidden to elements where i >= activities.length.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0d0b3c38-d24a-465c-b11f-3f2347fc3e9d
📒 Files selected for processing (1)
site/src/components/islands/mini/AgentDetailMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `font-sans` or `font-mono` for typography (maps to Geist tokens). NEVER set `fontFamily` directly
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create complex (>8 line) JSX inside `.map()` -- extract to a shared component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to web/src/**/*.{ts,tsx} : Web dashboard: NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions -- use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
🔇 Additional comments (1)
site/src/components/islands/mini/AgentDetailMini.tsx (1)
17-20: Bounded tick-cycle metrics look correct.
tick % 20with derivedtasksCompletedandcostTodaykeeps preview values in a realistic range.
Add 5 interactive components to the Astro landing page: - Animated particle network (Canvas hero background with agent nodes) - Scroll-synced split panel (4-step code + visualization walkthrough) - Expandable architecture diagram (accordion with detailed sub-modules) - Scrollable use case cards (horizontal snap on mobile, 6 detailed cards) - Interactive dashboard preview (React island with 4 mini pages) Also enriches landing page content: deeper feature showcase replacing Core Pillars, expanded proof strip, updated security section copy, and punchier hero subtext showcasing SynthOrg's differentiators. Closes #294 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix SVG attributeName casing in OrgChartMini (stroke-dashoffset) and update CLAUDE.md documentation entries to reflect React islands in the landing page. Pre-reviewed by 2 agents, 4 findings addressed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Accessibility: add missing button id for aria-labelledby, add inert/aria-hidden to collapsed accordion panels, complete ARIA tab pattern with id/aria-controls/aria-labelledby, add dot nav focus indicator. Reduced motion: honor prefers-reduced-motion in ScrollSyncPanel by disabling SVG SMIL animations and skipping scroll observer. Robustness: graceful canvas context null handling, replace brittle Tailwind class selectors with data attributes, stabilize IntersectionObserver by picking highest ratio entry, add observer and ResizeObserver cleanup for Astro view transitions, defensive guard for edge agent lookups. Correctness: fix lg:flex-shrink (invalid Tailwind v4) to lg:shrink, replace scrollbar Tailwind utilities with native CSS, close sparkline polyline to baseline, fix legend text (4 levels not 8), rename SVG gradient id to avoid collisions. Code quality: simplify nested setState, use Unicode glyphs instead of set:html, add stylelint blank line, type priorityColors strictly, move @types to devDependencies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- OrgChartMini: conditionally render SMIL animate for reduced motion - ParticleNetwork: clean up matchMedia listener on view transitions - UseCaseCards: use semantic h3 for card titles, scope CSS mask to class - FeatureShowcase: add focus-visible ring on card anchors for keyboard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Content: - Replace fictional `synthorg run` CLI command with actual setup wizard flow (template selection -> API/wizard config -> agent collaboration -> dashboard observation) - Show real template scale: 9 built-in templates from 2 agents (Solo Builder) to 30+ agents (Enterprise) across up to 9 departments - Expand SVG org chart from 3 agents to 10 agents across 5 departments (Executive, Engineering, Product, Design, QA) - Update all metrics to reflect realistic agency-scale org (12 agents, 47 tasks, EUR 18.92 cost) UX: - ScrollSyncPanel: move step dots from horizontal bottom to vertical side column with numbered clickable buttons showing scroll direction - DashboardPreview: fix size stability with fixed-height tabpanel (h-[280px]/h-[320px] + overflow-hidden) - DashboardPreview: replace tiny dot nav with proper bottom bar featuring prev/next arrows and labeled page buttons Code quality (CodeRabbit round 3): - FeatureShowcase: dynamic focus ring color matching card theme - FeatureShowcase: correct ring-offset background for compact cards - UseCaseCards: add -webkit-mask-image prefix for Safari - ParticleNetwork: extract drawEdges/drawNodes helpers (DRY) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iation SVG visualization now progressively builds across steps: - Step 1 (Pick a Template): empty department frames only - Step 2 (Configure): agents appear with hierarchy edges - Step 3 (Collaborate): communication edges, task delegation, status colors showing active work - Step 4 (Observe): all green + metrics panel Dashboard preview font sizes scaled up throughout: - Header: text-sm for company name, text-xs for badges/status - Tabs: text-sm with larger icons (14px) - Sidebar: 8x8 icons (was 6x6), wider padding - Content area: h-[360px]/h-[420px] (was 280/320) - Bottom nav: text-xs page labels (was 9px) Mini component fonts scaled up: - OrgChartMini: fontSize 12/10 for name/seniority (was 9/7) - All minis: text-[8px] -> text-xs, text-[9px] -> text-xs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scroll sync: use threshold 0.5 with -45% rootMargin to prevent title flicker when scrolling between steps. OrgChartMini: wider viewBox (500x230), repositioned agents for landscape layout, constrain SVG with max-h-full so it fits the container without clipping bottom agents. Gemini + CodeRabbit review fixes: - ParticleNetwork: defensive null check for canvas.parentElement in resize() and ResizeObserver.observe() - DashboardPreview: remove redundant conditional in disabled button onClick handlers - BudgetMini: use React useId() for SVG gradient ID (prevents collisions), move defs before usage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Doc links: fix 8 broken hrefs pointing to nonexistent design pages (/docs/design/providers/, tools/, budget/, observability/) -- all now point to /docs/design/operations/ where those topics live. Scroll sync: fix observer rootMargin from -45% to -35% (was too restrictive, steps never triggered). Observer now always runs even with prefers-reduced-motion (only SMIL animations disabled, not step navigation). Org chart: remove noisy status dots from agent cards, remove bottom badge, wider SVG viewBox (500x230) for better landscape fit. ParticleNetwork: pause canvas when off-screen via IntersectionObserver (CPU/battery savings). Defensive null check for canvas.parentElement. DashboardPreview: clamp selectTab index to valid range, clean up redundant onClick conditionals on disabled buttons. BudgetMini: useId() for gradient (no ID collisions), move defs before usage, bump text-[7px] to text-[9px]. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Budget gauge: move percentage text above arc, "budget remaining" below. Increase viewBox height to prevent overlap. Org chart: highlight edges connected to active agent (solid cyan vs dashed faint). Active agent visually connected to its neighbors. Scroll sync steps: Step 2 (Configure) now shows agents WITHOUT edges. Step 3 (Collaborate) adds ALL edges + communication + status colors. Clear visual progression between steps. TaskBoardMini: tasks now move between columns based on tick. Each task progresses at a different rate (offset by id). Highlight cycles through tasks. Cards redistribute across Backlog/Progress/Review/Done. DashboardPreview: onMouseLeave checks if focus is still inside before resuming auto-cycle (a11y fix). ParticleNetwork: shared isVisible flag ensures onMotionChange never restarts animation while hero is off-screen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OrgChartMini: realistic communication patterns cycling each tick. TaskBoardMini: remove card highlighting. ParticleNetwork: pointer-events-none on overlay, repaint on resize when reduced-motion active. BudgetMini: var(--dp-accent) for gradient stops. DashboardPreview: pages.length instead of hardcoded 4/3. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AgentDetailMini: remove redundant font-mono Tailwind class (inline fontFamily var(--dp-font-mono) already handles it). Add comment explaining intentional index-as-key for infinite scroll effect. ScrollSyncPanel: dot click respects prefers-reduced-motion (uses "auto" scroll instead of "smooth"). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AgentDetailMini: replace rgba(16,185,129,0.15) with color-mix(in srgb, var(--dp-success) 15%, transparent) so the muted green derives from the theme variable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tasksCompleted now cycles 47-51 (was unbounded growth). costToday now cycles EUR 12.40-15.25 (was unbounded growth). Uses tick % 20 to create a natural repeating pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded hex colors in activities array with var(--dp-success), var(--dp-accent), var(--dp-warning) so the dots follow the dashboard preview theme. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3c406d5 to
95b4167
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
site/src/layouts/Base.astro (1)
70-70: 🧹 Nitpick | 🔵 TrivialBody font-family still hardcodes Inter despite Geist being loaded as the primary font.
The font preload URLs now prioritize Geist, and
DashboardPreview.css(line 16-17) defines--dp-font-sans: "Geist", "Inter", ..., but the body class still explicitly usesfont-['Inter',sans-serif]. This means the page will render in Inter even though Geist is loaded first.If Geist is intended as the primary font site-wide:
♻️ Proposed fix
- <body class="bg-[`#0F1219`] text-white font-['Inter',sans-serif] antialiased"> + <body class="bg-[`#0F1219`] text-white font-['Geist','Inter',sans-serif] antialiased">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/layouts/Base.astro` at line 70, The body element in Base.astro currently hardcodes Inter via the class font-['Inter',sans-serif] which overrides the intended primary Geist font; update the body class to use the CSS variable defined in DashboardPreview.css (--dp-font-sans) or a neutral utility (e.g., remove the explicit font utility) so the site-wide font resolves to Geist first; locate the body element in Base.astro and replace the explicit Inter font utility with usage of the --dp-font-sans variable (or a generic sans fallback) so Geist, as preloaded and defined in --dp-font-sans, becomes the primary font site-wide.
♻️ Duplicate comments (2)
site/src/components/islands/mini/AgentDetailMini.tsx (1)
93-95:⚠️ Potential issue | 🟠 MajorPause the activity ticker when users interact with it.
This loop keeps animating even when the surrounding preview is paused, so the panel still has moving content while someone is trying to read it.
🛠️ Minimal pause-on-hover/focus fix
- <div className="h-[72px] overflow-hidden relative"> - <div className="dp-activity-scroll"> + <div + className="h-[72px] overflow-hidden relative group" + tabIndex={0} + aria-label="Recent activity ticker. Hover or focus to pause scrolling." + > + <div className="dp-activity-scroll group-hover:[animation-play-state:paused] group-focus-within:[animation-play-state:paused]">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/mini/AgentDetailMini.tsx` around lines 93 - 95, The activity ticker inside AgentDetailMini keeps animating even when the preview is paused; update the dp-activity-scroll element to pause animations on user interaction by adding hover/focus handlers: in the AgentDetailMini component add a local state (e.g., isTickerPaused) and set it true on onMouseEnter/onFocus and false on onMouseLeave/onBlur, then apply a conditional class or inline style to the element with className "dp-activity-scroll" that sets animation-play-state: paused when isTickerPaused is true; this will pause the infinite scroll loop during hover/focus and resume afterward.site/src/components/islands/DashboardPreview.tsx (1)
113-119:⚠️ Potential issue | 🟡 MinorPull the header pills from the same mock snapshot.
These literals still say
7 agents/12 tasks, which no longer matches the preview snapshot described in this PR. Keeping them hardcoded will keep drifting the landing page out of sync with the mini pages.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/DashboardPreview.tsx` around lines 113 - 119, The two hardcoded header pills in DashboardPreview.tsx ("7 agents" and "12 tasks") must be replaced with values read from the same mock snapshot used to render the preview mini-page; locate the DashboardPreview component and the span elements that render the agents/tasks pills and substitute their literal strings with the corresponding properties from the preview mock object (the mock snapshot or prop passed into DashboardPreview—use that identifier in this file) so the pill counts come from the snapshot data instead of being hardcoded.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/ExpandableArchitecture.astro`:
- Around line 173-180: The current panels in ExpandableArchitecture.astro are
rendered as JS-only collapsible regions (div with id `panel-${arch.id}`,
aria-hidden and inert) that rely on a click handler to reveal links; replace
each JS-only panel with a semantic <details> and <summary> structure (use the
mapped identifier `btn-${arch.id}` as the summary id/label and
`panel-${arch.id}` as the details element) so the collapse is usable without JS,
remove `inert`/`aria-hidden` from the server-rendered markup, and update any
associated event handlers or CSS transitions (targeting the details open state)
instead of toggling attributes; alternatively, if you must keep the current
structure, render at least the first panel server-side as open (add the `open`
attribute) so the content is accessible without JS — ensure IDs and
aria-labelledby relationships remain consistent.
In `@site/src/components/islands/DashboardPreview.tsx`:
- Around line 30-44: The animation tick effect currently always advances tick;
change the second useEffect that sets setInterval for setTick so it
early-returns (does not create the interval) when isPaused or when the user's
reduced-motion preference is set (e.g., prefersReducedMotion/ reduceMotion
flag); include those flags in the effect's dependency array and clear the timer
when they change so the shared preview clock stops when isPaused or
reduced-motion is enabled. Ensure you reference the existing symbols: useEffect,
setTick, tick timer, isPaused, and your reduced-motion flag
(prefersReducedMotion) when making the change.
In `@site/src/components/islands/mini/BudgetMini.tsx`:
- Around line 23-26: The arc math uses radius = 52 while the SVG path uses A 50
50, causing incorrect gauge fill; update the calculation to use the actual arc
radius (50) or derive it from the SVG arc params so circumference = Math.PI *
actualRadius and dashOffset = circumference * (1 - gaugeValue / 100) reflect the
real arc; adjust the variables radius, circumference, and dashOffset in
BudgetMini (where radius, circumference, dashOffset, and gaugeValue are defined)
so the visual percentage matches the SVG A 50 50 arc.
---
Outside diff comments:
In `@site/src/layouts/Base.astro`:
- Line 70: The body element in Base.astro currently hardcodes Inter via the
class font-['Inter',sans-serif] which overrides the intended primary Geist font;
update the body class to use the CSS variable defined in DashboardPreview.css
(--dp-font-sans) or a neutral utility (e.g., remove the explicit font utility)
so the site-wide font resolves to Geist first; locate the body element in
Base.astro and replace the explicit Inter font utility with usage of the
--dp-font-sans variable (or a generic sans fallback) so Geist, as preloaded and
defined in --dp-font-sans, becomes the primary font site-wide.
---
Duplicate comments:
In `@site/src/components/islands/DashboardPreview.tsx`:
- Around line 113-119: The two hardcoded header pills in DashboardPreview.tsx
("7 agents" and "12 tasks") must be replaced with values read from the same mock
snapshot used to render the preview mini-page; locate the DashboardPreview
component and the span elements that render the agents/tasks pills and
substitute their literal strings with the corresponding properties from the
preview mock object (the mock snapshot or prop passed into DashboardPreview—use
that identifier in this file) so the pill counts come from the snapshot data
instead of being hardcoded.
In `@site/src/components/islands/mini/AgentDetailMini.tsx`:
- Around line 93-95: The activity ticker inside AgentDetailMini keeps animating
even when the preview is paused; update the dp-activity-scroll element to pause
animations on user interaction by adding hover/focus handlers: in the
AgentDetailMini component add a local state (e.g., isTickerPaused) and set it
true on onMouseEnter/onFocus and false on onMouseLeave/onBlur, then apply a
conditional class or inline style to the element with className
"dp-activity-scroll" that sets animation-play-state: paused when isTickerPaused
is true; this will pause the infinite scroll loop during hover/focus and resume
afterward.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: dce4cc4c-5cba-4922-8a53-d6466116e07f
⛔ Files ignored due to path filters (1)
site/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (16)
CLAUDE.mdsite/astro.config.mjssite/package.jsonsite/src/components/ExpandableArchitecture.astrosite/src/components/FeatureShowcase.astrosite/src/components/ParticleNetwork.astrosite/src/components/ScrollSyncPanel.astrosite/src/components/UseCaseCards.astrosite/src/components/islands/DashboardPreview.csssite/src/components/islands/DashboardPreview.tsxsite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/layouts/Base.astrosite/src/pages/index.astro
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Socket Security: Pull Request Alerts
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (56)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones in the React dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/package.json : Web dashboard Node.js 22+, TypeScript 6.0+, dependencies in `web/package.json`
Applied to files:
site/package.jsonCLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Applied to files:
site/package.jsonsite/astro.config.mjsCLAUDE.mdsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/pages/index.astro
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to web/package.json : Web dashboard Node.js 20+; dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)
Applied to files:
site/package.jsonsite/astro.config.mjsCLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
Applied to files:
site/package.jsonCLAUDE.md
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/.storybook/{main,preview}.{ts,tsx} : Storybook 10: Use `defineMain` from `storybook/react-vite/node` and `definePreview` from `storybook/react-vite` in Storybook config files
Applied to files:
site/package.jsonsite/astro.config.mjs
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{ts,tsx} : CSS side-effect imports need type declarations; use Vite's `/// <reference types="vite/client" />` directive
Applied to files:
site/package.jsonsite/astro.config.mjs
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `font-sans` or `font-mono` for typography (maps to Geist tokens). NEVER set `fontFamily` directly
Applied to files:
site/src/layouts/Base.astrosite/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Web dashboard: see `web/CLAUDE.md` for commands, design system, and component inventory
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T21:35:00.759Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to docs/design/**/*.md : Update the relevant `docs/design/` page to reflect approved deviations from the original spec
Applied to files:
CLAUDE.mdsite/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/api/**/*.md : Library reference in `docs/api/` (auto-generated via mkdocstrings + Griffe, AST-based)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to {docs/rest-api.md,docs/_generated/api-reference.html} : REST API reference in `docs/rest-api.md` + `docs/_generated/api-reference.html` (generated by `scripts/export_openapi.py`)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
CLAUDE.mdsite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to pyproject.toml : Docs group in `pyproject.toml` includes: `zensical`, `mkdocstrings[python]`, `griffe-pydantic`
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to scripts/**/*.py : Scripts in `scripts/` (CI/build utilities and development-time validation hooks) — relaxed ruff rules: `print` and deferred imports allowed
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T21:35:00.759Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones in the React dashboard
Applied to files:
CLAUDE.mdsite/src/components/islands/DashboardPreview.tsxsite/src/pages/index.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
CLAUDE.mdsite/src/components/UseCaseCards.astrosite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/ExpandableArchitecture.astrosite/src/components/islands/mini/BudgetMini.tsxsite/src/components/islands/DashboardPreview.tsxsite/src/components/ScrollSyncPanel.astrosite/src/pages/index.astro
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).
Applied to files:
CLAUDE.mdsite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Install via `uv sync` (installs all deps including dev group by default)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-21T12:54:22.557Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T12:54:22.557Z
Learning: Go 1.26+ required; CLI dependencies in `cli/go.mod` (Cobra, charmbracelet/huh, charmbracelet/lipgloss, sigstore-go, go-containerregistry, go-tuf)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-21T14:12:17.848Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T14:12:17.848Z
Learning: Applies to cli/go.mod : CLI uses Go 1.26+. Dependencies: Cobra, charmbracelet/huh, charmbracelet/lipgloss, sigstore-go, go-containerregistry, go-tuf
Applied to files:
CLAUDE.md
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT build card-with-header layouts from scratch -- use `<SectionCard>` component
Applied to files:
site/src/components/UseCaseCards.astrosite/src/pages/index.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/UseCaseCards.astrosite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/UseCaseCards.astrosite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T21:35:00.759Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions in React components; use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/DashboardPreview.csssite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/DashboardPreview.csssite/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create metric displays with `text-metric font-bold` -- use `<MetricCard>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT create complex (>8 line) JSX inside `.map()` -- extract to a shared component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsxsite/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/mini/OrgChartMini.tsxsite/src/components/islands/mini/BudgetMini.tsxsite/src/components/ScrollSyncPanel.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing. NEVER hardcode pixel values for layout spacing
Applied to files:
site/src/components/islands/mini/AgentDetailMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astro
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. DESIGN_SPEC.md is a pointer file linking to the 7 design pages (index, agents, organization, communication, engine, memory, operations).
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/components/ExpandableArchitecture.astrosite/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-03-18T08:23:08.912Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T08:23:08.912Z
Learning: When approved deviations occur, update the relevant `docs/design/` page to reflect the new reality.
Applied to files:
site/src/components/FeatureShowcase.astro
📚 Learning: 2026-04-01T21:35:00.759Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue; design spec is the starting point for architecture, data models, and behavior
Applied to files:
site/src/components/FeatureShowcase.astrosite/src/pages/index.astro
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Create a `.stories.tsx` Storybook file alongside each new shared component with all states (default, hover, loading, error, empty)
Applied to files:
site/src/components/islands/mini/TaskBoardMini.tsxsite/src/components/islands/DashboardPreview.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Export props as a TypeScript interface for new components
Applied to files:
site/src/components/islands/mini/OrgChartMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Security: SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume).
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/security/**/*.py : Security module includes SecOps agent, rule engine (soft-allow/hard-deny), audit log, output scanner, risk classifier, autonomy levels (4 strategies), timeout policies.
Applied to files:
site/src/pages/index.astro
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Gitleaks scans for secrets via pre-commit hook and weekly CI job
Applied to files:
site/src/pages/index.astro
🔇 Additional comments (12)
site/src/components/ScrollSyncPanel.astro (4)
245-256: Reduced-motion: SMIL animations still render in initial HTML.The
<animate>elements are part of the server-rendered markup (lines 247, 250, 255). Users withprefers-reduced-motion: reducewill see animation on first paint before the client script removes them. This was flagged in a previous review.The fix requires either:
- Not rendering
<animate>elements server-side, adding them via JS only when motion is allowed- Using CSS to initially pause animations and only enable them client-side
425-436: Reduced-motion preference changes still not handled dynamically.The script checks
prefersReduced.matchesonce at load time but doesn't listen for changes. UnlikeOrgChartMini.tsxwhich usesaddEventListener("change", handler), this component cannot restore animations if the user toggles their preference. This was flagged in a previous review.
280-311: LGTM on the step synchronization logic.The
setStepfunction withcurrentStepguard prevents redundant updates. The SVG element lookups and step-specific visibility logic are well-organized.
438-456: LGTM on IntersectionObserver setup.Proper configuration with
-35%root margin for scroll-synced step detection. Theastro:before-swapcleanup correctly disconnects the observer for Astro's view transitions.site/astro.config.mjs (1)
4-4: LGTM!Standard React integration setup. The import and registration in the
integrationsarray follow the correct pattern for@astrojs/reactv5 with Astro 6.Also applies to: 11-11
site/package.json (1)
12-25: LGTM!Dependencies are correctly structured: runtime packages (
@astrojs/react,react,react-dom) independencies, type packages indevDependencies. React 19 aligns with the project's web dashboard stack.site/src/components/FeatureShowcase.astro (1)
89-114: LGTM!Well-structured hero card rendering with proper accessibility features:
- Focus-visible ring styles for keyboard navigation
- Color-coded visual hierarchy with consistent theming
- Semantic anchor elements for navigation
The dynamic class generation using ternary operators with full class name literals will be correctly detected by Tailwind's content scanner.
site/src/components/islands/mini/OrgChartMini.tsx (2)
40-49: Well-implemented reduced-motion handling.Unlike the server-rendered SVG in
ScrollSyncPanel.astro, this React component correctly uses state-driven conditional rendering for SMIL animations. TheuseEffectproperly:
- Initializes from the current preference
- Listens for dynamic changes
- Cleans up the listener on unmount
This allows animations to toggle without page reload when the user changes their motion preference.
55-133: LGTM!The SVG rendering is clean:
- Decorative chart correctly marked with
aria-hidden="true"- CSS custom properties (
--dp-font-sans,--dp-bg-card) used for theming consistency- Communication edge animations conditionally rendered based on motion preference
CLAUDE.md (1)
63-64: LGTM!Documentation accurately reflects the new architecture:
- Landing page now uses React islands via
@astrojs/react- Dependencies correctly listed (Astro 6,
@astrojs/react, React 19, Tailwind CSS 4)Also applies to: 109-110, 236-236
site/src/components/UseCaseCards.astro (2)
72-98: LGTM!Well-implemented responsive card layout with strong accessibility:
role="region"witharia-labelidentifies the scrollable areatabindex="0"enables keyboard users to scroll the container- Snap-scroll alignment (
snap-x snap-mandatory) provides good mobile UX- Responsive breakpoint switches from horizontal scroll to grid layout
100-135: Nice custom scrollbar and fade mask implementation.The CSS properly:
- Uses both standard (
scrollbar-width) and WebKit prefixes for cross-browser support- Applies gradient mask only on mobile (
max-width: 1023px) where scroll is active- Includes both
-webkit-mask-imageand standardmask-imagefor compatibility
| {architecture.map((arch) => ( | ||
| <div | ||
| id={`panel-${arch.id}`} | ||
| role="region" | ||
| aria-labelledby={`btn-${arch.id}`} | ||
| aria-hidden="true" | ||
| inert | ||
| class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-300 ease-in-out" |
There was a problem hiding this comment.
Don’t make the architecture links JS-only.
Every panel ships closed with aria-hidden + inert, and the click handler is the only path to reveal the submodule links. If JS is blocked or fails, this section becomes dead UI. In Astro, this is a better fit for semantic <details>/<summary> or at least one server-rendered open panel.
Also applies to: 198-232
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/ExpandableArchitecture.astro` around lines 173 - 180, The
current panels in ExpandableArchitecture.astro are rendered as JS-only
collapsible regions (div with id `panel-${arch.id}`, aria-hidden and inert) that
rely on a click handler to reveal links; replace each JS-only panel with a
semantic <details> and <summary> structure (use the mapped identifier
`btn-${arch.id}` as the summary id/label and `panel-${arch.id}` as the details
element) so the collapse is usable without JS, remove `inert`/`aria-hidden` from
the server-rendered markup, and update any associated event handlers or CSS
transitions (targeting the details open state) instead of toggling attributes;
alternatively, if you must keep the current structure, render at least the first
panel server-side as open (add the `open` attribute) so the content is
accessible without JS — ensure IDs and aria-labelledby relationships remain
consistent.
| // Auto-cycle tabs | ||
| useEffect(() => { | ||
| if (isPaused) return; | ||
| const timer = setInterval(() => { | ||
| setActiveTab((t) => (t + 1) % pages.length); | ||
| setPageKey((k) => k + 1); | ||
| }, 6000); | ||
| return () => clearInterval(timer); | ||
| }, [isPaused]); | ||
|
|
||
| // Animation tick (1Hz) | ||
| useEffect(() => { | ||
| const timer = setInterval(() => setTick((t) => t + 1), 1000); | ||
| return () => clearInterval(timer); | ||
| }, []); |
There was a problem hiding this comment.
Pause and reduced-motion should stop the shared preview clock.
isPaused only stops tab rotation. tick keeps advancing, so hover/focus "pause" still leaves the active mini page changing every second, and reduced-motion users still get automatic updates.
🛠️ Example of a shared animation gate
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
+
+ useEffect(() => {
+ const media = window.matchMedia("(prefers-reduced-motion: reduce)");
+ const sync = () => setPrefersReducedMotion(media.matches);
+ sync();
+ media.addEventListener("change", sync);
+ return () => media.removeEventListener("change", sync);
+ }, []);
+
+ const shouldAnimate = !isPaused && !prefersReducedMotion;
+
// Auto-cycle tabs
useEffect(() => {
- if (isPaused) return;
+ if (!shouldAnimate) return;
const timer = setInterval(() => {
setActiveTab((t) => (t + 1) % pages.length);
setPageKey((k) => k + 1);
}, 6000);
return () => clearInterval(timer);
- }, [isPaused]);
+ }, [shouldAnimate]);
// Animation tick (1Hz)
useEffect(() => {
+ if (!shouldAnimate) return;
const timer = setInterval(() => setTick((t) => t + 1), 1000);
return () => clearInterval(timer);
- }, []);
+ }, [shouldAnimate]);Also applies to: 59-69
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/islands/DashboardPreview.tsx` around lines 30 - 44, The
animation tick effect currently always advances tick; change the second
useEffect that sets setInterval for setTick so it early-returns (does not create
the interval) when isPaused or when the user's reduced-motion preference is set
(e.g., prefersReducedMotion/ reduceMotion flag); include those flags in the
effect's dependency array and clear the timer when they change so the shared
preview clock stops when isPaused or reduced-motion is enabled. Ensure you
reference the existing symbols: useEffect, setTick, tick timer, isPaused, and
your reduced-motion flag (prefersReducedMotion) when making the change.
The arc path uses A 50 50 but the JS calculation used radius=52, causing the dash offset to not match the visible arc length. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@site/src/components/islands/mini/BudgetMini.tsx`:
- Around line 17-28: The forecast never exceeds 500 with the current math, so
change the forecast calculation to allow values >500 (e.g. increase the
multiplier) and keep numeric comparison intact: update the forecast expression
in BudgetMini.tsx (symbol: forecast) from (500 * (1 - gaugeValue / 100) *
1.15).toFixed(2) to use a larger multiplier such as 1.5 (and still call
toFixed(2) for display), so forecastColor (symbol: forecastColor) can
realistically hit the "var(--dp-warning)" branch; ensure you still
parseFloat(forecast) for the comparison.
- Line 53: The progress bar in BudgetMini.tsx currently uses the classes
"transition-all duration-1000" which don't respect prefers-reduced-motion;
update the element that renders the progress fill (the same element using
transition-all) to add a reduced-motion fallback such as
"motion-reduce:transition-none" (or equivalent framework utility) so users with
prefers-reduced-motion will get no transition; keep the existing classes and
just append the motion-reduce utility to the className on the progress/fill
element (the element related to .dp-gauge-fill / progress fill).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3f31bbd3-e4e3-4aff-a5f4-64bfafdc9c5e
📒 Files selected for processing (1)
site/src/components/islands/mini/BudgetMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones in the React dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T21:35:00.759Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions in React components; use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
🔇 Additional comments (1)
site/src/components/islands/mini/BudgetMini.tsx (1)
15-16: Good use ofuseIdfor SVG gradient IDs.This avoids duplicate
idcollisions when multiple instances render.Also applies to: 115-132
| strokeLinecap="round" | ||
| strokeDasharray={`${circumference}`} | ||
| strokeDashoffset={dashOffset} | ||
| className="dp-gauge-fill" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether reduced-motion handling exists for BudgetMini animations.
# Expected: either Tailwind motion-reduce utilities on the elements,
# or CSS media-query overrides for `.dp-gauge-fill` and related transitions.
rg -n -C3 'dp-gauge-fill|transition-all|motion-reduce|prefers-reduced-motion' site/srcRepository: Aureliolo/synthorg
Length of output: 25621
🏁 Script executed:
# Check imports and CSS dependencies in BudgetMini.tsx
head -60 site/src/components/islands/mini/BudgetMini.tsxRepository: Aureliolo/synthorg
Length of output: 2290
🏁 Script executed:
# Check if DashboardPreview.css or other CSS files are imported
rg -n 'import.*\.css|import.*DashboardPreview' site/src/components/islands/mini/Repository: Aureliolo/synthorg
Length of output: 44
🏁 Script executed:
# Look for any motion-reduce or prefers-reduced-motion handling in BudgetMini.tsx
rg -n 'motion-reduce|prefers-reduced-motion|matchMedia' site/src/components/islands/mini/BudgetMini.tsxRepository: Aureliolo/synthorg
Length of output: 44
🏁 Script executed:
# Get full file length
wc -l site/src/components/islands/mini/BudgetMini.tsxRepository: Aureliolo/synthorg
Length of output: 113
🏁 Script executed:
# Read full BudgetMini.tsx to check all imports and CSS references
cat site/src/components/islands/mini/BudgetMini.tsxRepository: Aureliolo/synthorg
Length of output: 6083
🏁 Script executed:
# Check where dp-gauge-fill is actually defined
rg -l 'dp-gauge-fill' site/src --type cssRepository: Aureliolo/synthorg
Length of output: 110
🏁 Script executed:
# Check if DashboardPreview.css is imported globally or in layout
rg -n 'DashboardPreview.css|dp-gauge-fill|dp-border|dp-accent' site/src/layouts/ site/src/components/Layout.astro 2>/dev/null || trueRepository: Aureliolo/synthorg
Length of output: 44
🏁 Script executed:
# Check if DashboardPreview.css is imported in the main layout or globally
rg -n 'DashboardPreview.css' site/src --type astro --type tsx --type tsRepository: Aureliolo/synthorg
Length of output: 91
🏁 Script executed:
# Check where DashboardPreview component is used and how CSS is scoped
head -100 site/src/components/islands/DashboardPreview.tsx | grep -E "import|className|css"Repository: Aureliolo/synthorg
Length of output: 744
🏁 Script executed:
# Look for how Tailwind handles motion-reduce for duration classes
rg -A2 'motion-reduce|duration-1000' site/src/components --type tsx | head -50Repository: Aureliolo/synthorg
Length of output: 89
🏁 Script executed:
# Check where BudgetMini is used - is it always within DashboardPreview?
rg -n 'BudgetMini' site/src --type tsxRepository: Aureliolo/synthorg
Length of output: 89
🏁 Script executed:
# Check Tailwind config to see if motion-reduce is enabled globally
find site -name 'tailwind.config.*' -o -name 'tailwind.config.js' | head -1 | xargs catRepository: Aureliolo/synthorg
Length of output: 44
🏁 Script executed:
# Check if there's a globals CSS or base layout that imports DashboardPreview.css
rg -n 'DashboardPreview.css|import.*css' site/src/layouts/ site/src/ -m 10 | grep -E 'layout|main|index'Repository: Aureliolo/synthorg
Length of output: 183
🏁 Script executed:
# Check if BudgetMini is used outside DashboardPreview
rg -B2 -A2 'BudgetMini' site/srcRepository: Aureliolo/synthorg
Length of output: 1198
🏁 Script executed:
# Check Tailwind config for motion settings
find site -name '*.config.*' -type f | xargs cat 2>/dev/null | grep -A10 'motion\|animation'Repository: Aureliolo/synthorg
Length of output: 44
🏁 Script executed:
# Check if transition-all respects motion-reduce in Tailwind by default
rg -n 'transition-all.*motion' site --type cssRepository: Aureliolo/synthorg
Length of output: 44
Add reduced-motion fallback for the progress bar animation.
The gauge arc (line 53, .dp-gauge-fill) respects prefers-reduced-motion via the linked CSS file. However, the progress bar animation at lines 97–99 uses transition-all duration-1000 without an explicit fallback. Add motion-reduce:transition-none or similar to disable the animation for users who prefer reduced motion.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@site/src/components/islands/mini/BudgetMini.tsx` at line 53, The progress bar
in BudgetMini.tsx currently uses the classes "transition-all duration-1000"
which don't respect prefers-reduced-motion; update the element that renders the
progress fill (the same element using transition-all) to add a reduced-motion
fallback such as "motion-reduce:transition-none" (or equivalent framework
utility) so users with prefers-reduced-motion will get no transition; keep the
existing classes and just append the motion-reduce utility to the className on
the progress/fill element (the element related to .dp-gauge-fill / progress
fill).
With 1.15x, forecast maxed at ~402 (never exceeding 500 budget), making the warning branch dead code. With 1.5x, forecast reaches ~525 when gauge is low, correctly showing the warning color. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
site/src/components/islands/mini/BudgetMini.tsx (1)
97-99:⚠️ Potential issue | 🟡 MinorAdd reduced-motion fallback to the agent spend bar transitions.
Line 97 still animates unconditionally; this should respect
prefers-reduced-motion.♿ Minimal fix
- className="h-full rounded-full transition-all duration-1000" + className="h-full rounded-full transition-all duration-1000 motion-reduce:transition-none"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@site/src/components/islands/mini/BudgetMini.tsx` around lines 97 - 99, The agent spend bar currently always uses "transition-all duration-1000" (the JSX element with className="h-full rounded-full transition-all duration-1000" and style={{ width: `${a.pct}%`, background: a.color }}), which ignores the user's prefers-reduced-motion setting; detect prefers-reduced-motion (e.g. via window.matchMedia('(prefers-reduced-motion: reduce)') or a usePrefersReducedMotion hook) and conditionally remove the transition classes or set transition: 'none' on that element when reduced motion is requested so the bar updates instantly for those users.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@site/src/components/islands/mini/BudgetMini.tsx`:
- Around line 97-99: The agent spend bar currently always uses "transition-all
duration-1000" (the JSX element with className="h-full rounded-full
transition-all duration-1000" and style={{ width: `${a.pct}%`, background:
a.color }}), which ignores the user's prefers-reduced-motion setting; detect
prefers-reduced-motion (e.g. via window.matchMedia('(prefers-reduced-motion:
reduce)') or a usePrefersReducedMotion hook) and conditionally remove the
transition classes or set transition: 'none' on that element when reduced motion
is requested so the bar updates instantly for those users.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: c90591bf-1d6b-477c-86ae-ca2c34eb5220
📒 Files selected for processing (1)
site/src/components/islands/mini/BudgetMini.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use React 19, TypeScript 6.0+, and design system tokens from shadcn/ui + Tailwind CSS 4 + Radix UI in web dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones in the React dashboard
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : ALWAYS reuse existing components from `web/src/components/ui/` before creating new ones (StatusBadge, MetricCard, Sparkline, SectionCard, AgentCard, DeptHealthBar, ProgressGauge, StatPill, Avatar, Button, Toast, Skeleton, EmptyState, ErrorBoundary, ConfirmDialog, CommandPalette, InlineEdit, AnimatedPresence, StaggerGroup, Drawer, InputField, SelectField, SliderField, ToggleField, TaskStatusIndicator, PriorityBadge, ProviderHealthBadge, TokenUsageBar, CodeMirrorEditor, SegmentedControl, ThemeToggle, LiveRegion, MobileUnsupportedOverlay, LazyCodeMirrorEditor, TagInput, MetadataGrid, ProjectStatusBadge, ContentTypeBadge)
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T21:35:00.759Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T21:35:00.759Z
Learning: Applies to web/src/**/*.{ts,tsx} : Never hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions in React components; use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-*)`) for colors. NEVER hardcode hex values or rgba() in `.tsx`/`.ts` files
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/components/ui/**/*.tsx : Use design tokens exclusively in new components -- no hardcoded colors, fonts, or spacing
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to web/src/**/*.{ts,tsx} : NEVER hardcode hex colors, font-family, pixel spacing, or Framer Motion transitions — use design tokens and `@/lib/motion` presets
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Do NOT recreate status dots inline -- use `<StatusBadge>` component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. NEVER hardcode shadow or border values
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use Framer Motion presets from `@/lib/motion` instead of hardcoded transition durations
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
📚 Learning: 2026-04-01T06:54:44.133Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2026-04-01T06:54:44.133Z
Learning: Applies to web/src/**/*.{tsx,ts} : Use `health?` prop (optional, shows N/A when null) and `agentCount` (required) for DeptHealthBar component
Applied to files:
site/src/components/islands/mini/BudgetMini.tsx
🔇 Additional comments (2)
site/src/components/islands/mini/BudgetMini.tsx (2)
24-26: Arc dash math now correctly matches the SVG geometry.Line 24 using radius
50aligns with theA 50 50path, so the gauge fill percentage renders consistently.
17-29:⚠️ Potential issue | 🟠 MajorForecast warning state is still unreachable with current thresholds.
At Line 28,
forecast <= 500stays true for the currentgaugeValuerange from Lines 17-21, so the warning color branch never executes.💡 Proposed fix
- const spent = (500 * (1 - gaugeValue / 100)).toFixed(2); - const remaining = (500 * (gaugeValue / 100)).toFixed(2); - const forecast = (500 * (1 - gaugeValue / 100) * 1.5).toFixed(2); + const monthlyBudget = 500; + const spentValue = monthlyBudget * (1 - gaugeValue / 100); + const remainingValue = monthlyBudget * (gaugeValue / 100); + const forecastValue = spentValue * 1.5; + const spent = spentValue.toFixed(2); + const remaining = remainingValue.toFixed(2); + const forecast = forecastValue.toFixed(2); @@ - const forecastColor = parseFloat(forecast) <= 500 ? "var(--dp-success)" : "var(--dp-warning)"; + const warningThreshold = monthlyBudget * 0.6; // tune to intended UX threshold + const forecastColor = + forecastValue >= warningThreshold ? "var(--dp-warning)" : "var(--dp-success)";⛔ Skipped due to learnings
Learnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use `color?` and `animated?` props for Sparkline component (inline SVG trend lines)Learnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use `variant?` prop (defaults to `'circular'`) and `max?` prop (defaults to 100) for ProgressGauge componentLearnt from: CR Repo: Aureliolo/synthorg PR: 0 File: web/CLAUDE.md:0-0 Timestamp: 2026-04-01T06:54:44.133Z Learning: Applies to web/src/**/*.{tsx,ts} : Use role="meter" for TokenUsageBar component with animated multi-segment transitions
🤖 I have created a release *beep* *boop* --- ## [0.5.6](v0.5.5...v0.5.6) (2026-04-02) ### Features * calendar + hybrid ceremony scheduling strategies ([#985](#985)) ([59a9b84](59a9b84)), closes [#969](#969) [#970](#970) * landing page interactive components ([#984](#984)) ([49868cb](49868cb)) * log aggregation and shipping (syslog, HTTP, compression) ([#964](#964)) ([84be9f8](84be9f8)) * restructure builtin templates into inheritance tree ([#982](#982)) ([3794c12](3794c12)) * sprint ceremony runtime scheduler with pluggable strategies ([#983](#983)) ([43564a9](43564a9)) ### Maintenance * add no-bash-file-writes rule to CLAUDE.md ([#968](#968)) ([a854dcc](a854dcc)) * bump web dependencies (lodash, eslint-react v4, storybook, playwright, esbuild, codemirror) ([#987](#987)) ([c344dfb](c344dfb)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
@astrojs/reactfor React islands architecture -- React only loads when dashboard preview scrolls into view (client:visible), keeping above-the-fold JS at ~2KBContent accuracy
Test plan
npm --prefix site run buildpasses with zero errorsnpm --prefix site run devat localhostReview coverage
Skipping agent review (site-only changes, no backend/dashboard/CLI code). Build verified.
Closes #294