@loafmarkets/ui 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var clsx = require('clsx');
7
7
  var tailwindMerge = require('tailwind-merge');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
  var lucideReact = require('lucide-react');
10
- var lightweightCharts = require('lightweight-charts');
10
+ var LightweightCharts = require('lightweight-charts');
11
11
 
12
12
  function _interopNamespace(e) {
13
13
  if (e && e.__esModule) return e;
@@ -28,6 +28,7 @@ function _interopNamespace(e) {
28
28
  }
29
29
 
30
30
  var o__namespace = /*#__PURE__*/_interopNamespace(o);
31
+ var LightweightCharts__namespace = /*#__PURE__*/_interopNamespace(LightweightCharts);
31
32
 
32
33
  function cn(...inputs) {
33
34
  return tailwindMerge.twMerge(clsx.clsx(inputs));
@@ -805,6 +806,745 @@ function HousePositionSlider({
805
806
  ] })
806
807
  ] });
807
808
  }
809
+ var clamp2 = (v2, min, max) => Math.min(max, Math.max(min, v2));
810
+ var fmt02 = (v2) => Math.abs(v2).toLocaleString(void 0, { maximumFractionDigits: 0 });
811
+ var styles = {
812
+ // SliderContainer @media (max-width: 1024px)
813
+ sliderContainer: {
814
+ display: "flex",
815
+ flexDirection: "column",
816
+ alignItems: "center",
817
+ padding: "1.5rem 1rem 0.75rem",
818
+ background: "#111111",
819
+ borderRadius: "12px",
820
+ gap: "0.4rem",
821
+ position: "relative",
822
+ border: "1px solid rgba(255, 255, 255, 0.1)",
823
+ overflow: "hidden"
824
+ },
825
+ // ValueDisplay @media (max-width: 1024px)
826
+ valueDisplay: {
827
+ textAlign: "center",
828
+ marginBottom: "0.2rem"
829
+ },
830
+ // ValueLabel @media (max-width: 1024px)
831
+ valueLabel: {
832
+ fontSize: "0.65rem",
833
+ color: "#C9A227",
834
+ textTransform: "uppercase",
835
+ letterSpacing: "1px",
836
+ marginBottom: "0.2rem"
837
+ },
838
+ // ValueAmount @media (max-width: 1024px)
839
+ valueAmount: {
840
+ fontSize: "1.1rem",
841
+ fontWeight: 700,
842
+ color: "#fff",
843
+ display: "inline-flex",
844
+ alignItems: "baseline",
845
+ gap: "0.3rem"
846
+ },
847
+ // HouseWrapper @media (max-width: 1024px)
848
+ houseWrapper: {
849
+ display: "flex",
850
+ alignItems: "center",
851
+ justifyContent: "center",
852
+ gap: "0.75rem",
853
+ margin: "0.25rem 0",
854
+ width: "100%"
855
+ },
856
+ // HouseContainer @media (max-width: 1024px)
857
+ houseContainer: {
858
+ position: "relative",
859
+ width: "100px",
860
+ height: "130px",
861
+ cursor: "ns-resize",
862
+ touchAction: "none",
863
+ userSelect: "none"
864
+ },
865
+ // MobilePercentButtons @media (max-width: 1024px)
866
+ mobilePercentButtons: {
867
+ display: "flex",
868
+ flexDirection: "column",
869
+ justifyContent: "space-between",
870
+ height: "130px",
871
+ position: "absolute",
872
+ left: "-38px",
873
+ top: 0
874
+ },
875
+ // MobilePercentBtn
876
+ mobilePercentBtn: {
877
+ background: "rgba(255, 255, 255, 0.05)",
878
+ border: "1px solid rgba(255, 255, 255, 0.2)",
879
+ borderRadius: "4px",
880
+ color: "rgba(255, 255, 255, 0.6)",
881
+ fontSize: "0.55rem",
882
+ padding: "0.25rem 0.35rem",
883
+ cursor: "pointer",
884
+ transition: "all 0.15s ease",
885
+ textAlign: "center",
886
+ minWidth: "32px",
887
+ outline: "none",
888
+ WebkitTapHighlightColor: "transparent"
889
+ },
890
+ // ConfirmButton @media (max-width: 1024px)
891
+ confirmButton: {
892
+ width: "100%",
893
+ padding: "0.65rem",
894
+ fontSize: "0.85rem",
895
+ fontWeight: 600,
896
+ border: "none",
897
+ borderRadius: "8px",
898
+ cursor: "pointer",
899
+ transition: "all 0.2s ease"
900
+ },
901
+ // SummarySection @media (max-width: 1024px)
902
+ summarySection: {
903
+ width: "100%",
904
+ display: "flex",
905
+ flexDirection: "column",
906
+ gap: "0.4rem",
907
+ padding: "0.6rem",
908
+ background: "rgba(0, 0, 0, 0.2)",
909
+ borderRadius: "8px",
910
+ marginTop: 0
911
+ },
912
+ // BoxedSummaryRow @media (max-width: 1024px)
913
+ boxedSummaryRow: {
914
+ display: "flex",
915
+ justifyContent: "space-between",
916
+ alignItems: "center",
917
+ background: "transparent",
918
+ borderRadius: "6px",
919
+ padding: "0.35rem 0.5rem",
920
+ cursor: "text",
921
+ flexWrap: "nowrap",
922
+ fontSize: "0.75rem"
923
+ },
924
+ // SummaryLabel @media (max-width: 1024px)
925
+ summaryLabel: {
926
+ color: "rgba(255, 255, 255, 0.6)",
927
+ fontSize: "0.7rem",
928
+ whiteSpace: "nowrap"
929
+ },
930
+ // SummaryValue @media (max-width: 1024px)
931
+ summaryValue: {
932
+ color: "#fff",
933
+ fontWeight: 500,
934
+ fontSize: "0.8rem",
935
+ display: "flex",
936
+ alignItems: "center",
937
+ gap: "0.25rem",
938
+ overflow: "hidden",
939
+ flexShrink: 1,
940
+ minWidth: 0
941
+ },
942
+ // BoxedInput @media (max-width: 1024px)
943
+ boxedInput: {
944
+ background: "transparent",
945
+ border: "none",
946
+ fontWeight: 600,
947
+ fontSize: "0.8rem",
948
+ width: "50px",
949
+ textAlign: "right",
950
+ outline: "none",
951
+ padding: 0,
952
+ flexShrink: 0
953
+ },
954
+ // InputSuffix @media (max-width: 1024px)
955
+ inputSuffix: {
956
+ fontWeight: 600,
957
+ fontSize: "0.65rem",
958
+ marginLeft: "0.2rem",
959
+ display: "inline-flex",
960
+ alignItems: "center",
961
+ lineHeight: 1,
962
+ overflow: "hidden",
963
+ textOverflow: "ellipsis",
964
+ whiteSpace: "nowrap",
965
+ maxWidth: "80px"
966
+ },
967
+ // SummaryRow @media (max-width: 1024px)
968
+ summaryRow: {
969
+ display: "flex",
970
+ justifyContent: "space-between",
971
+ alignItems: "center",
972
+ fontSize: "0.8rem"
973
+ },
974
+ // OrderTypeToggle @media (max-width: 1024px)
975
+ orderTypeToggle: {
976
+ display: "flex",
977
+ backgroundColor: "rgba(255, 255, 255, 0.05)",
978
+ borderRadius: "6px",
979
+ padding: "2px",
980
+ marginBottom: 0,
981
+ width: "100%"
982
+ },
983
+ // OrderTypeButton @media (max-width: 1024px)
984
+ orderTypeButton: {
985
+ flex: 1,
986
+ padding: "0.35rem",
987
+ fontSize: "0.7rem",
988
+ fontWeight: 500,
989
+ border: "none",
990
+ borderRadius: "4px",
991
+ cursor: "pointer",
992
+ transition: "all 0.15s ease"
993
+ },
994
+ // AvailableFunds
995
+ availableFunds: {
996
+ width: "100%",
997
+ display: "flex",
998
+ justifyContent: "space-between",
999
+ alignItems: "center",
1000
+ fontSize: "0.75rem",
1001
+ color: "rgba(255, 255, 255, 0.5)"
1002
+ },
1003
+ // AddFundsButton
1004
+ addFundsButton: {
1005
+ background: "none",
1006
+ border: "none",
1007
+ color: "#f0b90b",
1008
+ fontSize: "0.75rem",
1009
+ cursor: "pointer",
1010
+ padding: 0
1011
+ }
1012
+ };
1013
+ function HousePositionSliderMobile({
1014
+ tokenId,
1015
+ tokenSymbol,
1016
+ totalTokens,
1017
+ currentPrice,
1018
+ availableCash,
1019
+ tokensHeld,
1020
+ defaultOrderType = "market",
1021
+ orderbook,
1022
+ ownershipPercentOverride,
1023
+ onConfirmOrder,
1024
+ className,
1025
+ ...props
1026
+ }) {
1027
+ const [orderMode, setOrderMode] = o__namespace.useState("none");
1028
+ const [deltaDollars, setDeltaDollars] = o__namespace.useState(0);
1029
+ const [deltaTokensSell, setDeltaTokensSell] = o__namespace.useState(0);
1030
+ const [deltaTokensBuy, setDeltaTokensBuy] = o__namespace.useState(0);
1031
+ const [buyTrackingMode, setBuyTrackingMode] = o__namespace.useState("dollars");
1032
+ const [orderType, setOrderType] = o__namespace.useState(defaultOrderType);
1033
+ const [limitPrice, setLimitPrice] = o__namespace.useState(currentPrice);
1034
+ const [limitPriceInput, setLimitPriceInput] = o__namespace.useState(currentPrice.toFixed(2));
1035
+ const [limitPriceDirty, setLimitPriceDirty] = o__namespace.useState(false);
1036
+ const [tokenAmountInput, setTokenAmountInput] = o__namespace.useState("");
1037
+ const houseRef = o__namespace.useRef(null);
1038
+ o__namespace.useEffect(() => {
1039
+ if (orderType !== "limit") return;
1040
+ if (limitPriceDirty) return;
1041
+ setLimitPrice(currentPrice);
1042
+ setLimitPriceInput(currentPrice.toFixed(2));
1043
+ }, [orderType, currentPrice, limitPriceDirty]);
1044
+ const effectivePrice = orderType === "limit" ? limitPrice : currentPrice;
1045
+ const holdingsValue = tokensHeld * effectivePrice;
1046
+ const totalCapacity = holdingsValue + availableCash;
1047
+ const baselinePct = totalCapacity > 0 ? holdingsValue / totalCapacity * 100 : 0;
1048
+ let deltaTokens;
1049
+ let deltaValue;
1050
+ let targetTokens;
1051
+ let targetValue;
1052
+ if (orderMode === "buy") {
1053
+ if (buyTrackingMode === "tokens") {
1054
+ deltaTokens = deltaTokensBuy;
1055
+ deltaValue = deltaTokensBuy * effectivePrice;
1056
+ targetTokens = tokensHeld + deltaTokensBuy;
1057
+ targetValue = targetTokens * effectivePrice;
1058
+ } else {
1059
+ deltaValue = deltaDollars;
1060
+ deltaTokens = effectivePrice > 0 ? deltaDollars / effectivePrice : 0;
1061
+ targetTokens = tokensHeld + deltaTokens;
1062
+ targetValue = targetTokens * effectivePrice;
1063
+ }
1064
+ } else if (orderMode === "sell") {
1065
+ deltaTokens = deltaTokensSell;
1066
+ deltaValue = deltaTokensSell * effectivePrice;
1067
+ targetTokens = tokensHeld + deltaTokensSell;
1068
+ targetValue = targetTokens * effectivePrice;
1069
+ } else {
1070
+ deltaTokens = 0;
1071
+ deltaValue = 0;
1072
+ targetTokens = tokensHeld;
1073
+ targetValue = holdingsValue;
1074
+ }
1075
+ const targetPct = totalCapacity > 0 ? targetValue / totalCapacity * 100 : 0;
1076
+ const isIncrease = orderMode === "buy";
1077
+ const hasChange = orderMode !== "none" && (Math.abs(deltaTokens) > 1e-3 || Math.abs(deltaValue) > 0.01);
1078
+ const targetOwnership = totalTokens > 0 ? targetTokens / totalTokens * 100 : 0;
1079
+ const estFeeTokens = effectivePrice > 0 ? Math.abs(deltaValue) * 5e-3 / effectivePrice : 0;
1080
+ const updateOrderFromTargetValue = o__namespace.useCallback(
1081
+ (newTargetValue) => {
1082
+ const newDeltaValue = newTargetValue - holdingsValue;
1083
+ if (newDeltaValue > 0.01) {
1084
+ const capped = Math.min(newDeltaValue, availableCash);
1085
+ setOrderMode("buy");
1086
+ setBuyTrackingMode("dollars");
1087
+ setDeltaDollars(capped);
1088
+ setDeltaTokensBuy(0);
1089
+ setDeltaTokensSell(0);
1090
+ } else if (newDeltaValue < -0.01) {
1091
+ const newDeltaTokens = effectivePrice > 0 ? newTargetValue / effectivePrice - tokensHeld : 0;
1092
+ const capped = Math.max(newDeltaTokens, -tokensHeld);
1093
+ setOrderMode("sell");
1094
+ setBuyTrackingMode("dollars");
1095
+ setDeltaTokensSell(capped);
1096
+ setDeltaDollars(0);
1097
+ setDeltaTokensBuy(0);
1098
+ } else {
1099
+ setOrderMode("none");
1100
+ setBuyTrackingMode("dollars");
1101
+ setDeltaDollars(0);
1102
+ setDeltaTokensBuy(0);
1103
+ setDeltaTokensSell(0);
1104
+ }
1105
+ },
1106
+ [holdingsValue, availableCash, effectivePrice, tokensHeld]
1107
+ );
1108
+ const updateOrderFromTokenAmount = o__namespace.useCallback(
1109
+ (tokenAmount) => {
1110
+ if (tokenAmount > 0) {
1111
+ const maxTokens = effectivePrice > 0 ? availableCash / effectivePrice : 0;
1112
+ const capped = Math.min(tokenAmount, maxTokens);
1113
+ setOrderMode("buy");
1114
+ setBuyTrackingMode("tokens");
1115
+ setDeltaTokensBuy(capped);
1116
+ setDeltaDollars(0);
1117
+ setDeltaTokensSell(0);
1118
+ } else if (tokenAmount < 0) {
1119
+ const capped = Math.max(tokenAmount, -tokensHeld);
1120
+ setOrderMode("sell");
1121
+ setBuyTrackingMode("dollars");
1122
+ setDeltaTokensSell(capped);
1123
+ setDeltaDollars(0);
1124
+ setDeltaTokensBuy(0);
1125
+ } else {
1126
+ setOrderMode("none");
1127
+ setBuyTrackingMode("dollars");
1128
+ setDeltaDollars(0);
1129
+ setDeltaTokensBuy(0);
1130
+ setDeltaTokensSell(0);
1131
+ }
1132
+ },
1133
+ [effectivePrice, availableCash, tokensHeld]
1134
+ );
1135
+ const handleMarkerClick = o__namespace.useCallback(
1136
+ (pct) => {
1137
+ const newTargetValue = pct / 100 * totalCapacity;
1138
+ updateOrderFromTargetValue(newTargetValue);
1139
+ },
1140
+ [totalCapacity, updateOrderFromTargetValue]
1141
+ );
1142
+ const onMouseDown = o__namespace.useCallback(
1143
+ (e) => {
1144
+ e.preventDefault();
1145
+ const move = (ev) => {
1146
+ if (!houseRef.current) return;
1147
+ const rect = houseRef.current.getBoundingClientRect();
1148
+ const y2 = ev.clientY - rect.top;
1149
+ const pct = clamp2(100 - y2 / rect.height * 100, 0, 100);
1150
+ const newTargetValue = pct / 100 * totalCapacity;
1151
+ updateOrderFromTargetValue(newTargetValue);
1152
+ };
1153
+ const up = () => {
1154
+ document.removeEventListener("mousemove", move);
1155
+ document.removeEventListener("mouseup", up);
1156
+ };
1157
+ document.addEventListener("mousemove", move);
1158
+ document.addEventListener("mouseup", up);
1159
+ },
1160
+ [totalCapacity, updateOrderFromTargetValue]
1161
+ );
1162
+ const onTouchStart = o__namespace.useCallback(
1163
+ (e) => {
1164
+ e.preventDefault();
1165
+ e.stopPropagation();
1166
+ const move = (ev) => {
1167
+ ev.preventDefault();
1168
+ ev.stopPropagation();
1169
+ if (!houseRef.current) return;
1170
+ const rect = houseRef.current.getBoundingClientRect();
1171
+ const touch = ev.touches[0];
1172
+ const y2 = touch.clientY - rect.top;
1173
+ const pct = clamp2(100 - y2 / rect.height * 100, 0, 100);
1174
+ const newTargetValue = pct / 100 * totalCapacity;
1175
+ updateOrderFromTargetValue(newTargetValue);
1176
+ };
1177
+ const up = () => {
1178
+ document.removeEventListener("touchmove", move);
1179
+ document.removeEventListener("touchend", up);
1180
+ };
1181
+ document.addEventListener("touchmove", move, { passive: false });
1182
+ document.addEventListener("touchend", up);
1183
+ },
1184
+ [totalCapacity, updateOrderFromTargetValue]
1185
+ );
1186
+ const handleConfirm = () => {
1187
+ if (!hasChange || !onConfirmOrder) return;
1188
+ onConfirmOrder({
1189
+ side: isIncrease ? "buy" : "sell",
1190
+ orderType,
1191
+ tokenId,
1192
+ tokenSymbol,
1193
+ price: effectivePrice,
1194
+ deltaTokens: Math.abs(deltaTokens),
1195
+ deltaValue: Math.abs(deltaValue),
1196
+ targetOwnership,
1197
+ targetTokens,
1198
+ targetValue
1199
+ });
1200
+ setOrderMode("none");
1201
+ setDeltaDollars(0);
1202
+ setDeltaTokensBuy(0);
1203
+ setDeltaTokensSell(0);
1204
+ };
1205
+ const rectTop = 10;
1206
+ const rectBottom = 150;
1207
+ const totalFillableHeight = rectBottom - rectTop;
1208
+ const baselineFillHeight = baselinePct / 100 * totalFillableHeight;
1209
+ const targetFillHeight = targetPct / 100 * totalFillableHeight;
1210
+ const baselineFillY = rectBottom - baselineFillHeight;
1211
+ const targetFillY = rectBottom - targetFillHeight;
1212
+ const showIncrease = targetPct > baselinePct;
1213
+ const showDecrease = targetPct < baselinePct;
1214
+ const valueLabel = `${tokenSymbol} OWNED`;
1215
+ const getBorderColor = () => {
1216
+ if (!hasChange) return "rgba(201, 162, 39, 0.5)";
1217
+ return isIncrease ? "rgba(14, 203, 129, 0.3)" : "rgba(246, 70, 93, 0.3)";
1218
+ };
1219
+ const getValueColor = () => {
1220
+ if (!hasChange) return "#fff";
1221
+ return isIncrease ? "#0ecb81" : "#f6465d";
1222
+ };
1223
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1224
+ "div",
1225
+ {
1226
+ style: styles.sliderContainer,
1227
+ className,
1228
+ ...props,
1229
+ children: [
1230
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.valueDisplay, children: [
1231
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.valueLabel, children: valueLabel }),
1232
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.valueAmount, children: [
1233
+ "$",
1234
+ fmt02(targetValue)
1235
+ ] })
1236
+ ] }),
1237
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.houseWrapper, children: /* @__PURE__ */ jsxRuntime.jsxs(
1238
+ "div",
1239
+ {
1240
+ ref: houseRef,
1241
+ style: styles.houseContainer,
1242
+ onMouseDown,
1243
+ onTouchStart,
1244
+ children: [
1245
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 120 160", style: { width: "100%", height: "100%", overflow: "visible" }, children: [
1246
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
1247
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "mobile-clip", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "12", y: "12", width: "96", height: "136", rx: "6" }) }),
1248
+ /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "mobileGoldFill", x1: "0%", y1: "0%", x2: "0%", y2: "100%", children: [
1249
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: "rgba(220, 175, 120, 0.7)" }),
1250
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: "rgba(220, 175, 120, 0.7)" })
1251
+ ] }),
1252
+ /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "mobileGreenFill", x1: "0%", y1: "0%", x2: "0%", y2: "100%", children: [
1253
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: "rgba(14, 203, 129, 0.5)" }),
1254
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: "rgba(14, 203, 129, 0.2)" })
1255
+ ] }),
1256
+ /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "mobileRedFill", x1: "0%", y1: "0%", x2: "0%", y2: "100%", children: [
1257
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: "rgba(246, 70, 93, 0.15)" }),
1258
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: "rgba(246, 70, 93, 0.5)" })
1259
+ ] }),
1260
+ /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "mobileGoldGlow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1261
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "6", result: "blur" }),
1262
+ /* @__PURE__ */ jsxRuntime.jsx("feFlood", { floodColor: "rgba(234, 217, 162, 0.6)", result: "color" }),
1263
+ /* @__PURE__ */ jsxRuntime.jsx("feComposite", { in: "color", in2: "blur", operator: "in", result: "glow" }),
1264
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1265
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "glow" }),
1266
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1267
+ ] })
1268
+ ] }),
1269
+ /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "mobileGreenGlow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1270
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "6", result: "blur" }),
1271
+ /* @__PURE__ */ jsxRuntime.jsx("feFlood", { floodColor: "rgba(14, 203, 129, 0.6)", result: "color" }),
1272
+ /* @__PURE__ */ jsxRuntime.jsx("feComposite", { in: "color", in2: "blur", operator: "in", result: "glow" }),
1273
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1274
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "glow" }),
1275
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1276
+ ] })
1277
+ ] }),
1278
+ /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "mobileRedGlow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1279
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "6", result: "blur" }),
1280
+ /* @__PURE__ */ jsxRuntime.jsx("feFlood", { floodColor: "rgba(246, 70, 93, 0.6)", result: "color" }),
1281
+ /* @__PURE__ */ jsxRuntime.jsx("feComposite", { in: "color", in2: "blur", operator: "in", result: "glow" }),
1282
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1283
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "glow" }),
1284
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1285
+ ] })
1286
+ ] })
1287
+ ] }),
1288
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "10", y: "10", width: "100", height: "140", rx: "8", fill: "rgba(255,255,255,0.04)" }),
1289
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: "url(#mobile-clip)", children: [
1290
+ /* @__PURE__ */ jsxRuntime.jsx(
1291
+ "rect",
1292
+ {
1293
+ x: "10",
1294
+ y: showDecrease ? targetFillY : baselineFillY,
1295
+ width: "100",
1296
+ height: showDecrease ? targetFillHeight : baselineFillHeight,
1297
+ fill: "url(#mobileGoldFill)"
1298
+ }
1299
+ ),
1300
+ showIncrease && /* @__PURE__ */ jsxRuntime.jsx(
1301
+ "rect",
1302
+ {
1303
+ x: "10",
1304
+ y: targetFillY,
1305
+ width: "100",
1306
+ height: targetFillHeight - baselineFillHeight,
1307
+ fill: "url(#mobileGreenFill)"
1308
+ }
1309
+ ),
1310
+ showDecrease && /* @__PURE__ */ jsxRuntime.jsx(
1311
+ "rect",
1312
+ {
1313
+ x: "10",
1314
+ y: baselineFillY,
1315
+ width: "100",
1316
+ height: baselineFillHeight - targetFillHeight,
1317
+ fill: "url(#mobileRedFill)"
1318
+ }
1319
+ ),
1320
+ /* @__PURE__ */ jsxRuntime.jsx(
1321
+ "line",
1322
+ {
1323
+ x1: "12",
1324
+ y1: targetFillY,
1325
+ x2: "108",
1326
+ y2: targetFillY,
1327
+ stroke: showIncrease ? "rgba(14, 203, 129, 1)" : showDecrease ? "rgba(246, 70, 93, 1)" : "rgba(234, 217, 162, 1)",
1328
+ strokeWidth: "2",
1329
+ strokeLinecap: "round",
1330
+ filter: showIncrease ? "url(#mobileGreenGlow)" : showDecrease ? "url(#mobileRedGlow)" : "url(#mobileGoldGlow)"
1331
+ }
1332
+ )
1333
+ ] }),
1334
+ /* @__PURE__ */ jsxRuntime.jsx(
1335
+ "rect",
1336
+ {
1337
+ x: "10",
1338
+ y: "10",
1339
+ width: "100",
1340
+ height: "140",
1341
+ rx: "8",
1342
+ fill: "none",
1343
+ stroke: showIncrease ? "rgba(14, 203, 129, 0.6)" : showDecrease ? "rgba(246, 70, 93, 0.6)" : "rgba(234, 217, 162, 0.6)",
1344
+ strokeWidth: "2",
1345
+ filter: showIncrease ? "url(#mobileGreenGlow)" : showDecrease ? "url(#mobileRedGlow)" : "url(#mobileGoldGlow)"
1346
+ }
1347
+ ),
1348
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "10", y: "10", width: "100", height: "140", rx: "8", fill: "none", stroke: "rgba(255, 255, 255, 0.1)", strokeWidth: "1" })
1349
+ ] }),
1350
+ /* @__PURE__ */ jsxRuntime.jsx(
1351
+ "div",
1352
+ {
1353
+ style: styles.mobilePercentButtons,
1354
+ onMouseDown: (e) => e.stopPropagation(),
1355
+ onTouchStart: (e) => e.stopPropagation(),
1356
+ children: [100, 50, 25, 0].map((pct) => /* @__PURE__ */ jsxRuntime.jsxs(
1357
+ "button",
1358
+ {
1359
+ type: "button",
1360
+ style: styles.mobilePercentBtn,
1361
+ onClick: (e) => {
1362
+ e.stopPropagation();
1363
+ handleMarkerClick(pct);
1364
+ },
1365
+ children: [
1366
+ pct,
1367
+ "%"
1368
+ ]
1369
+ },
1370
+ pct
1371
+ ))
1372
+ }
1373
+ )
1374
+ ]
1375
+ }
1376
+ ) }),
1377
+ /* @__PURE__ */ jsxRuntime.jsx(
1378
+ "button",
1379
+ {
1380
+ type: "button",
1381
+ disabled: !hasChange,
1382
+ onClick: handleConfirm,
1383
+ style: {
1384
+ ...styles.confirmButton,
1385
+ backgroundColor: !hasChange ? "rgba(255, 255, 255, 0.1)" : isIncrease ? "#0ecb81" : "#f6465d",
1386
+ color: !hasChange ? "rgba(255, 255, 255, 0.3)" : "#fff",
1387
+ cursor: !hasChange ? "not-allowed" : "pointer"
1388
+ },
1389
+ children: !hasChange ? "Adjust Position" : isIncrease ? `Buy $${fmt02(deltaValue)}` : `Sell $${fmt02(deltaValue)}`
1390
+ }
1391
+ ),
1392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.summarySection, children: [
1393
+ /* @__PURE__ */ jsxRuntime.jsxs(
1394
+ "div",
1395
+ {
1396
+ style: {
1397
+ ...styles.boxedSummaryRow,
1398
+ border: `1px solid ${getBorderColor()}`
1399
+ },
1400
+ onClick: (e) => {
1401
+ const input = e.currentTarget.querySelector("input");
1402
+ if (input && e.target !== input) {
1403
+ input.focus();
1404
+ const len = input.value.length;
1405
+ input.setSelectionRange(len, len);
1406
+ }
1407
+ },
1408
+ children: [
1409
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.summaryLabel, children: isIncrease ? "Est. Buy" : "Est. Sell" }),
1410
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles.summaryValue, children: [
1411
+ /* @__PURE__ */ jsxRuntime.jsx(
1412
+ "input",
1413
+ {
1414
+ type: "text",
1415
+ value: tokenAmountInput || Math.abs(deltaTokens).toFixed(2),
1416
+ onChange: (e) => {
1417
+ const val = e.target.value;
1418
+ if (val === "" || /^[0-9]*\.?[0-9]*$/.test(val)) setTokenAmountInput(val);
1419
+ },
1420
+ onFocus: () => setTokenAmountInput(Math.abs(deltaTokens).toFixed(2)),
1421
+ onBlur: () => {
1422
+ const num = Number.parseFloat(tokenAmountInput);
1423
+ if (Number.isFinite(num) && num >= 0) {
1424
+ const signed = isIncrease || orderMode === "none" ? num : -num;
1425
+ updateOrderFromTokenAmount(signed);
1426
+ }
1427
+ setTokenAmountInput("");
1428
+ },
1429
+ onKeyDown: (e) => {
1430
+ if (e.key === "Enter") e.target.blur();
1431
+ },
1432
+ style: {
1433
+ ...styles.boxedInput,
1434
+ color: getValueColor()
1435
+ }
1436
+ }
1437
+ ),
1438
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles.inputSuffix, color: getValueColor() }, children: tokenSymbol })
1439
+ ] })
1440
+ ]
1441
+ }
1442
+ ),
1443
+ /* @__PURE__ */ jsxRuntime.jsxs(
1444
+ "div",
1445
+ {
1446
+ style: {
1447
+ ...styles.boxedSummaryRow,
1448
+ border: `1px solid ${getBorderColor()}`
1449
+ },
1450
+ onClick: (e) => {
1451
+ if (orderType === "limit") {
1452
+ const input = e.currentTarget.querySelector("input");
1453
+ if (input && e.target !== input) {
1454
+ input.focus();
1455
+ const len = input.value.length;
1456
+ input.setSelectionRange(len, len);
1457
+ }
1458
+ }
1459
+ },
1460
+ children: [
1461
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.summaryLabel, children: orderType === "market" ? "Price" : "Limit Price" }),
1462
+ orderType === "market" ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, color: "rgba(255, 255, 255, 0.6)", fontSize: "0.8rem" }, children: "Market" }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles.summaryValue, children: [
1463
+ /* @__PURE__ */ jsxRuntime.jsx(
1464
+ "input",
1465
+ {
1466
+ type: "text",
1467
+ value: limitPriceInput,
1468
+ onChange: (e) => {
1469
+ const input = e.target.value;
1470
+ if (input === "" || /^[0-9]*\.?[0-9]*$/.test(input)) {
1471
+ setLimitPriceDirty(true);
1472
+ setLimitPriceInput(input);
1473
+ const num = Number.parseFloat(input);
1474
+ if (Number.isFinite(num) && num > 0) setLimitPrice(num);
1475
+ }
1476
+ },
1477
+ onBlur: () => {
1478
+ const num = Number.parseFloat(limitPriceInput);
1479
+ if (Number.isFinite(num) && num > 0) {
1480
+ setLimitPriceInput(num.toFixed(2));
1481
+ setLimitPrice(num);
1482
+ } else {
1483
+ setLimitPriceInput(limitPrice.toFixed(2));
1484
+ }
1485
+ },
1486
+ onKeyDown: (e) => {
1487
+ if (e.key === "Enter") e.target.blur();
1488
+ },
1489
+ style: {
1490
+ ...styles.boxedInput,
1491
+ color: getValueColor()
1492
+ }
1493
+ }
1494
+ ),
1495
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles.inputSuffix, color: getValueColor() }, children: "USD" })
1496
+ ] })
1497
+ ]
1498
+ }
1499
+ ),
1500
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.summaryRow, children: [
1501
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.summaryLabel, children: "Est. Fee" }),
1502
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: "#fff", fontWeight: 500, fontSize: "0.8rem" }, children: [
1503
+ estFeeTokens.toFixed(6),
1504
+ " ",
1505
+ tokenSymbol
1506
+ ] })
1507
+ ] })
1508
+ ] }),
1509
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.orderTypeToggle, children: [
1510
+ /* @__PURE__ */ jsxRuntime.jsx(
1511
+ "button",
1512
+ {
1513
+ type: "button",
1514
+ onClick: () => setOrderType("market"),
1515
+ style: {
1516
+ ...styles.orderTypeButton,
1517
+ backgroundColor: orderType === "market" ? "rgba(201, 162, 39, 0.2)" : "transparent",
1518
+ color: orderType === "market" ? "#C9A227" : "rgba(255, 255, 255, 0.5)"
1519
+ },
1520
+ children: "Market"
1521
+ }
1522
+ ),
1523
+ /* @__PURE__ */ jsxRuntime.jsx(
1524
+ "button",
1525
+ {
1526
+ type: "button",
1527
+ onClick: () => setOrderType("limit"),
1528
+ style: {
1529
+ ...styles.orderTypeButton,
1530
+ backgroundColor: orderType === "limit" ? "rgba(201, 162, 39, 0.2)" : "transparent",
1531
+ color: orderType === "limit" ? "#C9A227" : "rgba(255, 255, 255, 0.5)"
1532
+ },
1533
+ children: "Limit"
1534
+ }
1535
+ )
1536
+ ] }),
1537
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.availableFunds, children: [
1538
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1539
+ "Cash: $",
1540
+ availableCash.toLocaleString()
1541
+ ] }),
1542
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: styles.addFundsButton, children: "Add Funds" })
1543
+ ] })
1544
+ ]
1545
+ }
1546
+ );
1547
+ }
808
1548
 
