@geekapps/silo-elements-nextjs 0.2.26 → 0.2.28

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.
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo, useRef, useState, useCallback, useEffect } from 'react';
2
2
  import gsap from 'gsap';
3
- import { Play, Rewind, Pause, FastForward, VolumeX, Volume2, Captions, Settings, Minimize, Maximize } from 'lucide-react';
3
+ import { Play, Pause, VolumeX, Volume2, Captions, Settings, Minimize, Maximize } from 'lucide-react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  var AUTO_QUALITY = {
@@ -742,166 +742,167 @@ function Video({
742
742
  {
743
743
  ref: chromeRef,
744
744
  onClick: togglePlay,
745
- className: `absolute inset-0 z-30 flex flex-col justify-between transition-opacity duration-200 ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"}`,
745
+ className: `absolute inset-0 z-30 flex flex-col transition-opacity duration-200 ${isFullscreen ? "justify-between" : "justify-end"} ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"}`,
746
746
  children: [
747
- /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-black/70 to-transparent" }),
747
+ isFullscreen && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-black/70 to-transparent" }),
748
748
  /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-40 bg-linear-to-t from-black/80 to-transparent" }),
749
- /* @__PURE__ */ jsxs("header", { onClick: (e) => e.stopPropagation(), className: "relative z-10 flex items-start justify-between gap-4 px-4 pt-4 text-white @sm:px-7 @sm:pt-7 @lg:px-9 @lg:pt-8", children: [
750
- /* @__PURE__ */ jsxs("div", { children: [
751
- title && isFullscreen && /* @__PURE__ */ jsx("h1", { className: "text-sm font-bold tracking-wide @sm:text-base @md:text-lg @lg:text-xl", style: { textShadow: "0 1px 6px rgba(0,0,0,0.6)" }, children: title }),
752
- description && isFullscreen && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
753
- ] }),
754
- parsed.sources.length > 1 && /* @__PURE__ */ jsx(
755
- "select",
756
- {
757
- value: String(sourceIndex),
758
- onChange: (e) => setSourceIndex(Number(e.target.value)),
759
- "aria-label": "Video source",
760
- className: "h-8 rounded-full border border-white/15 bg-white/10 px-3 text-xs font-semibold text-white outline-none backdrop-blur-md transition hover:bg-white/15",
761
- children: parsed.sources.map((source, index) => /* @__PURE__ */ jsx("option", { value: String(index), className: "text-black", children: source.label ?? source.type ?? `Source ${index + 1}` }, `${source.src}-${index}`))
762
- }
763
- )
764
- ] }),
765
- /* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "relative z-10 px-3 pb-3 text-white @sm:px-5 @sm:pb-5 @lg:px-9 @lg:pb-8", children: [
749
+ isFullscreen && /* @__PURE__ */ jsx("header", { onClick: (e) => e.stopPropagation(), className: "relative z-10 flex items-start px-4 pt-4 text-white @sm:px-7 @sm:pt-7 @lg:px-9 @lg:pt-8", children: /* @__PURE__ */ jsxs("div", { children: [
750
+ title && /* @__PURE__ */ jsx("h1", { className: "text-sm font-bold tracking-wide @sm:text-base @md:text-lg @lg:text-xl", style: { textShadow: "0 1px 6px rgba(0,0,0,0.6)" }, children: title }),
751
+ description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
752
+ ] }) }),
753
+ /* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "relative z-10 px-4 pb-4 text-white", children: [
766
754
  settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
767
755
  /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-40", onClick: () => setSettingsOpen(false) }),
768
- /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-3 z-50 mb-2 w-56 overflow-hidden rounded-xl border border-white/10 bg-black/90 shadow-2xl backdrop-blur-xl @sm:right-5 @lg:right-9", children: [
769
- /* @__PURE__ */ jsxs(
770
- "div",
771
- {
772
- style: {
773
- display: settingsTab === "root" ? "block" : "none",
774
- animation: settingsTab === "root" ? "settingsSlideIn 0.18s ease" : void 0
775
- },
776
- children: [
777
- /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Settings" }),
778
- [
779
- { id: "quality", label: "Quality", value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" },
780
- ...parsed.subtitles.length > 0 ? [{ id: "subtitles", label: "Subtitles / CC", value: subtitleStyle.track === "off" ? "Off" : parsed.subtitles.find((s) => s.srclang === subtitleStyle.track)?.label ?? subtitleStyle.track }] : [],
781
- ...audioTracks.length > 1 ? [{ id: "audio", label: "Audio", value: audioTracks.find((t) => t.id === selectedAudio)?.label ?? "" }] : [],
782
- { id: "playback", label: "Speed", value: playbackRate === 1 ? "Normal" : `${playbackRate}x` }
783
- ].map((item) => /* @__PURE__ */ jsxs(
784
- "button",
785
- {
786
- type: "button",
787
- onClick: () => setSettingsTab(item.id),
788
- className: "flex w-full items-center justify-between gap-3 px-4 py-2.5 text-left text-sm font-medium text-white/80 transition hover:bg-white/10 hover:text-white",
789
- children: [
790
- /* @__PURE__ */ jsx("span", { children: item.label }),
791
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs text-white/40", children: [
792
- item.value,
793
- /* @__PURE__ */ jsx("svg", { className: "size-3.5 opacity-50", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M6 4l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
794
- ] })
795
- ]
796
- },
797
- item.id
798
- ))
799
- ]
800
- },
801
- "root"
802
- ),
803
- ["quality", "subtitles", "audio", "playback"].map((tab) => /* @__PURE__ */ jsxs(
804
- "div",
756
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-0 z-50 mb-2 w-56 overflow-hidden rounded-2xl bg-[#1c1c1e]/95 shadow-2xl backdrop-blur-xl ring-1 ring-white/10", style: { animation: "spFadeIn 0.15s ease" }, children: [
757
+ settingsTab === "root" && /* @__PURE__ */ jsx("div", { children: [
758
+ { id: "quality", label: "Qualidade", value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" },
759
+ ...parsed.subtitles.length > 0 ? [{ id: "subtitles", label: "Legendas", value: subtitleStyle.track === "off" ? "Desligado" : parsed.subtitles.find((s) => s.srclang === subtitleStyle.track)?.label ?? subtitleStyle.track }] : [],
760
+ ...audioTracks.length > 1 ? [{ id: "audio", label: "\xC1udio", value: audioTracks.find((t) => t.id === selectedAudio)?.label ?? "" }] : [],
761
+ { id: "playback", label: "Velocidade", value: playbackRate === 1 ? "Normal" : `${playbackRate}\xD7` }
762
+ ].map((item) => /* @__PURE__ */ jsxs(
763
+ "button",
805
764
  {
806
- style: {
807
- display: settingsTab === tab ? "block" : "none",
808
- animation: settingsTab === tab ? "settingsSlideIn 0.18s ease" : void 0
809
- },
765
+ type: "button",
766
+ onClick: () => setSettingsTab(item.id),
767
+ className: "flex w-full items-center justify-between gap-3 px-4 py-3 text-sm transition hover:bg-white/8 first:pt-3.5 last:pb-3.5",
810
768
  children: [
811
- /* @__PURE__ */ jsxs(
812
- "button",
813
- {
814
- type: "button",
815
- onClick: () => setSettingsTab("root"),
816
- className: "flex w-full items-center gap-2 border-b border-white/10 px-3 py-2.5 text-xs font-semibold text-white/60 transition hover:text-white",
817
- children: [
818
- /* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M10 4L6 8l4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
819
- tab === "quality" ? "Quality" : tab === "subtitles" ? "Subtitles / CC" : tab === "audio" ? "Audio" : "Speed"
820
- ]
821
- }
822
- ),
823
- /* @__PURE__ */ jsxs("div", { className: "max-h-52 overflow-y-auto py-1", children: [
824
- tab === "quality" && [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(SettingsItem, { active: selectedQuality === quality.id, onClick: () => {
825
- changeQuality(quality.id);
826
- setSettingsTab("root");
827
- }, children: [
828
- quality.label,
829
- quality.id === "auto" && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] text-white/40", children: "ABR" })
830
- ] }, quality.id)),
831
- tab === "subtitles" && /* @__PURE__ */ jsxs("div", { className: "px-3 py-2 space-y-3", children: [
832
- /* @__PURE__ */ jsxs("div", { children: [
833
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Track" }),
834
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: [{ srclang: "off", label: "Off" }, ...parsed.subtitles].map((s) => /* @__PURE__ */ jsx(
835
- "button",
836
- {
837
- type: "button",
838
- onClick: () => {
839
- const next = s.srclang === "off" ? "off" : s.srclang;
840
- setSubtitleMode(next);
841
- setSubtitleStyle((st) => ({ ...st, track: next }));
842
- },
843
- className: `rounded-md px-2 py-1 text-xs font-medium transition ${subtitleStyle.track === s.srclang ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
844
- children: s.label
845
- },
846
- s.srclang
847
- )) })
848
- ] }),
849
- /* @__PURE__ */ jsxs("div", { children: [
850
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Size" }),
851
- /* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
852
- "button",
853
- {
854
- type: "button",
855
- onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
856
- className: `rounded-md px-2 py-1 text-xs font-medium capitalize transition ${subtitleStyle.size === s ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
857
- children: s === "xlarge" ? "XL" : s.charAt(0).toUpperCase() + s.slice(1)
858
- },
859
- s
860
- )) })
861
- ] }),
862
- /* @__PURE__ */ jsxs("div", { children: [
863
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Color" }),
864
- /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: [["white", "#fff"], ["yellow", "#facc15"], ["cyan", "#22d3ee"]].map(([c, hex]) => /* @__PURE__ */ jsx(
865
- "button",
866
- {
867
- type: "button",
868
- onClick: () => setSubtitleStyle((st) => ({ ...st, color: c })),
869
- className: `size-5 rounded-full ring-2 transition ${subtitleStyle.color === c ? "ring-white" : "ring-transparent"}`,
870
- style: { backgroundColor: hex }
871
- },
872
- c
873
- )) })
874
- ] }),
875
- /* @__PURE__ */ jsxs("div", { children: [
876
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Background" }),
877
- /* @__PURE__ */ jsx("div", { className: "flex gap-1", children: [["none", "None"], ["semi", "Semi"], ["solid", "Solid"]].map(([v, label]) => /* @__PURE__ */ jsx(
878
- "button",
879
- {
880
- type: "button",
881
- onClick: () => setSubtitleStyle((st) => ({ ...st, bg: v })),
882
- className: `rounded-md px-2 py-1 text-xs font-medium transition ${subtitleStyle.bg === v ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
883
- children: label
884
- },
885
- v
886
- )) })
887
- ] })
888
- ] }),
889
- tab === "audio" && audioTracks.map((track) => /* @__PURE__ */ jsx(SettingsItem, { active: selectedAudio === track.id, onClick: () => {
890
- changeAudio(track.id);
891
- setSettingsTab("root");
892
- }, children: track.label }, track.id)),
893
- tab === "playback" && PLAYBACK_SPEEDS.map((speed) => /* @__PURE__ */ jsx(SettingsItem, { active: playbackRate === speed, onClick: () => {
894
- setPlaybackRate(speed);
895
- setSettingsOpen(false);
896
- setSettingsTab("root");
897
- }, children: speed === 1 ? "Normal" : `${speed}x` }, speed))
769
+ /* @__PURE__ */ jsx("span", { className: "text-white/80", children: item.label }),
770
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-xs text-white/40", children: [
771
+ item.value,
772
+ /* @__PURE__ */ jsx("svg", { className: "size-3 opacity-50", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4.5 3l3 3-3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
898
773
  ] })
899
774
  ]
900
775
  },
901
- tab
902
- ))
776
+ item.id
777
+ )) }),
778
+ settingsTab === "quality" && /* @__PURE__ */ jsxs("div", { children: [
779
+ /* @__PURE__ */ jsxs(
780
+ "button",
781
+ {
782
+ type: "button",
783
+ onClick: () => setSettingsTab("root"),
784
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
785
+ children: [
786
+ /* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M7.5 3L4.5 6l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
787
+ "Qualidade"
788
+ ]
789
+ }
790
+ ),
791
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(
792
+ "button",
793
+ {
794
+ type: "button",
795
+ onClick: () => {
796
+ changeQuality(quality.id);
797
+ setSettingsTab("root");
798
+ },
799
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
800
+ children: [
801
+ /* @__PURE__ */ jsx("svg", { className: `size-4 shrink-0 ${selectedQuality === quality.id ? "text-white" : "text-transparent"}`, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M3 8l3.5 3.5L13 4.5", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
802
+ /* @__PURE__ */ jsxs("span", { className: selectedQuality === quality.id ? "font-semibold text-white" : "text-white/55", children: [
803
+ quality.label,
804
+ quality.id === "auto" ? " (ABR)" : ""
805
+ ] })
806
+ ]
807
+ },
808
+ quality.id
809
+ )) })
810
+ ] }),
811
+ settingsTab === "subtitles" && /* @__PURE__ */ jsxs("div", { children: [
812
+ /* @__PURE__ */ jsxs(
813
+ "button",
814
+ {
815
+ type: "button",
816
+ onClick: () => setSettingsTab("root"),
817
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
818
+ children: [
819
+ /* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M7.5 3L4.5 6l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
820
+ "Legendas"
821
+ ]
822
+ }
823
+ ),
824
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [{ srclang: "off", label: "Desligado" }, ...parsed.subtitles].map((s) => /* @__PURE__ */ jsxs(
825
+ "button",
826
+ {
827
+ type: "button",
828
+ onClick: () => {
829
+ const next = s.srclang === "off" ? "off" : s.srclang;
830
+ setSubtitleMode(next);
831
+ setSubtitleStyle((st) => ({ ...st, track: next }));
832
+ setSettingsTab("root");
833
+ },
834
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
835
+ children: [
836
+ /* @__PURE__ */ jsx("svg", { className: `size-4 shrink-0 ${subtitleStyle.track === s.srclang ? "text-white" : "text-transparent"}`, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M3 8l3.5 3.5L13 4.5", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
837
+ /* @__PURE__ */ jsx("span", { className: subtitleStyle.track === s.srclang ? "font-semibold text-white" : "text-white/55", children: s.label })
838
+ ]
839
+ },
840
+ s.srclang
841
+ )) })
842
+ ] }),
843
+ settingsTab === "audio" && /* @__PURE__ */ jsxs("div", { children: [
844
+ /* @__PURE__ */ jsxs(
845
+ "button",
846
+ {
847
+ type: "button",
848
+ onClick: () => setSettingsTab("root"),
849
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
850
+ children: [
851
+ /* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M7.5 3L4.5 6l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
852
+ "\xC1udio"
853
+ ]
854
+ }
855
+ ),
856
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: audioTracks.map((track) => /* @__PURE__ */ jsxs(
857
+ "button",
858
+ {
859
+ type: "button",
860
+ onClick: () => {
861
+ changeAudio(track.id);
862
+ setSettingsTab("root");
863
+ },
864
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
865
+ children: [
866
+ /* @__PURE__ */ jsx("svg", { className: `size-4 shrink-0 ${selectedAudio === track.id ? "text-white" : "text-transparent"}`, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M3 8l3.5 3.5L13 4.5", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
867
+ /* @__PURE__ */ jsx("span", { className: selectedAudio === track.id ? "font-semibold text-white" : "text-white/55", children: track.label })
868
+ ]
869
+ },
870
+ track.id
871
+ )) })
872
+ ] }),
873
+ settingsTab === "playback" && /* @__PURE__ */ jsxs("div", { children: [
874
+ /* @__PURE__ */ jsxs(
875
+ "button",
876
+ {
877
+ type: "button",
878
+ onClick: () => setSettingsTab("root"),
879
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
880
+ children: [
881
+ /* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M7.5 3L4.5 6l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
882
+ "Velocidade"
883
+ ]
884
+ }
885
+ ),
886
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: PLAYBACK_SPEEDS.map((speed) => /* @__PURE__ */ jsxs(
887
+ "button",
888
+ {
889
+ type: "button",
890
+ onClick: () => {
891
+ setPlaybackRate(speed);
892
+ setSettingsOpen(false);
893
+ setSettingsTab("root");
894
+ },
895
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
896
+ children: [
897
+ /* @__PURE__ */ jsx("svg", { className: `size-4 shrink-0 ${playbackRate === speed ? "text-white" : "text-transparent"}`, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M3 8l3.5 3.5L13 4.5", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
898
+ /* @__PURE__ */ jsx("span", { className: playbackRate === speed ? "font-semibold text-white" : "text-white/55", children: speed === 1 ? "Normal" : `${speed}\xD7` })
899
+ ]
900
+ },
901
+ speed
902
+ )) })
903
+ ] })
903
904
  ] }),
904
- /* @__PURE__ */ jsx("style", { children: `@keyframes settingsSlideIn{from{opacity:0;transform:translateX(8px)}to{opacity:1;transform:translateX(0)}}` })
905
+ /* @__PURE__ */ jsx("style", { children: `@keyframes spFadeIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}` })
905
906
  ] }),
906
907
  /* @__PURE__ */ jsxs(
907
908
  "div",
@@ -910,33 +911,41 @@ function Video({
910
911
  onPointerMove: handleProgressPointerMove,
911
912
  onPointerLeave: handleProgressPointerLeave,
912
913
  onPointerDown: handleProgressPointerDown,
913
- className: "relative mb-3 h-5 cursor-pointer @sm:mb-4 @lg:mb-6",
914
+ className: "group relative mb-2 h-5 cursor-pointer",
914
915
  children: [
915
- preview && /* @__PURE__ */ jsxs(
916
- "div",
917
- {
918
- className: "pointer-events-none absolute bottom-8 z-20 -translate-x-1/2 rounded-lg bg-black/80 p-1 shadow-2xl ring-1 ring-white/15 backdrop-blur",
919
- style: { left: preview.left },
920
- children: [
921
- /* @__PURE__ */ jsx(
922
- "div",
923
- {
924
- className: "overflow-hidden rounded-md bg-neutral-900",
925
- style: {
926
- width: preview.cue.w ?? 160,
927
- height: preview.cue.h ?? 90,
928
- backgroundImage: `url(${preview.cue.image})`,
929
- backgroundPosition: preview.cue.x != null && preview.cue.y != null ? `-${preview.cue.x}px -${preview.cue.y}px` : "center",
930
- backgroundSize: preview.cue.x != null ? "auto" : "cover",
931
- backgroundRepeat: "no-repeat"
916
+ preview && (() => {
917
+ const srcW = preview.cue.w ?? 160;
918
+ const srcH = preview.cue.h ?? 90;
919
+ const aspect = srcW / srcH;
920
+ const thumbH = Math.max(120, Math.min(playerHeight * 0.25, 300));
921
+ const thumbW = Math.round(thumbH * aspect);
922
+ const scale = thumbH / srcH;
923
+ return /* @__PURE__ */ jsxs(
924
+ "div",
925
+ {
926
+ className: "pointer-events-none absolute bottom-10 z-60 -translate-x-1/2 rounded-xl bg-black/80 p-1.5 shadow-2xl ring-1 ring-white/15 backdrop-blur",
927
+ style: { left: preview.left },
928
+ children: [
929
+ /* @__PURE__ */ jsx(
930
+ "div",
931
+ {
932
+ className: "overflow-hidden rounded-lg bg-neutral-900",
933
+ style: {
934
+ width: thumbW,
935
+ height: thumbH,
936
+ backgroundImage: `url(${preview.cue.image})`,
937
+ backgroundPosition: preview.cue.x != null && preview.cue.y != null ? `-${preview.cue.x * scale}px -${preview.cue.y * scale}px` : "center",
938
+ backgroundSize: preview.cue.x != null ? `auto ${thumbH}px` : "cover",
939
+ backgroundRepeat: "no-repeat"
940
+ }
932
941
  }
933
- }
934
- ),
935
- /* @__PURE__ */ jsx("div", { className: "pt-1 text-center text-[11px] font-semibold text-white/80", children: formatTime(preview.time) })
936
- ]
937
- }
938
- ),
939
- /* @__PURE__ */ jsxs("div", { className: "absolute left-0 right-0 top-1/2 h-1 -translate-y-1/2 overflow-hidden rounded-full bg-white/22 @sm:h-1.25", children: [
942
+ ),
943
+ /* @__PURE__ */ jsx("div", { className: "pt-1.5 text-center text-xs font-semibold text-white/80", children: formatTime(preview.time) })
944
+ ]
945
+ }
946
+ );
947
+ })(),
948
+ /* @__PURE__ */ jsxs("div", { className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/22 transition-[height] duration-150 group-hover:h-1", style: { height: "2px" }, children: [
940
949
  /* @__PURE__ */ jsx(
941
950
  "div",
942
951
  {
@@ -955,42 +964,27 @@ function Video({
955
964
  ]
956
965
  }
957
966
  ),
958
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 @sm:gap-4 @lg:gap-5", children: [
959
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 @sm:gap-4 @lg:gap-5", children: [
960
- /* @__PURE__ */ jsx(
961
- "button",
962
- {
963
- type: "button",
964
- onClick: () => seekRelative(-10),
965
- className: "grid size-6 place-items-center text-white transition hover:scale-105 hover:text-white/80 @sm:size-8",
966
- "aria-label": "Rewind 10 seconds",
967
- children: /* @__PURE__ */ jsx(Rewind, { className: "size-4 @sm:size-6" })
968
- }
969
- ),
967
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
968
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 @sm:gap-2", children: [
969
+ /* @__PURE__ */ jsx(SeekButton, { seconds: 15, direction: "back", onClick: () => seekRelative(-15) }),
970
970
  /* @__PURE__ */ jsx(
971
971
  "button",
972
972
  {
973
973
  type: "button",
974
974
  onClick: togglePlay,
975
- className: "grid size-6 place-items-center text-white transition hover:scale-105 hover:text-white/80 @sm:size-8",
975
+ className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
976
976
  "aria-label": isPlaying ? "Pause" : "Play",
977
- children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-4 @sm:size-6" }) : /* @__PURE__ */ jsx(Play, { className: "size-4 @sm:size-6" })
977
+ children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-5 @sm:size-6" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-5 @sm:size-6" })
978
978
  }
979
979
  ),
980
- /* @__PURE__ */ jsx(
981
- "button",
982
- {
983
- type: "button",
984
- onClick: () => seekRelative(10),
985
- className: "grid size-6 place-items-center text-white transition hover:scale-105 hover:text-white/80 @sm:size-8",
986
- "aria-label": "Forward 10 seconds",
987
- children: /* @__PURE__ */ jsx(FastForward, { className: "size-4 @sm:size-6" })
988
- }
989
- ),
990
- /* @__PURE__ */ jsxs("div", { className: "hidden items-center gap-1 text-xs font-semibold text-white/75 @sm:flex @sm:gap-2 @sm:text-sm", children: [
980
+ /* @__PURE__ */ jsx(SeekButton, { seconds: 15, direction: "forward", onClick: () => seekRelative(15) }),
981
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs font-semibold text-white/75 @sm:text-sm", children: [
991
982
  /* @__PURE__ */ jsx("span", { children: formatTime(currentTime) }),
992
983
  /* @__PURE__ */ jsx("span", { className: "text-white/35", children: "/" }),
993
- /* @__PURE__ */ jsx("span", { children: formatTime(duration) })
984
+ /* @__PURE__ */ jsxs("span", { className: "text-white/50", children: [
985
+ "-",
986
+ formatTime(Math.max(0, duration - currentTime))
987
+ ] })
994
988
  ] })
995
989
  ] }),
996
990
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 @sm:gap-1", children: [
@@ -999,9 +993,9 @@ function Video({
999
993
  {
1000
994
  type: "button",
1001
995
  onClick: () => setIsMuted((value) => !value),
1002
- className: "grid size-6 place-items-center text-white transition hover:scale-105 hover:text-white/80 @sm:size-8",
996
+ className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
1003
997
  "aria-label": isMuted ? "Unmute" : "Mute",
1004
- children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-6" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-6" })
998
+ children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-5" })
1005
999
  }
1006
1000
  ),
1007
1001
  /* @__PURE__ */ jsx(
@@ -1027,12 +1021,12 @@ function Video({
1027
1021
  {
1028
1022
  type: "button",
1029
1023
  onClick: () => setSubtitleMode((m) => m === "off" ? parsed.subtitles[0]?.srclang ?? "off" : "off"),
1030
- className: `grid size-6 place-items-center rounded transition hover:text-white/80 @sm:size-8 ${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1024
+ className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1031
1025
  "aria-label": "Captions",
1032
1026
  children: /* @__PURE__ */ jsx(Captions, { className: "size-4 @sm:size-5" })
1033
1027
  }
1034
1028
  ),
1035
- /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
1029
+ /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
1036
1030
  "button",
1037
1031
  {
1038
1032
  type: "button",
@@ -1040,12 +1034,9 @@ function Video({
1040
1034
  setSettingsOpen((v) => !v);
1041
1035
  setSettingsTab("root");
1042
1036
  },
1043
- className: `flex h-6 items-center gap-1 rounded px-1.5 text-xs font-semibold transition hover:text-white/80 @sm:h-8 @sm:px-2 ${settingsOpen ? "text-white" : "text-white/60"}`,
1037
+ className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${settingsOpen ? "text-white" : "text-white/60"}`,
1044
1038
  "aria-label": "Settings",
1045
- children: [
1046
- /* @__PURE__ */ jsx(Settings, { className: "size-3.5 @sm:size-4" }),
1047
- /* @__PURE__ */ jsx("span", { className: "hidden @sm:inline", children: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" })
1048
- ]
1039
+ children: /* @__PURE__ */ jsx(Settings, { className: "size-4 @sm:size-5" })
1049
1040
  }
1050
1041
  ) }),
1051
1042
  /* @__PURE__ */ jsx(
@@ -1053,9 +1044,9 @@ function Video({
1053
1044
  {
1054
1045
  type: "button",
1055
1046
  onClick: toggleFullscreen,
1056
- className: "grid size-6 place-items-center text-white/60 transition hover:scale-105 hover:text-white/80 @sm:size-8",
1047
+ className: "grid size-8 place-items-center text-white/60 transition hover:scale-110 hover:text-white/80 @sm:size-10",
1057
1048
  "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
1058
- children: isFullscreen ? /* @__PURE__ */ jsx(Minimize, { className: "size-5 @sm:size-7" }) : /* @__PURE__ */ jsx(Maximize, { className: "size-5 @sm:size-7" })
1049
+ children: isFullscreen ? /* @__PURE__ */ jsx(Minimize, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Maximize, { className: "size-4 @sm:size-5" })
1059
1050
  }
1060
1051
  )
1061
1052
  ] })
@@ -1075,7 +1066,7 @@ function Video({
1075
1066
  activeCue && /* @__PURE__ */ jsx(
1076
1067
  "div",
1077
1068
  {
1078
- className: `pointer-events-none absolute inset-x-0 z-40 flex justify-center px-4 transition-all duration-200 ${controlsVisible ? "bottom-20 @sm:bottom-24 @lg:bottom-28" : "bottom-4 @sm:bottom-6"}`,
1069
+ className: `pointer-events-none absolute inset-x-0 z-35 flex justify-center px-4 transition-all duration-200 ${controlsVisible ? "bottom-20 @sm:bottom-24 @lg:bottom-28" : "bottom-4 @sm:bottom-6"}`,
1079
1070
  children: /* @__PURE__ */ jsx(
1080
1071
  "div",
1081
1072
  {
@@ -1105,21 +1096,36 @@ function Video({
1105
1096
  );
1106
1097
  }
1107
1098
  var VideoPlayer = Video;
1108
- function SettingsItem({
1109
- children,
1110
- active,
1111
- onClick
1112
- }) {
1113
- return /* @__PURE__ */ jsxs(
1099
+ function SeekButton({ seconds, direction, onClick }) {
1100
+ return /* @__PURE__ */ jsx(
1114
1101
  "button",
1115
1102
  {
1116
1103
  type: "button",
1117
1104
  onClick,
1118
- className: `flex w-full items-center gap-2 px-4 py-2.5 text-left text-base font-medium transition hover:bg-white/10 ${active ? "text-white" : "text-white/55"}`,
1119
- children: [
1120
- /* @__PURE__ */ jsx("span", { className: `size-1.5 rounded-full ${active ? "bg-white" : "bg-transparent"}` }),
1121
- children
1122
- ]
1105
+ className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
1106
+ "aria-label": `${direction === "back" ? "Rewind" : "Forward"} ${seconds} seconds`,
1107
+ children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 36 36", fill: "none", className: "size-7 @sm:size-8", children: [
1108
+ /* @__PURE__ */ jsx(
1109
+ "path",
1110
+ {
1111
+ d: direction === "back" ? "M18 6C11.373 6 6 11.373 6 18s5.373 12 12 12 12-5.373 12-12" : "M18 6C24.627 6 30 11.373 30 18S24.627 30 18 30 6 24.627 6 18",
1112
+ stroke: "currentColor",
1113
+ strokeWidth: "2",
1114
+ strokeLinecap: "round"
1115
+ }
1116
+ ),
1117
+ /* @__PURE__ */ jsx(
1118
+ "path",
1119
+ {
1120
+ d: direction === "back" ? "M18 6l-4 4 4 4" : "M18 6l4 4-4 4",
1121
+ stroke: "currentColor",
1122
+ strokeWidth: "2",
1123
+ strokeLinecap: "round",
1124
+ strokeLinejoin: "round"
1125
+ }
1126
+ ),
1127
+ /* @__PURE__ */ jsx("text", { x: "18", y: "22", textAnchor: "middle", fill: "currentColor", fontSize: "9", fontWeight: "600", fontFamily: "system-ui", children: seconds })
1128
+ ] })
1123
1129
  }
1124
1130
  );
1125
1131
  }