# Project export: Redundant

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2026
- Tagline: Your AI agents burn budget on calls you never see. Redundant catches the duplicate calls, logic loops, and cross-agent repetition a cache can't, prices them in dollars, and fixes or flags each.
- Devpost: https://devpost.com/software/redundant
- GitHub: https://github.com/aymbrrr/CalHacks.git
- Video: https://www.youtube.com/embed/LlrGQzr46BU?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 5 GitHub contributor(s) — Isaac Pressman (20 commits), Hailey Morgan (15 commits), juliameylu (8 commits), Jason X (7 commits), Claude Sonnet 4.6 (5 commits)

## Devpost submission (written by the team)

### Overview

Overview Redundant is a trace level profiler and cost firewall for multi agent AI workflows.

### Inspiration

Multi agent runs are becoming increasingly popular. We noticed they get expensive fast, with no easy to digest insights into why. A single research assistant can make dozens of tool and LLM calls, many of which are, well, redundant! We were inspired to make a tool beyond prompt caching that could catch issues like runaway loops, tool repetition, and multi agent redundancy and provide fixes that save users real money.

### What it does

Redundant sees the entire execution trace, finds waste that call-level tools can't see, pins a cost to each finding, and routes it to a fix or alert. There are two main detectors, one for catching repetitive tool calls and one for cycles, that flags agent loops. The detectors are priced with a per model token cost, such as, $X wasted of $Y total with a percentage visible on the UI to account for model pricing differences. Read only redundancy is forked to LangCache which is gated so we never serve an unsafe or stale result. High count or side effect repetition fires a Sentry alert on the dashboard since this suggests a reliability incident. The dashboard UI renders the run as a flamegraph, with issues in red, and prompts fixes such as a re-run with duplicated calls from the cache instead so you can see the cost drop in real time.

### How we built it

The backend is Python and FastAPI. Redis is integrated as the trace bus (Streams) and the cache (LangCache). Detection uses simple frequency grouping plus networkx for cycle detection. The dashboard is React + Vite with a custom SVG flamegraph. Band generates the demo trace, emitting one span per call on Redis Streams. The ingestion layer reads the stream, normalizes spans into an in-memory tree and call graph, and feeds the detectors. Findings flow out of a single FastAPI contract that both the UI and the remediation router consume: cacheable findings round-trip through LangCache, runaway findings go to Sentry via the SDK.

### Challenges we ran into

We ran into challenges wiring up the Band agents, Redis Vectorsearch, and the front end together. We had to coordinate closely as a team to get all of our working parts together.

### Accomplishments we're proud of

We are proud of making a working end-to-end product with several integrations within the short hackathon timeframe. Redundant actually traces multi-agent trace flows from Band through Redis Streams into our detectors, gets priced in real dollars on real spans, and routes itself to the right place. The most rewarding part for us was getting the fixes working and watching one go to LangCache while the other fires a Sentry alert in real time.

### What we learned

We learned the value of stepping back from call level AI cost tools and considering the issues that come up when you trace the run as a whole. We also learned a lot about Redis tools and when caching is safe versus unsafe with a read-only allowlist.

### What's next

We had some reach goals that we didn't quite have time for: A compression path for calls that are unsafe to cache but have bloated prompts, plus prompt-cache layout hints for the underlying model. A labeled evaluation set (via Terac) to validate the verifier's reuse decisions on held-out call pairs raw similarity versus verifier-gated reuse, with the numbers to back it up.

## README (from the GitHub repository)

# CalHacks

Planning materials for the Redundant hackathon project.

- [Redundant implementation plan](docs/redundant-plan.md)
- [Additional implementation context](docs/redundant-additional-context.md)
- [Original hackathon planning document](redundant_hackathon_plan.md)


## Detected evidence (automated analysis)

Indexed codebase: 84 recognized source files, 436 KB.
- FastAPI (technology) — detected in the code
- HTML (language) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Redis (technology) — detected in the code
- TypeScript (language) — detected in the code
- JavaScript (language) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: commit authorship or trailers

## Codebase structure (from repository index)

### Files (100 of 100)