809
1549
  // ../../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs
810
1550
  var __assign = function() {
@@ -2346,6 +3086,17 @@ var LoafLiquidityBadge = o__namespace.forwardRef(
2346
3086
  }
2347
3087
  );
2348
3088
  LoafLiquidityBadge.displayName = "LoafLiquidityBadge";
3089
+ function useViewportCompact(breakpoint) {
3090
+ const [isCompact, setIsCompact] = o__namespace.useState(false);
3091
+ o__namespace.useEffect(() => {
3092
+ if (typeof window === "undefined") return;
3093
+ const check = () => setIsCompact(window.innerWidth <= breakpoint);
3094
+ check();
3095
+ window.addEventListener("resize", check);
3096
+ return () => window.removeEventListener("resize", check);
3097
+ }, [breakpoint]);
3098
+ return isCompact;
3099
+ }
2349
3100
  var formatNumber = (value, precision) => value.toFixed(precision);
2350
3101
  function DepthRow({
2351
3102
  side,
@@ -2364,7 +3115,7 @@ function DepthRow({
2364
3115
  "absolute inset-y-0 right-0",
2365
3116
  isAsk ? "bg-rose-900/30" : "bg-emerald-900/30"
2366
3117
  ),
2367
- style: { width: `${clamp2(depthPct, 0, 100)}%` }
3118
+ style: { width: `${clamp3(depthPct, 0, 100)}%` }
2368
3119
  }
2369
3120
  ),
2370
3121
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2380,10 +3131,12 @@ function DepthRow({
2380
3131
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-[1] text-right tabular-nums text-white/90", children: formatNumber(amount, amountPrecision) })
2381
3132
  ] });
