@omni-design/components 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/OmniDesignProvider.esm.js +1 -1
  2. package/dist/OmniDesignProvider.esm.js.map +1 -1
  3. package/dist/OmniDesignProvider.js +1 -1
  4. package/dist/OmniDesignProvider.js.map +1 -1
  5. package/dist/index.esm.js +8 -3
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +8 -3
  8. package/dist/index.js.map +1 -1
  9. package/dist/types/components/BackgroundPicker.d.ts +1 -1
  10. package/dist/types/components/BrandIcon/BrandIcon.d.ts +23 -0
  11. package/dist/types/components/BrandIcon/BrandIconShowcase.d.ts +2 -0
  12. package/dist/types/components/BrandIcon/index.d.ts +2 -0
  13. package/dist/types/components/Button/Button.d.ts +35 -66
  14. package/dist/types/components/ButtonGroup/ButtonGroup.d.ts +3 -1
  15. package/dist/types/components/Charts/tokens.d.ts +1 -1
  16. package/dist/types/components/CodeBlock/index.d.ts +1 -0
  17. package/dist/types/components/Footer/Footer.d.ts +3 -1
  18. package/dist/types/components/Foundations/FoundationTopic.d.ts +4 -0
  19. package/dist/types/components/Foundations/HowToSlot.d.ts +16 -0
  20. package/dist/types/components/Foundations/TokenRoles.d.ts +19 -0
  21. package/dist/types/components/Foundations/TypographySummary.d.ts +2 -0
  22. package/dist/types/components/List/List.d.ts +2 -1
  23. package/dist/types/components/Rail/Rail.d.ts +2 -1
  24. package/dist/types/components/ShowcaseHeader.d.ts +5 -0
  25. package/dist/types/components/Slider/Slider.d.ts +6 -3
  26. package/dist/types/components/TextField/TextField.d.ts +1 -1
  27. package/dist/types/components/ToggleButtonGroup/ToggleButtonGroup.d.ts +8 -5
  28. package/dist/types/components/ToggleButtonGroup/ToggleButtonGroupShowcase.d.ts +2 -0
  29. package/dist/types/components/ToggleButtonGroup/index.d.ts +2 -0
  30. package/dist/types/components/Typography/Typography.d.ts +54 -1
  31. package/dist/types/components/Typography/index.d.ts +1 -1
  32. package/dist/types/components/_states.d.ts +1 -1
  33. package/dist/types/components/a11yPanel.d.ts +58 -0
  34. package/dist/types/components/index.d.ts +3 -2
  35. package/dist/types/docs/DocPanels.d.ts +0 -14
  36. package/dist/types/docs/components.d.ts +131 -0
  37. package/dist/types/docs/componentsNav.d.ts +29 -13
  38. package/dist/types/docs/componentsSurfaces.d.ts +113 -10
  39. package/dist/types/docs/examples.d.ts +55 -34
  40. package/dist/types/docs/examples.lead.d.ts +89 -0
  41. package/dist/types/docs/figmaHowTo.d.ts +28 -0
  42. package/dist/types/docs/figmaLinks.d.ts +59 -0
  43. package/dist/types/docs/foundations.d.ts +12 -0
  44. package/dist/types/docs/samples.buttongroup.d.ts +22 -0
  45. package/dist/types/docs/samples.core.d.ts +104 -0
  46. package/dist/types/docs/samples.d.ts +27 -0
  47. package/dist/types/docs/samples.forms.d.ts +69 -0
  48. package/dist/types/docs/samples.nav.d.ts +70 -0
  49. package/dist/types/docs/samples.slider.d.ts +12 -0
  50. package/dist/types/docs/samples.surfaces.d.ts +69 -0
  51. package/package.json +4 -2
  52. package/public/styles/Dark-Mode.css +6 -0
  53. package/public/styles/Light-Mode.css +6 -0
  54. package/public/styles/README.md +1 -1
  55. package/public/styles/base.css +64 -19
  56. package/public/styles/core.css +94 -15
  57. package/public/styles/foundation.css +18 -0
  58. package/public/styles/typography-tokens.css +269 -20
  59. package/dist/types/theme/useThemeMode.d.ts +0 -4
