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
2 changes: 2 additions & 0 deletions config/quality/dependency-allowlist.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"better-sqlite3",
"bottleneck",
"c8",
"clsx",
"commander",
"concurrently",
"cross-env",
Expand Down Expand Up @@ -106,6 +107,7 @@
"socks",
"sql.js",
"sqlite-vec",
"tailwind-merge",
"tailwindcss",
"tls-client-node",
"tsup",
Expand Down
218 changes: 218 additions & 0 deletions design.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
"axios": "^1.16.1",
"bcryptjs": "^3.0.3",
"bottleneck": "^2.19.5",
"clsx": "^2.1.1",
"commander": "^15.0.0",
"csv-stringify": "^6.7.0",
"express": "^5.2.1",
Expand Down Expand Up @@ -247,6 +248,7 @@
"socks": "^2.8.7",
"sql.js": "^1.14.1",
"sqlite-vec": "^0.1.9",
"tailwind-merge": "^3.6.0",
"tsx": "^4.22.3",
"undici": "^8.3.0",
"update-notifier": "^7.3.1",
Expand Down
59 changes: 59 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,29 @@
--shadow-soft: 0 1px 3px rgba(0, 0, 0, 0.02), 0 4px 12px rgba(0, 0, 0, 0.015);
--shadow-warm: 0 2px 12px -2px rgba(229, 77, 94, 0.12);
--shadow-elevated: 0 12px 28px -4px rgba(20, 20, 40, 0.06);

/* Graph-paper wallpaper grid — shared visual identity with the marketing site
(_mono_repo/omnirouteSite/css). Light theme values. Rendered by body::before. */
--grid-line: rgba(0, 0, 0, 0.045);
--grid-size: 46px;
--section-alt: rgba(0, 0, 0, 0.022);

/* Identity tokens mirrored from the site. Definitions only in this phase —
components are repointed to them in a later phase. */
--surface-2: #f5f5fa;
--radius: 14px;
--radius-control: 9px;
--grad-brand: linear-gradient(135deg, var(--color-primary), var(--color-accent-light));

/* Data-table surfaces — theme-aware. The DARK values (in .dark below) exactly mirror
the previous hardcoded rgba in DataTable.tsx so dark stays byte-identical; these
light values are the fix (the old code was always-dark via dead var fallbacks). */
--table-header-bg: rgba(249, 249, 251, 0.95);
--table-row-zebra: rgba(0, 0, 0, 0.02);
--table-row-hover: rgba(0, 0, 0, 0.04);
--table-cell-border: rgba(0, 0, 0, 0.04);
/* Selected row — an accent tint that reads on both themes (inherited by .dark). */
--table-row-selected: rgba(99, 102, 241, 0.1);
}

.dark {
Expand Down Expand Up @@ -125,6 +148,17 @@
--shadow-soft: 0 1px 3px rgba(0, 0, 0, 0.15), 0 4px 12px rgba(0, 0, 0, 0.1);
--shadow-warm: 0 2px 12px -2px rgba(229, 77, 94, 0.15);
--shadow-elevated: 0 12px 28px -4px rgba(0, 0, 0, 0.3);

/* Graph-paper wallpaper grid — dark theme values. */
--grid-line: rgba(255, 255, 255, 0.035);
--section-alt: rgba(255, 255, 255, 0.018);
--surface-2: #1c2230;

/* Data-table surfaces — dark = the exact old hardcoded values (byte-identical). */
--table-header-bg: rgba(15, 15, 25, 0.95);
--table-row-zebra: rgba(255, 255, 255, 0.02);
--table-row-hover: rgba(255, 255, 255, 0.04);
--table-cell-border: rgba(255, 255, 255, 0.04);
}

@theme inline {
Expand Down Expand Up @@ -176,6 +210,16 @@
/* Font - macOS system fonts */
--font-sans:
-apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", system-ui, sans-serif;
/* Monospace stack (parity with the site) — code blocks, IDs, endpoints, terminals */
--font-mono: ui-monospace, "JetBrains Mono", "Fira Code", "SF Mono", monospace;

/* Nested surface (enables bg-surface-2) */
--color-surface-2: var(--surface-2);

/* Semantic radius scale → rounded-card (surfaces, 14px) / rounded-control (controls,
9px). Custom names so the default rounded-sm/md/lg/xl utilities stay untouched. */
--radius-card: var(--radius);
--radius-control: var(--radius-control);
}

/* ── Focus Indicators (U-3) ── */
Expand Down Expand Up @@ -211,6 +255,21 @@ body {
-moz-osx-font-smoothing: grayscale;
}

/* Graph-paper wallpaper grid — one fixed, full-viewport layer behind every screen
(dashboard, auth, error pages). A z-index:-1 ::before paints above body's own
background but below all in-flow content, so it shows through any transparent
wrapper without lowering text contrast. Mirrors the marketing site exactly. */
body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background-image: linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
background-size: var(--grid-size) var(--grid-size);
}

