efficient-easel 0.99.1 → 0.100.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 (110) hide show
  1. package/README.md +281 -36
  2. package/dist/autosave/index.d.ts +12 -6
  3. package/dist/blocks/index.d.ts +2 -2
  4. package/dist/canvas/index.d.ts +3 -3
  5. package/dist/canvas/index.js +1 -1
  6. package/dist/chrome/chrome.css +96 -29
  7. package/dist/chrome/index.d.ts +72 -19
  8. package/dist/chrome/index.js +17 -21
  9. package/dist/chunk-3EDSDPIP.js +1 -0
  10. package/dist/chunk-67GNT6PF.js +1 -0
  11. package/dist/{chunk-PI26YXYD.js → chunk-6EIVTKZZ.js} +21 -14
  12. package/dist/chunk-A5UK76FC.js +6 -0
  13. package/dist/chunk-AZT7V4UM.js +10 -0
  14. package/dist/chunk-DICUMYMG.js +12 -0
  15. package/dist/chunk-HDVD27VB.js +1 -0
  16. package/dist/chunk-JQM3V7XQ.js +1 -0
  17. package/dist/{chunk-TDA4HH54.js → chunk-JUQ6YJCG.js} +1 -1
  18. package/dist/chunk-LA54QLP5.js +1 -0
  19. package/dist/chunk-LGKQXSKO.js +16 -0
  20. package/dist/chunk-M6F6LS3H.js +1 -0
  21. package/dist/chunk-MH5GUZFQ.js +9 -0
  22. package/dist/chunk-P6O363EE.js +6 -0
  23. package/dist/chunk-PAELDYYS.js +1 -0
  24. package/dist/{chunk-JYPOOHII.js → chunk-QKVR3K73.js} +3 -3
  25. package/dist/chunk-SAJUCHOX.js +1 -0
  26. package/dist/chunk-TRVZ7C23.js +1 -0
  27. package/dist/chunk-V7GIIXFB.js +16 -0
  28. package/dist/{chunk-IBOFSS56.js → chunk-WZ7TGAAT.js} +1 -1
  29. package/dist/chunk-ZJEBF4NB.js +1 -0
  30. package/dist/copy/copy.css +388 -5
  31. package/dist/copy/index.d.ts +271 -8
  32. package/dist/copy/index.js +31 -10
  33. package/dist/data/index.d.ts +4 -4
  34. package/dist/drag/drag.css +10 -1
  35. package/dist/drag/index.d.ts +102 -11
  36. package/dist/drag/index.js +18 -17
  37. package/dist/{editor/editor.css → easel/easel.css} +16 -1
  38. package/dist/{editor → easel}/index.d.ts +146 -51
  39. package/dist/easel/index.js +9 -0
  40. package/dist/edit-lock/index.d.ts +3 -3
  41. package/dist/edit-lock/index.js +1 -1
  42. package/dist/fields/fields.css +103 -26
  43. package/dist/fields/index.d.ts +51 -13
  44. package/dist/fields/index.js +30 -46
  45. package/dist/gold/index.js +1 -1
  46. package/dist/icons/index.d.ts +10 -1
  47. package/dist/icons/index.js +1 -1
  48. package/dist/index.d.ts +3 -3
  49. package/dist/index.js +1 -1
  50. package/dist/markup/index.d.ts +94 -10
  51. package/dist/markup/index.js +1 -1
  52. package/dist/menu/index.d.ts +61 -6
  53. package/dist/menu/index.js +15 -15
  54. package/dist/menu/menu.css +17 -6
  55. package/dist/node-ops/index.d.ts +9 -9
  56. package/dist/node-ops/index.js +1 -1
  57. package/dist/panel/index.d.ts +73 -5
  58. package/dist/panel/index.js +18 -16
  59. package/dist/panel/panel.css +56 -1
  60. package/dist/pick/index.d.ts +42 -4
  61. package/dist/pick/index.js +7 -14
  62. package/dist/pick/pick.css +14 -0
  63. package/dist/rail/index.d.ts +6 -6
  64. package/dist/rail/index.js +1 -1
  65. package/dist/rail/rail.css +1 -1
  66. package/dist/strings/catalogue.d.ts +24 -40
  67. package/dist/strings/catalogue.js +1 -1
  68. package/dist/strings/index.d.ts +25 -23
  69. package/dist/strings/index.js +2 -2
  70. package/dist/style-clipboard/index.d.ts +5 -5
  71. package/dist/style-clipboard/index.js +1 -1
  72. package/dist/text-styles/index.d.ts +328 -0
  73. package/dist/text-styles/index.js +38 -0
  74. package/dist/text-styles/text-styles.css +309 -0
  75. package/dist/tree/index.d.ts +44 -3
  76. package/dist/tree/index.js +1 -1
  77. package/dist/tree/tree.css +71 -0
  78. package/dist/{types-CnRzp9oc.d.ts → types-DGcCsxs8.d.ts} +79 -12
  79. package/dist/{types-DNrn_w4V.d.ts → types-DWS-s9z-.d.ts} +10 -10
  80. package/dist/{types-pGBXevBU.d.ts → types-Djdq6Xkd.d.ts} +15 -8
  81. package/dist/{types-Dy6oR6Z2.d.ts → types-E3HrTPg2.d.ts} +20 -14
  82. package/dist/{types-C7HFvdtk.d.ts → types-VqL6t5HH.d.ts} +82 -5
  83. package/dist/{watch-DmasQA61.d.ts → watch-BTYOJpQU.d.ts} +19 -2
  84. package/dist/{wordFit-9B9nqyf3.d.ts → wordFit-D4S36PvB.d.ts} +1 -1
  85. package/dist/{words-DagJdwIA.d.ts → words-AHHfiaRY.d.ts} +31 -2
  86. package/dist/{words-D9ChvbNC.d.ts → words-BDignMl_.d.ts} +1 -1
  87. package/dist/{words-Cqmyey0s.d.ts → words-BMzV04b1.d.ts} +2 -2
  88. package/dist/words-CJjUKcV5.d.ts +37 -0
  89. package/dist/words-CRYvAiHX.d.ts +105 -0
  90. package/dist/{words-B2YLaKEr.d.ts → words-CnnHb9jo.d.ts} +1 -1
  91. package/dist/{words-CD3WADyb.d.ts → words-CzoyDNHm.d.ts} +4 -0
  92. package/dist/{words-bOMsUJk9.d.ts → words-DBq7vfHy.d.ts} +59 -6
  93. package/dist/{words-DOhF-4D4.d.ts → words-DMG4dYq2.d.ts} +1 -1
  94. package/dist/{words-BK-npta-.d.ts → words-DgHcY5qB.d.ts} +10 -4
  95. package/dist/{words-B87GIFWH.d.ts → words-is_Vy6hn.d.ts} +1 -1
  96. package/package.json +14 -8
  97. package/dist/chunk-66CKSTXP.js +0 -14
  98. package/dist/chunk-67VZRQLG.js +0 -13
  99. package/dist/chunk-6PS6STGA.js +0 -1
  100. package/dist/chunk-7A7O2JWQ.js +0 -1
  101. package/dist/chunk-H4B72XCJ.js +0 -1
  102. package/dist/chunk-JE63JHKO.js +0 -1
  103. package/dist/chunk-KDIVA6WD.js +0 -1
  104. package/dist/chunk-MCLBHENY.js +0 -1
  105. package/dist/chunk-QB3BZIRA.js +0 -5
  106. package/dist/chunk-SJQG5ENJ.js +0 -1
  107. package/dist/chunk-SUO5627P.js +0 -1
  108. package/dist/chunk-ZT7M24XD.js +0 -1
  109. package/dist/editor/index.js +0 -9
  110. /package/dist/{chunk-GGTPNGFJ.js → chunk-AELNNAFM.js} +0 -0
