@fluencypassdevs/cycle 1.21.1 → 1.27.2

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 (48) hide show
  1. package/bin/components.generated.mjs +2937 -0
  2. package/bin/mcp.mjs +3 -1332
  3. package/dist/chunk-GI7MEYSN.js +163 -0
  4. package/dist/chunk-GI7MEYSN.js.map +1 -0
  5. package/dist/{chunk-LM5ZJFLA.js → chunk-GKJ45JXA.js} +10 -4
  6. package/dist/chunk-GKJ45JXA.js.map +1 -0
  7. package/dist/{chunk-YHCDOHJL.js → chunk-OLYW5LVG.js} +3 -3
  8. package/dist/{chunk-YHCDOHJL.js.map → chunk-OLYW5LVG.js.map} +1 -1
  9. package/dist/chunk-ONEVPGJY.js +152 -0
  10. package/dist/chunk-ONEVPGJY.js.map +1 -0
  11. package/dist/chunk-P7Y2OBHX.js +97 -0
  12. package/dist/chunk-P7Y2OBHX.js.map +1 -0
  13. package/dist/{chunk-UHFMTX23.js → chunk-QXZRH3HU.js} +10 -4
  14. package/dist/chunk-QXZRH3HU.js.map +1 -0
  15. package/dist/chunk-T73O7F3B.js +131 -0
  16. package/dist/chunk-T73O7F3B.js.map +1 -0
  17. package/dist/chunk-WVCNTN4F.js +232 -0
  18. package/dist/chunk-WVCNTN4F.js.map +1 -0
  19. package/dist/composites/chat-thread.js +1 -1
  20. package/dist/index.d.ts +8 -2
  21. package/dist/index.js +32 -27
  22. package/dist/marketing/effects/index.js +2 -2
  23. package/dist/marketing/motion/index.js +2 -2
  24. package/dist/marketing/typography/index.js +1 -1
  25. package/dist/styles/tokens.css +17 -0
  26. package/dist/ui/audio-player.d.ts +17 -3
  27. package/dist/ui/audio-player.js +1 -1
  28. package/dist/ui/chat-panel.js +2 -2
  29. package/dist/ui/command.d.ts +24 -0
  30. package/dist/ui/command.js +12 -0
  31. package/dist/ui/command.js.map +1 -0
  32. package/dist/ui/file-dropzone.d.ts +53 -0
  33. package/dist/ui/file-dropzone.js +12 -0
  34. package/dist/ui/file-dropzone.js.map +1 -0
  35. package/dist/ui/pagination.d.ts +26 -0
  36. package/dist/ui/pagination.js +11 -0
  37. package/dist/ui/pagination.js.map +1 -0
  38. package/dist/ui/stepper.d.ts +33 -0
  39. package/dist/ui/stepper.js +10 -0
  40. package/dist/ui/stepper.js.map +1 -0
  41. package/dist/ui/table.d.ts +13 -0
  42. package/dist/ui/table.js +7 -0
  43. package/dist/ui/table.js.map +1 -0
  44. package/dist/ui/video-player.d.ts +12 -3
  45. package/dist/ui/video-player.js +1 -1
  46. package/package.json +2 -1
  47. package/dist/chunk-LM5ZJFLA.js.map +0 -1
  48. package/dist/chunk-UHFMTX23.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -13,6 +13,11 @@ export { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collap
13
13
  export { Separator } from './ui/separator.js';
14
14
  export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './ui/card.js';
15
15
  export { Breadcrumb, BreadcrumbDot, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbSwitcherTrigger } from './ui/breadcrumb.js';
16
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './ui/table.js';
17
+ export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationLinkProps, PaginationNext, PaginationPrevious } from './ui/pagination.js';
18
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from './ui/command.js';
19
+ export { StepStatus, Stepper, StepperProps, StepperStep } from './ui/stepper.js';
20
+ export { FileDropzone, FileDropzoneItem, FileDropzoneItemProps, FileDropzoneItemStatus, FileDropzoneLabels, FileDropzoneProps, FileRejectionReason, formatFileSize } from './ui/file-dropzone.js';
16
21
  export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants } from './ui/tabs.js';
17
22
  export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from './ui/sheet.js';
18
23
  export { ScrollArea, ScrollBar } from './ui/scroll-area.js';
@@ -40,8 +45,8 @@ export { ChatThread, ChatThreadMessage, ChatThreadMessageStatus, ChatThreadPerso
40
45
  export { ChatPanel, ChatMessage as ChatPanelMessage, ChatPanelProps } from './ui/chat-panel.js';
41
46
  export { LikeDislike, LikeDislikeProps, LikeDislikeValue, likeDislikeVariants } from './ui/like-dislike.js';
42
47
  export { LiveWaiting, LiveWaitingProps } from './ui/live-waiting.js';
43
- export { AudioPlayer, AudioPlayerLabels, AudioPlayerProps, AudioPlayerRef } from './ui/audio-player.js';
44
- export { CaptionTrack, VideoPlayer, VideoPlayerLabels, VideoPlayerProps, VideoPlayerRef } from './ui/video-player.js';
48
+ export { AudioPlayer, AudioPlayerLabels, AudioPlayerProps, AudioPlayerRef, AudioPlayerSrc } from './ui/audio-player.js';
49
+ export { CaptionTrack, VideoPlayer, VideoPlayerLabels, VideoPlayerProps, VideoPlayerRef, VideoPlayerSrc } from './ui/video-player.js';
45
50
  export { PlayerLocale, PlayerLocaleData, VideoDesktopLabels, playerLocales } from './ui/player-i18n.js';
46
51
  export { Toaster, cycleToast } from './ui/sonner.js';
47
52
  export { Alert, AlertAction, AlertClose, AlertDescription, AlertProps, AlertTitle, alertVariants } from './ui/alert.js';
@@ -65,6 +70,7 @@ import 'react/jsx-runtime';
65
70
  import 'class-variance-authority/types';
66
71
  import 'class-variance-authority';
67
72
  import 'radix-ui';
73
+ import 'cmdk';
68
74
  import '@vidstack/react/player/layouts/default';
69
75
  import 'sonner';
70
76
  import 'react-resizable-panels';
package/dist/index.js CHANGED
@@ -1,59 +1,64 @@
1
1
  "use client";
2
- export { ClassLogo, GroupTalkLogo, PrivateTalkLogo, ProductLogo } from './chunk-WZTN5NHK.js';
3
- export { Skeleton } from './chunk-7QFXFNTZ.js';
4
- export { Spinner } from './chunk-TDBDX5NV.js';
5
- export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-AHHT4FZS.js';
6
2
  export { Fab, fabVariants } from './chunk-FQZHCNV7.js';
7
3
  export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger } from './chunk-WNG6RPIA.js';
