@quilltap/theme-storybook 1.0.75 → 1.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to `@quilltap/theme-storybook` will be documented in this file.
4
4
 
5
+ ## [1.0.76] - 2026-10-20
6
+
7
+ ### Added
8
+ - `stop-sign` (an octagon) and `hand-raised` in the Icons story's media group, mirroring the app's new registry entries for the Salon composer's Stop and raised-hand buttons.
9
+ - The composer action-button family in `qt-components.css`: `.qt-chat-composer-actions`, `.qt-chat-composer-send`, `.qt-chat-continue-button`, `.qt-chat-stop-button`, and the new `.qt-chat-interrupt-button` / `.qt-chat-interrupt-button-raised` (warning amber, with a pulsing ring while a hand is up). The Chat story's control-buttons section shows the trio.
10
+
5
11
  ## [1.0.75] - 2026-10-19
6
12
 
7
13
  ### Added
@@ -125,7 +125,7 @@ var ICON_GROUPS = [
125
125
  },
126
126
  {
127
127
  category: "Media",
128
- names: ["image", "camera", "play", "pause", "stop", "zoom-in", "zoom-out"]
128
+ names: ["image", "camera", "play", "pause", "stop", "stop-sign", "hand-raised", "zoom-in", "zoom-out"]
129
129
  },
