bearminion 1.5.0 → 1.6.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.
package/dist/ui/mount.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { a as sectionFieldKey, i as isPropShown, t as defaultTheme } from "../theme-DFjHjgFO.js";
2
2
  import { B as withImageLayout, F as DEFAULT_IMAGE_POSITION, I as IMAGE_FITS, L as IMAGE_POSITIONS, P as DEFAULT_IMAGE_FIT, R as isImageFit, S as upsertJsonLd, b as parseJsonLdInput, g as isPlaceholderSiteUrl, i as isSystemPage, m as generateSiteJsonLd, p as formatJsonLd, v as jsonLdWarnings, z as isImagePosition } from "../page-NOFVEqn1.js";
3
3
  import { applyTextMark, fontMarks, marksFromEmphasis, reconcileMarks, renderMarkedHtml } from "../marks.js";
4
- import { _ as consentCopy, c as hasThemeColors, d as tokenToHex, f as CONSENT_COPY, h as CONSENT_LIMITS, i as contrastChecks, n as HEX_COLOR, o as derivePalette, r as OVERRIDE_TOKENS, s as hasOverrides, t as DEFAULT_BRAND, u as themeCss, v as consentTextIssues } from "../theme-colors-CbCyVANH.js";
4
+ import { _ as consentCopy, b as parseMediaSource, c as hasThemeColors, d as tokenToHex, f as CONSENT_COPY, h as CONSENT_LIMITS, i as contrastChecks, n as HEX_COLOR, o as derivePalette, r as OVERRIDE_TOKENS, s as hasOverrides, t as DEFAULT_BRAND, u as themeCss, v as consentTextIssues } from "../theme-colors-CHROGZkI.js";
5
5
  import { _ as writeSaveNotice, a as localDraftStorage, d as removeDraft, f as savedNoticeFor, g as writeDraftRecord, h as sweepExpiredDrafts, i as isForeignSave, l as readDraftRecord, m as siteSavedKey, n as draftBannerText, o as pageDraftKey, p as siteDraftKey, r as hashText, s as pageSavedKey, t as assessStoredDraft, u as reloadDecision, x as draftImageUsages } from "../draft-store-1Y4-sn45.js";
6
6
  import { isSafeHref, markdownFromHtml, renderRichText, richLinkAt, sanitizeRichHtml, stripPlainRich, updateRichLink } from "../rich-text.js";
7
7
  import { Component, Fragment, createContext, isValidElement, options, render } from "preact";
8
8
  import { useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
9
9
  import { Fragment as Fragment$1, jsx, jsxs } from "preact/jsx-runtime";
10
+ //#endregion
10
11
  //#region ../../node_modules/.pnpm/@preact+signals-core@1.14.4/node_modules/@preact/signals-core/dist/signals-core.mjs
11
12
  const i$1 = Symbol.for("preact-signals");
12
13
  function t() {
@@ -5051,7 +5052,7 @@ function wrap(tr, range, wrappers) {
5051
5052
  let start = range.start, end = range.end;
5052
5053
  tr.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true));
5053
5054
  }
