@hydralms/components 0.1.0

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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/dist/assessment-toolbar/assessment-toolbar.d.ts +2 -0
  4. package/dist/assessment-toolbar/index.d.ts +4 -0
  5. package/dist/assessment-toolbar/question-navigator.d.ts +2 -0
  6. package/dist/assessment-toolbar/timer-display.d.ts +2 -0
  7. package/dist/assessment-toolbar/types.d.ts +89 -0
  8. package/dist/common/confirm-dialog.d.ts +2 -0
  9. package/dist/common/due-date-display.d.ts +2 -0
  10. package/dist/common/empty-state.d.ts +2 -0
  11. package/dist/common/index.d.ts +6 -0
  12. package/dist/common/search-input.d.ts +2 -0
  13. package/dist/common/status-badge.d.ts +2 -0
  14. package/dist/common/types.d.ts +124 -0
  15. package/dist/components.css +1 -0
  16. package/dist/content/content-block.d.ts +2 -0
  17. package/dist/content/file-upload-zone.d.ts +2 -0
  18. package/dist/content/index.d.ts +3 -0
  19. package/dist/content/types.d.ts +95 -0
  20. package/dist/curriculum/curriculum-item.d.ts +2 -0
  21. package/dist/curriculum/curriculum-tree.d.ts +2 -0
  22. package/dist/curriculum/index.d.ts +4 -0
  23. package/dist/curriculum/learning-object-icon.d.ts +2 -0
  24. package/dist/curriculum/types.d.ts +79 -0
  25. package/dist/feedback/feedback-banner.d.ts +2 -0
  26. package/dist/feedback/index.d.ts +4 -0
  27. package/dist/feedback/likert-scale.d.ts +2 -0
  28. package/dist/feedback/star-rating.d.ts +2 -0
  29. package/dist/feedback/types.d.ts +83 -0
  30. package/dist/flashcards/flashcard-deck.d.ts +2 -0
  31. package/dist/flashcards/flashcard.d.ts +2 -0
  32. package/dist/flashcards/index.d.ts +3 -0
  33. package/dist/flashcards/types.d.ts +58 -0
  34. package/dist/index.cjs +1 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.js +159 -0
  37. package/dist/lib/utils.d.ts +2 -0
  38. package/dist/progress/grade-indicator.d.ts +2 -0
  39. package/dist/progress/index.d.ts +4 -0
  40. package/dist/progress/progress-ring.d.ts +2 -0
  41. package/dist/progress/stat-card.d.ts +2 -0
  42. package/dist/progress/types.d.ts +73 -0
  43. package/dist/provider/HydraProvider.d.ts +9 -0
  44. package/dist/provider/index.d.ts +2 -0
  45. package/dist/questions/choice.d.ts +11 -0
  46. package/dist/questions/essay.d.ts +11 -0
  47. package/dist/questions/fill-in-the-blank.d.ts +11 -0
  48. package/dist/questions/index.d.ts +7 -0
  49. package/dist/questions/multiple-choice.d.ts +11 -0
  50. package/dist/questions/question-renderer.d.ts +12 -0
  51. package/dist/questions/true-false.d.ts +11 -0
  52. package/dist/questions/types.d.ts +47 -0
  53. package/dist/sections/AnnouncementFeed/AnnouncementFeed.d.ts +2 -0
  54. package/dist/sections/AnnouncementFeed/types.d.ts +52 -0
  55. package/dist/sections/AssessmentReview/AssessmentReview.d.ts +2 -0
  56. package/dist/sections/AssessmentReview/types.d.ts +58 -0
  57. package/dist/sections/AssignmentSubmission/AssignmentSubmission.d.ts +2 -0
  58. package/dist/sections/AssignmentSubmission/types.d.ts +65 -0
  59. package/dist/sections/CertificateViewer/CertificateViewer.d.ts +2 -0
  60. package/dist/sections/CertificateViewer/types.d.ts +47 -0
  61. package/dist/sections/CourseOutline/CourseOutline.d.ts +2 -0
  62. package/dist/sections/CourseOutline/types.d.ts +49 -0
  63. package/dist/sections/DiscussionThread/DiscussionThread.d.ts +2 -0
  64. package/dist/sections/DiscussionThread/types.d.ts +74 -0
  65. package/dist/sections/ExamSession/ExamSession.d.ts +2 -0
  66. package/dist/sections/ExamSession/types.d.ts +62 -0
  67. package/dist/sections/FlashcardStudySession/FlashcardStudySession.d.ts +2 -0
  68. package/dist/sections/FlashcardStudySession/types.d.ts +40 -0
  69. package/dist/sections/GradebookTable/GradebookTable.d.ts +2 -0
  70. package/dist/sections/GradebookTable/types.d.ts +71 -0
  71. package/dist/sections/LecturePlayer/LecturePlayer.d.ts +2 -0
  72. package/dist/sections/LecturePlayer/types.d.ts +47 -0
  73. package/dist/sections/LessonPage/LessonPage.d.ts +2 -0
  74. package/dist/sections/LessonPage/types.d.ts +40 -0
  75. package/dist/sections/PracticeQuiz/PracticeQuiz.d.ts +2 -0
  76. package/dist/sections/PracticeQuiz/types.d.ts +42 -0
  77. package/dist/sections/ProgressDashboard/ProgressDashboard.d.ts +2 -0
  78. package/dist/sections/ProgressDashboard/types.d.ts +73 -0
  79. package/dist/sections/QuizSession/QuizSession.d.ts +2 -0
  80. package/dist/sections/QuizSession/types.d.ts +46 -0
  81. package/dist/sections/ResourceLibrary/ResourceLibrary.d.ts +2 -0
  82. package/dist/sections/ResourceLibrary/types.d.ts +58 -0
  83. package/dist/sections/ScrollableQuiz/ScrollableQuiz.d.ts +2 -0
  84. package/dist/sections/ScrollableQuiz/types.d.ts +42 -0
  85. package/dist/sections/SurveyForm/SurveyForm.d.ts +2 -0
  86. package/dist/sections/SurveyForm/types.d.ts +69 -0
  87. package/dist/sections/index.d.ts +34 -0
  88. package/dist/sections.cjs +1 -0
  89. package/dist/sections.js +1898 -0
  90. package/dist/social/index.d.ts +3 -0
  91. package/dist/social/post-card.d.ts +2 -0
  92. package/dist/social/types.d.ts +59 -0
  93. package/dist/social/user-avatar.d.ts +2 -0
  94. package/dist/table-CW4_BYny.js +9869 -0
  95. package/dist/table-DSBBqb9X.cjs +56 -0
  96. package/dist/ui/alert-dialog.d.ts +14 -0
  97. package/dist/ui/alert.d.ts +9 -0
  98. package/dist/ui/avatar.d.ts +5 -0
  99. package/dist/ui/badge.d.ts +9 -0
  100. package/dist/ui/button.d.ts +10 -0
  101. package/dist/ui/card.d.ts +9 -0
  102. package/dist/ui/index.d.ts +15 -0
  103. package/dist/ui/input.d.ts +3 -0
  104. package/dist/ui/progress.d.ts +13 -0
  105. package/dist/ui/separator.d.ts +6 -0
  106. package/dist/ui/skeleton.d.ts +3 -0
  107. package/dist/ui/slot.d.ts +8 -0
  108. package/dist/ui/table.d.ts +10 -0
  109. package/dist/ui/tabs.d.ts +7 -0
  110. package/dist/ui/textarea.d.ts +3 -0
  111. package/dist/ui/tooltip.d.ts +8 -0
  112. package/dist/utils/debounce.d.ts +1 -0
  113. package/dist/utils/format-duration.d.ts +2 -0
  114. package/dist/video/index.d.ts +2 -0
  115. package/dist/video/types.d.ts +37 -0
  116. package/dist/video/video-player.d.ts +2 -0
  117. package/package.json +94 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 HydraLMS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @hydralms/components