130
130
  {
131
131
  category: "Content & sidebar navigation",
@@ -1979,6 +1979,34 @@ var Chat = () => {
1979
1979
  /* @__PURE__ */ jsxs14("section", { style: { marginBottom: "2rem" }, children: [
1980
1980
  /* @__PURE__ */ jsx14("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Chat Control Buttons" }),
1981
1981
  /* @__PURE__ */ jsx14("p", { style: { color: "var(--color-muted-foreground)", marginBottom: "1rem" }, children: "Continue and stop buttons for controlling AI response generation." }),
1982
+ /* @__PURE__ */ jsxs14("p", { style: { color: "var(--color-muted-foreground)", marginBottom: "1rem", fontSize: "0.875rem" }, children: [
1983
+ "The composer's action trio while a character is speaking: Send (disabled), the soft interrupt ",
1984
+ /* @__PURE__ */ jsx14("code", { children: ".qt-chat-interrupt-button" }),
1985
+ " (shown idle, then raised with",
1986
+ /* @__PURE__ */ jsx14("code", { children: ".qt-chat-interrupt-button-raised" }),
1987
+ "), and the hard ",
1988
+ /* @__PURE__ */ jsx14("code", { children: ".qt-chat-stop-button" }),
1989
+ "."
1990
+ ] }),
1991
+ /* @__PURE__ */ jsxs14("div", { className: "qt-chat-composer-actions", style: { marginBottom: "1.5rem" }, children: [
1992
+ /* @__PURE__ */ jsx14("button", { className: "qt-chat-composer-send", "aria-label": "Send message", disabled: true, children: /* @__PURE__ */ jsxs14("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
1993
+ /* @__PURE__ */ jsx14("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1994
+ /* @__PURE__ */ jsx14("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1995
+ ] }) }),
1996
+ /* @__PURE__ */ jsx14("button", { className: "qt-chat-composer-send qt-chat-interrupt-button", "aria-label": "Raise your hand to interrupt", children: /* @__PURE__ */ jsxs14("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
1997
+ /* @__PURE__ */ jsx14("path", { d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" }),
1998
+ /* @__PURE__ */ jsx14("path", { d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" }),
1999
+ /* @__PURE__ */ jsx14("path", { d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" }),
2000
+ /* @__PURE__ */ jsx14("path", { d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" })
2001
+ ] }) }),
2002
+ /* @__PURE__ */ jsx14("button", { className: "qt-chat-composer-send qt-chat-interrupt-button qt-chat-interrupt-button-raised", "aria-label": "Lower your hand", "aria-pressed": true, children: /* @__PURE__ */ jsxs14("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2003
+ /* @__PURE__ */ jsx14("path", { d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" }),
2004
+ /* @__PURE__ */ jsx14("path", { d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" }),
2005
+ /* @__PURE__ */ jsx14("path", { d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" }),
2006
+ /* @__PURE__ */ jsx14("path", { d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" })
2007
+ ] }) }),
2008
+ /* @__PURE__ */ jsx14("button", { className: "qt-chat-composer-send qt-chat-stop-button", "aria-label": "Stop", children: /* @__PURE__ */ jsx14("svg", { width: "20", height: "20", fill: "currentColor", stroke: "currentColor", strokeWidth: 1.5, strokeLinejoin: "round", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx14("polygon", { points: "8.36 3.22 15.64 3.22 20.78 8.36 20.78 15.64 15.64 20.78 8.36 20.78 3.22 15.64 3.22 8.36" }) }) })
2009
+ ] }),
1982
2010
  /* @__PURE__ */ jsxs14("div", { style: { display: "flex", gap: "1rem", maxWidth: "32rem" }, children: [
1983
2011
  /* @__PURE__ */ jsxs14("button", { className: "qt-chat-continue-button", children: [
1984
2012
  /* @__PURE__ */ jsxs14("svg", { className: "w-4 h-4 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
package/dist/index.css CHANGED
@@ -1727,6 +1727,84 @@ body {
1727
1727
  .qt-chat-composer-input:focus-within {
1728
1728
  outline: none;
1729
1729
  }
1730
+ .qt-chat-composer-actions {
1731
+ display: flex;
1732
+ align-items: center;
1733
+ gap: 0.5rem;
1734
+ flex-shrink: 0;
1735
+ }
1736
+ @media (max-width: 639px) {
1737
+ .qt-chat-composer-actions {
1738
+ flex-direction: column;
1739
+ gap: 0.375rem;
1740
+ }
1741
+ .qt-chat-composer-actions .qt-chat-composer-send {
1742
+ height: 2.5rem;
1743
+ width: 2.5rem;
1744
+ }
1745
+ }
1746
+ .qt-chat-composer-send {
1747
+ display: inline-flex;
1748
+ align-items: center;
1749
+ justify-content: center;
1750
+ height: 3rem;
1751
+ width: 3rem;
1752
+ border-radius: 9999px;
1753
+ transition: all 200ms;
1754
+ cursor: pointer;
1755
+ background: var(--qt-button-primary-bg);
1756
+ color: var(--qt-button-primary-fg);
1757
+ box-shadow: var(--qt-button-primary-shadow);
1758
+ }
1759
+ .qt-chat-composer-send:focus-visible {
1760
+ outline: none;
1761
+ box-shadow: 0 0 0 2px var(--color-background), 0 0 0 4px var(--color-ring);
1762
+ }
1763
+ .qt-chat-composer-send:disabled {
1764
+ opacity: 0.5;
1765
+ cursor: not-allowed;
1766
+ }
1767
+ .qt-chat-composer-send:hover:not(:disabled) {
1768
+ background: var(--qt-button-primary-hover-bg);
1769
+ }
1770
+ .qt-chat-continue-button {
1771
+ background: var(--qt-status-info-bg);
1772
+ color: var(--qt-status-info-fg);
1773
+ border: 1px solid var(--qt-status-info-border);
1774
+ }
1775
+ .qt-chat-stop-button {
1776
+ background: var(--qt-status-danger-bg);
1777
+ color: var(--qt-status-danger-fg);
1778
+ border: 1px solid var(--qt-status-danger-border);
1779
+ }
1780
+ .qt-chat-stop-button:hover:not(:disabled) {
1781
+ background: color-mix(in srgb, var(--qt-status-danger-bg) 70%, black);
1782
+ }
1783
+ .qt-chat-interrupt-button {
1784
+ background: var(--qt-status-warning-bg);
1785
+ color: var(--qt-status-warning-fg);
1786
+ border: 1px solid var(--qt-status-warning-border);
1787
+ }
1788
+ .qt-chat-interrupt-button:hover:not(:disabled) {
1789
+ background: color-mix(in srgb, var(--qt-status-warning-bg) 70%, black);
1790
+ }
1791
+ .qt-chat-interrupt-button-raised {
1792
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--qt-status-warning-border) 45%, transparent);
1793
+ animation: qt-hand-raised-pulse 1.6s ease-in-out infinite;
1794
+ }
1795
+ @keyframes qt-hand-raised-pulse {
1796
+ 0%, 100% {
1797
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--qt-status-warning-border) 45%, transparent);
1798
+ }
1799
+ 50% {
1800
+ box-shadow: 0 0 0 6px color-mix(in srgb, var(--qt-status-warning-border) 15%, transparent);
1801
+ }
1802
+ }
1803
+ @media (prefers-reduced-motion: reduce) {
1804
+ .qt-chat-interrupt-button-raised {
1805
+ animation: none;
1806
+ }
1807
+ }
1730
1808
  .qt-lexical-contenteditable {
1731
1809
  overflow-y: auto;
1732
1810
  position: relative;
package/dist/index.js CHANGED
@@ -235,7 +235,7 @@ var ICON_GROUPS = [
235
235
  },
236
236
  {
237
237
  category: "Media",
238
- names: ["image", "camera", "play", "pause", "stop", "zoom-in", "zoom-out"]
238
+ names: ["image", "camera", "play", "pause", "stop", "stop-sign", "hand-raised", "zoom-in", "zoom-out"]
239
239
  },
240
240
  {
241
241
  category: "Content & sidebar navigation",
@@ -2089,6 +2089,34 @@ var Chat = () => {
2089
2089
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
2090
2090
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Chat Control Buttons" }),
2091
2091
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { style: { color: "var(--color-muted-foreground)", marginBottom: "1rem" }, children: "Continue and stop buttons for controlling AI response generation." }),
2092
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { style: { color: "var(--color-muted-foreground)", marginBottom: "1rem", fontSize: "0.875rem" }, children: [
2093
+ "The composer's action trio while a character is speaking: Send (disabled), the soft interrupt ",
2094
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { children: ".qt-chat-interrupt-button" }),
2095
+ " (shown idle, then raised with",
2096
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { children: ".qt-chat-interrupt-button-raised" }),
2097
+ "), and the hard ",
2098
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { children: ".qt-chat-stop-button" }),
2099
+ "."
2100
+ ] }),
2101
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "qt-chat-composer-actions", style: { marginBottom: "1.5rem" }, children: [
2102
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "qt-chat-composer-send", "aria-label": "Send message", disabled: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2103
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
2104
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
2105
+ ] }) }),
2106
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "qt-chat-composer-send qt-chat-interrupt-button", "aria-label": "Raise your hand to interrupt", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2107
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" }),
2108
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" }),
2109
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" }),
2110
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" })
2111
+ ] }) }),
2112
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "qt-chat-composer-send qt-chat-interrupt-button qt-chat-interrupt-button-raised", "aria-label": "Lower your hand", "aria-pressed": true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2113
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" }),
2114
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" }),
2115
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" }),
2116
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" })
2117
+ ] }) }),
2118
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "qt-chat-composer-send qt-chat-stop-button", "aria-label": "Stop", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { width: "20", height: "20", fill: "currentColor", stroke: "currentColor", strokeWidth: 1.5, strokeLinejoin: "round", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("polygon", { points: "8.36 3.22 15.64 3.22 20.78 8.36 20.78 15.64 15.64 20.78 8.36 20.78 3.22 15.64 3.22 8.36" }) }) })
2119
+ ] }),
2092
2120
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", gap: "1rem", maxWidth: "32rem" }, children: [
2093
2121
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("button", { className: "qt-chat-continue-button", children: [
2094
2122
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { className: "w-4 h-4 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
package/dist/index.mjs CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  ThemeComparison,
22
22
  Typography,
23
23
  Workspace
24
- } from "./chunk-MZGSNC6E.mjs";
24
+ } from "./chunk-KJAOSO6L.mjs";
25
25
  import "./chunk-WUKYLWAZ.mjs";
26
26
 
27
27
  // src/preview.tsx
@@ -172,7 +172,7 @@ var ICON_GROUPS = [
172
172
  },
173
173
  {
174
174
  category: "Media",
175
- names: ["image", "camera", "play", "pause", "stop", "zoom-in", "zoom-out"]
175
+ names: ["image", "camera", "play", "pause", "stop", "stop-sign", "hand-raised", "zoom-in", "zoom-out"]
176
176
  },
177
177
  {
178
178
  category: "Content & sidebar navigation",
@@ -2026,6 +2026,34 @@ var Chat = () => {
2026
2026
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
2027
2027
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Chat Control Buttons" }),
2028
2028
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { style: { color: "var(--color-muted-foreground)", marginBottom: "1rem" }, children: "Continue and stop buttons for controlling AI response generation." }),
2029
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { style: { color: "var(--color-muted-foreground)", marginBottom: "1rem", fontSize: "0.875rem" }, children: [
2030
+ "The composer's action trio while a character is speaking: Send (disabled), the soft interrupt ",
2031
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { children: ".qt-chat-interrupt-button" }),
2032
+ " (shown idle, then raised with",
2033
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { children: ".qt-chat-interrupt-button-raised" }),
2034
+ "), and the hard ",
2035
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { children: ".qt-chat-stop-button" }),
2036
+ "."
2037
+ ] }),
2038
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "qt-chat-composer-actions", style: { marginBottom: "1.5rem" }, children: [
2039
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "qt-chat-composer-send", "aria-label": "Send message", disabled: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2040
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
2041
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
2042
+ ] }) }),
2043
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "qt-chat-composer-send qt-chat-interrupt-button", "aria-label": "Raise your hand to interrupt", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2044
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" }),
2045
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" }),
2046
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" }),
2047
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" })
2048
+ ] }) }),
2049
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "qt-chat-composer-send qt-chat-interrupt-button qt-chat-interrupt-button-raised", "aria-label": "Lower your hand", "aria-pressed": true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [
2050
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" }),
2051
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" }),
2052
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" }),
2053
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" })
2054
+ ] }) }),
2055
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "qt-chat-composer-send qt-chat-stop-button", "aria-label": "Stop", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "20", height: "20", fill: "currentColor", stroke: "currentColor", strokeWidth: 1.5, strokeLinejoin: "round", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("polygon", { points: "8.36 3.22 15.64 3.22 20.78 8.36 20.78 15.64 15.64 20.78 8.36 20.78 3.22 15.64 3.22 8.36" }) }) })
2056
+ ] }),
2029
2057
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", gap: "1rem", maxWidth: "32rem" }, children: [
2030
2058
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { className: "qt-chat-continue-button", children: [
2031
2059
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { className: "w-4 h-4 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
@@ -21,7 +21,7 @@ import {
21
21
  ThemeComparison,
22
22
  Typography,
23
23
  Workspace
24
- } from "../chunk-MZGSNC6E.mjs";
24
+ } from "../chunk-KJAOSO6L.mjs";
25
25
  import "../chunk-WUKYLWAZ.mjs";
26
26
  export {
27
27
  Avatars,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quilltap/theme-storybook",
3
- "version": "1.0.75",
3
+ "version": "1.0.76",
4
4
  "description": "Storybook preset and stories for developing Quilltap theme plugins",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -2098,6 +2098,95 @@
2098
2098
  outline: none;
2099
2099
  }
2100
2100
 
2101
+ /* Composer action buttons: Send, the soft interrupt (raise a hand) and the
2102
+ hard Stop. Mirrors app/styles/qt-components/_chat.css. */
2103
+ .qt-chat-composer-actions {
2104
+ display: flex;
2105
+ align-items: center;
2106
+ gap: 0.5rem;
2107
+ flex-shrink: 0;
2108
+ }
2109
+
2110
+ @media (max-width: 639px) {
2111
+ .qt-chat-composer-actions {
2112
+ flex-direction: column;
2113
+ gap: 0.375rem;
2114
+ }
2115
+
2116
+ .qt-chat-composer-actions .qt-chat-composer-send {
2117
+ height: 2.5rem;
2118
+ width: 2.5rem;
2119
+ }
2120
+ }
2121
+
2122
+ .qt-chat-composer-send {
2123
+ display: inline-flex;
2124
+ align-items: center;
2125
+ justify-content: center;
2126
+ height: 3rem;
2127
+ width: 3rem;
2128
+ border-radius: 9999px;
2129
+ transition: all 200ms;
2130
+ cursor: pointer;
2131
+ background: var(--qt-button-primary-bg);
2132
+ color: var(--qt-button-primary-fg);
2133
+ box-shadow: var(--qt-button-primary-shadow);
2134
+ }
2135
+
2136
+ .qt-chat-composer-send:focus-visible {
2137
+ outline: none;
2138
+ box-shadow: 0 0 0 2px var(--color-background), 0 0 0 4px var(--color-ring);
2139
+ }
2140
+
2141
+ .qt-chat-composer-send:disabled {
2142
+ opacity: 0.5;
2143
+ cursor: not-allowed;
2144
+ }
2145
+
2146
+ .qt-chat-composer-send:hover:not(:disabled) {
2147
+ background: var(--qt-button-primary-hover-bg);
2148
+ }
2149
+
2150
+ .qt-chat-continue-button {
2151
+ background: var(--qt-status-info-bg);
2152
+ color: var(--qt-status-info-fg);
2153
+ border: 1px solid var(--qt-status-info-border);
2154
+ }
2155
+
2156
+ .qt-chat-stop-button {
2157
+ background: var(--qt-status-danger-bg);
2158
+ color: var(--qt-status-danger-fg);
2159
+ border: 1px solid var(--qt-status-danger-border);
2160
+ }
2161
+
2162
+ .qt-chat-stop-button:hover:not(:disabled) {
2163
+ background: color-mix(in srgb, var(--qt-status-danger-bg) 70%, black);
2164
+ }
2165
+
2166
+ .qt-chat-interrupt-button {
2167
+ background: var(--qt-status-warning-bg);
2168
+ color: var(--qt-status-warning-fg);
2169
+ border: 1px solid var(--qt-status-warning-border);
2170
+ }
2171
+
2172
+ .qt-chat-interrupt-button:hover:not(:disabled) {
2173
+ background: color-mix(in srgb, var(--qt-status-warning-bg) 70%, black);
2174
+ }
2175
+
2176
+ .qt-chat-interrupt-button-raised {
2177
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--qt-status-warning-border) 45%, transparent);
2178
+ animation: qt-hand-raised-pulse 1.6s ease-in-out infinite;
2179
+ }
2180
+
2181
+ @keyframes qt-hand-raised-pulse {
2182
+ 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--qt-status-warning-border) 45%, transparent); }
2183
+ 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--qt-status-warning-border) 15%, transparent); }
2184
+ }
2185
+
2186
+ @media (prefers-reduced-motion: reduce) {
2187
+ .qt-chat-interrupt-button-raised { animation: none; }
2188
+ }
2189
+
2101
2190
  /* Lexical editor rich text node styles */
