@acms-subir/core 0.3.6 → 0.3.8

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 (116) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/integration.mjs +38 -2
  3. package/package.json +1 -1
  4. package/src/actions/index.ts +146 -2
  5. package/src/components/EmailSettings.tsx +6 -0
  6. package/src/components/EventPage.astro +25 -5
  7. package/src/components/booking/DurationEditor.astro +156 -0
  8. package/src/components/calendar/BookingsHead.astro +4 -3
  9. package/src/components/calendar/RoomHolds.tsx +13 -8
  10. package/src/components/editor/EventPanel.tsx +9 -383
  11. package/src/components/editor/LivePane.tsx +16 -3
  12. package/src/components/editor/PostEditor.tsx +59 -46
  13. package/src/components/editor/PreviewOverlay.tsx +7 -1
  14. package/src/components/editor/event/EventSheet.tsx +136 -0
  15. package/src/components/editor/event/LocationField.tsx +266 -0
  16. package/src/components/editor/event/OrganizeCard.tsx +87 -0
  17. package/src/components/editor/event/RegistrationCard.tsx +114 -0
  18. package/src/components/editor/event/RegistrationFormEditor.tsx +142 -0
  19. package/src/components/editor/event/Section.tsx +27 -0
  20. package/src/components/editor/event/WhenCard.tsx +217 -0
  21. package/src/components/editor/event/dates.ts +28 -0
  22. package/src/components/editor/event/registration.ts +39 -0
  23. package/src/components/editor/extensions/form.tsx +60 -0
  24. package/src/components/editor/extensions/slash.tsx +5 -0
  25. package/src/components/editor/frameNav.ts +20 -0
  26. package/src/components/forms/Canvas.tsx +149 -0
  27. package/src/components/forms/FormBuildPage.tsx +155 -0
  28. package/src/components/forms/FormBuilder.tsx +283 -0
  29. package/src/components/forms/FormHeader.astro +31 -0
  30. package/src/components/forms/InsertMenu.tsx +77 -0
  31. package/src/components/forms/Inspector.tsx +232 -0
  32. package/src/components/forms/Outline.tsx +93 -0
  33. package/src/components/forms/ResponsesTable.tsx +123 -0
  34. package/src/components/forms/TypeIcon.tsx +24 -0
  35. package/src/components/forms/dnd.ts +3 -0
  36. package/src/components/forms/meta.ts +84 -0
  37. package/src/components/forms/useFormHistory.ts +41 -0
  38. package/src/layouts/Admin.astro +3 -2
  39. package/src/lib/backup/content.ts +10 -5
  40. package/src/lib/booking/forms.ts +67 -0
  41. package/src/lib/booking/service.ts +6 -2
  42. package/src/lib/calendar/agent-schema.ts +7 -1
  43. package/src/lib/calendar/agent.ts +28 -3
  44. package/src/lib/calendar/api.ts +2 -0
  45. package/src/lib/calendar/ics-write.ts +2 -0
  46. package/src/lib/calendar/ics.ts +4 -0
  47. package/src/lib/calendar/import.ts +3 -3
  48. package/src/lib/calendar/schedule.ts +6 -2
  49. package/src/lib/calendar/seo.ts +4 -1
  50. package/src/lib/content-service.ts +30 -4
  51. package/src/lib/drafts.ts +9 -1
  52. package/src/lib/dynamicBlocks.ts +14 -3
  53. package/src/lib/editor/documents.ts +12 -3
  54. package/src/lib/editor/schemas.ts +4 -3
  55. package/src/lib/email/readiness.ts +14 -0
  56. package/src/lib/email/service.ts +8 -3
  57. package/src/lib/email/templates.ts +8 -2
  58. package/src/lib/email/types.ts +1 -0
  59. package/src/lib/forms/events.ts +40 -0
  60. package/src/lib/forms/export.ts +62 -0
  61. package/src/lib/forms/fields.ts +50 -0
  62. package/src/lib/forms/http.ts +29 -0
  63. package/src/lib/forms/render.ts +11 -0
  64. package/src/lib/forms/schema.ts +56 -0
  65. package/src/lib/forms/service.ts +38 -0
  66. package/src/lib/forms/store.ts +78 -0
  67. package/src/lib/forms/validate.ts +71 -0
  68. package/src/lib/maps/config.ts +64 -0
  69. package/src/lib/maps/migration.ts +12 -0
  70. package/src/lib/maps/parse.ts +180 -0
  71. package/src/lib/maps/places.ts +109 -0
  72. package/src/lib/maps/providers/geoapify.ts +36 -0
  73. package/src/lib/maps/providers/google.ts +54 -0
  74. package/src/lib/maps/providers/http.ts +96 -0
  75. package/src/lib/maps/providers/index.ts +37 -0
  76. package/src/lib/maps/providers/locationiq.ts +35 -0
  77. package/src/lib/maps/providers/mapbox.ts +38 -0
  78. package/src/lib/maps/providers/osm.ts +59 -0
  79. package/src/lib/maps/providers/pelias.ts +51 -0
  80. package/src/lib/maps/service.ts +281 -0
  81. package/src/lib/maps/types.ts +35 -0
  82. package/src/lib/mobile/bookings.ts +1 -1
  83. package/src/lib/mobile/schemas.ts +2 -2
  84. package/src/lib/repo/migrations.ts +8 -0
  85. package/src/lib/repo/sql.ts +99 -10
  86. package/src/lib/repo/types.ts +21 -1
  87. package/src/lib/schema.ts +38 -0
  88. package/src/lib/umami.ts +8 -1
  89. package/src/pages/admin/calendar/bookings.astro +23 -12
  90. package/src/pages/admin/calendar/events/[id].astro +5 -2
  91. package/src/pages/admin/calendar/events/index.astro +3 -0
  92. package/src/pages/admin/calendar/resources/[id].astro +11 -0
  93. package/src/pages/admin/calendar/resources/link.astro +95 -49
  94. package/src/pages/admin/calendar/settings.astro +140 -3
  95. package/src/pages/admin/forms/[id]/share.astro +121 -0
  96. package/src/pages/admin/forms/[id]/submissions.astro +143 -0
  97. package/src/pages/admin/forms/[id].astro +27 -0
  98. package/src/pages/admin/forms/index.astro +198 -0
  99. package/src/pages/admin/integrations.astro +57 -0
  100. package/src/pages/admin/settings.astro +1 -1
  101. package/src/pages/api/agent/index.ts +1 -1
  102. package/src/pages/api/calendar/docs.ts +2 -0
  103. package/src/pages/api/calendar/events/[id].ts +1 -1
  104. package/src/pages/api/calendar/events/index.ts +1 -1
  105. package/src/pages/api/email/settings.ts +4 -2
  106. package/src/pages/api/mcp.ts +1 -1
  107. package/src/pages/book/manage/[token].astro +4 -4
  108. package/src/pages/events/[slug].astro +24 -10
  109. package/src/pages/forms/[id].astro +27 -0
  110. package/src/styles/admin.css +2 -2
  111. package/src/styles/editor.css +275 -34
  112. package/src/styles/form-block.css +38 -0
  113. package/src/styles/forms-admin.css +184 -0
  114. package/src/styles/forms.css +281 -0
  115. package/src/styles/site.css +43 -0
  116. package/src/virtual.d.ts +2 -0
