@dododog/ui 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/{chunk-OK3E73OK.js → chunk-2XH74PQR.js} +14 -0
  2. package/dist/chunk-36JNXXGH.js +360 -0
  3. package/dist/{chunk-KVVXKSMQ.mjs → chunk-7JYJ7ICL.mjs} +14 -0
  4. package/dist/{chunk-NWLJ7VQF.js → chunk-AIA3NHCK.js} +1 -2
  5. package/dist/{chunk-YSJAEDMG.js → chunk-E24VNM6S.js} +8 -5
  6. package/dist/{chunk-RQGC6RPI.mjs → chunk-FL3GD5FJ.mjs} +1 -2
  7. package/dist/{chunk-TNGW36OC.mjs → chunk-LRNSVRUN.mjs} +2 -0
  8. package/dist/{chunk-76DZXGKJ.mjs → chunk-N6THLJIG.mjs} +8 -5
  9. package/dist/chunk-PBDPZTHK.mjs +53 -0
  10. package/dist/chunk-S732LTPT.js +75 -0
  11. package/dist/{chunk-3BPC4LNH.js → chunk-T4AT3YCT.js} +2 -0
  12. package/dist/chunk-XH2MVC4W.mjs +337 -0
  13. package/dist/components/Counter/index.js +2 -2
  14. package/dist/components/Counter/index.mjs +1 -1
  15. package/dist/components/DateRangePicker/index.js +3 -3
  16. package/dist/components/DateRangePicker/index.mjs +1 -1
  17. package/dist/components/DetailList/index.d.mts +8 -2
  18. package/dist/components/DetailList/index.d.ts +8 -2
  19. package/dist/components/DetailList/index.js +2 -2
  20. package/dist/components/DetailList/index.mjs +1 -1
  21. package/dist/components/FloatingDock/index.d.mts +44 -0
  22. package/dist/components/FloatingDock/index.d.ts +44 -0
  23. package/dist/components/FloatingDock/index.js +11 -0
  24. package/dist/components/FloatingDock/index.mjs +2 -0
  25. package/dist/components/RoomTypeCard/index.d.mts +92 -0
  26. package/dist/components/RoomTypeCard/index.d.ts +92 -0
  27. package/dist/components/RoomTypeCard/index.js +16 -0
  28. package/dist/components/RoomTypeCard/index.mjs +3 -0
  29. package/dist/index.d.mts +124 -4
  30. package/dist/index.d.ts +124 -4
  31. package/dist/index.js +507 -72
  32. package/dist/index.mjs +421 -18
  33. package/dist/tailwind-preset.d.mts +11 -0
  34. package/dist/tailwind-preset.d.ts +11 -0
  35. package/dist/tailwind-preset.js +7 -7
  36. package/dist/tailwind-preset.mjs +1 -1
  37. package/dist/tokens/index.d.mts +11 -0
  38. package/dist/tokens/index.d.ts +11 -0
  39. package/dist/tokens/index.js +8 -8
  40. package/dist/tokens/index.mjs +1 -1
  41. package/package.json +11 -1
@@ -27,6 +27,20 @@ var colors = {
27
27
  secondary: "#6b7280",
28
28
  muted: "#9ca3af"
29
29
  },
30
+ // Navy profond — bandeaux/overlays sombres (galerie, header sombre)
31
+ ink: {
32
+ DEFAULT: "#1d2230",
33
+ soft: "#3b4559"
34
+ },
35
+ // Surfaces éditoriales — fond page / sections alternées
36
+ surface: {
37
+ 1: "#fdfcf9",
38
+ 2: "#f7f3ec"
39
+ },
40
+ // Sémantiques fiche V2
41
+ positive: "#047857",
42
+ danger: "#a8473b",
43
+ "rating-mid": "#f5b301",
30
44
  white: "#ffffff",
31
45
  black: "#000000"
32
46
  };
