@cardinali-studio/adminkit 1.0.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 (181) hide show
  1. package/dist/api.d.ts +195 -0
  2. package/dist/api.js +118 -0
  3. package/dist/app/App.d.ts +3 -0
  4. package/dist/app/App.js +320 -0
  5. package/dist/app/app.css +2068 -0
  6. package/dist/app/index.d.ts +18 -0
  7. package/dist/app/index.js +33 -0
  8. package/dist/app/lib/bookings.d.ts +132 -0
  9. package/dist/app/lib/bookings.js +79 -0
  10. package/dist/app/lib/deliveries.d.ts +95 -0
  11. package/dist/app/lib/deliveries.js +104 -0
  12. package/dist/app/lib/delivery-drop.d.ts +1 -0
  13. package/dist/app/lib/delivery-drop.js +72 -0
  14. package/dist/app/lib/delivery-upload.d.ts +78 -0
  15. package/dist/app/lib/delivery-upload.js +585 -0
  16. package/dist/app/lib/groups.d.ts +9 -0
  17. package/dist/app/lib/groups.js +32 -0
  18. package/dist/app/lib/home.d.ts +11 -0
  19. package/dist/app/lib/home.js +67 -0
  20. package/dist/app/lib/overview.d.ts +82 -0
  21. package/dist/app/lib/overview.js +68 -0
  22. package/dist/app/lib/pages.d.ts +24 -0
  23. package/dist/app/lib/pages.js +156 -0
  24. package/dist/app/lib/publish.d.ts +18 -0
  25. package/dist/app/lib/publish.js +63 -0
  26. package/dist/app/lib/reorder.d.ts +3 -0
  27. package/dist/app/lib/reorder.js +31 -0
  28. package/dist/app/lib/requests.d.ts +10 -0
  29. package/dist/app/lib/requests.js +67 -0
  30. package/dist/app/lib/router.d.ts +1 -0
  31. package/dist/app/lib/router.js +14 -0
  32. package/dist/app/lib/settings.d.ts +29 -0
  33. package/dist/app/lib/settings.js +82 -0
  34. package/dist/app/lib/slug.d.ts +3 -0
  35. package/dist/app/lib/slug.js +23 -0
  36. package/dist/app/lib/text.d.ts +1 -0
  37. package/dist/app/lib/text.js +13 -0
  38. package/dist/app/lib/theme.d.ts +7 -0
  39. package/dist/app/lib/theme.js +43 -0
  40. package/dist/app/lib/upload-queue.d.ts +35 -0
  41. package/dist/app/lib/upload-queue.js +167 -0
  42. package/dist/app/routes/AboutEditor.d.ts +15 -0
  43. package/dist/app/routes/AboutEditor.js +122 -0
  44. package/dist/app/routes/Bookings.d.ts +21 -0
  45. package/dist/app/routes/Bookings.js +134 -0
  46. package/dist/app/routes/Deliveries.d.ts +37 -0
  47. package/dist/app/routes/Deliveries.js +563 -0
  48. package/dist/app/routes/GallerySectionsEditor.d.ts +12 -0
  49. package/dist/app/routes/GallerySectionsEditor.js +107 -0
  50. package/dist/app/routes/HomeEditor.d.ts +10 -0
  51. package/dist/app/routes/HomeEditor.js +188 -0
  52. package/dist/app/routes/Overview.d.ts +17 -0
  53. package/dist/app/routes/Overview.js +318 -0
  54. package/dist/app/routes/PageActions.d.ts +12 -0
  55. package/dist/app/routes/PageActions.js +93 -0
  56. package/dist/app/routes/PageEditor.d.ts +23 -0
  57. package/dist/app/routes/PageEditor.js +233 -0
  58. package/dist/app/routes/PageSeoEditor.d.ts +13 -0
  59. package/dist/app/routes/PageSeoEditor.js +102 -0
  60. package/dist/app/routes/PagesList.d.ts +10 -0
  61. package/dist/app/routes/PagesList.js +76 -0
  62. package/dist/app/routes/PortfolioWorksEditor.d.ts +12 -0
  63. package/dist/app/routes/PortfolioWorksEditor.js +139 -0
  64. package/dist/app/routes/Requests.d.ts +13 -0
  65. package/dist/app/routes/Requests.js +30 -0
  66. package/dist/app/routes/SiteSettingsEditor.d.ts +21 -0
  67. package/dist/app/routes/SiteSettingsEditor.js +66 -0
  68. package/dist/app/routes/UploadDock.d.ts +1 -0
  69. package/dist/app/routes/UploadDock.js +66 -0
  70. package/dist/app/routes/WorkshopEditionsEditor.d.ts +12 -0
  71. package/dist/app/routes/WorkshopEditionsEditor.js +101 -0
  72. package/dist/app/site.d.ts +37 -0
  73. package/dist/app/site.js +18 -0
  74. package/dist/app/ui/MediaSlot.d.ts +10 -0
  75. package/dist/app/ui/MediaSlot.js +20 -0
  76. package/dist/app/ui/OpenCard.d.ts +18 -0
  77. package/dist/app/ui/OpenCard.js +20 -0
  78. package/dist/app/ui/ParagraphEditor.d.ts +8 -0
  79. package/dist/app/ui/ParagraphEditor.js +37 -0
  80. package/dist/app/ui/dnd.d.ts +1 -0
  81. package/dist/app/ui/dnd.js +11 -0
  82. package/dist/app/ui/icons.d.ts +26 -0
  83. package/dist/app/ui/icons.js +45 -0
  84. package/dist/config.d.ts +5 -0
  85. package/dist/config.js +26 -0
  86. package/dist/form/MediaBrowser.d.ts +13 -0
  87. package/dist/form/MediaBrowser.js +24 -0
  88. package/dist/form/MediaPicker.d.ts +10 -0
  89. package/dist/form/MediaPicker.js +20 -0
  90. package/dist/form/SchemaForm.d.ts +21 -0
  91. package/dist/form/SchemaForm.js +67 -0
  92. package/dist/form/Trash.d.ts +1 -0
  93. package/dist/form/Trash.js +42 -0
  94. package/dist/form/fields/index.d.ts +1 -0
  95. package/dist/form/fields/index.js +110 -0
  96. package/dist/form/fields/objectList.d.ts +1 -0
  97. package/dist/form/fields/objectList.js +99 -0
  98. package/dist/form/index.d.ts +8 -0
  99. package/dist/form/index.js +8 -0
  100. package/dist/form/media/Lightbox.d.ts +4 -0
  101. package/dist/form/media/Lightbox.js +70 -0
  102. package/dist/form/media/MediaFolders.d.ts +20 -0
  103. package/dist/form/media/MediaFolders.js +116 -0
  104. package/dist/form/media/MediaGrid.d.ts +8 -0
  105. package/dist/form/media/MediaGrid.js +139 -0
  106. package/dist/form/media/UploadDialog.d.ts +4 -0
  107. package/dist/form/media/UploadDialog.js +37 -0
  108. package/dist/form/media/useMediaLibrary.d.ts +55 -0
  109. package/dist/form/media/useMediaLibrary.js +495 -0
  110. package/dist/form/prose/ProseBar.d.ts +21 -0
  111. package/dist/form/prose/ProseBar.js +111 -0
  112. package/dist/form/prose/ProseField.d.ts +11 -0
  113. package/dist/form/prose/ProseField.js +152 -0
  114. package/dist/form/prose/pages.d.ts +6 -0
  115. package/dist/form/prose/pages.js +13 -0
  116. package/dist/form/registry.d.ts +20 -0
  117. package/dist/form/registry.js +15 -0
  118. package/dist/frontmatter.d.ts +20 -0
  119. package/dist/frontmatter.js +202 -0
  120. package/dist/functions/_middleware.js +101 -0
  121. package/dist/functions/_shared/analytics-ga4.js +248 -0
  122. package/dist/functions/_shared/analytics-umami.js +119 -0
  123. package/dist/functions/_shared/assets.js +90 -0
  124. package/dist/functions/_shared/b2.js +300 -0
  125. package/dist/functions/_shared/delivery-crypto.js +99 -0
  126. package/dist/functions/_shared/delivery-purge.js +222 -0
  127. package/dist/functions/_shared/edge-cache.js +37 -0
  128. package/dist/functions/_shared/exif.js +53 -0
  129. package/dist/functions/_shared/github.js +138 -0
  130. package/dist/functions/_shared/imagesize.js +101 -0
  131. package/dist/functions/_shared/media-content.js +200 -0
  132. package/dist/functions/_shared/pending-media.js +98 -0
  133. package/dist/functions/_shared/refs.js +155 -0
  134. package/dist/functions/api/analytics.js +106 -0
  135. package/dist/functions/api/assets/delete.js +241 -0
  136. package/dist/functions/api/assets/folder.js +43 -0
  137. package/dist/functions/api/assets/folders.js +32 -0
  138. package/dist/functions/api/assets/move.js +253 -0
  139. package/dist/functions/api/assets/preview.js +17 -0
  140. package/dist/functions/api/assets/trash/delete.js +13 -0
  141. package/dist/functions/api/assets/trash/empty.js +16 -0
  142. package/dist/functions/api/assets/trash/restore.js +43 -0
  143. package/dist/functions/api/assets/trash.js +28 -0
  144. package/dist/functions/api/assets/upload.js +54 -0
  145. package/dist/functions/api/assets/usage.js +41 -0
  146. package/dist/functions/api/assets.js +94 -0
  147. package/dist/functions/api/deliveries.js +629 -0
  148. package/dist/functions/api/delivery/hero.js +21 -0
  149. package/dist/functions/api/delivery/image.js +35 -0
  150. package/dist/functions/api/delivery/multipart.js +261 -0
  151. package/dist/functions/api/pages/get.js +26 -0
  152. package/dist/functions/api/pages.js +354 -0
  153. package/dist/functions/api/publish.js +134 -0
  154. package/dist/functions/api/requests.js +57 -0
  155. package/dist/functions/api/settings.js +236 -0
  156. package/dist/functions/api/singleton.js +105 -0
  157. package/dist/functions/api/storage.js +125 -0
  158. package/dist/functions/index.js +124 -0
  159. package/dist/functions/site.js +38 -0
  160. package/dist/gallery.d.ts +28 -0
  161. package/dist/gallery.js +18 -0
  162. package/dist/index.d.ts +10 -0
  163. package/dist/index.js +10 -0
  164. package/dist/model.d.ts +2 -0
  165. package/dist/model.js +47 -0
  166. package/dist/normalize.d.ts +50 -0
  167. package/dist/normalize.js +120 -0
  168. package/dist/preview.d.ts +3 -0
  169. package/dist/preview.js +82 -0
  170. package/dist/prose.d.ts +17 -0
  171. package/dist/prose.js +205 -0
  172. package/dist/registries.d.ts +43 -0
  173. package/dist/registries.js +29 -0
  174. package/dist/serialize.d.ts +26 -0
  175. package/dist/serialize.js +136 -0
  176. package/dist/testing.d.ts +26 -0
  177. package/dist/testing.js +66 -0
  178. package/dist/theme.css +636 -0
  179. package/dist/yaml.d.ts +8 -0
  180. package/dist/yaml.js +90 -0
  181. package/package.json +97 -0
