@1agh/maude 0.43.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/studio/acp/bridge.ts +44 -10
- package/apps/studio/acp/env.ts +23 -0
- package/apps/studio/acp/login-state.ts +263 -0
- package/apps/studio/acp/plugin-bootstrap.ts +31 -25
- package/apps/studio/acp/probe.ts +152 -1
- package/apps/studio/annotations-layer.tsx +396 -46
- package/apps/studio/api.ts +395 -2
- package/apps/studio/bin/_audio-search.mjs +140 -0
- package/apps/studio/bin/_import-asset-pdf-worker.mjs +34 -0
- package/apps/studio/bin/_import-asset.mjs +815 -0
- package/apps/studio/bin/_import-brand.mjs +635 -0
- package/apps/studio/bin/_import-tokens-alias-resolver.mjs +95 -0
- package/apps/studio/bin/_import-tokens.mjs +1201 -0
- package/apps/studio/bin/_transcribe.mjs +419 -0
- package/apps/studio/bin/_transcribe.test.mjs +80 -0
- package/apps/studio/bin/audio-search.sh +28 -0
- package/apps/studio/bin/generate.sh +154 -0
- package/apps/studio/bin/import-asset.sh +34 -0
- package/apps/studio/bin/import-brand.sh +29 -0
- package/apps/studio/bin/import-tokens.sh +33 -0
- package/apps/studio/bin/photo-bg-remove.sh +119 -21
- package/apps/studio/bin/transcribe.sh +39 -0
- package/apps/studio/canvas-edit.ts +197 -2
- package/apps/studio/canvas-lib.tsx +115 -6
- package/apps/studio/client/app.jsx +1954 -685
- package/apps/studio/client/generate-dialog.jsx +352 -0
- package/apps/studio/client/github.js +14 -0
- package/apps/studio/client/inspector-controls.jsx +781 -0
- package/apps/studio/client/panels/BrandUploadPanel.jsx +233 -0
- package/apps/studio/client/panels/ChatPanel.jsx +15 -33
- package/apps/studio/client/panels/IntroVideoDialog.jsx +44 -0
- package/apps/studio/client/panels/OnboardingWizard.jsx +12 -0
- package/apps/studio/client/panels/ReadinessList.jsx +227 -7
- package/apps/studio/client/panels/SettingsPanel.jsx +828 -0
- package/apps/studio/client/panels/SetupChecklist.jsx +223 -0
- package/apps/studio/client/photo-knobs.jsx +167 -172
- package/apps/studio/client/styles/3-shell-maude.css +334 -28
- package/apps/studio/client/styles/4-components.css +223 -0
- package/apps/studio/client/styles/6-acp-chat.css +86 -0
- package/apps/studio/client/tour/quick-setup-tour.js +39 -0
- package/apps/studio/commands/annotation-strokes-command.ts +13 -3
- package/apps/studio/config.schema.json +70 -0
- package/apps/studio/context-menu.tsx +11 -2
- package/apps/studio/context.ts +16 -0
- package/apps/studio/design-setup-readiness.ts +115 -0
- package/apps/studio/dist/client.bundle.js +2097 -2088
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/draw/palette.ts +34 -0
- package/apps/studio/footage/schema.test.ts +92 -0
- package/apps/studio/footage/schema.ts +179 -1
- package/apps/studio/generation/adapters/elevenlabs.ts +370 -0
- package/apps/studio/generation/adapters/gemini.ts +542 -0
- package/apps/studio/generation/adapters/groq.test.ts +80 -0
- package/apps/studio/generation/adapters/groq.ts +247 -0
- package/apps/studio/generation/audio-library.test.ts +95 -0
- package/apps/studio/generation/audio-library.ts +156 -0
- package/apps/studio/generation/captions.test.ts +78 -0
- package/apps/studio/generation/captions.ts +132 -0
- package/apps/studio/generation/download.ts +76 -0
- package/apps/studio/generation/elevenlabs.test.ts +223 -0
- package/apps/studio/generation/gemini.test.ts +350 -0
- package/apps/studio/generation/jobs.test.ts +128 -0
- package/apps/studio/generation/jobs.ts +243 -0
- package/apps/studio/generation/keys.test.ts +75 -0
- package/apps/studio/generation/keys.ts +162 -0
- package/apps/studio/generation/prefs.test.ts +95 -0
- package/apps/studio/generation/prefs.ts +82 -0
- package/apps/studio/generation/registry.ts +88 -0
- package/apps/studio/generation/types.test.ts +123 -0
- package/apps/studio/generation/types.ts +266 -0
- package/apps/studio/generation/whisper-models.test.ts +152 -0
- package/apps/studio/generation/whisper-models.ts +257 -0
- package/apps/studio/generation/whisper-spike-results.md +61 -0
- package/apps/studio/git/service.ts +3 -1
- package/apps/studio/http.ts +867 -9
- package/apps/studio/media/intro.mp4 +0 -0
- package/apps/studio/media-commit-chain.ts +119 -0
- package/apps/studio/paths.ts +10 -0
- package/apps/studio/readiness.ts +108 -20
- package/apps/studio/scaffold-design.ts +1145 -0
- package/apps/studio/server.ts +13 -1
- package/apps/studio/test/_helpers.ts +15 -2
- package/apps/studio/test/acp-bridge.test.ts +34 -1
- package/apps/studio/test/acp-env.test.ts +30 -0
- package/apps/studio/test/acp-plugin-bootstrap.test.ts +23 -57
- package/apps/studio/test/acp-session-plugins.test.ts +72 -1
- package/apps/studio/test/annotation-strokes-command.test.ts +17 -0
- package/apps/studio/test/annotations-layer.test.ts +174 -0
- package/apps/studio/test/canvas-origin-gate.test.ts +37 -0
- package/apps/studio/test/csp-canvas-shell.test.ts +11 -0
- package/apps/studio/test/csrf-write-guard.test.ts +23 -1
- package/apps/studio/test/design-setup-readiness.test.ts +155 -0
- package/apps/studio/test/element-structural-edit.test.ts +108 -0
- package/apps/studio/test/fixtures/fake-claude-auth.mjs +13 -0
- package/apps/studio/test/generate-route.test.ts +106 -0
- package/apps/studio/test/import-asset-browser.test.ts +64 -0
- package/apps/studio/test/import-asset-route.test.ts +71 -0
- package/apps/studio/test/import-asset.test.ts +399 -0
- package/apps/studio/test/import-brand-browser.test.ts +88 -0
- package/apps/studio/test/import-brand-route.test.ts +120 -0
- package/apps/studio/test/import-brand.test.ts +206 -0
- package/apps/studio/test/import-tokens.test.ts +722 -0
- package/apps/studio/test/media-commit-chain.test.ts +210 -0
- package/apps/studio/test/photo-bg-remove-validation.test.ts +71 -0
- package/apps/studio/test/readiness.test.ts +13 -11
- package/apps/studio/test/scaffold-design.test.ts +122 -0
- package/apps/studio/test/tour-overlay.test.tsx +16 -0
- package/apps/studio/tool-palette.tsx +11 -6
- package/apps/studio/ui-prefs.ts +130 -0
- package/apps/studio/use-canvas-media-drop.tsx +4 -2
- package/apps/studio/use-chrome-visibility.tsx +8 -2
- package/apps/studio/whats-new.json +96 -0
- package/apps/studio/ws.ts +5 -0
- package/cli/bin/maude.mjs +6 -6
- package/cli/commands/design.mjs +33 -0
- package/cli/commands/init.mjs +7 -1
- package/cli/lib/gitignore-block.mjs +1 -0
- package/cli/lib/pkg-root.mjs +107 -0
- package/cli/lib/pkg-root.test.mjs +79 -0
- package/cli/lib/reconstruct-toolset.test.mjs +194 -0
- package/cli/lib/update-check.mjs +8 -0
- package/package.json +12 -10
- package/plugins/design/dependencies.json +18 -0
- package/plugins/flow/.claude-plugin/config.schema.json +5 -0
- package/plugins/flow/templates/ai-skeleton/scenario-guide.md +39 -0
- package/plugins/flow/templates/ai-skeleton/scenarios/README.md +2 -0
|
@@ -212,6 +212,20 @@
|
|
|
212
212
|
.st-body > .main { flex: 1; min-width: 0; }
|
|
213
213
|
.st-body > .st-rpanel { flex: 0 0 304px; }
|
|
214
214
|
|
|
215
|
+
/* ─── Dock slot (feature-configurable-panel-docking) ──────────────────────────
|
|
216
|
+
* A left/right slot: an optional tab strip over the active panel, which fills the
|
|
217
|
+
* remaining height. The wrapper owns the resizable width; the inner panel fills
|
|
218
|
+
* it (width:100% wins over the panel's own inline width, which we no longer set). */
|
|
219
|
+
.st-dockslot { display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden; flex: none; }
|
|
220
|
+
.st-dockslot.is-collapsed { width: 0 !important; flex-basis: 0 !important; }
|
|
221
|
+
.st-dockslot > .st-rpanel,
|
|
222
|
+
.st-dockslot > .st-sidebar { flex: 1 1 auto; width: 100%; min-height: 0; }
|
|
223
|
+
.st-docktabs { display: flex; gap: 2px; padding: var(--space-2) var(--space-2) 0; border-bottom: 1px solid var(--border-subtle); background: var(--bg-1); flex: none; }
|
|
224
|
+
.st-docktab { appearance: none; border: 0; background: transparent; cursor: pointer; padding: var(--space-1) var(--space-3); border-radius: var(--radius-sm) var(--radius-sm) 0 0; color: var(--fg-3); font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); transition: color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
|
|
225
|
+
.st-docktab:hover { color: var(--fg-1); background: var(--bg-2); }
|
|
226
|
+
.st-docktab.is-active { color: var(--fg-0); background: var(--bg-2); box-shadow: inset 0 -2px 0 var(--accent); }
|
|
227
|
+
.st-docktab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
228
|
+
|
|
215
229
|
/* ─── Left sidebar — file tree ────────────────────────────────────────────── */
|
|
216
230
|
.st-sidebar {
|
|
217
231
|
width: 252px; flex: 0 0 252px;
|
|
@@ -292,6 +306,20 @@
|
|
|
292
306
|
min-width: 16px; height: 16px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center;
|
|
293
307
|
border-radius: var(--radius-pill); background: var(--accent); color: var(--accent-fg); flex: none;
|
|
294
308
|
}
|
|
309
|
+
/* DDR-174 (T15) — "reconstructed from an image, experimental" marker. Sits left
|
|
310
|
+
of the git/open-count badges (which already claim margin-left:auto), so this
|
|
311
|
+
one gets an explicit left margin instead of fighting for the auto slot.
|
|
312
|
+
`--status-warn` stays on the border only (a UI-component outline needs just
|
|
313
|
+
3:1, which it clears) — a11y-auditor caught it also being used as 9px TEXT
|
|
314
|
+
color failing WCAG AA in light theme (~3.46:1 vs the required 4.5:1); the
|
|
315
|
+
sibling `.st-git-badge[data-kind="M"]` avoids this by using the warn token
|
|
316
|
+
as a fill with a fixed dark foreground instead. Text uses `--fg-2` (the
|
|
317
|
+
DS's own documented AA-clearing muted-text token) so both themes pass. */
|
|
318
|
+
.st-row-exp-badge {
|
|
319
|
+
margin-left: 6px; font-family: var(--font-mono); font-size: 9px; font-weight: 700; letter-spacing: 0.02em;
|
|
320
|
+
line-height: 1; padding: 2px 4px; display: inline-flex; align-items: center; justify-content: center;
|
|
321
|
+
border-radius: var(--radius-xs); border: 1px dashed var(--status-warn); color: var(--fg-2); flex: none;
|
|
322
|
+
}
|
|
295
323
|
/* delete affordance — sibling of the row button (can't nest buttons). */
|
|
296
324
|
.st-row-wrap { position: relative; display: flex; align-items: center; }
|
|
297
325
|
.st-row-wrap .st-row { flex: 1; }
|
|
@@ -352,6 +380,10 @@
|
|
|
352
380
|
.st-empty-body { max-width: 540px; font-size: var(--type-sm); line-height: 1.7; color: var(--fg-2); }
|
|
353
381
|
.st-empty-body code { font-family: var(--font-mono); font-size: var(--type-xs); background: var(--bg-2); color: var(--accent); padding: 1px 5px; border-radius: var(--radius-xs); }
|
|
354
382
|
.st-empty-body strong { color: var(--fg-0); font-weight: 600; }
|
|
383
|
+
/* DDR-166 plan, Phase 2 (T7) — persistent "Setup" affordance, shown only while
|
|
384
|
+
the project's own setup (design system / first canvas / brand assets) is
|
|
385
|
+
incomplete; auto-hides once probeSetupReadiness() reports ready. */
|
|
386
|
+
.st-empty-quick-setup { pointer-events: auto; margin-top: var(--space-2); }
|
|
355
387
|
|
|
356
388
|
/* ═══ Task 6 — right panel (Inspector / Comments) + palette + toast ═══════════ */
|
|
357
389
|
.st-rpanel {
|
|
@@ -495,6 +527,44 @@
|
|
|
495
527
|
.st-dialog-lbl { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
|
|
496
528
|
.st-select { flex: 1; appearance: none; background: var(--bg-2); color: var(--fg-0); border: 1px solid var(--border-default); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); font-family: var(--font-body); font-size: var(--type-sm); cursor: pointer; }
|
|
497
529
|
.st-dialog-ft { display: flex; align-items: center; gap: var(--space-3); justify-content: flex-end; padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-subtle); }
|
|
530
|
+
|
|
531
|
+
/* ── Unified Settings modal (feature-unified-settings-modal) ────────────────
|
|
532
|
+
* One modal for every Maude preference: a vertical tab rail + an internally
|
|
533
|
+
* scrolling pane, so no category can push the dialog off-screen. Extends the
|
|
534
|
+
* shared .st-dialog shell (which already clips + pops). */
|
|
535
|
+
.st-dialog.is-settings { width: 760px; }
|
|
536
|
+
.st-settings-tabs { display: grid; grid-template-columns: 184px 1fr; min-height: 0; }
|
|
537
|
+
.st-settings-rail { display: flex; flex-direction: column; gap: 2px; padding: var(--space-4); border-right: 1px solid var(--border-subtle); background: var(--bg-0); }
|
|
538
|
+
.st-settings-tab { appearance: none; border: 0; background: transparent; text-align: left; cursor: pointer; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); color: var(--fg-2); font-family: var(--font-body); font-size: var(--type-sm); transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
|
|
539
|
+
.st-settings-tab:hover { background: var(--bg-3); color: var(--fg-0); }
|
|
540
|
+
.st-settings-tab.is-active { background: var(--accent-tint); color: var(--fg-0); font-weight: 600; }
|
|
541
|
+
.st-settings-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
542
|
+
/* The scrolling pane — this is the fix for the AI-generation section overflowing
|
|
543
|
+
* the viewport; the pane scrolls, the page never does. */
|
|
544
|
+
.st-settings-pane { max-height: min(72vh, 620px); overflow-y: auto; padding: var(--space-5); }
|
|
545
|
+
.st-settings-pane .st-rp-hd { margin-bottom: var(--space-3); }
|
|
546
|
+
.st-pref-row { display: flex; align-items: flex-start; gap: var(--space-4); justify-content: space-between; padding: var(--space-3) 0; border-bottom: 1px solid var(--border-subtle); cursor: pointer; }
|
|
547
|
+
.st-pref-row:last-child { border-bottom: 0; }
|
|
548
|
+
.st-pref-row.is-disabled { cursor: default; opacity: 0.6; }
|
|
549
|
+
.st-pref-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
|
550
|
+
.st-pref-label { font-size: var(--type-sm); color: var(--fg-0); font-weight: 500; }
|
|
551
|
+
.st-pref-note { font-size: var(--type-xs); color: var(--fg-3); line-height: 1.45; }
|
|
552
|
+
/* Switch — styled checkbox; compositor-only transition (transform/background). */
|
|
553
|
+
.st-switch { appearance: none; flex: none; position: relative; width: 34px; height: 20px; border-radius: 999px; background: var(--bg-4); border: 1px solid var(--border-default); cursor: pointer; transition: background var(--dur-soft) var(--ease-out); margin-top: 2px; }
|
|
554
|
+
.st-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--fg-2); transition: transform var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
|
|
555
|
+
.st-switch:checked { background: var(--accent); border-color: var(--accent); }
|
|
556
|
+
.st-switch:checked::after { transform: translateX(14px); background: var(--accent-fg); }
|
|
557
|
+
.st-switch:disabled { cursor: default; }
|
|
558
|
+
.st-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
559
|
+
@media (prefers-reduced-motion: reduce) { .st-switch, .st-switch::after, .st-settings-tab { transition-duration: 1ms; } }
|
|
560
|
+
/* Layout tab — left/right segmented control per panel. */
|
|
561
|
+
.st-sidetoggle { display: inline-flex; flex: none; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; }
|
|
562
|
+
.st-sidebtn { appearance: none; border: 0; background: var(--bg-2); color: var(--fg-2); cursor: pointer; font-family: var(--font-mono); font-size: var(--type-xs); padding: var(--space-1) var(--space-3); min-width: 46px; transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
|
|
563
|
+
.st-sidebtn + .st-sidebtn { border-left: 1px solid var(--border-default); }
|
|
564
|
+
.st-sidebtn:hover:not(:disabled) { background: var(--bg-3); color: var(--fg-0); }
|
|
565
|
+
.st-sidebtn.is-active { background: var(--accent); color: var(--accent-fg); }
|
|
566
|
+
.st-sidebtn:disabled { opacity: 0.5; cursor: default; }
|
|
567
|
+
.st-sidebtn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
498
568
|
.st-export-recent { display: flex; flex-direction: column; gap: 2px; max-height: 132px; overflow-y: auto; }
|
|
499
569
|
.st-export-recent-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); font-size: var(--type-xs); color: var(--fg-2); }
|
|
500
570
|
.st-export-recent-row:hover { background: var(--bg-2); }
|
|
@@ -509,11 +579,25 @@
|
|
|
509
579
|
.st-ap-err { color: var(--danger, #e5484d); font-family: var(--font-mono); font-size: var(--type-xs); }
|
|
510
580
|
.st-ap-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: var(--space-3); max-height: 52vh; overflow-y: auto; padding: 2px; }
|
|
511
581
|
.st-ap-empty { grid-column: 1 / -1; color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); padding: var(--space-6) 0; text-align: center; }
|
|
512
|
-
.st-ap-cell { appearance: none; cursor: pointer; display: flex; flex-direction: column; gap: 4px; padding: 6px; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); background: var(--bg-2); text-align: left; transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
|
|
582
|
+
.st-ap-cell { position: relative; appearance: none; cursor: pointer; display: flex; flex-direction: column; gap: 4px; padding: 6px; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); background: var(--bg-2); text-align: left; transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
|
|
513
583
|
.st-ap-cell:hover { border-color: var(--accent, var(--border-strong, var(--border-default))); background: var(--bg-3); }
|
|
514
584
|
.st-ap-thumb { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-xs); background: var(--bg-4, var(--bg-3)); display: block; }
|
|
515
585
|
.st-ap-name { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
516
586
|
|
|
587
|
+
/* feature-bulk-media-insert — multi-select grid state + destination toggle + confirm bar */
|
|
588
|
+
.st-ap-cell[data-selected="true"] { border-color: var(--accent); background: var(--bg-3); }
|
|
589
|
+
.st-ap-check { position: absolute; top: 6px; right: 6px; width: 18px; height: 18px; border-radius: var(--radius-pill); border: 1px solid var(--border-default); background: var(--bg-1); color: var(--accent-fg, #fff); display: grid; place-items: center; }
|
|
590
|
+
.st-ap-cell[data-selected="true"] .st-ap-check { background: var(--accent); border-color: var(--accent); }
|
|
591
|
+
.st-ap-confirm { flex-wrap: wrap; }
|
|
592
|
+
.st-ap-count { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
|
|
593
|
+
.st-ap-seg { display: inline-flex; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-2); }
|
|
594
|
+
.st-ap-seg-btn { appearance: none; border: 0; background: transparent; color: var(--fg-2); font-size: var(--type-xs); font-family: var(--font-mono); padding: var(--space-2) var(--space-3); cursor: pointer; }
|
|
595
|
+
.st-ap-seg-btn[aria-pressed="true"] { background: var(--bg-4); color: var(--fg-0); }
|
|
596
|
+
.st-ap-seg-btn:disabled { opacity: 0.45; cursor: default; }
|
|
597
|
+
.st-ap-seg-btn + .st-ap-seg-btn { border-left: 1px solid var(--border-subtle); }
|
|
598
|
+
.st-ap-dest-note { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
|
|
599
|
+
.st-ap-confirm-spacer { flex: 1; }
|
|
600
|
+
|
|
517
601
|
/* ─── StickerPicker (feature-whiteboard-annotation-improvements Phase 4) ──── */
|
|
518
602
|
.st-sticker-picker { width: 640px; }
|
|
519
603
|
.st-sticker-picker .input {
|
|
@@ -637,11 +721,68 @@
|
|
|
637
721
|
* rail; 24px+ targets (bind / seg / box-model inputs); legible box-model. */
|
|
638
722
|
.st-cp { display: flex; flex-direction: column; gap: var(--space-4); }
|
|
639
723
|
|
|
640
|
-
/* element identity — Phase 12.3 (W2.3) hairline under the header for structure
|
|
641
|
-
|
|
724
|
+
/* element identity — Phase 12.3 (W2.3) hairline under the header for structure
|
|
725
|
+
* (Figma-ish). DDR-171 critic pass — this is the panel's own top-level
|
|
726
|
+
* boundary (vs. a section's internal divider below), so it gets the stronger
|
|
727
|
+
* of the two border tokens; otherwise the id-row rule and the first section's
|
|
728
|
+
* `.st-cp-sechd` rule read as identical weight stacked ~40px apart. */
|
|
729
|
+
.st-cp-id { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-strong); }
|
|
642
730
|
.st-cp-idtag { font-family: var(--font-mono); font-size: var(--type-sm); color: var(--fg-0); }
|
|
643
731
|
.st-cp-idcls { color: var(--accent); }
|
|
644
|
-
|
|
732
|
+
/* DDR-171 — the Advanced/Designer vocabulary toggle lives in the `.st-cp-id`
|
|
733
|
+
* row's corner slot as a plain `IconButtonGroup` (`.st-cp-iconseg`, styled
|
|
734
|
+
* below) — no extra wrapper class needed, `.st-cp-id`'s own flex/space-between
|
|
735
|
+
* places it. Deliberately NOT a full-width `Segmented` row (too heavy for a
|
|
736
|
+
* mode switch this minor — every other toggle in this panel is icon-sized).
|
|
737
|
+
* The active glyph gets the stronger accent-tint treatment (normally reserved
|
|
738
|
+
* for `aria-pressed` toggles) rather than the neutral `.is-active` fill every
|
|
739
|
+
* OTHER icon-seg in this panel uses — this one is a mode switch, not a value
|
|
740
|
+
* picker, so "which mode am I in" needs to read at a glance, not just on
|
|
741
|
+
* close inspection. Scoped to `.st-cp-idmode` so it doesn't touch direction /
|
|
742
|
+
* align / overflow etc. */
|
|
743
|
+
.st-cp-idmode .st-cp-iconseg button.is-active { background: var(--accent-tint); color: var(--accent); }
|
|
744
|
+
|
|
745
|
+
/* ── DDR-171 Designer-mode layout refinement ─────────────────────────────────
|
|
746
|
+
* Why Figma's panel reads cleaner than our raw-CSS panel, and what we borrow
|
|
747
|
+
* for Designer mode ONLY (Advanced mode stays byte-identical — it's the
|
|
748
|
+
* DDR-104-critic-gated developer surface where mono labels + provenance dots
|
|
749
|
+
* ARE the point). Three root causes, three scoped fixes:
|
|
750
|
+
*
|
|
751
|
+
* 1. Figma has NO per-row status dot — our provenance dot on every row builds
|
|
752
|
+
* a "punch-card" rail down the left edge. In Designer mode we hide the dot
|
|
753
|
+
* for INHERITED/unset rows (the common case) and keep it only where a value
|
|
754
|
+
* is genuinely token-bound or overridden — that's a useful "this is
|
|
755
|
+
* customized" marker even for a designer, and rare enough not to form a
|
|
756
|
+
* rail. The 14px grid column stays reserved so labels never shift.
|
|
757
|
+
* 2. Figma section headers are quiet title-case ("Auto layout"), not code
|
|
758
|
+
* labels ("AUTO LAYOUT"). We drop the mono/uppercase/tracking for the body
|
|
759
|
+
* font, sentence case, one step brighter — reads as a group heading, not a
|
|
760
|
+
* token name.
|
|
761
|
+
* 3. Figma row labels are soft sans, not monospace — we switch the label font
|
|
762
|
+
* to the body face so the column reads as prose, not a code editor. */
|
|
763
|
+
.st-cp--designer .st-cp-prov--inherit { visibility: hidden; }
|
|
764
|
+
.st-cp--designer .st-cp-sechd {
|
|
765
|
+
font-family: var(--font-body);
|
|
766
|
+
font-size: var(--type-sm);
|
|
767
|
+
font-weight: 600;
|
|
768
|
+
text-transform: none;
|
|
769
|
+
letter-spacing: normal;
|
|
770
|
+
color: var(--fg-1);
|
|
771
|
+
padding-bottom: var(--space-2);
|
|
772
|
+
}
|
|
773
|
+
.st-cp--designer .st-cp-sechd:hover, .st-cp--designer .st-cp-sechd:hover svg { color: var(--fg-0); }
|
|
774
|
+
.st-cp--designer .st-cp-label { font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-1); }
|
|
775
|
+
.st-cp--designer .st-cp-modelabel { font-family: var(--font-body); font-size: var(--type-sm); }
|
|
776
|
+
/* a touch more air between clusters — Figma's sections breathe. */
|
|
777
|
+
.st-cp--designer .st-cp-sec { gap: var(--space-3); }
|
|
778
|
+
|
|
779
|
+
/* a Designer cluster's "···" overflow disclosure — same visual weight as the
|
|
780
|
+
* section reset glyph (`.st-cp-secreset`), right-aligned under the cluster's
|
|
781
|
+
* common rows. */
|
|
782
|
+
.st-cp-clustermore-row { display: flex; justify-content: flex-end; }
|
|
783
|
+
.st-cp-clustermore { appearance: none; cursor: pointer; background: transparent; border: 0; color: var(--fg-3); font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs); }
|
|
784
|
+
.st-cp-clustermore:hover { color: var(--accent); background: var(--accent-tint); }
|
|
785
|
+
.st-cp-clustermore:focus-visible { outline: none; color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
|
|
645
786
|
|
|
646
787
|
/* sections */
|
|
647
788
|
.st-cp-sec { display: flex; flex-direction: column; gap: var(--space-2); }
|
|
@@ -660,13 +801,19 @@
|
|
|
660
801
|
.st-cp-reset { width: 16px; height: 16px; }
|
|
661
802
|
.st-cp-reset:hover, .st-cp-secreset:hover { color: var(--accent); background: var(--accent-tint); }
|
|
662
803
|
.st-cp-reset:focus-visible, .st-cp-secreset:focus-visible { outline: none; color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
|
|
663
|
-
.st-cp-secreset { align-self: center; }
|
|
804
|
+
.st-cp-secreset { align-self: center; display: inline-grid; place-items: center; }
|
|
805
|
+
.st-cp-secreset.is-quiet { color: var(--fg-3); opacity: 0.4; cursor: default; }
|
|
806
|
+
.st-cp-secreset.is-quiet:hover { color: var(--fg-3); background: transparent; }
|
|
664
807
|
/* read-only name field for an existing custom CSS prop / HTML attr row */
|
|
665
808
|
.st-cp-fin--ro { flex: 0 0 38%; background: var(--bg-2); color: var(--fg-2); cursor: default; }
|
|
666
809
|
.st-cp-fin--ro:focus { outline: none; border-color: var(--border-strong); box-shadow: none; }
|
|
667
810
|
|
|
668
|
-
/* a labelled row: [provenance] [css property] [control]
|
|
669
|
-
|
|
811
|
+
/* a labelled row: [provenance] [css property] [control]. DDR-171 critic pass —
|
|
812
|
+
* the dot column widened 10px→14px (was) so the provenance dot reads as a
|
|
813
|
+
* detached status signal instead of looking glued to the label when several
|
|
814
|
+
* rows stack (dot's own size is unchanged — this only adds breathing room,
|
|
815
|
+
* doesn't shrink an already-small interactive/focusable target). */
|
|
816
|
+
.st-cp-row { display: grid; grid-template-columns: 14px 92px 1fr; align-items: center; column-gap: var(--space-3); min-height: 32px; padding: 3px 0; }
|
|
670
817
|
/* #1 bigger-bet — unset rows recede so the overridden ones pop; full opacity on
|
|
671
818
|
* hover/focus so they're still editable. The panel reads as a diff of overrides. */
|
|
672
819
|
.st-cp-row.is-unset { opacity: 0.5; transition: opacity var(--dur-soft) var(--ease-out); }
|
|
@@ -679,7 +826,7 @@
|
|
|
679
826
|
/* provenance — SHAPE-coded so token/override/inherited survive small size +
|
|
680
827
|
* colour-blindness: token = filled accent circle · override = filled neutral
|
|
681
828
|
* square · inherited = hollow ring. Each carries role=img + aria-label. */
|
|
682
|
-
.st-cp-prov { width:
|
|
829
|
+
.st-cp-prov { width: 9px; height: 9px; display: inline-block; flex: none; padding: 0; }
|
|
683
830
|
/* Phase 12.3 (#4) — the row's leading dot is a button: provenance + save status
|
|
684
831
|
* (glow) + double-click reset. No appearance chrome; the variant fills it. */
|
|
685
832
|
/* reset native button chrome; the variants own the FILL (a transparent bg here
|
|
@@ -692,13 +839,12 @@ button.st-cp-prov { appearance: none; border: 0; cursor: default; }
|
|
|
692
839
|
.st-cp-prov.is-saved { box-shadow: 0 0 0 3px color-mix(in oklab, var(--status-success) 45%, transparent); }
|
|
693
840
|
.st-cp-prov.is-saving { box-shadow: 0 0 0 3px color-mix(in oklab, var(--fg-2) 35%, transparent); }
|
|
694
841
|
.st-cp-prov.is-err { background: var(--status-error); border-color: var(--status-error); box-shadow: 0 0 0 3px color-mix(in oklab, var(--status-error) 40%, transparent); }
|
|
695
|
-
/*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
|
|
699
|
-
.st-cp-prov--
|
|
700
|
-
.st-cp-prov--
|
|
701
|
-
.st-cp-prov--inherit { background: transparent; box-shadow: inset 0 0 0 1.5px var(--fg-3); border-radius: 50%; }
|
|
842
|
+
/* handoff — provenance dots match the design specimen (supersedes the older
|
|
843
|
+
* shape-coded/neutral scheme): token-bound = accent · raw override = fg-1 ·
|
|
844
|
+
* inherited = hollow ring. All circles. */
|
|
845
|
+
.st-cp-prov--bound { background: var(--accent); border-radius: 50%; }
|
|
846
|
+
.st-cp-prov--raw { background: var(--fg-1); border-radius: 50%; }
|
|
847
|
+
.st-cp-prov--inherit { background: transparent; box-shadow: inset 0 0 0 1.5px var(--border-strong); border-radius: 50%; }
|
|
702
848
|
|
|
703
849
|
/* colour swatch — standalone (border cluster) + inline (inside the token field) */
|
|
704
850
|
.st-cp-swatch { flex: none; width: 22px; height: 22px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); }
|
|
@@ -739,6 +885,128 @@ body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-sele
|
|
|
739
885
|
.st-cp-bind:hover::before { border-color: var(--accent); }
|
|
740
886
|
.st-cp-numin--mini { flex: none; width: 38px; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); }
|
|
741
887
|
|
|
888
|
+
/* feature-inspector-controls-redesign — shared control library (inspector-controls.jsx).
|
|
889
|
+
* The drag-to-scrub affordance now lives on the LEADING handle, not the input,
|
|
890
|
+
* so click-to-type + select-all work; the input keeps a plain text caret. */
|
|
891
|
+
.st-cp-handle { cursor: ew-resize; touch-action: none; }
|
|
892
|
+
.st-cp-handle:hover { color: var(--fg-1); background: var(--bg-3); }
|
|
893
|
+
.st-cp-grip { display: inline-block; width: 7px; height: 12px; color: var(--fg-2); background-image: radial-gradient(currentColor 0.8px, transparent 0.8px); background-size: 3px 4px; background-position: center; opacity: 0.7; }
|
|
894
|
+
.st-cp-handle:hover .st-cp-grip { opacity: 1; }
|
|
895
|
+
/* static unit suffix inside a number field (e.g. a SliderField's compact numeric) */
|
|
896
|
+
.st-cp-numsuffix { flex: none; display: inline-flex; align-items: center; padding: 0 6px; color: var(--fg-2); font-family: var(--font-mono); font-size: 10px; border-left: 1px solid var(--border-subtle); background: var(--bg-2); }
|
|
897
|
+
/* compact numeric — the exact-value box paired with a Slider */
|
|
898
|
+
.st-cp-num--compact { flex: 0 0 auto; width: 64px; }
|
|
899
|
+
.st-cp-num--compact .st-cp-numin { text-align: right; }
|
|
900
|
+
/* SliderField row: real slider (flex) + compact numeric (fixed) */
|
|
901
|
+
.st-cp-sfield { flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
|
|
902
|
+
/* Toggle (immediate-effect boolean) */
|
|
903
|
+
.st-cp-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; cursor: pointer; color: var(--fg-1); }
|
|
904
|
+
.st-cp-toggle-lbl { color: var(--fg-1); }
|
|
905
|
+
/* handoff — Toggle is a real switch (not a checkbox), matching the DS .switch. */
|
|
906
|
+
.st-cp-switch { appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 34px; height: 18px; border-radius: var(--radius-pill); background: var(--bg-4); border: 1px solid var(--border-default); cursor: pointer; transition: background var(--dur-flip) var(--ease-out), border-color var(--dur-flip) var(--ease-out); }
|
|
907
|
+
.st-cp-switch::after { content: ""; position: absolute; top: 1px; left: 1px; width: 14px; height: 14px; border-radius: var(--radius-pill); background: var(--fg-1); transition: transform var(--dur-flip) var(--ease-out), background var(--dur-flip) var(--ease-out); }
|
|
908
|
+
.st-cp-switch:checked { background: var(--accent); border-color: var(--accent); }
|
|
909
|
+
.st-cp-switch:checked::after { transform: translateX(16px); background: var(--accent-fg); }
|
|
910
|
+
.st-cp-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
911
|
+
/* inline help text under a Field control; wrapping a wide row keeps 3 controls fitting */
|
|
912
|
+
.st-cp-help { flex-basis: 100%; font-size: 10px; color: var(--fg-2); margin-top: 2px; }
|
|
913
|
+
.st-cp-row--wide { flex-wrap: wrap; }
|
|
914
|
+
|
|
915
|
+
/* ════ feature-inspector-controls-redesign — ported design controls ══════════
|
|
916
|
+
* The design-specimen control set promoted into the shared library
|
|
917
|
+
* (inspector-controls.jsx). lucide icons; `.st-cp-*` to match the shell. */
|
|
918
|
+
|
|
919
|
+
/* bipolar slider zero-tick */
|
|
920
|
+
.st-cp-zero { position: absolute; top: -3px; bottom: -3px; width: 1px; background: var(--border-strong); }
|
|
921
|
+
.st-cp-dial--scrub, body.st-scrubbing--dial, body.st-scrubbing--dial * { cursor: grabbing !important; }
|
|
922
|
+
|
|
923
|
+
/* icon button group (flex-direction / justify / align / text-align / overflow) */
|
|
924
|
+
.st-cp-iconseg { display: inline-flex; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-2); }
|
|
925
|
+
.st-cp-iconseg button { appearance: none; border: 0; background: transparent; color: var(--fg-2); min-width: 30px; height: 26px; display: grid; place-items: center; cursor: pointer; transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
|
|
926
|
+
.st-cp-iconseg button + button { border-left: 1px solid var(--border-subtle); }
|
|
927
|
+
.st-cp-iconseg button:hover:not(.is-active) { color: var(--fg-0); background: var(--bg-3); }
|
|
928
|
+
.st-cp-iconseg button.is-active { background: var(--bg-4); color: var(--fg-0); }
|
|
929
|
+
.st-cp-iconseg button[aria-pressed="true"] { background: var(--accent-tint); color: var(--accent); }
|
|
930
|
+
|
|
931
|
+
/* DS checkbox */
|
|
932
|
+
.st-cp-check { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 11px; color: var(--fg-1); cursor: pointer; }
|
|
933
|
+
.st-cp-check input { position: absolute; opacity: 0; width: 0; height: 0; }
|
|
934
|
+
.st-cp-check-box { flex: none; width: 15px; height: 15px; border-radius: var(--radius-xs); border: 1px solid var(--border-strong); background: var(--bg-3); display: grid; place-items: center; color: transparent; transition: background var(--dur-soft) var(--ease-out), border-color var(--dur-soft) var(--ease-out); }
|
|
935
|
+
.st-cp-check input:checked + .st-cp-check-box { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
|
|
936
|
+
.st-cp-check input:focus-visible + .st-cp-check-box { box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
937
|
+
|
|
938
|
+
/* 9-point alignment pad */
|
|
939
|
+
.st-cp-alignpad { width: 68px; height: 68px; display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); flex: none; }
|
|
940
|
+
.st-cp-alignpad button { appearance: none; border: 0; background: transparent; display: grid; place-items: center; cursor: pointer; }
|
|
941
|
+
.st-cp-alignpad button::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--fg-3); transition: background var(--dur-soft) var(--ease-out); }
|
|
942
|
+
.st-cp-alignpad button:hover::before { background: var(--fg-1); }
|
|
943
|
+
.st-cp-alignpad button.is-active::before { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
944
|
+
|
|
945
|
+
/* angle dial */
|
|
946
|
+
.st-cp-dial { flex: none; width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--border-default); background: var(--bg-3); position: relative; cursor: grab; touch-action: none; padding: 0; }
|
|
947
|
+
.st-cp-dial:active { cursor: grabbing; }
|
|
948
|
+
.st-cp-dial:hover { border-color: var(--border-strong); }
|
|
949
|
+
.st-cp-dial:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
950
|
+
.st-cp-dial-needle { position: absolute; top: 50%; left: 50%; width: 11px; height: 1.5px; background: var(--accent); border-radius: 1px; transform-origin: left center; transform: rotate(var(--angle, 0deg)); }
|
|
951
|
+
.st-cp-dial::after { content: ""; position: absolute; top: 50%; left: 50%; width: 4px; height: 4px; border-radius: 50%; background: var(--fg-1); transform: translate(-50%, -50%); }
|
|
952
|
+
|
|
953
|
+
/* collapsable section — height animation + caret rotation (on top of .st-cp-sec) */
|
|
954
|
+
.st-cp-sechd[aria-expanded="false"] .st-cp-caret { transform: rotate(-90deg); }
|
|
955
|
+
.st-cp-caret { transition: transform var(--dur-flip) var(--ease-out); display: inline-grid; place-items: center; }
|
|
956
|
+
.st-cp-sec-anim { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-panel) var(--ease-in-out); }
|
|
957
|
+
.st-cp-sec-anim.is-open { grid-template-rows: 1fr; }
|
|
958
|
+
.st-cp-sec-inner { overflow: hidden; min-height: 0; }
|
|
959
|
+
.st-cp-sec-anim.is-open .st-cp-sec-inner { padding-top: var(--space-1); }
|
|
960
|
+
|
|
961
|
+
/* compact composite colour field — swatch flush prefix + divider, value [+alpha+eye] */
|
|
962
|
+
.st-cp-cf { display: flex; align-items: stretch; min-height: 26px; min-width: 0; flex: 1 1 auto; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out); }
|
|
963
|
+
.st-cp-cf:hover { border-color: var(--border-strong); }
|
|
964
|
+
/* handoff — accent frame ONLY when editing the value input, not when the swatch
|
|
965
|
+
* (popover trigger) has focus — clicking the swatch left a persistent blue frame. */
|
|
966
|
+
.st-cp-cf:has(.st-cp-cf-in:focus) { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
967
|
+
.st-cp-cf .st-cp-tokwrap { display: flex; align-items: stretch; }
|
|
968
|
+
.st-cp-cf > *:last-child { border-top-right-radius: 2px; border-bottom-right-radius: 2px; }
|
|
969
|
+
.st-cp-cf-sw { flex: none; width: 26px; border: 0; border-right: 1px solid var(--border-default); border-radius: 2px 0 0 2px; padding: 0; cursor: pointer; position: relative; overflow: hidden; }
|
|
970
|
+
.st-cp-cf-in { flex: 1 1 auto; min-width: 0; width: 100%; border: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); text-transform: uppercase; padding: 0 var(--space-2); }
|
|
971
|
+
.st-cp-cf-in.is-bound { color: var(--accent); text-transform: none; }
|
|
972
|
+
.st-cp-cf-in:focus { outline: none; }
|
|
973
|
+
.st-cp-cf-alpha { flex: none; width: 42px; border: 0; border-left: 1px solid var(--border-default); background: transparent; color: var(--fg-1); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); text-align: right; padding: 0 6px; }
|
|
974
|
+
.st-cp-cf-alpha:focus { outline: none; }
|
|
975
|
+
.st-cp-cf-eye { flex: none; width: 26px; border: 0; border-left: 1px solid var(--border-default); background: transparent; color: var(--fg-2); cursor: pointer; display: grid; place-items: center; }
|
|
976
|
+
.st-cp-cf-eye:hover { color: var(--fg-0); background: var(--bg-2); }
|
|
977
|
+
.st-cp-cf-eye.is-off { color: var(--fg-3); }
|
|
978
|
+
|
|
979
|
+
/* value-token binding (◇ + bound chip) */
|
|
980
|
+
.st-cp-tokfield { display: flex; align-items: center; gap: var(--space-2); flex: 1 1 auto; min-width: 0; }
|
|
981
|
+
.st-cp-tokfield > .st-cp-num, .st-cp-tokfield > .st-cp-boundchip { flex: 1 1 auto; min-width: 0; }
|
|
982
|
+
.st-cp-tokbtn { flex: none; width: 24px; height: 24px; display: grid; place-items: center; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-2); color: var(--fg-2); cursor: pointer; position: relative; }
|
|
983
|
+
.st-cp-tokbtn:hover { border-color: var(--border-strong); color: var(--fg-0); }
|
|
984
|
+
.st-cp-tokbtn.is-bound { border-color: var(--accent); color: var(--accent); background: var(--accent-tint); }
|
|
985
|
+
.st-cp-boundchip { display: flex; align-items: center; gap: var(--space-2); min-height: 26px; border: 1px solid var(--accent-muted); border-radius: var(--radius-xs); background: var(--accent-tint); padding: 0 var(--space-2); }
|
|
986
|
+
.st-cp-boundchip-lead { display: inline-grid; place-items: center; color: var(--accent); }
|
|
987
|
+
.st-cp-boundchip-name { flex: 1 1 auto; min-width: 0; font-family: var(--font-mono); font-size: var(--type-xs); color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
988
|
+
.st-cp-boundchip-x { flex: none; appearance: none; border: 0; background: transparent; color: var(--accent); cursor: pointer; display: grid; place-items: center; padding: 0 2px; }
|
|
989
|
+
.st-cp-boundchip-x:hover { color: var(--fg-0); }
|
|
990
|
+
|
|
991
|
+
/* corner-radius control — uniform field + detach quad with per-corner glyphs */
|
|
992
|
+
.st-cp-radius { display: grid; gap: var(--space-2); flex: 1 1 auto; min-width: 0; }
|
|
993
|
+
.st-cp-radius-main { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
|
|
994
|
+
.st-cp-radius-main > .st-cp-num { flex: 1 1 auto; min-width: 0; }
|
|
995
|
+
.st-cp-splitbtn { flex: none; width: 24px; height: 24px; display: grid; place-items: center; border: 1px solid transparent; border-radius: var(--radius-xs); background: transparent; color: var(--fg-2); cursor: pointer; }
|
|
996
|
+
.st-cp-splitbtn:hover { color: var(--fg-0); background: var(--bg-3); }
|
|
997
|
+
.st-cp-splitbtn.is-on { color: var(--accent); border-color: var(--accent-muted); background: var(--accent-tint); }
|
|
998
|
+
.st-cp-corners { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
|
|
999
|
+
.st-cp-corner { display: flex; align-items: center; gap: 6px; min-height: 26px; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 0 8px; }
|
|
1000
|
+
.st-cp-corner:hover { border-color: var(--border-strong); }
|
|
1001
|
+
.st-cp-corner:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
1002
|
+
.st-cp-corner input { flex: 1; min-width: 0; width: 100%; appearance: none; border: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; padding: 0; }
|
|
1003
|
+
.st-cp-corner input:focus { outline: none; }
|
|
1004
|
+
.st-cp-cnr { flex: none; width: 11px; height: 11px; border: 1.5px solid var(--fg-2); box-sizing: border-box; }
|
|
1005
|
+
.st-cp-cnr--tl { border-right: 0; border-bottom: 0; border-top-left-radius: 4px; }
|
|
1006
|
+
.st-cp-cnr--tr { border-left: 0; border-bottom: 0; border-top-right-radius: 4px; }
|
|
1007
|
+
.st-cp-cnr--bl { border-right: 0; border-top: 0; border-bottom-left-radius: 4px; }
|
|
1008
|
+
.st-cp-cnr--br { border-left: 0; border-top: 0; border-bottom-right-radius: 4px; }
|
|
1009
|
+
|
|
742
1010
|
/* select (font-weight, border-style) */
|
|
743
1011
|
.st-cp-select { flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; justify-content: space-between; gap: var(--space-2); appearance: none; cursor: pointer; font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-0); background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 4px var(--space-2); min-height: 26px; }
|
|
744
1012
|
.st-cp-select span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -768,9 +1036,12 @@ body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-sele
|
|
|
768
1036
|
.st-cp-bars--just i { width: 100%; }
|
|
769
1037
|
|
|
770
1038
|
/* nested box-model widget (Webflow-style): margin outer · padding inner */
|
|
771
|
-
.st-cp-box { position: relative; margin-top: var(--space-
|
|
772
|
-
.st-cp-boxpad { position: relative; width: 100%; padding: 26px; border: 1px
|
|
773
|
-
|
|
1039
|
+
.st-cp-box { position: relative; margin-top: var(--space-2); padding: 34px 30px; border: 1px dashed var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); display: grid; place-items: center; }
|
|
1040
|
+
.st-cp-boxpad { position: relative; width: 100%; padding: 30px 26px; border: 1px dashed var(--border-subtle); border-radius: var(--radius-xs); background: var(--bg-1); display: grid; place-items: center; }
|
|
1041
|
+
/* handoff — spacing size core is PLAIN mono text (no box/border), 1:1 with the
|
|
1042
|
+
* design's .icp-box-core. Only the position core (--pos, below) is an accent bar. */
|
|
1043
|
+
.st-cp-boxcore { min-width: 72px; padding: 10px 16px; background: transparent; border: 0; color: var(--fg-2); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 10px; text-align: center; }
|
|
1044
|
+
.st-cp-boxcore--pos { padding: 7px 12px; border-radius: var(--radius-xs); font-size: 11px; }
|
|
774
1045
|
.st-cp-boxtag { position: absolute; top: 4px; left: 6px; display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); pointer-events: none; }
|
|
775
1046
|
.st-cp-boxtag .st-cp-prov { width: 6px; height: 6px; }
|
|
776
1047
|
.st-cp-boxv { position: absolute; width: 36px; height: 24px; border: 1px solid transparent; border-radius: var(--radius-xs); background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; text-align: center; padding: 0; }
|
|
@@ -788,27 +1059,33 @@ body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-sele
|
|
|
788
1059
|
.st-cp-boxv--il { left: 0; top: 50%; transform: translateY(-50%); }
|
|
789
1060
|
.st-cp-boxv--ir { right: 0; top: 50%; transform: translateY(-50%); }
|
|
790
1061
|
.st-cp-boxtag--i { color: var(--accent); }
|
|
791
|
-
|
|
1062
|
+
/* handoff — position core IS an accent bar (design); spacing core is plain text */
|
|
1063
|
+
.st-cp-boxcore--pos { text-transform: none; letter-spacing: 0; background: var(--accent-tint); border: 1px solid var(--accent); color: var(--accent); }
|
|
792
1064
|
.st-cp-boxhint { display: flex; flex-wrap: wrap; gap: var(--space-1); }
|
|
793
1065
|
.st-cp-boxhint + .st-cp-row { margin-top: var(--space-1); }
|
|
794
1066
|
.st-cp-chip { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 1px 6px; }
|
|
795
1067
|
|
|
796
1068
|
/* opacity slider — role=slider, focusable */
|
|
797
1069
|
.st-cp-slider { flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
|
|
798
|
-
.st-cp-track { position: relative; flex: 1 1 auto; height: 6px; border-radius: 3px; background: var(--bg-
|
|
1070
|
+
.st-cp-track { position: relative; flex: 1 1 auto; height: 6px; border-radius: 3px; background: var(--bg-2); border: 1px solid var(--border-default); cursor: pointer; }
|
|
799
1071
|
.st-cp-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
800
1072
|
.st-cp-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; background: var(--accent); }
|
|
801
1073
|
.st-cp-thumb { position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%; background: var(--fg-0); border: 2px solid var(--accent); transform: translate(-50%, -50%); }
|
|
802
1074
|
.st-cp-slval { flex: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); color: var(--fg-1); width: 34px; text-align: right; }
|
|
803
1075
|
|
|
804
1076
|
/* border cluster — fills to the right control rail */
|
|
805
|
-
.st-cp-border { flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
|
|
1077
|
+
.st-cp-border { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; }
|
|
806
1078
|
.st-cp-border .st-cp-swatch--mini { margin-left: 0; }
|
|
807
1079
|
/* design-critic 1.1 — the border row was cramming width+style+swatch; the
|
|
808
1080
|
* width field was eating the flex and clipping the style select to "styl▾".
|
|
809
|
-
* Fix the width field, let the style select take the rest.
|
|
1081
|
+
* Fix the width field, let the style select take the rest. Task 5 (feature-
|
|
1082
|
+
* inspector-controls-redesign) — border-width now skips its unit-select
|
|
1083
|
+
* (px-only, opts.fixedUnit) so the cluster is narrower to start with;
|
|
1084
|
+
* flex-wrap is the fallback so [width][style][swatch] never clips at the
|
|
1085
|
+
* panel's 260px minimum — the style select wraps to its own line rather than
|
|
1086
|
+
* shrinking to an illegible sliver. */
|
|
810
1087
|
.st-cp-border .st-cp-num { flex: 0 0 58px; }
|
|
811
|
-
.st-cp-border .st-cp-nsel { flex: 1 1
|
|
1088
|
+
.st-cp-border .st-cp-nsel { flex: 1 1 96px; max-width: none; min-width: 64px; }
|
|
812
1089
|
|
|
813
1090
|
/* per-field save state */
|
|
814
1091
|
/* #5 — error-only now (idle/saved status moved into each row's leading dot). */
|
|
@@ -837,11 +1114,26 @@ body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-sele
|
|
|
837
1114
|
|
|
838
1115
|
/* Stage M — Fixed / Hug / Fill sizing-mode segmented control (per axis). */
|
|
839
1116
|
.st-cp-modes { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-1); }
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
.st-cp-
|
|
843
|
-
.st-cp-
|
|
844
|
-
|
|
1117
|
+
/* handoff — Fixed/Hug/Fill uses the shared Segmented (.st-cp-seg) component,
|
|
1118
|
+
* stretched full-width, with a leading W/H axis label. */
|
|
1119
|
+
.st-cp-modeseg { display: flex; align-items: center; gap: var(--space-2); }
|
|
1120
|
+
.st-cp-modeax { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); }
|
|
1121
|
+
/* handoff — Size mode row: grid-aligned with the other rows (label column +
|
|
1122
|
+
* control column), the compact Segmented right-aligned to match the number
|
|
1123
|
+
* inputs below, at the same 26px input height. Neutral active, mono lowercase. */
|
|
1124
|
+
.st-cp-moderow { display: grid; grid-template-columns: 14px 92px 1fr; align-items: center; column-gap: var(--space-3); min-height: 32px; padding: 3px 0; }
|
|
1125
|
+
.st-cp-modelabel { grid-column: 2; font-size: var(--type-xs); color: var(--fg-1); }
|
|
1126
|
+
.st-cp-modeseg { grid-column: 3; display: flex; justify-content: flex-end; }
|
|
1127
|
+
.st-cp-modeseg .st-cp-seg { flex: none; display: inline-flex; height: 26px; background: var(--bg-2); border-radius: var(--radius-sm); }
|
|
1128
|
+
.st-cp-modeseg .st-cp-segbtn { flex: none; display: inline-flex; align-items: center; font-family: var(--font-mono); font-size: var(--type-xs); text-transform: lowercase; color: var(--fg-2); min-width: 0; min-height: 0; padding: 0 var(--space-4); }
|
|
1129
|
+
.st-cp-modeseg .st-cp-segbtn.is-active { background: var(--bg-4); color: var(--fg-0); }
|
|
1130
|
+
.st-cp-modeseg .st-cp-segbtn:hover:not(.is-active) { background: var(--bg-3); color: var(--fg-0); }
|
|
1131
|
+
/* .st-cp-modebtn — still used by the artboard height-sizing control (not CssKnobs). */
|
|
1132
|
+
.st-cp-modebtn { flex: 1; appearance: none; cursor: pointer; border: 1px solid var(--border-default); border-left-width: 0; background: var(--bg-2); color: var(--fg-2); font-family: var(--font-mono); font-size: 10px; text-transform: lowercase; min-height: 24px; padding: 0 var(--space-2); }
|
|
1133
|
+
.st-cp-modebtn:first-of-type { border-left-width: 1px; border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
|
|
1134
|
+
.st-cp-modebtn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
|
|
1135
|
+
.st-cp-modebtn:hover:not(.is-active):not(:disabled) { background: var(--bg-3); color: var(--fg-0); }
|
|
1136
|
+
.st-cp-modebtn.is-active { background: var(--bg-4); color: var(--fg-0); }
|
|
845
1137
|
.st-cp-modebtn:disabled { opacity: 0.5; cursor: default; }
|
|
846
1138
|
/* Stage M — sub-header for the flex-child row group + the make-flex CTA. */
|
|
847
1139
|
.st-cp-subhd { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); text-transform: uppercase; letter-spacing: 0.04em; margin-top: var(--space-2); }
|
|
@@ -919,6 +1211,17 @@ body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-sele
|
|
|
919
1211
|
* hue slider + eyedropper + hex field. The swatch on the colour row is the only
|
|
920
1212
|
* trigger (no separate native picker). */
|
|
921
1213
|
.st-cp-cpick { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-1); }
|
|
1214
|
+
/* handoff — hex row on top + preview circle + RGB fields (design parity) */
|
|
1215
|
+
.st-cp-cpick-hexrow { display: flex; align-items: center; gap: var(--space-2); }
|
|
1216
|
+
.st-cp-cpick-hexsw { flex: none; width: 34px; height: 26px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); }
|
|
1217
|
+
.st-cp-cpick-hex { flex: 1 1 auto; min-width: 0; appearance: none; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); color: var(--fg-0); font-family: var(--font-mono); font-size: var(--type-xs); padding: 4px var(--space-2); }
|
|
1218
|
+
.st-cp-cpick-hex:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
1219
|
+
.st-cp-cpick-preview { flex: none; width: 20px; height: 20px; border-radius: 50%; border: 1px solid var(--border-default); }
|
|
1220
|
+
.st-cp-cpick-rgb { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
|
|
1221
|
+
.st-cp-cpick-rgbf { display: grid; gap: 2px; justify-items: center; }
|
|
1222
|
+
.st-cp-cpick-rgbf input { width: 100%; text-align: center; appearance: none; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); padding: 3px 2px; }
|
|
1223
|
+
.st-cp-cpick-rgbf input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
|
|
1224
|
+
.st-cp-cpick-rgbf span { font-family: var(--font-mono); font-size: 9px; color: var(--fg-3); }
|
|
922
1225
|
.st-cp-swatch--trigger { position: relative; overflow: hidden; cursor: pointer; appearance: none; padding: 0; }
|
|
923
1226
|
.st-cp-swatch--trigger.is-bound { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
|
|
924
1227
|
.st-cp-cpick-sv { position: relative; display: block; width: 100%; height: 120px; border-radius: var(--radius-sm); border: 1px solid var(--border-default); overflow: hidden; cursor: crosshair; padding: 0; touch-action: none; }
|
|
@@ -1806,6 +2109,9 @@ body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-sele
|
|
|
1806
2109
|
.ob-eyebrow { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--accent); }
|
|
1807
2110
|
.ob-head h1 { margin: 0; font-family: var(--font-display); font-size: var(--type-3xl); line-height: var(--lh-2xl); font-weight: 600; letter-spacing: var(--tracking-tight); }
|
|
1808
2111
|
.ob-head p { margin: 0; max-width: 56ch; color: var(--fg-2); font-size: var(--type-md); line-height: var(--lh-lg); }
|
|
2112
|
+
.ob-watch-intro { align-self: flex-start; display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1); padding: var(--space-2) var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-pill); background: var(--bg-1); color: var(--fg-1); font-size: var(--type-sm); cursor: pointer; }
|
|
2113
|
+
.ob-watch-intro:hover { border-color: var(--border-strong); color: var(--fg-0); background: var(--bg-2); }
|
|
2114
|
+
.ob-watch-intro:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
1809
2115
|
|
|
1810
2116
|
.ob-doors { display: flex; flex-direction: column; gap: var(--space-4); max-width: 720px; }
|
|
1811
2117
|
.ob-door { position: relative; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-4); width: 100%; text-align: left; padding: var(--space-5); border: 1px solid var(--border-default); border-radius: var(--radius-lg); background: var(--bg-1); color: inherit; cursor: pointer; transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out), transform var(--dur-soft) var(--ease-out); }
|