your-ai-workflow-firebase-os 2.0.2 → 2.0.3

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 (180) hide show
  1. package/dist/AccessNotice-BZ5Gt1nP.js +40 -0
  2. package/dist/AccessNotice-CN7kc70o.cjs +1 -0
  3. package/dist/{AddressField-B2YBRXcx.js → AddressField-9Sqn8TvC.js} +3 -3
  4. package/dist/{AddressField-BBv8NGX8.cjs → AddressField-B7wtV8yA.cjs} +1 -1
  5. package/dist/Assets-DBMwZ3bN.cjs +1 -0
  6. package/dist/Assets-DT-NU_WO.js +296 -0
  7. package/dist/Attachments-Bl9_dfsu.js +46 -0
  8. package/dist/Attachments-UVK9SRXf.cjs +1 -0
  9. package/dist/Billing-0RIHayHy.cjs +1 -0
  10. package/dist/Billing-FNE2r3_d.js +379 -0
  11. package/dist/BookingCalendar-BP5kiv3d.cjs +1 -0
  12. package/dist/BookingCalendar-DZ2fEFja.js +309 -0
  13. package/dist/Button-4lzOE31p.js +48 -0
  14. package/dist/Button-5DlB2MCi.cjs +1 -0
  15. package/dist/CalendarView-BimoXy_k.cjs +1 -0
  16. package/dist/CalendarView-D-ykjpvI.js +664 -0
  17. package/dist/ConfirmModal-Di9GR-vV.cjs +1 -0
  18. package/dist/ConfirmModal-gKQEpd4d.js +113 -0
  19. package/dist/ContactPopup-BXnHrRwl.js +1114 -0
  20. package/dist/ContactPopup-lxmRMoIa.cjs +1 -0
  21. package/dist/CopyLink-BpEQWmfI.cjs +1 -0
  22. package/dist/CopyLink-CBAVfcm1.js +43 -0
  23. package/dist/DashboardNav-CXa_ci-_.cjs +1 -0
  24. package/dist/DashboardNav-Dmn7PVSp.js +886 -0
  25. package/dist/EmailAdmin-CjN_rvxT.js +318 -0
  26. package/dist/EmailAdmin-lAEBdY1s.cjs +1 -0
  27. package/dist/EventCard-46EquygT.cjs +1 -0
  28. package/dist/EventCard-B6xD-mk3.js +97 -0
  29. package/dist/FileViewerPopup-CX-J75TM.js +1283 -0
  30. package/dist/FileViewerPopup-D8-MmIoS.cjs +3 -0
  31. package/dist/FormNote-BivRNA3J.js +50 -0
  32. package/dist/FormNote-BtdTGpml.cjs +1 -0
  33. package/dist/FormsAdmin-B5PBCG2W.js +812 -0
  34. package/dist/FormsAdmin-BQCULvi5.cjs +1 -0
  35. package/dist/Inbox-BPk2ZkE5.js +779 -0
  36. package/dist/Inbox-DNrcBx0o.cjs +3 -0
  37. package/dist/Loader-Bu89fsbB.cjs +1 -0
  38. package/dist/Loader-D4gwgBOq.js +32 -0
  39. package/dist/ManagePlanButton-B0dwqZBd.cjs +1 -0
  40. package/dist/ManagePlanButton-BSrOHYze.js +29 -0
  41. package/dist/MyBookings-6qr0GgzO.cjs +1 -0
  42. package/dist/MyBookings-BQjGM2LQ.js +113 -0
  43. package/dist/PageTitle-CZhgmmDT.cjs +3 -0
  44. package/dist/PageTitle-D93YCiN8.js +1606 -0
  45. package/dist/PagesAdmin-BcHIcqM5.cjs +34 -0
  46. package/dist/PagesAdmin-D69P9nRb.js +5802 -0
  47. package/dist/PagesAdmin-DNwZOKjA.cjs +1 -0
  48. package/dist/PagesAdmin-HUITEcHx.js +3 -0
  49. package/dist/PaymentsAdmin-C2iCI9qC.js +1291 -0
  50. package/dist/PaymentsAdmin-CoXi2vCm.cjs +2 -0
  51. package/dist/{PhoneInputField-B3P_vUDW.cjs → PhoneInputField-BEwYZMB7.cjs} +1 -1
  52. package/dist/{PhoneInputField-D3wWs-M8.js → PhoneInputField-BG0L2djE.js} +2 -2
  53. package/dist/PhoneInputField-DfOtCIH_.js +2 -0
  54. package/dist/{PhoneInputField-CdNTvWXQ.cjs → PhoneInputField-jhWvto8C.cjs} +1 -1
  55. package/dist/Popup-DHYGFl2-.cjs +1 -0
  56. package/dist/Popup-xROLytgr.js +142 -0
  57. package/dist/ProviderMark-BBfaM5Yl.js +52 -0
  58. package/dist/ProviderMark-xLkUN3Fx.cjs +1 -0
  59. package/dist/PublishApp-Bm-6r3Td.js +595 -0
  60. package/dist/PublishApp-D4XJUkJa.cjs +2 -0
  61. package/dist/Said-CoC15awL.js +94 -0
  62. package/dist/Said-IqCNofdh.cjs +1 -0
  63. package/dist/ScheduleAdmin-BKfQkrR8.js +1853 -0
  64. package/dist/ScheduleAdmin-DwK36GAZ.cjs +1 -0
  65. package/dist/SchedulePicker--urIH2Eb.js +112 -0
  66. package/dist/SchedulePicker-nmqzUnUH.cjs +1 -0
  67. package/dist/Setup-CHLgd-ag.js +849 -0
  68. package/dist/Setup-CaDranTm.cjs +1374 -0
  69. package/dist/SetupPayments-CVIwh1eQ.js +411 -0
  70. package/dist/SetupPayments-HNXWA25X.cjs +1 -0
  71. package/dist/SignInAdmin-C94-A-0w.cjs +4 -0
  72. package/dist/SignInAdmin-Yxgv_8U4.js +766 -0
  73. package/dist/SupportBar-CDT0HwdP.cjs +1 -0
  74. package/dist/SupportBar-CN_JGC-9.js +117 -0
  75. package/dist/SystemTabContent-L3vGGF3P.cjs +1 -0
  76. package/dist/SystemTabContent-QdxxLILE.js +35 -0
  77. package/dist/TemplateDrive-DV8zNjYe.cjs +1 -0
  78. package/dist/TemplateDrive-NJY_AAvV.js +1197 -0
  79. package/dist/ThemeAdmin-BzFjJkLg.js +269 -0
  80. package/dist/ThemeAdmin-DVnPNxe7.cjs +1 -0
  81. package/dist/ThemeAdmin-DY7Vc4Sj.cjs +3 -0
  82. package/dist/ThemeAdmin-DnC-D2N3.js +2 -0
  83. package/dist/{ContactPopup-Dsg2ntq3.js → TimeZoneField-DkI1Bkcz.js} +3191 -5322
  84. package/dist/TimeZoneField-qs7NPR30.cjs +12 -0
  85. package/dist/TransactionsAdmin-BsZ-oQWi.js +582 -0
  86. package/dist/TransactionsAdmin-CTSTiPld.cjs +1 -0
  87. package/dist/Trouble-9es_AI4F.cjs +1 -0
  88. package/dist/Trouble-oWt9fMsm.js +164 -0
  89. package/dist/Users-CTitWXyd.cjs +1 -0
  90. package/dist/Users-DJjQTWJF.js +1207 -0
  91. package/dist/aiModels-DIP9fn8T.cjs +1 -0
  92. package/dist/{aiModels-BHlEfuRJ.js → aiModels-DnDhNGup.js} +29 -61
  93. package/dist/arrivalRoads-BJ-35vkk.js +228 -0
  94. package/dist/arrivalRoads-qoU-B4jt.cjs +4 -0
  95. package/dist/{bake-BWG3y-15.cjs → bake-n2wyFw0B.cjs} +1 -1
  96. package/dist/{bake-BtYOG1Du.js → bake-naZeMu98.js} +1 -1
  97. package/dist/bookingPages-C7a3srPG.js +102 -0
  98. package/dist/bookingPages-DvbFbD9X.cjs +1 -0
  99. package/dist/components/CustomSelect.d.ts +7 -1
  100. package/dist/components/RegistrationFields.d.ts +6 -1
  101. package/dist/components/Reveal.d.ts +12 -0
  102. package/dist/components/ScrollToTop.d.ts +4 -0
  103. package/dist/contentFallback-C9MZjdq7.cjs +1 -0
  104. package/dist/contentFallback-CEDY0Pwp.js +96 -0
  105. package/dist/contentKey-Bwry4lDa.js +13 -0
  106. package/dist/contentKey-DJGYYnAE.cjs +1 -0
  107. package/dist/email-BfnZnMwD.cjs +1 -0
  108. package/dist/email-Ddj8Dlu6.js +58 -0
  109. package/dist/{fileBytes-BdwaFKRy.cjs → fileBytes-BJPaiX9Y.cjs} +1 -1
  110. package/dist/{fileBytes-DuW2K-H_.js → fileBytes-bjgvCfWu.js} +2 -2
  111. package/dist/forms-Bvx9HTM6.js +75 -0
  112. package/dist/forms-CmNeTETW.cjs +1 -0
  113. package/dist/lib/ThemeContext.d.ts +0 -14
  114. package/dist/lib/bareImgWatch.d.ts +6 -1
  115. package/dist/lib/localEdits.d.ts +2 -0
  116. package/dist/lib/paymentProducts.d.ts +8 -0
  117. package/dist/lib/payments.d.ts +11 -1
  118. package/dist/notices-B7iIrIEg.js +29 -0
  119. package/dist/notices-upMg8UVh.cjs +1 -0
  120. package/dist/openOnArrival-Buwqb86D.cjs +1 -0
  121. package/dist/openOnArrival-S2K6v-lB.js +35 -0
  122. package/dist/pageFiles--Ih60ITP.js +45 -0
  123. package/dist/pageFiles-UtBmlOcD.cjs +1 -0
  124. package/dist/pages/PagesAdmin.d.ts +69 -0
  125. package/dist/people-2jZE_pdI.js +102 -0
  126. package/dist/people-BpVvIr9-.cjs +1 -0
  127. package/dist/personName-CFw3pxuu.js +18 -0
  128. package/dist/personName-CbzN_i57.cjs +1 -0
  129. package/dist/publishSteps-C1cDFzzB.js +88 -0
  130. package/dist/publishSteps-SSm8afDw.cjs +1 -0
  131. package/dist/recordLock-DHVvI9bP.js +61 -0
  132. package/dist/recordLock-DWeIxiwh.cjs +1 -0
  133. package/dist/recordsKey-B7QrxdeU.cjs +1 -0
  134. package/dist/recordsKey-D5-wC0Aw.js +141 -0
  135. package/dist/registrationFields-CLeR2lQJ.js +181 -0
  136. package/dist/registrationFields-v4pOoRdn.cjs +1 -0
  137. package/dist/renderer.cjs.js +1 -1
  138. package/dist/renderer.es.js +1 -1
  139. package/dist/roles-D6VaHWfV.js +147 -0
  140. package/dist/roles-DQUFFBQe.cjs +1 -0
  141. package/dist/scheduleData-ATN8w5hI.js +727 -0
  142. package/dist/scheduleData-Cltj0ABZ.cjs +1 -0
  143. package/dist/server.cjs.js +6 -6
  144. package/dist/server.es.js +716 -715
  145. package/dist/serviceStatus-TQyZO_Y_.cjs +1 -0
  146. package/dist/serviceStatus-vS8AI7SZ.js +125 -0
  147. package/dist/tabAudience-BqpN6dsR.cjs +1 -0
  148. package/dist/tabAudience-CRyMvv0v.js +34 -0
  149. package/dist/transactions-BqMQDRx3.js +343 -0
  150. package/dist/transactions-CufFrdAM.cjs +1 -0
  151. package/dist/useIsPhone-BVGx_X3e.js +13 -0
  152. package/dist/useIsPhone-o63tNneA.cjs +1 -0
  153. package/dist/{validate-DzSJWuyL.js → validate-CmC_tLK-.js} +433 -351
  154. package/dist/validate-DZMwqSrb.cjs +103 -0
  155. package/dist/vite/validate.d.ts +14 -0
  156. package/dist/vite.cjs.js +1 -1
  157. package/dist/vite.es.js +1 -1
  158. package/dist/your-ai-workflow-firebase-os.cjs.js +15 -1431
  159. package/dist/your-ai-workflow-firebase-os.css +1 -1
  160. package/dist/your-ai-workflow-firebase-os.es.js +8200 -32421
  161. package/package.json +1 -1
  162. package/src/index.css +122 -2
  163. package/dist/ContactPopup-IwBm-eqz.cjs +0 -12
  164. package/dist/PhoneInputField-CVamkTJg.js +0 -2
  165. package/dist/aiModels-BIhoTNH0.cjs +0 -1
  166. package/dist/validate-e48WXJdP.cjs +0 -103
  167. /package/dist/{address-DI1YaCI4.cjs → address-Bsb8COq2.cjs} +0 -0
  168. /package/dist/{address-Ca1h_UZX.js → address-C2bHNxJU.js} +0 -0
  169. /package/dist/{dist-BkUiTtIb.js → dist-DUPvBnOA.js} +0 -0
  170. /package/dist/{dist-BLGlDv1e.cjs → dist-E4jTFPs7.cjs} +0 -0
  171. /package/dist/{lucide-react-BYniZ3lQ.cjs → lucide-react-BwV6L6Is.cjs} +0 -0
  172. /package/dist/{lucide-react-ehRy1vqS.js → lucide-react-CA7GD7Nv.js} +0 -0
  173. /package/dist/{mediaKind-dk396a03.cjs → mediaKind-D0MWyv6b.cjs} +0 -0
  174. /package/dist/{mediaKind-De2Cx_kB.js → mediaKind-DmKMsjeY.js} +0 -0
  175. /package/dist/{pdf-u73U7-6s.js → pdf-DRXcPGkr.js} +0 -0
  176. /package/dist/{pdf-B24jYmSf.cjs → pdf-jLjjhvjp.cjs} +0 -0
  177. /package/dist/{pdf.worker.min-BPOWx2_9.js → pdf.worker.min-CfKZezeM.js} +0 -0
  178. /package/dist/{pdf.worker.min-BvhEiZFe.cjs → pdf.worker.min-bLgNWd7w.cjs} +0 -0
  179. /package/dist/{verifiedAccount-C1iCxopN.js → verifiedAccount-DRbRFJ6H.js} +0 -0
  180. /package/dist/{verifiedAccount-D3OeaOBo.cjs → verifiedAccount-DScyKk96.cjs} +0 -0