8
4
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './chunk-UAIVLCPV.js';
9
5
  export { Editor } from './chunk-7I2M55D7.js';
10
6
  import './chunk-JB64LF6D.js';
7
+ export { ClassLogo, GroupTalkLogo, PrivateTalkLogo, ProductLogo } from './chunk-WZTN5NHK.js';
11
8
  export { FluencypassIcon, FluencypassLogo } from './chunk-2SGRMGCM.js';
12
- export { Toaster, cycleToast } from './chunk-7ZSICZXA.js';
13
- export { Alert, AlertAction, AlertClose, AlertDescription, AlertTitle, alertVariants } from './chunk-PS3MV5G7.js';
14
9
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './chunk-U6TIZ4VM.js';
15
10
  export { Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger } from './chunk-LCBAI3A3.js';
16
11
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-6AZLLBX6.js';
17
12
  export { ResizableHandle, ResizablePanel, ResizablePanelGroup } from './chunk-6GP26S4R.js';
18
13
  export { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from './chunk-SDLHXYPS.js';
19
- export { ChatThread } from './chunk-EAVNA2RW.js';
20
- export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger } from './chunk-2KFWBA76.js';
21
- export { SelectorBar } from './chunk-SKBY6OZL.js';
22
- export { ChatPanel } from './chunk-YHCDOHJL.js';
14
+ export { Skeleton } from './chunk-7QFXFNTZ.js';
23
15
  export { LiveWaiting } from './chunk-NKBTC4IF.js';
24
- import './chunk-7FJ7LRSV.js';
25
- export { AudioPlayer } from './chunk-LM5ZJFLA.js';
26
- export { VideoPlayer } from './chunk-UHFMTX23.js';
16
+ export { AudioPlayer } from './chunk-GKJ45JXA.js';
17
+ export { VideoPlayer } from './chunk-QXZRH3HU.js';
27
18
  export { playerLocales } from './chunk-EFT7BHN7.js';
28
- export { Stack } from './chunk-ICNOGTXR.js';
29
- export { Grid, GridItem } from './chunk-325K2R3T.js';
30
- export { FileCard, fileCardVariants } from './chunk-ULVUD6RZ.js';
31
- export { ChatBubble, chatBubbleVariants } from './chunk-VHNPIT56.js';
19
+ export { Toaster, cycleToast } from './chunk-7ZSICZXA.js';
20
+ export { Alert, AlertAction, AlertClose, AlertDescription, AlertTitle, alertVariants } from './chunk-PS3MV5G7.js';
21
+ export { ChatThread } from './chunk-EAVNA2RW.js';
22
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger } from './chunk-2KFWBA76.js';
32
23
  export { ChatAudio, ChatMessage, chatMessageVariants } from './chunk-VUVC2NAK.js';
33
24
  export { LikeDislike, likeDislikeVariants } from './chunk-RPU3FY62.js';
34
- export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage } from './chunk-T2TJG24M.js';
35
25
  export { MessageRating } from './chunk-YIOXPV2N.js';
36
26
  export { MessageBar } from './chunk-TK67WF35.js';
37
- export { Switch, switchVariants } from './chunk-Y5M7UK7R.js';
38
- export { Slider, sliderVariants } from './chunk-6H7AHQ5J.js';
39
- export { Toggle, toggleVariants } from './chunk-FVWCKX3O.js';
40
- export { Progress, indicatorVariants, progressVariants } from './chunk-GDPUWRNH.js';
27
+ export { SelectorBar } from './chunk-SKBY6OZL.js';
28
+ export { ChatPanel } from './chunk-OLYW5LVG.js';
29
+ import './chunk-7FJ7LRSV.js';
30
+ export { ChatBubble, chatBubbleVariants } from './chunk-VHNPIT56.js';
31
+ export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage } from './chunk-T2TJG24M.js';
41
32
  export { ProgressStage } from './chunk-OM4W6UQG.js';
42
33
  export { ProgressDot, dotVariants, progressDotVariants } from './chunk-E7MMJTJY.js';
43
34
  export { CircularProgress, circularProgressVariants } from './chunk-KNJTTOAD.js';
44
35
  export { Container, containerVariants } from './chunk-JRQLKRNY.js';
36
+ export { Stack } from './chunk-ICNOGTXR.js';
37
+ export { Grid, GridItem } from './chunk-325K2R3T.js';
38
+ export { FileCard, fileCardVariants } from './chunk-ULVUD6RZ.js';
39
+ export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants } from './chunk-5TA6AMTY.js';
40
+ export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from './chunk-ULGVGD73.js';
41
+ export { ScrollArea, ScrollBar } from './chunk-6ZID2UNI.js';
42
+ export { Checkbox, checkboxVariants } from './chunk-XNSKKZB6.js';
43
+ export { RadioGroup, RadioGroupItem, radioVariants } from './chunk-3VRHZPW6.js';
44
+ export { Switch, switchVariants } from './chunk-Y5M7UK7R.js';
45
+ export { Slider, sliderVariants } from './chunk-6H7AHQ5J.js';
46
+ export { Toggle, toggleVariants } from './chunk-FVWCKX3O.js';
45
47
  export { Separator } from './chunk-2Z64TSF6.js';
46
48
  export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-JNAJZM2L.js';
47
49
  export { Breadcrumb, BreadcrumbDot, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbSwitcherTrigger } from './chunk-IGK22LGG.js';
50
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './chunk-P7Y2OBHX.js';
51
+ export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from './chunk-T73O7F3B.js';
52
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from './chunk-GI7MEYSN.js';
53
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-AHHT4FZS.js';
54
+ export { Stepper } from './chunk-ONEVPGJY.js';
55
+ export { FileDropzone, FileDropzoneItem, formatFileSize } from './chunk-WVCNTN4F.js';
56
+ export { Spinner } from './chunk-TDBDX5NV.js';
57
+ export { Progress, indicatorVariants, progressVariants } from './chunk-GDPUWRNH.js';
48
58
  import './chunk-N2F3ZG2S.js';