2102
2191
  .qt-lexical-contenteditable {
2103
2192
  overflow-y: auto;
@@ -579,6 +579,40 @@ export const Chat: React.FC = () => {
579
579
  <p style={{ color: 'var(--color-muted-foreground)', marginBottom: '1rem' }}>
580
580
  Continue and stop buttons for controlling AI response generation.
581
581
  </p>
582
+ <p style={{ color: 'var(--color-muted-foreground)', marginBottom: '1rem', fontSize: '0.875rem' }}>
583
+ The composer&apos;s action trio while a character is speaking: Send (disabled),
584
+ the soft interrupt <code>.qt-chat-interrupt-button</code> (shown idle, then raised with
585
+ <code>.qt-chat-interrupt-button-raised</code>), and the hard <code>.qt-chat-stop-button</code>.
586
+ </p>
587
+ <div className="qt-chat-composer-actions" style={{ marginBottom: '1.5rem' }}>
588
+ <button className="qt-chat-composer-send" aria-label="Send message" disabled>
589
+ <svg width="20" height="20" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" viewBox="0 0 24 24">
590
+ <line x1="22" y1="2" x2="11" y2="13" />
591
+ <polygon points="22 2 15 22 11 13 2 9 22 2" />
592
+ </svg>
593
+ </button>
594
+ <button className="qt-chat-composer-send qt-chat-interrupt-button" aria-label="Raise your hand to interrupt">
595
+ <svg width="20" height="20" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" viewBox="0 0 24 24">
596
+ <path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" />
597
+ <path d="M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" />
598
+ <path d="M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" />
599
+ <path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" />
600
+ </svg>
601
+ </button>
602
+ <button className="qt-chat-composer-send qt-chat-interrupt-button qt-chat-interrupt-button-raised" aria-label="Lower your hand" aria-pressed>
603
+ <svg width="20" height="20" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" viewBox="0 0 24 24">
604
+ <path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" />
605
+ <path d="M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" />
606
+ <path d="M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" />
607
+ <path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" />
608
+ </svg>
609
+ </button>
610
+ <button className="qt-chat-composer-send qt-chat-stop-button" aria-label="Stop">
611
+ <svg width="20" height="20" fill="currentColor" stroke="currentColor" strokeWidth={1.5} strokeLinejoin="round" viewBox="0 0 24 24">
612
+ <polygon points="8.36 3.22 15.64 3.22 20.78 8.36 20.78 15.64 15.64 20.78 8.36 20.78 3.22 15.64 3.22 8.36" />
613
+ </svg>
614
+ </button>
615
+ </div>
582
616
  <div style={{ display: 'flex', gap: '1rem', maxWidth: '32rem' }}>
583
617
  <button className="qt-chat-continue-button">
584
618
  <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -40,7 +40,7 @@ const ICON_GROUPS: IconGroup[] = [
40
40
  },
41
41
  {
42
42
  category: 'Media',
43
- names: ['image', 'camera', 'play', 'pause', 'stop', 'zoom-in', 'zoom-out'],
43
+ names: ['image', 'camera', 'play', 'pause', 'stop', 'stop-sign', 'hand-raised', 'zoom-in', 'zoom-out'],
44
44
  },
45
45
  {
46
46
  category: 'Content & sidebar navigation',