body.electron-macos {
--desktop-safe-top: 30px;
--desktop-safe-bottom: 8px;
Expand Down
9 changes: 5 additions & 4 deletions src/shared/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import { cn } from "@/shared/utils/cn";

const variants = {
primary: "bg-gradient-to-b from-primary to-primary-hover text-white shadow-sm",
primary: "bg-[image:var(--grad-brand)] text-white shadow-sm hover:brightness-105",
accent: "bg-accent text-white shadow-sm hover:bg-accent-hover",
secondary:
"bg-white dark:bg-white/10 border border-black/10 dark:border-white/10 text-text-main hover:bg-black/5 dark:hover:bg-white/5",
outline: "border border-black/15 dark:border-white/15 text-text-main hover:bg-black/5",
Expand All @@ -12,9 +13,9 @@ const variants = {
};

const sizes = {
sm: "h-7 px-3 text-xs rounded-md",
md: "h-9 px-4 text-sm rounded-lg",
lg: "h-11 px-6 text-sm rounded-lg",
sm: "h-7 px-3 text-xs rounded-control",
md: "h-9 px-4 text-sm rounded-control",
lg: "h-11 px-6 text-sm rounded-control",
};

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
Expand Down
8 changes: 4 additions & 4 deletions src/shared/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export default function Card({
<div
className={cn(
"bg-surface",
"border border-black/5 dark:border-white/5",
"rounded-lg shadow-sm",
"border border-border",
"rounded-card shadow-sm",
hover && "hover:shadow-md hover:border-primary/30 transition-all cursor-pointer",
paddings[padding],
className
Expand Down Expand Up @@ -76,7 +76,7 @@ Card.Section = function CardSection({ children, className, ...props }: CardSecti
className={cn(
"p-4 rounded-lg",
"bg-black/[0.02] dark:bg-white/[0.02]",
"border border-black/5 dark:border-white/5",
"border border-border",
className
)}
{...props}
Expand All @@ -96,7 +96,7 @@ Card.Row = function CardRow({ children, className, ...props }: CardRowProps) {
<div
className={cn(
"p-3 -mx-3 px-3 transition-colors",
"border-b border-black/5 dark:border-white/5 last:border-b-0",
"border-b border-border last:border-b-0",
"hover:bg-black/[0.02] dark:hover:bg-white/[0.02]",
className
)}
Expand Down
38 changes: 38 additions & 0 deletions src/shared/components/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";

import { cn } from "@/shared/utils/cn";

interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: React.ReactNode;
}

/**
* Checkbox — token-driven native checkbox (brand accent + keyboard focus ring).
* Replaces the ad-hoc `<input type="checkbox" style={{ accentColor: "#6366f1" }}>`
* pattern scattered across the dashboard. Optional `label` wraps it in a clickable row.
*/
export default function Checkbox({ label, className, id, ...props }: CheckboxProps) {
const box = (
<input
type="checkbox"
id={id}
className={cn(
"h-4 w-4 shrink-0 cursor-pointer rounded-[4px] accent-[var(--color-accent)]",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
"disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
/>
);
if (!label) return box;
return (
<label
htmlFor={id}
className="inline-flex items-center gap-2 cursor-pointer text-sm text-text-main"
>
{box}
<span>{label}</span>
</label>
);
}
20 changes: 10 additions & 10 deletions src/shared/components/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function DataTable({
alignItems: "center",
justifyContent: "center",
padding: "48px 24px",
color: "var(--text-secondary, #888)",
color: "var(--color-text-muted)",
fontSize: "14px",
}}
>
Expand All @@ -89,7 +89,7 @@ export default function DataTable({
alignItems: "center",
justifyContent: "center",
padding: "48px 24px",
color: "var(--text-secondary, #888)",
color: "var(--color-text-muted)",
fontSize: "14px",
}}
>
Expand Down Expand Up @@ -118,11 +118,11 @@ export default function DataTable({
padding: "8px 10px",
textAlign: "left",
fontWeight: 600,
color: "var(--text-secondary, #888)",
borderBottom: "1px solid rgba(255,255,255,0.08)",
color: "var(--color-text-muted)",
borderBottom: "1px solid var(--color-border)",
position: "sticky",
top: 0,
background: "var(--bg-table-header, rgba(15,15,25,0.95))",
background: "var(--table-header-bg)",
zIndex: 1,
whiteSpace: "nowrap",
fontSize: "11px",
Expand All @@ -144,21 +144,21 @@ export default function DataTable({
cursor: onRowClick ? "pointer" : "default",
background:
row.id === selectedId
? "rgba(99,102,241,0.1)"
? "var(--table-row-selected)"
: idx % 2 === 0
? "transparent"
: "rgba(255,255,255,0.02)",
: "var(--table-row-zebra)",
transition: "background 0.15s",
}}
onMouseEnter={(e) => {
if (row.id !== selectedId) {
e.currentTarget.style.background = "rgba(255,255,255,0.04)";
e.currentTarget.style.background = "var(--table-row-hover)";
}
}}
onMouseLeave={(e) => {
if (row.id !== selectedId) {
e.currentTarget.style.background =
idx % 2 === 0 ? "transparent" : "rgba(255,255,255,0.02)";
idx % 2 === 0 ? "transparent" : "var(--table-row-zebra)";
}
}}
>
Expand All @@ -167,7 +167,7 @@ export default function DataTable({
key={col.key}
style={{
padding: "6px 10px",
borderBottom: "1px solid rgba(255,255,255,0.04)",
borderBottom: "1px solid var(--table-cell-border)",
whiteSpace: "nowrap",
maxWidth: col.maxWidth || "200px",
overflow: "hidden",
Expand Down
2 changes: 1 addition & 1 deletion src/shared/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default function Input({
}}
className={cn(
"w-full py-2 px-3 text-sm text-text-main",
"bg-white dark:bg-white/5 border border-black/10 dark:border-white/10 rounded-md",
"bg-white dark:bg-white/5 border border-black/10 dark:border-white/10 rounded-control",
"placeholder-text-muted/60",
"focus:ring-1 focus:ring-primary/30 focus:border-primary/50 focus:outline-none",
"transition-all shadow-inner disabled:opacity-50 disabled:cursor-not-allowed",
Expand Down
2 changes: 1 addition & 1 deletion src/shared/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default function Modal({
className={cn(
"relative w-full bg-surface",
"border border-black/10 dark:border-white/10",
"rounded-xl shadow-2xl",
"rounded-card shadow-2xl",
"animate-in fade-in zoom-in-95 duration-200",
sizes[size],
className
Expand Down
2 changes: 1 addition & 1 deletion src/shared/components/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function Select({
aria-describedby={describedBy}
className={cn(
"w-full py-2 px-3 pe-10 text-sm text-text-main",
"bg-surface border border-black/10 dark:border-white/10 rounded-md appearance-none",
"bg-surface border border-black/10 dark:border-white/10 rounded-control appearance-none",
"focus:ring-1 focus:ring-primary/30 focus:border-primary/50 focus:outline-none",
"transition-all disabled:opacity-50 disabled:cursor-not-allowed",
"text-[16px] sm:text-sm",
Expand Down
29 changes: 29 additions & 0 deletions src/shared/components/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";

import { cn } from "@/shared/utils/cn";

interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
error?: boolean;
}

/**
* Textarea — token-driven multiline input mirroring the Input primitive (same border,
* focus ring and control radius). Replaces ad-hoc raw `<textarea>` styling at call sites.
*/
export default function Textarea({ className, error = false, ...props }: TextareaProps) {
return (
<textarea
className={cn(
"w-full py-2 px-3 text-sm text-text-main",
"bg-white dark:bg-white/5 border border-black/10 dark:border-white/10 rounded-control",
"placeholder-text-muted/60",
"focus:ring-1 focus:ring-primary/30 focus:border-primary/50 focus:outline-none",
"transition-all disabled:opacity-50 disabled:cursor-not-allowed",
"text-[16px] sm:text-sm",
error ? "border-red-500 focus:border-red-500 focus:ring-red-500/20" : "",
className
)}
{...props}
/>
);
}
9 changes: 5 additions & 4 deletions src/shared/components/TokenHealthBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import { useTranslations } from "next-intl";
*/

import { useState, useEffect } from "react";
import { STATUS_HEX } from "@/shared/constants/statusColors";

const STATUS_MAP = {
healthy: { icon: "check_circle", color: "#22c55e", tooltip: "All tokens healthy" },
warning: { icon: "warning", color: "#f59e0b", tooltip: "Some tokens need attention" },
error: { icon: "error", color: "#ef4444", tooltip: "Token refresh failures detected" },
unknown: { icon: "help", color: "#6b7280", tooltip: "Health status unknown" },
healthy: { icon: "check_circle", color: STATUS_HEX.success, tooltip: "All tokens healthy" },
warning: { icon: "warning", color: STATUS_HEX.warning, tooltip: "Some tokens need attention" },
error: { icon: "error", color: STATUS_HEX.error, tooltip: "Token refresh failures detected" },
unknown: { icon: "help", color: STATUS_HEX.muted, tooltip: "Health status unknown" },
};

export default function TokenHealthBadge() {
Expand Down
8 changes: 5 additions & 3 deletions src/shared/components/flow/edgeStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
* the Compression Studio (Tela A) so all three flow graphs speak the same
* color language: green = active, red = error, amber = last-used, muted = idle.
*/
import { STATUS_HEX } from "@/shared/constants/statusColors";

export const FLOW_EDGE_COLORS = {
active: "#22c55e",
error: "#ef4444",
last: "#f59e0b",
active: STATUS_HEX.success,
error: STATUS_HEX.error,
last: STATUS_HEX.warning,
idle: "var(--color-border)",
} as const;

Expand Down
2 changes: 2 additions & 0 deletions src/shared/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
export { default as Button } from "./Button";
export { default as Input } from "./Input";
export { default as Select } from "./Select";
export { default as Checkbox } from "./Checkbox";
export { default as Textarea } from "./Textarea";
export { default as Card } from "./Card";
export { default as Collapsible } from "./Collapsible";
export { default as Modal, ConfirmModal } from "./Modal";
Expand Down
Loading
Loading