```
.gitignore
agent_config.example.yaml
backend/.env.example
backend/.gitignore
backend/pyproject.toml
backend/README.md
backend/redundant/__init__.py
backend/redundant/api.py
backend/redundant/compressor.py
backend/redundant/config.py
backend/redundant/decision.py
backend/redundant/demo_trace.json
backend/redundant/demo.py
backend/redundant/detection.py
backend/redundant/embeddings.py
backend/redundant/estimate.py
backend/redundant/lang_cache.py
backend/redundant/memory_store.py
backend/redundant/normalize.py
backend/redundant/pricing.py
backend/redundant/redis_store.py
backend/redundant/report.py
backend/redundant/routing.py
backend/redundant/runtime.py
backend/redundant/schema.py
backend/redundant/sentry_dispatch.py
backend/redundant/span_schema.py
backend/redundant/tools.py
backend/redundant/trace_ingest.py
backend/redundant/verifier.py
backend/scripts/record_trace.py
backend/scripts/run_waste_demo.py
backend/scripts/verify_pipeline.py
backend/tests/conftest.py
backend/tests/test_api.py
backend/tests/test_decision.py
backend/tests/test_estimate.py
backend/tests/test_normalize.py
backend/tests/test_redis_store.py
backend/tests/test_report.py
backend/tests/test_runtime.py
backend/tests/test_schema.py
backend/tests/test_sentry.py
backend/uv.lock
demos/band/__init__.py
demos/band/agents/__init__.py
demos/band/agents/audit_agent.py
demos/band/agents/report_agent.py
demos/band/agents/research_agent.py
demos/band/agents/verifier_agent.py
demos/band/band_room_adapter.py
demos/band/fallback_band_room.py
demos/band/README.md
demos/band/real_band_adapter.py
demos/band/redundant_client.py
demos/band/redundant_runtime.py
demos/band/replay_trace.py
demos/band/run_band_demo.py
demos/band/run_real_band_agents.py
demos/band/scripted_tools.py
demos/band/trace_writer.py
demos/band/traces/band_demo_baseline_trace.json
demos/band/traces/band_demo_real_band_trace.json
demos/band/traces/band_demo_trace.json
docs/BAND_REQUIREMENTS.md
docs/DESIGN_redis.md
docs/redundant_master_plan.md
docs/SENTRY_REQUIREMENTS.md
docs/SHARED_AND_INTEGRATION.md
docs/UI_REQUIREMENTS.md
frontend/index.html
frontend/package.json
frontend/public/fixtures/findings.json
frontend/README.md
frontend/src/api/client.ts
frontend/src/api/displayMoney.ts
frontend/src/api/modelInfo.ts
frontend/src/App.tsx
frontend/src/components/DevInspector.tsx
frontend/src/components/ErrorBoundary.tsx
frontend/src/components/FindingsList.tsx
frontend/src/components/FixSuggestions.tsx
frontend/src/components/Flamegraph.tsx
frontend/src/components/HeadlineBanner.tsx
frontend/src/components/RerunBar.tsx
frontend/src/components/RootCausePanel.tsx
frontend/src/components/spanLayout.ts
frontend/src/components/SpanTimeline.tsx
frontend/src/components/TopBar.tsx
frontend/src/main.tsx
frontend/src/theme.ts
frontend/src/types.ts
frontend/tsconfig.json
frontend/tsconfig.node.json
frontend/vite.config.ts
LICENSE
pyproject.toml
README.md
scripts/verify_redundant_routing.py
uv.lock
```

### Dependencies

- backend/pyproject.toml: band-sdk@>=1.0.0, fastapi@>=0.110, httpx@>=0.27, networkx@>=3.2, openai@>=1.20, pydantic@>=2.6, pytest@>=8.0, pytest-asyncio@>=0.23, python-dotenv@>=1.0, redis@>=5.0, sentry-sdk@>=2.0, sse-starlette@>=2.0, uvicorn[standard]@>=0.27
- frontend/package.json: @types/react@^18.3.3, @types/react-dom@^18.3.0, @vitejs/plugin-react@^4.3.1, react@^18.3.1, react-dom@^18.3.1, typescript@^5.5.3, vite@^5.4.0
- pyproject.toml: band-sdk@>=1.0.0, openai@>=2.43.0, pyyaml@>=6.0

### Recent commits (newest first)

