@mhosaic/feedback 0.7.1 → 0.7.2

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.
@@ -605,8 +605,28 @@ import { useCallback } from "preact/hooks";
605
605
 
606
606
  // src/widget/Fab.tsx
607
607
  import { jsx } from "preact/jsx-runtime";
608
+ function ChatBubbleIcon() {
609
+ return /* @__PURE__ */ jsx(
610
+ "svg",
611
+ {
612
+ width: "24",
613
+ height: "24",
614
+ viewBox: "0 0 24 24",
615
+ fill: "none",
616
+ "aria-hidden": "true",
617
+ focusable: "false",
618
+ children: /* @__PURE__ */ jsx(
619
+ "path",
620
+ {
621
+ d: "M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z",
622
+ fill: "currentColor"
623
+ }
624
+ )
625
+ }
626
+ );
627
+ }
608
628
  function Fab({ label, onClick }) {
609
- return /* @__PURE__ */ jsx("button", { type: "button", class: "fab", "aria-label": label, onClick, children: "\u{1F4AC}" });
629
+ return /* @__PURE__ */ jsx("button", { type: "button", class: "fab", "aria-label": label, title: label, onClick, children: /* @__PURE__ */ jsx(ChatBubbleIcon, {}) });
610
630
  }
611
631
 
612
632
  // src/widget/Form.tsx
@@ -1601,28 +1621,60 @@ var WIDGET_STYLES = `
1601
1621
  }
1602
1622
  }
1603
1623
 
1624
+ /* FAB \u2014 56px (Material standard), two-layer elevation, scale-on-press,
1625
+ custom SVG icon (no emoji \u2014 emoji renders inconsistently across OSes
1626
+ and can't inherit color). */
1604
1627
  .fab {
1605
1628
  position: fixed;
1606
1629
  bottom: 24px;
1607
1630
  right: 24px;
1608
- width: 52px;
1609
- height: 52px;
1631
+ width: 56px;
1632
+ height: 56px;
1610
1633
  border-radius: 999px;
1611
1634
  background: var(--mfb-accent);
1612
1635
  color: var(--mfb-accent-contrast);
1613
1636
  border: none;
1614
1637
  cursor: pointer;
1615
- box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
1616
- font-size: 22px;
1638
+ /* Two-layer elevation: ambient (soft, large) + key (tighter, near). */
1639
+ box-shadow:
1640
+ 0 4px 12px rgba(0, 0, 0, 0.08),
1641
+ 0 2px 4px rgba(0, 0, 0, 0.12);
1617
1642
  display: grid;
1618
1643
  place-items: center;
1619
- transition: transform 120ms ease, box-shadow 120ms ease;
1644
+ transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1),
1645
+ box-shadow 180ms cubic-bezier(0.4, 0, 0.2, 1);
1646
+ }
1647
+
1648
+ .fab:hover {
1649
+ transform: translateY(-2px);
1650
+ box-shadow:
1651
+ 0 8px 24px rgba(0, 0, 0, 0.12),
1652
+ 0 3px 6px rgba(0, 0, 0, 0.16);
1653
+ }
1654
+ .fab:active {
1655
+ transform: translateY(0) scale(0.96);
1656
+ box-shadow:
1657
+ 0 3px 8px rgba(0, 0, 0, 0.10),
1658
+ 0 1px 2px rgba(0, 0, 0, 0.14);
1659
+ }
1660
+ .fab:focus-visible {
1661
+ outline: 2px solid var(--mfb-accent-contrast);
1662
+ outline-offset: 3px;
1663
+ box-shadow:
1664
+ 0 0 0 4px var(--mfb-accent),
1665
+ 0 4px 12px rgba(0, 0, 0, 0.08),
1666
+ 0 2px 4px rgba(0, 0, 0, 0.12);
1667
+ }
1668
+ @media (prefers-color-scheme: dark) {
1669
+ /* Slightly desaturate so the FAB doesn't glow against dark backgrounds. */
1670
+ .fab { box-shadow:
1671
+ 0 4px 12px rgba(0, 0, 0, 0.32),
1672
+ 0 2px 4px rgba(0, 0, 0, 0.40); }
1673
+ }
1674
+ @media (prefers-reduced-motion: reduce) {
1675
+ .fab { transition: none; }
1676
+ .fab:hover, .fab:active { transform: none; }
1620
1677
  }
1621
-
1622
- .fab:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.24); }
1623
- .fab:active { transform: translateY(0) scale(0.96); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.22); }
1624
- .fab:focus-visible { outline: 2px solid #fff; outline-offset: 3px; box-shadow: 0 0 0 4px var(--mfb-accent), 0 4px 14px rgba(0, 0, 0, 0.18); }
1625
- @media (prefers-reduced-motion: reduce) { .fab { transition: none; } .fab:hover, .fab:active { transform: none; } }
1626
1678
 
1627
1679
  .backdrop {
1628
1680
  position: fixed;
@@ -1636,11 +1688,16 @@ var WIDGET_STYLES = `
1636
1688
  background: var(--mfb-bg);