@@ -0,0 +1,360 @@
1
+ 'use strict';
2
+
3
+ var chunkNCU5PY34_js = require('./chunk-NCU5PY34.js');
4
+ var chunkADIDI7AJ_js = require('./chunk-ADIDI7AJ.js');
5
+ var React = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
27
+
28
+ function BedIcon({ className }) {
29
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: [
30
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 4v16" }),
31
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 8h18a2 2 0 0 1 2 2v10" }),
32
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 17h20" }),
33
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 8v9" })
34
+ ] });
35
+ }
36
+ function RulerIcon({ className }) {
37
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: [
38
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21.3 8.7 8.7 21.3a1 1 0 0 1-1.4 0l-4.6-4.6a1 1 0 0 1 0-1.4L15.3 2.7a1 1 0 0 1 1.4 0l4.6 4.6a1 1 0 0 1 0 1.4Z" }),
39
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m7.5 10.5 2 2" }),
40
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m10.5 7.5 2 2" }),
41
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m13.5 4.5 2 2" }),
42
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m4.5 13.5 2 2" })
43
+ ] });
44
+ }
45
+ function UsersIcon({ className }) {
46
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: [
47
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
48
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "7", r: "4" }),
49
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }),
50
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })
51
+ ] });
52
+ }
53
+ function CheckIcon({ className }) {
54
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) });
55
+ }
56
+ function NoRefundIcon({ className }) {
57
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: [
58
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "9" }),
59
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m5 5 14 14" })
60
+ ] });
61
+ }
62
+ function DogIcon({ className }) {
63
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: [
64
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 5.172C10 3.782 8.423 2.679 6.5 3c-2.823.47-4.113 6.006-4 7 .08.703 1.725 1.722 3.656 1 1.261-.472 1.96-1.45 2.344-2.5" }),
65
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14.267 5.172c0-1.39 1.577-2.493 3.5-2.172 2.823.47 4.113 6.006 4 7-.08.703-1.725 1.722-3.656 1-1.261-.472-1.855-1.45-2.239-2.5" }),
66
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 14v.5" }),
67
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 14v.5" }),
68
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.25 16.25h1.5L12 17l-.75-.75Z" }),
69
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.42 11.247A13.152 13.152 0 0 0 4 14.556C4 18.728 7.582 21 12 21s8-2.272 8-6.444c0-1.061-.162-2.2-.493-3.309m-9.243-6.082A8.801 8.801 0 0 1 12 5c.78 0 1.5.108 2.161.306" })
70
+ ] });
71
+ }
72
+ function ChevronDownIcon({ className }) {
73
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" }) });
74
+ }
75
+ function GalleryIcon({ className }) {
76
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: [
77
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
78
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "9", r: "2" }),
79
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
80
+ ] });
81
+ }
82
+ function formatPrice(price) {
83
+ return new Intl.NumberFormat("fr-FR", {
84
+ style: "currency",
85
+ currency: "EUR",
86
+ minimumFractionDigits: 0,
87
+ maximumFractionDigits: 0
88
+ }).format(price);
89
+ }
90
+ function CancellationChip({ cancellation }) {
91
+ if (cancellation.kind === "free") {
92
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 text-xs font-medium text-emerald-700", children: [
93
+ /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "w-3.5 h-3.5 flex-shrink-0" }),
94
+ cancellation.label
95
+ ] });
96
+ }
97
+ if (cancellation.kind === "partial") {
98
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 text-xs font-medium text-amber-700", children: [
99
+ /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "w-3.5 h-3.5 flex-shrink-0" }),
100
+ cancellation.label
101
+ ] });
102
+ }
103
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 text-xs text-text-muted", children: [
104
+ /* @__PURE__ */ jsxRuntime.jsx(NoRefundIcon, { className: "w-3.5 h-3.5 flex-shrink-0" }),
105
+ cancellation.label
106
+ ] });
107
+ }
108
+ function RateRow({
109
+ rate,
110
+ selected,
111
+ onSelect,
112
+ selectLabel,
113
+ withTopBorder
114
+ }) {
115
+ return /* @__PURE__ */ jsxRuntime.jsxs(
116
+ "div",
117
+ {
118
+ className: chunkADIDI7AJ_js.cn(
119
+ "flex items-end justify-between gap-3 py-3",
120
+ withTopBorder && "border-t border-dashed border-sand-dark"
121
+ ),
122
+ children: [
123
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
124
+ rate.mealLabel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[13px] font-medium text-primary", children: rate.mealLabel }),
125
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(CancellationChip, { cancellation: rate.cancellation }) }),
126
+ rate.dogFeeLabel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 inline-flex items-center gap-1.5 text-xs font-medium text-secondary", children: [
127
+ /* @__PURE__ */ jsxRuntime.jsx(DogIcon, { className: "w-3.5 h-3.5 flex-shrink-0" }),
128
+ rate.dogFeeLabel
129
+ ] })
130
+ ] }),
131
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right flex-shrink-0", children: [
132
+ rate.originalTotal && rate.originalTotal > rate.totalPrice && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[11px] text-text-muted line-through leading-none", children: formatPrice(rate.originalTotal) }),
133
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-heading text-lg font-bold text-primary leading-tight", children: formatPrice(rate.totalPrice) }),
134
+ rate.totalLabel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[11px] text-text-muted", children: rate.totalLabel }),
135
+ /* @__PURE__ */ jsxRuntime.jsx(
136
+ "button",
137
+ {
138
+ type: "button",
139
+ onClick: () => onSelect?.(rate.id),
140
+ "aria-pressed": selected,
141
+ className: chunkADIDI7AJ_js.cn(
142
+ "mt-1.5 text-[13px] font-medium px-4 py-1.5 rounded-full transition-colors",
143
+ selected ? "bg-secondary text-white" : "border border-secondary text-secondary hover:bg-secondary hover:text-white"
144
+ ),
145
+ children: selected ? "S\xE9lectionn\xE9" : selectLabel
146
+ }
147
+ )
148
+ ] })
149
+ ]
150
+ }
151
+ );
152
+ }
153
+ var RoomTypeCard = React__namespace.forwardRef(
154
+ ({
155
+ room,
156
+ rates,
157
+ selectedRateId,
158
+ onSelectRate,
159
+ initialVisibleRates = 2,
160
+ selectLabel = "Choisir",
161
+ variant = "default",
162
+ availability = "available",
163
+ onSeeOtherDates,
164
+ unavailableLabel = "Aucune disponibilit\xE9 sur notre site",
165
+ renderImage,
166
+ className,
167
+ ...props
168
+ }, ref) => {
169
+ const [expanded, setExpanded] = React__namespace.useState(false);
170
+ const visibleRates = expanded ? rates : rates.slice(0, initialVisibleRates);
171
+ const hiddenCount = rates.length - visibleRates.length;
172
+ const isCompact = variant === "compact";
173
+ const isUnavailable = availability === "unavailable";
174
+ const meta = [];
175
+ if (room.beds) {
176
+ meta.push(
177
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
178
+ /* @__PURE__ */ jsxRuntime.jsx(BedIcon, { className: "w-3.5 h-3.5" }),
179
+ room.beds
180
+ ] }, "beds")
181
+ );
182
+ }
183
+ if (room.sizeSqm) {
184
+ meta.push(
185
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
186
+ /* @__PURE__ */ jsxRuntime.jsx(RulerIcon, { className: "w-3.5 h-3.5" }),
187
+ room.sizeSqm,
188
+ " m\xB2"
189
+ ] }, "size")
190
+ );
191
+ }
192
+ if (room.maxOccupancy) {
193
+ meta.push(
194
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
195
+ /* @__PURE__ */ jsxRuntime.jsx(UsersIcon, { className: "w-3.5 h-3.5" }),
196
+ room.maxOccupancy,
197
+ " voyageur",
198
+ room.maxOccupancy > 1 ? "s" : ""
199
+ ] }, "occ")
200
+ );
201
+ }
202
+ return /* @__PURE__ */ jsxRuntime.jsxs(
203
+ "div",
204
+ {
205
+ ref,
206
+ className: chunkADIDI7AJ_js.cn(
207
+ "bg-white rounded-xl border border-sand-dark overflow-hidden",
208
+ className
209
+ ),
210
+ ...props,
211
+ children: [
212
+ /* @__PURE__ */ jsxRuntime.jsx(
213
+ "div",
214
+ {
215
+ className: chunkADIDI7AJ_js.cn(
216
+ "relative overflow-hidden bg-sand",
217
+ isCompact ? "h-32" : "aspect-[16/9]"
218
+ ),
219
+ children: room.image ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
220
+ renderImage ? renderImage({
221
+ src: room.image,
222
+ alt: room.establishmentPhotoLabel ?? room.name,
223
+ className: "object-cover w-full h-full"
224
+ }) : /* @__PURE__ */ jsxRuntime.jsx(
225
+ "img",
226
+ {
227
+ src: room.image,
228
+ alt: room.establishmentPhotoLabel ?? room.name,
229
+ className: "object-cover w-full h-full"
230
+ }
231
+ ),
232
+ room.establishmentPhotoLabel ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-2 left-2 inline-flex items-center gap-1 bg-black/55 text-white text-[11px] px-2 py-0.5 rounded-md", children: [
233
+ /* @__PURE__ */ jsxRuntime.jsx(GalleryIcon, { className: "w-3 h-3" }),
234
+ room.establishmentPhotoLabel
235
+ ] }) : room.imageCount != null && room.imageCount > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-2 left-2 inline-flex items-center gap-1 bg-black/55 text-white text-[11px] px-2 py-0.5 rounded-md", children: [
236
+ /* @__PURE__ */ jsxRuntime.jsx(GalleryIcon, { className: "w-3 h-3" }),
237
+ room.imageCount,
238
+ " photos"
239
+ ] })
240
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
241
+ "div",
242
+ {
243
+ className: "flex h-full w-full items-center justify-center text-text-muted",
244
+ role: "img",
245
+ "aria-label": "Photo de l'\xE9tablissement indisponible",
246
+ children: /* @__PURE__ */ jsxRuntime.jsx(GalleryIcon, { className: "h-8 w-8" })
247
+ }
248
+ )
249
+ }
250
+ ),
251
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn(isCompact ? "p-3" : "p-4"), children: [
252
+ /* @__PURE__ */ jsxRuntime.jsx(
253
+ "h3",
254
+ {
255
+ className: chunkADIDI7AJ_js.cn(
256
+ "font-heading font-bold text-primary",
257
+ isCompact ? "text-base" : "text-lg"
258
+ ),
259
+ children: room.name
260
+ }
261
+ ),
262
+ meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap gap-x-3 gap-y-1 text-[12.5px] text-text-muted", children: meta }),
263
+ room.highlight && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5 text-[12.5px] font-medium text-positive", children: room.highlight }),
264
+ room.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-[13px] leading-snug text-text-secondary", children: room.description }),
265
+ room.amenities && room.amenities.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2.5 flex flex-wrap gap-1.5", children: room.amenities.map((a, i) => /* @__PURE__ */ jsxRuntime.jsx(
266
+ "span",
267
+ {
268
+ className: "text-[11px] bg-sand-light text-text-muted px-2 py-1 rounded-full",
269
+ children: a
270
+ },
271
+ i
272
+ )) }),
273
+ isUnavailable ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3.5 border-t border-sand-dark pt-3.5", children: [
274
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[13px] font-semibold leading-snug text-danger", children: unavailableLabel }),
275
+ onSeeOtherDates && /* @__PURE__ */ jsxRuntime.jsx(
276
+ "button",
277
+ {
278
+ type: "button",
279
+ onClick: onSeeOtherDates,
280
+ className: "mt-2 inline-block text-[12.5px] font-semibold text-secondary-dark",
281
+ children: "Voir d'autres dates \u2192"
282
+ }
283
+ )
284
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3.5 border-t border-sand-dark pt-1", children: [
285
+ visibleRates.map((rate, i) => /* @__PURE__ */ jsxRuntime.jsx(
286
+ RateRow,
287
+ {
288
+ rate,
289
+ selected: rate.id === selectedRateId,
290
+ onSelect: onSelectRate,
291
+ selectLabel,
292
+ withTopBorder: i > 0
293
+ },
294
+ rate.id
295
+ )),
296
+ hiddenCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
297
+ "button",
298
+ {
299
+ type: "button",
300
+ onClick: () => setExpanded(true),
301
+ className: "mt-1 inline-flex items-center gap-1.5 text-[12.5px] font-medium text-secondary",
302
+ children: [
303
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "w-3.5 h-3.5" }),
304
+ hiddenCount,
305
+ " autre",
306
+ hiddenCount > 1 ? "s" : "",
307
+ " formule",
308
+ hiddenCount > 1 ? "s" : ""
309
+ ]
310
+ }
311
+ )
312
+ ] })
313
+ ] })
314
+ ]
315
+ }
316
+ );
317
+ }
318
+ );
319
+ RoomTypeCard.displayName = "RoomTypeCard";
320
+ var RoomTypeCardSkeleton = React__namespace.forwardRef(({ variant = "default", className, ...props }, ref) => {
321
+ const isCompact = variant === "compact";
322
+ return /* @__PURE__ */ jsxRuntime.jsxs(
323
+ "div",
324
+ {
325
+ "aria-hidden": "true",
326
+ className: chunkADIDI7AJ_js.cn(
327
+ "bg-white rounded-xl border border-sand-dark overflow-hidden",
328
+ className
329
+ ),
330
+ ref,
331
+ ...props,
332
+ children: [
333
+ /* @__PURE__ */ jsxRuntime.jsx(
334
+ chunkNCU5PY34_js.Skeleton,
335
+ {
336
+ className: chunkADIDI7AJ_js.cn("w-full rounded-none", isCompact ? "h-32" : "aspect-[16/9]")
337
+ }
338
+ ),
339
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn(isCompact ? "p-3" : "p-4", "space-y-3"), children: [
340
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNCU5PY34_js.Skeleton, { className: "h-5 w-2/3" }),
341
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
342
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNCU5PY34_js.Skeleton, { className: "h-4 w-16" }),
343
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNCU5PY34_js.Skeleton, { className: "h-4 w-20" })
344
+ ] }),
345
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-sand-dark pt-3 space-y-2", children: [
346
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNCU5PY34_js.SkeletonText, { lines: 2 }),
347
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end justify-between gap-3", children: [
348
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNCU5PY34_js.Skeleton, { className: "h-7 w-24" }),
349
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNCU5PY34_js.Skeleton, { className: "h-10 w-28 rounded-lg" })
350
+ ] })
351
+ ] })
352
+ ] })
353
+ ]
354
+ }
355
+ );
356
+ });
357
+ RoomTypeCardSkeleton.displayName = "RoomTypeCardSkeleton";
358
+
359
+ exports.RoomTypeCard = RoomTypeCard;
360
+ exports.RoomTypeCardSkeleton = RoomTypeCardSkeleton;
@@ -25,6 +25,20 @@ var colors = {
25
25
  secondary: "#6b7280",
26
26
  muted: "#9ca3af"
27
27
  },