49
59
  export { Achievement, Ai, Answer, Badge as BadgeIcon, Certificate, Chat as ChatIcon, Checkpoint, Completion, Conversation, Course, Deadline, Dialogue, Dictionary, Diploma, DotLive, Exercise, Feedback, Flashcard, Fluency, Goal, Grammar, GroupClass, Highlight, Language, Lesson, Listening, Live, MemoryCard, Milestone, Module, Presentation, PrivateClass, Progress as ProgressIcon, Question, Quiz, Ray, Reading, Recap, RecordedClass, Recurring, Repetition, Required, Schedule, Sentence, Streak, Task, Translate, Unit, Vocabulary, Whiteboard } from './chunk-KLX547KZ.js';
50
60
  export { CycleIcon, ICON_SIZES } from './chunk-US5LXJTO.js';
51
61
  import './chunk-LYTC7UMN.js';
52
- export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants } from './chunk-5TA6AMTY.js';
53
- export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from './chunk-ULGVGD73.js';
54
- export { ScrollArea, ScrollBar } from './chunk-6ZID2UNI.js';
55
- export { Checkbox, checkboxVariants } from './chunk-XNSKKZB6.js';
56
- export { RadioGroup, RadioGroupItem, radioVariants } from './chunk-3VRHZPW6.js';
57
62
  export { Button, buttonVariants } from './chunk-LALM2LHM.js';
58
63
  export { Input } from './chunk-OC5O5LV4.js';
59
64
  export { Textarea } from './chunk-KPE5CRIS.js';
@@ -1,10 +1,10 @@
1
1
  "use client";
2
- export { CircleGlow } from '../../chunk-4MDQXCMY.js';
3
2
  export { CardDarkGlow } from '../../chunk-NEMGLKDF.js';
4
3
  export { Marquee } from '../../chunk-HCVRYT4T.js';
5
- export { MagneticButton } from '../../chunk-QRJ4WJKZ.js';
6
4
  export { RotatingWord } from '../../chunk-X2ZI3JOX.js';
7
5
  export { HandUnderline } from '../../chunk-L6XU524P.js';
6
+ export { MagneticButton } from '../../chunk-QRJ4WJKZ.js';
7
+ export { CircleGlow } from '../../chunk-4MDQXCMY.js';
8
8
  import '../../chunk-2XFXNZNW.js';
9
9
  import '../../chunk-2MBHI4VU.js';
10
10
  import '../../chunk-W4KJCBMW.js';
@@ -1,10 +1,10 @@
1
1
  "use client";
2
- export { AnimatedNumber } from '../../chunk-XKMHNJCL.js';
3
- export { SmoothAnchor } from '../../chunk-GD4HLQDQ.js';
4
2
  export { RevealOnScroll } from '../../chunk-CRZ5YYB7.js';
5
3
  export { StaggerReveal } from '../../chunk-VHHYWRLE.js';
4
+ export { AnimatedNumber } from '../../chunk-XKMHNJCL.js';
6
5
  import '../../chunk-2XFXNZNW.js';
7
6
  import '../../chunk-2MBHI4VU.js';
7
+ export { SmoothAnchor } from '../../chunk-GD4HLQDQ.js';
8
8
  import '../../chunk-W4KJCBMW.js';
9
9
  import '../../chunk-2NMEKWO5.js';
10
10
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- export { SectionSubtitle } from '../../chunk-WAIOC22O.js';
3
2
  export { HeroHeading } from '../../chunk-K2CCV6UB.js';
4
3
  export { SectionHeading } from '../../chunk-IWRXFK4K.js';
5
4
  export { SectionEyebrow } from '../../chunk-WLDNN4UF.js';
5
+ export { SectionSubtitle } from '../../chunk-WAIOC22O.js';
6
6
  import '../../chunk-W4KJCBMW.js';
7
7
  import '../../chunk-2NMEKWO5.js';
8
8
  //# sourceMappingURL=index.js.map
@@ -931,6 +931,12 @@
931
931
  --checkbox-handle-bg: var(--primary-foreground);
932
932
  --divider: 1px solid var(--border);
933
933
  --section-divider: 1px solid var(--border);
934
+ /* O tema default do Vidstack trata este menu como popup FLUTUANTE e termina a
935
+ animação de entrada em `translateY(-24px)` (`theme.css`, "Mobile Popup").
936
+ Aqui ele é uma bottom sheet colada embaixo — sem zerar o offset sobra uma
937
+ faixa de 24px sob a sheet mostrando a página. A animação continua (ela
938
+ interpola de `--exit-transform` até este valor). */
939
+ --enter-transform: translateY(0) !important;
934
940
  }
935
941
 
936
942
  :is(.dark, .light) .vds-menu-items[data-root]:not([data-placement]) {
@@ -976,6 +982,17 @@
976
982
  display: none !important;
977
983
  }
978
984
 
985
+ /* ...mas quando o vídeo não tem faixa de legenda o `DefaultFontMenu` retorna
986
+ `null` (`if (!$hasCaptions) return null`), e aí a regra acima deixaria o
987
+ submenu Acessibilidade completamente vazio — o aluno abre e não vê nada.
988
+ Nesse caso o menu inteiro sai de cena: o `.vds-accessibility-menu` é o
989
+ `Menu.Root`, então esconder ele tira também o item "Acessibilidade" do menu
990
+ raiz. Com legenda anexada nada muda (o `.vds-font-menu` existe). */
991
+
992
+ .vds-accessibility-menu:not(:has(.vds-font-menu)) {
993
+ display: none !important;
994
+ }
995
+
979
996
  /* ─── Legenda no mobile: corpo mínimo legível ─── */
980
997
  /* O tamanho do cue do Vidstack é proporcional à altura do player
981
998
  (`--cue-default-font-size: calc(--overlay-height / 100 * 4.5)`). No player
@@ -12,9 +12,23 @@ interface AudioPlayerLabels {
12
12
  /** Label da velocidade normal no menu (default depende do locale) */
13
13
  speedNormal?: string;
14
14
  }
