@sphoro/bugcatch-web-sdk 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -3
- package/dist/bugcatch-call.es.js +201 -200
- package/dist/bugcatch-call.es.js.map +1 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-call.umd.js.map +1 -1
- package/dist/bugcatch-core.es.js +1085 -1007
- package/dist/bugcatch-core.es.js.map +1 -1
- package/dist/bugcatch-panel.es.js +1179 -1050
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +397 -326
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +520 -437
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +132 -120
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/accent.js +38 -0
- package/src/incoming-call.js +17 -15
- package/src/index.d.ts +43 -2
- package/src/index.js +26 -7
- package/src/panel/icons.js +2 -0
- package/src/panel/index.js +17 -3
- package/src/panel/messages.js +2 -2
- package/src/panel/picks.js +6 -2
- package/src/panel/refs.js +1 -1
- package/src/panel/render.js +11 -3
- package/src/panel/styles.js +242 -186
- package/src/panel/thread.js +117 -7
- package/src/updates.js +77 -27
- package/src/widget.js +160 -141
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){"use strict";const qe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>',_='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',J='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',O='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',ue='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>',He='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>',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>',Re='<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>',he='<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>',be='<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>',fe='<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>',Ae='<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',De='<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>',ee='<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>',Ve='<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>',F='<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
|
+
(function(){"use strict";const He='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>',Ie='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',Re='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',Ae='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',Y='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',X='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',W='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',pe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>',De='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>',Ve='<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>',je='<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>',ue='<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>',he='<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>',be='<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>',Oe='<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',Be='<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>',J='<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>',Ne='<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>',Pe='<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>',fe='<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>',We='<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>',Fe='<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>',Ye=`
|
|
2
2
|
@keyframes bc-fade-in { from { opacity: 0 } to { opacity: 1 } }
|
|
3
3
|
@keyframes bc-fade-out { to { opacity: 0 } }
|
|
4
4
|
@keyframes bc-panel-in { from { opacity: 0; transform: translateY(14px) scale(.965) } to { opacity: 1; transform: none } }
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
@keyframes bc-shimmer { from { background-position: 200% 0 } to { background-position: -200% 0 } }
|
|
15
15
|
|
|
16
16
|
/* ---------- scrim + panel ---------- */
|
|
17
|
+
/* Still modal — focus stays in the panel and a click outside closes it — but
|
|
18
|
+
the host's page only dims enough to say so. It is their product, and the
|
|
19
|
+
visitor is reporting something about what is on it. */
|
|
17
20
|
.scrim {
|
|
18
21
|
position: fixed; inset: 0; z-index: 2147483001;
|
|
19
|
-
background: rgba(
|
|
22
|
+
background: rgba(14,14,16,.14);
|
|
20
23
|
animation: bc-fade-in 200ms ease both;
|
|
21
24
|
}
|
|
22
25
|
.scrim.closing { animation: bc-fade-out 170ms ease both; }
|
|
@@ -28,12 +31,11 @@
|
|
|
28
31
|
.panel {
|
|
29
32
|
position: fixed;
|
|
30
33
|
display: flex; flex-direction: column;
|
|
31
|
-
width: calc(100vw - 40px); max-width:
|
|
34
|
+
width: calc(100vw - 40px); max-width: 400px;
|
|
32
35
|
max-height: calc(100vh - var(--bc-dock-h, 84px) - 52px);
|
|
33
36
|
overflow: hidden;
|
|
34
37
|
background: var(--bc-bg); color: var(--bc-fg);
|
|
35
38
|
border-radius: var(--bc-r-xl); box-shadow: var(--bc-shadow);
|
|
36
|
-
border: 1px solid color-mix(in srgb, var(--bc-border) 70%, transparent);
|
|
37
39
|
animation: bc-panel-in 340ms var(--bc-ease) both;
|
|
38
40
|
}
|
|
39
41
|
/* A conversation wants a height of its own, so the thread fills the panel
|
|
@@ -48,57 +50,58 @@
|
|
|
48
50
|
/* ---------- header ---------- */
|
|
49
51
|
.head {
|
|
50
52
|
flex: none; position: relative;
|
|
51
|
-
display: flex; align-items: center; gap:
|
|
52
|
-
padding:
|
|
53
|
-
background:
|
|
53
|
+
display: flex; align-items: center; gap: 11px;
|
|
54
|
+
padding: 14px 10px 13px var(--bc-pad);
|
|
55
|
+
background: var(--bc-bg);
|
|
54
56
|
border-bottom: 1px solid var(--bc-border);
|
|
55
57
|
}
|
|
56
|
-
.head .mark
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
|
|
60
|
-
color: var(--bc-on-accent); font-size: 19px;
|
|
61
|
-
box-shadow: 0 4px 12px color-mix(in srgb, var(--bc-accent) 30%, transparent);
|
|
62
|
-
}
|
|
63
|
-
/* The little "online" dot says someone — or something — is on the other end. */
|
|
64
|
-
.head .mark::after {
|
|
65
|
-
content: ''; position: absolute; right: -1px; bottom: -1px;
|
|
66
|
-
width: 11px; height: 11px; border-radius: 50%;
|
|
67
|
-
background: #22c55e; border: 2px solid var(--bc-bg);
|
|
68
|
-
}
|
|
58
|
+
.head .mark { width: 32px; }
|
|
59
|
+
/* The assistant asking its one follow-up wears the same orb, smaller. */
|
|
60
|
+
.avatar.orb { width: 26px; }
|
|
69
61
|
.head .titles { flex: 1; min-width: 0; }
|
|
70
62
|
.head h2 {
|
|
71
|
-
margin: 0 0
|
|
63
|
+
margin: 0 0 1px; font-size: var(--bc-fs-lg); font-weight: 600; letter-spacing: -.015em; line-height: 1.3;
|
|
64
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
65
|
+
}
|
|
66
|
+
.head p {
|
|
67
|
+
margin: 0; font-size: var(--bc-fs-sm); line-height: 1.4; color: var(--bc-muted);
|
|
72
68
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
73
69
|
}
|
|
74
|
-
.head p { margin: 0; font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted); }
|
|
75
70
|
.icon-btn {
|
|
76
71
|
flex: none; display: grid; place-items: center;
|
|
77
72
|
width: 32px; height: 32px; padding: 0; font-size: 16px;
|
|
78
|
-
border: none; border-radius:
|
|
73
|
+
border: none; border-radius: 999px; background: none; color: var(--bc-muted);
|
|
79
74
|
cursor: pointer; transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
80
75
|
}
|
|
81
76
|
.icon-btn:hover { background: color-mix(in srgb, var(--bc-fg) 7%, transparent); color: var(--bc-fg); }
|
|
82
77
|
.icon-btn:active { transform: scale(.92); }
|
|
83
78
|
.icon-btn.back { margin: 0 -6px 0 -8px; }
|
|
79
|
+
/* The theme button holds all three glyphs; the host's class picks one. */
|
|
80
|
+
.icon-btn.theme { font-size: 15px; margin-right: -4px; }
|
|
81
|
+
.icon-btn.theme > span { display: none; }
|
|
82
|
+
:host(.bc-light) .icon-btn.theme .m-light,
|
|
83
|
+
:host(.bc-dark) .icon-btn.theme .m-dark,
|
|
84
|
+
:host(.bc-auto) .icon-btn.theme .m-auto { display: block; }
|
|
84
85
|
|
|
85
86
|
.body {
|
|
86
87
|
flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
|
|
87
|
-
padding:
|
|
88
|
+
padding: 14px var(--bc-pad) 4px;
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
label { display: block; font-size:
|
|
91
|
+
label { display: block; font-size: 13px; font-weight: 560; color: var(--bc-fg); margin-bottom: 6px; letter-spacing: -.005em; }
|
|
91
92
|
label .opt { font-weight: 450; color: var(--bc-faint); }
|
|
93
|
+
/* Fields are stone wells that turn white when you are in them, the way the
|
|
94
|
+
rest of the product's forms do. */
|
|
92
95
|
input[type=text], input[type=email], textarea {
|
|
93
|
-
width: 100%; padding:
|
|
94
|
-
color: var(--bc-fg); background: var(--bc-
|
|
95
|
-
border: 1px solid
|
|
96
|
+
width: 100%; padding: 10px 12px; font-size: var(--bc-fs-md); line-height: 1.45;
|
|
97
|
+
color: var(--bc-fg); background: var(--bc-stone);
|
|
98
|
+
border: 1px solid transparent; border-radius: var(--bc-r-md);
|
|
96
99
|
transition: border-color 160ms, box-shadow 160ms, background 160ms;
|
|
97
100
|
}
|
|
98
101
|
input[type=text]::placeholder, input[type=email]::placeholder, textarea::placeholder { color: var(--bc-faint); }
|
|
99
|
-
input[type=text]:hover, input[type=email]:hover, textarea:hover { border-color:
|
|
102
|
+
input[type=text]:hover, input[type=email]:hover, textarea:hover { border-color: var(--bc-border); }
|
|
100
103
|
input[type=text]:focus, input[type=email]:focus, textarea:focus {
|
|
101
|
-
outline: none; border-color: var(--bc-accent); box-shadow: var(--bc-ring);
|
|
104
|
+
outline: none; background: var(--bc-bg); border-color: var(--bc-accent); box-shadow: var(--bc-ring);
|
|
102
105
|
}
|
|
103
106
|
input.invalid, input.invalid:focus, textarea.invalid {
|
|
104
107
|
border-color: var(--bc-danger); animation: bc-nudge 240ms ease;
|
|
@@ -110,8 +113,8 @@ input.invalid, input.invalid:focus, textarea.invalid {
|
|
|
110
113
|
animation: bc-rise 200ms var(--bc-ease) both;
|
|
111
114
|
}
|
|
112
115
|
.field-err svg { font-size: 13px; flex: none; }
|
|
113
|
-
textarea { min-height:
|
|
114
|
-
.field { margin-bottom:
|
|
116
|
+
textarea { min-height: 76px; resize: vertical; }
|
|
117
|
+
.field { margin-bottom: 14px; }
|
|
115
118
|
.field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
|
|
116
119
|
.field-head .count { font-size: var(--bc-fs-xs); color: var(--bc-faint); font-variant-numeric: tabular-nums; }
|
|
117
120
|
|
|
@@ -121,15 +124,15 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
121
124
|
.compose > .note:has(button) {
|
|
122
125
|
display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
|
|
123
126
|
margin: 0 0 14px; padding: 10px 12px; border-radius: var(--bc-r-md);
|
|
124
|
-
background: var(--bc-
|
|
127
|
+
background: var(--bc-subtle); border: 1px solid var(--bc-border);
|
|
125
128
|
font-size: var(--bc-fs-sm); color: var(--bc-fg);
|
|
126
129
|
}
|
|
127
130
|
.compose > .note button {
|
|
128
|
-
padding: 5px 11px; font: inherit; font-size: var(--bc-fs-xs); font-weight:
|
|
131
|
+
padding: 5px 11px; font: inherit; font-size: var(--bc-fs-xs); font-weight: 600;
|
|
129
132
|
border-radius: 999px; cursor: pointer;
|
|
130
133
|
border: 1px solid var(--bc-accent); background: var(--bc-accent); color: var(--bc-on-accent);
|
|
131
134
|
}
|
|
132
|
-
.compose > .note button[data-discard] { background:
|
|
135
|
+
.compose > .note button[data-discard] { background: var(--bc-bg); color: var(--bc-fg); border-color: var(--bc-border); }
|
|
133
136
|
|
|
134
137
|
/* ---------- what is already known ----------
|
|
135
138
|
A help surface in front of the form, not a step in it. Everything here is
|
|
@@ -137,58 +140,57 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
137
140
|
leave, tap "this is happening to me too" and leave, or type straight past all
|
|
138
141
|
of it and file the report they came to file. Nothing is ever in their way,
|
|
139
142
|
because a reporter who feels handled rather than helped stops reporting. */
|
|
140
|
-
|
|
141
|
-
.known .known-h {
|
|
142
|
-
margin: 0 0
|
|
143
|
+
/* One small eyebrow style for every group above the form. */
|
|
144
|
+
.known .known-h, .picks .picks-h {
|
|
145
|
+
margin: 0 0 7px; font-size: 11px; font-weight: 600; letter-spacing: .07em;
|
|
143
146
|
text-transform: uppercase; color: var(--bc-faint);
|
|
144
147
|
}
|
|
148
|
+
.known { margin-bottom: 14px; }
|
|
149
|
+
/* Hairline rows on the panel's own white, so they read as a list to scan
|
|
150
|
+
rather than more coloured cards to wade through. */
|
|
145
151
|
.known .issue {
|
|
146
152
|
display: flex; align-items: center; gap: 10px;
|
|
147
|
-
padding:
|
|
148
|
-
background: var(--bc-
|
|
153
|
+
padding: 8px 8px 8px 12px; margin-bottom: 6px;
|
|
154
|
+
background: var(--bc-bg); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
|
|
149
155
|
animation: bc-rise 240ms var(--bc-ease) both;
|
|
150
156
|
}
|
|
151
|
-
.known .issue.is-joined {
|
|
157
|
+
.known .issue.is-joined { background: color-mix(in srgb, var(--bc-ok) 6%, var(--bc-bg)); }
|
|
152
158
|
.known .issue .who { flex: 1; min-width: 0; }
|
|
153
159
|
.known .issue .t {
|
|
154
|
-
display: block; font-size: 13px; font-weight:
|
|
160
|
+
display: block; font-size: 13px; font-weight: 560; line-height: 1.4;
|
|
155
161
|
color: var(--bc-fg); overflow-wrap: anywhere;
|
|
156
162
|
}
|
|
157
163
|
.known .issue .meta {
|
|
158
|
-
display: block; margin-top:
|
|
164
|
+
display: block; margin-top: 2px; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted);
|
|
159
165
|
}
|
|
160
166
|
.known .issue .join {
|
|
161
|
-
flex: none; padding:
|
|
162
|
-
color: var(--bc-
|
|
163
|
-
border:
|
|
164
|
-
transition: background 160ms,
|
|
167
|
+
flex: none; height: 30px; padding: 0 12px; font: inherit; font-size: 12px; font-weight: 560;
|
|
168
|
+
color: var(--bc-fg); background: var(--bc-stone);
|
|
169
|
+
border: 0; border-radius: 999px; cursor: pointer;
|
|
170
|
+
transition: background 160ms, color 160ms;
|
|
165
171
|
}
|
|
166
|
-
.known .issue .join:hover {
|
|
167
|
-
.known .issue .join:disabled { color: var(--bc-ok);
|
|
172
|
+
.known .issue .join:hover { background: color-mix(in srgb, var(--bc-fg) 12%, var(--bc-stone)); }
|
|
173
|
+
.known .issue .join:disabled { color: var(--bc-ok); background: transparent; cursor: default; opacity: 1; }
|
|
168
174
|
.known .ask { display: flex; gap: 8px; margin: 2px 0 8px; }
|
|
169
175
|
.known .ask input { flex: 1; min-width: 0; }
|
|
170
176
|
.known .ask button { flex: none; }
|
|
171
177
|
.known .err { margin: 6px 0 0; font-size: 12px; line-height: 1.45; color: var(--bc-danger); }
|
|
172
178
|
|
|
173
179
|
/* ---------- questions the assistant answers by itself ---------- */
|
|
174
|
-
.picks { margin-bottom:
|
|
175
|
-
.picks .picks-
|
|
176
|
-
margin: 0 0 8px; font-size: 11px; font-weight: 680; letter-spacing: .06em;
|
|
177
|
-
text-transform: uppercase; color: var(--bc-faint);
|
|
178
|
-
}
|
|
179
|
-
.picks .picks-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
|
|
180
|
+
.picks { margin-bottom: 14px; }
|
|
181
|
+
.picks .picks-grid { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
180
182
|
.picks .pick {
|
|
181
|
-
display: flex;
|
|
182
|
-
padding:
|
|
183
|
-
color: var(--bc-fg); background: var(--bc-
|
|
184
|
-
border: 1px solid
|
|
185
|
-
transition: background 160ms, border-color 160ms, transform 160ms;
|
|
183
|
+
display: inline-flex; align-items: center; max-width: 100%;
|
|
184
|
+
min-height: 32px; padding: 6px 13px; text-align: left; cursor: pointer; font: inherit;
|
|
185
|
+
color: var(--bc-fg); background: var(--bc-stone);
|
|
186
|
+
border: 1px solid transparent; border-radius: 999px;
|
|
187
|
+
transition: background 160ms, border-color 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
186
188
|
animation: bc-rise 240ms var(--bc-ease) both;
|
|
187
189
|
}
|
|
188
|
-
.picks .pick:hover {
|
|
189
|
-
.picks .pick
|
|
190
|
-
.picks .pick
|
|
191
|
-
.picks .pick .
|
|
190
|
+
.picks .pick:hover { background: color-mix(in srgb, var(--bc-fg) 10%, var(--bc-stone)); }
|
|
191
|
+
.picks .pick:active { transform: scale(.97); }
|
|
192
|
+
.picks .pick[aria-pressed="true"] { background: var(--bc-accent); color: var(--bc-on-accent); }
|
|
193
|
+
.picks .pick .t { font-size: 13px; font-weight: 520; line-height: 1.35; overflow-wrap: anywhere; }
|
|
192
194
|
.picks .picks-note {
|
|
193
195
|
display: flex; gap: 6px; align-items: flex-start; margin: 8px 0 0;
|
|
194
196
|
font-size: 12px; line-height: 1.45; color: var(--bc-muted);
|
|
@@ -202,18 +204,21 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
202
204
|
strip is the whole panel. */
|
|
203
205
|
.whoami {
|
|
204
206
|
display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
|
|
205
|
-
margin-bottom:
|
|
207
|
+
margin-bottom: 14px; padding: 9px 12px;
|
|
206
208
|
font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted);
|
|
207
209
|
background: var(--bc-subtle); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md);
|
|
208
210
|
}
|
|
209
211
|
.whoami.asking { display: block; padding: 14px; }
|
|
212
|
+
.whoami.asking .row input { background: var(--bc-bg); border-color: var(--bc-border); }
|
|
210
213
|
.whoami .who { flex: 1; min-width: 0; }
|
|
211
214
|
.whoami .who strong { color: var(--bc-fg); font-weight: 620; word-break: break-all; }
|
|
212
215
|
.link {
|
|
213
|
-
padding: 0; font: inherit; font-size: var(--bc-fs-sm); font-weight:
|
|
214
|
-
color: var(--bc-
|
|
216
|
+
padding: 0; font: inherit; font-size: var(--bc-fs-sm); font-weight: 560; line-height: 1.45;
|
|
217
|
+
color: var(--bc-fg); background: none; border: none; cursor: pointer; border-radius: 4px;
|
|
218
|
+
text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--bc-fg) 30%, transparent);
|
|
219
|
+
text-underline-offset: 3px;
|
|
215
220
|
}
|
|
216
|
-
.link:hover { text-decoration
|
|
221
|
+
.link:hover { text-decoration-color: currentColor; }
|
|
217
222
|
.link:disabled { color: var(--bc-faint); cursor: default; text-decoration: none; }
|
|
218
223
|
.whoami .why { margin: 0 0 10px; font-size: var(--bc-fs-sm); line-height: 1.5; color: var(--bc-muted); }
|
|
219
224
|
.whoami .why strong { color: var(--bc-fg); font-weight: 620; word-break: break-all; }
|
|
@@ -230,18 +235,17 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
230
235
|
assistant asking one friendly follow-up, not as a form field that appeared. */
|
|
231
236
|
.refs {
|
|
232
237
|
position: relative;
|
|
233
|
-
margin-bottom:
|
|
238
|
+
margin-bottom: 14px; padding: 14px;
|
|
234
239
|
font-size: var(--bc-fs-sm); line-height: 1.45; color: var(--bc-muted);
|
|
235
|
-
background: var(--bc-
|
|
236
|
-
border: 1px solid var(--bc-
|
|
240
|
+
background: var(--bc-subtle);
|
|
241
|
+
border: 1px solid var(--bc-border); border-radius: var(--bc-r-lg);
|
|
237
242
|
animation: bc-item-in 280ms var(--bc-ease) both;
|
|
238
243
|
}
|
|
239
244
|
.refs .ask-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 11px; }
|
|
240
|
-
.refs .ask-head
|
|
241
|
-
.refs .ask-head strong { display: block; font-size: 13.5px; font-weight: 650; color: var(--bc-fg); margin-bottom: 1px; }
|
|
245
|
+
.refs .ask-head strong { display: block; font-size: 13.5px; font-weight: 600; color: var(--bc-fg); margin-bottom: 1px; }
|
|
242
246
|
.refs .why { margin: 0; font-size: var(--bc-fs-sm); line-height: 1.5; color: var(--bc-muted); }
|
|
243
247
|
.refs .row { display: flex; gap: 8px; align-items: stretch; }
|
|
244
|
-
.refs .row input { flex: 1; min-width: 0; background: var(--bc-bg); }
|
|
248
|
+
.refs .row input { flex: 1; min-width: 0; background: var(--bc-bg); border-color: var(--bc-border); }
|
|
245
249
|
.refs select {
|
|
246
250
|
flex: none; max-width: 45%; padding: 10px 10px; font-size: 13px;
|
|
247
251
|
color: var(--bc-fg); background: var(--bc-bg);
|
|
@@ -269,40 +273,44 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
269
273
|
.ref-found svg { width: 14px; height: 14px; flex: none; color: var(--bc-ok); }
|
|
270
274
|
.ref-found b { font-weight: 600; color: var(--bc-fg); }
|
|
271
275
|
|
|
272
|
-
/* ---------- severity ----------
|
|
273
|
-
|
|
276
|
+
/* ---------- severity ----------
|
|
277
|
+
The segmented control from the product: a stone track, the choice lifted out
|
|
278
|
+
of it on white. */
|
|
279
|
+
.seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; padding: 3px; background: var(--bc-stone); border-radius: 999px; }
|
|
274
280
|
.seg button {
|
|
275
281
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
276
|
-
padding:
|
|
277
|
-
color: var(--bc-muted); background: none; border: none; border-radius:
|
|
282
|
+
height: 30px; padding: 0 4px; font: inherit; font-size: var(--bc-fs-sm); font-weight: 520; line-height: 1;
|
|
283
|
+
color: var(--bc-muted); background: none; border: none; border-radius: 999px;
|
|
278
284
|
cursor: pointer; transition: background 180ms var(--bc-ease), color 180ms, box-shadow 180ms;
|
|
279
285
|
}
|
|
280
|
-
.seg button::before { content: ''; width:
|
|
281
|
-
.seg button[data-prio="LOW"] { --sev:
|
|
282
|
-
.seg button[data-prio="MEDIUM"] { --sev:
|
|
283
|
-
.seg button[data-prio="HIGH"] { --sev:
|
|
284
|
-
.seg button[data-prio="CRITICAL"] { --sev:
|
|
286
|
+
.seg button::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--sev, var(--bc-faint)); opacity: .5; transition: opacity 180ms; }
|
|
287
|
+
.seg button[data-prio="LOW"] { --sev: var(--bc-ok); }
|
|
288
|
+
.seg button[data-prio="MEDIUM"] { --sev: var(--bc-info); }
|
|
289
|
+
.seg button[data-prio="HIGH"] { --sev: var(--bc-warn); }
|
|
290
|
+
.seg button[data-prio="CRITICAL"] { --sev: var(--bc-danger); }
|
|
285
291
|
.seg button:hover { color: var(--bc-fg); }
|
|
286
292
|
.seg button[aria-pressed=true] {
|
|
287
|
-
background: var(--bc-raised); color: var(--bc-fg); font-weight:
|
|
288
|
-
box-shadow: 0 1px
|
|
293
|
+
background: var(--bc-raised); color: var(--bc-fg); font-weight: 600;
|
|
294
|
+
box-shadow: 0 1px 2px rgba(20,18,14,.10), 0 0 0 .5px rgba(20,18,14,.08);
|
|
289
295
|
}
|
|
290
296
|
.seg button[aria-pressed=true]::before { opacity: 1; }
|
|
291
297
|
.seg button:focus-visible { outline-offset: -2px; }
|
|
292
298
|
|
|
293
|
-
/* ---------- attachments ----------
|
|
294
|
-
|
|
299
|
+
/* ---------- attachments ----------
|
|
300
|
+
Three ring pills in a row: optional, so they take one line, not a band of
|
|
301
|
+
dashed drop zones. */
|
|
302
|
+
.tools { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
295
303
|
.tool {
|
|
296
|
-
display: inline-flex;
|
|
297
|
-
padding:
|
|
298
|
-
color: var(--bc-fg); background: var(--bc-
|
|
299
|
-
border: 1px
|
|
304
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
305
|
+
height: 32px; padding: 0 11px 0 9px; font: inherit; font-size: 12.5px; font-weight: 520; line-height: 1; white-space: nowrap;
|
|
306
|
+
color: var(--bc-fg); background: var(--bc-bg);
|
|
307
|
+
border: 1px solid var(--bc-border); border-radius: 999px; cursor: pointer;
|
|
300
308
|
transition: border-color 160ms, background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
301
309
|
}
|
|
302
|
-
.tool svg { font-size:
|
|
303
|
-
.tool:hover:not(:disabled) {
|
|
304
|
-
.tool:hover:not(:disabled) svg { color: var(--bc-
|
|
305
|
-
.tool:active:not(:disabled) { transform:
|
|
310
|
+
.tool svg { font-size: 15px; color: var(--bc-muted); transition: color 160ms; }
|
|
311
|
+
.tool:hover:not(:disabled) { background: var(--bc-subtle); border-color: color-mix(in srgb, var(--bc-fg) 20%, var(--bc-border)); }
|
|
312
|
+
.tool:hover:not(:disabled) svg { color: var(--bc-fg); }
|
|
313
|
+
.tool:active:not(:disabled) { transform: scale(.97); }
|
|
306
314
|
.tool:disabled { opacity: .45; cursor: not-allowed; }
|
|
307
315
|
.attach-hint { margin: 8px 0 0; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
308
316
|
|
|
@@ -353,7 +361,7 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
353
361
|
.foot {
|
|
354
362
|
flex: none;
|
|
355
363
|
display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
|
|
356
|
-
padding: 12px var(--bc-pad); border-top: 1px solid var(--bc-border);
|
|
364
|
+
padding: 12px 14px 12px var(--bc-pad); border-top: 1px solid var(--bc-border);
|
|
357
365
|
background: var(--bc-bg);
|
|
358
366
|
}
|
|
359
367
|
.foot .spacer { flex: 1; }
|
|
@@ -366,36 +374,39 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
366
374
|
size, and dimming it on top of that left it as a smudge in both themes. */
|
|
367
375
|
.powered {
|
|
368
376
|
flex: none; display: flex; align-items: center; justify-content: center; gap: 6px;
|
|
369
|
-
padding:
|
|
370
|
-
background: var(--bc-
|
|
377
|
+
padding: 0 var(--bc-pad) 10px; font-size: 10.5px; color: var(--bc-faint);
|
|
378
|
+
background: var(--bc-bg);
|
|
371
379
|
}
|
|
372
380
|
.brand-credit { display: flex; align-items: center; transition: color 0.15s; border-radius: 4px; }
|
|
373
|
-
.bc-brand { height:
|
|
381
|
+
.bc-brand { height: 15px; width: auto; display: block; color: var(--bc-brand-ink); }
|
|
374
382
|
.brand-credit:hover .bc-brand { color: var(--bc-fg); }
|
|
383
|
+
/* The product's two pills: ink for the one thing to do, a white ring for the
|
|
384
|
+
alternative. Flat — no glow, no lift. */
|
|
375
385
|
button.ghost, button.primary {
|
|
376
386
|
display: inline-flex; align-items: center; justify-content: center; gap: 7px;
|
|
377
|
-
height: 38px; padding: 0 15px; font: inherit; font-size:
|
|
387
|
+
height: 38px; padding: 0 15px; font: inherit; font-size: 13.5px; font-weight: 560; line-height: 1;
|
|
378
388
|
border-radius: 999px; cursor: pointer; white-space: nowrap;
|
|
379
389
|
transition: transform 160ms var(--bc-ease), filter 160ms, background 160ms, border-color 160ms, color 160ms, box-shadow 160ms;
|
|
380
390
|
}
|
|
381
|
-
button.ghost { background: var(--bc-bg); border:
|
|
382
|
-
button.ghost:hover:not(:disabled) { background: var(--bc-subtle);
|
|
391
|
+
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); }
|
|
392
|
+
button.ghost:hover:not(:disabled) { background: var(--bc-subtle); }
|
|
383
393
|
button.ghost svg, button.primary svg { font-size: 15px; }
|
|
384
394
|
button.primary {
|
|
385
395
|
padding: 0 18px;
|
|
386
|
-
background: var(--bc-accent); border:
|
|
387
|
-
box-shadow: 0
|
|
396
|
+
background: var(--bc-accent); border: 0; color: var(--bc-on-accent);
|
|
397
|
+
box-shadow: 0 1px 2px rgba(0,0,0,.14);
|
|
388
398
|
}
|
|
389
|
-
button.primary:hover:not(:disabled) {
|
|
390
|
-
button.primary:active:not(:disabled) { transform:
|
|
391
|
-
button:disabled { opacity: .
|
|
399
|
+
button.primary:hover:not(:disabled) { filter: brightness(1.12) contrast(.96); }
|
|
400
|
+
button.primary:active:not(:disabled) { transform: scale(.98); }
|
|
401
|
+
button:disabled { opacity: .45; cursor: not-allowed; }
|
|
392
402
|
button.primary:disabled { box-shadow: none; }
|
|
393
|
-
button.primary .spinner { border-color:
|
|
403
|
+
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; }
|
|
394
404
|
button.quiet {
|
|
395
|
-
padding: 0 4px; height: 38px; font: inherit; font-size: 13px; font-weight:
|
|
405
|
+
padding: 0 4px; height: 38px; font: inherit; font-size: 13px; font-weight: 520;
|
|
396
406
|
border: none; background: none; color: var(--bc-muted); cursor: pointer; border-radius: 8px;
|
|
407
|
+
text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px;
|
|
397
408
|
}
|
|
398
|
-
button.quiet:hover { color: var(--bc-
|
|
409
|
+
button.quiet:hover { color: var(--bc-fg); text-decoration-color: color-mix(in srgb, var(--bc-fg) 35%, transparent); }
|
|
399
410
|
|
|
400
411
|
/* ---------- your reports ---------- */
|
|
401
412
|
.history {
|
|
@@ -415,13 +426,13 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
415
426
|
.history .row:last-child { border-bottom: 0; }
|
|
416
427
|
.history .who { flex: 1; min-width: 0; }
|
|
417
428
|
.history .ttl {
|
|
418
|
-
display: block; font-size: 13.5px; font-weight:
|
|
429
|
+
display: block; font-size: 13.5px; font-weight: 560; color: var(--bc-fg);
|
|
419
430
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
420
431
|
}
|
|
421
432
|
.history .sub { display: block; margin-top: 3px; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
422
433
|
.history .row-ico {
|
|
423
434
|
flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
|
|
424
|
-
background: var(--bc-
|
|
435
|
+
background: var(--bc-stone); color: var(--bc-muted); font-size: 16px;
|
|
425
436
|
}
|
|
426
437
|
.history .chev { flex: none; color: var(--bc-faint); font-size: 15px; transition: transform 160ms var(--bc-ease), color 160ms; }
|
|
427
438
|
.empty {
|
|
@@ -430,7 +441,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
430
441
|
}
|
|
431
442
|
.empty .empty-ico {
|
|
432
443
|
display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
|
|
433
|
-
background: var(--bc-
|
|
444
|
+
background: var(--bc-stone); color: var(--bc-fg); font-size: 20px;
|
|
434
445
|
}
|
|
435
446
|
.skel {
|
|
436
447
|
display: block; height: 12px; border-radius: 6px; margin: 6px 0;
|
|
@@ -446,7 +457,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
446
457
|
animation: bc-rise 260ms var(--bc-ease) both;
|
|
447
458
|
}
|
|
448
459
|
.history button.row:hover { background: var(--bc-subtle); }
|
|
449
|
-
.history button.row:hover .chev { transform: translateX(2px); color: var(--bc-
|
|
460
|
+
.history button.row:hover .chev { transform: translateX(2px); color: var(--bc-fg); }
|
|
450
461
|
.history button.row:focus-visible { outline-offset: -2px; }
|
|
451
462
|
|
|
452
463
|
/* ---------- one report, and what happened to it ---------- */
|
|
@@ -456,7 +467,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
456
467
|
padding: 10px var(--bc-pad); border-bottom: 1px solid var(--bc-border);
|
|
457
468
|
background: var(--bc-bg);
|
|
458
469
|
}
|
|
459
|
-
.report-head .ttl { font-size:
|
|
470
|
+
.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; }
|
|
460
471
|
.report-head .sub { font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
461
472
|
.report-head .pill { grid-row: 1 / span 2; grid-column: 2; align-self: center; }
|
|
462
473
|
|
|
@@ -490,9 +501,9 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
490
501
|
border-radius: 50%; background: var(--bc-muted); vertical-align: middle;
|
|
491
502
|
}
|
|
492
503
|
.sys .t { color: var(--bc-faint); }
|
|
493
|
-
.sys.k-status .dot { background:
|
|
494
|
-
.sys.k-severity .dot { background:
|
|
495
|
-
.sys.k-assignment .dot { background:
|
|
504
|
+
.sys.k-status .dot { background: var(--bc-info); }
|
|
505
|
+
.sys.k-severity .dot { background: var(--bc-warn); }
|
|
506
|
+
.sys.k-assignment .dot { background: var(--bc-brand-mark); }
|
|
496
507
|
.sys.k-filed .dot { background: var(--bc-faint); }
|
|
497
508
|
|
|
498
509
|
/* ---------- the conversation ----------
|
|
@@ -525,24 +536,21 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
525
536
|
.msg-row.mine > * { grid-column: 1; }
|
|
526
537
|
.av {
|
|
527
538
|
display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
|
|
528
|
-
font-size: 11px; font-weight:
|
|
529
|
-
background:
|
|
530
|
-
}
|
|
531
|
-
.av.bot {
|
|
532
|
-
background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
|
|
533
|
-
color: var(--bc-on-accent); font-size: 14px;
|
|
539
|
+
font-size: 11px; font-weight: 650; letter-spacing: .02em;
|
|
540
|
+
background: var(--bc-stone); color: var(--bc-fg);
|
|
534
541
|
}
|
|
535
|
-
.
|
|
536
|
-
.msg-who
|
|
542
|
+
.av.bot { width: 28px; }
|
|
543
|
+
.msg-who { font-size: var(--bc-fs-xs); font-weight: 560; color: var(--bc-muted); padding: 0 4px 4px; }
|
|
544
|
+
.msg-who.auto { color: var(--bc-fg); display: inline-flex; align-items: center; gap: 5px; }
|
|
537
545
|
.msg-who .tag {
|
|
538
|
-
padding: 1px 6px; border-radius: 999px; font-size: 9.5px; font-weight:
|
|
539
|
-
text-transform: uppercase; background: var(--bc-
|
|
546
|
+
padding: 1px 6px; border-radius: 999px; font-size: 9.5px; font-weight: 650; letter-spacing: .05em;
|
|
547
|
+
text-transform: uppercase; background: var(--bc-stone); color: var(--bc-muted);
|
|
540
548
|
}
|
|
541
549
|
.bubble {
|
|
542
550
|
justify-self: start; max-width: 100%;
|
|
543
551
|
padding: 9px 13px; border-radius: 18px; font-size: 13.5px; line-height: 1.5;
|
|
544
|
-
background: var(--bc-
|
|
545
|
-
border: 1px solid
|
|
552
|
+
background: var(--bc-stone); color: var(--bc-fg);
|
|
553
|
+
border: 1px solid transparent;
|
|
546
554
|
border-bottom-left-radius: 6px;
|
|
547
555
|
}
|
|
548
556
|
/* pre-wrap belongs to the text, not the box — on the box it would also render
|
|
@@ -555,9 +563,10 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
555
563
|
}
|
|
556
564
|
.msg-row.cont.theirs .bubble { border-top-left-radius: 6px; }
|
|
557
565
|
.msg-row.cont.mine .bubble { border-top-right-radius: 6px; }
|
|
558
|
-
/* A reply nobody wrote:
|
|
559
|
-
it, so it reads the same to someone who cannot
|
|
560
|
-
|
|
566
|
+
/* A reply nobody wrote: drawn on white with a hairline, beside the orb and
|
|
567
|
+
labelled "Assistant" above it, so it reads the same to someone who cannot
|
|
568
|
+
see the difference at all. */
|
|
569
|
+
.msg-row.auto .bubble { background: var(--bc-bg); border-color: var(--bc-border); }
|
|
561
570
|
/* An attachment-only message has no text to wrap, so the bubble would be an
|
|
562
571
|
empty coloured box around it. */
|
|
563
572
|
.bubble.silent { padding: 0; background: none !important; border: 0; }
|
|
@@ -571,7 +580,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
571
580
|
/* The assistant, thinking. Three dots in a bubble where its next message will be. */
|
|
572
581
|
.typing { display: inline-flex; align-items: center; gap: 4px; padding: 12px 14px; justify-self: start; }
|
|
573
582
|
.typing i {
|
|
574
|
-
width:
|
|
583
|
+
width: 6px; height: 6px; border-radius: 50%; background: var(--bc-muted); opacity: .45;
|
|
575
584
|
animation: bc-typing 1.2s ease-in-out infinite;
|
|
576
585
|
}
|
|
577
586
|
.typing i:nth-child(2) { animation-delay: .15s; }
|
|
@@ -607,30 +616,29 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
607
616
|
background: var(--bc-subtle);
|
|
608
617
|
transition: background 400ms ease, border-color 400ms ease;
|
|
609
618
|
}
|
|
610
|
-
.assistant.
|
|
611
|
-
background: var(--bc-accent-soft); border-color: var(--bc-accent-line);
|
|
612
|
-
}
|
|
613
|
-
.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)); }
|
|
619
|
+
.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)); }
|
|
614
620
|
/* On a call: the call's own card is what they are watching. This one states
|
|
615
|
-
what is happening and stops moving — no
|
|
621
|
+
what is happening and stops moving — no breathing orb, no travelling bar. */
|
|
616
622
|
.assistant.calling { background: var(--bc-bg); }
|
|
617
623
|
.assistant.calling .as-progress i { transition: none; }
|
|
618
624
|
.as-body.entering { animation: bc-rise 360ms var(--bc-ease) both; }
|
|
619
625
|
.as-top { display: flex; gap: 11px; align-items: center; }
|
|
626
|
+
/* The orb, while the assistant is at work; a plain disc with a glyph once it
|
|
627
|
+
is on a call or has finished. */
|
|
620
628
|
.as-orb {
|
|
621
629
|
flex: none; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
|
|
622
|
-
color: var(--bc-on-accent); font-size: 15px;
|
|
623
|
-
background: linear-gradient(140deg, var(--bc-accent), color-mix(in srgb, var(--bc-accent) 60%, #fff));
|
|
630
|
+
color: var(--bc-on-accent); font-size: 15px; background: var(--bc-accent);
|
|
624
631
|
}
|
|
625
|
-
.
|
|
626
|
-
.assistant.
|
|
627
|
-
|
|
628
|
-
|
|
632
|
+
.as-orb.orb { background: var(--bc-o2); }
|
|
633
|
+
.assistant.analyzing .as-orb.orb { animation: as-breathe 2.4s ease-in-out infinite; }
|
|
634
|
+
@keyframes as-breathe { 50% { transform: scale(.88); } }
|
|
635
|
+
.assistant.resolved .as-orb { background: var(--bc-ok); color: #fff; }
|
|
636
|
+
.assistant.reviewing .as-orb.orb { filter: saturate(.35); }
|
|
629
637
|
.as-text { min-width: 0; flex: 1; }
|
|
630
|
-
.as-title { font-weight:
|
|
638
|
+
.as-title { font-weight: 600; font-size: 13.5px; letter-spacing: -.01em; color: var(--bc-fg); }
|
|
631
639
|
.as-detail { font-size: 12px; line-height: 1.45; color: var(--bc-muted); margin-top: 2px; }
|
|
632
640
|
.as-progress {
|
|
633
|
-
height:
|
|
641
|
+
height: 3px; margin: 12px 0 0; border-radius: 999px; overflow: hidden;
|
|
634
642
|
background: color-mix(in srgb, var(--bc-fg) 9%, transparent);
|
|
635
643
|
}
|
|
636
644
|
.as-progress i {
|
|
@@ -639,39 +647,42 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
639
647
|
}
|
|
640
648
|
.assistant.resolved .as-progress i { background: var(--bc-ok); }
|
|
641
649
|
.assistant.analyzing .as-progress i {
|
|
642
|
-
background: linear-gradient(90deg, var(--bc-accent) 0%, color-mix(in srgb, var(--bc-accent)
|
|
650
|
+
background: linear-gradient(90deg, var(--bc-accent) 0%, color-mix(in srgb, var(--bc-accent) 35%, var(--bc-bg)) 50%, var(--bc-accent) 100%);
|
|
643
651
|
background-size: 200% 100%; animation: bc-shimmer 1.6s linear infinite;
|
|
644
652
|
}
|
|
653
|
+
/* Four short labels under the bar. Allowed to wrap rather than be cut: at this
|
|
654
|
+
width "Report received" ellipsised to "Report recei…". */
|
|
645
655
|
.as-steps {
|
|
646
|
-
list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
|
|
647
|
-
margin: 8px 0 0; padding: 0; font-size: 10.5px; color: var(--bc-faint);
|
|
656
|
+
list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px 6px;
|
|
657
|
+
margin: 8px 0 0; padding: 0; font-size: 10.5px; line-height: 1.3; color: var(--bc-faint);
|
|
648
658
|
}
|
|
649
|
-
.as-steps li { display: flex; align-items:
|
|
650
|
-
.as-steps li .lbl { min-width: 0; overflow
|
|
651
|
-
.as-steps li .dot { flex: none; width:
|
|
659
|
+
.as-steps li { display: flex; align-items: flex-start; gap: 5px; min-width: 0; }
|
|
660
|
+
.as-steps li .lbl { min-width: 0; overflow-wrap: anywhere; }
|
|
661
|
+
.as-steps li .dot { flex: none; width: 7px; height: 7px; margin-top: 3px; border-radius: 50%; border: 1.5px solid currentColor; }
|
|
652
662
|
.as-steps li.done { color: var(--bc-muted); }
|
|
653
663
|
.as-steps li.done .dot { background: var(--bc-accent); border-color: var(--bc-accent); }
|
|
654
664
|
.assistant.resolved .as-steps li.done .dot { background: var(--bc-ok); border-color: var(--bc-ok); }
|
|
655
|
-
.as-steps li.active { color: var(--bc-fg); font-weight:
|
|
665
|
+
.as-steps li.active { color: var(--bc-fg); font-weight: 600; }
|
|
656
666
|
.as-steps li.active .dot { border-color: var(--bc-accent); background: var(--bc-bg); animation: as-pulse 1.2s ease-in-out infinite; }
|
|
657
|
-
@keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent)
|
|
658
|
-
@media (prefers-reduced-motion: reduce) { .as-
|
|
667
|
+
@keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent) 18%, transparent); } }
|
|
668
|
+
@media (prefers-reduced-motion: reduce) { .as-orb, .as-steps li.active .dot, .assistant.analyzing .as-progress i, .typing i { animation: none; } }
|
|
659
669
|
|
|
660
670
|
/* Quick answers under the confirm question — only on the latest message. */
|
|
661
671
|
.msg-row .quick { display: none; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
|
|
662
672
|
.msg-row:last-child .quick { display: flex; }
|
|
663
673
|
.quick button {
|
|
664
674
|
display: inline-flex; align-items: center; gap: 6px;
|
|
665
|
-
font: inherit; font-size: 13px; font-weight:
|
|
666
|
-
border:
|
|
675
|
+
font: inherit; font-size: 13px; font-weight: 560; height: 34px; padding: 0 14px; border-radius: 999px; cursor: pointer;
|
|
676
|
+
border: 0; background: var(--bc-bg); color: var(--bc-fg); box-shadow: 0 0 0 1px var(--bc-border);
|
|
667
677
|
transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
668
678
|
animation: bc-item-in 300ms var(--bc-ease) both;
|
|
669
679
|
}
|
|
670
|
-
.quick button:first-child { background: var(--bc-accent); color: var(--bc-on-accent); }
|
|
680
|
+
.quick button:first-child { background: var(--bc-accent); color: var(--bc-on-accent); box-shadow: none; }
|
|
671
681
|
.quick button:nth-child(2) { animation-delay: 60ms; }
|
|
672
682
|
.quick button svg { font-size: 13px; }
|
|
673
|
-
.quick button:hover {
|
|
674
|
-
.quick button:first-child:hover { background: var(--bc-accent); filter: brightness(1.
|
|
683
|
+
.quick button:hover { background: var(--bc-subtle); }
|
|
684
|
+
.quick button:first-child:hover { background: var(--bc-accent); filter: brightness(1.12) contrast(.96); }
|
|
685
|
+
.quick button:active { transform: scale(.97); }
|
|
675
686
|
|
|
676
687
|
/* ---------- the composer ---------- */
|
|
677
688
|
.composer {
|
|
@@ -688,10 +699,10 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
688
699
|
.composer .row {
|
|
689
700
|
display: flex; align-items: flex-end; gap: 4px;
|
|
690
701
|
padding: 5px; border-radius: 22px;
|
|
691
|
-
background: var(--bc-
|
|
692
|
-
transition: border-color 160ms, box-shadow 160ms;
|
|
702
|
+
background: var(--bc-stone); border: 1px solid transparent;
|
|
703
|
+
transition: border-color 160ms, box-shadow 160ms, background 160ms;
|
|
693
704
|
}
|
|
694
|
-
.composer .row:focus-within { border-color: var(--bc-accent); box-shadow: var(--bc-ring); }
|
|
705
|
+
.composer .row:focus-within { background: var(--bc-bg); border-color: var(--bc-accent); box-shadow: var(--bc-ring); }
|
|
695
706
|
.composer textarea {
|
|
696
707
|
flex: 1; min-width: 0; min-height: 34px; max-height: 120px; resize: none; padding: 7px 6px;
|
|
697
708
|
font: inherit; font-size: 13.5px; line-height: 1.45;
|
|
@@ -716,8 +727,8 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
716
727
|
display: grid; place-items: center;
|
|
717
728
|
transition: transform 160ms var(--bc-ease), opacity 160ms, filter 160ms;
|
|
718
729
|
}
|
|
719
|
-
.composer .send:hover:not(:disabled) { filter: brightness(1.
|
|
720
|
-
.composer .send:disabled { opacity: .
|
|
730
|
+
.composer .send:hover:not(:disabled) { filter: brightness(1.12) contrast(.96); transform: scale(1.04); }
|
|
731
|
+
.composer .send:disabled { opacity: .3; cursor: default; background: var(--bc-faint); }
|
|
721
732
|
.composer .staged { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 8px; }
|
|
722
733
|
.composer .chip {
|
|
723
734
|
display: flex; align-items: center; gap: 6px; max-width: 200px;
|
|
@@ -740,23 +751,16 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
740
751
|
lands on — which is what someone opening this screen came to check. */
|
|
741
752
|
.pill {
|
|
742
753
|
flex: none; display: inline-flex; align-items: center; gap: 5px;
|
|
743
|
-
font-size: 11px; font-weight:
|
|
754
|
+
font-size: 11px; font-weight: 600;
|
|
744
755
|
padding: 3px 9px; border-radius: 999px;
|
|
745
|
-
color: var(--bc-muted); background: var(--bc-
|
|
756
|
+
color: var(--bc-muted); background: var(--bc-stone);
|
|
746
757
|
}
|
|
747
758
|
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
|
748
|
-
|
|
749
|
-
.pill.
|
|
750
|
-
.pill.
|
|
759
|
+
/* The theme's own status colours, which already have a dark cut. */
|
|
760
|
+
.pill.open { color: var(--bc-warn); background: color-mix(in srgb, var(--bc-warn) 12%, var(--bc-bg)); }
|
|
761
|
+
.pill.in_progress { color: var(--bc-info); background: color-mix(in srgb, var(--bc-info) 12%, var(--bc-bg)); }
|
|
762
|
+
.pill.resolved { color: var(--bc-ok); background: color-mix(in srgb, var(--bc-ok) 12%, var(--bc-bg)); }
|
|
751
763
|
.pill.closed { color: var(--bc-muted); }
|
|
752
|
-
:host(.bc-dark) .pill.open { color: #fbbf24; }
|
|
753
|
-
:host(.bc-dark) .pill.in_progress { color: #7cb8ff; }
|
|
754
|
-
:host(.bc-dark) .pill.resolved { color: #4ade9a; }
|
|
755
|
-
@media (prefers-color-scheme: dark) {
|
|
756
|
-
:host(.bc-auto) .pill.open { color: #fbbf24; }
|
|
757
|
-
:host(.bc-auto) .pill.in_progress { color: #7cb8ff; }
|
|
758
|
-
:host(.bc-auto) .pill.resolved { color: #4ade9a; }
|
|
759
|
-
}
|
|
760
764
|
|
|
761
765
|
/* ---------- does the fix work ---------- */
|
|
762
766
|
.fix-verification {
|
|
@@ -776,6 +780,47 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
776
780
|
.fix-verification .feedback-status { margin: 6px 0 0; font-weight: 450; color: var(--bc-danger); font-size: var(--bc-fs-xs); }
|
|
777
781
|
.fix-verification .feedback-status:empty { display: none; }
|
|
778
782
|
|
|
783
|
+
/* ---------- how did we do ----------
|
|
784
|
+
Quieter than the card above it: that one asks whether the fix works, which
|
|
785
|
+
the team acts on; this asks how it felt, which they learn from. The stars
|
|
786
|
+
carry the only colour, so the one thing to do here is the thing you see. */
|
|
787
|
+
.fix-rating {
|
|
788
|
+
--bc-star: #f0a81c;
|
|
789
|
+
flex: none; margin: 10px 12px 0; padding: 12px 14px;
|
|
790
|
+
border-radius: var(--bc-r-lg); border: 1px solid var(--bc-border); background: var(--bc-bg);
|
|
791
|
+
font-size: var(--bc-fs-sm); color: var(--bc-fg);
|
|
792
|
+
animation: bc-rise 280ms var(--bc-ease) both;
|
|
793
|
+
}
|
|
794
|
+
.fix-rating .fr-q { margin: 0 0 6px; font-weight: 620; }
|
|
795
|
+
.fix-rating .stars { display: flex; gap: 2px; margin: 0 0 2px -4px; }
|
|
796
|
+
.fix-rating .stars button {
|
|
797
|
+
display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0;
|
|
798
|
+
border: 0; border-radius: 8px; background: transparent; cursor: pointer;
|
|
799
|
+
color: color-mix(in srgb, var(--bc-fg) 18%, transparent);
|
|
800
|
+
transition: color 120ms ease, transform 120ms var(--bc-ease);
|
|
801
|
+
}
|
|
802
|
+
.fix-rating .stars button svg { width: 24px; height: 24px; }
|
|
803
|
+
.fix-rating .stars button.on { color: var(--bc-star); }
|
|
804
|
+
.fix-rating .stars button:hover:not(:disabled) { transform: scale(1.08); }
|
|
805
|
+
.fix-rating .stars button:focus-visible { outline: none; box-shadow: var(--bc-ring); }
|
|
806
|
+
.fix-rating .stars button:disabled { cursor: default; }
|
|
807
|
+
.fix-rating .fr-hint { margin: 2px 0 0; font-size: var(--bc-fs-xs); color: var(--bc-faint); }
|
|
808
|
+
.fix-rating .fr-said { margin: 6px 0 0; font-size: 13px; color: var(--bc-muted); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
809
|
+
.fix-rating .fr-note { margin-top: 8px; }
|
|
810
|
+
.fix-rating .fr-note textarea { min-height: 52px; margin-bottom: 8px; font-size: 13px; }
|
|
811
|
+
.fix-rating .fr-note button {
|
|
812
|
+
padding: 7px 13px; font: inherit; font-size: 12.5px; font-weight: 620; border-radius: 999px; cursor: pointer;
|
|
813
|
+
border: 1px solid var(--bc-border); background: var(--bc-bg); color: var(--bc-fg);
|
|
814
|
+
}
|
|
815
|
+
.fix-rating .feedback-status { margin: 6px 0 0; color: var(--bc-danger); font-size: var(--bc-fs-xs); }
|
|
816
|
+
.fix-rating .feedback-status:empty { display: none; }
|
|
817
|
+
@media (prefers-reduced-motion: reduce) { .fix-rating .stars button { transition: none; } .fix-rating .stars button:hover { transform: none; } }
|
|
818
|
+
|
|
819
|
+
/* The rating on a history row: the score given, or a nudge to give one. */
|
|
820
|
+
.history .sub .rated { display: inline-flex; align-items: center; gap: 2px; color: var(--bc-muted); font-weight: 600; }
|
|
821
|
+
.history .sub .rated svg { width: 11px; height: 11px; color: #f0a81c; }
|
|
822
|
+
.history .sub .rate-ask { color: var(--bc-fg); font-weight: 600; }
|
|
823
|
+
|
|
779
824
|
/* A call in progress, in place of the form.
|
|
780
825
|
---------------------------------------------------------------------------
|
|
781
826
|
Deliberately not styled as a chat. Nothing arrives here to read — the
|
|
@@ -825,13 +870,13 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
825
870
|
and this screen's padding was landing on every one of them. */
|
|
826
871
|
div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 240ms ease both; }
|
|
827
872
|
.done .tick {
|
|
828
|
-
width:
|
|
829
|
-
display: grid; place-items: center; font-size:
|
|
830
|
-
background:
|
|
831
|
-
box-shadow: 0 0 0
|
|
873
|
+
width: 52px; height: 52px; margin: 0 auto 16px; border-radius: 50%;
|
|
874
|
+
display: grid; place-items: center; font-size: 24px;
|
|
875
|
+
background: var(--bc-ok); color: #fff;
|
|
876
|
+
box-shadow: 0 0 0 7px color-mix(in srgb, var(--bc-ok) 12%, transparent);
|
|
832
877
|
animation: bc-pop 420ms var(--bc-ease) both;
|
|
833
878
|
}
|
|
834
|
-
.done h3 { margin: 0 0 6px; font-size:
|
|
879
|
+
.done h3 { margin: 0 0 6px; font-size: 18px; font-weight: 600; letter-spacing: -.02em; }
|
|
835
880
|
.done p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--bc-muted); }
|
|
836
881
|
.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); }
|
|
837
882
|
/* The likely wait. Set apart from the reference line above it by a rule rather
|
|
@@ -895,7 +940,7 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
895
940
|
is open — the sheet has its own close button, and a launcher floating over
|
|
896
941
|
the send button would be in the way of the one thing that matters. */
|
|
897
942
|
@media (max-width: 480px) {
|
|
898
|
-
.scrim { background: rgba(
|
|
943
|
+
.scrim { background: rgba(14,14,16,.4); }
|
|
899
944
|
.panel, .scrim.at-right .panel, .scrim.at-left .panel, .scrim.at-bottom .panel, .scrim.at-top .panel {
|
|
900
945
|
inset: 0; width: 100%; max-width: none; height: 100%; max-height: none;
|
|
901
946
|
border-radius: 0; border: 0;
|
|
@@ -910,6 +955,16 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
910
955
|
.foot:has(+ .powered) { padding-bottom: 12px; }
|
|
911
956
|
.recbar .hint { display: none; }
|
|
912
957
|
.msg-row, .typing-row { max-width: 92%; }
|
|
958
|
+
/* The question chips are one row that scrolls sideways, edge to edge, rather
|
|
959
|
+
than three stacked rows pushing the form down the screen. */
|
|
960
|
+
.picks .picks-grid {
|
|
961
|
+
flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
|
|
962
|
+
margin: 0 calc(var(--bc-pad) * -1); padding: 0 var(--bc-pad) 2px;
|
|
963
|
+
scroll-snap-type: x proximity; scroll-padding: 0 var(--bc-pad);
|
|
964
|
+
}
|
|
965
|
+
.picks .picks-grid::-webkit-scrollbar { display: none; }
|
|
966
|
+
.picks .pick { flex: none; scroll-snap-align: start; }
|
|
967
|
+
.picks .pick .t { white-space: nowrap; }
|
|
913
968
|
}
|
|
914
969
|
|
|
915
970
|
@media (pointer: coarse) {
|
|
@@ -924,7 +979,8 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
924
979
|
under it, on the one surface in the product designed for someone who is
|
|
925
980
|
not an operator and gets no second attempt. */
|
|
926
981
|
.seg button { min-height: 44px; }
|
|
927
|
-
.tool { min-height:
|
|
982
|
+
.tool, .known .issue .join { min-height: 44px; }
|
|
983
|
+
.picks .pick { min-height: 40px; }
|
|
928
984
|
button.primary, button.ghost { height: 44px; }
|
|
929
985
|
.composer .send, .composer .tool { width: 40px; height: 40px; min-height: 0; }
|
|
930
986
|
textarea { min-height: 104px; }
|
|
@@ -933,7 +989,7 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
933
989
|
/* The close button and the thumbnails' remove buttons are small glyphs whose
|
|
934
990
|
boxes cannot grow without moving what is beside them, so each keeps its
|
|
935
991
|
size and gets an invisible target drawn around it instead. The theme
|
|
936
|
-
|
|
992
|
+
button in the header is one of these. */
|
|
937
993
|
.head .icon-btn, .thumb .drop, .brand-credit { position: relative; }
|
|
938
994
|
.thumb .drop { position: absolute; opacity: 1; }
|
|
939
995
|
.head .icon-btn::after, .thumb .drop::after, .brand-credit::after {
|
|
@@ -947,26 +1003,28 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
947
1003
|
@media (hover: none) {
|
|
948
1004
|
.tool:hover:not(:disabled) { transform: none; }
|
|
949
1005
|
}
|
|
950
|
-
`;function
|
|
1006
|
+
`;function re({title:e,sub:t,id:a="",back:h=!1,theme:i=""}){return`
|
|
951
1007
|
<div class="head">
|
|
952
|
-
${
|
|
953
|
-
<
|
|
1008
|
+
${h?`<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${Be}</button>`:""}
|
|
1009
|
+
<span class="orb mark" aria-hidden="true"></span>
|
|
954
1010
|
<div class="titles">
|
|
955
|
-
<h2${a?` id="${a}"`:""}>${
|
|
956
|
-
<p>${
|
|
1011
|
+
<h2${a?` id="${a}"`:""}>${$(e)}</h2>
|
|
1012
|
+
<p>${$(t)}</p>
|
|
957
1013
|
</div>
|
|
958
|
-
|
|
959
|
-
|
|
1014
|
+
${i?`<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${$(i)}"
|
|
1015
|
+
aria-label="Theme: ${$(i)}. Change theme"><span class="m-light">${Ie}</span><span class="m-dark">${Re}</span><span class="m-auto">${Ae}</span></button>`:""}
|
|
1016
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${X}</button>
|
|
1017
|
+
</div>`}function ie(e,t){return`<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${$(e)}</div>`}function _e(e){return Array.from({length:e},()=>`
|
|
960
1018
|
<div class="row" aria-hidden="true">
|
|
961
1019
|
<span class="row-ico"></span>
|
|
962
1020
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
963
|
-
</div>`).join("")+'<span class="sr-only">Loading…</span>'}function
|
|
1021
|
+
</div>`).join("")+'<span class="sr-only">Loading…</span>'}function Ke(){return`
|
|
964
1022
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
965
1023
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
966
1024
|
<span class="skel" style="width:66%;height:52px;border-radius:18px"></span>
|
|
967
1025
|
<span class="skel" style="width:48%;height:38px;border-radius:18px;align-self:flex-end"></span>
|
|
968
1026
|
</div>
|
|
969
|
-
<span class="sr-only">Loading…</span>`}function
|
|
1027
|
+
<span class="sr-only">Loading…</span>`}function Ue(e){const t=String(e).trim().split(/\s+/).filter(Boolean);return t.length?(t[0][0]+(t.length>1?t[t.length-1][0]:"")).toUpperCase():"?"}function K(e){const t=new Date(e);return Number.isFinite(t.getTime())?`${t.getFullYear()}-${t.getMonth()}-${t.getDate()}`:null}function Ze(e){const t=new Date(e),a=new Date,h=new Date(a.getFullYear(),a.getMonth(),a.getDate()-1);if(K(t)===K(a))return"Today";if(K(t)===K(h))return"Yesterday";try{return t.toLocaleDateString(void 0,{weekday:"short",day:"numeric",month:"short",...t.getFullYear()!==a.getFullYear()?{year:"numeric"}:{}})}catch{return ee(e)}}function ge(e){const t=new Date(e);if(!Number.isFinite(t.getTime()))return"";try{return t.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"})}catch{return""}}function me(e){return e.scrollHeight-e.scrollTop-e.clientHeight<40}function U(e,{smooth:t=!1}={}){const a=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches;t&&!a&&e.scrollTo?e.scrollTo({top:e.scrollHeight,behavior:"smooth"}):e.scrollTop=e.scrollHeight}function se(e){return{OPEN:"Open",IN_PROGRESS:"In progress",RESOLVED:"Fixed",CLOSED:"Closed"}[e]||String(e||"").toLowerCase()}function ee(e){const t=new Date(e).getTime();if(!Number.isFinite(t))return"";const a=Math.floor((Date.now()-t)/864e5);if(a<=0)return"today";if(a===1)return"yesterday";if(a<30)return`${a} days ago`;const h=Math.floor(a/30);return h===1?"a month ago":`${h} months ago`}function $(e){return String(e).replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}typeof window<"u"&&window.fetch&&window.fetch.bind(window);const ve=["image/png","image/jpeg","image/webp","image/gif","video/webm","video/mp4","audio/webm","audio/ogg","audio/mpeg","audio/mp4","audio/wav","application/pdf","text/plain","text/csv","application/json","application/zip","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],xe=["image/png","image/jpeg","image/webp","video/webm","video/mp4"],Ge=()=>{var e;return!!((e=navigator==null?void 0:navigator.mediaDevices)!=null&&e.getUserMedia&&typeof MediaRecorder<"u")},Xe=()=>{var e;return!!((e=navigator==null?void 0:navigator.mediaDevices)!=null&&e.getDisplayMedia&&typeof MediaRecorder<"u")},Je=()=>{var e;return!!((e=navigator==null?void 0:navigator.mediaDevices)!=null&&e.getDisplayMedia)};function et(e,t=ve){const a=String(e||"").split(";")[0].trim().toLowerCase();return t.includes(a)?a:null}async function tt(){const e=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:1},audio:!1});try{const t=e.getVideoTracks()[0],a=document.createElement("video");a.srcObject=e,a.muted=!0,a.playsInline=!0,await a.play(),await new Promise(s=>requestAnimationFrame(()=>requestAnimationFrame(s)));const{width:h,height:i}=t.getSettings(),v=document.createElement("canvas");v.width=h||a.videoWidth,v.height=i||a.videoHeight,v.getContext("2d").drawImage(a,0,0,v.width,v.height);const x=await new Promise(s=>v.toBlob(s,"image/png"));if(!x)throw new Error("The browser returned an empty screenshot.");return{blob:x,mime:"image/png",kind:"SCREENSHOT"}}finally{e.getTracks().forEach(t=>t.stop())}}async function at({maxMs:e=12e4,onTick:t,onAutoStop:a}={}){const h=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1}),i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"].find(l=>MediaRecorder.isTypeSupported(l))||"video/webm",v=new MediaRecorder(h,{mimeType:i,videoBitsPerSecond:25e5}),x=[];v.ondataavailable=l=>{l.data.size&&x.push(l.data)},v.start(1e3);const s=Date.now(),y=setInterval(()=>t==null?void 0:t(Math.floor((Date.now()-s)/1e3)),500),p=()=>{clearInterval(y),clearTimeout(r),h.getTracks().forEach(l=>l.stop())},b=new Promise(l=>{v.onstop=()=>{p(),l(new Blob(x,{type:i}))}}),E=()=>{v.state!=="inactive"&&v.stop(),a==null||a()};h.getVideoTracks()[0].addEventListener("ended",E);const r=setTimeout(E,e);return{mime:i,maxMs:e,async stop(){return clearTimeout(r),v.state!=="inactive"&&v.stop(),{blob:await b,mime:i,kind:"VIDEO"}},cancel(){p(),v.state!=="inactive"&&v.stop()}}}async function nt({maxMs:e=12e4,onTick:t,onAutoStop:a}={}){const h=await navigator.mediaDevices.getUserMedia({audio:!0}),i=["audio/webm;codecs=opus","audio/webm","audio/mp4","audio/ogg"].find(l=>MediaRecorder.isTypeSupported(l))||"",v=new MediaRecorder(h,i?{mimeType:i}:void 0),x=[];v.ondataavailable=l=>{l.data.size&&x.push(l.data)},v.start(1e3);const s=Date.now(),y=setInterval(()=>t==null?void 0:t(Math.floor((Date.now()-s)/1e3)),500),p=()=>{clearInterval(y),clearTimeout(r),h.getTracks().forEach(l=>l.stop())},b=new Promise(l=>{v.onstop=()=>{p(),l(new Blob(x,{type:v.mimeType||i}))}}),r=setTimeout(()=>{v.state!=="inactive"&&v.stop(),a==null||a()},e);return{mime:v.mimeType||i,maxMs:e,async stop(){clearTimeout(r),v.state!=="inactive"&&v.stop();const l=await b;return{blob:l,mime:l.type||v.mimeType||i,kind:"AUDIO"}},cancel(){p(),v.state!=="inactive"&&v.stop()}}}function _(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function te(e){const t=Math.floor(e/60),a=e%60;return`${t}:${String(a).padStart(2,"0")}`}const ot=7*24*60*60*1e3;let ae;function rt(){return ae||(ae=new Promise((e,t)=>{const a=indexedDB.open("bugcatch-drafts",1);a.onupgradeneeded=()=>a.result.createObjectStore("drafts"),a.onsuccess=()=>e(a.result),a.onerror=()=>t(a.error),a.onblocked=()=>t(new Error("Draft storage is blocked."))}).catch(e=>{throw ae=null,e})),ae}function it(e,t){var a,h;return JSON.stringify([e.apiBase,e.projectId,t||((a=e.user)==null?void 0:a.email)||((h=e.user)==null?void 0:h.id)||"anonymous"])}async function ne(e,t){const a=await rt();return new Promise((h,i)=>{const v=a.transaction("drafts",t===void 0?"readonly":"readwrite"),x=v.objectStore("drafts"),s=t===void 0?x.get(e):t===null?x.delete(e):x.put({...t,savedAt:Date.now()},e);v.oncomplete=()=>h(s.result),v.onerror=()=>i(v.error),v.onabort=()=>i(v.error||new Error("Draft was not saved."))})}async function st(e){const t=await ne(e);return t&&Date.now()-t.savedAt>ot?(await ne(e,null),null):t||null}const ye=[{value:"LOW",label:"Low"},{value:"MEDIUM",label:"Medium"},{value:"HIGH",label:"High"},{value:"CRITICAL",label:"Critical"}],we="MEDIUM";function lt(e){const t=e.attachments!==!1,a=t&&Je(),h=t&&Xe();return`
|
|
970
1028
|
<div class="compose">
|
|
971
1029
|
<div class="field">
|
|
972
1030
|
<label for="bc-title">What went wrong?</label>
|
|
@@ -998,218 +1056,231 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
998
1056
|
<span class="count" aria-live="polite"></span>
|
|
999
1057
|
</div>
|
|
1000
1058
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1001
|
-
${a?`<button class="tool" type="button" data-act="shot">${
|
|
1002
|
-
${
|
|
1003
|
-
<button class="tool" type="button" data-act="file">${
|
|
1059
|
+
${a?`<button class="tool" type="button" data-act="shot">${Ve}Screenshot</button>`:""}
|
|
1060
|
+
${h?`<button class="tool" type="button" data-act="rec">${je}Record screen</button>`:""}
|
|
1061
|
+
<button class="tool" type="button" data-act="file">${ue}Upload file</button>
|
|
1004
1062
|
</div>
|
|
1005
1063
|
<div class="thumbs"></div>
|
|
1006
1064
|
<input type="file" accept="${xe.join(",")}" multiple hidden />
|
|
1007
1065
|
</div>`:""}
|
|
1008
|
-
</div>`}function
|
|
1009
|
-
${
|
|
1010
|
-
<span class="kind">${
|
|
1011
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${
|
|
1012
|
-
${
|
|
1066
|
+
</div>`}function ct(e){var de,Z,G,q;const{client:t,cfg:a,root:h,host:i,dock:v,scrim:x,$:s,say:y,titleInput:p,descInput:b,compose:E,sendBtn:r,note:l}=e,S=s(".thumbs"),T=x.querySelector("input[type=file]"),M=[];let n=we,f=null;const o=document.createElement("div");o.setAttribute("role","status"),o.className="note",E.prepend(o);const u=it(a,(de=t.signedInAs())==null?void 0:de.email);let g=a.drafts===!1,c=!1,d=Promise.resolve(),k;function L(){if(clearTimeout(k),!g||c||a.drafts===!1)return d;const m=p.value||b.value||M.length?{title:p.value,description:b.value,priority:n,items:M.map(({blob:Q,mime:R,kind:C})=>({blob:Q,mime:R,kind:C}))}:null;return d=d.catch(()=>{}).then(()=>ne(u,m)).then(()=>{o.textContent=m?"Draft saved on this device":""}).catch(()=>{o.textContent="Draft could not be saved. Keep this tab open."}),d}function H(){clearTimeout(k),k=setTimeout(L,250)}E.addEventListener("input",H),E.addEventListener("change",H);const j=()=>{L()};window.addEventListener("pagehide",j);function N(){M.filter(m=>m.status==="failed").forEach(D)}window.addEventListener("online",N),a.drafts!==!1&&(E.inert=!0,st(u).then(m=>{e.closed||!m||(o.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>',o.querySelector("[data-resume]").onclick=()=>{p.value=m.title||"",b.value=m.description||"",n=ye.some(Q=>Q.value===m.priority)?m.priority:"MEDIUM",x.querySelectorAll("[data-prio]").forEach(Q=>Q.setAttribute("aria-pressed",String(Q.dataset.prio===n)));for(const Q of(m.items||[]).slice(0,a.maxAttachments??5))O(Q);g=!0,L()},o.querySelector("[data-discard]").onclick=()=>{g=!0,L()})}).catch(()=>{o.textContent="Draft storage is unavailable. Keep this tab open."}).finally(()=>{E.inert=!1,o.querySelector("[data-resume]")||(g=!0)})),e.onDestroy(()=>{var m;L(),clearTimeout(k),window.removeEventListener("pagehide",j),window.removeEventListener("online",N),f==null||f.cancel(),M.forEach(Q=>Q.previewUrl&&URL.revokeObjectURL(Q.previewUrl)),(m=h.querySelector(".recbar"))==null||m.remove()}),x.querySelectorAll("[data-prio]").forEach(m=>{m.addEventListener("click",()=>{n=m.dataset.prio,H(),x.querySelectorAll("[data-prio]").forEach(Q=>{Q.setAttribute("aria-pressed",String(Q===m))})})});const B=s("#bc-title-err");function w(m){B.hidden=!m,B.innerHTML=m?`${Y}<span>${$(m)}</span>`:"",p.classList.toggle("invalid",!!m),p.setAttribute("aria-invalid",String(!!m))}p.addEventListener("input",()=>{p.value.trim()&&w("")});function z(){const m=M.some(C=>C.status==="uploading");r.disabled=e.sending||m||M.some(C=>C.status==="failed"),l.textContent=m?"Waiting for the upload to finish…":M.some(C=>C.status==="failed")?"Retry or remove failed attachments before sending.":"";const Q=a.maxAttachments??5;x.querySelectorAll(".tool").forEach(C=>{C.disabled=e.sending||M.length>=Q});const R=s(".field-head .count");R&&(R.textContent=M.length?`${M.length} of ${Q}`:"")}e.refreshSendState=z;function A(m){var F;const Q=m.el,R=m.kind==="VIDEO"?"Video":"Shot",C=m.kind==="VIDEO"?`<video src="${m.previewUrl}" muted playsinline preload="metadata"></video>`:`<img src="${m.previewUrl}" alt="" />`;let V="";m.status==="uploading"?V=`<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(m.progress*100)}%"></i></div></div>`:m.status==="failed"&&(V=`<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Ne}</button>Failed</div>`),Q.innerHTML=`
|
|
1067
|
+
${C}
|
|
1068
|
+
<span class="kind">${R} · ${_(m.size)}</span>
|
|
1069
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${R.toLowerCase()}">${X}</button>
|
|
1070
|
+
${V}`,Q.querySelector('[data-act="drop"]').addEventListener("click",()=>I(m)),(F=Q.querySelector('[data-act="retry"]'))==null||F.addEventListener("click",()=>D(m))}function I(m){const Q=M.indexOf(m);Q>=0&&M.splice(Q,1),m.previewUrl&&URL.revokeObjectURL(m.previewUrl),m.el.remove(),L(),z()}async function D(m){m.status="uploading",m.progress=0,A(m),z();try{const{storageKey:Q,mime:R}=await t.uploadAttachment(m.blob,m.mime,C=>{m.progress=C;const V=m.el.querySelector(".bar i");V&&(V.style.width=`${Math.round(C*100)}%`)});m.storageKey=Q,m.mime=R,m.status="ready"}catch(Q){m.status="failed",y(Q.message.replace("[BugCatch] ",""))}A(m),z()}function O({blob:m,mime:Q,kind:R}){const C=a.maxAttachmentBytes??26214400;if(m.size>C){y(`That file is ${_(m.size)} — the limit is ${_(C)}.`);return}const V=et(Q||m.type,xe);if(!V){y("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");return}const F={blob:m,kind:R,mime:V,size:m.size,previewUrl:URL.createObjectURL(m),status:"uploading",progress:0,storageKey:null,el:document.createElement("div")};F.el.className="thumb",M.push(F),S.appendChild(F.el),y(""),L(),D(F)}async function oe(m){i.style.opacity="0",i.style.pointerEvents="none",await new Promise(Q=>requestAnimationFrame(()=>requestAnimationFrame(Q)));try{return await m()}finally{i.style.opacity="",i.style.pointerEvents=""}}(Z=x.querySelector('[data-act="shot"]'))==null||Z.addEventListener("click",async()=>{try{const m=await oe(tt);O(m)}catch(m){(m==null?void 0:m.name)!=="NotAllowedError"&&y(`Screenshot failed: ${m.message}`)}}),(G=x.querySelector('[data-act="file"]'))==null||G.addEventListener("click",()=>T.click()),T==null||T.addEventListener("change",()=>{const m=(a.maxAttachments??5)-M.length;[...T.files].slice(0,Math.max(m,0)).forEach(Q=>{O({blob:Q,mime:Q.type,kind:Q.type.startsWith("video/")?"VIDEO":"SCREENSHOT"})}),T.value=""}),(q=x.querySelector('[data-act="rec"]'))==null||q.addEventListener("click",async()=>{const m=a.maxRecordingMs??12e4;let Q;try{f=await at({maxMs:m,onTick:R=>{Q&&(Q.querySelector(".time").textContent=te(R))},onAutoStop:()=>{f&&P({keep:!0})}})}catch(R){(R==null?void 0:R.name)!=="NotAllowedError"&&y(`Recording failed: ${R.message}`);return}x.style.display="none",v.hidden=!0,Q=document.createElement("div"),Q.className="recbar",Q.innerHTML=`
|
|
1013
1071
|
<span class="dot"></span>
|
|
1014
1072
|
<span class="time">0:00</span>
|
|
1015
|
-
<span class="hint">Recording — up to ${
|
|
1073
|
+
<span class="hint">Recording — up to ${te(Math.round(m/1e3))}</span>
|
|
1016
1074
|
<button class="stop" type="button">Stop</button>
|
|
1017
|
-
<button class="ghost" type="button">Discard</button>`,
|
|
1075
|
+
<button class="ghost" type="button">Discard</button>`,Q.querySelector(".stop").addEventListener("click",()=>P({keep:!0})),Q.querySelector(".ghost").addEventListener("click",()=>P({keep:!1})),h.appendChild(Q),Q.querySelector(".stop").focus()});async function P({keep:m}){var R;const Q=f;if(Q){if(f=null,(R=h.querySelector(".recbar"))==null||R.remove(),x.style.display="",v.hidden=!1,!m){Q.cancel(),p.focus();return}try{const C=await Q.stop();C.blob.size?O(C):y("That recording came back empty — nothing was captured.")}catch(C){y(`Recording failed: ${C.message}`)}p.focus()}}e.isRecording=()=>!!f,e.stopRecording=P,r.addEventListener("click",async()=>{var R;const m=p.value;if(!m.trim()){w("Add a few words about what went wrong — a short sentence is plenty."),p.focus();return}if(e.holdForReference())return;e.sending=!0,y(""),z();const Q=r.innerHTML;r.innerHTML='<span class="spinner" aria-hidden="true"></span>Sending…';try{const C=await t.report({title:m,description:b.value,priority:n,references:e.answeredReference(),issue:((R=e.pickedIssue())==null?void 0:R.key)||null,attachments:M.filter(V=>V.status==="ready").map(V=>({type:V.kind,storageKey:V.storageKey,mime:V.mime}))});if(C!=null&&C.cancelled){e.sending=!1,r.innerHTML=Q,z();return}c=!0,clearTimeout(k),await d,a.drafts!==!1&&await ne(u,null).catch(()=>{}),e.succeed(C)}catch(C){e.sending=!1,r.innerHTML=Q,y(C.message.replace("[BugCatch] ","")),z(),e.recheckSignIn()}})}const dt=2e4,ke=120,le=200;function $e(e){if(typeof e!="string"||!e.trim()||e.length>400)return null;try{return new RegExp(e.trim(),"gi")}catch{return null}}const Se=e=>String(e).replace(/\s+/g," ").trim().slice(0,ke);function Le(e,t){const a=e&&e.normalize;if(a==="phone"){const h=t.replace(/\D/g,"");return h.length===10?h:h.length===12&&h.startsWith("91")?h.slice(2):h.length===11&&h.startsWith("0")?h.slice(1):t}return a==="upper"?t.toUpperCase():t}function Ee(e){const t=e.length>1&&e[1]!==void 0?e[1]:e[0];return typeof t!="string"||!t.trim()?null:{value:Se(t),start:e.index,end:e.index+e[0].length}}function pt(e,t){return((e.slice(t.start,t.valueStart)+e.slice(t.valueEnd,t.end)).match(/[a-z]/gi)||[]).length}const ut=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[A-Za-z0-9][\w-]{5,40}/gi,Me=/[\w-]/;function ht(e,t){const a=(e||[]).filter(r=>r&&r.scan!==!1&&r.pattern),h=[],i=[],v=(t||[]).map(r=>typeof r=="string"?r.slice(0,dt):"");v.forEach((r,l)=>{r&&a.forEach((S,T)=>{const M=$e(S.pattern);if(!M)return;let n,f=0;for(M.lastIndex=0;(n=M.exec(r))!==null&&!(++f>le);){if(n[0]===""){M.lastIndex+=1;continue}const o=Ee(n);if(!o)continue;const u=n.length>1&&n[1]!==void 0?n[1]:n[0],g=n.index+Math.max(0,n[0].indexOf(u)),c={block:l,order:T,key:S.key,label:S.label,value:Le(S,o.value),start:o.start,end:o.end,valueStart:g,valueEnd:g+u.length};c.weight=pt(r,c),h.push(c)}})});const x=h.filter(r=>!h.some(l=>l!==r&&l.block===r.block&&l.key!==r.key&&l.valueStart<=r.valueStart&&l.valueEnd>=r.valueEnd&&l.weight>r.weight)),s=new Map;for(const r of x){const l=r.value.toLowerCase();s.has(l)||s.set(l,{value:r.value,keys:new Map});const S=s.get(l);S.keys.has(r.key)||S.keys.set(r.key,{key:r.key,label:r.label,order:r.order})}const y=[],p=[],b=new Map;for(const r of s.values()){const l=[...r.keys.values()].sort((M,n)=>M.order-n.order);if(l.length>1){p.push({value:r.value,kinds:l.map(({key:M,label:n})=>({key:M,label:n}))});continue}const[{key:S,label:T}]=l;b.has(S)||b.set(S,[]),b.get(S).push({key:S,label:T,value:r.value})}for(const r of b.values())if(r.length===1)y.push(r[0]);else for(const l of r)p.push({value:l.value,kinds:[{key:l.key,label:l.label}]});const E=new Set(s.keys());return v.forEach((r,l)=>{if(!r)return;const S=h.filter(f=>f.block===l),T=new RegExp(ut.source,"gi");let M,n=0;for(;(M=T.exec(r))!==null&&++n<=le;){const f=M.index,o=f+M[0].length;if(S.some(L=>f<L.end&&o>L.start))continue;const u=r[f-1]||"",g=r[o]||"";if(Me.test(u)||Me.test(g)||u==="/"||u==="@"||g==="@"||u==="."||g==="."&&/\w/.test(r[o+1]||"")||!/\d/.test(M[0]))continue;const c=Se(M[0]),d=c.toLowerCase();if(E.has(d))continue;const k=(e||[]).filter(L=>L&&Qe(L,c)).map(({key:L,label:H})=>({key:L,label:H}));k.length&&(E.add(d),i.push({value:c,kinds:k}))}}),{found:y,conflicts:p,loose:i}}function Qe(e,t){const a=typeof t=="string"?t.trim():"";if(!a||a.length>ke)return null;const h=$e(e&&(e.valuePattern||e.pattern));if(!h)return null;let i,v=0;for(h.lastIndex=0;(i=h.exec(a))!==null&&!(++v>le);){if(i[0]===""){h.lastIndex+=1;continue}const x=i.index+i[0].length===a.length,s=i.index===0||i.index===1;if(x&&s){const y=Ee(i);if(y)return Le(e,y.value)}}return null}function bt(e){const{client:t,say:a,titleInput:h,descInput:i,sendBtn:v,refsBox:x}=e;let s={policy:"off",fields:[]},y=!1,p=null,b="",E="",r=[],l="ask",S=!1,T=!1;t.referenceFields().then(w=>{s=w,g()}).catch(()=>{});function M(){return s.policy==="off"||!s.fields.length?{found:[],conflicts:[],loose:[]}:ht(s.fields,[h.value,i.value])}function n(w=M()){return w.found.length>0&&w.conflicts.length===0}function f(){return!p||!b.trim()?[]:[{key:p,value:b.trim().slice(0,120)}]}const o=document.createElement("p");o.className="ref-found",o.setAttribute("aria-live","polite"),o.hidden=!0,i.closest(".field").after(o);let u;function g(){const w=M();if(n(w)){const z=w.found.slice(0,2).map(A=>`${$(A.label)} <b>${$(d(A.value))}</b>`).join(", ");o.innerHTML=`${W}<span>Found your ${z} — no need to add it again.</span>`,o.hidden=!1,y&&!f().length&&(y=!1,H())}else o.hidden=!0,o.innerHTML=""}const c=()=>{clearTimeout(u),u=setTimeout(g,250)};h.addEventListener("input",c),i.addEventListener("input",c);function d(w){return w.length>20?`${w.slice(0,8)}…${w.slice(-4)}`:w}function k(w){const z=w.trim().toLowerCase();return r.find(A=>A.value.toLowerCase()===z)||null}function L(w){b=w.value,w.kinds.length===1?p=w.kinds[0].key:w.kinds.some(z=>z.key===p)||(p=null),E="",T=!1}function H(){var Z,G;if(!y){x.hidden=!0,x.innerHTML="";return}const w=s.fields.find(q=>q.key===p)||null,z=s.policy!=="required",A=k(b),I=A&&A.kinds.length>1?s.fields.filter(q=>A.kinds.some(m=>m.key===q.key)):s.fields,D=r.length>1&&r.every(q=>q.kinds.length===1&&q.kinds[0].key===r[0].kinds[0].key),O={confirm:r.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."],suggest:["Is this your ID?","We spotted this in your message. Tell us what it is so we can find your record."],ask:z?["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."]}[l];x.hidden=!1;const oe=I.length>6;x.innerHTML=`
|
|
1018
1076
|
<div class="ask-head">
|
|
1019
|
-
<span class="avatar" aria-hidden="true"
|
|
1077
|
+
<span class="avatar orb" aria-hidden="true"></span>
|
|
1020
1078
|
<div>
|
|
1021
|
-
<strong>${
|
|
1022
|
-
<p class="why">${
|
|
1079
|
+
<strong>${$(O[0])}</strong>
|
|
1080
|
+
<p class="why">${$(O[1])}</p>
|
|
1023
1081
|
</div>
|
|
1024
1082
|
</div>
|
|
1025
|
-
${
|
|
1083
|
+
${r.length>1?`
|
|
1026
1084
|
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1027
|
-
${
|
|
1028
|
-
<button type="button" data-ref-cand="${
|
|
1029
|
-
aria-pressed="${!!
|
|
1085
|
+
${r.map((q,m)=>`
|
|
1086
|
+
<button type="button" data-ref-cand="${m}" title="${$(q.value)}"
|
|
1087
|
+
aria-pressed="${!!A&&A===q}">${$(d(q.value))}</button>
|
|
1030
1088
|
`).join("")}
|
|
1031
1089
|
</div>`:""}
|
|
1032
|
-
${
|
|
1090
|
+
${I.length>1&&!oe&&!D?`
|
|
1033
1091
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1034
|
-
${
|
|
1035
|
-
<button type="button" data-ref-kind="${
|
|
1092
|
+
${I.map(q=>`
|
|
1093
|
+
<button type="button" data-ref-kind="${$(q.key)}" aria-pressed="${!!w&&q.key===w.key}">${$(q.label)}</button>
|
|
1036
1094
|
`).join("")}
|
|
1037
1095
|
</div>`:""}
|
|
1038
1096
|
<div class="row">
|
|
1039
|
-
${
|
|
1097
|
+
${oe?`
|
|
1040
1098
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1041
|
-
${
|
|
1042
|
-
${
|
|
1043
|
-
<option value="${
|
|
1099
|
+
${w?"":'<option value="" selected disabled>What is it?</option>'}
|
|
1100
|
+
${I.map(q=>`
|
|
1101
|
+
<option value="${$(q.key)}" ${w&&q.key===w.key?"selected":""}>${$(q.label)}</option>
|
|
1044
1102
|
`).join("")}
|
|
1045
1103
|
</select>`:""}
|
|
1046
|
-
<input class="ref-value${
|
|
1047
|
-
inputmode="${
|
|
1048
|
-
value="${
|
|
1049
|
-
placeholder="${
|
|
1050
|
-
aria-label="${
|
|
1104
|
+
<input class="ref-value${E?" invalid":""}" type="${(w==null?void 0:w.inputMode)==="email"?"email":"text"}"
|
|
1105
|
+
inputmode="${$((w==null?void 0:w.inputMode)==="numeric"||(w==null?void 0:w.inputMode)==="tel"?"numeric":"text")}"
|
|
1106
|
+
value="${$(b)}"
|
|
1107
|
+
placeholder="${$(w?w.placeholder||w.label:"Your ID")}"
|
|
1108
|
+
aria-label="${$(w?w.label:"Your ID")}" ${E?'aria-invalid="true"':""} />
|
|
1051
1109
|
</div>
|
|
1052
|
-
${
|
|
1053
|
-
${
|
|
1054
|
-
${z?`<button type="button" class="link" data-act="ref-skip">${
|
|
1110
|
+
${w!=null&&w.hint?`<p class="hint">${$(w.hint)}</p>`:""}
|
|
1111
|
+
${E?`<p class="field-err" role="alert">${Y}<span>${$(E)}</span></p>`:""}
|
|
1112
|
+
${z?`<button type="button" class="link" data-act="ref-skip">${l==="ask"?"I don't have this — send without it":"Not sure — send as it is"}</button>`:""}`,x.querySelectorAll("[data-ref-cand]").forEach(q=>{q.addEventListener("click",()=>{L(r[Number(q.dataset.refCand)]),H()})}),x.querySelectorAll("[data-ref-kind]").forEach(q=>{q.addEventListener("click",()=>{p=q.dataset.refKind,E="",T=!1,H()})});const P=x.querySelector(".ref-value");P.addEventListener("input",()=>{b=P.value,E="",T=!1}),P.addEventListener("keydown",q=>{q.key==="Enter"&&(q.preventDefault(),v.click())}),(Z=x.querySelector(".ref-kind"))==null||Z.addEventListener("change",q=>{var m;p=q.target.value,E="",H(),(m=x.querySelector(".ref-value"))==null||m.focus()}),(G=x.querySelector('[data-act="ref-skip"]'))==null||G.addEventListener("click",()=>{S=!0,y=!1,p=null,b="",E="",T=!1,H(),a("")}),((!w&&b?x.querySelector("[data-ref-kind], .ref-kind"):null)||P).focus()}function j(w){if(r=w.conflicts.length?w.conflicts:w.loose.slice(0,4),l=w.conflicts.length?"confirm":w.loose.length?"suggest":"ask",y=!0,r.length)if(r.length===1)L(r[0]);else{b="";const[z]=r;p=r.every(I=>I.kinds.length===1&&I.kinds[0].key===z.kinds[0].key)?z.kinds[0].key:null}else p=p||s.fields[0].key;H()}function N(){if(s.policy==="off"||!s.fields.length||f().length)return!1;const w=M();return n(w)||S&&s.policy!=="required"?!1:w}function B(){if(y&&b.trim()&&!p)return E="Pick what this ID is.",H(),!0;const w=N();if(w)return y?H():j(w),a(""),!0;if(p&&b.trim()){const z=s.fields.find(A=>A.key===p);if(!T&&z&&!Qe(z,b))return E=`That does not look like a ${z.label.toLowerCase()}. Press Send again to use it anyway.`,T=!0,H(),!0}return!1}e.holdForReference=B,e.answeredReference=f}const ft={info:pe,success:W,warning:De,critical:Y};function gt(e,{where:t,onDismiss:a}){const h=document.createElement("div");h.className=`notice tone-${e.tone} at-${t}`,h.setAttribute("role","status");const i=document.createElement("span");i.className="notice-ico",i.setAttribute("aria-hidden","true"),i.innerHTML=ft[e.tone]||pe;const v=document.createElement("div");v.className="notice-text";const x=document.createElement("strong");if(x.textContent=e.title,v.append(x),e.body){const s=document.createElement("p");s.textContent=e.body,v.append(s)}if(e.ctaHref&&e.ctaLabel){const s=document.createElement("a");s.className="notice-cta",s.href=e.ctaHref,s.textContent=e.ctaLabel,/^https?:/i.test(e.ctaHref)&&(s.target="_blank",s.rel="noopener noreferrer"),v.append(s)}if(h.append(i,v),e.dismissible&&a){const s=document.createElement("button");s.type="button",s.className="notice-x",s.setAttribute("aria-label","Dismiss this notice"),s.innerHTML=X,s.addEventListener("click",()=>a(e)),h.append(s)}return h}const mt=3;function vt(e){const{client:t,cfg:a,notices:h}=e;let i=[];function v(){const s=i.slice(0,mt);h.replaceChildren(...s.map(y=>gt(y,{where:"panel",onDismiss:x}))),h.hidden=s.length===0}function x(s){t.dismissAnnouncement(s),i=i.filter(y=>y!==s),v(),e.titleInput.focus()}a.announcements!==!1&&typeof t.announcements=="function"&&t.announcements().then(s=>{e.closed||(i=s,v())}).catch(()=>{})}function xt(e){const{client:t,cfg:a,titleInput:h,known:i}=e;let v=[],x="",s=null,y=null;function p(){a.knownIssues!==!1&&t.knownIssues().then(S=>{v=S,r()}).catch(()=>{})}let b=null;function E(S){if(a.knownIssues===!1)return;clearTimeout(b),y==null||y.abort();const T=(S||"").trim();if(T.length<3){p();return}b=setTimeout(()=>{y=new AbortController,t.matchKnownIssues(T,{signal:y.signal}).then(M=>{M.length&&(v=M,r())}).catch(()=>{})},250)}function r(){if(!v.length){i.hidden=!0,i.innerHTML="";return}i.hidden=!1,i.innerHTML=`
|
|
1055
1113
|
<p class="known-h">Already reported</p>
|
|
1056
|
-
${
|
|
1057
|
-
<div class="issue ${
|
|
1114
|
+
${v.map(S=>`
|
|
1115
|
+
<div class="issue ${S.joined?"is-joined":""}">
|
|
1058
1116
|
<span class="who">
|
|
1059
|
-
<span class="t">${
|
|
1060
|
-
<span class="meta">${
|
|
1117
|
+
<span class="t">${$(S.title)}</span>
|
|
1118
|
+
<span class="meta">${$(l(S))}</span>
|
|
1061
1119
|
</span>
|
|
1062
|
-
<button class="join" type="button" data-join="${
|
|
1063
|
-
${
|
|
1120
|
+
<button class="join" type="button" data-join="${$(S.id)}"
|
|
1121
|
+
${S.joined?"disabled":""}>${S.joined?"Following":"Me too"}</button>
|
|
1064
1122
|
</div>
|
|
1065
|
-
${
|
|
1123
|
+
${s===S.id?`
|
|
1066
1124
|
<div class="ask">
|
|
1067
1125
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1068
1126
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1069
|
-
<button class="ghost" type="button" data-join-confirm="${
|
|
1127
|
+
<button class="ghost" type="button" data-join-confirm="${$(S.id)}">Follow</button>
|
|
1070
1128
|
</div>`:""}
|
|
1071
1129
|
`).join("")}
|
|
1072
|
-
${
|
|
1130
|
+
${x?`<p class="err">${$(x)}</p>`:""}`}function l(S){const T=S.status==="IN_PROGRESS"?"Being worked on now":"Not fixed yet",M=S.affectedCount===0?"":` · ${S.affectedCount} ${S.affectedCount===1?"person has":"people have"} said this is happening to them`;return`${T} · reported ${ee(S.since)}${M}`}i.addEventListener("click",async S=>{var o,u,g,c,d;const T=S.target.closest("[data-join]"),M=S.target.closest("[data-join-confirm]");if(!T&&!M)return;const n=(M||T).getAttribute(M?"data-join-confirm":"data-join");x="";const f=((u=(o=i.querySelector(".join-email"))==null?void 0:o.value)==null?void 0:u.trim())||((g=t.signedInAs())==null?void 0:g.email)||((c=t.config.user)==null?void 0:c.email);if(!f){s=n,r(),(d=i.querySelector(".join-email"))==null||d.focus();return}try{const k=await t.meToo(n,{email:f});s=null,v=v.map(L=>L.id===n?{...L,joined:!0,affectedCount:k.affectedCount??L.affectedCount}:L),r()}catch(k){x=k.message.replace("[BugCatch] ",""),r()}}),p(),h.addEventListener("input",()=>E(h.value))}function yt(e){const{client:t,cfg:a,titleInput:h,descInput:i,picks:v}=e;let x=[],s=null;function y(){if(!x.length){v.hidden=!0,v.innerHTML="";return}v.hidden=!1,v.innerHTML=`
|
|
1073
1131
|
<p class="picks-h">Get an answer right away</p>
|
|
1074
1132
|
<div class="picks-grid" role="group" aria-label="Common questions">
|
|
1075
|
-
${
|
|
1076
|
-
<button type="button" class="pick" data-pick="${
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1133
|
+
${x.map((p,b)=>`
|
|
1134
|
+
<button type="button" class="pick" data-pick="${$(p.key)}"
|
|
1135
|
+
${p.hint?`title="${$(p.hint)}" aria-describedby="bc-pick-h${b}"`:""}
|
|
1136
|
+
aria-pressed="${(s==null?void 0:s.key)===p.key}">
|
|
1137
|
+
<span class="t">${$(p.title)}</span>
|
|
1138
|
+
${p.hint?`<span class="h sr-only" id="bc-pick-h${b}">${$(p.hint)}</span>`:""}
|
|
1080
1139
|
</button>`).join("")}
|
|
1081
1140
|
</div>
|
|
1082
|
-
${
|
|
1141
|
+
${s?`<p class="picks-note">${W}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>`:""}`}v.addEventListener("click",p=>{const b=p.target.closest("[data-pick]");if(!b)return;const E=x.find(l=>l.key===b.dataset.pick);if(!E)return;const r=s&&h.value.trim()===s.title;(s==null?void 0:s.key)===E.key?(s=null,r&&(h.value="")):(s=E,(!h.value.trim()||r)&&(h.value=E.title)),h.dispatchEvent(new Event("input",{bubbles:!0})),y(),s&&i.focus()}),a.agentIssues!==!1&&typeof t.agentIssues=="function"&&t.agentIssues().then(p=>{x=p,y()}).catch(()=>{}),e.pickedIssue=()=>s}function wt(e){const{client:t,scrim:a,say:h,callBtn:i,close:v}=e;let x=!1;function s(){t.callKind().then(b=>{b&&(x=!0,e.preloadCall(),i.hidden=e.mustSignIn())}).catch(()=>{})}s(),i.addEventListener("click",async()=>{e.sending=!0,h(""),e.refreshSendState(),i.disabled=!0,i.innerHTML='<span class="spinner"></span>Ringing…';try{const b=await t.startCall();y(b)}catch(b){e.sending=!1,i.disabled=!1,i.innerHTML=`${J}Talk to the team`,e.refreshSendState(),b.filed?e.succeed(b.filed,{callFailed:b.reason||"The call could not be started."}):(h(b.message.replace("[BugCatch] ","")),e.recheckSignIn())}});function y(b){const E=a.querySelector(".panel"),r=b!=null&&b.bugId?String(b.bugId).slice(0,8):null;E.innerHTML=`
|
|
1083
1142
|
<div class="call">
|
|
1084
1143
|
<div class="call-head">
|
|
1085
1144
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1086
1145
|
<strong class="call-state">Ringing…</strong>
|
|
1087
1146
|
</div>
|
|
1088
1147
|
<p class="call-note">
|
|
1089
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1148
|
+
We're ringing the team now. Someone will pick up if they're free — your report${r?` <code>${$(r)}</code>`:""} is already filed either way, so nothing is lost if nobody answers.
|
|
1090
1149
|
</p>
|
|
1091
1150
|
<div class="foot">
|
|
1092
1151
|
<span class="spacer"></span>
|
|
1093
1152
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1094
1153
|
</div>
|
|
1095
|
-
</div>`;const
|
|
1154
|
+
</div>`;const l=E.querySelector(".call-state"),S=E.querySelector(".call-dot"),T={ringing:"Ringing the team…",connecting:"Someone answered — connecting…",connected:"Connected",missed:"Nobody was free",ended:"Call ended",failed:"The call dropped"},M=["ended","failed","missed"],n=t.on("call",({state:f})=>{if(l.textContent=T[f]||f,S.classList.toggle("off",M.includes(f)),M.includes(f)&&(E.querySelector('[data-act="hangup"]').textContent="Close",f==="missed")){const o=E.querySelector(".call-note");o&&(o.textContent="Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.")}});E.querySelector('[data-act="hangup"]').addEventListener("click",()=>{n(),t.endCall(),v()})}function p(b,E,r){const l=document.createElement("div");l.className="livecall",l.innerHTML=`
|
|
1096
1155
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1097
1156
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1098
1157
|
<span class="secs" hidden></span>
|
|
1099
|
-
${
|
|
1158
|
+
${r!=null&&r.recorded?'<span class="call-kept">This call is recorded.</span>':""}
|
|
1100
1159
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
1101
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1160
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,b.insertBefore(l,E);const S=l.querySelector(".who"),T=l.querySelector(".secs"),M=l.querySelector(".call-dot"),n=l.querySelector('[data-act="mute"]'),f=l.querySelector('[data-act="hangup"]');let o=null;const u=()=>{o&&(clearInterval(o),o=null)},g=d=>{u(),M.classList.add("off"),l.classList.add("over"),S.textContent=d,T.hidden=!0,n.hidden=!0,f.textContent="Dismiss",f.classList.remove("danger")},c=t.on("call",({state:d})=>{if(d==="ringing"&&(S.textContent="Calling the team…"),d==="connecting"&&(S.textContent="Someone answered — connecting…"),d==="connected"){S.textContent="You're on a call with the team",n.hidden=!1,T.hidden=!1;const k=Date.now();u(),o=setInterval(()=>{T.textContent=te(Math.floor((Date.now()-k)/1e3))},1e3),T.textContent="0s"}d==="missed"&&g("Nobody was free. Send a message instead and the team will pick it up."),d==="ended"&&g("Call ended."),d==="failed"&&g("The call dropped.")});n.addEventListener("click",()=>{const d=r.setMuted(!r.isMuted());n.textContent=d?"Unmute":"Mute",S.textContent=d?"You're muted":"You're on a call with the team"}),f.addEventListener("click",()=>{c(),u(),t.endCall(),l.remove(),e.refreshThread(e.openReportId())})}e.offerCall=s,e.callOffered=()=>x,e.showLiveCall=p}function kt(e){var c;const{client:t,say:a,compose:h,sendBtn:i,historyBtn:v,callBtn:x,whoami:s}=e;let y={mode:t.lastLoginMode||"off",signedIn:null},p="idle",b=((c=t.config.user)==null?void 0:c.email)||"",E="",r=!1,l="";const S=()=>y.mode==="required"&&!y.signedIn;function T(){const d=S();h.hidden=d,i.hidden=d,v&&(v.hidden=d),d?x.hidden=!0:e.callOffered()&&(x.hidden=!1)}function M(){var k;if(y.mode==="off"){s.hidden=!0,s.innerHTML="";return}s.hidden=!1,s.classList.toggle("asking",p!=="idle");const d=l?`<div class="after err">${$(l)}</div>`:"";if(p==="idle"){if(y.signedIn){s.innerHTML=`<span class="who">Signed in as <strong>${$(y.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;return}const L=(k=t.config.user)==null?void 0:k.email;s.innerHTML=`<span class="who">${y.mode==="required"?"Sign in to report a bug here.":L?`Reporting as <strong>${$(L)}</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>`;return}if(p==="email"){s.innerHTML=`
|
|
1102
1161
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
1103
|
-
It's how you hear back about this report${
|
|
1162
|
+
It's how you hear back about this report${y.mode==="required"?", and this project asks for it":""}.</p>
|
|
1104
1163
|
<div class="row">
|
|
1105
|
-
<input type="email" data-fld="email" value="${
|
|
1164
|
+
<input type="email" data-fld="email" value="${$(b)}"
|
|
1106
1165
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1107
|
-
aria-label="Your email address" ${
|
|
1108
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1109
|
-
${
|
|
1166
|
+
aria-label="Your email address" ${r?"disabled":""} />
|
|
1167
|
+
<button type="button" class="primary" data-act="code" ${r?"disabled":""}>
|
|
1168
|
+
${r?"Sending…":"Send code"}
|
|
1110
1169
|
</button>
|
|
1111
1170
|
</div>
|
|
1112
|
-
${
|
|
1113
|
-
${
|
|
1114
|
-
<p class="why">We sent a code to <strong>${
|
|
1171
|
+
${d}
|
|
1172
|
+
${y.mode==="optional"?'<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>':""}`;return}s.innerHTML=`
|
|
1173
|
+
<p class="why">We sent a code to <strong>${$(b)}</strong>. It expires in ten minutes.</p>
|
|
1115
1174
|
<div class="row">
|
|
1116
|
-
<input type="text" class="code" data-fld="code" value="${
|
|
1175
|
+
<input type="text" class="code" data-fld="code" value="${$(E)}"
|
|
1117
1176
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
1118
|
-
maxlength="8" aria-label="The code we emailed you" ${
|
|
1119
|
-
<button type="button" class="primary" data-act="confirm" ${
|
|
1120
|
-
${
|
|
1177
|
+
maxlength="8" aria-label="The code we emailed you" ${r?"disabled":""} />
|
|
1178
|
+
<button type="button" class="primary" data-act="confirm" ${r?"disabled":""}>
|
|
1179
|
+
${r?"Checking…":"Sign in"}
|
|
1121
1180
|
</button>
|
|
1122
1181
|
</div>
|
|
1123
|
-
${
|
|
1182
|
+
${d}
|
|
1124
1183
|
<div class="after">
|
|
1125
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1126
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1127
|
-
</div>`}function
|
|
1128
|
-
<div class="sys k-${
|
|
1129
|
-
<span class="dot" aria-hidden="true"></span>${
|
|
1130
|
-
<span class="t">· ${
|
|
1131
|
-
</div>`}function ze(e,t=""){const a=e.from==="reporter",
|
|
1132
|
-
<button type="button" data-quick="Yes, this is the problem">${
|
|
1184
|
+
<button type="button" class="link" data-act="resend" ${r?"disabled":""}>Send it again</button>
|
|
1185
|
+
<button type="button" class="link" data-act="signin-back" ${r?"disabled":""}>Use another address</button>
|
|
1186
|
+
</div>`}function n({focus:d=!1}={}){var L;if(M(),T(),!d||r)return;const k=s.querySelector("[data-fld]");k&&(k.focus(),(L=k.setSelectionRange)==null||L.call(k,k.value.length,k.value.length))}s.addEventListener("input",d=>{const k=d.target.closest("[data-fld]");k&&(k.dataset.fld==="email"?b=k.value:E=k.value)}),s.addEventListener("keydown",d=>{d.key!=="Enter"||!d.target.closest("[data-fld]")||(d.preventDefault(),p==="email"?f():o())});async function f({resent:d=!1}={}){const k=b.trim();if(!k){l="Enter the address to send the code to.",n({focus:!0});return}r=!0,l="",n();try{await t.signIn(k),b=k,d||(E=""),p="code"}catch(L){l=L.message}finally{r=!1,n({focus:!0})}}async function o(){const d=E.trim();if(!d){l="Enter the code we emailed you.",n({focus:!0});return}r=!0,l="",n();try{const k=await t.confirmSignIn(b.trim(),d);y.signedIn=k,p="idle",E="",a(""),e.offerCall()}catch(k){l=k.message}finally{r=!1,n({focus:p!=="idle"})}}s.addEventListener("click",async d=>{const k=d.target.closest("button[data-act]");if(!k)return;const L=k.dataset.act;if(L==="signin"){p="email",l="",n({focus:!0});return}if(L==="skip"){p="idle",l="",n();return}if(L==="signin-back"){p="email",l="",E="",n({focus:!0});return}if(L==="code"){f();return}if(L==="resend"){f({resent:!0});return}if(L==="confirm"){o();return}if(L==="signout"){r=!0,n();try{await t.signOut()}finally{y.signedIn=null,r=!1,p=y.mode==="required"?"email":"idle",n({focus:p!=="idle"})}}});async function u({announce:d=!1}={}){const k=await t.loginState();y={mode:k.mode,signedIn:k.signedIn},t.lastLoginMode=k.mode,S()&&p==="idle"&&(p="email"),y.signedIn&&(p="idle"),d&&k.signedOutReason&&a(k.signedOutReason,"info"),n()}u({announce:!0}).catch(()=>{});function g(){y.mode!=="off"&&u().catch(()=>{})}e.mustSignIn=S,e.recheckSignIn=g}const $t=/Did this answer your question\?/i;function Te(e){const t=e||[];if(!t.length)return"";let a=null,h=null;return t.map(i=>{var b,E,r,l;const v=K(i.at),x=v&&v!==a?`<div class="day-sep" role="separator">${$(Ze(i.at))}</div>`:"";if(x&&(a=v,h=null),!i.from)return h=null,x+Lt(i);const s={from:i.from,author:(b=i.reply)==null?void 0:b.author,automated:(E=i.reply)==null?void 0:E.automated,body:(r=i.reply)==null?void 0:r.body,at:i.at,attachments:(l=i.reply)==null?void 0:l.attachments},y=St(s),p=h&&h.who===y&&Math.abs(new Date(i.at).getTime()-new Date(h.at).getTime())<5*6e4;return h={who:y,at:i.at},x+ze(s,p?"cont":"")}).join("")}function St(e){return e.from==="reporter"?"me":e.automated?"assistant":`team:${e.author||""}`}function Lt(e){const t=ge(e.at);return`
|
|
1187
|
+
<div class="sys k-${$(e.kind)}">
|
|
1188
|
+
<span class="dot" aria-hidden="true"></span>${$(e.summary||"")}${t?`
|
|
1189
|
+
<span class="t">· ${$(t)}</span>`:""}
|
|
1190
|
+
</div>`}function ze(e,t=""){const a=e.from==="reporter",h=e.body||"",i=e.attachments||[],v=!a&&!!e.automated,x=h?`<span class="msg-text">${$(h)}</span>`:"",s=i.length?`<div class="att">${i.map(Mt).join("")}</div>`:"";let y="",p="";if(v)y='<span class="msg-who auto">Assistant <span class="tag">AI</span></span>',p='<span class="av bot orb" aria-hidden="true"></span>';else if(!a){const E=e.author||"Support team";y=`<span class="msg-who">${$(E)}</span>`,p=`<span class="av" aria-hidden="true">${$(Ue(E))}</span>`}t.includes("cont")&&(y="");const b=v&&/it goes to the same person/i.test(h)?`<div class="quick" role="group" aria-label="Answer">
|
|
1191
|
+
<button type="button" data-quick="Yes, this is the problem">${W}That's right</button>
|
|
1133
1192
|
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
1134
|
-
</div>`:
|
|
1135
|
-
<button type="button" data-quick="Yes, that answers it">${
|
|
1193
|
+
</div>`:v&&$t.test(h)?`<div class="quick" role="group" aria-label="Did this answer your question?">
|
|
1194
|
+
<button type="button" data-quick="Yes, that answers it">${W}Yes, that answers it</button>
|
|
1136
1195
|
<button type="button" data-quick="No, I still need help">No, I still need help</button>
|
|
1137
1196
|
</div>`:"";return`
|
|
1138
|
-
<div class="msg-row ${a?"mine":"theirs"} ${
|
|
1139
|
-
${
|
|
1140
|
-
${d}
|
|
1141
|
-
<div class="bubble ${l?"":"silent"}">${m}${o}</div>
|
|
1197
|
+
<div class="msg-row ${a?"mine":"theirs"} ${v?"auto":""} ${t}">
|
|
1198
|
+
${p}
|
|
1142
1199
|
${y}
|
|
1143
|
-
<
|
|
1144
|
-
|
|
1200
|
+
<div class="bubble ${h?"":"silent"}">${x}${s}</div>
|
|
1201
|
+
${b}
|
|
1202
|
+
<span class="msg-when">${$(ge(e.at)||ee(e.at))}</span>
|
|
1203
|
+
</div>`}function Et(){return`
|
|
1145
1204
|
<div class="typing-row">
|
|
1146
|
-
<span class="av bot" aria-hidden="true"
|
|
1205
|
+
<span class="av bot orb" aria-hidden="true"></span>
|
|
1147
1206
|
<span class="msg-who auto">Assistant <span class="tag">AI</span></span>
|
|
1148
1207
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
1149
|
-
</div>`}function
|
|
1208
|
+
</div>`}function Mt(e){const t=$(e.name||"attachment");if(!e.url)return`<span class="file"><span class="nm">${t}</span></span>`;const a=$(e.url);return e.type==="SCREENSHOT"?`<a href="${a}" target="_blank" rel="noopener noreferrer"><img src="${a}" alt="${t}" loading="lazy"></a>`:e.type==="AUDIO"?`<audio controls preload="metadata" src="${a}"></audio>`:e.type==="VIDEO"?`<video controls preload="metadata" src="${a}"></video>`:`
|
|
1150
1209
|
<a class="file" href="${a}" target="_blank" rel="noopener noreferrer" download>
|
|
1151
1210
|
<span class="nm">${t}</span>
|
|
1152
|
-
${e.size?`<span class="sz">${
|
|
1153
|
-
</a>`}function
|
|
1211
|
+
${e.size?`<span class="sz">${$(_(e.size))}</span>`:""}
|
|
1212
|
+
</a>`}function Qt(e,t,a,h){var g;const{client:i,cfg:v}=e,x=document.createElement("div");x.className="composer",x.innerHTML=`
|
|
1154
1213
|
<div class="staged" hidden></div>
|
|
1155
1214
|
<div class="row">
|
|
1156
1215
|
<div class="tools">
|
|
1157
|
-
${
|
|
1158
|
-
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${
|
|
1159
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
1160
|
-
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${
|
|
1216
|
+
${v.attachments===!1?"":`
|
|
1217
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${ue}</button>
|
|
1218
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${he}</button>`}
|
|
1219
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${J}</button>
|
|
1161
1220
|
</div>
|
|
1162
1221
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
1163
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
1222
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${be}</button>
|
|
1164
1223
|
</div>
|
|
1165
1224
|
<div class="note" hidden></div>
|
|
1166
|
-
<input type="file" hidden multiple accept="${ve.join(",")}">`,t.appendChild(
|
|
1167
|
-
<span class="chip ${
|
|
1168
|
-
<span class="nm">${
|
|
1169
|
-
<span class="sz">${
|
|
1170
|
-
<button type="button" data-drop="${
|
|
1171
|
-
</span>`).join("");for(const
|
|
1225
|
+
<input type="file" hidden multiple accept="${ve.join(",")}">`,t.appendChild(x);const s=x.querySelector(".staged"),y=x.querySelector("textarea"),p=x.querySelector('[data-act="send"]'),b=x.querySelector('[data-act="voice"]'),E=x.querySelector('[data-act="livecall"]'),r=x.querySelector("input[type=file]"),l=x.querySelector(".note"),S=[];let T=null,M=!1;function n(c,d=""){l.hidden=!c,l.className=`note ${d}`,l.textContent=c||""}function f(){const c=S.filter(d=>d.storageKey);p.disabled=M||!y.value.trim()&&!c.length,s.hidden=!S.length,s.innerHTML=S.map((d,k)=>`
|
|
1226
|
+
<span class="chip ${d.storageKey?"":"uploading"}">
|
|
1227
|
+
<span class="nm">${$(d.name)}</span>
|
|
1228
|
+
<span class="sz">${d.storageKey?_(d.size):"sending…"}</span>
|
|
1229
|
+
<button type="button" data-drop="${k}" aria-label="Remove ${$(d.name)}">${X}</button>
|
|
1230
|
+
</span>`).join("");for(const d of s.querySelectorAll("[data-drop]"))d.addEventListener("click",()=>{S.splice(Number(d.dataset.drop),1),f()})}async function o(c,d,k){const L={name:k,size:c.size,storageKey:null};S.push(L),f();try{const{storageKey:H,mime:j}=await i.uploadAttachment(c,d);L.storageKey=H,L.mime=j}catch(H){S.splice(S.indexOf(L),1),n(H.message||"That file could not be sent.","err")}f()}y.addEventListener("input",()=>{y.style.height="auto",y.style.height=`${Math.min(y.scrollHeight,120)}px`,f()}),y.addEventListener("keydown",c=>{c.key==="Enter"&&!c.shiftKey&&!c.isComposing&&(c.preventDefault(),u())}),(g=x.querySelector('[data-act="attach"]'))==null||g.addEventListener("click",()=>r.click()),r.addEventListener("change",()=>{n("");for(const c of r.files){if(c.size>i.config.maxAttachmentBytes){n(`${c.name} is larger than ${_(i.config.maxAttachmentBytes)}.`,"err");continue}o(c,c.type,c.name)}r.value=""}),b&&!Ge()&&(b.disabled=!0,b.title="This browser cannot record audio"),b==null||b.addEventListener("click",async()=>{if(T){const c=T;T=null,b.classList.remove("recording"),b.innerHTML=he,n("");const{blob:d,mime:k}=await c.stop();d.size&&o(d,k,"Voice note");return}try{n(""),T=await nt({maxMs:i.config.maxRecordingMs,onTick:c=>n(`Recording — ${te(c)}. Tap the mic to stop.`),onAutoStop:()=>b.click()}),b.classList.add("recording"),b.innerHTML=Oe}catch{T=null,n("The microphone is not available — check the browser permission.","err")}}),i.canCallTeam(h).then(c=>{c&&(E.hidden=!1,e.preloadCall())}).catch(()=>{}),E.addEventListener("click",async()=>{E.disabled=!0,n("");try{const c=await i.startLiveCall(h);e.showLiveCall(t,a,c)}catch(c){n(c.message.replace("[BugCatch] ",""),"err")}finally{E.disabled=!1}}),p.addEventListener("click",u),a.addEventListener("click",c=>{var k,L;const d=(L=(k=c.target).closest)==null?void 0:L.call(k,"[data-quick]");!d||M||(y.value=d.dataset.quick,u())});async function u(){var k;const c=y.value.trim(),d=S.filter(L=>L.storageKey);if(!(M||!c&&!d.length)){M=!0,f(),n(""),a.insertAdjacentHTML("beforeend",ze({from:"reporter",body:c,at:new Date().toISOString(),attachments:d.map(L=>({type:"FILE",name:L.name,size:L.size}))},"pending")),U(a,{smooth:!0});try{await i.replyToReport(h,{body:c,attachments:d.map(L=>({storageKey:L.storageKey,mime:L.mime,name:L.name,size:L.size}))}),y.value="",y.style.height="auto",S.length=0,await e.refreshThread(h)}catch(L){(k=a.querySelector(".msg-row.pending"))==null||k.classList.replace("pending","failed"),n(L.message||"That could not be sent — try again.","err")}finally{M=!1,f()}}}f()}const ce=new WeakMap;function qe(e){return JSON.stringify(e?[e.score,e.current,e.comment||null]:null)}function Tt(e){return e.rating?` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${fe}${Number(e.rating)}</span>`:e.ratingAsked?' · <span class="rate-ask">Rate it</span>':""}function zt(e){var M;const{client:t,scrim:a,close:h}=e;let i=null;function v(n,{callFailed:f=null}={}){if(n!=null&&n.id&&!f){y(n.id,{fresh:!0}).then(o=>{o||x(n,{callFailed:f})});return}x(n,{callFailed:f})}function x(n,{callFailed:f=null}={}){var c;const o=n!=null&&n.id?String(n.id).slice(0,8):null,u=(c=n==null?void 0:n.estimate)!=null&&c.label?String(n.estimate.label):null,g=f?`<p class="eta">${$(f)} Your report is filed, and the team will reply in the chat.</p>`:"";a.querySelector(".panel").innerHTML=`
|
|
1172
1231
|
<div class="done">
|
|
1173
|
-
<div class="tick">${
|
|
1232
|
+
<div class="tick">${W}</div>
|
|
1174
1233
|
<h3>Thanks — that's on its way.</h3>
|
|
1175
|
-
<p>${
|
|
1176
|
-
${
|
|
1177
|
-
${
|
|
1178
|
-
</div>`,setTimeout(
|
|
1179
|
-
${
|
|
1180
|
-
<div class="history" aria-busy="true">${
|
|
1181
|
-
<button class="row" type="button" data-report="${
|
|
1182
|
-
<span class="row-ico" aria-hidden="true">${
|
|
1234
|
+
<p>${o?`Filed as <code>${$(o)}</code>.`:"The team has what they need to reproduce it."}</p>
|
|
1235
|
+
${g}
|
|
1236
|
+
${u?`<p class="eta">Reports like this usually take <strong>${$(u)}</strong>. We'll let you know when it moves.</p>`:""}
|
|
1237
|
+
</div>`,setTimeout(h,g?6e3:u?4e3:2e3)}async function s(){const n=a.querySelector(".panel");clearTimeout(p),i=null,n.classList.remove("is-chat"),n.innerHTML=`
|
|
1238
|
+
${re({title:"Your reports",sub:"Where each one has got to.",theme:e.themeLabel()})}
|
|
1239
|
+
<div class="history" aria-busy="true">${_e(3)}</div>`,n.querySelector('[data-act="close"]').addEventListener("click",h);let f=[];try{({reports:f}=await t.myReports())}catch{const u=n.querySelector(".history");u&&(u.innerHTML=ie("Couldn't load your reports just now.",Y));return}const o=n.querySelector(".history");if(o){o.removeAttribute("aria-busy"),o.innerHTML=f.length?f.map((u,g)=>`
|
|
1240
|
+
<button class="row" type="button" data-report="${$(u.id)}" style="animation-delay:${Math.min(g,8)*30}ms">
|
|
1241
|
+
<span class="row-ico" aria-hidden="true">${He}</span>
|
|
1183
1242
|
<span class="who">
|
|
1184
|
-
<span class="ttl">${
|
|
1185
|
-
<span class="sub">${
|
|
1243
|
+
<span class="ttl">${$(u.title)}</span>
|
|
1244
|
+
<span class="sub">${$(u.reference)} · ${$(ee(u.createdAt))}${Tt(u)}</span>
|
|
1186
1245
|
</span>
|
|
1187
|
-
<span class="pill ${
|
|
1188
|
-
<span class="chev" aria-hidden="true">${
|
|
1189
|
-
</button>`).join(""):
|
|
1190
|
-
${
|
|
1191
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
1246
|
+
<span class="pill ${$(String(u.status).toLowerCase())}">${$(se(u.status))}</span>
|
|
1247
|
+
<span class="chev" aria-hidden="true">${Pe}</span>
|
|
1248
|
+
</button>`).join(""):ie("You haven't reported anything yet.",We);for(const u of o.querySelectorAll("[data-report]"))u.addEventListener("click",()=>y(u.dataset.report))}}async function y(n,{fresh:f=!1}={}){var k;const o=a.querySelector(".panel");clearTimeout(p),o.classList.add("is-chat"),o.innerHTML=`
|
|
1249
|
+
${re({back:!0,title:f?"Looking into it":"Your report",sub:f?"It may ask you a question here.":"Updates, and a way to reply.",theme:e.themeLabel()})}
|
|
1250
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${Ke()}</div></div>`,o.querySelector('[data-act="close"]').addEventListener("click",h),o.querySelector('[data-act="back"]').addEventListener("click",s);let u=null;try{u=await t.myReport(n)}catch{u=null}const g=o.querySelector(".history");if(!g||!o.querySelector('[data-act="back"]'))return!1;if(!u)return f?(o.classList.remove("is-chat"),!1):(g.removeAttribute("aria-busy"),g.innerHTML=ie("Couldn't load that report just now.",Y),!1);i=n,t.markReportRead(n);const c=Te(u.timeline);g.classList.add("chatting"),g.removeAttribute("aria-busy"),g.innerHTML=`
|
|
1192
1251
|
<div class="report-head">
|
|
1193
|
-
<span class="ttl">${
|
|
1194
|
-
<span class="sub">${
|
|
1195
|
-
<span class="pill ${
|
|
1196
|
-
${(
|
|
1252
|
+
<span class="ttl">${$(u.title)}</span>
|
|
1253
|
+
<span class="sub">${$(u.reference)} · ${$(u.project||"")}</span>
|
|
1254
|
+
<span class="pill ${$(String(u.status).toLowerCase())}">${$(se(u.status))}</span>
|
|
1255
|
+
${(k=u.estimate)!=null&&k.label?`<span class="eta-line">Usually takes ${$(String(u.estimate.label))}</span>`:""}
|
|
1197
1256
|
</div>
|
|
1198
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
1199
|
-
<div class="as-body${
|
|
1257
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${c}</div>`;const d=g.querySelector(".thread");return ce.set(d,c),U(d),E(g,u),r(g,u),u.canReply&&Qt(e,g,d,n),b(g,u,n),U(d),!0}let p=null;function b(n,f,o){var w,z,A;clearTimeout(p);const u=f.assistant,g=n.querySelector(".thread");let c=n.querySelector(".assistant");if(!u){c==null||c.remove(),(w=g==null?void 0:g.querySelector(".typing-row"))==null||w.remove();return}const d=(c==null?void 0:c.dataset.phase)||null;c||(c=document.createElement("div"),c.setAttribute("role","status"),c.setAttribute("aria-live","polite"),(z=n.querySelector(".report-head"))==null||z.after(c)),c.className=`assistant ${$(u.phase)}`,c.dataset.phase=u.phase;const k=u.steps||[],L=k.filter(I=>I.state==="done").length,H=k.some(I=>I.state==="active")?.5:0,j=k.length?Math.round((L+H)/k.length*100):0,N=`
|
|
1258
|
+
<div class="as-body${d&&d!==u.phase?" entering":""}">
|
|
1200
1259
|
<div class="as-top">
|
|
1201
|
-
<span class="as-orb"
|
|
1260
|
+
<span class="as-orb${u.phase==="calling"||u.phase==="resolved"?"":" orb"}" aria-hidden="true">${u.phase==="calling"?J:u.phase==="resolved"?W:""}</span>
|
|
1202
1261
|
<div class="as-text">
|
|
1203
|
-
<div class="as-title">${
|
|
1204
|
-
<div class="as-detail">${
|
|
1262
|
+
<div class="as-title">${$(u.title)}</div>
|
|
1263
|
+
<div class="as-detail">${$(u.detail)}</div>
|
|
1205
1264
|
</div>
|
|
1206
1265
|
</div>
|
|
1207
1266
|
</div>
|
|
1208
|
-
${
|
|
1209
|
-
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${
|
|
1210
|
-
<ol class="as-steps">${
|
|
1267
|
+
${k.length?`
|
|
1268
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${j}"><i style="width:${j}%"></i></div>
|
|
1269
|
+
<ol class="as-steps">${k.map(I=>`<li class="${$(I.state)}"${I.state==="active"?' aria-current="step"':""}><span class="dot"></span><span class="lbl">${$(I.label)}</span></li>`).join("")}</ol>`:""}`,B=JSON.stringify([u.phase,u.title,u.detail,k]);if(c.dataset.key!==B){const I=c.querySelector(".as-progress i"),D=I==null?void 0:I.style.width;c.innerHTML=N,c.dataset.key=B;const O=c.querySelector(".as-progress i");O&&D&&(O.style.width=D,requestAnimationFrame(()=>{O.style.width=`${j}%`}))}if(g){const I=me(g),D=g.querySelector(".typing-row");u.phase!=="analyzing"?D==null||D.remove():(!D||D!==g.lastElementChild)&&(D==null||D.remove(),g.insertAdjacentHTML("beforeend",Et()),I&&U(g))}u.phase==="analyzing"?p=setTimeout(()=>S(o),3e3):u.phase==="calling"?p=setTimeout(()=>S(o),1e4):u.phase==="needs_info"&&d!=="needs_info"&&((A=n.querySelector(".composer textarea"))==null||A.focus())}function E(n,f){var u,g;if((u=n.querySelector(".fix-verification"))==null||u.remove(),!f.resolvedAt||!["RESOLVED","CLOSED"].includes(f.status))return;const o=document.createElement("div");o.className="fix-verification",f.verification?o.textContent=f.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(c=>{c.onclick=async()=>{o.querySelectorAll("button").forEach(d=>{d.disabled=!0});try{await t.verifyFix(f.id,{result:c.dataset.result,resolvedAt:f.resolvedAt,note:o.querySelector("textarea").value}),await y(f.id)}catch(d){o.querySelector(".feedback-status").textContent=d.message,o.querySelectorAll("button").forEach(k=>{k.disabled=!1})}}})),(g=n.querySelector(".report-head"))==null||g.after(o)}function r(n,f){var g;let o=n.querySelector(".fix-rating");if(!["RESOLVED","CLOSED"].includes(f.status)||!f.ratingAsked){o==null||o.remove();return}o&&o.dataset.key===qe(f.rating)||(o||(o=document.createElement("div"),o.className="fix-rating",(g=n.querySelector(".fix-verification")||n.querySelector(".report-head"))==null||g.after(o)),l(o,f,f.rating||null))}function l(n,f,o,{justRated:u=!1}={}){var B;n.dataset.key=qe(o);const g=o!=null&&o.current?o.score:0,c=o?o.current?u?"Thanks — the team will see that.":`You rated this ${o.score} out of 5.`:`You rated an earlier fix ${o.score} out of 5. How did this one go?`:"How did we do?",d=u&&(o==null?void 0:o.current)&&!o.comment;n.innerHTML=`
|
|
1270
|
+
<p class="fr-q">${$(c)}</p>
|
|
1271
|
+
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1,2,3,4,5].map(w=>`
|
|
1272
|
+
<button type="button" data-score="${w}" aria-pressed="${w===g}" aria-label="${w} out of 5${w===1?", poor":w===5?", great":""}" class="${w<=g?"on":""}">${fe}</button>`).join("")}
|
|
1273
|
+
</div>
|
|
1274
|
+
${o!=null&&o.current&&o.comment?`<p class="fr-said">“${$(o.comment)}”</p>`:""}
|
|
1275
|
+
${d?`
|
|
1276
|
+
<div class="fr-note">
|
|
1277
|
+
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${o.score<=2?"What went wrong? (optional)":"Anything to add? (optional)"}"></textarea>
|
|
1278
|
+
<button type="button" data-act="rating-note">Add note</button>
|
|
1279
|
+
</div>`:""}
|
|
1280
|
+
${o?"":'<p class="fr-hint">1 is poor, 5 is great.</p>'}
|
|
1281
|
+
<p class="feedback-status" role="status"></p>`;const k=[...n.querySelectorAll("[data-score]")],L=w=>k.forEach(z=>z.classList.toggle("on",Number(z.dataset.score)<=w)),H=w=>n.querySelectorAll("button, textarea").forEach(z=>{z.disabled=w}),j=n.querySelector(".feedback-status");async function N(w,z){var A;H(!0),j.textContent="";try{const I=await t.rate(f.id,{score:w,comment:z});l(n,f,I,{justRated:!0}),(A=n.querySelector(".fr-note textarea"))==null||A.focus()}catch(I){j.textContent=I.message,H(!1),L(g)}}for(const w of k){const z=Number(w.dataset.score);w.addEventListener("mouseenter",()=>L(z)),w.addEventListener("focus",()=>L(z)),w.addEventListener("blur",()=>L(g)),w.addEventListener("click",()=>N(z))}n.querySelector(".stars").addEventListener("mouseleave",()=>L(g)),(B=n.querySelector('[data-act="rating-note"]'))==null||B.addEventListener("click",()=>{var z;const w=n.querySelector(".fr-note textarea").value.trim();if(!w){(z=n.querySelector(".fr-note"))==null||z.remove();return}N(o.score,w)})}async function S(n){const f=a.querySelector(".history.chatting"),o=f==null?void 0:f.querySelector(".thread");if(!o||i!==n)return;let u=null;try{u=await t.myReport(n)}catch{}if(e.closed||!u||i!==n)return;E(f,u),r(f,u);const g=me(o),c=Te(u.timeline);ce.get(o)!==c&&(o.innerHTML=c,ce.set(o,c)),b(f,u,n),g&&U(o);const d=f.querySelector(".report-head .pill");d&&(d.className=`pill ${String(u.status).toLowerCase()}`,d.textContent=se(u.status))}const T=t.on("update",n=>{!i||(n==null?void 0:n.bugId)!==i||(t.markReportRead(i),S(i))});e.onDestroy(()=>{T(),clearTimeout(p)}),(M=a.querySelector('[data-act="history"]'))==null||M.addEventListener("click",s),e.succeed=v,e.refreshThread=S,e.openReportId=()=>i}function qt({root:e,host:t,dock:a,client:h,onClose:i,preloadCall:v=()=>{},themeControls:x=null}){Ct(e);const s=h.config,y=()=>(x==null?void 0:x.label())||"",p=document.createElement("div");p.className=`scrim ${a.classList.contains("at-left")?"at-left":"at-right"} ${a.classList.contains("at-top")?"at-top":"at-bottom"}`,p.style.setProperty("--bc-dock-h",`${Math.round(a.getBoundingClientRect().height)}px`),p.innerHTML=`
|
|
1211
1282
|
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
|
|
1212
|
-
${
|
|
1283
|
+
${re({id:"bc-h",title:"Report a bug",sub:"We attach the page details for you.",theme:y()})}
|
|
1213
1284
|
<div class="body">
|
|
1214
1285
|
<div class="slot" role="alert"></div>
|
|
1215
1286
|
<!-- What the project's team is telling visitors. Drawn only when it
|
|
@@ -1220,21 +1291,21 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1220
1291
|
close by itself. Drawn only when the project offers any. -->
|
|
1221
1292
|
<div class="picks" hidden></div>
|
|
1222
1293
|
<div class="known" hidden></div>
|
|
1223
|
-
${
|
|
1294
|
+
${lt(s)}
|
|
1224
1295
|
</div>
|
|
1225
1296
|
<div class="foot">
|
|
1226
1297
|
<span class="note" aria-live="polite"></span>
|
|
1227
|
-
${
|
|
1298
|
+
${h.hasReports()?'<button class="quiet" type="button" data-act="history">Your reports</button>':""}
|
|
1228
1299
|
<span class="spacer"></span>
|
|
1229
1300
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
1230
1301
|
most cannot. Drawn here rather than as a second launcher because it
|
|
1231
1302
|
is the same errand as Send report — the difference is only whether
|
|
1232
1303
|
the reporter would rather say it than type it. -->
|
|
1233
|
-
<button class="ghost" type="button" data-act="call" hidden>${
|
|
1234
|
-
<button class="primary" type="button" data-act="send">Send report ${
|
|
1304
|
+
<button class="ghost" type="button" data-act="call" hidden>${J}Talk to the team</button>
|
|
1305
|
+
<button class="primary" type="button" data-act="send">Send report ${be}</button>
|
|
1235
1306
|
</div>
|
|
1236
1307
|
<div class="powered">Powered by
|
|
1237
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
1308
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Fe}</a>
|
|
1238
1309
|
</div>
|
|
1239
|
-
</div>`;const
|
|
1310
|
+
</div>`;const b=g=>p.querySelector(g),E=b(".slot"),r=[],l={client:h,cfg:s,root:e,host:t,dock:a,scrim:p,$:b,titleInput:b("#bc-title"),descInput:b("#bc-desc"),compose:b(".compose"),sendBtn:b('[data-act="send"]'),callBtn:b('[data-act="call"]'),historyBtn:b('[data-act="history"]'),note:b(".foot .note"),whoami:b(".whoami"),refsBox:b(".refs"),notices:b(".notices"),known:b(".known"),picks:b(".picks"),sending:!1,closed:!1,say:u,close:f,preloadCall:v,themeLabel:y,onDestroy:g=>{r.push(g)},refreshSendState:null,isRecording:null,stopRecording:null,holdForReference:null,answeredReference:null,pickedIssue:null,offerCall:null,callOffered:null,showLiveCall:null,mustSignIn:null,recheckSignIn:null,succeed:null,refreshThread:null,openReportId:null};ct(l),bt(l),vt(l),xt(l),yt(l),wt(l),kt(l),zt(l);const S=document.activeElement,T=document.documentElement.style,M=T.overflow;T.overflow="hidden";function n(){l.closed||(r.forEach(g=>g()),l.closed=!0,T.overflow=M,document.removeEventListener("keydown",o,!0),p.remove(),a.hidden=!1,t.style.opacity="",i==null||i())}function f(){var g;if(!l.closed){p.classList.add("closing"),setTimeout(n,160);try{(g=S==null?void 0:S.focus)==null||g.call(S)}catch{}}}function o(g){if(g.key==="Escape"){if(g.stopPropagation(),l.isRecording()){l.stopRecording({keep:!1});return}l.sending||f();return}if(g.key!=="Tab"||l.isRecording())return;const c=[...p.querySelectorAll("button:not(:disabled), input:not([hidden]), textarea, select, [href]")].filter(H=>H.offsetParent!==null||H===document.activeElement);if(!c.length)return;const d=c[0],k=c[c.length-1],L=p.getRootNode().activeElement;g.shiftKey&&L===d?(g.preventDefault(),k.focus()):!g.shiftKey&&L===k&&(g.preventDefault(),d.focus())}document.addEventListener("keydown",o,!0),p.addEventListener("click",g=>{g.target===p&&!l.sending&&f()}),b('[data-act="close"]').addEventListener("click",f),p.addEventListener("click",g=>{const c=g.target.closest('[data-act="theme"]');if(!c||!x)return;const d=x.cycle();c.title=`Theme: ${d.label}`,c.setAttribute("aria-label",`Theme: ${d.label}. Change theme`)});function u(g,c="err"){E.innerHTML=g?`<div class="msg ${c}">${c==="err"?Y:""}<span>${$(g)}</span></div>`:""}return e.appendChild(p),l.refreshSendState(),l.titleInput.focus(),{destroy:n,close:f}}function Ct(e){if(e.querySelector("style[data-panel]"))return;const t=document.createElement("style");t.setAttribute("data-panel",""),t.textContent=Ye;const a=e.querySelector("style");a?a.after(t):e.prepend(t)}const Ht=Object.freeze(Object.defineProperty({__proto__:null,openPanel:qt},Symbol.toStringTag,{value:"Module"})),It="0.19.0",Ce="__bugcatchChunks",Rt=e=>`${e}@${It}`;function At(e,t){const a=window[Ce]||(window[Ce]={});a[Rt(e)]=t}At("panel",Ht)})();
|
|
1240
1311
|
//# sourceMappingURL=bugcatch-panel.umd.js.map
|