{"version":3,"file":"CalendarWidget-DwbPq1ne.mjs","names":[],"sources":["../../widgets/src/hooks/use-calendar-events.preview.ts","../../widgets/src/hooks/use-calendar-events.ts","../../widgets/src/widgets/CalendarWidget.tsx"],"sourcesContent":["import type { CalendarEvent } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst today = new Date();\nconst inTwoDays = new Date(today);\ninTwoDays.setDate(inTwoDays.getDate() + 2);\n\nfunction toISO(date: Date, hours: number, minutes = 0): string {\n  const d = new Date(date);\n  d.setHours(hours, minutes, 0, 0);\n  return d.toISOString();\n}\n\nfunction toDateString(date: Date): string {\n  return date.toISOString().split(\"T\")[0]!;\n}\n\nexport const PREVIEW_DATA: CalendarEvent[] = [\n  {\n    id: 1,\n    title: \"Team Strategy Call\",\n    start: toISO(today, 9, 0),\n    end: toISO(today, 10, 0),\n    status: \"active\",\n    color: \"#4f46e5\",\n  },\n  {\n    id: 2,\n    title: \"Product Launch Webinar\",\n    start: toISO(today, 14, 0),\n    end: toISO(today, 15, 30),\n    status: \"active\",\n    color: \"#0891b2\",\n    venue: \"Zoom\",\n  },\n  {\n    id: 3,\n    title: \"Annual Leadership Summit\",\n    start: `${toDateString(inTwoDays)}T00:00:00.000Z`,\n    end: `${toDateString(inTwoDays)}T23:59:59.000Z`,\n    status: \"active\",\n    color: \"#059669\",\n    isAllDay: true,\n    venue: \"Convention Center\",\n  },\n];\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-calendar-events.preview\";\nimport type { CalendarEvent } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { CalendarEvent } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport function useCalendarEvents(): UseQueryResult<CalendarEvent[], Error> {\n  const widgetsApi = useWidgetsApi();\n  const { isPreview } = useWidgetPreviewContext();\n  const { baseUrl } = useDataSourceRegistryConfig();\n\n  return useQuery({\n    queryKey: [\n      \"portal-widget-use\",\n      \"calendar-events\",\n      isPreview ? \"preview\" : baseUrl,\n    ] as const,\n    queryFn: ({ signal }) => widgetsApi.fetchCalendarEvents(signal),\n    enabled: !isPreview,\n    ...(isPreview && { placeholderData: PREVIEW_DATA }),\n  });\n}\n","import {\n  useState,\n  useMemo,\n  useCallback,\n  useRef,\n  useEffect,\n  type ComponentProps,\n} from \"react\";\nimport type React from \"react\";\nimport type {\n  BackgroundValue,\n  BorderRadiusOptions,\n  BorderWidthOptions,\n  ColorOptions,\n  FontSizeOptions,\n  PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n  borderColorClasses,\n  borderWidthClasses,\n  getBorderColorField,\n  getBorderRadiusField,\n  getBorderWidthField,\n  getColorField,\n  getFontSizeField,\n  getPaddingField,\n} from \"../core/fields\";\nimport {\n  useCalendarEvents,\n  type CalendarEvent,\n} from \"../hooks/use-calendar-events\";\nimport { ErrorState } from \"../components/error-state\";\nimport { WidgetLoadingSkeleton } from \"../components/WidgetLoadingSkeleton\";\nimport {\n  Calendar,\n  CalendarCheck,\n  ChevronLeft,\n  ChevronRight,\n  ChevronsDown,\n  ChevronsUp,\n  Link2,\n  MapPin,\n  type LucideIcon,\n} from \"lucide-react\";\n\nconst DAY_NAMES = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"] as const;\n\nconst getDaysInMonth = (year: number, month: number): number =>\n  new Date(year, month + 1, 0).getDate();\n\nconst getFirstDayOfMonth = (year: number, month: number): number =>\n  new Date(year, month, 1).getDay();\n\nconst isSameDay = (a: Date, b: Date): boolean =>\n  a.getFullYear() === b.getFullYear() &&\n  a.getMonth() === b.getMonth() &&\n  a.getDate() === b.getDate();\n\nconst startOfDay = (d: Date): Date => {\n  const x = new Date(d);\n  x.setHours(0, 0, 0, 0);\n  return x;\n};\n\nconst addDays = (d: Date, n: number): Date => {\n  const x = new Date(d);\n  x.setDate(x.getDate() + n);\n  return x;\n};\n\nconst diffDays = (a: Date, b: Date): number => {\n  const ms = startOfDay(a).getTime() - startOfDay(b).getTime();\n  return Math.round(ms / 86400000);\n};\n\ntype DayCell = {\n  date: Date | null;\n  isToday: boolean;\n  isCurrentMonth: boolean;\n};\n\nconst generateMonthGrid = (year: number, month: number): DayCell[] => {\n  const daysInMonth = getDaysInMonth(year, month);\n  const firstDay = getFirstDayOfMonth(year, month);\n  const today = new Date();\n  const cells: DayCell[] = [];\n\n  for (let i = 0; i < firstDay; i++) {\n    cells.push({ date: null, isToday: false, isCurrentMonth: false });\n  }\n\n  for (let day = 1; day <= daysInMonth; day++) {\n    const date = new Date(year, month, day);\n    cells.push({\n      date,\n      isToday: isSameDay(date, today),\n      isCurrentMonth: true,\n    });\n  }\n\n  return cells;\n};\n\nconst generateWeekGrid = (): Array<{ date: Date; isToday: boolean }> => {\n  const today = new Date();\n  const weekday = today.getDay();\n  return Array.from({ length: 7 }, (_, i) => {\n    const date = addDays(today, -weekday + i);\n    return { date, isToday: isSameDay(date, today) };\n  });\n};\n\nconst formatContextualDate = (\n  date: Date,\n): { lead: string | null; detail: string } => {\n  const today = new Date();\n  const d = diffDays(date, today);\n  const weekday = date.toLocaleDateString(\"en-US\", { weekday: \"short\" });\n  const monthDay = date.toLocaleDateString(\"en-US\", {\n    month: \"short\",\n    day: \"numeric\",\n  });\n  if (d === 0) return { lead: \"Today\", detail: `${weekday}, ${monthDay}` };\n  if (d === 1) return { lead: \"Tomorrow\", detail: `${weekday}, ${monthDay}` };\n  if (d === -1) return { lead: \"Yesterday\", detail: `${weekday}, ${monthDay}` };\n  return { lead: null, detail: `${weekday}, ${monthDay}` };\n};\n\ntype DayCellButtonProps = {\n  date: Date;\n  isToday: boolean;\n  isSelected: boolean;\n  eventCount: number;\n  accentColor: ColorOptions;\n  textColor: ColorOptions;\n  showEventDensity: boolean;\n  onClick: () => void;\n};\n\nfunction DayCellButton({\n  date,\n  isToday,\n  isSelected,\n  eventCount,\n  accentColor,\n  textColor,\n  showEventDensity,\n  onClick,\n}: DayCellButtonProps) {\n  const dotCount = showEventDensity\n    ? Math.min(eventCount, 3)\n    : eventCount > 0\n      ? 1\n      : 0;\n\n  const baseClasses =\n    \"group relative flex aspect-square w-full flex-col items-center justify-center rounded-lg text-sm tabular-nums transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0\";\n\n  const stateClasses = isSelected\n    ? `bg-${accentColor} text-${accentColor}-foreground focus-visible:ring-${accentColor}/40`\n    : isToday\n      ? `bg-${accentColor}/10 text-${accentColor} font-semibold hover:bg-${accentColor}/20 focus-visible:ring-${accentColor}/40`\n      : `text-${textColor} hover:bg-${accentColor}/10 focus-visible:ring-${accentColor}/40`;\n\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      aria-label={date.toLocaleDateString(\"en-US\", {\n        weekday: \"long\",\n        month: \"long\",\n        day: \"numeric\",\n      })}\n      aria-current={isToday ? \"date\" : undefined}\n      aria-pressed={isSelected}\n      className={`${baseClasses} ${stateClasses}`}\n    >\n      <span className=\"leading-none\">{date.getDate()}</span>\n      {dotCount > 0 && (\n        <span\n          aria-hidden=\"true\"\n          className=\"absolute bottom-0.5 flex items-center gap-[2px]\"\n        >\n          {Array.from({ length: dotCount }).map((_, i) => (\n            <span\n              key={i}\n              className={`size-1 rounded-full ${\n                isSelected\n                  ? `bg-${accentColor}-foreground/70`\n                  : `bg-${accentColor}`\n              }`}\n            />\n          ))}\n        </span>\n      )}\n    </button>\n  );\n}\n\ntype EventCardProps = {\n  event: CalendarEvent;\n  accentColor: ColorOptions;\n  textColor: ColorOptions;\n};\n\n// Events render in the viewer's own timezone (browser local) so the same time\n// reads consistently on Portal and mobile. timeZoneName \"short\" appends the\n// viewer's zone abbreviation (e.g. MST).\nconst formatLongDateTime = (iso: string): string => {\n  const d = new Date(iso);\n  const datePart = d.toLocaleDateString(\"en-US\", {\n    month: \"short\",\n    day: \"numeric\",\n    year: \"numeric\",\n  });\n  const timePart = d.toLocaleTimeString(\"en-US\", {\n    hour: \"numeric\",\n    minute: \"2-digit\",\n    timeZoneName: \"short\",\n  });\n  return `${datePart} at ${timePart}`;\n};\n\nconst isSafeHttpUrl = (url: string): boolean => {\n  try {\n    const parsed = new URL(url);\n    return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n  } catch {\n    return false;\n  }\n};\n\nconst deriveEventStatus = (\n  event: CalendarEvent,\n): { label: string; tone: \"upcoming\" | \"live\" | \"past\" } => {\n  const rawStatus = event.status?.trim();\n  const normalized = rawStatus?.toLowerCase();\n  if (rawStatus && normalized !== \"active\" && normalized !== \"confirmed\") {\n    const label =\n      rawStatus.charAt(0).toUpperCase() + rawStatus.slice(1).toLowerCase();\n    return { label, tone: \"past\" };\n  }\n  const startMs = new Date(event.start).getTime();\n  const endMs = new Date(event.end).getTime();\n  const now = Date.now();\n  if (now < startMs) return { label: \"Upcoming\", tone: \"upcoming\" };\n  if (now <= endMs) return { label: \"Live\", tone: \"live\" };\n  return { label: \"Past\", tone: \"past\" };\n};\n\nfunction EventCard({ event, accentColor, textColor }: EventCardProps) {\n  const accentVar = `var(--color-${accentColor})`;\n  const barColor = event.color || accentVar;\n  const startDate = new Date(event.start);\n  // All events, all-day included, render in the viewer's own timezone, so the\n  // badge, start/end, and calendar cell agree with each other and with mobile.\n  const weekday = startDate.toLocaleDateString(\"en-US\", {\n    weekday: \"short\",\n  });\n  const monthDay = startDate.toLocaleDateString(\"en-US\", {\n    month: \"short\",\n    day: \"numeric\",\n  });\n  const status = deriveEventStatus(event);\n  const description = event.description?.body;\n\n  const startDisplay = formatLongDateTime(event.start);\n  const endDisplay = formatLongDateTime(event.end);\n\n  const statusToneClasses =\n    status.tone === \"live\"\n      ? `bg-${accentColor}/15 text-${accentColor}`\n      : status.tone === \"upcoming\"\n        ? `bg-${accentColor}/10 text-${accentColor}`\n        : `bg-${textColor}/10 text-${textColor}/60`;\n\n  return (\n    <article\n      className={`relative overflow-hidden rounded-lg border border-${textColor}/10`}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"absolute inset-y-0 left-0 w-[3px]\"\n        style={{ backgroundColor: barColor }}\n      />\n\n      {event.imageUrl && (\n        <img\n          src={event.imageUrl}\n          alt=\"\"\n          className=\"aspect-[16/7] w-full object-cover\"\n        />\n      )}\n\n      <div className=\"flex flex-col gap-4 p-4 pl-5\">\n        <div className=\"flex items-start gap-4\">\n          <div\n            className={`shrink-0 text-${textColor} leading-tight tabular-nums`}\n          >\n            <div className={`text-xs font-semibold text-${textColor}/55`}>\n              {weekday}\n            </div>\n            <div className=\"text-2xl font-bold tracking-[-0.015em]\">\n              {monthDay}\n            </div>\n          </div>\n\n          <div className=\"min-w-0 flex-1\">\n            <h4\n              className={`text-base font-bold text-${textColor} leading-tight tracking-[-0.01em]`}\n            >\n              {event.title}\n            </h4>\n            {description && (\n              <p\n                className={`mt-1 text-sm leading-snug whitespace-pre-wrap text-${textColor}/65`}\n              >\n                {description}\n              </p>\n            )}\n          </div>\n        </div>\n\n        <div className=\"flex flex-col gap-2.5\">\n          <div className=\"flex items-start gap-2\">\n            <Calendar\n              className={`mt-0.5 size-4 shrink-0 text-${textColor}/55`}\n            />\n            <div\n              className={`text-sm leading-snug text-${textColor}/80 tabular-nums`}\n            >\n              <div>\n                <span className=\"font-semibold\">Start</span> {startDisplay}\n              </div>\n              <div>\n                <span className=\"font-semibold\">End</span> {endDisplay}\n              </div>\n            </div>\n          </div>\n\n          <div>\n            <span\n              className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${statusToneClasses}`}\n            >\n              {status.label}\n            </span>\n          </div>\n\n          {event.url && isSafeHttpUrl(event.url) && (\n            <a\n              href={event.url}\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className={`flex items-center gap-2 text-sm text-${accentColor} break-all hover:underline`}\n            >\n              <Link2 className={`size-4 shrink-0 text-${textColor}/55`} />\n              <span>{event.url}</span>\n            </a>\n          )}\n\n          {event.venue && (\n            <a\n              href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(event.venue)}`}\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className={`flex items-start gap-2 text-sm text-${accentColor} hover:underline`}\n            >\n              <MapPin\n                className={`mt-0.5 size-4 shrink-0 text-${textColor}/55`}\n              />\n              <span>{event.venue}</span>\n            </a>\n          )}\n        </div>\n      </div>\n    </article>\n  );\n}\n\ntype NavButtonProps = {\n  icon: LucideIcon;\n  label: string;\n  variant: \"ghost\" | \"accent\";\n  accentColor: ColorOptions;\n  textColor: ColorOptions;\n  onClick: () => void;\n};\n\nfunction NavButton({\n  icon: Icon,\n  label,\n  variant,\n  accentColor,\n  textColor,\n  onClick,\n}: NavButtonProps) {\n  const classes =\n    variant === \"accent\"\n      ? `bg-${accentColor} text-${accentColor}-foreground hover:bg-${accentColor}/90 focus-visible:ring-${accentColor}/40`\n      : `bg-${textColor}/5 text-${textColor} hover:bg-${textColor}/10 focus-visible:ring-${textColor}/20`;\n\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      aria-label={label}\n      className={`flex size-8 items-center justify-center rounded-full text-[12px] transition-colors focus:outline-none focus-visible:ring-2 ${classes}`}\n    >\n      <Icon className=\"size-4\" />\n    </button>\n  );\n}\n\ntype CalendarView = {\n  month: number;\n  year: number;\n};\n\nconst getInitialCalendarView = (): CalendarView => {\n  const now = new Date();\n  return { month: now.getMonth(), year: now.getFullYear() };\n};\n\nfunction useCalendarNavigation(\n  setSelectedDate: React.Dispatch<React.SetStateAction<Date | null>>,\n) {\n  const [view, setView] = useState(getInitialCalendarView);\n  const [gridTransitioning, setGridTransitioning] = useState(false);\n  const transitionTimeoutRef = useRef<number | null>(null);\n\n  useEffect(\n    () => () => {\n      if (transitionTimeoutRef.current !== null) {\n        window.clearTimeout(transitionTimeoutRef.current);\n      }\n    },\n    [],\n  );\n\n  const clearPendingTransition = useCallback(() => {\n    if (transitionTimeoutRef.current !== null) {\n      window.clearTimeout(transitionTimeoutRef.current);\n      transitionTimeoutRef.current = null;\n    }\n  }, []);\n\n  const navigate = useCallback(\n    (direction: -1 | 1) => {\n      clearPendingTransition();\n      setGridTransitioning(true);\n      transitionTimeoutRef.current = window.setTimeout(() => {\n        setView((prev) => {\n          const next = prev.month + direction;\n          if (next < 0) return { month: 11, year: prev.year - 1 };\n          if (next > 11) return { month: 0, year: prev.year + 1 };\n          return { month: next, year: prev.year };\n        });\n        setGridTransitioning(false);\n        transitionTimeoutRef.current = null;\n      }, 120);\n    },\n    [clearPendingTransition],\n  );\n\n  const goToToday = useCallback(() => {\n    clearPendingTransition();\n    const now = new Date();\n    setGridTransitioning(true);\n    transitionTimeoutRef.current = window.setTimeout(() => {\n      setView({ month: now.getMonth(), year: now.getFullYear() });\n      setSelectedDate(now);\n      setGridTransitioning(false);\n      transitionTimeoutRef.current = null;\n    }, 80);\n  }, [clearPendingTransition, setSelectedDate]);\n\n  return { view, gridTransitioning, navigate, goToToday };\n}\n\n// The local Date whose calendar day equals the event's day in the viewer's own\n// timezone, so the dot sits on the same day the card shows it starting. Builder,\n// preview, and live portal agree because all read the same start/end instant,\n// whichever adapter fetched it.\nconst eventDayAnchor = (event: CalendarEvent, useEnd = false): Date => {\n  const iso = useEnd ? event.end : event.start;\n  return startOfDay(new Date(iso));\n};\n\nfunction useCalendarEventIndex(\n  events: CalendarEvent[],\n  selectedDate: Date | null,\n) {\n  const eventsByDate = useMemo(() => {\n    const map = new Map<string, CalendarEvent[]>();\n    for (const event of events) {\n      const start = eventDayAnchor(event);\n      const end = eventDayAnchor(event, true);\n      for (let cur = start; cur <= end; cur = addDays(cur, 1)) {\n        const key = `${cur.getFullYear()}-${cur.getMonth()}-${cur.getDate()}`;\n        const list = map.get(key);\n        if (list) {\n          list.push(event);\n        } else {\n          map.set(key, [event]);\n        }\n      }\n    }\n    return map;\n  }, [events]);\n\n  const lookupEventsForDate = useCallback(\n    (date: Date): CalendarEvent[] => {\n      const key = `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;\n      return eventsByDate.get(key) ?? [];\n    },\n    [eventsByDate],\n  );\n\n  const selectedDateEvents = useMemo(() => {\n    if (!selectedDate) return [];\n    return lookupEventsForDate(selectedDate);\n  }, [selectedDate, lookupEventsForDate]);\n\n  return { lookupEventsForDate, selectedDateEvents };\n}\n\ntype CalendarWidgetProps = ComponentProps<\"div\"> & {\n  // Title\n  titleEnabled?: boolean;\n  titleText?: string;\n  titleFontSize?: FontSizeOptions;\n  titleColor?: ColorOptions;\n\n  // Styling\n  background?: BackgroundValue;\n  textColor?: ColorOptions;\n  accentColor?: ColorOptions;\n  padding?: PaddingOptions;\n  borderRadius?: BorderRadiusOptions;\n  borderWidth?: BorderWidthOptions;\n  borderColor?: ColorOptions;\n\n  // Premium polish (new, additive)\n  showEventDensity?: boolean;\n  showTodayButton?: boolean;\n  weekendDim?: boolean;\n  showYearEyebrow?: boolean;\n};\n\nexport function CalendarWidget({\n  titleEnabled = true,\n  titleText = \"Calendar\",\n  titleFontSize = \"xl\",\n  titleColor = \"foreground\",\n\n  background = { type: \"solid\", color: \"background\" },\n  textColor = \"foreground\",\n  accentColor = \"primary\",\n  padding = 4,\n  borderRadius = \"md\",\n  borderWidth = \"none\",\n  borderColor = \"muted\",\n\n  showEventDensity = true,\n  showTodayButton = true,\n  weekendDim = true,\n  showYearEyebrow = true,\n\n  className,\n  ...props\n}: CalendarWidgetProps): React.JSX.Element {\n  const backgroundColor = background.color || \"background\";\n  const backgroundImage =\n    (background.resource?.image_url || background.resource?.imageUrl) &&\n    background.type === \"image\"\n      ? `url(${background.resource.image_url || background.resource.imageUrl})`\n      : \"none\";\n\n  const [isCollapsed, setIsCollapsed] = useState(false);\n  const [selectedDate, setSelectedDate] = useState<Date | null>(\n    () => new Date(),\n  );\n  const { view, gridTransitioning, navigate, goToToday } =\n    useCalendarNavigation(setSelectedDate);\n  const currentMonth = view.month;\n  const currentYear = view.year;\n\n  const { data: events = [], isLoading, isError } = useCalendarEvents();\n\n  const monthGrid = useMemo(\n    () => generateMonthGrid(currentYear, currentMonth),\n    [currentYear, currentMonth],\n  );\n  const weekGrid = generateWeekGrid();\n  const { lookupEventsForDate, selectedDateEvents } = useCalendarEventIndex(\n    events,\n    selectedDate,\n  );\n\n  const now = new Date();\n  const viewingCurrentMonth =\n    currentMonth === now.getMonth() && currentYear === now.getFullYear();\n\n  const monthLabel = new Date(currentYear, currentMonth).toLocaleString(\n    \"en-US\",\n    { month: \"long\" },\n  );\n  const yearLabel = String(currentYear);\n\n  const contextualDate = selectedDate\n    ? formatContextualDate(selectedDate)\n    : null;\n\n  return (\n    <div\n      className={`@container overflow-hidden rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} text-${textColor} ${className ?? \"\"}`}\n      style={{ backgroundImage }}\n      {...props}\n    >\n      {titleEnabled && titleText && (\n        <div className={`p-${padding} pb-0`}>\n          <h2\n            className={`text-${titleFontSize} text-${titleColor} font-bold tracking-[-0.012em]`}\n          >\n            {titleText}\n          </h2>\n        </div>\n      )}\n\n      {isLoading ? (\n        <div className={`p-${padding}`}>\n          <WidgetLoadingSkeleton minHeight={300} rows={4} />\n        </div>\n      ) : isError ? (\n        <ErrorState />\n      ) : (\n        <div className={`p-${padding}`}>\n          <div className=\"@md:flex @md:gap-6\">\n            <div className=\"@md:flex-none\">\n              {/* Header row: year eyebrow + month + asymmetric nav + Today pill */}\n              <div className=\"mb-4 flex items-start justify-between gap-3\">\n                <div className=\"flex min-w-0 flex-col\">\n                  {showYearEyebrow && (\n                    <span\n                      className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`}\n                    >\n                      {yearLabel}\n                    </span>\n                  )}\n                  <span\n                    className={`text-xl leading-tight font-bold tracking-[-0.015em] text-${textColor}`}\n                  >\n                    {monthLabel}\n                  </span>\n                </div>\n\n                <div className=\"flex shrink-0 items-center gap-1.5\">\n                  {showTodayButton && !viewingCurrentMonth && (\n                    <button\n                      type=\"button\"\n                      onClick={goToToday}\n                      className={`flex items-center gap-1 rounded-full bg-${accentColor}/10 px-2.5 py-1 text-[11px] font-semibold text-${accentColor} transition-colors hover:bg-${accentColor}/20 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40`}\n                    >\n                      <CalendarCheck className=\"size-3\" />\n                      Today\n                    </button>\n                  )}\n                  <NavButton\n                    icon={ChevronLeft}\n                    label=\"Previous month\"\n                    variant=\"ghost\"\n                    accentColor={accentColor}\n                    textColor={textColor}\n                    onClick={() => navigate(-1)}\n                  />\n                  <NavButton\n                    icon={ChevronRight}\n                    label=\"Next month\"\n                    variant=\"accent\"\n                    accentColor={accentColor}\n                    textColor={textColor}\n                    onClick={() => navigate(1)}\n                  />\n                </div>\n              </div>\n\n              {/* Day-of-week headers */}\n              <div className=\"mb-2 grid grid-cols-7 gap-1 text-center\">\n                {DAY_NAMES.map((day, idx) => {\n                  const isWeekend = idx === 0 || idx === 6;\n                  const dimmed = weekendDim && isWeekend;\n                  return (\n                    <div\n                      key={day}\n                      className={`text-[10px] font-semibold tracking-[0.12em] uppercase text-${textColor}/${dimmed ? \"40\" : \"55\"}`}\n                    >\n                      {day}\n                    </div>\n                  );\n                })}\n              </div>\n\n              {/* Grid wrapper (opacity transitions on month navigate) */}\n              <div\n                className=\"transition-opacity duration-150 ease-out\"\n                style={{ opacity: gridTransitioning ? 0.3 : 1 }}\n              >\n                {/* Collapsed week view on mobile */}\n                {isCollapsed && (\n                  <div className=\"grid grid-cols-7 gap-1 @md:hidden\">\n                    {weekGrid.map(({ date, isToday }) => (\n                      <DayCellButton\n                        key={date.toISOString()}\n                        date={date}\n                        isToday={isToday}\n                        isSelected={\n                          !!selectedDate && isSameDay(selectedDate, date)\n                        }\n                        eventCount={lookupEventsForDate(date).length}\n                        accentColor={accentColor}\n                        textColor={textColor}\n                        showEventDensity={showEventDensity}\n                        onClick={() => setSelectedDate(date)}\n                      />\n                    ))}\n                  </div>\n                )}\n\n                {/* Month grid */}\n                <div\n                  className={`grid grid-cols-7 gap-1 ${isCollapsed ? \"hidden @md:grid\" : \"grid\"}`}\n                >\n                  {monthGrid.map((cell, idx) => {\n                    if (!cell.date) {\n                      return (\n                        <div key={`empty-${idx}`} className=\"aspect-square\" />\n                      );\n                    }\n                    const eventCount = lookupEventsForDate(cell.date).length;\n                    return (\n                      <DayCellButton\n                        key={cell.date.toISOString()}\n                        date={cell.date}\n                        isToday={cell.isToday}\n                        isSelected={\n                          !!selectedDate && isSameDay(selectedDate, cell.date)\n                        }\n                        eventCount={eventCount}\n                        accentColor={accentColor}\n                        textColor={textColor}\n                        showEventDensity={showEventDensity}\n                        onClick={() => setSelectedDate(cell.date)}\n                      />\n                    );\n                  })}\n                </div>\n              </div>\n\n              {/* Mobile collapse toggle */}\n              <button\n                type=\"button\"\n                onClick={() => setIsCollapsed(!isCollapsed)}\n                className={`mt-2 flex w-full items-center justify-center gap-3 rounded-full p-1 text-${textColor}/40 transition-colors hover:text-${textColor}/60 @md:hidden`}\n                aria-label={\n                  isCollapsed ? \"Expand calendar\" : \"Collapse calendar\"\n                }\n              >\n                <div className={`h-px w-1/2 bg-${textColor}/20`} />\n                {isCollapsed ? (\n                  <ChevronsDown className=\"size-3\" />\n                ) : (\n                  <ChevronsUp className=\"size-3\" />\n                )}\n                <div className={`h-px w-1/2 bg-${textColor}/20`} />\n              </button>\n            </div>\n\n            {/* Events rail */}\n            <div\n              className={`mt-4 min-w-0 border-${textColor}/10 @md:relative @md:mt-0 @md:flex-1 @md:border-l`}\n            >\n              <div className=\"@md:absolute @md:inset-0 @md:overflow-y-auto @md:pr-1 @md:pl-6\">\n                {/* Context header */}\n                {contextualDate && (\n                  <div className=\"mb-3\">\n                    {contextualDate.lead && (\n                      <div\n                        className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${accentColor}`}\n                      >\n                        {contextualDate.lead}\n                      </div>\n                    )}\n                    <div\n                      className={`text-sm font-semibold text-${textColor} tabular-nums`}\n                    >\n                      {contextualDate.detail}\n                    </div>\n                  </div>\n                )}\n\n                {/* Events list with soft fade-in keyed by selected date */}\n                <div\n                  key={selectedDate?.toISOString() ?? \"none\"}\n                  className=\"animate-in fade-in slide-in-from-bottom-2 flex flex-col gap-3 duration-200 ease-out\"\n                >\n                  {selectedDateEvents.length > 0 ? (\n                    selectedDateEvents.map((event, idx) => (\n                      <EventCard\n                        key={`${event.id}-${idx}`}\n                        event={event}\n                        accentColor={accentColor}\n                        textColor={textColor}\n                      />\n                    ))\n                  ) : (\n                    <div\n                      className={`flex flex-col items-start gap-1 rounded-md border border-dashed border-${textColor}/15 px-3 py-3`}\n                    >\n                      <div className=\"flex items-center gap-1.5\">\n                        <CalendarCheck\n                          className={`size-3 text-${textColor}/40`}\n                        />\n                        <span\n                          className={`text-[11px] font-semibold text-${textColor}/60`}\n                        >\n                          Nothing scheduled\n                        </span>\n                      </div>\n                      <span className={`text-[11px] text-${textColor}/45`}>\n                        Enjoy the breather.\n                      </span>\n                    </div>\n                  )}\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n\nexport const calendarWidgetPropertySchema: WidgetPropertySchema = {\n  widgetType: \"CalendarWidget\",\n  displayName: \"Calendar Widget\",\n  tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n  fields: [\n    // Title group\n    {\n      key: \"titleEnabled\",\n      label: \"Widget Title\",\n      type: \"boolean\",\n      description: \"Enable the title displayed above the calendar\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Title\",\n    },\n    {\n      key: \"titleText\",\n      label: \"Title\",\n      type: \"text\",\n      description: \"Title text displayed above the calendar\",\n      defaultValue: \"Calendar\",\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    },\n    getFontSizeField({\n      key: \"titleFontSize\",\n      label: \"Title Font Size\",\n      description: \"Font size for the widget title\",\n      defaultValue: \"xl\",\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    }),\n    getColorField({\n      key: \"titleColor\",\n      label: \"Title Color\",\n      description: \"Color for the widget title\",\n      defaultValue: \"foreground\",\n      tab: \"styling\",\n      group: \"Title\",\n      requiresKeyToBeTrue: \"titleEnabled\",\n    }),\n\n    // Design group\n    {\n      type: \"background\",\n      key: \"background\",\n      label: \"Background\",\n      description: \"Background for the calendar container\",\n      defaultValue: { type: \"solid\", color: \"background\" },\n      tab: \"styling\",\n      group: \"Design\",\n    },\n    getColorField({\n      key: \"textColor\",\n      label: \"Text Color\",\n      description: \"Default text color for calendar content\",\n      defaultValue: \"foreground\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getColorField({\n      key: \"accentColor\",\n      label: \"Accent Color\",\n      description:\n        \"Drives today highlight, event dots, Today pill, and selected day\",\n      defaultValue: \"primary\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    {\n      key: \"separator\",\n      type: \"separator\",\n      label: \"Separator\",\n      tab: \"styling\",\n      group: \"Design\",\n    },\n    getPaddingField({\n      key: \"padding\",\n      label: \"Padding\",\n      description: \"Padding around the calendar container\",\n      defaultValue: 4,\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getBorderRadiusField({\n      key: \"borderRadius\",\n      label: \"Border Radius\",\n      description: \"Border radius for the calendar container\",\n      defaultValue: \"md\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getBorderWidthField({\n      key: \"borderWidth\",\n      label: \"Border Width\",\n      description: \"Border width for the calendar container\",\n      defaultValue: \"none\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getBorderColorField({\n      key: \"borderColor\",\n      label: \"Border Color\",\n      description: \"Border color for the calendar container\",\n      defaultValue: \"muted\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n\n    // Polish group (new)\n    {\n      key: \"showYearEyebrow\",\n      label: \"Year Eyebrow\",\n      type: \"boolean\",\n      description:\n        \"Small uppercase year label above the month (e.g. '2026 / November').\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Polish\",\n    },\n    {\n      key: \"showTodayButton\",\n      label: \"Today Button\",\n      type: \"boolean\",\n      description: \"Show a 'Today' pill when viewing a different month.\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Polish\",\n    },\n    {\n      key: \"showEventDensity\",\n      label: \"Event Density Dots\",\n      type: \"boolean\",\n      description:\n        \"Show 1–3 dots per day based on event count (off = single dot).\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Polish\",\n    },\n    {\n      key: \"weekendDim\",\n      label: \"Dim Weekends\",\n      type: \"boolean\",\n      description:\n        \"Subtly dim the Sun/Sat day-of-week headers for visual rhythm.\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Polish\",\n    },\n  ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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Ac,aAAa,IAAI,OA+BhC,CACF;;KACF,CAAA,CACF;;GACF,CAAA,CAEJ;;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD,iBAAiB;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EACF,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EAGF;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;IAAE,MAAM;IAAS,OAAO;IAAc;GACpD,KAAK;GACL,OAAO;GACR;EACD,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EAGF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACF;CACF"}