2484 lines
114 KiB
CSS
2484 lines
114 KiB
CSS
@import "tailwindcss";
|
||
@plugin "@tailwindcss/typography";
|
||
|
||
@font-face {
|
||
font-family: "InterVariable";
|
||
src: url("../fonts/InterVariable.woff2") format("woff2");
|
||
font-display: swap;
|
||
font-style: normal;
|
||
font-weight: 100 900;
|
||
}
|
||
|
||
@font-face {
|
||
font-family: "InterVariable";
|
||
src: url("../fonts/InterVariable-Italic.woff2") format("woff2");
|
||
font-display: swap;
|
||
font-style: italic;
|
||
font-weight: 100 900;
|
||
}
|
||
|
||
@custom-variant dark (&:is(.dark *));
|
||
|
||
@theme inline {
|
||
--font-sans: "InterVariable", "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||
--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-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);
|
||
/* Multiplicative radius ladder (modern shadcn/Tailwind v4 mapping):
|
||
sm/md/lg/xl/2xl/3xl/4xl = 0.6/0.8/1.0/1.4/1.8/2.2/2.6 x the single
|
||
--radius knob (base anchor 0.5rem = 8px; rounded-lg IS the anchor).
|
||
Replaces the additive +/-px ladder (DECISION-SHEET B4 → Run 3 review):
|
||
retune the whole app's corner language by editing --radius alone. */
|
||
--radius-sm: calc(var(--radius) * 0.6);
|
||
--radius-md: calc(var(--radius) * 0.8);
|
||
--radius-lg: var(--radius);
|
||
--radius-xl: calc(var(--radius) * 1.4);
|
||
--font-heading: var(--font-sans);
|
||
--radius-2xl: calc(var(--radius) * 1.8);
|
||
--radius-3xl: calc(var(--radius) * 2.2);
|
||
--radius-4xl: calc(var(--radius) * 2.6);
|
||
}
|
||
|
||
:root {
|
||
color-scheme: light;
|
||
--radius: 0.5rem;
|
||
--background: oklch(1 0 0);
|
||
--foreground: oklch(0.145 0 0);
|
||
--card: oklch(1 0 0);
|
||
--card-foreground: oklch(0.145 0 0);
|
||
--popover: oklch(1 0 0);
|
||
--popover-foreground: oklch(0.145 0 0);
|
||
--primary: oklch(0.205 0 0);
|
||
--primary-foreground: oklch(0.985 0 0);
|
||
--secondary: oklch(0.97 0 0);
|
||
--secondary-foreground: oklch(0.205 0 0);
|
||
--muted: oklch(0.97 0 0);
|
||
--muted-foreground: oklch(0.556 0 0);
|
||
--accent: oklch(0.97 0 0);
|
||
--accent-foreground: oklch(0.205 0 0);
|
||
--destructive: oklch(0.577 0.245 27.325);
|
||
--destructive-foreground: oklch(0.577 0.245 27.325);
|
||
--border: oklch(0.922 0 0);
|
||
--input: oklch(0.922 0 0);
|
||
--ring: oklch(0.708 0 0);
|
||
--chart-1: oklch(0.87 0 0);
|
||
--chart-2: oklch(0.556 0 0);
|
||
--chart-3: oklch(0.439 0 0);
|
||
--chart-4: oklch(0.371 0 0);
|
||
--chart-5: oklch(0.269 0 0);
|
||
--sidebar: oklch(0.985 0 0);
|
||
--sidebar-foreground: oklch(0.145 0 0);
|
||
--sidebar-primary: oklch(0.205 0 0);
|
||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||
--sidebar-accent: oklch(0.97 0 0);
|
||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||
--sidebar-border: oklch(0.922 0 0);
|
||
--sidebar-ring: oklch(0.708 0 0);
|
||
--chip-match-title-bg: oklch(0.97 0.02 265);
|
||
--chip-match-title-fg: oklch(0.4 0.13 265);
|
||
--chip-match-title-border: oklch(0.85 0.05 265);
|
||
--chip-match-comment-bg: oklch(0.97 0.02 145);
|
||
--chip-match-comment-fg: oklch(0.4 0.10 145);
|
||
--chip-match-comment-border: oklch(0.85 0.05 145);
|
||
--chip-match-document-bg: oklch(0.97 0.02 295);
|
||
--chip-match-document-fg: oklch(0.4 0.10 295);
|
||
--chip-match-document-border: oklch(0.85 0.05 295);
|
||
--chip-match-identifier-bg: var(--muted);
|
||
--chip-match-identifier-fg: var(--muted-foreground);
|
||
--chip-match-identifier-border: var(--border);
|
||
--paperclip-doc-annotation-highlight-open: #fef08a;
|
||
--paperclip-doc-annotation-highlight-focused: #fde047;
|
||
--paperclip-doc-annotation-highlight-stale: #fef08a;
|
||
--paperclip-doc-annotation-highlight-resolved: #fef9c3;
|
||
|
||
/* Brand agent-capsule gradient stops (paperclip.ing/brand/).
|
||
"The capsule is the agent" — each agent gets a 2-stop gradient,
|
||
--agent-Na (top) → --agent-Nb (bottom). Brand-fixed hex, identical
|
||
across themes. Indices 1–10; consumed by AgentCapsule. */
|
||
--agent-1a: #f7cfdc;
|
||
--agent-1b: #1f7a3a;
|
||
--agent-2a: #c9a9e8;
|
||
--agent-2b: #ee79a1;
|
||
--agent-3a: #28164b;
|
||
--agent-3b: #7a1530;
|
||
--agent-4a: #f3e6c4;
|
||
--agent-4b: #e3a21a;
|
||
--agent-5a: #1f4dd6;
|
||
--agent-5b: #3aa35c;
|
||
--agent-6a: #e94b27;
|
||
--agent-6b: #5a1122;
|
||
--agent-7a: #7eb6e3;
|
||
--agent-7b: #ee79a1;
|
||
--agent-8a: #9ce8a7;
|
||
--agent-8b: #bd7ff0;
|
||
--agent-9a: #f3b49e;
|
||
--agent-9b: #1f4ed4;
|
||
--agent-10a: #f2d95f;
|
||
--agent-10b: #4fbcba;
|
||
|
||
/* Status colors — one base hue per status, consumed by the agent / task
|
||
status chips and the task status icons. Mode-independent: the `.status-chip`,
|
||
`.status-fill` and inline icon helpers derive the light vs dark
|
||
fill/text/border from these via color-mix, so a single hue covers both
|
||
modes. Values mirror the PAP-75 brand palette (gray inert, blue liveness,
|
||
amber queued, violet review, green done, red blocked). */
|
||
--status-agent-idle: #a8aeb2;
|
||
--status-agent-running: #2563eb;
|
||
--status-agent-paused: #f59e0b;
|
||
--status-agent-error: #dc2626;
|
||
--status-task-backlog: #a8aeb2;
|
||
--status-task-todo: #f59e0b;
|
||
--status-task-in_progress: #2563eb;
|
||
--status-task-in_review: #7c3aed;
|
||
--status-task-done: #22c55e;
|
||
--status-task-blocked: #dc2626;
|
||
--status-task-cancelled: #a8aeb2;
|
||
|
||
/* Task status ICON hues (PAP-238 3b) — AA-tuned (every glyph ≥ 3:1 against
|
||
its surface, WCAG 2.1 AA, both modes). Distinct from the
|
||
`--status-task-*` chip base hues: a status chip carries its own bg/text
|
||
tint, but a bare glyph sitting next to text on the page needs a stronger
|
||
hue to clear 3:1. Where the chip base already passes (blue liveness, red
|
||
blocked, light violet review) the icon var simply re-points at it; the
|
||
gray / amber / green statuses are pinned to the board-approved AA hexes.
|
||
`in_queue` is the BLOCKED shape recoloured to the in_progress blue
|
||
(replaces the bespoke teal "covered" state). Light values here; the
|
||
`.dark` block below overrides the four that need a mode-specific hue. */
|
||
--status-task-icon-backlog: #52585d; /* gray darkened — 7.21:1 on paper */
|
||
--status-task-icon-todo: #cc7a00; /* amber darkened — clears 3:1 */
|
||
--status-task-icon-in_progress: var(--status-task-in_progress); /* #2563eb both modes */
|
||
--status-task-icon-in_review: var(--status-task-in_review); /* #7c3aed (light) */
|
||
--status-task-icon-done: #16a34a; /* green darkened — clears 3:1 */
|
||
--status-task-icon-blocked: var(--status-task-blocked); /* #dc2626 both modes */
|
||
--status-task-icon-cancelled: #52585d;
|
||
--status-task-icon-in_queue: var(--status-task-in_progress); /* blocked shape, blue */
|
||
|
||
--folder-color-indigo: #6366f1;
|
||
--folder-color-violet: #8b5cf6;
|
||
--folder-color-emerald: #10b981;
|
||
--folder-color-cyan: #06b6d4;
|
||
--folder-color-amber: #f59e0b;
|
||
--folder-color-slate: #64748b;
|
||
--gtc-folder-row: 1rem minmax(0, 1fr) auto;
|
||
--gtc-folder-row-actions: 1rem minmax(0, 1fr) auto auto;
|
||
--sz-folder-rail: 13.25rem;
|
||
--sz-folder-sheet-max: 80dvh;
|
||
--sz-tweak-panel-max: 70vh; /* Task Chat Redesign dev tweak panel scroll cap. */
|
||
|
||
/* New-task dialog geometry inputs and gap tokens. The derived top/height
|
||
calculations live on the dialog element so runtime Visual Viewport
|
||
overrides participate in computed-value resolution. */
|
||
--new-issue-visual-viewport-height: 100dvh;
|
||
--new-issue-visual-viewport-offset-top: 0px;
|
||
--new-issue-dialog-top-gap: max(1rem, env(safe-area-inset-top));
|
||
--new-issue-dialog-bottom-gap: max(1rem, env(safe-area-inset-bottom));
|
||
|
||
/* ────────────────────────────────────────────────────────────────────────
|
||
Motion tokens — chat-style task thread (default; classic legacy view sits
|
||
behind enableClassicTaskInterface).
|
||
|
||
These are the single source of truth for the redesigned thread's motion.
|
||
Kept in :root (NOT @theme inline) on purpose: @theme inline bakes literals
|
||
at build time, so the dev tweak panel — which writes these live via
|
||
element.style.setProperty — could not move a baked value. Rationale for
|
||
each transition point lives in DESIGN.md; VALUES here are tunable
|
||
placeholders the human tunes live via the tweak panel, then pastes back.
|
||
Reuses the two house easing curves already used across the app. Any new
|
||
motion in the redesigned thread MUST reference one of these tokens — no
|
||
hardcoded ms / cubic-bezier in components (enforced by a check script).
|
||
──────────────────────────────────────────────────────────────────────── */
|
||
|
||
/* Easing primitives (tunable). --motion-ease-out itself is declared by the
|
||
decision/quicklook motion block further down; the thread shares it. */
|
||
--motion-ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); /* house signature curve */
|
||
--motion-ease-standard: cubic-bezier(0.4, 0, 0.2, 1); /* house material curve */
|
||
|
||
/* Duration primitives (tunable) */
|
||
--motion-duration-instant: 80ms;
|
||
--motion-duration-fast: 160ms;
|
||
--motion-duration-base: 240ms;
|
||
--motion-duration-slow: 360ms;
|
||
--motion-duration-deliberate: 520ms;
|
||
|
||
/* State/component-scoped — grouped for the tweak panel (tunable) */
|
||
--motion-marker-enter: var(--motion-duration-base);
|
||
--motion-bubble-enter: var(--motion-duration-fast);
|
||
--motion-cot-line-stagger: 40ms;
|
||
--motion-cot-collapse: var(--motion-duration-base);
|
||
--motion-tool-enter: var(--motion-duration-base);
|
||
--motion-diff-reveal: var(--motion-duration-base);
|
||
--motion-status-enter: var(--motion-duration-fast);
|
||
--motion-status-exit: var(--motion-duration-fast);
|
||
--motion-approval-pulse: 1.6s;
|
||
--motion-plan-entry-stagger: 40ms;
|
||
--motion-plan-check: var(--motion-duration-fast);
|
||
--motion-count-tween: var(--motion-duration-slow);
|
||
--motion-streaming-cursor-blink: 1.1s;
|
||
--motion-turn-fold: 380ms; /* finished-turn activity folding into its summary line */
|
||
--motion-turn-meta: var(--motion-duration-fast); /* finished-turn hover metadata reveal */
|
||
--motion-line-scroll: 240ms; /* completed interstitial line sliding out of the 1lh live-line viewport */
|
||
--motion-interstitial-dwell: 4000ms; /* interstitial update hold: minimum before the next swaps in, and how long a finished update sits before sliding away */
|
||
--motion-scroll-pill-enter: 200ms; /* scroll-to-latest pill entry */
|
||
--motion-scroll-pill-exit: 400ms; /* scroll-to-latest pill exit */
|
||
--motion-ease-scroll-pill-in: cubic-bezier(0.23, 1, 0.32, 1);
|
||
--motion-ease-scroll-pill-out: cubic-bezier(0.7, 0, 0.84, 0);
|
||
--motion-pane-glide: 320ms; /* properties-pane maximize/restore glide */
|
||
|
||
/* Composer mode-chip hues (v5–v7 decisions): agent + plan reuse the task
|
||
status hues; ask is the v5 blue. Consumed as `--sc` seeds through the
|
||
.status-chip color-mix recipe. */
|
||
--tc-mode-agent: var(--status-task-backlog);
|
||
--tc-mode-plan: var(--status-task-todo);
|
||
--tc-mode-ask: #3b82f6;
|
||
|
||
/* Agent-comment comparison fill used by TaskChatLab. The chosen production
|
||
treatment sits directly on the page surface; this token keeps the darker
|
||
card available as an explicit lab alternative. */
|
||
--bubble-agent: oklch(0.97 0 0);
|
||
--bubble-agent-card-padding-inline: 0.875rem;
|
||
|
||
/* Redesigned thread viewport bound: lets the thread own its scroll (auto-
|
||
follow + pinned composer) inside the page flow. The issue header lives
|
||
INSIDE the scroll viewport (it scrolls away with the messages), so the
|
||
only chrome outside the thread is the top bar plus page padding ≈ 8rem —
|
||
this is what keeps the composer pinned near the viewport bottom. */
|
||
--tc-thread-max-h: calc(100dvh - 8rem);
|
||
|
||
/* Redesigned chat-shell column cap (phase 2c): one token caps the page
|
||
wrapper, thread body, and pinned composer so they widen in lockstep. */
|
||
--tc-shell-max-w: 60rem;
|
||
|
||
/* Mobile pinned-composer bottom offset (PAP-495). Default clears just the
|
||
safe-area inset (+20px); Layout raises it to the bottom-nav height
|
||
(--sz-calc-14) while the auto-hiding mobile nav is on screen, so the
|
||
composer's action row never hides behind the nav. Desktop and the classic
|
||
thread never override it and fall through to the safe-area default. */
|
||
--tc-composer-bottom: var(--sz-calc-8);
|
||
}
|
||
|
||
.dark {
|
||
--background: oklch(0.145 0 0);
|
||
--foreground: oklch(0.985 0 0);
|
||
--card: oklch(0.205 0 0);
|
||
--card-foreground: oklch(0.985 0 0);
|
||
--popover: oklch(0.205 0 0);
|
||
--popover-foreground: oklch(0.985 0 0);
|
||
--primary: oklch(0.922 0 0);
|
||
--primary-foreground: oklch(0.205 0 0);
|
||
--bubble-agent: oklch(0.185 0 0);
|
||
--secondary: oklch(0.269 0 0);
|
||
--secondary-foreground: oklch(0.985 0 0);
|
||
--muted: oklch(0.269 0 0);
|
||
--muted-foreground: oklch(0.708 0 0);
|
||
--accent: oklch(0.269 0 0);
|
||
--accent-foreground: oklch(0.985 0 0);
|
||
--destructive: oklch(0.637 0.237 25.331); /* Gallery feedback round 1: user preferred master's original dark destructive red over the preset's softer 0.704 0.191 22.216. */
|
||
--destructive-foreground: oklch(0.985 0 0);
|
||
--border: oklch(1 0 0 / 10%);
|
||
--input: oklch(1 0 0 / 15%);
|
||
--ring: oklch(0.556 0 0);
|
||
--chart-1: oklch(0.87 0 0);
|
||
--chart-2: oklch(0.556 0 0);
|
||
--chart-3: oklch(0.439 0 0);
|
||
--chart-4: oklch(0.371 0 0);
|
||
--chart-5: oklch(0.269 0 0);
|
||
--sidebar: oklch(0.205 0 0);
|
||
--sidebar-foreground: oklch(0.985 0 0);
|
||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||
--sidebar-accent: oklch(0.269 0 0);
|
||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||
--sidebar-border: oklch(1 0 0 / 10%);
|
||
--sidebar-ring: oklch(0.556 0 0);
|
||
--chip-match-title-bg: oklch(0.27 0.04 265 / 0.5);
|
||
--chip-match-title-fg: oklch(0.78 0.10 265);
|
||
--chip-match-title-border: oklch(0.4 0.06 265);
|
||
--chip-match-comment-bg: oklch(0.27 0.04 145 / 0.5);
|
||
--chip-match-comment-fg: oklch(0.78 0.08 145);
|
||
--chip-match-comment-border: oklch(0.4 0.05 145);
|
||
--chip-match-document-bg: oklch(0.27 0.04 295 / 0.5);
|
||
--chip-match-document-fg: oklch(0.78 0.08 295);
|
||
--chip-match-document-border: oklch(0.4 0.05 295);
|
||
--chip-match-identifier-bg: var(--muted);
|
||
--chip-match-identifier-fg: var(--muted-foreground);
|
||
--chip-match-identifier-border: var(--border);
|
||
--paperclip-doc-annotation-highlight-open: #a16207;
|
||
--paperclip-doc-annotation-highlight-focused: #ca8a04;
|
||
--paperclip-doc-annotation-highlight-stale: #854d0e;
|
||
--paperclip-doc-annotation-highlight-resolved: #713f12;
|
||
|
||
/* Dark-mode AA overrides for the status-icon hues that need a mode-specific
|
||
value (PAP-238). in_progress / blocked stay identical (same blue / red both
|
||
modes) and in_queue tracks in_progress, so they need no override. */
|
||
--status-task-icon-backlog: #9a958a;
|
||
--status-task-icon-todo: #fbbf24;
|
||
--status-task-icon-in_review: #9474f0; /* deeper than violet-400, reads purple */
|
||
--status-task-icon-done: #34d06f;
|
||
--status-task-icon-cancelled: #9a958a;
|
||
}
|
||
|
||
::highlight(paperclip-doc-annotation-open) {
|
||
background-color: var(--paperclip-doc-annotation-highlight-open);
|
||
color: inherit;
|
||
}
|
||
|
||
::highlight(paperclip-doc-annotation-focused) {
|
||
background-color: var(--paperclip-doc-annotation-highlight-focused);
|
||
color: inherit;
|
||
}
|
||
|
||
::highlight(paperclip-doc-annotation-stale) {
|
||
background-color: var(--paperclip-doc-annotation-highlight-stale);
|
||
color: inherit;
|
||
}
|
||
|
||
::highlight(paperclip-doc-annotation-resolved) {
|
||
background-color: var(--paperclip-doc-annotation-highlight-resolved);
|
||
color: inherit;
|
||
}
|
||
|
||
@layer base {
|
||
* {
|
||
@apply border-border outline-ring/50;
|
||
}
|
||
html {
|
||
height: 100%;
|
||
-webkit-tap-highlight-color: color-mix(in oklab, var(--foreground) 20%, transparent);
|
||
@apply font-sans;
|
||
}
|
||
body {
|
||
@apply antialiased bg-background text-foreground;
|
||
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;
|
||
}
|
||
|
||
/* Small inline widgets keep their design size on touch devices —
|
||
forcing 44px here stretches checkboxes, chip menus, and icon buttons
|
||
that live inside dense rows (sidebar headers, issue rows, filter
|
||
popovers). The surrounding row provides the touch area. */
|
||
[data-slot="toggle"],
|
||
[data-slot="checkbox"],
|
||
[data-slot="icon-button"],
|
||
[data-size="xs"],
|
||
[data-size="icon-xs"],
|
||
[data-size="icon-sm"],
|
||
input[type="checkbox"],
|
||
input[type="radio"],
|
||
/* Auto-resizing title fields are vertically centered inside their own bar,
|
||
which already provides the touch area; the 44px floor would top-align the
|
||
single line of text and push it too high (notably on mobile Safari). */
|
||
textarea[data-autosize-title] {
|
||
min-height: 0;
|
||
}
|
||
}
|
||
|
||
/* Dark mode scrollbars */
|
||
.dark {
|
||
color-scheme: dark;
|
||
}
|
||
|
||
.dark *::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
|
||
.dark *::-webkit-scrollbar-track {
|
||
background: oklch(0.205 0 0);
|
||
}
|
||
|
||
.dark *::-webkit-scrollbar-thumb {
|
||
background: oklch(0.4 0 0);
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.dark *::-webkit-scrollbar-thumb:hover {
|
||
background: oklch(0.5 0 0);
|
||
}
|
||
|
||
/* Auto-hide scrollbar: thin, stable gutter with the thumb visible only on hover */
|
||
.scrollbar-auto-hide {
|
||
scrollbar-gutter: stable;
|
||
scrollbar-width: thin;
|
||
scrollbar-color: transparent transparent;
|
||
}
|
||
|
||
.scrollbar-auto-hide::-webkit-scrollbar {
|
||
width: 8px !important;
|
||
height: 8px !important;
|
||
background: transparent !important;
|
||
}
|
||
.scrollbar-auto-hide::-webkit-scrollbar-track {
|
||
background: transparent !important;
|
||
}
|
||
.scrollbar-auto-hide::-webkit-scrollbar-thumb {
|
||
background: transparent !important;
|
||
}
|
||
|
||
/* The task-chat shell owns its desktop scroll viewport. Release Layout's
|
||
otherwise-useful reserved main scrollbar gutter so that viewport can meet
|
||
the properties-pane border instead of stopping one scrollbar-width early. */
|
||
#main-content:has([data-task-chat-shell]) {
|
||
scrollbar-gutter: auto;
|
||
}
|
||
/* Light mode scrollbar on hover */
|
||
.scrollbar-auto-hide:hover {
|
||
scrollbar-color: oklch(0.7 0 0) transparent;
|
||
}
|
||
.scrollbar-auto-hide:hover::-webkit-scrollbar-track {
|
||
background: transparent !important;
|
||
}
|
||
.scrollbar-auto-hide:hover::-webkit-scrollbar-thumb {
|
||
background: oklch(0.7 0 0) !important;
|
||
border-radius: 999px !important;
|
||
}
|
||
.scrollbar-auto-hide:hover::-webkit-scrollbar-thumb:hover {
|
||
background: oklch(0.6 0 0) !important;
|
||
}
|
||
/* Dark mode scrollbar on hover */
|
||
.dark .scrollbar-auto-hide:hover {
|
||
scrollbar-color: oklch(0.4 0 0) transparent;
|
||
}
|
||
.dark .scrollbar-auto-hide:hover::-webkit-scrollbar-track {
|
||
background: transparent !important;
|
||
}
|
||
.dark .scrollbar-auto-hide:hover::-webkit-scrollbar-thumb {
|
||
background: oklch(0.4 0 0) !important;
|
||
}
|
||
.dark .scrollbar-auto-hide:hover::-webkit-scrollbar-thumb:hover {
|
||
background: oklch(0.5 0 0) !important;
|
||
}
|
||
|
||
/* Typing indicator — three bouncing dots, used inside an agent chat bubble */
|
||
.typing-dots {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
padding: 4px 0;
|
||
}
|
||
.typing-dots span {
|
||
width: 5px;
|
||
height: 5px;
|
||
border-radius: 999px;
|
||
background: var(--muted-foreground);
|
||
animation: typing-bounce 1.2s ease-in-out infinite;
|
||
}
|
||
.typing-dots span:nth-child(2) {
|
||
animation-delay: 0.15s;
|
||
}
|
||
.typing-dots span:nth-child(3) {
|
||
animation-delay: 0.3s;
|
||
}
|
||
@keyframes typing-bounce {
|
||
0%,
|
||
60%,
|
||
100% {
|
||
transform: translateY(0);
|
||
opacity: 0.4;
|
||
}
|
||
30% {
|
||
transform: translateY(-3px);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.typing-dots span {
|
||
animation: none;
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
|
||
/* Task Chat Redesign motion tokens collapse to instant under reduced motion.
|
||
Zeroing the primitives cascades to every scoped token that references them;
|
||
the literal-valued scoped tokens (staggers, loops) are zeroed explicitly. */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
:root {
|
||
--motion-duration-instant: 0ms;
|
||
--motion-duration-fast: 0ms;
|
||
--motion-duration-base: 0ms;
|
||
--motion-duration-slow: 0ms;
|
||
--motion-duration-deliberate: 0ms;
|
||
--motion-cot-line-stagger: 0ms;
|
||
--motion-approval-pulse: 0ms;
|
||
--motion-plan-entry-stagger: 0ms;
|
||
--motion-streaming-cursor-blink: 0ms;
|
||
--motion-turn-fold: 0ms;
|
||
--motion-line-scroll: 0ms;
|
||
/* --motion-interstitial-dwell is deliberately NOT zeroed: it is a pacing
|
||
hold, not a movement — zeroing it would make the interstitial line churn
|
||
faster under reduced motion. Swaps themselves snap (line-scroll: 0). */
|
||
--motion-scroll-pill-enter: 0ms;
|
||
--motion-scroll-pill-exit: 0ms;
|
||
--motion-pane-glide: 0ms;
|
||
}
|
||
}
|
||
|
||
/* ────────────────────────────────────────────────────────────────────────
|
||
Chat-style task thread animation utilities (default view; classic legacy
|
||
view sits behind enableClassicTaskInterface).
|
||
|
||
These classes are the ONLY place the redesigned thread's motion is applied;
|
||
every duration/easing is a var(--motion-*) reference (never a literal), so
|
||
(a) the no-hardcoded-timing gate passes and (b) the dev tweak panel retunes
|
||
them live by writing the tokens on :root. Keep timing here, in tokens — the
|
||
components only add class names.
|
||
──────────────────────────────────────────────────────────────────────── */
|
||
@keyframes tc-fade-rise {
|
||
from { opacity: 0; transform: translateY(4px); }
|
||
to { opacity: 1; transform: none; }
|
||
}
|
||
@keyframes tc-fade-in {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
@keyframes tc-status-in {
|
||
from { opacity: 0; transform: translateY(2px) scale(0.98); }
|
||
to { opacity: 1; transform: none; }
|
||
}
|
||
@keyframes tc-approval-pulse {
|
||
0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--primary) 0%, transparent); }
|
||
50% { box-shadow: 0 0 0 3px color-mix(in oklab, var(--primary) 18%, transparent); }
|
||
}
|
||
@keyframes tc-cursor-blink {
|
||
0%, 45% { opacity: 1; }
|
||
55%, 100% { opacity: 0; }
|
||
}
|
||
.tc-enter-bubble { animation: tc-fade-rise var(--motion-bubble-enter) var(--motion-ease-out-expo) both; }
|
||
.tc-enter-marker { animation: tc-fade-in var(--motion-marker-enter) var(--motion-ease-out) both; }
|
||
.tc-enter-tool { animation: tc-fade-rise var(--motion-tool-enter) var(--motion-ease-out-expo) both; }
|
||
.tc-enter-status { animation: tc-status-in var(--motion-status-enter) var(--motion-ease-out-expo) both; }
|
||
.tc-enter-cot-line { animation: tc-fade-rise var(--motion-duration-fast) var(--motion-ease-standard) both; }
|
||
.tc-notice-chevron { transition-duration: var(--motion-duration-fast); }
|
||
.tc-reveal-diff { animation: tc-fade-in var(--motion-diff-reveal) var(--motion-ease-standard) both; }
|
||
.tc-approval { animation: tc-approval-pulse var(--motion-approval-pulse) var(--motion-ease-standard) infinite; }
|
||
.tc-cursor { animation: tc-cursor-blink var(--motion-streaming-cursor-blink) step-end infinite; }
|
||
.tc-enter-plan-entry { animation: tc-fade-rise var(--motion-plan-check) var(--motion-ease-out-expo) both; }
|
||
|
||
/* ────────────────────────────────────────────────────────────────────────
|
||
Agent-bubble treatment explorations (PAP-501). Scoped to the TaskChatLab
|
||
stage via [data-bubble-variant]; the live thread never sets that attribute,
|
||
so these overrides remain lab-only comparisons. Feedback: the former
|
||
dark-mode agent card (oklch 0.24) read too light against the near-black page
|
||
for the bulk of the text. The production treatment now sits directly on
|
||
the page background; the card alternatives remain available for comparison.
|
||
──────────────────────────────────────────────────────────────────────── */
|
||
|
||
/* Former production treatment, retained as a direct before/after comparison
|
||
for the darker default. */
|
||
[data-bubble-variant="former"] { --bubble-agent: oklch(0.955 0 0); }
|
||
.dark [data-bubble-variant="former"] { --bubble-agent: oklch(0.24 0 0); }
|
||
|
||
/* B · Hairline flush — near-page fill + a 1px hairline for gentle definition
|
||
without any brightness lift. */
|
||
[data-bubble-variant="hairline"] { --bubble-agent: var(--background); }
|
||
[data-bubble-variant="hairline"] [data-testid="task-chat-agent-bubble"] {
|
||
border: 1px solid var(--border);
|
||
}
|
||
.dark [data-bubble-variant="hairline"] { --bubble-agent: oklch(0.17 0 0); }
|
||
.dark [data-bubble-variant="hairline"] [data-testid="task-chat-agent-bubble"] {
|
||
border-color: oklch(1 0 0 / 8%);
|
||
}
|
||
|
||
/* Card variants restore the shared card geometry that production no longer
|
||
applies to agent prose. */
|
||
[data-bubble-variant="former"] [data-testid="task-chat-agent-bubble"],
|
||
[data-bubble-variant="darker"] [data-testid="task-chat-agent-bubble"],
|
||
[data-bubble-variant="hairline"] [data-testid="task-chat-agent-bubble"] {
|
||
background: var(--bubble-agent);
|
||
border-radius: var(--radius-2xl);
|
||
padding-left: var(--bubble-agent-card-padding-inline);
|
||
padding-right: var(--bubble-agent-card-padding-inline);
|
||
max-width: var(--pct-85);
|
||
}
|
||
/* Live-line viewport (PAP-361): exactly one line-height tall, clipping the
|
||
wrapped interstitial block. On wrap, the inner block translates up whole
|
||
line-heights (set inline as translateY(-(n−1)·1lh)) so the completed line
|
||
slides out the top — transform-only, same motion grammar as tool rows
|
||
animating in. */
|
||
.tc-line-scroll { display: block; height: 1lh; overflow: hidden; }
|
||
.tc-line-scroll-inner { transition: transform var(--motion-line-scroll) var(--motion-ease-standard); will-change: transform; }
|
||
|
||
/* Scroll-to-latest pill (stock shadcn MessageScrollerButton motion, tokenized).
|
||
The pill is centered with translateX(-50%), so the keyframes carry the X
|
||
offset through the whole transform. */
|
||
@keyframes tc-pill-in {
|
||
from { opacity: 0; transform: translate(-50%, 8px) scale(0.9); }
|
||
to { opacity: 1; transform: translate(-50%, 0) scale(1); }
|
||
}
|
||
@keyframes tc-pill-out {
|
||
from { opacity: 1; transform: translate(-50%, 0) scale(1); }
|
||
to { opacity: 0; transform: translate(-50%, 8px) scale(0.9); }
|
||
}
|
||
.tc-scroll-pill-in { animation: tc-pill-in var(--motion-scroll-pill-enter) var(--motion-ease-scroll-pill-in) both; }
|
||
.tc-scroll-pill-out { animation: tc-pill-out var(--motion-scroll-pill-exit) var(--motion-ease-scroll-pill-out) both; }
|
||
|
||
/* Finished-turn fold: grid-rows 1fr→0fr animates height without measuring;
|
||
the single grid child must be overflow-hidden for 0fr to clip. */
|
||
.tc-turn-fold {
|
||
display: grid;
|
||
grid-template-rows: 1fr;
|
||
transition: grid-template-rows var(--motion-turn-fold) var(--motion-ease-standard),
|
||
opacity var(--motion-turn-fold) var(--motion-ease-standard);
|
||
}
|
||
.tc-turn-fold[data-folded="true"] { grid-template-rows: 0fr; opacity: 0; }
|
||
.tc-turn-fold > * { overflow: hidden; min-height: 0; }
|
||
|
||
/* Settled-turn metadata remains available on hover/focus and while expanded,
|
||
but its collapsed grid track consumes no width at rest. */
|
||
.tc-turn-metrics {
|
||
display: grid;
|
||
grid-template-columns: 0fr;
|
||
opacity: 0;
|
||
transition: grid-template-columns var(--motion-turn-meta) var(--motion-ease-standard),
|
||
opacity var(--motion-turn-meta) var(--motion-ease-standard);
|
||
}
|
||
[data-testid="task-chat-turn-summary"]:hover .tc-turn-metrics,
|
||
[data-testid="task-chat-turn-summary"]:focus-visible .tc-turn-metrics,
|
||
.tc-turn-metrics[data-visible="true"] {
|
||
grid-template-columns: 1fr;
|
||
opacity: 1;
|
||
}
|
||
|
||
/* Properties-pane maximize/restore glide (left animates between docked and
|
||
sidebar-flush while the pane is position:fixed). */
|
||
.tc-pane-glide { transition: left var(--motion-pane-glide) var(--motion-ease-standard); }
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.tc-enter-bubble,
|
||
.tc-enter-marker,
|
||
.tc-enter-tool,
|
||
.tc-enter-status,
|
||
.tc-enter-cot-line,
|
||
.tc-reveal-diff,
|
||
.tc-scroll-pill-in,
|
||
.tc-scroll-pill-out,
|
||
.tc-enter-plan-entry { animation: none; }
|
||
.tc-turn-fold,
|
||
.tc-turn-metrics,
|
||
.tc-line-scroll-inner,
|
||
.tc-pane-glide { transition: none; }
|
||
/* The pill keyframes carry the X-centering; with animation:none restore it. */
|
||
.tc-scroll-pill-in,
|
||
.tc-scroll-pill-out { transform: translate(-50%, 0); }
|
||
.tc-approval { animation: none; box-shadow: 0 0 0 2px color-mix(in oklab, var(--primary) 18%, transparent); }
|
||
.tc-cursor { animation: none; opacity: 1; }
|
||
}
|
||
|
||
/* Expandable dialog transition for max-width changes */
|
||
[data-slot="dialog-content"] {
|
||
transition: max-width 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
Motion tokens
|
||
---------------------------------------------------------------------------
|
||
The first named motion values in the system. Durations and easings were
|
||
previously written inline at each call site; these give the "snappy, eases
|
||
in and out" behaviour one definition so surfaces stay in step.
|
||
|
||
Exit is deliberately shorter than enter: a thing appearing wants to be
|
||
followed, a thing leaving just needs to get out of the way.
|
||
|
||
The enter curve is the same cubic-bezier the dialog max-width transition
|
||
already used — decelerating hard at the end, which is what reads as "snappy"
|
||
rather than "slow start". Consumers: the decision-card disclosure and the
|
||
task quicklook, both below.
|
||
--------------------------------------------------------------------------- */
|
||
:root {
|
||
--motion-duration-enter: 160ms;
|
||
--motion-duration-exit: 110ms;
|
||
--motion-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
||
--motion-ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||
|
||
/* A crossfading pair must share one duration and one curve. Two elements
|
||
swapping places both change height, and the container shows the SUM. Give
|
||
them different timing — the outgoing on a 110ms ease-in against the
|
||
incoming on a 160ms ease-out — and that sum stops being monotonic: the
|
||
container bulges or dips mid-swap, which reads as a lurch even though each
|
||
half is individually smooth. Run both off the same clock and the same
|
||
curve and the sum collapses to a clean interpolation between the two
|
||
states, because at every moment progress is identical on both sides. */
|
||
--motion-duration-swap: 150ms;
|
||
}
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
Decision-card disclosure (See more / See less)
|
||
---------------------------------------------------------------------------
|
||
Radix Collapsible measures the panel and publishes its height, so the card
|
||
can grow and shrink to a real number instead of snapping. The content
|
||
unmounts once the exit finishes, so an expanded row's resolver is not left
|
||
running behind a collapsed card.
|
||
--------------------------------------------------------------------------- */
|
||
@keyframes decision-disclosure-open {
|
||
from {
|
||
height: 0;
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
height: var(--radix-collapsible-content-height);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
@keyframes decision-disclosure-close {
|
||
from {
|
||
height: var(--radix-collapsible-content-height);
|
||
opacity: 1;
|
||
}
|
||
to {
|
||
height: 0;
|
||
opacity: 0;
|
||
}
|
||
}
|
||
[data-slot="collapsible-content"][data-decision-disclosure] {
|
||
overflow: hidden;
|
||
}
|
||
[data-slot="collapsible-content"][data-decision-disclosure][data-state="open"] {
|
||
animation: decision-disclosure-open var(--motion-duration-swap) var(--motion-ease-out);
|
||
}
|
||
[data-slot="collapsible-content"][data-decision-disclosure][data-state="closed"] {
|
||
/* Same duration and same curve as the open side — see --motion-duration-swap.
|
||
The two run against each other, so matched timing is what keeps the card's
|
||
height a straight interpolation instead of a bulge. */
|
||
animation: decision-disclosure-close var(--motion-duration-swap) var(--motion-ease-out);
|
||
}
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
Task quicklook: a small scale-up out of the trigger, not a fade in place.
|
||
---------------------------------------------------------------------------
|
||
The shadcn PopoverContent class string carries `animate-in`, `zoom-in-95`
|
||
and friends, but those utilities come from the tailwindcss-animate plugin,
|
||
which this project does not install — there is no `enter`/`exit` keyframe in
|
||
the build, so they are inert. Rather than take on that dependency for one
|
||
surface (it would newly animate every dialog, dropdown and tooltip in the
|
||
app), the quicklook defines its own motion here.
|
||
|
||
The scale is deliberately shallow. `--radix-popover-content-transform-origin`
|
||
pins the origin to the corner nearest the trigger, so the card reads as
|
||
growing out of the task key that opened it rather than swelling in place.
|
||
--------------------------------------------------------------------------- */
|
||
@keyframes quicklook-open {
|
||
from {
|
||
opacity: 0;
|
||
transform: scale(0.96);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: scale(1);
|
||
}
|
||
}
|
||
@keyframes quicklook-close {
|
||
from {
|
||
opacity: 1;
|
||
transform: scale(1);
|
||
}
|
||
to {
|
||
opacity: 0;
|
||
transform: scale(0.96);
|
||
}
|
||
}
|
||
[data-slot="popover-content"][data-quicklook][data-state="open"] {
|
||
animation: quicklook-open var(--motion-duration-enter) var(--motion-ease-out);
|
||
}
|
||
[data-slot="popover-content"][data-quicklook][data-state="closed"] {
|
||
animation: quicklook-close var(--motion-duration-exit) var(--motion-ease-in);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
[data-slot="collapsible-content"][data-decision-disclosure][data-state="open"],
|
||
[data-slot="collapsible-content"][data-decision-disclosure][data-state="closed"],
|
||
[data-slot="popover-content"][data-quicklook][data-state="open"],
|
||
[data-slot="popover-content"][data-quicklook][data-state="closed"] {
|
||
animation: none;
|
||
}
|
||
}
|
||
|
||
/* 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;
|
||
}
|
||
}
|
||
|
||
/* Chain-of-thought reasoning line ticker animations.
|
||
Pure translate, no opacity — the overflow-hidden container clips.
|
||
Both keyframes share the same easing so the two spans move in lockstep. */
|
||
@keyframes cot-line-slide-in {
|
||
from { transform: translateY(100%); }
|
||
to { transform: translateY(0); }
|
||
}
|
||
|
||
@keyframes cot-line-slide-out {
|
||
from { transform: translateY(0); }
|
||
to { transform: translateY(-100%); }
|
||
}
|
||
|
||
.cot-line-enter {
|
||
animation: cot-line-slide-in 300ms cubic-bezier(0.4, 0, 0.2, 1) both;
|
||
}
|
||
|
||
.cot-line-exit {
|
||
animation: cot-line-slide-out 300ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.cot-line-enter,
|
||
.cot-line-exit {
|
||
animation: none;
|
||
}
|
||
}
|
||
|
||
/* RunTranscriptView live-tail motion (PAP-461, A3). The experimental chat-style
|
||
view streams its live output through RunTranscriptView; these token-driven
|
||
classes replace the raw Tailwind `animate-in … duration-300` / `animate-ping`
|
||
the tail used so its streaming affordances honor --motion-* retuning AND the
|
||
reduced-motion override below, exactly like the rest of the redesign. */
|
||
@keyframes tc-stream-block-in {
|
||
from { opacity: 0; transform: translateY(0.25rem); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.tc-stream-block-enter {
|
||
animation: tc-stream-block-in var(--motion-tool-enter) var(--motion-ease-standard) both;
|
||
}
|
||
|
||
@keyframes tc-live-ping {
|
||
75%, 100% { transform: scale(2); opacity: 0; }
|
||
}
|
||
|
||
.tc-live-ping {
|
||
animation: tc-live-ping var(--motion-approval-pulse) var(--motion-ease-standard) infinite;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.tc-stream-block-enter,
|
||
.tc-live-ping {
|
||
animation: none;
|
||
}
|
||
}
|
||
|
||
/* Shimmer text effect for active "Working" state — Cursor-style sweep */
|
||
@keyframes shimmer-text-slide {
|
||
0% { background-position: 100% center; }
|
||
60% { background-position: 0% center; }
|
||
100% { background-position: 0% center; }
|
||
}
|
||
|
||
.shimmer-text {
|
||
--shimmer-base: var(--foreground);
|
||
--shimmer-highlight: color-mix(in oklch, var(--foreground) 35%, transparent);
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--shimmer-base) 0%,
|
||
var(--shimmer-base) 40%,
|
||
var(--shimmer-highlight) 50%,
|
||
var(--shimmer-base) 60%,
|
||
var(--shimmer-base) 100%
|
||
);
|
||
background-size: 200% 100%;
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
animation: shimmer-text-slide 2.5s linear infinite;
|
||
}
|
||
|
||
.paperclip-thinking-icon {
|
||
transform-origin: 50% 50%;
|
||
}
|
||
|
||
@keyframes paperclip-thinking-draw {
|
||
0% {
|
||
stroke-dasharray: 0 85.717;
|
||
stroke-dashoffset: -85.717;
|
||
opacity: 1;
|
||
animation-timing-function: cubic-bezier(0.455, 0.03, 0.515, 0.955);
|
||
}
|
||
39.0625% {
|
||
stroke-dasharray: 85.717 85.717;
|
||
stroke-dashoffset: 0;
|
||
opacity: 1;
|
||
animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
||
}
|
||
78.125% {
|
||
stroke-dasharray: 0 85.717;
|
||
stroke-dashoffset: 0;
|
||
opacity: 1;
|
||
}
|
||
78.225% {
|
||
opacity: 0;
|
||
}
|
||
100% {
|
||
stroke-dasharray: 0 85.717;
|
||
stroke-dashoffset: 0;
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
.paperclip-thinking-icon-path {
|
||
animation: paperclip-thinking-draw 1s linear infinite;
|
||
}
|
||
|
||
/* Muted variant (task-chat v7 activity rows): the sweep runs over the
|
||
muted-foreground tier so live "Thinking…"/"Working…" labels stay subordinate
|
||
to real content. */
|
||
.shimmer-text-muted {
|
||
--shimmer-base: var(--muted-foreground);
|
||
--shimmer-highlight: color-mix(in oklch, var(--muted-foreground) 30%, transparent);
|
||
}
|
||
|
||
/* Utilities expected by shadcn base components (ui/attachment.tsx). Declared
|
||
with @utility so variant forms (e.g. group-data-[state=uploading]:shimmer)
|
||
compile under Tailwind v4. */
|
||
@utility shimmer {
|
||
--shimmer-base: var(--foreground);
|
||
--shimmer-highlight: color-mix(in oklch, var(--foreground) 35%, transparent);
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--shimmer-base) 0%,
|
||
var(--shimmer-base) 40%,
|
||
var(--shimmer-highlight) 50%,
|
||
var(--shimmer-base) 60%,
|
||
var(--shimmer-base) 100%
|
||
);
|
||
background-size: 200% 100%;
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
animation: shimmer-text-slide 2.5s linear infinite;
|
||
}
|
||
|
||
@utility scrollbar-none {
|
||
scrollbar-width: none;
|
||
&::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
}
|
||
|
||
@utility scroll-fade-x {
|
||
mask-image: linear-gradient(
|
||
to right,
|
||
transparent,
|
||
black 12px,
|
||
black calc(100% - 12px),
|
||
transparent
|
||
);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.shimmer-text {
|
||
animation: none;
|
||
-webkit-text-fill-color: unset;
|
||
background: none;
|
||
}
|
||
|
||
.paperclip-thinking-icon-path {
|
||
animation: none;
|
||
opacity: 1;
|
||
stroke-dasharray: 85.717 85.717;
|
||
stroke-dashoffset: 0;
|
||
}
|
||
}
|
||
|
||
/* Agent heartbeat capsule motion (PAP-75).
|
||
`hb-pulse` marks a running agent (live); `hb-blink` marks a broken agent
|
||
(error). The blink alternates the fill between brand red and the page
|
||
background so the capsule reads as a faltering heartbeat. */
|
||
@keyframes hb-pulse {
|
||
0%, 100% { opacity: 0.4; transform: scale(0.85); }
|
||
50% { opacity: 1; transform: scale(1); }
|
||
}
|
||
|
||
@keyframes hb-blink {
|
||
0%, 49.9% { background-color: #DC2626; }
|
||
50%, 100% { background-color: var(--background); }
|
||
}
|
||
|
||
.hb-pulse {
|
||
animation: hb-pulse 1.6s ease-in-out infinite;
|
||
}
|
||
|
||
.hb-blink {
|
||
animation: hb-blink 1.2s step-end infinite;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.hb-pulse,
|
||
.hb-blink {
|
||
animation: none;
|
||
}
|
||
}
|
||
|
||
/* Agent capsule motif (PAP-119) — "the capsule is the agent".
|
||
Three states realized in the AgentCapsule component:
|
||
- slot: dashed outline gently pulsing (an empty agent slot)
|
||
- configured: solid stroke (named/model picked, not yet live)
|
||
- online: brand agent-gradient liquid rises to fill + green online-pulse
|
||
prefers-reduced-motion skips the liquid rise + pulses and renders the
|
||
final state. */
|
||
@keyframes agent-cap-slot-pulse {
|
||
0%, 100% { opacity: 0.5; }
|
||
50% { opacity: 1; }
|
||
}
|
||
|
||
@keyframes agent-cap-rise {
|
||
0% { height: 0; }
|
||
100% { height: 100%; }
|
||
}
|
||
|
||
@keyframes agent-cap-online-pulse {
|
||
0%, 100% {
|
||
box-shadow: 0 0 0 0 color-mix(in oklab, #22c55e 0%, transparent);
|
||
transform: scale(1);
|
||
}
|
||
50% {
|
||
box-shadow: 0 0 0 6px color-mix(in oklab, #22c55e 18%, transparent);
|
||
transform: scale(1.03);
|
||
}
|
||
}
|
||
|
||
.agent-cap-slot {
|
||
animation: agent-cap-slot-pulse 1.6s ease-in-out infinite;
|
||
}
|
||
|
||
.agent-cap-liquid {
|
||
animation: agent-cap-rise 1.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||
}
|
||
|
||
.agent-cap-online {
|
||
animation: agent-cap-online-pulse 1.8s ease-in-out infinite;
|
||
}
|
||
|
||
/* Blue online-glow variant (PAP-125) — the Option 4 wizard's review step.
|
||
Same breathing ring as the green pulse, recoloured to brand blue (#2563eb). */
|
||
@keyframes agent-cap-online-pulse-blue {
|
||
0%, 100% {
|
||
box-shadow: 0 0 0 0 color-mix(in oklab, #2563eb 0%, transparent);
|
||
transform: scale(1);
|
||
}
|
||
50% {
|
||
box-shadow: 0 0 0 6px color-mix(in oklab, #2563eb 22%, transparent);
|
||
transform: scale(1.03);
|
||
}
|
||
}
|
||
|
||
.agent-cap-online-blue {
|
||
animation: agent-cap-online-pulse-blue 1.8s ease-in-out infinite;
|
||
}
|
||
|
||
/* Cross-fade the stacked dashed/solid border layers as the capsule evolves
|
||
in place (border-style itself is not animatable). */
|
||
.agent-cap-layer {
|
||
transition: opacity 0.5s ease;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.agent-cap-slot,
|
||
.agent-cap-online,
|
||
.agent-cap-online-blue {
|
||
animation: none;
|
||
}
|
||
.agent-cap-layer {
|
||
transition: none;
|
||
}
|
||
.agent-cap-liquid {
|
||
animation: none;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
/* 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: 1rem;
|
||
line-height: 1.5;
|
||
color: var(--foreground);
|
||
}
|
||
|
||
@media (min-width: 768px) {
|
||
.paperclip-mdxeditor-scope,
|
||
.paperclip-mdxeditor {
|
||
font-size: 0.875rem;
|
||
}
|
||
}
|
||
|
||
.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: inherit;
|
||
line-height: 1.5;
|
||
color: var(--muted-foreground);
|
||
}
|
||
|
||
/* MDXEditor defaults placeholders to a single clipped line. The task-chat
|
||
composer uses longer, assignee-aware copy, so keep it inside the editor by
|
||
giving the absolutely positioned placeholder a wrapping inline size. */
|
||
.paperclip-task-chat-composer .paperclip-mdxeditor [class*="_placeholder_"] {
|
||
display: block;
|
||
width: 100%;
|
||
overflow-wrap: anywhere;
|
||
white-space: normal;
|
||
}
|
||
|
||
.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%, #0969da 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: color-mix(in oklab, var(--foreground) 80%, #58a6ff 20%);
|
||
}
|
||
|
||
.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 0.625rem;
|
||
border: 1px solid var(--border);
|
||
border-radius: 999px;
|
||
font-size: 0.75rem;
|
||
line-height: 1.25;
|
||
text-decoration: none;
|
||
vertical-align: middle;
|
||
position: relative;
|
||
top: -1px;
|
||
white-space: nowrap;
|
||
user-select: none;
|
||
}
|
||
|
||
/* Strip the MDXEditor's default inline-code styling from the text inside chips
|
||
(the link label otherwise picks up a monospace font + gray tint). */
|
||
.paperclip-mdxeditor-content a.paperclip-mention-chip code,
|
||
.paperclip-mdxeditor-content a.paperclip-project-mention-chip code {
|
||
font-family: inherit;
|
||
background: none;
|
||
color: inherit;
|
||
padding: 0;
|
||
}
|
||
|
||
.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: var(--radius-lg);
|
||
background: var(--muted);
|
||
color: var(--foreground);
|
||
overflow-x: auto;
|
||
}
|
||
|
||
/* Dark theme for CodeMirror code blocks inside the MDXEditor.
|
||
Overrides the default cm6-theme-basic-light that MDXEditor bundles. */
|
||
.paperclip-mdxeditor .cm-editor {
|
||
background-color: #1e1e2e !important;
|
||
color: #cdd6f4 !important;
|
||
font-size: 1em;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-gutters {
|
||
background-color: #181825 !important;
|
||
color: #585b70 !important;
|
||
border-right: 1px solid #313244 !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-activeLineGutter {
|
||
background-color: #1e1e2e !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-activeLine {
|
||
background-color: color-mix(in oklab, #cdd6f4 5%, transparent) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-cursor,
|
||
.paperclip-mdxeditor .cm-dropCursor {
|
||
border-left-color: #cdd6f4 !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-selectionBackground {
|
||
background-color: color-mix(in oklab, #89b4fa 25%, transparent) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-focused .cm-selectionBackground {
|
||
background-color: color-mix(in oklab, #89b4fa 30%, transparent) !important;
|
||
}
|
||
|
||
.paperclip-mdxeditor .cm-content {
|
||
caret-color: #cdd6f4;
|
||
}
|
||
|
||
/* 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: #313244;
|
||
color: #cdd6f4;
|
||
border-color: #45475a;
|
||
}
|
||
|
||
.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).
|
||
Theme-aware: the block rides --muted/--foreground/--border so it follows
|
||
light and dark instead of pinning the old Catppuccin #1e1e2e/#cdd6f4 in
|
||
both modes. Override prose CSS variables so prose-invert can't revert to
|
||
defaults. */
|
||
.paperclip-markdown {
|
||
--tw-prose-pre-bg: var(--muted);
|
||
--tw-prose-pre-code: var(--foreground);
|
||
--tw-prose-invert-pre-bg: var(--muted);
|
||
--tw-prose-invert-pre-code: var(--foreground);
|
||
}
|
||
|
||
.paperclip-markdown pre {
|
||
border: 1px solid var(--border) !important;
|
||
border-radius: var(--radius-lg) !important;
|
||
background-color: var(--muted) !important;
|
||
color: var(--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;
|
||
}
|
||
|
||
/* Actions for fenced and indented preformatted markdown blocks */
|
||
.paperclip-markdown-codeblock {
|
||
position: relative;
|
||
}
|
||
|
||
.paperclip-markdown-codeblock-actions {
|
||
position: absolute;
|
||
top: 0.4rem;
|
||
right: 0.4rem;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.25rem;
|
||
opacity: 0;
|
||
transition: opacity 0.12s ease;
|
||
}
|
||
|
||
.paperclip-markdown-codeblock-action {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.25rem;
|
||
min-height: 1.55rem;
|
||
padding: 0.2rem 0.4rem;
|
||
border-radius: calc(var(--radius) - 4px);
|
||
border: 1px solid color-mix(in oklab, var(--foreground) 14%, transparent);
|
||
background-color: color-mix(in oklab, var(--muted) 92%, var(--background) 8%);
|
||
color: var(--muted-foreground);
|
||
font-size: 0.7rem;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
|
||
}
|
||
|
||
.paperclip-markdown-codeblock:hover .paperclip-markdown-codeblock-actions,
|
||
.paperclip-markdown-codeblock-actions:focus-within,
|
||
.paperclip-markdown-codeblock-actions[data-active] {
|
||
opacity: 1;
|
||
}
|
||
|
||
.paperclip-markdown-codeblock-action:hover {
|
||
background-color: var(--accent);
|
||
color: var(--accent-foreground);
|
||
}
|
||
|
||
.paperclip-markdown-codeblock-action[data-active],
|
||
.paperclip-markdown-codeblock-action[data-copied] {
|
||
border-color: color-mix(in oklab, var(--primary) 38%, transparent);
|
||
color: var(--primary);
|
||
}
|
||
|
||
.paperclip-markdown-codeblock-action[data-failed] {
|
||
color: var(--destructive);
|
||
}
|
||
|
||
.paperclip-markdown-codeblock-action-label {
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 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: #ffffff0f;
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent :not(pre) > code {
|
||
background-color: color-mix(in oklab, currentColor 24%, transparent);
|
||
color: currentColor;
|
||
}
|
||
|
||
.paperclip-markdown {
|
||
color: var(--foreground);
|
||
font-size: 0.9375rem;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent {
|
||
color: inherit;
|
||
--tw-prose-body: currentColor;
|
||
--tw-prose-headings: currentColor;
|
||
--tw-prose-lead: currentColor;
|
||
--tw-prose-links: currentColor;
|
||
--tw-prose-bold: currentColor;
|
||
--tw-prose-counters: currentColor;
|
||
--tw-prose-bullets: currentColor;
|
||
--tw-prose-hr: color-mix(in oklab, currentColor 24%, transparent);
|
||
--tw-prose-quotes: currentColor;
|
||
--tw-prose-quote-borders: color-mix(in oklab, currentColor 56%, transparent);
|
||
--tw-prose-captions: color-mix(in oklab, currentColor 84%, transparent);
|
||
--tw-prose-code: currentColor;
|
||
--tw-prose-th-borders: color-mix(in oklab, currentColor 34%, transparent);
|
||
--tw-prose-td-borders: color-mix(in oklab, currentColor 22%, transparent);
|
||
--tw-prose-invert-body: currentColor;
|
||
--tw-prose-invert-headings: currentColor;
|
||
--tw-prose-invert-lead: currentColor;
|
||
--tw-prose-invert-links: currentColor;
|
||
--tw-prose-invert-bold: currentColor;
|
||
--tw-prose-invert-counters: currentColor;
|
||
--tw-prose-invert-bullets: currentColor;
|
||
--tw-prose-invert-hr: color-mix(in oklab, currentColor 24%, transparent);
|
||
--tw-prose-invert-quotes: currentColor;
|
||
--tw-prose-invert-quote-borders: color-mix(in oklab, currentColor 56%, transparent);
|
||
--tw-prose-invert-captions: color-mix(in oklab, currentColor 84%, transparent);
|
||
--tw-prose-invert-code: currentColor;
|
||
--tw-prose-invert-th-borders: color-mix(in oklab, currentColor 34%, transparent);
|
||
--tw-prose-invert-td-borders: color-mix(in oklab, currentColor 22%, transparent);
|
||
}
|
||
|
||
.paperclip-markdown > :first-child {
|
||
margin-top: 0;
|
||
}
|
||
|
||
.paperclip-markdown > :last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.paperclip-markdown :where(p, ul, ol, blockquote, pre, .paperclip-markdown-table-scroll) {
|
||
margin-top: 0.7rem;
|
||
margin-bottom: 0.7rem;
|
||
}
|
||
|
||
.paperclip-markdown :where(ul, ol) {
|
||
padding-left: 1.5rem;
|
||
}
|
||
|
||
.paperclip-markdown ul {
|
||
list-style-type: disc;
|
||
}
|
||
|
||
.paperclip-markdown ol {
|
||
/* Enough inline start room to hold outside markers without clipped digits
|
||
when markdown lists sit flush against an overflow-constrained container. */
|
||
list-style-type: decimal;
|
||
padding-left: 2.5rem;
|
||
}
|
||
|
||
.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.paperclip-markdown-on-accent li::marker {
|
||
color: currentColor;
|
||
}
|
||
|
||
.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.paperclip-markdown-on-accent :where(h1, h2, h3, h4, strong, b) {
|
||
color: currentColor;
|
||
}
|
||
|
||
.paperclip-markdown :where(strong, b) {
|
||
color: var(--foreground);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.paperclip-markdown a {
|
||
color: color-mix(in oklab, var(--foreground) 76%, #0969da 24%);
|
||
text-decoration: underline;
|
||
text-underline-offset: 0.15em;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent :where(a, a:visited) {
|
||
color: currentColor;
|
||
text-decoration-color: color-mix(in oklab, currentColor 72%, transparent);
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent :where(a:hover, a:focus-visible) {
|
||
color: currentColor;
|
||
text-decoration-color: currentColor;
|
||
}
|
||
|
||
.paperclip-markdown a.paperclip-mention-chip {
|
||
text-decoration: none;
|
||
}
|
||
|
||
.paperclip-markdown a.paperclip-mention-chip[data-mention-kind="issue"] {
|
||
border-color: color-mix(in oklab, var(--foreground) 14%, var(--border) 86%);
|
||
background: color-mix(in oklab, var(--accent) 42%, transparent);
|
||
}
|
||
|
||
/* Inline issue references in markdown: no pill chrome, just a status icon
|
||
beside the link label — keeps the pair from splitting across lines. */
|
||
.paperclip-markdown-issue-ref {
|
||
display: inline;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* External object URL decorations follow the same pattern: the host renders
|
||
the icon prefix, the link text is left untouched (Postel's Law). */
|
||
.paperclip-markdown-external-ref {
|
||
display: inline;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.dark .paperclip-markdown a {
|
||
color: color-mix(in oklab, var(--foreground) 80%, #58a6ff 20%);
|
||
}
|
||
|
||
.dark .paperclip-markdown.paperclip-markdown-on-accent :where(a, a:visited) {
|
||
color: currentColor;
|
||
}
|
||
|
||
.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.paperclip-markdown-on-accent blockquote {
|
||
border-left-color: color-mix(in oklab, currentColor 56%, transparent);
|
||
color: color-mix(in oklab, currentColor 88%, transparent);
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent .paperclip-workspace-file-link {
|
||
border-color: color-mix(in oklab, currentColor 34%, transparent);
|
||
background-color: color-mix(in oklab, currentColor 16%, transparent);
|
||
color: currentColor;
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent .paperclip-workspace-file-link:hover {
|
||
background-color: color-mix(in oklab, currentColor 24%, transparent);
|
||
}
|
||
|
||
.paperclip-markdown.paperclip-markdown-on-accent :where(a.paperclip-mention-chip, a.paperclip-project-mention-chip) {
|
||
border-color: color-mix(in oklab, currentColor 34%, transparent) !important;
|
||
background: color-mix(in oklab, currentColor 16%, transparent) !important;
|
||
color: currentColor !important;
|
||
}
|
||
|
||
.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-scroll {
|
||
max-width: 100%;
|
||
overflow-x: auto;
|
||
overscroll-behavior-x: contain;
|
||
-webkit-overflow-scrolling: touch;
|
||
}
|
||
|
||
.paperclip-markdown-table-scroll:focus-visible {
|
||
outline: 2px solid var(--ring);
|
||
outline-offset: 2px;
|
||
}
|
||
|
||
.paperclip-markdown-table-scroll table {
|
||
width: max-content;
|
||
min-width: 100%;
|
||
margin: 0;
|
||
}
|
||
|
||
.paperclip-markdown-table-scroll :where(th, td) {
|
||
min-width: 8rem;
|
||
max-width: 18rem;
|
||
vertical-align: top;
|
||
}
|
||
|
||
.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;
|
||
}
|
||
|
||
/* Mention chips rendered inline in prose (MarkdownBody or inline anchors) */
|
||
a.paperclip-mention-chip,
|
||
a.paperclip-project-mention-chip,
|
||
span.paperclip-mention-chip,
|
||
span.paperclip-project-mention-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.25rem;
|
||
margin: 0 0.1rem;
|
||
padding: 0 0.625rem;
|
||
border: 1px solid var(--border);
|
||
border-radius: 999px;
|
||
font-size: 0.75rem;
|
||
line-height: 1.25;
|
||
text-decoration: none;
|
||
/* Center the pill on the surrounding x-height so it sits on the text line
|
||
instead of hanging below it. inline-flex baseline alignment is unreliable
|
||
across browsers, so use vertical-align: middle for a predictable result.
|
||
Nudge up 1px so it visually centers with the cap height of the text. */
|
||
vertical-align: middle;
|
||
position: relative;
|
||
top: -1px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* Touch target floor: WCAG 2.5.5 expects ≥24px on coarse pointers. The base
|
||
chip is 22px; bump it on touch viewports without disturbing inline metrics. */
|
||
@media (pointer: coarse) {
|
||
a.paperclip-mention-chip,
|
||
a.paperclip-project-mention-chip,
|
||
span.paperclip-mention-chip,
|
||
span.paperclip-project-mention-chip {
|
||
min-height: 24px;
|
||
}
|
||
}
|
||
|
||
/* External object pills: variant marker the host renders for known-resolved
|
||
external URLs. Inline status icon is rendered by ExternalObjectStatusIcon. */
|
||
a.paperclip-mention-chip[data-mention-kind="external-object"],
|
||
span.paperclip-mention-chip[data-mention-kind="external-object"] {
|
||
/* Inherit base chip styling; status colour comes from inline classes so the
|
||
host can vary tone per category without defining a CSS variant per state. */
|
||
}
|
||
|
||
/* When the identifier inside a chip is backtick-wrapped in markdown, strip the
|
||
inline-code monospace/gray styling so the pill label reads cleanly. */
|
||
.paperclip-markdown a.paperclip-mention-chip code,
|
||
.paperclip-markdown a.paperclip-project-mention-chip code,
|
||
.paperclip-markdown span.paperclip-mention-chip code,
|
||
.paperclip-markdown span.paperclip-project-mention-chip code {
|
||
font-family: inherit;
|
||
background: none;
|
||
color: inherit;
|
||
padding: 0;
|
||
font-size: inherit;
|
||
}
|
||
|
||
/* 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;
|
||
}
|
||
|
||
/* Status chip/fill helpers.
|
||
Each consumer sets a local `--sc` to the status' base hue (e.g.
|
||
`--sc: var(--status-task-in_progress)`); these rules derive the rendered
|
||
fill / text / border from it. `.status-chip` is the bordered chip (agent +
|
||
task chips); `.status-fill` a solid swatch (heartbeat capsule). Light mixes
|
||
the hue toward white for a soft fill; dark layers the hue at low alpha so it
|
||
reads on dark surfaces. A single hue covers both modes. */
|
||
.status-chip {
|
||
background-color: color-mix(in srgb, var(--sc) 15%, white);
|
||
color: color-mix(in srgb, var(--sc) 82%, black);
|
||
border-color: var(--sc);
|
||
}
|
||
.dark .status-chip {
|
||
background-color: color-mix(in srgb, var(--sc) 22%, transparent);
|
||
color: color-mix(in srgb, var(--sc) 80%, white);
|
||
border-color: color-mix(in srgb, var(--sc) 48%, transparent);
|
||
}
|
||
.status-fill {
|
||
background-color: var(--sc);
|
||
}
|
||
|
||
/* ── Extracted verbatim tokens (Phase 2, design/token-extraction) ── */
|
||
/* Batch 1/4: color literals only. Reused-from-existing-token sites (see
|
||
TOKEN-AUDIT.md section 1.1) are NOT duplicated here — they reference
|
||
--status-task-in_progress / --status-task-done directly at the call site.
|
||
|
||
Allowlist (sites intentionally left as hardcoded / functional literals,
|
||
NOT converted to tokens — each also carries an inline
|
||
`token-extraction: allowlisted` comment at the site):
|
||
- pages/CompanyEnvironments.tsx — xterm.js terminal theme config; functional JS values, third-party.
|
||
- pages/CompanySettings.tsx — <input type="color"> value; functional form control, not a rendered value. REMOVED: the company brand-color setting was deleted, so the control no longer exists.
|
||
- components/issue-properties/IssueProperties.tsx (newLabelColor) — color-picker seed persisted into label-create payload.
|
||
- pages/CompanySkills.tsx (DISCOVERY_ACCENTS) — persisted/compared skill.color JS data, not just rendered.
|
||
- components/IssueColumns.tsx (accentColor fallback) — also feeds pickTextColorForPillBg() contrast math.
|
||
- components/CompanyPatternIcon.tsx — canvas fillStyle computed at runtime from numeric props, not a static literal.
|
||
- pages/InviteUxLab.tsx (brandColor prop, x2) — demo/showcase-only prop feeding CompanyPatternIcon's hexToHue() color math, not a rendered CSS value. REMOVED: the brandColor prop was deleted, so the props no longer exist.
|
||
- components/FileViewerSheet.tsx — half-migrated var(--paperclip-code-highlight-*, fallback) pattern at the time of Batch 1; RESOLVED in Batch 4 via *-resolved wrapper tokens (see the Batch 4 MISC token block below) — no longer allowlisted.
|
||
*/
|
||
:root {
|
||
--hex-959596: #959596; /* Muted feed actor/verb/title text (ActivityFeed.tsx, FeedCard.tsx) — PRIOR-ART-flagged gap cluster, no existing token match. */
|
||
--hex-1d1d1d: #1d1d1d; /* OnboardingWizard.tsx dark decorative panel background, singleton. */
|
||
--hex-22d3ee: #22d3ee; /* OrgChart.tsx agent status dot — 'running' (independent palette from --status-agent-*, see TOKEN-AUDIT.md 1.2). */
|
||
--hex-4ade80: #4ade80; /* OrgChart.tsx agent status dot — 'active'. */
|
||
--hex-facc15: #facc15; /* OrgChart.tsx agent status dot — 'paused' / 'idle' (shared value). */
|
||
--hex-f87171: #f87171; /* OrgChart.tsx agent status dot — 'error'. */
|
||
--hex-a3a3a3: #a3a3a3; /* OrgChart.tsx agent status dot — 'terminated' + defaultDotColor fallback. */
|
||
--hex-ef4444: #ef4444; /* ActivityCharts.tsx — priority 'critical'; also the <0.5 success-rate bar tint and the run-activity 'failed' segment. (Chart STATUS hues re-pointed at --status-task-* in DECISION-SHEET.md B5; priority/success series stay independent.) */
|
||
--hex-f97316: #f97316; /* ActivityCharts.tsx — priority 'high'. */
|
||
--hex-eab308: #eab308; /* ActivityCharts.tsx — priority 'medium'; also the 0.5-0.8 success-rate bar tint. */
|
||
--hex-6b7280: #6b7280; /* ActivityCharts.tsx — priority 'low' + unknown-status statusColors fallback. */
|
||
--hex-10b981: #10b981; /* ActivityCharts.tsx — >=0.8 success-rate bar tint; also the run-activity 'succeeded' segment. */
|
||
--hex-737373: #737373; /* ActivityCharts.tsx — run activity 'other' segment tint. */
|
||
--project-none: #64748b; /* Semantic rename of --hex-64748b (DECISION-SHEET.md A3, value unchanged). 'No project assigned' muted-slate fallback (TOKEN-AUDIT.md 1.3) across Routines/MarkdownEditor/RoutineRunVariablesDialog/RoutineList/IssueColumns/editable-sections; also ActivityCharts.tsx status 'backlog'. */
|
||
--project-seed: #6366f1; /* Semantic rename of --hex-6366f1 (DECISION-SHEET.md A3, value unchanged). Project-color-fallback indigo seed default (ProjectDetail/PipelineSettings/IssueProperties/NewIssueDialog) — new-project-color-picker-seed family per TOKEN-AUDIT.md 1.3. */
|
||
--liveness-blue: #2563eb; /* DECISION-SHEET.md A6: IssueChatThread.tsx human-message 'liveness blue' bubble (PAP-95 rev 5). Same value as --status-task-in_progress by coincidence, decoupled on purpose so a future status-hue change doesn't drag the chat bubble along. */
|
||
--app-logo-tile-1: #ff4f00;
|
||
--app-logo-tile-2: #24292f;
|
||
--app-logo-tile-3: #4a154b;
|
||
--app-logo-tile-4: #0f172a;
|
||
--app-logo-tile-5: #5e6ad2;
|
||
--app-logo-tile-6: #1a73e8;
|
||
--app-logo-tile-7: #0f9d58;
|
||
--app-logo-tile-8: #ea4335;
|
||
--gradient-extract-1: linear-gradient(180deg,rgba(255,80,80,0.12),rgba(255,255,255,0.02)); /* Dashboard.tsx budget-alert card gradient. */
|
||
--gradient-extract-2: linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02)); /* Costs.tsx subtle white card gradient. */
|
||
--gradient-extract-3: radial-gradient(circle at top left,rgba(244,114,182,0.08),transparent 35%),radial-gradient(circle at bottom right,rgba(56,189,248,0.1),transparent 32%); /* AccountingModelCard.tsx decorative overlay. */
|
||
--gradient-extract-4: linear-gradient(180deg,rgba(255,70,70,0.10),rgba(255,255,255,0.02)); /* BudgetIncidentCard.tsx incident-card gradient. */
|
||
--gradient-extract-7: radial-gradient(circle at top right,rgba(255,255,255,0.22),transparent 34%),radial-gradient(circle at bottom left,rgba(255,255,255,0.08),transparent 36%); /* ProfileSettings.tsx:162 decorative overlay. */
|
||
}
|
||
|
||
/* ── Extracted verbatim TYPE tokens (Phase 2 Batch 2, design/token-extraction) ── */
|
||
/* Batch 2/4: font-size + letter-spacing + line-height literals, verbatim
|
||
(no normalizing — 9/10/11/12/13/14/15px and 0.08-0.24em all stay distinct;
|
||
the human scale-collapse decision comes later per DESIGN.md/TOKEN-AUDIT.md).
|
||
|
||
Allowlist (sites intentionally left as hardcoded / functional literals,
|
||
NOT converted to tokens — each also carries an inline
|
||
`token-extraction: allowlisted` comment at the site):
|
||
- pages/CompanyEnvironments.tsx (fontSize: 12) — xterm.js terminal theme
|
||
config; functional third-party numeric option, not a rendered CSS value.
|
||
Same allowlisted object as Batch 1's color entry for this file.
|
||
- pages/CompanySkills.tsx (fontSize: Math.round(size * 0.42)) — computed at
|
||
runtime from a prop; not a static literal, nothing to extract.
|
||
*/
|
||
:root {
|
||
/* ── Named type ladder (DECISION-SHEET.md B3, preset-tune session) ──
|
||
Collapses the 8 verbatim --fs-* font-size tokens and 9 --ls-*
|
||
letter-spacing tokens (extracted in Batch 2 above) into named steps.
|
||
Codemod: scripts/codemod-type-ladder.mjs. Mapping:
|
||
9px + 10px -> --text-nano (9 -> 10 bump per locked ladder)
|
||
11px + 0.7rem -> --text-micro (0.7rem = 11.2px -> 11px)
|
||
12px -> Tailwind `text-xs` class (12px exact match; scale
|
||
class preferred over a redundant token per DESIGN.md)
|
||
13px -> --text-compact (PRIOR-ART named this tier "sm 13",
|
||
but that collides with Tailwind text-sm = 14px,
|
||
hence "compact")
|
||
14px + 15px -> Tailwind `text-sm` class (14px; 15 -> 14)
|
||
Letter-spacing, nearest-step mapping:
|
||
0.08em, 0.1em -> --tracking-label
|
||
0.12em, 0.14em, 0.16em -> --tracking-eyebrow
|
||
0.18em, 0.2em, 0.22em, 0.24em -> --tracking-caps
|
||
NOTE: sites moved to text-xs/text-sm also pick up the Tailwind scale
|
||
line-height (text-(length:--x) set font-size only) — intentional,
|
||
reviewed on the post-preset contact sheet. */
|
||
--text-nano: 10px;
|
||
--text-micro: 11px;
|
||
--text-compact: 13px;
|
||
--tracking-label: 0.08em;
|
||
--tracking-eyebrow: 0.14em;
|
||
--tracking-caps: 0.2em;
|
||
}
|
||
|
||
/* ── Extracted verbatim SIZE/SPACING/RADIUS/SHADOW tokens (Phase 2 Batch 3, design/token-extraction) ── */
|
||
/* Batch 3/4: width/height/min/max, padding/margin/gap/inset/translate,
|
||
radius, ring/outline-width, and shadow literals, verbatim (no
|
||
normalizing — the human scale-collapse decision comes later per
|
||
DESIGN.md/TOKEN-AUDIT.md). --sz-* is ONE shared family across
|
||
w/h/p/m/gap/inset/translate so identical values dedupe regardless of
|
||
which property used them. --rad-* is likewise shared across
|
||
rounded, ring, and outline widths.
|
||
|
||
Allowlist (sites intentionally left as hardcoded / functional literals
|
||
or var()-only passthrough with no new token minted):
|
||
- components/ui/scroll-area.tsx (rounded-[inherit]) — CSS keyword, not a
|
||
literal value; nothing to extract.
|
||
- Bracket values that only wrap var(--radix-*-trigger-width/height) or
|
||
var(--new-issue-dialog-height) etc. are rewritten to the bare paren
|
||
form directly (e.g. w-(--radix-popover-trigger-width)) — these are
|
||
runtime library/component variables, not design values, so no new
|
||
--sz-* token is minted for them (see TOKEN-AUDIT.md extraction log
|
||
for the full site list).
|
||
*/
|
||
:root {
|
||
--sz-320px: 320px; /* Extracted from ui/src/components/ActiveAgentsPanel.tsx (h-[320px]). */
|
||
--sz-390px: 390px;
|
||
--sz-64px: 64px;
|
||
--sz-3px: 3px; /* Extracted from ui/src/components/ActivityCharts.tsx (gap-[3px]). */
|
||
--sz-calc-1: calc(100% - 1.5rem); /* Extracted from ui/src/components/ActivityFeed.tsx (w-[calc(100%-1.5rem)]). */
|
||
--sz-calc-2: calc(100% - 0.75rem); /* Extracted from ui/src/components/ActivityFeed.tsx (w-[calc(100%-0.75rem)]). */
|
||
--sz-16rem: 16rem; /* Extracted from ui/src/components/ActivityFeed.tsx (max-w-[16rem]). */
|
||
--sz-20rem: 20rem; /* AgentSkillReleasePicker.tsx release menu width cap. */
|
||
--sz-18px: 18px; /* Extracted from ui/src/components/ActivityFeed.tsx (p-[18px]). */
|
||
--sz-44px: 44px; /* Extracted from ui/src/components/AgentConfigForm.tsx (min-h-[44px]). */
|
||
--sz-88px: 88px; /* Extracted from ui/src/components/AgentConfigForm.tsx (min-h-[88px]). */
|
||
--sz-240px: 240px; /* Extracted from ui/src/components/AgentConfigForm.tsx (max-h-[240px]). */
|
||
--sz-10_5rem: 10.5rem; /* Extracted from ui/src/components/BlockedInboxView.tsx (w-[10.5rem]). */
|
||
--sz-150px: 150px; /* Extracted from ui/src/components/BlockedInboxView.tsx (w-[150px]). */
|
||
--sz-5_75rem: 5.75rem; /* Extracted from ui/src/components/BlockedInboxView.tsx (w-[5.75rem]). */
|
||
--sz-12rem: 12rem; /* Extracted from ui/src/components/BlockedInboxView.tsx (max-w-[12rem]). */
|
||
--sz-200px: 200px; /* Extracted from ui/src/components/ChatComposer.test.tsx (max-h-[200px]). */
|
||
--sz-22px: 22px; /* Extracted from ui/src/components/ChatComposer.test.tsx (max-h-[22px]). */
|
||
--sz-60px: 60px; /* Extracted from ui/src/components/CommentThread.tsx (min-h-[60px]). */
|
||
--sz-220px: 220px; /* Extracted from ui/src/components/CompanySwitcher.tsx (w-[220px]). */
|
||
--sz-88vh: 88vh; /* Extracted from ui/src/components/DocumentAnnotationPanel.tsx (max-h-[88vh]). */
|
||
--sz-80vh: 80vh; /* Extracted from ui/src/components/DocumentAnnotationPanel.tsx (max-h-[80vh]). */
|
||
--sz-360px: 360px; /* Extracted from ui/src/components/DocumentAnnotationPanel.tsx (w-[360px]). */
|
||
--sz-85vh: 85vh; /* Extracted from ui/src/components/DocumentDiffModal.tsx (max-h-[85vh]). */
|
||
--sz-6rem: 6rem; /* Extracted from ui/src/components/EntityRow.tsx (min-w-[6rem]). */
|
||
--sz-1px: 1px; /* Extracted from ui/src/components/EntityRow.tsx (top-[1px]). */
|
||
--sz-100px: 100px; /* Extracted from ui/src/components/ExecutionParticipantPicker.tsx (max-w-[100px]). */
|
||
--sz-calc-3: min(840px,calc(100dvh - 2rem)); /* Extracted from ui/src/components/FileViewerSheet.tsx (h-[min(840px,calc(100dvh-2rem))]). */
|
||
--sz-calc-4: calc(100vw - 2rem); /* Extracted from ui/src/components/FileViewerSheet.tsx (w-[calc(100vw-2rem)]). */
|
||
--sz-calc-5: min(1280px,calc(100vw - 2rem)); /* Extracted from ui/src/components/FileViewerSheet.tsx (max-w-[min(1280px,calc(100vw-2rem))]). */
|
||
--sz-94vw: 94vw; /* Extracted from ui/src/components/FileViewerSheet.tsx (w-[94vw]). */
|
||
--sz-1280px: 1280px; /* Extracted from ui/src/components/FileViewerSheet.tsx (max-w-[1280px]). */
|
||
--sz-60vh: 60vh; /* Extracted from ui/src/components/FrontDoor.tsx (min-h-[60vh]). */
|
||
--sz-52vh: 52vh;
|
||
--sz-40rem: 40rem;
|
||
--sz-44rem: 44rem;
|
||
--sz-30pct: 30%;
|
||
--sz-24pct: 24%;
|
||
--sz-18pct: 18%;
|
||
--sz-12pct: 12%;
|
||
--sz-calc-6: min(20rem,calc(100vw - 2rem)); /* Extracted from ui/src/components/InlineEntitySelector.tsx (w-[min(20rem,calc(100vw-2rem))]). */
|
||
--sz-18rem: 18rem; /* Extracted from ui/src/components/IssueBlockedNotice.tsx (max-w-[18rem]). */
|
||
--sz-70vh: 70vh; /* Extracted from ui/src/components/IssueChatThread.test.tsx (max-h-[70vh]). */
|
||
--sz-calc-7: calc(100% - 0.5rem); /* Extracted from ui/src/components/IssueChatThread.test.tsx (max-w-[calc(100%-0.5rem)]). */
|
||
--sz-28dvh: 28dvh; /* Extracted from ui/src/components/IssueChatThread.test.tsx (max-h-[28dvh]). */
|
||
--sz-72px: 72px; /* Extracted from ui/src/components/IssueChatThread.test.tsx (min-h-[72px]). */
|
||
--sz-15px: 15px; /* Extracted from ui/src/components/IssueChatThread.test.tsx (p-[15px]). */
|
||
--sz-calc-8: calc(env(safe-area-inset-bottom) + 20px); /* Extracted from ui/src/components/IssueChatThread.test.tsx (bottom-[calc(env(safe-area-inset-bottom)+20px)]). */
|
||
--sz-300px: 300px; /* Extracted from ui/src/components/IssueColumns.tsx (w-[300px]). */
|
||
--sz-calc-9: min(80vh,42rem); /* Extracted from ui/src/components/IssueFiltersPopover.test.tsx (max-h-[min(80vh,42rem)]). */
|
||
--sz-calc-10: min(780px,calc(100vw - 2rem)); /* Extracted from ui/src/components/IssueFiltersPopover.tsx (w-[min(780px,calc(100vw-2rem))]). */
|
||
--sz-24ch: 24ch; /* Extracted from ui/src/components/IssuePlanDecompositionsSection.tsx (max-w-[24ch]). */
|
||
--sz-calc-13: calc(0.75rem + 0.5rem); /* Extracted from ui/src/components/IssueRow.tsx (ml-[calc(theme(spacing.3)+theme(spacing.2))]). */
|
||
--sz-140px: 140px; /* Extracted from ui/src/components/JsonSchemaForm.tsx (min-h-[140px]). */
|
||
--sz-52px: 52px; /* Extracted from ui/src/components/KanbanBoard.tsx (w-[52px]). */
|
||
--sz-48px: 48px; /* Extracted from ui/src/components/KanbanBoard.tsx (min-w-[48px]). */
|
||
--sz-260px: 260px; /* Extracted from ui/src/components/KanbanBoard.tsx (min-w-[260px]). */
|
||
--sz-120px: 120px; /* Extracted from ui/src/components/KanbanBoard.tsx (min-h-[120px]). */
|
||
--sz-safe-top: env(safe-area-inset-top); /* Extracted from ui/src/components/Layout.tsx (pt-[env(safe-area-inset-top)]). */
|
||
--sz-calc-14: calc(5rem + env(safe-area-inset-bottom)); /* Extracted from ui/src/components/Layout.tsx (pb-[calc(5rem+env(safe-area-inset-bottom))]). */
|
||
--sz-38ch: 38ch; /* Extracted from ui/src/components/MarkdownBody.test.tsx (max-w-[38ch]). */
|
||
--sz-208px: 208px; /* Extracted from ui/src/components/MarkdownEditor.test.tsx (max-h-[208px]). */
|
||
--sz-180px: 180px; /* Extracted from ui/src/components/MarkdownEditor.tsx (min-w-[180px]). */
|
||
--sz-calc-15: calc(100vw - 16px); /* Extracted from ui/src/components/MarkdownEditor.tsx (max-w-[calc(100vw-16px)]). */
|
||
--sz-66px: 66px; /* Extracted from ui/src/components/MembershipAction.tsx (w-[66px]). */
|
||
--sz-safe-bottom: env(safe-area-inset-bottom); /* Extracted from ui/src/components/MobileBottomNav.tsx (pb-[env(safe-area-inset-bottom)]). */
|
||
--sz-calc-16: min(calc(100dvh - 2rem),46rem); /* Extracted from ui/src/components/NewAgentDialog.tsx (max-h-[min(calc(100dvh-2rem),46rem)]). */
|
||
--sz-24rem: 24rem; /* Extracted from ui/src/components/NewAgentDialog.tsx (h-[24rem]). */
|
||
--sz-50vh: 50vh; /* Extracted from ui/src/components/NewGoalDialog.tsx (max-h-[50vh]). */
|
||
--sz-8_5rem: 8.5rem; /* Extracted from ui/src/components/NewIssueDialog.tsx (min-w-[8.5rem]). */
|
||
--sz-160px: 160px; /* Extracted from ui/src/components/NewProjectDialog.tsx (max-w-[160px]). */
|
||
--sz-80px: 80px; /* Extracted from ui/src/components/OnboardingWizard.tsx (min-h-[80px]). */
|
||
--sz-calc-17: calc(100vh - 4rem); /* Extracted from ui/src/components/PageSkeleton.tsx (h-[calc(100vh-4rem)]). */
|
||
--sz-2px: 2px; /* Extracted from ui/src/components/QuotaBar.tsx (w-[2px]). */
|
||
--sz-calc-18: calc(100dvh - 2rem); /* Extracted from ui/src/components/RoutineRunVariablesDialog.test.tsx (max-h-[calc(100dvh-2rem)]). */
|
||
--sz-calc-19: calc(1rem + env(safe-area-inset-bottom)); /* Extracted from ui/src/components/RoutineRunVariablesDialog.test.tsx (pb-[calc(1rem+env(safe-area-inset-bottom))]). */
|
||
--sz-calc-20: min(calc(100dvh - 2rem),42rem); /* Extracted from ui/src/components/RoutineRunVariablesDialog.tsx (max-h-[min(calc(100dvh-2rem),42rem)]). */
|
||
--sz-100dvh: 100dvh; /* Extracted from ui/src/components/RoutineSubSidebar.tsx (max-h-[100dvh]). */
|
||
--sz-calc-21: calc(1.5rem + 5rem + env(safe-area-inset-bottom)); /* Extracted from ui/src/components/ScrollToBottom.tsx (bottom-[calc(1.5rem+5rem+env(safe-area-inset-bottom))]). */
|
||
--sz-calc-22: calc(320px + 1.5rem); /* Extracted from ui/src/components/ScrollToBottom.tsx (right-[calc(320px+1.5rem)]). */
|
||
--sz-calc-23: min(32rem,calc(100vw - 2rem)); /* Extracted from ui/src/components/SearchableSelect.tsx (max-w-[min(32rem,calc(100vw-2rem))]). */
|
||
--sz-277px: 277px; /* Extracted from ui/src/components/SidebarAccountMenu.test.tsx (w-[277px]). */
|
||
--sz-calc-24: calc(100vw - 1rem); /* Extracted from ui/src/components/SidebarAccountMenu.tsx (max-w-[calc(100vw-1rem)]). */
|
||
--sz-4_5rem: 4.5rem; /* Extracted from ui/src/components/SidebarAgents.tsx (min-w-[4.5rem]). */
|
||
--sz-36px: 36px; /* Extracted from ui/src/components/WorkspaceFileBrowser.tsx (min-h-[36px]). */
|
||
--sz-32px: 32px; /* Extracted from ui/src/components/WorkspaceFileBrowser.tsx (min-h-[32px]). */
|
||
--sz-30px: 30px; /* Extracted from ui/src/components/WorkspaceFileBrowser.tsx (min-h-[30px]). */
|
||
--sz-8px: 8px; /* Extracted from ui/src/components/artifacts/ArtifactGroupCard.tsx (translate-x-[8px]). */
|
||
--sz-4px: 4px; /* Extracted from ui/src/components/artifacts/ArtifactGroupCard.tsx (translate-x-[4px]). */
|
||
--sz-34px: 34px; /* Extracted from ui/src/components/environment-variables-editor/SecretPicker.tsx (h-[34px]). */
|
||
--sz-11rem: 11rem; /* Extracted from ui/src/components/issue-properties/IssueProperties.tsx (min-w-[11rem]). */
|
||
--sz-32rem: 32rem; /* Extracted from ui/src/components/issue-properties/IssueProperties.tsx (w-[32rem]). */
|
||
--sz-280px: 280px; /* Extracted from ui/src/components/timeline/WorkTimelineChart.tsx (max-w-[280px]). */
|
||
--sz-7px: 7px; /* Extracted from ui/src/components/transcript/RunTranscriptView.tsx (mt-[7px]). */
|
||
--sz-calc-25: calc(100% - 2rem); /* Extracted from ui/src/components/ui/alert-dialog.tsx (max-w-[calc(100%-2rem)]). */
|
||
--sz-calc-26: max(1rem,env(safe-area-inset-top)); /* Extracted from ui/src/components/ui/alert-dialog.tsx (top-[max(1rem,env(safe-area-inset-top))]). */
|
||
--sz-8rem: 8rem; /* Extracted from ui/src/components/ui/dropdown-menu.tsx (min-w-[8rem]). */
|
||
--sz-calc-27: calc(100% - 1px); /* Extracted from ui/src/components/ui/tabs.tsx (h-[calc(100%-1px)]). */
|
||
--sz-neg-5px: -5px; /* Extracted from ui/src/components/ui/tabs.tsx (bottom-[-5px]). */
|
||
--sz-calc-28: calc(-50% - 2px); /* Extracted from ui/src/components/ui/tooltip.tsx (translate-y-[calc(-50%_-_2px)]). */
|
||
--sz-420px: 420px; /* Extracted from ui/src/pages/AgentDetail.tsx (min-h-[420px]). */
|
||
--sz-30rem: 30rem; /* Extracted from ui/src/pages/AgentDetail.tsx (w-[30rem]). */
|
||
--sz-38rem: 38rem; /* Extracted from ui/src/pages/AgentDetail.tsx (max-h-[38rem]). */
|
||
--sz-7rem: 7rem; /* Extracted from ui/src/pages/Agents.test.tsx (min-w-[7rem]). */
|
||
--sz-calc-29: calc(100% + 3rem); /* Extracted from ui/src/pages/BoardChat.tsx (h-[calc(100%+3rem)]). */
|
||
--sz-22rem: 22rem; /* Extracted from ui/src/pages/CompanyEnvironments.tsx (h-[22rem]). */
|
||
--sz-560px: 560px; /* Extracted from ui/src/pages/CompanyExport.tsx (min-h-[560px]). */
|
||
--sz-520px: 520px; /* Extracted from ui/src/pages/CompanyExport.tsx (min-h-[520px]). */
|
||
--sz-480px: 480px; /* Extracted from ui/src/pages/CompanyExport.tsx (max-h-[480px]). */
|
||
--sz-calc-30: calc(100vh - 12rem); /* Extracted from ui/src/pages/CompanyExport.tsx (h-[calc(100vh-12rem)]). */
|
||
--sz-calc-31: calc(100vh - 16rem); /* Extracted from ui/src/pages/CompanyImport.tsx (h-[calc(100vh-16rem)]). */
|
||
--sz-calc-32: min(28rem,70vh); /* Extracted from ui/src/pages/CompanySkills.tsx (max-h-[min(28rem,70vh)]). */
|
||
--sz-11_5rem: 11.5rem; /* Extracted from ui/src/pages/CompanySkills.tsx (min-h-[11.5rem]). */
|
||
--sz-11_75rem: 11.75rem; /* SkillStudio.tsx file/input browser cap: five min-h-9 rows plus p-1 vertical padding. */
|
||
--sz-calc-33: calc(100dvh - 6rem); /* Extracted from ui/src/pages/CompanySkills.tsx (h-[calc(100dvh-6rem)]). */
|
||
--sz-calc-34: clamp(14rem,45vh,28rem); /* Extracted from ui/src/pages/CompanySkills.tsx (h-[clamp(14rem,45vh,28rem)]). */
|
||
--sz-400px: 400px; /* Extracted from ui/src/pages/CompanySkills.tsx (min-h-[400px]). */
|
||
--sz-calc-35: min(34rem,55vw); /* Extracted from ui/src/pages/CompanySkills.tsx (max-w-[min(34rem,55vw)]). */
|
||
--sz-640px: 640px; /* Extracted from ui/src/pages/DesignGuide.tsx (max-w-[640px]). */
|
||
--sz-28rem: 28rem; /* Extracted from ui/src/pages/DesignGuide.tsx (w-[28rem]). */
|
||
--sz-170px: 170px; /* Extracted from ui/src/pages/Inbox.tsx (w-[170px]). */
|
||
--sz-calc-36: min(28rem,65vh); /* Extracted from ui/src/pages/InstanceExperimentalSettings.tsx (max-h-[min(28rem,65vh)]). */
|
||
--sz-calc-37: min(100%,22rem); /* Extracted from ui/src/pages/IssueDetail.tsx (w-[min(100%,22rem)]). */
|
||
--sz-85dvh: 85dvh; /* Extracted from ui/src/pages/IssueDetail.tsx (max-h-[85dvh]). */
|
||
--sz-calc-38: calc(100dvh - 9rem); /* Extracted from ui/src/pages/OrgChart.tsx (h-[calc(100dvh-9rem)]). */
|
||
--sz-calc-39: calc(100dvh - 3.5rem); /* Extracted from ui/src/pages/PipelineSettings.tsx (max-h-[calc(100dvh-3.5rem)]). */
|
||
--sz-calc-40: min(24rem,calc(100vw - 2rem)); /* Extracted from ui/src/pages/PipelineSettings.tsx (w-[min(24rem,calc(100vw-2rem))]). */
|
||
--sz-780px: 780px; /* Extracted from ui/src/pages/Pipelines.tsx (min-w-[780px]). */
|
||
--sz-148px: 148px; /* Extracted from ui/src/pages/Pipelines.tsx (w-[148px]). */
|
||
--sz-11px: 11px; /* Extracted from ui/src/pages/Pipelines.tsx (h-[11px]). */
|
||
--sz-9px: 9px; /* Extracted from ui/src/pages/Pipelines.tsx (h-[9px]). */
|
||
--sz-720px: 720px; /* Extracted from ui/src/pages/RunTranscriptUxLab.tsx (max-h-[720px]). */
|
||
--sz-460px: 460px; /* Extracted from ui/src/pages/RunTranscriptUxLab.tsx (max-h-[460px]). */
|
||
--sz-960px: 960px; /* Extracted from ui/src/pages/Search.tsx (max-w-[960px]). */
|
||
--sz-70px: 70px; /* Extracted from ui/src/pages/Secrets.tsx (min-h-[70px]). */
|
||
--sz-calc-41: min(520px,calc(100vw - 2rem)); /* Extracted from ui/src/pages/Secrets.tsx (w-[min(520px,calc(100vw-2rem))]). */
|
||
--sz-calc-42: min(80vh,34rem); /* Extracted from ui/src/pages/Secrets.tsx (max-h-[min(80vh,34rem)]). */
|
||
--sz-14rem: 14rem; /* Extracted from ui/src/pages/TeamCatalog.tsx (max-w-[14rem]). */
|
||
--rad-3: 3px; /* Extracted from ui/src/components/ExternalObjectPill.tsx (ring-[3px]). */
|
||
--rad-4: 4px; /* Extracted from ui/src/components/IssueChatThread.tsx (rounded-br-[4px]). */
|
||
--rad-2: 2px; /* Extracted from ui/src/components/SidebarCompanyMenu.tsx (ring-[2px]). */
|
||
--rad-14: 14px; /* Extracted from ui/src/pages/CompanySettings.tsx (rounded-[14px]). */
|
||
--rad-28: 28px; /* Extracted from ui/src/pages/InviteUxLab.tsx (rounded-[28px]). */
|
||
--rad-24: 24px; /* Extracted from ui/src/pages/InviteUxLab.tsx (rounded-[24px]). */
|
||
--rad-32: 32px; /* Extracted from ui/src/pages/InviteUxLab.tsx (rounded-[32px]). */
|
||
--pct-90: 90%; /* Extracted from ui/src/components/DocumentDiffModal.tsx (max-w-[90%]). */
|
||
--pct-80: 80%; /* TaskChatThread composer width (PAP-498 follow-up). */
|
||
--pct-50: 50%; /* Extracted from ui/src/components/ImageGalleryModal.tsx (max-w-[50%]). */
|
||
--pct-85: 85%; /* Extracted from ui/src/components/IssueChatThread.test.tsx (max-w-[85%]). */
|
||
--pct-70: 70%; /* Extracted from ui/src/components/CaseFieldsPanel.tsx (max-w-[70%]). */
|
||
--pct-neg-50: -50%; /* Extracted from ui/src/components/ui/alert-dialog.tsx (translate-x-[-50%]). */
|
||
--pct-72: 72%; /* Extracted from ui/src/pages/IssueDetail.tsx (w-[72%]). */
|
||
--shadow-extract-1: 0 16px 40px rgba(37,99,235,0.08); /* ActiveAgentsPanel.tsx live-box glow. Gallery feedback r2: liveness glow recolored cyan->status blue (value edit, site unchanged; originally extracted as rgba(6,182,212,0.08)). */
|
||
--shadow-extract-2: 0 20px 80px -40px rgba(0,0,0,0.55); /* Extracted from ui/src/components/BudgetPolicyCard.tsx (shadow-[0_20px_80px_-40px_rgba(0,0,0,0.55)]). */
|
||
--shadow-extract-3: 0 0 0 1px rgba(255,255,255,0.08); /* Extracted from ui/src/components/BudgetSidebarMarker.tsx (shadow-[0_0_0_1px_rgba(255,255,255,0.08)]). */
|
||
--shadow-extract-4: 0 -12px 28px rgba(15,23,42,0.08); /* Extracted from ui/src/components/ChatComposer.test.tsx (shadow-[0_-12px_28px_rgba(15,23,42,0.08)]). */
|
||
--shadow-extract-5: 0 -12px 28px rgba(0,0,0,0.28); /* Extracted from ui/src/components/ChatComposer.test.tsx (shadow-[0_-12px_28px_rgba(0,0,0,0.28)]). */
|
||
--shadow-extract-6: 0 0 0 1px var(--color-background); /* Extracted from ui/src/components/DocumentAnnotationLayer.tsx (shadow-[0_0_0_1px_var(--color-background)]). */
|
||
--shadow-extract-7: 0 -12px 28px rgba(15,23,42,0.08),0 0 0 1px color-mix(in oklab, var(--primary) 16%, transparent); /* Extracted from ui/src/components/IssueChatThread.tsx; corrected for full-color semantic tokens. */
|
||
--shadow-extract-8: 0 1px 0 rgba(15,23,42,0.02); /* Extracted from ui/src/components/IssueRecoveryActionCard.tsx (shadow-[0_1px_0_rgba(15,23,42,0.02)]). */
|
||
--shadow-extract-9: 0 18px 42px rgba(15,23,42,0.06); /* Extracted from ui/src/components/IssueThreadInteractionCard.tsx (shadow-[0_18px_42px_rgba(15,23,42,0.06)]). */
|
||
--shadow-extract-10: 0 1px 0 1px var(--border); /* Extracted from ui/src/components/KeyboardShortcutsCheatsheet.tsx; corrected for full-color semantic tokens. */
|
||
--shadow-extract-11: 0 18px 50px rgba(37,99,235,0.08); /* LiveRunWidget.tsx glow. Gallery feedback r2: liveness glow recolored cyan->status blue (value edit, site unchanged; originally extracted as rgba(6,182,212,0.08)). */
|
||
--shadow-extract-12: 0 0 0 2px var(--background); /* Extracted from ui/src/components/SidebarNavItem.tsx; corrected for full-color semantic tokens. */
|
||
--shadow-extract-13: 0 0 0 3px rgba(245,158,11,0.18); /* Extracted from ui/src/components/environment-variables-editor/index.tsx (shadow-[0_0_0_3px_rgba(245,158,11,0.18)]). */
|
||
--shadow-extract-14: 0 0 12px rgba(37,99,235,0.08); /* AgentDetail.tsx live-card glow. Gallery feedback r2: liveness glow recolored cyan->status blue (value edit, site unchanged; originally extracted as rgba(6,182,212,0.08)). */
|
||
--shadow-extract-18: 0 18px 44px -28px rgba(0,0,0,0.45); /* Extracted from ui/src/pages/ProfileSettings.tsx (shadow-[0_18px_44px_-28px_rgba(0,0,0,0.45)]). */
|
||
}
|
||
|
||
/* ── Extracted verbatim MISC tokens (Phase 2 Batch 4, design/token-extraction) ── */
|
||
/* Batch 4/4 (final sweep): grid track lists, transition-property
|
||
lists, z-index, scale, easing, vertical-align, stroke-width, blur,
|
||
drop-shadow, and half-migrated var(x, fallback) color forms,
|
||
verbatim (no normalizing - the human scale-collapse decision comes
|
||
later per DESIGN.md/TOKEN-AUDIT.md). --gtc-* and --gtr-* and --tp-* are
|
||
sequentially numbered / slugged since their content (track lists,
|
||
property lists) is not safely nameable by value alone.
|
||
|
||
drop-shadow (a CSS filter function) gets its own
|
||
--drop-shadow-extract-* family, kept separate from Batch 3's
|
||
--shadow-extract-* box-shadow family per that batch's logged
|
||
human-decision note.
|
||
|
||
*-resolved wrapper tokens hold a verbatim var(--x, fallback)
|
||
expression for sites where Tailwind v4's paren-with-fallback-comma
|
||
shorthand does not parse (confirmed unsupported in this batch's
|
||
Step 0 syntax spike). theme(colors.a.b) fallbacks were resolved to
|
||
the equivalent var(--token) form the Tailwind build already
|
||
compiles them to today (inspected byte-for-byte from the built
|
||
storybook-static CSS before this codemod ran: theme(colors.muted.DEFAULT)
|
||
-> var(--muted), theme(colors.muted.foreground) -> var(--muted-foreground)).
|
||
|
||
--gradient-extract-* here CONTINUES Batch 1's counter (Batch 1 minted
|
||
1 through 24) rather than restarting it - these 2 sites use
|
||
hsl(var(...))/color-mix(...) CSS-native color functions rather than raw
|
||
hex/rgb literals, which is why Batch 1's hand-audited color-literal
|
||
table did not catch them, but they are still value-bearing gradient
|
||
brackets in scope for this batch's final sweep.
|
||
|
||
Allowlist (sites intentionally left as-is - see ALLOWLIST doc-comment
|
||
at the end of this file for the machine-readable list consumed by
|
||
scripts/check-token-gates.mjs):
|
||
allow ui/src/components/ui/dialog.tsx — tw-animate-css plugin utilities (zoom-in-[0.97] etc.) are dead/no-op classes today (plugin not installed, verified via built-CSS grep); nothing to tokenize without visually changing a currently-inert class
|
||
allow ui/src/components/ui/alert-dialog.tsx — same tw-animate-css dead-class situation as dialog.tsx
|
||
*/
|
||
:root {
|
||
--gtc-1: 56px 56px 24px minmax(0,1fr); /* Extracted from ui/src/components/DocumentDiffModal.tsx (grid-cols-[56px_56px_24px_minmax(0,1fr)]). */
|
||
--gtc-case-revisions: 16rem 1fr; /* Extracted from ui/src/components/CaseRevisionRail.tsx (grid-cols-[16rem_1fr]). */
|
||
--gtc-2: auto minmax(0,1fr) 2.25rem; /* Extracted from ui/src/components/FileTree.tsx (grid-cols-[auto_minmax(0,1fr)_2.25rem]). */
|
||
--gtc-3: minmax(0,1fr) 2.25rem; /* Extracted from ui/src/components/FileTree.tsx (grid-cols-[minmax(0,1fr)_2.25rem]). */
|
||
--gtc-4: minmax(0,1fr); /* Extracted from ui/src/components/FileTree.tsx (grid-cols-[minmax(0,1fr)]). */
|
||
--gtc-5: auto minmax(0,1fr); /* Extracted from ui/src/components/FileViewerSheet.tsx (grid-cols-[auto_minmax(0,1fr)]). */
|
||
--gtc-6: auto minmax(0,1fr) auto; /* Extracted from ui/src/components/FileViewerSheet.tsx (grid-cols-[auto_minmax(0,1fr)_auto]). */
|
||
--gtc-7: 7.5rem minmax(0,1fr); /* Extracted from ui/src/components/IssueChatThread.tsx (grid-cols-[7.5rem_minmax(0,1fr)]). */
|
||
--gtc-8: 7.5rem 1fr; /* Extracted from ui/src/components/IssueRecoveryActionCard.tsx (grid-cols-[7.5rem_1fr]). */
|
||
--gtc-9: 300px minmax(0,1fr); /* Extracted from ui/src/components/RoutineHistoryTab.tsx (grid-cols-[300px_minmax(0,1fr)]). */
|
||
--gtc-10: 10rem 1fr; /* Extracted from ui/src/components/SourceResolvedFoldCallout.tsx (grid-cols-[10rem_1fr]). */
|
||
--gtc-11: 12rem 1fr; /* Extracted from ui/src/components/SourceResolvedFoldCallout.tsx (grid-cols-[12rem_1fr]). */
|
||
--gtc-12: minmax(0,0.75fr) minmax(0,1fr); /* Extracted from ui/src/components/TrustPresetSection.tsx (grid-cols-[minmax(0,0.75fr)_minmax(0,1fr)]). */
|
||
--gtc-13: minmax(0,1fr) auto; /* Extracted from ui/src/components/environment-variables-editor/Row.tsx (grid-cols-[minmax(0,1fr)_auto]). */
|
||
--gtc-14: minmax(160px,2fr) minmax(240px,3fr) 32px; /* Extracted from ui/src/components/environment-variables-editor/Row.tsx (grid-cols-[minmax(160px,2fr)_minmax(240px,3fr)_32px]). */
|
||
--gtc-15: 6rem 1fr; /* Extracted from ui/src/components/issue-properties/IssueProperties.tsx (grid-cols-[6rem_1fr]). */
|
||
--gtc-16: auto 1fr; /* Extracted from ui/src/components/transcript/RunTranscriptView.tsx (grid-cols-[auto_1fr]). */
|
||
--gtc-17: 1fr auto; /* Extracted from ui/src/components/ui/card.tsx (grid-cols-[1fr_auto]). */
|
||
--gtc-18: auto minmax(0,1fr) minmax(12rem,0.65fr); /* Extracted from ui/src/pages/AgentDetail.tsx (grid-cols-[auto_minmax(0,1fr)_minmax(12rem,0.65fr)]). */
|
||
--gtc-19: 260px minmax(0,1fr); /* Extracted from ui/src/pages/AgentDetail.tsx (grid-cols-[260px_minmax(0,1fr)]). */
|
||
/* --gtc-20 through --gtc-23 retired with the removed Cloud Upstream page. */
|
||
--gtc-24: minmax(0,1.5fr) 120px 120px 180px; /* Extracted from ui/src/pages/CompanyAccess.tsx (grid-cols-[minmax(0,1.5fr)_120px_120px_180px]). */
|
||
--gtc-25: 19rem minmax(0,1fr); /* Extracted from ui/src/pages/CompanyExport.tsx (grid-cols-[19rem_minmax(0,1fr)]). */
|
||
--gtc-26: 7rem minmax(0,1fr); /* Extracted from ui/src/pages/CompanySkills.tsx (grid-cols-[7rem_minmax(0,1fr)]). */
|
||
--gtc-27: minmax(0,1fr) auto auto; /* Extracted from ui/src/pages/CompanySkills.tsx (grid-cols-[minmax(0,1fr)_auto_auto]). */
|
||
--gtc-28: 13rem minmax(0,1fr); /* Extracted from ui/src/pages/CompanySkills.tsx (grid-cols-[13rem_minmax(0,1fr)]). */
|
||
--gtc-29: minmax(0,1fr) 18rem; /* Extracted from ui/src/pages/CompanySkills.tsx (grid-cols-[minmax(0,1fr)_18rem]). */
|
||
--gtc-30: 14rem minmax(0,1fr); /* Extracted from ui/src/pages/CompanySkills.tsx (grid-cols-[14rem_minmax(0,1fr)]). */
|
||
--gtc-31: 1.3fr,1fr; /* Extracted from ui/src/pages/Costs.tsx (grid-cols-[1.3fr,1fr]). */
|
||
--gtc-32: 1.25fr,0.95fr; /* Extracted from ui/src/pages/Costs.tsx (grid-cols-[1.25fr,0.95fr]). */
|
||
--gtc-33: 1.2fr,0.95fr; /* Extracted from ui/src/pages/Costs.tsx (grid-cols-[1.2fr,0.95fr]). */
|
||
--gtc-34: 320px minmax(0,1fr); /* Extracted from ui/src/pages/InstanceAccess.tsx (grid-cols-[320px_minmax(0,1fr)]). */
|
||
--gtc-35: minmax(10rem,14rem) 1fr; /* Extracted from ui/src/pages/InstanceExperimentalSettings.tsx (grid-cols-[minmax(10rem,14rem)_1fr]). */
|
||
--gtc-36: minmax(0,1.15fr) minmax(360px,0.85fr); /* Extracted from ui/src/pages/InviteLanding.tsx (grid-cols-[minmax(0,1.15fr)_minmax(360px,0.85fr)]). */
|
||
--gtc-37: minmax(0,1.15fr) minmax(320px,0.85fr); /* Extracted from ui/src/pages/InviteUxLab.tsx (grid-cols-[minmax(0,1.15fr)_minmax(320px,0.85fr)]). */
|
||
--gtc-38: minmax(0,0.92fr) minmax(0,1.08fr); /* Extracted from ui/src/pages/InviteUxLab.tsx (grid-cols-[minmax(0,0.92fr)_minmax(0,1.08fr)]). */
|
||
--gtc-39: minmax(0,1.2fr) 320px; /* Extracted from ui/src/pages/InviteUxLab.tsx (grid-cols-[minmax(0,1.2fr)_320px]). */
|
||
--gtc-40: minmax(0,1fr) 320px; /* Extracted from ui/src/pages/IssueChatLongThreadPerf.tsx (grid-cols-[minmax(0,1fr)_320px]). */
|
||
--gtc-41: 10rem minmax(0,1fr); /* Extracted from ui/src/pages/PipelineSettings.tsx (grid-cols-[10rem_minmax(0,1fr)]). */
|
||
--gtc-42: minmax(0,1fr) 240px; /* Extracted from ui/src/pages/PipelineSettings.tsx (grid-cols-[minmax(0,1fr)_240px]). */
|
||
--gtc-43: minmax(0,1fr) minmax(0,1fr); /* Extracted from ui/src/pages/PipelineSettings.tsx (grid-cols-[minmax(0,1fr)_minmax(0,1fr)]). */
|
||
--gtc-44: 5rem 240px; /* Extracted from ui/src/pages/PipelineSettings.tsx (grid-cols-[5rem_240px]). */
|
||
--gtc-45: minmax(0,1fr) 340px; /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[minmax(0,1fr)_340px]). */
|
||
--gtc-46: 18px minmax(0,1fr); /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[18px_minmax(0,1fr)]). */
|
||
--gtc-47: 120px 1fr; /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[120px_1fr]). */
|
||
--gtc-48: 18px minmax(0,1fr) auto; /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[18px_minmax(0,1fr)_auto]). */
|
||
--gtc-49: 18px 1fr auto; /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[18px_1fr_auto]). */
|
||
--gtc-50: 1fr 280px; /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[1fr_280px]). */
|
||
--gtc-51: 160px 1fr; /* Extracted from ui/src/pages/Pipelines.tsx (grid-cols-[160px_1fr]). */
|
||
--gtc-52: minmax(0,1.4fr) minmax(220px,0.8fr); /* Extracted from ui/src/pages/PluginSettings.tsx (grid-cols-[minmax(0,1.4fr)_minmax(220px,0.8fr)]). */
|
||
--gtc-53: minmax(0,1.4fr) minmax(18rem,0.9fr); /* Extracted from ui/src/pages/ProjectWorkspaceDetail.tsx (grid-cols-[minmax(0,1.4fr)_minmax(18rem,0.9fr)]). */
|
||
--gtc-54: minmax(12rem,2.4fr) minmax(5.25rem,0.75fr) minmax(7rem,1fr) minmax(5rem,0.7fr) 2.75rem; /* Extracted from ui/src/pages/Secrets.tsx (grid-cols-[minmax(12rem,2.4fr)_minmax(5.25rem,0.75fr)_minmax(7rem,1fr)_minmax(5rem,0.7fr)_2.75rem]). */
|
||
--gtc-55: 8rem minmax(0,1fr); /* Extracted from ui/src/pages/Secrets.tsx (grid-cols-[8rem_minmax(0,1fr)]). */
|
||
--gtc-56: minmax(0,1fr) minmax(14rem,18rem); /* Extracted from ui/src/pages/TeamCatalog.tsx (grid-cols-[minmax(0,1fr)_minmax(14rem,18rem)]). */
|
||
--gtc-57: repeat(14,minmax(0,1fr)); /* Extracted from ui/src/pages/UserProfile.tsx (grid-cols-[repeat(14,minmax(0,1fr))]). */
|
||
--gtc-58: auto 1fr auto; /* Extracted from ui/src/pages/UserProfile.tsx (grid-cols-[auto_1fr_auto]). */
|
||
--gtc-59: 8rem 1fr;
|
||
--gtc-60: 1fr 1fr;
|
||
--gtc-61: 1fr 1fr 1fr;
|
||
--gtc-62: 1fr minmax(0,18rem);
|
||
--gtc-63: 280px 1fr;
|
||
--gtc-64: minmax(0,20rem) 1fr;
|
||
--gtc-65: minmax(8rem,0.38fr) minmax(0,0.62fr) auto;
|
||
--gtr-1: auto auto; /* Extracted from ui/src/components/ui/card.tsx (grid-rows-[auto_auto]). */
|
||
--gtr-2: 1fr; /* Extracted from ui/src/pages/CompanySkills.tsx (grid-rows-[1fr]). */
|
||
--gtr-3: 0fr; /* Extracted from ui/src/pages/CompanySkills.tsx (grid-rows-[0fr]). */
|
||
--tp-background-color-border-color: background-color,border-color; /* Extracted from ui/src/components/ActivityFeed.tsx (transition-[background-color,border-color]). */
|
||
--tp-width-background-color: width,background-color; /* Extracted from ui/src/components/BudgetPolicyCard.tsx (transition-[width,background-color]). */
|
||
--tp-width: width; /* Extracted from ui/src/components/ClaudeSubscriptionPanel.tsx (transition-[width]). */
|
||
--tp-background-color-color-opacity: background-color,color,opacity; /* Extracted from ui/src/components/FileTree.tsx (transition-[background-color,color,opacity]). */
|
||
--tp-max-height: max-height; /* Extracted from ui/src/components/FoldCurtain.tsx (transition-[max-height]). */
|
||
--tp-border-color-background-color-box-shadow: border-color,background-color,box-shadow; /* Extracted from ui/src/components/IssueChatThread.tsx (transition-[border-color,background-color,box-shadow]). */
|
||
--tp-width-min-width: width,min-width; /* Extracted from ui/src/components/KanbanBoard.tsx (transition-[width,min-width]). */
|
||
--tp-width-opacity: width,opacity; /* Extracted from ui/src/components/OnboardingWizard.tsx (transition-[width,opacity]). */
|
||
--tp-background-color-right: background-color,right; /* Extracted from ui/src/components/ScrollToBottom.tsx (transition-[background-color,right]). */
|
||
--tp-background-color-border-color-color: background-color,border-color,color; /* Extracted from ui/src/components/SystemNotice.tsx (transition-[background-color,border-color,color]). */
|
||
--tp-transform-opacity: transform,opacity; /* Extracted from ui/src/components/ToastViewport.tsx (transition-[transform,opacity]). */
|
||
--tp-color-box-shadow: color,box-shadow; /* Extracted from ui/src/components/ui/badge.tsx (transition-[color,box-shadow]). */
|
||
--tp-color-background-color-border-color-box-shadow-opacity: color,background-color,border-color,box-shadow,opacity; /* Extracted from ui/src/components/ui/button.tsx (transition-[color,background-color,border-color,box-shadow,opacity]). */
|
||
--tp-border-color-background-color: border-color,background-color; /* Extracted from ui/src/components/ui/radio-card.tsx (transition-[border-color,background-color]). */
|
||
--tp-color-background-color-border-color-box-shadow: color,background-color,border-color,box-shadow; /* Extracted from ui/src/components/ui/tabs.tsx (transition-[color,background-color,border-color,box-shadow]). */
|
||
--tp-grid-template-rows-opacity: grid-template-rows,opacity; /* Extracted from ui/src/pages/CompanySkills.tsx (transition-[grid-template-rows,opacity]). */
|
||
--tp-box-shadow-border-color: box-shadow,border-color; /* Extracted from ui/src/pages/OrgChart.tsx (transition-[box-shadow,border-color]). */
|
||
--tp-box-shadow: box-shadow; /* Extracted from ui/src/pages/ProjectDetail.tsx (transition-[box-shadow]). */
|
||
--tp-transform-box-shadow: transform,box-shadow; /* Extracted from ui/src/pages/ProjectDetail.tsx (transition-[transform,box-shadow]). */
|
||
--z-2: 2; /* Extracted from ui/src/components/DocumentAnnotationLayer.tsx (z-[2]). */
|
||
--z-20: 20; /* Anchored document annotation popover. */
|
||
--z-60: 60; /* Extracted from ui/src/components/DocumentAnnotationPanel.tsx (z-[60]). */
|
||
--z-1: 1; /* Extracted from ui/src/components/IssueDocumentAnnotations.tsx (z-[1]). */
|
||
--z-200: 200; /* Extracted from ui/src/components/Layout.tsx (z-[200]). */
|
||
--z-9999: 9999; /* Extracted from ui/src/components/MarkdownEditor.tsx (z-[9999]). */
|
||
--z-120: 120; /* Extracted from ui/src/components/ToastViewport.tsx (z-[120]). */
|
||
--s-0_98: 0.98; /* Extracted from ui/src/pages/Inbox.tsx (scale-[0.98]). */
|
||
--s-1_02: 1.02; /* Extracted from ui/src/components/CaseAttachmentsGallery.tsx (scale-[1.02]). */
|
||
--e-cubic-bezier-0_16-1-0_3-1: cubic-bezier(0.16,1,0.3,1); /* Extracted from ui/src/components/ui/alert-dialog.tsx (ease-[cubic-bezier(0.16,1,0.3,1)]). */
|
||
--va-0_125em: -0.125em; /* Extracted from ui/src/components/ExternalObjectStatusIcon.tsx (align-[-0.125em]). */
|
||
--sw-2_3: 2.3; /* Extracted from ui/src/components/MobileBottomNav.tsx (stroke-[2.3]). */
|
||
--blur-1px: 1px; /* Extracted from ui/src/components/ChatComposer.tsx (backdrop-blur-[1px]). */
|
||
--blur-2px: 2px; /* Extracted from ui/src/components/IssueChatThread.tsx (backdrop-blur-[2px]). */
|
||
--drop-shadow-extract-1: 0 1px 2px rgba(0,0,0,0.65); /* Extracted from ui/src/components/CompanyPatternIcon.tsx (drop-shadow-[0_1px_2px_rgba(0,0,0,0.65)]). */
|
||
--code-bg-resolved: var(--paperclip-code-bg, var(--muted)); /* Extracted from ui/src/components/FileViewerSheet.tsx (bg-[var(--paperclip-code-bg,theme(colors.muted.DEFAULT))]). */
|
||
--paperclip-code-highlight-bg: rgba(250,204,21,0.12); /* DECISION-SHEET.md A5: FileViewerSheet.tsx referenced this var without it ever being defined, relying on the var() fallback; minted here at exactly the former fallback value (zero pixels). */
|
||
--paperclip-code-highlight-border: rgb(234,179,8); /* DECISION-SHEET.md A5: same as --paperclip-code-highlight-bg — minted at the former fallback value. */
|
||
--code-highlight-bg-resolved: var(--paperclip-code-highlight-bg); /* Extracted from ui/src/components/FileViewerSheet.tsx; fallback dropped in A5 now that --paperclip-code-highlight-bg is a real token (was var(--paperclip-code-highlight-bg, rgba(250,204,21,0.12))). */
|
||
--code-gutter-fg-resolved: var(--paperclip-code-gutter-fg, var(--muted-foreground)); /* Extracted from ui/src/components/FileViewerSheet.tsx (text-[var(--paperclip-code-gutter-fg,theme(colors.muted.foreground))]). */
|
||
--code-highlight-border-resolved: var(--paperclip-code-highlight-border); /* Extracted from ui/src/components/FileViewerSheet.tsx; fallback dropped in A5 now that --paperclip-code-highlight-border is a real token (was var(--paperclip-code-highlight-border, rgb(234,179,8))). */
|
||
--gradient-extract-25: linear-gradient(135deg,var(--primary) 0%,var(--accent) 55%,var(--muted) 100%); /* Extracted from ui/src/components/SidebarAccountMenu.tsx; corrected for full-color semantic tokens. */
|
||
--gradient-extract-26: linear-gradient(135deg,var(--primary) 0%,var(--accent) 58%,color-mix(in oklab,var(--background) 76%,white 24%) 100%); /* Extracted from ui/src/pages/ProfileSettings.tsx; corrected for full-color semantic tokens. */
|
||
}
|
||
|
||
/* ── ALLOWLIST (Phase 2, design/token-extraction) ──────────────────────────
|
||
Canonical, MACHINE-READABLE allowlist consumed by
|
||
scripts/check-token-gates.mjs. This block consolidates every site the
|
||
Batch 1-4 codemods intentionally left un-tokenized (functional/third-party
|
||
values, CSS keywords, and currently-inert dead classes) into one list the
|
||
gate script parses directly, rather than re-deriving it from each batch's
|
||
prose log above. The per-batch prose blocks above are kept as historical
|
||
narrative (why each decision was made); this block is the source of truth
|
||
for WHICH sites are exempt.
|
||
|
||
CRITERIA UPDATE (Run 2 review, DECISION-SHEET.md B1 user ruling): the
|
||
allowlist criteria now also include FIRST-PARTY INTENTIONAL ONE-OFF
|
||
DECORATION — deliberate, never-reused decorative gradients/shadows on
|
||
demo/UX-lab surfaces stay inline (spirit over letter of DESIGN.md
|
||
principle 2) rather than being minted as singleton --gradient-extract-*
|
||
and --shadow-extract-* tokens. Production-surface decoration tokens were
|
||
KEPT; only tokens whose sole consumers were *UxLab.tsx demo pages were
|
||
reverted to their original literal form under this rule.
|
||
|
||
Format (one line per entry, do not reflow):
|
||
* allow <repo-relative-path> — <reason>
|
||
|
||
A path may appear more than once if it has more than one distinct
|
||
allowlisted concern. Paths are matched by the gate script as a substring
|
||
of the file being checked (repo-relative, POSIX-style).
|
||
* allow ui/src/pages/CompanyEnvironments.tsx — xterm.js terminal theme config (background/foreground/cursor/cursorAccent/selectionBackground hex, fontSize: 12); functional third-party option object, not a rendered CSS value
|
||
* allow ui/src/components/issue-properties/IssueProperties.tsx — newLabelColor color-picker seed state persisted into the label-create payload sent to the backend; a var() string would corrupt that payload
|
||
* allow ui/src/pages/CompanySkills.tsx — DISCOVERY_ACCENTS palette array feeds skill.color, persisted/compared JS data (SkillCreateDraft), not just a rendered value; also fontSize: Math.round(size * 0.42), computed at runtime from a prop, not a static literal
|
||
* allow ui/src/components/IssueColumns.tsx — accentColor fallback also feeds pickTextColorForPillBg() contrast math (lib/color-contrast.ts), which needs a real hex string to compute luminance
|
||
* allow ui/src/components/CompanyPatternIcon.tsx — canvas 2D fillStyle built from a runtime-computed template literal, not a static literal at all
|
||
* allow ui/src/components/onboarding/PillGuy.tsx — inline rendering of the approved pill-1 dormant/alive brand SVG assets; their fixed eye, body, tuft, and gradient fills are the illustration artwork rather than themeable interface colors
|
||
* allow ui/src/components/ui/scroll-area.tsx — rounded-[inherit] is a CSS keyword, not a literal value; nothing to extract
|
||
* allow ui/src/components/ui/dialog.tsx — tw-animate-css plugin utilities (zoom-in-[0.97], zoom-out-[0.97], slide-in-from-top-[1%], slide-out-to-top-[1%], animate-in, animate-out, fade-in-0, fade-out-0) are dead/no-op classes today (the tw-animate-css plugin is not installed and no matching @utility exists in this file; confirmed via grep of the built storybook-static CSS — none of these class names emit any rule); nothing to tokenize without visually changing a currently-inert class
|
||
* allow ui/src/components/ui/alert-dialog.tsx — same tw-animate-css dead-class situation as dialog.tsx (zoom-out-[0.97], zoom-in-[0.97])
|
||
* allow ui/src/components/ProjectWorkspaceSummaryCard.tsx — min-[420px]: is a Tailwind arbitrary BREAKPOINT variant (responsive container-query-style prefix), not a value applied to a property; the variant position cannot reference a CSS custom property, so it cannot be tokenized without changing Tailwind's own variant syntax
|
||
* allow ui/src/components/FileTree.tsx — max-[480px]: arbitrary breakpoint variant (x2), same reasoning as min-[420px] above
|
||
* allow ui/src/pages/RunTranscriptUxLab.tsx — first-party intentional one-off decoration (demo/UX-lab page): hero/card gradients + shadows reverted from singleton tokens per DECISION-SHEET.md B1 user ruling
|
||
* allow ui/src/pages/InviteUxLab.tsx — first-party intentional one-off decoration (demo/UX-lab page): hero/card gradients + shadows reverted from singleton tokens per DECISION-SHEET.md B1 user ruling
|
||
* allow ui/src/pages/IssueChatUxLab.tsx — first-party intentional one-off decoration (demo/UX-lab page): hero/card gradients + shadows reverted from singleton tokens per DECISION-SHEET.md B1 user ruling
|
||
* allow ui/src/pages/SystemNoticeUxLab.tsx — first-party intentional one-off decoration (demo/UX-lab page): hero/card gradients + shadows reverted from singleton tokens per DECISION-SHEET.md B1 user ruling
|
||
|
||
Test-fixture hex-literal policy (Batch 4, resolving TOKEN-AUDIT.md section
|
||
8 item 10 "Needs human decision" for these specific sites): the following
|
||
*.test.tsx files pass hex-literal strings as MOCK PROP / MOCK API-RESPONSE
|
||
DATA (label/project/company/brand `color` fields, xterm.js theme-mock
|
||
assertions) — not as Tailwind class strings or CSS-in-JS style
|
||
declarations. These are the test-file counterpart of the same
|
||
"functional/persisted data, not a rendered CSS value" category Batch 1
|
||
already allowlisted in production source (see CompanySkills.tsx,
|
||
IssueProperties.tsx, IssueColumns.tsx above); tokenizing them would
|
||
replace realistic-looking mock data with `var()` strings that no longer
|
||
resemble what a real API response contains, without touching any
|
||
rendered pixel. Each file is listed individually for reviewability.
|
||
* allow ui/src/components/IssueFiltersPopover.test.tsx — mock label color prop
|
||
* allow ui/src/components/IssueProperties.test.tsx — mock label/project color fixtures
|
||
* allow ui/src/components/MarkdownBody.test.tsx — mock project color fed through a mention-href builder
|
||
* allow ui/src/components/MarkdownEditor.test.tsx — mock projectColor mention fixture
|
||
* allow ui/src/components/NewIssueDialog.test.tsx — mock label color fixtures
|
||
* allow ui/src/components/ProjectTile.test.tsx — mock project color prop
|
||
* allow ui/src/components/RoutineRunVariablesDialog.test.tsx — mock label color fixture
|
||
* allow ui/src/components/SidebarProjects.test.tsx — mock project color fixture
|
||
* allow ui/src/components/SidebarStarredProjects.test.tsx — mock project color fixture
|
||
* allow ui/src/pages/CompanyEnvironments.test.tsx — xterm.js theme-mock assertion values (mirrors the allowlisted xterm.js config in the CompanyEnvironments.tsx source above)
|
||
* allow ui/src/pages/ExecutionWorkspaceDetail.test.tsx — mock project color fixture
|
||
* allow ui/src/pages/InviteLanding.test.tsx — "#NNNN" pull-request references inside explanatory comments, not color literals
|
||
* allow ui/src/pages/IssueDetail.test.tsx — mock project color fixture
|
||
* allow ui/src/pages/ProjectDetail.test.tsx — mock project color fixture
|
||
* allow ui/src/pages/ProjectWorkspaceDetail.test.tsx — mock project color fixture
|
||
* allow ui/src/pages/Projects.test.tsx — mock project color fixture
|
||
* allow ui/src/pages/Routines.test.tsx — mock routine/label color fixtures
|
||
── end allowlist ── */
|