@umriss-ui/schedule 0.42.0 → 0.43.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/CHANGELOG.md CHANGED
@@ -18,6 +18,30 @@ moves from here under the rule above.
18
18
 
19
19
  ---
20
20
 
21
+ ## 0.43.0 – A schedule that fills its frame, and takes a finger (Oct. 2026)
22
+
23
+ ### Added
24
+
25
+ - **`loading`**, as the chart has it: a plan stays, dims after `--u-delay-stale` and starts no drag, tooltip, context menu or key intent until the answer is in; a drag begun before it finishes. With no lanes, placeholder lines stand in the lane column. The plot is `aria-busy`, also in a server's markup.
26
+ - **Touch editing:** a long press on a bar grabs it, and the finger then moves it in time and across lanes as a mouse does, with `canMoveTo`, blocked time and auto-pan; stretching and lead-in/out stay with the mouse, pen and keyboard. A second finger cancels the grab, and the page does not scroll under a grabbed bar (ADR-0070).
27
+ - **`scrollToLane(lane)`, `scrollToSubtask(id)` and `focusSubtask(id)` on `useSchedule`'s return** show a lane or a subtask picked from a list of your own. `scrollToSubtask` brings the subtask's lane and time into view - the span moves to it and keeps its width - and leaves the focus; `focusSubtask` also makes it the Active subtask and focuses the plot. All three return `false` and change nothing for an unknown lane or subtask, a lane inside a folded group (none is unfolded) and a schedule that is not mounted.
28
+ - **`positionAt`, `clientPointOf` and `visibleDomain` on `useSchedule`'s return**, the functions the handle ref carried; the first two return `null` before mount.
29
+
30
+ ### Changed
31
+
32
+ - **Without `height` a schedule fills its frame and never goes below 400 px** (ADR-0050, amended). Alone in a block it is 400 px as before, whatever its lanes; in a frame taller than that it now takes that height.
33
+ - Migration: a schedule that relied on the 400 px default in a taller frame sets `height={400}` or `style={{ height: 400 }}`.
34
+ - **The schedule's `ref` is its root `<div>`** (ADR-0068): `className`, `style`, `id` and `data-*` reach it, `aria-label` and `aria-labelledby` name it, and a caller's `aria-describedby` follows the plot's own summary.
35
+ - Migration: nothing to change for an element ref.
36
+ - **`ScheduleHandle` is deprecated; 0.44.0 removes it.** A handle ref keeps working for this minor and warns once in development on its first call.
37
+ - Migration: replace `ref.current.positionAt(x, y)` with `positionAt(x, y)` from `const { positionAt } = useSchedule()`, and the same for `clientPointOf` and `visibleDomain`.
38
+ - **`ariaLabel` on `Schedule` is renamed `aria-label`.** `ariaLabel` stays as a deprecated alias and warns once in development; 0.44.0 removes it.
39
+ - Migration: write `aria-label`.
40
+ - **A vertical swipe over the plot scrolls the page while every lane fits.** While the lanes overflow, the plot keeps the swipe and scrolls its lanes; the lane names scroll the page.
41
+ - Migration: nothing to change; on a touch device a short plan no longer traps the page's scroll.
42
+ - **The peer ranges on core and charts move to `^0.43.0`.**
43
+ - Migration: install the 0.43 versions of `@umriss-ui/core` and `@umriss-ui/charts` beside it.
44
+
21
45
  ## 0.42.0 – A schedule under test, and quiet on a server (Oct. 2026)
22
46
 
23
47
  ### Added
