{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "calendar",
  "type": "registry:ui",
  "registryDependencies": [],
  "dependencies": ["motion", "lucide-react", "date-fns"],
  "devDependencies": [],
  "files": [
    {
      "path": "calendar.tsx",
      "content": "\"use client\";\n\nimport {\n  addDays,\n  addMonths,\n  eachDayOfInterval,\n  endOfMonth,\n  endOfWeek,\n  format,\n  isAfter,\n  isBefore,\n  isSameDay,\n  isSameMonth,\n  isToday,\n  isWithinInterval,\n  type Locale,\n  setMonth,\n  setYear,\n  startOfDay,\n  startOfMonth,\n  startOfWeek,\n  subMonths,\n} from \"date-fns\";\nimport { ChevronDown, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type CSSProperties,\n  forwardRef,\n  type KeyboardEvent,\n  type ReactNode,\n  type RefObject,\n  useCallback,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst componentThemeClassName =\n  \"[--ic-background:#ffffff] [--ic-foreground:#111111] [--ic-primary:#111111] [--ic-secondary:#646b75] [--ic-surface-border:#e9edf2] [--ic-border:#e3e7ec] [--ic-card:#ffffff] [--ic-card-foreground:#111111] [--ic-muted:#f5f7fa] [--ic-muted-foreground:#6d7480] [--ic-accent:#f3f5f8] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] [--ic-accent-foreground:#111111] [--ic-input:#e3e7ec] [--ic-ring:rgba(17,17,17,0.16)] [--ic-destructive:#dc2626] [--ic-paper:#fcfcfd] [--ic-popover-foreground:#111111] [--ic-brand:#0ea5e9] [--ic-brand-soft:#bae6fd] [--ic-primary-foreground:#ffffff] [--ic-shadow-soft:0_18px_38px_-24px_rgba(15,23,42,0.35)] [--ic-chart-1:oklch(0.52_0.19_254)] [--ic-chart-2:oklch(0.74_0.11_232)] [--ic-chart-3:oklch(0.42_0.16_262)] [--ic-chart-4:oklch(0.84_0.07_228)] [--ic-chart-5:oklch(0.62_0.14_240)] [--color-background:var(--ic-background)] [--color-foreground:var(--ic-foreground)] [--color-primary:var(--ic-primary)] [--color-primary-foreground:var(--ic-primary-foreground)] [--color-secondary:var(--ic-secondary)] [--color-border:var(--ic-border)] [--color-card:var(--ic-card)] [--color-card-foreground:var(--ic-card-foreground)] [--color-muted:var(--ic-muted)] [--color-muted-foreground:var(--ic-muted-foreground)] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] [--color-input:var(--ic-input)] [--color-ring:var(--ic-ring)] [--color-destructive:var(--ic-destructive)] [--color-paper:var(--ic-paper)] [--color-popover-foreground:var(--ic-popover-foreground)] [--color-brand:var(--ic-brand)] [--color-brand-soft:var(--ic-brand-soft)] [--color-chart-1:var(--ic-chart-1)] [--color-chart-2:var(--ic-chart-2)] [--color-chart-3:var(--ic-chart-3)] [--color-chart-4:var(--ic-chart-4)] [--color-chart-5:var(--ic-chart-5)] dark:[--ic-background:#111111] dark:[--ic-foreground:#f6f3ec] dark:[--ic-primary:#f6f3ec] dark:[--ic-primary-foreground:#111111] dark:[--ic-secondary:#cbc6bb] dark:[--ic-surface-border:#2a2a25] dark:[--ic-border:#2b2a25] dark:[--ic-card:#111111] dark:[--ic-card-foreground:#f6f3ec] dark:[--ic-muted:#171716] dark:[--ic-muted-foreground:#9a958a] dark:[--ic-accent:#1a1a18] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] dark:[--ic-accent-foreground:#f6f3ec] dark:[--ic-input:#2b2a25] dark:[--ic-ring:rgba(246,243,236,0.18)] dark:[--ic-destructive:#f87171] dark:[--ic-paper:#171716] dark:[--ic-popover-foreground:#f6f3ec] dark:[--ic-brand:#38bdf8] dark:[--ic-brand-soft:#0c4a6e] dark:[--ic-shadow-soft:0_20px_44px_-28px_rgba(0,0,0,0.6)] dark:[--ic-chart-1:oklch(0.68_0.17_250)] dark:[--ic-chart-2:oklch(0.82_0.09_225)] dark:[--ic-chart-3:oklch(0.58_0.15_260)] dark:[--ic-chart-4:oklch(0.75_0.12_235)] dark:[--ic-chart-5:oklch(0.88_0.06_220)]\";\n\nconst controlCornerClassName =\n  \"supports-[corner-shape:squircle]:corner-squircle\";\n\nconst focusVisibleClassName =\n  \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ic-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--ic-card)]\";\n\nconst SPRING_EASE: [number, number, number, number] = [0.34, 1.56, 0.64, 1];\nconst SMOOTH_EASE: [number, number, number, number] = [0.4, 0, 0.2, 1];\nconst WEEK_LENGTH = 7;\nconst FIXED_WEEK_COUNT = 6;\nconst YEAR_GRID_SIZE = 12;\nconst MONTH_GRID_COLS = 3;\nconst MAX_DISABLED_SCAN = 366;\n\nconst MONTH_GRID_VARIANTS = {\n  center: { opacity: 1, scale: 1, x: 0 },\n  enter: (direction: number) => ({\n    opacity: 0,\n    scale: 0.985,\n    x: direction === 0 ? 0 : direction * 14,\n  }),\n  exit: (direction: number) => ({\n    opacity: 0,\n    scale: 0.985,\n    x: direction === 0 ? 0 : direction * -14,\n  }),\n};\n\ntype CalendarSize = \"sm\" | \"md\" | \"lg\";\ntype WeekStartsOn = 0 | 1 | 2 | 3 | 4 | 5 | 6;\ntype CalendarMode = \"single\" | \"range\";\n\nexport type CalendarRange = {\n  from?: Date;\n  to?: Date;\n};\n\nexport type CalendarLabels = {\n  today: string;\n  selected: string;\n  outsideMonth: string;\n  unavailable: string;\n  noDateSelected: string;\n  chooseMonth: string;\n  chooseYear: string;\n  previousMonth: string;\n  nextMonth: string;\n  previousYears: string;\n  nextYears: string;\n  selectMonth: string;\n  selectYear: string;\n  rangeStart: string;\n  rangeEnd: string;\n  rangeMiddle: string;\n};\n\nexport const DEFAULT_CALENDAR_LABELS: CalendarLabels = {\n  today: \"Today\",\n  selected: \"Selected\",\n  outsideMonth: \"Outside current month\",\n  unavailable: \"Unavailable\",\n  noDateSelected: \"No date selected\",\n  chooseMonth: \"Choose month\",\n  chooseYear: \"Choose year\",\n  previousMonth: \"Previous month\",\n  nextMonth: \"Next month\",\n  previousYears: \"Previous years\",\n  nextYears: \"Next years\",\n  selectMonth: \"Select month\",\n  selectYear: \"Select year\",\n  rangeStart: \"Range start\",\n  rangeEnd: \"Range end\",\n  rangeMiddle: \"In selected range\",\n};\n\nexport interface CalendarProps {\n  selected?: Date | null;\n  defaultSelected?: Date | null;\n  onSelect?: (date: Date | null) => void;\n  range?: CalendarRange;\n  defaultRange?: CalendarRange;\n  onRangeSelect?: (range: CalendarRange) => void;\n  mode?: CalendarMode;\n  month?: Date;\n  defaultMonth?: Date;\n  onMonthChange?: (month: Date) => void;\n  disabled?: (date: Date) => boolean;\n  locale?: Locale;\n  labels?: Partial<CalendarLabels>;\n  size?: CalendarSize;\n  weekStartsOn?: WeekStartsOn;\n  minYear?: number;\n  maxYear?: number;\n  minDate?: Date;\n  maxDate?: Date;\n  showOutsideDays?: boolean;\n  fixedWeeks?: boolean;\n  modifiers?: Record<string, (date: Date) => boolean>;\n  modifierLabels?: Record<string, string>;\n  className?: string;\n  id?: string;\n  name?: string;\n}\n\ntype CalendarPalette = {\n  cardBackground: string;\n  cardBorder: string;\n  cardShadow: string;\n  textPrimary: string;\n  textMuted: string;\n  textDim: string;\n  titleColor: string;\n  navBackground: string;\n  navForeground: string;\n  navHoverBackground: string;\n  dayHoverBackground: string;\n  dayDisabledForeground: string;\n  selectedGradient: string;\n  selectedForeground: string;\n  rangeBackground: string;\n  todayBackground: string;\n  focusRing: string;\n  popoverBackground: string;\n  popoverBorder: string;\n  popoverShadow: string;\n  pickerHoverBackground: string;\n  modifierDot: string;\n};\n\ntype CalendarDimensions = {\n  cardPadding: number;\n  cardRadius: number;\n  dayCellFontSize: number;\n  dayCellMinHeight: number;\n  dayCellRadius: number;\n  headerGap: number;\n  monthFontSize: number;\n  monthTopMargin: number;\n  navButtonSize: number;\n  navGap: number;\n  navIconSize: number;\n  tableCellPadding: number;\n  tableHeaderFontSize: number;\n  tableHeaderPaddingBottom: number;\n  weekRowGap: number;\n  maxWidth: number;\n};\n\nconst CALENDAR_PALETTE: CalendarPalette = {\n  cardBackground: \"var(--ic-card)\",\n  cardBorder:\n    \"1px solid color-mix(in srgb, var(--ic-foreground) 4%, transparent)\",\n  cardShadow: \"var(--ic-shadow-soft)\",\n  textPrimary: \"var(--ic-foreground)\",\n  textMuted: \"var(--ic-muted-foreground)\",\n  textDim: \"color-mix(in srgb, var(--ic-muted-foreground) 68%, transparent)\",\n  titleColor: \"var(--ic-foreground)\",\n  navBackground: \"transparent\",\n  navForeground: \"var(--ic-foreground)\",\n  navHoverBackground: \"var(--ic-accent)\",\n  dayHoverBackground: \"var(--ic-accent)\",\n  dayDisabledForeground: \"var(--ic-muted-foreground)\",\n  selectedGradient: \"var(--ic-primary)\",\n  selectedForeground: \"var(--ic-primary-foreground)\",\n  rangeBackground: \"color-mix(in srgb, var(--ic-primary) 14%, transparent)\",\n  todayBackground: \"var(--ic-muted)\",\n  focusRing: \"var(--ic-ring)\",\n  popoverBackground: \"var(--ic-card)\",\n  popoverBorder:\n    \"1px solid color-mix(in srgb, var(--ic-foreground) 4%, transparent)\",\n  popoverShadow:\n    \"0 12px 32px -18px color-mix(in srgb, var(--ic-foreground) 18%, transparent)\",\n  pickerHoverBackground: \"var(--ic-accent)\",\n  modifierDot: \"var(--ic-brand)\",\n};\n\nconst CALENDAR_DIMENSIONS: Record<CalendarSize, CalendarDimensions> = {\n  sm: {\n    cardPadding: 8,\n    cardRadius: 11,\n    dayCellFontSize: 14,\n    dayCellMinHeight: 28,\n    dayCellRadius: 6,\n    headerGap: 16,\n    maxWidth: 212,\n    monthFontSize: 14,\n    monthTopMargin: 0,\n    navButtonSize: 28,\n    navGap: 4,\n    navIconSize: 16,\n    tableCellPadding: 0,\n    tableHeaderFontSize: 12,\n    tableHeaderPaddingBottom: 0,\n    weekRowGap: 8,\n  },\n  md: {\n    cardPadding: 8,\n    cardRadius: 11,\n    dayCellFontSize: 15,\n    dayCellMinHeight: 32,\n    dayCellRadius: 7,\n    headerGap: 16,\n    maxWidth: 240,\n    monthFontSize: 15,\n    monthTopMargin: 0,\n    navButtonSize: 32,\n    navGap: 6,\n    navIconSize: 16,\n    tableCellPadding: 0,\n    tableHeaderFontSize: 13,\n    tableHeaderPaddingBottom: 0,\n    weekRowGap: 8,\n  },\n  lg: {\n    cardPadding: 10,\n    cardRadius: 14,\n    dayCellFontSize: 16,\n    dayCellMinHeight: 38,\n    dayCellRadius: 8,\n    headerGap: 16,\n    maxWidth: 282,\n    monthFontSize: 16,\n    monthTopMargin: 0,\n    navButtonSize: 38,\n    navGap: 8,\n    navIconSize: 18,\n    tableCellPadding: 0,\n    tableHeaderFontSize: 14,\n    tableHeaderPaddingBottom: 0,\n    weekRowGap: 8,\n  },\n};\n\nconst getDateKey = (date: Date) => format(date, \"yyyy-MM-dd\");\n\nconst getCalendarOptions = (locale?: Locale, weekStartsOn?: WeekStartsOn) =>\n  weekStartsOn === undefined ? { locale } : { locale, weekStartsOn };\n\nconst createIsDateDisabled = ({\n  disabled,\n  minDate,\n  maxDate,\n}: {\n  disabled?: (date: Date) => boolean;\n  minDate?: Date;\n  maxDate?: Date;\n}) => {\n  const min = minDate ? startOfDay(minDate) : undefined;\n  const max = maxDate ? startOfDay(maxDate) : undefined;\n\n  return (date: Date) => {\n    const day = startOfDay(date);\n    if (min && isBefore(day, min)) return true;\n    if (max && isAfter(day, max)) return true;\n    return disabled?.(date) ?? false;\n  };\n};\n\nconst findFirstInteractiveDay = (\n  visibleMonth: Date,\n  isDateDisabled: (date: Date) => boolean\n) =>\n  eachDayOfInterval({\n    start: startOfMonth(visibleMonth),\n    end: endOfMonth(visibleMonth),\n  }).find((day) => !isDateDisabled(day)) ?? startOfMonth(visibleMonth);\n\nconst resolveFocusableDate = (\n  visibleMonth: Date,\n  preferredDate: Date | null | undefined,\n  isDateDisabled: (date: Date) => boolean\n) => {\n  if (\n    preferredDate &&\n    isSameMonth(preferredDate, visibleMonth) &&\n    !isDateDisabled(preferredDate)\n  ) {\n    return preferredDate;\n  }\n  const today = new Date();\n  if (isSameMonth(today, visibleMonth) && !isDateDisabled(today)) {\n    return today;\n  }\n  return findFirstInteractiveDay(visibleMonth, isDateDisabled);\n};\n\nconst findInteractiveDate = (\n  preferredDate: Date,\n  step: 1 | -1,\n  isDateDisabled: (date: Date) => boolean\n) => {\n  let candidate = preferredDate;\n  for (let index = 0; index < MAX_DISABLED_SCAN; index += 1) {\n    if (!isDateDisabled(candidate)) return candidate;\n    candidate = addDays(candidate, step);\n  }\n  return preferredDate;\n};\n\nconst normalizeRange = (range?: CalendarRange): CalendarRange => {\n  const from = range?.from;\n  const to = range?.to;\n  if (!(from && to)) return { from, to };\n  if (isBefore(startOfDay(from), startOfDay(to))) {\n    return { from, to };\n  }\n  return { from: to, to: from };\n};\n\nconst getRangeBounds = (range?: CalendarRange) => {\n  const normalized = normalizeRange(range);\n  if (!normalized.from) {\n    return null;\n  }\n  const end = normalized.to ?? normalized.from;\n  return {\n    start: startOfDay(normalized.from),\n    end: startOfDay(end),\n  };\n};\n\nconst getDayAriaLabel = ({\n  day,\n  locale,\n  labels,\n  today,\n  isSelected,\n  inMonth,\n  isDisabled,\n  rangeRole,\n  modifierNames,\n}: {\n  day: Date;\n  locale?: Locale;\n  labels: CalendarLabels;\n  today: boolean;\n  isSelected: boolean;\n  inMonth: boolean;\n  isDisabled: boolean;\n  rangeRole?: \"start\" | \"end\" | \"middle\" | null;\n  modifierNames: string[];\n}) => {\n  const parts = [format(day, \"PPPP\", { locale })];\n  if (today) parts.push(labels.today);\n  if (isSelected) parts.push(labels.selected);\n  if (rangeRole === \"start\") parts.push(labels.rangeStart);\n  if (rangeRole === \"end\") parts.push(labels.rangeEnd);\n  if (rangeRole === \"middle\") parts.push(labels.rangeMiddle);\n  if (!inMonth) parts.push(labels.outsideMonth);\n  else if (isDisabled) parts.push(labels.unavailable);\n  if (modifierNames.length > 0) {\n    parts.push(modifierNames.join(\", \"));\n  }\n  return parts.join(\", \");\n};\n\ntype DayCellStatus = {\n  inMonth: boolean;\n  isDisabled: boolean;\n  isSelectable: boolean;\n  isSelected: boolean;\n  showTodayIndicator: boolean;\n  today: boolean;\n  rangeRole: \"start\" | \"end\" | \"middle\" | null;\n  inRange: boolean;\n};\n\nconst getDayCellStatus = ({\n  currentMonth,\n  day,\n  isDateDisabled,\n  selectedDate,\n  rangeBounds,\n  mode,\n}: {\n  currentMonth: Date;\n  day: Date;\n  isDateDisabled: (date: Date) => boolean;\n  selectedDate: Date | null;\n  rangeBounds: ReturnType<typeof getRangeBounds>;\n  mode: CalendarMode;\n}): DayCellStatus => {\n  const inMonth = isSameMonth(day, currentMonth);\n  const today = isToday(day);\n  const isDisabled = isDateDisabled(day);\n  const isSelectable = !isDisabled;\n\n  let isSelected = false;\n  let rangeRole: DayCellStatus[\"rangeRole\"] = null;\n  let inRange = false;\n\n  if (mode === \"range\" && rangeBounds) {\n    const dayStart = startOfDay(day);\n    inRange = isWithinInterval(dayStart, {\n      start: rangeBounds.start,\n      end: rangeBounds.end,\n    });\n    if (inRange) {\n      isSelected = true;\n      if (isSameDay(day, rangeBounds.start)) rangeRole = \"start\";\n      else if (isSameDay(day, rangeBounds.end)) rangeRole = \"end\";\n      else rangeRole = \"middle\";\n    }\n  } else if (selectedDate) {\n    isSelected = isSameDay(day, selectedDate);\n  }\n\n  return {\n    inMonth,\n    isDisabled,\n    isSelectable,\n    isSelected,\n    showTodayIndicator: today && !isSelected && !isDisabled,\n    today,\n    rangeRole,\n    inRange,\n  };\n};\n\nconst canNavigateToMonth = (\n  targetMonth: Date,\n  minDate?: Date,\n  maxDate?: Date\n) => {\n  const monthStart = startOfMonth(targetMonth);\n  const monthEnd = endOfMonth(targetMonth);\n  if (minDate && isBefore(monthEnd, startOfDay(minDate))) return false;\n  if (maxDate && isAfter(monthStart, startOfDay(maxDate))) return false;\n  return true;\n};\n\nconst isMonthIndexDisabled = (\n  currentMonth: Date,\n  monthIndex: number,\n  minDate?: Date,\n  maxDate?: Date\n) => !canNavigateToMonth(setMonth(currentMonth, monthIndex), minDate, maxDate);\n\nconst getActiveModifiers = (\n  day: Date,\n  modifiers?: Record<string, (date: Date) => boolean>\n) => {\n  if (!modifiers) return [] as string[];\n  return Object.entries(modifiers)\n    .filter(([, matcher]) => matcher(day))\n    .map(([key]) => key);\n};\n\nconst moveGridIndex = (\n  index: number,\n  key: string,\n  columns: number,\n  itemCount: number\n) => {\n  if (key === \"ArrowLeft\") return Math.max(0, index - 1);\n  if (key === \"ArrowRight\") return Math.min(itemCount - 1, index + 1);\n  if (key === \"ArrowUp\") return Math.max(0, index - columns);\n  if (key === \"ArrowDown\") return Math.min(itemCount - 1, index + columns);\n  if (key === \"Home\") return 0;\n  if (key === \"End\") return itemCount - 1;\n  return index;\n};\n\nconst getSyncedFocusedDate = ({\n  currentMonth,\n  focusedDate,\n  isDateDisabled,\n  mode,\n  rangeBounds,\n  selectedDate,\n}: {\n  currentMonth: Date;\n  focusedDate: Date;\n  isDateDisabled: (date: Date) => boolean;\n  mode: CalendarMode;\n  rangeBounds: ReturnType<typeof getRangeBounds>;\n  selectedDate: Date | null;\n}) => {\n  if (mode === \"single\") {\n    if (\n      selectedDate &&\n      isSameMonth(selectedDate, currentMonth) &&\n      !isDateDisabled(selectedDate) &&\n      !isSameDay(selectedDate, focusedDate)\n    ) {\n      return selectedDate;\n    }\n  } else if (rangeBounds) {\n    const anchor = rangeBounds.end;\n    if (\n      isSameMonth(anchor, currentMonth) &&\n      !isDateDisabled(anchor) &&\n      !isSameDay(anchor, focusedDate)\n    ) {\n      return anchor;\n    }\n  }\n\n  const focusOk =\n    isSameMonth(focusedDate, currentMonth) && !isDateDisabled(focusedDate);\n  if (focusOk) return focusedDate;\n\n  const preferred =\n    mode === \"single\" ? selectedDate : (rangeBounds?.end ?? rangeBounds?.start);\n  return resolveFocusableDate(currentMonth, preferred, isDateDisabled);\n};\n\nconst applyRangeDaySelection = (\n  day: Date,\n  selectedRange: CalendarRange\n): CalendarRange => {\n  const current = normalizeRange(selectedRange);\n  if (!current.from || (current.from && current.to)) {\n    return { from: day, to: undefined };\n  }\n  if (isSameDay(day, current.from)) {\n    return { from: day, to: day };\n  }\n  if (isBefore(startOfDay(day), startOfDay(current.from))) {\n    return { from: day, to: current.from };\n  }\n  return { from: current.from, to: day };\n};\n\nconst trapPickerTabKey = (\n  event: globalThis.KeyboardEvent,\n  pickerEl: HTMLDivElement\n) => {\n  if (event.key !== \"Tab\") return;\n\n  const focusable = Array.from(\n    pickerEl.querySelectorAll<HTMLButtonElement>(\"button:not([disabled])\")\n  );\n  if (focusable.length === 0) return;\n\n  const first = focusable[0];\n  const last = focusable.at(-1);\n  if (!(first && last)) return;\n\n  if (event.shiftKey && document.activeElement === first) {\n    event.preventDefault();\n    last.focus();\n  } else if (!event.shiftKey && document.activeElement === last) {\n    event.preventDefault();\n    first.focus();\n  }\n};\n\nconst DayCellMarkup = ({\n  activeModifierKeys,\n  calendarMotionId,\n  day,\n  dimensions,\n  palette,\n  reduceMotion,\n  showEndpointHighlight,\n  status,\n  useSelectionLayout,\n}: {\n  activeModifierKeys: string[];\n  calendarMotionId: string;\n  day: Date;\n  dimensions: CalendarDimensions;\n  palette: CalendarPalette;\n  reduceMotion: boolean | null;\n  showEndpointHighlight: boolean;\n  status: DayCellStatus;\n  useSelectionLayout: boolean;\n}) => (\n  <>\n    {status.inRange && status.rangeRole === \"middle\" ? (\n      <div\n        style={{\n          position: \"absolute\",\n          inset: 0,\n          background: palette.rangeBackground,\n          zIndex: 0,\n        }}\n      />\n    ) : null}\n    {status.showTodayIndicator ? (\n      <motion.div\n        className={controlCornerClassName}\n        layoutId={reduceMotion ? undefined : `${calendarMotionId}-today-dot`}\n        style={{\n          position: \"absolute\",\n          inset: 0,\n          borderRadius: dimensions.dayCellRadius,\n          background: palette.todayBackground,\n        }}\n      />\n    ) : null}\n    {showEndpointHighlight ? (\n      <motion.div\n        className={controlCornerClassName}\n        layoutId={\n          useSelectionLayout ? `${calendarMotionId}-selected-day` : undefined\n        }\n        style={{\n          position: \"absolute\",\n          inset: 0,\n          borderRadius: dimensions.dayCellRadius,\n          background: palette.selectedGradient,\n          zIndex: 1,\n        }}\n        transition={\n          reduceMotion\n            ? { duration: 0 }\n            : { type: \"spring\", stiffness: 400, damping: 30 }\n        }\n      />\n    ) : null}\n    <span\n      style={{\n        position: \"relative\",\n        zIndex: 2,\n        display: \"flex\",\n        flexDirection: \"column\",\n        alignItems: \"center\",\n        gap: 2,\n        color: showEndpointHighlight ? palette.selectedForeground : undefined,\n        fontWeight: showEndpointHighlight ? 600 : undefined,\n      }}\n    >\n      {format(day, \"d\")}\n      {activeModifierKeys.length > 0 ? (\n        <span aria-hidden style={{ display: \"flex\", gap: 2 }}>\n          {activeModifierKeys.slice(0, 3).map((key) => (\n            <span\n              key={key}\n              style={{\n                width: 4,\n                height: 4,\n                borderRadius: 999,\n                background: palette.modifierDot,\n              }}\n            />\n          ))}\n        </span>\n      ) : null}\n    </span>\n  </>\n);\n\nconst CalendarHeader = ({\n  canGoNext,\n  canGoPrev,\n  currentMonth,\n  dimensions,\n  headingId,\n  labels,\n  locale,\n  monthPickerId,\n  monthTriggerRef,\n  onNext,\n  onOpenPicker,\n  onPrev,\n  palette,\n  picker,\n  yearPickerId,\n  yearTriggerRef,\n}: {\n  canGoNext: boolean;\n  canGoPrev: boolean;\n  currentMonth: Date;\n  dimensions: CalendarDimensions;\n  headingId: string;\n  labels: CalendarLabels;\n  locale?: Locale;\n  monthPickerId: string;\n  monthTriggerRef: RefObject<HTMLButtonElement | null>;\n  onNext: () => void;\n  onOpenPicker: (which: \"month\" | \"year\") => void;\n  onPrev: () => void;\n  palette: CalendarPalette;\n  picker: \"none\" | \"month\" | \"year\";\n  yearPickerId: string;\n  yearTriggerRef: RefObject<HTMLButtonElement | null>;\n}) => (\n  <div\n    style={{\n      position: \"relative\",\n      minHeight: dimensions.navButtonSize,\n      marginBottom: dimensions.headerGap,\n    }}\n  >\n    <div\n      style={{\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        minHeight: dimensions.navButtonSize,\n        minWidth: 0,\n        paddingLeft: dimensions.navButtonSize,\n        paddingRight: dimensions.navButtonSize,\n        textAlign: \"center\",\n        gap: 6,\n        flexWrap: \"wrap\",\n      }}\n    >\n      <div\n        style={{\n          display: \"inline-flex\",\n          alignItems: \"center\",\n          gap: 2,\n          width: \"fit-content\",\n        }}\n      >\n        <HeaderPickerButton\n          ariaControls={monthPickerId}\n          ariaExpanded={picker === \"month\"}\n          ariaLabel={labels.chooseMonth}\n          color={palette.titleColor}\n          onClick={() => onOpenPicker(\"month\")}\n          ref={monthTriggerRef}\n          showIndicator\n          size={dimensions.monthFontSize}\n        >\n          <span id={headingId}>{format(currentMonth, \"MMM\", { locale })}</span>\n        </HeaderPickerButton>\n        <HeaderPickerButton\n          ariaControls={yearPickerId}\n          ariaExpanded={picker === \"year\"}\n          ariaLabel={labels.chooseYear}\n          color={palette.textMuted}\n          onClick={() => onOpenPicker(\"year\")}\n          ref={yearTriggerRef}\n          showIndicator\n          size={dimensions.monthFontSize}\n        >\n          {format(currentMonth, \"yyyy\", { locale })}\n        </HeaderPickerButton>\n      </div>\n    </div>\n    <div\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        gap: dimensions.navGap,\n        alignItems: \"center\",\n        justifyContent: \"space-between\",\n        pointerEvents: \"none\",\n      }}\n    >\n      <NavButton\n        aria-label={labels.previousMonth}\n        dimensions={dimensions}\n        disabled={!canGoPrev}\n        onClick={onPrev}\n        palette={palette}\n        style={{ pointerEvents: \"auto\" }}\n      >\n        <ChevronLeft\n          style={{\n            height: dimensions.navIconSize,\n            width: dimensions.navIconSize,\n          }}\n        />\n      </NavButton>\n      <NavButton\n        aria-label={labels.nextMonth}\n        dimensions={dimensions}\n        disabled={!canGoNext}\n        onClick={onNext}\n        palette={palette}\n        style={{ pointerEvents: \"auto\" }}\n      >\n        <ChevronRight\n          style={{\n            height: dimensions.navIconSize,\n            width: dimensions.navIconSize,\n          }}\n        />\n      </NavButton>\n    </div>\n  </div>\n);\n\nconst CalendarRoot = forwardRef<HTMLDivElement, CalendarProps>(\n  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: calendar shell coordinates selection, navigation, overlays, and motion in one place.\n  function Calendar(\n    {\n      selected,\n      defaultSelected,\n      onSelect,\n      range,\n      defaultRange,\n      onRangeSelect,\n      mode = \"single\",\n      month,\n      defaultMonth,\n      onMonthChange,\n      disabled,\n      locale,\n      labels: labelsProp,\n      size = \"sm\",\n      weekStartsOn,\n      minYear,\n      maxYear,\n      minDate,\n      maxDate,\n      showOutsideDays = true,\n      fixedWeeks = false,\n      modifiers,\n      modifierLabels,\n      className,\n      id,\n      name,\n    },\n    ref\n  ) {\n    const labels = useMemo(\n      () => ({ ...DEFAULT_CALENDAR_LABELS, ...labelsProp }),\n      [labelsProp]\n    );\n    const reduceMotion = useReducedMotion();\n    const calendarMotionId = useId();\n    const rootId = id ?? calendarMotionId;\n    const headingId = `${rootId}-heading`;\n    const selectedInfoId = `${rootId}-selected`;\n    const monthPickerId = `${rootId}-month-picker`;\n    const yearPickerId = `${rootId}-year-picker`;\n\n    const initialMonth = startOfMonth(\n      month ?? defaultMonth ?? selected ?? defaultSelected ?? new Date()\n    );\n\n    const isDateDisabled = useMemo(\n      () => createIsDateDisabled({ disabled, minDate, maxDate }),\n      [disabled, minDate, maxDate]\n    );\n\n    const [internalMonth, setInternalMonth] = useState<Date>(\n      () => initialMonth\n    );\n    const [internalSelected, setInternalSelected] = useState<Date | null>(\n      () => defaultSelected ?? null\n    );\n    const [internalRange, setInternalRange] = useState<CalendarRange>(\n      () => defaultRange ?? {}\n    );\n    const [focusedDate, setFocusedDate] = useState<Date>(() =>\n      resolveFocusableDate(\n        initialMonth,\n        selected ?? defaultSelected ?? null,\n        isDateDisabled\n      )\n    );\n    const [shouldRestoreFocus, setShouldRestoreFocus] = useState(false);\n    const [picker, setPicker] = useState<\"none\" | \"month\" | \"year\">(\"none\");\n    const [yearPageStart, setYearPageStart] = useState<number>(\n      () =>\n        Math.floor(initialMonth.getFullYear() / YEAR_GRID_SIZE) * YEAR_GRID_SIZE\n    );\n    const [monthMotionDirection, setMonthMotionDirection] = useState(0);\n    const [pickerFocusIndex, setPickerFocusIndex] = useState(0);\n\n    const dayButtonRefs = useRef(new Map<string, HTMLButtonElement>());\n    const pickerRef = useRef<HTMLDivElement | null>(null);\n    const monthTriggerRef = useRef<HTMLButtonElement | null>(null);\n    const yearTriggerRef = useRef<HTMLButtonElement | null>(null);\n    const currentMonth = startOfMonth(month ?? internalMonth);\n    const selectedDate =\n      mode === \"single\"\n        ? selected === undefined\n          ? internalSelected\n          : selected\n        : null;\n    const selectedRange =\n      mode === \"range\" ? (range === undefined ? internalRange : range) : {};\n    const rangeBounds = mode === \"range\" ? getRangeBounds(selectedRange) : null;\n    const calendarOptions = useMemo(\n      () => getCalendarOptions(locale, weekStartsOn),\n      [locale, weekStartsOn]\n    );\n    const dimensions = CALENDAR_DIMENSIONS[size];\n    const palette = CALENDAR_PALETTE;\n\n    const prevMonth = subMonths(currentMonth, 1);\n    const nextMonth = addMonths(currentMonth, 1);\n    const canGoPrev = canNavigateToMonth(prevMonth, minDate, maxDate);\n    const canGoNext = canNavigateToMonth(nextMonth, minDate, maxDate);\n\n    useEffect(() => {\n      const next = getSyncedFocusedDate({\n        currentMonth,\n        focusedDate,\n        isDateDisabled,\n        mode,\n        rangeBounds,\n        selectedDate,\n      });\n      if (!isSameDay(next, focusedDate)) setFocusedDate(next);\n    }, [\n      currentMonth,\n      focusedDate,\n      isDateDisabled,\n      mode,\n      rangeBounds,\n      selectedDate,\n    ]);\n\n    const controlledSelectionMonthTime =\n      month === undefined &&\n      mode === \"single\" &&\n      selected !== undefined &&\n      selectedDate\n        ? startOfMonth(selectedDate).getTime()\n        : null;\n    const controlledRangeMonthTime =\n      month === undefined &&\n      mode === \"range\" &&\n      range !== undefined &&\n      rangeBounds\n        ? startOfMonth(rangeBounds.end).getTime()\n        : null;\n\n    useEffect(() => {\n      const targetTime =\n        controlledSelectionMonthTime ?? controlledRangeMonthTime;\n      if (targetTime === null) return;\n\n      const nextVisibleMonth = startOfMonth(new Date(targetTime));\n\n      setInternalMonth((prev) => {\n        if (isSameMonth(nextVisibleMonth, prev)) return prev;\n        const monthOffset =\n          (nextVisibleMonth.getFullYear() - prev.getFullYear()) * 12 +\n          nextVisibleMonth.getMonth() -\n          prev.getMonth();\n        setMonthMotionDirection(Math.sign(monthOffset));\n        onMonthChange?.(nextVisibleMonth);\n        return nextVisibleMonth;\n      });\n    }, [controlledRangeMonthTime, controlledSelectionMonthTime, onMonthChange]);\n\n    useEffect(() => {\n      if (!shouldRestoreFocus || typeof window === \"undefined\") return;\n      let frameId = 0;\n      const focusKey = getDateKey(focusedDate);\n      const focusTarget = () => {\n        const next = dayButtonRefs.current.get(focusKey);\n        if (next) {\n          next.focus();\n          setShouldRestoreFocus(false);\n          return;\n        }\n        frameId = window.requestAnimationFrame(focusTarget);\n      };\n      frameId = window.requestAnimationFrame(focusTarget);\n      return () => window.cancelAnimationFrame(frameId);\n    }, [focusedDate, shouldRestoreFocus]);\n\n    const closePicker = useCallback(() => {\n      setPicker((current) => {\n        if (current === \"month\") {\n          monthTriggerRef.current?.focus();\n        } else if (current === \"year\") {\n          yearTriggerRef.current?.focus();\n        }\n        return \"none\";\n      });\n    }, []);\n\n    useEffect(() => {\n      if (picker === \"none\") return;\n\n      const pickerEl = pickerRef.current;\n      if (!pickerEl) return;\n\n      const focusTarget = pickerEl.querySelector<HTMLButtonElement>(\n        `[data-calendar-picker-index=\"${pickerFocusIndex}\"]`\n      );\n      focusTarget?.focus();\n\n      const onDown = (event: MouseEvent) => {\n        const target = event.target as Node;\n        if (pickerEl.contains(target)) return;\n        if (monthTriggerRef.current?.contains(target)) return;\n        if (yearTriggerRef.current?.contains(target)) return;\n        closePicker();\n      };\n\n      const onKey = (event: globalThis.KeyboardEvent) => {\n        if (event.key === \"Escape\") {\n          event.preventDefault();\n          closePicker();\n          return;\n        }\n        trapPickerTabKey(event, pickerEl);\n      };\n\n      document.addEventListener(\"mousedown\", onDown);\n      document.addEventListener(\"keydown\", onKey);\n      return () => {\n        document.removeEventListener(\"mousedown\", onDown);\n        document.removeEventListener(\"keydown\", onKey);\n      };\n    }, [closePicker, picker, pickerFocusIndex]);\n\n    const setMonthValue = (nextMonth: Date) => {\n      const normalized = startOfMonth(nextMonth);\n      if (!canNavigateToMonth(normalized, minDate, maxDate)) return;\n      const monthOffset =\n        (normalized.getFullYear() - currentMonth.getFullYear()) * 12 +\n        normalized.getMonth() -\n        currentMonth.getMonth();\n      setMonthMotionDirection(Math.sign(monthOffset));\n      if (month === undefined) setInternalMonth(normalized);\n      onMonthChange?.(normalized);\n    };\n\n    const setSelectedValue = (nextDate: Date | null) => {\n      if (mode !== \"single\") return;\n      if (selected === undefined) setInternalSelected(nextDate);\n      onSelect?.(nextDate);\n    };\n\n    const setRangeValue = (nextRange: CalendarRange) => {\n      if (mode !== \"range\") return;\n      const normalized = normalizeRange(nextRange);\n      if (range === undefined) setInternalRange(normalized);\n      onRangeSelect?.(normalized);\n    };\n\n    const handleDaySelect = (day: Date) => {\n      if (isDateDisabled(day)) return;\n\n      if (mode === \"range\") {\n        setRangeValue(applyRangeDaySelection(day, selectedRange));\n        return;\n      }\n\n      if (!isSameMonth(day, currentMonth)) {\n        setMonthValue(startOfMonth(day));\n      }\n      setSelectedValue(day);\n    };\n\n    const shouldFixWeeks = fixedWeeks && showOutsideDays;\n\n    const days = useMemo(() => {\n      const start = startOfWeek(startOfMonth(currentMonth), calendarOptions);\n      const end = endOfWeek(endOfMonth(currentMonth), calendarOptions);\n      const intervalDays = eachDayOfInterval({ start, end });\n      if (!shouldFixWeeks) return intervalDays;\n      const targetLength = FIXED_WEEK_COUNT * WEEK_LENGTH;\n      if (intervalDays.length >= targetLength) return intervalDays;\n      const padded = [...intervalDays];\n      while (padded.length < targetLength) {\n        padded.push(addDays(padded.at(-1) ?? end, 1));\n      }\n      return padded;\n    }, [calendarOptions, currentMonth, shouldFixWeeks]);\n\n    const weeks = useMemo(() => {\n      const next: Date[][] = [];\n      for (let i = 0; i < days.length; i += WEEK_LENGTH) {\n        next.push(days.slice(i, i + WEEK_LENGTH));\n      }\n      return next;\n    }, [days]);\n\n    const weekdayHeaders = useMemo(() => {\n      const start = startOfWeek(new Date(), calendarOptions);\n      return Array.from({ length: WEEK_LENGTH }, (_, index) => {\n        const day = addDays(start, index);\n        return {\n          key: getDateKey(day),\n          shortLabel: format(day, \"EEEEEE\", { locale }),\n          fullLabel: format(day, \"EEEE\", { locale }),\n        };\n      });\n    }, [calendarOptions, locale]);\n\n    const monthLabels = useMemo(() => {\n      const ref = new Date(2000, 0, 1);\n      return Array.from({ length: 12 }, (_, i) => ({\n        index: i,\n        short: format(setMonth(ref, i), \"MMM\", { locale }),\n        full: format(setMonth(ref, i), \"MMMM\", { locale }),\n        disabled: isMonthIndexDisabled(currentMonth, i, minDate, maxDate),\n      }));\n    }, [currentMonth, locale, minDate, maxDate]);\n\n    const moveFocusToDate = (preferredDate: Date, step: 1 | -1) => {\n      const next = findInteractiveDate(preferredDate, step, isDateDisabled);\n      if (!isSameMonth(next, currentMonth)) {\n        setMonthValue(next);\n      }\n      setFocusedDate(next);\n      setShouldRestoreFocus(true);\n    };\n\n    const handlePrev = () => {\n      if (!canGoPrev) return;\n      setMonthValue(prevMonth);\n    };\n\n    const handleNext = () => {\n      if (!canGoNext) return;\n      setMonthValue(nextMonth);\n    };\n\n    const handleDayKeyDown = (\n      event: KeyboardEvent<HTMLButtonElement>,\n      day: Date\n    ) => {\n      switch (event.key) {\n        case \"ArrowLeft\":\n          event.preventDefault();\n          moveFocusToDate(addDays(day, -1), -1);\n          break;\n        case \"ArrowRight\":\n          event.preventDefault();\n          moveFocusToDate(addDays(day, 1), 1);\n          break;\n        case \"ArrowUp\":\n          event.preventDefault();\n          moveFocusToDate(addDays(day, -WEEK_LENGTH), -1);\n          break;\n        case \"ArrowDown\":\n          event.preventDefault();\n          moveFocusToDate(addDays(day, WEEK_LENGTH), 1);\n          break;\n        case \"Home\":\n          event.preventDefault();\n          moveFocusToDate(startOfWeek(day, calendarOptions), -1);\n          break;\n        case \"End\":\n          event.preventDefault();\n          moveFocusToDate(endOfWeek(day, calendarOptions), 1);\n          break;\n        case \"PageUp\":\n          event.preventDefault();\n          moveFocusToDate(subMonths(day, 1), -1);\n          break;\n        case \"PageDown\":\n          event.preventDefault();\n          moveFocusToDate(addMonths(day, 1), 1);\n          break;\n        case \"Enter\":\n        case \" \":\n          event.preventDefault();\n          handleDaySelect(day);\n          break;\n        default:\n          break;\n      }\n    };\n\n    const monthKey = format(currentMonth, \"yyyy-MM\");\n    const currentYear = currentMonth.getFullYear();\n    const currentMonthIndex = currentMonth.getMonth();\n\n    const openPicker = (which: \"month\" | \"year\") => {\n      setPicker((prev) => {\n        const next = prev === which ? \"none\" : which;\n        if (next === \"none\") {\n          if (which === \"month\") monthTriggerRef.current?.focus();\n          else yearTriggerRef.current?.focus();\n        } else if (next === \"year\") {\n          setYearPageStart(\n            Math.floor(currentYear / YEAR_GRID_SIZE) * YEAR_GRID_SIZE\n          );\n          setPickerFocusIndex(0);\n        } else {\n          setPickerFocusIndex(currentMonthIndex);\n        }\n        return next;\n      });\n    };\n\n    const selectMonth = (idx: number) => {\n      if (isMonthIndexDisabled(currentMonth, idx, minDate, maxDate)) return;\n      const next = setMonth(currentMonth, idx);\n      setMonthValue(next);\n      closePicker();\n    };\n\n    const selectYear = (year: number) => {\n      if (minYear !== undefined && year < minYear) return;\n      if (maxYear !== undefined && year > maxYear) return;\n      const next = setYear(currentMonth, year);\n      setMonthValue(next);\n      closePicker();\n    };\n\n    const handlePickerKeyDown = (\n      event: KeyboardEvent<HTMLButtonElement>,\n      index: number,\n      itemCount: number,\n      columns: number,\n      onSelectAtIndex: (index: number) => void,\n      isDisabledAtIndex: (index: number) => boolean\n    ) => {\n      if (\n        event.key === \"ArrowLeft\" ||\n        event.key === \"ArrowRight\" ||\n        event.key === \"ArrowUp\" ||\n        event.key === \"ArrowDown\" ||\n        event.key === \"Home\" ||\n        event.key === \"End\"\n      ) {\n        event.preventDefault();\n        let nextIndex = moveGridIndex(index, event.key, columns, itemCount);\n        for (let attempt = 0; attempt < itemCount; attempt += 1) {\n          if (!isDisabledAtIndex(nextIndex)) {\n            setPickerFocusIndex(nextIndex);\n            return;\n          }\n          nextIndex = moveGridIndex(nextIndex, event.key, columns, itemCount);\n        }\n        return;\n      }\n\n      if (event.key === \"Enter\" || event.key === \" \") {\n        event.preventDefault();\n        if (!isDisabledAtIndex(index)) onSelectAtIndex(index);\n      }\n    };\n\n    const selectionSummary = useMemo(() => {\n      if (mode === \"range\") {\n        const normalized = normalizeRange(selectedRange);\n        if (!normalized.from) return labels.noDateSelected;\n        if (!normalized.to || isSameDay(normalized.from, normalized.to)) {\n          return format(normalized.from, \"PPPP\", { locale });\n        }\n        return `${format(normalized.from, \"PPP\", { locale })} – ${format(normalized.to, \"PPP\", { locale })}`;\n      }\n      return selectedDate\n        ? format(selectedDate, \"PPPP\", { locale })\n        : labels.noDateSelected;\n    }, [labels.noDateSelected, locale, mode, selectedDate, selectedRange]);\n\n    const entranceTransition = reduceMotion\n      ? { duration: 0 }\n      : { duration: 0.6, ease: SPRING_EASE };\n\n    const monthTransition = reduceMotion\n      ? { duration: 0 }\n      : { duration: 0.22, ease: SMOOTH_EASE };\n\n    return (\n      <motion.div\n        animate={reduceMotion ? undefined : { opacity: 1, y: 0, scale: 1 }}\n        aria-describedby={selectedInfoId}\n        aria-labelledby={headingId}\n        className={cn(\n          componentThemeClassName,\n          controlCornerClassName,\n          className\n        )}\n        data-slot=\"calendar\"\n        id={rootId}\n        initial={reduceMotion ? false : { opacity: 0, y: 30, scale: 0.95 }}\n        ref={ref}\n        role=\"application\"\n        style={{\n          width: \"100%\",\n          maxWidth: dimensions.maxWidth,\n          borderRadius: dimensions.cardRadius,\n          padding: dimensions.cardPadding,\n          background: palette.cardBackground,\n          border: palette.cardBorder,\n          boxShadow: palette.cardShadow,\n          fontFamily: \"inherit\",\n          color: palette.textPrimary,\n          boxSizing: \"border-box\",\n          position: \"relative\",\n        }}\n        transition={entranceTransition}\n      >\n        {name && mode === \"single\" ? (\n          <input\n            name={name}\n            type=\"hidden\"\n            value={selectedDate ? format(selectedDate, \"yyyy-MM-dd\") : \"\"}\n          />\n        ) : null}\n\n        <CalendarHeader\n          canGoNext={canGoNext}\n          canGoPrev={canGoPrev}\n          currentMonth={currentMonth}\n          dimensions={dimensions}\n          headingId={headingId}\n          labels={labels}\n          locale={locale}\n          monthPickerId={monthPickerId}\n          monthTriggerRef={monthTriggerRef}\n          onNext={handleNext}\n          onOpenPicker={openPicker}\n          onPrev={handlePrev}\n          palette={palette}\n          picker={picker}\n          yearPickerId={yearPickerId}\n          yearTriggerRef={yearTriggerRef}\n        />\n\n        <div\n          style={{\n            position: \"relative\",\n            overflow: \"hidden\",\n            marginTop: dimensions.monthTopMargin,\n          }}\n        >\n          <AnimatePresence\n            custom={monthMotionDirection}\n            initial={false}\n            mode=\"popLayout\"\n          >\n            <motion.div\n              animate=\"center\"\n              custom={monthMotionDirection}\n              exit=\"exit\"\n              initial=\"enter\"\n              key={monthKey}\n              style={{ position: \"relative\" }}\n              transition={monthTransition}\n              variants={reduceMotion ? undefined : MONTH_GRID_VARIANTS}\n            >\n              <table\n                aria-labelledby={headingId}\n                style={{\n                  width: \"100%\",\n                  tableLayout: \"fixed\",\n                  borderCollapse: \"separate\",\n                  borderSpacing: 0,\n                }}\n              >\n                <thead>\n                  <tr>\n                    {weekdayHeaders.map((day) => (\n                      <th\n                        aria-label={day.fullLabel}\n                        key={day.key}\n                        scope=\"col\"\n                        style={{\n                          textAlign: \"center\",\n                          fontSize: dimensions.tableHeaderFontSize,\n                          fontWeight: 400,\n                          color: palette.textMuted,\n                          textTransform: \"none\",\n                          letterSpacing: 0,\n                          lineHeight: 1.5,\n                          padding: `0 ${dimensions.tableCellPadding}px ${dimensions.tableHeaderPaddingBottom}px`,\n                        }}\n                      >\n                        {day.shortLabel}\n                      </th>\n                    ))}\n                  </tr>\n                </thead>\n                <tbody>\n                  {weeks.map((week, weekIndex) => (\n                    <tr key={`${monthKey}-week-${weekIndex}`}>\n                      {week.map((day, dayIndex) => {\n                        const inMonth = isSameMonth(day, currentMonth);\n                        if (!(showOutsideDays || inMonth)) {\n                          return (\n                            <td\n                              aria-hidden\n                              key={getDateKey(day)}\n                              style={{\n                                padding: `${dimensions.weekRowGap}px ${dimensions.tableCellPadding}px 0`,\n                              }}\n                            />\n                          );\n                        }\n\n                        return (\n                          <td\n                            key={getDateKey(day)}\n                            style={{\n                              padding: `${dimensions.weekRowGap}px ${dimensions.tableCellPadding}px 0`,\n                              verticalAlign: \"middle\",\n                            }}\n                          >\n                            <DayCell\n                              calendarMotionId={calendarMotionId}\n                              currentMonth={currentMonth}\n                              day={day}\n                              dimensions={dimensions}\n                              index={weekIndex * WEEK_LENGTH + dayIndex}\n                              isDateDisabled={isDateDisabled}\n                              isFocused={isSameDay(day, focusedDate)}\n                              labels={labels}\n                              locale={locale}\n                              mode={mode}\n                              modifierLabels={modifierLabels}\n                              modifiers={modifiers}\n                              onDayFocus={setFocusedDate}\n                              onDayKeyDown={handleDayKeyDown}\n                              onSelectDay={handleDaySelect}\n                              palette={palette}\n                              rangeBounds={rangeBounds}\n                              reduceMotion={reduceMotion}\n                              registerDayButton={(\n                                buttonDay,\n                                node,\n                                interactive\n                              ) => {\n                                const key = getDateKey(buttonDay);\n                                if (!(interactive && node)) {\n                                  dayButtonRefs.current.delete(key);\n                                  return;\n                                }\n                                dayButtonRefs.current.set(key, node);\n                              }}\n                              selectedDate={selectedDate}\n                            />\n                          </td>\n                        );\n                      })}\n                    </tr>\n                  ))}\n                </tbody>\n              </table>\n            </motion.div>\n          </AnimatePresence>\n\n          <AnimatePresence>\n            {picker !== \"none\" ? (\n              <motion.div\n                animate={\n                  reduceMotion ? undefined : { opacity: 1, y: 0, scale: 1 }\n                }\n                className={controlCornerClassName}\n                exit={\n                  reduceMotion ? undefined : { opacity: 0, y: -6, scale: 0.98 }\n                }\n                initial={\n                  reduceMotion ? false : { opacity: 0, y: -6, scale: 0.98 }\n                }\n                ref={pickerRef}\n                style={{\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  boxSizing: \"border-box\",\n                  background: palette.popoverBackground,\n                  border: palette.popoverBorder,\n                  borderRadius: dimensions.cardRadius - 4,\n                  boxShadow: palette.popoverShadow,\n                  padding: dimensions.cardPadding - 2,\n                  zIndex: 20,\n                  display: \"flex\",\n                  flexDirection: \"column\",\n                }}\n                transition={monthTransition}\n              >\n                {picker === \"month\" ? (\n                  <MonthPicker\n                    currentMonthIndex={currentMonthIndex}\n                    dimensions={dimensions}\n                    id={monthPickerId}\n                    labels={labels}\n                    monthLabels={monthLabels}\n                    onKeyDown={(event, index) =>\n                      handlePickerKeyDown(\n                        event,\n                        index,\n                        monthLabels.length,\n                        MONTH_GRID_COLS,\n                        (targetIndex) => selectMonth(targetIndex),\n                        (targetIndex) =>\n                          monthLabels[targetIndex]?.disabled ?? false\n                      )\n                    }\n                    onSelect={selectMonth}\n                    palette={palette}\n                    pickerFocusIndex={pickerFocusIndex}\n                  />\n                ) : (\n                  <YearPicker\n                    currentYear={currentYear}\n                    dimensions={dimensions}\n                    id={yearPickerId}\n                    labels={labels}\n                    maxYear={maxYear}\n                    minYear={minYear}\n                    onKeyDown={(event, index, years) =>\n                      handlePickerKeyDown(\n                        event,\n                        index,\n                        years.length,\n                        MONTH_GRID_COLS,\n                        (targetIndex) => selectYear(years[targetIndex]),\n                        (targetIndex) =>\n                          isYearOutOfRange(years[targetIndex], minYear, maxYear)\n                      )\n                    }\n                    onPageChange={setYearPageStart}\n                    onSelect={selectYear}\n                    pageStart={yearPageStart}\n                    palette={palette}\n                    pickerFocusIndex={pickerFocusIndex}\n                  />\n                )}\n              </motion.div>\n            ) : null}\n          </AnimatePresence>\n        </div>\n\n        <div\n          aria-live=\"polite\"\n          id={selectedInfoId}\n          style={{\n            border: 0,\n            clip: \"rect(0 0 0 0)\",\n            height: 1,\n            margin: -1,\n            overflow: \"hidden\",\n            padding: 0,\n            position: \"absolute\",\n            whiteSpace: \"nowrap\",\n            width: 1,\n          }}\n        >\n          {selectionSummary}\n        </div>\n      </motion.div>\n    );\n  }\n);\n\nCalendarRoot.displayName = \"Calendar\";\n\nexport const Calendar = CalendarRoot;\n\nconst HeaderPickerButton = forwardRef<\n  HTMLButtonElement,\n  {\n    children: ReactNode;\n    onClick: () => void;\n    ariaLabel: string;\n    ariaExpanded: boolean;\n    ariaControls: string;\n    color: string;\n    size: number;\n    showIndicator?: boolean;\n  }\n>(function HeaderPickerButton(\n  {\n    children,\n    onClick,\n    ariaLabel,\n    ariaExpanded,\n    ariaControls,\n    color,\n    size,\n    showIndicator = false,\n  },\n  ref\n) {\n  return (\n    <button\n      aria-controls={ariaExpanded ? ariaControls : undefined}\n      aria-expanded={ariaExpanded}\n      aria-haspopup=\"dialog\"\n      aria-label={ariaLabel}\n      className={cn(controlCornerClassName, focusVisibleClassName)}\n      onClick={onClick}\n      ref={ref}\n      style={{\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        gap: showIndicator ? 2 : 0,\n        fontSize: size,\n        fontWeight: 500,\n        color,\n        letterSpacing: 0,\n        lineHeight: 1.1,\n        border: \"none\",\n        background: \"transparent\",\n        cursor: \"pointer\",\n        padding: \"2px 3px\",\n        borderRadius: 6,\n        fontFamily: \"inherit\",\n        fontVariantNumeric: \"tabular-nums\",\n        WebkitTapHighlightColor: \"transparent\",\n      }}\n      type=\"button\"\n    >\n      {children}\n      {showIndicator ? (\n        <span\n          aria-hidden\n          style={{\n            display: \"inline-flex\",\n            opacity: 0.55,\n            transform: ariaExpanded ? \"rotate(180deg)\" : undefined,\n            transition: \"transform 0.16s ease\",\n          }}\n        >\n          <ChevronDown style={{ height: 14, width: 14 }} />\n        </span>\n      ) : null}\n    </button>\n  );\n});\n\nconst MonthPicker = ({\n  id,\n  currentMonthIndex,\n  monthLabels,\n  onSelect,\n  onKeyDown,\n  palette,\n  dimensions,\n  labels,\n  pickerFocusIndex,\n}: {\n  id: string;\n  currentMonthIndex: number;\n  monthLabels: {\n    index: number;\n    short: string;\n    full: string;\n    disabled: boolean;\n  }[];\n  onSelect: (idx: number) => void;\n  onKeyDown: (event: KeyboardEvent<HTMLButtonElement>, index: number) => void;\n  palette: CalendarPalette;\n  dimensions: CalendarDimensions;\n  labels: CalendarLabels;\n  pickerFocusIndex: number;\n}) => (\n  <div\n    aria-label={labels.selectMonth}\n    id={id}\n    role=\"dialog\"\n    style={{\n      display: \"grid\",\n      gridTemplateColumns: \"repeat(3, 1fr)\",\n      gap: 4,\n      flex: 1,\n      alignContent: \"space-evenly\",\n    }}\n  >\n    {monthLabels.map((m, index) => {\n      const active = m.index === currentMonthIndex;\n      return (\n        <button\n          aria-current={active ? \"date\" : undefined}\n          aria-disabled={m.disabled || undefined}\n          aria-label={m.full}\n          className={cn(controlCornerClassName, focusVisibleClassName)}\n          data-calendar-picker-index={index}\n          disabled={m.disabled}\n          key={m.index}\n          onClick={() => onSelect(m.index)}\n          onKeyDown={(event) => onKeyDown(event, index)}\n          style={{\n            minHeight: dimensions.dayCellMinHeight,\n            padding: \"0 6px\",\n            borderRadius: dimensions.dayCellRadius,\n            border: \"none\",\n            background: active ? palette.selectedGradient : \"transparent\",\n            color: active ? palette.selectedForeground : palette.textPrimary,\n            fontWeight: 500,\n            fontSize: dimensions.dayCellFontSize,\n            cursor: m.disabled ? \"default\" : \"pointer\",\n            fontFamily: \"inherit\",\n            opacity: m.disabled ? 0.45 : 1,\n          }}\n          tabIndex={index === pickerFocusIndex ? 0 : -1}\n          type=\"button\"\n        >\n          {m.short}\n        </button>\n      );\n    })}\n  </div>\n);\n\nconst isYearOutOfRange = (year: number, minYear?: number, maxYear?: number) =>\n  (minYear !== undefined && year < minYear) ||\n  (maxYear !== undefined && year > maxYear);\n\nconst YearPicker = ({\n  id,\n  currentYear,\n  pageStart,\n  onPageChange,\n  onSelect,\n  onKeyDown,\n  palette,\n  dimensions,\n  minYear,\n  maxYear,\n  labels,\n  pickerFocusIndex,\n}: {\n  id: string;\n  currentYear: number;\n  pageStart: number;\n  onPageChange: (n: number) => void;\n  onSelect: (year: number) => void;\n  onKeyDown: (\n    event: KeyboardEvent<HTMLButtonElement>,\n    index: number,\n    years: number[]\n  ) => void;\n  palette: CalendarPalette;\n  dimensions: CalendarDimensions;\n  minYear?: number;\n  maxYear?: number;\n  labels: CalendarLabels;\n  pickerFocusIndex: number;\n}) => {\n  const pageEnd = pageStart + YEAR_GRID_SIZE - 1;\n  const years = Array.from(\n    { length: YEAR_GRID_SIZE },\n    (_, index) => pageStart + index\n  );\n  const canPrev = minYear === undefined || pageStart > minYear;\n  const canNext = maxYear === undefined || pageEnd < maxYear;\n\n  return (\n    <div\n      aria-label={labels.selectYear}\n      id={id}\n      role=\"dialog\"\n      style={{ display: \"flex\", flexDirection: \"column\", gap: 4, flex: 1 }}\n    >\n      <div\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"space-between\",\n          flexShrink: 0,\n        }}\n      >\n        <NavButton\n          aria-label={labels.previousYears}\n          dimensions={dimensions}\n          disabled={!canPrev}\n          onClick={() => onPageChange(pageStart - YEAR_GRID_SIZE)}\n          palette={palette}\n        >\n          <ChevronLeft\n            style={{\n              height: dimensions.navIconSize,\n              width: dimensions.navIconSize,\n            }}\n          />\n        </NavButton>\n        <span\n          style={{\n            fontSize: dimensions.tableHeaderFontSize,\n            fontWeight: 500,\n            color: palette.textMuted,\n            letterSpacing: 0,\n          }}\n        >\n          {pageStart} – {pageEnd}\n        </span>\n        <NavButton\n          aria-label={labels.nextYears}\n          dimensions={dimensions}\n          disabled={!canNext}\n          onClick={() => onPageChange(pageStart + YEAR_GRID_SIZE)}\n          palette={palette}\n        >\n          <ChevronRight\n            style={{\n              height: dimensions.navIconSize,\n              width: dimensions.navIconSize,\n            }}\n          />\n        </NavButton>\n      </div>\n      <div\n        style={{\n          display: \"grid\",\n          gridTemplateColumns: \"repeat(3, 1fr)\",\n          gap: 4,\n          flex: 1,\n          alignContent: \"space-evenly\",\n        }}\n      >\n        {years.map((year, index) => (\n          <YearPickerCell\n            currentYear={currentYear}\n            dimensions={dimensions}\n            index={index}\n            key={year}\n            maxYear={maxYear}\n            minYear={minYear}\n            onKeyDown={(event) => onKeyDown(event, index, years)}\n            onSelect={onSelect}\n            palette={palette}\n            pickerFocusIndex={pickerFocusIndex}\n            year={year}\n          />\n        ))}\n      </div>\n    </div>\n  );\n};\n\nconst YearPickerCell = ({\n  year,\n  currentYear,\n  index,\n  onSelect,\n  onKeyDown,\n  palette,\n  dimensions,\n  minYear,\n  maxYear,\n  pickerFocusIndex,\n}: {\n  year: number;\n  currentYear: number;\n  index: number;\n  onSelect: (year: number) => void;\n  onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;\n  palette: CalendarPalette;\n  dimensions: CalendarDimensions;\n  minYear?: number;\n  maxYear?: number;\n  pickerFocusIndex: number;\n}) => {\n  const active = year === currentYear;\n  const outOfRange = isYearOutOfRange(year, minYear, maxYear);\n\n  return (\n    <button\n      aria-current={active ? \"date\" : undefined}\n      aria-disabled={outOfRange || undefined}\n      aria-label={String(year)}\n      className={cn(controlCornerClassName, focusVisibleClassName)}\n      data-calendar-picker-index={index}\n      disabled={outOfRange}\n      onClick={() => onSelect(year)}\n      onKeyDown={onKeyDown}\n      style={{\n        minHeight: dimensions.dayCellMinHeight,\n        padding: \"0 6px\",\n        borderRadius: dimensions.dayCellRadius,\n        border: \"none\",\n        background: active ? palette.selectedGradient : \"transparent\",\n        color: active\n          ? palette.selectedForeground\n          : outOfRange\n            ? palette.textDim\n            : palette.textPrimary,\n        fontWeight: 500,\n        fontSize: dimensions.dayCellFontSize,\n        lineHeight: 1.2,\n        cursor: outOfRange ? \"default\" : \"pointer\",\n        fontFamily: \"inherit\",\n        opacity: outOfRange ? 0.45 : 1,\n      }}\n      tabIndex={index === pickerFocusIndex ? 0 : -1}\n      type=\"button\"\n    >\n      {year}\n    </button>\n  );\n};\n\ntype DayCellProps = {\n  calendarMotionId: string;\n  day: Date;\n  dimensions: CalendarDimensions;\n  index: number;\n  currentMonth: Date;\n  isDateDisabled: (date: Date) => boolean;\n  isFocused: boolean;\n  labels: CalendarLabels;\n  locale?: Locale;\n  mode: CalendarMode;\n  modifiers?: Record<string, (date: Date) => boolean>;\n  modifierLabels?: Record<string, string>;\n  onDayFocus: (day: Date) => void;\n  onDayKeyDown: (event: KeyboardEvent<HTMLButtonElement>, day: Date) => void;\n  onSelectDay: (day: Date) => void;\n  palette: CalendarPalette;\n  rangeBounds: ReturnType<typeof getRangeBounds>;\n  reduceMotion: boolean | null;\n  registerDayButton: (\n    day: Date,\n    node: HTMLButtonElement | null,\n    interactive: boolean\n  ) => void;\n  selectedDate: Date | null;\n};\n\nconst DayCell = ({\n  calendarMotionId,\n  day,\n  dimensions,\n  index,\n  currentMonth,\n  isDateDisabled,\n  isFocused,\n  labels,\n  locale,\n  mode,\n  modifiers,\n  modifierLabels,\n  onDayFocus,\n  onDayKeyDown,\n  onSelectDay,\n  palette,\n  rangeBounds,\n  reduceMotion,\n  registerDayButton,\n  selectedDate,\n}: DayCellProps) => {\n  const status = getDayCellStatus({\n    currentMonth,\n    day,\n    isDateDisabled,\n    selectedDate,\n    rangeBounds,\n    mode,\n  });\n  const activeModifierKeys = getActiveModifiers(day, modifiers);\n  const modifierNames = activeModifierKeys.map(\n    (key) => modifierLabels?.[key] ?? key\n  );\n\n  const handleClick = () => {\n    if (!status.isSelectable) return;\n    onSelectDay(day);\n  };\n\n  const showEndpointHighlight =\n    status.isSelected &&\n    (mode === \"single\" ||\n      status.rangeRole === \"start\" ||\n      status.rangeRole === \"end\" ||\n      !status.inRange);\n  const useSelectionLayout = mode === \"single\" && !reduceMotion;\n\n  return (\n    <motion.button\n      animate={reduceMotion ? undefined : { opacity: 1, scale: 1 }}\n      aria-current={status.today ? \"date\" : undefined}\n      aria-disabled={status.isDisabled || undefined}\n      aria-label={getDayAriaLabel({\n        day,\n        locale,\n        labels,\n        today: status.today,\n        isSelected: status.isSelected,\n        inMonth: status.inMonth,\n        isDisabled: status.isDisabled,\n        rangeRole: status.rangeRole,\n        modifierNames,\n      })}\n      aria-selected={status.isSelected || undefined}\n      className={cn(controlCornerClassName, focusVisibleClassName)}\n      disabled={!status.isSelectable}\n      initial={reduceMotion ? false : { opacity: 0, scale: 0.8 }}\n      onClick={handleClick}\n      onFocus={() => onDayFocus(day)}\n      onKeyDown={(event) => onDayKeyDown(event, day)}\n      ref={(node) => registerDayButton(day, node, status.isSelectable)}\n      style={{\n        position: \"relative\",\n        isolation: \"isolate\",\n        aspectRatio: \"1 / 1\",\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        width: \"100%\",\n        minHeight: dimensions.dayCellMinHeight,\n        fontSize: dimensions.dayCellFontSize,\n        fontWeight: 400,\n        borderRadius: dimensions.dayCellRadius,\n        border: \"none\",\n        background: \"transparent\",\n        cursor: status.isSelectable ? \"pointer\" : \"not-allowed\",\n        color: status.isDisabled\n          ? palette.dayDisabledForeground\n          : status.inMonth\n            ? palette.textPrimary\n            : palette.textDim,\n        padding: 0,\n        fontFamily: \"inherit\",\n        opacity: status.isDisabled ? 0.55 : 1,\n      }}\n      tabIndex={status.isSelectable ? (isFocused ? 0 : -1) : -1}\n      transition={\n        reduceMotion\n          ? { duration: 0 }\n          : { delay: index * 0.012, duration: 0.3, ease: SPRING_EASE }\n      }\n      type=\"button\"\n    >\n      <DayCellMarkup\n        activeModifierKeys={activeModifierKeys}\n        calendarMotionId={calendarMotionId}\n        day={day}\n        dimensions={dimensions}\n        palette={palette}\n        reduceMotion={reduceMotion}\n        showEndpointHighlight={showEndpointHighlight}\n        status={status}\n        useSelectionLayout={useSelectionLayout}\n      />\n    </motion.button>\n  );\n};\n\ntype NavButtonProps = {\n  children: ReactNode;\n  disabled?: boolean;\n  dimensions: CalendarDimensions;\n  onClick?: () => void;\n  \"aria-label\"?: string;\n  palette: CalendarPalette;\n  style?: CSSProperties;\n};\n\nconst NavButton = ({\n  children,\n  disabled = false,\n  dimensions,\n  onClick,\n  palette,\n  style,\n  ...rest\n}: NavButtonProps) => {\n  const [hovered, setHovered] = useState(false);\n\n  return (\n    <button\n      className={cn(controlCornerClassName, focusVisibleClassName)}\n      disabled={disabled}\n      onClick={onClick}\n      onMouseEnter={() => setHovered(true)}\n      onMouseLeave={() => setHovered(false)}\n      style={{\n        height: dimensions.navButtonSize,\n        width: dimensions.navButtonSize,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        borderRadius: dimensions.dayCellRadius,\n        backgroundColor:\n          hovered && !disabled\n            ? palette.navHoverBackground\n            : palette.navBackground,\n        color: disabled\n          ? palette.textDim\n          : hovered\n            ? palette.navForeground\n            : palette.textMuted,\n        border: \"none\",\n        cursor: disabled ? \"default\" : \"pointer\",\n        opacity: disabled ? 0.5 : 1,\n        padding: 0,\n        WebkitTapHighlightColor: \"transparent\",\n        transition: \"background-color 0.15s ease, color 0.15s ease\",\n        ...style,\n      }}\n      type=\"button\"\n      {...rest}\n    >\n      {children}\n    </button>\n  );\n};\n",
      "type": "registry:ui"
    }
  ],
  "title": "Calendar",
  "description": "shadcn-style monthly calendar with animated month/year transitions, selectable days, and date-fns-powered grid generation."
}
