@sphoro/bugcatch-web-sdk 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import { c as de, s as we, a as ke, R as be, h as P, n as $e, b as Se, d as Qe, e as te, f as G, g as W, r as Le, v as Te, i as ze, S as Ee, U as Me, j as qe, k as Ce, l as He } from "./bugcatch-core.es.js";
2
- const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>', Ae = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>', fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>', pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>', ge = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>', Re = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', Ve = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>', ne = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>', De = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>', X = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.5c.5 4.6 2.9 7 7.5 7.5v.1c-4.6.5-7 2.9-7.5 7.5h-.1c-.5-4.6-2.9-7-7.5-7.5V10c4.6-.5 7-2.9 7.5-7.5z"/><path d="M18.6 15.2c.2 1.9 1.2 2.9 3.1 3.1v.1c-1.9.2-2.9 1.2-3.1 3.1h-.1c-.2-1.9-1.2-2.9-3.1-3.1v-.1c1.9-.2 2.9-1.2 3.1-3.1z" opacity=".7"/></svg>', je = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>', Oe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>', Be = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', Ne = `
1
+ import { s as Le, m as Qe, a as Te, c as ce, b as qe, d as Ee, R as be, h as F, n as ze, e as Me, f as Ce, g as te, i as G, j as P, r as He, v as Ae, k as Re, S as Ie, U as De, l as Ve, o as je, p as Oe } from "./bugcatch-core.es.js";
2
+ const Ne = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>', Be = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>', fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>', pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>', ge = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>', Ye = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', We = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>', re = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>', Pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>', Fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>', me = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>', Ke = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>', Ue = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', Ze = `
3
3
  @keyframes bc-fade-in { from { opacity: 0 } to { opacity: 1 } }
4
4
  @keyframes bc-fade-out { to { opacity: 0 } }
5
5
  @keyframes bc-panel-in { from { opacity: 0; transform: translateY(14px) scale(.965) } to { opacity: 1; transform: none } }
@@ -15,9 +15,12 @@ const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-wi
15
15
  @keyframes bc-shimmer { from { background-position: 200% 0 } to { background-position: -200% 0 } }
16
16
 
17
17
  /* ---------- scrim + panel ---------- */
18
+ /* Still modal — focus stays in the panel and a click outside closes it — but
19
+ the host's page only dims enough to say so. It is their product, and the
20
+ visitor is reporting something about what is on it. */
18
21
  .scrim {
19
22
  position: fixed; inset: 0; z-index: 2147483001;
20
- background: rgba(10,12,16,.32);
23
+ background: rgba(14,14,16,.14);
21
24
  animation: bc-fade-in 200ms ease both;
22
25
  }
23
26
  .scrim.closing { animation: bc-fade-out 170ms ease both; }
@@ -29,12 +32,11 @@ const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-wi
29
32
  .panel {
30
33
  position: fixed;
31
34
  display: flex; flex-direction: column;
32
- width: calc(100vw - 40px); max-width: 420px;
35
+ width: calc(100vw - 40px); max-width: 400px;
33
36
  max-height: calc(100vh - var(--bc-dock-h, 84px) - 52px);
34
37
  overflow: hidden;
35
38
  background: var(--bc-bg); color: var(--bc-fg);
36
39
  border-radius: var(--bc-r-xl); box-shadow: var(--bc-shadow);
37
- border: 1px solid color-mix(in srgb, var(--bc-border) 70%, transparent);
38
40
  animation: bc-panel-in 340ms var(--bc-ease) both;
39
41
  }
40
42
  /* A conversation wants a height of its own, so the thread fills the panel
@@ -49,57 +51,58 @@ const Ie = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-wi
49
51
  /* ---------- header ---------- */
50
52
  .head {
51
53
  flex: none; position: relative;
52
- display: flex; align-items: center; gap: 12px;
53
- padding: 16px 14px 14px var(--bc-pad);
54
- background: linear-gradient(180deg, var(--bc-accent-soft), var(--bc-bg));
54
+ display: flex; align-items: center; gap: 11px;
55
+ padding: 14px 10px 13px var(--bc-pad);
56
+ background: var(--bc-bg);
55
57
  border-bottom: 1px solid var(--bc-border);
56
58
  }
57
- .head .mark, .avatar {
58
- flex: none; display: grid; place-items: center; position: relative;
59
- width: 38px; height: 38px; border-radius: 50%;
60
- background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
61
- color: var(--bc-on-accent); font-size: 19px;
62
- box-shadow: 0 4px 12px color-mix(in srgb, var(--bc-accent) 30%, transparent);
63
- }
64
- /* The little "online" dot says someone — or something — is on the other end. */
65
- .head .mark::after {
66
- content: ''; position: absolute; right: -1px; bottom: -1px;
67
- width: 11px; height: 11px; border-radius: 50%;
68
- background: #22c55e; border: 2px solid var(--bc-bg);
69
- }
59
+ .head .mark { width: 32px; }
60
+ /* The assistant asking its one follow-up wears the same orb, smaller. */
61
+ .avatar.orb { width: 26px; }
70
62
  .head .titles { flex: 1; min-width: 0; }
71
63
  .head h2 {
72
- margin: 0 0 2px; font-size: var(--bc-fs-lg); font-weight: 680; letter-spacing: -.02em; line-height: 1.25;
64
+ margin: 0 0 1px; font-size: var(--bc-fs-lg); font-weight: 600; letter-spacing: -.015em; line-height: 1.3;
65
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
66
+ }
67
+ .head p {
68
+ margin: 0; font-size: var(--bc-fs-sm); line-height: 1.4; color: var(--bc-muted);
73
69
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
74
70
  }
75
- .head p { margin: 0; font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted); }
76
71
  .icon-btn {
77
72
  flex: none; display: grid; place-items: center;
78
73
  width: 32px; height: 32px; padding: 0; font-size: 16px;
79
- border: none; border-radius: 10px; background: none; color: var(--bc-muted);
74
+ border: none; border-radius: 999px; background: none; color: var(--bc-muted);
80
75
  cursor: pointer; transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
81
76
  }
82
77
  .icon-btn:hover { background: color-mix(in srgb, var(--bc-fg) 7%, transparent); color: var(--bc-fg); }
83
78
  .icon-btn:active { transform: scale(.92); }
84
79
  .icon-btn.back { margin: 0 -6px 0 -8px; }
80
+ /* The theme button holds all three glyphs; the host's class picks one. */
81
+ .icon-btn.theme { font-size: 15px; margin-right: -4px; }
82
+ .icon-btn.theme > span { display: none; }
83
+ :host(.bc-light) .icon-btn.theme .m-light,
84
+ :host(.bc-dark) .icon-btn.theme .m-dark,
85
+ :host(.bc-auto) .icon-btn.theme .m-auto { display: block; }
85
86
 
86
87
  .body {
87
88
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
88
- padding: 16px var(--bc-pad) 6px;
89
+ padding: 14px var(--bc-pad) 4px;
89
90
  }
90
91
 
91
- label { display: block; font-size: var(--bc-fs-sm); font-weight: 620; color: var(--bc-fg); margin-bottom: 7px; }
92
+ label { display: block; font-size: 13px; font-weight: 560; color: var(--bc-fg); margin-bottom: 6px; letter-spacing: -.005em; }
92
93
  label .opt { font-weight: 450; color: var(--bc-faint); }
94
+ /* Fields are stone wells that turn white when you are in them, the way the
95
+ rest of the product's forms do. */
93
96
  input[type=text], input[type=email], textarea {
94
- width: 100%; padding: 11px 13px; font-size: var(--bc-fs-md); line-height: 1.45;
95
- color: var(--bc-fg); background: var(--bc-elevated);
96
- border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
97
+ width: 100%; padding: 10px 12px; font-size: var(--bc-fs-md); line-height: 1.45;
98
+ color: var(--bc-fg); background: var(--bc-stone);
99
+ border: 1px solid transparent; border-radius: var(--bc-r-md);
97
100
  transition: border-color 160ms, box-shadow 160ms, background 160ms;
98
101
  }
99
102
  input[type=text]::placeholder, input[type=email]::placeholder, textarea::placeholder { color: var(--bc-faint); }
100
- input[type=text]:hover, input[type=email]:hover, textarea:hover { border-color: color-mix(in srgb, var(--bc-fg) 18%, var(--bc-border)); }
103
+ input[type=text]:hover, input[type=email]:hover, textarea:hover { border-color: var(--bc-border); }
101
104
  input[type=text]:focus, input[type=email]:focus, textarea:focus {
102
- outline: none; border-color: var(--bc-accent); box-shadow: var(--bc-ring);
105
+ outline: none; background: var(--bc-bg); border-color: var(--bc-accent); box-shadow: var(--bc-ring);
103
106
  }
104
107
  input.invalid, input.invalid:focus, textarea.invalid {
105
108
  border-color: var(--bc-danger); animation: bc-nudge 240ms ease;
@@ -111,8 +114,8 @@ input.invalid, input.invalid:focus, textarea.invalid {
111
114
  animation: bc-rise 200ms var(--bc-ease) both;
112
115
  }
113
116
  .field-err svg { font-size: 13px; flex: none; }
114
- textarea { min-height: 88px; resize: vertical; }
115
- .field { margin-bottom: 16px; }
117
+ textarea { min-height: 76px; resize: vertical; }
118
+ .field { margin-bottom: 14px; }
116
119
  .field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
117
120
  .field-head .count { font-size: var(--bc-fs-xs); color: var(--bc-faint); font-variant-numeric: tabular-nums; }
118
121
 
@@ -122,15 +125,15 @@ textarea { min-height: 88px; resize: vertical; }
122
125
  .compose > .note:has(button) {
123
126
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
124
127
  margin: 0 0 14px; padding: 10px 12px; border-radius: var(--bc-r-md);
125
- background: var(--bc-accent-soft); border: 1px solid var(--bc-accent-line);
128
+ background: var(--bc-subtle); border: 1px solid var(--bc-border);
126
129
  font-size: var(--bc-fs-sm); color: var(--bc-fg);
127
130
  }
128
131
  .compose > .note button {
129
- padding: 5px 11px; font: inherit; font-size: var(--bc-fs-xs); font-weight: 620;
132
+ padding: 5px 11px; font: inherit; font-size: var(--bc-fs-xs); font-weight: 600;
130
133
  border-radius: 999px; cursor: pointer;
131
134
  border: 1px solid var(--bc-accent); background: var(--bc-accent); color: var(--bc-on-accent);
132
135
  }
133
- .compose > .note button[data-discard] { background: transparent; color: var(--bc-muted); border-color: var(--bc-border); }
136
+ .compose > .note button[data-discard] { background: var(--bc-bg); color: var(--bc-fg); border-color: var(--bc-border); }
134
137
 
135
138
  /* ---------- what is already known ----------
136
139
  A help surface in front of the form, not a step in it. Everything here is
@@ -138,58 +141,57 @@ textarea { min-height: 88px; resize: vertical; }
138
141
  leave, tap "this is happening to me too" and leave, or type straight past all
139
142
  of it and file the report they came to file. Nothing is ever in their way,
140
143
  because a reporter who feels handled rather than helped stops reporting. */
141
- .known { margin-bottom: 16px; }
142
- .known .known-h {
143
- margin: 0 0 8px; font-size: 11px; font-weight: 680; letter-spacing: .06em;
144
+ /* One small eyebrow style for every group above the form. */
145
+ .known .known-h, .picks .picks-h {
146
+ margin: 0 0 7px; font-size: 11px; font-weight: 600; letter-spacing: .07em;
144
147
  text-transform: uppercase; color: var(--bc-faint);
145
148
  }
149
+ .known { margin-bottom: 14px; }
150
+ /* Hairline rows on the panel's own white, so they read as a list to scan
151
+ rather than more coloured cards to wade through. */
146
152
  .known .issue {
147
153
  display: flex; align-items: center; gap: 10px;
148
- padding: 10px 12px; margin-bottom: 6px;
149
- background: var(--bc-subtle); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
154
+ padding: 8px 8px 8px 12px; margin-bottom: 6px;
155
+ background: var(--bc-bg); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
150
156
  animation: bc-rise 240ms var(--bc-ease) both;
151
157
  }
152
- .known .issue.is-joined { border-color: color-mix(in srgb, var(--bc-ok) 55%, var(--bc-border)); }
158
+ .known .issue.is-joined { background: color-mix(in srgb, var(--bc-ok) 6%, var(--bc-bg)); }
153
159
  .known .issue .who { flex: 1; min-width: 0; }
154
160
  .known .issue .t {
155
- display: block; font-size: 13px; font-weight: 620; line-height: 1.4;
161
+ display: block; font-size: 13px; font-weight: 560; line-height: 1.4;
156
162
  color: var(--bc-fg); overflow-wrap: anywhere;
157
163
  }
158
164
  .known .issue .meta {
159
- display: block; margin-top: 3px; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted);
165
+ display: block; margin-top: 2px; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted);
160
166
  }
161
167
  .known .issue .join {
162
- flex: none; padding: 7px 12px; font-size: 12px; font-weight: 620;
163
- color: var(--bc-accent); background: var(--bc-bg);
164
- border: 1px solid var(--bc-accent-line); border-radius: 999px; cursor: pointer;
165
- transition: background 160ms, border-color 160ms;
168
+ flex: none; height: 30px; padding: 0 12px; font: inherit; font-size: 12px; font-weight: 560;
169
+ color: var(--bc-fg); background: var(--bc-stone);
170
+ border: 0; border-radius: 999px; cursor: pointer;
171
+ transition: background 160ms, color 160ms;
166
172
  }
167
- .known .issue .join:hover { border-color: var(--bc-accent); background: var(--bc-accent-soft); }
168
- .known .issue .join:disabled { color: var(--bc-ok); border-color: var(--bc-border); background: var(--bc-bg); cursor: default; opacity: 1; }
173
+ .known .issue .join:hover { background: color-mix(in srgb, var(--bc-fg) 12%, var(--bc-stone)); }
174
+ .known .issue .join:disabled { color: var(--bc-ok); background: transparent; cursor: default; opacity: 1; }
169
175
  .known .ask { display: flex; gap: 8px; margin: 2px 0 8px; }
170
176
  .known .ask input { flex: 1; min-width: 0; }
171
177
  .known .ask button { flex: none; }
172
178
  .known .err { margin: 6px 0 0; font-size: 12px; line-height: 1.45; color: var(--bc-danger); }
173
179
 
174
180
  /* ---------- questions the assistant answers by itself ---------- */
175
- .picks { margin-bottom: 16px; }
176
- .picks .picks-h {
177
- margin: 0 0 8px; font-size: 11px; font-weight: 680; letter-spacing: .06em;
178
- text-transform: uppercase; color: var(--bc-faint);
179
- }
180
- .picks .picks-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
181
+ .picks { margin-bottom: 14px; }
182
+ .picks .picks-grid { display: flex; flex-wrap: wrap; gap: 6px; }
181
183
  .picks .pick {
182
- display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
183
- padding: 9px 11px; text-align: left; cursor: pointer; font: inherit;
184
- color: var(--bc-fg); background: var(--bc-subtle);
185
- border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
186
- transition: background 160ms, border-color 160ms, transform 160ms;
184
+ display: inline-flex; align-items: center; max-width: 100%;
185
+ min-height: 32px; padding: 6px 13px; text-align: left; cursor: pointer; font: inherit;
186
+ color: var(--bc-fg); background: var(--bc-stone);
187
+ border: 1px solid transparent; border-radius: 999px;
188
+ transition: background 160ms, border-color 160ms, color 160ms, transform 160ms var(--bc-ease);
187
189
  animation: bc-rise 240ms var(--bc-ease) both;
188
190
  }
189
- .picks .pick:hover { border-color: var(--bc-accent-line); background: var(--bc-accent-soft); }
190
- .picks .pick[aria-pressed="true"] { border-color: var(--bc-accent); background: var(--bc-accent-soft); }
191
- .picks .pick .t { font-size: 13px; font-weight: 620; line-height: 1.35; overflow-wrap: anywhere; }
192
- .picks .pick .h { font-size: var(--bc-fs-xs); line-height: 1.4; color: var(--bc-muted); }
191
+ .picks .pick:hover { background: color-mix(in srgb, var(--bc-fg) 10%, var(--bc-stone)); }
192
+ .picks .pick:active { transform: scale(.97); }
193
+ .picks .pick[aria-pressed="true"] { background: var(--bc-accent); color: var(--bc-on-accent); }
194
+ .picks .pick .t { font-size: 13px; font-weight: 520; line-height: 1.35; overflow-wrap: anywhere; }
193
195
  .picks .picks-note {
194
196
  display: flex; gap: 6px; align-items: flex-start; margin: 8px 0 0;
195
197
  font-size: 12px; line-height: 1.45; color: var(--bc-muted);
@@ -203,18 +205,21 @@ textarea { min-height: 88px; resize: vertical; }
203
205
  strip is the whole panel. */
204
206
  .whoami {
205
207
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
206
- margin-bottom: 16px; padding: 10px 12px;
208
+ margin-bottom: 14px; padding: 9px 12px;
207
209
  font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted);
208
210
  background: var(--bc-subtle); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
209
211
  }
210
212
  .whoami.asking { display: block; padding: 14px; }
213
+ .whoami.asking .row input { background: var(--bc-bg); border-color: var(--bc-border); }
211
214
  .whoami .who { flex: 1; min-width: 0; }
212
215
  .whoami .who strong { color: var(--bc-fg); font-weight: 620; word-break: break-all; }
213
216
  .link {
214
- padding: 0; font: inherit; font-size: var(--bc-fs-sm); font-weight: 620; line-height: 1.45;
215
- color: var(--bc-accent); background: none; border: none; cursor: pointer; border-radius: 4px;
217
+ padding: 0; font: inherit; font-size: var(--bc-fs-sm); font-weight: 560; line-height: 1.45;
218
+ color: var(--bc-fg); background: none; border: none; cursor: pointer; border-radius: 4px;
219
+ text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--bc-fg) 30%, transparent);
220
+ text-underline-offset: 3px;
216
221
  }
217
- .link:hover { text-decoration: underline; text-underline-offset: 2px; }
222
+ .link:hover { text-decoration-color: currentColor; }
218
223
  .link:disabled { color: var(--bc-faint); cursor: default; text-decoration: none; }
219
224
  .whoami .why { margin: 0 0 10px; font-size: var(--bc-fs-sm); line-height: 1.5; color: var(--bc-muted); }
220
225
  .whoami .why strong { color: var(--bc-fg); font-weight: 620; word-break: break-all; }
@@ -231,18 +236,17 @@ textarea { min-height: 88px; resize: vertical; }
231
236
  assistant asking one friendly follow-up, not as a form field that appeared. */
232
237
  .refs {
233
238
  position: relative;
234
- margin-bottom: 16px; padding: 14px;
239
+ margin-bottom: 14px; padding: 14px;
235
240
  font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted);
236
- background: var(--bc-accent-soft);
237
- border: 1px solid var(--bc-accent-line); border-radius: var(--bc-r-lg);
241
+ background: var(--bc-subtle);
242
+ border: 1px solid var(--bc-border); border-radius: var(--bc-r-lg);
238
243
  animation: bc-item-in 280ms var(--bc-ease) both;
239
244
  }
240
245
  .refs .ask-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 11px; }
241
- .refs .ask-head .avatar { width: 28px; height: 28px; font-size: 14px; box-shadow: none; }
242
- .refs .ask-head strong { display: block; font-size: 13.5px; font-weight: 650; color: var(--bc-fg); margin-bottom: 1px; }
246
+ .refs .ask-head strong { display: block; font-size: 13.5px; font-weight: 600; color: var(--bc-fg); margin-bottom: 1px; }
243
247
  .refs .why { margin: 0; font-size: var(--bc-fs-sm); line-height: 1.5; color: var(--bc-muted); }
244
248
  .refs .row { display: flex; gap: 8px; align-items: stretch; }
245
- .refs .row input { flex: 1; min-width: 0; background: var(--bc-bg); }
249
+ .refs .row input { flex: 1; min-width: 0; background: var(--bc-bg); border-color: var(--bc-border); }
246
250
  .refs select {
247
251
  flex: none; max-width: 45%; padding: 10px 10px; font-size: 13px;
248
252
  color: var(--bc-fg); background: var(--bc-bg);
@@ -270,40 +274,44 @@ textarea { min-height: 88px; resize: vertical; }
270
274
  .ref-found svg { width: 14px; height: 14px; flex: none; color: var(--bc-ok); }
271
275
  .ref-found b { font-weight: 600; color: var(--bc-fg); }
272
276
 
273
- /* ---------- severity ---------- */
274
- .seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; padding: 3px; background: var(--bc-subtle); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md); }
277
+ /* ---------- severity ----------
278
+ The segmented control from the product: a stone track, the choice lifted out
279
+ of it on white. */
280
+ .seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; padding: 3px; background: var(--bc-stone); border-radius: 999px; }
275
281
  .seg button {
276
282
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
277
- padding: 8px 4px; font-size: var(--bc-fs-sm); font-weight: 550; line-height: 1;
278
- color: var(--bc-muted); background: none; border: none; border-radius: 9px;
283
+ height: 30px; padding: 0 4px; font: inherit; font-size: var(--bc-fs-sm); font-weight: 520; line-height: 1;
284
+ color: var(--bc-muted); background: none; border: none; border-radius: 999px;
279
285
  cursor: pointer; transition: background 180ms var(--bc-ease), color 180ms, box-shadow 180ms;
280
286
  }
