nexus/ui/src/index.css
Nexus Dev 4b8f8178ee feat(nexus): design system phase 2 status and role color dictionaries
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>
2026-04-10 17:25:21 +00:00

951 lines
23 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@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;
}
}