5054
- function setBlockType(tr, from, to, type, attrs) {
5055
+ function setBlockType$1(tr, from, to, type, attrs) {
5055
5056
  if (!type.isTextblock) throw new RangeError("Type given to setBlockType should be a textblock");
5056
5057
  let mapFrom = tr.steps.length;
5057
5058
  tr.doc.nodesBetween(from, to, (node, pos) => {
@@ -5861,7 +5862,7 @@ var Transform = class {
5861
5862
  the given node type with the given attributes.
5862
5863
  */
5863
5864
  setBlockType(from, to = from, type, attrs = null) {
5864
- setBlockType(this, from, to, type, attrs);
5865
+ setBlockType$1(this, from, to, type, attrs);
5865
5866
  return this;
5866
5867
  }
5867
5868
  /**
@@ -7269,6 +7270,37 @@ const selectTextblockStart = selectTextblockSide(-1);
7269
7270
  Moves the cursor to the end of current text block.
7270
7271
  */
7271
7272
  const selectTextblockEnd = selectTextblockSide(1);
7273
+ /**
7274
+ Returns a command that tries to set the selected textblocks to the
7275
+ given node type with the given attributes.
7276
+ */
7277
+ function setBlockType(nodeType, attrs = null) {
7278
+ return function(state, dispatch) {
7279
+ let applicable = false;
7280
+ for (let i = 0; i < state.selection.ranges.length && !applicable; i++) {
7281
+ let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i];
7282
+ state.doc.nodesBetween(from, to, (node, pos) => {
7283
+ if (applicable) return false;
7284
+ if (!node.isTextblock || node.hasMarkup(nodeType, attrs)) return;
7285
+ if (node.type == nodeType) applicable = true;
7286
+ else {
7287
+ let $pos = state.doc.resolve(pos), index = $pos.index();
7288
+ applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType);
7289
+ }
7290
+ });
7291
+ }
7292
+ if (!applicable) return false;
7293
+ if (dispatch) {
7294
+ let tr = state.tr;
7295
+ for (let i = 0; i < state.selection.ranges.length; i++) {
7296
+ let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i];
7297
+ tr.setBlockType(from, to, nodeType, attrs);
7298
+ }
7299
+ dispatch(tr.scrollIntoView());
7300
+ }
7301
+ return true;
7302
+ };
7303
+ }
7272
7304
  function markApplies(doc, ranges, type, enterAtoms) {
7273
7305
  for (let i = 0; i < ranges.length; i++) {
7274
7306
  let { $from, $to } = ranges[i];
@@ -7941,7 +7973,7 @@ for (var i = 65; i <= 90; i++) {
7941
7973
  base[i] = String.fromCharCode(i + 32);
7942
7974
  shift[i] = String.fromCharCode(i);
7943
7975
  }
7944
- for (var code$1 in base) if (!shift.hasOwnProperty(code$1)) shift[code$1] = base[code$1];
7976
+ for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code];
7945
7977
  function keyName(event) {
7946
7978
  var name = !(mac$2 && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie$1 && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified") && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified";
7947
7979
  if (name == "Esc") name = "Escape";
@@ -12825,115 +12857,173 @@ function checkStateComponent(plugin) {
12825
12857
  }
12826
12858
  //#endregion
12827
12859
  //#region src/ui/rich-editor.ts
12828
- /**
12829
- * The rich-text subset as a ProseMirror schema: paragraphs, line breaks, flat bulleted and numbered lists, bold,
12830
- * italic, inline code and links. Nothing else can exist in the document, so nothing else can be pasted or typed into it.
12831
- * Storage stays the markdown subset of `rich-text.ts`; this module only converts at the edges.
12832
- */
12833
- const richSchema = new Schema({
12834
- nodes: {
12835
- doc: { content: "(paragraph | bullet_list | ordered_list)+" },
12836
- paragraph: {
12837
- content: "inline*",
12838
- group: "block",
12839
- parseDOM: [{ tag: "p" }],
12840
- toDOM: () => ["p", 0]
12841
- },
12842
- bullet_list: {
12843
- content: "list_item+",
12844
- group: "block",
12845
- parseDOM: [{ tag: "ul" }],
12846
- toDOM: () => ["ul", 0]
12847
- },
12848
- ordered_list: {
12849
- content: "list_item+",
12850
- group: "block",
12851
- parseDOM: [{ tag: "ol" }],
12852
- toDOM: () => ["ol", 0]
12860
+ /** A schema type that every rich schema defines, narrowed from `| undefined`. */
12861
+ function need(value) {
12862
+ if (value === void 0) throw new Error("Missing rich-text schema type");
12863
+ return value;
12864
+ }
12865
+ /** A heading the field allows: h2 or h3. The page title is the h1, and the markdown subset stops at three. */
12866
+ const headingNode = {
12867
+ attrs: { level: { default: 2 } },
12868
+ content: "inline*",
12869
+ group: "block",
12870
+ defining: true,
12871
+ parseDOM: [
12872
+ {
12873
+ tag: "h1",
12874
+ attrs: { level: 2 }
12853
12875
  },
12854
- list_item: {
12855
- content: "paragraph",
12856
- defining: true,
12857
- parseDOM: [{ tag: "li" }],
12858
- toDOM: () => ["li", 0]
12876
+ {
12877
+ tag: "h2",
12878
+ attrs: { level: 2 }
12859
12879
  },
12860
- hard_break: {
12861
- inline: true,
12862
- group: "inline",
12863
- selectable: false,
12864
- parseDOM: [{ tag: "br" }],
12865
- toDOM: () => ["br"]
12880
+ {
12881
+ tag: "h3",
12882
+ attrs: { level: 3 }
12866
12883
  },
12867
- text: { group: "inline" }
12868
- },
12869
- marks: {
12870
- strong: {
12871
- parseDOM: [{ tag: "strong" }, { tag: "b" }],
12872
- toDOM: () => ["strong", 0]
12884
+ {
12885
+ tag: "h4",
12886
+ attrs: { level: 3 }
12873
12887
  },
12874
- em: {
12875
- parseDOM: [{ tag: "em" }, { tag: "i" }],
12876
- toDOM: () => ["em", 0]
12888
+ {
12889
+ tag: "h5",
12890
+ attrs: { level: 3 }
12877
12891
  },
12878
- code: {
12879
- excludes: "_",
12880
- inclusive: false,
12881
- parseDOM: [{ tag: "code" }],
12882
- toDOM: () => ["code", 0]
12892
+ {
12893
+ tag: "h6",
12894
+ attrs: { level: 3 }
12895
+ }
12896
+ ],
12897
+ toDOM: (node) => [`h${node.attrs.level}`, 0]
12898
+ };
12899
+ function createSchema(headings) {
12900
+ return new Schema({
12901
+ nodes: {
12902
+ doc: { content: headings ? "(paragraph | heading | bullet_list | ordered_list)+" : "(paragraph | bullet_list | ordered_list)+" },
12903
+ paragraph: {
12904
+ content: "inline*",
12905
+ group: "block",
12906
+ parseDOM: [{ tag: "p" }],
12907
+ toDOM: () => ["p", 0]
12908
+ },
12909
+ ...headings ? { heading: headingNode } : {},
12910
+ bullet_list: {
12911
+ content: "list_item+",
12912
+ group: "block",
12913
+ parseDOM: [{ tag: "ul" }],
12914
+ toDOM: () => ["ul", 0]
12915
+ },
12916
+ ordered_list: {
12917
+ content: "list_item+",
12918
+ group: "block",
12919
+ parseDOM: [{ tag: "ol" }],
12920
+ toDOM: () => ["ol", 0]
12921
+ },
12922
+ list_item: {
12923
+ content: "paragraph",
12924
+ defining: true,
12925
+ parseDOM: [{ tag: "li" }],
12926
+ toDOM: () => ["li", 0]
12927
+ },
12928
+ hard_break: {
12929
+ inline: true,
12930
+ group: "inline",
12931
+ selectable: false,
12932
+ parseDOM: [{ tag: "br" }],
12933
+ toDOM: () => ["br"]
12934
+ },
12935
+ text: { group: "inline" }
12883
12936
  },
12884
- link: {
12885
- attrs: {
12886
- href: {},
12887
- newTab: { default: null }
12937
+ marks: {
12938
+ strong: {
12939
+ parseDOM: [{ tag: "strong" }, { tag: "b" }],
12940
+ toDOM: () => ["strong", 0]
12888
12941
  },
12889
- inclusive: false,
12890
- parseDOM: [{
12891
- tag: "a[href]",
12892
- getAttrs: (dom) => {
12893
- const href = dom.getAttribute("href") ?? "";
12894
- if (!isSafeHref(href)) return false;
12895
- const tab = dom.getAttribute("data-new-tab");
12896
- return {
12897
- href,
12898
- newTab: tab === "true" ? "new" : tab === "false" ? "same" : null
12899
- };
12942
+ em: {
12943
+ parseDOM: [{ tag: "em" }, { tag: "i" }],
12944
+ toDOM: () => ["em", 0]
12945
+ },
12946
+ code: {
12947
+ excludes: "_",
12948
+ inclusive: false,
12949
+ parseDOM: [{ tag: "code" }],
12950
+ toDOM: () => ["code", 0]
12951
+ },
12952
+ link: {
12953
+ attrs: {
12954
+ href: {},
12955
+ newTab: { default: null }
12956
+ },
12957
+ inclusive: false,
12958
+ parseDOM: [{
12959
+ tag: "a[href]",
12960
+ getAttrs: (dom) => {
12961
+ const href = dom.getAttribute("href") ?? "";
12962
+ if (!isSafeHref(href)) return false;
12963
+ const tab = dom.getAttribute("data-new-tab");
12964
+ return {
12965
+ href,
12966
+ newTab: tab === "true" ? "new" : tab === "false" ? "same" : null
12967
+ };
12968
+ }
12969
+ }],
12970
+ toDOM: (mark) => {
12971
+ const tab = mark.attrs.newTab;
12972
+ const attrs = { href: String(mark.attrs.href) };
12973
+ if (tab === "new") attrs["data-new-tab"] = "true";
12974
+ else if (tab === "same") attrs["data-new-tab"] = "false";
12975
+ return [
12976
+ "a",
12977
+ attrs,
12978
+ 0
12979
+ ];
12900
12980
  }
12901
- }],
12902
- toDOM: (mark) => {
12903
- const tab = mark.attrs.newTab;
12904
- const attrs = { href: String(mark.attrs.href) };
12905
- if (tab === "new") attrs["data-new-tab"] = "true";
12906
- else if (tab === "same") attrs["data-new-tab"] = "false";
12907
- return [
12908
- "a",
12909
- attrs,
12910
- 0
12911
- ];
12912
12981
  }
12913
12982
  }
12914
- }
12915
- });
12916
- const { paragraph, bullet_list, ordered_list, list_item, hard_break } = richSchema.nodes;
12917
- const { strong, em, code, link } = richSchema.marks;
12918
- const parser = DOMParser.fromSchema(richSchema);
12919
- const serializer = DOMSerializer.fromSchema(richSchema);
12983
+ });
12984
+ }
12985
+ /**
12986
+ * The rich-text subset as a ProseMirror schema: paragraphs, line breaks, flat bulleted and numbered lists, bold,
12987
+ * italic, inline code and links. Nothing else can exist in the document, so nothing else can be pasted or typed into it.
12988
+ * Storage stays the markdown subset of `rich-text.ts`; this module only converts at the edges.
12989
+ */
12990
+ const richSchema = createSchema(false);
12991
+ /** The same, plus h2 and h3, for the fields that ask for headings (`data-rich-headings` on the field). */
12992
+ const headingRichSchema = createSchema(true);
12993
+ function kitOf(headings) {
12994
+ const schema = headings ? headingRichSchema : richSchema;
12995
+ return {
12996
+ schema,
12997
+ parser: DOMParser.fromSchema(schema),
12998
+ serializer: DOMSerializer.fromSchema(schema),
12999
+ options: { headings }
13000
+ };
13001
+ }
13002
+ const plainKit = kitOf(false);
13003
+ const headingKit = kitOf(true);
13004
+ /** The kit a document or a state belongs to. */
13005
+ function kitFor(schema) {
13006
+ return schema === headingRichSchema ? headingKit : plainKit;
13007
+ }
12920
13008
  function container(html) {
12921
13009
  const node = document.createElement("div");
12922
13010
  node.innerHTML = html;
12923
13011
  return node;
12924
13012
  }
12925
13013
  /** Markdown → document, through the same renderer the page uses, so what you edit is what the page shows. */
12926
- function docFromMarkdown(markdown) {
12927
- return parser.parse(container(renderRichText(markdown)));
13014
+ function docFromMarkdown(markdown, headings = false) {
13015
+ const kit = headings ? headingKit : plainKit;
13016
+ return kit.parser.parse(container(renderRichText(markdown, kit.options)));
12928
13017
  }
12929
13018
  /** Document → markdown, through the same serializer the draft has always used. */
12930
13019
  function markdownFromDoc(doc) {
13020
+ const kit = kitFor(doc.type.schema);
12931
13021
  const holder = document.createElement("div");
12932
- holder.append(serializer.serializeFragment(doc.content));
12933
- return markdownFromHtml(holder.innerHTML);
13022
+ holder.append(kit.serializer.serializeFragment(doc.content));
13023
+ return markdownFromHtml(holder.innerHTML, kit.options);
12934
13024
  }
12935
- function sliceFromMarkdown(markdown) {
12936
- return parser.parseSlice(container(renderRichText(markdown)));
13025
+ function sliceFromMarkdown(markdown, kit) {
13026
+ return kit.parser.parseSlice(container(renderRichText(markdown, kit.options)));
12937
13027
  }
12938
13028
  /** Document position of the `offset`-th character of the text; breaks and block edges count for nothing. */
12939
13029
  function posAtTextOffset(doc, offset) {
@@ -12954,8 +13044,10 @@ function posAtTextOffset(doc, offset) {
12954
13044
  });
12955
13045
  return found >= 0 ? found : end;
12956
13046
  }
13047
+ /** A line break. A heading is one line of markdown, so Shift-Enter does nothing there. */
12957
13048
  const insertLineBreak = (state, dispatch) => {
12958
- dispatch?.(state.tr.replaceSelectionWith(hard_break.create()).scrollIntoView());
13049
+ if (state.selection.$from.parent.type.name === "heading") return true;
13050
+ dispatch?.(state.tr.replaceSelectionWith(need(state.schema.nodes.hard_break).create()).scrollIntoView());
12959
13051
  return true;
12960
13052
  };
12961
13053
  /**
@@ -12964,6 +13056,8 @@ const insertLineBreak = (state, dispatch) => {
12964
13056
  */
12965
13057
  function wrapEachInList(kind) {
12966
13058
  return (state, dispatch) => {
13059
+ const { paragraph, list_item } = state.schema.nodes;
13060
+ if (!paragraph || !list_item) return false;
12967
13061
  const range = state.selection.$from.blockRange(state.selection.$to);
12968
13062
  if (!range) return false;
12969
13063
  const paragraphs = [];
@@ -12977,6 +13071,7 @@ function wrapEachInList(kind) {
12977
13071
  }
12978
13072
  /** The lists the selection touches (lists never nest). Works for a caret, a range and select-all alike. */
12979
13073
  function listsIn(state) {
13074
+ const { bullet_list, ordered_list } = state.schema.nodes;
12980
13075
  const { from, to } = state.selection;
12981
13076
  const found = [];
12982
13077
  state.doc.nodesBetween(from, to, (node, pos) => {
@@ -13022,8 +13117,10 @@ function unwrapSelected(lists, from, to) {
13022
13117
  };
13023
13118
  }
13024
13119
  /** Toggle a list: unwrap the same kind, convert the other kind, otherwise wrap. */
13025
- function toggleList(kind) {
13120
+ function toggleList(name) {
13026
13121
  return (state, dispatch) => {
13122
+ const kind = state.schema.nodes[name];
13123
+ if (!kind) return false;
13027
13124
  const lists = listsIn(state);
13028
13125
  if (lists.length === 0) return wrapInList(kind)(state, dispatch) || wrapEachInList(kind)(state, dispatch);
13029
13126
  if (lists.every((list) => list.node.type === kind)) return unwrapSelected(lists, state.selection.from, state.selection.to)(state, dispatch);
@@ -13039,39 +13136,62 @@ function toggleList(kind) {
13039
13136
  function setLink(href) {
13040
13137
  return (state, dispatch) => {
13041
13138
  const { from, to, empty } = state.selection;
13042
- if (empty || !isSafeHref(href)) return false;
13139
+ const link = state.schema.marks.link;
13140
+ if (empty || !link || !isSafeHref(href)) return false;
13043
13141
  dispatch?.(state.tr.addMark(from, to, link.create({ href })));
13044
13142
  return true;
13045
13143
  };
13046
13144
  }
13047
- /** The editing command behind a toolbar button. `url` is for `link`. */
13145
+ /** Make the selected block a heading of this level, or a paragraph again when it already is one. */
13146
+ function toggleHeading(level) {
13147
+ return (state, dispatch) => {
13148
+ const { heading, paragraph } = state.schema.nodes;
13149
+ if (!heading || !paragraph) return false;
13150
+ const parent = state.selection.$from.parent;
13151
+ return (parent.type === heading && parent.attrs.level === level ? setBlockType(paragraph) : setBlockType(heading, { level }))(state, dispatch);
13152
+ };
13153
+ }
13154
+ /** The editing command behind a toolbar button. `url` is for `link`. It reads the node and mark types from the state it runs on. */
13048
13155
  function commandFor(command, url = "") {
13049
13156
  switch (command) {
13050
- case "bold": return toggleMark(strong);
13051
- case "italic": return toggleMark(em);
13052
- case "code": return toggleMark(code);
13053
- case "bulletList": return toggleList(bullet_list);
13054
- case "orderedList": return toggleList(ordered_list);
13157
+ case "bold": return (state, dispatch) => toggleMark(need(state.schema.marks.strong))(state, dispatch);
13158
+ case "italic": return (state, dispatch) => toggleMark(need(state.schema.marks.em))(state, dispatch);
13159
+ case "code": return (state, dispatch) => toggleMark(need(state.schema.marks.code))(state, dispatch);
13160
+ case "bulletList": return toggleList("bullet_list");
13161
+ case "orderedList": return toggleList("ordered_list");
13055
13162
  case "link": return setLink(url);
13163
+ case "heading2": return toggleHeading(2);
13164
+ case "heading3": return toggleHeading(3);
13056
13165
  }
13057
13166
  }
13167
+ /** Enter at the end of a heading starts a paragraph, not another heading. In the middle it splits the heading. */
13168
+ const enterInHeading = (state, dispatch) => {
13169
+ const { heading, paragraph } = state.schema.nodes;
13170
+ if (!heading || !paragraph || state.selection.$from.parent.type !== heading) return false;
13171
+ return splitBlockAs((_node, atEnd) => atEnd ? { type: paragraph } : null)(state, dispatch);
13172
+ };
13058
13173
  /** Enter is a line break, a new item inside a list, and leaves the list from an empty item. */
13059
- const enterCommand = chainCommands(splitListItem(list_item), liftEmptyBlock, insertLineBreak);
13174
+ const enterCommand = (state, dispatch) => chainCommands(enterInHeading, splitListItem(need(state.schema.nodes.list_item)), liftEmptyBlock, insertLineBreak)(state, dispatch);
13060
13175
  function activeOf(state) {
13061
13176
  const { $from, from, to, empty } = state.selection;
13062
- const marked = (type) => empty ? type.isInSet(state.storedMarks ?? $from.marks()) !== void 0 : state.doc.rangeHasMark(from, to, type);
13177
+ const { strong, em, code, link } = state.schema.marks;
13178
+ const { bullet_list, ordered_list, heading } = state.schema.nodes;
13179
+ const marked = (type) => type === void 0 ? false : empty ? type.isInSet(state.storedMarks ?? $from.marks()) !== void 0 : state.doc.rangeHasMark(from, to, type);
13063
13180
  const lists = listsIn(state);
13181
+ const level = heading !== void 0 && $from.parent.type === heading ? $from.parent.attrs.level : 0;
13064
13182
  return {
13065
13183
  bold: marked(strong),
13066
13184
  italic: marked(em),
13067
13185
  code: marked(code),
13068
13186
  link: marked(link),
13069
13187
  bulletList: lists.length > 0 && lists.every((item) => item.node.type === bullet_list),
13070
- orderedList: lists.length > 0 && lists.every((item) => item.node.type === ordered_list)
13188
+ orderedList: lists.length > 0 && lists.every((item) => item.node.type === ordered_list),
13189
+ heading: level === 2 || level === 3 ? level : 0,
13190
+ headings: heading !== void 0
13071
13191
  };
13072
13192
  }
13073
13193
  function sameActive(a, b) {
13074
- return a.bold === b.bold && a.italic === b.italic && a.code === b.code && a.link === b.link && a.bulletList === b.bulletList && a.orderedList === b.orderedList;
13194
+ return a.bold === b.bold && a.italic === b.italic && a.code === b.code && a.link === b.link && a.bulletList === b.bulletList && a.orderedList === b.orderedList && a.heading === b.heading && a.headings === b.headings;
13075
13195
  }
13076
13196
  const mounted = /* @__PURE__ */ new WeakMap();
13077
13197
  /** The editor mounted on `field`, if any. */
@@ -13082,16 +13202,18 @@ function richEditorOf(field) {
13082
13202
  * Make `field` a ProseMirror editor over `markdown`. The field element itself becomes the editable surface, so the
13083
13203
  * page's own typography applies. Focus leaving the field (to anywhere but the editor's panels) ends the edit.
13084
13204
  */
13085
- function mountRichEditor(field, { markdown, selection, onChange, onActive, keepsEdit, onDestroy }) {
13205
+ function mountRichEditor(field, { markdown, headings = false, selection, onChange, onActive, keepsEdit, onDestroy }) {
13086
13206
  const existing = mounted.get(field);
13087
13207
  if (existing) return existing;
13208
+ const kit = headings ? headingKit : plainKit;
13209
+ const { strong, em } = kit.schema.marks;
13088
13210
  const stateFor = (source) => EditorState.create({
13089
- doc: docFromMarkdown(source),
13211
+ doc: docFromMarkdown(source, headings),
13090
13212
  plugins: [
13091
13213
  history(),
13092
13214
  keymap({
13093
- "Mod-b": toggleMark(strong),
13094
- "Mod-i": toggleMark(em),
13215
+ "Mod-b": toggleMark(need(strong)),
13216
+ "Mod-i": toggleMark(need(em)),
13095
13217
  "Mod-z": undo,
13096
13218
  "Mod-y": redo,
13097
13219
  "Shift-Mod-z": redo,
@@ -13120,8 +13242,8 @@ function mountRichEditor(field, { markdown, selection, onChange, onActive, keeps
13120
13242
  lastMarkdown = markdownFromDoc(next.doc);
13121
13243
  onChange(lastMarkdown);
13122
13244
  },
13123
- transformPastedHTML: (html) => sanitizeRichHtml(html),
13124
- clipboardTextParser: (text) => sliceFromMarkdown(stripPlainRich(text))
13245
+ transformPastedHTML: (html) => sanitizeRichHtml(html, kit.options),
13246
+ clipboardTextParser: (text) => sliceFromMarkdown(stripPlainRich(text, kit.options), kit)
13125
13247
  });
13126
13248
  if (selection) {
13127
13249
  const { doc } = view.state;
@@ -13156,7 +13278,7 @@ function mountRichEditor(field, { markdown, selection, onChange, onActive, keeps
13156
13278
  field.removeAttribute("contenteditable");
13157
13279
  field.removeAttribute("translate");
13158
13280
  if (!field.getAttribute("class")) field.removeAttribute("class");
13159
- field.innerHTML = renderRichText(lastMarkdown);
13281
+ field.innerHTML = renderRichText(lastMarkdown, kit.options);
13160
13282
  onDestroy?.();
13161
13283
  }
13162
13284
  };
@@ -13321,7 +13443,7 @@ function paintPage(draft) {
13321
13443
  if (isRichField(raw, node.getAttribute("data-field-kind"))) {
13322
13444
  const editing = richEditorOf(node);
13323
13445
  if (editing) editing.setMarkdown(value);
13324
- else node.innerHTML = renderRichText(value);
13446
+ else node.innerHTML = renderRichText(value, { headings: node.getAttribute("data-rich-headings") === "true" });
13325
13447
  } else if (isHeadingField(path)) node.innerHTML = renderMarkedHtml(value, marksAt(draft, path));
13326
13448
  else node.textContent = value;
13327
13449
  }
@@ -13447,10 +13569,18 @@ function isOptionalPath(content, path) {
13447
13569
  if (parts.length === 3 && arrayKey !== void 0 && key !== void 0 && /^\d+$/.test(index ?? "")) return content.items?.[arrayKey]?.includes(key) ?? false;
13448
13570
  return false;
13449
13571
  }
13450
- /** Section content keys in the order the form lists them: defaults first, then any other optional prop. */
13572
+ /**
13573
+ * Section content keys in the order the form lists them: defaults first. An optional prop the defaults leave out sits
13574
+ * right after the optional prop listed before it (`body` after `heading`), or at the end when none of those exist.
13575
+ */
13451
13576
  function orderContentKeys(present, optional, defaultKeys) {
13452
13577
  const keys = [.../* @__PURE__ */ new Set([...present, ...optional])];
13453
- const rank = [...defaultKeys, ...optional];
13578
+ const rank = [...defaultKeys];
13579
+ optional.forEach((key, position) => {
13580
+ if (rank.includes(key)) return;
13581
+ const before = optional.slice(0, position).reverse().find((name) => rank.includes(name));
13582
+ rank.splice(before === void 0 ? rank.length : rank.indexOf(before) + 1, 0, key);
13583
+ });
13454
13584
  const at = (key) => {
13455
13585
  const found = rank.indexOf(key);
13456
13586
  return found === -1 ? Number.MAX_SAFE_INTEGER : found;
@@ -13593,6 +13723,7 @@ function attachPageEditing(editor) {
13593
13723
  let stop = () => {};
13594
13724
  const handle = mountRichEditor(field, {
13595
13725
  markdown: read(),
13726
+ headings: field.getAttribute("data-rich-headings") === "true",
13596
13727
  selection,
13597
13728
  onChange: (markdown) => edits.writeField(pathOf(field), markdown),
13598
13729
  keepsEdit: isInEditor,
@@ -14186,7 +14317,7 @@ function attachShortcuts(editor) {
14186
14317
  return;
14187
14318
  }
14188
14319
  if (ui.previewing.peek()) {
14189
- if (event.key === "Escape") {
14320
+ if (event.key === "Escape" && !document.querySelector("dialog[open]")) {
14190
14321
  event.preventDefault();
14191
14322
  chrome.exitPreview();
14192
14323
  }
@@ -14450,8 +14581,10 @@ function createChrome(ui) {
14450
14581
  for (const node of document.querySelectorAll("[data-field][contenteditable]")) node.removeAttribute("contenteditable");
14451
14582
  if (document.activeElement instanceof HTMLElement) document.activeElement.blur();
14452
14583
  document.documentElement.style.cursor = "";
14584
+ document.documentElement.setAttribute("data-bearminion-preview", "");
14453
14585
  }
14454
14586
  function exitPreview() {
14587
+ document.documentElement.removeAttribute("data-bearminion-preview");
14455
14588
  writeStorage(session, PREVIEW_KEY, null);
14456
14589
  n(() => {
14457
14590
  ui.previewing.value = false;
@@ -14568,6 +14701,15 @@ function uploadImage(file) {
14568
14701
  body
14569
14702
  });
14570
14703
  }
14704
+ const getVideos = () => request("/videos");
14705
+ function uploadVideo(file) {
14706
+ const body = new FormData();
14707
+ body.set("file", file);
14708
+ return request("/videos", {
14709
+ method: "POST",
14710
+ body
14711
+ });
14712
+ }
14571
14713
  const getGit = () => request("/git");
14572
14714
  const commit = (body) => request("/git/commit", sendJson("POST", body));
14573
14715
  /** Saved versions of the site (`scope` site) or of one page. */
@@ -16614,7 +16756,7 @@ const FOCUSABLE = "button:not(:disabled), input:not(:disabled), [tabindex=\"0\"]
16614
16756
  * Filled: thumbnail, file name, alt text, Change and Remove. The picker is a modal
16615
16757
  * with an Upload tab (drop or browse) and a Library tab (pick or delete).
16616
16758
  */
16617
- function ImageField({ label, path, value, images, withAlt = true, layout = true, hideable = false, onChange, onUploaded, onDeleted }) {
16759
+ function ImageField({ label, path, value, images, withAlt = true, layout = true, hideable = false, captionable = false, onChange, onUploaded, onDeleted }) {
16618
16760
  const [open, setOpen] = useState(false);
16619
16761
  const [error, setError] = useState("");
16620
16762
  const [over, setOver] = useState(false);
@@ -16626,18 +16768,24 @@ function ImageField({ label, path, value, images, withAlt = true, layout = true,
16626
16768
  const position = isImagePosition(value?.position) ? value.position : DEFAULT_IMAGE_POSITION;
16627
16769
  const showLayout = layout && withAlt;
16628
16770
  const hidden = hideable && value?.hidden === true;
16771
+ const caption = typeof value?.caption === "string" ? value.caption : "";
16629
16772
  const current = {
16630
16773
  src,
16631
16774
  alt,
16775
+ ...caption ? { caption } : {},
16632
16776
  fit,
16633
16777
  position,
16634
16778
  ...hidden ? { hidden } : {}
16635
16779
  };
16636
16780
  /** Emit the whole image object. A new file or alt keeps the fit and position already chosen. */
16637
- const emit = (patch) => onChange(compact({
16638
- ...current,
16639
- ...patch
16640
- }));
16781
+ const emit = (patch) => {
16782
+ const next = {
16783
+ ...current,
16784
+ ...patch
16785
+ };
16786
+ if (next.caption === "") delete next.caption;
16787
+ onChange(compact(next));
16788
+ };
16641
16789
  const empty = src === "" || src === "placeholder";
16642
16790
  const shown = previewSrc(src);
16643
16791
  const missing = useMissingFile(empty ? "" : src);
@@ -16704,15 +16852,9 @@ function ImageField({ label, path, value, images, withAlt = true, layout = true,
16704
16852
  children: [
16705
16853
  /* @__PURE__ */ jsx("span", {
16706
16854
  class: "bm-label",
16707
- children: /* @__PURE__ */ jsxs("span", {
16708
- class: "bm-label-row",
16709
- children: [/* @__PURE__ */ jsx("span", {
16710
- class: "bm-label-text",
16711
- children: label
16712
- }), withAlt && !empty && /* @__PURE__ */ jsx("span", {
16713
- class: "bm-meta-tag",
16714
- children: "alt required"
16715
- })]
16855
+ children: /* @__PURE__ */ jsx("span", {
16856
+ class: "bm-label-text",
16857
+ children: label
16716
16858
  })
16717
16859
  }),
16718
16860
  hideable && /* @__PURE__ */ jsxs("label", {
@@ -16840,12 +16982,46 @@ function ImageField({ label, path, value, images, withAlt = true, layout = true,
16840
16982
  })]
16841
16983
  })]
16842
16984
  })]
16843
- }), withAlt && /* @__PURE__ */ jsx("input", {
16844
- class: "bm-alt",
16845
- "aria-label": "Alt",
16846
- placeholder: "Alt text: describe the image",
16847
- value: alt,
16848
- onInput: (event) => emit({ alt: event.currentTarget.value })
16985
+ }), withAlt && /* @__PURE__ */ jsxs("div", {
16986
+ class: "bm-stack bm-stack-tight",
16987
+ children: [
16988
+ /* @__PURE__ */ jsxs("span", {
16989
+ class: "bm-label bm-label-row",
16990
+ "aria-hidden": "true",
16991
+ children: [/* @__PURE__ */ jsx("span", {
16992
+ class: "bm-label-text",
16993
+ children: "Alt text"
16994
+ }), /* @__PURE__ */ jsx("span", {
16995
+ class: "bm-meta-tag",
16996
+ children: "required"
16997
+ })]
16998
+ }),
16999
+ /* @__PURE__ */ jsx("input", {
17000
+ class: "bm-alt",
17001
+ "aria-label": "Alt",
17002
+ placeholder: "Describe the image",
17003
+ value: alt,
17004
+ onInput: (event) => emit({ alt: event.currentTarget.value })
17005
+ }),
17006
+ captionable && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
17007
+ class: "bm-label bm-label-row",
17008
+ "aria-hidden": "true",
17009
+ children: [/* @__PURE__ */ jsx("span", {
17010
+ class: "bm-label-text",
17011
+ children: "Caption"
17012
+ }), /* @__PURE__ */ jsx("span", {
17013
+ class: "bm-meta-tag",
17014
+ children: "optional, shown when opened large"
17015
+ })]
17016
+ }), /* @__PURE__ */ jsx("textarea", {
17017
+ class: "bm-alt",
17018
+ rows: 2,
17019
+ "aria-label": "Caption",
17020
+ placeholder: "Shown under the picture. Empty uses the alt text.",
17021
+ value: caption,
17022
+ onInput: (event) => emit({ caption: event.currentTarget.value })
17023
+ })] })
17024
+ ]
16849
17025
  })] }),
16850
17026
  missing && /* @__PURE__ */ jsxs("p", {
16851
17027
  class: "bm-error",
@@ -17279,6 +17455,126 @@ function ChoiceField({ label, value, choices, icons, path, segmented = true, onC
17279
17455
  });
17280
17456
  }
17281
17457
  //#endregion
17458
+ //#region src/ui/forms/video-source.tsx
17459
+ /** What a pasted video link is, or why it will not play. Empty for no link. */
17460
+ function describeVideoLink(value) {
17461
+ const link = value.trim();
17462
+ if (link === "") return null;
17463
+ const source = parseMediaSource(link);
17464
+ if (source?.kind === "youtube") return {
17465
+ ok: true,
17466
+ text: "YouTube video. It loads nothing until the visitor presses play."
17467
+ };
17468
+ if (source?.kind === "vimeo") return {
17469
+ ok: true,
17470
+ text: "Vimeo video. It loads nothing until the visitor presses play."
17471
+ };
17472
+ if (source?.kind === "file") return {
17473
+ ok: true,
17474
+ text: "Video file."
17475
+ };
17476
+ if (/^https?:\/\//i.test(link)) return {
17477
+ ok: false,
17478
+ text: "That is a page link, not a video. Use a YouTube or Vimeo link, or a link to a file ending in .mp4 or .webm."
17479
+ };
17480
+ return {
17481
+ ok: false,
17482
+ text: "Use a YouTube or Vimeo link, a link to a video file ending in .mp4 or .webm, or a path in public/ such as /videos/demo.webm."
17483
+ };
17484
+ }
17485
+ const megabytes = (bytes) => `${(bytes / 1048576).toFixed(bytes < 10485760 ? 1 : 0)} MB`;
17486
+ /** Under a video link field: says what the link is, uploads a video file, and picks one already uploaded. */
17487
+ function VideoSourceTools({ value, onPick }) {
17488
+ const input = useRef(null);
17489
+ const [library, setLibrary] = useState([]);
17490
+ const [busy, setBusy] = useState(false);
17491
+ const [note, setNote] = useState("");
17492
+ const [error, setError] = useState("");
17493
+ useEffect(() => {
17494
+ let live = true;
17495
+ getVideos().then((result) => {
17496
+ if (live && result.ok) setLibrary(result.value.videos);
17497
+ });
17498
+ return () => {
17499
+ live = false;
17500
+ };
17501
+ }, []);
17502
+ async function upload(file) {
17503
+ if (!file) return;
17504
+ setBusy(true);
17505
+ setError("");
17506
+ setNote("");
17507
+ const result = await uploadVideo(file);
17508
+ setBusy(false);
17509
+ if (!result.ok) {
17510
+ setError(result.status === 0 ? "Upload failed." : result.message);
17511
+ return;
17512
+ }
17513
+ setLibrary((current) => [...current.filter((item) => item.url !== result.value.url), result.value]);
17514
+ onPick(result.value.url);
17515
+ if ((result.value.bytes ?? 0) > 10485760) setNote(`${megabytes(result.value.bytes ?? 0)}: it is slow to load on every visit. YouTube or Vimeo is kinder to visitors.`);
17516
+ }
17517
+ const detected = describeVideoLink(value);
17518
+ return /* @__PURE__ */ jsxs("div", {
17519
+ class: "bm-stack bm-stack-tight",
17520
+ children: [
17521
+ detected ? /* @__PURE__ */ jsx("span", {
17522
+ class: detected.ok ? "bm-hint" : "bm-error",
17523
+ role: detected.ok ? void 0 : "alert",
17524
+ children: detected.text
17525
+ }) : /* @__PURE__ */ jsx("span", {
17526
+ class: "bm-hint",
17527
+ children: "Paste a YouTube or Vimeo link as it is, or upload a video file."
17528
+ }),
17529
+ /* @__PURE__ */ jsx("input", {
17530
+ ref: input,
17531
+ type: "file",
17532
+ accept: "video/mp4,video/webm,video/quicktime,video/ogg",
17533
+ hidden: true,
17534
+ onChange: (event) => {
17535
+ const file = event.currentTarget.files?.[0];
17536
+ event.currentTarget.value = "";
17537
+ upload(file);
17538
+ }
17539
+ }),
17540
+ /* @__PURE__ */ jsx("button", {
17541
+ type: "button",
17542
+ class: "bm-add bm-add-row",
17543
+ disabled: busy,
17544
+ onClick: () => input.current?.click(),
17545
+ children: busy ? "Uploading…" : "Upload a video file"
17546
+ }),
17547
+ library.length > 0 && /* @__PURE__ */ jsxs("label", {
17548
+ class: "bm-field",
17549
+ children: [/* @__PURE__ */ jsx("span", {
17550
+ class: "bm-label",
17551
+ children: "Uploaded videos"
17552
+ }), /* @__PURE__ */ jsxs("select", {
17553
+ value: "",
17554
+ "aria-label": "Uploaded videos",
17555
+ onChange: (event) => event.currentTarget.value && onPick(event.currentTarget.value),
17556
+ children: [/* @__PURE__ */ jsx("option", {
17557
+ value: "",
17558
+ children: "Choose one…"
17559
+ }), library.map((video) => /* @__PURE__ */ jsxs("option", {
17560
+ value: video.url,
17561
+ children: [video.filename, video.bytes ? ` (${megabytes(video.bytes)})` : ""]
17562
+ }, video.url))]
17563
+ })]
17564
+ }),
17565
+ note && /* @__PURE__ */ jsx("span", {
17566
+ class: "bm-hint",
17567
+ children: note
17568
+ }),
17569
+ error && /* @__PURE__ */ jsx("span", {
17570
+ class: "bm-error",
17571
+ role: "alert",
17572
+ children: error
17573
+ })
17574
+ ]
17575
+ });
17576
+ }
17577
+ //#endregion
17282
17578
  //#region src/ui/forms/fields.tsx
17283
17579
  /** `yearlyDiscount` and `cta_label` read as "Yearly discount" and "Cta label". Array item numbers stay numbers. */
17284
17580
  function humanize(key) {
@@ -17346,7 +17642,7 @@ function ValueEditor({ label: rawLabel, value, path, rule, variant, sample, imag
17346
17642
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === void 0) {
17347
17643
  const rich = typeof value === "string" && isRichField(path, null);
17348
17644
  const heading = isHeadingField(path);
17349
- return /* @__PURE__ */ jsx(OptionControl, {
17645
+ const control = /* @__PURE__ */ jsx(OptionControl, {
17350
17646
  option: {
17351
17647
  name: path,
17352
17648
  label,
@@ -17360,122 +17656,39 @@ function ValueEditor({ label: rawLabel, value, path, rule, variant, sample, imag
17360
17656
  value,
17361
17657
  onChange: (next) => onField(path, next)
17362
17658
  });
17659
+ if (!/(^|\.)props\.video$/.test(path)) return control;
17660
+ return /* @__PURE__ */ jsxs("div", {
17661
+ class: "bm-stack bm-stack-tight",
17662
+ children: [control, /* @__PURE__ */ jsx(VideoSourceTools, {
17663
+ value: typeof value === "string" ? value : "",
17664
+ onPick: (url) => onField(path, url)
17665
+ })]
17666
+ });
17363
17667
  }
17364
17668
  if (isImageRecord(value)) return /* @__PURE__ */ jsx(ImageField, {
17365
17669
  label,
17366
17670
  path,
17367
17671
  layout: !/(^|\.)logos\./.test(path),
17368
17672
  hideable: path.startsWith("sections.") && !/(^|\.)logos\./.test(path),
17673
+ captionable: isOptionalPath(optionalSpec, `${path}.caption`),
17369
17674
  value,
17370
17675
  images,
17371
17676
  onChange: (next) => onField(path, next),
17372
17677
  onUploaded,
17373
17678
  onDeleted
17374
17679
  });
17375
- if (Array.isArray(value)) {
17376
- const allowAdd = canAddItems(value.length, rule, variant);
17377
- const allowRemove = canRemoveItems(value.length, rule, variant);
17378
- return /* @__PURE__ */ jsxs("div", {
17379
- class: "bm-stack bm-stack-tight",
17380
- children: [/* @__PURE__ */ jsxs("span", {
17381
- class: "bm-label-row bm-label",
17382
- children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsxs("span", {
17383
- class: "bm-meta-tag",
17384
- children: [value.length, rule?.recommended !== void 0 ? `, recommended ${rule.recommended}` : ""]
17385
- })]
17386
- }), /* @__PURE__ */ jsxs("div", {
17387
- class: "bm-array",
17388
- children: [value.map((item, index) => /* @__PURE__ */ jsxs("details", {
17389
- class: "bm-array-item",
17390
- children: [/* @__PURE__ */ jsxs("summary", { children: [
17391
- /* @__PURE__ */ jsx("span", {
17392
- class: "bm-grip",
17393
- "aria-hidden": "true",
17394
- children: /* @__PURE__ */ jsx(Icon, {
17395
- name: "grip",
17396
- size: 12
17397
- })
17398
- }),
17399
- /* @__PURE__ */ jsx("span", {
17400
- class: "bm-array-summary",
17401
- children: itemSummary(item) || `${label} ${index + 1}`
17402
- }),
17403
- /* @__PURE__ */ jsx("span", {
17404
- class: "bm-chevron",
17405
- "aria-hidden": "true",
17406
- children: /* @__PURE__ */ jsx(Icon, {
17407
- name: "chevron-right",
17408
- size: 14
17409
- })
17410
- })
17411
- ] }), /* @__PURE__ */ jsxs("div", {
17412
- class: "bm-array-body",
17413
- children: [/* @__PURE__ */ jsx(ValueEditor, {
17414
- label: `${index + 1}`,
17415
- value: item,
17416
- path: `${path}.${index}`,
17417
- rule: void 0,
17418
- variant,
17419
- sample,
17420
- images,
17421
- onField,
17422
- onUploaded,
17423
- onDeleted
17424
- }), /* @__PURE__ */ jsxs("div", {
17425
- class: "bm-row bm-row-end",
17426
- children: [
17427
- /* @__PURE__ */ jsx("button", {
17428
- type: "button",
17429
- class: "bm-icon-btn",
17430
- "aria-label": "Move item up",
17431
- title: "Move up",
17432
- disabled: index === 0,
17433
- onClick: () => onField(path, reorderList(value, index, index - 1)),
17434
- children: /* @__PURE__ */ jsx(Icon, {
17435
- name: "arrow-up",
17436
- size: 14
17437
- })
17438
- }),
17439
- /* @__PURE__ */ jsx("button", {
17440
- type: "button",
17441
- class: "bm-icon-btn",
17442
- "aria-label": "Move item down",
17443
- title: "Move down",
17444
- disabled: index === value.length - 1,
17445
- onClick: () => onField(path, reorderList(value, index, index + 1)),
17446
- children: /* @__PURE__ */ jsx(Icon, {
17447
- name: "arrow-down",
17448
- size: 14
17449
- })
17450
- }),
17451
- /* @__PURE__ */ jsx("button", {
17452
- type: "button",
17453
- class: "bm-icon-btn bm-danger",
17454
- "aria-label": "Remove item",
17455
- title: "Remove",
17456
- disabled: !allowRemove,
17457
- onClick: () => onField(path, value.filter((_, itemIndex) => itemIndex !== index)),
17458
- children: /* @__PURE__ */ jsx(Icon, {
17459
- name: "trash",
17460
- size: 14
17461
- })
17462
- })
17463
- ]
17464
- })]
17465
- })]
17466
- }, `${path}.${index}`)), /* @__PURE__ */ jsx("button", {
17467
- type: "button",
17468
- class: "bm-add bm-add-row",
17469
- disabled: !allowAdd,
17470
- onClick: () => {
17471
- const next = sample === void 0 ? "New" : structuredClone(sample);
17472
- onField(path, [...value, next]);
17473
- },
17474
- children: "+ Add item"
17475
- })]
17476
- })]
17477
- });
17478
- }
17680
+ if (Array.isArray(value)) return /* @__PURE__ */ jsx(ArrayEditor, {
17681
+ label,
17682
+ value,
17683
+ path,
17684
+ rule,
17685
+ variant,
17686
+ sample,
17687
+ images,
17688
+ onField,
17689
+ onUploaded,
17690
+ onDeleted
17691
+ });
17479
17692
  if (isLinkRecord(value)) {
17480
17693
  const record = value;
17481
17694
  return /* @__PURE__ */ jsxs("div", {
@@ -17708,6 +17921,216 @@ function orderItemKeys(item, path, content) {
17708
17921
  const dropped = parts.length === 2 && /^\d+$/.test(parts[1] ?? "") ? content?.items?.[parts[0] ?? ""] ?? [] : [];
17709
17922
  return orderContentKeys(Object.keys(item), dropped, Object.keys(item));
17710
17923
  }
17924
+ let itemSeed = 0;
17925
+ /** Ids that follow each list item when it moves, so its open card, focus and inputs move with it. */
17926
+ function useItemIds(length) {
17927
+ const ids = useRef([]);
17928
+ while (ids.current.length < length) ids.current.push(`item-${++itemSeed}`);
17929
+ if (ids.current.length > length) ids.current.length = length;
17930
+ return ids;
17931
+ }
17932
+ /** Where a drop lands: the index the dragged item ends up at, or null when it would not move. */
17933
+ function dropTarget(drag) {
17934
+ const slot = drag.mode === "before" ? drag.over : drag.over + 1;
17935
+ const to = slot > drag.from ? slot - 1 : slot;
17936
+ return to === drag.from ? null : to;
17937
+ }
17938
+ /** A list of items. Each card keeps its identity when it moves, so a card you moved stays open and you can move it again. */
17939
+ function ArrayEditor({ label, value, path, rule, variant, sample, images, onField, onUploaded, onDeleted }) {
17940
+ const allowAdd = canAddItems(value.length, rule, variant);
17941
+ const allowRemove = canRemoveItems(value.length, rule, variant);
17942
+ const ids = useItemIds(value.length);
17943
+ const list = useRef(null);
17944
+ const [drag, setDrag] = useState(null);
17945
+ function move(from, to, refocus) {
17946
+ if (from === to || to < 0 || to >= value.length) return;
17947
+ const [id] = ids.current.splice(from, 1);
17948
+ if (id === void 0) return;
17949
+ ids.current.splice(to, 0, id);
17950
+ onField(path, reorderList(value, from, to));
17951
+ if (!refocus) return;
17952
+ const wanted = id;
17953
+ requestAnimationFrame(() => requestAnimationFrame(() => {
17954
+ const card = list.current?.querySelector(`[data-item-id="${wanted}"]`);
17955
+ const first = card?.querySelector(`[data-move="${refocus}"]`);
17956
+ const other = card?.querySelector(`[data-move="${refocus === "up" ? "down" : "up"}"]`);
17957
+ (first && !first.disabled ? first : other)?.focus();
17958
+ }));
17959
+ }
17960
+ return /* @__PURE__ */ jsxs("div", {
17961
+ class: "bm-stack bm-stack-tight",
17962
+ children: [/* @__PURE__ */ jsxs("span", {
17963
+ class: "bm-label-row bm-label",
17964
+ children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsxs("span", {
17965
+ class: "bm-meta-tag",
17966
+ children: [value.length, rule?.recommended !== void 0 ? `, recommended ${rule.recommended}` : ""]
17967
+ })]
17968
+ }), /* @__PURE__ */ jsxs("div", {
17969
+ class: "bm-array",
17970
+ ref: list,
17971
+ children: [value.map((item, index) => {
17972
+ const id = ids.current[index] ?? `${path}.${index}`;
17973
+ const mode = (drag !== null && drag.over === index ? dropTarget(drag) : null) === null || drag === null ? null : drag.mode;
17974
+ const rowClass = [
17975
+ "bm-array-row",
17976
+ drag?.from === index ? "bm-dragging" : "",
17977
+ mode === "before" ? "bm-drop-before" : "",
17978
+ mode === "after" ? "bm-drop-after" : ""
17979
+ ].filter(Boolean).join(" ");
17980
+ return /* @__PURE__ */ jsx("div", {
17981
+ class: rowClass,
17982
+ "data-item-id": id,
17983
+ "data-drop-hint": mode ? "Move here" : void 0,
17984
+ onDragOver: (event) => {
17985
+ if (!drag) return;
17986
+ event.preventDefault();
17987
+ event.stopPropagation();
17988
+ if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
17989
+ const box = event.currentTarget.getBoundingClientRect();
17990
+ const next = event.clientY < box.top + box.height / 2 ? "before" : "after";
17991
+ if (drag.over !== index || drag.mode !== next) setDrag({
17992
+ ...drag,
17993
+ over: index,
17994
+ mode: next
17995
+ });
17996
+ },
17997
+ onDragLeave: (event) => {
17998
+ const next = event.relatedTarget;
17999
+ if (!drag || next instanceof Node && event.currentTarget.contains(next)) return;
18000
+ if (drag.over === index) setDrag({
18001
+ ...drag,
18002
+ over: drag.from
18003
+ });
18004
+ },
18005
+ onDrop: (event) => {
18006
+ if (!drag) return;
18007
+ event.preventDefault();
18008
+ event.stopPropagation();
18009
+ const to = dropTarget({
18010
+ ...drag,
18011
+ over: index,
18012
+ mode: drag.over === index ? drag.mode : "before"
18013
+ });
18014
+ const from = drag.from;
18015
+ setDrag(null);
18016
+ if (to !== null) move(from, to);
18017
+ },
18018
+ children: /* @__PURE__ */ jsxs("details", {
18019
+ class: "bm-array-item",
18020
+ children: [/* @__PURE__ */ jsxs("summary", { children: [
18021
+ /* @__PURE__ */ jsx("span", {
18022
+ class: "bm-grip bm-array-grip",
18023
+ draggable: true,
18024
+ title: "Drag to reorder",
18025
+ "aria-hidden": "true",
18026
+ onClick: (event) => event.preventDefault(),
18027
+ onDragStart: (event) => {
18028
+ event.stopPropagation();
18029
+ const row = event.currentTarget.closest(".bm-array-row");
18030
+ if (event.dataTransfer) {
18031
+ event.dataTransfer.effectAllowed = "move";
18032
+ event.dataTransfer.setData("text/plain", id);
18033
+ if (row) event.dataTransfer.setDragImage(row, 16, 16);
18034
+ }
18035
+ setDrag({
18036
+ from: index,
18037
+ over: index,
18038
+ mode: "before"
18039
+ });
18040
+ },
18041
+ onDragEnd: () => setDrag(null),
18042
+ children: /* @__PURE__ */ jsx(Icon, {
18043
+ name: "grip",
18044
+ size: 12
18045
+ })
18046
+ }),
18047
+ /* @__PURE__ */ jsx("span", {
18048
+ class: "bm-array-summary",
18049
+ children: itemSummary(item) || `${label} ${index + 1}`
18050
+ }),
18051
+ /* @__PURE__ */ jsx("span", {
18052
+ class: "bm-chevron",
18053
+ "aria-hidden": "true",
18054
+ children: /* @__PURE__ */ jsx(Icon, {
18055
+ name: "chevron-right",
18056
+ size: 14
18057
+ })
18058
+ })
18059
+ ] }), /* @__PURE__ */ jsxs("div", {
18060
+ class: "bm-array-body",
18061
+ children: [/* @__PURE__ */ jsx(ValueEditor, {
18062
+ label: `${index + 1}`,
18063
+ value: item,
18064
+ path: `${path}.${index}`,
18065
+ rule: void 0,
18066
+ variant,
18067
+ sample,
18068
+ images,
18069
+ onField,
18070
+ onUploaded,
18071
+ onDeleted
18072
+ }), /* @__PURE__ */ jsxs("div", {
18073
+ class: "bm-row bm-row-end",
18074
+ children: [
18075
+ /* @__PURE__ */ jsx("button", {
18076
+ type: "button",
18077
+ class: "bm-icon-btn",
18078
+ "aria-label": "Move item up",
18079
+ title: "Move up",
18080
+ "data-move": "up",
18081
+ disabled: index === 0,
18082
+ onClick: () => move(index, index - 1, "up"),
18083
+ children: /* @__PURE__ */ jsx(Icon, {
18084
+ name: "arrow-up",
18085
+ size: 14
18086
+ })
18087
+ }),
18088
+ /* @__PURE__ */ jsx("button", {
18089
+ type: "button",
18090
+ class: "bm-icon-btn",
18091
+ "aria-label": "Move item down",
18092
+ title: "Move down",
18093
+ "data-move": "down",
18094
+ disabled: index === value.length - 1,
18095
+ onClick: () => move(index, index + 1, "down"),
18096
+ children: /* @__PURE__ */ jsx(Icon, {
18097
+ name: "arrow-down",
18098
+ size: 14
18099
+ })
18100
+ }),
18101
+ /* @__PURE__ */ jsx("button", {
18102
+ type: "button",
18103
+ class: "bm-icon-btn bm-danger",
18104
+ "aria-label": "Remove item",
18105
+ title: "Remove",
18106
+ disabled: !allowRemove,
18107
+ onClick: () => {
18108
+ ids.current.splice(index, 1);
18109
+ onField(path, value.filter((_, itemIndex) => itemIndex !== index));
18110
+ },
18111
+ children: /* @__PURE__ */ jsx(Icon, {
18112
+ name: "trash",
18113
+ size: 14
18114
+ })
18115
+ })
18116
+ ]
18117
+ })]
18118
+ })]
18119
+ })
18120
+ }, id);
18121
+ }), /* @__PURE__ */ jsx("button", {
18122
+ type: "button",
18123
+ class: "bm-add bm-add-row",
18124
+ disabled: !allowAdd,
18125
+ onClick: () => {
18126
+ const next = sample === void 0 ? "New" : structuredClone(sample);
18127
+ onField(path, [...value, next]);
18128
+ },
18129
+ children: "+ Add item"
18130
+ })]
18131
+ })]
18132
+ });
18133
+ }
17711
18134
  //#endregion
17712
18135
  //#region src/ui/dialogs/consent-dialog.tsx
17713
18136
  const KEYS = [
@@ -18956,6 +19379,30 @@ function RichTextBar() {
18956
19379
  class: "bm-rich",
18957
19380
  style: `top:${position.top}px;left:${position.left}px;`,
18958
19381
  children: [
19382
+ active?.headings && /* @__PURE__ */ jsxs(Fragment$1, { children: [
19383
+ /* @__PURE__ */ jsx("button", {
19384
+ type: "button",
19385
+ class: "bm-fmt-heading",
19386
+ "aria-label": "Heading",
19387
+ title: "Heading",
19388
+ "aria-pressed": active.heading === 2,
19389
+ onMouseDown: run("heading2"),
19390
+ children: "H2"
19391
+ }),
19392
+ /* @__PURE__ */ jsx("button", {
19393
+ type: "button",
19394
+ class: "bm-fmt-heading",
19395
+ "aria-label": "Subheading",
19396
+ title: "Subheading",
19397
+ "aria-pressed": active.heading === 3,
19398
+ onMouseDown: run("heading3"),
19399
+ children: "H3"
19400
+ }),
19401
+ /* @__PURE__ */ jsx("span", {
19402
+ class: "bm-sep",
19403
+ "aria-hidden": "true"
19404
+ })
19405
+ ] }),
18959
19406
  /* @__PURE__ */ jsx("button", {
18960
19407
  type: "button",
18961
19408
  class: "bm-fmt-bold",
@@ -20141,7 +20588,7 @@ function AdvancedLink({ edit }) {
20141
20588
  }
20142
20589
  //#endregion
20143
20590
  //#region src/ui/editor.css?raw
20144
- var editor_default = "/*\n * Editor styles. They live in a shadow root, so they never meet the site's Tailwind layer.\n * The editor is always light. Tokens and values follow the v4 editor design handoff.\n * The short names (--ink, --line, --accent ...) alias the --bm-* tokens so older rules read the same.\n */\n:host {\n all: initial;\n\n /* ---------- v4 tokens (editor-tokens.css) ---------- */\n --bm-font-ui: \"Bricolage Grotesque Variable\", \"Bricolage Grotesque\", ui-sans-serif, system-ui, sans-serif;\n --bm-font-mono: \"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace;\n --bm-font-serif: \"Instrument Serif\", Georgia, serif;\n\n --bm-ink: oklch(0.21 0.012 255);\n --bm-label: oklch(0.3 0.01 255);\n --bm-section: oklch(0.42 0.01 255);\n --bm-help: oklch(0.47 0.01 255);\n --bm-muted: oklch(0.5 0.01 255);\n --bm-icon: oklch(0.55 0.01 255);\n --bm-info: oklch(0.6 0.01 255);\n\n --bm-fill: oklch(0.955 0.003 250);\n --bm-fill-hover: oklch(0.93 0.004 250);\n --bm-fill-soft: oklch(0.965 0.003 250);\n --bm-fill-nested: oklch(0.97 0.003 250);\n --bm-border: oklch(0.88 0.005 250);\n --bm-divider: oklch(0.93 0.004 250);\n --bm-tab-rule: oklch(0.92 0.004 250);\n\n --bm-primary: oklch(0.46 0.13 145);\n --bm-primary-hover: oklch(0.4 0.12 145);\n --bm-primary-ring: oklch(0.46 0.13 145 / 0.15);\n --bm-link: oklch(0.4 0.12 145);\n\n --bm-saved-bg: oklch(0.94 0.045 145);\n --bm-saved-fg: oklch(0.36 0.1 145);\n --bm-unsaved-bg: oklch(0.95 0.05 80);\n --bm-unsaved-fg: oklch(0.48 0.1 60);\n --bm-unsaved-dot: oklch(0.75 0.15 70);\n --bm-badge-green-bg: oklch(0.93 0.06 145);\n --bm-badge-green-fg: oklch(0.38 0.1 145);\n --bm-badge-amber-bg: oklch(0.95 0.04 75);\n --bm-badge-amber-fg: oklch(0.45 0.09 60);\n\n --bm-danger: oklch(0.55 0.19 25);\n --bm-danger-text: oklch(0.52 0.17 25);\n --bm-danger-icon: oklch(0.58 0.18 25);\n --bm-danger-soft: oklch(0.96 0.025 20);\n\n --bm-diff-del-bg: oklch(0.97 0.02 20);\n --bm-diff-del-fg: oklch(0.45 0.13 25);\n --bm-diff-add-bg: oklch(0.96 0.04 145);\n --bm-diff-add-fg: oklch(0.34 0.1 145);\n\n --bm-switch-off: oklch(0.82 0.005 250);\n\n --bm-shadow-pop: 0 0 0 1px oklch(0.9 0.005 250), 0 16px 36px -16px oklch(0.2 0.02 255 / 0.35);\n --bm-shadow-dialog: 0 0 0 1px oklch(0.9 0.005 250), 0 24px 48px -24px oklch(0.2 0.02 255 / 0.35);\n --bm-shadow-segment-on: 0 1px 2px oklch(0 0 0 / 0.08), 0 0 0 1px oklch(0.9 0.005 250);\n\n /* ---------- aliases used by the rules below ---------- */\n --ink: var(--bm-ink);\n --ink-2: var(--bm-label);\n --muted: var(--bm-muted);\n --line: var(--bm-border);\n --line-soft: var(--bm-divider);\n --fill: var(--bm-fill);\n --fill-hover: var(--bm-fill-hover);\n --fill-soft: var(--bm-fill-soft);\n --accent: var(--bm-primary);\n --accent-hover: var(--bm-primary-hover);\n --accent-tint: oklch(0.96 0.03 145);\n --accent-ring: var(--bm-primary-ring);\n --warn-tint: var(--bm-unsaved-bg);\n --warn-ink: var(--bm-unsaved-fg);\n --warn-dot: var(--bm-unsaved-dot);\n --danger-hover: oklch(0.48 0.18 25);\n --danger-tint: var(--bm-danger-soft);\n --danger-ink: var(--bm-danger-text);\n --info-dot: oklch(0.6 0.15 255);\n --sans: var(--bm-font-ui);\n --mono: var(--bm-font-mono);\n --serif: var(--bm-font-serif);\n --shadow-pop: var(--bm-shadow-pop);\n}\n* {\n box-sizing: border-box;\n}\nbutton,\ninput,\nselect,\ntextarea {\n font: inherit;\n color: inherit;\n}\nbutton {\n cursor: pointer;\n}\n:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n\n/* On-page outlines */\n.bm-outline {\n position: fixed;\n pointer-events: none;\n border-radius: 6px;\n z-index: 1;\n}\n.bm-outline-section {\n border: 2px solid var(--accent);\n}\n.bm-outline-field {\n border: 2px solid var(--accent);\n background: oklch(0.46 0.13 145 / 0.08);\n}\n.bm-image-bar {\n flex-wrap: nowrap;\n left: auto;\n white-space: nowrap;\n}\n.bm-image-bar-group {\n display: flex;\n gap: 2px;\n}\n.bm-image-bar button[aria-pressed=\"true\"] {\n background: var(--bm-saved-bg);\n color: var(--bm-saved-fg);\n}\n.bm-image-bar-grid {\n display: grid;\n grid-template-columns: repeat(3, 9px);\n grid-template-rows: repeat(3, 9px);\n gap: 2px;\n align-self: center;\n padding: 0 4px;\n}\n.bm-image-bar .bm-pos-cell {\n width: 9px;\n height: 9px;\n /* `.bm-rich button` sets a 32px minimum for the bar's text buttons; the cells stay 9px. */\n min-width: 0;\n min-height: 0;\n padding: 0;\n border-radius: 2px;\n background: var(--line);\n}\n.bm-image-bar .bm-pos-cell:hover:not(:disabled) {\n background: var(--muted);\n}\n.bm-image-bar .bm-pos-cell[aria-pressed=\"true\"] {\n background: var(--accent);\n}\n.bm-image-bar .bm-pos-cell:disabled {\n opacity: 0.3;\n cursor: default;\n}\n.bm-outline-image {\n background: oklch(0.46 0.13 145 / 0.12);\n}\n.bm-outline-image::after {\n content: \"Change image\";\n position: absolute;\n top: 8px;\n left: 8px;\n padding: 4px 9px;\n border-radius: 6px;\n background: var(--accent);\n color: #fff;\n font: 500 11px / 1.3 var(--sans, system-ui, sans-serif);\n}\n\n.bm-toolbar,\n.bm-dock,\n.bm-exit-preview,\n.bm-sidebar,\n.bm-popover,\n.bm-dialog,\n.bm-rich,\n.bm-banner,\n.bm-scrim {\n pointer-events: auto;\n font-family: var(--sans);\n font-size: 13px;\n color: var(--ink);\n -webkit-font-smoothing: antialiased;\n}\n\n/*\n * Insert between sections. Three states:\n * idle / hover a solid line and a 28px circle; hover changes nothing.\n * open the picker is open: the line stays and a \"between A and B\" chip replaces the circle.\n */\n.bm-gap {\n position: fixed;\n z-index: 2;\n height: 0;\n pointer-events: none;\n}\n.bm-gap::before {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n height: 0;\n border-top: 2px solid var(--bm-primary);\n transform: translateY(-50%);\n}\n.bm-gap-add {\n position: absolute;\n left: 50%;\n top: 0;\n transform: translate(-50%, -50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 999px;\n pointer-events: auto;\n cursor: pointer;\n white-space: nowrap;\n background: var(--bm-primary);\n color: #fff;\n box-shadow: 0 0 0 2px #fff;\n}\n.bm-gap-add .bm-icon {\n width: 14px;\n height: 14px;\n stroke-width: 2.4;\n}\n.bm-gap-add:focus-visible {\n outline: 2px solid var(--ink);\n outline-offset: 3px;\n}\n.bm-gap-chip {\n position: absolute;\n left: 50%;\n top: 0;\n transform: translate(-50%, -50%);\n padding: 4px 10px;\n border-radius: 999px;\n background: #fff;\n color: var(--bm-ink);\n box-shadow: 0 0 0 1.5px var(--bm-primary);\n white-space: nowrap;\n pointer-events: none;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* Light floating bars: section toolbar, rich text bar, heading format bar */\n.bm-toolbar,\n.bm-rich {\n position: fixed;\n z-index: 3;\n display: flex;\n gap: 2px;\n padding: 4px;\n border-radius: 12px;\n background: #fff;\n color: var(--ink);\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-toolbar button,\n.bm-rich button {\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: inherit;\n min-height: 32px;\n padding: 0 10px;\n font-size: 12px;\n font-weight: 500;\n}\n.bm-toolbar button:hover:not(:disabled),\n.bm-rich button:hover {\n background: var(--fill);\n}\n.bm-rich button[aria-pressed=\"true\"] {\n background: var(--bm-saved-bg);\n box-shadow: inset 0 0 0 1px oklch(0.46 0.13 145 / 0.4);\n}\n.bm-toolbar :focus-visible,\n.bm-rich :focus-visible {\n outline-color: var(--accent);\n}\n.bm-toolbar {\n align-items: center;\n max-width: calc(100vw - 16px);\n padding: 5px;\n}\n.bm-toolbar button {\n width: 34px;\n min-height: 34px;\n height: 34px;\n padding: 0;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: oklch(0.4 0.01 255);\n}\n.bm-toolbar button:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n.bm-toolbar button:disabled {\n opacity: 0.35;\n cursor: default;\n}\n.bm-toolbar .bm-danger {\n color: var(--bm-danger-icon);\n}\n.bm-toolbar .bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-toolbar-active {\n box-shadow:\n 0 0 0 2px var(--bm-primary),\n 0 10px 24px -12px oklch(0.2 0.02 255 / 0.35);\n}\n.bm-toolbar-name {\n display: block;\n max-width: 16rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 12px 0 10px;\n}\n.bm-toolbar-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--bm-ink);\n}\n.bm-toolbar-anchor {\n font-family: var(--mono);\n font-size: 12px;\n font-weight: 400;\n color: var(--bm-muted);\n}\n.bm-sep {\n width: 1px;\n align-self: stretch;\n margin: 4px 2px;\n background: var(--line);\n}\n.bm-toolbar .bm-sep {\n align-self: center;\n height: 20px;\n margin: 0 4px;\n background: oklch(0.9 0.005 250);\n}\n.bm-icon {\n width: 16px;\n height: 16px;\n display: block;\n}\n.bm-rich {\n align-items: center;\n flex-wrap: wrap;\n max-width: calc(100vw - 16px);\n}\n.bm-rich button {\n min-height: 32px;\n min-width: 32px;\n}\n.bm-rich input {\n width: 168px;\n min-height: 30px;\n padding: 0 8px;\n border: 0;\n border-radius: 7px;\n background: var(--fill);\n color: var(--ink);\n font-size: 12px;\n}\n.bm-rich input:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--accent);\n}\n\n/* Heading format bar: each button shows \"Aa\" in its own weight or font over a mono caption. */\n.bm-rich.bm-format-bar {\n flex-wrap: nowrap;\n}\n.bm-rich.bm-format-bar button.bm-fmt {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n min-width: 42px;\n height: 48px;\n min-height: 48px;\n padding: 0 8px;\n border-radius: 8px;\n}\n.bm-fmt-sample {\n font-size: 15px;\n line-height: 1;\n color: var(--bm-ink);\n}\n.bm-fmt-caption {\n font-family: var(--mono);\n font-size: 9px;\n letter-spacing: 0.02em;\n color: var(--bm-muted);\n}\n.bm-rich.bm-format-bar button.bm-fmt[aria-pressed=\"true\"] {\n background: var(--bm-saved-bg);\n box-shadow: inset 0 0 0 1px oklch(0.46 0.13 145 / 0.4);\n}\n.bm-format-bar .bm-sep {\n align-self: stretch;\n margin: 6px 4px;\n}\n\n/* Light popovers: add menu, section picker, edit link */\n.bm-popover {\n position: fixed;\n z-index: 3;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n max-height: min(420px, calc(100vh - 16px));\n overflow: auto;\n padding: 6px;\n border-radius: 12px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-popover > button {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 34px;\n padding: 0 10px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n text-align: left;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-popover > button:hover {\n background: var(--fill);\n}\n\n/* Add section picker: wireframe cards */\n.bm-popover[aria-label=\"Add section\"][role=\"listbox\"] {\n gap: 14px;\n width: 640px;\n max-width: calc(100vw - 16px);\n max-height: calc(100vh - 16px);\n padding: 16px;\n border-radius: 14px;\n overflow: visible;\n box-shadow: var(--bm-shadow-dialog);\n}\n.bm-picker-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.bm-picker-title {\n font-size: 17px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n.bm-picker-where {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n color: var(--bm-muted);\n}\n.bm-picker-grid {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n max-height: 26rem;\n overflow-y: auto;\n padding: 2px 6px 2px 2px;\n margin-right: -6px;\n scrollbar-gutter: stable;\n}\n.bm-popover .bm-picker-grid > button {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: flex-start;\n gap: 6px;\n min-height: 0;\n padding: 8px 8px 10px;\n border: 1px solid oklch(0.9 0.005 250);\n border-radius: 10px;\n background: #fff;\n text-align: left;\n font-weight: 400;\n}\n.bm-popover .bm-picker-grid > button:hover {\n background: #fff;\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px oklch(0.46 0.13 145 / 0.12);\n}\n.bm-wire {\n position: relative;\n display: block;\n width: 100%;\n height: 76px;\n border-radius: 7px;\n background: oklch(0.97 0 0);\n overflow: hidden;\n}\n.bm-wire > span {\n position: absolute;\n display: block;\n}\n.bm-type-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 0 2px;\n}\n.bm-type-name {\n font-size: 14px;\n font-weight: 600;\n line-height: 1.25;\n color: var(--bm-ink);\n}\n.bm-type-variants {\n font-family: var(--mono);\n font-size: 10px;\n font-weight: 400;\n line-height: 1.35;\n white-space: nowrap;\n color: var(--muted);\n}\n.bm-type-desc {\n padding: 0 2px;\n font-size: 12px;\n line-height: 1.4;\n color: var(--bm-help);\n}\n.bm-picker-note {\n margin: 0;\n font-size: 12px;\n color: var(--bm-muted);\n}\n\n.bm-popover[aria-label=\"Edit link\"] {\n gap: 14px;\n padding: 16px;\n max-height: calc(100vh - 16px);\n}\n\n/* Dialogs and banners */\n.bm-dialog {\n position: fixed;\n z-index: 6;\n display: flex;\n flex-direction: column;\n gap: 16px;\n width: min(400px, calc(100vw - 32px));\n padding: 20px;\n border-radius: 14px;\n background: #fff;\n box-shadow: var(--bm-shadow-dialog);\n}\n.bm-dialog-head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n}\n.bm-dialog-heading {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.bm-dialog-sub {\n margin: 0;\n font-size: 13px;\n line-height: 1.4;\n color: var(--bm-help);\n}\n.bm-dialog .bm-dialog-x,\n.bm-popover .bm-dialog-x,\n.bm-modal .bm-dialog-x {\n flex: none;\n width: 32px;\n height: 32px;\n margin: -6px -8px -6px 0;\n background: transparent;\n color: var(--bm-icon);\n}\n.bm-dialog-title {\n margin: 0;\n font-size: 17px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--bm-ink);\n}\n.bm-popover .bm-dialog-title {\n font-size: 16px;\n}\n.bm-dialog .bm-note {\n color: var(--bm-label);\n font-size: 14px;\n line-height: 1.5;\n}\n.bm-dialog button,\n.bm-popover .bm-actions button,\n.bm-banner button {\n min-height: 38px;\n padding: 0 16px;\n border: 0;\n border-radius: 8px;\n background: var(--fill);\n font-size: 14px;\n font-weight: 400;\n}\n.bm-dialog button:hover:not(:disabled),\n.bm-popover .bm-actions button:hover:not(:disabled) {\n background: var(--fill-hover);\n}\n/* The primary action comes first in the DOM (focus lands on it); row-reverse shows it last, on the right. */\n.bm-actions {\n display: flex;\n flex-direction: row-reverse;\n justify-content: flex-start;\n align-items: center;\n gap: 8px;\n}\n.bm-dialog > .bm-actions,\n.bm-popover[aria-label=\"Edit link\"] > .bm-actions {\n padding-top: 12px;\n border-top: 1px solid var(--bm-divider);\n}\n.bm-dialog-foot {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 12px;\n border-top: 1px solid var(--bm-divider);\n}\n.bm-dialog-foot > .bm-hint {\n flex: 1;\n min-width: 0;\n margin: 0;\n}\n.bm-dialog-foot .bm-actions {\n flex: none;\n}\n\n/* Alert dialogs: [icon tile] [title / body / note] [x] */\n.bm-alert-main {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n.bm-alert-copy {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.bm-alert-body {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--bm-label);\n overflow-wrap: anywhere;\n}\n.bm-alert-body strong {\n font-weight: 600;\n color: var(--bm-ink);\n}\n.bm-alert-note {\n margin: 0;\n font-size: 12px;\n line-height: 1.45;\n color: var(--bm-muted);\n}\n.bm-tile {\n flex: none;\n display: grid;\n place-items: center;\n width: 36px;\n height: 36px;\n border-radius: 9px;\n}\n.bm-tile .bm-icon {\n width: 18px;\n height: 18px;\n}\n.bm-tile-warn {\n background: var(--bm-unsaved-bg);\n color: var(--bm-unsaved-fg);\n}\n.bm-tile-danger {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-tile-neutral {\n background: var(--bm-fill);\n color: var(--bm-label);\n}\n\n.bm-banner {\n position: fixed;\n z-index: 6;\n display: flex;\n align-items: center;\n gap: 12px;\n width: min(440px, calc(100vw - 32px));\n padding: 12px 14px;\n border-radius: 12px;\n box-shadow: 0 14px 34px -10px oklch(0.2 0.02 255 / 0.4);\n}\n.bm-banner button {\n min-height: 34px;\n padding: 0 14px;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-banner-ink {\n background: var(--ink);\n color: #fff;\n}\n.bm-banner-light {\n background: #fff;\n box-shadow: var(--shadow-pop);\n}\n.bm-banner-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.bm-banner-title {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.35;\n}\n.bm-banner-sub {\n margin: 0;\n font-size: 12px;\n line-height: 1.4;\n opacity: 0.7;\n}\n.bm-banner .bm-actions {\n flex: none;\n gap: 6px;\n}\n.bm-banner-ink button {\n min-height: 30px;\n padding: 0 12px;\n font-size: 12px;\n background: oklch(1 0 0 / 0.12);\n color: #fff;\n}\n.bm-banner-ink button:hover {\n background: oklch(1 0 0 / 0.2);\n}\n.bm-banner-ink .bm-primary {\n background: #fff;\n color: var(--ink);\n}\n.bm-banner-ink .bm-primary:hover {\n background: oklch(0.94 0.003 250);\n}\n.bm-banner-ink :focus-visible {\n outline-color: oklch(0.82 0.14 145);\n}\n.bm-dot-stale {\n background: oklch(0.7 0.18 25) !important;\n}\n.bm-dot-info {\n background: var(--info-dot) !important;\n}\n\n/* Closed editor. The dock sits where the sidebar header's controls sit: header padding (top 14, right 14) minus the dock's 7px padding. */\n.bm-dock {\n position: fixed;\n z-index: 5;\n top: 7px;\n right: 7px;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 7px 7px 10px;\n border-radius: 14px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-dot {\n flex: none;\n width: 8px;\n height: 8px;\n border-radius: 99px;\n background: oklch(0.72 0.17 145);\n}\n.bm-dot-dirty {\n background: var(--warn-dot);\n}\n\n/* Sidebar shell */\n.bm-sidebar {\n position: fixed;\n z-index: 4;\n top: 0;\n right: 0;\n bottom: 0;\n width: min(440px, 100vw);\n display: flex;\n flex-direction: column;\n background: #fff;\n box-shadow:\n 0 0 0 1px var(--line),\n -24px 0 48px -24px oklch(0.2 0.02 255 / 0.25);\n}\n.bm-resize {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: col-resize;\n touch-action: none;\n z-index: 2;\n}\n.bm-resize:hover,\n.bm-resize:focus-visible {\n background: oklch(0.46 0.13 145 / 0.25);\n}\n.bm-resize:focus-visible {\n outline-offset: -2px;\n}\n\n.bm-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 14px 14px 16px;\n border-bottom: 1px solid var(--line-soft);\n}\n.bm-mark {\n flex: none;\n display: block;\n width: 28px;\n height: auto;\n aspect-ratio: 21 / 19;\n image-rendering: pixelated;\n user-select: none;\n}\n/* Bear, name and slogan. Takes the space the controls leave; the text fades out when it no longer fits. */\n.bm-brand {\n position: relative;\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.bm-head-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n transition: opacity 160ms ease;\n}\n.bm-brand-compact .bm-head-text {\n opacity: 0;\n}\n/* The same two lines, in a card left of the sidebar (over the page), level with the header, while the pointer is on\n the brand. 16px is the header's left padding: the card clears the sidebar edge by 10px. */\n.bm-brand-tip {\n position: absolute;\n z-index: 5;\n top: 50%;\n right: calc(100% + 16px + 10px);\n display: flex;\n flex-direction: column;\n padding: 8px 12px;\n border-radius: 10px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n white-space: nowrap;\n opacity: 0;\n transform: translate(4px, -50%);\n pointer-events: none;\n transition:\n opacity 120ms ease,\n transform 120ms ease;\n}\n.bm-brand-compact:hover .bm-brand-tip {\n opacity: 1;\n transform: translate(0, -50%);\n transition-delay: 120ms;\n}\n@media (prefers-reduced-motion: reduce) {\n .bm-head-text,\n .bm-brand-tip {\n transition: none;\n }\n}\n/* A ring with one open quarter that turns while a save is written and the page reloads. */\n.bm-spin {\n flex: none;\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: bm-spin 0.8s linear infinite;\n}\n@keyframes bm-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .bm-spin {\n animation: none;\n }\n}\n.bm-faces {\n display: grid;\n}\n.bm-face {\n grid-area: 1 / 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n white-space: nowrap;\n}\n.bm-face[hidden-face] {\n visibility: hidden;\n}\n.bm-save:disabled {\n opacity: 0.85;\n cursor: progress;\n}\n.bm-head-title {\n font-size: 15px;\n font-weight: 600;\n letter-spacing: -0.015em;\n /* The controls beside it never shrink, so a narrow sidebar cuts the name, not the buttons. */\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-head-sub {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-pill {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 24px;\n padding: 0 10px;\n border-radius: 999px;\n background: var(--bm-saved-bg);\n color: var(--bm-saved-fg);\n font-size: 12px;\n font-weight: 500;\n}\n.bm-pill .bm-dot {\n width: 6px;\n height: 6px;\n background: var(--accent);\n}\n.bm-pill-dirty {\n background: var(--warn-tint);\n color: var(--warn-ink);\n}\n.bm-pill-dirty .bm-dot {\n background: var(--warn-dot);\n}\nbutton.bm-pill-btn {\n min-height: 0;\n padding: 0 10px;\n border: 0;\n border-radius: 999px;\n background: var(--warn-tint);\n color: var(--warn-ink);\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n}\n:is(.bm-sidebar, .bm-dock) button.bm-pill-btn:hover:not(:disabled) {\n background: oklch(0.93 0.06 75);\n color: var(--warn-ink);\n}\nbutton.bm-pill-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n.bm-dialog-wide {\n width: min(400px, calc(100vw - 32px));\n}\n.bm-dialog .bm-actions {\n flex-wrap: nowrap;\n}\n.bm-dialog .bm-actions button {\n flex: none;\n white-space: nowrap;\n}\n.bm-changes {\n width: min(540px, calc(100vw - 32px));\n}\n.bm-commit-files {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n max-height: min(34vh, 280px);\n overflow-y: auto;\n}\n.bm-commit-files label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n cursor: pointer;\n}\n.bm-commit-mark {\n font:\n 600 11px / 1 ui-monospace,\n monospace;\n width: 18px;\n text-align: center;\n opacity: 0.7;\n}\n.bm-commit-msg {\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n font: inherit;\n font-size: 14px;\n padding: 8px 12px;\n border: 1px solid var(--line);\n border-radius: 8px;\n background: transparent;\n color: inherit;\n}\n\n/* Unsaved changes review and version history: groups, rows, diff lines */\n.bm-changes-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-height: 22rem;\n overflow-y: auto;\n margin: 0 -4px;\n padding: 0 4px;\n}\n.bm-changes-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-changes-area {\n margin: 0;\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--bm-section);\n}\n.bm-changes-file {\n font-weight: 400;\n letter-spacing: 0;\n text-transform: none;\n color: oklch(0.55 0.01 255);\n}\n.bm-changes-count {\n margin-left: auto;\n font-weight: 400;\n letter-spacing: 0;\n color: var(--bm-muted);\n}\n.bm-changes ul {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n overflow: hidden;\n}\n.bm-change {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px;\n font-size: 14px;\n line-height: 1.4;\n}\n.bm-change + .bm-change {\n border-top: 1px solid var(--bm-divider);\n}\n.bm-change-mark {\n flex: none;\n display: grid;\n place-items: center;\n width: 22px;\n height: 22px;\n border-radius: 6px;\n font-family: var(--mono);\n font-size: 13px;\n font-weight: 600;\n background: var(--bm-unsaved-bg);\n color: var(--bm-unsaved-fg);\n}\n.bm-change-added .bm-change-mark {\n background: var(--bm-badge-green-bg);\n color: var(--bm-badge-green-fg);\n}\n.bm-change-removed .bm-change-mark {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-text);\n}\n.bm-change-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.bm-change-field {\n font-weight: 500;\n color: var(--bm-ink);\n overflow-wrap: anywhere;\n}\n.bm-change-values {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n.bm-change-values del,\n.bm-change-values ins {\n display: flex;\n gap: 6px;\n min-width: 0;\n padding: 3px 7px;\n border-radius: 5px;\n text-decoration: none;\n font-size: 13px;\n}\n.bm-change-values del {\n background: var(--bm-diff-del-bg);\n color: var(--bm-diff-del-fg);\n}\n.bm-change-values ins {\n background: var(--bm-diff-add-bg);\n color: var(--bm-diff-add-fg);\n}\n.bm-change-values del::before {\n content: \"\\2212\";\n flex: none;\n font-family: var(--mono);\n}\n.bm-change-values ins::before {\n content: \"+\";\n flex: none;\n font-family: var(--mono);\n}\n.bm-change-values del > span,\n.bm-change-values ins > span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-change-values del > span {\n text-decoration: line-through;\n text-decoration-color: oklch(0.45 0.13 25 / 0.5);\n}\n.bm-changes-empty {\n margin: 0;\n padding: 24px 0;\n text-align: center;\n font-size: 14px;\n color: var(--bm-muted);\n}\n\n.bm-changes ul.bm-versions {\n gap: 0;\n}\n.bm-version {\n padding: 0;\n}\n.bm-version + .bm-version {\n border-top: 1px solid var(--bm-divider);\n}\n.bm-version-when strong {\n font-weight: 600;\n}\n.bm-tipped {\n position: relative;\n}\n.bm-tipped::after {\n content: attr(data-tip);\n position: absolute;\n right: calc(100% + 6px);\n top: 50%;\n transform: translateY(-50%);\n padding: 4px 8px;\n border-radius: 6px;\n background: var(--ink);\n color: #fff;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n pointer-events: none;\n visibility: hidden;\n z-index: 5;\n}\n.bm-version-row > .bm-tipped:first-child::after {\n right: auto;\n left: calc(100% + 6px);\n}\n.bm-tipped:hover::after,\n.bm-tipped:focus-visible::after {\n visibility: visible;\n}\n.bm-version-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 8px 8px 10px;\n}\n.bm-version-when {\n flex: 1;\n min-width: 0;\n margin-right: auto;\n padding: 0 !important;\n min-height: 32px !important;\n font-weight: 500;\n display: flex !important;\n flex-direction: column;\n align-items: flex-start !important;\n justify-content: center;\n gap: 2px;\n text-align: left;\n}\n.bm-version-line {\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n.bm-version-sum {\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 400;\n color: var(--bm-help);\n}\n.bm-version-row .bm-restore {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n flex: none;\n min-height: 32px;\n padding: 0 10px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-version-rel {\n font-size: 14px;\n font-weight: 500;\n color: var(--bm-ink);\n}\n.bm-version-abs {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--bm-muted);\n}\n.bm-version-diff {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 4px 10px 12px 10px;\n border-top: 1px solid var(--bm-divider);\n margin-top: 0;\n}\n.bm-version-diff ul {\n margin: 0;\n}\n.bm-day {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.bm-restored {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 8px 8px 12px;\n border-radius: 9px;\n background: var(--bm-diff-add-bg);\n color: var(--bm-saved-fg);\n font-size: 13px;\n}\n.bm-restored > span {\n flex: 1;\n min-width: 0;\n}\n\n.bm-tabs {\n display: flex;\n gap: 0;\n padding: 0 12px;\n overflow-x: auto;\n border-bottom: 1px solid var(--bm-tab-rule);\n}\n.bm-tabs button {\n flex: 1 1 auto;\n height: 46px;\n padding: 0 6px;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: oklch(0.48 0.01 255);\n font-size: 13px;\n font-weight: 400;\n}\n.bm-tabs button:hover {\n color: var(--ink);\n background: var(--fill-soft);\n}\n.bm-tabs button[aria-selected=\"true\"] {\n color: var(--ink);\n background: transparent;\n font-weight: 600;\n box-shadow: inset 0 -2px 0 var(--accent);\n}\n.bm-tabs button:focus-visible {\n outline-offset: -2px;\n}\n\n.bm-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 24px 24px 32px;\n display: flex;\n flex-direction: column;\n gap: 18px;\n}\n.bm-foot {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n border-top: 1px solid var(--line-soft);\n font-family: var(--mono);\n font-size: 10px;\n color: var(--muted);\n}\n.bm-foot span:first-child {\n flex: none;\n white-space: nowrap;\n}\n.bm-foot span:last-child {\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n/* Group header: mono 11/500, then a 1px rule. With a right-hand item the rule sits on the flex wrapper. */\n.bm-group {\n margin: 18px 0 0;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--bm-divider);\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--bm-section);\n}\n.bm-group:first-child {\n margin-top: 0;\n}\n.bm-stack-tight > .bm-group {\n margin-bottom: 10px;\n}\n.bm-meta {\n margin: 0;\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n}\n\n/* Fields */\n.bm-label {\n display: flex;\n flex-direction: column;\n gap: 8px;\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n}\n.bm-field {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-hint {\n font-size: 12px;\n line-height: 1.45;\n font-weight: 400;\n color: var(--muted);\n}\n.bm-label-text {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n}\n.bm-info {\n position: relative;\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n margin-left: 4px;\n}\n.bm-info-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n margin: -3px 0;\n border-radius: 999px;\n color: var(--bm-info);\n cursor: help;\n text-transform: none;\n letter-spacing: 0;\n}\n.bm-info-btn:hover,\n.bm-info-btn[aria-expanded=\"true\"] {\n color: var(--ink);\n}\n.bm-info-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n}\n.bm-tip {\n position: fixed;\n z-index: 2147483647;\n visibility: hidden;\n pointer-events: none;\n padding: 8px 10px;\n border-radius: 8px;\n box-sizing: border-box;\n background: var(--ink);\n color: oklch(0.98 0.003 250);\n font-family: var(--sans, inherit);\n font-size: 12px;\n line-height: 1.45;\n font-weight: 400;\n text-transform: none;\n letter-spacing: 0;\n text-align: left;\n white-space: normal;\n box-shadow: 0 6px 20px rgb(0 0 0 / 0.25);\n}\n.bm-tip-open {\n visibility: visible;\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) :where(input:not([type=\"checkbox\"]):not([type=\"file\"]), select, textarea) {\n width: 100%;\n min-height: 40px;\n padding: 0 12px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n color: var(--ink);\n font-size: 14px;\n font-weight: 400;\n outline: none;\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) textarea {\n padding: 8px 12px;\n min-height: 72px;\n line-height: 1.5;\n resize: vertical;\n}\n:is(.bm-sidebar, .bm-popover) select:not([size]) {\n appearance: none;\n padding-right: 32px;\n /* A caret made of gradients, not a `data:` image: a site's Content-Security-Policy can block those. */\n background-image: linear-gradient(45deg, transparent 50%, #777 50%), linear-gradient(135deg, #777 50%, transparent 50%);\n background-size: 6px 6px;\n background-repeat: no-repeat;\n background-position:\n right 17px center,\n right 12px center;\n}\n.bm-sidebar select[size],\n.bm-popover select[size] {\n padding: 4px;\n font-size: 12px;\n}\n.bm-sidebar select[size] option,\n.bm-sidebar select[size] optgroup,\n.bm-popover select[size] option,\n.bm-popover select[size] optgroup {\n padding: 3px 6px;\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) :where(input:not([type=\"checkbox\"]):not([type=\"file\"]), select, textarea):focus {\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px var(--bm-primary-ring);\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) :where(input[aria-label=\"Link URL\"], .bm-mono) {\n font-family: var(--mono);\n font-size: 13px;\n}\n.bm-prefix-wrap {\n display: flex;\n align-items: center;\n min-height: 40px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n overflow: hidden;\n}\n.bm-prefix-wrap:focus-within {\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px var(--bm-primary-ring);\n}\n.bm-prefix {\n padding: 0 2px 0 12px;\n font-family: var(--mono);\n font-size: 13px;\n color: var(--muted);\n}\n.bm-prefix-wrap input {\n border: 0;\n box-shadow: none !important;\n min-height: 38px;\n padding-left: 2px;\n font-family: var(--mono);\n font-size: 13px;\n}\n.bm-stack {\n display: flex;\n flex-direction: column;\n gap: 18px;\n}\n.bm-stack-tight {\n gap: 8px;\n}\n.bm-groups {\n gap: 36px;\n}\n.bm-list {\n display: flex;\n flex-direction: column;\n border-radius: 10px;\n box-shadow: 0 0 0 1px var(--bm-border);\n overflow: hidden;\n}\n.bm-list-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px 8px 12px;\n border-bottom: 1px solid var(--line-soft);\n}\n.bm-list-row:last-child {\n border-bottom: 0;\n}\n.bm-list-row-on {\n background: var(--accent-tint);\n}\n.bm-list-row a {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n color: var(--ink);\n text-decoration: none;\n}\n.bm-list-row a:hover .bm-list-title {\n text-decoration: underline;\n}\n.bm-list-title {\n font-size: 14px;\n font-weight: 500;\n}\n.bm-list-path {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n}\n.bm-badge-home {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: var(--bm-badge-green-bg);\n color: var(--bm-badge-green-fg);\n}\n.bm-badge {\n font-family: var(--mono);\n font-size: 11px;\n padding: 3px 7px;\n border-radius: 5px;\n background: var(--bm-badge-amber-bg);\n color: var(--bm-badge-amber-fg);\n}\n.bm-badge-system {\n background: var(--fill);\n color: var(--ink-2);\n}\n.bm-badge-on {\n background: var(--bm-badge-green-bg);\n color: var(--bm-badge-green-fg);\n}\n.bm-row {\n display: flex;\n gap: 6px;\n align-items: center;\n flex-wrap: wrap;\n}\n.bm-row-split {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n.bm-error {\n color: var(--danger-ink);\n font-size: 12px;\n font-weight: 400;\n margin: 0;\n}\n.bm-warn {\n color: var(--warn-ink);\n font-size: 12px;\n margin: 0;\n}\n.bm-note {\n margin: 0;\n color: var(--bm-help);\n font-size: 13px;\n line-height: 1.55;\n font-weight: 400;\n}\n.bm-group + .bm-note,\n.bm-group-split + .bm-note {\n margin-top: -4px;\n}\n\n/* Switch: 36 x 20, knob 16 inset 2 */\n.bm-check {\n flex-direction: row;\n align-items: center;\n gap: 10px;\n font-weight: 500;\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"] {\n appearance: none;\n position: relative;\n flex: none;\n width: 36px;\n height: 20px;\n margin: 0;\n border-radius: 999px;\n background: var(--bm-switch-off);\n cursor: pointer;\n transition: background 0.15s;\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"]::before {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 1px 2px oklch(0 0 0 / 0.2);\n transition: transform 0.15s;\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"]:checked {\n background: var(--bm-primary);\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"]:checked::before {\n transform: translateX(16px);\n}\n.bm-popover .bm-check {\n color: var(--bm-label);\n font-size: 14px;\n}\n\n/* Buttons inside the sidebar */\n.bm-sidebar :where(button:not([role=\"tab\"]):not([role=\"radio\"]):not(.bm-resize)) {\n min-height: 32px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: var(--fill);\n color: var(--ink);\n font-size: 13px;\n font-weight: 500;\n}\n.bm-sidebar :where(button:not([role=\"tab\"]):not([role=\"radio\"]):not(.bm-resize)):hover:not(:disabled) {\n background: var(--fill-hover);\n}\n.bm-sidebar button:disabled {\n opacity: 0.45;\n cursor: default;\n}\n/* Dashed \"Add ...\" buttons: Add link, Add button, Add column, Add item */\n.bm-sidebar .bm-add {\n min-height: 44px;\n background: oklch(0.985 0.002 250);\n color: var(--bm-link);\n border: 1px dashed oklch(0.85 0.005 250);\n border-radius: 8px;\n}\n.bm-sidebar .bm-add:hover:not(:disabled) {\n background: var(--accent-tint);\n}\n\n/* Cards, lists, images */\n.bm-card {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n}\n.bm-card .bm-card {\n background: var(--bm-fill-nested);\n border-color: var(--line-soft);\n}\n.bm-card > .bm-label:first-child:not(:only-child) {\n font-family: var(--mono);\n font-size: 11px;\n letter-spacing: 0.04em;\n font-weight: 500;\n color: var(--muted);\n}\n.bm-card[draggable=\"true\"] {\n cursor: grab;\n}\n/* Drag and drop: the target shows what a drop would do. */\n.bm-dragging {\n opacity: 0.4;\n}\n.bm-drop-before,\n.bm-drop-after,\n.bm-drop-child {\n --drop: var(--accent);\n}\n.bm-drop-before::before,\n.bm-drop-after::before {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n height: 3px;\n border-radius: 3px;\n background: var(--drop);\n box-shadow: 0 0 0 2px var(--accent-ring);\n pointer-events: none;\n z-index: 2;\n}\n.bm-drop-before::before {\n top: -6px;\n}\n.bm-drop-after::before {\n bottom: -6px;\n}\n.bm-drop-child {\n box-shadow: inset 0 0 0 2px var(--drop);\n background: var(--accent-tint);\n}\n.bm-drop-before::after,\n.bm-drop-after::after,\n.bm-drop-child::after,\n.bm-drop-files::after {\n content: attr(data-drop-hint);\n position: absolute;\n right: 8px;\n padding: 3px 8px;\n border-radius: 6px;\n background: var(--ink);\n color: #fff;\n font-size: 11px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n pointer-events: none;\n z-index: 3;\n}\n.bm-drop-before::after {\n top: -22px;\n}\n.bm-drop-after::after {\n bottom: -22px;\n}\n.bm-drop-child::after {\n top: -11px;\n right: 12px;\n}\n.bm-drop-files {\n box-shadow: inset 0 0 0 2px var(--accent);\n background: var(--accent-tint);\n}\n.bm-drop-files::after {\n top: -11px;\n right: 12px;\n}\n.bm-thumb {\n width: 100%;\n height: 96px;\n object-fit: cover;\n border-radius: 7px;\n background: var(--fill);\n}\n.bm-drop {\n display: flex;\n flex-direction: column;\n gap: 8px;\n border: 1px dashed var(--line);\n border-radius: 10px;\n padding: 10px;\n background: var(--fill-soft);\n}\n.bm-drop input[type=\"file\"] {\n width: 100%;\n font-size: 12px;\n color: var(--muted);\n}\n.bm-drop input[type=\"file\"]::file-selector-button {\n height: 32px;\n margin-right: 10px;\n padding: 0 12px;\n border: 0;\n border-radius: 7px;\n background: var(--ink);\n color: #fff;\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n}\n.bm-alert {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px 14px;\n border-radius: 12px;\n background: var(--danger-tint);\n box-shadow: 0 0 0 1px oklch(0.55 0.18 25 / 0.35);\n}\n.bm-alert-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--danger-ink);\n}\n.bm-alert .bm-error {\n font-family: var(--mono);\n font-size: 11px;\n}\n.bm-alert-notice {\n background: var(--warn-tint);\n box-shadow: 0 0 0 1px oklch(0.45 0.09 65 / 0.2);\n}\n.bm-alert-notice .bm-note {\n color: var(--warn-ink);\n font-size: 12px;\n}\n\n/* Header actions */\n.bm-save {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 34px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: var(--accent);\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n}\n.bm-dialog .bm-primary kbd {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n margin-left: 8px;\n opacity: 0.8;\n}\n.bm-save kbd {\n font-family: var(--mono);\n font-size: 10px;\n font-weight: 400;\n opacity: 0.75;\n}\n/* Icon buttons: 32 x 32, transparent, grey icon, grey fill on hover. */\n.bm-icon-btn {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n min-height: 0 !important;\n padding: 0 !important;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--bm-icon);\n}\n.bm-icon-btn:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n.bm-icon-btn:disabled {\n opacity: 0.35;\n}\n.bm-close {\n width: 32px;\n height: 32px;\n background: transparent;\n color: var(--bm-icon);\n border-radius: 7px;\n}\n.bm-close:hover:not(:disabled) {\n background: var(--fill) !important;\n color: var(--ink);\n}\n.bm-dock .bm-save {\n font-family: var(--sans);\n}\n.bm-split {\n position: relative;\n display: inline-flex;\n flex: none;\n}\n.bm-split .bm-split-main {\n border-radius: 8px 0 0 8px;\n}\n.bm-split .bm-split-toggle {\n width: 28px;\n padding: 0;\n justify-content: center;\n border-radius: 0 8px 8px 0;\n box-shadow: inset 1px 0 0 oklch(1 0 0 / 0.35);\n}\n.bm-split .bm-split-toggle:focus-visible,\n.bm-split .bm-split-main:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n.bm-split-menu {\n position: absolute;\n z-index: 8;\n top: calc(100% + 6px);\n right: 0;\n min-width: 200px;\n display: flex;\n flex-direction: column;\n padding: 4px;\n border-radius: 10px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-split-menu button.bm-split-item {\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 34px;\n padding: 0 10px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--ink);\n font-family: var(--sans);\n font-size: 13px;\n font-weight: 500;\n text-align: left;\n}\n.bm-split-menu button.bm-split-item:hover:not(:disabled),\n.bm-split-menu button.bm-split-item:focus-visible {\n background: var(--fill);\n outline: none;\n}\n.bm-split-menu button.bm-split-danger {\n color: var(--danger-ink);\n}\n.bm-split-menu button.bm-split-item {\n justify-content: space-between;\n gap: 16px;\n}\n.bm-split-menu button.bm-split-item kbd {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--muted);\n}\n.bm-split-menu button.bm-split-sep {\n margin-top: 5px;\n position: relative;\n}\n.bm-split-menu button.bm-split-sep::before {\n content: \"\";\n position: absolute;\n left: 6px;\n right: 6px;\n top: -3px;\n height: 1px;\n background: var(--line);\n}\n.bm-split-menu button.bm-split-danger:hover:not(:disabled),\n.bm-split-menu button.bm-split-danger:focus-visible {\n background: var(--danger-tint);\n}\n.bm-split-menu button.bm-split-item:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.bm-sidebar .bm-icon-btn.bm-danger {\n color: var(--bm-danger-icon);\n}\n.bm-sidebar .bm-icon-btn.bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-small {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n min-height: 28px !important;\n padding: 0 10px !important;\n font-family: var(--sans);\n font-size: 12px !important;\n letter-spacing: 0;\n text-transform: none;\n align-self: flex-start;\n}\n.bm-group-split {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-top: 18px;\n margin-bottom: 0;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--bm-divider);\n}\n.bm-group-split:first-child {\n margin-top: 0;\n}\n.bm-group-split > .bm-group {\n margin: 0;\n padding: 0;\n border: 0;\n}\n.bm-group-split .bm-small {\n text-transform: none;\n letter-spacing: 0;\n}\n.bm-group-split span.bm-small {\n font-family: var(--mono);\n font-size: 11px !important;\n font-weight: 400;\n color: var(--bm-muted);\n padding: 0 !important;\n min-height: 0 !important;\n}\n.bm-stack-tight > .bm-group-split {\n margin-bottom: 10px;\n}\n\n/* Labels with a right-hand tag */\n.bm-label.bm-label-row,\n.bm-label-row {\n flex-direction: row;\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n}\n.bm-meta-tag {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0;\n color: var(--bm-muted);\n}\n\n/* Switch rows */\n.bm-switch-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n cursor: pointer;\n}\n.bm-switch-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.bm-switch-title {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n font-weight: 500;\n color: var(--bm-label);\n}\n\n/* Tone cards and segmented controls */\n.bm-tones {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 6px;\n}\n:is(.bm-sidebar, .bm-popover) .bm-tone {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 6px;\n min-height: 0;\n padding: 5px 5px 6px;\n border-radius: 9px;\n background: #fff;\n border: 0;\n box-shadow: inset 0 0 0 1px var(--bm-border);\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n}\n:is(.bm-sidebar, .bm-popover) .bm-tone:hover {\n background: var(--fill-soft);\n}\n:is(.bm-sidebar, .bm-popover) .bm-tone[aria-checked=\"true\"] {\n box-shadow: inset 0 0 0 2px var(--accent);\n background: #fff;\n}\n.bm-tones-2 {\n grid-template-columns: repeat(2, 1fr);\n}\n.bm-tones-3 {\n grid-template-columns: repeat(3, 1fr);\n}\n/* A miniature of each button look, drawn with the editor's colours so it does not depend on the site theme. */\n.bm-btnsample {\n display: grid;\n place-items: center;\n height: 26px;\n border-radius: 6px;\n background: var(--fill-soft);\n}\n.bm-btnsample > span {\n display: block;\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n}\n.bm-btnsample-default > span {\n color: var(--ink-2);\n}\n.bm-btnsample-primary > span {\n padding: 5px 12px;\n border-radius: 999px;\n background: var(--accent);\n color: #fff;\n}\n.bm-btnsample-secondary > span {\n padding: 5px 12px;\n border-radius: 999px;\n color: var(--ink);\n box-shadow: inset 0 0 0 1px var(--ink-2);\n}\n.bm-btnsample-tertiary > span {\n color: var(--accent);\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.bm-swatch {\n display: inline-block;\n flex: none;\n width: 10px;\n height: 10px;\n border-radius: 3px;\n box-shadow: inset 0 0 0 1px oklch(0.2 0.02 255 / 0.15);\n}\n.bm-swatch-lg {\n display: block;\n width: auto;\n height: 22px;\n border-radius: 6px;\n}\n.bm-swatch-base {\n background: #fff;\n}\n.bm-swatch-subtle {\n background: oklch(0.96 0.005 250);\n}\n.bm-swatch-inverse {\n background: var(--ink);\n}\n.bm-swatch-brand {\n background: var(--accent);\n}\n.bm-segmented {\n display: flex;\n padding: 3px;\n border-radius: 9px;\n background: var(--bm-fill);\n}\n.bm-sidebar .bm-segmented button,\n.bm-dialog .bm-segmented button {\n flex: 1;\n min-height: 36px;\n height: 36px;\n padding: 0 8px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: oklch(0.45 0.01 255);\n font-size: 13px;\n font-weight: 400;\n}\n.bm-sidebar .bm-segmented button:hover:not(:disabled),\n.bm-dialog .bm-segmented button:hover:not(:disabled) {\n background: oklch(1 0 0 / 0.5);\n}\n.bm-sidebar .bm-segmented button[aria-checked=\"true\"],\n.bm-dialog .bm-segmented button[aria-checked=\"true\"] {\n background: #fff;\n color: var(--ink);\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-icon-picker {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));\n gap: 4px;\n padding: 3px;\n border-radius: 9px;\n background: var(--bm-fill);\n}\n.bm-sidebar .bm-icon-picker button {\n display: grid;\n place-items: center;\n min-height: 40px;\n height: 40px;\n padding: 0;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: oklch(0.45 0.01 255);\n}\n.bm-sidebar .bm-icon-picker button:hover {\n background: oklch(1 0 0 / 0.5);\n color: var(--ink);\n}\n.bm-sidebar .bm-icon-picker button[aria-checked=\"true\"] {\n background: #fff;\n color: var(--accent);\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-icon-picker svg {\n width: 20px;\n height: 20px;\n}\n.bm-actions-split {\n display: flex;\n gap: 8px;\n padding-top: 4px;\n}\n.bm-actions-split button {\n flex: 1;\n min-height: 40px !important;\n font-size: 14px !important;\n}\n.bm-sidebar .bm-actions-split .bm-danger {\n background: var(--bm-danger-soft);\n}\n\n/* Arrays, links, images */\n.bm-array {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-array-item {\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n overflow: hidden;\n}\n.bm-array-item summary {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 44px;\n padding: 0 8px 0 10px;\n font-size: 14px;\n font-weight: 500;\n color: var(--ink);\n cursor: pointer;\n list-style: none;\n}\n.bm-array-item summary::-webkit-details-marker {\n display: none;\n}\n.bm-array-item summary:hover {\n background: var(--fill-soft);\n}\n.bm-array-summary {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-grip,\n.bm-chevron {\n display: inline-grid;\n place-items: center;\n color: oklch(0.65 0.01 255);\n}\n.bm-chevron {\n transition: transform 0.12s;\n}\ndetails[open] > summary .bm-chevron {\n transform: rotate(90deg);\n}\n.bm-array-body {\n display: flex;\n flex-direction: column;\n gap: 18px;\n padding: 12px;\n background: var(--bm-fill-nested);\n border-top: 1px solid var(--line-soft);\n}\n.bm-row-end {\n justify-content: flex-end;\n}\n.bm-sidebar .bm-add-row {\n width: 100%;\n}\n.bm-link-btn {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n min-height: 40px;\n padding: 0 12px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n text-align: left;\n color: var(--ink-2);\n}\n.bm-sidebar .bm-link-btn {\n background: #fff;\n border: 1px solid var(--bm-border);\n font-size: 14px;\n padding: 0 12px;\n}\n.bm-sidebar .bm-link-btn:hover:not(:disabled) {\n background: #fff;\n border-color: oklch(0.8 0.005 250);\n}\n.bm-link-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--ink);\n font-weight: 500;\n}\n.bm-link-href {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n max-width: 45%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-stripes {\n background: repeating-linear-gradient(135deg, oklch(0.93 0.004 250) 0 6px, oklch(0.965 0.003 250) 6px 12px);\n}\n\n/* Image field: label above, compact 56px row, alt text under it */\n.bm-imagefield {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-image-row {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n.bm-image-row .bm-thumb {\n flex: none;\n width: 56px;\n height: 56px;\n border-radius: 6px;\n}\n.bm-image-meta {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n justify-content: center;\n}\n.bm-image-path {\n font-family: var(--mono);\n font-size: 12px;\n color: var(--bm-label);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-sidebar .bm-alt {\n min-height: 40px;\n font-size: 14px;\n}\n.bm-image-actions {\n flex-wrap: nowrap;\n gap: 6px;\n}\n.bm-image-actions > button:not(.bm-icon-btn) {\n flex: 1;\n min-height: 36px;\n font-size: 13px;\n}\n.bm-layout {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding-top: 2px;\n}\n.bm-layout-row {\n display: grid;\n grid-template-columns: 56px 1fr;\n align-items: center;\n column-gap: 10px;\n row-gap: 4px;\n}\n.bm-layout-row .bm-label {\n margin: 0;\n}\n.bm-layout-row .bm-layout-hint {\n grid-column: 2;\n}\n.bm-position {\n display: grid;\n grid-template-columns: repeat(3, 20px);\n grid-template-rows: repeat(3, 20px);\n gap: 3px;\n padding: 4px;\n width: max-content;\n border-radius: 8px;\n background: var(--fill);\n}\n.bm-sidebar .bm-position-cell {\n width: 20px;\n height: 20px;\n min-height: 0;\n padding: 0;\n border: 0;\n border-radius: 5px;\n background: #fff;\n box-shadow: inset 0 0 0 1px var(--line);\n}\n.bm-sidebar .bm-position-cell:hover:not(:disabled) {\n background: var(--accent-tint);\n}\n.bm-sidebar .bm-position-cell[aria-checked=\"true\"],\n.bm-sidebar .bm-position-cell[aria-checked=\"true\"]:hover:not(:disabled) {\n background: var(--accent);\n box-shadow: none;\n}\n.bm-sidebar .bm-position-cell:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.bm-slot,\n.bm-dropzone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n width: 100%;\n min-height: 96px;\n padding: 14px;\n border: 1.5px dashed oklch(0.82 0.006 250);\n border-radius: 10px;\n background: var(--fill-soft);\n color: var(--ink-2);\n text-align: center;\n cursor: pointer;\n}\n.bm-sidebar .bm-slot:hover:not(:disabled),\n.bm-dropzone:hover {\n border-color: var(--accent);\n background: var(--accent-tint);\n}\n.bm-dropzone {\n min-height: 180px;\n position: relative;\n}\n.bm-dropzone:focus-within {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n.bm-dropzone-over {\n border-color: var(--accent);\n background: var(--accent-tint);\n}\n.bm-slot-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--ink);\n}\n.bm-slot-hint {\n font-size: 11px;\n color: var(--muted);\n}\n.bm-scrim {\n position: fixed;\n inset: 0;\n z-index: 7;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding: 10vh 16px 16px;\n background: oklch(0.2 0.01 255 / 0.4);\n}\n.bm-modal {\n display: flex;\n flex-direction: column;\n width: min(480px, 100%);\n max-height: min(560px, 80vh);\n overflow: hidden;\n padding: 20px 0 0;\n border-radius: 14px;\n background: #fff;\n box-shadow: var(--bm-shadow-dialog);\n}\n.bm-modal-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 0 20px 12px;\n}\n.bm-modal-head .bm-dialog-title {\n flex: none;\n}\n.bm-modal-head .bm-meta-tag {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-modal-head .bm-icon-btn {\n margin: -6px -8px -6px 0;\n}\n.bm-modal .bm-tabs {\n margin: 0 20px;\n padding: 3px;\n gap: 0;\n border: 0;\n border-radius: 9px;\n background: var(--bm-fill);\n overflow: visible;\n}\n.bm-modal .bm-tabs button {\n flex: 1;\n height: 36px;\n min-height: 36px;\n padding: 0 8px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 400;\n}\n.bm-modal .bm-tabs button:hover {\n background: oklch(1 0 0 / 0.5);\n}\n.bm-modal .bm-tabs button[aria-selected=\"true\"] {\n background: #fff;\n color: var(--ink);\n font-weight: 500;\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-modal-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 16px 20px 20px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.bm-library {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 10px;\n}\n.bm-library-item {\n position: relative;\n}\n.bm-library-pick {\n display: flex;\n flex-direction: column;\n gap: 4px;\n width: 100%;\n min-height: 0;\n padding: 4px;\n border: 0;\n border-radius: 9px;\n background: var(--fill-soft);\n text-align: left;\n font-family: var(--mono);\n font-size: 9px;\n font-weight: 400;\n color: var(--muted);\n word-break: break-all;\n cursor: pointer;\n}\n.bm-library-pick:hover {\n background: var(--fill-hover);\n}\n.bm-library-pick img {\n width: 100%;\n aspect-ratio: 1 / 1;\n object-fit: cover;\n border-radius: 6px;\n background: var(--fill);\n}\n.bm-library-pick[aria-pressed=\"true\"] {\n box-shadow: 0 0 0 2px var(--accent);\n background: var(--accent-tint);\n}\n.bm-library-delete {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 24px;\n height: 24px;\n min-height: 0;\n background: #fff;\n box-shadow: 0 1px 3px oklch(0.2 0.01 255 / 0.25);\n opacity: 0;\n}\n.bm-library-item:hover .bm-library-delete,\n.bm-library-delete:focus-visible {\n opacity: 1;\n}\n.bm-library-empty {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n}\n.bm-modal-confirm {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px 20px 16px;\n border-top: 1px solid var(--line-soft);\n background: var(--danger-tint);\n}\n.bm-modal-confirm .bm-note {\n color: var(--danger-ink);\n font-size: 13px;\n line-height: 1.5;\n}\n.bm-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n border: 0;\n white-space: nowrap;\n}\n.bm-popover-title {\n grid-column: 1 / -1;\n padding: 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--bm-ink);\n}\n.bm-popover-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0;\n}\n.bm-popover-head-wide {\n grid-column: 1 / -1;\n}\n.bm-popover[aria-label=\"Edit link\"],\n.bm-popover[aria-label=\"Add section\"][role=\"listbox\"] {\n z-index: 5;\n}\n.bm-popover :is(.bm-fmt-bold) {\n font-weight: 700;\n}\n.bm-fmt-bold {\n font-weight: 700;\n font-size: 13px;\n}\n.bm-fmt-italic {\n font-family: var(--serif);\n font-style: italic;\n font-size: 15px;\n}\n\n/* Edit link: Advanced row */\n.bm-advanced {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.bm-popover button.bm-advanced-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n min-height: 32px;\n padding: 0 2px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: var(--bm-label);\n font-size: 13px;\n font-weight: 500;\n text-align: left;\n}\n.bm-popover button.bm-advanced-toggle:hover {\n background: transparent;\n color: var(--bm-ink);\n}\n.bm-advanced-toggle .bm-chevron {\n transition: transform 0.12s;\n}\n.bm-advanced-toggle[aria-expanded=\"true\"] .bm-chevron {\n transform: rotate(90deg);\n}\n.bm-advanced-summary {\n margin-left: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--bm-muted);\n}\n\n/* SEO card and dialog */\n.bm-seo-card {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.bm-seo-badges {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.bm-seo-badge {\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--fill-soft);\n color: var(--bm-label);\n font-family: var(--mono);\n font-size: 11px;\n}\n.bm-seo-edit,\n.bm-consent-edit {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.bm-dialog.bm-seo {\n position: relative;\n width: min(560px, 100%);\n max-height: calc(100vh - 10vh - 32px);\n min-height: 0;\n}\n.bm-seo-body {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-height: 0;\n overflow-y: auto;\n padding: 2px 4px 2px 2px;\n}\n.bm-seo-json {\n min-height: 220px;\n white-space: pre;\n overflow: auto;\n tab-size: 2;\n}\n.bm-seo-json[aria-invalid=\"true\"] {\n border-color: var(--bm-danger);\n}\n.bm-seo-format {\n align-self: flex-start;\n}\n\n/* Cookie banner dialog */\n.bm-dialog.bm-consent {\n position: relative;\n width: min(520px, 100%);\n max-height: calc(100vh - 10vh - 32px);\n min-height: 0;\n}\n.bm-consent-body {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-height: 0;\n overflow-y: auto;\n padding: 2px 4px 2px 2px;\n}\n.bm-consent-preview {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--fill-soft);\n}\n.bm-consent-preview-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--bm-label);\n}\n.bm-consent-preview-text {\n margin: 0;\n font-size: 13px;\n line-height: 1.45;\n color: var(--bm-muted);\n overflow-wrap: anywhere;\n}\n.bm-consent-preview-link {\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.bm-consent-preview-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n.bm-consent-preview-buttons > span {\n padding: 5px 14px;\n border-radius: 999px;\n box-shadow: inset 0 0 0 1px var(--bm-border);\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n}\n\n/* SEO preview, OG row, outline */\n.bm-serp {\n display: flex;\n flex-direction: column;\n gap: 3px;\n padding: 12px 14px;\n border-radius: 10px;\n background: var(--fill-soft);\n}\n.bm-serp-image {\n flex-direction: row;\n align-items: flex-start;\n gap: 12px;\n}\n.bm-serp-text {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n.bm-serp-thumb {\n flex: none;\n width: 64px;\n height: 64px;\n border-radius: 8px;\n object-fit: cover;\n background: var(--fill);\n}\n.bm-serp-title {\n font-size: 15px;\n font-weight: 500;\n color: oklch(0.42 0.12 260);\n}\n.bm-serp-url {\n font-family: var(--mono);\n font-size: 11px;\n color: oklch(0.45 0.08 145);\n}\n.bm-serp-desc {\n font-size: 12px;\n line-height: 1.45;\n color: oklch(0.45 0.01 255);\n}\n.bm-outline-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.bm-sidebar .bm-outline-row {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n min-height: 40px;\n padding: 0 10px;\n border-radius: 8px;\n background: transparent;\n text-align: left;\n font-size: 14px;\n}\n.bm-sidebar .bm-outline-row:hover:not(:disabled) {\n background: var(--fill-soft);\n}\n\n/* Section rows (Pages tab): grip, tone swatch, name over #anchor and variant, then actions. */\n.bm-srow {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n min-height: 52px;\n padding: 6px 6px 6px 8px;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n}\n.bm-srow:hover {\n border-color: oklch(0.8 0.008 250);\n}\n.bm-srow-grip {\n flex: none;\n width: 16px;\n height: 32px;\n display: inline-grid;\n place-items: center;\n cursor: grab;\n touch-action: none;\n}\n.bm-srow-grip:active {\n cursor: grabbing;\n}\n.bm-srow .bm-outline-row {\n flex: 1;\n min-width: 0;\n width: auto;\n padding: 0 8px 0 4px;\n gap: 10px;\n}\n.bm-srow .bm-swatch {\n width: 10px;\n height: 10px;\n border-radius: 2px;\n}\n.bm-srow-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n.bm-srow-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--bm-ink);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-srow-meta {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--bm-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-srow .bm-outline-meta {\n flex: none;\n max-width: 40%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-srow-btn {\n width: 32px;\n height: 32px;\n background: transparent;\n color: var(--bm-icon);\n border-radius: 7px;\n}\n.bm-srow-btn:disabled {\n opacity: 0.35;\n}\n.bm-sidebar .bm-srow-btn:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n.bm-sidebar .bm-srow-btn.bm-danger {\n color: var(--bm-danger-icon);\n}\n.bm-sidebar .bm-srow-btn.bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n}\n.bm-srow-sep {\n flex: none;\n width: 1px;\n height: 20px;\n margin: 0 2px;\n background: var(--bm-divider);\n}\n.bm-outline-n {\n width: 18px;\n font-family: var(--mono);\n font-size: 11px;\n color: oklch(0.55 0.01 255);\n}\n.bm-outline-label {\n flex: 1;\n min-width: 0;\n font-weight: 500;\n}\n.bm-outline-meta {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--muted);\n}\n\n/* Navigation and footer link cards */\n.bm-nav-card {\n padding: 12px 12px 14px;\n gap: 10px;\n}\n.bm-nested {\n margin: 6px 0 0 16px;\n}\n.bm-nav-children {\n margin-top: -4px;\n}\n.bm-nav-head {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.bm-nav-head .bm-icon-btn,\n.bm-column-head .bm-icon-btn {\n background: var(--bm-fill);\n color: oklch(0.45 0.01 255);\n}\n.bm-nav-head .bm-icon-btn:hover:not(:disabled),\n.bm-column-head .bm-icon-btn:hover:not(:disabled) {\n background: var(--bm-fill-hover);\n color: var(--bm-ink);\n}\n.bm-sidebar .bm-nav-head .bm-icon-btn.bm-danger,\n.bm-sidebar .bm-column-head .bm-icon-btn.bm-danger {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-sidebar .bm-nav-label {\n flex: 1;\n min-width: 0;\n min-height: 32px;\n padding: 0 8px;\n border-color: transparent;\n font-weight: 500;\n}\n.bm-sidebar .bm-nav-label:hover {\n border-color: var(--line);\n}\n.bm-column {\n padding: 0;\n gap: 0;\n}\n.bm-column-head {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px;\n cursor: grab;\n}\n.bm-column-links > summary {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 40px;\n padding: 0 12px;\n border-top: 1px solid var(--line-soft);\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n cursor: pointer;\n list-style: none;\n}\n.bm-column-links > summary::-webkit-details-marker {\n display: none;\n}\n.bm-column-links > :not(summary) {\n margin: 10px 12px 0;\n}\n.bm-column-links > :last-child {\n margin-bottom: 12px;\n}\n\n/* Wordmark preview */\n.bm-card-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.bm-card-head .bm-label {\n flex: none;\n}\n.bm-combo {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n:is(.bm-sidebar, .bm-popover) .bm-combo-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n width: auto;\n max-width: 140px;\n min-height: 38px;\n padding: 0 10px 0 12px;\n border: 0;\n border-left: 1px solid var(--bm-border);\n border-radius: 0;\n background: var(--fill-soft);\n color: var(--ink-2);\n font-family: var(--mono);\n font-size: 12px;\n font-weight: 400;\n text-align: left;\n}\n:is(.bm-sidebar, .bm-popover) .bm-combo-trigger:hover:not(:disabled) {\n background: var(--fill-hover);\n}\n:is(.bm-sidebar, .bm-popover) .bm-combo-trigger[aria-expanded=\"true\"] {\n background: var(--accent-tint);\n color: var(--accent-hover);\n}\n/* One URL field: the text input and the page picker share a single border. */\n.bm-linkfield {\n display: flex;\n align-items: stretch;\n min-height: 40px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n overflow: hidden;\n}\n.bm-linkfield:focus-within {\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px var(--bm-primary-ring);\n}\n.bm-linkfield > input {\n flex: 1;\n min-width: 0;\n border: 0 !important;\n box-shadow: none !important;\n border-radius: 0;\n min-height: 38px;\n background: transparent;\n}\n.bm-linkfield .bm-combo {\n flex: none;\n max-width: 45%;\n}\n.bm-linkfield .bm-combo-trigger {\n height: 100%;\n}\n.bm-linkfield .bm-combo-trigger:focus-visible {\n outline-offset: -2px;\n}\n.bm-combo-trigger > span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-combo-trigger .bm-combo-custom {\n color: var(--muted);\n}\n.bm-combo-panel {\n position: fixed;\n z-index: 6;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 6px;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n box-shadow: 0 6px 18px oklch(0.2 0.02 255 / 0.1);\n}\n.bm-combo-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n.bm-combo-group {\n margin: 6px 6px 2px;\n font-family: var(--mono);\n font-size: 10px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--muted);\n}\n.bm-combo-option {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 10px;\n padding: 6px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--ink);\n cursor: pointer;\n}\n.bm-combo-option[aria-selected=\"true\"] {\n font-weight: 600;\n color: var(--accent-hover);\n}\n.bm-combo-active {\n background: var(--fill);\n}\n.bm-combo-value {\n flex: none;\n max-width: 50%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n}\n.bm-combo-empty {\n margin: 0;\n padding: 8px;\n font-size: 12px;\n color: var(--muted);\n}\n.bm-format {\n margin-top: -4px;\n}\n.bm-sidebar .bm-format button[aria-pressed=\"true\"] {\n background: #fff;\n color: var(--ink);\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-wordmark {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 14px;\n border-radius: 10px;\n background: var(--bm-fill-soft);\n}\n.bm-wordmark-name {\n font-size: 24px;\n font-weight: 600;\n letter-spacing: -0.03em;\n}\n.bm-alert-notice {\n flex-direction: row;\n align-items: flex-start;\n gap: 8px;\n color: var(--warn-ink);\n}\n.bm-alert-notice .bm-icon {\n margin-top: 2px;\n flex: none;\n}\n\n/*\n * Button system. Three variants, one danger modifier, one rule set.\n * secondary (default): neutral fill, ink text.\n * .bm-primary: the one main action of a surface. Solid accent, white text (AA).\n * .bm-tertiary: low emphasis text button (Cancel, Reset). No fill, no underline, grey fill on hover.\n * .bm-danger: modifier. primary = solid red, secondary = red text, tertiary = red text.\n * The scope list gives every rule enough specificity to beat the per-surface defaults above,\n * so the hover state of one variant can never fall back to the secondary fill.\n */\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button:where(.bm-primary, .bm-tertiary, .bm-danger):not(.bm-icon-btn, .bm-save) {\n transition:\n background-color 0.12s,\n color 0.12s;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary {\n background: var(--bm-primary);\n color: #fff;\n box-shadow: none;\n font-weight: 600;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary:hover:not(:disabled) {\n background: var(--bm-primary-hover);\n color: #fff;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary.bm-danger {\n background: var(--bm-danger);\n color: #fff;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary.bm-danger:hover:not(:disabled) {\n background: var(--danger-hover);\n color: #fff;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-danger:not(.bm-primary, .bm-tertiary, .bm-icon-btn) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-danger:not(.bm-primary, .bm-tertiary, .bm-icon-btn):hover:not(:disabled) {\n background: oklch(0.93 0.04 25);\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary {\n min-height: 32px;\n padding: 0 10px;\n border-radius: 8px;\n background: transparent;\n color: var(--bm-label);\n font-weight: 400;\n box-shadow: none;\n text-decoration: none;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal) button.bm-tertiary {\n min-height: 38px;\n font-size: 14px;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary.bm-danger {\n background: transparent;\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary.bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.bm-save:hover:not(:disabled) {\n background: var(--accent-hover);\n color: #fff;\n}\n.bm-sidebar .bm-save:hover:not(:disabled) {\n background: var(--accent-hover);\n color: #fff;\n}\n.bm-popover .bm-actions-remove,\n.bm-dialog .bm-actions-remove {\n margin-right: auto;\n}\n.bm-modal :where(button:not([role=\"tab\"], .bm-library-pick, .bm-icon-btn, .bm-tertiary)) {\n min-height: 38px;\n padding: 0 16px;\n border: 0;\n border-radius: 8px;\n background: var(--fill);\n color: var(--ink);\n font-size: 14px;\n font-weight: 400;\n}\n.bm-modal :where(button:not([role=\"tab\"], .bm-library-pick, .bm-icon-btn, .bm-tertiary)):hover:not(:disabled) {\n background: var(--fill-hover);\n}\n.bm-modal .bm-dropzone {\n font-family: var(--sans);\n}\n\n/* Design tab */\n.bm-colorrow {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.bm-colorpick {\n flex: none;\n width: 40px !important;\n height: 40px;\n min-height: 40px !important;\n padding: 2px !important;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n cursor: pointer;\n}\n.bm-colorhex {\n flex: 1;\n min-width: 0;\n font-family: var(--mono);\n font-size: 13px;\n text-transform: lowercase;\n}\n.bm-colorhex[aria-invalid=\"true\"] {\n border-color: var(--bm-danger);\n}\n.bm-overrides {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n overflow: hidden;\n}\n.bm-override-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 10px 8px 12px;\n}\n.bm-override-row + .bm-override-row {\n border-top: 1px solid var(--bm-divider);\n}\n.bm-override-label {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n}\n.bm-override-label .bm-meta-tag {\n font-size: 10px;\n}\n.bm-override-row .bm-colorpick {\n width: 32px !important;\n height: 32px;\n min-height: 32px !important;\n padding: 1px !important;\n border-radius: 7px;\n}\n.bm-override-row .bm-colorhex {\n flex: none;\n width: 104px;\n min-height: 36px;\n padding: 0 10px;\n}\n.bm-tone-matrix {\n display: grid;\n grid-template-columns: 60px minmax(0, 1fr) minmax(0, 1fr);\n gap: 8px;\n align-items: stretch;\n}\n.bm-tone-pick {\n border: 0;\n text-align: left;\n font: inherit;\n cursor: pointer;\n}\n.bm-tone-cell[aria-pressed=\"true\"] {\n outline: 2px solid var(--bm-primary);\n outline-offset: 0;\n}\n.bm-tone-head {\n font-family: var(--mono);\n font-size: 10px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--muted);\n}\n.bm-tone-name {\n align-self: center;\n font-size: 12px;\n font-weight: 500;\n color: var(--ink-2);\n}\n.bm-tone-cell {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n min-width: 0;\n min-height: 46px;\n padding: 0 10px;\n border-radius: 8px;\n overflow: hidden;\n white-space: nowrap;\n}\n.bm-tone-aa {\n flex: none;\n font-size: 16px;\n font-weight: 600;\n}\n.bm-tone-muted {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 11px;\n}\n.bm-tone-chip {\n flex: none;\n padding: 2px 6px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n}\n.bm-tone-link {\n flex: none;\n font-size: 11px;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.bm-contrast-list {\n margin: 6px 0 0;\n padding-left: 16px;\n font-family: var(--mono);\n font-size: 11px;\n color: var(--warn-ink);\n}\n.bm-range {\n flex: 1;\n min-width: 0;\n min-height: 28px;\n accent-color: var(--accent);\n cursor: pointer;\n}\n/* Preview: the only editor UI left on screen. */\n.bm-exit-preview {\n position: fixed;\n z-index: 7;\n right: 16px;\n bottom: 16px;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 40px;\n padding: 0 16px;\n border: 0;\n border-radius: 999px;\n background: var(--ink);\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n box-shadow: 0 10px 30px oklch(0.2 0.02 255 / 0.3);\n}\n.bm-exit-preview:hover {\n background: oklch(0.28 0.012 255);\n}\n.bm-exit-preview:focus-visible {\n outline-color: oklch(0.82 0.14 145);\n outline-offset: 3px;\n}\n.bm-srow-add {\n display: flex;\n justify-content: flex-end;\n padding-top: 6px;\n}\n.bm-sidebar .bm-add-section {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-height: 32px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: var(--bm-primary);\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-sidebar .bm-add-section:hover {\n background: var(--bm-primary-hover);\n}\n";
20591
+ var editor_default = "/*\n * Editor styles. They live in a shadow root, so they never meet the site's Tailwind layer.\n * The editor is always light. Tokens and values follow the v4 editor design handoff.\n * The short names (--ink, --line, --accent ...) alias the --bm-* tokens so older rules read the same.\n */\n:host {\n all: initial;\n\n /* ---------- v4 tokens (editor-tokens.css) ---------- */\n --bm-font-ui: \"Bricolage Grotesque Variable\", \"Bricolage Grotesque\", ui-sans-serif, system-ui, sans-serif;\n --bm-font-mono: \"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace;\n --bm-font-serif: \"Instrument Serif\", Georgia, serif;\n\n --bm-ink: oklch(0.21 0.012 255);\n --bm-label: oklch(0.3 0.01 255);\n --bm-section: oklch(0.42 0.01 255);\n --bm-help: oklch(0.47 0.01 255);\n --bm-muted: oklch(0.5 0.01 255);\n --bm-icon: oklch(0.55 0.01 255);\n --bm-info: oklch(0.6 0.01 255);\n\n --bm-fill: oklch(0.955 0.003 250);\n --bm-fill-hover: oklch(0.93 0.004 250);\n --bm-fill-soft: oklch(0.965 0.003 250);\n --bm-fill-nested: oklch(0.97 0.003 250);\n --bm-border: oklch(0.88 0.005 250);\n --bm-divider: oklch(0.93 0.004 250);\n --bm-tab-rule: oklch(0.92 0.004 250);\n\n --bm-primary: oklch(0.46 0.13 145);\n --bm-primary-hover: oklch(0.4 0.12 145);\n --bm-primary-ring: oklch(0.46 0.13 145 / 0.15);\n --bm-link: oklch(0.4 0.12 145);\n\n --bm-saved-bg: oklch(0.94 0.045 145);\n --bm-saved-fg: oklch(0.36 0.1 145);\n --bm-unsaved-bg: oklch(0.95 0.05 80);\n --bm-unsaved-fg: oklch(0.48 0.1 60);\n --bm-unsaved-dot: oklch(0.75 0.15 70);\n --bm-badge-green-bg: oklch(0.93 0.06 145);\n --bm-badge-green-fg: oklch(0.38 0.1 145);\n --bm-badge-amber-bg: oklch(0.95 0.04 75);\n --bm-badge-amber-fg: oklch(0.45 0.09 60);\n\n --bm-danger: oklch(0.55 0.19 25);\n --bm-danger-text: oklch(0.52 0.17 25);\n --bm-danger-icon: oklch(0.58 0.18 25);\n --bm-danger-soft: oklch(0.96 0.025 20);\n\n --bm-diff-del-bg: oklch(0.97 0.02 20);\n --bm-diff-del-fg: oklch(0.45 0.13 25);\n --bm-diff-add-bg: oklch(0.96 0.04 145);\n --bm-diff-add-fg: oklch(0.34 0.1 145);\n\n --bm-switch-off: oklch(0.82 0.005 250);\n\n --bm-shadow-pop: 0 0 0 1px oklch(0.9 0.005 250), 0 16px 36px -16px oklch(0.2 0.02 255 / 0.35);\n --bm-shadow-dialog: 0 0 0 1px oklch(0.9 0.005 250), 0 24px 48px -24px oklch(0.2 0.02 255 / 0.35);\n --bm-shadow-segment-on: 0 1px 2px oklch(0 0 0 / 0.08), 0 0 0 1px oklch(0.9 0.005 250);\n\n /* ---------- aliases used by the rules below ---------- */\n --ink: var(--bm-ink);\n --ink-2: var(--bm-label);\n --muted: var(--bm-muted);\n --line: var(--bm-border);\n --line-soft: var(--bm-divider);\n --fill: var(--bm-fill);\n --fill-hover: var(--bm-fill-hover);\n --fill-soft: var(--bm-fill-soft);\n --accent: var(--bm-primary);\n --accent-hover: var(--bm-primary-hover);\n --accent-tint: oklch(0.96 0.03 145);\n --accent-ring: var(--bm-primary-ring);\n --warn-tint: var(--bm-unsaved-bg);\n --warn-ink: var(--bm-unsaved-fg);\n --warn-dot: var(--bm-unsaved-dot);\n --danger-hover: oklch(0.48 0.18 25);\n --danger-tint: var(--bm-danger-soft);\n --danger-ink: var(--bm-danger-text);\n --info-dot: oklch(0.6 0.15 255);\n --sans: var(--bm-font-ui);\n --mono: var(--bm-font-mono);\n --serif: var(--bm-font-serif);\n --shadow-pop: var(--bm-shadow-pop);\n}\n* {\n box-sizing: border-box;\n}\nbutton,\ninput,\nselect,\ntextarea {\n font: inherit;\n color: inherit;\n}\nbutton {\n cursor: pointer;\n}\n:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n\n/* On-page outlines */\n.bm-outline {\n position: fixed;\n pointer-events: none;\n border-radius: 6px;\n z-index: 1;\n}\n.bm-outline-section {\n border: 2px solid var(--accent);\n}\n.bm-outline-field {\n border: 2px solid var(--accent);\n background: oklch(0.46 0.13 145 / 0.08);\n}\n.bm-image-bar {\n flex-wrap: nowrap;\n left: auto;\n white-space: nowrap;\n}\n.bm-image-bar-group {\n display: flex;\n gap: 2px;\n}\n.bm-image-bar button[aria-pressed=\"true\"] {\n background: var(--bm-saved-bg);\n color: var(--bm-saved-fg);\n}\n.bm-image-bar-grid {\n display: grid;\n grid-template-columns: repeat(3, 9px);\n grid-template-rows: repeat(3, 9px);\n gap: 2px;\n align-self: center;\n padding: 0 4px;\n}\n.bm-image-bar .bm-pos-cell {\n width: 9px;\n height: 9px;\n /* `.bm-rich button` sets a 32px minimum for the bar's text buttons; the cells stay 9px. */\n min-width: 0;\n min-height: 0;\n padding: 0;\n border-radius: 2px;\n background: var(--line);\n}\n.bm-image-bar .bm-pos-cell:hover:not(:disabled) {\n background: var(--muted);\n}\n.bm-image-bar .bm-pos-cell[aria-pressed=\"true\"] {\n background: var(--accent);\n}\n.bm-image-bar .bm-pos-cell:disabled {\n opacity: 0.3;\n cursor: default;\n}\n.bm-outline-image {\n background: oklch(0.46 0.13 145 / 0.12);\n}\n.bm-outline-image::after {\n content: \"Change image\";\n position: absolute;\n top: 8px;\n left: 8px;\n padding: 4px 9px;\n border-radius: 6px;\n background: var(--accent);\n color: #fff;\n font: 500 11px / 1.3 var(--sans, system-ui, sans-serif);\n}\n\n.bm-toolbar,\n.bm-dock,\n.bm-exit-preview,\n.bm-sidebar,\n.bm-popover,\n.bm-dialog,\n.bm-rich,\n.bm-banner,\n.bm-scrim {\n pointer-events: auto;\n font-family: var(--sans);\n font-size: 13px;\n color: var(--ink);\n -webkit-font-smoothing: antialiased;\n}\n\n/*\n * Insert between sections. Three states:\n * idle / hover a solid line and a 28px circle; hover changes nothing.\n * open the picker is open: the line stays and a \"between A and B\" chip replaces the circle.\n */\n.bm-gap {\n position: fixed;\n z-index: 2;\n height: 0;\n pointer-events: none;\n}\n.bm-gap::before {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n height: 0;\n border-top: 2px solid var(--bm-primary);\n transform: translateY(-50%);\n}\n.bm-gap-add {\n position: absolute;\n left: 50%;\n top: 0;\n transform: translate(-50%, -50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 999px;\n pointer-events: auto;\n cursor: pointer;\n white-space: nowrap;\n background: var(--bm-primary);\n color: #fff;\n box-shadow: 0 0 0 2px #fff;\n}\n.bm-gap-add .bm-icon {\n width: 14px;\n height: 14px;\n stroke-width: 2.4;\n}\n.bm-gap-add:focus-visible {\n outline: 2px solid var(--ink);\n outline-offset: 3px;\n}\n.bm-gap-chip {\n position: absolute;\n left: 50%;\n top: 0;\n transform: translate(-50%, -50%);\n padding: 4px 10px;\n border-radius: 999px;\n background: #fff;\n color: var(--bm-ink);\n box-shadow: 0 0 0 1.5px var(--bm-primary);\n white-space: nowrap;\n pointer-events: none;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* Light floating bars: section toolbar, rich text bar, heading format bar */\n.bm-toolbar,\n.bm-rich {\n position: fixed;\n z-index: 3;\n display: flex;\n gap: 2px;\n padding: 4px;\n border-radius: 12px;\n background: #fff;\n color: var(--ink);\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-toolbar button,\n.bm-rich button {\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: inherit;\n min-height: 32px;\n padding: 0 10px;\n font-size: 12px;\n font-weight: 500;\n}\n.bm-toolbar button:hover:not(:disabled),\n.bm-rich button:hover {\n background: var(--fill);\n}\n.bm-rich button[aria-pressed=\"true\"] {\n background: var(--bm-saved-bg);\n box-shadow: inset 0 0 0 1px oklch(0.46 0.13 145 / 0.4);\n}\n.bm-toolbar :focus-visible,\n.bm-rich :focus-visible {\n outline-color: var(--accent);\n}\n.bm-toolbar {\n align-items: center;\n max-width: calc(100vw - 16px);\n padding: 5px;\n}\n.bm-toolbar button {\n width: 34px;\n min-height: 34px;\n height: 34px;\n padding: 0;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: oklch(0.4 0.01 255);\n}\n.bm-toolbar button:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n.bm-toolbar button:disabled {\n opacity: 0.35;\n cursor: default;\n}\n.bm-toolbar .bm-danger {\n color: var(--bm-danger-icon);\n}\n.bm-toolbar .bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-toolbar-active {\n box-shadow:\n 0 0 0 2px var(--bm-primary),\n 0 10px 24px -12px oklch(0.2 0.02 255 / 0.35);\n}\n.bm-toolbar-name {\n display: block;\n max-width: 16rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 12px 0 10px;\n}\n.bm-toolbar-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--bm-ink);\n}\n.bm-toolbar-anchor {\n font-family: var(--mono);\n font-size: 12px;\n font-weight: 400;\n color: var(--bm-muted);\n}\n.bm-sep {\n width: 1px;\n align-self: stretch;\n margin: 4px 2px;\n background: var(--line);\n}\n.bm-toolbar .bm-sep {\n align-self: center;\n height: 20px;\n margin: 0 4px;\n background: oklch(0.9 0.005 250);\n}\n.bm-icon {\n width: 16px;\n height: 16px;\n display: block;\n}\n.bm-rich {\n align-items: center;\n flex-wrap: wrap;\n max-width: calc(100vw - 16px);\n}\n.bm-rich button {\n min-height: 32px;\n min-width: 32px;\n}\n.bm-rich input {\n width: 168px;\n min-height: 30px;\n padding: 0 8px;\n border: 0;\n border-radius: 7px;\n background: var(--fill);\n color: var(--ink);\n font-size: 12px;\n}\n.bm-rich input:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--accent);\n}\n\n/* Heading format bar: each button shows \"Aa\" in its own weight or font over a mono caption. */\n.bm-rich.bm-format-bar {\n flex-wrap: nowrap;\n}\n.bm-rich.bm-format-bar button.bm-fmt {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n min-width: 42px;\n height: 48px;\n min-height: 48px;\n padding: 0 8px;\n border-radius: 8px;\n}\n.bm-fmt-sample {\n font-size: 15px;\n line-height: 1;\n color: var(--bm-ink);\n}\n.bm-fmt-caption {\n font-family: var(--mono);\n font-size: 9px;\n letter-spacing: 0.02em;\n color: var(--bm-muted);\n}\n.bm-rich.bm-format-bar button.bm-fmt[aria-pressed=\"true\"] {\n background: var(--bm-saved-bg);\n box-shadow: inset 0 0 0 1px oklch(0.46 0.13 145 / 0.4);\n}\n.bm-format-bar .bm-sep {\n align-self: stretch;\n margin: 6px 4px;\n}\n\n/* Light popovers: add menu, section picker, edit link */\n.bm-popover {\n position: fixed;\n z-index: 3;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n max-height: min(420px, calc(100vh - 16px));\n overflow: auto;\n padding: 6px;\n border-radius: 12px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-popover > button {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 34px;\n padding: 0 10px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n text-align: left;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-popover > button:hover {\n background: var(--fill);\n}\n\n/* Add section picker: wireframe cards */\n.bm-popover[aria-label=\"Add section\"][role=\"listbox\"] {\n gap: 14px;\n width: 640px;\n max-width: calc(100vw - 16px);\n max-height: calc(100vh - 16px);\n padding: 16px;\n border-radius: 14px;\n overflow: visible;\n box-shadow: var(--bm-shadow-dialog);\n}\n.bm-picker-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.bm-picker-title {\n font-size: 17px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n.bm-picker-where {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n color: var(--bm-muted);\n}\n.bm-picker-grid {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n max-height: 26rem;\n overflow-y: auto;\n padding: 2px 6px 2px 2px;\n margin-right: -6px;\n scrollbar-gutter: stable;\n}\n.bm-popover .bm-picker-grid > button {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: flex-start;\n gap: 6px;\n min-height: 0;\n padding: 8px 8px 10px;\n border: 1px solid oklch(0.9 0.005 250);\n border-radius: 10px;\n background: #fff;\n text-align: left;\n font-weight: 400;\n}\n.bm-popover .bm-picker-grid > button:hover {\n background: #fff;\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px oklch(0.46 0.13 145 / 0.12);\n}\n.bm-wire {\n position: relative;\n display: block;\n width: 100%;\n height: 76px;\n border-radius: 7px;\n background: oklch(0.97 0 0);\n overflow: hidden;\n}\n.bm-wire > span {\n position: absolute;\n display: block;\n}\n.bm-type-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 0 2px;\n}\n.bm-type-name {\n font-size: 14px;\n font-weight: 600;\n line-height: 1.25;\n color: var(--bm-ink);\n}\n.bm-type-variants {\n font-family: var(--mono);\n font-size: 10px;\n font-weight: 400;\n line-height: 1.35;\n white-space: nowrap;\n color: var(--muted);\n}\n.bm-type-desc {\n padding: 0 2px;\n font-size: 12px;\n line-height: 1.4;\n color: var(--bm-help);\n}\n.bm-picker-note {\n margin: 0;\n font-size: 12px;\n color: var(--bm-muted);\n}\n\n.bm-popover[aria-label=\"Edit link\"] {\n gap: 14px;\n padding: 16px;\n max-height: calc(100vh - 16px);\n}\n\n/* Dialogs and banners */\n.bm-dialog {\n position: fixed;\n z-index: 6;\n display: flex;\n flex-direction: column;\n gap: 16px;\n width: min(400px, calc(100vw - 32px));\n padding: 20px;\n border-radius: 14px;\n background: #fff;\n box-shadow: var(--bm-shadow-dialog);\n}\n.bm-dialog-head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n}\n.bm-dialog-heading {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.bm-dialog-sub {\n margin: 0;\n font-size: 13px;\n line-height: 1.4;\n color: var(--bm-help);\n}\n.bm-dialog .bm-dialog-x,\n.bm-popover .bm-dialog-x,\n.bm-modal .bm-dialog-x {\n flex: none;\n width: 32px;\n height: 32px;\n margin: -6px -8px -6px 0;\n background: transparent;\n color: var(--bm-icon);\n}\n.bm-dialog-title {\n margin: 0;\n font-size: 17px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--bm-ink);\n}\n.bm-popover .bm-dialog-title {\n font-size: 16px;\n}\n.bm-dialog .bm-note {\n color: var(--bm-label);\n font-size: 14px;\n line-height: 1.5;\n}\n.bm-dialog button,\n.bm-popover .bm-actions button,\n.bm-banner button {\n min-height: 38px;\n padding: 0 16px;\n border: 0;\n border-radius: 8px;\n background: var(--fill);\n font-size: 14px;\n font-weight: 400;\n}\n.bm-dialog button:hover:not(:disabled),\n.bm-popover .bm-actions button:hover:not(:disabled) {\n background: var(--fill-hover);\n}\n/* The primary action comes first in the DOM (focus lands on it); row-reverse shows it last, on the right. */\n.bm-actions {\n display: flex;\n flex-direction: row-reverse;\n justify-content: flex-start;\n align-items: center;\n gap: 8px;\n}\n.bm-dialog > .bm-actions,\n.bm-popover[aria-label=\"Edit link\"] > .bm-actions {\n padding-top: 12px;\n border-top: 1px solid var(--bm-divider);\n}\n.bm-dialog-foot {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 12px;\n border-top: 1px solid var(--bm-divider);\n}\n.bm-dialog-foot > .bm-hint {\n flex: 1;\n min-width: 0;\n margin: 0;\n}\n.bm-dialog-foot .bm-actions {\n flex: none;\n}\n\n/* Alert dialogs: [icon tile] [title / body / note] [x] */\n.bm-alert-main {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n.bm-alert-copy {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.bm-alert-body {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--bm-label);\n overflow-wrap: anywhere;\n}\n.bm-alert-body strong {\n font-weight: 600;\n color: var(--bm-ink);\n}\n.bm-alert-note {\n margin: 0;\n font-size: 12px;\n line-height: 1.45;\n color: var(--bm-muted);\n}\n.bm-tile {\n flex: none;\n display: grid;\n place-items: center;\n width: 36px;\n height: 36px;\n border-radius: 9px;\n}\n.bm-tile .bm-icon {\n width: 18px;\n height: 18px;\n}\n.bm-tile-warn {\n background: var(--bm-unsaved-bg);\n color: var(--bm-unsaved-fg);\n}\n.bm-tile-danger {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-tile-neutral {\n background: var(--bm-fill);\n color: var(--bm-label);\n}\n\n.bm-banner {\n position: fixed;\n z-index: 6;\n display: flex;\n align-items: center;\n gap: 12px;\n width: min(440px, calc(100vw - 32px));\n padding: 12px 14px;\n border-radius: 12px;\n box-shadow: 0 14px 34px -10px oklch(0.2 0.02 255 / 0.4);\n}\n.bm-banner button {\n min-height: 34px;\n padding: 0 14px;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-banner-ink {\n background: var(--ink);\n color: #fff;\n}\n.bm-banner-light {\n background: #fff;\n box-shadow: var(--shadow-pop);\n}\n.bm-banner-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.bm-banner-title {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.35;\n}\n.bm-banner-sub {\n margin: 0;\n font-size: 12px;\n line-height: 1.4;\n opacity: 0.7;\n}\n.bm-banner .bm-actions {\n flex: none;\n gap: 6px;\n}\n.bm-banner-ink button {\n min-height: 30px;\n padding: 0 12px;\n font-size: 12px;\n background: oklch(1 0 0 / 0.12);\n color: #fff;\n}\n.bm-banner-ink button:hover {\n background: oklch(1 0 0 / 0.2);\n}\n.bm-banner-ink .bm-primary {\n background: #fff;\n color: var(--ink);\n}\n.bm-banner-ink .bm-primary:hover {\n background: oklch(0.94 0.003 250);\n}\n.bm-banner-ink :focus-visible {\n outline-color: oklch(0.82 0.14 145);\n}\n.bm-dot-stale {\n background: oklch(0.7 0.18 25) !important;\n}\n.bm-dot-info {\n background: var(--info-dot) !important;\n}\n\n/* Closed editor. The dock sits where the sidebar header's controls sit: header padding (top 14, right 14) minus the dock's 7px padding. */\n.bm-dock {\n position: fixed;\n z-index: 5;\n top: 7px;\n right: 7px;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 7px 7px 10px;\n border-radius: 14px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-dot {\n flex: none;\n width: 8px;\n height: 8px;\n border-radius: 99px;\n background: oklch(0.72 0.17 145);\n}\n.bm-dot-dirty {\n background: var(--warn-dot);\n}\n\n/* Sidebar shell */\n.bm-sidebar {\n position: fixed;\n z-index: 4;\n top: 0;\n right: 0;\n bottom: 0;\n width: min(440px, 100vw);\n display: flex;\n flex-direction: column;\n background: #fff;\n box-shadow:\n 0 0 0 1px var(--line),\n -24px 0 48px -24px oklch(0.2 0.02 255 / 0.25);\n}\n.bm-resize {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: col-resize;\n touch-action: none;\n z-index: 2;\n}\n.bm-resize:hover,\n.bm-resize:focus-visible {\n background: oklch(0.46 0.13 145 / 0.25);\n}\n.bm-resize:focus-visible {\n outline-offset: -2px;\n}\n\n.bm-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 14px 14px 16px;\n border-bottom: 1px solid var(--line-soft);\n}\n.bm-mark {\n flex: none;\n display: block;\n width: 28px;\n height: auto;\n aspect-ratio: 21 / 19;\n image-rendering: pixelated;\n user-select: none;\n}\n/* Bear, name and slogan. Takes the space the controls leave; the text fades out when it no longer fits. */\n.bm-brand {\n position: relative;\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.bm-head-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n transition: opacity 160ms ease;\n}\n.bm-brand-compact .bm-head-text {\n opacity: 0;\n}\n/* The same two lines, in a card left of the sidebar (over the page), level with the header, while the pointer is on\n the brand. 16px is the header's left padding: the card clears the sidebar edge by 10px. */\n.bm-brand-tip {\n position: absolute;\n z-index: 5;\n top: 50%;\n right: calc(100% + 16px + 10px);\n display: flex;\n flex-direction: column;\n padding: 8px 12px;\n border-radius: 10px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n white-space: nowrap;\n opacity: 0;\n transform: translate(4px, -50%);\n pointer-events: none;\n transition:\n opacity 120ms ease,\n transform 120ms ease;\n}\n.bm-brand-compact:hover .bm-brand-tip {\n opacity: 1;\n transform: translate(0, -50%);\n transition-delay: 120ms;\n}\n@media (prefers-reduced-motion: reduce) {\n .bm-head-text,\n .bm-brand-tip {\n transition: none;\n }\n}\n/* A ring with one open quarter that turns while a save is written and the page reloads. */\n.bm-spin {\n flex: none;\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: bm-spin 0.8s linear infinite;\n}\n@keyframes bm-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .bm-spin {\n animation: none;\n }\n}\n.bm-faces {\n display: grid;\n}\n.bm-face {\n grid-area: 1 / 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n white-space: nowrap;\n}\n.bm-face[hidden-face] {\n visibility: hidden;\n}\n.bm-save:disabled {\n opacity: 0.85;\n cursor: progress;\n}\n.bm-head-title {\n font-size: 15px;\n font-weight: 600;\n letter-spacing: -0.015em;\n /* The controls beside it never shrink, so a narrow sidebar cuts the name, not the buttons. */\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-head-sub {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-pill {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 24px;\n padding: 0 10px;\n border-radius: 999px;\n background: var(--bm-saved-bg);\n color: var(--bm-saved-fg);\n font-size: 12px;\n font-weight: 500;\n}\n.bm-pill .bm-dot {\n width: 6px;\n height: 6px;\n background: var(--accent);\n}\n.bm-pill-dirty {\n background: var(--warn-tint);\n color: var(--warn-ink);\n}\n.bm-pill-dirty .bm-dot {\n background: var(--warn-dot);\n}\nbutton.bm-pill-btn {\n min-height: 0;\n padding: 0 10px;\n border: 0;\n border-radius: 999px;\n background: var(--warn-tint);\n color: var(--warn-ink);\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n}\n:is(.bm-sidebar, .bm-dock) button.bm-pill-btn:hover:not(:disabled) {\n background: oklch(0.93 0.06 75);\n color: var(--warn-ink);\n}\nbutton.bm-pill-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n.bm-dialog-wide {\n width: min(400px, calc(100vw - 32px));\n}\n.bm-dialog .bm-actions {\n flex-wrap: nowrap;\n}\n.bm-dialog .bm-actions button {\n flex: none;\n white-space: nowrap;\n}\n.bm-changes {\n width: min(540px, calc(100vw - 32px));\n}\n.bm-commit-files {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n max-height: min(34vh, 280px);\n overflow-y: auto;\n}\n.bm-commit-files label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n cursor: pointer;\n}\n.bm-commit-mark {\n font:\n 600 11px / 1 ui-monospace,\n monospace;\n width: 18px;\n text-align: center;\n opacity: 0.7;\n}\n.bm-commit-msg {\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n font: inherit;\n font-size: 14px;\n padding: 8px 12px;\n border: 1px solid var(--line);\n border-radius: 8px;\n background: transparent;\n color: inherit;\n}\n\n/* Unsaved changes review and version history: groups, rows, diff lines */\n.bm-changes-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-height: 22rem;\n overflow-y: auto;\n margin: 0 -4px;\n padding: 0 4px;\n}\n.bm-changes-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-changes-area {\n margin: 0;\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--bm-section);\n}\n.bm-changes-file {\n font-weight: 400;\n letter-spacing: 0;\n text-transform: none;\n color: oklch(0.55 0.01 255);\n}\n.bm-changes-count {\n margin-left: auto;\n font-weight: 400;\n letter-spacing: 0;\n color: var(--bm-muted);\n}\n.bm-changes ul {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n overflow: hidden;\n}\n.bm-change {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px;\n font-size: 14px;\n line-height: 1.4;\n}\n.bm-change + .bm-change {\n border-top: 1px solid var(--bm-divider);\n}\n.bm-change-mark {\n flex: none;\n display: grid;\n place-items: center;\n width: 22px;\n height: 22px;\n border-radius: 6px;\n font-family: var(--mono);\n font-size: 13px;\n font-weight: 600;\n background: var(--bm-unsaved-bg);\n color: var(--bm-unsaved-fg);\n}\n.bm-change-added .bm-change-mark {\n background: var(--bm-badge-green-bg);\n color: var(--bm-badge-green-fg);\n}\n.bm-change-removed .bm-change-mark {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-text);\n}\n.bm-change-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.bm-change-field {\n font-weight: 500;\n color: var(--bm-ink);\n overflow-wrap: anywhere;\n}\n.bm-change-values {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n.bm-change-values del,\n.bm-change-values ins {\n display: flex;\n gap: 6px;\n min-width: 0;\n padding: 3px 7px;\n border-radius: 5px;\n text-decoration: none;\n font-size: 13px;\n}\n.bm-change-values del {\n background: var(--bm-diff-del-bg);\n color: var(--bm-diff-del-fg);\n}\n.bm-change-values ins {\n background: var(--bm-diff-add-bg);\n color: var(--bm-diff-add-fg);\n}\n.bm-change-values del::before {\n content: \"\\2212\";\n flex: none;\n font-family: var(--mono);\n}\n.bm-change-values ins::before {\n content: \"+\";\n flex: none;\n font-family: var(--mono);\n}\n.bm-change-values del > span,\n.bm-change-values ins > span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-change-values del > span {\n text-decoration: line-through;\n text-decoration-color: oklch(0.45 0.13 25 / 0.5);\n}\n.bm-changes-empty {\n margin: 0;\n padding: 24px 0;\n text-align: center;\n font-size: 14px;\n color: var(--bm-muted);\n}\n\n.bm-changes ul.bm-versions {\n gap: 0;\n}\n.bm-version {\n padding: 0;\n}\n.bm-version + .bm-version {\n border-top: 1px solid var(--bm-divider);\n}\n.bm-version-when strong {\n font-weight: 600;\n}\n.bm-tipped {\n position: relative;\n}\n.bm-tipped::after {\n content: attr(data-tip);\n position: absolute;\n right: calc(100% + 6px);\n top: 50%;\n transform: translateY(-50%);\n padding: 4px 8px;\n border-radius: 6px;\n background: var(--ink);\n color: #fff;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n pointer-events: none;\n visibility: hidden;\n z-index: 5;\n}\n.bm-version-row > .bm-tipped:first-child::after {\n right: auto;\n left: calc(100% + 6px);\n}\n.bm-tipped:hover::after,\n.bm-tipped:focus-visible::after {\n visibility: visible;\n}\n.bm-version-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 8px 8px 10px;\n}\n.bm-version-when {\n flex: 1;\n min-width: 0;\n margin-right: auto;\n padding: 0 !important;\n min-height: 32px !important;\n font-weight: 500;\n display: flex !important;\n flex-direction: column;\n align-items: flex-start !important;\n justify-content: center;\n gap: 2px;\n text-align: left;\n}\n.bm-version-line {\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n.bm-version-sum {\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 400;\n color: var(--bm-help);\n}\n.bm-version-row .bm-restore {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n flex: none;\n min-height: 32px;\n padding: 0 10px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-version-rel {\n font-size: 14px;\n font-weight: 500;\n color: var(--bm-ink);\n}\n.bm-version-abs {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--bm-muted);\n}\n.bm-version-diff {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 4px 10px 12px 10px;\n border-top: 1px solid var(--bm-divider);\n margin-top: 0;\n}\n.bm-version-diff ul {\n margin: 0;\n}\n.bm-day {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.bm-restored {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 8px 8px 12px;\n border-radius: 9px;\n background: var(--bm-diff-add-bg);\n color: var(--bm-saved-fg);\n font-size: 13px;\n}\n.bm-restored > span {\n flex: 1;\n min-width: 0;\n}\n\n.bm-tabs {\n display: flex;\n gap: 0;\n padding: 0 12px;\n overflow-x: auto;\n border-bottom: 1px solid var(--bm-tab-rule);\n}\n.bm-tabs button {\n flex: 1 1 auto;\n height: 46px;\n padding: 0 6px;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: oklch(0.48 0.01 255);\n font-size: 13px;\n font-weight: 400;\n}\n.bm-tabs button:hover {\n color: var(--ink);\n background: var(--fill-soft);\n}\n.bm-tabs button[aria-selected=\"true\"] {\n color: var(--ink);\n background: transparent;\n font-weight: 600;\n box-shadow: inset 0 -2px 0 var(--accent);\n}\n.bm-tabs button:focus-visible {\n outline-offset: -2px;\n}\n\n.bm-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 24px 24px 32px;\n display: flex;\n flex-direction: column;\n gap: 18px;\n}\n.bm-foot {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n border-top: 1px solid var(--line-soft);\n font-family: var(--mono);\n font-size: 10px;\n color: var(--muted);\n}\n.bm-foot span:first-child {\n flex: none;\n white-space: nowrap;\n}\n.bm-foot span:last-child {\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n/* Group header: mono 11/500, then a 1px rule. With a right-hand item the rule sits on the flex wrapper. */\n.bm-group {\n margin: 18px 0 0;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--bm-divider);\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--bm-section);\n}\n.bm-group:first-child {\n margin-top: 0;\n}\n.bm-stack-tight > .bm-group {\n margin-bottom: 10px;\n}\n.bm-meta {\n margin: 0;\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n}\n\n/* Fields */\n.bm-label {\n display: flex;\n flex-direction: column;\n gap: 8px;\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n}\n.bm-field {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-hint {\n font-size: 12px;\n line-height: 1.45;\n font-weight: 400;\n color: var(--muted);\n}\n.bm-label-text {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n}\n.bm-info {\n position: relative;\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n margin-left: 4px;\n}\n.bm-info-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n margin: -3px 0;\n border-radius: 999px;\n color: var(--bm-info);\n cursor: help;\n text-transform: none;\n letter-spacing: 0;\n}\n.bm-info-btn:hover,\n.bm-info-btn[aria-expanded=\"true\"] {\n color: var(--ink);\n}\n.bm-info-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n}\n.bm-tip {\n position: fixed;\n z-index: 2147483647;\n visibility: hidden;\n pointer-events: none;\n padding: 8px 10px;\n border-radius: 8px;\n box-sizing: border-box;\n background: var(--ink);\n color: oklch(0.98 0.003 250);\n font-family: var(--sans, inherit);\n font-size: 12px;\n line-height: 1.45;\n font-weight: 400;\n text-transform: none;\n letter-spacing: 0;\n text-align: left;\n white-space: normal;\n box-shadow: 0 6px 20px rgb(0 0 0 / 0.25);\n}\n.bm-tip-open {\n visibility: visible;\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) :where(input:not([type=\"checkbox\"]):not([type=\"file\"]), select, textarea) {\n width: 100%;\n min-height: 40px;\n padding: 0 12px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n color: var(--ink);\n font-size: 14px;\n font-weight: 400;\n outline: none;\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) textarea {\n padding: 8px 12px;\n min-height: 72px;\n line-height: 1.5;\n resize: vertical;\n}\n:is(.bm-sidebar, .bm-popover) select:not([size]) {\n appearance: none;\n padding-right: 32px;\n /* A caret made of gradients, not a `data:` image: a site's Content-Security-Policy can block those. */\n background-image: linear-gradient(45deg, transparent 50%, #777 50%), linear-gradient(135deg, #777 50%, transparent 50%);\n background-size: 6px 6px;\n background-repeat: no-repeat;\n background-position:\n right 17px center,\n right 12px center;\n}\n.bm-sidebar select[size],\n.bm-popover select[size] {\n padding: 4px;\n font-size: 12px;\n}\n.bm-sidebar select[size] option,\n.bm-sidebar select[size] optgroup,\n.bm-popover select[size] option,\n.bm-popover select[size] optgroup {\n padding: 3px 6px;\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) :where(input:not([type=\"checkbox\"]):not([type=\"file\"]), select, textarea):focus {\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px var(--bm-primary-ring);\n}\n:is(.bm-sidebar, .bm-popover, .bm-seo, .bm-consent) :where(input[aria-label=\"Link URL\"], .bm-mono) {\n font-family: var(--mono);\n font-size: 13px;\n}\n.bm-prefix-wrap {\n display: flex;\n align-items: center;\n min-height: 40px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n overflow: hidden;\n}\n.bm-prefix-wrap:focus-within {\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px var(--bm-primary-ring);\n}\n.bm-prefix {\n padding: 0 2px 0 12px;\n font-family: var(--mono);\n font-size: 13px;\n color: var(--muted);\n}\n.bm-prefix-wrap input {\n border: 0;\n box-shadow: none !important;\n min-height: 38px;\n padding-left: 2px;\n font-family: var(--mono);\n font-size: 13px;\n}\n.bm-stack {\n display: flex;\n flex-direction: column;\n gap: 18px;\n}\n.bm-stack-tight {\n gap: 8px;\n}\n.bm-groups {\n gap: 36px;\n}\n.bm-list {\n display: flex;\n flex-direction: column;\n border-radius: 10px;\n box-shadow: 0 0 0 1px var(--bm-border);\n overflow: hidden;\n}\n.bm-list-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px 8px 12px;\n border-bottom: 1px solid var(--line-soft);\n}\n.bm-list-row:last-child {\n border-bottom: 0;\n}\n.bm-list-row-on {\n background: var(--accent-tint);\n}\n.bm-list-row a {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n color: var(--ink);\n text-decoration: none;\n}\n.bm-list-row a:hover .bm-list-title {\n text-decoration: underline;\n}\n.bm-list-title {\n font-size: 14px;\n font-weight: 500;\n}\n.bm-list-path {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n}\n.bm-badge-home {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: var(--bm-badge-green-bg);\n color: var(--bm-badge-green-fg);\n}\n.bm-badge {\n font-family: var(--mono);\n font-size: 11px;\n padding: 3px 7px;\n border-radius: 5px;\n background: var(--bm-badge-amber-bg);\n color: var(--bm-badge-amber-fg);\n}\n.bm-badge-system {\n background: var(--fill);\n color: var(--ink-2);\n}\n.bm-badge-on {\n background: var(--bm-badge-green-bg);\n color: var(--bm-badge-green-fg);\n}\n.bm-row {\n display: flex;\n gap: 6px;\n align-items: center;\n flex-wrap: wrap;\n}\n.bm-row-split {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n.bm-error {\n color: var(--danger-ink);\n font-size: 12px;\n font-weight: 400;\n margin: 0;\n}\n.bm-warn {\n color: var(--warn-ink);\n font-size: 12px;\n margin: 0;\n}\n.bm-note {\n margin: 0;\n color: var(--bm-help);\n font-size: 13px;\n line-height: 1.55;\n font-weight: 400;\n}\n.bm-group + .bm-note,\n.bm-group-split + .bm-note {\n margin-top: -4px;\n}\n\n/* Switch: 36 x 20, knob 16 inset 2 */\n.bm-check {\n flex-direction: row;\n align-items: center;\n gap: 10px;\n font-weight: 500;\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"] {\n appearance: none;\n position: relative;\n flex: none;\n width: 36px;\n height: 20px;\n margin: 0;\n border-radius: 999px;\n background: var(--bm-switch-off);\n cursor: pointer;\n transition: background 0.15s;\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"]::before {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 1px 2px oklch(0 0 0 / 0.2);\n transition: transform 0.15s;\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"]:checked {\n background: var(--bm-primary);\n}\n:is(.bm-check, .bm-switch-row) input[type=\"checkbox\"]:checked::before {\n transform: translateX(16px);\n}\n.bm-popover .bm-check {\n color: var(--bm-label);\n font-size: 14px;\n}\n\n/* Buttons inside the sidebar */\n.bm-sidebar :where(button:not([role=\"tab\"]):not([role=\"radio\"]):not(.bm-resize)) {\n min-height: 32px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: var(--fill);\n color: var(--ink);\n font-size: 13px;\n font-weight: 500;\n}\n.bm-sidebar :where(button:not([role=\"tab\"]):not([role=\"radio\"]):not(.bm-resize)):hover:not(:disabled) {\n background: var(--fill-hover);\n}\n.bm-sidebar button:disabled {\n opacity: 0.45;\n cursor: default;\n}\n/* Dashed \"Add ...\" buttons: Add link, Add button, Add column, Add item */\n.bm-sidebar .bm-add {\n min-height: 44px;\n background: oklch(0.985 0.002 250);\n color: var(--bm-link);\n border: 1px dashed oklch(0.85 0.005 250);\n border-radius: 8px;\n}\n.bm-sidebar .bm-add:hover:not(:disabled) {\n background: var(--accent-tint);\n}\n\n/* Cards, lists, images */\n.bm-card {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n}\n.bm-card .bm-card {\n background: var(--bm-fill-nested);\n border-color: var(--line-soft);\n}\n.bm-card > .bm-label:first-child:not(:only-child) {\n font-family: var(--mono);\n font-size: 11px;\n letter-spacing: 0.04em;\n font-weight: 500;\n color: var(--muted);\n}\n.bm-card[draggable=\"true\"] {\n cursor: grab;\n}\n/* Drag and drop: the target shows what a drop would do. */\n.bm-dragging {\n opacity: 0.4;\n}\n.bm-drop-before,\n.bm-drop-after,\n.bm-drop-child {\n --drop: var(--accent);\n}\n.bm-drop-before::before,\n.bm-drop-after::before {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n height: 3px;\n border-radius: 3px;\n background: var(--drop);\n box-shadow: 0 0 0 2px var(--accent-ring);\n pointer-events: none;\n z-index: 2;\n}\n.bm-drop-before::before {\n top: -6px;\n}\n.bm-drop-after::before {\n bottom: -6px;\n}\n.bm-drop-child {\n box-shadow: inset 0 0 0 2px var(--drop);\n background: var(--accent-tint);\n}\n.bm-drop-before::after,\n.bm-drop-after::after,\n.bm-drop-child::after,\n.bm-drop-files::after {\n content: attr(data-drop-hint);\n position: absolute;\n right: 8px;\n padding: 3px 8px;\n border-radius: 6px;\n background: var(--ink);\n color: #fff;\n font-size: 11px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n pointer-events: none;\n z-index: 3;\n}\n.bm-drop-before::after {\n top: -22px;\n}\n.bm-drop-after::after {\n bottom: -22px;\n}\n.bm-drop-child::after {\n top: -11px;\n right: 12px;\n}\n.bm-drop-files {\n box-shadow: inset 0 0 0 2px var(--accent);\n background: var(--accent-tint);\n}\n.bm-drop-files::after {\n top: -11px;\n right: 12px;\n}\n.bm-thumb {\n width: 100%;\n height: 96px;\n object-fit: cover;\n border-radius: 7px;\n background: var(--fill);\n}\n.bm-drop {\n display: flex;\n flex-direction: column;\n gap: 8px;\n border: 1px dashed var(--line);\n border-radius: 10px;\n padding: 10px;\n background: var(--fill-soft);\n}\n.bm-drop input[type=\"file\"] {\n width: 100%;\n font-size: 12px;\n color: var(--muted);\n}\n.bm-drop input[type=\"file\"]::file-selector-button {\n height: 32px;\n margin-right: 10px;\n padding: 0 12px;\n border: 0;\n border-radius: 7px;\n background: var(--ink);\n color: #fff;\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n}\n.bm-alert {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px 14px;\n border-radius: 12px;\n background: var(--danger-tint);\n box-shadow: 0 0 0 1px oklch(0.55 0.18 25 / 0.35);\n}\n.bm-alert-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--danger-ink);\n}\n.bm-alert .bm-error {\n font-family: var(--mono);\n font-size: 11px;\n}\n.bm-alert-notice {\n background: var(--warn-tint);\n box-shadow: 0 0 0 1px oklch(0.45 0.09 65 / 0.2);\n}\n.bm-alert-notice .bm-note {\n color: var(--warn-ink);\n font-size: 12px;\n}\n\n/* Header actions */\n.bm-save {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 34px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: var(--accent);\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n}\n.bm-dialog .bm-primary kbd {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n margin-left: 8px;\n opacity: 0.8;\n}\n.bm-save kbd {\n font-family: var(--mono);\n font-size: 10px;\n font-weight: 400;\n opacity: 0.75;\n}\n/* Icon buttons: 32 x 32, transparent, grey icon, grey fill on hover. */\n.bm-icon-btn {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n min-height: 0 !important;\n padding: 0 !important;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--bm-icon);\n}\n.bm-icon-btn:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n.bm-icon-btn:disabled {\n opacity: 0.35;\n}\n.bm-close {\n width: 32px;\n height: 32px;\n background: transparent;\n color: var(--bm-icon);\n border-radius: 7px;\n}\n.bm-close:hover:not(:disabled) {\n background: var(--fill) !important;\n color: var(--ink);\n}\n.bm-dock .bm-save {\n font-family: var(--sans);\n}\n.bm-split {\n position: relative;\n display: inline-flex;\n flex: none;\n}\n.bm-split .bm-split-main {\n border-radius: 8px 0 0 8px;\n}\n.bm-split .bm-split-toggle {\n width: 28px;\n padding: 0;\n justify-content: center;\n border-radius: 0 8px 8px 0;\n box-shadow: inset 1px 0 0 oklch(1 0 0 / 0.35);\n}\n.bm-split .bm-split-toggle:focus-visible,\n.bm-split .bm-split-main:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n.bm-split-menu {\n position: absolute;\n z-index: 8;\n top: calc(100% + 6px);\n right: 0;\n min-width: 200px;\n display: flex;\n flex-direction: column;\n padding: 4px;\n border-radius: 10px;\n background: #fff;\n box-shadow: var(--bm-shadow-pop);\n}\n.bm-split-menu button.bm-split-item {\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 34px;\n padding: 0 10px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--ink);\n font-family: var(--sans);\n font-size: 13px;\n font-weight: 500;\n text-align: left;\n}\n.bm-split-menu button.bm-split-item:hover:not(:disabled),\n.bm-split-menu button.bm-split-item:focus-visible {\n background: var(--fill);\n outline: none;\n}\n.bm-split-menu button.bm-split-danger {\n color: var(--danger-ink);\n}\n.bm-split-menu button.bm-split-item {\n justify-content: space-between;\n gap: 16px;\n}\n.bm-split-menu button.bm-split-item kbd {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--muted);\n}\n.bm-split-menu button.bm-split-sep {\n margin-top: 5px;\n position: relative;\n}\n.bm-split-menu button.bm-split-sep::before {\n content: \"\";\n position: absolute;\n left: 6px;\n right: 6px;\n top: -3px;\n height: 1px;\n background: var(--line);\n}\n.bm-split-menu button.bm-split-danger:hover:not(:disabled),\n.bm-split-menu button.bm-split-danger:focus-visible {\n background: var(--danger-tint);\n}\n.bm-split-menu button.bm-split-item:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.bm-sidebar .bm-icon-btn.bm-danger {\n color: var(--bm-danger-icon);\n}\n.bm-sidebar .bm-icon-btn.bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-small {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n min-height: 28px !important;\n padding: 0 10px !important;\n font-family: var(--sans);\n font-size: 12px !important;\n letter-spacing: 0;\n text-transform: none;\n align-self: flex-start;\n}\n.bm-group-split {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-top: 18px;\n margin-bottom: 0;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--bm-divider);\n}\n.bm-group-split:first-child {\n margin-top: 0;\n}\n.bm-group-split > .bm-group {\n margin: 0;\n padding: 0;\n border: 0;\n}\n.bm-group-split .bm-small {\n text-transform: none;\n letter-spacing: 0;\n}\n.bm-group-split span.bm-small {\n font-family: var(--mono);\n font-size: 11px !important;\n font-weight: 400;\n color: var(--bm-muted);\n padding: 0 !important;\n min-height: 0 !important;\n}\n.bm-stack-tight > .bm-group-split {\n margin-bottom: 10px;\n}\n\n/* Labels with a right-hand tag */\n.bm-label.bm-label-row,\n.bm-label-row {\n flex-direction: row;\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n}\n.bm-meta-tag {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0;\n color: var(--bm-muted);\n}\n\n/* Switch rows */\n.bm-switch-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n cursor: pointer;\n}\n.bm-switch-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.bm-switch-title {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n font-weight: 500;\n color: var(--bm-label);\n}\n\n/* Tone cards and segmented controls */\n.bm-tones {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 6px;\n}\n:is(.bm-sidebar, .bm-popover) .bm-tone {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 6px;\n min-height: 0;\n padding: 5px 5px 6px;\n border-radius: 9px;\n background: #fff;\n border: 0;\n box-shadow: inset 0 0 0 1px var(--bm-border);\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n}\n:is(.bm-sidebar, .bm-popover) .bm-tone:hover {\n background: var(--fill-soft);\n}\n:is(.bm-sidebar, .bm-popover) .bm-tone[aria-checked=\"true\"] {\n box-shadow: inset 0 0 0 2px var(--accent);\n background: #fff;\n}\n.bm-tones-2 {\n grid-template-columns: repeat(2, 1fr);\n}\n.bm-tones-3 {\n grid-template-columns: repeat(3, 1fr);\n}\n/* A miniature of each button look, drawn with the editor's colours so it does not depend on the site theme. */\n.bm-btnsample {\n display: grid;\n place-items: center;\n height: 26px;\n border-radius: 6px;\n background: var(--fill-soft);\n}\n.bm-btnsample > span {\n display: block;\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n}\n.bm-btnsample-default > span {\n color: var(--ink-2);\n}\n.bm-btnsample-primary > span {\n padding: 5px 12px;\n border-radius: 999px;\n background: var(--accent);\n color: #fff;\n}\n.bm-btnsample-secondary > span {\n padding: 5px 12px;\n border-radius: 999px;\n color: var(--ink);\n box-shadow: inset 0 0 0 1px var(--ink-2);\n}\n.bm-btnsample-tertiary > span {\n color: var(--accent);\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.bm-swatch {\n display: inline-block;\n flex: none;\n width: 10px;\n height: 10px;\n border-radius: 3px;\n box-shadow: inset 0 0 0 1px oklch(0.2 0.02 255 / 0.15);\n}\n.bm-swatch-lg {\n display: block;\n width: auto;\n height: 22px;\n border-radius: 6px;\n}\n.bm-swatch-base {\n background: #fff;\n}\n.bm-swatch-subtle {\n background: oklch(0.96 0.005 250);\n}\n.bm-swatch-inverse {\n background: var(--ink);\n}\n.bm-swatch-brand {\n background: var(--accent);\n}\n.bm-segmented {\n display: flex;\n padding: 3px;\n border-radius: 9px;\n background: var(--bm-fill);\n}\n.bm-sidebar .bm-segmented button,\n.bm-dialog .bm-segmented button {\n flex: 1;\n min-height: 36px;\n height: 36px;\n padding: 0 8px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: oklch(0.45 0.01 255);\n font-size: 13px;\n font-weight: 400;\n}\n.bm-sidebar .bm-segmented button:hover:not(:disabled),\n.bm-dialog .bm-segmented button:hover:not(:disabled) {\n background: oklch(1 0 0 / 0.5);\n}\n.bm-sidebar .bm-segmented button[aria-checked=\"true\"],\n.bm-dialog .bm-segmented button[aria-checked=\"true\"] {\n background: #fff;\n color: var(--ink);\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-icon-picker {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));\n gap: 4px;\n padding: 3px;\n border-radius: 9px;\n background: var(--bm-fill);\n}\n.bm-sidebar .bm-icon-picker button {\n display: grid;\n place-items: center;\n min-height: 40px;\n height: 40px;\n padding: 0;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: oklch(0.45 0.01 255);\n}\n.bm-sidebar .bm-icon-picker button:hover {\n background: oklch(1 0 0 / 0.5);\n color: var(--ink);\n}\n.bm-sidebar .bm-icon-picker button[aria-checked=\"true\"] {\n background: #fff;\n color: var(--accent);\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-icon-picker svg {\n width: 20px;\n height: 20px;\n}\n.bm-actions-split {\n display: flex;\n gap: 8px;\n padding-top: 4px;\n}\n.bm-actions-split button {\n flex: 1;\n min-height: 40px !important;\n font-size: 14px !important;\n}\n.bm-sidebar .bm-actions-split .bm-danger {\n background: var(--bm-danger-soft);\n}\n\n/* Arrays, links, images */\n.bm-array {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-array-row {\n position: relative;\n}\n.bm-array-grip {\n cursor: grab;\n}\n.bm-array-item {\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n overflow: hidden;\n}\n.bm-array-item summary {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 44px;\n padding: 0 8px 0 10px;\n font-size: 14px;\n font-weight: 500;\n color: var(--ink);\n cursor: pointer;\n list-style: none;\n}\n.bm-array-item summary::-webkit-details-marker {\n display: none;\n}\n.bm-array-item summary:hover {\n background: var(--fill-soft);\n}\n.bm-array-summary {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-grip,\n.bm-chevron {\n display: inline-grid;\n place-items: center;\n color: oklch(0.65 0.01 255);\n}\n.bm-chevron {\n transition: transform 0.12s;\n}\ndetails[open] > summary .bm-chevron {\n transform: rotate(90deg);\n}\n.bm-array-body {\n display: flex;\n flex-direction: column;\n gap: 18px;\n padding: 12px;\n background: var(--bm-fill-nested);\n border-top: 1px solid var(--line-soft);\n}\n.bm-row-end {\n justify-content: flex-end;\n}\n.bm-sidebar .bm-add-row {\n width: 100%;\n}\n.bm-link-btn {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n min-height: 40px;\n padding: 0 12px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n text-align: left;\n color: var(--ink-2);\n}\n.bm-sidebar .bm-link-btn {\n background: #fff;\n border: 1px solid var(--bm-border);\n font-size: 14px;\n padding: 0 12px;\n}\n.bm-sidebar .bm-link-btn:hover:not(:disabled) {\n background: #fff;\n border-color: oklch(0.8 0.005 250);\n}\n.bm-link-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--ink);\n font-weight: 500;\n}\n.bm-link-href {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n max-width: 45%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-stripes {\n background: repeating-linear-gradient(135deg, oklch(0.93 0.004 250) 0 6px, oklch(0.965 0.003 250) 6px 12px);\n}\n\n/* Image field: label above, compact 56px row, alt text under it */\n.bm-imagefield {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.bm-image-row {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n.bm-image-row .bm-thumb {\n flex: none;\n width: 56px;\n height: 56px;\n border-radius: 6px;\n}\n.bm-image-meta {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n justify-content: center;\n}\n.bm-image-path {\n font-family: var(--mono);\n font-size: 12px;\n color: var(--bm-label);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-sidebar .bm-alt {\n min-height: 40px;\n font-size: 14px;\n}\n.bm-image-actions {\n flex-wrap: nowrap;\n gap: 6px;\n}\n.bm-image-actions > button:not(.bm-icon-btn) {\n flex: 1;\n min-height: 36px;\n font-size: 13px;\n}\n.bm-layout {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding-top: 2px;\n}\n.bm-layout-row {\n display: grid;\n grid-template-columns: 56px 1fr;\n align-items: center;\n column-gap: 10px;\n row-gap: 4px;\n}\n.bm-layout-row .bm-label {\n margin: 0;\n}\n.bm-layout-row .bm-layout-hint {\n grid-column: 2;\n}\n.bm-position {\n display: grid;\n grid-template-columns: repeat(3, 20px);\n grid-template-rows: repeat(3, 20px);\n gap: 3px;\n padding: 4px;\n width: max-content;\n border-radius: 8px;\n background: var(--fill);\n}\n.bm-sidebar .bm-position-cell {\n width: 20px;\n height: 20px;\n min-height: 0;\n padding: 0;\n border: 0;\n border-radius: 5px;\n background: #fff;\n box-shadow: inset 0 0 0 1px var(--line);\n}\n.bm-sidebar .bm-position-cell:hover:not(:disabled) {\n background: var(--accent-tint);\n}\n.bm-sidebar .bm-position-cell[aria-checked=\"true\"],\n.bm-sidebar .bm-position-cell[aria-checked=\"true\"]:hover:not(:disabled) {\n background: var(--accent);\n box-shadow: none;\n}\n.bm-sidebar .bm-position-cell:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.bm-slot,\n.bm-dropzone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n width: 100%;\n min-height: 96px;\n padding: 14px;\n border: 1.5px dashed oklch(0.82 0.006 250);\n border-radius: 10px;\n background: var(--fill-soft);\n color: var(--ink-2);\n text-align: center;\n cursor: pointer;\n}\n.bm-sidebar .bm-slot:hover:not(:disabled),\n.bm-dropzone:hover {\n border-color: var(--accent);\n background: var(--accent-tint);\n}\n.bm-dropzone {\n min-height: 180px;\n position: relative;\n}\n.bm-dropzone:focus-within {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n.bm-dropzone-over {\n border-color: var(--accent);\n background: var(--accent-tint);\n}\n.bm-slot-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--ink);\n}\n.bm-slot-hint {\n font-size: 11px;\n color: var(--muted);\n}\n.bm-scrim {\n position: fixed;\n inset: 0;\n z-index: 7;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding: 10vh 16px 16px;\n background: oklch(0.2 0.01 255 / 0.4);\n}\n.bm-modal {\n display: flex;\n flex-direction: column;\n width: min(480px, 100%);\n max-height: min(560px, 80vh);\n overflow: hidden;\n padding: 20px 0 0;\n border-radius: 14px;\n background: #fff;\n box-shadow: var(--bm-shadow-dialog);\n}\n.bm-modal-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 0 20px 12px;\n}\n.bm-modal-head .bm-dialog-title {\n flex: none;\n}\n.bm-modal-head .bm-meta-tag {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-modal-head .bm-icon-btn {\n margin: -6px -8px -6px 0;\n}\n.bm-modal .bm-tabs {\n margin: 0 20px;\n padding: 3px;\n gap: 0;\n border: 0;\n border-radius: 9px;\n background: var(--bm-fill);\n overflow: visible;\n}\n.bm-modal .bm-tabs button {\n flex: 1;\n height: 36px;\n min-height: 36px;\n padding: 0 8px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 400;\n}\n.bm-modal .bm-tabs button:hover {\n background: oklch(1 0 0 / 0.5);\n}\n.bm-modal .bm-tabs button[aria-selected=\"true\"] {\n background: #fff;\n color: var(--ink);\n font-weight: 500;\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-modal-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 16px 20px 20px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.bm-library {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 10px;\n}\n.bm-library-item {\n position: relative;\n}\n.bm-library-pick {\n display: flex;\n flex-direction: column;\n gap: 4px;\n width: 100%;\n min-height: 0;\n padding: 4px;\n border: 0;\n border-radius: 9px;\n background: var(--fill-soft);\n text-align: left;\n font-family: var(--mono);\n font-size: 9px;\n font-weight: 400;\n color: var(--muted);\n word-break: break-all;\n cursor: pointer;\n}\n.bm-library-pick:hover {\n background: var(--fill-hover);\n}\n.bm-library-pick img {\n width: 100%;\n aspect-ratio: 1 / 1;\n object-fit: cover;\n border-radius: 6px;\n background: var(--fill);\n}\n.bm-library-pick[aria-pressed=\"true\"] {\n box-shadow: 0 0 0 2px var(--accent);\n background: var(--accent-tint);\n}\n.bm-library-delete {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 24px;\n height: 24px;\n min-height: 0;\n background: #fff;\n box-shadow: 0 1px 3px oklch(0.2 0.01 255 / 0.25);\n opacity: 0;\n}\n.bm-library-item:hover .bm-library-delete,\n.bm-library-delete:focus-visible {\n opacity: 1;\n}\n.bm-library-empty {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n}\n.bm-modal-confirm {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px 20px 16px;\n border-top: 1px solid var(--line-soft);\n background: var(--danger-tint);\n}\n.bm-modal-confirm .bm-note {\n color: var(--danger-ink);\n font-size: 13px;\n line-height: 1.5;\n}\n.bm-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n border: 0;\n white-space: nowrap;\n}\n.bm-popover-title {\n grid-column: 1 / -1;\n padding: 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--bm-ink);\n}\n.bm-popover-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0;\n}\n.bm-popover-head-wide {\n grid-column: 1 / -1;\n}\n.bm-popover[aria-label=\"Edit link\"],\n.bm-popover[aria-label=\"Add section\"][role=\"listbox\"] {\n z-index: 5;\n}\n.bm-popover :is(.bm-fmt-bold) {\n font-weight: 700;\n}\n.bm-fmt-bold {\n font-weight: 700;\n font-size: 13px;\n}\n.bm-fmt-heading {\n font-weight: 700;\n font-size: 12px;\n letter-spacing: -0.02em;\n}\n.bm-fmt-italic {\n font-family: var(--serif);\n font-style: italic;\n font-size: 15px;\n}\n\n/* Edit link: Advanced row */\n.bm-advanced {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.bm-popover button.bm-advanced-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n min-height: 32px;\n padding: 0 2px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: var(--bm-label);\n font-size: 13px;\n font-weight: 500;\n text-align: left;\n}\n.bm-popover button.bm-advanced-toggle:hover {\n background: transparent;\n color: var(--bm-ink);\n}\n.bm-advanced-toggle .bm-chevron {\n transition: transform 0.12s;\n}\n.bm-advanced-toggle[aria-expanded=\"true\"] .bm-chevron {\n transform: rotate(90deg);\n}\n.bm-advanced-summary {\n margin-left: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--bm-muted);\n}\n\n/* SEO card and dialog */\n.bm-seo-card {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.bm-seo-badges {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.bm-seo-badge {\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--fill-soft);\n color: var(--bm-label);\n font-family: var(--mono);\n font-size: 11px;\n}\n.bm-seo-edit,\n.bm-consent-edit {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.bm-dialog.bm-seo {\n position: relative;\n width: min(560px, 100%);\n max-height: calc(100vh - 10vh - 32px);\n min-height: 0;\n}\n.bm-seo-body {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-height: 0;\n overflow-y: auto;\n padding: 2px 4px 2px 2px;\n}\n.bm-seo-json {\n min-height: 220px;\n white-space: pre;\n overflow: auto;\n tab-size: 2;\n}\n.bm-seo-json[aria-invalid=\"true\"] {\n border-color: var(--bm-danger);\n}\n.bm-seo-format {\n align-self: flex-start;\n}\n\n/* Cookie banner dialog */\n.bm-dialog.bm-consent {\n position: relative;\n width: min(520px, 100%);\n max-height: calc(100vh - 10vh - 32px);\n min-height: 0;\n}\n.bm-consent-body {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-height: 0;\n overflow-y: auto;\n padding: 2px 4px 2px 2px;\n}\n.bm-consent-preview {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--fill-soft);\n}\n.bm-consent-preview-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--bm-label);\n}\n.bm-consent-preview-text {\n margin: 0;\n font-size: 13px;\n line-height: 1.45;\n color: var(--bm-muted);\n overflow-wrap: anywhere;\n}\n.bm-consent-preview-link {\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.bm-consent-preview-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n.bm-consent-preview-buttons > span {\n padding: 5px 14px;\n border-radius: 999px;\n box-shadow: inset 0 0 0 1px var(--bm-border);\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n}\n\n/* SEO preview, OG row, outline */\n.bm-serp {\n display: flex;\n flex-direction: column;\n gap: 3px;\n padding: 12px 14px;\n border-radius: 10px;\n background: var(--fill-soft);\n}\n.bm-serp-image {\n flex-direction: row;\n align-items: flex-start;\n gap: 12px;\n}\n.bm-serp-text {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n.bm-serp-thumb {\n flex: none;\n width: 64px;\n height: 64px;\n border-radius: 8px;\n object-fit: cover;\n background: var(--fill);\n}\n.bm-serp-title {\n font-size: 15px;\n font-weight: 500;\n color: oklch(0.42 0.12 260);\n}\n.bm-serp-url {\n font-family: var(--mono);\n font-size: 11px;\n color: oklch(0.45 0.08 145);\n}\n.bm-serp-desc {\n font-size: 12px;\n line-height: 1.45;\n color: oklch(0.45 0.01 255);\n}\n.bm-outline-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.bm-sidebar .bm-outline-row {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n min-height: 40px;\n padding: 0 10px;\n border-radius: 8px;\n background: transparent;\n text-align: left;\n font-size: 14px;\n}\n.bm-sidebar .bm-outline-row:hover:not(:disabled) {\n background: var(--fill-soft);\n}\n\n/* Section rows (Pages tab): grip, tone swatch, name over #anchor and variant, then actions. */\n.bm-srow {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n min-height: 52px;\n padding: 6px 6px 6px 8px;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n}\n.bm-srow:hover {\n border-color: oklch(0.8 0.008 250);\n}\n.bm-srow-grip {\n flex: none;\n width: 16px;\n height: 32px;\n display: inline-grid;\n place-items: center;\n cursor: grab;\n touch-action: none;\n}\n.bm-srow-grip:active {\n cursor: grabbing;\n}\n.bm-srow .bm-outline-row {\n flex: 1;\n min-width: 0;\n width: auto;\n padding: 0 8px 0 4px;\n gap: 10px;\n}\n.bm-srow .bm-swatch {\n width: 10px;\n height: 10px;\n border-radius: 2px;\n}\n.bm-srow-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n.bm-srow-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--bm-ink);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-srow-meta {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--bm-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-srow .bm-outline-meta {\n flex: none;\n max-width: 40%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-srow-btn {\n width: 32px;\n height: 32px;\n background: transparent;\n color: var(--bm-icon);\n border-radius: 7px;\n}\n.bm-srow-btn:disabled {\n opacity: 0.35;\n}\n.bm-sidebar .bm-srow-btn:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n.bm-sidebar .bm-srow-btn.bm-danger {\n color: var(--bm-danger-icon);\n}\n.bm-sidebar .bm-srow-btn.bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n}\n.bm-srow-sep {\n flex: none;\n width: 1px;\n height: 20px;\n margin: 0 2px;\n background: var(--bm-divider);\n}\n.bm-outline-n {\n width: 18px;\n font-family: var(--mono);\n font-size: 11px;\n color: oklch(0.55 0.01 255);\n}\n.bm-outline-label {\n flex: 1;\n min-width: 0;\n font-weight: 500;\n}\n.bm-outline-meta {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 400;\n color: var(--muted);\n}\n\n/* Navigation and footer link cards */\n.bm-nav-card {\n padding: 12px 12px 14px;\n gap: 10px;\n}\n.bm-nested {\n margin: 6px 0 0 16px;\n}\n.bm-nav-children {\n margin-top: -4px;\n}\n.bm-nav-head {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.bm-nav-head .bm-icon-btn,\n.bm-column-head .bm-icon-btn {\n background: var(--bm-fill);\n color: oklch(0.45 0.01 255);\n}\n.bm-nav-head .bm-icon-btn:hover:not(:disabled),\n.bm-column-head .bm-icon-btn:hover:not(:disabled) {\n background: var(--bm-fill-hover);\n color: var(--bm-ink);\n}\n.bm-sidebar .bm-nav-head .bm-icon-btn.bm-danger,\n.bm-sidebar .bm-column-head .bm-icon-btn.bm-danger {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-icon);\n}\n.bm-sidebar .bm-nav-label {\n flex: 1;\n min-width: 0;\n min-height: 32px;\n padding: 0 8px;\n border-color: transparent;\n font-weight: 500;\n}\n.bm-sidebar .bm-nav-label:hover {\n border-color: var(--line);\n}\n.bm-column {\n padding: 0;\n gap: 0;\n}\n.bm-column-head {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px;\n cursor: grab;\n}\n.bm-column-links > summary {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 40px;\n padding: 0 12px;\n border-top: 1px solid var(--line-soft);\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n cursor: pointer;\n list-style: none;\n}\n.bm-column-links > summary::-webkit-details-marker {\n display: none;\n}\n.bm-column-links > :not(summary) {\n margin: 10px 12px 0;\n}\n.bm-column-links > :last-child {\n margin-bottom: 12px;\n}\n\n/* Wordmark preview */\n.bm-card-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.bm-card-head .bm-label {\n flex: none;\n}\n.bm-combo {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n:is(.bm-sidebar, .bm-popover) .bm-combo-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n width: auto;\n max-width: 140px;\n min-height: 38px;\n padding: 0 10px 0 12px;\n border: 0;\n border-left: 1px solid var(--bm-border);\n border-radius: 0;\n background: var(--fill-soft);\n color: var(--ink-2);\n font-family: var(--mono);\n font-size: 12px;\n font-weight: 400;\n text-align: left;\n}\n:is(.bm-sidebar, .bm-popover) .bm-combo-trigger:hover:not(:disabled) {\n background: var(--fill-hover);\n}\n:is(.bm-sidebar, .bm-popover) .bm-combo-trigger[aria-expanded=\"true\"] {\n background: var(--accent-tint);\n color: var(--accent-hover);\n}\n/* One URL field: the text input and the page picker share a single border. */\n.bm-linkfield {\n display: flex;\n align-items: stretch;\n min-height: 40px;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n overflow: hidden;\n}\n.bm-linkfield:focus-within {\n border-color: var(--bm-primary);\n box-shadow: 0 0 0 3px var(--bm-primary-ring);\n}\n.bm-linkfield > input {\n flex: 1;\n min-width: 0;\n border: 0 !important;\n box-shadow: none !important;\n border-radius: 0;\n min-height: 38px;\n background: transparent;\n}\n.bm-linkfield .bm-combo {\n flex: none;\n max-width: 45%;\n}\n.bm-linkfield .bm-combo-trigger {\n height: 100%;\n}\n.bm-linkfield .bm-combo-trigger:focus-visible {\n outline-offset: -2px;\n}\n.bm-combo-trigger > span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bm-combo-trigger .bm-combo-custom {\n color: var(--muted);\n}\n.bm-combo-panel {\n position: fixed;\n z-index: 6;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 6px;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n background: #fff;\n box-shadow: 0 6px 18px oklch(0.2 0.02 255 / 0.1);\n}\n.bm-combo-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n.bm-combo-group {\n margin: 6px 6px 2px;\n font-family: var(--mono);\n font-size: 10px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--muted);\n}\n.bm-combo-option {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 10px;\n padding: 6px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--ink);\n cursor: pointer;\n}\n.bm-combo-option[aria-selected=\"true\"] {\n font-weight: 600;\n color: var(--accent-hover);\n}\n.bm-combo-active {\n background: var(--fill);\n}\n.bm-combo-value {\n flex: none;\n max-width: 50%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--mono);\n font-size: 11px;\n color: var(--muted);\n}\n.bm-combo-empty {\n margin: 0;\n padding: 8px;\n font-size: 12px;\n color: var(--muted);\n}\n.bm-format {\n margin-top: -4px;\n}\n.bm-sidebar .bm-format button[aria-pressed=\"true\"] {\n background: #fff;\n color: var(--ink);\n box-shadow: var(--bm-shadow-segment-on);\n}\n.bm-wordmark {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 14px;\n border-radius: 10px;\n background: var(--bm-fill-soft);\n}\n.bm-wordmark-name {\n font-size: 24px;\n font-weight: 600;\n letter-spacing: -0.03em;\n}\n.bm-alert-notice {\n flex-direction: row;\n align-items: flex-start;\n gap: 8px;\n color: var(--warn-ink);\n}\n.bm-alert-notice .bm-icon {\n margin-top: 2px;\n flex: none;\n}\n\n/*\n * Button system. Three variants, one danger modifier, one rule set.\n * secondary (default): neutral fill, ink text.\n * .bm-primary: the one main action of a surface. Solid accent, white text (AA).\n * .bm-tertiary: low emphasis text button (Cancel, Reset). No fill, no underline, grey fill on hover.\n * .bm-danger: modifier. primary = solid red, secondary = red text, tertiary = red text.\n * The scope list gives every rule enough specificity to beat the per-surface defaults above,\n * so the hover state of one variant can never fall back to the secondary fill.\n */\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button:where(.bm-primary, .bm-tertiary, .bm-danger):not(.bm-icon-btn, .bm-save) {\n transition:\n background-color 0.12s,\n color 0.12s;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary {\n background: var(--bm-primary);\n color: #fff;\n box-shadow: none;\n font-weight: 600;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary:hover:not(:disabled) {\n background: var(--bm-primary-hover);\n color: #fff;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary.bm-danger {\n background: var(--bm-danger);\n color: #fff;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-primary.bm-danger:hover:not(:disabled) {\n background: var(--danger-hover);\n color: #fff;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-danger:not(.bm-primary, .bm-tertiary, .bm-icon-btn) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-danger:not(.bm-primary, .bm-tertiary, .bm-icon-btn):hover:not(:disabled) {\n background: oklch(0.93 0.04 25);\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary {\n min-height: 32px;\n padding: 0 10px;\n border-radius: 8px;\n background: transparent;\n color: var(--bm-label);\n font-weight: 400;\n box-shadow: none;\n text-decoration: none;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal) button.bm-tertiary {\n min-height: 38px;\n font-size: 14px;\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary:hover:not(:disabled) {\n background: var(--bm-fill);\n color: var(--bm-ink);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary.bm-danger {\n background: transparent;\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button.bm-tertiary.bm-danger:hover:not(:disabled) {\n background: var(--bm-danger-soft);\n color: var(--bm-danger-text);\n}\n:is(.bm-dialog, .bm-popover, .bm-modal, .bm-sidebar) button:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.bm-save:hover:not(:disabled) {\n background: var(--accent-hover);\n color: #fff;\n}\n.bm-sidebar .bm-save:hover:not(:disabled) {\n background: var(--accent-hover);\n color: #fff;\n}\n.bm-popover .bm-actions-remove,\n.bm-dialog .bm-actions-remove {\n margin-right: auto;\n}\n.bm-modal :where(button:not([role=\"tab\"], .bm-library-pick, .bm-icon-btn, .bm-tertiary)) {\n min-height: 38px;\n padding: 0 16px;\n border: 0;\n border-radius: 8px;\n background: var(--fill);\n color: var(--ink);\n font-size: 14px;\n font-weight: 400;\n}\n.bm-modal :where(button:not([role=\"tab\"], .bm-library-pick, .bm-icon-btn, .bm-tertiary)):hover:not(:disabled) {\n background: var(--fill-hover);\n}\n.bm-modal .bm-dropzone {\n font-family: var(--sans);\n}\n\n/* Design tab */\n.bm-colorrow {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.bm-colorpick {\n flex: none;\n width: 40px !important;\n height: 40px;\n min-height: 40px !important;\n padding: 2px !important;\n border: 1px solid var(--bm-border);\n border-radius: 8px;\n background: #fff;\n cursor: pointer;\n}\n.bm-colorhex {\n flex: 1;\n min-width: 0;\n font-family: var(--mono);\n font-size: 13px;\n text-transform: lowercase;\n}\n.bm-colorhex[aria-invalid=\"true\"] {\n border-color: var(--bm-danger);\n}\n.bm-overrides {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--bm-border);\n border-radius: 10px;\n overflow: hidden;\n}\n.bm-override-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 10px 8px 12px;\n}\n.bm-override-row + .bm-override-row {\n border-top: 1px solid var(--bm-divider);\n}\n.bm-override-label {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--bm-label);\n}\n.bm-override-label .bm-meta-tag {\n font-size: 10px;\n}\n.bm-override-row .bm-colorpick {\n width: 32px !important;\n height: 32px;\n min-height: 32px !important;\n padding: 1px !important;\n border-radius: 7px;\n}\n.bm-override-row .bm-colorhex {\n flex: none;\n width: 104px;\n min-height: 36px;\n padding: 0 10px;\n}\n.bm-tone-matrix {\n display: grid;\n grid-template-columns: 60px minmax(0, 1fr) minmax(0, 1fr);\n gap: 8px;\n align-items: stretch;\n}\n.bm-tone-pick {\n border: 0;\n text-align: left;\n font: inherit;\n cursor: pointer;\n}\n.bm-tone-cell[aria-pressed=\"true\"] {\n outline: 2px solid var(--bm-primary);\n outline-offset: 0;\n}\n.bm-tone-head {\n font-family: var(--mono);\n font-size: 10px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--muted);\n}\n.bm-tone-name {\n align-self: center;\n font-size: 12px;\n font-weight: 500;\n color: var(--ink-2);\n}\n.bm-tone-cell {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n min-width: 0;\n min-height: 46px;\n padding: 0 10px;\n border-radius: 8px;\n overflow: hidden;\n white-space: nowrap;\n}\n.bm-tone-aa {\n flex: none;\n font-size: 16px;\n font-weight: 600;\n}\n.bm-tone-muted {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 11px;\n}\n.bm-tone-chip {\n flex: none;\n padding: 2px 6px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n}\n.bm-tone-link {\n flex: none;\n font-size: 11px;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.bm-contrast-list {\n margin: 6px 0 0;\n padding-left: 16px;\n font-family: var(--mono);\n font-size: 11px;\n color: var(--warn-ink);\n}\n.bm-range {\n flex: 1;\n min-width: 0;\n min-height: 28px;\n accent-color: var(--accent);\n cursor: pointer;\n}\n/* Preview: the only editor UI left on screen. */\n.bm-exit-preview {\n position: fixed;\n z-index: 7;\n right: 16px;\n bottom: 16px;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 40px;\n padding: 0 16px;\n border: 0;\n border-radius: 999px;\n background: var(--ink);\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n box-shadow: 0 10px 30px oklch(0.2 0.02 255 / 0.3);\n}\n.bm-exit-preview:hover {\n background: oklch(0.28 0.012 255);\n}\n.bm-exit-preview:focus-visible {\n outline-color: oklch(0.82 0.14 145);\n outline-offset: 3px;\n}\n.bm-srow-add {\n display: flex;\n justify-content: flex-end;\n padding-top: 6px;\n}\n.bm-sidebar .bm-add-section {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-height: 32px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: var(--bm-primary);\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n}\n.bm-sidebar .bm-add-section:hover {\n background: var(--bm-primary-hover);\n}\n";
20145
20592
  //#endregion
20146
20593
  //#region src/ui/styles.ts
20147
20594
  function boxStyle(rect, offset = 0) {