@@ -0,0 +1,2068 @@
1
+ /* Impaginazione dell'applicazione. L'ASPETTO dei campi sta in adminkit (theme.css), qui c'è
2
+ solo come sono disposte le cose in questa app.
3
+
4
+ Tre colonne, e ognuna scorre per conto suo: la navigazione non si muove, l'elenco resta al suo
5
+ posto mentre si modifica, e a scorrere è solo la cosa che si sta guardando. Con una pagina sola
6
+ che scorreva tutta insieme, aprire una pagina in fondo all'elenco e tornare indietro
7
+ significava ritrovarsi in cima. */
8
+ * { box-sizing: border-box; }
9
+ body { margin: 0; background: var(--ak-bg); color: var(--ak-ink); font-family: var(--ak-font); }
10
+
11
+ .app {
12
+ height: 100vh;
13
+ display: grid;
14
+ grid-template-columns: var(--ak-rail-w) var(--ak-col-w) minmax(0, 1fr);
15
+ overflow: hidden;
16
+ }
17
+
18
+ /* Prenotazioni: agenda operativa e impostazioni condividono la stessa grammatica del
19
+ pannello, ma usano più spazio orizzontale per rendere leggibili orari e stati. */
20
+ .bk-page{max-width:1180px;margin:0 auto;padding:clamp(1.4rem,3vw,3rem)}
21
+ .bk-kicker{margin:0 0 .55rem;text-transform:uppercase;letter-spacing:.13em;font-size:.68rem;color:var(--ak-muted,#777)}
22
+ .bk-hero,.bk-detail-head{display:flex;justify-content:space-between;gap:2rem;align-items:flex-start;padding-bottom:2.2rem;border-bottom:1px solid var(--ak-line,#ddd)}
23
+ .bk-hero h2,.bk-detail-head h2,.bk-settings-section>header h2,.bk-settings-form>header h2{margin:0;font:400 clamp(2.1rem,4vw,4.5rem)/.98 Georgia,serif;letter-spacing:-.04em}
24
+ .bk-actions{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap}.ak-btn.is-danger{color:#9a3028;border-color:#c89892}
25
+ .bk-section{margin-top:2.5rem}.bk-section>h3,.bk-note>h3,.bk-reschedule>h3,.bk-settings-section>h3{font:400 1.15rem Georgia,serif}
26
+ .bk-filter-head{display:flex;align-items:center;justify-content:space-between;gap:1rem}.bk-filter-head h3{font:400 1.15rem Georgia,serif}.bk-filters{display:flex;gap:.5rem;flex-wrap:wrap}.bk-filters input,.bk-filters select{min-height:38px;padding:.5rem;border:1px solid var(--ak-line,#ccc);background:var(--ak-paper,#fff);color:inherit}
27
+ .bk-table{border-top:1px solid var(--ak-line,#ddd)}.bk-table>button{display:grid;grid-template-columns:1.3fr 1fr 1fr auto;gap:1rem;align-items:center;width:100%;padding:1rem 0;border:0;border-bottom:1px solid var(--ak-line,#ddd);background:none;text-align:left;cursor:pointer}.bk-table>button:hover{background:rgba(0,0,0,.025)}.bk-table time,.bk-table span{color:var(--ak-muted,#777);font-size:.82rem}.bk-table em{font-style:normal}
28
+ .bk-status{display:inline-flex;align-items:center;width:max-content;padding:.35rem .55rem;border:1px solid currentColor;border-radius:99px;font-size:.7rem}.bk-status.is-pending{color:#9c671e}.bk-status.is-confirmed{color:#25734b}.bk-status.is-cancelled,.bk-status.is-rejected{color:#9b3b32}.bk-status.is-completed{color:#4e6070}
29
+ .bk-list{min-height:100%;display:flex;flex-direction:column}.bk-list-label{padding:1.2rem .9rem .5rem;text-transform:uppercase;letter-spacing:.1em;font-size:.62rem;color:var(--ak-muted,#777)}.bk-list-item{display:grid!important;grid-template-columns:8px 1fr!important;align-items:start!important}.bk-list-item>span:last-child{display:grid;gap:.2rem}.bk-list-item small{font-size:.68rem;color:var(--ak-muted,#777);font-weight:400}.bk-dot{width:7px;height:7px;margin-top:.35rem;border-radius:50%;background:#aaa}.bk-dot.is-pending{background:#d79532}.bk-dot.is-confirmed{background:#3a8c63}.bk-settings-link{margin-top:auto!important;border-top:1px solid var(--ak-line,#ddd)!important}.bk-settings-link span{font-size:.7rem;color:var(--ak-muted,#777)}
30
+ .bk-manual{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin:1.5rem 0;padding:1.5rem;border:1px solid var(--ak-line,#ddd);background:var(--ak-paper,#fff)}.bk-manual h3{grid-column:1/-1;margin:0;font:400 1.4rem Georgia,serif}.bk-manual label,.bk-settings-form label,.bk-type label,.bk-target{display:grid;gap:.4rem;font-size:.72rem;color:var(--ak-muted,#777)}.bk-manual input,.bk-manual select,.bk-manual textarea,.bk-settings-form input,.bk-type input,.bk-type select,.bk-type textarea,.bk-target select,.bk-note textarea,.bk-reschedule input{min-height:40px;padding:.65rem;border:1px solid var(--ak-line,#ccc);background:var(--ak-paper,#fff);color:inherit;font:inherit}.bk-manual textarea,.bk-type textarea,.bk-note textarea{resize:vertical}.bk-manual .is-wide{grid-column:1/-1}.bk-manual button{grid-column:1/-1;justify-self:start}
31
+ .bk-blocks{display:grid;border-top:1px solid var(--ak-line,#ddd)}.bk-blocks>div{display:flex;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--ak-line,#ddd);font-size:.8rem}.bk-blocks button{border:0;background:none;text-decoration:underline;cursor:pointer}
32
+ .bk-facts{display:grid;grid-template-columns:1fr 1fr;margin:0}.bk-facts>div{padding:1.2rem 0;border-bottom:1px solid var(--ak-line,#ddd)}.bk-facts>div:nth-child(odd){padding-right:1.5rem}.bk-facts>div:nth-child(even){padding-left:1.5rem;border-left:1px solid var(--ak-line,#ddd)}.bk-facts dt{text-transform:uppercase;letter-spacing:.09em;font-size:.64rem;color:var(--ak-muted,#777)}.bk-facts dd{margin:.45rem 0 0;line-height:1.5}.bk-note,.bk-reschedule{margin-top:2rem}.bk-note p{max-width:70ch;white-space:pre-wrap;line-height:1.6}.bk-note textarea{display:block;width:min(100%,760px);margin-bottom:.7rem}.bk-reschedule{display:flex;align-items:end;gap:.7rem}.bk-reschedule h3{width:100%;margin:0}.bk-detail-actions{margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid var(--ak-line,#ddd)}
33
+ .bk-tabs{display:flex;gap:0;overflow-x:auto;margin-bottom:3rem;border-bottom:1px solid var(--ak-line,#ddd)}.bk-tabs button{padding:.8rem 1rem;border:0;border-bottom:2px solid transparent;background:none;white-space:nowrap;cursor:pointer}.bk-tabs button.is-on{border-bottom-color:currentColor}
34
+ .bk-settings-form,.bk-settings-section{display:grid;grid-template-columns:1fr 1fr;gap:1.2rem}.bk-settings-form>header,.bk-settings-section>header,.bk-settings-section>p,.bk-settings-section>h3,.bk-settings-section>.bk-actions,.bk-settings-section>.ak-btn,.bk-types,.bk-week,.bk-overrides,.bk-google-list,.bk-checklist,.bk-target{grid-column:1/-1}.bk-settings-form>header,.bk-settings-section>header{margin-bottom:1.3rem}.bk-settings-form .is-wide{grid-column:1/-1}.bk-settings-form>button{grid-column:1/-1;justify-self:start}
35
+ .bk-types{display:grid;gap:1rem}.bk-type{display:grid;grid-template-columns:repeat(3,1fr);gap:.8rem;padding:1.2rem;border:1px solid var(--ak-line,#ddd)}.bk-type-name{grid-column:span 2;font:400 1.2rem Georgia,serif!important}.bk-type textarea{grid-column:1/-1}.bk-check{display:flex!important;align-items:center!important}.bk-check input{min-height:0}.bk-type .bk-actions{grid-column:1/-1}
36
+ .bk-week{display:grid;border-top:1px solid var(--ak-line,#ddd)}.bk-week>div{display:grid;grid-template-columns:150px 1fr;gap:1rem;padding:.8rem 0;border-bottom:1px solid var(--ak-line,#ddd)}.bk-week>div>div{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap}.bk-week span{display:flex;gap:.35rem;align-items:center}.bk-week input{padding:.4rem;border:1px solid var(--ak-line,#ccc)}.bk-week button,.bk-overrides button{border:0;background:none;text-decoration:underline;cursor:pointer}
37
+ .bk-overrides{display:grid;gap:.6rem}.bk-overrides>div{display:flex;gap:.5rem;flex-wrap:wrap}.bk-overrides input,.bk-overrides select{padding:.55rem;border:1px solid var(--ak-line,#ccc);background:var(--ak-paper,#fff)}
38
+ .bk-google-list{display:grid;border-top:1px solid var(--ak-line,#ddd)}.bk-google-list label{display:flex;gap:.7rem;padding:.8rem 0;border-bottom:1px solid var(--ak-line,#ddd)}.bk-target{max-width:520px}
39
+ .bk-checklist{display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--ak-line,#ddd)}.bk-checklist>div{display:flex;gap:.7rem;padding:.8rem;border-bottom:1px solid var(--ak-line,#ddd);color:#9b3b32}.bk-checklist>div.is-ready{color:#25734b}
40
+ @media(max-width:800px){.bk-table>button{grid-template-columns:1fr 1fr}.bk-manual,.bk-settings-form,.bk-settings-section,.bk-facts{grid-template-columns:1fr}.bk-manual>*{grid-column:auto!important}.bk-settings-form>*,.bk-settings-section>*{grid-column:1!important}.bk-type{grid-template-columns:1fr}.bk-type>*{grid-column:1!important}.bk-facts>div:nth-child(n){padding-left:0;padding-right:0;border-left:0}.bk-week>div{grid-template-columns:1fr}.bk-hero{display:grid}.bk-checklist{grid-template-columns:1fr}}
41
+ /* Sezioni senza elenco (richieste, anteprima): la modifica prende tutto lo spazio, invece di una
42
+ colonna vuota che sembrerebbe rotta. */
43
+ .app.is-two { grid-template-columns: var(--ak-rail-w) minmax(0, 1fr); }
44
+
45
+ /* ---- Prima colonna: dove sono ---------------------------------------------------------- */
46
+ .rail {
47
+ display: flex; flex-direction: column; gap: 20px;
48
+ padding: 16px 12px;
49
+ background: var(--ak-rail-bg); color: var(--ak-rail-ink);
50
+ }
51
+ .rail-brand { display: flex; flex-direction: column; gap: 3px; padding: 4px 10px 0; }
52
+ .rail-brand-name { font: 600 13px/1.3 var(--ak-font); color: var(--ak-rail-ink-on); }
53
+ .rail-brand-role {
54
+ font: 500 10px/1 var(--ak-font); text-transform: uppercase; letter-spacing: .12em; opacity: .6;
55
+ }
56
+ .rail-nav { display: flex; flex-direction: column; gap: 1px; }
57
+ .rail-group + .rail-group { margin-top: 14px; }
58
+ /* Stessa ricetta tipografica di `.col-title`/`.pg-group-title` (maiuscolo, tracciato), ma NON
59
+ lo stesso colore: quelle usano `--ak-ink-quiet`, pensato per una superficie chiara, e sul rail
60
+ scuro sarebbe quasi invisibile. */
61
+ .rail-group-title {
62
+ display: block; margin: 0 0 3px; padding: 0 10px;
63
+ font: 600 10px/1 var(--ak-font); text-transform: uppercase; letter-spacing: .1em;
64
+ color: var(--ak-rail-ink); opacity: .65;
65
+ }
66
+ .rail-item {
67
+ display: flex; align-items: center; gap: 9px; width: 100%;
68
+ border: 0; background: transparent; cursor: pointer; text-align: left; text-decoration: none;
69
+ padding: 8px 10px; border-radius: 6px;
70
+ font: 500 13px/1.2 var(--ak-font); color: inherit;
71
+ }
72
+ .rail-item:hover { background: var(--ak-rail-hover); color: var(--ak-rail-ink-on); }
73
+ .rail-item.is-on { background: var(--ak-rail-on); color: var(--ak-rail-ink-on); }
74
+ .rail-item .ico { flex: none; opacity: .85; }
75
+ .rail-item.is-on .ico { opacity: 1; }
76
+ /* Quante richieste sono ancora da gestire. È l'unico numero della prima colonna: se ce ne
77
+ fossero altri smetterebbe di essere una cosa che si nota. */
78
+ .rail-badge {
79
+ margin-left: auto; flex: none; min-width: 18px; padding: 0 5px; border-radius: 9px;
80
+ background: var(--ak-accent); color: var(--ak-accent-ink);
81
+ font: 600 10px/18px var(--ak-font); text-align: center; font-variant-numeric: tabular-nums;
82
+ }
83
+ .rail-foot { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--ak-rail-line); }
84
+ .rail-foot { display: flex; flex-direction: column; gap: 1px; }
85
+
86
+ /* ---- Seconda colonna: cosa c'è dentro -------------------------------------------------- */
87
+ .col {
88
+ display: flex; flex-direction: column; min-width: 0; min-height: 0;
89
+ background: var(--ak-col-bg); border-right: 1px solid var(--ak-line);
90
+ }
91
+ .col-head {
92
+ flex: none; display: flex; align-items: center; min-height: 57px; padding: 10px 12px;
93
+ border-bottom: 1px solid var(--ak-line);
94
+ }
95
+ .col-title {
96
+ font: 600 11px/1 var(--ak-font); text-transform: uppercase; letter-spacing: .09em;
97
+ color: var(--ak-ink-quiet);
98
+ }
99
+ .col-body { flex: 1; min-height: 0; overflow-y: auto; padding: 10px; }
100
+ .col-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
101
+ .col-item {
102
+ display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
103
+ border: 1px solid transparent; border-radius: 6px; background: transparent; cursor: pointer;
104
+ padding: 8px 10px; font: 500 13px/1.3 var(--ak-font); color: var(--ak-ink);
105
+ }
106
+ .col-item:hover { background: var(--ak-hover); }
107
+ .col-item.is-on {
108
+ background: var(--ak-panel); border-color: var(--ak-line); font-weight: 600;
109
+ box-shadow: var(--ak-shadow), inset 2px 0 0 var(--ak-accent);
110
+ }
111
+ .col-item .ico { flex: none; color: var(--ak-ink-quiet); }
112
+ .settings-list { gap: 5px; }
113
+ .settings-list-item {
114
+ align-items: flex-start; flex-direction: column; gap: 5px; min-height: 68px; padding: 11px 12px;
115
+ }
116
+ .settings-list-item strong { font: 600 13px/1.2 var(--ak-font); }
117
+ .settings-list-item span { font: 400 11px/1.45 var(--ak-font); color: var(--ak-ink-quiet); }
118
+
119
+ /* ---- Terza colonna: cosa sto facendo --------------------------------------------------- */
120
+ /* `min-height: 0` non è decorazione: un elemento di griglia ha `min-height: auto`, quindi senza
121
+ questa riga la colonna cresce con il suo contenuto oltre l'altezza della riga, `.app` la taglia
122
+ con `overflow: hidden` e la parte in fondo diventa IRRAGGIUNGIBILE — il corpo non scorre perché
123
+ non è lui a essere troppo alto. Si vede solo sulle pagine lunghe (una gallery con molte foto). */
124
+ .pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--ak-bg); }
125
+ .pane-head {
126
+ flex: none; display: flex; align-items: center; gap: 10px; min-height: 57px; padding: 10px 20px;
127
+ background: var(--ak-panel); border-bottom: 1px solid var(--ak-line);
128
+ }
129
+ .pane-title { margin: 0; font: 600 15px/1.2 var(--ak-font); }
130
+ .pane-slug { font: 400 12px/1 var(--ak-font-mono); color: var(--ak-ink-quiet); }
131
+ .pane-count { font: 400 13px/1 var(--ak-font); color: var(--ak-ink-quiet); font-variant-numeric: tabular-nums; }
132
+ /* Il percorso dei media: ogni pezzo è un posto in cui tornare. L'ultimo è dove sei, e ha il peso
133
+ del titolo — è lui a fare da titolo, non un'aggiunta al titolo. */
134
+ .pane-crumbs { display: flex; align-items: center; gap: 6px; min-width: 0; flex-wrap: wrap; }
135
+ .pane-crumb-part { display: inline-flex; align-items: center; gap: 6px; }
136
+ .pane-crumb {
137
+ border: 0; background: transparent; cursor: pointer; padding: 2px 0; border-radius: 4px;
138
+ font: 500 14px/1.2 var(--ak-font); color: var(--ak-ink-quiet);
139
+ }
140
+ .pane-crumb:hover { color: var(--ak-accent); }
141
+ .pane-crumb.is-current { font: 600 15px/1.2 var(--ak-font); color: var(--ak-ink); cursor: default; }
142
+ .pane-crumb.is-current:hover { color: var(--ak-ink); }
143
+ .pane-crumb-sep { color: var(--ak-line); font-size: 14px; }
144
+ .pane-open {
145
+ display: inline-flex; align-items: center; gap: 4px; text-decoration: none;
146
+ font: 500 12px/1 var(--ak-font); color: var(--ak-ink-quiet);
147
+ }
148
+ .pane-open:hover { color: var(--ak-accent); }
149
+ .pane-spacer { flex: 1; }
150
+ .pane-notice {
151
+ border: 0; background: transparent; cursor: pointer; text-align: right;
152
+ font: 400 var(--ak-fs-small)/1.4 var(--ak-font); color: var(--ak-ink-quiet);
153
+ }
154
+ .pane-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--ak-accent); }
155
+ .pane-body { flex: 1; min-height: 0; overflow-y: auto; padding: 22px 24px 64px; }
156
+ /* Una colonna di testo che non diventa mai troppo larga da leggere. Il browser dei media invece
157
+ vuole tutto lo spazio: là le miniature sono il contenuto. */
158
+ .pane-body > .ed, .pane-body > .rq-detail, .pane-body > .rg, .pane-body > .pane-empty { max-width: 820px; }
159
+ .pane-body.is-wide { padding: 14px 16px 40px; }
160
+ .pane-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; margin: 0; }
161
+
162
+ .app-legacy {
163
+ flex: none; padding: 9px 20px; background: #fff8e6; border-bottom: 1px solid var(--ak-line);
164
+ font: 400 var(--ak-fs-small)/1.5 var(--ak-font); color: var(--ak-ink-quiet);
165
+ }
166
+ .app-legacy-row { margin: 0; display: flex; align-items: center; gap: 12px; }
167
+ .app-legacy-row > span { flex: 1; }
168
+ .app-legacy-list { margin: 6px 0 0; opacity: .8; }
169
+
170
+ /* ---- Impostazioni globali --------------------------------------------------------------- */
171
+ .settings-editor {
172
+ width: min(1120px, 100%); margin: 0 auto; padding: 12px 18px 70px;
173
+ display: flex; flex-direction: column; gap: 44px;
174
+ }
175
+ .st-intro { padding: 18px 0 22px; border-bottom: 1px solid var(--ak-line); }
176
+ .st-intro > span {
177
+ display: block; margin-bottom: 7px; color: var(--ak-accent);
178
+ font: 600 10px/1 var(--ak-font); letter-spacing: .1em; text-transform: uppercase;
179
+ }
180
+ .st-intro h2 { margin: 0; font: 600 24px/1.2 var(--ak-font); }
181
+ .st-intro p {
182
+ max-width: 640px; margin: 9px 0 0; color: var(--ak-ink-quiet);
183
+ font: 400 13px/1.55 var(--ak-font);
184
+ }
185
+ .st-section { display: flex; flex-direction: column; }
186
+ .st-section > h2 {
187
+ margin: 0; padding: 0 0 13px; border-bottom: 1px solid var(--ak-line);
188
+ font: 600 15px/1.2 var(--ak-font);
189
+ }
190
+ .st-row {
191
+ display: grid; grid-template-columns: minmax(210px, 300px) minmax(280px, 620px);
192
+ gap: clamp(30px, 6vw, 90px); align-items: start;
193
+ padding: 27px 0; border-bottom: 1px solid var(--ak-line);
194
+ }
195
+ .st-copy h3 { margin: 0 0 8px; font: 600 14px/1.3 var(--ak-font); }
196
+ .st-copy p {
197
+ margin: 0; color: var(--ak-ink-quiet); font: 400 12px/1.55 var(--ak-font);
198
+ }
199
+ .st-control { position: relative; min-width: 0; }
200
+ .st-input {
201
+ width: 100%; min-height: 43px; padding: 10px 12px;
202
+ border: 1px solid var(--ak-line); border-radius: 5px;
203
+ background: var(--ak-panel); color: var(--ak-ink);
204
+ font: 400 13px/1.45 var(--ak-font);
205
+ }
206
+ .st-input:focus {
207
+ outline: 2px solid color-mix(in srgb,var(--ak-accent) 24%,transparent);
208
+ border-color: var(--ak-accent);
209
+ }
210
+ .st-textarea { resize: vertical; min-height: 82px; }
211
+ /* L'interruttore di una funzione non attiva: si vede, non si preme. `not-allowed` sul cursore
212
+ dice che è così di proposito — un elemento solo sbiadito si scambia per un caricamento. */
213
+ .st-toggle.is-locked { cursor: not-allowed; opacity: .62; }
214
+ .st-toggle.is-locked input { cursor: not-allowed; }
215
+ .st-extras-note { margin-top: 2px; }
216
+ /* Arrivando dal pulsante «Attiva» di una card bloccata: un velo d'accento che si spegne da
217
+ solo. Serve a dire «è questa» dopo lo scorrimento, senza lasciare una sezione evidenziata
218
+ per sempre a chi poi resta a lavorare sulle impostazioni. */
219
+ .st-section.is-focused { animation: st-focus 2.4s ease-out 1; border-radius: 10px; }
220
+ @keyframes st-focus {
221
+ 0%, 40% { background: color-mix(in srgb, var(--ak-accent) 9%, transparent); }
222
+ 100% { background: transparent; }
223
+ }
224
+ /* Il campo del tag contiene codice, e si vede che lo contiene: a spaziatura fissa gli a capo
225
+ e le virgolette si contano, e nessuno lo scambia per una frase da scrivere. */
226
+ .st-code {
227
+ font: 400 12px/1.6 var(--ak-font-mono); white-space: pre; overflow-wrap: normal;
228
+ overflow-x: auto; tab-size: 2;
229
+ }
230
+ .st-count {
231
+ display: block; margin-top: 6px; text-align: right; color: var(--ak-ink-faint);
232
+ font: 400 10px/1 var(--ak-font-mono);
233
+ }
234
+ .st-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 13px; }
235
+ .st-inline-help {
236
+ margin: -3px 0 0; color: var(--ak-ink-quiet); font: 400 11px/1.45 var(--ak-font);
237
+ }
238
+ .st-favicon { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
239
+ .st-favicon-preview {
240
+ width: 48px; height: 48px; display: grid; place-items: center; flex: none;
241
+ overflow: hidden; border: 1px solid var(--ak-line); border-radius: 8px;
242
+ background: var(--ak-panel); color: var(--ak-ink-quiet);
243
+ }
244
+ .st-favicon-preview img { width: 100%; height: 100%; display: block; object-fit: contain; }
245
+ .st-toggle { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; }
246
+ .st-toggle input { position: absolute; width: 1px; height: 1px; opacity: 0; }
247
+ .st-toggle-track {
248
+ width: 39px; height: 23px; padding: 3px; flex: none; border-radius: 20px;
249
+ background: var(--ak-line); transition: background-color .16s;
250
+ }
251
+ .st-toggle-track span {
252
+ display: block; width: 17px; height: 17px; border-radius: 50%;
253
+ background: var(--ak-panel); box-shadow: 0 1px 3px rgba(0,0,0,.22);
254
+ transition: transform .16s;
255
+ }
256
+ .st-toggle input:checked + .st-toggle-track { background: var(--ak-accent); }
257
+ .st-toggle input:checked + .st-toggle-track span { transform: translateX(16px); }
258
+ .st-toggle input:focus-visible + .st-toggle-track {
259
+ outline: 2px solid var(--ak-accent); outline-offset: 2px;
260
+ }
261
+ .st-toggle > span:last-child {
262
+ color: var(--ak-ink-quiet); font: 500 12px/1.3 var(--ak-font);
263
+ }
264
+ .st-sitemap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
265
+ .st-sitemap code {
266
+ flex: 1; min-width: 240px; padding: 12px; overflow: hidden; text-overflow: ellipsis;
267
+ border: 1px solid var(--ak-line); border-radius: 5px; background: var(--ak-panel);
268
+ color: var(--ak-ink-quiet); font: 400 11px/1.4 var(--ak-font-mono); white-space: nowrap;
269
+ }
270
+ .st-sitemap .ak-btn { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
271
+ .st-sitemap .ico { width: 14px; height: 14px; }
272
+
273
+ /* ---- Elenco delle pagine (seconda colonna) --------------------------------------------- */
274
+ .pg { display: flex; flex-direction: column; gap: 18px; }
275
+ .pg-group-title {
276
+ font: 600 11px/1 var(--ak-font); text-transform: uppercase; letter-spacing: .09em;
277
+ color: var(--ak-ink-quiet); margin: 0 0 6px; padding: 0 10px;
278
+ }
279
+ .pg-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
280
+ .pg-empty { margin: 0; padding: 2px 10px; font: 400 12px/1 var(--ak-font); color: var(--ak-ink-quiet); }
281
+ .pg-row {
282
+ position: relative; display: flex; align-items: center; gap: 2px;
283
+ border: 1px solid transparent; border-radius: 6px; background: transparent;
284
+ }
285
+ .pg-row:hover { background: var(--ak-hover); }
286
+ .pg-row.is-on {
287
+ background: var(--ak-panel); border-color: var(--ak-line);
288
+ box-shadow: var(--ak-shadow), inset 2px 0 0 var(--ak-accent);
289
+ }
290
+ .pg-row.is-on .pg-title { font-weight: 600; }
291
+ .pg-row.is-dragging { background: var(--ak-panel); box-shadow: 0 8px 22px rgba(0,0,0,.14); z-index: 2; }
292
+ /* Maniglia e ••• compaiono al passaggio: in una colonna stretta, otto maniglie sempre accese
293
+ sono rumore. Restano raggiungibili da tastiera — `:focus-visible` le riaccende. */
294
+ .pg-handle {
295
+ flex: none; display: flex; border: 0; background: transparent; cursor: grab;
296
+ color: var(--ak-ink-quiet); padding: 6px 0 6px 5px; opacity: 0;
297
+ }
298
+ .pg-row:hover .pg-handle, .pg-row.is-dragging .pg-handle, .pg-handle:focus-visible { opacity: .5; }
299
+ .pg-open {
300
+ flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px;
301
+ border: 0; background: transparent; cursor: pointer; text-align: left;
302
+ padding: 8px 2px; font: 500 13px/1.3 var(--ak-font); color: var(--ak-ink);
303
+ }
304
+ .pg-icon, .pg-off { flex: none; display: flex; }
305
+ .pg-icon { color: var(--ak-ink-quiet); }
306
+ .pg-off { color: var(--ak-danger); opacity: .7; }
307
+ .pg-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
308
+
309
+ /* ---- Azioni sulla riga: popover ancorato ------------------------------------------------ */
310
+ .pa { position: relative; flex: none; }
311
+ .pa-more {
312
+ display: flex; border: 0; background: transparent; cursor: pointer; border-radius: 4px;
313
+ color: var(--ak-ink-quiet); padding: 6px; opacity: 0;
314
+ }
315
+ .pg-row:hover .pa-more, .pg-row.is-on .pa-more, .pa-more:focus-visible { opacity: 1; }
316
+ .pa-more:hover { background: var(--ak-bg); color: var(--ak-ink); }
317
+ .pa-menu {
318
+ position: absolute; top: calc(100% + 2px); right: 0; z-index: 20;
319
+ min-width: 196px; padding: 4px;
320
+ display: flex; flex-direction: column; gap: 1px;
321
+ background: var(--ak-panel); border: 1px solid var(--ak-line); border-radius: 8px;
322
+ box-shadow: 0 12px 30px rgba(0,0,0,.16);
323
+ }
324
+ .pa-menu > button {
325
+ border: 0; background: transparent; cursor: pointer; text-align: left; border-radius: 5px;
326
+ padding: 7px 9px; font: 400 13px/1.2 var(--ak-font); color: var(--ak-ink);
327
+ }
328
+ .pa-menu > button:hover { background: var(--ak-bg); }
329
+ .pa-menu > button.pa-danger { color: var(--ak-danger); }
330
+ .pa-menu-form { min-width: 252px; padding: 10px; gap: 8px; }
331
+ .pa-row { display: flex; gap: 6px; }
332
+ .pa-new { display: flex; flex-direction: column; gap: 8px; width: 100%; }
333
+
334
+ .ed { display: flex; flex-direction: column; gap: 18px; }
335
+ /* Gallery e portfolio prendono tutta la larghezza: il contenuto sono superfici e miniature,
336
+ non una colonna di testo da tenere leggibile. */
337
+ .pane-body > .ed.ed-gallery, .pane-body > .ed.ed-portfolio { max-width: none; }
338
+
339
+ /* ---- Editor visuale delle gallery -------------------------------------------------------
340
+ La gallery è il contenuto della pagina: niente fieldset e campi tecnici fra chi la modifica
341
+ e le sue fotografie. I controlli comuni restano nella prima riga, accanto al salvataggio. */
342
+ .pe-head-main {
343
+ min-width: 0; display: flex; align-items: center; gap: 20px;
344
+ }
345
+ .pe-title {
346
+ min-width: 0; max-width: min(34vw, 420px); overflow: hidden; text-overflow: ellipsis;
347
+ border: 0; padding: 3px 2px; background: transparent; color: var(--ak-ink); cursor: pointer;
348
+ font: 600 17px/1.2 var(--ak-font); white-space: nowrap; text-align: left;
349
+ }
350
+ .pe-title:hover { color: var(--ak-accent); }
351
+ .pe-title:focus-visible,
352
+ .pe-seo-button:focus-visible,
353
+ .pe-status:focus-visible,
354
+ .pe-menu-toggle:has(input:focus-visible) {
355
+ outline: 2px solid var(--ak-accent); outline-offset: 3px; border-radius: 3px;
356
+ }
357
+ .pe-seo-button {
358
+ flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 29px;
359
+ padding: 0 9px; border: 1px solid var(--ak-line); border-radius: 4px;
360
+ background: transparent; color: var(--ak-ink-quiet); cursor: pointer;
361
+ font: 600 11px/1 var(--ak-font); letter-spacing: .03em;
362
+ }
363
+ .pe-seo-button:hover { border-color: var(--ak-ink-quiet); color: var(--ak-ink); }
364
+ .pe-seo-button.is-active {
365
+ border-color: var(--ak-accent); background: color-mix(in srgb,var(--ak-accent) 8%,var(--ak-panel));
366
+ color: var(--ak-accent);
367
+ }
368
+ .pe-seo-button .ico { width: 14px; height: 14px; }
369
+ .pe-visibility { position: relative; flex: none; }
370
+ .pe-status {
371
+ display: inline-flex; align-items: center; gap: 7px; border: 0; padding: 5px 2px;
372
+ background: transparent; cursor: pointer; color: var(--ak-ink-quiet);
373
+ font: 500 13px/1 var(--ak-font);
374
+ }
375
+ .pe-status.is-online { color: #168666; }
376
+ .pe-status.is-offline { color: var(--ak-danger); }
377
+ .pe-status-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
378
+ .pe-chevron { margin-left: 1px; color: var(--ak-ink-quiet); transform: translateY(-1px); }
379
+ .pe-status-menu {
380
+ position: absolute; z-index: 40; top: calc(100% + 13px); right: -18px;
381
+ width: 330px; overflow: hidden; border: 1px solid var(--ak-line); border-radius: 8px;
382
+ background: var(--ak-panel); box-shadow: 0 18px 46px rgba(0,0,0,.18);
383
+ }
384
+ .pe-status-label {
385
+ display: block; padding: 17px 20px 13px; color: var(--ak-ink-quiet);
386
+ font: 600 10px/1 var(--ak-font); letter-spacing: .12em; text-transform: uppercase;
387
+ }
388
+ .pe-status-menu button {
389
+ width: 100%; min-height: 94px; display: grid; grid-template-columns: 24px minmax(0,1fr);
390
+ gap: 12px; align-items: start; padding: 18px 20px; border: 0; border-top: 1px solid var(--ak-line);
391
+ background: var(--ak-panel); color: var(--ak-ink); cursor: pointer; text-align: left;
392
+ }
393
+ .pe-status-menu button:hover { background: var(--ak-bg); }
394
+ .pe-status-menu button.is-selected {
395
+ background: color-mix(in srgb, #20b987 10%, var(--ak-panel));
396
+ box-shadow: inset 3px 0 0 #20b987;
397
+ }
398
+ .pe-status-menu button:last-child.is-selected {
399
+ background: color-mix(in srgb, var(--ak-danger) 7%, var(--ak-panel));
400
+ box-shadow: inset 3px 0 0 var(--ak-danger);
401
+ }
402
+ .pe-status-menu button > span:last-child { display: flex; flex-direction: column; gap: 7px; }
403
+ .pe-status-menu strong { font: 600 14px/1.2 var(--ak-font); }
404
+ .pe-status-menu small { color: var(--ak-ink-quiet); font: 400 12px/1.45 var(--ak-font); }
405
+ .pe-radio {
406
+ width: 17px; height: 17px; display: grid; place-items: center; border-radius: 50%;
407
+ border: 1px solid #c9c9c7; background: var(--ak-panel);
408
+ }
409
+ .is-selected .pe-radio span { width: 9px; height: 9px; border-radius: 50%; background: #20b987; }
410
+ .pe-status-menu button:last-child.is-selected .pe-radio span { background: var(--ak-danger); }
411
+ .pe-menu-toggle {
412
+ flex: none; display: inline-flex; align-items: center; gap: 8px; padding: 4px 2px;
413
+ color: var(--ak-ink); cursor: pointer; font: 500 12px/1 var(--ak-font);
414
+ }
415
+ .pe-menu-toggle input { width: 15px; height: 15px; margin: 0; }
416
+
417
+ .pe-modal {
418
+ position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 24px;
419
+ background: rgba(23,24,26,.42);
420
+ }
421
+ .pe-modal-card {
422
+ width: min(560px, 100%); overflow: hidden; border: 1px solid var(--ak-line); border-radius: 9px;
423
+ background: var(--ak-panel); box-shadow: 0 24px 70px rgba(0,0,0,.22);
424
+ }
425
+ .pe-modal-card header {
426
+ min-height: 70px; display: flex; align-items: center; padding: 0 24px;
427
+ border-bottom: 1px solid var(--ak-line);
428
+ }
429
+ .pe-modal-card h2 { margin: 0; font: 600 16px/1.2 var(--ak-font); }
430
+ .pe-modal-card header button {
431
+ margin-left: auto; border: 0; background: transparent; color: var(--ak-ink-quiet);
432
+ cursor: pointer; font: 300 24px/1 var(--ak-font);
433
+ }
434
+ .pe-modal-fields { display: grid; gap: 20px; padding: 24px; }
435
+ .pe-modal-fields label { display: grid; gap: 7px; color: var(--ak-ink); font: 500 13px/1.3 var(--ak-font); }
436
+ .pe-modal-fields input {
437
+ width: 100%; height: 43px; padding: 9px 11px; border: 1px solid var(--ak-line);
438
+ border-radius: 5px; background: var(--ak-panel); color: var(--ak-ink); font: 400 14px/1 var(--ak-font);
439
+ }
440
+ .pe-modal-fields input:focus { outline: 2px solid var(--ak-accent); outline-offset: 1px; }
441
+ .pe-modal-fields small { color: var(--ak-ink-quiet); font: 400 11px/1.4 var(--ak-font); }
442
+ .pe-url-input {
443
+ display: grid; grid-template-columns: auto minmax(0,1fr) auto; align-items: center;
444
+ border: 1px solid var(--ak-line); border-radius: 5px; padding: 0 11px; color: var(--ak-ink-quiet);
445
+ }
446
+ .pe-url-input:focus-within { outline: 2px solid var(--ak-accent); outline-offset: 1px; }
447
+ .pe-url-input input { height: 41px; padding-inline: 2px; border: 0; outline: 0 !important; }
448
+ .pe-modal-card footer {
449
+ display: flex; justify-content: flex-end; gap: 8px; padding: 16px 24px;
450
+ border-top: 1px solid var(--ak-line); background: var(--ak-bg);
451
+ }
452
+
453
+ .ed-gallery { width: 100%; }
454
+
455
+ /* Sezioni introduttive: blocchi progettati sopra la gallery.
456
+ Stesso linguaggio dell'editor dei lavori (`.pw-*`) e stessi valori, presi da `theme.css`:
457
+ niente tratti, superfici separate da tinta e ombra, campi riempiti. Erano card contornate su
458
+ fondo quasi bianco — la stessa mancanza di contrasto già corretta nel portfolio.
459
+
460
+ Cosa NON c'è più, e non è una dimenticanza: le barre blu di inserimento durante il
461
+ trascinamento. Erano un tratto di 3px in un blu (#1677ff) che non appartiene alla palette di
462
+ questo pannello, e soprattutto erano ridondanti — con `verticalListSortingStrategy` dnd-kit
463
+ allontana già gli elementi per mostrare dove cadrà quello trascinato, che è il modo in cui lo
464
+ raccontano le interfacce a cui punta il redesign. Vedi routes/GallerySectionsEditor.tsx. */
465
+ .gs-editor {
466
+ width: min(1080px, 100%); margin: 0 auto;
467
+ display: flex; flex-direction: column; align-items: stretch; gap: 14px;
468
+ padding: 4px 0 26px;
469
+ }
470
+ .gs-add-wrap { position: relative; align-self: center; z-index: 8; }
471
+ /* Pieno d'accento, non contornato: è l'unica azione primaria della zona. */
472
+ .gs-add {
473
+ min-height: 38px; display: inline-flex; align-items: center; justify-content: center; gap: 9px;
474
+ padding: 0 17px; border: 0; border-radius: 10px;
475
+ background: var(--ak-accent); color: #fff; cursor: pointer;
476
+ font: 600 12px/1 var(--ak-font); box-shadow: var(--ak-lift-2);
477
+ transition: background-color .15s;
478
+ }
479
+ .gs-add:hover { background: var(--ak-accent-hover); }
480
+ .gs-add:focus-visible { outline: 0; box-shadow: var(--ak-ring); }
481
+ .gs-add-menu {
482
+ position: absolute; z-index: 20; top: calc(100% + 8px); left: 50%; width: 300px;
483
+ padding: 6px; transform: translateX(-50%); border: 0;
484
+ border-radius: 12px; background: var(--ak-panel); box-shadow: var(--ak-lift-3);
485
+ }
486
+ .gs-add-menu button {
487
+ width: 100%; display: grid; grid-template-columns: 32px minmax(0,1fr); gap: 10px;
488
+ align-items: center; padding: 10px; border: 0; border-radius: 9px;
489
+ background: transparent; color: var(--ak-ink); cursor: pointer; text-align: left;
490
+ }
491
+ .gs-add-menu button:hover { background: var(--ak-inset); }
492
+ .gs-add-menu button > span:first-child {
493
+ width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px;
494
+ background: var(--ak-inset); color: var(--ak-ink-quiet);
495
+ }
496
+ .gs-add-menu button > span:last-child { display: flex; flex-direction: column; gap: 3px; }
497
+ .gs-add-menu strong { font: 600 12px/1.2 var(--ak-font); }
498
+ .gs-add-menu small { color: var(--ak-ink-quiet); font: 400 10px/1.3 var(--ak-font); }
499
+
500
+ .gs-list { display: flex; flex-direction: column; gap: 8px; }
501
+ .gs-card {
502
+ position: relative; overflow: visible; border: 0; border-radius: 14px;
503
+ background: var(--ak-panel); box-shadow: var(--ak-lift-1);
504
+ transition: box-shadow .18s ease;
505
+ }
506
+ .gs-card:hover { box-shadow: var(--ak-lift-2); }
507
+ /* Sollevata e semitrasparente mentre la si trascina: staccata dal foglio. Dove cadrà lo
508
+ mostrano gli altri che si spostano. */
509
+ .gs-card.is-dragging { z-index: 4; opacity: .9; box-shadow: var(--ak-lift-3); }
510
+
511
+ /* L'intestazione non è separata da niente: né riga né tinta. A distinguerla bastano lo spazio e
512
+ la micro-etichetta maiuscola (IMMAGINE, HEADER, TESTO), che è già un cambio di registro
513
+ tipografico — aggiungerci anche un fondo diverso sarebbe dire due volte la stessa cosa. */
514
+ .gs-card-head {
515
+ min-height: 46px; display: flex; align-items: center; gap: 8px; padding: 7px 12px 7px 7px;
516
+ }
517
+ .gs-drag {
518
+ display: grid; place-items: center; width: 26px; height: 32px; padding: 0; border: 0;
519
+ border-radius: 8px; background: transparent; color: var(--ak-ink-quiet); cursor: grab;
520
+ touch-action: none; opacity: 0; transition: opacity .15s, background-color .15s;
521
+ }
522
+ .gs-drag:active { cursor: grabbing; }
523
+ .gs-card:hover .gs-drag, .gs-card.is-dragging .gs-drag, .gs-drag:focus-visible { opacity: .55; }
524
+ .gs-drag:hover { background: var(--ak-inset); opacity: 1 !important; }
525
+ .gs-card-icon { display: flex; color: var(--ak-ink-quiet); }
526
+ .gs-card-head strong {
527
+ color: var(--ak-ink-quiet); font: 600 10px/1 var(--ak-font);
528
+ text-transform: uppercase; letter-spacing: .09em;
529
+ }
530
+ .gs-position { min-width: 18px; color: var(--ak-ink-faint, var(--ak-ink-quiet)); font: 400 10px/1 var(--ak-font-mono); }
531
+ /* Duplica ed Elimina compaiono al passaggio: sono azioni distruttive o moltiplicative, non
532
+ devono stare sotto il dito mentre si scorre. */
533
+ .gs-head-action {
534
+ margin-left: auto; padding: 6px 9px; border: 0; border-radius: 8px; background: transparent;
535
+ color: var(--ak-ink-quiet); cursor: pointer; font: 500 11px/1 var(--ak-font);
536
+ opacity: 0; transition: opacity .15s, background-color .15s, color .15s;
537
+ }
538
+ .gs-head-action + .gs-head-action { margin-left: 4px; }
539
+ .gs-card:hover .gs-head-action, .gs-card:focus-within .gs-head-action { opacity: 1; }
540
+ .gs-head-action:hover { background: var(--ak-inset); color: var(--ak-ink); }
541
+ .gs-head-action.is-danger { color: var(--ak-danger); }
542
+ .gs-head-action.is-danger:hover { background: color-mix(in srgb, var(--ak-danger) 9%, transparent); }
543
+
544
+ /* La griglia delle foto dentro il suo blocco. L'editor arriva già impaginato (`.pe-gallery`,
545
+ che vive fuori di qui): serve solo il contenimento, cioè togliergli i margini che aveva da
546
+ pannello a sé stante e dargli il respiro interno della card. */
547
+ .gs-gallery { padding: 0 14px 14px; }
548
+ .gs-gallery .pe-gallery { gap: 16px; }
549
+ .gs-gallery .pe-gallery-bar { padding-bottom: 0; }
550
+ /* Il fondo qui è bianco (la card), non il foglio tinto: la griglia non deve sembrare incollata
551
+ sul bordo. */
552
+ .gs-gallery .pe-photo-grid { padding-bottom: 4px; }
553
+ .gs-fields { display: grid; gap: 14px; padding: 2px 14px 16px; }
554
+ .gs-fields label,
555
+ .gs-image-fields label { display: flex; flex-direction: column; gap: 6px; }
556
+ .gs-fields label > span,
557
+ .gs-image-fields label > span,
558
+ .gs-layout > span { color: var(--ak-ink); font: 500 11px/1.3 var(--ak-font); }
559
+ .gs-fields label > span small,
560
+ .gs-image-fields label > span small { color: var(--ak-ink-quiet); font-weight: 400; }
561
+ /* Campi RIEMPITI: il contrasto col fondo dice già dove si scrive, e l'anello di focus fa il
562
+ lavoro che faceva il bordo. */
563
+ /* `.ak-prose-field` accanto a `textarea`: il campo di prosa non è più una textarea ma un
564
+ contenteditable (vedi adminkit form/prose/ProseField.tsx), e senza questo perderebbe il suo
565
+ riquadro — resterebbe testo appoggiato sul fondo della card. */
566
+ .gs-fields input,
567
+ .gs-fields textarea,
568
+ .gs-fields .ak-prose-field,
569
+ .gs-image-fields input {
570
+ width: 100%; padding: 10px 12px; border: 0; border-radius: 9px;
571
+ background: var(--ak-inset); color: var(--ak-ink); font: 400 13px/1.5 var(--ak-font);
572
+ transition: background-color .15s, box-shadow .15s;
573
+ }
574
+ .gs-fields textarea, .gs-fields .ak-prose-field { min-height: 96px; }
575
+ .gs-fields textarea { resize: vertical; }
576
+ .gs-fields input:hover, .gs-fields textarea:hover, .gs-fields .ak-prose-field:hover,
577
+ .gs-image-fields input:hover {
578
+ background: var(--ak-inset-deep);
579
+ }
580
+ .gs-fields input:focus,
581
+ .gs-fields textarea:focus,
582
+ .gs-fields .ak-prose-field:focus,
583
+ .gs-image-fields input:focus {
584
+ outline: 0; background: var(--ak-panel); box-shadow: var(--ak-ring);
585
+ }
586
+ .gs-fields label > small { color: var(--ak-ink-quiet); font: 400 10px/1.45 var(--ak-font); }
587
+ .gs-card.is-header .gs-fields label:nth-child(2) input {
588
+ padding-block: 13px; font-size: 18px; font-weight: 600; letter-spacing: -.01em;
589
+ }
590
+ .gs-image-editor {
591
+ display: grid; grid-template-columns: minmax(220px, .85fr) minmax(280px, 1.15fr);
592
+ gap: 18px; padding: 2px 14px 16px;
593
+ }
594
+ /* Il segnaposto è una superficie incassata, non un rettangolo tratteggiato: invita a premere
595
+ invece di sembrare un contenitore rotto. */
596
+ .gs-image-preview {
597
+ position: relative; min-height: 210px; display: grid; place-items: center; overflow: hidden;
598
+ padding: 0; border: 0; border-radius: 11px;
599
+ background: var(--ak-inset-deep); color: var(--ak-ink-quiet); cursor: pointer;
600
+ }
601
+ .gs-image-preview:hover { color: var(--ak-accent); }
602
+ .gs-image-preview img { width: 100%; height: 100%; max-height: 320px; display: block; object-fit: contain; }
603
+ .gs-image-preview > span { display: inline-flex; align-items: center; gap: 8px; font: 500 11px/1 var(--ak-font); }
604
+ .gs-image-fields { display: flex; flex-direction: column; gap: 13px; }
605
+ .gs-image-actions { display: flex; gap: 6px; flex-wrap: wrap; }
606
+ /* Larga/Contenuta è UNA scelta fra due, non due pulsanti: la vaschetta incassata e l'unica
607
+ opzione sollevata lo dicono senza contorni. */
608
+ .gs-layout { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
609
+
610
+ .pe-gallery { width: 100%; display: flex; flex-direction: column; gap: 26px; }
611
+ .pe-gallery-bar {
612
+ display: flex; align-items: center; justify-content: space-between; gap: 18px;
613
+ min-height: 48px; padding: 0 2px 18px; border-bottom: 1px solid var(--ak-line);
614
+ }
615
+ .pe-gallery-bar > div { display: flex; flex-direction: column; gap: 4px; }
616
+ .pe-gallery-bar strong { font: 600 13px/1.2 var(--ak-font); }
617
+ .pe-gallery-bar span { color: var(--ak-ink-quiet); font: 400 11px/1.3 var(--ak-font); }
618
+ /* Stessa forma di `.gs-add`: sono due azioni primarie sulla STESSA schermata (aggiungi una
619
+ sezione, aggiungi delle foto) e vederle una contornata e una piena le fa sembrare di peso
620
+ diverso, che non è. La griglia delle foto per il resto non è stata ridisegnata. */
621
+ .pe-add {
622
+ flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
623
+ min-height: 38px; padding: 0 17px; border: 0; border-radius: 10px;
624
+ background: var(--ak-accent); color: #fff; cursor: pointer;
625
+ font: 600 12px/1 var(--ak-font); box-shadow: var(--ak-lift-2);
626
+ transition: background-color .15s;
627
+ }
628
+ .pe-add:hover { background: var(--ak-accent-hover); }
629
+ .pe-add:focus-visible { outline: 0; box-shadow: var(--ak-ring); }
630
+ .pe-gallery-empty {
631
+ min-height: 300px; display: grid; place-content: center; justify-items: center; gap: 8px;
632
+ border: 1px dashed var(--ak-line); border-radius: 8px; background: var(--ak-panel);
633
+ color: var(--ak-ink-quiet); cursor: pointer;
634
+ }
635
+ .pe-gallery-empty .ico { width: 24px; height: 24px; margin-bottom: 4px; }
636
+ .pe-gallery-empty strong { color: var(--ak-ink); font: 600 14px/1.2 var(--ak-font); }
637
+ .pe-gallery-empty span { font: 400 12px/1.2 var(--ak-font); }
638
+ .pe-gallery-empty:hover { border-color: var(--ak-accent); color: var(--ak-accent); }
639
+
640
+ .pe-photo-grid {
641
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
642
+ gap: 28px 24px; align-items: start; padding: 4px 2px 40px;
643
+ }
644
+ .pe-photo {
645
+ position: relative; min-width: 0; margin: 0; padding-top: 18px;
646
+ display: flex; flex-direction: column; align-items: stretch; gap: 8px;
647
+ }
648
+ .pe-photo-frame {
649
+ position: relative; height: clamp(155px, 16vw, 230px); display: flex; align-items: center; justify-content: center;
650
+ cursor: grab; touch-action: none;
651
+ }
652
+ .pe-photo-frame:active { cursor: grabbing; }
653
+ .pe-photo-frame img {
654
+ max-width: 100%; max-height: 100%; width: auto; height: auto; display: block;
655
+ background: var(--ak-line); box-shadow: 0 1px 4px rgba(0,0,0,.15);
656
+ transition: opacity .15s, filter .15s;
657
+ }
658
+ .pe-photo figcaption {
659
+ overflow: hidden; padding-inline: 2px; color: #8a8a91; text-align: center;
660
+ font: 400 11px/1.3 var(--ak-font); text-overflow: ellipsis; white-space: nowrap;
661
+ }
662
+ .pe-photo-actions {
663
+ position: absolute; z-index: 3; top: 0; left: 50%; transform: translate(-50%, -18%);
664
+ display: flex; align-items: center; padding: 5px; border: 1px solid var(--ak-line);
665
+ border-radius: 5px; background: var(--ak-panel); box-shadow: 0 8px 24px rgba(0,0,0,.14);
666
+ opacity: 0; pointer-events: none; transition: opacity .12s, transform .12s;
667
+ }
668
+ .pe-photo:hover .pe-photo-actions,
669
+ .pe-photo:focus-within .pe-photo-actions {
670
+ opacity: 1; pointer-events: auto; transform: translate(-50%, -28%);
671
+ }
672
+ .pe-photo-actions button {
673
+ width: 34px; height: 32px; display: grid; place-items: center; border: 0; border-radius: 3px;
674
+ background: transparent; color: var(--ak-ink); cursor: pointer;
675
+ }
676
+ .pe-photo-actions button:hover { background: var(--ak-bg); }
677
+ .pe-photo-actions button.is-danger { color: var(--ak-danger); }
678
+ .pe-photo-actions .ico { width: 17px; height: 17px; }
679
+ .pe-photo.is-hidden .pe-photo-frame img { opacity: .25; filter: grayscale(1); }
680
+ .pe-hidden-label {
681
+ position: absolute; inset: auto 7px 7px; padding: 4px 7px; border-radius: 3px;
682
+ background: rgba(25,25,25,.78); color: #fff; font: 600 9px/1 var(--ak-font);
683
+ letter-spacing: .05em; text-transform: uppercase;
684
+ }
685
+ .pe-photo.is-dragging { opacity: .22; }
686
+ .pe-photo.is-insert-before::before,
687
+ .pe-photo.is-insert-after::after {
688
+ content: ""; position: absolute; z-index: 4; top: 17px; bottom: 29px; width: 3px;
689
+ border-radius: 3px; background: #1677ff; box-shadow: 0 0 0 1px rgba(22,119,255,.12);
690
+ }
691
+ .pe-photo.is-insert-before::before { left: -13px; }
692
+ .pe-photo.is-insert-after::after { right: -13px; }
693
+ .pe-photo-overlay {
694
+ width: 180px; height: 230px; display: flex; align-items: center; justify-content: center;
695
+ padding: 5px; background: rgba(255,255,255,.96); box-shadow: 0 16px 38px rgba(0,0,0,.2);
696
+ cursor: grabbing;
697
+ }
698
+ .pe-photo-overlay img { max-width: 100%; max-height: 100%; display: block; }
699
+ .pe-load-error {
700
+ margin: 0; padding: 9px 12px; border: 1px solid color-mix(in srgb,var(--ak-danger) 30%,var(--ak-line));
701
+ border-radius: 5px; color: var(--ak-danger); background: var(--ak-panel);
702
+ font: 500 11px/1.4 var(--ak-font);
703
+ }
704
+
705
+ /* ---- SEO della pagina ------------------------------------------------------------------
706
+ Tre colonne come nella reference: nome della proprietà, superficie operativa, spiegazione.
707
+ La colonna centrale resta quella dominante; gli aiuti accompagnano senza trasformarsi in
708
+ un'altra scheda da aprire. */
709
+ .seo-editor {
710
+ width: 100%; margin: 0; padding: 6px 18px 64px;
711
+ display: flex; flex-direction: column; gap: 26px;
712
+ }
713
+ .seo-intro {
714
+ display: flex; align-items: flex-start; justify-content: space-between; gap: 24px;
715
+ padding: 10px 0 21px; border-bottom: 1px solid var(--ak-line);
716
+ }
717
+ .seo-kicker {
718
+ display: block; margin-bottom: 8px; color: var(--ak-ink-quiet);
719
+ font: 600 10px/1 var(--ak-font); letter-spacing: .12em; text-transform: uppercase;
720
+ }
721
+ .seo-intro h2 { margin: 0; font: 600 23px/1.15 var(--ak-font); letter-spacing: -.02em; }
722
+ .seo-intro p { margin: 8px 0 0; color: var(--ak-ink-quiet); font: 400 12px/1.5 var(--ak-font); }
723
+ .seo-complete {
724
+ flex: none; display: inline-flex; align-items: center; gap: 8px; margin-top: 7px;
725
+ color: #a26a18; font: 600 12px/1 var(--ak-font);
726
+ }
727
+ .seo-complete > span {
728
+ width: 19px; height: 19px; display: grid; place-items: center; border: 1px solid currentColor;
729
+ border-radius: 50%; font: 700 11px/1 var(--ak-font);
730
+ }
731
+ .seo-complete.is-complete { color: #129c76; }
732
+ .seo-section {
733
+ display: flex; flex-direction: column; border-top: 1px solid var(--ak-line);
734
+ }
735
+ .seo-section-heading,
736
+ .seo-row {
737
+ display: grid;
738
+ grid-template-columns: clamp(110px, 10vw, 150px) minmax(440px, 720px) minmax(220px, 1fr);
739
+ gap: 22px; align-items: start;
740
+ }
741
+ .seo-section-heading { padding: 20px 0 17px; }
742
+ .seo-section-heading > span {
743
+ color: var(--ak-ink); font: 600 13px/1.3 var(--ak-font);
744
+ }
745
+ .seo-section-heading > div { grid-column: 2; }
746
+ .seo-section-heading h3 { margin: 0; font: 600 16px/1.2 var(--ak-font); }
747
+ .seo-section-heading p { margin: 5px 0 0; color: var(--ak-ink-quiet); font: 400 11px/1.4 var(--ak-font); }
748
+ .seo-row {
749
+ padding: 19px 0; border-top: 1px solid color-mix(in srgb,var(--ak-line) 72%,transparent);
750
+ }
751
+ .seo-row-label { padding-top: 4px; color: var(--ak-ink); font: 500 12px/1.3 var(--ak-font); }
752
+ .seo-row > .seo-field { grid-column: 2; }
753
+ .seo-row > .seo-help { grid-column: 3; }
754
+ .seo-help {
755
+ margin: 0; padding-top: 29px; color: #92929a; font: 400 11px/1.5 var(--ak-font);
756
+ }
757
+ .seo-preview-row .seo-help { padding-top: 4px; }
758
+ .seo-field { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
759
+ .seo-field > span:first-child { color: var(--ak-ink); font: 500 13px/1.3 var(--ak-font); }
760
+ .seo-field input,
761
+ .seo-field textarea {
762
+ width: 100%; border: 1px solid var(--ak-line); border-radius: 4px;
763
+ background: var(--ak-panel); color: var(--ak-ink); padding: 11px 12px;
764
+ font: 400 13px/1.45 var(--ak-font);
765
+ }
766
+ .seo-field textarea { resize: vertical; min-height: 105px; }
767
+ .seo-field input:focus,
768
+ .seo-field textarea:focus {
769
+ outline: 2px solid color-mix(in srgb,var(--ak-accent) 28%,transparent);
770
+ outline-offset: 1px; border-color: var(--ak-accent);
771
+ }
772
+ .seo-count {
773
+ align-self: flex-end; color: var(--ak-ink-quiet); font: 400 10px/1 var(--ak-font);
774
+ font-variant-numeric: tabular-nums;
775
+ }
776
+ .seo-count.is-long { color: #a26a18; }
777
+
778
+ .seo-search-preview {
779
+ min-height: 166px; display: flex; flex-direction: column; padding: 19px 21px;
780
+ border: 1px solid #ececec; border-radius: 7px; background: #fff;
781
+ box-shadow: 0 5px 18px rgba(0,0,0,.09); font-family: Arial, sans-serif;
782
+ }
783
+ .seo-search-site { color: #3c4043; font-size: 11px; line-height: 1.3; }
784
+ .seo-search-url {
785
+ margin-top: 2px; overflow: hidden; color: #202124; font-size: 10px; line-height: 1.3;
786
+ text-overflow: ellipsis; white-space: nowrap;
787
+ }
788
+ .seo-search-preview strong {
789
+ display: -webkit-box; margin-top: 7px; overflow: hidden; color: #1a0dab;
790
+ font-size: 18px; font-weight: 400; line-height: 1.2; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
791
+ }
792
+ .seo-search-preview p {
793
+ display: -webkit-box; margin: 6px 0 0; overflow: hidden; color: #4d5156;
794
+ font-size: 12px; line-height: 1.45; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
795
+ }
796
+
797
+ .seo-og-preview {
798
+ overflow: hidden; border: 1px solid #d9d9dc; border-radius: 7px; background: #f4f4f5;
799
+ box-shadow: 0 4px 15px rgba(0,0,0,.07);
800
+ }
801
+ .seo-og-image {
802
+ aspect-ratio: 1.91 / 1; display: grid; place-items: center; overflow: hidden;
803
+ background: #e8e8e8; color: var(--ak-ink-quiet);
804
+ }
805
+ .seo-og-image img { width: 100%; height: 100%; display: block; object-fit: cover; }
806
+ .seo-og-image > span { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; }
807
+ .seo-og-copy { display: flex; flex-direction: column; gap: 5px; padding: 12px 14px 14px; }
808
+ .seo-og-copy > span {
809
+ color: #65656d; font: 500 9px/1 var(--ak-font); letter-spacing: .04em;
810
+ }
811
+ .seo-og-copy strong {
812
+ overflow: hidden; color: #171719; font: 600 14px/1.25 var(--ak-font);
813
+ text-overflow: ellipsis; white-space: nowrap;
814
+ }
815
+ .seo-og-copy p {
816
+ display: -webkit-box; margin: 0; overflow: hidden; color: #65656d;
817
+ font: 400 11px/1.35 var(--ak-font); -webkit-line-clamp: 2; -webkit-box-orient: vertical;
818
+ }
819
+ .seo-image-picker { display: flex; align-items: flex-start; gap: 14px; }
820
+ .seo-image-picker > img,
821
+ .seo-image-picker > div:first-child {
822
+ flex: none; width: 150px; aspect-ratio: 1.91/1; display: grid; place-items: center;
823
+ object-fit: cover; border: 1px solid var(--ak-line); border-radius: 4px; background: var(--ak-bg);
824
+ color: var(--ak-ink-quiet);
825
+ }
826
+ .seo-image-picker > div:last-child { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 7px; }
827
+ .seo-image-picker small {
828
+ flex-basis: 100%; color: var(--ak-ink-quiet); font: 400 10px/1.4 var(--ak-font);
829
+ }
830
+
831
+ /* ---- Richieste dal form di contatto -----------------------------------------------------
832
+ Elenco a sinistra, messaggio a destra. Nell'elenco basta chi ha scritto, quando e le prime
833
+ parole — è così che si ritrova quella di tre settimane fa; nel messaggio invece niente
834
+ troncamenti. Le gestite restano, smorzate: sparire sarebbe perdere il filo di cosa è arrivato. */
835
+ .rq-bulk { display: flex; align-items: center; gap: 10px; width: 100%; }
836
+
837
+ .rq-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
838
+ .rq-row {
839
+ display: flex; align-items: flex-start; gap: 6px; padding: 2px 4px 2px 0;
840
+ border: 1px solid transparent; border-radius: 6px; background: transparent;
841
+ }
842
+ .rq-row:hover { background: var(--ak-hover); }
843
+ .rq-row.is-on {
844
+ background: var(--ak-panel); border-color: var(--ak-line);
845
+ box-shadow: var(--ak-shadow), inset 2px 0 0 var(--ak-accent);
846
+ }
847
+ /* Smorzata, non sparita: `opacity` sul contenuto e non sulla riga, così la casella per sceglierla
848
+ resta leggibile anche su una richiesta già chiusa. */
849
+ .rq-row.is-handled .rq-open { opacity: .55; }
850
+ .rq-pick { margin: 12px 0 0 8px; width: 14px; height: 14px; flex: none; }
851
+ /* Nome, data e anteprima incolonnati, come nella reference: un nome lungo — e i nomi veri lo
852
+ sono — non deve dividersi lo spazio con la data. Il pallino sta a destra, dove si guarda per
853
+ sapere se c'è qualcosa di nuovo, non attaccato al nome. */
854
+ .rq-open {
855
+ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px;
856
+ border: 0; background: transparent; cursor: pointer; text-align: left; padding: 9px 10px 10px 2px;
857
+ }
858
+ .rq-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
859
+ .rq-who {
860
+ flex: 1; min-width: 0; font: 600 13px/1.35 var(--ak-font); color: var(--ak-ink);
861
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
862
+ }
863
+ .rq-new { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--ak-accent); }
864
+ .rq-when { font: 400 11px/1.3 var(--ak-font-mono); color: var(--ak-ink-quiet); white-space: nowrap; }
865
+ .rq-snip {
866
+ font: 400 12px/1.4 var(--ak-font); color: var(--ak-ink-quiet);
867
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
868
+ }
869
+
870
+ .rq-detail {
871
+ display: flex; flex-direction: column;
872
+ background: var(--ak-panel); border: 1px solid var(--ak-line); border-radius: var(--ak-radius);
873
+ }
874
+ /* Una richiesta gestita si smorza nei CAMPI, non nei bottoni: dimmando tutta la scheda,
875
+ «Rispondi» sembrerebbe disattivato proprio quando serve rispondere di nuovo. Stessa regola
876
+ della foto nascosta nel widget delle gallery. */
877
+ .rq-detail.is-handled .rq-fields { opacity: .6; }
878
+ .rq-head {
879
+ display: flex; align-items: center; gap: 10px; padding: 12px 16px;
880
+ border-bottom: 1px solid var(--ak-line);
881
+ }
882
+ .rq-avatar {
883
+ flex: none; width: 30px; height: 30px; border-radius: 50%;
884
+ display: grid; place-items: center; background: var(--ak-ink); color: #fff;
885
+ font: 600 11px/1 var(--ak-font); letter-spacing: .04em;
886
+ }
887
+ .rq-name { font: 600 14px/1.2 var(--ak-font); }
888
+ .rq-tag {
889
+ font: 500 11px/1 var(--ak-font); padding: 3px 7px; border-radius: 20px;
890
+ background: var(--ak-bg); border: 1px solid var(--ak-line); color: var(--ak-ink-quiet);
891
+ }
892
+ .rq-date { font: 400 11px/1 var(--ak-font-mono); color: var(--ak-ink-quiet); white-space: nowrap; }
893
+ .rq-menu-wrap { position: relative; display: inline-flex; }
894
+
895
+ .rq-fields {
896
+ margin: 0; padding: 16px; display: grid; grid-template-columns: 130px minmax(0, 1fr);
897
+ gap: 14px 16px; align-items: baseline;
898
+ }
899
+ .rq-fields dt { font: 400 var(--ak-fs-small)/1.4 var(--ak-font); color: var(--ak-ink-quiet); }
900
+ .rq-fields dd { margin: 0; font: 400 var(--ak-fs)/1.5 var(--ak-font); }
901
+ .rq-mail { color: var(--ak-accent); text-decoration: none; }
902
+ .rq-mail:hover { text-decoration: underline; }
903
+ /* `pre-wrap`: chi scrive va a capo, e quegli a capo sono parte del messaggio. */
904
+ .rq-msg { white-space: pre-wrap; }
905
+ .rq-actions { display: flex; gap: 8px; padding: 0 16px 16px; }
906
+
907
+ /* ---- Consegne --------------------------------------------------------------------------
908
+ Una schermata sola per un transfer: a sinistra il lavoro (file, nome, messaggio, link), a
909
+ destra le opzioni. La forma viene da WeTransfer; la differenza è che qui lo spazio c'è, e
910
+ quindi le opzioni stanno APERTE invece che dietro a una freccia. Vedi routes/Deliveries.tsx.
911
+ -------------------------------------------------------------------------------------- */
912
+
913
+ /* L'elenco */
914
+ .dl-list { gap: 3px; }
915
+ .dl-row {
916
+ display: grid; grid-template-columns: 9px minmax(0,1fr) auto; gap: 5px 9px;
917
+ align-items: center; padding: 10px;
918
+ }
919
+ .dl-state { width: 8px; height: 8px; border-radius: 50%; background: var(--ak-ink-faint); grid-row: span 2; }
920
+ .dl-state.is-ready { background: #2f8b62; }
921
+ .dl-state.is-downloaded { background: #3978b8; }
922
+ .dl-state.is-expiring { background: #d28b27; }
923
+ .dl-state.is-uploading { background: var(--ak-accent); box-shadow: 0 0 0 3px color-mix(in srgb,var(--ak-accent) 15%,transparent); }
924
+ .dl-state.is-expired,.dl-state.is-archived { background: var(--ak-ink-quiet); }
925
+ .dl-row-main { display: flex; flex-direction: column; min-width: 0; text-align: left; }
926
+ .dl-row-main strong { overflow: hidden; text-overflow: ellipsis; font-size: 13px; }
927
+ .dl-row-main span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ak-ink-quiet); font-size: 11px; }
928
+ .dl-row-meta,.dl-row-size { font: 500 10px/1.2 var(--ak-font-mono); color: var(--ak-ink-quiet); white-space: nowrap; }
929
+ .dl-row-size { grid-column: 2/4; }
930
+ .dl-col-foot { flex: none; padding: 10px; border-top: 1px solid var(--ak-line); display: grid; gap: 6px; }
931
+ .dl-total { margin: 0; padding: 0 4px; font: 500 10px/1.2 var(--ak-font-mono); color: var(--ak-ink-faint); }
932
+
933
+ /* Lo spazio di lavoro */
934
+ .dl-work { width: min(1180px,100%); margin: 0 auto; display: grid; gap: 14px; padding-bottom: 48px; }
935
+ .dl-work-head {
936
+ position: sticky; z-index: 6; top: 0; margin: -4px 0 0; padding: 10px 0;
937
+ display: flex; align-items: center; justify-content: space-between; gap: 12px;
938
+ background: var(--ak-bg);
939
+ }
940
+ .dl-work-title { display: flex; align-items: center; gap: 9px; min-width: 0; }
941
+ .dl-work-title h2 {
942
+ margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
943
+ font: 600 17px/1.2 var(--ak-font);
944
+ }
945
+ .dl-work-actions { display: flex; align-items: center; gap: 6px; flex: none; }
946
+ .dl-pill {
947
+ flex: none; padding: 3px 9px; border-radius: 20px; background: var(--ak-inset);
948
+ font: 600 10px/1.2 var(--ak-font); color: var(--ak-ink-quiet);
949
+ }
950
+ .dl-pill.is-ready { color: #226c4c; background: color-mix(in srgb,#2f8b62 14%,var(--ak-panel)); }
951
+ .dl-pill.is-downloaded { color: #285f99; background: color-mix(in srgb,#3978b8 14%,var(--ak-panel)); }
952
+ .dl-pill.is-expiring { color: #8b5a15; background: color-mix(in srgb,#d28b27 16%,var(--ak-panel)); }
953
+ .dl-pill.is-uploading { color: var(--ak-accent); background: color-mix(in srgb,var(--ak-accent) 12%,var(--ak-panel)); }
954
+
955
+ .dl-feedback {
956
+ margin: 0; padding: 9px 12px; display: flex; align-items: center; justify-content: space-between;
957
+ border: 1px solid color-mix(in srgb,#c34848 35%,var(--ak-line)); border-radius: var(--ak-radius);
958
+ background: color-mix(in srgb,#c34848 8%,var(--ak-panel));
959
+ }
960
+ .dl-feedback.is-ok { color: #226c4c; border-color: color-mix(in srgb,#2f8b62 30%,var(--ak-line)); background: color-mix(in srgb,#2f8b62 7%,var(--ak-panel)); }
961
+ .dl-feedback button { border: 0; background: none; color: inherit; cursor: pointer; font-size: 17px; }
962
+
963
+ /* Le due colonne. 1fr/360px: la destra tiene le opzioni su una riga sola di testo.
964
+ `minmax(0,…)` e `min-width: 0` a OGNI livello annidato, non solo sul primo: un elemento di
965
+ griglia parte da `min-width: auto`, cioè «non più stretto del mio contenuto», e un nome di
966
+ file lungo con `white-space: nowrap` ha un contenuto minimo largo quanto tutta la riga. Il
967
+ risultato era che durante il caricamento la colonna di sinistra si allargava fin sotto a
968
+ quella di destra, e il nome non veniva mai troncato perché nessuno gli diceva quanto era
969
+ largo. `text-overflow: ellipsis` da solo non basta: prima serve una larghezza. */
970
+ .dl-grid { display: grid; grid-template-columns: minmax(0,1fr) 360px; gap: 14px; align-items: start; }
971
+ .dl-main,.dl-side {
972
+ display: grid; grid-template-columns: minmax(0,1fr); gap: 14px; align-content: start; min-width: 0;
973
+ }
974
+ .dl-card,.dl-group { min-width: 0; }
975
+ .dl-card { background: var(--ak-panel); border: 1px solid var(--ak-line); border-radius: var(--ak-radius); }
976
+
977
+ /* Le due mattonelle di scelta: sono la prima cosa che si guarda entrando. */
978
+ .dl-pick { padding: 14px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
979
+ .dl-pick-tile {
980
+ display: grid; justify-items: center; gap: 6px; padding: 18px 12px;
981
+ border: 1px solid color-mix(in srgb,var(--ak-accent) 22%,var(--ak-line)); border-radius: 10px;
982
+ background: color-mix(in srgb,var(--ak-accent) 5%,var(--ak-panel));
983
+ font: 600 12px/1.2 var(--ak-font); color: var(--ak-ink); cursor: pointer;
984
+ transition: background-color .15s, border-color .15s;
985
+ }
986
+ .dl-pick-tile span { font-size: 19px; line-height: 1; color: var(--ak-accent); }
987
+ .dl-pick-tile:hover:not(:disabled) { background: color-mix(in srgb,var(--ak-accent) 10%,var(--ak-panel)); border-color: var(--ak-accent); }
988
+ .dl-pick-tile:disabled { opacity: .5; cursor: default; }
989
+
990
+ .dl-drop {
991
+ margin: 0 14px 14px; padding: 16px; display: grid; gap: 3px; justify-items: center;
992
+ border: 1px dashed var(--ak-line); border-radius: 10px; text-align: center;
993
+ color: var(--ak-ink-quiet);
994
+ }
995
+ .dl-drop strong { color: var(--ak-ink); font-size: 12px; }
996
+ .dl-drop span { font-size: 10px; }
997
+ .dl-drop.is-over { border-color: var(--ak-accent); background: color-mix(in srgb,var(--ak-accent) 7%,var(--ak-panel)); }
998
+ .dl-drop.is-off { opacity: .5; }
999
+
1000
+ .dl-files { margin: 0; padding: 0 14px 14px; list-style: none; display: grid; gap: 8px; }
1001
+ .dl-file {
1002
+ display: grid; grid-template-columns: 26px minmax(0,1fr) auto; gap: 10px; align-items: center;
1003
+ padding: 10px; border: 1px solid var(--ak-line); border-radius: 8px; background: var(--ak-bg);
1004
+ }
1005
+ .dl-file-icon { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; background: var(--ak-panel); color: var(--ak-ink-quiet); }
1006
+ .dl-file.is-ready .dl-file-icon { color: #226c4c; background: color-mix(in srgb,#2f8b62 12%,var(--ak-panel)); }
1007
+ .dl-file-main { min-width: 0; display: grid; gap: 2px; }
1008
+ .dl-file-main strong { font-size: 13px; }
1009
+ .dl-file-main span { color: var(--ak-ink-quiet); font-size: 11px; }
1010
+ .dl-file-actions { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
1011
+ /* La riga che chiede conferma prende lo stesso rosso tenue del riquadro in fondo:
1012
+ «Rimuovi» cancella i byte all'istante, esattamente come «Elimina il transfer». */
1013
+ .dl-file.is-confirming {
1014
+ border-color: color-mix(in srgb,#c34848 35%,var(--ak-line));
1015
+ background: color-mix(in srgb,#c34848 6%,var(--ak-panel));
1016
+ }
1017
+
1018
+ .dl-progress { margin: 0 14px 14px; padding: 12px; border: 1px solid var(--ak-line); border-radius: 8px; background: var(--ak-bg); }
1019
+ .dl-progress-top { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; }
1020
+ .dl-progress-top strong { min-width: 0; font-weight: 600; }
1021
+ /* Il conteggio non si accorcia mai: a cedere è il nome del file, che è l'unica cosa lunga. */
1022
+ .dl-progress-top span { flex: 0 0 auto; color: var(--ak-ink-quiet); white-space: nowrap; }
1023
+ .dl-progress-track { height: 5px; margin: 9px 0; overflow: hidden; border-radius: 4px; background: var(--ak-line); }
1024
+ .dl-progress-track i { display: block; height: 100%; background: var(--ak-accent); transition: width .2s; }
1025
+ .dl-progress p,.dl-progress small { margin: 0; color: var(--ak-ink-quiet); font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1026
+ .dl-progress small { display: block; margin-top: 4px; white-space: normal; }
1027
+
1028
+ .dl-about { padding: 14px; display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; }
1029
+ .dl-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
1030
+ .dl-field.is-wide { grid-column: 1/-1; }
1031
+ .dl-field > span { font: 500 11px/1.3 var(--ak-font); color: var(--ak-ink-quiet); }
1032
+ .dl-field small { font: 400 10px/1.35 var(--ak-font); color: var(--ak-ink-faint); }
1033
+ .dl-field input,.dl-field textarea,.dl-select {
1034
+ width: 100%; padding: 8px 9px; border: 1px solid var(--ak-line); border-radius: 6px;
1035
+ font: inherit; font-size: 13px; color: var(--ak-ink); background: var(--ak-bg);
1036
+ }
1037
+ .dl-field textarea { resize: vertical; min-height: 62px; }
1038
+ .dl-field input:focus,.dl-field textarea:focus,.dl-select:focus {
1039
+ outline: 2px solid color-mix(in srgb,var(--ak-accent) 25%,transparent); border-color: var(--ak-accent);
1040
+ }
1041
+
1042
+ /* Il link: è il prodotto finito, e si vede che lo è. */
1043
+ .dl-link { padding: 14px; display: grid; gap: 10px; }
1044
+ .dl-link-head { display: grid; gap: 5px; }
1045
+ .dl-link-head code {
1046
+ padding: 9px 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1047
+ border: 1px solid var(--ak-line); border-radius: 6px; background: var(--ak-bg);
1048
+ color: var(--ak-accent); font: 400 12px/1.3 var(--ak-font-mono);
1049
+ }
1050
+ .dl-link-actions { display: flex; gap: 6px; flex-wrap: wrap; }
1051
+ .dl-link-stats { margin: 0; color: var(--ak-ink-quiet); font-size: 11px; line-height: 1.5; }
1052
+ .dl-step { color: var(--ak-ink-quiet); font: 500 10px/1 var(--ak-font); text-transform: uppercase; letter-spacing: .08em; }
1053
+
1054
+ .dl-get { padding: 14px; display: grid; gap: 8px; justify-items: start; }
1055
+ .dl-get-btn { padding: 11px 22px; font-size: 13px; }
1056
+ .dl-get p { margin: 0; color: var(--ak-ink-quiet); font-size: 11px; line-height: 1.5; }
1057
+
1058
+ /* La colonna delle opzioni */
1059
+ .dl-group {
1060
+ padding: 14px; display: grid; gap: 10px;
1061
+ background: var(--ak-panel); border: 1px solid var(--ak-line); border-radius: var(--ak-radius);
1062
+ }
1063
+ .dl-group h3 { margin: 0; font: 600 12px/1.2 var(--ak-font); }
1064
+ .dl-note { margin: 0; color: var(--ak-ink-quiet); font-size: 11px; line-height: 1.5; }
1065
+ .dl-radio,.dl-check { display: grid; grid-template-columns: 16px minmax(0,1fr); gap: 9px; align-items: start; cursor: pointer; }
1066
+ .dl-radio input,.dl-check input { margin: 2px 0 0; accent-color: var(--ak-accent); }
1067
+ .dl-radio span,.dl-check span { display: grid; gap: 2px; }
1068
+ .dl-radio strong,.dl-check strong { font: 500 12px/1.35 var(--ak-font); }
1069
+ .dl-radio small,.dl-check small { color: var(--ak-ink-quiet); font-size: 11px; line-height: 1.45; }
1070
+ .dl-code { display: flex; gap: 6px; }
1071
+ .dl-code input {
1072
+ flex: 1; min-width: 0; padding: 8px 9px; border: 1px solid var(--ak-line); border-radius: 6px;
1073
+ background: var(--ak-bg); color: var(--ak-ink);
1074
+ font: 600 13px/1.2 var(--ak-font-mono); letter-spacing: .08em; text-transform: uppercase;
1075
+ }
1076
+ .dl-group .dl-field { gap: 4px; }
1077
+
1078
+ /* La copertina: una griglia, quindi a piena larghezza */
1079
+ .dl-cover { display: grid; }
1080
+ .dl-cover-head {
1081
+ padding: 12px 14px; display: flex; align-items: center; justify-content: space-between; gap: 12px;
1082
+ border-bottom: 1px solid var(--ak-line);
1083
+ }
1084
+ .dl-cover-head p { margin: 3px 0 0; color: var(--ak-ink-quiet); font-size: 11px; }
1085
+ .dl-cover-actions { display: flex; gap: 6px; flex: none; }
1086
+ .dl-cover-grid { padding: 14px; display: grid; grid-template-columns: repeat(auto-fill,minmax(116px,1fr)); gap: 8px; }
1087
+ .dl-cover-grid button {
1088
+ position: relative; min-width: 0; padding: 0; overflow: hidden; cursor: pointer;
1089
+ border: 2px solid transparent; border-radius: 6px; background: var(--ak-bg);
1090
+ }
1091
+ .dl-cover-grid button.is-chosen { border-color: var(--ak-accent); }
1092
+ .dl-cover-grid img { width: 100%; aspect-ratio: 3/2; display: block; object-fit: cover; }
1093
+ .dl-cover-grid em {
1094
+ position: absolute; top: 5px; right: 5px; width: 18px; height: 18px; display: grid; place-items: center;
1095
+ border-radius: 50%; background: var(--ak-accent); color: #fff; font: 600 11px/1 var(--ak-font); font-style: normal;
1096
+ }
1097
+ .dl-cover-grid.is-static img { border-radius: 6px; }
1098
+ .dl-cover-empty { padding: 14px; }
1099
+
1100
+ /* Il fondo: le cose che tolgono */
1101
+ .dl-danger {
1102
+ display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
1103
+ padding-top: 6px; border-top: 1px solid var(--ak-line);
1104
+ }
1105
+ .dl-danger > div { display: flex; gap: 6px; flex-wrap: wrap; }
1106
+ .dl-danger-btn { color: #a33; border-color: color-mix(in srgb,#c34848 35%,var(--ak-line)); }
1107
+ .dl-danger-btn:hover { border-color: #c34848; }
1108
+ .dl-confirm {
1109
+ flex: 1; min-width: 260px; padding: 10px 12px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
1110
+ border: 1px solid color-mix(in srgb,#c34848 35%,var(--ak-line)); border-radius: var(--ak-radius);
1111
+ background: color-mix(in srgb,#c34848 6%,var(--ak-panel));
1112
+ }
1113
+ .dl-confirm p { margin: 0; flex: 1; min-width: 200px; font-size: 11px; line-height: 1.5; }
1114
+
1115
+ /* ---- Il riquadro dei caricamenti ---------------------------------------------------------
1116
+ In basso a destra, sopra tutto, sempre presente finché c'è un caricamento: è la prova
1117
+ visibile che l'upload NON è più prigioniero della schermata del transfer. Si riduce a una
1118
+ riga; non si chiude mentre lavora, perché chiuderlo sembrerebbe fermarlo. */
1119
+ .uk {
1120
+ position: fixed; z-index: 40; right: 14px; bottom: 14px; width: min(360px, calc(100vw - 28px));
1121
+ display: grid; overflow: hidden;
1122
+ background: var(--ak-panel); border: 1px solid var(--ak-line); border-radius: var(--ak-radius);
1123
+ box-shadow: var(--ak-shadow);
1124
+ }
1125
+ .uk-head {
1126
+ display: flex; align-items: center; justify-content: space-between; gap: 10px;
1127
+ padding: 10px 12px; border: 0; background: var(--ak-bg); cursor: pointer;
1128
+ font: 600 12px/1.2 var(--ak-font); color: var(--ak-ink); text-align: left;
1129
+ }
1130
+ .uk-head-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1131
+ .uk-chevron { color: var(--ak-ink-quiet); font-size: 10px; }
1132
+ .uk-list { margin: 0; padding: 0; list-style: none; display: grid; max-height: 46vh; overflow-y: auto; }
1133
+ .uk-job { padding: 11px 12px; display: grid; gap: 7px; border-top: 1px solid var(--ak-line); }
1134
+ .uk-job-top { display: grid; gap: 2px; }
1135
+ .uk-job-top strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
1136
+ .uk-job-top span { color: var(--ak-ink-quiet); font-size: 11px; }
1137
+ .uk-job.is-done .uk-job-top span { color: #226c4c; }
1138
+ .uk-job.is-failed .uk-job-top span { color: #a33; }
1139
+ .uk-track { height: 4px; overflow: hidden; border-radius: 3px; background: var(--ak-line); }
1140
+ .uk-track i { display: block; height: 100%; background: var(--ak-accent); transition: width .25s; }
1141
+ .uk-job.is-paused .uk-track i { background: var(--ak-ink-quiet); }
1142
+ .uk-error { margin: 0; color: #a33; font-size: 11px; line-height: 1.45; }
1143
+ .uk-job-actions { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
1144
+ .uk-job-actions .ak-btn { padding: 4px 9px; font-size: 11px; }
1145
+ .uk-confirm { flex: 1 0 100%; color: var(--ak-ink-quiet); font-size: 11px; }
1146
+ /* Il riquadro è `fixed` e copre l'angolo: finché c'è, il fondo della schermata si allunga,
1147
+ altrimenti l'ultima riga di ogni pagina resta là sotto senza modo di raggiungerla. */
1148
+ body:has(.uk) .pane-body { padding-bottom: 190px; }
1149
+
1150
+ @media (max-width: 1100px) {
1151
+ .dl-grid { grid-template-columns: minmax(0,1fr); }
1152
+ .dl-about { grid-template-columns: 1fr; }
1153
+ .dl-field.is-wide { grid-column: auto; }
1154
+ }
1155
+ @media (max-width: 800px) {
1156
+ .dl-pick { grid-template-columns: 1fr; }
1157
+ .dl-work-head { flex-wrap: wrap; }
1158
+ .dl-cover-head { flex-direction: column; align-items: flex-start; }
1159
+ .gs-image-editor { grid-template-columns: 1fr; }
1160
+ }
1161
+ /* ---- Portfolio: i lavori -----------------------------------------------------------------
1162
+ Linguaggio nuovo del pannello: NIENTE tratti. A separare sono il colore del fondo e l'ombra,
1163
+ come nelle interfacce editoriali a cui punta il redesign — un bordo di un pixel disegna una
1164
+ scatola, e una schermata piena di scatole si legge come un modulo da compilare invece che
1165
+ come il contenuto che rappresenta.
1166
+
1167
+ Tre livelli, e non di più: la pagina (fondo tenue), la card di un lavoro (bianca, sollevata),
1168
+ e dentro di essa i blocchi (fondo tenue di nuovo, incassati). Un quarto livello e la
1169
+ gerarchia smette di leggersi.
1170
+
1171
+ I valori (`--ak-ground`, `--ak-inset`, `--ak-inset-deep`, `--ak-lift-*`, `--ak-ring`) stanno
1172
+ in `theme.css`, non qui: li condivide con le sezioni delle gallery, ed è là che si cambiano
1173
+ per un altro cliente. Vedi routes/PortfolioWorksEditor.tsx.
1174
+ -------------------------------------------------------------------------------------- */
1175
+ /* Il FONDO su cui poggiano le card è più profondo di quello del resto del pannello. È l'unico
1176
+ modo di dare contrasto a una card bianca senza disegnarle un bordo intorno: se il foglio
1177
+ sotto è quasi bianco anche lui (`--ak-bg` è #fbfbfa, un punto e mezzo di differenza), la card
1178
+ resta appesa a un'ombra al cinque per cento e l'elenco si legge come un blocco unico.
1179
+ `:has()` invece di una classe passata da App.tsx: la tinta appartiene a queste schermate, e
1180
+ farla dipendere da uno stato React vorrebbe dire tenere allineate due cose che descrivono la
1181
+ stessa. */
1182
+ .pane-body:has(.ed-portfolio), .pane-body:has(.ed-gallery), .pane-body:has(.ed-about),
1183
+ .pane-body:has(.ed-workshop), .pane-body:has(.ed-home), .pane-body:has(.ov) { background: var(--ak-ground); }
1184
+
1185
+ /* I valori del linguaggio senza tratti stanno in `theme.css` (`--ak-ground`, `--ak-inset`,
1186
+ `--ak-inset-deep`, `--ak-lift-*`, `--ak-ring`): li usano sia questa schermata sia le sezioni
1187
+ delle gallery, e una seconda copia sarebbe la prima occasione per farle divergere. */
1188
+ .pw {
1189
+ width: min(1080px, 100%); margin: 0 auto;
1190
+ display: flex; flex-direction: column; gap: 16px;
1191
+ padding-bottom: 56px;
1192
+ }
1193
+
1194
+ .pw-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; padding: 2px 4px; }
1195
+ .pw-head h3 { margin: 0; font: 600 17px/1.2 var(--ak-font); letter-spacing: -.01em; }
1196
+ .pw-head p { margin: 5px 0 0; color: var(--ak-ink-quiet); font: 400 12px/1.45 var(--ak-font); }
1197
+ /* Il bottone della testata non si stringe e non va a capo: è l'azione, e «Aggiungi voce»
1198
+ spezzato su due righe si legge come due parole finite lì per sbaglio. A cedere è il testo
1199
+ accanto, che è una spiegazione e può andare a capo quanto vuole. */
1200
+ .pw-head > .btn-soft { flex: none; white-space: nowrap; }
1201
+
1202
+ .pw-list { display: flex; flex-direction: column; gap: 8px; }
1203
+
1204
+ /* La card di un lavoro. `transition` anche sull'ombra: aprendola l'elevazione cresce, e quel
1205
+ movimento è ciò che racconta che il contenuto sta uscendo da lì e non comparendo altrove. */
1206
+ .pw-work {
1207
+ position: relative; background: var(--ak-panel); border-radius: 14px;
1208
+ box-shadow: var(--ak-lift-1);
1209
+ transition: box-shadow .18s ease, transform .18s ease;
1210
+ }
1211
+ .pw-work:hover { box-shadow: var(--ak-lift-2); }
1212
+ .pw-work.is-open { box-shadow: var(--ak-lift-3); }
1213
+ /* Sollevata e semitrasparente mentre la si trascina: l'elemento sotto il dito è "staccato" dal
1214
+ foglio. Il posto in cui cadrà lo mostrano gli altri che si spostano — non serve una riga di
1215
+ inserimento, che sarebbe di nuovo un tratto. */
1216
+ .pw-work.is-dragging { z-index: 3; opacity: .9; box-shadow: var(--ak-lift-3); }
1217
+
1218
+ .pw-work-head { display: grid; grid-template-columns: 26px minmax(0, 1fr) auto; align-items: center; gap: 2px; padding: 8px 12px 8px 6px; }
1219
+
1220
+ /* La maniglia compare al passaggio: otto maniglie sempre accese sono rumore in un elenco che
1221
+ si guarda per capire l'ordine. Resta raggiungibile da tastiera. */
1222
+ .pw-grip {
1223
+ display: grid; place-items: center; width: 26px; height: 34px; padding: 0;
1224
+ border: 0; border-radius: 8px; background: transparent; color: var(--ak-ink-quiet);
1225
+ cursor: grab; touch-action: none; opacity: 0; transition: opacity .15s, background-color .15s;
1226
+ }
1227
+ .pw-grip:active { cursor: grabbing; }
1228
+ .pw-work:hover .pw-grip, .pw-work.is-open .pw-grip, .pw-grip:focus-visible,
1229
+ .pw-info-row:hover .pw-grip, .pw-card:hover .pw-grip { opacity: .55; }
1230
+ .pw-grip:hover { background: var(--ak-inset); opacity: 1 !important; }
1231
+
1232
+ .pw-work-open {
1233
+ display: flex; align-items: center; gap: 13px; min-width: 0; width: 100%;
1234
+ border: 0; border-radius: 10px; background: transparent; cursor: pointer;
1235
+ padding: 6px 8px; text-align: left; color: inherit; font: inherit;
1236
+ }
1237
+ .pw-work-open:hover { background: var(--ak-inset); }
1238
+ .pw-work-open:focus-visible { outline: 0; box-shadow: var(--ak-ring); }
1239
+
1240
+ .pw-thumb {
1241
+ flex: none; width: 52px; height: 52px; display: grid; place-items: center; overflow: hidden;
1242
+ padding: 0; border: 0; border-radius: 9px; background: var(--ak-inset-deep);
1243
+ color: var(--ak-ink-quiet); cursor: pointer;
1244
+ }
1245
+ .pw-thumb img { width: 100%; height: 100%; display: block; object-fit: cover; }
1246
+ .pw-thumb-empty { display: inline-flex; align-items: center; gap: 8px; font: 500 11px/1.2 var(--ak-font); }
1247
+ /* La copertina grande NON si taglia: `contain` su fondo tenue. Ritagliare la copertina di un
1248
+ libro nell'anteprima di chi la sta scegliendo è il modo più rapido per farla scegliere male. */
1249
+ .pw-thumb.is-cover, .pw-thumb.is-large, .pw-thumb.is-portrait {
1250
+ width: 100%; height: auto; aspect-ratio: 4 / 5; border-radius: 11px;
1251
+ }
1252
+ .pw-thumb.is-large { aspect-ratio: 3 / 2; }
1253
+ /* Il ritratto della pagina "chi sono": verticale, perché è la forma in cui esce sul sito. */
1254
+ .pw-thumb.is-portrait { aspect-ratio: 3 / 4; }
1255
+ .pw-thumb.is-cover img, .pw-thumb.is-large img, .pw-thumb.is-portrait img { object-fit: contain; }
1256
+ .pw-thumb:hover { color: var(--ak-accent); }
1257
+
1258
+ .pw-work-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
1259
+ .pw-work-title strong {
1260
+ overflow: hidden; font: 600 14px/1.3 var(--ak-font); text-overflow: ellipsis; white-space: nowrap;
1261
+ }
1262
+ .pw-work-title strong.is-empty { color: var(--ak-ink-quiet); font-weight: 500; font-style: italic; }
1263
+ .pw-work-title small { color: var(--ak-ink-quiet); font: 400 11px/1.2 var(--ak-font); }
1264
+
1265
+ .pw-chevron { flex: none; display: flex; color: var(--ak-ink-quiet); transition: transform .2s ease; }
1266
+ .pw-work.is-open .pw-chevron { transform: rotate(180deg); }
1267
+
1268
+ /* Duplica ed Elimina compaiono al passaggio o a card aperta: sono azioni distruttive o
1269
+ moltiplicative, non devono stare sotto il dito mentre si scorre un elenco. */
1270
+ .pw-work-actions { display: flex; gap: 4px; opacity: 0; transition: opacity .15s; }
1271
+ .pw-work:hover .pw-work-actions, .pw-work.is-open .pw-work-actions,
1272
+ .pw-work-actions:focus-within { opacity: 1; }
1273
+
1274
+ .pw-work-body { display: flex; flex-direction: column; gap: 14px; padding: 4px 16px 18px 16px; }
1275
+
1276
+ .pw-identity { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 18px; align-items: start; }
1277
+ /* La casella immagine: l'anteprima è il bersaglio, i comandi ci stanno sopra e compaiono al
1278
+ passaggio. Su touch restano visibili — senza `hover: none` la rimozione sarebbe
1279
+ irraggiungibile dall'iPad, che è un dispositivo con cui questo pannello si usa davvero. */
1280
+ .pw-media { position: relative; min-width: 0; }
1281
+ .pw-media-hint, .pw-media-clear {
1282
+ position: absolute; opacity: 0; pointer-events: none; transition: opacity .15s;
1283
+ }
1284
+ .pw-media-hint {
1285
+ left: 8px; bottom: 8px; padding: 5px 10px; border-radius: 7px;
1286
+ background: rgba(22, 22, 26, .72); color: #fff;
1287
+ font: 500 11px/1 var(--ak-font); backdrop-filter: blur(6px);
1288
+ }
1289
+ .pw-media-clear {
1290
+ top: 8px; right: 8px; width: 28px; height: 28px; display: grid; place-items: center;
1291
+ border: 0; border-radius: 8px; background: rgba(22, 22, 26, .72); color: #fff; cursor: pointer;
1292
+ backdrop-filter: blur(6px);
1293
+ }
1294
+ .pw-media-clear .ico { width: 14px; height: 14px; }
1295
+ .pw-media-clear:hover { background: var(--ak-danger); }
1296
+ .pw-media.has-image:hover .pw-media-hint,
1297
+ .pw-media.has-image:hover .pw-media-clear,
1298
+ .pw-media.has-image:focus-within .pw-media-hint,
1299
+ .pw-media.has-image:focus-within .pw-media-clear { opacity: 1; pointer-events: auto; }
1300
+ @media (hover: none) {
1301
+ .pw-media.has-image .pw-media-clear { opacity: 1; pointer-events: auto; }
1302
+ }
1303
+ .pw-identity-fields { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
1304
+
1305
+ .pw-label { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
1306
+ .pw-label > span { color: var(--ak-ink); font: 500 11px/1.3 var(--ak-font); }
1307
+ .pw-label > span small { color: var(--ak-ink-quiet); font-weight: 400; }
1308
+ .pw-label > small { color: var(--ak-ink-quiet); font: 400 10px/1.45 var(--ak-font); }
1309
+
1310
+ /* I campi sono RIEMPITI, non contornati: il contrasto col fondo dice già dove si scrive.
1311
+ Il fondo cambia con la superficie che li ospita — tenue sul bianco, bianco dentro un blocco
1312
+ tenue — così restano leggibili a qualunque profondità senza aggiungere una linea. */
1313
+ .pw-field {
1314
+ width: 100%; border: 0; border-radius: 9px; background: var(--ak-inset); color: var(--ak-ink);
1315
+ padding: 10px 12px; font: 400 13px/1.5 var(--ak-font);
1316
+ transition: background-color .15s, box-shadow .15s;
1317
+ }
1318
+ .pw-field::placeholder { color: color-mix(in srgb, var(--ak-ink-quiet) 70%, transparent); }
1319
+ .pw-field:hover { background: var(--ak-inset-deep); }
1320
+ .pw-field:focus { outline: 0; background: var(--ak-panel); box-shadow: var(--ak-ring); }
1321
+ .pw-textarea { resize: vertical; min-height: 96px; }
1322
+ .pw-field-title { font: 600 15px/1.4 var(--ak-font); }
1323
+ .pw-block .pw-field { background: var(--ak-panel); box-shadow: var(--ak-lift-1); }
1324
+ .pw-block .pw-field:hover { background: var(--ak-panel); box-shadow: var(--ak-lift-2); }
1325
+ .pw-block .pw-field:focus { box-shadow: var(--ak-ring); }
1326
+
1327
+ /* Un blocco: fondo tenue e nessun contorno. È il livello "incassato" dentro la card bianca. */
1328
+ .pw-block { display: flex; flex-direction: column; gap: 10px; padding: 13px 14px 14px; border-radius: 12px; background: var(--ak-inset); }
1329
+ .pw-block-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
1330
+ .pw-block-head h4 {
1331
+ margin: 0; color: var(--ak-ink-quiet); font: 600 10px/1 var(--ak-font);
1332
+ letter-spacing: .1em; text-transform: uppercase;
1333
+ }
1334
+ .pw-empty-note { margin: 0; color: var(--ak-ink-quiet); font: 400 11px/1.5 var(--ak-font); }
1335
+
1336
+ .pw-info-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
1337
+ .pw-info-row {
1338
+ display: grid; grid-template-columns: 26px minmax(0, 200px) minmax(0, 1fr) 32px;
1339
+ align-items: center; gap: 6px; border-radius: 10px;
1340
+ }
1341
+ .pw-info-row.is-dragging { z-index: 3; background: var(--ak-panel); box-shadow: var(--ak-lift-3); }
1342
+ .pw-field-label { font-weight: 500; text-transform: uppercase; letter-spacing: .04em; font-size: 11px; }
1343
+
1344
+ .pw-card-list { display: flex; flex-direction: column; gap: 8px; }
1345
+ .pw-card { background: var(--ak-panel); border-radius: 11px; box-shadow: var(--ak-lift-1); }
1346
+ .pw-card.is-dragging { z-index: 3; opacity: .9; box-shadow: var(--ak-lift-3); }
1347
+ .pw-card-head { display: grid; grid-template-columns: 26px auto minmax(0, 1fr) 32px; align-items: center; gap: 8px; padding: 8px 10px 8px 6px; }
1348
+ .pw-card-kind {
1349
+ color: var(--ak-ink-quiet); font: 600 10px/1 var(--ak-font);
1350
+ letter-spacing: .09em; text-transform: uppercase; white-space: nowrap;
1351
+ }
1352
+ .pw-card-body { display: flex; flex-direction: column; gap: 12px; padding: 0 12px 13px; }
1353
+ .pw-card-body.is-split { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 16px; align-items: start; }
1354
+ .pw-card-text { display: flex; flex-direction: column; gap: 11px; min-width: 0; }
1355
+
1356
+ /* Il segmentato, CONDIVISO fra l'editor dei lavori e quello delle sezioni: la scelta vive
1357
+ dentro una vaschetta incassata e l'opzione attiva è l'unica cosa sollevata. Bottoni
1358
+ contornati direbbero "tre pulsanti", non "una scelta fra tre". */
1359
+ .seg { justify-self: end; display: inline-flex; gap: 2px; padding: 2px; border-radius: 9px; background: var(--ak-inset-deep); }
1360
+ .seg-btn {
1361
+ border: 0; border-radius: 7px; background: transparent; cursor: pointer; padding: 5px 10px;
1362
+ color: var(--ak-ink-quiet); font: 500 11px/1 var(--ak-font); transition: background-color .15s, color .15s;
1363
+ }
1364
+ .seg-btn:hover { color: var(--ak-ink); }
1365
+ .seg-btn.is-on { background: var(--ak-panel); color: var(--ak-ink); box-shadow: var(--ak-lift-1); }
1366
+
1367
+ /* I bottoni senza contorno, condivisi dalle due schermate: il riempimento tenue basta a dire
1368
+ che sono premibili, e solo l'azione primaria è piena d'accento. */
1369
+ .btn-soft {
1370
+ display: inline-flex; align-items: center; gap: 7px; border: 0; border-radius: 9px;
1371
+ background: var(--ak-inset); color: var(--ak-ink); cursor: pointer; padding: 8px 13px;
1372
+ font: 500 12px/1 var(--ak-font); transition: background-color .15s, color .15s, box-shadow .15s;
1373
+ }
1374
+ .btn-soft:hover { background: var(--ak-inset-deep); }
1375
+ .btn-soft:focus-visible { outline: 0; box-shadow: var(--ak-ring); }
1376
+ .btn-soft.is-primary { background: var(--ak-accent); color: #fff; box-shadow: var(--ak-lift-2); }
1377
+ .btn-soft.is-primary:hover { background: var(--ak-accent-hover); }
1378
+ .btn-soft.is-quiet { background: transparent; color: var(--ak-ink-quiet); }
1379
+ .btn-soft.is-quiet:hover { background: var(--ak-inset); color: var(--ak-ink); }
1380
+ .btn-soft.is-danger { background: transparent; color: var(--ak-danger); }
1381
+ .btn-soft.is-danger:hover { background: color-mix(in srgb, var(--ak-danger) 9%, transparent); }
1382
+ .btn-soft .ico { width: 14px; height: 14px; }
1383
+
1384
+ .pw-icon-btn {
1385
+ display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 0;
1386
+ border-radius: 8px; background: transparent; color: var(--ak-ink-quiet); cursor: pointer;
1387
+ transition: background-color .15s, color .15s;
1388
+ }
1389
+ .pw-icon-btn:hover { background: var(--ak-inset); color: var(--ak-ink); }
1390
+ .pw-icon-btn.is-danger:hover { background: color-mix(in srgb, var(--ak-danger) 10%, transparent); color: var(--ak-danger); }
1391
+ .pw-icon-btn .ico { width: 15px; height: 15px; }
1392
+
1393
+ .pw-add-quiet {
1394
+ display: inline-flex; align-items: center; gap: 6px; border: 0; border-radius: 8px;
1395
+ background: transparent; color: var(--ak-ink-quiet); cursor: pointer; padding: 5px 8px;
1396
+ font: 500 11px/1 var(--ak-font);
1397
+ }
1398
+ .pw-add-quiet:hover { background: var(--ak-panel); color: var(--ak-ink); box-shadow: var(--ak-lift-1); }
1399
+ .pw-add-quiet .ico { width: 13px; height: 13px; }
1400
+
1401
+ .pw-add-wrap { position: relative; }
1402
+ .pw-menu {
1403
+ position: absolute; z-index: 20; top: calc(100% + 6px); right: 0; width: 268px; padding: 6px;
1404
+ border-radius: 12px; background: var(--ak-panel); box-shadow: var(--ak-lift-3);
1405
+ }
1406
+ .pw-menu button {
1407
+ width: 100%; display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 10px;
1408
+ align-items: center; padding: 9px 9px; border: 0; border-radius: 9px; background: transparent;
1409
+ color: var(--ak-ink); cursor: pointer; text-align: left;
1410
+ }
1411
+ .pw-menu button:hover { background: var(--ak-inset); }
1412
+ .pw-menu-icon { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 8px; background: var(--ak-inset); color: var(--ak-ink-quiet); }
1413
+ .pw-menu button > span:last-child { display: flex; flex-direction: column; gap: 2px; }
1414
+ .pw-menu strong { font: 600 12px/1.2 var(--ak-font); }
1415
+ .pw-menu small { color: var(--ak-ink-quiet); font: 400 10px/1.35 var(--ak-font); }
1416
+
1417
+ /* Il vuoto è una superficie, non un rettangolo tratteggiato: invita a premere invece di
1418
+ sembrare un contenitore rotto. */
1419
+ .pw-blank {
1420
+ display: grid; justify-items: center; gap: 6px; padding: 46px 20px; border: 0;
1421
+ border-radius: 14px; background: var(--ak-inset); color: var(--ak-ink-quiet); cursor: pointer;
1422
+ transition: background-color .15s, box-shadow .15s;
1423
+ }
1424
+ .pw-blank:hover { background: var(--ak-panel); box-shadow: var(--ak-lift-2); }
1425
+ .pw-blank .ico { width: 22px; height: 22px; margin-bottom: 4px; }
1426
+ .pw-blank strong { color: var(--ak-ink); font: 600 14px/1.2 var(--ak-font); }
1427
+ .pw-blank span { font: 400 12px/1.4 var(--ak-font); }
1428
+
1429
+ @media (max-width: 900px) {
1430
+ .pw-identity, .pw-card-body.is-split { grid-template-columns: minmax(0, 1fr); }
1431
+ .pw-identity > .pw-media { max-width: 240px; }
1432
+ .pw-card-head { grid-template-columns: 26px auto minmax(0, 1fr) 32px; }
1433
+ .seg { flex-wrap: wrap; }
1434
+ .pw-info-row { grid-template-columns: 26px minmax(0, 1fr) 32px; }
1435
+ .pw-info-row .pw-field:nth-of-type(2) { grid-column: 2 / 4; }
1436
+ }
1437
+
1438
+ /* ---- Chi sono ----------------------------------------------------------------------------
1439
+ Le due colonne della pagina vera: la biografia a sinistra, il ritratto fermo a destra. Stessi
1440
+ tre livelli e stessi valori del portfolio (`--ak-ground` sotto, `--ak-panel` per i blocchi,
1441
+ `--ak-inset` dentro) — qui non si dichiara nessun colore nuovo.
1442
+
1443
+ Il prefisso è `abo-` e non `ab-`: `ab-` è già il prefisso della pagina "chi sono" SUL SITO
1444
+ (static/css/about.css). Sono due fogli che non si incontrano mai, ma cercare `.ab-credit` e
1445
+ trovare due posti distanti è il modo in cui si finisce per modificare quello sbagliato.
1446
+ Vedi routes/AboutEditor.tsx. ------------------------------------------------------------ */
1447
+ .abo {
1448
+ width: min(1080px, 100%); margin: 0 auto; padding-bottom: 56px;
1449
+ display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 22px; align-items: start;
1450
+ }
1451
+ .abo-main { min-width: 0; display: flex; flex-direction: column; gap: 16px; }
1452
+
1453
+ /* Ferma mentre scorre il testo, come il ritratto nella pagina. 18px è il respiro sopra: senza,
1454
+ incollandosi al bordo sembra uscita dal pannello invece che ancorata. */
1455
+ .abo-side { position: sticky; top: 18px; }
1456
+ .abo-side-inner {
1457
+ display: flex; flex-direction: column; gap: 12px; padding: 16px;
1458
+ border-radius: 14px; background: var(--ak-panel); box-shadow: var(--ak-lift-1);
1459
+ }
1460
+ .abo-side-inner h3 { margin: 0; font: 600 13px/1.2 var(--ak-font); letter-spacing: -.01em; }
1461
+
1462
+ .abo-block {
1463
+ display: flex; flex-direction: column; gap: 12px; padding: 16px 18px 18px;
1464
+ border-radius: 14px; background: var(--ak-panel); box-shadow: var(--ak-lift-1);
1465
+ }
1466
+ .abo-block .pw-head { padding: 0; }
1467
+
1468
+ /* Quanto testo c'è. In cifre tabellari perché cambia a ogni tasto: senza, la riga balla. */
1469
+ .ed-count {
1470
+ flex: none; color: var(--ak-ink-quiet); font: 400 11px/1 var(--ak-font-mono);
1471
+ font-variant-numeric: tabular-nums;
1472
+ }
1473
+
1474
+ /* La colonna della biografia non supera la misura di lettura, e l'altezza la decide il testo
1475
+ (`ProseEditor` la ricalcola): un campo che scorre dentro una pagina che ha spazio libero è
1476
+ il modo più rapido per perdere il filo di quello che si sta scrivendo. */
1477
+ .ed-prose {
1478
+ width: 100%; max-width: 68ch; min-height: 160px; resize: none; overflow: hidden;
1479
+ font: 400 14px/1.75 var(--ak-font);
1480
+ }
1481
+
1482
+ /* I riconoscimenti: righe su fondo incassato, non card bianche. Sono voci di un elenco, e a
1483
+ distinguerle basta lo spazio — sollevarle una per una darebbe a tre parole il peso di un
1484
+ lavoro del portfolio. */
1485
+ .abo-credits { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
1486
+ .abo-credit {
1487
+ display: flex; flex-direction: column; gap: 6px; padding: 8px 10px 10px 6px;
1488
+ border-radius: 11px; background: var(--ak-inset);
1489
+ }
1490
+ .abo-credit.is-dragging { z-index: 3; background: var(--ak-panel); box-shadow: var(--ak-lift-3); }
1491
+ .abo-credit:hover .pw-grip, .abo-credit:focus-within .pw-grip { opacity: .55; }
1492
+ .abo-credit-main { display: grid; grid-template-columns: 26px 180px minmax(0, 1fr) 30px; align-items: center; gap: 8px; }
1493
+ .abo-credit .pw-field { background: var(--ak-panel); }
1494
+ .abo-credit .pw-field:hover { background: var(--ak-panel); box-shadow: var(--ak-lift-1); }
1495
+ .abo-credit .pw-field:focus { box-shadow: var(--ak-ring); }
1496
+
1497
+ /* Ruolo e nome hanno la grafia con cui escono sul sito: il ruolo è testo corrente, il nome è
1498
+ l'entità in evidenza (`.ab-credit-name` in about.css). Così la riga è già l'anteprima di sé
1499
+ stessa e non serve mostrarla due volte. */
1500
+ .abo-role { font: 400 13px/1.4 var(--ak-font); }
1501
+ .abo-name {
1502
+ color: var(--ak-accent); font: 600 12px/1.4 var(--ak-font);
1503
+ text-transform: uppercase; letter-spacing: .04em;
1504
+ }
1505
+
1506
+ /* L'indirizzo è il campo quieto: si vede sempre — nascondere una riga costerebbe uno stato per
1507
+ voce da ricalcolare a ogni riordino — ma si spegne finché è vuoto. */
1508
+ .abo-credit-link { display: grid; grid-template-columns: 26px minmax(0, 1fr) 30px; align-items: center; gap: 8px; opacity: .55; transition: opacity .15s; }
1509
+ .abo-credit-link:hover, .abo-credit-link:focus-within, .abo-credit-link.is-linked { opacity: 1; }
1510
+ .abo-link-mark { display: grid; place-items: center; color: var(--ak-ink-quiet); }
1511
+ .abo-credit-link.is-linked .abo-link-mark { color: var(--ak-accent); }
1512
+ .abo-link-mark .ico { width: 13px; height: 13px; }
1513
+ .abo-href { grid-column: 2; font: 400 11px/1.4 var(--ak-font-mono); }
1514
+
1515
+ /* Il riquadro dei recapiti: dice una cosa e porta altrove, quindi non è una superficie
1516
+ sollevata come i blocchi che si compilano. */
1517
+ .abo-note {
1518
+ display: flex; flex-direction: column; gap: 12px; align-items: flex-start;
1519
+ padding: 15px 18px 17px; border-radius: 14px; background: var(--ak-inset);
1520
+ }
1521
+ .abo-note-text h4 { margin: 0 0 5px; font: 600 12px/1.3 var(--ak-font); }
1522
+ .abo-note-text p { margin: 0; max-width: 64ch; color: var(--ak-ink-quiet); font: 400 12px/1.55 var(--ak-font); }
1523
+ .abo-note-list { margin: 0; display: flex; flex-wrap: wrap; gap: 6px 22px; }
1524
+ .abo-note-list > div { display: flex; flex-direction: column; gap: 2px; }
1525
+ .abo-note-list dt { color: var(--ak-ink-quiet); font: 400 10px/1 var(--ak-font); text-transform: uppercase; letter-spacing: .05em; }
1526
+ .abo-note-list dd { margin: 0; color: var(--ak-ink); font: 500 12px/1.3 var(--ak-font); }
1527
+
1528
+ /* Sotto i 900px la colonna è una sola e il ritratto passa SOPRA la biografia: è l'ordine della
1529
+ pagina vera su schermo stretto (`order: -1` in about.css), ed è la foto ad aprire. */
1530
+ @media (max-width: 900px) {
1531
+ .abo { grid-template-columns: minmax(0, 1fr); }
1532
+ .abo-side { position: static; order: -1; }
1533
+ .abo-side-inner { flex-direction: row; align-items: flex-start; gap: 16px; }
1534
+ .abo-side-inner h3 { flex: none; width: 72px; }
1535
+ .abo-side-inner .pw-media { flex: none; width: 160px; }
1536
+ /* Ruolo e nome si incolonnano invece di stringersi: «Contributor for» in un campo largo
1537
+ ottanta pixel non si legge. Aree esplicite, altrimenti l'auto-placement infila il cestino
1538
+ in una terza riga per conto suo. */
1539
+ .abo-credit-main {
1540
+ grid-template-columns: 26px minmax(0, 1fr) 30px;
1541
+ grid-template-areas: "grip role del" "grip name name";
1542
+ }
1543
+ .abo-credit-main .pw-grip { grid-area: grip; align-self: start; }
1544
+ .abo-credit-main .abo-role { grid-area: role; }
1545
+ .abo-credit-main .abo-name { grid-area: name; }
1546
+ .abo-credit-main .pw-icon-btn { grid-area: del; }
1547
+ }
1548
+
1549
+ /* ---- Workshop: introduzione ed edizioni --------------------------------------------------
1550
+ Quasi tutto è già scritto: la card di un'edizione è `.pw-work` (il guscio condiviso con i
1551
+ lavori, vedi ui/OpenCard.tsx) e i suoi blocchi sono `.pw-card` dentro un `.pw-block`. Qui
1552
+ restano l'introduzione in cima e le due cose che un blocco ha e una card di un lavoro no:
1553
+ il titolo dentro la testata, e nessun segmentato accanto. Vedi routes/WorkshopEditionsEditor.tsx.
1554
+ ------------------------------------------------------------------------------------------ */
1555
+ .ed-workshop { display: flex; flex-direction: column; gap: 16px; }
1556
+ /* Stessa misura e stesso fondo dell'elenco che segue: sono due parti della stessa pagina, non
1557
+ un riquadro appoggiato sopra un elenco. */
1558
+ .wsh-intro {
1559
+ width: min(1080px, 100%); margin: 0 auto;
1560
+ display: flex; flex-direction: column; gap: 12px; padding: 16px 18px 18px;
1561
+ border-radius: 14px; background: var(--ak-panel); box-shadow: var(--ak-lift-1);
1562
+ }
1563
+ .wsh-intro .pw-head { padding: 0; }
1564
+ .ed-workshop .pw { padding-bottom: 56px; }
1565
+
1566
+ /* La testata di un blocco: maniglia, titolo, cestino. Il titolo è un campo VERO e non
1567
+ un'etichetta, perché è l'unica cosa che distingue un blocco dall'altro — ma resta quieto
1568
+ (fondo trasparente finché non lo si tocca), altrimenti sembra la cosa principale. */
1569
+ .wsh-block-head { grid-template-columns: 26px minmax(0, 1fr) 32px; }
1570
+ .wsh-block-title {
1571
+ background: transparent; font: 600 12px/1.3 var(--ak-font);
1572
+ text-transform: uppercase; letter-spacing: .05em;
1573
+ }
1574
+ .wsh-block-title::placeholder { text-transform: none; letter-spacing: 0; font-weight: 400; }
1575
+ .wsh-block-title:hover { background: var(--ak-inset); }
1576
+
1577
+ /* ---- Home: una schermata alla volta -------------------------------------------------------
1578
+ Stessi tre livelli e stessi valori delle altre schermate (`--ak-ground` sotto, `--ak-panel`
1579
+ per i blocchi, `--ak-inset` dentro): qui non si dichiara nessun colore nuovo. Le porte verso
1580
+ le altre pagine riusano le card dei lavori (`.pw-*`), che sono la stessa cosa.
1581
+ Vedi routes/HomeEditor.tsx. --------------------------------------------------------------- */
1582
+ .hm { width: min(1080px, 100%); margin: 0 auto; padding-bottom: 56px; display: flex; flex-direction: column; gap: 16px; }
1583
+ .hm .pw-head { padding: 0 4px; }
1584
+ /* La riga che dice cos'è la schermata sul sito. Il suo NOME sta nella testata del pannello. */
1585
+ .hm-hint { margin: 0 4px; max-width: 76ch; color: var(--ak-ink-quiet); font: 400 12px/1.5 var(--ak-font); }
1586
+ /* L'anteprima del risultato di ricerca è quella della SEO delle pagine (`.seo-search-preview`),
1587
+ riusata invece che ricopiata. Là sta in una riga di griglia alta 166px; qui è in un blocco che
1588
+ si adatta al contenuto, e quel minimo lascerebbe un vuoto bianco sotto il testo. */
1589
+ .hm .seo-search-preview { min-height: 0; }
1590
+
1591
+ /* La foto a sinistra e i testi a destra: è l'impaginazione della schermata vera, e serve a
1592
+ ricordare che quella foto è la protagonista — non un campo come gli altri. */
1593
+ .hm-split { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 18px; align-items: start; }
1594
+ .hm-side { min-width: 0; display: flex; flex-direction: column; gap: 14px; }
1595
+ /* Le anteprime NON si stirano: due sfondi larghi mezzo schermo l'uno sono la cosa più grande
1596
+ della schermata, e non sono la cosa più importante — quello che si modifica qui sono i
1597
+ numeri. Colonne a larghezza fissa, quindi, non `1fr`. */
1598
+ .hm-photos { display: grid; grid-template-columns: repeat(auto-fill, 240px); gap: 18px; align-items: start; }
1599
+ .hm-photo { display: flex; flex-direction: column; gap: 8px; }
1600
+ .hm-photo-label { color: var(--ak-ink); font: 500 11px/1.3 var(--ak-font); }
1601
+ .hm-photo-label small { color: var(--ak-ink-quiet); font-weight: 400; }
1602
+
1603
+ .hm-block {
1604
+ display: flex; flex-direction: column; gap: 12px; padding: 15px 16px 17px;
1605
+ border-radius: 14px; background: var(--ak-panel); box-shadow: var(--ak-lift-1);
1606
+ }
1607
+ .hm-block .pw-block-head { margin-bottom: 2px; }
1608
+ .hm-two { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px 14px; }
1609
+ .hm-head-action { display: flex; justify-content: space-between; align-items: center; }
1610
+
1611
+ /* Le righe di un elenco: maniglia, campi, cestino. Fondo incassato invece che card sollevata —
1612
+ sono voci, non cose. */
1613
+ .hm-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
1614
+ .hm-row {
1615
+ display: grid; grid-template-columns: 26px minmax(0, 1fr) 30px; align-items: center; gap: 8px;
1616
+ padding: 4px 6px 4px 0; border-radius: 10px; background: var(--ak-inset);
1617
+ }
1618
+ .hm-row.is-dragging { z-index: 3; background: var(--ak-panel); box-shadow: var(--ak-lift-3); }
1619
+ .hm-row:hover .pw-grip, .hm-row:focus-within .pw-grip { opacity: .55; }
1620
+ .hm-row .pw-field { background: var(--ak-panel); }
1621
+ /* Due campi in una riga (numero + etichetta): il numero è corto e resta corto. */
1622
+ .hm-row:has(.hm-num) { grid-template-columns: 26px 96px minmax(0, 1fr) 30px; }
1623
+ .hm-num { font: 600 13px/1.4 var(--ak-font-mono); }
1624
+
1625
+ /* L'anteprima del titolo della home: le interruzioni di riga SONO contenuto (una riga più
1626
+ lunga rimpicciolisce tutto il titolo sul sito), e in un elenco di caselle non si vedono. */
1627
+ .hm-title-preview {
1628
+ display: flex; flex-direction: column; gap: 2px; padding: 12px 14px;
1629
+ border-radius: 10px; background: var(--ak-inset); overflow-x: auto;
1630
+ }
1631
+ .hm-title-preview span {
1632
+ white-space: nowrap; color: var(--ak-ink);
1633
+ font: 600 clamp(14px, 2.2vw, 20px)/1.15 var(--ak-font); letter-spacing: -.02em;
1634
+ }
1635
+ .hm-title-preview span.is-empty { color: var(--ak-ink-quiet); font-style: italic; font-weight: 400; }
1636
+
1637
+ /* Le foto che ciclano nell'ultima schermata: una griglia piccola, perché quello che conta è
1638
+ quali sono e in che ordine. */
1639
+ .hm-shots { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
1640
+ .hm-shot { position: relative; margin: 0; }
1641
+ .hm-shot-frame {
1642
+ aspect-ratio: 1; overflow: hidden; border-radius: 10px; background: var(--ak-inset-deep);
1643
+ cursor: grab; touch-action: none;
1644
+ }
1645
+ .hm-shot.is-dragging { z-index: 3; opacity: .9; }
1646
+ .hm-shot-frame img { width: 100%; height: 100%; display: block; object-fit: cover; }
1647
+ .hm-shot-remove {
1648
+ position: absolute; top: 6px; right: 6px; display: grid; place-items: center;
1649
+ width: 26px; height: 26px; border: 0; border-radius: 8px; cursor: pointer;
1650
+ background: color-mix(in srgb, var(--ak-panel) 88%, transparent); color: var(--ak-ink);
1651
+ opacity: 0; transition: opacity .15s, background-color .15s;
1652
+ }
1653
+ .hm-shot:hover .hm-shot-remove, .hm-shot:focus-within .hm-shot-remove { opacity: 1; }
1654
+ .hm-shot-remove:hover { background: var(--ak-danger); color: #fff; }
1655
+ @media (hover: none) { .hm-shot-remove { opacity: 1; } }
1656
+
1657
+ @media (max-width: 900px) {
1658
+ .hm-split { grid-template-columns: minmax(0, 1fr); }
1659
+ .hm-split > .hm-photo { max-width: 260px; }
1660
+ }
1661
+
1662
+ /* ---- Panoramica ------------------------------------------------------------------------
1663
+ Un bento: dodici colonne, riquadri che ne occupano da tre a otto. Gli span stanno in
1664
+ `data-span` e NON in uno stile inline, perché uno stile inline batte qualunque regola di un
1665
+ foglio di stile: su schermo stretto la griglia non potrebbe più collassare, e questo pannello
1666
+ si usa anche dall'iPad.
1667
+
1668
+ I riquadri hanno un raggio più generoso del resto del pannello (12px contro i 6 di
1669
+ `--ak-radius`): è una superficie diversa — si guarda, non si compila — e la differenza è
1670
+ quello che la fa leggere come un cruscotto invece che come un form senza campi.
1671
+ Vedi routes/Overview.tsx. ------------------------------------------------------------ */
1672
+ .ov { display: flex; flex-direction: column; gap: 14px; }
1673
+ .ov-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
1674
+ .ov-bar-hi { margin: 0; color: var(--ak-ink-quiet); font: 400 13px/1.4 var(--ak-font); }
1675
+
1676
+ /* `dense`: quando la griglia collassa, un riquadro che ci sta va a riempire il buco lasciato da
1677
+ uno più largo invece di andare a capo. A larghezza piena non cambia niente — le righe tornano
1678
+ esatte (3+3+3+3, 8+4, 7+5, 6+6) — ma a 1024px il grafico prende dodici colonne e senza questo
1679
+ accanto agli «Archivi» resterebbe mezza riga vuota, con l'elenco dei transfer buttato sotto. */
1680
+ .ov-grid {
1681
+ display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
1682
+ grid-auto-flow: row dense; gap: 12px;
1683
+ }
1684
+ .ov-grid > [data-span="3"] { grid-column: span 3; }
1685
+ .ov-grid > [data-span="4"] { grid-column: span 4; }
1686
+ .ov-grid > [data-span="5"] { grid-column: span 5; }
1687
+ .ov-grid > [data-span="6"] { grid-column: span 6; }
1688
+ .ov-grid > [data-span="7"] { grid-column: span 7; }
1689
+ .ov-grid > [data-span="8"] { grid-column: span 8; }
1690
+
1691
+ /* Si distingue dal fondo per TONO, non per ombra: il pane della Panoramica sta su `--ak-ground`
1692
+ (vedi la regola `.pane-body:has(.ov)` più sopra), quindi il pannello `--ak-panel` della card
1693
+ contrasta già di per sé — la stessa leva usata da `.ed-portfolio`/`.ed-gallery`. */
1694
+ .ov-tile {
1695
+ min-width: 0; display: flex; flex-direction: column; text-align: left;
1696
+ background: var(--ak-panel); border: 0; border-radius: 14px;
1697
+ color: var(--ak-ink); font: inherit; transition: filter .15s;
1698
+ }
1699
+ .ov-tile-head {
1700
+ display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
1701
+ padding: 15px 16px 12px;
1702
+ }
1703
+ .ov-tile-head h2 { margin: 0; font: 600 13px/1.2 var(--ak-font); }
1704
+ .ov-tile-head p { margin: 4px 0 0; color: var(--ak-ink-quiet); font: 400 11px/1.35 var(--ak-font); }
1705
+ .ov-pad { margin: 0; padding: 0 16px 16px; }
1706
+ .ov-more, .ov-link {
1707
+ flex: none; border: 0; background: transparent; cursor: pointer; padding: 0;
1708
+ color: var(--ak-ink-quiet); font: 500 11px/1 var(--ak-font);
1709
+ }
1710
+ .ov-more:hover, .ov-link:hover { color: var(--ak-accent); text-decoration: underline; }
1711
+
1712
+ /* La riga di sopra: una cifra sola per riquadro */
1713
+ .ov-stat { gap: 5px; padding: 15px 16px 16px; }
1714
+ .ov-stat.is-link { cursor: pointer; }
1715
+ /* Stesso principio del bottone Consegne (`.ov-cta:hover`, sotto): un cambio di tono, non
1716
+ un'ombra. Scurire invece di schiarire funziona su un pannello chiaro E su uno scuro. */
1717
+ .ov-stat.is-link:hover { filter: brightness(.97); }
1718
+ .ov-stat-icon {
1719
+ width: 30px; height: 30px; margin-bottom: 2px; flex: none;
1720
+ display: grid; place-items: center; border-radius: 9px;
1721
+ }
1722
+ .ov-stat-icon.is-accent { background: color-mix(in srgb, var(--ak-accent) 14%, var(--ak-panel)); color: var(--ak-accent); }
1723
+ .ov-stat-icon.is-green { background: color-mix(in srgb, #2f8b62 14%, var(--ak-panel)); color: #2f8b62; }
1724
+ .ov-stat-icon.is-blue { background: color-mix(in srgb, #3978b8 14%, var(--ak-panel)); color: #3978b8; }
1725
+ .ov-stat-icon.is-quiet { background: var(--ak-inset); color: var(--ak-ink-quiet); }
1726
+ .ov-stat-label {
1727
+ color: var(--ak-ink-quiet); font: 600 10px/1 var(--ak-font);
1728
+ letter-spacing: .1em; text-transform: uppercase;
1729
+ }
1730
+ .ov-stat-value {
1731
+ margin-top: 3px; font: 600 27px/1.1 var(--ak-font); letter-spacing: -.02em;
1732
+ font-variant-numeric: tabular-nums;
1733
+ }
1734
+ .ov-stat-foot {
1735
+ display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
1736
+ color: var(--ak-ink-quiet); font: 400 11px/1.3 var(--ak-font);
1737
+ }
1738
+ .ov-stat-quiet { font-style: normal; color: var(--ak-ink-faint, var(--ak-ink-quiet)); }
1739
+
1740
+ .ov-delta {
1741
+ display: inline-flex; align-items: center; gap: 3px; padding: 2px 6px; border-radius: 20px;
1742
+ font: 600 10px/1.3 var(--ak-font); font-style: normal; font-variant-numeric: tabular-nums;
1743
+ }
1744
+ .ov-delta.is-up { color: #226c4c; background: color-mix(in srgb,#2f8b62 13%,var(--ak-panel)); }
1745
+ .ov-delta.is-down { color: #97392b; background: color-mix(in srgb,var(--ak-accent) 12%,var(--ak-panel)); }
1746
+
1747
+ /* ---- Tonalità di stato per il tema scuro -------------------------------------------------
1748
+ La formula testo-scuro-fisso + color-mix(…, var(--ak-panel)) funziona su un pannello quasi
1749
+ bianco; su un pannello quasi nero un testo anch'esso scuro sparisce nel fondo. In scuro serve
1750
+ una tinta più CHIARA per il testo e un mix più forte per il fondo — verificato ≥5:1. */
1751
+ [data-theme="dark"] .dl-pill.is-ready, [data-theme="dark"] .ov-stat-icon.is-green
1752
+ { color: #8fe0b5; background: color-mix(in srgb, #2f8b62 22%, var(--ak-panel)); }
1753
+ [data-theme="dark"] .dl-pill.is-downloaded, [data-theme="dark"] .ov-stat-icon.is-blue
1754
+ { color: #9dc9f1; background: color-mix(in srgb, #3978b8 22%, var(--ak-panel)); }
1755
+ [data-theme="dark"] .dl-pill.is-expiring
1756
+ { color: #f4c988; background: color-mix(in srgb, #d28b27 22%, var(--ak-panel)); }
1757
+ [data-theme="dark"] .dl-pill.is-uploading, [data-theme="dark"] .ov-stat-icon.is-accent
1758
+ { color: #f5b39a; background: color-mix(in srgb, var(--ak-accent) 22%, var(--ak-panel)); }
1759
+ [data-theme="dark"] .ov-delta.is-up { color: #8fe0b5; background: color-mix(in srgb, #2f8b62 20%, var(--ak-panel)); }
1760
+ [data-theme="dark"] .ov-delta.is-down { color: #f5b39a; background: color-mix(in srgb, var(--ak-accent) 20%, var(--ak-panel)); }
1761
+
1762
+ /* La scorciatoia alle Consegne. È l'unico riquadro colorato della schermata: se ce ne fosse un
1763
+ secondo smetterebbe di essere quello che si nota. */
1764
+ .ov-cta {
1765
+ position: relative; overflow: hidden; cursor: pointer; justify-content: space-between;
1766
+ padding: 15px 16px 16px; border-color: transparent;
1767
+ background: linear-gradient(122deg, var(--ak-accent) 0%, #c95b34 52%, #d9834a 100%);
1768
+ color: #fff;
1769
+ }
1770
+ .ov-cta:hover { filter: brightness(1.06); }
1771
+ .ov-cta-copy { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 4px; }
1772
+ .ov-cta-copy strong { font: 600 15px/1.2 var(--ak-font); }
1773
+ .ov-cta-copy span { font: 400 11px/1.35 var(--ak-font); opacity: .82; }
1774
+ .ov-cta-go {
1775
+ position: absolute; z-index: 2; top: 13px; right: 13px;
1776
+ width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%;
1777
+ background: rgba(255,255,255,.2);
1778
+ }
1779
+ /* Le barrette in basso a destra sono decorazione, e si comportano come tale: `aria-hidden`,
1780
+ nessun dato dietro. Suggeriscono "qui si misura qualcosa" senza fingere un grafico vero. */
1781
+ .ov-cta-bars {
1782
+ position: absolute; z-index: 1; right: 0; bottom: 0; left: 42%; height: 54%;
1783
+ display: flex; align-items: flex-end; gap: 3px; padding: 0 12px 12px; opacity: .5;
1784
+ }
1785
+ .ov-cta-bars i { flex: 1; min-width: 0; border-radius: 2px 2px 0 0; background: rgba(255,255,255,.75); }
1786
+ .ov-cta-badge {
1787
+ position: relative; z-index: 2; align-self: flex-start; margin-top: 10px;
1788
+ padding: 3px 8px; border-radius: 20px; background: rgba(0,0,0,.22);
1789
+ font: 600 10px/1.4 var(--ak-font);
1790
+ }
1791
+
1792
+ /* Le visite */
1793
+ .ov-range { flex: none; display: flex; gap: 2px; padding: 2px; border-radius: 7px; background: var(--ak-bg); }
1794
+ .ov-range-btn {
1795
+ border: 0; border-radius: 5px; background: transparent; cursor: pointer; padding: 5px 9px;
1796
+ color: var(--ak-ink-quiet); font: 500 11px/1 var(--ak-font);
1797
+ }
1798
+ .ov-range-btn:hover { color: var(--ak-ink); }
1799
+ .ov-range-btn.is-on { background: var(--ak-panel); color: var(--ak-ink); box-shadow: var(--ak-shadow); }
1800
+
1801
+ .ov-chart-figures {
1802
+ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px;
1803
+ padding: 4px 16px 14px;
1804
+ }
1805
+ .ov-figure { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
1806
+ .ov-figure > span { color: var(--ak-ink-quiet); font: 400 10px/1.2 var(--ak-font); }
1807
+ .ov-figure strong { font: 600 18px/1.15 var(--ak-font); font-variant-numeric: tabular-nums; }
1808
+ .ov-figure .ov-delta { align-self: flex-start; }
1809
+
1810
+ /* Margini e non padding: il tooltip è posizionato in pixel a partire dal bordo del riquadro
1811
+ (`left: <x>px`, con la stessa x del punto sul grafico), e `left` di un elemento assoluto parte
1812
+ dal padding box — cioè PRIMA dell'eventuale padding. Con un padding qui, riquadretto e punto
1813
+ risulterebbero sfalsati esattamente di quel valore. */
1814
+ .ov-plot { position: relative; margin: 0 16px; padding-bottom: 12px; }
1815
+ /* La larghezza la decide il ResizeObserver e finisce nell'attributo `width`; qui c'è solo la
1816
+ garanzia che l'elemento non superi la sua colonna mentre la misura si aggiorna. */
1817
+ .ov-plot-svg { max-width: 100%; display: block; overflow: visible; }
1818
+ .ov-plot-grid { stroke: var(--ak-line); stroke-width: 1; opacity: .7; }
1819
+ .ov-plot-tick { fill: var(--ak-ink-quiet); font: 400 9px var(--ak-font); }
1820
+ .ov-plot-line { fill: none; stroke: var(--ak-accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
1821
+ .ov-plot-line.is-second { stroke: var(--ak-ink); stroke-width: 1.25; opacity: .35; stroke-dasharray: 3 3; }
1822
+ .ov-plot-cursor { stroke: var(--ak-ink); stroke-width: 1; opacity: .28; }
1823
+ .ov-plot-dot { fill: var(--ak-ink); stroke: var(--ak-panel); stroke-width: 2; }
1824
+ /* `left` e `transform` arrivano inline da Overview.tsx e si spostano col punto: qui c'è solo
1825
+ l'aspetto. Il valore di partenza serve al primo fotogramma, prima che React scriva il suo. */
1826
+ .ov-plot-tip {
1827
+ position: absolute; z-index: 3; top: 2px; transform: translateX(-50%);
1828
+ display: flex; flex-direction: column; gap: 2px; white-space: nowrap; pointer-events: none;
1829
+ padding: 7px 10px; border: 1px solid var(--ak-line); border-radius: 7px;
1830
+ background: var(--ak-panel); box-shadow: 0 10px 26px rgba(0,0,0,.14);
1831
+ }
1832
+ .ov-plot-tip strong { font: 600 11px/1.2 var(--ak-font); }
1833
+ .ov-plot-tip span { color: var(--ak-ink-quiet); font: 400 10px/1.2 var(--ak-font); }
1834
+ .ov-plot-legend { display: flex; gap: 14px; margin: 6px 0 0; }
1835
+ .ov-key {
1836
+ display: inline-flex; align-items: center; gap: 6px;
1837
+ color: var(--ak-ink-quiet); font: 400 10px/1 var(--ak-font);
1838
+ }
1839
+ .ov-key::before { content: ""; width: 11px; height: 2px; border-radius: 2px; background: var(--ak-accent); }
1840
+ .ov-key.is-second::before { background: var(--ak-ink); opacity: .35; }
1841
+
1842
+ /* Gli archivi. Il riquadro sta accanto al grafico, quindi è alto quanto lui: le tre righe si
1843
+ distribuiscono nello spazio (`space-evenly`) e le note restano in fondo, invece di lasciare
1844
+ mezzo riquadro bianco sotto un contenuto schiacciato in cima. */
1845
+ .ov-store { flex: 1; display: flex; flex-direction: column; gap: 14px; padding: 2px 16px 16px; }
1846
+ .ov-store-rows { flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; gap: 16px; }
1847
+ .ov-store-row {
1848
+ display: flex; flex-direction: column; gap: 6px; width: 100%; text-align: left;
1849
+ border: 0; background: transparent; cursor: pointer; padding: 0; color: inherit; font: inherit;
1850
+ }
1851
+ .ov-store-row:hover .ov-store-name { color: var(--ak-accent); }
1852
+ .ov-store-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
1853
+ .ov-store-name { display: inline-flex; align-items: center; gap: 6px; font: 500 12px/1.2 var(--ak-font); }
1854
+ .ov-store-name em {
1855
+ font: 600 9px/1 var(--ak-font-mono); font-style: normal; letter-spacing: .06em;
1856
+ color: var(--ak-ink-quiet); border: 1px solid var(--ak-line); border-radius: 3px; padding: 2px 4px;
1857
+ }
1858
+ .ov-store-top strong { font: 600 13px/1.2 var(--ak-font); font-variant-numeric: tabular-nums; }
1859
+ .ov-store-track { height: 6px; overflow: hidden; border-radius: 4px; background: var(--ak-bg); }
1860
+ /* `min-width` in pixel e non in percentuale: una quota dello 0,05% sparirebbe del tutto, e una
1861
+ barra assente si legge come «non misurato» invece che «quasi niente». Il minimo è un trattino
1862
+ sottile, non un pallino — con il raggio pieno su una larghezza di 5px diventava un punto, che
1863
+ sembrava un errore di disegno. La cifra esatta è comunque scritta accanto. */
1864
+ .ov-store-track i {
1865
+ display: block; height: 100%; min-width: 3px; border-radius: 1.5px; background: var(--ak-accent);
1866
+ }
1867
+ .ov-store-rows .ov-store-row:nth-child(2) .ov-store-track i { background: var(--ak-ink); opacity: .55; }
1868
+ .ov-store-rows .ov-store-row:nth-child(3) .ov-store-track i { background: var(--ak-ink); opacity: .25; }
1869
+ .ov-store-detail {
1870
+ display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
1871
+ color: var(--ak-ink-quiet); font: 400 10px/1.3 var(--ak-font);
1872
+ }
1873
+ .ov-store-detail > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1874
+ .ov-store-detail em {
1875
+ flex: none; font-style: normal; font-variant-numeric: tabular-nums; font-weight: 500;
1876
+ }
1877
+ .ov-store-notes {
1878
+ display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 5px 10px; margin: 0;
1879
+ padding-top: 12px; border-top: 1px solid var(--ak-line);
1880
+ }
1881
+ .ov-store-notes:empty { display: none; }
1882
+ .ov-store-notes dt { color: var(--ak-ink-quiet); font: 500 10px/1.4 var(--ak-font); }
1883
+ .ov-store-notes dd { margin: 0; font: 400 10px/1.4 var(--ak-font); }
1884
+
1885
+ /* Gli ultimi transfer */
1886
+ .ov-table { width: 100%; border-collapse: collapse; }
1887
+ .ov-table th {
1888
+ padding: 0 16px 8px; text-align: left; color: var(--ak-ink-quiet);
1889
+ font: 600 9px/1 var(--ak-font); letter-spacing: .09em; text-transform: uppercase;
1890
+ }
1891
+ .ov-table tbody tr { cursor: pointer; border-top: 1px solid var(--ak-line); }
1892
+ .ov-table tbody tr:hover { background: var(--ak-hover); }
1893
+ .ov-table td { padding: 9px 16px; vertical-align: middle; }
1894
+ .ov-table tbody tr:last-child td { padding-bottom: 13px; }
1895
+ .ov-table td:first-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
1896
+ .ov-row-main { overflow: hidden; font: 500 12px/1.3 var(--ak-font); text-overflow: ellipsis; white-space: nowrap; }
1897
+ .ov-row-sub { color: var(--ak-ink-quiet); font: 400 10px/1.3 var(--ak-font); }
1898
+ .ov-when { color: var(--ak-ink-quiet); font: 400 11px/1.2 var(--ak-font-mono); white-space: nowrap; }
1899
+ .ov-num { text-align: right; font: 600 13px/1.2 var(--ak-font); font-variant-numeric: tabular-nums; }
1900
+ .ov-num.is-zero { color: var(--ak-ink-quiet); font-weight: 400; }
1901
+ .ov-state { text-align: right; white-space: nowrap; }
1902
+
1903
+ /* L'ultima richiesta. `flex: 1` più `margin-top: auto` sui bottoni: il riquadro è alto quanto
1904
+ quello dei transfer che gli sta accanto, e un messaggio corto lasciava «Rispondi» a mezz'aria
1905
+ in mezzo al bianco. */
1906
+ .ov-req { flex: 1; display: flex; flex-direction: column; gap: 10px; padding: 2px 16px 16px; }
1907
+ .ov-req.is-handled .ov-req-msg { opacity: .6; }
1908
+ .ov-req-head { display: flex; align-items: center; gap: 10px; }
1909
+ .ov-req-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
1910
+ .ov-req-who strong { overflow: hidden; font: 600 13px/1.2 var(--ak-font); text-overflow: ellipsis; white-space: nowrap; }
1911
+ .ov-req-who a {
1912
+ overflow: hidden; color: var(--ak-accent); font: 400 11px/1.3 var(--ak-font);
1913
+ text-decoration: none; text-overflow: ellipsis; white-space: nowrap;
1914
+ }
1915
+ .ov-req-who a:hover { text-decoration: underline; }
1916
+ .ov-req-when { flex: none; color: var(--ak-ink-quiet); font: 400 10px/1.2 var(--ak-font-mono); }
1917
+ /* Quattro righe e poi sfuma: il messaggio intero sta nella sua sezione, e un troncamento netto
1918
+ a metà parola fa sembrare che manchi qualcosa invece di dire che continua. */
1919
+ .ov-req-msg {
1920
+ display: -webkit-box; margin: 0; overflow: hidden; -webkit-box-orient: vertical;
1921
+ -webkit-line-clamp: 4; white-space: pre-wrap;
1922
+ font: 400 12px/1.55 var(--ak-font); color: var(--ak-ink);
1923
+ }
1924
+ .ov-req-actions { margin-top: auto; padding-top: 4px; display: flex; align-items: center; gap: 8px; }
1925
+
1926
+ /* Le classifiche */
1927
+ .ov-top { list-style: none; margin: 0; padding: 2px 16px 16px; display: flex; flex-direction: column; gap: 9px; }
1928
+ /* Le classifiche stanno su quattro colonne, non sei: la barra si stringe e i numeri si
1929
+ avvicinano, altrimenti un titolo di pagina un po' lungo viene troncato a metà. */
1930
+ .ov-top li {
1931
+ display: grid; grid-template-columns: minmax(0, 1fr) 56px 36px; gap: 8px; align-items: center;
1932
+ }
1933
+ .ov-top-name { overflow: hidden; font: 400 12px/1.3 var(--ak-font); text-overflow: ellipsis; white-space: nowrap; }
1934
+ .ov-top-track { height: 5px; overflow: hidden; border-radius: 3px; background: var(--ak-bg); }
1935
+ .ov-top-track i { display: block; height: 100%; border-radius: 3px; background: var(--ak-accent); opacity: .75; }
1936
+ .ov-top-count {
1937
+ text-align: right; color: var(--ak-ink-quiet);
1938
+ font: 500 11px/1.2 var(--ak-font); font-variant-numeric: tabular-nums;
1939
+ }
1940
+
1941
+ /* Una funzione non attiva. Il riquadro resta un riquadro come gli altri — stesso bordo, stesso
1942
+ raggio, stesso titolo: se fosse tratteggiato o grigio sembrerebbe un errore invece di una
1943
+ cosa che si può avere. Il contenuto si centra nello spazio che avanza, così il pulsante sta
1944
+ dove cade l'occhio anche quando la card accanto è alta il doppio. */
1945
+ .ov-locked-body {
1946
+ flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
1947
+ gap: 12px; padding: 8px 16px 26px; text-align: center;
1948
+ }
1949
+ .ov-locked-body p { margin: 0; color: var(--ak-ink-quiet); font: 400 12px/1.5 var(--ak-font); }
1950
+ .ov-locked-body .ak-btn { padding-inline: 22px; }
1951
+
1952
+ /* I prossimi appuntamenti */
1953
+ .ov-bookings { list-style: none; margin: 0; padding: 2px 10px 14px; display: flex; flex-direction: column; gap: 2px; }
1954
+ .ov-bookings button {
1955
+ display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 8px; width: 100%;
1956
+ border: 0; border-radius: 7px; background: transparent; cursor: pointer; text-align: left;
1957
+ padding: 8px 6px; color: inherit; font: inherit;
1958
+ }
1959
+ .ov-bookings button:hover { background: var(--ak-hover); }
1960
+ .ov-book-when {
1961
+ grid-column: 1 / -1; color: var(--ak-ink-quiet);
1962
+ font: 500 10px/1.2 var(--ak-font-mono); text-transform: lowercase;
1963
+ }
1964
+ .ov-book-who { min-width: 0; overflow: hidden; font: 500 12px/1.3 var(--ak-font); text-overflow: ellipsis; white-space: nowrap; }
1965
+ .ov-book-what {
1966
+ grid-column: 1; min-width: 0; overflow: hidden; color: var(--ak-ink-quiet);
1967
+ font: 400 10px/1.3 var(--ak-font); text-overflow: ellipsis; white-space: nowrap;
1968
+ }
1969
+ .ov-bookings .dl-pill { grid-row: 2; grid-column: 2; align-self: center; }
1970
+
1971
+ /* Statistiche non collegate */
1972
+ .ov-setup { display: flex; flex-direction: column; gap: 8px; padding: 2px 16px 16px; }
1973
+ .ov-setup-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 10px; }
1974
+ .ov-setup-item { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
1975
+ .ov-setup-item > strong { font: 600 12px/1.2 var(--ak-font); }
1976
+ .ov-setup-ok { color: #226c4c; font: 500 11px/1.4 var(--ak-font); }
1977
+ .ov-setup p { margin: 0; color: var(--ak-ink-quiet); font: 400 12px/1.5 var(--ak-font); }
1978
+ .ov-setup p strong { color: var(--ak-ink); }
1979
+ /* I comandi VANNO A CAPO invece di scorrere in orizzontale: affiancando due servizi la colonna
1980
+ è stretta, e con `overflow-x` la metà destra di `wrangler pages secret put …` resta nascosta
1981
+ dietro un bordo — cioè proprio il pezzo da copiare. Il `\` di continuazione è già nel testo,
1982
+ quindi anche copiato a capo resta un comando valido. */
1983
+ .ov-setup pre {
1984
+ margin: 4px 0 0; padding: 11px 12px; white-space: pre-wrap; overflow-wrap: anywhere;
1985
+ border: 1px solid var(--ak-line); border-radius: 7px; background: var(--ak-bg);
1986
+ color: var(--ak-ink-quiet); font: 400 11px/1.6 var(--ak-font-mono);
1987
+ }
1988
+
1989
+ @media (max-width: 1240px) {
1990
+ .ov-grid > [data-span="7"], .ov-grid > [data-span="8"] { grid-column: span 12; }
1991
+ .ov-grid > [data-span="4"], .ov-grid > [data-span="5"] { grid-column: span 6; }
1992
+ }
1993
+ @media (max-width: 900px) {
1994
+ .ov-grid > [data-span] { grid-column: span 6; }
1995
+ .ov-chart-figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1996
+ }
1997
+ @media (max-width: 620px) {
1998
+ .ov-grid > [data-span] { grid-column: span 12; }
1999
+ }
2000
+
2001
+ /* ---- Schermi stretti (l'iPad in orizzontale è il caso reale) ---------------------------- */
2002
+ @media (max-width: 1040px) {
2003
+ .app { grid-template-columns: 52px var(--ak-col-w) minmax(0, 1fr); }
2004
+ .app.is-two { grid-template-columns: 52px minmax(0, 1fr); }
2005
+ .rail { padding: 14px 8px; align-items: center; }
2006
+ .rail-brand, .rail-item span, .rail-group-title { display: none; }
2007
+ .rail-item { justify-content: center; padding: 9px; }
2008
+ .rail-foot { width: 100%; }
2009
+ .pe-head-main { gap: 12px; }
2010
+ .pe-title { max-width: 25vw; }
2011
+ .pe-photo-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap-inline: 18px; }
2012
+ }
2013
+
2014
+ @media (max-width: 1280px) {
2015
+ .seo-section-heading,
2016
+ .seo-row { grid-template-columns: 110px minmax(0, 1fr); }
2017
+ .seo-section-heading > div { grid-column: 2; }
2018
+ .seo-row > .seo-field,
2019
+ .seo-row > .seo-help { grid-column: 2; }
2020
+ .seo-help { padding-top: 0; }
2021
+ }
2022
+
2023
+ @media (max-width: 900px) {
2024
+ .settings-editor { padding-inline: 6px; gap: 34px; }
2025
+ .st-row { grid-template-columns: minmax(0, 1fr); gap: 15px; padding: 22px 0; }
2026
+ .seo-editor { padding-inline: 6px; }
2027
+ .seo-section-heading,
2028
+ .seo-row { grid-template-columns: minmax(0, 1fr); gap: 12px; }
2029
+ .seo-section-heading > div,
2030
+ .seo-row > .seo-field,
2031
+ .seo-row > .seo-help,
2032
+ .seo-preview-row > * { grid-column: 1; }
2033
+ .seo-row-label { font-weight: 600; }
2034
+ }
2035
+
2036
+ /* ---- Una funzione aggiuntiva spenta ---------------------------------------------------------
2037
+ Non è una schermata d'errore e non deve sembrarlo: la funzione non è rotta, semplicemente non
2038
+ è stata attivata. Quindi niente rosso, niente icone d'allarme — la stessa impaginazione
2039
+ tranquilla delle altre schermate introduttive del pannello.
2040
+ -------------------------------------------------------------------------------------------- */
2041
+ .feature-off {
2042
+ max-width: 46rem; margin: 0 auto; padding: 48px 28px;
2043
+ }
2044
+ .feature-off-kicker {
2045
+ display: block; margin-bottom: 10px;
2046
+ font: 600 11px/1 var(--ak-font); letter-spacing: .08em; text-transform: uppercase;
2047
+ color: var(--ak-ink-quiet);
2048
+ }
2049
+ .feature-off h2 { margin: 0 0 12px; font: 600 26px/1.15 var(--ak-font); color: var(--ak-ink); }
2050
+ .feature-off-lead { margin: 0 0 24px; font: 400 15px/1.6 var(--ak-font); color: var(--ak-ink-quiet); }
2051
+ .feature-off ul { margin: 0 0 28px; padding: 0; list-style: none; display: grid; gap: 10px; }
2052
+ .feature-off li {
2053
+ position: relative; padding-left: 26px;
2054
+ font: 400 14px/1.5 var(--ak-font); color: var(--ak-ink);
2055
+ }
2056
+ /* Il segno di spunta è disegnato, non un carattere: un'emoji cambia forma e colore da un sistema
2057
+ all'altro, e qui deve restare dello stesso accento del resto del pannello. */
2058
+ .feature-off li::before {
2059
+ content: ""; position: absolute; left: 4px; top: 6px;
2060
+ width: 9px; height: 5px; border-left: 2px solid var(--ak-accent); border-bottom: 2px solid var(--ak-accent);
2061
+ transform: rotate(-45deg);
2062
+ }
2063
+ .feature-off-cta {
2064
+ margin: 0; padding: 18px 20px; border-radius: var(--ak-radius);
2065
+ background: var(--ak-inset); box-shadow: var(--ak-shadow);
2066
+ font: 400 14px/1.6 var(--ak-font); color: var(--ak-ink);
2067
+ }
2068
+ .feature-off-cta a { color: var(--ak-accent); text-decoration: underline; text-underline-offset: 2px; }