efficient-web-builder 6.0.0 → 6.1.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 (115) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +42 -0
  3. package/dist/components/ApplyCornersToSiblings.js +1 -1
  4. package/dist/components/Banner.js +1 -1
  5. package/dist/components/BlockGapField.js +1 -1
  6. package/dist/components/BlogPostSource.js +1 -1
  7. package/dist/components/Breadcrumb.js +1 -1
  8. package/dist/components/CardShadowField.js +1 -1
  9. package/dist/components/CategoryBar.js +1 -1
  10. package/dist/components/ChatSettingsPanel.js +1 -1
  11. package/dist/components/ClearColoursDialog.js +1 -1
  12. package/dist/components/CornersField.js +1 -1
  13. package/dist/components/DocBody.js +5 -5
  14. package/dist/components/DuplicateToPageMenu.js +1 -1
  15. package/dist/components/FAQ.js +1 -1
  16. package/dist/components/Flex.js +1 -1
  17. package/dist/components/Footprint.js +3 -3
  18. package/dist/components/HeadingAudit.js +1 -1
  19. package/dist/components/HeroImageField.js +1 -1
  20. package/dist/components/HeroSection.js +2 -2
  21. package/dist/components/HeroSingle.js +1 -1
  22. package/dist/components/HeroSlide.js +1 -1
  23. package/dist/components/HoverEffectField.js +1 -1
  24. package/dist/components/ImageFocusRow.js +1 -1
  25. package/dist/components/IntegrationsSection.js +1 -1
  26. package/dist/components/IntroBleed.js +1 -1
  27. package/dist/components/KeyFeatures.js +1 -1
  28. package/dist/components/LocationsGroupedField.js +1 -1
  29. package/dist/components/MediaUploadField.js +1 -1
  30. package/dist/components/MultiSelectField.js +1 -1
  31. package/dist/components/PagesPanel.js +1 -1
  32. package/dist/components/PartInkControl.js +1 -1
  33. package/dist/components/PartResetDot.js +1 -1
  34. package/dist/components/PartSettingsPanel.js +1 -1
  35. package/dist/components/PartTextBox.js +1 -1
  36. package/dist/components/PhotographyField.js +1 -1
  37. package/dist/components/ProcessSteps.js +1 -1
  38. package/dist/components/SearchSelectField.d.ts +1 -1
  39. package/dist/components/SearchSelectField.js +1 -1
  40. package/dist/components/SectionEditor.js +1 -1
  41. package/dist/components/SectionTextEntries.js +1 -1
  42. package/dist/components/SectionThemePicker.js +1 -1
  43. package/dist/components/Series.js +1 -1
  44. package/dist/components/ShadowColourField.js +1 -1
  45. package/dist/components/SideSpaceField.js +1 -1
  46. package/dist/components/SiteFields.js +1 -1
  47. package/dist/components/SiteWidthField.js +1 -1
  48. package/dist/components/SlotChildRows.js +1 -1
  49. package/dist/components/SocialLinksPanel.js +1 -1
  50. package/dist/components/SourceStatus.js +1 -1
  51. package/dist/components/SpecStrip.js +1 -1
  52. package/dist/components/Split.js +1 -1
  53. package/dist/components/StandaloneSectionEditor.js +1 -1
  54. package/dist/components/StatsParagraph.js +1 -1
  55. package/dist/components/StorefrontLinkField.js +1 -1
  56. package/dist/components/StylesPanel.js +1 -1
  57. package/dist/components/SwitchToBoxFooter.js +1 -1
  58. package/dist/components/Testimonials.js +1 -1
  59. package/dist/components/TextStyleRow.js +1 -1
  60. package/dist/components/TextStylesField.js +1 -1
  61. package/dist/components/ThemeCard.js +1 -1
  62. package/dist/components/ThemeColourField.js +1 -1
  63. package/dist/components/ThemeField.js +1 -1
  64. package/dist/components/TickerSection.js +1 -1
  65. package/dist/components/TickerSettingsPanel.js +1 -1
  66. package/dist/components/TitleWithButtons.js +1 -1
  67. package/dist/components/WebsiteScreenParts.js +1 -1
  68. package/dist/components/WebsiteSettingsPanel.js +1 -1
  69. package/dist/components/WidthFollowField.js +1 -1
  70. package/dist/components/preview-devices.js +1 -1
  71. package/dist/components/storefront-editor.css +43 -37
  72. package/dist/components/useLocationsTree.js +1 -1
  73. package/dist/lib/content/ink.d.ts +36 -0
  74. package/dist/lib/content/ink.js +1 -0
  75. package/dist/lib/content/section-surface.js +1 -1
  76. package/dist/lib/editor-words-catalogue.d.ts +1184 -0
  77. package/dist/lib/editor-words-catalogue.js +11 -0
  78. package/dist/lib/editor-words.d.ts +15 -0
  79. package/dist/lib/editor-words.js +1 -0
  80. package/dist/lib/links/link-picker-setup.js +1 -1
  81. package/dist/lib/puck/ColourControl.js +1 -1
  82. package/dist/lib/puck/MarkupToolbar.js +1 -1
  83. package/dist/lib/puck/apply-card-corners.js +1 -1
  84. package/dist/lib/puck/blocks/general/Breadcrumb/render.js +1 -1
  85. package/dist/lib/puck/blocks/general/Cards/render.js +1 -1
  86. package/dist/lib/puck/blocks/general/CategoryBar/render.js +1 -1
  87. package/dist/lib/puck/blocks/general/Chart/render.js +2 -2
  88. package/dist/lib/puck/blocks/general/DocBody/render.js +1 -1
  89. package/dist/lib/puck/blocks/general/DocMasthead/render.js +1 -1
  90. package/dist/lib/puck/blocks/general/DocTabs/render.js +1 -1
  91. package/dist/lib/puck/blocks/general/FAQ/render.js +1 -1
  92. package/dist/lib/puck/blocks/general/Footprint/render.js +2 -2
  93. package/dist/lib/puck/blocks/general/KeyFeatures/render.js +1 -1
  94. package/dist/lib/puck/blocks/general/Logos/render.js +1 -1
  95. package/dist/lib/puck/blocks/general/Masthead/render.js +1 -1
  96. package/dist/lib/puck/blocks/general/OrderSummary/render.js +1 -1
  97. package/dist/lib/puck/blocks/general/PaymentBadges/render.js +1 -1
  98. package/dist/lib/puck/blocks/general/ProcessSteps/render.js +1 -1
  99. package/dist/lib/puck/blocks/general/Series/render.js +1 -1
  100. package/dist/lib/puck/blocks/general/StatsParagraph/render.js +1 -1
  101. package/dist/lib/puck/blocks/general/Testimonials/render.js +1 -1
  102. package/dist/lib/puck/blocks/general/Timeline/render.js +2 -2
  103. package/dist/lib/puck/blocks/general/TimelineTrack/render.js +1 -1
  104. package/dist/lib/puck/blocks/scaffold.js +1 -1
  105. package/dist/lib/puck/controls.js +1 -1
  106. package/dist/lib/puck/footer-block-row-name.js +1 -1
  107. package/dist/lib/puck/page-root-fields.js +1 -1
  108. package/dist/lib/puck/theme-swatches.js +1 -1
  109. package/dist/lib/source-rules/editor-words.d.ts +26 -0
  110. package/dist/lib/source-rules/editor-words.js +3 -0
  111. package/dist/lib/source-rules/mirrored-rows-agree.js +1 -1
  112. package/dist/lib/source-rules/part-style-naming.js +1 -1
  113. package/dist/lib/source-rules/support/label-extraction.js +2 -2
  114. package/dist/lib/theme-save-message.js +1 -1
  115. package/package.json +6 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,174 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.1.0 - 2026-10-14
4
+
5
+ **The editor speaks its host's language.** A host that runs in another
6
+ language hands the editor its words, and the editor says them where it draws
7
+ them (programme: Foyerboard on EFFICIENT, editor languages step 3). In English
8
+ nothing reads differently.
9
+
10
+ - **One seam, `lib/editor-words`.** `configureEditorWords(words, locale,
11
+ easel)` lays a host's words over the English, during its frame's render, as
12
+ it configures `lib/web-runtime`; `say(english, values)` and
13
+ `sayCount(one, other, n)` answer the host's word, or the English. The words
14
+ are keyed by the English they replace: a plain word is a string, a sentence
15
+ names its values in braces (`"Delete {name}": "{name} löschen"`), and a
16
+ host may give a function of the values for a plural or an agreement. A word
17
+ left out, or empty, reads in English. The language is fixed for the life of
18
+ a page (harness UI-25), and plain functions read the words as well as
19
+ components, so they are the module's state.
20
+ - **The English stays the key; it is translated where it is shown.** A
21
+ settings row's label is still the literal its control builder is given, so
22
+ `field-groups` (`bucketOf`, `LABEL_BUCKET`, `RETIRED`), `field-noun`,
23
+ `ThemeCard`'s `ROW_ICON` and the label rules in `lib/source-rules` read the
24
+ same English. Inside `lib/puck/controls` every row says its label, hint,
25
+ placeholder, note and choices at render; the group headings, the Swatches'
26
+ names, the reset marks' details, the focal and placement grids' cells, the
27
+ text lists and the coordinates field do too.
28
+ - **Panels and dialogs** — Pages, Site styles, Styles, Theme, the part
29
+ settings, the Locations field, the text styles, Duplicate to page, Clear
30
+ colours, the chat, social and ticker panels, the section editor's head —
31
+ **block names and Add-panel blurbs** (said in the screen's block look:
32
+ `labelAtLevel`, `descriptions`, `categoryLabel`, and an Add target's
33
+ choices), the **preview devices**, and the **placeholders drawn on the
34
+ canvas while editing** (`phPrev`, and the scaffold rows of the general
35
+ blocks) read the seam.
36
+ - **A host's places are phrases of their own**: "Storefront ▸ Sites ▸
37
+ Settings", "Storefront → Blog" and "the admin" are each a phrase passed into
38
+ the sentence that names them, so a host whose menu is elsewhere renames them
39
+ once, in English too.
40
+ - **What is written into a page stays English** (harness UI-25): a block's
41
+ default content, a saved name, a seeded section. What a visitor reads on the
42
+ published page is never the editor's words.
43
+ - **Easel's words reach the parts that cannot read easel's provider.** A reset
44
+ mark (`SettingsDefaultReset`) drawn inside a control builder's closure is
45
+ handed the panel words the host's frame passed with `configureEditorWords`
46
+ (`editorEaselWords()`); the picture box, the Locations tree and the ticker's
47
+ Layers row are handed `useEaselStrings()`'s. The screen's own leaves (the
48
+ save pill, the right-click menu, Copy / Paste style, the Add panel's tiles)
49
+ are efficient-easel 3.1.0's to hand, and are with it.
50
+ - **The phrases are a typed catalogue**, `lib/editor-words-catalogue`
51
+ (`WEB_BUILDER_WORDS`, `WebBuilderPhrase`, 1,181 phrases), written from the
52
+ source by `pnpm run words` and held to it by the new tree-wide rule
53
+ `lib/source-rules/editor-words` (`scripts/test-editor-words.ts`). A host
54
+ types its words as `EditorWordsFor<WebBuilderPhrase>`. The rule reads a
55
+ phrase a builder or `say` is given as a literal; one built at run time
56
+ (`${kind} colour`) is not read and stays English, which is why such phrases
57
+ are now written whole (`"Padding top"`, `"{value} on desktop"`).
58
+ - **Peer `efficient-shell ^5.6.0 || ^6.4.0 || ^7.7.0`** (was `^5.6.0`), as
59
+ efficient-easel 3.0.0 has it; dev `^7.7.0`. The typecheck, every guard and
60
+ the build pass on 7.x.
61
+ - **Peer `efficient-easel ^2.0.0 || ^3.1.0`** (was `^2.0.0`). 3.1.0 is the
62
+ easel whose screen says its last words from the catalogue, hands its own
63
+ leaves their words and names a block row through the layer's
64
+ `labelAtLevel`, so a host on it gets the whole editor in its language; on
65
+ 2.x the screen's own parts and a block row's name stay English. Checked
66
+ against a local build of 3.1.0 before it was published: the typecheck, the
67
+ boundary, the screen rule and all 150 other guards pass (the one that fails
68
+ is the dev pin's own, which the injected build does not satisfy by design).
69
+ Dev stays on 2.2.0 until 3.1.0 is on npm.
70
+
71
+ - **The colour row's hex box is the swatch's small rung** (`size="sm"`).
72
+ From efficient-shell 7.11.0 the shell's `HexInput` defaults to a larger
73
+ rung, and in the row's fixed `.sf-colour-hexwrap` (4.75rem) `#FFFFFF` showed
74
+ as `#FFFFF` (the value was unchanged). A shell before the prop draws the
75
+ small box it always did. `test-one-colour-control` §5 holds the box to the
76
+ shell's own small rung.
77
+
78
+ ### For hosts
79
+
80
+ - A host in English needs nothing. A host in another language calls
81
+ `configureEditorWords(words, locale, useEaselStrings())` while its frame
82
+ renders (efficient-storefront-blocks does it for its `WebsiteEditor`'s
83
+ `words` / `locale`), and wraps the editor in efficient-easel's
84
+ `EaselStringsProvider`.
85
+ - The storefront's own guards that read a builder file's text are unaffected:
86
+ every word a guard pinned is still the English literal, now inside `say("…")`
87
+ where it is drawn. Three guards here read through `say("…")` now
88
+ (`mirrored-rows-agree`, `part-style-naming`, the panel label reader).
89
+
90
+ ### Guards
91
+
92
+ - New rule `lib/source-rules/editor-words` (`scripts/test-editor-words.ts`):
93
+ the reader on a fixture, a floor of 900 phrases, and the catalogue equal to
94
+ what the source says.
95
+ - New `scripts/test-editor-words-say.tsx`: a host's word, its values, a
96
+ function word, the English for a word left out, empty or throwing; a
97
+ control's row drawn in the host's words while its field keeps its English
98
+ label; a canvas placeholder said only while editing; and the English back
99
+ byte for byte with no words.
100
+ - `test-shell-peer-range` holds the wider range and a 7.x dev shell;
101
+ `test-panel-parts-from-the-shell` holds every range to start at 5.6.0.
102
+ - `support/label-extraction`'s JSX label reader, `mirrored-rows-agree`,
103
+ `part-style-naming`, `test-part-follows-style`, `test-clear-formatting` and
104
+ `test-save-as-template-action` read `label={say("…")}` as the label they
105
+ read before.
106
+
107
+ ## 6.0.3 - 2026-10-13
108
+
109
+ - **A block on a dark picture paints light ink, words and placeholders
110
+ alike** (card [FIX] Dark Text On Dark Hero Boxes, audit item 28). A
111
+ Heading or Text dropped into a Hero's box painted the page's ink (#111 on
112
+ a light site) on the dark overlay: the layer set `color` only, and a block
113
+ paints `text-fg` / `text-fg-dim` / `border-line`, which read the TOKENS
114
+ `--fg` / `--fg-dim` / `--site-line`. Every layer that puts blocks on a
115
+ darkened picture now sets the tokens too: the Hero's box layer, a Hero
116
+ slide's group layer, a Box with a darkened background image (it set no ink
117
+ at all before), the Banner and Split copy on a photograph, and IntroBleed.
118
+ The empty Heading and Text placeholders follow, as they are the same
119
+ elements.
120
+ - **One list of ink tokens, `lib/content/ink`.** `SECTION_PALETTE` names each
121
+ colour a section theme hands its band, with its token and whether it is ink;
122
+ `inkStyle(source)` is the one way a layer changes the ink, and
123
+ `ON_MEDIA_INK_STYLE` is the on-media ink (`--overlay-fg`, its dim and its
124
+ rule as thinned mixes, no raw hex). `sectionAccentVars` now emits its
125
+ `--sf-sec-*` from the same list, byte for byte as before.
126
+ - **Split's body on a photograph** is `text-fg-dim` again (the on-media dim);
127
+ the `opacity-85` patch that stood in for it is gone.
128
+ - Host follow-up: a host's `.sf-section-accent` / `.sf-header-theme` map each
129
+ `--sf-sec-<role>` onto its token; the storefront's own guard should pin that
130
+ list to `SECTION_PALETTE` when it moves to this release. A published hero
131
+ with boxes, every slide, and a Banner, Split or IntroBleed on a photograph
132
+ carry the new style attribute, so the storefront's byte baseline moves.
133
+
134
+ ## 6.0.2 - 2026-10-13
135
+
136
+ - **Every text size in the editor's stylesheet is a type step** (9 / 11 /
137
+ 12 / 14 / 16 / 18 / 20 / 24 / 30; Lewis, 2026-10-12). Each move is the one
138
+ the 10-12 type ruling names. GG confirmed on 2026-10-13 that "never smaller"
139
+ is about spacing and heights, not type.
140
+ - 10 → 11 ("other 10px → 11"): the dropdown caret, the page's Draft tag,
141
+ the chooser's meta line, the theme warning, the readability head.
142
+ - 10.5 → 11 (the same rule): the add card's description, the part chip,
143
+ the gallery count.
144
+ - 11.5 → 12 ("12 = table heads, grey meta (11.5, 12.5 → 12)"): the
145
+ site-wide row's description, the form summary warning, the part-style
146
+ state, the gallery filter.
147
+ - 12.5 → 12 (the same rule; "add-section card name 12.5 → 12"): the
148
+ site-wide row's name, the add card's name and its Add button, the empty
149
+ state's line.
150
+ - 15 → 16 ("15/17 → 16"): the add card's plus and the large A of the text
151
+ scale.
152
+ - The theme card's preview keeps its own sizes (7.5 / 8.5 / 9.5px): it is a
153
+ picture of a page, drawn small, and its type is the drawing's.
154
+
155
+ ## 6.0.1 - 2026-10-13
156
+
157
+ - **The settings panel's side padding is 16** (was 14). The spacing scale
158
+ Lewis ruled on 2026-10-12 is 2 / 4 / 8 / 12 / 16 / …, and a value off it
159
+ goes up, never down (2026-10-13). The narrow step stays 8. The content
160
+ width card 66212 protects (241px) now needs a 285px panel, so the
161
+ container line moves from `< 280px` to `< 284px`, for the body padding
162
+ and for the segmented strip's narrow padding together (one edge, one
163
+ number). At the 320 default the tab strip is 277 with a scrollbar, still
164
+ clear of the 270 its widest tier needs.
165
+ - **The editor's 13px text is 14** (the type steps: 9 / 11 / 12 / 14 / 16 /
166
+ …; 13 → 14 by name). The inspector's inputs, textareas and selects, the
167
+ dropdown trigger, the page list's search and its new-page row, the
168
+ chooser and its items, the read-only field, the preview pin's label, the
169
+ column step's value, the note, and the part-style options: 14 rules.
170
+ easel's own 13px rules move in easel's pull request.
171
+
3
172
  ## 6.0.0 - 2026-10-13