@@ -0,0 +1,16 @@
1
+ import{useNumberEntry as e,clampNumber as l}from"./chunk-A5UK76FC.js";import{DEFAULT_FIELDS_WORDS as a}from"./chunk-LA54QLP5.js";import{useWords as r}from"./chunk-MFIRYGHW.js";import{useId as n,useState as s,useRef as t,useMemo as i,useEffect as o}from"react";import{jsx as u,jsxs as c,Fragment as d}from"react/jsx-runtime";function p(e,l){return e.find(e=>Object.is(e.value,l))}function h(e){const{id:l,options:h,placeholder:f,readOnly:m=!1,ariaLabel:v,ariaLabelledBy:b,searchable:g=!1,searchPlaceholder:y,groupCount:N=!1,inline:w=!1,renderOption:x}=e,k=r("fields",a),D=n(),C=n(),$=l??C,[A,L]=s(!1),[O,j]=s(0),[E,M]=s(""),K=t(null),S=t(null),V=t(null),F=t(null),U=y??k.search??a.search,I=!0===e.multiple,P=I&&Array.isArray(e.value)?e.value:[],H=e=>P.some(l=>Object.is(l,e.value)),W=I?void 0:p(h,e.value),z=W?h.indexOf(W):-1,B=e=>I?H(h[e]):e===z,G=i(()=>{const e=g?E.trim().toLowerCase():"",l=[];return h.forEach((a,r)=>{e&&!a.label.toLowerCase().includes(e)||l.push(r)}),l},[h,E,g]),Q=i(()=>new Set(G),[G]),R=G.filter(e=>!h[e].disabled),T=h.some(e=>void 0!==e.thumb),Y=T||I||void 0!==x||h.some(e=>void 0!==e.meta),q=()=>{if(m||0===h.length)return;M("");const e=I?h.findIndex(e=>!e.disabled&&H(e)):z;j(e>=0?e:Math.max(h.findIndex(e=>!e.disabled),0)),L(!0)},J=e=>{L(!1),M(""),e&&S.current?.focus()},X=l=>{const a=h[l];if(a&&!a.disabled){if(!0===e.multiple){const r=!H(a);return void e.onChange(h.filter((e,a)=>a===l?r:H(e)).map(e=>e.value))}Object.is(a.value,e.value)||e.onChange(a.value),J(!0)}};o(()=>{if(!A)return;(g?F.current:V.current)?.focus();const e=K.current?.ownerDocument;if(!e)return;const l=e=>{K.current&&!K.current.contains(e.target)&&(L(!1),M(""))};return e.addEventListener("click",l,!0),()=>e.removeEventListener("click",l,!0)},[A,g]),o(()=>{A&&g&&j(R[0]??-1)},[E]);const Z=e=>{if(0===R.length)return;const l=R.indexOf(O),a=l<0?1===e?0:R.length-1:(l+e+R.length)%R.length;j(R[a])},_=e=>{switch(e.key){case"ArrowDown":return e.preventDefault(),Z(1),!0;case"ArrowUp":return e.preventDefault(),Z(-1),!0;case"Enter":return e.preventDefault(),Q.has(O)&&X(O),!0;case"Escape":return e.preventDefault(),e.stopPropagation(),J(!0),!0;case"Tab":return J(!1),!0;default:return!1}},ee=(e,l)=>{if(!Y)return e.label;const a={active:l===O,chosen:B(l)};/* @__PURE__ */
2
+ return c(d,{children:[I?/* @__PURE__ */u("span",{className:"es-fsel-tick"+(a.chosen?" is-on":""),"aria-hidden":"true"}):null,T?/* @__PURE__ */u("span",{className:"es-fsel-thumb","aria-hidden":"true",children:e.thumb?/* @__PURE__ */u("img",{src:e.thumb,alt:"",loading:"lazy"}):null}):null,x?x(e,a):/* @__PURE__ */u("span",{className:"es-fsel-label",children:e.label}),void 0!==e.meta?/* @__PURE__ */u("span",{className:"es-fsel-meta","aria-hidden":"true",children:e.meta}):null]})},le=function(e,l){const a=[];return e.forEach((e,r)=>{if(!l.has(r))return;const n=a[a.length-1];n&&n.group===e.group?n.items.push({o:e,i:r}):a.push({group:e.group,items:[{o:e,i:r}]})}),a}(h,Q),ae=le.map((e,l)=>{const a=e.items.map(({o:e,i:l})=>/* @__PURE__ */u("li",{id:`${D}-${l}`,role:"option","aria-selected":B(l),"aria-disabled":e.disabled||void 0,className:`es-fsel-option${Y?" es-fsel-option--rich":""}${l===O?" is-active":""}${B(l)?" is-chosen":""}`,onMouseEnter:()=>j(l),onClick:()=>X(l),children:ee(e,l)},`${l}-${String(e.value)}`));if(void 0===e.group)return a;const r=`${D}-g${l}`;/* @__PURE__ */
3
+ return c("li",{role:"presentation",className:"es-fsel-group",children:[
4
+ /* @__PURE__ */c("div",{id:r,role:"presentation",className:"es-fsel-group-head",children:[e.group,N?/* @__PURE__ */u("span",{className:"es-fsel-group-count",children:e.items.length}):null]}),
5
+ /* @__PURE__ */u("ul",{role:"group","aria-labelledby":r,className:"es-fsel-group-list",children:a})]},`g${l}`)}),re=Q.has(O)?`${D}-${O}`:void 0,ne=/* @__PURE__ */c("ul",{ref:V,id:D,role:"listbox",tabIndex:-1,className:"es-fsel-list","aria-multiselectable":I||void 0,"aria-activedescendant":g?void 0:re,"aria-labelledby":b??(v?void 0:$),"aria-label":b?void 0:v,onKeyDown:e=>{if(!_(e))switch(e.key){case"Home":return e.preventDefault(),void(R.length&&j(R[0]));case"End":return e.preventDefault(),void(R.length&&j(R[R.length-1]));case" ":return e.preventDefault(),void X(O);default:if(1===e.key.length&&/\S/.test(e.key)){const l=e.key.toLowerCase(),a=h.length;for(let e=1;e<=a;e++){const r=(O+e)%a;if(!h[r]?.disabled&&h[r]?.label.toLowerCase().startsWith(l))return void j(r)}}}},children:[ae,g&&0===G.length?/* @__PURE__ */u("li",{role:"presentation",className:"es-fsel-empty",children:k.noMatches??a.noMatches}):null]});let se,te;if(!0===e.multiple){const l=h.filter(H);te=0===l.length,se=e.renderValue?e.renderValue(l):te?f??k.choose:l.map(e=>e.label).join(", ")}else te=!W,se=e.renderValue?e.renderValue(W):W?W.label:f??k.choose;/* @__PURE__ */
6
+ return c("div",{className:"es-fsel"+(w?" es-fsel--inline":""),ref:K,children:[
7
+ /* @__PURE__ */c("button",{ref:S,id:$,type:"button",className:"es-fin es-fsel-button","aria-haspopup":"listbox","aria-expanded":A,"aria-controls":A?D:void 0,"aria-label":v,"aria-labelledby":b,disabled:m,onClick:()=>A?J(!1):q(),onKeyDown:e=>{"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),q())},children:[
8
+ /* @__PURE__ */u("span",{className:te?"es-fsel-value is-empty":"es-fsel-value",children:se}),
9
+ /* @__PURE__ */u("span",{className:"es-fsel-chev","aria-hidden":"true"})]}),A?g?/* @__PURE__ */c("div",{className:"es-fsel-pop",children:[
10
+ /* @__PURE__ */u("input",{ref:F,type:"text",className:"es-fin es-fsel-search",value:E,placeholder:U,"aria-label":U,"aria-autocomplete":"list","aria-controls":D,"aria-activedescendant":re,onChange:e=>M(e.target.value),onKeyDown:e=>{_(e)}}),ne]}):ne:null]})}function f({id:a,label:r,value:s,onChange:t,min:i,max:o,step:d=1,shiftStep:p,styleValue:h,unit:f,sliderMin:m,sliderMax:v,auto:b,readOnly:g=!1}){const y=n(),N=a??y,{inputProps:w,set:x,isStyle:k}=e({value:s,onChange:t,min:i,max:o,step:d,shiftStep:p,styleValue:h,readOnly:g}),D="number"==typeof s&&Number.isFinite(s)?s:void 0,C=void 0!==b&&void 0===D,$=Number((m-d).toFixed(6)),A=void 0!==b?$:m,L=D??(void 0!==b?$:h??m);/* @__PURE__ */
11
+ return c("div",{className:"es-fslider"+(k||C?" is-style":""),children:[
12
+ /* @__PURE__ */c("div",{className:"es-fslider-top",children:[
13
+ /* @__PURE__ */u("label",{className:"es-fslider-name",htmlFor:N,children:r}),
14
+ /* @__PURE__ */c("span",{className:"es-fslider-read",children:[
15
+ /* @__PURE__ */u("input",{id:N,type:"text",inputMode:"decimal",className:"es-fslider-value",...w,placeholder:b??w.placeholder,onKeyDown:e=>{if(C&&("ArrowUp"===e.key||"ArrowDown"===e.key))return e.preventDefault(),void("ArrowUp"===e.key&&x(l(m,i,o)));w.onKeyDown(e)}}),f&&!C?/* @__PURE__ */u("span",{className:"es-fslider-unit",children:f}):null]})]}),
16
+ /* @__PURE__ */u("input",{type:"range",className:"es-fslider-range",min:A,max:v,step:d,value:l(L,A,v),disabled:g,"aria-label":r,"aria-valuetext":C?b:void 0,onChange:e=>{const l=Number(e.target.value);x(void 0!==b&&l<m?void 0:l)}})]})}export{h as FieldSelect,f as FieldSlider,p as optionFor};
@@ -0,0 +1 @@
1
+ var e={groups:{heading:"Headings",body:"Body"},add:{heading:"+ Add heading",body:"+ Add body"},count:({n:e,max:a})=>`${e} / ${a}`,full:({kind:e,max:a})=>`Up to ${a} ${e} styles`,styleName:({kind:e,n:a})=>`${"heading"===e?"Heading":"Body"} ${a}`,remove:"Delete",removeNamed:({name:e})=>`Delete ${e}`,sample:"The quick brown fox jumps over the lazy dog",preview:"Preview",summary:({font:e,size:a,weight:t})=>`${e} · ${a} · ${t}`,px:({n:e})=>`${e} px`,auto:"Auto",weights:{thin:"Thin",extraLight:"Extra light",light:"Light",regular:"Regular",medium:"Medium",semibold:"Semibold",bold:"Bold",extraBold:"Extra bold",black:"Black"},settings:{font:"Font",color:"Color",size:"Font size",weight:"Weight",emphasis:"Style",lineSpacing:"Line spacing",letterSpacing:"Letter spacing",paragraphSpacing:"Paragraph spacing",letterCase:"Letter case",largestSize:"Largest size"},bold:"Bold",italic:"Italic",italicMissing:"Italic: this font has no italic loaded",case:{auto:"Auto",autoTitle:"Auto: as each section draws it",none:"As typed",upper:"Uppercase",lower:"Lowercase"},colour:{any:"Any color",follows:"Follows the style"}};export{e as DEFAULT_TEXT_STYLES_WORDS};
@@ -0,0 +1,9 @@
1
+ import{DEFAULT_CHROME_WORDS as e}from"./chunk-ZJEBF4NB.js";import{useWords as n}from"./chunk-MFIRYGHW.js";import{jsxs as i,jsx as s}from"react/jsx-runtime";function a({icon:e,name:n,kind:a,actions:l}){/* @__PURE__ */
2
+ return i("div",{className:"es-insp-head",children:[
3
+ /* @__PURE__ */s("span",{className:"es-insp-chip","aria-hidden":"true",children:e}),
4
+ /* @__PURE__ */i("div",{className:"es-insp-titles",children:[
5
+ /* @__PURE__ */s("h2",{className:"es-insp-name",children:n}),
6
+ /* @__PURE__ */s("div",{className:"es-insp-kind",children:a})]}),l?/* @__PURE__ */s("div",{className:"es-insp-actions",children:l}):null]})}function l({label:e,title:n,hasPopup:i,onClick:a,disabled:l,danger:c,expanded:t,buttonRef:r,children:p}){/* @__PURE__ */
7
+ return s("button",{ref:r,type:"button",className:c?"es-insp-iconbtn es-insp-iconbtn--danger":"es-insp-iconbtn",title:n??e,"aria-label":e,"aria-haspopup":i,"aria-expanded":t,disabled:l,onClick:a,children:p})}function c({name:a,onSelect:l,label:c,inline:t}){const r=n("chrome",e),p=c??r.upLevel,d=/* @__PURE__ */i("button",{type:"button",className:"es-insp-up-btn",title:p,"aria-label":r.upLevelTo({label:p,name:a}),onClick:l,children:[
8
+ /* @__PURE__ */s("span",{className:"es-insp-up-arrow","aria-hidden":"true",children:"←"}),
9
+ /* @__PURE__ */s("span",{className:"es-insp-up-name",children:a})]});return t?d:/* @__PURE__ */s("div",{className:"es-insp-up",children:d})}export{a as InspectorHead,l as InspectorIconButton,c as InspectorUpLevel};
@@ -0,0 +1,6 @@
1
+ import{wordFitVars as e}from"./chunk-BZ5ASXOL.js";import{jsx as a,jsxs as i}from"react/jsx-runtime";function s({options:s,value:l,onChange:t,ariaLabel:n,fit:r,disabled:d=!1,className:c}){const o=r&&e(s.length,r);
2
+ /* @__PURE__ */
3
+ return a("div",{className:"es-segs-fit",children:/* @__PURE__ */a("div",{role:"group","aria-label":n,"data-disabled":d||void 0,className:`es-segs${o?" is-measured":""}${c?` ${c}`:""}`,style:o,children:s.map(e=>{const s=e.id===l,n=e.title??("string"==typeof e.label?e.label:void 0),r=d||!0===e.disabled,c=`es-seg${e.icon?" has-icon":""}${s?" is-active":""}`;/* @__PURE__ */
4
+ return i("button",{type:"button",title:n,"aria-label":n,"aria-pressed":s,disabled:r,className:c,onClick:()=>t(e.id),children:[e.icon?/* @__PURE__ */a("span",{className:"es-seg-icon","aria-hidden":"true",children:e.icon}):null,
5
+ /* @__PURE__ */a("span",{className:"es-seg-word",children:e.label})]},String(e.id))})})})}function l({checked:e,onChange:i,disabled:s,id:l,ariaLabel:t,ariaLabelledBy:n,className:r}){/* @__PURE__ */
6
+ return a("button",{type:"button",role:"switch",id:l,"aria-checked":e,"aria-label":t,"aria-labelledby":n,disabled:s,className:r?`es-switch ${r}`:"es-switch",onClick:()=>i(!e)})}export{s as SettingsSegmented,l as SettingsSwitch};
@@ -0,0 +1 @@
1
+ import{removeCanvasStyle as e,upsertCanvasStyle as n}from"./chunk-ZNCEOSXO.js";import{useState as t,useEffect as o,useRef as r}from"react";var c="[data-puck-component]",u="[data-puck-dropzone]",s="iframe#preview-frame";function i(e){const n=e.contentDocument;if(!n||!e.contentWindow||"loading"===n.readyState||!n.body)return!1;if(e.hasAttribute("srcdoc"))return"about:srcdoc"===n.URL;const t=e.getAttribute("src");return!t||"about:blank"===t||"about:blank"!==n.URL}function l(e,n,{selector:t=s,readySelector:o}={}){let r=null,c=null,u=!1,l=!1,d=null;const a=()=>{d?.observer.disconnect(),d=null},m=()=>{if(l)return;let e=null;if(r&&i(r)){const n=r.contentDocument;(e=>{if(!o||e.querySelector(o))return a(),!0;if(d?.doc!==e){a();const n=e.defaultView?.MutationObserver;if(n){const t=new n(()=>m());t.observe(e,{childList:!0,subtree:!0}),d={doc:e,observer:t}}}return!1})(n)&&(e={frame:r,document:n,window:r.contentWindow})}else a();(e===c||!!e&&!!c&&e.frame===c.frame&&e.document===c.document)&&u||(u=!0,c=e,n(c))},f=()=>m(),v=()=>{const n=e.querySelector?.(t);n!==r?(r?.removeEventListener("load",f),r=n,r?.addEventListener("load",f),m()):m()},b=e.ownerDocument?.defaultView??e.defaultView,w=b?.MutationObserver,p=w?new w(e=>(e=>null!==r&&!r.isConnected||e.some(e=>[...e.addedNodes,...e.removedNodes].some(e=>"IFRAME"===e.nodeName||!!e.querySelector?.("iframe"))))(e)&&v()):null;return p?.observe(e,{childList:!0,subtree:!0}),v(),()=>{l=!0,p?.disconnect(),a(),r?.removeEventListener("load",f),r=null}}function d(e,{selector:n,readySelector:r}={}){const[c,u]=t(null);return o(()=>{const t=e.current;if(!t)return;const o=l(t,u,{selector:n,readySelector:r});return()=>{o(),u(null)}},[e,n,r]),c}function a(e,n,t,{on:c="document",capture:u=!1}={}){const s=r(t);s.current=t;const i=e?.document??null,l=e?.window??null;o(()=>{const e="window"===c?l:i;if(!e)return;const t=e=>s.current(e);return e.addEventListener(n,t,u),()=>e.removeEventListener(n,t,u)},[i,l,n,c,u])}function m(t,r,c){const u=t?.document??null;o(()=>{if(!u)return;if(!c)return void e(u,r);const t=n(u,r,c),o=u.defaultView?.MutationObserver,s=o?new o(()=>{t.isConnected||n(u,r,c)}):null;return s?.observe(u.head??u.documentElement,{childList:!0}),()=>{s?.disconnect(),e(u,r)}},[u,r,c])}function f(e,{settle:n=[150,450]}={}){const[r,c]=t(0),u=e?.frame??null,s=e?.document??null,i=e?.window??null,l=n.join(",");return o(()=>{if(!u||!s||!i)return;const e=u.ownerDocument.defaultView;let t=!1,o=0;const r=()=>{if(t)return;t=!0;const n=()=>{t=!1,c(e=>e+1)};e?.requestAnimationFrame?o=e.requestAnimationFrame(n):n()},l=[],d=(e,n)=>{e.addEventListener(n,r,!0),l.push(()=>e.removeEventListener(n,r,!0))};d(s,"scroll"),d(i,"resize"),e&&(d(e,"scroll"),d(e,"resize"));const a=e?.ResizeObserver;if(a){const e=new a(r);e.observe(u),s.documentElement&&e.observe(s.documentElement),l.push(()=>e.disconnect())}const m=s.defaultView?.MutationObserver,f=s.body??s.documentElement;if(m&&f){const e=new m(r);e.observe(s===u.ownerDocument?u:f,{childList:!0,subtree:!0}),l.push(()=>e.disconnect())}const v=s.fonts;v&&d(v,"loadingdone");const b=n.map(e=>setTimeout(r,e));return r(),()=>{for(const e of l)e();for(const e of b)clearTimeout(e);o&&e?.cancelAnimationFrame&&e.cancelAnimationFrame(o)}},[u,s,i,l]),r}export{c as BLOCK_SELECTOR,s as CANVAS_SELECTOR,u as LIST_SELECTOR,i as isFrameReady,a as useCanvasEvent,d as useCanvasFrame,f as useCanvasLayout,m as useCanvasStyle,l as watchCanvasFrame};
@@ -1,4 +1,4 @@
1
- import{tokenizeInline as e,STANDARD_MARKUP as t}from"./chunk-SJQG5ENJ.js";import{jsx as n,jsxs as l}from"react/jsx-runtime";import{useRef as r}from"react";function s(t,n){const l=[];let r=0;for(const s of e(t,n)){if("text"===s.kind){s.text.length>0&&(l.push({kind:"text",text:t.slice(r,r+s.text.length)}),r+=s.text.length);continue}const e=i(t,r,s.kind,s.text,n);if(!e)return[{kind:"text",text:t}];const o=r+e.open.length,c=o+s.text.length,a=c+e.close.length;l.push({kind:"delimiter",text:t.slice(r,o)}),l.push({kind:s.kind,text:t.slice(o,c)}),l.push({kind:"delimiter",text:t.slice(c,a)}),r=a}return l.map(e=>e.text).join("")!==t?[{kind:"text",text:t}]:l}function i(e,t,n,l,r){for(const s of r){if(s.kind!==n)continue;if(!e.startsWith(s.open,t))continue;const r=t+s.open.length;if(e.startsWith(l,r)&&e.startsWith(s.close,r+l.length))return s}return null}function o({value:e,rules:l=t,className:r,layerRef:i}){const o=s(e,l);/* @__PURE__ */
1
+ import{tokenizeInline as e,STANDARD_MARKUP as t}from"./chunk-HDVD27VB.js";import{jsx as n,jsxs as l}from"react/jsx-runtime";import{useRef as r}from"react";function s(t,n){const l=[];let r=0;for(const s of e(t,n)){if("text"===s.kind){s.text.length>0&&(l.push({kind:"text",text:t.slice(r,r+s.text.length)}),r+=s.text.length);continue}const e=i(t,r,s.kind,s.text,n);if(!e)return[{kind:"text",text:t}];const o=r+e.open.length,c=o+s.text.length,a=c+e.close.length;l.push({kind:"delimiter",text:t.slice(r,o)}),l.push({kind:s.kind,text:t.slice(o,c)}),l.push({kind:"delimiter",text:t.slice(c,a)}),r=a}return l.map(e=>e.text).join("")!==t?[{kind:"text",text:t}]:l}function i(e,t,n,l,r){for(const s of r){if(s.kind!==n)continue;if(!e.startsWith(s.open,t))continue;const r=t+s.open.length;if(e.startsWith(l,r)&&e.startsWith(s.close,r+l.length))return s}return null}function o({value:e,rules:l=t,className:r,layerRef:i}){const o=s(e,l);/* @__PURE__ */
2
2
  return n("div",{ref:i,className:["es-gold-layer",r??""].filter(Boolean).join(" "),"aria-hidden":"true",children:o.map((e,t)=>function(e,t){const{kind:l,text:r}=e;switch(l){case"delimiter":/* @__PURE__ */
3
3
  return n("span",{className:"es-gold-delim",children:r},t);case"accent":case"highlight":/* @__PURE__ */
4
4
  return n("em",{className:"es-gold-mark es-gold-accent",children:r},t);case"bold":/* @__PURE__ */
@@ -6,8 +6,8 @@ return n("strong",{className:"es-gold-mark es-gold-bold",children:r},t);case"ita
6
6
  return n("em",{className:"es-gold-mark es-gold-italic",children:r},t);case"strike":/* @__PURE__ */
7
7
  return n("s",{className:"es-gold-mark es-gold-strike",children:r},t);case"quiet":/* @__PURE__ */
8
8
  return n("span",{className:"es-gold-mark es-gold-quiet",children:r},t);default:/* @__PURE__ */
9
- return n("span",{className:"es-gold-text",children:r},t)}}(e,t))})}function c({value:e,onInput:s,onCommit:i,onCancel:c,multiline:a=!1,placeholder:u,className:d,rules:f=t,ariaLabel:m,disabled:h=!1,inputRef:g}){const p=r(null),k=r(e),x=r(!1);function N(e){x.current&&(x.current=!1,i?.(e))}/* @__PURE__ */
9
+ return n("span",{className:"es-gold-text",children:r},t)}}(e,t))})}function c({value:e,onInput:s,onCommit:i,onCancel:c,multiline:a=!1,placeholder:u,className:d,rules:f=t,ariaLabel:m,disabled:h=!1,inputRef:g}){const p=r(null),k=r(e),x=r(!1);function v(e){x.current&&(x.current=!1,i?.(e))}/* @__PURE__ */
10
10
  return l("div",{className:["es-gold",a?"es-gold-is-multiline":"es-gold-is-single",h?"es-gold-is-off":"",d??""].filter(Boolean).join(" "),children:[
11
11
  /* @__PURE__ */n(o,{value:e,rules:f,layerRef:p}),u&&""===e?
12
12
  /* @__PURE__ */n("div",{className:"es-gold-placeholder","aria-hidden":"true",children:u}):null,
13
- /* @__PURE__ */n("textarea",{ref:g,className:"es-gold-input",disabled:h,value:e,placeholder:u,"aria-label":m,onChange:function(e){x.current=!0,s(e.currentTarget.value)},onFocus:function(){k.current=e,x.current=!1},onBlur:function(){N(e)},onKeyDown:function(t){return"Escape"===t.key?(t.preventDefault(),x.current=!1,void c?.(k.current)):"Enter"!==t.key||a?void 0:(t.preventDefault(),void N(e))},onScroll:function(e){const t=p.current;t&&(t.scrollTop=e.currentTarget.scrollTop,t.scrollLeft=e.currentTarget.scrollLeft)}})]})}export{o as GoldLayer,c as GoldTextInput,s as goldSegments};
13
+ /* @__PURE__ */n("textarea",{ref:g,className:"es-gold-input",disabled:h,value:e,placeholder:u,"aria-label":m,onChange:function(e){x.current=!0,s(e.currentTarget.value)},onFocus:function(){k.current=e,x.current=!1},onBlur:function(){v(e)},onKeyDown:function(t){return"Escape"===t.key?(t.preventDefault(),x.current=!1,void c?.(k.current)):"Enter"!==t.key||a?void 0:(t.preventDefault(),void v(e))},onScroll:function(e){const t=p.current;t&&(t.scrollTop=e.currentTarget.scrollTop,t.scrollLeft=e.currentTarget.scrollLeft)}})]})}export{o as GoldLayer,c as GoldTextInput,s as goldSegments};
@@ -0,0 +1 @@
1
+ import{DEFAULT_TEXT_STYLES_WORDS as o}from"./chunk-M6F6LS3H.js";import{DEFAULT_STYLE_CLIPBOARD_WORDS as r}from"./chunk-6WY6ZXJG.js";import{DEFAULT_CANVAS_WORDS as t}from"./chunk-AELNNAFM.js";import{DEFAULT_TREE_WORDS as m}from"./chunk-3EDSDPIP.js";import{DEFAULT_PANEL_WORDS as n}from"./chunk-TRVZ7C23.js";import{DEFAULT_NODE_MENU_WORDS as c}from"./chunk-WK3AFPXY.js";import{DEFAULT_SAVE_WORDS as s}from"./chunk-H6DDIBQ4.js";import{DEFAULT_LOCK_WORDS as f}from"./chunk-RE4LP46F.js";import{DEFAULT_CHROME_WORDS as p,DEFAULT_NOTICE_WORDS as i}from"./chunk-ZJEBF4NB.js";import{DEFAULT_RAIL_WORDS as u}from"./chunk-2OAZYSWJ.js";import{DEFAULT_COPY_WORDS as e}from"./chunk-JQM3V7XQ.js";import{DEFAULT_PICK_WORDS as k}from"./chunk-ZAOM6PFH.js";import{DEFAULT_FIELDS_WORDS as j}from"./chunk-LA54QLP5.js";import{DEFAULT_DRAG_WORDS as h}from"./chunk-O2NLQBFX.js";var l={notice:i,lock:f,save:s,chrome:p,rail:u,tree:m,panel:n,fields:j,pick:k,drag:h,menu:c,styleClipboard:r,copy:e,canvas:t,textStyles:o},a=o=>"object"==typeof o&&null!==o;function y(o,r){const t={};for(const m of Object.keys(o)){const n=o[m],c=r[m];null==c?t[m]=n:a(n)?t[m]=a(c)?y(n,c):n:t[m]=typeof c==typeof n?c:n}return t}function F(o,r){return r?y(o,r):o}export{l as DEFAULT_EASEL_STRINGS,F as mergeEaselStrings};
@@ -0,0 +1 @@
1
+ var t={settings:"Settings",buckets:{Content:"Content",Style:"Style",Layout:"Layout",Animation:"Animation"},followsDefault:"Default",reset:"Reset",resetName:({label:t})=>`Reset ${t}`,backToDefault:({detail:t})=>`Back to default: ${t}`};export{t as DEFAULT_PANEL_WORDS};
@@ -0,0 +1,16 @@
1
+ import{DEFAULT_TREE_WORDS as e}from"./chunk-3EDSDPIP.js";import{ChevronIcon as a,AddIcon as r}from"./chunk-6EIVTKZZ.js";import{jsx as l,jsxs as n,Fragment as s}from"react/jsx-runtime";function t({className:e,children:a,rootProps:r}){/* @__PURE__ */
2
+ return l("div",{...r,className:e?`es-tree ${e}`:"es-tree",children:a})}function i({children:e}){/* @__PURE__ */
3
+ return l("div",{className:"es-tree-group",children:e})}function d({children:e}){/* @__PURE__ */
4
+ return l("div",{className:"es-subtree",children:e})}var o=e.dragHint;function c({icon:r,name:t,preview:i,selected:d,hidden:o,draggable:c,dragHint:p,dragging:m,drop:h,fold:u,handle:b,actions:N,nameSlot:g,onSelect:k,marks:y,badge:f,trailing:v,children:w,rowProps:P,words:j=e}){const x=["es-tree-row",d?"is-selected":"",o?"is-hidden":"",c?"is-draggable":"",m?"is-dragging":"",h?`is-drop-${h}`:""].filter(Boolean).join(" "),A=/* @__PURE__ */n(s,{children:[
5
+ /* @__PURE__ */n("span",{className:"es-tree-name",children:[t,i?/* @__PURE__ */l("span",{className:"es-tree-preview",children:i}):null]}),y?.map(e=>/* @__PURE__ */l("span",{className:"es-tree-mark",title:e.label,"aria-label":e.label,role:"img",children:e.icon},e.key)),null!=f&&!1!==f?/* @__PURE__ */l("span",{className:"es-tree-badge",children:f}):null]});/* @__PURE__ */
6
+ return n("div",{...P,className:x,children:[c?
7
+ /* @__PURE__ */n(s,{children:[
8
+ /* @__PURE__ */l("span",{className:"es-tree-grip","aria-hidden":"true",children:"⋮"}),
9
+ /* @__PURE__ */l("span",{className:"es-tree-hint","aria-hidden":"true",children:p??j.dragHint})]}):b?/* @__PURE__ */l("button",{type:"button",className:"es-tree-handle",...b,children:"⋮⋮"}):null,u?/* @__PURE__ */l("button",{type:"button",className:"es-tree-caret","aria-label":u.open?j.collapseNamed({label:u.label}):j.expandNamed({label:u.label}),"aria-expanded":u.open,title:u.open?j.collapse:j.expand,onClick:e=>{e.stopPropagation(),u.onToggle()},children:/* @__PURE__ */l(a,{size:11,strokeWidth:2.6,className:u.open?"es-tree-chev is-open":"es-tree-chev"})}):/* @__PURE__ */l("span",{className:"es-tree-caret-spacer","aria-hidden":"true"}),
10
+ /* @__PURE__ */l("span",{className:"es-tree-chip","aria-hidden":"true",children:r}),
11
+ /* @__PURE__ */n("span",{className:"es-tree-name-box",children:[g??(k?
12
+ /* @__PURE__ */l("button",{type:"button",className:"es-tree-select","aria-current":d?"true":void 0,"aria-keyshortcuts":c?"Alt+ArrowUp Alt+ArrowDown":void 0,onClick:k,children:A}):A),N?/* @__PURE__ */l("span",{className:"es-tree-actions",children:N}):null]}),v?/* @__PURE__ */l("span",{className:"es-tree-trailing",title:v.label,"aria-label":v.label,role:"img",children:v.icon}):null,w]})}function p({kind:e,label:a,onClick:r,pressed:n,disabled:s,children:t}){/* @__PURE__ */
13
+ return l("button",{type:"button",className:"delete"===e?"es-tree-del":"eye"===e?"es-tree-eye":"es-tree-act",title:a,"aria-label":a,"aria-pressed":n,disabled:s,onClick:e=>{e.stopPropagation(),r()},children:t})}function m({drop:e,onAdd:a,label:r,seamProps:n}){const s=["es-tree-seam",e?"is-drop":"",a?"has-add":""].filter(Boolean).join(" ");/* @__PURE__ */
14
+ return l("div",{...n,className:s,children:a?/* @__PURE__ */l("button",{type:"button",className:"es-tree-seam-add","aria-label":r,title:r,onClick:a,children:"+"}):null})}function h({drop:a,onAdd:s,label:t,seamProps:i,words:d=e}){const o=["es-tree-empty",a?"is-drop":"",s?"has-add":""].filter(Boolean).join(" "),c=d.dropHere??e.dropHere;/* @__PURE__ */
15
+ return l("div",{...i,className:o,children:s?/* @__PURE__ */n("button",{type:"button",className:"es-tree-empty-add",onClick:s,children:[
16
+ /* @__PURE__ */l(r,{size:12,"aria-hidden":"true"}),a?c:t??d.addBlock??e.addBlock]}):/* @__PURE__ */l("span",{className:"es-tree-empty-note",children:a?c:t??d.emptySlot??e.emptySlot})})}export{t as LayersTree,d as Subtree,o as TREE_DRAG_HINT,h as TreeEmptySlot,i as TreeGroupLabel,c as TreeRow,p as TreeRowAction,m as TreeSeam};
@@ -1,3 +1,3 @@
1
1
  import{DEFAULT_RAIL_WORDS as a}from"./chunk-2OAZYSWJ.js";import{wordFitVars as i}from"./chunk-BZ5ASXOL.js";import{jsxs as e,jsx as r}from"react/jsx-runtime";function o({label:a,worded:i,icon:o,active:l,disabled:t,onSelect:n,className:d}){const s=["es-rail-btn",l?"is-active":"",d??""].filter(Boolean).join(" ");/* @__PURE__ */
2
2
  return e("button",{type:"button",className:s,title:a,"aria-label":a,"aria-pressed":"boolean"==typeof l?l:void 0,disabled:t,onClick:t?void 0:n,children:[o,i?/* @__PURE__ */r("span",{className:"es-rail-word","aria-hidden":"true",children:a}):null]})}function l({items:e,ariaLabel:l=a.label,className:t,orientation:n="column",wordFit:d}){const s="row"===n,c=s&&d?d:void 0;/* @__PURE__ */
3
- return r("div",{className:["es-rail",s?"es-rail-row":"",c?"is-measured":"",t??""].filter(Boolean).join(" "),role:"toolbar","aria-orientation":s?"horizontal":"vertical","aria-label":l,style:c&&i(e.length,c),children:e.map(a=>/* @__PURE__ */r(o,{label:a.label,worded:Boolean(c),icon:a.icon,active:a.active,disabled:a.disabled,onSelect:a.onSelect},a.id))})}var t={railWidth:46,railPaddingY:8,railGap:4,railRadius:12,buttonSize:34,buttonRadius:9,iconSize:18,wordPaddingX:8,wordGap:8,wordFontSize:12,wordFontWeight:500,transition:"background 0.12s, color 0.12s",disabledOpacity:.35,color:{background:"#ffffff",shadow:"0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)",idle:"#6b7280",hoverBg:"#f3f4f6",hoverFg:"#111827",accent:"#2563eb",accentTint:"#eff6ff"}},n={railWidth:"--es-rail-w",railPaddingY:"--es-rail-pad-y",railGap:"--es-rail-gap",railRadius:"--es-rail-radius",buttonSize:"--es-rail-btn-size",buttonRadius:"--es-rail-btn-radius",iconSize:"--es-rail-icon-size",wordPaddingX:"--es-rail-word-pad-x",wordGap:"--es-rail-word-gap",wordFontSize:"--es-rail-word-size",wordFontWeight:"--es-rail-word-weight",background:"--es-rail-bg",shadow:"--es-rail-shadow",idle:"--es-rail-fg",hoverBg:"--es-rail-hover-bg",hoverFg:"--es-rail-hover-fg",accent:"--es-rail-accent",accentTint:"--es-rail-accent-tint"};export{l as EditorRail,o as EditorRailButton,n as railCssVars,t as railTokens};
3
+ return r("div",{className:["es-rail",s?"es-rail-row":"",c?"is-measured":"",t??""].filter(Boolean).join(" "),role:"toolbar","aria-orientation":s?"horizontal":"vertical","aria-label":l,style:c&&i(e.length,c),children:e.map(a=>/* @__PURE__ */r(o,{label:a.label,worded:Boolean(c),icon:a.icon,active:a.active,disabled:a.disabled,onSelect:a.onSelect},a.id))})}var t={railWidth:46,railPaddingY:8,railGap:4,railRadius:12,buttonSize:34,buttonRadius:9,iconSize:18,wordPaddingX:8,wordGap:8,wordFontSize:12,wordFontWeight:500,transition:"background 0.12s, color 0.12s",disabledOpacity:.35,color:{background:"#ffffff",shadow:"0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)",idle:"#6b7280",hoverBg:"#f3f4f6",hoverFg:"#111827",accent:"#2563eb",accentTint:"#eff6ff"}},n={railWidth:"--es-rail-w",railPaddingY:"--es-rail-pad-y",railGap:"--es-rail-gap",railRadius:"--es-rail-radius",buttonSize:"--es-rail-btn-size",buttonRadius:"--es-rail-btn-radius",iconSize:"--es-rail-icon-size",wordPaddingX:"--es-rail-word-pad-x",wordGap:"--es-rail-word-gap",wordFontSize:"--es-rail-word-size",wordFontWeight:"--es-rail-word-weight",background:"--es-rail-bg",shadow:"--es-rail-shadow",idle:"--es-rail-fg",hoverBg:"--es-rail-hover-bg",hoverFg:"--es-rail-hover-fg",accent:"--es-rail-accent",accentTint:"--es-rail-accent-tint"};export{l as EaselRail,o as EaselRailButton,n as railCssVars,t as railTokens};
@@ -0,0 +1 @@
1
+ var e={reload:"Reload the saved version",takeOver:"Take over editing",takeBack:"Take it back",viewReadOnly:"View read-only",savedByYou:({noun:e,when:i})=>`You saved this ${e} in another tab or window ${i}.`,savedByOther:({name:e,noun:i,when:n})=>`${e} saved this ${i} ${n}.`,conflictBody:"Your last change was not saved. It is still on screen here, but this copy is out of date — copy anything you need, then reload to carry on from the saved version.",takeOverWhileDeciding:"Nobody else can save while you decide. Nothing on your screen is lost.",tookOver:({name:e,noun:i,when:n})=>`${e} took over this ${i} ${n}.`,tookOverBody:"Your changes since then are still on screen but are no longer being saved.",viewingOnly:"Viewing only.",viewingOnlyBody:({name:e,noun:i,seen:n})=>`${e} is editing this ${i} (last seen ${n}). Nothing you change here is saved.`,editing:({name:e,noun:i})=>`${e} is editing this ${i}`,editingBody:({seen:e})=>`(last seen ${e}). Nothing you change here will be saved while they are in it.`,takeOverTold:"They are told straight away and stop being able to save."},i={device:"Preview device",upLevel:"Go up one level",upLevelTo:({label:e,name:i})=>`${e} to ${i}`,resize:"Drag to resize · double-click to reset",mediaLibrary:"Media library",mediaChoose:({kind:e})=>`Choose ${e}`,mediaFor:({field:e})=>`For ${e}`,mediaKinds:{image:"image",video:"video",svg:"SVG logo"},mediaCancel:"Cancel",mediaKeep:({kind:e})=>`Keep the current ${e}`,hidePanel:"Hide panel",hidePanelLabel:({side:e})=>`Hide the ${e} panel`};export{i as DEFAULT_CHROME_WORDS,e as DEFAULT_NOTICE_WORDS};
@@ -28,7 +28,14 @@
28
28
  * `.es-copy-box` below for the caret bug that rule exists to stop. */