package/README.md CHANGED
@@ -50,7 +50,7 @@ const dependencies: Dependency[] = [{ id: "move", from: "cut", to: "mill", lag:
50
50
  export function Plan() {
51
51
  const { Schedule, Lane, Subtasks, Dependencies } = useSchedule({ initialView: { domain: [at(5), at(12)] } });
52
52
  return (
53
- <Schedule ariaLabel="Plan of Tuesday">
53
+ <Schedule aria-label="Plan of Tuesday">
54
54
  <Lane id="saw" label="Saw" />
55
55
  <Lane id="mill" label="Mill" />
56
56
  <Dependencies data={dependencies} />
@@ -136,10 +136,20 @@ A tooltip on a hovered subtask or dependency names the order, the times, lead-in
136
136
  and lead-out and the findings; `tooltip` replaces its content or switches it
137
137
  off. `now` draws the present across the lanes. The wheel over the schedule,
138
138
  lane headers included, scrolls the lanes and releases the page at their end,
139
- Ctrl or ⌘ and a pinch zoom, Shift pans; on a touch screen one finger pans and a
140
- tap selects. The lane headers take at most 40 % of the width, so that on a
141
- phone the plot keeps the larger part; a ref handle turns a client point into a
142
- time and a lane and back.
139
+ Ctrl or ⌘ and a pinch zoom, Shift pans; on a touch screen one finger pans, a
140
+ tap selects and a long press on a bar grabs it (with `"move"` or `"lane"` in `intents`), and a vertical swipe scrolls the page while all lanes fit (when they
141
+ overflow, the lane names scroll the page). The lane headers take at most 40 % of the width, so that on a
142
+ phone the plot keeps the larger part; `positionAt` and `clientPointOf`, on what
143
+ `useSchedule` hands back, turn a client point into a time and a lane and back.
144
+
145
+ ## Its size
146
+
147
+ The width is the host's. Without `height`, a schedule fills its frame - a stretched grid cell, a card the
148
+ grid stretches, a container of definite height - and never goes below 400 px, which is also its height in
149
+ a frame without one: alone in a block it is 400 px however many lanes it holds, and the lanes beyond the
150
+ plot scroll inside it (ADR-0050). A number stays a fixed height. A different floor goes through `style`'s
151
+ `minHeight`, and `style` wins over the schedule's own sizing. A wrapper of your own between the frame and
152
+ the schedule passes the height on with `height: 100%`.
143
153
 
144
154
  ## The view
145
155
 
@@ -149,7 +159,11 @@ reports what the planner does, always the whole view; two schedules keep in
149
159
  step by sending each other what they report through `setView`, which is not
150
160
  reported in turn. Without a span the schedule shows the extent of its subtasks.
151
161
  `view`, `setView`, `setDomain`, `toggleGroup`, `foldAll` and `unfoldAll` stand on what the
152
- hook hands back.
162
+ hook hands back. `setDomain(span)` zooms to a span of two instants; `setDomain(null)` fits the work.
163
+
164
+ The schedule is a composite: its `ref`, `className`, `style`, `id` and `data-*` reach the root `<div>`;
165
+ `aria-label` (required) and `aria-labelledby` name the figure and the plot, and your `aria-describedby`
166
+ is joined to the plot's summary.
153
167
 
154
168
  ## Blocked time
155
169
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { CalendarInput } from '@umriss-ui/charts';
2
- import { CSSProperties } from 'react';
2
+ import { HTMLAttributes } from 'react';
3
3
  import { ReactNode } from 'react';
4
4
  import { Ref } from 'react';
5
+ import { RefObject } from 'react';
5
6
 
6
7
  /** The subtask as the intent asks for it. An intent for another subtask leaves
7
8
  it as it is. */
@@ -346,7 +347,8 @@ export declare interface ResolvedAppearance {
346
347
  export declare function ripple(subtasks: readonly Subtask[], dependencies: readonly Dependency[], intent: Intent): MoveIntent[];
347
348
 
348
349
  /** What a schedule offers a caller imperatively: the arithmetic between a
349
- point on the screen and a time on a lane. Everything else is props. */
350
+ point on the screen and a time on a lane. Everything else is props.
351
+ @deprecated since 0.43 - use the functions on `useSchedule`'s return. */
350
352
  export declare interface ScheduleHandle {
351
353
  /** The time and the lane at a client point, or null outside the plot. */
352
354
  positionAt: (clientX: number, clientY: number) => {
@@ -413,43 +415,17 @@ export declare interface ScheduleOptions {
413
415
  onViewChange?: (view: ScheduleView) => void;
414
416
  }
415
417
 
416
- /** What `useSchedule` hands back: the schedule and what is declared inside
417
- it, its view and the setters that change it. */
418
- export declare interface ScheduleParts {
419
- /** The schedule. One per `useSchedule`: a second schedule is a second call. */
420
- Schedule: (props: ScheduleProps) => ReactNode;
421
- Lane: typeof Lane;
422
- LaneGroup: typeof LaneGroup;
423
- Subtasks: typeof Subtasks;
424
- Dependencies: typeof Dependencies;
425
- BlockedTimes: typeof BlockedTimes;
426
- Milestones: typeof Milestones;
427
- /** How the planner is looking at the plan: the span and the folded groups. */
428
- view: ScheduleView;
429
- /** Goes to a whole view; what it leaves out is shown whole again. Not
430
- reported through `onViewChange`: two schedules kept in step by
431
- `onViewChange: (v) => other.setView(v)` in both directions do not answer
432
- each other. A view with the content already shown changes nothing. */
433
- setView: (view: ScheduleView) => void;
434
- /** Puts a span of two wall-clock instants in view; `null` shows the
435
- subtasks' extent. */
436
- setDomain: (span: readonly [number, number] | null) => void;
437
- /** Folds or unfolds one **Lane group**. */
438
- toggleGroup: (id: string) => void;
439
- /** Folds every group. */
440
- foldAll: () => void;
441
- /** Unfolds every group. */
442
- unfoldAll: () => void;
443
- }
444
-
445
- /** The props of `Schedule`. */
446
- export declare interface ScheduleProps {
447
- /** Receives the `ScheduleHandle` - not an element. */
448
- ref?: Ref<ScheduleHandle>;
449
- /** What the schedule shows, for a screen reader: "Plan of week 38". */
450
- ariaLabel: string;
451
- /** Height in CSS pixels, both bands included. The width is the host's.
452
- @default 400 */
418
+ declare interface ScheduleOwnProps extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "aria-label"> {
419
+ /** Receives the root element. A ref to the deprecated `ScheduleHandle` still
420
+ works for one more minor release: the element carries its three
421
+ functions. */
422
+ ref?: Ref<HTMLDivElement> | RefObject<ScheduleHandle | null> | undefined;
423
+ /** Height in CSS pixels, both bands included, fixed. Left out, the schedule
424
+ fills its frame - a stretched grid cell, a card the grid stretches, a
425
+ container of definite height - and never goes below 400 px, which is also
426
+ its height in a frame without one. A different floor goes through
427
+ `style`'s `minHeight` (ADR-0050). The width is the host's.
428
+ @default fills the frame, at least 400 px */
453
429
  height?: number;
454
430
  /** Height of one lane in pixels at the default font size of 16 px; the
455
431
  schedule multiplies it by the root font size over 16 px when that ratio
@@ -545,15 +521,90 @@ export declare interface ScheduleProps {
545
521
  the minute, an instant fixes it there.
546
522
  @default false */
547
523
  now?: boolean | number;
548
- /** Goes to the root element. */
549
- className?: string;
550
- /** Goes to the root element. */
551
- style?: CSSProperties;
524
+ /** The plan is on its way, as the chart's `loading` says (ADR-0042). A plan
525
+ already drawn stays: it dims after a moment and takes no pointer - no new
526
+ drag, no tooltip, no intent by key - until the answer is in; a drag
527
+ begun before finishes and reports. The keys still walk it. With no lanes,
528
+ placeholder lines stand in the lane column. The plot is `aria-busy`
529
+ meanwhile.
530
+ @default false */
531
+ loading?: boolean;
552
532
  /** `Lane`, `Dependencies` and `Subtasks`, in the order they are to stand and
553
533
  be drawn. */
554
534
  children?: ReactNode;
555
535
  }
556
536
 
537
+ /** What `useSchedule` hands back: the schedule and what is declared inside
538
+ it, its view and the setters that change it. */
539
+ export declare interface ScheduleParts {
540
+ /** The schedule. One per `useSchedule`: a second schedule is a second call. */
541
+ Schedule: (props: ScheduleProps) => ReactNode;
542
+ Lane: typeof Lane;
543
+ LaneGroup: typeof LaneGroup;
544
+ Subtasks: typeof Subtasks;
545
+ Dependencies: typeof Dependencies;
546
+ BlockedTimes: typeof BlockedTimes;
547
+ Milestones: typeof Milestones;
548
+ /** How the planner is looking at the plan: the span and the folded groups. */
549
+ view: ScheduleView;
550
+ /** Goes to a whole view; what it leaves out is shown whole again. Not
551
+ reported through `onViewChange`: two schedules kept in step by
552
+ `onViewChange: (v) => other.setView(v)` in both directions do not answer
553
+ each other. A view with the content already shown changes nothing. */
554
+ setView: (view: ScheduleView) => void;
555
+ /** Puts a span of two wall-clock instants in view; `null` shows the
556
+ subtasks' extent. */
557
+ setDomain: (span: readonly [number, number] | null) => void;
558
+ /** Folds or unfolds one **Lane group**. */
559
+ toggleGroup: (id: string) => void;
560
+ /** The time and the lane at a client point, or null outside the plot - and
561
+ null while no schedule is mounted. */
562
+ positionAt: (clientX: number, clientY: number) => {
563
+ time: number;
564
+ lane: string | null;
565
+ } | null;
566
+ /** The client point of a time - on the middle of a lane where one is named -
567
+ or null while the schedule is not on screen. */
568
+ clientPointOf: (time: number, lane?: string) => {
569
+ x: number;
570
+ y: number;
571
+ } | null;
572
+ /** The visible span, as two wall-clock instants. */
573
+ visibleDomain: () => readonly [number, number];
574
+ /** Scrolls the lanes until the lane's row is in view, and returns `true`; `false`
575
+ and nothing changed for an unknown lane, one inside a folded **Lane group**
576
+ (none is unfolded), or while no schedule is mounted. */
577
+ scrollToLane: (lane: string) => boolean;
578
+ /** Brings the subtask's lane and time into view, the span moving to it and keeping its
579
+ width as `setDomain` would, and leaves the focus where it is; `false` and nothing
580
+ changed in the cases of `scrollToLane`. */
581
+ scrollToSubtask: (id: string) => boolean;
582
+ /** Does what `scrollToSubtask` does, then makes the subtask the **Active subtask** and
583
+ moves the focus to the plot, where the live region reads it out as the arrow keys do;
584
+ `false` and nothing changed in the cases of `scrollToLane`. */
585
+ focusSubtask: (id: string) => boolean;
586
+ /** Folds every group. */
587
+ foldAll: () => void;
588
+ /** Unfolds every group. */
589
+ unfoldAll: () => void;
590
+ }
591
+
592
+ /** The props of `Schedule`: the attributes of a `<div>` and what the schedule
593
+ reads itself. `ref`, `className`, `style` and the rest reach the root; the
594
+ name (`aria-label`, `aria-labelledby`) reaches the figure root and the plot,
595
+ and a `aria-describedby` of yours is joined to the plot's summary. */
596
+ export declare type ScheduleProps = ScheduleOwnProps & ({
597
+ /** What the schedule shows, for a screen reader: "Plan of week 38". */
598
+ "aria-label": string;
599
+ /** @deprecated since 0.43 - use `aria-label`. */
600
+ ariaLabel?: string;
601
+ } | {
602
+ "aria-label"?: undefined;
603
+ /** What the schedule shows, for a screen reader.
604
+ @deprecated since 0.43 - use `aria-label`. */
605
+ ariaLabel: string;
606
+ });
607
+
557
608
  /** What a tooltip is about: the hovered subtask or dependency, with what the
558
609
  schedule knows about it. */
559
610
  export declare type ScheduleTooltipTarget = {
@@ -698,7 +749,8 @@ export declare interface Task {
698
749
  /** Declares a schedule: hands back `Schedule` and the parts declared inside it
699
750
  - `Lane`, `LaneGroup`, `Subtasks`, `Dependencies`, `BlockedTimes`, `Milestones` -, its
700
751
  `view` and the setters `setView`, `setDomain`, `toggleGroup`, `foldAll` and
701
- `unfoldAll`. A ref on `Schedule` still gives the `ScheduleHandle`. */
752
+ `unfoldAll`, `positionAt`, `clientPointOf` and `visibleDomain`, and `scrollToLane`, `scrollToSubtask` and
753
+ `focusSubtask`. */
702
754
  export declare function useSchedule(options?: ScheduleOptions): ScheduleParts;
703
755
 
704
756
  /** Every dependency whose successor is to be reached before the predecessor's
package/dist/schedule.css CHANGED
@@ -1 +1 @@
1
- @layer umriss.tokens,umriss.base,umriss.components;@layer umriss.base{._text_18806_22{font-family:var(--u-font-sans);font-size:var(--u-text-md);line-height:var(--u-leading-normal);color:var(--u-color-text);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}@media(pointer:fine){._dense_18806_38{--u-control-height-sm: var(--u-control-height-xs)}}._ink_18806_49{--u-color-text: var(--u-color-bg);--u-color-text-secondary: color-mix(in srgb, var(--u-color-bg) 75%, transparent);--u-color-text-muted: color-mix(in srgb, var(--u-color-bg) 60%, transparent)}._extent_18806_75{--_chars: 20;--_extra: 0;--_tracking: 0px;--_chrome: 0px;min-inline-size:0;max-inline-size:100%;contain:inline-size;contain-intrinsic-inline-size:calc((var(--_chars) + var(--_extra)) * (1ch + var(--_tracking)) + var(--_chrome))}._field_18806_90{caret-color:var(--u-color-accent)}._scroll_18806_96{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--u-color-text) 25%,transparent) transparent}._scroll_18806_96::-webkit-scrollbar{width:10px;height:10px}._scroll_18806_96::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--u-color-text) 22%,transparent);border-radius:var(--u-radius-full);border:3px solid transparent;background-clip:content-box}._scroll_18806_96::-webkit-scrollbar-track{background:transparent}}@layer umriss.components{._ring_18806_125:focus-visible{outline:2px solid transparent;box-shadow:var(--u-focus-ring)}@media(pointer:coarse){._field_18806_90._field_18806_90,._fieldRoot_18806_145._fieldRoot_18806_145{font-size:16px}}._field_18806_90:-webkit-autofill,._field_18806_90:-webkit-autofill:hover,._field_18806_90:-webkit-autofill:focus{-webkit-box-shadow:inset 0 0 0 1000px var(--u-color-surface),0 0 0 1px var(--u-edge-color-strong);-webkit-text-fill-color:var(--u-color-text);caret-color:var(--u-color-accent)}}@layer umriss.components{._root_1g7hg_4,._root_1g7hg_4:before,._root_1g7hg_4:after{box-sizing:border-box}._corner_1g7hg_19,._corner_1g7hg_19:before,._corner_1g7hg_19:after{box-sizing:border-box}._dayBand_1g7hg_23,._dayBand_1g7hg_23:before,._dayBand_1g7hg_23:after{box-sizing:border-box}._tickBand_1g7hg_24,._tickBand_1g7hg_24:before,._tickBand_1g7hg_24:after{box-sizing:border-box}._day_1g7hg_23,._day_1g7hg_23:before,._day_1g7hg_23:after{box-sizing:border-box}._dayLabel_1g7hg_50,._dayLabel_1g7hg_50:before,._dayLabel_1g7hg_50:after{box-sizing:border-box}._tick_1g7hg_24,._tick_1g7hg_24:before,._tick_1g7hg_24:after{box-sizing:border-box}._tickLabel_1g7hg_71,._tickLabel_1g7hg_71:before,._tickLabel_1g7hg_71:after{box-sizing:border-box}._headers_1g7hg_79,._headers_1g7hg_79:before,._headers_1g7hg_79:after{box-sizing:border-box}._header_1g7hg_79,._header_1g7hg_79:before,._header_1g7hg_79:after{box-sizing:border-box}._headerLabel_1g7hg_97,._headerLabel_1g7hg_97:before,._headerLabel_1g7hg_97:after{box-sizing:border-box}._headerCount_1g7hg_133,._headerCount_1g7hg_133:before,._headerCount_1g7hg_133:after{box-sizing:border-box}._chevron_1g7hg_142,._chevron_1g7hg_142:before,._chevron_1g7hg_142:after{box-sizing:border-box}._plot_1g7hg_197,._plot_1g7hg_197:before,._plot_1g7hg_197:after{box-sizing:border-box}._focusRing_1g7hg_204,._focusRing_1g7hg_204:before,._focusRing_1g7hg_204:after{box-sizing:border-box}._layer_1g7hg_222,._layer_1g7hg_222:before,._layer_1g7hg_222:after{box-sizing:border-box}._grip_1g7hg_231,._grip_1g7hg_231:before,._grip_1g7hg_231:after{box-sizing:border-box}._ghostLabel_1g7hg_241,._ghostLabel_1g7hg_241:before,._ghostLabel_1g7hg_241:after{box-sizing:border-box}._finding_1g7hg_254,._finding_1g7hg_254:before,._finding_1g7hg_254:after{box-sizing:border-box}._refusal_1g7hg_262,._refusal_1g7hg_262:before,._refusal_1g7hg_262:after{box-sizing:border-box}._tooltip_1g7hg_266,._tooltip_1g7hg_266:before,._tooltip_1g7hg_266:after{box-sizing:border-box}._tooltipHead_1g7hg_285,._tooltipHead_1g7hg_285:before,._tooltipHead_1g7hg_285:after{box-sizing:border-box}._tooltipTimes_1g7hg_290,._tooltipTimes_1g7hg_290:before,._tooltipTimes_1g7hg_290:after{box-sizing:border-box}._now_1g7hg_299,._now_1g7hg_299:before,._now_1g7hg_299:after{box-sizing:border-box}._barLabel_1g7hg_313,._barLabel_1g7hg_313:before,._barLabel_1g7hg_313:after{box-sizing:border-box}._barLabelText_1g7hg_326,._barLabelText_1g7hg_326:before,._barLabelText_1g7hg_326:after{box-sizing:border-box}._root_1g7hg_4{display:grid;grid-template-rows:28px minmax(0,1fr) 28px;width:100%;font-size:var(--u-text-sm);background:var(--u-color-surface);outline:1px solid transparent;box-shadow:var(--u-edge);border-radius:var(--u-radius-md);corner-shape:squircle;overflow:hidden;font-variant-numeric:tabular-nums;user-select:none}._corner_1g7hg_19{background:var(--u-color-surface)}._dayBand_1g7hg_23,._tickBand_1g7hg_24{position:relative;overflow:hidden;color:var(--u-color-text-muted);font-size:var(--u-text-xs)}._dayBand_1g7hg_23{border-bottom:1px solid var(--u-hairline-strong)}._tickBand_1g7hg_24{border-top:1px solid var(--u-hairline-strong)}._day_1g7hg_23{position:absolute;top:0;bottom:0;border-left:1px solid var(--u-hairline-strong);overflow:hidden}._dayLabel_1g7hg_50{position:absolute;z-index:1;left:var(--u-space-1);padding:0 var(--u-space-1);background:var(--u-color-surface);top:50%;transform:translateY(-50%);white-space:nowrap;color:var(--u-color-text);font-weight:var(--u-weight-medium)}._tick_1g7hg_24{position:absolute;top:0;bottom:0;width:1px;background:var(--u-hairline)}._tickLabel_1g7hg_71{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);white-space:nowrap}._headers_1g7hg_79{position:relative;overflow:hidden;border-right:1px solid var(--u-hairline-strong)}._header_1g7hg_79{display:flex;align-items:center;gap:var(--u-space-2);padding-right:var(--u-space-3);border-bottom:1px solid var(--u-hairline);overflow:hidden;white-space:nowrap}._headerLabel_1g7hg_97{min-width:0;overflow:hidden;text-overflow:ellipsis}._header_1g7hg_79[data-row=lane],._header_1g7hg_79[data-row=miniature]{container:lane-header / size}@container lane-header (height >= 2.5rem){._headerLabel_1g7hg_97:not(:has(*)){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;white-space:normal;text-wrap:balance}}._header_1g7hg_79[data-row=groupHead],._header_1g7hg_79[data-row=miniature]{font-weight:var(--u-weight-medium)}._headerCount_1g7hg_133{flex:none;color:var(--u-color-text-muted);font-size:var(--u-text-xs);font-variant-numeric:tabular-nums}._chevron_1g7hg_142{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;border-radius:var(--u-radius-xs);corner-shape:squircle;background:transparent;color:var(--u-color-text-secondary);cursor:pointer;transition:background-color var(--u-transition),color var(--u-transition)}._chevron_1g7hg_142:hover{background:var(--u-color-surface-sunken);color:var(--u-color-text)}._chevron_1g7hg_142:active{background:var(--u-color-surface-pressed)}._chevron_1g7hg_142:focus-visible{outline:2px solid transparent;box-shadow:var(--u-focus-ring)}._chevron_1g7hg_142 svg{box-sizing:border-box}._chevron_1g7hg_142 svg{transition:transform var(--u-transition-path)}._chevron_1g7hg_142 svg[data-open]{box-sizing:border-box}._chevron_1g7hg_142 svg[data-open]{transform:rotate(90deg)}@media(prefers-reduced-motion:reduce){._chevron_1g7hg_142 svg{transition:none}}._header_1g7hg_79[data-refused]{color:var(--u-color-text-muted)}._plot_1g7hg_197{position:relative;overflow:hidden;touch-action:none}._plot_1g7hg_197:focus{outline:none}._focusRing_1g7hg_204{position:absolute;inset:2px;border-radius:var(--u-radius-md);corner-shape:squircle;pointer-events:none}._plot_1g7hg_197:focus-visible>._focusRing_1g7hg_204{outline:2px solid transparent;box-shadow:var(--u-focus-ring)}._layer_1g7hg_222{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none}._grip_1g7hg_231{position:absolute;width:9px;margin-left:-4px;border-radius:var(--u-radius-xs);corner-shape:squircle;background:var(--u-color-surface);box-shadow:inset 0 0 0 1.5px var(--u-color-text);cursor:ew-resize}._ghostLabel_1g7hg_241{position:absolute;display:inline-flex;gap:var(--u-space-2);padding:1px var(--u-space-2);border-radius:var(--u-radius-sm);corner-shape:squircle;background:var(--u-color-text);color:var(--u-color-surface);font-size:var(--u-text-xs);white-space:nowrap;pointer-events:none}._finding_1g7hg_254{font-weight:var(--u-weight-semibold);color:var(--u-color-danger-subtle)}._refusal_1g7hg_262{font-weight:var(--u-weight-semibold)}._tooltip_1g7hg_266{position:absolute;z-index:1;display:flex;flex-direction:column;gap:1px;max-width:260px;padding:var(--u-space-2) var(--u-space-3);border-radius:var(--u-radius-sm);corner-shape:squircle;background:var(--u-color-surface);outline:1px solid transparent;box-shadow:var(--u-shadow-overlay);color:var(--u-color-text-secondary);font-size:var(--u-text-xs);line-height:var(--u-leading-tight);pointer-events:none;white-space:nowrap}._tooltipHead_1g7hg_285{color:var(--u-color-text);font-weight:var(--u-weight-semibold)}._tooltipTimes_1g7hg_290{color:var(--u-color-text)}._tooltip_1g7hg_266 ._finding_1g7hg_254{color:var(--u-color-danger-text)}._now_1g7hg_299{position:absolute;top:0;width:0;height:0;margin-left:-4px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid var(--u-color-accent)}._barLabel_1g7hg_313{position:absolute;display:flex;align-items:center;padding:0 var(--u-space-1);overflow:hidden;font-size:var(--u-text-xs);line-height:var(--u-leading-tight);pointer-events:none}._barLabelText_1g7hg_326{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}._barLabel_1g7hg_313[data-on=dark]{color:var(--u-color-on-accent)}._barLabel_1g7hg_313[data-on=light]{color:var(--u-color-text)}@media(forced-colors:active){._grip_1g7hg_231{outline:2px solid CanvasText;outline-offset:-2px}._ghostLabel_1g7hg_241{outline:1px solid CanvasText}}}
1
+ @layer umriss.tokens,umriss.base,umriss.components;@layer umriss.base{._text_18806_22{font-family:var(--u-font-sans);font-size:var(--u-text-md);line-height:var(--u-leading-normal);color:var(--u-color-text);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}@media(pointer:fine){._dense_18806_38{--u-control-height-sm: var(--u-control-height-xs)}}._ink_18806_49{--u-color-text: var(--u-color-bg);--u-color-text-secondary: color-mix(in srgb, var(--u-color-bg) 75%, transparent);--u-color-text-muted: color-mix(in srgb, var(--u-color-bg) 60%, transparent)}._extent_18806_75{--_chars: 20;--_extra: 0;--_tracking: 0px;--_chrome: 0px;min-inline-size:0;max-inline-size:100%;contain:inline-size;contain-intrinsic-inline-size:calc((var(--_chars) + var(--_extra)) * (1ch + var(--_tracking)) + var(--_chrome))}._field_18806_90{caret-color:var(--u-color-accent)}._scroll_18806_96{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--u-color-text) 25%,transparent) transparent}._scroll_18806_96::-webkit-scrollbar{width:10px;height:10px}._scroll_18806_96::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--u-color-text) 22%,transparent);border-radius:var(--u-radius-full);border:3px solid transparent;background-clip:content-box}._scroll_18806_96::-webkit-scrollbar-track{background:transparent}}@layer umriss.components{._ring_18806_125:focus-visible{outline:2px solid transparent;box-shadow:var(--u-focus-ring)}@media(pointer:coarse){._field_18806_90._field_18806_90,._fieldRoot_18806_145._fieldRoot_18806_145{font-size:16px}}._field_18806_90:-webkit-autofill,._field_18806_90:-webkit-autofill:hover,._field_18806_90:-webkit-autofill:focus{-webkit-box-shadow:inset 0 0 0 1000px var(--u-color-surface),0 0 0 1px var(--u-edge-color-strong);-webkit-text-fill-color:var(--u-color-text);caret-color:var(--u-color-accent)}}@layer umriss.components{._root_mm9nj_4,._root_mm9nj_4:before,._root_mm9nj_4:after{box-sizing:border-box}._corner_mm9nj_19,._corner_mm9nj_19:before,._corner_mm9nj_19:after{box-sizing:border-box}._dayBand_mm9nj_23,._dayBand_mm9nj_23:before,._dayBand_mm9nj_23:after{box-sizing:border-box}._tickBand_mm9nj_24,._tickBand_mm9nj_24:before,._tickBand_mm9nj_24:after{box-sizing:border-box}._day_mm9nj_23,._day_mm9nj_23:before,._day_mm9nj_23:after{box-sizing:border-box}._dayLabel_mm9nj_50,._dayLabel_mm9nj_50:before,._dayLabel_mm9nj_50:after{box-sizing:border-box}._tick_mm9nj_24,._tick_mm9nj_24:before,._tick_mm9nj_24:after{box-sizing:border-box}._tickLabel_mm9nj_71,._tickLabel_mm9nj_71:before,._tickLabel_mm9nj_71:after{box-sizing:border-box}._headers_mm9nj_81,._headers_mm9nj_81:before,._headers_mm9nj_81:after{box-sizing:border-box}._header_mm9nj_81,._header_mm9nj_81:before,._header_mm9nj_81:after{box-sizing:border-box}._headerLabel_mm9nj_100,._headerLabel_mm9nj_100:before,._headerLabel_mm9nj_100:after{box-sizing:border-box}._headerCount_mm9nj_136,._headerCount_mm9nj_136:before,._headerCount_mm9nj_136:after{box-sizing:border-box}._chevron_mm9nj_145,._chevron_mm9nj_145:before,._chevron_mm9nj_145:after{box-sizing:border-box}._plot_mm9nj_223,._plot_mm9nj_223:before,._plot_mm9nj_223:after{box-sizing:border-box}._focusRing_mm9nj_237,._focusRing_mm9nj_237:before,._focusRing_mm9nj_237:after{box-sizing:border-box}._layer_mm9nj_255,._layer_mm9nj_255:before,._layer_mm9nj_255:after{box-sizing:border-box}._grip_mm9nj_282,._grip_mm9nj_282:before,._grip_mm9nj_282:after{box-sizing:border-box}._ghostLabel_mm9nj_292,._ghostLabel_mm9nj_292:before,._ghostLabel_mm9nj_292:after{box-sizing:border-box}._finding_mm9nj_305,._finding_mm9nj_305:before,._finding_mm9nj_305:after{box-sizing:border-box}._refusal_mm9nj_313,._refusal_mm9nj_313:before,._refusal_mm9nj_313:after{box-sizing:border-box}._tooltip_mm9nj_317,._tooltip_mm9nj_317:before,._tooltip_mm9nj_317:after{box-sizing:border-box}._tooltipHead_mm9nj_336,._tooltipHead_mm9nj_336:before,._tooltipHead_mm9nj_336:after{box-sizing:border-box}._tooltipTimes_mm9nj_341,._tooltipTimes_mm9nj_341:before,._tooltipTimes_mm9nj_341:after{box-sizing:border-box}._now_mm9nj_350,._now_mm9nj_350:before,._now_mm9nj_350:after{box-sizing:border-box}._barLabel_mm9nj_364,._barLabel_mm9nj_364:before,._barLabel_mm9nj_364:after{box-sizing:border-box}._barLabelText_mm9nj_377,._barLabelText_mm9nj_377:before,._barLabelText_mm9nj_377:after{box-sizing:border-box}._root_mm9nj_4{display:grid;grid-template-rows:28px minmax(0,1fr) 28px;width:100%;font-size:var(--u-text-sm);background:var(--u-color-surface);outline:1px solid transparent;box-shadow:var(--u-edge);border-radius:var(--u-radius-md);corner-shape:squircle;overflow:hidden;font-variant-numeric:tabular-nums;user-select:none}._corner_mm9nj_19{background:var(--u-color-surface)}._dayBand_mm9nj_23,._tickBand_mm9nj_24{position:relative;overflow:hidden;color:var(--u-color-text-muted);font-size:var(--u-text-xs)}._dayBand_mm9nj_23{border-bottom:1px solid var(--u-hairline-strong)}._tickBand_mm9nj_24{border-top:1px solid var(--u-hairline-strong)}._day_mm9nj_23{position:absolute;top:0;bottom:0;border-left:1px solid var(--u-hairline-strong);overflow:hidden}._dayLabel_mm9nj_50{position:absolute;z-index:1;left:var(--u-space-1);padding:0 var(--u-space-1);background:var(--u-color-surface);top:50%;transform:translateY(-50%);white-space:nowrap;color:var(--u-color-text);font-weight:var(--u-weight-medium)}._tick_mm9nj_24{position:absolute;top:0;bottom:0;width:1px;background:var(--u-hairline)}._tickLabel_mm9nj_71{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);white-space:nowrap}._headers_mm9nj_81{contain:size;position:relative;overflow:hidden;border-right:1px solid var(--u-hairline-strong)}._header_mm9nj_81{display:flex;align-items:center;gap:var(--u-space-2);padding-right:var(--u-space-3);border-bottom:1px solid var(--u-hairline);overflow:hidden;white-space:nowrap}._headerLabel_mm9nj_100{min-width:0;overflow:hidden;text-overflow:ellipsis}._header_mm9nj_81[data-row=lane],._header_mm9nj_81[data-row=miniature]{container:lane-header / size}@container lane-header (height >= 2.5rem){._headerLabel_mm9nj_100:not(:has(*)){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;white-space:normal;text-wrap:balance}}._header_mm9nj_81[data-row=groupHead],._header_mm9nj_81[data-row=miniature]{font-weight:var(--u-weight-medium)}._headerCount_mm9nj_136{flex:none;color:var(--u-color-text-muted);font-size:var(--u-text-xs);font-variant-numeric:tabular-nums}._chevron_mm9nj_145{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;border-radius:var(--u-radius-xs);corner-shape:squircle;background:transparent;color:var(--u-color-text-secondary);cursor:pointer;transition:background-color var(--u-transition),color var(--u-transition)}._chevron_mm9nj_145:hover{background:var(--u-color-surface-sunken);color:var(--u-color-text)}._chevron_mm9nj_145:active{background:var(--u-color-surface-pressed)}._chevron_mm9nj_145:focus-visible{outline:2px solid transparent;box-shadow:var(--u-focus-ring)}._chevron_mm9nj_145 svg{box-sizing:border-box}._chevron_mm9nj_145 svg{transition:transform var(--u-transition-path)}._chevron_mm9nj_145 svg[data-open]{box-sizing:border-box}._chevron_mm9nj_145 svg[data-open]{transform:rotate(90deg)}@media(pointer:coarse){._chevron_mm9nj_145{position:relative}._chevron_mm9nj_145:after{content:"";position:absolute;inset:-4px}._header_mm9nj_81[data-row=groupHead]{overflow:clip;overflow-clip-margin:2px}}@media(prefers-reduced-motion:reduce){._chevron_mm9nj_145 svg{transition:none}}._header_mm9nj_81[data-refused]{color:var(--u-color-text-muted)}._plot_mm9nj_223{contain:size;position:relative;overflow:hidden;touch-action:none;-webkit-touch-callout:none;user-select:none}._plot_mm9nj_223:focus{outline:none}._focusRing_mm9nj_237{position:absolute;inset:2px;border-radius:var(--u-radius-md);corner-shape:squircle;pointer-events:none}._plot_mm9nj_223:focus-visible>._focusRing_mm9nj_237{outline:2px solid transparent;box-shadow:var(--u-focus-ring)}._layer_mm9nj_255{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none}._plot_mm9nj_223[data-stale]{pointer-events:none}._plot_mm9nj_223[data-stale]>:not(._focusRing_mm9nj_237){opacity:.5;transition:opacity var(--u-transition, .12s cubic-bezier(.22, 1, .36, 1)) var(--u-delay-stale, .2s)}@media(prefers-reduced-motion:reduce){._plot_mm9nj_223[data-stale]>:not(._focusRing_mm9nj_237){transition-duration:0s}}._grip_mm9nj_282{position:absolute;width:9px;margin-left:-4px;border-radius:var(--u-radius-xs);corner-shape:squircle;background:var(--u-color-surface);box-shadow:inset 0 0 0 1.5px var(--u-color-text);cursor:ew-resize}._ghostLabel_mm9nj_292{position:absolute;display:inline-flex;gap:var(--u-space-2);padding:1px var(--u-space-2);border-radius:var(--u-radius-sm);corner-shape:squircle;background:var(--u-color-text);color:var(--u-color-surface);font-size:var(--u-text-xs);white-space:nowrap;pointer-events:none}._finding_mm9nj_305{font-weight:var(--u-weight-semibold);color:var(--u-color-danger-subtle)}._refusal_mm9nj_313{font-weight:var(--u-weight-semibold)}._tooltip_mm9nj_317{position:absolute;z-index:1;display:flex;flex-direction:column;gap:1px;max-width:260px;padding:var(--u-space-2) var(--u-space-3);border-radius:var(--u-radius-sm);corner-shape:squircle;background:var(--u-color-surface);outline:1px solid transparent;box-shadow:var(--u-shadow-overlay);color:var(--u-color-text-secondary);font-size:var(--u-text-xs);line-height:var(--u-leading-tight);pointer-events:none;white-space:nowrap}._tooltipHead_mm9nj_336{color:var(--u-color-text);font-weight:var(--u-weight-semibold)}._tooltipTimes_mm9nj_341{color:var(--u-color-text)}._tooltip_mm9nj_317 ._finding_mm9nj_305{color:var(--u-color-danger-text)}._now_mm9nj_350{position:absolute;top:0;width:0;height:0;margin-left:-4px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid var(--u-color-accent)}._barLabel_mm9nj_364{position:absolute;display:flex;align-items:center;padding:0 var(--u-space-1);overflow:hidden;font-size:var(--u-text-xs);line-height:var(--u-leading-tight);pointer-events:none}._barLabelText_mm9nj_377{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}._barLabel_mm9nj_364[data-on=dark]{color:var(--u-color-on-accent)}._barLabel_mm9nj_364[data-on=light]{color:var(--u-color-text)}@media(forced-colors:active){._grip_mm9nj_282{outline:2px solid CanvasText;outline-offset:-2px}._ghostLabel_mm9nj_292{outline:1px solid CanvasText}}}