2382
3133
  }
2383
- var clamp2 = (value, min, max) => Math.min(max, Math.max(min, value));
3134
+ var clamp3 = (value, min, max) => Math.min(max, Math.max(min, value));
2384
3135
  var LEVEL_ROWS_VISIBLE = 6;
2385
3136
  var DEPTH_ROW_HEIGHT_PX = 34;
2386
- var SECTION_HEIGHT = LEVEL_ROWS_VISIBLE * DEPTH_ROW_HEIGHT_PX;
3137
+ var COMPACT_ROWS_VISIBLE = 5;
3138
+ var COMPACT_ROW_HEIGHT_PX = 30;
3139
+ var COMPACT_BREAKPOINT_PX = 1024;
2387
3140
  var Orderbook = o__namespace.forwardRef(
2388
3141
  ({
2389
3142
  asks,
@@ -2398,11 +3151,13 @@ var Orderbook = o__namespace.forwardRef(
2398
3151
  defaultTab = "orderbook",
2399
3152
  onTabChange,
2400
3153
  rightHeader = /* @__PURE__ */ jsxRuntime.jsx(LoafLiquidityBadge, { className: "text-[0.6rem]" }),
3154
+ variant = "auto",
2401
3155
  className,
2402
3156
  ...props
2403
3157
  }, ref) => {
2404
3158
  const [tab, setTab] = o__namespace.useState(defaultTab);
2405
3159
  const [tradeFilter, setTradeFilter] = o__namespace.useState("all");
3160
+ const viewportCompact = useViewportCompact(COMPACT_BREAKPOINT_PX);
2406
3161
  o__namespace.useEffect(() => {
2407
3162
  setTab(defaultTab);
2408
3163
  }, [defaultTab]);
@@ -2410,178 +3165,450 @@ var Orderbook = o__namespace.forwardRef(
2410
3165
  setTab(next2);
2411
3166
  onTabChange?.(next2);
2412
3167
  };
3168
+ const isCompact = variant === "compact" || variant === "auto" && viewportCompact;
3169
+ const sectionHeight = isCompact ? COMPACT_ROWS_VISIBLE * COMPACT_ROW_HEIGHT_PX : LEVEL_ROWS_VISIBLE * DEPTH_ROW_HEIGHT_PX;
2413
3170
  const maxAskDepth = Math.max(1, ...asks.map((l2) => l2.depth ?? l2.amount));
2414
3171
  const maxBidDepth = Math.max(1, ...bids.map((l2) => l2.depth ?? l2.amount));
2415
3172
  const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
2416
3173
  const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
2417
- return /* @__PURE__ */ jsxRuntime.jsxs(
3174
+ const layoutProps = {
3175
+ tab,
3176
+ handleTab,
3177
+ tradeFilter,
3178
+ setTradeFilter,
3179
+ rightHeader,
3180
+ priceLabel,
3181
+ amountLabel,
3182
+ tradeFiltered,
3183
+ precision,
3184
+ amountPrecision,
3185
+ asks,
3186
+ bids,
3187
+ maxAskDepth,
3188
+ maxBidDepth,
3189
+ midPrice,
3190
+ midChangePercent,
3191
+ midClass,
3192
+ sectionHeight
3193
+ };
3194
+ return /* @__PURE__ */ jsxRuntime.jsx(
2418
3195
  Card,
2419
3196
  {
2420
3197
  ref,
2421
3198
  className: cn(
2422
3199
  "w-full max-w-[520px] overflow-hidden rounded-[12px] border border-white/10 bg-[#111111] text-white shadow-md",
3200
+ isCompact && "max-w-none",
2423
3201
  className
2424
3202
  ),
2425
3203
  ...props,
2426
- children: [
2427
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 pt-4", children: [
2428
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
2429
- /* @__PURE__ */ jsxRuntime.jsxs(
2430
- "button",
2431
- {
2432
- type: "button",
2433
- onClick: () => handleTab("orderbook"),
2434
- className: cn(
2435
- "relative pb-2 text-sm font-semibold",
2436
- tab === "orderbook" ? "text-white" : "text-white/60"
2437
- ),
2438
- children: [
2439
- "Orderbook",
2440
- tab === "orderbook" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-px left-0 h-[2px] w-full bg-[#C9A227]" }) : null
2441
- ]
2442
- }
2443
- ),
2444
- /* @__PURE__ */ jsxRuntime.jsxs(
2445
- "button",
2446
- {
2447
- type: "button",
2448
- onClick: () => handleTab("trades"),
2449
- className: cn(
2450
- "relative pb-2 text-sm font-medium",
2451
- tab === "trades" ? "text-white" : "text-white/60"
2452
- ),
2453
- children: [
2454
- "Trades",
2455
- tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-px left-0 h-[2px] w-full bg-[#C9A227]" }) : null
2456
- ]
2457
- }
2458
- )
2459
- ] }),
2460
- tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-xs", children: [
2461
- /* @__PURE__ */ jsxRuntime.jsx(
2462
- "button",
2463
- {
2464
- type: "button",
2465
- onClick: () => setTradeFilter("all"),
2466
- className: cn(
2467
- "rounded-md px-2 py-1 transition",
2468
- tradeFilter === "all" ? "bg-white/10 text-white" : "text-white/70 hover:bg-white/10"
2469
- ),
2470
- children: "All"
2471
- }
2472
- ),
2473
- /* @__PURE__ */ jsxRuntime.jsx(
2474
- "button",
2475
- {
2476
- type: "button",
2477
- onClick: () => setTradeFilter("buy"),
2478
- className: cn(
2479
- "rounded-md px-2 py-1 transition",
2480
- tradeFilter === "buy" ? "bg-white/10 text-white" : "text-white/70 hover:bg-white/10"
2481
- ),
2482
- children: "Buy"
2483
- }
2484
- ),
2485
- /* @__PURE__ */ jsxRuntime.jsx(
2486
- "button",
2487
- {
2488
- type: "button",
2489
- onClick: () => setTradeFilter("sell"),
2490
- className: cn(
2491
- "rounded-md px-2 py-1 transition",
2492
- tradeFilter === "sell" ? "bg-white/10 text-white" : "text-white/70 hover:bg-white/10"
2493
- ),
2494
- children: "Sell"
2495
- }
2496
- )
2497
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: rightHeader })
2498
- ] }),
2499
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 pb-3 pt-2", children: [
2500
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-3 py-2 text-xs text-white/60", children: [
2501
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: priceLabel }),
2502
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: amountLabel })
2503
- ] }),
2504
- tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx(
2505
- "div",
2506
- {
2507
- className: "max-h-[380px] overflow-y-auto overflow-x-hidden",
2508
- style: { scrollbarGutter: "stable" },
2509
- children: tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-10 text-center text-sm text-white/50", children: "No trades" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-white/5", children: tradeFiltered.map((trade, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3 px-3 py-1.5", children: [
2510
- /* @__PURE__ */ jsxRuntime.jsxs(
2511
- "div",
2512
- {
2513
- className: cn(
2514
- "tabular-nums",
2515
- trade.type === "buy" ? "text-[#0ecb81]" : "text-[#f6465d]"
2516
- ),
2517
- children: [
2518
- "$",
2519
- formatNumber(trade.price, precision)
2520
- ]
2521
- }
2522
- ),
2523
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right tabular-nums text-white/90", children: formatNumber(trade.amount, amountPrecision) })
2524
- ] }, `${trade.type}-${trade.price}-${trade.amount}-${trade.time ?? i}`)) })
2525
- }
2526
- ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2527
- /* @__PURE__ */ jsxRuntime.jsx(
2528
- "div",
2529
- {
2530
- className: "divide-y divide-white/5 overflow-y-auto",
2531
- style: { height: `${SECTION_HEIGHT}px`, scrollbarGutter: "stable" },
2532
- children: asks.map((l2, idx) => /* @__PURE__ */ jsxRuntime.jsx(
2533
- DepthRow,
2534
- {
2535
- side: "ask",
2536
- price: l2.price,
2537
- amount: l2.amount,
2538
- depthPct: (l2.depth ?? l2.amount) / maxAskDepth * 100,
2539
- precision,
2540
- amountPrecision
2541
- },
2542
- `ask-${idx}-${l2.price}-${l2.amount}`
2543
- ))
2544
- }
2545
- ),
2546
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2", children: [
2547
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-lg font-semibold tabular-nums", midClass), children: [
2548
- "$",
2549
- formatNumber(midPrice, precision),
2550
- midChangePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-sm font-semibold", children: [
2551
- midChangePercent >= 0 ? "+" : "",
2552
- midChangePercent.toFixed(2),
2553
- "%"
2554
- ] })
2555
- ] }),
2556
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
2557
- ] }),
2558
- /* @__PURE__ */ jsxRuntime.jsx(
2559
- "div",
2560
- {
2561
- className: "divide-y divide-white/5 overflow-y-auto",
2562
- style: { height: `${SECTION_HEIGHT}px`, scrollbarGutter: "stable" },
2563
- children: bids.map((l2, idx) => /* @__PURE__ */ jsxRuntime.jsx(
2564
- DepthRow,
2565
- {
2566
- side: "bid",
2567
- price: l2.price,
2568
- amount: l2.amount,
2569
- depthPct: (l2.depth ?? l2.amount) / maxBidDepth * 100,
2570
- precision,
2571
- amountPrecision
2572
- },
2573
- `bid-${idx}-${l2.price}-${l2.amount}`
2574
- ))
2575
- }
2576
- )
2577
- ] })
2578
- ] })
2579
- ]
3204
+ children: isCompact ? /* @__PURE__ */ jsxRuntime.jsx(MobileOrderbookLayout, { ...layoutProps }) : /* @__PURE__ */ jsxRuntime.jsx(DesktopOrderbookLayout, { ...layoutProps })
2580
3205
  }
