Second phase of the DESIGN.md migration. Rewrites the two color
dictionaries that back most status/priority/role indicators across the
app, and adds the controlled "chart palette" exception for agent role
colors per user decision in MIGRATION-PLAN section 9.
status-colors.ts (full rewrite, 109 -> 122 lines)
- All 5 dictionaries (statusBadge, statusDot, priorityColor,
issueStatusIcon, agentStatusDot) + 5 defaults rewritten to use
semantic token classes:
* done/completed/approved -> bg-success/15 text-success border-success/30
* error/failed/terminated/rejected -> bg-destructive/15 text-destructive border-destructive/30
* pending/paused/in_review -> bg-warning/15 text-warning border-warning/30
* running/in_progress -> bg-primary/15 text-primary border-primary/30
* idle/planned/backlog/todo -> bg-muted text-muted-foreground border-border
* blocked -> bg-destructive/10 text-destructive border-destructive/25 (softer)
* cancelled/archived -> bg-muted/40 text-muted-foreground/70 border-border
* priority urgent/high/medium/low -> destructive/warning/primary/muted
- Zero raw palette utilities remain (rg verified).
- All export identifiers and signatures preserved; 11 caller files
across ui/src compile unchanged.
- Note: timed_out was not explicitly mapped in the spec but exists
in the source; agent chose warning (semantically closer than error).
agent-role-colors.ts (full rewrite, 17 -> 68 lines)
- Controlled "chart palette" exception: 5 muted desaturated hues,
passed WCAG AA for all 10 combinations (dark + light), 7/10
also pass AAA.
- 11 AgentRole entries cycle through 5 slots via mod-5:
* slot 1 (volt #faff69 dark / olive #4f5100 light): general, pm
* slot 2 (teal #6ee7b7 / #0f766e): devops, cto
* slot 3 (lavender #c4b5fd / violet #6d28d9): designer, cmo
* slot 4 (amber #fcd34d / #b45309): ceo, cfo, researcher
* slot 5 (silver #a0a0a0 / gray #6b6b6b): engineer, qa
- Hue collisions past slot 5 are intentional and documented inline;
secondary differentiation relies on icons/labels.
index.css
- Added 5 --chart-role-* vars to :root and .dark (light + dark modes).
- Mirrored as --color-chart-role-N in @theme inline so
text-chart-role-1..5 become valid Tailwind utilities.
- Minimal surgical additions — nothing else touched.
Verification
- npx tsc --noEmit in ui/: zero errors in modified files. Pre-existing
errors in unrelated files (AgentConfigForm, command.tsx, etc.)
remain unchanged.
- rg '(bg|text|border|ring)-(red|blue|green|amber|yellow|cyan|violet|pink|slate|zinc|neutral|sky|teal|emerald|indigo|rose|orange)-\d'
on modified files: zero matches.
Test follow-up (out of scope, flagged for next PR)
- ui/src/lib/agent-role-colors.test.ts asserts each role has a
"dark:" prefix (no longer true — CSS vars handle dark variants)
and that all roles have unique colors (no longer true — 11 roles,
5 slots). Both assertions need rewriting.
Phase 3 follow-ups
- Sweep agent should verify no component layers raw palette
utilities on top of dictionary output.
- Consumers that previously wrapped statusBadge output in their own
border-* class may now double-border — worth a visual audit.
- agentStatusDot's animate-pulse modifier is gone except on
"running" — if any caller expected animation on "active",
inline handling needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
951 lines
23 KiB
CSS
951 lines
23 KiB
CSS
@import "tailwindcss";
|
||
@plugin "@tailwindcss/typography";
|
||
|
||
@custom-variant dark (&:is(.dark *));
|
||
|
||
/* -- Fonts ------------------------------------------------------------- */
|
||
|
||
@font-face {
|
||
font-family: "Inter";
|
||
src: url("/fonts/InterVariable.woff2") format("woff2");
|
||
font-weight: 100 900;
|
||
font-style: normal;
|
||
font-display: swap;
|
||
}
|
||
|
||
@font-face {
|
||
font-family: "Inter";
|
||
src: url("/fonts/InterVariable-Italic.woff2") format("woff2");
|
||
font-weight: 100 900;
|
||
font-style: italic;
|
||
font-display: swap;
|
||
}
|
||
|
||
@theme inline {
|
||
--color-background: var(--background);
|
||
--color-foreground: var(--foreground);
|
||
--color-card: var(--card);
|
||
--color-card-foreground: var(--card-foreground);
|
||
--color-popover: var(--popover);
|
||
--color-popover-foreground: var(--popover-foreground);
|
||
--color-primary: var(--primary);
|
||
--color-primary-foreground: var(--primary-foreground);
|
||
--color-secondary: var(--secondary);
|
||
--color-secondary-foreground: var(--secondary-foreground);
|
||
--color-muted: var(--muted);
|
||
--color-muted-foreground: var(--muted-foreground);
|
||
--color-accent: var(--accent);
|
||
--color-accent-foreground: var(--accent-foreground);
|
||
--color-destructive: var(--destructive);
|
||
--color-destructive-foreground: var(--destructive-foreground);
|
||
--color-warning: var(--warning);
|
||
--color-warning-foreground: var(--warning-foreground);
|
||
--color-success: var(--success);
|
||
--color-success-foreground: var(--success-foreground);
|
||
--color-border: var(--border);
|
||
--color-input: var(--input);
|
||
--color-ring: var(--ring);
|
||
--color-chart-1: var(--chart-1);
|
||
--color-chart-2: var(--chart-2);
|
||
--color-chart-3: var(--chart-3);
|
||
--color-chart-4: var(--chart-4);
|
||
--color-chart-5: var(--chart-5);
|
||
--color-sidebar: var(--sidebar);
|
||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||
--color-sidebar-primary: var(--sidebar-primary);
|
||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||
--color-sidebar-accent: var(--sidebar-accent);
|
||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||
--color-sidebar-border: var(--sidebar-border);
|
||
--color-sidebar-ring: var(--sidebar-ring);
|
||
--color-volt: var(--volt);
|
||
--color-volt-pale: var(--volt-pale);
|
||
--color-volt-border: var(--volt-border);
|
||
--color-forest: var(--forest);
|
||
--color-forest-dark: var(--forest-dark);
|
||
--color-near-black: var(--near-black);
|
||
--color-hover-gray: var(--hover-gray);
|
||
--color-silver: var(--silver);
|
||
/* [nexus] chart palette exception — see MIGRATION-PLAN.md §6 and agent-role-colors.ts */
|
||
--color-chart-role-1: var(--chart-role-1);
|
||
--color-chart-role-2: var(--chart-role-2);
|
||
--color-chart-role-3: var(--chart-role-3);
|
||
--color-chart-role-4: var(--chart-role-4);
|
||
--color-chart-role-5: var(--chart-role-5);
|
||
--radius-sm: 4px;
|
||
--radius-md: 4px;
|
||
--radius-lg: 8px;
|
||
--radius-xl: 8px;
|
||
--radius-full: 9999px;
|
||
--font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
|
||
--font-mono: ui-monospace, "SFMono-Regular", Menlo, monospace;
|
||
--font-display: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
|
||
}
|
||
|
||
/* -- Light mode (default :root) ---------------------------------------- */
|
||
|
||
:root {
|
||
color-scheme: light;
|
||
--radius: 8px;
|
||
--background: #fafafa;
|
||
--foreground: #0a0a0a;
|
||
--card: #ffffff;
|
||
--card-foreground: #0a0a0a;
|
||
--popover: #ffffff;
|
||
--popover-foreground: #0a0a0a;
|
||
--primary: #166534;
|
||
--primary-foreground: #ffffff;
|
||
--secondary: #f1f5f1;
|
||
--secondary-foreground: #0a0a0a;
|
||
--muted: #f4f4f5;
|
||
--muted-foreground: #6b6b6b;
|
||
--accent: #fafff0;
|
||
--accent-foreground: #4f5100;
|
||
--destructive: #dc2626;
|
||
--destructive-foreground: #ffffff;
|
||
--warning: #b45309;
|
||
--warning-foreground: #ffffff;
|
||
--success: #166534;
|
||
--success-foreground: #ffffff;
|
||
--border: rgba(20, 20, 20, 0.12);
|
||
--input: #ffffff;
|
||
--ring: #166534;
|
||
--chart-1: #166534;
|
||
--chart-2: #4f5100;
|
||
--chart-3: #6b6b6b;
|
||
--chart-4: #8a8c00;
|
||
--chart-5: #dc2626;
|
||
--sidebar: #ffffff;
|
||
--sidebar-foreground: #6b6b6b;
|
||
--sidebar-primary: #166534;
|
||
--sidebar-primary-foreground: #ffffff;
|
||
--sidebar-accent: #f4f4f5;
|
||
--sidebar-accent-foreground: #0a0a0a;
|
||
--sidebar-border: rgba(20, 20, 20, 0.12);
|
||
--sidebar-ring: #166534;
|
||
/* Brand direct refs */
|
||
--volt: #4f5100;
|
||
--volt-pale: #8a8c00;
|
||
--volt-border: #4f5100;
|
||
--forest: #166534;
|
||
--forest-dark: #14572f;
|
||
--near-black: #0a0a0a;
|
||
--hover-gray: #e4e4e7;
|
||
--silver: #6b6b6b;
|
||
--charcoal-border: rgba(20, 20, 20, 0.12);
|
||
--charcoal-divider: rgba(20, 20, 20, 0.08);
|
||
/* [nexus] chart palette exception — 5 muted hues for agent-role differentiation */
|
||
--chart-role-1: #4f5100; /* olive (volt family) — generalist/primary */
|
||
--chart-role-2: #0f766e; /* teal — ops/secondary */
|
||
--chart-role-3: #6d28d9; /* violet — creative/tertiary */
|
||
--chart-role-4: #b45309; /* amber — data/quaternary */
|
||
--chart-role-5: #6b6b6b; /* gray — support/quinary */
|
||
}
|
||
|
||
/* -- Dark mode --------------------------------------------------------- */
|
||
|
||
.dark {
|
||
color-scheme: dark;
|
||
--radius: 8px;
|
||
--background: #000000;
|
||
--foreground: #ffffff;
|
||
--card: #141414;
|
||
--card-foreground: #ffffff;
|
||
--popover: #141414;
|
||
--popover-foreground: #ffffff;
|
||
--primary: #faff69;
|
||
--primary-foreground: #151515;
|
||
--secondary: #166534;
|
||
--secondary-foreground: #ffffff;
|
||
--muted: #141414;
|
||
--muted-foreground: #a0a0a0;
|
||
--accent: #141414;
|
||
--accent-foreground: #faff69;
|
||
--destructive: #ef4444;
|
||
--destructive-foreground: #ffffff;
|
||
--warning: #f59e0b;
|
||
--warning-foreground: #151515;
|
||
--success: #166534;
|
||
--success-foreground: #ffffff;
|
||
--border: rgba(65, 65, 65, 0.8);
|
||
--input: #141414;
|
||
--ring: #faff69;
|
||
--chart-1: #faff69;
|
||
--chart-2: #166534;
|
||
--chart-3: #a0a0a0;
|
||
--chart-4: #f4f692;
|
||
--chart-5: #ef4444;
|
||
--sidebar: #000000;
|
||
--sidebar-foreground: #a0a0a0;
|
||
--sidebar-primary: #faff69;
|
||
--sidebar-primary-foreground: #151515;
|
||
--sidebar-accent: #141414;
|
||
--sidebar-accent-foreground: #ffffff;
|
||
--sidebar-border: rgba(65, 65, 65, 0.8);
|
||
--sidebar-ring: #faff69;
|
||
/* Brand direct refs */
|
||
--volt: #faff69;
|
||
--volt-pale: #f4f692;
|
||
--volt-border: #4f5100;
|
||
--forest: #166534;
|
||
--forest-dark: #14572f;
|
||
--near-black: #141414;
|
||
--hover-gray: #3a3a3a;
|
||
--silver: #a0a0a0;
|
||
--charcoal-border: rgba(65, 65, 65, 0.8);
|
||
--charcoal-divider: #343434;
|
||
/* [nexus] chart palette exception — 5 muted hues for agent-role differentiation */
|
||
--chart-role-1: #faff69; /* volt — generalist/primary */
|
||
--chart-role-2: #6ee7b7; /* muted teal-green — ops/secondary */
|
||
--chart-role-3: #c4b5fd; /* muted lavender — creative/tertiary */
|
||
--chart-role-4: #fcd34d; /* muted amber — data/quaternary */
|
||
--chart-role-5: #a0a0a0; /* silver — support/quinary */
|
||
}
|
||
|
||
/* -- highlight.js syntax theme overrides (chat code blocks) ------------- */
|
||
|
||
/* Base hljs surface — themed via CSS vars */
|
||
.hljs {
|
||
background: var(--card) !important;
|
||
color: var(--foreground) !important;
|
||
}
|
||
|
||
/* Light mode hljs (default) */
|
||
.hljs-keyword,
|
||
.hljs-selector-tag,
|
||
.hljs-literal,
|
||
.hljs-number {
|
||
color: #166534;
|
||
}
|
||
.hljs-string,
|
||
.hljs-attr {
|
||
color: #4f5100;
|
||
}
|
||
.hljs-function,
|
||
.hljs-title,
|
||
.hljs-built_in,
|
||
.hljs-variable,
|
||
.hljs-type,
|
||
.hljs-meta {
|
||
color: #0a0a0a;
|
||
}
|
||
.hljs-comment {
|
||
color: #6b6b6b;
|
||
font-style: italic;
|
||
}
|
||
.hljs-deletion,
|
||
.hljs-selector-class {
|
||
color: #dc2626;
|
||
}
|
||
|
||
/* Dark mode hljs — overrides the light defaults */
|
||
.dark .hljs {
|
||
background: #141414 !important;
|
||
color: #ffffff !important;
|
||
}
|
||
.dark .hljs-keyword,
|
||
.dark .hljs-selector-tag,
|
||
.dark .hljs-literal,
|
||
.dark .hljs-number,
|
||
.dark .hljs-meta {
|
||
color: #faff69;
|
||
}
|
||
.dark .hljs-string,
|
||
.dark .hljs-attr,
|
||
.dark .hljs-type {
|
||
color: #f4f692;
|
||
}
|
||
.dark .hljs-function,
|
||
.dark .hljs-title,
|
||
.dark .hljs-built_in,
|
||
.dark .hljs-variable,
|
||
.dark .hljs-selector-class {
|
||
color: #ffffff;
|
||
}
|
||
.dark .hljs-comment {
|
||
color: #a0a0a0;
|
||
font-style: italic;
|
||
}
|
||
.dark .hljs-deletion {
|
||
color: #ef4444;
|
||
}
|
||
|
||
@layer base {
|
||
* {
|
||
@apply border-border;
|
||
}
|
||
html {
|
||
height: 100%;
|
||
-webkit-tap-highlight-color: color-mix(in oklab, var(--foreground) 20%, transparent);
|
||
}
|
||
body {
|
||
@apply bg-background text-foreground antialiased;
|
||
font-family: var(--font-sans);
|
||
height: 100%;
|
||
overflow: hidden;
|
||
}
|
||
h1,
|
||
h2,
|
||
h3 {
|
||
text-wrap: balance;
|
||
}
|
||
/* Prevent double-tap-to-zoom on interactive elements for mobile */
|
||
a,
|
||
button,
|
||
[role="button"],
|
||
input,
|
||
select,
|
||
textarea,
|
||
label {
|
||
touch-action: manipulation;
|
||
}
|
||
/* Let font-mono (utilities layer) override for monospace editors */
|
||
.paperclip-mdxeditor [class*="_placeholder_"],
|
||
.paperclip-mdxeditor-content {
|
||
font-family: inherit;
|
||
}
|
||
}
|
||
|
||
@media (pointer: coarse) {
|
||
button,
|
||
[role="button"],
|
||
input,
|
||
select,
|
||
textarea,
|
||
[data-slot="select-trigger"] {
|
||
min-height: 44px;
|
||
}
|
||
|
||
[data-slot="toggle"] {
|
||
min-height: 0;
|
||
}
|
||
}
|
||
|
||
/* Scrollbars — themed via CSS vars so they follow light/dark. */
|
||
*::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
|
||
*::-webkit-scrollbar-track {
|
||
background: var(--muted);
|
||
}
|
||
|
||
*::-webkit-scrollbar-thumb {
|
||
background: var(--charcoal-border);
|
||
border-radius: 4px;
|
||
}
|
||
|
||
*::-webkit-scrollbar-thumb:hover {
|
||
background: var(--hover-gray);
|
||
}
|
||
|
||
/* Auto-hide scrollbar: always reserves space, thumb visible only on hover */
|
||
.scrollbar-auto-hide::-webkit-scrollbar {
|
||
width: 8px !important;
|
||
background: transparent !important;
|
||
}
|
||
.scrollbar-auto-hide::-webkit-scrollbar-track {
|
||
background: transparent !important;
|
||
}
|
||
.scrollbar-auto-hide::-webkit-scrollbar-thumb {
|
||
background: transparent !important;
|
||
}
|
||
.scrollbar-auto-hide:hover::-webkit-scrollbar-track {
|
||
background: var(--muted) !important;
|
||
}
|
||
.scrollbar-auto-hide:hover::-webkit-scrollbar-thumb {
|
||
background: var(--charcoal-border) !important;
|
||
}
|
||
.scrollbar-auto-hide:hover::-webkit-scrollbar-thumb:hover {
|
||
background: var(--hover-gray) !important;
|
||
}
|
||
|
||
/* Expandable dialog transition for max-width changes */
|
||
[data-slot="dialog-content"] {
|
||
transition: max-width 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
|
||
/* Dashboard activity row entry motion */
|
||
@keyframes dashboard-activity-enter {
|
||
0% {
|
||
opacity: 0;
|
||
transform: translateY(-14px) scale(0.985);
|
||
filter: blur(4px);
|
||
}
|
||
62% {
|
||
opacity: 1;
|
||
transform: translateY(2px) scale(1.002);
|
||
filter: blur(0);
|
||
}
|
||
100% {
|
||
opacity: 1;
|
||
transform: translateY(0) scale(1);
|
||
filter: blur(0);
|
||
}
|
||
}
|
||
|
||
@keyframes dashboard-activity-highlight {
|
||
0% {
|
||
box-shadow: inset 2px 0 0 var(--primary);
|
||
background-color: color-mix(in oklab, var(--accent) 55%, transparent);
|
||
}
|
||
100% {
|
||
box-shadow: inset 0 0 0 transparent;
|
||
background-color: transparent;
|
||
}
|
||
}
|
||
|
||
.activity-row-enter {
|
||
animation:
|
||
dashboard-activity-enter 520ms cubic-bezier(0.16, 1, 0.3, 1),
|
||
dashboard-activity-highlight 920ms cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.activity-row-enter {
|
||
animation: none;
|
||
}
|
||
}
|
||
|
||
/* MDXEditor theme integration */
|
||
.paperclip-mdxeditor-scope,
|
||
.paperclip-mdxeditor {
|
||
--baseBase: var(--background);
|
||
--baseBg: transparent;
|
||
--baseBgSubtle: color-mix(in oklab, var(--accent) 35%, transparent);
|
||
--baseLine: var(--border);
|
||
--baseSolid: var(--muted-foreground);
|
||
--baseSolidHover: var(--foreground);
|
||
--baseText: var(--muted-foreground);
|
||
--baseBorderColor: var(--border);
|
||
--baseBorder: var(--border);
|
||
--baseBorderHover: var(--ring);
|
||
--baseTextContrast: var(--foreground);
|
||
--baseTextContrastMuted: var(--muted-foreground);
|
||
--baseTextEmphasis: var(--foreground);
|
||
--basePageBg: var(--background);
|
||
--baseRadius: var(--radius);
|
||
--baseLineHeight: 1.5;
|
||
--accentBorder: color-mix(in oklab, var(--primary) 35%, var(--border));
|
||
--accentSolid: var(--primary);
|
||
--accentSolidHover: var(--primary);
|
||
--accentLine: color-mix(in oklab, var(--primary) 20%, transparent);
|
||
--accentBg: var(--accent);
|
||
--accentBgHover: color-mix(in oklab, var(--accent) 80%, var(--background));
|
||
--accentBgActive: color-mix(in oklab, var(--accent) 72%, var(--background));
|
||
--accentText: var(--accent-foreground);
|
||
font-family: inherit;
|
||
font-size: 0.875rem;
|
||
line-height: 1.5;
|
||
color: var(--foreground);
|
||
}
|
||
|
||
.paperclip-mdxeditor-scope [class*="_iconButton_"],
|
||
.paperclip-mdxeditor [class*="_iconButton_"] {
|
||
color: var(--baseText);
|
||
}
|
||
|
||
.paperclip-mdxeditor-scope [class*="_iconButton_"]:hover,
|
||
.paperclip-mdxeditor [class*="_iconButton_"]:hover {
|
||
color: var(--baseTextContrast);
|
||
}
|
||
|
||
.paperclip-mdxeditor .mdxeditor-root-contenteditable {
|
||
min-height: 2.5rem;
|
||
padding: 0;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.paperclip-mdxeditor [class*="_contentEditable_"] {
|
||
padding: 0.375rem 0.625rem !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor--borderless [class*="_contentEditable_"] {
|
||
padding: 0 !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor [class*="_placeholder_"] {
|
||
font-size: 0.875rem;
|
||
line-height: 1.5;
|
||
color: var(--muted-foreground);
|
||
}
|
||
|
||
.paperclip-mdxeditor-content {
|
||
font-size: inherit;
|
||
line-height: inherit;
|
||
color: inherit;
|
||
}
|
||
|
||
.paperclip-edit-in-place-content {
|
||
font-size: 0.9375rem;
|
||
line-height: 1.75rem;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content > *:first-child {
|
||
margin-top: 0;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content > *:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content p {
|
||
margin: 0;
|
||
line-height: inherit;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content p + p {
|
||
margin-top: 1.1em;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content a:not(.paperclip-mention-chip):not(.paperclip-project-mention-chip) {
|
||
color: color-mix(in oklab, var(--foreground) 76%, var(--primary) 24%);
|
||
text-decoration: underline;
|
||
text-underline-offset: 0.15em;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.dark .paperclip-mdxeditor-content a:not(.paperclip-mention-chip):not(.paperclip-project-mention-chip) {
|
||
color: var(--volt);
|
||
}
|
||
|
||
.paperclip-mdxeditor-content a.paperclip-mention-chip,
|
||
.paperclip-mdxeditor-content a.paperclip-project-mention-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.25rem;
|
||
margin: 0 0.1rem;
|
||
padding: 0.05rem 0.45rem;
|
||
border: 1px solid var(--border);
|
||
border-radius: 999px;
|
||
font-size: 0.75rem;
|
||
line-height: 1.3;
|
||
text-decoration: none;
|
||
vertical-align: middle;
|
||
white-space: nowrap;
|
||
user-select: none;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content a.paperclip-mention-chip::before,
|
||
a.paperclip-mention-chip::before {
|
||
content: "";
|
||
flex: none;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content a.paperclip-mention-chip[data-mention-kind="project"]::before,
|
||
a.paperclip-mention-chip[data-mention-kind="project"]::before {
|
||
width: 0.45rem;
|
||
height: 0.45rem;
|
||
border-radius: 999px;
|
||
background-color: var(--paperclip-mention-project-color, currentColor);
|
||
}
|
||
|
||
.paperclip-mdxeditor-content a.paperclip-mention-chip[data-mention-kind="agent"]::before,
|
||
a.paperclip-mention-chip[data-mention-kind="agent"]::before {
|
||
width: 0.75rem;
|
||
height: 0.75rem;
|
||
background-color: currentColor;
|
||
-webkit-mask-image: var(--paperclip-mention-icon-mask);
|
||
mask-image: var(--paperclip-mention-icon-mask);
|
||
-webkit-mask-position: center;
|
||
mask-position: center;
|
||
-webkit-mask-repeat: no-repeat;
|
||
mask-repeat: no-repeat;
|
||
-webkit-mask-size: contain;
|
||
mask-size: contain;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content ul,
|
||
.paperclip-mdxeditor-content ol {
|
||
margin: 1.1em 0;
|
||
padding-left: 1.6em;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content ul {
|
||
list-style: disc;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content ol {
|
||
list-style: decimal;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content li {
|
||
display: list-item;
|
||
margin: 0.3em 0;
|
||
line-height: inherit;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content li::marker {
|
||
color: var(--muted-foreground);
|
||
}
|
||
|
||
.paperclip-mdxeditor-content h1 {
|
||
margin: 1.4em 0 0.9em;
|
||
font-size: 1.75em;
|
||
font-weight: 700;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content h2 {
|
||
margin: 1.3em 0 0.85em;
|
||
font-size: 1.35em;
|
||
font-weight: 700;
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content h3 {
|
||
margin: 1.2em 0 0.8em;
|
||
font-size: 1.15em;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content img {
|
||
max-height: 18rem;
|
||
border-radius: calc(var(--radius) - 2px);
|
||
}
|
||
|
||
.paperclip-mdxeditor-content blockquote {
|
||
margin: 1.2em 0;
|
||
padding-left: 1em;
|
||
border-left: 3px solid var(--border);
|
||
color: var(--muted-foreground);
|
||
line-height: inherit;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content code {
|
||
font-family: var(--font-mono);
|
||
font-size: 1em;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content pre {
|
||
margin: 0.4rem 0;
|
||
padding: 0;
|
||
border: 1px solid var(--border);
|
||
border-radius: calc(var(--radius) - 3px);
|
||
background: var(--card);
|
||
color: var(--card-foreground);
|
||
overflow-x: auto;
|
||
}
|
||
|
||
/* CodeMirror code blocks inside the MDXEditor — themed via CSS vars. */
|
||
.paperclip-mdxeditor .cm-editor {
|
||
background-color: var(--card) !important;
|
||
color: var(--card-foreground) !important;
|
||
font-size: 1em;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-gutters {
|
||
background-color: var(--muted) !important;
|
||
color: var(--muted-foreground) !important;
|
||
border-right: 1px solid var(--border) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-activeLineGutter {
|
||
background-color: var(--card) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-activeLine {
|
||
background-color: color-mix(in oklab, var(--foreground) 5%, transparent) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-cursor,
|
||
.paperclip-mdxeditor .cm-dropCursor {
|
||
border-left-color: var(--foreground) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-selectionBackground {
|
||
background-color: color-mix(in oklab, var(--primary) 25%, transparent) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-focused .cm-selectionBackground {
|
||
background-color: color-mix(in oklab, var(--primary) 30%, transparent) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-content {
|
||
caret-color: var(--foreground);
|
||
}
|
||
|
||
/* MDXEditor code block language selector – show on hover only */
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorWrapper_"] {
|
||
position: relative;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorToolbar_"],
|
||
.paperclip-mdxeditor-content [class*="_codeBlockToolbar_"] {
|
||
position: absolute;
|
||
top: 0.25rem;
|
||
right: 0.25rem;
|
||
z-index: 2;
|
||
opacity: 0;
|
||
transition: opacity 150ms ease;
|
||
}
|
||
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorToolbar_"] select,
|
||
.paperclip-mdxeditor-content [class*="_codeBlockToolbar_"] select {
|
||
background-color: var(--muted);
|
||
color: var(--foreground);
|
||
border-color: var(--border);
|
||
}
|
||
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorWrapper_"]:hover [class*="_codeMirrorToolbar_"],
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorWrapper_"]:hover [class*="_codeBlockToolbar_"],
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorWrapper_"]:focus-within [class*="_codeMirrorToolbar_"],
|
||
.paperclip-mdxeditor-content [class*="_codeMirrorWrapper_"]:focus-within [class*="_codeBlockToolbar_"] {
|
||
opacity: 1;
|
||
}
|
||
|
||
/* Rendered markdown code blocks & inline code (prose/MarkdownBody context). */
|
||
.paperclip-markdown {
|
||
--tw-prose-pre-bg: var(--card);
|
||
--tw-prose-pre-code: var(--card-foreground);
|
||
--tw-prose-invert-pre-bg: var(--card);
|
||
--tw-prose-invert-pre-code: var(--card-foreground);
|
||
}
|
||
|
||
.paperclip-markdown pre {
|
||
border: 1px solid var(--border) !important;
|
||
border-radius: calc(var(--radius) - 3px) !important;
|
||
background-color: var(--card) !important;
|
||
color: var(--card-foreground) !important;
|
||
padding: 0.5rem 0.65rem !important;
|
||
margin: 0.4rem 0 !important;
|
||
font-size: 1em !important;
|
||
overflow-x: auto;
|
||
white-space: pre;
|
||
}
|
||
|
||
.paperclip-markdown code {
|
||
font-family: var(--font-mono);
|
||
font-size: 1em;
|
||
}
|
||
|
||
.paperclip-markdown pre code {
|
||
font-size: inherit;
|
||
color: inherit;
|
||
background: none;
|
||
}
|
||
|
||
/* Remove backtick pseudo-elements from inline code (prose default adds them) */
|
||
.prose code::before,
|
||
.prose code::after {
|
||
content: none;
|
||
}
|
||
|
||
/* Inline code background (not inside a code block) */
|
||
.prose :not(pre) > code {
|
||
background-color: color-mix(in oklab, var(--accent) 60%, transparent);
|
||
padding: 0.15em 0.35em;
|
||
border-radius: 3px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.dark .prose :not(pre) > code {
|
||
background-color: color-mix(in oklab, var(--foreground) 6%, transparent);
|
||
}
|
||
|
||
.paperclip-markdown {
|
||
color: var(--foreground);
|
||
font-size: 0.9375rem;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.paperclip-markdown > :first-child {
|
||
margin-top: 0;
|
||
}
|
||
|
||
.paperclip-markdown > :last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.paperclip-markdown :where(p, ul, ol, blockquote, pre, table) {
|
||
margin-top: 0.7rem;
|
||
margin-bottom: 0.7rem;
|
||
}
|
||
|
||
.paperclip-markdown :where(ul, ol) {
|
||
padding-left: 1.15rem;
|
||
}
|
||
|
||
.paperclip-markdown ul {
|
||
list-style-type: disc;
|
||
}
|
||
|
||
.paperclip-markdown ol {
|
||
list-style-type: decimal;
|
||
}
|
||
|
||
.paperclip-markdown li {
|
||
margin: 0.14rem 0;
|
||
padding-left: 0.2rem;
|
||
}
|
||
|
||
.paperclip-markdown li > :where(p, ul, ol) {
|
||
margin-top: 0.3rem;
|
||
margin-bottom: 0.3rem;
|
||
}
|
||
|
||
.paperclip-markdown li::marker {
|
||
color: var(--muted-foreground);
|
||
}
|
||
|
||
.paperclip-markdown h1,
|
||
.paperclip-markdown h2,
|
||
.paperclip-markdown h3,
|
||
.paperclip-markdown h4 {
|
||
margin-top: 1.75rem;
|
||
margin-bottom: 0.45rem;
|
||
color: var(--foreground);
|
||
font-weight: 600;
|
||
letter-spacing: -0.01em;
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.paperclip-markdown h1 {
|
||
font-size: 1.5rem;
|
||
}
|
||
|
||
.paperclip-markdown h2 {
|
||
font-size: 1.25rem;
|
||
}
|
||
|
||
.paperclip-markdown h3 {
|
||
font-size: 1.05rem;
|
||
}
|
||
|
||
.paperclip-markdown h4 {
|
||
font-size: 0.95rem;
|
||
}
|
||
|
||
.paperclip-markdown :where(strong, b) {
|
||
color: var(--foreground);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.paperclip-markdown a {
|
||
color: color-mix(in oklab, var(--foreground) 76%, var(--primary) 24%);
|
||
text-decoration: underline;
|
||
text-underline-offset: 0.15em;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.paperclip-markdown a.paperclip-mention-chip {
|
||
text-decoration: none;
|
||
}
|
||
|
||
.dark .paperclip-markdown a {
|
||
color: var(--volt);
|
||
}
|
||
|
||
.paperclip-markdown blockquote {
|
||
margin-left: 0;
|
||
padding-left: 0.95rem;
|
||
border-left: 0.24rem solid color-mix(in oklab, var(--border) 84%, var(--muted-foreground) 16%);
|
||
color: var(--muted-foreground);
|
||
}
|
||
|
||
.paperclip-markdown hr {
|
||
margin: 1.25rem 0;
|
||
border-color: var(--border);
|
||
}
|
||
|
||
.paperclip-markdown img {
|
||
border-radius: calc(var(--radius) + 2px);
|
||
box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent);
|
||
}
|
||
|
||
.paperclip-markdown table {
|
||
width: 100%;
|
||
}
|
||
|
||
.paperclip-markdown th {
|
||
font-weight: 600;
|
||
text-align: left;
|
||
}
|
||
|
||
.paperclip-mermaid {
|
||
margin: 0.5rem 0;
|
||
padding: 0.45rem 0.55rem;
|
||
border: 1px solid var(--border);
|
||
border-radius: calc(var(--radius) - 3px);
|
||
background-color: color-mix(in oklab, var(--accent) 35%, transparent);
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.paperclip-mermaid svg {
|
||
display: block;
|
||
width: max-content;
|
||
max-width: none;
|
||
min-width: 100%;
|
||
height: auto;
|
||
}
|
||
|
||
.paperclip-mermaid-status {
|
||
margin: 0 0 0.45rem;
|
||
font-size: 0.75rem;
|
||
color: var(--muted-foreground);
|
||
}
|
||
|
||
.paperclip-mermaid-status-error {
|
||
color: var(--destructive);
|
||
}
|
||
|
||
.paperclip-mermaid-source {
|
||
margin: 0;
|
||
padding: 0;
|
||
border: 0;
|
||
background: transparent;
|
||
}
|
||
|
||
/* Project mention chips rendered inside MarkdownBody */
|
||
a.paperclip-mention-chip,
|
||
a.paperclip-project-mention-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.25rem;
|
||
margin: 0 0.1rem;
|
||
padding: 0.05rem 0.45rem;
|
||
border: 1px solid var(--border);
|
||
border-radius: 999px;
|
||
font-size: 0.75rem;
|
||
line-height: 1.3;
|
||
text-decoration: none;
|
||
vertical-align: middle;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* Keep MDXEditor popups above app dialogs, even when they portal to <body>. */
|
||
[class*="_popupContainer_"] {
|
||
z-index: 81 !important;
|
||
}
|
||
|
||
[class*="_dialogOverlay_"] {
|
||
z-index: 80;
|
||
}
|
||
|
||
[class*="_dialogContent_"],
|
||
[class*="_largeDialogContent_"],
|
||
[class*="_popoverContent_"],
|
||
[class*="_linkDialogPopoverContent_"],
|
||
[class*="_tableColumnEditorPopoverContent_"],
|
||
[class*="_toolbarButtonDropdownContainer_"],
|
||
[class*="_toolbarNodeKindSelectContainer_"] {
|
||
z-index: 81 !important;
|
||
}
|
||
|
||
@keyframes cursor-blink {
|
||
0%, 100% { opacity: 1; }
|
||
50% { opacity: 0; }
|
||
}
|
||
|
||
.animate-cursor-blink {
|
||
animation: cursor-blink 800ms step-start infinite;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.animate-cursor-blink {
|
||
animation: none;
|
||
opacity: 1;
|
||
}
|
||
}
|