1637
1689
  border-radius: calc(var(--mfb-radius) * 1.5);
1638
1690
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.25);
1639
- width: min(420px, 92vw);
1640
- padding: 20px;
1691
+ /* 440px is the industry sweet spot for short forms \u2014 Linear, Plain,
1692
+ Sentry all sit in the 420-480 range. 92vw caps it on narrow screens. */
1693
+ width: min(440px, 92vw);
1694
+ /* 24px is shadcn's default; gives every input room to breathe. */
1695
+ padding: 24px;
1641
1696
  display: flex;
1642
1697
  flex-direction: column;
1643
- gap: 12px;
1698
+ /* 18px between major blocks (h2 \u2192 field \u2192 field \u2192 footer). Within a
1699
+ field group, .field uses a tighter 6px label-to-input gap. */
1700
+ gap: 18px;
1644
1701
  position: relative;
1645
1702
  /* Cap modal height on short viewports (mobile landscape, tiny laptops)
1646
1703
  so the form scrolls inside the modal rather than overflowing the
@@ -1649,7 +1706,23 @@ var WIDGET_STYLES = `
1649
1706
  overflow-y: auto;
1650
1707
  }
1651
1708
 
1652
- .modal h2 { margin: 0 0 4px; font-size: 18px; font-weight: 600; padding-right: 28px; }
1709
+ .modal h2 {
1710
+ margin: 0;
1711
+ font-size: 17px;
1712
+ font-weight: 600;
1713
+ padding-right: 28px;
1714
+ letter-spacing: -0.01em;
1715
+ }
1716
+
1717
+ /* The form sits inside .modal as a single flex child, so the modal-level
1718
+ gap doesn't separate the form's *own* children. Mirror the column +
1719
+ gap pattern on the form itself; 22px lands in the middle of the
1720
+ 20-24px field-to-field range the design critic recommended. */
1721
+ .modal form {
1722
+ display: flex;
1723
+ flex-direction: column;
1724
+ gap: 22px;
1725
+ }
1653
1726
 
1654
1727
  .modal-close {
1655
1728
  position: absolute;
@@ -1671,15 +1744,22 @@ var WIDGET_STYLES = `
1671
1744
  .modal-close:hover { background: var(--mfb-surface); color: var(--mfb-text); }
1672
1745
  .modal-close:focus-visible { outline: 2px solid var(--mfb-accent); outline-offset: 2px; }
1673
1746
 
1674
- .field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
1747
+ /* Each field group: label (13px medium, muted) + input (14px regular)
1748
+ stacked with a 6px gap. The 18px modal-level gap separates groups. */
1749
+ .field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
1675
1750
 
1676
- .field label { color: var(--mfb-text-muted); }
1751
+ .field label {
1752
+ color: var(--mfb-text-muted);
1753
+ font-weight: 500;
1754
+ font-size: 12px;
1755
+ letter-spacing: 0.01em;
1756
+ }
1677
1757
 
1678
1758
  .field input, .field select, .field textarea {
1679
1759
  font-family: inherit;
1680
1760
  font-size: 14px;
1681
1761
  color: inherit;
1682
- padding: 8px 10px;
1762
+ padding: 9px 12px;
1683
1763
  border: 1px solid var(--mfb-border);
1684
1764
  border-radius: var(--mfb-radius);
1685
1765
  background: var(--mfb-surface);
@@ -1703,28 +1783,44 @@ var WIDGET_STYLES = `
1703
1783
  background-position: right 10px center;
1704
1784
  }
