@alikhalilll/a-smart-skeleton 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -118,6 +118,25 @@ ask-reveal[loading]:not(:defined) {
118
118
  background-repeat: no-repeat;
119
119
  }
120
120
 
121
+ /*
122
+ * Bones drawn by \`drawSkeleton\` live in the light DOM (no shadow root), so a
123
+ * consumer can target them with their own stylesheet. Positioning stays inline
124
+ * (per-bone), but the fill colour reads from a CSS custom property so the
125
+ * consumer's theme flows through — set \`--ask-base\` on any ancestor to
126
+ * recolour every bone inside it, or use the type modifier to style text / media
127
+ * / box bones separately.
128
+ *
129
+ * Chrome bones are excluded: they reproduce the consumer's own container paint
130
+ * (background, border, shadow) that \`captureChrome\` snapshotted, so they must
131
+ * NOT get a generic fill underneath. Without the \`:not()\`, a bordered-only
132
+ * container (e.g. a footer with \`border-t\`) would show as a solid filled
133
+ * rectangle instead of just its captured divider.
134
+ */
135
+ [${ATTR_RECT}]:not([${ATTR_RECT}="chrome"]) {
136
+ background-color: var(--ask-base, var(--ask-block, var(--ak-skeleton-block, rgb(128 128 128 / 0.2))));
137
+ background-repeat: no-repeat;
138
+ }
139
+
121
140
  /* Containers keep their surface; what they hold is drawn by bones, measured before the first paint */