281
- .seg button::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--sev, var(--bc-faint)); opacity: .55; transition: opacity 180ms; }
282
- .seg button[data-prio="LOW"] { --sev: #94a3b8; }
283
- .seg button[data-prio="MEDIUM"] { --sev: #3b82f6; }
284
- .seg button[data-prio="HIGH"] { --sev: #f59e0b; }
285
- .seg button[data-prio="CRITICAL"] { --sev: #ef4444; }
287
+ .seg button::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--sev, var(--bc-faint)); opacity: .5; transition: opacity 180ms; }
288
+ .seg button[data-prio="LOW"] { --sev: var(--bc-ok); }
289
+ .seg button[data-prio="MEDIUM"] { --sev: var(--bc-info); }
290
+ .seg button[data-prio="HIGH"] { --sev: var(--bc-warn); }
291
+ .seg button[data-prio="CRITICAL"] { --sev: var(--bc-danger); }
286
292
  .seg button:hover { color: var(--bc-fg); }
287
293
  .seg button[aria-pressed=true] {
288
- background: var(--bc-raised); color: var(--bc-fg); font-weight: 650;
289
- box-shadow: 0 1px 3px rgba(10,12,16,.14), 0 0 0 1px color-mix(in srgb, var(--bc-border) 60%, transparent);
294
+ background: var(--bc-raised); color: var(--bc-fg); font-weight: 600;
295
+ box-shadow: 0 1px 2px rgba(20,18,14,.10), 0 0 0 .5px rgba(20,18,14,.08);
290
296
  }
291
297
  .seg button[aria-pressed=true]::before { opacity: 1; }
292
298
  .seg button:focus-visible { outline-offset: -2px; }
293
299
 
294
- /* ---------- attachments ---------- */
295
- .tools { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; }
300
+ /* ---------- attachments ----------
301
+ Three ring pills in a row: optional, so they take one line, not a band of
302
+ dashed drop zones. */
303
+ .tools { display: flex; flex-wrap: wrap; gap: 6px; }
296
304
  .tool {
297
- display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
298
- padding: 12px 8px; font-size: 12px; font-weight: 600; line-height: 1;
299
- color: var(--bc-fg); background: var(--bc-elevated);
300
- border: 1px dashed color-mix(in srgb, var(--bc-fg) 20%, var(--bc-border)); border-radius: var(--bc-r-md); cursor: pointer;
305
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
306
+ height: 32px; padding: 0 11px 0 9px; font: inherit; font-size: 12.5px; font-weight: 520; line-height: 1; white-space: nowrap;
307
+ color: var(--bc-fg); background: var(--bc-bg);
308
+ border: 1px solid var(--bc-border); border-radius: 999px; cursor: pointer;
301
309
  transition: border-color 160ms, background 160ms, color 160ms, transform 160ms var(--bc-ease);
302
310
  }
303
- .tool svg { font-size: 19px; color: var(--bc-muted); transition: color 160ms; }
304
- .tool:hover:not(:disabled) { border-color: var(--bc-accent); border-style: solid; background: var(--bc-accent-soft); transform: translateY(-1px); }
305
- .tool:hover:not(:disabled) svg { color: var(--bc-accent); }
306
- .tool:active:not(:disabled) { transform: translateY(0) scale(.98); }
311
+ .tool svg { font-size: 15px; color: var(--bc-muted); transition: color 160ms; }
312
+ .tool:hover:not(:disabled) { background: var(--bc-subtle); border-color: color-mix(in srgb, var(--bc-fg) 20%, var(--bc-border)); }
313
+ .tool:hover:not(:disabled) svg { color: var(--bc-fg); }
314
+ .tool:active:not(:disabled) { transform: scale(.97); }
307
315
  .tool:disabled { opacity: .45; cursor: not-allowed; }
308
316
  .attach-hint { margin: 8px 0 0; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
309
317
 
@@ -354,7 +362,7 @@ textarea { min-height: 88px; resize: vertical; }
354
362
  .foot {
355
363
  flex: none;
356
364
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
357
- padding: 12px var(--bc-pad); border-top: 1px solid var(--bc-border);
365
+ padding: 12px 14px 12px var(--bc-pad); border-top: 1px solid var(--bc-border);
358
366
  background: var(--bc-bg);
359
367
  }
360
368
  .foot .spacer { flex: 1; }
@@ -367,36 +375,39 @@ textarea { min-height: 88px; resize: vertical; }
367
375
  size, and dimming it on top of that left it as a smudge in both themes. */
368
376
  .powered {
369
377
  flex: none; display: flex; align-items: center; justify-content: center; gap: 6px;
370
- padding: 7px var(--bc-pad) 9px; font-size: 10.5px; color: var(--bc-faint);
371
- background: var(--bc-subtle); border-top: 1px solid var(--bc-border);
378
+ padding: 0 var(--bc-pad) 10px; font-size: 10.5px; color: var(--bc-faint);
379
+ background: var(--bc-bg);
372
380
  }
373
381
  .brand-credit { display: flex; align-items: center; transition: color 0.15s; border-radius: 4px; }
374
- .bc-brand { height: 16px; width: auto; display: block; color: var(--bc-brand-ink); }
382
+ .bc-brand { height: 15px; width: auto; display: block; color: var(--bc-brand-ink); }
375
383
  .brand-credit:hover .bc-brand { color: var(--bc-fg); }
384
+ /* The product's two pills: ink for the one thing to do, a white ring for the
385
+ alternative. Flat — no glow, no lift. */
376
386
  button.ghost, button.primary {
377
387
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
378
- height: 38px; padding: 0 15px; font: inherit; font-size: 13px; font-weight: 620; line-height: 1;
388
+ height: 38px; padding: 0 15px; font: inherit; font-size: 13.5px; font-weight: 560; line-height: 1;
379
389
  border-radius: 999px; cursor: pointer; white-space: nowrap;
380
390
  transition: transform 160ms var(--bc-ease), filter 160ms, background 160ms, border-color 160ms, color 160ms, box-shadow 160ms;
381
391
  }
382
- button.ghost { background: var(--bc-bg); border: 1px solid var(--bc-border); color: var(--bc-fg); }
383
- button.ghost:hover:not(:disabled) { background: var(--bc-subtle); border-color: color-mix(in srgb, var(--bc-fg) 20%, var(--bc-border)); }
392
+ button.ghost { background: var(--bc-bg); border: 0; color: var(--bc-fg); box-shadow: 0 0 0 1px var(--bc-border), 0 1px 2px rgba(20,18,14,.05); }
393
+ button.ghost:hover:not(:disabled) { background: var(--bc-subtle); }
384
394
  button.ghost svg, button.primary svg { font-size: 15px; }
385
395
  button.primary {
386
396
  padding: 0 18px;
387
- background: var(--bc-accent); border: 1px solid var(--bc-accent); color: var(--bc-on-accent);
388
- box-shadow: 0 4px 12px color-mix(in srgb, var(--bc-accent) 30%, transparent);
397
+ background: var(--bc-accent); border: 0; color: var(--bc-on-accent);
398
+ box-shadow: 0 1px 2px rgba(0,0,0,.14);
389
399
  }
390
- button.primary:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.07); }
391
- button.primary:active:not(:disabled) { transform: none; }
392
- button:disabled { opacity: .5; cursor: not-allowed; }
400
+ button.primary:hover:not(:disabled) { filter: brightness(1.12) contrast(.96); }
401
+ button.primary:active:not(:disabled) { transform: scale(.98); }
402
+ button:disabled { opacity: .45; cursor: not-allowed; }
393
403
  button.primary:disabled { box-shadow: none; }
394
- button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color: #fff; width: 14px; height: 14px; }
404
+ button.primary .spinner { border-color: color-mix(in srgb, var(--bc-on-accent) 40%, transparent); border-top-color: var(--bc-on-accent); width: 14px; height: 14px; }
395
405
  button.quiet {
396
- padding: 0 4px; height: 38px; font: inherit; font-size: 13px; font-weight: 600;
406
+ padding: 0 4px; height: 38px; font: inherit; font-size: 13px; font-weight: 520;
397
407
  border: none; background: none; color: var(--bc-muted); cursor: pointer; border-radius: 8px;
408
+ text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px;
398
409
  }
399
- button.quiet:hover { color: var(--bc-accent); }
410
+ button.quiet:hover { color: var(--bc-fg); text-decoration-color: color-mix(in srgb, var(--bc-fg) 35%, transparent); }
400
411
 
401
412
  /* ---------- your reports ---------- */
402
413
  .history {
@@ -416,13 +427,13 @@ button.quiet:hover { color: var(--bc-accent); }
416
427
  .history .row:last-child { border-bottom: 0; }
417
428
  .history .who { flex: 1; min-width: 0; }
418
429
  .history .ttl {
419
- display: block; font-size: 13.5px; font-weight: 600; color: var(--bc-fg);
430
+ display: block; font-size: 13.5px; font-weight: 560; color: var(--bc-fg);
420
431
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
421
432
  }
422
433
  .history .sub { display: block; margin-top: 3px; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
423
434
  .history .row-ico {
424
435
  flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
425
- background: var(--bc-subtle); color: var(--bc-muted); font-size: 16px;
436
+ background: var(--bc-stone); color: var(--bc-muted); font-size: 16px;
426
437
  }
427
438
  .history .chev { flex: none; color: var(--bc-faint); font-size: 15px; transition: transform 160ms var(--bc-ease), color 160ms; }
428
439
  .empty {
@@ -431,7 +442,7 @@ button.quiet:hover { color: var(--bc-accent); }
431
442
  }
432
443
  .empty .empty-ico {
433
444
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
434
- background: var(--bc-accent-soft); color: var(--bc-accent); font-size: 20px;
445
+ background: var(--bc-stone); color: var(--bc-fg); font-size: 20px;
435
446
  }
436
447
  .skel {
437
448
  display: block; height: 12px; border-radius: 6px; margin: 6px 0;
@@ -447,7 +458,7 @@ button.quiet:hover { color: var(--bc-accent); }
447
458
  animation: bc-rise 260ms var(--bc-ease) both;
448
459
  }
449
460
  .history button.row:hover { background: var(--bc-subtle); }
450
- .history button.row:hover .chev { transform: translateX(2px); color: var(--bc-accent); }
461
+ .history button.row:hover .chev { transform: translateX(2px); color: var(--bc-fg); }
451
462
  .history button.row:focus-visible { outline-offset: -2px; }
452
463
 
453
464
  /* ---------- one report, and what happened to it ---------- */
@@ -457,7 +468,7 @@ button.quiet:hover { color: var(--bc-accent); }
457
468
  padding: 10px var(--bc-pad); border-bottom: 1px solid var(--bc-border);
458
469
  background: var(--bc-bg);
459
470
  }
460
- .report-head .ttl { font-size: 13px; font-weight: 620; color: var(--bc-fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
471
+ .report-head .ttl { font-size: 13.5px; font-weight: 600; color: var(--bc-fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
461
472
  .report-head .sub { font-size: var(--bc-fs-xs); color: var(--bc-faint); }
462
473
  .report-head .pill { grid-row: 1 / span 2; grid-column: 2; align-self: center; }
463
474
 
@@ -491,9 +502,9 @@ button.quiet:hover { color: var(--bc-accent); }
491
502
  border-radius: 50%; background: var(--bc-muted); vertical-align: middle;
492
503
  }
493
504
  .sys .t { color: var(--bc-faint); }
494
- .sys.k-status .dot { background: #4da3ff; }
495
- .sys.k-severity .dot { background: #e8912a; }
496
- .sys.k-assignment .dot { background: #8b7dff; }
505
+ .sys.k-status .dot { background: var(--bc-info); }
506
+ .sys.k-severity .dot { background: var(--bc-warn); }
507
+ .sys.k-assignment .dot { background: var(--bc-brand-mark); }
497
508
  .sys.k-filed .dot { background: var(--bc-faint); }
498
509
 
499
510
  /* ---------- the conversation ----------
@@ -526,24 +537,21 @@ button.quiet:hover { color: var(--bc-accent); }
526
537
  .msg-row.mine > * { grid-column: 1; }
527
538
  .av {
528
539
  display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
529
- font-size: 11px; font-weight: 700; letter-spacing: .02em;
530
- background: color-mix(in srgb, var(--bc-fg) 10%, var(--bc-bg)); color: var(--bc-fg);
531
- }
532
- .av.bot {
533
- background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
534
- color: var(--bc-on-accent); font-size: 14px;
540
+ font-size: 11px; font-weight: 650; letter-spacing: .02em;
541
+ background: var(--bc-stone); color: var(--bc-fg);
535
542
  }
536
- .msg-who { font-size: var(--bc-fs-xs); font-weight: 620; color: var(--bc-muted); padding: 0 4px 4px; }
537
- .msg-who.auto { color: var(--bc-accent); display: inline-flex; align-items: center; gap: 5px; }
543
+ .av.bot { width: 28px; }
544
+ .msg-who { font-size: var(--bc-fs-xs); font-weight: 560; color: var(--bc-muted); padding: 0 4px 4px; }
545
+ .msg-who.auto { color: var(--bc-fg); display: inline-flex; align-items: center; gap: 5px; }
538
546
  .msg-who .tag {
539
- padding: 1px 6px; border-radius: 999px; font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
540
- text-transform: uppercase; background: var(--bc-accent-soft); color: var(--bc-accent);
547
+ padding: 1px 6px; border-radius: 999px; font-size: 9.5px; font-weight: 650; letter-spacing: .05em;
548
+ text-transform: uppercase; background: var(--bc-stone); color: var(--bc-muted);
541
549
  }
542
550
  .bubble {
543
551
  justify-self: start; max-width: 100%;
544
552
  padding: 9px 13px; border-radius: 18px; font-size: 13.5px; line-height: 1.5;
545
- background: var(--bc-subtle); color: var(--bc-fg);
546
- border: 1px solid var(--bc-border);
553
+ background: var(--bc-stone); color: var(--bc-fg);
554
+ border: 1px solid transparent;
547
555
  border-bottom-left-radius: 6px;
548
556
  }
549
557
  /* pre-wrap belongs to the text, not the box — on the box it would also render
@@ -556,9 +564,10 @@ button.quiet:hover { color: var(--bc-accent); }
556
564
  }
557
565
  .msg-row.cont.theirs .bubble { border-top-left-radius: 6px; }
558
566
  .msg-row.cont.mine .bubble { border-top-right-radius: 6px; }
559
- /* A reply nobody wrote: tinted with the accent and labelled "Assistant" above
560
- it, so it reads the same to someone who cannot see the colour at all. */
561
- .msg-row.auto .bubble { background: var(--bc-accent-soft); border-color: var(--bc-accent-line); }
567
+ /* A reply nobody wrote: drawn on white with a hairline, beside the orb and
568
+ labelled "Assistant" above it, so it reads the same to someone who cannot
569
+ see the difference at all. */
570
+ .msg-row.auto .bubble { background: var(--bc-bg); border-color: var(--bc-border); }
562
571
  /* An attachment-only message has no text to wrap, so the bubble would be an
563
572
  empty coloured box around it. */
564
573
  .bubble.silent { padding: 0; background: none !important; border: 0; }
@@ -572,7 +581,7 @@ button.quiet:hover { color: var(--bc-accent); }
572
581
  /* The assistant, thinking. Three dots in a bubble where its next message will be. */
573
582
  .typing { display: inline-flex; align-items: center; gap: 4px; padding: 12px 14px; justify-self: start; }
574
583
  .typing i {
575
- width: 7px; height: 7px; border-radius: 50%; background: var(--bc-accent); opacity: .45;
584
+ width: 6px; height: 6px; border-radius: 50%; background: var(--bc-muted); opacity: .45;
576
585
  animation: bc-typing 1.2s ease-in-out infinite;
577
586
  }
578
587
  .typing i:nth-child(2) { animation-delay: .15s; }
@@ -608,30 +617,29 @@ button.quiet:hover { color: var(--bc-accent); }
608
617
  background: var(--bc-subtle);
609
618
  transition: background 400ms ease, border-color 400ms ease;
610
619
  }
611
- .assistant.analyzing, .assistant.confirming, .assistant.needs_info {
612
- background: var(--bc-accent-soft); border-color: var(--bc-accent-line);
613
- }
614
- .assistant.resolved { background: color-mix(in srgb, var(--bc-ok) 9%, var(--bc-bg)); border-color: color-mix(in srgb, var(--bc-ok) 35%, var(--bc-border)); }
620
+ .assistant.resolved { background: color-mix(in srgb, var(--bc-ok) 7%, var(--bc-bg)); border-color: color-mix(in srgb, var(--bc-ok) 30%, var(--bc-border)); }
615
621
  /* On a call: the call's own card is what they are watching. This one states
616
- what is happening and stops moving — no spinner, no travelling bar. */
622
+ what is happening and stops moving — no breathing orb, no travelling bar. */
617
623
  .assistant.calling { background: var(--bc-bg); }
618
624
  .assistant.calling .as-progress i { transition: none; }
619
625
  .as-body.entering { animation: bc-rise 360ms var(--bc-ease) both; }
620
626
  .as-top { display: flex; gap: 11px; align-items: center; }
627
+ /* The orb, while the assistant is at work; a plain disc with a glyph once it
628
+ is on a call or has finished. */
621
629
  .as-orb {
622
630
  flex: none; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
623
- color: var(--bc-on-accent); font-size: 15px;
624
- background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
631
+ color: var(--bc-on-accent); font-size: 15px; background: var(--bc-accent);
625
632
  }
626
- .assistant.resolved .as-orb { background: var(--bc-ok); }
627
- .assistant.reviewing .as-orb { background: color-mix(in srgb, var(--bc-fg) 55%, var(--bc-bg)); }
628
- .as-spin { width: 16px; height: 16px; border-radius: 50%; border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; animation: as-rot .8s linear infinite; }
629
- @keyframes as-rot { to { transform: rotate(360deg); } }
633
+ .as-orb.orb { background: var(--bc-o2); }
634
+ .assistant.analyzing .as-orb.orb { animation: as-breathe 2.4s ease-in-out infinite; }
635
+ @keyframes as-breathe { 50% { transform: scale(.88); } }
636
+ .assistant.resolved .as-orb { background: var(--bc-ok); color: #fff; }
637
+ .assistant.reviewing .as-orb.orb { filter: saturate(.35); }
630
638
  .as-text { min-width: 0; flex: 1; }
631
- .as-title { font-weight: 650; font-size: 13.5px; letter-spacing: -.01em; color: var(--bc-fg); }
639
+ .as-title { font-weight: 600; font-size: 13.5px; letter-spacing: -.01em; color: var(--bc-fg); }
632
640
  .as-detail { font-size: 12px; line-height: 1.45; color: var(--bc-muted); margin-top: 2px; }
633
641
  .as-progress {
634
- height: 4px; margin: 12px 0 0; border-radius: 999px; overflow: hidden;
642
+ height: 3px; margin: 12px 0 0; border-radius: 999px; overflow: hidden;
635
643
  background: color-mix(in srgb, var(--bc-fg) 9%, transparent);
636
644
  }
637
645
  .as-progress i {
@@ -640,39 +648,42 @@ button.quiet:hover { color: var(--bc-accent); }
640
648
  }
641
649
  .assistant.resolved .as-progress i { background: var(--bc-ok); }
642
650
  .assistant.analyzing .as-progress i {
643
- background: linear-gradient(90deg, var(--bc-accent) 0%, color-mix(in srgb, var(--bc-accent) 45%, #fff) 50%, var(--bc-accent) 100%);
651
+ background: linear-gradient(90deg, var(--bc-accent) 0%, color-mix(in srgb, var(--bc-accent) 35%, var(--bc-bg)) 50%, var(--bc-accent) 100%);
644
652
  background-size: 200% 100%; animation: bc-shimmer 1.6s linear infinite;
645
653
  }
654
+ /* Four short labels under the bar. Allowed to wrap rather than be cut: at this
655
+ width "Report received" ellipsised to "Report recei…". */
646
656
  .as-steps {
647
- list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
648
- margin: 8px 0 0; padding: 0; font-size: 10.5px; color: var(--bc-faint);
657
+ list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px 6px;
658
+ margin: 8px 0 0; padding: 0; font-size: 10.5px; line-height: 1.3; color: var(--bc-faint);
649
659
  }
650
- .as-steps li { display: flex; align-items: center; gap: 5px; min-width: 0; white-space: nowrap; }
651
- .as-steps li .lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
652
- .as-steps li .dot { flex: none; width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid currentColor; }
660
+ .as-steps li { display: flex; align-items: flex-start; gap: 5px; min-width: 0; }
661
+ .as-steps li .lbl { min-width: 0; overflow-wrap: anywhere; }
662
+ .as-steps li .dot { flex: none; width: 7px; height: 7px; margin-top: 3px; border-radius: 50%; border: 1.5px solid currentColor; }
653
663
  .as-steps li.done { color: var(--bc-muted); }
654
664
  .as-steps li.done .dot { background: var(--bc-accent); border-color: var(--bc-accent); }
655
665
  .assistant.resolved .as-steps li.done .dot { background: var(--bc-ok); border-color: var(--bc-ok); }
656
- .as-steps li.active { color: var(--bc-fg); font-weight: 650; }
666
+ .as-steps li.active { color: var(--bc-fg); font-weight: 600; }
657
667
  .as-steps li.active .dot { border-color: var(--bc-accent); background: var(--bc-bg); animation: as-pulse 1.2s ease-in-out infinite; }
658
- @keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent) 25%, transparent); } }
659
- @media (prefers-reduced-motion: reduce) { .as-spin, .as-steps li.active .dot, .assistant.analyzing .as-progress i, .typing i { animation: none; } }
668
+ @keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent) 18%, transparent); } }
669
+ @media (prefers-reduced-motion: reduce) { .as-orb, .as-steps li.active .dot, .assistant.analyzing .as-progress i, .typing i { animation: none; } }
660
670
 
661
671
  /* Quick answers under the confirm question — only on the latest message. */
662
672
  .msg-row .quick { display: none; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
663
673
  .msg-row:last-child .quick { display: flex; }
664
674
  .quick button {
665
675
  display: inline-flex; align-items: center; gap: 6px;
666
- font: inherit; font-size: 13px; font-weight: 600; padding: 8px 14px; border-radius: 999px; cursor: pointer;
667
- border: 1px solid var(--bc-accent); background: var(--bc-bg); color: var(--bc-accent);
676
+ font: inherit; font-size: 13px; font-weight: 560; height: 34px; padding: 0 14px; border-radius: 999px; cursor: pointer;
677
+ border: 0; background: var(--bc-bg); color: var(--bc-fg); box-shadow: 0 0 0 1px var(--bc-border);
668
678
  transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
669
679
  animation: bc-item-in 300ms var(--bc-ease) both;
670
680
  }
671
- .quick button:first-child { background: var(--bc-accent); color: var(--bc-on-accent); }
681
+ .quick button:first-child { background: var(--bc-accent); color: var(--bc-on-accent); box-shadow: none; }
672
682
  .quick button:nth-child(2) { animation-delay: 60ms; }
673
683
  .quick button svg { font-size: 13px; }
674
- .quick button:hover { transform: translateY(-1px); background: var(--bc-accent-soft); }
675
- .quick button:first-child:hover { background: var(--bc-accent); filter: brightness(1.07); }
684
+ .quick button:hover { background: var(--bc-subtle); }
685
+ .quick button:first-child:hover { background: var(--bc-accent); filter: brightness(1.12) contrast(.96); }
686
+ .quick button:active { transform: scale(.97); }
676
687
 
677
688
  /* ---------- the composer ---------- */
678
689
  .composer {
@@ -689,10 +700,10 @@ button.quiet:hover { color: var(--bc-accent); }
689
700
  .composer .row {
690
701
  display: flex; align-items: flex-end; gap: 4px;
691
702
  padding: 5px; border-radius: 22px;
692
- background: var(--bc-subtle); border: 1px solid var(--bc-border);
693
- transition: border-color 160ms, box-shadow 160ms;
703
+ background: var(--bc-stone); border: 1px solid transparent;
704
+ transition: border-color 160ms, box-shadow 160ms, background 160ms;
694
705
  }
695
- .composer .row:focus-within { border-color: var(--bc-accent); box-shadow: var(--bc-ring); }
706
+ .composer .row:focus-within { background: var(--bc-bg); border-color: var(--bc-accent); box-shadow: var(--bc-ring); }
696
707
  .composer textarea {
697
708
  flex: 1; min-width: 0; min-height: 34px; max-height: 120px; resize: none; padding: 7px 6px;
698
709
  font: inherit; font-size: 13.5px; line-height: 1.45;
@@ -717,8 +728,8 @@ button.quiet:hover { color: var(--bc-accent); }
717
728
  display: grid; place-items: center;
718
729
  transition: transform 160ms var(--bc-ease), opacity 160ms, filter 160ms;
719
730
  }
720
- .composer .send:hover:not(:disabled) { filter: brightness(1.08); transform: scale(1.05); }
721
- .composer .send:disabled { opacity: .35; cursor: default; background: var(--bc-faint); }
731
+ .composer .send:hover:not(:disabled) { filter: brightness(1.12) contrast(.96); transform: scale(1.04); }
732
+ .composer .send:disabled { opacity: .3; cursor: default; background: var(--bc-faint); }
722
733
  .composer .staged { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 8px; }
723
734
  .composer .chip {
724
735
  display: flex; align-items: center; gap: 6px; max-width: 200px;
@@ -741,23 +752,16 @@ button.quiet:hover { color: var(--bc-accent); }
741
752
  lands on — which is what someone opening this screen came to check. */
742
753
  .pill {
743
754
  flex: none; display: inline-flex; align-items: center; gap: 5px;
744
- font-size: 11px; font-weight: 650;
755
+ font-size: 11px; font-weight: 600;
745
756
  padding: 3px 9px; border-radius: 999px;
746
- color: var(--bc-muted); background: var(--bc-subtle);
757
+ color: var(--bc-muted); background: var(--bc-stone);
747
758
  }
748
759
  .pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
749
- .pill.open { color: #c2410c; background: color-mix(in srgb, #f59e0b 14%, var(--bc-bg)); }
750
- .pill.in_progress { color: #1d6fd1; background: color-mix(in srgb, #3b82f6 14%, var(--bc-bg)); }
751
- .pill.resolved { color: #0f8a5a; background: color-mix(in srgb, #10b981 14%, var(--bc-bg)); }
760
+ /* The theme's own status colours, which already have a dark cut. */
761
+ .pill.open { color: var(--bc-warn); background: color-mix(in srgb, var(--bc-warn) 12%, var(--bc-bg)); }
762
+ .pill.in_progress { color: var(--bc-info); background: color-mix(in srgb, var(--bc-info) 12%, var(--bc-bg)); }
763
+ .pill.resolved { color: var(--bc-ok); background: color-mix(in srgb, var(--bc-ok) 12%, var(--bc-bg)); }
752
764
  .pill.closed { color: var(--bc-muted); }
753
- :host(.bc-dark) .pill.open { color: #fbbf24; }
754
- :host(.bc-dark) .pill.in_progress { color: #7cb8ff; }
755
- :host(.bc-dark) .pill.resolved { color: #4ade9a; }
756
- @media (prefers-color-scheme: dark) {
757
- :host(.bc-auto) .pill.open { color: #fbbf24; }
758
- :host(.bc-auto) .pill.in_progress { color: #7cb8ff; }
759
- :host(.bc-auto) .pill.resolved { color: #4ade9a; }
760
- }
761
765
 
762
766
  /* ---------- does the fix work ---------- */
763
767
  .fix-verification {
@@ -777,6 +781,75 @@ button.quiet:hover { color: var(--bc-accent); }
777
781
  .fix-verification .feedback-status { margin: 6px 0 0; font-weight: 450; color: var(--bc-danger); font-size: var(--bc-fs-xs); }
778
782
  .fix-verification .feedback-status:empty { display: none; }
779
783
 
784
+ /* ---------- how did we do ----------
785
+ Quieter than the card above it: that one asks whether the fix works, which
786
+ the team acts on; this asks how it felt, which they learn from. The stars
787
+ carry the only colour, so the one thing to do here is the thing you see. */
788
+ .fix-rating {
789
+ --bc-star: #f0a81c;
790
+ flex: none; margin: 10px 12px 0; padding: 12px 14px;
791
+ border-radius: var(--bc-r-lg); border: 1px solid var(--bc-border); background: var(--bc-bg);
792
+ font-size: var(--bc-fs-sm); color: var(--bc-fg);
793
+ animation: bc-rise 280ms var(--bc-ease) both;
794
+ }
795
+ .fix-rating .fr-q { margin: 0 0 6px; font-weight: 620; }
796
+ .fix-rating .stars { display: flex; gap: 2px; margin: 0 0 2px -4px; }
797
+ .fix-rating .stars button {
798
+ display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0;
799
+ border: 0; border-radius: 8px; background: transparent; cursor: pointer;
800
+ color: color-mix(in srgb, var(--bc-fg) 18%, transparent);
801
+ transition: color 120ms ease, transform 120ms var(--bc-ease);
802
+ }
803
+ .fix-rating .stars button svg { width: 24px; height: 24px; }
804
+ .fix-rating .stars button.on { color: var(--bc-star); }
805
+ .fix-rating .stars button:hover:not(:disabled) { transform: scale(1.08); }
806
+ .fix-rating .stars button:focus-visible { outline: none; box-shadow: var(--bc-ring); }
807
+ .fix-rating .stars button:disabled { cursor: default; }
808
+ .fix-rating .fr-hint { margin: 2px 0 0; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
809
+ .fix-rating .fr-said { margin: 6px 0 0; font-size: 13px; color: var(--bc-muted); white-space: pre-wrap; overflow-wrap: anywhere; }
810
+ .fix-rating .fr-note { margin-top: 8px; }
811
+ .fix-rating .fr-note textarea { min-height: 52px; margin-bottom: 8px; font-size: 13px; }
812
+ .fix-rating .fr-note button {
813
+ padding: 7px 13px; font: inherit; font-size: 12.5px; font-weight: 620; border-radius: 999px; cursor: pointer;
814
+ border: 1px solid var(--bc-border); background: var(--bc-bg); color: var(--bc-fg);
815
+ }
816
+ .fix-rating .feedback-status { margin: 6px 0 0; color: var(--bc-danger); font-size: var(--bc-fs-xs); }
817
+ .fix-rating .feedback-status:empty { display: none; }
818
+ @media (prefers-reduced-motion: reduce) { .fix-rating .stars button { transition: none; } .fix-rating .stars button:hover { transform: none; } }
819
+
820
+ /* The rating on a history row: the score given, or a nudge to give one. */
821
+ .history .sub .rated { display: inline-flex; align-items: center; gap: 2px; color: var(--bc-muted); font-weight: 600; }
822
+ .history .sub .rated svg { width: 11px; height: 11px; color: #f0a81c; }
823
+ .history .sub .rate-ask { color: var(--bc-fg); font-weight: 600; }
824
+
825
+ /* ---------- a settled report waiting for its rating ----------
826
+ Above the form on the first screen: the same stars as under a report's
827
+ conversation, with the report they are about named on top. */
828
+ .rate-due { margin: 0 0 14px; }
829
+ .rate-due:focus { outline: none; }
830
+ .rate-due:focus-visible { box-shadow: var(--bc-ring); }
831
+ .rate-due .rd-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
832
+ .rate-due .rd-eyebrow {
833
+ font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--bc-faint);
834
+ }
835
+ .rate-due.is-required .rd-eyebrow { color: var(--bc-fg); }
836
+ .rate-due .rd-later { font-size: var(--bc-fs-xs); color: var(--bc-muted); }
837
+ .rate-due .rd-report {
838
+ display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 9px; align-items: center;
839
+ margin: 0 0 10px; padding: 0 0 10px; border-bottom: 1px solid var(--bc-border);
840
+ }
841
+ .rate-due .rd-ico {
842
+ grid-row: span 2; display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 999px;
843
+ background: color-mix(in srgb, var(--bc-ok) 14%, transparent); color: var(--bc-ok);
844
+ }
845
+ .rate-due .rd-ico svg { width: 13px; height: 13px; }
846
+ .rate-due .rd-ttl { font-weight: 620; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
847
+ .rate-due .rd-sub { font-size: var(--bc-fs-xs); color: var(--bc-muted); }
848
+
849
+ /* What a required rating is holding: still in sight, plainly not yet. */
850
+ .held { opacity: .42; transition: opacity 200ms ease; }
851
+ @media (prefers-reduced-motion: reduce) { .held { transition: none; } }
852
+
780
853
  /* A call in progress, in place of the form.
781
854
  ---------------------------------------------------------------------------
782
855
  Deliberately not styled as a chat. Nothing arrives here to read — the
@@ -826,13 +899,13 @@ button.quiet:hover { color: var(--bc-accent); }
826
899
  and this screen's padding was landing on every one of them. */
827
900
  div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 240ms ease both; }
828
901
  .done .tick {
829
- width: 56px; height: 56px; margin: 0 auto 16px; border-radius: 50%;
830
- display: grid; place-items: center; font-size: 26px;
831
- background: color-mix(in srgb, var(--bc-ok) 14%, transparent); color: var(--bc-ok);
832
- box-shadow: 0 0 0 8px color-mix(in srgb, var(--bc-ok) 6%, transparent);
902
+ width: 52px; height: 52px; margin: 0 auto 16px; border-radius: 50%;
903
+ display: grid; place-items: center; font-size: 24px;
904
+ background: var(--bc-ok); color: #fff;
905
+ box-shadow: 0 0 0 7px color-mix(in srgb, var(--bc-ok) 12%, transparent);
833
906
  animation: bc-pop 420ms var(--bc-ease) both;
834
907
  }
835
- .done h3 { margin: 0 0 6px; font-size: 17px; font-weight: 680; letter-spacing: -.015em; }
908
+ .done h3 { margin: 0 0 6px; font-size: 18px; font-weight: 600; letter-spacing: -.02em; }
836
909
  .done p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--bc-muted); }
837
910
  .done code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; padding: 1px 5px; border-radius: 5px; background: var(--bc-subtle); color: var(--bc-fg); }
838
911
  /* The likely wait. Set apart from the reference line above it by a rule rather
@@ -896,7 +969,7 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
896
969
  is open — the sheet has its own close button, and a launcher floating over
897
970
  the send button would be in the way of the one thing that matters. */
898
971
  @media (max-width: 480px) {
899
- .scrim { background: rgba(10,12,16,.4); }
972
+ .scrim { background: rgba(14,14,16,.4); }
900
973
  .panel, .scrim.at-right .panel, .scrim.at-left .panel, .scrim.at-bottom .panel, .scrim.at-top .panel {
901
974
  inset: 0; width: 100%; max-width: none; height: 100%; max-height: none;
902
975
  border-radius: 0; border: 0;
@@ -911,6 +984,16 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
911
984
  .foot:has(+ .powered) { padding-bottom: 12px; }
912
985
  .recbar .hint { display: none; }
913
986
  .msg-row, .typing-row { max-width: 92%; }
987
+ /* The question chips are one row that scrolls sideways, edge to edge, rather
988
+ than three stacked rows pushing the form down the screen. */
989
+ .picks .picks-grid {
990
+ flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
991
+ margin: 0 calc(var(--bc-pad) * -1); padding: 0 var(--bc-pad) 2px;
992
+ scroll-snap-type: x proximity; scroll-padding: 0 var(--bc-pad);
993
+ }
994
+ .picks .picks-grid::-webkit-scrollbar { display: none; }
995
+ .picks .pick { flex: none; scroll-snap-align: start; }
996
+ .picks .pick .t { white-space: nowrap; }
914
997
  }
915
998
 
916
999
  @media (pointer: coarse) {
@@ -925,7 +1008,8 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
925
1008
  under it, on the one surface in the product designed for someone who is
926
1009
  not an operator and gets no second attempt. */
927
1010
  .seg button { min-height: 44px; }
928
- .tool { min-height: 56px; }
1011
+ .tool, .known .issue .join { min-height: 44px; }
1012
+ .picks .pick { min-height: 40px; }
929
1013
  button.primary, button.ghost { height: 44px; }
930
1014
  .composer .send, .composer .tool { width: 40px; height: 40px; min-height: 0; }
931
1015
  textarea { min-height: 104px; }
@@ -934,7 +1018,7 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
934
1018
  /* The close button and the thumbnails' remove buttons are small glyphs whose
935
1019
  boxes cannot grow without moving what is beside them, so each keeps its
936
1020
  size and gets an invisible target drawn around it instead. The theme
937
- switch gets the same in the launcher's own sheet (widget.js). */
1021
+ button in the header is one of these. */
938
1022
  .head .icon-btn, .thumb .drop, .brand-credit { position: relative; }
939
1023
  .thumb .drop { position: absolute; opacity: 1; }
940
1024
  .head .icon-btn::after, .thumb .drop::after, .brand-credit::after {
@@ -949,29 +1033,31 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
949
1033
  .tool:hover:not(:disabled) { transform: none; }
950
1034
  }
951
1035
  `;
952
- function ce({ title: e, sub: t, id: n = "", back: y = !1 }) {
1036
+ function le({ title: e, sub: t, id: r = "", back: d = !1, theme: u = "" }) {
953
1037
  return `
954
1038
  <div class="head">
955
- ${y ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${Ve}</button>` : ""}
956
- <div class="mark" aria-hidden="true">${X}</div>
1039
+ ${d ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${We}</button>` : ""}
1040
+ <span class="orb mark" aria-hidden="true"></span>
957
1041
  <div class="titles">
958
- <h2${n ? ` id="${n}"` : ""}>${m(e)}</h2>
959
- <p>${m(t)}</p>
1042
+ <h2${r ? ` id="${r}"` : ""}>${v(e)}</h2>
1043
+ <p>${v(t)}</p>
960
1044
  </div>
961
- <button class="icon-btn" type="button" data-act="close" aria-label="Close">${de}</button>
1045
+ ${u ? `<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${v(u)}"
1046
+ aria-label="Theme: ${v(u)}. Change theme"><span class="m-light">${Le}</span><span class="m-dark">${Qe}</span><span class="m-auto">${Te}</span></button>` : ""}
1047
+ <button class="icon-btn" type="button" data-act="close" aria-label="Close">${ce}</button>
962
1048
  </div>`;
963
1049
  }
964
- function ie(e, t) {
965
- return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${m(e)}</div>`;
1050
+ function oe(e, t) {
1051
+ return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${v(e)}</div>`;
966
1052
  }
967
- function Ye(e) {
1053
+ function _e(e) {
968
1054
  return Array.from({ length: e }, () => `
969
1055
  <div class="row" aria-hidden="true">
970
1056
  <span class="row-ico"></span>
971
1057
  <span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
972
1058
  </div>`).join("") + '<span class="sr-only">Loading…</span>';
973
1059
  }
974
- function Pe() {
1060
+ function Ge() {
975
1061
  return `
976
1062
  <div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
977
1063
  <span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
@@ -980,7 +1066,7 @@ function Pe() {
980
1066
  </div>
981
1067
  <span class="sr-only">Loading…</span>`;
982
1068
  }
983
- function We(e) {
1069
+ function Je(e) {
984
1070
  const t = String(e).trim().split(/\s+/).filter(Boolean);
985
1071
  return t.length ? (t[0][0] + (t.length > 1 ? t[t.length - 1][0] : "")).toUpperCase() : "?";
986
1072
  }
@@ -988,22 +1074,22 @@ function Z(e) {
988
1074
  const t = new Date(e);
989
1075
  return Number.isFinite(t.getTime()) ? `${t.getFullYear()}-${t.getMonth()}-${t.getDate()}` : null;
990
1076
  }
991
- function Ke(e) {
992
- const t = new Date(e), n = /* @__PURE__ */ new Date(), y = new Date(n.getFullYear(), n.getMonth(), n.getDate() - 1);
993
- if (Z(t) === Z(n)) return "Today";
994
- if (Z(t) === Z(y)) return "Yesterday";
1077
+ function Xe(e) {
1078
+ const t = new Date(e), r = /* @__PURE__ */ new Date(), d = new Date(r.getFullYear(), r.getMonth(), r.getDate() - 1);
1079
+ if (Z(t) === Z(r)) return "Today";
1080
+ if (Z(t) === Z(d)) return "Yesterday";
995
1081
  try {
996
1082
  return t.toLocaleDateString(void 0, {
997
1083
  weekday: "short",
998
1084
  day: "numeric",
999
1085
  month: "short",
1000
- ...t.getFullYear() !== n.getFullYear() ? { year: "numeric" } : {}
1086
+ ...t.getFullYear() !== r.getFullYear() ? { year: "numeric" } : {}
1001
1087
  });
1002
1088
  } catch {
1003
- return oe(e);
1089
+ return J(e);
1004
1090
  }
1005
1091
  }
1006
- function me(e) {
1092
+ function ve(e) {
1007
1093
  const t = new Date(e);
1008
1094
  if (!Number.isFinite(t.getTime())) return "";
1009
1095
  try {
@@ -1016,10 +1102,10 @@ function ue(e) {
1016
1102
  return e.scrollHeight - e.scrollTop - e.clientHeight < 40;
1017
1103
  }
1018
1104
  function _(e, { smooth: t = !1 } = {}) {
1019
- const n = typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
1020
- t && !n && e.scrollTo ? e.scrollTo({ top: e.scrollHeight, behavior: "smooth" }) : e.scrollTop = e.scrollHeight;
1105
+ const r = typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
1106
+ t && !r && e.scrollTo ? e.scrollTo({ top: e.scrollHeight, behavior: "smooth" }) : e.scrollTop = e.scrollHeight;
1021
1107
  }
1022
- function se(e) {
1108
+ function ie(e) {
1023
1109
  return {
1024
1110
  OPEN: "Open",
1025
1111
  IN_PROGRESS: "In progress",
@@ -1027,52 +1113,52 @@ function se(e) {
1027
1113
  CLOSED: "Closed"
1028
1114
  }[e] || String(e || "").toLowerCase();
1029
1115
  }
1030
- function oe(e) {
1116
+ function J(e) {
1031
1117
  const t = new Date(e).getTime();
1032
1118
  if (!Number.isFinite(t)) return "";
1033
- const n = Math.floor((Date.now() - t) / 864e5);
1034
- if (n <= 0) return "today";
1035
- if (n === 1) return "yesterday";
1036
- if (n < 30) return `${n} days ago`;
1037
- const y = Math.floor(n / 30);
1038
- return y === 1 ? "a month ago" : `${y} months ago`;
1039
- }
1040
- function m(e) {
1119
+ const r = Math.floor((Date.now() - t) / 864e5);
1120
+ if (r <= 0) return "today";
1121
+ if (r === 1) return "yesterday";
1122
+ if (r < 30) return `${r} days ago`;
1123
+ const d = Math.floor(r / 30);
1124
+ return d === 1 ? "a month ago" : `${d} months ago`;
1125
+ }
1126
+ function v(e) {
1041
1127
  return String(e).replace(/[&<>"']/g, (t) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[t]);
1042
1128
  }
1043
- const Fe = 7 * 24 * 60 * 60 * 1e3;
1129
+ const et = 7 * 24 * 60 * 60 * 1e3;
1044
1130
  let ee;
1045
- function Ue() {
1131
+ function tt() {
1046
1132
  return ee || (ee = new Promise((e, t) => {
1047
- const n = indexedDB.open("bugcatch-drafts", 1);
1048
- n.onupgradeneeded = () => n.result.createObjectStore("drafts"), n.onsuccess = () => e(n.result), n.onerror = () => t(n.error), n.onblocked = () => t(new Error("Draft storage is blocked."));
1133
+ const r = indexedDB.open("bugcatch-drafts", 1);
1134
+ r.onupgradeneeded = () => r.result.createObjectStore("drafts"), r.onsuccess = () => e(r.result), r.onerror = () => t(r.error), r.onblocked = () => t(new Error("Draft storage is blocked."));
1049
1135
  }).catch((e) => {
1050
1136
  throw ee = null, e;
1051
1137
  })), ee;
1052
1138
  }
1053
- function Ze(e, t) {
1054
- var n, y;
1055
- return JSON.stringify([e.apiBase, e.projectId, t || ((n = e.user) == null ? void 0 : n.email) || ((y = e.user) == null ? void 0 : y.id) || "anonymous"]);
1139
+ function at(e, t) {
1140
+ var r, d;
1141
+ return JSON.stringify([e.apiBase, e.projectId, t || ((r = e.user) == null ? void 0 : r.email) || ((d = e.user) == null ? void 0 : d.id) || "anonymous"]);
1056
1142
  }
1057
1143
  async function ae(e, t) {
1058
- const n = await Ue();
1059
- return new Promise((y, u) => {
1060
- const T = n.transaction("drafts", t === void 0 ? "readonly" : "readwrite"), v = T.objectStore("drafts"), s = t === void 0 ? v.get(e) : t === null ? v.delete(e) : v.put({ ...t, savedAt: Date.now() }, e);
1061
- T.oncomplete = () => y(s.result), T.onerror = () => u(T.error), T.onabort = () => u(T.error || new Error("Draft was not saved."));
1144
+ const r = await tt();
1145
+ return new Promise((d, u) => {
1146
+ const S = r.transaction("drafts", t === void 0 ? "readonly" : "readwrite"), b = S.objectStore("drafts"), h = t === void 0 ? b.get(e) : t === null ? b.delete(e) : b.put({ ...t, savedAt: Date.now() }, e);
1147
+ S.oncomplete = () => d(h.result), S.onerror = () => u(S.error), S.onabort = () => u(S.error || new Error("Draft was not saved."));
1062
1148
  });
1063
1149
  }
1064
- async function _e(e) {
1150
+ async function rt(e) {
1065
1151
  const t = await ae(e);
1066
- return t && Date.now() - t.savedAt > Fe ? (await ae(e, null), null) : t || null;
1152
+ return t && Date.now() - t.savedAt > et ? (await ae(e, null), null) : t || null;
1067
1153
  }
1068
- const ve = [
1154
+ const xe = [
1069
1155
  { value: "LOW", label: "Low" },
1070
1156
  { value: "MEDIUM", label: "Medium" },
1071
1157
  { value: "HIGH", label: "High" },
1072
1158
  { value: "CRITICAL", label: "Critical" }
1073
- ], xe = "MEDIUM";
1074
- function Ge(e) {
1075
- const t = e.attachments !== !1, n = t && we(), y = t && ke();
1159
+ ], ye = "MEDIUM";
1160
+ function nt(e) {
1161
+ const t = e.attachments !== !1, r = t && qe(), d = t && Ee();
1076
1162
  return `
1077
1163
  <div class="compose">
1078
1164
  <div class="field">
@@ -1093,8 +1179,8 @@ function Ge(e) {
1093
1179
  <div class="field">
1094
1180
  <label id="bc-prio-l">How much is it getting in your way?</label>
1095
1181
  <div class="seg" role="group" aria-labelledby="bc-prio-l">
1096
- ${ve.map((u) => `
1097
- <button type="button" data-prio="${u.value}" aria-pressed="${u.value === xe}">${u.label}</button>
1182
+ ${xe.map((u) => `
1183
+ <button type="button" data-prio="${u.value}" aria-pressed="${u.value === ye}">${u.label}</button>
1098
1184
  `).join("")}
1099
1185
  </div>
1100
1186
  </div>
@@ -1105,8 +1191,8 @@ function Ge(e) {
1105
1191
  <span class="count" aria-live="polite"></span>
1106
1192
  </div>
1107
1193
  <div class="tools" role="group" aria-labelledby="bc-att-l">
1108
- ${n ? `<button class="tool" type="button" data-act="shot">${Ie}Screenshot</button>` : ""}
1109
- ${y ? `<button class="tool" type="button" data-act="rec">${Ae}Record screen</button>` : ""}
1194
+ ${r ? `<button class="tool" type="button" data-act="shot">${Ne}Screenshot</button>` : ""}
1195
+ ${d ? `<button class="tool" type="button" data-act="rec">${Be}Record screen</button>` : ""}
1110
1196
  <button class="tool" type="button" data-act="file">${fe}Upload file</button>
1111
1197
  </div>
1112
1198
  <div class="thumbs"></div>
@@ -1114,1165 +1200,1340 @@ function Ge(e) {
1114
1200
  </div>` : ""}
1115
1201
  </div>`;
1116
1202
  }
1117
- function Xe(e) {
1118
- var re, F, U, q;
1203
+ function ot(e) {
1204
+ var ne, K, U, z;
1119
1205
  const {
1120
1206
  client: t,
1121
- cfg: n,
1122
- root: y,
1207
+ cfg: r,
1208
+ root: d,
1123
1209
  host: u,
1124
- dock: T,
1125
- scrim: v,
1126
- $: s,
1127
- say: i,
1128
- titleInput: h,
1129
- descInput: g,
1130
- compose: f,
1131
- sendBtn: b,
1132
- note: z
1133
- } = e, Q = s(".thumbs"), c = v.querySelector("input[type=file]"), d = [];
1134
- let l = xe, a = null;
1135
- const r = document.createElement("div");
1136
- r.setAttribute("role", "status"), r.className = "note", f.prepend(r);
1137
- const $ = Ze(n, (re = t.signedInAs()) == null ? void 0 : re.email);
1138
- let E = n.drafts === !1, x = !1, p = Promise.resolve(), w;
1139
- function S() {
1140
- if (clearTimeout(w), !E || x || n.drafts === !1) return p;
1141
- const o = h.value || g.value || d.length ? {
1142
- title: h.value,
1143
- description: g.value,
1144
- priority: l,
1145
- items: d.map(({ blob: L, mime: I, kind: C }) => ({ blob: L, mime: I, kind: C }))
1210
+ dock: S,
1211
+ scrim: b,
1212
+ $: h,
1213
+ say: f,
1214
+ titleInput: s,
1215
+ descInput: c,
1216
+ compose: L,
1217
+ sendBtn: g,
1218
+ note: w
1219
+ } = e, x = h(".thumbs"), T = b.querySelector("input[type=file]"), i = [];
1220
+ let n = ye, o = null;
1221
+ const a = document.createElement("div");
1222
+ a.setAttribute("role", "status"), a.className = "note", L.prepend(a);
1223
+ const k = at(r, (ne = t.signedInAs()) == null ? void 0 : ne.email);
1224
+ let y = r.drafts === !1, m = !1, l = Promise.resolve(), $;
1225
+ function q() {
1226
+ if (clearTimeout($), !y || m || r.drafts === !1) return l;
1227
+ const p = s.value || c.value || i.length ? {
1228
+ title: s.value,
1229
+ description: c.value,
1230
+ priority: n,
1231
+ items: i.map(({ blob: E, mime: A, kind: R }) => ({ blob: E, mime: A, kind: R }))
1146
1232
  } : null;
1147
- return p = p.catch(() => {
1148
- }).then(() => ae($, o)).then(() => {
1149
- r.textContent = o ? "Draft saved on this device" : "";
1233
+ return l = l.catch(() => {
1234
+ }).then(() => ae(k, p)).then(() => {
1235
+ a.textContent = p ? "Draft saved on this device" : "";
1150
1236
  }).catch(() => {
1151
- r.textContent = "Draft could not be saved. Keep this tab open.";
1152
- }), p;
1237
+ a.textContent = "Draft could not be saved. Keep this tab open.";
1238
+ }), l;
1153
1239
  }
1154
- function A() {
1155
- clearTimeout(w), w = setTimeout(S, 250);
1240
+ function H() {
1241
+ clearTimeout($), $ = setTimeout(q, 250);
1156
1242
  }
1157
- f.addEventListener("input", A), f.addEventListener("change", A);
1158
- const D = () => {
1159
- S();
1243
+ L.addEventListener("input", H), L.addEventListener("change", H);
1244
+ const O = () => {
1245
+ q();
1160
1246
  };
1161
- window.addEventListener("pagehide", D);
1162
- function O() {
1163
- d.filter((o) => o.status === "failed").forEach(K);
1164
- }
1165
- window.addEventListener("online", O), n.drafts !== !1 && (f.inert = !0, _e($).then((o) => {
1166
- e.closed || !o || (r.innerHTML = '<span>You have an unfinished report on this device.</span> <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>', r.querySelector("[data-resume]").onclick = () => {
1167
- h.value = o.title || "", g.value = o.description || "", l = ve.some((L) => L.value === o.priority) ? o.priority : "MEDIUM", v.querySelectorAll("[data-prio]").forEach((L) => L.setAttribute("aria-pressed", String(L.dataset.prio === l)));
1168
- for (const L of (o.items || []).slice(0, n.maxAttachments ?? 5)) N(L);
1169
- E = !0, S();
1170
- }, r.querySelector("[data-discard]").onclick = () => {
1171
- E = !0, S();
1247
+ window.addEventListener("pagehide", O);
1248
+ function N() {
1249
+ i.filter((p) => p.status === "failed").forEach(V);
1250
+ }
1251
+ window.addEventListener("online", N), r.drafts !== !1 && (L.inert = !0, rt(k).then((p) => {
1252
+ e.closed || !p || (a.innerHTML = '<span>You have an unfinished report on this device.</span> <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>', a.querySelector("[data-resume]").onclick = () => {
1253
+ s.value = p.title || "", c.value = p.description || "", n = xe.some((E) => E.value === p.priority) ? p.priority : "MEDIUM", b.querySelectorAll("[data-prio]").forEach((E) => E.setAttribute("aria-pressed", String(E.dataset.prio === n)));
1254
+ for (const E of (p.items || []).slice(0, r.maxAttachments ?? 5)) Y(E);
1255
+ y = !0, q();
1256
+ }, a.querySelector("[data-discard]").onclick = () => {
1257
+ y = !0, q();
1172
1258
  });
1173
1259
  }).catch(() => {
1174
- r.textContent = "Draft storage is unavailable. Keep this tab open.";
1260
+ a.textContent = "Draft storage is unavailable. Keep this tab open.";
1175
1261
  }).finally(() => {
1176
- f.inert = !1, r.querySelector("[data-resume]") || (E = !0);
1262
+ L.inert = e.mustRate(), a.querySelector("[data-resume]") || (y = !0);
1177
1263
  })), e.onDestroy(() => {
1178
- var o;
1179
- S(), clearTimeout(w), window.removeEventListener("pagehide", D), window.removeEventListener("online", O), a == null || a.cancel(), d.forEach((L) => L.previewUrl && URL.revokeObjectURL(L.previewUrl)), (o = y.querySelector(".recbar")) == null || o.remove();
1180
- }), v.querySelectorAll("[data-prio]").forEach((o) => {
1181
- o.addEventListener("click", () => {
1182
- l = o.dataset.prio, A(), v.querySelectorAll("[data-prio]").forEach((L) => {
1183
- L.setAttribute("aria-pressed", String(L === o));
1264
+ var p;
1265
+ q(), clearTimeout($), window.removeEventListener("pagehide", O), window.removeEventListener("online", N), o == null || o.cancel(), i.forEach((E) => E.previewUrl && URL.revokeObjectURL(E.previewUrl)), (p = d.querySelector(".recbar")) == null || p.remove();
1266
+ }), b.querySelectorAll("[data-prio]").forEach((p) => {
1267
+ p.addEventListener("click", () => {
1268
+ n = p.dataset.prio, H(), b.querySelectorAll("[data-prio]").forEach((E) => {
1269
+ E.setAttribute("aria-pressed", String(E === p));
1184
1270
  });
1185
1271
  });
1186
1272
  });
1187
- const B = s("#bc-title-err");
1188
- function k(o) {
1189
- B.hidden = !o, B.innerHTML = o ? `${G}<span>${m(o)}</span>` : "", h.classList.toggle("invalid", !!o), h.setAttribute("aria-invalid", String(!!o));
1273
+ const B = h("#bc-title-err");
1274
+ function Q(p) {
1275
+ B.hidden = !p, B.innerHTML = p ? `${G}<span>${v(p)}</span>` : "", s.classList.toggle("invalid", !!p), s.setAttribute("aria-invalid", String(!!p));
1190
1276
  }
1191
- h.addEventListener("input", () => {
1192
- h.value.trim() && k("");
1277
+ s.addEventListener("input", () => {
1278
+ s.value.trim() && Q("");
1193
1279
  });
1194
- function M() {
1195
- const o = d.some((C) => C.status === "uploading");
1196
- b.disabled = e.sending || o || d.some((C) => C.status === "failed"), z.textContent = o ? "Waiting for the upload to finish…" : d.some((C) => C.status === "failed") ? "Retry or remove failed attachments before sending." : "";
1197
- const L = n.maxAttachments ?? 5;
1198
- v.querySelectorAll(".tool").forEach((C) => {
1199
- C.disabled = e.sending || d.length >= L;
1280
+ function C() {
1281
+ const p = i.some((I) => I.status === "uploading"), E = e.mustRate();
1282
+ g.disabled = e.sending || p || E || i.some((I) => I.status === "failed"), w.textContent = E ? "Rate your last report to send a new one." : p ? "Waiting for the upload to finish…" : i.some((I) => I.status === "failed") ? "Retry or remove failed attachments before sending." : "";
1283
+ const A = r.maxAttachments ?? 5;
1284
+ b.querySelectorAll(".tool").forEach((I) => {
1285
+ I.disabled = e.sending || i.length >= A;
1200
1286
  });
1201
- const I = s(".field-head .count");
1202
- I && (I.textContent = d.length ? `${d.length} of ${L}` : "");
1203
- }
1204
- e.refreshSendState = M;
1205
- function H(o) {
1206
- var Y;
1207
- const L = o.el, I = o.kind === "VIDEO" ? "Video" : "Shot", C = o.kind === "VIDEO" ? `<video src="${o.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${o.previewUrl}" alt="" />`;
1208
- let R = "";
1209
- o.status === "uploading" ? R = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(o.progress * 100)}%"></i></div></div>` : o.status === "failed" && (R = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${De}</button>Failed</div>`), L.innerHTML = `
1210
- ${C}
1211
- <span class="kind">${I} · ${P(o.size)}</span>
1212
- <button class="drop" type="button" data-act="drop" aria-label="Remove ${I.toLowerCase()}">${de}</button>
1213
- ${R}`, L.querySelector('[data-act="drop"]').addEventListener("click", () => V(o)), (Y = L.querySelector('[data-act="retry"]')) == null || Y.addEventListener("click", () => K(o));
1214
- }
1215
- function V(o) {
1216
- const L = d.indexOf(o);
1217
- L >= 0 && d.splice(L, 1), o.previewUrl && URL.revokeObjectURL(o.previewUrl), o.el.remove(), S(), M();
1218
- }
1219
- async function K(o) {
1220
- o.status = "uploading", o.progress = 0, H(o), M();
1287
+ const R = h(".field-head .count");
1288
+ R && (R.textContent = i.length ? `${i.length} of ${A}` : "");
1289
+ }
1290
+ e.refreshSendState = C;
1291
+ function M(p) {
1292
+ var W;
1293
+ const E = p.el, A = p.kind === "VIDEO" ? "Video" : "Shot", R = p.kind === "VIDEO" ? `<video src="${p.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${p.previewUrl}" alt="" />`;
1294
+ let I = "";
1295
+ p.status === "uploading" ? I = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(p.progress * 100)}%"></i></div></div>` : p.status === "failed" && (I = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Pe}</button>Failed</div>`), E.innerHTML = `
1296
+ ${R}
1297
+ <span class="kind">${A} · ${F(p.size)}</span>
1298
+ <button class="drop" type="button" data-act="drop" aria-label="Remove ${A.toLowerCase()}">${ce}</button>
1299
+ ${I}`, E.querySelector('[data-act="drop"]').addEventListener("click", () => D(p)), (W = E.querySelector('[data-act="retry"]')) == null || W.addEventListener("click", () => V(p));
1300
+ }
1301
+ function D(p) {
1302
+ const E = i.indexOf(p);
1303
+ E >= 0 && i.splice(E, 1), p.previewUrl && URL.revokeObjectURL(p.previewUrl), p.el.remove(), q(), C();
1304
+ }
1305
+ async function V(p) {
1306
+ p.status = "uploading", p.progress = 0, M(p), C();
1221
1307
  try {
1222
- const { storageKey: L, mime: I } = await t.uploadAttachment(o.blob, o.mime, (C) => {
1223
- o.progress = C;
1224
- const R = o.el.querySelector(".bar i");
1225
- R && (R.style.width = `${Math.round(C * 100)}%`);
1308
+ const { storageKey: E, mime: A } = await t.uploadAttachment(p.blob, p.mime, (R) => {
1309
+ p.progress = R;
1310
+ const I = p.el.querySelector(".bar i");
1311
+ I && (I.style.width = `${Math.round(R * 100)}%`);
1226
1312
  });
1227
- o.storageKey = L, o.mime = I, o.status = "ready";
1228
- } catch (L) {
1229
- o.status = "failed", i(L.message.replace("[BugCatch] ", ""));
1313
+ p.storageKey = E, p.mime = A, p.status = "ready";
1314
+ } catch (E) {
1315
+ p.status = "failed", f(E.message.replace("[BugCatch] ", ""));
1230
1316
  }
1231
- H(o), M();
1317
+ M(p), C();
1232
1318
  }
1233
- function N({ blob: o, mime: L, kind: I }) {
1234
- const C = n.maxAttachmentBytes ?? 26214400;
1235
- if (o.size > C) {
1236
- i(`That file is ${P(o.size)} — the limit is ${P(C)}.`);
1319
+ function Y({ blob: p, mime: E, kind: A }) {
1320
+ const R = r.maxAttachmentBytes ?? 26214400;
1321
+ if (p.size > R) {
1322
+ f(`That file is ${F(p.size)} — the limit is ${F(R)}.`);
1237
1323
  return;
1238
1324
  }
1239
- const R = $e(L || o.type, be);
1240
- if (!R) {
1241
- i("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
1325
+ const I = ze(E || p.type, be);
1326
+ if (!I) {
1327
+ f("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
1242
1328
  return;
1243
1329
  }
1244
- const Y = {
1245
- blob: o,
1246
- kind: I,
1247
- mime: R,
1248
- size: o.size,
1249
- previewUrl: URL.createObjectURL(o),
1330
+ const W = {
1331
+ blob: p,
1332
+ kind: A,
1333
+ mime: I,
1334
+ size: p.size,
1335
+ previewUrl: URL.createObjectURL(p),
1250
1336
  status: "uploading",
1251
1337
  progress: 0,
1252
1338
  storageKey: null,
1253
1339
  el: document.createElement("div")
1254
1340
  };
1255
- Y.el.className = "thumb", d.push(Y), Q.appendChild(Y.el), i(""), S(), K(Y);
1341
+ W.el.className = "thumb", i.push(W), x.appendChild(W.el), f(""), q(), V(W);
1256
1342
  }
1257
- async function J(o) {
1258
- u.style.opacity = "0", u.style.pointerEvents = "none", await new Promise((L) => requestAnimationFrame(() => requestAnimationFrame(L)));
1343
+ async function X(p) {
1344
+ u.style.opacity = "0", u.style.pointerEvents = "none", await new Promise((E) => requestAnimationFrame(() => requestAnimationFrame(E)));
1259
1345
  try {
1260
- return await o();
1346
+ return await p();
1261
1347
  } finally {
1262
1348
  u.style.opacity = "", u.style.pointerEvents = "";
1263
1349
  }
1264
1350
  }
1265
- (F = v.querySelector('[data-act="shot"]')) == null || F.addEventListener("click", async () => {
1351
+ (K = b.querySelector('[data-act="shot"]')) == null || K.addEventListener("click", async () => {
1266
1352
  try {
1267
- const o = await J(Se);
1268
- N(o);
1269
- } catch (o) {
1270
- (o == null ? void 0 : o.name) !== "NotAllowedError" && i(`Screenshot failed: ${o.message}`);
1353
+ const p = await X(Me);
1354
+ Y(p);
1355
+ } catch (p) {
1356
+ (p == null ? void 0 : p.name) !== "NotAllowedError" && f(`Screenshot failed: ${p.message}`);
1271
1357
  }
1272
- }), (U = v.querySelector('[data-act="file"]')) == null || U.addEventListener("click", () => c.click()), c == null || c.addEventListener("change", () => {
1273
- const o = (n.maxAttachments ?? 5) - d.length;
1274
- [...c.files].slice(0, Math.max(o, 0)).forEach((L) => {
1275
- N({
1276
- blob: L,
1277
- mime: L.type,
1278
- kind: L.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
1358
+ }), (U = b.querySelector('[data-act="file"]')) == null || U.addEventListener("click", () => T.click()), T == null || T.addEventListener("change", () => {
1359
+ const p = (r.maxAttachments ?? 5) - i.length;
1360
+ [...T.files].slice(0, Math.max(p, 0)).forEach((E) => {
1361
+ Y({
1362
+ blob: E,
1363
+ mime: E.type,
1364
+ kind: E.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
1279
1365
  });
1280
- }), c.value = "";
1281
- }), (q = v.querySelector('[data-act="rec"]')) == null || q.addEventListener("click", async () => {
1282
- const o = n.maxRecordingMs ?? 12e4;
1283
- let L;
1366
+ }), T.value = "";
1367
+ }), (z = b.querySelector('[data-act="rec"]')) == null || z.addEventListener("click", async () => {
1368
+ const p = r.maxRecordingMs ?? 12e4;
1369
+ let E;
1284
1370
  try {
1285
- a = await Qe({
1286
- maxMs: o,
1287
- onTick: (I) => {
1288
- L && (L.querySelector(".time").textContent = te(I));
1371
+ o = await Ce({
1372
+ maxMs: p,
1373
+ onTick: (A) => {
1374
+ E && (E.querySelector(".time").textContent = te(A));
1289
1375
  },
1290
1376
  onAutoStop: () => {
1291
- a && j({ keep: !0 });
1377
+ o && j({ keep: !0 });
1292
1378
  }
1293
1379
  });
1294
- } catch (I) {
1295
- (I == null ? void 0 : I.name) !== "NotAllowedError" && i(`Recording failed: ${I.message}`);
1380
+ } catch (A) {
1381
+ (A == null ? void 0 : A.name) !== "NotAllowedError" && f(`Recording failed: ${A.message}`);
1296
1382
  return;
1297
1383
  }
1298
- v.style.display = "none", T.hidden = !0, L = document.createElement("div"), L.className = "recbar", L.innerHTML = `
1384
+ b.style.display = "none", S.hidden = !0, E = document.createElement("div"), E.className = "recbar", E.innerHTML = `
1299
1385
  <span class="dot"></span>
1300
1386
  <span class="time">0:00</span>
1301
- <span class="hint">Recording — up to ${te(Math.round(o / 1e3))}</span>
1387
+ <span class="hint">Recording — up to ${te(Math.round(p / 1e3))}</span>
1302
1388
  <button class="stop" type="button">Stop</button>
1303
- <button class="ghost" type="button">Discard</button>`, L.querySelector(".stop").addEventListener("click", () => j({ keep: !0 })), L.querySelector(".ghost").addEventListener("click", () => j({ keep: !1 })), y.appendChild(L), L.querySelector(".stop").focus();
1389
+ <button class="ghost" type="button">Discard</button>`, E.querySelector(".stop").addEventListener("click", () => j({ keep: !0 })), E.querySelector(".ghost").addEventListener("click", () => j({ keep: !1 })), d.appendChild(E), E.querySelector(".stop").focus();
1304
1390
  });
1305
- async function j({ keep: o }) {
1306
- var I;
1307
- const L = a;
1308
- if (L) {
1309
- if (a = null, (I = y.querySelector(".recbar")) == null || I.remove(), v.style.display = "", T.hidden = !1, !o) {
1310
- L.cancel(), h.focus();
1391
+ async function j({ keep: p }) {
1392
+ var A;
1393
+ const E = o;
1394
+ if (E) {
1395
+ if (o = null, (A = d.querySelector(".recbar")) == null || A.remove(), b.style.display = "", S.hidden = !1, !p) {
1396
+ E.cancel(), s.focus();
1311
1397
  return;
1312
1398
  }
1313
1399
  try {
1314
- const C = await L.stop();
1315
- C.blob.size ? N(C) : i("That recording came back empty — nothing was captured.");
1316
- } catch (C) {
1317
- i(`Recording failed: ${C.message}`);
1400
+ const R = await E.stop();
1401
+ R.blob.size ? Y(R) : f("That recording came back empty — nothing was captured.");
1402
+ } catch (R) {
1403
+ f(`Recording failed: ${R.message}`);
1318
1404
  }
1319
- h.focus();
1405
+ s.focus();
1320
1406
  }
1321
1407
  }
1322
- e.isRecording = () => !!a, e.stopRecording = j, b.addEventListener("click", async () => {
1323
- var I;
1324
- const o = h.value;
1325
- if (!o.trim()) {
1326
- k("Add a few words about what went wrong — a short sentence is plenty."), h.focus();
1408
+ e.isRecording = () => !!o, e.stopRecording = j, g.addEventListener("click", async () => {
1409
+ var A;
1410
+ const p = s.value;
1411
+ if (!p.trim()) {
1412
+ Q("Add a few words about what went wrong — a short sentence is plenty."), s.focus();
1327
1413
  return;
1328
1414
  }
1329
1415
  if (e.holdForReference()) return;
1330
- e.sending = !0, i(""), M();
1331
- const L = b.innerHTML;
1332
- b.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
1416
+ e.sending = !0, f(""), C();
1417
+ const E = g.innerHTML;
1418
+ g.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
1333
1419
  try {
1334
- const C = await t.report({
1335
- title: o,
1336
- description: g.value,
1337
- priority: l,
1420
+ const R = await t.report({
1421
+ title: p,
1422
+ description: c.value,
1423
+ priority: n,
1338
1424
  references: e.answeredReference(),
1339
- issue: ((I = e.pickedIssue()) == null ? void 0 : I.key) || null,
1340
- attachments: d.filter((R) => R.status === "ready").map((R) => ({ type: R.kind, storageKey: R.storageKey, mime: R.mime }))
1425
+ issue: ((A = e.pickedIssue()) == null ? void 0 : A.key) || null,
1426
+ attachments: i.filter((I) => I.status === "ready").map((I) => ({ type: I.kind, storageKey: I.storageKey, mime: I.mime }))
1341
1427
  });
1342
- if (C != null && C.cancelled) {
1343
- e.sending = !1, b.innerHTML = L, M();
1428
+ if (R != null && R.cancelled) {
1429
+ e.sending = !1, g.innerHTML = E, C();
1344
1430
  return;
1345
1431
  }
1346
- x = !0, clearTimeout(w), await p, n.drafts !== !1 && await ae($, null).catch(() => {
1347
- }), e.succeed(C);
1348
- } catch (C) {
1349
- e.sending = !1, b.innerHTML = L, i(C.message.replace("[BugCatch] ", "")), M(), e.recheckSignIn();
1432
+ m = !0, clearTimeout($), await l, r.drafts !== !1 && await ae(k, null).catch(() => {
1433
+ }), e.succeed(R);
1434
+ } catch (R) {
1435
+ e.sending = !1, g.innerHTML = E, f(R.message.replace("[BugCatch] ", "")), C(), e.recheckSignIn();
1350
1436
  }
1351
1437
  });
1352
1438
  }
1353
- function Je(e) {
1439
+ function it(e) {
1354
1440
  const {
1355
1441
  client: t,
1356
- say: n,
1357
- titleInput: y,
1442
+ say: r,
1443
+ titleInput: d,
1358
1444
  descInput: u,
1359
- sendBtn: T,
1360
- refsBox: v
1445
+ sendBtn: S,
1446
+ refsBox: b
1361
1447
  } = e;
1362
- let s = { policy: "off", fields: [] }, i = !1, h = null, g = "", f = "", b = [], z = "ask", Q = !1, c = !1;
1363
- t.referenceFields().then((k) => {
1364
- s = k, E();
1448
+ let h = { policy: "off", fields: [] }, f = !1, s = null, c = "", L = "", g = [], w = "ask", x = !1, T = !1;
1449
+ t.referenceFields().then((Q) => {
1450
+ h = Q, y();
1365
1451
  }).catch(() => {
1366
1452
  });
1367
- function d() {
1368
- return s.policy === "off" || !s.fields.length ? { found: [], conflicts: [], loose: [] } : Le(s.fields, [y.value, u.value]);
1369
- }
1370
- function l(k = d()) {
1371
- return k.found.length > 0 && k.conflicts.length === 0;
1372
- }
1373
- function a() {
1374
- return !h || !g.trim() ? [] : [{ key: h, value: g.trim().slice(0, 120) }];
1375
- }
1376
- const r = document.createElement("p");
1377
- r.className = "ref-found", r.setAttribute("aria-live", "polite"), r.hidden = !0, u.closest(".field").after(r);
1378
- let $;
1379
- function E() {
1380
- const k = d();
1381
- if (l(k)) {
1382
- const M = k.found.slice(0, 2).map((H) => `${m(H.label)} <b>${m(p(H.value))}</b>`).join(", ");
1383
- r.innerHTML = `${W}<span>Found your ${M} — no need to add it again.</span>`, r.hidden = !1, i && !a().length && (i = !1, A());
1453
+ function i() {
1454
+ return h.policy === "off" || !h.fields.length ? { found: [], conflicts: [], loose: [] } : He(h.fields, [d.value, u.value]);
1455
+ }
1456
+ function n(Q = i()) {
1457
+ return Q.found.length > 0 && Q.conflicts.length === 0;
1458
+ }
1459
+ function o() {
1460
+ return !s || !c.trim() ? [] : [{ key: s, value: c.trim().slice(0, 120) }];
1461
+ }
1462
+ const a = document.createElement("p");
1463
+ a.className = "ref-found", a.setAttribute("aria-live", "polite"), a.hidden = !0, u.closest(".field").after(a);
1464
+ let k;
1465
+ function y() {
1466
+ const Q = i();
1467
+ if (n(Q)) {
1468
+ const C = Q.found.slice(0, 2).map((M) => `${v(M.label)} <b>${v(l(M.value))}</b>`).join(", ");
1469
+ a.innerHTML = `${P}<span>Found your ${C} — no need to add it again.</span>`, a.hidden = !1, f && !o().length && (f = !1, H());
1384
1470
  } else
1385
- r.hidden = !0, r.innerHTML = "";
1471
+ a.hidden = !0, a.innerHTML = "";
1386
1472
  }
1387
- const x = () => {
1388
- clearTimeout($), $ = setTimeout(E, 250);
1473
+ const m = () => {
1474
+ clearTimeout(k), k = setTimeout(y, 250);
1389
1475
  };
1390
- y.addEventListener("input", x), u.addEventListener("input", x);
1391
- function p(k) {
1392
- return k.length > 20 ? `${k.slice(0, 8)}…${k.slice(-4)}` : k;
1476
+ d.addEventListener("input", m), u.addEventListener("input", m);
1477
+ function l(Q) {
1478
+ return Q.length > 20 ? `${Q.slice(0, 8)}…${Q.slice(-4)}` : Q;
1393
1479
  }
1394
- function w(k) {
1395
- const M = k.trim().toLowerCase();
1396
- return b.find((H) => H.value.toLowerCase() === M) || null;
1480
+ function $(Q) {
1481
+ const C = Q.trim().toLowerCase();
1482
+ return g.find((M) => M.value.toLowerCase() === C) || null;
1397
1483
  }
1398
- function S(k) {
1399
- g = k.value, k.kinds.length === 1 ? h = k.kinds[0].key : k.kinds.some((M) => M.key === h) || (h = null), f = "", c = !1;
1484
+ function q(Q) {
1485
+ c = Q.value, Q.kinds.length === 1 ? s = Q.kinds[0].key : Q.kinds.some((C) => C.key === s) || (s = null), L = "", T = !1;
1400
1486
  }
1401
- function A() {
1402
- var F, U;
1403
- if (!i) {
1404
- v.hidden = !0, v.innerHTML = "";
1487
+ function H() {
1488
+ var K, U;
1489
+ if (!f) {
1490
+ b.hidden = !0, b.innerHTML = "";
1405
1491
  return;
1406
1492
  }
1407
- const k = s.fields.find((q) => q.key === h) || null, M = s.policy !== "required", H = w(g), V = H && H.kinds.length > 1 ? s.fields.filter((q) => H.kinds.some((o) => o.key === q.key)) : s.fields, K = b.length > 1 && b.every((q) => q.kinds.length === 1 && q.kinds[0].key === b[0].kinds[0].key), N = {
1408
- confirm: b.length > 1 ? ["Which one is this about?", "We found more than one ID in your message. Pick the one this problem is about."] : ["Is this the right ID?", "This could be more than one kind of ID. Tell us which it is."],
1493
+ const Q = h.fields.find((z) => z.key === s) || null, C = h.policy !== "required", M = $(c), D = M && M.kinds.length > 1 ? h.fields.filter((z) => M.kinds.some((p) => p.key === z.key)) : h.fields, V = g.length > 1 && g.every((z) => z.kinds.length === 1 && z.kinds[0].key === g[0].kinds[0].key), Y = {
1494
+ confirm: g.length > 1 ? ["Which one is this about?", "We found more than one ID in your message. Pick the one this problem is about."] : ["Is this the right ID?", "This could be more than one kind of ID. Tell us which it is."],
1409
1495
  suggest: ["Is this your ID?", "We spotted this in your message. Tell us what it is so we can find your record."],
1410
- ask: M ? ["One more thing", "So we can find your record — this helps us answer faster."] : ["We need one detail", "We need one of these to look this up."]
1411
- }[z];
1412
- v.hidden = !1;
1413
- const J = V.length > 6;
1414
- v.innerHTML = `
1496
+ ask: C ? ["One more thing", "So we can find your record — this helps us answer faster."] : ["We need one detail", "We need one of these to look this up."]
1497
+ }[w];
1498
+ b.hidden = !1;
1499
+ const X = D.length > 6;
1500
+ b.innerHTML = `
1415
1501
  <div class="ask-head">
1416
- <span class="avatar" aria-hidden="true">${X}</span>
1502
+ <span class="avatar orb" aria-hidden="true"></span>
1417
1503
  <div>
1418
- <strong>${m(N[0])}</strong>
1419
- <p class="why">${m(N[1])}</p>
1504
+ <strong>${v(Y[0])}</strong>
1505
+ <p class="why">${v(Y[1])}</p>
1420
1506
  </div>
1421
1507
  </div>
1422
- ${b.length > 1 ? `
1508
+ ${g.length > 1 ? `
1423
1509
  <div class="chips cands" role="group" aria-label="IDs found in your message">
1424
- ${b.map((q, o) => `
1425
- <button type="button" data-ref-cand="${o}" title="${m(q.value)}"
1426
- aria-pressed="${!!H && H === q}">${m(p(q.value))}</button>
1510
+ ${g.map((z, p) => `
1511
+ <button type="button" data-ref-cand="${p}" title="${v(z.value)}"
1512
+ aria-pressed="${!!M && M === z}">${v(l(z.value))}</button>
1427
1513
  `).join("")}
1428
1514
  </div>` : ""}
1429
- ${V.length > 1 && !J && !K ? `
1515
+ ${D.length > 1 && !X && !V ? `
1430
1516
  <div class="chips" role="group" aria-label="Which detail you are giving">
1431
- ${V.map((q) => `
1432
- <button type="button" data-ref-kind="${m(q.key)}" aria-pressed="${!!k && q.key === k.key}">${m(q.label)}</button>
1517
+ ${D.map((z) => `
1518
+ <button type="button" data-ref-kind="${v(z.key)}" aria-pressed="${!!Q && z.key === Q.key}">${v(z.label)}</button>
1433
1519
  `).join("")}
1434
1520
  </div>` : ""}
1435
1521
  <div class="row">
1436
- ${J ? `
1522
+ ${X ? `
1437
1523
  <select class="ref-kind" aria-label="Which detail you are giving">
1438
- ${k ? "" : '<option value="" selected disabled>What is it?</option>'}
1439
- ${V.map((q) => `
1440
- <option value="${m(q.key)}" ${k && q.key === k.key ? "selected" : ""}>${m(q.label)}</option>
1524
+ ${Q ? "" : '<option value="" selected disabled>What is it?</option>'}
1525
+ ${D.map((z) => `
1526
+ <option value="${v(z.key)}" ${Q && z.key === Q.key ? "selected" : ""}>${v(z.label)}</option>
1441
1527
  `).join("")}
1442
1528
  </select>` : ""}
1443
- <input class="ref-value${f ? " invalid" : ""}" type="${(k == null ? void 0 : k.inputMode) === "email" ? "email" : "text"}"
1444
- inputmode="${m((k == null ? void 0 : k.inputMode) === "numeric" || (k == null ? void 0 : k.inputMode) === "tel" ? "numeric" : "text")}"
1445
- value="${m(g)}"
1446
- placeholder="${m(k ? k.placeholder || k.label : "Your ID")}"
1447
- aria-label="${m(k ? k.label : "Your ID")}" ${f ? 'aria-invalid="true"' : ""} />
1529
+ <input class="ref-value${L ? " invalid" : ""}" type="${(Q == null ? void 0 : Q.inputMode) === "email" ? "email" : "text"}"
1530
+ inputmode="${v((Q == null ? void 0 : Q.inputMode) === "numeric" || (Q == null ? void 0 : Q.inputMode) === "tel" ? "numeric" : "text")}"
1531
+ value="${v(c)}"
1532
+ placeholder="${v(Q ? Q.placeholder || Q.label : "Your ID")}"
1533
+ aria-label="${v(Q ? Q.label : "Your ID")}" ${L ? 'aria-invalid="true"' : ""} />
1448
1534
  </div>
1449
- ${k != null && k.hint ? `<p class="hint">${m(k.hint)}</p>` : ""}
1450
- ${f ? `<p class="field-err" role="alert">${G}<span>${m(f)}</span></p>` : ""}
1451
- ${M ? `<button type="button" class="link" data-act="ref-skip">${z === "ask" ? "I don't have this — send without it" : "Not sure — send as it is"}</button>` : ""}`, v.querySelectorAll("[data-ref-cand]").forEach((q) => {
1452
- q.addEventListener("click", () => {
1453
- S(b[Number(q.dataset.refCand)]), A();
1535
+ ${Q != null && Q.hint ? `<p class="hint">${v(Q.hint)}</p>` : ""}
1536
+ ${L ? `<p class="field-err" role="alert">${G}<span>${v(L)}</span></p>` : ""}
1537
+ ${C ? `<button type="button" class="link" data-act="ref-skip">${w === "ask" ? "I don't have this — send without it" : "Not sure — send as it is"}</button>` : ""}`, b.querySelectorAll("[data-ref-cand]").forEach((z) => {
1538
+ z.addEventListener("click", () => {
1539
+ q(g[Number(z.dataset.refCand)]), H();
1454
1540
  });
1455
- }), v.querySelectorAll("[data-ref-kind]").forEach((q) => {
1456
- q.addEventListener("click", () => {
1457
- h = q.dataset.refKind, f = "", c = !1, A();
1541
+ }), b.querySelectorAll("[data-ref-kind]").forEach((z) => {
1542
+ z.addEventListener("click", () => {
1543
+ s = z.dataset.refKind, L = "", T = !1, H();
1458
1544
  });
1459
1545
  });
1460
- const j = v.querySelector(".ref-value");
1546
+ const j = b.querySelector(".ref-value");
1461
1547
  j.addEventListener("input", () => {
1462
- g = j.value, f = "", c = !1;
1463
- }), j.addEventListener("keydown", (q) => {
1464
- q.key === "Enter" && (q.preventDefault(), T.click());
1465
- }), (F = v.querySelector(".ref-kind")) == null || F.addEventListener("change", (q) => {
1466
- var o;
1467
- h = q.target.value, f = "", A(), (o = v.querySelector(".ref-value")) == null || o.focus();
1468
- }), (U = v.querySelector('[data-act="ref-skip"]')) == null || U.addEventListener("click", () => {
1469
- Q = !0, i = !1, h = null, g = "", f = "", c = !1, A(), n("");
1470
- }), ((!k && g ? v.querySelector("[data-ref-kind], .ref-kind") : null) || j).focus();
1471
- }
1472
- function D(k) {
1473
- if (b = k.conflicts.length ? k.conflicts : k.loose.slice(0, 4), z = k.conflicts.length ? "confirm" : k.loose.length ? "suggest" : "ask", i = !0, b.length)
1474
- if (b.length === 1) S(b[0]);
1548
+ c = j.value, L = "", T = !1;
1549
+ }), j.addEventListener("keydown", (z) => {
1550
+ z.key === "Enter" && (z.preventDefault(), S.click());
1551
+ }), (K = b.querySelector(".ref-kind")) == null || K.addEventListener("change", (z) => {
1552
+ var p;
1553
+ s = z.target.value, L = "", H(), (p = b.querySelector(".ref-value")) == null || p.focus();
1554
+ }), (U = b.querySelector('[data-act="ref-skip"]')) == null || U.addEventListener("click", () => {
1555
+ x = !0, f = !1, s = null, c = "", L = "", T = !1, H(), r("");
1556
+ }), ((!Q && c ? b.querySelector("[data-ref-kind], .ref-kind") : null) || j).focus();
1557
+ }
1558
+ function O(Q) {
1559
+ if (g = Q.conflicts.length ? Q.conflicts : Q.loose.slice(0, 4), w = Q.conflicts.length ? "confirm" : Q.loose.length ? "suggest" : "ask", f = !0, g.length)
1560
+ if (g.length === 1) q(g[0]);
1475
1561
  else {
1476
- g = "";
1477
- const [M] = b;
1478
- h = b.every((V) => V.kinds.length === 1 && V.kinds[0].key === M.kinds[0].key) ? M.kinds[0].key : null;
1562
+ c = "";
1563
+ const [C] = g;
1564
+ s = g.every((D) => D.kinds.length === 1 && D.kinds[0].key === C.kinds[0].key) ? C.kinds[0].key : null;
1479
1565
  }
1480
1566
  else
1481
- h = h || s.fields[0].key;
1482
- A();
1567
+ s = s || h.fields[0].key;
1568
+ H();
1483
1569
  }
1484
- function O() {
1485
- if (s.policy === "off" || !s.fields.length || a().length) return !1;
1486
- const k = d();
1487
- return l(k) || Q && s.policy !== "required" ? !1 : k;
1570
+ function N() {
1571
+ if (h.policy === "off" || !h.fields.length || o().length) return !1;
1572
+ const Q = i();
1573
+ return n(Q) || x && h.policy !== "required" ? !1 : Q;
1488
1574
  }
1489
1575
  function B() {
1490
- if (i && g.trim() && !h)
1491
- return f = "Pick what this ID is.", A(), !0;
1492
- const k = O();
1493
- if (k)
1494
- return i ? A() : D(k), n(""), !0;
1495
- if (h && g.trim()) {
1496
- const M = s.fields.find((H) => H.key === h);
1497
- if (!c && M && !Te(M, g))
1498
- return f = `That does not look like a ${M.label.toLowerCase()}. Press Send again to use it anyway.`, c = !0, A(), !0;
1576
+ if (f && c.trim() && !s)
1577
+ return L = "Pick what this ID is.", H(), !0;
1578
+ const Q = N();
1579
+ if (Q)
1580
+ return f ? H() : O(Q), r(""), !0;
1581
+ if (s && c.trim()) {
1582
+ const C = h.fields.find((M) => M.key === s);
1583
+ if (!T && C && !Ae(C, c))
1584
+ return L = `That does not look like a ${C.label.toLowerCase()}. Press Send again to use it anyway.`, T = !0, H(), !0;
1499
1585
  }
1500
1586
  return !1;
1501
1587
  }
1502
- e.holdForReference = B, e.answeredReference = a;
1588
+ e.holdForReference = B, e.answeredReference = o;
1503
1589
  }
1504
- const et = 3;
1505
- function tt(e) {
1506
- const { client: t, cfg: n, notices: y } = e;
1590
+ const st = 3;
1591
+ function lt(e) {
1592
+ const { client: t, cfg: r, notices: d } = e;
1507
1593
  let u = [];
1508
- function T() {
1509
- const s = u.slice(0, et);
1510
- y.replaceChildren(...s.map((i) => ze(i, { where: "panel", onDismiss: v }))), y.hidden = s.length === 0;
1594
+ function S() {
1595
+ const h = u.slice(0, st);
1596
+ d.replaceChildren(...h.map((f) => Re(f, { where: "panel", onDismiss: b }))), d.hidden = h.length === 0;
1511
1597
  }
1512
- function v(s) {
1513
- t.dismissAnnouncement(s), u = u.filter((i) => i !== s), T(), e.titleInput.focus();
1598
+ function b(h) {
1599
+ t.dismissAnnouncement(h), u = u.filter((f) => f !== h), S(), e.titleInput.focus();
1514
1600
  }
1515
- n.announcements !== !1 && typeof t.announcements == "function" && t.announcements().then((s) => {
1516
- e.closed || (u = s, T());
1601
+ r.announcements !== !1 && typeof t.announcements == "function" && t.announcements().then((h) => {
1602
+ e.closed || (u = h, S());
1517
1603
  }).catch(() => {
1518
1604
  });
1519
1605
  }
1520
- function at(e) {
1606
+ function ct(e) {
1521
1607
  const {
1522
1608
  client: t,
1523
- cfg: n,
1524
- titleInput: y,
1609
+ cfg: r,
1610
+ titleInput: d,
1525
1611
  known: u
1526
1612
  } = e;
1527
- let T = [], v = "", s = null, i = null;
1528
- function h() {
1529
- n.knownIssues !== !1 && t.knownIssues().then((Q) => {
1530
- T = Q, b();
1613
+ let S = [], b = "", h = null, f = null;
1614
+ function s() {
1615
+ r.knownIssues !== !1 && t.knownIssues().then((x) => {
1616
+ S = x, g();
1531
1617
  }).catch(() => {
1532
1618
  });
1533
1619
  }
1534
- let g = null;
1535
- function f(Q) {
1536
- if (n.knownIssues === !1) return;
1537
- clearTimeout(g), i == null || i.abort();
1538
- const c = (Q || "").trim();
1539
- if (c.length < 3) {
1540
- h();
1620
+ let c = null;
1621
+ function L(x) {
1622
+ if (r.knownIssues === !1) return;
1623
+ clearTimeout(c), f == null || f.abort();
1624
+ const T = (x || "").trim();
1625
+ if (T.length < 3) {
1626
+ s();
1541
1627
  return;
1542
1628
  }
1543
- g = setTimeout(() => {
1544
- i = new AbortController(), t.matchKnownIssues(c, { signal: i.signal }).then((d) => {
1545
- d.length && (T = d, b());
1629
+ c = setTimeout(() => {
1630
+ f = new AbortController(), t.matchKnownIssues(T, { signal: f.signal }).then((i) => {
1631
+ i.length && (S = i, g());
1546
1632
  }).catch(() => {
1547
1633
  });
1548
1634
  }, 250);
1549
1635
  }
1550
- function b() {
1551
- if (!T.length) {
1636
+ function g() {
1637
+ if (!S.length) {
1552
1638
  u.hidden = !0, u.innerHTML = "";
1553
1639
  return;
1554
1640
  }
1555
1641
  u.hidden = !1, u.innerHTML = `
1556
1642
  <p class="known-h">Already reported</p>
1557
- ${T.map((Q) => `
1558
- <div class="issue ${Q.joined ? "is-joined" : ""}">
1643
+ ${S.map((x) => `
1644
+ <div class="issue ${x.joined ? "is-joined" : ""}">
1559
1645
  <span class="who">
1560
- <span class="t">${m(Q.title)}</span>
1561
- <span class="meta">${m(z(Q))}</span>
1646
+ <span class="t">${v(x.title)}</span>
1647
+ <span class="meta">${v(w(x))}</span>
1562
1648
  </span>
1563
- <button class="join" type="button" data-join="${m(Q.id)}"
1564
- ${Q.joined ? "disabled" : ""}>${Q.joined ? "Following" : "Me too"}</button>
1649
+ <button class="join" type="button" data-join="${v(x.id)}"
1650
+ ${x.joined ? "disabled" : ""}>${x.joined ? "Following" : "Me too"}</button>
1565
1651
  </div>
1566
- ${s === Q.id ? `
1652
+ ${h === x.id ? `
1567
1653
  <div class="ask">
1568
1654
  <input type="email" class="join-email" placeholder="you@example.com"
1569
1655
  aria-label="Your email, so we can tell you when this is fixed" />
1570
- <button class="ghost" type="button" data-join-confirm="${m(Q.id)}">Follow</button>
1656
+ <button class="ghost" type="button" data-join-confirm="${v(x.id)}">Follow</button>
1571
1657
  </div>` : ""}
1572
1658
  `).join("")}
1573
- ${v ? `<p class="err">${m(v)}</p>` : ""}`;
1574
- }
1575
- function z(Q) {
1576
- const c = Q.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", d = Q.affectedCount === 0 ? "" : ` · ${Q.affectedCount} ${Q.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
1577
- return `${c} · reported ${oe(Q.since)}${d}`;
1578
- }
1579
- u.addEventListener("click", async (Q) => {
1580
- var r, $, E, x, p;
1581
- const c = Q.target.closest("[data-join]"), d = Q.target.closest("[data-join-confirm]");
1582
- if (!c && !d) return;
1583
- const l = (d || c).getAttribute(d ? "data-join-confirm" : "data-join");
1584
- v = "";
1585
- const a = (($ = (r = u.querySelector(".join-email")) == null ? void 0 : r.value) == null ? void 0 : $.trim()) || ((E = t.signedInAs()) == null ? void 0 : E.email) || ((x = t.config.user) == null ? void 0 : x.email);
1586
- if (!a) {
1587
- s = l, b(), (p = u.querySelector(".join-email")) == null || p.focus();
1659
+ ${b ? `<p class="err">${v(b)}</p>` : ""}`;
1660
+ }
1661
+ function w(x) {
1662
+ const T = x.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", i = x.affectedCount === 0 ? "" : ` · ${x.affectedCount} ${x.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
1663
+ return `${T} · reported ${J(x.since)}${i}`;
1664
+ }
1665
+ u.addEventListener("click", async (x) => {
1666
+ var a, k, y, m, l;
1667
+ const T = x.target.closest("[data-join]"), i = x.target.closest("[data-join-confirm]");
1668
+ if (!T && !i) return;
1669
+ const n = (i || T).getAttribute(i ? "data-join-confirm" : "data-join");
1670
+ b = "";
1671
+ const o = ((k = (a = u.querySelector(".join-email")) == null ? void 0 : a.value) == null ? void 0 : k.trim()) || ((y = t.signedInAs()) == null ? void 0 : y.email) || ((m = t.config.user) == null ? void 0 : m.email);
1672
+ if (!o) {
1673
+ h = n, g(), (l = u.querySelector(".join-email")) == null || l.focus();
1588
1674
  return;
1589
1675
  }
1590
1676
  try {
1591
- const w = await t.meToo(l, { email: a });
1592
- s = null, T = T.map((S) => S.id === l ? { ...S, joined: !0, affectedCount: w.affectedCount ?? S.affectedCount } : S), b();
1593
- } catch (w) {
1594
- v = w.message.replace("[BugCatch] ", ""), b();
1677
+ const $ = await t.meToo(n, { email: o });
1678
+ h = null, S = S.map((q) => q.id === n ? { ...q, joined: !0, affectedCount: $.affectedCount ?? q.affectedCount } : q), g();
1679
+ } catch ($) {
1680
+ b = $.message.replace("[BugCatch] ", ""), g();
1595
1681
  }
1596
- }), h(), y.addEventListener("input", () => f(y.value));
1682
+ }), s(), d.addEventListener("input", () => L(d.value));
1597
1683
  }
1598
- function nt(e) {
1684
+ function dt(e) {
1599
1685
  const {
1600
1686
  client: t,
1601
- cfg: n,
1602
- titleInput: y,
1687
+ cfg: r,
1688
+ titleInput: d,
1603
1689
  descInput: u,
1604
- picks: T
1690
+ picks: S
1605
1691
  } = e;
1606
- let v = [], s = null;
1607
- function i() {
1608
- if (!v.length) {
1609
- T.hidden = !0, T.innerHTML = "";
1692
+ let b = [], h = null;
1693
+ function f() {
1694
+ if (!b.length) {
1695
+ S.hidden = !0, S.innerHTML = "";
1610
1696
  return;
1611
1697
  }
1612
- T.hidden = !1, T.innerHTML = `
1698
+ S.hidden = !1, S.innerHTML = `
1613
1699
  <p class="picks-h">Get an answer right away</p>
1614
1700
  <div class="picks-grid" role="group" aria-label="Common questions">
1615
- ${v.map((h) => `
1616
- <button type="button" class="pick" data-pick="${m(h.key)}"
1617
- aria-pressed="${(s == null ? void 0 : s.key) === h.key}">
1618
- <span class="t">${m(h.title)}</span>
1619
- ${h.hint ? `<span class="h">${m(h.hint)}</span>` : ""}
1701
+ ${b.map((s, c) => `
1702
+ <button type="button" class="pick" data-pick="${v(s.key)}"
1703
+ ${s.hint ? `title="${v(s.hint)}" aria-describedby="bc-pick-h${c}"` : ""}
1704
+ aria-pressed="${(h == null ? void 0 : h.key) === s.key}">
1705
+ <span class="t">${v(s.title)}</span>
1706
+ ${s.hint ? `<span class="h sr-only" id="bc-pick-h${c}">${v(s.hint)}</span>` : ""}
1620
1707
  </button>`).join("")}
1621
1708
  </div>
1622
- ${s ? `<p class="picks-note">${W}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>` : ""}`;
1623
- }
1624
- T.addEventListener("click", (h) => {
1625
- const g = h.target.closest("[data-pick]");
1626
- if (!g) return;
1627
- const f = v.find((z) => z.key === g.dataset.pick);
1628
- if (!f) return;
1629
- const b = s && y.value.trim() === s.title;
1630
- (s == null ? void 0 : s.key) === f.key ? (s = null, b && (y.value = "")) : (s = f, (!y.value.trim() || b) && (y.value = f.title)), y.dispatchEvent(new Event("input", { bubbles: !0 })), i(), s && u.focus();
1631
- }), n.agentIssues !== !1 && typeof t.agentIssues == "function" && t.agentIssues().then((h) => {
1632
- v = h, i();
1709
+ ${h ? `<p class="picks-note">${P}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>` : ""}`;
1710
+ }
1711
+ S.addEventListener("click", (s) => {
1712
+ const c = s.target.closest("[data-pick]");
1713
+ if (!c) return;
1714
+ const L = b.find((w) => w.key === c.dataset.pick);
1715
+ if (!L) return;
1716
+ const g = h && d.value.trim() === h.title;
1717
+ (h == null ? void 0 : h.key) === L.key ? (h = null, g && (d.value = "")) : (h = L, (!d.value.trim() || g) && (d.value = L.title)), d.dispatchEvent(new Event("input", { bubbles: !0 })), f(), h && u.focus();
1718
+ }), r.agentIssues !== !1 && typeof t.agentIssues == "function" && t.agentIssues().then((s) => {
1719
+ b = s, f();
1633
1720
  }).catch(() => {
1634
- }), e.pickedIssue = () => s;
1721
+ }), e.pickedIssue = () => h;
1635
1722
  }
1636
- function ot(e) {
1723
+ function pt(e) {
1637
1724
  const {
1638
1725
  client: t,
1639
- scrim: n,
1640
- say: y,
1726
+ scrim: r,
1727
+ say: d,
1641
1728
  callBtn: u,
1642
- close: T
1729
+ close: S
1643
1730
  } = e;
1644
- let v = !1;
1645
- function s() {
1646
- t.callKind().then((g) => {
1647
- g && (v = !0, e.preloadCall(), u.hidden = e.mustSignIn());
1731
+ let b = !1;
1732
+ function h() {
1733
+ t.callKind().then((c) => {
1734
+ c && (b = !0, e.preloadCall(), u.hidden = e.mustSignIn() || e.mustRate());
1648
1735
  }).catch(() => {
1649
1736
  });
1650
1737
  }
1651
- s(), u.addEventListener("click", async () => {
1652
- e.sending = !0, y(""), e.refreshSendState(), u.disabled = !0, u.innerHTML = '<span class="spinner"></span>Ringing…';
1738
+ h(), u.addEventListener("click", async () => {
1739
+ e.sending = !0, d(""), e.refreshSendState(), u.disabled = !0, u.innerHTML = '<span class="spinner"></span>Ringing…';
1653
1740
  try {
1654
- const g = await t.startCall();
1655
- i(g);
1656
- } catch (g) {
1657
- e.sending = !1, u.disabled = !1, u.innerHTML = `${ne}Talk to the team`, e.refreshSendState(), g.filed ? e.succeed(g.filed, { callFailed: g.reason || "The call could not be started." }) : (y(g.message.replace("[BugCatch] ", "")), e.recheckSignIn());
1741
+ const c = await t.startCall();
1742
+ f(c);
1743
+ } catch (c) {
1744
+ e.sending = !1, u.disabled = !1, u.innerHTML = `${re}Talk to the team`, e.refreshSendState(), c.filed ? e.succeed(c.filed, { callFailed: c.reason || "The call could not be started." }) : (d(c.message.replace("[BugCatch] ", "")), e.recheckSignIn());
1658
1745
  }
1659
1746
  });
1660
- function i(g) {
1661
- const f = n.querySelector(".panel"), b = g != null && g.bugId ? String(g.bugId).slice(0, 8) : null;
1662
- f.innerHTML = `
1747
+ function f(c) {
1748
+ const L = r.querySelector(".panel"), g = c != null && c.bugId ? String(c.bugId).slice(0, 8) : null;
1749
+ L.innerHTML = `
1663
1750
  <div class="call">
1664
1751
  <div class="call-head">
1665
1752
  <span class="call-dot" aria-hidden="true"></span>
1666
1753
  <strong class="call-state">Ringing…</strong>
1667
1754
  </div>
1668
1755
  <p class="call-note">
1669
- We're ringing the team now. Someone will pick up if they're free — your report${b ? ` <code>${m(b)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
1756
+ We're ringing the team now. Someone will pick up if they're free — your report${g ? ` <code>${v(g)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
1670
1757
  </p>
1671
1758
  <div class="foot">
1672
1759
  <span class="spacer"></span>
1673
1760
  <button class="primary" type="button" data-act="hangup">Cancel</button>
1674
1761
  </div>
1675
1762
  </div>`;
1676
- const z = f.querySelector(".call-state"), Q = f.querySelector(".call-dot"), c = {
1763
+ const w = L.querySelector(".call-state"), x = L.querySelector(".call-dot"), T = {
1677
1764
  ringing: "Ringing the team…",
1678
1765
  connecting: "Someone answered — connecting…",
1679
1766
  connected: "Connected",
1680
1767
  missed: "Nobody was free",
1681
1768
  ended: "Call ended",
1682
1769
  failed: "The call dropped"
1683
- }, d = ["ended", "failed", "missed"], l = t.on("call", ({ state: a }) => {
1684
- if (z.textContent = c[a] || a, Q.classList.toggle("off", d.includes(a)), d.includes(a) && (f.querySelector('[data-act="hangup"]').textContent = "Close", a === "missed")) {
1685
- const r = f.querySelector(".call-note");
1686
- r && (r.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
1770
+ }, i = ["ended", "failed", "missed"], n = t.on("call", ({ state: o }) => {
1771
+ if (w.textContent = T[o] || o, x.classList.toggle("off", i.includes(o)), i.includes(o) && (L.querySelector('[data-act="hangup"]').textContent = "Close", o === "missed")) {
1772
+ const a = L.querySelector(".call-note");
1773
+ a && (a.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
1687
1774
  }
1688
1775
  });
1689
- f.querySelector('[data-act="hangup"]').addEventListener("click", () => {
1690
- l(), t.endCall(), T();
1776
+ L.querySelector('[data-act="hangup"]').addEventListener("click", () => {
1777
+ n(), t.endCall(), S();
1691
1778
  });
1692
1779
  }
1693
- function h(g, f, b) {
1694
- const z = document.createElement("div");
1695
- z.className = "livecall", z.innerHTML = `
1780
+ function s(c, L, g) {
1781
+ const w = document.createElement("div");
1782
+ w.className = "livecall", w.innerHTML = `
1696
1783
  <span class="call-dot" aria-hidden="true"></span>
1697
1784
  <span class="who" role="status" aria-live="polite">Calling the team…</span>
1698
1785
  <span class="secs" hidden></span>
1699
- ${b != null && b.recorded ? '<span class="call-kept">This call is recorded.</span>' : ""}
1786
+ ${g != null && g.recorded ? '<span class="call-kept">This call is recorded.</span>' : ""}
1700
1787
  <button class="act" type="button" data-act="mute" hidden>Mute</button>
1701
- <button class="act danger" type="button" data-act="hangup">Cancel</button>`, g.insertBefore(z, f);
1702
- const Q = z.querySelector(".who"), c = z.querySelector(".secs"), d = z.querySelector(".call-dot"), l = z.querySelector('[data-act="mute"]'), a = z.querySelector('[data-act="hangup"]');
1703
- let r = null;
1704
- const $ = () => {
1705
- r && (clearInterval(r), r = null);
1706
- }, E = (p) => {
1707
- $(), d.classList.add("off"), z.classList.add("over"), Q.textContent = p, c.hidden = !0, l.hidden = !0, a.textContent = "Dismiss", a.classList.remove("danger");
1708
- }, x = t.on("call", ({ state: p }) => {
1709
- if (p === "ringing" && (Q.textContent = "Calling the team…"), p === "connecting" && (Q.textContent = "Someone answered — connecting…"), p === "connected") {
1710
- Q.textContent = "You're on a call with the team", l.hidden = !1, c.hidden = !1;
1711
- const w = Date.now();
1712
- $(), r = setInterval(() => {
1713
- c.textContent = te(Math.floor((Date.now() - w) / 1e3));
1714
- }, 1e3), c.textContent = "0s";
1788
+ <button class="act danger" type="button" data-act="hangup">Cancel</button>`, c.insertBefore(w, L);
1789
+ const x = w.querySelector(".who"), T = w.querySelector(".secs"), i = w.querySelector(".call-dot"), n = w.querySelector('[data-act="mute"]'), o = w.querySelector('[data-act="hangup"]');
1790
+ let a = null;
1791
+ const k = () => {
1792
+ a && (clearInterval(a), a = null);
1793
+ }, y = (l) => {
1794
+ k(), i.classList.add("off"), w.classList.add("over"), x.textContent = l, T.hidden = !0, n.hidden = !0, o.textContent = "Dismiss", o.classList.remove("danger");
1795
+ }, m = t.on("call", ({ state: l }) => {
1796
+ if (l === "ringing" && (x.textContent = "Calling the team…"), l === "connecting" && (x.textContent = "Someone answered — connecting…"), l === "connected") {
1797
+ x.textContent = "You're on a call with the team", n.hidden = !1, T.hidden = !1;
1798
+ const $ = Date.now();
1799
+ k(), a = setInterval(() => {
1800
+ T.textContent = te(Math.floor((Date.now() - $) / 1e3));
1801
+ }, 1e3), T.textContent = "0s";
1715
1802
  }
1716
- p === "missed" && E("Nobody was free. Send a message instead and the team will pick it up."), p === "ended" && E("Call ended."), p === "failed" && E("The call dropped.");
1803
+ l === "missed" && y("Nobody was free. Send a message instead and the team will pick it up."), l === "ended" && y("Call ended."), l === "failed" && y("The call dropped.");
1717
1804
  });
1718
- l.addEventListener("click", () => {
1719
- const p = b.setMuted(!b.isMuted());
1720
- l.textContent = p ? "Unmute" : "Mute", Q.textContent = p ? "You're muted" : "You're on a call with the team";
1721
- }), a.addEventListener("click", () => {
1722
- x(), $(), t.endCall(), z.remove(), e.refreshThread(e.openReportId());
1805
+ n.addEventListener("click", () => {
1806
+ const l = g.setMuted(!g.isMuted());
1807
+ n.textContent = l ? "Unmute" : "Mute", x.textContent = l ? "You're muted" : "You're on a call with the team";
1808
+ }), o.addEventListener("click", () => {
1809
+ m(), k(), t.endCall(), w.remove(), e.refreshThread(e.openReportId());
1723
1810
  });
1724
1811
  }
1725
- e.offerCall = s, e.callOffered = () => v, e.showLiveCall = h;
1812
+ e.offerCall = h, e.callOffered = () => b, e.showLiveCall = s;
1726
1813
  }
1727
- function rt(e) {
1728
- var x;
1814
+ function ut(e) {
1815
+ var m;
1729
1816
  const {
1730
1817
  client: t,
1731
- say: n,
1732
- compose: y,
1818
+ say: r,
1819
+ compose: d,
1733
1820
  sendBtn: u,
1734
- historyBtn: T,
1735
- callBtn: v,
1736
- whoami: s
1821
+ historyBtn: S,
1822
+ callBtn: b,
1823
+ whoami: h
1737
1824
  } = e;
1738
- let i = { mode: t.lastLoginMode || "off", signedIn: null }, h = "idle", g = ((x = t.config.user) == null ? void 0 : x.email) || "", f = "", b = !1, z = "";
1739
- const Q = () => i.mode === "required" && !i.signedIn;
1740
- function c() {
1741
- const p = Q();
1742
- y.hidden = p, u.hidden = p, T && (T.hidden = p), p ? v.hidden = !0 : e.callOffered() && (v.hidden = !1);
1743
- }
1744
- function d() {
1745
- var w;
1746
- if (i.mode === "off") {
1747
- s.hidden = !0, s.innerHTML = "";
1825
+ let f = { mode: t.lastLoginMode || "off", signedIn: null }, s = "idle", c = ((m = t.config.user) == null ? void 0 : m.email) || "", L = "", g = !1, w = "";
1826
+ const x = () => f.mode === "required" && !f.signedIn;
1827
+ function T() {
1828
+ const l = x();
1829
+ d.hidden = l, u.hidden = l, S && (S.hidden = l), l ? b.hidden = !0 : e.callOffered() && !e.mustRate() && (b.hidden = !1);
1830
+ }
1831
+ function i() {
1832
+ var $;
1833
+ if (f.mode === "off") {
1834
+ h.hidden = !0, h.innerHTML = "";
1748
1835
  return;
1749
1836
  }
1750
- s.hidden = !1, s.classList.toggle("asking", h !== "idle");
1751
- const p = z ? `<div class="after err">${m(z)}</div>` : "";
1752
- if (h === "idle") {
1753
- if (i.signedIn) {
1754
- s.innerHTML = `<span class="who">Signed in as <strong>${m(i.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
1837
+ h.hidden = !1, h.classList.toggle("asking", s !== "idle");
1838
+ const l = w ? `<div class="after err">${v(w)}</div>` : "";
1839
+ if (s === "idle") {
1840
+ if (f.signedIn) {
1841
+ h.innerHTML = `<span class="who">Signed in as <strong>${v(f.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
1755
1842
  return;
1756
1843
  }
1757
- const S = (w = t.config.user) == null ? void 0 : w.email;
1758
- s.innerHTML = `<span class="who">${i.mode === "required" ? "Sign in to report a bug here." : S ? `Reporting as <strong>${m(S)}</strong>.` : "Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;
1844
+ const q = ($ = t.config.user) == null ? void 0 : $.email;
1845
+ h.innerHTML = `<span class="who">${f.mode === "required" ? "Sign in to report a bug here." : q ? `Reporting as <strong>${v(q)}</strong>.` : "Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;
1759
1846
  return;
1760
1847
  }
1761
- if (h === "email") {
1762
- s.innerHTML = `
1848
+ if (s === "email") {
1849
+ h.innerHTML = `
1763
1850
  <p class="why">Sign in with any email address — we'll send you a code.
1764
- It's how you hear back about this report${i.mode === "required" ? ", and this project asks for it" : ""}.</p>
1851
+ It's how you hear back about this report${f.mode === "required" ? ", and this project asks for it" : ""}.</p>
1765
1852
  <div class="row">
1766
- <input type="email" data-fld="email" value="${m(g)}"
1853
+ <input type="email" data-fld="email" value="${v(c)}"
1767
1854
  placeholder="you@example.com" autocomplete="email" spellcheck="false"
1768
- aria-label="Your email address" ${b ? "disabled" : ""} />
1769
- <button type="button" class="primary" data-act="code" ${b ? "disabled" : ""}>
1770
- ${b ? "Sending…" : "Send code"}
1855
+ aria-label="Your email address" ${g ? "disabled" : ""} />
1856
+ <button type="button" class="primary" data-act="code" ${g ? "disabled" : ""}>
1857
+ ${g ? "Sending…" : "Send code"}
1771
1858
  </button>
1772
1859
  </div>
1773
- ${p}
1774
- ${i.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
1860
+ ${l}
1861
+ ${f.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
1775
1862
  return;
1776
1863
  }
1777
- s.innerHTML = `
1778
- <p class="why">We sent a code to <strong>${m(g)}</strong>. It expires in ten minutes.</p>
1864
+ h.innerHTML = `
1865
+ <p class="why">We sent a code to <strong>${v(c)}</strong>. It expires in ten minutes.</p>
1779
1866
  <div class="row">
1780
- <input type="text" class="code" data-fld="code" value="${m(f)}"
1867
+ <input type="text" class="code" data-fld="code" value="${v(L)}"
1781
1868
  placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
1782
- maxlength="8" aria-label="The code we emailed you" ${b ? "disabled" : ""} />
1783
- <button type="button" class="primary" data-act="confirm" ${b ? "disabled" : ""}>
1784
- ${b ? "Checking…" : "Sign in"}
1869
+ maxlength="8" aria-label="The code we emailed you" ${g ? "disabled" : ""} />
1870
+ <button type="button" class="primary" data-act="confirm" ${g ? "disabled" : ""}>
1871
+ ${g ? "Checking…" : "Sign in"}
1785
1872
  </button>
1786
1873
  </div>
1787
- ${p}
1874
+ ${l}
1788
1875
  <div class="after">
1789
- <button type="button" class="link" data-act="resend" ${b ? "disabled" : ""}>Send it again</button>
1790
- <button type="button" class="link" data-act="signin-back" ${b ? "disabled" : ""}>Use another address</button>
1876
+ <button type="button" class="link" data-act="resend" ${g ? "disabled" : ""}>Send it again</button>
1877
+ <button type="button" class="link" data-act="signin-back" ${g ? "disabled" : ""}>Use another address</button>
1791
1878
  </div>`;
1792
1879
  }
1793
- function l({ focus: p = !1 } = {}) {
1794
- var S;
1795
- if (d(), c(), !p || b) return;
1796
- const w = s.querySelector("[data-fld]");
1797
- w && (w.focus(), (S = w.setSelectionRange) == null || S.call(w, w.value.length, w.value.length));
1798
- }
1799
- s.addEventListener("input", (p) => {
1800
- const w = p.target.closest("[data-fld]");
1801
- w && (w.dataset.fld === "email" ? g = w.value : f = w.value);
1802
- }), s.addEventListener("keydown", (p) => {
1803
- p.key !== "Enter" || !p.target.closest("[data-fld]") || (p.preventDefault(), h === "email" ? a() : r());
1880
+ function n({ focus: l = !1 } = {}) {
1881
+ var q;
1882
+ if (i(), T(), !l || g) return;
1883
+ const $ = h.querySelector("[data-fld]");
1884
+ $ && ($.focus(), (q = $.setSelectionRange) == null || q.call($, $.value.length, $.value.length));
1885
+ }
1886
+ h.addEventListener("input", (l) => {
1887
+ const $ = l.target.closest("[data-fld]");
1888
+ $ && ($.dataset.fld === "email" ? c = $.value : L = $.value);
1889
+ }), h.addEventListener("keydown", (l) => {
1890
+ l.key !== "Enter" || !l.target.closest("[data-fld]") || (l.preventDefault(), s === "email" ? o() : a());
1804
1891
  });
1805
- async function a({ resent: p = !1 } = {}) {
1806
- const w = g.trim();
1807
- if (!w) {
1808
- z = "Enter the address to send the code to.", l({ focus: !0 });
1892
+ async function o({ resent: l = !1 } = {}) {
1893
+ const $ = c.trim();
1894
+ if (!$) {
1895
+ w = "Enter the address to send the code to.", n({ focus: !0 });
1809
1896
  return;
1810
1897
  }
1811
- b = !0, z = "", l();
1898
+ g = !0, w = "", n();
1812
1899
  try {
1813
- await t.signIn(w), g = w, p || (f = ""), h = "code";
1814
- } catch (S) {
1815
- z = S.message;
1900
+ await t.signIn($), c = $, l || (L = ""), s = "code";
1901
+ } catch (q) {
1902
+ w = q.message;
1816
1903
  } finally {
1817
- b = !1, l({ focus: !0 });
1904
+ g = !1, n({ focus: !0 });
1818
1905
  }
1819
1906
  }
1820
- async function r() {
1821
- const p = f.trim();
1822
- if (!p) {
1823
- z = "Enter the code we emailed you.", l({ focus: !0 });
1907
+ async function a() {
1908
+ const l = L.trim();
1909
+ if (!l) {
1910
+ w = "Enter the code we emailed you.", n({ focus: !0 });
1824
1911
  return;
1825
1912
  }
1826
- b = !0, z = "", l();
1913
+ g = !0, w = "", n();
1827
1914
  try {
1828
- const w = await t.confirmSignIn(g.trim(), p);
1829
- i.signedIn = w, h = "idle", f = "", n(""), e.offerCall();
1830
- } catch (w) {
1831
- z = w.message;
1915
+ const $ = await t.confirmSignIn(c.trim(), l);
1916
+ f.signedIn = $, s = "idle", L = "", r(""), e.offerCall();
1917
+ } catch ($) {
1918
+ w = $.message;
1832
1919
  } finally {
1833
- b = !1, l({ focus: h !== "idle" });
1920
+ g = !1, n({ focus: s !== "idle" });
1834
1921
  }
1835
1922
  }
1836
- s.addEventListener("click", async (p) => {
1837
- const w = p.target.closest("button[data-act]");
1838
- if (!w) return;
1839
- const S = w.dataset.act;
1840
- if (S === "signin") {
1841
- h = "email", z = "", l({ focus: !0 });
1923
+ h.addEventListener("click", async (l) => {
1924
+ const $ = l.target.closest("button[data-act]");
1925
+ if (!$) return;
1926
+ const q = $.dataset.act;
1927
+ if (q === "signin") {
1928
+ s = "email", w = "", n({ focus: !0 });
1842
1929
  return;
1843
1930
  }
1844
- if (S === "skip") {
1845
- h = "idle", z = "", l();
1931
+ if (q === "skip") {
1932
+ s = "idle", w = "", n();
1846
1933
  return;
1847
1934
  }
1848
- if (S === "signin-back") {
1849
- h = "email", z = "", f = "", l({ focus: !0 });
1935
+ if (q === "signin-back") {
1936
+ s = "email", w = "", L = "", n({ focus: !0 });
1850
1937
  return;
1851
1938
  }
1852
- if (S === "code") {
1853
- a();
1939
+ if (q === "code") {
1940
+ o();
1854
1941
  return;
1855
1942
  }
1856
- if (S === "resend") {
1857
- a({ resent: !0 });
1943
+ if (q === "resend") {
1944
+ o({ resent: !0 });
1858
1945
  return;
1859
1946
  }
1860
- if (S === "confirm") {
1861
- r();
1947
+ if (q === "confirm") {
1948
+ a();
1862
1949
  return;
1863
1950
  }
1864
- if (S === "signout") {
1865
- b = !0, l();
1951
+ if (q === "signout") {
1952
+ g = !0, n();
1866
1953
  try {
1867
1954
  await t.signOut();
1868
1955
  } finally {
1869
- i.signedIn = null, b = !1, h = i.mode === "required" ? "email" : "idle", l({ focus: h !== "idle" });
1956
+ f.signedIn = null, g = !1, s = f.mode === "required" ? "email" : "idle", n({ focus: s !== "idle" });
1870
1957
  }
1871
1958
  }
1872
1959
  });
1873
- async function $({ announce: p = !1 } = {}) {
1874
- const w = await t.loginState();
1875
- i = { mode: w.mode, signedIn: w.signedIn }, t.lastLoginMode = w.mode, Q() && h === "idle" && (h = "email"), i.signedIn && (h = "idle"), p && w.signedOutReason && n(w.signedOutReason, "info"), l();
1960
+ async function k({ announce: l = !1 } = {}) {
1961
+ const $ = await t.loginState();
1962
+ f = { mode: $.mode, signedIn: $.signedIn }, t.lastLoginMode = $.mode, x() && s === "idle" && (s = "email"), f.signedIn && (s = "idle"), l && $.signedOutReason && r($.signedOutReason, "info"), n();
1876
1963
  }
1877
- $({ announce: !0 }).catch(() => {
1964
+ k({ announce: !0 }).catch(() => {
1878
1965
  });
1879
- function E() {
1880
- i.mode !== "off" && $().catch(() => {
1966
+ function y() {
1967
+ f.mode !== "off" && k().catch(() => {
1881
1968
  });
1882
1969
  }
1883
- e.mustSignIn = Q, e.recheckSignIn = E;
1970
+ e.mustSignIn = x, e.recheckSignIn = y;
1884
1971
  }
1885
1972
  function he(e) {
1886
1973
  const t = e || [];
1887
1974
  if (!t.length) return "";
1888
- let n = null, y = null;
1975
+ let r = null, d = null;
1889
1976
  return t.map((u) => {
1890
- var g, f, b, z;
1891
- const T = Z(u.at), v = T && T !== n ? `<div class="day-sep" role="separator">${m(Ke(u.at))}</div>` : "";
1892
- if (v && (n = T, y = null), !u.from)
1893
- return y = null, v + st(u);
1894
- const s = {
1977
+ var c, L, g, w;
1978
+ const S = Z(u.at), b = S && S !== r ? `<div class="day-sep" role="separator">${v(Xe(u.at))}</div>` : "";
1979
+ if (b && (r = S, d = null), !u.from)
1980
+ return d = null, b + bt(u);
1981
+ const h = {
1895
1982
  from: u.from,
1896
- author: (g = u.reply) == null ? void 0 : g.author,
1897
- automated: (f = u.reply) == null ? void 0 : f.automated,
1898
- body: (b = u.reply) == null ? void 0 : b.body,
1983
+ author: (c = u.reply) == null ? void 0 : c.author,
1984
+ automated: (L = u.reply) == null ? void 0 : L.automated,
1985
+ body: (g = u.reply) == null ? void 0 : g.body,
1899
1986
  at: u.at,
1900
- attachments: (z = u.reply) == null ? void 0 : z.attachments
1901
- }, i = it(s), h = y && y.who === i && Math.abs(new Date(u.at).getTime() - new Date(y.at).getTime()) < 5 * 6e4;
1902
- return y = { who: i, at: u.at }, v + ye(s, h ? "cont" : "");
1987
+ attachments: (w = u.reply) == null ? void 0 : w.attachments
1988
+ }, f = ht(h), s = d && d.who === f && Math.abs(new Date(u.at).getTime() - new Date(d.at).getTime()) < 5 * 6e4;
1989
+ return d = { who: f, at: u.at }, b + we(h, s ? "cont" : "");
1903
1990
  }).join("");
1904
1991
  }
1905
- function it(e) {
1992
+ function ht(e) {
1906
1993
  return e.from === "reporter" ? "me" : e.automated ? "assistant" : `team:${e.author || ""}`;
1907
1994
  }
1908
- function st(e) {
1909
- const t = me(e.at);
1995
+ function bt(e) {
1996
+ const t = ve(e.at);
1910
1997
  return `
1911
- <div class="sys k-${m(e.kind)}">
1912
- <span class="dot" aria-hidden="true"></span>${m(e.summary || "")}${t ? `
1913
- <span class="t">· ${m(t)}</span>` : ""}
1998
+ <div class="sys k-${v(e.kind)}">
1999
+ <span class="dot" aria-hidden="true"></span>${v(e.summary || "")}${t ? `
2000
+ <span class="t">· ${v(t)}</span>` : ""}
1914
2001
  </div>`;
1915
2002
  }
1916
- function ye(e, t = "") {
1917
- const n = e.from === "reporter", y = e.body || "", u = e.attachments || [], T = !n && !!e.automated, v = y ? `<span class="msg-text">${m(y)}</span>` : "", s = u.length ? `<div class="att">${u.map(ct).join("")}</div>` : "";
1918
- let i = "", h = "";
1919
- if (T)
1920
- i = '<span class="msg-who auto">Assistant <span class="tag">AI</span></span>', h = `<span class="av bot" aria-hidden="true">${X}</span>`;
1921
- else if (!n) {
1922
- const f = e.author || "Support team";
1923
- i = `<span class="msg-who">${m(f)}</span>`, h = `<span class="av" aria-hidden="true">${m(We(f))}</span>`;
1924
- }
1925
- t.includes("cont") && (i = "");
1926
- const g = T && /it goes to the same person/i.test(y) ? `<div class="quick" role="group" aria-label="Answer">
1927
- <button type="button" data-quick="Yes, this is the problem">${W}That's right</button>
2003
+ function we(e, t = "") {
2004
+ const r = e.from === "reporter", d = e.body || "", u = e.attachments || [], S = !r && !!e.automated, b = d ? `<span class="msg-text">${v(d)}</span>` : "", h = u.length ? `<div class="att">${u.map(gt).join("")}</div>` : "";
2005
+ let f = "", s = "";
2006
+ if (S)
2007
+ f = '<span class="msg-who auto">Assistant <span class="tag">AI</span></span>', s = '<span class="av bot orb" aria-hidden="true"></span>';
2008
+ else if (!r) {
2009
+ const L = e.author || "Support team";
2010
+ f = `<span class="msg-who">${v(L)}</span>`, s = `<span class="av" aria-hidden="true">${v(Je(L))}</span>`;
2011
+ }
2012
+ t.includes("cont") && (f = "");
2013
+ const c = S && /it goes to the same person/i.test(d) ? `<div class="quick" role="group" aria-label="Answer">
2014
+ <button type="button" data-quick="Yes, this is the problem">${P}That's right</button>
1928
2015
  <button type="button" data-quick="No, that is not the problem">That's not it</button>
1929
- </div>` : T && Ee.test(y) ? `<div class="quick" role="group" aria-label="Did this answer your question?">
1930
- <button type="button" data-quick="Yes, that answers it">${W}Yes, that answers it</button>
2016
+ </div>` : S && Ie.test(d) ? `<div class="quick" role="group" aria-label="Did this answer your question?">
2017
+ <button type="button" data-quick="Yes, that answers it">${P}Yes, that answers it</button>
1931
2018
  <button type="button" data-quick="No, I still need help">No, I still need help</button>
1932
2019
  </div>` : "";
1933
2020
  return `
1934
- <div class="msg-row ${n ? "mine" : "theirs"} ${T ? "auto" : ""} ${t}">
1935
- ${h}
1936
- ${i}
1937
- <div class="bubble ${y ? "" : "silent"}">${v}${s}</div>
1938
- ${g}
1939
- <span class="msg-when">${m(me(e.at) || oe(e.at))}</span>
2021
+ <div class="msg-row ${r ? "mine" : "theirs"} ${S ? "auto" : ""} ${t}">
2022
+ ${s}
2023
+ ${f}
2024
+ <div class="bubble ${d ? "" : "silent"}">${b}${h}</div>
2025
+ ${c}
2026
+ <span class="msg-when">${v(ve(e.at) || J(e.at))}</span>
1940
2027
  </div>`;
1941
2028
  }
1942
- function lt() {
2029
+ function ft() {
1943
2030
  return `
1944
2031
  <div class="typing-row">
1945
- <span class="av bot" aria-hidden="true">${X}</span>
2032
+ <span class="av bot orb" aria-hidden="true"></span>
1946
2033
  <span class="msg-who auto">Assistant <span class="tag">AI</span></span>
1947
2034
  <div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
1948
2035
  </div>`;
1949
2036
  }
1950
- function ct(e) {
1951
- const t = m(e.name || "attachment");
2037
+ function gt(e) {
2038
+ const t = v(e.name || "attachment");
1952
2039
  if (!e.url) return `<span class="file"><span class="nm">${t}</span></span>`;
1953
- const n = m(e.url);
1954
- return e.type === "SCREENSHOT" ? `<a href="${n}" target="_blank" rel="noopener noreferrer"><img src="${n}" alt="${t}" loading="lazy"></a>` : e.type === "AUDIO" ? `<audio controls preload="metadata" src="${n}"></audio>` : e.type === "VIDEO" ? `<video controls preload="metadata" src="${n}"></video>` : `
1955
- <a class="file" href="${n}" target="_blank" rel="noopener noreferrer" download>
2040
+ const r = v(e.url);
2041
+ return e.type === "SCREENSHOT" ? `<a href="${r}" target="_blank" rel="noopener noreferrer"><img src="${r}" alt="${t}" loading="lazy"></a>` : e.type === "AUDIO" ? `<audio controls preload="metadata" src="${r}"></audio>` : e.type === "VIDEO" ? `<video controls preload="metadata" src="${r}"></video>` : `
2042
+ <a class="file" href="${r}" target="_blank" rel="noopener noreferrer" download>
1956
2043
  <span class="nm">${t}</span>
1957
- ${e.size ? `<span class="sz">${m(P(e.size))}</span>` : ""}
2044
+ ${e.size ? `<span class="sz">${v(F(e.size))}</span>` : ""}
1958
2045
  </a>`;
1959
2046
  }
1960
- function dt(e, t, n, y) {
1961
- var E;
1962
- const { client: u, cfg: T } = e, v = document.createElement("div");
1963
- v.className = "composer", v.innerHTML = `
2047
+ function mt(e, t, r, d) {
2048
+ var y;
2049
+ const { client: u, cfg: S } = e, b = document.createElement("div");
2050
+ b.className = "composer", b.innerHTML = `
1964
2051
  <div class="staged" hidden></div>
1965
2052
  <div class="row">
1966
2053
  <div class="tools">
1967
- ${T.attachments === !1 ? "" : `
2054
+ ${S.attachments === !1 ? "" : `
1968
2055
  <button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${fe}</button>
1969
2056
  <button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${pe}</button>`}
1970
- <button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${ne}</button>
2057
+ <button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${re}</button>
1971
2058
  </div>
1972
2059
  <textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
1973
2060
  <button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${ge}</button>
1974
2061
  </div>
1975
2062
  <div class="note" hidden></div>
1976
- <input type="file" hidden multiple accept="${Me.join(",")}">`, t.appendChild(v);
1977
- const s = v.querySelector(".staged"), i = v.querySelector("textarea"), h = v.querySelector('[data-act="send"]'), g = v.querySelector('[data-act="voice"]'), f = v.querySelector('[data-act="livecall"]'), b = v.querySelector("input[type=file]"), z = v.querySelector(".note"), Q = [];
1978
- let c = null, d = !1;
1979
- function l(x, p = "") {
1980
- z.hidden = !x, z.className = `note ${p}`, z.textContent = x || "";
1981
- }
1982
- function a() {
1983
- const x = Q.filter((p) => p.storageKey);
1984
- h.disabled = d || !i.value.trim() && !x.length, s.hidden = !Q.length, s.innerHTML = Q.map((p, w) => `
1985
- <span class="chip ${p.storageKey ? "" : "uploading"}">
1986
- <span class="nm">${m(p.name)}</span>
1987
- <span class="sz">${p.storageKey ? P(p.size) : "sending…"}</span>
1988
- <button type="button" data-drop="${w}" aria-label="Remove ${m(p.name)}">${de}</button>
2063
+ <input type="file" hidden multiple accept="${De.join(",")}">`, t.appendChild(b);
2064
+ const h = b.querySelector(".staged"), f = b.querySelector("textarea"), s = b.querySelector('[data-act="send"]'), c = b.querySelector('[data-act="voice"]'), L = b.querySelector('[data-act="livecall"]'), g = b.querySelector("input[type=file]"), w = b.querySelector(".note"), x = [];
2065
+ let T = null, i = !1;
2066
+ function n(m, l = "") {
2067
+ w.hidden = !m, w.className = `note ${l}`, w.textContent = m || "";
2068
+ }
2069
+ function o() {
2070
+ const m = x.filter((l) => l.storageKey);
2071
+ s.disabled = i || !f.value.trim() && !m.length, h.hidden = !x.length, h.innerHTML = x.map((l, $) => `
2072
+ <span class="chip ${l.storageKey ? "" : "uploading"}">
2073
+ <span class="nm">${v(l.name)}</span>
2074
+ <span class="sz">${l.storageKey ? F(l.size) : "sending…"}</span>
2075
+ <button type="button" data-drop="${$}" aria-label="Remove ${v(l.name)}">${ce}</button>
1989
2076
  </span>`).join("");
1990
- for (const p of s.querySelectorAll("[data-drop]"))
1991
- p.addEventListener("click", () => {
1992
- Q.splice(Number(p.dataset.drop), 1), a();
2077
+ for (const l of h.querySelectorAll("[data-drop]"))
2078
+ l.addEventListener("click", () => {
2079
+ x.splice(Number(l.dataset.drop), 1), o();
1993
2080
  });
1994
2081
  }
1995
- async function r(x, p, w) {
1996
- const S = { name: w, size: x.size, storageKey: null };
1997
- Q.push(S), a();
2082
+ async function a(m, l, $) {
2083
+ const q = { name: $, size: m.size, storageKey: null };
2084
+ x.push(q), o();
1998
2085
  try {
1999
- const { storageKey: A, mime: D } = await u.uploadAttachment(x, p);
2000
- S.storageKey = A, S.mime = D;
2001
- } catch (A) {
2002
- Q.splice(Q.indexOf(S), 1), l(A.message || "That file could not be sent.", "err");
2086
+ const { storageKey: H, mime: O } = await u.uploadAttachment(m, l);
2087
+ q.storageKey = H, q.mime = O;
2088
+ } catch (H) {
2089
+ x.splice(x.indexOf(q), 1), n(H.message || "That file could not be sent.", "err");
2003
2090
  }
2004
- a();
2005
- }
2006
- i.addEventListener("input", () => {
2007
- i.style.height = "auto", i.style.height = `${Math.min(i.scrollHeight, 120)}px`, a();
2008
- }), i.addEventListener("keydown", (x) => {
2009
- x.key === "Enter" && !x.shiftKey && !x.isComposing && (x.preventDefault(), $());
2010
- }), (E = v.querySelector('[data-act="attach"]')) == null || E.addEventListener("click", () => b.click()), b.addEventListener("change", () => {
2011
- l("");
2012
- for (const x of b.files) {
2013
- if (x.size > u.config.maxAttachmentBytes) {
2014
- l(`${x.name} is larger than ${P(u.config.maxAttachmentBytes)}.`, "err");
2091
+ o();
2092
+ }
2093
+ f.addEventListener("input", () => {
2094
+ f.style.height = "auto", f.style.height = `${Math.min(f.scrollHeight, 120)}px`, o();
2095
+ }), f.addEventListener("keydown", (m) => {
2096
+ m.key === "Enter" && !m.shiftKey && !m.isComposing && (m.preventDefault(), k());
2097
+ }), (y = b.querySelector('[data-act="attach"]')) == null || y.addEventListener("click", () => g.click()), g.addEventListener("change", () => {
2098
+ n("");
2099
+ for (const m of g.files) {
2100
+ if (m.size > u.config.maxAttachmentBytes) {
2101
+ n(`${m.name} is larger than ${F(u.config.maxAttachmentBytes)}.`, "err");
2015
2102
  continue;
2016
2103
  }
2017
- r(x, x.type, x.name);
2104
+ a(m, m.type, m.name);
2018
2105
  }
2019
- b.value = "";
2020
- }), g && !qe() && (g.disabled = !0, g.title = "This browser cannot record audio"), g == null || g.addEventListener("click", async () => {
2021
- if (c) {
2022
- const x = c;
2023
- c = null, g.classList.remove("recording"), g.innerHTML = pe, l("");
2024
- const { blob: p, mime: w } = await x.stop();
2025
- p.size && r(p, w, "Voice note");
2106
+ g.value = "";
2107
+ }), c && !Ve() && (c.disabled = !0, c.title = "This browser cannot record audio"), c == null || c.addEventListener("click", async () => {
2108
+ if (T) {
2109
+ const m = T;
2110
+ T = null, c.classList.remove("recording"), c.innerHTML = pe, n("");
2111
+ const { blob: l, mime: $ } = await m.stop();
2112
+ l.size && a(l, $, "Voice note");
2026
2113
  return;
2027
2114
  }
2028
2115
  try {
2029
- l(""), c = await Ce({
2116
+ n(""), T = await je({
2030
2117
  maxMs: u.config.maxRecordingMs,
2031
- onTick: (x) => l(`Recording — ${te(x)}. Tap the mic to stop.`),
2032
- onAutoStop: () => g.click()
2033
- }), g.classList.add("recording"), g.innerHTML = Re;
2118
+ onTick: (m) => n(`Recording — ${te(m)}. Tap the mic to stop.`),
2119
+ onAutoStop: () => c.click()
2120
+ }), c.classList.add("recording"), c.innerHTML = Ye;
2034
2121
  } catch {
2035
- c = null, l("The microphone is not available — check the browser permission.", "err");
2122
+ T = null, n("The microphone is not available — check the browser permission.", "err");
2036
2123
  }
2037
- }), u.canCallTeam(y).then((x) => {
2038
- x && (f.hidden = !1, e.preloadCall());
2124
+ }), u.canCallTeam(d).then((m) => {
2125
+ m && (L.hidden = !1, e.preloadCall());
2039
2126
  }).catch(() => {
2040
- }), f.addEventListener("click", async () => {
2041
- f.disabled = !0, l("");
2127
+ }), L.addEventListener("click", async () => {
2128
+ L.disabled = !0, n("");
2042
2129
  try {
2043
- const x = await u.startLiveCall(y);
2044
- e.showLiveCall(t, n, x);
2045
- } catch (x) {
2046
- l(x.message.replace("[BugCatch] ", ""), "err");
2130
+ const m = await u.startLiveCall(d);
2131
+ e.showLiveCall(t, r, m);
2132
+ } catch (m) {
2133
+ n(m.message.replace("[BugCatch] ", ""), "err");
2047
2134
  } finally {
2048
- f.disabled = !1;
2135
+ L.disabled = !1;
2049
2136
  }
2050
- }), h.addEventListener("click", $), n.addEventListener("click", (x) => {
2051
- var w, S;
2052
- const p = (S = (w = x.target).closest) == null ? void 0 : S.call(w, "[data-quick]");
2053
- !p || d || (i.value = p.dataset.quick, $());
2137
+ }), s.addEventListener("click", k), r.addEventListener("click", (m) => {
2138
+ var $, q;
2139
+ const l = (q = ($ = m.target).closest) == null ? void 0 : q.call($, "[data-quick]");
2140
+ !l || i || (f.value = l.dataset.quick, k());
2054
2141
  });
2055
- async function $() {
2056
- var w;
2057
- const x = i.value.trim(), p = Q.filter((S) => S.storageKey);
2058
- if (!(d || !x && !p.length)) {
2059
- d = !0, a(), l(""), n.insertAdjacentHTML("beforeend", ye({
2142
+ async function k() {
2143
+ var $;
2144
+ const m = f.value.trim(), l = x.filter((q) => q.storageKey);
2145
+ if (!(i || !m && !l.length)) {
2146
+ i = !0, o(), n(""), r.insertAdjacentHTML("beforeend", we({
2060
2147
  from: "reporter",
2061
- body: x,
2148
+ body: m,
2062
2149
  at: (/* @__PURE__ */ new Date()).toISOString(),
2063
- attachments: p.map((S) => ({ type: "FILE", name: S.name, size: S.size }))
2064
- }, "pending")), _(n, { smooth: !0 });
2150
+ attachments: l.map((q) => ({ type: "FILE", name: q.name, size: q.size }))
2151
+ }, "pending")), _(r, { smooth: !0 });
2065
2152
  try {
2066
- await u.replyToReport(y, {
2067
- body: x,
2068
- attachments: p.map((S) => ({
2069
- storageKey: S.storageKey,
2070
- mime: S.mime,
2071
- name: S.name,
2072
- size: S.size
2153
+ await u.replyToReport(d, {
2154
+ body: m,
2155
+ attachments: l.map((q) => ({
2156
+ storageKey: q.storageKey,
2157
+ mime: q.mime,
2158
+ name: q.name,
2159
+ size: q.size
2073
2160
  }))
2074
- }), i.value = "", i.style.height = "auto", Q.length = 0, await e.refreshThread(y);
2075
- } catch (S) {
2076
- (w = n.querySelector(".msg-row.pending")) == null || w.classList.replace("pending", "failed"), l(S.message || "That could not be sent — try again.", "err");
2161
+ }), f.value = "", f.style.height = "auto", x.length = 0, await e.refreshThread(d);
2162
+ } catch (q) {
2163
+ ($ = r.querySelector(".msg-row.pending")) == null || $.classList.replace("pending", "failed"), n(q.message || "That could not be sent — try again.", "err");
2077
2164
  } finally {
2078
- d = !1, a();
2165
+ i = !1, o();
2079
2166
  }
2080
2167
  }
2081
2168
  }
2082
- a();
2169
+ o();
2170
+ }
2171
+ function ke(e) {
2172
+ return JSON.stringify(e ? [e.score, e.current, e.comment || null] : null);
2173
+ }
2174
+ function de(e, {
2175
+ client: t,
2176
+ report: r,
2177
+ rating: d,
2178
+ justRated: u = !1,
2179
+ question: S = null,
2180
+ onRated: b = null,
2181
+ onError: h = null
2182
+ }) {
2183
+ var i;
2184
+ e.dataset.key = ke(d);
2185
+ const f = d != null && d.current ? d.score : 0, s = d ? d.current ? u ? "Thanks — the team will see that." : `You rated this ${d.score} out of 5.` : `You rated an earlier fix ${d.score} out of 5. How did this one go?` : S || "How did we do?", c = u && (d == null ? void 0 : d.current) && !d.comment;
2186
+ e.innerHTML = `
2187
+ <p class="fr-q">${v(s)}</p>
2188
+ <div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1, 2, 3, 4, 5].map((n) => `
2189
+ <button type="button" data-score="${n}" aria-pressed="${n === f}" aria-label="${n} out of 5${n === 1 ? ", poor" : n === 5 ? ", great" : ""}" class="${n <= f ? "on" : ""}">${me}</button>`).join("")}
2190
+ </div>
2191
+ ${d != null && d.current && d.comment ? `<p class="fr-said">“${v(d.comment)}”</p>` : ""}
2192
+ ${c ? `
2193
+ <div class="fr-note">
2194
+ <textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${d.score <= 2 ? "What went wrong? (optional)" : "Anything to add? (optional)"}"></textarea>
2195
+ <button type="button" data-act="rating-note">Add note</button>
2196
+ </div>` : ""}
2197
+ ${d ? "" : '<p class="fr-hint">1 is poor, 5 is great.</p>'}
2198
+ <p class="feedback-status" role="status"></p>`;
2199
+ const L = [...e.querySelectorAll("[data-score]")], g = (n) => L.forEach((o) => o.classList.toggle("on", Number(o.dataset.score) <= n)), w = (n) => e.querySelectorAll("button, textarea").forEach((o) => {
2200
+ o.disabled = n;
2201
+ }), x = e.querySelector(".feedback-status");
2202
+ async function T(n, o) {
2203
+ var a;
2204
+ w(!0), x.textContent = "";
2205
+ try {
2206
+ const k = await t.rate(r.id, { score: n, comment: o });
2207
+ de(e, {
2208
+ client: t,
2209
+ report: r,
2210
+ rating: k,
2211
+ justRated: !0,
2212
+ question: S,
2213
+ onRated: b,
2214
+ onError: h
2215
+ }), (a = e.querySelector(".fr-note textarea")) == null || a.focus(), b == null || b(k);
2216
+ } catch (k) {
2217
+ x.textContent = k.message, w(!1), g(f), h == null || h(k);
2218
+ }
2219
+ }
2220
+ for (const n of L) {
2221
+ const o = Number(n.dataset.score);
2222
+ n.addEventListener("mouseenter", () => g(o)), n.addEventListener("focus", () => g(o)), n.addEventListener("blur", () => g(f)), n.addEventListener("click", () => T(o));
2223
+ }
2224
+ e.querySelector(".stars").addEventListener("mouseleave", () => g(f)), (i = e.querySelector('[data-act="rating-note"]')) == null || i.addEventListener("click", () => {
2225
+ var o;
2226
+ const n = e.querySelector(".fr-note textarea").value.trim();
2227
+ if (!n) {
2228
+ (o = e.querySelector(".fr-note")) == null || o.remove();
2229
+ return;
2230
+ }
2231
+ T(d.score, n);
2232
+ });
2083
2233
  }
2084
- const le = /* @__PURE__ */ new WeakMap();
2085
- function pt(e) {
2086
- var Q;
2234
+ const se = /* @__PURE__ */ new WeakMap();
2235
+ function vt(e) {
2236
+ return e.rating ? ` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${me}${Number(e.rating)}</span>` : e.ratingAsked ? ' · <span class="rate-ask">Rate it</span>' : "";
2237
+ }
2238
+ function xt(e) {
2239
+ var T;
2087
2240
  const {
2088
2241
  client: t,
2089
- scrim: n,
2090
- close: y
2242
+ scrim: r,
2243
+ close: d
2091
2244
  } = e;
2092
2245
  let u = null;
2093
- function T(c, { callFailed: d = null } = {}) {
2094
- if (c != null && c.id && !d) {
2095
- i(c.id, { fresh: !0 }).then((l) => {
2096
- l || v(c, { callFailed: d });
2246
+ function S(i, { callFailed: n = null } = {}) {
2247
+ if (i != null && i.id && !n) {
2248
+ f(i.id, { fresh: !0 }).then((o) => {
2249
+ o || b(i, { callFailed: n });
2097
2250
  });
2098
2251
  return;
2099
2252
  }
2100
- v(c, { callFailed: d });
2253
+ b(i, { callFailed: n });
2101
2254
  }
2102
- function v(c, { callFailed: d = null } = {}) {
2103
- var $;
2104
- const l = c != null && c.id ? String(c.id).slice(0, 8) : null, a = ($ = c == null ? void 0 : c.estimate) != null && $.label ? String(c.estimate.label) : null, r = d ? `<p class="eta">${m(d)} Your report is filed, and the team will reply in the chat.</p>` : "";
2105
- n.querySelector(".panel").innerHTML = `
2255
+ function b(i, { callFailed: n = null } = {}) {
2256
+ var y;
2257
+ const o = i != null && i.id ? String(i.id).slice(0, 8) : null, a = (y = i == null ? void 0 : i.estimate) != null && y.label ? String(i.estimate.label) : null, k = n ? `<p class="eta">${v(n)} Your report is filed, and the team will reply in the chat.</p>` : "";
2258
+ r.querySelector(".panel").innerHTML = `
2106
2259
  <div class="done">
2107
- <div class="tick">${W}</div>
2260
+ <div class="tick">${P}</div>
2108
2261
  <h3>Thanks — that's on its way.</h3>
2109
- <p>${l ? `Filed as <code>${m(l)}</code>.` : "The team has what they need to reproduce it."}</p>
2110
- ${r}
2111
- ${a ? `<p class="eta">Reports like this usually take <strong>${m(a)}</strong>. We'll let you know when it moves.</p>` : ""}
2112
- </div>`, setTimeout(y, r ? 6e3 : a ? 4e3 : 2e3);
2113
- }
2114
- async function s() {
2115
- const c = n.querySelector(".panel");
2116
- clearTimeout(h), u = null, c.classList.remove("is-chat"), c.innerHTML = `
2117
- ${ce({ title: "Your reports", sub: "Everything you've reported, and where each one got to." })}
2118
- <div class="history" aria-busy="true">${Ye(3)}</div>`, c.querySelector('[data-act="close"]').addEventListener("click", y);
2119
- let d = [];
2262
+ <p>${o ? `Filed as <code>${v(o)}</code>.` : "The team has what they need to reproduce it."}</p>
2263
+ ${k}
2264
+ ${a ? `<p class="eta">Reports like this usually take <strong>${v(a)}</strong>. We'll let you know when it moves.</p>` : ""}
2265
+ </div>`, setTimeout(d, k ? 6e3 : a ? 4e3 : 2e3);
2266
+ }
2267
+ async function h() {
2268
+ const i = r.querySelector(".panel");
2269
+ clearTimeout(s), u = null, i.classList.remove("is-chat"), i.innerHTML = `
2270
+ ${le({ title: "Your reports", sub: "Where each one has got to.", theme: e.themeLabel() })}
2271
+ <div class="history" aria-busy="true">${_e(3)}</div>`, i.querySelector('[data-act="close"]').addEventListener("click", d);
2272
+ let n = [];
2120
2273
  try {
2121
- ({ reports: d } = await t.myReports());
2274
+ ({ reports: n } = await t.myReports());
2122
2275
  } catch {
2123
- const a = c.querySelector(".history");
2124
- a && (a.innerHTML = ie("Couldn't load your reports just now.", G));
2276
+ const a = i.querySelector(".history");
2277
+ a && (a.innerHTML = oe("Couldn't load your reports just now.", G));
2125
2278
  return;
2126
2279
  }
2127
- const l = c.querySelector(".history");
2128
- if (l) {
2129
- l.removeAttribute("aria-busy"), l.innerHTML = d.length ? d.map((a, r) => `
2130
- <button class="row" type="button" data-report="${m(a.id)}" style="animation-delay:${Math.min(r, 8) * 30}ms">
2131
- <span class="row-ico" aria-hidden="true">${He}</span>
2280
+ const o = i.querySelector(".history");
2281
+ if (o) {
2282
+ o.removeAttribute("aria-busy"), o.innerHTML = n.length ? n.map((a, k) => `
2283
+ <button class="row" type="button" data-report="${v(a.id)}" style="animation-delay:${Math.min(k, 8) * 30}ms">
2284
+ <span class="row-ico" aria-hidden="true">${Oe}</span>
2132
2285
  <span class="who">
2133
- <span class="ttl">${m(a.title)}</span>
2134
- <span class="sub">${m(a.reference)} · ${m(oe(a.createdAt))}</span>
2286
+ <span class="ttl">${v(a.title)}</span>
2287
+ <span class="sub">${v(a.reference)} · ${v(J(a.createdAt))}${vt(a)}</span>
2135
2288
  </span>
2136
- <span class="pill ${m(String(a.status).toLowerCase())}">${m(se(a.status))}</span>
2137
- <span class="chev" aria-hidden="true">${je}</span>
2138
- </button>`).join("") : ie("You haven't reported anything yet.", Oe);
2139
- for (const a of l.querySelectorAll("[data-report]"))
2140
- a.addEventListener("click", () => i(a.dataset.report));
2289
+ <span class="pill ${v(String(a.status).toLowerCase())}">${v(ie(a.status))}</span>
2290
+ <span class="chev" aria-hidden="true">${Fe}</span>
2291
+ </button>`).join("") : oe("You haven't reported anything yet.", Ke);
2292
+ for (const a of o.querySelectorAll("[data-report]"))
2293
+ a.addEventListener("click", () => f(a.dataset.report));
2141
2294
  }
2142
2295
  }
2143
- async function i(c, { fresh: d = !1 } = {}) {
2144
- var x;
2145
- const l = n.querySelector(".panel");
2146
- clearTimeout(h), l.classList.add("is-chat"), l.innerHTML = `
2147
- ${ce({
2296
+ async function f(i, { fresh: n = !1 } = {}) {
2297
+ var l;
2298
+ const o = r.querySelector(".panel");
2299
+ clearTimeout(s), o.classList.add("is-chat"), o.innerHTML = `
2300
+ ${le({
2148
2301
  back: !0,
2149
- title: d ? "Looking into it" : "Your report",
2150
- sub: d ? "Our assistant is on it — it may ask you a question here." : "Everything that has happened, and a way to answer."
2302
+ title: n ? "Looking into it" : "Your report",
2303
+ sub: n ? "It may ask you a question here." : "Updates, and a way to reply.",
2304
+ theme: e.themeLabel()
2151
2305
  })}
2152
- <div class="history chatting" aria-busy="true"><div class="thread">${Pe()}</div></div>`, l.querySelector('[data-act="close"]').addEventListener("click", y), l.querySelector('[data-act="back"]').addEventListener("click", s);
2306
+ <div class="history chatting" aria-busy="true"><div class="thread">${Ge()}</div></div>`, o.querySelector('[data-act="close"]').addEventListener("click", d), o.querySelector('[data-act="back"]').addEventListener("click", h);
2153
2307
  let a = null;
2154
2308
  try {
2155
- a = await t.myReport(c);
2309
+ a = await t.myReport(i);
2156
2310
  } catch {
2157
2311
  a = null;
2158
2312
  }
2159
- const r = l.querySelector(".history");
2160
- if (!r || !l.querySelector('[data-act="back"]')) return !1;
2313
+ const k = o.querySelector(".history");
2314
+ if (!k || !o.querySelector('[data-act="back"]')) return !1;
2161
2315
  if (!a)
2162
- return d ? (l.classList.remove("is-chat"), !1) : (r.removeAttribute("aria-busy"), r.innerHTML = ie("Couldn't load that report just now.", G), !1);
2163
- u = c, t.markReportRead(c);
2164
- const $ = he(a.timeline);
2165
- r.classList.add("chatting"), r.removeAttribute("aria-busy"), r.innerHTML = `
2316
+ return n ? (o.classList.remove("is-chat"), !1) : (k.removeAttribute("aria-busy"), k.innerHTML = oe("Couldn't load that report just now.", G), !1);
2317
+ u = i, t.markReportRead(i);
2318
+ const y = he(a.timeline);
2319
+ k.classList.add("chatting"), k.removeAttribute("aria-busy"), k.innerHTML = `
2166
2320
  <div class="report-head">
2167
- <span class="ttl">${m(a.title)}</span>
2168
- <span class="sub">${m(a.reference)} · ${m(a.project || "")}</span>
2169
- <span class="pill ${m(String(a.status).toLowerCase())}">${m(se(a.status))}</span>
2170
- ${(x = a.estimate) != null && x.label ? `<span class="eta-line">Usually takes ${m(String(a.estimate.label))}</span>` : ""}
2321
+ <span class="ttl">${v(a.title)}</span>
2322
+ <span class="sub">${v(a.reference)} · ${v(a.project || "")}</span>
2323
+ <span class="pill ${v(String(a.status).toLowerCase())}">${v(ie(a.status))}</span>
2324
+ ${(l = a.estimate) != null && l.label ? `<span class="eta-line">Usually takes ${v(String(a.estimate.label))}</span>` : ""}
2171
2325
  </div>
2172
- <div class="thread" role="log" aria-live="polite" aria-label="Conversation">${$}</div>`;
2173
- const E = r.querySelector(".thread");
2174
- return le.set(E, $), _(E), f(r, a), a.canReply && dt(e, r, E, c), g(r, a, c), _(E), !0;
2175
- }
2176
- let h = null;
2177
- function g(c, d, l) {
2178
- var O, B, k;
2179
- clearTimeout(h);
2180
- const a = d.assistant, r = c.querySelector(".thread");
2181
- let $ = c.querySelector(".assistant");
2326
+ <div class="thread" role="log" aria-live="polite" aria-label="Conversation">${y}</div>`;
2327
+ const m = k.querySelector(".thread");
2328
+ return se.set(m, y), _(m), L(k, a), g(k, a), a.canReply && mt(e, k, m, i), c(k, a, i), _(m), !0;
2329
+ }
2330
+ let s = null;
2331
+ function c(i, n, o) {
2332
+ var B, Q, C;
2333
+ clearTimeout(s);
2334
+ const a = n.assistant, k = i.querySelector(".thread");
2335
+ let y = i.querySelector(".assistant");
2182
2336
  if (!a) {
2183
- $ == null || $.remove(), (O = r == null ? void 0 : r.querySelector(".typing-row")) == null || O.remove();
2337
+ y == null || y.remove(), (B = k == null ? void 0 : k.querySelector(".typing-row")) == null || B.remove();
2184
2338
  return;
2185
2339
  }
2186
- const E = ($ == null ? void 0 : $.dataset.phase) || null;
2187
- $ || ($ = document.createElement("div"), $.setAttribute("role", "status"), $.setAttribute("aria-live", "polite"), (B = c.querySelector(".report-head")) == null || B.after($)), $.className = `assistant ${m(a.phase)}`, $.dataset.phase = a.phase;
2188
- const x = a.steps || [], p = x.filter((M) => M.state === "done").length, w = x.some((M) => M.state === "active") ? 0.5 : 0, S = x.length ? Math.round((p + w) / x.length * 100) : 0, A = `
2189
- <div class="as-body${E && E !== a.phase ? " entering" : ""}">
2340
+ const m = (y == null ? void 0 : y.dataset.phase) || null;
2341
+ y || (y = document.createElement("div"), y.setAttribute("role", "status"), y.setAttribute("aria-live", "polite"), (Q = i.querySelector(".report-head")) == null || Q.after(y)), y.className = `assistant ${v(a.phase)}`, y.dataset.phase = a.phase;
2342
+ const l = a.steps || [], $ = l.filter((M) => M.state === "done").length, q = l.some((M) => M.state === "active") ? 0.5 : 0, H = l.length ? Math.round(($ + q) / l.length * 100) : 0, O = `
2343
+ <div class="as-body${m && m !== a.phase ? " entering" : ""}">
2190
2344
  <div class="as-top">
2191
- <span class="as-orb" aria-hidden="true">${a.phase === "analyzing" ? '<span class="as-spin"></span>' : a.phase === "calling" ? ne : a.phase === "resolved" ? W : X}</span>
2345
+ <span class="as-orb${a.phase === "calling" || a.phase === "resolved" ? "" : " orb"}" aria-hidden="true">${a.phase === "calling" ? re : a.phase === "resolved" ? P : ""}</span>
2192
2346
  <div class="as-text">
2193
- <div class="as-title">${m(a.title)}</div>
2194
- <div class="as-detail">${m(a.detail)}</div>
2347
+ <div class="as-title">${v(a.title)}</div>
2348
+ <div class="as-detail">${v(a.detail)}</div>
2195
2349
  </div>
2196
2350
  </div>
2197
2351
  </div>
2198
- ${x.length ? `
2199
- <div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${S}"><i style="width:${S}%"></i></div>
2200
- <ol class="as-steps">${x.map((M) => `<li class="${m(M.state)}"${M.state === "active" ? ' aria-current="step"' : ""}><span class="dot"></span><span class="lbl">${m(M.label)}</span></li>`).join("")}</ol>` : ""}`, D = JSON.stringify([a.phase, a.title, a.detail, x]);
2201
- if ($.dataset.key !== D) {
2202
- const M = $.querySelector(".as-progress i"), H = M == null ? void 0 : M.style.width;
2203
- $.innerHTML = A, $.dataset.key = D;
2204
- const V = $.querySelector(".as-progress i");
2205
- V && H && (V.style.width = H, requestAnimationFrame(() => {
2206
- V.style.width = `${S}%`;
2352
+ ${l.length ? `
2353
+ <div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${H}"><i style="width:${H}%"></i></div>
2354
+ <ol class="as-steps">${l.map((M) => `<li class="${v(M.state)}"${M.state === "active" ? ' aria-current="step"' : ""}><span class="dot"></span><span class="lbl">${v(M.label)}</span></li>`).join("")}</ol>` : ""}`, N = JSON.stringify([a.phase, a.title, a.detail, l]);
2355
+ if (y.dataset.key !== N) {
2356
+ const M = y.querySelector(".as-progress i"), D = M == null ? void 0 : M.style.width;
2357
+ y.innerHTML = O, y.dataset.key = N;
2358
+ const V = y.querySelector(".as-progress i");
2359
+ V && D && (V.style.width = D, requestAnimationFrame(() => {
2360
+ V.style.width = `${H}%`;
2207
2361
  }));
2208
2362
  }
2209
- if (r) {
2210
- const M = ue(r), H = r.querySelector(".typing-row");
2211
- a.phase !== "analyzing" ? H == null || H.remove() : (!H || H !== r.lastElementChild) && (H == null || H.remove(), r.insertAdjacentHTML("beforeend", lt()), M && _(r));
2363
+ if (k) {
2364
+ const M = ue(k), D = k.querySelector(".typing-row");
2365
+ a.phase !== "analyzing" ? D == null || D.remove() : (!D || D !== k.lastElementChild) && (D == null || D.remove(), k.insertAdjacentHTML("beforeend", ft()), M && _(k));
2212
2366
  }
2213
- a.phase === "analyzing" ? h = setTimeout(() => b(l), 3e3) : a.phase === "calling" ? h = setTimeout(() => b(l), 1e4) : a.phase === "needs_info" && E !== "needs_info" && ((k = c.querySelector(".composer textarea")) == null || k.focus());
2214
- }
2215
- function f(c, d) {
2216
- var a, r;
2217
- if ((a = c.querySelector(".fix-verification")) == null || a.remove(), !d.resolvedAt || !["RESOLVED", "CLOSED"].includes(d.status)) return;
2218
- const l = document.createElement("div");
2219
- l.className = "fix-verification", d.verification ? l.textContent = d.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (l.innerHTML = '<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>', l.querySelectorAll("[data-result]").forEach(($) => {
2220
- $.onclick = async () => {
2221
- l.querySelectorAll("button").forEach((E) => {
2222
- E.disabled = !0;
2367
+ a.phase === "analyzing" ? s = setTimeout(() => w(o), 3e3) : a.phase === "calling" ? s = setTimeout(() => w(o), 1e4) : a.phase === "needs_info" && m !== "needs_info" && ((C = i.querySelector(".composer textarea")) == null || C.focus());
2368
+ }
2369
+ function L(i, n) {
2370
+ var a, k;
2371
+ if ((a = i.querySelector(".fix-verification")) == null || a.remove(), !n.resolvedAt || !["RESOLVED", "CLOSED"].includes(n.status)) return;
2372
+ const o = document.createElement("div");
2373
+ o.className = "fix-verification", n.verification ? o.textContent = n.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (o.innerHTML = '<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>', o.querySelectorAll("[data-result]").forEach((y) => {
2374
+ y.onclick = async () => {
2375
+ o.querySelectorAll("button").forEach((m) => {
2376
+ m.disabled = !0;
2223
2377
  });
2224
2378
  try {
2225
- await t.verifyFix(d.id, { result: $.dataset.result, resolvedAt: d.resolvedAt, note: l.querySelector("textarea").value }), await i(d.id);
2226
- } catch (E) {
2227
- l.querySelector(".feedback-status").textContent = E.message, l.querySelectorAll("button").forEach((x) => {
2228
- x.disabled = !1;
2379
+ await t.verifyFix(n.id, { result: y.dataset.result, resolvedAt: n.resolvedAt, note: o.querySelector("textarea").value }), await f(n.id);
2380
+ } catch (m) {
2381
+ o.querySelector(".feedback-status").textContent = m.message, o.querySelectorAll("button").forEach((l) => {
2382
+ l.disabled = !1;
2229
2383
  });
2230
2384
  }
2231
2385
  };
2232
- })), (r = c.querySelector(".report-head")) == null || r.after(l);
2386
+ })), (k = i.querySelector(".report-head")) == null || k.after(o);
2387
+ }
2388
+ function g(i, n) {
2389
+ var k;
2390
+ let o = i.querySelector(".fix-rating");
2391
+ if (!["RESOLVED", "CLOSED"].includes(n.status) || !n.ratingAsked) {
2392
+ o == null || o.remove();
2393
+ return;
2394
+ }
2395
+ o && o.dataset.key === ke(n.rating) || (o || (o = document.createElement("div"), o.className = "fix-rating", (k = i.querySelector(".fix-verification") || i.querySelector(".report-head")) == null || k.after(o)), de(o, { client: t, report: n, rating: n.rating || null }));
2233
2396
  }
2234
- async function b(c) {
2235
- const d = n.querySelector(".history.chatting"), l = d == null ? void 0 : d.querySelector(".thread");
2236
- if (!l || u !== c) return;
2397
+ async function w(i) {
2398
+ const n = r.querySelector(".history.chatting"), o = n == null ? void 0 : n.querySelector(".thread");
2399
+ if (!o || u !== i) return;
2237
2400
  let a = null;
2238
2401
  try {
2239
- a = await t.myReport(c);
2402
+ a = await t.myReport(i);
2240
2403
  } catch {
2241
2404
  }
2242
- if (e.closed || !a || u !== c) return;
2243
- f(d, a);
2244
- const r = ue(l), $ = he(a.timeline);
2245
- le.get(l) !== $ && (l.innerHTML = $, le.set(l, $)), g(d, a, c), r && _(l);
2246
- const E = d.querySelector(".report-head .pill");
2247
- E && (E.className = `pill ${String(a.status).toLowerCase()}`, E.textContent = se(a.status));
2248
- }
2249
- const z = t.on("update", (c) => {
2250
- !u || (c == null ? void 0 : c.bugId) !== u || (t.markReportRead(u), b(u));
2405
+ if (e.closed || !a || u !== i) return;
2406
+ L(n, a), g(n, a);
2407
+ const k = ue(o), y = he(a.timeline);
2408
+ se.get(o) !== y && (o.innerHTML = y, se.set(o, y)), c(n, a, i), k && _(o);
2409
+ const m = n.querySelector(".report-head .pill");
2410
+ m && (m.className = `pill ${String(a.status).toLowerCase()}`, m.textContent = ie(a.status));
2411
+ }
2412
+ const x = t.on("update", (i) => {
2413
+ !u || (i == null ? void 0 : i.bugId) !== u || (t.markReportRead(u), w(u));
2251
2414
  });
2252
2415
  e.onDestroy(() => {
2253
- z(), clearTimeout(h);
2254
- }), (Q = n.querySelector('[data-act="history"]')) == null || Q.addEventListener("click", s), e.succeed = T, e.refreshThread = b, e.openReportId = () => u;
2416
+ x(), clearTimeout(s);
2417
+ }), (T = r.querySelector('[data-act="history"]')) == null || T.addEventListener("click", h), e.succeed = S, e.refreshThread = w, e.openReportId = () => u;
2418
+ }
2419
+ const $e = "bugcatch.rateLater", yt = 50;
2420
+ function Se() {
2421
+ try {
2422
+ const e = JSON.parse(window.localStorage.getItem($e) || "[]");
2423
+ return Array.isArray(e) ? e : [];
2424
+ } catch {
2425
+ return [];
2426
+ }
2427
+ }
2428
+ function wt(e) {
2429
+ try {
2430
+ const t = Se().filter((r) => r !== e);
2431
+ t.push(e), window.localStorage.setItem($e, JSON.stringify(t.slice(-yt)));
2432
+ } catch {
2433
+ }
2434
+ }
2435
+ function kt(e, t = Se()) {
2436
+ const r = new Set(t), d = (e || []).filter((S) => S.ratingDue === "require" || S.ratingDue === "ask" && !r.has(S.id));
2437
+ if (!d.length) return null;
2438
+ const u = (S) => new Date(S.resolvedAt || S.updatedAt || 0).getTime() || 0;
2439
+ return d.reduce((S, b) => u(b) > u(S) ? b : S);
2440
+ }
2441
+ function $t(e) {
2442
+ const {
2443
+ client: t,
2444
+ rateDue: r,
2445
+ compose: d,
2446
+ picks: u,
2447
+ known: S,
2448
+ callBtn: b,
2449
+ titleInput: h,
2450
+ scrim: f
2451
+ } = e;
2452
+ let s = !1;
2453
+ e.mustRate = () => s;
2454
+ function c(x) {
2455
+ s = x;
2456
+ for (const T of [d, u, S])
2457
+ T.classList.toggle("held", x), T.inert = x;
2458
+ x ? b.hidden = !0 : e.callOffered() && !e.mustSignIn() && (b.hidden = !1), e.refreshSendState();
2459
+ }
2460
+ function L() {
2461
+ s && c(!1);
2462
+ }
2463
+ function g() {
2464
+ r.hidden = !0, r.replaceChildren(), L(), h.focus();
2465
+ }
2466
+ function w(x) {
2467
+ var o;
2468
+ const T = x.ratingDue === "require", i = x.resolvedAt ? J(x.resolvedAt) : "", n = x.status === "CLOSED" ? "closed" : "fixed";
2469
+ if (r.hidden = !1, r.classList.toggle("is-required", T), r.innerHTML = `
2470
+ <div class="rd-head">
2471
+ <span class="rd-eyebrow">${T ? "Before you report something new" : `Your report was ${n}`}</span>
2472
+ ${T ? "" : '<button type="button" class="link rd-later" data-act="rate-later">Not now</button>'}
2473
+ </div>
2474
+ <p class="rd-report">
2475
+ <span class="rd-ico" aria-hidden="true">${P}</span>
2476
+ <span class="rd-ttl">${v(x.title)}</span>
2477
+ <span class="rd-sub">${v(x.reference)}${i ? ` · ${n} ${v(i)}` : ""}</span>
2478
+ </p>
2479
+ <div class="rd-stars"></div>`, (o = r.querySelector('[data-act="rate-later"]')) == null || o.addEventListener("click", () => {
2480
+ wt(x.id), g();
2481
+ }), de(r.querySelector(".rd-stars"), {
2482
+ client: t,
2483
+ report: x,
2484
+ rating: null,
2485
+ question: T ? "How did we handle it? Rate it to send a new one." : "How did we do?",
2486
+ onRated: () => {
2487
+ var a;
2488
+ r.querySelector(".rd-eyebrow").textContent = `Your report was ${n}`, (a = r.querySelector('[data-act="skip"]')) == null || a.remove(), r.classList.remove("is-required"), L();
2489
+ },
2490
+ // The rating could not be sent. A held form must not turn into a locked
2491
+ // door because of our outage: offer the way past.
2492
+ onError: () => {
2493
+ if (!s || r.querySelector('[data-act="skip"]')) return;
2494
+ const a = document.createElement("button");
2495
+ a.type = "button", a.className = "link rd-later", a.dataset.act = "skip", a.textContent = "Skip for now", a.addEventListener("click", g), r.querySelector(".rd-head").append(a);
2496
+ }
2497
+ }), T) {
2498
+ c(!0);
2499
+ const a = f.getRootNode().activeElement;
2500
+ (!a || !r.contains(a)) && r.focus();
2501
+ }
2502
+ }
2503
+ t.hasReports() && t.myReports().then(({ reports: x }) => {
2504
+ if (e.closed) return;
2505
+ const T = kt(x);
2506
+ T && w(T);
2507
+ }).catch(() => {
2508
+ });
2255
2509
  }
2256
- function bt({
2510
+ function Qt({
2257
2511
  root: e,
2258
2512
  host: t,
2259
- dock: n,
2260
- client: y,
2513
+ dock: r,
2514
+ client: d,
2261
2515
  onClose: u,
2262
- preloadCall: T = () => {
2263
- }
2516
+ preloadCall: S = () => {
2517
+ },
2518
+ themeControls: b = null
2264
2519
  }) {
2265
- ut(e);
2266
- const v = y.config, s = document.createElement("div");
2267
- s.className = `scrim ${n.classList.contains("at-left") ? "at-left" : "at-right"} ${n.classList.contains("at-top") ? "at-top" : "at-bottom"}`, s.style.setProperty("--bc-dock-h", `${Math.round(n.getBoundingClientRect().height)}px`), s.innerHTML = `
2520
+ St(e);
2521
+ const h = d.config, f = () => (b == null ? void 0 : b.label()) || "", s = document.createElement("div");
2522
+ s.className = `scrim ${r.classList.contains("at-left") ? "at-left" : "at-right"} ${r.classList.contains("at-top") ? "at-top" : "at-bottom"}`, s.style.setProperty("--bc-dock-h", `${Math.round(r.getBoundingClientRect().height)}px`), s.innerHTML = `
2268
2523
  <div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
2269
- ${ce({
2524
+ ${le({
2270
2525
  id: "bc-h",
2271
- title: "Tell us what went wrong",
2272
- sub: "Our assistant starts looking right away. We attach the page details for you."
2526
+ // Not "Tell us what went wrong": that is the first field's own label,
2527
+ // a few pixels below. The header names the errand the launcher named.
2528
+ title: "Report a bug",
2529
+ sub: "We attach the page details for you.",
2530
+ theme: f()
2273
2531
  })}
2274
2532
  <div class="body">
2275
2533
  <div class="slot" role="alert"></div>
2534
+ <!-- A settled report still waiting for its rating. Drawn only when the
2535
+ project asks for one here; see rate-due.js. -->
2536
+ <div class="rate-due fix-rating" tabindex="-1" hidden></div>
2276
2537
  <!-- What the project's team is telling visitors. Drawn only when it
2277
2538
  has published something. -->
2278
2539
  <div class="notices" hidden></div>
@@ -2281,51 +2542,53 @@ function bt({
2281
2542
  close by itself. Drawn only when the project offers any. -->
2282
2543
  <div class="picks" hidden></div>
2283
2544
  <div class="known" hidden></div>
2284
- ${Ge(v)}
2545
+ ${nt(h)}
2285
2546
  </div>
2286
2547
  <div class="foot">
2287
2548
  <span class="note" aria-live="polite"></span>
2288
- ${y.hasReports() ? '<button class="quiet" type="button" data-act="history">Your reports</button>' : ""}
2549
+ ${d.hasReports() ? '<button class="quiet" type="button" data-act="history">Your reports</button>' : ""}
2289
2550
  <span class="spacer"></span>
2290
2551
  <!-- Hidden until the API confirms this project can take a call, which
2291
2552
  most cannot. Drawn here rather than as a second launcher because it
2292
2553
  is the same errand as Send report — the difference is only whether
2293
2554
  the reporter would rather say it than type it. -->
2294
- <button class="ghost" type="button" data-act="call" hidden>${ne}Talk to the team</button>
2555
+ <button class="ghost" type="button" data-act="call" hidden>${re}Talk to the team</button>
2295
2556
  <button class="primary" type="button" data-act="send">Send report ${ge}</button>
2296
2557
  </div>
2297
2558
  <div class="powered">Powered by
2298
- <a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Be}</a>
2559
+ <a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Ue}</a>
2299
2560
  </div>
2300
2561
  </div>`;
2301
- const i = (r) => s.querySelector(r), h = i(".slot"), g = [], f = {
2302
- client: y,
2303
- cfg: v,
2562
+ const c = (y) => s.querySelector(y), L = c(".slot"), g = [], w = {
2563
+ client: d,
2564
+ cfg: h,
2304
2565
  root: e,
2305
2566
  host: t,
2306
- dock: n,
2567
+ dock: r,
2307
2568
  scrim: s,
2308
- $: i,
2309
- titleInput: i("#bc-title"),
2310
- descInput: i("#bc-desc"),
2311
- compose: i(".compose"),
2312
- sendBtn: i('[data-act="send"]'),
2313
- callBtn: i('[data-act="call"]'),
2314
- historyBtn: i('[data-act="history"]'),
2315
- note: i(".foot .note"),
2316
- whoami: i(".whoami"),
2317
- refsBox: i(".refs"),
2318
- notices: i(".notices"),
2319
- known: i(".known"),
2320
- picks: i(".picks"),
2569
+ $: c,
2570
+ titleInput: c("#bc-title"),
2571
+ descInput: c("#bc-desc"),
2572
+ compose: c(".compose"),
2573
+ sendBtn: c('[data-act="send"]'),
2574
+ callBtn: c('[data-act="call"]'),
2575
+ historyBtn: c('[data-act="history"]'),
2576
+ note: c(".foot .note"),
2577
+ whoami: c(".whoami"),
2578
+ refsBox: c(".refs"),
2579
+ notices: c(".notices"),
2580
+ known: c(".known"),
2581
+ picks: c(".picks"),
2582
+ rateDue: c(".rate-due"),
2321
2583
  // A report or a call is on its way. Escape and a click outside wait for it.
2322
2584
  sending: !1,
2323
2585
  closed: !1,
2324
- say: a,
2325
- close: d,
2326
- preloadCall: T,
2327
- onDestroy: (r) => {
2328
- g.push(r);
2586
+ say: k,
2587
+ close: o,
2588
+ preloadCall: S,
2589
+ themeLabel: f,
2590
+ onDestroy: (y) => {
2591
+ g.push(y);
2329
2592
  },
2330
2593
  // compose.js
2331
2594
  refreshSendState: null,
@@ -2343,60 +2606,67 @@ function bt({
2343
2606
  // signin.js
2344
2607
  mustSignIn: null,
2345
2608
  recheckSignIn: null,
2609
+ // rate-due.js
2610
+ mustRate: () => !1,
2346
2611
  // thread.js
2347
2612
  succeed: null,
2348
2613
  refreshThread: null,
2349
2614
  openReportId: null
2350
2615
  };
2351
- Xe(f), Je(f), tt(f), at(f), nt(f), ot(f), rt(f), pt(f);
2352
- const b = document.activeElement, z = document.documentElement.style, Q = z.overflow;
2353
- z.overflow = "hidden";
2354
- function c() {
2355
- f.closed || (g.forEach((r) => r()), f.closed = !0, z.overflow = Q, document.removeEventListener("keydown", l, !0), s.remove(), n.hidden = !1, t.style.opacity = "", u == null || u());
2356
- }
2357
- function d() {
2358
- var r;
2359
- if (!f.closed) {
2360
- s.classList.add("closing"), setTimeout(c, 160);
2616
+ ot(w), it(w), lt(w), ct(w), dt(w), pt(w), ut(w), xt(w), $t(w);
2617
+ const x = document.activeElement, T = document.documentElement.style, i = T.overflow;
2618
+ T.overflow = "hidden";
2619
+ function n() {
2620
+ w.closed || (g.forEach((y) => y()), w.closed = !0, T.overflow = i, document.removeEventListener("keydown", a, !0), s.remove(), r.hidden = !1, t.style.opacity = "", u == null || u());
2621
+ }
2622
+ function o() {
2623
+ var y;
2624
+ if (!w.closed) {
2625
+ s.classList.add("closing"), setTimeout(n, 160);
2361
2626
  try {
2362
- (r = b == null ? void 0 : b.focus) == null || r.call(b);
2627
+ (y = x == null ? void 0 : x.focus) == null || y.call(x);
2363
2628
  } catch {
2364
2629
  }
2365
2630
  }
2366
2631
  }
2367
- function l(r) {
2368
- if (r.key === "Escape") {
2369
- if (r.stopPropagation(), f.isRecording()) {
2370
- f.stopRecording({ keep: !1 });
2632
+ function a(y) {
2633
+ if (y.key === "Escape") {
2634
+ if (y.stopPropagation(), w.isRecording()) {
2635
+ w.stopRecording({ keep: !1 });
2371
2636
  return;
2372
2637
  }
2373
- f.sending || d();
2638
+ w.sending || o();
2374
2639
  return;
2375
2640
  }
2376
- if (r.key !== "Tab" || f.isRecording()) return;
2377
- const $ = [...s.querySelectorAll(
2641
+ if (y.key !== "Tab" || w.isRecording()) return;
2642
+ const m = [...s.querySelectorAll(
2378
2643
  "button:not(:disabled), input:not([hidden]), textarea, select, [href]"
2379
- )].filter((w) => w.offsetParent !== null || w === document.activeElement);
2380
- if (!$.length) return;
2381
- const E = $[0], x = $[$.length - 1], p = s.getRootNode().activeElement;
2382
- r.shiftKey && p === E ? (r.preventDefault(), x.focus()) : !r.shiftKey && p === x && (r.preventDefault(), E.focus());
2644
+ )].filter((H) => H.offsetParent !== null || H === document.activeElement);
2645
+ if (!m.length) return;
2646
+ const l = m[0], $ = m[m.length - 1], q = s.getRootNode().activeElement;
2647
+ y.shiftKey && q === l ? (y.preventDefault(), $.focus()) : !y.shiftKey && q === $ && (y.preventDefault(), l.focus());
2383
2648
  }
2384
- document.addEventListener("keydown", l, !0), s.addEventListener("click", (r) => {
2385
- r.target === s && !f.sending && d();
2386
- }), i('[data-act="close"]').addEventListener("click", d);
2387
- function a(r, $ = "err") {
2388
- h.innerHTML = r ? `<div class="msg ${$}">${$ === "err" ? G : ""}<span>${m(r)}</span></div>` : "";
2649
+ document.addEventListener("keydown", a, !0), s.addEventListener("click", (y) => {
2650
+ y.target === s && !w.sending && o();
2651
+ }), c('[data-act="close"]').addEventListener("click", o), s.addEventListener("click", (y) => {
2652
+ const m = y.target.closest('[data-act="theme"]');
2653
+ if (!m || !b) return;
2654
+ const l = b.cycle();
2655
+ m.title = `Theme: ${l.label}`, m.setAttribute("aria-label", `Theme: ${l.label}. Change theme`);
2656
+ });
2657
+ function k(y, m = "err") {
2658
+ L.innerHTML = y ? `<div class="msg ${m}">${m === "err" ? G : ""}<span>${v(y)}</span></div>` : "";
2389
2659
  }
2390
- return e.appendChild(s), f.refreshSendState(), f.titleInput.focus(), { destroy: c, close: d };
2660
+ return e.appendChild(s), w.refreshSendState(), w.titleInput.focus(), { destroy: n, close: o };
2391
2661
  }
2392
- function ut(e) {
2662
+ function St(e) {
2393
2663
  if (e.querySelector("style[data-panel]")) return;
2394
2664
  const t = document.createElement("style");
2395
- t.setAttribute("data-panel", ""), t.textContent = Ne;
2396
- const n = e.querySelector("style");
2397
- n ? n.after(t) : e.prepend(t);
2665
+ t.setAttribute("data-panel", ""), t.textContent = Ze;
2666
+ const r = e.querySelector("style");
2667
+ r ? r.after(t) : e.prepend(t);
2398
2668
  }
2399
2669
  export {
2400
- bt as openPanel
2670
+ Qt as openPanel
2401
2671
  };
2402
2672
  //# sourceMappingURL=bugcatch-panel.es.js.map