- Merge branch 'main' of https://github.com/aymbrrr/CalHacks
- Add windowing and cluster collapse to Flamegraph
- hopefully didnt break
- bedtime
- ah oh
- trace writer
- Merge branch 'dynamic-integration' into main
- agents fully integrated with backend
- Integrate real Band SDK agents with dynamic runtime and updated traces
- Merge branch 'main' of https://github.com/aymbrrr/CalHacks
- fix
- Wire real Band SDK agents into API run endpoint
- Merge branch 'main' into dynamic-integration
- Wire Band demo end-to-end: verify_source fix, store threading, live SSE frontend
- Merge branch 'main' of https://github.com/aymbrrr/CalHacks
- Frontend resilience + trace fallback
- fixes
- Frontend stuff
- Merge origin/main: resolve MODEL_PRICING conflict, untrack node_modules
- stuff

## Key source files (fetched from GitHub, selected and truncated for size)

### docs/SENTRY_REQUIREMENTS.md

```markdown
# Sentry Section — Requirements

*The alert arm. Turns runaway-loop findings into reliability incidents — the half of remediation that says "a stuck agent isn't a caching problem, page someone."*

Companion to `DESIGN_redis.md`. Consumes the Finding schema (§6.2) defined there.

---

## 1. Purpose

When the routing brain classifies a finding as `route == "alert"` — a runaway loop or a side-effecting redundancy — the Sentry section fires a **Sentry event rich enough to act on**: which agent, which tool, how many iterations, how many dollars burned, and that it isn't converging. This is the second remediation arm; LangCache absorbs the harmless waste, Sentry escalates the dangerous repetition.

The core owner *classifies*; this section *fires*. The UI *reflects* the fired state. Keep that split clean.

## 2. Dependencies & position

- **Upstream:** the core router hands off `route == "alert"` findings (interface in §4).
- **Downstream:** the UI shows the runaway as a fired incident (UR-12). This section must make the fired state observable to the UI.
- **External:** a Sentry project + DSN.

## 3. What it consumes

Alert-routed findings, per `DESIGN_redis.md §6.2`. The fields this section reads:
`finding_id`, `type`, `span_ids`, `representative_span_id`, `count`, `description`, `dollar_cost`, `severity` (`runaway`), `route` (`alert`), `cacheable` (`false` for side-effecting), `evidence.convergence`, plus the owning `agent_name` / `tool_name` from the representative span.

Two reasons a finding routes to alert, which produce **different** incidents:
1. **Runaway loop** — `count ≥ R_max` or `convergence == "none"`.
2. **Side-effecting redundancy** — a redundant call to a write tool the verifier refused to cache.

## 4. Interface with the core (pick one, lock it hour 0)

- **Option A (simple, default):** the core router calls an in-process `dispatch_alert(finding) -> ack`.
- **Option B (decoupled, on-theme):** the core router writes alert findings to a Redis stream/channel `alerts:{run_id}`; this section consumes them (`XREADGROUP` / pub-sub) and fires. Fits the Redis-centric design and enables live mode cleanly.

Either way, define `dispatch_alert(finding)` as the contract and agree it with the core owner before building.

## 5. Functional requirements

- **SR-1 · SDK init.** Initialize the Sentry SDK (`sentry-sdk`) from a `SENTRY_DSN` env var at startup. No DSN → fall back to mock mode (SR-9), never crash.

- **SR-2 · Consume alert findings.** Accept every `route == "alert"` finding via the §4 interface and fire exactly one incident per finding (subject to dedup, SR-6).

- **SR-3 · Rich event content.** Each event MUST carry:
  - **Message** — a plain-language incident title, e.g. *"Runaway agent loop: fact_checker retried verify_source 12× — $0.30 burned, no convergence."*
  - **Level** — `error` for runaways (`fatal` if cost or count is extreme); `warning` for side-effecting redundancy.
  - **Tags** (for filtering): `run_id`, `agent`, `tool`, `find
[truncated — 4992 more characters]
```

### docs/BAND_REQUIREMENTS.md

```markdown
# Band Section — Requirements

*The demo-trace generator. Produces the deliberately messy multi-agent run that Redundant ingests over Redis Streams and diagnoses on stage.*

Companion to `DESIGN_redis.md`. Span schema and stream convention are defined there (§6.1) and restated here as the hard contract.

---

## 1. Purpose

The Band section produces **one reproducible multi-agent agent run** whose execution trace contains, by construction, every pathology Redundant detects — so the diagnosis, the dollar attribution, and the cache/alert fork all have something real to fire on during the demo. This is the *input* to the whole pipeline; if it doesn't exhibit the pathologies cleanly, nothing downstream has anything to show.

