@nomideusz/svelte-calendar 0.4.0 → 0.5.2

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.
Files changed (73) hide show
  1. package/README.md +331 -568
  2. package/dist/adapters/recurring.d.ts +45 -8
  3. package/dist/adapters/recurring.js +227 -49
  4. package/dist/adapters/rest.js +6 -1
  5. package/dist/calendar/Calendar.svelte +118 -30
  6. package/dist/calendar/Calendar.svelte.d.ts +9 -8
  7. package/dist/calendar/index.d.ts +0 -1
  8. package/dist/calendar/index.js +0 -1
  9. package/dist/core/index.d.ts +5 -4
  10. package/dist/core/index.js +2 -3
  11. package/dist/core/locale.d.ts +74 -0
  12. package/dist/core/locale.js +96 -4
  13. package/dist/core/time.d.ts +30 -0
  14. package/dist/core/time.js +42 -0
  15. package/dist/core/types.d.ts +1 -72
  16. package/dist/core/types.js +1 -8
  17. package/dist/engine/event-store.svelte.js +2 -2
  18. package/dist/engine/index.d.ts +1 -1
  19. package/dist/engine/view-state.svelte.d.ts +11 -6
  20. package/dist/engine/view-state.svelte.js +5 -4
  21. package/dist/index.d.ts +6 -7
  22. package/dist/index.js +4 -4
  23. package/dist/primitives/EmptySlot.svelte +6 -16
  24. package/dist/primitives/EventBlock.svelte +6 -19
  25. package/dist/primitives/NowIndicator.svelte +7 -4
  26. package/dist/primitives/TimeGutter.svelte +1 -1
  27. package/dist/theme/index.d.ts +1 -1
  28. package/dist/theme/index.js +1 -1
  29. package/dist/theme/presets.d.ts +11 -19
  30. package/dist/theme/presets.js +25 -111
  31. package/dist/views/agenda/Agenda.svelte +17 -1516
  32. package/dist/views/agenda/Agenda.svelte.d.ts +0 -14
  33. package/dist/views/agenda/AgendaDay.svelte +976 -0
  34. package/dist/views/agenda/AgendaDay.svelte.d.ts +14 -0
  35. package/dist/views/agenda/AgendaWeek.svelte +775 -0
  36. package/dist/views/agenda/AgendaWeek.svelte.d.ts +15 -0
  37. package/dist/views/agenda/index.d.ts +2 -0
  38. package/dist/views/agenda/index.js +2 -0
  39. package/dist/views/index.d.ts +2 -6
  40. package/dist/views/index.js +2 -6
  41. package/dist/views/planner/Planner.svelte +17 -0
  42. package/dist/views/planner/Planner.svelte.d.ts +7 -0
  43. package/dist/views/planner/PlannerDay.svelte +957 -0
  44. package/dist/views/{day/DayGrid.svelte.d.ts → planner/PlannerDay.svelte.d.ts} +6 -16
  45. package/dist/views/planner/PlannerWeek.svelte +840 -0
  46. package/dist/views/{week/WeekGrid.svelte.d.ts → planner/PlannerWeek.svelte.d.ts} +4 -9
  47. package/dist/views/planner/index.d.ts +1 -0
  48. package/dist/views/planner/index.js +1 -0
  49. package/dist/widget/CalendarWidget.svelte +54 -33
  50. package/dist/widget/CalendarWidget.svelte.d.ts +1 -1
  51. package/package.json +70 -65
  52. package/widget/svelte-calendar.css +1 -0
  53. package/widget/widget.js +122 -260
  54. package/dist/calendar/Toolbar.svelte +0 -244
  55. package/dist/calendar/Toolbar.svelte.d.ts +0 -21
  56. package/dist/views/day/DayGrid.svelte +0 -1104
  57. package/dist/views/day/DayTimeline.svelte +0 -533
  58. package/dist/views/day/DayTimeline.svelte.d.ts +0 -8
  59. package/dist/views/day/index.d.ts +0 -2
  60. package/dist/views/day/index.js +0 -2
  61. package/dist/views/schedule/WeekSchedule.svelte +0 -137
  62. package/dist/views/schedule/WeekSchedule.svelte.d.ts +0 -40
  63. package/dist/views/schedule/index.d.ts +0 -1
  64. package/dist/views/schedule/index.js +0 -2
  65. package/dist/views/settings/Settings.svelte +0 -585
  66. package/dist/views/settings/Settings.svelte.d.ts +0 -39
  67. package/dist/views/settings/index.d.ts +0 -2
  68. package/dist/views/settings/index.js +0 -1
  69. package/dist/views/week/WeekGrid.svelte +0 -632
  70. package/dist/views/week/WeekHeatmap.svelte +0 -461
  71. package/dist/views/week/WeekHeatmap.svelte.d.ts +0 -9
  72. package/dist/views/week/index.d.ts +0 -2
  73. package/dist/views/week/index.js +0 -2
@@ -1,12 +1,8 @@
1
1
  import type { TimelineEvent } from '../../core/types.js';
2
2
  interface Props {
3
- weekOffset?: number;
4
3
  mondayStart?: boolean;
5
4
  locale?: string;
6
- hourHeight?: number;
7
- dayWidth?: number;
8
- nowPosition?: number;
9
- height?: number;
5
+ height?: number | null;
10
6
  events?: TimelineEvent[];
11
7
  style?: string;
12
8
  focusDate?: Date;
@@ -17,9 +13,8 @@ interface Props {
17
13
  }) => void;
18
14
  selectedEventId?: string | null;
19
15
  readOnly?: boolean;
20
- visibleHours?: [number, number];
21
16
  [key: string]: unknown;
22
17
  }
23
- declare const WeekGrid: import("svelte").Component<Props, {}, "">;
24
- type WeekGrid = ReturnType<typeof WeekGrid>;
25
- export default WeekGrid;
18
+ declare const PlannerWeek: import("svelte").Component<Props, {}, "">;
19
+ type PlannerWeek = ReturnType<typeof PlannerWeek>;
20
+ export default PlannerWeek;
@@ -0,0 +1 @@
1
+ export { default as Planner } from './Planner.svelte';
@@ -0,0 +1 @@
1
+ export { default as Planner } from './Planner.svelte';
@@ -8,7 +8,7 @@
8
8
  <day-calendar
9
9
  api="https://myschool.com/api/events"
10
10
  theme="neutral"
11
- view="week-grid"
11
+ view="week-planner"
12
12
  height="600"
13
13
  locale="en-US"
14
14
  ></day-calendar>
@@ -16,23 +16,23 @@
16
16
  <script lang="ts">
17
17
  import Calendar from '../calendar/Calendar.svelte';
18
18
  import type { CalendarView } from '../calendar/Calendar.svelte';
19
- import { DayGrid } from '../views/day/index.js';
20
- import { WeekGrid } from '../views/week/index.js';
19
+ import { Planner } from '../views/planner/index.js';
21
20
  import { Agenda } from '../views/agenda/index.js';
22
- import { WeekHeatmap } from '../views/week/index.js';
23
- import { DayTimeline } from '../views/day/index.js';
24
21
  import { createRestAdapter } from '../adapters/rest.js';
25
22
  import { createMemoryAdapter } from '../adapters/memory.js';
26
23
  import { presets } from '../theme/presets.js';
27
24
  import type { PresetName } from '../theme/presets.js';
28
25
  import type { TimelineEvent } from '../core/types.js';
26
+ import { getLabels } from '../core/locale.js';
27
+
28
+ const L = $derived(getLabels());
29
29
 
30
30
  interface Props {
31
31
  /** REST API base URL — if provided, fetches events from this endpoint */
32
32
  api?: string;
33
33
  /** JSON string of events for static/inline data (alternative to api) */
34
34
  events?: string;
35
- /** Theme preset name: midnight, parchment, indigo, neutral, bare */
35
+ /** Theme preset name: midnight, neutral */
36
36
  theme?: string;
37
37
  /** Default view ID */
38
38
  view?: string;
@@ -52,7 +52,7 @@
52
52
  api,
53
53
  events,
54
54
  theme = 'neutral',
55
- view = 'week-grid',
55
+ view = 'week-planner',
56
56
  height = '600',
57
57
  locale,
58
58
  dir,
@@ -71,17 +71,47 @@
71
71
  );
