efficient-web-builder 16.0.2 → 17.0.1

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 (48) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/components/ContactLocations.js +6 -6
  3. package/dist/components/Footprint.js +7 -7
  4. package/dist/components/HeroGroup.d.ts +5 -1
  5. package/dist/components/HeroGroup.js +1 -1
  6. package/dist/components/HeroSection.js +1 -1
  7. package/dist/components/HeroSingle.js +1 -1
  8. package/dist/components/HeroSlide.js +1 -1
  9. package/dist/components/PartSettingsPanel.d.ts +0 -20
  10. package/dist/components/PartSettingsPanel.js +1 -1
  11. package/dist/components/PartTextBox.d.ts +2 -1
  12. package/dist/components/PartTextBox.js +1 -1
  13. package/dist/components/SectionEditor.d.ts +0 -1
  14. package/dist/components/SectionEditor.js +1 -1
  15. package/dist/components/storefront-editor.css +35 -11
  16. package/dist/lib/content/borders.d.ts +21 -0
  17. package/dist/lib/content/borders.js +1 -0
  18. package/dist/lib/editor-words-catalogue.d.ts +14 -12
  19. package/dist/lib/editor-words-catalogue.js +5 -5
  20. package/dist/lib/maps-loader.d.ts +5 -0
  21. package/dist/lib/maps-loader.js +1 -1
  22. package/dist/lib/puck/blocks/general/CategoryBar/fields.js +1 -1
  23. package/dist/lib/puck/blocks/general/Chart/fields.js +1 -1
  24. package/dist/lib/puck/blocks/general/Countdown/fields.js +1 -1
  25. package/dist/lib/puck/blocks/general/Flex/fields.js +1 -1
  26. package/dist/lib/puck/blocks/general/HeroGroup/fields.js +1 -1
  27. package/dist/lib/puck/blocks/general/HeroGroup/render.js +1 -1
  28. package/dist/lib/puck/blocks/general/HeroSlide/fields.js +1 -1
  29. package/dist/lib/puck/blocks/general/ImageBlock/fields.js +1 -1
  30. package/dist/lib/puck/blocks/general/LogoBlock/fields.js +1 -1
  31. package/dist/lib/puck/blocks/general/Logos/fields.js +1 -1
  32. package/dist/lib/puck/blocks/general/SectionHeader/fields.js +1 -1
  33. package/dist/lib/puck/controls.d.ts +17 -0
  34. package/dist/lib/puck/controls.js +1 -1
  35. package/dist/lib/puck/field-groups.js +1 -1
  36. package/dist/lib/puck/part-styles.d.ts +2 -1
  37. package/dist/lib/puck/part-styles.js +2 -2
  38. package/dist/lib/puck/passes/borders.d.ts +2 -0
  39. package/dist/lib/puck/passes/borders.js +1 -0
  40. package/dist/lib/puck/passes/index.js +1 -1
  41. package/dist/lib/puck/passes/inspector.js +1 -1
  42. package/dist/lib/puck/passes/section-padding.js +1 -1
  43. package/dist/lib/puck/passes/types.d.ts +5 -0
  44. package/dist/lib/source-rules/label-vocabulary.js +3 -3
  45. package/dist/lib/source-rules/one-border-resolver.d.ts +4 -0
  46. package/dist/lib/source-rules/one-border-resolver.js +1 -0
  47. package/dist/lib/source-rules/support/part-slider-call-sites.js +3 -3
  48. package/package.json +5 -5