15
- interface AudioPlayerProps {
16
- /** URL do audio (mp3, ogg, m3u8) */
15
+ /** Fonte de audio: URL string ou objeto com MIME type explicito.
16
+ O Vidstack infere o tipo pela EXTENSAO no path da URL — quando ela nao
17
+ existe (blob: de arquivo local, endpoints sem extensao) ou engana
18
+ (.ogg casa com o regex de VIDEO da lib), o provider de audio nunca
19
+ carrega. Nesses casos, passar { src, type } (ex: type do File.type
20
+ local ou o ContentType salvo no upload). Para `blob:`, qualquer
21
+ `type` serve — o componente normaliza internamente para
22
+ "audio/object" (rota garantida do Vidstack: a decodificacao fica com
23
+ o <audio> nativo, que aceita formatos fora da allowlist da lib,
24
+ como audio/wav de gravacoes). */
25
+ type AudioPlayerSrc = string | {
17
26
  src: string;
27
+ type: string;
28
+ };
29
+ interface AudioPlayerProps {
30
+ /** Fonte do audio: URL (mp3, wav, m4a, m3u8...) ou { src, type } para blob:/URL sem extensao/.ogg */
31
+ src: AudioPlayerSrc;
18
32
  /** Nome da track/aula */
19
33
  title: string;
20
34
  /** Subtitulo / nome do curso */
@@ -49,4 +63,4 @@ interface AudioPlayerProps {
49
63
  }
50
64
  declare const AudioPlayer: React.ForwardRefExoticComponent<AudioPlayerProps & React.RefAttributes<AudioPlayerRef>>;
51
65
 
52
- export { AudioPlayer, type AudioPlayerLabels, type AudioPlayerProps, type AudioPlayerRef };
66
+ export { AudioPlayer, type AudioPlayerLabels, type AudioPlayerProps, type AudioPlayerRef, type AudioPlayerSrc };
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- export { AudioPlayer } from '../chunk-LM5ZJFLA.js';
2
+ export { AudioPlayer } from '../chunk-GKJ45JXA.js';
3
3
  import '../chunk-EFT7BHN7.js';
4
4
  import '../chunk-N2F3ZG2S.js';
5
5
  import '../chunk-KLX547KZ.js';
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- export { ChatPanel } from '../chunk-YHCDOHJL.js';
2
+ export { ChatPanel } from '../chunk-OLYW5LVG.js';
3
3
  import '../chunk-7FJ7LRSV.js';
4
4
  import '../chunk-VHNPIT56.js';
5
5
  import '../chunk-T2TJG24M.js';
6
+ import '../chunk-6ZID2UNI.js';
6
7
  import '../chunk-US5LXJTO.js';
7
8
  import '../chunk-LYTC7UMN.js';
8
- import '../chunk-6ZID2UNI.js';
9
9
  import '../chunk-LALM2LHM.js';
10
10
  import '../chunk-W4KJCBMW.js';
11
11
  import '../chunk-2NMEKWO5.js';
@@ -0,0 +1,24 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { Command as Command$1 } from 'cmdk';
4
+ import { Dialog } from './dialog.js';
5
+ import 'radix-ui';
6
+
7
+ declare function Command({ className, ...props }: React.ComponentProps<typeof Command$1>): react_jsx_runtime.JSX.Element;
8
+ /** Paleta de comandos em modal (Cmd+K). Composta com o Dialog do Cycle. */
9
+ declare function CommandDialog({ title, description, children, className, showCloseButton, ...props }: React.ComponentProps<typeof Dialog> & {
10
+ title?: string;
11
+ description?: string;
12
+ className?: string;
13
+ showCloseButton?: boolean;
14
+ }): react_jsx_runtime.JSX.Element;
15
+ declare function CommandInput({ className, ...props }: React.ComponentProps<typeof Command$1.Input>): react_jsx_runtime.JSX.Element;
16
+ declare function CommandList({ className, ...props }: React.ComponentProps<typeof Command$1.List>): react_jsx_runtime.JSX.Element;
17
+ declare function CommandEmpty({ ...props }: React.ComponentProps<typeof Command$1.Empty>): react_jsx_runtime.JSX.Element;
18
+ declare function CommandGroup({ className, ...props }: React.ComponentProps<typeof Command$1.Group>): react_jsx_runtime.JSX.Element;
19
+ declare function CommandSeparator({ className, ...props }: React.ComponentProps<typeof Command$1.Separator>): react_jsx_runtime.JSX.Element;
20
+ declare function CommandItem({ className, ...props }: React.ComponentProps<typeof Command$1.Item>): react_jsx_runtime.JSX.Element;
21
+ /** Atalho de teclado alinhado a direita do item (ex: ⌘K) */
22
+ declare function CommandShortcut({ className, ...props }: React.ComponentProps<"span">): react_jsx_runtime.JSX.Element;
23
+
24
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from '../chunk-GI7MEYSN.js';
3
+ import '../chunk-AHHT4FZS.js';
4
+ import '../chunk-N2F3ZG2S.js';
5
+ import '../chunk-KLX547KZ.js';
6
+ import '../chunk-US5LXJTO.js';
7
+ import '../chunk-LYTC7UMN.js';
8
+ import '../chunk-LALM2LHM.js';
9
+ import '../chunk-W4KJCBMW.js';
10
+ import '../chunk-2NMEKWO5.js';
11
+ //# sourceMappingURL=command.js.map
12
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"command.js"}
@@ -0,0 +1,53 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ /** Motivo de rejeição na validação de SELEÇÃO (upload é problema do consumidor) */
5
+ type FileRejectionReason = "type" | "size" | "empty" | "count";
6
+ interface FileDropzoneLabels {
7
+ /** Instrução principal (default: "Arraste um arquivo ou clique para selecionar") */
8
+ instruction?: string;
9
+ /** Texto de apoio (ex: "MP3 ou WAV até 20 MB") — default derivado de accept/maxSize */
10
+ hint?: string;
11
+ /** Mensagens de erro por motivo de rejeição */
12
+ errors?: Partial<Record<FileRejectionReason, string>>;
13
+ }
14
+ interface FileDropzoneProps extends Omit<React.ComponentProps<"div">, "onDrop"> {
15
+ /** Tipos aceitos, sintaxe do input nativo (ex: "audio/*,.mp3" ou "image/png,image/jpeg") */
16
+ accept?: string;
17
+ /** Tamanho máximo por arquivo, em bytes */
18
+ maxSize?: number;
19
+ /** Permitir múltiplos arquivos */
20
+ multiple?: boolean;
21
+ /** Máximo de arquivos por seleção (só com multiple) */
22
+ maxFiles?: number;
23
+ disabled?: boolean;
24
+ /** Arquivos que passaram na validação de seleção */
25
+ onFilesAccepted: (files: File[]) => void;
26
+ /** Arquivo rejeitado + motivo (type | size | empty | count) */
27
+ onFileRejected?: (file: File, reason: FileRejectionReason) => void;
28
+ /** Textos customizáveis (defaults PT-BR) */
29
+ labels?: FileDropzoneLabels;
30
+ }
31
+ /** Formata bytes em PT-BR (1,2 MB) */
32
+ declare function formatFileSize(bytes: number): string;
33
+ declare function FileDropzone({ accept, maxSize, multiple, maxFiles, disabled, onFilesAccepted, onFileRejected, labels, className, ...props }: FileDropzoneProps): react_jsx_runtime.JSX.Element;
34
+ type FileDropzoneItemStatus = "idle" | "uploading" | "success" | "error";
35
+ interface FileDropzoneItemProps extends React.ComponentProps<"div"> {
36
+ /** Nome do arquivo */
37
+ name: string;
38
+ /** Tamanho em bytes (formatado em PT-BR) */
39
+ size?: number;
40
+ /** Estado do upload — o upload em si é do consumidor */
41
+ status?: FileDropzoneItemStatus;
42
+ /** Progresso 0–100 (exibido quando status="uploading") */
43
+ progress?: number;
44
+ /** Mensagem exibida quando status="error" */
45
+ error?: string;
46
+ /** Remove o arquivo da lista (também usado para cancelar) */
47
+ onRemove?: () => void;
48
+ /** Label do botão remover (default: "Remover arquivo") */
49
+ removeLabel?: string;
50
+ }
51
+ declare function FileDropzoneItem({ name, size, status, progress, error, onRemove, removeLabel, className, ...props }: FileDropzoneItemProps): react_jsx_runtime.JSX.Element;
52
+
53
+ export { FileDropzone, FileDropzoneItem, type FileDropzoneItemProps, type FileDropzoneItemStatus, type FileDropzoneLabels, type FileDropzoneProps, type FileRejectionReason, formatFileSize };
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ export { FileDropzone, FileDropzoneItem, formatFileSize } from '../chunk-WVCNTN4F.js';
3
+ import '../chunk-TDBDX5NV.js';
4
+ import '../chunk-GDPUWRNH.js';
5
+ import '../chunk-N2F3ZG2S.js';
6
+ import '../chunk-KLX547KZ.js';
7
+ import '../chunk-US5LXJTO.js';
8
+ import '../chunk-LYTC7UMN.js';
9
+ import '../chunk-W4KJCBMW.js';
10
+ import '../chunk-2NMEKWO5.js';
11
+ //# sourceMappingURL=file-dropzone.js.map
12
+ //# sourceMappingURL=file-dropzone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"file-dropzone.js"}
@@ -0,0 +1,26 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ declare function Pagination({ className, ...props }: React.ComponentProps<"nav">): react_jsx_runtime.JSX.Element;
5
+ declare function PaginationContent({ className, ...props }: React.ComponentProps<"ul">): react_jsx_runtime.JSX.Element;
6
+ declare function PaginationItem({ ...props }: React.ComponentProps<"li">): react_jsx_runtime.JSX.Element;
7
+ interface PaginationLinkProps extends React.ComponentProps<"a"> {
8
+ /** Página atual — aplica visual outline + aria-current="page" */
9
+ isActive?: boolean;
10
+ /** Tamanho do botão (tokens do Button) */
11
+ size?: "icon-sm" | "icon" | "sm" | "default";
12
+ /** Renderiza o filho como link (ex: Next <Link>) mantendo o visual */
13
+ asChild?: boolean;
14
+ }
15
+ declare function PaginationLink({ className, isActive, size, asChild, ...props }: PaginationLinkProps): react_jsx_runtime.JSX.Element;
16
+ declare function PaginationPrevious({ className, label, ...props }: PaginationLinkProps & {
17
+ label?: string;
18
+ }): react_jsx_runtime.JSX.Element;
19
+ declare function PaginationNext({ className, label, ...props }: PaginationLinkProps & {
20
+ label?: string;
21
+ }): react_jsx_runtime.JSX.Element;
22
+ declare function PaginationEllipsis({ className, label, ...props }: React.ComponentProps<"span"> & {
23
+ label?: string;
24
+ }): react_jsx_runtime.JSX.Element;
25
+
26
+ export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from '../chunk-T73O7F3B.js';
3
+ import '../chunk-N2F3ZG2S.js';
4
+ import '../chunk-KLX547KZ.js';
5
+ import '../chunk-US5LXJTO.js';
6
+ import '../chunk-LYTC7UMN.js';
7
+ import '../chunk-LALM2LHM.js';
8
+ import '../chunk-W4KJCBMW.js';
9
+ import '../chunk-2NMEKWO5.js';
10
+ //# sourceMappingURL=pagination.js.map
11
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"pagination.js"}
@@ -0,0 +1,33 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as class_variance_authority_types from 'class-variance-authority/types';
3
+ import * as React from 'react';
4
+ import { VariantProps } from 'class-variance-authority';
5
+
6
+ type StepStatus = "completed" | "current" | "upcoming" | "error";
7
+ interface StepperStep {
8
+ /** Rótulo da etapa (ex: "Dados do curso") */
9
+ label: string;
10
+ /** Texto de apoio opcional abaixo do rótulo */
11
+ description?: string;
12
+ }
13
+ declare const stepIndicatorVariants: (props?: ({
14
+ size?: "sm" | "default" | null | undefined;
15
+ status?: "current" | "error" | "completed" | "upcoming" | null | undefined;
16
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
17
+ interface StepperProps extends Omit<React.ComponentProps<"ol">, "onClick">, VariantProps<typeof stepIndicatorVariants> {
18
+ /** Etapas na ordem do fluxo (2–8) */
19
+ steps: StepperStep[];
20
+ /** Índice (0-based) da etapa atual */
21
+ currentStep: number;
22
+ /** Índices de etapas com erro de validação */
23
+ errorSteps?: number[];
24
+ /** Orientação — horizontal (desktop) ou vertical (mobile/sidebars) */
25
+ orientation?: "horizontal" | "vertical";
26
+ /** Classe de tema aplicada apenas nos estados ativos (ex: "theme-class") */
27
+ theme?: string;
28
+ /** Torna etapas CONCLUÍDAS clicáveis para voltar — validação de pulo fica no consumidor */
29
+ onStepClick?: (index: number) => void;
30
+ }
31
+ declare function Stepper({ steps, currentStep, errorSteps, orientation, size, theme, onStepClick, className, ...props }: StepperProps): react_jsx_runtime.JSX.Element;
32
+
33
+ export { type StepStatus, Stepper, type StepperProps, type StepperStep };
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ export { Stepper } from '../chunk-ONEVPGJY.js';
3
+ import '../chunk-N2F3ZG2S.js';
4
+ import '../chunk-KLX547KZ.js';
5
+ import '../chunk-US5LXJTO.js';
6
+ import '../chunk-LYTC7UMN.js';
7
+ import '../chunk-W4KJCBMW.js';
8
+ import '../chunk-2NMEKWO5.js';
9
+ //# sourceMappingURL=stepper.js.map
10
+ //# sourceMappingURL=stepper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"stepper.js"}
@@ -0,0 +1,13 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ declare function Table({ className, ...props }: React.ComponentProps<"table">): react_jsx_runtime.JSX.Element;
5
+ declare function TableHeader({ className, ...props }: React.ComponentProps<"thead">): react_jsx_runtime.JSX.Element;
6
+ declare function TableBody({ className, ...props }: React.ComponentProps<"tbody">): react_jsx_runtime.JSX.Element;
7
+ declare function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">): react_jsx_runtime.JSX.Element;
8
+ declare function TableRow({ className, ...props }: React.ComponentProps<"tr">): react_jsx_runtime.JSX.Element;
9
+ declare function TableHead({ className, ...props }: React.ComponentProps<"th">): react_jsx_runtime.JSX.Element;
10
+ declare function TableCell({ className, ...props }: React.ComponentProps<"td">): react_jsx_runtime.JSX.Element;
11
+ declare function TableCaption({ className, ...props }: React.ComponentProps<"caption">): react_jsx_runtime.JSX.Element;
12
+
13
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from '../chunk-P7Y2OBHX.js';
3
+ import '../chunk-LYTC7UMN.js';
4
+ import '../chunk-W4KJCBMW.js';
5
+ import '../chunk-2NMEKWO5.js';
6
+ //# sourceMappingURL=table.js.map
7
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"table.js"}
@@ -20,9 +20,18 @@ interface VideoPlayerRef {
20
20
  }
21
21
  /** @deprecated Use `Partial<VideoDesktopLabels>` — kept for backward compatibility */
22
22
  type VideoPlayerLabels = Partial<VideoDesktopLabels>;
23
- interface VideoPlayerProps {
24
- /** URL do video (mp4, webm, m3u8 para HLS) */
23
+ /** Fonte de video: URL string ou objeto com MIME type explicito.
24
+ O Vidstack infere o tipo pela EXTENSAO no path da URL — quando ela nao
25
+ existe (blob: de arquivo local, endpoints sem extensao), o provider
26
+ nao carrega. Nesses casos, passar { src, type } (ex: type do File.type
27
+ local ou o ContentType salvo no upload). */
28
+ type VideoPlayerSrc = string | {
25
29
  src: string;
30
+ type: string;
31
+ };
32
+ interface VideoPlayerProps {
33
+ /** Fonte do video: URL (mp4, webm, m3u8 para HLS) ou { src, type } para blob:/URL sem extensao */
34
+ src: VideoPlayerSrc;
26
35
  /** URL da imagem de poster */
27
36
  poster?: string;
28
37
  /** Alt text do poster */
@@ -57,4 +66,4 @@ interface VideoPlayerProps {
57
66
  }
58
67
  declare const VideoPlayer: React.ForwardRefExoticComponent<VideoPlayerProps & React.RefAttributes<VideoPlayerRef>>;
59
68
 
60
- export { type CaptionTrack, VideoPlayer, type VideoPlayerLabels, type VideoPlayerProps, type VideoPlayerRef };
69
+ export { type CaptionTrack, VideoPlayer, type VideoPlayerLabels, type VideoPlayerProps, type VideoPlayerRef, type VideoPlayerSrc };
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- export { VideoPlayer } from '../chunk-UHFMTX23.js';
2
+ export { VideoPlayer } from '../chunk-QXZRH3HU.js';
3
3
  import '../chunk-EFT7BHN7.js';
4
4
  import '../chunk-N2F3ZG2S.js';
5
5
  import '../chunk-KLX547KZ.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluencypassdevs/cycle",
3
- "version": "1.21.1",
3
+ "version": "1.27.2",
4
4
  "description": "Cycle Design System — UI component library by Fluencypass (produto)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -126,6 +126,7 @@
126
126
  "@tiptap/starter-kit": "^3.22.3",
127
127
  "class-variance-authority": "^0.7.1",
128
128
  "clsx": "^2.1.1",
129
+ "cmdk": "^1.1.1",
129
130
  "lucide-react": "^0.577.0",
130
131
  "radix-ui": "^1.4.3",
131
132
  "react-resizable-panels": "^4.7.5",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/ui/audio-player.tsx"],"names":["AudioPlayer"],"mappings":"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","file":"chunk-LM5ZJFLA.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n MediaPlayer,\n MediaProvider,\n TimeSlider,\n VolumeSlider,\n Time,\n PlayButton,\n MuteButton,\n SeekButton,\n useMediaState,\n useMediaRemote,\n type MediaPlayerInstance,\n} from \"@vidstack/react\"\nimport \"@vidstack/react/player/styles/base.css\"\nimport {\n Play,\n Pause,\n Volume2,\n VolumeX,\n Volume1,\n RotateCcw,\n RotateCw,\n Gauge,\n Check,\n} from \"lucide-react\"\nimport { CycleIcon } from \"@/components/icons\"\nimport { cn } from \"@/lib/utils\"\nimport { type PlayerLocale, resolveAudioSpeedNormal } from \"@/components/ui/player-i18n\"\n\n/* ─── Types ─── */\n\nexport interface AudioPlayerRef {\n play(): void\n pause(): void\n readonly currentTime: number\n readonly duration: number\n}\n\nexport interface AudioPlayerLabels {\n /** Label da velocidade normal no menu (default depende do locale) */\n speedNormal?: string\n}\n\nexport interface AudioPlayerProps {\n /** URL do audio (mp3, ogg, m3u8) */\n src: string\n /** Nome da track/aula */\n title: string\n /** Subtitulo / nome do curso */\n subtitle?: string\n /** URL da imagem de capa (variante card) */\n coverArt?: string\n /** Alt text da imagem de capa */\n coverArtAlt?: string\n /** Variante de layout */\n variant?: \"default\" | \"card\"\n /** Icones, textos e sliders em primary-foreground — usar com .theme-* */\n filled?: boolean\n /** Iniciar automaticamente */\n autoPlay?: boolean\n /** Iniciar mutado */\n muted?: boolean\n /** Repetir ao terminar */\n loop?: boolean\n /** Exibir controle de velocidade (default: true — EdTech) */\n showSpeed?: boolean\n /** Tempo inicial em segundos — usado para retomar de onde o usuario parou (resume position) */\n startTime?: number\n /** Idioma dos controles (default: \"pt-BR\"). 13 locales pre-configurados. */\n locale?: PlayerLocale\n /** Overrides pontuais de labels — aplicados em cima do locale selecionado */\n labels?: AudioPlayerLabels\n /** Callback com progresso do audio (currentTime em segundos, duration em segundos) */\n onTimeUpdate?: (currentTime: number, duration: number) => void\n /** Callback disparado quando o audio termina */\n onEnded?: () => void\n className?: string\n}\n\n/* ─── Labels context ─── */\n\nconst AudioLabelsContext = React.createContext<{ speedNormal: string }>({ speedNormal: \"Normal\" })\nfunction useAudioLabels() {\n return React.useContext(AudioLabelsContext)\n}\n\n/* ─── Shared styles ─── */\n\nconst controlBtnClass =\n \"group/btn inline-flex size-9 cursor-pointer items-center justify-center rounded-md text-foreground outline-none transition-colors hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring group-data-[filled]:text-primary-foreground group-data-[filled]:hover:bg-primary-foreground/10\"\n\n/** Play, Pause e Volume usam icones filled (solid) — igual YouTube */\nconst filledIconClass =\n \"fill-current !stroke-transparent text-foreground group-data-[filled]:text-primary-foreground\"\n\nconst outlineIconClass =\n \"text-foreground group-data-[filled]:text-primary-foreground\"\n\n/* ─── Sub-components ─── */\n\nfunction AudioPlayControl() {\n const isPaused = useMediaState(\"paused\")\n return (\n <PlayButton className={controlBtnClass}>\n {isPaused ? (\n <CycleIcon icon={Play} size=\"sm\" decorative className={filledIconClass} />\n ) : (\n <CycleIcon icon={Pause} size=\"sm\" decorative className={filledIconClass} />\n )}\n </PlayButton>\n )\n}\n\nfunction AudioSeekBackwardControl() {\n return (\n <SeekButton className={controlBtnClass} seconds={-10}>\n <CycleIcon icon={RotateCcw} size=\"sm\" decorative className={outlineIconClass} />\n </SeekButton>\n )\n}\n\nfunction AudioSeekForwardControl() {\n return (\n <SeekButton className={controlBtnClass} seconds={10}>\n <CycleIcon icon={RotateCw} size=\"sm\" decorative className={outlineIconClass} />\n </SeekButton>\n )\n}\n\nfunction AudioMuteControl() {\n const volume = useMediaState(\"volume\")\n const isMuted = useMediaState(\"muted\")\n\n const Icon = isMuted || volume === 0 ? VolumeX : volume < 0.5 ? Volume1 : Volume2\n\n return (\n <MuteButton className={controlBtnClass}>\n <CycleIcon icon={Icon} size=\"sm\" decorative className={filledIconClass} />\n </MuteButton>\n )\n}\n\nfunction AudioVolumeControl() {\n return (\n <VolumeSlider.Root className=\"group relative hidden h-9 w-20 cursor-pointer touch-none select-none items-center outline-none sm:inline-flex\">\n <VolumeSlider.Track className=\"relative h-[4px] w-full rounded-full bg-accent group-data-[filled]/root:bg-primary-foreground/30\">\n <VolumeSlider.TrackFill className=\"absolute h-full w-[var(--slider-fill)] rounded-full bg-primary group-data-[filled]/root:bg-primary-foreground\" />\n </VolumeSlider.Track>\n <VolumeSlider.Thumb className=\"absolute left-[var(--slider-fill)] top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary opacity-0 transition-opacity group-data-[active]:opacity-100 group-data-[dragging]:opacity-100 group-data-[filled]/root:bg-primary-foreground\" />\n </VolumeSlider.Root>\n )\n}\n\nfunction AudioSeekBar() {\n return (\n <TimeSlider.Root className=\"group relative inline-flex h-9 w-full cursor-pointer touch-none select-none items-center outline-none\">\n <TimeSlider.Track className=\"relative h-[4px] w-full rounded-full bg-accent group-data-[filled]/root:bg-primary-foreground/30\">\n <TimeSlider.Progress className=\"absolute h-full w-[var(--slider-progress)] rounded-full bg-accent-foreground/20 group-data-[filled]/root:bg-primary-foreground/20\" />\n <TimeSlider.TrackFill className=\"absolute h-full w-[var(--slider-fill)] rounded-full bg-primary group-data-[filled]/root:bg-primary-foreground\" />\n </TimeSlider.Track>\n <TimeSlider.Thumb className=\"absolute left-[var(--slider-fill)] top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary opacity-0 transition-opacity group-data-[active]:opacity-100 group-data-[dragging]:opacity-100 group-data-[filled]/root:bg-primary-foreground\" />\n\n {/* Time preview on hover */}\n <TimeSlider.Preview className=\"pointer-events-none flex flex-col items-center opacity-0 transition-opacity duration-200 data-[visible]:opacity-100\">\n <TimeSlider.Value className=\"rounded bg-popover px-1.5 py-0.5 text-[11px] font-mono text-popover-foreground border border-border shadow-sm\" />\n </TimeSlider.Preview>\n </TimeSlider.Root>\n )\n}\n\nfunction AudioTimeDisplay() {\n return (\n <div className=\"flex items-center gap-1 text-xs font-mono text-muted-foreground tabular-nums group-data-[filled]:text-primary-foreground/80\">\n <Time type=\"current\" />\n <span>/</span>\n <Time type=\"duration\" />\n </div>\n )\n}\n\nfunction AudioSpeedControl() {\n const playbackRate = useMediaState(\"playbackRate\")\n const remote = useMediaRemote()\n const [open, setOpen] = React.useState(false)\n const l = useAudioLabels()\n\n const rates = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className={controlBtnClass}\n >\n {playbackRate === 1 ? (\n <CycleIcon icon={Gauge} size=\"sm\" decorative className={outlineIconClass} />\n ) : (\n <span className=\"text-xs font-mono font-semibold text-foreground group-data-[filled]:text-primary-foreground\">{playbackRate}x</span>\n )}\n </button>\n\n {open && (\n <>\n {/* Backdrop to close */}\n <div className=\"fixed inset-0 z-40\" onClick={() => setOpen(false)} />\n\n <div className=\"absolute bottom-full right-0 z-50 mb-2 min-w-[120px] rounded-lg border border-border bg-popover p-1 shadow-lg\">\n {rates.map((rate) => (\n <button\n key={rate}\n type=\"button\"\n onClick={() => {\n remote.changePlaybackRate(rate)\n setOpen(false)\n }}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-3 py-1.5 text-sm text-popover-foreground/80 transition-colors hover:bg-accent hover:text-popover-foreground\",\n playbackRate === rate && \"text-popover-foreground font-medium\"\n )}\n >\n <span className=\"size-4 flex items-center justify-center\">\n {playbackRate === rate && <CycleIcon icon={Check} size=\"2xs\" decorative className=\"text-popover-foreground\" />}\n </span>\n <span className=\"font-mono\">{rate === 1 ? l.speedNormal : `${rate}x`}</span>\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )\n}\n\n/* ─── Main component ─── */\n\nexport const AudioPlayer = React.forwardRef<AudioPlayerRef, AudioPlayerProps>(\n function AudioPlayer(\n {\n src,\n title,\n subtitle,\n coverArt,\n coverArtAlt = \"\",\n variant = \"default\",\n filled = false,\n autoPlay = false,\n muted = false,\n loop = false,\n showSpeed = true,\n startTime,\n locale = \"pt-BR\",\n labels,\n onTimeUpdate,\n onEnded,\n className,\n },\n ref\n ) {\n const resolvedLabels = React.useMemo(\n () => ({ speedNormal: resolveAudioSpeedNormal(locale, labels?.speedNormal) }),\n [locale, labels]\n )\n const player = React.useRef<MediaPlayerInstance>(null)\n\n React.useImperativeHandle(ref, () => ({\n play() {\n player.current?.play()\n },\n pause() {\n player.current?.pause()\n },\n get currentTime() {\n return player.current?.currentTime ?? 0\n },\n get duration() {\n return player.current?.duration ?? 0\n },\n }))\n\n const handleTimeUpdate = React.useCallback(\n (detail: { currentTime: number }) => {\n if (onTimeUpdate && player.current) {\n onTimeUpdate(detail.currentTime, player.current.duration)\n }\n },\n [onTimeUpdate]\n )\n\n const handleEnded = React.useCallback(() => {\n onEnded?.()\n }, [onEnded])\n\n // Resume position: seek to startTime once the player is ready\n const hasAppliedStartTime = React.useRef(false)\n const handleCanPlay = React.useCallback(() => {\n if (startTime && startTime > 0 && !hasAppliedStartTime.current && player.current) {\n player.current.currentTime = startTime\n hasAppliedStartTime.current = true\n }\n }, [startTime])\n\n const playerEvents = {\n onCanPlay: handleCanPlay,\n ...(onTimeUpdate ? { onTimeUpdate: handleTimeUpdate } : {}),\n ...(onEnded ? { onEnded: handleEnded } : {}),\n }\n\n if (variant === \"card\") {\n return (\n <AudioLabelsContext.Provider value={resolvedLabels}>\n <MediaPlayer\n ref={player}\n src={src}\n autoPlay={autoPlay}\n muted={muted}\n loop={loop}\n viewType=\"audio\"\n data-filled={filled ? \"\" : undefined}\n style={filled ? { '--primary-foreground': 'var(--secondary-foreground)' } as Record<string, string> : undefined}\n className={cn(\n \"group/root group !block w-full rounded-xl border border-border bg-card p-4 shadow-sm md:p-6\",\n className\n )}\n {...playerEvents}\n >\n <MediaProvider className=\"!hidden\" />\n\n {/* Top: cover art + text */}\n <div className=\"flex gap-4 mb-4 md:gap-5 md:mb-6\">\n {coverArt && (\n <img\n src={coverArt}\n alt={coverArtAlt}\n className=\"size-16 shrink-0 rounded-lg object-cover bg-muted md:size-24 md:rounded-xl\"\n />\n )}\n <div className=\"flex min-w-0 flex-col justify-center\">\n <p className={cn(\n \"truncate heading-md md:heading-xl\",\n filled ? \"text-primary-foreground\" : \"text-card-foreground\"\n )}>{title}</p>\n {subtitle && (\n <p className={cn(\n \"truncate body-md md:body-lg\",\n filled ? \"text-primary-foreground/70\" : \"text-muted-foreground\"\n )}>{subtitle}</p>\n )}\n </div>\n </div>\n\n {/* Seek bar */}\n <div className=\"flex w-full items-center\">\n <AudioSeekBar />\n </div>\n\n {/* Time */}\n <div className=\"flex items-center justify-between px-0.5 -mt-1 mb-1 md:mb-2\">\n <div className={cn(\n \"text-[11px] font-mono tabular-nums md:text-xs\",\n filled ? \"text-primary-foreground/80\" : \"text-muted-foreground\"\n )}>\n <Time type=\"current\" />\n </div>\n <div className={cn(\n \"text-[11px] font-mono tabular-nums md:text-xs\",\n filled ? \"text-primary-foreground/80\" : \"text-muted-foreground\"\n )}>\n <Time type=\"duration\" />\n </div>\n </div>\n\n {/* Controls */}\n <div className=\"flex items-center gap-1 md:gap-2\">\n <AudioSeekBackwardControl />\n <AudioPlayControl />\n <AudioSeekForwardControl />\n\n <div className=\"flex-1\" />\n\n {showSpeed && <AudioSpeedControl />}\n <AudioMuteControl />\n <AudioVolumeControl />\n </div>\n </MediaPlayer>\n </AudioLabelsContext.Provider>\n )\n }\n\n // Default variant (compact bar)\n return (\n <AudioLabelsContext.Provider value={resolvedLabels}>\n <MediaPlayer\n ref={player}\n src={src}\n autoPlay={autoPlay}\n muted={muted}\n loop={loop}\n viewType=\"audio\"\n data-filled={filled ? \"\" : undefined}\n style={filled ? { '--primary-foreground': 'var(--secondary-foreground)' } as Record<string, string> : undefined}\n className={cn(\n \"group/root group !flex w-full items-center gap-1.5 rounded-xl border border-border bg-card px-2 py-1.5 shadow-sm\",\n className\n )}\n {...playerEvents}\n >\n <MediaProvider className=\"!hidden\" />\n\n {/* Left controls */}\n <AudioSeekBackwardControl />\n <AudioPlayControl />\n <AudioSeekForwardControl />\n\n {/* Seek bar */}\n <div className=\"flex-1 px-1\">\n <AudioSeekBar />\n </div>\n\n {/* Time */}\n <AudioTimeDisplay />\n\n {/* Right controls */}\n {showSpeed && <AudioSpeedControl />}\n <AudioMuteControl />\n <AudioVolumeControl />\n </MediaPlayer>\n </AudioLabelsContext.Provider>\n )\n }\n)\n"]}