72
72
 
73
73
  // ── Parse static events from JSON attribute ──
74
+ function parseHeaders(json?: string): Record<string, string> | undefined {
75
+ if (!json) return undefined;
76
+ try {
77
+ const parsed = JSON.parse(json) as Record<string, unknown>;
78
+ const out: Record<string, string> = {};
79
+ for (const [k, v] of Object.entries(parsed)) {
80
+ out[k] = String(v);
81
+ }
82
+ return out;
83
+ } catch {
84
+ console.warn('[day-calendar] Failed to parse headers JSON:', json);
85
+ return undefined;
86
+ }
87
+ }
88
+
89
+ function toEvent(raw: Record<string, unknown>, fallbackId: string): TimelineEvent | null {
90
+ const start = new Date(String(raw.start ?? ''));
91
+ const end = new Date(String(raw.end ?? ''));
92
+ if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || end <= start) {
93
+ return null;
94
+ }
95
+ return {
96
+ id: String(raw.id ?? fallbackId),
97
+ title: String(raw.title ?? 'Untitled'),
98
+ start,
99
+ end,
100
+ color: raw.color ? String(raw.color) : undefined,
101
+ };
102
+ }
103
+
74
104
  function parseEvents(json?: string): TimelineEvent[] {
75
105
  if (!json) return [];
76
106
  try {
77
107
  const raw = JSON.parse(json) as Array<Record<string, unknown>>;
78
- return raw.map((e) => ({
79
- id: String(e.id ?? crypto.randomUUID()),
80
- title: String(e.title ?? 'Untitled'),
81
- start: new Date(e.start as string),
82
- end: new Date(e.end as string),
83
- color: e.color ? String(e.color) : undefined,
84
- }));
108
+ const parsed = raw
109
+ .map((e, idx) => toEvent(e, `inline-${idx}`))
110
+ .filter((ev): ev is TimelineEvent => ev !== null);
111
+ if (parsed.length !== raw.length) {
112
+ console.warn(`[day-calendar] Ignored ${raw.length - parsed.length} invalid event(s) from events JSON.`);
113
+ }
114
+ return parsed;
85
115
  } catch {
86
116
  console.warn('[day-calendar] Failed to parse events JSON:', json);
87
117
  return [];
@@ -91,22 +121,15 @@
91
121
  // ── Create adapter ──
92
122
  const adapter = $derived.by(() => {
93
123
  if (api) {
94
- const parsedHeaders = headers ? JSON.parse(headers) as Record<string, string> : undefined;
124
+ const parsedHeaders = parseHeaders(headers);
95
125
  return createRestAdapter({
96
126
  baseUrl: api,
97
127
  headers: parsedHeaders,
98
128
  mapEvents: (data: unknown) => {
99
129
  const arr = Array.isArray(data) ? data : (data as Record<string, unknown>).events as unknown[] ?? [];
100
- return arr.map((e: unknown) => {
101
- const ev = e as Record<string, unknown>;
102
- return {
103
- id: String(ev.id ?? ''),
104
- title: String(ev.title ?? 'Untitled'),
105
- start: new Date(ev.start as string),
106
- end: new Date(ev.end as string),
107
- color: ev.color ? String(ev.color) : undefined,
108
- };
109
- });
130
+ return arr
131
+ .map((e: unknown, idx) => toEvent(e as Record<string, unknown>, `api-${idx}`))
132
+ .filter((ev): ev is TimelineEvent => ev !== null);
110
133
  },
111
134
  });
112
135
  }
@@ -114,14 +137,12 @@
114
137
  });
115
138
 
116
139
  // ── Default views ──
117
- const defaultViews: CalendarView[] = [
118
- { id: 'day-grid', label: 'Grid', granularity: 'day', component: DayGrid },
119
- { id: 'week-grid', label: 'Grid', granularity: 'week', component: WeekGrid },
120
- { id: 'day-timeline', label: 'Timeline', granularity: 'day', component: DayTimeline },
121
- { id: 'day-agenda', label: 'Agenda', granularity: 'day', component: Agenda, props: { mode: 'day' } },
122
- { id: 'week-agenda', label: 'Agenda', granularity: 'week', component: Agenda, props: { mode: 'week' } },
123
- { id: 'week-heatmap', label: 'Heatmap', granularity: 'week', component: WeekHeatmap },
124
- ];
140
+ const defaultViews: CalendarView[] = $derived([
141
+ { id: 'day-planner', label: L.planner, granularity: 'day', component: Planner, props: { mode: 'day' } },
142
+ { id: 'week-planner', label: L.planner, granularity: 'week', component: Planner, props: { mode: 'week' } },
143
+ { id: 'day-agenda', label: L.agenda, granularity: 'day', component: Agenda, props: { mode: 'day' } },
144
+ { id: 'week-agenda', label: L.agenda, granularity: 'week', component: Agenda, props: { mode: 'week' } },
145
+ ]);
125
146
  </script>
126
147
 
127
148
  <Calendar
@@ -3,7 +3,7 @@ interface Props {
3
3
  api?: string;
4
4
  /** JSON string of events for static/inline data (alternative to api) */
5
5
  events?: string;
6
- /** Theme preset name: midnight, parchment, indigo, neutral, bare */
6
+ /** Theme preset name: midnight, neutral */
7
7
  theme?: string;
8
8
  /** Default view ID */
9
9
  view?: string;
package/package.json CHANGED
@@ -1,66 +1,71 @@
1
1
  {
2
- "name": "@nomideusz/svelte-calendar",
3
- "version": "0.4.0",
4
- "description": "A themeable, pluggable Svelte 5 calendar with Day and Week views — Grid, Timeline, Agenda, Heatmap.",
5
- "type": "module",
6
- "license": "MIT",
7
- "svelte": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "svelte": "./dist/index.js",
13
- "default": "./dist/index.js"
14
- },
15
- "./widget": "./widget/widget.js"
16
- },
17
- "files": [
18
- "dist",
19
- "widget",
20
- "!dist/**/*.test.*",
21
- "!dist/**/*.spec.*"
22
- ],
23
- "peerDependencies": {
24
- "svelte": "^5.0.0"
25
- },
26
- "devDependencies": {
27
- "@sveltejs/adapter-auto": "^7.0.0",
28
- "@sveltejs/kit": "^2.50.2",
29
- "@sveltejs/package": "^2.5.7",
30
- "@sveltejs/vite-plugin-svelte": "^6.2.4",
31
- "svelte": "^5.51.0",
32
- "svelte-check": "^4.3.6",
33
- "typescript": "^5.9.3",
34
- "vite": "^7.3.1",
35
- "vitest": "^4.0.18"
36
- },
37
- "dependencies": {
38
- "date-fns": "^4.1.0",
39
- "date-fns-tz": "^3.2.0"
40
- },
41
- "keywords": [
42
- "svelte",
43
- "calendar",
44
- "scheduler",
45
- "timeline",
46
- "week",
47
- "day",
48
- "booking",
49
- "svelte5"
50
- ],
51
- "repository": {
52
- "type": "git",
53
- "url": "https://github.com/nomideusz/svelte-calendar"
54
- },
55
- "scripts": {
56
- "dev": "vite dev",
57
- "build": "vite build",
58
- "package": "svelte-kit sync && svelte-package",
59
- "build:widget": "vite build --config vite.config.widget.ts",
60
- "preview": "vite preview",
61
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
62
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
63
- "test": "vitest run",
64
- "test:watch": "vitest"
65
- }
66
- }
2
+ "name": "@nomideusz/svelte-calendar",
3
+ "version": "0.5.2",
4
+ "description": "A themeable Svelte 5 calendar with Day and Week views — Planner and Agenda.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "svelte": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "svelte": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./widget": "./widget/widget.js"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "widget",
20
+ "!dist/**/*.test.*",
21
+ "!dist/**/*.spec.*"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite dev",
25
+ "build": "vite build",
26
+ "package": "svelte-kit sync && svelte-package",
27
+ "build:widget": "vite build --config vite.config.widget.ts",
28
+ "prepublishOnly": "npm run package",
29
+ "preview": "vite preview",
30
+ "prepare": "svelte-kit sync || echo ''",
31
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
32
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest"
35
+ },
36
+ "peerDependencies": {
37
+ "svelte": "^5.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@sveltejs/adapter-auto": "^7.0.0",
41
+ "@sveltejs/kit": "^2.50.2",
42
+ "@sveltejs/package": "^2.5.7",
43
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
44
+ "@types/node": "^22.0.0",
45
+ "@vercel/analytics": "^1.6.1",
46
+ "marked": "^17.0.3",
47
+ "svelte": "^5.51.0",
48
+ "svelte-check": "^4.3.6",
49
+ "typescript": "^5.9.3",
50
+ "vite": "^7.3.1",
51
+ "vitest": "^4.0.18"
52
+ },
53
+ "dependencies": {
54
+ "date-fns": "^4.1.0",
55
+ "date-fns-tz": "^3.2.0"
56
+ },
57
+ "keywords": [
58
+ "svelte",
59
+ "calendar",
60
+ "scheduler",
61
+ "timeline",
62
+ "week",
63
+ "day",
64
+ "booking",
65
+ "svelte5"
66
+ ],
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "https://github.com/nomideusz/svelte-calendar"
70
+ }
71
+ }
@@ -0,0 +1 @@
1
+ .tb.svelte-n03zvd{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--dt-surface, #10141c);border-bottom:1px solid var(--dt-border, rgba(148, 163, 184, .07));border-radius:10px 10px 0 0;flex-wrap:wrap}.tb-nav.svelte-n03zvd{display:flex;align-items:center;gap:4px}.tb-btn.svelte-n03zvd{display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--dt-text-2, rgba(148, 163, 184, .55));cursor:pointer;padding:4px 6px;border-radius:6px;font:500 11px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);transition:background .1s,color .1s}.tb-btn.svelte-n03zvd:hover{background:var(--dt-accent-dim, rgba(239, 68, 68, .18));color:var(--dt-text, rgba(226, 232, 240, .85))}.tb-today.svelte-n03zvd{padding:4px 10px;border:1px solid var(--dt-border, rgba(148, 163, 184, .07))}.tb-label.svelte-n03zvd{font:500 13px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);color:var(--dt-text, rgba(226, 232, 240, .85));letter-spacing:.01em;flex:1;min-width:0}.tb-links.svelte-n03zvd{display:flex;gap:6px}.tb-link.svelte-n03zvd{font:400 12px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);color:var(--dt-text-2, rgba(148, 163, 184, .55));border:1px solid var(--dt-border, rgba(148, 163, 184, .07));padding:4px 8px;border-radius:5px;text-decoration:none;transition:color .1s,border-color .1s}.tb-link.svelte-n03zvd:hover{color:var(--dt-text, rgba(226, 232, 240, .85));border-color:var(--dt-text-2, rgba(148, 163, 184, .25))}.tb-group.svelte-n03zvd{display:flex;gap:2px;background:var(--dt-bg, #0b0e14);border-radius:6px;padding:2px}.tb-seg.svelte-n03zvd{border:none;background:transparent;color:var(--dt-text-2, rgba(148, 163, 184, .55));cursor:pointer;font:600 12px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);padding:5px 12px;border-radius:4px;letter-spacing:.04em;text-transform:uppercase;transition:background .1s,color .1s}.tb-seg.svelte-n03zvd:hover{color:var(--dt-text, rgba(226, 232, 240, .85))}.tb-seg-active.svelte-n03zvd{background:var(--dt-accent, #ef4444);color:var(--dt-btn-text, #fff)}.tb-concepts.svelte-n03zvd{display:flex;gap:3px;background:var(--dt-bg, #0b0e14);border-radius:6px;padding:2px}.tb-pill.svelte-n03zvd{border:none;background:transparent;color:var(--dt-text-2, rgba(148, 163, 184, .55));cursor:pointer;font:400 12px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);padding:4px 9px;border-radius:4px;letter-spacing:.02em;transition:background .1s,color .1s;white-space:nowrap}.tb-pill.svelte-n03zvd:hover{color:var(--dt-text, rgba(226, 232, 240, .85))}.tb-pill-active.svelte-n03zvd{background:var(--dt-surface, #10141c);color:var(--dt-text, rgba(226, 232, 240, .85))}.cal.svelte-1b53e7w{position:relative;height:var(--cal-h, 600px);background:var(--dt-bg, #0b0e14);border-radius:12px;overflow:hidden;display:flex;flex-direction:column;border:1px solid var(--dt-border, rgba(148, 163, 184, .07))}.cal-body.svelte-1b53e7w{flex:1;min-height:0;overflow:hidden}.cal-empty.svelte-1b53e7w{display:flex;align-items:center;justify-content:center;height:100%;font:400 13px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);color:var(--dt-text-3, rgba(100, 116, 139, .55))}.cal-loading.svelte-1b53e7w{position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent 0%,var(--dt-accent, #ef4444) 50%,transparent 100%);animation:svelte-1b53e7w-cal-slide 1.2s ease-in-out infinite}@keyframes svelte-1b53e7w-cal-slide{0%{transform:translate(-100%)}to{transform:translate(100%)}}.fs.svelte-1g84p58{--dt-bg: #0b0e14;--dt-surface: #10141c;--dt-border: rgba(148, 163, 184, .07);--dt-border-day: rgba(148, 163, 184, .14);--dt-text: rgba(226, 232, 240, .92);--dt-text-2: rgba(148, 163, 184, .72);--dt-text-3: rgba(100, 116, 139, .7);--dt-accent: #ef4444;--dt-accent-dim: rgba(239, 68, 68, .18);--dt-glow: rgba(239, 68, 68, .35);--dt-today-bg: rgba(239, 68, 68, .025);--dt-btn-text: #fff;--dt-scrollbar: rgba(148, 163, 184, .12);--dt-night: #06080d;--dt-mono: "SF Mono", "Cascadia Code", "Fira Code", Consolas, monospace;--dt-sans: system-ui, -apple-system, "Segoe UI", sans-serif;position:relative;background:var(--dt-bg);border:1px solid var(--dt-border);border-radius:10px;overflow:hidden;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.fs-scroll.svelte-1g84p58{width:100%;height:100%;overflow-x:auto;overflow-y:hidden;touch-action:pan-x;cursor:grab;scrollbar-width:thin;scrollbar-color:var(--dt-scrollbar) transparent}.fs-scroll.svelte-1g84p58::-webkit-scrollbar{height:5px}.fs-scroll.svelte-1g84p58::-webkit-scrollbar-thumb{background:var(--dt-scrollbar);border-radius:4px}.fs-scroll.svelte-1g84p58::-webkit-scrollbar-track{background:transparent}.fs-grabbing.svelte-1g84p58{cursor:grabbing}.fs-track.svelte-1g84p58{position:relative;height:100%}.fs-day.svelte-1g84p58{position:absolute;top:0;height:100%;border-left:1px solid var(--dt-border-day);box-sizing:border-box;transition:background .2s}.fs-day.svelte-1g84p58:first-of-type{border-left:none}.fs-today.svelte-1g84p58{background:var(--dt-today-bg)}.fs-past.svelte-1g84p58{opacity:.7}.fs-day-hd.svelte-1g84p58{display:flex;align-items:center;gap:8px;padding:10px 14px;height:38px;box-sizing:border-box;border-bottom:1px solid var(--dt-border)}.fs-day-name.svelte-1g84p58{font:600 12px / 1 var(--dt-sans);letter-spacing:.04em;text-transform:uppercase;color:var(--dt-text-2);white-space:nowrap}.fs-today.svelte-1g84p58 .fs-day-name:where(.svelte-1g84p58){color:var(--dt-accent)}.fs-tick.svelte-1g84p58{position:absolute;top:38px;bottom:0;width:0}.fs-tick.svelte-1g84p58:before{content:"";position:absolute;top:18px;bottom:0;width:1px;background:var(--dt-border)}.fs-tick-lb.svelte-1g84p58{position:absolute;top:2px;left:5px;font:500 10px / 1 var(--dt-mono);color:var(--dt-text-3);white-space:nowrap;pointer-events:none}.fs-tick--half.svelte-1g84p58{bottom:auto;height:26px}.fs-tick--half.svelte-1g84p58:before{top:18px;height:6px;bottom:auto;opacity:.4}.fs-tick--night.svelte-1g84p58:before{opacity:.3}.fs-tick--night.svelte-1g84p58 .fs-tick-lb:where(.svelte-1g84p58){opacity:.5}.fs-night.svelte-1g84p58{position:absolute;top:0;height:100%;background:var(--dt-night);cursor:pointer;transition:width .3s ease;overflow:hidden;border-left:1px solid rgba(148,163,184,.04);border-right:1px solid rgba(148,163,184,.04)}.fs-night--open.svelte-1g84p58{cursor:default;background:color-mix(in srgb,var(--dt-night) 90%,var(--dt-bg))}.fs-night-band.svelte-1g84p58{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:4px;writing-mode:vertical-rl;text-orientation:mixed;transform:rotate(180deg)}.fs-night-label.svelte-1g84p58{font:500 10px / 1 var(--dt-sans);letter-spacing:.06em;text-transform:uppercase;color:var(--dt-text-3);white-space:nowrap}.fs-night-chevron.svelte-1g84p58{font:400 9px / 1 var(--dt-sans);letter-spacing:.1em;text-transform:uppercase;color:var(--dt-text-3);opacity:.5}.fs-night-toggle.svelte-1g84p58{position:absolute;top:8px;right:8px;z-index:2;font:500 10px / 1 var(--dt-sans);letter-spacing:.06em;text-transform:uppercase;color:var(--dt-text-3);background:#94a3b80f;border:1px solid rgba(148,163,184,.08);padding:4px 10px;border-radius:4px;cursor:pointer;transition:color .15s}.fs-night-toggle.svelte-1g84p58:hover{color:var(--dt-text-2)}.fs-now.svelte-1g84p58{position:absolute;top:0;bottom:0;z-index:10;pointer-events:none;transform:translate(-1px)}.fs-now-line.svelte-1g84p58{position:absolute;top:0;bottom:0;left:0;width:2px;background:var(--dt-accent);box-shadow:0 0 8px var(--dt-glow)}.fs-now-tag.svelte-1g84p58{position:absolute;top:8px;left:8px;font:700 11px / 1 var(--dt-mono);color:var(--dt-accent);background:color-mix(in srgb,var(--dt-bg) 92%,var(--dt-accent));border:1px solid var(--dt-accent-dim);padding:3px 6px;border-radius:4px;white-space:nowrap;z-index:1}.fs-now-sec.svelte-1g84p58{font-weight:400;opacity:.5;font-size:10px}.fs-btn.svelte-1g84p58{position:absolute;bottom:14px;right:14px;z-index:20;display:inline-flex;align-items:center;gap:5px;padding:5px 13px 5px 9px;font:600 11px / 1 var(--dt-sans);color:var(--dt-btn-text);background:var(--dt-accent);border:none;border-radius:100px;cursor:pointer;box-shadow:0 2px 16px var(--dt-glow);transition:transform .12s ease,box-shadow .12s ease}.fs-btn.svelte-1g84p58 svg:where(.svelte-1g84p58){width:13px;height:13px}.fs-btn.svelte-1g84p58:hover{transform:scale(1.06);box-shadow:0 4px 24px var(--dt-glow)}.fs-btn.svelte-1g84p58:active{transform:scale(.96)}.fs-event.svelte-1g84p58{position:absolute;z-index:6;border-radius:6px;cursor:pointer;background:color-mix(in srgb,var(--ev-color) 15%,transparent);border-top:3px solid var(--ev-color);overflow:hidden;display:flex;align-items:center;justify-content:center;transition:box-shadow .12s,background .12s}.fs-event.svelte-1g84p58:hover{background:color-mix(in srgb,var(--ev-color) 28%,transparent);box-shadow:0 2px 12px color-mix(in srgb,var(--ev-color) 25%,transparent)}.fs-event--selected.svelte-1g84p58{box-shadow:0 0 0 2px var(--ev-color),0 2px 14px color-mix(in srgb,var(--ev-color) 35%,transparent)}.fs-event--current.svelte-1g84p58{background:color-mix(in srgb,var(--ev-color) 22%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ev-color) 20%,transparent)}.fs-event--dragging.svelte-1g84p58{opacity:.85;z-index:50;box-shadow:0 4px 24px #00000059;cursor:grabbing;transition:none}.fs-ev-inner.svelte-1g84p58{writing-mode:vertical-rl;transform:rotate(180deg);display:flex;align-items:center;gap:6px;max-height:100%;overflow:hidden;padding:8px 4px}.fs-ev-live.svelte-1g84p58{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:var(--ev-color)}.fs-ev-title.svelte-1g84p58{font:600 13px / 1.15 var(--dt-sans);color:var(--dt-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fs-ev-time.svelte-1g84p58{font:400 10px / 1 var(--dt-mono);color:var(--dt-text-2);opacity:.7;white-space:nowrap}.fs-ev-sub.svelte-1g84p58{font:400 11px / 1 var(--dt-sans);color:var(--dt-text-2);opacity:.6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fs-ev-tags.svelte-1g84p58{display:flex;gap:4px}.fs-ev-tag.svelte-1g84p58{font:500 8px / 1 var(--dt-sans);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 18%,transparent);padding:1px 4px;border-radius:3px;white-space:nowrap}.fs-event.svelte-1g84p58:focus-visible,.fs-night.svelte-1g84p58:focus-visible{outline:2px solid var(--dt-accent);outline-offset:2px}.fs-night.svelte-1g84p58:hover{background:color-mix(in srgb,var(--dt-night) 85%,var(--dt-text-3))}.dt.svelte-p4fcuu{--dt-bg: #0b0e14;--dt-surface: #10141c;--dt-border: rgba(148, 163, 184, .07);--dt-border-day: rgba(148, 163, 184, .14);--dt-text: rgba(226, 232, 240, .85);--dt-text-2: rgba(148, 163, 184, .55);--dt-text-3: rgba(100, 116, 139, .55);--dt-accent: #ef4444;--dt-accent-dim: rgba(239, 68, 68, .18);--dt-glow: rgba(239, 68, 68, .35);--dt-today-bg: rgba(239, 68, 68, .02);--dt-btn-text: #fff;--dt-scrollbar: rgba(148, 163, 184, .12);--dt-header: 34px;--dt-ruler: 16px;--dt-mono: "SF Mono", "Cascadia Code", "Fira Code", Consolas, monospace;--dt-sans: system-ui, -apple-system, "Segoe UI", sans-serif;position:relative;height:160px;background:var(--dt-bg);border:1px solid var(--dt-border);border-radius:10px;overflow:hidden;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.dt-scroll.svelte-p4fcuu{width:100%;height:100%;overflow-x:auto;overflow-y:hidden;touch-action:pan-x;cursor:grab;scrollbar-width:thin;scrollbar-color:var(--dt-scrollbar) transparent}.dt-scroll.svelte-p4fcuu::-webkit-scrollbar{height:5px}.dt-scroll.svelte-p4fcuu::-webkit-scrollbar-thumb{background:var(--dt-scrollbar);border-radius:4px}.dt-scroll.svelte-p4fcuu::-webkit-scrollbar-track{background:transparent}.dt-grabbing.svelte-p4fcuu{cursor:grabbing}.dt-track.svelte-p4fcuu{position:relative;height:100%}.dt-day.svelte-p4fcuu{position:absolute;top:0;height:100%;border-left:1px solid var(--dt-border-day);box-sizing:border-box}.dt-day.svelte-p4fcuu:first-of-type{border-left:none}.dt-today.svelte-p4fcuu{background:var(--dt-today-bg)}.dt-day-hd.svelte-p4fcuu{display:flex;align-items:baseline;gap:8px;padding:9px 14px;height:var(--dt-header);box-sizing:border-box;border-bottom:1px solid var(--dt-border)}.dt-day-nm.svelte-p4fcuu{font:600 11px / 1 var(--dt-sans);letter-spacing:.04em;text-transform:uppercase;color:var(--dt-text-2);white-space:nowrap}.dt-today.svelte-p4fcuu .dt-day-nm:where(.svelte-p4fcuu){color:var(--dt-accent)}.dt-tick.svelte-p4fcuu{position:absolute;top:var(--dt-header);bottom:0;width:0}.dt-tick.svelte-p4fcuu:before{content:"";position:absolute;top:var(--dt-ruler);bottom:0;width:1px;background:var(--dt-border)}.dt-tick-lb.svelte-p4fcuu{position:absolute;top:1px;left:5px;font:500 9px / 1 var(--dt-mono);color:var(--dt-text-3);white-space:nowrap;pointer-events:none}.dt-tick--h.svelte-p4fcuu{bottom:auto;height:calc(var(--dt-ruler) + 8px)}.dt-tick--h.svelte-p4fcuu:before{top:var(--dt-ruler);height:6px;bottom:auto;opacity:.45}.dt-now.svelte-p4fcuu{position:absolute;top:0;bottom:0;z-index:10;pointer-events:none;transform:translate(-1px)}.dt-now-line.svelte-p4fcuu{position:absolute;top:0;bottom:0;left:0;width:2px;background:var(--dt-accent);box-shadow:0 0 10px var(--dt-glow),0 0 24px var(--dt-accent-dim);animation:svelte-p4fcuu-now-pulse 3s ease-in-out infinite}@keyframes svelte-p4fcuu-now-pulse{0%,to{box-shadow:0 0 10px var(--dt-glow),0 0 24px var(--dt-accent-dim)}50%{box-shadow:0 0 16px var(--dt-glow),0 0 36px var(--dt-glow)}}.dt-now-tag.svelte-p4fcuu{position:absolute;top:7px;left:8px;font:700 10px / 1 var(--dt-mono);color:var(--dt-accent);background:var(--dt-bg);border:1px solid var(--dt-accent-dim);padding:3px 6px;border-radius:4px;white-space:nowrap;z-index:1}.dt-now-sec.svelte-p4fcuu{font-weight:400;opacity:.5;font-size:9px}.dt-fog.svelte-p4fcuu{position:absolute;top:0;bottom:0;width:48px;pointer-events:none;z-index:5}.dt-fog--l.svelte-p4fcuu{left:0;background:linear-gradient(to right,var(--dt-bg),transparent)}.dt-fog--r.svelte-p4fcuu{right:0;background:linear-gradient(to left,var(--dt-bg),transparent)}.dt-btn.svelte-p4fcuu{position:absolute;bottom:14px;right:14px;z-index:20;display:inline-flex;align-items:center;gap:5px;padding:5px 13px 5px 9px;font:600 11px / 1 var(--dt-sans);color:var(--dt-btn-text);background:var(--dt-accent);border:none;border-radius:100px;cursor:pointer;box-shadow:0 2px 16px var(--dt-glow);transition:transform .12s ease,box-shadow .12s ease}.dt-btn.svelte-p4fcuu svg:where(.svelte-p4fcuu){width:13px;height:13px}.dt-btn.svelte-p4fcuu:hover{transform:scale(1.06);box-shadow:0 4px 24px var(--dt-glow)}.dt-btn.svelte-p4fcuu:active{transform:scale(.96)}.dt-event.svelte-p4fcuu{position:absolute;height:28px;z-index:6;border-radius:5px;padding:0 8px;display:flex;align-items:center;gap:4px;cursor:pointer;background:color-mix(in srgb,var(--ev-color) 22%,transparent);border-left:3px solid var(--ev-color);transition:box-shadow .12s,transform 80ms}.dt-event.svelte-p4fcuu:hover{box-shadow:0 2px 10px color-mix(in srgb,var(--ev-color) 30%,transparent);transform:translateY(-1px)}.dt-event--selected.svelte-p4fcuu{box-shadow:0 0 0 2px var(--ev-color),0 2px 12px color-mix(in srgb,var(--ev-color) 40%,transparent)}.dt-event--dragging.svelte-p4fcuu{opacity:.85;z-index:50;box-shadow:0 4px 24px #00000059;cursor:grabbing;transition:none}.dt-ev-title.svelte-p4fcuu{font:600 10px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);color:var(--dt-text, #e2e8f0);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dt-ev-sub.svelte-p4fcuu{font:400 9px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);color:var(--dt-text-2, rgba(148, 163, 184, .6));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dt-ev-tag.svelte-p4fcuu{font:500 7px / 1 var(--dt-sans, "Outfit", system-ui, sans-serif);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 20%,transparent);padding:1px 3px;border-radius:2px;white-space:nowrap;flex-shrink:0}.wg.svelte-j4rvbp{position:relative;background:var(--dt-bg, #fff);border:1px solid var(--dt-border, rgba(0, 0, 0, .08));border-radius:10px;overflow:hidden;display:flex;flex-direction:column;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.wg-body.svelte-j4rvbp{flex:1;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:var(--dt-scrollbar, rgba(0, 0, 0, .08)) transparent}.wg-body.svelte-j4rvbp::-webkit-scrollbar{width:4px}.wg-body.svelte-j4rvbp::-webkit-scrollbar-thumb{background:var(--dt-scrollbar, rgba(0, 0, 0, .1));border-radius:4px}.wg-body.svelte-j4rvbp::-webkit-scrollbar-track{background:transparent}.wg-week.svelte-j4rvbp{display:flex;border-bottom:1px solid var(--dt-border, rgba(0, 0, 0, .08))}.wg-week--current.svelte-j4rvbp{background:var(--dt-today-bg, rgba(239, 68, 68, .02))}.wg-gutter.svelte-j4rvbp{flex-shrink:0;width:48px;display:flex;align-items:center;justify-content:center;border-right:1px solid var(--dt-border, rgba(0, 0, 0, .08))}.wg-gutter-month.svelte-j4rvbp{font:800 11px / 1 var(--dt-sans, system-ui, sans-serif);letter-spacing:.06em;color:var(--dt-text-2, rgba(0, 0, 0, .45));writing-mode:vertical-rl;transform:rotate(180deg)}.wg-week-body.svelte-j4rvbp{flex:1;min-width:0;display:flex;flex-direction:column}.wg-days.svelte-j4rvbp{display:flex;flex:1}.wg-cell.svelte-j4rvbp{flex:1;position:relative;min-height:130px;padding:0 4px 8px;border-right:1px solid var(--dt-border, rgba(0, 0, 0, .06));cursor:pointer;transition:background .15s}.wg-cell.svelte-j4rvbp:last-child{border-right:none}.wg-cell.svelte-j4rvbp:hover{background:var(--dt-hover, rgba(0, 0, 0, .015))}.wg-cell--today.svelte-j4rvbp{background:var(--dt-today-bg, rgba(239, 68, 68, .03))}.wg-cell--today.svelte-j4rvbp:hover{background:#ef44440d}.wg-cell--past.svelte-j4rvbp{opacity:.55}.wg-cell--past.svelte-j4rvbp:hover{opacity:.75}.wg-cell--weekend.svelte-j4rvbp{background:var(--dt-weekend-bg, rgba(0, 0, 0, .012))}.wg-cell-hd.svelte-j4rvbp{display:flex;align-items:center;justify-content:center;gap:5px;padding:6px 0;border-bottom:1px solid var(--dt-border, rgba(0, 0, 0, .04));margin-bottom:4px}.wg-day-wd.svelte-j4rvbp{font:400 11px / 1 var(--dt-sans, system-ui, sans-serif);letter-spacing:.04em;text-transform:uppercase;color:var(--dt-text-3, rgba(0, 0, 0, .35))}.wg-cell-hd--today.svelte-j4rvbp .wg-day-wd:where(.svelte-j4rvbp){color:var(--dt-accent, #ef4444);font-weight:600}.wg-day-num.svelte-j4rvbp{font:700 14px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--dt-text, rgba(0, 0, 0, .85))}.wg-day-num--today.svelte-j4rvbp{background:var(--dt-accent, #ef4444);color:#fff;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;font-size:13px}.wg-cell-events.svelte-j4rvbp{display:flex;flex-direction:column;gap:3px}.wg-ev.svelte-j4rvbp{display:flex;align-items:center;flex-wrap:wrap;gap:3px 5px;padding:3px 6px;border-radius:4px;background:color-mix(in srgb,var(--ev-color) 12%,transparent);cursor:pointer;overflow:hidden;transition:background .12s}.wg-ev.svelte-j4rvbp:hover{background:color-mix(in srgb,var(--ev-color) 22%,transparent)}.wg-ev--selected.svelte-j4rvbp{box-shadow:0 0 0 1.5px var(--ev-color)}.wg-ev--current.svelte-j4rvbp{background:color-mix(in srgb,var(--ev-color) 18%,transparent)}.wg-ev-time.svelte-j4rvbp{font:400 10px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--dt-text-3, rgba(0, 0, 0, .4));flex-shrink:0;white-space:nowrap}.wg-ev-title.svelte-j4rvbp{font:500 12px / 1.1 var(--dt-sans, system-ui, sans-serif);color:var(--dt-text, rgba(0, 0, 0, .85));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wg-ev-sub.svelte-j4rvbp{font:400 10px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--dt-text-3, rgba(0, 0, 0, .4));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wg-ev-tags.svelte-j4rvbp{display:flex;gap:3px;flex-shrink:0}.wg-ev-tag.svelte-j4rvbp{font:500 8px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 15%,transparent);padding:1px 4px;border-radius:3px;white-space:nowrap}.wg-ev-more.svelte-j4rvbp{font:500 10px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--dt-text-3, rgba(0, 0, 0, .35));padding:2px 8px;cursor:pointer}.wg-ev-more.svelte-j4rvbp:hover{color:var(--dt-text-2, rgba(0, 0, 0, .55))}.wg-now.svelte-j4rvbp{position:absolute;left:0;right:0;z-index:4;pointer-events:none;display:flex;align-items:center;gap:0}.wg-now-time.svelte-j4rvbp{flex-shrink:0;font:500 9px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--dt-accent, #ef4444);padding:1px 4px;background:color-mix(in srgb,var(--dt-accent, #ef4444) 12%,var(--dt-bg, #fff));border-radius:3px;margin-left:-2px}.wg-now-line.svelte-j4rvbp{flex:1;height:1px;background:var(--dt-accent, #ef4444);opacity:.35}.wg-btn.svelte-j4rvbp{position:absolute;bottom:14px;right:14px;z-index:20;display:inline-flex;align-items:center;gap:5px;padding:5px 13px 5px 9px;font:600 11px / 1 var(--dt-sans, system-ui, sans-serif);color:#fff;background:var(--dt-accent, #ef4444);border:none;border-radius:100px;cursor:pointer;box-shadow:0 2px 16px color-mix(in srgb,var(--dt-accent, #ef4444) 35%,transparent);transition:transform .12s ease,box-shadow .12s ease}.wg-btn.svelte-j4rvbp svg:where(.svelte-j4rvbp){width:13px;height:13px}.wg-btn.svelte-j4rvbp:hover{transform:scale(1.06)}.wg-btn.svelte-j4rvbp:active{transform:scale(.96)}.wg-cell.svelte-j4rvbp:focus-visible{outline:2px solid var(--dt-accent, #ef4444);outline-offset:-2px}.wg-ev.svelte-j4rvbp:focus-visible{outline:2px solid var(--ev-color, var(--dt-accent, #ef4444));outline-offset:1px}.wg-ev--dragging.svelte-j4rvbp{opacity:.6;cursor:grabbing;box-shadow:0 2px 8px #0003}.ag.svelte-gg2mx3{position:relative;background:var(--dt-bg, #111);border:1px solid var(--dt-border, rgba(255, 255, 255, .06));border-radius:10px;overflow:hidden;-webkit-user-select:none;user-select:none;display:flex;flex-direction:column;color:var(--dt-text, rgba(255, 255, 255, .92));font-family:var(--dt-sans, system-ui, sans-serif)}.ag-header.svelte-gg2mx3{display:flex;justify-content:space-between;align-items:center;padding:14px 20px 10px;border-bottom:1px solid var(--dt-border, rgba(255, 255, 255, .06));flex-shrink:0}.ag-header-left.svelte-gg2mx3{display:flex;align-items:baseline;gap:10px}.ag-title.svelte-gg2mx3{font-size:14px;font-weight:600;line-height:1}.ag-subtitle.svelte-gg2mx3{font-size:12px;font-family:var(--dt-mono, monospace);color:var(--dt-text-2, rgba(255, 255, 255, .5))}.ag-clock.svelte-gg2mx3{font-size:13px;font-weight:600;font-family:var(--dt-mono, monospace);color:var(--dt-accent, #ff6b4a)}.ag-header-right.svelte-gg2mx3{display:flex;align-items:center;gap:8px}.ag-stat.svelte-gg2mx3{font-size:11px;color:var(--dt-text-3, rgba(255, 255, 255, .3));font-family:var(--dt-mono, monospace)}.ag-stat-sep.svelte-gg2mx3{font-size:11px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-progress-track.svelte-gg2mx3{width:52px;height:3px;background:var(--dt-border, rgba(255, 255, 255, .06));border-radius:2px;overflow:hidden}.ag-progress-fill.svelte-gg2mx3{height:100%;background:var(--dt-accent, #ff6b4a);border-radius:2px;opacity:.5;transition:width 1s linear}.ag-body.svelte-gg2mx3{flex:1;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--dt-border) transparent}.ag-body.svelte-gg2mx3::-webkit-scrollbar{width:4px}.ag-body.svelte-gg2mx3::-webkit-scrollbar-thumb{background:var(--dt-border);border-radius:2px}.ag-card.svelte-gg2mx3{display:flex;align-items:stretch;border-radius:8px;background:var(--dt-surface, #191919);border:1px solid var(--dt-border, rgba(255, 255, 255, .06));overflow:hidden;cursor:pointer;transition:border-color .15s}.ag-card.svelte-gg2mx3:hover{border-color:color-mix(in srgb,var(--ev-color) 40%,transparent)}.ag-card.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px}.ag-card--selected.svelte-gg2mx3{border-color:var(--ev-color);background:color-mix(in srgb,var(--ev-color) 6%,var(--dt-surface, #191919))}.ag-card-stripe.svelte-gg2mx3{width:3px;background:var(--ev-color, var(--dt-accent));flex-shrink:0}.ag-card-body.svelte-gg2mx3{padding:10px 12px;display:flex;flex-direction:column;gap:4px;min-width:0;flex:1}.ag-card-title.svelte-gg2mx3{font-size:13px;font-weight:600;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ag-card-meta.svelte-gg2mx3{font-size:11px;color:var(--dt-text-2, rgba(255, 255, 255, .5));font-family:var(--dt-mono, monospace);line-height:1}.ag-card-dur.svelte-gg2mx3{margin-left:6px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-card-sub.svelte-gg2mx3{font-size:11px;color:var(--dt-text-2, rgba(255, 255, 255, .45));line-height:1}.ag-card-tags.svelte-gg2mx3{display:flex;gap:4px;flex-wrap:wrap}.ag-card-tag.svelte-gg2mx3{font:500 9px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 15%,transparent);padding:2px 5px;border-radius:3px;white-space:nowrap}.ag-card-progress.svelte-gg2mx3{height:3px;background:var(--dt-border, rgba(255, 255, 255, .06));border-radius:2px;overflow:hidden;margin-top:2px}.ag-card-progress-fill.svelte-gg2mx3{height:100%;background:var(--ev-color, var(--dt-accent));border-radius:2px;transition:width 1s linear}.ag-empty{display:flex;align-items:center;justify-content:center;padding:40px 20px;font-size:13px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-q.svelte-gg2mx3{display:grid;grid-template-columns:.65fr 1.8fr .55fr;gap:0;flex:1;padding:8px 0 10px;min-height:0}.ag-q-label.svelte-gg2mx3{font-size:8px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--dt-text-3, rgba(255, 255, 255, .25));margin-bottom:8px;padding:0 12px;font-family:var(--dt-sans, system-ui, sans-serif)}.ag-q-empty.svelte-gg2mx3{display:flex;align-items:center;justify-content:center;flex:1;font-size:13px;font-weight:300;color:var(--dt-text-3, rgba(255, 255, 255, .25))}.ag-q-status.svelte-gg2mx3{padding:0 0 0 14px;border-right:1px solid var(--dt-border, rgba(255, 255, 255, .06));display:flex;flex-direction:column}.ag-q-now.svelte-gg2mx3{padding:8px 10px;border-radius:8px;background:var(--dt-surface, #191919);border:1px solid color-mix(in srgb,var(--ev-color, var(--dt-accent)) 15%,transparent);cursor:pointer;transition:border-color .15s;margin-right:10px}.ag-q-now.svelte-gg2mx3:hover{border-color:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 35%,transparent)}.ag-q-now.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px}.ag-q-now--selected.svelte-gg2mx3{border-color:var(--ev-color, var(--dt-accent))}.ag-q-now-dot.svelte-gg2mx3{width:6px;height:6px;border-radius:50%;background:var(--ev-color, var(--dt-accent, #ff6b4a));margin-bottom:6px;animation:svelte-gg2mx3-ag-pulse 2.5s ease-in-out infinite}@keyframes svelte-gg2mx3-ag-pulse{0%,to{opacity:1}50%{opacity:.4}}.ag-q-now-title.svelte-gg2mx3{font-size:11px;font-weight:600;line-height:1.2;color:var(--dt-text, rgba(255, 255, 255, .92));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:3px}.ag-q-now-time.svelte-gg2mx3{font-size:9px;font-family:var(--dt-mono, monospace);color:var(--dt-text-3, rgba(255, 255, 255, .35));margin-bottom:6px}.ag-q-now-track.svelte-gg2mx3{height:2px;background:var(--dt-border, rgba(255, 255, 255, .06));border-radius:1px;overflow:hidden}.ag-q-now-fill.svelte-gg2mx3{height:100%;background:var(--ev-color, var(--dt-accent, #ff6b4a));border-radius:1px;transition:width 1s linear}.ag-q-free.svelte-gg2mx3{padding:8px 10px;margin-right:10px}.ag-q-free-label.svelte-gg2mx3{font-size:12px;font-weight:300;color:var(--dt-text-3, rgba(255, 255, 255, .25));margin-bottom:2px}.ag-q-free-next{font-size:10px;font-weight:500;line-height:1.2;color:var(--dt-text-2, rgba(255, 255, 255, .5));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:2px}.ag-q-free-until{font-size:9px;font-family:var(--dt-mono, monospace);color:var(--dt-accent, #ff6b4a);opacity:.6}.ag-q-queue.svelte-gg2mx3{padding:0 16px;overflow-y:auto;scrollbar-width:none;display:flex;flex-direction:column}.ag-q-queue.svelte-gg2mx3::-webkit-scrollbar{display:none}.ag-q-card.svelte-gg2mx3{display:flex;align-items:stretch;border-radius:10px;background:var(--dt-surface, #191919);border:1px solid var(--dt-border, rgba(255, 255, 255, .06));overflow:hidden;cursor:pointer;margin-bottom:6px;transition:border-color .15s,transform .1s}.ag-q-card.svelte-gg2mx3:hover{border-color:color-mix(in srgb,var(--ev-color) 40%,transparent)}.ag-q-card.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px}.ag-q-card--selected.svelte-gg2mx3{border-color:var(--ev-color);background:color-mix(in srgb,var(--ev-color) 6%,var(--dt-surface, #191919))}.ag-q-card--hero.svelte-gg2mx3{background:color-mix(in srgb,var(--ev-color) 8%,var(--dt-surface, #191919));border-color:color-mix(in srgb,var(--ev-color) 25%,transparent)}.ag-q-card--hero.svelte-gg2mx3 .ag-q-card-title:where(.svelte-gg2mx3){font-size:16px;font-weight:700}.ag-q-card--hero.svelte-gg2mx3 .ag-q-card-eta:where(.svelte-gg2mx3){font-size:11px;background:color-mix(in srgb,var(--dt-accent, #ff6b4a) 18%,transparent);padding:2px 7px;border-radius:4px}.ag-q-card--hero.svelte-gg2mx3 .ag-q-card-body:where(.svelte-gg2mx3){padding:14px 16px}.ag-q-card-stripe.svelte-gg2mx3{width:3.5px;background:var(--ev-color, var(--dt-accent));flex-shrink:0}.ag-q-card-body.svelte-gg2mx3{padding:10px 12px;display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.ag-q-card-top.svelte-gg2mx3{display:flex;justify-content:space-between;align-items:flex-start;gap:8px}.ag-q-card-title.svelte-gg2mx3{font-size:13px;font-weight:600;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.ag-q-card-eta.svelte-gg2mx3{font-size:9px;font-weight:600;letter-spacing:.04em;color:var(--dt-accent, #ff6b4a);flex-shrink:0;white-space:nowrap}.ag-q-card-meta.svelte-gg2mx3{font-size:11px;color:var(--dt-text-2, rgba(255, 255, 255, .5));font-family:var(--dt-mono, monospace);line-height:1}.ag-q-card-dur.svelte-gg2mx3{margin-left:6px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-q-card-sub.svelte-gg2mx3{font-size:11px;color:var(--dt-text-2, rgba(255, 255, 255, .45));line-height:1}.ag-q-card-tags.svelte-gg2mx3{display:flex;gap:4px;flex-wrap:wrap;margin-top:2px}.ag-q-card-tag.svelte-gg2mx3{font:500 9px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 15%,transparent);padding:2px 5px;border-radius:3px;white-space:nowrap}.ag-q-done.svelte-gg2mx3{border-left:1px solid var(--dt-border, rgba(255, 255, 255, .06));overflow-y:auto;scrollbar-width:none;padding:0 14px 0 10px}.ag-q-done.svelte-gg2mx3::-webkit-scrollbar{display:none}.ag-q-done-item.svelte-gg2mx3{display:flex;align-items:center;gap:5px;padding:3px 0;opacity:.35;cursor:pointer}.ag-q-done-item.svelte-gg2mx3:hover{opacity:.6}.ag-q-done-item.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px;opacity:.6}.ag-q-done-item--selected.svelte-gg2mx3{opacity:.7}.ag-q-done-check.svelte-gg2mx3{font-size:9px;color:var(--dt-success, rgba(120, 200, 140, .7));flex-shrink:0}.ag-q-done-title.svelte-gg2mx3{font-size:10px;line-height:1.2;color:var(--dt-text-3, rgba(255, 255, 255, .35));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:line-through;text-decoration-color:var(--dt-text-3, rgba(255, 255, 255, .15))}.ag-log.svelte-gg2mx3{flex:1;padding:8px 20px 12px;overflow-y:auto;scrollbar-width:none;opacity:.7}.ag-log.svelte-gg2mx3::-webkit-scrollbar{display:none}.ag-log-row.svelte-gg2mx3{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--dt-border, rgba(255, 255, 255, .04));cursor:pointer;transition:opacity .15s}.ag-log-row.svelte-gg2mx3:last-child{border-bottom:none}.ag-log-row.svelte-gg2mx3:hover{opacity:1}.ag-log-row.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px}.ag-log-row--selected.svelte-gg2mx3{opacity:1;background:color-mix(in srgb,var(--ev-color) 6%,transparent);border-radius:6px;padding-left:8px;padding-right:8px}.ag-log-check.svelte-gg2mx3{font-size:10px;color:var(--dt-success, rgba(120, 200, 140, .5));flex-shrink:0}.ag-log-time.svelte-gg2mx3{font-size:11px;font-family:var(--dt-mono, monospace);color:var(--dt-text-3, rgba(255, 255, 255, .3));width:64px;flex-shrink:0}.ag-log-dot.svelte-gg2mx3{width:5px;height:5px;border-radius:50%;flex-shrink:0;opacity:.6}.ag-log-title.svelte-gg2mx3{font-size:13px;font-weight:500;line-height:1.2;color:var(--dt-text-2, rgba(255, 255, 255, .55));flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:line-through;text-decoration-color:var(--dt-border, rgba(255, 255, 255, .08))}.ag-log-dur.svelte-gg2mx3{font-size:10px;font-family:var(--dt-mono, monospace);color:var(--dt-text-3, rgba(255, 255, 255, .2));flex-shrink:0}.ag-plan.svelte-gg2mx3{flex:1;padding:8px 20px 12px;overflow-y:auto;scrollbar-width:none;display:flex;flex-direction:column;gap:6px}.ag-plan.svelte-gg2mx3::-webkit-scrollbar{display:none}.ag-plan-card.svelte-gg2mx3{display:flex;align-items:stretch;border-radius:10px;background:var(--dt-surface, #191919);border:1px solid var(--dt-border, rgba(255, 255, 255, .06));overflow:hidden;cursor:pointer;transition:border-color .15s}.ag-plan-card.svelte-gg2mx3:hover{border-color:color-mix(in srgb,var(--ev-color) 35%,transparent)}.ag-plan-card.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px}.ag-plan-card--selected.svelte-gg2mx3{border-color:var(--ev-color);background:color-mix(in srgb,var(--ev-color) 6%,var(--dt-surface, #191919))}.ag-plan-card--first.svelte-gg2mx3{background:color-mix(in srgb,var(--ev-color) 5%,var(--dt-surface, #191919));border-color:color-mix(in srgb,var(--ev-color) 15%,transparent)}.ag-plan-stripe.svelte-gg2mx3{width:3.5px;background:var(--ev-color, var(--dt-accent));flex-shrink:0}.ag-plan-body.svelte-gg2mx3{padding:12px 14px;display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.ag-plan-top.svelte-gg2mx3{display:flex;align-items:baseline;gap:8px}.ag-plan-order.svelte-gg2mx3{font-size:10px;font-weight:700;color:var(--dt-text-3, rgba(255, 255, 255, .2));font-family:var(--dt-mono, monospace);flex-shrink:0}.ag-plan-title.svelte-gg2mx3{font-size:14px;font-weight:600;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ag-plan-card--first.svelte-gg2mx3 .ag-plan-title:where(.svelte-gg2mx3){font-size:16px;font-weight:700}.ag-plan-meta.svelte-gg2mx3{font-size:11px;color:var(--dt-text-2, rgba(255, 255, 255, .5));font-family:var(--dt-mono, monospace);line-height:1}.ag-plan-dur.svelte-gg2mx3{margin-left:6px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-plan-sub.svelte-gg2mx3{font-size:11px;color:var(--dt-text-2, rgba(255, 255, 255, .45));line-height:1;padding-left:22px}.ag-plan-tags.svelte-gg2mx3{display:flex;gap:4px;flex-wrap:wrap;padding-left:22px;margin-top:2px}.ag-plan-tag.svelte-gg2mx3{font:500 9px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 15%,transparent);padding:2px 5px;border-radius:3px;white-space:nowrap}.ag-badge.svelte-gg2mx3{font-size:9px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;padding:2px 6px;border-radius:3px}.ag-badge--past.svelte-gg2mx3{color:var(--dt-text-3, rgba(255, 255, 255, .3));background:var(--dt-border, rgba(255, 255, 255, .06))}.ag-badge--future.svelte-gg2mx3{color:var(--dt-accent, #ff6b4a);background:color-mix(in srgb,var(--dt-accent, #ff6b4a) 12%,transparent)}.ag-wday.svelte-gg2mx3{border-bottom:1px solid var(--dt-border, rgba(255, 255, 255, .06))}.ag-wday--today.svelte-gg2mx3{background:color-mix(in srgb,var(--dt-accent, #ff6b4a) 4%,transparent)}.ag-wday--past.svelte-gg2mx3{opacity:.4}.ag-wday-head.svelte-gg2mx3{display:flex;justify-content:space-between;align-items:center;padding:10px 20px}.ag-wday-head-left.svelte-gg2mx3{display:flex;align-items:center;gap:8px}.ag-wday-badge.svelte-gg2mx3{font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--dt-accent, #ff6b4a);background:color-mix(in srgb,var(--dt-accent, #ff6b4a) 12%,transparent);padding:2px 7px;border-radius:3px}.ag-wday-badge--muted.svelte-gg2mx3{color:var(--dt-text-2, rgba(255, 255, 255, .5));background:color-mix(in srgb,var(--dt-text-2, rgba(255, 255, 255, .5)) 10%,transparent)}.ag-wday-name.svelte-gg2mx3{font-size:13px;font-weight:600}.ag-wday-date.svelte-gg2mx3{font-size:11px;font-family:var(--dt-mono, monospace);color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-wday-count.svelte-gg2mx3{font-size:11px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-wday-empty.svelte-gg2mx3{padding:4px 20px 10px;font-size:12px;color:var(--dt-text-3, rgba(255, 255, 255, .3))}.ag-wday-expanded.svelte-gg2mx3{padding:0 20px 12px}.ag-wslot.svelte-gg2mx3{margin-bottom:6px}.ag-wslot-header.svelte-gg2mx3{display:flex;align-items:baseline;gap:8px;padding:4px 0}.ag-wslot-time.svelte-gg2mx3{font-size:12px;font-weight:600;font-family:var(--dt-mono, monospace)}.ag-wslot-now.svelte-gg2mx3{font-size:9px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--dt-accent, #ff6b4a)}.ag-wslot-eta.svelte-gg2mx3{font-size:11px;font-weight:500;color:var(--dt-accent, #ff6b4a)}.ag-wslot-cards.svelte-gg2mx3{display:flex;flex-direction:column;gap:4px}.ag-wslot-cards--multi.svelte-gg2mx3{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:4px}.ag-wday-past-line.svelte-gg2mx3{font-size:10px;color:var(--dt-text-3, rgba(255, 255, 255, .3));padding:6px 0 0;opacity:.5}.ag-wday-compact.svelte-gg2mx3{padding:0 20px 10px}.ag-compact.svelte-gg2mx3{display:flex;align-items:center;gap:8px;padding:4px 0;cursor:pointer}.ag-compact.svelte-gg2mx3:hover .ag-compact-title:where(.svelte-gg2mx3){color:var(--dt-text)}.ag-compact.svelte-gg2mx3:focus-visible{outline:2px solid var(--dt-accent, #ff6b4a);outline-offset:2px}.ag-compact--past.svelte-gg2mx3{opacity:.4}.ag-compact--past.svelte-gg2mx3 .ag-compact-title:where(.svelte-gg2mx3){text-decoration:line-through;text-decoration-color:var(--dt-text-3)}.ag-compact-dot.svelte-gg2mx3{width:5px;height:5px;border-radius:50%;background:var(--ev-color, var(--dt-accent));flex-shrink:0}.ag-compact-time.svelte-gg2mx3{font-size:11px;font-family:var(--dt-mono, monospace);color:var(--dt-text-2, rgba(255, 255, 255, .5));min-width:64px;flex-shrink:0}.ag-compact-title.svelte-gg2mx3{font-size:12px;font-weight:500;color:var(--dt-text-2, rgba(255, 255, 255, .5));flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .15s}.ag-compact-dur.svelte-gg2mx3{font-size:10px;font-family:var(--dt-mono, monospace);color:var(--dt-text-3, rgba(255, 255, 255, .3));flex-shrink:0}.ag-compact-sub.svelte-gg2mx3{font-size:10px;color:var(--dt-text-3, rgba(255, 255, 255, .35));flex-shrink:0}.ag-compact-tag.svelte-gg2mx3{font:500 8px / 1 var(--dt-sans, system-ui, sans-serif);color:var(--ev-color, var(--dt-accent));background:color-mix(in srgb,var(--ev-color, var(--dt-accent)) 12%,transparent);padding:1px 4px;border-radius:3px;white-space:nowrap;flex-shrink:0}.ag-compact-more.svelte-gg2mx3{font-size:11px;color:var(--dt-text-3);padding:2px 0 0 13px}