## 2. Consumers (who depends on this)

- **Ingestion / detection** reads the spans off Redis Streams. Needs correct schema + populated tokens/model.
- **Flamegraph UI** renders the span tree. Needs a readable span count and clean nesting.
- **LangCache + verifier** needs at least one *cacheable* redundancy and (stretch) one *side-effecting* one.
- **Sentry path** needs at least one *runaway* loop.

## 3. The contract: how spans reach the system

Each span is one entry on a per-run Redis Stream. One run = one stream, keyed `trace:{run_id}`.

```
XADD trace:run-001 * data '{
  "span_id": "s_07",
  "parent_span_id": "s_03",
  "kind": "tool",                 // "agent" | "llm" | "tool"
  "name": "tool:web_search",
  "tool_name": "web_search",      // null unless kind=="tool"
  "agent_name": "researcher_a",   // owning agent — drives sub-agent grouping
  "input": "population of france 2024",
  "output": "~68 million",
  "input_hash": "a1b2c3",         // hash of NORMALIZED input
  "start_time": 1718877601200,    // epoch ms
  "end_time":   1718877602900,
  "tokens": { "input": 1800, "output": 320 },
  "model": "gpt-4o"               // null for pure tool calls
}'
```

## 4. Functional requirements

Each requirement is written so it's testable against the produced trace.

### Pathologies the run MUST contain

- **BR-1 · Redundant sub-agents (cacheable).** At least **3 distinct agents** (different `agent_name`) MUST each call the **same tool with inputs that normalize to the same `input_hash`**. This is what the repetition detector groups cross-agent and what LangCache caches.
  - *Why identical hash:* the exact-match repetition path and the cache key both key on `(tool_name, input_hash)`. If the inputs differ even slightly after normalization, they won't group. Make these calls genuinely identical.

- **BR-2 · Duplicate subgoal via differently-worded prompts (semantic).** At least **2 LLM/agent spans** MUST pursue the **same intent with different wording** — e.g. *"summarize how France's population is changing"* vs *"give an overview of French population trends."* Same meaning, different surface text → semantic-duplicate candidate.
  - *Why different wording:* this is the case `input_hash` can't catch; it exists specifically to exercis
[truncated — 5608 more characters]
```

### pyproject.toml

```
[project]
name = "redundant-demo"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
    "band-sdk>=1.0.0",
    "openai>=2.43.0",
    "pyyaml>=6.0",
]

```

### frontend/package.json

```
{
  "name": "redundant-dashboard",
  "private": true,
  "version": "0.0.1",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@vitejs/plugin-react": "^4.3.1",
    "typescript": "^5.5.3",
    "vite": "^5.4.0"
  }
}

```

### backend/pyproject.toml

```
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"

[project]
name = "redundant"
version = "0.1.0"
description = "Redundant: runtime firewall for multi-agent AI apps (Chunk 1 - Runtime + Redis Core)"
requires-python = ">=3.11"
dependencies = [
    "fastapi>=0.110",
    "uvicorn[standard]>=0.27",
    "redis>=5.0",
    "openai>=1.20",
    "pydantic>=2.6",
    "sse-starlette>=2.0",
    "python-dotenv>=1.0",
    "networkx>=3.2",
    "sentry-sdk>=2.0",
    "band-sdk>=1.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0",
    "pytest-asyncio>=0.23",
    "httpx>=0.27",
]

[tool.setuptools.packages.find]
where = ["."]
include = ["redundant*"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
markers = [
    "integration: requires live Redis / external APIs",
]

```

### frontend/src/main.tsx

```typescript
import React from "react";
import ReactDOM from "react-dom/client";
import { App } from "./App";
import { ErrorBoundary } from "./components/ErrorBoundary";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <ErrorBoundary>
      <App />
    </ErrorBoundary>
  </React.StrictMode>
);

