Spaces:
Running
Running
mfn
Your own agent: hosted relay by default (api.mrfake.name/relay), MCP over HTTP snippets, local relay moved to Advanced
e5b3e51 Download src/index.css from mrfakename/flow: direct link, hf CLI and curl.
- Browser
- Download file 143 kB
-
https://huggingface.co/spaces/mrfakename/flow/resolve/main/src/index.css
- Command line
-
hf download hf://spaces/mrfakename/flow/src/index.css
-
curl -L -o index.css https://huggingface.co/spaces/mrfakename/flow/resolve/main/src/index.css
143 kB
| @source "../node_modules/@cloudflare/kumo/dist/**/*.{js,jsx,ts,tsx}"; | |
| @import "@cloudflare/kumo/styles/tailwind"; | |
| @import "tailwindcss"; | |
| @import "@xyflow/react/dist/base.css"; | |
| /* ------------------------------------------------------------------ */ | |
| /* Tokens */ | |
| /* ------------------------------------------------------------------ */ | |
| @theme static { | |
| --font-sans: "Source Sans 3", "Source Sans Pro", ui-sans-serif, system-ui, -apple-system, sans-serif; | |
| --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace; | |
| /* Port / data-type colours. Tuned so both themes keep the same hue. */ | |
| --color-port-text: light-dark(oklch(72% 0.17 85), oklch(84% 0.16 92)); | |
| --color-port-number: light-dark(oklch(62% 0.12 190), oklch(76% 0.11 190)); | |
| --color-port-boolean: light-dark(oklch(62% 0.16 150), oklch(76% 0.15 150)); | |
| --color-port-image: light-dark(oklch(60% 0.16 245), oklch(74% 0.13 240)); | |
| --color-port-audio: light-dark(oklch(68% 0.18 55), oklch(78% 0.16 60)); | |
| --color-port-video: light-dark(oklch(66% 0.2 340), oklch(78% 0.16 340)); | |
| --color-port-file: light-dark(oklch(58% 0.15 270), oklch(74% 0.12 270)); | |
| --color-port-gallery: light-dark(oklch(62% 0.16 300), oklch(76% 0.13 300)); | |
| --color-port-json: light-dark(oklch(62% 0.2 25), oklch(72% 0.17 25)); | |
| --color-port-any: light-dark(oklch(60% 0 0), oklch(70% 0 0)); | |
| --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1); | |
| --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); | |
| --ease-spring: cubic-bezier(0.34, 1.3, 0.64, 1); | |
| /* Soft, slightly overdamped curve used for most micro-interactions. */ | |
| --ease-soft: cubic-bezier(0.32, 0.72, 0, 1); | |
| --t-fast: 120ms var(--ease-soft); | |
| --t-med: 200ms var(--ease-soft); | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* Palette: Hugging Face. Tailwind cool grays (as on huggingface.co), */ | |
| /* #0b0f19 night background, HF yellow (#FFD21E) as the single accent. */ | |
| /* Every Kumo semantic token is re-pointed so the whole UI follows. */ | |
| /* ------------------------------------------------------------------ */ | |
| :root { | |
| --hf-yellow: #ffd21e; | |
| --hf-gray-50: #f9fafb; | |
| --hf-gray-100: #f3f4f6; | |
| --hf-gray-200: #e5e7eb; | |
| --hf-gray-300: #d1d5db; | |
| --hf-gray-400: #9ca3af; | |
| --hf-gray-500: #6b7280; | |
| --hf-gray-600: #4b5563; | |
| --hf-gray-700: #374151; | |
| --hf-gray-800: #1f2937; | |
| --hf-gray-850: #172030; | |
| --hf-gray-900: #111827; | |
| --hf-gray-950: #0b0f19; | |
| } | |
| :root[data-mode="dark"] { | |
| --hf-red: #f87171; | |
| --hf-orange: #fb923c; | |
| --hf-amber: #fbbf24; | |
| --hf-yellow-soft: #fde68a; | |
| --hf-green: #4ade80; | |
| --hf-emerald: #34d399; | |
| --hf-cyan: #67e8f9; | |
| --hf-sky: #7dd3fc; | |
| --hf-indigo: #a5b4fc; | |
| --hf-pink: #f9a8d4; | |
| --hf-fuchsia: #e879f9; | |
| --color-kumo-canvas: var(--hf-gray-950); | |
| --color-kumo-base: #0e1320; | |
| --color-kumo-elevated: #131a29; | |
| --color-kumo-overlay: #161e2e; | |
| --color-kumo-recessed: #080b13; | |
| --color-kumo-control: var(--hf-gray-950); | |
| --color-kumo-tint: var(--hf-gray-850); | |
| --color-kumo-fill: var(--hf-gray-800); | |
| --color-kumo-fill-hover: #29364a; | |
| --color-kumo-interact: var(--hf-gray-700); | |
| --color-kumo-line: var(--hf-gray-800); | |
| --color-kumo-hairline: #1a2232; | |
| --color-kumo-contrast: var(--hf-gray-200); | |
| --color-kumo-shadow-edge: rgba(229, 231, 235, 0.06); | |
| --color-kumo-shadow-drop: rgba(0, 0, 0, 0.4); | |
| --color-kumo-arrow-edge: transparent; | |
| --color-kumo-arrow-stroke: var(--hf-gray-800); | |
| --color-kumo-brand: var(--hf-yellow); | |
| --color-kumo-brand-hover: #ffdc4d; | |
| --color-kumo-focus: var(--hf-yellow); | |
| --color-kumo-success: var(--hf-green); | |
| --color-kumo-danger: var(--hf-red); | |
| --color-kumo-warning: var(--hf-orange); | |
| --color-kumo-info: var(--hf-sky); | |
| --color-kumo-success-tint: rgba(74, 222, 128, 0.12); | |
| --color-kumo-danger-tint: rgba(248, 113, 113, 0.12); | |
| --color-kumo-warning-tint: rgba(251, 146, 60, 0.13); | |
| --color-kumo-info-tint: rgba(125, 211, 252, 0.12); | |
| --text-color-kumo-default: var(--hf-gray-200); | |
| --text-color-kumo-strong: var(--hf-gray-50); | |
| --text-color-kumo-subtle: var(--hf-gray-400); | |
| --text-color-kumo-placeholder: var(--hf-gray-500); | |
| --text-color-kumo-inactive: var(--hf-gray-600); | |
| --text-color-kumo-inverse: var(--hf-gray-950); | |
| --text-color-kumo-brand: var(--hf-yellow); | |
| --text-color-kumo-link: var(--hf-yellow-soft); | |
| --text-color-kumo-success: var(--hf-green); | |
| --text-color-kumo-danger: var(--hf-red); | |
| --text-color-kumo-warning: var(--hf-orange); | |
| --text-color-kumo-info: var(--hf-sky); | |
| --accent-soft: rgba(255, 210, 30, 0.12); | |
| --accent-ink: var(--hf-gray-950); | |
| --color-port-text: var(--hf-amber); | |
| --color-port-number: var(--hf-cyan); | |
| --color-port-boolean: var(--hf-green); | |
| --color-port-image: var(--hf-sky); | |
| --color-port-audio: var(--hf-orange); | |
| --color-port-video: var(--hf-pink); | |
| --color-port-file: var(--hf-indigo); | |
| --color-port-gallery: var(--hf-fuchsia); | |
| --color-port-json: var(--hf-red); | |
| --color-port-any: var(--hf-gray-500); | |
| } | |
| :root:not([data-mode="dark"]) { | |
| --hf-red: #dc2626; | |
| --hf-orange: #ea580c; | |
| --hf-amber: #d97706; | |
| --hf-amber-ink: #a16207; | |
| --hf-green: #16a34a; | |
| --hf-cyan: #0891b2; | |
| --hf-sky: #0284c7; | |
| --hf-indigo: #4f46e5; | |
| --hf-pink: #db2777; | |
| --hf-fuchsia: #c026d3; | |
| --color-kumo-canvas: var(--hf-gray-50); | |
| --color-kumo-base: #ffffff; | |
| --color-kumo-elevated: #ffffff; | |
| --color-kumo-overlay: #ffffff; | |
| --color-kumo-recessed: var(--hf-gray-100); | |
| --color-kumo-control: #ffffff; | |
| --color-kumo-tint: var(--hf-gray-100); | |
| --color-kumo-fill: var(--hf-gray-100); | |
| --color-kumo-fill-hover: var(--hf-gray-200); | |
| --color-kumo-interact: var(--hf-gray-300); | |
| --color-kumo-line: var(--hf-gray-200); | |
| --color-kumo-hairline: #edeff2; | |
| --color-kumo-contrast: var(--hf-gray-900); | |
| --color-kumo-shadow-edge: rgba(17, 24, 39, 0.1); | |
| --color-kumo-shadow-drop: rgba(17, 24, 39, 0.06); | |
| --color-kumo-arrow-edge: rgba(17, 24, 39, 0.1); | |
| --color-kumo-arrow-stroke: transparent; | |
| --color-kumo-brand: var(--hf-yellow); | |
| --color-kumo-brand-hover: #f5c400; | |
| --color-kumo-focus: #f59e0b; | |
| --color-kumo-success: var(--hf-green); | |
| --color-kumo-danger: var(--hf-red); | |
| --color-kumo-warning: var(--hf-orange); | |
| --color-kumo-info: var(--hf-sky); | |
| --color-kumo-success-tint: rgba(22, 163, 74, 0.1); | |
| --color-kumo-danger-tint: rgba(220, 38, 38, 0.08); | |
| --color-kumo-warning-tint: rgba(234, 88, 12, 0.1); | |
| --color-kumo-info-tint: rgba(2, 132, 199, 0.08); | |
| --text-color-kumo-default: var(--hf-gray-700); | |
| --text-color-kumo-strong: var(--hf-gray-900); | |
| --text-color-kumo-subtle: var(--hf-gray-500); | |
| --text-color-kumo-placeholder: var(--hf-gray-400); | |
| --text-color-kumo-inactive: var(--hf-gray-300); | |
| --text-color-kumo-inverse: #ffffff; | |
| /* Yellow text is unreadable on white; brand text uses HF's amber ink. */ | |
| --text-color-kumo-brand: var(--hf-amber-ink); | |
| --text-color-kumo-link: var(--hf-amber-ink); | |
| --text-color-kumo-success: var(--hf-green); | |
| --text-color-kumo-danger: var(--hf-red); | |
| --text-color-kumo-warning: #c2410c; | |
| --text-color-kumo-info: var(--hf-sky); | |
| --accent-soft: rgba(255, 210, 30, 0.2); | |
| --accent-ink: var(--hf-gray-900); | |
| --color-port-text: var(--hf-amber); | |
| --color-port-number: var(--hf-cyan); | |
| --color-port-boolean: var(--hf-green); | |
| --color-port-image: var(--hf-sky); | |
| --color-port-audio: var(--hf-orange); | |
| --color-port-video: var(--hf-pink); | |
| --color-port-file: var(--hf-indigo); | |
| --color-port-gallery: var(--hf-fuchsia); | |
| --color-port-json: var(--hf-red); | |
| --color-port-any: var(--hf-gray-400); | |
| } | |
| /* Kumo's primary button lightens the brand with white and forces white | |
| text, which falls apart on yellow. Keep the fill solid, flat, dark ink. | |
| Lives in `base` so its !important outranks the utility layer's. */ | |
| @layer base { | |
| [data-kumo-component="Button"][style*="kumo-button-emphasis"] { | |
| --kumo-button-emphasis-bg: var(--color-kumo-brand) ; | |
| --kumo-button-emphasis-ring: color-mix(in oklch, var(--color-kumo-brand), black 12%) ; | |
| --kumo-button-emphasis-gradient-start: var(--color-kumo-brand) ; | |
| --kumo-button-emphasis-gradient-end: var(--color-kumo-brand) ; | |
| color: var(--accent-ink) ; | |
| } | |
| [data-kumo-component="Button"][style*="kumo-button-emphasis"]:hover { | |
| --kumo-button-emphasis-bg: var(--color-kumo-brand-hover) ; | |
| --kumo-button-emphasis-gradient-start: var(--color-kumo-brand-hover) ; | |
| --kumo-button-emphasis-gradient-end: var(--color-kumo-brand-hover) ; | |
| } | |
| } | |
| /* Kumo's Switch hard-codes Tailwind blue; follow the accent instead. */ | |
| [data-kumo-component="Switch"][data-checked] { | |
| background: var(--color-kumo-brand); | |
| --tw-ring-color: var(--color-kumo-brand); | |
| } | |
| [data-kumo-component="Switch"][data-checked] > * { | |
| background: var(--accent-ink); | |
| } | |
| @layer base { | |
| html, | |
| body, | |
| #root { | |
| height: 100%; | |
| margin: 0; | |
| overscroll-behavior: none; | |
| } | |
| body { | |
| font-family: var(--font-sans); | |
| font-feature-settings: "tnum"; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| text-rendering: optimizeLegibility; | |
| background: var(--color-kumo-canvas); | |
| color: var(--text-color-kumo-default); | |
| user-select: none; | |
| } | |
| ::selection { | |
| background: color-mix(in oklch, var(--color-kumo-brand) 28%, transparent); | |
| color: var(--text-color-kumo-strong); | |
| } | |
| input, | |
| textarea { | |
| user-select: text; | |
| } | |
| button { | |
| font: inherit; | |
| } | |
| *:focus-visible { | |
| outline: 2px solid var(--color-kumo-brand); | |
| outline-offset: 2px; | |
| } | |
| ::-webkit-scrollbar { | |
| width: 10px; | |
| height: 10px; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: var(--color-kumo-interact); | |
| border: 3px solid transparent; | |
| border-radius: 999px; | |
| background-clip: padding-box; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: var(--text-color-kumo-subtle); | |
| background-clip: padding-box; | |
| border: 3px solid transparent; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* Theme switch: a short root crossfade; the mode thumb slides in its */ | |
| /* own layer so it glides instead of jumping. */ | |
| /* ------------------------------------------------------------------ */ | |
| ::view-transition { | |
| pointer-events: none; | |
| } | |
| ::view-transition-old(root), | |
| ::view-transition-new(root) { | |
| animation-duration: 180ms; | |
| animation-timing-function: var(--ease-soft); | |
| } | |
| html[data-vt="theme"] .mode-toggle__thumb { | |
| view-transition-name: mode-thumb; | |
| } | |
| html[data-vt="theme"] .mode-toggle > [data-mode="light"] { | |
| view-transition-name: mode-light; | |
| } | |
| html[data-vt="theme"] .mode-toggle > [data-mode="dark"] { | |
| view-transition-name: mode-dark; | |
| } | |
| ::view-transition-group(mode-thumb), | |
| ::view-transition-group(mode-light), | |
| ::view-transition-group(mode-dark) { | |
| animation-duration: 320ms; | |
| animation-timing-function: var(--ease-soft); | |
| } | |
| ::view-transition-group(mode-light), | |
| ::view-transition-group(mode-dark) { | |
| z-index: 1; | |
| } | |
| /* Light / Dark segmented toggle with a sliding thumb. Driven by */ | |
| /* html[data-mode] so it never desyncs from the actual theme. */ | |
| .mode-toggle { | |
| position: relative; | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 2px; | |
| padding: 3px; | |
| border-radius: 8px; | |
| background: var(--color-kumo-tint); | |
| } | |
| .mode-toggle__thumb { | |
| position: absolute; | |
| top: 3px; | |
| bottom: 3px; | |
| left: 3px; | |
| width: calc(50% - 4px); | |
| border-radius: 6px; | |
| background: var(--color-kumo-elevated); | |
| box-shadow: 0 0 0 1px var(--color-kumo-hairline); | |
| transition: translate 240ms var(--ease-soft); | |
| } | |
| html[data-mode="dark"] .mode-toggle__thumb { | |
| translate: calc(100% + 2px) 0; | |
| } | |
| .mode-toggle > button { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 6px; | |
| height: 26px; | |
| border: 0; | |
| border-radius: 6px; | |
| background: transparent; | |
| color: var(--text-color-kumo-subtle); | |
| font-size: 12px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: color var(--t-fast); | |
| } | |
| .mode-toggle > button:hover, | |
| html[data-mode="light"] .mode-toggle > [data-mode="light"], | |
| html[data-mode="dark"] .mode-toggle > [data-mode="dark"] { | |
| color: var(--text-color-kumo-strong); | |
| } | |
| /* Entrance for freshly mounted panels / sections. */ | |
| @keyframes rise-in { | |
| from { | |
| opacity: 0; | |
| transform: translateY(5px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: none; | |
| } | |
| } | |
| .rise-in { | |
| animation: rise-in 240ms var(--ease-soft) both; | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* Utilities */ | |
| /* ------------------------------------------------------------------ */ | |
| @utility hairline-b { | |
| border-bottom: 1px solid var(--color-kumo-hairline); | |
| } | |
| @utility hairline-t { | |
| border-top: 1px solid var(--color-kumo-hairline); | |
| } | |
| @utility hairline-l { | |
| border-left: 1px solid var(--color-kumo-hairline); | |
| } | |
| @utility hairline-r { | |
| border-right: 1px solid var(--color-kumo-hairline); | |
| } | |
| @utility tabular { | |
| font-variant-numeric: tabular-nums; | |
| } | |
| /* Port colour helper: `port-color-image` sets --port-color */ | |
| .port-color-text { | |
| --port-color: var(--color-port-text); | |
| } | |
| .port-color-number { | |
| --port-color: var(--color-port-number); | |
| } | |
| .port-color-boolean { | |
| --port-color: var(--color-port-boolean); | |
| } | |
| .port-color-image { | |
| --port-color: var(--color-port-image); | |
| } | |
| .port-color-audio { | |
| --port-color: var(--color-port-audio); | |
| } | |
| .port-color-video { | |
| --port-color: var(--color-port-video); | |
| } | |
| .port-color-file { | |
| --port-color: var(--color-port-file); | |
| } | |
| .port-color-gallery { | |
| --port-color: var(--color-port-gallery); | |
| } | |
| .port-color-json { | |
| --port-color: var(--color-port-json); | |
| } | |
| .port-color-any { | |
| --port-color: var(--color-port-any); | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* React Flow overrides */ | |
| /* ------------------------------------------------------------------ */ | |
| .react-flow { | |
| --xy-background-color: var(--color-kumo-canvas); | |
| --xy-selection-background-color: color-mix( | |
| in oklch, | |
| var(--color-kumo-brand) 8%, | |
| transparent | |
| ); | |
| --xy-selection-border: 1px solid | |
| color-mix(in oklch, var(--color-kumo-brand) 60%, transparent); | |
| --xy-edge-stroke: var(--color-kumo-interact); | |
| --xy-edge-stroke-width: 2; | |
| --xy-minimap-background-color: var(--color-kumo-base); | |
| --xy-minimap-mask-background-color: color-mix( | |
| in oklch, | |
| var(--color-kumo-canvas) 70%, | |
| transparent | |
| ); | |
| --xy-minimap-mask-stroke-color: var(--color-kumo-line); | |
| --xy-minimap-node-background-color: var(--color-kumo-interact); | |
| --xy-minimap-node-stroke-color: transparent; | |
| background: var(--color-kumo-canvas); | |
| font-size: 12px; | |
| } | |
| .react-flow__pane { | |
| cursor: default; | |
| } | |
| .react-flow__pane.dragging { | |
| cursor: grabbing; | |
| } | |
| /* The whole node body is a drag surface; only live controls opt out. */ | |
| .react-flow__node { | |
| cursor: grab; | |
| /* Promote each node to its own compositor layer so a move is a pure | |
| transform update rather than a repaint of the node's contents. */ | |
| will-change: transform; | |
| } | |
| .react-flow__node.dragging { | |
| cursor: grabbing; | |
| } | |
| .react-flow__node.dragging .canvas-node { | |
| border-color: var(--color-kumo-interact); | |
| box-shadow: | |
| 0 0 0 1px color-mix(in oklch, var(--node-accent) 35%, transparent), | |
| 0 12px 32px -12px var(--color-kumo-shadow-drop); | |
| } | |
| .react-flow__node.dragging .canvas-node .canvas-node__header { | |
| cursor: grabbing; | |
| } | |
| .react-flow__nodesselection-rect, | |
| .react-flow__selection { | |
| border-radius: 4px; | |
| } | |
| .react-flow__node.selected .canvas-node, | |
| .react-flow__node:focus-visible .canvas-node { | |
| --port-color: var(--color-port-any); | |
| --node-ring: var(--color-kumo-brand); | |
| --node-ring-width: 1.5px; | |
| } | |
| .react-flow__node:focus-visible { | |
| outline: none; | |
| } | |
| .react-flow__edge.selectable:hover .canvas-edge-path, | |
| .react-flow__edge.selected .canvas-edge-path { | |
| stroke-width: 3; | |
| } | |
| .react-flow__edge.updating .canvas-edge-path { | |
| stroke-dasharray: 6 6; | |
| opacity: 0.6; | |
| } | |
| .react-flow__edge.selected .canvas-edge-path { | |
| filter: saturate(1.3) brightness(1.15); | |
| } | |
| .react-flow__edge .canvas-edge-hit { | |
| stroke-width: 18; | |
| stroke: transparent; | |
| fill: none; | |
| cursor: pointer; | |
| } | |
| .react-flow__connectionline { | |
| pointer-events: none; | |
| } | |
| .react-flow__minimap { | |
| border-radius: 10px; | |
| border: 1px solid var(--color-kumo-line); | |
| overflow: hidden; | |
| margin: 0 ; | |
| } | |
| .react-flow__minimap svg { | |
| display: block; | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* Nodes */ | |
| /* ------------------------------------------------------------------ */ | |
| @keyframes node-in { | |
| from { | |
| opacity: 0; | |
| transform: scale(0.96) translateY(4px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: none; | |
| } | |
| } | |
| @keyframes node-pulse { | |
| 0%, | |
| 100% { | |
| box-shadow: 0 0 0 1.5px | |
| color-mix(in oklch, var(--node-accent) 70%, transparent); | |
| } | |
| 50% { | |
| box-shadow: 0 0 0 1.5px | |
| color-mix(in oklch, var(--node-accent) 25%, transparent); | |
| } | |
| } | |
| .canvas-node { | |
| --node-ring: var(--color-kumo-line); | |
| --node-ring-width: 1px; | |
| --node-accent: var(--color-kumo-interact); | |
| position: relative; | |
| background: var(--color-kumo-base); | |
| border-radius: 10px; | |
| box-shadow: 0 0 0 var(--node-ring-width) var(--node-ring); | |
| transition: | |
| box-shadow var(--t-fast), | |
| opacity 160ms var(--ease-soft), | |
| background-color var(--t-med); | |
| animation: node-in 220ms var(--ease-soft) both; | |
| } | |
| .canvas-node[data-status="running"] { | |
| animation: node-pulse 1.4s ease-in-out infinite; | |
| } | |
| .canvas-node[data-status="done"] { | |
| --node-ring: color-mix(in oklch, var(--color-kumo-success) 70%, transparent); | |
| } | |
| .canvas-node[data-status="error"] { | |
| --node-ring: var(--color-kumo-danger); | |
| } | |
| .react-flow__node.selected .canvas-node[data-status="running"] { | |
| animation: none; | |
| } | |
| .canvas-node[data-bypassed="true"] { | |
| opacity: 0.55; | |
| } | |
| .canvas-node[data-bypassed="true"] .canvas-node__header { | |
| background: repeating-linear-gradient( | |
| -45deg, | |
| color-mix(in oklch, var(--node-accent) 18%, transparent) 0 6px, | |
| transparent 6px 12px | |
| ); | |
| } | |
| .canvas-node__header { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| height: 32px; | |
| padding: 0 8px 0 12px; | |
| border-radius: 10px 10px 0 0; | |
| background: var(--color-kumo-tint); | |
| cursor: grab; | |
| overflow: hidden; | |
| } | |
| .canvas-node__header:active { | |
| cursor: grabbing; | |
| } | |
| .canvas-node__header { | |
| transition: border-radius 220ms var(--ease-soft); | |
| } | |
| .canvas-node[data-collapsed="true"] .canvas-node__header { | |
| border-radius: 10px; | |
| } | |
| /* A soft light that travels around the node's edge while it runs. Nothing | |
| paints over the content. */ | |
| @property --run-angle { | |
| syntax: "<angle>"; | |
| inherits: false; | |
| initial-value: 0deg; | |
| } | |
| .canvas-node__shimmer { | |
| position: absolute; | |
| inset: 0; | |
| z-index: 5; | |
| border-radius: 10px; | |
| padding: 1.5px; | |
| pointer-events: none; | |
| background: conic-gradient( | |
| from var(--run-angle), | |
| transparent 0deg, | |
| transparent 250deg, | |
| color-mix(in oklch, var(--node-accent) 55%, transparent) 300deg, | |
| var(--node-accent) 330deg, | |
| transparent 360deg | |
| ); | |
| mask: | |
| linear-gradient(#000 0 0) content-box, | |
| linear-gradient(#000 0 0); | |
| mask-composite: exclude; | |
| -webkit-mask-composite: xor; | |
| animation: run-light 2.2s linear infinite; | |
| } | |
| @keyframes run-light { | |
| to { | |
| --run-angle: 360deg; | |
| } | |
| } | |
| .canvas-node__dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 999px; | |
| background: var(--node-accent); | |
| flex: none; | |
| } | |
| .canvas-node__title { | |
| flex: 1; | |
| min-width: 0; | |
| font-size: 12.5px; | |
| font-weight: 500; | |
| letter-spacing: -0.005em; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| /* Collapse/expand animates the body's grid track from 1fr to 0fr. The | |
| padding lives on an inner element so the track can really reach 0. */ | |
| .canvas-node__body-wrap { | |
| display: grid; | |
| grid-template-rows: 1fr; | |
| transition: | |
| grid-template-rows 220ms var(--ease-soft), | |
| opacity 140ms var(--ease-soft); | |
| } | |
| .canvas-node[data-collapsed="true"] .canvas-node__body-wrap { | |
| grid-template-rows: 0fr; | |
| opacity: 0; | |
| pointer-events: none; | |
| } | |
| .canvas-node__body { | |
| min-height: 0; | |
| /* Clip vertically only: port dots hang 5px outside the node. */ | |
| overflow-x: visible; | |
| overflow-y: clip; | |
| } | |
| .canvas-node__body-inner { | |
| padding: 6px 0 8px; | |
| } | |
| .canvas-node__progress { | |
| position: absolute; | |
| left: 10px; | |
| right: 10px; | |
| bottom: 0; | |
| height: 2px; | |
| border-radius: 2px; | |
| background: color-mix(in oklch, var(--node-accent) 20%, transparent); | |
| overflow: hidden; | |
| } | |
| .canvas-node__progress > i { | |
| display: block; | |
| height: 100%; | |
| border-radius: 2px; | |
| background: var(--node-accent); | |
| transform-origin: left; | |
| transition: transform 120ms linear; | |
| } | |
| /* Extrapolated from past runs: softer, and eased to match the 250ms tick. */ | |
| .canvas-node__progress[data-estimated] i { | |
| opacity: 0.6; | |
| transition: transform 260ms linear; | |
| } | |
| /* Ports ----------------------------------------------------------- */ | |
| .port-row { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| height: 24px; | |
| align-items: center; | |
| } | |
| .port { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| height: 24px; | |
| font-size: 11.5px; | |
| color: var(--text-color-kumo-default); | |
| white-space: nowrap; | |
| min-width: 0; | |
| } | |
| .port--in { | |
| padding-left: 0; | |
| } | |
| .port--out { | |
| flex-direction: row-reverse; | |
| padding-right: 0; | |
| text-align: right; | |
| } | |
| .port__label { | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .port__type { | |
| font-family: var(--font-mono); | |
| font-size: 9.5px; | |
| letter-spacing: 0.04em; | |
| color: var(--text-color-kumo-placeholder); | |
| flex: none; | |
| } | |
| .port--in > .port__type { margin-left: -2px; } | |
| .port--out > .port__type { margin-right: -2px; } | |
| /* Widget rows: the type and the "pull out into an input node" button sit over the row's top-right | |
| corner and only show on hover, so the widget keeps its full width. */ | |
| .port__meta { | |
| position: absolute; | |
| top: 2px; | |
| right: 0; | |
| height: 24px; | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| padding-left: 6px; | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 120ms; | |
| } | |
| .port-row--widget:hover .port__meta, | |
| .port-row--widget:focus-within .port__meta { | |
| opacity: 1; | |
| pointer-events: auto; | |
| } | |
| .port__extract { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 5px; | |
| color: var(--text-color-kumo-subtle); | |
| background: var(--color-kumo-elevated, var(--color-kumo-base)); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line); | |
| } | |
| .port__extract:hover { | |
| color: var(--text-color-kumo-strong); | |
| background: var(--color-kumo-fill); | |
| } | |
| /* Handles are laid out inline in each row rather than absolutely | |
| positioned. React Flow measures their DOM rect, so this is safe. */ | |
| .canvas-node .react-flow__handle, | |
| .canvas-node .port__ghost { | |
| position: relative; | |
| top: auto; | |
| left: auto; | |
| right: auto; | |
| bottom: auto; | |
| transform: none; | |
| width: 10px; | |
| height: 10px; | |
| min-width: 0; | |
| min-height: 0; | |
| border-radius: 999px; | |
| border: 2px solid var(--color-kumo-base); | |
| background: var(--port-color); | |
| box-shadow: 0 0 0 1px var(--port-color); | |
| margin-left: -5px; | |
| transition: | |
| transform 120ms var(--ease-spring), | |
| opacity 120ms, | |
| box-shadow 120ms; | |
| cursor: crosshair; | |
| } | |
| .canvas-node .react-flow__handle.react-flow__handle-right, | |
| .canvas-node .port--out .port__ghost { | |
| margin-left: 0; | |
| margin-right: -5px; | |
| } | |
| /* Stand-in dot while the body animates shut; the live handles sit in the header. */ | |
| .canvas-node .port__ghost { | |
| flex: none; | |
| pointer-events: none; | |
| } | |
| /* Generous invisible hit target: the dot stays 10px, the grab zone is 28px. */ | |
| .canvas-node .react-flow__handle::before { | |
| content: ""; | |
| position: absolute; | |
| inset: -9px; | |
| border-radius: 999px; | |
| } | |
| /* Ports announce themselves when the pointer is over the node. */ | |
| .react-flow__node:hover .canvas-node .react-flow__handle { | |
| box-shadow: | |
| 0 0 0 1px var(--port-color), | |
| 0 0 0 4px color-mix(in oklch, var(--port-color) 22%, transparent); | |
| } | |
| .canvas-node .react-flow__handle:hover, | |
| .canvas-node .react-flow__handle.connectingfrom { | |
| transform: scale(1.35); | |
| } | |
| .canvas-node .react-flow__handle.valid-target { | |
| transform: scale(1.35); | |
| box-shadow: | |
| 0 0 0 1px var(--port-color), | |
| 0 0 0 5px color-mix(in oklch, var(--port-color) 30%, transparent); | |
| } | |
| .canvas-node .react-flow__handle.invalid-target { | |
| opacity: 0.25; | |
| } | |
| /* Widgets --------------------------------------------------------- */ | |
| .widget { | |
| display: flex; | |
| align-items: center; | |
| height: 24px; | |
| margin: 2px 10px; | |
| padding: 0 8px; | |
| border-radius: 6px; | |
| background: var(--color-kumo-recessed); | |
| font-size: 11.5px; | |
| color: var(--text-color-kumo-default); | |
| transition: background-color 120ms; | |
| } | |
| .widget:hover { | |
| background: var(--color-kumo-fill-hover); | |
| } | |
| [data-mode="dark"] .widget:hover { | |
| background: color-mix(in oklch, var(--color-kumo-recessed), white 4%); | |
| } | |
| .widget__label { | |
| flex: 1; | |
| min-width: 0; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .widget__value { | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| font-variant-numeric: tabular-nums; | |
| color: var(--text-color-kumo-strong); | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| max-width: 60%; | |
| } | |
| .widget__arrow { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 16px; | |
| height: 16px; | |
| margin: 0 -4px; | |
| border-radius: 4px; | |
| color: var(--text-color-kumo-placeholder); | |
| opacity: 0; | |
| transition: | |
| opacity 120ms, | |
| background-color 120ms, | |
| color 120ms; | |
| } | |
| .widget:hover .widget__arrow { | |
| opacity: 1; | |
| } | |
| .widget__arrow:hover { | |
| background: var(--color-kumo-fill); | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .widget__arrow:active { | |
| transform: translateY(0.5px); | |
| } | |
| .widget--number { | |
| cursor: grab; | |
| } | |
| .widget--number .widget__value { | |
| cursor: ew-resize; | |
| /* Give the scrub zone real width so it is easy to hit. */ | |
| min-width: 40%; | |
| text-align: right; | |
| padding-left: 8px; | |
| } | |
| .widget--number .widget__arrow { | |
| cursor: pointer; | |
| } | |
| .widget--number.is-editing { | |
| cursor: text; | |
| background: var(--color-kumo-control); | |
| box-shadow: 0 0 0 1.5px var(--color-kumo-brand); | |
| } | |
| .widget__input { | |
| flex: 1; | |
| min-width: 0; | |
| background: transparent; | |
| border: 0; | |
| outline: 0; | |
| padding: 0; | |
| font: inherit; | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| text-align: right; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .widget--slider { | |
| position: relative; | |
| overflow: hidden; | |
| cursor: ew-resize; | |
| } | |
| .widget--slider::before { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| width: calc(var(--fill, 0) * 100%); | |
| background: color-mix(in oklch, var(--node-accent) 14%, transparent); | |
| transition: width 60ms linear; | |
| pointer-events: none; | |
| } | |
| /* No easing while the pointer is down: the fill must track the hand. */ | |
| .widget--slider:active::before { | |
| transition: none; | |
| } | |
| .widget--slider > * { | |
| position: relative; | |
| } | |
| .widget--toggle { | |
| cursor: pointer; | |
| } | |
| .widget--select { | |
| cursor: pointer; | |
| } | |
| .widget--select[data-popup-open] { | |
| background: var(--color-kumo-fill); | |
| } | |
| .widget--text { | |
| cursor: grab; | |
| } | |
| .widget--text .widget__label { | |
| flex: none; | |
| max-width: 45%; | |
| } | |
| .widget__text { | |
| flex: 1; | |
| min-width: 0; | |
| height: 24px; | |
| line-height: 24px; | |
| margin: 0; | |
| padding: 0; | |
| border: 0; | |
| outline: 0; | |
| resize: none; | |
| overflow: hidden; | |
| background: transparent; | |
| font: inherit; | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| text-align: right; | |
| white-space: pre; | |
| color: var(--text-color-kumo-strong); | |
| cursor: text; | |
| } | |
| .widget__text-preview { | |
| flex: 1; | |
| max-width: none; | |
| margin-left: 8px; | |
| text-align: right; | |
| cursor: text; | |
| } | |
| .widget__text-preview[data-empty] { | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .widget__text::placeholder { | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .widget--text[data-multi] { | |
| flex-wrap: wrap; | |
| align-items: flex-start; | |
| height: auto; | |
| padding: 5px 8px 6px; | |
| cursor: default; | |
| } | |
| .widget--text[data-multi] .widget__label { | |
| flex: 0 0 100%; | |
| max-width: none; | |
| margin-bottom: 3px; | |
| font-size: 10.5px; | |
| line-height: 14px; | |
| } | |
| .widget--text[data-multi] .widget__text { | |
| flex: 0 0 100%; | |
| height: auto; | |
| min-height: 40px; | |
| max-height: 260px; | |
| overflow: auto; | |
| line-height: 1.45; | |
| text-align: left; | |
| white-space: pre-wrap; | |
| font-family: inherit; | |
| font-size: 11.5px; | |
| color: var(--text-color-kumo-default); | |
| } | |
| .widget__fold { | |
| flex: none; | |
| order: 3; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 16px; | |
| height: 16px; | |
| margin-left: 4px; | |
| border-radius: 4px; | |
| color: var(--text-color-kumo-subtle); | |
| cursor: pointer; | |
| } | |
| .widget__fold:hover { | |
| background: var(--color-kumo-fill); | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .widget--text[data-multi] { | |
| position: relative; | |
| } | |
| .widget--text[data-multi] .widget__label { | |
| padding-right: 20px; | |
| } | |
| .widget--text[data-multi] .widget__fold { | |
| position: absolute; | |
| top: 4px; | |
| right: 6px; | |
| margin: 0; | |
| } | |
| .widget--text:focus-within { | |
| background: var(--color-kumo-control); | |
| box-shadow: inset 0 0 0 1.5px var(--color-kumo-brand); | |
| } | |
| /* Preview thumbnail ------------------------------------------------- */ | |
| .node-preview { | |
| margin: 4px 10px 0; | |
| border-radius: 6px; | |
| overflow: hidden; | |
| aspect-ratio: 1; | |
| background: var(--color-kumo-recessed); | |
| position: relative; | |
| } | |
| .node-preview > svg, | |
| .node-preview > img { | |
| display: block; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| .node-preview__empty { | |
| position: absolute; | |
| inset: 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 6px; | |
| font-size: 11px; | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| /* Edges ------------------------------------------------------------ */ | |
| @keyframes edge-flow { | |
| to { | |
| stroke-dashoffset: -24; | |
| } | |
| } | |
| .canvas-edge-path { | |
| fill: none; | |
| stroke: var(--edge-color); | |
| stroke-width: 2; | |
| stroke-linecap: round; | |
| transition: | |
| stroke-width var(--t-fast), | |
| opacity 160ms var(--ease-soft); | |
| } | |
| .canvas-edge-flow { | |
| fill: none; | |
| stroke: color-mix(in oklch, var(--edge-color), white 40%); | |
| stroke-width: 2; | |
| stroke-linecap: round; | |
| stroke-dasharray: 6 18; | |
| animation: edge-flow 600ms linear infinite; | |
| pointer-events: none; | |
| } | |
| [data-mode="light"] .canvas-edge-flow, | |
| :root:not([data-mode="dark"]) .canvas-edge-flow { | |
| stroke: color-mix(in oklch, var(--edge-color), black 25%); | |
| } | |
| .canvas-edge-dim { | |
| opacity: 0.35; | |
| } | |
| /* A selected edge's SVG is lifted to z 1000; the label layer holding the | |
| remove button must sit above it or the stroke swallows the click. */ | |
| .react-flow__edgelabel-renderer { | |
| z-index: 1001; | |
| } | |
| .edge-delete { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 18px; | |
| height: 18px; | |
| border-radius: 999px; | |
| background: var(--color-kumo-base); | |
| color: var(--text-color-kumo-subtle); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line); | |
| pointer-events: all; | |
| cursor: pointer; | |
| transition: | |
| transform 120ms var(--ease-spring), | |
| color 120ms, | |
| box-shadow 120ms; | |
| } | |
| .edge-delete:hover { | |
| transform: scale(1.15); | |
| color: var(--text-color-kumo-danger); | |
| box-shadow: 0 0 0 1px var(--color-kumo-danger); | |
| } | |
| /* Library ----------------------------------------------------------- */ | |
| .lib-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| height: 30px; | |
| padding: 0 8px 0 10px; | |
| margin: 0 8px; | |
| border-radius: 7px; | |
| font-size: 12.5px; | |
| color: var(--text-color-kumo-default); | |
| cursor: grab; | |
| transition: | |
| background-color var(--t-fast), | |
| transform 160ms var(--ease-soft); | |
| } | |
| .lib-item:hover { | |
| background: var(--color-kumo-tint); | |
| } | |
| .lib-item:active { | |
| cursor: grabbing; | |
| transform: scale(0.985); | |
| } | |
| .lib-item[data-drop="true"] { | |
| background: var(--accent-soft); | |
| } | |
| .lib-item__dots { | |
| display: flex; | |
| gap: 3px; | |
| margin-left: auto; | |
| opacity: 0.9; | |
| } | |
| .lib-item__dots > i { | |
| display: block; | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 999px; | |
| background: var(--port-color); | |
| } | |
| /* Drag ghost rendered while dragging from the library */ | |
| .drag-ghost { | |
| position: fixed; | |
| top: -1000px; | |
| left: -1000px; | |
| pointer-events: none; | |
| padding: 6px 12px; | |
| border-radius: 8px; | |
| background: var(--color-kumo-base); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line); | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: var(--text-color-kumo-strong); | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| /* Panels ------------------------------------------------------------ */ | |
| .panel-section-title { | |
| font-size: 11px; | |
| font-weight: 500; | |
| letter-spacing: 0.04em; | |
| text-transform: uppercase; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .kbd { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| min-width: 18px; | |
| height: 18px; | |
| padding: 0 5px; | |
| border-radius: 4px; | |
| background: var(--color-kumo-recessed); | |
| box-shadow: inset 0 0 0 1px var(--color-kumo-hairline); | |
| font-family: var(--font-sans); | |
| font-size: 10.5px; | |
| font-weight: 500; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .history-thumb { | |
| border-radius: 6px; | |
| overflow: hidden; | |
| aspect-ratio: 1; | |
| background: var(--color-kumo-recessed); | |
| flex: none; | |
| } | |
| .history-thumb svg { | |
| display: block; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| /* Inspector slider (Base UI Slider primitive styled flat) */ | |
| .k-slider { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| height: 20px; | |
| width: 100%; | |
| touch-action: none; | |
| } | |
| .k-slider__track { | |
| position: relative; | |
| height: 4px; | |
| width: 100%; | |
| border-radius: 999px; | |
| background: var(--color-kumo-fill); | |
| } | |
| .k-slider__indicator { | |
| position: absolute; | |
| height: 100%; | |
| border-radius: 999px; | |
| background: var(--color-kumo-brand); | |
| } | |
| .k-slider__thumb { | |
| width: 14px; | |
| height: 14px; | |
| border-radius: 999px; | |
| background: var(--color-kumo-base); | |
| box-shadow: 0 0 0 1.5px var(--color-kumo-brand); | |
| transition: transform 120ms var(--ease-spring); | |
| } | |
| .k-slider__thumb:hover, | |
| .k-slider__thumb:focus-visible { | |
| transform: scale(1.15); | |
| outline: none; | |
| } | |
| .k-slider__thumb[data-dragging] { | |
| transform: scale(1.2); | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* Menus. Every menu is a Kumo DropdownMenu (Base UI underneath). */ | |
| /* Base UI portals them to <body> with no z-index, so a selected node */ | |
| /* (z 1000) or the minimap paints over them: lift the positioner. */ | |
| /* Kumo's popup animates on data-[state=open], which Base UI never sets */ | |
| /* (it emits data-starting-style / data-ending-style), hence no motion. */ | |
| /* ------------------------------------------------------------------ */ | |
| [data-base-ui-portal] > [role="presentation"][data-side] { | |
| z-index: 60; | |
| } | |
| [role="menu"][data-side], | |
| [role="listbox"][data-side] { | |
| min-width: 180px; | |
| padding: 5px; | |
| border-radius: 10px; | |
| /* Opaque: a menu is dense text and the canvas must not read through. */ | |
| background: var(--color-kumo-elevated); | |
| color: var(--text-color-kumo-default); | |
| box-shadow: | |
| 0 0 0 1px var(--color-kumo-line), | |
| 0 10px 28px -14px var(--color-kumo-shadow-drop); | |
| transform-origin: var(--transform-origin); | |
| transition: | |
| opacity 130ms ease, | |
| transform 190ms var(--ease-soft); | |
| } | |
| [role="menu"][data-side][data-starting-style], | |
| [role="menu"][data-side][data-ending-style], | |
| [role="listbox"][data-side][data-starting-style], | |
| [role="listbox"][data-side][data-ending-style] { | |
| opacity: 0; | |
| transform: scale(0.96) translateY(-5px); | |
| } | |
| /* Slide from whichever edge the menu is anchored to. */ | |
| [role="menu"][data-side="top"][data-starting-style], | |
| [role="menu"][data-side="top"][data-ending-style], | |
| [role="listbox"][data-side="top"][data-starting-style], | |
| [role="listbox"][data-side="top"][data-ending-style] { | |
| transform: scale(0.96) translateY(5px); | |
| } | |
| [role="menu"][data-side="right"][data-starting-style], | |
| [role="menu"][data-side="right"][data-ending-style], | |
| [role="menu"][data-side="inline-end"][data-starting-style], | |
| [role="menu"][data-side="inline-end"][data-ending-style] { | |
| transform: scale(0.96) translateX(-6px); | |
| } | |
| [role="menu"][data-side="left"][data-starting-style], | |
| [role="menu"][data-side="left"][data-ending-style], | |
| [role="menu"][data-side="inline-start"][data-starting-style], | |
| [role="menu"][data-side="inline-start"][data-ending-style] { | |
| transform: scale(0.96) translateX(6px); | |
| } | |
| /* Hopping between sibling menus swaps instantly; dismissals still fade. */ | |
| [role="menu"][data-side][data-instant="group"], | |
| [role="menu"][data-side][data-instant="trigger-change"] { | |
| transition-duration: 0s; | |
| } | |
| /* Rows ------------------------------------------------------------- */ | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] { | |
| gap: 8px; | |
| min-height: 30px; | |
| padding: 5px 8px; | |
| border-radius: 6px; | |
| font-size: 13px; | |
| font-weight: 450; | |
| line-height: 1.4; | |
| letter-spacing: -0.003em; | |
| color: var(--text-color-kumo-default); | |
| transition: | |
| background-color var(--t-fast), | |
| color var(--t-fast); | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] > a { | |
| gap: 8px; | |
| } | |
| /* data-highlighted paints the row; the brand focus ring on top is noise. */ | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"]:focus, | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"]:focus-visible { | |
| outline: none; | |
| box-shadow: none; | |
| --tw-ring-shadow: 0 0 #0000; | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][data-highlighted], | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][data-popup-open] { | |
| background: var(--color-kumo-tint); | |
| color: var(--text-color-kumo-strong); | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][data-disabled] { | |
| color: var(--text-color-kumo-inactive); | |
| opacity: 1; | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][class*="text-kumo-danger"] { | |
| color: var(--text-color-kumo-danger); | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][class*="text-kumo-danger"][data-highlighted] { | |
| background: color-mix(in oklch, var(--color-kumo-danger) 14%, transparent); | |
| color: var(--text-color-kumo-danger); | |
| } | |
| /* The 16px leading gutter: Kumo renders an icon three ways (raw element, | |
| 12px wrapper span, `mr-2 h-4 w-4` on sub-triggers). Every leading mark | |
| becomes one 16px box in the same place so labels line up. */ | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] > svg:first-child:not([class*="ml-auto"]), | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] > a > svg:first-child:not([class*="ml-auto"]), | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] > span:first-child:has(> svg) { | |
| flex: none; | |
| width: 16px; | |
| height: 16px; | |
| margin: 0; | |
| color: var(--text-color-kumo-subtle); | |
| transition: color var(--t-fast); | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"]:not([data-kumo-part="checkbox-item"]) > span:first-child:has(> svg) > svg { | |
| width: 16px; | |
| height: 16px; | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][data-highlighted] > svg:first-child:not([class*="ml-auto"]), | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"][data-highlighted] > span:first-child:has(> svg) { | |
| color: inherit; | |
| } | |
| /* The submenu caret sits at the far end, quieter than the label. */ | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="submenu-trigger"] > svg[class*="ml-auto"] { | |
| flex: none; | |
| width: 14px; | |
| height: 14px; | |
| margin-inline-start: auto; | |
| margin-inline-end: -2px; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| /* Ticks share the icon's box. */ | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="checkbox-item"] { | |
| padding-left: 32px; | |
| } | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="checkbox-item"] > span:first-child { | |
| left: 8px; | |
| color: var(--color-kumo-brand); | |
| } | |
| /* Kumo's radio item draws no tick of its own, so draw one and grow it in. */ | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="radio-item"] { | |
| padding-left: 32px; | |
| } | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="radio-item"]::before { | |
| content: ""; | |
| position: absolute; | |
| left: 8px; | |
| width: 16px; | |
| height: 16px; | |
| background: var(--color-kumo-brand); | |
| mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z'/%3E%3C/svg%3E") | |
| center / 12px 12px no-repeat; | |
| opacity: 0; | |
| transform: scale(0.7); | |
| transition: | |
| opacity var(--t-fast), | |
| transform 160ms var(--ease-soft); | |
| } | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="radio-item"][data-checked]::before { | |
| opacity: 1; | |
| transform: none; | |
| } | |
| [data-kumo-component="DropdownMenu"][data-kumo-part="radio-item"][data-checked] { | |
| color: var(--text-color-kumo-strong); | |
| } | |
| /* `selected` puts a tick after the label; keep it small and in the accent. */ | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] > span:last-child:not(:first-child):has(> svg) { | |
| flex: none; | |
| margin-inline-start: auto; | |
| padding-inline-start: 8px; | |
| color: var(--color-kumo-brand); | |
| } | |
| [data-kumo-component="DropdownMenu"][role^="menuitem"] > span:last-child:not(:first-child):has(> svg) > svg { | |
| width: 14px; | |
| height: 14px; | |
| } | |
| /* A menu with any leading mark indents its plain rows, so labels line up. */ | |
| [role="menu"][data-side]:has([role^="menuitem"] > svg:first-child:not([class*="ml-auto"])), | |
| [role="menu"][data-side]:has([role^="menuitem"] > a > svg:first-child:not([class*="ml-auto"])), | |
| [role="menu"][data-side]:has([data-kumo-part="checkbox-item"]), | |
| [role="menu"][data-side]:has([data-kumo-part="radio-item"]) { | |
| --menu-gutter: 32px; | |
| } | |
| [role="menu"][data-side] [role^="menuitem"]:not([data-kumo-part="checkbox-item"]):not([data-kumo-part="radio-item"]):not(:has(> svg:first-child:not([class*="ml-auto"]))):not(:has(> a > svg:first-child:not([class*="ml-auto"]))):not(:has(> span:first-child > svg)) { | |
| padding-left: var(--menu-gutter, 8px); | |
| } | |
| /* Trimmings ------------------------------------------------------- */ | |
| [role="menu"][data-side] [role="separator"] { | |
| height: 1px; | |
| margin: 5px -1px; | |
| background: var(--color-kumo-hairline); | |
| } | |
| [role="menu"][data-side] [role="group"] > [role="presentation"] { | |
| padding: 6px 8px 4px; | |
| font-size: 10.5px; | |
| font-weight: 600; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| /* Keyboard hints stay quiet and hug the right edge. */ | |
| [role="menu"][data-side] [role^="menuitem"] > span[class*="ml-auto"] { | |
| margin-inline-start: auto; | |
| padding-inline-start: 16px; | |
| font-family: var(--font-mono); | |
| font-size: 10.5px; | |
| font-variant-numeric: tabular-nums; | |
| letter-spacing: 0; | |
| opacity: 1; | |
| color: var(--text-color-kumo-inactive); | |
| } | |
| /* Grid dots only show while snapping is on. */ | |
| .react-flow__background.canvas-grid { | |
| transition: opacity 200ms var(--ease-soft); | |
| } | |
| /* Canvas controls (bottom-left) */ | |
| .canvas-ctls { | |
| display: flex; | |
| align-items: center; | |
| gap: 2px; | |
| padding: 3px; | |
| border-radius: 9px; | |
| background: var(--color-kumo-base); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line); | |
| } | |
| .canvas-ctls__sep { | |
| width: 1px; | |
| height: 14px; | |
| margin: 0 3px; | |
| background: var(--color-kumo-line); | |
| } | |
| .canvas-ctl { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| height: 26px; | |
| min-width: 26px; | |
| padding: 0; | |
| border-radius: 6px; | |
| color: var(--color-kumo-subtle); | |
| transition: | |
| background-color 120ms var(--ease-soft), | |
| color 120ms var(--ease-soft); | |
| } | |
| .canvas-ctl:hover { | |
| background: var(--color-kumo-tint); | |
| color: var(--color-kumo-strong); | |
| } | |
| .canvas-ctl:active { | |
| background: var(--color-kumo-fill); | |
| } | |
| .canvas-ctl[data-active] { | |
| color: var(--color-kumo-brand); | |
| } | |
| .canvas-ctl:focus-visible { | |
| outline: 2px solid var(--color-kumo-brand); | |
| outline-offset: -2px; | |
| } | |
| .canvas-ctl--zoom { | |
| min-width: 44px; | |
| padding: 0 6px; | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| font-variant-numeric: tabular-nums; | |
| color: var(--color-kumo-default); | |
| } | |
| /* View layers (canvas / pipeline) --------------------------------------- */ | |
| .view-layer { | |
| position: absolute; | |
| inset: 0; | |
| transition: | |
| opacity 220ms var(--ease-soft), | |
| transform 260ms var(--ease-soft), | |
| visibility 0s linear 220ms; | |
| } | |
| .view-layer[data-active="false"] { | |
| opacity: 0; | |
| visibility: hidden; | |
| transform: scale(0.985); | |
| pointer-events: none; | |
| } | |
| .view-layer[data-active="true"] { | |
| opacity: 1; | |
| visibility: visible; | |
| transform: none; | |
| transition-delay: 0s; | |
| } | |
| .view-switch { | |
| display: flex; | |
| gap: 2px; | |
| padding: 2px; | |
| border-radius: 8px; | |
| background: var(--color-kumo-tint); | |
| } | |
| .view-switch__btn { | |
| position: relative; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 26px; | |
| padding: 0 10px; | |
| border-radius: 6px; | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: var(--color-kumo-subtle); | |
| transition: color 140ms var(--ease-soft); | |
| } | |
| .view-switch__btn:hover { color: var(--color-kumo-default); } | |
| .view-switch__btn[data-active="true"] { color: var(--color-kumo-strong); } | |
| .view-switch__btn:focus-visible { outline: 2px solid var(--color-kumo-brand); outline-offset: -2px; } | |
| .view-switch__pill { | |
| position: absolute; | |
| inset: 0; | |
| border-radius: 6px; | |
| background: var(--color-kumo-base); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line), 0 1px 2px rgb(0 0 0 / 0.12); | |
| } | |
| /* Pipeline view --------------------------------------------------------- */ | |
| .pipe { | |
| position: absolute; | |
| inset: 0; | |
| overflow-y: auto; | |
| overflow-x: hidden; | |
| padding: 28px 24px 120px; | |
| } | |
| .pipe__col { | |
| width: min(100%, 560px); | |
| margin: 0 auto; | |
| min-height: 100%; | |
| } | |
| .pipe__list { list-style: none; margin: 0; padding: 0; } | |
| .pipe-item { position: relative; list-style: none; } | |
| .pipe__empty { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 10px; | |
| padding: 72px 24px; | |
| border-radius: 12px; | |
| border: 1px dashed var(--color-kumo-line); | |
| } | |
| /* connector between steps, with an insert button on the spine */ | |
| .pipe-insert { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| height: 28px; | |
| transition: height 160ms var(--ease-soft); | |
| } | |
| .pipe-insert[data-spine="true"]::before { | |
| content: ""; | |
| position: absolute; | |
| top: 0; | |
| bottom: 0; | |
| left: 50%; | |
| width: 2px; | |
| margin-left: -1px; | |
| border-radius: 1px; | |
| background: var(--color-kumo-line); | |
| } | |
| .pipe-insert__btn { | |
| position: relative; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 18px; | |
| height: 18px; | |
| border-radius: 999px; | |
| background: var(--color-kumo-base); | |
| color: var(--color-kumo-placeholder); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line); | |
| opacity: 0; | |
| transform: scale(0.7); | |
| transition: | |
| opacity 140ms var(--ease-soft), | |
| transform 160ms var(--ease-soft), | |
| color 140ms var(--ease-soft), | |
| background-color 140ms var(--ease-soft); | |
| } | |
| .pipe-insert:hover .pipe-insert__btn, | |
| .pipe-insert__btn:focus-visible, | |
| .pipe-insert[data-over="true"] .pipe-insert__btn { | |
| opacity: 1; | |
| transform: scale(1); | |
| } | |
| .pipe-insert__btn:hover, | |
| .pipe-insert[data-over="true"] .pipe-insert__btn { | |
| background: var(--color-kumo-brand); | |
| color: var(--accent-ink); | |
| box-shadow: none; | |
| } | |
| .pipe-insert[data-over="true"] { height: 44px; } | |
| .pipe-insert[data-over="true"]::after { | |
| content: ""; | |
| position: absolute; | |
| left: 8px; | |
| right: 8px; | |
| top: 50%; | |
| height: 2px; | |
| margin-top: -1px; | |
| border-radius: 1px; | |
| background: color-mix(in oklch, var(--color-kumo-brand) 55%, transparent); | |
| } | |
| /* block */ | |
| .pipe-block { | |
| --node-accent: var(--color-kumo-interact); | |
| position: relative; | |
| border-radius: 10px; | |
| background: var(--color-kumo-base); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line); | |
| overflow: hidden; | |
| transition: | |
| box-shadow 160ms var(--ease-soft), | |
| opacity 160ms var(--ease-soft); | |
| } | |
| .pipe-block[data-selected="true"] { | |
| box-shadow: | |
| 0 0 0 1px var(--node-accent), | |
| 0 0 0 4px color-mix(in oklch, var(--node-accent) 22%, transparent); | |
| } | |
| .pipe-block[data-bypassed="true"], | |
| .pipe-block[data-muted="true"] { opacity: 0.62; } | |
| .pipe-block[data-status="running"] { | |
| box-shadow: 0 0 0 1px color-mix(in oklch, var(--node-accent) 60%, var(--color-kumo-line)); | |
| } | |
| .pipe-block__head { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| height: 36px; | |
| padding: 0 8px 0 6px; | |
| background: var(--color-kumo-tint); | |
| border-bottom: 1px solid var(--color-kumo-line); | |
| overflow: hidden; | |
| transition: border-color 200ms var(--ease-soft); | |
| } | |
| .pipe-block[data-collapsed="true"] .pipe-block__head { border-bottom-color: transparent; } | |
| .pipe-block__grip { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 20px; | |
| height: 24px; | |
| border-radius: 5px; | |
| color: var(--color-kumo-placeholder); | |
| cursor: grab; | |
| touch-action: none; | |
| transition: color 120ms var(--ease-soft), background-color 120ms var(--ease-soft); | |
| } | |
| .pipe-block__grip:hover { color: var(--color-kumo-strong); background: var(--color-kumo-fill); } | |
| .pipe-block__grip:active { cursor: grabbing; } | |
| .pipe-block__index { | |
| min-width: 18px; | |
| font-family: var(--font-mono); | |
| font-size: 10.5px; | |
| font-variant-numeric: tabular-nums; | |
| color: var(--color-kumo-placeholder); | |
| } | |
| .pipe-block__title { | |
| flex: 1; | |
| min-width: 0; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| font-size: 12.5px; | |
| font-weight: 600; | |
| color: var(--color-kumo-strong); | |
| } | |
| .pipe-block__tag { | |
| padding: 1px 6px; | |
| border-radius: 4px; | |
| background: var(--color-kumo-fill); | |
| font-family: var(--font-mono); | |
| font-size: 9px; | |
| font-weight: 500; | |
| letter-spacing: 0.06em; | |
| color: var(--color-kumo-subtle); | |
| } | |
| .pipe-block__icon-btn { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 22px; | |
| height: 22px; | |
| border-radius: 5px; | |
| color: var(--color-kumo-subtle); | |
| transition: color 120ms var(--ease-soft), background-color 120ms var(--ease-soft); | |
| } | |
| .pipe-block__icon-btn:hover, | |
| .pipe-block__icon-btn[data-popup-open] { color: var(--color-kumo-strong); background: var(--color-kumo-fill); } | |
| /* collapse via grid track so it animates */ | |
| .pipe-block__body-wrap { display: grid; grid-template-rows: 1fr; transition: grid-template-rows 220ms var(--ease-soft); } | |
| .pipe-block[data-collapsed="true"] .pipe-block__body-wrap { grid-template-rows: 0fr; } | |
| .pipe-block__body { min-height: 0; overflow-y: clip; } | |
| .pipe-block__body-inner { padding: 6px 0 8px; } | |
| .pipe-block__inputs { padding: 2px 8px 4px; } | |
| .pipe-input { | |
| display: flex; | |
| flex-direction: column; | |
| min-height: 28px; | |
| } | |
| .pipe-input__head { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 8px; | |
| min-height: 28px; | |
| padding: 2px 0; | |
| min-width: 0; | |
| } | |
| /* Rows grow when a text widget expands; the dot and source picker stay on the first line. */ | |
| .pipe-input__head > .pipe-input__dot { margin-top: 8px; } | |
| .pipe-input__head > .pipe-input__name { line-height: 24px; } | |
| .pipe-input__head > .min-w-0 > .widget { margin: 0 10px; } | |
| .pipe-input__dot { | |
| width: 8px; | |
| height: 8px; | |
| flex: none; | |
| border-radius: 999px; | |
| background: var(--port-color); | |
| box-shadow: 0 0 0 2px color-mix(in oklch, var(--port-color) 25%, transparent); | |
| } | |
| .pipe-input__name { | |
| width: 96px; | |
| flex: none; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| font-size: 11.5px; | |
| color: var(--color-kumo-default); | |
| } | |
| .pipe-input__src { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| flex: 1; | |
| min-width: 0; | |
| height: 24px; | |
| padding: 0 6px 0 8px; | |
| border-radius: 6px; | |
| background: var(--color-kumo-tint); | |
| box-shadow: inset 0 0 0 1px var(--color-kumo-line); | |
| font-size: 11.5px; | |
| color: var(--color-kumo-strong); | |
| cursor: pointer; | |
| transition: background-color 120ms var(--ease-soft), box-shadow 120ms var(--ease-soft); | |
| } | |
| .pipe-input__src:hover, | |
| .pipe-input__src[data-popup-open] { background: var(--color-kumo-fill); } | |
| .pipe-input__src[data-empty="true"] { color: var(--color-kumo-placeholder); } | |
| .pipe-input__src[data-empty="true"] { box-shadow: none; border: 1px dashed var(--color-kumo-line); } | |
| .pipe-input__src-port { | |
| flex: none; | |
| padding: 0 5px; | |
| border-radius: 4px; | |
| background: var(--color-kumo-fill); | |
| font-family: var(--font-mono); | |
| font-size: 9.5px; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| color: var(--color-kumo-subtle); | |
| } | |
| .pipe-input__src-icon { display: none; } | |
| .pipe-block__widgets { padding: 0 2px; } | |
| .pipe-block__outputs { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 6px; | |
| padding: 6px 8px 0; | |
| } | |
| .pipe-out { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 5px; | |
| height: 20px; | |
| padding: 0 8px 0 6px; | |
| border-radius: 999px; | |
| background: var(--color-kumo-tint); | |
| font-family: var(--font-mono); | |
| font-size: 10px; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| color: var(--color-kumo-subtle); | |
| } | |
| .pipe-out[data-used="true"] { color: var(--color-kumo-default); } | |
| .pipe-out > i { | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 999px; | |
| background: var(--port-color); | |
| } | |
| .lib-item__remove { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 20px; | |
| height: 20px; | |
| margin-right: -4px; | |
| border-radius: 5px; | |
| color: var(--color-kumo-placeholder); | |
| opacity: 0; | |
| transition: opacity 120ms var(--ease-soft), color 120ms var(--ease-soft); | |
| } | |
| .lib-item:hover .lib-item__remove { opacity: 1; } | |
| .lib-item__remove:hover { color: var(--color-kumo-danger); background: var(--color-kumo-fill); } | |
| /* ---- Group node (canvas) ------------------------------------------- */ | |
| .group-node { | |
| position: relative; | |
| width: 100%; | |
| height: 100%; | |
| border-radius: 12px; | |
| border: 1px solid color-mix(in oklab, var(--color-kumo-brand) 35%, var(--color-kumo-line)); | |
| background: color-mix(in oklab, var(--color-kumo-brand) 6%, transparent); | |
| transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease; | |
| } | |
| .group-node[data-selected="true"] { | |
| border-color: var(--color-kumo-brand); | |
| box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-kumo-brand) 40%, transparent); | |
| } | |
| .group-node[data-collapsed="true"] { | |
| background: var(--color-kumo-base); | |
| border-color: var(--color-kumo-line); | |
| box-shadow: 0 1px 2px rgb(0 0 0 / 0.06), 0 8px 24px -12px rgb(0 0 0 / 0.25); | |
| } | |
| .group-node[data-collapsed="true"][data-selected="true"] { | |
| border-color: var(--color-kumo-brand); | |
| } | |
| .group-node__header { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 36px; | |
| padding: 0 10px 0 8px; | |
| border-bottom: 1px solid color-mix(in oklab, var(--color-kumo-brand) 20%, transparent); | |
| border-radius: 12px 12px 0 0; | |
| background: color-mix(in oklab, var(--color-kumo-brand) 8%, var(--color-kumo-base)); | |
| cursor: grab; | |
| user-select: none; | |
| } | |
| .group-node[data-collapsed="true"] .group-node__header { | |
| background: transparent; | |
| border-bottom-color: var(--color-kumo-line); | |
| } | |
| .group-node__title { | |
| flex: 1; | |
| min-width: 0; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| font-size: 12.5px; | |
| font-weight: 600; | |
| color: var(--color-kumo-strong); | |
| } | |
| .group-node__count { | |
| font-family: var(--font-mono); | |
| font-size: 10px; | |
| color: var(--color-kumo-subtle); | |
| } | |
| .group-node__ports { padding: 4px 0 6px; } | |
| .group-node__ports .port-row { display: grid; grid-template-columns: 1fr 1fr; } | |
| .group-node[data-status="running"] .group-node__header { position: relative; overflow: hidden; } | |
| /* ---- Pipeline groups ------------------------------------------------- */ | |
| .pipe-group { | |
| position: relative; | |
| border-radius: 12px; | |
| border: 1px solid color-mix(in oklab, var(--color-kumo-brand) 35%, var(--color-kumo-line)); | |
| background: color-mix(in oklab, var(--color-kumo-brand) 5%, var(--color-kumo-base)); | |
| transition: border-color 160ms ease, box-shadow 160ms ease; | |
| } | |
| .pipe-group[data-selected="true"] { | |
| border-color: var(--color-kumo-brand); | |
| box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-kumo-brand) 40%, transparent); | |
| } | |
| .pipe-group[data-collapsed="true"] { background: var(--color-kumo-base); } | |
| .pipe-group__head { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 38px; | |
| padding: 0 8px 0 6px; | |
| } | |
| .pipe-group__name { | |
| flex: 1; | |
| min-width: 0; | |
| background: transparent; | |
| border: 0; | |
| outline: 0; | |
| padding: 2px 4px; | |
| margin-left: -4px; | |
| border-radius: 6px; | |
| font-size: 12.5px; | |
| font-weight: 600; | |
| color: var(--color-kumo-strong); | |
| } | |
| .pipe-group__name:hover { background: color-mix(in oklab, var(--color-kumo-fill) 60%, transparent); } | |
| .pipe-group__name:focus { background: var(--color-kumo-fill); } | |
| .pipe-group__count { | |
| font-family: var(--font-mono); | |
| font-size: 10px; | |
| color: var(--color-kumo-subtle); | |
| white-space: nowrap; | |
| } | |
| .pipe-group__body, .pipe-group__summary { overflow: hidden; } | |
| .pipe-group__body-inner { | |
| padding: 0 10px 4px; | |
| border-top: 1px dashed color-mix(in oklab, var(--color-kumo-brand) 25%, transparent); | |
| } | |
| .pipe-group__summary-inner { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 0 10px 10px; | |
| } | |
| .pipe-group__ports { display: flex; flex-wrap: wrap; gap: 4px; } | |
| .pipe-group__body-inner > .pipe__list > .pipe-insert:first-child { height: 18px; } | |
| .pipe-group__body-inner > .pipe__list > .pipe-item:last-child > .pipe-insert { height: 18px; } | |
| .pipe-group__empty { | |
| margin: 4px 0 0; | |
| padding: 10px; | |
| text-align: center; | |
| font-size: 11px; | |
| color: var(--color-kumo-placeholder); | |
| border: 1px dashed var(--color-kumo-line); | |
| border-radius: 8px; | |
| } | |
| /* ---- Pipeline drag state -------------------------------------------- */ | |
| .pipe[data-dragging="true"] { cursor: grabbing; user-select: none; } | |
| .pipe[data-dragging="true"] .pipe-insert { height: 22px; } | |
| .pipe[data-dragging="true"] .pipe-insert[data-over="true"] { height: 44px; } | |
| .pipe-item[data-dragging="true"] { | |
| z-index: 20; | |
| pointer-events: none; | |
| transition: none; | |
| } | |
| .pipe-item[data-dragging="true"] > .pipe-block, | |
| .pipe-item[data-dragging="true"] > .pipe-group { | |
| box-shadow: 0 12px 32px -8px rgb(0 0 0 / 0.35), 0 0 0 1px var(--color-kumo-brand); | |
| opacity: 0.94; | |
| } | |
| .pipe-item[data-dragging="true"] > .pipe-insert { visibility: hidden; } | |
| /* Several outputs on one node: cap the stack so five music nodes still fit on a screen. */ | |
| .canvas-node__outputs { | |
| max-height: 360px; | |
| overflow: auto; | |
| overscroll-behavior: contain; | |
| } | |
| /* Output view ------------------------------------------------------- */ | |
| .node-output { | |
| margin: 4px 10px 0; | |
| border-radius: 6px; | |
| overflow: hidden; | |
| background: var(--color-kumo-recessed); | |
| position: relative; | |
| min-height: 28px; | |
| } | |
| .node-output > img, | |
| .node-output > video { | |
| display: block; | |
| width: 100%; | |
| max-height: 320px; | |
| object-fit: contain; | |
| background: var(--color-kumo-recessed); | |
| } | |
| .node-output > audio { | |
| display: block; | |
| width: 100%; | |
| height: 32px; | |
| } | |
| .node-output__text { | |
| margin: 0; | |
| padding: 7px 9px; | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| line-height: 1.45; | |
| color: var(--text-color-kumo-default); | |
| white-space: pre-wrap; | |
| word-break: break-word; | |
| max-height: 160px; | |
| overflow: auto; | |
| } | |
| .node-output__file { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| padding: 6px 9px; | |
| font-size: 11px; | |
| color: var(--text-color-kumo-default); | |
| text-decoration: none; | |
| } | |
| .node-output__file:hover { | |
| color: var(--color-kumo-brand); | |
| } | |
| .node-output__grid { | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 2px; | |
| } | |
| .node-output__grid img { | |
| display: block; | |
| width: 100%; | |
| aspect-ratio: 1; | |
| object-fit: cover; | |
| } | |
| .node-output__empty { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 6px; | |
| height: 28px; | |
| font-size: 11px; | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .node-output__open { | |
| position: absolute; | |
| top: 4px; | |
| right: 4px; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 5px; | |
| background: color-mix(in oklab, var(--color-kumo-base) 80%, transparent); | |
| color: var(--text-color-kumo-default); | |
| opacity: 0; | |
| transition: opacity 120ms ease-out; | |
| } | |
| .node-output:hover .node-output__open { | |
| opacity: 1; | |
| } | |
| .node-status { | |
| margin: 4px 10px 0; | |
| font-size: 10.5px; | |
| line-height: 1.4; | |
| color: var(--text-color-kumo-subtle); | |
| font-family: var(--font-mono); | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| .node-error { | |
| margin: 4px 10px 0; | |
| padding: 5px 8px; | |
| border-radius: 5px; | |
| font-size: 11px; | |
| line-height: 1.4; | |
| color: var(--text-color-kumo-danger); | |
| background: color-mix(in oklab, var(--color-kumo-danger) 12%, transparent); | |
| word-break: break-word; | |
| } | |
| /* Port row with an inline widget --------------------------------------- */ | |
| .port-row--widget { | |
| grid-template-columns: 1fr; | |
| padding-right: 0; | |
| } | |
| .port-row--widget { | |
| height: auto; | |
| min-height: 24px; | |
| } | |
| .port-row--widget .port--in { | |
| position: relative; | |
| padding-left: 0; | |
| min-width: 0; | |
| height: auto; | |
| min-height: 24px; | |
| align-items: flex-start; | |
| } | |
| /* Keep the dot on the first line when the widget grows taller. */ | |
| .port-row--widget .port--in > .react-flow__handle, | |
| .port-row--widget .port--in > .port__ghost { | |
| margin-top: 7px; | |
| } | |
| .port-row--widget .port--in > .widget { | |
| flex: 1; | |
| min-width: 0; | |
| margin: 0 10px 0 0; | |
| } | |
| .port-row--widget .port__label { | |
| display: none; | |
| } | |
| .port--in.is-linked .widget { | |
| opacity: 0.45; | |
| pointer-events: none; | |
| } | |
| /* File widget ------------------------------------------------------- */ | |
| .widget--file { | |
| gap: 6px; | |
| } | |
| .widget--file .widget__input { | |
| min-width: 0; | |
| flex: 1; | |
| } | |
| .widget__thumb { | |
| width: 18px; | |
| height: 18px; | |
| border-radius: 4px; | |
| object-fit: cover; | |
| flex: none; | |
| background: var(--color-kumo-recessed); | |
| } | |
| .widget--file .widget__arrow { | |
| opacity: 1; | |
| width: 18px; | |
| height: 18px; | |
| } | |
| /* Space search ------------------------------------------------------- */ | |
| .space-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| height: 40px; | |
| padding: 0 10px 0 14px; | |
| cursor: pointer; | |
| transition: background 100ms ease-out; | |
| } | |
| .space-row:hover { | |
| background: var(--color-kumo-tint); | |
| } | |
| .space-row[data-usable="false"] { | |
| opacity: 0.5; | |
| } | |
| .space-row__emoji { | |
| width: 20px; | |
| text-align: center; | |
| font-size: 14px; | |
| flex: none; | |
| } | |
| .space-row__main { | |
| min-width: 0; | |
| flex: 1; | |
| line-height: 1.25; | |
| } | |
| .space-row__title { | |
| font-size: 12.5px; | |
| font-weight: 500; | |
| color: var(--text-color-kumo-strong); | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| .space-row__meta { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| font-size: 10.5px; | |
| font-family: var(--font-mono); | |
| color: var(--text-color-kumo-subtle); | |
| overflow: hidden; | |
| white-space: nowrap; | |
| } | |
| .space-row__meta > span { | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .stage-dot { | |
| display: inline-block; | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 50%; | |
| flex: none; | |
| background: var(--color-kumo-hairline); | |
| } | |
| .stage-dot[data-stage="RUNNING"] { | |
| background: var(--color-kumo-success); | |
| } | |
| .stage-dot[data-stage="SLEEPING"], | |
| .stage-dot[data-stage="BUILDING"], | |
| .stage-dot[data-stage="APP_STARTING"] { | |
| background: var(--color-kumo-warning); | |
| } | |
| .stage-dot[data-stage="RUNTIME_ERROR"], | |
| .stage-dot[data-stage="BUILD_ERROR"], | |
| .stage-dot[data-stage="CONFIG_ERROR"] { | |
| background: var(--color-kumo-danger); | |
| } | |
| .wf-space__fix { flex: none; padding: 2px 8px; border-radius: 6px; font-size: 11px; font-weight: 500; color: var(--color-kumo-brand); text-decoration: none; } | |
| .wf-space__fix:hover { background: var(--color-kumo-tint); } | |
| .hw-tag { | |
| display: inline-block; | |
| padding: 0 4px; | |
| border-radius: 3px; | |
| font-size: 9.5px; | |
| font-weight: 600; | |
| letter-spacing: 0.02em; | |
| line-height: 14px; | |
| background: var(--color-kumo-fill); | |
| color: var(--text-color-kumo-subtle); | |
| flex: none; | |
| } | |
| .hw-tag[data-zero="true"] { | |
| background: color-mix(in oklab, var(--color-kumo-brand) 18%, transparent); | |
| color: var(--color-kumo-brand); | |
| } | |
| .history-thumb img { | |
| display: block; | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| } | |
| .avatar { | |
| width: 22px; | |
| height: 22px; | |
| border-radius: 50%; | |
| object-fit: cover; | |
| background: var(--color-kumo-recessed); | |
| } | |
| /* ---- Library: pin / hide / reorder --------------------------------- */ | |
| .lib-item__actions { | |
| display: none; | |
| align-items: center; | |
| gap: 2px; | |
| margin-right: -4px; | |
| } | |
| .lib-item:hover .lib-item__actions, | |
| .lib-item:focus-visible .lib-item__actions { | |
| display: inline-flex; | |
| } | |
| .lib-item:hover .lib-item__dots { | |
| display: none; | |
| } | |
| .lib-item__btn { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 5px; | |
| color: var(--text-color-kumo-subtle); | |
| transition: color var(--t-fast), background-color var(--t-fast); | |
| } | |
| .lib-item__btn:hover { | |
| color: var(--text-color-kumo-strong); | |
| background: var(--color-kumo-fill); | |
| } | |
| .lib-item__btn.is-danger:hover { | |
| color: var(--color-kumo-danger); | |
| } | |
| .lib-item__btn[data-active] { | |
| color: var(--color-kumo-brand); | |
| } | |
| .lib-item[data-hidden] { | |
| opacity: 0.55; | |
| } | |
| .lib-item[data-over] { | |
| position: relative; | |
| } | |
| .lib-item[data-over]::before { | |
| content: ""; | |
| position: absolute; | |
| left: 8px; | |
| right: 8px; | |
| height: 2px; | |
| border-radius: 2px; | |
| background: var(--color-kumo-brand); | |
| } | |
| .lib-item[data-over="before"]::before { top: -1px; } | |
| .lib-item[data-over="after"]::before { bottom: -1px; } | |
| .lib-footer { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 28px; | |
| margin: 6px 8px 0; | |
| padding: 0 10px; | |
| border-radius: 7px; | |
| font-size: 11px; | |
| color: var(--text-color-kumo-placeholder); | |
| transition: background-color var(--t-fast), color var(--t-fast); | |
| } | |
| .lib-footer:hover { | |
| color: var(--text-color-kumo-default); | |
| background: var(--color-kumo-tint); | |
| } | |
| /* ---- Context menu -------------------------------------------------- */ | |
| .ctx-menu { | |
| position: fixed; | |
| z-index: 60; | |
| min-width: 196px; | |
| padding: 4px; | |
| border-radius: 9px; | |
| background: var(--color-kumo-elevated, var(--color-kumo-base)); | |
| box-shadow: | |
| 0 0 0 1px var(--color-kumo-hairline), | |
| 0 12px 32px -8px rgb(0 0 0 / 0.45); | |
| animation: ctx-in 120ms var(--ease-soft); | |
| } | |
| @keyframes ctx-in { | |
| from { opacity: 0; transform: scale(0.97) translateY(-2px); } | |
| to { opacity: 1; transform: none; } | |
| } | |
| .ctx-menu__item { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| width: 100%; | |
| height: 28px; | |
| padding: 0 8px; | |
| border-radius: 6px; | |
| font-size: 12.5px; | |
| color: var(--text-color-kumo-default); | |
| text-align: left; | |
| } | |
| .ctx-menu__item:hover:not(:disabled) { | |
| background: var(--color-kumo-tint); | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .ctx-menu__item:disabled { opacity: 0.45; } | |
| .ctx-menu__item.is-danger:hover:not(:disabled) { color: var(--color-kumo-danger); } | |
| .ctx-menu__sep { | |
| height: 1px; | |
| margin: 4px 6px; | |
| background: var(--color-kumo-hairline); | |
| } | |
| .ctx-menu__kbd { | |
| font-family: var(--font-mono); | |
| font-size: 10px; | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| /* ---- Copilot dock -------------------------------------------------- */ | |
| .copilot { | |
| position: absolute; | |
| right: 12px; | |
| bottom: 12px; | |
| z-index: 30; | |
| display: flex; | |
| flex-direction: column; | |
| width: 380px; | |
| max-height: min(68vh, 640px); | |
| border-radius: 12px; | |
| background: var(--color-kumo-base); | |
| box-shadow: | |
| 0 0 0 1px var(--color-kumo-hairline), | |
| 0 20px 48px -16px rgb(0 0 0 / 0.5); | |
| overflow: hidden; | |
| } | |
| .copilot__header { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 38px; | |
| padding: 0 6px 0 10px; | |
| border-bottom: 1px solid var(--color-kumo-hairline); | |
| flex: none; | |
| } | |
| .copilot__header > .flex-1 { min-width: 4px; } | |
| .copilot--side { | |
| position: static; | |
| width: 100%; | |
| height: 100%; | |
| max-height: none; | |
| border-radius: 0; | |
| box-shadow: none; | |
| } | |
| .copilot__pick { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 4px; | |
| height: 24px; | |
| max-width: 150px; | |
| padding: 0 4px 0 6px; | |
| border-radius: 6px; | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: var(--text-color-kumo-strong); | |
| transition: background-color var(--t-fast); | |
| } | |
| .copilot__pick:hover { background: var(--color-kumo-tint); } | |
| .copilot__pick[data-bad] { color: var(--color-kumo-danger); } | |
| .copilot__pick-caret { flex: none; color: var(--text-color-kumo-placeholder); } | |
| .copilot__list { | |
| flex: 1 1 auto; | |
| min-height: 120px; | |
| overflow-y: auto; | |
| padding: 12px 12px 6px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| scroll-behavior: smooth; | |
| } | |
| /* Never let flex squash a message; the list scrolls instead. */ | |
| .copilot__list > * { flex: none; } | |
| .copilot--side { min-height: 0; } | |
| .copilot__empty { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 10px; | |
| padding: 8px 2px 4px; | |
| font-size: 12px; | |
| line-height: 1.5; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .copilot__chip { | |
| text-align: left; | |
| padding: 7px 10px; | |
| border-radius: 8px; | |
| font-size: 12px; | |
| color: var(--text-color-kumo-default); | |
| box-shadow: inset 0 0 0 1px var(--color-kumo-hairline); | |
| transition: background-color var(--t-fast), color var(--t-fast); | |
| } | |
| .copilot__chip:hover { background: var(--color-kumo-tint); color: var(--text-color-kumo-strong); } | |
| .copilot__msg { | |
| font-size: 12.5px; | |
| line-height: 1.5; | |
| white-space: pre-wrap; | |
| overflow-wrap: anywhere; | |
| } | |
| .copilot__msg--user { | |
| align-self: flex-end; | |
| max-width: 88%; | |
| padding: 6px 10px; | |
| border-radius: 10px 10px 3px 10px; | |
| background: var(--color-kumo-brand); | |
| color: var(--accent-ink); | |
| } | |
| .copilot__msg--ai { color: var(--text-color-kumo-default); padding: 0 2px; } | |
| .copilot__msg--error { | |
| display: flex; | |
| gap: 6px; | |
| padding: 6px 8px; | |
| border-radius: 8px; | |
| font-size: 12px; | |
| color: var(--color-kumo-danger); | |
| background: color-mix(in oklab, var(--color-kumo-danger) 10%, transparent); | |
| } | |
| .copilot__tools { | |
| display: flex; | |
| flex-direction: column; | |
| border-radius: 9px; | |
| box-shadow: inset 0 0 0 1px var(--color-kumo-hairline); | |
| overflow: hidden; | |
| } | |
| .copilot__tools[data-awaiting="true"] { | |
| box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--color-kumo-brand) 55%, var(--color-kumo-hairline)); | |
| } | |
| .copilot__tool { | |
| position: relative; | |
| display: flex; | |
| flex-direction: column; | |
| font-size: 12px; | |
| color: var(--text-color-kumo-default); | |
| } | |
| .copilot__tool + .copilot__tool { border-top: 1px solid var(--color-kumo-hairline); } | |
| .copilot__tool-row { | |
| display: flex; | |
| align-items: stretch; | |
| min-height: 30px; | |
| } | |
| .copilot__tool-main { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| min-width: 0; | |
| flex: 1; | |
| padding: 4px 4px 4px 10px; | |
| text-align: left; | |
| transition: background-color var(--t-fast); | |
| } | |
| .copilot__tool-main:not(:disabled):hover { background: var(--color-kumo-tint); } | |
| .copilot__tool[data-kind="read"] .copilot__tool-text { color: var(--text-color-kumo-subtle); } | |
| .copilot__tool[data-decision="rejected"] .copilot__tool-text > :first-child { color: var(--text-color-kumo-placeholder); text-decoration: line-through; } | |
| .copilot__tool-kind { | |
| flex: none; | |
| width: 30px; | |
| font-family: var(--font-mono); | |
| font-size: 9.5px; | |
| font-weight: 600; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .copilot__tool[data-kind="edit"] .copilot__tool-kind { color: var(--color-kumo-brand); } | |
| .copilot__tool[data-kind="run"] .copilot__tool-kind { color: var(--color-kumo-warning); } | |
| .copilot__tool-text { | |
| display: flex; | |
| min-width: 0; | |
| flex: 1; | |
| align-items: baseline; | |
| gap: 6px; | |
| } | |
| .copilot__tool-text > :first-child { min-width: 0; flex: 0 1 auto; } | |
| .copilot__tool-text > :last-child:not(:first-child) { min-width: 0; flex: 1 1 auto; font-size: 10.5px; } | |
| .copilot__tool-end { | |
| display: inline-flex; | |
| width: 22px; | |
| height: 22px; | |
| flex: none; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .copilot__tool-caret { | |
| color: var(--text-color-kumo-placeholder); | |
| transition: transform var(--t-fast) var(--ease-soft); | |
| } | |
| .copilot__tool[data-expanded] .copilot__tool-caret { transform: rotate(90deg); } | |
| .copilot__tool-decide { | |
| display: flex; | |
| flex: none; | |
| align-items: center; | |
| gap: 2px; | |
| padding-right: 4px; | |
| } | |
| .copilot__tool-body { | |
| padding: 2px 10px 8px 48px; | |
| font-size: 10.5px; | |
| } | |
| .copilot__tool-body pre { | |
| margin: 2px 0 6px; | |
| padding: 6px 8px; | |
| border-radius: 6px; | |
| background: var(--color-kumo-tint); | |
| font-family: var(--font-mono); | |
| font-size: 10px; | |
| line-height: 1.45; | |
| max-height: 180px; | |
| overflow: auto; | |
| white-space: pre-wrap; | |
| word-break: break-word; | |
| color: var(--text-color-kumo-default); | |
| } | |
| .copilot__tool-label { | |
| display: block; | |
| font-size: 9.5px; | |
| font-weight: 600; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .copilot__tool-icon { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 14px; | |
| height: 14px; | |
| flex: none; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .copilot__tool[data-status="done"] .copilot__tool-icon { color: var(--color-kumo-success); } | |
| .copilot__tool[data-status="error"] .copilot__tool-icon { color: var(--color-kumo-danger); } | |
| .copilot__tool[data-decision="rejected"] .copilot__tool-icon { color: var(--text-color-kumo-placeholder); } | |
| .copilot__tool[data-kind="run"] .copilot__tool-dot { background: var(--color-kumo-warning); } | |
| .copilot__tool-dot { | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 999px; | |
| background: var(--color-kumo-brand); | |
| } | |
| .copilot__mini { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 22px; | |
| height: 22px; | |
| border-radius: 6px; | |
| color: var(--text-color-kumo-subtle); | |
| transition: background-color var(--t-fast), color var(--t-fast); | |
| } | |
| .copilot__mini:hover { background: var(--color-kumo-fill); } | |
| .copilot__mini.is-yes:hover { color: var(--color-kumo-success); } | |
| .copilot__mini.is-no:hover { color: var(--color-kumo-danger); } | |
| .copilot__tools-actions { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 28px; | |
| padding: 0 4px 0 10px; | |
| border-top: 1px solid var(--color-kumo-hairline); | |
| font-size: 10.5px; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .copilot__act { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 5px; | |
| height: 22px; | |
| padding: 0 7px; | |
| border-radius: 5px; | |
| font-size: 11.5px; | |
| font-weight: 500; | |
| color: var(--text-color-kumo-subtle); | |
| transition: background-color var(--t-fast), color var(--t-fast); | |
| } | |
| .copilot__act:hover { background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); } | |
| .copilot__act.is-yes { color: var(--color-kumo-brand); } | |
| .copilot__act.is-yes:hover { background: color-mix(in oklab, var(--color-kumo-brand) 14%, transparent); } | |
| .copilot__act .kbd { font-size: 9px; opacity: 0.7; } | |
| .copilot__thinking { | |
| display: flex; | |
| gap: 4px; | |
| padding: 4px 2px; | |
| } | |
| .copilot__thinking span { | |
| width: 5px; | |
| height: 5px; | |
| border-radius: 999px; | |
| background: var(--text-color-kumo-placeholder); | |
| animation: think 1s ease-in-out infinite; | |
| } | |
| .copilot__thinking span:nth-child(2) { animation-delay: 0.15s; } | |
| .copilot__thinking span:nth-child(3) { animation-delay: 0.3s; } | |
| @keyframes think { 0%, 100% { opacity: 0.3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-2px); } } | |
| .copilot__composer { | |
| display: flex; | |
| align-items: flex-end; | |
| gap: 6px; | |
| padding: 8px 8px 8px 12px; | |
| border-top: 1px solid var(--color-kumo-hairline); | |
| flex: none; | |
| } | |
| .copilot__textarea { | |
| flex: 1; | |
| min-height: 24px; | |
| max-height: 140px; | |
| padding: 3px 0; | |
| resize: none; | |
| background: transparent; | |
| font-size: 12.5px; | |
| line-height: 1.45; | |
| color: var(--text-color-kumo-strong); | |
| outline: none; | |
| } | |
| .copilot__textarea::placeholder { color: var(--text-color-kumo-placeholder); } | |
| .copilot__send { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 26px; | |
| height: 26px; | |
| flex: none; | |
| border-radius: 8px; | |
| background: var(--color-kumo-brand); | |
| color: var(--accent-ink); | |
| transition: opacity var(--t-fast), transform 120ms var(--ease-soft); | |
| } | |
| .copilot__send:disabled { opacity: 0.35; } | |
| .copilot__send:not(:disabled):active { transform: scale(0.94); } | |
| .copilot__send.is-stop { background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); } | |
| .copilot__input { | |
| width: 100%; | |
| padding: 0 8px; | |
| border-radius: 6px; | |
| font-size: 12px; | |
| color: var(--text-color-kumo-strong); | |
| background: var(--color-kumo-control); | |
| box-shadow: inset 0 0 0 1px var(--color-kumo-hairline); | |
| outline: none; | |
| } | |
| .copilot__input:focus { box-shadow: inset 0 0 0 1.5px var(--color-kumo-brand); } | |
| /* ---- Resizable side panels ----------------------------------------- */ | |
| /* Message turns: hover actions under each bubble */ | |
| .copilot__turn { display: flex; flex-direction: column; gap: 2px; } | |
| .copilot__turn--user { align-items: flex-end; } | |
| .copilot__turn--user .copilot__msg--user { max-width: 100%; } | |
| .copilot__turn--ai { align-items: flex-start; } | |
| .copilot__actions { | |
| display: flex; | |
| align-items: center; | |
| gap: 1px; | |
| height: 20px; | |
| opacity: 0; | |
| transition: opacity var(--t-fast); | |
| } | |
| .copilot__turn:hover .copilot__actions, | |
| .copilot__actions:focus-within { opacity: 1; } | |
| .copilot__actions .copilot__mini { width: 20px; height: 20px; color: var(--text-color-kumo-placeholder); } | |
| .copilot__actions .copilot__mini:hover { color: var(--text-color-kumo-strong); } | |
| .copilot__actions .copilot__mini:disabled { opacity: 0.4; pointer-events: none; } | |
| .copilot__versions { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 1px; | |
| margin-right: 4px; | |
| font-family: var(--font-mono); | |
| font-size: 10px; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .copilot__turn:has(.copilot__versions) .copilot__actions { opacity: 1; } | |
| .copilot__edit { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 4px; | |
| padding: 6px; | |
| border-radius: 10px; | |
| box-shadow: inset 0 0 0 1.5px var(--color-kumo-brand); | |
| } | |
| .copilot__edit .copilot__textarea { padding: 2px 4px; } | |
| .copilot__edit-actions { display: flex; align-items: center; gap: 2px; } | |
| .copilot__edit-actions > :first-child { flex: 1; min-width: 0; } | |
| .copilot__act:disabled { opacity: 0.4; pointer-events: none; } | |
| .copilot__msg--error .copilot__act { height: 20px; padding: 0 6px; font-size: 11px; } | |
| .copilot__signin { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| height: 36px; | |
| padding: 0 6px 0 12px; | |
| border-top: 1px solid var(--color-kumo-hairline); | |
| font-size: 11.5px; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .copilot__signin > span { flex: 1; } | |
| /* Copilot history ----------------------------------------------------- */ | |
| .copilot__hist-list { display: flex; flex-direction: column; gap: 1px; } | |
| .copilot__hist { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| border-radius: 8px; | |
| transition: background-color var(--t-fast); | |
| } | |
| .copilot__hist:hover { background: var(--color-kumo-tint); } | |
| .copilot__hist[data-active] { background: var(--color-kumo-tint); box-shadow: inset 2px 0 0 var(--color-kumo-brand); } | |
| .copilot__hist-main { | |
| display: flex; | |
| min-width: 0; | |
| flex: 1; | |
| flex-direction: column; | |
| gap: 1px; | |
| padding: 7px 34px 7px 10px; | |
| text-align: left; | |
| font-size: 12.5px; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .copilot__hist-meta { font-size: 10.5px; color: var(--text-color-kumo-placeholder); } | |
| .copilot__hist-del { | |
| position: absolute; | |
| right: 6px; | |
| top: 50%; | |
| display: inline-flex; | |
| width: 24px; | |
| height: 24px; | |
| align-items: center; | |
| justify-content: center; | |
| border-radius: 6px; | |
| color: var(--text-color-kumo-placeholder); | |
| opacity: 0; | |
| transform: translateY(-50%); | |
| transition: opacity var(--t-fast), color var(--t-fast), background-color var(--t-fast); | |
| } | |
| .copilot__hist:hover .copilot__hist-del, | |
| .copilot__hist-del:focus-visible { opacity: 1; } | |
| .copilot__hist-del:hover { background: var(--color-kumo-fill); color: var(--color-kumo-danger); } | |
| /* Copilot markdown ---------------------------------------------------- */ | |
| .md { font-size: 12.5px; line-height: 1.55; overflow-wrap: anywhere; } | |
| .md > * + * { margin-top: 6px; } | |
| .md p { margin: 0; } | |
| .md-h { margin: 0; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .md > .md-h { margin-top: 10px; } | |
| .md-h4 { font-size: 13px; } | |
| .md-h5, .md-h6 { font-size: 12.5px; } | |
| .md ul, .md ol { margin: 0; padding-left: 18px; } | |
| .md ul { list-style: disc; } | |
| .md ol { list-style: decimal; } | |
| .md li + li { margin-top: 2px; } | |
| .md li::marker { color: var(--text-color-kumo-placeholder); } | |
| .md blockquote { | |
| margin: 0; | |
| padding: 2px 0 2px 10px; | |
| border-left: 2px solid var(--color-kumo-hairline); | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .md hr { margin: 8px 0; border: 0; border-top: 1px solid var(--color-kumo-hairline); } | |
| .md-code { | |
| padding: 1px 4px; | |
| border-radius: 4px; | |
| background: var(--color-kumo-tint); | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .md-pre { | |
| position: relative; | |
| margin: 0; | |
| padding: 8px 10px; | |
| border-radius: 8px; | |
| background: var(--color-kumo-tint); | |
| box-shadow: inset 0 0 0 1px var(--color-kumo-hairline); | |
| font-family: var(--font-mono); | |
| font-size: 11px; | |
| line-height: 1.5; | |
| overflow: auto; | |
| white-space: pre; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .md-pre[data-lang]:not([data-lang=""])::before { | |
| content: attr(data-lang); | |
| position: absolute; | |
| top: 5px; | |
| right: 8px; | |
| font-size: 9.5px; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .md-link { color: inherit; font-weight: 500; text-decoration: underline; text-decoration-color: var(--color-kumo-brand); text-decoration-thickness: 2px; text-underline-offset: 3px; overflow-wrap: anywhere; } | |
| .md-link:hover { text-decoration-color: currentColor; } | |
| .md strong { font-weight: 600; color: var(--text-color-kumo-strong); } | |
| @keyframes pulse-dot { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.35; } | |
| } | |
| /* Per-token fade in while streaming */ | |
| .tok { | |
| display: inline; | |
| animation: tok-in 280ms var(--ease-soft) both; | |
| } | |
| @keyframes tok-in { | |
| from { opacity: 0; filter: blur(2px); } | |
| to { opacity: 1; filter: blur(0); } | |
| } | |
| .copilot__msg--ai[data-streaming] .md > :last-child::after { | |
| content: ""; | |
| display: inline-block; | |
| width: 5px; | |
| height: 12px; | |
| margin-left: 2px; | |
| vertical-align: -1px; | |
| border-radius: 1px; | |
| background: var(--color-kumo-brand); | |
| animation: pulse-dot 1s ease-in-out infinite; | |
| } | |
| .panel-resize { | |
| position: absolute; | |
| top: 0; | |
| bottom: 0; | |
| width: 9px; | |
| z-index: 20; | |
| cursor: col-resize; | |
| touch-action: none; | |
| } | |
| .panel-resize[data-side="left"] { right: -5px; } | |
| .panel-resize[data-side="right"] { left: -5px; } | |
| .panel-resize::after { | |
| content: ""; | |
| position: absolute; | |
| top: 0; | |
| bottom: 0; | |
| left: 4px; | |
| width: 1px; | |
| background: var(--color-kumo-brand); | |
| opacity: 0; | |
| transition: opacity 120ms ease 80ms; | |
| } | |
| .panel-resize:hover::after, | |
| .panel-resize[data-active]::after { | |
| opacity: 1; | |
| } | |
| .panel-resize[data-active]::after { | |
| transition-delay: 0s; | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .tok { animation: none; } | |
| *, | |
| *::before, | |
| *::after { | |
| animation-duration: 0.001ms ; | |
| animation-iteration-count: 1 ; | |
| transition-duration: 0.001ms ; | |
| } | |
| } | |
| /* Collapsed-node handles stack on the header's edges */ | |
| .canvas-node__collapsed-handles { | |
| position: absolute; | |
| inset: 0; | |
| pointer-events: none; | |
| } | |
| .canvas-node .react-flow__handle.handle--collapsed { | |
| position: absolute; | |
| top: 11px; | |
| margin: 0; | |
| pointer-events: all; | |
| } | |
| .canvas-node .react-flow__handle.handle--collapsed-left { | |
| left: -5px; | |
| } | |
| .canvas-node .react-flow__handle.handle--collapsed-right { | |
| right: -5px; | |
| } | |
| /* React Flow attribution: keep it, but make it quiet */ | |
| .react-flow__attribution { | |
| background: transparent; | |
| font-size: 9px; | |
| color: var(--text-color-kumo-placeholder); | |
| margin: 4px 6px; | |
| } | |
| .react-flow__attribution a { | |
| color: inherit; | |
| text-decoration: none; | |
| } | |
| /* Agent bridge dialog ------------------------------------------------- */ | |
| .bridge { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px 16px; font-size: 12.5px; } | |
| .bridge__title { font-size: 14px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .bridge__desc { color: var(--text-color-kumo-subtle); line-height: 1.45; margin-top: -6px; } | |
| .bridge__row { display: flex; align-items: center; gap: 12px; min-height: 24px; } | |
| .bridge__status { display: inline-flex; align-items: center; gap: 6px; color: var(--text-color-kumo-subtle); font-size: 12px; min-width: 0; } | |
| .bridge__status > i { width: 6px; height: 6px; border-radius: 50%; background: var(--text-color-kumo-placeholder); flex: none; } | |
| .bridge__status.is-connected > i { background: var(--color-kumo-success); } | |
| .bridge__status.is-connecting > i { background: var(--color-kumo-warning); animation: pulse-dot 1.2s ease-in-out infinite; } | |
| .bridge__status.is-error { color: var(--color-kumo-danger); } | |
| .bridge__status.is-error > i { background: var(--color-kumo-danger); } | |
| .bridge__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 10px; } | |
| .bridge__field { display: flex; flex-direction: column; gap: 4px; min-width: 0; } | |
| .bridge__field > span { font-size: 11px; font-weight: 500; color: var(--text-color-kumo-subtle); display: flex; align-items: center; gap: 6px; } | |
| .bridge__hint { font-style: normal; font-weight: 400; color: var(--text-color-kumo-placeholder); font-size: 11px; } | |
| .bridge__input, .bridge__token { | |
| height: 28px; display: flex; align-items: center; gap: 2px; padding: 0 4px 0 8px; border-radius: 6px; | |
| background: var(--color-kumo-recessed); border: 1px solid var(--color-kumo-hairline); | |
| font-family: var(--font-mono); font-size: 11.5px; color: var(--text-color-kumo-default); min-width: 0; | |
| } | |
| .bridge__input { width: 100%; outline: none; padding-right: 8px; } | |
| .bridge__input:focus { border-color: var(--color-kumo-brand); } | |
| .bridge__token > code { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } | |
| .bridge__snip { display: flex; flex-direction: column; gap: 4px; min-width: 0; } | |
| .bridge__snip-head { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 500; color: var(--text-color-kumo-subtle); min-height: 22px; } | |
| .bridge__snip-head > .flex-1 { min-width: 4px; } | |
| .bridge__pre { | |
| margin: 0; padding: 8px 10px; border-radius: 6px; background: var(--color-kumo-recessed); border: 1px solid var(--color-kumo-hairline); | |
| font-family: var(--font-mono); font-size: 11px; line-height: 1.5; color: var(--text-color-kumo-default); | |
| white-space: pre-wrap; word-break: break-all; max-height: 180px; overflow: auto; | |
| } | |
| .bridge__tabs { align-self: flex-start; } | |
| .bridge__foot { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-color-kumo-subtle); border-top: 1px solid var(--color-kumo-hairline); padding-top: 10px; margin-top: 2px; } | |
| .bridge__foot > .flex-1 { min-width: 4px; } | |
| .bridge__link { color: var(--color-kumo-brand); text-decoration: none; } | |
| .bridge__link:hover { text-decoration: underline; } | |
| .bridge__dot { color: var(--text-color-kumo-placeholder); } | |
| .bridge__calls { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-color-kumo-placeholder); } | |
| .bridge__keyrow { gap: 8px; } | |
| .bridge__keyrow > .bridge__hint { line-height: 1.4; } | |
| .bridge__adv > summary { cursor: pointer; font-size: 11.5px; font-weight: 500; color: var(--text-color-kumo-subtle); width: max-content; } | |
| .bridge__adv-body { display: flex; flex-direction: column; gap: 10px; padding-top: 10px; } | |
| /* Beginner surfaces: quick start, shortcuts, pre-run check, empty canvas ---- */ | |
| /* Every dialog: sits a little below the top, never taller than the viewport, scrolls inside when it is. | |
| (Kumo's Dialog ships with no padding and no height cap; the history dialog manages its own panes.) */ | |
| [role="dialog"]:not(.ctx-menu):not(.explorer) { top: 48px ; } | |
| [role="dialog"]:not(.ctx-menu):not(.explorer):not(.hist) { max-height: calc(100dvh - 96px); } | |
| [role="dialog"]:not(.ctx-menu):not(.explorer):not(.hist) { overflow-y: auto; overscroll-behavior: contain; } | |
| .batch { display: flex; flex-direction: column; padding: 18px 20px 16px; font-size: 12.5px; } | |
| .batch .precheck__foot { position: sticky; bottom: -16px; margin: 4px -20px -16px; padding: 12px 20px 16px; background: var(--color-kumo-base); border-top: 1px solid var(--color-kumo-hairline); } | |
| .welcome { | |
| display: flex; flex-direction: column; gap: 14px; padding: 20px; | |
| max-height: calc(100dvh - 4rem); overflow-y: auto; font-size: 13.5px; line-height: 1.45; | |
| } | |
| @media (min-width: 640px) { .welcome { max-height: calc(100dvh - 8rem); } } | |
| .welcome__head { display: flex; flex-direction: column; gap: 4px; } | |
| .welcome__title { margin: 0; font-size: 20px; font-weight: 600; line-height: 1.25; letter-spacing: -0.005em; color: var(--text-color-kumo-strong); } | |
| .welcome__lede { margin: 0; font-size: 14px; color: var(--text-color-kumo-subtle); } | |
| .welcome__entries { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } | |
| .welcome__entry { | |
| display: flex; align-items: center; gap: 12px; padding: 12px; text-align: left; | |
| border-radius: 10px; border: 1px solid var(--color-kumo-line); background: var(--color-kumo-recessed); | |
| color: var(--text-color-kumo-default); transition: border-color 0.15s var(--ease-soft), background 0.15s var(--ease-soft); | |
| } | |
| .welcome__entry:hover { border-color: var(--color-kumo-interact); background: var(--color-kumo-tint); } | |
| .welcome__entry[data-brand] { border-color: color-mix(in oklab, var(--color-kumo-brand) 55%, var(--color-kumo-line)); } | |
| .welcome__entry[data-brand]:hover { border-color: var(--color-kumo-brand); } | |
| .welcome__icon { | |
| flex: none; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; | |
| background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); | |
| } | |
| .welcome__entry[data-brand] .welcome__icon { background: var(--color-kumo-brand); color: var(--accent-ink); } | |
| .welcome__text { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; } | |
| .welcome__text strong { font-size: 14px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .welcome__text span { font-size: 13px; color: var(--text-color-kumo-subtle); } | |
| .welcome__go { flex: none; color: var(--text-color-kumo-subtle); transition: transform 0.15s var(--ease-soft), color 0.15s; } | |
| .welcome__entry:hover .welcome__go { transform: translateX(2px); color: var(--text-color-kumo-strong); } | |
| .welcome__section { display: flex; flex-direction: column; gap: 8px; } | |
| .welcome__label { | |
| display: flex; align-items: center; gap: 6px; margin: 0; font-size: 12px; font-weight: 600; | |
| letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-color-kumo-subtle); | |
| } | |
| .welcome__templates { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 0; padding: 0; list-style: none; } | |
| .welcome__templates button { | |
| display: flex; flex-direction: column; gap: 2px; width: 100%; height: 100%; padding: 10px 12px; text-align: left; | |
| border-radius: 8px; border: 1px solid var(--color-kumo-line); background: transparent; | |
| transition: border-color 0.15s var(--ease-soft), background 0.15s var(--ease-soft); | |
| } | |
| .welcome__templates button:hover { border-color: var(--color-kumo-interact); background: var(--color-kumo-tint); } | |
| .welcome__templates b { font-size: 13.5px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .welcome__templates span { | |
| font-size: 12.5px; color: var(--text-color-kumo-subtle); | |
| display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; | |
| } | |
| .welcome__steps { | |
| display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin: 0; padding: 0; list-style: none; | |
| font-size: 13px; color: var(--text-color-kumo-default); | |
| } | |
| .welcome__steps li { display: flex; align-items: center; gap: 8px; } | |
| .welcome__n { | |
| flex: none; display: grid; place-items: center; width: 20px; height: 20px; border-radius: 6px; | |
| background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); font-size: 11.5px; font-weight: 600; | |
| } | |
| .welcome__foot { | |
| display: flex; align-items: center; justify-content: space-between; gap: 12px; | |
| padding-top: 14px; border-top: 1px solid var(--color-kumo-hairline); font-size: 13px; color: var(--text-color-kumo-subtle); | |
| } | |
| @media (max-width: 639px) { | |
| .welcome { padding: 16px; gap: 12px; } | |
| .welcome__title { font-size: 18px; } | |
| .welcome__entries, .welcome__templates { grid-template-columns: minmax(0, 1fr); } | |
| .welcome__templates span { -webkit-line-clamp: 1; } | |
| .welcome__steps { flex-direction: column; align-items: flex-start; } | |
| .welcome__foot { flex-direction: column; align-items: stretch; } | |
| } | |
| .shortcuts { padding: 18px 20px 16px; } | |
| .shortcuts__list { display: flex; flex-direction: column; gap: 2px; margin-top: 12px; font-size: 12.5px; } | |
| .shortcuts__list > div { display: grid; grid-template-columns: 132px 1fr; align-items: center; gap: 10px; padding: 5px 0; border-bottom: 1px solid var(--color-kumo-hairline); } | |
| .shortcuts__list > div:last-child { border-bottom: 0; } | |
| .shortcuts__list dt { display: flex; flex-wrap: wrap; gap: 4px; } | |
| .shortcuts__list dd { color: var(--text-color-kumo-default); } | |
| .precheck { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px 16px; font-size: 12.5px; } | |
| .precheck__list { display: flex; flex-direction: column; gap: 4px; max-height: 320px; overflow: auto; } | |
| .precheck__list button { | |
| display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; border-radius: 8px; text-align: left; | |
| background: var(--color-kumo-recessed); border: 1px solid var(--color-kumo-hairline); color: var(--text-color-kumo-default); | |
| } | |
| .precheck__list button:hover { border-color: var(--color-kumo-brand); background: var(--color-kumo-tint); } | |
| .precheck__list button > svg:first-child { flex: none; color: var(--color-kumo-warning); } | |
| .precheck__list button > svg:last-child { flex: none; margin-left: auto; color: var(--text-color-kumo-subtle); } | |
| .precheck__list span { display: flex; flex-direction: column; gap: 1px; min-width: 0; } | |
| .precheck__list strong { font-weight: 500; color: var(--text-color-kumo-strong); } | |
| .precheck__list em { font-style: normal; font-size: 11.5px; color: var(--text-color-kumo-subtle); } | |
| .precheck__foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; } | |
| .canvas-empty { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; z-index: 4; } | |
| .canvas-empty__card { | |
| display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 22px 26px; pointer-events: auto; | |
| border-radius: 14px; background: color-mix(in oklab, var(--color-kumo-base) 88%, transparent); backdrop-filter: blur(8px); | |
| border: 1px solid var(--color-kumo-hairline); box-shadow: 0 8px 30px -12px rgb(0 0 0 / 0.35); text-align: center; | |
| } | |
| .canvas-empty__title { font-size: 15px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .canvas-empty__sub { margin-top: -8px; font-size: 12.5px; color: var(--text-color-kumo-subtle); } | |
| .canvas-empty__row { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; } | |
| .canvas-empty__btn { | |
| display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border-radius: 8px; font-size: 12.5px; font-weight: 500; | |
| border: 1px solid var(--color-kumo-hairline); background: var(--color-kumo-recessed); color: var(--text-color-kumo-strong); | |
| } | |
| .canvas-empty__btn:hover { background: var(--color-kumo-tint); border-color: var(--color-kumo-line); } | |
| .canvas-empty__btn--brand { background: var(--color-kumo-brand); border-color: transparent; color: var(--accent-ink); } | |
| .canvas-empty__btn--brand:hover { background: var(--color-kumo-brand); filter: brightness(1.08); } | |
| .canvas-empty__btn--brand .kbd { background: rgb(255 255 255 / 0.18); color: inherit; border-color: transparent; } | |
| .canvas-empty__link { font-size: 12px; color: var(--text-color-kumo-subtle); text-decoration: underline; text-underline-offset: 3px; } | |
| .canvas-empty__link:hover { color: var(--text-color-kumo-strong); } | |
| .node-error__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-top: 5px; } | |
| .node-error__ask { display: inline-block; font-weight: 500; text-decoration: underline; text-underline-offset: 2px; color: inherit; opacity: 0.85; } | |
| .node-error__ask:hover { opacity: 1; } | |
| .node-error__act { | |
| display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 6px; font-weight: 600; font-size: 11px; | |
| color: var(--color-kumo-base); background: var(--color-kumo-danger); text-decoration: none; | |
| } | |
| .node-error__act:hover { filter: brightness(1.08); } | |
| .node-error__act:active { transform: translateY(0.5px); } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| /* Run history dialog: list of runs on the left, compare / grid on the right. */ | |
| .hist { display: flex; flex-direction: column; gap: 0; width: min(96vw, 1040px) ; max-width: none ; max-height: min(calc(100dvh - 96px), 760px); padding: 0; overflow: hidden; } | |
| .hist__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 14px 14px 10px 20px; border-bottom: 1px solid var(--color-kumo-hairline); } | |
| .hist__head h2 { margin: 0; } | |
| .hist__empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 48px 24px; text-align: center; } | |
| .hist__body { display: grid; grid-template-columns: 260px minmax(0, 1fr); min-height: 0; flex: 1 1 auto; } | |
| .hist__list { display: flex; flex-direction: column; gap: 4px; padding: 10px; overflow-y: auto; border-right: 1px solid var(--color-kumo-hairline); background: var(--color-kumo-recessed); } | |
| .hist__card { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px; border-radius: 10px; text-align: left; border: 1px solid transparent; } | |
| .hist__card:hover { background: var(--color-kumo-tint); } | |
| .hist__card[data-active] { background: var(--color-kumo-base); border-color: var(--color-kumo-line); box-shadow: 0 1px 4px -2px rgb(0 0 0 / 0.2); } | |
| .hist__thumb { display: grid; flex: none; place-items: center; width: 44px; height: 44px; border-radius: 8px; overflow: hidden; color: var(--text-color-kumo-placeholder); background: var(--color-kumo-fill); } | |
| .hist__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; } | |
| .hist__thumb--grid { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; gap: 1px; place-items: stretch; } | |
| .hist__thumb--grid img { width: 100%; height: 100%; } | |
| .hist__thumb--grid > svg { grid-column: 1 / -1; place-self: center; } | |
| .hist__meta { display: block; margin-top: 2px; font-family: var(--font-mono); font-size: 10.5px; color: var(--text-color-kumo-subtle); font-variant-numeric: tabular-nums; } | |
| .hist__vary { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 4px; } | |
| .hist__vary > span { max-width: 100%; padding: 1px 6px; border-radius: 999px; font-size: 10px; color: var(--text-color-kumo-default); background: var(--color-kumo-fill); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } | |
| .hist__main { display: flex; flex-direction: column; gap: 14px; min-height: 0; padding: 16px 18px 14px; overflow-y: auto; } | |
| .hist__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; } | |
| .hist__col { min-width: 0; } | |
| .hist__col[data-then] { --node-accent: var(--color-kumo-brand); } | |
| .hist__col-title { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-color-kumo-subtle); } | |
| .hist__outs { display: flex; flex-direction: column; gap: 8px; } | |
| .hist__out .node-output { margin: 0; } | |
| .hist__out .node-output img, .hist__out .node-output video { width: 100%; max-height: 300px; object-fit: contain; border-radius: 8px; background: var(--color-kumo-recessed); } | |
| .hist__out .node-output__text { max-height: 140px; } | |
| .hist__out-cap { margin-top: 3px; font-size: 11px; color: var(--text-color-kumo-subtle); } | |
| .hist__none { padding: 24px 12px; border-radius: 10px; border: 1px dashed var(--color-kumo-line); font-size: 12px; text-align: center; color: var(--text-color-kumo-subtle); } | |
| .hist__diff { padding-top: 12px; border-top: 1px solid var(--color-kumo-hairline); } | |
| .hist__table { width: 100%; border-collapse: collapse; font-size: 12px; } | |
| .hist__table th { display: flex; flex-direction: column; gap: 1px; width: 180px; padding: 5px 8px 5px 0; text-align: left; font-weight: 500; color: var(--text-color-kumo-strong); } | |
| .hist__table th em { font-style: normal; font-size: 10.5px; color: var(--text-color-kumo-subtle); } | |
| .hist__table td { max-width: 0; padding: 5px 8px; vertical-align: top; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: var(--font-mono); font-size: 11.5px; color: var(--text-color-kumo-default); } | |
| .hist__table td[data-then] { color: var(--color-kumo-brand); } | |
| .hist__table tr + tr { border-top: 1px solid var(--color-kumo-hairline); } | |
| .hist__hint { margin: 6px 0 0; font-size: 11px; color: var(--text-color-kumo-subtle); } | |
| .hist__foot { display: flex; align-items: center; gap: 12px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--color-kumo-hairline); } | |
| .hist__grid-wrap { overflow: auto; } | |
| .hist__grid { display: grid; gap: 8px; align-items: stretch; } | |
| .hist__row-label { display: flex; align-items: center; padding: 4px 6px; font-size: 11.5px; line-height: 1.35; color: var(--text-color-kumo-default); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; } | |
| .hist__cell { position: relative; display: flex; flex-direction: column; aspect-ratio: 1; border-radius: 10px; overflow: hidden; background: var(--color-kumo-recessed); box-shadow: 0 0 0 1px var(--color-kumo-hairline); transition: transform 120ms var(--ease-soft), box-shadow 120ms var(--ease-soft); } | |
| .hist__cell:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 0 0 2px var(--color-kumo-brand); } | |
| .hist__cell:disabled { cursor: default; opacity: 0.7; } | |
| .hist__cell img { width: 100%; height: 100%; object-fit: cover; } | |
| .hist__cell-empty { margin: auto; font-size: 11px; color: var(--text-color-kumo-placeholder); } | |
| .hist__cell[data-status="error"] .hist__cell-empty { color: var(--color-kumo-danger); } | |
| .hist__cell-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 6px; font-size: 10px; font-family: var(--font-mono); color: #fff; background: linear-gradient(transparent, rgb(0 0 0 / 0.55)); text-align: left; } | |
| /* Run strip (phones): under the top bar while a run is active. */ | |
| .run-strip { | |
| position: relative; z-index: 45; display: flex; flex: none; align-items: center; gap: 8px; width: 100%; padding: 0 14px; overflow: hidden; | |
| font-size: 12.5px; text-align: left; color: var(--text-color-kumo-strong); background: var(--color-kumo-recessed); border-bottom: 1px solid var(--color-kumo-hairline); | |
| } | |
| .run-strip[data-state="done"] { color: var(--color-kumo-success); background: color-mix(in oklab, var(--color-kumo-success) 10%, var(--color-kumo-base)); } | |
| .run-strip[data-state="failed"] { color: var(--color-kumo-danger); background: color-mix(in oklab, var(--color-kumo-danger) 10%, var(--color-kumo-base)); } | |
| .run-strip__main { flex: 1 1 auto; min-width: 0; font-weight: 600; } | |
| .run-strip__meta { display: inline-flex; flex: none; align-items: center; gap: 2px; max-width: 45%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 11.5px; font-variant-numeric: tabular-nums; opacity: 0.8; } | |
| .run-strip__spinner { flex: none; width: 12px; height: 12px; border-radius: 50%; border: 2px solid color-mix(in oklab, var(--color-kumo-brand) 30%, transparent); border-top-color: var(--color-kumo-brand); animation: spin 0.8s linear infinite; } | |
| .run-strip__bar { position: absolute; left: 0; bottom: 0; height: 2px; width: 100%; transform-origin: left; background: var(--color-kumo-brand); transition: transform 400ms var(--ease-soft); } | |
| /* Toast: bottom centre of the work area. */ | |
| .toast { | |
| position: absolute; left: 50%; bottom: 16px; z-index: 60; display: flex; align-items: center; gap: 10px; max-width: calc(100% - 24px); padding: 8px 8px 8px 14px; border-radius: 10px; | |
| transform: translateX(-50%); font-size: 12.5px; color: var(--text-color-kumo-strong); background: var(--color-kumo-base); | |
| border: 1px solid var(--color-kumo-hairline); box-shadow: 0 10px 30px -10px rgb(0 0 0 / 0.35); | |
| } | |
| .toast > span { min-width: 0; } | |
| .toast__act { display: inline-flex; flex: none; align-items: center; gap: 4px; height: 26px; padding: 0 10px; border-radius: 7px; font-weight: 600; color: var(--color-kumo-brand); background: color-mix(in oklab, var(--color-kumo-brand) 12%, transparent); } | |
| .toast__act:hover { background: color-mix(in oklab, var(--color-kumo-brand) 18%, transparent); } | |
| .toast__close { display: grid; flex: none; place-items: center; width: 26px; height: 26px; border-radius: 7px; color: var(--text-color-kumo-subtle); } | |
| .toast__close:hover { background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); } | |
| /* Results sheet (phones). */ | |
| .m-results { height: 100%; overflow-y: auto; padding: 12px 12px calc(24px + env(safe-area-inset-bottom)); } | |
| .m-results__empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; padding: 24px; text-align: center; } | |
| .m-result { margin-bottom: 18px; } | |
| .m-result__title { margin: 0 2px 8px; font-size: 14px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .m-result__label { margin: 8px 2px 4px; font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-color-kumo-subtle); } | |
| .m-result__port { margin-bottom: 10px; } | |
| .m-result .node-output { margin: 0; } | |
| .m-result .node-output img, .m-result .node-output video { width: 100%; max-height: 70vh; object-fit: contain; border-radius: 10px; } | |
| .m-result .node-output audio { width: 100%; } | |
| .m-result .node-output__text { max-height: 40vh; font-size: 13px; } | |
| .m-result .node-output__grid { grid-template-columns: repeat(2, 1fr); gap: 6px; } | |
| .m-result__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; } | |
| /* Pipeline pull-to-refresh + page dots (phones). */ | |
| .pipe__ptr { | |
| position: absolute; top: 0; left: 50%; z-index: 5; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; | |
| color: var(--text-color-kumo-subtle); background: var(--color-kumo-base); border: 1px solid var(--color-kumo-hairline); box-shadow: 0 4px 14px -6px rgb(0 0 0 / 0.3); pointer-events: none; | |
| } | |
| .pipe__ptr[data-armed] { color: var(--color-kumo-brand); } | |
| .pipe__dots { position: absolute; left: 0; right: 0; bottom: 10px; z-index: 5; display: flex; justify-content: center; gap: 6px; padding: 6px; pointer-events: none; } | |
| .pipe__dot { width: 7px; height: 7px; padding: 0; border-radius: 50%; background: color-mix(in oklab, var(--text-color-kumo-subtle) 40%, transparent); transition: transform 160ms var(--ease-soft), background 160ms var(--ease-soft); pointer-events: auto; } | |
| .pipe__dot[data-active] { background: var(--color-kumo-brand); transform: scale(1.3); } | |
| .canvas-tip { | |
| display: flex; align-items: center; gap: 8px; max-width: 520px; padding: 7px 8px 7px 12px; border-radius: 10px; font-size: 12px; line-height: 1.4; | |
| color: var(--text-color-kumo-default); background: color-mix(in oklab, var(--color-kumo-base) 92%, transparent); backdrop-filter: blur(8px); | |
| border: 1px solid var(--color-kumo-hairline); box-shadow: 0 6px 24px -10px rgb(0 0 0 / 0.3); | |
| } | |
| .canvas-tip > svg { flex: none; color: var(--color-kumo-warning); } | |
| .canvas-tip button { flex: none; height: 22px; padding: 0 8px; border-radius: 6px; font-weight: 500; color: var(--text-color-kumo-strong); background: var(--color-kumo-fill); } | |
| .canvas-tip button:hover { background: var(--color-kumo-tint); } | |
| /* Node explorer ------------------------------------------------------- */ | |
| .explorer__backdrop { position: fixed; inset: 0; z-index: 60; display: grid; place-items: start center; padding: 7vh 16px 16px; background: color-mix(in srgb, var(--color-kumo-base) 55%, transparent); backdrop-filter: blur(6px); } | |
| .explorer { display: flex; flex-direction: column; width: min(960px, 100%); height: min(640px, 84vh); overflow: hidden; border: 1px solid var(--color-kumo-line); border-radius: 14px; background: var(--color-kumo-base); box-shadow: 0 24px 80px -20px rgb(0 0 0 / 0.5), 0 0 0 1px rgb(0 0 0 / 0.04); } | |
| .explorer__head { display: flex; flex: none; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--color-kumo-hairline); } | |
| .explorer__search { display: flex; flex: 1; align-items: center; gap: 8px; height: 36px; padding: 0 8px 0 12px; border-radius: 9px; background: var(--color-kumo-recessed); border: 1px solid var(--color-kumo-hairline); color: var(--text-color-kumo-subtle); transition: border-color 0.12s; } | |
| .explorer__search:focus-within { border-color: var(--color-kumo-brand); } | |
| .explorer__search input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; font-size: 13.5px; color: var(--text-color-kumo-strong); } | |
| .explorer__search input::placeholder { color: var(--text-color-kumo-placeholder); } | |
| .explorer__icon-btn { display: grid; place-items: center; width: 26px; height: 26px; flex: none; border-radius: 7px; color: var(--text-color-kumo-subtle); } | |
| .explorer__icon-btn:hover { background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); } | |
| .explorer__panes { display: grid; flex: 1; min-height: 0; grid-template-columns: 280px 1fr; } | |
| .explorer__left { min-height: 0; overflow-y: auto; padding: 6px 8px 12px; border-right: 1px solid var(--color-kumo-hairline); background: var(--color-kumo-recessed); } | |
| .explorer__right { min-height: 0; overflow-y: auto; padding: 6px 14px 14px; } | |
| @media (max-width: 640px) { .explorer__panes { grid-template-columns: 1fr; grid-template-rows: auto 1fr; } .explorer__left { max-height: 40%; border-right: 0; border-bottom: 1px solid var(--color-kumo-hairline); } } | |
| .explorer__label { display: flex; align-items: center; gap: 6px; margin: 10px 4px 5px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-color-kumo-subtle); } | |
| .explorer__hint { margin: 4px 4px; font-size: 11.5px; line-height: 1.45; color: var(--text-color-kumo-placeholder); } | |
| .explorer__chips { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 4px; } | |
| .explorer__chip { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px 0 7px; border-radius: 999px; border: 1px solid var(--color-kumo-hairline); background: var(--color-kumo-base); font-size: 11.5px; color: var(--text-color-kumo-default); transition: border-color 0.12s, background 0.12s; } | |
| .explorer__chip:hover, .explorer__chip:focus-visible { border-color: var(--chip-accent); background: var(--color-kumo-tint); color: var(--text-color-kumo-strong); outline: none; } | |
| .explorer__chip-dot { width: 7px; height: 7px; flex: none; border-radius: 999px; background: var(--chip-accent); } | |
| .explorer__row { display: flex; align-items: center; gap: 7px; width: 100%; height: 28px; padding: 0 6px 0 8px; border-radius: 7px; font-size: 12.5px; text-align: left; color: var(--text-color-kumo-default); transition: background 0.12s; } | |
| .explorer__row[data-nested] { padding-left: 26px; font-size: 12px; } | |
| .explorer__row:hover, .explorer__row:focus-visible { background: var(--color-kumo-tint); color: var(--text-color-kumo-strong); outline: none; } | |
| .explorer__space { margin-top: 2px; border-radius: 8px; } | |
| .explorer__space[data-fresh] { background: color-mix(in srgb, var(--color-kumo-brand) 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-kumo-brand) 40%, transparent); } | |
| .explorer__space-head { display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 8px; font-size: 12px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .explorer__fresh { margin-left: auto; font-size: 10px; font-weight: 500; color: var(--color-kumo-brand); white-space: nowrap; } | |
| .explorer__ports { display: flex; gap: 3px; margin-left: auto; flex: none; } | |
| .explorer__ports > i { display: block; width: 6px; height: 6px; border-radius: 999px; background: var(--port-color); } | |
| .explorer__pin { display: grid; place-items: center; width: 20px; height: 20px; flex: none; border-radius: 5px; color: var(--text-color-kumo-placeholder); opacity: 0; transition: opacity 0.12s; } | |
| .explorer__pin:hover { background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); } | |
| .explorer__pin[data-active] { opacity: 1; color: var(--color-kumo-brand); } | |
| .explorer__row:hover .explorer__pin, .explorer__row:focus-visible .explorer__pin { opacity: 1; } | |
| .explorer__emoji { width: 16px; flex: none; text-align: center; font-size: 13px; line-height: 1; } | |
| .explorer__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 8px; } | |
| .explorer__card { position: relative; display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 10px 12px; overflow: hidden; text-align: left; border: 1px solid var(--color-kumo-hairline); border-radius: 10px; background: var(--color-kumo-base); transition: border-color 0.12s, background 0.12s; } | |
| .explorer__card::before { content: ""; position: absolute; inset: 0; background: var(--card-gradient); opacity: 0.16; pointer-events: none; transition: opacity 0.12s; } | |
| .explorer__card:hover::before, .explorer__card:focus-visible::before { opacity: 0.26; } | |
| .explorer__card > * { position: relative; } | |
| .explorer__card-emoji { display: grid; place-items: center; width: 28px; height: 28px; flex: none; border-radius: 8px; background: var(--card-gradient); font-size: 15px; line-height: 1; box-shadow: 0 1px 2px rgb(0 0 0 / 0.25); } | |
| .explorer__card:hover, .explorer__card:focus-visible { border-color: var(--color-kumo-brand); background: var(--color-kumo-tint); outline: none; } | |
| .explorer__card:disabled { opacity: 0.5; } | |
| .explorer__card[data-usable="false"] { opacity: 0.6; } | |
| .explorer__card-top { display: flex; align-items: center; gap: 7px; min-width: 0; } | |
| .explorer__card-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .explorer__card-id { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); font-size: 10.5px; color: var(--text-color-kumo-subtle); } | |
| .explorer__desc { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-top: 2px; font-size: 11.5px; line-height: 1.4; color: var(--text-color-kumo-default); } | |
| .explorer__meta { display: flex; align-items: center; gap: 6px; margin-top: 5px; font-size: 10.5px; color: var(--text-color-kumo-subtle); } | |
| .explorer__add { margin-left: auto; padding: 2px 9px; border-radius: 999px; background: var(--color-kumo-brand); color: var(--accent-ink); font-size: 10.5px; font-weight: 600; opacity: 0; transition: opacity 0.12s; } | |
| .explorer__card:hover .explorer__add, .explorer__card:focus-visible .explorer__add { opacity: 1; } | |
| .explorer__likes { flex: none; font-size: 10.5px; color: var(--text-color-kumo-subtle); font-variant-numeric: tabular-nums; } | |
| .explorer__foot { display: flex; flex: none; gap: 14px; padding: 7px 14px; border-top: 1px solid var(--color-kumo-hairline); font-size: 11px; color: var(--text-color-kumo-subtle); } | |
| .explorer__foot > span { display: inline-flex; align-items: center; gap: 5px; } | |
| .explorer__tabs { display: flex; flex: none; gap: 4px; padding: 0 10px 8px; } | |
| .explorer__tab { display: inline-flex; flex: 1; align-items: center; justify-content: center; gap: 6px; height: 34px; border-radius: 9px; background: var(--color-kumo-recessed); font-size: 13px; font-weight: 500; color: var(--text-color-kumo-subtle); transition: background 0.12s, color 0.12s; } | |
| .explorer__tab[data-active] { background: color-mix(in srgb, var(--color-kumo-brand) 14%, transparent); color: var(--text-color-kumo-strong); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-kumo-brand) 40%, transparent); } | |
| .explorer__switch { display: block; width: 100%; margin-top: 8px; height: 40px; border-radius: 10px; background: var(--color-kumo-brand); color: var(--accent-ink); font-size: 13.5px; font-weight: 600; } | |
| /* Workflow sidebar ----------------------------------------------------- */ | |
| .wf-h { display: flex; align-items: center; gap: 6px; margin: 16px 12px 6px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-color-kumo-subtle); } | |
| .wf-h__count { padding: 0 5px; border-radius: 999px; background: var(--color-kumo-fill); font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0; } | |
| .wf-hint { margin: 4px 12px 0; font-size: 11px; line-height: 1.45; color: var(--text-color-kumo-placeholder); } | |
| .dock { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 12px; } | |
| .dock-chip { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; height: 26px; padding: 0 9px 0 7px; border-radius: 999px; border: 1px solid var(--color-kumo-hairline); background: var(--color-kumo-recessed); font-size: 12px; color: var(--text-color-kumo-default); cursor: grab; transition: border-color 0.12s, background 0.12s, transform 0.12s; } | |
| .dock-chip:hover { border-color: var(--chip-accent); background: var(--color-kumo-tint); color: var(--text-color-kumo-strong); } | |
| .dock-chip:active { cursor: grabbing; transform: scale(0.97); } | |
| .dock-chip__swatch { width: 8px; height: 8px; flex: none; border-radius: 999px; background: var(--chip-accent); } | |
| .dock-chip__emoji { font-size: 12px; line-height: 1; } | |
| .dock-chip__pin { flex: none; color: var(--color-kumo-brand); } | |
| .wf-space { margin: 2px 6px 0; border-radius: 8px; transition: background 0.12s; } | |
| .wf-space[data-open] { background: var(--color-kumo-recessed); } | |
| .wf-space__row { display: flex; align-items: center; gap: 6px; padding: 6px 6px 6px 4px; border-radius: 8px; cursor: pointer; user-select: none; } | |
| .wf-space__row:hover { background: var(--color-kumo-tint); } | |
| .wf-space__toggle { display: grid; place-items: center; width: 18px; height: 18px; flex: none; border-radius: 4px; color: var(--text-color-kumo-subtle); } | |
| .wf-space__toggle:hover { background: var(--color-kumo-fill); color: var(--text-color-kumo-strong); } | |
| .wf-space__emoji { width: 16px; flex: none; text-align: center; font-size: 14px; line-height: 1; } | |
| .wf-space__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; font-weight: 500; color: var(--text-color-kumo-strong); } | |
| .wf-space__meta { display: flex; align-items: center; gap: 5px; overflow: hidden; white-space: nowrap; font-size: 10.5px; color: var(--text-color-kumo-subtle); } | |
| .wf-space__meta [data-bad] { color: var(--color-kumo-warning); } | |
| .wf-space__endpoints { padding: 0 4px 6px 14px; } | |
| .wf-outline { display: flex; flex-direction: column; gap: 1px; padding: 0 6px; } | |
| .wf-node { display: flex; align-items: center; gap: 7px; width: 100%; height: 28px; padding-right: 8px; border-radius: 7px; font-size: 12px; text-align: left; color: var(--text-color-kumo-default); transition: background 0.12s; } | |
| .wf-node:hover { background: var(--color-kumo-tint); color: var(--text-color-kumo-strong); } | |
| .wf-node[data-selected] { background: color-mix(in srgb, var(--color-kumo-brand) 12%, transparent); color: var(--text-color-kumo-strong); } | |
| .wf-node[data-mode] { opacity: 0.55; } | |
| .wf-node__status { display: grid; place-items: center; width: 14px; flex: none; color: var(--text-color-kumo-placeholder); } | |
| .wf-node[data-status="queued"] .wf-node__status { color: var(--text-color-kumo-subtle); } | |
| .wf-node[data-status="running"] .wf-node__status { color: var(--color-kumo-brand); } | |
| .wf-node[data-status="done"] .wf-node__status { color: var(--color-kumo-success); } | |
| .wf-node[data-status="error"] .wf-node__status { color: var(--color-kumo-danger); } | |
| .wf-node__dot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; } | |
| .wf-node[data-status="queued"] .wf-node__dot { animation: pulse-dot 1.2s ease-in-out infinite; } | |
| .wf-node__emoji { width: 14px; flex: none; text-align: center; font-size: 12px; line-height: 1; } | |
| .wf-node__swatch { width: 8px; height: 8px; flex: none; margin: 0 3px; border-radius: 2px; } | |
| .wf-node__meta { margin-left: auto; flex: none; font-family: var(--font-mono); font-size: 10px; color: var(--text-color-kumo-subtle); } | |
| .wf-node[data-status="error"] .wf-node__meta { color: var(--color-kumo-danger); } | |
| .wf-node__jump { flex: none; color: var(--text-color-kumo-placeholder); opacity: 0; transition: opacity 0.12s; } | |
| .wf-node:hover .wf-node__jump { opacity: 1; } | |
| .wf-node__error { margin: 0 6px 4px 0; padding: 4px 8px 4px 22px; border-radius: 6px; font-size: 11px; line-height: 1.4; color: var(--color-kumo-danger); background: color-mix(in srgb, var(--color-kumo-danger) 8%, transparent); cursor: pointer; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } | |
| .dock-chip[data-dim] { opacity: 0.5; } | |
| .dock-chip--ghost { border-style: dashed; color: var(--text-color-kumo-subtle); cursor: pointer; } | |
| /* Node colour tags, notes, locks ------------------------------------ */ | |
| .canvas-node[data-color] { | |
| --node-accent: var(--node-tint); | |
| } | |
| .canvas-node[data-color] .canvas-node__header { | |
| background: color-mix(in srgb, var(--node-tint) 22%, var(--color-kumo-tint)); | |
| } | |
| .canvas-node[data-color]:not([data-selected="true"]) { | |
| --node-ring: color-mix(in srgb, var(--node-tint) 45%, var(--color-kumo-line)); | |
| } | |
| .canvas-node__note { | |
| margin: 0 0 6px; | |
| padding: 6px 8px; | |
| border-radius: 6px; | |
| background: color-mix(in srgb, var(--color-kumo-warning) 12%, transparent); | |
| border-left: 2px solid color-mix(in srgb, var(--color-kumo-warning) 60%, transparent); | |
| color: var(--text-color-kumo-default); | |
| font-size: 11px; | |
| line-height: 1.4; | |
| white-space: pre-wrap; | |
| word-break: break-word; | |
| } | |
| .canvas-node[data-locked] .canvas-node__header { | |
| cursor: default; | |
| } | |
| .ctx-menu__row { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| padding: 6px 10px; | |
| } | |
| .ctx-swatch { | |
| width: 16px; | |
| height: 16px; | |
| border-radius: 999px; | |
| background: var(--swatch); | |
| box-shadow: 0 0 0 1px color-mix(in srgb, var(--swatch) 40%, transparent); | |
| cursor: pointer; | |
| transition: transform 120ms var(--ease-soft); | |
| } | |
| .ctx-swatch:hover { | |
| transform: scale(1.18); | |
| } | |
| .ctx-swatch[data-active="true"] { | |
| box-shadow: 0 0 0 2px var(--color-kumo-base), 0 0 0 3.5px var(--swatch); | |
| } | |
| .ctx-swatch--none { | |
| background: transparent; | |
| box-shadow: inset 0 0 0 1.5px var(--color-kumo-line); | |
| position: relative; | |
| } | |
| .ctx-swatch--none::after { | |
| content: ""; | |
| position: absolute; | |
| left: 3px; | |
| right: 3px; | |
| top: 50%; | |
| height: 1.5px; | |
| background: var(--color-kumo-line); | |
| transform: rotate(-45deg); | |
| } | |
| /* Find bar ----------------------------------------------------------- */ | |
| .findbar { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| height: 36px; | |
| padding: 0 6px 0 10px; | |
| border-radius: 10px; | |
| background: var(--color-kumo-base); | |
| box-shadow: 0 0 0 1px var(--color-kumo-line), 0 8px 24px -8px rgb(0 0 0 / 0.35); | |
| width: min(360px, calc(100vw - 32px)); | |
| } | |
| .findbar input { | |
| flex: 1; | |
| min-width: 0; | |
| background: transparent; | |
| border: 0; | |
| outline: 0; | |
| font-size: 13px; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .findbar input::placeholder { | |
| color: var(--text-color-kumo-placeholder); | |
| } | |
| .findbar__count { | |
| flex: none; | |
| font-family: var(--font-mono); | |
| font-size: 10.5px; | |
| color: var(--text-color-kumo-subtle); | |
| white-space: nowrap; | |
| } | |
| .findbar__btn { | |
| flex: none; | |
| display: grid; | |
| place-items: center; | |
| width: 24px; | |
| height: 24px; | |
| border-radius: 6px; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .findbar__btn:hover { | |
| background: var(--color-kumo-fill); | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .canvas-node[data-found="true"] { | |
| --node-ring: var(--color-kumo-warning); | |
| --node-ring-width: 2px; | |
| } | |
| /* Keyboard-focused widget values ------------------------------------- */ | |
| .widget__value:focus-visible { | |
| outline: 0; | |
| box-shadow: 0 0 0 1.5px var(--color-kumo-brand); | |
| border-radius: 4px; | |
| } | |
| /* Run history outputs ------------------------------------------------ */ | |
| .hist-outs { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 4px; | |
| margin-top: 6px; | |
| } | |
| .hist-outs__img { | |
| width: 44px; | |
| height: 44px; | |
| border-radius: 6px; | |
| object-fit: cover; | |
| background: var(--color-kumo-recessed); | |
| box-shadow: 0 0 0 1px var(--color-kumo-hairline); | |
| } | |
| .hist-outs__text { | |
| flex: 1 1 100%; | |
| font-size: 11px; | |
| line-height: 1.4; | |
| color: var(--text-color-kumo-default); | |
| background: var(--color-kumo-recessed); | |
| border-radius: 6px; | |
| padding: 5px 7px; | |
| max-height: 64px; | |
| overflow: hidden; | |
| white-space: pre-wrap; | |
| word-break: break-word; | |
| } | |
| .explorer__more { display: grid; place-items: center; height: 40px; color: var(--text-color-kumo-subtle); } | |
| /* ZeroGPU quota (user menu) ------------------------------------------- */ | |
| .quota { | |
| --quota-color: var(--color-kumo-success); | |
| display: flex; | |
| flex-direction: column; | |
| gap: 6px; | |
| margin: 2px 4px 6px; | |
| padding: 8px 10px 9px; | |
| border-radius: 8px; | |
| background: var(--color-kumo-recessed); | |
| font-size: 11.5px; | |
| color: var(--text-color-kumo-default); | |
| } | |
| .quota[data-level="low"] { --quota-color: var(--color-kumo-warning); } | |
| .quota[data-level="empty"] { --quota-color: var(--color-kumo-danger); } | |
| .quota[data-loading] .quota__bar { opacity: 0.6; } | |
| .quota__head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; } | |
| .quota__head b { font-weight: 500; font-family: var(--font-mono); font-size: 11px; color: var(--text-color-kumo-strong); } | |
| .quota__bar { | |
| position: relative; | |
| height: 5px; | |
| border-radius: 999px; | |
| overflow: hidden; | |
| background: var(--color-kumo-fill); | |
| } | |
| .quota__bar i, | |
| .quota-strip i { | |
| position: absolute; | |
| inset: 0; | |
| transform-origin: left; | |
| background: var(--quota-color); | |
| border-radius: inherit; | |
| transition: transform 300ms var(--ease-soft); | |
| } | |
| .quota__meta { display: flex; justify-content: space-between; gap: 12px; font-size: 11px; color: var(--text-color-kumo-subtle); } | |
| .quota__meta b { font-weight: 500; color: var(--text-color-kumo-default); } | |
| .quota__meta--warn, .quota__meta--warn b { color: var(--color-kumo-warning); } | |
| .quota__refresh { color: var(--text-color-kumo-subtle); text-decoration: underline dotted; text-underline-offset: 2px; cursor: pointer; } | |
| .quota__refresh:hover { color: var(--text-color-kumo-strong); } | |
| .quota__refresh:disabled { opacity: 0.5; cursor: default; } | |
| .quota__note { font-size: 11px; line-height: 1.4; color: var(--quota-color); } | |
| .quota__sub { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; padding-top: 6px; border-top: 1px solid var(--color-kumo-line); } | |
| .quota__toggle { width: 100%; cursor: pointer; text-align: left; } | |
| .quota__toggle:hover { color: var(--text-color-kumo-strong); } | |
| .quota__sub-body { display: flex; flex-direction: column; gap: 5px; padding-left: 13px; } | |
| .quota__bar--neutral { --quota-color: var(--color-kumo-brand); height: 4px; } | |
| /* Same quota as a 2px strip along the bottom of the user button. */ | |
| .quota-strip { | |
| --quota-color: var(--color-kumo-success); | |
| position: absolute; | |
| left: 6px; | |
| right: 6px; | |
| bottom: 0; | |
| height: 2px; | |
| border-radius: 999px; | |
| overflow: hidden; | |
| background: var(--color-kumo-fill); | |
| pointer-events: none; | |
| } | |
| .quota-strip[data-level="low"] { --quota-color: var(--color-kumo-warning); } | |
| .quota-strip[data-level="empty"] { --quota-color: var(--color-kumo-danger); } | |
| /* Same quota as a ring around the avatar (phones only). */ | |
| .quota-ring { position: relative; display: grid; place-items: center; flex: none; --quota-color: var(--color-kumo-success); } | |
| .quota-ring[data-level="low"] { --quota-color: var(--color-kumo-warning); } | |
| .quota-ring[data-level="empty"] { --quota-color: var(--color-kumo-danger); } | |
| .quota-ring::before { | |
| content: ""; | |
| display: none; | |
| position: absolute; | |
| inset: -3px; | |
| border-radius: 50%; | |
| background: conic-gradient(var(--quota-color) calc(var(--frac, 0) * 360deg), var(--color-kumo-fill) 0); | |
| mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2px)); | |
| -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2px)); | |
| pointer-events: none; | |
| } | |
| .quota-ring:not([data-level])::before { display: none ; } | |
| /* Phones ------------------------------------------------------------- */ | |
| /* Panels become full-height sheets, a bottom bar replaces the side toggles | |
| and the view switch, and the pipeline view is the default. */ | |
| .m-bar { | |
| position: relative; | |
| z-index: 50; | |
| display: flex; | |
| flex: none; | |
| align-items: stretch; | |
| height: calc(56px + env(safe-area-inset-bottom)); | |
| padding: 0 4px env(safe-area-inset-bottom); | |
| background: var(--color-kumo-base); | |
| border-top: 1px solid var(--color-kumo-hairline); | |
| } | |
| .m-bar__btn { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 3px; | |
| min-width: 0; | |
| font-size: 10.5px; | |
| font-weight: 500; | |
| color: var(--text-color-kumo-subtle); | |
| -webkit-tap-highlight-color: transparent; | |
| } | |
| .m-bar__btn[data-active] { color: var(--color-kumo-brand); } | |
| .m-bar__btn:active { color: var(--text-color-kumo-strong); } | |
| .m-bar__add { | |
| display: grid; | |
| place-items: center; | |
| width: 40px; | |
| height: 30px; | |
| border-radius: 10px; | |
| background: var(--color-kumo-brand); | |
| color: var(--accent-ink); | |
| } | |
| .m-bar__btn--add { gap: 2px; } | |
| .m-bar__dot { | |
| position: absolute; | |
| top: -1px; | |
| right: -3px; | |
| width: 7px; | |
| height: 7px; | |
| border-radius: 999px; | |
| background: var(--color-kumo-brand); | |
| box-shadow: 0 0 0 2px var(--color-kumo-base); | |
| } | |
| .m-sheet { | |
| position: absolute; | |
| inset: 0; | |
| z-index: 40; | |
| display: flex; | |
| flex-direction: column; | |
| background: var(--color-kumo-base); | |
| } | |
| .m-sheet__head { | |
| display: flex; | |
| flex: none; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 8px; | |
| height: 42px; | |
| padding: 0 8px 0 14px; | |
| border-bottom: 1px solid var(--color-kumo-hairline); | |
| font-size: 13px; | |
| font-weight: 600; | |
| color: var(--text-color-kumo-strong); | |
| } | |
| .m-sheet__close { | |
| display: grid; | |
| place-items: center; | |
| width: 30px; | |
| height: 30px; | |
| border-radius: 8px; | |
| color: var(--text-color-kumo-subtle); | |
| } | |
| .m-sheet__close:active { background: var(--color-kumo-fill); } | |
| .m-fab { | |
| display: grid; | |
| place-items: center; | |
| width: 44px; | |
| height: 44px; | |
| border-radius: 14px; | |
| background: var(--color-kumo-base); | |
| color: var(--text-color-kumo-strong); | |
| box-shadow: | |
| 0 0 0 1px var(--color-kumo-line), | |
| 0 8px 24px -8px rgb(0 0 0 / 0.5); | |
| } | |
| /* Narrow desktops: avatar-only user button (quota as a ring) and an icon-only view switch. */ | |
| @media (max-width: 1023px) { | |
| .quota-strip { display: none; } | |
| .quota-ring::before { display: block; } | |
| .view-switch__btn > span:last-child { display: none; } | |
| .view-switch__btn { padding-inline: 8px; } | |
| } | |
| @media (max-width: 767px) { | |
| .view-switch { display: none; } | |
| html, body, #root { height: 100dvh; } | |
| /* Pipeline: every top-level step is a page. The whole pipeline scrolls vertically as one; the row of | |
| pages slides sideways under JS control (touch-action keeps the browser out of the horizontal axis). */ | |
| .pipe { padding: 12px 0 96px; overflow-x: hidden; } | |
| .pipe__col { width: 100%; min-height: 0; } | |
| .pipe__pages > .pipe__list { display: flex; align-items: flex-start; touch-action: pan-y; will-change: transform; transform: translateX(calc(var(--page, 0) * -100%)); transition: transform 320ms cubic-bezier(0.16, 1, 0.3, 1); } | |
| .pipe__pages > .pipe__list > .pipe-item { flex: 0 0 100%; width: 100%; padding: 0 12px; } | |
| .pipe__pages > .pipe__list > .pipe-item[data-inactive] { max-height: calc(100dvh - 140px); overflow: hidden; } | |
| .pipe__pages > .pipe__list > .pipe-insert, .pipe__pages > .pipe__list > .pipe-item > .pipe-insert { display: none; } | |
| .pipe__empty { margin: 0 12px; } | |
| .pipe-group__body-inner .pipe-insert { height: 14px; } | |
| /* Input rows: an unlinked widget gets the full width; its source picker shrinks to a plug button, | |
| and disappears when nothing above could feed it. */ | |
| .pipe-input__head > .min-w-0 > .widget { margin: 0 2px; } | |
| .pipe-input__src[data-compact] { flex: none; width: 30px; justify-content: center; padding: 0; margin-top: 2px; } | |
| .pipe-input__src[data-compact] .pipe-input__src-label, | |
| .pipe-input__src[data-compact] .pipe-input__src-caret { display: none; } | |
| .pipe-input__src[data-compact] .pipe-input__src-icon { display: block; } | |
| .pipe-input__src[data-none] { display: none; } | |
| .pipe-input__name { width: 84px; } | |
| /* Node explorer: a full-screen sheet with a big search box, one pane at a time (tabs), one scroll region. */ | |
| .explorer__backdrop { padding: 0; place-items: stretch; backdrop-filter: none; } | |
| .explorer { width: 100%; max-width: none; height: 100%; max-height: none; border: 0; border-radius: 0; box-shadow: none; } | |
| .explorer__head { padding: calc(8px + env(safe-area-inset-top)) 10px 8px; gap: 6px; border-bottom: 0; } | |
| .explorer__search { height: 42px; padding-left: 12px; border-radius: 12px; } | |
| .explorer__search input { font-size: 16px; } | |
| .explorer__icon-btn { width: 36px; height: 36px; border-radius: 10px; } | |
| .explorer__panes { display: block; border-top: 1px solid var(--color-kumo-hairline); } | |
| .explorer__left, .explorer__right { height: 100%; max-height: none; border: 0; padding: 4px 10px calc(20px + env(safe-area-inset-bottom)); background: transparent; } | |
| .explorer__label { margin: 14px 2px 7px; } | |
| .explorer__hint { margin: 6px 2px; font-size: 13px; } | |
| .explorer__chips { gap: 6px; padding: 0; } | |
| .explorer__chip { height: 34px; padding: 0 12px 0 10px; font-size: 13px; } | |
| .explorer__row { height: 44px; padding-right: 2px; border-radius: 10px; font-size: 14px; } | |
| .explorer__row[data-nested] { padding-left: 30px; font-size: 13.5px; } | |
| .explorer__space { margin-top: 4px; } | |
| .explorer__space-head { height: 36px; font-size: 13.5px; } | |
| .explorer__pin { width: 34px; height: 34px; opacity: 1; } | |
| .explorer__grid { grid-template-columns: 1fr; gap: 8px; } | |
| .explorer__card { gap: 4px; padding: 12px 14px; border-radius: 12px; } | |
| .explorer__card-title { font-size: 14px; } | |
| .explorer__desc { font-size: 12.5px; } | |
| .explorer__meta { margin-top: 7px; font-size: 11px; } | |
| .explorer__add { opacity: 1; padding: 4px 12px; font-size: 11.5px; } | |
| .explorer__foot { display: none; } | |
| .copilot--side .copilot__list { padding: 10px 12px 6px; } | |
| .quota { margin: 2px 2px 6px; } | |
| .hist { max-height: calc(100dvh - 20px); } | |
| .hist__body { grid-template-columns: 1fr; grid-template-rows: minmax(0, 38%) minmax(0, 1fr); } | |
| .hist__list { border-right: 0; border-bottom: 1px solid var(--color-kumo-hairline); } | |
| .hist__cols { grid-template-columns: 1fr; } | |
| .hist__table th { width: 120px; } | |
| /* Dialogs fill the width with a small gutter. */ | |
| [role="dialog"]:not(.ctx-menu):not(.explorer) { | |
| top: 10px ; | |
| width: calc(100vw - 20px) ; | |
| max-width: calc(100vw - 20px) ; | |
| max-height: calc(100dvh - 20px); | |
| } | |
| .react-flow__panel.bottom.left { margin-bottom: 10px ; } | |
| } | |
| /* Fingers, not pointers: bigger hit areas, and no hover-only affordances. */ | |
| @media (pointer: coarse) { | |
| .canvas-node .react-flow__handle::before { inset: -14px; } | |
| .widget__fold, .pipe-block__icon-btn, .explorer__icon-btn { min-width: 30px; min-height: 30px; } | |
| .pipe-block__grip { padding: 6px; } | |
| .panel-resize { display: none; } | |
| } | |
| /* Cloud sync ------------------------------------------------------------- */ | |
| .sync-ind { display: inline-flex; height: 28px; width: 28px; flex: none; align-items: center; justify-content: center; border-radius: 6px; transition: background-color 120ms; } | |
| .sync-ind:hover { background: var(--color-kumo-tint); color: var(--text-color-kumo-strong); } | |
| .wfl, .commit { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px 16px; font-size: 13.5px; } | |
| @media (min-width: 640px) { .wfl, .commit { width: min(560px, calc(100vw - 2rem)); } } | |
| .wfl__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; } | |
| .wfl__title { font-size: 18px; font-weight: 600; line-height: 1.25; } | |
| .wfl__lede { margin: -4px 0 0; color: var(--text-color-kumo-subtle); } | |
| .wfl__lede a { color: var(--text-color-kumo-link, inherit); text-decoration: underline; text-underline-offset: 2px; } | |
| .wfl__empty { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 14px; border: 1px dashed var(--color-kumo-line); border-radius: 8px; color: var(--text-color-kumo-subtle); } | |
| .wfl__empty p { margin: 0; } | |
| .wfl__warn, .commit__ok { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; border-radius: 8px; background: var(--color-kumo-recessed); font-size: 13px; } | |
| .wfl__warn { color: var(--text-color-kumo-warning, inherit); } | |
| .wfl__list { display: flex; flex-direction: column; max-height: min(420px, calc(100dvh - 260px)); overflow: auto; margin: 0; padding: 0; list-style: none; border: 1px solid var(--color-kumo-hairline); border-radius: 8px; } | |
| .wfl__list li { display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 4px 6px 4px 4px; border-bottom: 1px solid var(--color-kumo-hairline); } | |
| .wfl__list li:last-child { border-bottom: 0; } | |
| .wfl__list li[data-current] { box-shadow: inset 3px 0 0 var(--hf-yellow); } | |
| .wfl__open { display: flex; min-width: 0; flex: 1; flex-direction: column; align-items: flex-start; gap: 1px; padding: 5px 8px; border-radius: 6px; text-align: left; } | |
| .wfl__open:hover { background: var(--color-kumo-tint); } | |
| .wfl__name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .wfl__meta { font-size: 12px; color: var(--text-color-kumo-subtle); } | |
| .wfl__input { flex: 1; height: 30px; margin: 4px; padding: 0 8px; border-radius: 6px; background: var(--color-kumo-control); color: var(--text-color-kumo-strong); font: inherit; font-weight: 600; outline: none; box-shadow: 0 0 0 1.5px var(--color-kumo-brand); } | |
| .wfl__actions { display: flex; flex: none; align-items: center; gap: 2px; } | |
| .wfl__ask { margin-right: 4px; font-size: 12.5px; color: var(--text-color-kumo-subtle); } | |
| .wfl .precheck__foot, .commit .precheck__foot { align-items: center; padding-top: 0; } | |
| .commit__form { display: flex; flex-direction: column; gap: 10px; } | |
| .commit__row { display: grid; grid-template-columns: 130px 1fr; gap: 8px; align-items: end; } | |
| .commit__repo { min-width: 0; } | |
| .commit__hint { margin: -4px 0 0; font-size: 12px; color: var(--text-color-kumo-subtle); } | |
| .commit__link { display: inline-flex; flex: none; align-items: center; gap: 4px; font-weight: 600; color: var(--text-color-kumo-link, inherit); } | |
| .commit__busy { margin-right: auto; font-size: 12.5px; color: var(--text-color-kumo-subtle); } | |
| .commit__open { margin-right: auto; font-size: 12.5px; color: var(--text-color-kumo-link, inherit); text-decoration: underline; text-underline-offset: 2px; } | |
| .commit__busy + .commit__open { margin-right: 0; } | |
| @media (max-width: 639px) { .commit__row { grid-template-columns: 1fr; } } | |
| .sync-ind[data-problem] { width: auto; gap: 5px; padding: 0 8px; font-size: 12px; font-weight: 600; white-space: nowrap; } | |
| .sync-ind__label { line-height: 1; } | |
| @media (max-width: 640px) { .sync-ind__label { display: none; } .sync-ind[data-problem] { width: 28px; padding: 0; } } | |
| .expired { display: flex; align-items: center; gap: 10px; padding: 6px 12px; background: var(--color-kumo-recessed); color: var(--text-color-kumo-default); font-size: 13px; border-bottom: 1px solid var(--color-kumo-line); } | |
| .expired > svg { color: var(--text-color-kumo-danger, #d33); } | |
| .expired__text { flex: 1; min-width: 0; } | |
| .expired__actions { display: flex; flex: none; gap: 6px; } | |
| @media (max-width: 640px) { .expired { flex-wrap: wrap; } .expired__actions { width: 100%; justify-content: flex-end; } } | |
| /* Sign-in gate: the only thing shown until the account's storage is open. */ | |
| .gate { display: flex; min-height: 100%; align-items: center; justify-content: center; padding: 24px 16px; background: var(--color-kumo-canvas); color: var(--text-color-kumo-default); } | |
| .gate__card { display: flex; width: 100%; max-width: 380px; flex-direction: column; align-items: flex-start; gap: 14px; } | |
| .gate__brand { display: flex; align-items: center; gap: 10px; } | |
| .gate__title { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.01em; color: var(--text-color-kumo-strong); } | |
| .gate__lede { margin: 0 0 6px; font-size: 15px; line-height: 1.45; color: var(--text-color-kumo-default); } | |
| .gate__msg { margin: 0; font-size: 14px; line-height: 1.5; } | |
| .gate__msg strong { color: var(--text-color-kumo-strong); } | |
| .gate__loading { display: flex; align-items: center; gap: 8px; color: var(--text-color-kumo-subtle); } | |
| .gate__actions { display: flex; flex-wrap: wrap; gap: 8px; } | |
| .gate__cta { width: 100%; justify-content: center; } | |
| .gate__err { margin: 0; font-size: 13px; line-height: 1.45; color: var(--text-color-kumo-danger, #d33); } | |
| .gate__fine { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--text-color-kumo-subtle); } | |
| .gate__link { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; } | |
| .gate__link:hover { color: var(--text-color-kumo-strong); } | |
| .welcome__brand { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-size: 13px; font-weight: 700; color: var(--text-color-kumo-strong); } | |
| /* Copilot links: user bubble is brand-coloured, so links there use the bubble's ink. */ | |
| .copilot__msg--user .md-link { color: inherit; text-decoration-color: color-mix(in oklab, currentColor 45%, transparent); } | |
| .md-media { display: block; margin: 6px 0 2px; max-width: 100%; } | |
| .md-media--image { width: fit-content; border-radius: 6px; overflow: hidden; border: 1px solid var(--color-kumo-line); background: var(--color-kumo-recessed); line-height: 0; } | |
| .md-media--image img { display: block; max-width: 100%; max-height: 220px; object-fit: contain; } | |
| .md-media audio { display: block; width: 100%; max-width: 320px; height: 32px; } | |
| .md-media video { display: block; max-width: 100%; max-height: 240px; border-radius: 6px; background: #000; } | |
| .beta-tag { display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: 4px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; line-height: 1; color: #6b4e00; background: #fff4c2; border: 1px solid #f5d76e; cursor: default; } | |
| html[data-mode="dark"] .beta-tag { color: #ffd21e; background: rgba(255, 210, 30, 0.1); border-color: rgba(255, 210, 30, 0.35); } | |
| /* Share dialog */ | |
| .share__row { display: flex; align-items: center; gap: 8px; } | |
| .share__title { flex: 1; min-width: 0; } | |
| .share__row > :first-child { flex: 1; min-width: 0; } | |
| .share__link { flex: 1; min-width: 0; height: 32px; padding: 0 10px; border-radius: 6px; border: 1px solid var(--color-kumo-hairline); background: var(--color-kumo-recessed); color: var(--text-color-kumo-strong); font: inherit; font-size: 13px; outline: none; } | |
| .share__link:focus { box-shadow: 0 0 0 1.5px var(--color-kumo-brand); } | |
| .share__made { display: flex; flex-direction: column; gap: 6px; } | |
| .share__mine { display: flex; flex-direction: column; gap: 8px; padding-top: 4px; } | |
| .share__h { margin: 0; font-size: 13px; font-weight: 600; color: var(--text-color-kumo-strong); } | |
| .share__list { max-height: min(260px, calc(100dvh - 380px)); } | |
| .share__by { margin: 0 0 -6px; font-size: 12.5px; font-weight: 600; color: var(--text-color-kumo-subtle); } | |
| .share__note { margin: 0; font-size: 13px; line-height: 1.45; } | |
| .gate__share { padding: 10px 12px; border-radius: 8px; background: var(--color-kumo-recessed); } | |