@tribepad/themis 1.9.4 → 1.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/elements/AlertDialog/index.js +1 -1
  3. package/dist/elements/AlertDialog/index.js.map +1 -1
  4. package/dist/elements/AlertDialog/index.mjs +1 -1
  5. package/dist/elements/AlertDialog/index.mjs.map +1 -1
  6. package/dist/elements/Breadcrumbs/index.js +1 -1
  7. package/dist/elements/Breadcrumbs/index.js.map +1 -1
  8. package/dist/elements/Breadcrumbs/index.mjs +1 -1
  9. package/dist/elements/Breadcrumbs/index.mjs.map +1 -1
  10. package/dist/elements/Button/index.js +1 -1
  11. package/dist/elements/Button/index.js.map +1 -1
  12. package/dist/elements/Button/index.mjs +1 -1
  13. package/dist/elements/Button/index.mjs.map +1 -1
  14. package/dist/elements/Card/index.js +1 -1
  15. package/dist/elements/Card/index.js.map +1 -1
  16. package/dist/elements/Card/index.mjs +1 -1
  17. package/dist/elements/Card/index.mjs.map +1 -1
  18. package/dist/elements/Carousel/Carousel.d.ts +8 -1
  19. package/dist/elements/Carousel/Carousel.d.ts.map +1 -1
  20. package/dist/elements/Carousel/LazyCarousel.d.ts +1 -1
  21. package/dist/elements/Carousel/LazyCarousel.d.ts.map +1 -1
  22. package/dist/elements/Carousel/index.js +1 -1
  23. package/dist/elements/Carousel/index.js.map +1 -1
  24. package/dist/elements/Carousel/index.mjs +1 -1
  25. package/dist/elements/Carousel/index.mjs.map +1 -1
  26. package/dist/elements/ChatInterface/ChatLiveRegions.d.ts +2 -2
  27. package/dist/elements/ChatInterface/ChatLiveRegions.d.ts.map +1 -1
  28. package/dist/elements/ChatInterface/ChatMessageBubble.d.ts +1 -1
  29. package/dist/elements/ChatInterface/ChatMessageBubble.d.ts.map +1 -1
  30. package/dist/elements/ChatInterface/ChatThinkingDisplay.d.ts +2 -2
  31. package/dist/elements/ChatInterface/ChatThinkingDisplay.d.ts.map +1 -1
  32. package/dist/elements/ChatInterface/ChatTypingIndicator.d.ts +2 -2
  33. package/dist/elements/ChatInterface/ChatTypingIndicator.d.ts.map +1 -1
  34. package/dist/elements/ChatInterface/index.js +1 -1
  35. package/dist/elements/ChatInterface/index.js.map +1 -1
  36. package/dist/elements/ChatInterface/index.mjs +1 -1
  37. package/dist/elements/ChatInterface/index.mjs.map +1 -1
  38. package/dist/elements/FeatureIcon/FeatureIcon.d.ts +3 -0
  39. package/dist/elements/FeatureIcon/FeatureIcon.d.ts.map +1 -0
  40. package/dist/elements/FeatureIcon/FeatureIcon.styles.d.ts +17 -0
  41. package/dist/elements/FeatureIcon/FeatureIcon.styles.d.ts.map +1 -0
  42. package/dist/elements/FeatureIcon/FeatureIcon.types.d.ts +137 -0
  43. package/dist/elements/FeatureIcon/FeatureIcon.types.d.ts.map +1 -0
  44. package/dist/elements/FeatureIcon/index.d.ts +25 -0
  45. package/dist/elements/FeatureIcon/index.d.ts.map +1 -0
  46. package/dist/elements/FeatureIcon/index.js +3 -0
  47. package/dist/elements/FeatureIcon/index.js.map +1 -0
  48. package/dist/elements/FeatureIcon/index.mjs +3 -0
  49. package/dist/elements/FeatureIcon/index.mjs.map +1 -0
  50. package/dist/elements/FileField/index.js +1 -1
  51. package/dist/elements/FileField/index.js.map +1 -1
  52. package/dist/elements/FileField/index.mjs +1 -1
  53. package/dist/elements/FileField/index.mjs.map +1 -1
  54. package/dist/elements/Filters/index.js +1 -1
  55. package/dist/elements/Filters/index.js.map +1 -1
  56. package/dist/elements/Filters/index.mjs +1 -1
  57. package/dist/elements/Filters/index.mjs.map +1 -1
  58. package/dist/elements/Modal/Modal.styles.d.ts +2 -2
  59. package/dist/elements/Modal/Modal.types.d.ts +2 -2
  60. package/dist/elements/NumberField/index.js +1 -1
  61. package/dist/elements/NumberField/index.js.map +1 -1
  62. package/dist/elements/NumberField/index.mjs +1 -1
  63. package/dist/elements/NumberField/index.mjs.map +1 -1
  64. package/dist/elements/PageTitle/index.js +1 -1
  65. package/dist/elements/PageTitle/index.js.map +1 -1
  66. package/dist/elements/PageTitle/index.mjs +1 -1
  67. package/dist/elements/PageTitle/index.mjs.map +1 -1
  68. package/dist/elements/Pagination/index.js +1 -1
  69. package/dist/elements/Pagination/index.js.map +1 -1
  70. package/dist/elements/Pagination/index.mjs +1 -1
  71. package/dist/elements/Pagination/index.mjs.map +1 -1
  72. package/dist/elements/Panel/Panel.d.ts +1 -1
  73. package/dist/elements/Panel/Panel.types.d.ts +2 -2
  74. package/dist/elements/PasswordField/index.js +1 -1
  75. package/dist/elements/PasswordField/index.js.map +1 -1
  76. package/dist/elements/PasswordField/index.mjs +1 -1
  77. package/dist/elements/PasswordField/index.mjs.map +1 -1
  78. package/dist/elements/Resizable/index.js +1 -1
  79. package/dist/elements/Resizable/index.js.map +1 -1
  80. package/dist/elements/Resizable/index.mjs +1 -1
  81. package/dist/elements/Resizable/index.mjs.map +1 -1
  82. package/dist/elements/SearchField/index.js +1 -1
  83. package/dist/elements/SearchField/index.js.map +1 -1
  84. package/dist/elements/SearchField/index.mjs +1 -1
  85. package/dist/elements/SearchField/index.mjs.map +1 -1
  86. package/dist/elements/Select/Select.d.ts +3 -3
  87. package/dist/elements/Select/Select.d.ts.map +1 -1
  88. package/dist/elements/Sidebar/Sidebar.styles.d.ts +1 -1
  89. package/dist/elements/Sidebar/Sidebar.styles.d.ts.map +1 -1
  90. package/dist/elements/Sidebar/Sidebar.types.d.ts +2 -2
  91. package/dist/elements/Sidebar/SidebarRail.d.ts.map +1 -1
  92. package/dist/elements/Sidebar/index.js +1 -1
  93. package/dist/elements/Sidebar/index.js.map +1 -1
  94. package/dist/elements/Sidebar/index.mjs +1 -1
  95. package/dist/elements/Sidebar/index.mjs.map +1 -1
  96. package/dist/elements/Table/index.js +1 -1
  97. package/dist/elements/Table/index.js.map +1 -1
  98. package/dist/elements/Table/index.mjs +1 -1
  99. package/dist/elements/Table/index.mjs.map +1 -1
  100. package/dist/elements/TextField/index.js +1 -1
  101. package/dist/elements/TextField/index.js.map +1 -1
  102. package/dist/elements/TextField/index.mjs +1 -1
  103. package/dist/elements/TextField/index.mjs.map +1 -1
  104. package/dist/elements/Timeline/index.js +1 -1
  105. package/dist/elements/Timeline/index.js.map +1 -1
  106. package/dist/elements/Timeline/index.mjs +1 -1
  107. package/dist/elements/Timeline/index.mjs.map +1 -1
  108. package/dist/elements/Toast/index.js +1 -1
  109. package/dist/elements/Toast/index.js.map +1 -1
  110. package/dist/elements/Toast/index.mjs +1 -1
  111. package/dist/elements/Toast/index.mjs.map +1 -1
  112. package/dist/elements/Wizard/index.js +1 -1
  113. package/dist/elements/Wizard/index.js.map +1 -1
  114. package/dist/elements/Wizard/index.mjs +1 -1
  115. package/dist/elements/Wizard/index.mjs.map +1 -1
  116. package/dist/elements/index.d.ts +2 -0
  117. package/dist/elements/index.d.ts.map +1 -1
  118. package/dist/elements/index.js +1 -1
  119. package/dist/elements/index.js.map +1 -1
  120. package/dist/elements/index.mjs +1 -1
  121. package/dist/elements/index.mjs.map +1 -1
  122. package/dist/index.js +2 -2
  123. package/dist/index.js.map +1 -1
  124. package/dist/index.mjs +2 -2
  125. package/dist/index.mjs.map +1 -1
  126. package/dist/styles/animations.css +15 -0
  127. package/package.json +16 -14
  128. package/src/elements/FeatureIcon/FeatureIcon.stories.tsx +164 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Button/Button.styles.ts","../../../src/styles/interaction-states.ts","../../../src/elements/ButtonGroup/ButtonGroupContext.tsx","../../../src/elements/ButtonGroup/ButtonGroup.variants.ts","../../../src/elements/Button/Button.tsx","../../../src/hooks/useContainerNarrow.ts","../../../src/hooks/useReducedMotion.ts","../../../src/elements/Timeline/TimelineContext.tsx","../../../src/elements/Timeline/Timeline.styles.ts","../../../src/elements/Timeline/TimelineItem.tsx","../../../src/elements/Timeline/Timeline.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/Timeline/Timeline.types.ts"],"names":["cn","inputs","twMerge","clsx","buttonOuterVariants","cva","buttonVisualVariants","PRESSED_STYLES","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","ButtonGroupContext","createContext","useButtonGroupContext","useContext","ButtonGroupItemContext","useButtonGroupItemContext","buttonGroupItemVariants","Button","memo","forwardRef","className","buttonVisualClassName","variant","size","visualSize","fullWidth","loading","loadingText","shortcut","children","isDisabled","paywall","paywallRedirect","paywallDescription","onPress","props","ref","paywallDescriptionId","useId","groupContext","itemContext","effectiveVariant","effectiveSize","effectiveIsDisabled","isInVerticalGroup","effectiveFullWidth","positionClassName","effectiveVisualSize","jsx","AriaButton","e","renderProps","jsxs","Fragment","Loader2","Zap","useContainerNarrow","breakpoint","narrow","setNarrow","useState","useEffect","el","measure","observer","QUERY","getInitialState","useReducedMotion","prefersReducedMotion","setPrefersReducedMotion","mql","handler","event","TimelineConfigContext","useTimelineContext","ctx","timelineVariants","timelineItemVariants","timelineMarkerVariants","timelineConnectorVariants","timelineContentVariants","RAIL_PRIMARY","META_CLASS","TITLE_CLASS","DESC_CLASS","INTERACTIVE_WRAP","HOVER_LAYER","DOT_HIGHLIGHT","ICON_HIGHLIGHT","TimelineItemImpl","id","date","label","dateFormatOptions","title","description","icon","href","target","rel","ariaLabel","ariaLabelledBy","ariaDescribedBy","testId","orientation","marker","locale","dateFormatter","formatDate","titleHeadingLevel","registerItem","itemFormatter","useMemo","dateObj","isValidDate","registerRef","useCallback","node","meta","interactive","Heading","titleNode","descNode","content","rail","dotAlign","markerHighlight","markerNode","connector","contentClass","interactiveBody","contentRegion","Link","TimelineItem","DEFAULT_DATE_OPTIONS","TimelineRoot","collapseBelow","onLoadMore","hasMore","isLoadingMore","loadMoreLabel","emptyState","landmarkLabel","rootRef","useRef","listRef","itemNodes","reducedMotion","effectiveOrientation","scrollToNode","itemId","useImperativeHandle","configValue","itemCount","Children","isValidElement","isEmpty","pendingLoadRef","liveMessage","setLiveMessage","handleLoadMore","pending","firstNew","list","Timeline","BaseComponentPropsSchema","z","TimelineOrientationSchema","TimelineMarkerSchema","TimelineHeadingLevelSchema","TimelinePropsSchema","TimelineItemPropsSchema"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { cva } from 'class-variance-authority';\n\n/**\n * Layer 1: Transparent outer touch target (44x44px minimum)\n * Handles WCAG 2.2 AAA touch target requirement\n * Always transparent, centers the visual button inside\n * IMPORTANT: Focus ring stays on Layer 1 for AAA compliance (2.4.13)\n *\n * In vertical ButtonGroups, uses items-stretch so the visual layer (Layer 2)\n * can fill the full touch target height, eliminating gaps between buttons.\n */\nexport const buttonOuterVariants = cva(\n \"inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n inVerticalGroup: {\n true: \"items-stretch\",\n false: \"items-center\",\n },\n },\n defaultVariants: {\n fullWidth: false,\n inVerticalGroup: false,\n },\n }\n);\n\n/**\n * Layer 2: Visual button appearance (adjustable size)\n * Provides the visual appearance with configurable size\n * Can be smaller than touch target for use cases like carousel dots\n * NOTE: NO focus-visible styles here - focus ring is on Layer 1\n */\nexport const buttonVisualVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1\",\n destructive:\n \"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake\",\n outline:\n \"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)]\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n link: \"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n visualSize: {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3 text-xs\",\n lg: \"h-11 rounded-md px-6 text-base\",\n icon: \"h-10 w-10\",\n dot: \"h-5 w-5 rounded-full p-0 min-h-0 min-w-0\",\n },\n paywall: {\n true: \"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n visualSize: \"default\",\n paywall: false,\n },\n }\n);\n\n/**\n * @deprecated Use buttonVisualVariants instead. This alias is kept for backward compatibility.\n */\nexport const buttonVariants = buttonVisualVariants;\n","/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","\"use client\";\n\nimport { createContext, useContext } from 'react';\nimport type {\n ButtonGroupContextValue,\n ButtonGroupItemContextValue,\n} from './ButtonGroup.types';\n\n/**\n * ButtonGroup Context System (Two-Level)\n *\n * Provides a two-level context pattern for ButtonGroup:\n *\n * 1. ButtonGroupContext (group-level):\n * - Provides: orientation, variant, size, isDisabled\n * - Consumed by: Button (for prop inheritance), Separator (for orientation)\n *\n * 2. ButtonGroupItemContext (item-level):\n * - Provides: position ('first' | 'middle' | 'last' | 'only')\n * - Consumed by: Button (for border-radius styling)\n *\n * Both contexts return null when not in a provider, allowing Button\n * to work standalone without any group context.\n *\n * @see plan.md for architecture details\n * @see ButtonGroup.tsx for Provider implementation\n */\n\n// =============================================================================\n// Group-Level Context\n// =============================================================================\n\n/**\n * Context for group-level props (orientation, variant, size, isDisabled)\n * Default value is null to indicate \"not in a group\"\n */\nconst ButtonGroupContext = createContext<ButtonGroupContextValue | null>(null);\n\nButtonGroupContext.displayName = 'ButtonGroupContext';\n\n/**\n * Hook to access group-level context\n * @returns ButtonGroupContextValue if inside a ButtonGroup, null otherwise\n */\nexport function useButtonGroupContext(): ButtonGroupContextValue | null {\n return useContext(ButtonGroupContext);\n}\n\n// =============================================================================\n// Item-Level Context\n// =============================================================================\n\n/**\n * Context for per-button position information\n * Default value is null to indicate \"not wrapped with position context\"\n */\nconst ButtonGroupItemContext =\n createContext<ButtonGroupItemContextValue | null>(null);\n\nButtonGroupItemContext.displayName = 'ButtonGroupItemContext';\n\n/**\n * Hook to access item-level context (position)\n * @returns ButtonGroupItemContextValue if wrapped with position context, null otherwise\n */\nexport function useButtonGroupItemContext(): ButtonGroupItemContextValue | null {\n return useContext(ButtonGroupItemContext);\n}\n\n// =============================================================================\n// Exports\n// =============================================================================\n\nexport { ButtonGroupContext, ButtonGroupItemContext };\n","import { cva } from 'class-variance-authority';\n\n/**\n * ButtonGroup CVA Variants\n *\n * Defines Class Variance Authority (CVA) variants for:\n * - ButtonGroup container (orientation-based layout)\n * - ButtonGroupItem (position-based border-radius)\n * - ButtonGroupSeparator (orientation-based styling)\n *\n * @see plan.md Phase 1: Design & Contracts - CVA Variants\n * @see constitution.md Principle V (Component Quality Standards)\n */\n\n// =============================================================================\n// Container Variants\n// =============================================================================\n\n/**\n * ButtonGroup container variants\n * Controls the layout direction based on orientation\n * Uses gap-0 to ensure buttons are connected (share borders)\n */\nexport const buttonGroupVariants = cva('inline-flex items-center gap-0', {\n variants: {\n orientation: {\n horizontal: 'flex-row',\n vertical: 'flex-col w-full',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n\n// =============================================================================\n// Item Position Variants\n// =============================================================================\n\n/**\n * ButtonGroupItem position variants\n * Applied to Button's visual layer (Layer 2) for position-aware border-radius\n *\n * Compound variants handle both orientation and position combinations:\n * - Horizontal: left/right borders and radii\n * - Vertical: top/bottom borders and radii\n */\nexport const buttonGroupItemVariants = cva('', {\n variants: {\n orientation: {\n // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)\n horizontal: 'min-w-[44px]',\n // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,\n // eliminating gaps between stacked buttons in vertical orientation\n vertical: 'flex min-h-[44px]',\n },\n position: {\n first: '',\n middle: '',\n last: '',\n only: '', // Single button - no modifications needed\n },\n },\n compoundVariants: [\n // ==========================================================================\n // Horizontal Orientation\n // ==========================================================================\n {\n orientation: 'horizontal',\n position: 'first',\n className: 'rounded-r-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'middle',\n className: 'rounded-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'last',\n className: 'rounded-l-none',\n },\n // ==========================================================================\n // Vertical Orientation\n // Note: w-full is handled by Button's effectiveFullWidth for both layers\n // ==========================================================================\n {\n orientation: 'vertical',\n position: 'first',\n className: 'rounded-b-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'middle',\n className: 'rounded-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'last',\n className: 'rounded-t-none',\n },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n position: 'only',\n },\n});\n\n// =============================================================================\n// Separator Variants\n// =============================================================================\n\n/**\n * ButtonGroupSeparator variants\n * Orientation-aware visual divider between button groups\n */\nexport const buttonGroupSeparatorVariants = cva('bg-[var(--border)]', {\n variants: {\n orientation: {\n horizontal: 'w-px h-6 mx-1',\n vertical: 'h-px w-full my-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n","\"use client\";\n\n/**\n * Button Component - 3-Layer Architecture\n * Accessible button with React Aria primitives and CVA styling\n *\n * Architecture:\n * - Layer 1: Touch Target (44x44px WCAG AAA compliant, transparent)\n * - Layer 2: Visual Button (configurable size, colors, borders)\n * - Layer 3: Content & Effects (text, icons, ripple, loading spinner)\n *\n * @see 3layer-plan.md for architecture details\n * @see spec.md FR-029 to FR-037 (Button Component Requirements)\n * @see spec.md FR-009 (WCAG 2.2 AAA - 7:1 contrast ratio)\n * @see spec.md FR-014 (44x44px minimum touch targets)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\nimport { forwardRef, memo, useId } from 'react';\nimport {\n Button as AriaButton,\n type ButtonProps as AriaButtonProps,\n} from 'react-aria-components';\nimport { Loader2, Zap } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport type { ButtonProps } from './Button.types';\nimport { buttonOuterVariants, buttonVisualVariants, buttonVariants } from './Button.styles';\nimport { PRESSED_STYLES, HOVER_STYLES, HIGH_CONTRAST_HOVER, HIGH_CONTRAST_PRESSED } from '../../styles/interaction-states';\nimport {\n useButtonGroupContext,\n useButtonGroupItemContext,\n} from '../ButtonGroup/ButtonGroupContext';\nimport { buttonGroupItemVariants } from '../ButtonGroup/ButtonGroup.variants';\n\n/**\n * Button Component - 3-Layer Architecture\n * Fully accessible button with React Aria and themed styling\n *\n * Layer 1: Touch Target (AriaButton) - 44x44px WCAG AAA compliant\n * Layer 2: Visual Button (span) - configurable appearance\n * Layer 3: Content (children) - text, icons, effects\n */\nconst Button = memo(forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n buttonVisualClassName,\n variant,\n size,\n visualSize,\n fullWidth,\n loading = false,\n loadingText = \"Loading...\",\n shortcut,\n children,\n isDisabled,\n paywall = false,\n paywallRedirect,\n paywallDescription,\n onPress,\n ...props\n },\n ref\n ) => {\n const paywallDescriptionId = useId();\n\n // ==========================================================================\n // ButtonGroup Context Integration\n // ==========================================================================\n\n // Consume group-level context (variant, size, isDisabled, orientation)\n const groupContext = useButtonGroupContext();\n\n // Consume item-level context (position for border-radius styling)\n const itemContext = useButtonGroupItemContext();\n\n // Merge context values with props (props take precedence)\n const effectiveVariant = variant ?? groupContext?.variant ?? 'default';\n const effectiveSize = size ?? groupContext?.size;\n const effectiveIsDisabled = isDisabled ?? groupContext?.isDisabled ?? false;\n\n // In vertical groups, buttons should be full width automatically\n const isInVerticalGroup = groupContext?.orientation === 'vertical';\n const effectiveFullWidth = fullWidth || isInVerticalGroup;\n\n // Position styling for ButtonGroup (only applied when in a group)\n const positionClassName = itemContext\n ? buttonGroupItemVariants({\n orientation: groupContext?.orientation ?? 'horizontal',\n position: itemContext.position,\n })\n : '';\n\n // Default visualSize to size for backward compatibility\n const effectiveVisualSize = visualSize ?? effectiveSize ?? 'default';\n\n // AAA Accessibility: Warn in dev/test if icon/dot variant lacks accessible name\n if (process.env.NODE_ENV !== 'production') {\n if (\n (effectiveVisualSize === 'dot' || effectiveVisualSize === 'icon') &&\n !props['aria-label'] &&\n !children\n ) {\n console.warn(\n '[Button] visualSize=\"dot\" or \"icon\" requires aria-label when no visible text is provided (WCAG 1.1.1)'\n );\n }\n }\n\n /**\n * Handle button press - intercepts action when paywalled\n * If paywalled with redirect URL, opens in new tab\n * Otherwise, calls the normal onPress handler\n */\n const handlePress = (e: Parameters<NonNullable<AriaButtonProps['onPress']>>[0]): void => {\n if (paywall) {\n if (paywallRedirect) {\n window.open(paywallRedirect, '_blank', 'noopener,noreferrer');\n }\n // Don't call onPress when paywalled\n return;\n }\n onPress?.(e);\n };\n\n // Only set isDisabled when we have a reason to disable\n // Otherwise, let slot system control disabled state (e.g., in NumberField)\n const computedIsDisabled = effectiveIsDisabled || loading || undefined;\n\n return (\n <AriaButton\n ref={ref}\n isDisabled={computedIsDisabled}\n aria-disabled={paywall ? true : undefined}\n aria-describedby={paywall ? paywallDescriptionId : undefined}\n onPress={handlePress}\n className={cn(buttonOuterVariants({ fullWidth: effectiveFullWidth, inVerticalGroup: isInVerticalGroup }), className)}\n {...props}\n >\n {(renderProps) => (\n /* Layer 2: Visual Button */\n <span\n className={cn(\n buttonVisualVariants({\n variant: effectiveVariant,\n visualSize: effectiveVisualSize,\n paywall,\n fullWidth: effectiveFullWidth,\n }),\n // Position styling from ButtonGroup context (border-radius adjustments)\n positionClassName,\n buttonVisualClassName,\n // Layer 2 interaction styles (no focus - focus ring is on Layer 1)\n PRESSED_STYLES,\n HOVER_STYLES,\n HIGH_CONTRAST_HOVER,\n HIGH_CONTRAST_PRESSED\n )}\n data-pressed={renderProps.isPressed || undefined}\n >\n {/* Layer 3: Content & Effects */}\n\n {/* FR-033: Loading spinner with screen reader announcement */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {loading && (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" aria-hidden=\"true\" />\n <span className=\"sr-only\" aria-live=\"polite\">\n {loadingText}\n </span>\n </>\n )}\n\n {/* Hide children during loading */}\n {!loading && children}\n\n {/* Paywall: Lightning bolt icon */}\n {paywall && (\n <Zap\n data-testid=\"zap-icon\"\n aria-hidden=\"true\"\n className=\"ml-1\"\n />\n )}\n\n {/* Paywall: Screen reader description */}\n {paywall && (\n <span id={paywallDescriptionId} className=\"sr-only\">\n Premium feature: {paywallDescription || \"Upgrade required to access this feature\"}\n </span>\n )}\n\n {/* FR-034: Keyboard shortcut display on focus */}\n {renderProps.isFocusVisible && shortcut && (\n <kbd className=\"ml-auto hidden text-xs opacity-60 lg:inline\">\n {shortcut}\n </kbd>\n )}\n\n </span>\n )}\n </AriaButton>\n );\n }\n));\n\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants, buttonOuterVariants, buttonVisualVariants };\nexport type { ButtonProps } from './Button.types';\n","'use client';\n\nimport { useEffect, useState, type RefObject } from 'react';\n\n/**\n * Track whether a referenced element is narrower than `breakpoint` (px), via a\n * `ResizeObserver`. This is a **container query**, not a viewport query — a table\n * inside a narrow panel reflows to cards even on a wide screen.\n *\n * Uses `offsetWidth` (ignores CSS transforms, e.g. zoom/preview scaling).\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * const narrow = useContainerNarrow(ref, 680);\n * return <div ref={ref}>{narrow ? <TableCardList .../> : <Table .../>}</div>;\n */\nexport function useContainerNarrow(\n ref: RefObject<HTMLElement | null>,\n breakpoint: number\n): boolean {\n const [narrow, setNarrow] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const measure = (): void => setNarrow(el.offsetWidth < breakpoint);\n measure(); // initial — covers an already-narrow mount\n\n let observer: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(measure);\n observer.observe(el);\n }\n window.addEventListener('resize', measure);\n return () => {\n window.removeEventListener('resize', measure);\n observer?.disconnect();\n };\n }, [ref, breakpoint]);\n\n return narrow;\n}\n","'use client';\n\nimport { useState, useEffect } from 'react';\n\nconst QUERY = '(prefers-reduced-motion: reduce)';\n\nfunction getInitialState(): boolean {\n if (typeof window === 'undefined') return false;\n return window.matchMedia(QUERY).matches;\n}\n\n/**\n * Detects whether the user prefers reduced motion.\n *\n * - SSR-safe (returns `false` on the server)\n * - Reacts to changes in the OS preference\n * - Cleans up the listener on unmount\n */\nexport function useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(getInitialState);\n\n useEffect(() => {\n const mql = window.matchMedia(QUERY);\n setPrefersReducedMotion(mql.matches);\n\n const handler = (event: MediaQueryListEvent): void => {\n setPrefersReducedMotion(event.matches);\n };\n\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n\n return prefersReducedMotion;\n}\n","'use client';\n\nimport { createContext, useContext } from 'react';\nimport type { ReactNode } from 'react';\nimport type {\n TimelineHeadingLevel,\n TimelineMarker,\n TimelineOrientation,\n} from './Timeline.types';\n\n/**\n * Stable configuration shared with every `Timeline.Item`. Memoised at the root and\n * changes ~never, so item content (notably date formatting) is not recomputed on\n * unrelated root re-renders.\n */\nexport interface TimelineConfigContextValue {\n /** Effective orientation (already resolved for the mobile collapse). */\n orientation: TimelineOrientation;\n marker: TimelineMarker;\n locale: string | undefined;\n /** Shared `Intl.DateTimeFormat` instance — built once, reused by all items. */\n dateFormatter: Intl.DateTimeFormat;\n formatDate: ((date: Date) => ReactNode) | undefined;\n dateFormatOptions: Intl.DateTimeFormatOptions | undefined;\n titleHeadingLevel: TimelineHeadingLevel;\n /** Whether the user prefers reduced motion (gates smooth scrolling). */\n reducedMotion: boolean;\n /** Items register their focus target node here for `scrollToItem`/`focusItem`. */\n registerItem: (id: string, node: HTMLElement | null) => void;\n}\n\nexport const TimelineConfigContext = createContext<TimelineConfigContextValue | null>(null);\n\nexport function useTimelineContext(): TimelineConfigContextValue {\n const ctx = useContext(TimelineConfigContext);\n if (!ctx) {\n throw new Error('Timeline.Item must be used within <Timeline>');\n }\n return ctx;\n}\n","import { cva } from 'class-variance-authority';\n\n/**\n * The ordered list. Vertical stacks top-to-bottom; horizontal flows left-to-right\n * and is keyboard-scrollable when it overflows (the component adds `tabIndex`).\n */\nexport const timelineVariants = cva('m-0 flex list-none p-0', {\n variants: {\n orientation: {\n vertical: 'flex-col',\n horizontal: 'flex-row items-stretch overflow-x-auto',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\n/**\n * A single event (`<li>`). Marker rail + content.\n *\n * `content-visibility: auto` keeps every node in the DOM and the a11y tree (Ctrl+F and\n * screen-reader traversal still work — AAA-safe) while skipping layout/paint for\n * off-screen items. `contain-intrinsic-size` is orientation-aware (height placeholder\n * when vertical, width placeholder when horizontal).\n */\nexport const timelineItemVariants = cva('relative [content-visibility:auto]', {\n variants: {\n orientation: {\n vertical:\n 'grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 [contain-intrinsic-size:auto_88px]',\n horizontal: 'flex min-w-[12rem] flex-1 flex-col [contain-intrinsic-size:14rem_auto]',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\n/**\n * The marker node for the `'dot'` and `'icon'` styles (the `'basic'` line style has no\n * marker). Dots are a muted node on the rail; the icon badge is primary-filled.\n */\nexport const timelineMarkerVariants = cva(\n 'relative z-10 flex shrink-0 items-center justify-center',\n {\n variants: {\n marker: {\n dot: 'h-3 w-3 rounded-full bg-[var(--input-border)]',\n icon: 'h-8 w-8 rounded-full bg-[var(--primary-action)] text-[var(--primary-action-foreground)] [&_svg]:h-4 [&_svg]:w-4',\n },\n },\n defaultVariants: {\n marker: 'dot',\n },\n }\n);\n\n/**\n * The connector between dot/icon markers — a muted line that `flex-1` fills down to\n * (vertical) or across to (horizontal) the next marker. (The `'basic'` style draws its\n * own full-length primary rail instead; see TimelineItem.)\n */\nexport const timelineConnectorVariants = cva(\n 'shrink-0 flex-1 rounded-full bg-[var(--border)]',\n {\n variants: {\n orientation: {\n vertical: 'mt-1 w-0.5',\n horizontal: 'ml-2 h-0.5',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n }\n);\n\n/**\n * The content column (meta / title / description / custom body). When the item is\n * interactive the inner Link/Button reuses these paddings.\n */\nexport const timelineContentVariants = cva('min-w-0', {\n variants: {\n orientation: {\n // Trailing space keeps an item's text off the next item (below / to the right).\n vertical: 'pb-6',\n horizontal: 'pt-3 pr-6',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n","'use client';\n\n/**\n * Timeline.Item — a single event (`<li>`): marker rail + content.\n *\n * Body precedence: `children` is the body and supersedes `title`/`description`\n * (dev-only warning if both are passed). The meta region (`date`/`label`) and the\n * marker are always owned here so date/marker presentation stays consistent even for\n * fully-custom bodies (e.g. an activity-log item composed via `icon` + `children`).\n *\n * Accessibility:\n * - The marker rail (decorative dot/icon + connector) is `aria-hidden`; meaning comes\n * from the text. Interactive items wrap the content in a real `<a>`/`<button>` with a\n * visible focus ring; static items are focusable only programmatically (`tabIndex=-1`)\n * so `focusItem`/`scrollToItem` can target them.\n * - The whole-card link/button must not contain nested interactive children — if an\n * item needs secondary actions, make only the title a link instead.\n */\n\nimport { memo, useCallback, useMemo, type ReactElement, type ReactNode } from 'react';\nimport { Link, Button as AriaButton } from 'react-aria-components';\nimport { cn } from '../../utils/cn';\nimport { useTimelineContext } from './TimelineContext';\nimport {\n timelineConnectorVariants,\n timelineContentVariants,\n timelineItemVariants,\n timelineMarkerVariants,\n} from './Timeline.styles';\nimport type { TimelineItemProps } from './Timeline.types';\n\n/** Primary rail/stub for the 'basic' line style. */\nconst RAIL_PRIMARY = 'bg-[var(--primary-action)]';\n\nconst META_CLASS = 'block text-xs text-[var(--muted-foreground)]';\nconst TITLE_CLASS = 'mt-0.5 text-base font-bold text-[var(--content-foreground)]';\nconst DESC_CLASS = 'mt-1 text-sm text-[var(--muted-foreground)]';\n\n// Interactive wrapper: keeps the content at its natural position (so text stays aligned\n// with the marker) and carries the keyboard focus ring.\nconst INTERACTIVE_WRAP =\n 'relative isolate block rounded-md text-[var(--content-foreground)] no-underline ' +\n 'cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] ' +\n 'focus-visible:ring-offset-2 [scroll-margin:1rem]';\n\n// Hover/focus background drawn as an absolute layer that bleeds 8px past the content\n// (`-inset-2`) — gives the highlight padding around the text WITHOUT moving the text and\n// without affecting item spacing. Behind the content via `isolate` + `-z-10` on the wrapper.\nconst HOVER_LAYER =\n 'pointer-events-none absolute -inset-2 -z-10 rounded-md transition-colors ' +\n 'group-hover/tl-item:bg-[var(--muted)] group-focus-within/tl-item:bg-[var(--muted)]';\n\n// Marker emphasis when the item is actionable and hovered/focused.\nconst DOT_HIGHLIGHT =\n 'transition-colors group-hover/tl-item:bg-[var(--primary-action)] ' +\n 'group-focus-within/tl-item:bg-[var(--primary-action)]';\nconst ICON_HIGHLIGHT =\n 'transition-transform group-hover/tl-item:scale-110 group-focus-within/tl-item:scale-110';\n\nfunction TimelineItemImpl({\n id,\n date,\n label,\n dateFormatOptions,\n title,\n description,\n children,\n icon,\n href,\n target,\n rel,\n onPress,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'data-testid': testId,\n}: TimelineItemProps): ReactElement {\n const {\n orientation,\n marker,\n locale,\n dateFormatter,\n formatDate,\n titleHeadingLevel,\n registerItem,\n } = useTimelineContext();\n\n if (\n process.env.NODE_ENV !== 'production' &&\n children != null &&\n (title != null || description != null)\n ) {\n console.warn(\n 'Timeline.Item: `children` supersedes `title`/`description` — pass one or the other.'\n );\n }\n\n // Per-item formatter only when the item overrides options; otherwise reuse the shared one.\n const itemFormatter = useMemo(\n () => (dateFormatOptions ? new Intl.DateTimeFormat(locale, dateFormatOptions) : dateFormatter),\n [dateFormatOptions, locale, dateFormatter]\n );\n\n const dateObj = useMemo(() => (date != null ? new Date(date) : null), [date]);\n const isValidDate = dateObj != null && !Number.isNaN(dateObj.getTime());\n\n // Register the focus target (interactive control, or the <li> itself when static).\n const registerRef = useCallback(\n (node: HTMLElement | null) => {\n if (id !== undefined) registerItem(id, node);\n },\n [id, registerItem]\n );\n\n const meta: ReactNode = isValidDate ? (\n <time dateTime={dateObj.toISOString()} className={META_CLASS}>\n {formatDate ? formatDate(dateObj) : itemFormatter.format(dateObj)}\n </time>\n ) : label != null ? (\n <span className={META_CLASS}>{label}</span>\n ) : null;\n\n const interactive = href != null || onPress != null;\n\n // Interactive items render the title/description as phrasing `block` spans so they are\n // valid inside an <a>/<button> (block elements can't nest in a <button>) and so the\n // title isn't a heading-inside-a-link. Static items use real heading/paragraph tags.\n const Heading = titleHeadingLevel === 'p' ? 'p' : titleHeadingLevel;\n const titleNode =\n title == null ? null : interactive ? (\n <span className={cn('block', TITLE_CLASS)}>{title}</span>\n ) : (\n <Heading className={TITLE_CLASS}>{title}</Heading>\n );\n const descNode =\n description == null ? null : interactive ? (\n <span className={cn('block', DESC_CLASS)}>{description}</span>\n ) : (\n <p className={DESC_CLASS}>{description}</p>\n );\n const body: ReactNode =\n children != null ? (\n children\n ) : (\n <>\n {titleNode}\n {descNode}\n </>\n );\n\n const content = (\n <>\n {meta}\n {body}\n </>\n );\n\n // The 'basic' style is a continuous primary rail running the full length, with a short\n // primary stub branching into each item at the meta row. The dot/icon styles place a\n // marker node with a muted connector filling to the next marker.\n let rail: ReactNode;\n if (marker === 'basic') {\n rail =\n orientation === 'vertical' ? (\n <div className=\"relative w-2 self-stretch\" aria-hidden=\"true\">\n <span\n data-timeline-connector\n className={cn('absolute inset-y-0 left-0 w-0.5', RAIL_PRIMARY)}\n />\n <span className={cn('absolute left-0 top-2 h-0.5 w-3', RAIL_PRIMARY)} />\n </div>\n ) : (\n <div className=\"relative h-2 w-full\" aria-hidden=\"true\">\n <span\n data-timeline-connector\n className={cn('absolute inset-x-0 top-0 h-0.5', RAIL_PRIMARY)}\n />\n {/* Down-stub at the item's start edge, lining up with the content below. */}\n <span className={cn('absolute left-0 top-0 h-3 w-0.5', RAIL_PRIMARY)} />\n </div>\n );\n } else {\n // Vertical: align the dot with the top of the date text (12px dot centred on the 16px\n // meta line) rather than the item's edge — corrects the Figma source, which is wrong\n // here. Horizontal keeps the dot centred on the connector line (which runs through it),\n // where its left edge already lines up with the date text below.\n const dotAlign = marker === 'dot' && orientation === 'vertical' ? 'mt-0.5' : '';\n const markerHighlight = !interactive ? '' : marker === 'dot' ? DOT_HIGHLIGHT : ICON_HIGHLIGHT;\n const markerNode = (\n <span className={cn(timelineMarkerVariants({ marker }), dotAlign, markerHighlight)}>\n {marker === 'icon' ? icon : null}\n </span>\n );\n const connector = (\n <span data-timeline-connector className={timelineConnectorVariants({ orientation })} />\n );\n rail =\n orientation === 'vertical' ? (\n <div className=\"flex flex-col items-center self-stretch\" aria-hidden=\"true\">\n {markerNode}\n {connector}\n </div>\n ) : (\n <div className=\"flex w-full items-center\" aria-hidden=\"true\">\n {markerNode}\n {connector}\n </div>\n );\n }\n\n const contentClass = timelineContentVariants({ orientation });\n\n // Interactive items wrap the content in a Link/Button; the hover/focus highlight is an\n // absolute layer behind the content so the text never shifts.\n const interactiveBody = (\n <>\n <span aria-hidden=\"true\" className={HOVER_LAYER} />\n {content}\n </>\n );\n\n // Spacing (item gap) lives on the outer cell; the interactive Link/Button hugs only the\n // text so the hover layer wraps the text, not the gap below it.\n let contentRegion: ReactNode;\n if (href != null) {\n contentRegion = (\n <div className={contentClass}>\n <Link\n ref={registerRef as (node: HTMLAnchorElement | null) => void}\n href={href}\n target={target}\n rel={rel}\n className={INTERACTIVE_WRAP}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n {interactiveBody}\n </Link>\n </div>\n );\n } else if (onPress != null) {\n contentRegion = (\n <div className={contentClass}>\n <AriaButton\n ref={registerRef as (node: HTMLButtonElement | null) => void}\n onPress={onPress}\n className={cn(INTERACTIVE_WRAP, 'w-full text-left')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n {interactiveBody}\n </AriaButton>\n </div>\n );\n } else {\n contentRegion = <div className={contentClass}>{content}</div>;\n }\n\n return (\n <li\n ref={interactive ? undefined : registerRef}\n tabIndex={interactive ? undefined : -1}\n className={cn(\n timelineItemVariants({ orientation }),\n // Hide the trailing dot/icon connector on the last item. The 'basic' rail is\n // intentionally continuous to the end, so it is never hidden.\n marker !== 'basic' && '[&:last-child_[data-timeline-connector]]:hidden',\n // Vertical basic rail: the FIRST item begins at the stub (not the item's top\n // edge) so the timeline opens with a clean 90° corner, not a stalk above the\n // stub. Horizontal's stub already sits at the item's start edge, so its rail\n // (inset-x-0) starts there naturally — no inset needed.\n marker === 'basic' &&\n orientation === 'vertical' &&\n '[&:first-child_[data-timeline-connector]]:top-2',\n // Named group so the marker + hover layer react to hovering/focusing the item.\n interactive && 'group/tl-item rounded-md outline-none',\n className\n )}\n data-testid={testId}\n >\n {rail}\n {contentRegion}\n </li>\n );\n}\n\nexport const TimelineItem = memo(TimelineItemImpl);\nTimelineItem.displayName = 'Timeline.Item';\n","'use client';\n\n/**\n * Timeline — compound root.\n *\n * An accessible, chronological feed of events rendered as a semantic `<ol>`. WCAG 2.2 AAA.\n *\n * Design notes:\n * - Renders EVERY child it is given — it never caps/slices present data (hidden content\n * would be invisible to find-in-page and screen readers). Large/server-fed data uses\n * `onLoadMore`/`hasMore` to append more `<Timeline.Item>` children; performance for\n * long, fully-rendered lists comes from `content-visibility: auto` on each item.\n * - Config (orientation, marker, formatter, …) lives in a memoised context.\n * - Horizontal timelines auto-collapse to vertical on narrow containers via\n * `useContainerNarrow`. There is no \"active\"/selected item concept; programmatic\n * navigation is via the imperative handle (`scrollToItem`/`focusItem`).\n *\n * @see Wizard (role=\"status\" live region, configurable heading level)\n * @see Tabs (compound children + context)\n */\n\nimport {\n Children,\n forwardRef,\n isValidElement,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n} from 'react';\nimport { Button } from '../Button';\nimport { useContainerNarrow } from '../../hooks/useContainerNarrow';\nimport { useReducedMotion } from '../../hooks/useReducedMotion';\nimport { cn } from '../../utils/cn';\nimport {\n TimelineConfigContext,\n type TimelineConfigContextValue,\n} from './TimelineContext';\nimport { TimelineItem } from './TimelineItem';\nimport { timelineVariants } from './Timeline.styles';\nimport type { TimelineHandle, TimelineProps } from './Timeline.types';\n\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long' };\n\nconst TimelineRoot = forwardRef<TimelineHandle, TimelineProps>(function TimelineRoot(\n {\n children,\n orientation = 'vertical',\n marker = 'dot',\n locale,\n dateFormatOptions,\n formatDate,\n titleHeadingLevel = 'p',\n collapseBelow = 640,\n onLoadMore,\n hasMore = false,\n isLoadingMore = false,\n loadMoreLabel = 'Show more',\n emptyState,\n landmarkLabel,\n className,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'data-testid': testId = 'timeline',\n },\n ref\n): ReactElement {\n const rootRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLOListElement>(null);\n const itemNodes = useRef<Map<string, HTMLElement>>(new Map());\n const reducedMotion = useReducedMotion();\n\n // Container-query collapse: a horizontal timeline reflows to vertical when narrow.\n // `collapseBelow === false` disables it (breakpoint 0 never matches).\n const narrow = useContainerNarrow(rootRef, collapseBelow === false ? 0 : collapseBelow);\n const effectiveOrientation =\n orientation === 'horizontal' && narrow ? 'vertical' : orientation;\n\n const scrollToNode = useCallback(\n (node: HTMLElement | undefined) => {\n node?.scrollIntoView({\n behavior: reducedMotion ? 'auto' : 'smooth',\n block: 'nearest',\n inline: 'nearest',\n });\n },\n [reducedMotion]\n );\n\n const registerItem = useCallback((itemId: string, node: HTMLElement | null) => {\n if (node) itemNodes.current.set(itemId, node);\n else itemNodes.current.delete(itemId);\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToItem: (itemId: string) => scrollToNode(itemNodes.current.get(itemId)),\n focusItem: (itemId: string) => itemNodes.current.get(itemId)?.focus(),\n }),\n [scrollToNode]\n );\n\n const dateFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, dateFormatOptions ?? DEFAULT_DATE_OPTIONS),\n [locale, dateFormatOptions]\n );\n\n const configValue = useMemo<TimelineConfigContextValue>(\n () => ({\n orientation: effectiveOrientation,\n marker,\n locale,\n dateFormatter,\n formatDate,\n dateFormatOptions,\n titleHeadingLevel,\n reducedMotion,\n registerItem,\n }),\n [\n effectiveOrientation,\n marker,\n locale,\n dateFormatter,\n formatDate,\n dateFormatOptions,\n titleHeadingLevel,\n reducedMotion,\n registerItem,\n ]\n );\n\n const itemCount = useMemo(\n () => Children.toArray(children).filter(isValidElement).length,\n [children]\n );\n const isEmpty = itemCount === 0;\n\n // \"Show more\" focus contract: focus stays on the button across loads; when the final\n // load removes the button (`hasMore` → false), move focus to the first new item so it\n // never drops to <body>. `aria-live` announcement fires only on a user-initiated load.\n const pendingLoadRef = useRef<number | null>(null);\n const [liveMessage, setLiveMessage] = useState('');\n\n const handleLoadMore = useCallback(() => {\n pendingLoadRef.current = itemCount;\n void onLoadMore?.();\n }, [itemCount, onLoadMore]);\n\n useEffect(() => {\n const pending = pendingLoadRef.current;\n if (pending == null || itemCount <= pending) return;\n if (!hasMore) {\n const firstNew = listRef.current?.children[pending] as HTMLElement | undefined;\n const focusTarget = firstNew?.querySelector<HTMLElement>('a, button') ?? firstNew;\n focusTarget?.focus();\n }\n setLiveMessage(`Showing ${itemCount} items`);\n pendingLoadRef.current = null;\n }, [itemCount, hasMore]);\n\n if (isEmpty) {\n return (\n <div ref={rootRef} id={id} className={className} data-testid={testId}>\n {emptyState ?? null}\n </div>\n );\n }\n\n const list = (\n <ol\n ref={listRef}\n className={timelineVariants({ orientation: effectiveOrientation })}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n // Keep an overflowing horizontal timeline keyboard-scrollable (WCAG 2.1.1).\n tabIndex={effectiveOrientation === 'horizontal' ? 0 : undefined}\n >\n {children}\n </ol>\n );\n\n return (\n <TimelineConfigContext.Provider value={configValue}>\n <div ref={rootRef} id={id} className={cn('w-full', className)} data-testid={testId}>\n {landmarkLabel != null ? <nav aria-label={landmarkLabel}>{list}</nav> : list}\n\n {hasMore && (\n <div className=\"mt-2 flex justify-center\">\n <Button\n variant=\"outline\"\n onPress={handleLoadMore}\n loading={isLoadingMore}\n loadingText=\"Loading…\"\n data-testid={`${testId}-load-more`}\n >\n {loadMoreLabel}\n </Button>\n </div>\n )}\n\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {liveMessage}\n </div>\n </div>\n </TimelineConfigContext.Provider>\n );\n});\n\nTimelineRoot.displayName = 'Timeline';\n\n/**\n * Timeline compound component.\n *\n * @example\n * ```tsx\n * <Timeline aria-label=\"Application history\" marker=\"dot\">\n * <Timeline.Item date=\"2025-04-02\" title=\"Applied\" description=\"Application received.\" />\n * <Timeline.Item date=\"2025-04-10\" title=\"Interview\" status=\"active\" />\n * </Timeline>\n * ```\n */\nexport const Timeline = Object.assign(TimelineRoot, {\n Item: TimelineItem,\n});\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode } from 'react';\n\n/**\n * Timeline orientation.\n *\n * - 'vertical': events stack top-to-bottom with a vertical connector rail (default).\n * - 'horizontal': events flow left-to-right with a horizontal connector. Auto-collapses\n * to vertical on narrow containers (see `collapseBelow`).\n */\nexport const TimelineOrientationSchema = z.enum(['vertical', 'horizontal']);\nexport type TimelineOrientation = z.infer<typeof TimelineOrientationSchema>;\n\n/**\n * Marker style for each event.\n *\n * - 'dot': small circular node on the connector (default).\n * - 'basic': no node — just the connector line; active items colour the line segment.\n * - 'icon': circular badge holding an icon or avatar.\n */\nexport const TimelineMarkerSchema = z.enum(['dot', 'basic', 'icon']);\nexport type TimelineMarker = z.infer<typeof TimelineMarkerSchema>;\n\n/**\n * Heading level for item titles. Mirrors Wizard's `stepHeadingLevel`. Defaults to\n * `'p'` (rendered as a styled `<strong>`-like paragraph) to avoid breaking the host\n * page's heading hierarchy; opt into real headings (`h2`–`h6`) when appropriate.\n */\nexport const TimelineHeadingLevelSchema = z.enum(['h2', 'h3', 'h4', 'h5', 'h6', 'p']);\nexport type TimelineHeadingLevel = z.infer<typeof TimelineHeadingLevelSchema>;\n\n/** A value accepted by `new Date(...)`. */\nexport type TimelineDateInput = Date | string | number;\n\n/**\n * Imperative handle exposed via `ref` for in-timeline navigation.\n */\nexport interface TimelineHandle {\n /** Scroll the item with this `id` into view (respects `prefers-reduced-motion`). */\n scrollToItem: (id: string) => void;\n /** Move focus to the item with this `id`. */\n focusItem: (id: string) => void;\n}\n\n/**\n * Timeline root props.\n *\n * Data enters via `<Timeline.Item>` children (compound pattern). Timeline renders\n * every child it is given — it never caps/slices present data (that would hide\n * content from find-in-page and screen readers). For large or server-fed data use\n * `onLoadMore`/`hasMore` to append more items.\n */\nexport const TimelinePropsSchema = BaseComponentPropsSchema.extend({\n /** `<Timeline.Item>` children. */\n children: z.custom<ReactNode>().optional(),\n\n /** Layout direction. Default `'vertical'`. */\n orientation: TimelineOrientationSchema.optional().default('vertical'),\n\n /** Marker style. Default `'dot'`. */\n marker: TimelineMarkerSchema.optional().default('dot'),\n\n /** BCP-47 locale for date formatting. Defaults to the runtime locale. */\n locale: z.string().optional(),\n\n /**\n * `Intl.DateTimeFormatOptions` controlling date granularity (hour/day/month/year).\n * Default `{ year: 'numeric', month: 'long' }` → e.g. \"April 2025\".\n */\n dateFormatOptions: z.custom<Intl.DateTimeFormatOptions>().optional(),\n\n /** Full override for rendering an item's date. Wins over `dateFormatOptions`. */\n formatDate: z.custom<(date: Date) => ReactNode>().optional(),\n\n /** Heading level for item titles. Default `'p'`. */\n titleHeadingLevel: TimelineHeadingLevelSchema.optional().default('p'),\n\n /**\n * Container width (px) below which a horizontal timeline collapses to vertical.\n * Default `640`. Pass `false` to disable collapsing.\n */\n collapseBelow: z.union([z.number(), z.literal(false)]).optional().default(640),\n\n /** Called when the \"Show more\" button is pressed (server/consumer-fed pagination). */\n onLoadMore: z.custom<() => void | Promise<void>>().optional(),\n\n /** Whether more items can be loaded (renders the \"Show more\" affordance). */\n hasMore: z.boolean().optional().default(false),\n\n /** Whether a load is in progress (puts the \"Show more\" button in a pending state). */\n isLoadingMore: z.boolean().optional().default(false),\n\n /** Label for the \"Show more\" button. Default `'Show more'`. */\n loadMoreLabel: z.string().optional(),\n\n /** Rendered instead of the list when there are no items. */\n emptyState: z.custom<ReactNode>().optional(),\n\n /**\n * When set, wraps the list in a `<nav>` landmark with this accessible label.\n * Opt-in only — a content timeline is not a navigation landmark by default.\n */\n landmarkLabel: z.string().optional(),\n});\n\nexport interface TimelineProps {\n className?: string;\n children?: ReactNode;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'data-testid'?: string;\n orientation?: TimelineOrientation;\n marker?: TimelineMarker;\n locale?: string;\n dateFormatOptions?: Intl.DateTimeFormatOptions;\n formatDate?: (date: Date) => ReactNode;\n titleHeadingLevel?: TimelineHeadingLevel;\n collapseBelow?: number | false;\n onLoadMore?: () => void | Promise<void>;\n hasMore?: boolean;\n isLoadingMore?: boolean;\n loadMoreLabel?: string;\n emptyState?: ReactNode;\n landmarkLabel?: string;\n}\n\n/**\n * Timeline.Item props.\n *\n * Body precedence: if `children` is provided it is the body and supersedes\n * `title`/`description` (a dev-only warning fires if both are passed). The meta\n * region (`date`/`label`) and the marker are always owned by Timeline.Item. There is\n * no \"active\"/selected concept — every item is presented identically per the variant.\n */\nexport const TimelineItemPropsSchema = BaseComponentPropsSchema.extend({\n /** Stable id — required for `activeId`, `scrollToItem`, and `focusItem`. */\n id: z.string().optional(),\n\n /** Event date. Anything `new Date(...)` accepts. Rendered in `<time dateTime>`. */\n date: z.custom<Date | string | number>().optional(),\n\n /** Non-date meta text, used instead of `date` (e.g. \"Step 1\"). */\n label: z.custom<ReactNode>().optional(),\n\n /** Per-item override of the timeline's `dateFormatOptions`. */\n dateFormatOptions: z.custom<Intl.DateTimeFormatOptions>().optional(),\n\n /** Event title (the common case). Ignored when `children` is provided. */\n title: z.custom<ReactNode>().optional(),\n\n /** Event description (the common case). Ignored when `children` is provided. */\n description: z.custom<ReactNode>().optional(),\n\n /** Custom body content. Supersedes `title`/`description`. */\n children: z.custom<ReactNode>().optional(),\n\n /** Icon or avatar node for the `'icon'` marker style. */\n icon: z.custom<ReactNode>().optional(),\n\n /** Make the whole item a link to this URL. */\n href: z.string().optional(),\n\n /** `target` attribute when `href` is set. */\n target: z.string().optional(),\n\n /** `rel` attribute when `href` is set. */\n rel: z.string().optional(),\n\n /** Make the whole item a button invoking this handler. */\n onPress: z.custom<() => void>().optional(),\n});\n\nexport interface TimelineItemProps {\n className?: string;\n children?: ReactNode;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'data-testid'?: string;\n date?: TimelineDateInput;\n label?: ReactNode;\n dateFormatOptions?: Intl.DateTimeFormatOptions;\n title?: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n href?: string;\n target?: string;\n rel?: string;\n onPress?: () => void;\n}\n"]}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Button/Button.styles.ts","../../../src/styles/interaction-states.ts","../../../src/elements/ButtonGroup/ButtonGroupContext.tsx","../../../src/elements/ButtonGroup/ButtonGroup.variants.ts","../../../src/elements/Button/Button.tsx","../../../src/hooks/useContainerNarrow.ts","../../../src/hooks/useReducedMotion.ts","../../../src/elements/Timeline/TimelineContext.tsx","../../../src/elements/Timeline/Timeline.styles.ts","../../../src/elements/Timeline/TimelineItem.tsx","../../../src/elements/Timeline/Timeline.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/Timeline/Timeline.types.ts"],"names":["cn","inputs","twMerge","clsx","buttonOuterVariants","cva","buttonVisualVariants","PRESSED_STYLES","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","ButtonGroupContext","createContext","useButtonGroupContext","useContext","ButtonGroupItemContext","useButtonGroupItemContext","buttonGroupItemVariants","Button","memo","forwardRef","className","buttonVisualClassName","variant","size","visualSize","fullWidth","loading","loadingText","shortcut","children","isDisabled","paywall","paywallRedirect","paywallDescription","onPress","props","ref","paywallDescriptionId","useId","groupContext","itemContext","effectiveVariant","effectiveSize","effectiveIsDisabled","isInVerticalGroup","effectiveFullWidth","positionClassName","effectiveVisualSize","jsx","AriaButton","e","renderProps","jsxs","Fragment","Loader2","Zap","useContainerNarrow","breakpoint","narrow","setNarrow","useState","useEffect","el","measure","observer","QUERY","getInitialState","useReducedMotion","prefersReducedMotion","setPrefersReducedMotion","mql","handler","event","TimelineConfigContext","useTimelineContext","ctx","timelineVariants","timelineItemVariants","timelineMarkerVariants","timelineConnectorVariants","timelineContentVariants","RAIL_PRIMARY","META_CLASS","TITLE_CLASS","DESC_CLASS","INTERACTIVE_WRAP","HOVER_LAYER","DOT_HIGHLIGHT","ICON_HIGHLIGHT","TimelineItemImpl","id","date","label","dateFormatOptions","title","description","icon","href","target","rel","ariaLabel","ariaLabelledBy","ariaDescribedBy","testId","orientation","marker","locale","dateFormatter","formatDate","titleHeadingLevel","registerItem","itemFormatter","useMemo","dateObj","isValidDate","registerRef","useCallback","node","meta","interactive","Heading","titleNode","descNode","content","rail","dotAlign","markerHighlight","markerNode","connector","contentClass","interactiveBody","contentRegion","Link","TimelineItem","DEFAULT_DATE_OPTIONS","TimelineRoot","collapseBelow","onLoadMore","hasMore","isLoadingMore","loadMoreLabel","emptyState","landmarkLabel","rootRef","useRef","listRef","itemNodes","reducedMotion","effectiveOrientation","scrollToNode","itemId","useImperativeHandle","configValue","itemCount","Children","isValidElement","isEmpty","pendingLoadRef","liveMessage","setLiveMessage","handleLoadMore","pending","firstNew","list","Timeline","BaseComponentPropsSchema","z","TimelineOrientationSchema","TimelineMarkerSchema","TimelineHeadingLevelSchema","TimelinePropsSchema","TimelineItemPropsSchema"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { cva } from 'class-variance-authority';\n\n/**\n * Layer 1: Transparent outer touch target (44x44px minimum)\n * Handles WCAG 2.2 AAA touch target requirement\n * Always transparent, centers the visual button inside\n * IMPORTANT: Focus ring stays on Layer 1 for AAA compliance (2.4.13)\n *\n * In vertical ButtonGroups, uses items-stretch so the visual layer (Layer 2)\n * can fill the full touch target height, eliminating gaps between buttons.\n */\nexport const buttonOuterVariants = cva(\n \"inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n inVerticalGroup: {\n true: \"items-stretch\",\n false: \"items-center\",\n },\n },\n defaultVariants: {\n fullWidth: false,\n inVerticalGroup: false,\n },\n }\n);\n\n/**\n * Layer 2: Visual button appearance (adjustable size)\n * Provides the visual appearance with configurable size\n * Can be smaller than touch target for use cases like carousel dots\n * NOTE: NO focus-visible styles here - focus ring is on Layer 1\n */\nexport const buttonVisualVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1\",\n destructive:\n \"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake\",\n outline:\n \"border border-[var(--input-border)] bg-[var(--content-background)] hover:bg-[var(--accent-background)]/50\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n link: \"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n visualSize: {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3 text-xs\",\n lg: \"h-11 rounded-md px-6 text-base\",\n icon: \"h-10 w-10\",\n dot: \"h-5 w-5 rounded-full p-0 min-h-0 min-w-0\",\n },\n paywall: {\n true: \"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n visualSize: \"default\",\n paywall: false,\n },\n }\n);\n\n/**\n * @deprecated Use buttonVisualVariants instead. This alias is kept for backward compatibility.\n */\nexport const buttonVariants = buttonVisualVariants;\n","/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","\"use client\";\n\nimport { createContext, useContext } from 'react';\nimport type {\n ButtonGroupContextValue,\n ButtonGroupItemContextValue,\n} from './ButtonGroup.types';\n\n/**\n * ButtonGroup Context System (Two-Level)\n *\n * Provides a two-level context pattern for ButtonGroup:\n *\n * 1. ButtonGroupContext (group-level):\n * - Provides: orientation, variant, size, isDisabled\n * - Consumed by: Button (for prop inheritance), Separator (for orientation)\n *\n * 2. ButtonGroupItemContext (item-level):\n * - Provides: position ('first' | 'middle' | 'last' | 'only')\n * - Consumed by: Button (for border-radius styling)\n *\n * Both contexts return null when not in a provider, allowing Button\n * to work standalone without any group context.\n *\n * @see plan.md for architecture details\n * @see ButtonGroup.tsx for Provider implementation\n */\n\n// =============================================================================\n// Group-Level Context\n// =============================================================================\n\n/**\n * Context for group-level props (orientation, variant, size, isDisabled)\n * Default value is null to indicate \"not in a group\"\n */\nconst ButtonGroupContext = createContext<ButtonGroupContextValue | null>(null);\n\nButtonGroupContext.displayName = 'ButtonGroupContext';\n\n/**\n * Hook to access group-level context\n * @returns ButtonGroupContextValue if inside a ButtonGroup, null otherwise\n */\nexport function useButtonGroupContext(): ButtonGroupContextValue | null {\n return useContext(ButtonGroupContext);\n}\n\n// =============================================================================\n// Item-Level Context\n// =============================================================================\n\n/**\n * Context for per-button position information\n * Default value is null to indicate \"not wrapped with position context\"\n */\nconst ButtonGroupItemContext =\n createContext<ButtonGroupItemContextValue | null>(null);\n\nButtonGroupItemContext.displayName = 'ButtonGroupItemContext';\n\n/**\n * Hook to access item-level context (position)\n * @returns ButtonGroupItemContextValue if wrapped with position context, null otherwise\n */\nexport function useButtonGroupItemContext(): ButtonGroupItemContextValue | null {\n return useContext(ButtonGroupItemContext);\n}\n\n// =============================================================================\n// Exports\n// =============================================================================\n\nexport { ButtonGroupContext, ButtonGroupItemContext };\n","import { cva } from 'class-variance-authority';\n\n/**\n * ButtonGroup CVA Variants\n *\n * Defines Class Variance Authority (CVA) variants for:\n * - ButtonGroup container (orientation-based layout)\n * - ButtonGroupItem (position-based border-radius)\n * - ButtonGroupSeparator (orientation-based styling)\n *\n * @see plan.md Phase 1: Design & Contracts - CVA Variants\n * @see constitution.md Principle V (Component Quality Standards)\n */\n\n// =============================================================================\n// Container Variants\n// =============================================================================\n\n/**\n * ButtonGroup container variants\n * Controls the layout direction based on orientation\n * Uses gap-0 to ensure buttons are connected (share borders)\n */\nexport const buttonGroupVariants = cva('inline-flex items-center gap-0', {\n variants: {\n orientation: {\n horizontal: 'flex-row',\n vertical: 'flex-col w-full',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n\n// =============================================================================\n// Item Position Variants\n// =============================================================================\n\n/**\n * ButtonGroupItem position variants\n * Applied to Button's visual layer (Layer 2) for position-aware border-radius\n *\n * Compound variants handle both orientation and position combinations:\n * - Horizontal: left/right borders and radii\n * - Vertical: top/bottom borders and radii\n */\nexport const buttonGroupItemVariants = cva('', {\n variants: {\n orientation: {\n // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)\n horizontal: 'min-w-[44px]',\n // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,\n // eliminating gaps between stacked buttons in vertical orientation\n vertical: 'flex min-h-[44px]',\n },\n position: {\n first: '',\n middle: '',\n last: '',\n only: '', // Single button - no modifications needed\n },\n },\n compoundVariants: [\n // ==========================================================================\n // Horizontal Orientation\n // ==========================================================================\n {\n orientation: 'horizontal',\n position: 'first',\n className: 'rounded-r-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'middle',\n className: 'rounded-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'last',\n className: 'rounded-l-none',\n },\n // ==========================================================================\n // Vertical Orientation\n // Note: w-full is handled by Button's effectiveFullWidth for both layers\n // ==========================================================================\n {\n orientation: 'vertical',\n position: 'first',\n className: 'rounded-b-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'middle',\n className: 'rounded-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'last',\n className: 'rounded-t-none',\n },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n position: 'only',\n },\n});\n\n// =============================================================================\n// Separator Variants\n// =============================================================================\n\n/**\n * ButtonGroupSeparator variants\n * Orientation-aware visual divider between button groups\n */\nexport const buttonGroupSeparatorVariants = cva('bg-[var(--border)]', {\n variants: {\n orientation: {\n horizontal: 'w-px h-6 mx-1',\n vertical: 'h-px w-full my-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n","\"use client\";\n\n/**\n * Button Component - 3-Layer Architecture\n * Accessible button with React Aria primitives and CVA styling\n *\n * Architecture:\n * - Layer 1: Touch Target (44x44px WCAG AAA compliant, transparent)\n * - Layer 2: Visual Button (configurable size, colors, borders)\n * - Layer 3: Content & Effects (text, icons, ripple, loading spinner)\n *\n * @see 3layer-plan.md for architecture details\n * @see spec.md FR-029 to FR-037 (Button Component Requirements)\n * @see spec.md FR-009 (WCAG 2.2 AAA - 7:1 contrast ratio)\n * @see spec.md FR-014 (44x44px minimum touch targets)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\nimport { forwardRef, memo, useId } from 'react';\nimport {\n Button as AriaButton,\n type ButtonProps as AriaButtonProps,\n} from 'react-aria-components';\nimport { Loader2, Zap } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport type { ButtonProps } from './Button.types';\nimport { buttonOuterVariants, buttonVisualVariants, buttonVariants } from './Button.styles';\nimport { PRESSED_STYLES, HOVER_STYLES, HIGH_CONTRAST_HOVER, HIGH_CONTRAST_PRESSED } from '../../styles/interaction-states';\nimport {\n useButtonGroupContext,\n useButtonGroupItemContext,\n} from '../ButtonGroup/ButtonGroupContext';\nimport { buttonGroupItemVariants } from '../ButtonGroup/ButtonGroup.variants';\n\n/**\n * Button Component - 3-Layer Architecture\n * Fully accessible button with React Aria and themed styling\n *\n * Layer 1: Touch Target (AriaButton) - 44x44px WCAG AAA compliant\n * Layer 2: Visual Button (span) - configurable appearance\n * Layer 3: Content (children) - text, icons, effects\n */\nconst Button = memo(forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n buttonVisualClassName,\n variant,\n size,\n visualSize,\n fullWidth,\n loading = false,\n loadingText = \"Loading...\",\n shortcut,\n children,\n isDisabled,\n paywall = false,\n paywallRedirect,\n paywallDescription,\n onPress,\n ...props\n },\n ref\n ) => {\n const paywallDescriptionId = useId();\n\n // ==========================================================================\n // ButtonGroup Context Integration\n // ==========================================================================\n\n // Consume group-level context (variant, size, isDisabled, orientation)\n const groupContext = useButtonGroupContext();\n\n // Consume item-level context (position for border-radius styling)\n const itemContext = useButtonGroupItemContext();\n\n // Merge context values with props (props take precedence)\n const effectiveVariant = variant ?? groupContext?.variant ?? 'default';\n const effectiveSize = size ?? groupContext?.size;\n const effectiveIsDisabled = isDisabled ?? groupContext?.isDisabled ?? false;\n\n // In vertical groups, buttons should be full width automatically\n const isInVerticalGroup = groupContext?.orientation === 'vertical';\n const effectiveFullWidth = fullWidth || isInVerticalGroup;\n\n // Position styling for ButtonGroup (only applied when in a group)\n const positionClassName = itemContext\n ? buttonGroupItemVariants({\n orientation: groupContext?.orientation ?? 'horizontal',\n position: itemContext.position,\n })\n : '';\n\n // Default visualSize to size for backward compatibility\n const effectiveVisualSize = visualSize ?? effectiveSize ?? 'default';\n\n // AAA Accessibility: Warn in dev/test if icon/dot variant lacks accessible name\n if (process.env.NODE_ENV !== 'production') {\n if (\n (effectiveVisualSize === 'dot' || effectiveVisualSize === 'icon') &&\n !props['aria-label'] &&\n !children\n ) {\n console.warn(\n '[Button] visualSize=\"dot\" or \"icon\" requires aria-label when no visible text is provided (WCAG 1.1.1)'\n );\n }\n }\n\n /**\n * Handle button press - intercepts action when paywalled\n * If paywalled with redirect URL, opens in new tab\n * Otherwise, calls the normal onPress handler\n */\n const handlePress = (e: Parameters<NonNullable<AriaButtonProps['onPress']>>[0]): void => {\n if (paywall) {\n if (paywallRedirect) {\n window.open(paywallRedirect, '_blank', 'noopener,noreferrer');\n }\n // Don't call onPress when paywalled\n return;\n }\n onPress?.(e);\n };\n\n // Only set isDisabled when we have a reason to disable\n // Otherwise, let slot system control disabled state (e.g., in NumberField)\n const computedIsDisabled = effectiveIsDisabled || loading || undefined;\n\n return (\n <AriaButton\n ref={ref}\n isDisabled={computedIsDisabled}\n aria-disabled={paywall ? true : undefined}\n aria-describedby={paywall ? paywallDescriptionId : undefined}\n onPress={handlePress}\n className={cn(buttonOuterVariants({ fullWidth: effectiveFullWidth, inVerticalGroup: isInVerticalGroup }), className)}\n {...props}\n >\n {(renderProps) => (\n /* Layer 2: Visual Button */\n <span\n className={cn(\n buttonVisualVariants({\n variant: effectiveVariant,\n visualSize: effectiveVisualSize,\n paywall,\n fullWidth: effectiveFullWidth,\n }),\n // Position styling from ButtonGroup context (border-radius adjustments)\n positionClassName,\n buttonVisualClassName,\n // Layer 2 interaction styles (no focus - focus ring is on Layer 1)\n PRESSED_STYLES,\n HOVER_STYLES,\n HIGH_CONTRAST_HOVER,\n HIGH_CONTRAST_PRESSED\n )}\n data-pressed={renderProps.isPressed || undefined}\n >\n {/* Layer 3: Content & Effects */}\n\n {/* FR-033: Loading spinner with screen reader announcement */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {loading && (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" aria-hidden=\"true\" />\n <span className=\"sr-only\" aria-live=\"polite\">\n {loadingText}\n </span>\n </>\n )}\n\n {/* Hide children during loading */}\n {!loading && children}\n\n {/* Paywall: Lightning bolt icon */}\n {paywall && (\n <Zap\n data-testid=\"zap-icon\"\n aria-hidden=\"true\"\n className=\"ml-1\"\n />\n )}\n\n {/* Paywall: Screen reader description */}\n {paywall && (\n <span id={paywallDescriptionId} className=\"sr-only\">\n Premium feature: {paywallDescription || \"Upgrade required to access this feature\"}\n </span>\n )}\n\n {/* FR-034: Keyboard shortcut display on focus */}\n {renderProps.isFocusVisible && shortcut && (\n <kbd className=\"ml-auto hidden text-xs opacity-60 lg:inline\">\n {shortcut}\n </kbd>\n )}\n\n </span>\n )}\n </AriaButton>\n );\n }\n));\n\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants, buttonOuterVariants, buttonVisualVariants };\nexport type { ButtonProps } from './Button.types';\n","'use client';\n\nimport { useEffect, useState, type RefObject } from 'react';\n\n/**\n * Track whether a referenced element is narrower than `breakpoint` (px), via a\n * `ResizeObserver`. This is a **container query**, not a viewport query — a table\n * inside a narrow panel reflows to cards even on a wide screen.\n *\n * Uses `offsetWidth` (ignores CSS transforms, e.g. zoom/preview scaling).\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * const narrow = useContainerNarrow(ref, 680);\n * return <div ref={ref}>{narrow ? <TableCardList .../> : <Table .../>}</div>;\n */\nexport function useContainerNarrow(\n ref: RefObject<HTMLElement | null>,\n breakpoint: number\n): boolean {\n const [narrow, setNarrow] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const measure = (): void => setNarrow(el.offsetWidth < breakpoint);\n measure(); // initial — covers an already-narrow mount\n\n let observer: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(measure);\n observer.observe(el);\n }\n window.addEventListener('resize', measure);\n return () => {\n window.removeEventListener('resize', measure);\n observer?.disconnect();\n };\n }, [ref, breakpoint]);\n\n return narrow;\n}\n","'use client';\n\nimport { useState, useEffect } from 'react';\n\nconst QUERY = '(prefers-reduced-motion: reduce)';\n\nfunction getInitialState(): boolean {\n if (typeof window === 'undefined') return false;\n return window.matchMedia(QUERY).matches;\n}\n\n/**\n * Detects whether the user prefers reduced motion.\n *\n * - SSR-safe (returns `false` on the server)\n * - Reacts to changes in the OS preference\n * - Cleans up the listener on unmount\n */\nexport function useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(getInitialState);\n\n useEffect(() => {\n const mql = window.matchMedia(QUERY);\n setPrefersReducedMotion(mql.matches);\n\n const handler = (event: MediaQueryListEvent): void => {\n setPrefersReducedMotion(event.matches);\n };\n\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n\n return prefersReducedMotion;\n}\n","'use client';\n\nimport { createContext, useContext } from 'react';\nimport type { ReactNode } from 'react';\nimport type {\n TimelineHeadingLevel,\n TimelineMarker,\n TimelineOrientation,\n} from './Timeline.types';\n\n/**\n * Stable configuration shared with every `Timeline.Item`. Memoised at the root and\n * changes ~never, so item content (notably date formatting) is not recomputed on\n * unrelated root re-renders.\n */\nexport interface TimelineConfigContextValue {\n /** Effective orientation (already resolved for the mobile collapse). */\n orientation: TimelineOrientation;\n marker: TimelineMarker;\n locale: string | undefined;\n /** Shared `Intl.DateTimeFormat` instance — built once, reused by all items. */\n dateFormatter: Intl.DateTimeFormat;\n formatDate: ((date: Date) => ReactNode) | undefined;\n dateFormatOptions: Intl.DateTimeFormatOptions | undefined;\n titleHeadingLevel: TimelineHeadingLevel;\n /** Whether the user prefers reduced motion (gates smooth scrolling). */\n reducedMotion: boolean;\n /** Items register their focus target node here for `scrollToItem`/`focusItem`. */\n registerItem: (id: string, node: HTMLElement | null) => void;\n}\n\nexport const TimelineConfigContext = createContext<TimelineConfigContextValue | null>(null);\n\nexport function useTimelineContext(): TimelineConfigContextValue {\n const ctx = useContext(TimelineConfigContext);\n if (!ctx) {\n throw new Error('Timeline.Item must be used within <Timeline>');\n }\n return ctx;\n}\n","import { cva } from 'class-variance-authority';\n\n/**\n * The ordered list. Vertical stacks top-to-bottom; horizontal flows left-to-right\n * and is keyboard-scrollable when it overflows (the component adds `tabIndex`).\n */\nexport const timelineVariants = cva('m-0 flex list-none p-0', {\n variants: {\n orientation: {\n vertical: 'flex-col',\n horizontal: 'flex-row items-stretch overflow-x-auto',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\n/**\n * A single event (`<li>`). Marker rail + content.\n *\n * `content-visibility: auto` keeps every node in the DOM and the a11y tree (Ctrl+F and\n * screen-reader traversal still work — AAA-safe) while skipping layout/paint for\n * off-screen items. `contain-intrinsic-size` is orientation-aware (height placeholder\n * when vertical, width placeholder when horizontal).\n */\nexport const timelineItemVariants = cva('relative [content-visibility:auto]', {\n variants: {\n orientation: {\n vertical:\n 'grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 [contain-intrinsic-size:auto_88px]',\n horizontal: 'flex min-w-[12rem] flex-1 flex-col [contain-intrinsic-size:14rem_auto]',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\n/**\n * The marker node for the `'dot'` and `'icon'` styles (the `'basic'` line style has no\n * marker). Dots are a muted node on the rail; the icon badge is primary-filled.\n */\nexport const timelineMarkerVariants = cva(\n 'relative z-10 flex shrink-0 items-center justify-center',\n {\n variants: {\n marker: {\n dot: 'h-3 w-3 rounded-full bg-[var(--input-border)]',\n icon: 'h-8 w-8 rounded-full bg-[var(--primary-action)] text-[var(--primary-action-foreground)] [&_svg]:h-4 [&_svg]:w-4',\n },\n },\n defaultVariants: {\n marker: 'dot',\n },\n }\n);\n\n/**\n * The connector between dot/icon markers — a muted line that `flex-1` fills down to\n * (vertical) or across to (horizontal) the next marker. (The `'basic'` style draws its\n * own full-length primary rail instead; see TimelineItem.)\n */\nexport const timelineConnectorVariants = cva(\n 'shrink-0 flex-1 rounded-full bg-[var(--border)]',\n {\n variants: {\n orientation: {\n vertical: 'mt-1 w-0.5',\n horizontal: 'ml-2 h-0.5',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n }\n);\n\n/**\n * The content column (meta / title / description / custom body). When the item is\n * interactive the inner Link/Button reuses these paddings.\n */\nexport const timelineContentVariants = cva('min-w-0', {\n variants: {\n orientation: {\n // Trailing space keeps an item's text off the next item (below / to the right).\n vertical: 'pb-6',\n horizontal: 'pt-3 pr-6',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n","'use client';\n\n/**\n * Timeline.Item — a single event (`<li>`): marker rail + content.\n *\n * Body precedence: `children` is the body and supersedes `title`/`description`\n * (dev-only warning if both are passed). The meta region (`date`/`label`) and the\n * marker are always owned here so date/marker presentation stays consistent even for\n * fully-custom bodies (e.g. an activity-log item composed via `icon` + `children`).\n *\n * Accessibility:\n * - The marker rail (decorative dot/icon + connector) is `aria-hidden`; meaning comes\n * from the text. Interactive items wrap the content in a real `<a>`/`<button>` with a\n * visible focus ring; static items are focusable only programmatically (`tabIndex=-1`)\n * so `focusItem`/`scrollToItem` can target them.\n * - The whole-card link/button must not contain nested interactive children — if an\n * item needs secondary actions, make only the title a link instead.\n */\n\nimport { memo, useCallback, useMemo, type ReactElement, type ReactNode } from 'react';\nimport { Link, Button as AriaButton } from 'react-aria-components';\nimport { cn } from '../../utils/cn';\nimport { useTimelineContext } from './TimelineContext';\nimport {\n timelineConnectorVariants,\n timelineContentVariants,\n timelineItemVariants,\n timelineMarkerVariants,\n} from './Timeline.styles';\nimport type { TimelineItemProps } from './Timeline.types';\n\n/** Primary rail/stub for the 'basic' line style. */\nconst RAIL_PRIMARY = 'bg-[var(--primary-action)]';\n\nconst META_CLASS = 'block text-xs text-[var(--muted-foreground)]';\nconst TITLE_CLASS = 'mt-0.5 text-base font-bold text-[var(--content-foreground)]';\nconst DESC_CLASS = 'mt-1 text-sm text-[var(--muted-foreground)]';\n\n// Interactive wrapper: keeps the content at its natural position (so text stays aligned\n// with the marker) and carries the keyboard focus ring.\nconst INTERACTIVE_WRAP =\n 'relative isolate block rounded-md text-[var(--content-foreground)] no-underline ' +\n 'cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] ' +\n 'focus-visible:ring-offset-2 [scroll-margin:1rem]';\n\n// Hover/focus background drawn as an absolute layer that bleeds 8px past the content\n// (`-inset-2`) — gives the highlight padding around the text WITHOUT moving the text and\n// without affecting item spacing. Behind the content via `isolate` + `-z-10` on the wrapper.\nconst HOVER_LAYER =\n 'pointer-events-none absolute -inset-2 -z-10 rounded-md transition-colors ' +\n 'group-hover/tl-item:bg-[var(--muted)] group-focus-within/tl-item:bg-[var(--muted)]';\n\n// Marker emphasis when the item is actionable and hovered/focused.\nconst DOT_HIGHLIGHT =\n 'transition-colors group-hover/tl-item:bg-[var(--primary-action)] ' +\n 'group-focus-within/tl-item:bg-[var(--primary-action)]';\nconst ICON_HIGHLIGHT =\n 'transition-transform group-hover/tl-item:scale-110 group-focus-within/tl-item:scale-110';\n\nfunction TimelineItemImpl({\n id,\n date,\n label,\n dateFormatOptions,\n title,\n description,\n children,\n icon,\n href,\n target,\n rel,\n onPress,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'data-testid': testId,\n}: TimelineItemProps): ReactElement {\n const {\n orientation,\n marker,\n locale,\n dateFormatter,\n formatDate,\n titleHeadingLevel,\n registerItem,\n } = useTimelineContext();\n\n if (\n process.env.NODE_ENV !== 'production' &&\n children != null &&\n (title != null || description != null)\n ) {\n console.warn(\n 'Timeline.Item: `children` supersedes `title`/`description` — pass one or the other.'\n );\n }\n\n // Per-item formatter only when the item overrides options; otherwise reuse the shared one.\n const itemFormatter = useMemo(\n () => (dateFormatOptions ? new Intl.DateTimeFormat(locale, dateFormatOptions) : dateFormatter),\n [dateFormatOptions, locale, dateFormatter]\n );\n\n const dateObj = useMemo(() => (date != null ? new Date(date) : null), [date]);\n const isValidDate = dateObj != null && !Number.isNaN(dateObj.getTime());\n\n // Register the focus target (interactive control, or the <li> itself when static).\n const registerRef = useCallback(\n (node: HTMLElement | null) => {\n if (id !== undefined) registerItem(id, node);\n },\n [id, registerItem]\n );\n\n const meta: ReactNode = isValidDate ? (\n <time dateTime={dateObj.toISOString()} className={META_CLASS}>\n {formatDate ? formatDate(dateObj) : itemFormatter.format(dateObj)}\n </time>\n ) : label != null ? (\n <span className={META_CLASS}>{label}</span>\n ) : null;\n\n const interactive = href != null || onPress != null;\n\n // Interactive items render the title/description as phrasing `block` spans so they are\n // valid inside an <a>/<button> (block elements can't nest in a <button>) and so the\n // title isn't a heading-inside-a-link. Static items use real heading/paragraph tags.\n const Heading = titleHeadingLevel === 'p' ? 'p' : titleHeadingLevel;\n const titleNode =\n title == null ? null : interactive ? (\n <span className={cn('block', TITLE_CLASS)}>{title}</span>\n ) : (\n <Heading className={TITLE_CLASS}>{title}</Heading>\n );\n const descNode =\n description == null ? null : interactive ? (\n <span className={cn('block', DESC_CLASS)}>{description}</span>\n ) : (\n <p className={DESC_CLASS}>{description}</p>\n );\n const body: ReactNode =\n children != null ? (\n children\n ) : (\n <>\n {titleNode}\n {descNode}\n </>\n );\n\n const content = (\n <>\n {meta}\n {body}\n </>\n );\n\n // The 'basic' style is a continuous primary rail running the full length, with a short\n // primary stub branching into each item at the meta row. The dot/icon styles place a\n // marker node with a muted connector filling to the next marker.\n let rail: ReactNode;\n if (marker === 'basic') {\n rail =\n orientation === 'vertical' ? (\n <div className=\"relative w-2 self-stretch\" aria-hidden=\"true\">\n <span\n data-timeline-connector\n className={cn('absolute inset-y-0 left-0 w-0.5', RAIL_PRIMARY)}\n />\n <span className={cn('absolute left-0 top-2 h-0.5 w-3', RAIL_PRIMARY)} />\n </div>\n ) : (\n <div className=\"relative h-2 w-full\" aria-hidden=\"true\">\n <span\n data-timeline-connector\n className={cn('absolute inset-x-0 top-0 h-0.5', RAIL_PRIMARY)}\n />\n {/* Down-stub at the item's start edge, lining up with the content below. */}\n <span className={cn('absolute left-0 top-0 h-3 w-0.5', RAIL_PRIMARY)} />\n </div>\n );\n } else {\n // Vertical: align the dot with the top of the date text (12px dot centred on the 16px\n // meta line) rather than the item's edge — corrects the Figma source, which is wrong\n // here. Horizontal keeps the dot centred on the connector line (which runs through it),\n // where its left edge already lines up with the date text below.\n const dotAlign = marker === 'dot' && orientation === 'vertical' ? 'mt-0.5' : '';\n const markerHighlight = !interactive ? '' : marker === 'dot' ? DOT_HIGHLIGHT : ICON_HIGHLIGHT;\n const markerNode = (\n <span className={cn(timelineMarkerVariants({ marker }), dotAlign, markerHighlight)}>\n {marker === 'icon' ? icon : null}\n </span>\n );\n const connector = (\n <span data-timeline-connector className={timelineConnectorVariants({ orientation })} />\n );\n rail =\n orientation === 'vertical' ? (\n <div className=\"flex flex-col items-center self-stretch\" aria-hidden=\"true\">\n {markerNode}\n {connector}\n </div>\n ) : (\n <div className=\"flex w-full items-center\" aria-hidden=\"true\">\n {markerNode}\n {connector}\n </div>\n );\n }\n\n const contentClass = timelineContentVariants({ orientation });\n\n // Interactive items wrap the content in a Link/Button; the hover/focus highlight is an\n // absolute layer behind the content so the text never shifts.\n const interactiveBody = (\n <>\n <span aria-hidden=\"true\" className={HOVER_LAYER} />\n {content}\n </>\n );\n\n // Spacing (item gap) lives on the outer cell; the interactive Link/Button hugs only the\n // text so the hover layer wraps the text, not the gap below it.\n let contentRegion: ReactNode;\n if (href != null) {\n contentRegion = (\n <div className={contentClass}>\n <Link\n ref={registerRef as (node: HTMLAnchorElement | null) => void}\n href={href}\n target={target}\n rel={rel}\n className={INTERACTIVE_WRAP}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n {interactiveBody}\n </Link>\n </div>\n );\n } else if (onPress != null) {\n contentRegion = (\n <div className={contentClass}>\n <AriaButton\n ref={registerRef as (node: HTMLButtonElement | null) => void}\n onPress={onPress}\n className={cn(INTERACTIVE_WRAP, 'w-full text-left')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n {interactiveBody}\n </AriaButton>\n </div>\n );\n } else {\n contentRegion = <div className={contentClass}>{content}</div>;\n }\n\n return (\n <li\n ref={interactive ? undefined : registerRef}\n tabIndex={interactive ? undefined : -1}\n className={cn(\n timelineItemVariants({ orientation }),\n // Hide the trailing dot/icon connector on the last item. The 'basic' rail is\n // intentionally continuous to the end, so it is never hidden.\n marker !== 'basic' && '[&:last-child_[data-timeline-connector]]:hidden',\n // Vertical basic rail: the FIRST item begins at the stub (not the item's top\n // edge) so the timeline opens with a clean 90° corner, not a stalk above the\n // stub. Horizontal's stub already sits at the item's start edge, so its rail\n // (inset-x-0) starts there naturally — no inset needed.\n marker === 'basic' &&\n orientation === 'vertical' &&\n '[&:first-child_[data-timeline-connector]]:top-2',\n // Named group so the marker + hover layer react to hovering/focusing the item.\n interactive && 'group/tl-item rounded-md outline-none',\n className\n )}\n data-testid={testId}\n >\n {rail}\n {contentRegion}\n </li>\n );\n}\n\nexport const TimelineItem = memo(TimelineItemImpl);\nTimelineItem.displayName = 'Timeline.Item';\n","'use client';\n\n/**\n * Timeline — compound root.\n *\n * An accessible, chronological feed of events rendered as a semantic `<ol>`. WCAG 2.2 AAA.\n *\n * Design notes:\n * - Renders EVERY child it is given — it never caps/slices present data (hidden content\n * would be invisible to find-in-page and screen readers). Large/server-fed data uses\n * `onLoadMore`/`hasMore` to append more `<Timeline.Item>` children; performance for\n * long, fully-rendered lists comes from `content-visibility: auto` on each item.\n * - Config (orientation, marker, formatter, …) lives in a memoised context.\n * - Horizontal timelines auto-collapse to vertical on narrow containers via\n * `useContainerNarrow`. There is no \"active\"/selected item concept; programmatic\n * navigation is via the imperative handle (`scrollToItem`/`focusItem`).\n *\n * @see Wizard (role=\"status\" live region, configurable heading level)\n * @see Tabs (compound children + context)\n */\n\nimport {\n Children,\n forwardRef,\n isValidElement,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n} from 'react';\nimport { Button } from '../Button';\nimport { useContainerNarrow } from '../../hooks/useContainerNarrow';\nimport { useReducedMotion } from '../../hooks/useReducedMotion';\nimport { cn } from '../../utils/cn';\nimport {\n TimelineConfigContext,\n type TimelineConfigContextValue,\n} from './TimelineContext';\nimport { TimelineItem } from './TimelineItem';\nimport { timelineVariants } from './Timeline.styles';\nimport type { TimelineHandle, TimelineProps } from './Timeline.types';\n\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long' };\n\nconst TimelineRoot = forwardRef<TimelineHandle, TimelineProps>(function TimelineRoot(\n {\n children,\n orientation = 'vertical',\n marker = 'dot',\n locale,\n dateFormatOptions,\n formatDate,\n titleHeadingLevel = 'p',\n collapseBelow = 640,\n onLoadMore,\n hasMore = false,\n isLoadingMore = false,\n loadMoreLabel = 'Show more',\n emptyState,\n landmarkLabel,\n className,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'data-testid': testId = 'timeline',\n },\n ref\n): ReactElement {\n const rootRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLOListElement>(null);\n const itemNodes = useRef<Map<string, HTMLElement>>(new Map());\n const reducedMotion = useReducedMotion();\n\n // Container-query collapse: a horizontal timeline reflows to vertical when narrow.\n // `collapseBelow === false` disables it (breakpoint 0 never matches).\n const narrow = useContainerNarrow(rootRef, collapseBelow === false ? 0 : collapseBelow);\n const effectiveOrientation =\n orientation === 'horizontal' && narrow ? 'vertical' : orientation;\n\n const scrollToNode = useCallback(\n (node: HTMLElement | undefined) => {\n node?.scrollIntoView({\n behavior: reducedMotion ? 'auto' : 'smooth',\n block: 'nearest',\n inline: 'nearest',\n });\n },\n [reducedMotion]\n );\n\n const registerItem = useCallback((itemId: string, node: HTMLElement | null) => {\n if (node) itemNodes.current.set(itemId, node);\n else itemNodes.current.delete(itemId);\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToItem: (itemId: string) => scrollToNode(itemNodes.current.get(itemId)),\n focusItem: (itemId: string) => itemNodes.current.get(itemId)?.focus(),\n }),\n [scrollToNode]\n );\n\n const dateFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, dateFormatOptions ?? DEFAULT_DATE_OPTIONS),\n [locale, dateFormatOptions]\n );\n\n const configValue = useMemo<TimelineConfigContextValue>(\n () => ({\n orientation: effectiveOrientation,\n marker,\n locale,\n dateFormatter,\n formatDate,\n dateFormatOptions,\n titleHeadingLevel,\n reducedMotion,\n registerItem,\n }),\n [\n effectiveOrientation,\n marker,\n locale,\n dateFormatter,\n formatDate,\n dateFormatOptions,\n titleHeadingLevel,\n reducedMotion,\n registerItem,\n ]\n );\n\n const itemCount = useMemo(\n () => Children.toArray(children).filter(isValidElement).length,\n [children]\n );\n const isEmpty = itemCount === 0;\n\n // \"Show more\" focus contract: focus stays on the button across loads; when the final\n // load removes the button (`hasMore` → false), move focus to the first new item so it\n // never drops to <body>. `aria-live` announcement fires only on a user-initiated load.\n const pendingLoadRef = useRef<number | null>(null);\n const [liveMessage, setLiveMessage] = useState('');\n\n const handleLoadMore = useCallback(() => {\n pendingLoadRef.current = itemCount;\n void onLoadMore?.();\n }, [itemCount, onLoadMore]);\n\n useEffect(() => {\n const pending = pendingLoadRef.current;\n if (pending == null || itemCount <= pending) return;\n if (!hasMore) {\n const firstNew = listRef.current?.children[pending] as HTMLElement | undefined;\n const focusTarget = firstNew?.querySelector<HTMLElement>('a, button') ?? firstNew;\n focusTarget?.focus();\n }\n setLiveMessage(`Showing ${itemCount} items`);\n pendingLoadRef.current = null;\n }, [itemCount, hasMore]);\n\n if (isEmpty) {\n return (\n <div ref={rootRef} id={id} className={className} data-testid={testId}>\n {emptyState ?? null}\n </div>\n );\n }\n\n const list = (\n <ol\n ref={listRef}\n className={timelineVariants({ orientation: effectiveOrientation })}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n // Keep an overflowing horizontal timeline keyboard-scrollable (WCAG 2.1.1).\n tabIndex={effectiveOrientation === 'horizontal' ? 0 : undefined}\n >\n {children}\n </ol>\n );\n\n return (\n <TimelineConfigContext.Provider value={configValue}>\n <div ref={rootRef} id={id} className={cn('w-full', className)} data-testid={testId}>\n {landmarkLabel != null ? <nav aria-label={landmarkLabel}>{list}</nav> : list}\n\n {hasMore && (\n <div className=\"mt-2 flex justify-center\">\n <Button\n variant=\"outline\"\n onPress={handleLoadMore}\n loading={isLoadingMore}\n loadingText=\"Loading…\"\n data-testid={`${testId}-load-more`}\n >\n {loadMoreLabel}\n </Button>\n </div>\n )}\n\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {liveMessage}\n </div>\n </div>\n </TimelineConfigContext.Provider>\n );\n});\n\nTimelineRoot.displayName = 'Timeline';\n\n/**\n * Timeline compound component.\n *\n * @example\n * ```tsx\n * <Timeline aria-label=\"Application history\" marker=\"dot\">\n * <Timeline.Item date=\"2025-04-02\" title=\"Applied\" description=\"Application received.\" />\n * <Timeline.Item date=\"2025-04-10\" title=\"Interview\" status=\"active\" />\n * </Timeline>\n * ```\n */\nexport const Timeline = Object.assign(TimelineRoot, {\n Item: TimelineItem,\n});\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode } from 'react';\n\n/**\n * Timeline orientation.\n *\n * - 'vertical': events stack top-to-bottom with a vertical connector rail (default).\n * - 'horizontal': events flow left-to-right with a horizontal connector. Auto-collapses\n * to vertical on narrow containers (see `collapseBelow`).\n */\nexport const TimelineOrientationSchema = z.enum(['vertical', 'horizontal']);\nexport type TimelineOrientation = z.infer<typeof TimelineOrientationSchema>;\n\n/**\n * Marker style for each event.\n *\n * - 'dot': small circular node on the connector (default).\n * - 'basic': no node — just the connector line; active items colour the line segment.\n * - 'icon': circular badge holding an icon or avatar.\n */\nexport const TimelineMarkerSchema = z.enum(['dot', 'basic', 'icon']);\nexport type TimelineMarker = z.infer<typeof TimelineMarkerSchema>;\n\n/**\n * Heading level for item titles. Mirrors Wizard's `stepHeadingLevel`. Defaults to\n * `'p'` (rendered as a styled `<strong>`-like paragraph) to avoid breaking the host\n * page's heading hierarchy; opt into real headings (`h2`–`h6`) when appropriate.\n */\nexport const TimelineHeadingLevelSchema = z.enum(['h2', 'h3', 'h4', 'h5', 'h6', 'p']);\nexport type TimelineHeadingLevel = z.infer<typeof TimelineHeadingLevelSchema>;\n\n/** A value accepted by `new Date(...)`. */\nexport type TimelineDateInput = Date | string | number;\n\n/**\n * Imperative handle exposed via `ref` for in-timeline navigation.\n */\nexport interface TimelineHandle {\n /** Scroll the item with this `id` into view (respects `prefers-reduced-motion`). */\n scrollToItem: (id: string) => void;\n /** Move focus to the item with this `id`. */\n focusItem: (id: string) => void;\n}\n\n/**\n * Timeline root props.\n *\n * Data enters via `<Timeline.Item>` children (compound pattern). Timeline renders\n * every child it is given — it never caps/slices present data (that would hide\n * content from find-in-page and screen readers). For large or server-fed data use\n * `onLoadMore`/`hasMore` to append more items.\n */\nexport const TimelinePropsSchema = BaseComponentPropsSchema.extend({\n /** `<Timeline.Item>` children. */\n children: z.custom<ReactNode>().optional(),\n\n /** Layout direction. Default `'vertical'`. */\n orientation: TimelineOrientationSchema.optional().default('vertical'),\n\n /** Marker style. Default `'dot'`. */\n marker: TimelineMarkerSchema.optional().default('dot'),\n\n /** BCP-47 locale for date formatting. Defaults to the runtime locale. */\n locale: z.string().optional(),\n\n /**\n * `Intl.DateTimeFormatOptions` controlling date granularity (hour/day/month/year).\n * Default `{ year: 'numeric', month: 'long' }` → e.g. \"April 2025\".\n */\n dateFormatOptions: z.custom<Intl.DateTimeFormatOptions>().optional(),\n\n /** Full override for rendering an item's date. Wins over `dateFormatOptions`. */\n formatDate: z.custom<(date: Date) => ReactNode>().optional(),\n\n /** Heading level for item titles. Default `'p'`. */\n titleHeadingLevel: TimelineHeadingLevelSchema.optional().default('p'),\n\n /**\n * Container width (px) below which a horizontal timeline collapses to vertical.\n * Default `640`. Pass `false` to disable collapsing.\n */\n collapseBelow: z.union([z.number(), z.literal(false)]).optional().default(640),\n\n /** Called when the \"Show more\" button is pressed (server/consumer-fed pagination). */\n onLoadMore: z.custom<() => void | Promise<void>>().optional(),\n\n /** Whether more items can be loaded (renders the \"Show more\" affordance). */\n hasMore: z.boolean().optional().default(false),\n\n /** Whether a load is in progress (puts the \"Show more\" button in a pending state). */\n isLoadingMore: z.boolean().optional().default(false),\n\n /** Label for the \"Show more\" button. Default `'Show more'`. */\n loadMoreLabel: z.string().optional(),\n\n /** Rendered instead of the list when there are no items. */\n emptyState: z.custom<ReactNode>().optional(),\n\n /**\n * When set, wraps the list in a `<nav>` landmark with this accessible label.\n * Opt-in only — a content timeline is not a navigation landmark by default.\n */\n landmarkLabel: z.string().optional(),\n});\n\nexport interface TimelineProps {\n className?: string;\n children?: ReactNode;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'data-testid'?: string;\n orientation?: TimelineOrientation;\n marker?: TimelineMarker;\n locale?: string;\n dateFormatOptions?: Intl.DateTimeFormatOptions;\n formatDate?: (date: Date) => ReactNode;\n titleHeadingLevel?: TimelineHeadingLevel;\n collapseBelow?: number | false;\n onLoadMore?: () => void | Promise<void>;\n hasMore?: boolean;\n isLoadingMore?: boolean;\n loadMoreLabel?: string;\n emptyState?: ReactNode;\n landmarkLabel?: string;\n}\n\n/**\n * Timeline.Item props.\n *\n * Body precedence: if `children` is provided it is the body and supersedes\n * `title`/`description` (a dev-only warning fires if both are passed). The meta\n * region (`date`/`label`) and the marker are always owned by Timeline.Item. There is\n * no \"active\"/selected concept — every item is presented identically per the variant.\n */\nexport const TimelineItemPropsSchema = BaseComponentPropsSchema.extend({\n /** Stable id — required for `activeId`, `scrollToItem`, and `focusItem`. */\n id: z.string().optional(),\n\n /** Event date. Anything `new Date(...)` accepts. Rendered in `<time dateTime>`. */\n date: z.custom<Date | string | number>().optional(),\n\n /** Non-date meta text, used instead of `date` (e.g. \"Step 1\"). */\n label: z.custom<ReactNode>().optional(),\n\n /** Per-item override of the timeline's `dateFormatOptions`. */\n dateFormatOptions: z.custom<Intl.DateTimeFormatOptions>().optional(),\n\n /** Event title (the common case). Ignored when `children` is provided. */\n title: z.custom<ReactNode>().optional(),\n\n /** Event description (the common case). Ignored when `children` is provided. */\n description: z.custom<ReactNode>().optional(),\n\n /** Custom body content. Supersedes `title`/`description`. */\n children: z.custom<ReactNode>().optional(),\n\n /** Icon or avatar node for the `'icon'` marker style. */\n icon: z.custom<ReactNode>().optional(),\n\n /** Make the whole item a link to this URL. */\n href: z.string().optional(),\n\n /** `target` attribute when `href` is set. */\n target: z.string().optional(),\n\n /** `rel` attribute when `href` is set. */\n rel: z.string().optional(),\n\n /** Make the whole item a button invoking this handler. */\n onPress: z.custom<() => void>().optional(),\n});\n\nexport interface TimelineItemProps {\n className?: string;\n children?: ReactNode;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'data-testid'?: string;\n date?: TimelineDateInput;\n label?: ReactNode;\n dateFormatOptions?: Intl.DateTimeFormatOptions;\n title?: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n href?: string;\n target?: string;\n rel?: string;\n onPress?: () => void;\n}\n"]}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- 'use strict';var react=require('react'),reactAria=require('react-aria'),reactStately=require('react-stately'),classVarianceAuthority=require('class-variance-authority'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),reactAriaComponents=require('react-aria-components'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod');function u(...t){return tailwindMerge.twMerge(clsx.clsx(t))}var $=classVarianceAuthority.cva("inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",{variants:{fullWidth:{true:"w-full",false:""},inVerticalGroup:{true:"items-stretch",false:"items-center"}},defaultVariants:{fullWidth:false,inVerticalGroup:false}}),Y=classVarianceAuthority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer",{variants:{variant:{default:"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1",destructive:"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake",outline:"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)]",secondary:"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]",ghost:"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]",link:"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]"},fullWidth:{true:"w-full",false:""},visualSize:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3 text-xs",lg:"h-11 rounded-md px-6 text-base",icon:"h-10 w-10",dot:"h-5 w-5 rounded-full p-0 min-h-0 min-w-0"},paywall:{true:"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent",false:""}},defaultVariants:{variant:"default",visualSize:"default",paywall:false}});var W="data-[pressed]:scale-[0.97]";var G="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",H="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";var it=react.createContext(null);it.displayName="ButtonGroupContext";function ut(){return react.useContext(it)}var lt=react.createContext(null);lt.displayName="ButtonGroupItemContext";function ct(){return react.useContext(lt)}classVarianceAuthority.cva("inline-flex items-center gap-0",{variants:{orientation:{horizontal:"flex-row",vertical:"flex-col w-full"}},defaultVariants:{orientation:"horizontal"}});var dt=classVarianceAuthority.cva("",{variants:{orientation:{horizontal:"min-w-[44px]",vertical:"flex min-h-[44px]"},position:{first:"",middle:"",last:"",only:""}},compoundVariants:[{orientation:"horizontal",position:"first",className:"rounded-r-none border-r-0"},{orientation:"horizontal",position:"middle",className:"rounded-none border-r-0"},{orientation:"horizontal",position:"last",className:"rounded-l-none"},{orientation:"vertical",position:"first",className:"rounded-b-none border-b-0"},{orientation:"vertical",position:"middle",className:"rounded-none border-b-0"},{orientation:"vertical",position:"last",className:"rounded-t-none"}],defaultVariants:{orientation:"horizontal",position:"only"}});classVarianceAuthority.cva("bg-[var(--border)]",{variants:{orientation:{horizontal:"w-px h-6 mx-1",vertical:"h-px w-full my-1"}},defaultVariants:{orientation:"horizontal"}});var P=react.memo(react.forwardRef(({className:t,buttonVisualClassName:e,variant:r,size:i,visualSize:c,fullWidth:f,loading:g=false,loadingText:v="Loading...",shortcut:T,children:n,isDisabled:y,paywall:l=false,paywallRedirect:h,paywallDescription:V,onPress:b,...R},M)=>{let B=react.useId(),x=ut(),I=ct(),o=r??x?.variant??"default",S=i??x?.size,A=y??x?.isDisabled??false,_=x?.orientation==="vertical",O=f||_,E=I?dt({orientation:x?.orientation??"horizontal",position:I.position}):"",d=c??S??"default";return process.env.NODE_ENV!=="production"&&(d==="dot"||d==="icon")&&!R["aria-label"]&&!n&&console.warn('[Button] visualSize="dot" or "icon" requires aria-label when no visible text is provided (WCAG 1.1.1)'),jsxRuntime.jsx(reactAriaComponents.Button,{ref:M,isDisabled:A||g||void 0,"aria-disabled":l?true:void 0,"aria-describedby":l?B:void 0,onPress:D=>{if(l){h&&window.open(h,"_blank","noopener,noreferrer");return}b?.(D);},className:u($({fullWidth:O,inVerticalGroup:_}),t),...R,children:D=>jsxRuntime.jsxs("span",{className:u(Y({variant:o,visualSize:d,paywall:l,fullWidth:O}),E,e,W,"",G,H),"data-pressed":D.isPressed||void 0,children:[g&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(lucideReact.Loader2,{className:"motion-safe:animate-spin","aria-hidden":"true"}),jsxRuntime.jsx("span",{className:"sr-only","aria-live":"polite",children:v})]}),!g&&n,l&&jsxRuntime.jsx(lucideReact.Zap,{"data-testid":"zap-icon","aria-hidden":"true",className:"ml-1"}),l&&jsxRuntime.jsxs("span",{id:B,className:"sr-only",children:["Premium feature: ",V||"Upgrade required to access this feature"]}),D.isFocusVisible&&T&&jsxRuntime.jsx("kbd",{className:"ml-auto hidden text-xs opacity-60 lg:inline",children:T})]})})}));P.displayName="Button";var vt=classVarianceAuthority.cva(["pointer-events-auto relative flex w-[380px] items-center gap-3","overflow-hidden p-4 pr-12","rounded-[20px_24px_22px_18px]","data-[entering]:toast-animate-in","data-[exiting]:toast-animate-out","motion-reduce:transition-none motion-reduce:animate-none","motion-reduce:!rounded-[20px_24px_22px_18px]","touch-pan-y"],{variants:{variant:{default:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border border-[var(--border)]"],primary:["bg-[var(--primary)]","text-[var(--primary-foreground)]","border border-[var(--primary)]"],destructive:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--destructive-background)]","border border-[var(--border)]"],accent:["bg-[var(--accent-background)]","text-[var(--accent-foreground)]","border border-[var(--accent-background)]"],success:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--success-background)]","border border-[var(--border)]"],warning:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--warning-background)]","border border-[var(--border)]"],info:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--info-background)]","border border-[var(--border)]"]}},defaultVariants:{variant:"default"}}),K=classVarianceAuthority.cva(["fixed z-50 flex flex-col gap-3 p-4","pointer-events-none","max-h-screen overflow-hidden"],{variants:{position:{"top-left":"top-0 left-0 items-start","top-center":"top-0 left-1/2 -translate-x-1/2 items-center","top-right":"top-0 right-0 items-end","bottom-left":"bottom-0 left-0 items-start","bottom-center":"bottom-0 left-1/2 -translate-x-1/2 items-center","bottom-right":"bottom-0 right-0 items-end"}},defaultVariants:{position:"bottom-right"}}),$t={success:jsxRuntime.jsx(lucideReact.CheckCircle,{className:"h-5 w-5 text-[var(--success-background)]","aria-hidden":"true"}),destructive:jsxRuntime.jsx(lucideReact.XCircle,{className:"h-5 w-5 text-[var(--destructive-background)]","aria-hidden":"true"}),warning:jsxRuntime.jsx(lucideReact.AlertTriangle,{className:"h-5 w-5 text-[var(--warning-background)]","aria-hidden":"true"}),info:jsxRuntime.jsx(lucideReact.Info,{className:"h-5 w-5 text-[var(--info-background)]","aria-hidden":"true"})},bt=react.memo(({timeout:t,isPaused:e,variant:r})=>{if(t===0)return null;let i={default:"bg-[var(--muted-foreground)]",primary:"bg-[var(--primary-foreground)]/50",destructive:"bg-[var(--destructive-background)]",accent:"bg-[var(--accent-foreground)]/50",success:"bg-[var(--success-background)]",warning:"bg-[var(--warning-background)]",info:"bg-[var(--info-background)]"};return jsxRuntime.jsx("div",{className:"absolute bottom-0 left-0 right-0 h-1 overflow-hidden rounded-b-[18px]","aria-hidden":"true",children:jsxRuntime.jsx("div",{className:u("h-full w-full toast-progress-bar opacity-40",i[r]??i.default),style:{animationDuration:`${t}ms`,animationPlayState:e?"paused":"running"}})})});bt.displayName="ProgressBar";var gt=react.memo(react.forwardRef(({variant:t="default",className:e,onPress:r},i)=>jsxRuntime.jsx(P,{ref:i,variant:"ghost",visualSize:"icon",onPress:r,className:u("absolute right-2 top-2",t==="primary"?"hover:bg-[var(--page-background)]/20":"hover:bg-[var(--accent-background)]/20",e),"aria-label":"Dismiss notification",children:jsxRuntime.jsx(lucideReact.X,{className:"h-4 w-4","aria-hidden":"true"})})));gt.displayName="CloseButton";var p=new reactStately.ToastQueue({maxVisibleToasts:3}),w=0,L=new Set;function Yt(){w++,L.forEach(t=>t());}function Wt(){w=Math.max(0,w-1),L.forEach(t=>t());}function Z(){return w}function Tt(t){return L.add(t),()=>L.delete(t)}var ht={add:(t,e)=>p.add(t,e),close:t=>{p.close(t);},closeAll:()=>{p.visibleToasts.forEach(t=>{p.close(t.key);});},pauseAll:()=>{p.pauseAll();},resumeAll:()=>{p.resumeAll();},get visibleToasts(){return p.visibleToasts},subscribe:t=>p.subscribe(t),get totalCount(){return w}};function z(){return p}function Xt(t){return t===0?0:Math.max(t,5e3)}function Ft(t={}){return {variant:t.variant??"default",timeout:t.timeout??5e3,onClose:t.onClose,title:t.title,description:t.description,icon:t.icon,showProgress:t.showProgress}}function m(t,e){let r=Ft(e),i=Xt(r.timeout),c="timeout";Yt();let f=ht.add({key:"",content:t,variant:r.variant,timeout:i,onClose:r.onClose,title:r.title,description:r.description,icon:r.icon,showProgress:r.showProgress},{timeout:i,onClose:()=>{Wt(),r.onClose&&r.onClose(f,c);}});return f}m.success=(t,e)=>m(t,{...e,variant:"success"});m.error=(t,e)=>m(t,{...e,variant:"destructive"});m.warning=(t,e)=>m(t,{...e,variant:"warning"});m.info=(t,e)=>m(t,{...e,variant:"info"});var J=react.memo(react.forwardRef(({toast:t,state:e},r)=>{let i=react.useRef(null),c=r||i,{toastProps:f,contentProps:g}=reactAria.useToast({toast:t},e,c),[v,T]=react.useState(null),[n,y]=react.useState(0),[l,h]=react.useState(false),V=50,b=react.useCallback(E=>{let d=E.touches[0];d&&T(d.clientX);},[]),R=react.useCallback(E=>{if(v===null)return;let d=E.touches[0];if(!d)return;let Q=d.clientX-v;Q>0&&y(Q);},[v]),M=react.useCallback(()=>{n>V&&e.close(t.key),y(0),T(null);},[n,e,t.key]),B=react.useCallback(()=>{e.close(t.key);},[e,t.key]),x=react.useCallback(()=>{h(true),"pauseAll"in e&&typeof e.pauseAll=="function"&&e.pauseAll();},[e]),I=react.useCallback(()=>{h(false),"resumeAll"in e&&typeof e.resumeAll=="function"&&e.resumeAll();},[e]),{content:o}=t,S=o.variant??"default",A=o.icon??$t[S]??null,_=o.showProgress??o.timeout>0,O=o.title??(typeof o.content=="string"?o.content:"Notification");return jsxRuntime.jsxs("div",{...f,ref:c,className:u(vt({variant:S})),"aria-label":O,style:{transform:n>0?`translateX(${n}px)`:void 0,opacity:n>0?1-n/200:void 0},onTouchStart:b,onTouchMove:R,onTouchEnd:M,onMouseEnter:x,onMouseLeave:I,children:[A&&jsxRuntime.jsx("div",{className:"flex-shrink-0",children:A}),jsxRuntime.jsxs("div",{...g,className:"flex-1 min-w-0",children:[o.title&&jsxRuntime.jsx("p",{className:"text-sm font-semibold leading-tight",children:o.title}),o.description&&jsxRuntime.jsx("p",{className:"text-sm opacity-80 mt-0.5 leading-tight",children:o.description}),!o.title&&!o.description&&(typeof o.content=="string"?jsxRuntime.jsx("p",{className:"text-sm font-medium",children:o.content}):o.content),(o.title||o.description)&&o.content&&typeof o.content!="string"&&jsxRuntime.jsx("div",{className:"mt-1",children:o.content})]}),jsxRuntime.jsx(gt,{variant:S,onPress:B}),_&&jsxRuntime.jsx(bt,{timeout:o.timeout,isPaused:l,variant:S})]})}));J.displayName="ToastItem";var Ut=zod.z.enum(["timeout","user","programmatic"]),xt=zod.z.enum(["default","primary","destructive","accent","success","warning","info"]),yt=zod.z.enum(["top-left","top-center","top-right","bottom-left","bottom-center","bottom-right"]),qt=zod.z.object({variant:xt.default("default"),timeout:zod.z.number().min(0).default(5e3),onClose:zod.z.function().optional(),title:zod.z.string().optional(),description:zod.z.string().optional(),showProgress:zod.z.boolean().optional()}),tt=zod.z.object({maxVisibleToasts:zod.z.number().min(1).default(3)}),et=zod.z.object({position:yt.default("bottom-right"),"aria-label":zod.z.string().default("Notifications"),className:zod.z.string().optional()});var Zt=react.createContext(null);function St({children:t,maxVisibleToasts:e=3}){tt.parse({maxVisibleToasts:e});let r=react.useMemo(()=>z(),[]);return jsxRuntime.jsx(Zt.Provider,{value:r,children:t})}St.displayName="ToastProvider";function ie({queuedCount:t}){if(t<=0)return null;let e=Math.min(t,2);return jsxRuntime.jsxs("div",{className:"relative w-[380px] pointer-events-none","aria-hidden":"true",children:[jsxRuntime.jsx("div",{className:u("absolute left-1/2 -translate-x-1/2 w-[360px] h-4","rounded-[14px_18px_16px_12px]","bg-[var(--content-background)] border border-[var(--border)]","opacity-60","transition-[opacity,transform] duration-200"),style:{top:0}}),e>=2&&jsxRuntime.jsx("div",{className:u("absolute left-1/2 -translate-x-1/2 w-[340px] h-2","rounded-b-[10px_14px_12px_8px]","bg-[var(--content-background)] border border-t-0 border-[var(--border)]","opacity-40","transition-[opacity,transform] duration-200"),style:{top:14}}),jsxRuntime.jsx("div",{className:"h-4"}),jsxRuntime.jsxs("div",{className:"text-sm text-[var(--content-foreground)] opacity-70 text-center py-2 pointer-events-auto","aria-live":"polite",children:["+",t," more notification",t>1?"s":""]})]})}var Pt=react.memo(react.forwardRef((t,e)=>{let r=et.parse(t),{position:i="bottom-right","aria-label":c="Notifications",className:f}=r,g=react.useRef(null),v=e||g,T=z(),n=reactStately.useToastQueue(T),y=react.useSyncExternalStore(Tt,Z,Z),{regionProps:l}=reactAria.useToastRegion({"aria-label":c},n,v),h=Math.max(0,y-n.visibleToasts.length),V=react.useCallback(()=>{n.visibleToasts.forEach(b=>{n.close(b.key);});},[n]);return n.visibleToasts.length===0?null:jsxRuntime.jsxs("div",{...l,ref:v,className:u(K({position:i}),f),children:[n.visibleToasts.map(b=>jsxRuntime.jsx(J,{toast:b,state:n},b.key)),jsxRuntime.jsx(ie,{queuedCount:h}),n.visibleToasts.length>=2&&jsxRuntime.jsx(P,{variant:"secondary",visualSize:"sm",onPress:V,"aria-label":"Clear all notifications",className:"mt-2 pointer-events-auto",children:"Clear All"})]})}));Pt.displayName="Toaster";exports.DismissReasonSchema=Ut;exports.ToastOptionsSchema=qt;exports.ToastProvider=St;exports.ToastProviderPropsSchema=tt;exports.ToastVariantSchema=xt;exports.Toaster=Pt;exports.ToasterPositionSchema=yt;exports.ToasterPropsSchema=et;exports.toast=m;exports.toastQueue=ht;exports.toastVariants=vt;exports.toasterVariants=K;//# sourceMappingURL=index.js.map
2
+ 'use strict';var react=require('react'),reactAria=require('react-aria'),reactStately=require('react-stately'),classVarianceAuthority=require('class-variance-authority'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),reactAriaComponents=require('react-aria-components'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod');function u(...t){return tailwindMerge.twMerge(clsx.clsx(t))}var $=classVarianceAuthority.cva("inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",{variants:{fullWidth:{true:"w-full",false:""},inVerticalGroup:{true:"items-stretch",false:"items-center"}},defaultVariants:{fullWidth:false,inVerticalGroup:false}}),Y=classVarianceAuthority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer",{variants:{variant:{default:"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1",destructive:"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake",outline:"border border-[var(--input-border)] bg-[var(--content-background)] hover:bg-[var(--accent-background)]/50",secondary:"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]",ghost:"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]",link:"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]"},fullWidth:{true:"w-full",false:""},visualSize:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3 text-xs",lg:"h-11 rounded-md px-6 text-base",icon:"h-10 w-10",dot:"h-5 w-5 rounded-full p-0 min-h-0 min-w-0"},paywall:{true:"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent",false:""}},defaultVariants:{variant:"default",visualSize:"default",paywall:false}});var W="data-[pressed]:scale-[0.97]";var G="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",H="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";var it=react.createContext(null);it.displayName="ButtonGroupContext";function ut(){return react.useContext(it)}var ct=react.createContext(null);ct.displayName="ButtonGroupItemContext";function lt(){return react.useContext(ct)}classVarianceAuthority.cva("inline-flex items-center gap-0",{variants:{orientation:{horizontal:"flex-row",vertical:"flex-col w-full"}},defaultVariants:{orientation:"horizontal"}});var dt=classVarianceAuthority.cva("",{variants:{orientation:{horizontal:"min-w-[44px]",vertical:"flex min-h-[44px]"},position:{first:"",middle:"",last:"",only:""}},compoundVariants:[{orientation:"horizontal",position:"first",className:"rounded-r-none border-r-0"},{orientation:"horizontal",position:"middle",className:"rounded-none border-r-0"},{orientation:"horizontal",position:"last",className:"rounded-l-none"},{orientation:"vertical",position:"first",className:"rounded-b-none border-b-0"},{orientation:"vertical",position:"middle",className:"rounded-none border-b-0"},{orientation:"vertical",position:"last",className:"rounded-t-none"}],defaultVariants:{orientation:"horizontal",position:"only"}});classVarianceAuthority.cva("bg-[var(--border)]",{variants:{orientation:{horizontal:"w-px h-6 mx-1",vertical:"h-px w-full my-1"}},defaultVariants:{orientation:"horizontal"}});var P=react.memo(react.forwardRef(({className:t,buttonVisualClassName:e,variant:r,size:i,visualSize:l,fullWidth:f,loading:g=false,loadingText:v="Loading...",shortcut:T,children:n,isDisabled:y,paywall:c=false,paywallRedirect:h,paywallDescription:V,onPress:b,...R},M)=>{let B=react.useId(),x=ut(),I=lt(),o=r??x?.variant??"default",S=i??x?.size,A=y??x?.isDisabled??false,_=x?.orientation==="vertical",O=f||_,E=I?dt({orientation:x?.orientation??"horizontal",position:I.position}):"",d=l??S??"default";return process.env.NODE_ENV!=="production"&&(d==="dot"||d==="icon")&&!R["aria-label"]&&!n&&console.warn('[Button] visualSize="dot" or "icon" requires aria-label when no visible text is provided (WCAG 1.1.1)'),jsxRuntime.jsx(reactAriaComponents.Button,{ref:M,isDisabled:A||g||void 0,"aria-disabled":c?true:void 0,"aria-describedby":c?B:void 0,onPress:D=>{if(c){h&&window.open(h,"_blank","noopener,noreferrer");return}b?.(D);},className:u($({fullWidth:O,inVerticalGroup:_}),t),...R,children:D=>jsxRuntime.jsxs("span",{className:u(Y({variant:o,visualSize:d,paywall:c,fullWidth:O}),E,e,W,"",G,H),"data-pressed":D.isPressed||void 0,children:[g&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(lucideReact.Loader2,{className:"motion-safe:animate-spin","aria-hidden":"true"}),jsxRuntime.jsx("span",{className:"sr-only","aria-live":"polite",children:v})]}),!g&&n,c&&jsxRuntime.jsx(lucideReact.Zap,{"data-testid":"zap-icon","aria-hidden":"true",className:"ml-1"}),c&&jsxRuntime.jsxs("span",{id:B,className:"sr-only",children:["Premium feature: ",V||"Upgrade required to access this feature"]}),D.isFocusVisible&&T&&jsxRuntime.jsx("kbd",{className:"ml-auto hidden text-xs opacity-60 lg:inline",children:T})]})})}));P.displayName="Button";var vt=classVarianceAuthority.cva(["pointer-events-auto relative flex w-[380px] items-center gap-3","overflow-hidden p-4 pr-12","rounded-[20px_24px_22px_18px]","data-[entering]:toast-animate-in","data-[exiting]:toast-animate-out","motion-reduce:transition-none motion-reduce:animate-none","motion-reduce:!rounded-[20px_24px_22px_18px]","touch-pan-y"],{variants:{variant:{default:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border border-[var(--border)]"],primary:["bg-[var(--primary)]","text-[var(--primary-foreground)]","border border-[var(--primary)]"],destructive:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--destructive-background)]","border border-[var(--border)]"],accent:["bg-[var(--accent-background)]","text-[var(--accent-foreground)]","border border-[var(--accent-background)]"],success:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--success-background)]","border border-[var(--border)]"],warning:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--warning-background)]","border border-[var(--border)]"],info:["bg-[var(--content-background)]","text-[var(--content-foreground)]","border-l-4 border-l-[var(--info-background)]","border border-[var(--border)]"]}},defaultVariants:{variant:"default"}}),K=classVarianceAuthority.cva(["fixed z-50 flex flex-col gap-3 p-4","pointer-events-none","max-h-screen overflow-hidden"],{variants:{position:{"top-left":"top-0 left-0 items-start","top-center":"top-0 left-1/2 -translate-x-1/2 items-center","top-right":"top-0 right-0 items-end","bottom-left":"bottom-0 left-0 items-start","bottom-center":"bottom-0 left-1/2 -translate-x-1/2 items-center","bottom-right":"bottom-0 right-0 items-end"}},defaultVariants:{position:"bottom-right"}}),$t={success:jsxRuntime.jsx(lucideReact.CheckCircle,{className:"h-5 w-5 text-[var(--success-background)]","aria-hidden":"true"}),destructive:jsxRuntime.jsx(lucideReact.XCircle,{className:"h-5 w-5 text-[var(--destructive-background)]","aria-hidden":"true"}),warning:jsxRuntime.jsx(lucideReact.AlertTriangle,{className:"h-5 w-5 text-[var(--warning-background)]","aria-hidden":"true"}),info:jsxRuntime.jsx(lucideReact.Info,{className:"h-5 w-5 text-[var(--info-background)]","aria-hidden":"true"})},bt=react.memo(({timeout:t,isPaused:e,variant:r})=>{if(t===0)return null;let i={default:"bg-[var(--muted-foreground)]",primary:"bg-[var(--primary-foreground)]/50",destructive:"bg-[var(--destructive-background)]",accent:"bg-[var(--accent-foreground)]/50",success:"bg-[var(--success-background)]",warning:"bg-[var(--warning-background)]",info:"bg-[var(--info-background)]"};return jsxRuntime.jsx("div",{className:"absolute bottom-0 left-0 right-0 h-1 overflow-hidden rounded-b-[18px]","aria-hidden":"true",children:jsxRuntime.jsx("div",{className:u("h-full w-full toast-progress-bar opacity-40",i[r]??i.default),style:{animationDuration:`${t}ms`,animationPlayState:e?"paused":"running"}})})});bt.displayName="ProgressBar";var gt=react.memo(react.forwardRef(({variant:t="default",className:e,onPress:r},i)=>jsxRuntime.jsx(P,{ref:i,variant:"ghost",visualSize:"icon",onPress:r,className:u("absolute right-2 top-2",t==="primary"?"hover:bg-[var(--page-background)]/20":"hover:bg-[var(--accent-background)]/20",e),"aria-label":"Dismiss notification",children:jsxRuntime.jsx(lucideReact.X,{className:"h-4 w-4","aria-hidden":"true"})})));gt.displayName="CloseButton";var p=new reactStately.ToastQueue({maxVisibleToasts:3}),w=0,L=new Set;function Yt(){w++,L.forEach(t=>t());}function Wt(){w=Math.max(0,w-1),L.forEach(t=>t());}function Z(){return w}function Tt(t){return L.add(t),()=>L.delete(t)}var ht={add:(t,e)=>p.add(t,e),close:t=>{p.close(t);},closeAll:()=>{p.visibleToasts.forEach(t=>{p.close(t.key);});},pauseAll:()=>{p.pauseAll();},resumeAll:()=>{p.resumeAll();},get visibleToasts(){return p.visibleToasts},subscribe:t=>p.subscribe(t),get totalCount(){return w}};function z(){return p}function Xt(t){return t===0?0:Math.max(t,5e3)}function Ft(t={}){return {variant:t.variant??"default",timeout:t.timeout??5e3,onClose:t.onClose,title:t.title,description:t.description,icon:t.icon,showProgress:t.showProgress}}function m(t,e){let r=Ft(e),i=Xt(r.timeout),l="timeout";Yt();let f=ht.add({key:"",content:t,variant:r.variant,timeout:i,onClose:r.onClose,title:r.title,description:r.description,icon:r.icon,showProgress:r.showProgress},{timeout:i,onClose:()=>{Wt(),r.onClose&&r.onClose(f,l);}});return f}m.success=(t,e)=>m(t,{...e,variant:"success"});m.error=(t,e)=>m(t,{...e,variant:"destructive"});m.warning=(t,e)=>m(t,{...e,variant:"warning"});m.info=(t,e)=>m(t,{...e,variant:"info"});var J=react.memo(react.forwardRef(({toast:t,state:e},r)=>{let i=react.useRef(null),l=r||i,{toastProps:f,contentProps:g}=reactAria.useToast({toast:t},e,l),[v,T]=react.useState(null),[n,y]=react.useState(0),[c,h]=react.useState(false),V=50,b=react.useCallback(E=>{let d=E.touches[0];d&&T(d.clientX);},[]),R=react.useCallback(E=>{if(v===null)return;let d=E.touches[0];if(!d)return;let Q=d.clientX-v;Q>0&&y(Q);},[v]),M=react.useCallback(()=>{n>V&&e.close(t.key),y(0),T(null);},[n,e,t.key]),B=react.useCallback(()=>{e.close(t.key);},[e,t.key]),x=react.useCallback(()=>{h(true),"pauseAll"in e&&typeof e.pauseAll=="function"&&e.pauseAll();},[e]),I=react.useCallback(()=>{h(false),"resumeAll"in e&&typeof e.resumeAll=="function"&&e.resumeAll();},[e]),{content:o}=t,S=o.variant??"default",A=o.icon??$t[S]??null,_=o.showProgress??o.timeout>0,O=o.title??(typeof o.content=="string"?o.content:"Notification");return jsxRuntime.jsxs("div",{...f,ref:l,className:u(vt({variant:S})),"aria-label":O,style:{transform:n>0?`translateX(${n}px)`:void 0,opacity:n>0?1-n/200:void 0},onTouchStart:b,onTouchMove:R,onTouchEnd:M,onMouseEnter:x,onMouseLeave:I,children:[A&&jsxRuntime.jsx("div",{className:"flex-shrink-0",children:A}),jsxRuntime.jsxs("div",{...g,className:"flex-1 min-w-0",children:[o.title&&jsxRuntime.jsx("p",{className:"text-sm font-semibold leading-tight",children:o.title}),o.description&&jsxRuntime.jsx("p",{className:"text-sm opacity-80 mt-0.5 leading-tight",children:o.description}),!o.title&&!o.description&&(typeof o.content=="string"?jsxRuntime.jsx("p",{className:"text-sm font-medium",children:o.content}):o.content),(o.title||o.description)&&o.content&&typeof o.content!="string"&&jsxRuntime.jsx("div",{className:"mt-1",children:o.content})]}),jsxRuntime.jsx(gt,{variant:S,onPress:B}),_&&jsxRuntime.jsx(bt,{timeout:o.timeout,isPaused:c,variant:S})]})}));J.displayName="ToastItem";var Ut=zod.z.enum(["timeout","user","programmatic"]),xt=zod.z.enum(["default","primary","destructive","accent","success","warning","info"]),yt=zod.z.enum(["top-left","top-center","top-right","bottom-left","bottom-center","bottom-right"]),qt=zod.z.object({variant:xt.default("default"),timeout:zod.z.number().min(0).default(5e3),onClose:zod.z.function().optional(),title:zod.z.string().optional(),description:zod.z.string().optional(),showProgress:zod.z.boolean().optional()}),tt=zod.z.object({maxVisibleToasts:zod.z.number().min(1).default(3)}),et=zod.z.object({position:yt.default("bottom-right"),"aria-label":zod.z.string().default("Notifications"),className:zod.z.string().optional()});var Zt=react.createContext(null);function St({children:t,maxVisibleToasts:e=3}){tt.parse({maxVisibleToasts:e});let r=react.useMemo(()=>z(),[]);return jsxRuntime.jsx(Zt.Provider,{value:r,children:t})}St.displayName="ToastProvider";function ie({queuedCount:t}){if(t<=0)return null;let e=Math.min(t,2);return jsxRuntime.jsxs("div",{className:"relative w-[380px] pointer-events-none","aria-hidden":"true",children:[jsxRuntime.jsx("div",{className:u("absolute left-1/2 -translate-x-1/2 w-[360px] h-4","rounded-[14px_18px_16px_12px]","bg-[var(--content-background)] border border-[var(--border)]","opacity-60","transition-[opacity,transform] duration-200"),style:{top:0}}),e>=2&&jsxRuntime.jsx("div",{className:u("absolute left-1/2 -translate-x-1/2 w-[340px] h-2","rounded-b-[10px_14px_12px_8px]","bg-[var(--content-background)] border border-t-0 border-[var(--border)]","opacity-40","transition-[opacity,transform] duration-200"),style:{top:14}}),jsxRuntime.jsx("div",{className:"h-4"}),jsxRuntime.jsxs("div",{className:"text-sm text-[var(--content-foreground)] opacity-70 text-center py-2 pointer-events-auto","aria-live":"polite",children:["+",t," more notification",t>1?"s":""]})]})}var Pt=react.memo(react.forwardRef((t,e)=>{let r=et.parse(t),{position:i="bottom-right","aria-label":l="Notifications",className:f}=r,g=react.useRef(null),v=e||g,T=z(),n=reactStately.useToastQueue(T),y=react.useSyncExternalStore(Tt,Z,Z),{regionProps:c}=reactAria.useToastRegion({"aria-label":l},n,v),h=Math.max(0,y-n.visibleToasts.length),V=react.useCallback(()=>{n.visibleToasts.forEach(b=>{n.close(b.key);});},[n]);return n.visibleToasts.length===0?null:jsxRuntime.jsxs("div",{...c,ref:v,className:u(K({position:i}),f),children:[n.visibleToasts.map(b=>jsxRuntime.jsx(J,{toast:b,state:n},b.key)),jsxRuntime.jsx(ie,{queuedCount:h}),n.visibleToasts.length>=2&&jsxRuntime.jsx(P,{variant:"secondary",visualSize:"sm",onPress:V,"aria-label":"Clear all notifications",className:"mt-2 pointer-events-auto",children:"Clear All"})]})}));Pt.displayName="Toaster";exports.DismissReasonSchema=Ut;exports.ToastOptionsSchema=qt;exports.ToastProvider=St;exports.ToastProviderPropsSchema=tt;exports.ToastVariantSchema=xt;exports.Toaster=Pt;exports.ToasterPositionSchema=yt;exports.ToasterPropsSchema=et;exports.toast=m;exports.toastQueue=ht;exports.toastVariants=vt;exports.toasterVariants=K;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map