Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions codegraph/web/static/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -661,4 +661,133 @@ html.theme-light .pyvis-warn { display: flex !important; }

.bg-app-1 { background: var(--bg-1); }
.bg-app-2 { background: var(--bg-2); }

/* =========================================================
Tailwind-compat utilities
Replaces the Tailwind CDN runtime. Covers only the utility
classes actually used in index.html (grepped exhaustively).
Custom design-token classes (ink-*, brand-*, shadow-*) are
mapped to CSS variables already defined above.
========================================================= */

/* --- Layout --- */
.flex { display: flex; }
.inline-flex { display: inline-flex; }
.flex-col { flex-direction: column; }
.flex-1 { flex: 1 1 0%; }
.flex-none { flex: none; }
.shrink-0 { flex-shrink: 0; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.relative { position: relative; }
.fixed { position: fixed; }
.sticky { position: sticky; }
.inset-0 { inset: 0; }
.top-0 { top: 0; }
.bottom-4 { bottom: 1rem; }
.right-4 { right: 1rem; }
.z-10 { z-index: 10; }
.z-50 { z-index: 50; }
.min-h-screen { min-height: 100vh; }
.h-screen { height: 100vh; }
.h-full { height: 100%; }
.w-full { width: 100%; }
.w-60 { width: 15rem; }
.w-9 { width: 2.25rem; }
.h-9 { height: 2.25rem; }
.w-3\.5 { width: 0.875rem; }
.h-3\.5 { height: 0.875rem; }
.min-w-0 { min-width: 0; }
.overflow-y-auto { overflow-y: auto; }
.overflow-hidden { overflow: hidden; }
.pointer-events-none { pointer-events: none; }

/* --- Gap & space --- */
.gap-2 { gap: 0.5rem; }
.gap-2\.5 { gap: 0.625rem; }
.gap-3 { gap: 0.75rem; }
.gap-4 { gap: 1rem; }
.space-y-0\.5 > * + * { margin-top: 0.125rem; }
.space-y-2 > * + * { margin-top: 0.5rem; }

/* --- Padding & margin --- */
.p-3 { padding: 0.75rem; }
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
.py-5 { padding-top: 1.25rem; padding-bottom: 1.25rem; }
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
.py-4 { padding-top: 1rem; padding-bottom: 1rem; }
.max-w-sm { max-width: 24rem; }
.mt-0\.5 { margin-top: 0.125rem; }
.ml-1 { margin-left: 0.25rem; }
.ml-auto { margin-left: auto; }

/* --- Borders --- */
.border { border-width: 1px; border-style: solid; }
.border-r { border-right-width: 1px; border-right-style: solid; }
.border-b { border-bottom-width: 1px; border-bottom-style: solid; }
.border-t { border-top-width: 1px; border-top-style: solid; }
.rounded-lg { border-radius: 0.5rem; }
.rounded-md { border-radius: 0.375rem; }

/* --- Opacity & transition --- */
.opacity-0 { opacity: 0; }
.transition { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; transition-timing-function: cubic-bezier(0.4,0,0.2,1); transition-duration: 150ms; }
.transition-opacity { transition-property: opacity; transition-timing-function: cubic-bezier(0.4,0,0.2,1); transition-duration: 150ms; }
.transition-\[width\] { transition-property: width; transition-timing-function: cubic-bezier(0.4,0,0.2,1); }
.duration-200 { transition-duration: 200ms; }

/* --- Backdrop --- */
.backdrop-blur { backdrop-filter: blur(8px); }

/* --- Typography --- */
.antialiased { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.font-sans { font-family: 'Inter var', 'Inter', system-ui, sans-serif; }
.font-mono { font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-sm { font-size: 0.875rem; line-height: 1.25rem; }
.text-xs { font-size: 0.75rem; line-height: 1rem; }
.text-lg { font-size: 1.125rem; line-height: 1.75rem; }
.text-base { font-size: 1rem; line-height: 1.5rem; }
.text-\[10px\] { font-size: 10px; }
.text-\[11px\] { font-size: 11px; }
.text-\[12\.5px\] { font-size: 12.5px; }
.tracking-tight { letter-spacing: -0.025em; }
.tracking-\[0\.14em\] { letter-spacing: 0.14em; }
.uppercase { text-transform: uppercase; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-center { text-align: center; }

/* --- Color tokens mapped to CSS vars --- */
.text-ink-50 { color: #e6ecf5; }
.text-ink-200 { color: #8b9ab8; }
.text-ink-300 { color: #5b6b8c; }
.text-ink-950 { color: #05070d; }
.bg-ink-700\/80 { background-color: rgba(22,31,51,0.80); }
.bg-ink-700\/95 { background-color: rgba(22,31,51,0.95); }
.bg-ink-900\/70 { background-color: rgba(10,15,28,0.70); }
.border-ink-500\/60 { border-color: rgba(42,57,87,0.60); }
.border-ink-500\/80 { border-color: rgba(42,57,87,0.80); }
.border-ink-600\/60 { border-color: rgba(29,41,66,0.60); }
.hover\:bg-ink-600:hover { background-color: #1d2942; }
.hover\:border-brand-500:hover { border-color: #818cf8; }

/* --- Gradient (for the logo badge) --- */
.bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-gradient-from, transparent), var(--tw-gradient-via, transparent), var(--tw-gradient-to, transparent)); }
.from-brand-500 { --tw-gradient-from: #818cf8; }
.via-brand-600 { --tw-gradient-via: #6366f1; }
.to-accent-cyan { --tw-gradient-to: #22d3ee; }

/* --- Custom shadows (from tailwind.config in index.html) --- */
.shadow-card { box-shadow: 0 1px 0 0 rgba(255,255,255,0.04) inset, 0 12px 32px -16px rgba(0,0,0,0.65); }
.shadow-glow { box-shadow: 0 0 0 1px rgba(129,140,248,0.4), 0 0 32px -8px rgba(129,140,248,0.45); }

/* --- Responsive: md breakpoint (768px+) --- */
@media (min-width: 768px) {
.md\:px-8 { padding-left: 2rem; padding-right: 2rem; }
}
.bg-app-3 { background: var(--bg-3); }
64 changes: 22 additions & 42 deletions codegraph/web/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,15 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>codegraph</title>
<link rel="preconnect" href="https://rsms.me/">
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter var', 'Inter', 'system-ui', 'sans-serif'],
mono: ['"JetBrains Mono"', 'ui-monospace', 'SFMono-Regular', 'Menlo', 'monospace'],
},
colors: {
ink: { 950:'#05070d', 900:'#0a0f1c', 800:'#0f1626', 700:'#161f33',
600:'#1d2942', 500:'#2a3957', 400:'#3b4a6a', 300:'#5b6b8c',
200:'#8b9ab8', 100:'#c4cfe2', 50:'#e6ecf5' },
brand: { 700:'#4f46e5', 600:'#6366f1', 500:'#818cf8', 400:'#a5b4fc', 300:'#c7d2fe' },
accent: { cyan:'#22d3ee', emerald:'#34d399', amber:'#fbbf24',
rose:'#f87171', violet:'#a78bfa', orange:'#fb923c' },
},
boxShadow: {
'card': '0 1px 0 0 rgba(255,255,255,0.04) inset, 0 12px 32px -16px rgba(0,0,0,0.65)',
'glow': '0 0 0 1px rgba(129,140,248,0.4), 0 0 32px -8px rgba(129,140,248,0.45)',
},
}
}
};
</script>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-sankey@0.12.3/dist/d3-sankey.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mermaid@10.9.1/dist/mermaid.min.js"></script>
<script src="https://unpkg.com/lucide@0.414.0"></script>
<!-- Fonts: vendored locally — no network required -->
<link rel="stylesheet" href="/static/vendor/fonts.css">
<!-- JS libraries: vendored locally — no CDN required -->
<script src="/static/vendor/d3.v7.min.js"></script>
<script src="/static/vendor/d3-sankey@0.12.3.min.js"></script>
<script src="/static/vendor/mermaid@10.9.1.min.js"
onerror="console.error('[codegraph] mermaid vendor file missing at /static/vendor/mermaid@10.9.1.min.js')"></script>
<script src="/static/vendor/lucide@0.414.0.min.js"
onerror="console.error('[codegraph] lucide vendor file missing at /static/vendor/lucide@0.414.0.min.js')"></script>
<link rel="stylesheet" href="/static/app.css">
<link rel="stylesheet" href="/static/views/graph3d.css">
</head>
Expand Down Expand Up @@ -94,17 +69,22 @@ <h1 class="text-lg font-semibold mt-0.5 tracking-tight truncate" id="page-title"
<script src="/static/views/graph3d_transform.js"></script>
<script src="/static/views/graph3d.js"></script>
<script src="/static/views/architecture.js"></script>
<!-- three-spritetext (ESM via esm.sh): pulls its own three bundle and exposes
a SpriteText class. Used by graph3d.js for always-visible node + edge
labels. Silently no-op if esm.sh is unreachable; HTML hover labels remain. -->
<!-- three-spritetext (vendored ESM stub): see /static/vendor/README.md for
why this resolves to undefined. window.SpriteText stays unset; graph3d.js
falls back to HTML hover labels — the 3D graph works fully offline. -->
<script type="module">
try {
const mod = await import('https://esm.sh/three-spritetext@1.10.0');
window.SpriteText = mod.default || mod.SpriteText || mod;
window.dispatchEvent(new Event('cg-spritetext-ready'));
const mod = await import('/static/vendor/three-spritetext@1.10.0.mjs');
const SpriteText = mod.default || mod.SpriteText;
if (typeof SpriteText === 'function') {
window.SpriteText = SpriteText;
window.dispatchEvent(new Event('cg-spritetext-ready'));
}
// If stub returns undefined, window.SpriteText stays unset and graph3d.js
// falls back gracefully to HTML hover labels.
} catch (e) {
// esm.sh blocked or offline — leave window.SpriteText undefined and
// let graph3d.js fall back to HTML hover labels.
// Vendor file missing — leave window.SpriteText undefined.
console.warn('[codegraph] three-spritetext vendor file unavailable:', e.message);
}
</script>
<script src="/static/app.js"></script>
Expand Down
5 changes: 5 additions & 0 deletions codegraph/web/static/vendor/3d-force-graph@1.min.js

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions codegraph/web/static/vendor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Vendored Frontend Dependencies

All files in this directory are vendored copies of third-party libraries.
The dashboard serves them locally so it works fully offline.

## Manifest

| File | Library | Version | Source URL | Size |
|------|---------|---------|-----------|------|
| `d3.v7.min.js` | D3.js | 7.9.0 | https://d3js.org/d3.v7.min.js | 273 KB |
| `d3-sankey@0.12.3.min.js` | d3-sankey | 0.12.3 | https://cdn.jsdelivr.net/npm/d3-sankey@0.12.3/dist/d3-sankey.min.js | 6 KB |
| `mermaid@10.9.1.min.js` | Mermaid | 10.9.1 | https://cdn.jsdelivr.net/npm/mermaid@10.9.1/dist/mermaid.min.js | 3.2 MB |
| `lucide@0.414.0.min.js` | Lucide Icons | 0.414.0 | https://unpkg.com/lucide@0.414.0 | 336 KB |
| `3d-force-graph@1.min.js` | 3d-force-graph | 1.80.0 | https://unpkg.com/3d-force-graph@1/dist/3d-force-graph.min.js | 1.3 MB |
| `three-spritetext@1.10.0.mjs` | three-spritetext | 1.10.0 | https://esm.sh/three-spritetext@1.10.0 | stub (see below) |
| `fonts.css` | Font declarations | — | local | 1 KB |
| `fonts/InterVariable.woff2` | Inter (variable) | 4.1 | https://rsms.me/inter/font-files/InterVariable.woff2 | 344 KB |
| `fonts/JetBrainsMono-400-latin.woff2` | JetBrains Mono | v24 | https://fonts.gstatic.com (latin subset, wt 400–500) | 31 KB |

**Total vendored size**: ~5.3 MB

## Notes

### three-spritetext stub
`three-spritetext@1.10.0.mjs` is a no-op stub. `three-spritetext` requires the
same `THREE.js` instance used by `3d-force-graph`. The `3d-force-graph@1` UMD bundle
embeds THREE internally and does not expose `window.THREE`, making it impossible to
share a compatible THREE instance without also vendoring a full three.js UMD (~600 KB,
version r128 or older). This would push total vendored size over the 6 MB budget and
introduce version-skew fragility.

The calling code in `index.html` already wraps the import in `try/catch` and falls
back to HTML hover-labels when `window.SpriteText` is absent. The 3D graph works
fully in offline mode; only the always-visible 3D text labels on nodes/edges are
absent. HTML hover-labels remain fully functional.

### Tailwind CSS
The Tailwind CDN runtime is NOT vendored (would add ~300 KB and requires a JS
runtime to generate CSS). Instead, `app.css` has been extended with a lightweight
utility layer (`/* --- Tailwind-compat utilities --- */`) that covers the small set
of utility classes used in `index.html`. Custom design tokens (`ink-*`, `brand-*`,
`accent-*`, `shadow-card`, `shadow-glow`) are expressed as CSS variables already
defined in `app.css`.

## Re-vendoring (update instructions)

To update a library, download its latest minified bundle to this directory using
the source URL above and update the version in this manifest. For `mermaid`, use the
`dist/mermaid.min.js` file from jsdelivr (not `mermaid.esm.min.mjs`).
2 changes: 2 additions & 0 deletions codegraph/web/static/vendor/d3-sankey@0.12.3.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions codegraph/web/static/vendor/d3.v7.min.js

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions codegraph/web/static/vendor/fonts.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* Vendored font definitions — served from /static/vendor/fonts/ */

/* Inter variable font (InterVariable) */
@font-face {
font-family: 'InterVariable';
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url('/static/vendor/fonts/InterVariable.woff2') format('woff2');
}
/* Legacy name "Inter var" */
@font-face {
font-family: 'Inter var';
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url('/static/vendor/fonts/InterVariable.woff2') format('woff2');
}
/* "Inter" alias for browsers that don't support variable fonts */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url('/static/vendor/fonts/InterVariable.woff2') format('woff2');
}

/* JetBrains Mono (latin, wt 400–500) */
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400 500;
font-display: swap;
src: url('/static/vendor/fonts/JetBrainsMono-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
Binary file not shown.
Binary file not shown.
12 changes: 12 additions & 0 deletions codegraph/web/static/vendor/lucide@0.414.0.min.js

Large diffs are not rendered by default.

Loading
Loading