@linto-ai/transcript-ui-webcomponent 0.9.23-unstable.202609181617 → 0.9.23

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.
@@ -3544,6 +3544,23 @@ var LintoEditor = (function(exports) {
3544
3544
  }
3545
3545
  return ret;
3546
3546
  }
3547
+ function createSlots(slots, dynamicSlots) {
3548
+ for (let i2 = 0; i2 < dynamicSlots.length; i2++) {
3549
+ const slot = dynamicSlots[i2];
3550
+ if (isArray(slot)) {
3551
+ for (let j = 0; j < slot.length; j++) {
3552
+ slots[slot[j].name] = slot[j].fn;
3553
+ }
3554
+ } else if (slot) {
3555
+ slots[slot.name] = slot.key ? (...args) => {
3556
+ const res = slot.fn(...args);
3557
+ if (res) res.key = slot.key;
3558
+ return res;
3559
+ } : slot.fn;
3560
+ }
3561
+ }
3562
+ return slots;
3563
+ }
3547
3564
  function renderSlot(slots, name, props, fallback, noSlotted, branchKey) {
3548
3565
  if (props == null) props = {};
3549
3566
  if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) {
@@ -9551,8 +9568,8 @@ var LintoEditor = (function(exports) {
9551
9568
  }
9552
9569
  return core;
9553
9570
  }
9554
- const _hoisted_1$H = ["aria-label"];
9555
- const _sfc_main$O = /* @__PURE__ */ defineComponent({
9571
+ const _hoisted_1$I = ["aria-label"];
9572
+ const _sfc_main$Q = /* @__PURE__ */ defineComponent({
9556
9573
  __name: "Badge",
9557
9574
  props: {
9558
9575
  ariaLabel: { type: String }
@@ -9564,11 +9581,11 @@ var LintoEditor = (function(exports) {
9564
9581
  "aria-label": __props.ariaLabel
9565
9582
  }, [
9566
9583
  renderSlot(_ctx.$slots, "default", {}, void 0, true)
9567
- ], 8, _hoisted_1$H);
9584
+ ], 8, _hoisted_1$I);
9568
9585
  };
9569
9586
  }
9570
9587
  });
9571
- const _style_0$G = "\n.editor-badge[data-v-392808cc] {\n display: inline-flex;\n align-items: center;\n padding: 2px var(--spacing-sm);\n font-size: var(--font-size-xs);\n font-weight: 500;\n color: var(--color-text-muted);\n background-color: var(--color-surface);\n border: 1px solid var(--color-border-light);\n border-radius: var(--radius-sm);\n white-space: nowrap;\n}\n";
9588
+ const _style_0$H = "\n.editor-badge[data-v-392808cc] {\n display: inline-flex;\n align-items: center;\n padding: 2px var(--spacing-sm);\n font-size: var(--font-size-xs);\n font-weight: 500;\n color: var(--color-text-muted);\n background-color: var(--color-surface);\n border: 1px solid var(--color-border-light);\n border-radius: var(--radius-sm);\n white-space: nowrap;\n}\n";
9572
9589
  const _export_sfc = (sfc, props) => {
9573
9590
  const target = sfc.__vccOpts || sfc;
9574
9591
  for (const [key, val] of props) {
@@ -9576,7 +9593,7 @@ var LintoEditor = (function(exports) {
9576
9593
  }
9577
9594
  return target;
9578
9595
  };
9579
- const Badge = /* @__PURE__ */ _export_sfc(_sfc_main$O, [["styles", [_style_0$G]], ["__scopeId", "data-v-392808cc"]]);
9596
+ const Badge = /* @__PURE__ */ _export_sfc(_sfc_main$Q, [["styles", [_style_0$H]], ["__scopeId", "data-v-392808cc"]]);
9580
9597
  const hasA11yProp = (props) => {
9581
9598
  for (const prop in props) {
9582
9599
  if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
@@ -10039,12 +10056,12 @@ var LintoEditor = (function(exports) {
10039
10056
  md: 20,
10040
10057
  lg: 24
10041
10058
  };
10042
- const _hoisted_1$G = {
10059
+ const _hoisted_1$H = {
10043
10060
  key: 1,
10044
10061
  class: "editor-icon editor-icon--missing",
10045
10062
  "aria-hidden": "true"
10046
10063
  };
10047
- const _sfc_main$N = /* @__PURE__ */ defineComponent({
10064
+ const _sfc_main$P = /* @__PURE__ */ defineComponent({
10048
10065
  __name: "EditorIcon",
10049
10066
  props: {
10050
10067
  name: { type: String },
@@ -10063,18 +10080,18 @@ var LintoEditor = (function(exports) {
10063
10080
  style: normalizeStyle(style.value),
10064
10081
  class: normalizeClass(["editor-icon", { "editor-icon--spin": __props.spin }]),
10065
10082
  "aria-hidden": "true"
10066
- }, null, 8, ["style", "class"])) : (openBlock(), createElementBlock("span", _hoisted_1$G, "?"));
10083
+ }, null, 8, ["style", "class"])) : (openBlock(), createElementBlock("span", _hoisted_1$H, "?"));
10067
10084
  };
10068
10085
  }
10069
10086
  });
10070
- const _style_0$F = "\n.editor-icon[data-v-bdd2a2df] {\n flex-shrink: 0;\n}\n.editor-icon--missing[data-v-bdd2a2df] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n opacity: 0.5;\n font-size: 1em;\n line-height: 1;\n}\n.editor-icon--spin[data-v-bdd2a2df] {\n animation: editor-icon-spin-bdd2a2df 1s linear infinite;\n}\n@keyframes editor-icon-spin-bdd2a2df {\nto {\n transform: rotate(360deg);\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.editor-icon--spin[data-v-bdd2a2df] {\n animation: none;\n}\n}\n";
10071
- const EditorIcon = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["styles", [_style_0$F]], ["__scopeId", "data-v-bdd2a2df"]]);
10072
- const _hoisted_1$F = ["type", "disabled", "aria-disabled", "aria-label"];
10073
- const _hoisted_2$v = {
10087
+ const _style_0$G = "\n.editor-icon[data-v-bdd2a2df] {\n flex-shrink: 0;\n}\n.editor-icon--missing[data-v-bdd2a2df] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n opacity: 0.5;\n font-size: 1em;\n line-height: 1;\n}\n.editor-icon--spin[data-v-bdd2a2df] {\n animation: editor-icon-spin-bdd2a2df 1s linear infinite;\n}\n@keyframes editor-icon-spin-bdd2a2df {\nto {\n transform: rotate(360deg);\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.editor-icon--spin[data-v-bdd2a2df] {\n animation: none;\n}\n}\n";
10088
+ const EditorIcon = /* @__PURE__ */ _export_sfc(_sfc_main$P, [["styles", [_style_0$G]], ["__scopeId", "data-v-bdd2a2df"]]);
10089
+ const _hoisted_1$G = ["type", "disabled", "aria-disabled", "aria-label"];
10090
+ const _hoisted_2$w = {
10074
10091
  key: 3,
10075
10092
  class: "editor-btn__label"
10076
10093
  };
10077
- const _sfc_main$M = /* @__PURE__ */ defineComponent({
10094
+ const _sfc_main$O = /* @__PURE__ */ defineComponent({
10078
10095
  __name: "Button",
10079
10096
  props: {
10080
10097
  label: { type: String },
@@ -10127,7 +10144,7 @@ var LintoEditor = (function(exports) {
10127
10144
  name: __props.icon,
10128
10145
  size: iconSize.value
10129
10146
  }, null, 8, ["name", "size"])) : _ctx.$slots.icon ? renderSlot(_ctx.$slots, "icon", {}, void 0, true, 2) : createCommentVNode("", true),
10130
- hasLabel.value ? (openBlock(), createElementBlock("span", _hoisted_2$v, [
10147
+ hasLabel.value ? (openBlock(), createElementBlock("span", _hoisted_2$w, [
10131
10148
  renderSlot(_ctx.$slots, "default", {}, () => [
10132
10149
  createTextVNode(toDisplayString(__props.label), 1)
10133
10150
  ], true)
@@ -10137,13 +10154,13 @@ var LintoEditor = (function(exports) {
10137
10154
  name: __props.iconRight,
10138
10155
  size: iconSize.value
10139
10156
  }, null, 8, ["name", "size"])) : _ctx.$slots["icon-right"] ? renderSlot(_ctx.$slots, "icon-right", {}, void 0, true, 5) : createCommentVNode("", true)
10140
- ], 10, _hoisted_1$F);
10157
+ ], 10, _hoisted_1$G);
10141
10158
  };
10142
10159
  }
10143
10160
  });
10144
- const _style_0$E = "\n.transcript-ui-root .editor-btn[data-v-050bd95b] {\n /* Default tokens — overridden by variant/intent/size modifiers */\n --btn-bg: transparent;\n --btn-text: var(--color-text-secondary);\n --btn-border-color: var(--color-border);\n --btn-hover-bg: var(--color-surface-hover);\n --btn-hover-text: var(--color-text-primary);\n --btn-padding-y: 0;\n --btn-padding-x: var(--spacing-sm);\n --btn-font-size: var(--font-size-xs);\n --btn-height: 32px;\n --btn-gap: var(--spacing-xs);\n\n /* Same reset as every other custom button in this codebase (see\n EditableText, EditorCheckbox, Tabs, SpeakerPopover, TranscriptionTurn):\n `all: unset` clears the UA button chrome (margin, appearance, inherited\n font mismatches on Safari/Firefox, the Firefox ::-moz-focus-inner\n padding) that the previous per-property overrides below left in place.\n Every property the button actually needs is re-declared after it. */\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--btn-gap);\n height: var(--btn-height);\n padding: var(--btn-padding-y) var(--btn-padding-x);\n font-family: var(--font-family);\n font-size: var(--btn-font-size);\n font-weight: 500;\n line-height: 1;\n color: var(--btn-text);\n background-color: var(--btn-bg);\n border: 1px solid var(--btn-border-color);\n border-radius: var(--radius-sm);\n cursor: pointer;\n white-space: nowrap;\n transition:\n background-color var(--transition-duration),\n color var(--transition-duration),\n border-color var(--transition-duration);\n}\n.transcript-ui-root .editor-btn[data-v-050bd95b]:hover:not(:disabled) {\n background-color: var(--btn-hover-bg);\n color: var(--btn-hover-text);\n}\n.transcript-ui-root .editor-btn[data-v-050bd95b]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n/* Note: this rule is repeated lower in the file (after variants) to win the\n cascade on the variant CSS vars. Keep this lightweight version for the\n cursor and hover suppression. */\n.transcript-ui-root .editor-btn[data-v-050bd95b]:disabled {\n cursor: not-allowed;\n}\n.transcript-ui-root .editor-btn[data-v-050bd95b]:disabled:hover {\n background-color: var(--btn-bg);\n color: var(--btn-text);\n}\n.editor-btn__label[data-v-050bd95b] {\n /* //overflow: hidden;\n text-overflow: ellipsis; */\n text-overflow: ellipsis;\n text-box: cap alphabetic;\n}\n\n/* Sizes.\n .transcript-ui-root prefix here too — not because Nextcloud could ever\n target --btn-* directly, but because these vars are read by the BASE\n .editor-btn rule (also prefixed, so specificity (0,3,0)): if a variant\n rule sets the same custom property at a lower specificity (0,2,0), the\n base rule's default wins over it regardless of source order, silently\n breaking every variant. All rules touching --btn-* must stay at the same\n specificity as the base rule. */\n.transcript-ui-root .editor-btn--sm[data-v-050bd95b] {\n /* defaults */\n}\n.transcript-ui-root .editor-btn--md[data-v-050bd95b] {\n --btn-padding-y: 0;\n --btn-padding-x: var(--spacing-md);\n --btn-font-size: var(--font-size-sm);\n --btn-height: 40px;\n}\n.transcript-ui-root .editor-btn--lg[data-v-050bd95b] {\n --btn-padding-y: 0;\n --btn-padding-x: var(--spacing-md);\n --btn-font-size: var(--font-size-base);\n --btn-height: 44px;\n}\n\n/* Icon-only: square */\n.transcript-ui-root .editor-btn--icon-only[data-v-050bd95b] {\n width: var(--btn-height);\n padding: 0;\n}\n.transcript-ui-root .editor-btn--block[data-v-050bd95b] {\n display: flex;\n width: 100%;\n}\n\n/* Variants — default intent */\n.transcript-ui-root .editor-btn--primary[data-v-050bd95b] {\n --btn-bg: var(--color-primary);\n --btn-text: var(--color-white);\n --btn-border-color: var(--color-primary);\n --btn-hover-bg: var(--color-primary-hover);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--secondary[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-primary);\n --btn-border-color: var(--color-primary);\n --btn-hover-bg: var(--color-primary);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--tertiary[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-text-primary);\n --btn-border-color: var(--color-border);\n --btn-hover-bg: var(--color-surface-hover);\n --btn-hover-text: var(--color-text-primary);\n}\n.transcript-ui-root .editor-btn--transparent[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-text-secondary);\n --btn-border-color: transparent;\n --btn-hover-bg: var(--color-surface-hover);\n --btn-hover-text: var(--color-text-primary);\n}\n\n/* Literal theme inversion: background = the theme's text color and\n vice-versa — high contrast in both light and dark themes without\n borrowing the primary color's semantics. */\n.transcript-ui-root .editor-btn--inverse[data-v-050bd95b] {\n --btn-bg: var(--color-text-primary);\n --btn-text: var(--color-background);\n --btn-border-color: transparent;\n --btn-hover-bg: var(--color-text-secondary);\n --btn-hover-text: var(--color-background);\n}\n\n/* Destructive intent overrides */\n.transcript-ui-root .editor-btn--destructive.editor-btn--primary[data-v-050bd95b] {\n --btn-bg: var(--color-danger);\n --btn-text: var(--color-white);\n --btn-border-color: var(--color-danger);\n --btn-hover-bg: var(--color-danger-hover);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--destructive.editor-btn--secondary[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-danger);\n --btn-border-color: var(--color-danger);\n --btn-hover-bg: var(--color-danger);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--destructive.editor-btn--tertiary[data-v-050bd95b],\n.transcript-ui-root .editor-btn--destructive.editor-btn--transparent[data-v-050bd95b] {\n --btn-text: var(--color-danger);\n --btn-hover-bg: var(--color-danger-soft);\n --btn-hover-text: var(--color-danger);\n}\n\n/* Disabled: gray-out regardless of variant. Placed after the variants so the\n CSS var overrides win the cascade (same specificity, last declaration). */\n.transcript-ui-root .editor-btn[data-v-050bd95b]:disabled {\n --btn-bg: var(--color-surface);\n --btn-text: var(--color-text-muted);\n --btn-border-color: var(--color-border);\n --btn-hover-bg: var(--color-surface);\n --btn-hover-text: var(--color-text-muted);\n}\n\n/* The transparent variant has no chrome when enabled — disabling it must not\n ADD a box; the muted text alone carries the disabled signal. */\n.transcript-ui-root .editor-btn--transparent[data-v-050bd95b]:disabled {\n --btn-bg: transparent;\n --btn-border-color: transparent;\n --btn-hover-bg: transparent;\n}\n\n/* Inverse stays a filled, borderless chip when disabled — dimmed, but the\n silhouette must not change. */\n.transcript-ui-root .editor-btn--inverse[data-v-050bd95b]:disabled {\n --btn-bg: var(--color-surface-hover);\n --btn-border-color: transparent;\n --btn-hover-bg: var(--color-surface-hover);\n}\n";
10145
- const Button = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["styles", [_style_0$E]], ["__scopeId", "data-v-050bd95b"]]);
10146
- const _sfc_main$L = /* @__PURE__ */ defineComponent({
10161
+ const _style_0$F = "\n.transcript-ui-root .editor-btn[data-v-050bd95b] {\n /* Default tokens — overridden by variant/intent/size modifiers */\n --btn-bg: transparent;\n --btn-text: var(--color-text-secondary);\n --btn-border-color: var(--color-border);\n --btn-hover-bg: var(--color-surface-hover);\n --btn-hover-text: var(--color-text-primary);\n --btn-padding-y: 0;\n --btn-padding-x: var(--spacing-sm);\n --btn-font-size: var(--font-size-xs);\n --btn-height: 32px;\n --btn-gap: var(--spacing-xs);\n\n /* Same reset as every other custom button in this codebase (see\n EditableText, EditorCheckbox, Tabs, SpeakerPopover, TranscriptionTurn):\n `all: unset` clears the UA button chrome (margin, appearance, inherited\n font mismatches on Safari/Firefox, the Firefox ::-moz-focus-inner\n padding) that the previous per-property overrides below left in place.\n Every property the button actually needs is re-declared after it. */\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--btn-gap);\n height: var(--btn-height);\n padding: var(--btn-padding-y) var(--btn-padding-x);\n font-family: var(--font-family);\n font-size: var(--btn-font-size);\n font-weight: 500;\n line-height: 1;\n color: var(--btn-text);\n background-color: var(--btn-bg);\n border: 1px solid var(--btn-border-color);\n border-radius: var(--radius-sm);\n cursor: pointer;\n white-space: nowrap;\n transition:\n background-color var(--transition-duration),\n color var(--transition-duration),\n border-color var(--transition-duration);\n}\n.transcript-ui-root .editor-btn[data-v-050bd95b]:hover:not(:disabled) {\n background-color: var(--btn-hover-bg);\n color: var(--btn-hover-text);\n}\n.transcript-ui-root .editor-btn[data-v-050bd95b]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n/* Note: this rule is repeated lower in the file (after variants) to win the\n cascade on the variant CSS vars. Keep this lightweight version for the\n cursor and hover suppression. */\n.transcript-ui-root .editor-btn[data-v-050bd95b]:disabled {\n cursor: not-allowed;\n}\n.transcript-ui-root .editor-btn[data-v-050bd95b]:disabled:hover {\n background-color: var(--btn-bg);\n color: var(--btn-text);\n}\n.editor-btn__label[data-v-050bd95b] {\n /* //overflow: hidden;\n text-overflow: ellipsis; */\n text-overflow: ellipsis;\n text-box: cap alphabetic;\n}\n\n/* Sizes.\n .transcript-ui-root prefix here too — not because Nextcloud could ever\n target --btn-* directly, but because these vars are read by the BASE\n .editor-btn rule (also prefixed, so specificity (0,3,0)): if a variant\n rule sets the same custom property at a lower specificity (0,2,0), the\n base rule's default wins over it regardless of source order, silently\n breaking every variant. All rules touching --btn-* must stay at the same\n specificity as the base rule. */\n.transcript-ui-root .editor-btn--sm[data-v-050bd95b] {\n /* defaults */\n}\n.transcript-ui-root .editor-btn--md[data-v-050bd95b] {\n --btn-padding-y: 0;\n --btn-padding-x: var(--spacing-md);\n --btn-font-size: var(--font-size-sm);\n --btn-height: 40px;\n}\n.transcript-ui-root .editor-btn--lg[data-v-050bd95b] {\n --btn-padding-y: 0;\n --btn-padding-x: var(--spacing-md);\n --btn-font-size: var(--font-size-base);\n --btn-height: 44px;\n}\n\n/* Icon-only: square */\n.transcript-ui-root .editor-btn--icon-only[data-v-050bd95b] {\n width: var(--btn-height);\n padding: 0;\n}\n.transcript-ui-root .editor-btn--block[data-v-050bd95b] {\n display: flex;\n width: 100%;\n}\n\n/* Variants — default intent */\n.transcript-ui-root .editor-btn--primary[data-v-050bd95b] {\n --btn-bg: var(--color-primary);\n --btn-text: var(--color-white);\n --btn-border-color: var(--color-primary);\n --btn-hover-bg: var(--color-primary-hover);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--secondary[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-primary);\n --btn-border-color: var(--color-primary);\n --btn-hover-bg: var(--color-primary);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--tertiary[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-text-primary);\n --btn-border-color: var(--color-border);\n --btn-hover-bg: var(--color-surface-hover);\n --btn-hover-text: var(--color-text-primary);\n}\n.transcript-ui-root .editor-btn--transparent[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-text-secondary);\n --btn-border-color: transparent;\n --btn-hover-bg: var(--color-surface-hover);\n --btn-hover-text: var(--color-text-primary);\n}\n\n/* Literal theme inversion: background = the theme's text color and\n vice-versa — high contrast in both light and dark themes without\n borrowing the primary color's semantics. */\n.transcript-ui-root .editor-btn--inverse[data-v-050bd95b] {\n --btn-bg: var(--color-text-primary);\n --btn-text: var(--color-background);\n --btn-border-color: transparent;\n --btn-hover-bg: var(--color-text-secondary);\n --btn-hover-text: var(--color-background);\n}\n\n/* Destructive intent overrides */\n.transcript-ui-root .editor-btn--destructive.editor-btn--primary[data-v-050bd95b] {\n --btn-bg: var(--color-danger);\n --btn-text: var(--color-white);\n --btn-border-color: var(--color-danger);\n --btn-hover-bg: var(--color-danger-hover);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--destructive.editor-btn--secondary[data-v-050bd95b] {\n --btn-bg: transparent;\n --btn-text: var(--color-danger);\n --btn-border-color: var(--color-danger);\n --btn-hover-bg: var(--color-danger);\n --btn-hover-text: var(--color-white);\n}\n.transcript-ui-root .editor-btn--destructive.editor-btn--tertiary[data-v-050bd95b],\n.transcript-ui-root .editor-btn--destructive.editor-btn--transparent[data-v-050bd95b] {\n --btn-text: var(--color-danger);\n --btn-hover-bg: var(--color-danger-soft);\n --btn-hover-text: var(--color-danger);\n}\n\n/* Disabled: gray-out regardless of variant. Placed after the variants so the\n CSS var overrides win the cascade (same specificity, last declaration). */\n.transcript-ui-root .editor-btn[data-v-050bd95b]:disabled {\n --btn-bg: var(--color-surface);\n --btn-text: var(--color-text-muted);\n --btn-border-color: var(--color-border);\n --btn-hover-bg: var(--color-surface);\n --btn-hover-text: var(--color-text-muted);\n}\n\n/* The transparent variant has no chrome when enabled — disabling it must not\n ADD a box; the muted text alone carries the disabled signal. */\n.transcript-ui-root .editor-btn--transparent[data-v-050bd95b]:disabled {\n --btn-bg: transparent;\n --btn-border-color: transparent;\n --btn-hover-bg: transparent;\n}\n\n/* Inverse stays a filled, borderless chip when disabled — dimmed, but the\n silhouette must not change. */\n.transcript-ui-root .editor-btn--inverse[data-v-050bd95b]:disabled {\n --btn-bg: var(--color-surface-hover);\n --btn-border-color: transparent;\n --btn-hover-bg: var(--color-surface-hover);\n}\n";
10162
+ const Button = /* @__PURE__ */ _export_sfc(_sfc_main$O, [["styles", [_style_0$F]], ["__scopeId", "data-v-050bd95b"]]);
10163
+ const _sfc_main$N = /* @__PURE__ */ defineComponent({
10147
10164
  __name: "CopyButton",
10148
10165
  props: {
10149
10166
  icon: { default: "copy", type: String },
@@ -10211,8 +10228,8 @@ var LintoEditor = (function(exports) {
10211
10228
  };
10212
10229
  }
10213
10230
  });
10214
- const _style_0$D = "\n.copy-btn--copied[data-v-5b088678] {\n color: var(--color-success, #2e7d32);\n}\n.copy-icon-enter-active[data-v-5b088678],\n.copy-icon-leave-active[data-v-5b088678] {\n transition:\n opacity var(--transition-duration) ease,\n scale var(--transition-duration) ease;\n}\n.copy-icon-enter-from[data-v-5b088678] {\n opacity: 0;\n scale: 0.6;\n}\n.copy-icon-leave-to[data-v-5b088678] {\n opacity: 0;\n scale: 0.6;\n}\n@media (prefers-reduced-motion: reduce) {\n.copy-icon-enter-active[data-v-5b088678],\n .copy-icon-leave-active[data-v-5b088678] {\n transition: none;\n}\n}\n";
10215
- const CopyButton = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["styles", [_style_0$D]], ["__scopeId", "data-v-5b088678"]]);
10231
+ const _style_0$E = "\n.copy-btn--copied[data-v-5b088678] {\n color: var(--color-success, #2e7d32);\n}\n.copy-icon-enter-active[data-v-5b088678],\n.copy-icon-leave-active[data-v-5b088678] {\n transition:\n opacity var(--transition-duration) ease,\n scale var(--transition-duration) ease;\n}\n.copy-icon-enter-from[data-v-5b088678] {\n opacity: 0;\n scale: 0.6;\n}\n.copy-icon-leave-to[data-v-5b088678] {\n opacity: 0;\n scale: 0.6;\n}\n@media (prefers-reduced-motion: reduce) {\n.copy-icon-enter-active[data-v-5b088678],\n .copy-icon-leave-active[data-v-5b088678] {\n transition: none;\n}\n}\n";
10232
+ const CopyButton = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["styles", [_style_0$E]], ["__scopeId", "data-v-5b088678"]]);
10216
10233
  const fr = {
10217
10234
  "editor.loading": "Chargement…",
10218
10235
  "editor.loadError": "Erreur de chargement",
@@ -10529,10 +10546,10 @@ var LintoEditor = (function(exports) {
10529
10546
  locale: fallbackLocale
10530
10547
  };
10531
10548
  }
10532
- const _hoisted_1$E = { class: "code-block" };
10533
- const _hoisted_2$u = ["innerHTML"];
10534
- const _hoisted_3$n = { key: 1 };
10535
- const _sfc_main$K = /* @__PURE__ */ defineComponent({
10549
+ const _hoisted_1$F = { class: "code-block" };
10550
+ const _hoisted_2$v = ["innerHTML"];
10551
+ const _hoisted_3$o = { key: 1 };
10552
+ const _sfc_main$M = /* @__PURE__ */ defineComponent({
10536
10553
  __name: "CodeBlock",
10537
10554
  props: {
10538
10555
  code: { type: String },
@@ -10561,7 +10578,7 @@ var LintoEditor = (function(exports) {
10561
10578
  { immediate: true }
10562
10579
  );
10563
10580
  return (_ctx, _cache) => {
10564
- return openBlock(), createElementBlock("div", _hoisted_1$E, [
10581
+ return openBlock(), createElementBlock("div", _hoisted_1$F, [
10565
10582
  !__props.streaming ? (openBlock(), createBlock(CopyButton, {
10566
10583
  key: 0,
10567
10584
  class: "code-block__copy",
@@ -10574,13 +10591,13 @@ var LintoEditor = (function(exports) {
10574
10591
  highlighted.value ? (openBlock(), createElementBlock("code", {
10575
10592
  key: 0,
10576
10593
  innerHTML: highlighted.value
10577
- }, null, 8, _hoisted_2$u)) : (openBlock(), createElementBlock("code", _hoisted_3$n, toDisplayString(__props.code), 1))
10594
+ }, null, 8, _hoisted_2$v)) : (openBlock(), createElementBlock("code", _hoisted_3$o, toDisplayString(__props.code), 1))
10578
10595
  ])
10579
10596
  ]);
10580
10597
  };
10581
10598
  }
10582
10599
  });
10583
- const _style_0$C = "\n.code-block[data-v-ad87d1e4] {\n position: relative;\n}\n.code-block__copy[data-v-ad87d1e4] {\n position: absolute;\n top: var(--spacing-xs);\n right: var(--spacing-xs);\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n.code-block:hover .code-block__copy[data-v-ad87d1e4],\n.code-block:focus-within .code-block__copy[data-v-ad87d1e4] {\n opacity: 1;\n}\n.code-block pre[data-v-ad87d1e4] {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-md);\n background-color: var(--color-surface);\n border-radius: var(--radius-md);\n overflow-x: auto;\n border: 1px solid var(--color-border);\n}\n.code-block pre code[data-v-ad87d1e4] {\n padding: 0;\n background: none;\n font-family: var(--font-family-mono);\n font-size: 0.9em;\n}\n@media (prefers-reduced-motion: reduce) {\n.code-block__copy[data-v-ad87d1e4] {\n transition: none;\n}\n}\n";
10600
+ const _style_0$D = "\n.code-block[data-v-ad87d1e4] {\n position: relative;\n}\n.code-block__copy[data-v-ad87d1e4] {\n position: absolute;\n top: var(--spacing-xs);\n right: var(--spacing-xs);\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n.code-block:hover .code-block__copy[data-v-ad87d1e4],\n.code-block:focus-within .code-block__copy[data-v-ad87d1e4] {\n opacity: 1;\n}\n.code-block pre[data-v-ad87d1e4] {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-md);\n background-color: var(--color-surface);\n border-radius: var(--radius-md);\n overflow-x: auto;\n border: 1px solid var(--color-border);\n}\n.code-block pre code[data-v-ad87d1e4] {\n padding: 0;\n background: none;\n font-family: var(--font-family-mono);\n font-size: 0.9em;\n}\n@media (prefers-reduced-motion: reduce) {\n.code-block__copy[data-v-ad87d1e4] {\n transition: none;\n}\n}\n";
10584
10601
  const _style_1 = `/**
10585
10602
  * prism.js default theme for JavaScript, CSS and HTML
10586
10603
  * Based on dabblet (http://dabblet.com)
@@ -10706,19 +10723,19 @@ pre[class*="language-"] {
10706
10723
  cursor: help;
10707
10724
  }
10708
10725
  `;
10709
- const CodeBlock = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["styles", [_style_0$C, _style_1]], ["__scopeId", "data-v-ad87d1e4"]]);
10710
- const _hoisted_1$D = {
10726
+ const CodeBlock = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["styles", [_style_0$D, _style_1]], ["__scopeId", "data-v-ad87d1e4"]]);
10727
+ const _hoisted_1$E = {
10711
10728
  key: 0,
10712
10729
  class: "form-field__header"
10713
10730
  };
10714
- const _hoisted_2$t = ["for"];
10715
- const _hoisted_3$m = {
10731
+ const _hoisted_2$u = ["for"];
10732
+ const _hoisted_3$n = {
10716
10733
  key: 0,
10717
10734
  class: "form-field__required",
10718
10735
  "aria-hidden": "true"
10719
10736
  };
10720
10737
  const _hoisted_4$e = { class: "form-field__input-wrapper" };
10721
- const _hoisted_5$c = ["id", "disabled", "required", "aria-required", "aria-invalid", "aria-describedby"];
10738
+ const _hoisted_5$d = ["id", "disabled", "required", "aria-required", "aria-invalid", "aria-describedby"];
10722
10739
  const _hoisted_6$b = ["value"];
10723
10740
  const _hoisted_7$5 = ["type", "id", "disabled", "readonly", "placeholder", "autocomplete", "required", "aria-required", "aria-invalid", "aria-describedby"];
10724
10741
  const _hoisted_8$3 = {
@@ -10731,8 +10748,8 @@ pre[class*="language-"] {
10731
10748
  "aria-hidden": "true"
10732
10749
  };
10733
10750
  const _hoisted_10$3 = ["id"];
10734
- const _hoisted_11$1 = { class: "form-field__error" };
10735
- const _sfc_main$J = /* @__PURE__ */ defineComponent({
10751
+ const _hoisted_11$2 = { class: "form-field__error" };
10752
+ const _sfc_main$L = /* @__PURE__ */ defineComponent({
10736
10753
  __name: "FormInput",
10737
10754
  props: {
10738
10755
  field: { type: Object },
@@ -10842,14 +10859,14 @@ pre[class*="language-"] {
10842
10859
  return openBlock(), createElementBlock("div", {
10843
10860
  class: normalizeClass(rootClasses.value)
10844
10861
  }, [
10845
- __props.field.label ? (openBlock(), createElementBlock("div", _hoisted_1$D, [
10862
+ __props.field.label ? (openBlock(), createElementBlock("div", _hoisted_1$E, [
10846
10863
  createBaseVNode("label", {
10847
10864
  class: "form-field__label",
10848
10865
  for: id.value
10849
10866
  }, [
10850
10867
  createTextVNode(toDisplayString(__props.field.label) + " ", 1),
10851
- isRequired.value ? (openBlock(), createElementBlock("span", _hoisted_3$m, "*")) : createCommentVNode("", true)
10852
- ], 8, _hoisted_2$t),
10868
+ isRequired.value ? (openBlock(), createElementBlock("span", _hoisted_3$n, "*")) : createCommentVNode("", true)
10869
+ ], 8, _hoisted_2$u),
10853
10870
  renderSlot(_ctx.$slots, "content-after-label", {}, void 0, true)
10854
10871
  ])) : createCommentVNode("", true),
10855
10872
  createBaseVNode("div", _hoisted_4$e, [
@@ -10880,7 +10897,7 @@ pre[class*="language-"] {
10880
10897
  value: opt.value
10881
10898
  }, toDisplayString(opt.label), 9, _hoisted_6$b);
10882
10899
  }), 128))
10883
- ], 16, _hoisted_5$c)), [
10900
+ ], 16, _hoisted_5$d)), [
10884
10901
  [vModelSelect, draft.value]
10885
10902
  ]) : withDirectives((openBlock(), createElementBlock("input", mergeProps({
10886
10903
  key: 2,
@@ -10933,16 +10950,16 @@ pre[class*="language-"] {
10933
10950
  id: `${id.value}-error`,
10934
10951
  class: "form-field__info"
10935
10952
  }, [
10936
- createBaseVNode("span", _hoisted_11$1, toDisplayString(errorMessage.value), 1)
10953
+ createBaseVNode("span", _hoisted_11$2, toDisplayString(errorMessage.value), 1)
10937
10954
  ], 8, _hoisted_10$3)) : createCommentVNode("", true)
10938
10955
  ], 2);
10939
10956
  };
10940
10957
  }
10941
10958
  });
10942
- const _style_0$B = "\n/* ── Root ──────────────────────────────────────────────────────────── */\n.form-field[data-v-863d0b18] {\n --field-height: 40px;\n --field-padding-x: var(--spacing-md);\n --field-font-size: var(--font-size-sm);\n\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n width: 100%;\n}\n.form-field--sm[data-v-863d0b18] {\n --field-height: 32px;\n --field-padding-x: var(--spacing-sm);\n --field-font-size: var(--font-size-xs);\n}\n.form-field--lg[data-v-863d0b18] {\n --field-height: 44px;\n --field-padding-x: var(--spacing-md);\n --field-font-size: var(--font-size-base);\n}\n.form-field--disabled[data-v-863d0b18] {\n opacity: 0.7;\n}\n\n/* ── Header (label row) ────────────────────────────────────────────── */\n.form-field__header[data-v-863d0b18] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-sm);\n}\n.form-field__label[data-v-863d0b18] {\n display: block;\n margin: 0;\n font-size: var(--font-size-sm);\n font-weight: 600;\n line-height: 1.2;\n color: var(--color-text-primary);\n}\n.form-field--error .form-field__label[data-v-863d0b18] {\n color: var(--color-danger);\n}\n.form-field__required[data-v-863d0b18] {\n margin-left: 2px;\n color: var(--color-danger);\n}\n\n/* ── Input wrapper ─────────────────────────────────────────────────── */\n.form-field__input-wrapper[data-v-863d0b18] {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-sm);\n width: 100%;\n}\n\n/* ── Input ─────────────────────────────────────────────────────────── */\n.form-field__input[data-v-863d0b18] {\n flex: 1;\n box-sizing: border-box;\n height: var(--field-height);\n padding: 0 var(--field-padding-x);\n font-family: inherit;\n font-size: var(--field-font-size);\n line-height: 1.4;\n color: var(--color-text-primary);\n background-color: var(--color-background);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n outline: none;\n transition:\n border-color var(--transition-duration),\n box-shadow var(--transition-duration);\n}\n.form-field__input[data-v-863d0b18]::placeholder {\n color: var(--color-text-muted);\n opacity: 1;\n}\n.form-field__input[data-v-863d0b18]:hover:not(:disabled) {\n border-color: var(--color-text-muted);\n}\n.form-field__input[data-v-863d0b18]:focus-visible {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-primary) 20%, transparent);\n}\n.form-field__input[data-v-863d0b18]:disabled {\n cursor: not-allowed;\n background-color: var(--color-surface);\n color: var(--color-text-muted);\n}\n.form-field__input--fullwidth[data-v-863d0b18] {\n width: 100%;\n max-width: none;\n}\n.form-field__input--select[data-v-863d0b18] {\n cursor: pointer;\n appearance: auto;\n}\n.form-field__input--error[data-v-863d0b18] {\n border-color: var(--color-danger);\n}\n.form-field__input--error[data-v-863d0b18]:focus-visible {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-danger) 20%, transparent);\n}\n\n/* ── Confirmation actions ──────────────────────────────────────────── */\n.form-field__actions[data-v-863d0b18] {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-xs);\n flex-shrink: 0;\n}\n.form-field__actions--placeholder[data-v-863d0b18] {\n /* Reserve space so showing the buttons doesn't shift layout. */\n width: calc(var(--field-height) * 2 + var(--spacing-xs));\n height: var(--field-height);\n pointer-events: none;\n opacity: 0;\n}\n\n/* ── Info / error ──────────────────────────────────────────────────── */\n.form-field__info[data-v-863d0b18] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n}\n.form-field__error[data-v-863d0b18] {\n margin: 0;\n font-size: var(--font-size-xs);\n line-height: 1.2;\n color: var(--color-danger);\n}\n\n/* ── Inline layout ─────────────────────────────────────────────────── */\n.form-field--inline[data-v-863d0b18] {\n flex-direction: row;\n align-items: center;\n gap: var(--spacing-md);\n}\n.form-field--inline .form-field__header[data-v-863d0b18] {\n flex-shrink: 0;\n min-width: 120px;\n}\n.form-field--inline .form-field__input-wrapper[data-v-863d0b18] {\n flex: 1;\n}\n\n/* ── Reduced motion ────────────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n.form-field__input[data-v-863d0b18] {\n transition: none;\n}\n}\n";
10943
- const FormInput = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["styles", [_style_0$B]], ["__scopeId", "data-v-863d0b18"]]);
10944
- const _hoisted_1$C = ["disabled", "aria-label"];
10945
- const _sfc_main$I = /* @__PURE__ */ defineComponent({
10959
+ const _style_0$C = "\n/* ── Root ──────────────────────────────────────────────────────────── */\n.form-field[data-v-863d0b18] {\n --field-height: 40px;\n --field-padding-x: var(--spacing-md);\n --field-font-size: var(--font-size-sm);\n\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n width: 100%;\n}\n.form-field--sm[data-v-863d0b18] {\n --field-height: 32px;\n --field-padding-x: var(--spacing-sm);\n --field-font-size: var(--font-size-xs);\n}\n.form-field--lg[data-v-863d0b18] {\n --field-height: 44px;\n --field-padding-x: var(--spacing-md);\n --field-font-size: var(--font-size-base);\n}\n.form-field--disabled[data-v-863d0b18] {\n opacity: 0.7;\n}\n\n/* ── Header (label row) ────────────────────────────────────────────── */\n.form-field__header[data-v-863d0b18] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-sm);\n}\n.form-field__label[data-v-863d0b18] {\n display: block;\n margin: 0;\n font-size: var(--font-size-sm);\n font-weight: 600;\n line-height: 1.2;\n color: var(--color-text-primary);\n}\n.form-field--error .form-field__label[data-v-863d0b18] {\n color: var(--color-danger);\n}\n.form-field__required[data-v-863d0b18] {\n margin-left: 2px;\n color: var(--color-danger);\n}\n\n/* ── Input wrapper ─────────────────────────────────────────────────── */\n.form-field__input-wrapper[data-v-863d0b18] {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-sm);\n width: 100%;\n}\n\n/* ── Input ─────────────────────────────────────────────────────────── */\n.form-field__input[data-v-863d0b18] {\n flex: 1;\n box-sizing: border-box;\n height: var(--field-height);\n padding: 0 var(--field-padding-x);\n font-family: inherit;\n font-size: var(--field-font-size);\n line-height: 1.4;\n color: var(--color-text-primary);\n background-color: var(--color-background);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n outline: none;\n transition:\n border-color var(--transition-duration),\n box-shadow var(--transition-duration);\n}\n.form-field__input[data-v-863d0b18]::placeholder {\n color: var(--color-text-muted);\n opacity: 1;\n}\n.form-field__input[data-v-863d0b18]:hover:not(:disabled) {\n border-color: var(--color-text-muted);\n}\n.form-field__input[data-v-863d0b18]:focus-visible {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-primary) 20%, transparent);\n}\n.form-field__input[data-v-863d0b18]:disabled {\n cursor: not-allowed;\n background-color: var(--color-surface);\n color: var(--color-text-muted);\n}\n.form-field__input--fullwidth[data-v-863d0b18] {\n width: 100%;\n max-width: none;\n}\n.form-field__input--select[data-v-863d0b18] {\n cursor: pointer;\n appearance: auto;\n}\n.form-field__input--error[data-v-863d0b18] {\n border-color: var(--color-danger);\n}\n.form-field__input--error[data-v-863d0b18]:focus-visible {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-danger) 20%, transparent);\n}\n\n/* ── Confirmation actions ──────────────────────────────────────────── */\n.form-field__actions[data-v-863d0b18] {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-xs);\n flex-shrink: 0;\n}\n.form-field__actions--placeholder[data-v-863d0b18] {\n /* Reserve space so showing the buttons doesn't shift layout. */\n width: calc(var(--field-height) * 2 + var(--spacing-xs));\n height: var(--field-height);\n pointer-events: none;\n opacity: 0;\n}\n\n/* ── Info / error ──────────────────────────────────────────────────── */\n.form-field__info[data-v-863d0b18] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n}\n.form-field__error[data-v-863d0b18] {\n margin: 0;\n font-size: var(--font-size-xs);\n line-height: 1.2;\n color: var(--color-danger);\n}\n\n/* ── Inline layout ─────────────────────────────────────────────────── */\n.form-field--inline[data-v-863d0b18] {\n flex-direction: row;\n align-items: center;\n gap: var(--spacing-md);\n}\n.form-field--inline .form-field__header[data-v-863d0b18] {\n flex-shrink: 0;\n min-width: 120px;\n}\n.form-field--inline .form-field__input-wrapper[data-v-863d0b18] {\n flex: 1;\n}\n\n/* ── Reduced motion ────────────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n.form-field__input[data-v-863d0b18] {\n transition: none;\n}\n}\n";
10960
+ const FormInput = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["styles", [_style_0$C]], ["__scopeId", "data-v-863d0b18"]]);
10961
+ const _hoisted_1$D = ["disabled", "aria-label"];
10962
+ const _sfc_main$K = /* @__PURE__ */ defineComponent({
10946
10963
  __name: "EditableText",
10947
10964
  props: {
10948
10965
  modelValue: { type: String },
@@ -11016,12 +11033,12 @@ pre[class*="language-"] {
11016
11033
  disabled: __props.disabled,
11017
11034
  "aria-label": __props.ariaLabel,
11018
11035
  onClick: startEdit
11019
- }, toDisplayString(__props.modelValue || __props.placeholder), 9, _hoisted_1$C));
11036
+ }, toDisplayString(__props.modelValue || __props.placeholder), 9, _hoisted_1$D));
11020
11037
  };
