{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"date-picker","type":"registry:ui","title":"Date picker","description":"A date field that opens a calendar, with min, max and today shortcuts.","dependencies":["@radix-ui/react-popover","clsx","lucide-react","tailwind-merge"],"registryDependencies":["https://caliperui.site/r/styles.json"],"files":[{"path":"ui/calendar.tsx","type":"registry:ui","target":"components/ui/calendar.tsx","content":"\"use client\";\n\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent } from \"react\";\nimport { cn } from \"./lib/cn\";\nimport { RollingValue } from \"./rolling-value\";\nimport \"./shared/calendar-day.css\";\nimport \"./shared/chip-option.css\";\nimport \"./calendar.css\";\n\nconst weekdays = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"];\n\nexport function isoDate(year: number, month: number, day: number) {\n  return `${year}-${String(month + 1).padStart(2, \"0\")}-${String(day).padStart(2, \"0\")}`;\n}\n\nexport function parseISODate(value: string) {\n  const [year, month, day] = value.split(\"-\").map(Number);\n  return { year, month: month - 1, day };\n}\n\nexport function formatISODate(value: string) {\n  const { year, month, day } = parseISODate(value);\n  return new Intl.DateTimeFormat(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" }).format(new Date(year, month, day));\n}\n\nexport function shiftMonth(year: number, month: number, amount: number) {\n  const date = new Date(year, month + amount, 1);\n  return { year: date.getFullYear(), month: date.getMonth() };\n}\n\nfunction monthName(year: number, month: number) {\n  return new Intl.DateTimeFormat(\"en-US\", { month: \"long\", year: \"numeric\" }).format(new Date(year, month, 1));\n}\n\nfunction buildDays(year: number, month: number) {\n  const first = new Date(year, month, 1).getDay();\n  const count = new Date(year, month + 1, 0).getDate();\n  const cells: { iso: string; day: number; outside: boolean }[] = [];\n  for (let index = 0; index < first; index += 1) {\n    const date = new Date(year, month, index - first + 1);\n    cells.push({ iso: isoDate(date.getFullYear(), date.getMonth(), date.getDate()), day: date.getDate(), outside: true });\n  }\n  for (let day = 1; day <= count; day += 1) cells.push({ iso: isoDate(year, month, day), day, outside: false });\n  while (cells.length % 7 !== 0) {\n    const date = new Date(year, month + 1, cells.length - (first + count) + 1);\n    cells.push({ iso: isoDate(date.getFullYear(), date.getMonth(), date.getDate()), day: date.getDate(), outside: true });\n  }\n  return cells;\n}\n\nfunction addDays(iso: string, amount: number) {\n  const { year, month, day } = parseISODate(iso);\n  const date = new Date(year, month, day + amount);\n  return isoDate(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction blocked(iso: string, min?: string, max?: string, disabledDates?: (iso: string) => boolean) {\n  if (min && iso < min) return true;\n  if (max && iso > max) return true;\n  return disabledDates?.(iso) ?? false;\n}\n\nexport function Calendar({\n  label,\n  year,\n  month,\n  onMonthChange,\n  selected,\n  rangeStart,\n  rangeEnd,\n  onSelect,\n  onHover,\n  min,\n  max,\n  disabledDates,\n  disabledReason,\n  marks,\n  showToday = false,\n  className,\n}: {\n  label?: string;\n  year?: number;\n  month?: number;\n  onMonthChange?: (year: number, month: number) => void;\n  selected?: string | null;\n  rangeStart?: string | null;\n  rangeEnd?: string | null;\n  onSelect?: (iso: string) => void;\n  onHover?: (iso: string | null) => void;\n  min?: string;\n  max?: string;\n  disabledDates?: (iso: string) => boolean;\n  /** Read with an unavailable day, e.g. \"banks closed\". */\n  disabledReason?: (iso: string) => string | undefined;\n  /** A quiet data mark under the day, e.g. invoices due; the label is read with the date. */\n  marks?: (iso: string) => string | undefined;\n  showToday?: boolean;\n  className?: string;\n}) {\n  const initial = selected ? parseISODate(selected) : { year: 2026, month: 9 };\n  const [localYear, setLocalYear] = useState(initial.year);\n  const [localMonth, setLocalMonth] = useState(initial.month);\n  const [motion, setMotion] = useState<\"next\" | \"prev\">(\"next\");\n  const [selectionMarks, setSelectionMarks] = useState<Array<{ key: string; x: number; y: number; w: number; h: number }>>([]);\n  const days = useRef<HTMLDivElement>(null);\n  const pending = useRef<string | null>(null);\n  const viewYear = year ?? localYear;\n  const viewMonth = month ?? localMonth;\n  const cells = buildDays(viewYear, viewMonth);\n  const today = isoDate(new Date().getFullYear(), new Date().getMonth(), new Date().getDate());\n  const prevMonth = shiftMonth(viewYear, viewMonth, -1);\n  const following = shiftMonth(viewYear, viewMonth, 1);\n  const prevDisabled = Boolean(min && isoDate(prevMonth.year, prevMonth.month, new Date(prevMonth.year, prevMonth.month + 1, 0).getDate()) < min);\n  const nextDisabled = Boolean(max && isoDate(following.year, following.month, 1) > max);\n  const start = rangeStart && rangeEnd && rangeStart > rangeEnd ? rangeEnd : rangeStart;\n  const end = rangeStart && rangeEnd && rangeStart > rangeEnd ? rangeStart : rangeEnd;\n\n  function setMonth(nextYear: number, nextMonth: number) {\n    const forward = nextYear > viewYear || (nextYear === viewYear && nextMonth > viewMonth);\n    setMotion(forward ? \"next\" : \"prev\");\n    if (onMonthChange) onMonthChange(nextYear, nextMonth);\n    else {\n      setLocalYear(nextYear);\n      setLocalMonth(nextMonth);\n    }\n  }\n\n  function focusIso(iso: string) {\n    const parsed = parseISODate(iso);\n    if (parsed.year !== viewYear || parsed.month !== viewMonth) {\n      pending.current = iso;\n      setMonth(parsed.year, parsed.month);\n      return;\n    }\n    days.current?.querySelector<HTMLButtonElement>(`[data-date=\"${iso}\"]`)?.focus();\n  }\n\n  function nearestOpen(iso: string, step: number) {\n    let next = iso;\n    for (let guard = 0; guard < 42 && blocked(next, min, max, disabledDates); guard += 1) next = addDays(next, step);\n    return blocked(next, min, max, disabledDates) ? null : next;\n  }\n\n  function move(event: KeyboardEvent<HTMLDivElement>) {\n    const current = (document.activeElement as HTMLElement | null)?.dataset.date;\n    if (!current) return;\n    const { year: y, month: m, day } = parseISODate(current);\n    const weekday = new Date(y, m, day).getDay();\n    let step = 0;\n    if (event.key === \"ArrowRight\") step = 1;\n    else if (event.key === \"ArrowLeft\") step = -1;\n    else if (event.key === \"ArrowDown\") step = 7;\n    else if (event.key === \"ArrowUp\") step = -7;\n    else if (event.key === \"Home\") step = -weekday;\n    else if (event.key === \"End\") step = 6 - weekday;\n    else if (event.key === \"PageDown\") step = event.shiftKey ? 365 : 30;\n    else if (event.key === \"PageUp\") step = event.shiftKey ? -365 : -30;\n    if (step === 0) return;\n    event.preventDefault();\n    const next = nearestOpen(addDays(current, step), step > 0 ? 1 : -1);\n    if (next) focusIso(next);\n  }\n\n  useEffect(() => {\n    const iso = pending.current;\n    if (!iso) return;\n    const button = days.current?.querySelector<HTMLButtonElement>(`[data-date=\"${iso}\"]`);\n    if (!button) return;\n    pending.current = null;\n    button.focus();\n  }, [viewYear, viewMonth, cells.length]);\n\n  useLayoutEffect(() => {\n    const root = days.current;\n    if (!root) return;\n    const ends = [selected, rangeStart, rangeEnd].filter((iso, index, list): iso is string => Boolean(iso) && list.indexOf(iso) === index);\n    const next = ends.flatMap((iso) => {\n      const node = root.querySelector<HTMLElement>(`[data-date=\"${iso}\"]`);\n      if (!node) return [];\n      return [{ key: iso, x: node.offsetLeft, y: node.offsetTop, w: node.offsetWidth, h: node.offsetHeight }];\n    });\n    setSelectionMarks((current) => (current.length === next.length && current.every((mark, index) => mark.key === next[index]?.key && mark.x === next[index]?.x && mark.y === next[index]?.y) ? current : next));\n  }, [selected, rangeStart, rangeEnd, viewYear, viewMonth, cells.length]);\n\n  return (\n    <div data-slot=\"calendar\" className={cn(\"w-[17.5rem] max-w-full\", className)}>\n      <div className=\"mb-2 flex items-center justify-between gap-2\">\n        <button type=\"button\" aria-label=\"Previous month\" aria-disabled={prevDisabled || undefined} disabled={prevDisabled} className=\"grid size-8 place-items-center rounded-control outline-none hover:bg-muted focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-ring disabled:opacity-35\" onClick={() => { const next = shiftMonth(viewYear, viewMonth, -1); setMonth(next.year, next.month); }}>\n          <ChevronLeft aria-hidden=\"true\" className=\"size-4\" />\n        </button>\n        <p className=\"text-sm font-semibold\">\n          <span className=\"sr-only\" aria-live=\"polite\">{monthName(viewYear, viewMonth)}</span>\n          <RollingValue value={monthName(viewYear, viewMonth)} direction={motion === \"next\" ? \"up\" : \"down\"} />\n        </p>\n        <button type=\"button\" aria-label=\"Next month\" aria-disabled={nextDisabled || undefined} disabled={nextDisabled} className=\"grid size-8 place-items-center rounded-control outline-none hover:bg-muted focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-ring disabled:opacity-35\" onClick={() => { const next = shiftMonth(viewYear, viewMonth, 1); setMonth(next.year, next.month); }}>\n          <ChevronRight aria-hidden=\"true\" className=\"size-4\" />\n        </button>\n      </div>\n      <div key={`${viewYear}-${viewMonth}`} role=\"grid\" aria-label={label ?? monthName(viewYear, viewMonth)} data-slot=\"calendar-grid\" data-motion={motion} onKeyDown={move} onMouseLeave={() => onHover?.(null)}>\n        <div className=\"grid grid-cols-7\" aria-hidden=\"true\">\n          {weekdays.map((day) => (\n            <span key={day} className=\"grid h-8 place-items-center text-xs font-medium text-muted-foreground\">{day}</span>\n          ))}\n        </div>\n        <div ref={days} className=\"relative grid grid-cols-7\">\n          {Array.from({ length: cells.length / 7 }, (_, week) => {\n            const row = cells.slice(week * 7, week * 7 + 7);\n            const first = row.findIndex((cell) => start && end && cell.iso >= start && cell.iso <= end);\n            let last = -1;\n            for (let index = row.length - 1; index >= 0; index -= 1) {\n              const cell = row[index];\n              if (cell && start && end && cell.iso >= start && cell.iso <= end) {\n                last = index;\n                break;\n              }\n            }\n            if (first < 0 || last < 0) return null;\n            return <span key={week} aria-hidden=\"true\" data-slot=\"calendar-range\" style={{ top: week * 36, left: `${(first / 7) * 100}%`, width: `${((last - first + 1) / 7) * 100}%` }} />;\n          })}\n          {selectionMarks.map((mark) => (\n            <span key={mark.key} aria-hidden=\"true\" data-slot=\"calendar-selection\" style={{ width: mark.w, height: mark.h, transform: `translate(${mark.x}px, ${mark.y}px)` }} />\n          ))}\n          {cells.map((cell) => {\n            const inRange = Boolean(start && end && cell.iso >= start && cell.iso <= end);\n            const isSelected = cell.iso === selected || cell.iso === rangeStart || cell.iso === rangeEnd;\n            const isDisabled = blocked(cell.iso, min, max, disabledDates);\n            const mark = marks?.(cell.iso);\n            const reason = isDisabled ? disabledReason?.(cell.iso) : undefined;\n            const tabIso = selected && cells.some((item) => item.iso === selected) ? selected : cells.find((item) => !item.outside && !blocked(item.iso, min, max, disabledDates))?.iso;\n            return (\n              <button\n                key={cell.iso}\n                type=\"button\"\n                role=\"gridcell\"\n                tabIndex={cell.iso === tabIso ? 0 : -1}\n                data-date={cell.iso}\n                data-slot=\"calendar-day\"\n                data-selected={isSelected || undefined}\n                data-in-range={inRange || undefined}\n                data-outside={cell.outside}\n                aria-selected={isSelected}\n                aria-current={cell.iso === today ? \"date\" : undefined}\n                aria-disabled={isDisabled || undefined}\n                aria-label={[formatISODate(cell.iso), mark, reason && `unavailable: ${reason}`].filter(Boolean).join(\", \")}\n                data-mark={mark ? true : undefined}\n                className=\"relative z-10 grid aspect-square w-full max-w-9 place-items-center text-sm outline-none focus-visible:outline-solid focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring aria-disabled:opacity-35 data-[outside=true]:text-muted-foreground data-[selected=true]:text-accent-foreground\"\n                onMouseEnter={() => onHover?.(cell.iso)}\n                onClick={() => {\n                  if (!isDisabled) onSelect?.(cell.iso);\n                }}\n              >\n                {cell.day}\n              </button>\n            );\n          })}\n        </div>\n      </div>\n      {showToday && (\n        <button type=\"button\" className=\"mt-2 h-8 w-full rounded-surface text-sm font-medium outline-none hover:bg-muted focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-ring\" onClick={() => {\n          const now = new Date();\n          const today = isoDate(now.getFullYear(), now.getMonth(), now.getDate());\n          if (!blocked(today, min, max, disabledDates)) {\n            setMonth(now.getFullYear(), now.getMonth());\n            onSelect?.(today);\n          }\n        }}>\n          Today\n        </button>\n      )}\n    </div>\n  );\n}\n"},{"path":"ui/date-picker.tsx","type":"registry:ui","target":"components/ui/date-picker.tsx","content":"\"use client\";\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Calendar as CalendarIcon } from \"lucide-react\";\nimport { useId, useRef, useState } from \"react\";\nimport { Calendar, formatISODate, parseISODate } from \"./calendar\";\nimport { Label } from \"./label\";\nimport { RollingValue } from \"./rolling-value\";\nimport { cn } from \"./lib/cn\";\nimport \"./shared/date-menu.css\";\n\nfunction DateParts({ value, direction }: { value: string; direction: \"up\" | \"down\" | \"none\" }) {\n  const { year, month, day } = parseISODate(value);\n  const monthLabel = new Intl.DateTimeFormat(\"en-US\", { month: \"short\" }).format(new Date(year, month, day));\n  return (\n    <span className=\"inline-flex items-baseline gap-1\">\n      <RollingValue value={monthLabel} direction={direction} />\n      <RollingValue value={String(day)} direction={direction} />\n      <RollingValue value={String(year)} direction={direction} />\n    </span>\n  );\n}\n\nexport function DatePicker({\n  label,\n  value,\n  defaultValue = null,\n  onValueChange,\n  min,\n  max,\n  showToday = true,\n  name,\n  disabled,\n  className,\n}: {\n  label: string;\n  value?: string | null;\n  defaultValue?: string | null;\n  onValueChange?: (value: string | null) => void;\n  min?: string;\n  max?: string;\n  showToday?: boolean;\n  name?: string;\n  disabled?: boolean;\n  className?: string;\n}) {\n  const fieldId = useId();\n  const root = useRef<HTMLDivElement>(null);\n  const [local, setLocal] = useState(defaultValue);\n  const [open, setOpen] = useState(false);\n  const [direction, setDirection] = useState<\"up\" | \"down\" | \"none\">(\"none\");\n  const current = value === undefined ? local : value;\n\n  function choose(next: string) {\n    if (current) setDirection(next > current ? \"up\" : \"down\");\n    if (value === undefined) setLocal(next);\n    onValueChange?.(next);\n    window.setTimeout(() => setOpen(false), 240);\n  }\n\n  function clear() {\n    setDirection(\"none\");\n    if (value === undefined) setLocal(null);\n    onValueChange?.(null);\n    setOpen(false);\n  }\n\n\n  return (\n    <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n    <div ref={root} className={cn(\"relative grid max-w-sm gap-1.5\", className)}>\n      <Label htmlFor={fieldId}>{label}</Label>\n      <PopoverPrimitive.Trigger asChild>\n      <button\n        id={fieldId}\n        type=\"button\"\n        disabled={disabled}\n        aria-haspopup=\"dialog\"\n        aria-expanded={open}\n        className=\"flex h-[var(--control-height)] items-center rounded-control bg-[var(--field)] shadow-[var(--shadow-field)] transition-shadow hover:shadow-[var(--shadow-field-hover)] px-3 text-left text-sm outline-none focus-visible:shadow-[var(--shadow-field-focus)] disabled:opacity-45\"\n        onKeyDown={(event) => {\n          if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n            event.preventDefault();\n            setOpen(true);\n          }\n        }}\n      >\n        {current ? (\n          <>\n            <span className=\"sr-only\">{formatISODate(current)}</span>\n            <DateParts value={current} direction={direction} />\n          </>\n        ) : (\n          <span className=\"text-muted-foreground\">Select a date</span>\n        )}\n        <CalendarIcon aria-hidden=\"true\" className=\"ml-auto size-4 shrink-0 text-muted-foreground\" />\n      </button>\n      </PopoverPrimitive.Trigger>\n      <PopoverPrimitive.Portal>\n        <PopoverPrimitive.Content\n          aria-label={label}\n          data-slot=\"date-menu\"\n          align=\"start\"\n          sideOffset={4}\n          collisionPadding={12}\n          className=\"z-50 max-h-[var(--radix-popover-content-available-height)] overflow-y-auto p-3 outline-none\"\n          onOpenAutoFocus={(event) => {\n            // Land on the chosen day (or the first day) rather than the first button.\n            const target = (event.currentTarget as HTMLElement | null)?.querySelector<HTMLButtonElement>(current ? `[data-date=\"${current}\"]` : \"[data-date]\");\n            if (target) {\n              event.preventDefault();\n              target.focus();\n            }\n          }}\n        >\n          <Calendar label={label} selected={current} onSelect={choose} min={min} max={max} showToday={showToday} />\n          {current ? (\n            <button type=\"button\" className=\"mt-2 h-8 w-full rounded-surface text-sm font-medium outline-none hover:bg-muted focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-ring\" onClick={clear}>\n              Clear\n            </button>\n          ) : null}\n        </PopoverPrimitive.Content>\n      </PopoverPrimitive.Portal>\n      {name ? <input type=\"hidden\" name={name} value={current ?? \"\"} /> : null}\n    </div>\n    </PopoverPrimitive.Root>\n  );\n}\n"},{"path":"ui/label.tsx","type":"registry:ui","target":"components/ui/label.tsx","content":"import type { ComponentProps } from \"react\";\nimport { cn } from \"./lib/cn\";\n\nexport function Label({ className, ...props }: ComponentProps<\"label\">) {\n  return (\n    <label\n      data-slot=\"label\"\n      className={cn(\n        \"inline-block max-w-full text-sm leading-5 font-medium [overflow-wrap:anywhere]\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n"},{"path":"ui/lib/cn.ts","type":"registry:ui","target":"components/ui/lib/cn.ts","content":"import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n  extend: { theme: { radius: [\"control\", \"surface\", \"overlay\"], shadow: [\"overlay\"] } },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"},{"path":"ui/rolling-value.tsx","type":"registry:ui","target":"components/ui/rolling-value.tsx","content":"\"use client\";\n\nimport { useState } from \"react\";\nimport \"./rolling-value.css\";\n\nexport function RollingValue({\n  value,\n  direction,\n}: {\n  value: string;\n  direction: \"up\" | \"down\" | \"none\";\n}) {\n  const [frame, setFrame] = useState({ value, prior: value });\n  if (frame.value !== value) setFrame({ value, prior: frame.value });\n  const prior = frame.prior;\n  const glyphs = [...value];\n\n  return (\n    <span className=\"inline-flex items-center font-medium tabular-nums\" aria-hidden=\"true\">\n      {glyphs.map((glyph, index) => {\n        const changed = prior.length !== glyphs.length || prior[index] !== glyph;\n        return (\n          <span key={`${index}-${glyph}`} className=\"inline-block h-[1.2em] overflow-hidden\">\n            <span\n              data-slot=\"number-digit\"\n              data-direction={changed ? direction : \"none\"}\n              className=\"block\"\n            >\n              {glyph === \" \" ? \"\\u00A0\" : glyph}\n            </span>\n          </span>\n        );\n      })}\n    </span>\n  );\n}\n"},{"path":"ui/shared/calendar-day.css","type":"registry:file","target":"components/ui/shared/calendar-day.css","content":"/* Shared by calendar.tsx, returns-calendar.tsx; each imports it. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  /* Calendar: today gets an ember dot, data marks a quiet bar, unavailable days are struck through. */\n  [data-slot=\"calendar-day\"][aria-current=\"date\"] {\n    font-weight: 600;\n  }\n  [data-slot=\"calendar-day\"][aria-current=\"date\"]::before {\n    content: \"\";\n    position: absolute;\n    top: 5px;\n    left: 50%;\n    width: 4px;\n    height: 4px;\n    margin-left: -2px;\n    border-radius: 50%;\n    background: var(--ring);\n  }\n  [data-slot=\"calendar-day\"][data-mark]::after {\n    content: \"\";\n    position: absolute;\n    bottom: 5px;\n    left: 50%;\n    width: 12px;\n    height: 2px;\n    margin-left: -6px;\n    border-radius: 1px;\n    background: var(--border-strong);\n  }\n  [data-slot=\"calendar-day\"][data-selected=\"true\"]::after,\n  [data-slot=\"calendar-day\"][data-selected=\"true\"]::before {\n    background: var(--accent-foreground);\n  }\n  [data-slot=\"calendar-day\"][aria-disabled=\"true\"] {\n    text-decoration: line-through;\n  }\n  [data-slot=\"calendar-day\"] {\n    transition:\n      background-color var(--duration-travel) var(--ease-showcase),\n      color var(--duration-fast) var(--ease-out);\n  }\n  [data-slot=\"calendar-day\"][data-selected=\"true\"] {\n    color: var(--background);\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"calendar-day\"] {\n      transition:\n        background-color 400ms var(--ease-showcase),\n        color 120ms var(--ease-out);\n    }\n    [data-slot=\"calendar-day\"][data-selected=\"true\"] {\n      animation: caliper-day-select 400ms var(--ease-showcase);\n    }\n  }\n  [data-slot=\"calendar-day\"] {\n    font-size: 0.75rem;\n    color: var(--muted-foreground);\n  }\n}\n"},{"path":"ui/shared/chip-option.css","type":"registry:file","target":"components/ui/shared/chip-option.css","content":"/* Shared by calendar.tsx, chart-parts.tsx, chip-group.tsx, data-table.tsx, number-field.tsx, password-field.tsx, stepper.tsx; each imports it. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  /* Depth sets 2 and 3 end */\n\n  /* Press feedback (2026-10-20, motion audit): every pressable control answers a press. Compact controls take the\n     system press scale, as Button does; wide rows deepen their fill instead, since scaling a full-width row reads as a\n     jump. Disabled controls stay still. */\n  :is([data-slot=\"chip-option\"], [data-slot=\"number-field\"] button, [data-slot=\"password-toggle\"], [data-slot=\"calendar\"] button, [data-slot=\"chart-legend-item\"], [data-slot=\"sort-button\"], [data-slot=\"stepper\"] button):active:not(:disabled):not([aria-disabled=\"true\"]) {\n    scale: var(--motion-press-scale);\n  }\n}\n"},{"path":"ui/calendar.css","type":"registry:file","target":"components/ui/calendar.css","content":"/* calendar.tsx's styles; it imports this file. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  [data-slot=\"calendar-grid\"][data-motion=\"next\"] {\n    animation: caliper-calendar-next var(--duration-travel) var(--ease-showcase);\n  }\n  [data-slot=\"calendar-grid\"][data-motion=\"prev\"] {\n    animation: caliper-calendar-prev var(--duration-travel) var(--ease-showcase);\n  }\n  [data-slot=\"calendar-range\"] {\n    position: absolute;\n    z-index: 0;\n    height: 2.25rem;\n    border-radius: 999px;\n    background: var(--muted);\n    transition:\n      left var(--duration-travel) var(--ease-showcase),\n      width var(--duration-travel) var(--ease-showcase);\n  }\n  [data-slot=\"calendar-selection\"] {\n    position: absolute;\n    z-index: 1;\n    border-radius: var(--radius-control);\n    background: var(--accent);\n    pointer-events: none;\n    transition:\n      transform var(--duration-travel) var(--ease-showcase),\n      width var(--duration-travel) var(--ease-showcase),\n      height var(--duration-travel) var(--ease-showcase);\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"calendar-grid\"][data-motion=\"next\"] {\n      animation: caliper-calendar-next 400ms var(--ease-showcase);\n    }\n    [data-slot=\"calendar-grid\"][data-motion=\"prev\"] {\n      animation: caliper-calendar-prev 400ms var(--ease-showcase);\n    }\n  }\n}\n"},{"path":"ui/shared/date-menu.css","type":"registry:file","target":"components/ui/shared/date-menu.css","content":"/* Shared by date-picker.tsx, date-range-picker.tsx; each imports it. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  [data-slot=\"date-menu\"] {\n    border: 1px solid var(--border);\n    border-radius: var(--radius-overlay);\n    transform-origin: top center;\n    animation: caliper-menu-enter var(--duration-travel) var(--ease-showcase);\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"date-menu\"] {\n      animation: caliper-menu-enter 400ms var(--ease-showcase);\n    }\n  }\n}\n\n[data-slot=\"date-menu\"] {\n  background-color: var(--elevated-glass);\n  border-color: color-mix(in srgb, var(--edge-light) 45%, var(--border));\n  backdrop-filter: blur(var(--blur-overlay));\n  box-shadow:\n    var(--shadow-overlay),\n    0 0 40px var(--edge-glow),\n    inset 0 1px 0 var(--edge-light);\n}\n"},{"path":"ui/rolling-value.css","type":"registry:file","target":"components/ui/rolling-value.css","content":"/* rolling-value.tsx's styles; it imports this file. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  [data-slot=\"number-digit\"][data-direction=\"up\"] {\n    animation: caliper-digit-in var(--duration-travel) var(--ease-showcase);\n  }\n  [data-slot=\"number-digit\"][data-direction=\"down\"] {\n    animation: caliper-digit-down var(--duration-travel) var(--ease-showcase);\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"number-digit\"][data-direction=\"up\"] {\n      animation: caliper-digit-in 400ms var(--ease-showcase);\n    }\n    [data-slot=\"number-digit\"][data-direction=\"down\"] {\n      animation: caliper-digit-down 400ms var(--ease-showcase);\n    }\n  }\n}\n\n@keyframes caliper-digit-down {\n  from {\n    transform: translateY(70%);\n  }\n  to {\n    transform: translateY(0);\n  }\n}\n"}],"categories":["dates-colour"],"meta":{"tier":"free","license":"MIT","family":"dates","docs":"/docs/components/date-picker"}}