@@ -1,2 +1,2 @@
1
- import{useState as e,useRef as t,useEffect as r,useCallback as n,useMemo as o,useContext as a,createContext as s}from"react";import{jsxs as l,jsx as i}from"react/jsx-runtime";const d=s(null),u=["Default","Primary","Secondary","Tertiary","Neutral","Info","Success","Warning","Error","App-Bar","Nav-Bar","Status"],c=["Professional","Modern","Bold","Playful"],m=["Surface-Dimmest","Surface-Dim","Surface","Surface-Bright","Surface-Brightest","Container","Container-Low","Container-Lowest","Container-High","Container-Highest"],f={"light-tonal":{theme:"Primary",rootSurface:"Surface-Brightest"},"grey-professional":{theme:"Neutral",rootSurface:"Surface"},"dark-professional":{theme:"Neutral",rootSurface:"Surface-Dimmest"}},h="omni-foundation",y="omni-core",g="omni-typography",S="omni-mode",p="omni-base",v="omni-styles";function k(e){document.getElementById(e)?.remove()}function P(e,t,r){return t?function(e){return!(!e||"string"!=typeof e)&&(e.startsWith("http")||e.startsWith("/")||e.endsWith(".css"))}(t)?function(e,t,r){const n=document.getElementById(e);return n?"LINK"===n.tagName&&n.getAttribute("href")!==t?new Promise((e,r)=>{n.onload=()=>e(n),n.onerror=()=>r(new Error(`OmniDesignProvider: failed to load ${t}`)),n.setAttribute("href",t)}):Promise.resolve(n):new Promise((n,o)=>{const a=document.createElement("link");a.id=e,a.rel="stylesheet",a.setAttribute("data-omni","true"),a.onload=()=>n(a),a.onerror=()=>o(new Error(`OmniDesignProvider: failed to load ${t}`)),a.href=t;const s=r?document.getElementById(r):null;s?document.head.insertBefore(a,s):document.head.appendChild(a)})}(e,t,r):function(e,t,r){if(!t)return Promise.resolve(null);const n=document.getElementById(e);if(n)return n.textContent=t,Promise.resolve(n);const o=document.createElement("style");o.id=e,o.setAttribute("data-omni","true"),o.textContent=t;const a=r?document.getElementById(r):null;return a?document.head.insertBefore(o,a):document.head.appendChild(o),Promise.resolve(o)}(e,t,r):Promise.resolve(null)}function D({themeURL:a,foundationCSS:s,coreCSS:D,typographyCSS:M,lightModeCSS:C,darkModeCSS:w,baseCSS:L,stylesCSS:b,defaultTheme:R="Default",defaultStyle:U="Modern",defaultSurface:N="Surface",surfaceStyle:T,defaultDarkMode:$=!1,darkTheme:B="Neutral",darkMode:E,onDarkModeChange:O,className:I,style:j,fullHeight:A=!0,children:x}){const[H,W]=e($),K=void 0!==E,q=K?E:H,[z,F]=e({foundation:s??null,core:D??null,typography:M??null,lightMode:C??null,darkMode:w??null,base:L??null,styles:b??null}),[G,J]=e({}),Q=t(!0);r(()=>(Q.current=!0,()=>{Q.current=!1}),[]),r(()=>{a&&(le("loading"),async function(e){const t=/\.json(\?|$)/.test(e)?e:`${e.replace(/\/$/,"")}/theme.json`,r=e.replace(/\/$/,"").replace(/\/theme\.json(\?.*)?$/,""),n=await fetch(t);if(!n.ok)throw new Error(`OmniDesignProvider: could not load theme manifest from ${t} (${n.status})`);const o=await n.json(),a=e=>e?/^https?:\/\//i.test(e)?e:`${r}/${e}`:null;return{foundationURL:a(o.foundation),coreURL:a(o.core),typographyURL:a(o.typography),lightModeURL:a(o.lightMode),darkModeURL:a(o.darkMode),baseURL:a(o.base),stylesURL:a(o.styles),defaultTheme:o.defaultTheme??null,defaultStyle:o.defaultStyle??null,defaultSurface:o.defaultSurface??null,darkTheme:o.darkTheme??null,name:o.name??null}}(a).then(e=>{Q.current&&(F({foundation:s??e.foundationURL,core:D??e.coreURL,typography:M??e.typographyURL,lightMode:C??e.lightModeURL,darkMode:w??e.darkModeURL,base:L??e.baseURL,styles:b??e.stylesURL}),J({defaultTheme:e.defaultTheme,defaultStyle:e.defaultStyle,defaultSurface:e.defaultSurface,darkTheme:e.darkTheme,name:e.name}))}).catch(e=>{Q.current&&(console.error("OmniDesignProvider: manifest error:",e),de(e.message),le("error"))}))},[a]);const V=T?f[T]?.theme??R:"Default"!==R?R:G.defaultTheme??R,X=T?f[T]?.rootSurface??N:G.defaultSurface??N,Y=G.defaultStyle??U,Z="Neutral"!==B?B:G.darkTheme??B,[_,ee]=e(V),[te,re]=e(Y),[ne,oe]=e(X),ae=!!(a||s||D||M||C||w||L||b),[se,le]=e(ae?"loading":"ready"),[ie,de]=e(null);r(()=>{const{foundation:e,core:t,typography:r,base:n,styles:o}=z;if(e||t||r||n||o)return le("loading"),de(null),Promise.all([P(h,e),P(y,t),P(g,r).catch(e=>{console.warn("OmniDesignProvider: typography CSS did not load —",e.message)}),P(p,n),P(v,o)]).then(()=>{Q.current&&le("ready")}).catch(e=>{Q.current&&(console.error("OmniDesignProvider CSS error:",e),de(e.message),le("error"))}),()=>{k(h),k(y),k(g),k(p),k(v)};le("ready")},[z.foundation,z.core,z.typography,z.base,z.styles]),r(()=>{const e=q?z.darkMode:z.lightMode;e&&P(S,e,p).catch(e=>console.error("OmniDesignProvider mode CSS error:",e))},[q,z.lightMode,z.darkMode]),r(()=>()=>k(S),[]);const ue=q?Z:_,ce=n(()=>{K?O?.(!q):W(e=>!e)},[K,q,O]),me=n(e=>{u.includes(e)||console.warn(`OmniDesignProvider: unknown theme "${e}"`),ee(e)},[]),fe=n(e=>{c.includes(e)||console.warn(`OmniDesignProvider: unknown style "${e}"`),re(e)},[]),he=n(e=>{m.includes(e)||console.warn(`OmniDesignProvider: unknown surface "${e}"`),oe(e)},[]),ye=o(()=>({theme:ue,style:te,surface:ne,isDark:q,cssStatus:se,cssError:ie,setTheme:me,setStyle:fe,setSurface:he,toggleDarkMode:ce,themes:u,styles:c,surfaces:m,name:G.name??null}),[ue,te,ne,q,se,ie,me,fe,he,ce,G.name]);return l(d.Provider,{value:ye,children:[i("style",{"data-omni":"hide-during-load",children:'[data-omni-css="loading"]{visibility:hidden}'}),i("div",{"data-theme":ue,"data-style":te,"data-surface":ne,"data-omni-css":se,className:I,style:{...A?{minHeight:"100vh"}:{},...j},children:x})]})}function M(){const e=a(d);if(!e)throw new Error("useOmniDesign must be used inside a <OmniDesignProvider>");return e}function C({theme:e,surface:t,as:r="div",children:n,className:o,style:a,...s}){return i(r,{"data-theme":e,"data-surface":t,className:o,style:a,...s,children:n})}function w({surface:e,as:t="div",children:r,className:n,style:o,...a}){return i(t,{"data-surface":e,className:n,style:o,...a,children:r})}const L=D,b=M,R=u,U=c,N=m;export{U as DYNO_STYLES,N as DYNO_SURFACES,R as DYNO_THEMES,L as DynoDesignProvider,c as OMNI_STYLES,m as OMNI_SURFACES,u as OMNI_THEMES,D as OmniDesignProvider,f as SURFACE_STYLE_THEME_MAP,w as Surfaced,C as ThemedZone,D as default,b as useDynoDesign,M as useOmniDesign};
1
+ import{useState as e,useRef as t,useEffect as r,useCallback as n,useMemo as o,useContext as a,createContext as s}from"react";import{jsxs as l,jsx as i}from"react/jsx-runtime";const d=s(null),u=["Default","Primary","Secondary","Tertiary","Neutral","Info","Success","Warning","Error","App-Bar","Nav-Bar","Status"],c=["Professional","Modern","Bold","Playful"],m=["Surface-Dimmest","Surface-Dim","Surface","Surface-Bright","Surface-Brightest","Container","Container-Low","Container-Lowest","Container-High","Container-Highest"],f={"light-tonal":{theme:"Primary",rootSurface:"Surface-Brightest"},"grey-professional":{theme:"Neutral",rootSurface:"Surface"},"dark-professional":{theme:"Neutral",rootSurface:"Surface-Dimmest"}},h="omni-foundation",y="omni-core",g="omni-typography",S="omni-mode",p="omni-base",v="omni-styles";function k(e){document.getElementById(e)?.remove()}function P(e,t,r){return t?function(e){return!(!e||"string"!=typeof e)&&(e.startsWith("http")||e.startsWith("/")||e.endsWith(".css"))}(t)?function(e,t,r){const n=document.getElementById(e);return n?"LINK"===n.tagName&&n.getAttribute("href")!==t?new Promise((e,r)=>{n.onload=()=>e(n),n.onerror=()=>r(new Error(`OmniDesignProvider: failed to load ${t}`)),n.setAttribute("href",t)}):Promise.resolve(n):new Promise((n,o)=>{const a=document.createElement("link");a.id=e,a.rel="stylesheet",a.setAttribute("data-omni","true"),a.onload=()=>n(a),a.onerror=()=>o(new Error(`OmniDesignProvider: failed to load ${t}`)),a.href=t;const s=r?document.getElementById(r):null;s?document.head.insertBefore(a,s):document.head.appendChild(a)})}(e,t,r):function(e,t,r){if(!t)return Promise.resolve(null);const n=document.getElementById(e);if(n)return n.textContent=t,Promise.resolve(n);const o=document.createElement("style");o.id=e,o.setAttribute("data-omni","true"),o.textContent=t;const a=r?document.getElementById(r):null;return a?document.head.insertBefore(o,a):document.head.appendChild(o),Promise.resolve(o)}(e,t,r):Promise.resolve(null)}function D({themeURL:a,foundationCSS:s,coreCSS:D,typographyCSS:M,lightModeCSS:C,darkModeCSS:w,baseCSS:L,stylesCSS:b,defaultTheme:R="Default",defaultStyle:U="Modern",defaultSurface:T="Surface",surfaceStyle:$,defaultDarkMode:B=!1,darkTheme:E=null,darkMode:N,onDarkModeChange:O,className:I,style:j,fullHeight:A=!0,children:x}){const[H,W]=e(B),K=void 0!==N,q=K?N:H,[z,F]=e({foundation:s??null,core:D??null,typography:M??null,lightMode:C??null,darkMode:w??null,base:L??null,styles:b??null}),[G,J]=e({}),Q=t(!0);r(()=>(Q.current=!0,()=>{Q.current=!1}),[]),r(()=>{a&&(le("loading"),async function(e){const t=/\.json(\?|$)/.test(e)?e:`${e.replace(/\/$/,"")}/theme.json`,r=e.replace(/\/$/,"").replace(/\/theme\.json(\?.*)?$/,""),n=await fetch(t);if(!n.ok)throw new Error(`OmniDesignProvider: could not load theme manifest from ${t} (${n.status})`);const o=await n.json(),a=e=>e?/^https?:\/\//i.test(e)?e:`${r}/${e}`:null;return{foundationURL:a(o.foundation),coreURL:a(o.core),typographyURL:a(o.typography),lightModeURL:a(o.lightMode),darkModeURL:a(o.darkMode),baseURL:a(o.base),stylesURL:a(o.styles),defaultTheme:o.defaultTheme??null,defaultStyle:o.defaultStyle??null,defaultSurface:o.defaultSurface??null,darkTheme:o.darkTheme??null,name:o.name??null}}(a).then(e=>{Q.current&&(F({foundation:s??e.foundationURL,core:D??e.coreURL,typography:M??e.typographyURL,lightMode:C??e.lightModeURL,darkMode:w??e.darkModeURL,base:L??e.baseURL,styles:b??e.stylesURL}),J({defaultTheme:e.defaultTheme,defaultStyle:e.defaultStyle,defaultSurface:e.defaultSurface,darkTheme:e.darkTheme,name:e.name}))}).catch(e=>{Q.current&&(console.error("OmniDesignProvider: manifest error:",e),de(e.message),le("error"))}))},[a]);const V=$?f[$]?.theme??R:"Default"!==R?R:G.defaultTheme??R,X=$?f[$]?.rootSurface??T:G.defaultSurface??T,Y=G.defaultStyle??U,Z=E??G.darkTheme??null,[_,ee]=e(V),[te,re]=e(Y),[ne,oe]=e(X),ae=!!(a||s||D||M||C||w||L||b),[se,le]=e(ae?"loading":"ready"),[ie,de]=e(null);r(()=>{const{foundation:e,core:t,typography:r,base:n,styles:o}=z;if(e||t||r||n||o)return le("loading"),de(null),Promise.all([P(h,e),P(y,t),P(g,r).catch(e=>{console.warn("OmniDesignProvider: typography CSS did not load —",e.message)}),P(p,n),P(v,o)]).then(()=>{Q.current&&le("ready")}).catch(e=>{Q.current&&(console.error("OmniDesignProvider CSS error:",e),de(e.message),le("error"))}),()=>{k(h),k(y),k(g),k(p),k(v)};le("ready")},[z.foundation,z.core,z.typography,z.base,z.styles]),r(()=>{const e=q?z.darkMode:z.lightMode;e&&P(S,e,p).catch(e=>console.error("OmniDesignProvider mode CSS error:",e))},[q,z.lightMode,z.darkMode]),r(()=>()=>k(S),[]);const ue=q&&Z?Z:_,ce=n(()=>{K?O?.(!q):W(e=>!e)},[K,q,O]),me=n(e=>{u.includes(e)||console.warn(`OmniDesignProvider: unknown theme "${e}"`),ee(e)},[]),fe=n(e=>{c.includes(e)||console.warn(`OmniDesignProvider: unknown style "${e}"`),re(e)},[]),he=n(e=>{m.includes(e)||console.warn(`OmniDesignProvider: unknown surface "${e}"`),oe(e)},[]),ye=o(()=>({theme:ue,style:te,surface:ne,isDark:q,cssStatus:se,cssError:ie,setTheme:me,setStyle:fe,setSurface:he,toggleDarkMode:ce,themes:u,styles:c,surfaces:m,name:G.name??null}),[ue,te,ne,q,se,ie,me,fe,he,ce,G.name]);return l(d.Provider,{value:ye,children:[i("style",{"data-omni":"hide-during-load",children:'[data-omni-css="loading"]{visibility:hidden}'}),i("div",{"data-theme":ue,"data-style":te,"data-surface":ne,"data-omni-css":se,className:I,style:{...A?{minHeight:"100vh"}:{},...j},children:x})]})}function M(){const e=a(d);if(!e)throw new Error("useOmniDesign must be used inside a <OmniDesignProvider>");return e}function C({theme:e,surface:t,as:r="div",children:n,className:o,style:a,...s}){return i(r,{"data-theme":e,"data-surface":t,className:o,style:a,...s,children:n})}function w({surface:e,as:t="div",children:r,className:n,style:o,...a}){return i(t,{"data-surface":e,className:n,style:o,...a,children:r})}const L=D,b=M,R=u,U=c,T=m;export{U as DYNO_STYLES,T as DYNO_SURFACES,R as DYNO_THEMES,L as DynoDesignProvider,c as OMNI_STYLES,m as OMNI_SURFACES,u as OMNI_THEMES,D as OmniDesignProvider,f as SURFACE_STYLE_THEME_MAP,w as Surfaced,C as ThemedZone,D as default,b as useDynoDesign,M as useOmniDesign};
2
2
  //# sourceMappingURL=OmniDesignProvider.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OmniDesignProvider.esm.js","sources":["../src/OmniDesignProvider.js"],"sourcesContent":["/**\n * OmniDesignProvider\n *\n * Wires the full OmniDesign token cascade into any React app.\n *\n * ── Two ways to provide CSS ───────────────────────────────────────────────────\n *\n * 1. SIMPLE — single themeURL (recommended):\n *\n * <OmniDesignProvider\n * themeURL=\"https://themes.omnidesign.com/acme-corp\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * The Provider fetches {themeURL}/theme.json to discover the CSS files,\n * then loads them in the correct order automatically.\n *\n * 2. MANUAL — individual CSS props (local dev / custom setups):\n *\n * <OmniDesignProvider\n * foundationCSS=\"/styles/foundation.css\"\n * coreCSS=\"/styles/core.css\"\n * typographyCSS=\"/styles/typography-tokens.css\"\n * lightModeCSS=\"/styles/Light-Mode.css\"\n * darkModeCSS=\"/styles/Dark-Mode.css\"\n * baseCSS=\"/styles/base.css\"\n * stylesCSS=\"/styles/styles.css\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * ── theme.json format ─────────────────────────────────────────────────────────\n *\n * {\n * \"foundation\": \"foundation.css\",\n * \"core\": \"core.css\",\n * \"typography\": \"typography-tokens.css\", // optional\n * \"lightMode\": \"Light-Mode.css\",\n * \"darkMode\": \"Dark-Mode.css\",\n * \"base\": \"base.css\",\n * \"styles\": \"styles.css\",\n * \"defaultTheme\": \"Default\",\n * \"defaultStyle\": \"Modern\",\n * \"defaultSurface\": \"Surface\",\n * \"darkTheme\": \"Neutral\"\n * }\n *\n * All fields are optional — only include the files you have.\n * Props passed directly to the Provider always override theme.json values.\n *\n * ── CSS load order ────────────────────────────────────────────────────────────\n * 1. foundation.css — primitives\n * 2. core.css — component base styles\n * 3. typography-tokens.css — platform type ramps (optional)\n * 4. Light-Mode.css OR Dark-Mode.css (one at a time, swaps on toggle)\n * 5. base.css — data-style / data-surface rules\n * 6. styles.css — final overrides\n *\n * ── How CSS is loaded ─────────────────────────────────────────────────────────\n * URL sources (the common production case) load as <link rel=\"stylesheet\">\n * tags. The browser fetches them in parallel, caches them, and blocks paint\n * until they apply — no flash of unbranded styling.\n *\n * Raw CSS strings (local dev, custom setups) load as <style> tags.\n *\n * While loading, the Provider wrapper carries data-omni-css=\"loading\" and is\n * visibility:hidden — once every sheet resolves it flips to \"ready\" and\n * becomes visible. Error state stays visible so the consumer can render\n * a fallback.\n */\n\nimport React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n} from 'react';\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nconst OmniDesignContext = createContext(null);\n\n// ─── Valid values ─────────────────────────────────────────────────────────────\n\n/* Nine themes plus the three bars. The -Light / -Medium / -Dark shades are\n * gone: a shade and a surface level were two ways of saying one thing, and the\n * surface ladder already walks that axis — `theme=\"Primary\"\n * surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n *\n * This list had kept all 24, so anything driven by it — a theme picker, a\n * validation check — offered fifteen names a generated design system does not\n * define. They bind nothing and paint the parent's palette, which reads as the\n * picker being broken rather than the name being dead. */\nexport const OMNI_THEMES = [\n 'Default',\n 'Primary', 'Secondary', 'Tertiary', 'Neutral',\n 'Info', 'Success', 'Warning', 'Error',\n 'App-Bar', 'Nav-Bar', 'Status',\n];\n\nexport const OMNI_STYLES = ['Professional', 'Modern', 'Bold', 'Playful'];\n\nexport const OMNI_SURFACES = [\n // Five surface levels, darkest to lightest. Surface-Dimmest and\n // Surface-Brightest are the ends of the ramp: Brightest is the level that\n // replaced the <Palette>-Light themes, so `theme=\"Primary\"\n // surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n 'Surface-Dimmest', 'Surface-Dim', 'Surface', 'Surface-Bright', 'Surface-Brightest',\n 'Container', 'Container-Low', 'Container-Lowest',\n 'Container-High', 'Container-Highest',\n];\n\nexport const SURFACE_STYLE_THEME_MAP = {\n // Primary at its brightest surface — what theme:'Primary-Light' used to mean,\n // and the only form generated design systems actually define.\n 'light-tonal': { theme: 'Primary', rootSurface: 'Surface-Brightest' },\n 'grey-professional': { theme: 'Neutral', rootSurface: 'Surface' },\n // The mirror of light-tonal: same palette, the other end of the ramp. What\n // theme:'Neutral-Dark' used to mean, and the only form that is defined.\n 'dark-professional': { theme: 'Neutral', rootSurface: 'Surface-Dimmest' },\n};\n\n// ─── Style tag IDs ────────────────────────────────────────────────────────────\n//\n// #omni-foundation (1st)\n// #omni-core (2nd)\n// #omni-typography (3rd) ← platform type ramps; must follow core\n// #omni-mode (4th) ← swaps between light/dark\n// #omni-base (5th)\n// #omni-styles (6th) ← always last\n\nconst TAG = {\n foundation: 'omni-foundation',\n core: 'omni-core',\n typography: 'omni-typography',\n mode: 'omni-mode',\n base: 'omni-base',\n styles: 'omni-styles',\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Detect whether a CSS source is a URL or a raw CSS string. URLs load via\n * <link rel=\"stylesheet\"> (render-blocking, browser-cached, no FOUC); raw\n * strings load via <style> (the only option for inline CSS).\n */\nfunction isURL(source) {\n if (!source || typeof source !== 'string') return false;\n return source.startsWith('http')\n || source.startsWith('/')\n || source.endsWith('.css');\n}\n\n/**\n * Insert a <link rel=\"stylesheet\"> for a URL source. Returns a Promise that\n * resolves when the stylesheet has loaded (so we can flip cssStatus to\n * 'ready' only after every brand sheet is actually applied — avoiding the\n * Provider-default-then-brand flicker that the fetch+<style> path causes).\n *\n * `beforeId` controls cascade order: pass the id of the tag that should come\n * AFTER this one. The lib's order is foundation → core → mode → base → styles,\n * and CSS variable resolution depends on it.\n */\nfunction injectLinkTag(id, href, beforeId) {\n const existing = document.getElementById(id);\n if (existing) {\n if (existing.tagName === 'LINK' && existing.getAttribute('href') !== href) {\n // Swap href in place — browser refetches. Use the existing onload so\n // callers can still await readiness on a mode swap.\n return new Promise((resolve, reject) => {\n existing.onload = () => resolve(existing);\n existing.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n existing.setAttribute('href', href);\n });\n }\n return Promise.resolve(existing);\n }\n return new Promise((resolve, reject) => {\n const tag = document.createElement('link');\n tag.id = id;\n tag.rel = 'stylesheet';\n tag.setAttribute('data-omni', 'true');\n tag.onload = () => resolve(tag);\n tag.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n tag.href = href;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n });\n}\n\n/**\n * Insert an inline <style> for a raw CSS string. Used only when the consumer\n * passes raw CSS (not a URL) — most production use cases are URLs and go\n * through injectLinkTag.\n */\nfunction injectStyleTag(id, css, beforeId) {\n if (!css) return Promise.resolve(null);\n const existing = document.getElementById(id);\n if (existing) {\n existing.textContent = css;\n return Promise.resolve(existing);\n }\n const tag = document.createElement('style');\n tag.id = id;\n tag.setAttribute('data-omni', 'true');\n tag.textContent = css;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n return Promise.resolve(tag);\n}\n\nfunction removeStyleTag(id) {\n document.getElementById(id)?.remove();\n}\n\n/**\n * Load a CSS source into the document at the position specified by beforeId.\n * Routes to <link> for URLs (no fetch round-trip; browser handles caching)\n * and <style> for raw CSS strings.\n */\nfunction loadCSSSource(id, source, beforeId) {\n if (!source) return Promise.resolve(null);\n if (isURL(source)) return injectLinkTag(id, source, beforeId);\n return injectStyleTag(id, source, beforeId);\n}\n\n/**\n * Fetch and parse theme.json from a themeURL.\n * Returns an object with resolved absolute URLs for each CSS file.\n *\n * @param {string} themeURL — base URL, e.g. \"https://themes.omnidesign.com/acme-corp\"\n * @returns {Promise<object>} — { foundationURL, coreURL, lightModeURL, darkModeURL,\n * baseURL, stylesURL, defaultTheme, defaultStyle,\n * defaultSurface, darkTheme }\n */\nasync function fetchThemeManifest(themeURL) {\n // If themeURL already points to a .json file (e.g. a Firebase Storage URL), use it directly.\n // Otherwise treat it as a folder and append /theme.json (legacy path-based hosting).\n const isManifestUrl = /\\.json(\\?|$)/.test(themeURL);\n const manifestURL = isManifestUrl ? themeURL : `${themeURL.replace(/\\/$/, '')}/theme.json`;\n // Folder base (used only for path-based fallback when manifest values are relative filenames)\n const base = themeURL.replace(/\\/$/, '').replace(/\\/theme\\.json(\\?.*)?$/, '');\n\n const res = await fetch(manifestURL);\n if (!res.ok) {\n throw new Error(`OmniDesignProvider: could not load theme manifest from ${manifestURL} (${res.status})`);\n }\n\n const manifest = await res.json();\n\n // Resolve each manifest entry. If it's already a full URL, pass it through unchanged.\n // Otherwise, treat it as a relative filename and join it with the folder base.\n const resolve = (value) => {\n if (!value) return null;\n if (/^https?:\\/\\//i.test(value)) return value;\n return `${base}/${value}`;\n };\n\n return {\n foundationURL: resolve(manifest.foundation),\n coreURL: resolve(manifest.core),\n typographyURL: resolve(manifest.typography),\n lightModeURL: resolve(manifest.lightMode),\n darkModeURL: resolve(manifest.darkMode),\n baseURL: resolve(manifest.base),\n stylesURL: resolve(manifest.styles),\n // Theme config from manifest (props override these)\n defaultTheme: manifest.defaultTheme ?? null,\n defaultStyle: manifest.defaultStyle ?? null,\n defaultSurface: manifest.defaultSurface ?? null,\n darkTheme: manifest.darkTheme ?? null,\n // Human-readable design system name — surfaced on the context so consumers\n // (AppBar brand, page headers, etc.) can display it.\n name: manifest.name ?? null,\n };\n}\n\n// ─── Provider ─────────────────────────────────────────────────────────────────\n\n/**\n * @param {object} props\n *\n * Theme URL (simplest — recommended for production):\n * @param {string} props.themeURL Base URL of the theme folder.\n * Must contain a theme.json manifest.\n * e.g. \"https://themes.omnidesign.com/acme-corp\"\n *\n * Individual CSS props (manual / local dev):\n * @param {string} props.foundationCSS foundation.css (URL or raw string)\n * @param {string} props.coreCSS core.css\n * @param {string} props.typographyCSS typography-tokens.css\n * @param {string} props.lightModeCSS Light-Mode.css\n * @param {string} props.darkModeCSS Dark-Mode.css\n * @param {string} props.baseCSS base.css\n * @param {string} props.stylesCSS styles.css (loaded last)\n *\n * Theme config (props override theme.json values):\n * @param {string} props.defaultTheme Starting data-theme (default: 'Default')\n * @param {string} props.defaultStyle Starting data-style (default: 'Modern')\n * @param {string} props.defaultSurface Root data-surface (default: 'Surface')\n * @param {string} props.surfaceStyle 'light-tonal' | 'grey-professional' | 'dark-professional'\n *\n * Dark mode — uncontrolled:\n * @param {boolean} props.defaultDarkMode Initial dark mode (default: false)\n * @param {string} props.darkTheme data-theme in dark mode (default: 'Neutral')\n *\n * Dark mode — controlled:\n * @param {boolean} props.darkMode\n * @param {function} props.onDarkModeChange\n *\n * DOM:\n * @param {string} props.className\n * @param {object} props.style\n * @param {boolean} props.fullHeight Adds minHeight: 100vh (default: true)\n * @param {React.ReactNode} props.children\n */\nexport function OmniDesignProvider({\n // Theme URL\n themeURL,\n\n // Individual CSS (manual / local dev)\n foundationCSS,\n coreCSS,\n typographyCSS,\n lightModeCSS,\n darkModeCSS,\n baseCSS,\n stylesCSS,\n\n // Theme config\n defaultTheme: defaultThemeProp = 'Default',\n defaultStyle: defaultStyleProp = 'Modern',\n defaultSurface: defaultSurfaceProp = 'Surface',\n surfaceStyle,\n\n // Dark mode\n defaultDarkMode = false,\n darkTheme: darkThemeProp = 'Neutral',\n\n // Controlled dark mode\n darkMode: controlledDarkMode,\n onDarkModeChange,\n\n // DOM\n className,\n style: styleProp,\n fullHeight = true,\n\n children,\n}) {\n\n // ── Dark mode ──────────────────────────────────────────────────────────────\n const [internalDark, setInternalDark] = useState(defaultDarkMode);\n const isControlled = controlledDarkMode !== undefined;\n const isDark = isControlled ? controlledDarkMode : internalDark;\n\n // ── Resolved CSS sources ───────────────────────────────────────────────────\n // When themeURL is provided, manifest values fill in anything not passed as props.\n const [resolvedSources, setResolvedSources] = useState({\n foundation: foundationCSS ?? null,\n core: coreCSS ?? null,\n typography: typographyCSS ?? null,\n lightMode: lightModeCSS ?? null,\n darkMode: darkModeCSS ?? null,\n base: baseCSS ?? null,\n styles: stylesCSS ?? null,\n });\n\n // Theme config — may be overridden by manifest values\n const [manifestThemeConfig, setManifestThemeConfig] = useState({});\n\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => { mountedRef.current = false; };\n }, []);\n\n // ── EFFECT: Fetch manifest if themeURL provided ────────────────────────────\n useEffect(() => {\n if (!themeURL) return;\n\n setCssStatus('loading');\n\n fetchThemeManifest(themeURL)\n .then(manifest => {\n if (!mountedRef.current) return;\n\n // Individual CSS props always take precedence over manifest\n setResolvedSources({\n foundation: foundationCSS ?? manifest.foundationURL,\n core: coreCSS ?? manifest.coreURL,\n typography: typographyCSS ?? manifest.typographyURL,\n lightMode: lightModeCSS ?? manifest.lightModeURL,\n darkMode: darkModeCSS ?? manifest.darkModeURL,\n base: baseCSS ?? manifest.baseURL,\n styles: stylesCSS ?? manifest.stylesURL,\n });\n\n // Store manifest theme config — props will override in render\n setManifestThemeConfig({\n defaultTheme: manifest.defaultTheme,\n defaultStyle: manifest.defaultStyle,\n defaultSurface: manifest.defaultSurface,\n darkTheme: manifest.darkTheme,\n name: manifest.name,\n });\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider: manifest error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n }, [themeURL]);\n\n // ── Theme / style / surface ────────────────────────────────────────────────\n // Priority: prop → manifest → default\n const resolvedDefaultTheme = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.theme ?? defaultThemeProp)\n : (defaultThemeProp !== 'Default' ? defaultThemeProp : (manifestThemeConfig.defaultTheme ?? defaultThemeProp));\n\n const resolvedDefaultSurface = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.rootSurface ?? defaultSurfaceProp)\n : (manifestThemeConfig.defaultSurface ?? defaultSurfaceProp);\n\n const resolvedDefaultStyle = manifestThemeConfig.defaultStyle ?? defaultStyleProp;\n const resolvedDarkTheme = darkThemeProp !== 'Neutral'\n ? darkThemeProp\n : (manifestThemeConfig.darkTheme ?? darkThemeProp);\n\n const [theme, setThemeState] = useState(resolvedDefaultTheme);\n const [styleVariant, setStyleVariant] = useState(resolvedDefaultStyle);\n const [rootSurface, setRootSurface] = useState(resolvedDefaultSurface);\n\n // ── CSS status ─────────────────────────────────────────────────────────────\n // 'loading' while sheets are in flight, 'ready' after they apply, 'error' on\n // a load failure. Initial value is 'ready' when the consumer passes neither\n // a themeURL nor any individual CSS prop — that case means they're using\n // the Provider only for theme-context (no brand sheets to load), so the\n // hide-during-load rule shouldn't keep the page invisible forever.\n const hasAnyCSSSource = !!(\n themeURL || foundationCSS || coreCSS || typographyCSS\n || lightModeCSS || darkModeCSS || baseCSS || stylesCSS\n );\n const [cssStatus, setCssStatus] = useState(hasAnyCSSSource ? 'loading' : 'ready');\n const [cssError, setCssError] = useState(null);\n\n // ── EFFECT: Inject static CSS (foundation, core, base, styles) ────────────\n // Injects each sheet in its correct cascade slot. URLs become <link> tags\n // (browser-cached, render-blocking — no flash); raw CSS strings become\n // <style> tags. The mode sheet's slot (#omni-mode) sits between core and\n // base; we anchor base/styles after it by passing the right beforeId so\n // the order stays foundation → core → mode → base → styles regardless of\n // which sheet resolves first.\n useEffect(() => {\n const { foundation, core, typography, base, styles } = resolvedSources;\n if (!foundation && !core && !typography && !base && !styles) {\n // Nothing in the static slots. The mode sheet, if there is one, loads on\n // its own effect below and needs nothing from here.\n //\n // This MUST still flip the status: 'loading' hides the whole tree behind\n // the anti-FOUC rule, so returning early without it left an app that\n // supplies only lightModeCSS/darkModeCSS — index.html carrying the rest —\n // permanently invisible.\n setCssStatus('ready');\n return;\n }\n\n setCssStatus('loading');\n setCssError(null);\n\n // Order matters: inject earlier slots first so later slots can use them\n // as `beforeId` anchors. Each call is non-blocking; we await the union\n // before flipping to 'ready' so we don't unhide before the brand actually\n // applies.\n // typography goes in after core and before base. It carries the platform\n // ramps under [data-platform=\"…\"], whose specificity ties with the :root\n // ramp in core.css — so whichever loads LAST wins, and the design\n // system's own ramp has to be the one that does. A design system that\n // ships no typography-tokens.css leaves this slot empty and the copy\n // bundled with the lib (linked from index.html) stands.\n Promise.all([\n loadCSSSource(TAG.foundation, foundation),\n loadCSSSource(TAG.core, core),\n // Optional slot: a design system that doesn't publish one must not take\n // the whole app down, so a failed load here is swallowed rather than\n // failing the Promise.all.\n loadCSSSource(TAG.typography, typography).catch(err => {\n console.warn('OmniDesignProvider: typography CSS did not load —', err.message);\n }),\n loadCSSSource(TAG.base, base),\n loadCSSSource(TAG.styles, styles),\n ])\n .then(() => {\n if (!mountedRef.current) return;\n setCssStatus('ready');\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider CSS error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n return () => {\n removeStyleTag(TAG.foundation);\n removeStyleTag(TAG.core);\n removeStyleTag(TAG.typography);\n removeStyleTag(TAG.base);\n removeStyleTag(TAG.styles);\n };\n }, [resolvedSources.foundation, resolvedSources.core, resolvedSources.typography,\n resolvedSources.base, resolvedSources.styles]);\n\n // ── EFFECT: Swap active mode CSS ──────────────────────────────────────────\n // Mode sheet inserts before #omni-base so the cascade slot is always\n // foundation → core → MODE → base → styles, regardless of dark/light\n // toggling order. <link> swap just changes href in place — the browser\n // refetches (cache-control on the storage layer decides whether the\n // network hit happens).\n useEffect(() => {\n const activeSource = isDark ? resolvedSources.darkMode : resolvedSources.lightMode;\n if (!activeSource) return;\n\n loadCSSSource(TAG.mode, activeSource, TAG.base)\n .catch(err => console.error('OmniDesignProvider mode CSS error:', err));\n\n }, [isDark, resolvedSources.lightMode, resolvedSources.darkMode]);\n\n // Cleanup mode tag on unmount\n useEffect(() => { return () => removeStyleTag(TAG.mode); }, []);\n\n // ── Public API ─────────────────────────────────────────────────────────────\n const activeTheme = isDark ? resolvedDarkTheme : theme;\n\n const toggleDarkMode = useCallback(() => {\n if (isControlled) onDarkModeChange?.(!isDark);\n else setInternalDark(d => !d);\n }, [isControlled, isDark, onDarkModeChange]);\n\n const setTheme = useCallback((next) => {\n if (!OMNI_THEMES.includes(next)) console.warn(`OmniDesignProvider: unknown theme \"${next}\"`);\n setThemeState(next);\n }, []);\n\n const setStyle = useCallback((next) => {\n if (!OMNI_STYLES.includes(next)) console.warn(`OmniDesignProvider: unknown style \"${next}\"`);\n setStyleVariant(next);\n }, []);\n\n const setSurface = useCallback((next) => {\n if (!OMNI_SURFACES.includes(next)) console.warn(`OmniDesignProvider: unknown surface \"${next}\"`);\n setRootSurface(next);\n }, []);\n\n // ── Context ────────────────────────────────────────────────────────────────\n const contextValue = useMemo(() => ({\n theme: activeTheme, style: styleVariant, surface: rootSurface,\n isDark, cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n themes: OMNI_THEMES, styles: OMNI_STYLES, surfaces: OMNI_SURFACES,\n name: manifestThemeConfig.name ?? null,\n }), [\n activeTheme, styleVariant, rootSurface, isDark,\n cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n manifestThemeConfig.name,\n ]);\n\n // ── Render ─────────────────────────────────────────────────────────────────\n // The inline <style> below is rendered as part of the React tree so the\n // hide rule is in the DOM before paint — without it, the consumer would\n // see the lib's <OmniDesignProvider>-default tokens for a frame before\n // the brand sheets resolve and apply. `data-omni-css=\"loading\"` flips to\n // `ready` (or `error`) once every brand sheet has finished loading, at\n // which point the wrapper becomes visible. Error state stays visible so\n // the consumer can render a fallback message.\n return (\n <OmniDesignContext.Provider value={contextValue}>\n <style data-omni=\"hide-during-load\">{`[data-omni-css=\"loading\"]{visibility:hidden}`}</style>\n <div\n data-theme={activeTheme}\n data-style={styleVariant}\n data-surface={rootSurface}\n data-omni-css={cssStatus}\n className={className}\n style={{ ...(fullHeight ? { minHeight: '100vh' } : {}), ...styleProp }}\n >\n {children}\n </div>\n </OmniDesignContext.Provider>\n );\n}\n\n// ─── Hook ─────────────────────────────────────────────────────────────────────\n\nexport function useOmniDesign() {\n const ctx = useContext(OmniDesignContext);\n if (!ctx) throw new Error('useOmniDesign must be used inside a <OmniDesignProvider>');\n return ctx;\n}\n\n// ─── ThemedZone ───────────────────────────────────────────────────────────────\n\nexport function ThemedZone({ theme, surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-theme={theme} data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ─── Surfaced ─────────────────────────────────────────────────────────────────\n\nexport function Surfaced({ surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ── Back-compat aliases ──────────────────────────────────────────────────────\n// The system was called DynoDesign before this release. A design system's API\n// is frozen for consumers the moment they install it, and they upgrade on their\n// own schedule, so the old names keep resolving. Write the Omni names.\nexport const DynoDesignProvider = OmniDesignProvider;\nexport const useDynoDesign = useOmniDesign;\nexport const DYNO_THEMES = OMNI_THEMES;\nexport const DYNO_STYLES = OMNI_STYLES;\nexport const DYNO_SURFACES = OMNI_SURFACES;\n\nexport default OmniDesignProvider;"],"names":["OmniDesignContext","createContext","OMNI_THEMES","OMNI_STYLES","OMNI_SURFACES","SURFACE_STYLE_THEME_MAP","theme","rootSurface","TAG","removeStyleTag","id","document","getElementById","remove","loadCSSSource","source","beforeId","startsWith","endsWith","isURL","href","existing","tagName","getAttribute","Promise","resolve","reject","onload","onerror","Error","setAttribute","tag","createElement","rel","before","head","insertBefore","appendChild","injectLinkTag","css","textContent","injectStyleTag","OmniDesignProvider","themeURL","foundationCSS","coreCSS","typographyCSS","lightModeCSS","darkModeCSS","baseCSS","stylesCSS","defaultTheme","defaultThemeProp","defaultStyle","defaultStyleProp","defaultSurface","defaultSurfaceProp","surfaceStyle","defaultDarkMode","darkTheme","darkThemeProp","darkMode","controlledDarkMode","onDarkModeChange","className","style","styleProp","fullHeight","children","internalDark","setInternalDark","useState","isControlled","undefined","isDark","resolvedSources","setResolvedSources","foundation","core","typography","lightMode","base","styles","manifestThemeConfig","setManifestThemeConfig","mountedRef","useRef","useEffect","current","setCssStatus","async","manifestURL","test","replace","res","fetch","ok","status","manifest","json","value","foundationURL","coreURL","typographyURL","lightModeURL","darkModeURL","baseURL","stylesURL","name","fetchThemeManifest","then","catch","err","console","error","setCssError","message","resolvedDefaultTheme","resolvedDefaultSurface","resolvedDefaultStyle","resolvedDarkTheme","setThemeState","styleVariant","setStyleVariant","setRootSurface","hasAnyCSSSource","cssStatus","cssError","all","warn","activeSource","activeTheme","toggleDarkMode","useCallback","d","setTheme","next","includes","setStyle","setSurface","contextValue","useMemo","surface","themes","surfaces","_jsxs","Provider","_jsx","minHeight","useOmniDesign","ctx","useContext","ThemedZone","as","Tag","rest","Surfaced","DynoDesignProvider","useDynoDesign","DYNO_THEMES","DYNO_STYLES","DYNO_SURFACES"],"mappings":"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"}
1
+ {"version":3,"file":"OmniDesignProvider.esm.js","sources":["../src/OmniDesignProvider.js"],"sourcesContent":["/**\n * OmniDesignProvider\n *\n * Wires the full OmniDesign token cascade into any React app.\n *\n * ── Two ways to provide CSS ───────────────────────────────────────────────────\n *\n * 1. SIMPLE — single themeURL (recommended):\n *\n * <OmniDesignProvider\n * themeURL=\"https://themes.omnidesign.com/acme-corp\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * The Provider fetches {themeURL}/theme.json to discover the CSS files,\n * then loads them in the correct order automatically.\n *\n * 2. MANUAL — individual CSS props (local dev / custom setups):\n *\n * <OmniDesignProvider\n * foundationCSS=\"/styles/foundation.css\"\n * coreCSS=\"/styles/core.css\"\n * typographyCSS=\"/styles/typography-tokens.css\"\n * lightModeCSS=\"/styles/Light-Mode.css\"\n * darkModeCSS=\"/styles/Dark-Mode.css\"\n * baseCSS=\"/styles/base.css\"\n * stylesCSS=\"/styles/styles.css\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * ── theme.json format ─────────────────────────────────────────────────────────\n *\n * {\n * \"foundation\": \"foundation.css\",\n * \"core\": \"core.css\",\n * \"typography\": \"typography-tokens.css\", // optional\n * \"lightMode\": \"Light-Mode.css\",\n * \"darkMode\": \"Dark-Mode.css\",\n * \"base\": \"base.css\",\n * \"styles\": \"styles.css\",\n * \"defaultTheme\": \"Default\",\n * \"defaultStyle\": \"Modern\",\n * \"defaultSurface\": \"Surface\",\n * \"darkTheme\": \"Neutral\"\n * }\n *\n * All fields are optional — only include the files you have.\n * Props passed directly to the Provider always override theme.json values.\n *\n * ── CSS load order ────────────────────────────────────────────────────────────\n * 1. foundation.css — primitives\n * 2. core.css — component base styles\n * 3. typography-tokens.css — platform type ramps (optional)\n * 4. Light-Mode.css OR Dark-Mode.css (one at a time, swaps on toggle)\n * 5. base.css — data-style / data-surface rules\n * 6. styles.css — final overrides\n *\n * ── How CSS is loaded ─────────────────────────────────────────────────────────\n * URL sources (the common production case) load as <link rel=\"stylesheet\">\n * tags. The browser fetches them in parallel, caches them, and blocks paint\n * until they apply — no flash of unbranded styling.\n *\n * Raw CSS strings (local dev, custom setups) load as <style> tags.\n *\n * While loading, the Provider wrapper carries data-omni-css=\"loading\" and is\n * visibility:hidden — once every sheet resolves it flips to \"ready\" and\n * becomes visible. Error state stays visible so the consumer can render\n * a fallback.\n */\n\nimport React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n} from 'react';\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nconst OmniDesignContext = createContext(null);\n\n// ─── Valid values ─────────────────────────────────────────────────────────────\n\n/* Nine themes plus the three bars. The -Light / -Medium / -Dark shades are\n * gone: a shade and a surface level were two ways of saying one thing, and the\n * surface ladder already walks that axis — `theme=\"Primary\"\n * surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n *\n * This list had kept all 24, so anything driven by it — a theme picker, a\n * validation check — offered fifteen names a generated design system does not\n * define. They bind nothing and paint the parent's palette, which reads as the\n * picker being broken rather than the name being dead. */\nexport const OMNI_THEMES = [\n 'Default',\n 'Primary', 'Secondary', 'Tertiary', 'Neutral',\n 'Info', 'Success', 'Warning', 'Error',\n 'App-Bar', 'Nav-Bar', 'Status',\n];\n\nexport const OMNI_STYLES = ['Professional', 'Modern', 'Bold', 'Playful'];\n\nexport const OMNI_SURFACES = [\n // Five surface levels, darkest to lightest. Surface-Dimmest and\n // Surface-Brightest are the ends of the ramp: Brightest is the level that\n // replaced the <Palette>-Light themes, so `theme=\"Primary\"\n // surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n 'Surface-Dimmest', 'Surface-Dim', 'Surface', 'Surface-Bright', 'Surface-Brightest',\n 'Container', 'Container-Low', 'Container-Lowest',\n 'Container-High', 'Container-Highest',\n];\n\nexport const SURFACE_STYLE_THEME_MAP = {\n // Primary at its brightest surface — what theme:'Primary-Light' used to mean,\n // and the only form generated design systems actually define.\n 'light-tonal': { theme: 'Primary', rootSurface: 'Surface-Brightest' },\n 'grey-professional': { theme: 'Neutral', rootSurface: 'Surface' },\n // The mirror of light-tonal: same palette, the other end of the ramp. What\n // theme:'Neutral-Dark' used to mean, and the only form that is defined.\n 'dark-professional': { theme: 'Neutral', rootSurface: 'Surface-Dimmest' },\n};\n\n// ─── Style tag IDs ────────────────────────────────────────────────────────────\n//\n// #omni-foundation (1st)\n// #omni-core (2nd)\n// #omni-typography (3rd) ← platform type ramps; must follow core\n// #omni-mode (4th) ← swaps between light/dark\n// #omni-base (5th)\n// #omni-styles (6th) ← always last\n\nconst TAG = {\n foundation: 'omni-foundation',\n core: 'omni-core',\n typography: 'omni-typography',\n mode: 'omni-mode',\n base: 'omni-base',\n styles: 'omni-styles',\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Detect whether a CSS source is a URL or a raw CSS string. URLs load via\n * <link rel=\"stylesheet\"> (render-blocking, browser-cached, no FOUC); raw\n * strings load via <style> (the only option for inline CSS).\n */\nfunction isURL(source) {\n if (!source || typeof source !== 'string') return false;\n return source.startsWith('http')\n || source.startsWith('/')\n || source.endsWith('.css');\n}\n\n/**\n * Insert a <link rel=\"stylesheet\"> for a URL source. Returns a Promise that\n * resolves when the stylesheet has loaded (so we can flip cssStatus to\n * 'ready' only after every brand sheet is actually applied — avoiding the\n * Provider-default-then-brand flicker that the fetch+<style> path causes).\n *\n * `beforeId` controls cascade order: pass the id of the tag that should come\n * AFTER this one. The lib's order is foundation → core → mode → base → styles,\n * and CSS variable resolution depends on it.\n */\nfunction injectLinkTag(id, href, beforeId) {\n const existing = document.getElementById(id);\n if (existing) {\n if (existing.tagName === 'LINK' && existing.getAttribute('href') !== href) {\n // Swap href in place — browser refetches. Use the existing onload so\n // callers can still await readiness on a mode swap.\n return new Promise((resolve, reject) => {\n existing.onload = () => resolve(existing);\n existing.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n existing.setAttribute('href', href);\n });\n }\n return Promise.resolve(existing);\n }\n return new Promise((resolve, reject) => {\n const tag = document.createElement('link');\n tag.id = id;\n tag.rel = 'stylesheet';\n tag.setAttribute('data-omni', 'true');\n tag.onload = () => resolve(tag);\n tag.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n tag.href = href;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n });\n}\n\n/**\n * Insert an inline <style> for a raw CSS string. Used only when the consumer\n * passes raw CSS (not a URL) — most production use cases are URLs and go\n * through injectLinkTag.\n */\nfunction injectStyleTag(id, css, beforeId) {\n if (!css) return Promise.resolve(null);\n const existing = document.getElementById(id);\n if (existing) {\n existing.textContent = css;\n return Promise.resolve(existing);\n }\n const tag = document.createElement('style');\n tag.id = id;\n tag.setAttribute('data-omni', 'true');\n tag.textContent = css;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n return Promise.resolve(tag);\n}\n\nfunction removeStyleTag(id) {\n document.getElementById(id)?.remove();\n}\n\n/**\n * Load a CSS source into the document at the position specified by beforeId.\n * Routes to <link> for URLs (no fetch round-trip; browser handles caching)\n * and <style> for raw CSS strings.\n */\nfunction loadCSSSource(id, source, beforeId) {\n if (!source) return Promise.resolve(null);\n if (isURL(source)) return injectLinkTag(id, source, beforeId);\n return injectStyleTag(id, source, beforeId);\n}\n\n/**\n * Fetch and parse theme.json from a themeURL.\n * Returns an object with resolved absolute URLs for each CSS file.\n *\n * @param {string} themeURL — base URL, e.g. \"https://themes.omnidesign.com/acme-corp\"\n * @returns {Promise<object>} — { foundationURL, coreURL, lightModeURL, darkModeURL,\n * baseURL, stylesURL, defaultTheme, defaultStyle,\n * defaultSurface, darkTheme }\n */\nasync function fetchThemeManifest(themeURL) {\n // If themeURL already points to a .json file (e.g. a Firebase Storage URL), use it directly.\n // Otherwise treat it as a folder and append /theme.json (legacy path-based hosting).\n const isManifestUrl = /\\.json(\\?|$)/.test(themeURL);\n const manifestURL = isManifestUrl ? themeURL : `${themeURL.replace(/\\/$/, '')}/theme.json`;\n // Folder base (used only for path-based fallback when manifest values are relative filenames)\n const base = themeURL.replace(/\\/$/, '').replace(/\\/theme\\.json(\\?.*)?$/, '');\n\n const res = await fetch(manifestURL);\n if (!res.ok) {\n throw new Error(`OmniDesignProvider: could not load theme manifest from ${manifestURL} (${res.status})`);\n }\n\n const manifest = await res.json();\n\n // Resolve each manifest entry. If it's already a full URL, pass it through unchanged.\n // Otherwise, treat it as a relative filename and join it with the folder base.\n const resolve = (value) => {\n if (!value) return null;\n if (/^https?:\\/\\//i.test(value)) return value;\n return `${base}/${value}`;\n };\n\n return {\n foundationURL: resolve(manifest.foundation),\n coreURL: resolve(manifest.core),\n typographyURL: resolve(manifest.typography),\n lightModeURL: resolve(manifest.lightMode),\n darkModeURL: resolve(manifest.darkMode),\n baseURL: resolve(manifest.base),\n stylesURL: resolve(manifest.styles),\n // Theme config from manifest (props override these)\n defaultTheme: manifest.defaultTheme ?? null,\n defaultStyle: manifest.defaultStyle ?? null,\n defaultSurface: manifest.defaultSurface ?? null,\n darkTheme: manifest.darkTheme ?? null,\n // Human-readable design system name — surfaced on the context so consumers\n // (AppBar brand, page headers, etc.) can display it.\n name: manifest.name ?? null,\n };\n}\n\n// ─── Provider ─────────────────────────────────────────────────────────────────\n\n/**\n * @param {object} props\n *\n * Theme URL (simplest — recommended for production):\n * @param {string} props.themeURL Base URL of the theme folder.\n * Must contain a theme.json manifest.\n * e.g. \"https://themes.omnidesign.com/acme-corp\"\n *\n * Individual CSS props (manual / local dev):\n * @param {string} props.foundationCSS foundation.css (URL or raw string)\n * @param {string} props.coreCSS core.css\n * @param {string} props.typographyCSS typography-tokens.css\n * @param {string} props.lightModeCSS Light-Mode.css\n * @param {string} props.darkModeCSS Dark-Mode.css\n * @param {string} props.baseCSS base.css\n * @param {string} props.stylesCSS styles.css (loaded last)\n *\n * Theme config (props override theme.json values):\n * @param {string} props.defaultTheme Starting data-theme (default: 'Default')\n * @param {string} props.defaultStyle Starting data-style (default: 'Modern')\n * @param {string} props.defaultSurface Root data-surface (default: 'Surface')\n * @param {string} props.surfaceStyle 'light-tonal' | 'grey-professional' | 'dark-professional'\n *\n * Dark mode — uncontrolled:\n * @param {boolean} props.defaultDarkMode Initial dark mode (default: false)\n * @param {string} props.darkTheme data-theme in dark mode (default: 'Neutral')\n *\n * Dark mode — controlled:\n * @param {boolean} props.darkMode\n * @param {function} props.onDarkModeChange\n *\n * DOM:\n * @param {string} props.className\n * @param {object} props.style\n * @param {boolean} props.fullHeight Adds minHeight: 100vh (default: true)\n * @param {React.ReactNode} props.children\n */\nexport function OmniDesignProvider({\n // Theme URL\n themeURL,\n\n // Individual CSS (manual / local dev)\n foundationCSS,\n coreCSS,\n typographyCSS,\n lightModeCSS,\n darkModeCSS,\n baseCSS,\n stylesCSS,\n\n // Theme config\n defaultTheme: defaultThemeProp = 'Default',\n defaultStyle: defaultStyleProp = 'Modern',\n defaultSurface: defaultSurfaceProp = 'Surface',\n surfaceStyle,\n\n // Dark mode\n defaultDarkMode = false,\n /* null, not 'Neutral'.\n This defaulted to 'Neutral' and activeTheme applied it unconditionally in\n dark mode, so the whole app became data-theme=\"Neutral\" the moment dark\n was switched on — and Neutral is the ONE palette that is light in dark\n mode. Figma: Neutral/Dark-Mode/Surface is #cccccc. That is the grey.\n It also discarded the chosen theme: pick Primary, switch to dark, get\n Neutral. The architecture doc says the opposite — \"the theme carries over,\n the tone does not\" — because the MODE is carried by the stylesheet\n (Light-Mode.css vs Dark-Mode.css), not by swapping palettes.\n The prop stays as an opt-in escape hatch for a brand that genuinely wants\n a different palette in dark; it simply no longer fires by default. */\n darkTheme: darkThemeProp = null,\n\n // Controlled dark mode\n darkMode: controlledDarkMode,\n onDarkModeChange,\n\n // DOM\n className,\n style: styleProp,\n fullHeight = true,\n\n children,\n}) {\n\n // ── Dark mode ──────────────────────────────────────────────────────────────\n const [internalDark, setInternalDark] = useState(defaultDarkMode);\n const isControlled = controlledDarkMode !== undefined;\n const isDark = isControlled ? controlledDarkMode : internalDark;\n\n // ── Resolved CSS sources ───────────────────────────────────────────────────\n // When themeURL is provided, manifest values fill in anything not passed as props.\n const [resolvedSources, setResolvedSources] = useState({\n foundation: foundationCSS ?? null,\n core: coreCSS ?? null,\n typography: typographyCSS ?? null,\n lightMode: lightModeCSS ?? null,\n darkMode: darkModeCSS ?? null,\n base: baseCSS ?? null,\n styles: stylesCSS ?? null,\n });\n\n // Theme config — may be overridden by manifest values\n const [manifestThemeConfig, setManifestThemeConfig] = useState({});\n\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => { mountedRef.current = false; };\n }, []);\n\n // ── EFFECT: Fetch manifest if themeURL provided ────────────────────────────\n useEffect(() => {\n if (!themeURL) return;\n\n setCssStatus('loading');\n\n fetchThemeManifest(themeURL)\n .then(manifest => {\n if (!mountedRef.current) return;\n\n // Individual CSS props always take precedence over manifest\n setResolvedSources({\n foundation: foundationCSS ?? manifest.foundationURL,\n core: coreCSS ?? manifest.coreURL,\n typography: typographyCSS ?? manifest.typographyURL,\n lightMode: lightModeCSS ?? manifest.lightModeURL,\n darkMode: darkModeCSS ?? manifest.darkModeURL,\n base: baseCSS ?? manifest.baseURL,\n styles: stylesCSS ?? manifest.stylesURL,\n });\n\n // Store manifest theme config — props will override in render\n setManifestThemeConfig({\n defaultTheme: manifest.defaultTheme,\n defaultStyle: manifest.defaultStyle,\n defaultSurface: manifest.defaultSurface,\n darkTheme: manifest.darkTheme,\n name: manifest.name,\n });\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider: manifest error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n }, [themeURL]);\n\n // ── Theme / style / surface ────────────────────────────────────────────────\n // Priority: prop → manifest → default\n const resolvedDefaultTheme = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.theme ?? defaultThemeProp)\n : (defaultThemeProp !== 'Default' ? defaultThemeProp : (manifestThemeConfig.defaultTheme ?? defaultThemeProp));\n\n const resolvedDefaultSurface = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.rootSurface ?? defaultSurfaceProp)\n : (manifestThemeConfig.defaultSurface ?? defaultSurfaceProp);\n\n const resolvedDefaultStyle = manifestThemeConfig.defaultStyle ?? defaultStyleProp;\n const resolvedDarkTheme = darkThemeProp ?? manifestThemeConfig.darkTheme ?? null;\n\n const [theme, setThemeState] = useState(resolvedDefaultTheme);\n const [styleVariant, setStyleVariant] = useState(resolvedDefaultStyle);\n const [rootSurface, setRootSurface] = useState(resolvedDefaultSurface);\n\n // ── CSS status ─────────────────────────────────────────────────────────────\n // 'loading' while sheets are in flight, 'ready' after they apply, 'error' on\n // a load failure. Initial value is 'ready' when the consumer passes neither\n // a themeURL nor any individual CSS prop — that case means they're using\n // the Provider only for theme-context (no brand sheets to load), so the\n // hide-during-load rule shouldn't keep the page invisible forever.\n const hasAnyCSSSource = !!(\n themeURL || foundationCSS || coreCSS || typographyCSS\n || lightModeCSS || darkModeCSS || baseCSS || stylesCSS\n );\n const [cssStatus, setCssStatus] = useState(hasAnyCSSSource ? 'loading' : 'ready');\n const [cssError, setCssError] = useState(null);\n\n // ── EFFECT: Inject static CSS (foundation, core, base, styles) ────────────\n // Injects each sheet in its correct cascade slot. URLs become <link> tags\n // (browser-cached, render-blocking — no flash); raw CSS strings become\n // <style> tags. The mode sheet's slot (#omni-mode) sits between core and\n // base; we anchor base/styles after it by passing the right beforeId so\n // the order stays foundation → core → mode → base → styles regardless of\n // which sheet resolves first.\n useEffect(() => {\n const { foundation, core, typography, base, styles } = resolvedSources;\n if (!foundation && !core && !typography && !base && !styles) {\n // Nothing in the static slots. The mode sheet, if there is one, loads on\n // its own effect below and needs nothing from here.\n //\n // This MUST still flip the status: 'loading' hides the whole tree behind\n // the anti-FOUC rule, so returning early without it left an app that\n // supplies only lightModeCSS/darkModeCSS — index.html carrying the rest —\n // permanently invisible.\n setCssStatus('ready');\n return;\n }\n\n setCssStatus('loading');\n setCssError(null);\n\n // Order matters: inject earlier slots first so later slots can use them\n // as `beforeId` anchors. Each call is non-blocking; we await the union\n // before flipping to 'ready' so we don't unhide before the brand actually\n // applies.\n // typography goes in after core and before base. It carries the platform\n // ramps under [data-platform=\"…\"], whose specificity ties with the :root\n // ramp in core.css — so whichever loads LAST wins, and the design\n // system's own ramp has to be the one that does. A design system that\n // ships no typography-tokens.css leaves this slot empty and the copy\n // bundled with the lib (linked from index.html) stands.\n Promise.all([\n loadCSSSource(TAG.foundation, foundation),\n loadCSSSource(TAG.core, core),\n // Optional slot: a design system that doesn't publish one must not take\n // the whole app down, so a failed load here is swallowed rather than\n // failing the Promise.all.\n loadCSSSource(TAG.typography, typography).catch(err => {\n console.warn('OmniDesignProvider: typography CSS did not load —', err.message);\n }),\n loadCSSSource(TAG.base, base),\n loadCSSSource(TAG.styles, styles),\n ])\n .then(() => {\n if (!mountedRef.current) return;\n setCssStatus('ready');\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider CSS error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n return () => {\n removeStyleTag(TAG.foundation);\n removeStyleTag(TAG.core);\n removeStyleTag(TAG.typography);\n removeStyleTag(TAG.base);\n removeStyleTag(TAG.styles);\n };\n }, [resolvedSources.foundation, resolvedSources.core, resolvedSources.typography,\n resolvedSources.base, resolvedSources.styles]);\n\n // ── EFFECT: Swap active mode CSS ──────────────────────────────────────────\n // Mode sheet inserts before #omni-base so the cascade slot is always\n // foundation → core → MODE → base → styles, regardless of dark/light\n // toggling order. <link> swap just changes href in place — the browser\n // refetches (cache-control on the storage layer decides whether the\n // network hit happens).\n useEffect(() => {\n const activeSource = isDark ? resolvedSources.darkMode : resolvedSources.lightMode;\n if (!activeSource) return;\n\n loadCSSSource(TAG.mode, activeSource, TAG.base)\n .catch(err => console.error('OmniDesignProvider mode CSS error:', err));\n\n }, [isDark, resolvedSources.lightMode, resolvedSources.darkMode]);\n\n // Cleanup mode tag on unmount\n useEffect(() => { return () => removeStyleTag(TAG.mode); }, []);\n\n // ── Public API ─────────────────────────────────────────────────────────────\n /* The chosen theme, in both modes. A dark theme applies only when one was\n explicitly asked for — otherwise dark mode is the same theme read from the\n dark stylesheet, which is what makes Primary stay Primary when you flip\n the switch. */\n const activeTheme = (isDark && resolvedDarkTheme) ? resolvedDarkTheme : theme;\n\n const toggleDarkMode = useCallback(() => {\n if (isControlled) onDarkModeChange?.(!isDark);\n else setInternalDark(d => !d);\n }, [isControlled, isDark, onDarkModeChange]);\n\n const setTheme = useCallback((next) => {\n if (!OMNI_THEMES.includes(next)) console.warn(`OmniDesignProvider: unknown theme \"${next}\"`);\n setThemeState(next);\n }, []);\n\n const setStyle = useCallback((next) => {\n if (!OMNI_STYLES.includes(next)) console.warn(`OmniDesignProvider: unknown style \"${next}\"`);\n setStyleVariant(next);\n }, []);\n\n const setSurface = useCallback((next) => {\n if (!OMNI_SURFACES.includes(next)) console.warn(`OmniDesignProvider: unknown surface \"${next}\"`);\n setRootSurface(next);\n }, []);\n\n // ── Context ────────────────────────────────────────────────────────────────\n const contextValue = useMemo(() => ({\n theme: activeTheme, style: styleVariant, surface: rootSurface,\n isDark, cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n themes: OMNI_THEMES, styles: OMNI_STYLES, surfaces: OMNI_SURFACES,\n name: manifestThemeConfig.name ?? null,\n }), [\n activeTheme, styleVariant, rootSurface, isDark,\n cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n manifestThemeConfig.name,\n ]);\n\n // ── Render ─────────────────────────────────────────────────────────────────\n // The inline <style> below is rendered as part of the React tree so the\n // hide rule is in the DOM before paint — without it, the consumer would\n // see the lib's <OmniDesignProvider>-default tokens for a frame before\n // the brand sheets resolve and apply. `data-omni-css=\"loading\"` flips to\n // `ready` (or `error`) once every brand sheet has finished loading, at\n // which point the wrapper becomes visible. Error state stays visible so\n // the consumer can render a fallback message.\n return (\n <OmniDesignContext.Provider value={contextValue}>\n <style data-omni=\"hide-during-load\">{`[data-omni-css=\"loading\"]{visibility:hidden}`}</style>\n <div\n data-theme={activeTheme}\n data-style={styleVariant}\n data-surface={rootSurface}\n data-omni-css={cssStatus}\n className={className}\n style={{ ...(fullHeight ? { minHeight: '100vh' } : {}), ...styleProp }}\n >\n {children}\n </div>\n </OmniDesignContext.Provider>\n );\n}\n\n// ─── Hook ─────────────────────────────────────────────────────────────────────\n\nexport function useOmniDesign() {\n const ctx = useContext(OmniDesignContext);\n if (!ctx) throw new Error('useOmniDesign must be used inside a <OmniDesignProvider>');\n return ctx;\n}\n\n// ─── ThemedZone ───────────────────────────────────────────────────────────────\n\nexport function ThemedZone({ theme, surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-theme={theme} data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ─── Surfaced ─────────────────────────────────────────────────────────────────\n\nexport function Surfaced({ surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ── Back-compat aliases ──────────────────────────────────────────────────────\n// The system was called DynoDesign before this release. A design system's API\n// is frozen for consumers the moment they install it, and they upgrade on their\n// own schedule, so the old names keep resolving. Write the Omni names.\nexport const DynoDesignProvider = OmniDesignProvider;\nexport const useDynoDesign = useOmniDesign;\nexport const DYNO_THEMES = OMNI_THEMES;\nexport const DYNO_STYLES = OMNI_STYLES;\nexport const DYNO_SURFACES = OMNI_SURFACES;\n\nexport default OmniDesignProvider;"],"names":["OmniDesignContext","createContext","OMNI_THEMES","OMNI_STYLES","OMNI_SURFACES","SURFACE_STYLE_THEME_MAP","theme","rootSurface","TAG","removeStyleTag","id","document","getElementById","remove","loadCSSSource","source","beforeId","startsWith","endsWith","isURL","href","existing","tagName","getAttribute","Promise","resolve","reject","onload","onerror","Error","setAttribute","tag","createElement","rel","before","head","insertBefore","appendChild","injectLinkTag","css","textContent","injectStyleTag","OmniDesignProvider","themeURL","foundationCSS","coreCSS","typographyCSS","lightModeCSS","darkModeCSS","baseCSS","stylesCSS","defaultTheme","defaultThemeProp","defaultStyle","defaultStyleProp","defaultSurface","defaultSurfaceProp","surfaceStyle","defaultDarkMode","darkTheme","darkThemeProp","darkMode","controlledDarkMode","onDarkModeChange","className","style","styleProp","fullHeight","children","internalDark","setInternalDark","useState","isControlled","undefined","isDark","resolvedSources","setResolvedSources","foundation","core","typography","lightMode","base","styles","manifestThemeConfig","setManifestThemeConfig","mountedRef","useRef","useEffect","current","setCssStatus","async","manifestURL","test","replace","res","fetch","ok","status","manifest","json","value","foundationURL","coreURL","typographyURL","lightModeURL","darkModeURL","baseURL","stylesURL","name","fetchThemeManifest","then","catch","err","console","error","setCssError","message","resolvedDefaultTheme","resolvedDefaultSurface","resolvedDefaultStyle","resolvedDarkTheme","setThemeState","styleVariant","setStyleVariant","setRootSurface","hasAnyCSSSource","cssStatus","cssError","all","warn","activeSource","activeTheme","toggleDarkMode","useCallback","d","setTheme","next","includes","setStyle","setSurface","contextValue","useMemo","surface","themes","surfaces","_jsxs","Provider","_jsx","minHeight","useOmniDesign","ctx","useContext","ThemedZone","as","Tag","rest","Surfaced","DynoDesignProvider","useDynoDesign","DYNO_THEMES","DYNO_STYLES","DYNO_SURFACES"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react/jsx-runtime");const r=e.createContext(null),n=["Default","Primary","Secondary","Tertiary","Neutral","Info","Success","Warning","Error","App-Bar","Nav-Bar","Status"],o=["Professional","Modern","Bold","Playful"],a=["Surface-Dimmest","Surface-Dim","Surface","Surface-Bright","Surface-Brightest","Container","Container-Low","Container-Lowest","Container-High","Container-Highest"],s={"light-tonal":{theme:"Primary",rootSurface:"Surface-Brightest"},"grey-professional":{theme:"Neutral",rootSurface:"Surface"},"dark-professional":{theme:"Neutral",rootSurface:"Surface-Dimmest"}},l="omni-foundation",u="omni-core",i="omni-typography",d="omni-mode",c="omni-base",m="omni-styles";function f(e){document.getElementById(e)?.remove()}function h(e,t,r){return t?function(e){return!(!e||"string"!=typeof e)&&(e.startsWith("http")||e.startsWith("/")||e.endsWith(".css"))}(t)?function(e,t,r){const n=document.getElementById(e);return n?"LINK"===n.tagName&&n.getAttribute("href")!==t?new Promise((e,r)=>{n.onload=()=>e(n),n.onerror=()=>r(new Error(`OmniDesignProvider: failed to load ${t}`)),n.setAttribute("href",t)}):Promise.resolve(n):new Promise((n,o)=>{const a=document.createElement("link");a.id=e,a.rel="stylesheet",a.setAttribute("data-omni","true"),a.onload=()=>n(a),a.onerror=()=>o(new Error(`OmniDesignProvider: failed to load ${t}`)),a.href=t;const s=r?document.getElementById(r):null;s?document.head.insertBefore(a,s):document.head.appendChild(a)})}(e,t,r):function(e,t,r){if(!t)return Promise.resolve(null);const n=document.getElementById(e);if(n)return n.textContent=t,Promise.resolve(n);const o=document.createElement("style");o.id=e,o.setAttribute("data-omni","true"),o.textContent=t;const a=r?document.getElementById(r):null;return a?document.head.insertBefore(o,a):document.head.appendChild(o),Promise.resolve(o)}(e,t,r):Promise.resolve(null)}function S({themeURL:S,foundationCSS:y,coreCSS:g,typographyCSS:p,lightModeCSS:D,darkModeCSS:M,baseCSS:v,stylesCSS:E,defaultTheme:k="Default",defaultStyle:C="Modern",defaultSurface:P="Surface",surfaceStyle:x,defaultDarkMode:L=!1,darkTheme:O="Neutral",darkMode:T,onDarkModeChange:b,className:N,style:w,fullHeight:R=!0,children:U}){const[$,B]=e.useState(L),j=void 0!==T,_=j?T:$,[I,A]=e.useState({foundation:y??null,core:g??null,typography:p??null,lightMode:D??null,darkMode:M??null,base:v??null,styles:E??null}),[H,Y]=e.useState({}),W=e.useRef(!0);e.useEffect(()=>(W.current=!0,()=>{W.current=!1}),[]),e.useEffect(()=>{S&&(re("loading"),async function(e){const t=/\.json(\?|$)/.test(e)?e:`${e.replace(/\/$/,"")}/theme.json`,r=e.replace(/\/$/,"").replace(/\/theme\.json(\?.*)?$/,""),n=await fetch(t);if(!n.ok)throw new Error(`OmniDesignProvider: could not load theme manifest from ${t} (${n.status})`);const o=await n.json(),a=e=>e?/^https?:\/\//i.test(e)?e:`${r}/${e}`:null;return{foundationURL:a(o.foundation),coreURL:a(o.core),typographyURL:a(o.typography),lightModeURL:a(o.lightMode),darkModeURL:a(o.darkMode),baseURL:a(o.base),stylesURL:a(o.styles),defaultTheme:o.defaultTheme??null,defaultStyle:o.defaultStyle??null,defaultSurface:o.defaultSurface??null,darkTheme:o.darkTheme??null,name:o.name??null}}(S).then(e=>{W.current&&(A({foundation:y??e.foundationURL,core:g??e.coreURL,typography:p??e.typographyURL,lightMode:D??e.lightModeURL,darkMode:M??e.darkModeURL,base:v??e.baseURL,styles:E??e.stylesURL}),Y({defaultTheme:e.defaultTheme,defaultStyle:e.defaultStyle,defaultSurface:e.defaultSurface,darkTheme:e.darkTheme,name:e.name}))}).catch(e=>{W.current&&(console.error("OmniDesignProvider: manifest error:",e),oe(e.message),re("error"))}))},[S]);const F=x?s[x]?.theme??k:"Default"!==k?k:H.defaultTheme??k,q=x?s[x]?.rootSurface??P:H.defaultSurface??P,K=H.defaultStyle??C,Z="Neutral"!==O?O:H.darkTheme??O,[z,G]=e.useState(F),[J,Q]=e.useState(K),[V,X]=e.useState(q),ee=!!(S||y||g||p||D||M||v||E),[te,re]=e.useState(ee?"loading":"ready"),[ne,oe]=e.useState(null);e.useEffect(()=>{const{foundation:e,core:t,typography:r,base:n,styles:o}=I;if(e||t||r||n||o)return re("loading"),oe(null),Promise.all([h(l,e),h(u,t),h(i,r).catch(e=>{console.warn("OmniDesignProvider: typography CSS did not load —",e.message)}),h(c,n),h(m,o)]).then(()=>{W.current&&re("ready")}).catch(e=>{W.current&&(console.error("OmniDesignProvider CSS error:",e),oe(e.message),re("error"))}),()=>{f(l),f(u),f(i),f(c),f(m)};re("ready")},[I.foundation,I.core,I.typography,I.base,I.styles]),e.useEffect(()=>{const e=_?I.darkMode:I.lightMode;e&&h(d,e,c).catch(e=>console.error("OmniDesignProvider mode CSS error:",e))},[_,I.lightMode,I.darkMode]),e.useEffect(()=>()=>f(d),[]);const ae=_?Z:z,se=e.useCallback(()=>{j?b?.(!_):B(e=>!e)},[j,_,b]),le=e.useCallback(e=>{n.includes(e)||console.warn(`OmniDesignProvider: unknown theme "${e}"`),G(e)},[]),ue=e.useCallback(e=>{o.includes(e)||console.warn(`OmniDesignProvider: unknown style "${e}"`),Q(e)},[]),ie=e.useCallback(e=>{a.includes(e)||console.warn(`OmniDesignProvider: unknown surface "${e}"`),X(e)},[]),de=e.useMemo(()=>({theme:ae,style:J,surface:V,isDark:_,cssStatus:te,cssError:ne,setTheme:le,setStyle:ue,setSurface:ie,toggleDarkMode:se,themes:n,styles:o,surfaces:a,name:H.name??null}),[ae,J,V,_,te,ne,le,ue,ie,se,H.name]);return t.jsxs(r.Provider,{value:de,children:[t.jsx("style",{"data-omni":"hide-during-load",children:'[data-omni-css="loading"]{visibility:hidden}'}),t.jsx("div",{"data-theme":ae,"data-style":J,"data-surface":V,"data-omni-css":te,className:N,style:{...R?{minHeight:"100vh"}:{},...w},children:U})]})}function y(){const t=e.useContext(r);if(!t)throw new Error("useOmniDesign must be used inside a <OmniDesignProvider>");return t}const g=S,p=y,D=n,M=o,v=a;exports.DYNO_STYLES=M,exports.DYNO_SURFACES=v,exports.DYNO_THEMES=D,exports.DynoDesignProvider=g,exports.OMNI_STYLES=o,exports.OMNI_SURFACES=a,exports.OMNI_THEMES=n,exports.OmniDesignProvider=S,exports.SURFACE_STYLE_THEME_MAP=s,exports.Surfaced=function({surface:e,as:r="div",children:n,className:o,style:a,...s}){return t.jsx(r,{"data-surface":e,className:o,style:a,...s,children:n})},exports.ThemedZone=function({theme:e,surface:r,as:n="div",children:o,className:a,style:s,...l}){return t.jsx(n,{"data-theme":e,"data-surface":r,className:a,style:s,...l,children:o})},exports.default=S,exports.useDynoDesign=p,exports.useOmniDesign=y;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react/jsx-runtime");const r=e.createContext(null),n=["Default","Primary","Secondary","Tertiary","Neutral","Info","Success","Warning","Error","App-Bar","Nav-Bar","Status"],o=["Professional","Modern","Bold","Playful"],a=["Surface-Dimmest","Surface-Dim","Surface","Surface-Bright","Surface-Brightest","Container","Container-Low","Container-Lowest","Container-High","Container-Highest"],s={"light-tonal":{theme:"Primary",rootSurface:"Surface-Brightest"},"grey-professional":{theme:"Neutral",rootSurface:"Surface"},"dark-professional":{theme:"Neutral",rootSurface:"Surface-Dimmest"}},l="omni-foundation",u="omni-core",i="omni-typography",d="omni-mode",c="omni-base",m="omni-styles";function f(e){document.getElementById(e)?.remove()}function h(e,t,r){return t?function(e){return!(!e||"string"!=typeof e)&&(e.startsWith("http")||e.startsWith("/")||e.endsWith(".css"))}(t)?function(e,t,r){const n=document.getElementById(e);return n?"LINK"===n.tagName&&n.getAttribute("href")!==t?new Promise((e,r)=>{n.onload=()=>e(n),n.onerror=()=>r(new Error(`OmniDesignProvider: failed to load ${t}`)),n.setAttribute("href",t)}):Promise.resolve(n):new Promise((n,o)=>{const a=document.createElement("link");a.id=e,a.rel="stylesheet",a.setAttribute("data-omni","true"),a.onload=()=>n(a),a.onerror=()=>o(new Error(`OmniDesignProvider: failed to load ${t}`)),a.href=t;const s=r?document.getElementById(r):null;s?document.head.insertBefore(a,s):document.head.appendChild(a)})}(e,t,r):function(e,t,r){if(!t)return Promise.resolve(null);const n=document.getElementById(e);if(n)return n.textContent=t,Promise.resolve(n);const o=document.createElement("style");o.id=e,o.setAttribute("data-omni","true"),o.textContent=t;const a=r?document.getElementById(r):null;return a?document.head.insertBefore(o,a):document.head.appendChild(o),Promise.resolve(o)}(e,t,r):Promise.resolve(null)}function S({themeURL:S,foundationCSS:y,coreCSS:g,typographyCSS:p,lightModeCSS:D,darkModeCSS:M,baseCSS:v,stylesCSS:E,defaultTheme:k="Default",defaultStyle:C="Modern",defaultSurface:P="Surface",surfaceStyle:x,defaultDarkMode:L=!1,darkTheme:O=null,darkMode:T,onDarkModeChange:b,className:w,style:R,fullHeight:N=!0,children:U}){const[$,B]=e.useState(L),j=void 0!==T,_=j?T:$,[I,A]=e.useState({foundation:y??null,core:g??null,typography:p??null,lightMode:D??null,darkMode:M??null,base:v??null,styles:E??null}),[H,Y]=e.useState({}),W=e.useRef(!0);e.useEffect(()=>(W.current=!0,()=>{W.current=!1}),[]),e.useEffect(()=>{S&&(re("loading"),async function(e){const t=/\.json(\?|$)/.test(e)?e:`${e.replace(/\/$/,"")}/theme.json`,r=e.replace(/\/$/,"").replace(/\/theme\.json(\?.*)?$/,""),n=await fetch(t);if(!n.ok)throw new Error(`OmniDesignProvider: could not load theme manifest from ${t} (${n.status})`);const o=await n.json(),a=e=>e?/^https?:\/\//i.test(e)?e:`${r}/${e}`:null;return{foundationURL:a(o.foundation),coreURL:a(o.core),typographyURL:a(o.typography),lightModeURL:a(o.lightMode),darkModeURL:a(o.darkMode),baseURL:a(o.base),stylesURL:a(o.styles),defaultTheme:o.defaultTheme??null,defaultStyle:o.defaultStyle??null,defaultSurface:o.defaultSurface??null,darkTheme:o.darkTheme??null,name:o.name??null}}(S).then(e=>{W.current&&(A({foundation:y??e.foundationURL,core:g??e.coreURL,typography:p??e.typographyURL,lightMode:D??e.lightModeURL,darkMode:M??e.darkModeURL,base:v??e.baseURL,styles:E??e.stylesURL}),Y({defaultTheme:e.defaultTheme,defaultStyle:e.defaultStyle,defaultSurface:e.defaultSurface,darkTheme:e.darkTheme,name:e.name}))}).catch(e=>{W.current&&(console.error("OmniDesignProvider: manifest error:",e),oe(e.message),re("error"))}))},[S]);const F=x?s[x]?.theme??k:"Default"!==k?k:H.defaultTheme??k,q=x?s[x]?.rootSurface??P:H.defaultSurface??P,K=H.defaultStyle??C,Z=O??H.darkTheme??null,[z,G]=e.useState(F),[J,Q]=e.useState(K),[V,X]=e.useState(q),ee=!!(S||y||g||p||D||M||v||E),[te,re]=e.useState(ee?"loading":"ready"),[ne,oe]=e.useState(null);e.useEffect(()=>{const{foundation:e,core:t,typography:r,base:n,styles:o}=I;if(e||t||r||n||o)return re("loading"),oe(null),Promise.all([h(l,e),h(u,t),h(i,r).catch(e=>{console.warn("OmniDesignProvider: typography CSS did not load —",e.message)}),h(c,n),h(m,o)]).then(()=>{W.current&&re("ready")}).catch(e=>{W.current&&(console.error("OmniDesignProvider CSS error:",e),oe(e.message),re("error"))}),()=>{f(l),f(u),f(i),f(c),f(m)};re("ready")},[I.foundation,I.core,I.typography,I.base,I.styles]),e.useEffect(()=>{const e=_?I.darkMode:I.lightMode;e&&h(d,e,c).catch(e=>console.error("OmniDesignProvider mode CSS error:",e))},[_,I.lightMode,I.darkMode]),e.useEffect(()=>()=>f(d),[]);const ae=_&&Z?Z:z,se=e.useCallback(()=>{j?b?.(!_):B(e=>!e)},[j,_,b]),le=e.useCallback(e=>{n.includes(e)||console.warn(`OmniDesignProvider: unknown theme "${e}"`),G(e)},[]),ue=e.useCallback(e=>{o.includes(e)||console.warn(`OmniDesignProvider: unknown style "${e}"`),Q(e)},[]),ie=e.useCallback(e=>{a.includes(e)||console.warn(`OmniDesignProvider: unknown surface "${e}"`),X(e)},[]),de=e.useMemo(()=>({theme:ae,style:J,surface:V,isDark:_,cssStatus:te,cssError:ne,setTheme:le,setStyle:ue,setSurface:ie,toggleDarkMode:se,themes:n,styles:o,surfaces:a,name:H.name??null}),[ae,J,V,_,te,ne,le,ue,ie,se,H.name]);return t.jsxs(r.Provider,{value:de,children:[t.jsx("style",{"data-omni":"hide-during-load",children:'[data-omni-css="loading"]{visibility:hidden}'}),t.jsx("div",{"data-theme":ae,"data-style":J,"data-surface":V,"data-omni-css":te,className:w,style:{...N?{minHeight:"100vh"}:{},...R},children:U})]})}function y(){const t=e.useContext(r);if(!t)throw new Error("useOmniDesign must be used inside a <OmniDesignProvider>");return t}const g=S,p=y,D=n,M=o,v=a;exports.DYNO_STYLES=M,exports.DYNO_SURFACES=v,exports.DYNO_THEMES=D,exports.DynoDesignProvider=g,exports.OMNI_STYLES=o,exports.OMNI_SURFACES=a,exports.OMNI_THEMES=n,exports.OmniDesignProvider=S,exports.SURFACE_STYLE_THEME_MAP=s,exports.Surfaced=function({surface:e,as:r="div",children:n,className:o,style:a,...s}){return t.jsx(r,{"data-surface":e,className:o,style:a,...s,children:n})},exports.ThemedZone=function({theme:e,surface:r,as:n="div",children:o,className:a,style:s,...l}){return t.jsx(n,{"data-theme":e,"data-surface":r,className:a,style:s,...l,children:o})},exports.default=S,exports.useDynoDesign=p,exports.useOmniDesign=y;
2
2
  //# sourceMappingURL=OmniDesignProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OmniDesignProvider.js","sources":["../src/OmniDesignProvider.js"],"sourcesContent":["/**\n * OmniDesignProvider\n *\n * Wires the full OmniDesign token cascade into any React app.\n *\n * ── Two ways to provide CSS ───────────────────────────────────────────────────\n *\n * 1. SIMPLE — single themeURL (recommended):\n *\n * <OmniDesignProvider\n * themeURL=\"https://themes.omnidesign.com/acme-corp\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * The Provider fetches {themeURL}/theme.json to discover the CSS files,\n * then loads them in the correct order automatically.\n *\n * 2. MANUAL — individual CSS props (local dev / custom setups):\n *\n * <OmniDesignProvider\n * foundationCSS=\"/styles/foundation.css\"\n * coreCSS=\"/styles/core.css\"\n * typographyCSS=\"/styles/typography-tokens.css\"\n * lightModeCSS=\"/styles/Light-Mode.css\"\n * darkModeCSS=\"/styles/Dark-Mode.css\"\n * baseCSS=\"/styles/base.css\"\n * stylesCSS=\"/styles/styles.css\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * ── theme.json format ─────────────────────────────────────────────────────────\n *\n * {\n * \"foundation\": \"foundation.css\",\n * \"core\": \"core.css\",\n * \"typography\": \"typography-tokens.css\", // optional\n * \"lightMode\": \"Light-Mode.css\",\n * \"darkMode\": \"Dark-Mode.css\",\n * \"base\": \"base.css\",\n * \"styles\": \"styles.css\",\n * \"defaultTheme\": \"Default\",\n * \"defaultStyle\": \"Modern\",\n * \"defaultSurface\": \"Surface\",\n * \"darkTheme\": \"Neutral\"\n * }\n *\n * All fields are optional — only include the files you have.\n * Props passed directly to the Provider always override theme.json values.\n *\n * ── CSS load order ────────────────────────────────────────────────────────────\n * 1. foundation.css — primitives\n * 2. core.css — component base styles\n * 3. typography-tokens.css — platform type ramps (optional)\n * 4. Light-Mode.css OR Dark-Mode.css (one at a time, swaps on toggle)\n * 5. base.css — data-style / data-surface rules\n * 6. styles.css — final overrides\n *\n * ── How CSS is loaded ─────────────────────────────────────────────────────────\n * URL sources (the common production case) load as <link rel=\"stylesheet\">\n * tags. The browser fetches them in parallel, caches them, and blocks paint\n * until they apply — no flash of unbranded styling.\n *\n * Raw CSS strings (local dev, custom setups) load as <style> tags.\n *\n * While loading, the Provider wrapper carries data-omni-css=\"loading\" and is\n * visibility:hidden — once every sheet resolves it flips to \"ready\" and\n * becomes visible. Error state stays visible so the consumer can render\n * a fallback.\n */\n\nimport React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n} from 'react';\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nconst OmniDesignContext = createContext(null);\n\n// ─── Valid values ─────────────────────────────────────────────────────────────\n\n/* Nine themes plus the three bars. The -Light / -Medium / -Dark shades are\n * gone: a shade and a surface level were two ways of saying one thing, and the\n * surface ladder already walks that axis — `theme=\"Primary\"\n * surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n *\n * This list had kept all 24, so anything driven by it — a theme picker, a\n * validation check — offered fifteen names a generated design system does not\n * define. They bind nothing and paint the parent's palette, which reads as the\n * picker being broken rather than the name being dead. */\nexport const OMNI_THEMES = [\n 'Default',\n 'Primary', 'Secondary', 'Tertiary', 'Neutral',\n 'Info', 'Success', 'Warning', 'Error',\n 'App-Bar', 'Nav-Bar', 'Status',\n];\n\nexport const OMNI_STYLES = ['Professional', 'Modern', 'Bold', 'Playful'];\n\nexport const OMNI_SURFACES = [\n // Five surface levels, darkest to lightest. Surface-Dimmest and\n // Surface-Brightest are the ends of the ramp: Brightest is the level that\n // replaced the <Palette>-Light themes, so `theme=\"Primary\"\n // surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n 'Surface-Dimmest', 'Surface-Dim', 'Surface', 'Surface-Bright', 'Surface-Brightest',\n 'Container', 'Container-Low', 'Container-Lowest',\n 'Container-High', 'Container-Highest',\n];\n\nexport const SURFACE_STYLE_THEME_MAP = {\n // Primary at its brightest surface — what theme:'Primary-Light' used to mean,\n // and the only form generated design systems actually define.\n 'light-tonal': { theme: 'Primary', rootSurface: 'Surface-Brightest' },\n 'grey-professional': { theme: 'Neutral', rootSurface: 'Surface' },\n // The mirror of light-tonal: same palette, the other end of the ramp. What\n // theme:'Neutral-Dark' used to mean, and the only form that is defined.\n 'dark-professional': { theme: 'Neutral', rootSurface: 'Surface-Dimmest' },\n};\n\n// ─── Style tag IDs ────────────────────────────────────────────────────────────\n//\n// #omni-foundation (1st)\n// #omni-core (2nd)\n// #omni-typography (3rd) ← platform type ramps; must follow core\n// #omni-mode (4th) ← swaps between light/dark\n// #omni-base (5th)\n// #omni-styles (6th) ← always last\n\nconst TAG = {\n foundation: 'omni-foundation',\n core: 'omni-core',\n typography: 'omni-typography',\n mode: 'omni-mode',\n base: 'omni-base',\n styles: 'omni-styles',\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Detect whether a CSS source is a URL or a raw CSS string. URLs load via\n * <link rel=\"stylesheet\"> (render-blocking, browser-cached, no FOUC); raw\n * strings load via <style> (the only option for inline CSS).\n */\nfunction isURL(source) {\n if (!source || typeof source !== 'string') return false;\n return source.startsWith('http')\n || source.startsWith('/')\n || source.endsWith('.css');\n}\n\n/**\n * Insert a <link rel=\"stylesheet\"> for a URL source. Returns a Promise that\n * resolves when the stylesheet has loaded (so we can flip cssStatus to\n * 'ready' only after every brand sheet is actually applied — avoiding the\n * Provider-default-then-brand flicker that the fetch+<style> path causes).\n *\n * `beforeId` controls cascade order: pass the id of the tag that should come\n * AFTER this one. The lib's order is foundation → core → mode → base → styles,\n * and CSS variable resolution depends on it.\n */\nfunction injectLinkTag(id, href, beforeId) {\n const existing = document.getElementById(id);\n if (existing) {\n if (existing.tagName === 'LINK' && existing.getAttribute('href') !== href) {\n // Swap href in place — browser refetches. Use the existing onload so\n // callers can still await readiness on a mode swap.\n return new Promise((resolve, reject) => {\n existing.onload = () => resolve(existing);\n existing.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n existing.setAttribute('href', href);\n });\n }\n return Promise.resolve(existing);\n }\n return new Promise((resolve, reject) => {\n const tag = document.createElement('link');\n tag.id = id;\n tag.rel = 'stylesheet';\n tag.setAttribute('data-omni', 'true');\n tag.onload = () => resolve(tag);\n tag.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n tag.href = href;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n });\n}\n\n/**\n * Insert an inline <style> for a raw CSS string. Used only when the consumer\n * passes raw CSS (not a URL) — most production use cases are URLs and go\n * through injectLinkTag.\n */\nfunction injectStyleTag(id, css, beforeId) {\n if (!css) return Promise.resolve(null);\n const existing = document.getElementById(id);\n if (existing) {\n existing.textContent = css;\n return Promise.resolve(existing);\n }\n const tag = document.createElement('style');\n tag.id = id;\n tag.setAttribute('data-omni', 'true');\n tag.textContent = css;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n return Promise.resolve(tag);\n}\n\nfunction removeStyleTag(id) {\n document.getElementById(id)?.remove();\n}\n\n/**\n * Load a CSS source into the document at the position specified by beforeId.\n * Routes to <link> for URLs (no fetch round-trip; browser handles caching)\n * and <style> for raw CSS strings.\n */\nfunction loadCSSSource(id, source, beforeId) {\n if (!source) return Promise.resolve(null);\n if (isURL(source)) return injectLinkTag(id, source, beforeId);\n return injectStyleTag(id, source, beforeId);\n}\n\n/**\n * Fetch and parse theme.json from a themeURL.\n * Returns an object with resolved absolute URLs for each CSS file.\n *\n * @param {string} themeURL — base URL, e.g. \"https://themes.omnidesign.com/acme-corp\"\n * @returns {Promise<object>} — { foundationURL, coreURL, lightModeURL, darkModeURL,\n * baseURL, stylesURL, defaultTheme, defaultStyle,\n * defaultSurface, darkTheme }\n */\nasync function fetchThemeManifest(themeURL) {\n // If themeURL already points to a .json file (e.g. a Firebase Storage URL), use it directly.\n // Otherwise treat it as a folder and append /theme.json (legacy path-based hosting).\n const isManifestUrl = /\\.json(\\?|$)/.test(themeURL);\n const manifestURL = isManifestUrl ? themeURL : `${themeURL.replace(/\\/$/, '')}/theme.json`;\n // Folder base (used only for path-based fallback when manifest values are relative filenames)\n const base = themeURL.replace(/\\/$/, '').replace(/\\/theme\\.json(\\?.*)?$/, '');\n\n const res = await fetch(manifestURL);\n if (!res.ok) {\n throw new Error(`OmniDesignProvider: could not load theme manifest from ${manifestURL} (${res.status})`);\n }\n\n const manifest = await res.json();\n\n // Resolve each manifest entry. If it's already a full URL, pass it through unchanged.\n // Otherwise, treat it as a relative filename and join it with the folder base.\n const resolve = (value) => {\n if (!value) return null;\n if (/^https?:\\/\\//i.test(value)) return value;\n return `${base}/${value}`;\n };\n\n return {\n foundationURL: resolve(manifest.foundation),\n coreURL: resolve(manifest.core),\n typographyURL: resolve(manifest.typography),\n lightModeURL: resolve(manifest.lightMode),\n darkModeURL: resolve(manifest.darkMode),\n baseURL: resolve(manifest.base),\n stylesURL: resolve(manifest.styles),\n // Theme config from manifest (props override these)\n defaultTheme: manifest.defaultTheme ?? null,\n defaultStyle: manifest.defaultStyle ?? null,\n defaultSurface: manifest.defaultSurface ?? null,\n darkTheme: manifest.darkTheme ?? null,\n // Human-readable design system name — surfaced on the context so consumers\n // (AppBar brand, page headers, etc.) can display it.\n name: manifest.name ?? null,\n };\n}\n\n// ─── Provider ─────────────────────────────────────────────────────────────────\n\n/**\n * @param {object} props\n *\n * Theme URL (simplest — recommended for production):\n * @param {string} props.themeURL Base URL of the theme folder.\n * Must contain a theme.json manifest.\n * e.g. \"https://themes.omnidesign.com/acme-corp\"\n *\n * Individual CSS props (manual / local dev):\n * @param {string} props.foundationCSS foundation.css (URL or raw string)\n * @param {string} props.coreCSS core.css\n * @param {string} props.typographyCSS typography-tokens.css\n * @param {string} props.lightModeCSS Light-Mode.css\n * @param {string} props.darkModeCSS Dark-Mode.css\n * @param {string} props.baseCSS base.css\n * @param {string} props.stylesCSS styles.css (loaded last)\n *\n * Theme config (props override theme.json values):\n * @param {string} props.defaultTheme Starting data-theme (default: 'Default')\n * @param {string} props.defaultStyle Starting data-style (default: 'Modern')\n * @param {string} props.defaultSurface Root data-surface (default: 'Surface')\n * @param {string} props.surfaceStyle 'light-tonal' | 'grey-professional' | 'dark-professional'\n *\n * Dark mode — uncontrolled:\n * @param {boolean} props.defaultDarkMode Initial dark mode (default: false)\n * @param {string} props.darkTheme data-theme in dark mode (default: 'Neutral')\n *\n * Dark mode — controlled:\n * @param {boolean} props.darkMode\n * @param {function} props.onDarkModeChange\n *\n * DOM:\n * @param {string} props.className\n * @param {object} props.style\n * @param {boolean} props.fullHeight Adds minHeight: 100vh (default: true)\n * @param {React.ReactNode} props.children\n */\nexport function OmniDesignProvider({\n // Theme URL\n themeURL,\n\n // Individual CSS (manual / local dev)\n foundationCSS,\n coreCSS,\n typographyCSS,\n lightModeCSS,\n darkModeCSS,\n baseCSS,\n stylesCSS,\n\n // Theme config\n defaultTheme: defaultThemeProp = 'Default',\n defaultStyle: defaultStyleProp = 'Modern',\n defaultSurface: defaultSurfaceProp = 'Surface',\n surfaceStyle,\n\n // Dark mode\n defaultDarkMode = false,\n darkTheme: darkThemeProp = 'Neutral',\n\n // Controlled dark mode\n darkMode: controlledDarkMode,\n onDarkModeChange,\n\n // DOM\n className,\n style: styleProp,\n fullHeight = true,\n\n children,\n}) {\n\n // ── Dark mode ──────────────────────────────────────────────────────────────\n const [internalDark, setInternalDark] = useState(defaultDarkMode);\n const isControlled = controlledDarkMode !== undefined;\n const isDark = isControlled ? controlledDarkMode : internalDark;\n\n // ── Resolved CSS sources ───────────────────────────────────────────────────\n // When themeURL is provided, manifest values fill in anything not passed as props.\n const [resolvedSources, setResolvedSources] = useState({\n foundation: foundationCSS ?? null,\n core: coreCSS ?? null,\n typography: typographyCSS ?? null,\n lightMode: lightModeCSS ?? null,\n darkMode: darkModeCSS ?? null,\n base: baseCSS ?? null,\n styles: stylesCSS ?? null,\n });\n\n // Theme config — may be overridden by manifest values\n const [manifestThemeConfig, setManifestThemeConfig] = useState({});\n\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => { mountedRef.current = false; };\n }, []);\n\n // ── EFFECT: Fetch manifest if themeURL provided ────────────────────────────\n useEffect(() => {\n if (!themeURL) return;\n\n setCssStatus('loading');\n\n fetchThemeManifest(themeURL)\n .then(manifest => {\n if (!mountedRef.current) return;\n\n // Individual CSS props always take precedence over manifest\n setResolvedSources({\n foundation: foundationCSS ?? manifest.foundationURL,\n core: coreCSS ?? manifest.coreURL,\n typography: typographyCSS ?? manifest.typographyURL,\n lightMode: lightModeCSS ?? manifest.lightModeURL,\n darkMode: darkModeCSS ?? manifest.darkModeURL,\n base: baseCSS ?? manifest.baseURL,\n styles: stylesCSS ?? manifest.stylesURL,\n });\n\n // Store manifest theme config — props will override in render\n setManifestThemeConfig({\n defaultTheme: manifest.defaultTheme,\n defaultStyle: manifest.defaultStyle,\n defaultSurface: manifest.defaultSurface,\n darkTheme: manifest.darkTheme,\n name: manifest.name,\n });\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider: manifest error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n }, [themeURL]);\n\n // ── Theme / style / surface ────────────────────────────────────────────────\n // Priority: prop → manifest → default\n const resolvedDefaultTheme = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.theme ?? defaultThemeProp)\n : (defaultThemeProp !== 'Default' ? defaultThemeProp : (manifestThemeConfig.defaultTheme ?? defaultThemeProp));\n\n const resolvedDefaultSurface = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.rootSurface ?? defaultSurfaceProp)\n : (manifestThemeConfig.defaultSurface ?? defaultSurfaceProp);\n\n const resolvedDefaultStyle = manifestThemeConfig.defaultStyle ?? defaultStyleProp;\n const resolvedDarkTheme = darkThemeProp !== 'Neutral'\n ? darkThemeProp\n : (manifestThemeConfig.darkTheme ?? darkThemeProp);\n\n const [theme, setThemeState] = useState(resolvedDefaultTheme);\n const [styleVariant, setStyleVariant] = useState(resolvedDefaultStyle);\n const [rootSurface, setRootSurface] = useState(resolvedDefaultSurface);\n\n // ── CSS status ─────────────────────────────────────────────────────────────\n // 'loading' while sheets are in flight, 'ready' after they apply, 'error' on\n // a load failure. Initial value is 'ready' when the consumer passes neither\n // a themeURL nor any individual CSS prop — that case means they're using\n // the Provider only for theme-context (no brand sheets to load), so the\n // hide-during-load rule shouldn't keep the page invisible forever.\n const hasAnyCSSSource = !!(\n themeURL || foundationCSS || coreCSS || typographyCSS\n || lightModeCSS || darkModeCSS || baseCSS || stylesCSS\n );\n const [cssStatus, setCssStatus] = useState(hasAnyCSSSource ? 'loading' : 'ready');\n const [cssError, setCssError] = useState(null);\n\n // ── EFFECT: Inject static CSS (foundation, core, base, styles) ────────────\n // Injects each sheet in its correct cascade slot. URLs become <link> tags\n // (browser-cached, render-blocking — no flash); raw CSS strings become\n // <style> tags. The mode sheet's slot (#omni-mode) sits between core and\n // base; we anchor base/styles after it by passing the right beforeId so\n // the order stays foundation → core → mode → base → styles regardless of\n // which sheet resolves first.\n useEffect(() => {\n const { foundation, core, typography, base, styles } = resolvedSources;\n if (!foundation && !core && !typography && !base && !styles) {\n // Nothing in the static slots. The mode sheet, if there is one, loads on\n // its own effect below and needs nothing from here.\n //\n // This MUST still flip the status: 'loading' hides the whole tree behind\n // the anti-FOUC rule, so returning early without it left an app that\n // supplies only lightModeCSS/darkModeCSS — index.html carrying the rest —\n // permanently invisible.\n setCssStatus('ready');\n return;\n }\n\n setCssStatus('loading');\n setCssError(null);\n\n // Order matters: inject earlier slots first so later slots can use them\n // as `beforeId` anchors. Each call is non-blocking; we await the union\n // before flipping to 'ready' so we don't unhide before the brand actually\n // applies.\n // typography goes in after core and before base. It carries the platform\n // ramps under [data-platform=\"…\"], whose specificity ties with the :root\n // ramp in core.css — so whichever loads LAST wins, and the design\n // system's own ramp has to be the one that does. A design system that\n // ships no typography-tokens.css leaves this slot empty and the copy\n // bundled with the lib (linked from index.html) stands.\n Promise.all([\n loadCSSSource(TAG.foundation, foundation),\n loadCSSSource(TAG.core, core),\n // Optional slot: a design system that doesn't publish one must not take\n // the whole app down, so a failed load here is swallowed rather than\n // failing the Promise.all.\n loadCSSSource(TAG.typography, typography).catch(err => {\n console.warn('OmniDesignProvider: typography CSS did not load —', err.message);\n }),\n loadCSSSource(TAG.base, base),\n loadCSSSource(TAG.styles, styles),\n ])\n .then(() => {\n if (!mountedRef.current) return;\n setCssStatus('ready');\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider CSS error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n return () => {\n removeStyleTag(TAG.foundation);\n removeStyleTag(TAG.core);\n removeStyleTag(TAG.typography);\n removeStyleTag(TAG.base);\n removeStyleTag(TAG.styles);\n };\n }, [resolvedSources.foundation, resolvedSources.core, resolvedSources.typography,\n resolvedSources.base, resolvedSources.styles]);\n\n // ── EFFECT: Swap active mode CSS ──────────────────────────────────────────\n // Mode sheet inserts before #omni-base so the cascade slot is always\n // foundation → core → MODE → base → styles, regardless of dark/light\n // toggling order. <link> swap just changes href in place — the browser\n // refetches (cache-control on the storage layer decides whether the\n // network hit happens).\n useEffect(() => {\n const activeSource = isDark ? resolvedSources.darkMode : resolvedSources.lightMode;\n if (!activeSource) return;\n\n loadCSSSource(TAG.mode, activeSource, TAG.base)\n .catch(err => console.error('OmniDesignProvider mode CSS error:', err));\n\n }, [isDark, resolvedSources.lightMode, resolvedSources.darkMode]);\n\n // Cleanup mode tag on unmount\n useEffect(() => { return () => removeStyleTag(TAG.mode); }, []);\n\n // ── Public API ─────────────────────────────────────────────────────────────\n const activeTheme = isDark ? resolvedDarkTheme : theme;\n\n const toggleDarkMode = useCallback(() => {\n if (isControlled) onDarkModeChange?.(!isDark);\n else setInternalDark(d => !d);\n }, [isControlled, isDark, onDarkModeChange]);\n\n const setTheme = useCallback((next) => {\n if (!OMNI_THEMES.includes(next)) console.warn(`OmniDesignProvider: unknown theme \"${next}\"`);\n setThemeState(next);\n }, []);\n\n const setStyle = useCallback((next) => {\n if (!OMNI_STYLES.includes(next)) console.warn(`OmniDesignProvider: unknown style \"${next}\"`);\n setStyleVariant(next);\n }, []);\n\n const setSurface = useCallback((next) => {\n if (!OMNI_SURFACES.includes(next)) console.warn(`OmniDesignProvider: unknown surface \"${next}\"`);\n setRootSurface(next);\n }, []);\n\n // ── Context ────────────────────────────────────────────────────────────────\n const contextValue = useMemo(() => ({\n theme: activeTheme, style: styleVariant, surface: rootSurface,\n isDark, cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n themes: OMNI_THEMES, styles: OMNI_STYLES, surfaces: OMNI_SURFACES,\n name: manifestThemeConfig.name ?? null,\n }), [\n activeTheme, styleVariant, rootSurface, isDark,\n cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n manifestThemeConfig.name,\n ]);\n\n // ── Render ─────────────────────────────────────────────────────────────────\n // The inline <style> below is rendered as part of the React tree so the\n // hide rule is in the DOM before paint — without it, the consumer would\n // see the lib's <OmniDesignProvider>-default tokens for a frame before\n // the brand sheets resolve and apply. `data-omni-css=\"loading\"` flips to\n // `ready` (or `error`) once every brand sheet has finished loading, at\n // which point the wrapper becomes visible. Error state stays visible so\n // the consumer can render a fallback message.\n return (\n <OmniDesignContext.Provider value={contextValue}>\n <style data-omni=\"hide-during-load\">{`[data-omni-css=\"loading\"]{visibility:hidden}`}</style>\n <div\n data-theme={activeTheme}\n data-style={styleVariant}\n data-surface={rootSurface}\n data-omni-css={cssStatus}\n className={className}\n style={{ ...(fullHeight ? { minHeight: '100vh' } : {}), ...styleProp }}\n >\n {children}\n </div>\n </OmniDesignContext.Provider>\n );\n}\n\n// ─── Hook ─────────────────────────────────────────────────────────────────────\n\nexport function useOmniDesign() {\n const ctx = useContext(OmniDesignContext);\n if (!ctx) throw new Error('useOmniDesign must be used inside a <OmniDesignProvider>');\n return ctx;\n}\n\n// ─── ThemedZone ───────────────────────────────────────────────────────────────\n\nexport function ThemedZone({ theme, surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-theme={theme} data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ─── Surfaced ─────────────────────────────────────────────────────────────────\n\nexport function Surfaced({ surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ── Back-compat aliases ──────────────────────────────────────────────────────\n// The system was called DynoDesign before this release. A design system's API\n// is frozen for consumers the moment they install it, and they upgrade on their\n// own schedule, so the old names keep resolving. Write the Omni names.\nexport const DynoDesignProvider = OmniDesignProvider;\nexport const useDynoDesign = useOmniDesign;\nexport const DYNO_THEMES = OMNI_THEMES;\nexport const DYNO_STYLES = OMNI_STYLES;\nexport const DYNO_SURFACES = OMNI_SURFACES;\n\nexport default OmniDesignProvider;"],"names":["OmniDesignContext","createContext","OMNI_THEMES","OMNI_STYLES","OMNI_SURFACES","SURFACE_STYLE_THEME_MAP","theme","rootSurface","TAG","removeStyleTag","id","document","getElementById","remove","loadCSSSource","source","beforeId","startsWith","endsWith","isURL","href","existing","tagName","getAttribute","Promise","resolve","reject","onload","onerror","Error","setAttribute","tag","createElement","rel","before","head","insertBefore","appendChild","injectLinkTag","css","textContent","injectStyleTag","OmniDesignProvider","themeURL","foundationCSS","coreCSS","typographyCSS","lightModeCSS","darkModeCSS","baseCSS","stylesCSS","defaultTheme","defaultThemeProp","defaultStyle","defaultStyleProp","defaultSurface","defaultSurfaceProp","surfaceStyle","defaultDarkMode","darkTheme","darkThemeProp","darkMode","controlledDarkMode","onDarkModeChange","className","style","styleProp","fullHeight","children","internalDark","setInternalDark","useState","isControlled","undefined","isDark","resolvedSources","setResolvedSources","foundation","core","typography","lightMode","base","styles","manifestThemeConfig","setManifestThemeConfig","mountedRef","useRef","useEffect","current","setCssStatus","async","manifestURL","test","replace","res","fetch","ok","status","manifest","json","value","foundationURL","coreURL","typographyURL","lightModeURL","darkModeURL","baseURL","stylesURL","name","fetchThemeManifest","then","catch","err","console","error","setCssError","message","resolvedDefaultTheme","resolvedDefaultSurface","resolvedDefaultStyle","resolvedDarkTheme","setThemeState","styleVariant","setStyleVariant","setRootSurface","hasAnyCSSSource","cssStatus","cssError","all","warn","activeSource","activeTheme","toggleDarkMode","useCallback","d","setTheme","next","includes","setStyle","setSurface","contextValue","useMemo","surface","themes","surfaces","_jsxs","Provider","_jsx","minHeight","useOmniDesign","ctx","useContext","DynoDesignProvider","useDynoDesign","DYNO_THEMES","DYNO_STYLES","DYNO_SURFACES","as","Tag","rest"],"mappings":"0HAoFA,MAAMA,EAAoBC,EAAAA,cAAc,MAa3BC,EAAc,CACzB,UACA,UAAW,YAAa,WAAY,UACpC,OAAQ,UAAW,UAAW,QAC9B,UAAW,UAAW,UAGXC,EAAc,CAAC,eAAgB,SAAU,OAAQ,WAEjDC,EAAgB,CAK3B,kBAAmB,cAAe,UAAW,iBAAkB,oBAC/D,YAAa,gBAAiB,mBAC9B,iBAAkB,qBAGPC,EAA0B,CAGrC,cAAqB,CAAEC,MAAO,UAAkBC,YAAa,qBAC7D,oBAAqB,CAAED,MAAO,UAAkBC,YAAa,WAG7D,oBAAqB,CAAED,MAAO,UAAkBC,YAAa,oBAYzDC,EACQ,kBADRA,EAEQ,YAFRA,EAGQ,kBAHRA,EAIQ,YAJRA,EAKQ,YALRA,EAMQ,cAmFd,SAASC,EAAeC,GACtBC,SAASC,eAAeF,IAAKG,QAC/B,CAOA,SAASC,EAAcJ,EAAIK,EAAQC,GACjC,OAAKD,EAnFP,SAAeA,GACb,SAAKA,GAA4B,iBAAXA,KACfA,EAAOE,WAAW,SAClBF,EAAOE,WAAW,MAClBF,EAAOG,SAAS,QACzB,CA+EMC,CAAMJ,GAnEZ,SAAuBL,EAAIU,EAAMJ,GAC/B,MAAMK,EAAWV,SAASC,eAAeF,GACzC,OAAIW,EACuB,SAArBA,EAASC,SAAsBD,EAASE,aAAa,UAAYH,EAG5D,IAAII,QAAQ,CAACC,EAASC,KAC3BL,EAASM,OAAS,IAAMF,EAAQJ,GAChCA,EAASO,QAAU,IAAMF,EAAO,IAAIG,MAAM,sCAAsCT,MAChFC,EAASS,aAAa,OAAQV,KAG3BI,QAAQC,QAAQJ,GAElB,IAAIG,QAAQ,CAACC,EAASC,KAC3B,MAAMK,EAAMpB,SAASqB,cAAc,QACnCD,EAAIrB,GAAKA,EACTqB,EAAIE,IAAM,aACVF,EAAID,aAAa,YAAa,QAC9BC,EAAIJ,OAAS,IAAMF,EAAQM,GAC3BA,EAAIH,QAAU,IAAMF,EAAO,IAAIG,MAAM,sCAAsCT,MAC3EW,EAAIX,KAAOA,EACX,MAAMc,EAASlB,EAAWL,SAASC,eAAeI,GAAY,KAC1DkB,EACFvB,SAASwB,KAAKC,aAAaL,EAAKG,GAEhCvB,SAASwB,KAAKE,YAAYN,IAGhC,CAsC4BO,CAAc5B,EAAIK,EAAQC,GA/BtD,SAAwBN,EAAI6B,EAAKvB,GAC/B,IAAKuB,EAAK,OAAOf,QAAQC,QAAQ,MACjC,MAAMJ,EAAWV,SAASC,eAAeF,GACzC,GAAIW,EAEF,OADAA,EAASmB,YAAcD,EAChBf,QAAQC,QAAQJ,GAEzB,MAAMU,EAAMpB,SAASqB,cAAc,SACnCD,EAAIrB,GAAKA,EACTqB,EAAID,aAAa,YAAa,QAC9BC,EAAIS,YAAcD,EAClB,MAAML,EAASlB,EAAWL,SAASC,eAAeI,GAAY,KAM9D,OALIkB,EACFvB,SAASwB,KAAKC,aAAaL,EAAKG,GAEhCvB,SAASwB,KAAKE,YAAYN,GAErBP,QAAQC,QAAQM,EACzB,CAcSU,CAAe/B,EAAIK,EAAQC,GAFdQ,QAAQC,QAAQ,KAGtC,CA4FO,SAASiB,GAAmBC,SAEjCA,EAAQC,cAGRA,EAAaC,QACbA,EAAOC,cACPA,EAAaC,aACbA,EAAYC,YACZA,EAAWC,QACXA,EAAOC,UACPA,EAGAC,aAAgBC,EAAqB,UACrCC,aAAgBC,EAAqB,SACrCC,eAAgBC,EAAqB,UAASC,aAC9CA,EAAYC,gBAGZA,GAAkB,EAClBC,UAAgBC,EAAgB,UAGhCC,SAAUC,EAAkBC,iBAC5BA,EAAgBC,UAGhBA,EACAC,MAAOC,EAASC,WAChBA,GAAa,EAAIC,SAEjBA,IAIA,MAAOC,EAAcC,GAAmBC,EAAAA,SAASb,GAC3Cc,OAAsCC,IAAvBX,EACfY,EAASF,EAAeV,EAAqBO,GAI5CM,EAAiBC,GAAsBL,WAAS,CACrDM,WAAYjC,GAAiB,KAC7BkC,KAAYjC,GAAiB,KAC7BkC,WAAYjC,GAAiB,KAC7BkC,UAAYjC,GAAiB,KAC7Bc,SAAYb,GAAiB,KAC7BiC,KAAYhC,GAAiB,KAC7BiC,OAAYhC,GAAiB,QAIxBiC,EAAqBC,GAA0Bb,EAAAA,SAAS,CAAA,GAEzDc,EAAaC,EAAAA,QAAO,GAC1BC,EAAAA,UAAU,KACRF,EAAWG,SAAU,EACd,KAAQH,EAAWG,SAAU,IACnC,IAGHD,EAAAA,UAAU,KACH5C,IAEL8C,GAAa,WAlJjBC,eAAkC/C,GAGhC,MACMgD,EADgB,eAAeC,KAAKjD,GACNA,EAAW,GAAGA,EAASkD,QAAQ,MAAO,iBAEpEZ,EAAOtC,EAASkD,QAAQ,MAAO,IAAIA,QAAQ,wBAAyB,IAEpEC,QAAYC,MAAMJ,GACxB,IAAKG,EAAIE,GACP,MAAM,IAAInE,MAAM,0DAA0D8D,MAAgBG,EAAIG,WAGhG,MAAMC,QAAiBJ,EAAIK,OAIrB1E,EAAW2E,GACVA,EACD,gBAAgBR,KAAKQ,GAAeA,EACjC,GAAGnB,KAAQmB,IAFC,KAKrB,MAAO,CACLC,cAAgB5E,EAAQyE,EAASrB,YACjCyB,QAAgB7E,EAAQyE,EAASpB,MACjCyB,cAAgB9E,EAAQyE,EAASnB,YACjCyB,aAAgB/E,EAAQyE,EAASlB,WACjCyB,YAAgBhF,EAAQyE,EAASrC,UACjC6C,QAAgBjF,EAAQyE,EAASjB,MACjC0B,UAAgBlF,EAAQyE,EAAShB,QAEjC/B,aAAgB+C,EAAS/C,cAAkB,KAC3CE,aAAgB6C,EAAS7C,cAAkB,KAC3CE,eAAgB2C,EAAS3C,gBAAkB,KAC3CI,UAAgBuC,EAASvC,WAAkB,KAG3CiD,KAAgBV,EAASU,MAAkB,KAE/C,CA4GIC,CAAmBlE,GAChBmE,KAAKZ,IACCb,EAAWG,UAGhBZ,EAAmB,CACjBC,WAAYjC,GAAiBsD,EAASG,cACtCvB,KAAYjC,GAAiBqD,EAASI,QACtCvB,WAAYjC,GAAiBoD,EAASK,cACtCvB,UAAYjC,GAAiBmD,EAASM,aACtC3C,SAAYb,GAAiBkD,EAASO,YACtCxB,KAAYhC,GAAiBiD,EAASQ,QACtCxB,OAAYhC,GAAiBgD,EAASS,YAIxCvB,EAAuB,CACrBjC,aAAgB+C,EAAS/C,aACzBE,aAAgB6C,EAAS7C,aACzBE,eAAgB2C,EAAS3C,eACzBI,UAAgBuC,EAASvC,UACzBiD,KAAgBV,EAASU,UAG5BG,MAAMC,IACA3B,EAAWG,UAChByB,QAAQC,MAAM,sCAAuCF,GACrDG,GAAYH,EAAII,SAChB3B,GAAa,cAGhB,CAAC9C,IAIJ,MAAM0E,EAAuB5D,EACxBpD,EAAwBoD,IAAenD,OAAS8C,EAC3B,YAArBA,EAAiCA,EAAoB+B,EAAoBhC,cAAgBC,EAExFkE,EAAyB7D,EAC1BpD,EAAwBoD,IAAelD,aAAeiD,EACtD2B,EAAoB5B,gBAAkBC,EAErC+D,EAAuBpC,EAAoB9B,cAAgBC,EAC3DkE,EAAyC,YAAlB5D,EACzBA,EACCuB,EAAoBxB,WAAaC,GAE/BtD,EAAcmH,GAAmBlD,EAAAA,SAAS8C,IAC1CK,EAAcC,GAAmBpD,EAAAA,SAASgD,IAC1ChH,EAAcqH,GAAmBrD,EAAAA,SAAS+C,GAQ3CO,MACJlF,GAAYC,GAAiBC,GAAWC,GACnCC,GAAgBC,GAAeC,GAAWC,IAE1C4E,GAAWrC,IAAgBlB,EAAAA,SAASsD,GAAkB,UAAY,UAClEE,GAAWZ,IAAgB5C,EAAAA,SAAS,MAS3CgB,EAAAA,UAAU,KACR,MAAMV,WAAEA,EAAUC,KAAEA,EAAIC,WAAEA,EAAUE,KAAEA,EAAIC,OAAEA,GAAWP,EACvD,GAAKE,GAAeC,GAASC,GAAeE,GAASC,EAgDrD,OApCAO,GAAa,WACb0B,GAAY,MAYZ3F,QAAQwG,IAAI,CACVlH,EAAcN,EAAgBqE,GAC9B/D,EAAcN,EAAgBsE,GAI9BhE,EAAcN,EAAgBuE,GAAYgC,MAAMC,IAC9CC,QAAQgB,KAAK,oDAAqDjB,EAAII,WAExEtG,EAAcN,EAAgByE,GAC9BnE,EAAcN,EAAgB0E,KAE7B4B,KAAK,KACCzB,EAAWG,SAChBC,GAAa,WAEdsB,MAAMC,IACA3B,EAAWG,UAChByB,QAAQC,MAAM,gCAAiCF,GAC/CG,GAAYH,EAAII,SAChB3B,GAAa,YAGV,KACLhF,EAAeD,GACfC,EAAeD,GACfC,EAAeD,GACfC,EAAeD,GACfC,EAAeD,IA7CfiF,GAAa,UA+Cd,CAACd,EAAgBE,WAAYF,EAAgBG,KAAMH,EAAgBI,WAClEJ,EAAgBM,KAAMN,EAAgBO,SAQ1CK,EAAAA,UAAU,KACR,MAAM2C,EAAexD,EAASC,EAAgBd,SAAWc,EAAgBK,UACpEkD,GAELpH,EAAcN,EAAU0H,EAAc1H,GACnCuG,MAAMC,GAAOC,QAAQC,MAAM,qCAAsCF,KAEnE,CAACtC,EAAQC,EAAgBK,UAAWL,EAAgBd,WAGvD0B,EAAAA,UAAU,IAAe,IAAM9E,EAAeD,GAAc,IAG5D,MAAM2H,GAAczD,EAAS8C,EAAoBlH,EAE3C8H,GAAiBC,EAAAA,YAAY,KAC7B7D,EAAcT,KAAoBW,GACjCJ,EAAgBgE,IAAMA,IAC1B,CAAC9D,EAAcE,EAAQX,IAEpBwE,GAAWF,EAAAA,YAAaG,IACvBtI,EAAYuI,SAASD,IAAOvB,QAAQgB,KAAK,sCAAsCO,MACpFf,EAAce,IACb,IAEGE,GAAWL,EAAAA,YAAaG,IACvBrI,EAAYsI,SAASD,IAAOvB,QAAQgB,KAAK,sCAAsCO,MACpFb,EAAgBa,IACf,IAEGG,GAAaN,EAAAA,YAAaG,IACzBpI,EAAcqI,SAASD,IAAOvB,QAAQgB,KAAK,wCAAwCO,MACxFZ,EAAeY,IACd,IAGGI,GAAeC,EAAAA,QAAQ,KAAA,CAC3BvI,MAAO6H,GAAalE,MAAOyD,EAAcoB,QAASvI,EAClDmE,SAAQoD,aAAWC,YACnBQ,YAAUG,YAAUC,cAAYP,kBAChCW,OAAQ7I,EAAagF,OAAQ/E,EAAa6I,SAAU5I,EACpDwG,KAAMzB,EAAoByB,MAAQ,OAChC,CACFuB,GAAaT,EAAcnH,EAAamE,EACxCoD,GAAWC,GACXQ,GAAUG,GAAUC,GAAYP,GAChCjD,EAAoByB,OAWtB,OACEqC,EAAAA,KAACjJ,EAAkBkJ,SAAQ,CAAC9C,MAAOwC,GAAaxE,UAC9C+E,EAAAA,IAAA,QAAA,CAAO,YAAU,mBAAkB/E,SAAE,iDACrC+E,EAAAA,IAAA,MAAA,CACE,aAAYhB,GACZ,aAAYT,EACZ,eAAcnH,EACd,gBAAeuH,GACf9D,UAAWA,EACXC,MAAO,IAAME,EAAa,CAAEiF,UAAW,SAAY,MAAQlF,GAAYE,SAEtEA,MAIT,CAIO,SAASiF,IACd,MAAMC,EAAMC,EAAAA,WAAWvJ,GACvB,IAAKsJ,EAAK,MAAM,IAAIzH,MAAM,4DAC1B,OAAOyH,CACT,CA0BO,MAAME,EAAqB9G,EACrB+G,EAAoBJ,EACpBK,EAAoBxJ,EACpByJ,EAAoBxJ,EACpByJ,EAAoBxJ,uPAhB1B,UAAkB0I,QAAEA,EAASe,GAAIC,EAAM,MAAK1F,SAAEA,EAAQJ,UAAEA,EAASC,MAAEA,KAAU8F,IAClF,OACEZ,EAAAA,IAACW,EAAG,CAAC,eAAchB,EAAS9E,UAAWA,EAAWC,MAAOA,KAAW8F,EAAI3F,SACrEA,GAGP,qBAhBO,UAAoB9D,MAAEA,EAAKwI,QAAEA,EAASe,GAAIC,EAAM,MAAK1F,SAAEA,EAAQJ,UAAEA,EAASC,MAAEA,KAAU8F,IAC3F,OACEZ,EAAAA,IAACW,EAAG,CAAC,aAAYxJ,EAAO,eAAcwI,EAAS9E,UAAWA,EAAWC,MAAOA,KAAW8F,EAAI3F,SACxFA,GAGP"}
1
+ {"version":3,"file":"OmniDesignProvider.js","sources":["../src/OmniDesignProvider.js"],"sourcesContent":["/**\n * OmniDesignProvider\n *\n * Wires the full OmniDesign token cascade into any React app.\n *\n * ── Two ways to provide CSS ───────────────────────────────────────────────────\n *\n * 1. SIMPLE — single themeURL (recommended):\n *\n * <OmniDesignProvider\n * themeURL=\"https://themes.omnidesign.com/acme-corp\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * The Provider fetches {themeURL}/theme.json to discover the CSS files,\n * then loads them in the correct order automatically.\n *\n * 2. MANUAL — individual CSS props (local dev / custom setups):\n *\n * <OmniDesignProvider\n * foundationCSS=\"/styles/foundation.css\"\n * coreCSS=\"/styles/core.css\"\n * typographyCSS=\"/styles/typography-tokens.css\"\n * lightModeCSS=\"/styles/Light-Mode.css\"\n * darkModeCSS=\"/styles/Dark-Mode.css\"\n * baseCSS=\"/styles/base.css\"\n * stylesCSS=\"/styles/styles.css\"\n * defaultTheme=\"Default\"\n * defaultStyle=\"Modern\"\n * >\n *\n * ── theme.json format ─────────────────────────────────────────────────────────\n *\n * {\n * \"foundation\": \"foundation.css\",\n * \"core\": \"core.css\",\n * \"typography\": \"typography-tokens.css\", // optional\n * \"lightMode\": \"Light-Mode.css\",\n * \"darkMode\": \"Dark-Mode.css\",\n * \"base\": \"base.css\",\n * \"styles\": \"styles.css\",\n * \"defaultTheme\": \"Default\",\n * \"defaultStyle\": \"Modern\",\n * \"defaultSurface\": \"Surface\",\n * \"darkTheme\": \"Neutral\"\n * }\n *\n * All fields are optional — only include the files you have.\n * Props passed directly to the Provider always override theme.json values.\n *\n * ── CSS load order ────────────────────────────────────────────────────────────\n * 1. foundation.css — primitives\n * 2. core.css — component base styles\n * 3. typography-tokens.css — platform type ramps (optional)\n * 4. Light-Mode.css OR Dark-Mode.css (one at a time, swaps on toggle)\n * 5. base.css — data-style / data-surface rules\n * 6. styles.css — final overrides\n *\n * ── How CSS is loaded ─────────────────────────────────────────────────────────\n * URL sources (the common production case) load as <link rel=\"stylesheet\">\n * tags. The browser fetches them in parallel, caches them, and blocks paint\n * until they apply — no flash of unbranded styling.\n *\n * Raw CSS strings (local dev, custom setups) load as <style> tags.\n *\n * While loading, the Provider wrapper carries data-omni-css=\"loading\" and is\n * visibility:hidden — once every sheet resolves it flips to \"ready\" and\n * becomes visible. Error state stays visible so the consumer can render\n * a fallback.\n */\n\nimport React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n} from 'react';\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nconst OmniDesignContext = createContext(null);\n\n// ─── Valid values ─────────────────────────────────────────────────────────────\n\n/* Nine themes plus the three bars. The -Light / -Medium / -Dark shades are\n * gone: a shade and a surface level were two ways of saying one thing, and the\n * surface ladder already walks that axis — `theme=\"Primary\"\n * surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n *\n * This list had kept all 24, so anything driven by it — a theme picker, a\n * validation check — offered fifteen names a generated design system does not\n * define. They bind nothing and paint the parent's palette, which reads as the\n * picker being broken rather than the name being dead. */\nexport const OMNI_THEMES = [\n 'Default',\n 'Primary', 'Secondary', 'Tertiary', 'Neutral',\n 'Info', 'Success', 'Warning', 'Error',\n 'App-Bar', 'Nav-Bar', 'Status',\n];\n\nexport const OMNI_STYLES = ['Professional', 'Modern', 'Bold', 'Playful'];\n\nexport const OMNI_SURFACES = [\n // Five surface levels, darkest to lightest. Surface-Dimmest and\n // Surface-Brightest are the ends of the ramp: Brightest is the level that\n // replaced the <Palette>-Light themes, so `theme=\"Primary\"\n // surface=\"Surface-Brightest\"` is what `theme=\"Primary-Light\"` used to be.\n 'Surface-Dimmest', 'Surface-Dim', 'Surface', 'Surface-Bright', 'Surface-Brightest',\n 'Container', 'Container-Low', 'Container-Lowest',\n 'Container-High', 'Container-Highest',\n];\n\nexport const SURFACE_STYLE_THEME_MAP = {\n // Primary at its brightest surface — what theme:'Primary-Light' used to mean,\n // and the only form generated design systems actually define.\n 'light-tonal': { theme: 'Primary', rootSurface: 'Surface-Brightest' },\n 'grey-professional': { theme: 'Neutral', rootSurface: 'Surface' },\n // The mirror of light-tonal: same palette, the other end of the ramp. What\n // theme:'Neutral-Dark' used to mean, and the only form that is defined.\n 'dark-professional': { theme: 'Neutral', rootSurface: 'Surface-Dimmest' },\n};\n\n// ─── Style tag IDs ────────────────────────────────────────────────────────────\n//\n// #omni-foundation (1st)\n// #omni-core (2nd)\n// #omni-typography (3rd) ← platform type ramps; must follow core\n// #omni-mode (4th) ← swaps between light/dark\n// #omni-base (5th)\n// #omni-styles (6th) ← always last\n\nconst TAG = {\n foundation: 'omni-foundation',\n core: 'omni-core',\n typography: 'omni-typography',\n mode: 'omni-mode',\n base: 'omni-base',\n styles: 'omni-styles',\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Detect whether a CSS source is a URL or a raw CSS string. URLs load via\n * <link rel=\"stylesheet\"> (render-blocking, browser-cached, no FOUC); raw\n * strings load via <style> (the only option for inline CSS).\n */\nfunction isURL(source) {\n if (!source || typeof source !== 'string') return false;\n return source.startsWith('http')\n || source.startsWith('/')\n || source.endsWith('.css');\n}\n\n/**\n * Insert a <link rel=\"stylesheet\"> for a URL source. Returns a Promise that\n * resolves when the stylesheet has loaded (so we can flip cssStatus to\n * 'ready' only after every brand sheet is actually applied — avoiding the\n * Provider-default-then-brand flicker that the fetch+<style> path causes).\n *\n * `beforeId` controls cascade order: pass the id of the tag that should come\n * AFTER this one. The lib's order is foundation → core → mode → base → styles,\n * and CSS variable resolution depends on it.\n */\nfunction injectLinkTag(id, href, beforeId) {\n const existing = document.getElementById(id);\n if (existing) {\n if (existing.tagName === 'LINK' && existing.getAttribute('href') !== href) {\n // Swap href in place — browser refetches. Use the existing onload so\n // callers can still await readiness on a mode swap.\n return new Promise((resolve, reject) => {\n existing.onload = () => resolve(existing);\n existing.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n existing.setAttribute('href', href);\n });\n }\n return Promise.resolve(existing);\n }\n return new Promise((resolve, reject) => {\n const tag = document.createElement('link');\n tag.id = id;\n tag.rel = 'stylesheet';\n tag.setAttribute('data-omni', 'true');\n tag.onload = () => resolve(tag);\n tag.onerror = () => reject(new Error(`OmniDesignProvider: failed to load ${href}`));\n tag.href = href;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n });\n}\n\n/**\n * Insert an inline <style> for a raw CSS string. Used only when the consumer\n * passes raw CSS (not a URL) — most production use cases are URLs and go\n * through injectLinkTag.\n */\nfunction injectStyleTag(id, css, beforeId) {\n if (!css) return Promise.resolve(null);\n const existing = document.getElementById(id);\n if (existing) {\n existing.textContent = css;\n return Promise.resolve(existing);\n }\n const tag = document.createElement('style');\n tag.id = id;\n tag.setAttribute('data-omni', 'true');\n tag.textContent = css;\n const before = beforeId ? document.getElementById(beforeId) : null;\n if (before) {\n document.head.insertBefore(tag, before);\n } else {\n document.head.appendChild(tag);\n }\n return Promise.resolve(tag);\n}\n\nfunction removeStyleTag(id) {\n document.getElementById(id)?.remove();\n}\n\n/**\n * Load a CSS source into the document at the position specified by beforeId.\n * Routes to <link> for URLs (no fetch round-trip; browser handles caching)\n * and <style> for raw CSS strings.\n */\nfunction loadCSSSource(id, source, beforeId) {\n if (!source) return Promise.resolve(null);\n if (isURL(source)) return injectLinkTag(id, source, beforeId);\n return injectStyleTag(id, source, beforeId);\n}\n\n/**\n * Fetch and parse theme.json from a themeURL.\n * Returns an object with resolved absolute URLs for each CSS file.\n *\n * @param {string} themeURL — base URL, e.g. \"https://themes.omnidesign.com/acme-corp\"\n * @returns {Promise<object>} — { foundationURL, coreURL, lightModeURL, darkModeURL,\n * baseURL, stylesURL, defaultTheme, defaultStyle,\n * defaultSurface, darkTheme }\n */\nasync function fetchThemeManifest(themeURL) {\n // If themeURL already points to a .json file (e.g. a Firebase Storage URL), use it directly.\n // Otherwise treat it as a folder and append /theme.json (legacy path-based hosting).\n const isManifestUrl = /\\.json(\\?|$)/.test(themeURL);\n const manifestURL = isManifestUrl ? themeURL : `${themeURL.replace(/\\/$/, '')}/theme.json`;\n // Folder base (used only for path-based fallback when manifest values are relative filenames)\n const base = themeURL.replace(/\\/$/, '').replace(/\\/theme\\.json(\\?.*)?$/, '');\n\n const res = await fetch(manifestURL);\n if (!res.ok) {\n throw new Error(`OmniDesignProvider: could not load theme manifest from ${manifestURL} (${res.status})`);\n }\n\n const manifest = await res.json();\n\n // Resolve each manifest entry. If it's already a full URL, pass it through unchanged.\n // Otherwise, treat it as a relative filename and join it with the folder base.\n const resolve = (value) => {\n if (!value) return null;\n if (/^https?:\\/\\//i.test(value)) return value;\n return `${base}/${value}`;\n };\n\n return {\n foundationURL: resolve(manifest.foundation),\n coreURL: resolve(manifest.core),\n typographyURL: resolve(manifest.typography),\n lightModeURL: resolve(manifest.lightMode),\n darkModeURL: resolve(manifest.darkMode),\n baseURL: resolve(manifest.base),\n stylesURL: resolve(manifest.styles),\n // Theme config from manifest (props override these)\n defaultTheme: manifest.defaultTheme ?? null,\n defaultStyle: manifest.defaultStyle ?? null,\n defaultSurface: manifest.defaultSurface ?? null,\n darkTheme: manifest.darkTheme ?? null,\n // Human-readable design system name — surfaced on the context so consumers\n // (AppBar brand, page headers, etc.) can display it.\n name: manifest.name ?? null,\n };\n}\n\n// ─── Provider ─────────────────────────────────────────────────────────────────\n\n/**\n * @param {object} props\n *\n * Theme URL (simplest — recommended for production):\n * @param {string} props.themeURL Base URL of the theme folder.\n * Must contain a theme.json manifest.\n * e.g. \"https://themes.omnidesign.com/acme-corp\"\n *\n * Individual CSS props (manual / local dev):\n * @param {string} props.foundationCSS foundation.css (URL or raw string)\n * @param {string} props.coreCSS core.css\n * @param {string} props.typographyCSS typography-tokens.css\n * @param {string} props.lightModeCSS Light-Mode.css\n * @param {string} props.darkModeCSS Dark-Mode.css\n * @param {string} props.baseCSS base.css\n * @param {string} props.stylesCSS styles.css (loaded last)\n *\n * Theme config (props override theme.json values):\n * @param {string} props.defaultTheme Starting data-theme (default: 'Default')\n * @param {string} props.defaultStyle Starting data-style (default: 'Modern')\n * @param {string} props.defaultSurface Root data-surface (default: 'Surface')\n * @param {string} props.surfaceStyle 'light-tonal' | 'grey-professional' | 'dark-professional'\n *\n * Dark mode — uncontrolled:\n * @param {boolean} props.defaultDarkMode Initial dark mode (default: false)\n * @param {string} props.darkTheme data-theme in dark mode (default: 'Neutral')\n *\n * Dark mode — controlled:\n * @param {boolean} props.darkMode\n * @param {function} props.onDarkModeChange\n *\n * DOM:\n * @param {string} props.className\n * @param {object} props.style\n * @param {boolean} props.fullHeight Adds minHeight: 100vh (default: true)\n * @param {React.ReactNode} props.children\n */\nexport function OmniDesignProvider({\n // Theme URL\n themeURL,\n\n // Individual CSS (manual / local dev)\n foundationCSS,\n coreCSS,\n typographyCSS,\n lightModeCSS,\n darkModeCSS,\n baseCSS,\n stylesCSS,\n\n // Theme config\n defaultTheme: defaultThemeProp = 'Default',\n defaultStyle: defaultStyleProp = 'Modern',\n defaultSurface: defaultSurfaceProp = 'Surface',\n surfaceStyle,\n\n // Dark mode\n defaultDarkMode = false,\n /* null, not 'Neutral'.\n This defaulted to 'Neutral' and activeTheme applied it unconditionally in\n dark mode, so the whole app became data-theme=\"Neutral\" the moment dark\n was switched on — and Neutral is the ONE palette that is light in dark\n mode. Figma: Neutral/Dark-Mode/Surface is #cccccc. That is the grey.\n It also discarded the chosen theme: pick Primary, switch to dark, get\n Neutral. The architecture doc says the opposite — \"the theme carries over,\n the tone does not\" — because the MODE is carried by the stylesheet\n (Light-Mode.css vs Dark-Mode.css), not by swapping palettes.\n The prop stays as an opt-in escape hatch for a brand that genuinely wants\n a different palette in dark; it simply no longer fires by default. */\n darkTheme: darkThemeProp = null,\n\n // Controlled dark mode\n darkMode: controlledDarkMode,\n onDarkModeChange,\n\n // DOM\n className,\n style: styleProp,\n fullHeight = true,\n\n children,\n}) {\n\n // ── Dark mode ──────────────────────────────────────────────────────────────\n const [internalDark, setInternalDark] = useState(defaultDarkMode);\n const isControlled = controlledDarkMode !== undefined;\n const isDark = isControlled ? controlledDarkMode : internalDark;\n\n // ── Resolved CSS sources ───────────────────────────────────────────────────\n // When themeURL is provided, manifest values fill in anything not passed as props.\n const [resolvedSources, setResolvedSources] = useState({\n foundation: foundationCSS ?? null,\n core: coreCSS ?? null,\n typography: typographyCSS ?? null,\n lightMode: lightModeCSS ?? null,\n darkMode: darkModeCSS ?? null,\n base: baseCSS ?? null,\n styles: stylesCSS ?? null,\n });\n\n // Theme config — may be overridden by manifest values\n const [manifestThemeConfig, setManifestThemeConfig] = useState({});\n\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => { mountedRef.current = false; };\n }, []);\n\n // ── EFFECT: Fetch manifest if themeURL provided ────────────────────────────\n useEffect(() => {\n if (!themeURL) return;\n\n setCssStatus('loading');\n\n fetchThemeManifest(themeURL)\n .then(manifest => {\n if (!mountedRef.current) return;\n\n // Individual CSS props always take precedence over manifest\n setResolvedSources({\n foundation: foundationCSS ?? manifest.foundationURL,\n core: coreCSS ?? manifest.coreURL,\n typography: typographyCSS ?? manifest.typographyURL,\n lightMode: lightModeCSS ?? manifest.lightModeURL,\n darkMode: darkModeCSS ?? manifest.darkModeURL,\n base: baseCSS ?? manifest.baseURL,\n styles: stylesCSS ?? manifest.stylesURL,\n });\n\n // Store manifest theme config — props will override in render\n setManifestThemeConfig({\n defaultTheme: manifest.defaultTheme,\n defaultStyle: manifest.defaultStyle,\n defaultSurface: manifest.defaultSurface,\n darkTheme: manifest.darkTheme,\n name: manifest.name,\n });\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider: manifest error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n }, [themeURL]);\n\n // ── Theme / style / surface ────────────────────────────────────────────────\n // Priority: prop → manifest → default\n const resolvedDefaultTheme = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.theme ?? defaultThemeProp)\n : (defaultThemeProp !== 'Default' ? defaultThemeProp : (manifestThemeConfig.defaultTheme ?? defaultThemeProp));\n\n const resolvedDefaultSurface = surfaceStyle\n ? (SURFACE_STYLE_THEME_MAP[surfaceStyle]?.rootSurface ?? defaultSurfaceProp)\n : (manifestThemeConfig.defaultSurface ?? defaultSurfaceProp);\n\n const resolvedDefaultStyle = manifestThemeConfig.defaultStyle ?? defaultStyleProp;\n const resolvedDarkTheme = darkThemeProp ?? manifestThemeConfig.darkTheme ?? null;\n\n const [theme, setThemeState] = useState(resolvedDefaultTheme);\n const [styleVariant, setStyleVariant] = useState(resolvedDefaultStyle);\n const [rootSurface, setRootSurface] = useState(resolvedDefaultSurface);\n\n // ── CSS status ─────────────────────────────────────────────────────────────\n // 'loading' while sheets are in flight, 'ready' after they apply, 'error' on\n // a load failure. Initial value is 'ready' when the consumer passes neither\n // a themeURL nor any individual CSS prop — that case means they're using\n // the Provider only for theme-context (no brand sheets to load), so the\n // hide-during-load rule shouldn't keep the page invisible forever.\n const hasAnyCSSSource = !!(\n themeURL || foundationCSS || coreCSS || typographyCSS\n || lightModeCSS || darkModeCSS || baseCSS || stylesCSS\n );\n const [cssStatus, setCssStatus] = useState(hasAnyCSSSource ? 'loading' : 'ready');\n const [cssError, setCssError] = useState(null);\n\n // ── EFFECT: Inject static CSS (foundation, core, base, styles) ────────────\n // Injects each sheet in its correct cascade slot. URLs become <link> tags\n // (browser-cached, render-blocking — no flash); raw CSS strings become\n // <style> tags. The mode sheet's slot (#omni-mode) sits between core and\n // base; we anchor base/styles after it by passing the right beforeId so\n // the order stays foundation → core → mode → base → styles regardless of\n // which sheet resolves first.\n useEffect(() => {\n const { foundation, core, typography, base, styles } = resolvedSources;\n if (!foundation && !core && !typography && !base && !styles) {\n // Nothing in the static slots. The mode sheet, if there is one, loads on\n // its own effect below and needs nothing from here.\n //\n // This MUST still flip the status: 'loading' hides the whole tree behind\n // the anti-FOUC rule, so returning early without it left an app that\n // supplies only lightModeCSS/darkModeCSS — index.html carrying the rest —\n // permanently invisible.\n setCssStatus('ready');\n return;\n }\n\n setCssStatus('loading');\n setCssError(null);\n\n // Order matters: inject earlier slots first so later slots can use them\n // as `beforeId` anchors. Each call is non-blocking; we await the union\n // before flipping to 'ready' so we don't unhide before the brand actually\n // applies.\n // typography goes in after core and before base. It carries the platform\n // ramps under [data-platform=\"…\"], whose specificity ties with the :root\n // ramp in core.css — so whichever loads LAST wins, and the design\n // system's own ramp has to be the one that does. A design system that\n // ships no typography-tokens.css leaves this slot empty and the copy\n // bundled with the lib (linked from index.html) stands.\n Promise.all([\n loadCSSSource(TAG.foundation, foundation),\n loadCSSSource(TAG.core, core),\n // Optional slot: a design system that doesn't publish one must not take\n // the whole app down, so a failed load here is swallowed rather than\n // failing the Promise.all.\n loadCSSSource(TAG.typography, typography).catch(err => {\n console.warn('OmniDesignProvider: typography CSS did not load —', err.message);\n }),\n loadCSSSource(TAG.base, base),\n loadCSSSource(TAG.styles, styles),\n ])\n .then(() => {\n if (!mountedRef.current) return;\n setCssStatus('ready');\n })\n .catch(err => {\n if (!mountedRef.current) return;\n console.error('OmniDesignProvider CSS error:', err);\n setCssError(err.message);\n setCssStatus('error');\n });\n\n return () => {\n removeStyleTag(TAG.foundation);\n removeStyleTag(TAG.core);\n removeStyleTag(TAG.typography);\n removeStyleTag(TAG.base);\n removeStyleTag(TAG.styles);\n };\n }, [resolvedSources.foundation, resolvedSources.core, resolvedSources.typography,\n resolvedSources.base, resolvedSources.styles]);\n\n // ── EFFECT: Swap active mode CSS ──────────────────────────────────────────\n // Mode sheet inserts before #omni-base so the cascade slot is always\n // foundation → core → MODE → base → styles, regardless of dark/light\n // toggling order. <link> swap just changes href in place — the browser\n // refetches (cache-control on the storage layer decides whether the\n // network hit happens).\n useEffect(() => {\n const activeSource = isDark ? resolvedSources.darkMode : resolvedSources.lightMode;\n if (!activeSource) return;\n\n loadCSSSource(TAG.mode, activeSource, TAG.base)\n .catch(err => console.error('OmniDesignProvider mode CSS error:', err));\n\n }, [isDark, resolvedSources.lightMode, resolvedSources.darkMode]);\n\n // Cleanup mode tag on unmount\n useEffect(() => { return () => removeStyleTag(TAG.mode); }, []);\n\n // ── Public API ─────────────────────────────────────────────────────────────\n /* The chosen theme, in both modes. A dark theme applies only when one was\n explicitly asked for — otherwise dark mode is the same theme read from the\n dark stylesheet, which is what makes Primary stay Primary when you flip\n the switch. */\n const activeTheme = (isDark && resolvedDarkTheme) ? resolvedDarkTheme : theme;\n\n const toggleDarkMode = useCallback(() => {\n if (isControlled) onDarkModeChange?.(!isDark);\n else setInternalDark(d => !d);\n }, [isControlled, isDark, onDarkModeChange]);\n\n const setTheme = useCallback((next) => {\n if (!OMNI_THEMES.includes(next)) console.warn(`OmniDesignProvider: unknown theme \"${next}\"`);\n setThemeState(next);\n }, []);\n\n const setStyle = useCallback((next) => {\n if (!OMNI_STYLES.includes(next)) console.warn(`OmniDesignProvider: unknown style \"${next}\"`);\n setStyleVariant(next);\n }, []);\n\n const setSurface = useCallback((next) => {\n if (!OMNI_SURFACES.includes(next)) console.warn(`OmniDesignProvider: unknown surface \"${next}\"`);\n setRootSurface(next);\n }, []);\n\n // ── Context ────────────────────────────────────────────────────────────────\n const contextValue = useMemo(() => ({\n theme: activeTheme, style: styleVariant, surface: rootSurface,\n isDark, cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n themes: OMNI_THEMES, styles: OMNI_STYLES, surfaces: OMNI_SURFACES,\n name: manifestThemeConfig.name ?? null,\n }), [\n activeTheme, styleVariant, rootSurface, isDark,\n cssStatus, cssError,\n setTheme, setStyle, setSurface, toggleDarkMode,\n manifestThemeConfig.name,\n ]);\n\n // ── Render ─────────────────────────────────────────────────────────────────\n // The inline <style> below is rendered as part of the React tree so the\n // hide rule is in the DOM before paint — without it, the consumer would\n // see the lib's <OmniDesignProvider>-default tokens for a frame before\n // the brand sheets resolve and apply. `data-omni-css=\"loading\"` flips to\n // `ready` (or `error`) once every brand sheet has finished loading, at\n // which point the wrapper becomes visible. Error state stays visible so\n // the consumer can render a fallback message.\n return (\n <OmniDesignContext.Provider value={contextValue}>\n <style data-omni=\"hide-during-load\">{`[data-omni-css=\"loading\"]{visibility:hidden}`}</style>\n <div\n data-theme={activeTheme}\n data-style={styleVariant}\n data-surface={rootSurface}\n data-omni-css={cssStatus}\n className={className}\n style={{ ...(fullHeight ? { minHeight: '100vh' } : {}), ...styleProp }}\n >\n {children}\n </div>\n </OmniDesignContext.Provider>\n );\n}\n\n// ─── Hook ─────────────────────────────────────────────────────────────────────\n\nexport function useOmniDesign() {\n const ctx = useContext(OmniDesignContext);\n if (!ctx) throw new Error('useOmniDesign must be used inside a <OmniDesignProvider>');\n return ctx;\n}\n\n// ─── ThemedZone ───────────────────────────────────────────────────────────────\n\nexport function ThemedZone({ theme, surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-theme={theme} data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ─── Surfaced ─────────────────────────────────────────────────────────────────\n\nexport function Surfaced({ surface, as: Tag = 'div', children, className, style, ...rest }) {\n return (\n <Tag data-surface={surface} className={className} style={style} {...rest}>\n {children}\n </Tag>\n );\n}\n\n// ── Back-compat aliases ──────────────────────────────────────────────────────\n// The system was called DynoDesign before this release. A design system's API\n// is frozen for consumers the moment they install it, and they upgrade on their\n// own schedule, so the old names keep resolving. Write the Omni names.\nexport const DynoDesignProvider = OmniDesignProvider;\nexport const useDynoDesign = useOmniDesign;\nexport const DYNO_THEMES = OMNI_THEMES;\nexport const DYNO_STYLES = OMNI_STYLES;\nexport const DYNO_SURFACES = OMNI_SURFACES;\n\nexport default OmniDesignProvider;"],"names":["OmniDesignContext","createContext","OMNI_THEMES","OMNI_STYLES","OMNI_SURFACES","SURFACE_STYLE_THEME_MAP","theme","rootSurface","TAG","removeStyleTag","id","document","getElementById","remove","loadCSSSource","source","beforeId","startsWith","endsWith","isURL","href","existing","tagName","getAttribute","Promise","resolve","reject","onload","onerror","Error","setAttribute","tag","createElement","rel","before","head","insertBefore","appendChild","injectLinkTag","css","textContent","injectStyleTag","OmniDesignProvider","themeURL","foundationCSS","coreCSS","typographyCSS","lightModeCSS","darkModeCSS","baseCSS","stylesCSS","defaultTheme","defaultThemeProp","defaultStyle","defaultStyleProp","defaultSurface","defaultSurfaceProp","surfaceStyle","defaultDarkMode","darkTheme","darkThemeProp","darkMode","controlledDarkMode","onDarkModeChange","className","style","styleProp","fullHeight","children","internalDark","setInternalDark","useState","isControlled","undefined","isDark","resolvedSources","setResolvedSources","foundation","core","typography","lightMode","base","styles","manifestThemeConfig","setManifestThemeConfig","mountedRef","useRef","useEffect","current","setCssStatus","async","manifestURL","test","replace","res","fetch","ok","status","manifest","json","value","foundationURL","coreURL","typographyURL","lightModeURL","darkModeURL","baseURL","stylesURL","name","fetchThemeManifest","then","catch","err","console","error","setCssError","message","resolvedDefaultTheme","resolvedDefaultSurface","resolvedDefaultStyle","resolvedDarkTheme","setThemeState","styleVariant","setStyleVariant","setRootSurface","hasAnyCSSSource","cssStatus","cssError","all","warn","activeSource","activeTheme","toggleDarkMode","useCallback","d","setTheme","next","includes","setStyle","setSurface","contextValue","useMemo","surface","themes","surfaces","_jsxs","Provider","_jsx","minHeight","useOmniDesign","ctx","useContext","DynoDesignProvider","useDynoDesign","DYNO_THEMES","DYNO_STYLES","DYNO_SURFACES","as","Tag","rest"],"mappings":"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"}