11021
11038
  }
11022
11039
  });
11023
- const _style_0$A = "\n.transcript-ui-root .editable-text-display[data-v-ff6456c8] {\n all: unset;\n cursor: text;\n text-align: left;\n font: inherit;\n color: inherit;\n line-height: inherit;\n padding: 0;\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n min-width: 0;\n}\n.transcript-ui-root .editable-text-display[data-v-ff6456c8]:not(:disabled):hover {\n border-color: var(--color-border);\n}\n.transcript-ui-root .editable-text-display[data-v-ff6456c8]:disabled {\n cursor: default;\n}\n";
11024
- const EditableText = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["styles", [_style_0$A]], ["__scopeId", "data-v-ff6456c8"]]);
11040
+ const _style_0$B = "\n.transcript-ui-root .editable-text-display[data-v-ff6456c8] {\n all: unset;\n cursor: text;\n text-align: left;\n font: inherit;\n color: inherit;\n line-height: inherit;\n padding: 0;\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n min-width: 0;\n}\n.transcript-ui-root .editable-text-display[data-v-ff6456c8]:not(:disabled):hover {\n border-color: var(--color-border);\n}\n.transcript-ui-root .editable-text-display[data-v-ff6456c8]:disabled {\n cursor: default;\n}\n";
11041
+ const EditableText = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["styles", [_style_0$B]], ["__scopeId", "data-v-ff6456c8"]]);
11025
11042
  function serialize(input) {
11026
11043
  if (typeof input === "string") return `'${input}'`;
11027
11044
  return new Serializer().serialize(input);
@@ -15438,7 +15455,7 @@ pre[class*="language-"] {
15438
15455
  update
15439
15456
  };
15440
15457
  }
15441
- const _hoisted_1$B = ["dir"];
15458
+ const _hoisted_1$C = ["dir"];
15442
15459
  const PopperContentPropsDefaultValue = {
15443
15460
  side: "bottom",
15444
15461
  sideOffset: 0,
@@ -15731,7 +15748,7 @@ pre[class*="language-"] {
15731
15748
  "data-align",
15732
15749
  "dir",
15733
15750
  "style"
15734
- ]))], 12, _hoisted_1$B);
15751
+ ]))], 12, _hoisted_1$C);
15735
15752
  };
15736
15753
  }
15737
15754
  });
@@ -17549,7 +17566,7 @@ pre[class*="language-"] {
17549
17566
  }
17550
17567
  });
17551
17568
  var DropdownMenuTrigger_default = DropdownMenuTrigger_vue_vue_type_script_setup_true_lang_default;
17552
- const _sfc_main$H = /* @__PURE__ */ defineComponent({
17569
+ const _sfc_main$J = /* @__PURE__ */ defineComponent({
17553
17570
  __name: "EditorCheckbox",
17554
17571
  props: {
17555
17572
  modelValue: { type: Boolean },
@@ -17582,8 +17599,8 @@ pre[class*="language-"] {
17582
17599
  };
17583
17600
  }
17584
17601
  });
17585
- const _style_0$z = '\n.transcript-ui-root .checkbox[data-v-ed0978f7] {\n all: unset;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n border: 1.5px solid var(--color-border);\n border-radius: var(--radius-sm);\n background-color: var(--color-surface);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition:\n background-color var(--transition-duration),\n border-color var(--transition-duration);\n}\n.transcript-ui-root .checkbox[data-v-ed0978f7]:hover {\n border-color: var(--color-primary);\n}\n.transcript-ui-root .checkbox[data-v-ed0978f7]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.transcript-ui-root .checkbox[data-state="checked"][data-v-ed0978f7] {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n}\n.checkbox-indicator[data-v-ed0978f7] {\n color: var(--color-white, #fff);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n';
17586
- const EditorCheckbox = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["styles", [_style_0$z]], ["__scopeId", "data-v-ed0978f7"]]);
17602
+ const _style_0$A = '\n.transcript-ui-root .checkbox[data-v-ed0978f7] {\n all: unset;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n border: 1.5px solid var(--color-border);\n border-radius: var(--radius-sm);\n background-color: var(--color-surface);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition:\n background-color var(--transition-duration),\n border-color var(--transition-duration);\n}\n.transcript-ui-root .checkbox[data-v-ed0978f7]:hover {\n border-color: var(--color-primary);\n}\n.transcript-ui-root .checkbox[data-v-ed0978f7]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.transcript-ui-root .checkbox[data-state="checked"][data-v-ed0978f7] {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n}\n.checkbox-indicator[data-v-ed0978f7] {\n color: var(--color-white, #fff);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n';
17603
+ const EditorCheckbox = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["styles", [_style_0$A]], ["__scopeId", "data-v-ed0978f7"]]);
17587
17604
  function extend(destination) {
17588
17605
  for (var i2 = 1; i2 < arguments.length; i2++) {
17589
17606
  var source = arguments[i2];
@@ -21182,17 +21199,23 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21182
21199
  const tokens = f$1.lexer(md);
21183
21200
  const segments = [];
21184
21201
  let buffer = [];
21185
- const flush = () => {
21202
+ function renderGroup(group) {
21203
+ const list = group;
21204
+ list.links = tokens.links;
21205
+ return purify.sanitize(f$1.parser(list));
21206
+ }
21207
+ function flush() {
21186
21208
  if (buffer.length === 0) return;
21187
- const group = buffer;
21188
- group.links = tokens.links;
21189
- segments.push({ type: "html", html: purify.sanitize(f$1.parser(group)) });
21209
+ segments.push({ type: "html", html: renderGroup(buffer) });
21190
21210
  buffer = [];
21191
- };
21211
+ }
21192
21212
  for (const token of tokens) {
21193
21213
  if (token.type === "code") {
21194
21214
  flush();
21195
21215
  segments.push({ type: "code", code: token.text, lang: token.lang ?? "" });
21216
+ } else if (token.type === "table") {
21217
+ flush();
21218
+ segments.push({ type: "table", html: renderGroup([token]) });
21196
21219
  } else {
21197
21220
  buffer.push(token);
21198
21221
  }
@@ -21229,10 +21252,10 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21229
21252
  function getShadowRootSelection(root2) {
21230
21253
  return root2.getSelection?.() ?? null;
21231
21254
  }
21232
- const _hoisted_1$A = { class: "markdown-editor" };
21233
- const _hoisted_2$s = ["aria-label"];
21234
- const _hoisted_3$l = ["contenteditable"];
21235
- const _sfc_main$G = /* @__PURE__ */ defineComponent({
21255
+ const _hoisted_1$B = { class: "markdown-editor" };
21256
+ const _hoisted_2$t = ["aria-label"];
21257
+ const _hoisted_3$m = ["contenteditable"];
21258
+ const _sfc_main$I = /* @__PURE__ */ defineComponent({
21236
21259
  __name: "MarkdownEditor",
21237
21260
  props: {
21238
21261
  modelValue: { type: String },
@@ -21453,7 +21476,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21453
21476
  }
21454
21477
  );
21455
21478
  return (_ctx, _cache) => {
21456
- return openBlock(), createElementBlock("div", _hoisted_1$A, [
21479
+ return openBlock(), createElementBlock("div", _hoisted_1$B, [
21457
21480
  !__props.disabled ? (openBlock(), createElementBlock("div", {
21458
21481
  key: 0,
21459
21482
  class: "markdown-editor__toolbar",
@@ -21564,7 +21587,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21564
21587
  title: unref(t2)("mdToolbar.redo"),
21565
21588
  onClick: _cache[8] || (_cache[8] = ($event) => execCmd("redo"))
21566
21589
  }, null, 8, ["aria-label", "title"])
21567
- ], 8, _hoisted_2$s)) : createCommentVNode("", true),
21590
+ ], 8, _hoisted_2$t)) : createCommentVNode("", true),
21568
21591
  createBaseVNode("div", {
21569
21592
  ref: "editorEl",
21570
21593
  class: "markdown-editor__content",
@@ -21574,16 +21597,17 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21574
21597
  onPaste,
21575
21598
  onFocus: startSelectionListener,
21576
21599
  onBlur: stopSelectionListener
21577
- }, null, 40, _hoisted_3$l)
21600
+ }, null, 40, _hoisted_3$m)
21578
21601
  ]);
21579
21602
  };
21580
21603
  }
21581
21604
  });