@@ -0,0 +1,184 @@
1
+ /* Forms admin: shared form header, forms list + New form gallery, Responses
2
+ table + drawer, Share tab. Admin tokens only (see DESIGN.md). */
3
+
4
+ /* status: coloured text led by a 7px rounded-square marker (never a pill) */
5
+ .fst { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; white-space: nowrap; margin: 0; }
6
+ .fst > i { width: 7px; height: 7px; border-radius: 2px; background: currentColor; flex: 0 0 auto; }
7
+ .fst-green { color: var(--green); }
8
+ .fst-amber { color: var(--amber); }
9
+ .fst-muted { color: var(--muted); }
10
+
11
+ /* ---- one form: breadcrumb, name + status, Build · Responses · Share ---- */
12
+ .fh { margin-bottom: 18px; }
13
+ .fh-crumb { margin: 0 0 4px; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
14
+ .fh-crumb a { color: var(--muted); }
15
+ .fh-crumb a:hover { color: var(--text); }
16
+ .fh-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
17
+ .fh-row h1 { margin: 0; min-width: 0; overflow-wrap: anywhere; }
18
+ .fh-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
19
+ .fh-actions:empty { display: none; }
20
+ .fh-tabs { margin: 0; }
21
+
22
+ /* ---- forms list: Ghost-style rows ---- */
23
+ .fl { margin-top: -6px; }
24
+ .fl-head, .fl-row { display: grid; grid-template-columns: minmax(0, 1fr) 130px 96px 130px 36px; gap: 14px; align-items: center; }
25
+ .fl-head { padding: 8px 8px; font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em; border-bottom: 1px solid var(--line); }
26
+ .fl-row { position: relative; padding: 0 8px; border-bottom: 1px solid var(--line); border-radius: var(--r-md); }
27
+ .fl-row:hover, .fl-row:focus-within { background: var(--hover); }
28
+ .fl-main { display: flex; flex-direction: column; min-width: 0; padding: 12px 0; color: inherit; text-decoration: none; }
29
+ .fl-main::after { content: ''; position: absolute; inset: 0; border-radius: inherit; } /* whole row clicks through */
30
+ .fl-main b { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
31
+ .fl-main small { color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
32
+ .fl-main small.is-attn { color: var(--amber); }
33
+ .fl-meta { color: var(--text-2); font-size: 13px; white-space: nowrap; font-variant-numeric: tabular-nums; }
34
+ .fl-num { text-align: right; }
35
+ .fl-menu { position: relative; z-index: 2; justify-self: end; }
36
+ .fl-menu[open] { z-index: 5; }
37
+ .fl-menu .rmenu-pop form { display: contents; }
38
+ .fl-menu .rmenu-pop .menu-item { width: 100%; text-align: left; text-decoration: none; }
39
+
40
+ /* ---- New form dialog ---- */
41
+ dialog#fl-new { width: min(720px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); overflow: auto; }
42
+ .fl-gallery { border: 0; margin: 0 0 6px; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; min-width: 0; }
43
+ .fl-gallery-title { margin: 14px 0 8px; font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em; }
44
+ .fl-gallery-title small { display: block; margin-top: 2px; text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 12px; color: var(--faint); }
45
+ .fl-tile { position: relative; display: flex; flex-direction: column; gap: 1px; padding: 10px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg); cursor: pointer; min-width: 0; }
46
+ .fl-tile:hover { border-color: var(--line-strong); }
47
+ .fl-tile:has(input:checked) { background: var(--sel); border-color: var(--line-strong); }
48
+ .fl-tile:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--accent-ring); }
49
+ .fl-tile input { position: absolute; opacity: 0; pointer-events: none; }
50
+ .fl-tile b { font-size: 13px; color: var(--text); margin-top: 8px; }
51
+ .fl-tile:has(input:checked) b { font-weight: 700; }
52
+ .fl-tile small { font-size: 11.5px; color: var(--muted); line-height: 1.35; }
53
+ /* tiny skeleton of the form: label + input per question, then the button */
54
+ .fl-skel { display: flex; flex-direction: column; gap: 4px; height: 88px; padding: 9px 10px; border-radius: 8px; background: var(--panel); border: 1px solid var(--line); overflow: hidden; }
55
+ .fl-skel i { display: block; height: 9px; border-radius: 3px; border: 1px solid var(--line-strong); position: relative; margin-top: 6px; flex: 0 0 auto; }
56
+ .fl-skel i::before { content: ''; position: absolute; left: -1px; top: -7px; width: 34%; height: 3px; border-radius: 2px; background: var(--line-strong); }
57
+ .fl-skel i.tall { height: 14px; }
58
+ .fl-skel i.check { width: 9px; }
59
+ .fl-skel i.check::before { left: 13px; top: 2px; width: 50px; }
60
+ .fl-skel u { display: block; width: 38%; height: 8px; border-radius: 3px; background: var(--muted); opacity: 0.55; margin-top: auto; flex: 0 0 auto; }
61
+ .fl-skel.is-blank { align-items: center; justify-content: center; border-style: dashed; border-color: var(--line-strong); background: transparent; }
62
+ .fl-skel.is-blank em { font-style: normal; font-size: 22px; font-weight: 300; color: var(--muted); }
63
+ .fl-name { margin: 16px 0 0; }
64
+ dialog#fl-new .modal-x:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
65
+
66
+ /* ---- Responses ---- */
67
+ .fr-kpis { margin-bottom: 14px; }
68
+ .fr-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
69
+ .fr-search { position: relative; flex: 0 1 300px; min-width: 180px; }
70
+ .fr-search svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--faint); pointer-events: none; }
71
+ .fr-search input[type='search'] { padding-left: 30px; }
72
+ .fr-tools select { width: auto; }
73
+ .fr-count { margin-left: auto; color: var(--faint); font-size: 12px; font-variant-numeric: tabular-nums; }
74
+ .fr-none { padding: 24px 0; }
75
+ .fr-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--panel); }
76
+ .fr-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
77
+ .fr-table th, .fr-table td { padding: 9px 12px; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; border-bottom: 1px solid var(--line); }
78
+ .fr-table th { position: sticky; top: 0; background: var(--panel-2); color: var(--muted); font-size: 11.5px; font-weight: 600; z-index: 1; }
79
+ .fr-table tbody tr:last-child td { border-bottom: 0; }
80
+ .fr-table tbody tr { cursor: pointer; }
81
+ .fr-table tbody tr:hover { background: var(--hover); }
82
+ .fr-table tbody tr.is-picked { background: var(--hover); }
83
+ .fr-table tbody tr.is-open { background: var(--sel); }
84
+ .fr-table tbody tr.is-open td { color: var(--text); }
85
+ .fr-table tbody tr.is-open td.is-empty { color: var(--faint); }
86
+ .fr-table tbody tr:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent-ring); }
87
+ .fr-table td { color: var(--text-2); }
88
+ .fr-table td.is-empty { color: var(--faint); }
89
+ .fr-table .fr-check { width: 36px; padding-right: 0; text-overflow: clip; }
90
+ .fr-table .fr-check input { width: 15px; height: 15px; margin: 0; accent-color: var(--accent); vertical-align: middle; }
91
+ .fr-table .fr-when { color: var(--text); font-weight: 500; font-variant-numeric: tabular-nums; }
92
+ .fr-pager { display: flex; justify-content: space-between; align-items: center; margin-top: 14px; }
93
+
94
+ /* side drawer (desktop) → bottom sheet (phones) */
95
+ .fr-drawer {
96
+ position: fixed; z-index: 70; top: 12px; right: 12px; bottom: 12px; width: min(420px, calc(100vw - 24px));
97
+ display: flex; flex-direction: column; background: var(--panel); color: var(--text);
98
+ border: 1px solid var(--line-strong); border-radius: var(--r-lg); box-shadow: var(--shadow-pop);
99
+ animation: fr-in 0.16s ease-out; outline: none;
100
+ }
101
+ @keyframes fr-in { from { opacity: 0; transform: translateX(12px); } }
102
+ .fr-drawer-head { display: flex; align-items: center; gap: 10px; padding: 14px 12px 0 18px; }
103
+ .fr-drawer-head b { flex: 1; min-width: 0; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
104
+ .fr-drawer-nav { display: flex; gap: 2px; }
105
+ .fr-drawer-nav .icon-btn { width: 32px; height: 32px; font-size: 17px; }
106
+ .fr-drawer-nav .icon-btn:disabled { opacity: 0.35; cursor: default; background: none; }
107
+ .fr-drawer-meta { margin: 2px 18px 0; color: var(--muted); font-size: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
108
+ .fr-drawer-body { flex: 1; overflow-y: auto; padding: 4px 18px 12px; }
109
+ .fr-dl { margin: 0; }
110
+ .fr-dl div { padding: 10px 0; border-bottom: 1px solid var(--line); }
111
+ .fr-dl div:last-child { border-bottom: 0; }
112
+ .fr-dl dt { color: var(--muted); font-size: 12px; margin-bottom: 2px; }
113
+ .fr-dl dd { margin: 0; font-size: 13.5px; white-space: pre-wrap; overflow-wrap: anywhere; }
114
+ .fr-dl dd.is-empty { color: var(--faint); }
115
+ .fr-older { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em; }
116
+ .fr-older small { display: block; text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--faint); font-size: 12px; }
117
+ .fr-drawer-foot { display: flex; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--line); }
118
+ .fr-drawer-foot .btn.danger { margin-left: auto; }
119
+ .fr-confirm { margin: 0; color: var(--text-2); }
120
+ .btn.fr-danger { background: var(--red); border-color: var(--red); color: var(--bg); }
121
+ .btn.fr-danger:hover { filter: brightness(0.94); border-color: var(--red); }
122
+ .fr-bulk { z-index: 65; }
123
+ @media (min-width: 1280px) {
124
+ /* leave room for the drawer so the open row stays visible */
125
+ .fr.has-drawer { margin-right: 420px; }
126
+ }
127
+
128
+ /* ---- Share ---- */
129
+ .fs { max-width: 920px; }
130
+ .fs-sec { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 28px; padding: 20px 0; border-bottom: 1px solid var(--line); }
131
+ .fs-sec:first-child { padding-top: 4px; }
132
+ .fs-sec:last-child { border-bottom: 0; }
133
+ .fs-label b { display: block; font-size: 14px; font-weight: 600; }
134
+ .fs-label small { display: block; color: var(--muted); font-size: 12.5px; line-height: 1.45; margin-top: 2px; }
135
+ .fs-body { min-width: 0; }
136
+ .fs-body .hint { margin: 6px 0 0; }
137
+ .fs-state { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
138
+ .fs-state-title { font-size: 14px; }
139
+ .fs-state .hint { margin-top: 2px; }
140
+ .fs-state-actions { display: flex; gap: 8px; flex-wrap: wrap; }
141
+ .fs-copy { display: flex; gap: 8px; }
142
+ .fs-copy input { flex: 1; min-width: 0; }
143
+ input.mono { font-family: ui-monospace, 'SF Mono', monospace; font-size: 12.5px; }
144
+ .fs-copy .btn, .fs-row .btn { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
145
+ .fs-copy svg, .fs-row svg { width: 14px; height: 14px; }
146
+ .fs-embed { resize: none; color: var(--text-2); }
147
+ .fs-row { margin-top: 8px; }
148
+ .fs-used { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); }
149
+ .fs-used li { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 14px; border-bottom: 1px solid var(--line); }
150
+ .fs-used li:last-child { border-bottom: 0; }
151
+ .fs-used li > a:first-child { flex: 1; min-width: 0; color: inherit; display: flex; flex-direction: column; }
152
+ .fs-used b { font-size: 13.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
153
+ .fs-used small { color: var(--muted); font-size: 12px; }
154
+ .fs-used .status { font-size: 12px; }
155
+ .fs-none { margin-top: 0; }
156
+
157
+ @media (max-width: 767px) {
158
+ .fh-row { gap: 8px 10px; }
159
+ .fh-actions { margin-left: 0; width: 100%; }
160
+ .fh-tabs { overflow-x: auto; scrollbar-width: none; }
161
+ /* list collapses to name + status */
162
+ .fl { margin: 0 -16px; }
163
+ .fl-head { display: none; }
164
+ .fl-head, .fl-row { grid-template-columns: minmax(0, 1fr) auto 36px; gap: 10px; }
165
+ .fl-row { padding: 0 8px 0 16px; border-radius: 0; }
166
+ .fl-row > .fl-meta { display: none; }
167
+ .fl-gallery { grid-template-columns: 1fr 1fr; gap: 8px; }
168
+ .fl-skel { height: 64px; padding: 6px 8px; }
169
+ .fl-skel i.tall { height: 10px; }
170
+ .fr-search { flex: 1 1 100%; }
171
+ .fr-count { margin-left: 0; }
172
+ .fr-table-wrap { margin: 0 -16px; border-radius: 0; border-left: 0; border-right: 0; }
173
+ .fr-table th, .fr-table td { max-width: 180px; }
174
+ .fr-drawer {
175
+ top: auto; left: 0; right: 0; bottom: var(--tabbar-h); width: auto; max-height: 82dvh;
176
+ border-radius: var(--r-xl) var(--r-xl) 0 0; border-bottom: 0;
177
+ padding-bottom: env(safe-area-inset-bottom); animation-name: fr-up;
178
+ }
179
+ .fr-drawer-head::before { content: ''; position: absolute; left: 50%; top: 6px; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: var(--line-strong); }
180
+ .fr-drawer-head { padding-top: 18px; }
181
+ .fs-sec { grid-template-columns: 1fr; gap: 10px; padding: 16px 0; }
182
+ .fs-state-actions { width: 100%; }
183
+ }
184
+ @keyframes fr-up { from { opacity: 0; transform: translateY(24px); } }
@@ -0,0 +1,281 @@
1
+ /* Form builder (components/forms/*): outline · canvas · inspector.
2
+ Admin tokens only (DESIGN.md). Works on the Build page and inside the event
3
+ editor; the layout class (.fb-wide / .fb-mid / .fb-phone) comes from the
4
+ builder's own width, not the viewport. */
5
+
6
+ .fb { position: relative; display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--bg); overflow: clip; color: var(--text); font-size: 13.5px; outline: none; }
7
+ .fb button { font-family: inherit; }
8
+ .fb svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
9
+ .fb kbd, .fb-ins kbd { font: 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--faint); border: 1px solid var(--line-strong); border-radius: 4px; padding: 2px 4px; background: var(--panel); }
10
+
11
+ /* small kit (self-contained so the event editor doesn't need admin.css) */
12
+ .fb-btn { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--panel); color: var(--text); font-weight: 600; font-size: 13px; line-height: 1; font-family: inherit; cursor: pointer; box-shadow: var(--shadow-sm); white-space: nowrap; }
13
+ .fb-btn:hover { border-color: var(--faint); }
14
+ .fb-btn.sm { height: 30px; padding: 0 10px; font-size: 12.5px; }
15
+ .fb-btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
16
+ .fb-btn.primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
17
+ .fb-btn:disabled { opacity: .5; cursor: default; }
18
+ .fb-btn svg { width: 15px; height: 15px; }
19
+ .fb-btn small { color: var(--muted); font-weight: 600; }
20
+ .fb-icon { display: inline-grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--r-sm); background: none; color: var(--muted); font-size: 15px; cursor: pointer; flex: none; }
21
+ .fb-icon:hover:not(:disabled) { background: var(--hover); color: var(--text); }
22
+ .fb-icon:disabled { opacity: .4; cursor: default; }
23
+ .fb-icon.sm { width: 26px; height: 26px; font-size: 12px; }
24
+ .fb-icon.danger:hover { color: var(--red); }
25
+ .fb-icon svg { width: 16px; height: 16px; }
26
+ .fb-link { border: 0; background: none; padding: 0; color: var(--accent-deep); font-weight: 600; font-size: 12.5px; line-height: 1.4; font-family: inherit; cursor: pointer; }
27
+ .fb-link:hover { text-decoration: underline; }
28
+ .fb-link:disabled { color: var(--faint); cursor: default; text-decoration: none; }
29
+ .fb-seg { display: inline-flex; gap: 1px; padding: 2px; border-radius: 9px; background: var(--sel); }
30
+ .fb-seg > button { border: 0; background: none; padding: 5px 12px; border-radius: 7px; font-weight: 600; font-size: 12px; line-height: 1.2; font-family: inherit; color: var(--muted); cursor: pointer; white-space: nowrap; }
31
+ .fb-seg > button:hover { color: var(--text); }
32
+ .fb-seg > button[aria-pressed='true'] { background: var(--bg); color: var(--text); box-shadow: var(--shadow-sm); }
33
+ :root[data-theme='dark'] .fb-seg > button[aria-pressed='true'] { background: #3a3632; }
34
+ .fb-ty { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; background: var(--panel-2); color: var(--muted); font-style: normal; flex: none; }
35
+ .fb-ty svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
36
+ .fb-q.on .fb-ty, .fb-ins-item[aria-selected='true'] .fb-ty { background: var(--panel); color: var(--text-2); }
37
+ .fb :focus-visible, .fb-ins :focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
38
+
39
+ /* toolbar */
40
+ .fb-bar { display: flex; align-items: center; gap: 6px; min-height: 46px; padding: 7px 10px; border-bottom: 1px solid var(--line); background: var(--bg); }
41
+ .fb-bar-sp { flex: 1; }
42
+
43
+ /* panes */
44
+ .fb-main { position: relative; display: grid; background: var(--bg); grid-template-columns: 240px minmax(0, 1fr) 300px; flex: 1; min-height: min(720px, calc(100dvh - 230px)); }
45
+ .fb-mid .fb-main { grid-template-columns: minmax(0, 1fr) 300px; }
46
+ .fb.is-preview .fb-main, .fb-phone .fb-main { grid-template-columns: minmax(0, 1fr); }
47
+ .fb-wide .fb-out, .fb-insp { position: sticky; top: 64px; align-self: start; max-height: calc(100dvh - 80px); overflow-y: auto; overscroll-behavior: contain; }
48
+
49
+ /* outline */
50
+ .fb-out { display: flex; flex-direction: column; gap: 2px; padding: 12px 10px 16px; background: var(--bg); min-width: 0; }
51
+ .fb-out-h { display: flex; justify-content: space-between; margin: 0; padding: 6px 8px 8px; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
52
+ .fb-out-h span + span { color: var(--faint); }
53
+ .fb-out-after { margin-top: 14px; }
54
+ .fb-out-empty { margin: 4px 8px; font-size: 12.5px; color: var(--faint); }
55
+ .fb-q-list { display: flex; flex-direction: column; gap: 2px; }
56
+ .fb-q-wrap { position: relative; display: flex; align-items: center; gap: 2px; }
57
+ .fb-q-wrap.dragging { z-index: 2; }
58
+ .fb-q-wrap.dragging .fb-q { background: var(--panel); box-shadow: var(--shadow-pop); }
59
+ .fb-q { display: grid; grid-template-columns: 14px 22px minmax(0, 1fr) auto; gap: 8px; align-items: center; width: 100%; min-height: 36px; padding: 6px 8px; border: 0; border-radius: var(--r-sm); background: none; color: var(--text-2); font-weight: 500; font-size: 13px; line-height: 1.3; font-family: inherit; text-align: left; cursor: pointer; touch-action: manipulation; }
60
+ .fb-q:hover { background: var(--hover); }
61
+ .fb-q.on { background: var(--sel); color: var(--text); font-weight: 600; }
62
+ .fb-q.sys { color: var(--muted); cursor: default; }
63
+ .fb-q.sys.on { color: var(--text); }
64
+ .fb-q-l { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
65
+ .fb-q-m { min-width: 10px; text-align: right; }
66
+ .fb-grip { color: var(--faint); font-size: 10px; letter-spacing: -2px; cursor: grab; user-select: none; touch-action: none; }
67
+ .fb-q:hover .fb-grip { color: var(--muted); }
68
+ .fb-req { color: var(--accent-deep); font-weight: 700; }
69
+ .fb-issue { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: var(--amber-soft); color: var(--amber); font-size: 11px; font-weight: 800; }
70
+ .fb-lock { width: 13px; height: 13px; color: var(--faint); }
71
+ .fb-add { display: flex; align-items: center; gap: 8px; margin: 8px 0 0; padding: 8px 10px; border: 1px dashed var(--line-strong); border-radius: var(--r-sm); background: none; color: var(--text-2); font-weight: 600; font-size: 12.5px; line-height: 1.2; font-family: inherit; cursor: pointer; min-height: 36px; }
72
+ .fb-add:hover:not(:disabled) { background: var(--hover); color: var(--text); }
73
+ .fb-add:disabled { opacity: .5; cursor: default; }
74
+ .fb-add kbd { margin-left: auto; }
75
+ .fb-add > span { font-size: 15px; line-height: 1; }
76
+
77
+ /* canvas: the form drawn with the public markup */
78
+ .fb-canvas { position: relative; display: flex; justify-content: center; align-items: flex-start; min-width: 0; padding: 28px 24px 56px; background: var(--panel-2); }
79
+ .fb-wide .fb-canvas { border-left: 1px solid var(--line); }
80
+ .fb-wide .fb-canvas, .fb-mid .fb-canvas { border-right: 1px solid var(--line); }
81
+ .fb.is-preview .fb-canvas { border: 0; }
82
+ .fb-wide .fb-canvas:has(> .fb-float) { padding-top: 48px; }
83
+ .fb-float { position: absolute; top: 8px; right: 10px; z-index: 3; display: flex; gap: 2px; padding: 2px; border-radius: 10px; background: color-mix(in srgb, var(--panel-2) 85%, transparent); }
84
+ .fb-paper {
85
+ /* the public form's tokens, mapped onto the admin palette */
86
+ --ink: var(--text); --line-2: var(--line-strong); --btn: var(--text); --btn-ink: var(--bg); --accent-text: var(--accent-deep);
87
+ position: relative; width: 100%; max-width: 560px; padding: 26px 30px 30px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-card); color: var(--text); font-size: 14.5px;
88
+ }
89
+ .fb-paper .pc-bk-field { display: block; margin: 0; }
90
+ .fb-paper .pc-bk-field > span, .fb-paper .fb-legend, .fb-paper .pc-bk-choices > legend { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 600; color: var(--text); }
91
+ .fb-paper .pc-bk-field input, .fb-paper .pc-bk-field select, .fb-paper .pc-bk-field textarea { width: 100%; font: inherit; font-size: 14.5px; padding: 9px 12px; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--bg); color: var(--text); }
92
+ .fb-paper .pc-bk-field textarea { resize: vertical; min-height: 76px; }
93
+ .fb-paper input::placeholder, .fb-paper textarea::placeholder { color: var(--faint); }
94
+ .fb-paper .pc-bk-field input:focus, .fb-paper .pc-bk-field select:focus, .fb-paper .pc-bk-field textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
95
+ .fb-paper .pc-bk-field small, .fb-paper .pc-bk-check small { display: block; margin-top: 4px; color: var(--muted); font-size: 12.5px; font-weight: 400; }
96
+ .fb-paper .pc-bk-check { display: flex; gap: 9px; align-items: flex-start; margin: 0; font-size: 14px; }
97
+ .fb-paper .pc-bk-check input { width: 17px; height: 17px; margin: 2px 0 0; flex: none; accent-color: var(--accent); }
98
+ .fb-paper .pc-bk-check > span { min-width: 0; flex: 1; }
99
+ .fb-paper .pc-bk-choices { border: 0; padding: 0; margin: 0; min-width: 0; }
100
+ .fb-paper .pc-bk-options { display: grid; gap: 6px; }
101
+ .fb-paper .pc-bk-option { display: flex; gap: 10px; align-items: center; min-height: 40px; padding: 7px 12px; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--bg); font-size: 14px; cursor: pointer; }
102
+ .fb-paper .pc-bk-option:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
103
+ .fb-paper .pc-bk-field .pc-bk-option input[type=radio], .fb-paper .pc-bk-field .pc-bk-option input[type=checkbox] { flex: none; width: 17px; height: 17px; margin: 0; padding: 0; accent-color: var(--accent); box-shadow: none; }
104
+ .fb-paper .pc-bk-field .pc-bk-other input[type=text] { flex: 1; min-width: 0; padding: 5px 9px; font-size: 13.5px; background: var(--panel); }
105
+ .fb-paper .pc-form-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(200px, calc(50% - 8px)), 1fr)); gap: 0 16px; align-items: start; }
106
+ .fb-paper .pc-form-heading { margin: 8px 0 0; }
107
+ .fb-paper .pc-form-heading h3 { margin: 0 0 4px; font-size: 17px; font-weight: 650; letter-spacing: -0.01em; }
108
+ .fb-paper .pc-form-heading p { margin: 0; color: var(--muted); font-size: 13.5px; }
109
+ .fb-paper .pc-bk-submit { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 44px; margin-top: 4px; padding: 0 16px; border: 0; border-radius: 12px; background: var(--btn); color: var(--btn-ink); font-weight: 600; font-size: 14.5px; line-height: 1.2; font-family: inherit; cursor: pointer; }
110
+ .fb-paper h2, .fb-title { margin: 0 0 6px; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; }
111
+ .fb-intro, .fb-pv-intro { margin: 0; color: var(--text-2); font-size: 14px; line-height: 1.5; white-space: pre-wrap; }
112
+
113
+ /* selectable items on the canvas */
114
+ .fb-item { position: relative; margin: 0 -12px 6px; padding: 10px 12px; border: 1.5px solid transparent; border-radius: 12px; cursor: pointer; outline: none; transition: border-color .12s, background-color .12s; }
115
+ .fb-item:hover { border-color: var(--line-strong); border-style: dashed; }
116
+ .fb-item.on, .fb-item.on:hover { border-style: solid; border-color: var(--accent); background: var(--accent-soft); }
117
+ .fb-item:focus-visible { box-shadow: 0 0 0 3px var(--accent-ring); }
118
+ .fb-head { margin-bottom: 12px; }
119
+ .fb-paper:not(.fb-pv) .pc-form-row > .fb-item { margin-inline: 0; min-width: 0; }
120
+ .fb-paper:not(.fb-pv) .pc-form-row { margin-inline: -12px; gap: 0 8px; }
121
+ .fb-sys { cursor: default; opacity: .62; }
122
+ .fb-sys.on { opacity: 1; }
123
+ .fb-control { pointer-events: none; }
124
+ .fb-req-mark { color: var(--accent-deep); }
125
+ .fb-item-tools { position: absolute; top: -15px; right: 8px; z-index: 2; display: flex; gap: 2px; padding: 2px; border: 1px solid var(--line-strong); border-radius: 9px; background: var(--panel); box-shadow: var(--shadow-pop); }
126
+ .fb-item-tools .fb-icon { width: 28px; height: 28px; font-size: 16px; }
127
+ .fb-item-tools .fb-icon svg { width: 15px; height: 15px; }
128
+ .fb-submit-wrap { margin-top: 10px; margin-bottom: 0; }
129
+ .fb-paper .fb-submit { cursor: text; }
130
+ .fb-empty { display: grid; gap: 4px; width: 100%; margin: 4px 0 16px; padding: 22px 16px; border: 1.5px dashed var(--line-strong); border-radius: 12px; background: none; color: var(--muted); text-align: center; cursor: pointer; font-size: 13px; line-height: 1.4; font-family: inherit; }
131
+ .fb-empty b { color: var(--text); font-size: 14px; }
132
+ .fb-empty:hover { background: var(--hover); }
133
+ .fb-paper-tag { margin: 0 0 14px; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
134
+ .fb-thanks { margin: 6px 0 18px; padding: 10px 12px; border: 1.5px solid var(--accent); border-radius: 12px; background: var(--accent-soft); white-space: pre-wrap; }
135
+
136
+ /* inline editing */
137
+ .fb-inline { display: inline-block; min-width: 2ch; max-width: 100%; outline: none; border-radius: 4px; cursor: text; overflow-wrap: anywhere; white-space: pre-wrap; }
138
+ .fb-inline:empty::before { content: attr(data-placeholder); color: var(--faint); font-weight: inherit; pointer-events: none; }
139
+ .fb-inline:focus { background: var(--panel); box-shadow: 0 0 0 2px var(--accent-ring); }
140
+ .fb-intro .fb-inline, .fb-help .fb-inline, .fb-thanks .fb-inline, .pc-form-heading p .fb-inline { display: block; }
141
+ .fb-submit .fb-inline:focus { background: transparent; box-shadow: 0 0 0 2px color-mix(in srgb, var(--btn-ink) 55%, transparent); }
142
+
143
+ /* preview */
144
+ .fb-pv-frame { width: 100%; display: flex; justify-content: center; }
145
+ .fb-pv-frame.desktop .fb-pv { max-width: 640px; }
146
+ .fb-pv-frame.phone .fb-pv { max-width: 390px; padding: 20px 18px 24px; }
147
+ .fb-pv { display: grid; gap: 16px; }
148
+ .fb-pv > div { display: grid; gap: 16px; }
149
+ .fb-pv > div > h2 { margin-bottom: -10px; }
150
+ .fb-pv .pc-form-row { row-gap: 16px; }
151
+ .fb-pv-result { margin: 0; padding: 10px 12px; border-radius: 10px; font-size: 13.5px; }
152
+ .fb-pv-result.ok { background: var(--green-soft); color: var(--text); }
153
+ .fb-pv-result.bad { background: var(--red-soft); color: var(--red); }
154
+ .fb-phone .fb-pv-frame.phone .fb-pv { max-width: none; }
155
+
156
+ /* inspector */
157
+ .fb-insp { background: var(--bg); min-width: 0; }
158
+ .fb-insp-body { display: grid; gap: 16px; align-content: start; padding: 16px 18px 24px; }
159
+ .fb-insp-h { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
160
+ .fb-insp-h > div { min-width: 0; }
161
+ .fb-insp-h b { display: block; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
162
+ .fb-insp-h small { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }
163
+ .fb-insp-none { color: var(--muted); font-size: 13px; }
164
+ .fb-insp-none b { color: var(--text); font-size: 14px; }
165
+ .fb-insp-none p { margin: 0; line-height: 1.5; }
166
+ .fb-insp-none .fb-btn { justify-self: start; }
167
+ .fb-keys { display: grid; gap: 6px; margin: 6px 0 0; padding-top: 14px; border-top: 1px solid var(--line); font-size: 12.5px; }
168
+ .fb-keys div { display: flex; justify-content: space-between; gap: 12px; }
169
+ .fb-keys dt { font-size: 12.5px; letter-spacing: .04em; color: var(--text-2); }
170
+ .fb-keys dd { margin: 0; }
171
+ .fb-f { display: grid; gap: 6px; min-width: 0; margin: 0; }
172
+ .fb-lab { font-size: 12px; font-weight: 600; color: var(--text-2); }
173
+ .fb-lab small { font-weight: 400; color: var(--muted); }
174
+ .fb-f input, .fb-f select, .fb-f textarea { width: 100%; min-height: 36px; padding: 7px 10px; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--panel); color: var(--text); font: inherit; font-size: 13.5px; }
175
+ .fb-f textarea { resize: vertical; line-height: 1.45; }
176
+ .fb-f input:focus, .fb-f select:focus, .fb-f textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
177
+ .fb-f input[readonly] { background: var(--panel-2); color: var(--muted); }
178
+ .fb-f [aria-invalid='true'] { border-color: var(--red); }
179
+ .fb-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace !important; font-size: 12.5px !important; }
180
+ .fb-hint { font-size: 12px; color: var(--muted); line-height: 1.4; }
181
+ .fb-err { font-size: 12px; color: var(--red); }
182
+ .fb-warn { margin: 0; padding: 8px 10px; border-radius: var(--r-sm); background: var(--amber-soft); color: var(--amber); font-size: 12.5px; font-weight: 600; }
183
+ .fb-note { margin: 0; padding: 10px 12px; border-radius: var(--r-md); background: var(--panel-2); color: var(--text-2); font-size: 12.5px; line-height: 1.5; }
184
+ .fb-opts { display: grid; gap: 2px; padding: 4px 0; border-block: 1px solid var(--line); }
185
+ .fb-sw-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; min-height: 40px; padding: 4px 0; cursor: pointer; }
186
+ .fb-sw-row b { display: block; font-size: 13px; font-weight: 600; }
187
+ .fb-sw-row small { display: block; font-size: 12px; color: var(--muted); }
188
+ .fb-switch { position: relative; width: 30px; height: 18px; padding: 0; border: 0; border-radius: 9px; background: var(--line-strong); cursor: pointer; flex: none; transition: background-color .15s; }
189
+ .fb-switch i { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--panel); box-shadow: 0 1px 2px rgb(0 0 0 / 25%); transition: left .15s; }
190
+ .fb-switch[aria-checked='true'] { background: var(--accent); }
191
+ .fb-switch[aria-checked='true'] i { left: 14px; }
192
+ .fb-choices { display: grid; gap: 6px; }
193
+ .fb-choice { display: grid; grid-template-columns: 14px minmax(0, 1fr) 26px; gap: 6px; align-items: center; }
194
+ .fb-choice.dragging { z-index: 2; position: relative; }
195
+ .fb-choice.dragging input { box-shadow: var(--shadow-pop); }
196
+ .fb-choice input { min-height: 34px; }
197
+ .fb-choice-add { margin: 2px 0 0; font-size: 12px; color: var(--muted); }
198
+
199
+ /* menus */
200
+ .fb-more, .fb-q-more { position: relative; flex: none; }
201
+ .fb-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 30; display: grid; min-width: 180px; padding: 6px; border: 1px solid var(--line-strong); border-radius: var(--r-lg); background: var(--panel); box-shadow: var(--shadow-pop); }
202
+ .fb-menu button { display: flex; align-items: center; min-height: 34px; padding: 7px 10px; border: 0; border-radius: var(--r-sm); background: none; color: var(--text-2); font-weight: 500; font-size: 13px; line-height: 1.2; font-family: inherit; text-align: left; cursor: pointer; white-space: nowrap; }
203
+ .fb-menu button:hover:not(:disabled) { background: var(--hover); color: var(--text); }
204
+ .fb-menu button:disabled { color: var(--faint); cursor: default; }
205
+ .fb-menu button.danger { color: var(--red); }
206
+
207
+ /* insert menu */
208
+ .fb-ins-back { position: fixed; inset: 0; z-index: 200; display: grid; place-items: start center; padding: 12vh 16px 16px; background: var(--dim); animation: fb-fade .15s ease-out; }
209
+ .fb-ins { display: grid; grid-template-columns: 240px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); width: min(660px, 100%); max-height: min(600px, 80dvh); overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--r-lg); background: var(--panel); box-shadow: var(--shadow-pop); color: var(--text); font-size: 13.5px; }
210
+ .fb-ins-search { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
211
+ .fb-ins-search svg { width: 16px; height: 16px; flex: none; fill: none; stroke: var(--muted); stroke-width: 1.8; stroke-linecap: round; }
212
+ .fb-ins-search input, .fb-ins-search input:focus { flex: 1; min-width: 0; height: 32px; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; color: var(--text); font: inherit; font-size: 14.5px; outline: none; }
213
+ .fb-ins-search input::placeholder { color: var(--faint); }
214
+ .fb-ins-list { overflow-y: auto; padding: 6px 8px 10px; border-right: 1px solid var(--line); }
215
+ .fb-ins-g { margin: 0; padding: 10px 8px 4px; font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
216
+ .fb-ins-item { display: flex; align-items: center; gap: 9px; min-height: 34px; padding: 5px 8px; border-radius: var(--r-sm); color: var(--text-2); font-size: 13px; cursor: pointer; }
217
+ .fb-ins-item[aria-selected='true'] { background: var(--sel); color: var(--text); font-weight: 600; }
218
+ .fb-ins-item kbd { margin-left: auto; }
219
+ .fb-ins-empty { margin: 12px 8px; color: var(--muted); font-size: 13px; }
220
+ .fb-ins-pv { display: grid; gap: 10px; align-content: start; padding: 18px; overflow-y: auto; }
221
+ .fb-ins-pv > b { font-size: 15px; }
222
+ .fb-ins-pv > p { margin: 0; color: var(--muted); font-size: 13px; line-height: 1.5; }
223
+ .fb-ins-pv .fb-btn { justify-self: start; }
224
+ .fb-ins-sample { padding: 16px; box-shadow: none; background: var(--bg); font-size: 13.5px; }
225
+
226
+ /* phone layout: the question list is the main view, settings open in a sheet */
227
+ .fb-phone .fb-out { border-right: 0; padding: 10px 10px 18px; }
228
+ .fb-phone .fb-q { min-height: 46px; font-size: 14.5px; }
229
+ .fb-phone .fb-q-more .fb-icon { width: 40px; height: 40px; font-size: 18px; }
230
+ .fb-phone .fb-grip { padding: 10px 6px; margin: -10px -6px; font-size: 12px; }
231
+ .fb-phone .fb-add { min-height: 46px; font-size: 14px; justify-content: center; }
232
+ .fb-phone .fb-canvas { padding: 14px 10px 28px; }
233
+ .fb-phone .fb-paper { padding: 20px 16px 22px; }
234
+ .fb-q-plain { grid-template-columns: 14px 22px minmax(0, 1fr) auto; }
235
+ .fb-sheet-back { position: fixed; inset: 0; z-index: 200; display: flex; align-items: flex-end; justify-content: center; background: var(--dim); animation: fb-fade .15s ease-out; }
236
+ .fb-sheet { display: flex; flex-direction: column; width: min(560px, 100%); max-height: 88dvh; border-radius: var(--r-xl) var(--r-xl) 0 0; background: var(--bg); box-shadow: var(--shadow-pop); animation: fb-up .2s ease-out; }
237
+ .fb-sheet-grab { width: 36px; height: 4px; margin: 8px auto 0; border-radius: 4px; background: var(--line-strong); flex: none; }
238
+ .fb-sheet-top { display: flex; justify-content: flex-end; padding: 4px 12px 0; }
239
+ .fb-sheet-body { overflow-y: auto; overscroll-behavior: contain; padding-bottom: env(safe-area-inset-bottom); }
240
+ .fb-sheet .fb-insp-body { padding-top: 4px; }
241
+ .fb-sheet .fb-f input, .fb-sheet .fb-f select, .fb-sheet .fb-f textarea { font-size: 16px; min-height: 42px; }
242
+ .fb-sheet .fb-seg > button { padding: 8px 16px; font-size: 13px; }
243
+
244
+ /* tablet layout: outline in a drawer over the canvas */
245
+ .fb-drawer-back { position: absolute; inset: 0; z-index: 20; background: var(--dim); }
246
+ .fb-drawer { position: absolute; top: 0; left: 0; bottom: 0; z-index: 21; width: min(280px, 85%); overflow-y: auto; box-shadow: var(--shadow-pop); animation: fb-in .15s ease-out; }
247
+ .fb-drawer .fb-out { min-height: 100%; }
248
+
249
+ /* undo toast: inverted floating bar (kit pattern) */
250
+ .fb-toast { position: fixed; left: 50%; bottom: calc(24px + var(--tabbar-h, 0px)); z-index: 210; transform: translateX(-50%); display: flex; align-items: center; gap: 12px; max-width: calc(100vw - 24px); padding: 8px 8px 8px 16px; border-radius: var(--r-md); background: var(--text); color: var(--bg); box-shadow: var(--shadow-pop); font-size: 13px; animation: fb-fade .15s ease-out; }
251
+ .fb-toast span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
252
+ .fb-toast button { border: 0; background: none; color: var(--bg); font-weight: 700; font-size: 13px; line-height: 1; font-family: inherit; padding: 7px 8px; border-radius: 6px; cursor: pointer; }
253
+ .fb-toast button:hover { background: color-mix(in srgb, var(--bg) 14%, transparent); }
254
+ .fb-toast .fb-toast-x { font-weight: 400; opacity: .7; }
255
+
256
+ /* Build page header actions (portaled into FormHeader's slot) */
257
+ .fb-actions-slot { display: contents; }
258
+ .fb-actions .btn:disabled { opacity: .5; cursor: default; }
259
+ .fb-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
260
+ .fb-state { font-size: 12.5px; color: var(--muted); max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
261
+ .fb-state.warn { color: var(--amber); font-weight: 600; }
262
+ .fb-state.bad { color: var(--red); font-weight: 600; white-space: normal; }
263
+
264
+ @keyframes fb-fade { from { opacity: 0; } }
265
+ @keyframes fb-up { from { transform: translateY(24px); opacity: .6; } }
266
+ @keyframes fb-in { from { transform: translateX(-16px); opacity: .6; } }
267
+
268
+ @media (max-width: 767px) {
269
+ .fb { border-radius: var(--r-md); }
270
+ .fb-actions { width: 100%; justify-content: flex-start; }
271
+ .fb-state { flex-basis: 100%; max-width: none; }
272
+ .fb-ins-back { padding: 10px; place-items: end center; }
273
+ .fb-ins { grid-template-columns: minmax(0, 1fr); max-height: 80dvh; }
274
+ .fb-ins-pv { display: none; }
275
+ .fb-ins-list { border-right: 0; }
276
+ .fb-ins-item { min-height: 42px; font-size: 14.5px; }
277
+ .fb-ins-search input { font-size: 16px; }
278
+ }
279
+ @media (prefers-reduced-motion: reduce) {
280
+ .fb *, .fb-ins-back, .fb-sheet, .fb-sheet-back, .fb-toast { animation: none !important; transition: none !important; }
281
+ }
@@ -871,6 +871,19 @@ li::marker { color: var(--muted); }
871
871
  .pc-ev-fact b { display: block; font-weight: 600; line-height: 1.35; }
872
872
  .pc-ev-fact span { display: block; color: var(--muted); font-size: 13.5px; line-height: 1.4; }
873
873
  .pc-ev-fact a { color: var(--accent-text); }
874
+ /* static map under the place: light/dark pair follows the site scheme like the logo */
875
+ .pc-ev-map { margin: 0 0 12px; }
876
+ .pc-ev-map a { display: block; border-radius: var(--r-sm); overflow: hidden; border: 1px solid var(--line); background: var(--soft); }
877
+ .pc-ev-map a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
878
+ .pc-ev-map-img { display: block; width: 100%; height: auto; aspect-ratio: 12 / 5; object-fit: cover; }
879
+ .pc-ev-map-img.is-dark { display: none; }
880
+ :root[data-scheme='dark'] .pc-ev-map-img.is-light { display: none; }
881
+ :root[data-scheme='dark'] .pc-ev-map-img.is-dark { display: block; }
882
+ @media (prefers-color-scheme: dark) {
883
+ :root:not([data-scheme='light']) .pc-ev-map-img.is-light { display: none; }
884
+ :root:not([data-scheme='light']) .pc-ev-map-img.is-dark { display: block; }
885
+ }
886
+ .pc-ev-map-credit { margin-top: 5px; font-size: 11px; line-height: 1.35; color: var(--muted); }
874
887
  .pc-ev-side .pc-ev-cta { width: 100%; margin-top: 14px; }
875
888
  .pc-ev-add { position: relative; margin-top: 8px; }
876
889
  .pc-ev-add > summary, .pc-ev-share {
@@ -1170,3 +1183,33 @@ li::marker { color: var(--muted); }
1170
1183
  .preview-bar-label small, .preview-bar-div, .preview-bar a[href='/admin/design'] { display: none; }
1171
1184
  }
1172
1185
  }
1186
+
1187
+ /* Shared contact/registration forms use the booking theme controls. */
1188
+ .pc-simple-form { max-width: 640px; margin: 32px auto; padding: 24px; }
1189
+ .pc-simple-form form { display: grid; gap: 16px; }
1190
+ .pc-simple-form .pc-bk-field { margin: 0; }
1191
+ .pc-form-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
1192
+ .pc-bk-check { display: flex; gap: 8px; align-items: start; margin-block: 12px; }
1193
+ .pc-bk-check input { width: auto; margin-top: 5px; }
1194
+ .pc-bk-check small, .pc-bk-field small { display: block; font-size: .85em; opacity: .8; }
1195
+ /* Half-width questions: pairs sit side by side once the form is ~520px wide, and stack below that. */
1196
+ .pc-form-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(240px, calc(50% - 8px)), 1fr)); column-gap: 16px; align-items: start; }
1197
+ .pc-simple-form .pc-form-row { row-gap: 16px; }
1198
+ .pc-form-row > .pc-bk-check { margin-block: 4px 12px; }
1199
+ /* Multiple choice + checkbox groups */
1200
+ .pc-bk-choices { border: 0; padding: 0; margin: 0 0 12px; min-width: 0; }
1201
+ .pc-simple-form .pc-bk-choices { margin: 0; }
1202
+ .pc-bk-choices > legend { padding: 0; margin-bottom: 6px; font-size: 13px; font-weight: 600; }
1203
+ .pc-bk-options { display: grid; gap: 6px; }
1204
+ .pc-bk-option { display: flex; gap: 10px; align-items: center; min-height: 42px; padding: 8px 12px; border: 1px solid var(--line-2, var(--line)); border-radius: 10px; background: var(--panel); color: var(--ink); font-size: 14.5px; cursor: pointer; transition: border-color .15s, background-color .15s; }
1205
+ .pc-bk-option:hover { border-color: color-mix(in srgb, var(--ink) 30%, transparent); }
1206
+ .pc-bk-option:has(input:checked) { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 7%, var(--panel)); }
1207
+ .pc-bk-option:focus-within { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
1208
+ .pc-bk-field .pc-bk-option input[type=radio], .pc-bk-field .pc-bk-option input[type=checkbox] { flex: none; width: 17px; height: 17px; margin: 0; padding: 0; box-shadow: none; accent-color: var(--accent); }
1209
+ .pc-bk-option > span { flex: none; }
1210
+ .pc-bk-field .pc-bk-other input[type=text] { flex: 1; min-width: 0; padding: 5px 9px; font-size: 14px; }
1211
+ .pc-form-heading { margin: 10px 0 4px; }
1212
+ .pc-form-heading h3 { margin: 0 0 4px; font-size: 1.15em; letter-spacing: -0.01em; }
1213
+ .pc-form-heading p { margin: 0; color: var(--muted); font-size: .95em; }
1214
+
1215
+ .pc-form-embed { display: block; width: 100%; height: 720px; border: 0; background: transparent; }
package/src/virtual.d.ts CHANGED
@@ -15,6 +15,8 @@ declare module 'virtual:acms-config' {
15
15
  i18n: { locales: string[]; defaultLocale: string };
16
16
  mobile?: { ios?: { teamId: string; bundleId: string; paths: string[] }; android?: { package: string; sha256CertFingerprints: string[] }; push?: { enabled: boolean; retentionDays: number }; editor?: { enabled: boolean; name: string; redirectUris: string[]; accessTokenMinutes: number; refreshTokenDays: number } };
17
17
  search?: { enabled: boolean };
18
+ // resolved by integration.mjs; '' = pick from the environment (lib/maps/config.ts)
19
+ maps?: { provider: '' | 'geoapify' | 'google' | 'mapbox' | 'locationiq' | 'stadia' | 'photon' | 'nominatim' | 'pelias' };
18
20
  legal?: { enabled: boolean; operatorName: string; contactEmail: string; updatedAt: string };
19
21
  // resolved by integration.mjs (lib/calendar/config.ts documents the shape)
20
22
  calendar?: {