domma-cms 0.53.0 → 0.54.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.
- package/CLAUDE.md +2 -0
- package/admin/index.html +4 -0
- package/admin/js/lib/sidebar-renderer.js +3 -3
- package/admin/js/templates/menu-editor.html +47 -0
- package/admin/js/views/menu-editor.js +14 -14
- package/package.json +1 -1
- package/public/css/menu-highlight.css +1 -0
- package/public/css/site.css +1 -1
- package/public/js/menu-decor.mjs +1 -1
- package/public/js/site.js +1 -1
- package/server/services/markdown.js +8 -4
- package/server/services/menuRender.js +38 -8
- package/server/services/menus.js +42 -0
- package/server/services/renderer.js +16 -3
- package/server/templates/page.html +4 -1
package/CLAUDE.md
CHANGED
|
@@ -152,6 +152,8 @@ Menus live in `config/menus/<slug>.json`. The slot → menu map lives in `config
|
|
|
152
152
|
|
|
153
153
|
**Bindings.** A menu can carry `binding: {slot, projects: [], pages: []}` and take that slot over on matching pages instead of being mapped globally. `resolveLocation(slot, user, {urlPath, project})` checks bindings first (exact page > `/glob/*` > project, longest pattern wins) and falls back to `menu-locations.json`; **callers that know the page must pass the ctx** or bindings silently never fire - `renderer.js` (both render paths) and `parseMarkdown({urlPath})` do. All menu files are cached in-process via `getAllMenus()`; anything writing a menu file outside `menus.js` must call `invalidateMenuIndex()` (the two boot migrations do).
|
|
154
154
|
|
|
155
|
+
**Item highlighting.** `highlight: {hover, active, accent}` on a menu picks the pointer effect and the current-page marker; the whole implementation is `public/css/menu-highlight.css` keyed off `data-menu-hover` / `data-menu-active` (+ inline `--dm-menu-highlight`), stamped by `applyHighlight` (client) and `buildMenuNav` (server). Unlike the float helpers, `highlightAttrs`/`isCurrentItem` live ONCE in `menu-decor.mjs` and the server imports them - do not duplicate them into `menus.js`. Marking the current item needs the page's URL: `buildMenuNav({currentPath})` (renderer + markdown pass it), `location.pathname` in site.js. The rules carry `!important` because Domma's `.navbar-dark .navbar-link:hover` and site.css's blanket `.page-body a` rule both outrank a class selector - and site.css's rule additionally excludes `:not([data-menu-hover] a):not([data-menu-active] a)`, so a highlighted `[menu]` in the body is not underlined at rest.
|
|
156
|
+
|
|
155
157
|
**Orientation.** `orientation: horizontal|vertical` + `side: left|right`. Vertical navbar = CSS rail over Domma's normal navbar markup (`#site-navbar.dm-nav-vertical` + server-stamped `body.dm-vnav-*` gutter, ≥993px only; below that the mobile drawer already applies). The `[menu]` shortcode emits `dm-menu--vertical|horizontal` **only when set** - no class means the historic plain-list rendering.
|
|
156
158
|
|
|
157
159
|
**Floating panel surface.** `float` also takes `radius`, `shadow` (`none|sm|md|lg|xl` → `--dm-shadow-*`), `accent` (preset key or hex → border tint + leading-edge stripe via `--dm-menu-accent`) and `opacity` (20-100 → `--dm-menu-panel-opacity`, blurred translucent surface). `floatToCss` exists twice - `server/services/menus.js` and `public/js/menu-decor.mjs` - and `tests/services/menus-float.test.js` asserts the copies agree.
|
package/admin/index.html
CHANGED
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
|
|
22
22
|
<!-- Forms CSS - needed for conditional logic preview (.fb-field-hidden, etc.) -->
|
|
23
23
|
<link rel="stylesheet" href="/public/css/forms.css?v=20260817-multi-chooser">
|
|
24
|
+
|
|
25
|
+
<!-- Menu item hover / current-page effects - the admin sidebar is a menu
|
|
26
|
+
like any other, so it honours the same `highlight` block. -->
|
|
27
|
+
<link rel="stylesheet" href="/public/css/menu-highlight.css?v=20260905-menu-highlight">
|
|
24
28
|
</head>
|
|
25
29
|
<body class="dm-cloaked dm-theme-charcoal-dark dashboard-layout">
|
|
26
30
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{api as c}from"../api.js";import{colourToCss as R,applyFloat as
|
|
2
|
-
<summary${
|
|
1
|
+
import{api as c}from"../api.js";import{colourToCss as R,applyFloat as K,applyHighlight as G}from"/public/js/menu-decor.mjs?v=20260905-menu-highlight";import{groupPluginItems as O,stripItemByUrl as V,insertFoldersBeforeSystem as Y,pruneEmptySynthesisedFolders as J,MANAGE_PLUGINS_URL as Q}from"./sidebar-grouping.js";function h(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}const Z=[{text:"Dashboard",url:"#/",icon:"home"},{text:"Menus",url:"#/menus",icon:"menu"}];function B(e,a){return a?!e||!e.length?!1:e.includes(a)?!0:["read","create","update","delete"].some(t=>e.includes(`${a}.${t}`)):!0}function I(e,a){const t=[];for(const n of e){if(n.hidden||n.permission&&!B(a,n.permission))continue;const i=Array.isArray(n.items)&&n.items.length?I(n.items,a):[];t.push({...n,items:i})}return t}function ee(e,a){if(!a||!a.length)return e;const t=(n,i)=>{for(const d of n){if((d.text||"").toLowerCase()===i.toLowerCase())return d;if(Array.isArray(d.items)){const r=t(d.items,i);if(r)return r}}return null};for(const n of a)if(n.parent){const i=t(e,n.parent);i?(i.items=Array.isArray(i.items)?i.items:[],i.items.push(n.item)):e.push(n.item)}else e.push(n.item);return e}async function te(e){if(!B(e,"projects"))return[];let a=[];try{a=await c.projects.list()}catch{return[]}const t={};await Promise.all(a.map(async i=>{try{const d=await c.projects.artefacts(i.slug);t[i.slug]=d}catch{t[i.slug]={}}}));const n=[{key:"pages",text:"Pages",icon:"file-text",path:"/pages"},{key:"collections",text:"Collections",icon:"database",path:"/collections"},{key:"forms",text:"Forms",icon:"layout",path:"/forms"},{key:"actions",text:"Actions",icon:"zap",path:"/actions"},{key:"menus",text:"Menus",icon:"menu",path:"/menus"},{key:"blocks",text:"Blocks",icon:"box",path:"/blocks"},{key:"components",text:"Components",icon:"component",path:"/components"},{key:"views",text:"Views",icon:"eye",path:"/views"},{key:"roles",text:"Roles",icon:"shield",path:"/roles"},{key:"users",text:"Users",icon:"users",path:"/users"},{key:"apis",text:"APIs",icon:"code",path:"/apis"}];return a.map(i=>{const r="#/projects/"+encodeURIComponent(i.slug),m=t[i.slug]||{},f=[{text:"Overview",url:r,icon:i.icon||"folder"}];for(const p of n){const y=m[p.key],g=Array.isArray(y)?y.length:0;g<=0||f.push({text:`${p.text} (${g})`,url:r+p.path,icon:p.icon})}f.push({text:"Settings",url:r+"/settings",icon:"settings"});const u=i.enabled===!1;return{text:i.name||i.slug,icon:i.icon||"folder",items:f,...u&&{colour:"neutral",badge:{text:"off"}}}})}function ne(e,a){for(const t of e)if((t.text||"").toLowerCase()==="projects"){t.items=Array.isArray(t.items)?t.items.slice():[],t.items.push(...a);return}}function se(e,a){if(!e.url||!a)return"";const t=a[e.url];return t==null||t<=0?"":`<span class="sidebar-badge">${h(String(t))}</span>`}function ie(e){const a=(e.text||"").replace(/\s*\(\d+\)\s*$/,"").toLowerCase().replace(/\s+/g,"-"),t=(e.url||"").match(/^#\/projects\/([^/]+)/);return`sidebar.expanded.${t?`project-${decodeURIComponent(t[1])}.`:""}${a}`}function N(e,a){if(e&&e.type==="separator")return'<hr class="sidebar-divider">';if(e&&e.type==="spacer"){const u=["xs","sm","md","lg","xl","flex"].includes(e.size)?e.size:"md";return`<div class="sidebar-spacer sidebar-spacer--${h(u)}" aria-hidden="true"></div>`}const t=e.icon?`<span data-icon="${h(e.icon)}"></span>`:"",n=h(e.text||""),i=e.url?h(e.url):"",d=Array.isArray(e.items)&&e.items.length>0,r=e.colour?R(e.colour):"",m=r?` style="color:${h(r)}"`:"";let f="";if(e.badge&&e.badge.text!=null&&e.badge.text!==""){const u=e.badge.variant?R(e.badge.variant):"";f=`<span class="dm-menu-badge"${u?` style="background:${h(u)};color:var(--dm-text-inverse,#fff)"`:""}>${h(String(e.badge.text))}</span>`}if(d){const u=ie(e),p=S.get(u)!==!1,y=e.items.map(g=>N(g,a)).join("");return`<details data-state-key="${h(u)}"${p?" open":""}>
|
|
2
|
+
<summary${m}>${t} <span class="sidebar-text">${n}</span>${f}</summary>
|
|
3
3
|
<div class="sidebar-children">${y}</div>
|
|
4
|
-
</details>`}return`<a href="${i}" class="sidebar-link" data-url="${i}"${
|
|
4
|
+
</details>`}return`<a href="${i}" class="sidebar-link" data-url="${i}"${m}>${t} <span class="sidebar-text">${n}</span>${se(e,a)}${f}</a>`}async function ae(){const e=g=>g.then(b=>Array.isArray(b)?b.length:Array.isArray(b?.entries)?b.entries.length:0).catch(()=>0),[a,t,n,i,d,r,m,f,u,p,y]=await Promise.all([e(c.pages.list()),e(c.media.list()),e(c.collections.list()),e(c.forms.list()),e(c.views.list()),e(c.actions.list()),e(c.blocks.list()),e(c.components.list()),e(c.users.list()),e(c.plugins.list()),c.system?.notifications?.unreadCount?.().then(g=>g?.count??0).catch(()=>0)??Promise.resolve(0)]);return{"#/pages":a,"#/media":t,"#/collections":n,"#/forms":i,"#/views":d,"#/actions":r,"#/blocks":m,"#/components":f,"#/users":u,"#/plugins":p,"#/system/notifications":y}}async function re(){try{const e=await c.settings.get();return e?.adminBrand?.title||e?.title||"Admin"}catch{return"Admin"}}export async function renderAdminSidebar({mount:e,permissions:a}){const t=$(e).get(0);if(!t)return;let n,i=null,d=null,r=null,m=null,f=null;try{const s=await c.menus.get("admin-sidebar");n=Array.isArray(s?.items)?s.items:null,i=s?.variant||null,d=s?.position||null,r=s?.style||null,m=s?.float||null,f=s?.highlight||null}catch{n=null}(!n||!n.length)&&(console.warn("[admin-sidebar] No admin-sidebar menu found; using fallback tree"),n=Z.slice());let u=[];try{u=await H.get("/api/sidebar/registered-items")||[]}catch{}n=V(n,Q);const{toolsFolder:p,pluginsFolder:y,parented:g}=O(u);n=ee(n,g),n=Y(n,[p,y]);const b=await te(a);b.length&&ne(n,b),n=I(n,a),n=J(n);const[T,U]=await Promise.all([ae().catch(()=>({})),re()]),q=i?` dm-admin-sidebar--${h(i)}`:"";function j(s,l="px"){if(s==null)return s;const o=String(s).trim();return/^\d+(\.\d+)?$/.test(o)?`${o}${l}`:o}let E="";if(r){const s=[];r.fontFamily&&s.push(`font-family: ${r.fontFamily}, sans-serif`),r.fontSize&&s.push(`font-size: ${j(r.fontSize)}`),r.fontWeight&&s.push(`font-weight: ${r.fontWeight}`),r.letterSpacing&&s.push(`letter-spacing: ${j(r.letterSpacing,"em")}`);const l=[];if(s.length&&l.push(`#admin-sidebar .dm-admin-sidebar, #admin-sidebar .dm-admin-sidebar .sidebar-link, #admin-sidebar .dm-admin-sidebar summary, #admin-sidebar .dm-admin-sidebar .sidebar-text { ${s.join("; ")} }`),r.iconSize){const o=j(r.iconSize);l.push(`#admin-sidebar .dm-admin-sidebar [data-icon], #admin-sidebar .dm-admin-sidebar [data-icon] svg { width: ${o} !important; height: ${o} !important; }`)}l.length&&(E=`<style data-admin-sidebar-style>${l.join(" ")}</style>`)}const X=`<div class="dm-admin-sidebar-header"><span data-icon="layout"></span> ${h(U)}</div>`,W=n.some(s=>s&&s.type==="spacer"&&s.size==="flex")?" dm-admin-sidebar--has-flex-spacer":"",D=`${E}<nav class="dm-admin-sidebar${q}${W}">${X}${n.map(s=>N(s,T)).join("")}</nav>`,L=document.createRange();L.selectNodeContents(t);const _=L.createContextualFragment(D);t.replaceChildren(_),Domma.icons.scan(t);const v=Number.parseInt(S.get("sidebar.width"),10);Number.isFinite(v)&&v>=180&&v<=480&&(t.style.width=v+"px"),t.removeAttribute("data-menu-hover"),t.removeAttribute("data-menu-active"),t.style.removeProperty("--dm-menu-highlight"),G(t,{highlight:f});const x=document.querySelector(".dashboard-wrapper");if(["position","top","bottom","left","right","zIndex","maxHeight","transform"].forEach(s=>{t.style[s]=""}),t.classList.remove("dm-menu-floating"),x&&(x.style.paddingLeft="",x.style.paddingRight=""),d==="floating"){K(t,{position:"floating",float:m||{}});const l=m&&m.anchor||"TL",o=Number.isFinite(Number(m?.offsetX))?Number(m.offsetX):16,A=t.getBoundingClientRect().width||v||260;if(x){const C=Math.round(A+o*2)+"px";l==="R"||l==="TR"||l==="BR"?x.style.paddingRight=C:x.style.paddingLeft=C}}const w=document.createElement("div");w.className="dm-admin-sidebar-handle",w.setAttribute("aria-label","Resize sidebar"),t.appendChild(w),t.querySelectorAll("details").forEach(s=>{s.addEventListener("toggle",function(){const l=this.getAttribute("data-state-key");l&&S.set(l,this.open);const o=this.querySelector(":scope > .sidebar-children");if(o)if(this.open){const A=o.scrollHeight;o.style.maxHeight="0",requestAnimationFrame(()=>{o.style.maxHeight=A+"px",o.addEventListener("transitionend",function C(){o.style.maxHeight="none",o.removeEventListener("transitionend",C)})})}else{const A=o.scrollHeight;o.style.maxHeight=A+"px",requestAnimationFrame(()=>{o.style.maxHeight="0"})}})});let k=!1,P=0,F=0;w.addEventListener("mousedown",s=>{k=!0,P=s.clientX,F=t.getBoundingClientRect().width,document.body.style.cursor="col-resize",document.body.style.userSelect="none",s.preventDefault()}),document.addEventListener("mousemove",s=>{if(!k)return;const l=Math.max(180,Math.min(480,F+(s.clientX-P)));t.style.width=l+"px"}),document.addEventListener("mouseup",()=>{k&&(k=!1,document.body.style.cursor="",document.body.style.userSelect="",S.set("sidebar.width",parseInt(t.style.width,10)))});function z(){const s=location.hash||"#/";$(t).find(".sidebar-link").removeClass("active"),$(t).find(`.sidebar-link[data-url="${s}"]`).addClass("active")}z(),M.subscribe("router:afterChange",z)}
|
|
@@ -159,6 +159,53 @@
|
|
|
159
159
|
Reveal dropdowns on hover (desktop navbar; click still works)
|
|
160
160
|
</label>
|
|
161
161
|
</div>
|
|
162
|
+
<div class="form-group">
|
|
163
|
+
<label for="me-highlight-hover">Hover effect</label>
|
|
164
|
+
<select id="me-highlight-hover" name="highlightHover" class="form-input">
|
|
165
|
+
<option value="">- theme default -</option>
|
|
166
|
+
<option value="none">None - no change on hover</option>
|
|
167
|
+
<option value="colour">Colour change</option>
|
|
168
|
+
<option value="underline">Underline</option>
|
|
169
|
+
<option value="overline">Overline</option>
|
|
170
|
+
<option value="background">Background tint</option>
|
|
171
|
+
<option value="uppercase">Uppercase</option>
|
|
172
|
+
<option value="grow">Grow</option>
|
|
173
|
+
<option value="breathe">Breathe</option>
|
|
174
|
+
<option value="glow">Glow</option>
|
|
175
|
+
</select>
|
|
176
|
+
<small class="form-hint">What an item does under the pointer. Applies wherever this menu is drawn - navbar, footer, <code>[menu]</code> and the admin sidebar.</small>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="form-group">
|
|
179
|
+
<label for="me-highlight-active">Current page</label>
|
|
180
|
+
<select id="me-highlight-active" name="highlightActive" class="form-input">
|
|
181
|
+
<option value="">- theme default -</option>
|
|
182
|
+
<option value="none">None - not marked at all</option>
|
|
183
|
+
<option value="bold">Bold</option>
|
|
184
|
+
<option value="underline">Underline</option>
|
|
185
|
+
<option value="overline">Overline</option>
|
|
186
|
+
<option value="background">Background tint</option>
|
|
187
|
+
<option value="darken">Darkened</option>
|
|
188
|
+
<option value="pill">Filled pill</option>
|
|
189
|
+
</select>
|
|
190
|
+
<small class="form-hint">How the item pointing at the page you are on is marked out.</small>
|
|
191
|
+
</div>
|
|
192
|
+
<div class="form-group">
|
|
193
|
+
<label for="me-highlight-accent">Highlight colour</label>
|
|
194
|
+
<div class="me-colour-control">
|
|
195
|
+
<select id="me-highlight-accent" name="highlightAccent" class="form-input">
|
|
196
|
+
<option value="">- theme primary -</option>
|
|
197
|
+
<option value="primary">primary</option>
|
|
198
|
+
<option value="success">success</option>
|
|
199
|
+
<option value="danger">danger</option>
|
|
200
|
+
<option value="warning">warning</option>
|
|
201
|
+
<option value="info">info</option>
|
|
202
|
+
<option value="neutral">neutral</option>
|
|
203
|
+
<option value="__custom__">Custom…</option>
|
|
204
|
+
</select>
|
|
205
|
+
<input type="color" id="me-highlight-accent-hex" class="form-input me-colour-hex" value="#000000" style="display:none">
|
|
206
|
+
</div>
|
|
207
|
+
<small class="form-hint">Used by the colour, underline, overline, tint, glow and pill effects. The underline and overline effects fall back to the item's own text colour when this is unset.</small>
|
|
208
|
+
</div>
|
|
162
209
|
<div class="form-group">
|
|
163
210
|
<label for="me-fontFamily">Font family</label>
|
|
164
211
|
<input type="text" id="me-fontFamily" name="fontFamily" class="form-input" placeholder="Inter">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{api as
|
|
2
|
-
<div class="menu-tree-row menu-tree-row--separator" data-id="${
|
|
1
|
+
import{api as _}from"../api.js";import{colourToCss as bt}from"/public/js/menu-decor.mjs?v=20260905-menu-highlight";import{openIconPicker as gt}from"../lib/card-builder.js";import{applyDrop as vt}from"../lib/menu-tree.js";let yt=1;const D=()=>"i_"+yt++,wt=760;function lt(t,d=null,s=[]){for(const i of t||[]){const n=D();if(i&&i.type==="separator"){s.push({id:n,parentId:d,type:"separator"});continue}if(i&&i.type==="spacer"){s.push({id:n,parentId:d,type:"spacer",size:i.size||"md"});continue}s.push({id:n,parentId:d,text:i.text||"",url:i.url||"",icon:i.icon||"",visibility:i.visibility||"",permission:i.permission||"",hidden:!!i.hidden,bundled:!!i.bundled,badge:i.badge?{...i.badge}:null,pill:i.pill?{...i.pill}:null,colour:i.colour||""}),Array.isArray(i.items)&&i.items.length&<(i.items,n,s)}return s}function xt(t){const d=new Map;for(const i of t)d.has(i.parentId)||d.set(i.parentId,[]),d.get(i.parentId).push(i);function s(i){return(d.get(i)||[]).map(n=>{if(n.type==="separator")return{type:"separator"};if(n.type==="spacer")return{type:"spacer",...n.size&&n.size!=="md"&&{size:n.size}};const o=s(n.id);return{text:(n.text||"").trim(),url:(n.url||"").trim(),...n.icon&&{icon:n.icon.trim()},...n.visibility&&{visibility:n.visibility},...n.permission&&{permission:n.permission},...n.hidden&&{hidden:!0},...n.bundled&&{bundled:!0},...n.badge&&(n.badge.text||n.badge.countFrom)?{badge:{...n.badge.text&&{text:n.badge.text},...n.badge.countFrom&&{countFrom:n.badge.countFrom},...n.badge.variant&&{variant:n.badge.variant}}}:{},...n.pill&&n.pill.variant?{pill:{style:n.pill.style||"filled",variant:n.pill.variant}}:{},...n.colour&&{colour:n.colour},...o.length&&{items:o}}})}return s(null)}function h(t){return String(t||"").replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<")}function kt(t,d){let s=0,i=d.find(n=>n.id===t);for(;i&&i.parentId;)s++,i=d.find(n=>n.id===i.parentId);return s}function dt(t,d){const{top:s,height:i}=t.getBoundingClientRect(),n=i?(d-s)/i:.5;return n<.25?"above":n>.75?"below":"into"}const ct=["me-drop-above","me-drop-below","me-drop-into"];function tt(t){t.get(0).querySelectorAll(".menu-tree-row").forEach(d=>d.classList.remove(...ct))}function _t(t,d,s){let i=null;t.get(0).querySelectorAll(".menu-tree-row").forEach(n=>{const o=n.querySelector(".menu-tree-grip");n.draggable=!1,o&&(o.addEventListener("mousedown",()=>{n.draggable=!0}),o.addEventListener("mouseup",()=>{n.draggable=!1})),n.addEventListener("dragstart",r=>{i=n.dataset.id,n.style.opacity="0.45",r.dataTransfer.effectAllowed="move";try{r.dataTransfer.setData("text/plain",i)}catch{}}),n.addEventListener("dragend",()=>{n.style.opacity="",n.draggable=!1,i=null,tt(t)}),n.addEventListener("dragover",r=>{if(!i||i===n.dataset.id)return;r.preventDefault(),r.dataTransfer.dropEffect="move";const y=dt(n,r.clientY);tt(t),n.classList.add(`me-drop-${y}`)}),n.addEventListener("dragleave",()=>n.classList.remove(...ct)),n.addEventListener("drop",r=>{r.preventDefault();const y=n.dataset.id,x=dt(n,r.clientY);if(tt(t),!i)return;const v=vt(d(),i,y,x);i=null,v&&s()})})}function At(t,d,s=()=>""){t.html("");function i(n){for(const o of d.filter(r=>r.parentId===n)){const r=kt(o.id,d);if(o.type==="separator"){t.append(`
|
|
2
|
+
<div class="menu-tree-row menu-tree-row--separator" data-id="${o.id}" style="margin-left:${r*28}px">
|
|
3
3
|
<span class="menu-tree-grip" data-icon="move"></span>
|
|
4
4
|
<span class="me-sep-line"><span class="me-sep-label">Separator</span></span>
|
|
5
5
|
<button class="btn btn-sm btn-ghost me-ins-item" data-tooltip="Add item below"><span data-icon="plus"></span></button>
|
|
@@ -10,8 +10,8 @@ import{api as S}from"../api.js";import{colourToCss as ct}from"/public/js/menu-de
|
|
|
10
10
|
<button class="btn btn-sm btn-ghost me-down" data-tooltip="Move down"><span data-icon="arrow-down"></span></button>
|
|
11
11
|
<button class="btn btn-sm btn-ghost me-remove" data-tooltip="Remove"><span data-icon="trash"></span></button>
|
|
12
12
|
</div>
|
|
13
|
-
`);continue}if(
|
|
14
|
-
<div class="menu-tree-row menu-tree-row--spacer" data-id="${
|
|
13
|
+
`);continue}if(o.type==="spacer"){const P=["xs","sm","md","lg","xl","flex"].map(z=>`<option value="${z}"${(o.size||"md")===z?" selected":""}>${z==="flex"?"flexible":z}</option>`).join("");t.append(`
|
|
14
|
+
<div class="menu-tree-row menu-tree-row--spacer" data-id="${o.id}" style="margin-left:${r*28}px">
|
|
15
15
|
<span class="menu-tree-grip" data-icon="move"></span>
|
|
16
16
|
<span class="me-spacer-line">
|
|
17
17
|
<span class="me-spacer-label">Spacer</span>
|
|
@@ -25,23 +25,23 @@ import{api as S}from"../api.js";import{colourToCss as ct}from"/public/js/menu-de
|
|
|
25
25
|
<button class="btn btn-sm btn-ghost me-down" data-tooltip="Move down"><span data-icon="arrow-down"></span></button>
|
|
26
26
|
<button class="btn btn-sm btn-ghost me-remove" data-tooltip="Remove"><span data-icon="trash"></span></button>
|
|
27
27
|
</div>
|
|
28
|
-
`);continue}const
|
|
29
|
-
<div class="menu-tree-row menu-tree-row--slim${
|
|
28
|
+
`);continue}const y=o.badge&&(o.badge.text||o.badge.countFrom)?`<span class="dm-menu-badge">${h(String(o.badge.text||"#"))}</span>`:"",x=bt(o.colour),v=x?` style="color:${h(x)}"`:"";t.append(`
|
|
29
|
+
<div class="menu-tree-row menu-tree-row--slim${o.hidden?" menu-tree-row--hidden":""}" data-id="${o.id}" style="margin-left:${r*28}px">
|
|
30
30
|
<span class="menu-tree-grip" data-icon="move"></span>
|
|
31
|
-
<span class="me-row-label"${
|
|
32
|
-
<span class="me-row-url">${
|
|
31
|
+
<span class="me-row-label"${v}>${h(o.text||"(untitled)")}${y}</span>
|
|
32
|
+
<span class="me-row-url">${h(o.url||"")}</span>
|
|
33
33
|
<button class="btn btn-sm btn-ghost me-ins-item" data-tooltip="Add item below"><span data-icon="plus"></span></button>
|
|
34
34
|
<button class="btn btn-sm btn-ghost me-ins-sep" data-tooltip="Add separator below"><span data-icon="minus"></span></button>
|
|
35
35
|
<button class="btn btn-sm btn-ghost me-outdent" data-tooltip="Outdent"><span data-icon="chevron-left"></span></button>
|
|
36
36
|
<button class="btn btn-sm btn-ghost me-indent" data-tooltip="Indent"><span data-icon="chevron-right"></span></button>
|
|
37
37
|
<button class="btn btn-sm btn-ghost me-up" data-tooltip="Move up"><span data-icon="arrow-up"></span></button>
|
|
38
38
|
<button class="btn btn-sm btn-ghost me-down" data-tooltip="Move down"><span data-icon="arrow-down"></span></button>
|
|
39
|
-
<button class="btn btn-sm btn-ghost me-hidden ${
|
|
39
|
+
<button class="btn btn-sm btn-ghost me-hidden ${o.hidden?"active":""}" data-tooltip="${o.hidden?"Show":"Hide"}"><span data-icon="eye-off"></span></button>
|
|
40
40
|
<button class="btn btn-sm btn-secondary me-edit" data-tooltip="Edit"><span data-icon="edit"></span></button>
|
|
41
41
|
<button class="btn btn-sm btn-ghost me-remove" data-tooltip="Remove"><span data-icon="trash"></span></button>
|
|
42
42
|
</div>
|
|
43
|
-
`),o(i.id)}}o(null),Domma.icons.scan(t.get(0)),t.get(0).querySelectorAll("[data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})})}function j(t,d){t.find(".menu-tree-row").each(function(){const s=$(this).data("id"),o=d.find(y=>y.id===s);if(!o||o.type==="separator")return;if(o.type==="spacer"){const y=$(this).find(".me-spacer-size");y.length&&(o.size=y.val());return}const n=$(this).find(".me-text");n.length&&(o.text=n.val());const i=$(this).find(".me-url");i.length&&(o.url=i.val());const r=$(this).find(".me-icon");r.length&&(o.icon=r.val());const w=$(this).find(".me-vis");w.length&&(o.visibility=w.val());const k=$(this).find(".me-perm");k.length&&(o.permission=k.val())})}function _t(t,d){const s={};for(const o of d){const n=t.querySelector(`[name="${o}"]`);n&&(s[o]=n.type==="checkbox"?n.checked:n.value)}return s}function g(t,d={},...s){const o=document.createElement(t);Object.assign(o,d);for(const n of s)n!=null&&o.append(n);return o}function A(t,d,s){const o=g("label",{className:"form-field"},g("span",{className:"form-label",textContent:t}),d);return s&&o.append(g("small",{className:"form-hint",textContent:s,style:"display:block;font-size:.78em;opacity:.7;margin-top:.25rem;line-height:1.35"})),o}function ht(t,d){const s=[["","- Everyone -"],["public","Public - anyone, incl. logged-out"],...(d||[]).map(n=>[n.name,`${n.label||n.name} and above`]),["private","Private - super-admin only"]];t&&!s.some(([n])=>n===t)&&s.push([t,`${t} (custom)`]);const o=M(s,t||"");return o.name="visibility",o}function M(t,d){const s=g("select",{className:"form-select"});return t.forEach(([o,n])=>s.add(new Option(n,o))),s.value=d??"",s}function K(t,d){const s=typeof d=="string"&&d.startsWith("#"),o=M([["","- none -"],["primary","primary"],["success","success"],["danger","danger"],["warning","warning"],["info","info"],["neutral","neutral"],["__custom__","Custom\u2026"]],s?"__custom__":d||""),n=g("input",{type:"color",className:"form-input me-colour-hex",value:s?d:"#000000"});n.style.display=s?"":"none",o.addEventListener("change",()=>{n.style.display=o.value==="__custom__"?"":"none"});const i=A(t,o);return i.append(n),i._read=()=>o.value==="__custom__"?n.value:o.value,i}function yt(t,d){const s=g("input",{className:"form-input me-icon",name:"icon",value:d||""}),o=g("span",{className:"me-icon-preview"});d&&o.setAttribute("data-icon",d);const n=g("button",{type:"button",className:"btn btn-sm btn-ghost",textContent:"Browse\u2026"}),i=r=>{r?o.setAttribute("data-icon",r):o.removeAttribute("data-icon"),Domma.icons.scan(o.parentNode||o)};return n.addEventListener("click",()=>rt(r=>{s.value=r,i(r)})),s.addEventListener("input",()=>i(s.value.trim())),A(t,g("div",{className:"me-icon-field"},s,n,o))}function Z(...t){return g("div",{className:"me-field-grid"},...t)}async function wt(t,d,s,o,n){const i=u=>g("h4",{className:"me-form-section",textContent:u}),r=A("Label",g("input",{className:"form-input",name:"text",value:t.text||""}),"The text shown for this item."),w=A("URL",g("input",{className:"form-input",name:"url",value:t.url||""}),"Where it links. Must start with /, #, https://, or mailto: . Leave blank for a parent that only groups sub-items."),k=yt("Icon",t.icon||""),y=A("Visibility",ht(t.visibility||"",o),"Who can see this item, by role seniority. Picking a role shows it to that role and anyone more senior. Blank = everyone."),P=M([["","- no permission gate -"],...(d||[]).map(u=>[u.key,u.label||u.key])],t.permission||"");P.name="permission";const O=A("Permission",P,"Hide unless the viewer holds this specific permission. Independent of Visibility - both must pass."),J=A("Badge text",g("input",{className:"form-input",name:"badgeText",value:t.badge?.text||""})),X=M([["","- none -"],...(s||[]).map(u=>[u.slug,u.title||u.slug])],t.badge?.countFrom||"");X.name="badgeCount";const V=A("Badge count from",X,"Show a live count of this collection\u2019s entries as the badge."),U=K("Badge colour",t.badge?.variant||""),l=M([["link","Link"],["pill","Pill"]],t.pill?"pill":"link");l.name="renderAs";const x=A("Render as",l,"Pill draws the item as a rounded chip. Pill styling applies to top-level navbar items."),v=A("Pill style",M([["filled","Filled"],["outline","Outline"]],t.pill?.style||"filled"));v.querySelector("select").name="pillStyle";const W=K("Pill colour",t.pill?.variant||""),R=g("div",{className:"me-pill-wrap"},Z(v,W));R.style.display=t.pill?"":"none",l.addEventListener("change",()=>{R.style.display=l.value==="pill"?"":"none"});const T=K("Text colour",t.colour||""),q=g("button",{className:"btn btn-primary",textContent:"Apply"}),z=g("div",{className:"me-item-form"},i("Link"),r,w,k,i("Access"),Z(y,O),i("Badge"),Z(J,U),V,i("Appearance"),x,R,T,q),_=E.slideover({title:"Edit menu item",size:"lg",position:"right"});_.element.appendChild(z),_.open();const B=_.element.closest(".dm-slideover")||_.element.querySelector(".dm-slideover")||_.element;B.style.setProperty("width",ft+"px","important"),B.style.setProperty("max-width","95vw","important"),Domma.icons.scan(z);const I=u=>z.querySelector(`[name="${u}"]`)?.value||"";q.addEventListener("click",()=>{t.text=I("text"),t.url=I("url"),t.icon=I("icon"),t.visibility=I("visibility"),t.permission=I("permission");const u=I("badgeText"),F=I("badgeCount"),N=U._read();if(t.badge=u||F?{...u&&{text:u},...F&&{countFrom:F},...N&&{variant:N}}:null,I("renderAs")==="pill"){const L=W._read();t.pill={style:I("pillStyle")||"filled",...L&&{variant:L}}}else t.pill=null;t.colour=T._read(),_.close(),n()})}export const menuEditorView={templateUrl:"/admin/js/templates/menu-editor.html",async onMount(t){const d=location.hash.match(/^#\/menus\/edit\/(.+)$/),s=d?decodeURIComponent(d[1]):null,o=!s,n=E.loader(t.get(0),{type:"dots"});let i,r,w,k,y,P,O;try{if(o)i={slug:"",name:"",description:"",items:[]};else try{i=await S.menus.get(s)}catch(e){E.toast(`Failed to load menu: ${e.message||e}`,{type:"error"}),location.hash="#/menus";return}r=await S.projects.list().catch(()=>[]),w=await H.get("/api/auth/permissions-registry").catch(()=>({resources:[]})),k=await S.collections.list().catch(()=>[]),y=await S.get("/collections/roles/entries?limit=100").catch(()=>null),P=await S.menuLocations.registry().catch(()=>[]),O=await S.pages.list().catch(()=>[])}finally{n.destroy()}const X=(Array.isArray(y)?y:y?.entries||[]).map(e=>({name:e.data?.name,label:e.data?.label,level:e.data?.level??99})).filter(e=>e.name).sort((e,a)=>a.level-e.level),V='<option value="">- no permission gate -</option>',U=e=>V+(w.resources||[]).map(a=>{const c=(e||"")===a.key?" selected":"";return`<option value="${a.key}"${c}>${a.label||a.key}</option>`}).join("");t.find("#me-title").text(o?"New menu":`Edit "${i.slug}"`);let l=et(i.items);const x=t.find("#me-items-list");function v(){vt(x,l,U),gt(x,()=>l,v)}v(),t.find("#me-add-item").on("click",()=>{j(x,l),l.push({id:D(),parentId:null,text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}),v()}),t.find("#me-add-separator").on("click",()=>{j(x,l),l.push({id:D(),parentId:null,type:"separator"}),v()}),t.find("#me-add-spacer").on("click",()=>{j(x,l),l.push({id:D(),parentId:null,type:"spacer",size:"md"}),v()});function W(e){return function(){j(x,l);const a=$(this).closest(".menu-tree-row").data("id"),c=l.findIndex(h=>h.id===a);if(c===-1)return;const f=l[c],p={separator:{type:"separator"},spacer:{type:"spacer",size:"md"}}[e],m=p?{id:D(),parentId:f.parentId,...p}:{id:D(),parentId:f.parentId,text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1};l.splice(c+1,0,m),v()}}t.off("click",".me-ins-item").on("click",".me-ins-item",W("item")),t.off("click",".me-ins-sep").on("click",".me-ins-sep",W("separator")),t.off("click",".me-remove").on("click",".me-remove",function(){const e=$(this).closest(".menu-tree-row").data("id");l=l.filter(a=>a.id!==e&&a.parentId!==e),v()}),t.off("click",".me-indent").on("click",".me-indent",function(){j(x,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(p=>p.id===e);if(!a)return;const c=l.filter(p=>p.parentId===a.parentId),f=c.findIndex(p=>p.id===e);f<=0||["separator","spacer"].includes(c[f-1].type)||(a.parentId=c[f-1].id,v())}),t.off("click",".me-outdent").on("click",".me-outdent",function(){j(x,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(f=>f.id===e);if(!a||a.parentId==null)return;const c=l.find(f=>f.id===a.parentId);a.parentId=c?c.parentId:null,v()}),t.off("click",".me-up").on("click",".me-up",function(){j(x,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.filter(m=>m.parentId===l.find(h=>h.id===e)?.parentId),c=a.findIndex(m=>m.id===e);if(c<=0)return;const f=l.indexOf(a[c]),p=l.indexOf(a[c-1]);[l[f],l[p]]=[l[p],l[f]],v()}),t.off("click",".me-down").on("click",".me-down",function(){j(x,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.filter(m=>m.parentId===l.find(h=>h.id===e)?.parentId),c=a.findIndex(m=>m.id===e);if(c===-1||c>=a.length-1)return;const f=l.indexOf(a[c]),p=l.indexOf(a[c+1]);[l[f],l[p]]=[l[p],l[f]],v()}),t.off("click",".me-hidden").on("click",".me-hidden",function(){j(x,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(c=>c.id===e);a&&(a.hidden=!a.hidden),v()}),t.off("click",".me-edit").on("click",".me-edit",function(){const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(c=>c.id===e);!a||["separator","spacer"].includes(a.type)||wt(a,w.resources||[],k,X,()=>v())}),E.tabs(t.find("#me-tabs").get(0)),t.find("#me-variant").val(i.variant||""),t.find("#me-position").val(i.position||"");const R=t.find("#me-appearOnHover").get(0);R&&(R.checked=i.appearOnHover===!0),t.find("#me-float-anchor").val(i.float?.anchor||"TL"),t.find("#me-float-offsetX").val(i.float?.offsetX??""),t.find("#me-float-offsetY").val(i.float?.offsetY??""),t.find("#me-float-width").val(i.float?.width??""),t.find("#me-float-radius").val(i.float?.radius??""),t.find("#me-float-shadow").val(i.float?.shadow||""),t.find("#me-float-opacity").val(i.float?.opacity??""),t.find("#me-float-title").val(i.float?.title||"");for(const[e,a]of[["#me-float-collapsible",i.float?.collapsible],["#me-float-collapsed",i.float?.collapsed],["#me-float-movable",i.float?.movable],["#me-float-resizable",i.float?.resizable]]){const c=t.find(e).get(0);c&&(c.checked=a===!0)}const T=i.float?.accent||"",q=T.startsWith("#"),z=t.find("#me-float-accent"),_=t.find("#me-float-accent-hex");z.val(q?"__custom__":T),q&&_.val(T);const B=()=>{_.get(0).style.display=z.val()==="__custom__"?"":"none"};B(),z.on("change",B);const I=()=>z.val()==="__custom__"?_.val():z.val(),u=()=>{const e=t.find("#me-position").val()==="floating";t.find(".dm-float-field").each(function(){this.style.display=e?"":"none"}),e&&B();const a=t.find("#me-orientation").val()==="vertical";t.find(".dm-vertical-field").each(function(){this.style.display=a?"":"none"});const c=!!(t.find("#me-float-collapsible").get(0)||{}).checked;t.find(".dm-float-collapsed-field").each(function(){this.style.display=e&&c?"":"none"})};t.find("#me-orientation").val(i.orientation||""),t.find("#me-side").val(i.side||"left"),u(),t.find("#me-position").on("change",u),t.find("#me-orientation").on("change",u),t.find("#me-float-collapsible").on("change",u),t.find("#me-fontFamily").val(i.style?.fontFamily||""),t.find("#me-fontSize").val(i.style?.fontSize||""),t.find("#me-fontWeight").val(i.style?.fontWeight||""),t.find("#me-letterSpacing").val(i.style?.letterSpacing||""),t.find("#me-iconSize").val(i.style?.iconSize||"");const F=t.find("#me-bind-slot"),N=t.find("#me-bind-projects"),L=t.find("#me-bind-pages");F.html('<option value="">- not bound -</option>'+(P||[]).map(e=>`<option value="${b(e.slot)}">${b(e.label||e.slot)} (${b(e.slot)})</option>`).join("")),N.html(r.map(e=>`<option value="${b(e.slug)}">${b(e.name||e.slug)}</option>`).join("")),F.val(i.binding?.slot||"");const it=new Set(i.binding?.projects||[]);Array.from(N.get(0).options).forEach(e=>{e.selected=it.has(e.value)}),L.val((i.binding?.pages||[]).join(`
|
|
44
|
-
`)),t.find("#me-bind-page-pick").html('<option value="">- pick a page -</option>'+
|
|
45
|
-
`).map(c=>c.trim()).filter(Boolean);a.includes(e)||a.push(e),
|
|
46
|
-
`)),
|
|
47
|
-
`).map(a=>a.trim()).filter(Boolean)}:null}function
|
|
43
|
+
`),i(o.id)}}i(null),Domma.icons.scan(t.get(0)),t.get(0).querySelectorAll("[data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})})}function j(t,d){t.find(".menu-tree-row").each(function(){const s=$(this).data("id"),i=d.find(v=>v.id===s);if(!i||i.type==="separator")return;if(i.type==="spacer"){const v=$(this).find(".me-spacer-size");v.length&&(i.size=v.val());return}const n=$(this).find(".me-text");n.length&&(i.text=n.val());const o=$(this).find(".me-url");o.length&&(i.url=o.val());const r=$(this).find(".me-icon");r.length&&(i.icon=r.val());const y=$(this).find(".me-vis");y.length&&(i.visibility=y.val());const x=$(this).find(".me-perm");x.length&&(i.permission=x.val())})}function Lt(t,d){const s={};for(const i of d){const n=t.querySelector(`[name="${i}"]`);n&&(s[i]=n.type==="checkbox"?n.checked:n.value)}return s}function b(t,d={},...s){const i=document.createElement(t);Object.assign(i,d);for(const n of s)n!=null&&i.append(n);return i}function O(t,d,s){const i=b("label",{className:"form-field"},b("span",{className:"form-label",textContent:t}),d);return s&&i.append(b("small",{className:"form-hint",textContent:s,style:"display:block;font-size:.78em;opacity:.7;margin-top:.25rem;line-height:1.35"})),i}function St(t,d){const s=[["","- Everyone -"],["public","Public - anyone, incl. logged-out"],...(d||[]).map(n=>[n.name,`${n.label||n.name} and above`]),["private","Private - super-admin only"]];t&&!s.some(([n])=>n===t)&&s.push([t,`${t} (custom)`]);const i=W(s,t||"");return i.name="visibility",i}function W(t,d){const s=b("select",{className:"form-select"});return t.forEach(([i,n])=>s.add(new Option(n,i))),s.value=d??"",s}function et(t,d){const s=typeof d=="string"&&d.startsWith("#"),i=W([["","- none -"],["primary","primary"],["success","success"],["danger","danger"],["warning","warning"],["info","info"],["neutral","neutral"],["__custom__","Custom\u2026"]],s?"__custom__":d||""),n=b("input",{type:"color",className:"form-input me-colour-hex",value:s?d:"#000000"});n.style.display=s?"":"none",i.addEventListener("change",()=>{n.style.display=i.value==="__custom__"?"":"none"});const o=O(t,i);return o.append(n),o._read=()=>i.value==="__custom__"?n.value:i.value,o}function It(t,d){const s=b("input",{className:"form-input me-icon",name:"icon",value:d||""}),i=b("span",{className:"me-icon-preview"});d&&i.setAttribute("data-icon",d);const n=b("button",{type:"button",className:"btn btn-sm btn-ghost",textContent:"Browse\u2026"}),o=r=>{r?i.setAttribute("data-icon",r):i.removeAttribute("data-icon"),Domma.icons.scan(i.parentNode||i)};return n.addEventListener("click",()=>gt(r=>{s.value=r,o(r)})),s.addEventListener("input",()=>o(s.value.trim())),O(t,b("div",{className:"me-icon-field"},s,n,i))}function nt(...t){return b("div",{className:"me-field-grid"},...t)}async function jt(t,d,s,i,n){const o=u=>b("h4",{className:"me-form-section",textContent:u}),r=O("Label",b("input",{className:"form-input",name:"text",value:t.text||""}),"The text shown for this item."),y=O("URL",b("input",{className:"form-input",name:"url",value:t.url||""}),"Where it links. Must start with /, #, https://, or mailto: . Leave blank for a parent that only groups sub-items."),x=It("Icon",t.icon||""),v=O("Visibility",St(t.visibility||"",i),"Who can see this item, by role seniority. Picking a role shows it to that role and anyone more senior. Blank = everyone."),P=W([["","- no permission gate -"],...(d||[]).map(u=>[u.key,u.label||u.key])],t.permission||"");P.name="permission";const z=O("Permission",P,"Hide unless the viewer holds this specific permission. Independent of Visibility - both must pass."),it=O("Badge text",b("input",{className:"form-input",name:"badgeText",value:t.badge?.text||""})),U=W([["","- none -"],...(s||[]).map(u=>[u.slug,u.title||u.slug])],t.badge?.countFrom||"");U.name="badgeCount";const J=O("Badge count from",U,"Show a live count of this collection\u2019s entries as the badge."),G=et("Badge colour",t.badge?.variant||""),l=W([["link","Link"],["pill","Pill"]],t.pill?"pill":"link");l.name="renderAs";const w=O("Render as",l,"Pill draws the item as a rounded chip. Pill styling applies to top-level navbar items."),g=O("Pill style",W([["filled","Filled"],["outline","Outline"]],t.pill?.style||"filled"));g.querySelector("select").name="pillStyle";const M=et("Pill colour",t.pill?.variant||""),R=b("div",{className:"me-pill-wrap"},nt(g,M));R.style.display=t.pill?"":"none",l.addEventListener("change",()=>{R.style.display=l.value==="pill"?"":"none"});const T=et("Text colour",t.colour||""),q=b("button",{className:"btn btn-primary",textContent:"Apply"}),C=b("div",{className:"me-item-form"},o("Link"),r,y,x,o("Access"),nt(v,z),o("Badge"),nt(it,G),J,o("Appearance"),w,R,T,q),S=E.slideover({title:"Edit menu item",size:"lg",position:"right"});S.element.appendChild(C),S.open();const B=S.element.closest(".dm-slideover")||S.element.querySelector(".dm-slideover")||S.element;B.style.setProperty("width",wt+"px","important"),B.style.setProperty("max-width","95vw","important"),Domma.icons.scan(C);const A=u=>C.querySelector(`[name="${u}"]`)?.value||"";q.addEventListener("click",()=>{t.text=A("text"),t.url=A("url"),t.icon=A("icon"),t.visibility=A("visibility"),t.permission=A("permission");const u=A("badgeText"),N=A("badgeCount"),Y=G._read();if(t.badge=u||N?{...u&&{text:u},...N&&{countFrom:N},...Y&&{variant:Y}}:null,A("renderAs")==="pill"){const L=M._read();t.pill={style:A("pillStyle")||"filled",...L&&{variant:L}}}else t.pill=null;t.colour=T._read(),S.close(),n()})}export const menuEditorView={templateUrl:"/admin/js/templates/menu-editor.html",async onMount(t){const d=location.hash.match(/^#\/menus\/edit\/(.+)$/),s=d?decodeURIComponent(d[1]):null,i=!s,n=E.loader(t.get(0),{type:"dots"});let o,r,y,x,v,P,z;try{if(i)o={slug:"",name:"",description:"",items:[]};else try{o=await _.menus.get(s)}catch(e){E.toast(`Failed to load menu: ${e.message||e}`,{type:"error"}),location.hash="#/menus";return}r=await _.projects.list().catch(()=>[]),y=await H.get("/api/auth/permissions-registry").catch(()=>({resources:[]})),x=await _.collections.list().catch(()=>[]),v=await _.get("/collections/roles/entries?limit=100").catch(()=>null),P=await _.menuLocations.registry().catch(()=>[]),z=await _.pages.list().catch(()=>[])}finally{n.destroy()}const U=(Array.isArray(v)?v:v?.entries||[]).map(e=>({name:e.data?.name,label:e.data?.label,level:e.data?.level??99})).filter(e=>e.name).sort((e,a)=>a.level-e.level),J='<option value="">- no permission gate -</option>',G=e=>J+(y.resources||[]).map(a=>{const c=(e||"")===a.key?" selected":"";return`<option value="${a.key}"${c}>${a.label||a.key}</option>`}).join("");t.find("#me-title").text(i?"New menu":`Edit "${o.slug}"`);let l=lt(o.items);const w=t.find("#me-items-list");function g(){At(w,l,G),_t(w,()=>l,g)}g(),t.find("#me-add-item").on("click",()=>{j(w,l),l.push({id:D(),parentId:null,text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}),g()}),t.find("#me-add-separator").on("click",()=>{j(w,l),l.push({id:D(),parentId:null,type:"separator"}),g()}),t.find("#me-add-spacer").on("click",()=>{j(w,l),l.push({id:D(),parentId:null,type:"spacer",size:"md"}),g()});function M(e){return function(){j(w,l);const a=$(this).closest(".menu-tree-row").data("id"),c=l.findIndex(k=>k.id===a);if(c===-1)return;const f=l[c],p={separator:{type:"separator"},spacer:{type:"spacer",size:"md"}}[e],m=p?{id:D(),parentId:f.parentId,...p}:{id:D(),parentId:f.parentId,text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1};l.splice(c+1,0,m),g()}}t.off("click",".me-ins-item").on("click",".me-ins-item",M("item")),t.off("click",".me-ins-sep").on("click",".me-ins-sep",M("separator")),t.off("click",".me-remove").on("click",".me-remove",function(){const e=$(this).closest(".menu-tree-row").data("id");l=l.filter(a=>a.id!==e&&a.parentId!==e),g()}),t.off("click",".me-indent").on("click",".me-indent",function(){j(w,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(p=>p.id===e);if(!a)return;const c=l.filter(p=>p.parentId===a.parentId),f=c.findIndex(p=>p.id===e);f<=0||["separator","spacer"].includes(c[f-1].type)||(a.parentId=c[f-1].id,g())}),t.off("click",".me-outdent").on("click",".me-outdent",function(){j(w,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(f=>f.id===e);if(!a||a.parentId==null)return;const c=l.find(f=>f.id===a.parentId);a.parentId=c?c.parentId:null,g()}),t.off("click",".me-up").on("click",".me-up",function(){j(w,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.filter(m=>m.parentId===l.find(k=>k.id===e)?.parentId),c=a.findIndex(m=>m.id===e);if(c<=0)return;const f=l.indexOf(a[c]),p=l.indexOf(a[c-1]);[l[f],l[p]]=[l[p],l[f]],g()}),t.off("click",".me-down").on("click",".me-down",function(){j(w,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.filter(m=>m.parentId===l.find(k=>k.id===e)?.parentId),c=a.findIndex(m=>m.id===e);if(c===-1||c>=a.length-1)return;const f=l.indexOf(a[c]),p=l.indexOf(a[c+1]);[l[f],l[p]]=[l[p],l[f]],g()}),t.off("click",".me-hidden").on("click",".me-hidden",function(){j(w,l);const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(c=>c.id===e);a&&(a.hidden=!a.hidden),g()}),t.off("click",".me-edit").on("click",".me-edit",function(){const e=$(this).closest(".menu-tree-row").data("id"),a=l.find(c=>c.id===e);!a||["separator","spacer"].includes(a.type)||jt(a,y.resources||[],x,U,()=>g())}),E.tabs(t.find("#me-tabs").get(0)),t.find("#me-variant").val(o.variant||""),t.find("#me-position").val(o.position||"");const R=t.find("#me-appearOnHover").get(0);R&&(R.checked=o.appearOnHover===!0),t.find("#me-float-anchor").val(o.float?.anchor||"TL"),t.find("#me-float-offsetX").val(o.float?.offsetX??""),t.find("#me-float-offsetY").val(o.float?.offsetY??""),t.find("#me-float-width").val(o.float?.width??""),t.find("#me-float-radius").val(o.float?.radius??""),t.find("#me-float-shadow").val(o.float?.shadow||""),t.find("#me-float-opacity").val(o.float?.opacity??""),t.find("#me-float-title").val(o.float?.title||"");for(const[e,a]of[["#me-float-collapsible",o.float?.collapsible],["#me-float-collapsed",o.float?.collapsed],["#me-float-movable",o.float?.movable],["#me-float-resizable",o.float?.resizable]]){const c=t.find(e).get(0);c&&(c.checked=a===!0)}const T=o.float?.accent||"",q=T.startsWith("#"),C=t.find("#me-float-accent"),S=t.find("#me-float-accent-hex");C.val(q?"__custom__":T),q&&S.val(T);const B=()=>{S.get(0).style.display=C.val()==="__custom__"?"":"none"};B(),C.on("change",B);const A=()=>C.val()==="__custom__"?S.val():C.val(),u=()=>{const e=t.find("#me-position").val()==="floating";t.find(".dm-float-field").each(function(){this.style.display=e?"":"none"}),e&&B();const a=t.find("#me-orientation").val()==="vertical";t.find(".dm-vertical-field").each(function(){this.style.display=a?"":"none"});const c=!!(t.find("#me-float-collapsible").get(0)||{}).checked;t.find(".dm-float-collapsed-field").each(function(){this.style.display=e&&c?"":"none"})};t.find("#me-orientation").val(o.orientation||""),t.find("#me-side").val(o.side||"left"),u(),t.find("#me-position").on("change",u),t.find("#me-orientation").on("change",u),t.find("#me-float-collapsible").on("change",u),t.find("#me-highlight-hover").val(o.highlight?.hover||""),t.find("#me-highlight-active").val(o.highlight?.active||"");const N=o.highlight?.accent||"",Y=N.startsWith("#"),L=t.find("#me-highlight-accent"),Q=t.find("#me-highlight-accent-hex");L.val(Y?"__custom__":N),Y&&Q.val(N);const ot=()=>{Q.get(0).style.display=L.val()==="__custom__"?"":"none"};ot(),L.on("change",ot);const rt=()=>L.val()==="__custom__"?Q.val():L.val();t.find("#me-fontFamily").val(o.style?.fontFamily||""),t.find("#me-fontSize").val(o.style?.fontSize||""),t.find("#me-fontWeight").val(o.style?.fontWeight||""),t.find("#me-letterSpacing").val(o.style?.letterSpacing||""),t.find("#me-iconSize").val(o.style?.iconSize||"");const K=t.find("#me-bind-slot"),Z=t.find("#me-bind-projects"),X=t.find("#me-bind-pages");K.html('<option value="">- not bound -</option>'+(P||[]).map(e=>`<option value="${h(e.slot)}">${h(e.label||e.slot)} (${h(e.slot)})</option>`).join("")),Z.html(r.map(e=>`<option value="${h(e.slug)}">${h(e.name||e.slug)}</option>`).join("")),K.val(o.binding?.slot||"");const pt=new Set(o.binding?.projects||[]);Array.from(Z.get(0).options).forEach(e=>{e.selected=pt.has(e.value)}),X.val((o.binding?.pages||[]).join(`
|
|
44
|
+
`)),t.find("#me-bind-page-pick").html('<option value="">- pick a page -</option>'+z.map(e=>{const a=e.urlPath||e.url||"";return a?`<option value="${h(a)}">${h(e.title||a)} - ${h(a)}</option>`:""}).join("")),t.find("#me-bind-page-add").on("click",()=>{const e=t.find("#me-bind-page-pick").val();if(!e)return;const a=X.val().split(`
|
|
45
|
+
`).map(c=>c.trim()).filter(Boolean);a.includes(e)||a.push(e),X.val(a.join(`
|
|
46
|
+
`)),V()});function at(){const e=K.val();return e?{slot:e,projects:Array.from(Z.get(0).selectedOptions).map(a=>a.value),pages:X.val().split(`
|
|
47
|
+
`).map(a=>a.trim()).filter(Boolean)}:null}function V(){const e=at(),a=t.find("#me-bind-summary");if(!e){a.html('<span class="text-muted">Not bound - this menu renders only where it is mapped or placed by a shortcode.</span>');return}const c=[];e.projects.length&&c.push(`pages in ${e.projects.map(m=>`<code>${h(m)}</code>`).join(", ")}`),e.pages.length&&c.push(`pages matching ${e.pages.map(m=>`<code>${h(m)}</code>`).join(", ")}`);const f=e.pages.filter(m=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(m)),p=f.length?`<div class="text-danger" style="margin-top:.4rem">Not valid page patterns: ${f.map(m=>`<code>${h(m)}</code>`).join(", ")}</div>`:"";a.html(c.length?`Takes over the <code>${h(e.slot)}</code> slot on ${c.join(" and ")}.${p}`:`<span class="text-warning">Slot <code>${h(e.slot)}</code> selected but no project or page chosen - the binding will never match.</span>`)}K.on("change",V),Z.on("change",V),X.on("input",V),V();const{getProjectFromHash:mt}=await import("../lib/project-context.js"),ft=i?mt():null,st=t.find("#me-project");st.html('<option value="">- none -</option>'+r.map(e=>`<option value="${h(e.slug)}">${h(e.name||e.slug)}</option>`).join("")),t.find("#me-slug").val(o.slug||""),t.find("#me-name").val(o.name||""),t.find("#me-description").val(o.description||""),st.val(o.meta?.project||ft||""),Domma.icons.scan(t.get(0)),t.find("#me-save").on("click",async()=>{j(w,l);const e={variant:t.find("#me-variant").val(),position:t.find("#me-position").val(),appearOnHover:!!(t.find("#me-appearOnHover").get(0)||{}).checked,floatAnchor:t.find("#me-float-anchor").val(),floatOffsetX:t.find("#me-float-offsetX").val(),floatOffsetY:t.find("#me-float-offsetY").val(),floatWidth:t.find("#me-float-width").val(),floatRadius:t.find("#me-float-radius").val(),floatShadow:t.find("#me-float-shadow").val(),floatAccent:A(),floatOpacity:t.find("#me-float-opacity").val(),floatTitle:t.find("#me-float-title").val().trim(),floatCollapsible:!!(t.find("#me-float-collapsible").get(0)||{}).checked,floatCollapsed:!!(t.find("#me-float-collapsed").get(0)||{}).checked,floatMovable:!!(t.find("#me-float-movable").get(0)||{}).checked,floatResizable:!!(t.find("#me-float-resizable").get(0)||{}).checked,highlightHover:t.find("#me-highlight-hover").val(),highlightActive:t.find("#me-highlight-active").val(),highlightAccent:rt(),orientation:t.find("#me-orientation").val(),side:t.find("#me-side").val(),fontFamily:t.find("#me-fontFamily").val(),fontSize:t.find("#me-fontSize").val(),fontWeight:t.find("#me-fontWeight").val(),letterSpacing:t.find("#me-letterSpacing").val(),iconSize:t.find("#me-iconSize").val()},a={slug:t.find("#me-slug").val().trim(),name:t.find("#me-name").val().trim(),description:t.find("#me-description").val().trim(),project:t.find("#me-project").val()},c=["fontFamily","fontSize","fontWeight","letterSpacing","iconSize"],f=Object.fromEntries(Object.entries(e).filter(([I,F])=>c.includes(I)&&F)),p={};if(e.position==="floating"){e.floatAnchor&&(p.anchor=e.floatAnchor);for(const[I,F]of[["offsetX",e.floatOffsetX],["offsetY",e.floatOffsetY],["width",e.floatWidth],["radius",e.floatRadius],["opacity",e.floatOpacity]])F!==""&&F!=null&&Number.isFinite(Number(F))&&(p[I]=Number(F));e.floatShadow&&(p.shadow=e.floatShadow),e.floatAccent&&(p.accent=e.floatAccent),e.floatTitle&&(p.title=e.floatTitle),e.floatCollapsible&&(p.collapsible=!0),e.floatCollapsible&&e.floatCollapsed&&(p.collapsed=!0),e.floatMovable&&(p.movable=!0),e.floatResizable&&(p.resizable=!0)}const m={};e.highlightHover&&(m.hover=e.highlightHover),e.highlightActive&&(m.active=e.highlightActive),e.highlightAccent&&(m.accent=e.highlightAccent);const k={slug:a.slug,name:a.name,description:a.description,...e.variant&&{variant:e.variant},...e.position&&{position:e.position},...e.orientation&&{orientation:e.orientation},...e.orientation==="vertical"&&e.side&&{side:e.side},...Object.keys(p).length&&{float:p},...Object.keys(m).length&&{highlight:m},...e.appearOnHover&&{appearOnHover:!0},...Object.keys(f).length&&{style:f},binding:at(),items:xt(l),meta:{...o.meta||{},project:a.project||null}};try{if(i)await _.menus.create(k);else if(k.slug!==o.slug){await _.menus.create(k);const I=await _.menuLocations.get();let F=!1;for(const[ut,ht]of Object.entries(I))ht===o.slug&&(I[ut]=k.slug,F=!0);F&&await _.menuLocations.save(I),await _.menus.remove(o.slug)}else await _.menus.update(o.slug,k);E.toast("Saved.",{type:"success"}),location.hash="#/menus/edit/"+encodeURIComponent(k.slug)}catch(I){E.toast(`Save failed: ${I.message||I}`,{type:"error"})}})}};
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a){transition:color .18s ease,background-color .18s ease,text-shadow .18s ease,transform .18s ease,letter-spacing .18s ease,text-decoration-color .18s ease}.page-body :is([data-menu-hover],[data-menu-active]).dm-menu li>a{color:var(--dm-primary, inherit);text-decoration:none}[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{color:inherit!important;background-color:transparent!important;text-decoration:none!important;text-shadow:none!important;transform:none!important}[data-menu-hover=colour] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{color:var(--dm-menu-highlight, var(--dm-primary))!important;background-color:transparent!important;text-decoration:none!important}[data-menu-hover=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-hover=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-hover=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}[data-menu-hover=uppercase] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{text-transform:uppercase!important;letter-spacing:.04em;background-color:transparent!important;text-decoration:none!important}:is([data-menu-hover=grow],[data-menu-hover=breathe]) :is(.dm-menu,.footer-nav) li>a{display:inline-block}[data-menu-hover=grow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{transform:scale(1.08);background-color:transparent!important;text-decoration:none!important}@keyframes dm-menu-breathe{0%,to{opacity:1;transform:scale(1)}50%{opacity:.72;transform:scale(1.05)}}[data-menu-hover=breathe] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{animation:dm-menu-breathe 1.4s ease-in-out infinite;background-color:transparent!important;text-decoration:none!important}[data-menu-hover=glow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{text-shadow:0 0 8px color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary)) 70%,transparent);background-color:transparent!important;text-decoration:none!important}[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){box-shadow:none!important;text-decoration:none!important}[data-menu-active=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){font-weight:inherit!important;background-color:transparent!important}[data-menu-active=bold] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){font-weight:700!important;background-color:transparent!important}[data-menu-active=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-active=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-active=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px)}[data-menu-active=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){background-color:#00000038!important;border-radius:var(--dm-radius-md, 6px)}[data-menu-active=pill] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){background-color:var(--dm-menu-highlight, var(--dm-primary))!important;color:#fff!important;border-radius:999px;padding-inline:.9em}@media(prefers-reduced-motion:reduce){[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover{transition:none;animation:none!important;transform:none!important}}
|
package/public/css/site.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
body,button,input,select,textarea{font-family:Roboto,sans-serif}.navbar-brand-logo{height:32px;width:auto;display:inline-block;vertical-align:middle;margin-right:.4em}.navbar-brand-tagline{display:block;font-size:.65em;opacity:.75;line-height:1.2;letter-spacing:.02em}.navbar-brand-text.navbar-brand-sm{font-size:.85em}.navbar-brand-text.navbar-brand-lg{font-size:1.25em}.navbar-actions{order:4;margin-left:auto;display:flex;align-items:center;gap:.5rem}#site-navbar.navbar-dark .navbar-actions,#site-navbar.navbar-light .navbar-actions{color:var(--dm-navbar-text)}#site-navbar.navbar-dark .site-search-shortcut-hint,#site-navbar.navbar-light .site-search-shortcut-hint{color:color-mix(in srgb,var(--dm-navbar-text) 65%,var(--dm-navbar-bg));border-color:color-mix(in srgb,var(--dm-navbar-text) 28%,transparent)}.site-main{min-height:calc(100vh - 60px);padding-top:2rem;padding-bottom:4rem}.site-main.with-sidebar{display:grid;grid-template-columns:260px 1fr;gap:0}.site-sidebar{min-height:100%;border-right:1px solid var(--dm-border, rgba(255,255,255,.08))}.site-content{overflow:hidden}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.container{padding:0 1.5rem}.page-title{font-size:clamp(1.5rem,4vw,2rem);font-weight:700;margin-bottom:1.5rem;line-height:1.2}.page-body{line-height:1.7;font-size:1rem}.page-body h1,.page-body h2,.page-body h3,.page-body h4{margin-top:2rem;margin-bottom:.75rem;font-weight:600}.page-body h2{font-size:clamp(1.2rem,3vw,1.5rem)}.page-body h3{font-size:clamp(1.1rem,2.5vw,1.25rem)}.page-body p{margin-bottom:1rem}.page-body ul,.page-body ol{margin-bottom:1rem;padding-left:1.5rem}.page-body a{color:var(--dm-primary, #5b8cff)}.page-body a:hover{text-decoration:underline}.page-body code{font-family:Fira Code,Courier New,monospace;font-size:.9em;background:var(--dm-code-bg, rgba(255,255,255,.06));color:var(--dm-code-text, inherit);padding:.15em .35em;border-radius:3px}.page-body pre{background:var(--dm-code-bg, rgba(0,0,0,.3));color:var(--dm-code-text, inherit);border:1px solid var(--dm-code-border, rgba(255,255,255,.08));border-radius:6px;padding:1rem;overflow-x:auto;margin-bottom:1rem}.page-body pre code{background:none;padding:0}.page-body img{max-width:100%;border-radius:6px}.page-body blockquote{border-left:3px solid var(--dm-primary, #5b8cff);margin:1.5rem 0;padding:.75rem 1rem;background:color-mix(in srgb,var(--dm-primary, #5b8cff) 8%,transparent);border-radius:0 6px 6px 0}h3.accordion-header{margin:0}.accordion-button{all:unset;display:flex;align-items:center;justify-content:space-between;width:100%;cursor:pointer;font:inherit}.page-body .card-header h2{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.card[data-collapsible] .card-header{cursor:pointer;user-select:none;display:flex;align-items:center;justify-content:space-between}.card[data-collapsible] .card-header:after{content:"\25be";font-size:1.1em;line-height:1;display:inline-block;transition:transform .25s ease;flex-shrink:0}.card[data-collapsible].is-collapsed .card-header:after{transform:rotate(-90deg)}.card[data-collapsible] .card-body{overflow:hidden;max-height:4000px;opacity:1;transition:max-height .3s ease,opacity .25s ease}.card[data-collapsible].is-collapsed .card-body{max-height:0;opacity:0}.card-primary>.card-header,.card-primary>.card-footer{background-color:color-mix(in srgb,var(--dm-primary) 18%,var(--dm-surface));color:var(--dm-text);border-color:var(--dm-primary)}.card-primary>.card-header .card-title{color:var(--dm-text)}.navbar-link span[data-icon],.navbar-link svg,.navbar-dropdown-toggle span[data-icon],.navbar-dropdown-toggle svg,.navbar-dropdown-item span[data-icon],.navbar-dropdown-item svg{width:13px!important;height:13px!important;margin-right:10px!important}#site-navbar .navbar-dropdown-toggle,#site-navbar .navbar-dropdown-item{font-size:var(--dm-font-size-base)}@media(min-width:993px){#site-navbar .navbar-dropdown-toggle,#site-navbar .navbar-dropdown-item{font-size:var(--dm-font-size-sm)}}@media(min-width:1201px){#site-navbar .navbar-dropdown-toggle,#site-navbar .navbar-dropdown-item{font-size:var(--dm-font-size-xs)}}.dm-reduced-motion *,.dm-reduced-motion *:before,.dm-reduced-motion *:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}.page-footer{border-top:1px solid var(--dm-border, rgba(255,255,255,.08));padding:1.5rem 0}.footer-inner{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;max-width:1200px;margin:0 auto}.footer-inner p{margin:0;color:var(--dm-text-muted, #888);font-size:.875rem}.footer-links{display:flex;gap:1.25rem}.footer-links a{color:var(--dm-text-muted, #888);font-size:.875rem;text-decoration:none}.footer-links a:hover{color:var(--dm-text, #eee)}.footer-social{display:flex;gap:.5rem;align-items:center}.footer-social-link{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;color:var(--dm-text-muted, #888);transition:color .15s}.footer-social-link:hover{color:var(--dm-text, #eee)}.footer-social-link svg{width:1rem;height:1rem}.footer-motion-switch{font-size:.8rem;color:var(--dm-text-muted, #888);white-space:nowrap}.footer-motion-switch .form-switch-label{color:var(--dm-text-muted, #888)}.footer-motion-switch .form-switch-input{width:2rem;height:1.125rem}.footer-motion-switch .form-switch-input:after{width:.875rem;height:.875rem}.footer-motion-switch .form-switch-input:checked:after{transform:translate(.875rem)}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:.875rem 1.25rem;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .08));flex-shrink:0}.dm-slideover-title{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.dm-slideover-body{padding:1.25rem;overflow:auto;overscroll-behavior:contain;flex:1;min-height:0;scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}.dm-slideover-body::-webkit-scrollbar{width:8px;height:8px}.dm-slideover-body::-webkit-scrollbar-track{background:transparent}.dm-slideover-body::-webkit-scrollbar-thumb{background:var(--dm-border);border-radius:4px}.dm-slideover-body::-webkit-scrollbar-thumb:hover{background:var(--dm-text-muted)}@media(max-width:768px){.site-main.with-sidebar{grid-template-columns:1fr}.site-sidebar{display:none}}.dm-spacer{display:block;width:100%}.hero-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.site-main:has(.page-body>.hero-breakout:first-child){padding-top:0}body[data-layout=landing]>.site-main{padding-top:0}body[data-layout=landing]>.site-main .container{max-width:none;padding:0}body[data-layout=landing] .page-body{padding-left:1.5rem;padding-right:1.5rem}body[data-layout=landing] .page-body>p,body[data-layout=landing] .page-body>h1,body[data-layout=landing] .page-body>h2,body[data-layout=landing] .page-body>h3,body[data-layout=landing] .page-body>ul,body[data-layout=landing] .page-body>ol,body[data-layout=landing] .page-body>blockquote{max-width:860px;margin-left:auto;margin-right:auto}.hero-breakout{width:100vw;margin-left:calc((100% - 100vw)/2);max-width:none}body[data-layout=landing] .page-body .hero-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem}body[data-layout=landing] .page-body .grid-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem;padding-left:1.5rem;padding-right:1.5rem}.page-body .card{transition:transform .2s ease,box-shadow .2s ease}.page-body .card:hover{transform:translateY(-3px);box-shadow:0 8px 24px #00000059}.page-body .card-header-icon-inline{display:flex;align-items:center;gap:.6rem}.page-body .card-header-icon-inline [data-icon]{flex-shrink:0;line-height:0}.page-body .card-header-icon-inline [data-icon] svg,.page-body .card-header-icon-inline>svg{display:block;width:1.25rem;height:1.25rem}.page-body .card-header-icon-stacked{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.35rem;padding-top:.25rem}.page-body .card-header-icon-stacked [data-icon],.page-body .card-header-icon-stacked svg{width:2rem;height:2rem}.page-body .dm-card-clean{background:var(--dm-surface);border:1px solid var(--dm-border);box-shadow:0 1px 4px #0000000f,0 2px 8px #0000000a;transition:transform .2s ease,box-shadow .2s ease}.page-body .dm-card-clean:hover{transform:translateY(-4px);box-shadow:0 8px 24px #0000001a,0 2px 8px #0000000f}.page-body .dm-card-clean .card-header{color:var(--dm-text)}.page-body .dm-card-clean .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-clean .card-footer{color:var(--dm-text-muted);border-top:1px solid var(--dm-border)}.page-body .dm-card-gradient{background:var(--dm-card-bg, #fff);border:none;box-shadow:0 4px 20px #6366f124;transition:transform .2s ease,box-shadow .2s ease}.page-body .dm-card-gradient:hover{transform:translateY(-5px);box-shadow:0 16px 40px #6366f140}.page-body .dm-card-gradient .card-header{background:linear-gradient(135deg,var(--dm-card-g-start, #6366f1),var(--dm-card-g-end, #8b5cf6));color:#fff;border-bottom:none}.page-body .dm-card-gradient .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-gradient .card-footer{color:var(--dm-text-muted);border-top:1px solid var(--dm-border)}.page-body .dm-card-glass{background:#ffffff2e;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1px solid rgba(255,255,255,.38);box-shadow:0 4px 24px #00000014;transition:transform .2s ease,box-shadow .2s ease,background .2s ease}.page-body .dm-card-glass:hover{transform:translateY(-4px);box-shadow:0 12px 36px #00000024;background:#ffffff42}.page-body .dm-card-glass .card-header{border-bottom:1px solid rgba(255,255,255,.25);color:var(--dm-text)}.page-body .dm-card-glass .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-glass .card-footer{color:var(--dm-text-muted)}.page-body .dm-card-accent{background:var(--dm-surface);border:1px solid var(--dm-border);border-left:4px solid var(--dm-primary, #6366f1);box-shadow:0 1px 4px #0000000d;transition:transform .2s ease,box-shadow .2s ease,border-left-color .2s ease}.page-body .dm-card-accent:hover{transform:translateY(-3px);border-left-color:var(--dm-primary-hover, #4f46e5);box-shadow:0 8px 24px #6366f11f}.page-body .dm-card-accent .card-header{color:var(--dm-primary);border-bottom:none}.page-body .dm-card-accent .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-accent .card-footer{color:var(--dm-text-muted);border-top:1px solid var(--dm-border)}.page-body .dm-card-dark{background:linear-gradient(160deg,#1e293b,#0f172a);border:1px solid rgba(255,255,255,.06);box-shadow:0 4px 20px #0000004d;transition:transform .2s ease,box-shadow .2s ease}.page-body .dm-card-dark:hover{transform:translateY(-4px) scale(1.012);box-shadow:0 16px 40px #00000073}.page-body .dm-card-dark .card-header{color:#f1f5f9;border-bottom:1px solid rgba(255,255,255,.08)}.page-body .dm-card-dark .card-body{color:#94a3b8}.page-body .dm-card-dark .card-footer{color:#475569;border-top:1px solid rgba(255,255,255,.06)}.page-body .dm-card-glow{background:var(--dm-surface);border:1px solid color-mix(in srgb,var(--dm-primary, #6366f1) 45%,transparent);box-shadow:0 0 #6366f100;transition:transform .2s ease,box-shadow .3s ease,border-color .2s ease}.page-body .dm-card-glow:hover{transform:translateY(-3px);border-color:var(--dm-primary, #818cf8);box-shadow:0 0 0 4px color-mix(in srgb,var(--dm-primary, #6366f1) 14%,transparent),0 0 28px color-mix(in srgb,var(--dm-primary, #6366f1) 22%,transparent)}.page-body .dm-card-glow .card-header{color:var(--dm-primary);border-bottom:1px solid color-mix(in srgb,var(--dm-primary, #6366f1) 20%,transparent)}.page-body .dm-card-glow .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-glow .card-footer{border-top:1px solid color-mix(in srgb,var(--dm-primary, #6366f1) 20%,transparent);color:var(--dm-primary, #818cf8)}.page-body .card-hover{transition:transform .2s ease,box-shadow .2s ease}.page-body .card-hover:hover{transform:translateY(-3px);box-shadow:0 8px 20px #0000001a}.card-gradient-indigo{background:linear-gradient(135deg,#6366f1,#8b5cf6)}.card-gradient-ocean{background:linear-gradient(135deg,#0891b2,#2563eb)}.card-gradient-sunset{background:linear-gradient(135deg,#f59e0b,#ef4444,#ec4899)}.card-gradient-forest{background:linear-gradient(135deg,#10b981,#0d9488)}.card-gradient-rose{background:linear-gradient(135deg,#fb7185,#e11d48)}.card-gradient-midnight{background:linear-gradient(135deg,#1e1b4b,#4338ca)}.card-gradient-aurora{background:linear-gradient(135deg,#06b6d4,#6366f1,#a855f7)}.card-gradient-fire{background:linear-gradient(135deg,#ef4444,#f97316,#fbbf24)}.card-gradient-lagoon{background:linear-gradient(135deg,#06b6d4,#0e7490)}.card-gradient-dusk{background:linear-gradient(135deg,#7c3aed,#db2777)}.card-gradient-lime{background:linear-gradient(135deg,#84cc16,#10b981)}.card-gradient-gold{background:linear-gradient(135deg,#f59e0b,#b45309)}.card-gradient-arctic{background:linear-gradient(135deg,#bae6fd,#e0f2fe);color:#1e293b}.card-gradient-slate{background:linear-gradient(135deg,#475569,#1e293b)}[class*=card-gradient-]:not(.card-gradient-arctic){color:#fff}.page-body .card-font-serif{font-family:Georgia,Times New Roman,serif}.page-body .card-font-mono{font-family:SF Mono,Fira Code,Courier New,monospace}.page-body .card-text-sm{font-size:.85rem}.page-body .card-text-lg{font-size:1.1rem}.page-body .card-text-xl{font-size:1.25rem}.page-body .card-borderless{border:none!important}.page-body .card-shadow-none{box-shadow:none!important}.page-body .card-shadow-md{box-shadow:0 4px 12px #0000001a}.page-body .card-shadow-lg{box-shadow:0 10px 30px #0000002e}.page-body .card-rounded-none{border-radius:0}.page-body .card-rounded-sm{border-radius:4px}.page-body .card-rounded-lg{border-radius:20px}.page-body .card-rounded-full{border-radius:9999px}.page-body .card-align-center{text-align:center}.page-body .card-align-right{text-align:right}.page-body .card-pad-compact .card-body,.page-body .card-pad-compact .card-header,.page-body .card-pad-compact .card-footer{padding:8px 12px}.page-body .card-pad-spacious .card-body,.page-body .card-pad-spacious .card-header,.page-body .card-pad-spacious .card-footer{padding:24px 28px}.card-img-top{width:100%;height:180px;background-size:cover;background-position:center;background-color:var(--dm-border,#e2e8f0);display:flex;align-items:center;justify-content:center;font-size:2.5rem;color:color-mix(in srgb,var(--dm-text) 15%,transparent)}.card-img-left,.card-img-right{width:90px;flex-shrink:0;background-size:cover;background-position:center;background-color:var(--dm-border,#e2e8f0);display:flex;align-items:center;justify-content:center;font-size:1.75rem;color:color-mix(in srgb,var(--dm-text) 20%,transparent)}.card-img-wide{width:130px;flex-shrink:0;background-size:cover;background-position:center;background-color:var(--dm-border,#e2e8f0);display:flex;align-items:center;justify-content:center;font-size:2rem;color:color-mix(in srgb,var(--dm-text) 20%,transparent)}.card-layout-horizontal,.card-layout-thumb-left,.card-layout-thumb-right{display:flex}.card-layout-thumb-left .card-body,.card-layout-thumb-right .card-body,.card-layout-horizontal .card-body{flex:1;min-width:0}.card-layout-split{display:flex;min-height:140px}.card-split-left{width:50%;display:flex;align-items:center;justify-content:center;font-size:2.25rem;flex-shrink:0;background:linear-gradient(160deg,#6366f1,#8b5cf6)}.card-split-right{flex:1;background:#1e293b;display:flex;flex-direction:column;justify-content:center}.card-split-right .card-body{color:#94a3b8}.card-split-right .card-title{color:#f1f5f9}.card-img-overlay{position:relative;height:180px;overflow:hidden;background-size:cover;background-position:center;background-color:#1e293b;display:flex;align-items:flex-end}.card-overlay-text{width:100%;padding:40px 16px 14px;background:linear-gradient(to top,rgba(0,0,0,.75),transparent)}.card-overlay-text .card-title{color:#fff}.dm-card-dark .card-img-top,.dm-card-dark .card-img-left,.dm-card-dark .card-img-right,.dm-card-dark .card-img-wide{filter:brightness(.7)}.card-stat-value{font-size:2.4rem;font-weight:800;color:var(--dm-text);line-height:1.1}.card-stat-delta{font-size:.8rem;font-weight:600;margin-top:2px}.card-stat-delta.positive{color:var(--dm-success, #10b981)}.card-stat-delta.negative{color:var(--dm-danger, #ef4444)}.card-stat-bar{height:5px;background:var(--dm-border);border-radius:3px;margin-top:14px;overflow:hidden}.card-stat-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,#6366f1,#8b5cf6)}.card-progress-bar{height:8px;background:var(--dm-border);border-radius:4px;overflow:hidden;margin:8px 0}.card-progress-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,#6366f1,#8b5cf6)}.card-milestone{display:flex;align-items:center;gap:8px;font-size:.8rem;color:var(--dm-text-secondary);padding:3px 0}.card-milestone-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.card-milestone-dot.done{background:var(--dm-success, #10b981)}.card-milestone-dot.pending{background:var(--dm-border, #e5e7eb)}.card-header-icon-stacked{text-align:center;padding:20px 16px 12px}.card-header-icon-stacked [data-icon],.card-header-icon-stacked .card-icon{font-size:2rem;display:block;margin-bottom:8px}.card-step-bg{position:relative;overflow:hidden;min-height:60px;display:flex;align-items:center;padding:14px 16px}.card-step-ghost{position:absolute;right:8px;top:-10px;font-size:5rem;font-weight:900;color:color-mix(in srgb,var(--dm-primary, #6366f1) 12%,transparent);line-height:1;pointer-events:none}.card-step-badge{width:32px;height:32px;border-radius:50%;background:var(--dm-primary, #6366f1);color:var(--dm-primary-text, #fff);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.85rem;z-index:1;flex-shrink:0}.card-corner-badge-wrap{position:relative}.card-corner-badge{position:absolute;top:10px;right:10px;background:var(--dm-danger, #ef4444);color:#fff;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;padding:2px 8px;border-radius:20px}.card-callout{border-left:4px solid var(--dm-primary, #6366f1)}.card-callout.warn{border-left-color:var(--dm-warning, #f59e0b)}.card-callout.success{border-left-color:var(--dm-success, #10b981)}.card-callout.error{border-left-color:var(--dm-danger, #ef4444)}.card-callout-inner{display:flex;gap:12px;align-items:flex-start}.card-callout-icon{font-size:1.2rem;flex-shrink:0;margin-top:1px}.card-quote-mark{font-size:3.5rem;color:color-mix(in srgb,var(--dm-primary, #6366f1) 18%,transparent);line-height:.8;padding:14px 16px 0;font-family:Georgia,serif;display:block}.card-quote-text{padding:4px 16px 14px;font-style:italic;color:var(--dm-text-secondary);line-height:1.7}.card-quote-attr{display:flex;align-items:center;gap:10px}.card-quote-avatar{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:.85rem;color:#fff;flex-shrink:0}.card-video-thumb{position:relative;height:160px;background:#1e293b;display:flex;align-items:center;justify-content:center;background-size:cover;background-position:center}.card-play-btn{width:52px;height:52px;border-radius:50%;background:#ffffffe6;display:flex;align-items:center;justify-content:center;font-size:1.2rem;box-shadow:0 4px 16px #0000004d}.card-video-duration{position:absolute;bottom:8px;right:10px;background:#000000b3;color:#fff;font-size:.65rem;font-weight:600;padding:2px 7px;border-radius:4px}.card-map-placeholder{height:130px;background:linear-gradient(160deg,#bfdbfe,#dbeafe);position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden}.card-map-grid{position:absolute;inset:0;background-image:repeating-linear-gradient(0deg,rgba(59,130,246,.08) 0,rgba(59,130,246,.08) 1px,transparent 1px,transparent 32px),repeating-linear-gradient(90deg,rgba(59,130,246,.08) 0,rgba(59,130,246,.08) 1px,transparent 1px,transparent 32px)}.card-map-pin{font-size:2rem;z-index:1}.card-avatar{width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:1.8rem;color:#fff;margin:0 auto 12px}.card-avatar-wrap{text-align:center;padding:24px 16px 16px}.card-tag-pills{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-top:10px}.card-pill{background:color-mix(in srgb,var(--dm-primary, #7c3aed) 15%,transparent);color:var(--dm-primary, #7c3aed);font-size:.7rem;font-weight:700;padding:3px 9px;border-radius:20px}.card-tag-cloud{padding:14px 16px;display:flex;flex-wrap:wrap;gap:7px}.card-tag{padding:4px 11px;border-radius:20px;font-size:.78rem;font-weight:600}.card-file-row{display:flex;gap:14px;align-items:center;padding:16px}.card-file-icon{width:48px;height:58px;border-radius:7px;background:linear-gradient(160deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:1.4rem;color:#fff;flex-shrink:0;position:relative}.card-file-ext{position:absolute;bottom:4px;left:0;right:0;text-align:center;font-size:.55rem;font-weight:800;color:#ffffffe6;letter-spacing:.05em}.card-file-dl{font-size:.78rem;font-weight:700;color:var(--dm-primary, #6366f1);display:inline-block;margin-top:4px}.card-stars{color:#f59e0b;letter-spacing:2px;padding:14px 16px 0;display:block}.card-verified{display:inline-block;background:color-mix(in srgb,var(--dm-success, #10b981) 18%,transparent);color:var(--dm-success, #065f46);font-size:.6rem;font-weight:700;padding:1px 5px;border-radius:3px;margin-left:6px}.card-activity-item{display:flex;gap:10px;align-items:flex-start;padding:8px 14px;border-bottom:1px solid var(--dm-border)}.card-activity-item:last-child{border-bottom:none}.card-activity-avatar{width:30px;height:30px;border-radius:50%;flex-shrink:0;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:.8rem;color:#fff}.card-compare-grid{display:grid;grid-template-columns:1fr 1fr}.card-compare-col{padding:12px 14px}.card-compare-col+.card-compare-col{border-left:1px solid var(--dm-border)}.card-compare-label{font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;margin-bottom:8px;display:block}.card-compare-label.before{color:var(--dm-danger, #ef4444)}.card-compare-label.after{color:var(--dm-success, #10b981)}.card-compare-item{display:flex;gap:7px;align-items:flex-start;font-size:.78rem;color:var(--dm-text-secondary);padding:3px 0;line-height:1.4}.card-compare-x{color:var(--dm-danger, #ef4444);flex-shrink:0}.card-compare-check{color:var(--dm-success, #10b981);flex-shrink:0}.card-pricing-features{padding:14px 16px}.card-pricing-feature{display:flex;align-items:center;gap:8px;font-size:.82rem;color:var(--dm-text-secondary);padding:4px 0}.card-pricing-check{color:var(--dm-success, #10b981)}.card-pricing-cta{display:block;text-align:center;background:var(--dm-primary, #6366f1);color:var(--dm-primary-text, #fff);font-size:.82rem;font-weight:700;padding:9px;border-radius:8px;text-decoration:none;margin:0 16px 14px}.card-timeline-row{display:flex}.card-timeline-side{width:44px;flex-shrink:0;display:flex;flex-direction:column;align-items:center;padding-top:14px}.card-timeline-dot{width:12px;height:12px;border-radius:50%;background:var(--dm-primary, #6366f1);flex-shrink:0}.card-timeline-line{width:2px;background:var(--dm-border, #e5e7eb);flex:1;margin-top:4px}.card-timeline-body{flex:1;padding:12px 14px 12px 0}.card-timeline-date{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--dm-text-muted)}.card-timeline-tag{display:inline-block;background:color-mix(in srgb,var(--dm-success, #10b981) 18%,transparent);color:var(--dm-success, #065f46);font-size:.65rem;font-weight:700;padding:2px 6px;border-radius:4px;margin-top:6px}.card-code-header{background:#1e293b;display:flex;justify-content:space-between;align-items:center;padding:8px 14px}.card-code-lang{font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:#6366f1}.card-code-body{background:#0f172a;padding:14px;font-family:Courier New,monospace;font-size:.78rem;line-height:1.8;color:#94a3b8;overflow-x:auto}.card-glass-outer{background:linear-gradient(135deg,#6366f1,#8b5cf6,#ec4899);border-radius:12px;padding:2px}.card-glass-inner{background:#ffffffeb;backdrop-filter:blur(10px);border-radius:10px;padding:16px}.card-badge-band{display:flex;align-items:center;justify-content:space-between;padding:12px 16px}.card-badge-band-label{background:#fff3;color:#fff;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;padding:3px 8px;border-radius:4px}.card-badge-band-icon{font-size:1.4rem}.dm-card-full-bg{background:linear-gradient(160deg,#1e293b,#0f172a);color:#cbd5e1}.dm-card-full-bg .card-body{color:#94a3b8}.dm-card-full-bg .card-title{color:#f1f5f9;font-size:1rem}.dm-card-full-bg .card-footer{border-top-color:#ffffff14;color:#64748b}.card-fc-row{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;border-bottom:1px solid var(--dm-border);font-size:.82rem;color:var(--dm-text-secondary)}.card-fc-row:last-child{border-bottom:none}.card-fc-yes{color:var(--dm-success, #10b981)}.card-fc-no{color:var(--dm-text-disabled, #d1d5db)}@media(max-width:480px){.card-layout-thumb-left,.card-layout-thumb-right,.card-layout-horizontal{flex-direction:column}.card-img-left,.card-img-right,.card-img-wide{width:100%;height:120px}.card-layout-split{flex-direction:column}.card-split-left{width:100%;height:100px}}.hero.hero-dark{background:linear-gradient(135deg,#1f2937,#111827);color:#e2e8f0}.hero .hero-content{position:relative;z-index:2}.hero.hero-left .hero-content{text-align:left;align-items:flex-start;max-width:62%}@media(max-width:768px){.hero.hero-left .hero-content{max-width:100%}}.hero .hero-cta{display:flex;gap:.85rem;flex-wrap:wrap;margin-top:1.75rem}.hero .hero-cta a{display:inline-flex;align-items:center;gap:.4rem;padding:.55rem 1.35rem;border-radius:6px;font-size:.95rem;font-weight:500;text-decoration:none;transition:background .2s ease,border-color .2s ease,transform .15s ease,box-shadow .2s ease}.hero .hero-cta a:first-child{background:#ffffffeb;color:#111;border:1px solid transparent}.hero .hero-cta a:first-child:hover{background:#fff;box-shadow:0 4px 16px #00000040;transform:translateY(-2px)}.hero .hero-cta a:last-child{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4)}.hero .hero-cta a:last-child:hover{border-color:#ffffffbf;background:#ffffff14;transform:translateY(-2px)}.hero .hero-label{display:inline-block;margin-bottom:.9rem;padding:.2rem .8rem;border-radius:999px;font-size:.72rem;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:#ffffffb3;border:1px solid rgba(255,255,255,.22)}.grid-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.dm-breadcrumbs{position:fixed;z-index:200;display:inline-flex;align-items:center;gap:.2rem;padding:.3rem .8rem;border-radius:999px;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);background:#00000047;border:1px solid rgba(255,255,255,.11);box-shadow:0 2px 10px #00000038;font-size:.72rem;font-weight:500;letter-spacing:.01em;line-height:1.4;max-width:calc(100vw - 2rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-breadcrumbs .dm-breadcrumbs-item{color:#ffffffa6}.dm-breadcrumbs .dm-breadcrumbs-link{display:inline-flex;align-items:center;gap:.25rem;color:#ffffff8c;text-decoration:none;transition:color .15s}.dm-breadcrumbs .dm-breadcrumbs-home-icon{flex-shrink:0;vertical-align:middle}.dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#fffffff2}.dm-breadcrumbs .dm-breadcrumbs-current{color:#ffffffeb;font-weight:600}.dm-breadcrumbs .dm-breadcrumbs-separator{color:#ffffff47;font-size:.8em;line-height:1;margin:0 .05rem}body[class*=-light] .dm-breadcrumbs{background:#ffffff8c;border-color:#00000012;box-shadow:0 2px 10px #00000014}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-item,body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-link{color:#0000008c}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#000000e6}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-current{color:#000000d9}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-separator{color:#00000040}.dm-collection-display{margin:1.5rem 0}.dm-collection-list{display:flex;flex-direction:column;gap:0}.dm-collection-list-item{padding:1rem 0;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .08))}.dm-collection-list-item:last-child{border-bottom:none}.dm-collection-list-item strong{display:block;font-size:1rem;margin-bottom:.25rem}.dm-collection-list-item p{margin:0;color:var(--dm-text-muted, #888);font-size:.9rem}.dm-collection-empty p{color:var(--dm-text-muted, #888);font-style:italic}.hero-gradient-purple,.hero-gradient-blue,.hero-gradient-green,.hero-gradient-sunset,.hero-gradient-ocean,.hero-gradient-rose,.hero-gradient-forest{background:linear-gradient(135deg,color-mix(in srgb,var(--hero-hue) 22%,var(--dm-background)),color-mix(in srgb,var(--hero-hue) 10%,var(--dm-background)));color:var(--dm-text)}.hero-gradient-purple{--hero-hue: #8b5cf6}.hero-gradient-blue{--hero-hue: #3b82f6}.hero-gradient-green{--hero-hue: #10b981}.hero-gradient-sunset{--hero-hue: #f59e0b}.hero-gradient-ocean{--hero-hue: #0ea5e9}.hero-gradient-rose{--hero-hue: #ec4899}.hero-gradient-forest{--hero-hue: #16a34a}.hero-gradient-night{background:linear-gradient(135deg,#334155,#1e293b);color:#e2e8f0}.hero-gradient-ocean-light{background:linear-gradient(135deg,#e0f2fe,#caf0f8);color:#1e293b}.hero-gradient-ocean-dark{background:linear-gradient(135deg,#0c4a6e,#164e63);color:#e2e8f0}.hero-gradient-forest-light{background:linear-gradient(135deg,#d1fae5,#c6f6dc);color:#1e293b}.hero-gradient-forest-dark{background:linear-gradient(135deg,#1a4731,#166534);color:#e2e8f0}.hero-gradient-sunset-light{background:linear-gradient(135deg,#fde8d8,#fddcc9);color:#1e293b}.hero-gradient-sunset-dark{background:linear-gradient(135deg,#6b3727,#7c4036);color:#f5ede8}.hero-gradient-royal-light{background:linear-gradient(135deg,#e8f0fd,#dce8fc);color:#1e293b}.hero-gradient-royal-dark{background:linear-gradient(135deg,#1e3465,#263d7a);color:#e2e8f0}.hero-gradient-lemon-light{background:linear-gradient(135deg,#fefce8,#fef9c3);color:#1e293b}.hero-gradient-lemon-dark{background:linear-gradient(135deg,#5c4d1a,#6b5920);color:#fefce8}.hero-gradient-silver-light{background:linear-gradient(135deg,#f1f5f9,#e2e8f0);color:#1e293b}.hero-gradient-silver-dark{background:linear-gradient(135deg,#2d3748,#374151);color:#e2e8f0}.hero-gradient-charcoal-light{background:linear-gradient(135deg,#eceff1,#e1e7eb);color:#1e293b}.hero-gradient-charcoal-dark{background:linear-gradient(135deg,#2c3843,#374451);color:#e2e8f0}.hero-gradient-christmas-light{background:linear-gradient(135deg,#fde8ea,#fdd5d8);color:#1e293b}.hero-gradient-christmas-dark{background:linear-gradient(135deg,#5c0f1d,#7a1525);color:#fde8ea}.hero-gradient-unicorn-light{background:linear-gradient(135deg,#f5e8fd,#edd6fb);color:#1e293b}.hero-gradient-unicorn-dark{background:linear-gradient(135deg,#3d1a5a,#4a2068);color:#f5e8fd}.hero-gradient-dreamy-light{background:linear-gradient(135deg,#f5ede8,#eeddd4);color:#1e293b}.hero-gradient-dreamy-dark{background:linear-gradient(135deg,#3d2820,#503328);color:#f5ede8}.hero-gradient-grayve-light{background:linear-gradient(135deg,#e0f7f9,#cbf2f5);color:#1e293b}.hero-gradient-grayve-dark{background:linear-gradient(135deg,#00363d,#00444d);color:#e0f7f9}.hero-gradient-mint-light{background:linear-gradient(135deg,#d8f5ea,#c5efdd);color:#1e293b}.hero-gradient-mint-dark{background:linear-gradient(135deg,#134d33,#195f3f);color:#d8f5ea}.hero-gradient-wedding-light{background:linear-gradient(135deg,#faf3e0,#f5e9c7);color:#1e293b}.hero-gradient-wedding-dark{background:linear-gradient(135deg,#5c4418,#6f5320);color:#faf3e0}.tabs-centered{text-align:center}.tabs-centered .tab-list{display:inline-flex}.tabs-centered .tab-content{text-align:left}.site-main{overflow-x:hidden}@media(max-width:768px){.hero .hero-cta a,.dm-so-trigger,.dm-cta-trigger{min-height:44px;padding:.6rem 1.25rem}}.dm-banner{position:relative;display:flex;flex-direction:row;align-items:flex-start;gap:.75rem;padding:.85rem 2.5rem .85rem 1rem;border-radius:var(--dm-radius-md, 6px);border-left:4px solid transparent;margin-bottom:1rem}.dm-banner__icon{flex-shrink:0;margin-top:.1rem;width:1.15rem;height:1.15rem}.dm-banner__icon svg{width:1.15rem;height:1.15rem}.dm-banner__body{flex:1;min-width:0}.dm-banner__title{display:block;margin-bottom:.2rem;font-size:.9em;font-weight:600}.dm-banner__dismiss{position:absolute;top:.5rem;right:.5rem;background:transparent;border:none;cursor:pointer;font-size:1.1rem;line-height:1;padding:.1rem .3rem;opacity:.6}.dm-banner__dismiss:hover{opacity:1}.dm-banner--info{background:color-mix(in srgb,var(--dm-info, #3b82f6) 12%,transparent);border-left-color:var(--dm-info, #3b82f6);color:inherit}.dm-banner--success{background:color-mix(in srgb,var(--dm-success, #22c55e) 12%,transparent);border-left-color:var(--dm-success, #22c55e);color:inherit}.dm-banner--warning{background:color-mix(in srgb,var(--dm-warning, #f59e0b) 12%,transparent);border-left-color:var(--dm-warning, #f59e0b);color:inherit}.dm-banner--danger{background:color-mix(in srgb,var(--dm-danger, #ef4444) 12%,transparent);border-left-color:var(--dm-danger, #ef4444);color:inherit}.dm-banner--neutral{background:color-mix(in srgb,var(--dm-text-muted, #888) 12%,transparent);border-left-color:var(--dm-text-muted, #888);color:inherit}body.dm-layout-narrow .page-body{max-width:768px;margin-inline:auto}body.dm-layout-normal .page-body{max-width:1100px;margin-inline:auto}body.dm-layout-wide .page-body{max-width:min(75vw,2000px);margin-inline:auto}body.dm-layout-full .page-body{max-width:none}.hero h1{font-size:clamp(2.4rem,4.5vw,3.75rem);font-weight:900;line-height:1.08;letter-spacing:-.03em}.hero-gradient-dreamy-light h1{color:#1e293b}.hero-gradient-dreamy-light p{font-size:1.125rem;line-height:1.7;color:#1e293bcc;max-width:48ch}.page-body h2{font-weight:800;letter-spacing:-.025em}.page-body h3{font-weight:700;letter-spacing:-.015em}.hero-gradient-dreamy-light .hero-cta a:first-child{background:#1e293b!important;color:#f5ede8!important;border-color:#1e293b!important}.hero-gradient-dreamy-light .hero-cta a:first-child:hover{background:#0f172a!important;color:#fff!important}.hero-gradient-dreamy-light .hero-cta a:last-child{background:transparent!important;color:#1e293b!important;border:1px solid rgba(30,41,59,.45)!important}.hero-gradient-dreamy-light .hero-cta a:last-child:hover{background:#1e293b14!important;border-color:#1e293bb3!important}.card[data-hover=true]{transition:transform .22s ease,box-shadow .22s ease!important;will-change:transform}.card[data-hover=true]:hover{transform:translateY(-5px)!important;box-shadow:0 24px 64px #0003,0 8px 24px #0000001f!important}.card-icon{font-size:2.5rem!important;margin-bottom:12px!important;opacity:.95}.card-avatar-wrap{padding:20px 16px 12px!important;gap:.5rem}.mk-card-icon-wrap,.card-icon-wrap{width:3rem;height:3rem;border-radius:.75rem;background:#ffffff2e;display:flex;align-items:center;justify-content:center;margin-bottom:1.125rem;font-size:1.3rem;flex-shrink:0;box-shadow:0 2px 8px #0000001f}.mk-card-corner-badge,.card-corner-badge{position:absolute;top:1rem;right:1rem;background:linear-gradient(135deg,#f59e0b,#d97706);color:#fff;font-size:.6875rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;padding:.25rem .7rem;border-radius:99px;box-shadow:0 2px 10px #f59e0b73}.card-premium .card-subtitle{display:inline-block!important;font-size:.6875rem!important;font-weight:700!important;letter-spacing:.07em!important;text-transform:uppercase!important;opacity:1!important;color:#fff!important;background:linear-gradient(135deg,#f59e0b,#d97706)!important;padding:.2rem .65rem!important;border-radius:99px!important;box-shadow:0 2px 8px #f59e0b66!important;margin-bottom:.75rem!important}.mk-card-badge-band,.card-badge-band{display:inline-flex;align-items:center;gap:.35rem;font-size:.6875rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;padding:.2rem .6rem;border-radius:99px;margin-bottom:.875rem;background:#fff3;border:1px solid rgba(255,255,255,.3)}.mk-card-stars,.card-stars{color:#f59e0b;font-size:1rem;letter-spacing:.12em;margin-bottom:.75rem}.mk-card-reviewer,.card-reviewer{display:flex;flex-direction:column;gap:.15rem;margin-top:1rem;padding-top:1rem;border-top:1px solid rgba(255,255,255,.15)}.mk-card-reviewer-name,.card-reviewer-name{font-weight:700;font-size:.9375rem}.mk-card-reviewer-role,.card-reviewer-role{font-size:.8125rem;opacity:.65}.mk-banner.type-info,[class*=banner-info],.mk-banner[data-type=info]{border-left:4px solid var(--dm-primary, #5c3d2e)}.mk-banner.type-success,[class*=banner-success],.mk-banner[data-type=success]{border-left:4px solid var(--dm-success, #22c55e)}.mk-banner.type-warning,[class*=banner-warning],.mk-banner[data-type=warning]{border-left:4px solid var(--dm-warning, #f59e0b)}.mk-stat-number{font-size:5rem;font-weight:900;line-height:1;letter-spacing:-.03em;color:var(--dm-primary, #5c3d2e)}.mk-stat-label{font-size:.9375rem;font-weight:600;opacity:.65;margin-top:.5rem;letter-spacing:.02em;text-transform:uppercase}.mk-footer-inner{max-width:1200px;margin:0 auto;padding:3rem 2rem 1.5rem}.mk-footer-columns{display:grid;grid-template-columns:repeat(4,1fr);gap:2rem;margin-bottom:2.5rem}@media(max-width:900px){.mk-footer-columns{grid-template-columns:repeat(2,1fr)}}@media(max-width:480px){.mk-footer-columns{grid-template-columns:1fr}}.mk-footer-col-title{font-size:.75rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;opacity:.5;margin:0 0 .75rem}.mk-footer-col-links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}.mk-footer-col-links a{font-size:.875rem;opacity:.75;text-decoration:none;transition:opacity .15s}.mk-footer-col-links a:hover{opacity:1}.mk-footer-bottom{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;padding-top:1.5rem;border-top:1px solid var(--dm-border, rgba(0, 0, 0, .08))}.mk-footer-copyright{font-size:.8125rem;opacity:.5;margin:0}.mk-footer-bottom-right{display:flex;align-items:center;gap:1.25rem}.mk-footer-social{display:flex;gap:.75rem}.mk-footer-social-link{opacity:.5;transition:opacity .15s;font-size:1.125rem}.mk-footer-social-link:hover{opacity:1}.mk-motion-label{display:flex;align-items:center;gap:.4rem;font-size:.75rem;opacity:.5;cursor:pointer;user-select:none}.mk-motion-label:hover{opacity:.75}.dm-static-block{display:contents}.mk-window{border-radius:10px;overflow:hidden;box-shadow:0 16px 56px #0000002e,0 4px 16px #0000001a;background:#fff;border:1px solid rgba(0,0,0,.06)}.mk-window-bar{background:#e8e8e8;padding:10px 16px;display:flex;gap:7px;align-items:center}.mk-dot{width:12px;height:12px;border-radius:50%;flex-shrink:0}.mk-dot-red{background:#ff5f57}.mk-dot-amber{background:#febc2e}.mk-dot-green{background:#28c840}.mk-window-body img{width:100%;display:block;max-height:480px;object-fit:cover;object-position:top}.dm-static-block+p{margin-top:.5rem}.navbar-link.active{opacity:1!important;font-weight:700!important;position:relative}.navbar-link.active:after{content:"";position:absolute;bottom:-3px;left:0;right:0;height:2px;background:currentColor;border-radius:2px;opacity:.6}.mk-divider{border:none;border-top:1px solid var(--dm-border-light, rgba(0, 0, 0, .07));margin:0}.page-body .mk-tabs,.page-body .tabs-wrapper,.page-body>.tabs{padding-left:1.5rem;padding-right:1.5rem}.mk-section-label,.section-label{display:inline-block;font-size:.75rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:.3rem .875rem;border-radius:99px;margin-bottom:1.125rem;background:color-mix(in srgb,var(--dm-primary, #5c3d2e) 10%,transparent);color:var(--dm-primary, #5c3d2e);border:1px solid color-mix(in srgb,var(--dm-primary, #5c3d2e) 20%,transparent)}.page-body .btn-primary,.page-body a.btn-primary{background-color:var(--dm-primary, #8d6e63)!important;color:var(--dm-text-inverse, #ffffff)!important;border:1px solid var(--dm-primary, #8d6e63)!important;text-decoration:none!important;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.page-body .btn-primary:hover,.page-body a.btn-primary:hover{background-color:var(--dm-primary-hover, #6d4c41)!important;color:var(--dm-text-inverse, #ffffff)!important;border-color:var(--dm-primary-hover, #6d4c41)!important;text-decoration:none!important}.page-body .btn-outline,.page-body a.btn-outline{background-color:transparent!important;color:var(--dm-primary, #8d6e63)!important;border:1.5px solid var(--dm-primary, #8d6e63)!important;text-decoration:none!important;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.page-body .btn-outline:hover,.page-body a.btn-outline:hover{background-color:var(--dm-primary, #8d6e63)!important;color:var(--dm-text-inverse, #ffffff)!important;border-color:var(--dm-primary, #8d6e63)!important;text-decoration:none!important}.page-body .btn-ghost,.page-body a.btn-ghost{background-color:transparent!important;color:var(--dm-primary, #8d6e63)!important;border:1px solid transparent!important;text-decoration:none!important;transition:background-color .15s ease,color .15s ease}.page-body .btn-ghost:hover,.page-body a.btn-ghost:hover{background-color:var(--dm-primary-light, rgba(141, 110, 99, .1))!important;color:var(--dm-primary-hover, #6d4c41)!important;text-decoration:none!important}.mk-card-step-number,.card-step-number{font-size:3rem;font-weight:900;line-height:1;letter-spacing:-.04em;opacity:.25;margin-bottom:.75rem}.mk-card-step-title,.card-step-title{font-size:1rem;font-weight:700;margin-bottom:.5rem}.card[data-badge=Enterprise] .mk-card-corner-badge,.card[data-badge=Enterprise] .card-corner-badge{background:linear-gradient(135deg,#1e293b,#334155);box-shadow:0 2px 10px #1e293b80}.card-badge-band-icon{font-size:1.75rem!important}.card-badge-band{padding:14px 18px!important;gap:.5rem}.card-badge-band-label{font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}.card-title{font-size:1.2rem!important;font-weight:800!important;letter-spacing:-.015em!important;line-height:1.25!important;margin-bottom:.4rem!important;color:var(--dm-text, #f1f5f9)!important}.card-subtitle{font-size:.8125rem!important;opacity:.7!important;margin-bottom:.5rem!important;font-weight:500!important;color:var(--dm-text, #f1f5f9)!important}.mk-card-body p,.card-body p,.card>p{font-size:.9375rem;line-height:1.65;opacity:.88}.card-gradient-purple{background:linear-gradient(135deg,#ede9fe,#ddd6fe)!important;color:#1e1b4b!important}.card-gradient-blue{background:linear-gradient(135deg,#dbeafe,#bfdbfe)!important;color:#1e3a5f!important}.card-gradient-green{background:linear-gradient(135deg,#d1fae5,#a7f3d0)!important;color:#064e3b!important}.card-gradient-night{background:linear-gradient(135deg,#334155,#1e293b)!important;color:#e2e8f0!important}.card-gradient-ocean-light{background:linear-gradient(135deg,#e0f2fe,#caf0f8)!important;color:#1e293b!important}.card-gradient-ocean-dark{background:linear-gradient(135deg,#0c4a6e,#164e63)!important;color:#e2e8f0!important}.card-gradient-forest-light{background:linear-gradient(135deg,#d1fae5,#c6f6dc)!important;color:#1e293b!important}.card-gradient-forest-dark{background:linear-gradient(135deg,#1a4731,#166534)!important;color:#e2e8f0!important}.card-gradient-sunset-light{background:linear-gradient(135deg,#fde8d8,#fddcc9)!important;color:#1e293b!important}.card-gradient-sunset-dark{background:linear-gradient(135deg,#6b3727,#7c4036)!important;color:#f5ede8!important}.card-gradient-royal-light{background:linear-gradient(135deg,#e8f0fd,#dce8fc)!important;color:#1e293b!important}.card-gradient-royal-dark{background:linear-gradient(135deg,#1e3465,#263d7a)!important;color:#e2e8f0!important}.card-gradient-lemon-light{background:linear-gradient(135deg,#fefce8,#fef9c3)!important;color:#1e293b!important}.card-gradient-lemon-dark{background:linear-gradient(135deg,#5c4d1a,#6b5920)!important;color:#fefce8!important}.card-gradient-silver-light{background:linear-gradient(135deg,#f1f5f9,#e2e8f0)!important;color:#1e293b!important}.card-gradient-silver-dark{background:linear-gradient(135deg,#2d3748,#374151)!important;color:#e2e8f0!important}.card-gradient-charcoal-light{background:linear-gradient(135deg,#eceff1,#e1e7eb)!important;color:#1e293b!important}.card-gradient-charcoal-dark{background:linear-gradient(135deg,#2c3843,#374451)!important;color:#e2e8f0!important}.card-gradient-christmas-light{background:linear-gradient(135deg,#fde8ea,#fdd5d8)!important;color:#1e293b!important}.card-gradient-christmas-dark{background:linear-gradient(135deg,#5c0f1d,#7a1525)!important;color:#fde8ea!important}.card-gradient-unicorn-light{background:linear-gradient(135deg,#f5e8fd,#edd6fb)!important;color:#1e293b!important}.card-gradient-unicorn-dark{background:linear-gradient(135deg,#3d1a5a,#4a2068)!important;color:#f5e8fd!important}.card-gradient-dreamy-light{background:linear-gradient(135deg,#f5ede8,#eeddd4)!important;color:#1e293b!important}.card-gradient-dreamy-dark{background:linear-gradient(135deg,#3d2820,#503328)!important;color:#f5ede8!important}.card-gradient-grayve-light{background:linear-gradient(135deg,#e0f7f9,#cbf2f5)!important;color:#1e293b!important}.card-gradient-grayve-dark{background:linear-gradient(135deg,#00363d,#00444d)!important;color:#e0f7f9!important}.card-gradient-mint-light{background:linear-gradient(135deg,#d8f5ea,#c5efdd)!important;color:#1e293b!important}.card-gradient-mint-dark{background:linear-gradient(135deg,#134d33,#195f3f)!important;color:#d8f5ea!important}.card-gradient-wedding-light{background:linear-gradient(135deg,#faf3e0,#f5e9c7)!important;color:#1e293b!important}.card-gradient-wedding-dark{background:linear-gradient(135deg,#5c4418,#6f5320)!important;color:#faf3e0!important}.card-gradient-slate{--dm-card-g-start: #475569;--dm-card-g-end: #1e293b}.card-gradient-dusk{--dm-card-g-start: #7c3aed;--dm-card-g-end: #db2777}.card-gradient-sunset{--dm-card-g-start: #f59e0b;--dm-card-g-end: #ec4899}.card-gradient-rose{--dm-card-g-start: #fb7185;--dm-card-g-end: #e11d48}.card-gradient-gold{--dm-card-g-start: #f59e0b;--dm-card-g-end: #b45309}.card-gradient-fire{--dm-card-g-start: #ef4444;--dm-card-g-end: #fbbf24}.page-body .card.dm-card-gradient.card-gradient-sunset .card-header,.page-body .card.dm-card-gradient.card-gradient-rose .card-header,.page-body .card.dm-card-gradient.card-gradient-gold .card-header,.page-body .card.dm-card-gradient.card-gradient-fire .card-header{color:#1e293b!important}.page-body .card.dm-card-gradient[class*=-light] .card-header,.page-body .card.dm-card-gradient[class*=-dark] .card-header,.page-body .card.dm-card-gradient.card-gradient-purple .card-header,.page-body .card.dm-card-gradient.card-gradient-blue .card-header,.page-body .card.dm-card-gradient.card-gradient-green .card-header,.page-body .card.dm-card-gradient.card-gradient-night .card-header{background:transparent!important;color:inherit!important;border-bottom:1px solid rgba(0,0,0,.08)}.card[class*=card-gradient-] .card-title,.card[class*=card-gradient-] .card-subtitle{color:inherit!important}.card[class*=gradient] .mk-window-bar,.card[data-gradient] .mk-window-bar{background:#00000040}.card[class*=gradient] .mk-dot-red{background:#ff5f57b3}.card[class*=gradient] .mk-dot-amber{background:#febc2eb3}.card[class*=gradient] .mk-dot-green{background:#28c840b3}.hero .card .mk-listgroup-item,.hero .card .list-group-item{padding-top:.45rem;padding-bottom:.45rem;font-size:.9rem}.card .dm-static-block{display:block;width:100%}.card .mk-window{margin-bottom:0}.wf-feature{display:flex;align-items:center;gap:14px;padding:14px 16px;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:8px;box-shadow:0 1px 3px #0f172a0a;transition:border-color .15s ease,box-shadow .15s ease,transform .15s ease}.wf-feature:hover{border-color:var(--dm-border-dark, #475569);box-shadow:0 6px 18px #0f172a14;transform:translateY(-1px)}.wf-feature-icon{flex-shrink:0;width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:8px;font-size:1.1rem}.wf-feature-text{font-size:.9rem;font-weight:500;color:var(--dm-text, #1e293b);line-height:1.4;flex:1 1 auto}.plugin-card{display:flex;flex-direction:column;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:12px;overflow:hidden;box-shadow:0 2px 6px #0f172a0d;text-decoration:none!important;color:inherit!important;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;height:100%;min-height:340px}.plugin-card:hover{transform:translateY(-3px);box-shadow:0 18px 40px #0f172a1f;border-color:var(--dm-border-dark, #475569)}.plugin-card-cover{position:relative;width:100%;height:150px;background-size:cover;background-position:center;background-color:var(--dm-background-alt, #e2e8f0);flex-shrink:0}.plugin-card-cover:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,#0000001a,#0f172a8c)}.plugin-card-tier-badge{position:absolute;top:12px;right:12px;z-index:2;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;padding:4px 10px;border-radius:20px;color:#1e293b;background:#fff;box-shadow:0 2px 8px #0f172a40}.plugin-card[data-tier=free] .plugin-card-tier-badge:before{content:"Free"}.plugin-card[data-tier=premium] .plugin-card-tier-badge:before{content:"Premium"}.plugin-card[data-tier=premium] .plugin-card-tier-badge{color:#f1f5f9;background:linear-gradient(135deg,#475569,#1e293b)}.plugin-card-body{flex:1 1 auto;padding:20px;display:flex;flex-direction:column;gap:10px;background:var(--dm-card-bg, #fff);color:var(--dm-text, #1e293b)}.plugin-card-head{display:flex;align-items:center;gap:12px}.plugin-card-icon{flex-shrink:0;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:10px;font-size:1.3rem;box-shadow:0 2px 6px #0f172a2e}.plugin-card-title{font-size:1.15rem!important;font-weight:700!important;color:var(--dm-text, #1e293b)!important;line-height:1.2!important;margin:0!important}.plugin-card-desc{font-size:.88rem!important;color:var(--dm-text-secondary, #475569)!important;line-height:1.5!important;margin:0!important;flex:1 1 auto}.plugin-card-cta{display:inline-flex;align-items:center;gap:4px;font-size:.82rem;font-weight:600;color:var(--dm-text-secondary, #475569);margin-top:8px;transition:color .15s ease,gap .15s ease}.plugin-card:hover .plugin-card-cta{color:var(--dm-text, #1e293b);gap:8px}.page-body a:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]){color:var(--dm-primary, var(--dm-text, #5d4037))!important;text-decoration:underline;text-decoration-color:var(--dm-border, rgba(0, 0, 0, .2));text-underline-offset:3px;text-decoration-thickness:1.5px;transition:color .15s ease,text-decoration-color .15s ease}.page-body a:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):hover{color:var(--dm-primary-hover, var(--dm-text, #3e2723))!important;text-decoration-color:var(--dm-primary, currentColor)}.page-body .dm-card-gradient .card-body a:not([class*=btn]){color:var(--dm-primary, var(--dm-text, #5d4037))!important}.page-body .dm-card-gradient .card-body a:not([class*=btn]):hover{color:var(--dm-primary-hover, var(--dm-text, #3e2723))!important}html body .page-body a[href]:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):not(.dm-breadcrumbs-link){color:var(--dm-primary, #8d6e63)!important}html body .page-body a[href]:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):not(.dm-breadcrumbs-link):hover{color:var(--dm-primary-hover, #6d4c41)!important}.page-body .hero-cta:not(.hero .hero-cta) a:not([class*=btn]),.page-body>* .hero-cta a:not([class*=btn]){color:var(--dm-primary, #8d6e63)!important;text-decoration:none!important;background:transparent;border:1px solid var(--dm-border, rgba(141, 110, 99, .35));padding:.55rem 1.35rem;border-radius:6px;font-weight:500;display:inline-flex;align-items:center;gap:.4rem;transition:background .15s ease,border-color .15s ease,color .15s ease}.page-body .hero-cta:not(.hero .hero-cta) a:not([class*=btn]):hover,.page-body>* .hero-cta a:not([class*=btn]):hover{color:var(--dm-primary-hover, #6d4c41)!important;background:var(--dm-primary-light, rgba(141, 110, 99, .08));border-color:var(--dm-primary, #8d6e63)}.feature-image{width:100%;max-height:420px;object-fit:cover;border-radius:12px;box-shadow:0 12px 36px #0f172a26;display:block}.page-body .grid>.col:has(>.feature-image),.page-body .grid>.col:has(.reveal>.feature-image),.page-body .grid>.col:has(.feature-image){display:flex;flex-direction:column;justify-content:center}.code-label{display:inline-flex;align-items:center;gap:8px;font-family:Fira Code,Consolas,Monaco,monospace;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:#f1f5f9bf;background:#0f172a8c;padding:6px 12px;border-radius:6px 6px 0 0;border-bottom:1px solid rgba(241,245,249,.12)}.code-label+.code-block{margin-top:0!important;border-top-left-radius:0;border-top-right-radius:0}.code-block{display:block;background:#0f172a!important;color:#e2e8f0!important;padding:18px 20px!important;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.55;margin:0 0 20px;box-shadow:inset 0 0 0 1px #f1f5f914;white-space:pre;font-family:Fira Code,Consolas,Monaco,Courier New,monospace}.code-block code{background:transparent!important;color:inherit!important;padding:0!important;font-family:inherit!important;font-size:inherit;white-space:pre;display:block}.page-body .card-body>pre>code,.page-body .card-body pre.code-block>code{color:#e2e8f0!important}.run-option-card{display:flex;flex-direction:column;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:14px;overflow:hidden;box-shadow:0 4px 14px #0f172a14;height:100%;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}.run-option-card:hover{transform:translateY(-3px);box-shadow:0 20px 48px #0f172a24;border-color:var(--dm-border-dark, #475569)}.run-option-banner{position:relative;width:100%;height:180px;background-size:cover;background-position:center;background-color:var(--dm-background-alt, #e2e8f0);flex-shrink:0}.run-option-banner:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,#0f172a1a,#0f172ab3)}.run-option-icon-chip{position:absolute;bottom:-26px;left:24px;z-index:2;width:56px;height:56px;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:14px;font-size:1.6rem;box-shadow:0 8px 20px #0f172a4d;border:3px solid var(--dm-card-bg, #fff)}.run-option-card-body{flex:1 1 auto;padding:40px 24px 24px;display:flex;flex-direction:column;gap:10px}.run-option-title{font-size:1.5rem!important;font-weight:800!important;color:var(--dm-text, #1e293b)!important;margin:0!important;line-height:1.15!important;letter-spacing:-.01em!important}.run-option-sub{font-size:.9rem!important;font-weight:600!important;color:var(--dm-primary, #5d4037)!important;margin:0 0 8px!important;text-transform:uppercase;letter-spacing:.06em}.run-option-content{flex:1 1 auto;font-size:.92rem;line-height:1.55;color:var(--dm-text-secondary, #475569)}.run-option-content p{margin:0 0 12px}.run-option-content .run-option-intro{font-size:.98rem;color:var(--dm-text, #1e293b);font-weight:500;margin-bottom:16px}.run-option-content .run-option-body-label{font-size:.82rem;text-transform:uppercase;letter-spacing:.08em;color:var(--dm-primary, #5d4037);margin-bottom:8px}.run-option-content .run-option-req{font-size:.82rem;color:var(--dm-text-muted, #64748b);margin-top:14px}.run-option-content .code-block{margin:8px 0 14px}.run-option-list{list-style:none;padding:0;margin:0 0 14px;display:flex;flex-direction:column;gap:8px}.run-option-list li{display:flex;align-items:center;gap:10px;font-size:.9rem;color:var(--dm-text, #1e293b)}.run-option-list li [data-icon]{color:var(--dm-primary, #5d4037);flex-shrink:0}.run-option-ctas{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px;padding-top:20px;border-top:1px solid var(--dm-border, #e2e8f0)}.run-option-ctas .btn{flex:1 1 auto;text-align:center;white-space:nowrap;min-width:fit-content}.quickstart-step{position:relative;padding:28px 22px 24px;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:12px;box-shadow:0 2px 8px #0f172a0d;overflow:hidden;height:100%;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}.quickstart-step:hover{transform:translateY(-3px);box-shadow:0 16px 36px #0f172a1f;border-color:var(--dm-border-dark, #475569)}.quickstart-step-number{position:absolute;top:8px;right:14px;font-size:5rem;font-weight:900;line-height:1;color:color-mix(in srgb,var(--dm-text) 8%,transparent);font-variant-numeric:tabular-nums;pointer-events:none;user-select:none}.quickstart-step-icon{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:10px;font-size:1.3rem;margin-bottom:14px;box-shadow:0 4px 12px #0f172a2e;position:relative;z-index:1}.quickstart-step-title{font-size:1.1rem!important;font-weight:800!important;color:var(--dm-text, #1e293b)!important;margin:0 0 8px!important;line-height:1.2!important;letter-spacing:-.01em!important;position:relative;z-index:1}.quickstart-step-desc{font-size:.86rem;line-height:1.55;color:var(--dm-text-secondary, #475569);margin:0;position:relative;z-index:1}:not(:defined){visibility:hidden}.dm-collection-browser{display:block;margin:1.5rem 0}.dm-collection-browser.dm-cb-hydrated .dm-cb-fallback{display:none}.dm-cb-header{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:space-between;margin-bottom:1rem}.dm-cb-search{flex:1 1 240px;min-width:200px}.dm-cb-search-input{width:100%;padding:.5rem .75rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);color:var(--dm-text, #111827);font-size:.95rem}.dm-cb-sort{display:flex;align-items:center;gap:.5rem;flex:0 0 auto}.dm-cb-sort-label{font-size:.85rem;color:var(--dm-text-muted, #6b7280);margin:0}.dm-cb-sort-select{padding:.45rem .6rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);color:var(--dm-text, #111827)}.dm-cb-sort-dir{width:2rem;height:2rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);cursor:pointer;font-weight:700}.dm-cb-sort-dir:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-layout{display:grid;grid-template-columns:minmax(220px,1fr) 3fr;gap:1.5rem;align-items:start}@media(max-width:768px){.dm-cb-layout{grid-template-columns:1fr}.dm-cb-filter-rail{border:1px solid var(--dm-border, #e5e7eb);border-radius:var(--dm-radius-md, 6px);padding:.75rem}}.dm-cb-filter-rail{padding:.5rem 0;font-size:.92rem}.dm-cb-filter-heading{margin:0 0 .75rem;font-size:.95rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--dm-text-muted, #6b7280)}.dm-cb-filter{margin-bottom:1rem;display:flex;flex-direction:column;gap:.35rem}.dm-cb-filter-label{font-weight:600;font-size:.85rem;color:var(--dm-text, #111827)}.dm-cb-text,.dm-cb-select,.dm-cb-range input{width:100%;padding:.4rem .55rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);color:var(--dm-text, #111827);font-size:.9rem}.dm-cb-range{display:flex;align-items:center;gap:.4rem}.dm-cb-range input{flex:1;min-width:0}.dm-cb-multiselect{display:flex;flex-direction:column;gap:.3rem;max-height:11rem;overflow-y:auto;padding:.4rem .55rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px)}.dm-cb-check{display:flex;align-items:center;gap:.4rem;font-size:.88rem;cursor:pointer;margin:0}.dm-cb-filter-reset{width:100%;margin-top:.5rem;padding:.45rem .6rem;border:1px solid var(--dm-border, #d1d5db);background:transparent;color:var(--dm-text, #374151);border-radius:var(--dm-radius-md, 6px);cursor:pointer;font-size:.85rem}.dm-cb-filter-reset:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-body{min-height:4rem}.dm-cb-pagination{display:flex;align-items:center;justify-content:center;gap:1rem;margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--dm-border, #e5e7eb)}.dm-cb-page-info{font-size:.88rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-page-prev[disabled],.dm-cb-page-next[disabled]{opacity:.45;cursor:not-allowed}.dm-cb-chips{display:flex;flex-wrap:wrap;gap:.35rem;padding:.1rem 0}.dm-cb-chip{display:inline-flex;align-items:center;gap:.4rem;padding:.25rem .6rem;border:1px solid var(--dm-border, #d1d5db);background:var(--dm-background, #fff);color:var(--dm-text, #111827);border-radius:999px;cursor:pointer;font-size:.82rem;transition:background-color .12s ease,border-color .12s ease}.dm-cb-chip:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-chip-active{background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);border-color:var(--dm-primary, #2563eb)}.dm-cb-chip-count{font-size:.75rem;opacity:.75;font-variant-numeric:tabular-nums}.dm-cb-chip-active .dm-cb-chip-count{opacity:.85}.dm-cb-slider{position:relative;height:1.5rem;margin:.5rem .25rem}.dm-cb-slider-track{position:absolute;top:50%;left:0;right:0;transform:translateY(-50%);height:4px;background:var(--dm-border, #e5e7eb);border-radius:2px}.dm-cb-slider-fill{position:absolute;top:0;bottom:0;background:var(--dm-primary, #2563eb);border-radius:2px}.dm-cb-slider-handle{position:absolute;inset:0;width:100%;height:100%;margin:0;background:transparent;pointer-events:none;-webkit-appearance:none;appearance:none}.dm-cb-slider-handle::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;height:1rem;width:1rem;border-radius:50%;background:var(--dm-primary, #2563eb);border:2px solid var(--dm-background, #fff);box-shadow:0 1px 3px #00000026;pointer-events:auto;cursor:grab}.dm-cb-slider-handle::-moz-range-thumb{height:1rem;width:1rem;border-radius:50%;background:var(--dm-primary, #2563eb);border:2px solid var(--dm-background, #fff);box-shadow:0 1px 3px #00000026;pointer-events:auto;cursor:grab}.dm-cb-range-inputs{display:flex;gap:.4rem;align-items:center}.dm-cb-saved{position:relative}.dm-cb-saved-menu{position:absolute;right:0;top:calc(100% + .25rem);min-width:12rem;padding:.5rem;background:var(--dm-background, #fff);border:1px solid var(--dm-border, #e5e7eb);border-radius:var(--dm-radius-md, 6px);box-shadow:0 8px 24px #0f172a1f;z-index:20}.dm-cb-saved-empty{margin:0 0 .5rem;font-size:.85rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-saved-item{display:flex;align-items:center;gap:.4rem;margin-bottom:.25rem}.dm-cb-saved-apply{flex:1;text-align:left;padding:.35rem .5rem;background:transparent;border:0;border-radius:var(--dm-radius-md, 6px);cursor:pointer;font-size:.88rem;color:var(--dm-text, #111827)}.dm-cb-saved-apply:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-saved-del{width:1.5rem;height:1.5rem;padding:0;background:transparent;border:0;color:var(--dm-text-muted, #9ca3af);cursor:pointer;font-size:1.1rem}.dm-cb-saved-del:hover{color:var(--dm-danger, #dc2626)}.dm-cb-saved-actions{border-top:1px solid var(--dm-border, #e5e7eb);padding-top:.5rem;margin-top:.5rem}.dm-cb-saved-create{width:100%;padding:.45rem .6rem;font-size:.85rem}.dm-cb-export{padding:.45rem .7rem;font-size:.85rem}.dm-cb-empty-clear{margin-top:.75rem}.dm-cb-scroll-sentinel{text-align:center;padding:1rem 0;font-size:.85rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-scroll-end{text-align:center;margin:1rem 0 0;font-size:.85rem;color:var(--dm-text-muted, #9ca3af);font-style:italic}.dm-cb-block-loading{text-align:center;padding:2rem 0;color:var(--dm-text-muted, #9ca3af);font-style:italic}.dm-cb-drawer-toggle{display:none;align-items:center;gap:.4rem;padding:.45rem .75rem;font-size:.88rem}.dm-cb-drawer-count{font-variant-numeric:tabular-nums;font-weight:600;color:var(--dm-primary, #2563eb)}.dm-cb-drawer-count:empty{display:none}@media(max-width:768px){.dm-cb-drawer-toggle{display:inline-flex}.dm-cb-filter-rail{position:fixed;top:0;left:-100%;width:85%;max-width:22rem;height:100vh;background:var(--dm-background, #fff);border-right:1px solid var(--dm-border, #e5e7eb);box-shadow:4px 0 16px #00000014;padding:1.25rem;z-index:100;overflow-y:auto;transition:left .22s ease}.dm-cb-drawer-open .dm-cb-filter-rail{left:0}.dm-cb-drawer-open:before{content:"";position:fixed;inset:0;background:#00000059;z-index:99}}.dm-file-thumb{max-width:180px;max-height:120px;border-radius:var(--dm-radius-md, 6px);border:1px solid var(--dm-border, #e5e7eb);display:inline-block;object-fit:cover}.dm-cb-transitions{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.5rem;font-size:.85rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-transitions:empty{display:none}.dm-cb-transition-btn{padding:.35rem .7rem;font-size:.82rem}.dm-menu-sep,.footer-sep{list-style:none}.dm-menu-sep hr,.footer-sep hr{border:0;border-top:1px solid var(--dm-border, rgba(128, 128, 128, .35));margin:.4rem 0}.dm-menu-spacer{list-style:none;pointer-events:none;padding:0;margin:0;border:0}.dm-menu-spacer--xs{height:var(--dm-space-1, .25rem)}.dm-menu-spacer--sm{height:var(--dm-space-2, .5rem)}.dm-menu-spacer--md{height:var(--dm-space-4, 1rem)}.dm-menu-spacer--lg{height:var(--dm-space-6, 1.5rem)}.dm-menu-spacer--xl{height:var(--dm-space-10, 2.5rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--xs,.navbar-nav>.dm-menu-spacer--xs{height:auto;width:var(--dm-space-1, .25rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--sm,.navbar-nav>.dm-menu-spacer--sm{height:auto;width:var(--dm-space-2, .5rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--md,.navbar-nav>.dm-menu-spacer--md{height:auto;width:var(--dm-space-4, 1rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--lg,.navbar-nav>.dm-menu-spacer--lg{height:auto;width:var(--dm-space-6, 1.5rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--xl,.navbar-nav>.dm-menu-spacer--xl{height:auto;width:var(--dm-space-10, 2.5rem)}.dm-menu--has-flex-spacer>ul{display:flex;flex-direction:column}.dm-menu--has-flex-spacer.dm-menu--horizontal>ul{flex-direction:row;align-items:center}.dm-menu-spacer--flex{flex:1 1 auto;height:auto;width:auto}.dm-menu-floating .dm-menu-spacer--flex{min-height:var(--dm-space-4, 1rem)}@media(max-width:768px){.dm-menu--has-flex-spacer.dm-menu--horizontal>ul{flex-wrap:wrap}}#site-navbar .navbar-dropdown-divider{background:var(--dm-border, rgba(128, 128, 128, .5));opacity:.8}.dm-menu-badge{display:inline-block;margin-left:6px;padding:1px 7px;font-size:.7em;font-weight:700;line-height:1.4;border-radius:999px;background:var(--dm-text-muted);color:var(--dm-text-inverse, #fff);vertical-align:middle}.dm-nav-pill{border-radius:999px;padding:6px 14px;font-weight:600}.dm-nav-pill--outline{background:transparent!important;border:1px solid currentColor}@media(max-width:992px){#site-navbar .navbar-toggle{order:0;margin-right:var(--dm-space-2)}#site-navbar .navbar-brand{order:1}#site-navbar .navbar-collapse{position:fixed;top:0;left:0;bottom:0;width:86vw;max-width:340px;z-index:1100;margin:0;padding:var(--dm-space-3) 0 var(--dm-space-6);background:var(--dm-navbar-bg, var(--dm-surface));border-top:none;border-right:1px solid var(--dm-border);box-shadow:4px 0 18px #00000059;transform:translate(-100%);transition:transform .25s ease;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}#site-navbar .navbar-collapse.show{transform:translate(0)}body.dm-drawer-open #site-navbar{z-index:1100}#site-navbar .navbar-nav{max-height:none;overflow:visible}#site-navbar .navbar-dropdown-toggle{display:flex;align-items:center;justify-content:space-between;width:100%;padding:var(--dm-space-3) var(--dm-space-4);font-size:var(--dm-font-size-base)}#site-navbar .navbar-caret{margin-left:auto;flex:none;width:16px;height:16px;opacity:.9}#site-navbar .navbar-dropdown-menu{position:static;display:none;min-width:0;width:100%;margin:0;padding:0;border:0;border-radius:0;box-shadow:none;background:color-mix(in srgb,var(--dm-text) 8%,transparent)}#site-navbar .navbar-dropdown.open>.navbar-dropdown-menu{display:block}#site-navbar .navbar-dropdown-item{padding-left:calc(var(--dm-space-4) + var(--dm-space-5))}.dm-navbar-backdrop{position:fixed;inset:0;z-index:1090;background:#00000073;border:0;padding:0;cursor:pointer}body.dm-drawer-open{overflow:hidden}}.dm-embed{margin:1.5rem 0}.dm-embed-frame{overflow:hidden;border-radius:8px;background:#000}.dm-embed-caption{margin-top:.5rem;font-size:.85rem;color:var(--dm-text-muted, #6b7280);text-align:center}.dm-embed-blocked{margin:1.5rem 0;padding:.75rem 1rem;border:1px dashed var(--dm-border, #d1d5db);border-radius:8px;background:var(--dm-background-alt, #f9fafb);color:var(--dm-text-muted, #6b7280);font-size:.9rem}.dm-menu-missing{margin:1rem 0;padding:.6rem .9rem;border:1px dashed var(--dm-border, #d1d5db);border-radius:8px;background:var(--dm-background-alt, #f9fafb);color:var(--dm-text-muted, #6b7280);font-size:.9rem}.dm-embed-blocked code{font-family:var(--dm-font-mono, monospace);font-size:.85em}.dm-menu-floating{overflow:auto;overscroll-behavior:contain;background:var(--dm-surface);color:var(--dm-text);border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 8px);box-shadow:var(--dm-shadow-lg);scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}.dm-menu-floating[style*=--dm-menu-accent]{border-left:3px solid var(--dm-menu-accent)}.dm-menu-floating[data-float-anchor=TR][style*=--dm-menu-accent],.dm-menu-floating[data-float-anchor=BR][style*=--dm-menu-accent],.dm-menu-floating[data-float-anchor=R][style*=--dm-menu-accent]{border-left:1px solid var(--dm-menu-accent);border-right:3px solid var(--dm-menu-accent)}.dm-menu-floating[style*=--dm-menu-panel-opacity]{background:color-mix(in srgb,var(--dm-surface) calc(var(--dm-menu-panel-opacity) * 100%),transparent);backdrop-filter:blur(8px)}.dm-menu-float-bar{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dm-space-2, .5rem);padding:var(--dm-space-2, .5rem) var(--dm-space-3, .75rem);background:inherit;border-bottom:1px solid var(--dm-border);border-radius:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0}.dm-menu-float-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;font-weight:600;letter-spacing:.02em;color:var(--dm-text-muted, #6b7280)}.dm-menu-float-grip{flex:0 0 auto;width:10px;height:16px;background-image:radial-gradient(currentColor 1px,transparent 1px);background-size:5px 5px;background-position:0 2px;color:var(--dm-text-muted, #6b7280);opacity:.6}.dm-menu-floating[data-float-movable] .dm-menu-float-bar{cursor:grab}.dm-menu-floating.is-dragging,.dm-menu-floating.is-dragging .dm-menu-float-bar{cursor:grabbing}.dm-menu-floating.is-dragging{user-select:none}.dm-menu-floating[data-float-movable] .dm-menu-float-bar{touch-action:none}.dm-menu-float-toggle{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:0;border-radius:var(--dm-radius-sm, 4px);background:transparent;color:var(--dm-text);cursor:pointer}.dm-menu-float-toggle:hover{background:var(--dm-surface-alt, rgba(0, 0, 0, .06))}.dm-menu-float-toggle:focus-visible{outline:2px solid var(--dm-primary);outline-offset:1px}.dm-menu-float-icon{position:relative;width:16px;height:2px;background:currentColor;border-radius:1px}.dm-menu-float-icon:before,.dm-menu-float-icon:after{content:"";position:absolute;left:0;width:100%;height:2px;background:currentColor;border-radius:1px}.dm-menu-float-icon:before{top:-5px}.dm-menu-float-icon:after{top:5px}.dm-menu-floating.is-collapsed{width:auto!important;max-height:none!important;overflow:visible;padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none;resize:none;min-width:0;min-height:0}.dm-menu-floating.is-collapsed>*:not(.dm-menu-float-bar),.dm-menu-floating.is-collapsed .dm-menu-float-grip,.dm-menu-floating.is-collapsed .dm-menu-float-title{display:none}#site-navbar.dm-menu-floating.is-collapsed>*:not(.dm-menu-float-bar){display:none}#site-navbar.dm-menu-floating.is-collapsed{width:auto!important;max-height:none!important;padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none}.dm-menu-floating.is-collapsed .dm-menu-float-bar{padding:0;border:0;background:transparent;cursor:default}.dm-menu-floating.is-collapsed .dm-menu-float-toggle{width:44px;height:44px;border-radius:50%;background:var(--dm-surface);border:1px solid var(--dm-menu-accent, var(--dm-border));box-shadow:var(--dm-shadow-lg)}.navbar-transparent,.dm-menu--variant-transparent,.dm-menu-floating.navbar-transparent,.dm-menu-floating.dm-menu--variant-transparent{background:transparent;border-color:transparent;box-shadow:none;backdrop-filter:none}.navbar-transparent.is-collapsed .dm-menu-float-toggle,.dm-menu--variant-transparent.is-collapsed .dm-menu-float-toggle{background:var(--dm-surface)}.navbar-transparent .dm-menu-float-bar,.dm-menu--variant-transparent .dm-menu-float-bar{border-bottom-color:transparent}.dm-menu-floating[data-float-resizable]:not(.is-collapsed){resize:both;min-width:120px;min-height:48px}@media(max-width:768px){.dm-menu-floating{position:static!important;inset:auto!important;width:auto!important;max-height:none!important;transform:none!important;resize:none!important}.dm-menu-floating[data-float-movable] .dm-menu-float-bar{cursor:default}.dm-menu-floating[data-float-movable] .dm-menu-float-grip{display:none}}.dm-menu--vertical ul,.dm-menu--horizontal ul{list-style:none;margin:0;padding:0}.dm-menu--vertical>ul{display:flex;flex-direction:column;gap:2px}.dm-menu--vertical>ul>li>a{display:block;padding:.4rem .75rem;border-radius:var(--dm-radius-md, 6px);text-decoration:none}.dm-menu--vertical>ul>li>a:hover{background:color-mix(in srgb,var(--dm-text) 8%,transparent)}.dm-menu--vertical ul ul{margin-left:.75rem;border-left:1px solid var(--dm-border, rgba(128, 128, 128, .35));padding-left:.4rem}.dm-menu--horizontal>ul{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem 1rem}.dm-menu--horizontal>ul>li{position:relative}.dm-menu--horizontal>ul>li>a{display:inline-block;padding:.35rem .5rem;text-decoration:none}.dm-menu--horizontal>ul>li>ul{position:absolute;top:100%;left:0;z-index:40;display:none;min-width:180px;padding:.35rem 0;background:var(--dm-surface);border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 8px);box-shadow:var(--dm-shadow-lg)}.dm-menu--horizontal>ul>li:hover>ul,.dm-menu--horizontal>ul>li:focus-within>ul{display:block}.dm-menu--horizontal>ul>li>ul a{display:block;padding:.35rem .9rem;text-decoration:none}@media(max-width:768px){.dm-menu--horizontal>ul{flex-direction:column;align-items:stretch}.dm-menu--horizontal>ul>li>ul{position:static;display:block;border:0;box-shadow:none;padding-left:.75rem}}:root{--dm-vnav-width: 240px}@media(min-width:993px){#site-navbar.dm-nav-vertical:not(.dm-menu-floating){position:fixed;top:0;bottom:0;height:100vh;height:100dvh;width:var(--dm-vnav-width);flex-direction:column;flex-wrap:nowrap;align-items:stretch;justify-content:flex-start;gap:var(--dm-space-2);padding:var(--dm-space-4) var(--dm-space-3);overflow-y:auto;overscroll-behavior:contain;border-bottom:none;z-index:100}#site-navbar.dm-nav-vertical-left:not(.dm-menu-floating){left:0;right:auto;border-right:1px solid var(--dm-border)}#site-navbar.dm-nav-vertical-right:not(.dm-menu-floating){right:0;left:auto;border-left:1px solid var(--dm-border)}body.dm-vnav-left{padding-left:var(--dm-vnav-width)}body.dm-vnav-right{padding-right:var(--dm-vnav-width)}#site-navbar.dm-nav-vertical .navbar-container{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:var(--dm-space-2);width:100%;min-height:100%;padding:0;margin:0}#site-navbar.dm-nav-vertical .navbar-toggle{display:none!important}#site-navbar.dm-nav-vertical .navbar-brand{padding:0 var(--dm-space-2) var(--dm-space-3);margin:0;width:100%}#site-navbar.dm-nav-vertical .navbar-collapse{display:flex!important;flex-direction:column!important;align-items:stretch!important;width:100%!important;flex-grow:1!important;padding:0!important;border:none!important}#site-navbar.dm-nav-vertical .navbar-nav{display:flex!important;flex-direction:column!important;align-items:stretch!important;justify-content:flex-start!important;gap:2px!important;width:100%!important;flex:none!important;margin:0!important;padding:0!important}#site-navbar.dm-nav-vertical .navbar-nav li,#site-navbar.dm-nav-vertical .navbar-nav .navbar-item{width:100%!important;display:block!important}#site-navbar.dm-nav-vertical .navbar-link,#site-navbar.dm-nav-vertical .navbar-dropdown-toggle{display:flex!important;align-items:center!important;justify-content:flex-start!important;gap:var(--dm-space-2)!important;width:100%!important;padding:var(--dm-space-2) var(--dm-space-3)!important;font-size:var(--dm-font-size-sm)!important;text-align:left!important;border-radius:var(--dm-radius-md)!important;white-space:normal!important}#site-navbar.dm-nav-vertical .navbar-link:hover,#site-navbar.dm-nav-vertical .navbar-dropdown-toggle:hover{background-color:color-mix(in srgb,var(--dm-text) 8%,transparent)}#site-navbar.dm-nav-vertical .navbar-dropdown-toggle .navbar-caret{margin-left:auto}#site-navbar.dm-nav-vertical .navbar-dropdown{position:static!important;width:100%!important}#site-navbar.dm-nav-vertical .navbar-dropdown-menu{position:static!important;display:none;width:100%!important;min-width:0!important;margin:0!important;padding:0!important;border:0!important;border-radius:0!important;box-shadow:none!important;background:color-mix(in srgb,var(--dm-text) 8%,transparent)!important}#site-navbar.dm-nav-vertical .navbar-dropdown.open>.navbar-dropdown-menu{display:block!important}#site-navbar.dm-nav-vertical .navbar-dropdown-item{display:block!important;width:100%!important;padding:var(--dm-space-2) var(--dm-space-3) var(--dm-space-2) calc(var(--dm-space-3) + var(--dm-space-5))!important}#site-navbar.dm-nav-vertical .navbar-actions{display:flex;flex-direction:column;align-items:stretch;margin-left:0;margin-top:auto;padding-top:var(--dm-space-3)}}@media print{body.dm-ctx-printing *{visibility:hidden}body.dm-ctx-printing [data-dm-print],body.dm-ctx-printing [data-dm-print] *{visibility:visible}body.dm-ctx-printing [data-dm-print]{position:absolute;left:0;top:0;width:100%}body.dm-ctx-printing [data-dm-print] .accordion-content{display:block!important;height:auto!important}body.dm-ctx-printing .dm-ctx-hidden{display:none!important}}
|
|
1
|
+
body,button,input,select,textarea{font-family:Roboto,sans-serif}.navbar-brand-logo{height:32px;width:auto;display:inline-block;vertical-align:middle;margin-right:.4em}.navbar-brand-tagline{display:block;font-size:.65em;opacity:.75;line-height:1.2;letter-spacing:.02em}.navbar-brand-text.navbar-brand-sm{font-size:.85em}.navbar-brand-text.navbar-brand-lg{font-size:1.25em}.navbar-actions{order:4;margin-left:auto;display:flex;align-items:center;gap:.5rem}#site-navbar.navbar-dark .navbar-actions,#site-navbar.navbar-light .navbar-actions{color:var(--dm-navbar-text)}#site-navbar.navbar-dark .site-search-shortcut-hint,#site-navbar.navbar-light .site-search-shortcut-hint{color:color-mix(in srgb,var(--dm-navbar-text) 65%,var(--dm-navbar-bg));border-color:color-mix(in srgb,var(--dm-navbar-text) 28%,transparent)}.site-main{min-height:calc(100vh - 60px);padding-top:2rem;padding-bottom:4rem}.site-main.with-sidebar{display:grid;grid-template-columns:260px 1fr;gap:0}.site-sidebar{min-height:100%;border-right:1px solid var(--dm-border, rgba(255,255,255,.08))}.site-content{overflow:hidden}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.container{padding:0 1.5rem}.page-title{font-size:clamp(1.5rem,4vw,2rem);font-weight:700;margin-bottom:1.5rem;line-height:1.2}.page-body{line-height:1.7;font-size:1rem}.page-body h1,.page-body h2,.page-body h3,.page-body h4{margin-top:2rem;margin-bottom:.75rem;font-weight:600}.page-body h2{font-size:clamp(1.2rem,3vw,1.5rem)}.page-body h3{font-size:clamp(1.1rem,2.5vw,1.25rem)}.page-body p{margin-bottom:1rem}.page-body ul,.page-body ol{margin-bottom:1rem;padding-left:1.5rem}.page-body a{color:var(--dm-primary, #5b8cff)}.page-body a:hover{text-decoration:underline}.page-body code{font-family:Fira Code,Courier New,monospace;font-size:.9em;background:var(--dm-code-bg, rgba(255,255,255,.06));color:var(--dm-code-text, inherit);padding:.15em .35em;border-radius:3px}.page-body pre{background:var(--dm-code-bg, rgba(0,0,0,.3));color:var(--dm-code-text, inherit);border:1px solid var(--dm-code-border, rgba(255,255,255,.08));border-radius:6px;padding:1rem;overflow-x:auto;margin-bottom:1rem}.page-body pre code{background:none;padding:0}.page-body img{max-width:100%;border-radius:6px}.page-body blockquote{border-left:3px solid var(--dm-primary, #5b8cff);margin:1.5rem 0;padding:.75rem 1rem;background:color-mix(in srgb,var(--dm-primary, #5b8cff) 8%,transparent);border-radius:0 6px 6px 0}h3.accordion-header{margin:0}.accordion-button{all:unset;display:flex;align-items:center;justify-content:space-between;width:100%;cursor:pointer;font:inherit}.page-body .card-header h2{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.card[data-collapsible] .card-header{cursor:pointer;user-select:none;display:flex;align-items:center;justify-content:space-between}.card[data-collapsible] .card-header:after{content:"\25be";font-size:1.1em;line-height:1;display:inline-block;transition:transform .25s ease;flex-shrink:0}.card[data-collapsible].is-collapsed .card-header:after{transform:rotate(-90deg)}.card[data-collapsible] .card-body{overflow:hidden;max-height:4000px;opacity:1;transition:max-height .3s ease,opacity .25s ease}.card[data-collapsible].is-collapsed .card-body{max-height:0;opacity:0}.card-primary>.card-header,.card-primary>.card-footer{background-color:color-mix(in srgb,var(--dm-primary) 18%,var(--dm-surface));color:var(--dm-text);border-color:var(--dm-primary)}.card-primary>.card-header .card-title{color:var(--dm-text)}.navbar-link span[data-icon],.navbar-link svg,.navbar-dropdown-toggle span[data-icon],.navbar-dropdown-toggle svg,.navbar-dropdown-item span[data-icon],.navbar-dropdown-item svg{width:13px!important;height:13px!important;margin-right:10px!important}#site-navbar .navbar-dropdown-toggle,#site-navbar .navbar-dropdown-item{font-size:var(--dm-font-size-base)}@media(min-width:993px){#site-navbar .navbar-dropdown-toggle,#site-navbar .navbar-dropdown-item{font-size:var(--dm-font-size-sm)}}@media(min-width:1201px){#site-navbar .navbar-dropdown-toggle,#site-navbar .navbar-dropdown-item{font-size:var(--dm-font-size-xs)}}.dm-reduced-motion *,.dm-reduced-motion *:before,.dm-reduced-motion *:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}.page-footer{border-top:1px solid var(--dm-border, rgba(255,255,255,.08));padding:1.5rem 0}.footer-inner{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;max-width:1200px;margin:0 auto}.footer-inner p{margin:0;color:var(--dm-text-muted, #888);font-size:.875rem}.footer-links{display:flex;gap:1.25rem}.footer-links a{color:var(--dm-text-muted, #888);font-size:.875rem;text-decoration:none}.footer-links a:hover{color:var(--dm-text, #eee)}.footer-social{display:flex;gap:.5rem;align-items:center}.footer-social-link{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;color:var(--dm-text-muted, #888);transition:color .15s}.footer-social-link:hover{color:var(--dm-text, #eee)}.footer-social-link svg{width:1rem;height:1rem}.footer-motion-switch{font-size:.8rem;color:var(--dm-text-muted, #888);white-space:nowrap}.footer-motion-switch .form-switch-label{color:var(--dm-text-muted, #888)}.footer-motion-switch .form-switch-input{width:2rem;height:1.125rem}.footer-motion-switch .form-switch-input:after{width:.875rem;height:.875rem}.footer-motion-switch .form-switch-input:checked:after{transform:translate(.875rem)}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:.875rem 1.25rem;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .08));flex-shrink:0}.dm-slideover-title{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.dm-slideover-body{padding:1.25rem;overflow:auto;overscroll-behavior:contain;flex:1;min-height:0;scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}.dm-slideover-body::-webkit-scrollbar{width:8px;height:8px}.dm-slideover-body::-webkit-scrollbar-track{background:transparent}.dm-slideover-body::-webkit-scrollbar-thumb{background:var(--dm-border);border-radius:4px}.dm-slideover-body::-webkit-scrollbar-thumb:hover{background:var(--dm-text-muted)}@media(max-width:768px){.site-main.with-sidebar{grid-template-columns:1fr}.site-sidebar{display:none}}.dm-spacer{display:block;width:100%}.hero-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.site-main:has(.page-body>.hero-breakout:first-child){padding-top:0}body[data-layout=landing]>.site-main{padding-top:0}body[data-layout=landing]>.site-main .container{max-width:none;padding:0}body[data-layout=landing] .page-body{padding-left:1.5rem;padding-right:1.5rem}body[data-layout=landing] .page-body>p,body[data-layout=landing] .page-body>h1,body[data-layout=landing] .page-body>h2,body[data-layout=landing] .page-body>h3,body[data-layout=landing] .page-body>ul,body[data-layout=landing] .page-body>ol,body[data-layout=landing] .page-body>blockquote{max-width:860px;margin-left:auto;margin-right:auto}.hero-breakout{width:100vw;margin-left:calc((100% - 100vw)/2);max-width:none}body[data-layout=landing] .page-body .hero-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem}body[data-layout=landing] .page-body .grid-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem;padding-left:1.5rem;padding-right:1.5rem}.page-body .card{transition:transform .2s ease,box-shadow .2s ease}.page-body .card:hover{transform:translateY(-3px);box-shadow:0 8px 24px #00000059}.page-body .card-header-icon-inline{display:flex;align-items:center;gap:.6rem}.page-body .card-header-icon-inline [data-icon]{flex-shrink:0;line-height:0}.page-body .card-header-icon-inline [data-icon] svg,.page-body .card-header-icon-inline>svg{display:block;width:1.25rem;height:1.25rem}.page-body .card-header-icon-stacked{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.35rem;padding-top:.25rem}.page-body .card-header-icon-stacked [data-icon],.page-body .card-header-icon-stacked svg{width:2rem;height:2rem}.page-body .dm-card-clean{background:var(--dm-surface);border:1px solid var(--dm-border);box-shadow:0 1px 4px #0000000f,0 2px 8px #0000000a;transition:transform .2s ease,box-shadow .2s ease}.page-body .dm-card-clean:hover{transform:translateY(-4px);box-shadow:0 8px 24px #0000001a,0 2px 8px #0000000f}.page-body .dm-card-clean .card-header{color:var(--dm-text)}.page-body .dm-card-clean .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-clean .card-footer{color:var(--dm-text-muted);border-top:1px solid var(--dm-border)}.page-body .dm-card-gradient{background:var(--dm-card-bg, #fff);border:none;box-shadow:0 4px 20px #6366f124;transition:transform .2s ease,box-shadow .2s ease}.page-body .dm-card-gradient:hover{transform:translateY(-5px);box-shadow:0 16px 40px #6366f140}.page-body .dm-card-gradient .card-header{background:linear-gradient(135deg,var(--dm-card-g-start, #6366f1),var(--dm-card-g-end, #8b5cf6));color:#fff;border-bottom:none}.page-body .dm-card-gradient .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-gradient .card-footer{color:var(--dm-text-muted);border-top:1px solid var(--dm-border)}.page-body .dm-card-glass{background:#ffffff2e;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1px solid rgba(255,255,255,.38);box-shadow:0 4px 24px #00000014;transition:transform .2s ease,box-shadow .2s ease,background .2s ease}.page-body .dm-card-glass:hover{transform:translateY(-4px);box-shadow:0 12px 36px #00000024;background:#ffffff42}.page-body .dm-card-glass .card-header{border-bottom:1px solid rgba(255,255,255,.25);color:var(--dm-text)}.page-body .dm-card-glass .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-glass .card-footer{color:var(--dm-text-muted)}.page-body .dm-card-accent{background:var(--dm-surface);border:1px solid var(--dm-border);border-left:4px solid var(--dm-primary, #6366f1);box-shadow:0 1px 4px #0000000d;transition:transform .2s ease,box-shadow .2s ease,border-left-color .2s ease}.page-body .dm-card-accent:hover{transform:translateY(-3px);border-left-color:var(--dm-primary-hover, #4f46e5);box-shadow:0 8px 24px #6366f11f}.page-body .dm-card-accent .card-header{color:var(--dm-primary);border-bottom:none}.page-body .dm-card-accent .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-accent .card-footer{color:var(--dm-text-muted);border-top:1px solid var(--dm-border)}.page-body .dm-card-dark{background:linear-gradient(160deg,#1e293b,#0f172a);border:1px solid rgba(255,255,255,.06);box-shadow:0 4px 20px #0000004d;transition:transform .2s ease,box-shadow .2s ease}.page-body .dm-card-dark:hover{transform:translateY(-4px) scale(1.012);box-shadow:0 16px 40px #00000073}.page-body .dm-card-dark .card-header{color:#f1f5f9;border-bottom:1px solid rgba(255,255,255,.08)}.page-body .dm-card-dark .card-body{color:#94a3b8}.page-body .dm-card-dark .card-footer{color:#475569;border-top:1px solid rgba(255,255,255,.06)}.page-body .dm-card-glow{background:var(--dm-surface);border:1px solid color-mix(in srgb,var(--dm-primary, #6366f1) 45%,transparent);box-shadow:0 0 #6366f100;transition:transform .2s ease,box-shadow .3s ease,border-color .2s ease}.page-body .dm-card-glow:hover{transform:translateY(-3px);border-color:var(--dm-primary, #818cf8);box-shadow:0 0 0 4px color-mix(in srgb,var(--dm-primary, #6366f1) 14%,transparent),0 0 28px color-mix(in srgb,var(--dm-primary, #6366f1) 22%,transparent)}.page-body .dm-card-glow .card-header{color:var(--dm-primary);border-bottom:1px solid color-mix(in srgb,var(--dm-primary, #6366f1) 20%,transparent)}.page-body .dm-card-glow .card-body{color:var(--dm-text-secondary)}.page-body .dm-card-glow .card-footer{border-top:1px solid color-mix(in srgb,var(--dm-primary, #6366f1) 20%,transparent);color:var(--dm-primary, #818cf8)}.page-body .card-hover{transition:transform .2s ease,box-shadow .2s ease}.page-body .card-hover:hover{transform:translateY(-3px);box-shadow:0 8px 20px #0000001a}.card-gradient-indigo{background:linear-gradient(135deg,#6366f1,#8b5cf6)}.card-gradient-ocean{background:linear-gradient(135deg,#0891b2,#2563eb)}.card-gradient-sunset{background:linear-gradient(135deg,#f59e0b,#ef4444,#ec4899)}.card-gradient-forest{background:linear-gradient(135deg,#10b981,#0d9488)}.card-gradient-rose{background:linear-gradient(135deg,#fb7185,#e11d48)}.card-gradient-midnight{background:linear-gradient(135deg,#1e1b4b,#4338ca)}.card-gradient-aurora{background:linear-gradient(135deg,#06b6d4,#6366f1,#a855f7)}.card-gradient-fire{background:linear-gradient(135deg,#ef4444,#f97316,#fbbf24)}.card-gradient-lagoon{background:linear-gradient(135deg,#06b6d4,#0e7490)}.card-gradient-dusk{background:linear-gradient(135deg,#7c3aed,#db2777)}.card-gradient-lime{background:linear-gradient(135deg,#84cc16,#10b981)}.card-gradient-gold{background:linear-gradient(135deg,#f59e0b,#b45309)}.card-gradient-arctic{background:linear-gradient(135deg,#bae6fd,#e0f2fe);color:#1e293b}.card-gradient-slate{background:linear-gradient(135deg,#475569,#1e293b)}[class*=card-gradient-]:not(.card-gradient-arctic){color:#fff}.page-body .card-font-serif{font-family:Georgia,Times New Roman,serif}.page-body .card-font-mono{font-family:SF Mono,Fira Code,Courier New,monospace}.page-body .card-text-sm{font-size:.85rem}.page-body .card-text-lg{font-size:1.1rem}.page-body .card-text-xl{font-size:1.25rem}.page-body .card-borderless{border:none!important}.page-body .card-shadow-none{box-shadow:none!important}.page-body .card-shadow-md{box-shadow:0 4px 12px #0000001a}.page-body .card-shadow-lg{box-shadow:0 10px 30px #0000002e}.page-body .card-rounded-none{border-radius:0}.page-body .card-rounded-sm{border-radius:4px}.page-body .card-rounded-lg{border-radius:20px}.page-body .card-rounded-full{border-radius:9999px}.page-body .card-align-center{text-align:center}.page-body .card-align-right{text-align:right}.page-body .card-pad-compact .card-body,.page-body .card-pad-compact .card-header,.page-body .card-pad-compact .card-footer{padding:8px 12px}.page-body .card-pad-spacious .card-body,.page-body .card-pad-spacious .card-header,.page-body .card-pad-spacious .card-footer{padding:24px 28px}.card-img-top{width:100%;height:180px;background-size:cover;background-position:center;background-color:var(--dm-border,#e2e8f0);display:flex;align-items:center;justify-content:center;font-size:2.5rem;color:color-mix(in srgb,var(--dm-text) 15%,transparent)}.card-img-left,.card-img-right{width:90px;flex-shrink:0;background-size:cover;background-position:center;background-color:var(--dm-border,#e2e8f0);display:flex;align-items:center;justify-content:center;font-size:1.75rem;color:color-mix(in srgb,var(--dm-text) 20%,transparent)}.card-img-wide{width:130px;flex-shrink:0;background-size:cover;background-position:center;background-color:var(--dm-border,#e2e8f0);display:flex;align-items:center;justify-content:center;font-size:2rem;color:color-mix(in srgb,var(--dm-text) 20%,transparent)}.card-layout-horizontal,.card-layout-thumb-left,.card-layout-thumb-right{display:flex}.card-layout-thumb-left .card-body,.card-layout-thumb-right .card-body,.card-layout-horizontal .card-body{flex:1;min-width:0}.card-layout-split{display:flex;min-height:140px}.card-split-left{width:50%;display:flex;align-items:center;justify-content:center;font-size:2.25rem;flex-shrink:0;background:linear-gradient(160deg,#6366f1,#8b5cf6)}.card-split-right{flex:1;background:#1e293b;display:flex;flex-direction:column;justify-content:center}.card-split-right .card-body{color:#94a3b8}.card-split-right .card-title{color:#f1f5f9}.card-img-overlay{position:relative;height:180px;overflow:hidden;background-size:cover;background-position:center;background-color:#1e293b;display:flex;align-items:flex-end}.card-overlay-text{width:100%;padding:40px 16px 14px;background:linear-gradient(to top,rgba(0,0,0,.75),transparent)}.card-overlay-text .card-title{color:#fff}.dm-card-dark .card-img-top,.dm-card-dark .card-img-left,.dm-card-dark .card-img-right,.dm-card-dark .card-img-wide{filter:brightness(.7)}.card-stat-value{font-size:2.4rem;font-weight:800;color:var(--dm-text);line-height:1.1}.card-stat-delta{font-size:.8rem;font-weight:600;margin-top:2px}.card-stat-delta.positive{color:var(--dm-success, #10b981)}.card-stat-delta.negative{color:var(--dm-danger, #ef4444)}.card-stat-bar{height:5px;background:var(--dm-border);border-radius:3px;margin-top:14px;overflow:hidden}.card-stat-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,#6366f1,#8b5cf6)}.card-progress-bar{height:8px;background:var(--dm-border);border-radius:4px;overflow:hidden;margin:8px 0}.card-progress-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,#6366f1,#8b5cf6)}.card-milestone{display:flex;align-items:center;gap:8px;font-size:.8rem;color:var(--dm-text-secondary);padding:3px 0}.card-milestone-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.card-milestone-dot.done{background:var(--dm-success, #10b981)}.card-milestone-dot.pending{background:var(--dm-border, #e5e7eb)}.card-header-icon-stacked{text-align:center;padding:20px 16px 12px}.card-header-icon-stacked [data-icon],.card-header-icon-stacked .card-icon{font-size:2rem;display:block;margin-bottom:8px}.card-step-bg{position:relative;overflow:hidden;min-height:60px;display:flex;align-items:center;padding:14px 16px}.card-step-ghost{position:absolute;right:8px;top:-10px;font-size:5rem;font-weight:900;color:color-mix(in srgb,var(--dm-primary, #6366f1) 12%,transparent);line-height:1;pointer-events:none}.card-step-badge{width:32px;height:32px;border-radius:50%;background:var(--dm-primary, #6366f1);color:var(--dm-primary-text, #fff);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.85rem;z-index:1;flex-shrink:0}.card-corner-badge-wrap{position:relative}.card-corner-badge{position:absolute;top:10px;right:10px;background:var(--dm-danger, #ef4444);color:#fff;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;padding:2px 8px;border-radius:20px}.card-callout{border-left:4px solid var(--dm-primary, #6366f1)}.card-callout.warn{border-left-color:var(--dm-warning, #f59e0b)}.card-callout.success{border-left-color:var(--dm-success, #10b981)}.card-callout.error{border-left-color:var(--dm-danger, #ef4444)}.card-callout-inner{display:flex;gap:12px;align-items:flex-start}.card-callout-icon{font-size:1.2rem;flex-shrink:0;margin-top:1px}.card-quote-mark{font-size:3.5rem;color:color-mix(in srgb,var(--dm-primary, #6366f1) 18%,transparent);line-height:.8;padding:14px 16px 0;font-family:Georgia,serif;display:block}.card-quote-text{padding:4px 16px 14px;font-style:italic;color:var(--dm-text-secondary);line-height:1.7}.card-quote-attr{display:flex;align-items:center;gap:10px}.card-quote-avatar{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:.85rem;color:#fff;flex-shrink:0}.card-video-thumb{position:relative;height:160px;background:#1e293b;display:flex;align-items:center;justify-content:center;background-size:cover;background-position:center}.card-play-btn{width:52px;height:52px;border-radius:50%;background:#ffffffe6;display:flex;align-items:center;justify-content:center;font-size:1.2rem;box-shadow:0 4px 16px #0000004d}.card-video-duration{position:absolute;bottom:8px;right:10px;background:#000000b3;color:#fff;font-size:.65rem;font-weight:600;padding:2px 7px;border-radius:4px}.card-map-placeholder{height:130px;background:linear-gradient(160deg,#bfdbfe,#dbeafe);position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden}.card-map-grid{position:absolute;inset:0;background-image:repeating-linear-gradient(0deg,rgba(59,130,246,.08) 0,rgba(59,130,246,.08) 1px,transparent 1px,transparent 32px),repeating-linear-gradient(90deg,rgba(59,130,246,.08) 0,rgba(59,130,246,.08) 1px,transparent 1px,transparent 32px)}.card-map-pin{font-size:2rem;z-index:1}.card-avatar{width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:1.8rem;color:#fff;margin:0 auto 12px}.card-avatar-wrap{text-align:center;padding:24px 16px 16px}.card-tag-pills{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-top:10px}.card-pill{background:color-mix(in srgb,var(--dm-primary, #7c3aed) 15%,transparent);color:var(--dm-primary, #7c3aed);font-size:.7rem;font-weight:700;padding:3px 9px;border-radius:20px}.card-tag-cloud{padding:14px 16px;display:flex;flex-wrap:wrap;gap:7px}.card-tag{padding:4px 11px;border-radius:20px;font-size:.78rem;font-weight:600}.card-file-row{display:flex;gap:14px;align-items:center;padding:16px}.card-file-icon{width:48px;height:58px;border-radius:7px;background:linear-gradient(160deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:1.4rem;color:#fff;flex-shrink:0;position:relative}.card-file-ext{position:absolute;bottom:4px;left:0;right:0;text-align:center;font-size:.55rem;font-weight:800;color:#ffffffe6;letter-spacing:.05em}.card-file-dl{font-size:.78rem;font-weight:700;color:var(--dm-primary, #6366f1);display:inline-block;margin-top:4px}.card-stars{color:#f59e0b;letter-spacing:2px;padding:14px 16px 0;display:block}.card-verified{display:inline-block;background:color-mix(in srgb,var(--dm-success, #10b981) 18%,transparent);color:var(--dm-success, #065f46);font-size:.6rem;font-weight:700;padding:1px 5px;border-radius:3px;margin-left:6px}.card-activity-item{display:flex;gap:10px;align-items:flex-start;padding:8px 14px;border-bottom:1px solid var(--dm-border)}.card-activity-item:last-child{border-bottom:none}.card-activity-avatar{width:30px;height:30px;border-radius:50%;flex-shrink:0;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:.8rem;color:#fff}.card-compare-grid{display:grid;grid-template-columns:1fr 1fr}.card-compare-col{padding:12px 14px}.card-compare-col+.card-compare-col{border-left:1px solid var(--dm-border)}.card-compare-label{font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;margin-bottom:8px;display:block}.card-compare-label.before{color:var(--dm-danger, #ef4444)}.card-compare-label.after{color:var(--dm-success, #10b981)}.card-compare-item{display:flex;gap:7px;align-items:flex-start;font-size:.78rem;color:var(--dm-text-secondary);padding:3px 0;line-height:1.4}.card-compare-x{color:var(--dm-danger, #ef4444);flex-shrink:0}.card-compare-check{color:var(--dm-success, #10b981);flex-shrink:0}.card-pricing-features{padding:14px 16px}.card-pricing-feature{display:flex;align-items:center;gap:8px;font-size:.82rem;color:var(--dm-text-secondary);padding:4px 0}.card-pricing-check{color:var(--dm-success, #10b981)}.card-pricing-cta{display:block;text-align:center;background:var(--dm-primary, #6366f1);color:var(--dm-primary-text, #fff);font-size:.82rem;font-weight:700;padding:9px;border-radius:8px;text-decoration:none;margin:0 16px 14px}.card-timeline-row{display:flex}.card-timeline-side{width:44px;flex-shrink:0;display:flex;flex-direction:column;align-items:center;padding-top:14px}.card-timeline-dot{width:12px;height:12px;border-radius:50%;background:var(--dm-primary, #6366f1);flex-shrink:0}.card-timeline-line{width:2px;background:var(--dm-border, #e5e7eb);flex:1;margin-top:4px}.card-timeline-body{flex:1;padding:12px 14px 12px 0}.card-timeline-date{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--dm-text-muted)}.card-timeline-tag{display:inline-block;background:color-mix(in srgb,var(--dm-success, #10b981) 18%,transparent);color:var(--dm-success, #065f46);font-size:.65rem;font-weight:700;padding:2px 6px;border-radius:4px;margin-top:6px}.card-code-header{background:#1e293b;display:flex;justify-content:space-between;align-items:center;padding:8px 14px}.card-code-lang{font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:#6366f1}.card-code-body{background:#0f172a;padding:14px;font-family:Courier New,monospace;font-size:.78rem;line-height:1.8;color:#94a3b8;overflow-x:auto}.card-glass-outer{background:linear-gradient(135deg,#6366f1,#8b5cf6,#ec4899);border-radius:12px;padding:2px}.card-glass-inner{background:#ffffffeb;backdrop-filter:blur(10px);border-radius:10px;padding:16px}.card-badge-band{display:flex;align-items:center;justify-content:space-between;padding:12px 16px}.card-badge-band-label{background:#fff3;color:#fff;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;padding:3px 8px;border-radius:4px}.card-badge-band-icon{font-size:1.4rem}.dm-card-full-bg{background:linear-gradient(160deg,#1e293b,#0f172a);color:#cbd5e1}.dm-card-full-bg .card-body{color:#94a3b8}.dm-card-full-bg .card-title{color:#f1f5f9;font-size:1rem}.dm-card-full-bg .card-footer{border-top-color:#ffffff14;color:#64748b}.card-fc-row{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;border-bottom:1px solid var(--dm-border);font-size:.82rem;color:var(--dm-text-secondary)}.card-fc-row:last-child{border-bottom:none}.card-fc-yes{color:var(--dm-success, #10b981)}.card-fc-no{color:var(--dm-text-disabled, #d1d5db)}@media(max-width:480px){.card-layout-thumb-left,.card-layout-thumb-right,.card-layout-horizontal{flex-direction:column}.card-img-left,.card-img-right,.card-img-wide{width:100%;height:120px}.card-layout-split{flex-direction:column}.card-split-left{width:100%;height:100px}}.hero.hero-dark{background:linear-gradient(135deg,#1f2937,#111827);color:#e2e8f0}.hero .hero-content{position:relative;z-index:2}.hero.hero-left .hero-content{text-align:left;align-items:flex-start;max-width:62%}@media(max-width:768px){.hero.hero-left .hero-content{max-width:100%}}.hero .hero-cta{display:flex;gap:.85rem;flex-wrap:wrap;margin-top:1.75rem}.hero .hero-cta a{display:inline-flex;align-items:center;gap:.4rem;padding:.55rem 1.35rem;border-radius:6px;font-size:.95rem;font-weight:500;text-decoration:none;transition:background .2s ease,border-color .2s ease,transform .15s ease,box-shadow .2s ease}.hero .hero-cta a:first-child{background:#ffffffeb;color:#111;border:1px solid transparent}.hero .hero-cta a:first-child:hover{background:#fff;box-shadow:0 4px 16px #00000040;transform:translateY(-2px)}.hero .hero-cta a:last-child{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4)}.hero .hero-cta a:last-child:hover{border-color:#ffffffbf;background:#ffffff14;transform:translateY(-2px)}.hero .hero-label{display:inline-block;margin-bottom:.9rem;padding:.2rem .8rem;border-radius:999px;font-size:.72rem;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:#ffffffb3;border:1px solid rgba(255,255,255,.22)}.grid-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.dm-breadcrumbs{position:fixed;z-index:200;display:inline-flex;align-items:center;gap:.2rem;padding:.3rem .8rem;border-radius:999px;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);background:#00000047;border:1px solid rgba(255,255,255,.11);box-shadow:0 2px 10px #00000038;font-size:.72rem;font-weight:500;letter-spacing:.01em;line-height:1.4;max-width:calc(100vw - 2rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-breadcrumbs .dm-breadcrumbs-item{color:#ffffffa6}.dm-breadcrumbs .dm-breadcrumbs-link{display:inline-flex;align-items:center;gap:.25rem;color:#ffffff8c;text-decoration:none;transition:color .15s}.dm-breadcrumbs .dm-breadcrumbs-home-icon{flex-shrink:0;vertical-align:middle}.dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#fffffff2}.dm-breadcrumbs .dm-breadcrumbs-current{color:#ffffffeb;font-weight:600}.dm-breadcrumbs .dm-breadcrumbs-separator{color:#ffffff47;font-size:.8em;line-height:1;margin:0 .05rem}body[class*=-light] .dm-breadcrumbs{background:#ffffff8c;border-color:#00000012;box-shadow:0 2px 10px #00000014}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-item,body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-link{color:#0000008c}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#000000e6}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-current{color:#000000d9}body[class*=-light] .dm-breadcrumbs .dm-breadcrumbs-separator{color:#00000040}.dm-collection-display{margin:1.5rem 0}.dm-collection-list{display:flex;flex-direction:column;gap:0}.dm-collection-list-item{padding:1rem 0;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .08))}.dm-collection-list-item:last-child{border-bottom:none}.dm-collection-list-item strong{display:block;font-size:1rem;margin-bottom:.25rem}.dm-collection-list-item p{margin:0;color:var(--dm-text-muted, #888);font-size:.9rem}.dm-collection-empty p{color:var(--dm-text-muted, #888);font-style:italic}.hero-gradient-purple,.hero-gradient-blue,.hero-gradient-green,.hero-gradient-sunset,.hero-gradient-ocean,.hero-gradient-rose,.hero-gradient-forest{background:linear-gradient(135deg,color-mix(in srgb,var(--hero-hue) 22%,var(--dm-background)),color-mix(in srgb,var(--hero-hue) 10%,var(--dm-background)));color:var(--dm-text)}.hero-gradient-purple{--hero-hue: #8b5cf6}.hero-gradient-blue{--hero-hue: #3b82f6}.hero-gradient-green{--hero-hue: #10b981}.hero-gradient-sunset{--hero-hue: #f59e0b}.hero-gradient-ocean{--hero-hue: #0ea5e9}.hero-gradient-rose{--hero-hue: #ec4899}.hero-gradient-forest{--hero-hue: #16a34a}.hero-gradient-night{background:linear-gradient(135deg,#334155,#1e293b);color:#e2e8f0}.hero-gradient-ocean-light{background:linear-gradient(135deg,#e0f2fe,#caf0f8);color:#1e293b}.hero-gradient-ocean-dark{background:linear-gradient(135deg,#0c4a6e,#164e63);color:#e2e8f0}.hero-gradient-forest-light{background:linear-gradient(135deg,#d1fae5,#c6f6dc);color:#1e293b}.hero-gradient-forest-dark{background:linear-gradient(135deg,#1a4731,#166534);color:#e2e8f0}.hero-gradient-sunset-light{background:linear-gradient(135deg,#fde8d8,#fddcc9);color:#1e293b}.hero-gradient-sunset-dark{background:linear-gradient(135deg,#6b3727,#7c4036);color:#f5ede8}.hero-gradient-royal-light{background:linear-gradient(135deg,#e8f0fd,#dce8fc);color:#1e293b}.hero-gradient-royal-dark{background:linear-gradient(135deg,#1e3465,#263d7a);color:#e2e8f0}.hero-gradient-lemon-light{background:linear-gradient(135deg,#fefce8,#fef9c3);color:#1e293b}.hero-gradient-lemon-dark{background:linear-gradient(135deg,#5c4d1a,#6b5920);color:#fefce8}.hero-gradient-silver-light{background:linear-gradient(135deg,#f1f5f9,#e2e8f0);color:#1e293b}.hero-gradient-silver-dark{background:linear-gradient(135deg,#2d3748,#374151);color:#e2e8f0}.hero-gradient-charcoal-light{background:linear-gradient(135deg,#eceff1,#e1e7eb);color:#1e293b}.hero-gradient-charcoal-dark{background:linear-gradient(135deg,#2c3843,#374451);color:#e2e8f0}.hero-gradient-christmas-light{background:linear-gradient(135deg,#fde8ea,#fdd5d8);color:#1e293b}.hero-gradient-christmas-dark{background:linear-gradient(135deg,#5c0f1d,#7a1525);color:#fde8ea}.hero-gradient-unicorn-light{background:linear-gradient(135deg,#f5e8fd,#edd6fb);color:#1e293b}.hero-gradient-unicorn-dark{background:linear-gradient(135deg,#3d1a5a,#4a2068);color:#f5e8fd}.hero-gradient-dreamy-light{background:linear-gradient(135deg,#f5ede8,#eeddd4);color:#1e293b}.hero-gradient-dreamy-dark{background:linear-gradient(135deg,#3d2820,#503328);color:#f5ede8}.hero-gradient-grayve-light{background:linear-gradient(135deg,#e0f7f9,#cbf2f5);color:#1e293b}.hero-gradient-grayve-dark{background:linear-gradient(135deg,#00363d,#00444d);color:#e0f7f9}.hero-gradient-mint-light{background:linear-gradient(135deg,#d8f5ea,#c5efdd);color:#1e293b}.hero-gradient-mint-dark{background:linear-gradient(135deg,#134d33,#195f3f);color:#d8f5ea}.hero-gradient-wedding-light{background:linear-gradient(135deg,#faf3e0,#f5e9c7);color:#1e293b}.hero-gradient-wedding-dark{background:linear-gradient(135deg,#5c4418,#6f5320);color:#faf3e0}.tabs-centered{text-align:center}.tabs-centered .tab-list{display:inline-flex}.tabs-centered .tab-content{text-align:left}.site-main{overflow-x:hidden}@media(max-width:768px){.hero .hero-cta a,.dm-so-trigger,.dm-cta-trigger{min-height:44px;padding:.6rem 1.25rem}}.dm-banner{position:relative;display:flex;flex-direction:row;align-items:flex-start;gap:.75rem;padding:.85rem 2.5rem .85rem 1rem;border-radius:var(--dm-radius-md, 6px);border-left:4px solid transparent;margin-bottom:1rem}.dm-banner__icon{flex-shrink:0;margin-top:.1rem;width:1.15rem;height:1.15rem}.dm-banner__icon svg{width:1.15rem;height:1.15rem}.dm-banner__body{flex:1;min-width:0}.dm-banner__title{display:block;margin-bottom:.2rem;font-size:.9em;font-weight:600}.dm-banner__dismiss{position:absolute;top:.5rem;right:.5rem;background:transparent;border:none;cursor:pointer;font-size:1.1rem;line-height:1;padding:.1rem .3rem;opacity:.6}.dm-banner__dismiss:hover{opacity:1}.dm-banner--info{background:color-mix(in srgb,var(--dm-info, #3b82f6) 12%,transparent);border-left-color:var(--dm-info, #3b82f6);color:inherit}.dm-banner--success{background:color-mix(in srgb,var(--dm-success, #22c55e) 12%,transparent);border-left-color:var(--dm-success, #22c55e);color:inherit}.dm-banner--warning{background:color-mix(in srgb,var(--dm-warning, #f59e0b) 12%,transparent);border-left-color:var(--dm-warning, #f59e0b);color:inherit}.dm-banner--danger{background:color-mix(in srgb,var(--dm-danger, #ef4444) 12%,transparent);border-left-color:var(--dm-danger, #ef4444);color:inherit}.dm-banner--neutral{background:color-mix(in srgb,var(--dm-text-muted, #888) 12%,transparent);border-left-color:var(--dm-text-muted, #888);color:inherit}body.dm-layout-narrow .page-body{max-width:768px;margin-inline:auto}body.dm-layout-normal .page-body{max-width:1100px;margin-inline:auto}body.dm-layout-wide .page-body{max-width:min(75vw,2000px);margin-inline:auto}body.dm-layout-full .page-body{max-width:none}.hero h1{font-size:clamp(2.4rem,4.5vw,3.75rem);font-weight:900;line-height:1.08;letter-spacing:-.03em}.hero-gradient-dreamy-light h1{color:#1e293b}.hero-gradient-dreamy-light p{font-size:1.125rem;line-height:1.7;color:#1e293bcc;max-width:48ch}.page-body h2{font-weight:800;letter-spacing:-.025em}.page-body h3{font-weight:700;letter-spacing:-.015em}.hero-gradient-dreamy-light .hero-cta a:first-child{background:#1e293b!important;color:#f5ede8!important;border-color:#1e293b!important}.hero-gradient-dreamy-light .hero-cta a:first-child:hover{background:#0f172a!important;color:#fff!important}.hero-gradient-dreamy-light .hero-cta a:last-child{background:transparent!important;color:#1e293b!important;border:1px solid rgba(30,41,59,.45)!important}.hero-gradient-dreamy-light .hero-cta a:last-child:hover{background:#1e293b14!important;border-color:#1e293bb3!important}.card[data-hover=true]{transition:transform .22s ease,box-shadow .22s ease!important;will-change:transform}.card[data-hover=true]:hover{transform:translateY(-5px)!important;box-shadow:0 24px 64px #0003,0 8px 24px #0000001f!important}.card-icon{font-size:2.5rem!important;margin-bottom:12px!important;opacity:.95}.card-avatar-wrap{padding:20px 16px 12px!important;gap:.5rem}.mk-card-icon-wrap,.card-icon-wrap{width:3rem;height:3rem;border-radius:.75rem;background:#ffffff2e;display:flex;align-items:center;justify-content:center;margin-bottom:1.125rem;font-size:1.3rem;flex-shrink:0;box-shadow:0 2px 8px #0000001f}.mk-card-corner-badge,.card-corner-badge{position:absolute;top:1rem;right:1rem;background:linear-gradient(135deg,#f59e0b,#d97706);color:#fff;font-size:.6875rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;padding:.25rem .7rem;border-radius:99px;box-shadow:0 2px 10px #f59e0b73}.card-premium .card-subtitle{display:inline-block!important;font-size:.6875rem!important;font-weight:700!important;letter-spacing:.07em!important;text-transform:uppercase!important;opacity:1!important;color:#fff!important;background:linear-gradient(135deg,#f59e0b,#d97706)!important;padding:.2rem .65rem!important;border-radius:99px!important;box-shadow:0 2px 8px #f59e0b66!important;margin-bottom:.75rem!important}.mk-card-badge-band,.card-badge-band{display:inline-flex;align-items:center;gap:.35rem;font-size:.6875rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;padding:.2rem .6rem;border-radius:99px;margin-bottom:.875rem;background:#fff3;border:1px solid rgba(255,255,255,.3)}.mk-card-stars,.card-stars{color:#f59e0b;font-size:1rem;letter-spacing:.12em;margin-bottom:.75rem}.mk-card-reviewer,.card-reviewer{display:flex;flex-direction:column;gap:.15rem;margin-top:1rem;padding-top:1rem;border-top:1px solid rgba(255,255,255,.15)}.mk-card-reviewer-name,.card-reviewer-name{font-weight:700;font-size:.9375rem}.mk-card-reviewer-role,.card-reviewer-role{font-size:.8125rem;opacity:.65}.mk-banner.type-info,[class*=banner-info],.mk-banner[data-type=info]{border-left:4px solid var(--dm-primary, #5c3d2e)}.mk-banner.type-success,[class*=banner-success],.mk-banner[data-type=success]{border-left:4px solid var(--dm-success, #22c55e)}.mk-banner.type-warning,[class*=banner-warning],.mk-banner[data-type=warning]{border-left:4px solid var(--dm-warning, #f59e0b)}.mk-stat-number{font-size:5rem;font-weight:900;line-height:1;letter-spacing:-.03em;color:var(--dm-primary, #5c3d2e)}.mk-stat-label{font-size:.9375rem;font-weight:600;opacity:.65;margin-top:.5rem;letter-spacing:.02em;text-transform:uppercase}.mk-footer-inner{max-width:1200px;margin:0 auto;padding:3rem 2rem 1.5rem}.mk-footer-columns{display:grid;grid-template-columns:repeat(4,1fr);gap:2rem;margin-bottom:2.5rem}@media(max-width:900px){.mk-footer-columns{grid-template-columns:repeat(2,1fr)}}@media(max-width:480px){.mk-footer-columns{grid-template-columns:1fr}}.mk-footer-col-title{font-size:.75rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;opacity:.5;margin:0 0 .75rem}.mk-footer-col-links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}.mk-footer-col-links a{font-size:.875rem;opacity:.75;text-decoration:none;transition:opacity .15s}.mk-footer-col-links a:hover{opacity:1}.mk-footer-bottom{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;padding-top:1.5rem;border-top:1px solid var(--dm-border, rgba(0, 0, 0, .08))}.mk-footer-copyright{font-size:.8125rem;opacity:.5;margin:0}.mk-footer-bottom-right{display:flex;align-items:center;gap:1.25rem}.mk-footer-social{display:flex;gap:.75rem}.mk-footer-social-link{opacity:.5;transition:opacity .15s;font-size:1.125rem}.mk-footer-social-link:hover{opacity:1}.mk-motion-label{display:flex;align-items:center;gap:.4rem;font-size:.75rem;opacity:.5;cursor:pointer;user-select:none}.mk-motion-label:hover{opacity:.75}.dm-static-block{display:contents}.mk-window{border-radius:10px;overflow:hidden;box-shadow:0 16px 56px #0000002e,0 4px 16px #0000001a;background:#fff;border:1px solid rgba(0,0,0,.06)}.mk-window-bar{background:#e8e8e8;padding:10px 16px;display:flex;gap:7px;align-items:center}.mk-dot{width:12px;height:12px;border-radius:50%;flex-shrink:0}.mk-dot-red{background:#ff5f57}.mk-dot-amber{background:#febc2e}.mk-dot-green{background:#28c840}.mk-window-body img{width:100%;display:block;max-height:480px;object-fit:cover;object-position:top}.dm-static-block+p{margin-top:.5rem}.navbar-link.active{opacity:1!important;font-weight:700!important;position:relative}.navbar-link.active:after{content:"";position:absolute;bottom:-3px;left:0;right:0;height:2px;background:currentColor;border-radius:2px;opacity:.6}.mk-divider{border:none;border-top:1px solid var(--dm-border-light, rgba(0, 0, 0, .07));margin:0}.page-body .mk-tabs,.page-body .tabs-wrapper,.page-body>.tabs{padding-left:1.5rem;padding-right:1.5rem}.mk-section-label,.section-label{display:inline-block;font-size:.75rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:.3rem .875rem;border-radius:99px;margin-bottom:1.125rem;background:color-mix(in srgb,var(--dm-primary, #5c3d2e) 10%,transparent);color:var(--dm-primary, #5c3d2e);border:1px solid color-mix(in srgb,var(--dm-primary, #5c3d2e) 20%,transparent)}.page-body .btn-primary,.page-body a.btn-primary{background-color:var(--dm-primary, #8d6e63)!important;color:var(--dm-text-inverse, #ffffff)!important;border:1px solid var(--dm-primary, #8d6e63)!important;text-decoration:none!important;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.page-body .btn-primary:hover,.page-body a.btn-primary:hover{background-color:var(--dm-primary-hover, #6d4c41)!important;color:var(--dm-text-inverse, #ffffff)!important;border-color:var(--dm-primary-hover, #6d4c41)!important;text-decoration:none!important}.page-body .btn-outline,.page-body a.btn-outline{background-color:transparent!important;color:var(--dm-primary, #8d6e63)!important;border:1.5px solid var(--dm-primary, #8d6e63)!important;text-decoration:none!important;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.page-body .btn-outline:hover,.page-body a.btn-outline:hover{background-color:var(--dm-primary, #8d6e63)!important;color:var(--dm-text-inverse, #ffffff)!important;border-color:var(--dm-primary, #8d6e63)!important;text-decoration:none!important}.page-body .btn-ghost,.page-body a.btn-ghost{background-color:transparent!important;color:var(--dm-primary, #8d6e63)!important;border:1px solid transparent!important;text-decoration:none!important;transition:background-color .15s ease,color .15s ease}.page-body .btn-ghost:hover,.page-body a.btn-ghost:hover{background-color:var(--dm-primary-light, rgba(141, 110, 99, .1))!important;color:var(--dm-primary-hover, #6d4c41)!important;text-decoration:none!important}.mk-card-step-number,.card-step-number{font-size:3rem;font-weight:900;line-height:1;letter-spacing:-.04em;opacity:.25;margin-bottom:.75rem}.mk-card-step-title,.card-step-title{font-size:1rem;font-weight:700;margin-bottom:.5rem}.card[data-badge=Enterprise] .mk-card-corner-badge,.card[data-badge=Enterprise] .card-corner-badge{background:linear-gradient(135deg,#1e293b,#334155);box-shadow:0 2px 10px #1e293b80}.card-badge-band-icon{font-size:1.75rem!important}.card-badge-band{padding:14px 18px!important;gap:.5rem}.card-badge-band-label{font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}.card-title{font-size:1.2rem!important;font-weight:800!important;letter-spacing:-.015em!important;line-height:1.25!important;margin-bottom:.4rem!important;color:var(--dm-text, #f1f5f9)!important}.card-subtitle{font-size:.8125rem!important;opacity:.7!important;margin-bottom:.5rem!important;font-weight:500!important;color:var(--dm-text, #f1f5f9)!important}.mk-card-body p,.card-body p,.card>p{font-size:.9375rem;line-height:1.65;opacity:.88}.card-gradient-purple{background:linear-gradient(135deg,#ede9fe,#ddd6fe)!important;color:#1e1b4b!important}.card-gradient-blue{background:linear-gradient(135deg,#dbeafe,#bfdbfe)!important;color:#1e3a5f!important}.card-gradient-green{background:linear-gradient(135deg,#d1fae5,#a7f3d0)!important;color:#064e3b!important}.card-gradient-night{background:linear-gradient(135deg,#334155,#1e293b)!important;color:#e2e8f0!important}.card-gradient-ocean-light{background:linear-gradient(135deg,#e0f2fe,#caf0f8)!important;color:#1e293b!important}.card-gradient-ocean-dark{background:linear-gradient(135deg,#0c4a6e,#164e63)!important;color:#e2e8f0!important}.card-gradient-forest-light{background:linear-gradient(135deg,#d1fae5,#c6f6dc)!important;color:#1e293b!important}.card-gradient-forest-dark{background:linear-gradient(135deg,#1a4731,#166534)!important;color:#e2e8f0!important}.card-gradient-sunset-light{background:linear-gradient(135deg,#fde8d8,#fddcc9)!important;color:#1e293b!important}.card-gradient-sunset-dark{background:linear-gradient(135deg,#6b3727,#7c4036)!important;color:#f5ede8!important}.card-gradient-royal-light{background:linear-gradient(135deg,#e8f0fd,#dce8fc)!important;color:#1e293b!important}.card-gradient-royal-dark{background:linear-gradient(135deg,#1e3465,#263d7a)!important;color:#e2e8f0!important}.card-gradient-lemon-light{background:linear-gradient(135deg,#fefce8,#fef9c3)!important;color:#1e293b!important}.card-gradient-lemon-dark{background:linear-gradient(135deg,#5c4d1a,#6b5920)!important;color:#fefce8!important}.card-gradient-silver-light{background:linear-gradient(135deg,#f1f5f9,#e2e8f0)!important;color:#1e293b!important}.card-gradient-silver-dark{background:linear-gradient(135deg,#2d3748,#374151)!important;color:#e2e8f0!important}.card-gradient-charcoal-light{background:linear-gradient(135deg,#eceff1,#e1e7eb)!important;color:#1e293b!important}.card-gradient-charcoal-dark{background:linear-gradient(135deg,#2c3843,#374451)!important;color:#e2e8f0!important}.card-gradient-christmas-light{background:linear-gradient(135deg,#fde8ea,#fdd5d8)!important;color:#1e293b!important}.card-gradient-christmas-dark{background:linear-gradient(135deg,#5c0f1d,#7a1525)!important;color:#fde8ea!important}.card-gradient-unicorn-light{background:linear-gradient(135deg,#f5e8fd,#edd6fb)!important;color:#1e293b!important}.card-gradient-unicorn-dark{background:linear-gradient(135deg,#3d1a5a,#4a2068)!important;color:#f5e8fd!important}.card-gradient-dreamy-light{background:linear-gradient(135deg,#f5ede8,#eeddd4)!important;color:#1e293b!important}.card-gradient-dreamy-dark{background:linear-gradient(135deg,#3d2820,#503328)!important;color:#f5ede8!important}.card-gradient-grayve-light{background:linear-gradient(135deg,#e0f7f9,#cbf2f5)!important;color:#1e293b!important}.card-gradient-grayve-dark{background:linear-gradient(135deg,#00363d,#00444d)!important;color:#e0f7f9!important}.card-gradient-mint-light{background:linear-gradient(135deg,#d8f5ea,#c5efdd)!important;color:#1e293b!important}.card-gradient-mint-dark{background:linear-gradient(135deg,#134d33,#195f3f)!important;color:#d8f5ea!important}.card-gradient-wedding-light{background:linear-gradient(135deg,#faf3e0,#f5e9c7)!important;color:#1e293b!important}.card-gradient-wedding-dark{background:linear-gradient(135deg,#5c4418,#6f5320)!important;color:#faf3e0!important}.card-gradient-slate{--dm-card-g-start: #475569;--dm-card-g-end: #1e293b}.card-gradient-dusk{--dm-card-g-start: #7c3aed;--dm-card-g-end: #db2777}.card-gradient-sunset{--dm-card-g-start: #f59e0b;--dm-card-g-end: #ec4899}.card-gradient-rose{--dm-card-g-start: #fb7185;--dm-card-g-end: #e11d48}.card-gradient-gold{--dm-card-g-start: #f59e0b;--dm-card-g-end: #b45309}.card-gradient-fire{--dm-card-g-start: #ef4444;--dm-card-g-end: #fbbf24}.page-body .card.dm-card-gradient.card-gradient-sunset .card-header,.page-body .card.dm-card-gradient.card-gradient-rose .card-header,.page-body .card.dm-card-gradient.card-gradient-gold .card-header,.page-body .card.dm-card-gradient.card-gradient-fire .card-header{color:#1e293b!important}.page-body .card.dm-card-gradient[class*=-light] .card-header,.page-body .card.dm-card-gradient[class*=-dark] .card-header,.page-body .card.dm-card-gradient.card-gradient-purple .card-header,.page-body .card.dm-card-gradient.card-gradient-blue .card-header,.page-body .card.dm-card-gradient.card-gradient-green .card-header,.page-body .card.dm-card-gradient.card-gradient-night .card-header{background:transparent!important;color:inherit!important;border-bottom:1px solid rgba(0,0,0,.08)}.card[class*=card-gradient-] .card-title,.card[class*=card-gradient-] .card-subtitle{color:inherit!important}.card[class*=gradient] .mk-window-bar,.card[data-gradient] .mk-window-bar{background:#00000040}.card[class*=gradient] .mk-dot-red{background:#ff5f57b3}.card[class*=gradient] .mk-dot-amber{background:#febc2eb3}.card[class*=gradient] .mk-dot-green{background:#28c840b3}.hero .card .mk-listgroup-item,.hero .card .list-group-item{padding-top:.45rem;padding-bottom:.45rem;font-size:.9rem}.card .dm-static-block{display:block;width:100%}.card .mk-window{margin-bottom:0}.wf-feature{display:flex;align-items:center;gap:14px;padding:14px 16px;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:8px;box-shadow:0 1px 3px #0f172a0a;transition:border-color .15s ease,box-shadow .15s ease,transform .15s ease}.wf-feature:hover{border-color:var(--dm-border-dark, #475569);box-shadow:0 6px 18px #0f172a14;transform:translateY(-1px)}.wf-feature-icon{flex-shrink:0;width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:8px;font-size:1.1rem}.wf-feature-text{font-size:.9rem;font-weight:500;color:var(--dm-text, #1e293b);line-height:1.4;flex:1 1 auto}.plugin-card{display:flex;flex-direction:column;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:12px;overflow:hidden;box-shadow:0 2px 6px #0f172a0d;text-decoration:none!important;color:inherit!important;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;height:100%;min-height:340px}.plugin-card:hover{transform:translateY(-3px);box-shadow:0 18px 40px #0f172a1f;border-color:var(--dm-border-dark, #475569)}.plugin-card-cover{position:relative;width:100%;height:150px;background-size:cover;background-position:center;background-color:var(--dm-background-alt, #e2e8f0);flex-shrink:0}.plugin-card-cover:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,#0000001a,#0f172a8c)}.plugin-card-tier-badge{position:absolute;top:12px;right:12px;z-index:2;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;padding:4px 10px;border-radius:20px;color:#1e293b;background:#fff;box-shadow:0 2px 8px #0f172a40}.plugin-card[data-tier=free] .plugin-card-tier-badge:before{content:"Free"}.plugin-card[data-tier=premium] .plugin-card-tier-badge:before{content:"Premium"}.plugin-card[data-tier=premium] .plugin-card-tier-badge{color:#f1f5f9;background:linear-gradient(135deg,#475569,#1e293b)}.plugin-card-body{flex:1 1 auto;padding:20px;display:flex;flex-direction:column;gap:10px;background:var(--dm-card-bg, #fff);color:var(--dm-text, #1e293b)}.plugin-card-head{display:flex;align-items:center;gap:12px}.plugin-card-icon{flex-shrink:0;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:10px;font-size:1.3rem;box-shadow:0 2px 6px #0f172a2e}.plugin-card-title{font-size:1.15rem!important;font-weight:700!important;color:var(--dm-text, #1e293b)!important;line-height:1.2!important;margin:0!important}.plugin-card-desc{font-size:.88rem!important;color:var(--dm-text-secondary, #475569)!important;line-height:1.5!important;margin:0!important;flex:1 1 auto}.plugin-card-cta{display:inline-flex;align-items:center;gap:4px;font-size:.82rem;font-weight:600;color:var(--dm-text-secondary, #475569);margin-top:8px;transition:color .15s ease,gap .15s ease}.plugin-card:hover .plugin-card-cta{color:var(--dm-text, #1e293b);gap:8px}.page-body a:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):not([data-menu-hover] a):not([data-menu-active] a){color:var(--dm-primary, var(--dm-text, #5d4037))!important;text-decoration:underline;text-decoration-color:var(--dm-border, rgba(0, 0, 0, .2));text-underline-offset:3px;text-decoration-thickness:1.5px;transition:color .15s ease,text-decoration-color .15s ease}.page-body a:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):not([data-menu-hover] a):not([data-menu-active] a):hover{color:var(--dm-primary-hover, var(--dm-text, #3e2723))!important;text-decoration-color:var(--dm-primary, currentColor)}.page-body .dm-card-gradient .card-body a:not([class*=btn]){color:var(--dm-primary, var(--dm-text, #5d4037))!important}.page-body .dm-card-gradient .card-body a:not([class*=btn]):hover{color:var(--dm-primary-hover, var(--dm-text, #3e2723))!important}html body .page-body a[href]:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):not(.dm-breadcrumbs-link):not([data-menu-hover] a):not([data-menu-active] a){color:var(--dm-primary, #8d6e63)!important}html body .page-body a[href]:not([class*=btn]):not(.plugin-card):not([class*=nav]):not([class*=footer]):not(.dm-breadcrumbs-link):not([data-menu-hover] a):not([data-menu-active] a):hover{color:var(--dm-primary-hover, #6d4c41)!important}.page-body .hero-cta:not(.hero .hero-cta) a:not([class*=btn]),.page-body>* .hero-cta a:not([class*=btn]){color:var(--dm-primary, #8d6e63)!important;text-decoration:none!important;background:transparent;border:1px solid var(--dm-border, rgba(141, 110, 99, .35));padding:.55rem 1.35rem;border-radius:6px;font-weight:500;display:inline-flex;align-items:center;gap:.4rem;transition:background .15s ease,border-color .15s ease,color .15s ease}.page-body .hero-cta:not(.hero .hero-cta) a:not([class*=btn]):hover,.page-body>* .hero-cta a:not([class*=btn]):hover{color:var(--dm-primary-hover, #6d4c41)!important;background:var(--dm-primary-light, rgba(141, 110, 99, .08));border-color:var(--dm-primary, #8d6e63)}.feature-image{width:100%;max-height:420px;object-fit:cover;border-radius:12px;box-shadow:0 12px 36px #0f172a26;display:block}.page-body .grid>.col:has(>.feature-image),.page-body .grid>.col:has(.reveal>.feature-image),.page-body .grid>.col:has(.feature-image){display:flex;flex-direction:column;justify-content:center}.code-label{display:inline-flex;align-items:center;gap:8px;font-family:Fira Code,Consolas,Monaco,monospace;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:#f1f5f9bf;background:#0f172a8c;padding:6px 12px;border-radius:6px 6px 0 0;border-bottom:1px solid rgba(241,245,249,.12)}.code-label+.code-block{margin-top:0!important;border-top-left-radius:0;border-top-right-radius:0}.code-block{display:block;background:#0f172a!important;color:#e2e8f0!important;padding:18px 20px!important;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.55;margin:0 0 20px;box-shadow:inset 0 0 0 1px #f1f5f914;white-space:pre;font-family:Fira Code,Consolas,Monaco,Courier New,monospace}.code-block code{background:transparent!important;color:inherit!important;padding:0!important;font-family:inherit!important;font-size:inherit;white-space:pre;display:block}.page-body .card-body>pre>code,.page-body .card-body pre.code-block>code{color:#e2e8f0!important}.run-option-card{display:flex;flex-direction:column;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:14px;overflow:hidden;box-shadow:0 4px 14px #0f172a14;height:100%;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}.run-option-card:hover{transform:translateY(-3px);box-shadow:0 20px 48px #0f172a24;border-color:var(--dm-border-dark, #475569)}.run-option-banner{position:relative;width:100%;height:180px;background-size:cover;background-position:center;background-color:var(--dm-background-alt, #e2e8f0);flex-shrink:0}.run-option-banner:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,#0f172a1a,#0f172ab3)}.run-option-icon-chip{position:absolute;bottom:-26px;left:24px;z-index:2;width:56px;height:56px;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:14px;font-size:1.6rem;box-shadow:0 8px 20px #0f172a4d;border:3px solid var(--dm-card-bg, #fff)}.run-option-card-body{flex:1 1 auto;padding:40px 24px 24px;display:flex;flex-direction:column;gap:10px}.run-option-title{font-size:1.5rem!important;font-weight:800!important;color:var(--dm-text, #1e293b)!important;margin:0!important;line-height:1.15!important;letter-spacing:-.01em!important}.run-option-sub{font-size:.9rem!important;font-weight:600!important;color:var(--dm-primary, #5d4037)!important;margin:0 0 8px!important;text-transform:uppercase;letter-spacing:.06em}.run-option-content{flex:1 1 auto;font-size:.92rem;line-height:1.55;color:var(--dm-text-secondary, #475569)}.run-option-content p{margin:0 0 12px}.run-option-content .run-option-intro{font-size:.98rem;color:var(--dm-text, #1e293b);font-weight:500;margin-bottom:16px}.run-option-content .run-option-body-label{font-size:.82rem;text-transform:uppercase;letter-spacing:.08em;color:var(--dm-primary, #5d4037);margin-bottom:8px}.run-option-content .run-option-req{font-size:.82rem;color:var(--dm-text-muted, #64748b);margin-top:14px}.run-option-content .code-block{margin:8px 0 14px}.run-option-list{list-style:none;padding:0;margin:0 0 14px;display:flex;flex-direction:column;gap:8px}.run-option-list li{display:flex;align-items:center;gap:10px;font-size:.9rem;color:var(--dm-text, #1e293b)}.run-option-list li [data-icon]{color:var(--dm-primary, #5d4037);flex-shrink:0}.run-option-ctas{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px;padding-top:20px;border-top:1px solid var(--dm-border, #e2e8f0)}.run-option-ctas .btn{flex:1 1 auto;text-align:center;white-space:nowrap;min-width:fit-content}.quickstart-step{position:relative;padding:28px 22px 24px;background:var(--dm-card-bg, #ffffff);border:1px solid var(--dm-card-border, #e2e8f0);border-radius:12px;box-shadow:0 2px 8px #0f172a0d;overflow:hidden;height:100%;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}.quickstart-step:hover{transform:translateY(-3px);box-shadow:0 16px 36px #0f172a1f;border-color:var(--dm-border-dark, #475569)}.quickstart-step-number{position:absolute;top:8px;right:14px;font-size:5rem;font-weight:900;line-height:1;color:color-mix(in srgb,var(--dm-text) 8%,transparent);font-variant-numeric:tabular-nums;pointer-events:none;user-select:none}.quickstart-step-icon{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#475569,#1e293b);color:#f1f5f9;border-radius:10px;font-size:1.3rem;margin-bottom:14px;box-shadow:0 4px 12px #0f172a2e;position:relative;z-index:1}.quickstart-step-title{font-size:1.1rem!important;font-weight:800!important;color:var(--dm-text, #1e293b)!important;margin:0 0 8px!important;line-height:1.2!important;letter-spacing:-.01em!important;position:relative;z-index:1}.quickstart-step-desc{font-size:.86rem;line-height:1.55;color:var(--dm-text-secondary, #475569);margin:0;position:relative;z-index:1}:not(:defined){visibility:hidden}.dm-collection-browser{display:block;margin:1.5rem 0}.dm-collection-browser.dm-cb-hydrated .dm-cb-fallback{display:none}.dm-cb-header{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:space-between;margin-bottom:1rem}.dm-cb-search{flex:1 1 240px;min-width:200px}.dm-cb-search-input{width:100%;padding:.5rem .75rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);color:var(--dm-text, #111827);font-size:.95rem}.dm-cb-sort{display:flex;align-items:center;gap:.5rem;flex:0 0 auto}.dm-cb-sort-label{font-size:.85rem;color:var(--dm-text-muted, #6b7280);margin:0}.dm-cb-sort-select{padding:.45rem .6rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);color:var(--dm-text, #111827)}.dm-cb-sort-dir{width:2rem;height:2rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);cursor:pointer;font-weight:700}.dm-cb-sort-dir:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-layout{display:grid;grid-template-columns:minmax(220px,1fr) 3fr;gap:1.5rem;align-items:start}@media(max-width:768px){.dm-cb-layout{grid-template-columns:1fr}.dm-cb-filter-rail{border:1px solid var(--dm-border, #e5e7eb);border-radius:var(--dm-radius-md, 6px);padding:.75rem}}.dm-cb-filter-rail{padding:.5rem 0;font-size:.92rem}.dm-cb-filter-heading{margin:0 0 .75rem;font-size:.95rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--dm-text-muted, #6b7280)}.dm-cb-filter{margin-bottom:1rem;display:flex;flex-direction:column;gap:.35rem}.dm-cb-filter-label{font-weight:600;font-size:.85rem;color:var(--dm-text, #111827)}.dm-cb-text,.dm-cb-select,.dm-cb-range input{width:100%;padding:.4rem .55rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px);background:var(--dm-background, #fff);color:var(--dm-text, #111827);font-size:.9rem}.dm-cb-range{display:flex;align-items:center;gap:.4rem}.dm-cb-range input{flex:1;min-width:0}.dm-cb-multiselect{display:flex;flex-direction:column;gap:.3rem;max-height:11rem;overflow-y:auto;padding:.4rem .55rem;border:1px solid var(--dm-border, #d1d5db);border-radius:var(--dm-radius-md, 6px)}.dm-cb-check{display:flex;align-items:center;gap:.4rem;font-size:.88rem;cursor:pointer;margin:0}.dm-cb-filter-reset{width:100%;margin-top:.5rem;padding:.45rem .6rem;border:1px solid var(--dm-border, #d1d5db);background:transparent;color:var(--dm-text, #374151);border-radius:var(--dm-radius-md, 6px);cursor:pointer;font-size:.85rem}.dm-cb-filter-reset:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-body{min-height:4rem}.dm-cb-pagination{display:flex;align-items:center;justify-content:center;gap:1rem;margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--dm-border, #e5e7eb)}.dm-cb-page-info{font-size:.88rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-page-prev[disabled],.dm-cb-page-next[disabled]{opacity:.45;cursor:not-allowed}.dm-cb-chips{display:flex;flex-wrap:wrap;gap:.35rem;padding:.1rem 0}.dm-cb-chip{display:inline-flex;align-items:center;gap:.4rem;padding:.25rem .6rem;border:1px solid var(--dm-border, #d1d5db);background:var(--dm-background, #fff);color:var(--dm-text, #111827);border-radius:999px;cursor:pointer;font-size:.82rem;transition:background-color .12s ease,border-color .12s ease}.dm-cb-chip:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-chip-active{background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);border-color:var(--dm-primary, #2563eb)}.dm-cb-chip-count{font-size:.75rem;opacity:.75;font-variant-numeric:tabular-nums}.dm-cb-chip-active .dm-cb-chip-count{opacity:.85}.dm-cb-slider{position:relative;height:1.5rem;margin:.5rem .25rem}.dm-cb-slider-track{position:absolute;top:50%;left:0;right:0;transform:translateY(-50%);height:4px;background:var(--dm-border, #e5e7eb);border-radius:2px}.dm-cb-slider-fill{position:absolute;top:0;bottom:0;background:var(--dm-primary, #2563eb);border-radius:2px}.dm-cb-slider-handle{position:absolute;inset:0;width:100%;height:100%;margin:0;background:transparent;pointer-events:none;-webkit-appearance:none;appearance:none}.dm-cb-slider-handle::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;height:1rem;width:1rem;border-radius:50%;background:var(--dm-primary, #2563eb);border:2px solid var(--dm-background, #fff);box-shadow:0 1px 3px #00000026;pointer-events:auto;cursor:grab}.dm-cb-slider-handle::-moz-range-thumb{height:1rem;width:1rem;border-radius:50%;background:var(--dm-primary, #2563eb);border:2px solid var(--dm-background, #fff);box-shadow:0 1px 3px #00000026;pointer-events:auto;cursor:grab}.dm-cb-range-inputs{display:flex;gap:.4rem;align-items:center}.dm-cb-saved{position:relative}.dm-cb-saved-menu{position:absolute;right:0;top:calc(100% + .25rem);min-width:12rem;padding:.5rem;background:var(--dm-background, #fff);border:1px solid var(--dm-border, #e5e7eb);border-radius:var(--dm-radius-md, 6px);box-shadow:0 8px 24px #0f172a1f;z-index:20}.dm-cb-saved-empty{margin:0 0 .5rem;font-size:.85rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-saved-item{display:flex;align-items:center;gap:.4rem;margin-bottom:.25rem}.dm-cb-saved-apply{flex:1;text-align:left;padding:.35rem .5rem;background:transparent;border:0;border-radius:var(--dm-radius-md, 6px);cursor:pointer;font-size:.88rem;color:var(--dm-text, #111827)}.dm-cb-saved-apply:hover{background:var(--dm-background-alt, #f3f4f6)}.dm-cb-saved-del{width:1.5rem;height:1.5rem;padding:0;background:transparent;border:0;color:var(--dm-text-muted, #9ca3af);cursor:pointer;font-size:1.1rem}.dm-cb-saved-del:hover{color:var(--dm-danger, #dc2626)}.dm-cb-saved-actions{border-top:1px solid var(--dm-border, #e5e7eb);padding-top:.5rem;margin-top:.5rem}.dm-cb-saved-create{width:100%;padding:.45rem .6rem;font-size:.85rem}.dm-cb-export{padding:.45rem .7rem;font-size:.85rem}.dm-cb-empty-clear{margin-top:.75rem}.dm-cb-scroll-sentinel{text-align:center;padding:1rem 0;font-size:.85rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-scroll-end{text-align:center;margin:1rem 0 0;font-size:.85rem;color:var(--dm-text-muted, #9ca3af);font-style:italic}.dm-cb-block-loading{text-align:center;padding:2rem 0;color:var(--dm-text-muted, #9ca3af);font-style:italic}.dm-cb-drawer-toggle{display:none;align-items:center;gap:.4rem;padding:.45rem .75rem;font-size:.88rem}.dm-cb-drawer-count{font-variant-numeric:tabular-nums;font-weight:600;color:var(--dm-primary, #2563eb)}.dm-cb-drawer-count:empty{display:none}@media(max-width:768px){.dm-cb-drawer-toggle{display:inline-flex}.dm-cb-filter-rail{position:fixed;top:0;left:-100%;width:85%;max-width:22rem;height:100vh;background:var(--dm-background, #fff);border-right:1px solid var(--dm-border, #e5e7eb);box-shadow:4px 0 16px #00000014;padding:1.25rem;z-index:100;overflow-y:auto;transition:left .22s ease}.dm-cb-drawer-open .dm-cb-filter-rail{left:0}.dm-cb-drawer-open:before{content:"";position:fixed;inset:0;background:#00000059;z-index:99}}.dm-file-thumb{max-width:180px;max-height:120px;border-radius:var(--dm-radius-md, 6px);border:1px solid var(--dm-border, #e5e7eb);display:inline-block;object-fit:cover}.dm-cb-transitions{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.5rem;font-size:.85rem;color:var(--dm-text-muted, #6b7280)}.dm-cb-transitions:empty{display:none}.dm-cb-transition-btn{padding:.35rem .7rem;font-size:.82rem}.dm-menu-sep,.footer-sep{list-style:none}.dm-menu-sep hr,.footer-sep hr{border:0;border-top:1px solid var(--dm-border, rgba(128, 128, 128, .35));margin:.4rem 0}.dm-menu-spacer{list-style:none;pointer-events:none;padding:0;margin:0;border:0}.dm-menu-spacer--xs{height:var(--dm-space-1, .25rem)}.dm-menu-spacer--sm{height:var(--dm-space-2, .5rem)}.dm-menu-spacer--md{height:var(--dm-space-4, 1rem)}.dm-menu-spacer--lg{height:var(--dm-space-6, 1.5rem)}.dm-menu-spacer--xl{height:var(--dm-space-10, 2.5rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--xs,.navbar-nav>.dm-menu-spacer--xs{height:auto;width:var(--dm-space-1, .25rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--sm,.navbar-nav>.dm-menu-spacer--sm{height:auto;width:var(--dm-space-2, .5rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--md,.navbar-nav>.dm-menu-spacer--md{height:auto;width:var(--dm-space-4, 1rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--lg,.navbar-nav>.dm-menu-spacer--lg{height:auto;width:var(--dm-space-6, 1.5rem)}.dm-menu--horizontal>ul>.dm-menu-spacer--xl,.navbar-nav>.dm-menu-spacer--xl{height:auto;width:var(--dm-space-10, 2.5rem)}.dm-menu--has-flex-spacer>ul{display:flex;flex-direction:column}.dm-menu--has-flex-spacer.dm-menu--horizontal>ul{flex-direction:row;align-items:center}.dm-menu-spacer--flex{flex:1 1 auto;height:auto;width:auto}.dm-menu-floating .dm-menu-spacer--flex{min-height:var(--dm-space-4, 1rem)}@media(max-width:768px){.dm-menu--has-flex-spacer.dm-menu--horizontal>ul{flex-wrap:wrap}}#site-navbar .navbar-dropdown-divider{background:var(--dm-border, rgba(128, 128, 128, .5));opacity:.8}.dm-menu-badge{display:inline-block;margin-left:6px;padding:1px 7px;font-size:.7em;font-weight:700;line-height:1.4;border-radius:999px;background:var(--dm-text-muted);color:var(--dm-text-inverse, #fff);vertical-align:middle}.dm-nav-pill{border-radius:999px;padding:6px 14px;font-weight:600}.dm-nav-pill--outline{background:transparent!important;border:1px solid currentColor}@media(max-width:992px){#site-navbar .navbar-toggle{order:0;margin-right:var(--dm-space-2)}#site-navbar .navbar-brand{order:1}#site-navbar .navbar-collapse{position:fixed;top:0;left:0;bottom:0;width:86vw;max-width:340px;z-index:1100;margin:0;padding:var(--dm-space-3) 0 var(--dm-space-6);background:var(--dm-navbar-bg, var(--dm-surface));border-top:none;border-right:1px solid var(--dm-border);box-shadow:4px 0 18px #00000059;transform:translate(-100%);transition:transform .25s ease;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}#site-navbar .navbar-collapse.show{transform:translate(0)}body.dm-drawer-open #site-navbar{z-index:1100}#site-navbar .navbar-nav{max-height:none;overflow:visible}#site-navbar .navbar-dropdown-toggle{display:flex;align-items:center;justify-content:space-between;width:100%;padding:var(--dm-space-3) var(--dm-space-4);font-size:var(--dm-font-size-base)}#site-navbar .navbar-caret{margin-left:auto;flex:none;width:16px;height:16px;opacity:.9}#site-navbar .navbar-dropdown-menu{position:static;display:none;min-width:0;width:100%;margin:0;padding:0;border:0;border-radius:0;box-shadow:none;background:color-mix(in srgb,var(--dm-text) 8%,transparent)}#site-navbar .navbar-dropdown.open>.navbar-dropdown-menu{display:block}#site-navbar .navbar-dropdown-item{padding-left:calc(var(--dm-space-4) + var(--dm-space-5))}.dm-navbar-backdrop{position:fixed;inset:0;z-index:1090;background:#00000073;border:0;padding:0;cursor:pointer}body.dm-drawer-open{overflow:hidden}}.dm-embed{margin:1.5rem 0}.dm-embed-frame{overflow:hidden;border-radius:8px;background:#000}.dm-embed-caption{margin-top:.5rem;font-size:.85rem;color:var(--dm-text-muted, #6b7280);text-align:center}.dm-embed-blocked{margin:1.5rem 0;padding:.75rem 1rem;border:1px dashed var(--dm-border, #d1d5db);border-radius:8px;background:var(--dm-background-alt, #f9fafb);color:var(--dm-text-muted, #6b7280);font-size:.9rem}.dm-menu-missing{margin:1rem 0;padding:.6rem .9rem;border:1px dashed var(--dm-border, #d1d5db);border-radius:8px;background:var(--dm-background-alt, #f9fafb);color:var(--dm-text-muted, #6b7280);font-size:.9rem}.dm-embed-blocked code{font-family:var(--dm-font-mono, monospace);font-size:.85em}.dm-menu-floating{overflow:auto;overscroll-behavior:contain;background:var(--dm-surface);color:var(--dm-text);border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 8px);box-shadow:var(--dm-shadow-lg);scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}.dm-menu-floating[style*=--dm-menu-accent]{border-left:3px solid var(--dm-menu-accent)}.dm-menu-floating[data-float-anchor=TR][style*=--dm-menu-accent],.dm-menu-floating[data-float-anchor=BR][style*=--dm-menu-accent],.dm-menu-floating[data-float-anchor=R][style*=--dm-menu-accent]{border-left:1px solid var(--dm-menu-accent);border-right:3px solid var(--dm-menu-accent)}.dm-menu-floating[style*=--dm-menu-panel-opacity]{background:color-mix(in srgb,var(--dm-surface) calc(var(--dm-menu-panel-opacity) * 100%),transparent);backdrop-filter:blur(8px)}.dm-menu-float-bar{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dm-space-2, .5rem);padding:var(--dm-space-2, .5rem) var(--dm-space-3, .75rem);background:inherit;border-bottom:1px solid var(--dm-border);border-radius:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0}.dm-menu-float-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;font-weight:600;letter-spacing:.02em;color:var(--dm-text-muted, #6b7280)}.dm-menu-float-grip{flex:0 0 auto;width:10px;height:16px;background-image:radial-gradient(currentColor 1px,transparent 1px);background-size:5px 5px;background-position:0 2px;color:var(--dm-text-muted, #6b7280);opacity:.6}.dm-menu-floating[data-float-movable] .dm-menu-float-bar{cursor:grab}.dm-menu-floating.is-dragging,.dm-menu-floating.is-dragging .dm-menu-float-bar{cursor:grabbing}.dm-menu-floating.is-dragging{user-select:none}.dm-menu-floating[data-float-movable] .dm-menu-float-bar{touch-action:none}.dm-menu-float-toggle{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:0;border-radius:var(--dm-radius-sm, 4px);background:transparent;color:var(--dm-text);cursor:pointer}.dm-menu-float-toggle:hover{background:var(--dm-surface-alt, rgba(0, 0, 0, .06))}.dm-menu-float-toggle:focus-visible{outline:2px solid var(--dm-primary);outline-offset:1px}.dm-menu-float-icon{position:relative;width:16px;height:2px;background:currentColor;border-radius:1px}.dm-menu-float-icon:before,.dm-menu-float-icon:after{content:"";position:absolute;left:0;width:100%;height:2px;background:currentColor;border-radius:1px}.dm-menu-float-icon:before{top:-5px}.dm-menu-float-icon:after{top:5px}.dm-menu-floating.is-collapsed{width:auto!important;max-height:none!important;overflow:visible;padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none;resize:none;min-width:0;min-height:0}.dm-menu-floating.is-collapsed>*:not(.dm-menu-float-bar),.dm-menu-floating.is-collapsed .dm-menu-float-grip,.dm-menu-floating.is-collapsed .dm-menu-float-title{display:none}#site-navbar.dm-menu-floating.is-collapsed>*:not(.dm-menu-float-bar){display:none}#site-navbar.dm-menu-floating.is-collapsed{width:auto!important;max-height:none!important;padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none}.dm-menu-floating.is-collapsed .dm-menu-float-bar{padding:0;border:0;background:transparent;cursor:default}.dm-menu-floating.is-collapsed .dm-menu-float-toggle{width:44px;height:44px;border-radius:50%;background:var(--dm-surface);border:1px solid var(--dm-menu-accent, var(--dm-border));box-shadow:var(--dm-shadow-lg)}.navbar-transparent,.dm-menu--variant-transparent,.dm-menu-floating.navbar-transparent,.dm-menu-floating.dm-menu--variant-transparent{background:transparent;border-color:transparent;box-shadow:none;backdrop-filter:none}.navbar-transparent.is-collapsed .dm-menu-float-toggle,.dm-menu--variant-transparent.is-collapsed .dm-menu-float-toggle{background:var(--dm-surface)}.navbar-transparent .dm-menu-float-bar,.dm-menu--variant-transparent .dm-menu-float-bar{border-bottom-color:transparent}.dm-menu-floating[data-float-resizable]:not(.is-collapsed){resize:both;min-width:120px;min-height:48px}@media(max-width:768px){.dm-menu-floating{position:static!important;inset:auto!important;width:auto!important;max-height:none!important;transform:none!important;resize:none!important}.dm-menu-floating[data-float-movable] .dm-menu-float-bar{cursor:default}.dm-menu-floating[data-float-movable] .dm-menu-float-grip{display:none}}.dm-menu--vertical ul,.dm-menu--horizontal ul{list-style:none;margin:0;padding:0}.dm-menu--vertical>ul{display:flex;flex-direction:column;gap:2px}.dm-menu--vertical>ul>li>a{display:block;padding:.4rem .75rem;border-radius:var(--dm-radius-md, 6px);text-decoration:none}.dm-menu--vertical>ul>li>a:hover{background:color-mix(in srgb,var(--dm-text) 8%,transparent)}.dm-menu--vertical ul ul{margin-left:.75rem;border-left:1px solid var(--dm-border, rgba(128, 128, 128, .35));padding-left:.4rem}.dm-menu--horizontal>ul{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem 1rem}.dm-menu--horizontal>ul>li{position:relative}.dm-menu--horizontal>ul>li>a{display:inline-block;padding:.35rem .5rem;text-decoration:none}.dm-menu--horizontal>ul>li>ul{position:absolute;top:100%;left:0;z-index:40;display:none;min-width:180px;padding:.35rem 0;background:var(--dm-surface);border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 8px);box-shadow:var(--dm-shadow-lg)}.dm-menu--horizontal>ul>li:hover>ul,.dm-menu--horizontal>ul>li:focus-within>ul{display:block}.dm-menu--horizontal>ul>li>ul a{display:block;padding:.35rem .9rem;text-decoration:none}@media(max-width:768px){.dm-menu--horizontal>ul{flex-direction:column;align-items:stretch}.dm-menu--horizontal>ul>li>ul{position:static;display:block;border:0;box-shadow:none;padding-left:.75rem}}:root{--dm-vnav-width: 240px}@media(min-width:993px){#site-navbar.dm-nav-vertical:not(.dm-menu-floating){position:fixed;top:0;bottom:0;height:100vh;height:100dvh;width:var(--dm-vnav-width);flex-direction:column;flex-wrap:nowrap;align-items:stretch;justify-content:flex-start;gap:var(--dm-space-2);padding:var(--dm-space-4) var(--dm-space-3);overflow-y:auto;overscroll-behavior:contain;border-bottom:none;z-index:100}#site-navbar.dm-nav-vertical-left:not(.dm-menu-floating){left:0;right:auto;border-right:1px solid var(--dm-border)}#site-navbar.dm-nav-vertical-right:not(.dm-menu-floating){right:0;left:auto;border-left:1px solid var(--dm-border)}body.dm-vnav-left{padding-left:var(--dm-vnav-width)}body.dm-vnav-right{padding-right:var(--dm-vnav-width)}#site-navbar.dm-nav-vertical .navbar-container{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:var(--dm-space-2);width:100%;min-height:100%;padding:0;margin:0}#site-navbar.dm-nav-vertical .navbar-toggle{display:none!important}#site-navbar.dm-nav-vertical .navbar-brand{padding:0 var(--dm-space-2) var(--dm-space-3);margin:0;width:100%}#site-navbar.dm-nav-vertical .navbar-collapse{display:flex!important;flex-direction:column!important;align-items:stretch!important;width:100%!important;flex-grow:1!important;padding:0!important;border:none!important}#site-navbar.dm-nav-vertical .navbar-nav{display:flex!important;flex-direction:column!important;align-items:stretch!important;justify-content:flex-start!important;gap:2px!important;width:100%!important;flex:none!important;margin:0!important;padding:0!important}#site-navbar.dm-nav-vertical .navbar-nav li,#site-navbar.dm-nav-vertical .navbar-nav .navbar-item{width:100%!important;display:block!important}#site-navbar.dm-nav-vertical .navbar-link,#site-navbar.dm-nav-vertical .navbar-dropdown-toggle{display:flex!important;align-items:center!important;justify-content:flex-start!important;gap:var(--dm-space-2)!important;width:100%!important;padding:var(--dm-space-2) var(--dm-space-3)!important;font-size:var(--dm-font-size-sm)!important;text-align:left!important;border-radius:var(--dm-radius-md)!important;white-space:normal!important}#site-navbar.dm-nav-vertical .navbar-link:hover,#site-navbar.dm-nav-vertical .navbar-dropdown-toggle:hover{background-color:color-mix(in srgb,var(--dm-text) 8%,transparent)}#site-navbar.dm-nav-vertical .navbar-dropdown-toggle .navbar-caret{margin-left:auto}#site-navbar.dm-nav-vertical .navbar-dropdown{position:static!important;width:100%!important}#site-navbar.dm-nav-vertical .navbar-dropdown-menu{position:static!important;display:none;width:100%!important;min-width:0!important;margin:0!important;padding:0!important;border:0!important;border-radius:0!important;box-shadow:none!important;background:color-mix(in srgb,var(--dm-text) 8%,transparent)!important}#site-navbar.dm-nav-vertical .navbar-dropdown.open>.navbar-dropdown-menu{display:block!important}#site-navbar.dm-nav-vertical .navbar-dropdown-item{display:block!important;width:100%!important;padding:var(--dm-space-2) var(--dm-space-3) var(--dm-space-2) calc(var(--dm-space-3) + var(--dm-space-5))!important}#site-navbar.dm-nav-vertical .navbar-actions{display:flex;flex-direction:column;align-items:stretch;margin-left:0;margin-top:auto;padding-top:var(--dm-space-3)}}@media print{body.dm-ctx-printing *{visibility:hidden}body.dm-ctx-printing [data-dm-print],body.dm-ctx-printing [data-dm-print] *{visibility:visible}body.dm-ctx-printing [data-dm-print]{position:absolute;left:0;top:0;width:100%}body.dm-ctx-printing [data-dm-print] .accordion-content{display:block!important;height:auto!important}body.dm-ctx-printing .dm-ctx-hidden{display:none!important}}
|
package/public/js/menu-decor.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PRESET_COLOUR_VARS={primary:"--dm-primary",success:"--dm-success",danger:"--dm-danger",warning:"--dm-warning",info:"--dm-info",neutral:"--dm-text-muted"};const
|
|
1
|
+
export const PRESET_COLOUR_VARS={primary:"--dm-primary",success:"--dm-success",danger:"--dm-danger",warning:"--dm-warning",info:"--dm-info",neutral:"--dm-text-muted"};const l=/^#[0-9a-fA-F]{6}$/;export function colourToCss(t){return typeof t!="string"?"":PRESET_COLOUR_VARS[t]?`var(${PRESET_COLOUR_VARS[t]})`:l.test(t)?t:""}export const FLOAT_ANCHORS=["TL","TR","BL","BR","L","R"],FLOAT_DEFAULTS={anchor:"TL",offsetX:16,offsetY:16,zIndex:150},FLOAT_SHADOWS={none:"none",sm:"var(--dm-shadow-sm)",md:"var(--dm-shadow-md)",lg:"var(--dm-shadow-lg)",xl:"var(--dm-shadow-xl)"};function s(t,o,e,r){const n=Number(t);return Number.isFinite(n)?Math.min(r,Math.max(e,Math.round(n))):o}function f(t){const o=[];if(t.radius!=null&&t.radius!==""&&o.push(`border-radius:${s(t.radius,8,0,48)}px`),t.shadow!=null&&t.shadow!==""&&Object.prototype.hasOwnProperty.call(FLOAT_SHADOWS,t.shadow)&&o.push(`box-shadow:${FLOAT_SHADOWS[t.shadow]}`),t.accent&&colourToCss(t.accent)){const e=colourToCss(t.accent);o.push(`--dm-menu-accent:${e}`,`border-color:${e}`)}return t.opacity!=null&&t.opacity!==""&&o.push(`--dm-menu-panel-opacity:${s(t.opacity,100,20,100)/100}`),o}export function floatToCss(t){if(!t||t.position!=="floating")return"";const o=t.float&&typeof t.float=="object"&&!Array.isArray(t.float)?t.float:{},e=FLOAT_ANCHORS.includes(o.anchor)?o.anchor:FLOAT_DEFAULTS.anchor,r=s(o.offsetX,FLOAT_DEFAULTS.offsetX,0,4e3),n=s(o.offsetY,FLOAT_DEFAULTS.offsetY,0,4e3),a=["position:fixed",`z-index:${s(o.zIndex,FLOAT_DEFAULTS.zIndex,0,2147483647)}`];return e==="L"||e==="R"?(a.push("top:50%","transform:translateY(-50%)"),a.push(e==="L"?`left:${r}px`:`right:${r}px`)):(a.push(e[0]==="T"?`top:${n}px`:`bottom:${n}px`),a.push(e[1]==="L"?`left:${r}px`:`right:${r}px`)),o.width!=null&&o.width!==""&&a.push(`width:${s(o.width,260,120,600)}px`),a.push(`max-height:calc(100vh - ${e==="L"||e==="R"?32:n*2}px)`),a.push(...f(o)),a.join(";")}export const FLOAT_FLAGS=["collapsible","collapsed","movable","resizable"];export function floatBehaviour(t){const o={collapsible:!1,collapsed:!1,movable:!1,resizable:!1,chrome:!1,title:""};if(!t||t.position!=="floating")return o;const e=t.float&&typeof t.float=="object"&&!Array.isArray(t.float)?t.float:{},r={collapsible:!!e.collapsible,collapsed:!!e.collapsible&&!!e.collapsed,movable:!!e.movable,resizable:!!e.resizable},n=r.collapsible||r.movable,i=typeof e.title=="string"&&e.title!==""?e.title:t.name||"";return{...r,chrome:n,title:n?i:""}}export function applyFloat(t,o){const e=floatToCss(o);if(!t||!e)return!1;t.style.cssText+=";"+e,t.classList.add("dm-menu-floating"),o.slug&&!t.hasAttribute("data-menu")&&t.setAttribute("data-menu",o.slug),o.float?.anchor&&t.setAttribute("data-float-anchor",o.float.anchor);const r=floatBehaviour(o);for(const n of FLOAT_FLAGS)n!=="collapsed"&&r[n]&&t.setAttribute(`data-float-${n}`,"1");return r.collapsed&&t.setAttribute("data-float-collapsed","1"),r.title&&t.setAttribute("data-float-title",r.title),!0}export function makeBadgeEl(t){if(!t||t.text==null||t.text==="")return null;const o=document.createElement("span");o.className="dm-menu-badge",o.textContent=String(t.text);const e=t.variant?colourToCss(t.variant):"";return e&&(o.style.background=e,o.style.color="var(--dm-text-inverse, #fff)"),o}export function applyColour(t,o){const e=colourToCss(o);e&&(t.style.color=e)}export function applyPill(t,o){if(!o)return;t.classList.add("dm-nav-pill");const e=o.variant?colourToCss(o.variant):"";o.style==="outline"?(t.classList.add("dm-nav-pill--outline"),e&&(t.style.borderColor=e,t.style.color=e)):e&&(t.style.background=e,t.style.color="#fff")}export const HIGHLIGHT_HOVER=["none","colour","underline","overline","background","uppercase","grow","breathe","glow"],HIGHLIGHT_ACTIVE=["none","bold","underline","overline","background","darken","pill"],LEGACY_STYLE_HOVER={none:"none",underline:"underline",overline:"overline",transform:"uppercase","text-transform":"uppercase",breathe:"breathe"},LEGACY_STYLE_ACTIVE={none:"none",darken:"darken",background:"background","background-color":"background",underline:"underline",overline:"overline"};export function legacyStyleHighlight(t){const o=t&&typeof t=="object"&&!Array.isArray(t)?t:{};return{hover:LEGACY_STYLE_HOVER[o.hover]||"",active:LEGACY_STYLE_ACTIVE[o.active]||""}}export function highlightAttrs(t){const o=t&&t.highlight&&typeof t.highlight=="object"&&!Array.isArray(t.highlight)?t.highlight:{},e=legacyStyleHighlight(t&&t.style);return{hover:HIGHLIGHT_HOVER.includes(o.hover)?o.hover:e.hover,active:HIGHLIGHT_ACTIVE.includes(o.active)?o.active:e.active,accent:o.accent?colourToCss(o.accent):""}}export function applyHighlight(t,o){if(!t)return!1;const{hover:e,active:r,accent:n}=highlightAttrs(o);return e&&t.setAttribute("data-menu-hover",e),r&&t.setAttribute("data-menu-active",r),n&&t.style.setProperty("--dm-menu-highlight",n),!!(e||r||n)}function c(t){if(typeof t!="string"||!t)return"";const o=t.split("#")[0].split("?")[0];return o.startsWith("/")?o.length>1&&o.endsWith("/")?o.slice(0,-1):o:""}export function isCurrentItem(t,o){const e=c(t),r=c(o);return!!e&&!!r&&e===r}
|
package/public/js/site.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{makeBadgeEl as z,applyColour as M,applyPill as O,applyFloat as j}from"/public/js/menu-decor.mjs?v=20260829-float-panel";import{initFloatingMenus as B}from"/public/js/menu-float.js?v=20260829-float-panel";import{enhancePickerFields as N,markInvalidFields as P,showValidationPopup as R}from"/public/js/forms.js?v=20260821-wizard-grid";import{buildWizardSteps as V}from"/public/js/form-steps.mjs";$(()=>{const w=window.__CMS_NAV__||{},h=window.__CMS_SITE__||{};if(h.autoTheme?.enabled){let t=function(n){const e=(n||"07:00").split(":");return+e[0]*60+(+e[1]||0)},a=function(){const n=new Date,e=n.getHours()*60+n.getMinutes();return e>=t(o.dayStart)&&e<t(o.nightStart)?o.dayTheme:o.nightTheme};const o=h.autoTheme;Domma.theme.set(a()),setInterval(()=>Domma.theme.set(a()),6e4)}const C=$("#site-navbar");if(C.length&&w.brand){let a=function(i,c=0){return Array.isArray(i)?i.filter(s=>!(s&&s.type==="spacer")).filter(s=>!(s&&s.type==="separator"&&c===0)).map(s=>s&&s.type==="separator"?{divider:!0}:Array.isArray(s?.items)?{...s,items:a(s.items,c+1)}:s):i},n=function(i){return Array.isArray(i)?i.filter(c=>!(c&&(c.type==="separator"||c.type==="spacer"))):[]};const o={...w.brand},t=o.size&&o.size!=="md"?` navbar-brand-${o.size}`:"";if(o.logo||o.icon||o.tagline){let i="";o.logo?i+=`<img src="${o.logo}" class="navbar-brand-logo" alt="${o.text||""}">`:o.icon&&(i+=`<span data-icon="${o.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),o.text&&(i+=`<span class="navbar-brand-text${t}">${o.text}</span>`),o.tagline&&(i+=`<small class="navbar-brand-tagline">${o.tagline}</small>`),o.html=i}else t&&o.text&&(o.html=`<span class="navbar-brand-text${t}">${o.text}</span>`);const e=w.position==="floating",u=w.orientation==="vertical";Domma.elements.navbar("#site-navbar",{brand:o,items:a(w.items||[]),variant:w.variant||"dark",position:e?"static":w.position||"sticky",collapsible:!0,appearOnHover:!!w.appearOnHover}),Domma.icons.scan("#site-navbar"),u&&C.get(0).classList.add("dm-nav-vertical",w.side==="right"?"dm-nav-vertical-right":"dm-nav-vertical-left"),e&&(j(C.get(0),w),B(C.get(0).parentNode||document));const g=C.get(0),y=g.querySelector(".navbar-toggle"),f=g.querySelector(".navbar-collapse");if(y&&f){let i=null;const c=()=>{f.classList.contains("show")&&y.click()},s=()=>{i&&(i.remove(),i=null),document.body.classList.remove("dm-drawer-open")},r=()=>{i||(i=document.createElement("div"),i.className="dm-navbar-backdrop",i.addEventListener("click",c),document.body.appendChild(i),document.body.classList.add("dm-drawer-open"))};y.addEventListener("click",()=>{requestAnimationFrame(()=>{f.classList.contains("show")?r():s()})}),f.addEventListener("click",l=>{l.target.closest("a")&&requestAnimationFrame(s)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&f.classList.contains("show")&&c()})}const d=g.querySelector(".navbar-nav");if(d){const i=Array.from(d.children);let c=0;for(const s of w.items||[])if(!(s&&s.type==="separator")){if(s&&s.type==="spacer"){const r=document.createElement("li"),l=["xs","sm","md","lg","xl","flex"].includes(s.size)?s.size:"md";r.className=`dm-menu-spacer dm-menu-spacer--${l}`,r.setAttribute("aria-hidden","true"),d.insertBefore(r,i[c]||null);continue}c++}}const b=n(w.items||[]);g.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(i=>{const c=b[parseInt(i.dataset.index,10)];if(!c)return;const s=i.dataset.subindex!=null,r=s&&Array.isArray(c.items)?c.items[parseInt(i.dataset.subindex,10)]:c;if(!r)return;r.colour&&M(i,r.colour),r.pill&&!s&&O(i,r.pill);const l=z(r.badge);l&&i.appendChild(l)})}const x=$("#site-footer");if(x.length){let e=function(r){return String(r??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},u=function(r){return e(r).replace(/'/g,"'")},g=function(r){if(r&&r.type==="separator")return'<li class="footer-sep"><hr></li>';if(r&&r.type==="spacer")return`<li class="dm-menu-spacer dm-menu-spacer--${["xs","sm","md","lg","xl","flex"].includes(r.size)?r.size:"md"}" aria-hidden="true"></li>`;const l=u(r.url||"#"),m=e(r.text||""),v=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(g).join("")}</ul>`:"";return`<li><a href="${l}">${m}</a>${v}</li>`},y=function(r,l){return(r||[]).forEach(m=>{m&&(m.type==="separator"||m.type==="spacer")||(l.push(m),Array.isArray(m.items)&&m.items.length&&y(m.items,l))}),l};const o=h.social||{},t={twitter:{label:"X / Twitter",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.742l7.73-8.835L1.254 2.25H8.08l4.259 5.629L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>'},facebook:{label:"Facebook",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'},instagram:{label:"Instagram",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>'},linkedin:{label:"LinkedIn",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'},github:{label:"GitHub",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>'},youtube:{label:"YouTube",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/></svg>'}};let a='<div class="footer-inner container">';const n=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""};if(n.copyright&&(a+=`<p>${e(n.copyright)}</p>`),n.primary.length&&(a+=`<nav class="footer-nav footer-nav--primary"><ul>${n.primary.map(g).join("")}</ul></nav>`),n.legal.length&&(a+=`<nav class="footer-nav footer-nav--legal"><ul>${n.legal.map(g).join("")}</ul></nav>`),h.footer){const r=Object.keys(t).filter(l=>o[l]);r.length&&(a+='<div class="footer-social">',r.forEach(l=>{const{label:m,svg:v}=t[l];a+=`<a href="${o[l]}" target="_blank" rel="noopener noreferrer" aria-label="${m}" class="footer-social-link">${v}</a>`}),a+="</div>")}a+="</div>",x.html(a);const f=[...y(n.primary,[]),...y(n.legal,[])];x.get(0).querySelectorAll(".footer-nav a").forEach((r,l)=>{const m=f[l];if(!m)return;m.colour&&M(r,m.colour);const v=z(m.badge);v&&r.appendChild(v)});const b=h.footer?.showMotionToggle!==!1,i=S.get("reduced_motion"),c=i!==null?!!i:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),s=x.get(0).querySelector(".footer-inner");if(b&&s){const r=document.createElement("input");r.type="checkbox",r.className="form-switch-input",r.id="dm-motion-switch",r.checked=c,r.addEventListener("change",function(){S.set("reduced_motion",this.checked),window.location.reload()});const l=document.createElement("span");l.className="form-switch-label",l.textContent="Reduce motion";const m=document.createElement("label");m.className="form-switch footer-motion-switch",m.title="Reduce motion",m.appendChild(r),m.appendChild(l),s.appendChild(m)}}$("#site-sidebar").length&&Domma.elements.sidebar("#site-sidebar",{autoGenerate:!0,selector:"h2, h3",collapsible:!1,push:!0,contentSelector:".site-content"}),Domma.icons.scan(),Domma.syntax?.scan&&Domma.syntax.scan();const p=$(".page-body");if(p.length){p.find(".accordion").each(function(){Domma.elements.accordion(this,{allowMultiple:this.dataset.multi==="true"})}),p.find(".tabs").each(function(){Domma.elements.tabs(this)}),p.find(".carousel").each(function(){const o={autoplay:this.dataset.autoplay==="true",interval:parseInt(this.dataset.interval,10)||5e3,loop:this.dataset.loop!=="false",animation:this.dataset.animation||"slide"};if(this.dataset.animationDuration){const t=parseInt(this.dataset.animationDuration,10);Number.isFinite(t)&&(o.animationDuration=t)}this.dataset.animationEasing&&(o.animationEasing=this.dataset.animationEasing),this.dataset.ctx&&(this._dmCtxSlides=Array.from(this.querySelectorAll(".carousel-slide")).map(t=>t.cloneNode(!0)),this._dmCarouselOpts=o),this._dmCarousel=Domma.elements.carousel(this,o)}),p.find(".dm-countdown").each(function(){const o={autoStart:!0};this.dataset.to&&(o.targetDate=new Date(this.dataset.to)),this.dataset.duration&&(o.duration=parseInt(this.dataset.duration,10)),this.dataset.format&&(o.format=this.dataset.format),Domma.elements.timer(this,o)}),p.find("[data-tooltip]").each(function(){Domma.elements.tooltip(this,{content:$(this).data("tooltip"),position:$(this).data("tooltip-position")||"top"})}),p.find(".dm-progression").each(function(){const o=Array.from(this.querySelectorAll(".dm-progression-item")).map(n=>{const e={title:n.querySelector(".dm-progression-item-title")?.textContent?.trim()||"",description:n.querySelector(".dm-progression-item-body")?.innerHTML?.trim()||""};return n.dataset.date&&(e.date=n.dataset.date),n.dataset.status&&(e.status=n.dataset.status),n.dataset.entryId&&(e._entryId=n.dataset.entryId),e}),t=this.dataset.layout==="centred"?"centered":this.dataset.layout||"vertical",a=Domma.elements.progression(this,{layout:t,theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0,allowHtml:!0,...o.length?{items:o}:{}});o.length&&(this._dmCtx={instance:a,items:o})});try{Domma.effects.reveal(".page-body .hero",{animation:"slide-up",duration:480,threshold:.06,stagger:60,once:!1})}catch{}document.querySelectorAll(".page-body .row[data-reveal]").forEach(o=>{const t=o.dataset.revealMode||"stagger",a=o.dataset.revealAnimation||"slide-up",n=parseInt(o.dataset.revealDuration,10)||400,e=parseInt(o.dataset.revealStagger,10)||60,u=parseInt(o.dataset.revealDelay,10)||0,g=o.dataset.revealDirection==="rtl",y=Array.from(o.children),f={"slide-up":"translateY(30px)","slide-down":"translateY(-30px)","slide-left":"translateX(30px)","slide-right":"translateX(-30px)",zoom:"scale(0.85)",flip:"perspective(600px) rotateX(15deg)"};y.forEach((d,b)=>{d.style.opacity="0",d.style.transform=f[a]||"",d.style.transition=`opacity ${n}ms ease, transform ${n}ms ease`;const i=g?y.length-1-b:b;d.style.transitionDelay=t==="stagger"?`${u+i*e}ms`:`${u}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const d=new IntersectionObserver(b=>{b.forEach(i=>{i.isIntersecting&&(i.target.offsetWidth,i.target.style.opacity="1",i.target.style.transform="none",d.unobserve(i.target))})},{threshold:.1});y.forEach(b=>d.observe(b))}))}),p.find(".card[data-collapsible]").each(function(){const o=this.querySelector(".card-header");o&&o.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),p.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const o=this.dataset.soTarget,t=document.getElementById(o);if(!t)return;const a=E.slideover({title:t.dataset.soTitle||"",size:t.dataset.soSize||"md",position:t.dataset.soPosition||"right"});t.style.display="",a.setContent(t),a.open()})})}if(typeof $.setup=="function"){const o=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(t=>{try{const a=atob(t.dataset.config),n=JSON.parse(a);Object.assign(o,n)}catch{}}),Object.keys(o).length>0){const t={};for(const[a,n]of Object.entries(o)){const e=n?.events?.click,{confirm:u,toast:g,alert:y,prompt:f,...d}=e||{};u||g||y||f?($(a).on("click",async function(i){if(i.preventDefault(),u&&!await E.confirm(u))return;let c=null;if(!(f&&(c=await E.prompt(f,{inputPlaceholder:d.promptPlaceholder||"",inputValue:d.promptDefault||""}),c===null))){if(d.target){const s=$(d.target);d.toggleClass&&s.toggleClass(d.toggleClass),d.addClass&&s.addClass(d.addClass),d.removeClass&&s.removeClass(d.removeClass),c!==null&&(d.setText&&s.text(c),d.setVal&&s.val(c),d.setAttr&&s.attr(d.setAttr,c))}d.href&&(window.location.href=d.href),g&&E.toast(g,{type:d.toastType||"success"}),y&&E.alert(y)}}),Object.keys(d).length&&(t[a]={...n,events:{...n.events,click:d}})):t[a]=n}$.setup(t)}}p.length&&D(p.get(0))});function D(w){w.querySelectorAll(".dm-cta-trigger").forEach(h=>{h.__ctaWired||(h.__ctaWired=!0,h.addEventListener("click",async()=>{const C=h.dataset.action,x=h.dataset.entry,k=h.dataset.confirm;let p=S.get("auth_token");if(!p){E.toast("Please log in to perform this action.",{type:"warning"});return}if(k&&!await E.confirm(k))return;const o=Array.from(h.childNodes).map(a=>a.cloneNode(!0));h.disabled=!0,h.textContent="Running\u2026";const t=a=>fetch(`/api/actions/${C}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({entryId:x})});try{let a=await t(p);if(a.status===401){const e=S.get("auth_refresh_token");if(e){const u=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(u.ok){const{token:g}=await u.json();S.set("auth_token",g),p=g,a=await t(p)}}}const n=await a.json().catch(()=>({}));if(!a.ok)throw new Error(n.error||n.message||`Error ${a.status}`);E.toast(n.message||"Action completed.",{type:"success"})}catch(a){E.toast(a.message||"Action failed.",{type:"error"})}finally{h.disabled=!1,h.textContent="",o.forEach(a=>h.appendChild(a)),Domma.icons.scan(h)}}))})}(function(){const h=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!h.length)return;const C=S.get("auth_token");function x(p,o){const t=document.createElement("div");t.className="dm-collection-display dm-collection-empty";const a=document.createElement("p");if(o){a.appendChild(document.createTextNode("Please "));const n=document.createElement("a");n.href="/login",n.textContent="sign in",a.appendChild(n),a.appendChild(document.createTextNode(" to view your entries."))}else a.textContent=p;return t.appendChild(a),t}function k(p,o){const t=document.createElement("template");t.innerHTML=o||"",p.replaceWith(t.content)}h.forEach(async p=>{const o=p.dataset.collectionAttrs;if(!o)return;if(!C){p.replaceChildren(x("",!0));return}const t=a=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({attrs:o})});try{let a=C,n=await t(a);if(n.status===401){const u=S.get("auth_refresh_token");if(u){const g=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:u})});if(g.ok){const{token:y}=await g.json();S.set("auth_token",y),a=y,n=await t(a)}}}if(!n.ok){const{error:u}=await n.json().catch(()=>({}));p.replaceChildren(x(u||"Unable to load entries.",!1));return}const{html:e}=await n.json();k(p,e)}catch{p.replaceChildren(x("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),D(document.body)},100)})(),(function(){const h=document.querySelectorAll("[data-collection-table]");!h.length||typeof T>"u"||!T.create||h.forEach(C=>{let x;try{x=JSON.parse(atob(C.dataset.payload))}catch{return}const{columns:k,rows:p,search:o,sortable:t,exportable:a,pageSize:n,empty:e,ctaConfig:u,slug:g,exportCfg:y}=x;if(!k?.length)return;if(u){const b=k.findIndex(i=>i.key==="_cta");b!==-1&&(k[b]={key:"_cta",title:"",render:(i,c)=>{const s=document.createElement("button");if(s.className=`btn btn-${u.style||"primary"} dm-cta-trigger`,s.dataset.action=u.action||"",s.dataset.entry=c._entryId||"",u.confirm&&(s.dataset.confirm=u.confirm),u.icon){const r=document.createElement("span");r.dataset.icon=u.icon,s.appendChild(r),s.appendChild(document.createTextNode(" "))}return s.appendChild(document.createTextNode(u.label||"Run")),s}})}const f="col-table-"+Math.random().toString(36).slice(2,7),d=document.createElement("div");d.id=f,C.replaceChildren(d),T.create("#"+f,{data:p,columns:k,search:o,sortable:t,exportable:a,pageSize:n,emptyMessage:e}),u&&D(d),C._dmTable={columns:k,rows:p,slug:g,exportCfg:y,render(b){T.create("#"+f,{data:b,columns:k,search:o,sortable:t,exportable:a,pageSize:n,emptyMessage:e}),u&&D(d)}}})})(),(function(){const h=document.querySelectorAll("[data-form-inline]");if(!h.length||typeof F>"u")return;function C(t){const a=t&&t.logic;return!!(a&&(a.visibility||a.requirement))}function x(t,a){const n={};return(t||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const u=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),g=e.type==="checkbox"?"boolean":e.type==="date"||e.type==="icon"||e.type==="image"?"string":u?"chooser":e.type,y={...e.formConfig||{}};y.span==="full"&&a&&(y.span=a);const f={type:g,required:C(e)?!1:e.required,label:e.label,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...y}};u&&(e.variant&&(f.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(f.multiple=!0),e.density&&(f.density=e.density),e.columns&&(f.columns=e.columns),e.accent&&(f.accent=e.accent),e.accentStyle&&(f.accentStyle=e.accentStyle),e.glow&&(f.glow=!0),e.glowColour&&(f.glowColour=e.glowColour),e.shadow&&(f.shadow=e.shadow),e.shadowColour&&(f.shadowColour=e.shadowColour)),n[e.name]=f}),n}function k(t){const a={};return(t||[]).forEach(n=>{if(!(!n.name||n.type==="page-break"||n.type==="spacer")&&(n.type==="select"||n.type==="multiselect")&&n.required){const e=(n.options||[])[0];e&&(a[n.name]=typeof e=="object"?e.value:e)}}),a}function p(t,a){(a||[]).forEach(n=>{if(n.type!=="date"||!n.name)return;const e=t.querySelector(`[name="${n.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function o(t,a,n){let e=t.querySelector(".cms-form-message");e||(e=document.createElement("p"),e.className="cms-form-message",t.appendChild(e)),e.textContent=a,e.style.cssText=n?"color:var(--dm-danger);margin-top:.75rem;":"color:var(--dm-success);margin-top:.75rem;"}h.forEach(t=>{let a;try{a=JSON.parse(atob(t.dataset.formInline))}catch{return}const n=a.fields||[],e=a.settings||{},u=Number(e.columns)===3?3:2,g=e.layout||"grid",y=n.some(c=>c.type==="page-break"),f=async c=>{try{const s=t.querySelector(".fb-form-honeypot"),r=s?.querySelector('input[type="text"]')||null,l=s?.querySelector('[name="_t"]')||null,m=Object.assign({},c);delete m._t,s?.dataset.hpName&&delete m[s.dataset.hpName],r!==null&&(m._hp=r.value),l!==null&&(m._t=l.value);const v=await H.post(`/api/forms/submit/${a.slug}`,m);if(v&&v.error){o(t,v.error,!0);const A=new Error(v.error);throw A.formSubmitFailed=!0,A}if(v?.redirect){window.location.href=v.redirect;return}for(;t.firstChild;)t.removeChild(t.firstChild);o(t,v?.message||e.successMessage||"Thank you for your submission.",!1)}catch(s){throw s.formSubmitFailed||o(t,s.message||"Submission failed. Please try again.",!0),s}},d=Date.now();function b(c){const s=c.querySelector("form");if(!s||s.querySelector(".fb-form-honeypot"))return;const r=document.createElement("div");r.className="fb-form-honeypot",r.setAttribute("aria-hidden","true");const l=document.createElement("input");l.name=s.querySelector('[name="website"]')?"_website":"website",r.dataset.hpName=l.name,l.type="text",l.tabIndex=-1,l.autocomplete="url",l.placeholder="https://",r.appendChild(l);const m=document.createElement("input");m.name="_t",m.type="hidden",m.value=d,r.appendChild(m),s.appendChild(r)}function i(c){if(!window.FormLogicEngine||!n.some(r=>r.logic))return null;const s=new window.FormLogicEngine.FormLogicRuntime(a,t,c?{baseValues:c}:void 0);if(s.init(),t._formLogicRuntime=s,t._formLogicObserved)return s;if(t._formLogicObserved=!0,t.parentNode&&typeof MutationObserver<"u"){const r=new MutationObserver(function(l){for(const m of l)for(const v of m.removedNodes)if(v===t||v.nodeType===1&&v.contains&&v.contains(t)){t._formLogicRuntime&&t._formLogicRuntime.destroy(),r.disconnect();return}});r.observe(t.parentNode,{childList:!0,subtree:!1}),t._formLogicObserver=r}return s}if(y&&F.wizard){const c=V(n,a.title),s=c.map(_=>({title:_.title,description:_.description,fields:x(_.fields,u)})),r=c.map(_=>_.fields);let l=0,m=null,v=null;const A=_=>{const I=window.FormLogicEngine;if(!I||!I.validateFields)return;const L=I.validateFields(t,r[l]||[]);L.valid||(_.preventDefault(),_.stopImmediatePropagation(),P(t,L.missing),R(L))},q=()=>{const _=r[l]||n;p(t,_),N(t,_),e.honeypot!==!1&&b(t),m&&m.destroy(),m=i(v?.getStepData?v.getStepData():void 0),t.querySelectorAll(".wizard-next, .wizard-submit").forEach(I=>I.addEventListener("click",A,!0))};v=F.wizard(t,{schema:{steps:s},layout:g,columns:u,finishText:e.submitText||"Finish",onSubmit:f,onStepChange:_=>{l=_,setTimeout(q,0)}}),Promise.resolve(v).then(q)}else if(F.render){const c=F.render(t,x(n,u),k(n),{submitText:e.submitText||"Submit",layout:g,columns:u,onSubmit:f});Promise.resolve(c).then(function(){if(g==="grid"&&e.submitSpan==="full"){const s=t.querySelector(".form-buttons");s&&s.classList.add("col-span-full")}p(t,n),N(t,n),e.honeypot!==!1&&b(t),i()})}}),$(document).on("click",".dm-banner__dismiss",function(){$(this).closest(".dm-banner").remove()})})();
|
|
1
|
+
import{makeBadgeEl as M,applyColour as N,applyPill as B,applyFloat as P,applyHighlight as q,isCurrentItem as O}from"/public/js/menu-decor.mjs?v=20260905-menu-highlight";import{initFloatingMenus as R}from"/public/js/menu-float.js?v=20260829-float-panel";import{enhancePickerFields as j,markInvalidFields as V,showValidationPopup as J}from"/public/js/forms.js?v=20260821-wizard-grid";import{buildWizardSteps as W}from"/public/js/form-steps.mjs";$(()=>{const w=window.__CMS_NAV__||{},g=window.__CMS_SITE__||{};if(g.autoTheme?.enabled){let t=function(a){const e=(a||"07:00").split(":");return+e[0]*60+(+e[1]||0)},o=function(){const a=new Date,e=a.getHours()*60+a.getMinutes();return e>=t(n.dayStart)&&e<t(n.nightStart)?n.dayTheme:n.nightTheme};const n=g.autoTheme;Domma.theme.set(o()),setInterval(()=>Domma.theme.set(o()),6e4)}const x=$("#site-navbar");if(x.length&&w.brand){let o=function(i,c=0){return Array.isArray(i)?i.filter(r=>!(r&&r.type==="spacer")).filter(r=>!(r&&r.type==="separator"&&c===0)).map(r=>r&&r.type==="separator"?{divider:!0}:Array.isArray(r?.items)?{...r,items:o(r.items,c+1)}:r):i},a=function(i){return Array.isArray(i)?i.filter(c=>!(c&&(c.type==="separator"||c.type==="spacer"))):[]};const n={...w.brand},t=n.size&&n.size!=="md"?` navbar-brand-${n.size}`:"";if(n.logo||n.icon||n.tagline){let i="";n.logo?i+=`<img src="${n.logo}" class="navbar-brand-logo" alt="${n.text||""}">`:n.icon&&(i+=`<span data-icon="${n.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),n.text&&(i+=`<span class="navbar-brand-text${t}">${n.text}</span>`),n.tagline&&(i+=`<small class="navbar-brand-tagline">${n.tagline}</small>`),n.html=i}else t&&n.text&&(n.html=`<span class="navbar-brand-text${t}">${n.text}</span>`);const e=w.position==="floating",u=w.orientation==="vertical";Domma.elements.navbar("#site-navbar",{brand:n,items:o(w.items||[]),variant:w.variant||"dark",position:e?"static":w.position||"sticky",collapsible:!0,appearOnHover:!!w.appearOnHover}),Domma.icons.scan("#site-navbar");const h=x.get(0);u&&x.get(0).classList.add("dm-nav-vertical",w.side==="right"?"dm-nav-vertical-right":"dm-nav-vertical-left"),q(h,w),e&&(P(x.get(0),w),R(x.get(0).parentNode||document));const y=h.querySelector(".navbar-toggle"),f=h.querySelector(".navbar-collapse");if(y&&f){let i=null;const c=()=>{f.classList.contains("show")&&y.click()},r=()=>{i&&(i.remove(),i=null),document.body.classList.remove("dm-drawer-open")},s=()=>{i||(i=document.createElement("div"),i.className="dm-navbar-backdrop",i.addEventListener("click",c),document.body.appendChild(i),document.body.classList.add("dm-drawer-open"))};y.addEventListener("click",()=>{requestAnimationFrame(()=>{f.classList.contains("show")?s():r()})}),f.addEventListener("click",l=>{l.target.closest("a")&&requestAnimationFrame(r)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&f.classList.contains("show")&&c()})}const m=h.querySelector(".navbar-nav");if(m){const i=Array.from(m.children);let c=0;for(const r of w.items||[])if(!(r&&r.type==="separator")){if(r&&r.type==="spacer"){const s=document.createElement("li"),l=["xs","sm","md","lg","xl","flex"].includes(r.size)?r.size:"md";s.className=`dm-menu-spacer dm-menu-spacer--${l}`,s.setAttribute("aria-hidden","true"),m.insertBefore(s,i[c]||null);continue}c++}}const b=a(w.items||[]);h.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(i=>{const c=b[parseInt(i.dataset.index,10)];if(!c)return;const r=i.dataset.subindex!=null,s=r&&Array.isArray(c.items)?c.items[parseInt(i.dataset.subindex,10)]:c;if(!s)return;s.colour&&N(i,s.colour),s.pill&&!r&&B(i,s.pill);const l=M(s.badge);l&&i.appendChild(l),O(s.url,location.pathname)&&(i.classList.add("active"),i.setAttribute("aria-current","page"))})}const C=$("#site-footer");if(C.length){let e=function(s){return String(s??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},u=function(s){return e(s).replace(/'/g,"'")},h=function(s){if(s&&s.type==="separator")return'<li class="footer-sep"><hr></li>';if(s&&s.type==="spacer")return`<li class="dm-menu-spacer dm-menu-spacer--${["xs","sm","md","lg","xl","flex"].includes(s.size)?s.size:"md"}" aria-hidden="true"></li>`;const l=u(s.url||"#"),d=e(s.text||""),v=Array.isArray(s.items)&&s.items.length?`<ul>${s.items.map(h).join("")}</ul>`:"";return`<li><a href="${l}">${d}</a>${v}</li>`},y=function(s,l){return(s||[]).forEach(d=>{d&&(d.type==="separator"||d.type==="spacer")||(l.push(d),Array.isArray(d.items)&&d.items.length&&y(d.items,l))}),l};const n=g.social||{},t={twitter:{label:"X / Twitter",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.742l7.73-8.835L1.254 2.25H8.08l4.259 5.629L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>'},facebook:{label:"Facebook",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'},instagram:{label:"Instagram",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>'},linkedin:{label:"LinkedIn",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'},github:{label:"GitHub",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>'},youtube:{label:"YouTube",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/></svg>'}};let o='<div class="footer-inner container">';const a=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""};if(a.copyright&&(o+=`<p>${e(a.copyright)}</p>`),a.primary.length&&(o+=`<nav class="footer-nav footer-nav--primary"><ul>${a.primary.map(h).join("")}</ul></nav>`),a.legal.length&&(o+=`<nav class="footer-nav footer-nav--legal"><ul>${a.legal.map(h).join("")}</ul></nav>`),g.footer){const s=Object.keys(t).filter(l=>n[l]);s.length&&(o+='<div class="footer-social">',s.forEach(l=>{const{label:d,svg:v}=t[l];o+=`<a href="${n[l]}" target="_blank" rel="noopener noreferrer" aria-label="${d}" class="footer-social-link">${v}</a>`}),o+="</div>")}o+="</div>",C.html(o);const f=[...y(a.primary,[]),...y(a.legal,[])];C.get(0).querySelectorAll(".footer-nav a").forEach((s,l)=>{const d=f[l];if(!d)return;d.colour&&N(s,d.colour);const v=M(d.badge);v&&s.appendChild(v),O(d.url,location.pathname)&&(s.classList.add("is-active"),s.setAttribute("aria-current","page"))}),q(C.get(0).querySelector(".footer-nav--primary"),{highlight:a.primaryHighlight}),q(C.get(0).querySelector(".footer-nav--legal"),{highlight:a.legalHighlight});const b=g.footer?.showMotionToggle!==!1,i=S.get("reduced_motion"),c=i!==null?!!i:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),r=C.get(0).querySelector(".footer-inner");if(b&&r){const s=document.createElement("input");s.type="checkbox",s.className="form-switch-input",s.id="dm-motion-switch",s.checked=c,s.addEventListener("change",function(){S.set("reduced_motion",this.checked),window.location.reload()});const l=document.createElement("span");l.className="form-switch-label",l.textContent="Reduce motion";const d=document.createElement("label");d.className="form-switch footer-motion-switch",d.title="Reduce motion",d.appendChild(s),d.appendChild(l),r.appendChild(d)}}$("#site-sidebar").length&&Domma.elements.sidebar("#site-sidebar",{autoGenerate:!0,selector:"h2, h3",collapsible:!1,push:!0,contentSelector:".site-content"}),Domma.icons.scan(),Domma.syntax?.scan&&Domma.syntax.scan();const p=$(".page-body");if(p.length){p.find(".accordion").each(function(){Domma.elements.accordion(this,{allowMultiple:this.dataset.multi==="true"})}),p.find(".tabs").each(function(){Domma.elements.tabs(this)}),p.find(".carousel").each(function(){const n={autoplay:this.dataset.autoplay==="true",interval:parseInt(this.dataset.interval,10)||5e3,loop:this.dataset.loop!=="false",animation:this.dataset.animation||"slide"};if(this.dataset.animationDuration){const t=parseInt(this.dataset.animationDuration,10);Number.isFinite(t)&&(n.animationDuration=t)}this.dataset.animationEasing&&(n.animationEasing=this.dataset.animationEasing),this.dataset.ctx&&(this._dmCtxSlides=Array.from(this.querySelectorAll(".carousel-slide")).map(t=>t.cloneNode(!0)),this._dmCarouselOpts=n),this._dmCarousel=Domma.elements.carousel(this,n)}),p.find(".dm-countdown").each(function(){const n={autoStart:!0};this.dataset.to&&(n.targetDate=new Date(this.dataset.to)),this.dataset.duration&&(n.duration=parseInt(this.dataset.duration,10)),this.dataset.format&&(n.format=this.dataset.format),Domma.elements.timer(this,n)}),p.find("[data-tooltip]").each(function(){Domma.elements.tooltip(this,{content:$(this).data("tooltip"),position:$(this).data("tooltip-position")||"top"})}),p.find(".dm-progression").each(function(){const n=Array.from(this.querySelectorAll(".dm-progression-item")).map(a=>{const e={title:a.querySelector(".dm-progression-item-title")?.textContent?.trim()||"",description:a.querySelector(".dm-progression-item-body")?.innerHTML?.trim()||""};return a.dataset.date&&(e.date=a.dataset.date),a.dataset.status&&(e.status=a.dataset.status),a.dataset.entryId&&(e._entryId=a.dataset.entryId),e}),t=this.dataset.layout==="centred"?"centered":this.dataset.layout||"vertical",o=Domma.elements.progression(this,{layout:t,theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0,allowHtml:!0,...n.length?{items:n}:{}});n.length&&(this._dmCtx={instance:o,items:n})});try{Domma.effects.reveal(".page-body .hero",{animation:"slide-up",duration:480,threshold:.06,stagger:60,once:!1})}catch{}document.querySelectorAll(".page-body .row[data-reveal]").forEach(n=>{const t=n.dataset.revealMode||"stagger",o=n.dataset.revealAnimation||"slide-up",a=parseInt(n.dataset.revealDuration,10)||400,e=parseInt(n.dataset.revealStagger,10)||60,u=parseInt(n.dataset.revealDelay,10)||0,h=n.dataset.revealDirection==="rtl",y=Array.from(n.children),f={"slide-up":"translateY(30px)","slide-down":"translateY(-30px)","slide-left":"translateX(30px)","slide-right":"translateX(-30px)",zoom:"scale(0.85)",flip:"perspective(600px) rotateX(15deg)"};y.forEach((m,b)=>{m.style.opacity="0",m.style.transform=f[o]||"",m.style.transition=`opacity ${a}ms ease, transform ${a}ms ease`;const i=h?y.length-1-b:b;m.style.transitionDelay=t==="stagger"?`${u+i*e}ms`:`${u}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const m=new IntersectionObserver(b=>{b.forEach(i=>{i.isIntersecting&&(i.target.offsetWidth,i.target.style.opacity="1",i.target.style.transform="none",m.unobserve(i.target))})},{threshold:.1});y.forEach(b=>m.observe(b))}))}),p.find(".card[data-collapsible]").each(function(){const n=this.querySelector(".card-header");n&&n.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),p.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const n=this.dataset.soTarget,t=document.getElementById(n);if(!t)return;const o=E.slideover({title:t.dataset.soTitle||"",size:t.dataset.soSize||"md",position:t.dataset.soPosition||"right"});t.style.display="",o.setContent(t),o.open()})})}if(typeof $.setup=="function"){const n=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(t=>{try{const o=atob(t.dataset.config),a=JSON.parse(o);Object.assign(n,a)}catch{}}),Object.keys(n).length>0){const t={};for(const[o,a]of Object.entries(n)){const e=a?.events?.click,{confirm:u,toast:h,alert:y,prompt:f,...m}=e||{};u||h||y||f?($(o).on("click",async function(i){if(i.preventDefault(),u&&!await E.confirm(u))return;let c=null;if(!(f&&(c=await E.prompt(f,{inputPlaceholder:m.promptPlaceholder||"",inputValue:m.promptDefault||""}),c===null))){if(m.target){const r=$(m.target);m.toggleClass&&r.toggleClass(m.toggleClass),m.addClass&&r.addClass(m.addClass),m.removeClass&&r.removeClass(m.removeClass),c!==null&&(m.setText&&r.text(c),m.setVal&&r.val(c),m.setAttr&&r.attr(m.setAttr,c))}m.href&&(window.location.href=m.href),h&&E.toast(h,{type:m.toastType||"success"}),y&&E.alert(y)}}),Object.keys(m).length&&(t[o]={...a,events:{...a.events,click:m}})):t[o]=a}$.setup(t)}}p.length&&D(p.get(0))});function D(w){w.querySelectorAll(".dm-cta-trigger").forEach(g=>{g.__ctaWired||(g.__ctaWired=!0,g.addEventListener("click",async()=>{const x=g.dataset.action,C=g.dataset.entry,k=g.dataset.confirm;let p=S.get("auth_token");if(!p){E.toast("Please log in to perform this action.",{type:"warning"});return}if(k&&!await E.confirm(k))return;const n=Array.from(g.childNodes).map(o=>o.cloneNode(!0));g.disabled=!0,g.textContent="Running\u2026";const t=o=>fetch(`/api/actions/${x}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({entryId:C})});try{let o=await t(p);if(o.status===401){const e=S.get("auth_refresh_token");if(e){const u=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(u.ok){const{token:h}=await u.json();S.set("auth_token",h),p=h,o=await t(p)}}}const a=await o.json().catch(()=>({}));if(!o.ok)throw new Error(a.error||a.message||`Error ${o.status}`);E.toast(a.message||"Action completed.",{type:"success"})}catch(o){E.toast(o.message||"Action failed.",{type:"error"})}finally{g.disabled=!1,g.textContent="",n.forEach(o=>g.appendChild(o)),Domma.icons.scan(g)}}))})}(function(){const g=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!g.length)return;const x=S.get("auth_token");function C(p,n){const t=document.createElement("div");t.className="dm-collection-display dm-collection-empty";const o=document.createElement("p");if(n){o.appendChild(document.createTextNode("Please "));const a=document.createElement("a");a.href="/login",a.textContent="sign in",o.appendChild(a),o.appendChild(document.createTextNode(" to view your entries."))}else o.textContent=p;return t.appendChild(o),t}function k(p,n){const t=document.createElement("template");t.innerHTML=n||"",p.replaceWith(t.content)}g.forEach(async p=>{const n=p.dataset.collectionAttrs;if(!n)return;if(!x){p.replaceChildren(C("",!0));return}const t=o=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({attrs:n})});try{let o=x,a=await t(o);if(a.status===401){const u=S.get("auth_refresh_token");if(u){const h=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:u})});if(h.ok){const{token:y}=await h.json();S.set("auth_token",y),o=y,a=await t(o)}}}if(!a.ok){const{error:u}=await a.json().catch(()=>({}));p.replaceChildren(C(u||"Unable to load entries.",!1));return}const{html:e}=await a.json();k(p,e)}catch{p.replaceChildren(C("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),D(document.body)},100)})(),(function(){const g=document.querySelectorAll("[data-collection-table]");!g.length||typeof T>"u"||!T.create||g.forEach(x=>{let C;try{C=JSON.parse(atob(x.dataset.payload))}catch{return}const{columns:k,rows:p,search:n,sortable:t,exportable:o,pageSize:a,empty:e,ctaConfig:u,slug:h,exportCfg:y}=C;if(!k?.length)return;if(u){const b=k.findIndex(i=>i.key==="_cta");b!==-1&&(k[b]={key:"_cta",title:"",render:(i,c)=>{const r=document.createElement("button");if(r.className=`btn btn-${u.style||"primary"} dm-cta-trigger`,r.dataset.action=u.action||"",r.dataset.entry=c._entryId||"",u.confirm&&(r.dataset.confirm=u.confirm),u.icon){const s=document.createElement("span");s.dataset.icon=u.icon,r.appendChild(s),r.appendChild(document.createTextNode(" "))}return r.appendChild(document.createTextNode(u.label||"Run")),r}})}const f="col-table-"+Math.random().toString(36).slice(2,7),m=document.createElement("div");m.id=f,x.replaceChildren(m),T.create("#"+f,{data:p,columns:k,search:n,sortable:t,exportable:o,pageSize:a,emptyMessage:e}),u&&D(m),x._dmTable={columns:k,rows:p,slug:h,exportCfg:y,render(b){T.create("#"+f,{data:b,columns:k,search:n,sortable:t,exportable:o,pageSize:a,emptyMessage:e}),u&&D(m)}}})})(),(function(){const g=document.querySelectorAll("[data-form-inline]");if(!g.length||typeof F>"u")return;function x(t){const o=t&&t.logic;return!!(o&&(o.visibility||o.requirement))}function C(t,o){const a={};return(t||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const u=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),h=e.type==="checkbox"?"boolean":e.type==="date"||e.type==="icon"||e.type==="image"?"string":u?"chooser":e.type,y={...e.formConfig||{}};y.span==="full"&&o&&(y.span=o);const f={type:h,required:x(e)?!1:e.required,label:e.label,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...y}};u&&(e.variant&&(f.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(f.multiple=!0),e.density&&(f.density=e.density),e.columns&&(f.columns=e.columns),e.accent&&(f.accent=e.accent),e.accentStyle&&(f.accentStyle=e.accentStyle),e.glow&&(f.glow=!0),e.glowColour&&(f.glowColour=e.glowColour),e.shadow&&(f.shadow=e.shadow),e.shadowColour&&(f.shadowColour=e.shadowColour)),a[e.name]=f}),a}function k(t){const o={};return(t||[]).forEach(a=>{if(!(!a.name||a.type==="page-break"||a.type==="spacer")&&(a.type==="select"||a.type==="multiselect")&&a.required){const e=(a.options||[])[0];e&&(o[a.name]=typeof e=="object"?e.value:e)}}),o}function p(t,o){(o||[]).forEach(a=>{if(a.type!=="date"||!a.name)return;const e=t.querySelector(`[name="${a.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function n(t,o,a){let e=t.querySelector(".cms-form-message");e||(e=document.createElement("p"),e.className="cms-form-message",t.appendChild(e)),e.textContent=o,e.style.cssText=a?"color:var(--dm-danger);margin-top:.75rem;":"color:var(--dm-success);margin-top:.75rem;"}g.forEach(t=>{let o;try{o=JSON.parse(atob(t.dataset.formInline))}catch{return}const a=o.fields||[],e=o.settings||{},u=Number(e.columns)===3?3:2,h=e.layout||"grid",y=a.some(c=>c.type==="page-break"),f=async c=>{try{const r=t.querySelector(".fb-form-honeypot"),s=r?.querySelector('input[type="text"]')||null,l=r?.querySelector('[name="_t"]')||null,d=Object.assign({},c);delete d._t,r?.dataset.hpName&&delete d[r.dataset.hpName],s!==null&&(d._hp=s.value),l!==null&&(d._t=l.value);const v=await H.post(`/api/forms/submit/${o.slug}`,d);if(v&&v.error){n(t,v.error,!0);const A=new Error(v.error);throw A.formSubmitFailed=!0,A}if(v?.redirect){window.location.href=v.redirect;return}for(;t.firstChild;)t.removeChild(t.firstChild);n(t,v?.message||e.successMessage||"Thank you for your submission.",!1)}catch(r){throw r.formSubmitFailed||n(t,r.message||"Submission failed. Please try again.",!0),r}},m=Date.now();function b(c){const r=c.querySelector("form");if(!r||r.querySelector(".fb-form-honeypot"))return;const s=document.createElement("div");s.className="fb-form-honeypot",s.setAttribute("aria-hidden","true");const l=document.createElement("input");l.name=r.querySelector('[name="website"]')?"_website":"website",s.dataset.hpName=l.name,l.type="text",l.tabIndex=-1,l.autocomplete="url",l.placeholder="https://",s.appendChild(l);const d=document.createElement("input");d.name="_t",d.type="hidden",d.value=m,s.appendChild(d),r.appendChild(s)}function i(c){if(!window.FormLogicEngine||!a.some(s=>s.logic))return null;const r=new window.FormLogicEngine.FormLogicRuntime(o,t,c?{baseValues:c}:void 0);if(r.init(),t._formLogicRuntime=r,t._formLogicObserved)return r;if(t._formLogicObserved=!0,t.parentNode&&typeof MutationObserver<"u"){const s=new MutationObserver(function(l){for(const d of l)for(const v of d.removedNodes)if(v===t||v.nodeType===1&&v.contains&&v.contains(t)){t._formLogicRuntime&&t._formLogicRuntime.destroy(),s.disconnect();return}});s.observe(t.parentNode,{childList:!0,subtree:!1}),t._formLogicObserver=s}return r}if(y&&F.wizard){const c=W(a,o.title),r=c.map(_=>({title:_.title,description:_.description,fields:C(_.fields,u)})),s=c.map(_=>_.fields);let l=0,d=null,v=null;const A=_=>{const I=window.FormLogicEngine;if(!I||!I.validateFields)return;const L=I.validateFields(t,s[l]||[]);L.valid||(_.preventDefault(),_.stopImmediatePropagation(),V(t,L.missing),J(L))},z=()=>{const _=s[l]||a;p(t,_),j(t,_),e.honeypot!==!1&&b(t),d&&d.destroy(),d=i(v?.getStepData?v.getStepData():void 0),t.querySelectorAll(".wizard-next, .wizard-submit").forEach(I=>I.addEventListener("click",A,!0))};v=F.wizard(t,{schema:{steps:r},layout:h,columns:u,finishText:e.submitText||"Finish",onSubmit:f,onStepChange:_=>{l=_,setTimeout(z,0)}}),Promise.resolve(v).then(z)}else if(F.render){const c=F.render(t,C(a,u),k(a),{submitText:e.submitText||"Submit",layout:h,columns:u,onSubmit:f});Promise.resolve(c).then(function(){if(h==="grid"&&e.submitSpan==="full"){const r=t.querySelector(".form-buttons");r&&r.classList.add("col-span-full")}p(t,a),j(t,a),e.honeypot!==!1&&b(t),i()})}}),$(document).on("click",".dm-banner__dismiss",function(){$(this).closest(".dm-banner").remove()})})();
|
|
@@ -3918,7 +3918,10 @@ async function processMenuBlocks(markdown, user, ctx = {}) {
|
|
|
3918
3918
|
orientation: attrs.orientation,
|
|
3919
3919
|
variant: attrs.variant,
|
|
3920
3920
|
class: attrs.class,
|
|
3921
|
-
noFloat: attrs.float === 'no'
|
|
3921
|
+
noFloat: attrs.float === 'no',
|
|
3922
|
+
// Without the page's own path the current item is never marked, so
|
|
3923
|
+
// a menu's `highlight.active` effect would silently do nothing here.
|
|
3924
|
+
currentPath: ctx?.urlPath || ''
|
|
3922
3925
|
});
|
|
3923
3926
|
out = out.replace(m[0], html);
|
|
3924
3927
|
}
|
|
@@ -4118,9 +4121,10 @@ export async function parseMarkdown(raw, opts = {}) {
|
|
|
4118
4121
|
allowedAttributes: {
|
|
4119
4122
|
...sanitizeHtml.defaults.allowedAttributes,
|
|
4120
4123
|
// aria-hidden marks decorative markup (menu spacers, the floating panel's
|
|
4121
|
-
// drag grip) so it isn't announced as an empty item.
|
|
4122
|
-
//
|
|
4123
|
-
|
|
4124
|
+
// drag grip) so it isn't announced as an empty item. aria-current marks
|
|
4125
|
+
// the [menu] item for the page you are on. Both presentational only, no
|
|
4126
|
+
// script surface - unlike the on* handlers stripped globally.
|
|
4127
|
+
'*': ['class', 'id', 'style', 'data-*', 'aria-hidden', 'aria-current'],
|
|
4124
4128
|
img: ['src', 'alt', 'title', 'width', 'height', 'loading'],
|
|
4125
4129
|
form: ['action', 'method'],
|
|
4126
4130
|
input: ['type', 'name', 'placeholder', 'value', 'required', 'disabled',
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
* resolution happen before this - callers hand in the items they want drawn.
|
|
12
12
|
*/
|
|
13
13
|
import {colourToCss, floatToCss, floatBehaviour, spacerSize} from './menus.js';
|
|
14
|
+
// Highlight helpers live once, in the browser module, and are imported here -
|
|
15
|
+
// the same shared-module arrangement collection-export.mjs has with
|
|
16
|
+
// collections.js. Nothing in them touches the DOM.
|
|
17
|
+
import {highlightAttrs, isCurrentItem} from '../../public/js/menu-decor.mjs';
|
|
14
18
|
|
|
15
19
|
/** Attribute-safe escaping - mirrors escapeAttr in markdown.js. */
|
|
16
20
|
function esc(str) {
|
|
@@ -28,10 +32,13 @@ function esc(str) {
|
|
|
28
32
|
* children are drawn inline. Returns '' for an empty list so callers can
|
|
29
33
|
* decide whether an empty menu is worth a wrapper at all.
|
|
30
34
|
*
|
|
31
|
-
* @param {Array}
|
|
35
|
+
* @param {Array} items
|
|
36
|
+
* @param {string} [currentPath] The URL path being rendered. Items pointing at
|
|
37
|
+
* it are marked `is-active` + `aria-current` so a `highlight.active` effect
|
|
38
|
+
* has something to style. Omitted (the default) marks nothing.
|
|
32
39
|
* @returns {string}
|
|
33
40
|
*/
|
|
34
|
-
export function renderMenuItemsAsUl(items) {
|
|
41
|
+
export function renderMenuItemsAsUl(items, currentPath = '') {
|
|
35
42
|
if (!items || !items.length) return '';
|
|
36
43
|
const lis = items.map(it => {
|
|
37
44
|
if (it && it.type === 'separator') return '<li class="dm-menu-sep" role="separator"><hr></li>';
|
|
@@ -42,7 +49,13 @@ export function renderMenuItemsAsUl(items) {
|
|
|
42
49
|
}
|
|
43
50
|
const href = esc(it.url || '#');
|
|
44
51
|
const text = esc(it.text || '');
|
|
45
|
-
const child = Array.isArray(it.items) && it.items.length ? renderMenuItemsAsUl(it.items) : '';
|
|
52
|
+
const child = Array.isArray(it.items) && it.items.length ? renderMenuItemsAsUl(it.items, currentPath) : '';
|
|
53
|
+
|
|
54
|
+
// The item for the page we are on. Both markers are emitted because
|
|
55
|
+
// sanitize-html keeps the class on every path while the aria attribute
|
|
56
|
+
// needs an explicit allowlist entry.
|
|
57
|
+
const current = isCurrentItem(it.url, currentPath);
|
|
58
|
+
const classAttr = current ? ' class="is-active" aria-current="page"' : '';
|
|
46
59
|
|
|
47
60
|
// Colour override (the server sanitiser allows inline style on <a>).
|
|
48
61
|
const colourCss = it.colour ? colourToCss(it.colour) : '';
|
|
@@ -56,7 +69,7 @@ export function renderMenuItemsAsUl(items) {
|
|
|
56
69
|
badge = `<span class="dm-menu-badge"${badgeStyle}>${esc(String(it.badge.text))}</span>`;
|
|
57
70
|
}
|
|
58
71
|
|
|
59
|
-
return `<li><a href="${href}"${styleAttr}>${text}${badge}</a>${child}</li>`;
|
|
72
|
+
return `<li><a href="${href}"${classAttr}${styleAttr}>${text}${badge}</a>${child}</li>`;
|
|
60
73
|
}).join('');
|
|
61
74
|
return `<ul>${lis}</ul>`;
|
|
62
75
|
}
|
|
@@ -71,6 +84,8 @@ export function renderMenuItemsAsUl(items) {
|
|
|
71
84
|
* @param {string} [opts.variant] Adds `dm-menu--variant-<x>`
|
|
72
85
|
* @param {string} [opts.class] Extra classes on the wrapper
|
|
73
86
|
* @param {boolean}[opts.noFloat] Render inline even if the menu floats in its slot
|
|
87
|
+
* @param {string} [opts.currentPath] URL path of the page being rendered, for
|
|
88
|
+
* marking the current item. Callers that know it should always pass it.
|
|
74
89
|
* @returns {string}
|
|
75
90
|
*/
|
|
76
91
|
export function buildMenuNav(menu, items, opts = {}) {
|
|
@@ -86,8 +101,8 @@ export function buildMenuNav(menu, items, opts = {}) {
|
|
|
86
101
|
|
|
87
102
|
const floatCss = opts.noFloat ? '' : floatToCss(menu);
|
|
88
103
|
const floatClass = floatCss ? ' dm-menu-floating' : '';
|
|
89
|
-
const
|
|
90
|
-
? `
|
|
104
|
+
const floatAnchorAttr = floatCss
|
|
105
|
+
? ` data-float-anchor="${esc(menu.float?.anchor || 'TL')}"`
|
|
91
106
|
: '';
|
|
92
107
|
|
|
93
108
|
// Panel behaviour - only ever applies where the menu actually floats, so a
|
|
@@ -104,10 +119,25 @@ export function buildMenuNav(menu, items, opts = {}) {
|
|
|
104
119
|
|
|
105
120
|
const flexClass = hasFlexSpacer(items) ? ' dm-menu--has-flex-spacer' : '';
|
|
106
121
|
|
|
122
|
+
// Item highlighting - two data attributes and an optional accent custom
|
|
123
|
+
// property; public/css/menu-highlight.css does the rest. A menu with no
|
|
124
|
+
// `highlight` block emits nothing here and renders as it always has.
|
|
125
|
+
const hl = highlightAttrs(menu);
|
|
126
|
+
const hlAttrs = [
|
|
127
|
+
hl.hover && ` data-menu-hover="${esc(hl.hover)}"`,
|
|
128
|
+
hl.active && ` data-menu-active="${esc(hl.active)}"`
|
|
129
|
+
].filter(Boolean).join('');
|
|
130
|
+
// The accent joins whatever floatToCss already put in the style attribute
|
|
131
|
+
// rather than opening a second one.
|
|
132
|
+
const hlStyle = hl.accent ? `--dm-menu-highlight:${hl.accent}` : '';
|
|
133
|
+
const styleAttr = (floatCss || hlStyle)
|
|
134
|
+
? ` style="${esc([floatCss, hlStyle].filter(Boolean).join(';'))}"`
|
|
135
|
+
: '';
|
|
136
|
+
|
|
107
137
|
return `<nav class="dm-menu dm-menu--${esc(menu.slug)}${orientClass}${variantClass}${floatClass}${collapsedClass}${flexClass}${klass}"`
|
|
108
|
-
+ ` data-menu="${esc(menu.slug)}"${
|
|
138
|
+
+ ` data-menu="${esc(menu.slug)}"${styleAttr}${floatAnchorAttr}${behAttrs}${hlAttrs}>`
|
|
109
139
|
+ buildFloatChrome(menu, beh)
|
|
110
|
-
+ renderMenuItemsAsUl(items)
|
|
140
|
+
+ renderMenuItemsAsUl(items, opts.currentPath || '')
|
|
111
141
|
+ `</nav>`;
|
|
112
142
|
}
|
|
113
143
|
|
package/server/services/menus.js
CHANGED
|
@@ -14,6 +14,12 @@ import {fileURLToPath} from 'url';
|
|
|
14
14
|
import {checkVisibility} from '../middleware/auth.js';
|
|
15
15
|
import {listEntries} from './collections.js';
|
|
16
16
|
import * as cache from './cache/index.js';
|
|
17
|
+
// The highlight vocabularies are defined once, in the browser module, and
|
|
18
|
+
// imported here so validation and the renderer can never drift apart.
|
|
19
|
+
import {
|
|
20
|
+
HIGHLIGHT_HOVER, HIGHLIGHT_ACTIVE,
|
|
21
|
+
LEGACY_STYLE_HOVER, LEGACY_STYLE_ACTIVE, legacyStyleHighlight
|
|
22
|
+
} from '../../public/js/menu-decor.mjs';
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* Bust the response-cache tags that menu changes affect. Public pages are
|
|
@@ -444,6 +450,7 @@ export async function createMenu(input) {
|
|
|
444
450
|
...(input.side != null && {side: input.side}),
|
|
445
451
|
...(input.appearOnHover != null && {appearOnHover: !!input.appearOnHover}),
|
|
446
452
|
...(input.float != null && {float: input.float}),
|
|
453
|
+
...(input.highlight != null && {highlight: input.highlight}),
|
|
447
454
|
...(input.style != null && {style: input.style}),
|
|
448
455
|
...(binding != null && {binding}),
|
|
449
456
|
items: Array.isArray(input.items) ? input.items : [],
|
|
@@ -487,6 +494,7 @@ export async function updateMenu(slug, input) {
|
|
|
487
494
|
...(input.side != null && {side: input.side}),
|
|
488
495
|
...(input.appearOnHover != null && {appearOnHover: !!input.appearOnHover}),
|
|
489
496
|
...(input.float != null && {float: input.float}),
|
|
497
|
+
...(input.highlight != null && {highlight: input.highlight}),
|
|
490
498
|
...(input.style != null && {style: input.style}),
|
|
491
499
|
...(binding != null && {binding}),
|
|
492
500
|
items: Array.isArray(input.items) ? input.items : [],
|
|
@@ -604,6 +612,24 @@ export function validateMenu(menu) {
|
|
|
604
612
|
if (menu.side != null && !SIDES.has(menu.side)) {
|
|
605
613
|
errors.push(`Invalid side "${menu.side}" - expected one of: ${[...SIDES].join(', ')}`);
|
|
606
614
|
}
|
|
615
|
+
if (menu.style != null) {
|
|
616
|
+
if (typeof menu.style !== 'object' || Array.isArray(menu.style)) {
|
|
617
|
+
errors.push('style must be an object');
|
|
618
|
+
} else {
|
|
619
|
+
// `style.hover` / `style.active` are the deprecated spelling of the
|
|
620
|
+
// `highlight` block - see LEGACY_STYLE_HOVER in menu-decor.mjs.
|
|
621
|
+
// Judged against the same vocabulary the resolver accepts, so a file
|
|
622
|
+
// that validates is a file that renders.
|
|
623
|
+
if (menu.style.hover != null && menu.style.hover !== ''
|
|
624
|
+
&& !legacyStyleHighlight(menu.style).hover) {
|
|
625
|
+
errors.push(`style.hover must be one of: ${Object.keys(LEGACY_STYLE_HOVER).join(', ')}`);
|
|
626
|
+
}
|
|
627
|
+
if (menu.style.active != null && menu.style.active !== ''
|
|
628
|
+
&& !legacyStyleHighlight(menu.style).active) {
|
|
629
|
+
errors.push(`style.active must be one of: ${Object.keys(LEGACY_STYLE_ACTIVE).join(', ')}`);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
607
633
|
if (menu.binding != null) {
|
|
608
634
|
if (typeof menu.binding !== 'object' || Array.isArray(menu.binding)) {
|
|
609
635
|
errors.push('binding must be an object');
|
|
@@ -661,6 +687,22 @@ export function validateMenu(menu) {
|
|
|
661
687
|
}
|
|
662
688
|
}
|
|
663
689
|
}
|
|
690
|
+
if (menu.highlight != null) {
|
|
691
|
+
if (typeof menu.highlight !== 'object' || Array.isArray(menu.highlight)) {
|
|
692
|
+
errors.push('highlight must be an object');
|
|
693
|
+
} else {
|
|
694
|
+
const {hover, active, accent} = menu.highlight;
|
|
695
|
+
if (hover != null && hover !== '' && !HIGHLIGHT_HOVER.includes(hover)) {
|
|
696
|
+
errors.push(`highlight.hover must be one of: ${HIGHLIGHT_HOVER.join(', ')}`);
|
|
697
|
+
}
|
|
698
|
+
if (active != null && active !== '' && !HIGHLIGHT_ACTIVE.includes(active)) {
|
|
699
|
+
errors.push(`highlight.active must be one of: ${HIGHLIGHT_ACTIVE.join(', ')}`);
|
|
700
|
+
}
|
|
701
|
+
if (accent != null && accent !== '' && !isValidColour(accent)) {
|
|
702
|
+
errors.push('highlight.accent must be a preset key or #rrggbb');
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
664
706
|
if (!Array.isArray(menu.items)) {
|
|
665
707
|
errors.push('items must be an array');
|
|
666
708
|
} else {
|
|
@@ -70,7 +70,8 @@ async function buildOverlayMenus(menuCtx, user) {
|
|
|
70
70
|
const overlays = await resolveOverlaysForPage(menuCtx, user);
|
|
71
71
|
if (!overlays.length) return '';
|
|
72
72
|
const navs = await Promise.all(overlays.map(async (menu) =>
|
|
73
|
-
buildMenuNav(menu, await resolveMenuDecorations(menu.items)
|
|
73
|
+
buildMenuNav(menu, await resolveMenuDecorations(menu.items),
|
|
74
|
+
{currentPath: menuCtx?.urlPath || ''})));
|
|
74
75
|
return navs.join('');
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -141,6 +142,9 @@ export async function renderPage(page, opts = {}) {
|
|
|
141
142
|
...(navMenu.orientation === 'vertical' && {orientation: 'vertical', side: navMenu.side === 'right' ? 'right' : 'left'}),
|
|
142
143
|
...(navMenu.float && {float: navMenu.float}),
|
|
143
144
|
...(navMenu.appearOnHover && {appearOnHover: true}),
|
|
145
|
+
// Item highlighting: the navbar is built in the browser, so the
|
|
146
|
+
// config has to travel to site.js rather than being rendered here.
|
|
147
|
+
...(navMenu.highlight && {highlight: navMenu.highlight}),
|
|
144
148
|
...(navMenu.style && {style: navMenu.style})
|
|
145
149
|
}
|
|
146
150
|
: (await readLegacyNavBackup()) || {brand: site.brand || {}, items: []};
|
|
@@ -209,7 +213,10 @@ export async function renderPage(page, opts = {}) {
|
|
|
209
213
|
const footer = {
|
|
210
214
|
primary: footerPrimaryDecorated,
|
|
211
215
|
legal: footerLegalDecorated,
|
|
212
|
-
copyright: site.footer?.copyright || ''
|
|
216
|
+
copyright: site.footer?.copyright || '',
|
|
217
|
+
// Highlighting is per menu, and the two footer columns are two menus.
|
|
218
|
+
...(footerPrimary?.highlight && {primaryHighlight: footerPrimary.highlight}),
|
|
219
|
+
...(footerLegal?.highlight && {legalHighlight: footerLegal.highlight})
|
|
213
220
|
};
|
|
214
221
|
const footerJson = JSON.stringify(footer).replace(/<\/script>/gi, '<\\/script>');
|
|
215
222
|
|
|
@@ -711,6 +718,9 @@ export async function renderBlogPage(templatePath, data = {}, seoMeta = {}) {
|
|
|
711
718
|
// existing sites.
|
|
712
719
|
...(navMenu.orientation === 'vertical' && {orientation: 'vertical', side: navMenu.side === 'right' ? 'right' : 'left'}),
|
|
713
720
|
...(navMenu.appearOnHover && {appearOnHover: true}),
|
|
721
|
+
// Item highlighting: the navbar is built in the browser, so the
|
|
722
|
+
// config has to travel to site.js rather than being rendered here.
|
|
723
|
+
...(navMenu.highlight && {highlight: navMenu.highlight}),
|
|
714
724
|
...(navMenu.style && {style: navMenu.style})
|
|
715
725
|
}
|
|
716
726
|
: (await readLegacyNavBackup()) || {brand: site.brand || {}, items: []};
|
|
@@ -755,7 +765,10 @@ export async function renderBlogPage(templatePath, data = {}, seoMeta = {}) {
|
|
|
755
765
|
const footer = {
|
|
756
766
|
primary: footerPrimaryDecorated,
|
|
757
767
|
legal: footerLegalDecorated,
|
|
758
|
-
copyright: site.footer?.copyright || ''
|
|
768
|
+
copyright: site.footer?.copyright || '',
|
|
769
|
+
// Highlighting is per menu, and the two footer columns are two menus.
|
|
770
|
+
...(footerPrimary?.highlight && {primaryHighlight: footerPrimary.highlight}),
|
|
771
|
+
...(footerLegal?.highlight && {legalHighlight: footerLegal.highlight})
|
|
759
772
|
};
|
|
760
773
|
const footerJson = JSON.stringify(footer).replace(/<\/script>/gi, '<\\/script>');
|
|
761
774
|
|
|
@@ -24,8 +24,11 @@
|
|
|
24
24
|
<link rel="stylesheet" href="/dist/domma/themes/domma-themes.css">
|
|
25
25
|
|
|
26
26
|
<!-- Site CSS -->
|
|
27
|
-
<link rel="stylesheet" href="/public/css/site.css?v=
|
|
27
|
+
<link rel="stylesheet" href="/public/css/site.css?v=20260905-menu-highlight">
|
|
28
28
|
<link rel="stylesheet" href="/public/css/forms.css?v=20260821-wizard-steps">
|
|
29
|
+
<!-- Menu item hover / current-page effects. Loaded after site.css so a
|
|
30
|
+
menu's own highlight wins over the blanket link styling there. -->
|
|
31
|
+
<link rel="stylesheet" href="/public/css/menu-highlight.css?v=20260905-menu-highlight">
|
|
29
32
|
|
|
30
33
|
<!-- Font overrides -->
|
|
31
34
|
{{fontStyleTag}}
|