29
29
  --es-copy-field-pad: 4px 8px;
30
30
  --es-copy-field-ring: var(--es-accent, #2563eb);
31
- --es-copy-radius: 4px;
31
+ /* react-os-shell's inputClasses (design v5, 0.95.0): text-sm, a blue-400
32
+ border and a 2px blue-400/30 ring while focused. One set of numbers for
33
+ BOTH views, so flipping "Show marks" moves no word. */
34
+ --es-copy-field-font: 14px;
35
+ --es-copy-field-line: 1.5;
36
+ --es-copy-focus-border: #60a5fa;
37
+ --es-copy-focus-ring: 0 0 0 2px rgba(96, 165, 250, 0.3);
38
+ --es-copy-radius: 6px;
32
39
 
33
40
  display: block;
34
41
  /* A container, so a host can query the box's own width. Never on
@@ -184,15 +191,16 @@
184
191
  }
185
192
 
186
193
  .es-copy-box {
187
-
188
194
  border: 1px solid var(--es-copy-field-border);
189
195
  border-radius: var(--es-copy-radius);
190
196
  background: var(--es-copy-field-bg);
191
- font-size: 12px;
197
+ font-size: var(--es-copy-field-font);
198
+ line-height: var(--es-copy-field-line);
192
199
  }
193
200
 
194
201
  .es-copy-box:focus-within {
195
- border-color: var(--es-copy-field-ring);
202
+ border-color: var(--es-copy-focus-border);
203
+ box-shadow: var(--es-copy-focus-ring);
196
204
  }
197
205
 
198
206
  .es-copy-box.es-gold-is-off {
@@ -254,10 +262,25 @@
254
262
 
255
263
  .es-copy-link-actions {
256
264
  display: flex;
257
- justify-content: flex-end;
265
+ align-items: center;
266
+ justify-content: space-between;
258
267
  gap: 8px;
259
268
  }
260
269
 
270
+ /* Cancel and Apply sit together at the end; Remove, when there is a link to
271
+ take off, at the start (the design's footer). */
272
+ .es-copy-link-end {
273
+ display: flex;
274
+ gap: var(--es-space-4, 4px);
275
+ margin-left: auto;
276
+ }
277
+
278
+ .es-copy-link-btn.is-danger {
279
+ border-color: transparent;
280
+ background: transparent;
281
+ color: var(--es-danger, #dc2626);
282
+ }
283
+
261
284
  .es-copy-link-btn {
262
285
  height: 28px;
263
286
  padding: 0 12px;
@@ -280,3 +303,363 @@
280
303
  opacity: 0.5;
281
304
  cursor: default;
282
305
  }
306
+
307
+ /* — the rich view (0.95.0, rulings B + C) — */
308
+
309
+ /*
310
+ * The box that shows the EFFECT (./RichBox). Same frame and same type as the
311
+ * marks view above, so the "Show marks" switch flips the marks in and out and
312
+ * moves nothing else.
313
+ *
314
+ * Unlike the gold layer, weight and slant are SAFE here: there is no second
315
+ * surface for a wider glyph to drift from — the caret is the browser's own,
316
+ * in the same text it draws.
317
+ *
318
+ * The colours are the gold layer's (`--es-gold-accent`, `--es-gold-quiet`), so
319
+ * Emphasis and Quiet look the same in both views and a host aliases them once.
320
+ */
321
+ .es-rich-wrap {
322
+ position: relative;
323
+ }
324
+
325
+ .es-rich {
326
+ box-sizing: border-box;
327
+ min-height: calc(var(--es-copy-field-font) * var(--es-copy-field-line) + 14px);
328
+ padding: var(--es-copy-field-pad);
329
+ border: 1px solid var(--es-copy-field-border);
330
+ border-radius: var(--es-copy-radius);
331
+ background: var(--es-copy-field-bg);
332
+ color: var(--es-text, #111827);
333
+ font: inherit;
334
+ font-size: var(--es-copy-field-font);
335
+ line-height: var(--es-copy-field-line);
336
+ white-space: pre-wrap;
337
+ overflow-wrap: anywhere;
338
+ outline: none;
339
+ cursor: text;
340
+ }
341
+
342
+ /* Many lines: room for three, like the textarea it replaces (design: the
343
+ empty box is 4.625rem). */
344
+ .es-rich.is-multiline {
345
+ min-height: 4.625rem;
346
+ }
347
+
348
+ /* One line: it scrolls sideways rather than wrapping, as an <input> does. */
349
+ .es-rich.is-single {
350
+ white-space: pre;
351
+ overflow-x: auto;
352
+ overflow-y: hidden;
353
+ scrollbar-width: none;
354
+ }
355
+
356
+ .es-rich:focus {
357
+ border-color: var(--es-copy-focus-border);
358
+ box-shadow: var(--es-copy-focus-ring);
359
+ }
360
+
361
+ .es-rich.is-off {
362
+ background: var(--es-field-bg-off, #f9fafb);
363
+ opacity: 0.6;
364
+ cursor: not-allowed;
365
+ }
366
+
367
+ .es-rich-line {
368
+ min-height: calc(var(--es-copy-field-font) * var(--es-copy-field-line));
369
+ }
370
+
371
+ .es-rich-line.is-bullet {
372
+ display: list-item;
373
+ list-style: disc outside;
374
+ margin-left: 1.25em;
375
+ }
376
+
377
+ .es-rich-line.is-bullet::marker {
378
+ color: var(--es-text-muted, #9ca3af);
379
+ }
380
+
381
+ /* A numbered line (E1's `12. words`) draws the number AS SAVED — `01` stays
382
+ `01` — in the margin, where the caret never goes. Not `list-item`: a list
383
+ counter would renumber, and the saved digits are the truth. */
384
+ .es-rich-line.is-numbered {
385
+ position: relative;
386
+ /* Room for up to three digits and the dot ("100.") left of the words. */
387
+ margin-left: 2em;
388
+ }
389
+
390
+ .es-rich-line.is-numbered::before {
391
+ content: attr(data-number) '.';
392
+ position: absolute;
393
+ right: 100%;
394
+ padding-right: 0.35em;
395
+ white-space: nowrap;
396
+ color: var(--es-text-muted, #9ca3af);
397
+ font-variant-numeric: tabular-nums;
398
+ pointer-events: none;
399
+ user-select: none;
400
+ }
401
+
402
+ /* E1's spans. Underline, sup and sub are the browser's own <u>, <sup>, <sub>.
403
+ A theme colour reads `--es-color-<name>`, which the HOST sets from its
404
+ theme (RichBox draws the var); the words keep the text colour until it does. */
405
+ .es-rich u {
406
+ text-underline-offset: 2px;
407
+ }
408
+
409
+ .es-rich sup,
410
+ .es-rich sub {
411
+ font-size: 0.75em;
412
+ line-height: 0;
413
+ }
414
+
415
+ .es-rich strong {
416
+ font-weight: 600;
417
+ }
418
+
419
+ .es-rich .es-rich-emphasis {
420
+ color: var(--es-gold-accent, var(--gold, #c9a461));
421
+ font-weight: 600;
422
+ }
423
+
424
+ .es-rich .es-rich-quiet {
425
+ color: var(--es-gold-quiet, #6b7280);
426
+ font-size: 0.86em;
427
+ }
428
+
429
+ .es-rich .es-rich-link {
430
+ color: var(--es-accent, #2563eb);
431
+ text-decoration: underline;
432
+ text-underline-offset: 3px;
433
+ cursor: text;
434
+ }
435
+
436
+ .es-rich-placeholder {
437
+ position: absolute;
438
+ inset: 0;
439
+ padding: var(--es-copy-field-pad);
440
+ border: 1px solid transparent;
441
+ color: var(--es-gold-placeholder, #9ca3af);
442
+ font-size: var(--es-copy-field-font);
443
+ line-height: var(--es-copy-field-line);
444
+ pointer-events: none;
445
+ }
446
+
447
+ /* The "Show marks" switch, under the box (design v5: react-os-shell's Switch
448
+ with its label to the right). The switch is the panel's own (`.es-switch`). */
449
+ .es-copy-marks {
450
+ display: flex;
451
+ align-items: center;
452
+ gap: var(--es-space-8, 8px);
453
+ margin-top: var(--es-copy-gap);
454
+ }
455
+
456
+ .es-copy-marks-label {
457
+ font-size: 13px;
458
+ color: var(--es-text-secondary, #374151);
459
+ }
460
+
461
+ /* — the final toolbar (E5b, design final 2026-10-06) — */
462
+
463
+ /*
464
+ * TWO ROWS ON ONE 9-COLUMN GRID, flush to the box at both ends: every button
465
+ * sits under the one above it. The size is react-os-shell's IconButton md
466
+ * (`--es-copy-mark-size`, 32px), the size the design draws in a 320px panel.
467
+ * A cell the host does not offer is drawn EMPTY, so the columns still line up.
468
+ */
469
+ .es-tb-wrap {
470
+ /*
471
+ * The button size: react-os-shell's IconButton md (32px) — but never more
472
+ * than a ninth of the row, so the row is FLUSH to the box at both ends. A
473
+ * 320px panel's box is 286px (its 1px border takes two), and nine 32px
474
+ * buttons would overrun it by 2px; here they are 31.8px. On the WRAPPER, so
475
+ * the two windows, which sit beside the toolbar, read it too.
476
+ */
477
+ --es-tb-size: min(var(--es-copy-mark-size), calc(100cqw / 9));
478
+ position: relative;
479
+ margin-bottom: var(--es-copy-gap);
480
+ }
481
+
482
+ .es-tb {
483
+ display: flex;
484
+ flex-direction: column;
485
+ gap: var(--es-space-4, 4px);
486
+ }
487
+
488
+ .es-tb-row {
489
+ display: grid;
490
+ grid-template-columns: repeat(9, var(--es-tb-size));
491
+ justify-content: space-between;
492
+ }
493
+
494
+ /* The alignment and case groups are radiogroups for a screen reader and
495
+ nothing for the grid: their buttons are cells of the row. */
496
+ .es-tb-group {
497
+ display: contents;
498
+ }
499
+
500
+ .es-tb-btn {
501
+ box-sizing: border-box;
502
+ width: var(--es-tb-size);
503
+ height: var(--es-tb-size);
504
+ display: inline-flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ padding: 0;
508
+ border: 0;
509
+ border-radius: 6px;
510
+ background: transparent;
511
+ color: var(--es-text-secondary, #374151);
512
+ cursor: pointer;
513
+ }
514
+
515
+ .es-tb-btn svg {
516
+ width: 16px;
517
+ height: 16px;
518
+ }
519
+
520
+ .es-tb-btn:hover:not(:disabled) {
521
+ background: var(--es-hover, #f3f4f6);
522
+ }
523
+
524
+ .es-tb-btn:focus-visible {
525
+ outline: none;
526
+ box-shadow: var(--es-copy-focus-ring);
527
+ }
528
+
529
+ /* Lit: the selection wears the mark (a press takes it off), the window is
530
+ open, or the field holds that value — react-os-shell's selected tone. */
531
+ .es-tb-btn.is-on,
532
+ .es-tb-btn.is-on:hover:not(:disabled) {
533
+ background: var(--es-accent-tint, #eff6ff);
534
+ color: var(--es-accent-text, #1d4ed8);
535
+ }
536
+
537
+ .es-tb-btn:disabled {
538
+ opacity: 0.6;
539
+ cursor: not-allowed;
540
+ }
541
+
542
+ /* The bar under the A is the colour the selected words wear. */
543
+ .es-tb-color svg rect {
544
+ fill: var(--es-tb-run, currentColor);
545
+ }
546
+
547
+ /*
548
+ * A NARROW BOX keeps both rows and shrinks the buttons a little — never wraps.
549
+ * The design: under a 300px panel, the shell's next size down (24px), and no
550
+ * wider than a ninth of the row. A 300px panel less its two 16px gutters is a
551
+ * 268px box: `.es-copy` is the container that measures it.
552
+ */
553
+ @container (width < 268px) {
554
+ .es-tb-wrap {
555
+ --es-tb-size: min(24px, calc(100cqw / 9));
556
+ }
557
+
558
+ .es-tb-btn {
559
+ border-radius: 5px;
560
+ }
561
+
562
+ .es-tb-btn svg {
563
+ width: 14px;
564
+ height: 14px;
565
+ }
566
+ }
567
+
568
+ /*
569
+ * THE TWO WINDOWS (colour, link) drop from their button, under the first row
570
+ * and over the second, pushing nothing down — as drawn. They sit over the box
571
+ * itself, so the panel's scrolling edge is not near them. DatePicker's
572
+ * popover: 288px, 12px corners, a 12px inset, react-os-shell's shadow.
573
+ */
574
+ .es-copy-pop {
575
+ position: absolute;
576
+ z-index: 5;
577
+ left: 0;
578
+ top: calc(var(--es-tb-size) + 6px);
579
+ box-sizing: border-box;
580
+ width: 288px;
581
+ max-width: 100%;
582
+ margin-top: 0;
583
+ display: flex;
584
+ flex-direction: column;
585
+ gap: var(--es-space-8, 8px);
586
+ padding: 12px;
587
+ border: 1px solid var(--es-border, #e5e7eb);
588
+ border-radius: 12px;
589
+ background: var(--es-raised, #fff);
590
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
591
+ }
592
+
593
+ /* The point, aimed at its button: column k of 9 across the row (100cqw). */
594
+ .es-copy-pop::before {
595
+ content: '';
596
+ position: absolute;
597
+ top: -6px;
598
+ width: 10px;
599
+ height: 10px;
600
+ background: inherit;
601
+ border-left: 1px solid var(--es-border, #e5e7eb);
602
+ border-top: 1px solid var(--es-border, #e5e7eb);
603
+ transform: rotate(45deg);
604
+ }
605
+
606
+ .es-copy-colors::before {
607
+ left: calc(4 * (100cqw - var(--es-tb-size)) / 8 + var(--es-tb-size) / 2 - 6px);
608
+ }
609
+
610
+ .es-copy-link.es-copy-pop::before {
611
+ left: calc(5 * (100cqw - var(--es-tb-size)) / 8 + var(--es-tb-size) / 2 - 6px);
612
+ }
613
+
614
+ .es-copy-pop-label,
615
+ .es-copy-pop .es-copy-link-label {
616
+ font-size: 12px;
617
+ font-weight: 500;
618
+ color: var(--es-text-secondary, #4b5563);
619
+ }
620
+
621
+ .es-copy-swatches {
622
+ display: flex;
623
+ flex-wrap: wrap;
624
+ /* One group of colours: the scale's step for things that are one thing. */
625
+ gap: var(--es-space-4, 4px);
626
+ }
627
+
628
+ .es-copy-swatch {
629
+ width: 22px;
630
+ height: 22px;
631
+ padding: 0;
632
+ border: 0;
633
+ border-radius: 6px;
634
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
635
+ cursor: pointer;
636
+ }
637
+
638
+ .es-copy-swatch[aria-pressed='true'] {
639
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 2px #fff, 0 0 0 4px var(--es-accent, #2563eb);
640
+ }
641
+
642
+ /* Any color (E1 widened 2026-10-06) is pick's own ColourWindow (pick.css):
643
+ inside this window it is not a second box — no border, no inset. */
644
+ .es-copy-colors .es-pick-window {
645
+ padding: 0;
646
+ border: 0;
647
+ border-radius: 0;
648
+ background: transparent;
649
+ gap: var(--es-space-8, 8px);
650
+ }
651
+
652
+ .es-copy-pop-foot {
653
+ display: flex;
654
+ justify-content: space-between;
655
+ align-items: center;
656
+ gap: var(--es-space-4, 4px);
657
+ }
658
+
659
+ /* — the number cells (E5b): a 2-column grid between the toolbar and the box — */
660
+ .es-copy-cells {
661
+ display: grid;
662
+ grid-template-columns: repeat(2, minmax(0, 1fr));
663
+ gap: var(--es-space-4, 4px);
664
+ margin-bottom: var(--es-copy-gap);
665
+ }