@@ -0,0 +1,269 @@
1
+ import { a as e, i as t, o as n, r, t as i } from "./PageTitle-D93YCiN8.js";
2
+ import { _ as a, b as o, o as s, sr as c, w as l, x as u } from "./TimeZoneField-DkI1Bkcz.js";
3
+ import { t as d, w as f } from "./DashboardNav-Dmn7PVSp.js";
4
+ import { L as p } from "./lucide-react-CA7GD7Nv.js";
5
+ import { t as m } from "./ConfirmModal-gKQEpd4d.js";
6
+ import { t as h } from "./SupportBar-CN_JGC-9.js";
7
+ import { useState as g } from "react";
8
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
9
+ import { Link as y } from "react-router-dom";
10
+ //#region src/pages/ThemeAdmin.tsx
11
+ var b = "fbos_theme_ai_draft", x = b, S = () => {
12
+ try {
13
+ return JSON.parse(localStorage.getItem(x) || "{}");
14
+ } catch {
15
+ return {};
16
+ }
17
+ }, C = (e) => {
18
+ let t = String(e?.defaultTheme || "").trim();
19
+ return t === "light" || t === "dark" ? t : null;
20
+ }, w = "My logo is attached to this message as a picture. Read the colours straight out of that picture and build this look from them — that is what matching my logo means. If no picture reached you, say so and ask me for it, rather than picking colours of your own.", T = "Do it all in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts — the colours, the typefaces and how rounded things are. Do not restyle by rewriting components, and do not put colours or a font of your own anywhere else.", E = "Choose the typefaces too, in the same file: fonts: { display, body } — a display face for the headings and a body face for everything else, each a Google Fonts family name spelled exactly as Google Fonts spells it, since the app loads it from there. Pick them for THIS brief the way you picked the colours: a luxury label, a playful shop and a law firm do not share a face, and the pair should look chosen together — the display face may be a serif, a slab, a geometric or a light grotesque, whatever the brief is about, while the body face stays easy to read at small sizes in both modes. Leaving fonts empty gives Inter, the face the app shipped in, which is the one choice that looks like no design at all.", D = "Use every colour the picture has, not just one. The accent is the one that stands out most — never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the logo instead of plain white or black. Read the exact shades off the picture; do not round them to the nearest colour you already know.", O = "Mix a palette of your own for this brief — more than one colour. The accent is the colour my brief is most about — the one its words and its mood lead with, not simply the loudest, and never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the palette instead of plain white or black.", k = "Be as bold as my brief allows and decide everything yourself: this is your design, and a look that could pass for a default is the one thing I do not want. Mix each shade for this look. A swatch you know by heart from Tailwind, Material or any other stock palette — #38bdf8, #0f172a, #f8fafc and their kind — means you did not look, so mix your own instead. Keep text readable on its background in both modes.", A = "Every mode needs these five: background, backgroundSecondary, foreground, accent and buttonText. The other colours the file allows — the button fade and its hover, the quiet button, panel fill and edge, the focus glow, the notification dot, the heading gradient, and the highlight behind text someone selects together with the colour of that selected text — are yours to set wherever the look calls for them, and a colourful look wants the button fade, the heading gradient and the selection highlight at the least: selected text left in a colour from the look before is the first thing people notice. Where I have named a colour myself, use my exact value. Anything left in the file that you did not choose for this look, delete rather than keep: a colour left over from the look before is what makes a new theme come out wrong.", j = "A colour I ask for is set in the dark colours and the light colours both, and where I name one, use my exact value. If the change touches the accent, the highlight behind selected text follows it. Mix any new shade; never a stock swatch.", M = (e, t) => String(e || "").trim() === String(t || "").trim(), N = (e, t) => e === "light" || e === "dark" ? t.defaultTheme === e && t.showThemeToggle === !1 : e === "system" ? t.defaultTheme === "system" : !1, P = (e, t) => {
21
+ if (!t) return e;
22
+ let n = { ...e };
23
+ return M(e.appName, t.appName) && delete n.appName, M(e.logoUrl, t.logoUrl) && delete n.logoUrl, M(e.faviconUrl, t.faviconUrl) && delete n.faviconUrl, N(String(e.defaultTheme || "").trim(), t) && delete n.defaultTheme, n;
24
+ }, F = "Before you tell me it is done, read the file back: if background, backgroundSecondary, foreground or accent is still the value it held when you started, in either mode, then you have not done what I asked — go and set it. And if every value you wrote is a stock swatch, you have not designed anything — go back and mix your own.", I = (e) => {
25
+ let t = C(e), n = "That is ten values at the least — five in dark, five in light — and every one of them changes: the colours in that file now are the look I am replacing, so a colour you leave where it is is the mistake I am trying to avoid.";
26
+ if (t) {
27
+ let e = t === "light" ? "dark" : "light";
28
+ return `My site is ${t} only, so the ${t} colours are the ones everyone sees — design those with the most care. Set the ${e} colours as well, the same look ${e === "dark" ? "at night" : "by day"}, since the file needs both. ${n}`;
29
+ }
30
+ return `Set the dark colours and the light colours both, so my site reads well either way — the same hues in both, dark mode being the same look at night, not a second palette. ${n}`;
31
+ }, L = (e) => {
32
+ let t = String(e?.brief || "").trim(), n = String(e?.logoUrl || "").trim() !== "";
33
+ return [...[
34
+ `Design the look of my whole app. Here is what I am after: ${t || "___"}`,
35
+ ...n ? [w] : [],
36
+ T,
37
+ I(e),
38
+ n ? D : O,
39
+ k,
40
+ E,
41
+ A,
42
+ ...V(e),
43
+ F
44
+ ], ...H].join("\n");
45
+ }, R = (e, t) => {
46
+ let n = String(e?.changes || "").trim(), r = P(e || {}, t);
47
+ return [...[
48
+ "My app already has a look I am happy with, in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts.",
49
+ "Change that one file, and change only what I ask for below — everything else in it stays exactly as it is: how rounded things are, fonts (unless my words are about the type), and every colour I have not mentioned. Do not tidy up, rebalance or improve anything I did not ask about, or restyle by rewriting components.",
50
+ j,
51
+ `Here is what I would like changed: ${n || "___"}`,
52
+ ...V(r, "change")
53
+ ], ...H].join("\n");
54
+ }, z = (e) => {
55
+ let t = String(e?.defaultTheme || "").trim();
56
+ return t === "light" || t === "dark" ? `In that same file, set defaultTheme to '${t}' and showThemeToggle to false: my site is ${t} only, and visitors get no switch.` : t === "system" ? "In that same file, set defaultTheme to 'system', so my site opens in whichever mode the visitor's device already uses, and leave showThemeToggle as it is." : "Leave defaultTheme exactly as it is — how my site opens is not part of this job, and changing it is not a redesign.";
57
+ }, B = "The empty space round that picture has already been cut away, and the top bar shows it whole, sized to the bar. Wherever you draw it yourself, size and place it as you see fit — but always the whole picture (fit=\"contain\"), never cropped, never padded out, never redrawn and never with any part of it cut off.", V = (e, t = "design") => {
58
+ let n = String(e?.appName || "").trim(), r = String(e?.logoUrl || "").trim(), i = String(e?.faviconUrl || "").trim(), a = [
59
+ "light",
60
+ "dark",
61
+ "system"
62
+ ].includes(String(e?.defaultTheme || "").trim()), o = a || t === "design" ? [z(e)] : [];
63
+ if (n && o.push(`In that same file, set appName to exactly: ${n}`), r && (o.push(`In that same file, set logoUrl to exactly this link: ${r} — that is my logo for the top bar. Use my link character for character, and never swap it for a placeholder or a picture of your own.`), o.push(B)), i && o.push(i === r ? "Set faviconUrl to that same link — it is my browser tab icon too." : `In that same file, set faviconUrl to exactly this link: ${i} — that is my browser tab icon. Use my link character for character.`), t === "change") {
64
+ let e = [
65
+ ...r ? [] : ["logoUrl"],
66
+ ...i ? [] : ["faviconUrl"],
67
+ ...n ? [] : ["appName"],
68
+ ...a ? [] : ["defaultTheme and showThemeToggle"]
69
+ ];
70
+ if (e.length) {
71
+ let t = e.length > 1 ? `${e.slice(0, -1).join(", ")} and ${e[e.length - 1]}` : e[0];
72
+ o.push(`Leave ${t} exactly as they are — not part of this change.`);
73
+ }
74
+ return o;
75
+ }
76
+ return !r && !i ? o.push("Leave logoUrl and faviconUrl exactly as they are. The logo and the browser tab icon are mine, and my Theme screen is the only place they change.") : r ? i || o.push("Leave faviconUrl exactly as it is — my browser tab icon is mine, and my Theme screen is the only place it changes.") : o.push("Leave logoUrl exactly as it is — my logo is mine, and my Theme screen is the only place it changes."), o;
77
+ }, H = ["Tell me what you picked and why, in one short paragraph."], U = (e, t = "design") => t === "change" ? String(e?.changes || "").trim() ? "" : "Say what you would like changed, and this sentence is ready to copy." : String(e?.brief || "").trim() ? "" : "Say what look you are after, and this sentence is ready to copy.";
78
+ function W() {
79
+ let { activeConfig: b } = f(), [C, w] = g(S), [T, E] = g(() => S().mode === "change" ? "change" : "design"), D = (e) => {
80
+ E(e), w((t) => {
81
+ let n = { ...t };
82
+ e === "change" ? n.mode = "change" : delete n.mode;
83
+ try {
84
+ localStorage.setItem(x, JSON.stringify(n));
85
+ } catch {}
86
+ return n;
87
+ });
88
+ }, O = (e, t) => w((n) => {
89
+ let r = {
90
+ ...n,
91
+ [e]: t
92
+ };
93
+ try {
94
+ localStorage.setItem(x, JSON.stringify(r));
95
+ } catch {}
96
+ return r;
97
+ }), [k, A] = g(!1), [j, M] = g(null), [N, P] = g(0), F = (e) => P((t) => Math.max(0, t + (e ? 1 : -1))), I = () => {
98
+ A(!0);
99
+ try {
100
+ localStorage.removeItem(x), localStorage.removeItem("theme-mode"), localStorage.removeItem("last-seen-default-theme"), localStorage.removeItem("theme_saved_cache");
101
+ } catch {}
102
+ w({}), E("design"), setTimeout(() => A(!1), 600);
103
+ };
104
+ return /* @__PURE__ */ v("main", {
105
+ className: "flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen",
106
+ children: [
107
+ /* @__PURE__ */ v(c.div, {
108
+ initial: {
109
+ opacity: 0,
110
+ y: 20
111
+ },
112
+ animate: {
113
+ opacity: 1,
114
+ y: 0
115
+ },
116
+ className: "mb-6",
117
+ children: [/* @__PURE__ */ _(i, { children: "Theme" }), /* @__PURE__ */ v("div", {
118
+ className: "flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]",
119
+ children: [/* @__PURE__ */ _("span", { className: "w-8 h-[1px] bg-foreground/10" }), "/theme"]
120
+ })]
121
+ }),
122
+ /* @__PURE__ */ v("div", {
123
+ className: "flex flex-col gap-6 flex-1 pb-16",
124
+ children: [/* @__PURE__ */ _(d, {}), /* @__PURE__ */ _("div", {
125
+ className: "glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col fbos-tab-fill",
126
+ children: /* @__PURE__ */ v("div", {
127
+ className: "flex flex-col gap-5",
128
+ children: [
129
+ /* @__PURE__ */ v("div", {
130
+ className: "flex items-start justify-between gap-3",
131
+ children: [/* @__PURE__ */ v("div", {
132
+ className: "min-w-0",
133
+ children: [/* @__PURE__ */ _("h2", {
134
+ className: "text-[17px] sm:text-xl font-bold text-foreground tracking-tight",
135
+ children: T === "change" ? "Change it with your assistant" : "Design it with your assistant"
136
+ }), /* @__PURE__ */ v("p", {
137
+ className: "text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5",
138
+ children: [/* @__PURE__ */ _("span", {
139
+ className: "sm:hidden",
140
+ children: "Fill these in for your assistant."
141
+ }), /* @__PURE__ */ _("span", {
142
+ className: "max-sm:hidden",
143
+ children: T === "change" ? "Say what to change, then copy the sentence below into your assistant’s chat. Nothing you do not mention is touched." : "Fill these in, then copy the sentence below into your assistant’s chat. It designs the whole look — colours, corners, logo — and there is nothing to set by hand."
144
+ })]
145
+ })]
146
+ }), /* @__PURE__ */ v("div", {
147
+ className: "shrink-0 flex items-center gap-2",
148
+ children: [/* @__PURE__ */ _(l, {
149
+ to: "/",
150
+ title: "View your app",
151
+ children: "View app"
152
+ }), /* @__PURE__ */ _(s, {
153
+ icon: p,
154
+ tone: "danger",
155
+ compact: !0,
156
+ busy: k,
157
+ title: "Start the whole look again",
158
+ onClick: () => M({
159
+ title: "Start the whole look again?",
160
+ message: "Your answers here clear and the sentence goes back to designing the whole look. Your theme file is not touched — copy the new sentence to your assistant to change it.",
161
+ apply: I
162
+ }),
163
+ children: "Start again"
164
+ })]
165
+ })]
166
+ }),
167
+ /* @__PURE__ */ _(e, {
168
+ label: "Logo",
169
+ hint: "The picture in the top bar. Attach this same picture in your assistant's chat — it cannot open the link, and the picture is where the colours come from.",
170
+ value: C.logoUrl || "",
171
+ onChange: (e) => O("logoUrl", e),
172
+ tips: t,
173
+ whole: !0,
174
+ trim: !0,
175
+ onBusyChange: F
176
+ }),
177
+ /* @__PURE__ */ _(e, {
178
+ label: "Browser tab icon",
179
+ hint: "The tiny picture on the browser tab.",
180
+ value: C.faviconUrl || "",
181
+ onChange: (e) => O("faviconUrl", e),
182
+ tips: r,
183
+ whole: !0,
184
+ onBusyChange: F
185
+ }),
186
+ /* @__PURE__ */ _(u, {
187
+ label: "App name",
188
+ hint: "It goes in the top bar and on the browser tab.",
189
+ value: C.appName || "",
190
+ onChange: (e) => O("appName", e),
191
+ placeholder: "Bright Studio"
192
+ }),
193
+ /* @__PURE__ */ _(a, {
194
+ label: "Light or dark",
195
+ hint: "Which one your app opens in. Always light or always dark means that one mode and no switch for visitors; otherwise whichever the visitor already uses on their device, with a switch.",
196
+ value: C.defaultTheme || "",
197
+ onChange: (e) => O("defaultTheme", e),
198
+ placeholder: "Leave it as it is",
199
+ options: [
200
+ {
201
+ value: "system",
202
+ label: "Whatever their device uses"
203
+ },
204
+ {
205
+ value: "light",
206
+ label: "Always light"
207
+ },
208
+ {
209
+ value: "dark",
210
+ label: "Always dark"
211
+ }
212
+ ]
213
+ }),
214
+ T === "change" ? /* @__PURE__ */ _(o, {
215
+ label: "What would you like changed?",
216
+ hint: "Name just the parts you want moved. Everything else stays as it is.",
217
+ value: C.changes || "",
218
+ onChange: (e) => O("changes", e),
219
+ placeholder: "Make the buttons a softer green, and warm up the page background a little. Leave the cards as they are."
220
+ }) : /* @__PURE__ */ _(o, {
221
+ label: "What look would you like?",
222
+ hint: "What you do, who it is for, and the feeling you are after. Your assistant designs the rest — the more feeling you give it, the further it goes.",
223
+ value: C.brief || "",
224
+ onChange: (e) => O("brief", e),
225
+ placeholder: "A calm, modern look for a small physiotherapy clinic. Soft greens, lots of white space, nothing shouty. Rounded corners."
226
+ }),
227
+ /* @__PURE__ */ _(n, {
228
+ title: "Copy this to your assistant",
229
+ prompt: T === "change" ? R(C, b) : L(C),
230
+ locked: !!U(C, T),
231
+ busy: N > 0,
232
+ onCopied: T === "change" ? void 0 : () => D("change")
233
+ }),
234
+ /* @__PURE__ */ v("p", {
235
+ className: "text-[11.5px] text-foreground/45 font-medium leading-snug px-1",
236
+ children: [
237
+ "That sentence is the only way the look changes — there is nothing to set by hand here. Uploads are kept on your",
238
+ " ",
239
+ /* @__PURE__ */ _(y, {
240
+ to: "/assets",
241
+ className: "text-accent font-bold hover:underline",
242
+ children: "Assets page"
243
+ }),
244
+ " ",
245
+ "too; edit the fields and copy the sentence again any time."
246
+ ]
247
+ })
248
+ ]
249
+ })
250
+ })]
251
+ }),
252
+ /* @__PURE__ */ _(h, {}),
253
+ /* @__PURE__ */ _(m, {
254
+ isOpen: !!j,
255
+ title: j?.title || "",
256
+ message: j?.message || "",
257
+ confirmText: "Start again",
258
+ cancelText: "Keep it",
259
+ isProcessing: k,
260
+ onCancel: () => M(null),
261
+ onConfirm: () => {
262
+ j?.apply(), M(null);
263
+ }
264
+ })
265
+ ]
266
+ });
267
+ }
268
+ //#endregion
269
+ export { U as a, R as i, b as n, L as o, W as r, B as t };
@@ -0,0 +1 @@
1
+ require(`./chunk-CiTBaPhY.cjs`);const e=require(`./ThemeAdmin-DY7Vc4Sj.cjs`);exports.ThemeAdmin=e.r;
@@ -0,0 +1,3 @@
1
+ const e=require(`./chunk-CiTBaPhY.cjs`),t=require(`./PageTitle-CZhgmmDT.cjs`),n=require(`./TimeZoneField-qs7NPR30.cjs`),r=require(`./DashboardNav-CXa_ci-_.cjs`),i=require(`./lucide-react-BwV6L6Is.cjs`),a=require(`./ConfirmModal-Di9GR-vV.cjs`),o=require(`./SupportBar-CDT0HwdP.cjs`);let s=require(`react`);s=e.a(s,1);let c=require(`react/jsx-runtime`),l=require(`react-router-dom`);var u=`fbos_theme_ai_draft`,d=u,f=()=>{try{return JSON.parse(localStorage.getItem(d)||`{}`)}catch{return{}}},p=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`||t===`dark`?t:null},m=`My logo is attached to this message as a picture. Read the colours straight out of that picture and build this look from them — that is what matching my logo means. If no picture reached you, say so and ask me for it, rather than picking colours of your own.`,h=`Do it all in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts — the colours, the typefaces and how rounded things are. Do not restyle by rewriting components, and do not put colours or a font of your own anywhere else.`,g=`Choose the typefaces too, in the same file: fonts: { display, body } — a display face for the headings and a body face for everything else, each a Google Fonts family name spelled exactly as Google Fonts spells it, since the app loads it from there. Pick them for THIS brief the way you picked the colours: a luxury label, a playful shop and a law firm do not share a face, and the pair should look chosen together — the display face may be a serif, a slab, a geometric or a light grotesque, whatever the brief is about, while the body face stays easy to read at small sizes in both modes. Leaving fonts empty gives Inter, the face the app shipped in, which is the one choice that looks like no design at all.`,_=`Use every colour the picture has, not just one. The accent is the one that stands out most — never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the logo instead of plain white or black. Read the exact shades off the picture; do not round them to the nearest colour you already know.`,v=`Mix a palette of your own for this brief — more than one colour. The accent is the colour my brief is most about — the one its words and its mood lead with, not simply the loudest, and never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the palette instead of plain white or black.`,y=`Be as bold as my brief allows and decide everything yourself: this is your design, and a look that could pass for a default is the one thing I do not want. Mix each shade for this look. A swatch you know by heart from Tailwind, Material or any other stock palette — #38bdf8, #0f172a, #f8fafc and their kind — means you did not look, so mix your own instead. Keep text readable on its background in both modes.`,b=`Every mode needs these five: background, backgroundSecondary, foreground, accent and buttonText. The other colours the file allows — the button fade and its hover, the quiet button, panel fill and edge, the focus glow, the notification dot, the heading gradient, and the highlight behind text someone selects together with the colour of that selected text — are yours to set wherever the look calls for them, and a colourful look wants the button fade, the heading gradient and the selection highlight at the least: selected text left in a colour from the look before is the first thing people notice. Where I have named a colour myself, use my exact value. Anything left in the file that you did not choose for this look, delete rather than keep: a colour left over from the look before is what makes a new theme come out wrong.`,x=`A colour I ask for is set in the dark colours and the light colours both, and where I name one, use my exact value. If the change touches the accent, the highlight behind selected text follows it. Mix any new shade; never a stock swatch.`,S=(e,t)=>String(e||``).trim()===String(t||``).trim(),C=(e,t)=>e===`light`||e===`dark`?t.defaultTheme===e&&t.showThemeToggle===!1:e===`system`?t.defaultTheme===`system`:!1,w=(e,t)=>{if(!t)return e;let n={...e};return S(e.appName,t.appName)&&delete n.appName,S(e.logoUrl,t.logoUrl)&&delete n.logoUrl,S(e.faviconUrl,t.faviconUrl)&&delete n.faviconUrl,C(String(e.defaultTheme||``).trim(),t)&&delete n.defaultTheme,n},T=`Before you tell me it is done, read the file back: if background, backgroundSecondary, foreground or accent is still the value it held when you started, in either mode, then you have not done what I asked — go and set it. And if every value you wrote is a stock swatch, you have not designed anything — go back and mix your own.`,E=e=>{let t=p(e),n=`That is ten values at the least — five in dark, five in light — and every one of them changes: the colours in that file now are the look I am replacing, so a colour you leave where it is is the mistake I am trying to avoid.`;if(t){let e=t===`light`?`dark`:`light`;return`My site is ${t} only, so the ${t} colours are the ones everyone sees — design those with the most care. Set the ${e} colours as well, the same look ${e===`dark`?`at night`:`by day`}, since the file needs both. ${n}`}return`Set the dark colours and the light colours both, so my site reads well either way — the same hues in both, dark mode being the same look at night, not a second palette. ${n}`},D=e=>{let t=String(e?.brief||``).trim(),n=String(e?.logoUrl||``).trim()!==``;return[...[`Design the look of my whole app. Here is what I am after: ${t||`___`}`,...n?[m]:[],h,E(e),n?_:v,y,g,b,...j(e),T],...M].join(`
2
+ `)},O=(e,t)=>{let n=String(e?.changes||``).trim(),r=w(e||{},t);return[...[`My app already has a look I am happy with, in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts.`,`Change that one file, and change only what I ask for below — everything else in it stays exactly as it is: how rounded things are, fonts (unless my words are about the type), and every colour I have not mentioned. Do not tidy up, rebalance or improve anything I did not ask about, or restyle by rewriting components.`,x,`Here is what I would like changed: ${n||`___`}`,...j(r,`change`)],...M].join(`
3
+ `)},k=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`||t===`dark`?`In that same file, set defaultTheme to '${t}' and showThemeToggle to false: my site is ${t} only, and visitors get no switch.`:t===`system`?`In that same file, set defaultTheme to 'system', so my site opens in whichever mode the visitor's device already uses, and leave showThemeToggle as it is.`:`Leave defaultTheme exactly as it is — how my site opens is not part of this job, and changing it is not a redesign.`},A=`The empty space round that picture has already been cut away, and the top bar shows it whole, sized to the bar. Wherever you draw it yourself, size and place it as you see fit — but always the whole picture (fit="contain"), never cropped, never padded out, never redrawn and never with any part of it cut off.`,j=(e,t=`design`)=>{let n=String(e?.appName||``).trim(),r=String(e?.logoUrl||``).trim(),i=String(e?.faviconUrl||``).trim(),a=[`light`,`dark`,`system`].includes(String(e?.defaultTheme||``).trim()),o=a||t===`design`?[k(e)]:[];if(n&&o.push(`In that same file, set appName to exactly: ${n}`),r&&(o.push(`In that same file, set logoUrl to exactly this link: ${r} — that is my logo for the top bar. Use my link character for character, and never swap it for a placeholder or a picture of your own.`),o.push(A)),i&&o.push(i===r?`Set faviconUrl to that same link — it is my browser tab icon too.`:`In that same file, set faviconUrl to exactly this link: ${i} — that is my browser tab icon. Use my link character for character.`),t===`change`){let e=[...r?[]:[`logoUrl`],...i?[]:[`faviconUrl`],...n?[]:[`appName`],...a?[]:[`defaultTheme and showThemeToggle`]];if(e.length){let t=e.length>1?`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`:e[0];o.push(`Leave ${t} exactly as they are — not part of this change.`)}return o}return!r&&!i?o.push(`Leave logoUrl and faviconUrl exactly as they are. The logo and the browser tab icon are mine, and my Theme screen is the only place they change.`):r?i||o.push(`Leave faviconUrl exactly as it is — my browser tab icon is mine, and my Theme screen is the only place it changes.`):o.push(`Leave logoUrl exactly as it is — my logo is mine, and my Theme screen is the only place it changes.`),o},M=[`Tell me what you picked and why, in one short paragraph.`],N=(e,t=`design`)=>t===`change`?String(e?.changes||``).trim()?``:`Say what you would like changed, and this sentence is ready to copy.`:String(e?.brief||``).trim()?``:`Say what look you are after, and this sentence is ready to copy.`;function P(){let{activeConfig:e}=r.w(),[u,p]=(0,s.useState)(f),[m,h]=(0,s.useState)(()=>f().mode===`change`?`change`:`design`),g=e=>{h(e),p(t=>{let n={...t};e===`change`?n.mode=`change`:delete n.mode;try{localStorage.setItem(d,JSON.stringify(n))}catch{}return n})},_=(e,t)=>p(n=>{let r={...n,[e]:t};try{localStorage.setItem(d,JSON.stringify(r))}catch{}return r}),[v,y]=(0,s.useState)(!1),[b,x]=(0,s.useState)(null),[S,C]=(0,s.useState)(0),w=e=>C(t=>Math.max(0,t+(e?1:-1))),T=()=>{y(!0);try{localStorage.removeItem(d),localStorage.removeItem(`theme-mode`),localStorage.removeItem(`last-seen-default-theme`),localStorage.removeItem(`theme_saved_cache`)}catch{}p({}),h(`design`),setTimeout(()=>y(!1),600)};return(0,c.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,c.jsxs)(n.sr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,c.jsx)(t.t,{children:`Theme`}),(0,c.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,c.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/theme`]})]}),(0,c.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,c.jsx)(r.t,{}),(0,c.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col fbos-tab-fill`,children:(0,c.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,c.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,c.jsxs)(`div`,{className:`min-w-0`,children:[(0,c.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-bold text-foreground tracking-tight`,children:m===`change`?`Change it with your assistant`:`Design it with your assistant`}),(0,c.jsxs)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:[(0,c.jsx)(`span`,{className:`sm:hidden`,children:`Fill these in for your assistant.`}),(0,c.jsx)(`span`,{className:`max-sm:hidden`,children:m===`change`?`Say what to change, then copy the sentence below into your assistant’s chat. Nothing you do not mention is touched.`:`Fill these in, then copy the sentence below into your assistant’s chat. It designs the whole look — colours, corners, logo — and there is nothing to set by hand.`})]})]}),(0,c.jsxs)(`div`,{className:`shrink-0 flex items-center gap-2`,children:[(0,c.jsx)(n.w,{to:`/`,title:`View your app`,children:`View app`}),(0,c.jsx)(n.o,{icon:i.L,tone:`danger`,compact:!0,busy:v,title:`Start the whole look again`,onClick:()=>x({title:`Start the whole look again?`,message:`Your answers here clear and the sentence goes back to designing the whole look. Your theme file is not touched — copy the new sentence to your assistant to change it.`,apply:T}),children:`Start again`})]})]}),(0,c.jsx)(t.a,{label:`Logo`,hint:`The picture in the top bar. Attach this same picture in your assistant's chat — it cannot open the link, and the picture is where the colours come from.`,value:u.logoUrl||``,onChange:e=>_(`logoUrl`,e),tips:t.i,whole:!0,trim:!0,onBusyChange:w}),(0,c.jsx)(t.a,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab.`,value:u.faviconUrl||``,onChange:e=>_(`faviconUrl`,e),tips:t.r,whole:!0,onBusyChange:w}),(0,c.jsx)(n.x,{label:`App name`,hint:`It goes in the top bar and on the browser tab.`,value:u.appName||``,onChange:e=>_(`appName`,e),placeholder:`Bright Studio`}),(0,c.jsx)(n._,{label:`Light or dark`,hint:`Which one your app opens in. Always light or always dark means that one mode and no switch for visitors; otherwise whichever the visitor already uses on their device, with a switch.`,value:u.defaultTheme||``,onChange:e=>_(`defaultTheme`,e),placeholder:`Leave it as it is`,options:[{value:`system`,label:`Whatever their device uses`},{value:`light`,label:`Always light`},{value:`dark`,label:`Always dark`}]}),m===`change`?(0,c.jsx)(n.b,{label:`What would you like changed?`,hint:`Name just the parts you want moved. Everything else stays as it is.`,value:u.changes||``,onChange:e=>_(`changes`,e),placeholder:`Make the buttons a softer green, and warm up the page background a little. Leave the cards as they are.`}):(0,c.jsx)(n.b,{label:`What look would you like?`,hint:`What you do, who it is for, and the feeling you are after. Your assistant designs the rest — the more feeling you give it, the further it goes.`,value:u.brief||``,onChange:e=>_(`brief`,e),placeholder:`A calm, modern look for a small physiotherapy clinic. Soft greens, lots of white space, nothing shouty. Rounded corners.`}),(0,c.jsx)(t.o,{title:`Copy this to your assistant`,prompt:m===`change`?O(u,e):D(u),locked:!!N(u,m),busy:S>0,onCopied:m===`change`?void 0:()=>g(`change`)}),(0,c.jsxs)(`p`,{className:`text-[11.5px] text-foreground/45 font-medium leading-snug px-1`,children:[`That sentence is the only way the look changes — there is nothing to set by hand here. Uploads are kept on your`,` `,(0,c.jsx)(l.Link,{to:`/assets`,className:`text-accent font-bold hover:underline`,children:`Assets page`}),` `,`too; edit the fields and copy the sentence again any time.`]})]})})]}),(0,c.jsx)(o.t,{}),(0,c.jsx)(a.t,{isOpen:!!b,title:b?.title||``,message:b?.message||``,confirmText:`Start again`,cancelText:`Keep it`,isProcessing:v,onCancel:()=>x(null),onConfirm:()=>{b?.apply(),x(null)}})]})}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return A}});
@@ -0,0 +1,2 @@
1
+ import { r as e } from "./ThemeAdmin-BzFjJkLg.js";
2
+ export { e as ThemeAdmin };