21582
- const _style_0$y = "\n.markdown-editor[data-v-d9e8bd29] {\n display: flex;\n flex-direction: column;\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n}\n.markdown-editor__toolbar[data-v-d9e8bd29] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-xs);\n padding: var(--spacing-xs) var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n background-color: var(--color-surface);\n position: sticky;\n top: var(--document-toolbar-height, 49px);\n z-index: 1;\n}\n.markdown-editor__separator[data-v-d9e8bd29] {\n width: 1px;\n height: 20px;\n background-color: var(--color-border);\n margin: 0 var(--spacing-xs);\n}\n.markdown-editor__content[data-v-d9e8bd29] {\n padding: 4rem clamp(1.5rem, 6rem, 8%);\n outline: none;\n min-height: 200px;\n}\n.markdown-editor__content[data-v-d9e8bd29] > *:first-child {\n margin-top: 0;\n}\n.markdown-editor__content[data-v-d9e8bd29] h1,\n.markdown-editor__content[data-v-d9e8bd29] h2,\n.markdown-editor__content[data-v-d9e8bd29] h3,\n.markdown-editor__content[data-v-d9e8bd29] h4 {\n margin: var(--spacing-lg) 0 var(--spacing-sm);\n font-weight: 700;\n color: var(--color-text-primary);\n}\n.markdown-editor__content[data-v-d9e8bd29] h1 {\n font-size: var(--font-size-xl);\n}\n.markdown-editor__content[data-v-d9e8bd29] h2 {\n font-size: var(--font-size-lg);\n}\n.markdown-editor__content[data-v-d9e8bd29] h3 {\n font-size: var(--font-size-base);\n}\n.markdown-editor__content[data-v-d9e8bd29] h4 {\n font-size: var(--font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-secondary);\n}\n.markdown-editor__content[data-v-d9e8bd29] p {\n margin: 0 0 var(--spacing-md);\n}\n.markdown-editor__content[data-v-d9e8bd29] ul,\n.markdown-editor__content[data-v-d9e8bd29] ol {\n margin: 0 0 var(--spacing-md);\n padding-left: var(--spacing-lg);\n}\n.markdown-editor__content[data-v-d9e8bd29] li {\n margin: var(--spacing-xs) 0;\n}\n.markdown-editor__content[data-v-d9e8bd29] blockquote {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-sm) var(--spacing-md);\n border-left: 3px solid var(--color-border);\n color: var(--color-text-secondary);\n font-style: italic;\n}\n.markdown-editor__content[data-v-d9e8bd29] code {\n font-family: var(--font-family-mono);\n font-size: 0.9em;\n padding: 1px 4px;\n background-color: var(--color-surface);\n border-radius: var(--radius-sm);\n}\n.markdown-editor__content[data-v-d9e8bd29] pre {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-md);\n background-color: var(--color-surface);\n border-radius: var(--radius-md);\n overflow-x: auto;\n}\n.markdown-editor__content[data-v-d9e8bd29] pre code {\n padding: 0;\n background: none;\n}\n.markdown-editor__content[data-v-d9e8bd29] a {\n color: var(--color-primary);\n text-decoration: underline;\n}\n.markdown-editor__content[data-v-d9e8bd29] hr {\n border: 0;\n border-top: 1px solid var(--color-border);\n margin: var(--spacing-lg) 0;\n}\n.markdown-editor__content[data-v-d9e8bd29] strong {\n font-weight: 700;\n}\n.markdown-editor__content[data-v-d9e8bd29] table {\n border-collapse: collapse;\n margin: var(--spacing-md) 0;\n}\n.markdown-editor__content[data-v-d9e8bd29] th,\n.markdown-editor__content[data-v-d9e8bd29] td {\n border: 1px solid var(--color-border);\n padding: var(--spacing-xs) var(--spacing-sm);\n}\n.markdown-editor__content[data-v-d9e8bd29] th {\n background-color: var(--color-surface);\n font-weight: 600;\n}\n";
21583
- const MarkdownEditor = /* @__PURE__ */ _export_sfc(_sfc_main$G, [["styles", [_style_0$y]], ["__scopeId", "data-v-d9e8bd29"]]);
21584
- const _hoisted_1$z = { class: "markdown-view" };
21585
- const _hoisted_2$r = ["innerHTML"];
21586
- const _sfc_main$F = /* @__PURE__ */ defineComponent({
21605
+ const _style_0$z = "\n.markdown-editor[data-v-a278828c] {\n display: flex;\n flex-direction: column;\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n}\n.markdown-editor__toolbar[data-v-a278828c] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-xs);\n padding: var(--spacing-xs) var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n background-color: var(--color-surface);\n position: sticky;\n top: var(--document-toolbar-height, 0px);\n z-index: 1;\n}\n.markdown-editor__separator[data-v-a278828c] {\n width: 1px;\n height: 20px;\n background-color: var(--color-border);\n margin: 0 var(--spacing-xs);\n}\n.markdown-editor__content[data-v-a278828c] {\n padding: 4rem clamp(1.5rem, 6rem, 8%);\n outline: none;\n min-height: 200px;\n}\n.markdown-editor__content[data-v-a278828c] > *:first-child {\n margin-top: 0;\n}\n.markdown-editor__content[data-v-a278828c] h1,\n.markdown-editor__content[data-v-a278828c] h2,\n.markdown-editor__content[data-v-a278828c] h3,\n.markdown-editor__content[data-v-a278828c] h4 {\n margin: var(--spacing-lg) 0 var(--spacing-sm);\n font-weight: 700;\n color: var(--color-text-primary);\n}\n.markdown-editor__content[data-v-a278828c] h1 {\n font-size: var(--font-size-xl);\n}\n.markdown-editor__content[data-v-a278828c] h2 {\n font-size: var(--font-size-lg);\n}\n.markdown-editor__content[data-v-a278828c] h3 {\n font-size: var(--font-size-base);\n}\n.markdown-editor__content[data-v-a278828c] h4 {\n font-size: var(--font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-secondary);\n}\n.markdown-editor__content[data-v-a278828c] p {\n margin: 0 0 var(--spacing-md);\n}\n.markdown-editor__content[data-v-a278828c] ul,\n.markdown-editor__content[data-v-a278828c] ol {\n margin: 0 0 var(--spacing-md);\n padding-left: var(--spacing-lg);\n}\n.markdown-editor__content[data-v-a278828c] li {\n margin: var(--spacing-xs) 0;\n}\n.markdown-editor__content[data-v-a278828c] blockquote {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-sm) var(--spacing-md);\n border-left: 3px solid var(--color-border);\n color: var(--color-text-secondary);\n font-style: italic;\n}\n.markdown-editor__content[data-v-a278828c] code {\n font-family: var(--font-family-mono);\n font-size: 0.9em;\n padding: 1px 4px;\n background-color: var(--color-surface);\n border-radius: var(--radius-sm);\n}\n.markdown-editor__content[data-v-a278828c] pre {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-md);\n background-color: var(--color-surface);\n border-radius: var(--radius-md);\n overflow-x: auto;\n}\n.markdown-editor__content[data-v-a278828c] pre code {\n padding: 0;\n background: none;\n}\n.markdown-editor__content[data-v-a278828c] a {\n color: var(--color-primary);\n text-decoration: underline;\n}\n.markdown-editor__content[data-v-a278828c] hr {\n border: 0;\n border-top: 1px solid var(--color-border);\n margin: var(--spacing-lg) 0;\n}\n.markdown-editor__content[data-v-a278828c] strong {\n font-weight: 700;\n}\n.markdown-editor__content[data-v-a278828c] table {\n border-collapse: collapse;\n margin: var(--spacing-md) 0;\n}\n.markdown-editor__content[data-v-a278828c] th,\n.markdown-editor__content[data-v-a278828c] td {\n border: 1px solid var(--color-border);\n padding: var(--spacing-xs) var(--spacing-sm);\n}\n.markdown-editor__content[data-v-a278828c] th {\n background-color: var(--color-surface);\n font-weight: 600;\n}\n";
21606
+ const MarkdownEditor = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["styles", [_style_0$z]], ["__scopeId", "data-v-a278828c"]]);
21607
+ const _hoisted_1$A = { class: "markdown-view" };
21608
+ const _hoisted_2$s = ["innerHTML"];
21609
+ const _hoisted_3$l = ["innerHTML"];
21610
+ const _sfc_main$H = /* @__PURE__ */ defineComponent({
21587
21611
  __name: "MarkdownView",
21588
21612
  props: {
21589
21613
  source: { type: String },
@@ -21593,15 +21617,19 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21593
21617
  const props = __props;
21594
21618
  const segments = computed(() => renderMarkdownSegments(props.source));
21595
21619
  return (_ctx, _cache) => {
21596
- return openBlock(), createElementBlock("div", _hoisted_1$z, [
21620
+ return openBlock(), createElementBlock("div", _hoisted_1$A, [
21597
21621
  (openBlock(true), createElementBlock(Fragment, null, renderList(segments.value, (seg, i2) => {
21598
21622
  return openBlock(), createElementBlock(Fragment, { key: i2 }, [
21599
21623
  seg.type === "html" ? (openBlock(), createElementBlock("div", {
21600
21624
  key: 0,
21601
21625
  class: "markdown-view__html",
21602
21626
  innerHTML: seg.html
21603
- }, null, 8, _hoisted_2$r)) : (openBlock(), createBlock(CodeBlock, {
21627
+ }, null, 8, _hoisted_2$s)) : seg.type === "table" ? (openBlock(), createElementBlock("div", {
21604
21628
  key: 1,
21629
+ class: "markdown-view__table",
21630
+ innerHTML: seg.html
21631
+ }, null, 8, _hoisted_3$l)) : (openBlock(), createBlock(CodeBlock, {
21632
+ key: 2,
21605
21633
  code: seg.code,
21606
21634
  lang: seg.lang,
21607
21635
  streaming: __props.streaming
@@ -21612,18 +21640,18 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21612
21640
  };
21613
21641
  }
21614
21642
  });
21615
- const _style_0$x = "\n.markdown-view[data-v-6e1cc74b] {\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n}\n\n/* No box: block children flow as direct children of .markdown-view so margin\n collapsing keeps working across html/code segment boundaries. */\n.markdown-view__html[data-v-6e1cc74b] {\n display: contents;\n}\n\n/* Trim the outer margins of the first/last rendered block (reach through the\n display:contents wrapper to the real content element). */\n.markdown-view > .markdown-view__html[data-v-6e1cc74b]:first-child > :first-child {\n margin-top: 0;\n}\n.markdown-view > .markdown-view__html[data-v-6e1cc74b]:last-child > :last-child {\n margin-bottom: 0;\n}\n.markdown-view[data-v-6e1cc74b] h1,\n.markdown-view[data-v-6e1cc74b] h2,\n.markdown-view[data-v-6e1cc74b] h3,\n.markdown-view[data-v-6e1cc74b] h4 {\n margin: var(--spacing-lg) 0 var(--spacing-sm);\n font-weight: 700;\n color: var(--color-text-primary);\n}\n.markdown-view[data-v-6e1cc74b] h1 {\n font-size: var(--font-size-xl);\n}\n.markdown-view[data-v-6e1cc74b] h2 {\n font-size: var(--font-size-lg);\n}\n.markdown-view[data-v-6e1cc74b] h3 {\n font-size: var(--font-size-base);\n}\n.markdown-view[data-v-6e1cc74b] h4 {\n font-size: var(--font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-secondary);\n}\n.markdown-view[data-v-6e1cc74b] p {\n margin: 0 0 var(--spacing-md);\n}\n.markdown-view[data-v-6e1cc74b] ul,\n.markdown-view[data-v-6e1cc74b] ol {\n margin: 0 0 var(--spacing-md);\n padding-left: var(--spacing-lg);\n}\n.markdown-view[data-v-6e1cc74b] li {\n margin: var(--spacing-xs) 0;\n}\n.markdown-view[data-v-6e1cc74b] blockquote {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-sm) var(--spacing-md);\n border-left: 3px solid var(--color-border);\n color: var(--color-text-secondary);\n font-style: italic;\n}\n\n/* Inline code only — fenced blocks render via <CodeBlock>. Scoped to the html\n wrapper so it never reaches into the CodeBlock component. */\n.markdown-view__html[data-v-6e1cc74b] code {\n font-family: var(--font-family-mono);\n font-size: 0.9em;\n padding: 1px 4px;\n background-color: var(--color-surface);\n border-radius: var(--radius-sm);\n}\n\n/* Fallback for raw <pre> written as literal HTML (not fenced code). */\n.markdown-view__html[data-v-6e1cc74b] pre {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-md);\n background-color: var(--color-surface);\n border-radius: var(--radius-md);\n overflow-x: auto;\n border: 1px solid var(--color-border);\n}\n.markdown-view__html[data-v-6e1cc74b] pre code {\n padding: 0;\n background: none;\n}\n.markdown-view[data-v-6e1cc74b] a {\n color: var(--color-primary);\n text-decoration: underline;\n}\n.markdown-view[data-v-6e1cc74b] hr {\n border: 0;\n border-top: 1px solid var(--color-border);\n margin: var(--spacing-lg) 0;\n}\n.markdown-view[data-v-6e1cc74b] strong {\n font-weight: 700;\n}\n.markdown-view[data-v-6e1cc74b] table {\n border-collapse: collapse;\n margin: var(--spacing-md) 0;\n}\n.markdown-view[data-v-6e1cc74b] th,\n.markdown-view[data-v-6e1cc74b] td {\n border: 1px solid var(--color-border);\n padding: var(--spacing-xs) var(--spacing-sm);\n}\n.markdown-view[data-v-6e1cc74b] th {\n background-color: var(--color-surface);\n font-weight: 600;\n}\n";
21616
- const MarkdownView = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["styles", [_style_0$x]], ["__scopeId", "data-v-6e1cc74b"]]);
21617
- const _hoisted_1$y = {
21643
+ const _style_0$y = "\n.markdown-view[data-v-b6eeece0] {\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n /* Long URLs and identifiers wrap instead of running past a narrow\n column (phones, chat), where the overflow would just be clipped. */\n overflow-wrap: break-word;\n}\n\n/* No box: block children flow as direct children of .markdown-view so margin\n collapsing keeps working across html/code segment boundaries. */\n.markdown-view__html[data-v-b6eeece0] {\n display: contents;\n}\n\n/* Trim the outer margins of the first/last rendered block (reach through the\n display:contents wrapper to the real content element). */\n.markdown-view > .markdown-view__html[data-v-b6eeece0]:first-child > :first-child {\n margin-top: 0;\n}\n.markdown-view > .markdown-view__html[data-v-b6eeece0]:last-child > :last-child {\n margin-bottom: 0;\n}\n.markdown-view > .markdown-view__table[data-v-b6eeece0]:first-child {\n margin-top: 0;\n}\n.markdown-view > .markdown-view__table[data-v-b6eeece0]:last-child {\n margin-bottom: 0;\n}\n.markdown-view[data-v-b6eeece0] h1,\n.markdown-view[data-v-b6eeece0] h2,\n.markdown-view[data-v-b6eeece0] h3,\n.markdown-view[data-v-b6eeece0] h4 {\n margin: var(--spacing-lg) 0 var(--spacing-sm);\n font-weight: 700;\n color: var(--color-text-primary);\n}\n.markdown-view[data-v-b6eeece0] h1 {\n font-size: var(--font-size-xl);\n}\n.markdown-view[data-v-b6eeece0] h2 {\n font-size: var(--font-size-lg);\n}\n.markdown-view[data-v-b6eeece0] h3 {\n font-size: var(--font-size-base);\n}\n.markdown-view[data-v-b6eeece0] h4 {\n font-size: var(--font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-secondary);\n}\n.markdown-view[data-v-b6eeece0] p {\n margin: 0 0 var(--spacing-md);\n}\n.markdown-view[data-v-b6eeece0] ul,\n.markdown-view[data-v-b6eeece0] ol {\n margin: 0 0 var(--spacing-md);\n padding-left: var(--spacing-lg);\n}\n.markdown-view[data-v-b6eeece0] li {\n margin: var(--spacing-xs) 0;\n}\n.markdown-view[data-v-b6eeece0] blockquote {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-sm) var(--spacing-md);\n border-left: 3px solid var(--color-border);\n color: var(--color-text-secondary);\n font-style: italic;\n}\n\n/* Inline code only — fenced blocks render via <CodeBlock>. Scoped to the html\n wrapper so it never reaches into the CodeBlock component. */\n.markdown-view__html[data-v-b6eeece0] code {\n font-family: var(--font-family-mono);\n font-size: 0.9em;\n padding: 1px 4px;\n background-color: var(--color-surface);\n border-radius: var(--radius-sm);\n}\n\n/* Fallback for raw <pre> written as literal HTML (not fenced code). */\n.markdown-view__html[data-v-b6eeece0] pre {\n margin: var(--spacing-md) 0;\n padding: var(--spacing-md);\n background-color: var(--color-surface);\n border-radius: var(--radius-md);\n overflow-x: auto;\n border: 1px solid var(--color-border);\n}\n.markdown-view__html[data-v-b6eeece0] pre code {\n padding: 0;\n background: none;\n}\n.markdown-view[data-v-b6eeece0] a {\n color: var(--color-primary);\n text-decoration: underline;\n}\n.markdown-view[data-v-b6eeece0] hr {\n border: 0;\n border-top: 1px solid var(--color-border);\n margin: var(--spacing-lg) 0;\n}\n.markdown-view[data-v-b6eeece0] strong {\n font-weight: 700;\n}\n.markdown-view[data-v-b6eeece0] img {\n max-width: 100%;\n height: auto;\n}\n\n/* A table wider than the column scrolls on its own, the text around it\n keeps the column width. */\n.markdown-view__table[data-v-b6eeece0] {\n margin: var(--spacing-md) 0;\n overflow-x: auto;\n}\n.markdown-view[data-v-b6eeece0] table {\n border-collapse: collapse;\n}\n.markdown-view[data-v-b6eeece0] th,\n.markdown-view[data-v-b6eeece0] td {\n border: 1px solid var(--color-border);\n padding: var(--spacing-xs) var(--spacing-sm);\n}\n.markdown-view[data-v-b6eeece0] th {\n background-color: var(--color-surface);\n font-weight: 600;\n}\n";
21644
+ const MarkdownView = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["styles", [_style_0$y]], ["__scopeId", "data-v-b6eeece0"]]);
21645
+ const _hoisted_1$z = {
21618
21646
  key: 0,
21619
21647
  class: "transcript-ui-popover-list__items"
21620
21648
  };
21621
- const _hoisted_2$q = {
21649
+ const _hoisted_2$r = {
21622
21650
  key: 0,
21623
21651
  class: "transcript-ui-popover-list__divider"
21624
21652
  };
21625
21653
  const _hoisted_3$k = { class: "transcript-ui-popover-list__footer" };
21626
- const _sfc_main$E = /* @__PURE__ */ defineComponent({
21654
+ const _sfc_main$G = /* @__PURE__ */ defineComponent({
21627
21655
  __name: "PopoverList",
21628
21656
  props: {
21629
21657
  items: { type: Array },
@@ -21676,7 +21704,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21676
21704
  "side-offset": __props.sideOffset
21677
21705
  }, {
21678
21706
  default: withCtx(() => [
21679
- __props.items.length > 0 ? (openBlock(), createElementBlock("ul", _hoisted_1$y, [
21707
+ __props.items.length > 0 ? (openBlock(), createElementBlock("ul", _hoisted_1$z, [
21680
21708
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, index) => {
21681
21709
  return openBlock(), createBlock(unref(DropdownMenuItem_default), {
21682
21710
  key: keyFor(item, index),
@@ -21692,7 +21720,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21692
21720
  }), 128))
21693
21721
  ])) : createCommentVNode("", true),
21694
21722
  _ctx.$slots.footer ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
21695
- __props.items.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$q)) : createCommentVNode("", true),
21723
+ __props.items.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$r)) : createCommentVNode("", true),
21696
21724
  createBaseVNode("div", _hoisted_3$k, [
21697
21725
  renderSlot(_ctx.$slots, "footer")
21698
21726
  ])
@@ -21709,8 +21737,8 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21709
21737
  };
21710
21738
  }
21711
21739
  });
21712
- const _hoisted_1$x = ["disabled", "aria-current"];
21713
- const _hoisted_2$p = {
21740
+ const _hoisted_1$y = ["disabled", "aria-current"];
21741
+ const _hoisted_2$q = {
21714
21742
  key: 0,
21715
21743
  class: "selectable-list-item__leading"
21716
21744
  };
@@ -21719,11 +21747,11 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21719
21747
  key: 1,
21720
21748
  class: "selectable-list-item__trailing"
21721
21749
  };
21722
- const _hoisted_5$b = {
21750
+ const _hoisted_5$c = {
21723
21751
  key: 0,
21724
21752
  class: "selectable-list-item__actions"
21725
21753
  };
21726
- const _sfc_main$D = /* @__PURE__ */ defineComponent({
21754
+ const _sfc_main$F = /* @__PURE__ */ defineComponent({
21727
21755
  __name: "SelectableListItem",
21728
21756
  props: {
21729
21757
  current: { type: Boolean },
@@ -21748,7 +21776,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21748
21776
  "aria-current": __props.current ? "true" : void 0,
21749
21777
  onClick: _cache[0] || (_cache[0] = ($event) => emit2("select"))
21750
21778
  }, [
21751
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$p, [
21779
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$q, [
21752
21780
  renderSlot(_ctx.$slots, "leading", {}, void 0, true)
21753
21781
  ])) : createCommentVNode("", true),
21754
21782
  createBaseVNode("span", _hoisted_3$j, [
@@ -21759,17 +21787,17 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21759
21787
  _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_4$d, [
21760
21788
  renderSlot(_ctx.$slots, "trailing", {}, void 0, true)
21761
21789
  ])) : createCommentVNode("", true)
21762
- ], 8, _hoisted_1$x),
21763
- _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$b, [
21790
+ ], 8, _hoisted_1$y),
21791
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$c, [
21764
21792
  renderSlot(_ctx.$slots, "actions", {}, void 0, true)
21765
21793
  ])) : createCommentVNode("", true)
21766
21794
  ], 2);
21767
21795
  };
21768
21796
  }
21769
21797
  });
21770
- const _style_0$w = "\n.selectable-list-item[data-v-46747619] {\n position: relative;\n display: flex;\n border: 1px solid transparent;\n transition:\n background-color var(--transition-duration),\n box-shadow var(--transition-duration);\n}\n.selectable-list-item--md[data-v-46747619] {\n font-size: var(--font-size-sm);\n}\n.selectable-list-item--sm[data-v-46747619] {\n font-size: var(--font-size-xs);\n}\n.selectable-list-item[data-v-46747619]:hover {\n background-color: var(--color-surface-hover);\n}\n.selectable-list-item--current[data-v-46747619],\n.selectable-list-item--current[data-v-46747619]:hover {\n background-color: color-mix(in srgb, var(--color-primary) 12%, transparent);\n box-shadow: inset 2px 0 0 var(--color-primary);\n}\n\n/* ── The selectable button ── */\n.transcript-ui-root .selectable-list-item__main[data-v-46747619] {\n /* Full reset (same convention as Button, EditableText, Tabs…): the\n previous partial reset (background/border/font only) left margin,\n padding, and appearance to whatever the host page's UA/global styles\n happened to set. */\n all: unset;\n box-sizing: border-box;\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n font: inherit;\n color: var(--color-text-primary);\n text-align: left;\n cursor: pointer;\n}\n.transcript-ui-root .selectable-list-item--md .selectable-list-item__main[data-v-46747619] {\n padding: var(--spacing-sm);\n}\n.transcript-ui-root .selectable-list-item--sm .selectable-list-item__main[data-v-46747619] {\n padding: var(--spacing-xs) var(--spacing-sm);\n color: var(--color-text-secondary);\n}\n.transcript-ui-root .selectable-list-item__main[data-v-46747619]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: -2px;\n}\n.transcript-ui-root .selectable-list-item__main[data-v-46747619]:disabled {\n cursor: not-allowed;\n}\n.transcript-ui-root .selectable-list-item--current .selectable-list-item__main[data-v-46747619] {\n color: var(--color-primary);\n font-weight: 600;\n}\n.selectable-list-item__label[data-v-46747619] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n}\n.selectable-list-item__leading[data-v-46747619],\n.selectable-list-item__trailing[data-v-46747619] {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* Trailing content (hints, dates) stays muted even on the active row. */\n.selectable-list-item__trailing[data-v-46747619] {\n font-size: var(--font-size-xs);\n color: var(--color-text-muted);\n}\n\n/* ── Trailing actions (hover / focus reveal, overlaying the row) ── */\n.selectable-list-item__actions[data-v-46747619] {\n position: absolute;\n inset-block: 0;\n inset-inline-end: 0;\n display: flex;\n align-items: center;\n gap: 2px;\n padding-inline: var(--spacing-md) var(--spacing-xs);\n /* Fade the label out behind the actions, matching the row surface. */\n background: linear-gradient(\n to right,\n transparent,\n var(--color-surface-hover) var(--spacing-md)\n );\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--transition-duration);\n}\n.selectable-list-item:hover .selectable-list-item__actions[data-v-46747619],\n.selectable-list-item:focus-within .selectable-list-item__actions[data-v-46747619] {\n opacity: 1;\n pointer-events: auto;\n}\n\n/* Match the fade to the selected surface on the active row. */\n.selectable-list-item--current .selectable-list-item__actions[data-v-46747619] {\n background: linear-gradient(\n to right,\n transparent,\n color-mix(in srgb, var(--color-primary) 12%, var(--color-surface-hover))\n var(--spacing-md)\n );\n}\n@media (prefers-reduced-motion: reduce) {\n.selectable-list-item[data-v-46747619],\n .selectable-list-item__actions[data-v-46747619] {\n transition: none;\n}\n}\n";
21771
- const SelectableListItem = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["styles", [_style_0$w]], ["__scopeId", "data-v-46747619"]]);
21772
- const _sfc_main$C = /* @__PURE__ */ defineComponent({
21798
+ const _style_0$x = "\n.selectable-list-item[data-v-46747619] {\n position: relative;\n display: flex;\n border: 1px solid transparent;\n transition:\n background-color var(--transition-duration),\n box-shadow var(--transition-duration);\n}\n.selectable-list-item--md[data-v-46747619] {\n font-size: var(--font-size-sm);\n}\n.selectable-list-item--sm[data-v-46747619] {\n font-size: var(--font-size-xs);\n}\n.selectable-list-item[data-v-46747619]:hover {\n background-color: var(--color-surface-hover);\n}\n.selectable-list-item--current[data-v-46747619],\n.selectable-list-item--current[data-v-46747619]:hover {\n background-color: color-mix(in srgb, var(--color-primary) 12%, transparent);\n box-shadow: inset 2px 0 0 var(--color-primary);\n}\n\n/* ── The selectable button ── */\n.transcript-ui-root .selectable-list-item__main[data-v-46747619] {\n /* Full reset (same convention as Button, EditableText, Tabs…): the\n previous partial reset (background/border/font only) left margin,\n padding, and appearance to whatever the host page's UA/global styles\n happened to set. */\n all: unset;\n box-sizing: border-box;\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n font: inherit;\n color: var(--color-text-primary);\n text-align: left;\n cursor: pointer;\n}\n.transcript-ui-root .selectable-list-item--md .selectable-list-item__main[data-v-46747619] {\n padding: var(--spacing-sm);\n}\n.transcript-ui-root .selectable-list-item--sm .selectable-list-item__main[data-v-46747619] {\n padding: var(--spacing-xs) var(--spacing-sm);\n color: var(--color-text-secondary);\n}\n.transcript-ui-root .selectable-list-item__main[data-v-46747619]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: -2px;\n}\n.transcript-ui-root .selectable-list-item__main[data-v-46747619]:disabled {\n cursor: not-allowed;\n}\n.transcript-ui-root .selectable-list-item--current .selectable-list-item__main[data-v-46747619] {\n color: var(--color-primary);\n font-weight: 600;\n}\n.selectable-list-item__label[data-v-46747619] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n}\n.selectable-list-item__leading[data-v-46747619],\n.selectable-list-item__trailing[data-v-46747619] {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* Trailing content (hints, dates) stays muted even on the active row. */\n.selectable-list-item__trailing[data-v-46747619] {\n font-size: var(--font-size-xs);\n color: var(--color-text-muted);\n}\n\n/* ── Trailing actions (hover / focus reveal, overlaying the row) ── */\n.selectable-list-item__actions[data-v-46747619] {\n position: absolute;\n inset-block: 0;\n inset-inline-end: 0;\n display: flex;\n align-items: center;\n gap: 2px;\n padding-inline: var(--spacing-md) var(--spacing-xs);\n /* Fade the label out behind the actions, matching the row surface. */\n background: linear-gradient(\n to right,\n transparent,\n var(--color-surface-hover) var(--spacing-md)\n );\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--transition-duration);\n}\n.selectable-list-item:hover .selectable-list-item__actions[data-v-46747619],\n.selectable-list-item:focus-within .selectable-list-item__actions[data-v-46747619] {\n opacity: 1;\n pointer-events: auto;\n}\n\n/* Match the fade to the selected surface on the active row. */\n.selectable-list-item--current .selectable-list-item__actions[data-v-46747619] {\n background: linear-gradient(\n to right,\n transparent,\n color-mix(in srgb, var(--color-primary) 12%, var(--color-surface-hover))\n var(--spacing-md)\n );\n}\n@media (prefers-reduced-motion: reduce) {\n.selectable-list-item[data-v-46747619],\n .selectable-list-item__actions[data-v-46747619] {\n transition: none;\n}\n}\n";
21799
+ const SelectableListItem = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["styles", [_style_0$x]], ["__scopeId", "data-v-46747619"]]);
21800
+ const _sfc_main$E = /* @__PURE__ */ defineComponent({
21773
21801
  __name: "SpeakerIndicator",
21774
21802
  props: {
21775
21803
  color: { type: String }
@@ -21784,12 +21812,12 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21784
21812
  };
21785
21813
  }
21786
21814
  });
21787
- const _style_0$v = "\n.speaker-indicator[data-v-324978c0] {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n";
21788
- const SpeakerIndicator = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["styles", [_style_0$v]], ["__scopeId", "data-v-324978c0"]]);
21789
- const _hoisted_1$w = { class: "switch" };
21790
- const _hoisted_2$o = ["id", "checked", "disabled"];
21815
+ const _style_0$w = "\n.speaker-indicator[data-v-324978c0] {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n";
21816
+ const SpeakerIndicator = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["styles", [_style_0$w]], ["__scopeId", "data-v-324978c0"]]);
21817
+ const _hoisted_1$x = { class: "switch" };
21818
+ const _hoisted_2$p = ["id", "checked", "disabled"];
21791
21819
  const _hoisted_3$i = ["for"];
21792
- const _sfc_main$B = /* @__PURE__ */ defineComponent({
21820
+ const _sfc_main$D = /* @__PURE__ */ defineComponent({
21793
21821
  __name: "SwitchToggle",
21794
21822
  props: {
21795
21823
  modelValue: { type: Boolean },
@@ -21802,14 +21830,14 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21802
21830
  const emit2 = __emit;
21803
21831
  const inputId = props.id ?? useId$1();
21804
21832
  return (_ctx, _cache) => {
21805
- return openBlock(), createElementBlock("div", _hoisted_1$w, [
21833
+ return openBlock(), createElementBlock("div", _hoisted_1$x, [
21806
21834
  createBaseVNode("input", {
21807
21835
  type: "checkbox",
21808
21836
  id: unref(inputId),
21809
21837
  checked: __props.modelValue,
21810
21838
  disabled: __props.disabled,
21811
21839
  onChange: _cache[0] || (_cache[0] = ($event) => emit2("update:modelValue", $event.target.checked))
21812
- }, null, 40, _hoisted_2$o),
21840
+ }, null, 40, _hoisted_2$p),
21813
21841
  createBaseVNode("label", { for: unref(inputId) }, [..._cache[1] || (_cache[1] = [
21814
21842
  createBaseVNode("div", { class: "switch-slider" }, null, -1)
21815
21843
  ])], 8, _hoisted_3$i)
@@ -21817,15 +21845,15 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21817
21845
  };
21818
21846
  }
21819
21847
  });
21820
- const _style_0$u = "\n.switch[data-v-44d0160b] {\n display: inline-block;\n flex-shrink: 0;\n}\n.switch input[data-v-44d0160b] {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n.switch label[data-v-44d0160b] {\n height: 20px;\n width: 40px;\n display: block;\n border: 1px solid var(--color-border);\n border-radius: 20px;\n cursor: pointer;\n background-color: var(--color-border);\n transition: background-color var(--transition-duration);\n}\n.switch .switch-slider[data-v-44d0160b] {\n height: 22px;\n width: 22px;\n border: 1px solid var(--color-border);\n border-radius: 50%;\n position: relative;\n top: -2px;\n left: -2px;\n background-color: var(--color-white);\n transition: left var(--transition-duration);\n}\n.switch input:checked + label[data-v-44d0160b] {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n}\n.switch input:checked + label .switch-slider[data-v-44d0160b] {\n left: 20px;\n border-color: var(--color-primary);\n}\n.switch input:disabled + label[data-v-44d0160b] {\n cursor: not-allowed;\n opacity: 0.5;\n}\n";
21821
- const SwitchToggle = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["styles", [_style_0$u]], ["__scopeId", "data-v-44d0160b"]]);
21848
+ const _style_0$v = "\n.switch[data-v-44d0160b] {\n display: inline-block;\n flex-shrink: 0;\n}\n.switch input[data-v-44d0160b] {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n.switch label[data-v-44d0160b] {\n height: 20px;\n width: 40px;\n display: block;\n border: 1px solid var(--color-border);\n border-radius: 20px;\n cursor: pointer;\n background-color: var(--color-border);\n transition: background-color var(--transition-duration);\n}\n.switch .switch-slider[data-v-44d0160b] {\n height: 22px;\n width: 22px;\n border: 1px solid var(--color-border);\n border-radius: 50%;\n position: relative;\n top: -2px;\n left: -2px;\n background-color: var(--color-white);\n transition: left var(--transition-duration);\n}\n.switch input:checked + label[data-v-44d0160b] {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n}\n.switch input:checked + label .switch-slider[data-v-44d0160b] {\n left: 20px;\n border-color: var(--color-primary);\n}\n.switch input:disabled + label[data-v-44d0160b] {\n cursor: not-allowed;\n opacity: 0.5;\n}\n";
21849
+ const SwitchToggle = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["styles", [_style_0$v]], ["__scopeId", "data-v-44d0160b"]]);
21822
21850
  function computeInitials(name) {
21823
21851
  const words = name.trim().split(/\s+/).filter(Boolean);
21824
21852
  if (words.length === 0) return "?";
21825
21853
  return words.slice(0, 2).map((w2) => w2[0].toUpperCase()).join("");
21826
21854
  }
21827
- const _hoisted_1$v = ["title", "aria-label"];
21828
- const _sfc_main$A = /* @__PURE__ */ defineComponent({
21855
+ const _hoisted_1$w = ["title", "aria-label"];
21856
+ const _sfc_main$C = /* @__PURE__ */ defineComponent({
21829
21857
  __name: "UserAvatar",
21830
21858
  props: {
21831
21859
  name: { type: String },
@@ -21841,35 +21869,40 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21841
21869
  role: "img",
21842
21870
  title: title.value,
21843
21871
  "aria-label": title.value
21844
- }, toDisplayString(initials.value), 9, _hoisted_1$v);
21872
+ }, toDisplayString(initials.value), 9, _hoisted_1$w);
21845
21873
  };
21846
21874
  }
21847
21875
  });
21848
- const _style_0$t = "\n.user-avatar[data-v-977a8d17] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background-color: var(--color-primary);\n color: var(--color-white);\n font-size: var(--font-size-xs);\n font-weight: 600;\n user-select: none;\n cursor: default;\n}\n";
21849
- const UserAvatar = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["styles", [_style_0$t]], ["__scopeId", "data-v-977a8d17"]]);
21850
- const _hoisted_1$u = ["data-status"];
21851
- const _hoisted_2$n = { class: "document-article__toolbar-left" };
21852
- const _hoisted_3$h = { class: "document-article__toolbar-center" };
21853
- const _hoisted_4$c = { class: "document-article__toolbar-right" };
21854
- const _hoisted_5$a = { class: "document-article__body" };
21855
- const _hoisted_6$a = {
21876
+ const _style_0$u = "\n.user-avatar[data-v-977a8d17] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background-color: var(--color-primary);\n color: var(--color-white);\n font-size: var(--font-size-xs);\n font-weight: 600;\n user-select: none;\n cursor: default;\n}\n";
21877
+ const UserAvatar = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["styles", [_style_0$u]], ["__scopeId", "data-v-977a8d17"]]);
21878
+ const _hoisted_1$v = ["data-status"];
21879
+ const _hoisted_2$o = {
21880
+ key: 0,
21881
+ class: "document-article__toolbar",
21882
+ role: "toolbar"
21883
+ };
21884
+ const _hoisted_3$h = { class: "document-article__toolbar-left" };
21885
+ const _hoisted_4$c = { class: "document-article__toolbar-center" };
21886
+ const _hoisted_5$b = { class: "document-article__toolbar-right" };
21887
+ const _hoisted_6$a = { class: "document-article__body" };
21888
+ const _hoisted_7$4 = {
21856
21889
  key: 0,
21857
21890
  class: "document-article__center document-article__center--processing",
21858
21891
  role: "status",
21859
21892
  "aria-live": "polite"
21860
21893
  };
