CoolFace
Apppublic

GHSsda/HotelManagement

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
Dashboard.html1975 linesDownload Raw Back to root
1<!DOCTYPE html>
2<html lang="it">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width, initial-scale=1.0">
6<title>Flora · Yield Intelligence</title>
7<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,300&display=swap" rel="stylesheet">
9
10<style>
11/* ═══════════════════════════════════════
12   TOKENS — Apple HIG 2025
13═══════════════════════════════════════ */
14:root {
15  /* Neutrals */
16  --ink:        #1a1a1a;
17  --ink-2:      #3d3d3d;
18  --ink-3:      #8a8a8e;
19  --ink-4:      #c7c7cc;
20  --ink-5:      #e5e5ea;
21  --ink-6:      #f2f2f7;
22  --bg:         #fafafa;
23  --white:      #ffffff;
24
25  /* Accent — single restrained blue */
26  --blue:       #006edc;
27  --blue-soft:  rgba(0, 110, 220, 0.08);
28  --blue-ring:  rgba(0, 110, 220, 0.2);
29
30  /* Semantic */
31  --green:      #30a46c;
32  --green-soft: rgba(48, 164, 108, 0.08);
33  --amber:      #e07b00;
34  --amber-soft: rgba(224, 123, 0, 0.08);
35  --red:        #e5484d;
36  --red-soft:   rgba(229, 72, 77, 0.08);
37
38  /* Surface */
39  --card-bg:    rgba(255,255,255,0.72);
40  --card-border: rgba(0,0,0,0.06);
41  --card-shadow: 0 1px 3px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.04);
42  --card-shadow-hover: 0 1px 3px rgba(0,0,0,0.06), 0 8px 28px rgba(0,0,0,0.08);
43
44  /* Layout */
45  --sidebar-w:  228px;
46  --bar-h:      50px;
47  --r:          14px;
48  --r-sm:       9px;
49  --r-xs:       6px;
50
51  /* Motion */
52  --spring:     cubic-bezier(0.34, 1.56, 0.64, 1);
53  --ease:       cubic-bezier(0.25, 0.1, 0.25, 1);
54  --fast:       0.15s;
55  --mid:        0.25s;
56  --slow:       0.4s;
57}
58
59[data-theme="dark"] {
60  --ink:        #f7f7fb;
61  --ink-2:      #e4e7ef;
62  --ink-3:      #9aa3b2;
63  --ink-4:      #657083;
64  --ink-5:      #263142;
65  --ink-6:      #151c28;
66  --bg:         #0b111b;
67  --white:      #111827;
68  --blue:       #63a7ff;
69  --blue-soft:  rgba(99, 167, 255, 0.14);
70  --blue-ring:  rgba(99, 167, 255, 0.28);
71  --green:      #57d08d;
72  --green-soft: rgba(87, 208, 141, 0.13);
73  --amber:      #ffb454;
74  --amber-soft: rgba(255, 180, 84, 0.13);
75  --red:        #ff6b72;
76  --red-soft:   rgba(255, 107, 114, 0.13);
77  --card-bg:    rgba(17,24,39,0.72);
78  --card-border: rgba(255,255,255,0.08);
79  --card-shadow: 0 1px 3px rgba(0,0,0,0.24), 0 14px 42px rgba(0,0,0,0.22);
80  --card-shadow-hover: 0 1px 3px rgba(0,0,0,0.30), 0 18px 56px rgba(0,0,0,0.30);
81}
82
83/* ═══ RESET ═══ */
84*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
85html { height: 100%; }
86body {
87  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'DM Sans', sans-serif;
88  background:
89    linear-gradient(180deg, rgba(255,255,255,0.88) 0%, rgba(242,244,248,0.9) 46%, rgba(238,241,246,1) 100%),
90    var(--bg);
91  color: var(--ink);
92  height: 100vh;
93  overflow: hidden;
94  -webkit-font-smoothing: antialiased;
95  text-rendering: optimizeLegibility;
96  font-size: 13px;
97  line-height: 1.5;
98}
99
100/* ═══ SCROLLBAR ═══ */
101::-webkit-scrollbar { width: 4px; height: 4px; }
102::-webkit-scrollbar-track { background: transparent; }
103::-webkit-scrollbar-thumb { background: var(--ink-5); border-radius: 4px; }
104::-webkit-scrollbar-thumb:hover { background: var(--ink-4); }
105.hide-scroll::-webkit-scrollbar { display: none; }
106
107/* ═══ SELECTION ═══ */
108::selection { background: var(--blue-soft); color: var(--blue); }
109
110/* ═══════════════════════════════════════
111   LAYOUT
112═══════════════════════════════════════ */
113.app { display: flex; height: 100vh; }
114
115/* ═══════════════════════════════════════
116   SIDEBAR
117═══════════════════════════════════════ */
118.sidebar {
119  width: var(--sidebar-w);
120  flex-shrink: 0;
121  background: rgba(250,250,252,0.88);
122  backdrop-filter: blur(24px) saturate(180%);
123  -webkit-backdrop-filter: blur(24px) saturate(180%);
124  border-right: 1px solid var(--card-border);
125  display: flex;
126  flex-direction: column;
127  overflow: hidden;
128  position: relative;
129  z-index: 10;
130}
131
132/* Subtle noise texture overlay */
133.sidebar::before {
134  content: '';
135  position: absolute;
136  inset: 0;
137  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E");
138  pointer-events: none;
139  z-index: 0;
140}
141.sidebar > * { position: relative; z-index: 1; }
142
143/* Logo area */
144.sb-top {
145  padding: 20px 16px 16px;
146  border-bottom: 1px solid var(--card-border);
147}
148.wordmark {
149  display: flex; align-items: center; gap: 10px;
150  user-select: none; cursor: default;
151}
152.wordmark-icon {
153  width: 32px; height: 32px;
154  border-radius: 9px;
155  background: var(--ink);
156  display: flex; align-items: center; justify-content: center;
157  flex-shrink: 0;
158  position: relative;
159  overflow: hidden;
160}
161.wordmark-icon::after {
162  content: '';
163  position: absolute;
164  top: 0; left: 0; right: 0;
165  height: 50%;
166  background: linear-gradient(180deg, rgba(255,255,255,0.12) 0%, transparent 100%);
167  border-radius: 9px 9px 0 0;
168}
169.wi-letter {
170  font-size: 15px;
171  font-weight: 700;
172  color: #fff;
173  letter-spacing: -0.04em;
174  line-height: 1;
175}
176.wordmark-text { flex: 1; }
177.wm-name {
178  font-size: 14px;
179  font-weight: 700;
180  letter-spacing: -0.02em;
181  color: var(--ink);
182  line-height: 1.1;
183}
184.wm-sub {
185  font-size: 10.5px;
186  font-weight: 400;
187  color: var(--ink-3);
188  margin-top: 1px;
189  letter-spacing: 0.01em;
190}
191
192/* Room switcher */
193.room-sw {
194  margin-top: 14px;
195  background: var(--ink-6);
196  border-radius: var(--r-xs);
197  padding: 3px;
198  display: flex;
199  position: relative;
200}
201.room-sw-track {
202  position: absolute;
203  top: 3px; bottom: 3px;
204  width: calc(50% - 3px);
205  background: var(--white);
206  border-radius: 4px;
207  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
208  transition: transform var(--mid) var(--spring);
209  pointer-events: none;
210  left: 3px;
211}
212.room-sw-track.right { transform: translateX(calc(100% + 0px)); }
213.room-btn {
214  flex: 1;
215  padding: 5px 0;
216  font-size: 11px;
217  font-weight: 600;
218  letter-spacing: 0.02em;
219  text-transform: uppercase;
220  font-family: 'DM Sans', sans-serif;
221  border: none;
222  background: transparent;
223  color: var(--ink-3);
224  cursor: pointer;
225  transition: color var(--fast) var(--ease);
226  position: relative; z-index: 1;
227}
228.room-btn.active { color: var(--ink); }
229
230/* Nav */
231.sb-nav { flex: 1; overflow-y: auto; padding: 10px 8px; }
232.nav-section-label {
233  font-size: 10px;
234  font-weight: 600;
235  letter-spacing: 0.09em;
236  text-transform: uppercase;
237  color: var(--ink-4);
238  padding: 10px 8px 5px;
239}
240
241.nav-item {
242  display: flex; align-items: center; gap: 9px;
243  width: 100%; padding: 8px 10px;
244  border-radius: var(--r-xs);
245  border: none;
246  background: transparent;
247  color: var(--ink-3);
248  font-family: 'DM Sans', sans-serif;
249  font-size: 13px;
250  font-weight: 500;
251  cursor: pointer;
252  text-align: left;
253  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
254  position: relative;
255  margin-bottom: 1px;
256}
257.nav-item svg { width: 15px; height: 15px; flex-shrink: 0; transition: opacity var(--fast); opacity: 0.5; }
258.nav-item:hover { background: rgba(0,0,0,0.04); color: var(--ink-2); }
259.nav-item:hover svg { opacity: 0.75; }
260.nav-item.active { background: var(--white); color: var(--ink); font-weight: 600; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
261.nav-item.active svg { opacity: 1; }
262.nav-item.active::before {
263  content: '';
264  position: absolute;
265  left: 0; top: 50%;
266  transform: translateY(-50%);
267  width: 3px; height: 16px;
268  background: var(--blue);
269  border-radius: 0 2px 2px 0;
270}
271
272/* Sidebar footer */
273.sb-footer {
274  padding: 10px 10px 14px;
275  border-top: 1px solid var(--card-border);
276  display: flex; flex-direction: column; gap: 8px;
277}
278
279.status-chip {
280  display: flex; align-items: center; gap: 7px;
281  padding: 7px 10px;
282  border-radius: var(--r-xs);
283  background: var(--green-soft);
284  border: 1px solid rgba(48,164,108,0.12);
285}
286.s-dot {
287  width: 6px; height: 6px;
288  border-radius: 50%;
289  background: var(--green);
290  flex-shrink: 0;
291  animation: breathe 2.4s ease-in-out infinite;
292}
293@keyframes breathe {
294  0%,100% { opacity: 1; transform: scale(1); }
295  50% { opacity: 0.3; transform: scale(0.7); }
296}
297.s-label { font-size: 11px; font-weight: 600; color: var(--green); letter-spacing: 0.01em; }
298.s-clock { font-size: 11px; color: var(--ink-3); margin-left: auto; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
299
300/* ═══════════════════════════════════════
301   MAIN AREA
302═══════════════════════════════════════ */
303.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; }
304
305/* Topbar */
306.topbar {
307  height: var(--bar-h);
308  background: rgba(250,250,252,0.88);
309  backdrop-filter: blur(24px);
310  -webkit-backdrop-filter: blur(24px);
311  border-bottom: 1px solid var(--card-border);
312  display: flex; align-items: center;
313  justify-content: space-between;
314  padding: 0 20px;
315  flex-shrink: 0;
316  gap: 12px;
317}
318
319.topbar-left { display: flex; align-items: center; gap: 12px; }
320.topbar-title {
321  font-size: 14px;
322  font-weight: 700;
323  letter-spacing: -0.02em;
324  color: var(--ink);
325}
326.topbar-div { width: 1px; height: 16px; background: var(--ink-5); }
327.topbar-meta {
328  font-size: 11.5px;
329  color: var(--ink-3);
330  font-weight: 400;
331  display: flex; align-items: center; gap: 5px;
332}
333.topbar-meta svg { width: 12px; height: 12px; opacity: 0.5; }
334.topbar-actions { display: flex; align-items: center; gap: 8px; }
335.scan-state {
336  display: flex; align-items: center; gap: 6px;
337  padding: 6px 9px;
338  border-radius: var(--r-xs);
339  background: var(--ink-6);
340  border: 1px solid var(--card-border);
341  color: var(--ink-3);
342  font-size: 11px;
343  font-weight: 600;
344  white-space: nowrap;
345}
346.scan-state.running { color: var(--blue); background: var(--blue-soft); }
347.scan-state.error { color: var(--red); background: var(--red-soft); }
348.theme-toggle {
349  width: 32px; height: 32px;
350  border: 1px solid var(--card-border);
351  border-radius: var(--r-sm);
352  background: var(--card-bg);
353  color: var(--ink-2);
354  display: flex; align-items: center; justify-content: center;
355  cursor: pointer;
356  transition: transform var(--fast) var(--spring), background var(--fast), color var(--fast);
357}
358.theme-toggle:hover { transform: translateY(-1px); color: var(--ink); }
359.theme-toggle svg { width: 15px; height: 15px; }
360
361/* Scan button */
362.scan-btn {
363  display: flex; align-items: center; gap: 7px;
364  padding: 7px 15px;
365  background: var(--ink);
366  color: #fff;
367  border: none;
368  border-radius: var(--r-sm);
369  font-family: 'DM Sans', sans-serif;
370  font-size: 12px;
371  font-weight: 600;
372  cursor: pointer;
373  transition: opacity var(--fast), transform var(--fast) var(--spring), background var(--fast);
374  letter-spacing: -0.01em;
375  position: relative;
376  overflow: hidden;
377}
378.scan-btn::after {
379  content: '';
380  position: absolute;
381  top: 0; left: 0; right: 0;
382  height: 50%;
383  background: linear-gradient(180deg, rgba(255,255,255,0.08) 0%, transparent 100%);
384}
385.scan-btn:hover { opacity: 0.85; }
386.scan-btn:active { transform: scale(0.96); }
387.scan-btn:disabled { opacity: 0.3; cursor: not-allowed; }
388.scan-btn svg { width: 12px; height: 12px; position: relative; z-index: 1; }
389.scan-btn span { position: relative; z-index: 1; }
390
391[data-theme="dark"] .sidebar,
392[data-theme="dark"] .topbar { background: rgba(13,20,32,0.88); }
393[data-theme="dark"] body {
394  background:
395    linear-gradient(180deg, rgba(11,17,27,1) 0%, rgba(16,24,38,1) 48%, rgba(9,14,23,1) 100%),
396    var(--bg);
397}
398[data-theme="dark"] .kpi-card,
399[data-theme="dark"] .panel,
400[data-theme="dark"] .decision-card { background: rgba(17,24,39,0.78); }
401[data-theme="dark"] .decision-metric { background: rgba(255,255,255,0.04); }
402[data-theme="dark"] .legend-line.comp { background: rgba(255,255,255,0.32); }
403[data-theme="dark"] .nav-item:hover,
404[data-theme="dark"] .mtx tbody tr:hover td { background: rgba(255,255,255,0.04); }
405[data-theme="dark"] .nav-item.active { background: rgba(255,255,255,0.08); }
406[data-theme="dark"] .room-sw { background: rgba(255,255,255,0.06); }
407[data-theme="dark"] .room-sw-track { background: rgba(255,255,255,0.12); }
408[data-theme="dark"] .mtx thead th { background: rgba(13,20,32,0.96); }
409[data-theme="dark"] .mtx tbody td { border-bottom-color: rgba(255,255,255,0.05); }
410[data-theme="dark"] .mtx tbody tr:hover td:first-child { background: rgba(20,29,44,0.98); }
411[data-theme="dark"] .modal-box { background: rgba(17,24,39,0.94); border-color: var(--card-border); }
412
413@media (max-width: 860px) {
414  .app { flex-direction: column; }
415  .sidebar { width: 100%; height: auto; max-height: 220px; border-right: none; border-bottom: 1px solid var(--card-border); }
416  .sb-nav { display: flex; overflow-x: auto; padding: 8px; }
417  .nav-section-label { display: none; }
418  .nav-item { width: auto; white-space: nowrap; }
419  .sb-footer { display: none; }
420  .topbar { height: auto; min-height: var(--bar-h); align-items: flex-start; flex-direction: column; padding: 12px 14px; }
421  .topbar-actions { width: 100%; justify-content: flex-end; flex-wrap: wrap; }
422  .decision-panel { grid-template-columns: 1fr; }
423  .decision-main { align-items: flex-start; flex-direction: column; }
424  .decision-side { width: 100%; grid-template-columns: 1fr 1fr; }
425  .kpi-row, .g2, .g2eq { grid-template-columns: 1fr; }
426  .content { padding: 14px; }
427}
428
429@media (max-width: 520px) {
430  .decision-side { grid-template-columns: 1fr; }
431  .decision-card { padding: 18px; }
432}
433
434/* ═══════════════════════════════════════
435   CONTENT
436═══════════════════════════════════════ */
437.content {
438  flex: 1;
439  overflow-y: auto;
440  padding: 20px 22px 30px;
441}
442
443/* Page transition */
444.view { animation: viewIn var(--mid) var(--ease) both; }
445@keyframes viewIn {
446  from { opacity: 0; transform: translateY(6px); }
447  to   { opacity: 1; transform: translateY(0); }
448}
449
450/* ═══════════════════════════════════════
451   KPI ROW
452═══════════════════════════════════════ */
453.decision-panel {
454  display: grid;
455  grid-template-columns: minmax(0, 1.4fr) minmax(280px, 0.8fr);
456  gap: 12px;
457  margin-bottom: 12px;
458}
459
460.decision-card {
461  min-height: 154px;
462  padding: 22px 24px;
463  border-radius: 8px;
464  border: 1px solid var(--card-border);
465  background:
466    linear-gradient(135deg, rgba(255,255,255,0.88), rgba(255,255,255,0.64)),
467    rgba(255,255,255,0.78);
468  box-shadow: var(--card-shadow);
469  backdrop-filter: blur(22px) saturate(170%);
470  -webkit-backdrop-filter: blur(22px) saturate(170%);
471  display: flex;
472  flex-direction: column;
473  justify-content: space-between;
474  overflow: hidden;
475}
476
477.decision-main {
478  display: flex;
479  align-items: flex-end;
480  justify-content: space-between;
481  gap: 18px;
482}
483
484.decision-copy { min-width: 0; }
485.decision-eyebrow {
486  font-size: 11px;
487  font-weight: 700;
488  color: var(--ink-3);
489  letter-spacing: 0.06em;
490  text-transform: uppercase;
491  margin-bottom: 10px;
492}
493.decision-value {
494  font-size: clamp(44px, 5vw, 68px);
495  line-height: 0.95;
496  letter-spacing: -0.06em;
497  color: var(--ink);
498  font-weight: 750;
499  font-variant-numeric: tabular-nums;
500}
501.decision-sub {
502  margin-top: 12px;
503  display: flex;
504  align-items: center;
505  gap: 8px;
506  flex-wrap: wrap;
507  color: var(--ink-3);
508  font-size: 12px;
509  font-weight: 500;
510}
511.decision-chip {
512  display: inline-flex;
513  align-items: center;
514  gap: 6px;
515  padding: 5px 9px;
516  border-radius: 999px;
517  background: var(--blue-soft);
518  color: var(--blue);
519  font-weight: 700;
520}
521.decision-side {
522  display: grid;
523  grid-template-columns: 1fr;
524  gap: 8px;
525  min-width: 190px;
526}
527.decision-metric {
528  padding: 12px 14px;
529  border-radius: 8px;
530  border: 1px solid var(--card-border);
531  background: rgba(255,255,255,0.52);
532}
533.dm-label {
534  color: var(--ink-3);
535  font-size: 10.5px;
536  font-weight: 700;
537  letter-spacing: 0.05em;
538  text-transform: uppercase;
539}
540.dm-value {
541  color: var(--ink);
542  font-size: 20px;
543  font-weight: 750;
544  letter-spacing: -0.04em;
545  margin-top: 4px;
546  font-variant-numeric: tabular-nums;
547}
548.dm-value.clickable {
549  cursor: pointer;
550  text-decoration: underline;
551  text-decoration-color: var(--ink-4);
552  text-underline-offset: 4px;
553  transition: color 0.2s;
554}
555.dm-value.clickable:hover {
556  color: var(--blue);
557  text-decoration-color: var(--blue);
558}
559
560.chart-legend {
561  display: flex;
562  align-items: center;
563  gap: 12px;
564  flex-wrap: wrap;
565  font-size: 11px;
566  color: var(--ink-3);
567  font-weight: 600;
568}
569.legend-item {
570  display: inline-flex;
571  align-items: center;
572  gap: 6px;
573  white-space: nowrap;
574}
575.legend-line {
576  width: 22px;
577  height: 2px;
578  border-radius: 999px;
579  background: var(--ink-4);
580}
581.legend-line.flora { background: var(--green); height: 3px; }
582.legend-line.avg {
583  background: repeating-linear-gradient(90deg, var(--blue) 0 6px, transparent 6px 10px);
584  height: 3px;
585}
586.legend-line.comp { background: rgba(0,0,0,0.22); }
587
588.kpi-row {
589  display: grid;
590  grid-template-columns: repeat(4, minmax(0, 1fr));
591  gap: 10px;
592  margin-bottom: 12px;
593}
594
595.kpi-card {
596  background: rgba(255,255,255,0.78);
597  backdrop-filter: blur(18px) saturate(160%);
598  -webkit-backdrop-filter: blur(18px) saturate(160%);
599  border: 1px solid var(--card-border);
600  border-radius: 8px;
601  padding: 16px 18px;
602  box-shadow: var(--card-shadow);
603  transition: box-shadow var(--mid) var(--ease), transform var(--mid) var(--spring), border-color var(--fast);
604  cursor: default;
605  position: relative;
606  overflow: hidden;
607}
608.kpi-card::before {
609  content: '';
610  position: absolute;
611  top: 0; left: 0; right: 0;
612  height: 1px;
613  background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.9) 50%, transparent 100%);
614}
615.kpi-card:hover {
616  box-shadow: var(--card-shadow-hover);
617  transform: translateY(-1px);
618  border-color: rgba(0,0,0,0.09);
619}
620
621.kpi-eyebrow {
622  display: flex; align-items: center; gap: 5px;
623  font-size: 10.5px;
624  font-weight: 500;
625  color: var(--ink-3);
626  letter-spacing: 0.04em;
627  text-transform: uppercase;
628  margin-bottom: 10px;
629}
630.kpi-eyebrow svg { width: 11px; height: 11px; opacity: 0.6; }
631
632.kpi-value {
633  font-size: 28px;
634  font-weight: 700;
635  letter-spacing: -0.04em;
636  line-height: 1;
637  color: var(--ink);
638  transition: color var(--mid);
639}
640.kpi-value.blue  { color: var(--blue); }
641.kpi-value.green { color: var(--green); }
642.kpi-value.amber { color: var(--amber); }
643
644.kpi-hint {
645  display: flex; align-items: center; gap: 5px;
646  font-size: 11px;
647  color: var(--ink-3);
648  margin-top: 6px;
649  font-weight: 400;
650}
651
652/* ═══════════════════════════════════════
653   PANELS
654═══════════════════════════════════════ */
655.panel {
656  background: rgba(255,255,255,0.78);
657  backdrop-filter: blur(18px) saturate(160%);
658  -webkit-backdrop-filter: blur(18px) saturate(160%);
659  border: 1px solid var(--card-border);
660  border-radius: 8px;
661  box-shadow: var(--card-shadow);
662  overflow: hidden;
663  position: relative;
664  transition: box-shadow var(--mid) var(--ease);
665}
666.panel::before {
667  content: '';
668  position: absolute;
669  top: 0; left: 0; right: 0;
670  height: 1px;
671  background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.9) 50%, transparent 100%);
672  z-index: 1;
673}
674.panel:hover { box-shadow: var(--card-shadow-hover); }
675
676.panel-head {
677  display: flex; align-items: center; justify-content: space-between;
678  padding: 13px 18px;
679  border-bottom: 1px solid var(--card-border);
680  gap: 12px;
681  flex-wrap: wrap;
682}
683.panel-title {
684  display: flex; align-items: center; gap: 7px;
685  font-size: 12.5px;
686  font-weight: 700;
687  color: var(--ink);
688  letter-spacing: -0.01em;
689}
690.panel-title svg { width: 14px; height: 14px; color: var(--ink-3); }
691
692/* Date range control */
693.date-range {
694  display: flex; align-items: center; gap: 8px;
695  background: var(--ink-6);
696  border: 1px solid var(--card-border);
697  border-radius: var(--r-xs);
698  padding: 5px 10px;
699}
700.dr-lbl {
701  font-size: 9.5px;
702  font-weight: 600;
703  letter-spacing: 0.07em;
704  text-transform: uppercase;
705  color: var(--ink-3);
706}
707.dr-sep { width: 1px; height: 10px; background: var(--ink-5); }
708input[type="date"], select {
709  background: transparent;
710  border: none;
711  outline: none;
712  color: var(--ink-2);
713  font-family: 'DM Sans', sans-serif;
714  font-size: 11.5px;
715  font-weight: 500;
716  cursor: pointer;
717}
718input[type="date"]:focus, select:focus { color: var(--ink); }
719
720/* ═══════════════════════════════════════
721   TWO-COLUMN GRID
722═══════════════════════════════════════ */
723.g2   { display: grid; grid-template-columns: 1fr 295px; gap: 10px; }
724.g2eq { display: grid; grid-template-columns: 1fr 1fr;   gap: 10px; }
725.mb10 { margin-bottom: 10px; }
726.mb12 { margin-bottom: 12px; }
727
728/* ═══════════════════════════════════════
729   MATRIX TABLE
730═══════════════════════════════════════ */
731.mtx-scroll { overflow: auto; max-height: 420px; }
732.mtx { width: 100%; border-collapse: collapse; }
733.mtx thead th {
734  position: sticky; top: 0; z-index: 10;
735  background: rgba(250,250,252,0.95);
736  backdrop-filter: blur(8px);
737  font-size: 9.5px;
738  font-weight: 600;
739  letter-spacing: 0.07em;
740  text-transform: uppercase;
741  color: var(--ink-3);
742  padding: 9px 14px;
743  border-bottom: 1px solid var(--card-border);
744  white-space: nowrap;
745  text-align: center;
746  cursor: pointer;
747  transition: color 0.15s, background 0.15s;
748}
749.mtx thead th:hover {
750  color: var(--blue);
751  background: rgba(0,110,220,0.04);
752}
753.mtx thead th:first-child { text-align: left; position: sticky; left: 0; z-index: 20; cursor: default; }
754.mtx thead th:first-child:hover { color: var(--ink-3); background: rgba(250,250,252,0.95); }
755.mtx tbody td {
756  padding: 8px 14px;
757  font-size: 12px;
758  text-align: center;
759  color: var(--ink-2);
760  border-bottom: 1px solid rgba(0,0,0,0.04);
761  font-variant-numeric: tabular-nums;
762  transition: background var(--fast);
763}
764.mtx tbody td:first-child {
765  text-align: left;
766  position: sticky; left: 0;
767  background: var(--card-bg);
768  z-index: 5;
769}
770.mtx tbody tr:last-child td { border-bottom: none; }
771.mtx tbody tr { transition: background var(--fast); }
772.mtx tbody tr:hover td { background: rgba(0,0,0,0.015); }
773.mtx tbody tr:hover td:first-child { background: rgba(250,250,252,0.98); }
774.mtx tbody tr.is-target td:first-child { background: var(--blue-soft); }
775.mtx tbody tr.is-target:hover td:first-child { background: rgba(0,110,220,0.1); }
776
777.h-cell { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
778.h-name {
779  font-size: 12px;
780  font-weight: 500;
781  color: var(--ink-2);
782  white-space: nowrap;
783  overflow: hidden;
784  text-overflow: ellipsis;
785  max-width: 126px;
786}
787.h-name.target { color: var(--ink); font-weight: 600; }
788
789.badge {
790  display: inline-flex; align-items: center;
791  font-size: 9px;
792  font-weight: 700;
793  letter-spacing: 0.06em;
794  text-transform: uppercase;
795  padding: 2px 6px;
796  border-radius: 4px;
797  flex-shrink: 0;
798}
799.badge-you { background: var(--blue-soft); color: var(--blue); }
800.badge-so  { background: var(--red-soft);  color: var(--red); }
801
802.p-val { font-size: 12px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--ink-2); }
803.p-val.target { color: var(--green); font-weight: 600; }
804
805.mv-btn {
806  background: none; border: none; cursor: pointer;
807  color: var(--ink-4);
808  font-size: 9px;
809  padding: 1px 2px;
810  border-radius: 3px;
811  line-height: 1;
812  transition: color var(--fast), background var(--fast);
813}
814.mv-btn:hover { color: var(--ink); background: var(--ink-6); }
815
816/* ═══════════════════════════════════════
817   ACTION PLAN
818═══════════════════════════════════════ */
819.apl {
820  padding: 8px;
821  display: flex;
822  flex-direction: column;
823  gap: 5px;
824  max-height: 420px;
825  overflow-y: auto;
826}
827
828.acard {
829  border: 1px solid var(--card-border);
830  border-radius: var(--r-sm);
831  padding: 11px 13px;
832  cursor: pointer;
833  background: rgba(0,0,0,0.014);
834  transition: background var(--fast), border-color var(--fast), transform var(--fast) var(--spring), box-shadow var(--fast);
835  position: relative;
836}
837.acard:hover {
838  background: var(--white);
839  border-color: rgba(0,0,0,0.1);
840  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
841  transform: translateY(-1px);
842}
843.acard.sel {
844  background: var(--blue-soft);
845  border-color: var(--blue-ring);
846  box-shadow: 0 0 0 1px var(--blue-ring);
847}
848.acard.sel:hover { transform: none; }
849
850.ac-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
851.ac-date {
852  font-size: 12.5px;
853  font-weight: 700;
854  color: var(--ink);
855  letter-spacing: -0.02em;
856  font-variant-numeric: tabular-nums;
857}
858.pill {
859  font-size: 9.5px;
860  font-weight: 700;
861  letter-spacing: 0.04em;
862  text-transform: uppercase;
863  padding: 3px 8px;
864  border-radius: 20px;
865}
866.pill-g { background: var(--green-soft); color: var(--green); }
867.pill-b { background: var(--blue-soft);  color: var(--blue); }
868.pill-a { background: var(--amber-soft); color: var(--amber); }
869.pill-r { background: var(--red-soft);   color: var(--red); }
870
871.ac-body { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
872.ac-metric {}
873.ac-metric-lbl { font-size: 10px; color: var(--ink-3); font-weight: 400; }
874.ac-metric-val {
875  font-size: 15px;
876  font-weight: 700;
877  color: var(--ink);
878  letter-spacing: -0.03em;
879  font-variant-numeric: tabular-nums;
880  margin-top: 1px;
881}
882.ac-metric-val.accent { color: var(--blue); }
883
884/* ═══════════════════════════════════════
885   SECTION HEADER
886═══════════════════════════════════════ */
887.view-head { margin-bottom: 16px; }
888.vh-title {
889  font-size: 22px;
890  font-weight: 700;
891  letter-spacing: -0.04em;
892  color: var(--ink);
893}
894.vh-sub {
895  font-size: 12.5px;
896  color: var(--ink-3);
897  margin-top: 3px;
898  font-weight: 400;
899}
900
901/* ═══════════════════════════════════════
902   SELECT CONTROL
903═══════════════════════════════════════ */
904.sel-box {
905  background: var(--ink-6);
906  border: 1px solid var(--card-border);
907  border-radius: var(--r-xs);
908  padding: 5px 10px;
909  font-family: 'DM Sans', sans-serif;
910  font-size: 11.5px;
911  font-weight: 500;
912  color: var(--ink-2);
913  outline: none;
914  cursor: pointer;
915  transition: border-color var(--fast), color var(--fast);
916}
917.sel-box:focus { border-color: var(--blue); color: var(--ink); }
918.sel-box:hover { border-color: var(--ink-4); }
919
920/* ═══════════════════════════════════════
921   YIELD RULES
922═══════════════════════════════════════ */
923.yield-rule {
924  background: rgba(0,0,0,0.015);
925  border: 1px solid var(--card-border);
926  border-left: 2px solid;
927  border-radius: var(--r-sm);
928  padding: 14px 16px;
929  transition: background var(--fast);
930}
931.yield-rule:hover { background: rgba(0,0,0,0.03); }
932.yr-title { font-size: 12.5px; font-weight: 700; margin-bottom: 5px; letter-spacing: -0.01em; }
933.yr-body  { font-size: 12px; color: var(--ink-2); line-height: 1.6; }
934
935/* ═══════════════════════════════════════
936   VIEWS
937═══════════════════════════════════════ */
938#view-radar, #view-seasonal { display: none; }
939
940/* ═══════════════════════════════════════
941   EMPTY STATE
942═══════════════════════════════════════ */
943.empty-state {
944  display: flex; flex-direction: column; align-items: center; justify-content: center;
945  padding: 52px 24px; text-align: center;
946}
947.empty-state svg { width: 28px; height: 28px; color: var(--ink-4); margin-bottom: 12px; }
948.es-title { font-size: 13.5px; font-weight: 600; color: var(--ink-2); margin-bottom: 4px; }
949.es-sub   { font-size: 12px; color: var(--ink-3); }
950
951/* ═══════════════════════════════════════
952   MODAL
953═══════════════════════════════════════ */
954.modal-ov {
955  position: fixed; inset: 0; z-index: 200;
956  background: rgba(0,0,0,0.25);
957  backdrop-filter: blur(10px) saturate(160%);
958  -webkit-backdrop-filter: blur(10px) saturate(160%);
959  display: flex; align-items: center; justify-content: center;
960  animation: fadeOv var(--fast) var(--ease) both;
961}
962@keyframes fadeOv { from { opacity: 0; } to { opacity: 1; } }
963
964.modal-box {
965  background: rgba(255,255,255,0.9);
966  backdrop-filter: blur(32px) saturate(200%);
967  -webkit-backdrop-filter: blur(32px) saturate(200%);
968  border: 1px solid rgba(0,0,0,0.08);
969  border-radius: 18px;
970  width: 100%;
971  max-width: 580px;
972  margin: 0 16px;
973  overflow: hidden;
974  box-shadow: 0 4px 8px rgba(0,0,0,0.04), 0 24px 64px rgba(0,0,0,0.12), 0 0 0 1px rgba(255,255,255,0.6) inset;
975  animation: modalIn var(--mid) var(--spring) both;
976}
977@keyframes modalIn {
978  from { opacity: 0; transform: scale(0.96) translateY(4px); }
979  to   { opacity: 1; transform: scale(1) translateY(0); }
980}
981
982.modal-head {
983  padding: 14px 18px;
984  border-bottom: 1px solid var(--card-border);
985  display: flex; align-items: center; justify-content: space-between;
986}
987.modal-close {
988  width: 24px; height: 24px;
989  border-radius: 50%;
990  background: var(--ink-6);
991  border: 1px solid var(--card-border);
992  display: flex; align-items: center; justify-content: center;
993  cursor: pointer;
994  color: var(--ink-3);
995  transition: background var(--fast), color var(--fast), transform var(--fast) var(--spring);
996}
997.modal-close:hover { background: var(--ink-5); color: var(--ink); transform: scale(1.1); }
998.modal-close svg { width: 11px; height: 11px; }
999
1000/* ═══════════════════════════════════════
1001   INLINE SVG ICONS (no external dep)
1002═══════════════════════════════════════ */
1003.ico { display: inline-block; vertical-align: middle; flex-shrink: 0; }
1004</style>
1005</head>
1006<body>
1007
1008<div class="app">
1009
1010  <!-- ════════════════════════
1011       SIDEBAR
1012  ════════════════════════ -->
1013  <aside class="sidebar">
1014    <div class="sb-top">
1015      <div class="wordmark">
1016        <div class="wordmark-icon">
1017          <span class="wi-letter">F</span>
1018        </div>
1019        <div class="wordmark-text">
1020          <div class="wm-name">Flora</div>
1021          <div class="wm-sub">Yield Intelligence</div>
1022        </div>
1023      </div>
1024
1025      <!-- Room switcher -->
1026      <div class="room-sw" id="room-sw">
1027        <div class="room-sw-track" id="room-track"></div>
1028        <button class="room-btn" id="btn-room-Singola" onclick="setRoom('Singola')">Singola</button>
1029        <button class="room-btn active" id="btn-room-Doppia" onclick="setRoom('Doppia')">Doppia</button>
1030      </div>
1031    </div>
1032
1033    <nav class="sb-nav">
1034      <div class="nav-section-label">Analisi</div>
1035      <button class="nav-item active" id="btn-dashboard" onclick="setView('dashboard')">
1036        <svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="1" width="6" height="6" rx="1.5"/><rect x="9" y="1" width="6" height="6" rx="1.5"/><rect x="1" y="9" width="6" height="6" rx="1.5"/><rect x="9" y="9" width="6" height="6" rx="1.5"/></svg>
1037        Operativa
1038      </button>
1039      <button class="nav-item" id="btn-radar" onclick="setView('radar')">
1040        <svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="7"/><circle cx="8" cy="8" r="4"/><circle cx="8" cy="8" r="1" fill="currentColor" stroke="none"/><line x1="8" y1="1" x2="8" y2="4"/><line x1="11.5" y1="4.5" x2="9.5" y2="6.5"/></svg>
1041        Radar 365
1042      </button>
1043      <button class="nav-item" id="btn-seasonal" onclick="setView('seasonal')">
1044        <svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1,12 5,7 9,10 15,3"/><line x1="1" y1="15" x2="15" y2="15"/></svg>
1045        Stagionale
1046      </button>
1047    </nav>
1048
1049    <div class="sb-footer">
1050      <div class="status-chip">
1051        <div class="s-dot"></div>
1052        <span class="s-label">Live</span>
1053        <span class="s-clock" id="hclock">--:--</span>
1054      </div>
1055    </div>
1056  </aside>
1057
1058  <!-- ════════════════════════
1059       MAIN
1060  ════════════════════════ -->
1061  <div class="main">
1062
1063    <!-- Topbar -->
1064    <header class="topbar">
1065      <div class="topbar-left">
1066        <span class="topbar-title" id="topbar-title">Operativa</span>
1067        <div class="topbar-div"></div>
1068        <span class="topbar-meta">
1069          <svg class="ico" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><rect x="1" y="2" width="10" height="9" rx="1.5"/><line x1="4" y1="1" x2="4" y2="3"/><line x1="8" y1="1" x2="8" y2="3"/><line x1="1" y1="5" x2="11" y2="5"/></svg>
1070          Hotel Flora · 50 camere
1071        </span>
1072      </div>
1073      <div class="topbar-actions">
1074        <div class="scan-state" id="scan-state">Pronto</div>
1075        <button class="theme-toggle" id="theme-toggle" onclick="toggleTheme()" title="Cambia tema">
1076          <svg id="theme-icon" class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="3.5"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.1 3.1l1.4 1.4M11.5 11.5l1.4 1.4M12.9 3.1l-1.4 1.4M4.5 11.5l-1.4 1.4"/></svg>
1077        </button>
1078        <button class="scan-btn" id="btn-run-bot" onclick="avviaBotRemoto()">
1079          <svg id="bot-icon" class="ico" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><polygon points="3,1 11,6 3,11"/></svg>
1080          <span id="bot-text">Avvia Scansione</span>
1081        </button>
1082      </div>
1083    </header>
1084
1085    <!-- Content -->
1086    <div class="content">
1087
1088      <!-- ══════════ DASHBOARD ══════════ -->
1089      <div id="view-dashboard" class="view">
1090
1091        <div class="decision-panel">
1092          <section class="decision-card">
1093            <div>
1094              <div class="decision-eyebrow">Decisione tariffaria</div>
1095              <div class="decision-main">
1096                <div class="decision-copy">
1097                  <div class="decision-value" id="hero-suggested">—</div>
1098                  <div class="decision-sub">
1099                    <span class="decision-chip" id="hero-strategy">Strategia —</span>
1100                    <span id="hero-delta">vs media aggregata —</span>
1101                  </div>
1102                </div>
1103                <div class="decision-side">
1104                  <div class="decision-metric">
1105                    <div class="dm-label">Media aggregata</div>
1106                    <div class="dm-value" id="hero-avg">—</div>
1107                  </div>
1108                  <div class="decision-metric">
1109                    <div class="dm-label">Data selezionata</div>
1110                    <div class="dm-value clickable" id="hero-date" onclick="pickDate()" title="Clicca per cambiare data">—</div>
1111                  </div>
1112                </div>
1113              </div>
1114            </div>
1115          </section>
1116
1117          <section class="decision-card">
1118            <div class="decision-eyebrow">Mercato</div>
1119            <div class="decision-side" style="min-width:0;">
1120              <div class="decision-metric">
1121                <div class="dm-label">Competitor attivi</div>
1122                <div class="dm-value" id="hero-active">—</div>
1123              </div>
1124              <div class="decision-metric">
1125                <div class="dm-label">Incasso stimato</div>
1126                <div class="dm-value" id="hero-revenue">—</div>
1127              </div>
1128            </div>
1129          </section>
1130        </div>
1131
1132        <!-- KPIs -->
1133        <div class="kpi-row mb12">
1134          <div class="kpi-card">
1135            <div class="kpi-eyebrow">
1136              <svg class="ico" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><polyline points="1,9 4,5 7,7 11,2"/></svg>
1137              Stato Mercato
1138            </div>
1139            <div class="kpi-value blue" id="kpi-strategy">—</div>
1140            <div class="kpi-hint" id="kpi-active-comps">— competitor attivi</div>
1141          </div>
1142          <div class="kpi-card">
1143            <div class="kpi-eyebrow">
1144              <svg class="ico" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><polygon points="6,1 8,4 11,4.5 9,7 9.5,11 6,9.5 2.5,11 3,7 1,4.5 4,4"/></svg>
1145              Prezzo Suggerito
1146            </div>
1147            <div style="display:flex;align-items:baseline;gap:7px;">
1148              <div class="kpi-value green" id="kpi-suggested">—</div>
1149              <div class="kpi-hint" id="kpi-avg" style="margin-top:0;">vs — media</div>
1150            </div>
1151            <div class="kpi-hint" id="kpi-strategy-desc">Strategia: —</div>
1152          </div>
1153          <div class="kpi-card">
1154            <div class="kpi-eyebrow">
1155              <svg class="ico" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><line x1="1" y1="9" x2="11" y2="9"/><line x1="2" y1="6" x2="10" y2="6"/><line x1="3" y1="3" x2="9" y2="3"/></svg>
1156              Media Aggregata
1157            </div>
1158            <div class="kpi-value blue" id="kpi-aggregate">—</div>
1159            <div class="kpi-hint">Benchmark competitor filtrato</div>
1160          </div>
1161          <div class="kpi-card">
1162            <div class="kpi-eyebrow">
1163              <svg class="ico" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><polyline points="1,10 4,6 7,8 11,3"/><polyline points="8,3 11,3 11,6"/></svg>
1164              Proiezione Incasso
1165            </div>
1166            <div class="kpi-value amber" id="kpi-revenue">—</div>
1167            <div class="kpi-hint" id="kpi-revenue-desc">Target 20 camere · 100% occupazione</div>
1168          </div>
1169        </div>
1170
1171        <!-- Chart -->
1172        <div class="panel mb10">
1173          <div class="panel-head">
1174            <div class="panel-title">
1175              <svg class="ico" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1,10 5,5.5 8,8 13,2.5"/></svg>
1176              Andamento Prezzi
1177            </div>
1178            <div class="chart-legend" aria-label="Legenda andamento prezzi">
1179              <span class="legend-item"><span class="legend-line flora"></span>Hotel Flora</span>
1180              <span class="legend-item"><span class="legend-line avg"></span>Media aggregata</span>
1181              <span class="legend-item"><span class="legend-line comp"></span>Competitor</span>
1182            </div>
1183            <div class="date-range">
1184              <span class="dr-lbl">Da</span>
1185              <input type="date" id="dash-chart-start" onchange="renderFilteredChart()">
1186              <div class="dr-sep"></div>
1187              <span class="dr-lbl">A</span>
1188              <input type="date" id="dash-chart-end" onchange="renderFilteredChart()">
1189            </div>
1190          </div>
1191          <div style="padding:16px 18px;">
1192            <div style="height:318px;position:relative;"><canvas id="filteredChart"></canvas></div>
1193          </div>
1194        </div>
1195
1196        <!-- Matrix + Action -->
1197        <div class="g2">
1198          <div class="panel" style="display:flex;flex-direction:column;">
1199            <div class="panel-head">
1200              <div class="panel-title">

Showing the first 1,200 of 1975 lines. Download the file for the rest.