4
173
 
5
174
  - **Breaking: efficient-shell ^5.6.0** (peer; was `^4.171.0 || ^5.0.0`). The
package/README.md CHANGED
@@ -32,6 +32,48 @@ What a host adds, it hands over on the editor's session
32
32
 
33
33
  The storefront's are assembled in its `lib/storefront-editor.ts`.
34
34
 
35
+ ## The editor's words in a host's language
36
+
37
+ The editor speaks English, and a host that runs in another language lays its
38
+ own words over it (6.1.0). The English stays in the code, where it is said,
39
+ and many of the words are also keys (a row is filed under its tab and given
40
+ its glyph by its English label), so it is translated where it is SHOWN:
41
+
42
+ - **The words are keyed by the English they replace.**
43
+ `efficient-web-builder/lib/editor-words-catalogue` exports
44
+ `WEB_BUILDER_WORDS`, every phrase the editor says (a settings row's label,
45
+ hint and choices, a group heading, a panel's and a dialog's words, a block's
46
+ name and its Add-panel blurb, a placeholder drawn on the canvas while
47
+ editing), and the type of its keys, `WebBuilderPhrase`. It is written from
48
+ the source by `pnpm run words` and held to it by
49
+ `scripts/test-editor-words.ts`, so a host typing its catalogue as
50
+ `EditorWordsFor<WebBuilderPhrase>` fails its typecheck on a phrase it lacks.
51
+ - **A sentence with a value names it in braces**, in the English and in the
52
+ host's word alike: `"Delete {name}": "{name} löschen"`. A host may give a
53
+ function of the values instead, for a plural or an agreement the braces
54
+ cannot say (`"{n} pages": ({ n }) => …`). A count is two phrases
55
+ (`sayCount("{n} page", "{n} pages", n)`).
56
+ - **Names of a host's places are phrases of their own**, so a host renames
57
+ them once, in English too: the editor says "Storefront ▸ Sites ▸ Settings"
58
+ and "the admin", where an EFFICIENT admin has them, and a host whose menu
59
+ is elsewhere says its own.
60
+ - **The host hands its words once, while its frame renders**, with
61
+ `configureEditorWords(words, locale)` from `lib/editor-words` — as it
62
+ configures `lib/web-runtime`. The words are fixed for the life of a page
63
+ (harness UI-25), one editor is mounted at a time, and they are read by plain
64
+ functions as well as components, so they are the module's state, not a
65
+ React context. A word left out reads in English.
66
+ - **What is written into a page stays English**: a block's default content, a
67
+ saved name. And what a visitor reads on the published page is never the
68
+ editor's words.
69
+ - **The engine's words are efficient-easel's** (`EaselStringsProvider`); a host
70
+ wraps the editor in it. The parts the builder draws itself that take
71
+ easel's words as a prop (a picture box, a Locations tree) are handed
72
+ `useEaselStrings()`'s.
73
+
74
+ `efficient-storefront-blocks` adds the phrases of its own blocks the same way
75
+ and takes a host's words on its `WebsiteEditor` (`words`, `locale`).
76
+
35
77
  Two checks hold the rule, both in CI and both without an allow-list:
36
78
 
37
79
  - `pnpm run typecheck` — `@/…` points at `src/` and nowhere else, so an import