2581
3206
  );
2582
3207
  }
2583
3208
  );
2584
3209
  Orderbook.displayName = "Orderbook";
3210
+ function DesktopOrderbookLayout({
3211
+ tab,
3212
+ handleTab,
3213
+ tradeFilter,
3214
+ setTradeFilter,
3215
+ rightHeader,
3216
+ priceLabel,
3217
+ amountLabel,
3218
+ tradeFiltered,
3219
+ precision,
3220
+ amountPrecision,
3221
+ asks,
3222
+ bids,
3223
+ maxAskDepth,
3224
+ maxBidDepth,
3225
+ midPrice,
3226
+ midChangePercent,
3227
+ midClass,
3228
+ sectionHeight
3229
+ }) {
3230
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3231
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 pt-4", children: [
3232
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
3233
+ /* @__PURE__ */ jsxRuntime.jsxs(
3234
+ "button",
3235
+ {
3236
+ type: "button",
3237
+ onClick: () => handleTab("orderbook"),
3238
+ className: cn(
3239
+ "relative pb-2 text-sm font-semibold",
3240
+ tab === "orderbook" ? "text-white" : "text-white/60"
3241
+ ),
3242
+ children: [
3243
+ "Orderbook",
3244
+ tab === "orderbook" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-px left-0 h-[2px] w-full bg-[#C9A227]" }) : null
3245
+ ]
3246
+ }
3247
+ ),
3248
+ /* @__PURE__ */ jsxRuntime.jsxs(
3249
+ "button",
3250
+ {
3251
+ type: "button",
3252
+ onClick: () => handleTab("trades"),
3253
+ className: cn(
3254
+ "relative pb-2 text-sm font-medium",
3255
+ tab === "trades" ? "text-white" : "text-white/60"
3256
+ ),
3257
+ children: [
3258
+ "Trades",
3259
+ tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-px left-0 h-[2px] w-full bg-[#C9A227]" }) : null
3260
+ ]
3261
+ }
3262
+ )
3263
+ ] }),
3264
+ tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-xs", children: [
3265
+ /* @__PURE__ */ jsxRuntime.jsx(
3266
+ "button",
3267
+ {
3268
+ type: "button",
3269
+ onClick: () => setTradeFilter("all"),
3270
+ className: cn(
3271
+ "rounded-md px-2 py-1 transition",
3272
+ tradeFilter === "all" ? "bg-white/10 text-white" : "text-white/70 hover:bg-white/10"
3273
+ ),
3274
+ children: "All"
3275
+ }
3276
+ ),
3277
+ /* @__PURE__ */ jsxRuntime.jsx(
3278
+ "button",
3279
+ {
3280
+ type: "button",
3281
+ onClick: () => setTradeFilter("buy"),
3282
+ className: cn(
3283
+ "rounded-md px-2 py-1 transition",
3284
+ tradeFilter === "buy" ? "bg-white/10 text-white" : "text-white/70 hover:bg-white/10"
3285
+ ),
3286
+ children: "Buy"
3287
+ }
3288
+ ),
3289
+ /* @__PURE__ */ jsxRuntime.jsx(
3290
+ "button",
3291
+ {
3292
+ type: "button",
3293
+ onClick: () => setTradeFilter("sell"),
3294
+ className: cn(
3295
+ "rounded-md px-2 py-1 transition",
3296
+ tradeFilter === "sell" ? "bg-white/10 text-white" : "text-white/70 hover:bg-white/10"
3297
+ ),
3298
+ children: "Sell"
3299
+ }
3300
+ )
3301
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: rightHeader })
3302
+ ] }),
3303
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 pb-3 pt-2", children: [
3304
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-3 py-2 text-xs text-white/60", children: [
3305
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: priceLabel }),
3306
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: amountLabel })
3307
+ ] }),
3308
+ tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx(
3309
+ "div",
3310
+ {
3311
+ className: "max-h-[380px] overflow-y-auto overflow-x-hidden",
3312
+ style: { scrollbarGutter: "stable" },
3313
+ children: tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-10 text-center text-sm text-white/50", children: "No trades" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-white/5", children: tradeFiltered.map((trade, i) => /* @__PURE__ */ jsxRuntime.jsxs(
3314
+ "div",
3315
+ {
3316
+ className: "grid grid-cols-2 items-center gap-3 px-3 py-1.5",
3317
+ children: [
3318
+ /* @__PURE__ */ jsxRuntime.jsxs(
3319
+ "div",
3320
+ {
3321
+ className: cn(
3322
+ "tabular-nums",
3323
+ trade.type === "buy" ? "text-[#0ecb81]" : "text-[#f6465d]"
3324
+ ),
3325
+ children: [
3326
+ "$",
3327
+ formatNumber(trade.price, precision)
3328
+ ]
3329
+ }
3330
+ ),
3331
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right tabular-nums text-white/90", children: formatNumber(trade.amount, amountPrecision) })
3332
+ ]
3333
+ },
3334
+ `${trade.type}-${trade.price}-${trade.amount}-${trade.time ?? i}`
3335
+ )) })
3336
+ }
3337
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3338
+ /* @__PURE__ */ jsxRuntime.jsx(
3339
+ "div",
3340
+ {
3341
+ className: "divide-y divide-white/5 overflow-y-auto",
3342
+ style: { height: `${sectionHeight}px`, scrollbarGutter: "stable" },
3343
+ children: asks.map((l2, idx) => /* @__PURE__ */ jsxRuntime.jsx(
3344
+ DepthRow,
3345
+ {
3346
+ side: "ask",
3347
+ price: l2.price,
3348
+ amount: l2.amount,
3349
+ depthPct: (l2.depth ?? l2.amount) / maxAskDepth * 100,
3350
+ precision,
3351
+ amountPrecision
3352
+ },
3353
+ `ask-${idx}-${l2.price}-${l2.amount}`
3354
+ ))
3355
+ }
3356
+ ),
3357
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2", children: [
3358
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-lg font-semibold tabular-nums", midClass), children: [
3359
+ "$",
3360
+ formatNumber(midPrice, precision),
3361
+ midChangePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-sm font-semibold", children: [
3362
+ midChangePercent >= 0 ? "+" : "",
3363
+ midChangePercent.toFixed(2),
3364
+ "%"
3365
+ ] })
3366
+ ] }),
3367
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
3368
+ ] }),
3369
+ /* @__PURE__ */ jsxRuntime.jsx(
3370
+ "div",
3371
+ {
3372
+ className: "divide-y divide-white/5 overflow-y-auto",
3373
+ style: { height: `${sectionHeight}px`, scrollbarGutter: "stable" },
3374
+ children: bids.map((l2, idx) => /* @__PURE__ */ jsxRuntime.jsx(
3375
+ DepthRow,
3376
+ {
3377
+ side: "bid",
3378
+ price: l2.price,
3379
+ amount: l2.amount,
3380
+ depthPct: (l2.depth ?? l2.amount) / maxBidDepth * 100,
3381
+ precision,
3382
+ amountPrecision
3383
+ },
3384
+ `bid-${idx}-${l2.price}-${l2.amount}`
3385
+ ))
3386
+ }
3387
+ )
3388
+ ] })
3389
+ ] })
3390
+ ] });
3391
+ }
3392
+ function MobileOrderbookLayout({
3393
+ tab,
3394
+ handleTab,
3395
+ tradeFilter,
3396
+ setTradeFilter,
3397
+ rightHeader,
3398
+ priceLabel,
3399
+ amountLabel,
3400
+ tradeFiltered,
3401
+ precision,
3402
+ amountPrecision,
3403
+ asks,
3404
+ bids,
3405
+ maxAskDepth,
3406
+ maxBidDepth,
3407
+ midPrice,
3408
+ midChangePercent,
3409
+ midClass,
3410
+ sectionHeight
3411
+ }) {
3412
+ const visibleAsks = o__namespace.useMemo(() => asks.slice(0, COMPACT_ROWS_VISIBLE), [asks]);
3413
+ const visibleBids = o__namespace.useMemo(() => bids.slice(0, COMPACT_ROWS_VISIBLE), [bids]);
3414
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3415
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
3416
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
3417
+ /* @__PURE__ */ jsxRuntime.jsx(
3418
+ "span",
3419
+ {
3420
+ onClick: () => handleTab("orderbook"),
3421
+ style: {
3422
+ cursor: "pointer",
3423
+ fontSize: "0.8rem",
3424
+ fontWeight: tab === "orderbook" ? 600 : 400,
3425
+ color: tab === "orderbook" ? "#fff" : "rgba(255,255,255,0.6)",
3426
+ borderBottom: tab === "orderbook" ? "2px solid #C9A227" : "none",
3427
+ paddingBottom: "0.25rem"
3428
+ },
3429
+ children: "Orderbook"
3430
+ }
3431
+ ),
3432
+ /* @__PURE__ */ jsxRuntime.jsx(
3433
+ "span",
3434
+ {
3435
+ onClick: () => handleTab("trades"),
3436
+ style: {
3437
+ cursor: "pointer",
3438
+ fontSize: "0.8rem",
3439
+ fontWeight: tab === "trades" ? 600 : 400,
3440
+ color: tab === "trades" ? "#fff" : "rgba(255,255,255,0.6)",
3441
+ borderBottom: tab === "trades" ? "2px solid #C9A227" : "none",
3442
+ paddingBottom: "0.25rem"
3443
+ },
3444
+ children: "Trades"
3445
+ }
3446
+ )
3447
+ ] }),
3448
+ tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 text-[0.6rem] text-white/70", children: ["all", "buy", "sell"].map((filter2) => /* @__PURE__ */ jsxRuntime.jsx(
3449
+ "button",
3450
+ {
3451
+ type: "button",
3452
+ onClick: () => setTradeFilter(filter2),
3453
+ className: cn(
3454
+ "rounded-md border border-white/15 px-2 py-1",
3455
+ tradeFilter === filter2 ? "bg-white/15 text-white" : "hover:bg-white/10"
3456
+ ),
3457
+ children: filter2 === "all" ? "All" : filter2 === "buy" ? "Buy" : "Sell"
3458
+ },
3459
+ filter2
3460
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden text-xs text-white/70 sm:flex", children: rightHeader })
3461
+ ] }) }),
3462
+ tab === "orderbook" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden px-3 pb-2", children: [
3463
+ /* @__PURE__ */ jsxRuntime.jsx(
3464
+ "div",
3465
+ {
3466
+ className: "inline-flex sm:hidden",
3467
+ style: { padding: "0.5rem 0", marginBottom: "0.5rem", transform: "scale(0.85)", transformOrigin: "left center" },
3468
+ children: rightHeader
3469
+ }
3470
+ ),
3471
+ /* @__PURE__ */ jsxRuntime.jsxs(
3472
+ "div",
3473
+ {
3474
+ className: "grid text-white/60",
3475
+ style: { gridTemplateColumns: "1.2fr 0.8fr", padding: "0.3rem 0 0.2rem 0", fontSize: "0.75rem", fontWeight: 500 },
3476
+ children: [
3477
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: priceLabel }),
3478
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right", paddingRight: "0.5rem" }, children: amountLabel })
3479
+ ]
3480
+ }
3481
+ ),
3482
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: visibleAsks.map((l2, idx) => /* @__PURE__ */ jsxRuntime.jsx(
3483
+ MobileDepthRow,
3484
+ {
3485
+ side: "ask",
3486
+ price: l2.price,
3487
+ amount: l2.amount,
3488
+ depthPct: (l2.depth ?? l2.amount) / maxAskDepth * 100,
3489
+ precision,
3490
+ amountPrecision
3491
+ },
3492
+ `mobile-ask-${idx}-${l2.price}-${l2.amount}`
3493
+ )) }),
3494
+ /* @__PURE__ */ jsxRuntime.jsxs(
3495
+ "div",
3496
+ {
3497
+ className: "grid",
3498
+ style: {
3499
+ gridTemplateColumns: "1.2fr 0.8fr",
3500
+ padding: "0.3rem 0",
3501
+ fontSize: "0.8rem",
3502
+ backgroundColor: "rgba(0, 123, 255, 0.05)",
3503
+ borderTop: "1px solid rgba(255,255,255,0.1)",
3504
+ borderBottom: "1px solid rgba(255,255,255,0.1)"
3505
+ },
3506
+ children: [
3507
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontWeight: "bold", display: "flex", alignItems: "center", gap: "8px" }, className: midClass, children: [
3508
+ "$",
3509
+ formatNumber(midPrice, precision),
3510
+ midChangePercent != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.8rem" }, className: midClass, children: [
3511
+ midChangePercent >= 0 ? "+" : "",
3512
+ midChangePercent.toFixed(2),
3513
+ "%"
3514
+ ] })
3515
+ ] }),
3516
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
3517
+ ]
3518
+ }
3519
+ ),
3520
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: visibleBids.map((l2, idx) => /* @__PURE__ */ jsxRuntime.jsx(
3521
+ MobileDepthRow,
3522
+ {
3523
+ side: "bid",
3524
+ price: l2.price,
3525
+ amount: l2.amount,
3526
+ depthPct: (l2.depth ?? l2.amount) / maxBidDepth * 100,
3527
+ precision,
3528
+ amountPrecision
3529
+ },
3530
+ `mobile-bid-${idx}-${l2.price}-${l2.amount}`
3531
+ )) })
3532
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden px-3 pb-2", children: [
3533
+ /* @__PURE__ */ jsxRuntime.jsxs(
3534
+ "div",
3535
+ {
3536
+ className: "grid text-white/60",
3537
+ style: { gridTemplateColumns: "1.2fr 0.8fr", padding: "0.3rem 0 0.2rem 0", fontSize: "0.75rem", fontWeight: 500 },
3538
+ children: [
3539
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: priceLabel }),
3540
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right", paddingRight: "0.5rem" }, children: amountLabel })
3541
+ ]
3542
+ }
3543
+ ),
3544
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, overflowY: "auto", minHeight: 0 }, children: tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-6 text-center text-[0.7rem] text-white/50", children: "No trades" }) : tradeFiltered.map((trade, i) => /* @__PURE__ */ jsxRuntime.jsxs(
3545
+ "div",
3546
+ {
3547
+ className: "grid",
3548
+ style: { gridTemplateColumns: "1.2fr 0.8fr", padding: "0.2rem 0", fontSize: "0.8rem" },
3549
+ children: [
3550
+ /* @__PURE__ */ jsxRuntime.jsxs(
3551
+ "div",
3552
+ {
3553
+ style: { color: trade.type === "buy" ? "#0ecb81" : "#f6465d", fontWeight: 500 },
3554
+ children: [
3555
+ "$",
3556
+ formatNumber(trade.price, precision)
3557
+ ]
3558
+ }
3559
+ ),
3560
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right", paddingRight: "0.5rem" }, children: formatNumber(trade.amount, amountPrecision) })
3561
+ ]
3562
+ },
3563
+ `${trade.type}-${trade.price}-${trade.amount}-${trade.time ?? i}`
3564
+ )) })
3565
+ ] })
3566
+ ] });
3567
+ }
3568
+ function MobileDepthRow({
3569
+ side,
3570
+ price,
3571
+ amount,
3572
+ depthPct,
3573
+ precision,
3574
+ amountPrecision
3575
+ }) {
3576
+ const isAsk = side === "ask";
3577
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3578
+ "div",
3579
+ {
3580
+ style: {
3581
+ display: "grid",
3582
+ gridTemplateColumns: "1.2fr 0.8fr",
3583
+ padding: "0.2rem 0",
3584
+ fontSize: "0.8rem",
3585
+ position: "relative"
3586
+ },
3587
+ children: [
3588
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", zIndex: 1, color: isAsk ? "#f6465d" : "#0ecb81" }, children: [
3589
+ "$",
3590
+ formatNumber(price, precision)
3591
+ ] }),
3592
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right", paddingRight: "0.5rem", position: "relative", zIndex: 1 }, children: formatNumber(amount, amountPrecision) }),
3593
+ /* @__PURE__ */ jsxRuntime.jsx(
3594
+ "div",
3595
+ {
3596
+ style: {
3597
+ position: "absolute",
3598
+ top: 0,
3599
+ right: 0,
3600
+ bottom: 0,
3601
+ width: `${clamp3(depthPct, 0, 100)}%`,
3602
+ backgroundColor: isAsk ? "#f6465d" : "#0ecb81",
3603
+ opacity: 0.1,
3604
+ zIndex: 0
3605
+ }
3606
+ }
3607
+ )
3608
+ ]
3609
+ }
3610
+ );
3611
+ }
2585
3612
  var PropertyTour = o__namespace.forwardRef(
2586
3613
  ({
2587
3614
  className,
@@ -2786,7 +3813,7 @@ var PropertyNewsUpdates = o__namespace.forwardRef(
2786
3813
  children: hasItems ? paginatedItems.map((item, index) => {
2787
3814
  const absoluteIndex = page * ITEMS_PER_PAGE + index;
2788
3815
  const key = item.displayId ?? item.id ?? `${item.title}-${absoluteIndex}`;
2789
- const styles = categoryStyles[item.type] ?? categoryStyles.market;
3816
+ const styles2 = categoryStyles[item.type] ?? categoryStyles.market;
2790
3817
  const dateLabel = item.isNew ?? (highlightFirst && absoluteIndex === 0) ? "Just now" : typeof item.date === "string" && item.date.trim().length > 0 ? item.date : formatDate(item.date);
2791
3818
  const isHighlighted = item.isNew ?? (highlightFirst && absoluteIndex === 0);
2792
3819
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2820,14 +3847,14 @@ var PropertyNewsUpdates = o__namespace.forwardRef(
2820
3847
  style: {
2821
3848
  padding: "0.25rem 0.6rem",
2822
3849
  borderRadius: "4px",
2823
- border: `1px solid ${styles.borderColor}`,
2824
- backgroundColor: styles.backgroundColor,
2825
- color: styles.color,
3850
+ border: `1px solid ${styles2.borderColor}`,
3851
+ backgroundColor: styles2.backgroundColor,
3852
+ color: styles2.color,
2826
3853
  fontSize: "0.68rem",
2827
3854
  fontWeight: 600,
2828
3855
  textTransform: "uppercase"
2829
3856
  },
2830
- children: item.type === "property" ? styles.label : "Market News"
3857
+ children: item.type === "property" ? styles2.label : "Market News"
2831
3858
  }
2832
3859
  )
2833
3860
  ]
@@ -2891,6 +3918,7 @@ var PropertyCompareBar = o__namespace.forwardRef(
2891
3918
  onSelectAddress,
2892
3919
  propertyValue,
2893
3920
  propertyValueVariant = "classic",
3921
+ price,
2894
3922
  ...props
2895
3923
  }, ref) => {
2896
3924
  const normalizedAddresses = o__namespace.useMemo(() => {
@@ -2957,7 +3985,36 @@ var PropertyCompareBar = o__namespace.forwardRef(
2957
3985
  const formattedPropertyChange = propertyValue?.change == null ? null : `${propertyValue.change >= 0 ? "+" : "-"}${propertyValueCurrency}${Math.abs(
2958
3986
  propertyValue.change
2959
3987
  ).toLocaleString(void 0, propertyValueFormat)}`;
2960
- propertyValue?.change == null ? void 0 : propertyValue.change >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
3988
+ const priceCurrency = price?.currencySymbol ?? "$";
3989
+ const priceFormat = price?.formatOptions ?? { minimumFractionDigits: 2, maximumFractionDigits: 2 };
3990
+ const pricePercentFormat = price?.percentFormatOptions ?? { minimumFractionDigits: 2, maximumFractionDigits: 2 };
3991
+ const formattedPriceValue = price == null ? null : `${priceCurrency}${price.value.toLocaleString(void 0, priceFormat)}`;
3992
+ const formattedPriceChange = price?.change == null ? null : `${price.change >= 0 ? "+" : "-"}${priceCurrency}${Math.abs(price.change).toLocaleString(
3993
+ void 0,
3994
+ priceFormat
3995
+ )}`;
3996
+ const formattedPricePercent = price?.changePercent == null ? null : `${price.changePercent >= 0 ? "+" : "-"}${Math.abs(price.changePercent).toLocaleString(
3997
+ void 0,
3998
+ pricePercentFormat
3999
+ )}%`;
4000
+ const priceContent = formattedPriceValue && propertyValueVariant === "pill" ? /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock, { $variant: propertyValueVariant, children: [
4001
+ /* @__PURE__ */ jsxRuntime.jsx(PriceAmount, { children: formattedPriceValue }),
4002
+ formattedPriceChange || formattedPricePercent ? /* @__PURE__ */ jsxRuntime.jsxs(
4003
+ PriceChange,
4004
+ {
4005
+ $isPositive: price?.change != null ? price.change >= 0 : price?.changePercent != null ? price.changePercent >= 0 : void 0,
4006
+ children: [
4007
+ formattedPriceChange ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedPriceChange }) : null,
4008
+ formattedPricePercent ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedPricePercent }) : null
4009
+ ]
4010
+ }
4011
+ ) : null
4012
+ ] }) : null;
4013
+ const propertyValueContent = formattedPropertyValue ? /* @__PURE__ */ jsxRuntime.jsxs(PropertyValueBlock, { $variant: propertyValueVariant, children: [
4014
+ /* @__PURE__ */ jsxRuntime.jsx(PropertyValueLabel, { children: propertyValueLabel }),
4015
+ /* @__PURE__ */ jsxRuntime.jsx(PropertyValueAmount, { children: formattedPropertyValue }),
4016
+ formattedPropertyChange ? /* @__PURE__ */ jsxRuntime.jsx(PropertyValueChange, { $isPositive: propertyValue?.change != null ? propertyValue.change >= 0 : void 0, children: formattedPropertyChange }) : null
4017
+ ] }) : null;
2961
4018
  return /* @__PURE__ */ jsxRuntime.jsxs(PropertySelectorContainer, { ref, className, $variant: propertyValueVariant, ...props, children: [
2962
4019
  /* @__PURE__ */ jsxRuntime.jsxs(PropertySelector, { ref: dropdownRef, onClick: () => hasAddresses && setIsDropdownOpen((prev2) => !prev2), children: [
2963
4020
  /* @__PURE__ */ jsxRuntime.jsxs(PropertyAddress, { children: [
@@ -2988,11 +4045,10 @@ var PropertyCompareBar = o__namespace.forwardRef(
2988
4045
  option.id
2989
4046
  )) })
2990
4047
  ] }),
2991
- formattedPropertyValue ? /* @__PURE__ */ jsxRuntime.jsxs(PropertyValueBlock, { $variant: propertyValueVariant, children: [
2992
- /* @__PURE__ */ jsxRuntime.jsx(PropertyValueLabel, { children: propertyValueLabel }),
2993
- /* @__PURE__ */ jsxRuntime.jsx(PropertyValueAmount, { children: formattedPropertyValue }),
2994
- formattedPropertyChange ? /* @__PURE__ */ jsxRuntime.jsx(PropertyValueChange, { $isPositive: propertyValue?.change != null ? propertyValue.change >= 0 : void 0, children: formattedPropertyChange }) : null
2995
- ] }) : null
4048
+ propertyValueVariant === "pill" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4049
+ priceContent,
4050
+ propertyValueContent
4051
+ ] }) : propertyValueContent
2996
4052
  ] });
