@timebraid/vue 1.17.0 → 1.18.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/README.md CHANGED
@@ -35,6 +35,7 @@ Import `@timebraid/tokens/styles.css` once in `main.ts` (or `@timebraid/vue/styl
35
35
  | `TField` | Filled text field |
36
36
  | `TSelect` | Trailing-value select with `chevrons-up-down`, used inside `TRow`; name the control with `label` (rendered visually hidden) or `ariaLabel` |
37
37
  | `TBadge` | Status pill: neutral, running, green, red, soon |
38
+ | `TKbd` | A keycap: "⌘K", "↵" or "esc" in mono on `--fill` inside a `--sep-strong` ring, 20px (`md` 24px); the palette's rows and foot use it |
38
39
  | `TBanner` | Full-width bar for a standing notice such as "Signed in as Mia Okafor" while an admin acts as another person: an optional icon, a bold title with the text (or the default slot) under it, and a pill `action` on the right; `inverse` (the tooltip's `--label` and `--bg` pairing) by default or `accent`, `compact` for the phone sizes |
39
40
  | `TBar` | Animated value bar |
40
41
  | `TBudgetBar` | A budget bar for Reports: used fills the track, the gap up to where the budget stands by now is tinted and marked, time past the budget runs red |
@@ -54,6 +55,7 @@ Import `@timebraid/tokens/styles.css` once in `main.ts` (or `@timebraid/vue/styl
54
55
  | `TWorkspaceMenu` | The workspace list shared by the switcher's popover and the drawer; `embedded` drops its shadow for inline use; `actions` sit between two hairlines above New workspace |
55
56
  | `TWorkspaceDrawer` | Full-height phone workspace list; drag the panel to dismiss; `actions` pin above Add a workspace and emit `action` with the id, then `close` |
56
57
  | `TTimerBar` | Phone bottom timer bar: takes the full `timers` array, count first with the longest leading; with several timers its stop control emits `open` for the running sheet instead of stopping them all |
58
+ | `TAuthBackdrop` | The sign-in stage from the app icon: brand field, oversized stopwatch dial, sweeping orange hand |
57
59
  | `TStrokes` | Oversized faded tally strokes behind sign-in and empty states |
58
60
  | `TStartHero` | The pill-shaped start field that opens Today: "Start a timer" with "Quick start" chips on desktop when nothing runs, "Start another timer" with a "Runs in parallel" hint (chips kept) when `hasRunning`, the bare pill when `mobile` |
59
61
  | `TIOSNav` | iOS nav bar under the status-bar inset (`--inset-top`); the `leading` control, the large title and the `right` actions share one line and the title collapses in place on scroll |
@@ -72,6 +74,7 @@ Import `@timebraid/tokens/styles.css` once in `main.ts` (or `@timebraid/vue/styl
72
74
  | `TPeriodStepper` | ‹ This week › at the top of a chart card: the arrows step one day, week or month, the label opens a `TMenu` of Day, Week, Month and Custom range…, and a text link returns to the current period |
73
75
  | `TMenu` | A small choice menu: a 230px popover under its anchor on the desktop, a bottom sheet of rows on the phone, the chosen item in accent with a check |
74
76
  | `TSearchField` | Page search field with a `/` keycap that focuses it from anywhere, a clear button once there is text, and Escape to clear and blur; `size="sm"` for lists in sheets, `busy` for a spinner |
77
+ | `TCommandPalette` | The ⌘K search: a centred dialog on a scrim with a combobox head, grouped option rows led by an avatar, a colour dot or an icon tile with the query marked in every title, hints and keycaps on the right, arrow keys, Enter and Escape, an empty state and a foot of keycap hints; `mobile` fills the screen with Cancel; `paletteIds` and `stepActive` walk the groups |
75
78
  | `TParallelMark` | Two short running bars, titled "Ran alongside {names}"; replaces the "in parallel" chip on rows |
76
79
  | `TAutoStopMark` | An orange `timer-off`, titled "Stopped automatically. Check the end time"; replaces that chip on rows |
77
80
  | `TFilterButton` | The Filters button beside search; accent with a count badge when filters are on, icon-only with a corner badge when `compact` |
@@ -83,7 +86,7 @@ Import `@timebraid/tokens/styles.css` once in `main.ts` (or `@timebraid/vue/styl
83
86
  | `TSkeleton` | A shimmering placeholder block (text line, block, circle or pill) for a page that has not drawn yet; `.t-skeleton` in the tokens paints the shimmer |
84
87
  | `TSkeletonList` | The skeleton of a list card: rows of a leading mark, two lines of differing length and a short right block |
85
88
 
86
- Also exported: `formatDuration(seconds, 'clock' | 'short' | 'compact' | 'friendly')`, the timeline helpers (`timelineSpan`, `isRunningEntry`, `parallelMinutes`, `parallelPartners`), the task colours (`taskSwatches`, `swatchFill`, `swatchInk`, `SWATCH_COLORS`, `STRIPES`, `RUNNING_SHEEN`), `hourLabel`, `minutesToAmPm`, `toggleId`, the filter helpers (`emptyFilters`, `copyFilters`, `filterCount`, `entriesText`, `ENTRY_FLAGS`, `NOTE_FILTERS`, `DIMENSION_KEYS`, `FLAG_LABELS`, `FLAG_HINTS`, `NOTE_LABELS`) and their types, `PickItem` and `PickPage`, `highlightSegments`, `PROJECT_COLORS`, `TIMEBRAID_ICON_BASE`, `DEFAULT_ICON_BASE`, `resolveTheme`, `applyTheme`, `watchTheme`, `THEME_PREFERENCES`.
89
+ Also exported: `formatDuration(seconds, 'clock' | 'short' | 'compact' | 'friendly')`, the timeline helpers (`timelineSpan`, `isRunningEntry`, `parallelMinutes`, `parallelPartners`), the task colours (`taskSwatches`, `swatchFill`, `swatchInk`, `SWATCH_COLORS`, `STRIPES`, `RUNNING_SHEEN`), `hourLabel`, `minutesToAmPm`, `toggleId`, the filter helpers (`emptyFilters`, `copyFilters`, `filterCount`, `entriesText`, `ENTRY_FLAGS`, `NOTE_FILTERS`, `DIMENSION_KEYS`, `FLAG_LABELS`, `FLAG_HINTS`, `NOTE_LABELS`) and their types, `PickItem` and `PickPage`, `highlightSegments`, the palette helpers (`paletteIds`, `stepActive`) and their types `PaletteItem` and `PaletteGroup`, `PROJECT_COLORS`, `TIMEBRAID_ICON_BASE`, `DEFAULT_ICON_BASE`, `resolveTheme`, `applyTheme`, `watchTheme`, `THEME_PREFERENCES`.
87
90
 
88
91
  `TIcon` ships its glyphs: `scripts/glyphs.mjs` writes the Lucide paths for every name the products use into `packages/vue/src/icons/glyphs.ts`, and the component renders them inline in `currentColor`. Nothing is fetched at runtime. To add a glyph, add its name to `NAMES` in the script and run `pnpm glyphs`. `ICON_NAMES` and `hasIcon()` are exported so an app can assert every name it uses is bundled. A name missing from the table still masks from `TIMEBRAID_ICON_BASE` (or the `base` prop) with a dev warning, so nothing breaks while the table catches up.
89
92
 
package/dist/index.d.ts CHANGED
@@ -12,19 +12,20 @@ plainTitle: boolean;
12
12
  declare const __VLS_component_10: DefineComponent<__VLS_Props_34, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
13
13
  stop: (id: string) => any;
14
14
  start: () => any;
15
+ openApp: () => any;
15
16
  "update:open": (v: boolean) => any;
16
17
  stopAll: () => any;
17
- openApp: () => any;
18
18
  }, string, PublicProps, Readonly<__VLS_Props_34> & Readonly<{
19
19
  onStop?: ((id: string) => any) | undefined;
20
20
  onStart?: (() => any) | undefined;
21
+ onOpenApp?: (() => any) | undefined;
21
22
  "onUpdate:open"?: ((v: boolean) => any) | undefined;
22
23
  onStopAll?: (() => any) | undefined;
23
- onOpenApp?: (() => any) | undefined;
24
24
  }>, {
25
25
  compact: boolean;
26
26
  open: boolean;
27
27
  paused: boolean;
28
+ openApp: boolean;
28
29
  }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
29
30
 
30
31
  declare const __VLS_component_11: DefineComponent<__VLS_Props_41, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_41> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
@@ -383,6 +384,7 @@ declare type __VLS_Props_34 = {
383
384
  compact?: boolean;
384
385
  paused?: boolean;
385
386
  open?: boolean;
387
+ openApp?: boolean;
386
388
  };
387
389
 
388
390
  declare type __VLS_Props_35 = {
@@ -667,6 +669,11 @@ declare type __VLS_Props_66 = {
667
669
  compact?: boolean;
668
670
  };
669
671
 
672
+ declare type __VLS_Props_67 = {
673
+ keys: string;
674
+ size?: keyof typeof SIZES_3;
675
+ };
676
+
670
677
  declare type __VLS_Props_7 = {
671
678
  modelValue: string;
672
679
  options: {
@@ -1247,6 +1254,28 @@ export declare interface PageSlice<T> extends PageBounds {
1247
1254
 
1248
1255
  export declare function pageSlice<T>(items: readonly T[], page: number, size: number): PageSlice<T>;
1249
1256
 
1257
+ export declare interface PaletteGroup {
1258
+ id: string;
1259
+ title: string;
1260
+ items: readonly PaletteItem[];
1261
+ }
1262
+
1263
+ export declare const paletteIds: (groups: readonly PaletteGroup[]) => string[];
1264
+
1265
+ export declare interface PaletteItem {
1266
+ id: string;
1267
+ title: string;
1268
+ subtitle?: string;
1269
+ icon?: string;
1270
+ color?: string;
1271
+ avatar?: {
1272
+ name: string;
1273
+ src?: string;
1274
+ };
1275
+ hint?: string;
1276
+ kbd?: string;
1277
+ }
1278
+
1250
1279
  export declare function parallelMinutes(spans: readonly TimelineSpan[]): number;
1251
1280
 
1252
1281
  export declare function parallelPartners(spans: readonly TimelineSpan[]): Map<string, string[]>;
@@ -1413,10 +1442,23 @@ declare const SIZES_2: {
1413
1442
  };
1414
1443
  };
1415
1444
 
1445
+ declare const SIZES_3: {
1446
+ readonly sm: {
1447
+ readonly height: 20;
1448
+ readonly font: 11;
1449
+ };
1450
+ readonly md: {
1451
+ readonly height: 24;
1452
+ readonly font: 12;
1453
+ };
1454
+ };
1455
+
1416
1456
  export declare function spanLabel(from: string, to: string, today: string): string;
1417
1457
 
1418
1458
  export declare function startOfWeekIso(iso: string): string;
1419
1459
 
1460
+ export declare const stepActive: (groups: readonly PaletteGroup[], activeId: string | null, delta: 1 | -1) => string | null;
1461
+
1420
1462
  export declare const STRIPES = "repeating-linear-gradient(135deg, rgba(255,255,255,.55) 0 2px, transparent 2px 5px)";
1421
1463
 
1422
1464
  export declare const SWATCH_COLORS: readonly string[];
@@ -1456,6 +1498,8 @@ export declare interface TaskSwatch {
1456
1498
 
1457
1499
  export declare function taskSwatches(ids: readonly string[]): Map<string, TaskSwatch>;
1458
1500
 
1501
+ export declare const TAuthBackdrop: DefineComponent< {}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, true, {}, HTMLDivElement>;
1502
+
1459
1503
  export declare const TAuthCard: __VLS_WithTemplateSlots_13<typeof __VLS_component_13, __VLS_TemplateResult_13["slots"]>;
1460
1504
 
1461
1505
  export declare const TAutoStopMark: DefineComponent< {}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, true, {}, HTMLSpanElement>;
@@ -1520,6 +1564,47 @@ modelValue: string;
1520
1564
  autofocus: boolean;
1521
1565
  }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
1522
1566
 
1567
+ export declare const TCommandPalette: DefineComponent< {
1568
+ open: boolean;
1569
+ query: string;
1570
+ groups: readonly PaletteGroup[];
1571
+ activeId: string | null;
1572
+ placeholder?: string;
1573
+ empty?: string;
1574
+ mobile?: boolean;
1575
+ teleport?: boolean;
1576
+ busy?: boolean;
1577
+ }, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
1578
+ close: () => any;
1579
+ pick: (id: string) => any;
1580
+ "update:query": (value: string) => any;
1581
+ "update:activeId": (id: string | null) => any;
1582
+ }, string, PublicProps, Readonly<{
1583
+ open: boolean;
1584
+ query: string;
1585
+ groups: readonly PaletteGroup[];
1586
+ activeId: string | null;
1587
+ placeholder?: string;
1588
+ empty?: string;
1589
+ mobile?: boolean;
1590
+ teleport?: boolean;
1591
+ busy?: boolean;
1592
+ }> & Readonly<{
1593
+ onClose?: (() => any) | undefined;
1594
+ onPick?: ((id: string) => any) | undefined;
1595
+ "onUpdate:query"?: ((value: string) => any) | undefined;
1596
+ "onUpdate:activeId"?: ((id: string | null) => any) | undefined;
1597
+ }>, {
1598
+ placeholder: string;
1599
+ teleport: boolean;
1600
+ mobile: boolean;
1601
+ empty: string;
1602
+ busy: boolean;
1603
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {
1604
+ input: HTMLInputElement;
1605
+ list: HTMLDivElement;
1606
+ }, any>;
1607
+
1523
1608
  export declare const TConfirmButton: __VLS_WithTemplateSlots_4<typeof __VLS_component_4, __VLS_TemplateResult_4["slots"]>;
1524
1609
 
1525
1610
  export declare const TConfirmRow: __VLS_WithTemplateSlots_3<typeof __VLS_component_3, __VLS_TemplateResult_3["slots"]>;
@@ -1751,6 +1836,10 @@ export declare const TIOSTabBar: DefineComponent<__VLS_Props_42, {}, {}, {}, {},
1751
1836
  indicator: boolean;
1752
1837
  }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLElement>;
1753
1838
 
1839
+ export declare const TKbd: DefineComponent<__VLS_Props_67, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_67> & Readonly<{}>, {
1840
+ size: keyof typeof SIZES_3;
1841
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLElement>;
1842
+
1754
1843
  export declare const TLargeTitle: __VLS_WithTemplateSlots_8<typeof __VLS_component_8, __VLS_TemplateResult_8["slots"]>;
1755
1844
 
1756
1845
  export declare const TLogo: DefineComponent<__VLS_Props_46, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_46> & Readonly<{}>, {
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @import"https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=JetBrains+Mono:wght@400..700&display=swap";:root{--font-display:var(--font-sans);--font-ui:var(--font-sans);--font-numeric:var(--font-mono)}:root{--font-sans:"Instrument Sans",-apple-system,BlinkMacSystemFont,"SF Pro Text",sans-serif;--font-mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,monospace;--indigo-400:#6C77DE;--indigo-500:#4A57D2;--indigo-600:#3A44AF;--indigo-700:#2C3391;--chart-1:#0072B2;--chart-2:#E69F00;--chart-3:#009E73;--chart-4:#CC79A7;--chart-5:#56B4E9;--chart-6:#D55E00;--chart-7:#F0E442;--chart-8:#6B7085;--bg:#F2F3F8;--bg-elev:#FFFFFF;--bg-elev-2:#F7F8FC;--bg-sidebar:rgba(244,245,250,.86);--bg-bar:rgba(242,243,248,.82);--fill:rgba(20,22,40,.06);--fill-2:rgba(20,22,40,.1);--fill-3:rgba(20,22,40,.16);--sep:rgba(20,22,40,.1);--sep-strong:rgba(20,22,40,.18);--label:#0E1024;--label-2:#5C6178;--label-3:#8B90A5;--label-4:#B7BBCB;--on-accent:#FFFFFF;--accent:#4A57D2;--accent-hover:#3F4BC0;--accent-soft:rgba(74,87,210,.12);--accent-soft-2:rgba(74,87,210,.2);--running:#4A57D2;--running-soft:rgba(74,87,210,.1);--green:#1E9E6A;--green-soft:rgba(30,158,106,.12);--red:#D6453D;--red-soft:rgba(214,69,61,.1);--orange:#D97B0F;--r-cell:12px;--r-card:14px;--r-btn:10px;--r-pill:999px;--r-sheet:20px;--r-window:12px;--sh-card:0 1px 2px rgba(14,16,36,.04),0 0 0 1px rgba(14,16,36,.04);--sh-float:0 12px 32px -8px rgba(14,16,36,.22),0 2px 6px rgba(14,16,36,.08),0 0 0 1px rgba(14,16,36,.05);--sh-sheet:0 -8px 40px -8px rgba(14,16,36,.24);--sh-thumb:0 2px 6px rgba(0,0,0,.25);--sh-seg:0 1px 2px rgba(0,0,0,.14),0 3px 8px -2px rgba(0,0,0,.12),0 0 0 .5px var(--sep);--blur:saturate(180%) blur(22px);--scrim:rgba(10,11,20,.42);--dash:rgba(255,255,255,.7);--ease:cubic-bezier(.2,0,.2,1);--ease-out:cubic-bezier(.16,1,.3,1);--ease-sheet:cubic-bezier(.32,.72,0,1);--t-fast:.14s;--t-base:.22s;--t-sheet:.42s}[data-theme=dark]{--bg:#15161F;--bg-elev:#1F2030;--bg-elev-2:#282A3C;--bg-sidebar:rgba(24,25,36,.86);--bg-bar:rgba(21,22,31,.78);--fill:rgba(255,255,255,.07);--fill-2:rgba(255,255,255,.11);--fill-3:rgba(255,255,255,.17);--sep:rgba(255,255,255,.09);--sep-strong:rgba(255,255,255,.16);--label:#F3F4FA;--label-2:#A7ABC0;--label-3:#7D8199;--label-4:#575B70;--accent:#7A84E6;--accent-hover:#8C95EC;--accent-soft:rgba(122,132,230,.16);--accent-soft-2:rgba(122,132,230,.26);--running:#8A93EC;--running-soft:rgba(122,132,230,.14);--green:#3CC08A;--green-soft:rgba(60,192,138,.14);--red:#F06B62;--red-soft:rgba(240,107,98,.14);--orange:#F0A24B;--chart-8:#9A9FB4;--sh-card:0 1px 2px rgba(0,0,0,.2),0 0 0 1px rgba(255,255,255,.04);--sh-float:0 16px 40px -8px rgba(0,0,0,.6),0 2px 8px rgba(0,0,0,.3),0 0 0 1px rgba(255,255,255,.08);--sh-sheet:0 -8px 40px -8px rgba(0,0,0,.6);--scrim:rgba(0,0,0,.55)}:root{--text-display-1:64px;--leading-display-1:1.02;--tracking-display-1:-.03em;--text-display-2:48px;--leading-display-2:1.06;--tracking-display-2:-.025em;--text-large-title:30px;--text-large-title-phone:34px;--tracking-large-title:-.025em;--leading-large-title:1.1;--text-title:17px;--text-row:15px;--text-subtitle:12.5px;--text-section:12px;--tracking-section:.04em;--text-body:14px;--text-body-lg:18px;--leading-body-lg:1.6;--text-caption:12px;--text-footnote:11.5px;--text-timer-xl:44px;--text-timer-lg:28px;--text-timer-md:22px;--text-timer-sm:15px;--weight-regular:400;--weight-medium:500;--weight-semibold:600;--weight-bold:700}:root{--space-0:0px;--space-1:2px;--space-2:4px;--space-3:8px;--space-4:12px;--space-5:16px;--space-6:20px;--space-7:24px;--space-8:32px;--space-9:40px;--space-10:48px;--space-11:64px;--space-12:80px;--space-13:112px;--space-14:160px;--section-y:112px;--section-y-tight:72px;--container-max:1160px;--container-prose:660px;--gutter:24px;--sidebar-w:232px;--content-max:1040px;--content-max-narrow:760px;--gutter-phone:16px;--row-h:46px;--row-h-sub:56px;--row-h-dense:40px;--control-h-sm:30px;--control-h-md:36px;--control-h-lg:44px;--control-h-xl:50px;--pill-h:46px;--pill-h-compact:30px;--timer-bar-h:56px;--timer-bar-pad:72px;--inset-top:env(safe-area-inset-top,0px);--inset-bottom:env(safe-area-inset-bottom,0px);--tab-bar-inset-ios:max(10px,calc(var(--inset-bottom) - 12px));--tab-bar-h-ios:calc(42px + var(--tab-bar-inset-ios));--timer-bar-bottom-ios:calc(var(--tab-bar-h-ios) + 10px);--tab-bar-pad-ios:calc(var(--tab-bar-h-ios) + 16px);--nav-bar-h-android:80px;--nav-bar-pad-android:96px;--toggle-w:46px;--toggle-h:28px;--field-h:38px;--seg-h:36px;--seg-h-sm:30px;--icon-square:28px}*,*:before,*:after{box-sizing:border-box}html,body{margin:0}html{-webkit-text-size-adjust:100%}body{font-family:var(--font-sans);color:var(--label);background:var(--bg);-webkit-font-smoothing:antialiased;font-size:var(--text-body);line-height:1.45}button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent}input,select,textarea{font:inherit;color:inherit}a{color:var(--accent);text-decoration:none}a:hover{color:var(--accent-hover)}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}.clamp-2{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere;line-height:1.3;min-width:0}.ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::selection{background:var(--accent-soft-2)}@keyframes t-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes t-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.t-skeleton{background:linear-gradient(90deg,var(--fill) 25%,var(--fill-2) 50%,var(--fill) 75%);background-size:400% 100%;animation:t-shimmer 1.6s linear infinite}@media (prefers-reduced-motion:reduce){.t-skeleton{animation:none;background:var(--fill)}}@keyframes t-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}@keyframes t-sheet{0%{transform:translateY(100%)}to{transform:none}}@keyframes t-drawer{0%{transform:translate(-100%)}to{transform:none}}@keyframes t-scrim{0%{opacity:0}to{opacity:1}}@keyframes t-pop{0%{opacity:0;transform:scale(.96) translateY(6px)}to{opacity:1;transform:none}}@keyframes t-island{0%{transform:scaleX(.6);opacity:.4}to{transform:none;opacity:1}}.view-in{animation:t-in var(--t-base) var(--ease-out) both}.press{transition:transform var(--t-fast) var(--ease),background var(--t-fast) var(--ease),opacity var(--t-fast) var(--ease)}.press:active{transform:scale(.98)}.row-press:active{background:var(--fill-2)!important}@media (prefers-reduced-motion:reduce){*{animation-duration:0ms!important;transition-duration:0ms!important}}.t-wheel-list[data-v-f89240c7]{scrollbar-width:none}.t-wheel-list[data-v-f89240c7]::-webkit-scrollbar{display:none}.t-wheel-list[data-v-f89240c7]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--r-btn)}.check:focus-within .box[data-v-8c783040]{outline:2px solid var(--accent);outline-offset:2px}.t-spinner[data-v-a41169e8]{animation:t-spinner-turn-a41169e8 .7s linear infinite}@keyframes t-spinner-turn-a41169e8{to{transform:rotate(360deg)}}
1
+ @import"https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=JetBrains+Mono:wght@400..700&display=swap";:root{--font-display:var(--font-sans);--font-ui:var(--font-sans);--font-numeric:var(--font-mono)}:root{--font-sans:"Instrument Sans",-apple-system,BlinkMacSystemFont,"SF Pro Text",sans-serif;--font-mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,monospace;--indigo-400:#6C77DE;--indigo-500:#4A57D2;--indigo-600:#3A44AF;--indigo-700:#2C3391;--chart-1:#0072B2;--chart-2:#E69F00;--chart-3:#009E73;--chart-4:#CC79A7;--chart-5:#56B4E9;--chart-6:#D55E00;--chart-7:#F0E442;--chart-8:#6B7085;--bg:#F2F3F8;--bg-elev:#FFFFFF;--bg-elev-2:#F7F8FC;--bg-sidebar:rgba(244,245,250,.86);--bg-bar:rgba(242,243,248,.82);--fill:rgba(20,22,40,.06);--fill-2:rgba(20,22,40,.1);--fill-3:rgba(20,22,40,.16);--sep:rgba(20,22,40,.1);--sep-strong:rgba(20,22,40,.18);--label:#0E1024;--label-2:#5C6178;--label-3:#8B90A5;--label-4:#B7BBCB;--on-accent:#FFFFFF;--accent:#4A57D2;--accent-hover:#3F4BC0;--accent-soft:rgba(74,87,210,.12);--accent-soft-2:rgba(74,87,210,.2);--running:#4A57D2;--running-soft:rgba(74,87,210,.1);--green:#1E9E6A;--green-soft:rgba(30,158,106,.12);--red:#D6453D;--red-soft:rgba(214,69,61,.1);--orange:#D97B0F;--brand-field:#5D68CF;--brand-field-deep:#191E5E;--brand-ink:#141846;--r-cell:12px;--r-card:14px;--r-btn:10px;--r-pill:999px;--r-sheet:20px;--r-window:12px;--sh-card:0 1px 2px rgba(14,16,36,.04),0 0 0 1px rgba(14,16,36,.04);--sh-float:0 12px 32px -8px rgba(14,16,36,.22),0 2px 6px rgba(14,16,36,.08),0 0 0 1px rgba(14,16,36,.05);--sh-sheet:0 -8px 40px -8px rgba(14,16,36,.24);--sh-thumb:0 2px 6px rgba(0,0,0,.25);--sh-seg:0 1px 2px rgba(0,0,0,.14),0 3px 8px -2px rgba(0,0,0,.12),0 0 0 .5px var(--sep);--blur:saturate(180%) blur(22px);--scrim:rgba(10,11,20,.42);--dash:rgba(255,255,255,.7);--ease:cubic-bezier(.2,0,.2,1);--ease-out:cubic-bezier(.16,1,.3,1);--ease-sheet:cubic-bezier(.32,.72,0,1);--t-fast:.14s;--t-base:.22s;--t-sheet:.42s}[data-theme=dark]{--bg:#15161F;--bg-elev:#1F2030;--bg-elev-2:#282A3C;--bg-sidebar:rgba(24,25,36,.86);--bg-bar:rgba(21,22,31,.78);--fill:rgba(255,255,255,.07);--fill-2:rgba(255,255,255,.11);--fill-3:rgba(255,255,255,.17);--sep:rgba(255,255,255,.09);--sep-strong:rgba(255,255,255,.16);--label:#F3F4FA;--label-2:#A7ABC0;--label-3:#7D8199;--label-4:#575B70;--accent:#7A84E6;--accent-hover:#8C95EC;--accent-soft:rgba(122,132,230,.16);--accent-soft-2:rgba(122,132,230,.26);--running:#8A93EC;--running-soft:rgba(122,132,230,.14);--green:#3CC08A;--green-soft:rgba(60,192,138,.14);--red:#F06B62;--red-soft:rgba(240,107,98,.14);--orange:#F0A24B;--chart-8:#9A9FB4;--sh-card:0 1px 2px rgba(0,0,0,.2),0 0 0 1px rgba(255,255,255,.04);--sh-float:0 16px 40px -8px rgba(0,0,0,.6),0 2px 8px rgba(0,0,0,.3),0 0 0 1px rgba(255,255,255,.08);--sh-sheet:0 -8px 40px -8px rgba(0,0,0,.6);--scrim:rgba(0,0,0,.55)}:root{--text-display-1:64px;--leading-display-1:1.02;--tracking-display-1:-.03em;--text-display-2:48px;--leading-display-2:1.06;--tracking-display-2:-.025em;--text-large-title:30px;--text-large-title-phone:34px;--tracking-large-title:-.025em;--leading-large-title:1.1;--text-title:17px;--text-row:15px;--text-subtitle:12.5px;--text-section:12px;--tracking-section:.04em;--text-body:14px;--text-body-lg:18px;--leading-body-lg:1.6;--text-caption:12px;--text-footnote:11.5px;--text-timer-xl:44px;--text-timer-lg:28px;--text-timer-md:22px;--text-timer-sm:15px;--weight-regular:400;--weight-medium:500;--weight-semibold:600;--weight-bold:700}:root{--space-0:0px;--space-1:2px;--space-2:4px;--space-3:8px;--space-4:12px;--space-5:16px;--space-6:20px;--space-7:24px;--space-8:32px;--space-9:40px;--space-10:48px;--space-11:64px;--space-12:80px;--space-13:112px;--space-14:160px;--section-y:112px;--section-y-tight:72px;--container-max:1160px;--container-prose:660px;--gutter:24px;--sidebar-w:232px;--content-max:1040px;--content-max-narrow:760px;--gutter-phone:16px;--row-h:46px;--row-h-sub:56px;--row-h-dense:40px;--control-h-sm:30px;--control-h-md:36px;--control-h-lg:44px;--control-h-xl:50px;--pill-h:46px;--pill-h-compact:30px;--timer-bar-h:56px;--timer-bar-pad:72px;--inset-top:env(safe-area-inset-top,0px);--inset-bottom:env(safe-area-inset-bottom,0px);--tab-bar-inset-ios:max(10px,calc(var(--inset-bottom) - 12px));--tab-bar-h-ios:calc(42px + var(--tab-bar-inset-ios));--timer-bar-bottom-ios:calc(var(--tab-bar-h-ios) + 10px);--tab-bar-pad-ios:calc(var(--tab-bar-h-ios) + 16px);--nav-bar-h-android:80px;--nav-bar-pad-android:96px;--toggle-w:46px;--toggle-h:28px;--field-h:38px;--seg-h:36px;--seg-h-sm:30px;--icon-square:28px}*,*:before,*:after{box-sizing:border-box}html,body{margin:0}html{-webkit-text-size-adjust:100%}body{font-family:var(--font-sans);color:var(--label);background:var(--bg);-webkit-font-smoothing:antialiased;font-size:var(--text-body);line-height:1.45}button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent}input,select,textarea{font:inherit;color:inherit}a{color:var(--accent);text-decoration:none}a:hover{color:var(--accent-hover)}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}.clamp-2{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere;line-height:1.3;min-width:0}.ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::selection{background:var(--accent-soft-2)}@keyframes t-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes t-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.t-skeleton{background:linear-gradient(90deg,var(--fill) 25%,var(--fill-2) 50%,var(--fill) 75%);background-size:400% 100%;animation:t-shimmer 1.6s linear infinite}@media (prefers-reduced-motion:reduce){.t-skeleton{animation:none;background:var(--fill)}}@keyframes t-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}@keyframes t-sheet{0%{transform:translateY(100%)}to{transform:none}}@keyframes t-drawer{0%{transform:translate(-100%)}to{transform:none}}@keyframes t-scrim{0%{opacity:0}to{opacity:1}}@keyframes t-pop{0%{opacity:0;transform:scale(.96) translateY(6px)}to{opacity:1;transform:none}}@keyframes t-island{0%{transform:scaleX(.6);opacity:.4}to{transform:none;opacity:1}}@keyframes t-sweep{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes t-float{0%,to{translate:0 0}50%{translate:0 -6px}}@keyframes t-flash{0%,30%{background-color:var(--accent-soft);box-shadow:inset 0 0 0 1.5px var(--accent)}to{background-color:transparent;box-shadow:none}}.view-in{animation:t-in var(--t-base) var(--ease-out) both}.t-flash{animation:t-flash 2s var(--ease) 1 both}.press{transition:transform var(--t-fast) var(--ease),background var(--t-fast) var(--ease),opacity var(--t-fast) var(--ease)}.press:active{transform:scale(.98)}.row-press:active{background:var(--fill-2)!important}@media (prefers-reduced-motion:reduce){*{animation-duration:0ms!important;transition-duration:0ms!important}}.t-wheel-list[data-v-f89240c7]{scrollbar-width:none}.t-wheel-list[data-v-f89240c7]::-webkit-scrollbar{display:none}.t-wheel-list[data-v-f89240c7]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--r-btn)}.check:focus-within .box[data-v-8c783040]{outline:2px solid var(--accent);outline-offset:2px}.t-spinner[data-v-a41169e8]{animation:t-spinner-turn-a41169e8 .7s linear infinite}@keyframes t-spinner-turn-a41169e8{to{transform:rotate(360deg)}}[data-palette-item][data-v-088bc492]:hover:not([aria-selected=true]){background:var(--fill)}