@cocoar/vue-calendar 1.18.0 → 2.1.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.
Files changed (62) hide show
  1. package/dist/builders/calendar-builder.d.ts +179 -2
  2. package/dist/builders/calendar-builder.d.ts.map +1 -1
  3. package/dist/builders/types.d.ts +41 -0
  4. package/dist/builders/types.d.ts.map +1 -1
  5. package/dist/components/CoarAgendaView.vue.d.ts.map +1 -1
  6. package/dist/components/CoarCalendar.vue.d.ts.map +1 -1
  7. package/dist/components/CoarMonthView.vue.d.ts.map +1 -1
  8. package/dist/components/CoarTimeGrid.vue.d.ts.map +1 -1
  9. package/dist/components/CoarTimelineView.vue.d.ts +68 -0
  10. package/dist/components/CoarTimelineView.vue.d.ts.map +1 -0
  11. package/dist/components/CoarWorkWeekView.vue.d.ts +53 -0
  12. package/dist/components/CoarWorkWeekView.vue.d.ts.map +1 -0
  13. package/dist/components/internal/CoarEventDecorations.vue.d.ts +1 -1
  14. package/dist/components/internal/CoarEventDecorations.vue.d.ts.map +1 -1
  15. package/dist/composables/useViewWindow.d.ts.map +1 -1
  16. package/dist/core/dnd/move-math.d.ts +23 -0
  17. package/dist/core/dnd/move-math.d.ts.map +1 -1
  18. package/dist/core/index.d.ts +8 -15
  19. package/dist/core/index.d.ts.map +1 -1
  20. package/dist/core/temporal.d.ts +13 -0
  21. package/dist/core/temporal.d.ts.map +1 -1
  22. package/dist/core/timelineLayout.d.ts +77 -0
  23. package/dist/core/timelineLayout.d.ts.map +1 -0
  24. package/dist/core/types.d.ts +1 -1
  25. package/dist/core/types.d.ts.map +1 -1
  26. package/dist/core/viewWindow.d.ts +8 -1
  27. package/dist/core/viewWindow.d.ts.map +1 -1
  28. package/dist/{core-DK63eHat.js → core-D-gBBiQ5.js} +276 -400
  29. package/dist/core.js +3 -2
  30. package/dist/index.d.ts +5 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1739 -1232
  33. package/dist/move-math-vYSpEW-r.js +215 -0
  34. package/dist/recurrence/index.d.ts +70 -0
  35. package/dist/recurrence/index.d.ts.map +1 -0
  36. package/dist/recurrence/internal/default-engine.d.ts +20 -0
  37. package/dist/recurrence/internal/default-engine.d.ts.map +1 -0
  38. package/dist/recurrence/internal/dst-resolve.d.ts +12 -0
  39. package/dist/recurrence/internal/dst-resolve.d.ts.map +1 -0
  40. package/dist/recurrence/internal/engine-to-events.d.ts +38 -0
  41. package/dist/recurrence/internal/engine-to-events.d.ts.map +1 -0
  42. package/dist/recurrence/internal/series-to-engine.d.ts +4 -0
  43. package/dist/recurrence/internal/series-to-engine.d.ts.map +1 -0
  44. package/dist/recurrence/types.d.ts +252 -0
  45. package/dist/recurrence/types.d.ts.map +1 -0
  46. package/dist/recurrence-rrule-temporal/index.d.ts +12 -0
  47. package/dist/recurrence-rrule-temporal/index.d.ts.map +1 -0
  48. package/dist/recurrence-rrule-temporal.js +158 -0
  49. package/dist/recurrence.js +225 -0
  50. package/dist/types-fzCER_SC.js +4 -0
  51. package/dist/useTimelineView.d.ts +6 -0
  52. package/dist/useTimelineView.d.ts.map +1 -0
  53. package/dist/useWorkWeekView.d.ts +6 -0
  54. package/dist/useWorkWeekView.d.ts.map +1 -0
  55. package/dist/vue-calendar.css +1 -1
  56. package/package.json +12 -7
  57. package/dist/core/recurrence-public.d.ts +0 -59
  58. package/dist/core/recurrence-public.d.ts.map +0 -1
  59. package/dist/core/recurrence.d.ts +0 -112
  60. package/dist/core/recurrence.d.ts.map +0 -1
  61. package/dist/core/recurrenceWorker.d.ts +0 -62
  62. package/dist/core/recurrenceWorker.d.ts.map +0 -1