@@ -1 +1 @@
1
- "use client";import{jsx as n,jsxs as f,Fragment as v}from"react/jsx-runtime";import{useState as fe}from"react";import{useEasel as ue}from"efficient-easel/easel";import{InspectorHead as he,InspectorIconButton as R}from"efficient-easel/chrome";import{DuplicateIcon as Se,TrashIcon as we}from"efficient-easel/icons";import{panelFieldsOf as be}from"../lib/puck/panel-fields.js";import{TICKER_PART_LABEL as F}from"./PreviewTickerContext.js";import ge from"./SectionIcon.js";import{PanelHideButton as x}from"./SidePanelHead.js";import{useEditorSession as ke}from"../lib/editor-session-context.js";import{say as i}from"../lib/editor-words.js";import ve,{HintsToggle as Pe,SHOW_HINTS_DEFAULT as ye}from"./WebsiteSettingsPanel.js";import Ee from"./ChatSettingsPanel.js";import Ie from"./SocialLinksPanel.js";import Ne from"./TickerSettingsPanel.js";import Le,{PartSourceNote as Oe,partStyleName as Te}from"./PartSettingsPanel.js";import He from"./DuplicateToPageMenu.js";import{useStorefrontDocument as _e}from"./StorefrontDocumentContext.js";import{usePreviewHeader as De}from"./PreviewHeaderContext.js";import{usePartStyle as Ae}from"./PreviewPartStyleContext.js";import{useSectionOps as Ce}from"../lib/puck/use-section-ops.js";import{SELECTION_MODE as Re}from"../lib/editor-screen.js";import{usePreviewParts as Fe}from"./PreviewPartsContext.js";import{entryPartsOf as xe,SectionTextEntries as Be}from"./SectionTextEntries.js";import{SectionTextSuppressProvider as ze}from"../lib/puck/section-text-suppress.js";import{HEADER_TYPE as Ke,ROOT_ZONE as B}from"../lib/puck/content-tree.js";import{websiteDuplicateBlocked as Me}from"../lib/puck/every-page.js";import{FOOTER_TYPE as P}from"../lib/puck/footer-blocks.js";import We from"./SwitchToBoxFooter.js";import{SiteFields as z}from"./SiteFields.js";import{SettingsSwitch as je}from"efficient-easel/panel";import{foldTopTier as Ue}from"../lib/puck/field-groups.js";import{FoldHeadingScope as Ye}from"../lib/puck/panel-heading-scope.js";import{partRowField as Ze}from"../lib/puck/part-row-field.js";import{decodePartKey as $e,partRowHeadLabel as qe}from"../lib/puck/part-rows.js";import{encodePartId as K,partHeadLabel as Ge,partLabel as Je,sectionTextParts as Qe}from"../lib/puck/text-parts.js";import{partSourceOf as Ve,sourceSlugOf as Xe}from"../lib/puck/source-bound-parts.js";const Ut=Re,Yt={kind:"header"},Zt={kind:"website"},$t={kind:"chat"},qt={kind:"social"},g="Part";function M(e){return i("Part of {name}",{name:i(e)})}function et(e,o,r){const c=e.describeNode(o);return{name:r,kindLabel:c?M(c.label):i(g)}}function tt(e){switch(e){case"Header":return{title:i("Header settings belong to a website."),own:i("Each website created from this template sets its own header afterwards.")};case"Appearance":return{title:i("Appearance settings belong to a website."),own:i("Each website created from this template sets its own appearance afterwards.")};case"Live chat":return{title:i("Live chat settings belong to a website."),own:i("Each website created from this template sets its own live chat afterwards.")};case"Social link":return{title:i("Social link settings belong to a website."),own:i("Each website created from this template sets its own social link afterwards.")};default:return{title:i("{what} settings belong to a website.",{what:e}),own:i("Each website created from this template sets its own {what} afterwards.",{what:e.toLowerCase()})}}}function W({what:e}){const o=tt(e);return f("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:o.title})}),f("p",{children:[i("A template is a blueprint — it has no website of its own, so there is nothing here to change.")," ",o.own]})]})}const nt={header:{name:"Header",kindLabel:"Site settings",icon:"header",render:(e,o)=>{const r=o.hostPanels?.header;return r?n(r,{placeholderMode:o.capabilities.placeholderFrames,tokenRef:o.tokenRef,siteId:o.siteId,websiteName:o.websiteName,onOpenWebsiteSettings:o.onOpenWebsiteSettings,onAuthExpired:()=>o.notifyParent("storefront-editor:auth-expired")}):null}},website:{name:"Appearance",kindLabel:"Site settings",icon:"website",render:(e,o)=>n(ve,{themeFromDocument:!o.capabilities.hasSiteTheme,tokenRef:o.tokenRef,siteId:o.siteId,onNotify:o.onNotify})},chat:{name:"Live chat",kindLabel:"Site settings",icon:"chat",render:()=>n(Ee,{})},social:{name:"Social links",kindLabel:"Site settings",icon:"social",render:()=>n(Ie,{unavailable:n(W,{what:"Social link"})})},ticker:{name:F,kindLabel:g,icon:"ticker",head:(e,o)=>e.kind==="ticker"?et(o,e.heroId,i(F)):null,render:e=>n(Ne,{heroId:e.kind==="ticker"?e.heroId:""})},part:{name:g,kindLabel:g,icon:"Text",head:(e,o)=>{if(e.kind!=="part")return null;const r=o.describeNode(e.nodeId);if(!r)return null;const{key:c,row:h}=$e(e.propKey),w=h?Ze(r.fields[c],h):r.fields[c],u=qe(i(Ge(Je(w??{},c))),h),p=o.styleNameOfPart(e.nodeId,e.propKey);return{name:p!==null?i(p):u,kindLabel:M(r.label)}},render:(e,o)=>e.kind==="part"?n(Le,{nodeId:e.nodeId,propKey:e.propKey,onBack:()=>o.onSelectNode(e.nodeId),onEditStyle:o.onOpenSiteStyles}):null}},ot=new Set(["header","website","chat"]);function it(e,o){if(e==="puck")return null;const r=nt[e];return ot.has(e)&&!o.hasSiteSettings?{...r,kindLabel:"Not part of a template",render:()=>n(W,{what:r.name})}:r}function rt({mode:e,onOpenWebsiteSettings:o,onOpenSiteStyles:r,onSelectNode:c,hideNodeActions:h=!1,onNotify:w,onHidePanel:u}){const{capabilities:p,tokenRef:y,notifyParent:j,currentSlug:U,siteId:E,runAuthed:Y,readOnly:Z}=_e(),{websiteName:$,fonts:q}=De(),{partStyle:I}=Ae(),b=Ce({readOnly:Z}),{select:G}=Fe(),{selectedItem:t,getItemById:N,getSelectorForId:J,config:d,appState:Q}=ue(l=>l),V=be(d,t?{type:t.type,props:t.props}:null),L=t?Qe(V??d.components[t.type]?.fields,t.props):[],X=l=>d.components[l]?.label??l,s=t?J(t.props.id):void 0,a=it(e.kind,p),ee=ke(),O={capabilities:p,tokenRef:y,hostPanels:ee.chrome?.panels,describeNode:l=>{const m=N(l);if(!m)return null;const S=d.components[m.type];return{type:m.type,label:S?.label??m.type,fields:S?.fields??{}}},styleNameOfPart:(l,m)=>{const S=N(l);if(!S)return null;const de=K(l,m),me=I?.partId===de?I:null;return Te(S.props,m,me,q)},siteId:E,websiteName:$??null,notifyParent:j,onNotify:w,onOpenWebsiteSettings:o,onOpenSiteStyles:r,onSelectNode:c},T=a?.head?.(e,O)??null,te=T?.name??(a?i(a.name):t?i(X(t.type)):i("Page settings")),ne=T?.kindLabel??(a?i(a.kindLabel):t?s&&s.zone!==B?i("Block"):i("Section"):i("Page")),oe=a?a.icon:t?t.type:"page",H=a?null:t?d.components[t.type]?.fields??null:d.root?.fields??null,ie=H?Ue(H):2,_=e.kind==="puck"&&t?Ve(t.type):null,re=!!t&&!!s&&s.zone===B&&t.type!==P&&t.type!==Ke,k=Me(Q?.data,t),se=()=>{k||s&&b.duplicateComponent(s.zone,s.index)},ae=()=>{s&&(b.removeComponent(s.zone,s.index),b.select(null))},le=t?d.components[t.type]?.defaultProps?.previewHover:void 0,D=e.kind==="puck"&&!!t&&!!s&&le!==void 0,A=D&&t.props.previewHover===!0,ce=()=>{!t||!s||b.replaceComponent(s.zone,s.index,{...t,props:{...t.props,previewHover:!A}})},[C,pe]=fe(ye);return f("div",{className:`es-sidepanel es-sidepanel--right sf-panel sf-panel--right${C||!(!a&&!!t)?"":" sf-hints-folded"}`,children:[n(he,{icon:n(ge,{type:oe,size:15}),name:te,kind:ne,actions:!h&&e.kind==="puck"&&t&&t.type!==P?f(v,{children:[n(R,{label:i("Duplicate section"),title:k??void 0,disabled:k!==null,onClick:se,children:n(Se,{size:15})}),re&&p.hasSiteSettings&&n(He,{node:t,currentSlug:U,siteId:E??void 0,tokenRef:y,runAuthed:Y,onNotify:w}),n(R,{label:i("Remove section"),danger:!0,onClick:ae,children:n(we,{size:15})}),u?n(x,{side:"right",onHide:u,divider:!0}):null]}):u?n(x,{side:"right",onHide:u}):void 0}),D&&f("div",{className:"sf-preview-pin",children:[f("div",{className:"sf-preview-pin-text",children:[n("span",{className:"sf-preview-pin-label",children:i("Preview hover state")}),n("span",{className:"sf-preview-pin-hint",children:i("not shown live")})]}),n(je,{checked:A,onChange:ce,ariaLabel:i("Preview hover state")})]}),n(Ye,{tier:ie,children:n("div",{className:"sf-insp-body sf-scroll",children:a?a.render(e,O):t?f(v,{children:[t.type===P&&p.hasSiteSettings&&n(We,{}),n(ze,{children:n(z,{entries:n(Be,{parts:L,heading:!1,onOpen:l=>G(K(t.props.id,l))}),entryCount:xe(L).length})}),_&&n(Oe,{source:_,slug:Xe(t?.props)}),n(Pe,{shown:C,onChange:pe})]}):n(v,{children:n(z,{})})})})]})}export{$t as CHAT_MODE,Yt as HEADER_MODE,Ut as PUCK_MODE,qt as SOCIAL_MODE,Zt as WEBSITE_MODE,rt as default,it as resolvePanel};
1
+ "use client";import{jsx as n,jsxs as m,Fragment as v}from"react/jsx-runtime";import{useState as ae}from"react";import{useEasel as le}from"efficient-easel/easel";import{headWords as ce,InspectorHead as pe,InspectorIconButton as A}from"efficient-easel/chrome";import{DuplicateIcon as de,TrashIcon as me}from"efficient-easel/icons";import{panelFieldsOf as fe}from"../lib/puck/panel-fields.js";import{TICKER_PART_LABEL as C}from"./PreviewTickerContext.js";import ue from"./SectionIcon.js";import{PanelHideButton as R}from"./SidePanelHead.js";import{useEditorSession as he}from"../lib/editor-session-context.js";import{say as o}from"../lib/editor-words.js";import we,{HintsToggle as Se,SHOW_HINTS_DEFAULT as be}from"./WebsiteSettingsPanel.js";import ge from"./ChatSettingsPanel.js";import ke from"./SocialLinksPanel.js";import ve from"./TickerSettingsPanel.js";import Pe,{PartSourceNote as Ee}from"./PartSettingsPanel.js";import ye from"./DuplicateToPageMenu.js";import{useStorefrontDocument as Ie}from"./StorefrontDocumentContext.js";import{usePreviewHeader as Le}from"./PreviewHeaderContext.js";import{useSectionOps as Oe}from"../lib/puck/use-section-ops.js";import{SELECTION_MODE as Te}from"../lib/editor-screen.js";import{usePreviewParts as Ne}from"./PreviewPartsContext.js";import{entryPartsOf as He,SectionTextEntries as _e}from"./SectionTextEntries.js";import{SectionTextSuppressProvider as De}from"../lib/puck/section-text-suppress.js";import{HEADER_TYPE as Ae,ROOT_ZONE as x}from"../lib/puck/content-tree.js";import{websiteDuplicateBlocked as Ce}from"../lib/puck/every-page.js";import{FOOTER_TYPE as P}from"../lib/puck/footer-blocks.js";import Re from"./SwitchToBoxFooter.js";import{SiteFields as F}from"./SiteFields.js";import{SettingsSwitch as xe}from"efficient-easel/panel";import{foldTopTier as Fe}from"../lib/puck/field-groups.js";import{FoldHeadingScope as Be}from"../lib/puck/panel-heading-scope.js";import{partRowField as ze}from"../lib/puck/part-row-field.js";import{decodePartKey as Ke,partRowHeadLabel as Me}from"../lib/puck/part-rows.js";import{encodePartId as We,partHeadLabel as je,partLabel as Ue,sectionTextParts as Ye}from"../lib/puck/text-parts.js";import{partSourceOf as Ze,sourceSlugOf as $e}from"../lib/puck/source-bound-parts.js";const Bt=Te,zt={kind:"header"},Kt={kind:"website"},Mt={kind:"chat"},Wt={kind:"social"},g="Part";function qe(e){return o("Part of {name}",{name:o(e)})}function Ge(e,i,r){const l=e.describeNode(i);return{name:r,kindLabel:l?qe(l.label):o(g)}}function Je(e){switch(e){case"Header":return{title:o("Header settings belong to a website."),own:o("Each website created from this template sets its own header afterwards.")};case"Appearance":return{title:o("Appearance settings belong to a website."),own:o("Each website created from this template sets its own appearance afterwards.")};case"Live chat":return{title:o("Live chat settings belong to a website."),own:o("Each website created from this template sets its own live chat afterwards.")};case"Social link":return{title:o("Social link settings belong to a website."),own:o("Each website created from this template sets its own social link afterwards.")};default:return{title:o("{what} settings belong to a website.",{what:e}),own:o("Each website created from this template sets its own {what} afterwards.",{what:e.toLowerCase()})}}}function B({what:e}){const i=Je(e);return m("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:i.title})}),m("p",{children:[o("A template is a blueprint — it has no website of its own, so there is nothing here to change.")," ",i.own]})]})}const Qe={header:{name:"Header",kindLabel:"Site settings",icon:"header",render:(e,i)=>{const r=i.hostPanels?.header;return r?n(r,{placeholderMode:i.capabilities.placeholderFrames,tokenRef:i.tokenRef,siteId:i.siteId,websiteName:i.websiteName,onOpenWebsiteSettings:i.onOpenWebsiteSettings,onAuthExpired:()=>i.notifyParent("storefront-editor:auth-expired")}):null}},website:{name:"Appearance",kindLabel:"Site settings",icon:"website",render:(e,i)=>n(we,{themeFromDocument:!i.capabilities.hasSiteTheme,tokenRef:i.tokenRef,siteId:i.siteId,onNotify:i.onNotify})},chat:{name:"Live chat",kindLabel:"Site settings",icon:"chat",render:()=>n(ge,{})},social:{name:"Social links",kindLabel:"Site settings",icon:"social",render:()=>n(ke,{unavailable:n(B,{what:"Social link"})})},ticker:{name:C,kindLabel:g,icon:"ticker",head:(e,i)=>e.kind==="ticker"?Ge(i,e.heroId,o(C)):null,render:e=>n(ve,{heroId:e.kind==="ticker"?e.heroId:""})},part:{name:g,kindLabel:g,icon:"Text",head:(e,i)=>{if(e.kind!=="part")return null;const r=i.describeNode(e.nodeId);if(!r)return null;const{key:l,row:u}=Ke(e.propKey),h=u?ze(r.fields[l],u):r.fields[l],f=Me(o(je(Ue(h??{},l))),u),p=ce({name:f,tier:"part",of:o(r.label)},{partOf:({name:w})=>o("Part of {name}",{name:w})});return{name:p.name,kindLabel:p.kind}},render:(e,i)=>e.kind==="part"?n(Pe,{nodeId:e.nodeId,propKey:e.propKey,onBack:()=>i.onSelectNode(e.nodeId),onEditStyle:i.onOpenSiteStyles}):null}},Ve=new Set(["header","website","chat"]);function Xe(e,i){if(e==="puck")return null;const r=Qe[e];return Ve.has(e)&&!i.hasSiteSettings?{...r,kindLabel:"Not part of a template",render:()=>n(B,{what:r.name})}:r}function et({mode:e,onOpenWebsiteSettings:i,onOpenSiteStyles:r,onSelectNode:l,hideNodeActions:u=!1,onNotify:h,onHidePanel:f}){const{capabilities:p,tokenRef:w,notifyParent:z,currentSlug:K,siteId:E,runAuthed:M,readOnly:W}=Ie(),{websiteName:j}=Le(),S=Oe({readOnly:W}),{select:U}=Ne(),{selectedItem:t,getItemById:Y,getSelectorForId:Z,config:d,appState:$}=le(c=>c),q=fe(d,t?{type:t.type,props:t.props}:null),y=t?Ye(q??d.components[t.type]?.fields,t.props):[],G=c=>d.components[c]?.label??c,s=t?Z(t.props.id):void 0,a=Xe(e.kind,p),J=he(),I={capabilities:p,tokenRef:w,hostPanels:J.chrome?.panels,describeNode:c=>{const b=Y(c);if(!b)return null;const D=d.components[b.type];return{type:b.type,label:D?.label??b.type,fields:D?.fields??{}}},siteId:E,websiteName:j??null,notifyParent:z,onNotify:h,onOpenWebsiteSettings:i,onOpenSiteStyles:r,onSelectNode:l},L=a?.head?.(e,I)??null,Q=L?.name??(a?o(a.name):t?o(G(t.type)):o("Page settings")),V=L?.kindLabel??(a?o(a.kindLabel):t?s&&s.zone!==x?o("Block"):o("Section"):o("Page")),X=a?a.icon:t?t.type:"page",O=a?null:t?d.components[t.type]?.fields??null:d.root?.fields??null,ee=O?Fe(O):2,T=e.kind==="puck"&&t?Ze(t.type):null,te=!!t&&!!s&&s.zone===x&&t.type!==P&&t.type!==Ae,k=Ce($?.data,t),ne=()=>{k||s&&S.duplicateComponent(s.zone,s.index)},oe=()=>{s&&(S.removeComponent(s.zone,s.index),S.select(null))},ie=t?d.components[t.type]?.defaultProps?.previewHover:void 0,N=e.kind==="puck"&&!!t&&!!s&&ie!==void 0,H=N&&t.props.previewHover===!0,re=()=>{!t||!s||S.replaceComponent(s.zone,s.index,{...t,props:{...t.props,previewHover:!H}})},[_,se]=ae(be);return m("div",{className:`es-sidepanel es-sidepanel--right sf-panel sf-panel--right${_||!(!a&&!!t)?"":" sf-hints-folded"}`,children:[n(pe,{icon:n(ue,{type:X,size:15}),name:Q,kind:V,actions:!u&&e.kind==="puck"&&t&&t.type!==P?m(v,{children:[n(A,{label:o("Duplicate section"),title:k??void 0,disabled:k!==null,onClick:ne,children:n(de,{size:15})}),te&&p.hasSiteSettings&&n(ye,{node:t,currentSlug:K,siteId:E??void 0,tokenRef:w,runAuthed:M,onNotify:h}),n(A,{label:o("Remove section"),danger:!0,onClick:oe,children:n(me,{size:15})}),f?n(R,{side:"right",onHide:f,divider:!0}):null]}):f?n(R,{side:"right",onHide:f}):void 0}),N&&m("div",{className:"sf-preview-pin",children:[m("div",{className:"sf-preview-pin-text",children:[n("span",{className:"sf-preview-pin-label",children:o("Preview hover state")}),n("span",{className:"sf-preview-pin-hint",children:o("not shown live")})]}),n(xe,{checked:H,onChange:re,ariaLabel:o("Preview hover state")})]}),n(Be,{tier:ee,children:n("div",{className:"sf-insp-body es-insp-body sf-scroll",children:a?a.render(e,I):t?m(v,{children:[t.type===P&&p.hasSiteSettings&&n(Re,{}),n(De,{children:n(F,{entries:n(_e,{parts:y,heading:!1,onOpen:c=>U(We(t.props.id,c))}),entryCount:He(y).length})}),T&&n(Ee,{source:T,slug:$e(t?.props)}),n(Se,{shown:_,onChange:se})]}):n(v,{children:n(F,{})})})})]})}export{Mt as CHAT_MODE,zt as HEADER_MODE,Bt as PUCK_MODE,Wt as SOCIAL_MODE,Kt as WEBSITE_MODE,et as default,Xe as resolvePanel};
@@ -735,9 +735,15 @@
735
735
 
736
736
  /* C · the block you are pointing at: one line, solid, 1px, 2px off the words.
737
737
  Puck's own overlay-portal sheet drew it 2px dashed and this file narrowed it;
738
- since that sheet left with 5.5 the whole line is declared here. */
738
+ since that sheet left with 5.5 the whole line is declared here.
739
+ ITS COLOUR IS THE ENGINE'S HOVER COLOUR (2026-10-16): the accent at 60%, as
740
+ `.es-canvas-outline.is-hover` draws it in efficient-easel easel.css, so a
741
+ pointed-at word and a pointed-at block look the same. It was Puck's azure-09
742
+ (#dbeafe), a tint of white: next to the engine's box it read as a second,
743
+ lighter box, and once E below took that box away it was all but invisible
744
+ on a light page. */
739
745
  [data-puck-overlay-portal]:hover {
740
- outline: 1px solid var(--es-accent-tint-strong, #dbeafe);
746
+ outline: 1px solid color-mix(in srgb, var(--es-accent, #2563eb) 60%, transparent);
741
747
  outline-offset: 2px;
742
748
  }
743
749
 
@@ -790,6 +796,24 @@
790
796
  outline: none;
791
797
  }
792
798
 
799
+ /* E · …and the engine's hover box stands aside for it.
800
+ Lewis, 2026-10-16, on the Hartes homepage hero: pointing at the "Ranger II"
801
+ heading drew TWO lines again, the words' own (C) and a wider box round the
802
+ Heading block. That box is the engine's (`.es-canvas-outline.is-hover`,
803
+ efficient-easel easel.css), drawn on its outline layer over the block the
804
+ next click would pick. It came with the engine in blueprint 5.5, after A-D
805
+ were written, so nothing here answered it. But a click on a marked element
806
+ never reaches the engine (PreviewPartAnchors and the hero / ticker / location
807
+ bridges stop it and open their own thing), so over one the engine's box
808
+ names the wrong target, and the innermost line D keeps is the true one.
809
+ Off a marked element the engine's box is the only line, and stays. Led by
810
+ `[data-puck-entry]`, the frame's root, as A is; (0,5,0) against the
811
+ engine's (0,2,0). `scripts/test-part-outline-hairline.tsx` §3
812
+ resolves both sheets. */
813
+ [data-puck-entry]:has([data-puck-overlay-portal]:hover) .es-canvas-outline.is-hover {
814
+ outline: none;
815
+ }
816
+
793
817
  /* @tokens canvas-end */
794
818
 
795
819
  /* ── Canvas "Add section" seams (overlay between preview sections) ──────────
@@ -846,8 +870,13 @@
846
870
  came to hang 6px OUTSIDE the panel at every width under 280 (measured: gap
847
871
  -6.0px at 260 and at 220, against 0.0 at the default 320). One name, read
848
872
  by the padding, by the narrow override, and by anything that undoes it. */
849
- --sf-insp-pad-x: var(--space-16);
850
- padding: 4px var(--sf-insp-pad-x) 18px;
873
+ /* THE SIDES ARE EASEL'S NOW (one text panel W1): the body wears
874
+ `es-insp-body` (efficient-easel 9.0.0 chrome.css), the one row inset both
875
+ editors share — 16px, 8px under a 284px panel, the numbers this sheet
876
+ measured and set (card 66212, 2026-10-13). The token stays, as a name for
877
+ that inset, because rules below read it to reach the panel's edge. */
878
+ --sf-insp-pad-x: var(--es-insp-pad-x, var(--space-16));
879
+ padding-block: 4px 18px;
851
880
 
852
881
  /* THE DROPDOWN ARROW, WRITTEN ONCE — card 66399.c.
853
882
  Read by `.sf-insp-body select` at rest AND by the hover rule beside it. The
@@ -912,13 +941,8 @@
912
941
  and 10 has nothing to spare, and type is paid vertically as well — card 66206
913
942
  has just set the row rhythm to 16px, which shrinking type would hand straight
914
943
  back. The padding was the horizontal cost, so the padding is what moved. */
915
- @container (width < 284px) {
916
- .sf-insp-body {
917
- /* The TOKEN, not `padding-inline` — so everything that reads the padding
918
- narrows with it, instead of only the padding itself. */
919
- --sf-insp-pad-x: var(--space-8);
920
- }
921
- }
944
+ /* The narrow inset (8px under a 284px panel) is easel's `.es-insp-body` rule
945
+ now; `--sf-insp-pad-x` follows it, so every reader narrows with it. */
922
946
 
923
947
  /* Floating-styled form controls for Puck's native fields — and ONLY those.
924
948
 
@@ -0,0 +1,21 @@
1
+ import type { CSSProperties } from "react";
2
+ export declare const BORDER_MAX = 20;
3
+ export declare const BORDER_STYLES: readonly ["solid", "dashed", "dotted"];
4
+ export type BorderStyle = (typeof BORDER_STYLES)[number];
5
+ export declare const BORDER_SIDES: readonly ["top", "right", "bottom", "left"];
6
+ export type BorderSide = (typeof BORDER_SIDES)[number];
7
+ export type BorderValue = {
8
+ width?: number | null;
9
+ top?: number | null;
10
+ right?: number | null;
11
+ bottom?: number | null;
12
+ left?: number | null;
13
+ style?: BorderStyle | string | null;
14
+ color?: string | null;
15
+ };
16
+ export declare const SECTION_BORDER_CLASS = "sf-section-border";
17
+ export declare function hasOwnBorder(value: BorderValue | null | undefined): boolean;
18
+ export declare function borderVars(value: BorderValue | null | undefined, { phone }?: {
19
+ phone?: boolean;
20
+ }): Record<string, string> | undefined;
21
+ export declare function sectionBorderStyle(desktop: BorderValue | null | undefined, phone: BorderValue | null | undefined): CSSProperties | undefined;
@@ -0,0 +1 @@
1
+ const h=20,i=["solid","dashed","dotted"],c=["top","right","bottom","left"],b="sf-section-border",p=/^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i,f=t=>typeof t=="number"&&Number.isFinite(t)?`${Math.min(20,Math.max(0,Math.round(t)))}px`:void 0;function u(t){return r(t)!==void 0}function r(t,{phone:n=!1}={}){if(!t||typeof t!="object")return;const e=n?"-phone":"",o={};for(const s of c){const d=f(t[s])??f(t.width);d!==void 0&&(o[`--sf-border-${s}-width${e}`]=d)}return typeof t.style=="string"&&i.includes(t.style)&&(o[`--sf-border-style${e}`]=t.style),typeof t.color=="string"&&p.test(t.color)&&(o[`--sf-border-color${e}`]=t.color.toLowerCase()),Object.keys(o).length?o:void 0}function x(t,n){const e=r(t),o=r(n,{phone:!0});return e||o?{...e,...o}:void 0}export{h as BORDER_MAX,c as BORDER_SIDES,i as BORDER_STYLES,b as SECTION_BORDER_CLASS,r as borderVars,u as hasOwnBorder,x as sectionBorderStyle};
@@ -186,6 +186,14 @@ export declare const WEB_BUILDER_WORDS: {
186
186
  readonly "Bold is the weight above \u2014 one value, two ways to set it.": "Bold is the weight above — one value, two ways to set it.";
187
187
  readonly "Bold word": "Bold word";
188
188
  readonly "Booking Form": "Booking Form";
189
+ readonly Border: "Border";
190
+ readonly "Border bottom": "Border bottom";
191
+ readonly "Border color": "Border color";
192
+ readonly "Border left": "Border left";
193
+ readonly "Border right": "Border right";
194
+ readonly "Border style": "Border style";
195
+ readonly "Border top": "Border top";
196
+ readonly "Border width": "Border width";
189
197
  readonly Borders: "Borders";
190
198
  readonly Bottom: "Bottom";
191
199
  readonly "Bottom center": "Bottom center";
@@ -243,7 +251,6 @@ export declare const WEB_BUILDER_WORDS: {
243
251
  readonly "Cell width": "Cell width";
244
252
  readonly Center: "Center";
245
253
  readonly "Changed on every page": "Changed on every page";
246
- readonly "Changes apply to all selected.": "Changes apply to all selected.";
247
254
  readonly "Changes not live yet": "Changes not live yet";
248
255
  readonly Chart: "Chart";
249
256
  readonly "Chart style": "Chart style";
@@ -260,7 +267,6 @@ export declare const WEB_BUILDER_WORDS: {
260
267
  readonly "City strip": "City strip";
261
268
  readonly "Claims bars": "Claims bars";
262
269
  readonly "Claims panel (rows + defect bars)": "Claims panel (rows + defect bars)";
263
- readonly Clear: "Clear";
264
270
  readonly "Clear change": "Clear change";
265
271
  readonly "Clear change: {label}": "Clear change: {label}";
266
272
  readonly "Clear colors": "Clear colors";
@@ -328,6 +334,7 @@ export declare const WEB_BUILDER_WORDS: {
328
334
  readonly "Dark band": "Dark band";
329
335
  readonly Darken: "Darken";
330
336
  readonly "Darken style": "Darken style";
337
+ readonly Dashed: "Dashed";
331
338
  readonly "Data points": "Data points";
332
339
  readonly Date: "Date";
333
340
  readonly "Deck / standfirst": "Deck / standfirst";
@@ -368,6 +375,7 @@ export declare const WEB_BUILDER_WORDS: {
368
375
  readonly "Donut (split of a whole)": "Donut (split of a whole)";
369
376
  readonly "Dot \u25CF": "Dot ●";
370
377
  readonly Dots: "Dots";
378
+ readonly Dotted: "Dotted";
371
379
  readonly Down: "Down";
372
380
  readonly "Drop in your own sanitized HTML.": "Drop in your own sanitized HTML.";
373
381
  readonly "Duplicate section": "Duplicate section";
@@ -378,6 +386,7 @@ export declare const WEB_BUILDER_WORDS: {
378
386
  readonly "Dynamic Pages": "Dynamic Pages";
379
387
  readonly "EU Tyre Label": "EU Tyre Label";
380
388
  readonly "Each block": "Each block";
389
+ readonly "Each side": "Each side";
381
390
  readonly "Each website created from this template sets its own appearance afterwards.": "Each website created from this template sets its own appearance afterwards.";
382
391
  readonly "Each website created from this template sets its own header afterwards.": "Each website created from this template sets its own header afterwards.";
383
392
  readonly "Each website created from this template sets its own live chat afterwards.": "Each website created from this template sets its own live chat afterwards.";
@@ -449,11 +458,9 @@ export declare const WEB_BUILDER_WORDS: {
449
458
  readonly "Follow the page": "Follow the page";
450
459
  readonly "Follow the slideshow": "Follow the slideshow";
451
460
  readonly "Follows Desktop": "Follows Desktop";
452
- readonly "Follows no style \u2014 change": "Follows no style — change";
453
461
  readonly "Follows the section's Corners until you set a number here.": "Follows the section's Corners until you set a number here.";
454
462
  readonly "Follows the site": "Follows the site";
455
463
  readonly "Follows the style": "Follows the style";
456
- readonly "Follows {name} \u2014 change": "Follows {name} — change";
457
464
  readonly Font: "Font";
458
465
  readonly "Footer Box": "Footer Box";
459
466
  readonly "Footer \u00B7 on every page": "Footer · on every page";
@@ -608,6 +615,7 @@ export declare const WEB_BUILDER_WORDS: {
608
615
  readonly "Leave a blank line between paragraphs to start a new one.": "Leave a blank line between paragraphs to start a new one.";
609
616
  readonly "Leave a field blank to use the built-in wording.": "Leave a field blank to use the built-in wording.";
610
617
  readonly Left: "Left";
618
+ readonly "Left and right": "Left and right";
611
619
  readonly "Left of the copy": "Left of the copy";
612
620
  readonly "Legal & documents": "Legal & documents";
613
621
  readonly "Legal Line": "Legal Line";
@@ -673,7 +681,6 @@ export declare const WEB_BUILDER_WORDS: {
673
681
  readonly "Milestone title.": "Milestone title.";
674
682
  readonly Milestones: "Milestones";
675
683
  readonly Mixed: "Mixed";
676
- readonly "Mixed styles": "Mixed styles";
677
684
  readonly "Mockup Card": "Mockup Card";
678
685
  readonly "Mockup card": "Mockup card";
679
686
  readonly "Mockup position": "Mockup position";
@@ -822,7 +829,6 @@ export declare const WEB_BUILDER_WORDS: {
822
829
  readonly "Reel label": "Reel label";
823
830
  readonly "Refresh now": "Refresh now";
824
831
  readonly "Region \u00B7 country": "Region · country";
825
- readonly Regular: "Regular";
826
832
  readonly "Related Products": "Related Products";
827
833
  readonly "Remove section": "Remove section";
828
834
  readonly "Repeating full-width rows \u2014 eyebrow, title and copy beside a numbered close-up image, alternating sides each row.": "Repeating full-width rows — eyebrow, title and copy beside a numbered close-up image, alternating sides each row.";
@@ -885,7 +891,6 @@ export declare const WEB_BUILDER_WORDS: {
885
891
  readonly "Select a word, then press the highlighter.": "Select a word, then press the highlighter.";
886
892
  readonly "Selector guide (pills + results)": "Selector guide (pills + results)";
887
893
  readonly "Selector pills": "Selector pills";
888
- readonly Semibold: "Semibold";
889
894
  readonly Separator: "Separator";
890
895
  readonly "Series title": "Series title";
891
896
  readonly Serif: "Serif";
@@ -914,7 +919,6 @@ export declare const WEB_BUILDER_WORDS: {
914
919
  readonly "Signup Form": "Signup Form";
915
920
  readonly Simple: "Simple";
916
921
  readonly "Site settings": "Site settings";
917
- readonly "Site style": "Site style";
918
922
  readonly "Site styles": "Site styles";
919
923
  readonly "Six across": "Six across";
920
924
  readonly "Six stagger": "Six stagger";
@@ -1058,7 +1062,6 @@ export declare const WEB_BUILDER_WORDS: {
1058
1062
  readonly "This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.": "This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.";
1059
1063
  readonly "This site has {n} color theme of its own. Clearing takes them away and puts back the four the shop supplies.": "This site has {n} color theme of its own. Clearing takes them away and puts back the four the shop supplies.";
1060
1064
  readonly "This site has {n} color themes of its own. Clearing takes them away and puts back the four the shop supplies.": "This site has {n} color themes of its own. Clearing takes them away and puts back the four the shop supplies.";
1061
- readonly "This text follows the site style.": "This text follows the site style.";
1062
1065
  readonly "This ticker\u2019s hero is no longer on the page.": "This ticker’s hero is no longer on the page.";
1063
1066
  readonly "Three across": "Three across";
1064
1067
  readonly "Three ladder": "Three ladder";
@@ -1074,6 +1077,7 @@ export declare const WEB_BUILDER_WORDS: {
1074
1077
  readonly Title: "Title";
1075
1078
  readonly Tone: "Tone";
1076
1079
  readonly Top: "Top";
1080
+ readonly "Top and bottom": "Top and bottom";
1077
1081
  readonly "Top border": "Top border";
1078
1082
  readonly "Top center": "Top center";
1079
1083
  readonly "Top left": "Top left";
@@ -1173,6 +1177,7 @@ export declare const WEB_BUILDER_WORDS: {
1173
1177
  readonly manifesto: "manifesto";
1174
1178
  readonly "not set": "not set";
1175
1179
  readonly "not shown live": "not shown live";
1180
+ readonly part: "part";
1176
1181
  readonly px: "px";
1177
1182
  readonly "the Text style in Site styles": "the Text style in Site styles";
1178
1183
  readonly "the admin": "the admin";
@@ -1185,7 +1190,6 @@ export declare const WEB_BUILDER_WORDS: {
1185
1190
  readonly "videos only": "videos only";
1186
1191
  readonly "{face} is loaded without an italic, so it cannot be set in italic. Slanting it would deform the letters rather than style them.": "{face} is loaded without an italic, so it cannot be set in italic. Slanting it would deform the letters rather than style them.";
1187
1192
  readonly "{grade} on the button": "{grade} on the button";
1188
- readonly "{kind} \u00B7 every row": "{kind} · every row";
1189
1193
  readonly "{label} hex code": "{label} hex code";
1190
1194
  readonly "{label} {n}": "{label} {n}";
1191
1195
  readonly "{label} \u2014 row {n}": "{label} — row {n}";
@@ -1193,11 +1197,9 @@ export declare const WEB_BUILDER_WORDS: {
1193
1197
  readonly "{name} (unavailable)": "{name} (unavailable)";
1194
1198
  readonly "{name} is on this section": "{name} is on this section";
1195
1199
  readonly "{name} \u2014 renamed in the Console: {place}.": "{name} — renamed in the Console: {place}.";
1196
- readonly "{n} changed": "{n} changed";
1197
1200
  readonly "{n} cities": "{n} cities";
1198
1201
  readonly "{n} city": "{n} city";
1199
1202
  readonly "{n} of {total} layouts": "{n} of {total} layouts";
1200
- readonly "{n} selected": "{n} selected";
1201
1203
  readonly "{value} from {from}": "{value} from {from}";
1202
1204
  readonly "{value} on desktop": "{value} on desktop";
1203
1205
  readonly "{what} settings belong to a website.": "{what} settings belong to a website.";