pxengine 0.1.117 → 0.1.119

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.
package/dist/index.mjs CHANGED
@@ -15797,6 +15797,10 @@ var RefreshIcon = () => /* @__PURE__ */ jsxs108("svg", { width: "14", height: "1
15797
15797
  /* @__PURE__ */ jsx147("polyline", { points: "23 4 23 10 17 10" }),
15798
15798
  /* @__PURE__ */ jsx147("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
15799
15799
  ] });
15800
+ var EditIcon = () => /* @__PURE__ */ jsxs108("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15801
+ /* @__PURE__ */ jsx147("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
15802
+ /* @__PURE__ */ jsx147("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
15803
+ ] });
15800
15804
  var SlideTypeIcon = () => /* @__PURE__ */ jsxs108("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15801
15805
  /* @__PURE__ */ jsx147("rect", { x: "3", y: "4", width: "18", height: "14", rx: "2" }),
15802
15806
  /* @__PURE__ */ jsx147("line", { x1: "3", y1: "10", x2: "21", y2: "10" })
@@ -15807,6 +15811,7 @@ function formatTemplateLabel(templateId) {
15807
15811
  if (!templateId) return null;
15808
15812
  return templateId.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
15809
15813
  }
15814
+ var Chip = ({ children }) => /* @__PURE__ */ jsx147("span", { className: "inline-flex items-center px-2 h-[22px] rounded-md bg-zinc-800/70 border border-zinc-700/50 text-[11px] font-medium text-zinc-400 whitespace-nowrap", children });
15810
15815
  function deriveJobStatusUrl(newJobId, pollUrl, regenerateUrl) {
15811
15816
  const base = pollUrl?.replace(/\/api\/jobs\/[^/]+\/status.*$/, "") ?? regenerateUrl?.replace(/\/api\/presentations\/[^/]+\/regenerate.*$/, "") ?? "";
15812
15817
  return `${base}/api/jobs/${newJobId}/status`;
@@ -15834,7 +15839,7 @@ var FORMATS = [
15834
15839
  ext: ".html",
15835
15840
  emoji: "\u{1F310}",
15836
15841
  desc: "Interactive web presentation \u2014 download and open in browser",
15837
- accent: { text: "text-indigo-400", bg: "bg-indigo-500/10 border-indigo-500/20" }
15842
+ accent: { text: "text-sky-400", bg: "bg-sky-500/10 border-sky-500/20" }
15838
15843
  }
15839
15844
  ];
15840
15845
  var ExportModal = ({ formats, title, onClose }) => {
@@ -15951,7 +15956,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
15951
15956
  return /* @__PURE__ */ jsxs108("div", { className: "fixed inset-0 z-50 bg-black flex flex-col", children: [
15952
15957
  /* @__PURE__ */ jsxs108("div", { className: "flex items-center justify-between gap-4 px-4 h-11 bg-zinc-950/90 border-b border-zinc-800/60 flex-shrink-0", children: [
15953
15958
  /* @__PURE__ */ jsxs108("div", { className: "flex items-center gap-3 min-w-0", children: [
15954
- /* @__PURE__ */ jsx147("span", { className: "text-indigo-400 flex-shrink-0", children: /* @__PURE__ */ jsx147(SlidesIcon, {}) }),
15959
+ /* @__PURE__ */ jsx147("span", { className: "text-[#DCC99B] flex-shrink-0", children: /* @__PURE__ */ jsx147(SlidesIcon, {}) }),
15955
15960
  /* @__PURE__ */ jsx147("span", { className: "text-sm font-medium text-zinc-300 truncate", children: title }),
15956
15961
  slideCount > 0 && /* @__PURE__ */ jsxs108("span", { className: "text-xs text-zinc-600 flex-shrink-0", children: [
15957
15962
  currentSlide,
@@ -15965,7 +15970,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
15965
15970
  {
15966
15971
  onClick: () => sendSlideCommand("prevSlide"),
15967
15972
  disabled: !iframeReady,
15968
- className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-indigo-500 hover:text-indigo-400 text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
15973
+ className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
15969
15974
  "aria-label": "Previous slide",
15970
15975
  children: /* @__PURE__ */ jsx147(ChevronLeft2, {})
15971
15976
  }
@@ -15975,7 +15980,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
15975
15980
  {
15976
15981
  onClick: () => sendSlideCommand("nextSlide"),
15977
15982
  disabled: !iframeReady,
15978
- className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-indigo-500 hover:text-indigo-400 text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
15983
+ className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
15979
15984
  "aria-label": "Next slide",
15980
15985
  children: /* @__PURE__ */ jsx147(ChevronRight2, {})
15981
15986
  }
@@ -16551,11 +16556,11 @@ var PresentationJobCard = ({
16551
16556
  /* @__PURE__ */ jsx147(
16552
16557
  "div",
16553
16558
  {
16554
- className: "h-[3px] bg-gradient-to-r from-indigo-500 via-purple-500 to-indigo-500 bg-[length:200%_100%] animate-[gradient-shift_2s_ease-in-out_infinite]",
16559
+ className: "h-[3px]",
16555
16560
  style: {
16561
+ backgroundImage: accentGradient || "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B, #C0AE82, #8B7D5E)",
16556
16562
  backgroundSize: "200% 100%",
16557
- animation: "gradient-shift 2s ease-in-out infinite",
16558
- ...accentGradient ? { backgroundImage: accentGradient } : {}
16563
+ animation: "gradient-shift 2s ease-in-out infinite"
16559
16564
  }
16560
16565
  }
16561
16566
  ),
@@ -16564,7 +16569,7 @@ var PresentationJobCard = ({
16564
16569
  /* @__PURE__ */ jsx147(
16565
16570
  "div",
16566
16571
  {
16567
- className: "w-10 h-10 rounded-xl bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center flex-shrink-0",
16572
+ className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0",
16568
16573
  style: { ...t.accentSubtle(0.1), ...t.accentBorder },
16569
16574
  children: /* @__PURE__ */ jsx147("span", { className: "text-lg", children: getPhaseIcon() })
16570
16575
  }
@@ -16582,10 +16587,11 @@ var PresentationJobCard = ({
16582
16587
  /* @__PURE__ */ jsx147("div", { className: "h-2 bg-zinc-800 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx147(
16583
16588
  "div",
16584
16589
  {
16585
- className: "h-full bg-gradient-to-r from-indigo-500 to-purple-500 rounded-full transition-all duration-500 ease-out",
16590
+ className: "h-full rounded-full transition-all duration-500 ease-out",
16586
16591
  style: {
16587
16592
  width: `${Math.max(pct, 2)}%`,
16588
- ...accentGradient ? { backgroundImage: accentGradient } : t.accentBg
16593
+ backgroundImage: accentGradient || "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)",
16594
+ ...!accentGradient ? t.accentBg : {}
16589
16595
  }
16590
16596
  }
16591
16597
  ) }),
@@ -16595,7 +16601,7 @@ var PresentationJobCard = ({
16595
16601
  ] })
16596
16602
  ] }),
16597
16603
  /* @__PURE__ */ jsxs108("div", { className: "flex items-center gap-2", children: [
16598
- /* @__PURE__ */ jsx147("div", { className: "w-2 h-2 rounded-full bg-indigo-500 animate-pulse", style: t.accentBg }),
16604
+ /* @__PURE__ */ jsx147("div", { className: "w-2 h-2 rounded-full bg-[#C0AE82] animate-pulse", style: t.accentBg }),
16599
16605
  /* @__PURE__ */ jsx147("span", { className: "text-xs text-zinc-400", children: step })
16600
16606
  ] }),
16601
16607
  phase === "ai_generation" && slidesTotal > 0 && /* @__PURE__ */ jsxs108("div", { className: "flex items-center gap-2 pt-1", children: [
@@ -16604,7 +16610,7 @@ var PresentationJobCard = ({
16604
16610
  {
16605
16611
  className: cn(
16606
16612
  "w-6 h-1.5 rounded-full transition-all duration-300",
16607
- i < slidesCompleted ? "bg-indigo-500" : i === slidesCompleted ? "bg-indigo-500/50 animate-pulse" : "bg-zinc-700"
16613
+ i < slidesCompleted ? "bg-[#C0AE82]" : i === slidesCompleted ? "bg-[#C0AE82]/50 animate-pulse" : "bg-zinc-700"
16608
16614
  )
16609
16615
  },
16610
16616
  i
@@ -16652,7 +16658,7 @@ var PresentationJobCard = ({
16652
16658
  /* @__PURE__ */ jsx147(
16653
16659
  "div",
16654
16660
  {
16655
- className: "w-10 h-10 rounded-xl bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center flex-shrink-0 text-indigo-400",
16661
+ className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0 text-[#DCC99B]",
16656
16662
  style: { ...t.accentSubtle(0.1), ...t.accentBorder, ...t.accent },
16657
16663
  children: /* @__PURE__ */ jsx147(SlidesIcon, {})
16658
16664
  }
@@ -16689,7 +16695,7 @@ var PresentationJobCard = ({
16689
16695
  onChange: (e) => setSlideTemplate(i, e.target.value),
16690
16696
  disabled: rowBusy,
16691
16697
  title: "Design template for this slide only (default: deck's template)",
16692
- className: "w-24 flex-shrink-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-1.5 h-8 text-[10px] text-zinc-300 focus:border-indigo-500 outline-none disabled:opacity-60",
16698
+ className: "w-24 flex-shrink-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-1.5 h-8 text-[10px] text-zinc-300 focus:border-[#C0AE82] outline-none disabled:opacity-60",
16693
16699
  children: [
16694
16700
  /* @__PURE__ */ jsx147("option", { value: "", children: "Deck default" }),
16695
16701
  slideTemplateOptions.map((opt) => /* @__PURE__ */ jsx147("option", { value: opt.id, children: opt.name }, opt.id))
@@ -16702,7 +16708,7 @@ var PresentationJobCard = ({
16702
16708
  value: messageEdits[i] ?? s.message ?? "",
16703
16709
  onChange: (e) => setMessageEdits((prev) => ({ ...prev, [i]: e.target.value })),
16704
16710
  disabled: building,
16705
- className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-indigo-500 outline-none disabled:opacity-60"
16711
+ className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-[#C0AE82] outline-none disabled:opacity-60"
16706
16712
  }
16707
16713
  ),
16708
16714
  /* @__PURE__ */ jsx147(
@@ -16777,34 +16783,88 @@ var PresentationJobCard = ({
16777
16783
  /* @__PURE__ */ jsx147(
16778
16784
  "div",
16779
16785
  {
16780
- className: "w-10 h-10 rounded-xl bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center flex-shrink-0 text-indigo-400",
16786
+ className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0 text-[#DCC99B]",
16781
16787
  style: { ...t.accentSubtle(0.1), ...t.accentBorder, ...t.accent },
16782
16788
  children: /* @__PURE__ */ jsx147(SlidesIcon, {})
16783
16789
  }
16784
16790
  ),
16785
16791
  /* @__PURE__ */ jsxs108("div", { className: "flex-1 min-w-0", children: [
16786
16792
  /* @__PURE__ */ jsx147("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", style: t.text, children: title }),
16787
- /* @__PURE__ */ jsxs108("p", { className: "text-xs text-zinc-500 mt-0.5", style: t.muted, children: [
16788
- slideCount ? `${slideCount} slides` : "Presentation",
16789
- " \xB7 Ready to export",
16790
- templateLabel && ` \xB7 ${templateLabel}`
16793
+ /* @__PURE__ */ jsxs108("div", { className: "flex flex-wrap items-center gap-1.5 mt-1.5", children: [
16794
+ /* @__PURE__ */ jsx147(Chip, { children: slideCount ? `${slideCount} slides` : "Presentation" }),
16795
+ templateLabel && /* @__PURE__ */ jsx147(Chip, { children: templateLabel })
16791
16796
  ] }),
16792
- generationMode === "template" && /* @__PURE__ */ jsx147("p", { className: "text-xs mt-1", children: isApproved ? /* @__PURE__ */ jsx147("span", { className: "text-emerald-400/90", children: "Approved \u2014 future decks use this format" }) : reviewStatus === "pending_review" ? /* @__PURE__ */ jsx147("span", { className: "text-amber-400/90", children: "Review this deck, then approve to lock the format" }) : null })
16797
+ generationMode === "template" && (isApproved || reviewStatus === "pending_review") && /* @__PURE__ */ jsxs108("p", { className: "flex items-center gap-1.5 text-xs mt-2", children: [
16798
+ /* @__PURE__ */ jsx147(
16799
+ "span",
16800
+ {
16801
+ className: cn(
16802
+ "w-1.5 h-1.5 rounded-full flex-shrink-0",
16803
+ isApproved ? "bg-emerald-400" : "bg-amber-400"
16804
+ )
16805
+ }
16806
+ ),
16807
+ isApproved ? /* @__PURE__ */ jsx147("span", { className: "text-emerald-400/90", children: "Approved \u2014 future decks use this format" }) : /* @__PURE__ */ jsx147("span", { className: "text-amber-400/90", children: "Review this deck, then approve to lock the format" })
16808
+ ] })
16793
16809
  ] }),
16794
16810
  /* @__PURE__ */ jsxs108("div", { className: "flex items-center gap-1.5 flex-shrink-0 flex-wrap justify-end", children: [
16795
- canRegenerate && /* @__PURE__ */ jsxs108(
16796
- "button",
16797
- {
16798
- onClick: handleRegenerate,
16799
- disabled: regenerating || approving,
16800
- title: "Try another design template with the same content",
16801
- className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-300 text-xs font-medium transition-colors disabled:opacity-50",
16802
- children: [
16803
- /* @__PURE__ */ jsx147(RefreshIcon, {}),
16804
- /* @__PURE__ */ jsx147("span", { children: regenerating ? "Switching..." : "Regenerate" })
16805
- ]
16806
- }
16807
- ),
16811
+ /* @__PURE__ */ jsxs108("div", { className: "flex items-center rounded-lg border border-zinc-700 bg-zinc-800 overflow-hidden divide-x divide-zinc-700", children: [
16812
+ /* @__PURE__ */ jsxs108(
16813
+ "a",
16814
+ {
16815
+ href: hasHtml ? `/presentations/${_job_id}/edit` : void 0,
16816
+ "aria-disabled": !hasHtml,
16817
+ title: "Edit presentation content",
16818
+ className: cn(
16819
+ "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors",
16820
+ !hasHtml && "pointer-events-none opacity-40"
16821
+ ),
16822
+ children: [
16823
+ /* @__PURE__ */ jsx147(EditIcon, {}),
16824
+ /* @__PURE__ */ jsx147("span", { children: "Edit" })
16825
+ ]
16826
+ }
16827
+ ),
16828
+ /* @__PURE__ */ jsxs108(
16829
+ "button",
16830
+ {
16831
+ onClick: () => setShowFullscreen(true),
16832
+ disabled: !hasHtml,
16833
+ title: "Open fullscreen preview",
16834
+ className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
16835
+ children: [
16836
+ /* @__PURE__ */ jsx147(ExpandIcon, {}),
16837
+ /* @__PURE__ */ jsx147("span", { children: "Preview" })
16838
+ ]
16839
+ }
16840
+ ),
16841
+ canRegenerate && /* @__PURE__ */ jsxs108(
16842
+ "button",
16843
+ {
16844
+ onClick: handleRegenerate,
16845
+ disabled: regenerating || approving,
16846
+ title: "Try another design template with the same content",
16847
+ className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40",
16848
+ children: [
16849
+ /* @__PURE__ */ jsx147(RefreshIcon, {}),
16850
+ /* @__PURE__ */ jsx147("span", { children: regenerating ? "Switching\u2026" : "Regenerate" })
16851
+ ]
16852
+ }
16853
+ ),
16854
+ /* @__PURE__ */ jsx147(
16855
+ "button",
16856
+ {
16857
+ onClick: handleShare,
16858
+ disabled: !hasHtml,
16859
+ title: copied ? "Copied!" : "Copy shareable link",
16860
+ className: cn(
16861
+ "flex items-center justify-center w-7 h-7 transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
16862
+ copied ? "text-green-400" : "text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60"
16863
+ ),
16864
+ children: copied ? /* @__PURE__ */ jsx147(CheckIcon, {}) : /* @__PURE__ */ jsx147(ShareIcon, {})
16865
+ }
16866
+ )
16867
+ ] }),
16808
16868
  canApprove && /* @__PURE__ */ jsxs108(
16809
16869
  "button",
16810
16870
  {
@@ -16819,39 +16879,16 @@ var PresentationJobCard = ({
16819
16879
  }
16820
16880
  ),
16821
16881
  isApproved && /* @__PURE__ */ jsx147("span", { className: "flex items-center justify-center w-7 h-7 rounded-lg border border-emerald-500/40 bg-emerald-500/10 text-emerald-400", title: "Format saved", children: /* @__PURE__ */ jsx147(CheckIcon, {}) }),
16822
- /* @__PURE__ */ jsx147(
16823
- "button",
16824
- {
16825
- onClick: handleShare,
16826
- disabled: !hasHtml,
16827
- title: copied ? "Copied!" : "Copy shareable link",
16828
- className: cn(
16829
- "w-7 h-7 rounded-lg border flex items-center justify-center transition-all",
16830
- copied ? "border-green-500/40 bg-green-500/10 text-green-400" : "border-zinc-700 bg-zinc-800 text-zinc-400 hover:border-zinc-500 hover:text-zinc-200",
16831
- "disabled:opacity-30 disabled:cursor-not-allowed"
16832
- ),
16833
- children: copied ? /* @__PURE__ */ jsx147(CheckIcon, {}) : /* @__PURE__ */ jsx147(ShareIcon, {})
16834
- }
16835
- ),
16836
- /* @__PURE__ */ jsxs108(
16837
- "button",
16838
- {
16839
- onClick: () => setShowFullscreen(true),
16840
- disabled: !hasHtml,
16841
- title: "Open fullscreen preview",
16842
- className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 text-xs font-medium transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
16843
- children: [
16844
- /* @__PURE__ */ jsx147(ExpandIcon, {}),
16845
- /* @__PURE__ */ jsx147("span", { children: "Preview" })
16846
- ]
16847
- }
16848
- ),
16849
16882
  /* @__PURE__ */ jsxs108(
16850
16883
  "button",
16851
16884
  {
16852
16885
  onClick: () => setShowExport(true),
16853
- className: "flex items-center gap-1.5 px-2.5 h-7 bg-indigo-600 hover:bg-indigo-500 active:bg-indigo-700 text-white text-xs font-medium rounded-lg transition-colors",
16854
- style: { ...t.accentBg, ...t.accentText },
16886
+ className: "flex items-center gap-1.5 px-3 h-7 text-xs font-semibold rounded-lg transition-colors",
16887
+ style: {
16888
+ backgroundImage: accentGradient || "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)",
16889
+ color: "#0A0A0A",
16890
+ ...accentGradient ? t.accentText : {}
16891
+ },
16855
16892
  children: [
16856
16893
  /* @__PURE__ */ jsx147(DownloadIcon, {}),
16857
16894
  /* @__PURE__ */ jsx147("span", { children: "Export" })
@@ -16906,7 +16943,7 @@ var PresentationJobCard = ({
16906
16943
  sendSlideCommand("prevSlide");
16907
16944
  },
16908
16945
  disabled: !hasHtml || !iframeReady,
16909
- className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-indigo-500 hover:text-indigo-400 text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
16946
+ className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
16910
16947
  "aria-label": "Previous slide",
16911
16948
  children: /* @__PURE__ */ jsx147(ChevronLeft2, {})
16912
16949
  }
@@ -16924,7 +16961,7 @@ var PresentationJobCard = ({
16924
16961
  sendSlideCommand("nextSlide");
16925
16962
  },
16926
16963
  disabled: !hasHtml || !iframeReady,
16927
- className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-indigo-500 hover:text-indigo-400 text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
16964
+ className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
16928
16965
  "aria-label": "Next slide",
16929
16966
  children: /* @__PURE__ */ jsx147(ChevronRight2, {})
16930
16967
  }
@@ -16951,10 +16988,11 @@ var PresentationJobCard = ({
16951
16988
  import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef7, useState as useState11 } from "react";
16952
16989
  import { Fragment as Fragment6, jsx as jsx148, jsxs as jsxs109 } from "react/jsx-runtime";
16953
16990
  var DEFAULT_THEME = {
16954
- primary: "#8b5cf6",
16955
- secondary: "#a78bfa",
16956
- accent: "#c4b5fd"
16991
+ primary: "#C0AE82",
16992
+ secondary: "#C4AD7C",
16993
+ accent: "#DCC99B"
16957
16994
  };
16995
+ var GOLD_GRADIENT = "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)";
16958
16996
  function readableOn(bg) {
16959
16997
  if (!bg || typeof bg !== "string") return "#ffffff";
16960
16998
  const hex = bg.replace("#", "");
@@ -17001,6 +17039,10 @@ var RefreshIcon2 = () => /* @__PURE__ */ jsxs109("svg", { width: "14", height: "
17001
17039
  /* @__PURE__ */ jsx148("polyline", { points: "23 4 23 10 17 10" }),
17002
17040
  /* @__PURE__ */ jsx148("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
17003
17041
  ] });
17042
+ var EditIcon2 = () => /* @__PURE__ */ jsxs109("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
17043
+ /* @__PURE__ */ jsx148("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
17044
+ /* @__PURE__ */ jsx148("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
17045
+ ] });
17004
17046
  function formatTemplateLabel2(templateId) {
17005
17047
  if (!templateId) return null;
17006
17048
  return templateId.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
@@ -17022,7 +17064,7 @@ var FullscreenPreviewModal = ({ url, title, onClose }) => {
17022
17064
  return /* @__PURE__ */ jsxs109("div", { className: "fixed inset-0 z-50 bg-black flex flex-col", children: [
17023
17065
  /* @__PURE__ */ jsxs109("div", { className: "flex items-center justify-between gap-4 px-4 h-11 bg-zinc-950/90 border-b border-zinc-800/60 flex-shrink-0", children: [
17024
17066
  /* @__PURE__ */ jsxs109("div", { className: "flex items-center gap-3 min-w-0", children: [
17025
- /* @__PURE__ */ jsx148("span", { className: "text-violet-400 flex-shrink-0", children: /* @__PURE__ */ jsx148(DocumentIcon, {}) }),
17067
+ /* @__PURE__ */ jsx148("span", { className: "text-[#DCC99B] flex-shrink-0", children: /* @__PURE__ */ jsx148(DocumentIcon, {}) }),
17026
17068
  /* @__PURE__ */ jsx148("span", { className: "text-sm font-medium text-zinc-300 truncate", children: title })
17027
17069
  ] }),
17028
17070
  /* @__PURE__ */ jsxs109(
@@ -17048,6 +17090,102 @@ var FullscreenPreviewModal = ({ url, title, onClose }) => {
17048
17090
  ) })
17049
17091
  ] });
17050
17092
  };
17093
+ var Chip2 = ({ children }) => /* @__PURE__ */ jsx148("span", { className: "inline-flex items-center px-2 h-[22px] rounded-md bg-zinc-800/70 border border-zinc-700/50 text-[11px] font-medium text-zinc-400 whitespace-nowrap capitalize", children });
17094
+ var REPORT_FORMATS = [
17095
+ {
17096
+ key: "pdf",
17097
+ label: "PDF",
17098
+ ext: ".pdf",
17099
+ emoji: "\u{1F4C4}",
17100
+ desc: "Print-ready, fixed layout \u2014 open in any PDF viewer",
17101
+ accent: { text: "text-red-400", bg: "bg-red-500/10 border-red-500/20" }
17102
+ },
17103
+ {
17104
+ key: "html",
17105
+ label: "HTML",
17106
+ ext: ".html",
17107
+ emoji: "\u{1F310}",
17108
+ desc: "Interactive web page \u2014 download and open in a browser",
17109
+ accent: { text: "text-sky-400", bg: "bg-sky-500/10 border-sky-500/20" }
17110
+ }
17111
+ ];
17112
+ var ReportExportModal = ({ htmlUrl, pdfUrl, title, onClose }) => {
17113
+ const urls = { pdf: pdfUrl, html: htmlUrl };
17114
+ const available = REPORT_FORMATS.filter((f) => urls[f.key]);
17115
+ const filename = (title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase();
17116
+ const [downloadingKey, setDownloadingKey] = useState11(null);
17117
+ useEffect8(() => {
17118
+ const onKey = (e) => {
17119
+ if (e.key === "Escape") onClose();
17120
+ };
17121
+ document.addEventListener("keydown", onKey);
17122
+ return () => document.removeEventListener("keydown", onKey);
17123
+ }, [onClose]);
17124
+ const handleDownload = async (key, url, ext) => {
17125
+ if (downloadingKey) return;
17126
+ const downloadName = `${filename}${ext}`;
17127
+ const href = `/api/download?url=${encodeURIComponent(url)}&filename=${encodeURIComponent(downloadName)}`;
17128
+ try {
17129
+ setDownloadingKey(key);
17130
+ const response = await fetch(href);
17131
+ if (!response.ok) throw new Error(`status ${response.status}`);
17132
+ const blob = await response.blob();
17133
+ const objectUrl = window.URL.createObjectURL(blob);
17134
+ const anchor = document.createElement("a");
17135
+ anchor.href = objectUrl;
17136
+ anchor.download = downloadName;
17137
+ document.body.appendChild(anchor);
17138
+ anchor.click();
17139
+ anchor.remove();
17140
+ window.URL.revokeObjectURL(objectUrl);
17141
+ } catch {
17142
+ window.open(url, "_blank", "noopener,noreferrer");
17143
+ } finally {
17144
+ setDownloadingKey(null);
17145
+ }
17146
+ };
17147
+ return /* @__PURE__ */ jsxs109("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
17148
+ /* @__PURE__ */ jsx148("div", { className: "absolute inset-0 bg-black/70 backdrop-blur-sm", onClick: onClose }),
17149
+ /* @__PURE__ */ jsxs109("div", { className: "relative z-10 bg-zinc-900 border border-zinc-800 rounded-2xl w-full max-w-sm p-6 shadow-2xl", children: [
17150
+ /* @__PURE__ */ jsxs109("div", { className: "flex items-start justify-between mb-5", children: [
17151
+ /* @__PURE__ */ jsxs109("div", { className: "min-w-0 pr-3", children: [
17152
+ /* @__PURE__ */ jsx148("h3", { className: "text-sm font-semibold text-zinc-100", children: "Download report" }),
17153
+ /* @__PURE__ */ jsx148("p", { className: "text-xs text-zinc-500 mt-0.5 truncate", children: title })
17154
+ ] }),
17155
+ /* @__PURE__ */ jsx148("button", { onClick: onClose, className: "text-zinc-500 hover:text-zinc-200 transition-colors flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx148(CloseIcon2, {}) })
17156
+ ] }),
17157
+ /* @__PURE__ */ jsxs109("div", { className: "space-y-2.5", children: [
17158
+ available.length === 0 && /* @__PURE__ */ jsx148("p", { className: "text-sm text-zinc-500 text-center py-6", children: "No formats available yet" }),
17159
+ available.map((fmt) => {
17160
+ const url = urls[fmt.key];
17161
+ const isDownloading = downloadingKey === fmt.key;
17162
+ return /* @__PURE__ */ jsxs109(
17163
+ "button",
17164
+ {
17165
+ type: "button",
17166
+ disabled: Boolean(downloadingKey),
17167
+ onClick: () => handleDownload(fmt.key, url, fmt.ext),
17168
+ className: cn(
17169
+ "flex w-full items-center gap-3.5 p-3.5 rounded-xl border transition-all text-left",
17170
+ "hover:brightness-110 disabled:opacity-60 disabled:cursor-not-allowed",
17171
+ fmt.accent.bg
17172
+ ),
17173
+ children: [
17174
+ /* @__PURE__ */ jsx148("span", { className: "text-xl flex-shrink-0", children: fmt.emoji }),
17175
+ /* @__PURE__ */ jsxs109("div", { className: "flex-1 min-w-0", children: [
17176
+ /* @__PURE__ */ jsx148("p", { className: cn("text-sm font-semibold", fmt.accent.text), children: isDownloading ? `Downloading ${fmt.label}...` : fmt.label }),
17177
+ /* @__PURE__ */ jsx148("p", { className: "text-xs text-zinc-500 mt-0.5 leading-relaxed", children: isDownloading ? "Please wait while the file is being prepared." : fmt.desc })
17178
+ ] }),
17179
+ /* @__PURE__ */ jsx148("span", { className: cn("flex-shrink-0", fmt.accent.text), children: /* @__PURE__ */ jsx148(DownloadIcon2, {}) })
17180
+ ]
17181
+ },
17182
+ fmt.key
17183
+ );
17184
+ })
17185
+ ] })
17186
+ ] })
17187
+ ] });
17188
+ };
17051
17189
  function deriveJobStatusUrl2(newJobId, pollUrl, regenerateUrl) {
17052
17190
  const base = pollUrl?.replace(/\/api\/jobs\/[^/]+\/status.*$/, "") ?? regenerateUrl?.replace(/\/api\/reports\/[^/]+\/regenerate.*$/, "") ?? "";
17053
17191
  return `${base}/api/jobs/${newJobId}/status`;
@@ -17111,6 +17249,7 @@ var ResearchReportJobCard = (props) => {
17111
17249
  const [error, setError] = useState11(initialError);
17112
17250
  const [progress, setProgress] = useState11(initialProgress);
17113
17251
  const [showPreview, setShowPreview] = useState11(false);
17252
+ const [showExport, setShowExport] = useState11(false);
17114
17253
  const [previewScale, setPreviewScale] = useState11(1);
17115
17254
  const [copied, setCopied] = useState11(false);
17116
17255
  const [approving, setApproving] = useState11(false);
@@ -17503,8 +17642,9 @@ var ResearchReportJobCard = (props) => {
17503
17642
  /* @__PURE__ */ jsx148(
17504
17643
  "div",
17505
17644
  {
17506
- className: "h-[3px] bg-gradient-to-r from-violet-500 via-purple-500 to-violet-500",
17645
+ className: "h-[3px]",
17507
17646
  style: {
17647
+ backgroundImage: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B, #C0AE82, #8B7D5E)",
17508
17648
  backgroundSize: "200% 100%",
17509
17649
  animation: "gradient-shift 2s ease-in-out infinite"
17510
17650
  }
@@ -17512,7 +17652,7 @@ var ResearchReportJobCard = (props) => {
17512
17652
  ),
17513
17653
  /* @__PURE__ */ jsxs109("div", { className: "p-5", children: [
17514
17654
  /* @__PURE__ */ jsxs109("div", { className: "flex items-start gap-3", children: [
17515
- /* @__PURE__ */ jsx148("div", { className: "w-10 h-10 rounded-xl bg-violet-500/10 border border-violet-500/20 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx148("span", { className: "text-lg", children: getPhaseIcon() }) }),
17655
+ /* @__PURE__ */ jsx148("div", { className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx148("span", { className: "text-lg", children: getPhaseIcon() }) }),
17516
17656
  /* @__PURE__ */ jsxs109("div", { className: "flex-1 min-w-0", children: [
17517
17657
  /* @__PURE__ */ jsx148("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title || "Generating Research Report" }),
17518
17658
  /* @__PURE__ */ jsxs109("p", { className: "text-xs text-zinc-500 mt-0.5", children: [
@@ -17527,8 +17667,8 @@ var ResearchReportJobCard = (props) => {
17527
17667
  /* @__PURE__ */ jsx148("div", { className: "h-2 bg-zinc-800 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx148(
17528
17668
  "div",
17529
17669
  {
17530
- className: "h-full bg-gradient-to-r from-violet-500 to-purple-500 rounded-full transition-all duration-500 ease-out",
17531
- style: { width: `${Math.max(pct, 2)}%` }
17670
+ className: "h-full rounded-full transition-all duration-500 ease-out",
17671
+ style: { width: `${Math.max(pct, 2)}%`, backgroundImage: GOLD_GRADIENT }
17532
17672
  }
17533
17673
  ) }),
17534
17674
  /* @__PURE__ */ jsxs109("span", { className: "absolute right-0 -top-5 text-xs text-zinc-500 font-medium tabular-nums", children: [
@@ -17537,7 +17677,7 @@ var ResearchReportJobCard = (props) => {
17537
17677
  ] })
17538
17678
  ] }),
17539
17679
  /* @__PURE__ */ jsxs109("div", { className: "flex items-center gap-2", children: [
17540
- /* @__PURE__ */ jsx148("div", { className: "w-2 h-2 rounded-full bg-violet-500 animate-pulse" }),
17680
+ /* @__PURE__ */ jsx148("div", { className: "w-2 h-2 rounded-full bg-[#C0AE82] animate-pulse" }),
17541
17681
  /* @__PURE__ */ jsx148("span", { className: "text-xs text-zinc-400", children: step })
17542
17682
  ] }),
17543
17683
  phase === "ai_generation" && searchesTotal > 0 && /* @__PURE__ */ jsxs109("div", { className: "pt-1", children: [
@@ -17554,7 +17694,7 @@ var ResearchReportJobCard = (props) => {
17554
17694
  {
17555
17695
  className: cn(
17556
17696
  "flex-1 h-1 rounded-full transition-all duration-300",
17557
- i < searchesCompleted ? "bg-violet-500" : i === searchesCompleted ? "bg-violet-500/50 animate-pulse" : "bg-zinc-700"
17697
+ i < searchesCompleted ? "bg-[#C0AE82]" : i === searchesCompleted ? "bg-[#C0AE82]/50 animate-pulse" : "bg-zinc-700"
17558
17698
  )
17559
17699
  },
17560
17700
  i
@@ -17588,12 +17728,12 @@ var ResearchReportJobCard = (props) => {
17588
17728
  "div",
17589
17729
  {
17590
17730
  className: "h-[3px]",
17591
- style: { background: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)" }
17731
+ style: { backgroundImage: GOLD_GRADIENT }
17592
17732
  }
17593
17733
  ),
17594
17734
  /* @__PURE__ */ jsxs109("div", { className: "p-5", children: [
17595
17735
  /* @__PURE__ */ jsxs109("div", { className: "flex items-start gap-3", children: [
17596
- /* @__PURE__ */ jsx148("div", { className: "w-10 h-10 rounded-xl bg-violet-500/10 border border-violet-500/20 flex items-center justify-center flex-shrink-0 text-violet-300", children: /* @__PURE__ */ jsx148(DocumentIcon, {}) }),
17736
+ /* @__PURE__ */ jsx148("div", { className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0 text-[#DCC99B]", children: /* @__PURE__ */ jsx148(DocumentIcon, {}) }),
17597
17737
  /* @__PURE__ */ jsxs109("div", { className: "flex-1 min-w-0", children: [
17598
17738
  /* @__PURE__ */ jsx148("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title || "Report outline" }),
17599
17739
  /* @__PURE__ */ jsxs109("p", { className: "text-xs text-amber-400/90 mt-0.5", children: [
@@ -17614,7 +17754,7 @@ var ResearchReportJobCard = (props) => {
17614
17754
  value: headingEdits[i] ?? s.heading ?? "",
17615
17755
  onChange: (e) => setHeadingEdits((prev) => ({ ...prev, [i]: e.target.value })),
17616
17756
  disabled: building,
17617
- className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-violet-500 outline-none disabled:opacity-60"
17757
+ className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-[#C0AE82] outline-none disabled:opacity-60"
17618
17758
  }
17619
17759
  ),
17620
17760
  /* @__PURE__ */ jsx148(
@@ -17700,46 +17840,6 @@ var ResearchReportJobCard = (props) => {
17700
17840
  ] }) })
17701
17841
  ] }) });
17702
17842
  }
17703
- const handleDownload = async () => {
17704
- if (!htmlUrl) return;
17705
- const filename = `${(title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase()}.html`;
17706
- const href = `/api/download?url=${encodeURIComponent(htmlUrl)}&filename=${encodeURIComponent(filename)}`;
17707
- try {
17708
- const response = await fetch(href);
17709
- if (!response.ok) throw new Error(`status ${response.status}`);
17710
- const blob = await response.blob();
17711
- const objectUrl = window.URL.createObjectURL(blob);
17712
- const anchor = document.createElement("a");
17713
- anchor.href = objectUrl;
17714
- anchor.download = filename;
17715
- document.body.appendChild(anchor);
17716
- anchor.click();
17717
- anchor.remove();
17718
- window.URL.revokeObjectURL(objectUrl);
17719
- } catch {
17720
- window.open(htmlUrl, "_blank", "noopener,noreferrer");
17721
- }
17722
- };
17723
- const handleDownloadPdf = async () => {
17724
- if (!pdfUrl) return;
17725
- const filename = `${(title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase()}.pdf`;
17726
- const href = `/api/download?url=${encodeURIComponent(pdfUrl)}&filename=${encodeURIComponent(filename)}`;
17727
- try {
17728
- const response = await fetch(href);
17729
- if (!response.ok) throw new Error(`status ${response.status}`);
17730
- const blob = await response.blob();
17731
- const objectUrl = window.URL.createObjectURL(blob);
17732
- const anchor = document.createElement("a");
17733
- anchor.href = objectUrl;
17734
- anchor.download = filename;
17735
- document.body.appendChild(anchor);
17736
- anchor.click();
17737
- anchor.remove();
17738
- window.URL.revokeObjectURL(objectUrl);
17739
- } catch {
17740
- window.open(pdfUrl, "_blank", "noopener,noreferrer");
17741
- }
17742
- };
17743
17843
  const resolveShareLink = () => {
17744
17844
  if (shareUrl) return shareUrl;
17745
17845
  if (typeof window !== "undefined" && job_id) {
@@ -17865,30 +17965,93 @@ var ResearchReportJobCard = (props) => {
17865
17965
  ),
17866
17966
  /* @__PURE__ */ jsxs109("div", { className: "flex-1 min-w-0", children: [
17867
17967
  /* @__PURE__ */ jsx148("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title }),
17868
- /* @__PURE__ */ jsxs109("p", { className: "text-xs text-zinc-500 mt-0.5", children: [
17869
- depth && /* @__PURE__ */ jsx148("span", { className: "capitalize", children: depth }),
17870
- depth && sectionCount > 0 && " \xB7 ",
17871
- sectionCount > 0 && `${sectionCount} sections`,
17872
- sourceCount > 0 && ` \xB7 ${sourceCount} sources`,
17873
- wordCount > 0 && ` \xB7 ${formatWordCount(wordCount)} words`,
17874
- templateLabel && ` \xB7 ${templateLabel}`
17968
+ (depth || sectionCount > 0 || sourceCount > 0 || wordCount > 0 || templateLabel) && /* @__PURE__ */ jsxs109("div", { className: "flex flex-wrap items-center gap-1.5 mt-1.5", children: [
17969
+ depth && /* @__PURE__ */ jsx148(Chip2, { children: depth }),
17970
+ sectionCount > 0 && /* @__PURE__ */ jsxs109(Chip2, { children: [
17971
+ sectionCount,
17972
+ " sections"
17973
+ ] }),
17974
+ sourceCount > 0 && /* @__PURE__ */ jsxs109(Chip2, { children: [
17975
+ sourceCount,
17976
+ " sources"
17977
+ ] }),
17978
+ wordCount > 0 && /* @__PURE__ */ jsxs109(Chip2, { children: [
17979
+ formatWordCount(wordCount),
17980
+ " words"
17981
+ ] }),
17982
+ templateLabel && /* @__PURE__ */ jsx148(Chip2, { children: templateLabel })
17875
17983
  ] }),
17876
- generationMode === "template" && /* @__PURE__ */ jsx148("p", { className: "text-xs mt-1", children: isApproved ? /* @__PURE__ */ jsx148("span", { className: "text-emerald-400/90", children: "Approved \u2014 future reports use this format" }) : reviewStatus === "pending_review" ? /* @__PURE__ */ jsx148("span", { className: "text-amber-400/90", children: "Review this report, then approve to lock the layout" }) : null })
17984
+ generationMode === "template" && (isApproved || reviewStatus === "pending_review") && /* @__PURE__ */ jsxs109("p", { className: "flex items-center gap-1.5 text-xs mt-2", children: [
17985
+ /* @__PURE__ */ jsx148(
17986
+ "span",
17987
+ {
17988
+ className: cn(
17989
+ "w-1.5 h-1.5 rounded-full flex-shrink-0",
17990
+ isApproved ? "bg-emerald-400" : "bg-amber-400"
17991
+ )
17992
+ }
17993
+ ),
17994
+ isApproved ? /* @__PURE__ */ jsx148("span", { className: "text-emerald-400/90", children: "Approved \u2014 future reports use this format" }) : /* @__PURE__ */ jsx148("span", { className: "text-amber-400/90", children: "Review this report, then approve to lock the layout" })
17995
+ ] })
17877
17996
  ] }),
17878
17997
  /* @__PURE__ */ jsxs109("div", { className: "flex items-center gap-1.5 flex-shrink-0 flex-wrap justify-end", children: [
17879
- canRegenerate && /* @__PURE__ */ jsxs109(
17880
- "button",
17881
- {
17882
- onClick: handleRegenerate,
17883
- disabled: regenerating || approving,
17884
- title: "Try another report template with the same data",
17885
- className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-300 text-xs font-medium transition-colors disabled:opacity-50",
17886
- children: [
17887
- /* @__PURE__ */ jsx148(RefreshIcon2, {}),
17888
- /* @__PURE__ */ jsx148("span", { children: regenerating ? "Switching..." : "Regenerate" })
17889
- ]
17890
- }
17891
- ),
17998
+ /* @__PURE__ */ jsxs109("div", { className: "flex items-center rounded-lg border border-zinc-700 bg-zinc-800 overflow-hidden divide-x divide-zinc-700", children: [
17999
+ /* @__PURE__ */ jsxs109(
18000
+ "a",
18001
+ {
18002
+ href: htmlUrl ? `/reports/${job_id}/edit` : void 0,
18003
+ "aria-disabled": !htmlUrl,
18004
+ title: "Edit report content",
18005
+ className: cn(
18006
+ "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors",
18007
+ !htmlUrl && "pointer-events-none opacity-40"
18008
+ ),
18009
+ children: [
18010
+ /* @__PURE__ */ jsx148(EditIcon2, {}),
18011
+ /* @__PURE__ */ jsx148("span", { children: "Edit" })
18012
+ ]
18013
+ }
18014
+ ),
18015
+ /* @__PURE__ */ jsxs109(
18016
+ "button",
18017
+ {
18018
+ onClick: () => setShowPreview(true),
18019
+ disabled: !hasHTML,
18020
+ title: "Preview report",
18021
+ className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
18022
+ children: [
18023
+ /* @__PURE__ */ jsx148(ExpandIcon2, {}),
18024
+ /* @__PURE__ */ jsx148("span", { children: "Preview" })
18025
+ ]
18026
+ }
18027
+ ),
18028
+ canRegenerate && /* @__PURE__ */ jsxs109(
18029
+ "button",
18030
+ {
18031
+ onClick: handleRegenerate,
18032
+ disabled: regenerating || approving,
18033
+ title: "Try another report template with the same data",
18034
+ className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40",
18035
+ children: [
18036
+ /* @__PURE__ */ jsx148(RefreshIcon2, {}),
18037
+ /* @__PURE__ */ jsx148("span", { children: regenerating ? "Switching\u2026" : "Regenerate" })
18038
+ ]
18039
+ }
18040
+ ),
18041
+ /* @__PURE__ */ jsx148(
18042
+ "button",
18043
+ {
18044
+ onClick: handleShare,
18045
+ disabled: !canShare,
18046
+ title: !canShare && reviewStatus === "pending_review" ? "Approve the report to enable sharing" : copied ? "Copied!" : "Copy shareable link",
18047
+ className: cn(
18048
+ "flex items-center justify-center w-7 h-7 transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
18049
+ copied ? "text-green-400" : "text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60"
18050
+ ),
18051
+ children: copied ? /* @__PURE__ */ jsx148(CheckIcon2, {}) : /* @__PURE__ */ jsx148(ShareIcon2, {})
18052
+ }
18053
+ )
18054
+ ] }),
17892
18055
  canApprove && /* @__PURE__ */ jsxs109(
17893
18056
  "button",
17894
18057
  {
@@ -17903,53 +18066,15 @@ var ResearchReportJobCard = (props) => {
17903
18066
  }
17904
18067
  ),
17905
18068
  isApproved && /* @__PURE__ */ jsx148("span", { className: "flex items-center justify-center w-7 h-7 rounded-lg border border-emerald-500/40 bg-emerald-500/10 text-emerald-400", title: "Format saved", children: /* @__PURE__ */ jsx148(CheckIcon2, {}) }),
17906
- /* @__PURE__ */ jsx148(
17907
- "button",
17908
- {
17909
- onClick: handleShare,
17910
- disabled: !canShare,
17911
- title: !canShare && reviewStatus === "pending_review" ? "Approve the report to enable sharing" : copied ? "Copied!" : "Copy shareable link",
17912
- className: cn(
17913
- "w-7 h-7 rounded-lg border flex items-center justify-center transition-all",
17914
- copied ? "border-green-500/40 bg-green-500/10 text-green-400" : "border-zinc-700 bg-zinc-800 text-zinc-400 hover:border-zinc-500 hover:text-zinc-200",
17915
- "disabled:opacity-30 disabled:cursor-not-allowed"
17916
- ),
17917
- children: copied ? /* @__PURE__ */ jsx148(CheckIcon2, {}) : /* @__PURE__ */ jsx148(ShareIcon2, {})
17918
- }
17919
- ),
17920
- /* @__PURE__ */ jsxs109(
17921
- "button",
17922
- {
17923
- onClick: () => setShowPreview(true),
17924
- disabled: !hasHTML,
17925
- title: "Preview report",
17926
- className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 text-xs font-medium transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
17927
- children: [
17928
- /* @__PURE__ */ jsx148(ExpandIcon2, {}),
17929
- /* @__PURE__ */ jsx148("span", { children: "Preview" })
17930
- ]
17931
- }
17932
- ),
17933
- pdfUrl && /* @__PURE__ */ jsxs109(
17934
- "button",
17935
- {
17936
- onClick: handleDownloadPdf,
17937
- title: "Download PDF",
17938
- className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 text-xs font-medium transition-colors",
17939
- children: [
17940
- /* @__PURE__ */ jsx148(DownloadIcon2, {}),
17941
- /* @__PURE__ */ jsx148("span", { children: "PDF" })
17942
- ]
17943
- }
17944
- ),
17945
18069
  /* @__PURE__ */ jsxs109(
17946
18070
  "button",
17947
18071
  {
17948
- onClick: handleDownload,
17949
- disabled: !hasHTML,
17950
- className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
17951
- style: { backgroundColor: primaryColor, color: readableOn(primaryColor) },
17952
- onMouseEnter: (e) => e.currentTarget.style.filter = "brightness(1.15)",
18072
+ onClick: () => setShowExport(true),
18073
+ disabled: !hasHTML && !pdfUrl,
18074
+ title: "Download this report (PDF or HTML)",
18075
+ className: "flex items-center gap-1.5 px-3 h-7 text-xs font-semibold rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
18076
+ style: { backgroundImage: GOLD_GRADIENT, color: readableOn(primaryColor) },
18077
+ onMouseEnter: (e) => e.currentTarget.style.filter = "brightness(1.1)",
17953
18078
  onMouseLeave: (e) => e.currentTarget.style.filter = "brightness(1)",
17954
18079
  children: [
17955
18080
  /* @__PURE__ */ jsx148(DownloadIcon2, {}),
@@ -18003,6 +18128,15 @@ var ResearchReportJobCard = (props) => {
18003
18128
  title,
18004
18129
  onClose: () => setShowPreview(false)
18005
18130
  }
18131
+ ),
18132
+ showExport && /* @__PURE__ */ jsx148(
18133
+ ReportExportModal,
18134
+ {
18135
+ htmlUrl,
18136
+ pdfUrl,
18137
+ title,
18138
+ onClose: () => setShowExport(false)
18139
+ }
18006
18140
  )
18007
18141
  ] });
18008
18142
  };
@@ -18147,7 +18281,7 @@ var WebSearchJobCard = ({
18147
18281
  {
18148
18282
  className: "h-[3px]",
18149
18283
  style: {
18150
- background: "linear-gradient(90deg, #d97706, #f59e0b, #d97706)",
18284
+ backgroundImage: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B, #C0AE82, #8B7D5E)",
18151
18285
  backgroundSize: "200% 100%",
18152
18286
  animation: "gradient-shift 2s ease-in-out infinite"
18153
18287
  }
@@ -18169,7 +18303,7 @@ var WebSearchJobCard = ({
18169
18303
  className: "h-full rounded-full transition-all duration-500 ease-out",
18170
18304
  style: {
18171
18305
  width: `${Math.max(pct, 2)}%`,
18172
- background: "linear-gradient(90deg, #d97706, #f59e0b)"
18306
+ backgroundImage: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)"
18173
18307
  }
18174
18308
  }
18175
18309
  ) }),
@@ -18179,7 +18313,7 @@ var WebSearchJobCard = ({
18179
18313
  ] })
18180
18314
  ] }),
18181
18315
  /* @__PURE__ */ jsxs110("div", { className: "flex items-center gap-2", children: [
18182
- /* @__PURE__ */ jsx149("div", { className: "w-2 h-2 rounded-full bg-amber-500 animate-pulse flex-shrink-0" }),
18316
+ /* @__PURE__ */ jsx149("div", { className: "w-2 h-2 rounded-full bg-[#C0AE82] animate-pulse flex-shrink-0" }),
18183
18317
  /* @__PURE__ */ jsx149("span", { className: "text-xs text-zinc-400", children: step })
18184
18318
  ] }),
18185
18319
  searchesTotal > 0 && /* @__PURE__ */ jsxs110("div", { className: "pt-1", children: [
@@ -18196,7 +18330,7 @@ var WebSearchJobCard = ({
18196
18330
  {
18197
18331
  className: cn(
18198
18332
  "flex-1 h-1 rounded-full transition-all duration-300",
18199
- i < searchesCompleted ? "bg-amber-500" : phase === "ai_generation" && i === searchesCompleted ? "bg-amber-500/50 animate-pulse" : "bg-zinc-700"
18333
+ i < searchesCompleted ? "bg-[#C0AE82]" : phase === "ai_generation" && i === searchesCompleted ? "bg-[#C0AE82]/50 animate-pulse" : "bg-zinc-700"
18200
18334
  )
18201
18335
  },
18202
18336
  i
@@ -21436,7 +21570,7 @@ function PlatformMetricsBanner({
21436
21570
  return /* @__PURE__ */ jsxs132(
21437
21571
  "div",
21438
21572
  {
21439
- className: "\r\n grid grid-cols-1 gap-3 rounded-xl py-4 px-4 shadow-sm\r\n md:flex md:overflow-x-auto md:gap-6 md:rounded-l-xl md:py-4 md:px-4 md:items-center md:gap-0 md:px-0 md:ml-8\r\n ",
21573
+ className: "\n grid grid-cols-1 gap-3 rounded-xl py-4 px-4 shadow-sm\n md:flex md:overflow-x-auto md:gap-6 md:rounded-l-xl md:py-4 md:px-4 md:items-center md:gap-0 md:px-0 md:ml-8\n ",
21440
21574
  style: { backgroundColor: bgColor },
21441
21575
  children: [
21442
21576
  /* @__PURE__ */ jsxs132("div", { className: "flex flex-col items-center md:min-w-0", children: [