2997
4053
  }
2998
4054
  );
@@ -3019,14 +4075,36 @@ var PropertySelectorContainer = at.div`
3019
4075
  border-radius: 0;
3020
4076
  margin-top: 0;
3021
4077
  padding-top: 0.5rem;
3022
- flex-direction: column;
3023
- align-items: flex-start;
3024
- gap: 0.75rem;
3025
4078
  }
3026
4079
 
3027
4080
  @media (max-width: 600px) {
3028
- flex-direction: column;
3029
- gap: 0.5rem;
4081
+ width: 100%;
4082
+
4083
+ ${({ $variant }) => $variant === "pill" ? rt`
4084
+ display: grid;
4085
+ grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr) minmax(0, 1fr);
4086
+ gap: 0.35rem;
4087
+ align-items: center;
4088
+
4089
+ > *:nth-child(1) {
4090
+ width: 100%;
4091
+ }
4092
+
4093
+ > *:nth-child(2) {
4094
+ justify-self: center;
4095
+ width: 100%;
4096
+ }
4097
+
4098
+ > *:nth-child(3) {
4099
+ justify-self: end;
4100
+ text-align: right;
4101
+ }
4102
+ ` : rt`
4103
+ flex-direction: row;
4104
+ align-items: center;
4105
+ justify-content: space-between;
4106
+ gap: 0.5rem;
4107
+ `};
3030
4108
  }
3031
4109
  `;
3032
4110
  var PropertySelector = at.div`
@@ -3044,7 +4122,7 @@ var PropertySelector = at.div`
3044
4122
  }
3045
4123
  `;
3046
4124
  var PropertyAddress = at.div`
3047
- font-size: 1.25rem;
4125
+ font-size: 1.125rem;
3048
4126
  font-weight: 600;
3049
4127
  display: flex;
3050
4128
  align-items: center;
@@ -3054,6 +4132,15 @@ var PropertyAddress = at.div`
3054
4132
  svg {
3055
4133
  transition: transform 0.2s;
3056
4134
  }
4135
+
4136
+ @media (max-width: 600px) {
4137
+ flex-direction: column;
4138
+ align-items: flex-start;
4139
+ gap: 0.2rem;
4140
+ font-size: 1rem;
4141
+ line-height: 1.2;
4142
+ white-space: normal;
4143
+ }
3057
4144
  `;
3058
4145
  var PropertySelectorDropdown = at.div`
3059
4146
  position: absolute;
@@ -3104,6 +4191,19 @@ var PropertyValueBlock = at.div`
3104
4191
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
3105
4192
  gap: 0.85rem;
3106
4193
  justify-content: flex-end;
4194
+
4195
+ @media (max-width: 600px) {
4196
+ margin: 0;
4197
+ width: auto;
4198
+ min-width: 0;
4199
+ flex-direction: column;
4200
+ align-items: flex-end;
4201
+ gap: 0.125rem;
4202
+ padding: 0;
4203
+ background: transparent;
4204
+ border-radius: 0;
4205
+ box-shadow: none;
4206
+ }
3107
4207
  `}
3108
4208
 
3109
4209
  ${({ $variant }) => $variant === "pill" && rt`
@@ -3115,17 +4215,29 @@ var PropertyValueBlock = at.div`
3115
4215
  padding: 0.5rem 1rem;
3116
4216
  gap: 1rem;
3117
4217
  align-items: center;
3118
- `}
3119
4218
 
