@taprootio/espalier 6.2.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -5
  3. package/custom-elements.json +1498 -778
  4. package/dist/action-menu/esp-action-menu-item.js +1 -0
  5. package/dist/action-menu/esp-action-menu.js +4 -3
  6. package/dist/box/esp-box.d.ts +49 -3
  7. package/dist/box/esp-box.js +26 -11
  8. package/dist/button/esp-button.d.ts +4 -4
  9. package/dist/date-picker/helpers/styles.js +1 -0
  10. package/dist/details/esp-details.d.ts +3 -0
  11. package/dist/details/esp-details.js +13 -6
  12. package/dist/dialog/esp-dialog.d.ts +82 -2
  13. package/dist/dialog/esp-dialog.js +71 -59
  14. package/dist/flyout/esp-flyout.d.ts +2 -2
  15. package/dist/flyout/esp-flyout.js +6 -5
  16. package/dist/focus-picker/esp-focus-picker.js +3 -2
  17. package/dist/footer/esp-footer.d.ts +3 -3
  18. package/dist/footer/esp-footer.js +10 -10
  19. package/dist/grid/esp-grid.d.ts +3 -0
  20. package/dist/grid/esp-grid.js +25 -17
  21. package/dist/header/esp-header-button.d.ts +6 -15
  22. package/dist/header/esp-header.d.ts +4 -2
  23. package/dist/header/esp-header.js +8 -7
  24. package/dist/image-picker/esp-image-picker.js +1 -0
  25. package/dist/image-upload/esp-image-upload.js +1 -0
  26. package/dist/info/esp-info.d.ts +3 -1
  27. package/dist/info/esp-info.js +8 -8
  28. package/dist/lightbox/esp-lightbox.d.ts +3 -0
  29. package/dist/lightbox/esp-lightbox.js +12 -9
  30. package/dist/menu/esp-menu-group.js +6 -2
  31. package/dist/menu/esp-menu-item.js +7 -3
  32. package/dist/menu/esp-menu.js +4 -2
  33. package/dist/page/esp-page.d.ts +1 -1
  34. package/dist/page/esp-page.styles.js +1 -0
  35. package/dist/pickers/esp-pick-one.d.ts +1 -2
  36. package/dist/pickers/esp-pick-some.d.ts +1 -1
  37. package/dist/pickers/esp-picker-item.js +9 -5
  38. package/dist/pickers/esp-picker-menu.js +2 -0
  39. package/dist/popover/esp-popover.d.ts +2 -4
  40. package/dist/repeater/esp-repeater.js +1 -0
  41. package/dist/root/esp-root.d.ts +4 -4
  42. package/dist/root/esp-root.js +5 -3
  43. package/dist/row/esp-row.d.ts +1 -2
  44. package/dist/search/esp-search.js +2 -0
  45. package/dist/section/esp-section.d.ts +1 -1
  46. package/dist/section/esp-section.js +2 -1
  47. package/dist/shared/configured-brand.d.ts +11 -37
  48. package/dist/shared/esp-element-base.d.ts +4 -1
  49. package/dist/shared/esp-element-base.js +27 -30
  50. package/dist/shared/justified-layout.d.ts +6 -18
  51. package/dist/shared/surface-layer.d.ts +12 -0
  52. package/dist/shared/surface-layer.js +10 -0
  53. package/dist/shared/theme.d.ts +7 -18
  54. package/dist/slider/esp-slider.d.ts +2 -4
  55. package/dist/stack/esp-stack.d.ts +1 -2
  56. package/dist/switch/esp-switch.d.ts +2 -4
  57. package/dist/tabs/esp-tab-group.d.ts +3 -0
  58. package/dist/tabs/esp-tab-group.js +7 -7
  59. package/dist/tooltip/esp-tooltip.js +1 -0
  60. package/dist/tree/esp-tree.d.ts +0 -5
  61. package/dist/tree/esp-tree.js +3 -0
  62. package/espalier.css-data.json +17 -1
  63. package/espalier.token-manifest.json +25 -1
  64. package/licenses/README.md +18 -15
  65. package/package.json +5 -1