28
+ // Navy profond — bandeaux/overlays sombres (galerie, header sombre)
29
+ ink: {
30
+ DEFAULT: "#1d2230",
31
+ soft: "#3b4559"
32
+ },
33
+ // Surfaces éditoriales — fond page / sections alternées
34
+ surface: {
35
+ 1: "#fdfcf9",
36
+ 2: "#f7f3ec"
37
+ },
38
+ // Sémantiques fiche V2
39
+ positive: "#047857",
40
+ danger: "#a8473b",
41
+ "rating-mid": "#f5b301",
28
42
  white: "#ffffff",
29
43
  black: "#000000"
30
44
  };
@@ -189,10 +189,9 @@ var DateRangePicker = React__namespace.forwardRef(
189
189
  }, [isOpen]);
190
190
  React__namespace.useEffect(() => {
191
191
  if (isOpen && isMobile) {
192
- const prev = document.body.style.overflow;
193
192
  document.body.style.overflow = "hidden";
194
193
  return () => {
195
- document.body.style.overflow = prev;
194
+ document.body.style.overflow = "";
196
195
  };
197
196
  }
198
197
  }, [isOpen, isMobile]);
@@ -29,18 +29,19 @@ var DetailList = React__namespace.forwardRef(
29
29
  return /* @__PURE__ */ jsxRuntime.jsx(
30
30
  "dl",
31
31
  {
32
- ref,
33
32
  className: chunkADIDI7AJ_js.cn(
34
33
  direction === "horizontal" ? "flex flex-wrap gap-6" : "space-y-0",
35
34
  className
36
35
  ),
36
+ ref,
37
37
  ...props,
38
38
  children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(
39
39
  "div",
40
40
  {
41
41
  className: chunkADIDI7AJ_js.cn(
42
42
  direction === "vertical" && "flex items-center justify-between py-3",
43
- direction === "vertical" && dividers && i < items.length - 1 && "border-b border-gray-100",
43
+ direction === "stacked" && "py-3",
44
+ (direction === "vertical" || direction === "stacked") && dividers && i < items.length - 1 && "border-b border-gray-100",
44
45
  direction === "horizontal" && "flex flex-col"
45
46
  ),
46
47
  children: [
@@ -48,11 +49,12 @@ var DetailList = React__namespace.forwardRef(
48
49
  "dt",
49
50
  {
50
51
  className: chunkADIDI7AJ_js.cn(
51
- "flex items-center gap-2 text-sm text-text-secondary",
52
+ "flex items-center gap-2 text-sm",
53
+ direction === "stacked" ? "font-medium text-primary mb-1" : "text-text-secondary",
52
54
  direction === "horizontal" && "text-xs uppercase tracking-wider mb-1"
53
55
  ),
54
56
  children: [
55
- item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", "aria-hidden": "true", children: item.icon }),
57
+ item.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex-shrink-0", children: item.icon }) : null,
56
58
  item.label
57
59
  ]
58
60
  }
@@ -61,7 +63,8 @@ var DetailList = React__namespace.forwardRef(
61
63
  "dd",
62
64
  {
63
65
  className: chunkADIDI7AJ_js.cn(
64
- "text-sm font-medium text-primary",
66
+ "text-sm",
67
+ direction === "stacked" ? "text-text-secondary pl-6" : "font-medium text-primary",
65
68
  direction === "horizontal" && "text-lg font-bold"
66
69
  ),
67
70
  children: item.value
@@ -167,10 +167,9 @@ var DateRangePicker = React.forwardRef(
167
167
  }, [isOpen]);
168
168
  React.useEffect(() => {
169
169
  if (isOpen && isMobile) {
170
- const prev = document.body.style.overflow;
171
170
  document.body.style.overflow = "hidden";
172
171
  return () => {
173
- document.body.style.overflow = prev;
172
+ document.body.style.overflow = "";
174
173
  };
175
174
  }
176
175
  }, [isOpen, isMobile]);
@@ -17,6 +17,7 @@ var Counter = React.forwardRef(
17
17
  {
18
18
  type: "button",
19
19
  disabled: !canDecrement,
20
+ onPointerDown: (e) => e.stopPropagation(),
20
21
  onClick: () => canDecrement && onChange?.(value - 1),
21
22
  className: cn(
22
23
  "w-8 h-8 rounded-full border flex items-center justify-center transition-colors",
@@ -32,6 +33,7 @@ var Counter = React.forwardRef(
32
33
  {
33
34
  type: "button",
34
35
  disabled: !canIncrement,
36
+ onPointerDown: (e) => e.stopPropagation(),
35
37
  onClick: () => canIncrement && onChange?.(value + 1),
36
38
  className: cn(
37
39
  "w-8 h-8 rounded-full border flex items-center justify-center transition-colors",
@@ -7,18 +7,19 @@ var DetailList = React.forwardRef(
7
7
  return /* @__PURE__ */ jsx(
8
8
  "dl",
9
9
  {
10
- ref,
11
10
  className: cn(
12
11
  direction === "horizontal" ? "flex flex-wrap gap-6" : "space-y-0",
13
12
  className
14
13
  ),
14
+ ref,
15
15
  ...props,
16
16
  children: items.map((item, i) => /* @__PURE__ */ jsxs(
17
17
  "div",
18
18
  {
19
19
  className: cn(
20
20
  direction === "vertical" && "flex items-center justify-between py-3",
21
- direction === "vertical" && dividers && i < items.length - 1 && "border-b border-gray-100",
21
+ direction === "stacked" && "py-3",
22
+ (direction === "vertical" || direction === "stacked") && dividers && i < items.length - 1 && "border-b border-gray-100",
22
23
  direction === "horizontal" && "flex flex-col"
23
24
  ),
24
25
  children: [
@@ -26,11 +27,12 @@ var DetailList = React.forwardRef(
26
27
  "dt",
27
28
  {
28
29
  className: cn(
29
- "flex items-center gap-2 text-sm text-text-secondary",
30
+ "flex items-center gap-2 text-sm",
31
+ direction === "stacked" ? "font-medium text-primary mb-1" : "text-text-secondary",
30
32
  direction === "horizontal" && "text-xs uppercase tracking-wider mb-1"
31
33
  ),
32
34
  children: [
33
- item.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", "aria-hidden": "true", children: item.icon }),
35
+ item.icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "flex-shrink-0", children: item.icon }) : null,
34
36
  item.label
35
37
  ]
36
38
  }
@@ -39,7 +41,8 @@ var DetailList = React.forwardRef(
39
41
  "dd",
40
42
  {
41
43
  className: cn(
42
- "text-sm font-medium text-primary",
44
+ "text-sm",
45
+ direction === "stacked" ? "text-text-secondary pl-6" : "font-medium text-primary",
43
46
  direction === "horizontal" && "text-lg font-bold"
44
47
  ),
45
48
  children: item.value
@@ -0,0 +1,53 @@
1
+ import { cn } from './chunk-IMKLN273.mjs';
2
+ import * as React from 'react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ var FloatingDock = React.forwardRef(
6
+ ({ items, className, ariaLabel = "Navigation rapide", onNavigate }, ref) => {
7
+ return /* @__PURE__ */ jsx(
8
+ "nav",
9
+ {
10
+ ref,
11
+ "aria-label": ariaLabel,
12
+ className: cn(
13
+ "inline-flex items-center gap-1 rounded-full border border-black/5 bg-white/95 px-2 py-2 shadow-[0_8px_30px_rgba(0,0,0,0.12)] backdrop-blur",
14
+ className
15
+ ),
16
+ children: items.map((item) => /* @__PURE__ */ jsxs(
17
+ "a",
18
+ {
19
+ href: item.href,
20
+ "aria-label": item.label,
21
+ "aria-current": item.isActive ? "page" : void 0,
22
+ title: item.label,
23
+ onClick: onNavigate ? (event) => {
24
+ event.preventDefault();
25
+ onNavigate(item);
26
+ } : void 0,
27
+ className: cn(
28
+ "flex min-h-[44px] items-center justify-center rounded-full outline-none transition-colors focus-visible:ring-2 focus-visible:ring-secondary focus-visible:ring-offset-2",
29
+ item.isActive ? "bg-secondary px-4 text-white" : "w-11 text-primary/70 hover:bg-secondary/5 hover:text-secondary"
30
+ ),
31
+ children: [
32
+ /* @__PURE__ */ jsx("span", { className: "shrink-0", "aria-hidden": "true", children: item.icon }),
33
+ /* @__PURE__ */ jsx(
34
+ "span",
35
+ {
36
+ className: cn(
37
+ "overflow-hidden whitespace-nowrap text-sm font-medium transition-all duration-300",
38
+ item.isActive ? "ml-2 max-w-[8rem] opacity-100" : "ml-0 max-w-0 opacity-0"
39
+ ),
40
+ children: item.label
41
+ }
42
+ )
43
+ ]
44
+ },
45
+ item.key
46
+ ))
47
+ }
48
+ );
49
+ }
50
+ );
51
+ FloatingDock.displayName = "FloatingDock";
52
+
53
+ export { FloatingDock };