3120
- @media (max-width: 768px) {
3121
- margin-left: 0;
3122
- }
4219
+ @media (max-width: 600px) {
4220
+ margin: 0;
4221
+ width: 100%;
4222
+ min-width: 0;
4223
+ flex-direction: column;
4224
+ align-items: flex-end;
4225
+ text-align: right;
4226
+ gap: 0.2rem;
4227
+ padding: 0;
4228
+ background: transparent;
4229
+ border-radius: 0;
4230
+ border: none;
4231
+ white-space: normal;
4232
+ }
4233
+ `}
3123
4234
 
3124
4235
  @media (max-width: 600px) {
3125
4236
  margin: 0;
3126
4237
  flex-direction: column;
3127
- align-items: flex-start;
3128
- gap: 0.125rem;
4238
+ align-items: flex-end;
4239
+ gap: 0.2rem;
4240
+ white-space: normal;
3129
4241
  }
3130
4242
  `;
3131
4243
  var PropertyValueLabel = at.span`
@@ -3133,18 +4245,59 @@ var PropertyValueLabel = at.span`
3133
4245
  color: var(--color-text-secondary, rgba(255, 255, 255, 0.6));
3134
4246
  text-transform: uppercase;
3135
4247
  letter-spacing: 0.5px;
4248
+
4249
+ @media (max-width: 600px) {
4250
+ font-size: 0.6rem;
4251
+ letter-spacing: 0.4px;
4252
+ }
3136
4253
  `;
3137
4254
  var PropertyValueAmount = at.span`
3138
4255
  font-size: 1.1rem;
3139
4256
  font-weight: 600;
3140
4257
  color: #fff;
4258
+
4259
+ @media (max-width: 600px) {
4260
+ font-size: 0.95rem;
4261
+ }
3141
4262
  `;
3142
4263
  var PropertyValueChange = at.span`
3143
4264
  font-size: 0.75rem;
3144
4265
  font-weight: 500;
3145
4266
  color: ${(props) => props.$isPositive == null ? "var(--color-text-secondary, rgba(255, 255, 255, 0.6))" : props.$isPositive ? "var(--color-positive, #0ecb81)" : "var(--color-negative, #f6465d)"};
4267
+
4268
+ @media (max-width: 600px) {
4269
+ font-size: 0.65rem;
4270
+ }
4271
+ `;
4272
+ var PriceBlock = at.div`
4273
+ display: none;
4274
+
4275
+ ${({ $variant }) => $variant === "pill" && rt`
4276
+ @media (max-width: 600px) {
4277
+ display: flex;
4278
+ flex: none;
4279
+ flex-direction: column;
4280
+ align-items: center;
4281
+ justify-content: center;
4282
+ gap: 0.15rem;
4283
+ width: 100%;
4284
+ }
4285
+ `}
4286
+ `;
4287
+ var PriceAmount = at.span`
4288
+ font-size: 1.6rem;
4289
+ font-weight: 600;
4290
+ color: #fff;
4291
+ letter-spacing: 0.2px;
4292
+ `;
4293
+ var PriceChange = at.span`
4294
+ font-size: 0.85rem;
4295
+ font-weight: 500;
4296
+ display: inline-flex;
4297
+ gap: 0.35rem;
4298
+ color: ${(props) => props.$isPositive == null ? "var(--color-text-secondary, rgba(255, 255, 255, 0.6))" : props.$isPositive ? "var(--color-positive, #0ecb81)" : "var(--color-negative, #f6465d)"};
3146
4299
  `;
3147
- var TABS = [
4300
+ var DEFAULT_TABS = [
3148
4301
  { id: "portfolio", label: "Portfolio" },
3149
4302
  { id: "openOrders", label: "Open Orders" },
3150
4303
  { id: "tradeHistory", label: "Trade History" },
@@ -3153,7 +4306,7 @@ var TABS = [
3153
4306
  var panelStyle = {
3154
4307
  width: "100%",
3155
4308
  borderRadius: "16px",
3156
- backgroundColor: "#111111",
4309
+ backgroundColor: "#0b0e10",
3157
4310
  border: "1px solid rgba(255,255,255,0.08)",
3158
4311
  color: "#ffffff",
3159
4312
  display: "flex",
@@ -3239,12 +4392,29 @@ var formatPercent = (value, fractionDigits = 2) => {
3239
4392
  return `${value.toFixed(fractionDigits)}%`;
3240
4393
  };
3241
4394
  var YourOrders = o__namespace.forwardRef(
3242
- ({ className, title = "Portfolio Holdings (Demo)", orders, renderOrderActions, ...props }, ref) => {
3243
- const [activeTab, setActiveTab] = o__namespace.useState("portfolio");
3244
- const hasOrders = Array.isArray(orders) && orders.length > 0;
3245
- const renderPortfolio = () => {
4395
+ ({ className, title, orders, tabs, activeTabId, onTabChange, renderOrderActions, ...props }, ref) => {
4396
+ const [internalActiveTab, setInternalActiveTab] = o__namespace.useState(tabs?.[0]?.id ?? "portfolio");
4397
+ const effectiveActiveTabId = activeTabId ?? internalActiveTab;
4398
+ const handleTabChange = (tabId) => {
4399
+ if (onTabChange) {
4400
+ onTabChange(tabId);
4401
+ } else {
4402
+ setInternalActiveTab(tabId);
4403
+ }
4404
+ };
4405
+ const resolvedTabs = tabs ?? DEFAULT_TABS.map((t) => ({ ...t, orders: orders ?? [], emptyState: `No ${t.label.toLowerCase()} data available.` }));
4406
+ const activeTab = resolvedTabs.find((t) => t.id === effectiveActiveTabId) ?? resolvedTabs[0];
4407
+ const activeOrders = activeTab?.orders ?? orders ?? [];
4408
+ const displayTitle = title ?? activeTab?.title ?? activeTab?.label ?? "Portfolio Holdings";
4409
+ console.log("[YourOrders] tabs:", tabs?.map((t) => ({ id: t.id, ordersCount: t.orders?.length })));
4410
+ console.log("[YourOrders] activeTabId prop:", activeTabId);
4411
+ console.log("[YourOrders] effectiveActiveTabId:", effectiveActiveTabId);
4412
+ console.log("[YourOrders] activeTab:", activeTab?.id, "orders count:", activeOrders?.length);
4413
+ const hasOrders = Array.isArray(activeOrders) && activeOrders.length > 0;
4414
+ const emptyMessage = activeTab?.emptyState ?? "No holdings yet. Start trading to build your portfolio.";
4415
+ const renderOrders = () => {
3246
4416
  if (!hasOrders) {
3247
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: emptyStateStyle, children: "No holdings yet. Start trading to build your portfolio." });
4417
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: emptyStateStyle, children: emptyMessage });
3248
4418
  }
3249
4419
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3250
4420
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tableHeaderStyle, children: [
@@ -3255,7 +4425,7 @@ var YourOrders = o__namespace.forwardRef(
3255
4425
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: tableHeaderCell, children: "Avg Price" }),
3256
4426
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: tableHeaderCell, children: "P&L" })
3257
4427
  ] }),
3258
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.65rem" }, children: orders.map((order) => {
4428
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.65rem" }, children: activeOrders.map((order) => {
3259
4429
  const propertyName = order.asset;
3260
4430
  const holding = order.holdingLabel ?? `${order.amount.toLocaleString(void 0, {
3261
4431
  minimumFractionDigits: 0,
@@ -3348,60 +4518,52 @@ var YourOrders = o__namespace.forwardRef(
3348
4518
  }) })
3349
4519
  ] });
3350
4520
  };
3351
- const renderOtherTab = (label) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: emptyStateStyle, children: `No ${label.toLowerCase()} data available.` });
3352
- let tabContent = null;
3353
- switch (activeTab) {
3354
- case "portfolio":
3355
- tabContent = renderPortfolio();
3356
- break;
3357
- case "openOrders":
3358
- tabContent = renderOtherTab("Open Orders");
3359
- break;
3360
- case "tradeHistory":
3361
- tabContent = renderOtherTab("Trade History");
3362
- break;
3363
- case "orderHistory":
3364
- tabContent = renderOtherTab("Order History");
3365
- break;
3366
- default:
3367
- tabContent = null;
3368
- }
3369
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: panelStyle, className, ...props, children: [
3370
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle, children: /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: title }) }),
3371
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tabsRowStyle, children: TABS.map((tab) => {
3372
- const isActive = activeTab === tab.id;
3373
- return /* @__PURE__ */ jsxRuntime.jsxs(
3374
- "button",
3375
- {
3376
- type: "button",
3377
- onClick: () => setActiveTab(tab.id),
3378
- style: {
3379
- ...tabButtonBase,
3380
- color: isActive ? "#ffffff" : "rgba(255,255,255,0.55)",
3381
- fontWeight: isActive ? 600 : 400
3382
- },
3383
- children: [
3384
- tab.label,
3385
- isActive ? /* @__PURE__ */ jsxRuntime.jsx(
3386
- "div",
3387
- {
3388
- style: {
3389
- position: "absolute",
3390
- bottom: "-1px",
3391
- left: 0,
3392
- right: 0,
3393
- height: "2px",
3394
- background: "#f0b90b"
3395
- }
3396
- }
3397
- ) : null
3398
- ]
3399
- },
3400
- tab.id
3401
- );
3402
- }) }),
3403
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tabContentWrapper, children: tabContent })
3404
- ] });
4521
+ const tabContent = renderOrders();
4522
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4523
+ "div",
4524
+ {
4525
+ ref,
4526
+ style: { ...panelStyle, ...props.style ?? {} },
4527
+ className,
4528
+ ...props,
4529
+ children: [
4530
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle, children: /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: displayTitle }) }),
4531
+ resolvedTabs.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: tabsRowStyle, children: resolvedTabs.map((tab) => {
4532
+ const isActive = effectiveActiveTabId === tab.id;
4533
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4534
+ "button",
4535
+ {
4536
+ type: "button",
4537
+ onClick: () => handleTabChange(tab.id),
4538
+ style: {
4539
+ ...tabButtonBase,
4540
+ color: isActive ? "#ffffff" : "rgba(255,255,255,0.55)",
4541
+ fontWeight: isActive ? 600 : 400
4542
+ },
4543
+ children: [
4544
+ tab.label,
4545
+ isActive ? /* @__PURE__ */ jsxRuntime.jsx(
4546
+ "div",
4547
+ {
4548
+ style: {
4549
+ position: "absolute",
4550
+ bottom: "-1px",
4551
+ left: 0,
4552
+ right: 0,
4553
+ height: "2px",
4554
+ background: "#f0b90b"
4555
+ }
4556
+ }
4557
+ ) : null
4558
+ ]
4559
+ },
4560
+ tab.id
4561
+ );
4562
+ }) }),
4563
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tabContentWrapper, children: tabContent })
4564
+ ]
4565
+ }
4566
+ );
3405
4567
  }
3406
4568
  );
3407
4569
  YourOrders.displayName = "YourOrders";