21861
- const _hoisted_7$4 = ["value"];
21862
- const _hoisted_8$2 = {
21894
+ const _hoisted_8$2 = ["value"];
21895
+ const _hoisted_9$2 = {
21863
21896
  key: 0,
21864
21897
  class: "document-article__progress-value"
21865
21898
  };
21866
- const _hoisted_9$2 = {
21899
+ const _hoisted_10$2 = {
21867
21900
  key: 1,
21868
21901
  class: "document-article__center document-article__center--error",
21869
21902
  role: "alert"
21870
21903
  };
21871
- const _hoisted_10$2 = { class: "document-article__error-text" };
21872
- const _sfc_main$z = /* @__PURE__ */ defineComponent({
21904
+ const _hoisted_11$1 = { class: "document-article__error-text" };
21905
+ const _sfc_main$B = /* @__PURE__ */ defineComponent({
21873
21906
  __name: "DocumentArticle",
21874
21907
  props: {
21875
21908
  status: { default: "done", type: String },
@@ -21884,22 +21917,6 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21884
21917
  const errorText = computed(
21885
21918
  () => props.errorMessage || t2("llmService.errorTemporary")
21886
21919
  );
21887
- const articleEl = /* @__PURE__ */ ref(null);
21888
- const toolbarEl = /* @__PURE__ */ ref(null);
21889
- let toolbarObserver = null;
21890
- function publishToolbarHeight() {
21891
- const height = toolbarEl.value?.offsetHeight ?? 0;
21892
- articleEl.value?.style.setProperty("--document-toolbar-height", `${height}px`);
21893
- }
21894
- onMounted(() => {
21895
- publishToolbarHeight();
21896
- if (typeof ResizeObserver === "undefined" || !toolbarEl.value) return;
21897
- toolbarObserver = new ResizeObserver(publishToolbarHeight);
21898
- toolbarObserver.observe(toolbarEl.value);
21899
- });
21900
- onBeforeUnmount(() => {
21901
- toolbarObserver?.disconnect();
21902
- });
21903
21920
  const progressValue = computed(() => {
21904
21921
  const v2 = props.progress;
21905
21922
  if (v2 == null || !Number.isFinite(v2)) return null;
@@ -21907,30 +21924,22 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21907
21924
  });
21908
21925
  return (_ctx, _cache) => {
21909
21926
  return openBlock(), createElementBlock("article", {
21910
- ref_key: "articleEl",
21911
- ref: articleEl,
21912
21927
  class: "document-article",
21913
21928
  "data-status": props.status
21914
21929
  }, [
21915
- _ctx.$slots["toolbar-left"] || _ctx.$slots["toolbar-center"] || _ctx.$slots["toolbar-right"] ? (openBlock(), createElementBlock("div", {
21916
- key: 0,
21917
- ref_key: "toolbarEl",
21918
- ref: toolbarEl,
21919
- class: "document-article__toolbar",
21920
- role: "toolbar"
21921
- }, [
21922
- createBaseVNode("div", _hoisted_2$n, [
21930
+ _ctx.$slots["toolbar-left"] || _ctx.$slots["toolbar-center"] || _ctx.$slots["toolbar-right"] ? (openBlock(), createElementBlock("div", _hoisted_2$o, [
21931
+ createBaseVNode("div", _hoisted_3$h, [
21923
21932
  renderSlot(_ctx.$slots, "toolbar-left", {}, void 0, true)
21924
21933
  ]),
21925
- createBaseVNode("div", _hoisted_3$h, [
21934
+ createBaseVNode("div", _hoisted_4$c, [
21926
21935
  renderSlot(_ctx.$slots, "toolbar-center", {}, void 0, true)
21927
21936
  ]),
21928
- createBaseVNode("div", _hoisted_4$c, [
21937
+ createBaseVNode("div", _hoisted_5$b, [
21929
21938
  renderSlot(_ctx.$slots, "toolbar-right", {}, void 0, true)
21930
21939
  ])
21931
- ], 512)) : createCommentVNode("", true),
21932
- createBaseVNode("div", _hoisted_5$a, [
21933
- props.status === "processing" ? (openBlock(), createElementBlock("div", _hoisted_6$a, [
21940
+ ])) : createCommentVNode("", true),
21941
+ createBaseVNode("div", _hoisted_6$a, [
21942
+ props.status === "processing" ? (openBlock(), createElementBlock("div", _hoisted_7$4, [
21934
21943
  createVNode(EditorIcon, {
21935
21944
  name: "spinner",
21936
21945
  spin: "",
@@ -21940,10 +21949,10 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21940
21949
  class: "document-article__progress",
21941
21950
  max: 100,
21942
21951
  value: progressValue.value ?? void 0
21943
- }, null, 8, _hoisted_7$4),
21944
- progressValue.value !== null ? (openBlock(), createElementBlock("span", _hoisted_8$2, toDisplayString(progressValue.value) + "% ", 1)) : createCommentVNode("", true)
21945
- ])) : props.status === "error" ? (openBlock(), createElementBlock("div", _hoisted_9$2, [
21946
- createBaseVNode("p", _hoisted_10$2, toDisplayString(errorText.value), 1),
21952
+ }, null, 8, _hoisted_8$2),
21953
+ progressValue.value !== null ? (openBlock(), createElementBlock("span", _hoisted_9$2, toDisplayString(progressValue.value) + "% ", 1)) : createCommentVNode("", true)
21954
+ ])) : props.status === "error" ? (openBlock(), createElementBlock("div", _hoisted_10$2, [
21955
+ createBaseVNode("p", _hoisted_11$1, toDisplayString(errorText.value), 1),
21947
21956
  createVNode(Button, {
21948
21957
  variant: "primary",
21949
21958
  icon: "refresh-cw",
@@ -21956,13 +21965,13 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21956
21965
  })
21957
21966
  ])) : renderSlot(_ctx.$slots, "default", {}, void 0, true, 2)
21958
21967
  ])
21959
- ], 8, _hoisted_1$u);
21968
+ ], 8, _hoisted_1$v);
21960
21969
  };
21961
21970
  }
21962
21971
  });
21963
- const _style_0$s = "\n.document-article[data-v-54a8890c] {\n width: min(1088px, calc(100% - 16px));\n max-width: 1088px;\n margin: var(--spacing-lg) auto;\n background-color: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n display: flex;\n flex-direction: column;\n}\n.document-article__toolbar[data-v-54a8890c] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n position: sticky;\n top: 0;\n background-color: var(--color-surface);\n border-radius: var(--radius-md) var(--radius-md) 0 0;\n z-index: 1;\n}\n.document-article__toolbar-left[data-v-54a8890c],\n.document-article__toolbar-right[data-v-54a8890c] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n flex-shrink: 0;\n}\n.document-article__toolbar-center[data-v-54a8890c] {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n min-width: 0;\n}\n.document-article__body[data-v-54a8890c] {\n flex: 1;\n min-height: 0;\n}\n.document-article__center[data-v-54a8890c] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-xl) var(--spacing-md);\n text-align: center;\n}\n.document-article__center--processing[data-v-54a8890c] {\n color: var(--color-primary);\n}\n.document-article__center--error[data-v-54a8890c] {\n color: var(--color-danger, #d33);\n}\n.document-article__progress[data-v-54a8890c] {\n width: min(280px, 100%);\n height: 6px;\n}\n.document-article__progress-value[data-v-54a8890c] {\n font-size: var(--font-size-xs);\n font-variant-numeric: tabular-nums;\n color: var(--color-text-muted);\n}\n\n/* Phone: the status line takes its own row under the buttons, so nothing\n ever needs to scroll sideways. */\n@media (max-width: 767px) {\n.document-article[data-v-54a8890c] {\n width: calc(100% - 16px);\n margin: var(--spacing-sm) auto;\n}\n.document-article__toolbar-center[data-v-54a8890c] {\n order: 3;\n flex-basis: 100%;\n justify-content: flex-start;\n}\n}\n.document-article__error-text[data-v-54a8890c] {\n margin: 0;\n max-width: 480px;\n font-size: var(--font-size-sm);\n line-height: var(--line-height);\n color: var(--color-text-secondary);\n}\n";
21964
- const DocumentArticle = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["styles", [_style_0$s]], ["__scopeId", "data-v-54a8890c"]]);
21965
- const _sfc_main$y = /* @__PURE__ */ defineComponent({
21972
+ const _style_0$t = "\n.document-article[data-v-dda12eb4] {\n /* One row of buttons plus padding and border. Declared rather than\n measured: slot content must stay on one line (truncate, don't wrap), and\n content stuck right under the toolbar (the markdown editor's toolbar)\n reads this value as its offset. */\n --document-toolbar-height: 49px;\n\n width: min(1088px, calc(100% - 16px));\n max-width: 1088px;\n margin: var(--spacing-lg) auto;\n background-color: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n display: flex;\n flex-direction: column;\n}\n.document-article__toolbar[data-v-dda12eb4] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n height: var(--document-toolbar-height);\n padding: 0 var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n position: sticky;\n top: 0;\n background-color: var(--color-surface);\n border-radius: var(--radius-md) var(--radius-md) 0 0;\n z-index: 1;\n}\n.document-article__toolbar-left[data-v-dda12eb4],\n.document-article__toolbar-right[data-v-dda12eb4] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n flex-shrink: 0;\n}\n.document-article__toolbar-center[data-v-dda12eb4] {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n min-width: 0;\n}\n.document-article__body[data-v-dda12eb4] {\n flex: 1;\n min-height: 0;\n}\n.document-article__center[data-v-dda12eb4] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-xl) var(--spacing-md);\n text-align: center;\n}\n.document-article__center--processing[data-v-dda12eb4] {\n color: var(--color-primary);\n}\n.document-article__center--error[data-v-dda12eb4] {\n color: var(--color-danger, #d33);\n}\n.document-article__progress[data-v-dda12eb4] {\n width: min(280px, 100%);\n height: 6px;\n}\n.document-article__progress-value[data-v-dda12eb4] {\n font-size: var(--font-size-xs);\n font-variant-numeric: tabular-nums;\n color: var(--color-text-muted);\n}\n@media (max-width: 767px) {\n.document-article[data-v-dda12eb4] {\n margin: var(--spacing-sm) auto;\n}\n}\n.document-article__error-text[data-v-dda12eb4] {\n margin: 0;\n max-width: 480px;\n font-size: var(--font-size-sm);\n line-height: var(--line-height);\n color: var(--color-text-secondary);\n}\n";
21973
+ const DocumentArticle = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["styles", [_style_0$t]], ["__scopeId", "data-v-dda12eb4"]]);
21974
+ const _sfc_main$A = /* @__PURE__ */ defineComponent({
21966
21975
  __name: "DownloadMenu",
21967
21976
  props: {
21968
21977
  formats: { type: Array },
@@ -21978,7 +21987,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
21978
21987
  emit2("select", item.format);
21979
21988
  }
21980
21989
  return (_ctx, _cache) => {
21981
- return openBlock(), createBlock(_sfc_main$E, {
21990
+ return openBlock(), createBlock(_sfc_main$G, {
21982
21991
  items: props.formats,
21983
21992
  "item-key": (f2) => f2.format,
21984
21993
  align: "end",
@@ -22006,7 +22015,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22006
22015
  };
22007
22016
  }
22008
22017
  });
22009
- const _sfc_main$x = /* @__PURE__ */ defineComponent({
22018
+ const _sfc_main$z = /* @__PURE__ */ defineComponent({
22010
22019
  __name: "SpeakerMenu",
22011
22020
  emits: ["merge"],
22012
22021
  setup(__props, { emit: __emit }) {
@@ -22019,7 +22028,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22019
22028
  if (action.id === "merge") emit2("merge");
22020
22029
  }
22021
22030
  return (_ctx, _cache) => {
22022
- return openBlock(), createBlock(_sfc_main$E, {
22031
+ return openBlock(), createBlock(_sfc_main$G, {
22023
22032
  items: items.value,
22024
22033
  "item-key": (a2) => a2.id,
22025
22034
  align: "end",
@@ -22040,13 +22049,13 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22040
22049
  };
22041
22050
  }
22042
22051
  });
22043
- const _hoisted_1$t = ["aria-label"];
22044
- const _hoisted_2$m = ["aria-selected", "aria-disabled", "disabled", "onClick"];
22052
+ const _hoisted_1$u = ["aria-label"];
22053
+ const _hoisted_2$n = ["aria-selected", "aria-disabled", "disabled", "onClick"];
22045
22054
  const _hoisted_3$g = { class: "tab__label" };
22046
22055
  const _hoisted_4$b = ["aria-selected", "aria-label"];
22047
- const _hoisted_5$9 = { class: "tab__label" };
22056
+ const _hoisted_5$a = { class: "tab__label" };
22048
22057
  const _hoisted_6$9 = { class: "tab__menu-item" };
22049
- const _sfc_main$w = /* @__PURE__ */ defineComponent({
22058
+ const _sfc_main$y = /* @__PURE__ */ defineComponent({
22050
22059
  __name: "Tabs",
22051
22060
  props: {
22052
22061
  tabs: { type: Array },
@@ -22106,9 +22115,9 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22106
22115
  ]),
22107
22116
  _: 2
22108
22117
  }, 1024)) : createCommentVNode("", true)
22109
- ], 10, _hoisted_2$m);
22118
+ ], 10, _hoisted_2$n);
22110
22119
  }), 128)),
22111
- collapsedTabs.value.length > 0 ? (openBlock(), createBlock(_sfc_main$E, {
22120
+ collapsedTabs.value.length > 0 ? (openBlock(), createBlock(_sfc_main$G, {
22112
22121
  key: 0,
22113
22122
  items: collapsedTabs.value,
22114
22123
  "item-key": (tab) => tab.value,
@@ -22124,7 +22133,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22124
22133
  "aria-selected": activeCollapsedTab.value !== null,
22125
22134
  "aria-label": unref(t2)("tabs.moreLabel")
22126
22135
  }, [
22127
- createBaseVNode("span", _hoisted_5$9, toDisplayString(activeCollapsedTab.value ? activeCollapsedTab.value.label : unref(t2)("tabs.moreLabel")), 1),
22136
+ createBaseVNode("span", _hoisted_5$a, toDisplayString(activeCollapsedTab.value ? activeCollapsedTab.value.label : unref(t2)("tabs.moreLabel")), 1),
22128
22137
  activeCollapsedTab.value?.badge ? (openBlock(), createBlock(Badge, {
22129
22138
  key: 0,
22130
22139
  class: "tab__badge"
@@ -22159,12 +22168,12 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22159
22168
  ]),
22160
22169
  _: 1
22161
22170
  }, 8, ["items", "item-key", "is-current"])) : createCommentVNode("", true)
22162
- ], 8, _hoisted_1$t);
22171
+ ], 8, _hoisted_1$u);
22163
22172
  };
22164
22173
  }
22165
22174
  });
22166
- const _style_0$r = '\n.tabs[data-v-30747b8d] {\n display: flex;\n align-items: stretch;\n gap: var(--spacing-xs);\n padding: 0 var(--spacing-lg);\n border-bottom: 1px solid var(--color-border);\n background-color: var(--color-surface);\n overflow-x: auto;\n scrollbar-width: thin;\n}\n.transcript-ui-root .tab[data-v-30747b8d] {\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-xs);\n height: 44px;\n padding: 0 var(--spacing-sm);\n font-family: var(--font-family);\n font-size: var(--font-size-sm);\n font-weight: 500;\n color: var(--color-text-secondary);\n cursor: pointer;\n white-space: nowrap;\n border-bottom: 2px solid transparent;\n transition:\n color var(--transition-duration),\n border-color var(--transition-duration);\n}\n.transcript-ui-root .tab[data-v-30747b8d]:hover:not([disabled]) {\n color: var(--color-text-primary);\n}\n.transcript-ui-root .tab[data-v-30747b8d]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: -2px;\n border-radius: var(--radius-sm);\n}\n.transcript-ui-root .tab--active[data-v-30747b8d] {\n color: var(--color-text-primary);\n border-bottom-color: var(--color-primary);\n}\n.transcript-ui-root .tab[disabled][data-v-30747b8d] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.tab__icon[data-v-30747b8d] {\n flex-shrink: 0;\n color: currentColor;\n}\n.tab__label[data-v-30747b8d] {\n text-box: cap alphabetic;\n}\n.tab__badge[data-v-30747b8d] {\n margin-left: var(--spacing-xs);\n}\n.tab__chevron[data-v-30747b8d] {\n flex-shrink: 0;\n color: currentColor;\n}\n.tab__menu-item[data-v-30747b8d] {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n\n/* Phone: the inline tabs share the width, labels shrink with an ellipsis,\n icons go, nothing scrolls sideways (the rest lives in the "More" menu). */\n@media (max-width: 767px) {\n.tabs[data-v-30747b8d] {\n padding: 0 var(--spacing-sm);\n overflow-x: hidden;\n}\n.transcript-ui-root .tab[data-v-30747b8d] {\n flex: 1;\n min-width: 0;\n justify-content: center;\n padding: 0 var(--spacing-xs);\n font-size: var(--font-size-xs);\n}\n.tab__icon[data-v-30747b8d] {\n display: none;\n}\n.tab__label[data-v-30747b8d] {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n}\n';
22167
- const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["styles", [_style_0$r]], ["__scopeId", "data-v-30747b8d"]]);
22175
+ const _style_0$s = '\n.tabs[data-v-30747b8d] {\n display: flex;\n align-items: stretch;\n gap: var(--spacing-xs);\n padding: 0 var(--spacing-lg);\n border-bottom: 1px solid var(--color-border);\n background-color: var(--color-surface);\n overflow-x: auto;\n scrollbar-width: thin;\n}\n.transcript-ui-root .tab[data-v-30747b8d] {\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-xs);\n height: 44px;\n padding: 0 var(--spacing-sm);\n font-family: var(--font-family);\n font-size: var(--font-size-sm);\n font-weight: 500;\n color: var(--color-text-secondary);\n cursor: pointer;\n white-space: nowrap;\n border-bottom: 2px solid transparent;\n transition:\n color var(--transition-duration),\n border-color var(--transition-duration);\n}\n.transcript-ui-root .tab[data-v-30747b8d]:hover:not([disabled]) {\n color: var(--color-text-primary);\n}\n.transcript-ui-root .tab[data-v-30747b8d]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: -2px;\n border-radius: var(--radius-sm);\n}\n.transcript-ui-root .tab--active[data-v-30747b8d] {\n color: var(--color-text-primary);\n border-bottom-color: var(--color-primary);\n}\n.transcript-ui-root .tab[disabled][data-v-30747b8d] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.tab__icon[data-v-30747b8d] {\n flex-shrink: 0;\n color: currentColor;\n}\n.tab__label[data-v-30747b8d] {\n text-box: cap alphabetic;\n}\n.tab__badge[data-v-30747b8d] {\n margin-left: var(--spacing-xs);\n}\n.tab__chevron[data-v-30747b8d] {\n flex-shrink: 0;\n color: currentColor;\n}\n.tab__menu-item[data-v-30747b8d] {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n\n/* Phone: the inline tabs share the width, labels shrink with an ellipsis,\n icons go, nothing scrolls sideways (the rest lives in the "More" menu). */\n@media (max-width: 767px) {\n.tabs[data-v-30747b8d] {\n padding: 0 var(--spacing-sm);\n overflow-x: hidden;\n}\n.transcript-ui-root .tab[data-v-30747b8d] {\n flex: 1;\n min-width: 0;\n justify-content: center;\n padding: 0 var(--spacing-xs);\n font-size: var(--font-size-xs);\n}\n.tab__icon[data-v-30747b8d] {\n display: none;\n}\n.tab__label[data-v-30747b8d] {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n}\n';
22176
+ const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["styles", [_style_0$s]], ["__scopeId", "data-v-30747b8d"]]);
22168
22177
  const TEXT_NODE$1 = 3;
22169
22178
  function placeCaretAt(element, offset2) {
22170
22179
  element.focus({ preventScroll: true });
@@ -22221,8 +22230,8 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22221
22230
  if (!focus2 || !container.contains(focus2.node)) return null;
22222
22231
  return computeTextOffsetInContainer(container, focus2.node, focus2.offset);
22223
22232
  }
22224
- const _hoisted_1$s = ["aria-label", "textContent"];
22225
- const _sfc_main$v = /* @__PURE__ */ defineComponent({
22233
+ const _hoisted_1$t = ["aria-label", "textContent"];
22234
+ const _sfc_main$x = /* @__PURE__ */ defineComponent({
22226
22235
  __name: "TurnTextEditor",
22227
22236
  props: {
22228
22237
  text: { type: String },
@@ -22276,22 +22285,22 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22276
22285
  onKeydown,
22277
22286
  onBlur,
22278
22287
  textContent: toDisplayString(__props.text)
22279
- }, null, 40, _hoisted_1$s);
22288
+ }, null, 40, _hoisted_1$t);
22280
22289
  };
22281
22290
  }
22282
22291
  });
22283
- const _style_0$q = "\n.turn-text-editor[data-v-597e2575] {\n margin: 0;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n cursor: text;\n outline: 2px solid var(--color-primary);\n border-radius: var(--radius-sm);\n background-color: var(--color-surface);\n padding: 0;\n}\n";
22284
- const TurnTextEditor = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["styles", [_style_0$q]], ["__scopeId", "data-v-597e2575"]]);
22285
- const _hoisted_1$r = { class: "editor-header" };
22286
- const _hoisted_2$l = { class: "header-main" };
22292
+ const _style_0$r = "\n.turn-text-editor[data-v-597e2575] {\n margin: 0;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n cursor: text;\n outline: 2px solid var(--color-primary);\n border-radius: var(--radius-sm);\n background-color: var(--color-surface);\n padding: 0;\n}\n";
22293
+ const TurnTextEditor = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["styles", [_style_0$r]], ["__scopeId", "data-v-597e2575"]]);
22294
+ const _hoisted_1$s = { class: "editor-header" };
22295
+ const _hoisted_2$m = { class: "header-main" };
22287
22296
  const _hoisted_3$f = { class: "document-title" };
22288
22297
  const _hoisted_4$a = {
22289
22298
  key: 0,
22290
22299
  class: "document-meta"
22291
22300
  };
22292
- const _hoisted_5$8 = { class: "header-right" };
22301
+ const _hoisted_5$9 = { class: "header-right" };
22293
22302
  const _hoisted_6$8 = { key: 0 };
