@timebraid/vue 1.17.0 → 1.19.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 +4 -1
- package/dist/index.d.ts +93 -2
- package/dist/style.css +1 -1
- package/dist/timebraid-vue.js +2400 -1984
- package/dist/timebraid-vue.umd.cjs +1 -1
- package/package.json +3 -3
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"]>;
|
|
@@ -1707,6 +1792,7 @@ export declare interface TimelineDay {
|
|
|
1707
1792
|
export declare interface TimelineEntry {
|
|
1708
1793
|
id: string;
|
|
1709
1794
|
task: string;
|
|
1795
|
+
taskId?: string;
|
|
1710
1796
|
start: number;
|
|
1711
1797
|
end?: number | null;
|
|
1712
1798
|
color: string;
|
|
@@ -1719,6 +1805,7 @@ export declare interface TimelineSpan {
|
|
|
1719
1805
|
id: string;
|
|
1720
1806
|
start: number;
|
|
1721
1807
|
end: number;
|
|
1808
|
+
group?: string;
|
|
1722
1809
|
}
|
|
1723
1810
|
|
|
1724
1811
|
export declare function timelineSpan(e: TimelineEntry, nowMin?: number | null): TimelineSpan;
|
|
@@ -1751,6 +1838,10 @@ export declare const TIOSTabBar: DefineComponent<__VLS_Props_42, {}, {}, {}, {},
|
|
|
1751
1838
|
indicator: boolean;
|
|
1752
1839
|
}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLElement>;
|
|
1753
1840
|
|
|
1841
|
+
export declare const TKbd: DefineComponent<__VLS_Props_67, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_67> & Readonly<{}>, {
|
|
1842
|
+
size: keyof typeof SIZES_3;
|
|
1843
|
+
}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLElement>;
|
|
1844
|
+
|
|
1754
1845
|
export declare const TLargeTitle: __VLS_WithTemplateSlots_8<typeof __VLS_component_8, __VLS_TemplateResult_8["slots"]>;
|
|
1755
1846
|
|
|
1756
1847
|
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)}
|