@@ -0,0 +1,158 @@
1
+ import "./types-fzCER_SC.js";
2
+ import { Temporal as e } from "@js-temporal/polyfill";
3
+ import { RRuleTemporal as t } from "rrule-temporal";
4
+ //#region src/recurrence-rrule-temporal/index.ts
5
+ var n = class {
6
+ async expand(e) {
7
+ let t = [], n = [];
8
+ for (let i of e.series) try {
9
+ let n = r(i, e.window.startMs, e.window.endMs);
10
+ t.push(n);
11
+ } catch (e) {
12
+ n.push({
13
+ seriesId: i.seriesId,
14
+ message: e.message ?? String(e)
15
+ });
16
+ }
17
+ return {
18
+ results: t,
19
+ errors: n
20
+ };
21
+ }
22
+ };
23
+ function r(e, t, n) {
24
+ return e.kind === "timed" ? i(e, t, n) : a(e, t, n);
25
+ }
26
+ function i(n, r, i) {
27
+ let a = o(n.dtstart), s = n.dtstart.tzid, c = n.exdates.map((e) => o(e).withTimeZone(s)), l = [], u = [];
28
+ for (let e of n.rdates) {
29
+ let t = o(e);
30
+ l.push(t.withTimeZone(s)), u.push(e.tzid);
31
+ }
32
+ let d = [];
33
+ for (let l of n.rules) {
34
+ let u = {
35
+ rruleString: l.rrule,
36
+ dtstart: a,
37
+ tzid: s,
38
+ exDate: c
39
+ };
40
+ if (l.until) {
41
+ let e = l.until;
42
+ if ("hour" in e) u.until = o(e);
43
+ else throw TypeError(`[${n.seriesId}] timed series must use WallclockTimed for UNTIL, got WallclockDate.`);
44
+ }
45
+ let f = new t(u).between(e.Instant.fromEpochMilliseconds(r).toZonedDateTimeISO("UTC"), e.Instant.fromEpochMilliseconds(i).toZonedDateTimeISO("UTC"), !1);
46
+ for (let e of f) d.push({
47
+ instant: e.toInstant().epochMilliseconds,
48
+ tzid: s,
49
+ origin: 0
50
+ });
51
+ }
52
+ for (let e = 0; e < l.length; e++) {
53
+ let t = l[e].toInstant().epochMilliseconds;
54
+ t >= r && t < i && d.push({
55
+ instant: t,
56
+ tzid: u[e],
57
+ origin: 1
58
+ });
59
+ }
60
+ let f = new Set(c.map((e) => e.toInstant().epochMilliseconds)), p = d.filter((e) => !f.has(e.instant));
61
+ p.sort((e, t) => e.instant - t.instant);
62
+ let m = new Float64Array(p.length), h = new Uint8Array(p.length), g = !1;
63
+ for (let e = 0; e < p.length; e++) m[e] = p[e].instant, h[e] = p[e].origin, p[e].tzid !== s && (g = !0);
64
+ if (!g) return {
65
+ seriesId: n.seriesId,
66
+ kind: "timed",
67
+ timestamps: m,
68
+ seriesTzid: s,
69
+ origins: h
70
+ };
71
+ let _ = /* @__PURE__ */ new Map();
72
+ _.set(s, 0);
73
+ let v = [s], y = new Uint16Array(p.length);
74
+ for (let e = 0; e < p.length; e++) {
75
+ let t = p[e].tzid, n = _.get(t);
76
+ n === void 0 && (n = v.length, v.push(t), _.set(t, n)), y[e] = n;
77
+ }
78
+ return {
79
+ seriesId: n.seriesId,
80
+ kind: "timed",
81
+ timestamps: m,
82
+ seriesTzid: s,
83
+ occurrenceTzids: {
84
+ pool: v,
85
+ indices: y
86
+ },
87
+ origins: h
88
+ };
89
+ }
90
+ function a(n, r, i) {
91
+ let a = s(n.dtstart), o = n.exdates.map(s), l = n.rdates.map(s), u = [];
92
+ for (let c of n.rules) {
93
+ let l = {
94
+ rruleString: c.rrule,
95
+ dtstart: a,
96
+ tzid: "UTC",
97
+ exDate: o
98
+ };
99
+ if (c.until) {
100
+ let e = c.until;
101
+ if ("hour" in e) throw TypeError(`[${n.seriesId}] all-day series must use WallclockDate for UNTIL, got WallclockTimed.`);
102
+ l.until = s(e);
103
+ }
104
+ let d = new t(l).between(e.Instant.fromEpochMilliseconds(r).toZonedDateTimeISO("UTC"), e.Instant.fromEpochMilliseconds(i).toZonedDateTimeISO("UTC"), !1);
105
+ for (let e of d) u.push({
106
+ year: e.year,
107
+ month: e.month,
108
+ day: e.day,
109
+ origin: 0
110
+ });
111
+ }
112
+ for (let e of l) {
113
+ let t = e.toInstant().epochMilliseconds;
114
+ t >= r && t < i && u.push({
115
+ year: e.year,
116
+ month: e.month,
117
+ day: e.day,
118
+ origin: 1
119
+ });
120
+ }
121
+ let d = new Set(o.map((e) => c(e.year, e.month, e.day))), f = u.filter((e) => !d.has(c(e.year, e.month, e.day)));
122
+ f.sort((e, t) => c(e.year, e.month, e.day) - c(t.year, t.month, t.day));
123
+ let p = new Int32Array(f.length), m = new Uint8Array(f.length);
124
+ for (let e = 0; e < f.length; e++) p[e] = c(f[e].year, f[e].month, f[e].day), m[e] = f[e].origin;
125
+ return {
126
+ seriesId: n.seriesId,
127
+ kind: "allDay",
128
+ dates: p,
129
+ origins: m
130
+ };
131
+ }
132
+ function o(t) {
133
+ return e.ZonedDateTime.from({
134
+ year: t.year,
135
+ month: t.month,
136
+ day: t.day,
137
+ hour: t.hour,
138
+ minute: t.minute,
139
+ second: t.second,
140
+ timeZone: t.tzid
141
+ });
142
+ }
143
+ function s(t) {
144
+ return e.ZonedDateTime.from({
145
+ year: t.year,
146
+ month: t.month,
147
+ day: t.day,
148
+ hour: 0,
149
+ minute: 0,
150
+ second: 0,
151
+ timeZone: "UTC"
152
+ });
153
+ }
154
+ function c(e, t, n) {
155
+ return e * 512 + t * 32 + n;
156
+ }
157
+ //#endregion
158
+ export { n as RruleTemporalEngine };
@@ -0,0 +1,225 @@
1
+ import { a as e, t } from "./move-math-vYSpEW-r.js";
2
+ import { n, t as r } from "./types-fzCER_SC.js";
3
+ import { Temporal as i } from "@js-temporal/polyfill";
4
+ //#region src/recurrence/internal/series-to-engine.ts
5
+ function a(e) {
6
+ if (e.dtstart instanceof i.ZonedDateTime) return o(e, e.dtstart);
7
+ if (e.dtstart instanceof i.PlainDate) return s(e, e.dtstart);
8
+ throw TypeError(`[${e.id}] dtstart must be Temporal.ZonedDateTime (timed) or Temporal.PlainDate (all-day). Got ${e.dtstart?.constructor?.name ?? typeof e.dtstart}.`);
9
+ }
10
+ function o(e, t) {
11
+ let n = [];
12
+ if (e.rdate) for (let t = 0; t < e.rdate.length; t++) {
13
+ let r = e.rdate[t];
14
+ if (!(r instanceof i.ZonedDateTime)) throw TypeError(`[${e.id}] rdate[${t}] must be Temporal.ZonedDateTime for a timed series (dtstart is ZonedDateTime). Got ${r?.constructor?.name ?? typeof r}.`);
15
+ n.push(c(r));
16
+ }
17
+ let r = [];
18
+ if (e.exdate) for (let t = 0; t < e.exdate.length; t++) {
19
+ let n = e.exdate[t];
20
+ if (!(n instanceof i.ZonedDateTime)) throw TypeError(`[${e.id}] exdate[${t}] must be Temporal.ZonedDateTime for a timed series (dtstart is ZonedDateTime). Got ${n?.constructor?.name ?? typeof n}.`);
21
+ r.push(c(n));
22
+ }
23
+ return {
24
+ seriesId: e.id,
25
+ kind: "timed",
26
+ dtstart: c(t),
27
+ rules: [{ rrule: e.rrule }],
28
+ rdates: n,
29
+ exdates: r
30
+ };
31
+ }
32
+ function s(e, t) {
33
+ let n = [];
34
+ if (e.rdate) for (let t = 0; t < e.rdate.length; t++) {
35
+ let r = e.rdate[t];
36
+ if (!(r instanceof i.PlainDate)) throw TypeError(`[${e.id}] rdate[${t}] must be Temporal.PlainDate for an all-day series (dtstart is PlainDate). Got ${r?.constructor?.name ?? typeof r}.`);
37
+ n.push(l(r));
38
+ }
39
+ let r = [];
40
+ if (e.exdate) for (let t = 0; t < e.exdate.length; t++) {
41
+ let n = e.exdate[t];
42
+ if (!(n instanceof i.PlainDate)) throw TypeError(`[${e.id}] exdate[${t}] must be Temporal.PlainDate for an all-day series (dtstart is PlainDate). Got ${n?.constructor?.name ?? typeof n}.`);
43
+ r.push(l(n));
44
+ }
45
+ return {
46
+ seriesId: e.id,
47
+ kind: "allDay",
48
+ dtstart: l(t),
49
+ rules: [{ rrule: e.rrule }],
50
+ rdates: n,
51
+ exdates: r
52
+ };
53
+ }
54
+ function c(e) {
55
+ return {
56
+ year: e.year,
57
+ month: e.month,
58
+ day: e.day,
59
+ hour: e.hour,
60
+ minute: e.minute,
61
+ second: e.second,
62
+ tzid: e.timeZoneId
63
+ };
64
+ }
65
+ function l(e) {
66
+ return {
67
+ year: e.year,
68
+ month: e.month,
69
+ day: e.day
70
+ };
71
+ }
72
+ //#endregion
73
+ //#region src/recurrence/internal/engine-to-events.ts
74
+ var u = "__recurrence";
75
+ function d(e, t) {
76
+ return e.kind === "timed" ? f(e, t) : p(e, t);
77
+ }
78
+ function f(e, t) {
79
+ let n = [], { timestamps: r, seriesTzid: a, occurrenceTzids: o, origins: s } = e, c = o?.pool, l = o?.indices;
80
+ for (let e = 0; e < r.length; e++) {
81
+ let o = c && l ? c[l[e]] : a, u = i.Instant.fromEpochMilliseconds(r[e]).toZonedDateTimeISO(o), d = m(u, t.duration), f = s[e] === 1 ? "rdate" : "rrule";
82
+ n.push(g(t, u, d, u, f));
83
+ }
84
+ return n;
85
+ }
86
+ function p(e, t) {
87
+ let n = [], { dates: r, origins: a } = e;
88
+ for (let e = 0; e < r.length; e++) {
89
+ let o = r[e], s = o & 31, c = o >> 5 & 15, l = o >> 9, u = i.PlainDate.from({
90
+ year: l,
91
+ month: c,
92
+ day: s
93
+ }), d = h(u, t.duration), f = a[e] === 1 ? "rdate" : "rrule";
94
+ n.push(g(t, u, d, u, f));
95
+ }
96
+ return n;
97
+ }
98
+ function m(e, t) {
99
+ if (!t) return;
100
+ if (t.days !== void 0) throw TypeError("duration.days is only valid for all-day series (PlainDate dtstart). For timed series use {hours, minutes}.");
101
+ let n = t.hours ?? 0, r = t.minutes ?? 0;
102
+ if (!(n === 0 && r === 0)) return e.add({
103
+ hours: n,
104
+ minutes: r
105
+ });
106
+ }
107
+ function h(e, t) {
108
+ if (!t) return;
109
+ if (t.hours !== void 0 || t.minutes !== void 0) throw TypeError("duration.hours / duration.minutes are only valid for timed series (ZonedDateTime dtstart). For all-day series use {days}.");
110
+ let n = t.days ?? 0;
111
+ if (n !== 0) return e.add({ days: n });
112
+ }
113
+ function g(e, t, n, r, i) {
114
+ let a = {
115
+ ...e.meta,
116
+ [u]: {
117
+ seriesId: e.id,
118
+ recurrenceId: r,
119
+ source: i
120
+ }
121
+ }, o = {
122
+ id: `${e.id}__${r.toString()}`,
123
+ start: t,
124
+ meta: a
125
+ };
126
+ return n !== void 0 && (o.end = n), o;
127
+ }
128
+ function _(e) {
129
+ let t = e.meta;
130
+ if (!t) return null;
131
+ let n = t[u];
132
+ return !n || typeof n != "object" ? null : n;
133
+ }
134
+ //#endregion
135
+ //#region src/recurrence/internal/default-engine.ts
136
+ var v = null, y = null;
137
+ async function b() {
138
+ return v || y || (y = import("./recurrence-rrule-temporal.js").then((e) => (v = new e.RruleTemporalEngine(), v)).catch((e) => {
139
+ throw y = null, Error("[@cocoar/vue-calendar] Failed to load default recurrence engine (rrule-temporal). Ensure `rrule-temporal` is installed, or pass an explicit engine to `expandSeries(series, window, dstPolicy, engine)` / `builder.recurrenceEngine(...)`. Original error: " + (e.message ?? String(e)), { cause: e });
140
+ }), y);
141
+ }
142
+ //#endregion
143
+ //#region src/recurrence/internal/dst-resolve.ts
144
+ function x(n, r, a) {
145
+ if (!(r.dtstart instanceof i.ZonedDateTime)) return n;
146
+ let o = r.dtstart, s = o.timeZoneId, c = o.hour, l = o.minute, u = o.second, d = [];
147
+ for (let i of n) {
148
+ if (_(i)?.source === "rdate") {
149
+ d.push(i);
150
+ continue;
151
+ }
152
+ let n = i.start.withTimeZone(s), o = {
153
+ year: n.year,
154
+ month: n.month,
155
+ day: n.day,
156
+ hour: c,
157
+ minute: l,
158
+ second: u
159
+ }, f = e(s, o);
160
+ if (f === null) {
161
+ let e = S(o, s, "compatible");
162
+ d.push(C(i, e, r));
163
+ continue;
164
+ }
165
+ switch (a) {
166
+ case "compatible": {
167
+ let e = S(o, s, "compatible");
168
+ d.push(C(i, e, r));
169
+ break;
170
+ }
171
+ case "reject": throw new t(f, `[@cocoar/vue-calendar] series '${r.id}' has a recurring occurrence at ${w(o)} in zone '${s}' which falls in a DST ${f}. Set dstPolicy to 'compatible' (forward-shift), 'earlier' (last instant before transition), or 'later' (first instant after transition) to resolve.`);
172
+ case "earlier":
173
+ case "later": {
174
+ let e = S(o, s, a);
175
+ d.push(C(i, e, r));
176
+ break;
177
+ }
178
+ }
179
+ }
180
+ return d;
181
+ }
182
+ function S(e, t, n) {
183
+ return i.PlainDateTime.from({
184
+ year: e.year,
185
+ month: e.month,
186
+ day: e.day,
187
+ hour: e.hour,
188
+ minute: e.minute,
189
+ second: e.second
190
+ }).toZonedDateTime(t, { disambiguation: n });
191
+ }
192
+ function C(e, t, n) {
193
+ let r = {
194
+ id: e.id,
195
+ start: t,
196
+ meta: e.meta
197
+ }, i = n.duration;
198
+ return i && (i.hours !== void 0 || i.minutes !== void 0) && (r.end = t.add({
199
+ hours: i.hours ?? 0,
200
+ minutes: i.minutes ?? 0
201
+ })), r;
202
+ }
203
+ function w(e) {
204
+ let t = (e) => String(e).padStart(2, "0");
205
+ return `${e.year}-${t(e.month)}-${t(e.day)} ${t(e.hour)}:${t(e.minute)}`;
206
+ }
207
+ //#endregion
208
+ //#region src/recurrence/index.ts
209
+ async function T(e, t, n, r) {
210
+ let i = r ?? await b(), o = a(e), s = t.start.toInstant().epochMilliseconds, c = t.end.toInstant().epochMilliseconds, l = await i.expand({
211
+ window: {
212
+ startMs: s,
213
+ endMs: c
214
+ },
215
+ series: [o]
216
+ });
217
+ if (l.errors.length > 0) {
218
+ let e = l.errors[0];
219
+ throw Error(`[@cocoar/vue-calendar] Engine failed to expand series '${e.seriesId}': ${e.message}`);
220
+ }
221
+ let u = l.results[0];
222
+ return u ? x(d(u, e), e, n) : [];
223
+ }
224
+ //#endregion
225
+ export { r as ORIGIN_RDATE, n as ORIGIN_RRULE, T as expandSeries, _ as getRecurrenceMeta };
@@ -0,0 +1,4 @@
1
+ //#region src/recurrence/types.ts
2
+ var e = 0, t = 1;
3
+ //#endregion
4
+ export { e as n, t };
@@ -0,0 +1,6 @@
1
+ import { CalendarBuilder, CalendarApi } from './builders/calendar-builder';
2
+ export declare function useTimelineView<TMeta extends Record<string, unknown> = Record<string, unknown>>(): {
3
+ builder: CalendarBuilder<TMeta>;
4
+ api: CalendarApi<TMeta>;
5
+ };
6
+ //# sourceMappingURL=useTimelineView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimelineView.d.ts","sourceRoot":"","sources":["../src/useTimelineView.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAEhF,wBAAgB,eAAe,CAC7B,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5D;IACH,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAChC,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;CACzB,CAKA"}
@@ -0,0 +1,6 @@
1
+ import { CalendarBuilder, CalendarApi } from './builders/calendar-builder';
2
+ export declare function useWorkWeekView<TMeta extends Record<string, unknown> = Record<string, unknown>>(): {
3
+ builder: CalendarBuilder<TMeta>;
4
+ api: CalendarApi<TMeta>;
5
+ };
6
+ //# sourceMappingURL=useWorkWeekView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWorkWeekView.d.ts","sourceRoot":"","sources":["../src/useWorkWeekView.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAEhF,wBAAgB,eAAe,CAC7B,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5D;IACH,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAChC,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;CACzB,CAKA"}
@@ -1,2 +1,2 @@
1
- .coar-event-decorations__utc[data-v-c94b210c],.coar-event-decorations__cross-zone[data-v-c94b210c]{color:var(--coar-text-subtle,#6c7280);flex:none;justify-content:center;align-items:center;margin-right:4px;display:inline-flex}.coar-event-decorations__cross-zone[data-v-c94b210c]{position:relative}.coar-event-decorations__cross-zone[data-v-c94b210c]:after{content:"";background:var(--coar-color-accent,#2563eb);border-radius:50%;width:4px;height:4px;position:absolute;top:0;right:-2px}.coar-event-decorations__sr-only[data-v-c94b210c]{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.coar-time-grid-event[data-v-9d7d3ab2]{box-sizing:border-box;font-size:var(--coar-font-size-xs,11px);cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none;contain:layout paint;border-radius:3px;position:absolute;overflow:hidden}.coar-time-grid-event--clipped-top[data-v-9d7d3ab2]{border-top-left-radius:0;border-top-right-radius:0}.coar-time-grid-event--clipped-bottom[data-v-9d7d3ab2]{border-bottom-right-radius:0;border-bottom-left-radius:0}.coar-time-grid-event[data-v-9d7d3ab2]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-time-grid-event--ghost[data-v-9d7d3ab2]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-time-grid-event--source-phantom[data-v-9d7d3ab2]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-time-grid-event--invalid[data-v-9d7d3ab2]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-time-grid-event--snap-back[data-v-9d7d3ab2]{animation:.22s ease-out forwards coar-time-grid-event-snap-back-9d7d3ab2}@keyframes coar-time-grid-event-snap-back-9d7d3ab2{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-time-grid-event--snap-back[data-v-9d7d3ab2]{opacity:0;animation:none}}.coar-time-grid-event__default[data-v-9d7d3ab2]{height:100%;padding:2px 6px}.coar-time-grid-event__title-row[data-v-9d7d3ab2]{align-items:center;gap:0;min-width:0;display:flex}.coar-time-grid-event__title[data-v-9d7d3ab2]{color:var(--coar-text-base,#1a1c1f);white-space:nowrap;text-overflow:ellipsis;font-weight:600;display:block;overflow:hidden}.coar-time-grid-event__resize[data-v-9d7d3ab2]{cursor:ns-resize;-webkit-user-select:none;user-select:none;pointer-events:auto;z-index:2;height:6px;position:absolute;left:0;right:0}.coar-time-grid-event__resize--top[data-v-9d7d3ab2]{top:0}.coar-time-grid-event__resize--bottom[data-v-9d7d3ab2]{bottom:0}.coar-time-grid-event--density-compact[data-v-9d7d3ab2]{font-size:10px}.coar-time-grid-event--density-compact .coar-time-grid-event__default[data-v-9d7d3ab2]{padding:1px 4px}.coar-time-grid-all-day-bar[data-v-4fac0b2d]{box-sizing:border-box;font-size:var(--coar-font-size-xs,11px);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;touch-action:none;contain:layout paint;border-radius:3px;align-items:center;padding:1px 6px;display:flex;position:absolute;overflow:hidden}.coar-time-grid-all-day-bar--clipped-start[data-v-4fac0b2d]{border-top-left-radius:0;border-bottom-left-radius:0}.coar-time-grid-all-day-bar--clipped-end[data-v-4fac0b2d]{border-top-right-radius:0;border-bottom-right-radius:0}.coar-time-grid-all-day-bar[data-v-4fac0b2d]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-time-grid-all-day-bar--ghost[data-v-4fac0b2d]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-time-grid-all-day-bar--source-phantom[data-v-4fac0b2d]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-time-grid-all-day-bar--invalid[data-v-4fac0b2d]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-time-grid-all-day-bar--snap-back[data-v-4fac0b2d]{animation:.22s ease-out forwards coar-time-grid-all-day-bar-snap-back-4fac0b2d}@keyframes coar-time-grid-all-day-bar-snap-back-4fac0b2d{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-time-grid-all-day-bar--snap-back[data-v-4fac0b2d]{opacity:0;animation:none}}.coar-time-grid-all-day-bar__title[data-v-4fac0b2d]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;font-weight:600;overflow:hidden}.coar-time-grid-all-day-bar__resize[data-v-4fac0b2d]{cursor:ew-resize;-webkit-user-select:none;user-select:none;pointer-events:auto;z-index:2;width:6px;position:absolute;top:0;bottom:0}.coar-time-grid-all-day-bar__resize--start[data-v-4fac0b2d]{left:0}.coar-time-grid-all-day-bar__resize--end[data-v-4fac0b2d]{right:0}.coar-time-grid-all-day-bar--density-compact[data-v-4fac0b2d]{padding:0 4px;font-size:10px}.coar-time-grid-now-marker[data-v-ce9e34d0]{pointer-events:none;z-index:5;position:absolute;left:0;right:0}.coar-time-grid-now-marker__dot[data-v-ce9e34d0]{background:var(--coar-color-danger,#dc2626);border-radius:50%;width:8px;height:8px;position:absolute;top:-4px;left:-4px}.coar-time-grid-now-marker__line[data-v-ce9e34d0]{background:var(--coar-color-danger,#dc2626);height:1px;display:block}.coar-time-grid-header[data-v-ed6739ff]{grid-template-columns:var(--coar-time-grid-axis-width) 1fr;border-bottom:1px solid var(--coar-calendar-border,#d1d5db);background:var(--coar-calendar-bg,#fff);min-height:var(--coar-time-grid-header-height);display:grid}.coar-time-grid-header__cells[data-v-ed6739ff]{grid-auto-columns:1fr;grid-auto-flow:column;display:grid}.coar-time-grid-header__cell[data-v-ed6739ff]{border-left:1px solid var(--coar-calendar-border,#d1d5db);font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-base,#1a1c1f);background:var(--coar-calendar-bg,#fff);padding:8px 12px;font-weight:600}.coar-time-grid-header__cell--today[data-v-ed6739ff]{color:var(--coar-color-accent,#2563eb)}.coar-time-grid-header__cell--weekend[data-v-ed6739ff]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-time-grid-header--density-compact .coar-time-grid-header__cell[data-v-ed6739ff]{font-size:var(--coar-font-size-xs,11px);padding:4px 8px}.coar-time-grid-all-day-band[data-v-4eabecb1]{grid-template-columns:var(--coar-time-grid-axis-width) 1fr;border-bottom:1px solid var(--coar-calendar-border,#d1d5db);background:var(--coar-calendar-bg,#fff);font-size:var(--coar-font-size-xs,11px);display:grid}.coar-time-grid-all-day-band__axis[data-v-4eabecb1]{text-transform:uppercase;letter-spacing:.04em;color:var(--coar-text-subtle,#6c7280);align-self:start;padding:4px 6px;line-height:1.2}.coar-time-grid-all-day-band__columns[data-v-4eabecb1]{grid-auto-columns:1fr;grid-auto-flow:column;display:grid;position:relative}.coar-time-grid-all-day-band__cell[data-v-4eabecb1]{border-left:1px solid var(--coar-calendar-border,#d1d5db);cursor:pointer}.coar-time-grid-all-day-band__cell--weekend[data-v-4eabecb1]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-time-grid-all-day-band__cell--today[data-v-4eabecb1]{background:var(--coar-calendar-bg-today,#2563eb0a)}.coar-time-grid-column[data-v-32d41217]{border-left:1px solid var(--coar-calendar-border,#d1d5db);background:var(--coar-calendar-bg,#fff);contain:layout;position:relative}.coar-time-grid-column--weekend[data-v-32d41217]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-time-grid-column--today[data-v-32d41217]{background:var(--coar-calendar-bg-today,#2563eb0a)}.coar-time-grid__a11y-live[data-v-7e4afbd4]{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.coar-time-grid[data-v-7e4afbd4]{font-family:var(--coar-body-base-family,system-ui, sans-serif);font-variant-numeric:tabular-nums;background:var(--coar-calendar-bg,#fff);--coar-time-grid-header-height:36px;--coar-time-grid-axis-width:80px;flex-direction:column;display:flex}.coar-time-grid__sticky-top[data-v-7e4afbd4]{z-index:20;background:var(--coar-calendar-bg,#fff);position:sticky;top:0}.coar-time-grid__all-day-bar-title[data-v-7e4afbd4]{text-overflow:ellipsis;color:var(--coar-text-base,#1a1c1f);font-weight:600;overflow:hidden}.coar-time-grid__body[data-v-7e4afbd4]{grid-template-columns:var(--coar-time-grid-axis-width) 1fr;display:grid;position:relative;overflow:hidden}.coar-time-grid__hour-axis[data-v-7e4afbd4]{position:relative}.coar-time-grid__hour-label[data-v-7e4afbd4]{text-align:right;font-size:var(--coar-font-size-xs,11px);color:var(--coar-text-subtle,#6c7280);padding-right:8px;position:absolute;left:0;right:8px;transform:translateY(-50%)}.coar-time-grid__columns[data-v-7e4afbd4]{grid-auto-columns:1fr;grid-auto-flow:column;display:grid;position:relative}.coar-time-grid__event-default[data-v-7e4afbd4]{flex-direction:column;height:100%;display:flex}.coar-time-grid__event-title[data-v-7e4afbd4]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.coar-day-view[data-v-639564d0],.coar-week-view[data-v-29a99a70]{width:100%;display:block}.coar-month-pill[data-v-ca59e6dd]{font-size:var(--coar-font-size-xs,11px);cursor:pointer;white-space:nowrap;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;touch-action:none;border-radius:3px;flex:none;align-items:center;min-width:0;padding:1px 6px;display:flex;overflow:hidden}.coar-month-pill[data-v-ca59e6dd]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-month-pill--ghost[data-v-ca59e6dd]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-month-pill--source-phantom[data-v-ca59e6dd]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-month-pill--invalid[data-v-ca59e6dd]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-month-pill__title[data-v-ca59e6dd]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.coar-month-pill--snap-back[data-v-ca59e6dd]{animation:.22s ease-out forwards coar-month-pill-snap-back-ca59e6dd}@keyframes coar-month-pill-snap-back-ca59e6dd{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-month-pill--snap-back[data-v-ca59e6dd]{opacity:0;animation:none}}.coar-month-pill--density-compact[data-v-ca59e6dd]{padding:0 4px;font-size:10px}.coar-month-bar[data-v-aae90a51]{box-sizing:border-box;font-size:var(--coar-font-size-xs,11px);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;touch-action:none;contain:layout paint;border-radius:3px;align-items:center;padding:1px 6px;display:flex;position:absolute;overflow:hidden}.coar-month-bar--clipped-start[data-v-aae90a51]{border-top-left-radius:0;border-bottom-left-radius:0}.coar-month-bar--clipped-end[data-v-aae90a51]{border-top-right-radius:0;border-bottom-right-radius:0}.coar-month-bar[data-v-aae90a51]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-month-bar--ghost[data-v-aae90a51]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-month-bar--source-phantom[data-v-aae90a51]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-month-bar--invalid[data-v-aae90a51]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-month-bar__title[data-v-aae90a51]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;font-weight:600;overflow:hidden}.coar-month-bar__resize[data-v-aae90a51]{cursor:ew-resize;-webkit-user-select:none;user-select:none;pointer-events:auto;z-index:2;width:6px;position:absolute;top:0;bottom:0}.coar-month-bar__resize--start[data-v-aae90a51]{left:0}.coar-month-bar__resize--end[data-v-aae90a51]{right:0}.coar-month-bar--snap-back[data-v-aae90a51]{animation:.22s ease-out forwards coar-month-bar-snap-back-aae90a51}@keyframes coar-month-bar-snap-back-aae90a51{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-month-bar--snap-back[data-v-aae90a51]{opacity:0;animation:none}}.coar-month-bar--density-compact[data-v-aae90a51]{padding:0 4px;font-size:10px}.coar-month-cell[data-v-a2e2a614]{border-left:1px solid var(--coar-calendar-border,#d1d5db);cursor:pointer;background:var(--coar-calendar-bg,#fff);contain:layout paint;flex-direction:column;min-width:0;min-height:0;display:flex;position:relative}.coar-month-cell[data-v-a2e2a614]:first-child{border-left:none}.coar-month-cell--weekend[data-v-a2e2a614]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-month-cell--other-month[data-v-a2e2a614]{background:var(--coar-calendar-bg-other-month,#fafafb);color:var(--coar-text-subtle,#9ca3af)}.coar-month-cell--today[data-v-a2e2a614]{background:var(--coar-calendar-bg-today,#2563eb0a)}.coar-month-cell__day-number-row[data-v-a2e2a614]{box-sizing:border-box;align-items:center;height:24px;padding:4px 6px;display:flex}.coar-month-cell__day-number[data-v-a2e2a614]{font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-base,#1a1c1f);font-weight:600}.coar-month-cell--today .coar-month-cell__day-number[data-v-a2e2a614]{color:var(--coar-color-accent,#2563eb)}.coar-month-cell--other-month .coar-month-cell__day-number[data-v-a2e2a614]{color:var(--coar-text-subtle,#9ca3af);font-weight:500}.coar-month-cell__pills[data-v-a2e2a614]{scrollbar-width:thin;scrollbar-color:var(--coar-border-neutral-tertiary,#d1d5db) transparent;flex-direction:column;flex:1 1 0;gap:2px;min-height:0;padding:3px 4px 4px;display:flex;overflow-y:auto}.coar-month-cell__pills[data-v-a2e2a614]::-webkit-scrollbar{width:6px}.coar-month-cell__pills[data-v-a2e2a614]::-webkit-scrollbar-thumb{background:var(--coar-border-neutral-tertiary,#d1d5db);border-radius:3px}.coar-month-cell__pills[data-v-a2e2a614]::-webkit-scrollbar-track{background:0 0}.coar-month-cell__menu-trigger[data-v-a2e2a614]{cursor:pointer;width:18px;height:18px;color:var(--coar-text-subtle,#6c7280);border-radius:var(--coar-radius-xs,2px);background:0 0;border:0;justify-content:center;align-items:center;margin-left:auto;padding:0;display:inline-flex}.coar-month-cell__menu-trigger[data-v-a2e2a614]:hover,.coar-month-cell__menu-trigger[data-v-a2e2a614]:focus-visible,.coar-month-cell__menu-trigger[aria-expanded=true][data-v-a2e2a614]{background:var(--coar-background-neutral-tertiary,#f3f4f6);color:var(--coar-text-base,#1a1c1f)}@media (hover:hover){.coar-month-cell__menu-trigger[data-v-a2e2a614]{opacity:0}.coar-month-cell:hover .coar-month-cell__menu-trigger[data-v-a2e2a614],.coar-month-cell__menu-trigger[data-v-a2e2a614]:focus-visible,.coar-month-cell__menu-trigger[aria-expanded=true][data-v-a2e2a614]{opacity:1}}.coar-month-row[data-v-8f7c41d6]{border-bottom:1px solid var(--coar-calendar-border,#d1d5db);grid-template-columns:repeat(7,1fr);min-height:100px;transition:height .2s ease-out;display:grid;position:relative}@media (prefers-reduced-motion:reduce){.coar-month-row[data-v-8f7c41d6]{transition:none}}.coar-month-row[data-v-8f7c41d6]:last-child{border-bottom:none}.coar-month-row--density-compact[data-v-8f7c41d6]{min-height:80px}.coar-month-grid[data-v-d0d74cdf]{display:contents}.coar-month-grid__weekday-row[data-v-d0d74cdf]{border-bottom:1px solid var(--coar-calendar-border,#d1d5db);z-index:5;background:var(--coar-calendar-bg,#fff);grid-template-columns:repeat(7,1fr);display:grid;position:sticky;top:0}.coar-month-grid__weekday-cell[data-v-d0d74cdf]{font-size:var(--coar-font-size-xs,11px);text-transform:uppercase;letter-spacing:.04em;color:var(--coar-text-subtle,#6c7280);border-left:1px solid var(--coar-calendar-border,#d1d5db);padding:8px 12px;font-weight:600}.coar-month-grid__weekday-cell[data-v-d0d74cdf]:first-child{border-left:none}.coar-month-view__a11y-live[data-v-ce373bd0]{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.coar-month-view[data-v-ce373bd0]{background:var(--coar-calendar-bg,#fff);font-family:var(--coar-body-base-family,system-ui, sans-serif);font-variant-numeric:tabular-nums;flex-direction:column;display:flex}.coar-month-view__pill-title[data-v-ce373bd0]{color:var(--coar-text-base,#1a1c1f);font-weight:600}.coar-month-view__bar-title[data-v-ce373bd0]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;font-weight:600;overflow:hidden}.coar-virtualized-surface-1dy[data-v-50d47c8e]{contain:strict;position:relative;overflow:hidden auto}.coar-virtualized-surface-1dy__spacer[data-v-50d47c8e]{width:100%;position:relative}.coar-virtualized-surface-1dy__item[data-v-50d47c8e]{contain:layout paint style;position:absolute;top:0;left:0;right:0}.coar-agenda-day-header[data-v-990c502f]{background:var(--coar-calendar-bg,#fff);border-bottom:1px solid var(--coar-calendar-border,#e3e5e9);font-weight:600;font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-base,#1a1c1f);align-items:baseline;gap:8px;padding:8px 16px;display:flex}.coar-agenda-day-header--today[data-v-990c502f]{color:var(--coar-color-accent,#2563eb)}.coar-agenda-day-header--empty[data-v-990c502f]{color:var(--coar-text-subtle,#9ca3af);font-style:italic}.coar-agenda-day-header--floating[data-v-990c502f]{z-index:10;will-change:transform;margin-right:14px;position:absolute;top:0;left:0;right:0}.coar-agenda-day-header__today[data-v-990c502f]{font-size:var(--coar-font-size-xs,11px);text-transform:uppercase;letter-spacing:.05em;background:var(--coar-color-accent,#2563eb);color:#fff;border-radius:999px;padding:2px 8px;font-weight:700}.coar-agenda-event[data-v-12cce1c9]{border-bottom:1px solid var(--coar-calendar-border,#f3f4f6);cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--coar-calendar-bg,#fff);padding:10px 16px;transition:background-color 80ms}.coar-agenda-event[data-v-12cce1c9]:hover{background:var(--coar-surface-subtle,#f6f7f9)}.coar-agenda-event--continuation[data-v-12cce1c9]{opacity:.7}.coar-agenda-event__default[data-v-12cce1c9]{align-items:center;gap:12px;display:flex}.coar-agenda-event__color[data-v-12cce1c9]{border-radius:50%;flex:none;width:8px;height:8px}.coar-agenda-event__time[data-v-12cce1c9]{font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-subtle,#6c7280);font-variant-numeric:tabular-nums;min-width:80px}.coar-agenda-event__title[data-v-12cce1c9]{font-size:var(--coar-font-size-base,14px);color:var(--coar-text-base,#1a1c1f);font-weight:500}.coar-agenda-event__continuation-tag[data-v-12cce1c9]{font-size:var(--coar-font-size-xs,11px);color:var(--coar-text-subtle,#9ca3af);margin-left:6px;font-style:italic;font-weight:400}.coar-agenda-view[data-v-881506a3]{background:var(--coar-calendar-bg,#fff);font-family:var(--coar-body-base-family,system-ui, sans-serif);height:100%;position:relative;overflow:hidden}.coar-agenda-view__surface[data-v-881506a3]{height:100%}.coar-calendar[data-v-b90f5519]{background:var(--coar-background-neutral-primary);height:100%;font-family:var(--coar-body-base-family);color:var(--coar-text-neutral-primary);flex-direction:column;display:flex}.coar-calendar__header[data-v-b90f5519]{align-items:center;gap:var(--coar-spacing-m);padding:var(--coar-spacing-s) var(--coar-spacing-m);border-bottom:1px solid var(--coar-border-neutral-tertiary);background:var(--coar-background-neutral-primary);flex:none;display:flex}.coar-calendar__nav[data-v-b90f5519]{align-items:center;gap:var(--coar-spacing-xs);display:flex}.coar-calendar__range-label[data-v-b90f5519]{font-size:var(--coar-component-m-font-size);color:var(--coar-text-neutral-primary);white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.coar-calendar__spacer[data-v-b90f5519]{flex:auto}.coar-calendar__body[data-v-b90f5519]{flex:auto;min-height:0}.coar-calendar__body--day[data-v-b90f5519],.coar-calendar__body--week[data-v-b90f5519],.coar-calendar__body--month[data-v-b90f5519]{overflow:hidden auto}.coar-calendar__body--agenda[data-v-b90f5519]{overflow:hidden}.coar-virtualized-surface-2d[data-v-fbba32db]{contain:strict;position:relative;overflow:auto}.coar-virtualized-surface-2d__spacer[data-v-fbba32db]{position:relative}.coar-virtualized-surface-2d__cell[data-v-fbba32db]{contain:layout paint size style;box-sizing:border-box;position:absolute;top:0;left:0}
1
+ .coar-event-decorations__utc[data-v-c94b210c],.coar-event-decorations__cross-zone[data-v-c94b210c]{color:var(--coar-text-subtle,#6c7280);flex:none;justify-content:center;align-items:center;margin-right:4px;display:inline-flex}.coar-event-decorations__cross-zone[data-v-c94b210c]{position:relative}.coar-event-decorations__cross-zone[data-v-c94b210c]:after{content:"";background:var(--coar-color-accent,#2563eb);border-radius:50%;width:4px;height:4px;position:absolute;top:0;right:-2px}.coar-event-decorations__sr-only[data-v-c94b210c]{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.coar-time-grid-event[data-v-9d7d3ab2]{box-sizing:border-box;font-size:var(--coar-font-size-xs,11px);cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none;contain:layout paint;border-radius:3px;position:absolute;overflow:hidden}.coar-time-grid-event--clipped-top[data-v-9d7d3ab2]{border-top-left-radius:0;border-top-right-radius:0}.coar-time-grid-event--clipped-bottom[data-v-9d7d3ab2]{border-bottom-right-radius:0;border-bottom-left-radius:0}.coar-time-grid-event[data-v-9d7d3ab2]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-time-grid-event--ghost[data-v-9d7d3ab2]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-time-grid-event--source-phantom[data-v-9d7d3ab2]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-time-grid-event--invalid[data-v-9d7d3ab2]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-time-grid-event--snap-back[data-v-9d7d3ab2]{animation:.22s ease-out forwards coar-time-grid-event-snap-back-9d7d3ab2}@keyframes coar-time-grid-event-snap-back-9d7d3ab2{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-time-grid-event--snap-back[data-v-9d7d3ab2]{opacity:0;animation:none}}.coar-time-grid-event__default[data-v-9d7d3ab2]{height:100%;padding:2px 6px}.coar-time-grid-event__title-row[data-v-9d7d3ab2]{align-items:center;gap:0;min-width:0;display:flex}.coar-time-grid-event__title[data-v-9d7d3ab2]{color:var(--coar-text-base,#1a1c1f);white-space:nowrap;text-overflow:ellipsis;font-weight:600;display:block;overflow:hidden}.coar-time-grid-event__resize[data-v-9d7d3ab2]{cursor:ns-resize;-webkit-user-select:none;user-select:none;pointer-events:auto;z-index:2;height:6px;position:absolute;left:0;right:0}.coar-time-grid-event__resize--top[data-v-9d7d3ab2]{top:0}.coar-time-grid-event__resize--bottom[data-v-9d7d3ab2]{bottom:0}.coar-time-grid-event--density-compact[data-v-9d7d3ab2]{font-size:10px}.coar-time-grid-event--density-compact .coar-time-grid-event__default[data-v-9d7d3ab2]{padding:1px 4px}.coar-time-grid-all-day-bar[data-v-4fac0b2d]{box-sizing:border-box;font-size:var(--coar-font-size-xs,11px);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;touch-action:none;contain:layout paint;border-radius:3px;align-items:center;padding:1px 6px;display:flex;position:absolute;overflow:hidden}.coar-time-grid-all-day-bar--clipped-start[data-v-4fac0b2d]{border-top-left-radius:0;border-bottom-left-radius:0}.coar-time-grid-all-day-bar--clipped-end[data-v-4fac0b2d]{border-top-right-radius:0;border-bottom-right-radius:0}.coar-time-grid-all-day-bar[data-v-4fac0b2d]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-time-grid-all-day-bar--ghost[data-v-4fac0b2d]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-time-grid-all-day-bar--source-phantom[data-v-4fac0b2d]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-time-grid-all-day-bar--invalid[data-v-4fac0b2d]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-time-grid-all-day-bar--snap-back[data-v-4fac0b2d]{animation:.22s ease-out forwards coar-time-grid-all-day-bar-snap-back-4fac0b2d}@keyframes coar-time-grid-all-day-bar-snap-back-4fac0b2d{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-time-grid-all-day-bar--snap-back[data-v-4fac0b2d]{opacity:0;animation:none}}.coar-time-grid-all-day-bar__title[data-v-4fac0b2d]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;font-weight:600;overflow:hidden}.coar-time-grid-all-day-bar__resize[data-v-4fac0b2d]{cursor:ew-resize;-webkit-user-select:none;user-select:none;pointer-events:auto;z-index:2;width:6px;position:absolute;top:0;bottom:0}.coar-time-grid-all-day-bar__resize--start[data-v-4fac0b2d]{left:0}.coar-time-grid-all-day-bar__resize--end[data-v-4fac0b2d]{right:0}.coar-time-grid-all-day-bar--density-compact[data-v-4fac0b2d]{padding:0 4px;font-size:10px}.coar-time-grid-now-marker[data-v-ce9e34d0]{pointer-events:none;z-index:5;position:absolute;left:0;right:0}.coar-time-grid-now-marker__dot[data-v-ce9e34d0]{background:var(--coar-color-danger,#dc2626);border-radius:50%;width:8px;height:8px;position:absolute;top:-4px;left:-4px}.coar-time-grid-now-marker__line[data-v-ce9e34d0]{background:var(--coar-color-danger,#dc2626);height:1px;display:block}.coar-time-grid-header[data-v-ed6739ff]{grid-template-columns:var(--coar-time-grid-axis-width) 1fr;border-bottom:1px solid var(--coar-calendar-border,#d1d5db);background:var(--coar-calendar-bg,#fff);min-height:var(--coar-time-grid-header-height);display:grid}.coar-time-grid-header__cells[data-v-ed6739ff]{grid-auto-columns:1fr;grid-auto-flow:column;display:grid}.coar-time-grid-header__cell[data-v-ed6739ff]{border-left:1px solid var(--coar-calendar-border,#d1d5db);font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-base,#1a1c1f);background:var(--coar-calendar-bg,#fff);padding:8px 12px;font-weight:600}.coar-time-grid-header__cell--today[data-v-ed6739ff]{color:var(--coar-color-accent,#2563eb)}.coar-time-grid-header__cell--weekend[data-v-ed6739ff]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-time-grid-header--density-compact .coar-time-grid-header__cell[data-v-ed6739ff]{font-size:var(--coar-font-size-xs,11px);padding:4px 8px}.coar-time-grid-all-day-band[data-v-4eabecb1]{grid-template-columns:var(--coar-time-grid-axis-width) 1fr;border-bottom:1px solid var(--coar-calendar-border,#d1d5db);background:var(--coar-calendar-bg,#fff);font-size:var(--coar-font-size-xs,11px);display:grid}.coar-time-grid-all-day-band__axis[data-v-4eabecb1]{text-transform:uppercase;letter-spacing:.04em;color:var(--coar-text-subtle,#6c7280);align-self:start;padding:4px 6px;line-height:1.2}.coar-time-grid-all-day-band__columns[data-v-4eabecb1]{grid-auto-columns:1fr;grid-auto-flow:column;display:grid;position:relative}.coar-time-grid-all-day-band__cell[data-v-4eabecb1]{border-left:1px solid var(--coar-calendar-border,#d1d5db);cursor:pointer}.coar-time-grid-all-day-band__cell--weekend[data-v-4eabecb1]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-time-grid-all-day-band__cell--today[data-v-4eabecb1]{background:var(--coar-calendar-bg-today,#2563eb0a)}.coar-time-grid-column[data-v-32d41217]{border-left:1px solid var(--coar-calendar-border,#d1d5db);background:var(--coar-calendar-bg,#fff);contain:layout;position:relative}.coar-time-grid-column--weekend[data-v-32d41217]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-time-grid-column--today[data-v-32d41217]{background:var(--coar-calendar-bg-today,#2563eb0a)}.coar-time-grid__a11y-live[data-v-9e7bf32c]{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.coar-time-grid[data-v-9e7bf32c]{font-family:var(--coar-body-base-family,system-ui, sans-serif);font-variant-numeric:tabular-nums;background:var(--coar-calendar-bg,#fff);--coar-time-grid-header-height:36px;--coar-time-grid-axis-width:80px;flex-direction:column;display:flex}.coar-time-grid__sticky-top[data-v-9e7bf32c]{z-index:20;background:var(--coar-calendar-bg,#fff);position:sticky;top:0}.coar-time-grid__all-day-bar-title[data-v-9e7bf32c]{text-overflow:ellipsis;color:var(--coar-text-base,#1a1c1f);font-weight:600;overflow:hidden}.coar-time-grid__body[data-v-9e7bf32c]{grid-template-columns:var(--coar-time-grid-axis-width) 1fr;display:grid;position:relative;overflow:hidden}.coar-time-grid__hour-axis[data-v-9e7bf32c]{position:relative}.coar-time-grid__hour-label[data-v-9e7bf32c]{text-align:right;font-size:var(--coar-font-size-xs,11px);color:var(--coar-text-subtle,#6c7280);padding-right:8px;position:absolute;left:0;right:8px;transform:translateY(-50%)}.coar-time-grid__columns[data-v-9e7bf32c]{grid-auto-columns:1fr;grid-auto-flow:column;display:grid;position:relative}.coar-time-grid__event-default[data-v-9e7bf32c]{flex-direction:column;height:100%;display:flex}.coar-time-grid__event-title[data-v-9e7bf32c]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.coar-day-view[data-v-639564d0],.coar-week-view[data-v-29a99a70],.coar-work-week-view[data-v-0cfec5b4]{width:100%;display:block}.coar-month-pill[data-v-ca59e6dd]{font-size:var(--coar-font-size-xs,11px);cursor:pointer;white-space:nowrap;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;touch-action:none;border-radius:3px;flex:none;align-items:center;min-width:0;padding:1px 6px;display:flex;overflow:hidden}.coar-month-pill[data-v-ca59e6dd]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-month-pill--ghost[data-v-ca59e6dd]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-month-pill--source-phantom[data-v-ca59e6dd]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-month-pill--invalid[data-v-ca59e6dd]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-month-pill__title[data-v-ca59e6dd]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.coar-month-pill--snap-back[data-v-ca59e6dd]{animation:.22s ease-out forwards coar-month-pill-snap-back-ca59e6dd}@keyframes coar-month-pill-snap-back-ca59e6dd{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-month-pill--snap-back[data-v-ca59e6dd]{opacity:0;animation:none}}.coar-month-pill--density-compact[data-v-ca59e6dd]{padding:0 4px;font-size:10px}.coar-month-bar[data-v-aae90a51]{box-sizing:border-box;font-size:var(--coar-font-size-xs,11px);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;touch-action:none;contain:layout paint;border-radius:3px;align-items:center;padding:1px 6px;display:flex;position:absolute;overflow:hidden}.coar-month-bar--clipped-start[data-v-aae90a51]{border-top-left-radius:0;border-bottom-left-radius:0}.coar-month-bar--clipped-end[data-v-aae90a51]{border-top-right-radius:0;border-bottom-right-radius:0}.coar-month-bar[data-v-aae90a51]:focus{outline:2px solid var(--coar-background-accent-primary,#2563eb);outline-offset:1px}.coar-month-bar--ghost[data-v-aae90a51]{pointer-events:none;outline:2px dashed var(--coar-background-accent-primary,#2563eb);outline-offset:1px;box-shadow:0 4px 12px #0000001f}.coar-month-bar--source-phantom[data-v-aae90a51]{opacity:.4;pointer-events:none;cursor:grabbing}.coar-month-bar--invalid[data-v-aae90a51]{pointer-events:none;cursor:not-allowed;opacity:.7;outline:2px dashed var(--coar-color-danger,#dc2626);outline-offset:1px;background-image:repeating-linear-gradient(45deg,#dc26262e 0 6px,#0000 6px 12px);box-shadow:0 4px 12px #dc262626}.coar-month-bar__title[data-v-aae90a51]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;font-weight:600;overflow:hidden}.coar-month-bar__resize[data-v-aae90a51]{cursor:ew-resize;-webkit-user-select:none;user-select:none;pointer-events:auto;z-index:2;width:6px;position:absolute;top:0;bottom:0}.coar-month-bar__resize--start[data-v-aae90a51]{left:0}.coar-month-bar__resize--end[data-v-aae90a51]{right:0}.coar-month-bar--snap-back[data-v-aae90a51]{animation:.22s ease-out forwards coar-month-bar-snap-back-aae90a51}@keyframes coar-month-bar-snap-back-aae90a51{0%{opacity:.7;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@media (prefers-reduced-motion:reduce){.coar-month-bar--snap-back[data-v-aae90a51]{opacity:0;animation:none}}.coar-month-bar--density-compact[data-v-aae90a51]{padding:0 4px;font-size:10px}.coar-month-cell[data-v-a2e2a614]{border-left:1px solid var(--coar-calendar-border,#d1d5db);cursor:pointer;background:var(--coar-calendar-bg,#fff);contain:layout paint;flex-direction:column;min-width:0;min-height:0;display:flex;position:relative}.coar-month-cell[data-v-a2e2a614]:first-child{border-left:none}.coar-month-cell--weekend[data-v-a2e2a614]{background:var(--coar-calendar-bg-weekend,#f6f7f9)}.coar-month-cell--other-month[data-v-a2e2a614]{background:var(--coar-calendar-bg-other-month,#fafafb);color:var(--coar-text-subtle,#9ca3af)}.coar-month-cell--today[data-v-a2e2a614]{background:var(--coar-calendar-bg-today,#2563eb0a)}.coar-month-cell__day-number-row[data-v-a2e2a614]{box-sizing:border-box;align-items:center;height:24px;padding:4px 6px;display:flex}.coar-month-cell__day-number[data-v-a2e2a614]{font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-base,#1a1c1f);font-weight:600}.coar-month-cell--today .coar-month-cell__day-number[data-v-a2e2a614]{color:var(--coar-color-accent,#2563eb)}.coar-month-cell--other-month .coar-month-cell__day-number[data-v-a2e2a614]{color:var(--coar-text-subtle,#9ca3af);font-weight:500}.coar-month-cell__pills[data-v-a2e2a614]{scrollbar-width:thin;scrollbar-color:var(--coar-border-neutral-tertiary,#d1d5db) transparent;flex-direction:column;flex:1 1 0;gap:2px;min-height:0;padding:3px 4px 4px;display:flex;overflow-y:auto}.coar-month-cell__pills[data-v-a2e2a614]::-webkit-scrollbar{width:6px}.coar-month-cell__pills[data-v-a2e2a614]::-webkit-scrollbar-thumb{background:var(--coar-border-neutral-tertiary,#d1d5db);border-radius:3px}.coar-month-cell__pills[data-v-a2e2a614]::-webkit-scrollbar-track{background:0 0}.coar-month-cell__menu-trigger[data-v-a2e2a614]{cursor:pointer;width:18px;height:18px;color:var(--coar-text-subtle,#6c7280);border-radius:var(--coar-radius-xs,2px);background:0 0;border:0;justify-content:center;align-items:center;margin-left:auto;padding:0;display:inline-flex}.coar-month-cell__menu-trigger[data-v-a2e2a614]:hover,.coar-month-cell__menu-trigger[data-v-a2e2a614]:focus-visible,.coar-month-cell__menu-trigger[aria-expanded=true][data-v-a2e2a614]{background:var(--coar-background-neutral-tertiary,#f3f4f6);color:var(--coar-text-base,#1a1c1f)}@media (hover:hover){.coar-month-cell__menu-trigger[data-v-a2e2a614]{opacity:0}.coar-month-cell:hover .coar-month-cell__menu-trigger[data-v-a2e2a614],.coar-month-cell__menu-trigger[data-v-a2e2a614]:focus-visible,.coar-month-cell__menu-trigger[aria-expanded=true][data-v-a2e2a614]{opacity:1}}.coar-month-row[data-v-8f7c41d6]{border-bottom:1px solid var(--coar-calendar-border,#d1d5db);grid-template-columns:repeat(7,1fr);min-height:100px;transition:height .2s ease-out;display:grid;position:relative}@media (prefers-reduced-motion:reduce){.coar-month-row[data-v-8f7c41d6]{transition:none}}.coar-month-row[data-v-8f7c41d6]:last-child{border-bottom:none}.coar-month-row--density-compact[data-v-8f7c41d6]{min-height:80px}.coar-month-grid[data-v-d0d74cdf]{display:contents}.coar-month-grid__weekday-row[data-v-d0d74cdf]{border-bottom:1px solid var(--coar-calendar-border,#d1d5db);z-index:5;background:var(--coar-calendar-bg,#fff);grid-template-columns:repeat(7,1fr);display:grid;position:sticky;top:0}.coar-month-grid__weekday-cell[data-v-d0d74cdf]{font-size:var(--coar-font-size-xs,11px);text-transform:uppercase;letter-spacing:.04em;color:var(--coar-text-subtle,#6c7280);border-left:1px solid var(--coar-calendar-border,#d1d5db);padding:8px 12px;font-weight:600}.coar-month-grid__weekday-cell[data-v-d0d74cdf]:first-child{border-left:none}.coar-month-view__a11y-live[data-v-8b07a2bc]{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.coar-month-view[data-v-8b07a2bc]{background:var(--coar-calendar-bg,#fff);font-family:var(--coar-body-base-family,system-ui, sans-serif);font-variant-numeric:tabular-nums;flex-direction:column;display:flex}.coar-month-view__pill-title[data-v-8b07a2bc]{color:var(--coar-text-base,#1a1c1f);font-weight:600}.coar-month-view__bar-title[data-v-8b07a2bc]{color:var(--coar-text-base,#1a1c1f);text-overflow:ellipsis;font-weight:600;overflow:hidden}.coar-virtualized-surface-1dy[data-v-50d47c8e]{contain:strict;position:relative;overflow:hidden auto}.coar-virtualized-surface-1dy__spacer[data-v-50d47c8e]{width:100%;position:relative}.coar-virtualized-surface-1dy__item[data-v-50d47c8e]{contain:layout paint style;position:absolute;top:0;left:0;right:0}.coar-agenda-day-header[data-v-990c502f]{background:var(--coar-calendar-bg,#fff);border-bottom:1px solid var(--coar-calendar-border,#e3e5e9);font-weight:600;font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-base,#1a1c1f);align-items:baseline;gap:8px;padding:8px 16px;display:flex}.coar-agenda-day-header--today[data-v-990c502f]{color:var(--coar-color-accent,#2563eb)}.coar-agenda-day-header--empty[data-v-990c502f]{color:var(--coar-text-subtle,#9ca3af);font-style:italic}.coar-agenda-day-header--floating[data-v-990c502f]{z-index:10;will-change:transform;margin-right:14px;position:absolute;top:0;left:0;right:0}.coar-agenda-day-header__today[data-v-990c502f]{font-size:var(--coar-font-size-xs,11px);text-transform:uppercase;letter-spacing:.05em;background:var(--coar-color-accent,#2563eb);color:#fff;border-radius:999px;padding:2px 8px;font-weight:700}.coar-agenda-event[data-v-12cce1c9]{border-bottom:1px solid var(--coar-calendar-border,#f3f4f6);cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--coar-calendar-bg,#fff);padding:10px 16px;transition:background-color 80ms}.coar-agenda-event[data-v-12cce1c9]:hover{background:var(--coar-surface-subtle,#f6f7f9)}.coar-agenda-event--continuation[data-v-12cce1c9]{opacity:.7}.coar-agenda-event__default[data-v-12cce1c9]{align-items:center;gap:12px;display:flex}.coar-agenda-event__color[data-v-12cce1c9]{border-radius:50%;flex:none;width:8px;height:8px}.coar-agenda-event__time[data-v-12cce1c9]{font-size:var(--coar-font-size-sm,13px);color:var(--coar-text-subtle,#6c7280);font-variant-numeric:tabular-nums;min-width:80px}.coar-agenda-event__title[data-v-12cce1c9]{font-size:var(--coar-font-size-base,14px);color:var(--coar-text-base,#1a1c1f);font-weight:500}.coar-agenda-event__continuation-tag[data-v-12cce1c9]{font-size:var(--coar-font-size-xs,11px);color:var(--coar-text-subtle,#9ca3af);margin-left:6px;font-style:italic;font-weight:400}.coar-agenda-view[data-v-7a664b01]{background:var(--coar-calendar-bg,#fff);font-family:var(--coar-body-base-family,system-ui, sans-serif);height:100%;position:relative;overflow:hidden}.coar-agenda-view__surface[data-v-7a664b01]{height:100%}.coar-timeline-view[data-v-b47f606a]{width:100%;height:100%;font-family:var(--coar-body-base-family);font-size:var(--coar-body-s-size,13px);background:var(--coar-background-neutral-primary);cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none;display:block;overflow:auto}.coar-timeline-view--panning[data-v-b47f606a]{cursor:grabbing}.coar-timeline-view .coar-timeline-view__bar[data-v-b47f606a]{cursor:pointer}.coar-timeline-view--panning .coar-timeline-view__bar[data-v-b47f606a]{cursor:grabbing}.coar-timeline-view__grid[data-v-b47f606a]{display:grid;position:relative}.coar-timeline-view__corner[data-v-b47f606a]{z-index:3;background:var(--coar-background-neutral-secondary);border-right:1px solid var(--coar-border-neutral-tertiary);border-bottom:1px solid var(--coar-border-neutral-tertiary);padding:0 var(--coar-spacing-s,8px);grid-area:1/1;align-items:center;display:flex;position:sticky;top:0;left:0}.coar-timeline-view__corner-title[data-v-b47f606a]{color:var(--coar-text-neutral-secondary);text-transform:uppercase;letter-spacing:.05em;font-size:11px;font-weight:600}.coar-timeline-view__date-axis[data-v-b47f606a]{z-index:2;background:var(--coar-background-neutral-secondary);border-bottom:1px solid var(--coar-border-neutral-tertiary);grid-area:1/2;display:flex;position:sticky;top:0}.coar-timeline-view__date-cell[data-v-b47f606a]{box-sizing:border-box;border-right:1px solid var(--coar-border-neutral-tertiary);color:var(--coar-text-neutral-secondary);flex:none;justify-content:center;align-items:center;font-size:11px;display:flex}.coar-timeline-view__date-cell--today[data-v-b47f606a]{background:var(--coar-background-accent-soft,#eff6ff);color:var(--coar-text-accent,#2563eb);font-weight:600}.coar-timeline-view__date-cell--weekend[data-v-b47f606a]{background:var(--coar-background-neutral-tertiary,#f5f5f5)}.coar-timeline-view__label-column[data-v-b47f606a]{z-index:2;background:var(--coar-background-neutral-primary);border-right:1px solid var(--coar-border-neutral-tertiary);grid-area:2/1;position:sticky;left:0}.coar-timeline-view__label-inner[data-v-b47f606a]{width:100%;position:relative}.coar-timeline-view__label-row[data-v-b47f606a]{padding:0 var(--coar-spacing-s,8px);border-bottom:1px solid var(--coar-border-neutral-tertiary);box-sizing:border-box;align-items:center;gap:6px;display:flex;position:absolute;left:0;right:0;overflow:hidden}.coar-timeline-view__label-text[data-v-b47f606a]{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;font-weight:500;overflow:hidden}.coar-timeline-view__label-count[data-v-b47f606a]{color:var(--coar-text-neutral-secondary);font-variant-numeric:tabular-nums;background:var(--coar-background-neutral-tertiary,#f5f5f5);border-radius:9999px;flex:none;padding:1px 6px;font-size:11px}.coar-timeline-view__bars-area[data-v-b47f606a]{grid-area:2/2;position:relative}.coar-timeline-view__day-grid-bg[data-v-b47f606a]{pointer-events:none;z-index:0;display:flex;position:absolute;inset:0}.coar-timeline-view__day-grid-cell[data-v-b47f606a]{box-sizing:border-box;border-right:1px solid var(--coar-border-neutral-tertiary);flex:none;height:100%}.coar-timeline-view__day-grid-cell--weekend[data-v-b47f606a]{background:var(--coar-background-neutral-tertiary,#f5f5f5);opacity:.4}.coar-timeline-view__bar[data-v-b47f606a]{border-radius:var(--coar-radius-xs,4px);color:#fff;text-align:left;cursor:pointer;text-overflow:ellipsis;white-space:nowrap;z-index:1;border:none;padding:0 8px;font-size:12px;font-weight:500;transition:filter .1s;position:absolute;overflow:hidden}.coar-timeline-view__bar[data-v-b47f606a]:hover{filter:brightness(1.05)}.coar-timeline-view__bar[data-v-b47f606a]:focus-visible{outline:2px solid var(--coar-border-accent,#2563eb);outline-offset:2px}.coar-timeline-view__bar--clipped-start[data-v-b47f606a]{border-top-left-radius:0;border-bottom-left-radius:0}.coar-timeline-view__bar--clipped-end[data-v-b47f606a]{border-top-right-radius:0;border-bottom-right-radius:0}.coar-timeline-view__bar-label[data-v-b47f606a]{text-overflow:ellipsis;white-space:nowrap;display:inline-block;overflow:hidden}.coar-calendar[data-v-b56d4847]{background:var(--coar-background-neutral-primary);height:100%;font-family:var(--coar-body-base-family);color:var(--coar-text-neutral-primary);flex-direction:column;display:flex}.coar-calendar__header[data-v-b56d4847]{align-items:center;gap:var(--coar-spacing-m);padding:var(--coar-spacing-s) var(--coar-spacing-m);border-bottom:1px solid var(--coar-border-neutral-tertiary);background:var(--coar-background-neutral-primary);flex:none;display:flex}.coar-calendar__nav[data-v-b56d4847]{align-items:center;gap:var(--coar-spacing-xs);display:flex}.coar-calendar__range-label[data-v-b56d4847]{font-size:var(--coar-component-m-font-size);color:var(--coar-text-neutral-primary);white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.coar-calendar__spacer[data-v-b56d4847]{flex:auto}.coar-calendar__body[data-v-b56d4847]{flex:auto;min-height:0}.coar-calendar__body--day[data-v-b56d4847],.coar-calendar__body--week[data-v-b56d4847],.coar-calendar__body--month[data-v-b56d4847]{overflow:hidden auto}.coar-calendar__body--agenda[data-v-b56d4847]{overflow:hidden}.coar-virtualized-surface-2d[data-v-fbba32db]{contain:strict;position:relative;overflow:auto}.coar-virtualized-surface-2d__spacer[data-v-fbba32db]{position:relative}.coar-virtualized-surface-2d__cell[data-v-fbba32db]{contain:layout paint size style;box-sizing:border-box;position:absolute;top:0;left:0}
2
2
  /*$vite$:1*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocoar/vue-calendar",
3
- "version": "1.18.0",
3
+ "version": "2.1.0",
4
4
  "description": "Vue 3 calendar component — Temporal-only public surface, single drop pipeline, per-endpoint source-zone preservation, explicit DST policy. Built on the principles laid out in the Time in Software, Done Right article series.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -37,6 +37,14 @@
37
37
  "./core": {
38
38
  "import": "./dist/core.js",
39
39
  "types": "./dist/core.d.ts"
40
+ },
41
+ "./recurrence": {
42
+ "import": "./dist/recurrence.js",
43
+ "types": "./dist/recurrence.d.ts"
44
+ },
45
+ "./recurrence-rrule-temporal": {
46
+ "import": "./dist/recurrence-rrule-temporal.js",
47
+ "types": "./dist/recurrence-rrule-temporal.d.ts"
40
48
  }
41
49
  },
42
50
  "files": [
@@ -50,20 +58,17 @@
50
58
  },
51
59
  "dependencies": {
52
60
  "@js-temporal/polyfill": "^0.5.1",
53
- "@napi-rs/wasm-runtime": "^1.1.4",
54
- "rrule-rust": "~3.1.1"
61
+ "rrule-temporal": "~1.5.3"
55
62
  },
56
63
  "peerDependencies": {
57
- "@cocoar/vue-localization": "1.18.0",
58
- "@cocoar/vue-ui": "1.18.0",
64
+ "@cocoar/vue-localization": "2.1.0",
65
+ "@cocoar/vue-ui": "2.1.0",
59
66
  "vue": "^3.5.0"
60
67
  },
61
68
  "devDependencies": {
62
69
  "@cocoar/vue-localization": "workspace:*",
63
70
  "@cocoar/vue-ui": "workspace:*",
64
71
  "fast-check": "^4.7.0",
65
- "rrule": "~2.8.1",
66
- "rrule-temporal": "~1.5.3",
67
72
  "vue": "^3.5.32"
68
73
  }
69
74
  }
@@ -1,59 +0,0 @@
1
- import { Temporal } from '@js-temporal/polyfill';
2
- import { CalendarEvent, RecurrenceExpansionWindow, RecurringSeries } from './types';
3
- import { DstPolicy } from './dnd/move-math';
4
- /**
5
- * Expand a `RecurringSeries` into the concrete occurrences that fall
6
- * within `window`, applying `dstPolicy` to any occurrence whose
7
- * wall-time hits a DST gap or overlap in the series' source zone.
8
- *
9
- * **Inputs**
10
- *
11
- * - `series` — the rule + dtstart + optional duration / rdate / exdate.
12
- * - `window` — inclusive-start / exclusive-end. Typically the
13
- * calendar's `_visibleRange` plus a small overscan.
14
- * - `dstPolicy` — required (C4). Same options as the drag pipeline.
15
- *
16
- * **Output**
17
- *
18
- * `CalendarEvent<TMeta>[]` where every occurrence:
19
- * - shares the series' `id` (use `start` to distinguish).
20
- * - has `start` typed identically to `series.dtstart` (timed → ZDT,
21
- * all-day → PD).
22
- * - has `start.timeZoneId === series.dtstart.timeZoneId` for timed
23
- * series — the engine never collapses to UTC or to the calendar's
24
- * display zone.
25
- * - has `end` computed from `series.duration` if present.
26
- * - has `meta` shallow-copied from `series.meta`.
27
- *
28
- * **Throws**
29
- *
30
- * Until Phase 4: a `TypeError` with an informative message. Consumers
31
- * can rely on the type contract NOW; expansion arrives without an
32
- * API change.
33
- *
34
- * After Phase 4 (planned): a `DstResolutionError` if any occurrence
35
- * lands in a DST gap/overlap and `dstPolicy === 'reject'`.
36
- */
37
- export declare function expandSeries<TMeta extends Record<string, unknown> = Record<string, unknown>>(_series: RecurringSeries<TMeta>, _window: RecurrenceExpansionWindow, _dstPolicy: DstPolicy): CalendarEvent<TMeta>[];
38
- /**
39
- * Re-export for ergonomics — consumers usually `import { expandSeries }`
40
- * alongside the types they're constructing.
41
- *
42
- * Session 2 also re-uses this constant in tests to assert the stub
43
- * shape without duplicating the message.
44
- */
45
- export declare const EXPAND_SERIES_NOT_IMPLEMENTED_MESSAGE = "[@cocoar/vue-calendar] expandSeries() is not implemented yet \u2014 the recurrence engine integration is Phase 4. The TYPE contract for RecurringSeries is enforced from Session 2 so your data layer can build against it now; expansion will become available without API changes.";
46
- /**
47
- * Type-only re-exports so consumers writing `import { ... } from '@cocoar/vue-calendar'`
48
- * find the recurrence types alongside `expandSeries` without needing
49
- * to know they were declared in `core/types.ts`.
50
- */
51
- export type { RecurringSeries, RecurrencePattern, RecurrenceExpansionWindow, } from './types';
52
- /**
53
- * Re-exported `Temporal` for convenience when constructing series.
54
- *
55
- * Without it consumers would have to add a separate
56
- * `@js-temporal/polyfill` import for `Temporal.ZonedDateTime.from(...)`.
57
- */
58
- export type { Temporal };
59
- //# sourceMappingURL=recurrence-public.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"recurrence-public.d.ts","sourceRoot":"","sources":["../../src/core/recurrence-public.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EACV,aAAa,EACb,yBAAyB,EACzB,eAAe,EAChB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAKjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,YAAY,CAC1B,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAG/D,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAE/B,OAAO,EAAE,yBAAyB,EAElC,UAAU,EAAE,SAAS,GACpB,aAAa,CAAC,KAAK,CAAC,EAAE,CAExB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qCAAqC,yRAAkB,CAAC;AAErE;;;;GAIG;AACH,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AAEjB;;;;;GAKG;AACH,YAAY,EAAE,QAAQ,EAAE,CAAC"}