2
+
3
+ A React component library for building learning management systems. 49 composable components and 17 full-page sections built on Tailwind CSS v4 and Base UI.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @hydralms/components
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ ```bash
14
+ pnpm add react react-dom tailwindcss@^4 @base-ui/react
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ Wrap your app with `HydraProvider` and import the stylesheet:
20
+
21
+ ```tsx
22
+ import { HydraProvider } from "@hydralms/components";
23
+ import "@hydralms/components/styles.css";
24
+
25
+ function App() {
26
+ return (
27
+ <HydraProvider>
28
+ <YourApp />
29
+ </HydraProvider>
30
+ );
31
+ }
32
+ ```
33
+
34
+ Import components directly:
35
+
36
+ ```tsx
37
+ import { VideoPlayer, FlashcardDeck, StatusBadge } from "@hydralms/components";
38
+ import { QuizSession, GradebookTable } from "@hydralms/components/sections";
39
+ ```
40
+
41
+ ## What's Included
42
+
43
+ ### Base Components (32)
44
+
45
+ Assessment, quiz questions, curriculum trees, video players, flashcards, progress indicators, feedback controls, and more.
46
+
47
+ ### Page Sections (17)
48
+
49
+ Drop-in LMS features: QuizSession, LecturePlayer, GradebookTable, ProgressDashboard, CourseOutline, AssessmentReview, and more.
50
+
51
+ ## Tailwind CSS v4
52
+
53
+ This library uses Tailwind CSS v4 with design tokens scoped under `.hydra-root`. The `HydraProvider` handles this automatically.
54
+
55
+ ## Documentation
56
+
57
+ Full docs with live demos: [hydralms.com](https://hydralms.com)
58
+
59
+ ## License
60
+
61
+ MIT
@@ -0,0 +1,2 @@
1
+ import { AssessmentToolbarProps } from './types';
2
+ export declare const AssessmentToolbar: ({ currentQuestionIndex, totalQuestions, hasNext, hasPrevious, onNext, onPrevious, onSubmit, timeElapsedSeconds, timeLimitSeconds, questions, onNavigateToQuestion, onToggleFlag, currentQuestionUid, isCompleted, isSubmitting, readOnly, }: AssessmentToolbarProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export { AssessmentToolbar } from './assessment-toolbar';
2
+ export { TimerDisplay } from './timer-display';
3
+ export { QuestionNavigator } from './question-navigator';
4
+ export type { AssessmentToolbarProps, TimerDisplayProps, QuestionNavigatorProps, QuestionNavigatorItem, } from './types';
@@ -0,0 +1,2 @@
1
+ import { QuestionNavigatorProps } from './types';
2
+ export declare const QuestionNavigator: ({ questions, currentQuestionUid, onNavigate, onToggleFlag, readOnly, }: QuestionNavigatorProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { TimerDisplayProps } from './types';
2
+ export declare const TimerDisplay: ({ timeElapsedSeconds, timeLimitSeconds, variant, }: TimerDisplayProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * AssessmentToolbar provides navigation controls, timer, and question overview for quiz/assessment sessions.
3
+ *
4
+ * @example
5
+ * <AssessmentToolbar
6
+ * currentQuestionIndex={0}
7
+ * totalQuestions={10}
8
+ * hasNext
9
+ * hasPrevious={false}
10
+ * onNext={() => setIndex(i => i + 1)}
11
+ * onPrevious={() => setIndex(i => i - 1)}
12
+ * onSubmit={handleSubmit}
13
+ * timeElapsedSeconds={120}
14
+ * timeLimitSeconds={1800}
15
+ * />
16
+ */
17
+ export interface AssessmentToolbarProps {
18
+ /** Zero-based index of the current question */
19
+ currentQuestionIndex: number;
20
+ /** Total number of questions in the assessment */
21
+ totalQuestions: number;
22
+ /** Whether a next question is available */
23
+ hasNext: boolean;
24
+ /** Whether a previous question is available */
25
+ hasPrevious: boolean;
26
+ /** Called when the user clicks Next */
27
+ onNext: () => void;
28
+ /** Called when the user clicks Previous */
29
+ onPrevious: () => void;
30
+ /** Called when the user submits the assessment */
31
+ onSubmit: () => void;
32
+ /** Elapsed time in seconds for the timer display */
33
+ timeElapsedSeconds?: number;
34
+ /** Time limit in seconds — when set, shows countdown instead of elapsed */
35
+ timeLimitSeconds?: number;
36
+ /** List of questions for the navigator chips */
37
+ questions?: QuestionNavigatorItem[];
38
+ /** Called when the user navigates to a specific question via the navigator */
39
+ onNavigateToQuestion?: (questionUid: string) => void;
40
+ /** Called when the user flags or unflags a question */
41
+ onToggleFlag?: (questionUid: string) => void;
42
+ /** UID of the currently active question */
43
+ currentQuestionUid?: string;
44
+ /** Whether the assessment has been completed/submitted */
45
+ isCompleted?: boolean;
46
+ /** Whether the submit action is in progress */
47
+ isSubmitting?: boolean;
48
+ /** When true, disables all interactive controls */
49
+ readOnly?: boolean;
50
+ }
51
+ /**
52
+ * TimerDisplay shows elapsed or remaining time for an assessment.
53
+ *
54
+ * @example
55
+ * <TimerDisplay timeElapsedSeconds={90} timeLimitSeconds={600} variant="compact" />
56
+ */
57
+ export interface TimerDisplayProps {
58
+ /** Total seconds elapsed since the assessment started */
59
+ timeElapsedSeconds: number;
60
+ /** Optional time limit in seconds — enables countdown mode */
61
+ timeLimitSeconds?: number;
62
+ /** Display variant: compact chip or full text */
63
+ variant?: "compact" | "full";
64
+ }
65
+ /**
66
+ * QuestionNavigator renders chip-based navigation for quickly jumping between questions.
67
+ *
68
+ * @example
69
+ * <QuestionNavigator
70
+ * questions={questions}
71
+ * currentQuestionUid={currentUid}
72
+ * onNavigate={handleNavigate}
73
+ * onToggleFlag={handleFlag}
74
+ * />
75
+ */
76
+ export interface QuestionNavigatorProps {
77
+ questions: QuestionNavigatorItem[];
78
+ currentQuestionUid?: string;
79
+ onNavigate?: (questionUid: string) => void;
80
+ onToggleFlag?: (questionUid: string) => void;
81
+ readOnly?: boolean;
82
+ }
83
+ export interface QuestionNavigatorItem {
84
+ uid: string;
85
+ sequence: number;
86
+ isFlagged: boolean;
87
+ isAnswered: boolean;
88
+ isSkipped: boolean;
89
+ }
@@ -0,0 +1,2 @@
1
+ import { ConfirmDialogProps } from './types';
2
+ export declare function ConfirmDialog({ open, title, message, confirmLabel, cancelLabel, confirmColor, onConfirm, onCancel, isLoading, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { DueDateDisplayProps } from './types';
2
+ export declare function DueDateDisplay({ dueDate, submittedDate, showRelative, size, className, style, }: DueDateDisplayProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { EmptyStateProps } from './types';
2
+ export declare function EmptyState({ icon, title, description, action, className, style }: EmptyStateProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ export { EmptyState } from './empty-state';
2
+ export { ConfirmDialog } from './confirm-dialog';
3
+ export { SearchInput } from './search-input';
4
+ export { StatusBadge } from './status-badge';
5
+ export { DueDateDisplay } from './due-date-display';
6
+ export type { EmptyStateProps, ConfirmDialogProps, SearchInputProps, StatusBadgeProps, DueDateDisplayProps, } from './types';
@@ -0,0 +1,2 @@
1
+ import { SearchInputProps } from './types';
2
+ export declare function SearchInput({ value, onChange, placeholder, debounceMs, fullWidth, size, className, style, }: SearchInputProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { StatusBadgeProps } from './types';
2
+ export declare function StatusBadge({ status, colorMap, size, variant, }: StatusBadgeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,124 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * EmptyState displays a centered placeholder with an icon, title, and optional description
4
+ * for empty lists or views.
5
+ *
6
+ * @example
7
+ * <EmptyState
8
+ * title="No announcements"
9
+ * description="Check back later for updates"
10
+ * />
11
+ */
12
+ export interface EmptyStateProps {
13
+ /** Optional icon rendered above the title */
14
+ icon?: ReactNode;
15
+ /** Primary message text */
16
+ title: string;
17
+ /** Secondary descriptive text */
18
+ description?: string;
19
+ /** Optional call-to-action element below the description */
20
+ action?: ReactNode;
21
+ /** CSS class name for the root element */
22
+ className?: string;
23
+ /** Inline styles for the root element */
24
+ style?: React.CSSProperties;
25
+ }
26
+ /**
27
+ * ConfirmDialog renders a modal confirmation dialog with customizable title,
28
+ * message, and confirm/cancel actions.
29
+ *
30
+ * @example
31
+ * <ConfirmDialog
32
+ * open={showDialog}
33
+ * title="Submit exam?"
34
+ * message="You cannot change your answers after submitting."
35
+ * onConfirm={handleSubmit}
36
+ * onCancel={() => setShowDialog(false)}
37
+ * />
38
+ */
39
+ export interface ConfirmDialogProps {
40
+ /** Whether the dialog is open */
41
+ open: boolean;
42
+ /** Dialog title */
43
+ title: string;
44
+ /** Dialog body content */
45
+ message: ReactNode;
46
+ /** Label for the confirm button */
47
+ confirmLabel?: string;
48
+ /** Label for the cancel button */
49
+ cancelLabel?: string;
50
+ /** Color of the confirm button */
51
+ confirmColor?: "primary" | "error" | "warning";
52
+ /** Called when the user confirms */
53
+ onConfirm: () => void;
54
+ /** Called when the user cancels */
55
+ onCancel: () => void;
56
+ /** Whether the confirm action is in progress */
57
+ isLoading?: boolean;
58
+ }
59
+ /**
60
+ * SearchInput provides a debounced text field with a search icon and clear button.
61
+ *
62
+ * @example
63
+ * <SearchInput
64
+ * value={query}
65
+ * onChange={setQuery}
66
+ * placeholder="Search resources..."
67
+ * />
68
+ */
69
+ export interface SearchInputProps {
70
+ /** Current search value */
71
+ value: string;
72
+ /** Called with the new value after debounce */
73
+ onChange: (value: string) => void;
74
+ /** Placeholder text */
75
+ placeholder?: string;
76
+ /** Debounce delay in milliseconds */
77
+ debounceMs?: number;
78
+ /** Whether the input spans full width */
79
+ fullWidth?: boolean;
80
+ /** Input size variant */
81
+ size?: "small" | "medium";
82
+ /** CSS class name for the root element */
83
+ className?: string;
84
+ /** Inline styles for the root element */
85
+ style?: React.CSSProperties;
86
+ }
87
+ /**
88
+ * StatusBadge renders a semantic colored chip for displaying entity statuses
89
+ * such as "submitted", "graded", "late", or "missing".
90
+ *
91
+ * @example
92
+ * <StatusBadge status="submitted" />
93
+ */
94
+ export interface StatusBadgeProps {
95
+ /** Status string to display */
96
+ status: string;
97
+ /** Custom color mapping override — falls back to built-in defaults */
98
+ colorMap?: Record<string, "success" | "error" | "warning" | "info" | "default">;
99
+ /** Chip size */
100
+ size?: "small" | "medium";
101
+ /** Chip variant */
102
+ variant?: "filled" | "outlined";
103
+ }
104
+ /**
105
+ * DueDateDisplay shows a due date with relative time ("in 2 days", "3 days ago")
106
+ * and urgency-based coloring.
107
+ *
108
+ * @example
109
+ * <DueDateDisplay dueDate="2025-03-15T23:59:00Z" />
110
+ */
111
+ export interface DueDateDisplayProps {
112
+ /** Due date as an ISO 8601 string */
113
+ dueDate: string;
114
+ /** Submission date — if provided, shows "submitted" state instead of urgency */
115
+ submittedDate?: string;
116
+ /** Whether to show the relative time label */
117
+ showRelative?: boolean;
118
+ /** Display size */
119
+ size?: "small" | "medium";
120
+ /** CSS class name for the root element */
121
+ className?: string;
122
+ /** Inline styles for the root element */
123
+ style?: React.CSSProperties;
124
+ }
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-950:oklch(27.9% .077 45.635);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-800:oklch(44.8% .119 151.328);--color-green-950:oklch(26.6% .065 152.934);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-800:oklch(43.2% .095 166.913);--color-emerald-950:oklch(26.2% .051 172.552);--color-blue-50:oklch(97% .014 254.604);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-950:oklch(28.2% .091 267.935);--color-violet-50:oklch(96.9% .016 293.756);--color-violet-200:oklch(89.4% .057 293.283);--color-violet-800:oklch(43.2% .232 292.759);--color-violet-950:oklch(28.3% .141 291.089);--color-rose-50:oklch(96.9% .015 12.422);--color-rose-200:oklch(89.2% .058 10.001);--color-rose-800:oklch(45.5% .188 13.697);--color-rose-950:oklch(27.1% .105 12.094);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-1\/2{top:50%}.top-4{top:calc(var(--spacing) * 4)}.-right-0\.5{right:calc(var(--spacing) * -.5)}.right-0{right:calc(var(--spacing) * 0)}.-bottom-0\.5{bottom:calc(var(--spacing) * -.5)}.bottom-0{bottom:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-10{z-index:10}.z-50{z-index:50}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.mx-auto{margin-inline:auto}.my-2{margin-block:calc(var(--spacing) * 2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.-ml-px{margin-left:-1px}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.line-clamp-\(--preview-lines\){-webkit-line-clamp:var(--preview-lines);-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-14{width:calc(var(--spacing) * 14);height:calc(var(--spacing) * 14)}.size-full{width:100%;height:100%}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-5\.5{height:calc(var(--spacing) * 5.5)}.h-6{height:calc(var(--spacing) * 6)}.h-6\.5{height:calc(var(--spacing) * 6.5)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-15{min-height:calc(var(--spacing) * 15)}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-24{min-height:calc(var(--spacing) * 24)}.min-h-30{min-height:calc(var(--spacing) * 30)}.min-h-45{min-height:calc(var(--spacing) * 45)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-50{width:calc(var(--spacing) * 50)}.w-full{width:100%}.w-px{width:1px}.max-w-50{max-width:calc(var(--spacing) * 50)}.max-w-60{max-width:calc(var(--spacing) * 60)}.max-w-80{max-width:calc(var(--spacing) * 80)}.max-w-200{max-width:calc(var(--spacing) * 200)}.max-w-\[360px\]{max-width:360px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-4{min-width:calc(var(--spacing) * 4)}.min-w-9{min-width:calc(var(--spacing) * 9)}.min-w-10{min-width:calc(var(--spacing) * 10)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.transform-\[rotateY\(180deg\)\]{transform:rotateY(180deg)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.grid-cols-\[repeat\(auto-fill\,minmax\(140px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}.grid-cols-\[repeat\(auto-fill\,minmax\(240px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}.grid-cols-\[repeat\(auto-fit\,minmax\(160px\,1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-px{gap:1px}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-t-lg{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[3px\]{border-style:var(--tw-border-style);border-width:3px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-amber-200{border-color:var(--color-amber-200)}.border-background{border-color:var(--background)}.border-blue-200{border-color:var(--color-blue-200)}.border-border{border-color:var(--border)}.border-current{border-color:currentColor}.border-destructive,.border-destructive\/30{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/30{border-color:color-mix(in oklab,var(--destructive) 30%,transparent)}}.border-destructive\/50{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/50{border-color:color-mix(in oklab,var(--destructive) 50%,transparent)}}.border-emerald-200{border-color:var(--color-emerald-200)}.border-green-200{border-color:var(--color-green-200)}.border-info,.border-info\/50{border-color:var(--info)}@supports (color:color-mix(in lab,red,red)){.border-info\/50{border-color:color-mix(in oklab,var(--info) 50%,transparent)}}.border-input{border-color:var(--input)}.border-primary{border-color:var(--primary)}.border-rose-200{border-color:var(--color-rose-200)}.border-success,.border-success\/30{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.border-success\/30{border-color:color-mix(in oklab,var(--success) 30%,transparent)}}.border-success\/50{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.border-success\/50{border-color:color-mix(in oklab,var(--success) 50%,transparent)}}.border-transparent{border-color:#0000}.border-violet-200{border-color:var(--color-violet-200)}.border-warning,.border-warning\/30{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/30{border-color:color-mix(in oklab,var(--warning) 30%,transparent)}}.border-warning\/50{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/50{border-color:color-mix(in oklab,var(--warning) 50%,transparent)}}.border-t-transparent{border-top-color:#0000}.border-l-warning{border-left-color:var(--warning)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-200{background-color:var(--color-amber-200)}.bg-background{background-color:var(--background)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black) 30%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-200{background-color:var(--color-blue-200)}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-destructive,.bg-destructive\/5{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/5{background-color:color-mix(in oklab,var(--destructive) 5%,transparent)}}.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/10{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-200{background-color:var(--color-emerald-200)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-200{background-color:var(--color-green-200)}.bg-info,.bg-info\/5{background-color:var(--info)}@supports (color:color-mix(in lab,red,red)){.bg-info\/5{background-color:color-mix(in oklab,var(--info) 5%,transparent)}}.bg-info\/15{background-color:var(--info)}@supports (color:color-mix(in lab,red,red)){.bg-info\/15{background-color:color-mix(in oklab,var(--info) 15%,transparent)}}.bg-muted{background-color:var(--muted)}.bg-muted-foreground\/10{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.bg-muted-foreground\/10{background-color:color-mix(in oklab,var(--muted-foreground) 10%,transparent)}}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/50{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.bg-primary,.bg-primary\/10{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.bg-primary\/10{background-color:color-mix(in oklab,var(--primary) 10%,transparent)}}.bg-rose-50{background-color:var(--color-rose-50)}.bg-rose-200{background-color:var(--color-rose-200)}.bg-secondary{background-color:var(--secondary)}.bg-success,.bg-success\/5{background-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.bg-success\/5{background-color:color-mix(in oklab,var(--success) 5%,transparent)}}.bg-success\/10{background-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.bg-success\/10{background-color:color-mix(in oklab,var(--success) 10%,transparent)}}.bg-success\/15{background-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.bg-success\/15{background-color:color-mix(in oklab,var(--success) 15%,transparent)}}.bg-transparent{background-color:#0000}.bg-violet-50{background-color:var(--color-violet-50)}.bg-violet-200{background-color:var(--color-violet-200)}.bg-warning,.bg-warning\/5{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.bg-warning\/5{background-color:color-mix(in oklab,var(--warning) 5%,transparent)}}.bg-warning\/10{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.bg-warning\/10{background-color:color-mix(in oklab,var(--warning) 10%,transparent)}}.bg-warning\/15{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.bg-warning\/15{background-color:color-mix(in oklab,var(--warning) 15%,transparent)}}.bg-linear-to-br{--tw-gradient-position:to bottom right}@supports (background-image:linear-gradient(in lab,red,red)){.bg-linear-to-br{--tw-gradient-position:to bottom right in oklab}}.bg-linear-to-br{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-linear-to-t{--tw-gradient-position:to top}@supports (background-image:linear-gradient(in lab,red,red)){.bg-linear-to-t{--tw-gradient-position:to top in oklab}}.bg-linear-to-t{background-image:linear-gradient(var(--tw-gradient-stops))}.from-\[\#fff5f5\]{--tw-gradient-from:#fff5f5;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-\[\#fffbe6\]{--tw-gradient-from:#fffbe6;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-black\/60{--tw-gradient-from:#0009}@supports (color:color-mix(in lab,red,red)){.from-black\/60{--tw-gradient-from:color-mix(in oklab, var(--color-black) 60%, transparent)}}.from-black\/60{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#fee2e2\]{--tw-gradient-to:#fee2e2;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#fff8e1\]{--tw-gradient-to:#fff8e1;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.fill-primary{fill:var(--primary)}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing) * 0)}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-0{padding-inline:calc(var(--spacing) * 0)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[3px\]{--tw-tracking:3px;letter-spacing:3px}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-foreground,.text-foreground\/70{color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.text-foreground\/70{color:color-mix(in oklab,var(--foreground) 70%,transparent)}}.text-info{color:var(--info)}.text-info-foreground{color:var(--info-foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-success{color:var(--success)}.text-success-foreground{color:var(--success-foreground)}.text-warning{color:var(--warning)}.text-warning-foreground{color:var(--warning-foreground)}.text-white{color:var(--color-white)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline-offset-4{text-underline-offset:4px}.accent-primary{accent-color:var(--primary)}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-85{opacity:.85}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.backface-hidden{backface-visibility:hidden}.perspective-\[1000px\]{perspective:1000px}.transform-3d{transform-style:preserve-3d}.selection\:bg-primary ::selection{background-color:var(--primary)}.selection\:bg-primary::selection{background-color:var(--primary)}.selection\:text-primary-foreground ::selection{color:var(--primary-foreground)}.selection\:text-primary-foreground::selection{color:var(--primary-foreground)}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-7::file-selector-button{height:calc(var(--spacing) * 7)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.first\:ml-0:first-child{margin-left:calc(var(--spacing) * 0)}.first\:rounded-l-md:first-child{border-top-left-radius:calc(var(--radius) - 2px);border-bottom-left-radius:calc(var(--radius) - 2px)}.last\:rounded-r-md:last-child{border-top-right-radius:calc(var(--radius) - 2px);border-bottom-right-radius:calc(var(--radius) - 2px)}.focus-within\:border-ring:focus-within{border-color:var(--ring)}.focus-within\:ring-\[3px\]:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\:ring-ring\/50:focus-within{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){.focus-within\:ring-ring\/50:focus-within{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}@media(hover:hover){.hover\:-translate-y-px:hover{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-primary:hover{border-color:var(--primary)}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive) 90%,transparent)}}.hover\:bg-muted:hover,.hover\:bg-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary) 80%,transparent)}}.hover\:bg-warning\/90:hover{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-warning\/90:hover{background-color:color-mix(in oklab,var(--warning) 90%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-warning:hover{color:var(--warning)}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-sm:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}.has-data-\[slot\=card-action\]\:flex-row:has([data-slot=card-action]){flex-direction:row}.has-data-\[slot\=card-action\]\:items-center:has([data-slot=card-action]){align-items:center}.has-data-\[slot\=card-action\]\:justify-between:has([data-slot=card-action]){justify-content:space-between}.has-\[input\:disabled\]\:cursor-default:has(:is(input:disabled)){cursor:default}.has-\[input\:disabled\]\:opacity-60:has(:is(input:disabled)){opacity:.6}.has-\[\>svg\]\:px-1\.5:has(>svg){padding-inline:calc(var(--spacing) * 1.5)}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing) * 3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing) * 4)}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.data-\[ending-style\]\:scale-95[data-ending-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.data-\[ending-style\]\:opacity-0[data-ending-style]{opacity:0}.data-\[selected\]\:border-b-primary[data-selected]{border-bottom-color:var(--primary)}.data-\[selected\]\:text-primary[data-selected]{color:var(--primary)}.data-\[starting-style\]\:scale-95[data-starting-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.data-\[starting-style\]\:opacity-0[data-starting-style]{opacity:0}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@media(min-width:40rem){.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:p-5{padding:calc(var(--spacing) * 5)}.sm\:text-left{text-align:left}}@media(min-width:48rem){.md\:block{display:block}.md\:p-6{padding:calc(var(--spacing) * 6)}}.dark\:border-amber-800:is(.dark *){border-color:var(--color-amber-800)}.dark\:border-blue-800:is(.dark *){border-color:var(--color-blue-800)}.dark\:border-emerald-800:is(.dark *){border-color:var(--color-emerald-800)}.dark\:border-green-800:is(.dark *){border-color:var(--color-green-800)}.dark\:border-input:is(.dark *){border-color:var(--input)}.dark\:border-rose-800:is(.dark *){border-color:var(--color-rose-800)}.dark\:border-violet-800:is(.dark *){border-color:var(--color-violet-800)}.dark\:bg-amber-800:is(.dark *){background-color:var(--color-amber-800)}.dark\:bg-amber-950\/40:is(.dark *){background-color:#46190166}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-amber-950) 40%,transparent)}}.dark\:bg-blue-800:is(.dark *){background-color:var(--color-blue-800)}.dark\:bg-blue-950\/40:is(.dark *){background-color:#16245666}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-950) 40%,transparent)}}.dark\:bg-destructive\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-destructive\/60:is(.dark *){background-color:color-mix(in oklab,var(--destructive) 60%,transparent)}}.dark\:bg-emerald-800:is(.dark *){background-color:var(--color-emerald-800)}.dark\:bg-emerald-950\/40:is(.dark *){background-color:#002c2266}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-emerald-950) 40%,transparent)}}.dark\:bg-green-800:is(.dark *){background-color:var(--color-green-800)}.dark\:bg-green-950\/40:is(.dark *){background-color:#032e1566}@supports (color:color-mix(in lab,red,red)){.dark\:bg-green-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-green-950) 40%,transparent)}}.dark\:bg-input\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-input\/30:is(.dark *){background-color:color-mix(in oklab,var(--input) 30%,transparent)}}.dark\:bg-rose-800:is(.dark *){background-color:var(--color-rose-800)}.dark\:bg-rose-950\/40:is(.dark *){background-color:#4d021866}@supports (color:color-mix(in lab,red,red)){.dark\:bg-rose-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-rose-950) 40%,transparent)}}.dark\:bg-violet-800:is(.dark *){background-color:var(--color-violet-800)}.dark\:bg-violet-950\/40:is(.dark *){background-color:#2f0d6866}@supports (color:color-mix(in lab,red,red)){.dark\:bg-violet-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-violet-950) 40%,transparent)}}@media(hover:hover){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--input) 50%,transparent)}}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.\[\&_ol\]\:pl-\[1\.5em\] ol{padding-left:1.5em}.\[\&_p\]\:mb-\[1\.5em\] p{margin-bottom:1.5em}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&_ul\]\:pl-\[1\.5em\] ul{padding-left:1.5em}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>path\]\:stroke-primary>path{stroke:var(--primary)}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:size-6>svg{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.\[\&\>svg\]\:size-12>svg{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:translate-y-0\.5>svg{--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>svg\]\:text-destructive>svg{color:var(--destructive)}.\[\&\>svg\]\:text-info>svg{color:var(--info)}.\[\&\>svg\]\:text-success>svg{color:var(--success)}.\[\&\>svg\]\:text-warning>svg{color:var(--warning)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}.hydra-root{--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(52% .22 22);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.1% .01 22);--secondary-foreground:oklch(40% .12 22);--muted:oklch(96.1% .005 22);--muted-foreground:oklch(50% .02 22);--accent:oklch(95.2% .012 22);--accent-foreground:oklch(40% .12 22);--destructive:oklch(57.7% .245 27.325);--destructive-foreground:oklch(98.5% 0 0);--border:oklch(90.5% .008 22);--input:oklch(90.5% .008 22);--ring:oklch(52% .22 22);--success:oklch(72.3% .191 142.5);--success-foreground:oklch(96.2% .044 156);--warning:oklch(70.2% .183 55);--warning-foreground:oklch(98% .016 73);--info:oklch(62.3% .214 259);--info-foreground:oklch(97% .014 254);--purple:oklch(62.7% .265 303);--teal:oklch(69.7% .146 182);color:var(--foreground);background:var(--background);font-family:system-ui,-apple-system,sans-serif}.hydra-root.dark,.dark .hydra-root{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% .008 22);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% .008 22);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(68% .2 22);--primary-foreground:oklch(14.5% 0 0);--secondary:oklch(26.9% .015 22);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% .015 22);--muted-foreground:oklch(65% .02 22);--accent:oklch(26.9% .015 22);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--destructive-foreground:oklch(14.5% 0 0);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(68% .2 22);--success:oklch(72.3% .191 142.5);--success-foreground:oklch(15% .05 150);--warning:oklch(70.2% .183 55);--warning-foreground:oklch(15% .05 60);--info:oklch(62.3% .214 259);--info-foreground:oklch(15% .05 255);--purple:oklch(62.7% .265 303);--teal:oklch(69.7% .146 182)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
@@ -0,0 +1,2 @@
1
+ import { ContentBlockProps } from './types';
2
+ export declare function ContentBlock({ block, onQuestionAnswer, readOnly, className, style, }: ContentBlockProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,2 @@
1
+ import { FileUploadZoneProps } from './types';
2
+ export declare function FileUploadZone({ files, onFilesAdded, onFileRemove, accept, maxFiles, maxSizeMB, disabled, label, }: FileUploadZoneProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,3 @@
1
+ export { ContentBlock } from './content-block';
2
+ export { FileUploadZone } from './file-upload-zone';
3
+ export type { LessonBlock, ContentBlockProps, FileUploadZoneProps, } from './types';
@@ -0,0 +1,95 @@
1
+ import { ReactNode } from 'react';
2
+ import { VideoPlayerProps } from '../video/types';
3
+ import { QuestionData, SessionAnswer } from '../questions/types';
4
+ import { FlashcardData } from '../flashcards/types';
5
+ /**
6
+ * A single content block within a lesson page.
7
+ */
8
+ export type LessonBlock = {
9
+ type: "video";
10
+ video: VideoPlayerProps;
11
+ } | {
12
+ type: "richtext";
13
+ html: string;
14
+ } | {
15
+ type: "heading";
16
+ text: string;
17
+ level?: 1 | 2 | 3;
18
+ } | {
19
+ type: "image";
20
+ src: string;
21
+ alt?: string;
22
+ caption?: string;
23
+ } | {
24
+ type: "callout";
25
+ content: string;
26
+ variant?: "info" | "warning" | "tip";
27
+ } | {
28
+ type: "question";
29
+ question: QuestionData;
30
+ } | {
31
+ type: "flashcards";
32
+ cards: FlashcardData[];
33
+ deckName?: string;
34
+ } | {
35
+ type: "divider";
36
+ } | {
37
+ type: "custom";
38
+ render: ReactNode;
39
+ };
40
+ /**
41
+ * ContentBlock renders a single typed content block within a lesson,
42
+ * dispatching to the appropriate component based on the block type.
43
+ *
44
+ * @example
45
+ * <ContentBlock
46
+ * block={{ type: "callout", content: "Remember to save your work!", variant: "tip" }}
47
+ * />
48
+ */
49
+ export interface ContentBlockProps {
50
+ /** The content block to render */
51
+ block: LessonBlock;
52
+ /** Called when the user answers an embedded question */
53
+ onQuestionAnswer?: (questionUid: string, answers: SessionAnswer[]) => void;
54
+ /** When true, disables interactive elements */
55
+ readOnly?: boolean;
56
+ /** CSS class name for the root element */
57
+ className?: string;
58
+ /** Inline styles for the root element */
59
+ style?: React.CSSProperties;
60
+ }
61
+ /**
62
+ * FileUploadZone provides a drag-and-drop file upload area with file list
63
+ * preview, type icons, size display, and remove capability.
64
+ *
65
+ * @example
66
+ * <FileUploadZone
67
+ * files={files}
68
+ * onFilesAdded={(newFiles) => setFiles([...files, ...newFiles])}
69
+ * onFileRemove={(index) => setFiles(files.filter((_, i) => i !== index))}
70
+ * accept=".pdf,.docx"
71
+ * maxFiles={5}
72
+ * />
73
+ */
74
+ export interface FileUploadZoneProps {
75
+ /** Currently selected files */
76
+ files: File[];
77
+ /** Called when new files are added via drop or browse */
78
+ onFilesAdded: (files: File[]) => void;
79
+ /** Called when a file is removed by index */
80
+ onFileRemove: (index: number) => void;
81
+ /** Accepted file types (e.g. ".pdf,.docx") */
82
+ accept?: string;
83
+ /** Maximum number of files allowed */
84
+ maxFiles?: number;
85
+ /** Maximum file size in megabytes */
86
+ maxSizeMB?: number;
87
+ /** Whether the upload zone is disabled */
88
+ disabled?: boolean;
89
+ /** Label text inside the drop zone */
90
+ label?: string;
91
+ /** CSS class name for the root element */
92
+ className?: string;
93
+ /** Inline styles for the root element */
94
+ style?: React.CSSProperties;
95
+ }
@@ -0,0 +1,2 @@
1
+ import { CurriculumItemRowProps } from './types';
2
+ export declare const CurriculumItemRow: ({ item, level, isActive, isCompleted, isExpanded, hasChildren, onToggleExpand, onClick, showDuration, showIcon, showProgress, }: CurriculumItemRowProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { CurriculumTreeProps } from './types';
2
+ export declare const CurriculumTree: ({ items, progress, activeItemUid, onItemClick, readOnly, showDuration, showIcons, showProgress, }: CurriculumTreeProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,4 @@
1
+ export { CurriculumTree } from './curriculum-tree';
2
+ export { CurriculumItemRow } from './curriculum-item';
3
+ export { LearningObjectIcon } from './learning-object-icon';
4
+ export type { CurriculumItem, CurriculumItemProgress, CurriculumTreeProps, CurriculumItemRowProps, LearningObjectIconProps, } from './types';
@@ -0,0 +1,2 @@
1
+ import { LearningObjectIconProps } from './types';
2
+ export declare const LearningObjectIcon: ({ type, size, }: LearningObjectIconProps) => import("react/jsx-runtime").JSX.Element;