@marco.colia/react-fast-scheduler 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +273 -136
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,22 +1,52 @@
|
|
|
1
1
|
# react-fast-scheduler
|
|
2
2
|
|
|
3
|
-
A lightweight React
|
|
3
|
+
A lightweight React day scheduler for resource-based booking UIs.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`react-fast-scheduler` gives you a controlled day view with:
|
|
6
|
+
|
|
7
|
+
- resource columns for staff, rooms, or assets
|
|
8
|
+
- drag and resize interactions
|
|
9
|
+
- date navigation with a built-in toolbar and date picker
|
|
10
|
+
- customizable appointment rendering
|
|
11
|
+
- a simple adapter layer for your backend data
|
|
12
|
+
|
|
13
|
+

|
|
6
14
|
|
|
7
15
|
## Install
|
|
8
16
|
|
|
9
17
|
```bash
|
|
10
|
-
npm
|
|
18
|
+
npm install @marco.colia/react-fast-scheduler
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Peer dependencies:
|
|
22
|
+
|
|
23
|
+
- `react` `^18 || ^19`
|
|
24
|
+
- `react-dom` `^18 || ^19`
|
|
25
|
+
|
|
26
|
+
Import the packaged styles once in your app:
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import "@marco.colia/react-fast-scheduler/styles.css";
|
|
11
30
|
```
|
|
12
31
|
|
|
13
|
-
##
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
The scheduler is a controlled component:
|
|
35
|
+
|
|
36
|
+
- your app owns `selectedDate`
|
|
37
|
+
- your app fetches appointments for that date
|
|
38
|
+
- the scheduler calls `onSelectedDateChange` when the user navigates
|
|
39
|
+
- your app updates `appointments` and passes the new data back in
|
|
14
40
|
|
|
15
41
|
```tsx
|
|
16
42
|
import { useEffect, useState } from "react";
|
|
17
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
Scheduler,
|
|
45
|
+
applySchedulerAppointmentChange,
|
|
46
|
+
type BaseSchedulerResource,
|
|
47
|
+
type SchedulerAppointmentChangeArgs,
|
|
48
|
+
} from "@marco.colia/react-fast-scheduler";
|
|
18
49
|
import "@marco.colia/react-fast-scheduler/styles.css";
|
|
19
|
-
import type { BaseSchedulerResource } from "@marco.colia/react-fast-scheduler";
|
|
20
50
|
|
|
21
51
|
type Staff = BaseSchedulerResource<number> & {
|
|
22
52
|
firstName: string;
|
|
@@ -26,17 +56,24 @@ type Staff = BaseSchedulerResource<number> & {
|
|
|
26
56
|
type Appointment = {
|
|
27
57
|
id: number;
|
|
28
58
|
staffId: number;
|
|
29
|
-
description?: string;
|
|
30
59
|
customerName: string;
|
|
31
60
|
title: string;
|
|
32
|
-
|
|
33
|
-
|
|
61
|
+
description?: string;
|
|
62
|
+
start: string;
|
|
63
|
+
end: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const formatLocalDate = (date: Date) => {
|
|
67
|
+
const year = date.getFullYear();
|
|
68
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
69
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
70
|
+
return `${year}-${month}-${day}`;
|
|
34
71
|
};
|
|
35
72
|
|
|
36
|
-
export
|
|
73
|
+
export const SchedulerExample = () => {
|
|
37
74
|
const [staff, setStaff] = useState<Staff[]>([]);
|
|
38
|
-
const [selectedDate, setSelectedDate] = useState(new Date("2026-03-20T00:00:00.000Z"));
|
|
39
75
|
const [appointments, setAppointments] = useState<Appointment[]>([]);
|
|
76
|
+
const [selectedDate, setSelectedDate] = useState(() => new Date());
|
|
40
77
|
|
|
41
78
|
const loadStaff = async () => {
|
|
42
79
|
const response = await fetch("/api/staff");
|
|
@@ -45,44 +82,46 @@ export function SchedulerExample() {
|
|
|
45
82
|
};
|
|
46
83
|
|
|
47
84
|
const loadAppointments = async (date: Date) => {
|
|
48
|
-
const
|
|
49
|
-
const response = await fetch(`/api/appointments?date=${isoDate}`);
|
|
85
|
+
const response = await fetch(`/api/appointments?date=${formatLocalDate(date)}`);
|
|
50
86
|
const data = (await response.json()) as Appointment[];
|
|
51
87
|
setAppointments(data);
|
|
52
88
|
};
|
|
53
89
|
|
|
54
|
-
const
|
|
90
|
+
const persistAppointment = async (
|
|
91
|
+
appointmentId: number,
|
|
92
|
+
nextAppointment: Appointment
|
|
93
|
+
) => {
|
|
55
94
|
await fetch(`/api/appointments/${appointmentId}`, {
|
|
56
95
|
method: "PATCH",
|
|
57
96
|
headers: { "Content-Type": "application/json" },
|
|
58
|
-
body: JSON.stringify(
|
|
97
|
+
body: JSON.stringify(nextAppointment),
|
|
59
98
|
});
|
|
60
99
|
};
|
|
61
100
|
|
|
62
|
-
const handleAppointmentChange = async (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
101
|
+
const handleAppointmentChange = async (
|
|
102
|
+
change: SchedulerAppointmentChangeArgs<Appointment, number>
|
|
103
|
+
) => {
|
|
104
|
+
const optimisticAppointments = applySchedulerAppointmentChange(appointments, change, {
|
|
105
|
+
getId: (item) => item.id,
|
|
106
|
+
setResourceId: (item, resourceId) => ({ ...item, staffId: resourceId }),
|
|
107
|
+
setStart: (item, start) => ({ ...item, start: start.toISOString() }),
|
|
108
|
+
setEnd: (item, end) => ({ ...item, end: end.toISOString() }),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
setAppointments(optimisticAppointments);
|
|
112
|
+
|
|
113
|
+
const nextAppointment = optimisticAppointments.find(
|
|
114
|
+
(item) => item.id === change.appointment.id
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
if (!nextAppointment) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
69
120
|
|
|
70
121
|
try {
|
|
71
|
-
await
|
|
72
|
-
await loadAppointments(selectedDate);
|
|
122
|
+
await persistAppointment(change.appointment.id, nextAppointment);
|
|
73
123
|
} catch {
|
|
74
|
-
|
|
75
|
-
current.map((item) =>
|
|
76
|
-
item.id === appointment.id
|
|
77
|
-
? {
|
|
78
|
-
...item,
|
|
79
|
-
staffId: previous.resourceId,
|
|
80
|
-
start: previous.start.toISOString(),
|
|
81
|
-
end: previous.end.toISOString(),
|
|
82
|
-
}
|
|
83
|
-
: item
|
|
84
|
-
)
|
|
85
|
-
);
|
|
124
|
+
await loadAppointments(selectedDate);
|
|
86
125
|
}
|
|
87
126
|
};
|
|
88
127
|
|
|
@@ -100,73 +139,168 @@ export function SchedulerExample() {
|
|
|
100
139
|
appointments={appointments}
|
|
101
140
|
selectedDate={selectedDate}
|
|
102
141
|
onSelectedDateChange={setSelectedDate}
|
|
103
|
-
prevButtonLabel="Previous day"
|
|
104
|
-
nextButtonLabel="Next day"
|
|
105
142
|
adapter={{
|
|
106
|
-
getId: (
|
|
107
|
-
getResourceId: (
|
|
108
|
-
getStart: (
|
|
109
|
-
getEnd: (
|
|
110
|
-
getTitle: (
|
|
143
|
+
getId: (item) => item.id,
|
|
144
|
+
getResourceId: (item) => item.staffId,
|
|
145
|
+
getStart: (item) => item.start,
|
|
146
|
+
getEnd: (item) => item.end,
|
|
147
|
+
getTitle: (item) => `${item.customerName} - ${item.title}`,
|
|
111
148
|
}}
|
|
112
149
|
onAppointmentChange={handleAppointmentChange}
|
|
113
|
-
resourceAppointmentClassMap={{
|
|
114
|
-
"1": "bg-amber-100 dark:bg-amber-950/40",
|
|
115
|
-
"2": "bg-blue-100 dark:bg-blue-950/40",
|
|
116
|
-
}}
|
|
117
150
|
dayStart="09:00"
|
|
118
151
|
dayEnd="18:00"
|
|
119
152
|
/>
|
|
120
153
|
);
|
|
121
|
-
}
|
|
154
|
+
};
|
|
122
155
|
```
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
During move drag, the scheduler keeps the original card in place and renders a floating ghost preview by default.
|
|
126
|
-
`renderToolbar` is optional. If you omit it, the scheduler uses a built-in shadcn-style toolbar with prev/next buttons and a calendar popover date picker.
|
|
127
|
-
`renderDatePicker` is optional. If you omit it, the default toolbar uses the built-in calendar popover date picker.
|
|
128
|
-
`onAppointmentChange` is the main integration point for state updates and API persistence.
|
|
157
|
+
## How Data Flow Works
|
|
129
158
|
|
|
130
|
-
|
|
159
|
+
When the user changes the day from the built-in toolbar or date picker:
|
|
131
160
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
- `resourceAppointmentClassMap`: optional map of `resourceId -> className` for per-resource appointment colors/styles.
|
|
138
|
-
- `getResourceAppointmentColorToken`: optional function to provide a semantic color token per resource (for example `"amber"`).
|
|
139
|
-
- `appointmentColorTokenClassMap`: optional map to override token -> class resolution.
|
|
140
|
-
- `getResourceAppointmentAppearance`: optional low-level function to provide appointment `className` per resource.
|
|
141
|
-
- `getResourceAppointmentBackground`: legacy optional function to provide appointment background as a string.
|
|
142
|
-
- `renderToolbar`: optional render hook to replace the entire scheduler toolbar/header controls.
|
|
143
|
-
- `prevButtonLabel` and `nextButtonLabel`: custom labels for toolbar navigation buttons.
|
|
144
|
-
- `renderDatePicker`: optional render hook for the date picker slot used by the default toolbar.
|
|
145
|
-
- `renderResourceHeader`: optional render hook for resource column headers.
|
|
146
|
-
- `renderAppointment`: optional render hook to fully customize appointment cards.
|
|
161
|
+
1. the scheduler calls `onSelectedDateChange(nextDate)`
|
|
162
|
+
2. your state updates `selectedDate`
|
|
163
|
+
3. your `useEffect` runs again
|
|
164
|
+
4. your app fetches appointments for the new date
|
|
165
|
+
5. you pass the fetched appointments back into `appointments`
|
|
147
166
|
|
|
148
|
-
|
|
167
|
+
This is the intended integration pattern:
|
|
149
168
|
|
|
150
|
-
|
|
151
|
-
|
|
169
|
+
```tsx
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
void loadAppointments(selectedDate);
|
|
172
|
+
}, [selectedDate]);
|
|
152
173
|
|
|
153
|
-
|
|
174
|
+
<Scheduler
|
|
175
|
+
selectedDate={selectedDate}
|
|
176
|
+
onSelectedDateChange={setSelectedDate}
|
|
177
|
+
appointments={appointments}
|
|
178
|
+
resources={resources}
|
|
179
|
+
adapter={adapter}
|
|
180
|
+
/>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Core Concepts
|
|
184
|
+
|
|
185
|
+
### `resources`
|
|
186
|
+
|
|
187
|
+
Each column in the scheduler is a resource. A resource must have at least:
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
type BaseSchedulerResource<TId> = {
|
|
191
|
+
id: TId;
|
|
192
|
+
label: string;
|
|
193
|
+
};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Typical resources:
|
|
197
|
+
|
|
198
|
+
- staff members
|
|
199
|
+
- rooms
|
|
200
|
+
- desks
|
|
201
|
+
- service stations
|
|
202
|
+
|
|
203
|
+
### `appointments`
|
|
154
204
|
|
|
155
|
-
|
|
205
|
+
Appointments stay in your own shape. The scheduler reads them through the `adapter`.
|
|
156
206
|
|
|
157
|
-
###
|
|
207
|
+
### `adapter`
|
|
208
|
+
|
|
209
|
+
The adapter maps your appointment structure into scheduler fields:
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
adapter={{
|
|
213
|
+
getId: (item) => item.id,
|
|
214
|
+
getResourceId: (item) => item.staffId,
|
|
215
|
+
getStart: (item) => item.start,
|
|
216
|
+
getEnd: (item) => item.end,
|
|
217
|
+
getTitle: (item) => item.title,
|
|
218
|
+
}}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
`getStart` and `getEnd` can return either a `Date` or a date string.
|
|
222
|
+
|
|
223
|
+
## Drag, Resize, and Persistence
|
|
224
|
+
|
|
225
|
+
Use `onAppointmentChange` as the main integration point for move and resize operations.
|
|
226
|
+
|
|
227
|
+
It receives:
|
|
228
|
+
|
|
229
|
+
- `appointment`: the original raw appointment
|
|
230
|
+
- `previous`: the previous resource and time range
|
|
231
|
+
- `next`: the new resource and time range after drop
|
|
232
|
+
- `kind`: `"move"` or `"resize"`
|
|
233
|
+
|
|
234
|
+
Example:
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
<Scheduler
|
|
238
|
+
// ...other props
|
|
239
|
+
onAppointmentChange={async ({ appointment, next }) => {
|
|
240
|
+
const nextAppointment = {
|
|
241
|
+
...appointment,
|
|
242
|
+
staffId: next.resourceId,
|
|
243
|
+
start: next.start.toISOString(),
|
|
244
|
+
end: next.end.toISOString(),
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
await fetch(`/api/appointments/${appointment.id}`, {
|
|
248
|
+
method: "PATCH",
|
|
249
|
+
headers: { "Content-Type": "application/json" },
|
|
250
|
+
body: JSON.stringify(nextAppointment),
|
|
251
|
+
});
|
|
252
|
+
}}
|
|
253
|
+
/>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
If you want a small helper for optimistic local state updates, use `applySchedulerAppointmentChange`:
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
const nextAppointments = applySchedulerAppointmentChange(appointments, change, {
|
|
260
|
+
getId: (item) => item.id,
|
|
261
|
+
setResourceId: (item, resourceId) => ({ ...item, staffId: resourceId }),
|
|
262
|
+
setStart: (item, start) => ({ ...item, start: start.toISOString() }),
|
|
263
|
+
setEnd: (item, end) => ({ ...item, end: end.toISOString() }),
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
`onPersistMoveResize` is still available as a legacy callback, but `onAppointmentChange` is the recommended API.
|
|
268
|
+
|
|
269
|
+
## Styling
|
|
270
|
+
|
|
271
|
+
The package ships precompiled CSS:
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
import "@marco.colia/react-fast-scheduler/styles.css";
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
You can override the exposed CSS variables in your app:
|
|
278
|
+
|
|
279
|
+
```css
|
|
280
|
+
:root {
|
|
281
|
+
--rfs-bg: #f8fafc;
|
|
282
|
+
--rfs-surface: #ffffff;
|
|
283
|
+
--rfs-border: #e2e8f0;
|
|
284
|
+
--rfs-text: #0f172a;
|
|
285
|
+
--rfs-muted: #64748b;
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Resource-based colors
|
|
290
|
+
|
|
291
|
+
The simplest option is `resourceAppointmentClassMap`:
|
|
158
292
|
|
|
159
293
|
```tsx
|
|
160
294
|
<Scheduler
|
|
161
295
|
// ...other props
|
|
162
296
|
resourceAppointmentClassMap={{
|
|
163
|
-
"
|
|
164
|
-
"
|
|
297
|
+
"1": "bg-amber-100 dark:bg-amber-950/40",
|
|
298
|
+
"2": "bg-blue-100 dark:bg-blue-950/40",
|
|
165
299
|
}}
|
|
166
300
|
/>
|
|
167
301
|
```
|
|
168
302
|
|
|
169
|
-
|
|
303
|
+
If you want semantic mapping, use `getResourceAppointmentColorToken` plus `appointmentColorTokenClassMap`:
|
|
170
304
|
|
|
171
305
|
```tsx
|
|
172
306
|
<Scheduler
|
|
@@ -179,7 +313,24 @@ The `renderAppointment` args also include:
|
|
|
179
313
|
/>
|
|
180
314
|
```
|
|
181
315
|
|
|
182
|
-
|
|
316
|
+
For full control, use `getResourceAppointmentAppearance`.
|
|
317
|
+
|
|
318
|
+
## Custom Rendering
|
|
319
|
+
|
|
320
|
+
### Custom appointment card
|
|
321
|
+
|
|
322
|
+
`renderAppointment` lets you fully replace the built-in card.
|
|
323
|
+
|
|
324
|
+
The appointment passed to your renderer also includes:
|
|
325
|
+
|
|
326
|
+
- `visualState`: `"normal" | "ghost" | "dragging"`
|
|
327
|
+
- `renderKey`: an internal render key
|
|
328
|
+
|
|
329
|
+
The renderer also receives:
|
|
330
|
+
|
|
331
|
+
- `isDropInvalid`: `true` when the current drag position overlaps another appointment
|
|
332
|
+
- `onPointerDown`: attach this to your appointment root for move interactions
|
|
333
|
+
- `onResizePointerDown`: attach this to your resize handle
|
|
183
334
|
|
|
184
335
|
```tsx
|
|
185
336
|
<Scheduler
|
|
@@ -208,11 +359,6 @@ The `renderAppointment` args also include:
|
|
|
208
359
|
}`
|
|
209
360
|
}`}
|
|
210
361
|
>
|
|
211
|
-
{isDropInvalid ? (
|
|
212
|
-
<div className="absolute right-1 top-1 flex h-4 w-4 items-center justify-center rounded-full bg-red-600 text-[10px] font-bold text-white">
|
|
213
|
-
X
|
|
214
|
-
</div>
|
|
215
|
-
) : null}
|
|
216
362
|
<div className="text-xs font-semibold">{appointment.title}</div>
|
|
217
363
|
{appointment.raw.description ? (
|
|
218
364
|
<div className="mt-1 text-[10px] font-medium text-slate-500">
|
|
@@ -222,12 +368,12 @@ The `renderAppointment` args also include:
|
|
|
222
368
|
<div
|
|
223
369
|
role="button"
|
|
224
370
|
aria-label="Resize appointment"
|
|
225
|
-
onPointerDown={(
|
|
371
|
+
onPointerDown={(event) => {
|
|
226
372
|
if (appointment.visualState === "ghost") {
|
|
227
373
|
return;
|
|
228
374
|
}
|
|
229
|
-
|
|
230
|
-
onResizePointerDown(
|
|
375
|
+
event.stopPropagation();
|
|
376
|
+
onResizePointerDown(event);
|
|
231
377
|
}}
|
|
232
378
|
className="absolute inset-x-1 bottom-1 h-2 cursor-ns-resize rounded-full bg-slate-300/90 hover:bg-slate-400"
|
|
233
379
|
/>
|
|
@@ -238,6 +384,10 @@ The `renderAppointment` args also include:
|
|
|
238
384
|
|
|
239
385
|
### Custom toolbar
|
|
240
386
|
|
|
387
|
+
If you omit `renderToolbar`, the scheduler renders a built-in toolbar with previous/next navigation and a date picker.
|
|
388
|
+
|
|
389
|
+
Use `renderToolbar` when you want to replace the whole header:
|
|
390
|
+
|
|
241
391
|
```tsx
|
|
242
392
|
<Scheduler
|
|
243
393
|
// ...other props
|
|
@@ -248,15 +398,11 @@ The `renderAppointment` args also include:
|
|
|
248
398
|
<div className="text-xs text-muted-foreground">Team schedule</div>
|
|
249
399
|
</div>
|
|
250
400
|
<div className="flex items-center gap-2">
|
|
251
|
-
<button
|
|
252
|
-
className="rounded-md border px-3 py-2 text-sm"
|
|
253
|
-
type="button"
|
|
254
|
-
onClick={goToPreviousDay}
|
|
255
|
-
>
|
|
401
|
+
<button type="button" className="rounded-md border px-3 py-2 text-sm" onClick={goToPreviousDay}>
|
|
256
402
|
Previous
|
|
257
403
|
</button>
|
|
258
404
|
{defaultDatePicker}
|
|
259
|
-
<button className="rounded-md border px-3 py-2 text-sm"
|
|
405
|
+
<button type="button" className="rounded-md border px-3 py-2 text-sm" onClick={goToNextDay}>
|
|
260
406
|
Next
|
|
261
407
|
</button>
|
|
262
408
|
</div>
|
|
@@ -267,62 +413,53 @@ The `renderAppointment` args also include:
|
|
|
267
413
|
|
|
268
414
|
### Custom date picker slot
|
|
269
415
|
|
|
270
|
-
|
|
271
|
-
import { Button } from "@/components/ui/button";
|
|
272
|
-
import { Calendar } from "@/components/ui/calendar";
|
|
273
|
-
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
|
416
|
+
If you want to keep the default toolbar but swap the date picker UI, use `renderDatePicker`.
|
|
274
417
|
|
|
418
|
+
```tsx
|
|
275
419
|
<Scheduler
|
|
276
420
|
// ...other props
|
|
277
421
|
renderDatePicker={({ selectedDate, onSelectedDateChange }) => (
|
|
278
|
-
<
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
</PopoverTrigger>
|
|
282
|
-
<PopoverContent className="w-auto p-0">
|
|
283
|
-
<Calendar
|
|
284
|
-
mode="single"
|
|
285
|
-
selected={selectedDate}
|
|
286
|
-
onSelect={(date) => date && onSelectedDateChange(date)}
|
|
287
|
-
initialFocus
|
|
288
|
-
/>
|
|
289
|
-
</PopoverContent>
|
|
290
|
-
</Popover>
|
|
422
|
+
<button type="button" onClick={() => onSelectedDateChange(new Date())}>
|
|
423
|
+
{selectedDate.toDateString()}
|
|
424
|
+
</button>
|
|
291
425
|
)}
|
|
292
|
-
|
|
426
|
+
/>
|
|
293
427
|
```
|
|
294
428
|
|
|
295
|
-
##
|
|
429
|
+
## Props Reference
|
|
296
430
|
|
|
297
|
-
|
|
431
|
+
### Required props
|
|
298
432
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
433
|
+
- `resources`: array of resource objects
|
|
434
|
+
- `appointments`: array of raw appointment objects
|
|
435
|
+
- `selectedDate`: currently visible day
|
|
436
|
+
- `onSelectedDateChange`: controlled date change handler
|
|
437
|
+
- `adapter`: mapper between your appointment shape and scheduler fields
|
|
302
438
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
```tsx
|
|
306
|
-
import React from "react";
|
|
307
|
-
import ReactDOM from "react-dom/client";
|
|
308
|
-
import { SchedulerExample } from "./SchedulerExample";
|
|
309
|
-
import "@marco.colia/react-fast-scheduler/styles.css";
|
|
439
|
+
### Common optional props
|
|
310
440
|
|
|
311
|
-
|
|
312
|
-
|
|
441
|
+
- `onAppointmentChange`: async or sync handler for move and resize persistence
|
|
442
|
+
- `renderToolbar`: replace the full toolbar
|
|
443
|
+
- `renderDatePicker`: replace only the date picker slot used by the default toolbar
|
|
444
|
+
- `renderResourceHeader`: custom resource header renderer
|
|
445
|
+
- `renderAppointment`: custom appointment renderer
|
|
446
|
+
- `resourceAppointmentClassMap`: per-resource class names
|
|
447
|
+
- `getResourceAppointmentColorToken`: semantic color token selector
|
|
448
|
+
- `appointmentColorTokenClassMap`: token-to-class map
|
|
449
|
+
- `getResourceAppointmentAppearance`: low-level class name appearance mapping
|
|
450
|
+
- `getResourceAppointmentBackground`: legacy background string hook
|
|
451
|
+
- `prevButtonLabel`: custom previous button label
|
|
452
|
+
- `nextButtonLabel`: custom next button label
|
|
453
|
+
- `dayStart`: visible schedule start time, for example `"09:00"`
|
|
454
|
+
- `dayEnd`: visible schedule end time, for example `"18:00"`
|
|
313
455
|
|
|
314
|
-
|
|
456
|
+
## Production Notes
|
|
315
457
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
--rfs-border: #e2e8f0;
|
|
321
|
-
--rfs-text: #0f172a;
|
|
322
|
-
--rfs-muted: #64748b;
|
|
323
|
-
}
|
|
324
|
-
```
|
|
458
|
+
- Keep `selectedDate` in application state and fetch data when it changes.
|
|
459
|
+
- Prefer formatting dates in local time for day-based API queries. `toISOString().slice(0, 10)` can shift the day around midnight because it uses UTC.
|
|
460
|
+
- If persistence fails after a drag or resize, either roll back local state or refetch the visible day.
|
|
461
|
+
- Import the package CSS once at app startup.
|
|
325
462
|
|
|
326
463
|
## Development
|
|
327
464
|
|
|
328
|
-
Repo-specific development notes, local demo usage,
|
|
465
|
+
Repo-specific development notes, local demo usage, and release workflow are in [DEVELOPMENT.md](./DEVELOPMENT.md).
|
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-serif:var(--font-serif);--font-mono:var(--font-mono);--color-red-100:oklch(93.6% .032 17.717);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-950:oklch(25.8% .092 26.042);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-950:oklch(26.6% .079 36.259);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-950:oklch(27.9% .077 45.635);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-950:oklch(28.6% .066 53.813);--color-lime-100:oklch(96.7% .067 122.328);--color-lime-950:oklch(27.4% .072 132.109);--color-green-100:oklch(96.2% .044 156.743);--color-green-950:oklch(26.6% .065 152.934);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-950:oklch(26.2% .051 172.552);--color-teal-100:oklch(95.3% .051 180.801);--color-teal-950:oklch(27.7% .046 192.524);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-950:oklch(30.2% .056 229.695);--color-sky-100:oklch(95.1% .026 236.824);--color-sky-950:oklch(29.3% .066 243.157);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-950:oklch(28.2% .091 267.935);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-950:oklch(25.7% .09 281.288);--color-violet-100:oklch(94.3% .029 294.588);--color-violet-950:oklch(28.3% .141 291.089);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-950:oklch(29.1% .149 302.717);--color-fuchsia-100:oklch(95.2% .037 318.852);--color-fuchsia-950:oklch(29.3% .136 325.661);--color-pink-100:oklch(94.8% .028 342.258);--color-pink-950:oklch(28.4% .109 3.907);--color-rose-100:oklch(94.1% .03 12.58);--color-rose-950:oklch(27.1% .105 12.094);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-900:oklch(21% .034 264.665);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-900:oklch(21% .006 285.885);--color-neutral-100:oklch(97% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-stone-100:oklch(97% .001 106.424);--color-stone-900:oklch(21.6% .006 56.043);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-normal:var(--tracking-normal);--leading-tight:1.25;--shadow-2xs:var(--shadow-2xs);--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:var(--shadow-md);--shadow-lg:var(--shadow-lg);--shadow-xl:var(--shadow-xl);--shadow-2xl:var(--shadow-2xl);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--shadow:var(--shadow)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-x-1{inset-inline:calc(var(--spacing) * 1)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-1{top:calc(var(--spacing) * 1)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.bottom-1{bottom:calc(var(--spacing) * 1)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.w-4{width:calc(var(--spacing) * 4)}.w-8{width:calc(var(--spacing) * 8)}.w-72{width:calc(var(--spacing) * 72)}.w-auto{width:auto}.min-w-40{min-width:calc(var(--spacing) * 40)}.min-w-72{min-width:calc(var(--spacing) * 72)}.min-w-\[400px\]{min-width:400px}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-ns-resize{cursor:ns-resize}.resize{resize:both}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.overflow-hidden{overflow:hidden}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-border,.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.border-red-500{border-color:var(--color-red-500)}.border-slate-300{border-color:var(--color-slate-300)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-background{background-color:var(--background)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-border\/90{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.bg-border\/90{background-color:color-mix(in oklab, var(--border) 90%, transparent)}}.bg-card{background-color:var(--card)}.bg-cyan-100{background-color:var(--color-cyan-100)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-fuchsia-100{background-color:var(--color-fuchsia-100)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-green-100{background-color:var(--color-green-100)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-lime-100{background-color:var(--color-lime-100)}.bg-muted\/40{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/40{background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-orange-100{background-color:var(--color-orange-100)}.bg-pink-100{background-color:var(--color-pink-100)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-100\/80{background-color:#ffe2e2cc}@supports (color:color-mix(in lab, red, red)){.bg-red-100\/80{background-color:color-mix(in oklab, var(--color-red-100) 80%, transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-rose-100{background-color:var(--color-rose-100)}.bg-sky-100{background-color:var(--color-sky-100)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-300\/90{background-color:#cad5e2e6}@supports (color:color-mix(in lab, red, red)){.bg-slate-300\/90{background-color:color-mix(in oklab, var(--color-slate-300) 90%, transparent)}}.bg-stone-100{background-color:var(--color-stone-100)}.bg-teal-100{background-color:var(--color-teal-100)}.bg-violet-100{background-color:var(--color-violet-100)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-zinc-100{background-color:var(--color-zinc-100)}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:calc(var(--tracking-normal) - .025em);letter-spacing:calc(var(--tracking-normal) - .025em)}.tracking-wide{--tw-tracking:calc(var(--tracking-normal) + .025em);letter-spacing:calc(var(--tracking-normal) + .025em)}.whitespace-nowrap{white-space:nowrap}.text-foreground{color:var(--foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-950{color:var(--color-red-950)}.text-slate-500{color:var(--color-slate-500)}.text-white{color:var(--color-white)}.opacity-35{opacity:.35}.opacity-55{opacity:.55}.opacity-60{opacity:.6}.shadow-md{--tw-shadow:var(--shadow-md);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:var(--shadow-sm);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:var(--shadow-xl);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:var(--shadow-xs);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-border\/70{--tw-ring-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.ring-border\/70{--tw-ring-color:color-mix(in oklab, var(--border) 70%, transparent)}}.ring-red-500\/60{--tw-ring-color:#fb2c3699}@supports (color:color-mix(in lab, red, red)){.ring-red-500\/60{--tw-ring-color:color-mix(in oklab, var(--color-red-500) 60%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:bg-border:hover{background-color:var(--border)}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-slate-400:hover{background-color:var(--color-slate-400)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:48rem){.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media (min-width:64rem){.lg\:w-full{width:100%}}.dark\:bg-amber-950\/40:is(.dark *){background-color:#46190166}@supports (color:color-mix(in lab, red, red)){.dark\:bg-amber-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-amber-950) 40%, transparent)}}.dark\:bg-blue-950\/40:is(.dark *){background-color:#16245666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-blue-950) 40%, transparent)}}.dark\:bg-cyan-950\/40:is(.dark *){background-color:#05334566}@supports (color:color-mix(in lab, red, red)){.dark\:bg-cyan-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-cyan-950) 40%, transparent)}}.dark\:bg-emerald-950\/40:is(.dark *){background-color:#002c2266}@supports (color:color-mix(in lab, red, red)){.dark\:bg-emerald-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-emerald-950) 40%, transparent)}}.dark\:bg-fuchsia-950\/40:is(.dark *){background-color:#4b004f66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-fuchsia-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-fuchsia-950) 40%, transparent)}}.dark\:bg-gray-900\/40:is(.dark *){background-color:#10182866}@supports (color:color-mix(in lab, red, red)){.dark\:bg-gray-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-gray-900) 40%, transparent)}}.dark\:bg-green-950\/40:is(.dark *){background-color:#032e1566}@supports (color:color-mix(in lab, red, red)){.dark\:bg-green-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-green-950) 40%, transparent)}}.dark\:bg-indigo-950\/40:is(.dark *){background-color:#1e1a4d66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-indigo-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-indigo-950) 40%, transparent)}}.dark\:bg-lime-950\/40:is(.dark *){background-color:#192e0366}@supports (color:color-mix(in lab, red, red)){.dark\:bg-lime-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-lime-950) 40%, transparent)}}.dark\:bg-muted\/30:is(.dark *){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-muted\/30:is(.dark *){background-color:color-mix(in oklab, var(--muted) 30%, transparent)}}.dark\:bg-neutral-900\/40:is(.dark *){background-color:#17171766}@supports (color:color-mix(in lab, red, red)){.dark\:bg-neutral-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-neutral-900) 40%, transparent)}}.dark\:bg-orange-950\/40:is(.dark *){background-color:#44130666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-orange-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-orange-950) 40%, transparent)}}.dark\:bg-pink-950\/40:is(.dark *){background-color:#51042466}@supports (color:color-mix(in lab, red, red)){.dark\:bg-pink-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-pink-950) 40%, transparent)}}.dark\:bg-purple-950\/40:is(.dark *){background-color:#3c036666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-purple-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-purple-950) 40%, transparent)}}.dark\:bg-red-950\/40:is(.dark *){background-color:#46080966}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-red-950) 40%, transparent)}}.dark\:bg-rose-950\/40:is(.dark *){background-color:#4d021866}@supports (color:color-mix(in lab, red, red)){.dark\:bg-rose-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-rose-950) 40%, transparent)}}.dark\:bg-sky-950\/40:is(.dark *){background-color:#052f4a66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-sky-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-sky-950) 40%, transparent)}}.dark\:bg-slate-900\/40:is(.dark *){background-color:#0f172b66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-slate-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-slate-900) 40%, transparent)}}.dark\:bg-stone-900\/40:is(.dark *){background-color:#1c191766}@supports (color:color-mix(in lab, red, red)){.dark\:bg-stone-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-stone-900) 40%, transparent)}}.dark\:bg-teal-950\/40:is(.dark *){background-color:#022f2e66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-teal-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-teal-950) 40%, transparent)}}.dark\:bg-violet-950\/40:is(.dark *){background-color:#2f0d6866}@supports (color:color-mix(in lab, red, red)){.dark\:bg-violet-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-violet-950) 40%, transparent)}}.dark\:bg-yellow-950\/40:is(.dark *){background-color:#43200466}@supports (color:color-mix(in lab, red, red)){.dark\:bg-yellow-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-yellow-950) 40%, transparent)}}.dark\:bg-zinc-900\/40:is(.dark *){background-color:#18181b66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-zinc-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-zinc-900) 40%, transparent)}}.dark\:text-red-100:is(.dark *){color:var(--color-red-100)}}:root{--topbar-h:39px;--header-h:87px;--footer-h:359px;--site-content-min-h:calc(100dvh - var(--topbar-h) - var(--header-h) - var(--footer-h));--background:oklch(100% 0 0);--foreground:oklch(21.93% .0122 145.145);--card:oklch(100% 0 0);--card-foreground:oklch(21.93% .0122 145.145);--popover:oklch(100% 0 0);--popover-foreground:oklch(21.93% .0122 145.145);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(100% 0 0);--secondary:oklch(96.07% .0112 141.263);--secondary-foreground:oklch(44.45% .0502 141.758);--muted:oklch(96.07% .0112 141.263);--muted-foreground:oklch(53.51% .0432 142.652);--accent:oklch(96.07% .0112 141.263);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(68.07% .1129 109.059);--destructive-foreground:oklch(100% 0 0);--border:oklch(91% .021 140.896);--input:oklch(91% .021 140.896);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(60.42% .0688 140.724);--chart-3:oklch(84.06% .0531 141.655);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(91% .021 140.896);--sidebar:oklch(97.77% .0078 139.442);--sidebar-foreground:oklch(21.93% .0122 145.145);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(100% 0 0);--sidebar-accent:oklch(91% .021 140.896);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(91% .021 140.896);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:4px;--shadow-blur:10px;--shadow-spread:0px;--shadow-opacity:.05;--shadow-color:0 0 0;--shadow-2xs:0px 4px 10px 0px #00000008;--shadow-xs:0px 4px 10px 0px #00000008;--shadow-sm:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow-md:0px 4px 10px 0px #0000000d, 0px 2px 4px -1px #0000000d;--shadow-lg:0px 4px 10px 0px #0000000d, 0px 4px 6px -1px #0000000d;--shadow-xl:0px 4px 10px 0px #0000000d, 0px 8px 10px -1px #0000000d;--shadow-2xl:0px 4px 10px 0px #00000021;--tracking-normal:.01em;--spacing:.3rem;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.dark{--background:oklch(21.93% .0122 145.145);--foreground:oklch(96.07% .0112 141.263);--card:oklch(21.93% .0122 145.145);--card-foreground:oklch(96.07% .0112 141.263);--popover:oklch(21.93% .0122 145.145);--popover-foreground:oklch(96.07% .0112 141.263);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(21.93% .0122 145.145);--secondary:oklch(27.44% .0184 145.053);--secondary-foreground:oklch(84.06% .0531 141.655);--muted:oklch(27.44% .0184 145.053);--muted-foreground:oklch(60.42% .0688 140.724);--accent:oklch(27.44% .0184 145.053);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(88.44% .1663 107.49);--destructive-foreground:oklch(100% 0 0);--border:oklch(27.44% .0184 145.053);--input:oklch(27.44% .0184 145.053);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(84.06% .0531 141.655);--chart-3:oklch(60.42% .0688 140.724);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(35.96% .0355 143.305);--sidebar:oklch(21.93% .0122 145.145);--sidebar-foreground:oklch(96.07% .0112 141.263);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(21.93% .0122 145.145);--sidebar-accent:oklch(27.44% .0184 145.053);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(27.44% .0184 145.053);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:10px;--shadow-blur:20px;--shadow-spread:0px;--shadow-opacity:.4;--shadow-color:0 0 0;--shadow-2xs:0px 10px 20px 0px #0003;--shadow-xs:0px 10px 20px 0px #0003;--shadow-sm:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow-md:0px 10px 20px 0px #0006, 0px 2px 4px -1px #0006;--shadow-lg:0px 10px 20px 0px #0006, 0px 4px 6px -1px #0006;--shadow-xl:0px 10px 20px 0px #0006, 0px 8px 10px -1px #0006;--shadow-2xl:0px 10px 20px 0px #000;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.rfs-root{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--rfs-text)}.rfs-root--drag-move{cursor:grabbing;-webkit-user-select:none;user-select:none}.rfs-root--drag-resize{cursor:ns-resize;-webkit-user-select:none;user-select:none}.rfs-card-slot--ghost{z-index:10;pointer-events:none}.rfs-card-slot--dragging{z-index:30}.rfs-drag-overlay{z-index:60;pointer-events:none;position:fixed}.rfs-toolbar{margin-bottom:calc(var(--spacing) * 3);align-items:center;gap:calc(var(--spacing) * 2);display:flex}.rfs-btn{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-btn:hover{background:var(--rfs-bg)}.rfs-btn:disabled{cursor:not-allowed;opacity:.5}.rfs-date-label{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-shell{border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);overflow-x:auto}.rfs-header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--rfs-border);display:flex}.rfs-gutter{left:calc(var(--spacing) * 0);z-index:20;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky}.rfs-resource-header{border-right-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 2);border-right-width:1px;border-color:var(--rfs-border)}.rfs-resource-subtitle{margin-top:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--rfs-muted)}.rfs-body{display:flex}.rfs-times{left:calc(var(--spacing) * 0);z-index:10;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky;box-shadow:8px 0 12px -12px #0000002e}.rfs-time-tick{left:calc(var(--spacing) * 1);color:var(--rfs-muted);font-size:11px;position:absolute}.rfs-grid{flex:1;display:flex}.rfs-col{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border)}.rfs-col-inner{position:relative}.rfs-hour-line,.rfs-slot-line{right:calc(var(--spacing) * 0);left:calc(var(--spacing) * 0);border-top-style:var(--tw-border-style);--tw-border-style:dotted;border-style:dotted;border-top-width:1px;border-color:var(--rfs-border);opacity:.5;position:absolute}.rfs-card-slot{padding:calc(var(--spacing) * .5);position:absolute}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-serif:var(--font-serif);--font-mono:var(--font-mono);--color-red-100:oklch(93.6% .032 17.717);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-950:oklch(25.8% .092 26.042);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-950:oklch(26.6% .079 36.259);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-950:oklch(27.9% .077 45.635);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-950:oklch(28.6% .066 53.813);--color-lime-100:oklch(96.7% .067 122.328);--color-lime-950:oklch(27.4% .072 132.109);--color-green-100:oklch(96.2% .044 156.743);--color-green-950:oklch(26.6% .065 152.934);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-950:oklch(26.2% .051 172.552);--color-teal-100:oklch(95.3% .051 180.801);--color-teal-950:oklch(27.7% .046 192.524);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-950:oklch(30.2% .056 229.695);--color-sky-100:oklch(95.1% .026 236.824);--color-sky-950:oklch(29.3% .066 243.157);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-950:oklch(28.2% .091 267.935);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-950:oklch(25.7% .09 281.288);--color-violet-100:oklch(94.3% .029 294.588);--color-violet-950:oklch(28.3% .141 291.089);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-950:oklch(29.1% .149 302.717);--color-fuchsia-100:oklch(95.2% .037 318.852);--color-fuchsia-950:oklch(29.3% .136 325.661);--color-pink-100:oklch(94.8% .028 342.258);--color-pink-950:oklch(28.4% .109 3.907);--color-rose-100:oklch(94.1% .03 12.58);--color-rose-950:oklch(27.1% .105 12.094);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-900:oklch(21% .034 264.665);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-900:oklch(21% .006 285.885);--color-neutral-100:oklch(97% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-stone-100:oklch(97% .001 106.424);--color-stone-900:oklch(21.6% .006 56.043);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-normal:var(--tracking-normal);--leading-tight:1.25;--shadow-2xs:var(--shadow-2xs);--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:var(--shadow-md);--shadow-lg:var(--shadow-lg);--shadow-xl:var(--shadow-xl);--shadow-2xl:var(--shadow-2xl);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--shadow:var(--shadow)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-x-1{inset-inline:calc(var(--spacing) * 1)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-1{top:calc(var(--spacing) * 1)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.bottom-1{bottom:calc(var(--spacing) * 1)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.w-4{width:calc(var(--spacing) * 4)}.w-8{width:calc(var(--spacing) * 8)}.w-72{width:calc(var(--spacing) * 72)}.w-auto{width:auto}.min-w-40{min-width:calc(var(--spacing) * 40)}.min-w-72{min-width:calc(var(--spacing) * 72)}.min-w-\[400px\]{min-width:400px}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-ns-resize{cursor:ns-resize}.resize{resize:both}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.overflow-hidden{overflow:hidden}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-border,.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.border-red-500{border-color:var(--color-red-500)}.border-slate-300{border-color:var(--color-slate-300)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-background{background-color:var(--background)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-border\/90{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.bg-border\/90{background-color:color-mix(in oklab, var(--border) 90%, transparent)}}.bg-card{background-color:var(--card)}.bg-cyan-100{background-color:var(--color-cyan-100)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-fuchsia-100{background-color:var(--color-fuchsia-100)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-green-100{background-color:var(--color-green-100)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-lime-100{background-color:var(--color-lime-100)}.bg-muted\/40{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/40{background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-orange-100{background-color:var(--color-orange-100)}.bg-pink-100{background-color:var(--color-pink-100)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-100\/80{background-color:#ffe2e2cc}@supports (color:color-mix(in lab, red, red)){.bg-red-100\/80{background-color:color-mix(in oklab, var(--color-red-100) 80%, transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-rose-100{background-color:var(--color-rose-100)}.bg-sky-100{background-color:var(--color-sky-100)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-300\/90{background-color:#cad5e2e6}@supports (color:color-mix(in lab, red, red)){.bg-slate-300\/90{background-color:color-mix(in oklab, var(--color-slate-300) 90%, transparent)}}.bg-stone-100{background-color:var(--color-stone-100)}.bg-teal-100{background-color:var(--color-teal-100)}.bg-violet-100{background-color:var(--color-violet-100)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-zinc-100{background-color:var(--color-zinc-100)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:calc(var(--tracking-normal) - .025em);letter-spacing:calc(var(--tracking-normal) - .025em)}.tracking-wide{--tw-tracking:calc(var(--tracking-normal) + .025em);letter-spacing:calc(var(--tracking-normal) + .025em)}.whitespace-nowrap{white-space:nowrap}.text-foreground{color:var(--foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-950{color:var(--color-red-950)}.text-slate-500{color:var(--color-slate-500)}.text-white{color:var(--color-white)}.opacity-35{opacity:.35}.opacity-55{opacity:.55}.opacity-60{opacity:.6}.shadow-md{--tw-shadow:var(--shadow-md);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:var(--shadow-sm);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:var(--shadow-xl);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:var(--shadow-xs);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-border\/70{--tw-ring-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.ring-border\/70{--tw-ring-color:color-mix(in oklab, var(--border) 70%, transparent)}}.ring-red-500\/60{--tw-ring-color:#fb2c3699}@supports (color:color-mix(in lab, red, red)){.ring-red-500\/60{--tw-ring-color:color-mix(in oklab, var(--color-red-500) 60%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:bg-border:hover{background-color:var(--border)}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-slate-400:hover{background-color:var(--color-slate-400)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:48rem){.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media (min-width:64rem){.lg\:w-full{width:100%}}.dark\:bg-amber-950\/40:is(.dark *){background-color:#46190166}@supports (color:color-mix(in lab, red, red)){.dark\:bg-amber-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-amber-950) 40%, transparent)}}.dark\:bg-blue-950\/40:is(.dark *){background-color:#16245666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-blue-950) 40%, transparent)}}.dark\:bg-cyan-950\/40:is(.dark *){background-color:#05334566}@supports (color:color-mix(in lab, red, red)){.dark\:bg-cyan-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-cyan-950) 40%, transparent)}}.dark\:bg-emerald-950\/40:is(.dark *){background-color:#002c2266}@supports (color:color-mix(in lab, red, red)){.dark\:bg-emerald-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-emerald-950) 40%, transparent)}}.dark\:bg-fuchsia-950\/40:is(.dark *){background-color:#4b004f66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-fuchsia-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-fuchsia-950) 40%, transparent)}}.dark\:bg-gray-900\/40:is(.dark *){background-color:#10182866}@supports (color:color-mix(in lab, red, red)){.dark\:bg-gray-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-gray-900) 40%, transparent)}}.dark\:bg-green-950\/40:is(.dark *){background-color:#032e1566}@supports (color:color-mix(in lab, red, red)){.dark\:bg-green-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-green-950) 40%, transparent)}}.dark\:bg-indigo-950\/40:is(.dark *){background-color:#1e1a4d66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-indigo-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-indigo-950) 40%, transparent)}}.dark\:bg-lime-950\/40:is(.dark *){background-color:#192e0366}@supports (color:color-mix(in lab, red, red)){.dark\:bg-lime-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-lime-950) 40%, transparent)}}.dark\:bg-muted\/30:is(.dark *){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-muted\/30:is(.dark *){background-color:color-mix(in oklab, var(--muted) 30%, transparent)}}.dark\:bg-neutral-900\/40:is(.dark *){background-color:#17171766}@supports (color:color-mix(in lab, red, red)){.dark\:bg-neutral-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-neutral-900) 40%, transparent)}}.dark\:bg-orange-950\/40:is(.dark *){background-color:#44130666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-orange-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-orange-950) 40%, transparent)}}.dark\:bg-pink-950\/40:is(.dark *){background-color:#51042466}@supports (color:color-mix(in lab, red, red)){.dark\:bg-pink-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-pink-950) 40%, transparent)}}.dark\:bg-purple-950\/40:is(.dark *){background-color:#3c036666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-purple-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-purple-950) 40%, transparent)}}.dark\:bg-red-950\/40:is(.dark *){background-color:#46080966}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-red-950) 40%, transparent)}}.dark\:bg-rose-950\/40:is(.dark *){background-color:#4d021866}@supports (color:color-mix(in lab, red, red)){.dark\:bg-rose-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-rose-950) 40%, transparent)}}.dark\:bg-sky-950\/40:is(.dark *){background-color:#052f4a66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-sky-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-sky-950) 40%, transparent)}}.dark\:bg-slate-900\/40:is(.dark *){background-color:#0f172b66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-slate-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-slate-900) 40%, transparent)}}.dark\:bg-stone-900\/40:is(.dark *){background-color:#1c191766}@supports (color:color-mix(in lab, red, red)){.dark\:bg-stone-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-stone-900) 40%, transparent)}}.dark\:bg-teal-950\/40:is(.dark *){background-color:#022f2e66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-teal-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-teal-950) 40%, transparent)}}.dark\:bg-violet-950\/40:is(.dark *){background-color:#2f0d6866}@supports (color:color-mix(in lab, red, red)){.dark\:bg-violet-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-violet-950) 40%, transparent)}}.dark\:bg-yellow-950\/40:is(.dark *){background-color:#43200466}@supports (color:color-mix(in lab, red, red)){.dark\:bg-yellow-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-yellow-950) 40%, transparent)}}.dark\:bg-zinc-900\/40:is(.dark *){background-color:#18181b66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-zinc-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--color-zinc-900) 40%, transparent)}}.dark\:text-red-100:is(.dark *){color:var(--color-red-100)}}:root{--topbar-h:39px;--header-h:87px;--footer-h:359px;--site-content-min-h:calc(100dvh - var(--topbar-h) - var(--header-h) - var(--footer-h));--background:oklch(100% 0 0);--foreground:oklch(21.93% .0122 145.145);--card:oklch(100% 0 0);--card-foreground:oklch(21.93% .0122 145.145);--popover:oklch(100% 0 0);--popover-foreground:oklch(21.93% .0122 145.145);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(100% 0 0);--secondary:oklch(96.07% .0112 141.263);--secondary-foreground:oklch(44.45% .0502 141.758);--muted:oklch(96.07% .0112 141.263);--muted-foreground:oklch(53.51% .0432 142.652);--accent:oklch(96.07% .0112 141.263);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(68.07% .1129 109.059);--destructive-foreground:oklch(100% 0 0);--border:oklch(91% .021 140.896);--input:oklch(91% .021 140.896);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(60.42% .0688 140.724);--chart-3:oklch(84.06% .0531 141.655);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(91% .021 140.896);--sidebar:oklch(97.77% .0078 139.442);--sidebar-foreground:oklch(21.93% .0122 145.145);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(100% 0 0);--sidebar-accent:oklch(91% .021 140.896);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(91% .021 140.896);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:4px;--shadow-blur:10px;--shadow-spread:0px;--shadow-opacity:.05;--shadow-color:0 0 0;--shadow-2xs:0px 4px 10px 0px #00000008;--shadow-xs:0px 4px 10px 0px #00000008;--shadow-sm:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow-md:0px 4px 10px 0px #0000000d, 0px 2px 4px -1px #0000000d;--shadow-lg:0px 4px 10px 0px #0000000d, 0px 4px 6px -1px #0000000d;--shadow-xl:0px 4px 10px 0px #0000000d, 0px 8px 10px -1px #0000000d;--shadow-2xl:0px 4px 10px 0px #00000021;--tracking-normal:.01em;--spacing:.3rem;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.dark{--background:oklch(21.93% .0122 145.145);--foreground:oklch(96.07% .0112 141.263);--card:oklch(21.93% .0122 145.145);--card-foreground:oklch(96.07% .0112 141.263);--popover:oklch(21.93% .0122 145.145);--popover-foreground:oklch(96.07% .0112 141.263);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(21.93% .0122 145.145);--secondary:oklch(27.44% .0184 145.053);--secondary-foreground:oklch(84.06% .0531 141.655);--muted:oklch(27.44% .0184 145.053);--muted-foreground:oklch(60.42% .0688 140.724);--accent:oklch(27.44% .0184 145.053);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(88.44% .1663 107.49);--destructive-foreground:oklch(100% 0 0);--border:oklch(27.44% .0184 145.053);--input:oklch(27.44% .0184 145.053);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(84.06% .0531 141.655);--chart-3:oklch(60.42% .0688 140.724);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(35.96% .0355 143.305);--sidebar:oklch(21.93% .0122 145.145);--sidebar-foreground:oklch(96.07% .0112 141.263);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(21.93% .0122 145.145);--sidebar-accent:oklch(27.44% .0184 145.053);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(27.44% .0184 145.053);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:10px;--shadow-blur:20px;--shadow-spread:0px;--shadow-opacity:.4;--shadow-color:0 0 0;--shadow-2xs:0px 10px 20px 0px #0003;--shadow-xs:0px 10px 20px 0px #0003;--shadow-sm:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow-md:0px 10px 20px 0px #0006, 0px 2px 4px -1px #0006;--shadow-lg:0px 10px 20px 0px #0006, 0px 4px 6px -1px #0006;--shadow-xl:0px 10px 20px 0px #0006, 0px 8px 10px -1px #0006;--shadow-2xl:0px 10px 20px 0px #000;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.rfs-root{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--rfs-text)}.rfs-root--drag-move{cursor:grabbing;-webkit-user-select:none;user-select:none}.rfs-root--drag-resize{cursor:ns-resize;-webkit-user-select:none;user-select:none}.rfs-card-slot--ghost{z-index:10;pointer-events:none}.rfs-card-slot--dragging{z-index:30}.rfs-drag-overlay{z-index:60;pointer-events:none;position:fixed}.rfs-toolbar{margin-bottom:calc(var(--spacing) * 3);align-items:center;gap:calc(var(--spacing) * 2);display:flex}.rfs-btn{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-btn:hover{background:var(--rfs-bg)}.rfs-btn:disabled{cursor:not-allowed;opacity:.5}.rfs-date-label{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-shell{border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);overflow-x:auto}.rfs-header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--rfs-border);display:flex}.rfs-gutter{left:calc(var(--spacing) * 0);z-index:20;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky}.rfs-resource-header{border-right-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 2);border-right-width:1px;border-color:var(--rfs-border)}.rfs-resource-subtitle{margin-top:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--rfs-muted)}.rfs-body{display:flex}.rfs-times{left:calc(var(--spacing) * 0);z-index:10;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky;box-shadow:8px 0 12px -12px #0000002e}.rfs-time-tick{left:calc(var(--spacing) * 1);color:var(--rfs-muted);font-size:11px;position:absolute}.rfs-grid{flex:1;display:flex}.rfs-col{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border)}.rfs-col-inner{position:relative}.rfs-hour-line,.rfs-slot-line{right:calc(var(--spacing) * 0);left:calc(var(--spacing) * 0);border-top-style:var(--tw-border-style);--tw-border-style:dotted;border-style:dotted;border-top-width:1px;border-color:var(--rfs-border);opacity:.5;position:absolute}.rfs-card-slot{padding:calc(var(--spacing) * .5);position:absolute}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|