122
141
  @scope ([${ATTR_LOADING}]) to ([${ATTR_OWN}], [${ATTR_LAYER}]) {
123
142
  :scope,
@@ -215,7 +234,7 @@ function removeStyles() {
215
234
  }
216
235
  //#endregion
217
236
  //#region src/core/inline.generated.ts
218
- const INLINE_SCRIPT = "\"use strict\";(()=>{var B=\"ask-ghost\";var D=\"ask-layer\",L=\"ask-rect\";var R=\"ask-covered\",$=\"ask-own\",v=\"ask-ignore\",H=\"ask-block\",I=Symbol.for(\"a-smart-skeleton.ghost\"),G=Symbol.for(\"a-smart-skeleton.uncover\"),P=\"a-smart-skeleton.boot\";var W=\"var(--ask-base, rgb(128 128 128 / 0.2))\",z=\"var(--ask-highlight, rgb(255 255 255 / 0.12))\";var F={shimmer:{slow:4e3,fast:2e3},pulse:{slow:2400,fast:1200}},X=[\"a\",\"b\",\"code\",\"dd\",\"dt\",\"em\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"i\",\"label\",\"li\",\"p\",\"small\",\"span\",\"strong\",\"td\",\"th\",\"time\"],U=[\"audio\",\"canvas\",\"embed\",\"iframe\",\"img\",\"input\",\"object\",\"picture\",\"select\",\"svg\",\"textarea\",\"video\"];var gt,V=()=>gt??(gt=/jsdom/.test(navigator.userAgent)?null:document.createElement(\"canvas\").getContext(\"2d\"));var J=(t,n)=>t?{left:Math.max(t.left,n.left),right:Math.min(t.right,n.right),top:Math.max(t.top,n.top),bottom:Math.min(t.bottom,n.bottom)}:n,A=t=>[[t.left,t.top],[t.right,t.top],[t.right,t.bottom],[t.left,t.bottom]],k=(t,n)=>Math.abs(t[0]-n[0])<1&&Math.abs(t[1]-n[1])<1;function Q(t,n){let e=Math.min(n.right-n.left,n.bottom-n.top),o=r=>r.endsWith(\"%\")?parseFloat(r)/100*e:parseFloat(r)||0;return[o(t.borderTopLeftRadius),o(t.borderTopRightRadius),o(t.borderBottomRightRadius),o(t.borderBottomLeftRadius)]}function bt(t,n,e){let o=J(t,n),r=Q(e,n),c=t?A(t):[],a=A(n),m=A(o).map((f,T)=>k(f,a[T])?r[T]:t&&k(f,c[T])?t.corners[T]:0),{left:s,right:i,top:l,bottom:h}=o;return{left:s,right:i,top:l,bottom:h,corners:m}}function Tt(t,n,e,o){if(!t)return e;let r=A(t),c=A(n).map((m,s)=>t.corners[s]>0&&k(m,r[s]));if(!c.some(Boolean))return e;let a=Q(o,n);return c.map((m,s)=>m?Math.max(a[s],t.corners[s]):a[s]).map(m=>`${m}px`).join(\" \")}var j=(t,n)=>{let e=J(n,t);return e.right-e.left>=2&&e.bottom-e.top>=2?e:null},q={top:\"ascender\",bottom:\"descender\"},C=new Map,tt=t=>[...t.getClientRects?.()??[]];function St(t){let n=`${t.fontStyle} ${t.fontWeight} ${t.fontSize} ${t.fontFamily}`;if(C.has(n))return C.get(n);let e=V(),o=null;if(e){e.font=n;let r=e.measureText(\"H\"),c=a=>e.measureText(a).actualBoundingBoxAscent;o={ascent:r.fontBoundingBoxAscent,descent:r.fontBoundingBoxDescent,ascender:c(\"bdfhkl\"),capHeight:r.actualBoundingBoxAscent,xHeight:c(\"xz\"),descender:e.measureText(\"gjpqy\").actualBoundingBoxDescent}}return C.set(n,o),o}var Y={ascender:\"ascender\",\"cap-height\":\"capHeight\",\"x-height\":\"xHeight\"},K=(t,n,e,o)=>{let r=t.getPropertyValue(n).trim();return e.includes(r)?r:o};function xt(t,n,e){let o=St(n);if(!o){let s=Math.min(e*.72,t.bottom-t.top),i=(t.top+t.bottom)/2;return{barTop:i-s/2,barBottom:i+s/2}}let r=K(n,\"--ask-text-top\",Object.keys(Y),q.top),c=K(n,\"--ask-text-bottom\",[\"baseline\",\"descender\"],q.bottom),a=o.ascent+o.descent,m=t.top+(t.bottom-t.top-a)/2+o.ascent;return{barTop:m-o[Y[r]],barBottom:m+(c===\"descender\"?o.descender:0)}}var Et=new Set(U),Rt=new Set(X),et=.4,At=/[,/]\\s*0\\)$/,y=(t,n)=>t!==\"\"&&t!==n,yt=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Mt=t=>yt.every(n=>y(t[`border${n}Style`],\"none\")&&y(t[`border${n}Width`],\"0px\")),Ct=t=>{let[n=0,e=0,o=0,r=0]=(t.replace(/rgba?\\([^)]*\\)|#\\w+/g,\"\").match(/-?[\\d.]+px/g)??[]).map(parseFloat);return t.includes(\"inset\")&&!o&&!r&&n===0!=(e===0)&&Math.abs(n+e)<=2},kt=t=>y(t,\"none\")&&!t.split(/,(?![^(]*\\))/).every(Ct),Ot=t=>y(t.backgroundColor,\"transparent\")&&!At.test(t.backgroundColor)||y(t.backgroundImage,\"none\")||kt(t.boxShadow)||Mt(t),ot=t=>Et.has(t.localName),nt=t=>Rt.has(t.localName)&&!t.firstElementChild&&!t.textContent?.trim(),wt=t=>{let n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT),e=document.createRange(),o=[],r=0;for(;n.nextNode();){let i=n.currentNode;if(i.nodeType===Node.TEXT_NODE){let l=i.parentElement;if(!i.textContent?.trim()||!l)continue;r++;let h=l.getBoundingClientRect();if(h.width<=1||h.height<=1)continue;e.selectNodeContents(i),o.push(tt(e).filter(f=>f.width||f.height))}else nt(i)&&(r++,o.push([...i.getClientRects()]))}if(!o.some(i=>i.length))return r;let c=(parseFloat(getComputedStyle(t).fontSize)||16)*et,a=(i,l)=>Math.min(i.bottom,l.bottom)-Math.max(i.top,l.top)>=Math.min(i.height,l.height)/2&&Math.max(i.left,l.left)-Math.min(i.right,l.right)<=c,m=o.map((i,l)=>l),s=i=>m[i]===i?i:m[i]=s(m[i]);for(let i=0;i<o.length;i++)for(let l=i+1;l<o.length;l++)o[i].some(h=>o[l].some(f=>a(h,f)))&&(m[s(l)]=s(i));return new Set(o.map((i,l)=>s(l))).size},Nt=(t,n)=>t.hasAttribute(H)||ot(t)||Ot(n)&&wt(t)<=1;function _t(t,n){if(parseFloat(n.borderRadius)||!t.parentElement)return n.borderRadius||\"0px\";let e=t.parentElement,o=getComputedStyle(e),r=t.getBoundingClientRect(),c=e.getBoundingClientRect();return Math.abs(r.width-c.width)<1&&Math.abs(r.height-c.height)<1&&o.overflow!==\"visible\"?o.borderRadius:n.borderRadius||\"0px\"}function Z(t){t.sort((e,o)=>e.left-o.left);let n=[];for(let e of t){let o=n.find(r=>{let c=Math.min(r.bottom,e.bottom)-Math.max(r.top,e.top),a=Math.min(r.bottom-r.top,e.bottom-e.top),m=e.left-r.right;return c>=a/2&&m<=Math.max(r.fontSize,e.fontSize)*et});o?(o.left=Math.min(o.left,e.left),o.right=Math.max(o.right,e.right),o.top=Math.min(o.top,e.top),o.bottom=Math.max(o.bottom,e.bottom),o.fontSize=Math.max(o.fontSize,e.fontSize),o.barTop=Math.min(o.barTop,e.barTop),o.barBottom=Math.max(o.barBottom,e.barBottom)):n.push({...e})}return n.map(e=>{let o=e.barBottom-e.barTop;return{x:e.left,y:e.barTop,width:e.right-e.left,height:o,radius:e.radius||`${Math.round(o/3)}px`}})}function rt(t,n,{mark:e=!0,onCovered:o}={}){let r=n.getBoundingClientRect(),c=n.offsetWidth?r.width/n.offsetWidth:1,a=n.offsetHeight?r.height/n.offsetHeight:1,m=d=>({left:(d.left-r.left)/c,right:(d.right-r.left)/c,top:(d.top-r.top)/a,bottom:(d.bottom-r.top)/a}),s=[],i=[],l=new Set,h=document.createRange(),f=(d,g,b)=>{let u=j(d,b);if(!u)return;let p=parseFloat(g.fontSize)||16,M=m(u);i.push({...M,fontSize:p,...xt(M,g,p),radius:g.getPropertyValue(\"--ask-radius\").trim()})},T=(d,g)=>{let b=d.data.search(/\\S/);if(b<0||!d.parentElement)return;h.setStart(d,b),h.setEnd(d,d.data.trimEnd().length);let u=getComputedStyle(d.parentElement);for(let p of tt(h))f(p,u,g)},_=(d,g)=>{for(let b of d.childNodes){if(b.nodeType===Node.TEXT_NODE){T(b,g);continue}if(b.nodeType!==Node.ELEMENT_NODE)continue;let u=b;if(u.hasAttribute(v)||u.hasAttribute($))continue;let p=getComputedStyle(u);if(p.display===\"none\")continue;if(Nt(u,p)){let E=j(u.getBoundingClientRect(),g);if(E){let S=m(E);s.push({x:S.left,y:S.top,width:S.right-S.left,height:S.bottom-S.top,radius:Tt(g,E,_t(u,p),p)})}ot(u)||l.add(u);continue}if(nt(u)){for(let E of u.getClientRects())f(E,p,g);continue}let M=p.overflowX!==\"visible\"||p.overflowY!==\"visible\";_(u,M?bt(g,u.getBoundingClientRect(),p):g)}};if(_(t,null),o?.(l),!e)return[...s,...Z(i)];for(let d of t.querySelectorAll(`[${R}]`))l.has(d)||d.removeAttribute(R);for(let d of l)d.hasAttribute(R)||d.setAttribute(R,\"\");return[...s,...Z(i)]}var Bt=t=>typeof matchMedia<\"u\"&&matchMedia(t).matches,Dt=()=>typeof Element<\"u\"&&typeof Element.prototype.animate==\"function\",st=()=>!Dt()||Bt(\"(prefers-reduced-motion: reduce)\");var it=t=>t.getAnimations?.()??[];var Lt=.7,$t=1280,at=320,vt=2.5,Ht=.45,It=[\"shimmer\",\"group-shimmer\",\"pulse\",\"none\"];function mt(t){let n=getComputedStyle(t),e=(c,a,m)=>{let s=n.getPropertyValue(c).trim();return a.includes(s)?s:m},o=e(\"--ask-animation\",It,\"shimmer\"),r=e(\"--ask-speed\",[\"slow\",\"fast\"],\"slow\");return{animation:o,duration:F[o===\"pulse\"?\"pulse\":\"shimmer\"][r]}}var w=20,Gt=Math.sin(w*Math.PI/180),lt=Math.cos(w*Math.PI/180),Pt=Gt/lt;var Wt=`${90+w}deg`,O=.85,x=12,ct=t=>(1-Math.cos(Math.PI*t))/2;function zt(t){let n=t*vt,e=(r,c)=>`color-mix(in srgb, ${z} ${(c*100).toFixed(1)}%, transparent) ${(r*t).toFixed(2)}px`,o=[];for(let r=0;r<=x;r++)o.push(e(r/x*O,ct(r/x)));for(let r=1;r<=x;r++)o.push(e(O+r/x*(1-O),ct(1-r/x)));return{width:n/lt,image:`repeating-linear-gradient(${Wt}, ${o.join(\", \")}, transparent ${n.toFixed(2)}px)`}}function Ft(t,n,e=mt(t)){for(let f of it(t))f.cancel();if(t.style.backgroundImage=\"\",t.style.backgroundRepeat=\"\",st()||typeof t.animate!=\"function\"||e.animation===\"none\")return;let o={duration:e.duration,iterations:1/0};if(e.animation===\"pulse\"){t.animate([{opacity:1,easing:\"ease-in-out\"},{opacity:Ht,easing:\"ease-in-out\"},{opacity:1}],o).startTime=0;return}let r=t.getBoundingClientRect(),c=r.left+scrollX,a=e.animation===\"group-shimmer\"?n??{left:c,top:r.top,width:r.width,height:r.height}:{left:0,top:0,width:document.documentElement.clientWidth||innerWidth,height:innerHeight},m=Math.min(Math.max(a.width*.4,80),at),{width:s,image:i}=zt(m),l=c-a.left+(r.top-a.top)*Pt,h=e.duration*Lt/($t+at);t.style.backgroundImage=i,t.style.backgroundSize=`${s}px 100%`,t.style.backgroundRepeat=\"repeat-x\",t.animate([{backgroundPosition:`${-l}px 0`},{backgroundPosition:`${s-l}px 0`}],{duration:s*h,iterations:1/0}).startTime=0}var Xt=t=>t.shadowRoot??t.attachShadow({mode:\"open\"});function dt(t,n){let e=Xt(t),o=t.getBoundingClientRect(),r={left:o.left+scrollX,top:o.top,width:o.width,height:o.height},c=mt(t);for(n.forEach((a,m)=>{let s=e.children[m];s||(s=document.createElement(\"div\"),s.setAttribute(L,\"\"),s.style.cssText=`position:absolute;display:block;pointer-events:none;background-color:${W};background-repeat:no-repeat`,e.append(s)),Object.assign(s.style,{left:`${a.x}px`,top:`${a.y}px`,width:`${a.width}px`,height:`${a.height}px`,borderRadius:a.radius});let i=`${Math.round(r.left+a.x)}|${Math.round(a.y)}|${Math.round(a.height)}|${Math.round(r.left)}|${Math.round(r.width)}|${Math.round(r.height)}|${document.documentElement.clientWidth}|${c.animation}|${c.duration}`;s.dataset.motion!==i&&(s.dataset.motion=i,Ft(s,r,c))});e.children.length>n.length;)e.lastElementChild.remove()}var pt=t=>t.parentElement?`${pt(t.parentElement)} > :nth-child(${[...t.parentElement.children].indexOf(t)+1})`:\":root\";function N(t){let n=t?.previousElementSibling,e=n?.querySelector(`:scope > [${B}]`),o=n?.querySelector(`:scope > [${D}]`);if(!n||!e||!o)return;let r=typeof CSSStyleSheet==\"function\"&&\"replaceSync\"in CSSStyleSheet.prototype?new CSSStyleSheet:null;r&&(document.adoptedStyleSheets=[...document.adoptedStyleSheets,r],n[G]=()=>{document.adoptedStyleSheets=document.adoptedStyleSheets.filter(s=>s!==r)});let c=s=>r?.replaceSync(s.size?`${[...s].map(pt).join(\", \")} { visibility: hidden !important; }`:\"\"),a=()=>{if(!o.isConnected||n[I])return m.disconnect();e.getClientRects().length&&dt(o,rt(e,o,{mark:!1,onCovered:c}))},m=new ResizeObserver(a);m.observe(n),document.fonts?.ready.then(a)}var ht=self,ft=Symbol.for(P),ut=ht[ft];ht[ft]=N;Array.isArray(ut)&&ut.forEach(N);N(document.currentScript);})();";
237
+ const INLINE_SCRIPT = "\"use strict\";(()=>{var H=\"ask-ghost\";var G=\"ask-layer\",M=\"ask-rect\";var A=\"ask-covered\",P=\"ask-own\",W=\"ask-ignore\",F=\"ask-block\",z=Symbol.for(\"a-smart-skeleton.ghost\"),U=Symbol.for(\"a-smart-skeleton.uncover\"),X=\"a-smart-skeleton.boot\";var j=\"var(--ask-highlight, rgb(255 255 255 / 0.12))\";var V={shimmer:{slow:4e3,fast:2e3},pulse:{slow:2400,fast:1200}},q=[\"a\",\"b\",\"code\",\"dd\",\"dt\",\"em\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"i\",\"label\",\"li\",\"p\",\"small\",\"span\",\"strong\",\"td\",\"th\",\"time\"],Y=[\"audio\",\"canvas\",\"embed\",\"iframe\",\"img\",\"input\",\"object\",\"picture\",\"select\",\"svg\",\"textarea\",\"video\"];var Et,K=()=>Et??(Et=/jsdom/.test(navigator.userAgent)?null:document.createElement(\"canvas\").getContext(\"2d\"));var nt=(t,e)=>t?{left:Math.max(t.left,e.left),right:Math.min(t.right,e.right),top:Math.max(t.top,e.top),bottom:Math.min(t.bottom,e.bottom)}:e,k=t=>[[t.left,t.top],[t.right,t.top],[t.right,t.bottom],[t.left,t.bottom]],$=(t,e)=>Math.abs(t[0]-e[0])<1&&Math.abs(t[1]-e[1])<1;function rt(t,e){let r=Math.min(e.right-e.left,e.bottom-e.top),o=n=>n.endsWith(\"%\")?parseFloat(n)/100*r:parseFloat(n)||0;return[o(t.borderTopLeftRadius),o(t.borderTopRightRadius),o(t.borderBottomRightRadius),o(t.borderBottomLeftRadius)]}function At(t,e,r){let o=nt(t,e),n=rt(r,e),c=t?k(t):[],i=k(e),l=k(o).map((b,R)=>$(b,i[R])?n[R]:t&&$(b,c[R])?t.corners[R]:0),{left:s,right:a,top:d,bottom:h}=o;return{left:s,right:a,top:d,bottom:h,corners:l}}function Z(t,e,r,o){if(!t)return r;let n=k(t),c=k(e).map((l,s)=>t.corners[s]>0&&$(l,n[s]));if(!c.some(Boolean))return r;let i=rt(o,e);return c.map((l,s)=>l?Math.max(i[s],t.corners[s]):i[s]).map(l=>`${l}px`).join(\" \")}var O=(t,e)=>{let r=nt(e,t);return r.right-r.left>=2&&r.bottom-r.top>=2?r:null},J={top:\"ascender\",bottom:\"descender\"},w=new Map,st=t=>[...t.getClientRects?.()??[]];function kt(t){let e=`${t.fontStyle} ${t.fontWeight} ${t.fontSize} ${t.fontFamily}`;if(w.has(e))return w.get(e);let r=K(),o=null;if(r){r.font=e;let n=r.measureText(\"H\"),c=i=>r.measureText(i).actualBoundingBoxAscent;o={ascent:n.fontBoundingBoxAscent,descent:n.fontBoundingBoxDescent,ascender:c(\"bdfhkl\"),capHeight:n.actualBoundingBoxAscent,xHeight:c(\"xz\"),descender:r.measureText(\"gjpqy\").actualBoundingBoxDescent}}return w.set(e,o),o}var Q={ascender:\"ascender\",\"cap-height\":\"capHeight\",\"x-height\":\"xHeight\"},tt=(t,e,r,o)=>{let n=t.getPropertyValue(e).trim();return r.includes(n)?n:o};function Ct(t,e,r){let o=kt(e);if(!o){let s=Math.min(r*.72,t.bottom-t.top),a=(t.top+t.bottom)/2;return{barTop:a-s/2,barBottom:a+s/2}}let n=tt(e,\"--ask-text-top\",Object.keys(Q),J.top),c=tt(e,\"--ask-text-bottom\",[\"baseline\",\"descender\"],J.bottom),i=o.ascent+o.descent,l=t.top+(t.bottom-t.top-i)/2+o.ascent;return{barTop:l-o[Q[n]],barBottom:l+(c===\"descender\"?o.descender:0)}}var Mt=new Set(Y),Ot=new Set(q),it=.4,at=/[,/]\\s*0\\)$/,g=(t,e)=>t!==\"\"&&t!==e,N=[\"Top\",\"Right\",\"Bottom\",\"Left\"],wt=t=>N.every(e=>g(t[`border${e}Style`],\"none\")&&g(t[`border${e}Width`],\"0px\")),$t=t=>N.some(e=>g(t[`border${e}Style`],\"none\")&&g(t[`border${e}Width`],\"0px\")),Bt=t=>{let[e=0,r=0,o=0,n=0]=(t.replace(/rgba?\\([^)]*\\)|#\\w+/g,\"\").match(/-?[\\d.]+px/g)??[]).map(parseFloat);return t.includes(\"inset\")&&!o&&!n&&e===0!=(r===0)&&Math.abs(e+r)<=2},ct=t=>g(t,\"none\")&&!t.split(/,(?![^(]*\\))/).every(Bt);function Nt(t){let e=[],r=0,o=0;for(let n=0;n<t.length;n++){let c=t[n];c===\"(\"?r++:c===\")\"?r--:c===\",\"&&r===0&&(e.push(t.slice(o,n)),o=n+1)}return e.push(t.slice(o)),e.map(n=>n.trim()).filter(n=>n&&!n.startsWith(\"url(\")).join(\", \")}var dt=t=>g(t.backgroundColor,\"transparent\")&&!at.test(t.backgroundColor)||g(t.backgroundImage,\"none\")||ct(t.boxShadow)||wt(t);function _t(t){let e={},r=t.backgroundColor;g(r,\"transparent\")&&!at.test(r)&&(e.background=r);let o=t.backgroundImage;if(g(o,\"none\")){let n=Nt(o);n&&(e.background=e.background?`${n}, ${e.background}`:n)}for(let n of N){let c=t[`border${n}Width`],i=t[`border${n}Style`],l=t[`border${n}Color`];if(g(i,\"none\")&&g(c,\"0px\")&&parseFloat(c)>0){let s=`border${n}`;e[s]=`${c} ${i} ${l}`}}return ct(t.boxShadow)&&(e.boxShadow=t.boxShadow),Object.keys(e).length?e:void 0}var B=t=>Mt.has(t.localName),lt=t=>Ot.has(t.localName)&&!t.firstElementChild&&!t.textContent?.trim(),Dt=t=>{let e=document.createTreeWalker(t,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT),r=document.createRange(),o=[],n=0;for(;e.nextNode();){let a=e.currentNode;if(a.nodeType===Node.TEXT_NODE){let d=a.parentElement;if(!a.textContent?.trim()||!d)continue;n++;let h=d.getBoundingClientRect();if(h.width<=1||h.height<=1)continue;r.selectNodeContents(a),o.push(st(r).filter(b=>b.width||b.height))}else lt(a)&&(n++,o.push([...a.getClientRects()]))}if(!o.some(a=>a.length))return n;let c=(parseFloat(getComputedStyle(t).fontSize)||16)*it,i=(a,d)=>Math.min(a.bottom,d.bottom)-Math.max(a.top,d.top)>=Math.min(a.height,d.height)/2&&Math.max(a.left,d.left)-Math.min(a.right,d.right)<=c,l=o.map((a,d)=>d),s=a=>l[a]===a?a:l[a]=s(l[a]);for(let a=0;a<o.length;a++)for(let d=a+1;d<o.length;d++)o[a].some(h=>o[d].some(b=>i(h,b)))&&(l[s(d)]=s(a));return new Set(o.map((a,d)=>s(d))).size},Lt=(t,e)=>t.hasAttribute(F)||B(t)||dt(e)&&Dt(t)<=1;function et(t,e){if(parseFloat(e.borderRadius)||!t.parentElement)return e.borderRadius||\"0px\";let r=t.parentElement,o=getComputedStyle(r),n=t.getBoundingClientRect(),c=r.getBoundingClientRect();return Math.abs(n.width-c.width)<1&&Math.abs(n.height-c.height)<1&&o.overflow!==\"visible\"?o.borderRadius:e.borderRadius||\"0px\"}function ot(t){t.sort((r,o)=>r.left-o.left);let e=[];for(let r of t){let o=e.find(n=>{let c=Math.min(n.bottom,r.bottom)-Math.max(n.top,r.top),i=Math.min(n.bottom-n.top,r.bottom-r.top),l=r.left-n.right;return c>=i/2&&l<=Math.max(n.fontSize,r.fontSize)*it});o?(o.left=Math.min(o.left,r.left),o.right=Math.max(o.right,r.right),o.top=Math.min(o.top,r.top),o.bottom=Math.max(o.bottom,r.bottom),o.fontSize=Math.max(o.fontSize,r.fontSize),o.barTop=Math.min(o.barTop,r.barTop),o.barBottom=Math.max(o.barBottom,r.barBottom)):e.push({...r})}return e.map(r=>{let o=r.barBottom-r.barTop;return{type:\"text\",x:r.left,y:r.barTop,width:r.right-r.left,height:o,radius:r.radius||`${Math.round(o/3)}px`}})}function mt(t,e,{mark:r=!0,onCovered:o}={}){let n=e.getBoundingClientRect(),c=e.offsetWidth?n.width/e.offsetWidth:1,i=e.offsetHeight?n.height/e.offsetHeight:1,l=m=>({left:(m.left-n.left)/c,right:(m.right-n.left)/c,top:(m.top-n.top)/i,bottom:(m.bottom-n.top)/i}),s=[],a=[],d=new Set,h=document.createRange(),b=(m,f,T)=>{let u=O(m,T);if(!u)return;let p=parseFloat(f.fontSize)||16,C=l(u);a.push({...C,fontSize:p,...Ct(C,f,p),radius:f.getPropertyValue(\"--ask-radius\").trim()})},R=(m,f)=>{let T=m.data.search(/\\S/);if(T<0||!m.parentElement)return;h.setStart(m,T),h.setEnd(m,m.data.trimEnd().length);let u=getComputedStyle(m.parentElement);for(let p of st(h))b(p,u,f)},I=(m,f)=>{for(let T of m.childNodes){if(T.nodeType===Node.TEXT_NODE){R(T,f);continue}if(T.nodeType!==Node.ELEMENT_NODE)continue;let u=T;if(u.hasAttribute(W)||u.hasAttribute(P))continue;let p=getComputedStyle(u);if(p.display===\"none\")continue;if(Lt(u,p)){let x=O(u.getBoundingClientRect(),f);if(x){let S=l(x);s.push({type:B(u)?\"media\":\"box\",x:S.left,y:S.top,width:S.right-S.left,height:S.bottom-S.top,radius:Z(f,x,et(u,p),p)})}B(u)||d.add(u);continue}if(lt(u)){for(let x of u.getClientRects())b(x,p,f);continue}if(dt(p)||$t(p)){let x=_t(p);if(x){let S=O(u.getBoundingClientRect(),f);if(S){let y=l(S);s.push({type:\"chrome\",x:y.left,y:y.top,width:y.right-y.left,height:y.bottom-y.top,radius:Z(f,S,et(u,p),p),chrome:x})}}}let C=p.overflowX!==\"visible\"||p.overflowY!==\"visible\";I(u,C?At(f,u.getBoundingClientRect(),p):f)}};if(I(t,null),o?.(d),!r)return[...s,...ot(a)];for(let m of t.querySelectorAll(`[${A}]`))d.has(m)||m.removeAttribute(A);for(let m of d)m.hasAttribute(A)||m.setAttribute(A,\"\");return[...s,...ot(a)]}var vt=t=>typeof matchMedia<\"u\"&&matchMedia(t).matches,It=()=>typeof Element<\"u\"&&typeof Element.prototype.animate==\"function\",ut=()=>!It()||vt(\"(prefers-reduced-motion: reduce)\");var _=t=>t.getAnimations?.()??[];var Ht=.7,Gt=1280,pt=320,Pt=2.5,Wt=.45,Ft=[\"shimmer\",\"group-shimmer\",\"pulse\",\"none\"];function bt(t){let e=getComputedStyle(t),r=(c,i,l)=>{let s=e.getPropertyValue(c).trim();return i.includes(s)?s:l},o=r(\"--ask-animation\",Ft,\"shimmer\"),n=r(\"--ask-speed\",[\"slow\",\"fast\"],\"slow\");return{animation:o,duration:V[o===\"pulse\"?\"pulse\":\"shimmer\"][n]}}var L=20,zt=Math.sin(L*Math.PI/180),gt=Math.cos(L*Math.PI/180),Ut=zt/gt;var Xt=`${90+L}deg`,D=.85,E=12,ht=t=>(1-Math.cos(Math.PI*t))/2;function jt(t){let e=t*Pt,r=(n,c)=>`color-mix(in srgb, ${j} ${(c*100).toFixed(1)}%, transparent) ${(n*t).toFixed(2)}px`,o=[];for(let n=0;n<=E;n++)o.push(r(n/E*D,ht(n/E)));for(let n=1;n<=E;n++)o.push(r(D+n/E*(1-D),ht(1-n/E)));return{width:e/gt,image:`repeating-linear-gradient(${Xt}, ${o.join(\", \")}, transparent ${e.toFixed(2)}px)`}}function Vt(t,e,r=bt(t)){for(let b of _(t))b.cancel();if(t.style.backgroundImage=\"\",t.style.backgroundRepeat=\"\",ut()||typeof t.animate!=\"function\"||r.animation===\"none\")return;let o={duration:r.duration,iterations:1/0};if(r.animation===\"pulse\"){t.animate([{opacity:1,easing:\"ease-in-out\"},{opacity:Wt,easing:\"ease-in-out\"},{opacity:1}],o).startTime=0;return}let n=t.getBoundingClientRect(),c=n.left+scrollX,i=r.animation===\"group-shimmer\"?e??{left:c,top:n.top,width:n.width,height:n.height}:{left:0,top:0,width:document.documentElement.clientWidth||innerWidth,height:innerHeight},l=Math.min(Math.max(i.width*.4,80),pt),{width:s,image:a}=jt(l),d=c-i.left+(n.top-i.top)*Ut,h=r.duration*Ht/(Gt+pt);t.style.backgroundImage=a,t.style.backgroundSize=`${s}px 100%`,t.style.backgroundRepeat=\"repeat-x\",t.animate([{backgroundPosition:`${-d}px 0`},{backgroundPosition:`${s-d}px 0`}],{duration:s*h,iterations:1/0}).startTime=0}var qt=t=>[...t.querySelectorAll(`:scope > [${M}]`)],ft=4,Yt=t=>t.replace(/(\\d+(?:\\.\\d+)?)px/g,(e,r)=>{let o=parseFloat(r);return Number.isFinite(o)&&o<ft?`${ft}px`:`${o}px`});function St(t,e){let r=qt(t),o=t.getBoundingClientRect(),n={left:o.left+scrollX,top:o.top,width:o.width,height:o.height},c=bt(t);e.forEach((i,l)=>{let s=r[l];if(s||(s=document.createElement(\"div\"),s.style.cssText=\"position:absolute;display:block;pointer-events:none;background-repeat:no-repeat\",t.append(s)),s.setAttribute(M,i.type),Object.assign(s.style,{left:`${i.x}px`,top:`${i.y}px`,width:`${i.width}px`,height:`${i.height}px`,borderRadius:i.type===\"chrome\"?i.radius:Yt(i.radius)}),i.type===\"chrome\"){for(let h of _(s))h.cancel();s.style.backgroundImage=\"\",s.style.backgroundSize=\"\",s.style.backgroundRepeat=\"\";let d=i.chrome;s.style.background=d?.background??\"\",s.style.borderTop=d?.borderTop??\"\",s.style.borderRight=d?.borderRight??\"\",s.style.borderBottom=d?.borderBottom??\"\",s.style.borderLeft=d?.borderLeft??\"\",s.style.boxShadow=d?.boxShadow??\"\",s.dataset.motion=\"chrome\";return}s.dataset.motion===\"chrome\"&&(s.style.background=\"\",s.style.borderTop=\"\",s.style.borderRight=\"\",s.style.borderBottom=\"\",s.style.borderLeft=\"\",s.style.boxShadow=\"\");let a=`${Math.round(n.left+i.x)}|${Math.round(i.y)}|${Math.round(i.height)}|${Math.round(n.left)}|${Math.round(n.width)}|${Math.round(n.height)}|${document.documentElement.clientWidth}|${c.animation}|${c.duration}`;s.dataset.motion!==a&&(s.dataset.motion=a,Vt(s,n,c))});for(let i=r.length-1;i>=e.length;i--)r[i].remove()}var xt=t=>t.parentElement?`${xt(t.parentElement)} > :nth-child(${[...t.parentElement.children].indexOf(t)+1})`:\":root\";function v(t){let e=t?.previousElementSibling,r=e?.querySelector(`:scope > [${H}]`),o=e?.querySelector(`:scope > [${G}]`);if(!e||!r||!o)return;let n=typeof CSSStyleSheet==\"function\"&&\"replaceSync\"in CSSStyleSheet.prototype?new CSSStyleSheet:null;n&&(document.adoptedStyleSheets=[...document.adoptedStyleSheets,n],e[U]=()=>{document.adoptedStyleSheets=document.adoptedStyleSheets.filter(s=>s!==n)});let c=s=>n?.replaceSync(s.size?`${[...s].map(xt).join(\", \")} { visibility: hidden !important; }`:\"\"),i=()=>{if(!o.isConnected||e[z])return l.disconnect();r.getClientRects().length&&St(o,mt(r,o,{mark:!1,onCovered:c}))},l=new ResizeObserver(i);l.observe(e),document.fonts?.ready.then(i)}var Rt=self,yt=Symbol.for(X),Tt=Rt[yt];Rt[yt]=v;Array.isArray(Tt)&&Tt.forEach(v);v(document.currentScript);})();";
219
238
  /** For every skeleton after a page's first: calls the boot INLINE_SCRIPT left on window. */
220
239
  const INLINE_STUB = "(s=>{let k=Symbol.for(\"a-smart-skeleton.boot\"),b=self[k];typeof b==\"function\"?b(s):(self[k]=b||[]).push(s)})(document.currentScript)";
221
240
  /** Either, as a whole element — for templates where a literal script tag would be read as the component's own. */
@@ -732,12 +751,56 @@ const SIDES = [
732
751
  "Left"
733
752
  ];
734
753
  const bordered = (style) => SIDES.every((side) => isSet(style[`border${side}Style`], "none") && isSet(style[`border${side}Width`], "0px"));
754
+ const anyBordered = (style) => SIDES.some((side) => isSet(style[`border${side}Style`], "none") && isSet(style[`border${side}Width`], "0px"));
735
755
  const isRule = (shadow) => {
736
756
  const [x = 0, y = 0, blur = 0, spread = 0] = (shadow.replace(/rgba?\([^)]*\)|#\w+/g, "").match(/-?[\d.]+px/g) ?? []).map(parseFloat);
737
757
  return shadow.includes("inset") && !blur && !spread && x === 0 !== (y === 0) && Math.abs(x + y) <= 2;
738
758
  };
739
759
  const shadowPaints = (boxShadow) => isSet(boxShadow, "none") && !boxShadow.split(/,(?![^(]*\))/).every(isRule);
760
+ /** Splits `background-image` on its top-level commas (respecting nested parens, which
761
+ * gradient stops abuse heavily) and drops any layer that starts with `url(`. Returns
762
+ * an empty string when nothing survives — the caller treats that as "no background". */
763
+ function stripUrlLayers(bgImage) {
764
+ const layers = [];
765
+ let depth = 0;
766
+ let start = 0;
767
+ for (let i = 0; i < bgImage.length; i++) {
768
+ const ch = bgImage[i];
769
+ if (ch === "(") depth++;
770
+ else if (ch === ")") depth--;
771
+ else if (ch === "," && depth === 0) {
772
+ layers.push(bgImage.slice(start, i));
773
+ start = i + 1;
774
+ }
775
+ }
776
+ layers.push(bgImage.slice(start));
777
+ return layers.map((l) => l.trim()).filter((l) => l && !l.startsWith("url(")).join(", ");
778
+ }
740
779
  const isPainted = (style) => isSet(style.backgroundColor, "transparent") && !TRANSPARENT.test(style.backgroundColor) || isSet(style.backgroundImage, "none") || shadowPaints(style.boxShadow) || bordered(style);
780
+ /** Reads the painted chrome off a container so the skeleton can reproduce it exactly —
781
+ * background, four border sides, and box-shadow, but only the properties that are set.
782
+ * Returns `undefined` when nothing paints, so callers can skip emitting a chrome bone. */
783
+ function captureChrome(style) {
784
+ const chrome = {};
785
+ const bg = style.backgroundColor;
786
+ if (isSet(bg, "transparent") && !TRANSPARENT.test(bg)) chrome.background = bg;
787
+ const bgImage = style.backgroundImage;
788
+ if (isSet(bgImage, "none")) {
789
+ const gradientsOnly = stripUrlLayers(bgImage);
790
+ if (gradientsOnly) chrome.background = chrome.background ? `${gradientsOnly}, ${chrome.background}` : gradientsOnly;
791
+ }
792
+ for (const side of SIDES) {
793
+ const width = style[`border${side}Width`];
794
+ const styleProp = style[`border${side}Style`];
795
+ const color = style[`border${side}Color`];
796
+ if (isSet(styleProp, "none") && isSet(width, "0px") && parseFloat(width) > 0) {
797
+ const key = `border${side}`;
798
+ chrome[key] = `${width} ${styleProp} ${color}`;
799
+ }
800
+ }
801
+ if (shadowPaints(style.boxShadow)) chrome.boxShadow = style.boxShadow;
802
+ return Object.keys(chrome).length ? chrome : void 0;
803
+ }
741
804
  const isMedia = (element) => MEDIA.has(element.localName);
742
805
  const isEmptyText = (element) => TEXT.has(element.localName) && !element.firstElementChild && !element.textContent?.trim();
743
806
  /** Labels inside: one per piece of text, however many lines it wraps to or nodes it's split into. */
@@ -801,6 +864,7 @@ function toBars(lines) {
801
864
  return merged.map((line) => {
802
865
  const height = line.barBottom - line.barTop;
803
866
  return {
867
+ type: "text",
804
868
  x: line.left,
805
869
  y: line.barTop,
806
870
  width: line.right - line.left,
@@ -860,6 +924,7 @@ function measureSkeleton(root, layer, { mark = true, onCovered } = {}) {
860
924
  if (visible) {
861
925
  const box = local(visible);
862
926
  blocks.push({
927
+ type: isMedia(element) ? "media" : "box",
863
928
  x: box.left,
864
929
  y: box.top,
865
930
  width: box.right - box.left,
@@ -874,6 +939,24 @@ function measureSkeleton(root, layer, { mark = true, onCovered } = {}) {
874
939
  for (const rect of element.getClientRects()) addLine(rect, style, clip);
875
940
  continue;
876
941
  }
942
+ if (isPainted(style) || anyBordered(style)) {
943
+ const chrome = captureChrome(style);
944
+ if (chrome) {
945
+ const visible = clipped(element.getBoundingClientRect(), clip);
946
+ if (visible) {
947
+ const box = local(visible);
948
+ blocks.push({
949
+ type: "chrome",
950
+ x: box.left,
951
+ y: box.top,
952
+ width: box.right - box.left,
953
+ height: box.bottom - box.top,
954
+ radius: roundedBy(clip, visible, radiusOf(element, style), style),
955
+ chrome
956
+ });
957
+ }
958
+ }
959
+ }
877
960
  visit(element, style.overflowX !== "visible" || style.overflowY !== "visible" ? clipWithin(clip, element.getBoundingClientRect(), style) : clip);
878
961
  }
879
962
  };
@@ -993,12 +1076,30 @@ function paceOf(element) {
993
1076
  if (motion.animation !== "shimmer" && motion.animation !== "group-shimmer") return null;
994
1077
  return motion.duration * SWEEP / 1600;
995
1078
  }
996
- const shadow = (layer) => layer.shadowRoot ?? layer.attachShadow({ mode: "open" });
997
1079
  /** The rect elements drawn into `layer`. */
998
- const rectsOf = (layer) => layer.shadowRoot ? [...layer.shadowRoot.children] : [];
999
- /** Draws `rects` into `layer`, reusing the elements already there. */
1080
+ const rectsOf = (layer) => [...layer.querySelectorAll(`:scope > [${ATTR_RECT}]`)];
1081
+ /** Soft floor on skeleton bone corners — anything sharper than this reads as a glyph,
1082
+ * not a placeholder, which fights the whole point of a skeleton. 4 px is the smallest
1083
+ * radius that still reads as "rounded" at typical display DPI. Applied only to
1084
+ * text / media / box bones; chrome bones carry the consumer's own radius verbatim. */
1085
+ const MIN_BONE_RADIUS = 4;
1086
+ const clampRadius = (radius) => radius.replace(/(\d+(?:\.\d+)?)px/g, (_, raw) => {
1087
+ const n = parseFloat(raw);
1088
+ return Number.isFinite(n) && n < MIN_BONE_RADIUS ? `${MIN_BONE_RADIUS}px` : `${n}px`;
1089
+ });
1090
+ /** Draws `rects` into `layer`, reusing the elements already there.
1091
+ *
1092
+ * Bones live in the light DOM (not a shadow root) so a consumer's stylesheet
1093
+ * can reach them — selectors like `[ask-rect="text"]`, `[ask-rect="media"]`,
1094
+ * `[ask-rect="box"]`, or the `--ask-base` / `--ask-highlight` custom
1095
+ * properties — and theme the skeleton with the consumer's own tokens rather
1096
+ * than plugin defaults. Positioning (x/y/width/height/radius) stays inline
1097
+ * because it is per-bone; fill colour comes from the stylesheet.
1098
+ *
1099
+ * Added after mount, so Vue/React hydration never sees them.
1100
+ */
1000
1101
  function drawSkeleton(layer, rects) {
1001
- const root = shadow(layer);
1102
+ const existing = rectsOf(layer);
1002
1103
  const rect = layer.getBoundingClientRect();
1003
1104
  const group = {
1004
1105
  left: rect.left + scrollX,
@@ -1008,27 +1109,50 @@ function drawSkeleton(layer, rects) {
1008
1109
  };
1009
1110
  const motion = motionOf(layer);
1010
1111
  rects.forEach((part, index) => {
1011
- let element = root.children[index];
1112
+ let element = existing[index];
1012
1113
  if (!element) {
1013
1114
  element = document.createElement("div");
1014
- element.setAttribute(ATTR_RECT, "");
1015
- element.style.cssText = `position:absolute;display:block;pointer-events:none;background-color:${BASE};background-repeat:no-repeat`;
1016
- root.append(element);
1115
+ element.style.cssText = `position:absolute;display:block;pointer-events:none;background-repeat:no-repeat`;
1116
+ layer.append(element);
1017
1117
  }
1118
+ element.setAttribute(ATTR_RECT, part.type);
1018
1119
  Object.assign(element.style, {
1019
1120
  left: `${part.x}px`,
1020
1121
  top: `${part.y}px`,
1021
1122
  width: `${part.width}px`,
1022
1123
  height: `${part.height}px`,
1023
- borderRadius: part.radius
1124
+ borderRadius: part.type === "chrome" ? part.radius : clampRadius(part.radius)
1024
1125
  });
1126
+ if (part.type === "chrome") {
1127
+ for (const anim of animationsOf(element)) anim.cancel();
1128
+ element.style.backgroundImage = "";
1129
+ element.style.backgroundSize = "";
1130
+ element.style.backgroundRepeat = "";
1131
+ const chrome = part.chrome;
1132
+ element.style.background = chrome?.background ?? "";
1133
+ element.style.borderTop = chrome?.borderTop ?? "";
1134
+ element.style.borderRight = chrome?.borderRight ?? "";
1135
+ element.style.borderBottom = chrome?.borderBottom ?? "";
1136
+ element.style.borderLeft = chrome?.borderLeft ?? "";
1137
+ element.style.boxShadow = chrome?.boxShadow ?? "";
1138
+ element.dataset.motion = "chrome";
1139
+ return;
1140
+ }
1141
+ if (element.dataset.motion === "chrome") {
1142
+ element.style.background = "";
1143
+ element.style.borderTop = "";
1144
+ element.style.borderRight = "";
1145
+ element.style.borderBottom = "";
1146
+ element.style.borderLeft = "";
1147
+ element.style.boxShadow = "";
1148
+ }
1025
1149
  const key = `${Math.round(group.left + part.x)}|${Math.round(part.y)}|${Math.round(part.height)}|${Math.round(group.left)}|${Math.round(group.width)}|${Math.round(group.height)}|${document.documentElement.clientWidth}|${motion.animation}|${motion.duration}`;
1026
1150
  if (element.dataset.motion !== key) {
1027
1151
  element.dataset.motion = key;
1028
1152
  shimmer(element, group, motion);
1029
1153
  }
1030
1154
  });
1031
- while (root.children.length > rects.length) root.lastElementChild.remove();
1155
+ for (let i = existing.length - 1; i >= rects.length; i--) existing[i].remove();
1032
1156
  }
1033
1157
  //#endregion
1034
1158
  //#region src/core/plan.ts
@@ -1749,9 +1873,13 @@ const NAMED = {
1749
1873
  together,
1750
1874
  sequence,
1751
1875
  smart,
1752
- sweep
1876
+ sweep,
1877
+ instant
1878
+ };
1879
+ const revealSpec = (mode = "smart") => {
1880
+ if (typeof mode !== "string") return mode;
1881
+ return NAMED[mode] ?? smart;
1753
1882
  };
1754
- const revealSpec = (mode = "smart") => typeof mode === "string" ? NAMED[mode] : mode;
1755
1883
  /** Longest a pane can take to leave under `mode`, for a framework that has to know up front. */
1756
1884
  function exitDuration(mode) {
1757
1885
  const spec = revealSpec(mode);
@@ -1803,7 +1931,7 @@ function holdImages(element, root) {
1803
1931
  const bone = bones.find((b) => sameBox(b.getBoundingClientRect(), rect));
1804
1932
  const box = bone?.getBoundingClientRect() ?? rect;
1805
1933
  const stand = document.createElement("div");
1806
- stand.setAttribute(ATTR_RECT, "");
1934
+ stand.setAttribute(ATTR_RECT, "media");
1807
1935
  Object.assign(stand.style, {
1808
1936
  position: "absolute",
1809
1937
  left: `${box.left - origin.left - root.clientLeft}px`,
@@ -1811,7 +1939,6 @@ function holdImages(element, root) {
1811
1939
  width: `${box.width}px`,
1812
1940
  height: `${box.height}px`,
1813
1941
  borderRadius: bone?.style.borderRadius || getComputedStyle(image).borderRadius,
1814
- backgroundColor: BASE,
1815
1942
  backgroundRepeat: "no-repeat",
1816
1943
  pointerEvents: "none"
1817
1944
  });