@industry-theme/file-city-panel 0.5.61 → 0.5.62

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.
@@ -257801,7 +257801,8 @@ const TrailMarkdownOverlay = ({
257801
257801
  markdown: markdown2,
257802
257802
  slideIdPrefix,
257803
257803
  bottomOffset,
257804
- containerRef: externalContainerRef
257804
+ containerRef: externalContainerRef,
257805
+ nav
257805
257806
  }) => {
257806
257807
  const { theme: theme2 } = useTheme();
257807
257808
  const body = markdown2.trim();
@@ -257948,6 +257949,7 @@ const TrailMarkdownOverlay = ({
257948
257949
  enableKeyboardScrolling: false
257949
257950
  }
257950
257951
  ) }) }),
257952
+ nav ? /* @__PURE__ */ jsx(TrailMarkdownOverlayFooter, { nav }) : null,
257951
257953
  /* @__PURE__ */ jsx(
257952
257954
  "div",
257953
257955
  {
@@ -257983,6 +257985,104 @@ const TrailMarkdownOverlay = ({
257983
257985
  }
257984
257986
  );
257985
257987
  };
257988
+ const TrailMarkdownOverlayFooter = ({
257989
+ nav
257990
+ }) => {
257991
+ const { theme: theme2 } = useTheme();
257992
+ const idle = nav.position < 0;
257993
+ const canPrev = !idle && nav.position > 0;
257994
+ const canNext = !idle && nav.position < nav.total - 1;
257995
+ const stepButtonStyle = (enabled) => ({
257996
+ background: "transparent",
257997
+ border: `1px solid ${theme2.colors.muted}`,
257998
+ borderRadius: theme2.radii[2],
257999
+ color: enabled ? theme2.colors.text : theme2.colors.textTertiary,
258000
+ cursor: enabled ? "pointer" : "not-allowed",
258001
+ padding: "4px 10px",
258002
+ fontFamily: theme2.fonts.body,
258003
+ fontSize: theme2.fontSizes[0],
258004
+ lineHeight: 1.2,
258005
+ opacity: enabled ? 1 : 0.5
258006
+ });
258007
+ return /* @__PURE__ */ jsx(
258008
+ "div",
258009
+ {
258010
+ style: {
258011
+ padding: "8px 14px",
258012
+ borderTop: `1px solid ${theme2.colors.border}`,
258013
+ display: "flex",
258014
+ alignItems: "center",
258015
+ justifyContent: idle ? "center" : "space-between",
258016
+ gap: 8,
258017
+ flexShrink: 0
258018
+ },
258019
+ children: idle ? /* @__PURE__ */ jsx(
258020
+ "button",
258021
+ {
258022
+ type: "button",
258023
+ onClick: nav.onStart,
258024
+ disabled: nav.total === 0,
258025
+ title: nav.total === 0 ? "No markers in this repo" : "Jump to the first marker",
258026
+ style: {
258027
+ background: theme2.colors.accent,
258028
+ color: theme2.colors.background,
258029
+ border: "none",
258030
+ borderRadius: theme2.radii[3],
258031
+ padding: "6px 14px",
258032
+ fontFamily: theme2.fonts.body,
258033
+ fontSize: theme2.fontSizes[0],
258034
+ fontWeight: theme2.fontWeights.semibold,
258035
+ cursor: nav.total === 0 ? "not-allowed" : "pointer",
258036
+ opacity: nav.total === 0 ? 0.5 : 1,
258037
+ lineHeight: 1.2
258038
+ },
258039
+ children: "Start trail"
258040
+ }
258041
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
258042
+ /* @__PURE__ */ jsx(
258043
+ "button",
258044
+ {
258045
+ type: "button",
258046
+ onClick: nav.onPrev,
258047
+ disabled: !canPrev,
258048
+ "aria-label": "Previous marker",
258049
+ title: "Previous marker",
258050
+ style: stepButtonStyle(canPrev),
258051
+ children: "◀ Prev"
258052
+ }
258053
+ ),
258054
+ /* @__PURE__ */ jsxs(
258055
+ "span",
258056
+ {
258057
+ style: {
258058
+ fontFamily: theme2.fonts.body,
258059
+ fontSize: theme2.fontSizes[0],
258060
+ color: theme2.colors.textSecondary,
258061
+ fontVariantNumeric: "tabular-nums"
258062
+ },
258063
+ children: [
258064
+ nav.position + 1,
258065
+ " / ",
258066
+ nav.total
258067
+ ]
258068
+ }
258069
+ ),
258070
+ /* @__PURE__ */ jsx(
258071
+ "button",
258072
+ {
258073
+ type: "button",
258074
+ onClick: nav.onNext,
258075
+ disabled: !canNext,
258076
+ "aria-label": "Next marker",
258077
+ title: "Next marker",
258078
+ style: stepButtonStyle(canNext),
258079
+ children: "Next ▶"
258080
+ }
258081
+ )
258082
+ ] })
258083
+ }
258084
+ );
258085
+ };
257986
258086
  const TrailSnippetView = ({
257987
258087
  filePath,
257988
258088
  fileName,
@@ -258258,7 +258358,7 @@ const pierreStyle = {
258258
258358
  const SEQUENCE_DRAWER_HEIGHT_PCT = 38;
258259
258359
  const SNIPPET_PANE_WIDTH_PX = 460;
258260
258360
  const HEADER_HEIGHT_PX = 48;
258261
- const SNIPPET_PANE_BG = "#0b0f14";
258361
+ const THREE_D_TOGGLE_DISABLED = true;
258262
258362
  const FileCityTrailExplorerPanel = ({ context, actions }) => {
258263
258363
  var _a;
258264
258364
  const tree = context.fileTree.data;
@@ -258314,6 +258414,7 @@ const FileCityTrailExplorerPanel = ({ context, actions }) => {
258314
258414
  selectedMarkerId,
258315
258415
  onSelectMarker: setSelectedMarkerId,
258316
258416
  cityData,
258417
+ hasLineCounts: lineCounts != null && Object.keys(lineCounts).length > 0,
258317
258418
  readFile: actions.readFile
258318
258419
  }
258319
258420
  );
@@ -258325,9 +258426,18 @@ const FileCityTrailSequenceLayout = ({
258325
258426
  selectedMarkerId,
258326
258427
  onSelectMarker,
258327
258428
  cityData,
258429
+ hasLineCounts,
258328
258430
  readFile
258329
258431
  }) => {
258330
258432
  var _a, _b;
258433
+ const { theme: theme2 } = useTheme();
258434
+ const [show3D, setShow3D] = React.useState(
258435
+ false
258436
+ );
258437
+ React.useEffect(() => {
258438
+ return;
258439
+ }, [hasLineCounts]);
258440
+ const effectiveShow3D = false;
258331
258441
  const selectedMarker = React.useMemo(() => {
258332
258442
  if (!selectedMarkerId) return null;
258333
258443
  return trail2.markers.find((m) => m.id === selectedMarkerId) ?? null;
@@ -258347,10 +258457,72 @@ const FileCityTrailSequenceLayout = ({
258347
258457
  },
258348
258458
  [markerBySourcePathForThisRepo, selectedMarkerId, onSelectMarker]
258349
258459
  );
258460
+ const stepperIndex = React.useMemo(() => {
258461
+ if (!selectedMarkerId) return -1;
258462
+ return markersForThisRepo.findIndex((m) => m.id === selectedMarkerId);
258463
+ }, [markersForThisRepo, selectedMarkerId]);
258464
+ const handleStartTrail = React.useCallback(() => {
258465
+ const first = markersForThisRepo[0];
258466
+ if (first) onSelectMarker(first.id);
258467
+ }, [markersForThisRepo, onSelectMarker]);
258468
+ const handleStepPrev = React.useCallback(() => {
258469
+ if (stepperIndex <= 0) return;
258470
+ const target = markersForThisRepo[stepperIndex - 1];
258471
+ if (target) onSelectMarker(target.id);
258472
+ }, [markersForThisRepo, stepperIndex, onSelectMarker]);
258473
+ const handleStepNext = React.useCallback(() => {
258474
+ if (stepperIndex < 0 || stepperIndex >= markersForThisRepo.length - 1) return;
258475
+ const target = markersForThisRepo[stepperIndex + 1];
258476
+ if (target) onSelectMarker(target.id);
258477
+ }, [markersForThisRepo, stepperIndex, onSelectMarker]);
258478
+ const trailFilesHighlightLayers = React.useMemo(() => {
258479
+ if (!cityData) return null;
258480
+ const sourcePaths = markersForThisRepo.map((m) => m.sourcePath).filter((p2) => typeof p2 === "string" && p2.length > 0);
258481
+ if (sourcePaths.length === 0) return null;
258482
+ const buildingByPath = new Map(cityData.buildings.map((b) => [b.path, b]));
258483
+ const byColor = /* @__PURE__ */ new Map();
258484
+ const seen = /* @__PURE__ */ new Set();
258485
+ for (const sourcePath of sourcePaths) {
258486
+ if (seen.has(sourcePath)) continue;
258487
+ const building = buildingByPath.get(sourcePath) ?? cityData.buildings.find((b) => b.path.endsWith(`/${sourcePath}`));
258488
+ if (!building) continue;
258489
+ seen.add(sourcePath);
258490
+ const color2 = building.color ?? getFileColor(building.path);
258491
+ if (!color2) continue;
258492
+ const list2 = byColor.get(color2) ?? [];
258493
+ list2.push(building.path);
258494
+ byColor.set(color2, list2);
258495
+ }
258496
+ if (byColor.size === 0) return null;
258497
+ let i = 0;
258498
+ return Array.from(byColor.entries()).map(([color2, paths]) => ({
258499
+ id: `trail-files-${i++}`,
258500
+ name: "Trail files",
258501
+ enabled: true,
258502
+ color: color2,
258503
+ opacity: 1,
258504
+ priority: 50,
258505
+ items: paths.map((path2) => ({
258506
+ path: path2,
258507
+ type: "file",
258508
+ renderStrategy: "fill"
258509
+ }))
258510
+ }));
258511
+ }, [markersForThisRepo, cityData]);
258512
+ const trailFilesActive = trailFilesHighlightLayers !== null && trailFilesHighlightLayers.length > 0;
258350
258513
  const containerRef = React.useRef(null);
258351
258514
  const snippetPaneRef = React.useRef(null);
258352
258515
  const leaderLineRef = React.useRef(null);
258353
258516
  const [markdownOverlayWidth, setMarkdownOverlayWidth] = React.useState(null);
258517
+ const [snippetPaneEl, setSnippetPaneEl] = React.useState(null);
258518
+ const snippetPaneCallbackRef = React.useCallback(
258519
+ (node2) => {
258520
+ snippetPaneRef.current = node2;
258521
+ setSnippetPaneEl(node2);
258522
+ },
258523
+ []
258524
+ );
258525
+ const [snippetPaneWidth, setSnippetPaneWidth] = React.useState(null);
258354
258526
  const [containerSize, setContainerSize] = React.useState(null);
258355
258527
  const selectedBuilding = React.useMemo(() => {
258356
258528
  if (!cityData || !(selectedMarker == null ? void 0 : selectedMarker.sourcePath)) return null;
@@ -258395,6 +258567,17 @@ const FileCityTrailSequenceLayout = ({
258395
258567
  observer.observe(markdownOverlayEl);
258396
258568
  return () => observer.disconnect();
258397
258569
  }, [markdownOverlayEl]);
258570
+ React.useEffect(() => {
258571
+ if (!snippetPaneEl) {
258572
+ setSnippetPaneWidth(null);
258573
+ return;
258574
+ }
258575
+ const update = () => setSnippetPaneWidth(snippetPaneEl.getBoundingClientRect().width);
258576
+ update();
258577
+ const observer = new ResizeObserver(update);
258578
+ observer.observe(snippetPaneEl);
258579
+ return () => observer.disconnect();
258580
+ }, [snippetPaneEl]);
258398
258581
  const overlayMarkdown = ((_a = selectedMarker == null ? void 0 : selectedMarker.description) == null ? void 0 : _a.trim()) ? {
258399
258582
  eyebrow: "Marker",
258400
258583
  title: selectedMarker.label ?? selectedMarker.id,
@@ -258415,12 +258598,10 @@ const FileCityTrailSequenceLayout = ({
258415
258598
  const apply = () => {
258416
258599
  if (cancelled) return;
258417
258600
  if (hasOverlayMarkdown && markdownOverlayWidth == null) return;
258601
+ if (showSnippetPane && snippetPaneWidth == null) return;
258418
258602
  const FLOAT_INSET2 = 16;
258419
258603
  const leftInset = hasOverlayMarkdown ? FLOAT_INSET2 + (markdownOverlayWidth ?? 0) : 0;
258420
- const snippetW = Math.min(
258421
- SNIPPET_PANE_WIDTH_PX,
258422
- containerSize.width / 2
258423
- );
258604
+ const snippetW = snippetPaneWidth ?? SNIPPET_PANE_WIDTH_PX;
258424
258605
  const rightInset = showSnippetPane ? snippetW + FLOAT_INSET2 : 0;
258425
258606
  const topInset = FLOAT_INSET2;
258426
258607
  const bottomInset = SEQUENCE_DRAWER_HEIGHT_PCT / 100 * containerSize.height;
@@ -258466,6 +258647,7 @@ const FileCityTrailSequenceLayout = ({
258466
258647
  cityData,
258467
258648
  containerSize,
258468
258649
  showSnippetPane,
258650
+ snippetPaneWidth,
258469
258651
  hasOverlayMarkdown,
258470
258652
  markdownOverlayWidth
258471
258653
  ]);
@@ -258478,11 +258660,20 @@ const FileCityTrailSequenceLayout = ({
258478
258660
  height: "100%",
258479
258661
  display: "flex",
258480
258662
  flexDirection: "column",
258481
- backgroundColor: "#0b0f14",
258482
- color: "#e5e7eb"
258663
+ backgroundColor: theme2.colors.background,
258664
+ color: theme2.colors.text
258483
258665
  },
258484
258666
  children: [
258485
- /* @__PURE__ */ jsx(TrailHeader, { trail: trail2, markerCount: markersForThisRepo.length }),
258667
+ /* @__PURE__ */ jsx(
258668
+ TrailHeader,
258669
+ {
258670
+ trail: trail2,
258671
+ markerCount: markersForThisRepo.length,
258672
+ show3D: effectiveShow3D,
258673
+ onToggle3D: () => setShow3D((v) => !v),
258674
+ hideToggle: THREE_D_TOGGLE_DISABLED
258675
+ }
258676
+ ),
258486
258677
  /* @__PURE__ */ jsxs(
258487
258678
  "div",
258488
258679
  {
@@ -258504,7 +258695,11 @@ const FileCityTrailSequenceLayout = ({
258504
258695
  onBuildingClick: handleBuildingClick,
258505
258696
  onCameraFrame,
258506
258697
  showControls: false,
258507
- backgroundColor: "#0b0f14"
258698
+ backgroundColor: theme2.colors.background,
258699
+ textColor: theme2.colors.textMuted,
258700
+ isGrown: effectiveShow3D,
258701
+ highlightLayers: trailFilesHighlightLayers ?? void 0,
258702
+ defaultBuildingColor: trailFilesActive ? theme2.colors.textTertiary : void 0
258508
258703
  }
258509
258704
  ) : /* @__PURE__ */ jsx(CityLoadingPlaceholder, {}),
258510
258705
  /* @__PURE__ */ jsx(
@@ -258525,7 +258720,14 @@ const FileCityTrailSequenceLayout = ({
258525
258720
  markdown: overlayMarkdown.markdown,
258526
258721
  slideIdPrefix: overlayMarkdown.slideIdPrefix,
258527
258722
  bottomOffset: `${SEQUENCE_DRAWER_HEIGHT_PCT}%`,
258528
- containerRef: setMarkdownOverlayEl
258723
+ containerRef: setMarkdownOverlayEl,
258724
+ nav: markersForThisRepo.length > 0 ? {
258725
+ position: stepperIndex,
258726
+ total: markersForThisRepo.length,
258727
+ onStart: handleStartTrail,
258728
+ onPrev: handleStepPrev,
258729
+ onNext: handleStepNext
258730
+ } : void 0
258529
258731
  }
258530
258732
  ) : null,
258531
258733
  /* @__PURE__ */ jsx(
@@ -258540,7 +258742,7 @@ const FileCityTrailSequenceLayout = ({
258540
258742
  (selectedMarker == null ? void 0 : selectedMarker.snippet) ? /* @__PURE__ */ jsx(
258541
258743
  SnippetSidePane,
258542
258744
  {
258543
- ref: snippetPaneRef,
258745
+ ref: snippetPaneCallbackRef,
258544
258746
  marker: selectedMarker,
258545
258747
  snippet: selectedMarker.snippet,
258546
258748
  readFile,
@@ -258560,6 +258762,7 @@ const SequenceDrawer = ({
258560
258762
  selectedMarkerId,
258561
258763
  onSelectMarker
258562
258764
  }) => {
258765
+ const { theme: theme2 } = useTheme();
258563
258766
  const inputs = React.useMemo(
258564
258767
  () => buildSequenceViewInputs(trail2, view),
258565
258768
  [trail2, view]
@@ -258580,8 +258783,8 @@ const SequenceDrawer = ({
258580
258783
  right: 0,
258581
258784
  bottom: 0,
258582
258785
  height: `${SEQUENCE_DRAWER_HEIGHT_PCT}%`,
258583
- backgroundColor: "rgba(11, 15, 20, 0.92)",
258584
- borderTop: "1px solid #1f2937",
258786
+ backgroundColor: withAlpha(theme2.colors.background, 92),
258787
+ borderTop: `1px solid ${theme2.colors.border}`,
258585
258788
  zIndex: 10
258586
258789
  },
258587
258790
  children: /* @__PURE__ */ jsx(
@@ -258603,8 +258806,19 @@ const SequenceDrawer = ({
258603
258806
  );
258604
258807
  };
258605
258808
  const SnippetSidePane = React.forwardRef(function SnippetSidePane2({ marker, snippet: snippet2, readFile, onClose }, ref) {
258809
+ const { theme: theme2 } = useTheme();
258606
258810
  if (!marker.sourcePath) {
258607
- return /* @__PURE__ */ jsx(SidePaneFrame, { ref, marker, onClose, children: /* @__PURE__ */ jsx("div", { style: { fontSize: 11, opacity: 0.6, padding: 8 }, children: "Marker has no sourcePath; snippet cannot be rendered." }) });
258811
+ return /* @__PURE__ */ jsx(SidePaneFrame, { ref, marker, onClose, children: /* @__PURE__ */ jsx(
258812
+ "div",
258813
+ {
258814
+ style: {
258815
+ fontSize: theme2.fontSizes[0],
258816
+ color: theme2.colors.textSecondary,
258817
+ padding: 8
258818
+ },
258819
+ children: "Marker has no sourcePath; snippet cannot be rendered."
258820
+ }
258821
+ ) });
258608
258822
  }
258609
258823
  const fileName = marker.sourcePath.split("/").pop() ?? marker.sourcePath;
258610
258824
  return /* @__PURE__ */ jsx(SidePaneFrame, { ref, marker, onClose, children: snippet2.kind === "slice" ? /* @__PURE__ */ jsx(
@@ -258617,7 +258831,7 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({ marker, sni
258617
258831
  focusLine: snippet2.focusLine,
258618
258832
  contextLines: snippet2.contextLines,
258619
258833
  readFile,
258620
- background: SNIPPET_PANE_BG
258834
+ background: theme2.colors.background
258621
258835
  }
258622
258836
  ) : /* @__PURE__ */ jsx(
258623
258837
  TrailDiffSnippetView,
@@ -258632,33 +258846,130 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({ marker, sni
258632
258846
  focusLine: snippet2.focusLine,
258633
258847
  contextLines: snippet2.contextLines,
258634
258848
  diffStyle: snippet2.diffStyle,
258635
- background: SNIPPET_PANE_BG
258849
+ background: theme2.colors.background
258636
258850
  }
258637
258851
  ) });
258638
258852
  });
258853
+ const SNIPPET_PANE_MIN_WIDTH_PX = 320;
258854
+ const SNIPPET_PANE_RESIZE_HANDLE_WIDTH = 6;
258639
258855
  const SidePaneFrame = React.forwardRef(
258640
258856
  function SidePaneFrame2({ marker, onClose, children: children2 }, ref) {
258857
+ const { theme: theme2 } = useTheme();
258858
+ const [widthPx, setWidthPx] = React.useState(null);
258859
+ const [isResizing, setIsResizing] = React.useState(false);
258860
+ const innerRef = React.useRef(null);
258861
+ const setInnerRef = React.useCallback(
258862
+ (node2) => {
258863
+ innerRef.current = node2;
258864
+ if (typeof ref === "function") {
258865
+ ref(node2);
258866
+ } else if (ref) {
258867
+ ref.current = node2;
258868
+ }
258869
+ },
258870
+ [ref]
258871
+ );
258872
+ const dragStateRef = React.useRef(null);
258873
+ const handleResizePointerDown = React.useCallback(
258874
+ (e) => {
258875
+ if (e.button !== 0) return;
258876
+ const el = innerRef.current;
258877
+ if (!el) return;
258878
+ e.preventDefault();
258879
+ dragStateRef.current = {
258880
+ startX: e.clientX,
258881
+ startWidth: el.getBoundingClientRect().width
258882
+ };
258883
+ setIsResizing(true);
258884
+ e.currentTarget.setPointerCapture(e.pointerId);
258885
+ },
258886
+ []
258887
+ );
258888
+ const handleResizePointerMove = React.useCallback(
258889
+ (e) => {
258890
+ var _a;
258891
+ const drag2 = dragStateRef.current;
258892
+ if (!drag2) return;
258893
+ const parent = (_a = innerRef.current) == null ? void 0 : _a.parentElement;
258894
+ const parentWidth = (parent == null ? void 0 : parent.clientWidth) ?? window.innerWidth;
258895
+ const maxWidth = Math.max(
258896
+ SNIPPET_PANE_MIN_WIDTH_PX,
258897
+ parentWidth - 32
258898
+ );
258899
+ const dx = e.clientX - drag2.startX;
258900
+ const next2 = Math.min(
258901
+ maxWidth,
258902
+ Math.max(SNIPPET_PANE_MIN_WIDTH_PX, drag2.startWidth - dx)
258903
+ );
258904
+ setWidthPx(next2);
258905
+ },
258906
+ []
258907
+ );
258908
+ const handleResizePointerUp = React.useCallback(
258909
+ (e) => {
258910
+ if (!dragStateRef.current) return;
258911
+ dragStateRef.current = null;
258912
+ setIsResizing(false);
258913
+ if (e.currentTarget.hasPointerCapture(e.pointerId)) {
258914
+ e.currentTarget.releasePointerCapture(e.pointerId);
258915
+ }
258916
+ },
258917
+ []
258918
+ );
258641
258919
  return /* @__PURE__ */ jsxs(
258642
258920
  "div",
258643
258921
  {
258644
- ref,
258922
+ ref: setInnerRef,
258645
258923
  style: {
258646
258924
  position: "absolute",
258647
258925
  top: 16,
258648
258926
  right: 16,
258649
258927
  bottom: `calc(${SEQUENCE_DRAWER_HEIGHT_PCT}% + 16px)`,
258650
- width: SNIPPET_PANE_WIDTH_PX,
258651
- maxWidth: "50%",
258652
- backgroundColor: SNIPPET_PANE_BG,
258653
- border: "1px solid #1f2937",
258654
- borderRadius: 12,
258655
- boxShadow: "-2px 0 12px rgba(0,0,0,0.35)",
258928
+ width: widthPx ?? SNIPPET_PANE_WIDTH_PX,
258929
+ minWidth: SNIPPET_PANE_MIN_WIDTH_PX,
258930
+ backgroundColor: theme2.colors.background,
258931
+ border: `1px solid ${theme2.colors.border}`,
258932
+ borderRadius: theme2.radii[5],
258933
+ boxShadow: theme2.shadows[3],
258656
258934
  display: "flex",
258657
258935
  flexDirection: "column",
258658
258936
  overflow: "hidden",
258659
- zIndex: 1900
258937
+ zIndex: 1900,
258938
+ userSelect: isResizing ? "none" : void 0
258660
258939
  },
258661
258940
  children: [
258941
+ /* @__PURE__ */ jsx(
258942
+ "div",
258943
+ {
258944
+ role: "separator",
258945
+ "aria-orientation": "vertical",
258946
+ "aria-label": "Resize snippet panel",
258947
+ onPointerDown: handleResizePointerDown,
258948
+ onPointerMove: handleResizePointerMove,
258949
+ onPointerUp: handleResizePointerUp,
258950
+ onPointerCancel: handleResizePointerUp,
258951
+ style: {
258952
+ position: "absolute",
258953
+ top: 0,
258954
+ left: 0,
258955
+ bottom: 0,
258956
+ width: SNIPPET_PANE_RESIZE_HANDLE_WIDTH,
258957
+ cursor: "ew-resize",
258958
+ backgroundColor: isResizing ? theme2.colors.accent : "transparent",
258959
+ transition: isResizing ? void 0 : "background-color 120ms ease",
258960
+ touchAction: "none",
258961
+ zIndex: 1
258962
+ },
258963
+ onMouseEnter: (e) => {
258964
+ if (isResizing) return;
258965
+ e.currentTarget.style.backgroundColor = theme2.colors.border;
258966
+ },
258967
+ onMouseLeave: (e) => {
258968
+ if (isResizing) return;
258969
+ e.currentTarget.style.backgroundColor = "transparent";
258970
+ }
258971
+ }
258972
+ ),
258662
258973
  /* @__PURE__ */ jsxs(
258663
258974
  "div",
258664
258975
  {
@@ -258668,19 +258979,30 @@ const SidePaneFrame = React.forwardRef(
258668
258979
  justifyContent: "space-between",
258669
258980
  gap: 8,
258670
258981
  padding: "10px 14px",
258671
- borderBottom: "1px solid #1f2937",
258982
+ borderBottom: `1px solid ${theme2.colors.border}`,
258672
258983
  flexShrink: 0
258673
258984
  },
258674
258985
  children: [
258675
258986
  /* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
258676
- /* @__PURE__ */ jsx("div", { style: { fontSize: 12, fontWeight: 600 }, children: marker.label ?? marker.id }),
258987
+ /* @__PURE__ */ jsx(
258988
+ "div",
258989
+ {
258990
+ style: {
258991
+ fontFamily: theme2.fonts.heading,
258992
+ fontSize: theme2.fontSizes[0],
258993
+ fontWeight: theme2.fontWeights.semibold,
258994
+ color: theme2.colors.text
258995
+ },
258996
+ children: marker.label ?? marker.id
258997
+ }
258998
+ ),
258677
258999
  marker.sourcePath ? /* @__PURE__ */ jsx(
258678
259000
  "div",
258679
259001
  {
258680
259002
  style: {
258681
- fontSize: 11,
258682
- opacity: 0.6,
258683
- fontFamily: "ui-monospace, SFMono-Regular, monospace",
259003
+ fontSize: theme2.fontSizes[0],
259004
+ color: theme2.colors.textSecondary,
259005
+ fontFamily: theme2.fonts.monospace,
258684
259006
  marginTop: 2,
258685
259007
  wordBreak: "break-all"
258686
259008
  },
@@ -258694,12 +259016,13 @@ const SidePaneFrame = React.forwardRef(
258694
259016
  onClick: onClose,
258695
259017
  style: {
258696
259018
  background: "transparent",
258697
- color: "#e5e7eb",
258698
- border: "1px solid #374151",
258699
- borderRadius: 4,
259019
+ color: theme2.colors.text,
259020
+ border: `1px solid ${theme2.colors.muted}`,
259021
+ borderRadius: theme2.radii[2],
258700
259022
  padding: "2px 8px",
258701
259023
  cursor: "pointer",
258702
- fontSize: 11,
259024
+ fontSize: theme2.fontSizes[0],
259025
+ fontFamily: theme2.fonts.body,
258703
259026
  flexShrink: 0
258704
259027
  },
258705
259028
  children: "Close"
@@ -258714,28 +259037,94 @@ const SidePaneFrame = React.forwardRef(
258714
259037
  );
258715
259038
  }
258716
259039
  );
258717
- const TrailHeader = ({ trail: trail2, markerCount }) => {
259040
+ const TrailHeader = ({
259041
+ trail: trail2,
259042
+ markerCount,
259043
+ show3D,
259044
+ onToggle3D,
259045
+ hideToggle = false
259046
+ }) => {
259047
+ const { theme: theme2 } = useTheme();
258718
259048
  return /* @__PURE__ */ jsxs(
258719
259049
  "div",
258720
259050
  {
258721
259051
  style: {
258722
259052
  height: HEADER_HEIGHT_PX,
258723
259053
  padding: "8px 16px",
258724
- borderBottom: "1px solid #1f2937",
259054
+ borderBottom: `1px solid ${theme2.colors.border}`,
258725
259055
  display: "flex",
258726
- flexDirection: "column",
258727
- justifyContent: "center",
258728
- gap: 2,
259056
+ flexDirection: "row",
259057
+ alignItems: "center",
259058
+ justifyContent: "space-between",
259059
+ gap: 12,
258729
259060
  flexShrink: 0
258730
259061
  },
258731
259062
  children: [
258732
- /* @__PURE__ */ jsx("div", { style: { fontSize: 14, fontWeight: 600 }, children: trail2.title }),
258733
- /* @__PURE__ */ jsxs("div", { style: { fontSize: 11, opacity: 0.6 }, children: [
258734
- markerCount,
258735
- " marker",
258736
- markerCount === 1 ? "" : "s",
258737
- " in this repo"
258738
- ] })
259063
+ /* @__PURE__ */ jsxs(
259064
+ "div",
259065
+ {
259066
+ style: {
259067
+ display: "flex",
259068
+ flexDirection: "column",
259069
+ justifyContent: "center",
259070
+ gap: 2,
259071
+ minWidth: 0
259072
+ },
259073
+ children: [
259074
+ /* @__PURE__ */ jsx(
259075
+ "div",
259076
+ {
259077
+ style: {
259078
+ fontFamily: theme2.fonts.heading,
259079
+ fontSize: theme2.fontSizes[1],
259080
+ fontWeight: theme2.fontWeights.semibold,
259081
+ color: theme2.colors.text
259082
+ },
259083
+ children: trail2.title
259084
+ }
259085
+ ),
259086
+ /* @__PURE__ */ jsxs(
259087
+ "div",
259088
+ {
259089
+ style: {
259090
+ fontFamily: theme2.fonts.body,
259091
+ fontSize: theme2.fontSizes[0],
259092
+ color: theme2.colors.textSecondary
259093
+ },
259094
+ children: [
259095
+ markerCount,
259096
+ " marker",
259097
+ markerCount === 1 ? "" : "s",
259098
+ " in this repo"
259099
+ ]
259100
+ }
259101
+ )
259102
+ ]
259103
+ }
259104
+ ),
259105
+ hideToggle ? null : /* @__PURE__ */ jsx(
259106
+ "button",
259107
+ {
259108
+ type: "button",
259109
+ onClick: onToggle3D,
259110
+ "aria-pressed": show3D,
259111
+ title: show3D ? "Switch to flat (2D) view" : "Switch to 3D view",
259112
+ style: {
259113
+ flexShrink: 0,
259114
+ fontFamily: theme2.fonts.body,
259115
+ fontSize: theme2.fontSizes[0],
259116
+ fontWeight: theme2.fontWeights.medium,
259117
+ color: show3D ? theme2.colors.background : theme2.colors.text,
259118
+ background: show3D ? theme2.colors.accent : "transparent",
259119
+ border: `1px solid ${show3D ? theme2.colors.accent : theme2.colors.muted}`,
259120
+ borderRadius: theme2.radii[3],
259121
+ padding: "4px 10px",
259122
+ cursor: "pointer",
259123
+ lineHeight: 1.2
259124
+ },
259125
+ children: "3D"
259126
+ }
259127
+ )
258739
259128
  ]
258740
259129
  }
258741
259130
  );
@@ -258744,6 +259133,7 @@ const FileCityTrailExplorerEmptyState = ({
258744
259133
  message,
258745
259134
  cityData
258746
259135
  }) => {
259136
+ const { theme: theme2 } = useTheme();
258747
259137
  return /* @__PURE__ */ jsxs(
258748
259138
  "div",
258749
259139
  {
@@ -258751,8 +259141,8 @@ const FileCityTrailExplorerEmptyState = ({
258751
259141
  position: "relative",
258752
259142
  width: "100%",
258753
259143
  height: "100%",
258754
- backgroundColor: "#0b0f14",
258755
- color: "#e5e7eb"
259144
+ backgroundColor: theme2.colors.background,
259145
+ color: theme2.colors.text
258756
259146
  },
258757
259147
  children: [
258758
259148
  cityData ? /* @__PURE__ */ jsx(
@@ -258762,7 +259152,8 @@ const FileCityTrailExplorerEmptyState = ({
258762
259152
  width: "100%",
258763
259153
  height: "100%",
258764
259154
  showControls: false,
258765
- backgroundColor: "#0b0f14"
259155
+ backgroundColor: theme2.colors.background,
259156
+ textColor: theme2.colors.textMuted
258766
259157
  }
258767
259158
  ) : null,
258768
259159
  /* @__PURE__ */ jsx(
@@ -258775,9 +259166,10 @@ const FileCityTrailExplorerEmptyState = ({
258775
259166
  alignItems: "center",
258776
259167
  justifyContent: "center",
258777
259168
  padding: 16,
258778
- backgroundColor: cityData ? "rgba(11, 15, 20, 0.6)" : void 0,
258779
- opacity: 0.85,
258780
- fontSize: 13
259169
+ backgroundColor: cityData ? withAlpha(theme2.colors.background, 60) : void 0,
259170
+ color: theme2.colors.textSecondary,
259171
+ fontFamily: theme2.fonts.body,
259172
+ fontSize: theme2.fontSizes[1]
258781
259173
  },
258782
259174
  children: message
258783
259175
  }
@@ -258786,21 +259178,25 @@ const FileCityTrailExplorerEmptyState = ({
258786
259178
  }
258787
259179
  );
258788
259180
  };
258789
- const CityLoadingPlaceholder = () => /* @__PURE__ */ jsx(
258790
- "div",
258791
- {
258792
- style: {
258793
- width: "100%",
258794
- height: "100%",
258795
- display: "flex",
258796
- alignItems: "center",
258797
- justifyContent: "center",
258798
- opacity: 0.5,
258799
- fontSize: 12
258800
- },
258801
- children: "Building the city…"
258802
- }
258803
- );
259181
+ const CityLoadingPlaceholder = () => {
259182
+ const { theme: theme2 } = useTheme();
259183
+ return /* @__PURE__ */ jsx(
259184
+ "div",
259185
+ {
259186
+ style: {
259187
+ width: "100%",
259188
+ height: "100%",
259189
+ display: "flex",
259190
+ alignItems: "center",
259191
+ justifyContent: "center",
259192
+ color: theme2.colors.textMuted,
259193
+ fontFamily: theme2.fonts.body,
259194
+ fontSize: theme2.fontSizes[0]
259195
+ },
259196
+ children: "Building the city…"
259197
+ }
259198
+ );
259199
+ };
258804
259200
  function filterMarkersForRepo(trail2, repository) {
258805
259201
  const repos = trail2.repos ?? [];
258806
259202
  if (repos.length <= 1 || !repository) {