1705
1785
 
1706
- .field textarea { min-height: 88px; resize: vertical; }
1786
+ .field textarea { min-height: 96px; resize: vertical; line-height: 1.45; }
1707
1787
 
1708
- .row { display: flex; gap: 8px; }
1788
+ .row { display: flex; gap: 12px; }
1709
1789
  .row > * { flex: 1; }
1710
1790
 
1711
- .actions { display: flex; gap: 8px; justify-content: flex-end; padding-top: 8px; }
1791
+ /* Footer separation: border-top + 16px breathing room, Stripe/Linear pattern.
1792
+ Stops Cancel/Send from floating against the dropzone or page-URL footer. */
1793
+ .actions {
1794
+ display: flex;
1795
+ gap: 8px;
1796
+ justify-content: flex-end;
1797
+ padding-top: 16px;
1798
+ margin-top: 4px;
1799
+ border-top: 1px solid var(--mfb-border);
1800
+ }
1712
1801
 
1713
1802
  .btn {
1714
- padding: 8px 14px;
1803
+ padding: 9px 16px;
1715
1804
  border-radius: var(--mfb-radius);
1716
1805
  border: 1px solid var(--mfb-border);
1717
1806
  background: var(--mfb-bg);
1718
1807
  color: var(--mfb-text);
1719
1808
  font: inherit;
1809
+ font-weight: 500;
1720
1810
  cursor: pointer;
1811
+ transition: background 120ms ease, border-color 120ms ease;
1721
1812
  }
1813
+ .btn:hover { background: var(--mfb-surface); }
1722
1814
 
1723
1815
  .btn--primary {
1724
1816
  background: var(--mfb-accent);
1725
1817
  color: var(--mfb-accent-contrast);
1726
1818
  border-color: var(--mfb-accent);
1727
1819
  }
1820
+ .btn--primary:hover {
1821
+ background: color-mix(in srgb, var(--mfb-accent) 88%, black);
1822
+ border-color: color-mix(in srgb, var(--mfb-accent) 88%, black);
1823
+ }
1728
1824
 
1729
1825
  .btn[disabled] { opacity: 0.6; cursor: not-allowed; }
1730
1826
 
@@ -1748,7 +1844,7 @@ var WIDGET_STYLES = `
1748
1844
  .screenshot-dropzone {
1749
1845
  border: 1px dashed var(--mfb-border);
1750
1846
  border-radius: var(--mfb-radius);
1751
- padding: 14px 12px;
1847
+ padding: 18px 14px;
1752
1848
  text-align: center;
1753
1849
  cursor: pointer;
1754
1850
  background: var(--mfb-surface);
@@ -1821,12 +1917,12 @@ var WIDGET_STYLES = `
1821
1917
  text-transform: uppercase;
1822
1918
  font-weight: 600;
1823
1919
  letter-spacing: 0.04em;
1920
+ font-size: 10px;
1824
1921
  }
1825
1922
  .page-context-url {
1826
1923
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1827
- background: var(--mfb-surface);
1828
- padding: 4px 6px;
1829
- border-radius: 4px;
1924
+ font-size: 11px;
1925
+ color: var(--mfb-text-muted);
1830
1926
  flex: 1;
1831
1927
  overflow: hidden;
1832
1928
  text-overflow: ellipsis;
@@ -2486,4 +2582,4 @@ function createFeedback(config) {
2486
2582
  export {
2487
2583
  createFeedback
2488
2584
  };
2489
- //# sourceMappingURL=chunk-F3FVKCBE.mjs.map
2585
+ //# sourceMappingURL=chunk-2TLTE2VZ.mjs.map