@@ -1,19 +1,8 @@
1
- var c=function(f,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(f,e,t,r);else for(var i=f.length-1;i>=0;i--)(a=f[i])&&(s=(o<3?a(s):o>3?a(e,t,s):a(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as R,LitElement as C}from"lit";import{property as d,state as S}from"lit/decorators.js";import{subscribeToRootEvent as p}from"./root-event-subscription.js";import{traverseToClosest as g}from"./utilities.js";import{parseCssColor as w,serializeOklch as P,gamutMapToSRGB as x}from"./color-engine.js";import{computeVariants as v}from"../root/helpers/compute-variants.js";import{computeSemanticProperties as m}from"../root/helpers/compute-semantic-properties.js";import{DocumentSpriteController as E}from"./document-sprite.js";import{dataCompanionProperties as V}from"../root/helpers/data-companion-properties.js";import{dataSeriesProperties as U}from"../root/helpers/compute-theme-properties.js";import{lightnessRampProperties as I}from"../root/helpers/lightness-ramp-properties.js";import{ELEVATION_PROPERTIES as O,TYPE_ROLE_COLOR_PROPERTIES as A}from"./scale-engine.js";import{resolveContextTheme as y,resolveDataColorSource as _,semanticToCSS as D}from"./theme.js";import{alignAttributeTextInheritance as z,focusRing as N}from"./style-fragments.js";import{syncNormalizedAttribute as F}from"./attribute-helpers.js";import{INTENT_VARIANTS as k,normalizeIntentVariant as j}from"./intent-values.js";import{ESP_EVENTS as B}from"./events.js";class n extends C{get seedColor(){return this.seedColorBacker}set seedColor(e){this.seedColorBacker=e}focusResolvedElementAfterUpdate(e,t){const r=()=>{const o=e();return o?(o.focus(t),!0):!1};r()||this.updateComplete.then(()=>{r()})}focusShadowElementAfterUpdate(e,t){this.focusResolvedElementAfterUpdate(()=>this.shadowRoot?.querySelector(e),t)}emitValueChanged(e){this.dispatchEvent(new CustomEvent(B.VALUE_CHANGED,{detail:e,bubbles:!0,composed:!0}))}get intent(){return this.intentBacker}set intent(e){const t=typeof e=="string"?e.trim():"";t!==""&&!k.includes(t)&&!this.warnedUnknownIntents.has(t)&&(this.warnedUnknownIntents.add(t),console.warn(`Espalier intent: "${t}" is not an intent; expected one of ${k.join(", ")}. Treating it as "neutral".`));const r=this.intentBacker,o=j(e);F(this,"intent",o),o!==r&&(this.intentBacker=o,this.requestUpdate("intent",r),this.applyTokensWhenRootReady())}get context(){return this.contextBacker}set context(e){const t=e??"";t!==this.contextBacker&&(this.contextBacker=t,this.applyTokensWhenRootReady(),this.refreshDescendantIntentDerivations())}refreshDescendantIntentDerivations(){const e=new Set,t=o=>{for(const s of Array.from(o.children))r(s)},r=o=>{if(!e.has(o)){if(e.add(o),o instanceof n&&o.applyTokensWhenRootReady(),o.shadowRoot&&t(o.shadowRoot),o instanceof HTMLSlotElement)for(const s of o.assignedElements({flatten:!0}))r(s);t(o)}};t(this),this.shadowRoot&&t(this.shadowRoot)}static flattenedParent(e){return e instanceof Element&&e.assignedSlot?e.assignedSlot:e instanceof ShadowRoot?e.host:e.parentNode}resolveAncestorZoneTheme(e){let t=n.flattenedParent(this);for(;t;){if(t instanceof Element&&t.localName==="esp-root")return null;if(t instanceof n){const r=t.contextBacker.trim();if(r){const o=this.resolveNamedContextTheme(e,r);if(o)return o}}t=n.flattenedParent(t)}return null}connectedCallback(){super.connectedCallback();const e=this.syncRootFromDom(!1);e&&this.subscribeToRootEvents(e)}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeFromRootEvents(),this.clearScopedTokens(),this.espRoot=null}firstUpdated(e){this.syncRootFromDom(!0),this.applyTokensWhenRootReady()}syncRootFromDom(e){const t=g(this,"esp-root");if(!t){if(this.espRoot&&this.clearScopedTokens(),this.unsubscribeFromRootEvents(),this.espRoot=null,!e)return null;throw new Error("No esp-root ancestor found. Espalier components must be placed inside an <esp-root> element.")}const r=t!==this.espRoot,s=t.scheme==="dark"?"dark":"light",a=this.scheme!==s,i=this.seedColor!==t.seedColor;return this.espRoot=t,r&&this.isConnected&&this.subscribeToRootEvents(t),(r||a||i)&&(this.scheme=s,this.seedColor=t.seedColor,this.applyTokensWhenRootReady()),r&&this.requestUpdate(),t}applyTokensWhenRootReady(){const e=this.espRoot;if(e&&(!e.hasUpdated||e.isUpdatePending)){this.applyTokensAfterInitialRootUpdate(e);return}this.applyScopedColorTokens()}applyTokensAfterInitialRootUpdate(e){if(this.pendingInitialThemeRoot===e)return;this.pendingInitialThemeRoot=e;const t=e.updateComplete;if(!t){this.pendingInitialThemeRoot=null,this.applyScopedColorTokens();return}t.then(()=>{this.pendingInitialThemeRoot===e&&(this.pendingInitialThemeRoot=null),!(!this.isConnected||this.espRoot!==e)&&(this.scheme=e.scheme==="dark"?"dark":"light",this.seedColor=e.seedColor,this.applyScopedColorTokens())})}subscribeToRootEvents(e){this.rootEventSubscriptionsActive&&this.subscribedRoot===e||(this.unsubscribeFromRootEvents(),this.subscribedRoot=e,this.rootEventUnsubscribers=[p(e,"seed-color-changed",this.handleSeedColorChanged),p(e,"scheme-changed",this.handleSchemeChanged),p(e,"theme-changed",this.handleThemeChanged),p(e,"icon-sprite-url-changed",this.handleIconSpriteUrlChanged)],this.rootEventSubscriptionsActive=!0)}unsubscribeFromRootEvents(){if(this.rootEventSubscriptionsActive){for(const e of this.rootEventUnsubscribers)e();this.rootEventUnsubscribers=[],this.subscribedRoot=null,this.rootEventSubscriptionsActive=!1}}constructor(){super(),this.seedColorBacker="oklch(0.7 0.125 216)",this.espRoot=null,this.contextBacker="",this.scopedTokenOriginalValues=new Map,this.warnedUnknownContexts=new Set,this.pendingInitialThemeRoot=null,this.rootEventSubscriptionsActive=!1,this.subscribedRoot=null,this.rootEventUnsubscribers=[],this.intentBacker="neutral",this.intentEmitsTokens=!0,this.warnedUnknownIntents=new Set,this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.scheme="light",this.handleSeedColorChanged=e=>{this.syncRootFromDom(!1)&&(this.seedColor=e.seedColor,this.applyScopedColorTokens())},this.handleSchemeChanged=e=>{!this.syncRootFromDom(!1)||this.scheme===e.scheme||(this.scheme=e.scheme,this.applyScopedColorTokens())},this.handleThemeChanged=()=>{this.syncRootFromDom(!1)&&this.applyScopedColorTokens()},this.handleIconSpriteUrlChanged=()=>{this.syncRootFromDom(!1)&&this.requestUpdate()},new E(this,{reactToSpriteChanges:!1})}traverseToClosest(e){return g(this,e)}applyScopedColorTokens(){if(!this.espRoot)return;const e=this.intentEmitsTokens?n.intentColorSources[this.intentBacker]:"";if(!e&&!this.context.trim()){this.clearScopedTokens();return}const t=this.espRoot.activeTheme;if(!t){this.clearScopedTokens();return}const r=this.resolveContextTheme(t),o=r.theme,s=w(o.seedColor);if(!s)return;const a=v(s,o),i={};if(r.applied&&(Object.assign(i,m(o,a)),Object.assign(i,I(o)),Object.assign(i,O),Object.assign(i,A),Object.assign(i,V(i,U(o,s,l=>(typeof l=="string"?_(l,o.anchors):null)??o.seedColor)))),e){let l=o;r.applied||(l=this.resolveAncestorZoneTheme(t)??o);const b=l===o?a:v(s,l),T=m(l,b,{effectiveSource:(u,h)=>n.semanticActionTokens.has(u)?e:h});i["--esp-color-primary"]=P(x(b[e]));for(const u of n.semanticActionTokens){const h=D(u);i[h]=T[h]}}this.applyScopedTokenProperties(i)}resolveContextTheme(e){const t=this.context.trim();if(!t)return{applied:!1,theme:e};const r=this.resolveNamedContextTheme(e,t);return r?{applied:!0,theme:r}:(this.warnUnknownContextWhenSettled(t),{applied:!1,theme:e})}warnUnknownContextWhenSettled(e){if(this.warnedUnknownContexts.has(e))return;const t=this.espRoot;if(t&&!t.themeSettled){t.whenThemeSettled().then(()=>{if(!this.isConnected||this.espRoot!==t||this.context.trim()!==e)return;const r=t.activeTheme;r&&y(r,e)||this.warnUnknownContextWhenSettled(e)});return}this.warnedUnknownContexts.add(e),console.warn(`Espalier context: "${e}" is not defined by the active theme; inheriting root tokens.`)}resolveNamedContextTheme(e,t){return y(e,t)}applyScopedTokenProperties(e){for(const t of this.scopedTokenOriginalValues.keys())t in e||this.restoreScopedTokenProperty(t);for(const[t,r]of Object.entries(e))this.setScopedTokenProperty(t,r)}setScopedTokenProperty(e,t){const r=this.scopedTokenOriginalValues.get(e);if(r){const o=this.style.getPropertyValue(e),s=this.style.getPropertyPriority(e);(o!==r.generatedValue||s!==r.generatedPriority)&&(r.originalValue=o.length?o:null,r.originalPriority=s),r.generatedValue=t,r.generatedPriority=""}else{const o=this.style.getPropertyValue(e);this.scopedTokenOriginalValues.set(e,{generatedPriority:"",generatedValue:t,originalPriority:this.style.getPropertyPriority(e),originalValue:o.length?o:null})}this.style.setProperty(e,t)}restoreScopedTokenProperty(e){const t=this.scopedTokenOriginalValues.get(e);if(!t)return;const r=this.style.getPropertyValue(e),o=this.style.getPropertyPriority(e);(r!==t.generatedValue||o!==t.generatedPriority)&&(t.originalValue=r.length?r:null,t.originalPriority=o),t.originalValue===null?this.style.removeProperty(e):this.style.setProperty(e,t.originalValue,t.originalPriority),this.scopedTokenOriginalValues.delete(e)}clearScopedTokens(){for(const e of[...this.scopedTokenOriginalValues.keys()])this.restoreScopedTokenProperty(e)}}n.intentColorSources={danger:"danger",info:"info",neutral:"",success:"success",warning:"warning"},n.semanticActionTokens=new Set(["actionBackground","actionText"]),n.styles=[N(".esp-field:focus-within","--esp-field-focus-shadow"),z,R`
1
+ var c=function(f,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(f,e,t,r);else for(var i=f.length-1;i>=0;i--)(a=f[i])&&(s=(o<3?a(s):o>3?a(e,t,s):a(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as C,LitElement as S}from"lit";import{property as h,state as w}from"lit/decorators.js";import{subscribeToRootEvent as p}from"./root-event-subscription.js";import{traverseToClosest as b}from"./utilities.js";import{parseCssColor as P,serializeOklch as x,gamutMapToSRGB as E}from"./color-engine.js";import{computeVariants as m}from"../root/helpers/compute-variants.js";import{computeSemanticProperties as v}from"../root/helpers/compute-semantic-properties.js";import{DocumentSpriteController as V}from"./document-sprite.js";import{dataCompanionProperties as U}from"../root/helpers/data-companion-properties.js";import{dataSeriesProperties as _}from"../root/helpers/compute-theme-properties.js";import{lightnessRampProperties as I}from"../root/helpers/lightness-ramp-properties.js";import{ELEVATION_PROPERTIES as A,TYPE_ROLE_COLOR_PROPERTIES as O}from"./scale-engine.js";import{resolveContextTheme as y,resolveDataColorSource as D,semanticToCSS as z}from"./theme.js";import{alignAttributeTextInheritance as N,focusRing as F}from"./style-fragments.js";import{syncNormalizedAttribute as j}from"./attribute-helpers.js";import{INTENT_VARIANTS as k,normalizeIntentVariant as B}from"./intent-values.js";import{ESP_EVENTS as W}from"./events.js";import{surfaceLayerAttributes as R,surfaceLayerColor as L}from"./surface-layer.js";class n extends S{get seedColor(){return this.seedColorBacker}set seedColor(e){this.seedColorBacker=e}focusResolvedElementAfterUpdate(e,t){const r=()=>{const o=e();return o?(o.focus(t),!0):!1};r()||this.updateComplete.then(()=>{r()})}focusShadowElementAfterUpdate(e,t){this.focusResolvedElementAfterUpdate(()=>this.shadowRoot?.querySelector(e),t)}emitValueChanged(e){this.dispatchEvent(new CustomEvent(W.VALUE_CHANGED,{detail:e,bubbles:!0,composed:!0}))}get intent(){return this.intentBacker}set intent(e){const t=typeof e=="string"?e.trim():"";t!==""&&!k.includes(t)&&!this.warnedUnknownIntents.has(t)&&(this.warnedUnknownIntents.add(t),console.warn(`Espalier intent: "${t}" is not an intent; expected one of ${k.join(", ")}. Treating it as "neutral".`));const r=this.intentBacker,o=B(e);j(this,"intent",o),o!==r&&(this.intentBacker=o,this.requestUpdate("intent",r),this.applyTokensWhenRootReady())}get context(){return this.contextBacker}set context(e){const t=e??"";t!==this.contextBacker&&(this.contextBacker=t,this.applyTokensWhenRootReady(),this.refreshDescendantIntentDerivations())}refreshDescendantIntentDerivations(){const e=new Set,t=o=>{for(const s of Array.from(o.children))r(s)},r=o=>{if(!e.has(o)){if(e.add(o),o instanceof n&&o.applyTokensWhenRootReady(),o.shadowRoot&&t(o.shadowRoot),o instanceof HTMLSlotElement)for(const s of o.assignedElements({flatten:!0}))r(s);t(o)}};t(this),this.shadowRoot&&t(this.shadowRoot)}static flattenedParent(e){return e instanceof Element&&e.assignedSlot?e.assignedSlot:e instanceof ShadowRoot?e.host:e.parentNode}resolveAncestorZoneTheme(e){let t=n.flattenedParent(this);for(;t;){if(t instanceof Element&&t.localName==="esp-root")return null;if(t instanceof n){const r=t.contextBacker.trim();if(r){const o=this.resolveNamedContextTheme(e,r);if(o)return o}}t=n.flattenedParent(t)}return null}connectedCallback(){super.connectedCallback();const e=this.syncRootFromDom(!1);e&&this.subscribeToRootEvents(e)}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeFromRootEvents(),this.clearScopedTokens(),this.espRoot=null}firstUpdated(e){this.syncRootFromDom(!0),this.applyTokensWhenRootReady()}syncRootFromDom(e){const t=b(this,"esp-root");if(!t){if(this.espRoot&&this.clearScopedTokens(),this.unsubscribeFromRootEvents(),this.espRoot=null,!e)return null;throw new Error("No esp-root ancestor found. Espalier components must be placed inside an <esp-root> element.")}const r=t!==this.espRoot,s=t.scheme==="dark"?"dark":"light",a=this.scheme!==s,i=this.seedColor!==t.seedColor;return this.espRoot=t,r&&this.isConnected&&this.subscribeToRootEvents(t),(r||a||i)&&(this.scheme=s,this.seedColor=t.seedColor,this.applyTokensWhenRootReady()),r&&this.requestUpdate(),t}applyTokensWhenRootReady(){const e=this.espRoot;if(e&&(!e.hasUpdated||e.isUpdatePending)){this.applyTokensAfterInitialRootUpdate(e);return}this.applyScopedColorTokens()}applyTokensAfterInitialRootUpdate(e){if(this.pendingInitialThemeRoot===e)return;this.pendingInitialThemeRoot=e;const t=e.updateComplete;if(!t){this.pendingInitialThemeRoot=null,this.applyScopedColorTokens();return}t.then(()=>{this.pendingInitialThemeRoot===e&&(this.pendingInitialThemeRoot=null),!(!this.isConnected||this.espRoot!==e)&&(this.scheme=e.scheme==="dark"?"dark":"light",this.seedColor=e.seedColor,this.applyScopedColorTokens())})}subscribeToRootEvents(e){this.rootEventSubscriptionsActive&&this.subscribedRoot===e||(this.unsubscribeFromRootEvents(),this.subscribedRoot=e,this.rootEventUnsubscribers=[p(e,"seed-color-changed",this.handleSeedColorChanged),p(e,"scheme-changed",this.handleSchemeChanged),p(e,"theme-changed",this.handleThemeChanged),p(e,"icon-sprite-url-changed",this.handleIconSpriteUrlChanged)],this.rootEventSubscriptionsActive=!0)}unsubscribeFromRootEvents(){if(this.rootEventSubscriptionsActive){for(const e of this.rootEventUnsubscribers)e();this.rootEventUnsubscribers=[],this.subscribedRoot=null,this.rootEventSubscriptionsActive=!1}}constructor(){super(),this.seedColorBacker="oklch(0.7 0.125 216)",this.espRoot=null,this.contextBacker="",this.scopedTokenOriginalValues=new Map,this.warnedUnknownContexts=new Set,this.pendingInitialThemeRoot=null,this.rootEventSubscriptionsActive=!1,this.subscribedRoot=null,this.rootEventUnsubscribers=[],this.intentBacker="neutral",this.intentEmitsTokens=!0,this.warnedUnknownIntents=new Set,this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.scheme="light",this.handleSeedColorChanged=e=>{this.syncRootFromDom(!1)&&(this.seedColor=e.seedColor,this.applyScopedColorTokens())},this.handleSchemeChanged=e=>{!this.syncRootFromDom(!1)||this.scheme===e.scheme||(this.scheme=e.scheme,this.applyScopedColorTokens())},this.handleThemeChanged=()=>{this.syncRootFromDom(!1)&&this.applyScopedColorTokens()},this.handleIconSpriteUrlChanged=()=>{this.syncRootFromDom(!1)&&this.requestUpdate()},new V(this,{reactToSpriteChanges:!1})}traverseToClosest(e){return b(this,e)}applyScopedColorTokens(){if(!this.espRoot)return;const e=this.intentEmitsTokens?n.intentColorSources[this.intentBacker]:"";if(!e&&!this.context.trim()){this.clearScopedTokens();return}const t=this.espRoot.activeTheme;if(!t){this.clearScopedTokens();return}const r=this.resolveContextTheme(t),o=r.theme,s=P(o.seedColor);if(!s)return;const a=m(s,o),i={};if(r.applied&&(Object.assign(i,v(o,a)),Object.assign(i,I(o)),Object.assign(i,A),Object.assign(i,O),Object.assign(i,U(i,_(o,s,l=>(typeof l=="string"?D(l,o.anchors):null)??o.seedColor)))),e){let l=o;r.applied||(l=this.resolveAncestorZoneTheme(t)??o);const g=l===o?a:m(s,l),T=v(l,g,{effectiveSource:(u,d)=>n.semanticActionTokens.has(u)?e:d});i["--esp-color-primary"]=x(E(g[e]));for(const u of n.semanticActionTokens){const d=z(u);i[d]=T[d]}}this.applyScopedTokenProperties(i)}resolveContextTheme(e){const t=this.context.trim();if(!t)return{applied:!1,theme:e};const r=this.resolveNamedContextTheme(e,t);return r?{applied:!0,theme:r}:(this.warnUnknownContextWhenSettled(t),{applied:!1,theme:e})}warnUnknownContextWhenSettled(e){if(this.warnedUnknownContexts.has(e))return;const t=this.espRoot;if(t&&!t.themeSettled){t.whenThemeSettled().then(()=>{if(!this.isConnected||this.espRoot!==t||this.context.trim()!==e)return;const r=t.activeTheme;r&&y(r,e)||this.warnUnknownContextWhenSettled(e)});return}this.warnedUnknownContexts.add(e),console.warn(`Espalier context: "${e}" is not defined by the active theme; inheriting root tokens.`)}resolveNamedContextTheme(e,t){return y(e,t)}applyScopedTokenProperties(e){for(const t of this.scopedTokenOriginalValues.keys())t in e||this.restoreScopedTokenProperty(t);for(const[t,r]of Object.entries(e))this.setScopedTokenProperty(t,r)}setScopedTokenProperty(e,t){const r=this.scopedTokenOriginalValues.get(e);if(r){const o=this.style.getPropertyValue(e),s=this.style.getPropertyPriority(e);(o!==r.generatedValue||s!==r.generatedPriority)&&(r.originalValue=o.length?o:null,r.originalPriority=s),r.generatedValue=t,r.generatedPriority=""}else{const o=this.style.getPropertyValue(e);this.scopedTokenOriginalValues.set(e,{generatedPriority:"",generatedValue:t,originalPriority:this.style.getPropertyPriority(e),originalValue:o.length?o:null})}this.style.setProperty(e,t)}restoreScopedTokenProperty(e){const t=this.scopedTokenOriginalValues.get(e);if(!t)return;const r=this.style.getPropertyValue(e),o=this.style.getPropertyPriority(e);(r!==t.generatedValue||o!==t.generatedPriority)&&(t.originalValue=r.length?r:null,t.originalPriority=o),t.originalValue===null?this.style.removeProperty(e):this.style.setProperty(e,t.originalValue,t.originalPriority),this.scopedTokenOriginalValues.delete(e)}clearScopedTokens(){for(const e of[...this.scopedTokenOriginalValues.keys()])this.restoreScopedTokenProperty(e)}}n.intentColorSources={danger:"danger",info:"info",neutral:"",success:"success",warning:"warning"},n.semanticActionTokens=new Set(["actionBackground","actionText"]),n.styles=[R(":host"),R("[surface-layer]"),F(".esp-field:focus-within","--esp-field-focus-shadow"),N,C`
2
2
  :host {
3
3
 
4
4
  --_esp-font-body-fallback: system-ui, sans-serif;
5
5
  --_esp-font-monospace-fallback: monospace;
6
-
7
-
8
- --_esp-field-resolved-hover-bg: var(
9
- --esp-field-hover-bg,
10
- oklch(from var(--esp-field-background, var(--esp-color-layer-2)) calc(l * 0.88) c h)
11
- );
12
- --_esp-field-resolved-focus-bg: var(
13
- --esp-field-focus-bg,
14
- oklch(from var(--esp-field-background, var(--esp-color-layer-2)) calc(l * 0.82) c h)
15
- );
16
-
17
6
  display: block;
18
7
 
19
8
  * {
@@ -21,21 +10,6 @@ var c=function(f,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
21
10
  }
22
11
  }
23
12
 
24
- :host([scheme="light"]) {
25
- --_esp-field-resolved-hover-bg: var(
26
- --esp-field-hover-bg,
27
- oklch(
28
- from var(--esp-field-background, var(--esp-color-layer-2)) calc(l + (1 - l) * 0.5) c h
29
- )
30
- );
31
- --_esp-field-resolved-focus-bg: var(
32
- --esp-field-focus-bg,
33
- oklch(
34
- from var(--esp-field-background, var(--esp-color-layer-2)) calc(l + (1 - l) * 0.75) c h
35
- )
36
- );
37
- }
38
-
39
13
  ::placeholder {
40
14
  color: var(--esp-color-headings);
41
15
  }
@@ -68,13 +42,25 @@ var c=function(f,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
68
42
  }
69
43
 
70
44
  .esp-field {
45
+ --_esp-field-resolved-background: var(--esp-field-background, ${L(2)});
46
+
47
+
48
+ --_esp-field-resolved-hover-bg: var(
49
+ --esp-field-hover-bg,
50
+ oklch(from var(--_esp-field-resolved-background) calc(l * 0.88) c h)
51
+ );
52
+ --_esp-field-resolved-focus-bg: var(
53
+ --esp-field-focus-bg,
54
+ oklch(from var(--_esp-field-resolved-background) calc(l * 0.82) c h)
55
+ );
56
+
71
57
  font-family: var(
72
58
  --_esp-font-body-effective,
73
59
  var(--esp-font-body, var(--_esp-font-body-fallback))
74
60
  );
75
61
  font-size: var(--esp-size-font);
76
62
  font-weight: var(--esp-font-weight-body);
77
- background-color: var(--esp-field-background, var(--esp-color-layer-2));
63
+ background-color: var(--_esp-field-resolved-background);
78
64
  border-radius: var(--esp-size-border-radius);
79
65
  border: var(--esp-field-border-width, 1px) solid
80
66
  var(--esp-field-border-color, var(--esp-color-border));
@@ -125,6 +111,17 @@ var c=function(f,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
125
111
  }
126
112
  }
127
113
 
114
+ :host([scheme="light"]) .esp-field {
115
+ --_esp-field-resolved-hover-bg: var(
116
+ --esp-field-hover-bg,
117
+ oklch(from var(--_esp-field-resolved-background) calc(l + (1 - l) * 0.5) c h)
118
+ );
119
+ --_esp-field-resolved-focus-bg: var(
120
+ --esp-field-focus-bg,
121
+ oklch(from var(--_esp-field-resolved-background) calc(l + (1 - l) * 0.75) c h)
122
+ );
123
+ }
124
+
128
125
  .esp-field:has(button:disabled),
129
126
  .esp-field:has(a:disabled),
130
127
  .esp-field:has(input:disabled),
@@ -136,6 +133,6 @@ var c=function(f,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
136
133
  .esp-field:has(a:disabled):hover,
137
134
  .esp-field:has(input:disabled):hover,
138
135
  .esp-field:has(textarea:disabled):hover {
139
- background-color: var(--esp-field-background, var(--esp-color-layer-2));
136
+ background-color: var(--_esp-field-resolved-background);
140
137
  }
141
- `],c([S()],n.prototype,"seedColor",null),c([d({attribute:!1})],n.prototype,"correlationId",void 0),c([d({type:String,reflect:!0})],n.prototype,"scheme",void 0),c([d({type:String,attribute:"intent",reflect:!0,useDefault:!0})],n.prototype,"intent",null),c([d({type:String,attribute:"context",reflect:!0})],n.prototype,"context",null);export{n as EspalierElementBase};
138
+ `],c([w()],n.prototype,"seedColor",null),c([h({attribute:!1})],n.prototype,"correlationId",void 0),c([h({type:String,reflect:!0})],n.prototype,"scheme",void 0),c([h({type:String,attribute:"intent",reflect:!0,useDefault:!0})],n.prototype,"intent",null),c([h({type:String,attribute:"context",reflect:!0})],n.prototype,"context",null);export{n as EspalierElementBase};
@@ -67,25 +67,13 @@ export declare function normalizeAlbumMaxRowHeightVh(value: unknown): number;
67
67
  */
68
68
  export declare function normalizeMaxImagesPerRow(value: unknown, fallback?: number, maximum?: number): number;
69
69
  /**
70
- * Compute justified album rows with explicit cell widths.
70
+ * Compute justified album rows and the geometry a renderer needs for cropping.
71
71
  *
72
- * Algorithm:
73
- * 1. Add images to a row one at a time, scaled to the target row height.
74
- * 2. When the combined width overflows the container, the row breaks either
75
- * before or after the overflowing image — whichever leaves the row height
76
- * closer to the target. Keeping the image shrinks the row slightly below
77
- * target; pushing it to the next row stretches the row above target.
78
- * 3. Scale the finished row so it fills the container width exactly.
72
+ * Completed rows fill the available width. A row capped by `maxRowHeight` keeps
73
+ * relative cell widths, allowing `object-fit: cover` to crop its images. A final
74
+ * row below a finite `maxImagesPerRow` remains partial and preserves proportions;
75
+ * its height is capped by the preceding rows or target height and `maxRowHeight`.
79
76
  *
80
- * Completed rows always span the available width. When their justified height exceeds
81
- * `maxRowHeight`, their cells retain their relative widths while expanding to
82
- * the row width at the ceiling; a renderer can use `object-fit: cover` to crop
83
- * the resulting cells. A final row below a finite `maxImagesPerRow` instead
84
- * remains partial and preserves its image proportions. Its height is capped by
85
- * the tallest preceding row (or the target height when it is the only row) and
86
- * by `maxRowHeight`.
87
- *
88
- * With an omitted or invalid `maxImagesPerRow`, rows are unlimited in length
89
- * and every row is completed.
77
+ * An omitted or invalid `maxImagesPerRow` means unlimited, completed rows.
90
78
  */
91
79
  export declare function calculateAlbumLayout<T extends LayoutImage>(images: T[], options: AlbumLayoutOptions): AlbumLayoutRow<T>[];
@@ -0,0 +1,12 @@
1
+ import { type CSSResult } from "lit";
2
+ export type SurfaceLayer = 1 | 2 | 3 | 4;
3
+ /**
4
+ * Support `surface-layer="1|2|3|4"` on consumer surfaces in a shadow root.
5
+ * Include `surfaceLayerAttributes(":host")` for the consumer component's host,
6
+ * or `surfaceLayerAttributes("[surface-layer]")` for elements inside its shadow
7
+ * tree. Espalier installs these rules for its own hosts and root light DOM.
8
+ * The attribute declares depth; consumer components still paint their surface.
9
+ * A component that always paints a known layer can pass that depth as its
10
+ * default, so callers do not need to declare it on each instance.
11
+ */
12
+ export declare function surfaceLayerAttributes(selector: string, defaultLayer?: SurfaceLayer): CSSResult;
@@ -0,0 +1,10 @@
1
+ import{css as t,unsafeCSS as a}from"lit";function l(r,o){return a((o===void 0?"":`${r} { --_esp-surface-layer: ${o}; }
2
+ `)+[1,2,3,4].map(e=>`${r===":host"?`:host([surface-layer="${e}"])`:`${r}[surface-layer="${e}"]`} { --_esp-surface-layer: ${e}; }`).join(`
3
+ `))}function $(r,o=r){const e=["","var(--esp-color-layer-1)","var(--esp-color-layer-2)","var(--esp-color-layer-3)","var(--esp-color-layer-4)"],c=s=>s===o?e[s]:`${e[s].slice(0,-1)}, ${e[o]})`;let n=c(r);for(let s=r+1;s<=4;s++){const u=s-r;n=`color-mix(in oklch, ${n}, ${c(s)} calc(clamp(0, var(--_esp-surface-layer, 1) - ${u}, 1) * 100%))`}return a(n)}function f(r,o=":host"){return t`
4
+ ${a(o)} {
5
+ --_esp-surface-layer: ${r};
6
+ --_esp-surface-background: ${$(1,r)};
7
+ }
8
+ ${o===":host"?t``:a([1,2,3,4].map(e=>`:host([surface-layer="${e}"]) ${o} { --_esp-surface-layer: ${e}; }`).join(`
9
+ `))}
10
+ `}export{f as paintedSurface,l as surfaceLayerAttributes,$ as surfaceLayerColor};
@@ -254,19 +254,11 @@ export type PartialThemeContexts = Record<string, ThemeContext | undefined>;
254
254
  /** Ordered role names, for validation and iteration. */
255
255
  export declare const ROLE_NAMES: readonly RoleName[];
256
256
  /**
257
- * Which semantic tokens each role slot paints, and at which ramp stop.
257
+ * Map role slots to semantic tokens and ramp stops.
258
258
  *
259
- * This is the compilation table: it turns five designer-facing roles
260
- * into the twenty-three engine-room tokens. `dangerText` is absent by
261
- * design — the status family is reserved and keeps its own source.
262
- *
263
- * The `accent` role has no body-text slot on purpose. "Rose is
264
- * decorative only" is a structural guarantee here, not a comment: text
265
- * that must come from the accent family comes through `accent.text`,
266
- * the deepened variant a designer picked for legibility. `accent.hover`
267
- * lets a hover change *family*, not just lightness — "plum link, rose
268
- * hover" is an ordinary brand rule (ESP0172); absent, `linkHover` keeps
269
- * following `accent.text` exactly as before.
259
+ * `dangerText` stays outside the roles layer because status meanings are reserved.
260
+ * Accent body copy must use the legible `accent.text` slot. `accent.hover` can
261
+ * select a different family; without it, hovered links follow `accent.text`.
270
262
  */
271
263
  export declare const ROLE_TOKEN_PLAN: Readonly<Record<RoleName, Readonly<Record<string, ReadonlyArray<[SemanticColorName, LightnessKey]>>>>>;
272
264
  /**
@@ -323,13 +315,10 @@ interface CompileRoleOptions {
323
315
  actionSurfacePole?: (source: MappingSource, lightness: number) => "dark" | "light";
324
316
  }
325
317
  /**
326
- * Compile roles into semantic mappings.
318
+ * Compile declared roles into semantic mappings.
327
319
  *
328
- * Only the tokens a declared role owns are emitted, so a theme that
329
- * declares no roles compiles to nothing and every existing theme keeps
330
- * its exact output. Token-level `semanticMappings` layer over the
331
- * result — the engine room stays available for the cases roles do not
332
- * reach.
320
+ * A theme with no roles produces no role overrides. Token-level
321
+ * `semanticMappings` take precedence over the compiled result.
333
322
  */
334
323
  export declare function compileRoles(roles: ThemeRoles, lightness: LightnessMap, baseMappings: SemanticMappings, options?: CompileRoleOptions): Partial<SemanticMappings>;
335
324
  /**
@@ -2,10 +2,8 @@ import { type PropertyValues } from "lit";
2
2
  import { EspalierElementBase } from "../shared/esp-element-base.js";
3
3
  import { type EspalierFormField } from "../form-item/esp-form-item.js";
4
4
  /**
5
- * A range slider for selecting numeric values. Built entirely from
6
- * custom elements with ARIA `role="slider"` — no native
7
- * `<input type="range">` — for consistent cross-browser styling and
8
- * intentional touch interaction.
5
+ * A numeric range slider with ARIA `role="slider"`, keyboard support,
6
+ * and separate touch and pointer behavior.
9
7
  *
10
8
  * On touch devices, only dragging the thumb changes the value.
11
9
  * Tapping the track is ignored so the user can scroll the page
@@ -7,8 +7,7 @@ declare const STACK_ALIGNS: readonly ["start", "center", "end", "stretch"];
7
7
  export type EspalierAlign = (typeof STACK_ALIGNS)[number];
8
8
  export { STACK_GAPS, STACK_ALIGNS };
9
9
  /**
10
- * A vertical flow: children stack in a column with a themed gap —
11
- * "column, gap X" without writing flexbox (ADR-010's micro half).
10
+ * Stacks children vertically with a themed gap.
12
11
  *
13
12
  * ```html
14
13
  * <esp-stack gap="medium">
@@ -1,10 +1,8 @@
1
1
  import { EspalierElementBase } from "../shared/esp-element-base.js";
2
2
  import { type EspalierFormField } from "../form-item/esp-form-item.js";
3
3
  /**
4
- * A toggle switch for boolean on/off values. Uses a CSS-only
5
- * track-and-thumb design with a smooth sliding transition.
6
- * Functionally equivalent to a checkbox but visually communicates
7
- * an immediate state change rather than a deferred selection.
4
+ * An on/off switch for settings that take effect immediately. Use a
5
+ * checkbox when the choice should be applied with a later form submission.
8
6
  *
9
7
  * ```html
10
8
  * <esp-box>
@@ -6,6 +6,9 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
6
6
  * generated automatically from each child's `label` attribute.
7
7
  * Only one tab panel is visible at a time.
8
8
  *
9
+ * A field fills one layer above the surface it sits on.
10
+ * Use `surface-layer="1|2|3|4"` to select the default painted layer.
11
+ *
9
12
  * ```html
10
13
  * <esp-tab-group>
11
14
  * <esp-tab label="Overview">
@@ -1,4 +1,4 @@
1
- var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnPropertyDescriptor(t,a):e,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(l,t,a,e);else for(var n=l.length-1;n>=0;n--)(o=l[n])&&(r=(s<3?o(r):s>3?o(t,a,r):o(t,a))||r);return s>3&&r&&Object.defineProperty(t,a,r),r};import{css as u,html as c,nothing as v}from"lit";import{customElement as f,property as g,state as m}from"lit/decorators.js";import{createRef as y,ref as w}from"lit/directives/ref.js";import{EspalierElementBase as b}from"../shared/esp-element-base.js";import{ESP_EVENTS as x}from"../shared/events.js";import{EspalierTab as p}from"./esp-tab.js";import{disabledControl as T}from"../shared/style-fragments.js";let i=class extends b{constructor(){super(...arguments),this.panelsSlot=y(),this.disabled=!1,this.tabData=[]}getTabs(){const t=this.panelsSlot.value?Array.from(this.panelsSlot.value.assignedElements()).filter(a=>a instanceof p):[];return t.length>0?t:Array.from(this.children).filter(a=>a instanceof p)}syncTabData(){const t=this.getTabs();if(t.length===0){this.tabData=[];return}const a=t.find(e=>e.active&&!e.disabled);if(a)for(const e of t)e!==a&&(e.active=!1);else{const e=t.find(s=>!s.disabled);e?e.active=!0:t[0].active=!0}this.tabData=t.map((e,s)=>{const r=`esp-tab-btn-${this.correlationId}-${s}`,o=`esp-tab-panel-${this.correlationId}-${s}`;return e.panelId=o,e.ariaLabelledBy=r,{label:e.label,active:e.active,disabled:this.disabled||e.disabled,buttonId:r,panelId:o}})}activateTab(t){const a=this.getTabs(),e=a[t];if(!(!e||e.disabled||this.disabled)){for(const s of a)s.active=s===e;this.syncTabData(),this.dispatchEvent(new CustomEvent(x.TAB_GROUP_CHANGED,{detail:{index:t,label:e.label},bubbles:!0,composed:!0}))}}handleTabClick(t){this.activateTab(t),this.updateComplete.then(()=>{this.shadowRoot?.getElementById(this.tabData[t]?.buttonId)?.focus()})}handleKeyDown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;t.preventDefault();const e=this.tabData.map((n,h)=>({td:n,i:h})).filter(({td:n})=>!n.disabled).map(({i:n})=>n);if(e.length===0)return;const s=this.tabData.findIndex(n=>n.active),r=e.indexOf(s);let o;switch(t.key){case"ArrowRight":r===-1?o=e[0]:o=e[(r+1)%e.length];break;case"ArrowLeft":r===-1?o=e[e.length-1]:o=e[(r-1+e.length)%e.length];break;case"Home":o=e[0];break;case"End":o=e[e.length-1];break;default:return}this.activateTab(o),this.updateComplete.then(()=>{this.shadowRoot?.getElementById(this.tabData[o]?.buttonId)?.focus()})}handleChildUpdated(){this.syncTabData()}handleSlotChange(){this.syncTabData()}connectedCallback(){super.connectedCallback(),this.syncTabData()}willUpdate(t){super.willUpdate(t),t.has("disabled")&&this.syncTabData()}render(){return c`
1
+ var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnPropertyDescriptor(t,a):e,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(l,t,a,e);else for(var n=l.length-1;n>=0;n--)(o=l[n])&&(r=(s<3?o(r):s>3?o(t,a,r):o(t,a))||r);return s>3&&r&&Object.defineProperty(t,a,r),r};import{paintedSurface as u}from"../shared/surface-layer.js";import{css as v,html as c,nothing as f}from"lit";import{customElement as g,property as m,state as y}from"lit/decorators.js";import{createRef as w,ref as x}from"lit/directives/ref.js";import{EspalierElementBase as b}from"../shared/esp-element-base.js";import{ESP_EVENTS as T}from"../shared/events.js";import{EspalierTab as p}from"./esp-tab.js";import{disabledControl as k}from"../shared/style-fragments.js";let i=class extends b{constructor(){super(...arguments),this.panelsSlot=w(),this.disabled=!1,this.tabData=[]}getTabs(){const t=this.panelsSlot.value?Array.from(this.panelsSlot.value.assignedElements()).filter(a=>a instanceof p):[];return t.length>0?t:Array.from(this.children).filter(a=>a instanceof p)}syncTabData(){const t=this.getTabs();if(t.length===0){this.tabData=[];return}const a=t.find(e=>e.active&&!e.disabled);if(a)for(const e of t)e!==a&&(e.active=!1);else{const e=t.find(s=>!s.disabled);e?e.active=!0:t[0].active=!0}this.tabData=t.map((e,s)=>{const r=`esp-tab-btn-${this.correlationId}-${s}`,o=`esp-tab-panel-${this.correlationId}-${s}`;return e.panelId=o,e.ariaLabelledBy=r,{label:e.label,active:e.active,disabled:this.disabled||e.disabled,buttonId:r,panelId:o}})}activateTab(t){const a=this.getTabs(),e=a[t];if(!(!e||e.disabled||this.disabled)){for(const s of a)s.active=s===e;this.syncTabData(),this.dispatchEvent(new CustomEvent(T.TAB_GROUP_CHANGED,{detail:{index:t,label:e.label},bubbles:!0,composed:!0}))}}handleTabClick(t){this.activateTab(t),this.updateComplete.then(()=>{this.shadowRoot?.getElementById(this.tabData[t]?.buttonId)?.focus()})}handleKeyDown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;t.preventDefault();const e=this.tabData.map((n,h)=>({td:n,i:h})).filter(({td:n})=>!n.disabled).map(({i:n})=>n);if(e.length===0)return;const s=this.tabData.findIndex(n=>n.active),r=e.indexOf(s);let o;switch(t.key){case"ArrowRight":r===-1?o=e[0]:o=e[(r+1)%e.length];break;case"ArrowLeft":r===-1?o=e[e.length-1]:o=e[(r-1+e.length)%e.length];break;case"Home":o=e[0];break;case"End":o=e[e.length-1];break;default:return}this.activateTab(o),this.updateComplete.then(()=>{this.shadowRoot?.getElementById(this.tabData[o]?.buttonId)?.focus()})}handleChildUpdated(){this.syncTabData()}handleSlotChange(){this.syncTabData()}connectedCallback(){super.connectedCallback(),this.syncTabData()}willUpdate(t){super.willUpdate(t),t.has("disabled")&&this.syncTabData()}render(){return c`
2
2
  <div class="tab-container">
3
3
  <div class="tab-list" role="tablist" part="tab-list" @keydown=${this.handleKeyDown}>
4
4
  ${this.tabData.map((t,a)=>c`
@@ -9,7 +9,7 @@ var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnP
9
9
  part="tab-button"
10
10
  aria-selected=${t.active?"true":"false"}
11
11
  aria-controls=${t.panelId}
12
- aria-disabled=${t.disabled?"true":v}
12
+ aria-disabled=${t.disabled?"true":f}
13
13
  tabindex=${t.active?"0":"-1"}
14
14
  ?disabled=${t.disabled}
15
15
  @click=${()=>this.handleTabClick(a)}
@@ -20,13 +20,13 @@ var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnP
20
20
  </div>
21
21
  <div class="panels" part="panels">
22
22
  <slot
23
- ${w(this.panelsSlot)}
23
+ ${x(this.panelsSlot)}
24
24
  @slotchange=${this.handleSlotChange}
25
25
  @esp-internal-tab-updated=${this.handleChildUpdated}
26
26
  ></slot>
27
27
  </div>
28
28
  </div>
29
- `}};i.styles=[...b.styles,T(".tab-button[disabled]"),u`
29
+ `}};i.styles=[...b.styles,u(1),k(".tab-button[disabled]"),v`
30
30
  :host {
31
31
  display: block;
32
32
  --_esp-tab-resolved-button-hover: var(
@@ -45,7 +45,7 @@ var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnP
45
45
  .tab-container {
46
46
 
47
47
  --_esp-tab-inner-radius: max(0px, calc(var(--esp-size-border-radius) - 1px));
48
- background-color: var(--esp-tab-color-background, var(--esp-color-layer-1));
48
+ background-color: var(--esp-tab-color-background, var(--_esp-surface-background));
49
49
  border-radius: var(--esp-size-border-radius);
50
50
  box-shadow: 1px 1px 4px var(--esp-color-shadow);
51
51
  border: 1px solid var(--esp-tab-color-border, var(--esp-color-border));
@@ -56,7 +56,7 @@ var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnP
56
56
  .tab-list {
57
57
  display: flex;
58
58
  overflow-x: auto;
59
- background-color: var(--esp-tab-color-strip-background, var(--esp-color-layer-1));
59
+ background-color: var(--esp-tab-color-strip-background, var(--_esp-surface-background));
60
60
  border-bottom: 1px solid var(--esp-tab-color-border, var(--esp-color-border));
61
61
  border-start-start-radius: var(--_esp-tab-inner-radius);
62
62
  border-start-end-radius: var(--_esp-tab-inner-radius);
@@ -119,4 +119,4 @@ var d=function(l,t,a,e){var s=arguments.length,r=s<3?t:e===null?e=Object.getOwnP
119
119
  .panels {
120
120
 
121
121
  }
122
- `],d([g({type:Boolean,reflect:!0})],i.prototype,"disabled",void 0),d([m()],i.prototype,"tabData",void 0),i=d([f("esp-tab-group")],i);export{i as EspalierTabGroup};
122
+ `],d([m({type:Boolean,reflect:!0})],i.prototype,"disabled",void 0),d([y()],i.prototype,"tabData",void 0),i=d([g("esp-tab-group")],i);export{i as EspalierTabGroup};
@@ -44,6 +44,7 @@ var o=function(a,e,t,n){var p=arguments.length,r=p<3?e:n===null?n=Object.getOwnP
44
44
  }
45
45
 
46
46
  .tooltip-content {
47
+ --_esp-surface-layer: 1;
47
48
 
48
49
  white-space: normal;
49
50
  overflow-wrap: anywhere;
@@ -127,11 +127,6 @@ export declare function buildWebTreePath({ parentPath, segment, rootPath, }: Esp
127
127
  * For static declarative node definitions, see
128
128
  * [`<esp-tree-item>`](/components/tree/item/).
129
129
  *
130
- * The name is apt: an espalier is a tree trained flat against a frame,
131
- * so the visual language — branches trained to vertical guide wires,
132
- * grafting a new shoot onto an existing limb — is the component's own
133
- * metaphor.
134
- *
135
130
  * ## Data-driven first, composition-capable
136
131
  *
137
132
  * Bind a hierarchy to the `nodes` property for the primary, data-driven
@@ -311,6 +311,7 @@ var d=function(c,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnP
311
311
  }
312
312
 
313
313
  .row {
314
+ --_esp-surface-layer: 1;
314
315
  background-color: var(--esp-tree-row-bg, var(--esp-color-layer-1));
315
316
  border: 1px solid var(--esp-tree-row-border-color, var(--esp-color-border));
316
317
  border-radius: var(--esp-size-border-radius);
@@ -334,6 +335,7 @@ var d=function(c,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnP
334
335
  }
335
336
 
336
337
  .row:hover {
338
+ --_esp-surface-layer: 2;
337
339
  background-color: var(--esp-tree-hover-bg, var(--esp-color-layer-2));
338
340
  border-color: oklch(
339
341
  from var(--esp-tree-row-border-color, var(--esp-color-border)) calc(l * 1.1) c h
@@ -341,6 +343,7 @@ var d=function(c,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnP
341
343
  }
342
344
 
343
345
  .row.selected {
346
+ --_esp-surface-layer: 3;
344
347
  border-color: var(--esp-color-primary);
345
348
  background-color: var(--esp-tree-selected-bg, var(--esp-color-layer-3));
346
349
  }
@@ -469,9 +469,25 @@
469
469
  "name": "--esp-dialog-bg-opacity",
470
470
  "description": "The opacity of the dialog overlay background."
471
471
  },
472
+ {
473
+ "name": "--esp-dialog-inset-block-end",
474
+ "description": "The bottom edge of the area the dialog covers, as a length from the viewport bottom. Defaults to `0px`."
475
+ },
476
+ {
477
+ "name": "--esp-dialog-inset-block-start",
478
+ "description": "The top edge of the area the dialog covers, as a length from the viewport top. Defaults to `0px`."
479
+ },
480
+ {
481
+ "name": "--esp-dialog-inset-inline-end",
482
+ "description": "The trailing edge (right in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
483
+ },
484
+ {
485
+ "name": "--esp-dialog-inset-inline-start",
486
+ "description": "The leading edge (left in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
487
+ },
472
488
  {
473
489
  "name": "--esp-field-background",
474
- "description": "Background color of the shared field shell. Defaults to `var(--esp-color-layer-2)`."
490
+ "description": "Background color of the shared field shell. Defaults to one layer above the nearest declared surface, capped at `var(--esp-color-layer-4)`, or `var(--esp-color-layer-2)` without a declared surface. An explicit override wins."
475
491
  },
476
492
  {
477
493
  "name": "--esp-field-border-color",
@@ -633,10 +633,34 @@
633
633
  "component": "esp-dialog",
634
634
  "description": "The opacity of the dialog overlay background."
635
635
  },
636
+ {
637
+ "name": "--esp-dialog-inset-block-end",
638
+ "category": "component",
639
+ "component": "esp-dialog",
640
+ "description": "The bottom edge of the area the dialog covers, as a length from the viewport bottom. Defaults to `0px`."
641
+ },
642
+ {
643
+ "name": "--esp-dialog-inset-block-start",
644
+ "category": "component",
645
+ "component": "esp-dialog",
646
+ "description": "The top edge of the area the dialog covers, as a length from the viewport top. Defaults to `0px`."
647
+ },
648
+ {
649
+ "name": "--esp-dialog-inset-inline-end",
650
+ "category": "component",
651
+ "component": "esp-dialog",
652
+ "description": "The trailing edge (right in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
653
+ },
654
+ {
655
+ "name": "--esp-dialog-inset-inline-start",
656
+ "category": "component",
657
+ "component": "esp-dialog",
658
+ "description": "The leading edge (left in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
659
+ },
636
660
  {
637
661
  "name": "--esp-field-background",
638
662
  "category": "shared-hook",
639
- "description": "Background color of the shared field shell. Defaults to `var(--esp-color-layer-2)`."
663
+ "description": "Background color of the shared field shell. Defaults to one layer above the nearest declared surface, capped at `var(--esp-color-layer-4)`, or `var(--esp-color-layer-2)` without a declared surface. An explicit override wins."
640
664
  },
641
665
  {
642
666
  "name": "--esp-field-border-color",
@@ -1,36 +1,39 @@
1
- # Espalier Commercial Licensing Drafts
1
+ # Licensing and commercial documents
2
2
 
3
- These files are draft business/legal documents for attorney review. They are
4
- intended to support a proprietary public package containing compiled and
5
- obfuscated Espalier artifacts, without publishing source code.
3
+ The [binary license](ESPALIER_PROPRIETARY_BINARY_LICENSE.md) governs the public
4
+ compiled package. Its approved text is recorded in
5
+ [LICENSE_APPROVAL.json](LICENSE_APPROVAL.json); the publish gate verifies that
6
+ the shipped text matches that approval.
6
7
 
7
- They are not legal advice and should not be used with customers or partners
8
- until reviewed and adapted by qualified IP and technology-transactions counsel.
8
+ The order form, term sheets, and escrow addendum are commercial templates for
9
+ attorney review. Have counsel review and adapt them before customer or partner
10
+ use. Notices and provenance records document the assets distributed with
11
+ Espalier.
9
12
 
10
13
  ## Documents
11
14
 
12
- - `ESPALIER_PROPRIETARY_BINARY_LICENSE.md` - default license for the public
15
+ - [ESPALIER_PROPRIETARY_BINARY_LICENSE.md](ESPALIER_PROPRIETARY_BINARY_LICENSE.md) - default license for the public
13
16
  compiled package and for paid production use by direct enterprise customers.
14
- - `ESPALIER_ENTERPRISE_ORDER_FORM_TEMPLATE.md` - short commercial order form to
17
+ - [ESPALIER_ENTERPRISE_ORDER_FORM_TEMPLATE.md](ESPALIER_ENTERPRISE_ORDER_FORM_TEMPLATE.md) - short commercial order form to
15
18
  pair with the binary license for direct customers.
16
- - `ESPALIER_STRATEGIC_PARTNER_LICENSE_TERM_SHEET.md` - draft terms for a
19
+ - [ESPALIER_STRATEGIC_PARTNER_LICENSE_TERM_SHEET.md](ESPALIER_STRATEGIC_PARTNER_LICENSE_TERM_SHEET.md) - draft terms for a
17
20
  strategic enterprise reseller/OEM/private-label deal with a $3M+ annual
18
21
  minimum guarantee.
19
- - `ESPALIER_SOURCE_ESCROW_ADDENDUM.md` - source escrow terms for enterprise
22
+ - [ESPALIER_SOURCE_ESCROW_ADDENDUM.md](ESPALIER_SOURCE_ESCROW_ADDENDUM.md) - source escrow terms for enterprise
20
23
  reassurance without giving source away in the ordinary case.
21
- - `ESPALIER_SOURCE_SNAPSHOT_PURCHASE_TERM_SHEET.md` - draft terms for a
24
+ - [ESPALIER_SOURCE_SNAPSHOT_PURCHASE_TERM_SHEET.md](ESPALIER_SOURCE_SNAPSHOT_PURCHASE_TERM_SHEET.md) - draft terms for a
22
25
  $20M+ one-time source snapshot transaction while preserving Taproot's
23
26
  continuing ownership and future development rights unless counsel negotiates
24
27
  a broader sale.
25
- - `ESPALIER_DEAL_READINESS_CHECKLIST.md` - practical readiness checklist for
28
+ - [ESPALIER_DEAL_READINESS_CHECKLIST.md](ESPALIER_DEAL_READINESS_CHECKLIST.md) - practical readiness checklist for
26
29
  lawyer review, diligence, packaging, and outreach.
27
- - `THIRD_PARTY_NOTICES.md` - third-party open-source notices for materials
30
+ - [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) - third-party open-source notices for materials
28
31
  copied into Espalier distribution artifacts, including Lit Virtualizer,
29
32
  Tabler Icons, and the self-hosted documentation shell fonts.
30
- - `asset-provenance.json` and `ASSET_PROVENANCE.md` - machine-readable and
33
+ - [asset-provenance.json](asset-provenance.json) and [ASSET_PROVENANCE.md](ASSET_PROVENANCE.md) - machine-readable and
31
34
  human-readable provenance records for generated fonts, icons, vendored
32
35
  runtime source, textures, demo datasets, and docs assets.
33
- - `open-source-audit/` - preserved dependency/license audit material for
36
+ - [open-source-audit/](open-source-audit/) - preserved dependency/license audit material for
34
37
  open-source diligence, SBOM planning, and third-party notice review.
35
38
 
36
39
  ## Commercial Position
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taprootio/espalier",
3
- "version": "6.2.0",
3
+ "version": "6.4.0",
4
4
  "packageManager": "bun@1.3.12",
5
5
  "description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
6
6
  "customElements": "custom-elements.json",
@@ -373,6 +373,10 @@
373
373
  "./textures/espalier-paper.png": "./css/textures/espalier-paper.png",
374
374
  "./textures/espalier-grain.png": "./css/textures/espalier-grain.png",
375
375
  "./textures/espalier-grunge.png": "./css/textures/espalier-grunge.png",
376
+ "./shared/surface-layer": {
377
+ "types": "./dist/shared/surface-layer.d.ts",
378
+ "import": "./dist/shared/surface-layer.js"
379
+ },
376
380
  "./custom-elements.json": "./custom-elements.json",
377
381
  "./espalier.css-data.json": "./espalier.css-data.json",
378
382
  "./css/esp-reset.css": "./css/esp-reset.css",