22294
- const _sfc_main$u = /* @__PURE__ */ defineComponent({
22303
+ const _sfc_main$w = /* @__PURE__ */ defineComponent({
22295
22304
  __name: "Header",
22296
22305
  props: {
22297
22306
  title: { type: String },
@@ -22325,8 +22334,8 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22325
22334
  ].filter(Boolean)
22326
22335
  );
22327
22336
  return (_ctx, _cache) => {
22328
- return openBlock(), createElementBlock("header", _hoisted_1$r, [
22329
- createBaseVNode("div", _hoisted_2$l, [
22337
+ return openBlock(), createElementBlock("header", _hoisted_1$s, [
22338
+ createBaseVNode("div", _hoisted_2$m, [
22330
22339
  createBaseVNode("h1", _hoisted_3$f, toDisplayString(formattedTitle.value), 1),
22331
22340
  metaParts.value.length ? (openBlock(), createElementBlock("div", _hoisted_4$a, [
22332
22341
  (openBlock(true), createElementBlock(Fragment, null, renderList(metaParts.value, (part, i2) => {
@@ -22337,7 +22346,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22337
22346
  }), 128))
22338
22347
  ])) : createCommentVNode("", true)
22339
22348
  ]),
22340
- createBaseVNode("div", _hoisted_5$8, [
22349
+ createBaseVNode("div", _hoisted_5$9, [
22341
22350
  __props.isMobile ? (openBlock(), createBlock(unref(Button), {
22342
22351
  key: 0,
22343
22352
  variant: "transparent",
@@ -22404,13 +22413,13 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22404
22413
  };
22405
22414
  }
22406
22415
  });
22407
- const _style_0$p = '\n.editor-header[data-v-491cf8ab] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-md);\n padding: var(--spacing-sm) var(--spacing-lg);\n min-height: var(--header-height);\n border-bottom: 1px solid var(--color-border);\n background-color: var(--color-surface);\n flex-shrink: 0;\n}\n.header-main[data-v-491cf8ab] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n.document-title[data-v-491cf8ab] {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0;\n}\n.document-meta[data-v-491cf8ab] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-xs);\n font-size: var(--font-size-xs);\n color: var(--color-text-muted);\n}\n.document-meta__part[data-v-491cf8ab] {\n text-box: cap alphabetic;\n}\n.document-meta__part + .document-meta__part[data-v-491cf8ab]::before {\n content: "·";\n margin-right: var(--spacing-xs);\n}\n.header-right[data-v-491cf8ab] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n flex-shrink: 0;\n}\n@media (max-width: 767px) {\n.editor-header[data-v-491cf8ab] {\n padding: var(--spacing-xs) var(--spacing-md);\n}\n.document-title[data-v-491cf8ab] {\n font-size: var(--font-size-base);\n}\n}\n';
22408
- const Header = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["styles", [_style_0$p]], ["__scopeId", "data-v-491cf8ab"]]);
22416
+ const _style_0$q = '\n.editor-header[data-v-491cf8ab] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-md);\n padding: var(--spacing-sm) var(--spacing-lg);\n min-height: var(--header-height);\n border-bottom: 1px solid var(--color-border);\n background-color: var(--color-surface);\n flex-shrink: 0;\n}\n.header-main[data-v-491cf8ab] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n.document-title[data-v-491cf8ab] {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0;\n}\n.document-meta[data-v-491cf8ab] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-xs);\n font-size: var(--font-size-xs);\n color: var(--color-text-muted);\n}\n.document-meta__part[data-v-491cf8ab] {\n text-box: cap alphabetic;\n}\n.document-meta__part + .document-meta__part[data-v-491cf8ab]::before {\n content: "·";\n margin-right: var(--spacing-xs);\n}\n.header-right[data-v-491cf8ab] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n flex-shrink: 0;\n}\n@media (max-width: 767px) {\n.editor-header[data-v-491cf8ab] {\n padding: var(--spacing-xs) var(--spacing-md);\n}\n.document-title[data-v-491cf8ab] {\n font-size: var(--font-size-base);\n}\n}\n';
22417
+ const Header = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["styles", [_style_0$q]], ["__scopeId", "data-v-491cf8ab"]]);
22409
22418
  const TRANSCRIPTION_TAB = "__transcription__";
22410
22419
  const VERBATIM_TAB = "__verbatim__";
22411
22420
  const MOBILE_BREAKPOINT = "(max-width: 767px)";
22412
22421
  function useIsMobile() {
22413
- const isMobile = /* @__PURE__ */ ref(false);
22422
+ const isMobile = /* @__PURE__ */ ref(window.matchMedia(MOBILE_BREAKPOINT).matches);
22414
22423
  let mql = null;
22415
22424
  function onChange(e2) {
22416
22425
  isMobile.value = e2.matches;
@@ -22425,7 +22434,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22425
22434
  });
22426
22435
  return { isMobile };
22427
22436
  }
22428
- const _sfc_main$t = /* @__PURE__ */ defineComponent({
22437
+ const _sfc_main$v = /* @__PURE__ */ defineComponent({
22429
22438
  __name: "TabBar",
22430
22439
  props: {
22431
22440
  modelValue: { type: String },
@@ -22845,7 +22854,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22845
22854
  };
22846
22855
  }
22847
22856
  var StickToBottomKey = /* @__PURE__ */ Symbol("StickToBottom");
22848
- var _hoisted_1$q = { style: {
22857
+ var _hoisted_1$r = { style: {
22849
22858
  "position": "relative",
22850
22859
  "height": "100%",
22851
22860
  "width": "100%",
@@ -22911,7 +22920,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22911
22920
  stopScroll
22912
22921
  }));
22913
22922
  return (_ctx, _cache) => {
22914
- return openBlock(), createElementBlock("div", null, [createBaseVNode("div", _hoisted_1$q, [createBaseVNode("div", {
22923
+ return openBlock(), createElementBlock("div", null, [createBaseVNode("div", _hoisted_1$r, [createBaseVNode("div", {
22915
22924
  ref_key: "scrollRef",
22916
22925
  ref: scrollRef,
22917
22926
  style: normalizeStyle({
@@ -22928,12 +22937,12 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22928
22937
  };
22929
22938
  }
22930
22939
  });
22931
- const _hoisted_1$p = ["datetime"];
22932
- const _hoisted_2$k = {
22940
+ const _hoisted_1$q = ["datetime"];
22941
+ const _hoisted_2$l = {
22933
22942
  key: 2,
22934
22943
  class: "lang"
22935
22944
  };
22936
- const _sfc_main$s = /* @__PURE__ */ defineComponent({
22945
+ const _sfc_main$u = /* @__PURE__ */ defineComponent({
22937
22946
  __name: "SpeakerLabel",
22938
22947
  props: {
22939
22948
  speaker: { type: Object },
@@ -22985,19 +22994,19 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
22985
22994
  key: 1,
22986
22995
  class: "timestamp",
22987
22996
  datetime: timestamp.value.datetime
22988
- }, toDisplayString(timestamp.value.text), 9, _hoisted_1$p)) : createCommentVNode("", true),
22989
- languageName.value ? (openBlock(), createElementBlock("span", _hoisted_2$k, toDisplayString(languageName.value), 1)) : createCommentVNode("", true)
22997
+ }, toDisplayString(timestamp.value.text), 9, _hoisted_1$q)) : createCommentVNode("", true),
22998
+ languageName.value ? (openBlock(), createElementBlock("span", _hoisted_2$l, toDisplayString(languageName.value), 1)) : createCommentVNode("", true)
22990
22999
  ], 2);
22991
23000
  };
22992
23001
  }
22993
23002
  });
22994
- const _style_0$o = "\n.speaker-label[data-v-76cb4ed6] {\n display: flex;\n border-bottom: 2px solid transparent;\n align-items: center;\n gap: var(--spacing-sm);\n}\n.speaker-name[data-v-76cb4ed6] {\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.speaker-name--unknown[data-v-76cb4ed6] {\n font-weight: 400;\n font-style: italic;\n color: var(--color-text-muted);\n}\n.speaker-label--interactive:hover .speaker-name[data-v-76cb4ed6] {\n text-decoration: underline;\n}\n.timestamp[data-v-76cb4ed6] {\n font-size: var(--font-size-xs);\n font-family: var(--font-family-mono);\n color: var(--color-text-muted);\n /* not supported on firefox yet */\n text-box: trim-both cap alphabetic;\n}\n.lang[data-v-76cb4ed6] {\n font-size: var(--font-size-xs);\n font-weight: 400;\n /* not supported on firefox yet */\n text-box: trim-both cap alphabetic;\n}\n";
22995
- const SpeakerLabel = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["styles", [_style_0$o]], ["__scopeId", "data-v-76cb4ed6"]]);
22996
- const _hoisted_1$o = {
23003
+ const _style_0$p = "\n.speaker-label[data-v-76cb4ed6] {\n display: flex;\n border-bottom: 2px solid transparent;\n align-items: center;\n gap: var(--spacing-sm);\n}\n.speaker-name[data-v-76cb4ed6] {\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.speaker-name--unknown[data-v-76cb4ed6] {\n font-weight: 400;\n font-style: italic;\n color: var(--color-text-muted);\n}\n.speaker-label--interactive:hover .speaker-name[data-v-76cb4ed6] {\n text-decoration: underline;\n}\n.timestamp[data-v-76cb4ed6] {\n font-size: var(--font-size-xs);\n font-family: var(--font-family-mono);\n color: var(--color-text-muted);\n /* not supported on firefox yet */\n text-box: trim-both cap alphabetic;\n}\n.lang[data-v-76cb4ed6] {\n font-size: var(--font-size-xs);\n font-weight: 400;\n /* not supported on firefox yet */\n text-box: trim-both cap alphabetic;\n}\n";
23004
+ const SpeakerLabel = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["styles", [_style_0$p]], ["__scopeId", "data-v-76cb4ed6"]]);
23005
+ const _hoisted_1$p = {
22997
23006
  key: 0,
22998
23007
  class: "merge-turns"
22999
23008
  };
23000
- const _sfc_main$r = /* @__PURE__ */ defineComponent({
23009
+ const _sfc_main$t = /* @__PURE__ */ defineComponent({
23001
23010
  __name: "MergeTurnsButton",
23002
23011
  props: {
23003
23012
  firstTurnId: { type: String },
@@ -23017,7 +23026,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23017
23026
  core.transcriptionEditor.mergeTurns(props.firstTurnId, props.secondTurnId);
23018
23027
  }
23019
23028
  return (_ctx, _cache) => {
23020
- return canShow.value ? (openBlock(), createElementBlock("div", _hoisted_1$o, [
23029
+ return canShow.value ? (openBlock(), createElementBlock("div", _hoisted_1$p, [
23021
23030
  createVNode(unref(Button), {
23022
23031
  size: "sm",
23023
23032
  variant: "inverse",
@@ -23030,8 +23039,8 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23030
23039
  };
23031
23040
  }
23032
23041
  });
23033
- const _style_0$n = "\n.merge-turns[data-v-8d977feb] {\n display: flex;\n justify-content: center;\n}\n\n/* Compact: the control sits in the gap between turns without inflating it. */\n.merge-turns[data-v-8d977feb] .editor-btn {\n --btn-height: 22px;\n}\n";
23034
- const MergeTurnsButton = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["styles", [_style_0$n]], ["__scopeId", "data-v-8d977feb"]]);
23042
+ const _style_0$o = "\n.merge-turns[data-v-8d977feb] {\n display: flex;\n justify-content: center;\n}\n\n/* Compact: the control sits in the gap between turns without inflating it. */\n.merge-turns[data-v-8d977feb] .editor-btn {\n --btn-height: 22px;\n}\n";
23043
+ const MergeTurnsButton = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["styles", [_style_0$o]], ["__scopeId", "data-v-8d977feb"]]);
23035
23044
  function renameSpeaker$1(core, speakerId, newName) {
23036
23045
  const trimmed = newName.trim();
23037
23046
  const existing = core.speakers.all.get(speakerId);
@@ -23094,12 +23103,12 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23094
23103
  switchTurnSpeaker: switchTurnSpeaker$1,
23095
23104
  updateTurnWords
23096
23105
  }, Symbol.toStringTag, { value: "Module" }));
23097
- const _hoisted_1$n = {
23106
+ const _hoisted_1$o = {
23098
23107
  type: "button",
23099
23108
  class: "speaker-popover-trigger"
23100
23109
  };
23101
- const _hoisted_2$j = { class: "speaker-popover-name" };
23102
- const _sfc_main$q = /* @__PURE__ */ defineComponent({
23110
+ const _hoisted_2$k = { class: "speaker-popover-name" };
23111
+ const _sfc_main$s = /* @__PURE__ */ defineComponent({
23103
23112
  __name: "SpeakerPopover",
23104
23113
  props: {
23105
23114
  turnId: { type: String },
@@ -23165,7 +23174,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23165
23174
  isCreatingNew.value = false;
23166
23175
  }
23167
23176
  return (_ctx, _cache) => {
23168
- return openBlock(), createBlock(unref(_sfc_main$E), {
23177
+ return openBlock(), createBlock(unref(_sfc_main$G), {
23169
23178
  open: isOpen.value,
23170
23179
  "onUpdate:open": _cache[1] || (_cache[1] = ($event) => isOpen.value = $event),
23171
23180
  items: speakers.value,
@@ -23174,7 +23183,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23174
23183
  onSelect: onPickExisting
23175
23184
  }, {
23176
23185
  trigger: withCtx(() => [
23177
- createBaseVNode("button", _hoisted_1$n, [
23186
+ createBaseVNode("button", _hoisted_1$o, [
23178
23187
  renderSlot(_ctx.$slots, "default", {}, void 0, true)
23179
23188
  ])
23180
23189
  ]),
@@ -23182,7 +23191,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23182
23191
  createVNode(unref(SpeakerIndicator), {
23183
23192
  color: item.color
23184
23193
  }, null, 8, ["color"]),
23185
- createBaseVNode("span", _hoisted_2$j, toDisplayString(item.name), 1)
23194
+ createBaseVNode("span", _hoisted_2$k, toDisplayString(item.name), 1)
23186
23195
  ]),
23187
23196
  footer: withCtx(() => [
23188
23197
  !isCreatingNew.value ? (openBlock(), createBlock(unref(Button), {
@@ -23215,8 +23224,8 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
23215
23224
  };
23216
23225
  }
23217
23226
  });
23218
- const _style_0$m = "\n.transcript-ui-root .speaker-popover-trigger[data-v-0679fde9] {\n all: unset;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n border-radius: var(--radius-sm);\n}\n.transcript-ui-root .speaker-popover-trigger[data-v-0679fde9]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.speaker-popover-name[data-v-0679fde9] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
23219
- const SpeakerPopover = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["styles", [_style_0$m]], ["__scopeId", "data-v-0679fde9"]]);
23227
+ const _style_0$n = "\n.transcript-ui-root .speaker-popover-trigger[data-v-0679fde9] {\n all: unset;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n border-radius: var(--radius-sm);\n}\n.transcript-ui-root .speaker-popover-trigger[data-v-0679fde9]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.speaker-popover-name[data-v-0679fde9] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
23228
+ const SpeakerPopover = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["styles", [_style_0$n]], ["__scopeId", "data-v-0679fde9"]]);
23220
23229
  const turnSelectionKey = /* @__PURE__ */ Symbol("turnSelection");
23221
23230
  function getTurnText(turn) {
23222
23231
  if (turn.words.length > 0) {
@@ -23362,14 +23371,14 @@ ${text2}` : text2;
23362
23371
  (w2) => w2.charStart != null && w2.charEnd != null && w2.charStart <= offset2 && offset2 < w2.charEnd
23363
23372
  );
23364
23373
  }
23365
- const _hoisted_1$m = ["data-turn-active", "aria-selected"];
23366
- const _hoisted_2$i = {
23374
+ const _hoisted_1$n = ["data-turn-active", "aria-selected"];
23375
+ const _hoisted_2$j = {
23367
23376
  key: 4,
23368
23377
  class: "turn-edit-actions"
23369
23378
  };
23370
23379
  const _hoisted_3$e = ["role", "tabindex", "aria-label", "aria-disabled"];
23371
23380
  const _hoisted_4$9 = ["data-word-active"];
23372
- const _sfc_main$p = /* @__PURE__ */ defineComponent({
23381
+ const _sfc_main$r = /* @__PURE__ */ defineComponent({
23373
23382
  __name: "TranscriptionTurn",
23374
23383
  props: {
23375
23384
  turn: { type: Object },
@@ -23550,7 +23559,7 @@ ${text2}` : text2;
23550
23559
  "start-date": __props.turn.startDate,
23551
23560
  language: __props.turn.language
23552
23561
  }, null, 8, ["speaker", "start-time", "start-date", "language"])),
23553
- isEditing.value || turnLock.value ? (openBlock(), createElementBlock("div", _hoisted_2$i, [
23562
+ isEditing.value || turnLock.value ? (openBlock(), createElementBlock("div", _hoisted_2$j, [
23554
23563
  isEditing.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
23555
23564
  createVNode(unref(Button), {
23556
23565
  size: "sm",
@@ -23612,43 +23621,43 @@ ${text2}` : text2;
23612
23621
  createTextVNode(toDisplayString(__props.turn.text), 1)
23613
23622
  ], 64)) : createCommentVNode("", true)
23614
23623
  ], 42, _hoisted_3$e))
23615
- ], 14, _hoisted_1$m);
23624
+ ], 14, _hoisted_1$n);
23616
23625
  };
23617
23626
  }
23618
23627
  });
23619
- const _style_0$l = "\n.turn[data-v-5a13b85e] {\n padding: var(--spacing-sm) var(--spacing-lg);\n}\n.turn-header[data-v-5a13b85e] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n cursor: pointer;\n user-select: none;\n border-radius: var(--radius-sm);\n padding: var(--spacing-xxs) 0;\n /* Reserve the edit-actions height (Button sm) so entering/leaving edit\n mode never shifts the layout. */\n min-height: 36px;\n}\n.turn-edit-actions[data-v-5a13b85e] {\n margin-left: auto;\n display: flex;\n gap: var(--spacing-xs);\n}\n\n/* Same reset as the popover's own trigger: the label IS the button. */\n.transcript-ui-root .speaker-trigger[data-v-5a13b85e] {\n all: unset;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n border-radius: var(--radius-sm);\n}\n.transcript-ui-root .speaker-trigger[data-v-5a13b85e]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.turn[data-v-5a13b85e]:has(.turn-header:hover) {\n background-color: var(--color-surface-hover);\n}\n.turn-text[data-v-5a13b85e] {\n margin-top: var(--spacing-xs);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n}\n.turn-text--editable[data-v-5a13b85e] {\n cursor: text;\n}\n.turn-text--editable[data-v-5a13b85e]:focus-visible {\n outline: 2px solid var(--color-primary);\n border-radius: var(--radius-sm);\n}\n.turn--selected[data-v-5a13b85e] {\n background-color: color-mix(in srgb, var(--color-primary) 8%, transparent);\n border-left: 3px solid var(--color-primary);\n padding-left: calc(var(--spacing-lg) - 3px);\n}\n.turn--active[data-v-5a13b85e]:not(.turn--selected) {\n border-left: 3px solid var(--speaker-color);\n background-color: color-mix(in srgb, var(--speaker-color) 8%, transparent);\n padding-left: calc(var(--spacing-lg) - 3px);\n}\n.word--active[data-v-5a13b85e] {\n text-decoration: underline;\n text-decoration-color: var(--color-primary);\n text-decoration-thickness: 2px;\n text-underline-offset: 3px;\n color: var(--color-primary);\n}\n.turn--partial .turn-text[data-v-5a13b85e] {\n font-style: italic;\n color: var(--color-text-muted);\n animation: partial-fade-in-5a13b85e 200ms ease;\n}\n@keyframes partial-fade-in-5a13b85e {\nfrom {\n opacity: 0;\n}\nto {\n opacity: 1;\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.turn--partial .turn-text[data-v-5a13b85e] {\n animation: none;\n}\n}\n@media (max-width: 767px) {\n.turn[data-v-5a13b85e] {\n padding: var(--spacing-sm) var(--spacing-md);\n}\n.turn--selected[data-v-5a13b85e],\n .turn--active[data-v-5a13b85e]:not(.turn--selected) {\n padding-left: calc(var(--spacing-md) - 3px);\n}\n}\n";
23620
- const TranscriptionTurn = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["styles", [_style_0$l]], ["__scopeId", "data-v-5a13b85e"]]);
23621
- const _sfc_main$o = {};
23622
- const _hoisted_1$l = {
23628
+ const _style_0$m = "\n.turn[data-v-5a13b85e] {\n padding: var(--spacing-sm) var(--spacing-lg);\n}\n.turn-header[data-v-5a13b85e] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n cursor: pointer;\n user-select: none;\n border-radius: var(--radius-sm);\n padding: var(--spacing-xxs) 0;\n /* Reserve the edit-actions height (Button sm) so entering/leaving edit\n mode never shifts the layout. */\n min-height: 36px;\n}\n.turn-edit-actions[data-v-5a13b85e] {\n margin-left: auto;\n display: flex;\n gap: var(--spacing-xs);\n}\n\n/* Same reset as the popover's own trigger: the label IS the button. */\n.transcript-ui-root .speaker-trigger[data-v-5a13b85e] {\n all: unset;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n border-radius: var(--radius-sm);\n}\n.transcript-ui-root .speaker-trigger[data-v-5a13b85e]:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.turn[data-v-5a13b85e]:has(.turn-header:hover) {\n background-color: var(--color-surface-hover);\n}\n.turn-text[data-v-5a13b85e] {\n margin-top: var(--spacing-xs);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n}\n.turn-text--editable[data-v-5a13b85e] {\n cursor: text;\n}\n.turn-text--editable[data-v-5a13b85e]:focus-visible {\n outline: 2px solid var(--color-primary);\n border-radius: var(--radius-sm);\n}\n.turn--selected[data-v-5a13b85e] {\n background-color: color-mix(in srgb, var(--color-primary) 8%, transparent);\n border-left: 3px solid var(--color-primary);\n padding-left: calc(var(--spacing-lg) - 3px);\n}\n.turn--active[data-v-5a13b85e]:not(.turn--selected) {\n border-left: 3px solid var(--speaker-color);\n background-color: color-mix(in srgb, var(--speaker-color) 8%, transparent);\n padding-left: calc(var(--spacing-lg) - 3px);\n}\n.word--active[data-v-5a13b85e] {\n text-decoration: underline;\n text-decoration-color: var(--color-primary);\n text-decoration-thickness: 2px;\n text-underline-offset: 3px;\n color: var(--color-primary);\n}\n.turn--partial .turn-text[data-v-5a13b85e] {\n font-style: italic;\n color: var(--color-text-muted);\n animation: partial-fade-in-5a13b85e 200ms ease;\n}\n@keyframes partial-fade-in-5a13b85e {\nfrom {\n opacity: 0;\n}\nto {\n opacity: 1;\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.turn--partial .turn-text[data-v-5a13b85e] {\n animation: none;\n}\n}\n@media (max-width: 767px) {\n.turn[data-v-5a13b85e] {\n padding: var(--spacing-sm) var(--spacing-md);\n}\n.turn--selected[data-v-5a13b85e],\n .turn--active[data-v-5a13b85e]:not(.turn--selected) {\n padding-left: calc(var(--spacing-md) - 3px);\n}\n}\n";
23629
+ const TranscriptionTurn = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["styles", [_style_0$m]], ["__scopeId", "data-v-5a13b85e"]]);
23630
+ const _sfc_main$q = {};
23631
+ const _hoisted_1$m = {
23623
23632
  viewBox: "0 0 938 604",
23624
23633
  fill: "none",
23625
23634
  xmlns: "http://www.w3.org/2000/svg"
23626
23635
  };
23627
23636
  function _sfc_render(_ctx, _cache) {
23628
- return openBlock(), createElementBlock("svg", _hoisted_1$l, [..._cache[0] || (_cache[0] = [
23637
+ return openBlock(), createElementBlock("svg", _hoisted_1$m, [..._cache[0] || (_cache[0] = [
23629
23638
  createStaticVNode('<polygon points="331.5,533.5 331.5,520.5 702.5,428.5 705.5,443.5" fill="#3f3d56" transform="matrix(1.8176168,0,0,1.8176168,-452.14416,-495.30213)"></polygon><polygon points="564.5,469.5 555.5,452.5 544.5,455.5 542.5,472.5" fill="#3f3d56" transform="matrix(1.8176168,0,0,1.8176168,-452.14416,-495.30213)"></polygon><path d="m 317.61655,19.99224 c 0,0 79.97514,-5.452851 101.78654,56.34612 21.81141,61.79897 72.70468,172.67359 92.69846,189.03214 19.99379,16.35855 41.80519,59.98136 38.16995,74.52229" stroke="#3f3d56" stroke-miterlimit="10" stroke-width="9.08808"></path><path d="m 329.43106,19.083431 c 0,8.532657 -9.0733,15.449743 -23.62902,15.449743 -14.55571,0 -21.8114,-6.917086 -21.8114,-15.449743 0,-8.532657 7.25569,-15.4497427 21.8114,-15.4497427 14.55572,0 23.62902,6.9170857 23.62902,15.4497427 z" fill="currentColor" style="fill:#999999;"></path><polygon points="691.5,439.5 364.5,521.5 377.5,602.5 666.5,602.5" fill="#3f3d56" transform="matrix(1.8176168,0,0,1.8176168,-456.32371,-492.51252)"></polygon>', 5)
23630
23639
  ])]);
23631
23640
  }
23632
- const MicrophoneIllustration = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render]]);
23633
- const _hoisted_1$k = { class: "transcription-empty" };
23634
- const _hoisted_2$h = { class: "message" };
23635
- const _sfc_main$n = /* @__PURE__ */ defineComponent({
23641
+ const MicrophoneIllustration = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["render", _sfc_render]]);
23642
+ const _hoisted_1$l = { class: "transcription-empty" };
23643
+ const _hoisted_2$i = { class: "message" };
23644
+ const _sfc_main$p = /* @__PURE__ */ defineComponent({
23636
23645
  __name: "TranscriptionEmpty",
23637
23646
  setup(__props) {
23638
23647
  const { t: t2 } = useI18n();
23639
23648
  return (_ctx, _cache) => {
23640
- return openBlock(), createElementBlock("div", _hoisted_1$k, [
23649
+ return openBlock(), createElementBlock("div", _hoisted_1$l, [
23641
23650
  createVNode(MicrophoneIllustration, {
23642
23651
  class: "illustration",
23643
23652
  "aria-hidden": "true"
23644
23653
  }),
23645
- createBaseVNode("p", _hoisted_2$h, toDisplayString(unref(t2)("transcription.empty")), 1)
23654
+ createBaseVNode("p", _hoisted_2$i, toDisplayString(unref(t2)("transcription.empty")), 1)
23646
23655
  ]);
23647
23656
  };
23648
23657
  }
23649
23658
  });
23650
- const _style_0$k = "\n.transcription-empty[data-v-585c4f2b] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-lg);\n padding: var(--spacing-xl);\n}\n.illustration[data-v-585c4f2b] {\n width: 180px;\n height: auto;\n color: var(--color-text-muted);\n opacity: 0.5;\n}\n.message[data-v-585c4f2b] {\n color: var(--color-text-muted);\n font-size: var(--font-size-sm);\n text-align: center;\n margin: 0;\n}\n";
23651
- const TranscriptionEmpty = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["styles", [_style_0$k]], ["__scopeId", "data-v-585c4f2b"]]);
23659
+ const _style_0$l = "\n.transcription-empty[data-v-585c4f2b] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-lg);\n padding: var(--spacing-xl);\n}\n.illustration[data-v-585c4f2b] {\n width: 180px;\n height: auto;\n color: var(--color-text-muted);\n opacity: 0.5;\n}\n.message[data-v-585c4f2b] {\n color: var(--color-text-muted);\n font-size: var(--font-size-sm);\n text-align: center;\n margin: 0;\n}\n";
23660
+ const TranscriptionEmpty = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["styles", [_style_0$l]], ["__scopeId", "data-v-585c4f2b"]]);
23652
23661
  function activeWordRange(root2, core, wordId2) {
23653
23662
  const parsed = parseWordId(wordId2);
23654
23663
  if (!parsed) return null;
@@ -23783,8 +23792,8 @@ ${text2}` : text2;
23783
23792
  }
23784
23793
  return { isFollowing, resumeFollow };
23785
23794
  }
23786
- const _hoisted_1$j = { class: "transcription-panel" };
23787
- const _hoisted_2$g = {
23795
+ const _hoisted_1$k = { class: "transcription-panel" };
23796
+ const _hoisted_2$h = {
23788
23797
  ref: "scrollContainer",
23789
23798
  class: "scroll-container"
23790
23799
  };
@@ -23794,7 +23803,7 @@ ${text2}` : text2;
23794
23803
  class: "history-loading",
23795
23804
  role: "status"
23796
23805
  };
23797
- const _hoisted_5$7 = {
23806
+ const _hoisted_5$8 = {
23798
23807
  key: 1,
23799
23808
  class: "history-start"
23800
23809
  };
@@ -23802,7 +23811,7 @@ ${text2}` : text2;
23802
23811
  key: 0,
23803
23812
  class: "resume-scroll-anchor"
23804
23813
  };
23805
- const _sfc_main$m = /* @__PURE__ */ defineComponent({
23814
+ const _sfc_main$o = /* @__PURE__ */ defineComponent({
23806
23815
  __name: "TranscriptionPanel",
23807
23816
  props: {
23808
23817
  turns: { type: Array },
@@ -23899,13 +23908,13 @@ ${text2}` : text2;
23899
23908
  scrollContainerRef.value?.removeEventListener("scroll", onScrollTop);
23900
23909
  });
23901
23910
  return (_ctx, _cache) => {
23902
- return openBlock(), createElementBlock("article", _hoisted_1$j, [
23903
- createBaseVNode("div", _hoisted_2$g, [
23911
+ return openBlock(), createElementBlock("article", _hoisted_1$k, [
23912
+ createBaseVNode("div", _hoisted_2$h, [
23904
23913
  createBaseVNode("div", _hoisted_3$d, [
23905
23914
  isLoadingHistory.value ? (openBlock(), createElementBlock("div", _hoisted_4$8, [..._cache[2] || (_cache[2] = [
23906
23915
  createBaseVNode("progress", null, null, -1)
23907
23916
  ])])) : createCommentVNode("", true),
23908
- !hasMoreHistory.value && __props.turns.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_5$7, toDisplayString(unref(t2)("transcription.historyStart")), 1)) : createCommentVNode("", true),
23917
+ !hasMoreHistory.value && __props.turns.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_5$8, toDisplayString(unref(t2)("transcription.historyStart")), 1)) : createCommentVNode("", true),
23909
23918
  __props.turns.length === 0 && !isLoadingHistory.value && !partialTurn.value ? (openBlock(), createBlock(TranscriptionEmpty, {
23910
23919
  key: 2,
23911
23920
  class: "transcription-empty"
@@ -23959,13 +23968,13 @@ ${text2}` : text2;
23959
23968
  };
23960
23969
  }
23961
23970
  });
23962
- const _style_0$j = "\n.transcription-panel[data-v-66b767d7] {\n min-height: 0;\n overflow: hidden;\n background-color: var(--color-surface);\n}\n.scroll-container[data-v-66b767d7] {\n height: 100%;\n overflow: auto;\n position: relative;\n}\n.turns-container[data-v-66b767d7] {\n max-width: 80ch;\n margin-inline: auto;\n padding: var(--spacing-lg);\n}\n.turns-container[data-v-66b767d7]:has(.transcription-empty) {\n display: flex;\n flex-direction: column;\n min-height: 100%;\n}\n.history-loading[data-v-66b767d7] {\n text-align: center;\n padding: var(--spacing-md);\n}\n.history-loading progress[data-v-66b767d7] {\n width: 120px;\n}\n.history-start[data-v-66b767d7] {\n text-align: center;\n padding: var(--spacing-md);\n color: var(--color-text-muted);\n font-size: var(--font-size-sm);\n}\n\n/* Resume scroll button — placement lives on this wrapper, never on the\n button itself: Button.vue's `.editor-btn` base rule resets `position` via\n `all: unset` (and, in the webcomponent build, gets re-injected a second\n time after everything else to reach teleported popovers/dialogs — see\n packages/webcomponent/src/index.ts), so any positioning put directly on\n the button is one rebuild away from being silently overridden again. */\n.resume-scroll-anchor[data-v-66b767d7] {\n position: sticky;\n bottom: var(--spacing-lg);\n z-index: var(--z-sticky);\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.resume-scroll-btn[data-v-66b767d7] {\n /* No backdrop-filter: this button is sticky inside the tall scroll\n container, where a backdrop-filter makes WebRender allocate a render\n target spanning the whole scroll height — multi-GB on a long transcript. */\n background: white !important;\n border: 1px solid var(--color-border);\n box-shadow: var(--shadow-sm);\n}\n\n/* Transition */\n.fade-slide-enter-active[data-v-66b767d7],\n.fade-slide-leave-active[data-v-66b767d7] {\n transition:\n opacity 200ms ease,\n translate 200ms ease;\n}\n.fade-slide-enter-from[data-v-66b767d7],\n.fade-slide-leave-to[data-v-66b767d7] {\n opacity: 0;\n translate: 0 8px;\n}\n@media (prefers-reduced-motion: reduce) {\n.fade-slide-enter-active[data-v-66b767d7],\n .fade-slide-leave-active[data-v-66b767d7] {\n transition: none;\n}\n}\n@media (max-width: 767px) {\n.turns-container[data-v-66b767d7] {\n padding: var(--spacing-md);\n}\n}\n";
23963
- const TranscriptionPanel = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["styles", [_style_0$j]], ["__scopeId", "data-v-66b767d7"]]);
23964
- const _hoisted_1$i = { class: "verbatim-panel" };
23965
- const _hoisted_2$f = { class: "verbatim-panel__content" };
23971
+ const _style_0$k = "\n.transcription-panel[data-v-66b767d7] {\n min-height: 0;\n overflow: hidden;\n background-color: var(--color-surface);\n}\n.scroll-container[data-v-66b767d7] {\n height: 100%;\n overflow: auto;\n position: relative;\n}\n.turns-container[data-v-66b767d7] {\n max-width: 80ch;\n margin-inline: auto;\n padding: var(--spacing-lg);\n}\n.turns-container[data-v-66b767d7]:has(.transcription-empty) {\n display: flex;\n flex-direction: column;\n min-height: 100%;\n}\n.history-loading[data-v-66b767d7] {\n text-align: center;\n padding: var(--spacing-md);\n}\n.history-loading progress[data-v-66b767d7] {\n width: 120px;\n}\n.history-start[data-v-66b767d7] {\n text-align: center;\n padding: var(--spacing-md);\n color: var(--color-text-muted);\n font-size: var(--font-size-sm);\n}\n\n/* Resume scroll button — placement lives on this wrapper, never on the\n button itself: Button.vue's `.editor-btn` base rule resets `position` via\n `all: unset` (and, in the webcomponent build, gets re-injected a second\n time after everything else to reach teleported popovers/dialogs — see\n packages/webcomponent/src/index.ts), so any positioning put directly on\n the button is one rebuild away from being silently overridden again. */\n.resume-scroll-anchor[data-v-66b767d7] {\n position: sticky;\n bottom: var(--spacing-lg);\n z-index: var(--z-sticky);\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.resume-scroll-btn[data-v-66b767d7] {\n /* No backdrop-filter: this button is sticky inside the tall scroll\n container, where a backdrop-filter makes WebRender allocate a render\n target spanning the whole scroll height — multi-GB on a long transcript. */\n background: white !important;\n border: 1px solid var(--color-border);\n box-shadow: var(--shadow-sm);\n}\n\n/* Transition */\n.fade-slide-enter-active[data-v-66b767d7],\n.fade-slide-leave-active[data-v-66b767d7] {\n transition:\n opacity 200ms ease,\n translate 200ms ease;\n}\n.fade-slide-enter-from[data-v-66b767d7],\n.fade-slide-leave-to[data-v-66b767d7] {\n opacity: 0;\n translate: 0 8px;\n}\n@media (prefers-reduced-motion: reduce) {\n.fade-slide-enter-active[data-v-66b767d7],\n .fade-slide-leave-active[data-v-66b767d7] {\n transition: none;\n}\n}\n@media (max-width: 767px) {\n.turns-container[data-v-66b767d7] {\n padding: var(--spacing-md);\n}\n}\n";
23972
+ const TranscriptionPanel = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["styles", [_style_0$k]], ["__scopeId", "data-v-66b767d7"]]);
23973
+ const _hoisted_1$j = { class: "verbatim-panel" };
23974
+ const _hoisted_2$g = { class: "verbatim-panel__content" };
23966
23975
  const _hoisted_3$c = { class: "verbatim-panel__header" };
23967
23976
  const _hoisted_4$7 = { class: "verbatim-panel__doc-title" };
23968
- const _hoisted_5$6 = { class: "verbatim-panel__turns" };
23977
+ const _hoisted_5$7 = { class: "verbatim-panel__turns" };
23969
23978
  const _hoisted_6$6 = { class: "verbatim-panel__turn-header" };
23970
23979
  const _hoisted_7$3 = { class: "verbatim-panel__speaker-name" };
23971
23980
  const _hoisted_8$1 = {
@@ -23977,7 +23986,7 @@ ${text2}` : text2;
23977
23986
  class: "verbatim-panel__meta"
23978
23987
  };
23979
23988
  const _hoisted_10$1 = { class: "verbatim-panel__text" };
23980
- const _sfc_main$l = /* @__PURE__ */ defineComponent({
23989
+ const _sfc_main$n = /* @__PURE__ */ defineComponent({
23981
23990
  __name: "VerbatimPanel",
23982
23991
  setup(__props) {
23983
23992
  const core = useCore();
@@ -24023,20 +24032,20 @@ ${text2}` : text2;
24023
24032
  core.emit("verbatim:export", { format: format2 });
24024
24033
  }
24025
24034
  return (_ctx, _cache) => {
24026
- return openBlock(), createElementBlock("section", _hoisted_1$i, [
24035
+ return openBlock(), createElementBlock("section", _hoisted_1$j, [
24027
24036
  createVNode(unref(DocumentArticle), null, {
24028
24037
  "toolbar-right": withCtx(() => [
24029
- createVNode(unref(_sfc_main$y), {
24038
+ createVNode(unref(_sfc_main$A), {
24030
24039
  formats: unref(core).verbatimFormats.value,
24031
24040
  onSelect: onExport
24032
24041
  }, null, 8, ["formats"])
24033
24042
  ]),
24034
24043
  default: withCtx(() => [
24035
- createBaseVNode("article", _hoisted_2$f, [
24044
+ createBaseVNode("article", _hoisted_2$g, [
24036
24045
  createBaseVNode("header", _hoisted_3$c, [
24037
24046
  createBaseVNode("h1", _hoisted_4$7, toDisplayString(title.value), 1)
24038
24047
  ]),
24039
- createBaseVNode("ul", _hoisted_5$6, [
24048
+ createBaseVNode("ul", _hoisted_5$7, [
24040
24049
  (openBlock(true), createElementBlock(Fragment, null, renderList(turns.value, (turn) => {
24041
24050
  return openBlock(), createElementBlock("li", {
24042
24051
  key: turn.id,
@@ -24071,9 +24080,9 @@ ${text2}` : text2;
24071
24080
  };
24072
24081
  }
24073
24082
  });
24074
- const _style_0$i = "\n.verbatim-panel[data-v-7a077f5a] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n}\n.verbatim-panel__content[data-v-7a077f5a] {\n padding: 4rem clamp(1.5rem, 6rem, 8%);\n}\n.verbatim-panel__header[data-v-7a077f5a] {\n margin-bottom: var(--spacing-lg);\n padding-bottom: var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n}\n.verbatim-panel__doc-title[data-v-7a077f5a] {\n font-size: var(--font-size-xl);\n font-weight: 700;\n margin: 0;\n color: var(--color-text-primary);\n}\n.verbatim-panel__turns[data-v-7a077f5a] {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-lg);\n}\n.verbatim-panel__turn[data-v-7a077f5a] {\n display: block;\n}\n.verbatim-panel__turn-header[data-v-7a077f5a] {\n margin: 0 0 var(--spacing-xs);\n font-size: var(--font-size-base);\n line-height: 1.4;\n}\n.verbatim-panel__speaker-name[data-v-7a077f5a] {\n font-weight: 700;\n color: var(--color-text-primary);\n}\n.verbatim-panel__meta[data-v-7a077f5a] {\n color: var(--color-text-muted);\n font-weight: 400;\n}\n.verbatim-panel__sep[data-v-7a077f5a] {\n margin: 0 0.35em;\n}\n.verbatim-panel__text[data-v-7a077f5a] {\n margin: 0;\n font-size: var(--font-size-base);\n line-height: 1.6;\n color: var(--color-text-primary);\n}\n\n";
24075
- const VerbatimPanel = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["styles", [_style_0$i]], ["__scopeId", "data-v-7a077f5a"]]);
24076
- const _sfc_main$k = /* @__PURE__ */ defineComponent({
24083
+ const _style_0$j = "\n.verbatim-panel[data-v-7a077f5a] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n}\n.verbatim-panel__content[data-v-7a077f5a] {\n padding: 4rem clamp(1.5rem, 6rem, 8%);\n}\n.verbatim-panel__header[data-v-7a077f5a] {\n margin-bottom: var(--spacing-lg);\n padding-bottom: var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n}\n.verbatim-panel__doc-title[data-v-7a077f5a] {\n font-size: var(--font-size-xl);\n font-weight: 700;\n margin: 0;\n color: var(--color-text-primary);\n}\n.verbatim-panel__turns[data-v-7a077f5a] {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-lg);\n}\n.verbatim-panel__turn[data-v-7a077f5a] {\n display: block;\n}\n.verbatim-panel__turn-header[data-v-7a077f5a] {\n margin: 0 0 var(--spacing-xs);\n font-size: var(--font-size-base);\n line-height: 1.4;\n}\n.verbatim-panel__speaker-name[data-v-7a077f5a] {\n font-weight: 700;\n color: var(--color-text-primary);\n}\n.verbatim-panel__meta[data-v-7a077f5a] {\n color: var(--color-text-muted);\n font-weight: 400;\n}\n.verbatim-panel__sep[data-v-7a077f5a] {\n margin: 0 0.35em;\n}\n.verbatim-panel__text[data-v-7a077f5a] {\n margin: 0;\n font-size: var(--font-size-base);\n line-height: 1.6;\n color: var(--color-text-primary);\n}\n\n";
24084
+ const VerbatimPanel = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["styles", [_style_0$j]], ["__scopeId", "data-v-7a077f5a"]]);
24085
+ const _sfc_main$m = /* @__PURE__ */ defineComponent({
24077
24086
  __name: "ChannelSelector",
24078
24087
  props: {
24079
24088
  channels: { type: Array },
@@ -24099,7 +24108,7 @@ ${text2}` : text2;
24099
24108
  };
24100
24109
  }
24101
24110
  });
24102
- const _sfc_main$j = /* @__PURE__ */ defineComponent({
24111
+ const _sfc_main$l = /* @__PURE__ */ defineComponent({
24103
24112
  __name: "TranslationSelector",
24104
24113
  props: {
24105
24114
  translations: { type: Array },
@@ -24131,10 +24140,10 @@ ${text2}` : text2;
24131
24140
  };
24132
24141
  }
24133
24142
  });
24134
- const _hoisted_1$h = { class: "merge-dialog-title" };
24135
- const _hoisted_2$e = { class: "merge-dialog-description" };
24143
+ const _hoisted_1$i = { class: "merge-dialog-title" };
24144
+ const _hoisted_2$f = { class: "merge-dialog-description" };
24136
24145
  const _hoisted_3$b = { class: "merge-dialog-actions" };
24137
- const _sfc_main$i = /* @__PURE__ */ defineComponent({
24146
+ const _sfc_main$k = /* @__PURE__ */ defineComponent({
24138
24147
  __name: "MergeDialog",
24139
24148
  props: {
24140
24149
  open: { type: Boolean },
@@ -24202,8 +24211,8 @@ ${text2}` : text2;
24202
24211
  class: "merge-dialog-form",
24203
24212
  onSubmit: withModifiers(onConfirm, ["prevent"])
24204
24213
  }, [
24205
- createBaseVNode("h2", _hoisted_1$h, toDisplayString(unref(t2)("mergeDialog.title")), 1),
24206
- createBaseVNode("p", _hoisted_2$e, [
24214
+ createBaseVNode("h2", _hoisted_1$i, toDisplayString(unref(t2)("mergeDialog.title")), 1),
24215
+ createBaseVNode("p", _hoisted_2$f, [
24207
24216
  createBaseVNode("strong", null, toDisplayString(fromSpeaker.value.name), 1),
24208
24217
  createTextVNode(" · " + toDisplayString(affectedCount.value) + " " + toDisplayString(unref(t2)("mergeDialog.turnsAffected")), 1)
24209
24218
  ]),
@@ -24241,10 +24250,10 @@ ${text2}` : text2;
24241
24250
  };
24242
24251
  }
24243
24252
  });
24244
- const _style_0$h = "\n.merge-dialog[data-v-e658bcd0] {\n margin: auto;\n max-width: 420px;\n width: 90vw;\n padding: var(--spacing-lg);\n background-color: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n color: var(--color-text-primary);\n box-shadow: 0 16px 48px color-mix(in srgb, var(--color-text-primary) 20%, transparent);\n}\n.merge-dialog[data-v-e658bcd0]::backdrop {\n /* No backdrop-filter: a full-viewport backdrop blur is a large WebRender\n render target; the dim background alone is enough. */\n background-color: color-mix(in srgb, var(--color-text-primary) 35%, transparent);\n}\n.merge-dialog-form[data-v-e658bcd0] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-md);\n}\n.merge-dialog-title[data-v-e658bcd0] {\n margin: 0;\n font-size: var(--font-size-lg);\n font-weight: 600;\n}\n.merge-dialog-description[data-v-e658bcd0] {\n margin: 0;\n font-size: var(--font-size-sm);\n color: var(--color-text-secondary);\n}\n.merge-dialog-actions[data-v-e658bcd0] {\n display: flex;\n justify-content: flex-end;\n gap: var(--spacing-sm);\n}\n";
24245
- const MergeDialog = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["styles", [_style_0$h]], ["__scopeId", "data-v-e658bcd0"]]);
24246
- const _hoisted_1$g = { class: "speaker-sidebar" };
24247
- const _hoisted_2$d = {
24253
+ const _style_0$i = "\n.merge-dialog[data-v-e658bcd0] {\n margin: auto;\n max-width: 420px;\n width: 90vw;\n padding: var(--spacing-lg);\n background-color: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n color: var(--color-text-primary);\n box-shadow: 0 16px 48px color-mix(in srgb, var(--color-text-primary) 20%, transparent);\n}\n.merge-dialog[data-v-e658bcd0]::backdrop {\n /* No backdrop-filter: a full-viewport backdrop blur is a large WebRender\n render target; the dim background alone is enough. */\n background-color: color-mix(in srgb, var(--color-text-primary) 35%, transparent);\n}\n.merge-dialog-form[data-v-e658bcd0] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-md);\n}\n.merge-dialog-title[data-v-e658bcd0] {\n margin: 0;\n font-size: var(--font-size-lg);\n font-weight: 600;\n}\n.merge-dialog-description[data-v-e658bcd0] {\n margin: 0;\n font-size: var(--font-size-sm);\n color: var(--color-text-secondary);\n}\n.merge-dialog-actions[data-v-e658bcd0] {\n display: flex;\n justify-content: flex-end;\n gap: var(--spacing-sm);\n}\n";
24254
+ const MergeDialog = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["styles", [_style_0$i]], ["__scopeId", "data-v-e658bcd0"]]);
24255
+ const _hoisted_1$h = { class: "speaker-sidebar" };
24256
+ const _hoisted_2$e = {
24248
24257
  key: 0,
24249
24258
  class: "sidebar-section sidebar-section--selector"
24250
24259
  };
@@ -24253,7 +24262,7 @@ ${text2}` : text2;
24253
24262
  key: 1,
24254
24263
  class: "sidebar-section sidebar-section--selector"
24255
24264
  };
24256
- const _hoisted_5$5 = { class: "sidebar-title" };
24265
+ const _hoisted_5$6 = { class: "sidebar-title" };
24257
24266
  const _hoisted_6$5 = {
24258
24267
  key: 2,
24259
24268
  class: "sidebar-section"
@@ -24296,7 +24305,7 @@ ${text2}` : text2;
24296
24305
  };
24297
24306
  const _hoisted_28 = { class: "sidebar-title" };
24298
24307
  const _hoisted_29 = { class: "speaker-list" };
24299
- const _sfc_main$h = /* @__PURE__ */ defineComponent({
24308
+ const _sfc_main$j = /* @__PURE__ */ defineComponent({
24300
24309
  __name: "SpeakerSidebar",
24301
24310
  props: {
24302
24311
  speakers: { type: Array },
@@ -24381,18 +24390,18 @@ ${text2}` : text2;
24381
24390
  core.emit("llmService:selectVersion", { id: service.id, versionNumber });
24382
24391
  }
24383
24392
  return (_ctx, _cache) => {
24384
- return openBlock(), createElementBlock("aside", _hoisted_1$g, [
24385
- __props.channels.length > 1 ? (openBlock(), createElementBlock("section", _hoisted_2$d, [
24393
+ return openBlock(), createElementBlock("aside", _hoisted_1$h, [
24394
+ __props.channels.length > 1 ? (openBlock(), createElementBlock("section", _hoisted_2$e, [
24386
24395
  createBaseVNode("h2", _hoisted_3$a, toDisplayString(unref(t2)("sidebar.channel")), 1),
24387
- createVNode(_sfc_main$k, {
24396
+ createVNode(_sfc_main$m, {
24388
24397
  channels: __props.channels,
24389
24398
  "selected-channel-id": __props.selectedChannelId,
24390
24399
  "onUpdate:selectedChannelId": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:selectedChannelId", $event))
24391
24400
  }, null, 8, ["channels", "selected-channel-id"])
24392
24401
  ])) : createCommentVNode("", true),
24393
24402
  __props.translations.length > 1 ? (openBlock(), createElementBlock("section", _hoisted_4$6, [
24394
- createBaseVNode("h2", _hoisted_5$5, toDisplayString(unref(t2)("sidebar.translation")), 1),
24395
- createVNode(_sfc_main$j, {
24403
+ createBaseVNode("h2", _hoisted_5$6, toDisplayString(unref(t2)("sidebar.translation")), 1),
24404
+ createVNode(_sfc_main$l, {
24396
24405
  translations: __props.translations,
24397
24406
  "selected-translation-id": __props.selectedTranslationId,
24398
24407
  "onUpdate:selectedTranslationId": _cache[1] || (_cache[1] = ($event) => _ctx.$emit("update:selectedTranslationId", $event))
@@ -24537,7 +24546,7 @@ ${text2}` : text2;
24537
24546
  "aria-label": unref(t2)("sidebar.renameSpeaker"),
24538
24547
  onCommit: ($event) => onRename(speaker.id, $event)
24539
24548
  }, null, 8, ["model-value", "disabled", "aria-label", "onCommit"]),
24540
- canEditSpeakers.value && __props.speakers.length > 1 ? (openBlock(), createBlock(unref(_sfc_main$x), {
24549
+ canEditSpeakers.value && __props.speakers.length > 1 ? (openBlock(), createBlock(unref(_sfc_main$z), {
24541
24550
  key: 0,
24542
24551
  "speaker-name": speaker.name,
24543
24552
  onMerge: ($event) => onOpenMerge(speaker.id)
@@ -24556,9 +24565,9 @@ ${text2}` : text2;
24556
24565
  };
24557
24566
  }
24558
24567
  });
24559
- const _style_0$g = '\n.speaker-sidebar[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-lg);\n padding: var(--spacing-lg);\n border-left: 1px solid var(--color-border);\n background-color: var(--color-surface);\n overflow-y: auto;\n}\n.sidebar-section[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm);\n}\n.sidebar-title[data-v-3b1e278f] {\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--color-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n.speaker-list[data-v-3b1e278f] {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n}\n.speaker-item[data-v-3b1e278f] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm);\n border-radius: var(--radius-md);\n transition: background-color var(--transition-duration);\n}\n.speaker-item[data-v-3b1e278f]:hover {\n background-color: var(--color-surface-hover);\n}\n.speaker-name[data-v-3b1e278f] {\n flex: 1;\n font-size: var(--font-size-sm);\n font-weight: 500;\n color: var(--color-text-primary);\n}\n.subtitle-toggle[data-v-3b1e278f] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-sm);\n border-radius: var(--radius-md);\n}\n.subtitle-toggle-label[data-v-3b1e278f] {\n font-size: var(--font-size-sm);\n color: var(--color-text-primary);\n}\n.voice-playback-hint[data-v-3b1e278f] {\n padding: 0 var(--spacing-sm);\n font-size: var(--font-size-xs);\n color: var(--color-text-muted);\n}\n.voice-playback-hint--warning[data-v-3b1e278f] {\n color: var(--color-danger);\n}\n.subtitle-slider[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n padding: var(--spacing-sm);\n}\n.subtitle-slider-label[data-v-3b1e278f] {\n display: flex;\n justify-content: space-between;\n font-size: var(--font-size-sm);\n color: var(--color-text-primary);\n}\n.subtitle-slider-value[data-v-3b1e278f] {\n color: var(--color-text-muted);\n font-variant-numeric: tabular-nums;\n}\n.subtitle-slider input[type="range"][data-v-3b1e278f] {\n width: 100%;\n accent-color: var(--color-primary);\n}\n.subtitle-slider input[type="range"][data-v-3b1e278f]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* ── History (LLM generations + versions) ──────────────────────────── */\n.sidebar-section--busy[data-v-3b1e278f] {\n opacity: 0.6;\n pointer-events: none;\n}\n.history-list[data-v-3b1e278f] {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n margin: 0;\n padding: 0;\n}\n.history-generation[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n}\n.history-generation__status--completed[data-v-3b1e278f] {\n color: var(--color-success, #2e7d32);\n}\n.history-generation__status--error[data-v-3b1e278f] {\n color: var(--color-danger, #d33);\n}\n.history-generation__status--processing[data-v-3b1e278f],\n.history-generation__status--queued[data-v-3b1e278f] {\n color: var(--color-primary);\n}\n.history-version-list[data-v-3b1e278f] {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin: var(--spacing-xs) 0 0 var(--spacing-md);\n padding: 0;\n border-left: 1px solid var(--color-border);\n}\n\n/* Nudge nested version rows off the connecting border line. */\n.history-version-list[data-v-3b1e278f] .selectable-list-item {\n margin-left: var(--spacing-xs);\n}\n@media (max-width: 767px) {\n.speaker-sidebar[data-v-3b1e278f] {\n border-left: none;\n}\n.sidebar-section--selector[data-v-3b1e278f] {\n display: none;\n}\n}\n';
24560
- const SpeakerSidebar = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["styles", [_style_0$g]], ["__scopeId", "data-v-3b1e278f"]]);
24561
- const _sfc_main$g = /* @__PURE__ */ defineComponent({
24568
+ const _style_0$h = '\n.speaker-sidebar[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-lg);\n padding: var(--spacing-lg);\n border-left: 1px solid var(--color-border);\n background-color: var(--color-surface);\n overflow-y: auto;\n}\n.sidebar-section[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm);\n}\n.sidebar-title[data-v-3b1e278f] {\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--color-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n.speaker-list[data-v-3b1e278f] {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n}\n.speaker-item[data-v-3b1e278f] {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm);\n border-radius: var(--radius-md);\n transition: background-color var(--transition-duration);\n}\n.speaker-item[data-v-3b1e278f]:hover {\n background-color: var(--color-surface-hover);\n}\n.speaker-name[data-v-3b1e278f] {\n flex: 1;\n font-size: var(--font-size-sm);\n font-weight: 500;\n color: var(--color-text-primary);\n}\n.subtitle-toggle[data-v-3b1e278f] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-sm);\n border-radius: var(--radius-md);\n}\n.subtitle-toggle-label[data-v-3b1e278f] {\n font-size: var(--font-size-sm);\n color: var(--color-text-primary);\n}\n.voice-playback-hint[data-v-3b1e278f] {\n padding: 0 var(--spacing-sm);\n font-size: var(--font-size-xs);\n color: var(--color-text-muted);\n}\n.voice-playback-hint--warning[data-v-3b1e278f] {\n color: var(--color-danger);\n}\n.subtitle-slider[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n padding: var(--spacing-sm);\n}\n.subtitle-slider-label[data-v-3b1e278f] {\n display: flex;\n justify-content: space-between;\n font-size: var(--font-size-sm);\n color: var(--color-text-primary);\n}\n.subtitle-slider-value[data-v-3b1e278f] {\n color: var(--color-text-muted);\n font-variant-numeric: tabular-nums;\n}\n.subtitle-slider input[type="range"][data-v-3b1e278f] {\n width: 100%;\n accent-color: var(--color-primary);\n}\n.subtitle-slider input[type="range"][data-v-3b1e278f]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* ── History (LLM generations + versions) ──────────────────────────── */\n.sidebar-section--busy[data-v-3b1e278f] {\n opacity: 0.6;\n pointer-events: none;\n}\n.history-list[data-v-3b1e278f] {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n margin: 0;\n padding: 0;\n}\n.history-generation[data-v-3b1e278f] {\n display: flex;\n flex-direction: column;\n}\n.history-generation__status--completed[data-v-3b1e278f] {\n color: var(--color-success, #2e7d32);\n}\n.history-generation__status--error[data-v-3b1e278f] {\n color: var(--color-danger, #d33);\n}\n.history-generation__status--processing[data-v-3b1e278f],\n.history-generation__status--queued[data-v-3b1e278f] {\n color: var(--color-primary);\n}\n.history-version-list[data-v-3b1e278f] {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin: var(--spacing-xs) 0 0 var(--spacing-md);\n padding: 0;\n border-left: 1px solid var(--color-border);\n}\n\n/* Nudge nested version rows off the connecting border line. */\n.history-version-list[data-v-3b1e278f] .selectable-list-item {\n margin-left: var(--spacing-xs);\n}\n@media (max-width: 767px) {\n.speaker-sidebar[data-v-3b1e278f] {\n border-left: none;\n}\n.sidebar-section--selector[data-v-3b1e278f] {\n display: none;\n}\n}\n';
24569
+ const SpeakerSidebar = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["styles", [_style_0$h]], ["__scopeId", "data-v-3b1e278f"]]);
24570
+ const _sfc_main$i = /* @__PURE__ */ defineComponent({
24562
24571
  __name: "SidebarDrawer",
24563
24572
  props: {
24564
24573
  "open": { type: Boolean, ...{ required: true } },
@@ -24607,10 +24616,10 @@ ${text2}` : text2;
24607
24616
  };
24608
24617
  }
24609
24618
  });
24610
- const _hoisted_1$f = ["aria-label"];
24611
- const _hoisted_2$c = { class: "selection-count" };
24619
+ const _hoisted_1$g = ["aria-label"];
24620
+ const _hoisted_2$d = { class: "selection-count" };
24612
24621
  const _hoisted_3$9 = { class: "selection-actions" };
24613
- const _sfc_main$f = /* @__PURE__ */ defineComponent({
24622
+ const _sfc_main$h = /* @__PURE__ */ defineComponent({
24614
24623
  __name: "SelectionActionBar",
24615
24624
  setup(__props) {
24616
24625
  const selection = useTurnSelection();
@@ -24622,7 +24631,7 @@ ${text2}` : text2;
24622
24631
  role: "toolbar",
24623
24632
  "aria-label": unref(t2)("selection.count")
24624
24633
  }, [
24625
- createBaseVNode("span", _hoisted_2$c, toDisplayString(unref(selection).count.value) + " " + toDisplayString(unref(t2)("selection.count")), 1),
24634
+ createBaseVNode("span", _hoisted_2$d, toDisplayString(unref(selection).count.value) + " " + toDisplayString(unref(t2)("selection.count")), 1),
24626
24635
  createBaseVNode("div", _hoisted_3$9, [
24627
24636
  createVNode(unref(CopyButton), {
24628
24637
  icon: "clipboard-type",
@@ -24654,18 +24663,18 @@ ${text2}` : text2;
24654
24663
  _: 1
24655
24664
  })
24656
24665
  ])
24657
- ], 8, _hoisted_1$f)) : createCommentVNode("", true);
24666
+ ], 8, _hoisted_1$g)) : createCommentVNode("", true);
24658
24667
  };
24659
24668
  }
24660
24669
  });
24661
- const _style_0$f = "\n.selection-bar[data-v-9bad1410] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-xs) var(--spacing-lg);\n /* No backdrop-filter: it forces a WebRender backdrop render target sized to\n the content behind, a heavy GPU-memory cost on long transcripts. The\n semi-opaque glass background stays legible without the blur. */\n background: var(--glass-background);\n border-bottom: 1px solid var(--color-border);\n animation: bar-slide-down-9bad1410 var(--transition-duration) ease;\n}\n.selection-count[data-v-9bad1410] {\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--color-primary);\n}\n.selection-actions[data-v-9bad1410] {\n display: flex;\n gap: var(--spacing-xs);\n}\n@keyframes bar-slide-down-9bad1410 {\nfrom {\n opacity: 0;\n translate: 0 -4px;\n}\nto {\n opacity: 1;\n translate: 0 0;\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.selection-bar[data-v-9bad1410] {\n animation: none;\n}\n}\n@media (max-width: 767px) {\n.selection-bar[data-v-9bad1410] {\n padding: var(--spacing-xs) var(--spacing-md);\n flex-wrap: wrap;\n gap: var(--spacing-xs);\n}\n}\n";
24662
- const SelectionActionBar = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["styles", [_style_0$f]], ["__scopeId", "data-v-9bad1410"]]);
24663
- const _hoisted_1$e = { class: "editor-layout" };
24664
- const _hoisted_2$b = {
24670
+ const _style_0$g = "\n.selection-bar[data-v-9bad1410] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-xs) var(--spacing-lg);\n /* No backdrop-filter: it forces a WebRender backdrop render target sized to\n the content behind, a heavy GPU-memory cost on long transcripts. The\n semi-opaque glass background stays legible without the blur. */\n background: var(--glass-background);\n border-bottom: 1px solid var(--color-border);\n animation: bar-slide-down-9bad1410 var(--transition-duration) ease;\n}\n.selection-count[data-v-9bad1410] {\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--color-primary);\n}\n.selection-actions[data-v-9bad1410] {\n display: flex;\n gap: var(--spacing-xs);\n}\n@keyframes bar-slide-down-9bad1410 {\nfrom {\n opacity: 0;\n translate: 0 -4px;\n}\nto {\n opacity: 1;\n translate: 0 0;\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.selection-bar[data-v-9bad1410] {\n animation: none;\n}\n}\n@media (max-width: 767px) {\n.selection-bar[data-v-9bad1410] {\n padding: var(--spacing-xs) var(--spacing-md);\n flex-wrap: wrap;\n gap: var(--spacing-xs);\n}\n}\n";
24671
+ const SelectionActionBar = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["styles", [_style_0$g]], ["__scopeId", "data-v-9bad1410"]]);
24672
+ const _hoisted_1$f = { class: "editor-layout" };
24673
+ const _hoisted_2$c = {
24665
24674
  key: 6,
24666
24675
  class: "mobile-selectors"
24667
24676
  };
24668
- const _sfc_main$e = /* @__PURE__ */ defineComponent({
24677
+ const _sfc_main$g = /* @__PURE__ */ defineComponent({
24669
24678
  __name: "Layout",
24670
24679
  props: {
24671
24680
  showHeader: { type: Boolean, default: true },
@@ -24730,7 +24739,9 @@ ${text2}` : text2;
24730
24739
  () => props.showVerbatim,
24731
24740
  (canShow) => {
24732
24741
  if (canShow) return;
24733
- const withoutVerbatim = shownPanels.value.filter((id) => id !== VERBATIM_TAB);
24742
+ const withoutVerbatim = shownPanels.value.filter(
24743
+ (id) => id !== VERBATIM_TAB
24744
+ );
24734
24745
  shownPanels.value = withoutVerbatim.length > 0 ? withoutVerbatim : [TRANSCRIPTION_TAB];
24735
24746
  }
24736
24747
  );
@@ -24755,7 +24766,7 @@ ${text2}` : text2;
24755
24766
  core.activeChannel.value?.setActiveTranslation(translationId);
24756
24767
  }
24757
24768
  return (_ctx, _cache) => {
24758
- return openBlock(), createElementBlock("div", _hoisted_1$e, [
24769
+ return openBlock(), createElementBlock("div", _hoisted_1$f, [
24759
24770
  props.showHeader ? (openBlock(), createBlock(Header, {
24760
24771
  key: 0,
24761
24772
  title: unref(core).title.value,
@@ -24771,7 +24782,7 @@ ${text2}` : text2;
24771
24782
  onUndo: _cache[2] || (_cache[2] = ($event) => unref(core).transcriptionEditor?.undo()),
24772
24783
  onRedo: _cache[3] || (_cache[3] = ($event) => unref(core).transcriptionEditor?.redo())
24773
24784
  }, null, 8, ["title", "date", "duration", "speaker-count", "is-mobile", "can-ask", "can-undo", "can-redo"])) : createCommentVNode("", true),
24774
- createVNode(_sfc_main$t, {
24785
+ createVNode(_sfc_main$v, {
24775
24786
  "model-value": activeTab.value,
24776
24787
  "show-verbatim": props.showVerbatim,
24777
24788
  "onUpdate:modelValue": _cache[4] || (_cache[4] = (tab) => shownPanels.value = [tab])
@@ -24811,7 +24822,7 @@ ${text2}` : text2;
24811
24822
  "onUpdate:selectedChannelId": onChannelChange,
24812
24823
  "onUpdate:selectedTranslationId": onTranslationChange
24813
24824
  }, null, 8, ["speakers", "channels", "selected-channel-id", "translations", "selected-translation-id", "show-speakers"])) : createCommentVNode("", true),
24814
- unref(isMobile) && panels.value.length === 1 ? (openBlock(), createBlock(_sfc_main$g, {
24825
+ unref(isMobile) && panels.value.length === 1 ? (openBlock(), createBlock(_sfc_main$i, {
24815
24826
  key: 1,
24816
24827
  open: isSidebarOpen.value,
24817
24828
  "onUpdate:open": _cache[6] || (_cache[6] = ($event) => isSidebarOpen.value = $event)
@@ -24840,14 +24851,14 @@ ${text2}` : text2;
24840
24851
  unref(core).subtitle?.isVisible.value && !unref(isMobile) && !unref(core).subtitle.isFullscreen.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(core).components.subtitleBanner), { key: 3 })) : createCommentVNode("", true),
24841
24852
  unref(core).subtitle?.isFullscreen.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(core).components.subtitleFullscreen), { key: 4 })) : createCommentVNode("", true),
24842
24853
  unref(core).chat ? (openBlock(), createBlock(resolveDynamicComponent(unref(core).components.chatDrawer), { key: 5 })) : createCommentVNode("", true),
24843
- unref(isMobile) && (channels.value.length > 1 || translations.value.length > 1) ? (openBlock(), createElementBlock("div", _hoisted_2$b, [
24844
- channels.value.length > 1 ? (openBlock(), createBlock(_sfc_main$k, {
24854
+ unref(isMobile) && (channels.value.length > 1 || translations.value.length > 1) ? (openBlock(), createElementBlock("div", _hoisted_2$c, [
24855
+ channels.value.length > 1 ? (openBlock(), createBlock(_sfc_main$m, {
24845
24856
  key: 0,
24846
24857
  channels: channels.value,
24847
24858
  "selected-channel-id": unref(core).activeChannelId.value,
24848
24859
  "onUpdate:selectedChannelId": onChannelChange
24849
24860
  }, null, 8, ["channels", "selected-channel-id"])) : createCommentVNode("", true),
24850
- translations.value.length > 1 ? (openBlock(), createBlock(_sfc_main$j, {
24861
+ translations.value.length > 1 ? (openBlock(), createBlock(_sfc_main$l, {
24851
24862
  key: 1,
24852
24863
  translations: translations.value,
24853
24864
  "selected-translation-id": activeTranslationId.value,
@@ -24858,41 +24869,41 @@ ${text2}` : text2;
24858
24869
  };
24859
24870
  }
24860
24871
  });
24861
- const _style_0$e = "\n.editor-layout[data-v-972b2fff] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n background-color: var(--color-background);\n}\n.editor-body[data-v-972b2fff] {\n display: grid;\n grid-template-columns: 1fr var(--sidebar-width);\n flex: 1;\n min-height: 0;\n}\n\n/* Split mode: two panels already share the body between them, no room (or\n need) for the speaker sidebar too — see Layout's panels/isSplit state. */\n.editor-body--no-sidebar[data-v-972b2fff] {\n grid-template-columns: 1fr;\n}\n.editor-body__panels[data-v-972b2fff] {\n display: flex;\n min-width: 0;\n min-height: 0;\n}\n.editor-body__panels[data-v-972b2fff] > * {\n flex: 1;\n min-width: 0;\n}\n.editor-body__panels--split[data-v-972b2fff] > * + * {\n border-left: 1px solid var(--color-border);\n}\n.mobile-selectors[data-v-972b2fff] {\n display: flex;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n border-top: 1px solid var(--color-border);\n background-color: var(--color-surface);\n flex-shrink: 0;\n box-shadow: var(--shadow-md);\n align-items: end;\n}\n.mobile-selectors[data-v-972b2fff] > * {\n flex: 1;\n min-width: 0;\n}\n@media (max-width: 767px) {\n.editor-body[data-v-972b2fff] {\n grid-template-columns: 1fr;\n}\n}\n";
24862
- const Layout = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["styles", [_style_0$e]], ["__scopeId", "data-v-972b2fff"]]);
24863
- const _hoisted_1$d = {
24872
+ const _style_0$f = "\n.editor-layout[data-v-c7029599] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n background-color: var(--color-background);\n}\n.editor-body[data-v-c7029599] {\n display: grid;\n grid-template-columns: 1fr var(--sidebar-width);\n flex: 1;\n min-height: 0;\n}\n\n/* Split mode: two panels already share the body between them, no room (or\n need) for the speaker sidebar too — see Layout's panels/isSplit state. */\n.editor-body--no-sidebar[data-v-c7029599] {\n grid-template-columns: 1fr;\n}\n.editor-body__panels[data-v-c7029599] {\n display: flex;\n min-width: 0;\n min-height: 0;\n}\n.editor-body__panels[data-v-c7029599] > * {\n flex: 1;\n min-width: 0;\n}\n.editor-body__panels--split[data-v-c7029599] > * + * {\n border-left: 1px solid var(--color-border);\n}\n.mobile-selectors[data-v-c7029599] {\n display: flex;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n border-top: 1px solid var(--color-border);\n background-color: var(--color-surface);\n flex-shrink: 0;\n box-shadow: var(--shadow-md);\n align-items: end;\n}\n.mobile-selectors[data-v-c7029599] > * {\n flex: 1;\n min-width: 0;\n}\n@media (max-width: 767px) {\n.editor-body[data-v-c7029599] {\n grid-template-columns: 1fr;\n}\n}\n";
24873
+ const Layout = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["styles", [_style_0$f]], ["__scopeId", "data-v-c7029599"]]);
24874
+ const _hoisted_1$e = {
24864
24875
  class: "editor-loading",
24865
24876
  role: "status",
24866
24877
  "aria-live": "polite"
24867
24878
  };
24868
- const _hoisted_2$a = { class: "editor-loading__label" };
24869
- const _sfc_main$d = /* @__PURE__ */ defineComponent({
24879
+ const _hoisted_2$b = { class: "editor-loading__label" };
24880
+ const _sfc_main$f = /* @__PURE__ */ defineComponent({
24870
24881
  __name: "EditorLoadingOverlay",
24871
24882
  setup(__props) {
24872
24883
  const { t: t2 } = useI18n();
24873
24884
  return (_ctx, _cache) => {
24874
- return openBlock(), createElementBlock("div", _hoisted_1$d, [
24885
+ return openBlock(), createElementBlock("div", _hoisted_1$e, [
24875
24886
  _cache[0] || (_cache[0] = createBaseVNode("span", {
24876
24887
  class: "editor-loading__spinner",
24877
24888
  "aria-hidden": "true"
24878
24889
  }, null, -1)),
24879
- createBaseVNode("span", _hoisted_2$a, toDisplayString(unref(t2)("editor.loading")), 1)
24890
+ createBaseVNode("span", _hoisted_2$b, toDisplayString(unref(t2)("editor.loading")), 1)
24880
24891
  ]);
24881
24892
  };
24882
24893
  }
24883
24894
  });
24884
- const _style_0$d = "\n.editor-loading[data-v-f56c39db] {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-md);\n /* Opaque so the half-built layout never flashes behind while collab syncs.\n No backdrop-filter: it is banned in this package (WebRender GTT freeze). */\n background-color: var(--color-background);\n color: var(--color-text-secondary);\n font-family: var(--font-family);\n font-size: var(--font-size-sm);\n}\n.editor-loading__spinner[data-v-f56c39db] {\n width: 32px;\n height: 32px;\n border: 3px solid var(--color-border);\n border-top-color: var(--color-primary);\n border-radius: 50%;\n animation: editor-loading-spin-f56c39db 0.8s linear infinite;\n}\n@keyframes editor-loading-spin-f56c39db {\nto {\n transform: rotate(360deg);\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.editor-loading__spinner[data-v-f56c39db] {\n animation: none;\n}\n}\n";
24885
- const EditorLoadingOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["styles", [_style_0$d]], ["__scopeId", "data-v-f56c39db"]]);
24886
- const _hoisted_1$c = {
24895
+ const _style_0$e = "\n.editor-loading[data-v-f56c39db] {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-md);\n /* Opaque so the half-built layout never flashes behind while collab syncs.\n No backdrop-filter: it is banned in this package (WebRender GTT freeze). */\n background-color: var(--color-background);\n color: var(--color-text-secondary);\n font-family: var(--font-family);\n font-size: var(--font-size-sm);\n}\n.editor-loading__spinner[data-v-f56c39db] {\n width: 32px;\n height: 32px;\n border: 3px solid var(--color-border);\n border-top-color: var(--color-primary);\n border-radius: 50%;\n animation: editor-loading-spin-f56c39db 0.8s linear infinite;\n}\n@keyframes editor-loading-spin-f56c39db {\nto {\n transform: rotate(360deg);\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.editor-loading__spinner[data-v-f56c39db] {\n animation: none;\n}\n}\n";
24896
+ const EditorLoadingOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["styles", [_style_0$e]], ["__scopeId", "data-v-f56c39db"]]);
24897
+ const _hoisted_1$d = {
24887
24898
  class: "editor-error",
24888
24899
  role: "alert"
24889
24900
  };
24890
- const _hoisted_2$9 = { class: "editor-error__title" };
24901
+ const _hoisted_2$a = { class: "editor-error__title" };
24891
24902
  const _hoisted_3$8 = {
24892
24903
  key: 0,
24893
24904
  class: "editor-error__detail"
24894
24905
  };
24895
- const _sfc_main$c = /* @__PURE__ */ defineComponent({
24906
+ const _sfc_main$e = /* @__PURE__ */ defineComponent({
24896
24907
  __name: "EditorErrorOverlay",
24897
24908
  props: {
24898
24909
  message: { type: [String, null] }
@@ -24900,20 +24911,20 @@ ${text2}` : text2;
24900
24911
  setup(__props) {
24901
24912
  const { t: t2 } = useI18n();
24902
24913
  return (_ctx, _cache) => {
24903
- return openBlock(), createElementBlock("div", _hoisted_1$c, [
24914
+ return openBlock(), createElementBlock("div", _hoisted_1$d, [
24904
24915
  createVNode(unref(EditorIcon), {
24905
24916
  name: "warning",
24906
24917
  size: 40,
24907
24918
  class: "editor-error__icon"
24908
24919
  }),
24909
- createBaseVNode("p", _hoisted_2$9, toDisplayString(unref(t2)("editor.loadError")), 1),
24920
+ createBaseVNode("p", _hoisted_2$a, toDisplayString(unref(t2)("editor.loadError")), 1),
24910
24921
  __props.message ? (openBlock(), createElementBlock("p", _hoisted_3$8, toDisplayString(__props.message), 1)) : createCommentVNode("", true)
24911
24922
  ]);
24912
24923
  };
24913
24924
  }
24914
24925
  });
24915
- const _style_0$c = "\n.editor-error[data-v-eefc2d23] {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-xl);\n text-align: center;\n /* Opaque so the half-built layout never shows behind. No backdrop-filter:\n it is banned in this package (WebRender GTT freeze). */\n background-color: var(--color-background);\n font-family: var(--font-family);\n}\n.editor-error__icon[data-v-eefc2d23] {\n color: var(--color-danger);\n}\n.editor-error__title[data-v-eefc2d23] {\n margin: 0;\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.editor-error__detail[data-v-eefc2d23] {\n margin: 0;\n font-size: var(--font-size-sm);\n color: var(--color-text-muted);\n}\n";
24916
- const EditorErrorOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["styles", [_style_0$c]], ["__scopeId", "data-v-eefc2d23"]]);
24926
+ const _style_0$d = "\n.editor-error[data-v-eefc2d23] {\n position: absolute;\n inset: 0;\n z-index: 20;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-xl);\n text-align: center;\n /* Opaque so the half-built layout never shows behind. No backdrop-filter:\n it is banned in this package (WebRender GTT freeze). */\n background-color: var(--color-background);\n font-family: var(--font-family);\n}\n.editor-error__icon[data-v-eefc2d23] {\n color: var(--color-danger);\n}\n.editor-error__title[data-v-eefc2d23] {\n margin: 0;\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.editor-error__detail[data-v-eefc2d23] {\n margin: 0;\n font-size: var(--font-size-sm);\n color: var(--color-text-muted);\n}\n";
24927
+ const EditorErrorOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["styles", [_style_0$d]], ["__scopeId", "data-v-eefc2d23"]]);
24917
24928
  const READY_TIMEOUT_MS = 2e4;
24918
24929
  function useEditorReady(core) {
24919
24930
  const isLoading = /* @__PURE__ */ ref(true);
@@ -24947,8 +24958,8 @@ ${text2}` : text2;
24947
24958
  });
24948
24959
  return { isLoading, error };
24949
24960
  }
24950
- const _hoisted_1$b = { class: "transcript-ui-root" };
24951
- const _sfc_main$b = /* @__PURE__ */ defineComponent({
24961
+ const _hoisted_1$c = { class: "transcript-ui-root" };
24962
+ const _sfc_main$d = /* @__PURE__ */ defineComponent({
24952
24963
  __name: "TranscriptUI",
24953
24964
  props: {
24954
24965
  locale: { default: "fr", type: String },
@@ -24971,7 +24982,7 @@ ${text2}` : text2;
24971
24982
  onBeforeUnmount(() => core.destroy());
24972
24983
  __expose({ core });
24973
24984
  return (_ctx, _cache) => {
24974
- return openBlock(), createElementBlock("div", _hoisted_1$b, [
24985
+ return openBlock(), createElementBlock("div", _hoisted_1$c, [
24975
24986
  unref(core).channels.size ? (openBlock(), createBlock(Layout, {
24976
24987
  key: 0,
24977
24988
  "show-header": !props.noHeader,
@@ -24985,7 +24996,7 @@ ${text2}` : text2;
24985
24996
  };
24986
24997
  }
24987
24998
  });
24988
- const _style_0$b = `
24999
+ const _style_0$c = `
24989
25000
  /* NOT fonts.css: a @font-face declared inside a shadow root isn't reliably
24990
25001
  * applied by browsers (document.fonts never registers it) — dead weight in
24991
25002
  * the webcomponent bundle specifically, which always runs shadow-DOM'd. The
@@ -25312,7 +25323,7 @@ section.turn:has([data-state="open"]) {
25312
25323
  height: 100%;
25313
25324
  }
25314
25325
  `;
25315
- const TranscriptUI = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["styles", [_style_0$b]]]);
25326
+ const TranscriptUI = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["styles", [_style_0$c]]]);
25316
25327
  function mapApiTurns(apiTurns) {
25317
25328
  return apiTurns.map((t2) => {
25318
25329
  const words = wordsFromApi$2(t2.turn_id, t2.words);
@@ -25679,14 +25690,14 @@ section.turn:has([data-state="open"]) {
25679
25690
  }
25680
25691
  };
25681
25692
  }
25682
- const _hoisted_1$a = { class: "player-controls" };
25683
- const _hoisted_2$8 = { class: "controls-left" };
25693
+ const _hoisted_1$b = { class: "player-controls" };
25694
+ const _hoisted_2$9 = { class: "controls-left" };
25684
25695
  const _hoisted_3$7 = { class: "controls-time" };
25685
25696
  const _hoisted_4$5 = { class: "time-display" };
25686
- const _hoisted_5$4 = { class: "time-display" };
25697
+ const _hoisted_5$5 = { class: "time-display" };
25687
25698
  const _hoisted_6$4 = { class: "controls-right" };
25688
25699
  const _hoisted_7$1 = ["value", "aria-label", "disabled"];
25689
- const _sfc_main$a = /* @__PURE__ */ defineComponent({
25700
+ const _sfc_main$c = /* @__PURE__ */ defineComponent({
25690
25701
  __name: "AudioPlayerControls",
25691
25702
  props: {
25692
25703
  isPlaying: { type: Boolean },
@@ -25707,8 +25718,8 @@ section.turn:has([data-state="open"]) {
25707
25718
  emit2("update:volume", parseFloat(target.value));
25708
25719
  }
25709
25720
  return (_ctx, _cache) => {
25710
- return openBlock(), createElementBlock("div", _hoisted_1$a, [
25711
- createBaseVNode("div", _hoisted_2$8, [
25721
+ return openBlock(), createElementBlock("div", _hoisted_1$b, [
25722
+ createBaseVNode("div", _hoisted_2$9, [
25712
25723
  createVNode(unref(Button), {
25713
25724
  variant: "transparent",
25714
25725
  size: "md",
@@ -25758,7 +25769,7 @@ section.turn:has([data-state="open"]) {
25758
25769
  createBaseVNode("div", _hoisted_3$7, [
25759
25770
  createBaseVNode("time", _hoisted_4$5, toDisplayString(__props.currentTime), 1),
25760
25771
  _cache[7] || (_cache[7] = createBaseVNode("span", { class: "time-separator" }, "/", -1)),
25761
- createBaseVNode("time", _hoisted_5$4, toDisplayString(__props.duration), 1)
25772
+ createBaseVNode("time", _hoisted_5$5, toDisplayString(__props.duration), 1)
25762
25773
  ]),
25763
25774
  createBaseVNode("div", _hoisted_6$4, [
25764
25775
  createBaseVNode("div", {
@@ -25816,8 +25827,8 @@ section.turn:has([data-state="open"]) {
25816
25827
  };
25817
25828
  }
25818
25829
  });
25819
- const _style_0$a = "\n.player-controls[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-md);\n padding: var(--spacing-xs) var(--spacing-lg);\n height: 44px;\n}\n.controls-left[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n.controls-time[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xxs);\n font-family: var(--font-family-mono);\n font-size: var(--font-size-sm);\n color: var(--color-text-muted);\n user-select: none;\n}\n.time-separator[data-v-fb293305] {\n color: var(--color-text-muted);\n opacity: 0.5;\n}\n.controls-right[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n margin-left: auto;\n}\n.volume-group[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n.volume-slider[data-v-fb293305] {\n width: 80px;\n height: 4px;\n accent-color: var(--color-primary);\n cursor: pointer;\n}\n.volume-slider[data-v-fb293305]:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.play-button[data-v-fb293305] {\n width: 40px;\n height: 40px;\n}\n.speed-button[data-v-fb293305] {\n font-size: var(--font-size-sm);\n font-family: var(--font-family-mono);\n}\n@media (max-width: 767px) {\n.skip-button[data-v-fb293305] {\n display: none;\n}\n.volume-slider[data-v-fb293305] {\n display: none;\n}\n.player-controls[data-v-fb293305] {\n padding: var(--spacing-xs) var(--spacing-md);\n gap: var(--spacing-sm);\n}\n}\n";
25820
- const AudioPlayerControls = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["styles", [_style_0$a]], ["__scopeId", "data-v-fb293305"]]);
25830
+ const _style_0$b = "\n.player-controls[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-md);\n padding: var(--spacing-xs) var(--spacing-lg);\n height: 44px;\n}\n.controls-left[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n.controls-time[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xxs);\n font-family: var(--font-family-mono);\n font-size: var(--font-size-sm);\n color: var(--color-text-muted);\n user-select: none;\n}\n.time-separator[data-v-fb293305] {\n color: var(--color-text-muted);\n opacity: 0.5;\n}\n.controls-right[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n margin-left: auto;\n}\n.volume-group[data-v-fb293305] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n.volume-slider[data-v-fb293305] {\n width: 80px;\n height: 4px;\n accent-color: var(--color-primary);\n cursor: pointer;\n}\n.volume-slider[data-v-fb293305]:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.play-button[data-v-fb293305] {\n width: 40px;\n height: 40px;\n}\n.speed-button[data-v-fb293305] {\n font-size: var(--font-size-sm);\n font-family: var(--font-family-mono);\n}\n@media (max-width: 767px) {\n.skip-button[data-v-fb293305] {\n display: none;\n}\n.volume-slider[data-v-fb293305] {\n display: none;\n}\n.player-controls[data-v-fb293305] {\n padding: var(--spacing-xs) var(--spacing-md);\n gap: var(--spacing-sm);\n}\n}\n";
25831
+ const AudioPlayerControls = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["styles", [_style_0$b]], ["__scopeId", "data-v-fb293305"]]);
25821
25832
  function t$1(t2, e2, i2, n2) {
25822
25833
  return new (i2 || (i2 = Promise))((function(s2, r2) {
25823
25834
  function o2(t3) {
@@ -27749,8 +27760,8 @@ section.turn:has([data-state="open"]) {
27749
27760
  toggleMute
27750
27761
  };
27751
27762
  }
27752
- const _hoisted_1$9 = { class: "audio-player" };
27753
- const _sfc_main$9 = /* @__PURE__ */ defineComponent({
27763
+ const _hoisted_1$a = { class: "audio-player" };
27764
+ const _sfc_main$b = /* @__PURE__ */ defineComponent({
27754
27765
  __name: "AudioPlayer",
27755
27766
  props: {
27756
27767
  audioSrc: { type: String }
@@ -27780,7 +27791,7 @@ section.turn:has([data-state="open"]) {
27780
27791
  });
27781
27792
  __expose({ seekTo, pause });
27782
27793
  return (_ctx, _cache) => {
27783
- return openBlock(), createElementBlock("footer", _hoisted_1$9, [
27794
+ return openBlock(), createElementBlock("footer", _hoisted_1$a, [
27784
27795
  createBaseVNode("div", {
27785
27796
  ref_key: "waveformRef",
27786
27797
  ref: waveformRef,
@@ -27805,8 +27816,8 @@ section.turn:has([data-state="open"]) {
27805
27816
  };
27806
27817
  }
27807
27818
  });
27808
- const _style_0$9 = "\n.audio-player[data-v-580c393d] {\n border-top: 1px solid var(--color-border);\n background-color: var(--color-surface);\n flex-shrink: 0;\n}\n.transcript-ui-waveform-container[data-v-580c393d] {\n min-height: 32px;\n}\n.transcript-ui-waveform-container--loading[data-v-580c393d] {\n background: linear-gradient(\n 90deg,\n var(--color-border-light, var(--color-border)) 25%,\n var(--color-border) 50%,\n var(--color-border-light, var(--color-border)) 75%\n );\n background-size: 200% 100%;\n animation: shimmer-580c393d 1.5s ease-in-out infinite;\n border-radius: var(--radius-sm);\n}\n@keyframes shimmer-580c393d {\n0% {\n background-position: 200% 0;\n}\n100% {\n background-position: -200% 0;\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.transcript-ui-waveform-container--loading[data-v-580c393d] {\n animation: none;\n}\n}\n";
27809
- const AudioPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["styles", [_style_0$9]], ["__scopeId", "data-v-580c393d"]]);
27819
+ const _style_0$a = "\n.audio-player[data-v-580c393d] {\n border-top: 1px solid var(--color-border);\n background-color: var(--color-surface);\n flex-shrink: 0;\n}\n.transcript-ui-waveform-container[data-v-580c393d] {\n min-height: 32px;\n}\n.transcript-ui-waveform-container--loading[data-v-580c393d] {\n background: linear-gradient(\n 90deg,\n var(--color-border-light, var(--color-border)) 25%,\n var(--color-border) 50%,\n var(--color-border-light, var(--color-border)) 75%\n );\n background-size: 200% 100%;\n animation: shimmer-580c393d 1.5s ease-in-out infinite;\n border-radius: var(--radius-sm);\n}\n@keyframes shimmer-580c393d {\n0% {\n background-position: 200% 0;\n}\n100% {\n background-position: -200% 0;\n}\n}\n@media (prefers-reduced-motion: reduce) {\n.transcript-ui-waveform-container--loading[data-v-580c393d] {\n animation: none;\n}\n}\n";
27820
+ const AudioPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["styles", [_style_0$a]], ["__scopeId", "data-v-580c393d"]]);
27810
27821
  const { findActiveWord, firstWordStart, lastWordEnd } = utils;
27811
27822
  const WORD_TRACK_INTERVAL = 0.05;
27812
27823
  function createAudioPlugin(options = {}) {
@@ -28524,14 +28535,14 @@ section.turn:has([data-state="open"]) {
28524
28535
  }
28525
28536
  return parts;
28526
28537
  }
28527
- const _hoisted_1$8 = {
28538
+ const _hoisted_1$9 = {
28528
28539
  key: 0,
28529
28540
  class: "watermark",
28530
28541
  "aria-hidden": "true"
28531
28542
  };
28532
- const _hoisted_2$7 = ["src", "alt"];
28543
+ const _hoisted_2$8 = ["src", "alt"];
28533
28544
  const _hoisted_3$6 = { key: 1 };
28534
- const _sfc_main$8 = /* @__PURE__ */ defineComponent({
28545
+ const _sfc_main$a = /* @__PURE__ */ defineComponent({
28535
28546
  __name: "SubtitleWatermark",
28536
28547
  props: {
28537
28548
  visible: { type: Boolean }
@@ -28546,7 +28557,7 @@ section.turn:has([data-state="open"]) {
28546
28557
  return (_ctx, _cache) => {
28547
28558
  return openBlock(), createBlock(Transition, { name: "watermark" }, {
28548
28559
  default: withCtx(() => [
28549
- __props.visible && unref(watermark) ? (openBlock(), createElementBlock("div", _hoisted_1$8, [
28560
+ __props.visible && unref(watermark) ? (openBlock(), createElementBlock("div", _hoisted_1$9, [
28550
28561
  (openBlock(true), createElementBlock(Fragment, null, renderList(parts.value, (part, i2) => {
28551
28562
  return openBlock(), createElementBlock(Fragment, { key: i2 }, [
28552
28563
  part.type === "token" ? (openBlock(), createElementBlock("img", {
@@ -28554,7 +28565,7 @@ section.turn:has([data-state="open"]) {
28554
28565
  src: part.src,
28555
28566
  alt: part.alt,
28556
28567
  class: "watermark__img"
28557
- }, null, 8, _hoisted_2$7)) : (openBlock(), createElementBlock("span", _hoisted_3$6, toDisplayString(part.value), 1))
28568
+ }, null, 8, _hoisted_2$8)) : (openBlock(), createElementBlock("span", _hoisted_3$6, toDisplayString(part.value), 1))
28558
28569
  ], 64);
28559
28570
  }), 128))
28560
28571
  ])) : createCommentVNode("", true)
@@ -28564,10 +28575,10 @@ section.turn:has([data-state="open"]) {
28564
28575
  };
28565
28576
  }
28566
28577
  });
28567
- const _style_0$8 = "\n.watermark[data-v-eb604a8e] {\n position: absolute;\n right: var(--spacing-md, 16px);\n bottom: 4px;\n display: inline-flex;\n align-items: center;\n gap: 0.25em;\n font-size: 1.2rem;\n color: var(--color-white, #fff);\n pointer-events: none;\n line-height: 1;\n}\n.watermark__img[data-v-eb604a8e] {\n height: 1em;\n vertical-align: middle;\n}\n.watermark-enter-active[data-v-eb604a8e],\n.watermark-leave-active[data-v-eb604a8e] {\n transition:\n opacity 0.4s ease,\n transform 0.4s ease;\n}\n.watermark-enter-from[data-v-eb604a8e],\n.watermark-leave-to[data-v-eb604a8e] {\n opacity: 0;\n transform: translate(6px, 6px);\n}\n@media (prefers-reduced-motion: reduce) {\n.watermark-enter-active[data-v-eb604a8e],\n .watermark-leave-active[data-v-eb604a8e] {\n transition: opacity 0.01s;\n transform: none;\n}\n}\n";
28568
- const SubtitleWatermark = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["styles", [_style_0$8]], ["__scopeId", "data-v-eb604a8e"]]);
28569
- const _hoisted_1$7 = ["height"];
28570
- const _sfc_main$7 = /* @__PURE__ */ defineComponent({
28578
+ const _style_0$9 = "\n.watermark[data-v-eb604a8e] {\n position: absolute;\n right: var(--spacing-md, 16px);\n bottom: 4px;\n display: inline-flex;\n align-items: center;\n gap: 0.25em;\n font-size: 1.2rem;\n color: var(--color-white, #fff);\n pointer-events: none;\n line-height: 1;\n}\n.watermark__img[data-v-eb604a8e] {\n height: 1em;\n vertical-align: middle;\n}\n.watermark-enter-active[data-v-eb604a8e],\n.watermark-leave-active[data-v-eb604a8e] {\n transition:\n opacity 0.4s ease,\n transform 0.4s ease;\n}\n.watermark-enter-from[data-v-eb604a8e],\n.watermark-leave-to[data-v-eb604a8e] {\n opacity: 0;\n transform: translate(6px, 6px);\n}\n@media (prefers-reduced-motion: reduce) {\n.watermark-enter-active[data-v-eb604a8e],\n .watermark-leave-active[data-v-eb604a8e] {\n transition: opacity 0.01s;\n transform: none;\n}\n}\n";
28579
+ const SubtitleWatermark = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["styles", [_style_0$9]], ["__scopeId", "data-v-eb604a8e"]]);
28580
+ const _hoisted_1$8 = ["height"];
28581
+ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
28571
28582
  __name: "SubtitleBanner",
28572
28583
  setup(__props) {
28573
28584
  const core = useCore();
@@ -28601,20 +28612,20 @@ section.turn:has([data-state="open"]) {
28601
28612
  ref: "canvas",
28602
28613
  class: normalizeClass(["subtitle-canvas", { "subtitle-canvas--shrunk": unref(watermarkVisible) }]),
28603
28614
  height: canvasHeight.value
28604
- }, null, 10, _hoisted_1$7),
28615
+ }, null, 10, _hoisted_1$8),
28605
28616
  createVNode(SubtitleWatermark, { visible: unref(watermarkVisible) }, null, 8, ["visible"])
28606
28617
  ], 4);
28607
28618
  };
28608
28619
  }
28609
28620
  });
28610
- const _style_0$7 = "\n.subtitle-banner[data-v-6b9b2fb2] {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n flex-shrink: 0;\n background-color: var(--color-black);\n overflow: hidden;\n z-index: 1001;\n}\n.subtitle-canvas[data-v-6b9b2fb2] {\n display: block;\n width: 100%;\n height: 100%;\n transition: transform 0.4s ease;\n transform-origin: top center;\n}\n.subtitle-canvas--shrunk[data-v-6b9b2fb2] {\n transform: scale(0.8) translateY(-8%);\n}\n@media (prefers-reduced-motion: reduce) {\n.subtitle-canvas[data-v-6b9b2fb2] {\n transition: none;\n}\n}\n";
28611
- const SubtitleBanner = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["styles", [_style_0$7]], ["__scopeId", "data-v-6b9b2fb2"]]);
28612
- const _hoisted_1$6 = {
28621
+ const _style_0$8 = "\n.subtitle-banner[data-v-6b9b2fb2] {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n flex-shrink: 0;\n background-color: var(--color-black);\n overflow: hidden;\n z-index: 1001;\n}\n.subtitle-canvas[data-v-6b9b2fb2] {\n display: block;\n width: 100%;\n height: 100%;\n transition: transform 0.4s ease;\n transform-origin: top center;\n}\n.subtitle-canvas--shrunk[data-v-6b9b2fb2] {\n transform: scale(0.8) translateY(-8%);\n}\n@media (prefers-reduced-motion: reduce) {\n.subtitle-canvas[data-v-6b9b2fb2] {\n transition: none;\n}\n}\n";
28622
+ const SubtitleBanner = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["styles", [_style_0$8]], ["__scopeId", "data-v-6b9b2fb2"]]);
28623
+ const _hoisted_1$7 = {
28613
28624
  ref: "container",
28614
28625
  class: "subtitle-fullscreen"
28615
28626
  };
28616
- const _hoisted_2$6 = ["aria-label"];
28617
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
28627
+ const _hoisted_2$7 = ["aria-label"];
28628
+ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
28618
28629
  __name: "SubtitleFullscreen",
28619
28630
  setup(__props) {
28620
28631
  const core = useCore();
@@ -28672,14 +28683,14 @@ section.turn:has([data-state="open"]) {
28672
28683
  }
28673
28684
  });
28674
28685
  return (_ctx, _cache) => {
28675
- return openBlock(), createElementBlock("div", _hoisted_1$6, [
28686
+ return openBlock(), createElementBlock("div", _hoisted_1$7, [
28676
28687
  createBaseVNode("button", {
28677
28688
  class: "subtitle-fullscreen__close",
28678
28689
  "aria-label": unref(t2)("subtitle.exitFullscreen"),
28679
28690
  onClick: close
28680
28691
  }, [
28681
28692
  createVNode(unref(X$1), { size: 24 })
28682
- ], 8, _hoisted_2$6),
28693
+ ], 8, _hoisted_2$7),
28683
28694
  createBaseVNode("canvas", {
28684
28695
  ref: "canvas",
28685
28696
  class: normalizeClass(["subtitle-fullscreen__canvas", { "subtitle-fullscreen__canvas--shrunk": unref(watermarkVisible) }])
@@ -28689,8 +28700,8 @@ section.turn:has([data-state="open"]) {
28689
28700
  };
28690
28701
  }
28691
28702
  });
28692
- const _style_0$6 = "\n.subtitle-fullscreen[data-v-4dac7247] {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background-color: var(--color-black);\n}\n.transcript-ui-root .subtitle-fullscreen__close[data-v-4dac7247] {\n /* Full reset (same convention as Button, EditableText, Tabs…): the\n previous partial reset (border/background only) left margin, padding,\n and appearance to whatever the host page's UA/global styles set. */\n all: unset;\n box-sizing: border-box;\n position: absolute;\n top: var(--spacing-md, 16px);\n right: var(--spacing-md, 16px);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: rgba(255, 255, 255, 0.1);\n color: var(--color-white);\n border-radius: var(--radius-md, 8px);\n cursor: pointer;\n transition: background-color var(--transition-duration) ease;\n}\n.transcript-ui-root .subtitle-fullscreen__close[data-v-4dac7247]:hover,\n.transcript-ui-root .subtitle-fullscreen__close[data-v-4dac7247]:focus-visible {\n background: rgba(255, 255, 255, 0.25);\n outline: 2px solid rgba(255, 255, 255, 0.5);\n outline-offset: 2px;\n}\n.subtitle-fullscreen__canvas[data-v-4dac7247] {\n display: block;\n width: 100%;\n height: 100%;\n transition: transform 0.4s ease;\n transform-origin: center;\n}\n.subtitle-fullscreen__canvas--shrunk[data-v-4dac7247] {\n transform: scale(0.85) translateY(-4%);\n}\n@media (prefers-reduced-motion: reduce) {\n.subtitle-fullscreen__close[data-v-4dac7247],\n .subtitle-fullscreen__canvas[data-v-4dac7247] {\n transition: none;\n}\n}\n";
28693
- const SubtitleFullscreen = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["styles", [_style_0$6]], ["__scopeId", "data-v-4dac7247"]]);
28703
+ const _style_0$7 = "\n.subtitle-fullscreen[data-v-4dac7247] {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background-color: var(--color-black);\n}\n.transcript-ui-root .subtitle-fullscreen__close[data-v-4dac7247] {\n /* Full reset (same convention as Button, EditableText, Tabs…): the\n previous partial reset (border/background only) left margin, padding,\n and appearance to whatever the host page's UA/global styles set. */\n all: unset;\n box-sizing: border-box;\n position: absolute;\n top: var(--spacing-md, 16px);\n right: var(--spacing-md, 16px);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: rgba(255, 255, 255, 0.1);\n color: var(--color-white);\n border-radius: var(--radius-md, 8px);\n cursor: pointer;\n transition: background-color var(--transition-duration) ease;\n}\n.transcript-ui-root .subtitle-fullscreen__close[data-v-4dac7247]:hover,\n.transcript-ui-root .subtitle-fullscreen__close[data-v-4dac7247]:focus-visible {\n background: rgba(255, 255, 255, 0.25);\n outline: 2px solid rgba(255, 255, 255, 0.5);\n outline-offset: 2px;\n}\n.subtitle-fullscreen__canvas[data-v-4dac7247] {\n display: block;\n width: 100%;\n height: 100%;\n transition: transform 0.4s ease;\n transform-origin: center;\n}\n.subtitle-fullscreen__canvas--shrunk[data-v-4dac7247] {\n transform: scale(0.85) translateY(-4%);\n}\n@media (prefers-reduced-motion: reduce) {\n.subtitle-fullscreen__close[data-v-4dac7247],\n .subtitle-fullscreen__canvas[data-v-4dac7247] {\n transition: none;\n}\n}\n";
28704
+ const SubtitleFullscreen = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["styles", [_style_0$7]], ["__scopeId", "data-v-4dac7247"]]);
28694
28705
  function createSubtitlePlugin(options = {}) {
28695
28706
  return {
28696
28707
  name: "subtitle",
@@ -29492,15 +29503,48 @@ section.turn:has([data-state="open"]) {
29492
29503
  }
29493
29504
  };
29494
29505
  }
29506
+ const _hoisted_1$6 = ["title"];
29507
+ const _hoisted_2$6 = { class: "llm-service-status__label" };
29508
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
29509
+ __name: "LLMServiceStatus",
29510
+ props: {
29511
+ isUpdated: { type: Boolean }
29512
+ },
29513
+ setup(__props) {
29514
+ const props = __props;
29515
+ const { t: t2 } = useI18n();
29516
+ const label = computed(
29517
+ () => props.isUpdated ? t2("llmService.statusUpdated") : t2("llmService.statusOutdated")
29518
+ );
29519
+ return (_ctx, _cache) => {
29520
+ return openBlock(), createElementBlock("span", {
29521
+ class: normalizeClass([
29522
+ "llm-service-status",
29523
+ __props.isUpdated ? "llm-service-status--ok" : "llm-service-status--warn"
29524
+ ]),
29525
+ title: label.value
29526
+ }, [
29527
+ createVNode(unref(EditorIcon), {
29528
+ name: __props.isUpdated ? "check" : "warning",
29529
+ size: 14
29530
+ }, null, 8, ["name"]),
29531
+ createBaseVNode("span", _hoisted_2$6, toDisplayString(label.value), 1)
29532
+ ], 10, _hoisted_1$6);
29533
+ };
29534
+ }
29535
+ });
29536
+ const _style_0$6 = "\n.llm-service-status[data-v-f6c4d61b] {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-xs);\n min-width: 0;\n font-size: var(--font-size-xs);\n font-weight: 500;\n}\n.llm-service-status--ok[data-v-f6c4d61b] {\n color: var(--color-success, #2e7d32);\n}\n.llm-service-status--warn[data-v-f6c4d61b] {\n color: var(--color-warning, #ed6c02);\n}\n.llm-service-status[data-v-f6c4d61b] .editor-icon {\n flex-shrink: 0;\n}\n.llm-service-status__label[data-v-f6c4d61b] {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
29537
+ const LLMServiceStatus = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["styles", [_style_0$6]], ["__scopeId", "data-v-f6c4d61b"]]);
29495
29538
  const _hoisted_1$5 = { class: "llm-service-panel" };
29496
- const _hoisted_2$5 = { class: "llm-service-panel__download-label" };
29497
- const _hoisted_3$5 = {
29539
+ const _hoisted_2$5 = {
29498
29540
  key: 0,
29499
29541
  class: "llm-service-panel__empty",
29500
29542
  role: "status"
29501
29543
  };
29502
- const _hoisted_4$4 = { class: "llm-service-panel__empty-text" };
29503
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
29544
+ const _hoisted_3$5 = { class: "llm-service-panel__empty-text" };
29545
+ const _hoisted_4$4 = { class: "llm-service-panel__reading-status" };
29546
+ const _hoisted_5$4 = { class: "llm-service-panel__reading-actions" };
29547
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
29504
29548
  __name: "LLMServicePanel",
29505
29549
  props: {
29506
29550
  service: { type: Object },
@@ -29512,6 +29556,8 @@ section.turn:has([data-state="open"]) {
29512
29556
  const emit2 = __emit;
29513
29557
  const core = useCore();
29514
29558
  const { t: t2 } = useI18n();
29559
+ const { isMobile } = useIsMobile();
29560
+ const isReadOnly = computed(() => isMobile.value);
29515
29561
  function toggleSplit() {
29516
29562
  emit2("update:split", !props.split);
29517
29563
  }
@@ -29578,66 +29624,10 @@ section.turn:has([data-state="open"]) {
29578
29624
  status: articleStatus.value,
29579
29625
  progress: progress.value,
29580
29626
  onRetry: onRegenerate
29581
- }, {
29582
- "toolbar-left": withCtx(() => [
29583
- createVNode(unref(Button), {
29584
- variant: "primary",
29585
- icon: "save",
29586
- disabled: !dirty.value || busy.value,
29587
- "aria-label": unref(t2)("llmService.save"),
29588
- title: unref(t2)("llmService.save"),
29589
- onClick: onSave
29590
- }, null, 8, ["disabled", "aria-label", "title"]),
29591
- createVNode(unref(Button), {
29592
- variant: "secondary",
29593
- icon: "refresh-cw",
29594
- loading: articleStatus.value === "processing",
29595
- disabled: isUpdated.value || busy.value || articleStatus.value === "processing",
29596
- "aria-label": unref(t2)("llmService.regenerate"),
29597
- title: unref(t2)("llmService.regenerate"),
29598
- onClick: onRegenerate
29599
- }, null, 8, ["loading", "disabled", "aria-label", "title"])
29600
- ]),
29601
- "toolbar-center": withCtx(() => [
29602
- createBaseVNode("span", {
29603
- class: normalizeClass(["llm-service-panel__status", [
29604
- isUpdated.value ? "llm-service-panel__status--ok" : "llm-service-panel__status--warn"
29605
- ]])
29606
- }, [
29607
- createVNode(unref(EditorIcon), {
29608
- name: isUpdated.value ? "check" : "warning",
29609
- size: 14
29610
- }, null, 8, ["name"]),
29611
- createBaseVNode("span", null, toDisplayString(isUpdated.value ? unref(t2)("llmService.statusUpdated") : unref(t2)("llmService.statusOutdated")), 1)
29612
- ], 2)
29613
- ]),
29614
- "toolbar-right": withCtx(() => [
29615
- createVNode(unref(Button), {
29616
- variant: "primary",
29617
- icon: "download",
29618
- disabled: articleStatus.value === "processing" || !hasContent.value,
29619
- "aria-label": unref(t2)("llmService.download"),
29620
- title: unref(t2)("llmService.download"),
29621
- onClick: onExport
29622
- }, {
29623
- default: withCtx(() => [
29624
- createBaseVNode("span", _hoisted_2$5, toDisplayString(unref(t2)("llmService.download")), 1)
29625
- ]),
29626
- _: 1
29627
- }, 8, ["disabled", "aria-label", "title"]),
29628
- createVNode(unref(Button), {
29629
- class: "llm-service-panel__split",
29630
- variant: __props.split ? "primary" : "secondary",
29631
- icon: "panel-right",
29632
- "aria-pressed": !!__props.split,
29633
- "aria-label": unref(t2)("llmService.split"),
29634
- title: unref(t2)("llmService.split"),
29635
- onClick: toggleSplit
29636
- }, null, 8, ["variant", "aria-pressed", "aria-label", "title"])
29637
- ]),
29627
+ }, createSlots({
29638
29628
  default: withCtx(() => [
29639
- isEmpty.value ? (openBlock(), createElementBlock("div", _hoisted_3$5, [
29640
- createBaseVNode("p", _hoisted_4$4, toDisplayString(unref(t2)("llmService.empty")), 1),
29629
+ isEmpty.value ? (openBlock(), createElementBlock("div", _hoisted_2$5, [
29630
+ createBaseVNode("p", _hoisted_3$5, toDisplayString(unref(t2)("llmService.empty")), 1),
29641
29631
  createVNode(unref(Button), {
29642
29632
  variant: "primary",
29643
29633
  icon: "sparkles",
@@ -29649,21 +29639,108 @@ section.turn:has([data-state="open"]) {
29649
29639
  ]),
29650
29640
  _: 1
29651
29641
  }, 8, ["disabled"])
29652
- ])) : (openBlock(), createBlock(unref(MarkdownEditor), {
29642
+ ])) : !isReadOnly.value ? (openBlock(), createBlock(unref(MarkdownEditor), {
29653
29643
  key: 1,
29654
29644
  modelValue: draft.value,
29655
29645
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => draft.value = $event),
29656
29646
  disabled: busy.value
29657
- }, null, 8, ["modelValue", "disabled"]))
29647
+ }, null, 8, ["modelValue", "disabled"])) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
29648
+ createBaseVNode("div", _hoisted_4$4, [
29649
+ createVNode(LLMServiceStatus, { "is-updated": isUpdated.value }, null, 8, ["is-updated"]),
29650
+ createBaseVNode("div", _hoisted_5$4, [
29651
+ !isUpdated.value ? (openBlock(), createBlock(unref(Button), {
29652
+ key: 0,
29653
+ variant: "secondary",
29654
+ icon: "refresh-cw",
29655
+ disabled: busy.value,
29656
+ onClick: onRegenerate
29657
+ }, {
29658
+ default: withCtx(() => [
29659
+ createTextVNode(toDisplayString(unref(t2)("llmService.regenerate")), 1)
29660
+ ]),
29661
+ _: 1
29662
+ }, 8, ["disabled"])) : createCommentVNode("", true),
29663
+ createVNode(unref(Button), {
29664
+ variant: "primary",
29665
+ icon: "download",
29666
+ "aria-label": unref(t2)("llmService.download"),
29667
+ title: unref(t2)("llmService.download"),
29668
+ onClick: onExport
29669
+ }, null, 8, ["aria-label", "title"])
29670
+ ])
29671
+ ]),
29672
+ createVNode(unref(MarkdownView), {
29673
+ class: "llm-service-panel__reading",
29674
+ source: draft.value
29675
+ }, null, 8, ["source"])
29676
+ ], 64))
29658
29677
  ]),
29659
- _: 1
29660
- }, 8, ["status", "progress"])
29678
+ _: 2
29679
+ }, [
29680
+ !isReadOnly.value ? {
29681
+ name: "toolbar-left",
29682
+ fn: withCtx(() => [
29683
+ createVNode(unref(Button), {
29684
+ variant: "primary",
29685
+ icon: "save",
29686
+ disabled: !dirty.value || busy.value,
29687
+ "aria-label": unref(t2)("llmService.save"),
29688
+ title: unref(t2)("llmService.save"),
29689
+ onClick: onSave
29690
+ }, null, 8, ["disabled", "aria-label", "title"]),
29691
+ createVNode(unref(Button), {
29692
+ variant: "secondary",
29693
+ icon: "refresh-cw",
29694
+ loading: articleStatus.value === "processing",
29695
+ disabled: isUpdated.value || busy.value || articleStatus.value === "processing",
29696
+ "aria-label": unref(t2)("llmService.regenerate"),
29697
+ title: unref(t2)("llmService.regenerate"),
29698
+ onClick: onRegenerate
29699
+ }, null, 8, ["loading", "disabled", "aria-label", "title"])
29700
+ ]),
29701
+ key: "0"
29702
+ } : void 0,
29703
+ !isReadOnly.value ? {
29704
+ name: "toolbar-center",
29705
+ fn: withCtx(() => [
29706
+ createVNode(LLMServiceStatus, { "is-updated": isUpdated.value }, null, 8, ["is-updated"])
29707
+ ]),
29708
+ key: "1"
29709
+ } : void 0,
29710
+ !isReadOnly.value ? {
29711
+ name: "toolbar-right",
29712
+ fn: withCtx(() => [
29713
+ createVNode(unref(Button), {
29714
+ variant: "primary",
29715
+ icon: "download",
29716
+ disabled: articleStatus.value === "processing" || !hasContent.value,
29717
+ "aria-label": unref(t2)("llmService.download"),
29718
+ title: unref(t2)("llmService.download"),
29719
+ onClick: onExport
29720
+ }, {
29721
+ default: withCtx(() => [
29722
+ createTextVNode(toDisplayString(unref(t2)("llmService.download")), 1)
29723
+ ]),
29724
+ _: 1
29725
+ }, 8, ["disabled", "aria-label", "title"]),
29726
+ createVNode(unref(Button), {
29727
+ variant: __props.split ? "primary" : "secondary",
29728
+ icon: "panel-right",
29729
+ "aria-pressed": !!__props.split,
29730
+ "aria-label": unref(t2)("llmService.split"),
29731
+ title: unref(t2)("llmService.split"),
29732
+ onClick: toggleSplit
29733
+ }, null, 8, ["variant", "aria-pressed", "aria-label", "title"])
29734
+ ]),
29735
+ key: "2"
29736
+ } : void 0
29737
+ ]), 1032, ["status", "progress"])
29661
29738
  ]);
29662
29739
  };
29663
29740
  }
29664
29741
  });
29665
- const _style_0$5 = "\n.llm-service-panel[data-v-920b527a] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n}\n.llm-service-panel__status[data-v-920b527a] {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-xs);\n font-size: var(--font-size-xs);\n font-weight: 500;\n}\n.llm-service-panel__status--ok[data-v-920b527a] {\n color: var(--color-success, #2e7d32);\n}\n.llm-service-panel__status--warn[data-v-920b527a] {\n color: var(--color-warning, #ed6c02);\n}\n.llm-service-panel__empty[data-v-920b527a] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-md);\n padding: var(--spacing-xl) var(--spacing-md);\n text-align: center;\n}\n.llm-service-panel__empty-text[data-v-920b527a] {\n margin: 0;\n max-width: 400px;\n font-size: var(--font-size-sm);\n color: var(--color-text-secondary);\n}\n\n/* Phone: no side-by-side (Layout forces split off below 767px), and the\n download button keeps its icon only. */\n@media (max-width: 767px) {\n.llm-service-panel[data-v-920b527a] {\n padding: var(--spacing-sm) 0;\n}\n.llm-service-panel__split[data-v-920b527a],\n .llm-service-panel__download-label[data-v-920b527a] {\n display: none;\n}\n}\n";
29666
- const LLMServicePanel = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["styles", [_style_0$5]], ["__scopeId", "data-v-920b527a"]]);
29742
+ const _style_0$5 = "\n.llm-service-panel[data-v-2d38dcc6] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n}\n.llm-service-panel__reading-status[data-v-2d38dcc6] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n border-bottom: 1px solid var(--color-border);\n}\n.llm-service-panel__reading-actions[data-v-2d38dcc6] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n margin-left: auto;\n}\n.llm-service-panel__reading[data-v-2d38dcc6] {\n padding: var(--spacing-xl) var(--spacing-lg);\n}\n.llm-service-panel__empty[data-v-2d38dcc6] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-md);\n padding: var(--spacing-xl) var(--spacing-md);\n text-align: center;\n}\n.llm-service-panel__empty-text[data-v-2d38dcc6] {\n margin: 0;\n max-width: 400px;\n font-size: var(--font-size-sm);\n color: var(--color-text-secondary);\n}\n";
29743
+ const LLMServicePanel = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["styles", [_style_0$5]], ["__scopeId", "data-v-2d38dcc6"]]);
29667
29744
  function createService(init) {
29668
29745
  return {
29669
29746
  id: init.id,
@@ -29864,7 +29941,7 @@ section.turn:has([data-state="open"]) {
29864
29941
  class: "chat-session-confirm"
29865
29942
  };
29866
29943
  const _hoisted_6$3 = { class: "chat-session-confirm__text" };
29867
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
29944
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
29868
29945
  __name: "ChatSessionList",
29869
29946
  props: {
29870
29947
  sessions: { type: Array },
@@ -29996,7 +30073,48 @@ section.turn:has([data-state="open"]) {
29996
30073
  }
29997
30074
  });
29998
30075
  const _style_0$4 = "\n.chat-session-list[data-v-c13478f0] {\n width: var(--chat-session-list-width, 200px);\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n border-right: 1px solid var(--color-border);\n background-color: var(--color-surface-hover);\n transition: width 0.2s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n.chat-session-list[data-v-c13478f0] {\n transition: none;\n}\n}\n.chat-session-list__header[data-v-c13478f0] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--spacing-sm) var(--spacing-md);\n}\n.chat-session-list__title[data-v-c13478f0] {\n margin: 0;\n font-size: var(--font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-muted);\n}\n.chat-session-list__items[data-v-c13478f0] {\n flex: 1;\n margin: 0;\n padding: 0;\n list-style: none;\n overflow-y: auto;\n}\n\n/* Delete confirmation row */\n.chat-session-confirm[data-v-c13478f0] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: var(--spacing-xs) var(--spacing-sm);\n}\n.chat-session-confirm__text[data-v-c13478f0] {\n flex: 1;\n min-width: 0;\n font-size: var(--font-size-xs);\n color: var(--color-danger);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n";
29999
- const ChatSessionList = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["styles", [_style_0$4]], ["__scopeId", "data-v-c13478f0"]]);
30076
+ const ChatSessionList = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["styles", [_style_0$4]], ["__scopeId", "data-v-c13478f0"]]);
30077
+ function computeSessionOptions(sessions, activeSessionId, newSessionLabel) {
30078
+ const options = sessions.map((session) => ({
30079
+ value: session.id,
30080
+ label: session.title || newSessionLabel
30081
+ }));
30082
+ const isActiveListed = sessions.some((s2) => s2.id === activeSessionId);
30083
+ if (isActiveListed) return options;
30084
+ return [{ value: activeSessionId ?? "", label: newSessionLabel }, ...options];
30085
+ }
30086
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
30087
+ __name: "ChatSessionSelect",
30088
+ props: {
30089
+ sessions: { type: Array },
30090
+ activeSessionId: { type: [String, null] }
30091
+ },
30092
+ emits: ["select"],
30093
+ setup(__props, { emit: __emit }) {
30094
+ const props = __props;
30095
+ const emit2 = __emit;
30096
+ const { t: t2 } = useI18n();
30097
+ const options = computed(
30098
+ () => computeSessionOptions(props.sessions, props.activeSessionId, t2("chat.newChat"))
30099
+ );
30100
+ const field = computed(() => ({
30101
+ customParams: { "aria-label": t2("chat.history") }
30102
+ }));
30103
+ function onChange(sessionId) {
30104
+ if (sessionId && sessionId !== props.activeSessionId) emit2("select", sessionId);
30105
+ }
30106
+ return (_ctx, _cache) => {
30107
+ return openBlock(), createBlock(unref(FormInput), {
30108
+ select: "",
30109
+ "full-width": "",
30110
+ field: field.value,
30111
+ options: options.value,
30112
+ "model-value": __props.activeSessionId ?? "",
30113
+ "onUpdate:modelValue": onChange
30114
+ }, null, 8, ["field", "options", "model-value"]);
30115
+ };
30116
+ }
30117
+ });
30000
30118
  const _hoisted_1$3 = {
30001
30119
  key: 0,
30002
30120
  class: "chat-message chat-message--user"
@@ -30179,6 +30297,7 @@ section.turn:has([data-state="open"]) {
30179
30297
  class: "chat-composer__textarea",
30180
30298
  placeholder: unref(t2)("chat.placeholder"),
30181
30299
  disabled: __props.disabled,
30300
+ enterkeyhint: "send",
30182
30301
  rows: "2",
30183
30302
  ref: "chat-composer__textarea",
30184
30303
  onKeydown
@@ -30197,8 +30316,8 @@ section.turn:has([data-state="open"]) {
30197
30316
  };
30198
30317
  }
30199
30318
  });
30200
- const _style_0$1 = "\n.chat-composer[data-v-05dbe7e6] {\n display: flex;\n align-items: flex-end;\n gap: var(--spacing-sm);\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-border);\n flex-shrink: 0;\n /* Match the message column width when the panel is expanded. */\n width: 100%;\n max-width: var(--chat-content-max-width, 760px);\n margin-inline: auto;\n}\n.chat-composer__textarea[data-v-05dbe7e6] {\n flex: 1;\n resize: none;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: var(--spacing-sm) var(--spacing-md);\n font-family: inherit;\n font-size: var(--font-size-sm);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n background-color: var(--color-surface);\n outline: none;\n}\n.chat-composer__textarea[data-v-05dbe7e6]:focus {\n border-color: var(--color-primary);\n}\n.chat-composer__textarea[data-v-05dbe7e6]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n";
30201
- const ChatComposer = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["styles", [_style_0$1]], ["__scopeId", "data-v-05dbe7e6"]]);
30319
+ const _style_0$1 = "\n.chat-composer[data-v-037fb976] {\n display: flex;\n align-items: flex-end;\n gap: var(--spacing-sm);\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-border);\n flex-shrink: 0;\n /* Match the message column width when the panel is expanded. */\n width: 100%;\n max-width: var(--chat-content-max-width, 760px);\n margin-inline: auto;\n}\n.chat-composer__textarea[data-v-037fb976] {\n flex: 1;\n resize: none;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: var(--spacing-sm) var(--spacing-md);\n font-family: inherit;\n font-size: var(--font-size-sm);\n line-height: var(--line-height);\n color: var(--color-text-primary);\n background-color: var(--color-surface);\n outline: none;\n}\n.chat-composer__textarea[data-v-037fb976]:focus {\n border-color: var(--color-primary);\n}\n.chat-composer__textarea[data-v-037fb976]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n";
30320
+ const ChatComposer = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["styles", [_style_0$1]], ["__scopeId", "data-v-037fb976"]]);
30202
30321
  const _hoisted_1 = ["aria-labelledby"];
30203
30322
  const _hoisted_2 = { class: "chat-drawer__header" };
30204
30323
  const _hoisted_3 = ["id"];
@@ -30210,6 +30329,7 @@ section.turn:has([data-state="open"]) {
30210
30329
  setup(__props) {
30211
30330
  const core = useCore();
30212
30331
  const { t: t2 } = useI18n();
30332
+ const { isMobile } = useIsMobile();
30213
30333
  const chat = core.chat;
30214
30334
  const titleId = useId$1();
30215
30335
  const expanded = /* @__PURE__ */ ref(false);
@@ -30259,7 +30379,7 @@ section.turn:has([data-state="open"]) {
30259
30379
  onClick: withModifiers(close, ["self"])
30260
30380
  }, [
30261
30381
  createBaseVNode("aside", {
30262
- class: normalizeClass(["chat-drawer", { "chat-drawer--expanded": expanded.value }]),
30382
+ class: normalizeClass(["chat-drawer", { "chat-drawer--expanded": expanded.value && !unref(isMobile) }]),
30263
30383
  role: "dialog",
30264
30384
  "aria-modal": "true",
30265
30385
  "aria-labelledby": unref(titleId)
@@ -30267,23 +30387,37 @@ section.turn:has([data-state="open"]) {
30267
30387
  createBaseVNode("header", _hoisted_2, [
30268
30388
  createBaseVNode("h2", {
30269
30389
  id: unref(titleId),
30270
- class: "chat-drawer__title"
30390
+ class: normalizeClass(["chat-drawer__title", { "transcript-ui-sr-only": unref(isMobile) }])
30271
30391
  }, [
30272
30392
  createVNode(unref(EditorIcon), {
30273
30393
  name: "sparkles",
30274
30394
  size: 18
30275
30395
  }),
30276
30396
  createTextVNode(" " + toDisplayString(unref(t2)("chat.title")), 1)
30277
- ], 8, _hoisted_3),
30397
+ ], 10, _hoisted_3),
30398
+ unref(isMobile) ? (openBlock(), createBlock(_sfc_main$4, {
30399
+ key: 0,
30400
+ class: "chat-drawer__session-select",
30401
+ sessions: unref(chat).sessions.value,
30402
+ "active-session-id": unref(chat).activeSessionId.value,
30403
+ onSelect
30404
+ }, null, 8, ["sessions", "active-session-id"])) : createCommentVNode("", true),
30278
30405
  createBaseVNode("div", _hoisted_4, [
30279
- createVNode(unref(Button), {
30280
- class: "chat-drawer__expand",
30406
+ unref(isMobile) ? (openBlock(), createBlock(unref(Button), {
30407
+ key: 0,
30408
+ icon: "plus",
30409
+ variant: "tertiary",
30410
+ size: "sm",
30411
+ "aria-label": unref(t2)("chat.newChat"),
30412
+ onClick: onCreate
30413
+ }, null, 8, ["aria-label"])) : (openBlock(), createBlock(unref(Button), {
30414
+ key: 1,
30281
30415
  icon: expanded.value ? "minimize" : "maximize",
30282
30416
  variant: "tertiary",
30283
30417
  size: "sm",
30284
30418
  "aria-label": expanded.value ? unref(t2)("chat.collapse") : unref(t2)("chat.expand"),
30285
30419
  onClick: toggleExpanded
30286
- }, null, 8, ["icon", "aria-label"]),
30420
+ }, null, 8, ["icon", "aria-label"])),
30287
30421
  createVNode(unref(Button), {
30288
30422
  icon: "x",
30289
30423
  variant: "tertiary",
@@ -30294,14 +30428,15 @@ section.turn:has([data-state="open"]) {
30294
30428
  ])
30295
30429
  ]),
30296
30430
  createBaseVNode("div", _hoisted_5, [
30297
- createVNode(ChatSessionList, {
30431
+ !unref(isMobile) ? (openBlock(), createBlock(ChatSessionList, {
30432
+ key: 0,
30298
30433
  sessions: unref(chat).sessions.value,
30299
30434
  "active-session-id": unref(chat).activeSessionId.value,
30300
30435
  onSelect,
30301
30436
  onCreate,
30302
30437
  onRename,
30303
30438
  onDelete
30304
- }, null, 8, ["sessions", "active-session-id"]),
30439
+ }, null, 8, ["sessions", "active-session-id"])) : createCommentVNode("", true),
30305
30440
  createBaseVNode("div", _hoisted_6, [
30306
30441
  createVNode(ChatMessageList, {
30307
30442
  messages: unref(chat).allMessages.value,
@@ -30322,8 +30457,8 @@ section.turn:has([data-state="open"]) {
30322
30457
  };
30323
30458
  }
30324
30459
  });
30325
- const _style_0 = "\n.chat-overlay[data-v-673d2314] {\n position: fixed;\n inset: 0;\n z-index: var(--z-drawer);\n background-color: rgba(0, 0, 0, 0.4);\n display: flex;\n justify-content: flex-end;\n}\n.chat-drawer[data-v-673d2314] {\n /* Centered reading column for messages + composer; cascades to the child\n components through the DOM regardless of scoped styles. */\n --chat-content-max-width: 760px;\n --chat-session-list-width: 200px;\n width: min(620px, 100vw);\n height: 100%;\n display: flex;\n flex-direction: column;\n background-color: var(--color-surface);\n box-shadow: var(--shadow-md);\n transition: width 0.2s ease;\n}\n\n/* Near-full-width: keeps a backdrop strip on the left so click-outside still\n closes the panel. */\n.chat-drawer--expanded[data-v-673d2314] {\n width: min(1400px, 96vw);\n --chat-session-list-width: 300px;\n}\n.chat-drawer__header[data-v-673d2314] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n min-height: var(--header-height);\n border-bottom: 1px solid var(--color-border);\n flex-shrink: 0;\n}\n.chat-drawer__title[data-v-673d2314] {\n margin: 0;\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-sm);\n font-size: var(--font-size-base);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.chat-drawer__title[data-v-673d2314] .editor-icon {\n color: var(--color-primary);\n}\n.chat-drawer__actions[data-v-673d2314] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n\n/* The expand toggle is desktop-only: on phones the panel is already full-width. */\n@media (max-width: 640px) {\n.chat-drawer__expand[data-v-673d2314] {\n display: none;\n}\n}\n.chat-drawer__body[data-v-673d2314] {\n flex: 1;\n min-height: 0;\n display: flex;\n}\n.chat-drawer__main[data-v-673d2314] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n/* ── Slide + fade transition ── */\n.chat-drawer-enter-active[data-v-673d2314],\n.chat-drawer-leave-active[data-v-673d2314] {\n transition: opacity 0.2s ease;\n}\n.chat-drawer-enter-active .chat-drawer[data-v-673d2314],\n.chat-drawer-leave-active .chat-drawer[data-v-673d2314] {\n transition: transform 0.25s ease;\n}\n.chat-drawer-enter-from[data-v-673d2314],\n.chat-drawer-leave-to[data-v-673d2314] {\n opacity: 0;\n}\n.chat-drawer-enter-from .chat-drawer[data-v-673d2314],\n.chat-drawer-leave-to .chat-drawer[data-v-673d2314] {\n transform: translateX(100%);\n}\n@media (prefers-reduced-motion: reduce) {\n.chat-drawer[data-v-673d2314],\n .chat-drawer-enter-active[data-v-673d2314],\n .chat-drawer-leave-active[data-v-673d2314],\n .chat-drawer-enter-active .chat-drawer[data-v-673d2314],\n .chat-drawer-leave-active .chat-drawer[data-v-673d2314] {\n transition: none;\n}\n}\n";
30326
- const ChatDrawer = /* @__PURE__ */ _export_sfc(_sfc_main, [["styles", [_style_0]], ["__scopeId", "data-v-673d2314"]]);
30460
+ const _style_0 = "\n.chat-overlay[data-v-25f4e0cf] {\n position: fixed;\n inset: 0;\n z-index: var(--z-drawer);\n background-color: rgba(0, 0, 0, 0.4);\n display: flex;\n justify-content: flex-end;\n}\n.chat-drawer[data-v-25f4e0cf] {\n /* Centered reading column for messages + composer; cascades to the child\n components through the DOM regardless of scoped styles. */\n --chat-content-max-width: 760px;\n --chat-session-list-width: 200px;\n width: min(620px, 100vw);\n height: 100%;\n display: flex;\n flex-direction: column;\n background-color: var(--color-surface);\n box-shadow: var(--shadow-md);\n transition: width 0.2s ease;\n}\n\n/* Near-full-width: keeps a backdrop strip on the left so click-outside still\n closes the panel. */\n.chat-drawer--expanded[data-v-25f4e0cf] {\n width: min(1400px, 96vw);\n --chat-session-list-width: 300px;\n}\n.chat-drawer__header[data-v-25f4e0cf] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--spacing-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n min-height: var(--header-height);\n border-bottom: 1px solid var(--color-border);\n flex-shrink: 0;\n}\n.chat-drawer__title[data-v-25f4e0cf] {\n margin: 0;\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-sm);\n font-size: var(--font-size-base);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.chat-drawer__title[data-v-25f4e0cf] .editor-icon {\n color: var(--color-primary);\n}\n.chat-drawer__session-select[data-v-25f4e0cf] {\n flex: 1;\n min-width: 0;\n}\n.chat-drawer__actions[data-v-25f4e0cf] {\n display: flex;\n align-items: center;\n gap: var(--spacing-xs);\n}\n.chat-drawer__body[data-v-25f4e0cf] {\n flex: 1;\n min-height: 0;\n display: flex;\n}\n.chat-drawer__main[data-v-25f4e0cf] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n/* ── Slide + fade transition ── */\n.chat-drawer-enter-active[data-v-25f4e0cf],\n.chat-drawer-leave-active[data-v-25f4e0cf] {\n transition: opacity 0.2s ease;\n}\n.chat-drawer-enter-active .chat-drawer[data-v-25f4e0cf],\n.chat-drawer-leave-active .chat-drawer[data-v-25f4e0cf] {\n transition: transform 0.25s ease;\n}\n.chat-drawer-enter-from[data-v-25f4e0cf],\n.chat-drawer-leave-to[data-v-25f4e0cf] {\n opacity: 0;\n}\n.chat-drawer-enter-from .chat-drawer[data-v-25f4e0cf],\n.chat-drawer-leave-to .chat-drawer[data-v-25f4e0cf] {\n transform: translateX(100%);\n}\n@media (prefers-reduced-motion: reduce) {\n.chat-drawer[data-v-25f4e0cf],\n .chat-drawer-enter-active[data-v-25f4e0cf],\n .chat-drawer-leave-active[data-v-25f4e0cf],\n .chat-drawer-enter-active .chat-drawer[data-v-25f4e0cf],\n .chat-drawer-leave-active .chat-drawer[data-v-25f4e0cf] {\n transition: none;\n}\n}\n";
30461
+ const ChatDrawer = /* @__PURE__ */ _export_sfc(_sfc_main, [["styles", [_style_0]], ["__scopeId", "data-v-25f4e0cf"]]);
30327
30462
  const STREAMING_MESSAGE_ID = "__streaming__";
30328
30463
  function createChatPlugin() {
30329
30464
  return {