```

### frontend/src/App.tsx

```typescript
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { getFindings, getReport, listRuns, rerun, startRun, streamRun } from "./api/client";
import { DevInspector } from "./components/DevInspector";
import { Flamegraph } from "./components/Flamegraph";
import { HeadlineBanner } from "./components/HeadlineBanner";
import { FindingsList } from "./components/FindingsList";
import { FixSuggestions } from "./components/FixSuggestions";
import { RerunBar } from "./components/RerunBar";
import { RootCausePanel } from "./components/RootCausePanel";
import { SpanTimeline } from "./components/SpanTimeline";
import { TopBar } from "./components/TopBar";
import { theme } from "./theme";
import type { FindingsResponse, RerunResponse, Run, RunReport } from "./types";

export function App() {
  const [runs, setRuns] = useState<Run[]>([]);
  const [selectedRun, setSelectedRun] = useState<string>("");
  const [mode, setMode] = useState<"batch" | "replay">("batch");
  const [diagnosed, setDiagnosed] = useState(true);
  const [reran, setReran] = useState(false);
  const [rerunData, setRerunData] = useState<RerunResponse | null>(null);
  const [data, setData] = useState<FindingsResponse | null>(null);
  const [report, setReport] = useState<RunReport | null>(null);
  const [selectedFinding, setSelectedFinding] = useState<string | null>(null);
  const [expandedSpan, setExpandedSpan] = useState<string | null>(null);
  const [scrubVal, setScrubVal] = useState<number | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [runStatus, setRunStatus] = useState<string>("idle");
  const [liveEventCount, setLiveEventCount] = useState<number>(0);
  const [loading, setLoading] = useState(false);

  // Monotonic request id for findings/report fetches. A stale response (older
  // request, newer selectedRun) will see its id mismatch the current one and
  // get dropped instead of overwriting fresh state.
  const fetchSeq = useRef(0);

  const selectedRunObj = useMemo(
    () => runs.find((r) => r.run_id === selectedRun) ?? null,
    [runs, selectedRun]
  );

  const refreshRuns = useCallback(async () => {
    const rs = await listRuns();
    setRuns(rs);
    setSelectedRun((current) => current || rs[0]?.run_id || "");
  }, []);

  const refreshRunData = useCallback(
    async (runId: string | undefined, { showLoading = false, resetView = false } = {}) => {
      const seq = ++fetchSeq.current;
      setError(null);
      if (showLoading) setLoading(true);

      getFindings(runId)
        .then((d) => {
          if (seq !== fetchSeq.current) return; // stale response, drop it
          setData(d);
          if (resetView) {
            setReran(false);
            setRerunData(null);
            setScrubVal(null);
            setExpandedSpan(null);
          }
        })
        .catch((e) => {
          if (seq !== fetchSeq.current) return;
          setError(String(e));
        })
        .finally(() => {
          if (seq === fetchSeq.current && showLoading) setLoading(false);
        });

      getReport(runId || "").then((r) => {
        if (seq !== fetchSeq.current) return;
        setReport(r);
      });
    },
    []
  );

  // Keep externally-started Band/API runs visible. Band can write Redis without
  // the dashboard initiating the run, so a one-shot mount fetch leaves the
  // selector stale.
  useEffect(() => {
    refreshRuns().catch(() => {});
    const timer = window.setInterval(() => {
      refreshRuns().catch(() => {});
    }, 2000);
    return () => window.clearInterval(timer);
  }, [refreshRuns]);

  // Load findings + report whenever the selected run changes.
  //
  // Bug history: this effect used to setData(null) synchronously, which caused
  // the body to unmount and reappear as a blank screen whenever selectedRun
  // changed (most visibly: after listRuns resolves on mount). Stale data is
  // strictly better than no data — the new payload overwrites when it arrives.
  useEffect(() => {
    refreshRunData(selectedRun || undefined, { showLoading: true, resetView: true });
  }, [refreshRunData, selectedRun]);

  // A selected running run should keep moving even if it was started outside
  // this tab. Polling covers missing/closed SSE connections and refreshes the
  // findings payload as trace:{run_id} grows.
  useEffect(() => {
    if (!selectedRun || selectedRunObj?.status !== "running") return;
    setRunStatus("running");
    const timer = window.setInterval(() => {
      refreshRunData(selectedRun, { showLoading: false, resetView: false });
    }, 1500);
    return () => window.clearInterval(timer);
  }, [refreshRunData, selectedRun, selectedRunObj?.status]);

  // Subscribe to whichever running run is selected, not only runs started by
  // this tab. Events drive the live counter and nudge a findings/report refresh.
  useEffect(() => {
    if (!selectedRun || selectedRunObj?.status !== "running") return;
    setLiveEventCount(0);
    const cleanup = streamRun(
      selectedRun,
      () => {
        setLiveEventCount((n) => n + 1);
        refreshRunData(selectedRun, { showLoading: false, resetView: false });
      },
      (completedRun) => {
        setRunStatus(completedRun.status);
        setRuns((prev) => [completedRun, ...prev.filter((r) => r.run_id !== completedRun.run_id)]);
        refreshRunData(completedRun.run_id, { showLoading: false, resetView: false });
      }
    );
    return cleanup;
  }, [refreshRunData, selectedRun, selectedRunObj?.status]);

  // Reset scrub when toggling between batch and replay so the bar shows "all"
  // by default whenever the user enters replay mode.
  useEffect(() => {
    setScrubVal(null);
  }, [mode]);

  const handleStartRun = async () => {
    try {
      setRunStatus("running");
      setLiveEventCount(0);
      const newRun = await startRun("Band multi-agent demo", "band");
      setRuns((prev) => [newRun, ...prev]);
      setSelectedRun(newRun.run_id);
      const cleanup = streamR
[truncated — 6729 more characters]
```

### agent_config.example.yaml

```yaml
# Copy this file to agent_config.yaml and fill in the values from Band.
# Do not commit agent_config.yaml; it contains live API keys.

research_agent:
  agent_id: "<research-agent-uuid>"
  api_key: "<research-agent-api-key>"

report_agent:
  agent_id: "<report-agent-uuid>"
  api_key: "<report-agent-api-key>"

audit_agent:
  agent_id: "<audit-agent-uuid>"
  api_key: "<audit-agent-api-key>"

verifier_agent:
  agent_id: "<verifier-agent-uuid>"
  api_key: "<verifier-agent-api-key>"


```

### frontend/vite.config.ts

```typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// Proxies FastAPI endpoints to the running uvicorn server so the dev tab can
// hit /api, /findings, /alerts without CORS. Backend defaults to :8000.
export default defineConfig({
  plugins: [react()],
  server: {
    port: 5173,
    proxy: {
      "/api": "http://localhost:8000",
      "/findings": "http://localhost:8000",
      "/alerts": "http://localhost:8000",
    },
  },
});

```

### frontend/index.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Redundant · the AI cost firewall</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap"
      rel="stylesheet"
    />
    <style>
      :root {
        --gt-dim: #8c95a2;
        --gt-dimmer: #6b7480;
        --gt-sec: #bac2cc;
        --gt-mut: #9aa3b0;
      }
      [data-contrast="standard"] {
        --gt-dim: #6b7480;
        --gt-dimmer: #4b525b;
        --gt-sec: #a9b2bd;
        --gt-mut: #8a94a6;
      }
      *,
      *::before,
      *::after {
        box-sizing: border-box;
      }
      html,
      body,
      #root {
        margin: 0;
        padding: 0;
        height: 100%;
        background: #0b0d10;
      }
      body {
        font-family: "Geist", system-ui, sans-serif;
        -webkit-font-smoothing: antialiased;
        color: #e6ebf0;
      }
      ::selection {
        background: rgba(74, 222, 128, 0.25);
      }
      .rdt-scroll::-webkit-scrollbar {
        width: 9px;
        height: 9px;
      }
      .rdt-scroll::-webkit-scrollbar-thumb {
        background: #2a323c;
        border-radius: 6px;
        border: 2px solid #0b0d10;
      }
      .rdt-scroll::-webkit-scrollbar-track {
        background: transparent;
      }
      @keyframes rdtPulse {
        0%,
        100% {
          opacity: 1;
        }
        50% {
          opacity: 0.4;
        }
      }
      @keyframes rdtAlertPulse {
        0%,
        100% {
          box-shadow: 0 0 0 0 rgba(248, 113, 113, 0.4);
        }
        50% {
          box-shadow: 0 0 0 4px rgba(248, 113, 113, 0);
        }
      }
      .rdt-pulse {
        animation: rdtPulse 1.3s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
      }
      .rdt-alert {
        animation: rdtAlertPulse 1.6s ease-out infinite;
      }
      @media (prefers-reduced-motion: reduce) {
        .rdt-pulse,
        .rdt-alert {
          animation: none !important;
        }
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

```

[73 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]