diff --git a/packages/json-document-calendar/src/calendar-time-grid.tsx b/packages/json-document-calendar/src/calendar-time-grid.tsx
index aea1d644..01dc8434 100644
--- a/packages/json-document-calendar/src/calendar-time-grid.tsx
+++ b/packages/json-document-calendar/src/calendar-time-grid.tsx
@@ -112,7 +112,7 @@ export function CalendarTimeGrid(props: CalendarTimeGridProps): ReactNode {
if (start !== null && end !== null) hand.createInterval(start, end);
}
- const gridColumns = `3.25rem repeat(${days.length}, minmax(4.5rem, 1fr))`;
+ const gridColumns = `4rem repeat(${days.length}, minmax(4.5rem, 1fr))`;
const gridHeight = (props.hourEnd - props.hourStart) * props.pixelsPerHour;
return (
+ {Array.from({ length: props.hourEnd - props.hourStart }, (_, index) => index === 0 ? null : props.hourStart + index).map((hour) => hour === null ? null : (
+
{props.labels.hour(hour)}
))}
diff --git a/packages/json-document-calendar/src/use-calendar-pointer-interactions.ts b/packages/json-document-calendar/src/use-calendar-pointer-interactions.ts
index 1fc18bec..940b8882 100644
--- a/packages/json-document-calendar/src/use-calendar-pointer-interactions.ts
+++ b/packages/json-document-calendar/src/use-calendar-pointer-interactions.ts
@@ -130,7 +130,10 @@ export function useCalendarPointerInteractions(hand: CalendarHand, policy: Calen
return;
}
setHoveredTime(null);
- const targetInstant = instantAt(day, event.clientY, grid);
+ const targetGridMinutes = calendarMinutesFromWebGrid(event.clientY, grid.getBoundingClientRect(), {
+ hourStart: policy.hourStart, hourEnd: policy.hourEnd, stepMinutes: policy.stepMinutes,
+ });
+ const targetInstant = calendarInstantAt(day, targetGridMinutes);
if (targetInstant === null) return;
const next = timePointer.preview(event.pointerId, (state) => {
const dragSource = state.dragSource ?? (state.dragCandidate !== null && targetInstant !== state.originInstant
@@ -139,8 +142,11 @@ export function useCalendarPointerInteractions(hand: CalendarHand, policy: Calen
return { ...state, targetInstant, dragSource };
});
if (next?.dragSource !== null && next?.dragSource !== undefined) {
- if (selectionDrag.getActive() === null) selectionDrag.begin({ type: "calendar-selection-drag", source: next.dragSource, target: { type: "instant", instant: next.originInstant } });
- const gesture = selectionDrag.preview((active) => ({ ...active, target: { type: "instant", instant: targetInstant } }));
+ const originAnchor = next.dragSource.anchor.occurrenceStart;
+ const move = interpretCalendarTimeGridPointer(next);
+ if (move?.type !== "event.move") return;
+ if (selectionDrag.getActive() === null) selectionDrag.begin({ type: "calendar-selection-drag", source: next.dragSource, target: { type: "instant", instant: originAnchor } });
+ const gesture = selectionDrag.preview((active) => ({ ...active, target: { type: "instant", instant: move.start } }));
hand.previewSelectionDrag(gesture);
} else if (next !== null) hand.setTimePreview(next);
}
diff --git a/packages/json-document-calendar/tests/calendar-time-grid.test.tsx b/packages/json-document-calendar/tests/calendar-time-grid.test.tsx
index 5709b4c0..b39ad427 100644
--- a/packages/json-document-calendar/tests/calendar-time-grid.test.tsx
+++ b/packages/json-document-calendar/tests/calendar-time-grid.test.tsx
@@ -66,7 +66,11 @@ describe("CalendarTimeGrid", () => {
}
render(
);
- expect(screen.getByRole("grid", { name: "Week" })).toBeTruthy();
+ const grid = screen.getByRole("grid", { name: "Week" });
+ expect(grid).toBeTruthy();
+ expect((grid.firstElementChild as HTMLElement).style.gridTemplateColumns).toBe("4rem repeat(7, minmax(4.5rem, 1fr))");
+ expect(grid.querySelector('[data-calendar-hour="00"]')).toBeNull();
+ expect((grid.querySelector('[data-calendar-hour="01"]') as HTMLElement).style.top).toBe("72px");
expect(screen.getAllByRole("columnheader")).toHaveLength(7);
expect(screen.getByText("all-day")).toBeTruthy();
expect(screen.getByRole("presentation", { name: "Now" })).toBeTruthy();
diff --git a/packages/json-document-calendar/tests/use-calendar-hand.test.tsx b/packages/json-document-calendar/tests/use-calendar-hand.test.tsx
index 2851e9a9..999ec4bf 100644
--- a/packages/json-document-calendar/tests/use-calendar-hand.test.tsx
+++ b/packages/json-document-calendar/tests/use-calendar-hand.test.tsx
@@ -210,17 +210,17 @@ describe("useCalendarHand", () => {
releasePointerCapture: () => undefined,
};
act(() => result.current.pointer.timePointerDown({
- button: 0, clientY: 540, currentTarget: target, pointerId: 7,
+ button: 0, clientY: 555, currentTarget: target, pointerId: 7,
} as never, "2026-08-03", "standup", "2026-08-03T09:00", "2026-08-03T09:30", "body"));
act(() => result.current.pointer.timePointerMove({ pointerId: 7, clientX: 50, clientY: 600, target } as never));
expect(result.current.hand.selectionDragPreview).not.toBeNull();
expect(result.current.hand.paintedEvents.map((item) => item.start)).toEqual([
- "2026-08-03T10:00", "2026-08-04T12:00",
+ "2026-08-03T09:45", "2026-08-04T11:45",
]);
act(() => result.current.pointer.timePointerUp({ pointerId: 7 } as never));
expect(result.current.hand.selectionDragPreview).toBeNull();
expect(result.current.hand.document.events.map((item) => item.start)).toEqual([
- "2026-08-03T10:00", "2026-08-04T12:00",
+ "2026-08-03T09:45", "2026-08-04T11:45",
]);
expect(result.current.hand.selectedOccurrences).toHaveLength(2);
act(() => result.current.hand.undo());
diff --git a/site/src/routes/calendar-demo/CalendarDemoRoute.tsx b/site/src/routes/calendar-demo/CalendarDemoRoute.tsx
index a8408b46..41424d63 100644
--- a/site/src/routes/calendar-demo/CalendarDemoRoute.tsx
+++ b/site/src/routes/calendar-demo/CalendarDemoRoute.tsx
@@ -45,7 +45,6 @@ import {
ToolbarGroup,
ToolbarLayout,
ToolbarRegion,
- ToolbarSeparator,
Toggle,
} from "@interactive-os/json-document-ui-primitives-react";
import { useDemoEmbed } from "../../shared/demo-workbench/DemoPage";
@@ -160,6 +159,7 @@ export function CalendarDemoRoute(props: {
active: !embedded && (view === "day" || view === "week"),
resetKey: `${view}:${visibleDate}`,
targetHour: workHourStart,
+ viewportOffset: 16,
});
function setLocation(nextView: CalendarView, nextDate: string): void {
@@ -179,8 +179,13 @@ export function CalendarDemoRoute(props: {
const document = hand.document;
const calendars = calendarDocumentCalendars(document);
const selectedEvent = hand.selectedEvent;
+ const pointerGestureActive = hand.timePreview !== null
+ || hand.allDayPreview !== null
+ || hand.monthPreview !== null
+ || hand.selectionDragPreview !== null;
+ const eventInspectorVisible = selectedEvent !== null && !pointerGestureActive;
const eventDetailsPosition = useAnchoredFloatingPosition
({
- active: selectedEvent !== null,
+ active: eventInspectorVisible,
policy: {
type: "preferred",
placement: "right-start",
@@ -267,10 +272,10 @@ export function CalendarDemoRoute(props: {
stickyHeader: classes("grid", styles.weekSticky()),
columnHeader: styles.weekHead(),
weekday: ui.text.meta,
- dayNumber: styles.dayNumber(),
- today: styles.todayMark(),
- allDayLabel: classes("px-1 py-2 text-right", ui.text.meta),
- allDayCell: classes("min-h-10", styles.weekCell()),
+ dayNumber: classes(styles.dayNumber(), ui.text.body),
+ today: styles.weekToday(),
+ allDayLabel: classes("whitespace-nowrap px-1 py-1.5 text-right text-foreground-muted/70", ui.text.meta),
+ allDayCell: classes("min-h-8", styles.weekCell()),
allDayEventContainer: "group/event relative z-10 mx-0.5 my-1",
allDayEvent: styles.allDayEvent(),
resizeAllDayEnd: styles.resizeEdgeVertical(),
@@ -278,16 +283,16 @@ export function CalendarDemoRoute(props: {
timeViewportFill: styles.weekHours(),
hourGutter: "relative overflow-hidden",
viewportAnchor: "pointer-events-none absolute left-0 top-0",
- hourLabel: styles.hourLabel(),
+ hourLabel: classes(styles.hourLabel(), ui.text.meta),
timeCell: classes("overflow-hidden", styles.weekCell()),
selectedSlot: styles.selectedSlot(),
hourRule: styles.hourRule(),
nowLine: styles.nowLine(),
- creationTimeHint: styles.creationTimeHint(),
- timedEventContainer: "group/event absolute z-10",
+ creationTimeHint: classes(styles.creationTimeHint(), ui.text.meta),
+ timedEventContainer: "group/event absolute z-10 py-0.5",
timedEvent: styles.timedEvent(),
- eventTitle: "min-w-0 truncate",
- eventTime: styles.eventTime(),
+ eventTitle: classes("min-w-0 truncate", ui.text.meta),
+ eventTime: classes(styles.eventTime(), ui.text.meta),
resizeTimedEnd: styles.resizeEdge(),
}}
labels={{
@@ -295,7 +300,7 @@ export function CalendarDemoRoute(props: {
allDay: "all-day",
now: "Now",
resizeEnd: (event) => `Resize ${event.title} end`,
- hour: (hour) => String(hour).padStart(2, "0"),
+ hour: calendarHourLabel,
}}
getEventColor={(event) => calendarColor(document, event.calendarId)}
/>
@@ -312,27 +317,20 @@ export function CalendarDemoRoute(props: {
+
- {visiblePeriodLabel(view, visibleDate, {
- monthNames: months,
- weekSeparator: " – ",
- })}
setVisibleDate(shiftVisibleDate(visibleDate, view, -1))}>
+ setLocation(view === "year" ? "month" : view, today)}>Today
setVisibleDate(shiftVisibleDate(visibleDate, view, 1))}>
-
-
- setLocation(view === "year" ? "month" : view, today)}>Today
-
-
+
+
+ {(context) => (
+ <>
+
+ {context.visible.includes("sources") ? (
+
+ ) : null}
+ >
+ )}
+
+
)}
>
-
-
+ {eventInspectorVisible ? ,
+ remove: ,
+ time: ,
+ calendar: ,
+ repeat: ,
+ }}
+ /> : null}
+
- {(context) => context.visible.includes("sources") ? (
-
- ) :
Calendars}
-
-
+
+
+
Visual preview only. AI commands are not available in this demo.
+
+
+
+
+
+
+
{visiblePeriodLabel(view, visibleDate, {
+ monthNames: months,
+ weekSeparator: " – ",
+ })}
{view === "day" || view === "week" ? timeGrid : null}
{view === "month" ? (
) : null}
-
- ,
- remove: ,
- time: ,
- calendar: ,
- repeat: ,
- }}
- />
-
-
-
-
-
Visual preview only. AI commands are not available in this demo.
-
-
-
@@ -581,3 +589,9 @@ export function CalendarDemoRoute(props: {
function calendarColor(document: CalendarDocument, calendarId: string): "accent" | "subtle" {
return calendarDocumentCalendar(document, calendarId)?.color === "accent" ? "accent" : "subtle";
}
+
+function calendarHourLabel(hour: number): string {
+ const period = hour < 12 ? "AM" : "PM";
+ const displayHour = hour % 12 || 12;
+ return `${displayHour} ${period}`;
+}
diff --git a/site/src/routes/calendar-demo/calendar-demo-styles.ts b/site/src/routes/calendar-demo/calendar-demo-styles.ts
index 09934eee..f270dae7 100644
--- a/site/src/routes/calendar-demo/calendar-demo-styles.ts
+++ b/site/src/routes/calendar-demo/calendar-demo-styles.ts
@@ -5,9 +5,11 @@ const chipFill = "bg-background-subtle text-foreground-strong data-[calendar-col
export const calendarDemoRecipe = tv({
slots: {
- shell: "relative isolate overflow-hidden bg-background-canvas",
+ shell: "relative isolate overflow-hidden bg-background-canvas [&>[data-ui-toolbar=product]]:absolute [&>[data-ui-toolbar=product]]:right-4 [&>[data-ui-toolbar=product]]:top-3 [&>[data-ui-toolbar=product]]:z-50 [&>[data-ui-toolbar=product]]:w-auto [&>[data-ui-toolbar=product]]:max-w-[calc(100%-1.5rem)] sm:[&>[data-ui-toolbar=product]]:max-w-[calc(100%-8rem)] [&>[data-ui-toolbar=product]]:rounded-full [&>[data-ui-toolbar=product]]:border [&>[data-ui-toolbar=product]]:border-line-subtle/35 [&>[data-ui-toolbar=product]]:bg-background-canvas [&>[data-ui-toolbar=product]]:px-1 [&>[data-ui-toolbar=product]]:py-1 [&>[data-ui-toolbar=product]]:shadow-none [&>[data-ui-toolbar=product]]:transition-[border-color,box-shadow] [&>[data-ui-toolbar=product]]:hover:border-line-subtle/60 [&>[data-ui-toolbar=product]]:focus-within:border-line-subtle/60 [&>[data-ui-toolbar=product]_[data-placement=end]]:overflow-visible [&>[data-ui-toolbar=product]_[data-ui-segment=true]]:rounded-full [&>[data-ui-toolbar=product]_[data-ui-segment=true]]:border-transparent [&>[data-ui-toolbar=product]_[data-ui-segment=true]]:bg-transparent [&>[data-ui-toolbar=product]_[data-ui-segment=true]]:shadow-none [&>[data-ui-toolbar=product]_[data-ui-segment=true]]:hover:bg-background-subtle/60 [&>[data-ui-toolbar=product]_[data-ui-segment=true][aria-checked=true]]:bg-background-subtle [&>[data-ui-toolbar=product]_[data-ui-segment=true][aria-checked=true]]:text-foreground-strong",
+ controlLayer: "pointer-events-none absolute inset-0 z-40 [&>*]:pointer-events-auto",
+ contentLayer: "relative z-0 h-full min-h-0 min-w-0 pb-24",
allDayEvent: `h-full w-full rounded-control border-0 px-2 py-0.5 text-left text-xs leading-4 ${chipFill} ${chipRail}`,
- hourRule: "absolute inset-x-0 border-t border-line-subtle/70",
+ hourRule: "absolute inset-x-0 border-t border-line-subtle/45",
timedEvent: `group flex h-full w-full flex-col items-stretch gap-0 overflow-hidden rounded-control border-0 px-2 py-0.5 pl-2.5 text-left text-xs leading-4 ${chipFill} ${chipRail}`,
monthWeek: "relative grid min-w-[36rem] grid-cols-7 border-t border-line-subtle/60",
monthDay: "relative z-0 flex min-h-32 w-full flex-col items-stretch px-1.5 pb-1 text-left text-xs",
@@ -18,17 +20,17 @@ export const calendarDemoRecipe = tv({
quietAction: "border-0 bg-transparent p-0 shadow-none hover:border-0 hover:bg-transparent",
monthOverflow: "absolute left-0 top-0 z-30 flex w-max min-w-full max-w-56 flex-col gap-0.5 p-1.5",
monthHead: "px-2 py-1.5 text-center text-xs text-foreground-muted",
- weekSticky: "z-30 shrink-0 border-b border-line-subtle/60 bg-background-canvas",
+ weekSticky: "z-30 shrink-0 border-b border-line-subtle/40 bg-background-canvas pt-14",
weekHours: "min-h-0 flex-1 overflow-auto",
- weekHead: "flex flex-col items-center gap-0.5 px-1 py-2 text-center",
- weekCell: "relative border-l border-line-subtle/60",
- selectedSlot: "pointer-events-none absolute inset-x-0 z-10 rounded-control bg-background-subtle/60 ring-1 ring-inset ring-line-subtle/40",
+ weekHead: "flex min-h-12 items-center justify-center gap-1 px-1 py-2 text-center",
+ weekCell: "relative border-l border-line-subtle/30 outline-none focus-visible:ring-0 focus-visible:ring-offset-0",
+ selectedSlot: "pointer-events-none absolute inset-x-1 z-10 rounded-control border-y-2 border-transparent bg-background-accent-subtle/70 bg-clip-padding before:absolute before:inset-y-1 before:left-1 before:w-0.5 before:rounded-full before:bg-background-accent",
resizeEdge: "absolute inset-x-0 bottom-0 h-2",
resizeEdgeVertical: "absolute right-0 top-0 h-full w-2",
- period: "px-1 text-sm font-medium text-foreground-strong",
+ periodHeading: "pointer-events-none absolute left-14 top-4 z-40 m-0 hidden whitespace-nowrap text-sm font-medium text-foreground-strong sm:block",
todayAction: "border-0 bg-transparent px-2 shadow-none hover:border-0 hover:bg-background-subtle",
- contextualSidebar: "relative z-30 w-20 shrink-0 rounded-control px-1 py-2 outline-none transition-[width] focus-within:w-44 hover:w-44 focus-visible:ring-2 focus-visible:ring-line-accent/25",
- sidebarHint: "block text-center text-overline text-foreground-muted [writing-mode:vertical-rl]",
+ toolbarSources: "relative grid size-8 place-items-center rounded-full outline-none focus-visible:ring-2 focus-visible:ring-line-accent/25",
+ sidebarHint: "grid h-5 place-items-center text-foreground-muted",
yearMonth: "flex min-h-0 w-full flex-col gap-1 px-1 py-1 text-left",
yearDay: "flex aspect-square w-full items-center justify-center border-0 bg-transparent p-0 text-overline shadow-none hover:border-0 hover:bg-transparent",
@@ -36,21 +38,22 @@ export const calendarDemoRecipe = tv({
nowLine: "pointer-events-none absolute inset-x-0 z-20 border-t border-line-accent",
today: "font-semibold text-foreground-accent",
todayMark: "font-semibold text-foreground-strong",
- dayNumber: "inline-flex size-7 items-center justify-center text-sm font-medium",
- sidebar: "flex w-44 shrink-0 flex-col gap-3 overflow-auto pr-1",
- inspector: "group/details z-40 flex w-80 min-w-0 flex-col gap-3 overflow-auto border border-line-subtle/60 p-3.5 shadow-overlay",
+ weekToday: "rounded-full bg-background-accent text-foreground-inverse",
+ dayNumber: "inline-flex size-7 items-center justify-center font-medium text-foreground-strong",
+ sidebar: "absolute right-0 top-[calc(100%+0.75rem)] flex max-h-[calc(100vh-8rem)] w-44 shrink-0 flex-col gap-3 overflow-auto rounded-surface border border-line-subtle/45 bg-background-canvas p-3 shadow-overlay",
+ inspector: "group/details z-50 flex w-80 min-w-0 flex-col gap-3 overflow-auto rounded-surface border border-line-subtle/45 bg-background-canvas p-3.5 shadow-surface",
field: "grid gap-1",
inspectorHeader: "flex min-w-0 items-center gap-2",
inspectorTitle: "m-0 min-w-0 flex-1 truncate px-0 text-base font-semibold tracking-tight text-foreground-strong",
inspectorActions: "flex shrink-0 items-center gap-0.5 [&_[data-ui-control=command]]:size-7 [&_[data-ui-control=command]]:border-0 [&_[data-ui-control=command]]:bg-transparent [&_[data-ui-control=command]]:p-0 [&_[data-ui-control=command]]:shadow-none",
eventSummary: "grid gap-2 border-t border-line-subtle/40 pt-3 text-xs text-foreground-muted [&_p]:m-0 [&_p]:flex [&_p]:items-center [&_p]:gap-2 [&_svg]:shrink-0 [&_svg]:text-foreground-muted",
detailsEditor: "grid gap-3 border-t border-line-subtle/40 pt-3",
- calendarToggle: "group flex w-full items-center justify-start gap-2 border-0 bg-transparent px-1 text-left shadow-none hover:border-0 hover:bg-transparent aria-pressed:border-0 aria-pressed:bg-transparent aria-pressed:text-foreground-strong aria-[pressed=false]:text-foreground-muted",
+ calendarToggle: "group flex w-full items-center justify-start gap-2 rounded-control border-0 bg-transparent px-2 py-1.5 text-left shadow-none outline-none hover:border-0 hover:bg-background-subtle focus-visible:ring-2 focus-visible:ring-foreground-muted/25 aria-pressed:border-0 aria-pressed:bg-transparent aria-pressed:text-foreground-strong aria-[pressed=false]:text-foreground-muted",
calendarSwatch: "size-2.5 shrink-0 rounded-full bg-foreground-muted opacity-40 data-[calendar-color=accent]:bg-background-accent group-aria-pressed:opacity-100",
- eventTime: "truncate text-overline font-normal text-foreground-muted",
- creationTimeHint: "pointer-events-none absolute left-1 z-20 -translate-y-1/2 whitespace-nowrap text-overline tabular-nums leading-none text-foreground-muted/55",
- hourLabel: "absolute right-1 whitespace-nowrap text-right text-overline tabular-nums leading-none text-foreground-muted",
- composerDock: "bottom-4 left-1/2 z-30 flex w-[min(42rem,calc(100%-2rem))] -translate-x-1/2 items-center gap-2 rounded-surface border border-line-subtle/70 bg-background-canvas/95 p-2 pl-3 shadow-overlay backdrop-blur",
+ eventTime: "truncate font-normal text-foreground-muted",
+ creationTimeHint: "pointer-events-none absolute left-2 z-20 translate-y-1 whitespace-nowrap tabular-nums text-foreground-muted/55",
+ hourLabel: "absolute right-2 -translate-y-1/2 whitespace-nowrap text-right tabular-nums text-foreground-muted/70",
+ composerDock: "bottom-4 left-1/2 z-30 flex w-[min(36rem,calc(100%-2rem))] -translate-x-1/2 items-center gap-2 rounded-full border border-line-subtle/55 bg-background-canvas p-2 pl-3 shadow-none",
composerDockFixed: "fixed",
composerDockEmbedded: "absolute",
composerSpark: "shrink-0 text-foreground-accent",
diff --git a/site/src/routes/date-controls-demo/date-controls-demo-styles.ts b/site/src/routes/date-controls-demo/date-controls-demo-styles.ts
index 6fc7fd2c..e04785c1 100644
--- a/site/src/routes/date-controls-demo/date-controls-demo-styles.ts
+++ b/site/src/routes/date-controls-demo/date-controls-demo-styles.ts
@@ -31,7 +31,7 @@ export const dateControlsDemoRecipe = tv({
timeViewport: "grid",
timeHourGutter: "relative overflow-hidden",
timeViewportAnchor: "pointer-events-none absolute left-0 top-0",
- timeHourLabel: "absolute right-1 text-xs text-foreground-muted",
+ timeHourLabel: "absolute right-1 -translate-y-1/2 text-xs text-foreground-muted",
timeCell: "relative overflow-hidden border-l border-line-subtle",
timeSelectedSlot: "pointer-events-none absolute inset-x-0 bg-background-subtle",
timeHourRule: "absolute inset-x-0 border-t border-line-subtle",
diff --git a/site/tests/unit/calendar-product-design.test.ts b/site/tests/unit/calendar-product-design.test.ts
index d9b4651d..ef67db55 100644
--- a/site/tests/unit/calendar-product-design.test.ts
+++ b/site/tests/unit/calendar-product-design.test.ts
@@ -17,6 +17,7 @@ function assertNoAccentChrome(source: string, label: string): void {
describe("calendar product design", () => {
const styles = calendarDemoRecipe();
+ const route = readFileSync(path.join(siteRoot, "src/routes/calendar-demo/CalendarDemoRoute.tsx"), "utf8");
test("event chips and calendar-visibility toggles use fill and type, not accent chrome", () => {
assertNoAccentChrome(styles.timedEvent(), "timedEvent");
@@ -52,12 +53,18 @@ describe("calendar product design", () => {
test("time grid keeps calendar structure visible without a full-column hover wash", () => {
const css = readFileSync(path.join(siteRoot, "src/app/index.css"), "utf8");
- expect(styles.hourRule()).toContain("border-line-subtle/70");
- expect(styles.weekCell()).toContain("border-line-subtle/60");
- expect(styles.weekSticky()).toContain("border-line-subtle/60");
+ expect(styles.hourRule()).toContain("border-line-subtle/45");
+ expect(styles.weekCell()).toContain("border-line-subtle/30");
+ expect(styles.weekSticky()).toContain("border-line-subtle/40");
expect(styles.monthWeek()).toContain("border-line-subtle/60");
expect(styles.creationTimeHint()).toContain("text-foreground-muted/55");
+ expect(styles.creationTimeHint()).toContain("translate-y-1");
+ expect(styles.creationTimeHint()).not.toContain("-translate-y-1/2");
+ expect(route).toContain("const eventInspectorVisible = selectedEvent !== null && !pointerGestureActive");
+ expect(route).toContain("eventInspectorVisible ?