@@ -1 +1 @@
1
- "use client";import{jsx as l}from"react/jsx-runtime";import{useCallback as i,useEffect as a,useRef as m,useState as f}from"react";import{useEasel as C}from"efficient-easel/easel";import{SettingsAction as d}from"efficient-easel/panel";import{applyCorners as A,applyCornersDoneLabel as S,applyCornersNote as y,planApplyCorners as b}from"../lib/puck/apply-card-corners.js";import{useSectionOps as _}from"../lib/puck/use-section-ops.js";const x=2200,E="apply-corners-to-siblings",L="Apply to all cards";function P({plan:e,doneCount:n,onPress:r}){return l(d,{id:E,label:L,note:y(e),disabled:!e.can,done:n!==null,doneLabel:S(n??0),onPress:r})}function N(){const{appState:e,config:n}=C(u=>u),r=_(),[p,s]=f(null),o=m(null);a(()=>()=>{o.current&&clearTimeout(o.current)},[]);const t=b(n,e.data.content??[],e.ui.itemSelector),c=i(()=>{A(t,r.replaceComponent),t.can&&(s(t.others),o.current&&clearTimeout(o.current),o.current=setTimeout(()=>s(null),x))},[t,r]);return l(P,{plan:t,doneCount:p,onPress:c})}export{x as APPLY_CORNERS_DONE_MS,L as APPLY_CORNERS_LABEL,P as ApplyCornersButton,N as default};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{useCallback as u,useEffect as a,useRef as m,useState as f}from"react";import{useEasel as C}from"efficient-easel/easel";import{SettingsAction as d}from"efficient-easel/panel";import{say as y}from"../lib/editor-words.js";import{applyCorners as A,applyCornersDoneLabel as S,applyCornersNote as b,planApplyCorners as _}from"../lib/puck/apply-card-corners.js";import{useSectionOps as x}from"../lib/puck/use-section-ops.js";const E=2200,L="apply-corners-to-siblings",P="Apply to all cards";function N({plan:e,doneCount:n,onPress:r}){return l(d,{id:L,label:y(P),note:b(e),disabled:!e.can,done:n!==null,doneLabel:S(n??0),onPress:r})}function O(){const{appState:e,config:n}=C(i=>i),r=x(),[p,s]=f(null),o=m(null);a(()=>()=>{o.current&&clearTimeout(o.current)},[]);const t=_(n,e.data.content??[],e.ui.itemSelector),c=u(()=>{A(t,r.replaceComponent),t.can&&(s(t.others),o.current&&clearTimeout(o.current),o.current=setTimeout(()=>s(null),E))},[t,r]);return l(N,{plan:t,doneCount:p,onPress:c})}export{E as APPLY_CORNERS_DONE_MS,P as APPLY_CORNERS_LABEL,N as ApplyCornersButton,O as default};
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import h from"./BlockFrame.js";import f from"./Btn.js";import{media as v}from"../lib/media.js";import g from"./SectionEyebrow.js";import{renderGold as t,renderHeadline as u,splitParagraphs as N}from"./goldPhrases.js";function b({eyebrow:i,title:s,body:l,ctaText:n,ctaHref:d,imageSrc:a,contained:m,overlay:o=60}){const c=Math.min(Math.max(o,0),100)/100;return e(h,{contained:m,className:"py-6",children:r("div",{className:"sf-card relative overflow-hidden border border-line bg-surface px-10 py-16 max-[800px]:px-6 max-[800px]:py-10",children:[a&&r("div",{className:"absolute inset-0","aria-hidden":!0,children:[e("img",{src:v(a),alt:"",className:"h-full w-full object-cover"}),e("div",{className:"absolute inset-0",style:{background:`rgba(0,0,0,${c})`}})]}),r("div",{className:"relative z-[1] flex max-w-[680px] flex-col gap-5",style:a?{color:"var(--overlay-fg)"}:void 0,children:[i&&e(g,{text:i}),s&&e("h2",{className:"font-heading2 text-[length:min(var(--size-headingMedium,44px),var(--sf-heading-max,9999px))] font-medium leading-[1.05] tracking-[-0.03em] max-[800px]:text-[length:min(var(--size-headingMedium,32px),var(--sf-heading-max,9999px))]",children:u(s,!1)}),l&&N(l).map((p,x)=>e("p",{className:"text-[length:var(--size-body,16px)] leading-[1.6] opacity-85",children:t(p)},x)),n&&e("div",{className:"mt-2 self-start",children:e(f,{href:d||"#",variant:"primary",children:t(n)})})]})]})})}export{b as default};
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import h from"./BlockFrame.js";import f from"./Btn.js";import{media as g}from"../lib/media.js";import v from"./SectionEyebrow.js";import{renderGold as t,renderHeadline as u,splitParagraphs as N}from"./goldPhrases.js";import{ON_MEDIA_INK_STYLE as b}from"../lib/content/ink.js";function y({eyebrow:i,title:s,body:n,ctaText:l,ctaHref:m,imageSrc:a,contained:d,overlay:o=60}){const p=Math.min(Math.max(o,0),100)/100;return e(h,{contained:d,className:"py-6",children:r("div",{className:"sf-card relative overflow-hidden border border-line bg-surface px-10 py-16 max-[800px]:px-6 max-[800px]:py-10",children:[a&&r("div",{className:"absolute inset-0","aria-hidden":!0,children:[e("img",{src:g(a),alt:"",className:"h-full w-full object-cover"}),e("div",{className:"absolute inset-0",style:{background:`rgba(0,0,0,${p})`}})]}),r("div",{className:"relative z-[1] flex max-w-[680px] flex-col gap-5",style:a?b:void 0,children:[i&&e(v,{text:i}),s&&e("h2",{className:"font-heading2 text-[length:min(var(--size-headingMedium,44px),var(--sf-heading-max,9999px))] font-medium leading-[1.05] tracking-[-0.03em] max-[800px]:text-[length:min(var(--size-headingMedium,32px),var(--sf-heading-max,9999px))]",children:u(s,!1)}),n&&N(n).map((c,x)=>e("p",{className:"text-[length:var(--size-body,16px)] leading-[1.6] opacity-85",children:t(c)},x)),l&&e("div",{className:"mt-2 self-start",children:e(f,{href:m||"#",variant:"primary",children:t(l)})})]})]})})}export{y as default};
@@ -1 +1 @@
1
- "use client";import{jsx as a}from"react/jsx-runtime";import{SettingsDefaultReset as s,SettingsField as r}from"efficient-easel/panel";import{AlignSeparateIcon as c}from"efficient-easel/icons";import{CONTAINER_GAP_BUILT_IN as d,SITE_BLOCK_GAP as t}from"../lib/content/container-gap.js";import{Slider as p}from"../lib/puck/controls.js";const m="The space between the blocks inside a row, a grid or a box. Default means each one keeps the spacing it already has.",o="Block gap",f=d.Grid;function u({value:n,onChange:i,showHint:l=!0}){const e=n===null;return a(r,{label:o,labelId:"sf-block-gap",icon:a(c,{}),value:e?void 0:`${n}px`,changed:!e,action:a(s,{label:o,changed:!e,detail:"each block's own spacing",onReset:()=>i(null)}),hint:l?m:void 0,children:a(p,{min:t.min,max:t.max,step:t.step,value:e?f:n,readout:!1,ariaLabel:o,onChange:i})})}export{u as default};
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{SettingsDefaultReset as r,SettingsField as c}from"efficient-easel/panel";import{AlignSeparateIcon as d}from"efficient-easel/icons";import{CONTAINER_GAP_BUILT_IN as p,SITE_BLOCK_GAP as o}from"../lib/content/container-gap.js";import{say as e,editorEaselWords as m}from"../lib/editor-words.js";import{Slider as f}from"../lib/puck/controls.js";const u="The space between the blocks inside a row, a grid or a box. Default means each one keeps the spacing it already has.",i="Block gap",_=p.Grid;function g({value:n,onChange:l,showHint:s=!0}){const a=n===null;return t(c,{label:e(i),labelId:"sf-block-gap",icon:t(d,{}),value:a?void 0:`${n}px`,changed:!a,action:t(r,{words:m()?.panel,label:e(i),changed:!a,detail:e("each block's own spacing"),onReset:()=>l(null)}),hint:s?e(u):void 0,children:t(f,{min:o.min,max:o.max,step:o.step,value:a?_:n,readout:!1,ariaLabel:e(i),onChange:l})})}export{g as default};
@@ -1 +1 @@
1
- "use client";import{jsx as t,Fragment as l,jsxs as B}from"react/jsx-runtime";import{useContext as y}from"react";import{SettingsField as c}from"efficient-easel/panel";import{FieldSelect as d}from"efficient-easel/fields";import{BlogPostIcon as g}from"efficient-easel/icons";import{StorefrontDocumentContext as x}from"./StorefrontDocumentContext.js";import{loadStorefrontBlogPosts as L}from"./useStorefrontBlogPosts.js";import{useSnapshotSource as N}from"./useSnapshotSource.js";import P from"./SourceStatus.js";function C(o){if(!o)return"";const e=new Date(o);return Number.isNaN(e.getTime())?"":e.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"2-digit"})}function f(o){return{slug:o.slug,image:o.coverImage,title:o.title,dek:o.excerpt,date:C(o.publishedAt),href:o.href}}function D({value:o,onChange:e}){const r=y(x);return r&&!r.capabilities.hasBlog?o?.slug?t(F,{value:o,onChange:e}):t(l,{}):t(T,{value:o,onChange:e})}function F({value:o,onChange:e}){return t("div",{children:t(c,{label:"Blog post source",icon:t(g,{}),hint:t(l,{children:"Linked to a blog post. This editor has no blog to pick another from; choose “None (manual)” to author the section yourself."}),children:t(d,{value:o.slug,ariaLabel:"Blog post source",onChange:r=>r?void 0:e(null),options:[{label:"None (manual)",value:""},{label:o.title||o.slug,value:o.slug}]})})})}function T({value:o,onChange:e}){const{rows:r,loading:h,refreshing:i,errored:u,refresh:m}=N({load:L,resolve:(n,s)=>n.find(a=>a.slug===s.slug),snapshot:f,value:o,onChange:e}),p=n=>{if(!n){e(null);return}const s=(r??[]).find(a=>a.slug===n);s&&e(f(s))},b=o?.slug&&!(r??[]).some(n=>n.slug===o.slug),S=u?"error":i?"loading":"idle",k=u?"Couldn’t reach Storefront → Blog.":i?"Syncing from Storefront → Blog…":`Linked to “${o?.title||o?.slug||""}”`;return B("div",{children:[t(c,{label:"Blog post source",icon:t(g,{}),hint:o?.slug?void 0:t(l,{children:"Pick a post from Storefront → Blog to auto-fill this section, or keep “None (manual)” to author it yourself below."}),children:t(d,{value:o?.slug??"",ariaLabel:"Blog post source",onChange:p,readOnly:h,options:[{label:"None (manual)",value:""},...b?[{label:`${o.title||o.slug} (unavailable)`,value:o.slug}]:[],...(r??[]).map(n=>({label:n.title,value:n.slug}))]})}),o?.slug?t(P,{status:S,statusText:k,onRefresh:m,busy:i,hint:t(l,{children:"Auto-fills the cover image, headline, dek, date and link from this post each time you open the editor. Those fields are hidden while a post is linked; the remaining fields stay yours to set."})}):null]})}export{D as default};
1
+ "use client";import{jsx as o,Fragment as i,jsxs as B}from"react/jsx-runtime";import{useContext as P}from"react";import{SettingsField as m}from"efficient-easel/panel";import{FieldSelect as g}from"efficient-easel/fields";import{BlogPostIcon as f}from"efficient-easel/icons";import{StorefrontDocumentContext as L}from"./StorefrontDocumentContext.js";import{loadStorefrontBlogPosts as N}from"./useStorefrontBlogPosts.js";import{useSnapshotSource as F}from"./useSnapshotSource.js";import T from"./SourceStatus.js";import{say as t}from"../lib/editor-words.js";function j(e){if(!e)return"";const n=new Date(e);return Number.isNaN(n.getTime())?"":n.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"2-digit"})}function h(e){return{slug:e.slug,image:e.coverImage,title:e.title,dek:e.excerpt,date:j(e.publishedAt),href:e.href}}function w({value:e,onChange:n}){const r=P(L);return r&&!r.capabilities.hasBlog?e?.slug?o(C,{value:e,onChange:n}):o(i,{}):o(D,{value:e,onChange:n})}function C({value:e,onChange:n}){return o("div",{children:o(m,{label:t("Blog post source"),icon:o(f,{}),hint:o(i,{children:t("Linked to a blog post. This editor has no blog to pick another from; choose “None (manual)” to author the section yourself.")}),children:o(g,{value:e.slug,ariaLabel:t("Blog post source"),onChange:r=>r?void 0:n(null),options:[{label:t("None (manual)"),value:""},{label:e.title||e.slug,value:e.slug}]})})})}function D({value:e,onChange:n}){const{rows:r,loading:p,refreshing:a,errored:d,refresh:b}=F({load:N,resolve:(s,l)=>s.find(c=>c.slug===l.slug),snapshot:h,value:e,onChange:n}),k=s=>{if(!s){n(null);return}const l=(r??[]).find(c=>c.slug===s);l&&n(h(l))},S=e?.slug&&!(r??[]).some(s=>s.slug===e.slug),y=d?"error":a?"loading":"idle",u=t("Storefront → Blog"),x=d?t("Couldn’t reach {place}.",{place:u}):a?t("Syncing from {place}…",{place:u}):t("Linked to “{name}”",{name:e?.title||e?.slug||""});return B("div",{children:[o(m,{label:t("Blog post source"),icon:o(f,{}),hint:e?.slug?void 0:o(i,{children:t("Pick a post from {place} to auto-fill this section, or keep “None (manual)” to author it yourself below.",{place:u})}),children:o(g,{value:e?.slug??"",ariaLabel:t("Blog post source"),onChange:k,readOnly:p,options:[{label:t("None (manual)"),value:""},...S?[{label:t("{name} (unavailable)",{name:e.title||e.slug}),value:e.slug}]:[],...(r??[]).map(s=>({label:s.title,value:s.slug}))]})}),e?.slug?o(T,{status:y,statusText:x,onRefresh:b,busy:a,hint:o(i,{children:t("Auto-fills the cover image, headline, dek, date and link from this post each time you open the editor. Those fields are hidden while a post is linked; the remaining fields stay yours to set.")})}):null]})}export{w as default};
@@ -1 +1 @@
1
- import{jsx as r,jsxs as s,Fragment as c}from"react/jsx-runtime";import{Fragment as f}from"react";import{SiteLink as x}from"../lib/site-runtime.js";import{renderChrome as m,renderGold as d}from"./goldPhrases.js";function h({items:p,meta:n,editing:o=!1}){const l=(p??[]).filter(e=>e?.label?.trim()),t=l.length>0?l:o?[{label:"Breadcrumb"}]:[];return t.length===0&&!n?null:s("nav",{className:"flex items-center gap-4 border-b border-line px-[var(--sf-site-gutter,40px)] py-6 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.2em] text-fg-dim max-[720px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[720px]:py-4",children:[t.map((e,a)=>{const i=a===t.length-1;return s(f,{children:[a>0&&r("span",{className:"opacity-40",children:"/"}),e.href&&!i?r(x,{href:e.href,className:"hover:text-fg",children:m(e.label)}):r("span",{className:i?"text-fg":void 0,children:m(e.label)})]},a)}),n&&s(c,{children:[r("span",{className:"opacity-40",children:"·"}),r("span",{children:d(n)})]})]})}export{h as default};
1
+ import{jsx as r,jsxs as s,Fragment as c}from"react/jsx-runtime";import{Fragment as f}from"react";import{SiteLink as x}from"../lib/site-runtime.js";import{renderChrome as m,renderGold as d}from"./goldPhrases.js";import{say as h}from"../lib/editor-words.js";function g({items:o,meta:t,editing:p=!1}){const l=(o??[]).filter(e=>e?.label?.trim()),a=l.length>0?l:p?[{label:h("Breadcrumb")}]:[];return a.length===0&&!t?null:s("nav",{className:"flex items-center gap-4 border-b border-line px-[var(--sf-site-gutter,40px)] py-6 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.2em] text-fg-dim max-[720px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[720px]:py-4",children:[a.map((e,n)=>{const i=n===a.length-1;return s(f,{children:[n>0&&r("span",{className:"opacity-40",children:"/"}),e.href&&!i?r(x,{href:e.href,className:"hover:text-fg",children:m(e.label)}):r("span",{className:i?"text-fg":void 0,children:m(e.label)})]},n)}),t&&s(c,{children:[r("span",{className:"opacity-40",children:"·"}),r("span",{children:d(t)})]})]})}export{g as default};
@@ -1 +1 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import{SettingsDefaultReset as r,SettingsField as c,SettingsSegmented as p}from"efficient-easel/panel";import{ShadowIcon as f}from"efficient-easel/icons";import{CARD_SHADOWS as x,DEFAULT_CARD_SHADOW as i}from"../lib/theme.js";const n={none:"None",soft:"Soft",lifted:"Lifted"},h="Applies to cards — products, brands, journal entries and filter cells. Round things like swatches and status dots are never shadowed.",u={none:"none",soft:"0 1px 1px rgba(20, 20, 22, 0.10), 0 2px 4px -1px rgba(20, 20, 22, 0.14)",lifted:"0 1px 2px rgba(20, 20, 22, 0.10), 0 4px 7px -2px rgba(20, 20, 22, 0.30)"},S={labelsPx:90.25,widestLabelPx:34.6};function b({value:a,onChange:o,showHint:l=!0}){const s=a===null,d=a??i;return e(c,{label:"Card shadow",icon:e(f,{}),value:n[d],changed:!s,action:e(r,{label:"Card shadow",changed:!s,detail:n[i],onReset:()=>o(null)}),hint:l?h:void 0,children:e(p,{options:x.map(t=>({id:t,label:n[t],icon:e("span",{className:"sf-shadow-chip",style:{boxShadow:u[t]}})})),value:d,ariaLabel:"Card shadow",fit:S,onChange:o})})}export{b as default};
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{SettingsDefaultReset as p,SettingsField as c,SettingsSegmented as f}from"efficient-easel/panel";import{ShadowIcon as x}from"efficient-easel/icons";import{say as e,editorEaselWords as h}from"../lib/editor-words.js";import{CARD_SHADOWS as u,DEFAULT_CARD_SHADOW as r}from"../lib/theme.js";const a={none:"None",soft:"Soft",lifted:"Lifted"},S="Applies to cards — products, brands, journal entries and filter cells. Round things like swatches and status dots are never shadowed.",m={none:"none",soft:"0 1px 1px rgba(20, 20, 22, 0.10), 0 2px 4px -1px rgba(20, 20, 22, 0.14)",lifted:"0 1px 2px rgba(20, 20, 22, 0.10), 0 4px 7px -2px rgba(20, 20, 22, 0.30)"},b={labelsPx:90.25,widestLabelPx:34.6};function A({value:n,onChange:s,showHint:l=!0}){const d=n===null,i=n??r;return t(c,{label:e("Card shadow"),icon:t(x,{}),value:e(a[i]),changed:!d,action:t(p,{words:h()?.panel,label:e("Card shadow"),changed:!d,detail:e(a[r]),onReset:()=>s(null)}),hint:l?e(S):void 0,children:t(f,{options:u.map(o=>({id:o,label:e(a[o]),icon:t("span",{className:"sf-shadow-chip",style:{boxShadow:m[o]}})})),value:i,ariaLabel:e("Card shadow"),fit:b,onChange:s})})}export{A as default};
@@ -1 +1 @@
1
- import{jsx as r,jsxs as n}from"react/jsx-runtime";import{SiteLink as g}from"../lib/site-runtime.js";import{renderChrome as l}from"./goldPhrases.js";import{STICKY_UNDERHEADER_CLASS as u}from"../lib/puck/header-clearance.js";function v({tabs:m,activeTab:o,links:d,sticky:b=!0,editing:h=!1}){const i=(m??[]).filter(e=>e?.label?.trim()),a=i.length>0?i:h?[{label:"Tab"}]:[],s=(d??[]).filter(e=>e?.label?.trim());if(a.length===0&&s.length===0)return null;const c=o?a.findIndex(e=>e.label.toLowerCase()===o.toLowerCase()):-1,f=c===-1?0:c;return r("nav",{className:`${b?`${u} sticky top-[var(--sf-header-h,88px)] z-40 `:""}border-b border-line px-[var(--sf-site-gutter,40px)] backdrop-blur-md max-[1100px]:px-[min(16px,var(--sf-site-gutter,40px))]`,style:{background:"color-mix(in oklab, var(--bg) 92%, transparent)"},children:n("div",{className:"mx-auto flex max-w-[calc(var(--sf-site-width,1600px)_-_var(--sf-site-gutter,40px)*2)] items-stretch gap-0 overflow-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:[a.map((e,t)=>{const p=t===f,x=e.count?.trim()?e.count:"";return n("span",{className:["relative whitespace-nowrap border-r border-line px-[22px] py-[18px] font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.22em] transition-colors",t===0?"border-l border-line":"",p?"text-fg":"text-fg-dim hover:text-fg"].join(" "),children:[l(e.label),x&&r("span",{className:"ml-2 text-[length:var(--size-body,12px)] text-accent opacity-70",children:l(x)}),p&&r("span",{className:"absolute inset-x-0 -bottom-px h-[2px] bg-accent"})]},t)}),s.length>0&&r("div",{className:"ml-auto flex border-l border-line",children:s.map((e,t)=>n(g,{href:e.href||"#",className:"flex items-center gap-2.5 px-[22px] py-[18px] font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.22em] text-fg-dim hover:text-fg",children:[l(e.label)," ",r("span",{className:"text-accent",children:"↗"})]},t))})]})})}export{v as default};
1
+ import{jsx as r,jsxs as n}from"react/jsx-runtime";import{SiteLink as g}from"../lib/site-runtime.js";import{renderChrome as o}from"./goldPhrases.js";import{STICKY_UNDERHEADER_CLASS as u}from"../lib/puck/header-clearance.js";import{say as v}from"../lib/editor-words.js";function k({tabs:m,activeTab:l,links:d,sticky:b=!0,editing:f=!1}){const i=(m??[]).filter(e=>e?.label?.trim()),a=i.length>0?i:f?[{label:v("Tab")}]:[],s=(d??[]).filter(e=>e?.label?.trim());if(a.length===0&&s.length===0)return null;const c=l?a.findIndex(e=>e.label.toLowerCase()===l.toLowerCase()):-1,h=c===-1?0:c;return r("nav",{className:`${b?`${u} sticky top-[var(--sf-header-h,88px)] z-40 `:""}border-b border-line px-[var(--sf-site-gutter,40px)] backdrop-blur-md max-[1100px]:px-[min(16px,var(--sf-site-gutter,40px))]`,style:{background:"color-mix(in oklab, var(--bg) 92%, transparent)"},children:n("div",{className:"mx-auto flex max-w-[calc(var(--sf-site-width,1600px)_-_var(--sf-site-gutter,40px)*2)] items-stretch gap-0 overflow-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:[a.map((e,t)=>{const p=t===h,x=e.count?.trim()?e.count:"";return n("span",{className:["relative whitespace-nowrap border-r border-line px-[22px] py-[18px] font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.22em] transition-colors",t===0?"border-l border-line":"",p?"text-fg":"text-fg-dim hover:text-fg"].join(" "),children:[o(e.label),x&&r("span",{className:"ml-2 text-[length:var(--size-body,12px)] text-accent opacity-70",children:o(x)}),p&&r("span",{className:"absolute inset-x-0 -bottom-px h-[2px] bg-accent"})]},t)}),s.length>0&&r("div",{className:"ml-auto flex border-l border-line",children:s.map((e,t)=>n(g,{href:e.href||"#",className:"flex items-center gap-2.5 px-[22px] py-[18px] font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.22em] text-fg-dim hover:text-fg",children:[o(e.label)," ",r("span",{className:"text-accent",children:"↗"})]},t))})]})})}export{k as default};
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as b,jsxs as d}from"react/jsx-runtime";import{useEffect as m,useId as f,useState as g}from"react";import{usePreviewChat as p}from"./PreviewChatContext.js";import{SettingsField as u,SettingsSwitch as w}from"efficient-easel/panel";import{EyeIcon as C,TypeIcon as E}from"efficient-easel/icons";import{GroupLabel as L}from"../lib/puck/controls.js";const y="Chat with us",T="We usually reply within a few minutes",v="Hi! Ask us anything — about a wheel, an order, or fitment. Leave your details and we’ll reply.";function s({label:t,value:a,placeholder:i,onCommit:l,multiline:c=!1}){const[o,r]=g(a);m(()=>r(a),[a]);const h=()=>{o!==a&&l(o)};return e(u,{label:t,icon:e(E,{}),children:c?e("textarea",{value:o,placeholder:i,rows:3,onChange:n=>r(n.target.value),onBlur:h,"aria-label":t}):e("input",{type:"text",value:o,placeholder:i,onChange:n=>r(n.target.value),onBlur:h,onKeyDown:n=>{n.key==="Enter"&&n.currentTarget.blur()},"aria-label":t,autoComplete:"off"})})}function x(){const{chat:t,setChat:a}=p(),i=f();return d(b,{children:[e(u,{label:"Show the chat bubble",labelId:i,icon:e(C,{}),action:e(w,{checked:t.enabled,onChange:l=>a({enabled:l}),ariaLabelledBy:i}),hint:t.enabled?"The floating chat bubble shows in the corner of every page.":"The chat bubble is hidden across the whole site."}),e(L,{label:"Wording"}),e(s,{label:"Title",value:t.title,placeholder:y,onCommit:l=>a({title:l})}),e(s,{label:"Subtitle",value:t.subtitle,placeholder:T,onCommit:l=>a({subtitle:l})}),e(s,{label:"Greeting message",value:t.greeting,placeholder:v,onCommit:l=>a({greeting:l}),multiline:!0}),e("p",{className:"es-field-hint sf-hint-keep",children:"Leave a field blank to use the built-in wording."})]})}export{x as default};
1
+ "use client";import{jsx as e,Fragment as b,jsxs as d}from"react/jsx-runtime";import{useEffect as f,useId as g,useState as p}from"react";import{usePreviewChat as w}from"./PreviewChatContext.js";import{SettingsField as c,SettingsSwitch as C}from"efficient-easel/panel";import{EyeIcon as y,TypeIcon as E}from"efficient-easel/icons";import{GroupLabel as L}from"../lib/puck/controls.js";import{say as n}from"../lib/editor-words.js";const T="Chat with us",v="We usually reply within a few minutes",x="Hi! Ask us anything — about a wheel, an order, or fitment. Leave your details and we’ll reply.";function h({label:t,value:a,placeholder:i,onCommit:l,multiline:m=!1}){const[r,s]=p(a);f(()=>s(a),[a]);const u=()=>{r!==a&&l(r)};return e(c,{label:t,icon:e(E,{}),children:m?e("textarea",{value:r,placeholder:i,rows:3,onChange:o=>s(o.target.value),onBlur:u,"aria-label":t}):e("input",{type:"text",value:r,placeholder:i,onChange:o=>s(o.target.value),onBlur:u,onKeyDown:o=>{o.key==="Enter"&&o.currentTarget.blur()},"aria-label":t,autoComplete:"off"})})}function I(){const{chat:t,setChat:a}=w(),i=g();return d(b,{children:[e(c,{label:n("Show the chat bubble"),labelId:i,icon:e(y,{}),action:e(C,{checked:t.enabled,onChange:l=>a({enabled:l}),ariaLabelledBy:i}),hint:t.enabled?n("The floating chat bubble shows in the corner of every page."):n("The chat bubble is hidden across the whole site.")}),e(L,{label:"Wording"}),e(h,{label:n("Title"),value:t.title,placeholder:T,onCommit:l=>a({title:l})}),e(h,{label:n("Subtitle"),value:t.subtitle,placeholder:v,onCommit:l=>a({subtitle:l})}),e(h,{label:n("Greeting message"),value:t.greeting,placeholder:x,onCommit:l=>a({greeting:l}),multiline:!0}),e("p",{className:"es-field-hint sf-hint-keep",children:n("Leave a field blank to use the built-in wording.")})]})}export{I as default};
@@ -1 +1 @@
1
- "use client";import{jsxs as r,jsx as o,Fragment as a}from"react/jsx-runtime";import{Button as t,Dialog as i}from"efficient-shell/ui";function l(e){return e===1?"1 color theme":`${e} color themes`}function m({count:e,onCancel:s,onConfirm:n}){return r(i,{open:!0,onClose:s,role:"alertdialog",size:"sm",title:"Clear this site’s colors?",footer:r(a,{children:[o(t,{variant:"secondary",onClick:s,children:"Cancel"}),o(t,{variant:"danger",onClick:n,children:"Clear colors"})]}),children:[r("p",{children:["This site has ",l(e)," of its own. Clearing takes them away and puts back the four the shop supplies."]}),o("p",{className:"mt-2 font-medium",children:"This cannot be undone."})]})}export{m as ClearColoursDialog};
1
+ "use client";import{jsx as e,Fragment as i,jsxs as n}from"react/jsx-runtime";import{Button as r,Dialog as l}from"efficient-shell/ui";import{say as s,sayCount as h}from"../lib/editor-words.js";function c(t){return h("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 themes of its own. Clearing takes them away and puts back the four the shop supplies.",t)}function d({count:t,onCancel:o,onConfirm:a}){return n(l,{open:!0,onClose:o,role:"alertdialog",size:"sm",title:s("Clear this site’s colors?"),footer:n(i,{children:[e(r,{variant:"secondary",onClick:o,children:s("Cancel")}),e(r,{variant:"danger",onClick:a,children:s("Clear colors")})]}),children:[e("p",{children:c(t)}),e("p",{className:"mt-2 font-medium",children:s("This cannot be undone.")})]})}export{d as ClearColoursDialog};
@@ -1 +1 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import{SettingsDefaultReset as a,SettingsField as l}from"efficient-easel/panel";import{SquareIcon as u}from"efficient-easel/icons";import{CORNER_RADIUS_MAX as d,CORNER_RADIUS_MIN as r}from"../lib/theme.js";import{Slider as c}from"../lib/puck/controls.js";const p="Applies to panels, cards, inputs and buttons. Round things — color swatches, switches, status dots — stay round.",o="Corners";function R({value:t,onChange:s,showHint:i=!0}){const n=t===null;return e(l,{label:o,icon:e(u,{}),value:n?void 0:`${t}px`,changed:!n,action:e(a,{label:o,changed:!n,detail:"the built-in corners",onReset:()=>s(null)}),hint:i?p:void 0,children:e(c,{min:r,max:d,step:1,value:t??r,readout:!1,ariaLabel:o,onChange:s})})}export{o as CORNERS_LABEL,R as default};
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{SettingsDefaultReset as l,SettingsField as d}from"efficient-easel/panel";import{SquareIcon as u}from"efficient-easel/icons";import{CORNER_RADIUS_MAX as c,CORNER_RADIUS_MIN as i}from"../lib/theme.js";import{say as e,editorEaselWords as p}from"../lib/editor-words.js";import{Slider as m}from"../lib/puck/controls.js";const R="Applies to panels, cards, inputs and buttons. Round things — color swatches, switches, status dots — stay round.",s="Corners";function f({value:n,onChange:r,showHint:a=!0}){const o=n===null;return t(d,{label:e(s),icon:t(u,{}),value:o?void 0:`${n}px`,changed:!o,action:t(l,{words:p()?.panel,label:e(s),changed:!o,detail:e("the built-in corners"),onReset:()=>r(null)}),hint:a?e(R):void 0,children:t(m,{min:i,max:c,step:1,value:n??i,readout:!1,ariaLabel:e(s),onChange:r})})}export{s as CORNERS_LABEL,f as default};
@@ -1,7 +1,7 @@
1
- import{jsx as r,jsxs as m}from"react/jsx-runtime";import{renderGold as c}from"./goldPhrases.js";import{storefrontLines as b}from"../lib/markup.js";function u(i,l){return i.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||`section-${l+1}`}function y(i){const l=[];for(const p of i.replace(/\r\n?/g,`
2
- `).split(/\n[ \t]*\n/))p.split(`
3
- `).map(a=>a.replace(/\s+$/,"")).filter(a=>a.trim()!=="").forEach((a,d)=>{const x=b(a)[0].bullet,n=l.at(-1),e=d===0||!n||n.type==="ul"!==x;if(x){const t=a.slice(2);!e&&n?.type==="ul"?n.items.push(t):l.push({type:"ul",items:[t]})}else!e&&n?.type==="p"?n.text+=`
4
- ${a}`:l.push({type:"p",text:a})});return l}const v=[{label:"First section",heading:"Your *first* section.",body:`Write the opening paragraph here.
1
+ import{jsx as r,jsxs as f}from"react/jsx-runtime";import{renderGold as c}from"./goldPhrases.js";import{storefrontLines as u}from"../lib/markup.js";import{say as p}from"../lib/editor-words.js";function y(o,s){return o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||`section-${s+1}`}function v(o){const s=[];for(const d of o.replace(/\r\n?/g,`
2
+ `).split(/\n[ \t]*\n/))d.split(`
3
+ `).map(a=>a.replace(/\s+$/,"")).filter(a=>a.trim()!=="").forEach((a,x)=>{const m=u(a)[0].bullet,n=s.at(-1),e=x===0||!n||n.type==="ul"!==m;if(m){const t=a.slice(2);!e&&n?.type==="ul"?n.items.push(t):s.push({type:"ul",items:[t]})}else!e&&n?.type==="p"?n.text+=`
4
+ ${a}`:s.push({type:"p",text:a})});return s}const w=()=>[{label:p("First section"),heading:p("Your *first* section."),body:p(`Write the opening paragraph here.
5
5
 
6
6
  - Start a line with a dash for a bullet.
7
- - Add as many as you like.`},{label:"Second section",heading:"Your *second* section.",body:"Leave a blank line between paragraphs to start a new one."}],w=120;function N({tocTitle:i,sections:l,editing:p=!1,stickyTop:f=w}){const a=(l??[]).filter(e=>(e.heading??"").trim()!==""||(e.label??"").trim()!==""||(e.body??"").trim()!=="");if(a.length===0&&!p)return null;const d=a.length===0&&p?v:a,x=new Set,n=d.map((e,t)=>{const o=u(e.label||e.heading||"",t);let s=o,g=2;for(;x.has(s);)s=`${o}-${g++}`;return x.add(s),s});return r("section",{className:"relative z-[2] bg-bg",children:m("div",{className:"mx-auto grid max-w-[var(--sf-site-width,1600px)] grid-cols-[240px_1fr] items-start gap-20 border-b border-line px-[var(--sf-site-gutter,40px)] py-20 max-[900px]:grid-cols-1 max-[900px]:gap-10 max-[900px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[900px]:py-[60px]",children:[m("aside",{className:"sticky flex flex-col self-start max-[900px]:static",style:{top:f},children:[i&&r("h4",{className:"mb-[18px] font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.3em] text-accent",children:c(i)}),d.map((e,t)=>m("a",{href:`#${n[t]}`,className:`flex items-center justify-between gap-3 border-b border-line py-2.5 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.18em] text-fg-dim transition-colors hover:text-fg${t===0?" border-t":""}`,children:[r("span",{children:c(e.label||"Section")}),r("span",{className:"text-accent",children:String(t+1).padStart(2,"0")})]},n[t]))]}),r("div",{className:"flex flex-col gap-16",children:d.map((e,t)=>m("article",{id:n[t],className:"flex flex-col gap-[18px]",style:{scrollMarginTop:f},children:[m("span",{className:"font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.3em] text-accent",children:[String(t+1).padStart(2,"0")," · ",c(e.label||"Section")]}),e.heading&&r("h2",{className:"mb-2 border-b border-line pb-[18px] font-heading2 text-[length:min(var(--size-headingMedium,clamp(28px,3.5vw,44px)),var(--sf-heading-max,9999px))] font-medium uppercase leading-[1.04] tracking-[-0.025em]",children:c(e.heading)}),y(e.body??"").map((o,s)=>o.type==="ul"?r("ul",{className:"flex max-w-[680px] list-none flex-col gap-2.5 pl-0",children:o.items.map((g,h)=>r("li",{className:"relative pl-6 font-serif text-[length:var(--size-body,17px)] leading-[1.65] text-fg-dim before:absolute before:-top-0.5 before:left-1.5 before:text-[length:var(--size-body,24px)] before:leading-none before:text-accent before:content-['·']",children:c(g)},h))},s):r("p",{className:"max-w-[680px] font-serif text-[length:var(--size-body,17px)] leading-[1.7] text-fg-dim",children:c(o.text)},s))]},n[t]))})]})})}export{N as default,u as sectionAnchorId};
7
+ - Add as many as you like.`)},{label:p("Second section"),heading:p("Your *second* section."),body:p("Leave a blank line between paragraphs to start a new one.")}],N=120;function S({tocTitle:o,sections:s,editing:d=!1,stickyTop:g=N}){const a=(s??[]).filter(e=>(e.heading??"").trim()!==""||(e.label??"").trim()!==""||(e.body??"").trim()!=="");if(a.length===0&&!d)return null;const x=a.length===0&&d?w():a,m=new Set,n=x.map((e,t)=>{const i=y(e.label||e.heading||"",t);let l=i,h=2;for(;m.has(l);)l=`${i}-${h++}`;return m.add(l),l});return r("section",{className:"relative z-[2] bg-bg",children:f("div",{className:"mx-auto grid max-w-[var(--sf-site-width,1600px)] grid-cols-[240px_1fr] items-start gap-20 border-b border-line px-[var(--sf-site-gutter,40px)] py-20 max-[900px]:grid-cols-1 max-[900px]:gap-10 max-[900px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[900px]:py-[60px]",children:[f("aside",{className:"sticky flex flex-col self-start max-[900px]:static",style:{top:g},children:[o&&r("h4",{className:"mb-[18px] font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.3em] text-accent",children:c(o)}),x.map((e,t)=>f("a",{href:`#${n[t]}`,className:`flex items-center justify-between gap-3 border-b border-line py-2.5 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.18em] text-fg-dim transition-colors hover:text-fg${t===0?" border-t":""}`,children:[r("span",{children:c(e.label||"Section")}),r("span",{className:"text-accent",children:String(t+1).padStart(2,"0")})]},n[t]))]}),r("div",{className:"flex flex-col gap-16",children:x.map((e,t)=>f("article",{id:n[t],className:"flex flex-col gap-[18px]",style:{scrollMarginTop:g},children:[f("span",{className:"font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.3em] text-accent",children:[String(t+1).padStart(2,"0")," · ",c(e.label||"Section")]}),e.heading&&r("h2",{className:"mb-2 border-b border-line pb-[18px] font-heading2 text-[length:min(var(--size-headingMedium,clamp(28px,3.5vw,44px)),var(--sf-heading-max,9999px))] font-medium uppercase leading-[1.04] tracking-[-0.025em]",children:c(e.heading)}),v(e.body??"").map((i,l)=>i.type==="ul"?r("ul",{className:"flex max-w-[680px] list-none flex-col gap-2.5 pl-0",children:i.items.map((h,b)=>r("li",{className:"relative pl-6 font-serif text-[length:var(--size-body,17px)] leading-[1.65] text-fg-dim before:absolute before:-top-0.5 before:left-1.5 before:text-[length:var(--size-body,24px)] before:leading-none before:text-accent before:content-['·']",children:c(h)},b))},l):r("p",{className:"max-w-[680px] font-serif text-[length:var(--size-body,17px)] leading-[1.7] text-fg-dim",children:c(i.text)},l))]},n[t]))})]})})}export{S as default,y as sectionAnchorId};
@@ -1 +1 @@
1
- "use client";import{jsx as t,jsxs as f,Fragment as _}from"react/jsx-runtime";import{useCallback as A,useRef as L,useState as o}from"react";import{InspectorIconButton as z}from"efficient-easel/chrome";import{PopupMenu as W,PopupMenuItem as $,PopupMenuLabel as l}from"efficient-shell/ui";import{CopyToPageIcon as H}from"efficient-easel/icons";import{backendOf as E}from"../lib/website-session.js";import{useEditorSession as Y}from"../lib/editor-session-context.js";import{cloneNodeWithFreshIds as q}from"../lib/puck/section-doc.js";import{FOOTER_TYPE as G}from"../lib/puck/content-tree.js";function J({node:M,currentSlug:N,siteId:a,tokenRef:g,runAuthed:T,onNotify:D}){const[i,s]=o(!1),[h,y]=o(null),n=Y(),[I,c]=o(!1),[u,x]=o(null),b=L(null),[d,j]=o(null),B=A(async()=>{if(n.usesBridgedToken&&!g.current){c(!0);return}try{y(await E(n).pages.list(a?{siteId:a}:void 0))}catch{c(!0)}},[g,a,n]),F=()=>{if(i){s(!1);return}const e=b.current?.getBoundingClientRect();e&&j({top:e.bottom+6,right:Math.max(8,window.innerWidth-e.right)}),y(null),c(!1),B(),s(!0)},P=(h??[]).filter(e=>e.slug!==N),O=async e=>{if(u)return;x(e.slug);const k=q(M),R=n.documentHooks?.storedNode?.(k)??k,w=E(n).pages,C=await T(async()=>{const p=await w.load({id:e.id});if(!p)throw new Error(`Page "${e.slug}" no longer exists.`);const m=p.layout??{},r=Array.isArray(m.content)?[...m.content]:[],v=r.findIndex(S=>S?.type===G);r.splice(v===-1?r.length:v,0,R),await w.save(e.id,{layout:{root:{},zones:{},...m,content:r}},{version:p.version,clientId:""})});x(null),s(!1),D?.(C?`Duplicated to “${e.label}”`:"Couldn’t duplicate the section — please retry",C?"success":"error")};return f(_,{children:[t("span",{"data-menu-toggle":!0,style:{display:"contents"},children:t(z,{buttonRef:b,label:"Duplicate to another page",hasPopup:"menu",expanded:i,onClick:F,children:t(H,{size:15})})}),i&&d&&t(W,{portal:!0,style:{top:d.top,right:d.right},onClose:()=>s(!1),children:f("div",{role:"menu","aria-label":"Duplicate to page",children:[t(l,{children:"Duplicate to page…"}),I?t(l,{children:"Couldn’t load pages"}):h===null?t(l,{children:"Loading…"}):P.length===0?t(l,{children:"No other pages"}):P.map(e=>f($,{role:"menuitem",disabled:u!==null,onClick:()=>{O(e)},children:[t("span",{className:"min-w-0 flex-1 truncate",children:e.label}),u===e.slug?t("span",{className:"shrink-0 text-xs",children:"Copying…"}):e.draft&&t("span",{className:"shrink-0 text-xs",children:"draft"})]},e.id))]})})]})}export{J as default};
1
+ "use client";import{jsx as t,jsxs as g,Fragment as A}from"react/jsx-runtime";import{useCallback as L,useRef as z,useState as s}from"react";import{InspectorIconButton as W}from"efficient-easel/chrome";import{PopupMenu as H,PopupMenuItem as Y,PopupMenuLabel as a}from"efficient-shell/ui";import{CopyToPageIcon as $}from"efficient-easel/icons";import{backendOf as M}from"../lib/website-session.js";import{useEditorSession as q}from"../lib/editor-session-context.js";import{say as n}from"../lib/editor-words.js";import{cloneNodeWithFreshIds as G}from"../lib/puck/section-doc.js";import{FOOTER_TYPE as J}from"../lib/puck/content-tree.js";function K({node:N,currentSlug:T,siteId:i,tokenRef:h,runAuthed:D,onNotify:I}){const[c,r]=s(!1),[y,x]=s(null),o=q(),[j,u]=s(!1),[d,b]=s(null),P=z(null),[p,B]=s(null),F=L(async()=>{if(o.usesBridgedToken&&!h.current){u(!0);return}try{x(await M(o).pages.list(i?{siteId:i}:void 0))}catch{u(!0)}},[h,i,o]),O=()=>{if(c){r(!1);return}const e=P.current?.getBoundingClientRect();e&&B({top:e.bottom+6,right:Math.max(8,window.innerWidth-e.right)}),x(null),u(!1),F(),r(!0)},k=(y??[]).filter(e=>e.slug!==T),R=async e=>{if(d)return;b(e.slug);const w=G(N),S=o.documentHooks?.storedNode?.(w)??w,C=M(o).pages,v=await D(async()=>{const m=await C.load({id:e.id});if(!m)throw new Error(`Page "${e.slug}" no longer exists.`);const f=m.layout??{},l=Array.isArray(f.content)?[...f.content]:[],E=l.findIndex(_=>_?.type===J);l.splice(E===-1?l.length:E,0,S),await C.save(e.id,{layout:{root:{},zones:{},...f,content:l}},{version:m.version,clientId:""})});b(null),r(!1),I?.(v?n("Duplicated to “{name}”",{name:e.label}):n("Couldn’t duplicate the section — please retry"),v?"success":"error")};return g(A,{children:[t("span",{"data-menu-toggle":!0,style:{display:"contents"},children:t(W,{buttonRef:P,label:n("Duplicate to another page"),hasPopup:"menu",expanded:c,onClick:O,children:t($,{size:15})})}),c&&p&&t(H,{portal:!0,style:{top:p.top,right:p.right},onClose:()=>r(!1),children:g("div",{role:"menu","aria-label":n("Duplicate to page"),children:[t(a,{children:n("Duplicate to page…")}),j?t(a,{children:n("Couldn’t load pages")}):y===null?t(a,{children:n("Loading…")}):k.length===0?t(a,{children:n("No other pages")}):k.map(e=>g(Y,{role:"menuitem",disabled:d!==null,onClick:()=>{R(e)},children:[t("span",{className:"min-w-0 flex-1 truncate",children:e.label}),d===e.slug?t("span",{className:"shrink-0 text-xs",children:n("Copying…")}):e.draft&&t("span",{className:"shrink-0 text-xs",children:n("draft")})]},e.id))]})})]})}export{K as default};
@@ -1 +1 @@
1
- import{Fragment as q,jsx as e,jsxs as c}from"react/jsx-runtime";import{stripMarkup as v}from"../lib/markup.js";import{renderGold as i,renderHeadline as A}from"./goldPhrases.js";import E from"./SectionHeader.js";import F from"./SectionTextPartBridge.js";import{TEXT_REGION_ATTR as S,regionStyle as R,textRegionPartKey as T}from"../lib/sections/text-regions.js";import{FAQ_REGIONS as z}from"../lib/sections/faq-text-regions.js";import{SIZE_STEP_OF_ROLE as I}from"../lib/fonts.js";function h(t){return v(t).trim()}function m(t,r){return t?{[S]:r}:{}}function x(t,r){const a=t?.[T(r)]?.role;return R(a,z[r],I)}function O({editing:t,nodeId:r,children:a}){return!t||!r?e(q,{children:a}):e(F,{nodeId:r,sectionType:"FAQ",children:a})}const j="relative z-[2] bg-bg px-[var(--sf-site-gutter,40px)] py-[120px] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[800px]:py-[70px]",Q="relative z-[2] bg-bg px-[var(--sf-site-gutter,40px)] pt-0 pb-[120px] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[800px]:pt-0 max-[800px]:pb-[70px]";function k({num:t,title:r,link:a,items:y,defaultOpen:_=!0,editing:s=!1,omitHead:d=!1,nodeId:b,partStyles:o}){const p=(y??[]).filter(n=>(n.question??"").trim()!==""),w=s&&p.length===0;if(p.length===0&&!s)return null;const u=w?[{question:"Add your first question",answer:"Write the answer here."},{question:"Add another question",answer:"Write the answer here."}]:p,f=u.filter(n=>(n.answer??"").trim()!=="").map(n=>({"@type":"Question",name:h(n.question??""),acceptedAnswer:{"@type":"Answer",text:h(n.answer??"")}})),g=!s&&f.length>0?JSON.stringify({"@context":"https://schema.org","@type":"FAQPage",mainEntity:f}).replace(/</g,"\\u003c"):null,N=r?A(r,!0):void 0;return c("section",{className:d?Q:j,children:[e("style",{children:".faq-acc__ico{transition:transform .2s ease}details[open]>summary .faq-acc__ico{transform:rotate(45deg)}"}),g&&e("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:g}}),d?null:e(E,{num:t!==void 0?i(t):void 0,title:N,link:a?{text:i(a.text),href:a.href}:void 0,accent:!0}),e(O,{editing:s,nodeId:b,children:e("div",{children:u.map((n,l)=>c("details",{open:l===0&&_,className:"border-b border-line",children:[c("summary",{className:"flex cursor-pointer list-none items-center gap-6 py-7 [&::-webkit-details-marker]:hidden max-[800px]:gap-4 max-[800px]:py-5",children:[e("span",{className:"font-mono text-[length:var(--size-label,14px)] tracking-[0.2em] text-accent",...m(s,"number"),style:x(o,"number"),children:String(l+1).padStart(2,"0")}),e("span",{className:"flex-1 font-display text-[length:var(--size-body,18px)] font-medium uppercase tracking-[0.02em] text-fg max-[800px]:text-[length:var(--size-body,15px)]",...m(s,"question"),style:x(o,"question"),children:i(n.question??"")}),e("span",{"aria-hidden":!0,className:"faq-acc__ico shrink-0 text-[length:var(--size-body,22px)] leading-none text-fg-dim",children:"+"})]}),n.answer&&e("div",{className:"pb-8 pl-11 pr-8 max-[800px]:pl-0 max-[800px]:pr-0",children:e("p",{className:"max-w-[760px] text-[length:var(--size-body,15px)] leading-[1.7] text-fg-dim",...m(s,"answer"),style:x(o,"answer"),children:i(n.answer)})})]},l))})})]})}export{k as default};
1
+ import{Fragment as v,jsx as e,jsxs as c}from"react/jsx-runtime";import{stripMarkup as A}from"../lib/markup.js";import{renderGold as i,renderHeadline as E}from"./goldPhrases.js";import F from"./SectionHeader.js";import S from"./SectionTextPartBridge.js";import{TEXT_REGION_ATTR as R,regionStyle as T,textRegionPartKey as z}from"../lib/sections/text-regions.js";import{FAQ_REGIONS as I}from"../lib/sections/faq-text-regions.js";import{SIZE_STEP_OF_ROLE as O}from"../lib/fonts.js";import{say as o}from"../lib/editor-words.js";function y(t){return A(t).trim()}function x(t,r){return t?{[R]:r}:{}}function d(t,r){const a=t?.[z(r)]?.role;return T(a,I[r],O)}function j({editing:t,nodeId:r,children:a}){return!t||!r?e(v,{children:a}):e(S,{nodeId:r,sectionType:"FAQ",children:a})}const Q="relative z-[2] bg-bg px-[var(--sf-site-gutter,40px)] py-[120px] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[800px]:py-[70px]",k="relative z-[2] bg-bg px-[var(--sf-site-gutter,40px)] pt-0 pb-[120px] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[800px]:pt-0 max-[800px]:pb-[70px]";function L({num:t,title:r,link:a,items:_,defaultOpen:b=!0,editing:s=!1,omitHead:u=!1,nodeId:w,partStyles:p}){const l=(_??[]).filter(n=>(n.question??"").trim()!==""),N=s&&l.length===0;if(l.length===0&&!s)return null;const f=N?[{question:o("Add your first question"),answer:o("Write the answer here.")},{question:o("Add another question"),answer:o("Write the answer here.")}]:l,g=f.filter(n=>(n.answer??"").trim()!=="").map(n=>({"@type":"Question",name:y(n.question??""),acceptedAnswer:{"@type":"Answer",text:y(n.answer??"")}})),h=!s&&g.length>0?JSON.stringify({"@context":"https://schema.org","@type":"FAQPage",mainEntity:g}).replace(/</g,"\\u003c"):null,q=r?E(r,!0):void 0;return c("section",{className:u?k:Q,children:[e("style",{children:".faq-acc__ico{transition:transform .2s ease}details[open]>summary .faq-acc__ico{transform:rotate(45deg)}"}),h&&e("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:h}}),u?null:e(F,{num:t!==void 0?i(t):void 0,title:q,link:a?{text:i(a.text),href:a.href}:void 0,accent:!0}),e(j,{editing:s,nodeId:w,children:e("div",{children:f.map((n,m)=>c("details",{open:m===0&&b,className:"border-b border-line",children:[c("summary",{className:"flex cursor-pointer list-none items-center gap-6 py-7 [&::-webkit-details-marker]:hidden max-[800px]:gap-4 max-[800px]:py-5",children:[e("span",{className:"font-mono text-[length:var(--size-label,14px)] tracking-[0.2em] text-accent",...x(s,"number"),style:d(p,"number"),children:String(m+1).padStart(2,"0")}),e("span",{className:"flex-1 font-display text-[length:var(--size-body,18px)] font-medium uppercase tracking-[0.02em] text-fg max-[800px]:text-[length:var(--size-body,15px)]",...x(s,"question"),style:d(p,"question"),children:i(n.question??"")}),e("span",{"aria-hidden":!0,className:"faq-acc__ico shrink-0 text-[length:var(--size-body,22px)] leading-none text-fg-dim",children:"+"})]}),n.answer&&e("div",{className:"pb-8 pl-11 pr-8 max-[800px]:pl-0 max-[800px]:pr-0",children:e("p",{className:"max-w-[760px] text-[length:var(--size-body,15px)] leading-[1.7] text-fg-dim",...x(s,"answer"),style:d(p,"answer"),children:i(n.answer)})})]},m))})})]})}export{L as default};
@@ -1 +1 @@
1
- import{jsx as s,jsxs as X,Fragment as T}from"react/jsx-runtime";import U from"./BoxTabs.js";import q from"./SiteGutterFrame.js";import{BoxSurfaceProvider as J}from"./BoxSurfaceContext.js";import{useInSiteHeader as K}from"./PhoneMenuTools.js";import{FRAME_BASE as Q,FRAME_GUTTER as V}from"./BlockFrame.js";import{containerGapProps as Y}from"../lib/content/container-gap.js";import{boxLayoutClasses as Z,boxBlockSpacingClass as ee,boxPhoneRowClasses as se,boxShareClasses as oe,boxWrapClass as re}from"../lib/content/box-layout.js";import{BOX_CARD_PAD as e,BOX_OWNS_SIDES_CLASS as te,boxDarkenStyle as ae,boxPlacementClasses as ne,CARD_SHADOW_CLASS as le,isBackgroundBox as ie}from"../lib/content/box-background.js";import{sectionPadAttrs as ce}from"../lib/content/section-padding.js";function me({direction:r,label:N,gap:g,justify:v,align:P,wrap:w,share:B,phoneRow:E,blockSpacing:F,bgImage:l,darken:j,darkenStyle:D,placement:H,padTop:i,padBottom:c,padTopPhone:m,padBottomPhone:f,padLeft:u,padRight:d,padLeftPhone:b,padRightPhone:p,contained:O=!0,fillHeight:R=!1,content:z}){const t=ie(l),x=K(),y=[oe(B),ee(F)].filter(Boolean).join(" "),G=y?` ${y}`:"",$=["flex",r==="row"?`flex-row ${se(E)}`:"flex-col",re(w),t?ne(H??"center",r):Z(v,P)].join(" ")+G,o=R||t?" h-full":"",S=t||x?"":" py-6",L=`${Q}${S} ${V}${o}`,W=x?o.trim():`w-full${S}${o}`,a=Y("Flex",g,r==="row"?"inline":"block"),C=s(z,{className:`${$}${a.className}${o}`,style:a.style,minEmptyHeight:120}),h=r==="tabs"?s(U,{className:`${$}${a.className}${o}`,style:a.style,children:C}):C,I=N?.trim()||void 0,_=M=>s(q,{contained:O,framedClass:L,fillClass:W,tabLabel:I,children:M});if(!t)return _(h);const n=ae(j,D),A=ce(typeof i=="number"?i:e.desktop,typeof c=="number"?c:e.desktop,typeof m=="number"?m:e.phone,typeof f=="number"?f:e.phone,typeof u=="number"?u:e.side,typeof d=="number"?d:e.side,typeof b=="number"?b:e.sidePhone,typeof p=="number"?p:e.sidePhone),k=s("div",{className:`relative z-[1] ${te} ${A?.className??""}`.trimEnd(),style:A?.style,children:h});return _(s(T,{children:X("div",{className:`relative isolate overflow-hidden ${le}${o}`,style:{backgroundImage:`url(${l})`,backgroundSize:"cover",backgroundPosition:"center"},children:[n&&s("div",{className:"absolute inset-0 z-0",style:n,"aria-hidden":!0}),n?s(J,{children:k}):k]})}))}export{me as default};
1
+ import{jsx as s,jsxs as T,Fragment as X}from"react/jsx-runtime";import K from"./BoxTabs.js";import U from"./SiteGutterFrame.js";import{BoxSurfaceProvider as Y}from"./BoxSurfaceContext.js";import{useInSiteHeader as q}from"./PhoneMenuTools.js";import{FRAME_BASE as J,FRAME_GUTTER as Q}from"./BlockFrame.js";import{containerGapProps as V}from"../lib/content/container-gap.js";import{boxLayoutClasses as Z,boxBlockSpacingClass as ee,boxPhoneRowClasses as se,boxShareClasses as oe,boxWrapClass as re}from"../lib/content/box-layout.js";import{BOX_CARD_PAD as e,BOX_OWNS_SIDES_CLASS as te,boxDarkenStyle as ae,boxPlacementClasses as ne,CARD_SHADOW_CLASS as le,isBackgroundBox as ie}from"../lib/content/box-background.js";import{sectionPadAttrs as me}from"../lib/content/section-padding.js";import{ON_MEDIA_INK_STYLE as ce}from"../lib/content/ink.js";function fe({direction:r,label:k,gap:E,justify:g,align:v,wrap:P,share:w,phoneRow:B,blockSpacing:D,bgImage:i,darken:F,darkenStyle:j,placement:O,padTop:m,padBottom:c,padTopPhone:f,padBottomPhone:u,padLeft:d,padRight:b,padLeftPhone:p,padRightPhone:y,contained:H=!0,fillHeight:I=!1,content:L}){const t=ie(i),x=q(),S=[oe(w),ee(D)].filter(Boolean).join(" "),R=S?` ${S}`:"",$=["flex",r==="row"?`flex-row ${se(B)}`:"flex-col",re(P),t?ne(O??"center",r):Z(g,v)].join(" ")+R,o=I||t?" h-full":"",C=t||x?"":" py-6",z=`${J}${C} ${Q}${o}`,G=x?o.trim():`w-full${C}${o}`,a=V("Flex",E,r==="row"?"inline":"block"),_=s(L,{className:`${$}${a.className}${o}`,style:a.style,minEmptyHeight:120}),h=r==="tabs"?s(K,{className:`${$}${a.className}${o}`,style:a.style,children:_}):_,M=k?.trim()||void 0,A=W=>s(U,{contained:H,framedClass:z,fillClass:G,tabLabel:M,children:W});if(!t)return A(h);const n=ae(F,j),l=me(typeof m=="number"?m:e.desktop,typeof c=="number"?c:e.desktop,typeof f=="number"?f:e.phone,typeof u=="number"?u:e.phone,typeof d=="number"?d:e.side,typeof b=="number"?b:e.side,typeof p=="number"?p:e.sidePhone,typeof y=="number"?y:e.sidePhone),N=s("div",{className:`relative z-[1] ${te} ${l?.className??""}`.trimEnd(),style:n?{...l?.style,...ce}:l?.style,children:h});return A(s(X,{children:T("div",{className:`relative isolate overflow-hidden ${le}${o}`,style:{backgroundImage:`url(${i})`,backgroundSize:"cover",backgroundPosition:"center"},children:[n&&s("div",{className:"absolute inset-0 z-0",style:n,"aria-hidden":!0}),n?s(Y,{children:N}):N]})}))}export{fe as default};
@@ -1,4 +1,4 @@
1
- "use client";import{jsx as r,Fragment as nt,jsxs as w}from"react/jsx-runtime";import{useEffect as S,useRef as f,useState as P}from"react";import{MAP_PALETTE as Q,mapBackgroundFor as F,mapMarkerColorFor as U,mapPaletteFor as H,mapStylesFor as X,watchMapTheme as rt}from"../lib/map-styles.js";import{hasMapCoords as J,loadGoogleMaps as ot}from"../lib/maps-loader.js";import{resolveMapId as at,resolveMapsKey as st,useSiteMapId as lt,useSiteMapsKey as it}from"../lib/maps-config.js";import{bucketByGroup as ct,groupColsClass as pt}from"../lib/locations-grid.js";import ut from"./EditorialSectionHead.js";import{LocationGroupHeader as dt}from"./LocationGroupHeader.js";import{renderGold as mt,renderHeadline as ft}from"./goldPhrases.js";import gt from"./PartStyledText.js";const xt=11,bt=6,q=60;function G(t){return t.replace(/[&<>"']/g,o=>o==="&"?"&amp;":o==="<"?"&lt;":o===">"?"&gt;":o==='"'?"&quot;":"&#39;")}function V(t,o,u){return{path:o.SymbolPath.CIRCLE,scale:t.hq?xt:bt,fillColor:U(u),fillOpacity:1,strokeColor:U(u),strokeOpacity:t.hq?.3:.25,strokeWeight:t.hq?14:9}}function Y(t,o,u,e,l,M){l.forEach(a=>a.setMap(null)),l.clear();const g=new o.LatLngBounds;return e.forEach((a,x)=>{if(!J(a.lat,a.lng))return;g.extend({lat:a.lat,lng:a.lng});const m=new o.Marker({map:t,position:{lat:a.lat,lng:a.lng},icon:V(a,o,u),title:a.city,zIndex:a.hq?100:10,cursor:"pointer"});m.addListener("click",()=>M(x)),l.set(x,m)}),g}function yt(t){return`
1
+ "use client";import{jsx as r,Fragment as nt,jsxs as w}from"react/jsx-runtime";import{useEffect as S,useRef as f,useState as P}from"react";import{MAP_PALETTE as Q,mapBackgroundFor as F,mapMarkerColorFor as U,mapPaletteFor as H,mapStylesFor as X,watchMapTheme as rt}from"../lib/map-styles.js";import{hasMapCoords as J,loadGoogleMaps as ot}from"../lib/maps-loader.js";import{resolveMapId as at,resolveMapsKey as st,useSiteMapId as lt,useSiteMapsKey as it}from"../lib/maps-config.js";import{bucketByGroup as ct,groupColsClass as pt}from"../lib/locations-grid.js";import ut from"./EditorialSectionHead.js";import{LocationGroupHeader as dt}from"./LocationGroupHeader.js";import{renderGold as mt,renderHeadline as ft}from"./goldPhrases.js";import gt from"./PartStyledText.js";import{say as xt}from"../lib/editor-words.js";const bt=11,yt=6,q=60;function G(t){return t.replace(/[&<>"']/g,o=>o==="&"?"&amp;":o==="<"?"&lt;":o===">"?"&gt;":o==='"'?"&quot;":"&#39;")}function V(t,o,u){return{path:o.SymbolPath.CIRCLE,scale:t.hq?bt:yt,fillColor:U(u),fillOpacity:1,strokeColor:U(u),strokeOpacity:t.hq?.3:.25,strokeWeight:t.hq?14:9}}function Y(t,o,u,e,l,M){l.forEach(a=>a.setMap(null)),l.clear();const g=new o.LatLngBounds;return e.forEach((a,x)=>{if(!J(a.lat,a.lng))return;g.extend({lat:a.lat,lng:a.lng});const m=new o.Marker({map:t,position:{lat:a.lat,lng:a.lng},icon:V(a,o,u),title:a.city,zIndex:a.hq?100:10,cursor:"pointer"});m.addListener("click",()=>M(x)),l.set(x,m)}),g}function vt(t){return`
2
2
  .footprint-map .gm-style { font-family: var(--font-role-label), var(--font-mono-fallback) !important; }
3
3
  .footprint-map .gm-style .gm-style-iw-c {
4
4
  background: ${t.bg} !important;
@@ -16,7 +16,7 @@
16
16
  .footprint-map .gm-style button[aria-label="Close"] > span {
17
17
  background-color: ${t.closeX} !important;
18
18
  }
19
- `}function T({pal:t}){const o=t?t.marker:"var(--accent)",u=t?t.info.bg:"var(--site-surface)",e=t?t.background:"var(--bg)",l=t?`color-mix(in oklab, ${t.info.fgDim} 12%, transparent)`:"color-mix(in oklab, var(--fg) 3%, transparent)";return w(nt,{children:[r("div",{className:"pointer-events-none absolute inset-0",style:{backgroundImage:`radial-gradient(60% 70% at 50% 50%, color-mix(in oklab, ${o} 8%, ${u}) 0%, ${u} 60%, ${e} 100%)`}}),r("div",{className:"pointer-events-none absolute inset-0",style:{backgroundImage:`repeating-linear-gradient(0deg, transparent 0 22px, ${l} 22px 23px), repeating-linear-gradient(90deg, transparent 0 22px, ${l} 22px 23px)`}})]})}function vt({sectionNumber:t="",heading:o="",tagline:u="",offices:e=[],apiKey:l="",mapId:M="",mapTheme:g="auto",padTop:a,padBottom:x,editing:m,omitHead:$=!1}){const L=typeof a=="number"?a:120,z=typeof x=="number"?x:120,[b,h]=P(null),v=e.length===0&&!t&&!o&&!u;if(S(()=>{h(n=>n!==null&&n>=e.length?null:n)},[e]),v&&!m)return null;const N=ct(e,n=>String(n.group??""),()=>"");return r("section",{className:"relative z-[2] bg-bg",children:w("div",{className:"mx-auto max-w-[var(--sf-site-width,1600px)] border-b border-line px-[var(--sf-site-gutter,40px)] max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))]",style:{paddingTop:L,paddingBottom:z},children:[!$&&(t||o||u)&&r(ut,{num:t,title:o?ft(o):void 0,desc:u||void 0,spaceBelow:"mb-12"}),r(ht,{offices:e,apiKey:l,mapId:M,mapTheme:g,activeIndex:b,onSelect:h}),e.length>0&&r("div",{className:"mt-12 flex flex-col gap-8",children:N.map((n,C)=>w("div",{children:[n.key&&r(dt,{groupKey:n.key,count:n.items.length}),r("div",{className:["grid gap-[2px] bg-bg",pt(n.items.length),n.items.length>2?"max-[1100px]:grid-cols-2 max-[700px]:grid-cols-1":n.items.length===2?"max-[700px]:grid-cols-1":""].join(" "),children:n.items.map(({item:i,index:k})=>{const A=b===k;return w("button",{type:"button",onClick:()=>h(k),"aria-pressed":A,className:["flex flex-col gap-1.5 bg-bg px-6 py-5 text-left transition-colors outline outline-1 -outline-offset-1",A?"outline-accent":"outline-transparent hover:outline-line"].join(" "),children:[w("span",{className:"flex items-center gap-2.5 font-mono text-[length:var(--size-label,11px)] uppercase tracking-[0.28em]",children:[i.hq&&r("span",{className:"border border-accent bg-accent px-1.5 py-0.5 text-[length:var(--size-body,10px)] text-bg",children:"HQ"}),i.role&&r("span",{className:"text-accent",children:i.role})]}),i.city&&r("span",{className:"font-display text-[length:var(--size-body,18px)] font-medium leading-[1.2] tracking-[-0.01em] text-fg",children:r(gt,{value:i.city,children:i.city})}),i.country&&r("span",{className:"font-mono text-[length:var(--size-label,11px)] uppercase tracking-[0.2em] text-fg-dim",children:i.country}),i.address&&r("span",{className:"font-mono text-[length:var(--size-label,11px)] uppercase tracking-[0.2em] text-fg-dim",children:mt(i.address)})]},k)})})]},n.key?`g:${n.key}`:`ungrouped:${C}`))}),e.length===0&&m&&r("p",{className:"mt-8 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em] text-fg-dim",children:"Add an office in the inspector"})]})})}function ht({offices:t,apiKey:o,mapId:u,mapTheme:e,activeIndex:l,onSelect:M}){const g=st(o,it()),a=at(u,lt()),x=!!g&&t.some(c=>J(c.lat,c.lng)),m=e!=="auto",$=H(e),L=f(null),z=f(null),b=f(null),h=f(null),v=f(new Map),N=f(null),n=f(null),C=f(null),i=f(M);i.current=M;const k=f(t);k.current=t;const A=f(l);A.current=l;const[_,D]=P(!1),[j,K]=P(Q.dark),[tt,W]=P(Q.dark.background);return S(()=>{K(H(e)),W(F(e))},[e]),S(()=>{if(!x)return;const c=L.current;if(!c)return;let d=!1,p=null;const I=async()=>{try{const s=await ot(g);if(d||!z.current)return;const y=new s.Map(z.current,{center:{lat:25,lng:0},zoom:2,minZoom:1,maxZoom:5,disableDefaultUI:!0,gestureHandling:"cooperative",keyboardShortcuts:!1,clickableIcons:!1,backgroundColor:F(e),...a?{mapId:a}:{styles:X(e)}});b.current=y,h.current=s;const R=Y(y,s,e,k.current,v.current,B=>i.current(B));n.current=R,R.isEmpty()||y.fitBounds(R,q);const O=new s.InfoWindow({disableAutoPan:!0});O.addListener("closeclick",()=>i.current(null)),N.current=O,y.addListener("click",()=>i.current(null)),y.addListener("tilesloaded",()=>{d||D(!0)}),e==="auto"&&!a&&(p=rt(()=>{d||!b.current||(b.current.setOptions({styles:X(e),backgroundColor:F(e)}),v.current.forEach((B,et)=>{const Z=k.current[et];Z&&B.setIcon(V(Z,s,e))}),K(H(e)),W(F(e)))}))}catch(s){console.error("[FootprintMap] Maps SDK failed:",s)}},E=new IntersectionObserver(s=>{for(const y of s)if(y.isIntersecting){E.disconnect(),I();break}},{rootMargin:"200px"});return E.observe(c),()=>{d=!0,E.disconnect(),p?.(),N.current?.close(),N.current=null,b.current=null,h.current=null,v.current.forEach(s=>s.setMap(null)),v.current.clear(),n.current=null,D(!1)}},[x,g,a,e]),S(()=>{const c=b.current,d=h.current;if(!c||!d)return;const p=Y(c,d,e,t,v.current,I=>i.current(I));n.current=p,A.current===null&&!p.isEmpty()&&c.fitBounds(p,q)},[t,e]),S(()=>{const c=b.current,d=N.current;if(!c||!d)return;if(l===null){d.close(),C.current!==null&&n.current&&!n.current.isEmpty()&&c.fitBounds(n.current,q),C.current=null;return}const p=t[l],I=v.current.get(l);if(!p||!I){d.close(),C.current=l;return}c.panTo({lat:p.lat,lng:p.lng});const E=c.getZoom();E!=null&&E<4&&c.setZoom(4);const s=j.info,y=p.hq?`<span style="background:${s.accent};color:${s.bg};padding:1px 6px;font-size:10px;letter-spacing:0.18em;">HQ</span>`:"",R=p.role?`<span style="color:${s.accent};">${G(p.role)}</span>`:"";d.setContent(`
19
+ `}function T({pal:t}){const o=t?t.marker:"var(--accent)",u=t?t.info.bg:"var(--site-surface)",e=t?t.background:"var(--bg)",l=t?`color-mix(in oklab, ${t.info.fgDim} 12%, transparent)`:"color-mix(in oklab, var(--fg) 3%, transparent)";return w(nt,{children:[r("div",{className:"pointer-events-none absolute inset-0",style:{backgroundImage:`radial-gradient(60% 70% at 50% 50%, color-mix(in oklab, ${o} 8%, ${u}) 0%, ${u} 60%, ${e} 100%)`}}),r("div",{className:"pointer-events-none absolute inset-0",style:{backgroundImage:`repeating-linear-gradient(0deg, transparent 0 22px, ${l} 22px 23px), repeating-linear-gradient(90deg, transparent 0 22px, ${l} 22px 23px)`}})]})}function ht({sectionNumber:t="",heading:o="",tagline:u="",offices:e=[],apiKey:l="",mapId:M="",mapTheme:g="auto",padTop:a,padBottom:x,editing:m,omitHead:$=!1}){const L=typeof a=="number"?a:120,z=typeof x=="number"?x:120,[b,h]=P(null),v=e.length===0&&!t&&!o&&!u;if(S(()=>{h(n=>n!==null&&n>=e.length?null:n)},[e]),v&&!m)return null;const N=ct(e,n=>String(n.group??""),()=>"");return r("section",{className:"relative z-[2] bg-bg",children:w("div",{className:"mx-auto max-w-[var(--sf-site-width,1600px)] border-b border-line px-[var(--sf-site-gutter,40px)] max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))]",style:{paddingTop:L,paddingBottom:z},children:[!$&&(t||o||u)&&r(ut,{num:t,title:o?ft(o):void 0,desc:u||void 0,spaceBelow:"mb-12"}),r(kt,{offices:e,apiKey:l,mapId:M,mapTheme:g,activeIndex:b,onSelect:h}),e.length>0&&r("div",{className:"mt-12 flex flex-col gap-8",children:N.map((n,C)=>w("div",{children:[n.key&&r(dt,{groupKey:n.key,count:n.items.length}),r("div",{className:["grid gap-[2px] bg-bg",pt(n.items.length),n.items.length>2?"max-[1100px]:grid-cols-2 max-[700px]:grid-cols-1":n.items.length===2?"max-[700px]:grid-cols-1":""].join(" "),children:n.items.map(({item:i,index:k})=>{const A=b===k;return w("button",{type:"button",onClick:()=>h(k),"aria-pressed":A,className:["flex flex-col gap-1.5 bg-bg px-6 py-5 text-left transition-colors outline outline-1 -outline-offset-1",A?"outline-accent":"outline-transparent hover:outline-line"].join(" "),children:[w("span",{className:"flex items-center gap-2.5 font-mono text-[length:var(--size-label,11px)] uppercase tracking-[0.28em]",children:[i.hq&&r("span",{className:"border border-accent bg-accent px-1.5 py-0.5 text-[length:var(--size-body,10px)] text-bg",children:"HQ"}),i.role&&r("span",{className:"text-accent",children:i.role})]}),i.city&&r("span",{className:"font-display text-[length:var(--size-body,18px)] font-medium leading-[1.2] tracking-[-0.01em] text-fg",children:r(gt,{value:i.city,children:i.city})}),i.country&&r("span",{className:"font-mono text-[length:var(--size-label,11px)] uppercase tracking-[0.2em] text-fg-dim",children:i.country}),i.address&&r("span",{className:"font-mono text-[length:var(--size-label,11px)] uppercase tracking-[0.2em] text-fg-dim",children:mt(i.address)})]},k)})})]},n.key?`g:${n.key}`:`ungrouped:${C}`))}),e.length===0&&m&&r("p",{className:"mt-8 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em] text-fg-dim",children:xt("Add an office in the inspector")})]})})}function kt({offices:t,apiKey:o,mapId:u,mapTheme:e,activeIndex:l,onSelect:M}){const g=st(o,it()),a=at(u,lt()),x=!!g&&t.some(c=>J(c.lat,c.lng)),m=e!=="auto",$=H(e),L=f(null),z=f(null),b=f(null),h=f(null),v=f(new Map),N=f(null),n=f(null),C=f(null),i=f(M);i.current=M;const k=f(t);k.current=t;const A=f(l);A.current=l;const[_,D]=P(!1),[j,K]=P(Q.dark),[tt,W]=P(Q.dark.background);return S(()=>{K(H(e)),W(F(e))},[e]),S(()=>{if(!x)return;const c=L.current;if(!c)return;let d=!1,p=null;const I=async()=>{try{const s=await ot(g);if(d||!z.current)return;const y=new s.Map(z.current,{center:{lat:25,lng:0},zoom:2,minZoom:1,maxZoom:5,disableDefaultUI:!0,gestureHandling:"cooperative",keyboardShortcuts:!1,clickableIcons:!1,backgroundColor:F(e),...a?{mapId:a}:{styles:X(e)}});b.current=y,h.current=s;const R=Y(y,s,e,k.current,v.current,B=>i.current(B));n.current=R,R.isEmpty()||y.fitBounds(R,q);const O=new s.InfoWindow({disableAutoPan:!0});O.addListener("closeclick",()=>i.current(null)),N.current=O,y.addListener("click",()=>i.current(null)),y.addListener("tilesloaded",()=>{d||D(!0)}),e==="auto"&&!a&&(p=rt(()=>{d||!b.current||(b.current.setOptions({styles:X(e),backgroundColor:F(e)}),v.current.forEach((B,et)=>{const Z=k.current[et];Z&&B.setIcon(V(Z,s,e))}),K(H(e)),W(F(e)))}))}catch(s){console.error("[FootprintMap] Maps SDK failed:",s)}},E=new IntersectionObserver(s=>{for(const y of s)if(y.isIntersecting){E.disconnect(),I();break}},{rootMargin:"200px"});return E.observe(c),()=>{d=!0,E.disconnect(),p?.(),N.current?.close(),N.current=null,b.current=null,h.current=null,v.current.forEach(s=>s.setMap(null)),v.current.clear(),n.current=null,D(!1)}},[x,g,a,e]),S(()=>{const c=b.current,d=h.current;if(!c||!d)return;const p=Y(c,d,e,t,v.current,I=>i.current(I));n.current=p,A.current===null&&!p.isEmpty()&&c.fitBounds(p,q)},[t,e]),S(()=>{const c=b.current,d=N.current;if(!c||!d)return;if(l===null){d.close(),C.current!==null&&n.current&&!n.current.isEmpty()&&c.fitBounds(n.current,q),C.current=null;return}const p=t[l],I=v.current.get(l);if(!p||!I){d.close(),C.current=l;return}c.panTo({lat:p.lat,lng:p.lng});const E=c.getZoom();E!=null&&E<4&&c.setZoom(4);const s=j.info,y=p.hq?`<span style="background:${s.accent};color:${s.bg};padding:1px 6px;font-size:10px;letter-spacing:0.18em;">HQ</span>`:"",R=p.role?`<span style="color:${s.accent};">${G(p.role)}</span>`:"";d.setContent(`
20
20
  <div style="padding:10px 14px 12px;min-width:180px;color:${s.fg};">
21
21
  <div style="display:flex;align-items:center;gap:8px;font-family:var(--font-role-label),var(--font-mono-fallback);font-size:11px;letter-spacing:0.28em;text-transform:uppercase;">
22
22
  ${y}${R}
@@ -24,4 +24,4 @@
24
24
  <div style="font-family:var(--font-display),Georgia,serif;font-size:20px;font-weight:500;line-height:1.2;margin-top:6px;color:${s.fg};">${G(p.city)}</div>
25
25
  <div style="font-family:var(--font-role-label),var(--font-mono-fallback);font-size:11px;letter-spacing:0.2em;text-transform:uppercase;color:${s.fgDim};margin-top:4px;">${G(p.country)}</div>
26
26
  </div>
27
- `),d.open({map:c,anchor:I}),C.current=l},[l,_,j,t]),x?w("div",{ref:L,className:"sf-card footprint-map relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",style:{backgroundColor:tt},children:[r("style",{dangerouslySetInnerHTML:{__html:yt(j.info)}}),r(T,{pal:m?$:void 0}),r("div",{ref:z,className:"gmap-canvas absolute inset-0 transition-opacity duration-500",style:{opacity:_?1:0}}),r("div",{className:["pointer-events-none absolute inset-0 flex items-center justify-center font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em] text-fg-dim transition-opacity duration-500",_?"opacity-0":"opacity-100"].join(" "),children:"Loading map…"})]}):w("div",{className:["relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",m?"":"bg-bg"].join(" "),style:m?{backgroundColor:$.background}:void 0,children:[r(T,{pal:m?$:void 0}),r("div",{className:["absolute inset-0 flex items-center justify-center px-6 text-center font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em]",m?"":"text-fg-dim"].join(" "),style:m?{color:$.info.fgDim}:void 0,children:g?"Add office coordinates to plot the map":"Add a Google Maps API key to show the map"})]})}export{vt as default};
27
+ `),d.open({map:c,anchor:I}),C.current=l},[l,_,j,t]),x?w("div",{ref:L,className:"sf-card footprint-map relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",style:{backgroundColor:tt},children:[r("style",{dangerouslySetInnerHTML:{__html:vt(j.info)}}),r(T,{pal:m?$:void 0}),r("div",{ref:z,className:"gmap-canvas absolute inset-0 transition-opacity duration-500",style:{opacity:_?1:0}}),r("div",{className:["pointer-events-none absolute inset-0 flex items-center justify-center font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em] text-fg-dim transition-opacity duration-500",_?"opacity-0":"opacity-100"].join(" "),children:"Loading map…"})]}):w("div",{className:["relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",m?"":"bg-bg"].join(" "),style:m?{backgroundColor:$.background}:void 0,children:[r(T,{pal:m?$:void 0}),r("div",{className:["absolute inset-0 flex items-center justify-center px-6 text-center font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em]",m?"":"text-fg-dim"].join(" "),style:m?{color:$.info.fgDim}:void 0,children:g?"Add office coordinates to plot the map":"Add a Google Maps API key to show the map"})]})}export{ht as default};
@@ -1 +1 @@
1
- "use client";import{jsx as t,jsxs as a}from"react/jsx-runtime";import{useEasel as r}from"efficient-easel/easel";import{headingOutline as o}from"../lib/puck/heading-outline.js";function p(){const{appState:i,config:l}=r(e=>e),c=i?.data,n=o(c?.content??[],l),s=n.filter(e=>e.level===1).length;return a("div",{className:"px-4 py-3 text-[13px] text-zinc-600",children:[a("div",{className:"mb-2 flex items-center justify-between text-[11px] font-semibold uppercase tracking-wide text-zinc-500",children:[t("span",{children:"Heading outline"}),t("span",{children:n.length})]}),s!==1&&t("div",{className:"mb-2 rounded bg-amber-50 px-2 py-1 text-[12px] text-amber-700",children:s===0?"No H1 — add one for SEO.":`${s} H1s — a page should have exactly one.`}),n.length===0?t("p",{className:"text-zinc-400",children:"No headings yet."}):t("ul",{className:"space-y-1",children:n.map((e,d)=>a("li",{className:"flex items-baseline gap-2",style:{paddingLeft:`${(e.level-1)*12}px`},children:[a("span",{className:"shrink-0 font-mono text-[11px] text-zinc-400",children:["H",e.level]}),t("span",{className:"truncate text-zinc-700",children:e.text})]},d))})]})}export{p as default};
1
+ "use client";import{jsx as t,jsxs as a}from"react/jsx-runtime";import{useEasel as o}from"efficient-easel/easel";import{headingOutline as p}from"../lib/puck/heading-outline.js";import{say as s}from"../lib/editor-words.js";function x(){const{appState:l,config:c}=o(e=>e),d=l?.data,n=p(d?.content??[],c),i=n.filter(e=>e.level===1).length;return a("div",{className:"px-4 py-3 text-[13px] text-zinc-600",children:[a("div",{className:"mb-2 flex items-center justify-between text-[11px] font-semibold uppercase tracking-wide text-zinc-500",children:[t("span",{children:s("Heading outline")}),t("span",{children:n.length})]}),i!==1&&t("div",{className:"mb-2 rounded bg-amber-50 px-2 py-1 text-[12px] text-amber-700",children:i===0?s("No H1 — add one for SEO."):s("{n} H1s — a page should have exactly one.",{n:i})}),n.length===0?t("p",{className:"text-zinc-400",children:s("No headings yet.")}):t("ul",{className:"space-y-1",children:n.map((e,r)=>a("li",{className:"flex items-baseline gap-2",style:{paddingLeft:`${(e.level-1)*12}px`},children:[a("span",{className:"shrink-0 font-mono text-[11px] text-zinc-400",children:["H",e.level]}),t("span",{className:"truncate text-zinc-700",children:e.text})]},r))})]})}export{x as default};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{SettingsDefaultReset as f,SettingsField as h,SettingsSegmented as g}from"efficient-easel/panel";import{WIDTH_CHOICE_LABEL as d}from"../lib/content/section-width.js";import{ImageIcon as c}from"efficient-easel/icons";const l="Hero image",o=[{followsWidth:!1,label:d.full},{followsWidth:!0,label:d.page}],u="Whether the big picture at the top of a page runs edge to edge, or sits inside the page width. The words follow the page width either way.";function p({value:i,onChange:a,showHint:r=!0}){const n=i===null,s=i??!1;return t(h,{label:l,icon:t(c,{}),value:o.find(e=>e.followsWidth===s).label,changed:!n,action:t(f,{label:l,changed:!n,detail:o.find(e=>!e.followsWidth).label,onReset:()=>a(null)}),hint:r?u:void 0,children:t(g,{options:o.map(e=>({id:e.followsWidth,label:e.label})),value:s,ariaLabel:l,onChange:a})})}export{l as HERO_IMAGE_LABEL,p as default};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{SettingsDefaultReset as h,SettingsField as g,SettingsSegmented as p}from"efficient-easel/panel";import{say as e,editorEaselWords as c}from"../lib/editor-words.js";import{WIDTH_CHOICE_LABEL as d}from"../lib/content/section-width.js";import{ImageIcon as m}from"efficient-easel/icons";const o="Hero image",i=[{followsWidth:!1,label:d.full},{followsWidth:!0,label:d.page}],u="Whether the big picture at the top of a page runs edge to edge, or sits inside the page width. The words follow the page width either way.";function w({value:a,onChange:n,showHint:f=!0}){const s=a===null,r=a??!1;return l(g,{label:e(o),icon:l(m,{}),value:e(i.find(t=>t.followsWidth===r).label),changed:!s,action:l(h,{words:c()?.panel,label:e(o),changed:!s,detail:e(i.find(t=>!t.followsWidth).label),onReset:()=>n(null)}),hint:f?e(u):void 0,children:l(p,{options:i.map(t=>({id:t.followsWidth,label:e(t.label)})),value:r,ariaLabel:e(o),onChange:n})})}export{o as HERO_IMAGE_LABEL,w as default};