@@ -3412,6 +4574,17 @@ var formatPrice = (value, currencySymbol) => {
3412
4574
  maximumFractionDigits: 2
3413
4575
  })}`;
3414
4576
  };
4577
+ function createCandlestickSeries(chart, options) {
4578
+ const chartWithSeries = chart;
4579
+ if (typeof chartWithSeries.addCandlestickSeries === "function") {
4580
+ return chartWithSeries.addCandlestickSeries(options);
4581
+ }
4582
+ const candlestickCtor = LightweightCharts__namespace.CandlestickSeries;
4583
+ if (typeof chartWithSeries.addSeries === "function" && candlestickCtor) {
4584
+ return chartWithSeries.addSeries(candlestickCtor, options);
4585
+ }
4586
+ throw new Error("Candlestick series API is not available in the current lightweight-charts version.");
4587
+ }
3415
4588
  var PriceChart = o__namespace.forwardRef(
3416
4589
  ({
3417
4590
  className,
@@ -3443,10 +4616,16 @@ var PriceChart = o__namespace.forwardRef(
3443
4616
  if (first == null || last == null || first === 0) return void 0;
3444
4617
  return (last - first) / first * 100;
3445
4618
  }, [changePercent, data]);
4619
+ const dollarChange = o__namespace.useMemo(() => {
4620
+ const first = data[0]?.open;
4621
+ const last = data.at(-1)?.close;
4622
+ if (first == null || last == null) return void 0;
4623
+ return last - first;
4624
+ }, [data]);
3446
4625
  o__namespace.useEffect(() => {
3447
4626
  const el = containerRef.current;
3448
4627
  if (!el) return;
3449
- const chart = lightweightCharts.createChart(el, {
4628
+ const chart = LightweightCharts__namespace.createChart(el, {
3450
4629
  autoSize: true,
3451
4630
  layout: {
3452
4631
  background: { color: "transparent" },
@@ -3471,7 +4650,7 @@ var PriceChart = o__namespace.forwardRef(
3471
4650
  horzLine: { color: "rgba(255,255,255,0.12)" }
3472
4651
  }
3473
4652
  });
3474
- const series = chart.addCandlestickSeries({
4653
+ const series = createCandlestickSeries(chart, {
3475
4654
  upColor: "#0ecb81",
3476
4655
  downColor: "#f6465d",
3477
4656
  borderVisible: false,
@@ -3530,15 +4709,15 @@ var PriceChart = o__namespace.forwardRef(
3530
4709
  {
3531
4710
  ref,
3532
4711
  className: cn(
3533
- "w-full min-h-[450px] rounded-lg border border-white/10 bg-black/30 text-white backdrop-blur-md",
4712
+ "w-full min-h-[360px] rounded-lg border border-white/10 bg-black/30 text-white backdrop-blur-md sm:min-h-[450px]",
3534
4713
  className
3535
4714
  ),
3536
4715
  ...props,
3537
4716
  children: [
3538
- /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4 px-6 pb-2 pt-6", children: [
3539
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4717
+ /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "flex flex-col gap-4 px-4 pb-2 pt-5 md:flex-row md:items-start md:justify-between md:px-6 md:pt-6", children: [
4718
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-3 md:w-auto", children: [
3540
4719
  /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "m-0 text-[1.1rem] font-semibold text-white", children: title }),
3541
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex items-center gap-2", children: ranges.map((r2) => {
4720
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: ranges.map((r2) => {
3542
4721
  const active = r2 === selectedRange;
3543
4722
  const hovered = hoveredRange === r2;
3544
4723
  const style = {
@@ -3563,16 +4742,43 @@ var PriceChart = o__namespace.forwardRef(
3563
4742
  );
3564
4743
  }) })
3565
4744
  ] }),
3566
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
3567
- resolvedPrice == null ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-xl font-semibold tabular-nums", changeClass), children: formatPrice(resolvedPrice, currencySymbol) }),
3568
- inferredChangePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("rounded-md px-2 py-1 text-xs font-semibold tabular-nums", badgeClass), children: [
3569
- sign,
3570
- inferredChangePercent?.toFixed(2),
3571
- "%"
3572
- ] })
4745
+ resolvedPrice == null && inferredChangePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
4746
+ resolvedPrice == null ? null : /* @__PURE__ */ jsxRuntime.jsx(
4747
+ "div",
4748
+ {
4749
+ className: cn("text-xl font-semibold tabular-nums", changeClass),
4750
+ style: { marginRight: "1rem" },
4751
+ children: formatPrice(resolvedPrice, currencySymbol)
4752
+ }
4753
+ ),
4754
+ dollarChange != null ? /* @__PURE__ */ jsxRuntime.jsxs(
4755
+ "span",
4756
+ {
4757
+ className: cn("text-base font-medium tabular-nums", changeClass),
4758
+ style: { marginRight: "0.5rem" },
4759
+ children: [
4760
+ dollarChange >= 0 ? "+" : "",
4761
+ dollarChange.toFixed(2)
4762
+ ]
4763
+ }
4764
+ ) : null,
4765
+ inferredChangePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(
4766
+ "div",
4767
+ {
4768
+ className: cn(
4769
+ "rounded-md px-2 py-1 text-xs font-semibold tabular-nums",
4770
+ badgeClass
4771
+ ),
4772
+ children: [
4773
+ sign,
4774
+ inferredChangePercent?.toFixed(2),
4775
+ "%"
4776
+ ]
4777
+ }
4778
+ )
3573
4779
  ] })
3574
4780
  ] }),
3575
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 pb-6 pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
4781
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 pb-5 pt-2 md:px-6 md:pb-6", children: /* @__PURE__ */ jsxRuntime.jsx(
3576
4782
  "div",
3577
4783
  {
3578
4784
  ref: containerRef,
@@ -3615,195 +4821,369 @@ var PropertyHeroHeader = o__namespace.forwardRef(
3615
4821
  const tradeHoverColor = "#f5dd9a";
3616
4822
  const [isTradeInteracting, setIsTradeInteracting] = o__namespace.useState(false);
3617
4823
  const [isOfferInteracting, setIsOfferInteracting] = o__namespace.useState(false);
4824
+ const hasAmenities = beds != null || baths != null || cars != null || propertyTypeLabel != null;
3618
4825
  const headingStyle = {
3619
- fontSize: "2.5rem",
4826
+ fontSize: "clamp(1.6rem, 4vw, 2.5rem)",
3620
4827
  marginBottom: "0.5rem",
3621
4828
  color: "#ffffff",
3622
4829
  textShadow: "0 2px 4px rgba(0, 0, 0, 0.3)",
3623
4830
  fontWeight: 600,
3624
4831
  lineHeight: 1.2
3625
4832
  };
3626
- const priceBlockStyle = {
3627
- fontSize: "1.25rem",
3628
- fontWeight: 600,
3629
- color: "var(--color-accent, #f0b90b)",
3630
- marginLeft: "1rem",
3631
- paddingLeft: "1rem",
3632
- borderLeft: "1px solid rgba(255, 255, 255, 0.3)",
3633
- display: "flex",
3634
- alignItems: "center"
3635
- };
3636
- const locationStyle = {
3637
- fontSize: "1.25rem",
3638
- color: "rgba(255, 255, 255, 0.9)",
3639
- marginBottom: "0.75rem",
3640
- display: "flex",
3641
- alignItems: "center"
3642
- };
3643
- return /* @__PURE__ */ jsxRuntime.jsxs(
3644
- "div",
3645
- {
3646
- ref,
3647
- className: cn(
3648
- "relative w-[1200px] h-[500px] overflow-hidden bg-black rounded-[12px]",
3649
- className
4833
+ return /* @__PURE__ */ jsxRuntime.jsxs(OuterWrapper, { ref, className: cn(className), ...props, children: [
4834
+ /* @__PURE__ */ jsxRuntime.jsxs(HeroContainer, { children: [
4835
+ /* @__PURE__ */ jsxRuntime.jsx(
4836
+ HeroImage,
4837
+ {
4838
+ src: imageUrl,
4839
+ alt: imageAlt ?? name
4840
+ }
3650
4841
  ),
3651
- ...props,
3652
- children: [
3653
- /* @__PURE__ */ jsxRuntime.jsx(
3654
- "img",
3655
- {
3656
- src: imageUrl,
3657
- alt: imageAlt ?? name,
3658
- className: "absolute inset-0 block h-full w-full object-cover object-center",
3659
- style: { transform: "scale(1.20)", transformOrigin: "center" }
3660
- }
3661
- ),
3662
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 z-10 flex w-full items-end justify-between gap-4 p-8 max-[768px]:flex-col max-[768px]:items-start max-[768px]:gap-4 max-[768px]:p-6 max-[480px]:p-4", children: [
3663
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-block w-full rounded-lg bg-black/15 px-4 py-3 text-white shadow-[0px_1px_1px_rgba(0,0,0,0.3)] backdrop-blur-[3px] max-[768px]:w-full max-[768px]:px-3 max-[768px]:py-3 max-[480px]:px-3 max-[480px]:py-2 min-[769px]:flex-1 min-[769px]:min-w-0", children: [
3664
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-2", children: [
3665
- /* @__PURE__ */ jsxRuntime.jsx("h1", { style: headingStyle, className: "break-words", children: name }),
3666
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 flex flex-wrap items-center max-[768px]:mb-[0.6rem] max-[768px]:text-[1.1rem] max-[480px]:mb-[0.5rem] max-[480px]:text-[1rem]", children: [
3667
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: locationStyle, children: location }),
3668
- price == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("span", { style: priceBlockStyle, children: [
3669
- formatPrice2(price, currencySymbol),
3670
- changePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(
3671
- "span",
3672
- {
3673
- className: cn(
3674
- "ml-2 flex items-center text-[0.875rem] font-medium",
3675
- isPositive ? "text-[#0ecb81]" : "text-[#f6465d]"
4842
+ /* @__PURE__ */ jsxRuntime.jsx(HeroGradient, { "aria-hidden": "true" }),
4843
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 z-10 flex w-full flex-wrap items-end justify-between gap-4 p-8 max-[768px]:gap-4 max-[640px]:gap-3 max-[768px]:p-6 max-[480px]:p-4", children: [
4844
+ /* @__PURE__ */ jsxRuntime.jsxs(InfoCard, { children: [
4845
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-2", children: [
4846
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { style: headingStyle, className: "break-words", children: name }),
4847
+ /* @__PURE__ */ jsxRuntime.jsxs(InfoRow, { className: "mb-3 max-[768px]:mb-[0.6rem] max-[480px]:mb-[0.5rem]", children: [
4848
+ /* @__PURE__ */ jsxRuntime.jsx(LocationText, { children: location }),
4849
+ price == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock2, { children: [
4850
+ formatPrice2(price, currencySymbol),
4851
+ changePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(
4852
+ "span",
4853
+ {
4854
+ className: cn(
4855
+ "ml-2 flex items-center text-[0.875rem] font-medium",
4856
+ isPositive ? "text-[#0ecb81]" : "text-[#f6465d]"
4857
+ ),
4858
+ children: [
4859
+ /* @__PURE__ */ jsxRuntime.jsx(
4860
+ "svg",
4861
+ {
4862
+ xmlns: "http://www.w3.org/2000/svg",
4863
+ width: "12",
4864
+ height: "12",
4865
+ viewBox: "0 0 24 24",
4866
+ fill: "currentColor",
4867
+ className: "mr-[0.15rem]",
4868
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: isPositive ? "M7 14l5-5 5 5H7z" : "M7 10l5 5 5-5H7z" })
4869
+ }
3676
4870
  ),
3677
- children: [
3678
- /* @__PURE__ */ jsxRuntime.jsx(
3679
- "svg",
3680
- {
3681
- xmlns: "http://www.w3.org/2000/svg",
3682
- width: "12",
3683
- height: "12",
3684
- viewBox: "0 0 24 24",
3685
- fill: "currentColor",
3686
- className: "mr-[0.15rem]",
3687
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: isPositive ? "M7 14l5-5 5 5H7z" : "M7 10l5 5 5-5H7z" })
3688
- }
3689
- ),
3690
- Math.abs(changePercent).toFixed(2),
3691
- "%"
3692
- ]
3693
- }
3694
- )
3695
- ] })
4871
+ Math.abs(changePercent).toFixed(2),
4872
+ "%"
4873
+ ]
4874
+ }
4875
+ )
3696
4876
  ] })
3697
- ] }),
3698
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-6 text-[0.95rem] text-white/90 max-[768px]:hidden", children: [
3699
- beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
3700
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "mr-2 h-[18px] w-[18px]" }),
3701
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3702
- beds,
3703
- " Beds"
3704
- ] })
3705
- ] }),
3706
- baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
3707
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "mr-2 h-[18px] w-[18px]" }),
3708
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3709
- baths,
3710
- " Baths"
3711
- ] })
3712
- ] }),
3713
- cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
3714
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "mr-2 h-[18px] w-[18px]" }),
3715
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3716
- cars,
3717
- " Cars"
3718
- ] })
3719
- ] }),
3720
- propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { children: propertyTypeLabel })
3721
4877
  ] })
3722
4878
  ] }),
3723
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-3 max-[768px]:w-full max-[768px]:justify-between max-[768px]:gap-2 max-[480px]:gap-2", children: [
3724
- /* @__PURE__ */ jsxRuntime.jsx(
3725
- "button",
3726
- {
3727
- type: "button",
3728
- onClick: onTrade,
3729
- className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
3730
- style: {
3731
- backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
3732
- color: "black",
3733
- width: "88.06px",
3734
- height: "43px",
3735
- minWidth: "88.06px",
3736
- borderColor: isTradeInteracting ? accentColor : "transparent",
3737
- boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none"
3738
- },
3739
- onMouseEnter: () => setIsTradeInteracting(true),
3740
- onMouseLeave: () => setIsTradeInteracting(false),
3741
- onMouseDown: () => setIsTradeInteracting(true),
3742
- onMouseUp: () => setIsTradeInteracting(false),
3743
- onFocus: () => setIsTradeInteracting(true),
3744
- onBlur: () => setIsTradeInteracting(false),
3745
- onTouchStart: () => setIsTradeInteracting(true),
3746
- onTouchEnd: () => setIsTradeInteracting(false),
3747
- children: "Trade"
3748
- }
3749
- ),
3750
- /* @__PURE__ */ jsxRuntime.jsx(
3751
- "button",
3752
- {
3753
- type: "button",
3754
- onClick: onMakeOffer,
3755
- className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
3756
- style: {
3757
- backgroundColor: isOfferInteracting ? accentColor : "transparent",
3758
- borderColor: accentColor,
3759
- color: isOfferInteracting ? "black" : accentColor,
3760
- width: "127.14px",
3761
- height: "43px",
3762
- minWidth: "127.14px",
3763
- boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none"
3764
- },
3765
- onMouseEnter: () => setIsOfferInteracting(true),
3766
- onMouseLeave: () => setIsOfferInteracting(false),
3767
- onMouseDown: () => setIsOfferInteracting(true),
3768
- onMouseUp: () => setIsOfferInteracting(false),
3769
- onFocus: () => setIsOfferInteracting(true),
3770
- onBlur: () => setIsOfferInteracting(false),
3771
- onTouchStart: () => setIsOfferInteracting(true),
3772
- onTouchEnd: () => setIsOfferInteracting(false),
3773
- children: "Make Offer"
3774
- }
3775
- )
4879
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-6 text-[0.95rem] text-white/90 max-[768px]:hidden", children: [
4880
+ beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4881
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "mr-2 h-[18px] w-[18px]" }),
4882
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4883
+ beds,
4884
+ " Beds"
4885
+ ] })
4886
+ ] }),
4887
+ baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4888
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "mr-2 h-[18px] w-[18px]" }),
4889
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4890
+ baths,
4891
+ " Baths"
4892
+ ] })
4893
+ ] }),
4894
+ cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4895
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "mr-2 h-[18px] w-[18px]" }),
4896
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4897
+ cars,
4898
+ " Cars"
4899
+ ] })
4900
+ ] }),
4901
+ propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { children: propertyTypeLabel })
3776
4902
  ] })
4903
+ ] }),
4904
+ /* @__PURE__ */ jsxRuntime.jsxs(ActionButtons, { children: [
4905
+ /* @__PURE__ */ jsxRuntime.jsx(
4906
+ "button",
4907
+ {
4908
+ type: "button",
4909
+ onClick: onTrade,
4910
+ className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
4911
+ style: {
4912
+ backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
4913
+ color: "black",
4914
+ width: "88.06px",
4915
+ height: "43px",
4916
+ minWidth: "88.06px",
4917
+ borderColor: isTradeInteracting ? accentColor : "transparent",
4918
+ boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none"
4919
+ },
4920
+ onMouseEnter: () => setIsTradeInteracting(true),
4921
+ onMouseLeave: () => setIsTradeInteracting(false),
4922
+ onMouseDown: () => setIsTradeInteracting(true),
4923
+ onMouseUp: () => setIsTradeInteracting(false),
4924
+ onFocus: () => setIsTradeInteracting(true),
4925
+ onBlur: () => setIsTradeInteracting(false),
4926
+ onTouchStart: () => setIsTradeInteracting(true),
4927
+ onTouchEnd: () => setIsTradeInteracting(false),
4928
+ children: "Trade"
4929
+ }
4930
+ ),
4931
+ /* @__PURE__ */ jsxRuntime.jsx(
4932
+ "button",
4933
+ {
4934
+ type: "button",
4935
+ onClick: onMakeOffer,
4936
+ className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
4937
+ style: {
4938
+ backgroundColor: isOfferInteracting ? accentColor : "transparent",
4939
+ borderColor: accentColor,
4940
+ color: isOfferInteracting ? "black" : accentColor,
4941
+ width: "127.14px",
4942
+ height: "43px",
4943
+ minWidth: "127.14px",
4944
+ boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none"
4945
+ },
4946
+ onMouseEnter: () => setIsOfferInteracting(true),
4947
+ onMouseLeave: () => setIsOfferInteracting(false),
4948
+ onMouseDown: () => setIsOfferInteracting(true),
4949
+ onMouseUp: () => setIsOfferInteracting(false),
4950
+ onFocus: () => setIsOfferInteracting(true),
4951
+ onBlur: () => setIsOfferInteracting(false),
4952
+ onTouchStart: () => setIsOfferInteracting(true),
4953
+ onTouchEnd: () => setIsOfferInteracting(false),
4954
+ children: "Make Offer"
4955
+ }
4956
+ )
3777
4957
  ] })
3778
- ]
3779
- }
3780
- );
4958
+ ] })
4959
+ ] }),
4960
+ hasAmenities ? /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenities, { children: [
4961
+ beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4962
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "h-4 w-4" }),
4963
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4964
+ beds,
4965
+ " Beds"
4966
+ ] })
4967
+ ] }),
4968
+ baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4969
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "h-4 w-4" }),
4970
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4971
+ baths,
4972
+ " Baths"
4973
+ ] })
4974
+ ] }),
4975
+ cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4976
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "h-4 w-4" }),
4977
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4978
+ cars,
4979
+ " Cars"
4980
+ ] })
4981
+ ] }),
4982
+ propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx(MobileAmenity, { children: propertyTypeLabel })
4983
+ ] }) : null
4984
+ ] });
3781
4985
  }
3782
4986
  );
3783
4987
  PropertyHeroHeader.displayName = "PropertyHeroHeader";
4988
+ var OuterWrapper = at.div`
4989
+ width: 100%;
4990
+ max-width: 1200px;
4991
+ margin: 0 auto;
4992
+ display: flex;
4993
+ flex-direction: column;
4994
+ gap: 0.5rem;
4995
+ `;
4996
+ var HeroContainer = at.div`
4997
+ position: relative;
4998
+ width: 100%;
4999
+ height: 500px;
5000
+ border-radius: 12px;
5001
+ overflow: hidden;
5002
+ background-color: #000;
5003
+
5004
+ @media (max-width: 1024px) {
5005
+ height: 420px;
5006
+ }
5007
+
5008
+ @media (max-width: 768px) {
5009
+ height: 320px;
5010
+ }
5011
+
5012
+ @media (max-width: 640px) {
5013
+ height: 280px;
5014
+ }
5015
+
5016
+ @media (max-width: 540px) {
5017
+ height: 250px;
5018
+ }
5019
+
5020
+ @media (max-width: 420px) {
5021
+ height: 220px;
5022
+ }
5023
+
5024
+ @media (max-width: 360px) {
5025
+ height: 200px;
5026
+ }
5027
+ `;
5028
+ var MobileAmenities = at.div`
5029
+ display: none;
5030
+ align-items: center;
5031
+ justify-content: space-between;
5032
+ gap: 0.5rem;
5033
+ padding: 0.5rem 0.75rem;
5034
+ background: rgba(8, 8, 12, 0.85);
5035
+ border-radius: 12px;
5036
+ border: 1px solid rgba(255, 255, 255, 0.1);
5037
+ color: rgba(255, 255, 255, 0.85);
5038
+ font-size: 0.85rem;
5039
+
5040
+ @media (max-width: 768px) {
5041
+ display: flex;
5042
+ flex-wrap: wrap;
5043
+ }
5044
+ `;
5045
+ var MobileAmenity = at.span`
5046
+ display: inline-flex;
5047
+ align-items: center;
5048
+ gap: 0.35rem;
5049
+ padding: 0.35rem 0.5rem;
5050
+ border-radius: 999px;
5051
+ background: rgba(255, 255, 255, 0.08);
5052
+ font-weight: 500;
5053
+ `;
5054
+ var HeroImage = at.img`
5055
+ position: absolute;
5056
+ inset: 0;
5057
+ width: 100%;
5058
+ height: 100%;
5059
+ object-fit: cover;
5060
+ object-position: center;
5061
+ transform: scale(1.15);
5062
+ transform-origin: center;
5063
+ min-width: 110%;
5064
+ transition: transform 0.5s ease-out;
5065
+ `;
5066
+ var HeroGradient = at.div`
5067
+ position: absolute;
5068
+ inset: 0;
5069
+ z-index: 1;
5070
+ background: linear-gradient(180deg, rgba(0, 0, 0, 0.05) 0%, rgba(0, 0, 0, 0.25) 45%, rgba(0, 0, 0, 0.75) 100%);
5071
+ `;
5072
+ var ActionButtons = at.div`
5073
+ display: flex;
5074
+ flex-wrap: wrap;
5075
+ align-items: center;
5076
+ gap: 0.75rem;
5077
+ justify-content: flex-start;
5078
+
5079
+ @media (max-width: 768px) {
5080
+ gap: 0.5rem;
5081
+ }
5082
+
5083
+ @media (max-width: 640px) {
5084
+ display: none;
5085
+ }
5086
+ `;
5087
+ var InfoCard = at.div`
5088
+ display: inline-block;
5089
+ width: fit-content;
5090
+ max-width: 70%;
5091
+ border-radius: 12px;
5092
+ background: rgba(0, 0, 0, 0.12);
5093
+ padding: 0.75rem 1rem;
5094
+ color: #fff;
5095
+ backdrop-filter: blur(6px);
5096
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
5097
+ border: 1px solid rgba(255, 255, 255, 0.12);
5098
+ min-width: 0;
5099
+
5100
+ @media (max-width: 768px) {
5101
+ max-width: 85%;
5102
+ }
5103
+
5104
+ @media (max-width: 640px) {
5105
+ max-width: 92%;
5106
+ }
5107
+
5108
+ @media (max-width: 480px) {
5109
+ max-width: 95%;
5110
+ }
5111
+ `;
5112
+ var InfoRow = at.div`
5113
+ display: grid;
5114
+ grid-template-columns: minmax(0, 1fr) auto;
5115
+ align-items: center;
5116
+ gap: 0.75rem;
5117
+ width: 100%;
5118
+
5119
+ @media (max-width: 640px) {
5120
+ gap: 0.5rem;
5121
+ }
5122
+ `;
5123
+ var LocationText = at.span`
5124
+ font-size: clamp(1rem, 2.6vw, 1.25rem);
5125
+ color: rgba(255, 255, 255, 0.9);
5126
+ font-weight: 500;
5127
+ overflow: hidden;
5128
+ text-overflow: ellipsis;
5129
+ white-space: nowrap;
5130
+ `;
5131
+ var PriceBlock2 = at.span`
5132
+ display: flex;
5133
+ align-items: center;
5134
+ font-size: clamp(1rem, 2.2vw, 1.25rem);
5135
+ font-weight: 600;
5136
+ color: var(--color-accent, #f0b90b);
5137
+ padding-left: 1rem;
5138
+ border-left: 1px solid rgba(255, 255, 255, 0.25);
5139
+ min-height: 1.5rem;
5140
+ `;
3784
5141
  var PropertySubheader = o__namespace.forwardRef(
3785
5142
  ({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
5143
+ const tabsContainerRef = o__namespace.useRef(null);
5144
+ o__namespace.useEffect(() => {
5145
+ const container = tabsContainerRef.current;
5146
+ if (!container) return;
5147
+ const isMobile = window.innerWidth <= 768;
5148
+ if (!isMobile) return;
5149
+ const forceScrollbar = () => {
5150
+ if (container.scrollWidth > container.clientWidth) {
5151
+ container.scrollTop = 1;
5152
+ container.scrollTop = 0;
5153
+ container.scrollLeft = 1;
5154
+ container.scrollLeft = 0;
5155
+ }
5156
+ };
5157
+ setTimeout(forceScrollbar, 100);
5158
+ window.addEventListener("resize", forceScrollbar);
5159
+ return () => window.removeEventListener("resize", forceScrollbar);
5160
+ }, [tabs]);
3786
5161
  return /* @__PURE__ */ jsxRuntime.jsxs(
3787
5162
  "div",
3788
5163
  {
3789
5164
  ref,
3790
- className: cn("w-full font-normal flex flex-col gap-3 md:flex-row md:items-center md:justify-between", className),
5165
+ className: cn(
5166
+ "w-full font-normal",
5167
+ "flex flex-col-reverse gap-3",
5168
+ "md:flex-row md:items-center md:justify-between",
5169
+ className
5170
+ ),
3791
5171
  ...props,
3792
5172
  children: [
3793
5173
  /* @__PURE__ */ jsxRuntime.jsx(
3794
5174
  "div",
3795
5175
  {
5176
+ ref: tabsContainerRef,
3796
5177
  className: cn(
3797
5178
  "flex items-center border-b border-white/10",
3798
5179
  "overflow-x-auto md:overflow-visible",
3799
5180
  "[-webkit-overflow-scrolling:touch]",
3800
- "[scrollbar-width:none]",
3801
5181
  "[scroll-behavior:smooth]",
3802
5182
  "[touch-action:pan-x]",
3803
5183
  "md:border-b-0"
3804
5184
  ),
3805
5185
  style: { WebkitTapHighlightColor: "transparent" },
3806
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max gap-2 lg:gap-4", children: tabs.map((tab) => {
5186
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max", children: tabs.map((tab) => {
3807
5187
  const active = tab.id === activeTabId;
3808
5188
  return /* @__PURE__ */ jsxRuntime.jsxs(
3809
5189
  "button",
@@ -3812,13 +5192,12 @@ var PropertySubheader = o__namespace.forwardRef(
3812
5192
  onClick: () => onTabChange?.(tab.id),
3813
5193
  className: cn(
3814
5194
  "relative whitespace-nowrap",
3815
- "px-5 py-4 lg:px-6",
3816
- "text-[16px]",
3817
- "font-medium",
5195
+ "px-6 py-4",
5196
+ "font-normal",
3818
5197
  "transition-colors",
3819
5198
  "max-[768px]:px-[1.2rem] max-[768px]:py-[0.8rem]",
3820
- "max-[480px]:px-4 max-[480px]:py-[0.7rem]",
3821
- active ? "font-semibold text-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#f1d27a)]" : "text-white/65 hover:text-white"
5199
+ "max-[480px]:px-4 max-[480px]:py-[0.7rem] max-[480px]:text-[0.9rem]",
5200
+ active ? "font-semibold text-[var(--color-accent,#e6c87e)]" : "text-white/60 hover:text-white"
3822
5201
  ),
3823
5202
  style: {
3824
5203
  borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
@@ -3861,10 +5240,10 @@ var PropertySubheader = o__namespace.forwardRef(
3861
5240
  onClick: action.onClick,
3862
5241
  className: cn(
3863
5242
  "flex shrink-0 items-center gap-[5px] whitespace-nowrap",
3864
- "rounded-[6px]",
3865
- "border border-white/15",
5243
+ "rounded",
5244
+ "border border-white/10",
3866
5245
  "bg-transparent",
3867
- "px-3.5 py-1.5 text-[14px] font-medium",
5246
+ "px-3 py-1.5 text-[14px] font-normal",
3868
5247
  "transition-all",
3869
5248
  "max-[768px]:px-2.5 max-[768px]:py-[5px] max-[768px]:text-[13px]",
3870
5249
  "hover:bg-white/5 hover:border-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#e6c87e)]"
@@ -3884,6 +5263,65 @@ var PropertySubheader = o__namespace.forwardRef(
3884
5263
  }
3885
5264
  );
3886
5265
  PropertySubheader.displayName = "PropertySubheader";
5266
+ var MobileToggleContainer = at.div`
5267
+ display: none;
5268
+
5269
+ @media (max-width: 1024px) {
5270
+ display: flex;
5271
+ gap: 0.5rem;
5272
+ position: fixed;
5273
+ bottom: 0;
5274
+ left: 0;
5275
+ right: 0;
5276
+ background-color: var(--color-card-darker, #111);
5277
+ padding: 0.75rem 1rem;
5278
+ padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
5279
+ border-top: 1px solid var(--color-border);
5280
+ z-index: 100;
5281
+ box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.3);
5282
+ }
5283
+ `;
5284
+ var MobileToggleButton = at.button`
5285
+ flex: 1;
5286
+ padding: 0.75rem;
5287
+ background-color: ${(props) => props.active ? "var(--color-accent)" : "transparent"};
5288
+ color: ${(props) => props.active ? "#000" : "var(--color-text-secondary)"};
5289
+ border: ${(props) => props.active ? "1px solid var(--color-accent)" : "1px solid rgba(255, 255, 255, 0.2)"};
5290
+ border-radius: 6px;
5291
+ font-size: 0.9rem;
5292
+ font-weight: 600;
5293
+ cursor: pointer;
5294
+ transition: all 0.2s ease;
5295
+ white-space: nowrap;
5296
+
5297
+ &:hover {
5298
+ background-color: ${(props) => props.active ? "var(--color-accent-hover)" : "rgba(255, 255, 255, 0.05)"};
5299
+ border-color: ${(props) => props.active ? "var(--color-accent)" : "rgba(255, 255, 255, 0.3)"};
5300
+ }
5301
+
5302
+ @media (max-width: 480px) {
5303
+ font-size: 0.85rem;
5304
+ padding: 0.6rem 0.5rem;
5305
+ }
5306
+ `;
5307
+ var MobileTradeNav = o__namespace.forwardRef(
5308
+ ({ className, items, activeId, onChange, ...props }, ref) => {
5309
+ return /* @__PURE__ */ jsxRuntime.jsx(MobileToggleContainer, { ref, className: cn(className), ...props, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
5310
+ MobileToggleButton,
5311
+ {
5312
+ type: "button",
5313
+ active: item.id === activeId,
5314
+ onClick: () => onChange?.(item.id),
5315
+ children: [
5316
+ item.icon,
5317
+ item.label
5318
+ ]
5319
+ },
5320
+ item.id
5321
+ )) });
5322
+ }
5323
+ );
5324
+ MobileTradeNav.displayName = "MobileTradeNav";
3887
5325
 
3888
5326
  exports.Badge = Badge;
3889
5327
  exports.Button = Button;
@@ -3894,7 +5332,9 @@ exports.CardFooter = CardFooter;
3894
5332
  exports.CardHeader = CardHeader;
3895
5333
  exports.CardTitle = CardTitle;
3896
5334
  exports.HousePositionSlider = HousePositionSlider;
5335
+ exports.HousePositionSliderMobile = HousePositionSliderMobile;
3897
5336
  exports.LoafLiquidityBadge = LoafLiquidityBadge;
5337
+ exports.MobileTradeNav = MobileTradeNav;
3898
5338
  exports.Orderbook = Orderbook;
3899
5339
  exports.PortfolioSummary = PortfolioSummary;
3900
5340
  exports.PriceChart = PriceChart;