@kitlangton/knobs 0.4.0-next.1 → 0.4.0-next.11
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/README.md +191 -13
- package/dist/dev/{chunk-ayb292zj.js → chunk-75gbzbyd.js} +3 -3
- package/dist/dev/{chunk-1qzffbpa.js → chunk-bnhzf1tj.js} +240 -87
- package/dist/dev/{chunk-8mabjeyk.js → chunk-j57rhjtm.js} +166 -2
- package/dist/dev/{chunk-3ygqgy1x.js → chunk-mjdgzad5.js} +15 -2
- package/dist/dev/index.js +37 -14
- package/dist/index.js +46 -11
- package/dist/panel.js +408 -73
- package/dist/review-react.js +18580 -0
- package/dist/review-solid.js +18482 -0
- package/dist/review.js +18488 -0
- package/dist/themes.js +281 -23
- package/dist/types/core/remote.d.ts +2 -0
- package/dist/types/core/schema.d.ts +13 -1
- package/dist/types/core/store.d.ts +8 -0
- package/dist/types/panel/gpu/renderer.d.ts +2 -0
- package/dist/types/panel/presets.d.ts +7 -1
- package/dist/types/review/font.d.ts +13 -0
- package/dist/types/review/foundations.d.ts +175 -0
- package/dist/types/review/index.d.ts +13 -0
- package/dist/types/review/react.d.ts +1 -0
- package/dist/types/review/solid.d.ts +1 -0
- package/dist/types/themes/index.d.ts +7 -2
- package/dist/types/themes/review.d.ts +8 -0
- package/dist/types/tokens/schema.d.ts +180 -0
- package/dist/types/ui/compare-css.d.ts +1 -1
- package/dist/types/ui/compare-gpu.d.ts +6 -6
- package/dist/types/ui/compare-model.d.ts +85 -2
- package/dist/types/ui/compare.d.ts +18 -4
- package/dist/types/ui/diff.d.ts +4 -5
- package/dist/types/ui/history-css.d.ts +1 -0
- package/dist/types/ui/history-model.d.ts +249 -0
- package/dist/types/ui/history.d.ts +38 -0
- package/dist/types/ui/icons.d.ts +40 -0
- package/dist/types/ui/index.d.ts +8 -4
- package/dist/types/ui/player-css.d.ts +1 -0
- package/dist/types/ui/player.d.ts +51 -0
- package/dist/types/ui/review-look.d.ts +6 -0
- package/dist/types/ui/review-options.d.ts +28 -0
- package/dist/types/ui/selection-pill-css.d.ts +1 -0
- package/dist/types/ui/selection-pill.d.ts +106 -0
- package/dist/types/ui/timeline-model.d.ts +27 -0
- package/dist/types/ui/timeline.d.ts +16 -1
- package/dist/types/ui/tree.d.ts +3 -2
- package/dist/types/ui/walkthrough-annotations.d.ts +42 -0
- package/dist/types/ui/walkthrough-blocks.d.ts +87 -0
- package/dist/types/ui/walkthrough-media.d.ts +30 -1
- package/dist/types/ui/walkthrough-model.d.ts +469 -5
- package/dist/types/ui/walkthrough.d.ts +27 -5
- package/dist/ui-react.js +5124 -1031
- package/dist/ui-solid.js +5136 -1043
- package/dist/ui.js +6411 -2269
- package/package.json +13 -1
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
pushReadout,
|
|
45
45
|
READOUT,
|
|
46
46
|
storageKey
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-mjdgzad5.js";
|
|
48
48
|
import {
|
|
49
49
|
resolveLook,
|
|
50
50
|
themeOf,
|
|
@@ -116,7 +116,7 @@ import {
|
|
|
116
116
|
createHintController,
|
|
117
117
|
pageHints,
|
|
118
118
|
toggleLayer
|
|
119
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-j57rhjtm.js";
|
|
120
120
|
|
|
121
121
|
// src/panel/die.ts
|
|
122
122
|
var ROUND = 16 * Math.sqrt(5), DIE = { half: 64 + ROUND, round: ROUND, pip: 12 }, PIPS = {
|
|
@@ -994,6 +994,9 @@ function resolveActivePresetEntry(entries, currentValues, lastAppliedId, baseId
|
|
|
994
994
|
isCustom: !0
|
|
995
995
|
};
|
|
996
996
|
}
|
|
997
|
+
function presetsTouch(entries, keys, defaults) {
|
|
998
|
+
return entries.some((e) => !(e.kind === "preset" && e.rawId === "default") && keys.some((k) => !same(e.values[k], defaults[k])));
|
|
999
|
+
}
|
|
997
1000
|
function nextPresetIndex(count, activeIndex, direction) {
|
|
998
1001
|
if (count <= 0)
|
|
999
1002
|
return -1;
|
|
@@ -1001,7 +1004,7 @@ function nextPresetIndex(count, activeIndex, direction) {
|
|
|
1001
1004
|
return direction > 0 ? 0 : count - 1;
|
|
1002
1005
|
return ((activeIndex + direction) % count + count) % count;
|
|
1003
1006
|
}
|
|
1004
|
-
function createPresetStrip(doc, controls, showVariants, run, onAfterChange, presetLabel = (id) => controls.presetLabel(id)) {
|
|
1007
|
+
function createPresetStrip(doc, controls, showVariants, run, onAfterChange, presetLabel = (id) => controls.presetLabel(id), relevant) {
|
|
1005
1008
|
let wake = () => onAfterChange?.(), el = (tag, cls, text) => {
|
|
1006
1009
|
let node = doc.createElement(tag);
|
|
1007
1010
|
if (cls)
|
|
@@ -1018,7 +1021,13 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1018
1021
|
saveButton.type = "button", saveButton.tabIndex = -1, saveButton.setAttribute("aria-label", "Save as variant"), saveButton.setAttribute("aria-keyshortcuts", "Shift+S"), saveButton.dataset.hint = "Save", saveButton.onclick = () => run(save);
|
|
1019
1022
|
if (track.append(pill), root.append(track), saveButton)
|
|
1020
1023
|
root.append(saveButton);
|
|
1021
|
-
let pillEdges = new Edges, pillY = new Spring(0, 28, 0.86), pillAlpha = new Spring(1, 26, 0.9), entries = [], buttons = [], signature = "", lastVariantsRef = null, lastAppliedId = null, activeState = { activeId: "p:default", activeIndex: 0, isCustom: !1 }, prevActiveId = "", prevActiveIndex = -2, prevIsCustom = !1, prevDrifted = !1, initializedPill = !1, slideUntil = 0
|
|
1024
|
+
let pillEdges = new Edges, pillY = new Spring(0, 28, 0.86), pillAlpha = new Spring(1, 26, 0.9), entries = [], buttons = [], signature = "", lastVariantsRef = null, lastAppliedId = null, activeState = { activeId: "p:default", activeIndex: 0, isCustom: !1 }, prevActiveId = "", prevActiveIndex = -2, prevIsCustom = !1, prevDrifted = !1, initializedPill = !1, slideUntil = 0, unpinned = (values) => {
|
|
1025
|
+
let out;
|
|
1026
|
+
for (let k of Object.keys(values))
|
|
1027
|
+
if (controls.isPinned(k) && !same(values[k], controls.locked[k]))
|
|
1028
|
+
out ??= { ...values }, out[k] = controls.locked[k];
|
|
1029
|
+
return out ?? values;
|
|
1030
|
+
};
|
|
1022
1031
|
function buildEntries() {
|
|
1023
1032
|
let presetEntries = Object.entries(controls.presets).map(([id, presetValues]) => ({
|
|
1024
1033
|
id: `p:${id}`,
|
|
@@ -1035,7 +1044,7 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1035
1044
|
kind: "variant",
|
|
1036
1045
|
rawId: v.id,
|
|
1037
1046
|
label: v.name ?? v.id.slice(0, 8),
|
|
1038
|
-
values: v.values,
|
|
1047
|
+
values: unpinned(v.values),
|
|
1039
1048
|
apply: (coalesce) => controls.variants.load(v.id, { coalesce })
|
|
1040
1049
|
}));
|
|
1041
1050
|
return [...presetEntries, ...variantEntries];
|
|
@@ -1070,7 +1079,12 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1070
1079
|
if (pill.style.left = `${left}px`, pill.style.right = `${box.trackWidth - right}px`, pill.style.top = `${top}px`, pill.style.height = `${box.height}px`, pill.style.opacity = activeState.drifted ? String(DRIFTED_PILL) : "1", pill.style.scale = "", first)
|
|
1071
1080
|
doc.defaultView?.requestAnimationFrame(() => pill.style.transition = "");
|
|
1072
1081
|
}
|
|
1073
|
-
let resolve = () => resolveActivePresetEntry(entries, controls.get(), lastAppliedId, activeEntryId(controls));
|
|
1082
|
+
let resolve = () => resolveActivePresetEntry(entries, unpinned(controls.get()), lastAppliedId, activeEntryId(controls)), wanted = (list) => (list.length > 1 || showVariants) && (relevant?.(list) ?? !0);
|
|
1083
|
+
function syncShown() {
|
|
1084
|
+
let show = wanted(entries);
|
|
1085
|
+
if (root.hidden === show && root.dataset.presence === void 0)
|
|
1086
|
+
root.hidden = !show;
|
|
1087
|
+
}
|
|
1074
1088
|
function syncSelection(snap = !1) {
|
|
1075
1089
|
if (activeState = resolve(), lastAppliedId !== null && activeState.activeId !== lastAppliedId)
|
|
1076
1090
|
lastAppliedId = null;
|
|
@@ -1110,12 +1124,12 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1110
1124
|
run(() => {
|
|
1111
1125
|
let variantsRef = showVariants ? controls.variants.list() : null;
|
|
1112
1126
|
if (signature !== "" && variantsRef === lastVariantsRef) {
|
|
1113
|
-
syncSelection(!1);
|
|
1127
|
+
syncShown(), syncSelection(!1);
|
|
1114
1128
|
return;
|
|
1115
1129
|
}
|
|
1116
1130
|
lastVariantsRef = variantsRef;
|
|
1117
|
-
let nextEntries = buildEntries(), nextSig = JSON.stringify(nextEntries.map((e) => [e.id, e.label]))
|
|
1118
|
-
if (
|
|
1131
|
+
let nextEntries = buildEntries(), nextSig = JSON.stringify(nextEntries.map((e) => [e.id, e.label]));
|
|
1132
|
+
if (entries = nextEntries, syncShown(), nextSig !== signature)
|
|
1119
1133
|
signature = nextSig, entries = nextEntries, buttons = entries.map((entry, idx) => {
|
|
1120
1134
|
let b = el("button", "knobs-preset-chip", entry.label);
|
|
1121
1135
|
return b.type = "button", b.tabIndex = -1, b.dataset.presetId = entry.id, b.dataset.presetKind = entry.kind, b.dataset.presetName = entry.label, b.setAttribute("role", "radio"), b.setAttribute("aria-label", entry.label), b.onclick = (e) => {
|
|
@@ -1286,6 +1300,7 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1286
1300
|
getEntries: () => entries,
|
|
1287
1301
|
getButtons: () => buttons,
|
|
1288
1302
|
getActiveState: () => activeState,
|
|
1303
|
+
shows: () => wanted(entries),
|
|
1289
1304
|
cycle,
|
|
1290
1305
|
selectById,
|
|
1291
1306
|
save: () => {
|
|
@@ -3762,7 +3777,9 @@ class GpuOverlayManager {
|
|
|
3762
3777
|
let ro = new ResizeObserver(() => {
|
|
3763
3778
|
this.wake();
|
|
3764
3779
|
});
|
|
3765
|
-
ro.observe(panel.root), ro.observe(panel.body),
|
|
3780
|
+
if (ro.observe(panel.root), ro.observe(panel.body), panel.pinned)
|
|
3781
|
+
ro.observe(panel.pinned);
|
|
3782
|
+
ro.observe(panel.presetStrip.track);
|
|
3766
3783
|
let mo = new MutationObserver(() => {
|
|
3767
3784
|
this.styleVersion++, this.wake();
|
|
3768
3785
|
});
|
|
@@ -5838,8 +5855,9 @@ class GpuOverlayManager {
|
|
|
5838
5855
|
], this.maskCount * MASK_FLOATS), this.curMask = ++this.maskCount;
|
|
5839
5856
|
}
|
|
5840
5857
|
}
|
|
5841
|
-
let ps = panel.presetStrip, hinting = panel.root.classList.contains("knobs-hinting");
|
|
5858
|
+
let ps = panel.presetStrip, hinting = panel.root.classList.contains("knobs-hinting"), stripAlpha = this.curAlpha;
|
|
5842
5859
|
if (!ps.element.hidden) {
|
|
5860
|
+
this.curAlpha = stripAlpha * this.presence(ps.element);
|
|
5843
5861
|
let psHovered = this.curPanelHovered && ps.element.matches(":hover");
|
|
5844
5862
|
this.curSubHovered = psHovered;
|
|
5845
5863
|
let psRect = this.rectOf(ps.element), trackRect = this.rectOf(ps.track);
|
|
@@ -5941,6 +5959,7 @@ class GpuOverlayManager {
|
|
|
5941
5959
|
align: "center"
|
|
5942
5960
|
});
|
|
5943
5961
|
}
|
|
5962
|
+
this.curAlpha = stripAlpha;
|
|
5944
5963
|
}
|
|
5945
5964
|
let tabs = panel.tabs;
|
|
5946
5965
|
if (tabs && !tabs.element.hidden)
|
|
@@ -6042,7 +6061,7 @@ class GpuOverlayManager {
|
|
|
6042
6061
|
}
|
|
6043
6062
|
if (bodyRevealing || pageMoving)
|
|
6044
6063
|
this.curBypassRectCache = !0;
|
|
6045
|
-
let bodyHovered = this.curPanelHovered && panel.body.matches(":hover");
|
|
6064
|
+
let bodyHovered = this.curPanelHovered && (panel.body.matches(":hover") || Boolean(panel.pinned?.matches(":hover")));
|
|
6046
6065
|
this.curSubHovered = bodyHovered, this.curPointerRow = bodyHovered && panel.root.hasAttribute("data-k-row-hover");
|
|
6047
6066
|
let panelAlpha = this.curAlpha;
|
|
6048
6067
|
for (let g of panel.groups) {
|
|
@@ -11446,14 +11465,23 @@ var compareCss = `
|
|
|
11446
11465
|
.knobs-ui.knobs-compare{--_ku-cmp-diff:var(--k-compare-diff,var(--_k-ok));--_ku-cmp-line:var(--_k-compare-divider);
|
|
11447
11466
|
--_ku-cmp-stage:var(--_k-compare-stage);
|
|
11448
11467
|
display:flex;flex-direction:column;gap:6px;width:100%;height:100%;min-height:160px;outline:none;user-select:none;-webkit-user-select:none;
|
|
11449
|
-
font:var(--_k-weight) var(--_k-
|
|
11468
|
+
font:var(--_k-weight) var(--_k-type-small)/var(--_k-leading-small) var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
11450
11469
|
:where(.knobs-ui) :is(.knobs-cmp-mode,.knobs-cmp-toggle){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
|
|
11451
|
-
.knobs-cmp-bar{flex:none;display:flex;align-items:center;gap:
|
|
11452
|
-
|
|
11453
|
-
|
|
11454
|
-
|
|
11455
|
-
.knobs-
|
|
11456
|
-
|
|
11470
|
+
.knobs-cmp-bar{flex:none;display:flex;align-items:center;gap:var(--_k-gap);height:var(--_k-control-h)}
|
|
11471
|
+
/* The modes: one fill, the selection pill on the one picked; a mode isn't brighter for being
|
|
11472
|
+
picked: the pill's bright copy is. */
|
|
11473
|
+
.knobs-cmp-modes{position:relative;display:inline-flex;height:var(--_k-control-h);border-radius:var(--_k-radius);background:var(--_k-fill)}
|
|
11474
|
+
.knobs-cmp-modes[hidden]{display:none}
|
|
11475
|
+
/* Hover is a quiet fill under the arrow cursor (no hand, no brightening), there at once. */
|
|
11476
|
+
.knobs-ui .knobs-cmp-mode{display:inline-flex;align-items:center;height:100%;padding:0 8px;border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:default;white-space:nowrap;
|
|
11477
|
+
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
11478
|
+
.knobs-ui .knobs-cmp-mode:not([aria-checked="true"]):is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
11479
|
+
/* Toggles: icon buttons, the accent's wash when on. */
|
|
11480
|
+
.knobs-ui .knobs-cmp-toggle{display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:default;
|
|
11481
|
+
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
11482
|
+
.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
11483
|
+
.knobs-ui .knobs-cmp-toggle[aria-pressed="true"]{color:var(--_k-accent-fg);background:var(--_k-accent-soft)}
|
|
11484
|
+
.knobs-cmp-toggle svg{display:block}
|
|
11457
11485
|
.knobs-cmp-fill{flex:1}
|
|
11458
11486
|
.knobs-cmp-toggle[hidden]{display:none}
|
|
11459
11487
|
/* One surface: on a card (a walkthrough's step, a split's pane, anything .knobs-surface) or marked
|
|
@@ -11466,49 +11494,96 @@ var compareCss = `
|
|
|
11466
11494
|
.knobs-compare[data-frame="flat"] .knobs-cmp-stage{border-radius:0}
|
|
11467
11495
|
.knobs-compare[data-mode="wipe"] .knobs-cmp-stage{cursor:ew-resize}
|
|
11468
11496
|
/* Unzoomed, a finger still scrolls the page up and down; zoomed, the stage takes every gesture. */
|
|
11469
|
-
.
|
|
11470
|
-
.knobs-compare[data-
|
|
11471
|
-
.knobs-compare[data-
|
|
11497
|
+
/* Zoomed, it pans: a move cursor, never a hand. */
|
|
11498
|
+
.knobs-compare[data-zoomed] .knobs-cmp-stage{cursor:move;touch-action:none}
|
|
11499
|
+
.knobs-compare[data-panning],.knobs-compare[data-panning] *{cursor:move!important}
|
|
11500
|
+
/* Wiping, the grip stands in for the cursor. */
|
|
11501
|
+
.knobs-compare[data-dragging],.knobs-compare[data-dragging] *{cursor:none!important}
|
|
11472
11502
|
.knobs-cmp-sizer{position:absolute;left:0;right:0;top:0;height:0;visibility:hidden;pointer-events:none}
|
|
11473
11503
|
.knobs-cmp-canvas{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none}
|
|
11474
11504
|
.knobs-cmp-media{position:absolute;left:0;top:0;display:block;max-width:none;margin:0;padding:0;border:0;object-fit:fill;transform-origin:0 0;pointer-events:none;will-change:transform}
|
|
11475
11505
|
.knobs-compare[data-renderer="gpu"] .knobs-cmp-media{opacity:0}
|
|
11476
|
-
/*
|
|
11477
|
-
.knobs-cmp-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
.knobs-cmp-label
|
|
11481
|
-
.
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
.knobs-cmp-
|
|
11485
|
-
.knobs-cmp-
|
|
11486
|
-
|
|
11487
|
-
.knobs-cmp-
|
|
11488
|
-
|
|
11489
|
-
|
|
11490
|
-
.knobs-cmp-
|
|
11506
|
+
/* The media comes in with its first frames: a fade and a 4px blur on the default spring. */
|
|
11507
|
+
.knobs-cmp-canvas,.knobs-compare[data-renderer="dom"] .knobs-cmp-media{transition:opacity calc(var(--_k-motion-default-ms) * 1ms) var(--_k-motion-default),filter calc(var(--_k-motion-default-ms) * 1ms) var(--_k-motion-default)}
|
|
11508
|
+
.knobs-compare:not([data-ready]) :is(.knobs-cmp-canvas,.knobs-cmp-media){opacity:0;filter:blur(4px)}
|
|
11509
|
+
/* Over the pictures: a quiet scrim, dark in either appearance, blurred, with no ring. */
|
|
11510
|
+
.knobs-cmp-label,.knobs-cmp-zoom,.knobs-cmp-grip{background:var(--_ku-media-scrim);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
|
|
11511
|
+
/* ✗ Before · ✓ After: Before quieter, After in full. Neutral: no colour of its own. */
|
|
11512
|
+
.knobs-cmp-label{position:absolute;left:0;top:0;display:flex;align-items:center;gap:4px;padding:1px 7px 1px 5px;border-radius:999px;font-weight:var(--_k-weight-label);
|
|
11513
|
+
white-space:nowrap;pointer-events:none;will-change:transform}
|
|
11514
|
+
.knobs-cmp-label[data-side="before"]{color:var(--_ku-on-media-2)}
|
|
11515
|
+
.knobs-cmp-label[data-side="after"]{color:var(--_ku-on-media)}
|
|
11516
|
+
/* Fusing, the mark folds away and the label is its name. */
|
|
11517
|
+
.knobs-cmp-mark{flex:none;display:flex;justify-content:flex-end;overflow:hidden}
|
|
11518
|
+
.knobs-cmp-mark svg{display:block;flex:none;width:12px;height:12px}
|
|
11519
|
+
/* The fuse's seam: a blurred strip over where the sides meet, soft at both sides. */
|
|
11520
|
+
.knobs-cmp-seam{position:absolute;left:0;top:0;width:8px;height:0;opacity:0;pointer-events:none;will-change:transform,opacity;
|
|
11521
|
+
-webkit-mask-image:linear-gradient(to right,transparent,#000 35%,#000 65%,transparent);mask-image:linear-gradient(to right,transparent,#000 35%,#000 65%,transparent)}
|
|
11522
|
+
/* The wipe: a hairline down the line with a raised grip in its middle (at the pointer's height
|
|
11523
|
+
while dragged); a wider strip takes the hand and the keys (a slider). It fades in with the
|
|
11524
|
+
fuse; wiping, line and grip brighten. */
|
|
11525
|
+
.knobs-cmp-handle{cursor:ew-resize;position:absolute;left:-12px;top:0;width:24px;height:0;opacity:0;pointer-events:none;outline:none;will-change:transform,opacity}
|
|
11526
|
+
.knobs-cmp-handle[data-on]{pointer-events:auto}
|
|
11527
|
+
.knobs-cmp-handle::before{content:"";position:absolute;top:0;bottom:0;left:11.5px;width:1px;background:color-mix(in srgb,var(--_ku-cmp-line) 72%,transparent);box-shadow:0 0 6px var(--_ku-media-scrim)}
|
|
11528
|
+
.knobs-compare[data-dragging] .knobs-cmp-handle::before{background:var(--_ku-cmp-line)}
|
|
11529
|
+
.knobs-cmp-grip{position:absolute;top:0;left:4px;width:16px;height:28px;border-radius:min(8px,calc(var(--_k-radius) * 999));will-change:transform}
|
|
11530
|
+
.knobs-cmp-grip::before,.knobs-cmp-grip::after{content:"";position:absolute;top:10px;width:1px;height:8px;background:var(--_ku-on-media-2);transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
11531
|
+
.knobs-cmp-grip::before{left:6px}
|
|
11532
|
+
.knobs-cmp-grip::after{left:9px}
|
|
11533
|
+
.knobs-compare[data-dragging] .knobs-cmp-grip::before,.knobs-compare[data-dragging] .knobs-cmp-grip::after{background:var(--_ku-on-media)}
|
|
11534
|
+
.knobs-cmp-handle:focus-visible .knobs-cmp-grip,.knobs-compare[data-keyboard] .knobs-cmp-handle:focus .knobs-cmp-grip{box-shadow:0 0 0 2px var(--_k-accent)}
|
|
11491
11535
|
/* The split's hairline, down the middle side by side. */
|
|
11492
11536
|
.knobs-cmp-split{position:absolute;left:0;top:0;width:1px;height:0;margin-left:-.5px;background:color-mix(in srgb,var(--_k-bg) 72%,transparent);pointer-events:none;will-change:transform,opacity}
|
|
11493
11537
|
/* Zoomed: how far, and a way back, in the stage's corner; it fades in and out, nothing shifts. */
|
|
11494
11538
|
.knobs-cmp-zoom{position:absolute;right:8px;bottom:8px;display:flex;align-items:center;gap:4px;height:26px;padding:0 3px 0 10px;border-radius:999px;
|
|
11495
|
-
color:var(--
|
|
11539
|
+
color:var(--_ku-on-media);font-variant-numeric:tabular-nums;font-feature-settings:var(--_kr-data,"tnum");white-space:nowrap;
|
|
11496
11540
|
opacity:0;scale:.96;pointer-events:none;transition:opacity .16s cubic-bezier(.4,0,1,1),scale .16s cubic-bezier(.4,0,1,1)}
|
|
11497
11541
|
.knobs-cmp-zoom[data-on]{opacity:1;scale:1;pointer-events:auto;transition:opacity .2s cubic-bezier(.2,.8,.2,1),scale .2s cubic-bezier(.2,.8,.2,1)}
|
|
11498
11542
|
:where(.knobs-ui) .knobs-cmp-zoom-reset{all:revert;box-sizing:border-box;font:inherit;letter-spacing:inherit;margin:0;border:0;outline:none;box-shadow:none;
|
|
11499
|
-
height:20px;padding:0
|
|
11500
|
-
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){
|
|
11501
|
-
.knobs-cmp-note{position:absolute;left:50%;top:50%;translate:-50% -50%;color:var(--_k-fg-3);
|
|
11543
|
+
display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border-radius:999px;background:transparent;color:var(--_ku-on-media-2);cursor:default;transition:background calc(var(--_k-hover-out) * 1ms),color calc(var(--_k-hover-out) * 1ms)}
|
|
11544
|
+
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){background:color-mix(in srgb,var(--_ku-on-media) 16%,transparent);color:var(--_ku-on-media);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
11545
|
+
.knobs-cmp-note{position:absolute;left:50%;top:50%;translate:-50% -50%;color:var(--_k-fg-3);pointer-events:none}
|
|
11502
11546
|
.knobs-cmp-note:empty{display:none}
|
|
11503
11547
|
.knobs-cmp-strip-host{flex:none;height:60px;min-height:0}
|
|
11504
|
-
.knobs-cmp-timeline-host{flex:none;
|
|
11548
|
+
.knobs-cmp-timeline-host{flex:none;min-height:0}
|
|
11505
11549
|
/* The frame strip: Before over After per column, a difference bar under them, a dot where it peaks. */
|
|
11506
11550
|
.knobs-ui.knobs-cmp-strip{--_ku-cmp-diff:var(--k-compare-diff,var(--_k-ok));position:relative;width:100%;height:100%;min-height:40px;overflow:hidden;cursor:col-resize;touch-action:none;
|
|
11507
|
-
font:var(--_k-weight) var(--_k-
|
|
11551
|
+
font:var(--_k-weight) var(--_k-type-small)/var(--_k-leading-small) var(--_k-font);color:var(--_k-fg)}
|
|
11508
11552
|
.knobs-cmp-strip>canvas{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none}
|
|
11509
11553
|
@media(prefers-reduced-motion:reduce){:is(.knobs-compare,.knobs-cmp-strip) :where(*,::before,::after){transition-duration:.12s!important}}
|
|
11510
11554
|
`;
|
|
11511
11555
|
|
|
11556
|
+
// src/ui/player-css.ts
|
|
11557
|
+
var playerCss = `
|
|
11558
|
+
:where(.knobs-player,.knobs-player *){box-sizing:border-box}
|
|
11559
|
+
.knobs-ui.knobs-player{--_kp-stage:var(--_k-compare-stage);display:flex;flex-direction:column;gap:6px;width:100%;outline:none;
|
|
11560
|
+
font:var(--_k-weight) var(--_k-type-small)/var(--_k-leading-small) var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
11561
|
+
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui.knobs-player,.knobs-ui.knobs-player[data-nested]{--_kp-stage:var(--k-compare-stage,transparent)}
|
|
11562
|
+
.knobs-player-frame{position:relative;width:100%;aspect-ratio:var(--kp-aspect,16/9);overflow:hidden;border-radius:var(--_k-radius-panel);background:var(--_kp-stage)}
|
|
11563
|
+
.knobs-player[data-frame="flat"] .knobs-player-frame{border-radius:0}
|
|
11564
|
+
.knobs-player-media{position:absolute;inset:0;display:block;width:100%;height:100%;margin:0;padding:0;border:0;object-fit:contain;
|
|
11565
|
+
opacity:0;filter:blur(4px);transition:opacity calc(var(--_k-motion-default-ms) * 1ms) var(--_k-motion-default),filter calc(var(--_k-motion-default-ms) * 1ms) var(--_k-motion-default)}
|
|
11566
|
+
.knobs-player[data-ready] .knobs-player-media{opacity:1;filter:none}
|
|
11567
|
+
.knobs-player-line{flex:none;min-height:0}
|
|
11568
|
+
/* The timeline's own stylesheet is look.ts's; what the player's row and every timeline share
|
|
11569
|
+
about the hand is set here, after it. No hand cursor anywhere (the arrow, or a resize where it
|
|
11570
|
+
resizes); hover is a quiet fill (fill-hover), in at once (hover-in, 0 ms), out easing. */
|
|
11571
|
+
.knobs-ui .knobs-tl-play,.knobs-ui.knobs-timeline :is(.knobs-tl-pin,.knobs-tl-rlabel),
|
|
11572
|
+
.knobs-ui.knobs-timeline[data-dragging] .knobs-tl-marker :is(.knobs-tl-pin,.knobs-tl-mlabel){cursor:default}
|
|
11573
|
+
.knobs-ui .knobs-tl-play:hover,.knobs-tl-edge:hover::after,.knobs-tl-rlabel:hover,.knobs-tl-track:hover .knobs-tl-hover,
|
|
11574
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-track:hover .knobs-tl-segs{transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
11575
|
+
/* The line's row: a minimal play/pause (the filled pair, a 28px target, no fill at rest), then
|
|
11576
|
+
the line, centred on it. */
|
|
11577
|
+
.knobs-ui.knobs-timeline[data-variant="line"]{gap:4px;align-items:center}
|
|
11578
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-transport{display:flex}
|
|
11579
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-play{width:28px;height:28px;min-width:28px;min-height:28px;border-radius:var(--_k-radius);background:transparent;color:var(--_k-fg-2);
|
|
11580
|
+
transition:background calc(var(--_k-hover-out) * 1ms),transform .15s var(--_ku-ease)}
|
|
11581
|
+
.knobs-ui.knobs-timeline[data-variant="line"][data-playing] .knobs-tl-play{background:transparent;color:var(--_k-fg-2)}
|
|
11582
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-play:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
11583
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track{cursor:default;transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
11584
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
11585
|
+
`;
|
|
11586
|
+
|
|
11512
11587
|
// src/ui/overlay-css.ts
|
|
11513
11588
|
var overlayCss = `
|
|
11514
11589
|
.knobs-layers{position:fixed;inset:0;z-index:2147480005;pointer-events:none}
|
|
@@ -11640,7 +11715,7 @@ var snappy = springLinear(SPRINGS2.snappy), pickerCss = `
|
|
|
11640
11715
|
.knobs-picker-suggested{flex:none;color:var(--_k-fg-3);font-size:var(--_k-text-meta)}
|
|
11641
11716
|
.knobs-picker-check{flex:none;display:flex;width:14px;height:14px;color:var(--_k-accent);opacity:0;scale:.6;filter:blur(2px);
|
|
11642
11717
|
transition:opacity .11s ease-in,scale .11s ease-in,filter .11s ease-in}
|
|
11643
|
-
.knobs-picker-check svg{display:block;width:
|
|
11718
|
+
.knobs-picker-check svg{display:block;width:12px;height:12px}
|
|
11644
11719
|
.knobs-picker-option[data-chosen] .knobs-picker-check{opacity:1;scale:1;filter:none;transition:opacity .15s ease-out,scale var(--kp-snappy-ms) var(--kp-snappy),filter .15s ease-out}
|
|
11645
11720
|
.knobs-picker-body{position:relative;overflow:visible}
|
|
11646
11721
|
.knobs-picker-body[data-moving]{overflow:hidden}
|
|
@@ -11742,6 +11817,15 @@ var readoutCss = `
|
|
|
11742
11817
|
.knobs-panel[data-gpu-active="true"] .knobs-rd-find{position:relative;z-index:2147480003}
|
|
11743
11818
|
@media(prefers-reduced-motion:reduce){.knobs-rd :where(*){transition:none!important}}
|
|
11744
11819
|
`;
|
|
11820
|
+
|
|
11821
|
+
// src/ui/selection-pill-css.ts
|
|
11822
|
+
var selectionPillCss = `
|
|
11823
|
+
.knobs-pick-pill,.knobs-pick-copy{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;transition:opacity .1s linear}
|
|
11824
|
+
.knobs-pick-pill{background:var(--_k-fill-selected);will-change:transform}
|
|
11825
|
+
.knobs-pick-copy{overflow:hidden;will-change:transform}
|
|
11826
|
+
.knobs-pick-copy-rows{position:absolute;left:0;top:0;width:0;height:0}
|
|
11827
|
+
:is(.knobs-pick-pill,.knobs-pick-copy)[data-off]{opacity:0}
|
|
11828
|
+
`;
|
|
11745
11829
|
// src/ui/look.ts
|
|
11746
11830
|
var css = `
|
|
11747
11831
|
:where(.knobs-ui){
|
|
@@ -11753,6 +11837,9 @@ var css = `
|
|
|
11753
11837
|
--_ku-wash:var(--k-ui-wash,color-mix(in srgb,var(--_k-fill) 70%,transparent));
|
|
11754
11838
|
--_ku-wash-hi:var(--k-ui-wash-hi,var(--_k-fill-selected));
|
|
11755
11839
|
--_ku-ease:var(--_k-motion-snappy);--_ku-ease-ms:calc(var(--_k-motion-snappy-ms) * 1ms);
|
|
11840
|
+
/* Over a picture: a quiet dark scrim in either appearance (a picture is no lighter in light
|
|
11841
|
+
mode), light type on it, no ring. */
|
|
11842
|
+
--_ku-media-scrim:rgb(0 0 0/.5);--_ku-on-media:#fff;--_ku-on-media-2:color-mix(in srgb,var(--_ku-on-media) 64%,transparent);
|
|
11756
11843
|
/* The card frame (knobs' own look): every leaf pane a rounded card on the page, half a gap
|
|
11757
11844
|
inside its slot, so panes sit a gap apart with the dividers' grips between them; tree rows
|
|
11758
11845
|
inset as soft rounded washes. --k-frame: flat (labPreset) puts panes edge to edge on
|
|
@@ -11777,6 +11864,12 @@ var css = `
|
|
|
11777
11864
|
--_ku-pane-bg and --_ku-pane-ring so this reaches them. */
|
|
11778
11865
|
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui:not(.knobs-surface),.knobs-ui[data-nested]{--_ku-gap:var(--k-ui-gap,0px);--_ku-pane-bg:transparent;--_ku-pane-ring:none;
|
|
11779
11866
|
--_ku-divider:var(--_k-split-gutter);--_kd-bg:transparent}
|
|
11867
|
+
/* What draws its box without those: a picker's card keeps its fill as the highlight but drops its
|
|
11868
|
+
ring; a timeline's track drops its well for a hairline under the lane; an inline panel sheds its
|
|
11869
|
+
card (--k-chrome 0). A full-window step is the one raised exception (it is the surface). */
|
|
11870
|
+
:is(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-picker-card,.knobs-ui[data-nested] .knobs-picker-card{box-shadow:none}
|
|
11871
|
+
:is(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-tl-track,.knobs-ui[data-nested] .knobs-tl-track{background:transparent;border-radius:0;box-shadow:inset 0 -1px 0 var(--_k-border-subtle)}
|
|
11872
|
+
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-panel.knobs-inline:not(.knobs-page){--k-chrome:0}
|
|
11780
11873
|
/* Only the pieces' own elements take their type and resets: what you put in a pane is yours. */
|
|
11781
11874
|
.knobs-ui{box-sizing:border-box}
|
|
11782
11875
|
:where(.knobs-split>*,.knobs-pane-clip,.knobs-pane-inner,.knobs-pane-body,.knobs-pane-head,.knobs-pane-head *,.knobs-pane-rail,.knobs-pane-rail *,.knobs-tree,.knobs-tree *,.knobs-tree-ghost){box-sizing:border-box}
|
|
@@ -11911,11 +12004,9 @@ var css = `
|
|
|
11911
12004
|
.knobs-tree:focus .knobs-tree-row[data-active][aria-selected="true"]::before{background:var(--_ku-select-focus)}
|
|
11912
12005
|
.knobs-tree-row[data-drop="into"]::before{opacity:1;background:color-mix(in srgb,var(--_k-accent) 30%,transparent)}
|
|
11913
12006
|
.knobs-tree-row[data-dragged]{opacity:.38}
|
|
11914
|
-
/* glide:
|
|
11915
|
-
.knobs-tree-
|
|
11916
|
-
|
|
11917
|
-
.knobs-tree-cursor[data-on]{opacity:1}
|
|
11918
|
-
.knobs-tree:focus .knobs-tree-cursor{background:var(--_ku-select-focus)}
|
|
12007
|
+
/* glide: the selection pill on the selected row, in the selection's colour (the row's own stays off). */
|
|
12008
|
+
.knobs-tree>.knobs-pick-pill{background:var(--_ku-select)}
|
|
12009
|
+
.knobs-tree:focus>.knobs-pick-pill{background:var(--_ku-select-focus)}
|
|
11919
12010
|
.knobs-tree[data-glide] .knobs-tree-row[aria-selected="true"]::before{opacity:0!important}
|
|
11920
12011
|
.knobs-tree-row>*{position:relative}
|
|
11921
12012
|
.knobs-tree-caret{flex:none;display:flex;align-items:center;justify-content:center;width:16px;height:100%;color:var(--_k-fg-3);transition:transform var(--_ku-ease-ms) var(--_ku-ease)}
|
|
@@ -11947,22 +12038,20 @@ var css = `
|
|
|
11947
12038
|
box-shadow:0 0 0 1px var(--_k-border-strong),0 6px 18px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)));pointer-events:none;white-space:nowrap;font:var(--_k-weight) var(--_k-font-size)/1.6 var(--_k-font)}
|
|
11948
12039
|
.knobs-tree-empty{padding:10px var(--_k-inset);color:var(--_k-fg-3)}
|
|
11949
12040
|
|
|
11950
|
-
/* Timeline:
|
|
11951
|
-
|
|
12041
|
+
/* Timeline: play beside a track: the ruler's canvas over a lane of markers, ranges as soft bands,
|
|
12042
|
+
and the playhead, a hairline in the accent with a cap. No clock: the time shows under the
|
|
12043
|
+
pointer on the track (the tag), in seconds, while hovering or scrubbing. */
|
|
11952
12044
|
:where(.knobs-timeline,.knobs-timeline *){box-sizing:border-box}
|
|
11953
12045
|
.knobs-ui.knobs-timeline{display:flex;align-items:stretch;gap:10px;width:100%;height:100%;min-height:52px;padding:6px var(--_k-inset) 8px 8px;outline:none;user-select:none;-webkit-user-select:none;
|
|
11954
12046
|
font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
11955
12047
|
:where(.knobs-ui) :is(.knobs-tl-play,.knobs-tl-edit){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
|
|
11956
|
-
.knobs-tl-transport{flex:none;display:flex;align-items:center
|
|
12048
|
+
.knobs-tl-transport{flex:none;display:flex;align-items:center}
|
|
11957
12049
|
.knobs-ui .knobs-tl-play{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);min-width:22px;min-height:22px;border-radius:calc(var(--_k-radius) * 999);
|
|
11958
12050
|
background:var(--_k-fill-selected);color:var(--_k-fg);cursor:pointer;transition:background .15s,transform .15s var(--_ku-ease)}
|
|
11959
12051
|
.knobs-ui .knobs-tl-play:hover{background:color-mix(in srgb,var(--_k-fg) 16%,transparent)}
|
|
11960
12052
|
.knobs-ui .knobs-tl-play:active{transform:scale(.94)}
|
|
11961
12053
|
.knobs-tl-play svg{width:12px;height:12px}
|
|
11962
12054
|
.knobs-timeline[data-playing] .knobs-tl-play{background:var(--_k-accent);color:var(--_k-bg)}
|
|
11963
|
-
.knobs-tl-time{display:flex;flex-direction:column;line-height:1.2;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
|
|
11964
|
-
.knobs-tl-now{font:var(--_k-weight) var(--_k-value-size)/1.2 var(--_k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";color:var(--_k-fg);white-space:nowrap}
|
|
11965
|
-
.knobs-tl-sub{font-size:var(--_k-text-meta);color:var(--_k-fg-3);white-space:nowrap}
|
|
11966
12055
|
.knobs-tl-track{position:relative;flex:1;min-width:0;overflow:hidden;border-radius:var(--_k-radius);background:var(--_k-fill);cursor:col-resize;touch-action:none;
|
|
11967
12056
|
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
11968
12057
|
.knobs-timeline:focus-visible .knobs-tl-track,.knobs-timeline[data-keyboard]:focus .knobs-tl-track{background:color-mix(in srgb,var(--_k-fill-selected) 80%,transparent)}
|
|
@@ -11986,7 +12075,8 @@ var css = `
|
|
|
11986
12075
|
.knobs-tl-pin{position:absolute;top:13px;left:-5px;width:10px;height:10px;pointer-events:auto;cursor:grab}
|
|
11987
12076
|
.knobs-tl-pin::after{content:"";position:absolute;inset:1.5px;border-radius:min(2px,var(--_k-radius));background:var(--knobs-tl-c);rotate:45deg;transition:background .15s,scale .2s var(--_ku-ease)}
|
|
11988
12077
|
.knobs-tl-mlabel{position:absolute;top:26px;left:3px;max-width:140px;padding:0 6px;border-radius:max(0px,calc(var(--_k-radius) - 3px));background:var(--_k-fill-selected);color:var(--_k-fg);
|
|
11989
|
-
font-size:var(--_k-text-meta);line-height:17px;white-space:nowrap;
|
|
12078
|
+
font-size:var(--_k-text-meta);line-height:17px;white-space:nowrap;pointer-events:auto;cursor:grab;transition:background .15s,color .15s}
|
|
12079
|
+
.knobs-tl-mtext{display:block;overflow:hidden;white-space:nowrap}
|
|
11990
12080
|
.knobs-tl-marker[data-selected]{--knobs-tl-c:var(--_k-accent)}
|
|
11991
12081
|
.knobs-tl-marker[data-selected] .knobs-tl-mlabel{background:color-mix(in srgb,var(--_k-accent) 24%,var(--_k-fill-selected))}
|
|
11992
12082
|
.knobs-tl-marker[data-selected] .knobs-tl-pin::after{scale:1.2}
|
|
@@ -12005,9 +12095,42 @@ var css = `
|
|
|
12005
12095
|
.knobs-tl-hover{position:absolute;left:0;top:0;bottom:0;width:1px;margin-left:-.5px;background:var(--_k-border-strong);transform:translateX(-100px);pointer-events:none;opacity:0;transition:opacity .15s}
|
|
12006
12096
|
.knobs-tl-track:hover .knobs-tl-hover{opacity:1}
|
|
12007
12097
|
.knobs-timeline[data-scrubbing] .knobs-tl-hover{opacity:0}
|
|
12098
|
+
.knobs-tl-tag{position:absolute;left:0;bottom:2px;font-size:var(--_k-text-meta);line-height:16px;color:var(--_k-fg);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;pointer-events:none;opacity:0}
|
|
12099
|
+
.knobs-tl-tag[data-on]{opacity:1}
|
|
12100
|
+
/* The lane (variant: "lane"): one slim track of ticks under a compare or a video; markers are
|
|
12101
|
+
faint chapter ticks, the current one in text colour; nothing to edit. */
|
|
12102
|
+
.knobs-ui.knobs-timeline[data-variant="lane"]{height:auto;min-height:0;padding:0;gap:var(--_k-gap)}
|
|
12103
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-track{height:var(--_k-control-h)}
|
|
12104
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-ruler{height:100%}
|
|
12105
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-lane{top:0}
|
|
12106
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-marker{top:0}
|
|
12107
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-marker::before{top:0;bottom:50%;left:-.75px;width:1.5px;background:var(--_k-fg-3)}
|
|
12108
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-marker[data-current]::before{background:var(--_k-fg)}
|
|
12109
|
+
.knobs-timeline[data-variant="lane"] :is(.knobs-tl-pin,.knobs-tl-mlabel,.knobs-tl-rlabel){display:none}
|
|
12110
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-head::before{top:0}
|
|
12111
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-head::after{content:none}
|
|
12112
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-tag{top:2px;bottom:auto}
|
|
12113
|
+
/* The line (variant: "line"): a player's progress under its media. One 2px line, fg-3 with fg
|
|
12114
|
+
filling it, a segment per chapter; it thickens under the pointer and while scrubbing. The
|
|
12115
|
+
chapter and time under the pointer float over it; nothing else shows. */
|
|
12116
|
+
.knobs-ui.knobs-timeline[data-variant="line"]{height:auto;min-height:0;padding:0;gap:0}
|
|
12117
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-transport{display:none}
|
|
12118
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track{height:16px;overflow:visible;border-radius:var(--_k-radius);background:transparent;box-shadow:none;cursor:pointer}
|
|
12119
|
+
.knobs-timeline[data-variant="line"] :is(.knobs-tl-ruler,.knobs-tl-lane,.knobs-tl-hover,.knobs-tl-head,.knobs-tl-rlabel){display:none}
|
|
12120
|
+
.knobs-tl-segs{position:absolute;left:0;right:0;top:50%;height:2px;margin-top:-1px;pointer-events:none;transition:scale calc(var(--_k-hover-out) * 1ms) var(--_ku-ease)}
|
|
12121
|
+
.knobs-tl-seg{position:absolute;left:0;top:0;height:100%;overflow:hidden;border-radius:1px;background:var(--_k-fg-3);will-change:transform}
|
|
12122
|
+
.knobs-tl-seg-fill{position:absolute;inset:0;background:var(--_k-fg);transform-origin:0 0;will-change:transform}
|
|
12123
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-track:hover .knobs-tl-segs,.knobs-timeline[data-variant="line"][data-scrubbing] .knobs-tl-segs{scale:1 2}
|
|
12124
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-range{top:3px;bottom:3px;border-radius:3px}
|
|
12125
|
+
.knobs-timeline[data-variant="line"]:focus-visible .knobs-tl-track,.knobs-timeline[data-variant="line"][data-keyboard]:focus .knobs-tl-track{background:transparent;box-shadow:0 0 0 2px color-mix(in srgb,var(--_k-accent) 60%,transparent)}
|
|
12126
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-tag{top:auto;bottom:calc(100% + 2px);display:flex;gap:6px;padding:0 6px;border-radius:calc(var(--_k-radius) * 999);background:var(--_ku-media-scrim);color:var(--_ku-on-media);
|
|
12127
|
+
font-size:var(--_k-type-small);line-height:var(--_k-leading-small);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
|
|
12128
|
+
.knobs-tl-tag-label{color:var(--_k-fg-2)}
|
|
12129
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-tag-label{color:var(--_ku-on-media-2)}
|
|
12130
|
+
.knobs-tl-tag-label:empty{display:none}
|
|
12008
12131
|
@media(prefers-reduced-motion:reduce){.knobs-timeline :where(*,::before,::after){transition:none!important}}
|
|
12009
12132
|
@media(prefers-reduced-motion:reduce){:is(.knobs-tree,.knobs-split>.knobs-divider,.knobs-pane-head,.knobs-pane-rail) :where(*,::before,::after){transition:none!important}}
|
|
12010
|
-
`, uiCss = () => aliased(css + readoutCss + overlayCss + bentoCss + activityCss + pickerCss + compareCss) + rolling_css_default;
|
|
12133
|
+
`, uiCss = () => aliased(css + readoutCss + overlayCss + bentoCss + activityCss + pickerCss + compareCss + playerCss + selectionPillCss) + rolling_css_default;
|
|
12011
12134
|
function injectUiStyles(doc) {
|
|
12012
12135
|
if (injectTokens(doc), doc.querySelector("style[data-knobs-ui]"))
|
|
12013
12136
|
return;
|
|
@@ -14752,7 +14875,7 @@ function buildPanel(controls, host, options) {
|
|
|
14752
14875
|
if (helpButton?.hidden)
|
|
14753
14876
|
titleEl.title = `${titleEl.textContent ? `${titleEl.textContent}
|
|
14754
14877
|
` : ""}Press ${show("help")} for keyboard shortcuts`;
|
|
14755
|
-
let presetLabel = (id) => options.presetLabels?.[id] ?? (id === "default" ? options.defaultLabel : void 0) ?? controls.presetLabel(id), presetStrip = createPresetStrip(doc, controls, showVariants, run, () => wakeGpu(), presetLabel), tabStrip = createTabStrip(doc, (id, animate) => selectTab(id, animate)), activeTab, searchOptions = typeof options.search === "object" ? options.search : {}, chipTests = /* @__PURE__ */ new Map, search = options.search && !page ? createSearch(doc, {
|
|
14878
|
+
let presetLabel = (id) => options.presetLabels?.[id] ?? (id === "default" ? options.defaultLabel : void 0) ?? controls.presetLabel(id), presetStrip = createPresetStrip(doc, controls, showVariants, run, () => wakeGpu(), presetLabel, (entries) => presetsTouchTab(entries)), tabStrip = createTabStrip(doc, (id, animate) => selectTab(id, animate)), activeTab, searchOptions = typeof options.search === "object" ? options.search : {}, chipTests = /* @__PURE__ */ new Map, search = options.search && !page ? createSearch(doc, {
|
|
14756
14879
|
placeholder: searchOptions.placeholder ?? "Search",
|
|
14757
14880
|
chips: (searchOptions.chips ?? ["modified"]).map((chip) => {
|
|
14758
14881
|
if (chip === "modified")
|
|
@@ -14774,7 +14897,10 @@ function buildPanel(controls, host, options) {
|
|
|
14774
14897
|
let allActions = [
|
|
14775
14898
|
...controls.actions ?? [],
|
|
14776
14899
|
...options.actions ?? []
|
|
14777
|
-
], body = el("div"), tabMotion = tabTransition(body, root, () => wakeGpu()),
|
|
14900
|
+
], body = el("div"), tabMotion = tabTransition(body, root, () => wakeGpu()), pinnedBody = el("div");
|
|
14901
|
+
if (pinnedBody.className = "knobs-pinned", !page)
|
|
14902
|
+
body.append(presetStrip.element);
|
|
14903
|
+
let blocks = [], cards = [], groupResetButtons = /* @__PURE__ */ new Map, groupDice = /* @__PURE__ */ new Map, gpuGroups = [], gpuRows = [], layout, layoutTick = 0, foldSource = null, userFolding = !1, noteFold = (source) => {
|
|
14778
14904
|
if (foldSource !== "user")
|
|
14779
14905
|
foldSource = source;
|
|
14780
14906
|
}, byUser = (act) => {
|
|
@@ -15091,8 +15217,11 @@ function buildPanel(controls, host, options) {
|
|
|
15091
15217
|
section: field.section
|
|
15092
15218
|
});
|
|
15093
15219
|
}
|
|
15094
|
-
|
|
15095
|
-
|
|
15220
|
+
let planned = gatherSubsections(specs);
|
|
15221
|
+
if (page || !planned.some(pinnedRow))
|
|
15222
|
+
return planned;
|
|
15223
|
+
return [...planned.filter(pinnedRow), ...planned.filter((spec) => !pinnedRow(spec))];
|
|
15224
|
+
}, pinnedRow = (r) => !page && controls.isPinned(r.keys[0] ?? r.id), gatherSubsections = (specs) => {
|
|
15096
15225
|
let out = [];
|
|
15097
15226
|
for (let i = 0;i < specs.length; ) {
|
|
15098
15227
|
let end = i;
|
|
@@ -15616,13 +15745,13 @@ function buildPanel(controls, host, options) {
|
|
|
15616
15745
|
} else {
|
|
15617
15746
|
let runs = [];
|
|
15618
15747
|
for (let r of next) {
|
|
15619
|
-
let last = runs.at(-1);
|
|
15620
|
-
if (last && last.group === r.group)
|
|
15748
|
+
let last = runs.at(-1), pinned = pinnedRow(r);
|
|
15749
|
+
if (last && last.group === r.group && last.pinned === pinned)
|
|
15621
15750
|
last.rows.push(r);
|
|
15622
15751
|
else
|
|
15623
|
-
runs.push({ group: r.group, rows: [r] });
|
|
15752
|
+
runs.push({ group: r.group, pinned, rows: [r] });
|
|
15624
15753
|
}
|
|
15625
|
-
let free = blocks.filter((b) => !b.leaving), chosen = [], usedSubheads = /* @__PURE__ */ new Set;
|
|
15754
|
+
let free = blocks.filter((b) => !b.leaving), chosen = [], pinnedBlocks = /* @__PURE__ */ new Set, usedSubheads = /* @__PURE__ */ new Set;
|
|
15626
15755
|
for (let run of runs) {
|
|
15627
15756
|
let at = free.findIndex((b) => b.group === run.group), block = at >= 0 ? free.splice(at, 1)[0] : newBlock(run.group);
|
|
15628
15757
|
if (at < 0) {
|
|
@@ -15637,7 +15766,8 @@ function buildPanel(controls, host, options) {
|
|
|
15637
15766
|
motion.push({ node: block.card, show: !0 });
|
|
15638
15767
|
}
|
|
15639
15768
|
}
|
|
15640
|
-
chosen.push(block)
|
|
15769
|
+
if (chosen.push(block), run.pinned)
|
|
15770
|
+
pinnedBlocks.add(block);
|
|
15641
15771
|
let nodes = [], under;
|
|
15642
15772
|
for (let r of run.rows) {
|
|
15643
15773
|
let name = r.field.subsection;
|
|
@@ -15662,7 +15792,8 @@ function buildPanel(controls, host, options) {
|
|
|
15662
15792
|
gpuRows.splice(gi, 1);
|
|
15663
15793
|
subheads.delete(id);
|
|
15664
15794
|
}
|
|
15665
|
-
|
|
15795
|
+
let nodesOf = (list) => list.flatMap((b) => b.head ? [b.head, b.card] : [b.card]);
|
|
15796
|
+
arrange(pinnedBody, nodesOf(chosen.filter((b) => pinnedBlocks.has(b)))), arrange(body, [presetStrip.element, ...nodesOf(chosen.filter((b) => !pinnedBlocks.has(b)))]);
|
|
15666
15797
|
for (let block of free) {
|
|
15667
15798
|
block.leaving = !0;
|
|
15668
15799
|
let fold = () => {
|
|
@@ -15768,15 +15899,24 @@ function buildPanel(controls, host, options) {
|
|
|
15768
15899
|
if (f.group === group && f.tab !== void 0)
|
|
15769
15900
|
return f.tab;
|
|
15770
15901
|
return;
|
|
15771
|
-
}, tabOf = (r) => r.field.tab ?? (r.group !== void 0 ? groupTab(r.group) : void 0), tabList = () => {
|
|
15902
|
+
}, tabOf = (r) => pinnedRow(r) ? void 0 : r.field.tab ?? (r.group !== void 0 ? groupTab(r.group) : void 0), tabList = () => {
|
|
15772
15903
|
if (page)
|
|
15773
15904
|
return [];
|
|
15774
15905
|
let list = (options.tabs ?? []).map((t) => typeof t === "string" ? { id: t, label: readableTitle(t) } : { id: t.id, label: t.label ?? readableTitle(t.id) }), seen = new Set(list.map((t) => t.id));
|
|
15775
|
-
for (let f of Object.
|
|
15776
|
-
if (f.tab !== void 0 && !seen.has(f.tab))
|
|
15906
|
+
for (let [key, f] of Object.entries(controls.schema))
|
|
15907
|
+
if (f.tab !== void 0 && !seen.has(f.tab) && !controls.isPinned(key))
|
|
15777
15908
|
seen.add(f.tab), list.push({ id: f.tab, label: readableTitle(f.tab) });
|
|
15778
15909
|
return list;
|
|
15779
15910
|
};
|
|
15911
|
+
function presetsTouchTab(entries) {
|
|
15912
|
+
if (page || activeTab === void 0)
|
|
15913
|
+
return !0;
|
|
15914
|
+
let keys = rows.flatMap((r) => {
|
|
15915
|
+
let tab = tabOf(r);
|
|
15916
|
+
return !pinnedRow(r) && (tab === void 0 || tab === activeTab) ? r.keys : [];
|
|
15917
|
+
});
|
|
15918
|
+
return presetsTouch(entries, keys, controls.locked);
|
|
15919
|
+
}
|
|
15780
15920
|
function syncTabs() {
|
|
15781
15921
|
let list = tabList(), has = (id) => id !== void 0 && list.some((t) => t.id === id);
|
|
15782
15922
|
if (!has(activeTab))
|
|
@@ -15830,7 +15970,7 @@ function buildPanel(controls, host, options) {
|
|
|
15830
15970
|
want.set(b.head, any);
|
|
15831
15971
|
want.set(b.card, any && !(b.group !== void 0 && folds.get(b.group) && !finding));
|
|
15832
15972
|
}
|
|
15833
|
-
return want;
|
|
15973
|
+
return want.set(presetStrip.element, presetStrip.shows()), want;
|
|
15834
15974
|
}
|
|
15835
15975
|
let shift = (node, show, delay) => {
|
|
15836
15976
|
shifting.add(node), node.dataset.presence = show ? "in" : "out", reveal(node, show, () => {
|
|
@@ -15847,6 +15987,9 @@ function buildPanel(controls, host, options) {
|
|
|
15847
15987
|
}
|
|
15848
15988
|
if (tabMotion.running)
|
|
15849
15989
|
tabMotion.finish();
|
|
15990
|
+
let strip = presetStrip.element;
|
|
15991
|
+
if (strip.hidden === want.get(strip))
|
|
15992
|
+
strip.hidden = !want.get(strip);
|
|
15850
15993
|
let showing = (n) => !n.hidden && n.dataset.leaving !== "true", set = (node, show, animate) => {
|
|
15851
15994
|
if (showing(node) === show)
|
|
15852
15995
|
return;
|
|
@@ -16051,9 +16194,9 @@ function buildPanel(controls, host, options) {
|
|
|
16051
16194
|
} else {
|
|
16052
16195
|
if (root.append(header), showFooter)
|
|
16053
16196
|
root.append(popover);
|
|
16054
|
-
if (root.append(tabStrip.element), search)
|
|
16197
|
+
if (root.append(pinnedBody, tabStrip.element), search)
|
|
16055
16198
|
root.append(search.element);
|
|
16056
|
-
if (root.append(
|
|
16199
|
+
if (root.append(body), panelActions.length > 0)
|
|
16057
16200
|
root.append(customActions);
|
|
16058
16201
|
root.append(text, apply, status, live);
|
|
16059
16202
|
}
|
|
@@ -16285,35 +16428,44 @@ function buildPanel(controls, host, options) {
|
|
|
16285
16428
|
nodes.push(...r.editor?.stops() ?? [r.input]);
|
|
16286
16429
|
return nodes.push(...body.querySelectorAll("[data-knobs-stop],.knobs-tile>[data-foldable],.knobs-section-head[data-foldable]")), nodes.filter(visible).sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
16287
16430
|
}, actionBarButtons = () => [...customActions.querySelectorAll("button")].filter((b) => visible(b) && !b.disabled), lastActionButton, stops = () => {
|
|
16288
|
-
let list = [];
|
|
16431
|
+
let list = [], strips = [];
|
|
16289
16432
|
if (visible(tabStrip.element))
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
focus: (o) => tabStrip.focus(o)
|
|
16433
|
+
strips.push({
|
|
16434
|
+
at: tabStrip.element,
|
|
16435
|
+
stops: [{ contains: (n) => tabStrip.element.contains(n), focus: (o) => tabStrip.focus(o) }]
|
|
16293
16436
|
});
|
|
16294
16437
|
if (visible(presetStrip.element))
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
|
|
16438
|
+
strips.push({
|
|
16439
|
+
at: presetStrip.element,
|
|
16440
|
+
stops: [
|
|
16441
|
+
{
|
|
16442
|
+
contains: (n) => presetStrip.element.contains(n),
|
|
16443
|
+
focus: (o) => presetStrip.element.focus(o)
|
|
16444
|
+
}
|
|
16445
|
+
]
|
|
16298
16446
|
});
|
|
16299
16447
|
if (page) {
|
|
16448
|
+
for (let strip of strips)
|
|
16449
|
+
list.push(...strip.stops);
|
|
16300
16450
|
for (let stop of pageStops())
|
|
16301
16451
|
list.push({ contains: (n) => stop.contains(n), focus: (o) => stop.focus(o) });
|
|
16302
16452
|
return list;
|
|
16303
16453
|
}
|
|
16304
|
-
let
|
|
16454
|
+
let stopOf = (stop) => ({
|
|
16455
|
+
contains: (n) => stop.contains(n),
|
|
16456
|
+
focus: (o) => stop.focus(o)
|
|
16457
|
+
}), shown = (stops) => stops.filter((s) => !s.closest('[hidden],[data-presence="out"]')).map(stopOf), runs = rows.map((r) => ({
|
|
16305
16458
|
at: r.row,
|
|
16306
|
-
stops: r.editor?.stops() ?? [r.input]
|
|
16459
|
+
stops: shown(r.editor?.stops() ?? [r.input])
|
|
16307
16460
|
}));
|
|
16308
16461
|
for (let b of blocks)
|
|
16309
16462
|
if (b.head?.hasAttribute("data-foldable") && !b.leaving)
|
|
16310
|
-
runs.push({ at: b.head, stops: [b.head] });
|
|
16463
|
+
runs.push({ at: b.head, stops: shown([b.head]) });
|
|
16311
16464
|
for (let sh of subheads.values())
|
|
16312
|
-
runs.push({ at: sh.el, stops: [sh.el] });
|
|
16313
|
-
runs.sort((a, b) => a.at.compareDocumentPosition(b.at) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
16465
|
+
runs.push({ at: sh.el, stops: shown([sh.el]) });
|
|
16466
|
+
runs.push(...strips), runs.sort((a, b) => a.at.compareDocumentPosition(b.at) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
16314
16467
|
for (let run of runs)
|
|
16315
|
-
|
|
16316
|
-
list.push({ contains: (n) => stop.contains(n), focus: (o) => stop.focus(o) });
|
|
16468
|
+
list.push(...run.stops);
|
|
16317
16469
|
let bar = actionBarButtons();
|
|
16318
16470
|
if (bar.length)
|
|
16319
16471
|
list.push({
|
|
@@ -17419,6 +17571,7 @@ function buildPanel(controls, host, options) {
|
|
|
17419
17571
|
id: controls.id,
|
|
17420
17572
|
root,
|
|
17421
17573
|
body,
|
|
17574
|
+
pinned: pinnedBody,
|
|
17422
17575
|
inline,
|
|
17423
17576
|
header,
|
|
17424
17577
|
titleEl,
|