@mrrocket/sdk 0.18.0 → 0.22.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +36 -1
  3. package/dist/api-client.d.ts +28 -4
  4. package/dist/api-client.js +30 -13
  5. package/dist/api-client.js.map +1 -1
  6. package/dist/browser/mrrocket-flows.js +8 -3
  7. package/dist/browser/mrrocket-messenger.js +38 -5
  8. package/dist/browser/mrrocket.js +1 -1
  9. package/dist/browser.d.ts +2 -2
  10. package/dist/browser.js +2 -1
  11. package/dist/browser.js.map +1 -1
  12. package/dist/client.d.ts +17 -1
  13. package/dist/client.js +25 -5
  14. package/dist/client.js.map +1 -1
  15. package/dist/core.d.ts +5 -1
  16. package/dist/core.js +1 -1
  17. package/dist/core.js.map +1 -1
  18. package/dist/feedback.js +161 -119
  19. package/dist/feedback.js.map +1 -1
  20. package/dist/flows-ui.d.ts +1 -1
  21. package/dist/flows-ui.js +100 -72
  22. package/dist/flows-ui.js.map +1 -1
  23. package/dist/flows-web.js +2 -1
  24. package/dist/flows-web.js.map +1 -1
  25. package/dist/flows.d.ts +38 -6
  26. package/dist/flows.js +51 -17
  27. package/dist/flows.js.map +1 -1
  28. package/dist/i18n.d.ts +22 -0
  29. package/dist/i18n.js +74 -0
  30. package/dist/i18n.js.map +1 -0
  31. package/dist/index.d.ts +4 -1
  32. package/dist/index.js +5 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/messenger-ui.d.ts +9 -3
  35. package/dist/messenger-ui.js +324 -152
  36. package/dist/messenger-ui.js.map +1 -1
  37. package/dist/messenger.d.ts +3 -1
  38. package/dist/messenger.js +3 -2
  39. package/dist/messenger.js.map +1 -1
  40. package/dist/onboarding-report.d.ts +19 -0
  41. package/dist/onboarding-report.js +23 -0
  42. package/dist/onboarding-report.js.map +1 -0
  43. package/dist/onboarding-state.d.ts +3 -0
  44. package/dist/onboarding-state.js +7 -1
  45. package/dist/onboarding-state.js.map +1 -1
  46. package/dist/paywall.js +2 -1
  47. package/dist/paywall.js.map +1 -1
  48. package/dist/react-native/index.d.cts +93 -8
  49. package/dist/react-native/index.d.ts +93 -8
  50. package/dist/react-native/index.js +819 -511
  51. package/dist/react-native/index.js.map +1 -1
  52. package/dist/server.d.ts +4 -2
  53. package/dist/server.js +2 -2
  54. package/dist/server.js.map +1 -1
  55. package/dist/styles-css.d.ts +1 -1
  56. package/dist/styles-css.js +35 -2
  57. package/dist/styles-css.js.map +1 -1
  58. package/dist/survey.js +18 -14
  59. package/dist/survey.js.map +1 -1
  60. package/dist/ui.d.ts +2 -0
  61. package/dist/ui.js +15 -12
  62. package/dist/ui.js.map +1 -1
  63. package/package.json +6 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/styles-css.ts"],"sourcesContent":["/** The widgets' stylesheet as a string, without React, so the script tag's widgets (src/script) inject the same CSS. */\nexport const STYLE_ID = \"ckw-styles\";\n\n/** The one stylesheet for every Cockpit widget. Everything is scoped under `.ckw-root` and prefixed `ckw-`. */\nexport const CSS = `\n.ckw-root{--ckw-accent:#3f76ff;--ckw-accent-ink:#fff;--ckw-bg:#fff;--ckw-bg2:#f7f7f8;--ckw-bg3:#eeeff1;--ckw-fg:#1c1d20;--ckw-fg2:#5d6068;--ckw-fg3:#8b8e96;--ckw-line:#e4e5e8;--ckw-danger:#d92d20;--ckw-shadow:0 8px 30px rgba(16,18,24,.16);--ckw-card:#fff;--ckw-col:#f5f6f7;--ckw-lift:0 1px 2px rgba(16,18,24,.06),0 0 0 1px rgba(16,18,24,.07);--ckw-raise:0 0 0 1px rgba(16,18,24,.05),0 1px 2px rgba(16,18,24,.05),0 6px 18px rgba(16,18,24,.06);--ckw-float:0 0 0 1px rgba(16,18,24,.06),0 18px 50px rgba(16,18,24,.2);--ckw-soft:0 2px 8px rgba(16,18,24,.05),0 18px 48px rgba(16,18,24,.15);\nfont-size:14px;line-height:1.45;font-family:inherit;color:var(--ckw-fg);box-sizing:border-box;-webkit-font-smoothing:antialiased}\n.ckw-root[data-theme=dark]{--ckw-bg:#111214;--ckw-bg2:#1a1b1f;--ckw-bg3:#26272c;--ckw-fg:#f1f2f4;--ckw-fg2:#a9acb3;--ckw-fg3:#7a7d86;--ckw-line:#2a2b31;--ckw-shadow:0 8px 30px rgba(0,0,0,.5);--ckw-card:#1b1c20;--ckw-col:#16171a;--ckw-lift:0 0 0 1px rgba(255,255,255,.07);--ckw-raise:0 0 0 1px rgba(255,255,255,.07);--ckw-float:0 0 0 1px rgba(255,255,255,.09),0 18px 50px rgba(0,0,0,.55);--ckw-soft:0 0 0 1px rgba(255,255,255,.07),0 18px 50px rgba(0,0,0,.55)}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto]{--ckw-bg:#111214;--ckw-bg2:#1a1b1f;--ckw-bg3:#26272c;--ckw-fg:#f1f2f4;--ckw-fg2:#a9acb3;--ckw-fg3:#7a7d86;--ckw-line:#2a2b31;--ckw-shadow:0 8px 30px rgba(0,0,0,.5);--ckw-card:#1b1c20;--ckw-col:#16171a;--ckw-lift:0 0 0 1px rgba(255,255,255,.07);--ckw-raise:0 0 0 1px rgba(255,255,255,.07);--ckw-float:0 0 0 1px rgba(255,255,255,.09),0 18px 50px rgba(0,0,0,.55);--ckw-soft:0 0 0 1px rgba(255,255,255,.07),0 18px 50px rgba(0,0,0,.55)}}\n.ckw-root *,.ckw-root *::before,.ckw-root *::after{box-sizing:border-box}\n.ckw-root{--ckw-r-panel:22px;--ckw-r-bubble:18px;--ckw-r-tail:6px;--ckw-r-card:16px;--ckw-r-field:20px;--ckw-r-pill:999px;--ckw-r-fab:999px}\n.ckw-root[data-corners=soft]{--ckw-r-panel:14px;--ckw-r-bubble:12px;--ckw-r-tail:4px;--ckw-r-card:10px;--ckw-r-field:10px;--ckw-r-pill:10px;--ckw-r-fab:18px}\n.ckw-root[data-corners=square]{--ckw-r-panel:6px;--ckw-r-bubble:6px;--ckw-r-tail:2px;--ckw-r-card:4px;--ckw-r-field:4px;--ckw-r-pill:4px;--ckw-r-fab:8px}\n.ckw-root[data-font=system]{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif}\n:where(.ckw-root) :where(button,input,select,textarea){font:inherit;color:inherit;margin:0}\n.ckw-root button{cursor:pointer}\n.ckw-root :focus-visible{outline:2px solid var(--ckw-accent);outline-offset:2px}\n.ckw-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}\n.ckw-title{font-size:20px;font-weight:600;margin:0;letter-spacing:-.01em}\n.ckw-sub{color:var(--ckw-fg2);margin:2px 0 0;font-size:13px}\n.ckw-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border-radius:8px;border:1px solid var(--ckw-line);background:var(--ckw-bg);font-weight:500;font-size:13px;white-space:nowrap}\n.ckw-btn:hover{background:var(--ckw-bg2)}\n.ckw-btn[disabled]{opacity:.55;cursor:not-allowed}\n.ckw-btn-primary{background:var(--ckw-accent);border-color:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-btn-primary:hover{background:var(--ckw-accent);filter:brightness(1.08)}\n.ckw-btn-ghost{border-color:transparent;background:transparent;color:var(--ckw-fg2)}\n.ckw-icon{width:16px;height:16px;flex:none;display:block}\n.ckw-tabs{display:flex;gap:4px;border-bottom:1px solid var(--ckw-line);margin-bottom:12px;overflow-x:auto}\n.ckw-tab{background:none;border:0;border-bottom:2px solid transparent;padding:8px 10px;margin-bottom:-1px;color:var(--ckw-fg2);font-weight:500;font-size:13px;white-space:nowrap}\n.ckw-tab[aria-selected=true]{color:var(--ckw-fg);border-bottom-color:var(--ckw-accent)}\n.ckw-tools{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:10px}\n.ckw-input,.ckw-select,.ckw-textarea{width:100%;border:1px solid var(--ckw-line);border-radius:8px;background:var(--ckw-bg);padding:7px 10px;font-size:14px;min-height:34px}\n.ckw-input::placeholder,.ckw-textarea::placeholder{color:var(--ckw-fg3)}\n.ckw-textarea{resize:vertical;min-height:72px}\n.ckw-search{flex:1 1 160px;min-width:0}\n.ckw-seg{display:inline-flex;border:1px solid var(--ckw-line);border-radius:8px;overflow:hidden}\n.ckw-seg button{border:0;background:var(--ckw-bg);padding:0 10px;height:32px;font-size:13px;color:var(--ckw-fg2)}\n.ckw-seg button[aria-pressed=true]{background:var(--ckw-bg3);color:var(--ckw-fg);font-weight:500}\n.ckw-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}\n.ckw-chip{border:1px solid var(--ckw-line);background:var(--ckw-bg);border-radius:999px;padding:3px 10px;font-size:12px;color:var(--ckw-fg2)}\n.ckw-chip[aria-pressed=true],.ckw-chip[aria-checked=true]{background:var(--ckw-fg);color:var(--ckw-bg);border-color:var(--ckw-fg)}\n.ckw-list{list-style:none;margin:0;padding:0;border:1px solid var(--ckw-line);border-radius:8px;overflow:hidden}\n.ckw-list>li+li{border-top:1px solid var(--ckw-line)}\n.ckw-row{display:flex;gap:12px;align-items:flex-start;padding:10px 12px;background:var(--ckw-bg)}\n.ckw-row:hover{background:var(--ckw-bg2)}\n.ckw-vote{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;width:44px;min-height:48px;border:1px solid var(--ckw-line);border-radius:8px;background:var(--ckw-bg);font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;padding:4px 0;color:var(--ckw-fg2)}\n.ckw-vote:hover{border-color:var(--ckw-accent);color:var(--ckw-accent)}\n.ckw-vote[aria-pressed=true]{background:var(--ckw-accent);border-color:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-vote-sm{width:auto;min-height:0;flex-direction:row;gap:4px;padding:2px 8px}\n.ckw-main{flex:1;min-width:0;text-align:left}\n.ckw-link{display:block;width:100%;text-align:left;background:none;border:0;padding:0;font-weight:600;font-size:14px;color:var(--ckw-fg);overflow-wrap:anywhere}\n.ckw-link:hover{color:var(--ckw-accent)}\n.ckw-excerpt{margin:2px 0 0;color:var(--ckw-fg2);font-size:13px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}\n.ckw-meta{display:flex;gap:8px;align-items:center;margin-top:6px;color:var(--ckw-fg3);font-size:12px;flex-wrap:wrap}\n.ckw-pill{display:inline-flex;align-items:center;border-radius:999px;padding:1px 8px;font-size:11px;font-weight:600;background:var(--ckw-bg3);color:var(--ckw-fg2)}\n.ckw-pill[data-s=planned]{background:rgba(63,118,255,.14);color:#3f76ff}\n.ckw-pill[data-s=progress]{background:rgba(245,158,11,.16);color:#b45309}\n.ckw-pill[data-s=shipped]{background:rgba(22,163,74,.15);color:#15803d}\n.ckw-root[data-theme=dark] .ckw-pill[data-s=progress]{color:#fbbf24}\n.ckw-root[data-theme=dark] .ckw-pill[data-s=shipped]{color:#4ade80}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto] .ckw-pill[data-s=progress]{color:#fbbf24}.ckw-root[data-theme=auto] .ckw-pill[data-s=shipped]{color:#4ade80}}\n.ckw-stat{display:inline-flex;align-items:center;gap:4px}\n.ckw-empty{padding:64px 16px;text-align:center;color:var(--ckw-fg2)}\n.ckw-empty-icon{display:block;width:56px;height:56px;margin:0 auto 14px;opacity:.3}\n.ckw-error{border:1px solid color-mix(in srgb,var(--ckw-danger) 40%,transparent);background:color-mix(in srgb,var(--ckw-danger) 8%,transparent);color:var(--ckw-danger);border-radius:8px;padding:8px 10px;font-size:13px;display:flex;gap:8px;align-items:center;justify-content:space-between;margin-bottom:10px}\n.ckw-skel{height:68px;border-radius:8px;background:var(--ckw-bg2);animation:ckw-sh 1.2s ease-in-out infinite;margin-bottom:6px}\n@keyframes ckw-sh{50%{opacity:.5}}\n@media (prefers-reduced-motion:reduce){.ckw-skel,.ckw-scrim,.ckw-modal{animation:none}.ckw-root *{transition:none!important}}\n.ckw-form{display:flex;flex-direction:column;gap:10px;border:1px solid var(--ckw-line);border-radius:8px;padding:12px;margin-bottom:12px;background:var(--ckw-bg)}\n.ckw-field{display:flex;flex-direction:column;gap:4px}\n.ckw-label{font-size:12px;font-weight:600;color:var(--ckw-fg2)}\n.ckw-actions{display:flex;gap:8px;justify-content:flex-end}\n.ckw-dupes{border:1px solid var(--ckw-line);border-radius:8px;background:var(--ckw-bg2);padding:8px 10px;font-size:13px}\n.ckw-dupes p{margin:0 0 4px;color:var(--ckw-fg2);font-size:12px}\n.ckw-dupe{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:3px 0}\n.ckw-dupe span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-team{margin-left:6px;background:var(--ckw-accent);color:var(--ckw-accent-ink);border-radius:4px;padding:0 5px;font-size:10px;font-weight:700;text-transform:uppercase;vertical-align:1px}\n.ckw-time{color:var(--ckw-fg3);font-size:12px;margin-left:6px}\n.ckw-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n/* Board */\n.ckw-board{width:100%;max-width:1160px;margin:0 auto;background:var(--ckw-bg);min-width:0}\n.ckw-board.ckw-full{max-width:none;min-height:100%;min-height:100dvh}\n.ckw-board.ckw-full>.ckw-body-wrap{max-width:1160px;margin:0 auto;padding:0 16px 56px}\n.ckw-top{position:sticky;top:0;z-index:5;background:color-mix(in srgb,var(--ckw-bg) 88%,transparent);backdrop-filter:saturate(1.4) blur(10px);-webkit-backdrop-filter:saturate(1.4) blur(10px);border-bottom:1px solid var(--ckw-line);margin-bottom:24px}\n.ckw-top-row{max-width:1160px;margin:0 auto;padding:10px 16px;display:flex;align-items:center;gap:16px;flex-wrap:wrap}\n.ckw-brand{display:inline-flex;align-items:center;gap:10px;font-weight:650;font-size:15px;color:var(--ckw-fg);background:none;border:0;padding:4px 2px;border-radius:8px;min-width:0}\n.ckw-brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}\n.ckw-brand img{width:28px;height:28px;border-radius:7px;object-fit:cover;outline:1px solid oklch(0 0 0/.1);outline-offset:-1px;flex:none}\n.ckw-root[data-theme=dark] .ckw-brand img{outline-color:oklch(1 0 0/.1)}\n.ckw-brand-mark{width:28px;height:28px;border-radius:7px;background:var(--ckw-accent);color:var(--ckw-accent-ink);display:inline-flex;align-items:center;justify-content:center;font-size:14px;flex:none}\n.ckw-nav{display:flex;gap:2px;flex:1;min-width:0}\n.ckw-nav-tab{background:none;border:0;border-radius:8px;padding:0 12px;height:34px;color:var(--ckw-fg2);font-weight:550;font-size:14px;white-space:nowrap;transition:background-color .1s linear,color .1s linear}\n.ckw-nav-tab:hover{color:var(--ckw-fg);background:var(--ckw-bg2)}\n.ckw-nav-tab[aria-selected=true]{color:var(--ckw-fg);background:var(--ckw-bg3)}\n.ckw-top-tools{display:flex;align-items:center;gap:6px;margin-left:auto}\n.ckw-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:8px;border:0;background:none;color:var(--ckw-fg2);flex:none}\n.ckw-icon-btn:hover{background:var(--ckw-bg2);color:var(--ckw-fg)}\n.ckw-searchbox{display:flex;align-items:center;border-radius:8px;transition:background-color .1s linear}\n.ckw-search-input{width:0;padding:0;border:0;background:none;outline:none;font-size:14px;height:34px;transition:width .15s cubic-bezier(.2,0,0,1)}\n.ckw-searchbox[data-open]{background:var(--ckw-bg2)}\n.ckw-searchbox[data-open] .ckw-search-input{width:180px;padding-right:10px}\n.ckw-searchbox:focus-within{outline:2px solid var(--ckw-accent);outline-offset:0}\n.ckw-root .ckw-search-input:focus-visible{outline:none}\n.ckw-search-input::-webkit-search-cancel-button{display:none}\n.ckw-submit{height:34px}\n.ckw-btn,.ckw-vote,.ckw-upvote,.ckw-icon-btn{transition-property:background-color,border-color,color,scale;transition-duration:.1s;transition-timing-function:linear}\n.ckw-btn:active:not([disabled]),.ckw-vote:active,.ckw-upvote:active,.ckw-icon-btn:active{scale:.96}\n.ckw-intro{margin:0 0 20px}\n.ckw-intro h1{font-size:24px;font-weight:650;letter-spacing:-.02em;margin:0;text-wrap:balance}\n.ckw-intro p{margin:4px 0 0;color:var(--ckw-fg2);font-size:14px;text-wrap:pretty}\n.ckw-note{display:flex;align-items:center;justify-content:space-between;gap:8px;border-radius:10px;padding:6px 6px 6px 12px;margin-bottom:14px;background:color-mix(in srgb,var(--ckw-accent) 10%,transparent);color:var(--ckw-fg);font-size:13px;font-weight:500}\n.ckw-tools .ckw-chips-inline{margin:0}\n.ckw-posts{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}\n.ckw-post{position:relative;display:flex;gap:14px;align-items:flex-start;padding:14px 16px;border-radius:12px;background:var(--ckw-card);box-shadow:var(--ckw-lift);transition:box-shadow .1s linear}\n.ckw-post:hover{box-shadow:var(--ckw-lift),0 4px 14px rgba(16,18,24,.06)}\n.ckw-post .ckw-vote,.ckw-card .ckw-vote{position:relative;z-index:1}\n.ckw-stretch::after{content:\"\";position:absolute;inset:0;border-radius:inherit}\n.ckw-post .ckw-link,.ckw-card .ckw-link{font-size:15px;font-weight:600;text-wrap:pretty}\n.ckw-dot-sep{color:var(--ckw-fg3)}\n.ckw-type{display:inline-flex;align-items:center;gap:5px;border-radius:6px;padding:1px 7px;font-size:11.5px;font-weight:600;color:var(--ckw-fg2);background:var(--ckw-bg2);white-space:nowrap;width:max-content}\n.ckw-type::before{content:\"\";width:6px;height:6px;border-radius:50%;background:var(--ckw-fg3)}\n.ckw-type[data-tone=blue]::before{background:#3f76ff}\n.ckw-type[data-tone=red]::before{background:#ef4444}\n.ckw-type[data-tone=violet]::before{background:#8b5cf6}\n.ckw-type[data-tone=green]::before{background:#22c55e}\n.ckw-av{width:22px;height:22px;border-radius:50%;flex:none;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:650;background:var(--ckw-bg3);color:var(--ckw-fg2)}\n.ckw-av[data-team]{background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-count{font-weight:500;color:var(--ckw-fg3);font-variant-numeric:tabular-nums;margin-left:2px}\n.ckw-empty p{margin:0 0 12px}\n.ckw-empty p:only-child{margin:0}\n/* Roadmap */\n.ckw-cols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;align-items:start}\n.ckw-col{background:var(--ckw-col);border-radius:14px;padding:6px;min-width:0}\n.ckw-col-head{padding:8px 8px 10px}\n.ckw-col-head h3{display:flex;align-items:center;gap:8px;margin:0;font-size:14px;font-weight:650}\n.ckw-col-head p{margin:2px 0 0 16px;font-size:12px;color:var(--ckw-fg3)}\n.ckw-sdot{width:8px;height:8px;border-radius:50%;background:var(--ckw-fg3);flex:none}\n.ckw-sdot[data-s=planned]{background:#3f76ff}\n.ckw-sdot[data-s=progress]{background:#f59e0b}\n.ckw-sdot[data-s=shipped]{background:#22c55e}\n.ckw-col-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}\n.ckw-col-empty{margin:0;padding:24px 8px;text-align:center;font-size:12px;color:var(--ckw-fg3)}\n.ckw-col .ckw-skel{margin:0 0 6px;height:96px;background:var(--ckw-card)}\n.ckw-card{position:relative;display:flex;flex-direction:column;gap:6px;padding:12px;border-radius:8px;background:var(--ckw-card);box-shadow:var(--ckw-lift);transition:box-shadow .1s linear}\n.ckw-card:hover{box-shadow:var(--ckw-lift),0 4px 14px rgba(16,18,24,.07)}\n.ckw-card .ckw-link{font-size:14px}\n.ckw-card .ckw-excerpt{margin:0}\n.ckw-card-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:4px}\n.ckw-who{display:inline-flex;align-items:center;gap:6px;min-width:0;font-size:12px;color:var(--ckw-fg2)}\n.ckw-who span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-vote-sm{height:28px;border-radius:7px;font-size:12px}\n@media (max-width:900px){.ckw-cols{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;margin:0 -16px;padding:0 16px 8px;scroll-padding:0 16px}.ckw-col{flex:0 0 min(82%,300px);scroll-snap-align:start}}\n/* Post page */\n.ckw-back{display:inline-flex;align-items:center;gap:4px;background:none;border:0;padding:6px 8px 6px 4px;margin:0 0 12px -4px;border-radius:8px;color:var(--ckw-fg2);font-size:13px;font-weight:550}\n.ckw-back:hover{color:var(--ckw-fg);background:var(--ckw-bg2)}\n.ckw-back-icon{display:inline-block;transform:rotate(-90deg);line-height:0}\n.ckw-detail-grid{display:grid;grid-template-columns:minmax(0,1fr) 260px;gap:32px;align-items:start}\n.ckw-detail-title{margin:0 0 8px;font-size:22px;font-weight:650;letter-spacing:-.015em;overflow-wrap:anywhere;text-wrap:balance}\n.ckw-byline{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ckw-fg2)}\n.ckw-body{white-space:pre-wrap;overflow-wrap:anywhere;color:var(--ckw-fg);margin:16px 0 0;font-size:14.5px;line-height:1.6;text-wrap:pretty}\n.ckw-h{display:flex;align-items:center;gap:6px;font-size:14px;font-weight:650;margin:28px 0 10px;padding-top:20px;border-top:1px solid var(--ckw-line)}\n.ckw-composer{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}\n.ckw-composer .ckw-actions{align-items:center}\n.ckw-as{margin:0 auto 0 0}\n.ckw-comment{display:flex;gap:10px;padding:12px 0;border-top:1px solid var(--ckw-line)}\n.ckw-comment b{font-size:13px}\n.ckw-comment p{margin:3px 0 0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px}\n.ckw-side{position:sticky;top:76px;display:flex;flex-direction:column;gap:12px;padding:14px;border-radius:12px;background:var(--ckw-card);box-shadow:var(--ckw-lift)}\n.ckw-upvote{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;border-radius:8px;border:1px solid var(--ckw-line);background:var(--ckw-bg);font-weight:600;font-size:14px;color:var(--ckw-fg)}\n.ckw-upvote b{margin-left:auto;font-variant-numeric:tabular-nums}\n.ckw-upvote:hover{border-color:var(--ckw-accent);color:var(--ckw-accent)}\n.ckw-upvote[aria-pressed=true]{background:var(--ckw-accent);border-color:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-facts{margin:0;display:flex;flex-direction:column;gap:10px;font-size:13px}\n.ckw-facts div{display:flex;justify-content:space-between;align-items:center;gap:8px}\n.ckw-facts dt{color:var(--ckw-fg3)}\n.ckw-facts dd{margin:0;color:var(--ckw-fg)}\n@media (max-width:760px){.ckw-detail-grid{grid-template-columns:1fr;gap:16px}.ckw-side{position:static;order:-1}}\n/* Changelog */\n.ckw-log{max-width:820px}\n.ckw-entry{display:grid;grid-template-columns:160px minmax(0,1fr);gap:24px;padding:20px 0;border-top:1px solid var(--ckw-line)}\n.ckw-entry:first-child{border-top:0;padding-top:4px}\n.ckw-entry time{font-size:13px;color:var(--ckw-fg3);padding-top:2px}\n.ckw-entry h3{font-size:17px;font-weight:650;margin:0 0 6px;text-wrap:balance}\n.ckw-entry p{margin:0;color:var(--ckw-fg2);white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.6}\n@media (max-width:640px){.ckw-entry{grid-template-columns:1fr;gap:4px}}\n/* Dialog */\n.ckw-scrim{position:fixed;inset:0;z-index:2147483002;background:rgba(0,0,0,.36);display:flex;align-items:center;justify-content:center;padding:16px;animation:ckw-fade .15s ease-out}\n.ckw-modal{width:100%;max-width:520px;max-height:calc(100dvh - 32px);overflow-y:auto;background:var(--ckw-bg);color:var(--ckw-fg);border-radius:14px;box-shadow:var(--ckw-shadow),0 0 0 1px var(--ckw-line);animation:ckw-in .18s ease-out}\n.ckw-modal-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 10px 4px 18px}\n.ckw-modal-head h2{margin:0;font-size:16px;font-weight:650}\n.ckw-modal-body{display:flex;flex-direction:column;gap:12px;padding:8px 18px 18px}\n@keyframes ckw-fade{from{opacity:0}}\n@media (max-width:520px){.ckw-scrim{align-items:flex-end;padding:0}.ckw-modal{max-width:none;border-radius:14px 14px 0 0;max-height:92dvh}}\n.ckw-pair{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n@media (max-width:480px){.ckw-pair{grid-template-columns:1fr}}\n.ckw-fine{margin:-4px 0 0;font-size:12px;color:var(--ckw-fg3);text-wrap:pretty}\n.ckw-opt-l{font-weight:500;color:var(--ckw-fg3)}\n.ckw-foot{text-align:center;font-size:12px;color:var(--ckw-fg3);margin:0;padding:0 16px 24px}\n.ckw-linkish{background:none;border:0;padding:0;color:var(--ckw-fg2);text-decoration:underline;font-size:12px}\n@media (max-width:720px){.ckw-top-row{gap:8px;padding:8px 12px}.ckw-nav{order:3;flex-basis:100%;overflow-x:auto;margin:0 -4px}.ckw-submit span{display:none}.ckw-submit{width:34px;padding:0}.ckw-searchbox[data-open] .ckw-search-input{width:120px}.ckw-top{margin-bottom:16px}.ckw-board.ckw-full>.ckw-body-wrap{padding:0 12px 40px}.ckw-post{padding:12px}.ckw-intro h1{font-size:20px}}\n/* Floating widget */\n.ckw-fab{position:fixed;z-index:2147483000;bottom:20px;display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 16px;border-radius:999px;border:0;background:var(--ckw-accent);color:var(--ckw-accent-ink);font-weight:600;font-size:14px;box-shadow:var(--ckw-shadow)}\n.ckw-fab[data-pos=bottom-right],.ckw-pop[data-pos=bottom-right]{right:20px}\n.ckw-fab[data-pos=bottom-left],.ckw-pop[data-pos=bottom-left]{left:20px}\n.ckw-pop{position:fixed;z-index:2147483001;bottom:70px;width:380px;max-width:calc(100vw - 24px);max-height:min(560px,calc(100vh - 90px));display:flex;flex-direction:column;background:var(--ckw-bg);border:1px solid var(--ckw-line);border-radius:12px;box-shadow:var(--ckw-shadow);overflow:hidden}\n.ckw-pop-head{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--ckw-line);font-weight:600}\n.ckw-pop-body{padding:12px;overflow-y:auto;flex:1}\n.ckw-pop-foot{padding:8px 12px;border-top:1px solid var(--ckw-line);display:flex;justify-content:space-between;align-items:center;font-size:13px}\n.ckw-pop-foot a{color:var(--ckw-accent);text-decoration:none;font-weight:500}\n.ckw-pop .ckw-list{border:0;border-radius:0}\n.ckw-pop .ckw-row{padding:8px 0}\n.ckw-pop .ckw-form{border:0;padding:0;margin:12px 0 0}\n@media (max-width:520px){.ckw-pop{left:0!important;right:0!important;bottom:0;width:100%;max-width:100%;border-radius:12px 12px 0 0;max-height:85vh}.ckw-fab{bottom:14px}.ckw-fab[data-pos=bottom-right]{right:14px}.ckw-fab[data-pos=bottom-left]{left:14px}}\n/* Messenger (messenger-ui.ts). Motion: one soft ease (.32,.72,0,1) for things that arrive, a quick ease-in for things that leave. */\n.ckw-msgr-fab{position:fixed;bottom:20px;height:52px;padding:0 20px 0 16px;gap:8px;font-size:15px;box-shadow:0 1px 2px rgba(16,18,24,.1),0 6px 20px rgba(16,18,24,.16);transition:transform .3s cubic-bezier(.32,.72,0,1),box-shadow .2s linear}\n.ckw-msgr-fab:hover{transform:scale(1.05);box-shadow:0 1px 2px rgba(16,18,24,.1),0 10px 28px rgba(16,18,24,.2)}\n.ckw-msgr-fab:active{transform:scale(.94);transition-duration:.1s}\n.ckw-msgr-round{width:56px;height:56px;padding:0;justify-content:center}\n.ckw-msgr-fab{border-radius:var(--ckw-r-fab)}\n.ckw-msgr-fab-ic{position:relative;display:block;width:20px;height:20px;flex:none}\n.ckw-msgr-round .ckw-msgr-fab-ic{width:27px;height:27px}\n.ckw-msgr-fab .ckw-cut{stroke:var(--ckw-accent)}\n.ckw-msgr-fab-i{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;transition:transform .38s cubic-bezier(.32,.72,0,1),opacity .2s linear}\n.ckw-msgr-fab-i .ckw-icon{width:auto;height:auto}\n.ckw-msgr-fab-i[data-i=x],.ckw-msgr-fab[data-open] .ckw-msgr-fab-i[data-i=chat]{opacity:0;transform:rotate(-90deg) scale(.4)}\n.ckw-msgr-fab[data-open] .ckw-msgr-fab-i[data-i=chat]{transform:rotate(90deg) scale(.4)}\n.ckw-msgr-fab[data-open] .ckw-msgr-fab-i[data-i=x]{opacity:1;transform:none}\n.ckw-msgr-fab-i[data-i=x] .ckw-icon{stroke-width:2.2}\n.ckw-msgr-count{position:absolute;top:-2px;right:-2px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:#ef4444;color:#fff;font-size:10.5px;font-weight:700;line-height:18px;text-align:center;box-shadow:0 0 0 2px var(--ckw-bg);font-variant-numeric:tabular-nums;animation:ckw-badge .4s cubic-bezier(.34,1.56,.64,1)}\n@keyframes ckw-badge{from{transform:scale(0)}}\n.ckw-msgr-av{width:36px;height:36px;border-radius:50%;flex:none;display:inline-flex;align-items:center;justify-content:center;background:var(--ckw-accent);color:var(--ckw-accent-ink);font-size:15px;font-weight:700;line-height:1}\n.ckw-msgr-av-sm{width:26px;height:26px;font-size:12px}\n.ckw-msgr-online{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ckw-fg2)}\n.ckw-msgr-online::before{content:\"\";width:7px;height:7px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 3px color-mix(in srgb,#22c55e 22%,transparent);flex:none}\n/* Floating card over the closed launcher: a new answer */\n.ckw-msgr-preview{position:fixed;z-index:2147483000;bottom:92px;width:320px;max-width:calc(100vw - 32px);transform-origin:bottom right;animation:ckw-rise .34s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-preview[data-pos=bottom-right]{right:20px}\n.ckw-msgr-preview[data-pos=bottom-left]{left:20px;transform-origin:bottom left}\n.ckw-msgr-preview[data-out]{animation:ckw-sink .16s cubic-bezier(.4,0,1,1) forwards;pointer-events:none}\n@keyframes ckw-rise{from{opacity:0;transform:translateY(10px) scale(.94)}}\n@keyframes ckw-sink{to{opacity:0;transform:translateY(6px) scale(.97)}}\n.ckw-msgr-preview-card{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;padding:14px 40px 14px 16px;border:0;border-radius:calc(var(--ckw-r-card) + 2px);background:var(--ckw-bg);box-shadow:var(--ckw-soft);transition:transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-preview-card:hover{transform:translateY(-2px)}\n.ckw-msgr-preview-main{display:flex;flex-direction:column;gap:2px;min-width:0}\n.ckw-msgr-preview-who{font-size:12px;font-weight:600;color:var(--ckw-fg3)}\n.ckw-msgr-preview-text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:pre-wrap;overflow-wrap:anywhere}\n.ckw-msgr-preview-x{position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:50%;border:0;background:transparent;color:var(--ckw-fg3);display:flex;align-items:center;justify-content:center;padding:0;transition:background-color .12s linear,color .12s linear}\n.ckw-msgr-preview-x:hover{background:var(--ckw-bg2);color:var(--ckw-fg)}\n/* The panel */\n.ckw-msgr{bottom:92px;width:400px;height:min(680px,calc(100vh - 112px));max-height:none;border:0;border-radius:var(--ckw-r-panel);box-shadow:var(--ckw-soft);transform-origin:bottom right;animation:ckw-msgr-in .42s cubic-bezier(.32,.72,0,1);transition:width .36s cubic-bezier(.32,.72,0,1),height .36s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr[data-pos=bottom-left]{transform-origin:bottom left}\n.ckw-msgr[data-wide]{width:680px;height:calc(100vh - 112px);max-height:860px}\n.ckw-msgr[data-still]{animation:none}\n.ckw-msgr[data-out]{animation:ckw-msgr-out .2s cubic-bezier(.4,0,1,1) forwards;pointer-events:none}\n@keyframes ckw-msgr-in{from{opacity:0;transform:translateY(20px) scale(.9)}}\n@keyframes ckw-msgr-out{to{opacity:0;transform:translateY(14px) scale(.94)}}\n.ckw-msgr-bar{position:relative;z-index:2;display:flex;align-items:center;gap:8px;padding:12px 12px 10px;background:var(--ckw-bg);flex:none;transition:background-color .25s linear,color .25s linear}\n.ckw-msgr-lead,.ckw-msgr-trail{display:flex;align-items:center;gap:2px;flex:1;min-width:0}\n.ckw-msgr-trail{justify-content:flex-end}\n.ckw-msgr-ib{width:34px;height:34px;padding:0;flex:none;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:transparent;color:var(--ckw-fg2);transition:background-color .12s linear,transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-ib:hover,.ckw-msgr-ib[aria-expanded=true]{background:var(--ckw-bg3);color:var(--ckw-fg)}\n.ckw-msgr-ib:active{transform:scale(.9)}\n.ckw-msgr-ib[aria-current=page]{color:var(--ckw-fg)}\n.ckw-msgr-x{display:none}\n.ckw-msgr-count-tab{top:-1px;right:-3px;min-width:0;width:8px;height:8px;padding:0;font-size:0;line-height:0;box-shadow:0 0 0 2px var(--ckw-bg)}\n.ckw-msgr-menu{position:absolute;z-index:3;top:52px;right:12px;min-width:200px;padding:6px;border-radius:14px;background:var(--ckw-bg);box-shadow:var(--ckw-float);display:flex;flex-direction:column;transform-origin:top right;animation:ckw-menu-in .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-menu[data-out]{animation:ckw-menu-out .12s cubic-bezier(.4,0,1,1) forwards}\n@keyframes ckw-menu-in{from{opacity:0;transform:translateY(-4px) scale(.94)}}\n@keyframes ckw-menu-out{to{opacity:0;transform:scale(.96)}}\n.ckw-msgr-menu-h{padding:6px 10px 4px;font-size:12px;font-weight:600;color:var(--ckw-fg3)}\n.ckw-msgr-menu-i{display:flex;align-items:center;gap:10px;height:36px;padding:0 10px;border:0;border-radius:9px;background:none;font-size:14px;text-align:left;color:var(--ckw-fg)}\n.ckw-msgr-menu-i:hover,.ckw-msgr-menu-i:focus-visible{background:var(--ckw-bg2)}\n.ckw-msgr-menu-i .ckw-icon{color:var(--ckw-fg2)}\n.ckw-msgr-body{display:flex;flex-direction:column;gap:12px;background:var(--ckw-bg);padding:4px 16px 16px;overscroll-behavior:contain;scrollbar-width:thin}\n.ckw-msgr-enter>*{animation:ckw-view .3s cubic-bezier(.32,.72,0,1) backwards}\n.ckw-msgr-enter>:nth-child(2){animation-delay:.03s}\n.ckw-msgr-enter>:nth-child(3){animation-delay:.06s}\n.ckw-msgr-enter>:nth-child(n+4){animation-delay:.09s}\n@keyframes ckw-view{from{opacity:0;transform:translateY(8px)}}\n/* Home */\n.ckw-msgr-hero{display:flex;flex-direction:column;gap:6px;padding:10px 4px 8px}\n.ckw-msgr-brand{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--ckw-fg2);min-width:0}\n.ckw-msgr-brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-msgr-hello{margin:14px 0 0;font-size:28px;font-weight:650;letter-spacing:-.03em;line-height:1.12;text-wrap:balance;overflow-wrap:anywhere}\n.ckw-msgr-card{position:relative;display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:14px 16px;border:0;border-radius:var(--ckw-r-card);background:var(--ckw-bg2);transition:background-color .15s linear,box-shadow .15s linear,transform .25s cubic-bezier(.32,.72,0,1)}\nbutton.ckw-msgr-card:hover{background:var(--ckw-bg3)}\n.ckw-msgr-card-col .ckw-msgr-search{background:var(--ckw-bg)}\n.ckw-msgr-card .ckw-msgr-art:hover{background:var(--ckw-bg3)}\nbutton.ckw-msgr-card:active{transform:scale(.985)}\n.ckw-msgr-card-col{flex-direction:column;align-items:stretch;gap:2px;padding:8px}\n.ckw-msgr-card-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}\n.ckw-msgr-card-main b{font-size:15px;font-weight:650}\n.ckw-msgr-card-sub{color:var(--ckw-fg2);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.ckw-msgr-card-label{font-size:12px;font-weight:600;color:var(--ckw-fg3)}\n.ckw-msgr-card-meta{font-size:12px;color:var(--ckw-fg3)}\n.ckw-msgr-recent{flex-direction:column;align-items:stretch;gap:10px}\n.ckw-msgr-recent-row{display:flex;align-items:center;gap:12px;min-width:0}\n.ckw-msgr-recent-text{color:var(--ckw-fg);font-size:14px}\n.ckw-msgr-card .ckw-icon{color:var(--ckw-fg3)}\n.ckw-msgr-go{width:34px;height:34px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--ckw-accent) 12%,transparent);transition:transform .25s cubic-bezier(.32,.72,0,1)}\nbutton.ckw-msgr-card:hover .ckw-msgr-go{transform:translateX(2px)}\n.ckw-msgr-card .ckw-msgr-go .ckw-icon{color:var(--ckw-accent)}\n.ckw-msgr-badge{width:8px;height:8px;flex:none;border-radius:50%;background:var(--ckw-danger);font-size:0}\n/* Search */\n.ckw-msgr-search{display:flex;align-items:center;gap:10px;height:46px;padding:0 14px;border:1px solid transparent;border-radius:var(--ckw-r-field);background:var(--ckw-bg2);color:var(--ckw-fg3);cursor:text;transition:border-color .15s linear,box-shadow .15s linear,background-color .15s linear}\n.ckw-msgr-card-col .ckw-msgr-search{margin-bottom:4px;height:42px}\n.ckw-msgr-search:focus-within{border-color:var(--ckw-accent);background:var(--ckw-bg);box-shadow:0 0 0 4px color-mix(in srgb,var(--ckw-accent) 16%,transparent);color:var(--ckw-accent)}\n.ckw-msgr-search-in{flex:1;min-width:0;border:0;background:transparent;outline:none;font-size:14.5px;color:var(--ckw-fg)}\n.ckw-root .ckw-msgr-search-in:focus-visible{outline:none}\n.ckw-msgr-search-in::placeholder{color:var(--ckw-fg3)}\n.ckw-msgr-search-in::-webkit-search-cancel-button{display:none}\n.ckw-msgr-art{display:flex;align-items:center;gap:8px;width:100%;text-align:left;padding:10px 8px;border:0;border-radius:10px;background:transparent;font-size:14px;transition:background-color .12s linear}\n.ckw-msgr-art:hover{background:var(--ckw-bg2)}\n.ckw-msgr-art-t{flex:1;min-width:0}\n.ckw-msgr-art .ckw-icon{color:var(--ckw-accent);transition:transform .25s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-art:hover .ckw-icon{transform:translateX(2px)}\n.ckw-msgr-skel{height:40px;margin:4px 0 0}\n/* Help */\n.ckw-msgr-help-h{margin:6px 0 2px;text-align:center;font-size:16px;font-weight:700;letter-spacing:-.01em}\n.ckw-msgr-hlist{display:flex;flex-direction:column;margin:0 -8px}\n.ckw-msgr-hrow{display:flex;align-items:center;gap:12px;width:100%;padding:12px;border:0;border-radius:14px;background:transparent;text-align:left;transition:background-color .12s linear}\n.ckw-msgr-hrow+.ckw-msgr-hrow{box-shadow:0 -1px 0 var(--ckw-line)}\n.ckw-msgr-hrow:hover,.ckw-msgr-hrow:hover+.ckw-msgr-hrow{box-shadow:none}\n.ckw-msgr-hrow:hover{background:var(--ckw-bg2)}\n.ckw-msgr-hrow-main{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}\n.ckw-msgr-hrow-main b{font-size:14.5px;font-weight:650}\n.ckw-msgr-hrow-sub{font-size:13px;color:var(--ckw-fg2);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.4}\n.ckw-msgr-hrow-meta{font-size:12px;color:var(--ckw-fg3)}\n.ckw-msgr-hrow .ckw-icon{color:var(--ckw-fg3);transition:transform .25s cubic-bezier(.32,.72,0,1),color .12s linear}\n.ckw-msgr-hrow:hover .ckw-icon{color:var(--ckw-fg);transform:translateX(2px)}\n.ckw-msgr-empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:28px 8px;text-align:center;color:var(--ckw-fg2)}\n.ckw-msgr-empty p{margin:0}\n.ckw-msgr-doc{display:flex;flex-direction:column;gap:6px;padding-top:4px}\n.ckw-msgr-doc-t{margin:0;font-size:20px;font-weight:700;letter-spacing:-.015em;line-height:1.3}\n.ckw-msgr-doc-c{margin:0;font-size:12px;color:var(--ckw-fg3)}\n.ckw-msgr-doc-b{margin-top:8px;font-size:14px;line-height:1.6;overflow-wrap:anywhere}\n.ckw-msgr-doc-b>*{margin:0 0 10px}\n.ckw-msgr-doc-b h2{font-size:16px;margin-top:16px}\n.ckw-msgr-doc-b h3{font-size:15px;margin-top:12px}\n.ckw-msgr-doc-b ul,.ckw-msgr-doc-b ol{padding-left:20px}\n.ckw-msgr-doc-b blockquote{border-left:3px solid var(--ckw-line);padding-left:10px;color:var(--ckw-fg2)}\n.ckw-msgr-doc-b pre{background:var(--ckw-bg2);border-radius:8px;padding:10px;overflow-x:auto;font-size:13px}\n.ckw-msgr-doc-b code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}\n.ckw-msgr-doc-b a{color:var(--ckw-accent)}\n.ckw-msgr-doc-b hr{border:0;border-top:1px solid var(--ckw-line)}\n.ckw-msgr-rate{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-top:8px;padding:12px;border-radius:12px;background:var(--ckw-bg2);font-size:13px;color:var(--ckw-fg2)}\n.ckw-msgr-rate-b{display:flex;gap:6px}\n.ckw-msgr-ask{margin-top:6px;width:100%;height:40px;border-radius:12px}\n/* Chat */\n.ckw-msgr-cite{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:7px 10px;border:1px solid var(--ckw-line);border-radius:12px;background:var(--ckw-bg);font-size:13px;text-align:left}\n.ckw-msgr-cite .ckw-icon{color:var(--ckw-accent)}\n.ckw-msgr-cite span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-msgs{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:12px}\n.ckw-msg{display:flex;flex-direction:column;align-items:flex-start;gap:4px;max-width:82%;transform-origin:bottom left}\n.ckw-msg[data-from=me]{align-self:flex-end;align-items:flex-end;transform-origin:bottom right}\n.ckw-msg[data-new]{animation:ckw-bub .4s cubic-bezier(.32,.72,0,1)}\n@keyframes ckw-bub{from{opacity:0;transform:translateY(10px) scale(.92)}}\n.ckw-bubble{padding:10px 14px;border-radius:var(--ckw-r-bubble) var(--ckw-r-bubble) var(--ckw-r-bubble) var(--ckw-r-tail);background:var(--ckw-bg3);white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;line-height:1.45;text-wrap:pretty}\n.ckw-msg[data-from=me] .ckw-bubble{background:var(--ckw-accent);color:var(--ckw-accent-ink);border-radius:var(--ckw-r-bubble) var(--ckw-r-bubble) var(--ckw-r-tail) var(--ckw-r-bubble)}\n.ckw-msg[aria-busy=true] .ckw-bubble{opacity:.7}\n.ckw-msg-meta{font-size:11px;color:var(--ckw-fg3);font-variant-numeric:tabular-nums;padding:0 6px}\n.ckw-msgr-sugg{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:auto;padding-top:12px}\n.ckw-msgr-sugg-b{max-width:100%;padding:9px 14px;border:0;border-radius:var(--ckw-r-card);background:var(--ckw-bg2);font-size:13.5px;text-align:left;color:var(--ckw-fg);transition:background-color .12s linear,color .12s linear,transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-sugg-b:hover{background:var(--ckw-bg3);color:var(--ckw-accent)}\n.ckw-msgr-sugg-b:active{transform:scale(.96)}\n.ckw-msgr-enter .ckw-msgr-sugg-b{animation:ckw-view .34s cubic-bezier(.32,.72,0,1) backwards}\n.ckw-msgr-enter .ckw-msgr-sugg-b:nth-child(2){animation-delay:.12s}\n.ckw-msgr-enter .ckw-msgr-sugg-b:nth-child(3){animation-delay:.18s}\n.ckw-msgr-note{margin:4px 0 0;text-align:center}\n.ckw-msgr-compose{display:flex;flex-direction:column;gap:8px;padding:4px 14px 14px;background:var(--ckw-bg);flex:none}\n.ckw-msgr-compose .ckw-input{border:0;border-radius:var(--ckw-r-field);background:var(--ckw-bg2);min-height:40px;padding:8px 16px}\n.ckw-root .ckw-msgr-compose .ckw-input:focus-visible{outline:none;background:var(--ckw-bg3)}\n.ckw-msgr-box{display:flex;flex-direction:column;align-items:stretch;gap:4px;padding:12px 8px 8px 16px;border:0;border-radius:calc(var(--ckw-r-card) + 4px);background:var(--ckw-bg2);box-shadow:0 0 0 1px color-mix(in srgb,var(--ckw-line) 70%,transparent);cursor:text;transition:background-color .15s linear,box-shadow .15s linear}\n.ckw-msgr-box:focus-within{background:var(--ckw-bg);box-shadow:0 0 0 1px var(--ckw-line),0 6px 18px rgba(16,18,24,.07)}\n.ckw-msgr-tools{display:flex;align-items:center;gap:2px;margin-left:-8px}\n.ckw-msgr-sp{flex:1}\n.ckw-msgr-input{flex:1;min-width:0;min-height:24px;max-height:140px;padding:2px 8px 2px 0;border:0;border-radius:0;background:transparent;resize:none;field-sizing:content;font-size:14.5px}\n.ckw-root .ckw-msgr-input:focus-visible{outline:none}\n.ckw-msgr-send{width:32px;height:32px;padding:0;flex:none;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:var(--ckw-accent);color:var(--ckw-accent-ink);transition:background-color .15s linear,color .15s linear,transform .25s cubic-bezier(.34,1.56,.64,1)}\n.ckw-msgr-send:not(:disabled):hover{transform:scale(1.08)}\n.ckw-msgr-send:not(:disabled):active{transform:scale(.9)}\n.ckw-msgr-send:disabled{background:var(--ckw-bg3);color:var(--ckw-fg3);cursor:default}\n/* Files: the paperclip in the field, picked files above it, sent ones in the bubbles, dropping onto the panel */\n.ckw-msgr-compose{position:relative}\n.ckw-msgr-clip{width:32px;height:32px;padding:0;flex:none;display:flex;align-items:center;justify-content:center;border:0;border-radius:calc(var(--ckw-r-field) - 4px);background:transparent;color:var(--ckw-fg3);transition:color .12s linear,background-color .12s linear,transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-clip:hover,.ckw-msgr-clip[aria-expanded=true]{color:var(--ckw-fg);background:color-mix(in srgb,var(--ckw-fg) 7%,transparent)}\n.ckw-msgr-clip:active{transform:scale(.9)}\n\n.ckw-msgr-amenu{top:auto;bottom:calc(100% - 6px);left:14px;right:auto;min-width:0;transform-origin:bottom left}\n.ckw-msgr-files{display:flex;flex-wrap:wrap;gap:10px;padding:6px 2px 0}\n.ckw-msgr-file{position:relative;width:56px;height:56px;border-radius:calc(var(--ckw-r-card) - 4px);background:var(--ckw-bg2);box-shadow:0 0 0 1px var(--ckw-line)}\n.ckw-msgr-file img{display:block;width:100%;height:100%;object-fit:cover;border-radius:inherit}\n.ckw-msgr-file[aria-busy=true] img,.ckw-msgr-file[aria-busy=true] .ckw-msgr-file-doc{opacity:.45}\n.ckw-msgr-file[aria-busy=true]::after{content:\"\";position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-9px 0 0 -9px;border:2px solid var(--ckw-fg2);border-right-color:transparent;border-radius:50%;animation:ckw-spin .8s linear infinite}\n@keyframes ckw-spin{to{transform:rotate(360deg)}}\n.ckw-msgr-file-doc{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;width:100%;height:100%;padding:4px;color:var(--ckw-fg2);font-size:10px;line-height:1.2}\n.ckw-msgr-file-doc span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-msgr-file-x{position:absolute;top:-7px;right:-7px;width:20px;height:20px;padding:0;display:flex;align-items:center;justify-content:center;border:2px solid var(--ckw-bg);border-radius:50%;background:var(--ckw-fg);color:var(--ckw-bg)}\n.ckw-msgr-file-x .ckw-icon{width:10px;height:10px}\n.ckw-msg-files{display:flex;flex-wrap:wrap;gap:6px;max-width:100%}\n.ckw-msg[data-from=me] .ckw-msg-files{justify-content:flex-end}\n.ckw-msg-img{display:block;overflow:hidden;border-radius:var(--ckw-r-bubble);background:var(--ckw-bg3);box-shadow:0 0 0 1px var(--ckw-line)}\n.ckw-msg-img img{display:block;max-width:220px;max-height:200px;min-width:48px;min-height:48px;object-fit:cover}\n.ckw-msg-files a.ckw-msgr-cite{color:var(--ckw-fg);text-decoration:none}\n.ckw-msgr[data-drop]::after{content:\"Drop to attach\";position:absolute;inset:8px;z-index:5;display:flex;align-items:center;justify-content:center;border:2px dashed var(--ckw-accent);border-radius:calc(var(--ckw-r-panel) - 6px);background:color-mix(in srgb,var(--ckw-bg) 90%,transparent);color:var(--ckw-fg);font-size:15px;font-weight:600;pointer-events:none}\n/* Powered by */\n.ckw-msgr-powered{flex:none;display:block;padding:2px 0 10px;text-align:center;font-size:11.5px;color:var(--ckw-fg3);text-decoration:none;background:var(--ckw-bg)}\n.ckw-msgr-powered b{font-weight:650;color:var(--ckw-fg2)}\n.ckw-msgr-powered:hover b{color:var(--ckw-fg)}\n.ckw-msgr-compose:has(+.ckw-msgr-powered){padding-bottom:8px}\n.ckw-msgr-error{margin:0;font-size:12px;color:var(--ckw-danger)}\n.ckw-msgr .ckw-input[aria-invalid=true]{box-shadow:0 0 0 1px var(--ckw-danger)}\n/* The email asked of anonymous visitors: the box's first line, under a hairline the message follows */\n.ckw-root .ckw-msgr-box .ckw-input.ckw-msgr-email{min-height:0;height:26px;margin:-2px 8px 6px 0;padding:0 0 6px;border:0;border-radius:0;background:none;box-shadow:0 1px 0 var(--hu-border,var(--ckw-line));font-size:13px;color:var(--ckw-fg2)}\n.ckw-root .ckw-msgr-box .ckw-input.ckw-msgr-email:focus-visible{background:none;box-shadow:0 1px 0 var(--ckw-accent);color:var(--ckw-fg)}\n.ckw-root .ckw-msgr-box .ckw-input.ckw-msgr-email[aria-invalid=true]{box-shadow:0 1px 0 var(--ckw-danger)}\n/* The team's mark as a picture, the AI agent's face on its answers */\n.ckw-root .ckw-msgr-av-img{background:none;overflow:hidden}\n.ckw-msgr-av-img img{width:100%;height:100%;object-fit:cover;border-radius:inherit}\n.ckw-msg-face{width:16px;height:16px;margin:0 5px -3px 0;border-radius:50%;object-fit:cover}\n/* Bar middle, tab bar, Home's glow and \"Ask a question\" (Featurebase-like) */\n.ckw-msgr-mid{display:flex;align-items:center;justify-content:center;gap:10px;min-width:0;max-width:62%;flex:none}\n.ckw-msgr-mid b{font-size:15px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.ckw-msgr-mid-t{display:flex;flex-direction:column;gap:1px;min-width:0;line-height:1.25}\n.ckw-msgr-mid-t .ckw-msgr-online{font-size:11.5px;white-space:nowrap}\n.ckw-msgr-mid-t .ckw-msgr-online::before{width:6px;height:6px;box-shadow:none}\n.ckw-msgr-tabs{flex:none;display:flex;padding:6px 10px 4px;background:var(--ckw-bg);box-shadow:0 -1px 0 color-mix(in srgb,var(--ckw-line) 60%,transparent)}\n.ckw-msgr-tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 0 4px;border:0;border-radius:12px;background:none;color:var(--ckw-fg3);font-size:12px;font-weight:550;transition:color .15s linear}\n.ckw-msgr-tab:hover{color:var(--ckw-fg2)}\n.ckw-msgr-tab[aria-current=page]{color:var(--ckw-fg)}\n.ckw-msgr-tab-ic{position:relative;display:block;width:22px;height:22px;transition:transform .25s cubic-bezier(.34,1.56,.64,1)}\n.ckw-msgr-tab:active .ckw-msgr-tab-ic{transform:scale(.88)}\n.ckw-msgr-tab-ic>.ckw-icon{position:absolute;inset:0;transition:opacity .15s linear,transform .3s cubic-bezier(.34,1.56,.64,1)}\n.ckw-msgr-tab-ic>.ckw-icon+.ckw-icon{opacity:0;transform:scale(.75)}\n.ckw-msgr-tab[aria-current=page] .ckw-msgr-tab-ic>.ckw-icon:first-child{opacity:0}\n.ckw-msgr-tab[aria-current=page] .ckw-msgr-tab-ic>.ckw-icon+.ckw-icon{opacity:1;transform:none}\n.ckw-cut{stroke:var(--ckw-bg)}\n.ckw-root:not([data-header=color]) .ckw-msgr[data-view=home] :is(.ckw-msgr-bar,.ckw-msgr-body){background:transparent}\n.ckw-msgr-askq{display:flex;align-items:center;gap:8px;height:52px;margin:6px 0 4px;padding:0 7px 0 18px;border-radius:var(--ckw-r-field);background:var(--ckw-bg2);box-shadow:0 0 0 1px color-mix(in srgb,var(--ckw-line) 70%,transparent);transition:background-color .15s linear,box-shadow .15s linear}\n.ckw-msgr-askq:focus-within{background:var(--ckw-bg);box-shadow:0 0 0 1px var(--ckw-line),0 6px 18px rgba(16,18,24,.07)}\n.ckw-msgr-askq-in{flex:1;min-width:0;border:0;background:transparent;outline:none;font-size:15px;color:var(--ckw-fg)}\n.ckw-msgr-askq-in::placeholder{color:var(--ckw-fg3)}\n.ckw-root .ckw-msgr-askq-in:focus-visible{outline:none}\n.ckw-msgr-askq .ckw-msgr-send{width:38px;height:38px}\n.ckw-root[data-header=color] .ckw-msgr-askq{background:var(--ckw-card);box-shadow:var(--ckw-raise)}\n/* Home in the accent color (look: header \"color\"): the bar and the top in the accent, raised cards over its edge */\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-bar{background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-ib{color:color-mix(in srgb,var(--ckw-accent-ink) 80%,transparent)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-ib:hover,.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-ib[aria-expanded=true]{background:color-mix(in srgb,var(--ckw-accent-ink) 14%,transparent);color:var(--ckw-accent-ink)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-body,.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-powered{background:var(--ckw-bg2)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-body{scrollbar-width:none}\n.ckw-root[data-header=color] .ckw-msgr-hero{margin:-4px -16px 0;padding:14px 20px 64px;background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-root[data-header=color] .ckw-msgr-hero .ckw-msgr-brand,.ckw-root[data-header=color] .ckw-msgr-hero .ckw-msgr-online{color:color-mix(in srgb,var(--ckw-accent-ink) 82%,transparent)}\n.ckw-root[data-header=color] .ckw-msgr-hero .ckw-msgr-av{background:var(--ckw-accent-ink);color:var(--ckw-accent)}\n.ckw-root[data-header=color] .ckw-msgr-hero+*{margin-top:-58px}\n.ckw-root[data-header=color] .ckw-msgr-card{background:var(--ckw-card);box-shadow:var(--ckw-raise)}\n.ckw-root[data-header=color] button.ckw-msgr-card:hover{background:var(--ckw-card);transform:translateY(-1px)}\n.ckw-root[data-header=color] .ckw-msgr-card-col .ckw-msgr-search{background:var(--ckw-bg2)}\n.ckw-root[data-header=color] .ckw-msgr-card .ckw-msgr-art:hover{background:var(--ckw-bg2)}\n/* Where it sits: a corner, the middle of the top or bottom edge, or the middle of a side; panel and cards open from the launcher */\n.ckw-msgr-fab[data-pos$=left],.ckw-msgr[data-pos$=left],.ckw-msgr-preview[data-pos$=left]{left:20px;right:auto}\n.ckw-msgr-fab[data-pos$=right],.ckw-msgr[data-pos$=right],.ckw-msgr-preview[data-pos$=right]{right:20px;left:auto}\n.ckw-msgr-fab[data-pos$=center],.ckw-msgr[data-pos$=center],.ckw-msgr-preview[data-pos$=center]{left:50%;right:auto;translate:-50% 0}\n.ckw-msgr-fab[data-pos^=top]{top:20px;bottom:auto}\n.ckw-msgr[data-pos^=top],.ckw-msgr-preview[data-pos^=top]{top:92px;bottom:auto}\n.ckw-msgr-fab[data-pos^=middle],.ckw-msgr[data-pos^=middle],.ckw-msgr-preview[data-pos^=middle]{top:50%;bottom:auto;translate:0 -50%}\n.ckw-msgr[data-pos=middle-left],.ckw-msgr-preview[data-pos=middle-left]{left:92px}\n.ckw-msgr[data-pos=middle-right],.ckw-msgr-preview[data-pos=middle-right]{right:92px}\n.ckw-msgr[data-pos^=middle]{height:min(680px,calc(100vh - 40px))}\n.ckw-msgr[data-pos=top-right],.ckw-msgr-preview[data-pos=top-right]{transform-origin:top right}\n.ckw-msgr[data-pos=top-left],.ckw-msgr-preview[data-pos=top-left]{transform-origin:top left}\n.ckw-msgr[data-pos=top-center],.ckw-msgr-preview[data-pos=top-center]{transform-origin:top center}\n.ckw-msgr[data-pos=bottom-center],.ckw-msgr-preview[data-pos=bottom-center]{transform-origin:bottom center}\n.ckw-msgr[data-pos=middle-left],.ckw-msgr-preview[data-pos=middle-left]{transform-origin:center left}\n.ckw-msgr[data-pos=middle-right],.ckw-msgr-preview[data-pos=middle-right]{transform-origin:center right}\n@media (max-width:520px){.ckw-root:not([data-contained]) .ckw-msgr{top:0;translate:none}.ckw-msgr-fab[data-pos$=left]{left:14px}.ckw-msgr-fab[data-pos$=right]{right:14px}.ckw-msgr-fab[data-pos^=top]{top:14px}.ckw-msgr-preview[data-pos^=top]{top:84px}.ckw-msgr-preview[data-pos^=middle]{top:auto;bottom:20px;left:16px;right:16px;width:auto;translate:none}}\n/* Inside MRRocket's preview: placed in its frame, not the page */\n.ckw-root[data-contained]{position:absolute;inset:0;pointer-events:none;overflow:hidden}\n.ckw-root[data-contained]>*{position:absolute;pointer-events:auto}\n.ckw-root[data-contained] .ckw-msgr{height:min(680px,calc(100% - 112px));max-width:calc(100% - 40px)}\n.ckw-root[data-contained] .ckw-msgr[data-wide]{height:calc(100% - 112px)}\n.ckw-root[data-contained] .ckw-msgr[data-pos^=middle]{height:min(680px,calc(100% - 40px));max-width:calc(100% - 112px)}\n.ckw-root[data-contained] .ckw-msgr-preview[data-pos^=middle]{max-width:calc(100% - 112px)}\n@media (max-width:520px){.ckw-root:not([data-contained]) .ckw-msgr{width:100%;height:100dvh;bottom:0;border-radius:0;transform-origin:bottom center}.ckw-root:not([data-contained]) .ckw-msgr-x{display:flex}.ckw-msgr-preview{bottom:84px}}\n@media (prefers-reduced-motion:reduce){.ckw-msgr,.ckw-msgr[data-out],.ckw-msgr-preview,.ckw-msgr-menu,.ckw-msgr-count,.ckw-msg[data-new],.ckw-msgr-enter>*,.ckw-msgr-enter .ckw-msgr-sugg-b{animation:none}.ckw-msgr-fab,.ckw-msgr-fab-i,.ckw-msgr-tab-ic,.ckw-msgr-tab-ic>.ckw-icon,.ckw-msgr{transition:none}}\n/* The messenger in HeroUI v3's look (heroui.com, its free components): a soft gray ground, white surfaces with a hairline\n shadow, white fields, pill buttons and a pill tab switch, a 2px ring in the accent on focus. Its tokens (--hu-*) map onto\n the widget's own, inside the messenger only, so the other widgets keep theirs. */\n.ckw-root{--hu-bg:#fff;--hu-surface:#f4f4f5;--hu-default:#ececee;--hu-default-hover:#e4e4e7;--hu-segment:#fff;--hu-muted:#71717a;--hu-fg:#18181b;--hu-border:#e4e4e7;--hu-shadow:0 0 0 0 transparent;--hu-lift:0 1px 2px rgba(0,0,0,.08),0 0 1px rgba(0,0,0,.1);--hu-overlay:0 0 0 1px rgba(0,0,0,.05),0 2px 8px rgba(0,0,0,.05),0 18px 40px rgba(0,0,0,.1)}\n.ckw-root[data-theme=dark]{--hu-bg:#111113;--hu-surface:#1c1c1f;--hu-default:#26262a;--hu-default-hover:#2e2e33;--hu-segment:#3a3a40;--hu-muted:#a1a1aa;--hu-fg:#fafafa;--hu-border:#27272a;--hu-shadow:0 0 0 0 transparent;--hu-lift:0 0 0 1px rgba(255,255,255,.06);--hu-overlay:0 0 0 1px rgba(255,255,255,.08),0 18px 40px rgba(0,0,0,.55)}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto]{--hu-bg:#111113;--hu-surface:#1c1c1f;--hu-default:#26262a;--hu-default-hover:#2e2e33;--hu-segment:#3a3a40;--hu-muted:#a1a1aa;--hu-fg:#fafafa;--hu-border:#27272a;--hu-shadow:0 0 0 0 transparent;--hu-lift:0 0 0 1px rgba(255,255,255,.06);--hu-overlay:0 0 0 1px rgba(255,255,255,.08),0 18px 40px rgba(0,0,0,.55)}}\n.ckw-msgr,.ckw-msgr-preview{--ckw-bg:var(--hu-bg);--ckw-bg2:var(--hu-surface);--ckw-bg3:var(--hu-default);--ckw-card:var(--hu-surface);--ckw-fg:var(--hu-fg);--ckw-fg2:var(--hu-muted);--ckw-fg3:var(--hu-muted);--ckw-line:var(--hu-border);--ckw-soft:var(--hu-overlay);--ckw-raise:var(--hu-shadow)}\n.ckw-root .ckw-msgr-preview-card{background:var(--hu-surface)}\n.ckw-root .ckw-msgr-card,.ckw-root .ckw-msgr-sugg-b,.ckw-root .ckw-msgr-rate,.ckw-root .ckw-msgr-cite{background:var(--hu-surface);box-shadow:var(--hu-shadow);border:0}\n.ckw-root button.ckw-msgr-card:hover{background:var(--hu-default)}\n.ckw-root .ckw-msgr-card-col{padding:6px}\n.ckw-root .ckw-msgr-card .ckw-msgr-art:hover,.ckw-root .ckw-msgr-hrow:hover{background:var(--hu-default)}\n.ckw-root .ckw-msgr-hrow+.ckw-msgr-hrow{box-shadow:0 -1px 0 var(--hu-border)}\n.ckw-root .ckw-msgr-search,.ckw-root .ckw-msgr-askq,.ckw-root .ckw-msgr-box,.ckw-root .ckw-msgr-compose .ckw-input{background:var(--hu-surface);border:0;box-shadow:var(--hu-shadow)}\n.ckw-root .ckw-msgr-search:focus-within,.ckw-root .ckw-msgr-askq:focus-within,.ckw-root .ckw-msgr-box:focus-within,.ckw-root .ckw-msgr-compose .ckw-input:focus-visible{background:var(--hu-surface);box-shadow:0 0 0 1.5px color-mix(in srgb,var(--ckw-accent) 55%,transparent),0 0 0 5px color-mix(in srgb,var(--ckw-accent) 12%,transparent);color:var(--ckw-fg3)}\n.ckw-root .ckw-msgr-askq{height:48px;border-radius:24px}\n.ckw-root .ckw-msgr-box{border-radius:20px}\n.ckw-root .ckw-msgr-send{border-radius:999px}\n.ckw-root .ckw-msgr-send:disabled{background:var(--hu-default);color:var(--hu-muted)}\n.ckw-root .ckw-msgr-send:not(:disabled):hover{transform:none;filter:brightness(1.08)}\n.ckw-root .ckw-msgr-send:not(:disabled):active{transform:scale(.97)}\n.ckw-root .ckw-bubble{background:var(--hu-surface);box-shadow:var(--hu-shadow)}\n.ckw-root .ckw-msg[data-from=me] .ckw-bubble{box-shadow:none}\n.ckw-root .ckw-msgr-av{background:color-mix(in srgb,var(--ckw-accent) 16%,var(--hu-surface));color:var(--ckw-accent);font-weight:600}\n.ckw-root .ckw-msgr-ib:hover,.ckw-root .ckw-msgr-ib[aria-expanded=true]{background:var(--hu-default)}\n.ckw-root .ckw-msgr-menu{background:var(--hu-surface);box-shadow:var(--hu-overlay);border-radius:16px}\n.ckw-root .ckw-msgr-menu-i{border-radius:10px}\n.ckw-root .ckw-msgr-menu-i:hover,.ckw-root .ckw-msgr-menu-i:focus-visible{background:var(--hu-default)}\n.ckw-root .ckw-msgr .ckw-btn{height:36px;padding:0 16px;border:0;border-radius:999px;background:var(--hu-default);color:var(--hu-fg);font-size:14px;font-weight:500;box-shadow:none;transition:transform .25s cubic-bezier(.32,.72,0,1),background-color .1s linear}\n.ckw-root .ckw-msgr .ckw-btn:hover{background:var(--hu-default-hover);filter:none}\n.ckw-root .ckw-msgr .ckw-btn:active{transform:scale(.97)}\n.ckw-root .ckw-msgr .ckw-btn-primary{background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-root .ckw-msgr .ckw-btn-primary:hover{background:var(--ckw-accent);filter:brightness(1.08)}\n.ckw-root .ckw-msgr-sugg-b{border-radius:999px}\n.ckw-root .ckw-msgr-ask{height:40px;border-radius:999px}\n/* Home like Featurebase: the product's icon top left, \"Hi, Lukas 👋\" over the greeting in gray, a silk of the accent\n with drifting dots behind the top right (.ckw-msgr-sky, also drawn by MRRocket's phone preview) */\n.ckw-msgr-logo{display:flex;align-items:center;min-width:32px;height:32px;flex:none;margin-left:6px}\n.ckw-msgr-logo img{height:28px;width:auto;min-width:28px;max-width:132px;border-radius:8px;object-fit:contain}\n.ckw-root .ckw-msgr[data-view=home] .ckw-msgr-bar{padding-top:16px}\n.ckw-root .ckw-msgr[data-view=home] .ckw-msgr-body{position:relative;z-index:1;gap:10px;padding-top:0}\n.ckw-root .ckw-msgr-hero.ckw-msgr-hello{display:flex;flex-direction:column;gap:1px;margin:22px 0 10px;padding:0 4px;font-size:25px;font-weight:600;letter-spacing:-.028em;line-height:1.2;color:var(--hu-fg)}\n.ckw-msgr-hello-sub{color:var(--hu-muted);font-weight:500}\n.ckw-msgr-wave{display:inline-block;transform-origin:70% 75%;animation:ckw-wave 2.4s ease-in-out .6s 1 both}\n@keyframes ckw-wave{0%,60%,100%{transform:none}10%,30%{transform:rotate(14deg)}20%{transform:rotate(-8deg)}40%{transform:rotate(-4deg)}50%{transform:rotate(10deg)}}\n.ckw-root .ckw-msgr[data-view=home] .ckw-msgr-askq{margin:0 0 6px}\n.ckw-msgr-sky{position:absolute;z-index:0;top:0;left:0;right:0;height:250px;pointer-events:none;overflow:hidden;border-radius:inherit;-webkit-mask-image:linear-gradient(to bottom,#000 25%,transparent 92%);mask-image:linear-gradient(to bottom,#000 25%,transparent 92%)}\n.ckw-msgr-sky::before{content:\"\";position:absolute;top:-45%;right:-25%;width:115%;height:135%;background:radial-gradient(36% 40% at 62% 46%,color-mix(in srgb,var(--ckw-accent) 92%,#fff) 0%,transparent 70%),radial-gradient(32% 36% at 86% 24%,color-mix(in srgb,var(--ckw-glow2,var(--ckw-accent)) 70%,#fff) 0%,transparent 72%),radial-gradient(46% 30% at 36% 64%,color-mix(in srgb,var(--ckw-glow3,var(--ckw-glow2,var(--ckw-accent))) 50%,#fff) 0%,transparent 70%);filter:blur(20px);opacity:.75;animation:ckw-silk 16s cubic-bezier(.45,0,.55,1) infinite alternate}\n@keyframes ckw-silk{to{transform:translate(-7%,5%) rotate(8deg) scale(1.08)}}\n.ckw-msgr-sky::after{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,color-mix(in srgb,var(--ckw-accent) 85%,#fff) .9px,transparent 1.4px);background-size:5px 5px;-webkit-mask-image:linear-gradient(110deg,transparent 0%,#000 18%,transparent 34%,#000 52%,transparent 70%),radial-gradient(70% 85% at 88% 12%,#000 15%,transparent 75%);-webkit-mask-size:220% 100%,100% 100%;-webkit-mask-repeat:repeat-x,no-repeat;-webkit-mask-composite:source-in;mask-image:linear-gradient(110deg,transparent 0%,#000 18%,transparent 34%,#000 52%,transparent 70%),radial-gradient(70% 85% at 88% 12%,#000 15%,transparent 75%);mask-size:220% 100%,100% 100%;mask-repeat:repeat-x,no-repeat;mask-composite:intersect;opacity:.6;animation:ckw-dots 11s linear infinite}\n@keyframes ckw-dots{from{-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0}to{-webkit-mask-position:-220% 0,0 0;mask-position:-220% 0,0 0}}\n.ckw-root[data-theme=dark] .ckw-msgr-sky::before{opacity:.4}\n.ckw-root[data-theme=dark] .ckw-msgr-sky::after{opacity:.4}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto] .ckw-msgr-sky::before{opacity:.4}.ckw-root[data-theme=auto] .ckw-msgr-sky::after{opacity:.4}}\n.ckw-root[data-header=color] .ckw-msgr-sky{display:none}\n@media (prefers-reduced-motion:reduce){.ckw-msgr-sky::before,.ckw-msgr-sky::after,.ckw-msgr-wave{animation:none}}\n/* Home's latest message: one quiet row, the small mark, the words, who and when */\n.ckw-root .ckw-msgr-recent{padding:10px 12px;gap:0}\n.ckw-root .ckw-msgr-recent .ckw-msgr-recent-row{gap:10px}\n.ckw-root .ckw-msgr-recent .ckw-msgr-card-main{gap:1px}\n.ckw-root .ckw-msgr-recent-text{font-size:13.5px;font-weight:500}\n.ckw-root .ckw-msgr-recent .ckw-msgr-card-meta{font-size:11.5px}\n/* The tab switch: HeroUI's Tabs, a gray pill with the current tab on a raised white one */\n.ckw-root .ckw-msgr-tabs{position:relative;z-index:1;margin:2px 12px 8px;padding:4px;gap:0;border-radius:999px;background:var(--hu-surface);box-shadow:none}\n.ckw-root .ckw-msgr-tab{flex-direction:row;justify-content:center;gap:7px;height:36px;padding:0 10px;border-radius:999px;color:var(--hu-muted);font-size:13.5px;font-weight:500;transition:color .15s ease,background-color .15s ease,box-shadow .15s ease,opacity .15s ease}\n.ckw-root .ckw-msgr-tab:not([aria-current=page]):hover{color:var(--hu-muted);opacity:.7}\n.ckw-root .ckw-msgr-tab[aria-current=page]{background:var(--hu-segment);color:var(--hu-fg);box-shadow:var(--hu-lift)}\n.ckw-root .ckw-msgr-tab-ic{width:18px;height:18px}\n.ckw-root .ckw-msgr-tab .ckw-cut{stroke:var(--hu-segment)}\n.ckw-root .ckw-msgr-count-tab{box-shadow:0 0 0 2px var(--hu-default)}\n.ckw-root .ckw-msgr-tab[aria-current=page] .ckw-msgr-count-tab{box-shadow:0 0 0 2px var(--hu-segment)}\n.ckw-root .ckw-msgr-powered{background:var(--hu-bg);padding-top:0}\n/* Survey */\n.ckw-survey{position:fixed;z-index:2147483000;left:20px;bottom:20px;width:360px;max-width:calc(100vw - 24px);background:var(--ckw-bg);border:1px solid var(--ckw-line);border-radius:12px;box-shadow:var(--ckw-shadow);padding:14px;animation:ckw-in .2s ease-out}\n@keyframes ckw-in{from{opacity:0;transform:translateY(8px)}}\n@media (max-width:520px){.ckw-survey{left:0;right:0;bottom:0;width:100%;max-width:100%;border-radius:12px 12px 0 0}}\n.ckw-sv-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}\n.ckw-dots{display:flex;gap:4px}\n.ckw-dot{width:6px;height:6px;border-radius:50%;background:var(--ckw-bg3)}\n.ckw-dot[data-on=true]{background:var(--ckw-accent)}\n.ckw-q{font-weight:600;font-size:15px;margin:0 0 2px;border:0;padding:0}\n.ckw-root .ckw-q:focus-visible{outline:none}\n.ckw-qd{color:var(--ckw-fg2);font-size:13px;margin:0 0 10px}\n.ckw-scale{display:flex;gap:4px;flex-wrap:wrap}\n.ckw-num{flex:1 1 0;min-width:26px;height:34px;border:1px solid var(--ckw-line);background:var(--ckw-bg);border-radius:8px;font-size:13px;font-weight:600;padding:0}\n.ckw-num:hover{border-color:var(--ckw-accent)}\n.ckw-num[aria-pressed=true]{background:var(--ckw-accent);color:var(--ckw-accent-ink);border-color:var(--ckw-accent)}\n.ckw-root .ckw-star{background:none;border:0;padding:2px;color:var(--ckw-bg3)}\n.ckw-root .ckw-star[data-on=true]{color:#f5a524}\n.ckw-star svg{width:28px;height:28px}\n.ckw-lh{display:flex;justify-content:space-between;color:var(--ckw-fg3);font-size:11px;margin-top:4px}\n.ckw-opts{display:flex;flex-direction:column;gap:6px}\n.ckw-opt{display:flex;gap:8px;align-items:center;border:1px solid var(--ckw-line);border-radius:8px;padding:7px 10px;background:var(--ckw-bg);cursor:pointer}\n.ckw-opt:has(input:checked){border-color:var(--ckw-accent);background:color-mix(in srgb,var(--ckw-accent) 8%,transparent)}\n.ckw-opt input{accent-color:var(--ckw-accent)}\n.ckw-sv-foot{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-top:12px}\n.ckw-thanks{text-align:center;padding:14px 0;display:flex;flex-direction:column;align-items:center;gap:8px}\n.ckw-tick{width:32px;height:32px;border-radius:50%;background:var(--ckw-accent);color:var(--ckw-accent-ink);display:flex;align-items:center;justify-content:center}\n`;\n\n/** Puts the stylesheet into the page once, however many widgets mount. */\nexport const injectStyles = () => {\n if (typeof document === \"undefined\" || document.getElementById(STYLE_ID)) return;\n const el = document.createElement(\"style\");\n el.id = STYLE_ID;\n el.textContent = CSS;\n document.head.appendChild(el);\n};\n"],"mappings":";AACO,IAAM,WAAW;AAGjB,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAskBZ,IAAM,eAAe,MAAM;AAC9B,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,QAAQ,EAAG;AAC1E,QAAM,KAAK,SAAS,cAAc,OAAO;AACzC,KAAG,KAAK;AACR,KAAG,cAAc;AACjB,WAAS,KAAK,YAAY,EAAE;AAChC;","names":[]}
1
+ {"version":3,"sources":["../src/styles-css.ts"],"sourcesContent":["/** The widgets' stylesheet as a string, without React, so the script tag's widgets (src/script) inject the same CSS. */\nexport const STYLE_ID = \"ckw-styles\";\n\n/** The one stylesheet for every Cockpit widget. Everything is scoped under `.ckw-root` and prefixed `ckw-`. */\nexport const CSS = `\n.ckw-root{--ckw-accent:#3f76ff;--ckw-accent-ink:#fff;--ckw-bg:#fff;--ckw-bg2:#f7f7f8;--ckw-bg3:#eeeff1;--ckw-fg:#1c1d20;--ckw-fg2:#5d6068;--ckw-fg3:#8b8e96;--ckw-line:#e4e5e8;--ckw-danger:#d92d20;--ckw-shadow:0 8px 30px rgba(16,18,24,.16);--ckw-card:#fff;--ckw-col:#f5f6f7;--ckw-lift:0 1px 2px rgba(16,18,24,.06),0 0 0 1px rgba(16,18,24,.07);--ckw-raise:0 0 0 1px rgba(16,18,24,.05),0 1px 2px rgba(16,18,24,.05),0 6px 18px rgba(16,18,24,.06);--ckw-float:0 0 0 1px rgba(16,18,24,.06),0 18px 50px rgba(16,18,24,.2);--ckw-soft:0 2px 8px rgba(16,18,24,.05),0 18px 48px rgba(16,18,24,.15);\nfont-size:14px;line-height:1.45;font-family:inherit;color:var(--ckw-fg);box-sizing:border-box;-webkit-font-smoothing:antialiased}\n.ckw-root[data-theme=dark]{--ckw-bg:#111214;--ckw-bg2:#1a1b1f;--ckw-bg3:#26272c;--ckw-fg:#f1f2f4;--ckw-fg2:#a9acb3;--ckw-fg3:#7a7d86;--ckw-line:#2a2b31;--ckw-shadow:0 8px 30px rgba(0,0,0,.5);--ckw-card:#1b1c20;--ckw-col:#16171a;--ckw-lift:0 0 0 1px rgba(255,255,255,.07);--ckw-raise:0 0 0 1px rgba(255,255,255,.07);--ckw-float:0 0 0 1px rgba(255,255,255,.09),0 18px 50px rgba(0,0,0,.55);--ckw-soft:0 0 0 1px rgba(255,255,255,.07),0 18px 50px rgba(0,0,0,.55)}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto]{--ckw-bg:#111214;--ckw-bg2:#1a1b1f;--ckw-bg3:#26272c;--ckw-fg:#f1f2f4;--ckw-fg2:#a9acb3;--ckw-fg3:#7a7d86;--ckw-line:#2a2b31;--ckw-shadow:0 8px 30px rgba(0,0,0,.5);--ckw-card:#1b1c20;--ckw-col:#16171a;--ckw-lift:0 0 0 1px rgba(255,255,255,.07);--ckw-raise:0 0 0 1px rgba(255,255,255,.07);--ckw-float:0 0 0 1px rgba(255,255,255,.09),0 18px 50px rgba(0,0,0,.55);--ckw-soft:0 0 0 1px rgba(255,255,255,.07),0 18px 50px rgba(0,0,0,.55)}}\n.ckw-root *,.ckw-root *::before,.ckw-root *::after{box-sizing:border-box}\n.ckw-root{--ckw-r-panel:22px;--ckw-r-bubble:18px;--ckw-r-tail:6px;--ckw-r-card:16px;--ckw-r-field:20px;--ckw-r-pill:999px;--ckw-r-fab:999px}\n.ckw-root[data-corners=soft]{--ckw-r-panel:14px;--ckw-r-bubble:12px;--ckw-r-tail:4px;--ckw-r-card:10px;--ckw-r-field:10px;--ckw-r-pill:10px;--ckw-r-fab:18px}\n.ckw-root[data-corners=square]{--ckw-r-panel:6px;--ckw-r-bubble:6px;--ckw-r-tail:2px;--ckw-r-card:4px;--ckw-r-field:4px;--ckw-r-pill:4px;--ckw-r-fab:8px}\n.ckw-root[data-font=system]{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif}\n:where(.ckw-root) :where(button,input,select,textarea){font:inherit;color:inherit;margin:0}\n.ckw-root button{cursor:pointer}\n.ckw-root :focus-visible{outline:2px solid var(--ckw-accent);outline-offset:2px}\n.ckw-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}\n.ckw-title{font-size:20px;font-weight:600;margin:0;letter-spacing:-.01em}\n.ckw-sub{color:var(--ckw-fg2);margin:2px 0 0;font-size:13px}\n.ckw-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border-radius:8px;border:1px solid var(--ckw-line);background:var(--ckw-bg);font-weight:500;font-size:13px;white-space:nowrap}\n.ckw-btn:hover{background:var(--ckw-bg2)}\n.ckw-btn[disabled]{opacity:.55;cursor:not-allowed}\n.ckw-btn-primary{background:var(--ckw-accent);border-color:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-btn-primary:hover{background:var(--ckw-accent);filter:brightness(1.08)}\n.ckw-btn-ghost{border-color:transparent;background:transparent;color:var(--ckw-fg2)}\n.ckw-icon{width:16px;height:16px;flex:none;display:block}\n.ckw-tabs{display:flex;gap:4px;border-bottom:1px solid var(--ckw-line);margin-bottom:12px;overflow-x:auto}\n.ckw-tab{background:none;border:0;border-bottom:2px solid transparent;padding:8px 10px;margin-bottom:-1px;color:var(--ckw-fg2);font-weight:500;font-size:13px;white-space:nowrap}\n.ckw-tab[aria-selected=true]{color:var(--ckw-fg);border-bottom-color:var(--ckw-accent)}\n.ckw-tools{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:10px}\n.ckw-input,.ckw-select,.ckw-textarea{width:100%;border:1px solid var(--ckw-line);border-radius:8px;background:var(--ckw-bg);padding:7px 10px;font-size:14px;min-height:34px}\n.ckw-input::placeholder,.ckw-textarea::placeholder{color:var(--ckw-fg3)}\n.ckw-textarea{resize:vertical;min-height:72px}\n.ckw-search{flex:1 1 160px;min-width:0}\n.ckw-seg{display:inline-flex;border:1px solid var(--ckw-line);border-radius:8px;overflow:hidden}\n.ckw-seg button{border:0;background:var(--ckw-bg);padding:0 10px;height:32px;font-size:13px;color:var(--ckw-fg2)}\n.ckw-seg button[aria-pressed=true]{background:var(--ckw-bg3);color:var(--ckw-fg);font-weight:500}\n.ckw-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}\n.ckw-chip{border:1px solid var(--ckw-line);background:var(--ckw-bg);border-radius:999px;padding:3px 10px;font-size:12px;color:var(--ckw-fg2)}\n.ckw-chip[aria-pressed=true],.ckw-chip[aria-checked=true]{background:var(--ckw-fg);color:var(--ckw-bg);border-color:var(--ckw-fg)}\n.ckw-list{list-style:none;margin:0;padding:0;border:1px solid var(--ckw-line);border-radius:8px;overflow:hidden}\n.ckw-list>li+li{border-top:1px solid var(--ckw-line)}\n.ckw-row{display:flex;gap:12px;align-items:flex-start;padding:10px 12px;background:var(--ckw-bg)}\n.ckw-row:hover{background:var(--ckw-bg2)}\n.ckw-vote{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;width:44px;min-height:48px;border:1px solid var(--ckw-line);border-radius:8px;background:var(--ckw-bg);font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;padding:4px 0;color:var(--ckw-fg2)}\n.ckw-vote:hover{border-color:var(--ckw-accent);color:var(--ckw-accent)}\n.ckw-vote[aria-pressed=true]{background:var(--ckw-accent);border-color:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-vote-sm{width:auto;min-height:0;flex-direction:row;gap:4px;padding:2px 8px}\n.ckw-main{flex:1;min-width:0;text-align:left}\n.ckw-link{display:block;width:100%;text-align:left;background:none;border:0;padding:0;font-weight:600;font-size:14px;color:var(--ckw-fg);overflow-wrap:anywhere}\n.ckw-link:hover{color:var(--ckw-accent)}\n.ckw-excerpt{margin:2px 0 0;color:var(--ckw-fg2);font-size:13px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}\n.ckw-meta{display:flex;gap:8px;align-items:center;margin-top:6px;color:var(--ckw-fg3);font-size:12px;flex-wrap:wrap}\n.ckw-pill{display:inline-flex;align-items:center;border-radius:999px;padding:1px 8px;font-size:11px;font-weight:600;background:var(--ckw-bg3);color:var(--ckw-fg2)}\n.ckw-pill[data-s=planned]{background:rgba(63,118,255,.14);color:#3f76ff}\n.ckw-pill[data-s=progress]{background:rgba(245,158,11,.16);color:#b45309}\n.ckw-pill[data-s=shipped]{background:rgba(22,163,74,.15);color:#15803d}\n.ckw-root[data-theme=dark] .ckw-pill[data-s=progress]{color:#fbbf24}\n.ckw-root[data-theme=dark] .ckw-pill[data-s=shipped]{color:#4ade80}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto] .ckw-pill[data-s=progress]{color:#fbbf24}.ckw-root[data-theme=auto] .ckw-pill[data-s=shipped]{color:#4ade80}}\n.ckw-stat{display:inline-flex;align-items:center;gap:4px}\n.ckw-empty{padding:64px 16px;text-align:center;color:var(--ckw-fg2)}\n.ckw-empty-icon{display:block;width:56px;height:56px;margin:0 auto 14px;opacity:.3}\n.ckw-error{border:1px solid color-mix(in srgb,var(--ckw-danger) 40%,transparent);background:color-mix(in srgb,var(--ckw-danger) 8%,transparent);color:var(--ckw-danger);border-radius:8px;padding:8px 10px;font-size:13px;display:flex;gap:8px;align-items:center;justify-content:space-between;margin-bottom:10px}\n.ckw-skel{height:68px;border-radius:8px;background:var(--ckw-bg2);animation:ckw-sh 1.2s ease-in-out infinite;margin-bottom:6px}\n@keyframes ckw-sh{50%{opacity:.5}}\n@media (prefers-reduced-motion:reduce){.ckw-skel,.ckw-scrim,.ckw-modal{animation:none}.ckw-root *{transition:none!important}}\n.ckw-form{display:flex;flex-direction:column;gap:10px;border:1px solid var(--ckw-line);border-radius:8px;padding:12px;margin-bottom:12px;background:var(--ckw-bg)}\n.ckw-field{display:flex;flex-direction:column;gap:4px}\n.ckw-label{font-size:12px;font-weight:600;color:var(--ckw-fg2)}\n.ckw-actions{display:flex;gap:8px;justify-content:flex-end}\n.ckw-dupes{border:1px solid var(--ckw-line);border-radius:8px;background:var(--ckw-bg2);padding:8px 10px;font-size:13px}\n.ckw-dupes p{margin:0 0 4px;color:var(--ckw-fg2);font-size:12px}\n.ckw-dupe{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:3px 0}\n.ckw-dupe span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-team{margin-left:6px;background:var(--ckw-accent);color:var(--ckw-accent-ink);border-radius:4px;padding:0 5px;font-size:10px;font-weight:700;text-transform:uppercase;vertical-align:1px}\n.ckw-time{color:var(--ckw-fg3);font-size:12px;margin-left:6px}\n.ckw-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n/* Board */\n.ckw-board{width:100%;max-width:1160px;margin:0 auto;background:var(--ckw-bg);min-width:0}\n.ckw-board.ckw-full{max-width:none;min-height:100%;min-height:100dvh;display:flex;flex-direction:column}\n.ckw-board.ckw-full>.ckw-body-wrap{flex:1 0 auto;width:100%;max-width:1160px;margin:0 auto;padding:24px 16px 40px}\n.ckw-req{container-type:inline-size}\n.ckw-req-side{display:none}\n.ckw-side-part{display:flex;flex-direction:column;gap:2px;padding:10px;border-radius:14px;background:var(--ckw-bg2)}\n.ckw-side-part h2{margin:0;padding:2px 8px 6px;font-size:13px;font-weight:650;color:var(--ckw-fg)}\n.ckw-side-row{display:flex;align-items:center;gap:8px;width:100%;min-height:32px;padding:4px 8px;border:0;border-radius:8px;background:none;color:var(--ckw-fg2);font-size:13px;font-weight:500;text-align:left;transition:background-color .1s linear,color .1s linear}\n.ckw-side-row:hover{background:var(--ckw-bg3);color:var(--ckw-fg)}\n.ckw-side-row[aria-pressed=true]{background:var(--ckw-bg3);color:var(--ckw-fg);font-weight:600}\n.ckw-side-row .ckw-count{margin-left:auto}\n@container (min-width:760px){.ckw-req-grid[data-side]{display:grid;grid-template-columns:minmax(0,1fr) 260px;gap:24px;align-items:start}.ckw-req-grid[data-side] .ckw-chips-inline{display:none}.ckw-req-side{display:flex;flex-direction:column;gap:10px;position:sticky;top:72px}}\n.ckw-powered{display:block;padding:8px 16px 20px;text-align:center;font-size:12px;color:var(--ckw-fg3);text-decoration:none}\n.ckw-powered b{font-weight:650;color:var(--ckw-fg2)}\n.ckw-powered:hover b{color:var(--ckw-fg)}\n.ckw-board .ckw-top{border-bottom:0}\n.ckw-board .ckw-post{background:var(--ckw-bg2);box-shadow:none;transition:background-color .1s linear}\n.ckw-board .ckw-post:hover{background:var(--ckw-bg3);box-shadow:none}\n.ckw-board .ckw-vote:not([aria-pressed=true]){border-color:transparent}\n.ckw-board .ckw-seg{border:0;gap:2px;padding:2px;border-radius:9px;background:var(--ckw-bg2)}\n.ckw-board .ckw-seg button{height:28px;border-radius:7px;background:none}\n.ckw-board .ckw-seg button[aria-pressed=true]{background:var(--ckw-bg)}\n.ckw-board .ckw-chip:not([aria-pressed=true]){border-color:transparent;background:var(--ckw-bg2)}\n.ckw-board .ckw-col{background:var(--ckw-bg2)}\n.ckw-board .ckw-card{background:var(--ckw-bg);box-shadow:none}\n.ckw-top{position:sticky;top:0;z-index:5;background:color-mix(in srgb,var(--ckw-bg) 88%,transparent);backdrop-filter:saturate(1.4) blur(10px);-webkit-backdrop-filter:saturate(1.4) blur(10px);border-bottom:1px solid var(--ckw-line);margin-bottom:24px}\n.ckw-top-row{max-width:1160px;margin:0 auto;padding:10px 16px;display:flex;align-items:center;gap:16px;flex-wrap:wrap}\n.ckw-brand{display:inline-flex;align-items:center;gap:10px;font-weight:650;font-size:15px;color:var(--ckw-fg);background:none;border:0;padding:4px 2px;border-radius:8px;min-width:0}\n.ckw-brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}\n.ckw-brand img{width:28px;height:28px;border-radius:7px;object-fit:cover;outline:1px solid oklch(0 0 0/.1);outline-offset:-1px;flex:none}\n.ckw-root[data-theme=dark] .ckw-brand img{outline-color:oklch(1 0 0/.1)}\n.ckw-brand-mark{width:28px;height:28px;border-radius:7px;background:var(--ckw-accent);color:var(--ckw-accent-ink);display:inline-flex;align-items:center;justify-content:center;font-size:14px;flex:none}\n.ckw-nav{display:flex;gap:2px;flex:1;min-width:0}\n.ckw-nav-tab{background:none;border:0;border-radius:8px;padding:0 12px;height:34px;color:var(--ckw-fg2);font-weight:550;font-size:14px;white-space:nowrap;transition:background-color .1s linear,color .1s linear}\n.ckw-nav-tab:hover{color:var(--ckw-fg);background:var(--ckw-bg2)}\n.ckw-nav-tab[aria-selected=true]{color:var(--ckw-fg);background:var(--ckw-bg3)}\n.ckw-top-tools{display:flex;align-items:center;gap:6px;margin-left:auto}\n.ckw-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:8px;border:0;background:none;color:var(--ckw-fg2);flex:none}\n.ckw-icon-btn:hover{background:var(--ckw-bg2);color:var(--ckw-fg)}\n.ckw-searchbox{display:flex;align-items:center;border-radius:8px;transition:background-color .1s linear}\n.ckw-search-input{width:0;padding:0;border:0;background:none;outline:none;font-size:14px;height:34px;transition:width .15s cubic-bezier(.2,0,0,1)}\n.ckw-searchbox[data-open]{background:var(--ckw-bg2)}\n.ckw-searchbox[data-open] .ckw-search-input{width:180px;padding-right:10px}\n.ckw-searchbox:focus-within{outline:2px solid var(--ckw-accent);outline-offset:0}\n.ckw-root .ckw-search-input:focus-visible{outline:none}\n.ckw-search-input::-webkit-search-cancel-button{display:none}\n.ckw-submit{height:34px}\n.ckw-btn,.ckw-vote,.ckw-upvote,.ckw-icon-btn{transition-property:background-color,border-color,color,scale;transition-duration:.1s;transition-timing-function:linear}\n.ckw-btn:active:not([disabled]),.ckw-vote:active,.ckw-upvote:active,.ckw-icon-btn:active{scale:.96}\n.ckw-intro{margin:0 0 20px}\n.ckw-intro h1{font-size:24px;font-weight:650;letter-spacing:-.02em;margin:0;text-wrap:balance}\n.ckw-intro p{margin:4px 0 0;color:var(--ckw-fg2);font-size:14px;text-wrap:pretty}\n.ckw-note{display:flex;align-items:center;justify-content:space-between;gap:8px;border-radius:10px;padding:6px 6px 6px 12px;margin-bottom:14px;background:color-mix(in srgb,var(--ckw-accent) 10%,transparent);color:var(--ckw-fg);font-size:13px;font-weight:500}\n.ckw-tools .ckw-chips-inline{margin:0}\n.ckw-posts{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}\n.ckw-post{position:relative;display:flex;gap:14px;align-items:flex-start;padding:14px 16px;border-radius:12px;background:var(--ckw-card);box-shadow:var(--ckw-lift);transition:box-shadow .1s linear}\n.ckw-post:hover{box-shadow:var(--ckw-lift),0 4px 14px rgba(16,18,24,.06)}\n.ckw-post .ckw-vote,.ckw-card .ckw-vote{position:relative;z-index:1}\n.ckw-stretch::after{content:\"\";position:absolute;inset:0;border-radius:inherit}\n.ckw-post .ckw-link,.ckw-card .ckw-link{font-size:15px;font-weight:600;text-wrap:pretty}\n.ckw-dot-sep{color:var(--ckw-fg3)}\n.ckw-type{display:inline-flex;align-items:center;gap:5px;border-radius:6px;padding:1px 7px;font-size:11.5px;font-weight:600;color:var(--ckw-fg2);background:var(--ckw-bg2);white-space:nowrap;width:max-content}\n.ckw-type::before{content:\"\";width:6px;height:6px;border-radius:50%;background:var(--ckw-fg3)}\n.ckw-type[data-tone=blue]::before{background:#3f76ff}\n.ckw-type[data-tone=red]::before{background:#ef4444}\n.ckw-type[data-tone=violet]::before{background:#8b5cf6}\n.ckw-type[data-tone=green]::before{background:#22c55e}\n.ckw-av{width:22px;height:22px;border-radius:50%;flex:none;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:650;background:var(--ckw-bg3);color:var(--ckw-fg2)}\n.ckw-av[data-team]{background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-count{font-weight:500;color:var(--ckw-fg3);font-variant-numeric:tabular-nums;margin-left:2px}\n.ckw-empty p{margin:0 0 12px}\n.ckw-empty p:only-child{margin:0}\n/* Roadmap */\n.ckw-cols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;align-items:start}\n.ckw-col{background:var(--ckw-col);border-radius:14px;padding:6px;min-width:0}\n.ckw-col-head{padding:8px 8px 10px}\n.ckw-col-head h3{display:flex;align-items:center;gap:8px;margin:0;font-size:14px;font-weight:650}\n.ckw-col-head p{margin:2px 0 0 16px;font-size:12px;color:var(--ckw-fg3)}\n.ckw-sdot{width:8px;height:8px;border-radius:50%;background:var(--ckw-fg3);flex:none}\n.ckw-sdot[data-s=planned]{background:#3f76ff}\n.ckw-sdot[data-s=progress]{background:#f59e0b}\n.ckw-sdot[data-s=shipped]{background:#22c55e}\n.ckw-col-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}\n.ckw-col-empty{margin:0;padding:24px 8px;text-align:center;font-size:12px;color:var(--ckw-fg3)}\n.ckw-col .ckw-skel{margin:0 0 6px;height:96px;background:var(--ckw-card)}\n.ckw-card{position:relative;display:flex;flex-direction:column;gap:6px;padding:12px;border-radius:8px;background:var(--ckw-card);box-shadow:var(--ckw-lift);transition:box-shadow .1s linear}\n.ckw-card:hover{box-shadow:var(--ckw-lift),0 4px 14px rgba(16,18,24,.07)}\n.ckw-card .ckw-link{font-size:14px}\n.ckw-card .ckw-excerpt{margin:0}\n.ckw-card-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:4px}\n.ckw-who{display:inline-flex;align-items:center;gap:6px;min-width:0;font-size:12px;color:var(--ckw-fg2)}\n.ckw-who span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-vote-sm{height:28px;border-radius:7px;font-size:12px}\n@media (max-width:900px){.ckw-cols{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;margin:0 -16px;padding:0 16px 8px;scroll-padding:0 16px}.ckw-col{flex:0 0 min(82%,300px);scroll-snap-align:start}}\n/* Post page */\n.ckw-back{display:inline-flex;align-items:center;gap:4px;background:none;border:0;padding:6px 8px 6px 4px;margin:0 0 12px -4px;border-radius:8px;color:var(--ckw-fg2);font-size:13px;font-weight:550}\n.ckw-back:hover{color:var(--ckw-fg);background:var(--ckw-bg2)}\n.ckw-back-icon{display:inline-block;transform:rotate(-90deg);line-height:0}\n.ckw-detail-grid{display:grid;grid-template-columns:minmax(0,1fr) 260px;gap:32px;align-items:start}\n.ckw-detail-title{margin:0 0 8px;font-size:22px;font-weight:650;letter-spacing:-.015em;overflow-wrap:anywhere;text-wrap:balance}\n.ckw-byline{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ckw-fg2)}\n.ckw-body{white-space:pre-wrap;overflow-wrap:anywhere;color:var(--ckw-fg);margin:16px 0 0;font-size:14.5px;line-height:1.6;text-wrap:pretty}\n.ckw-h{display:flex;align-items:center;gap:6px;font-size:14px;font-weight:650;margin:28px 0 10px;padding-top:20px;border-top:1px solid var(--ckw-line)}\n.ckw-composer{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}\n.ckw-composer .ckw-actions{align-items:center}\n.ckw-as{margin:0 auto 0 0}\n.ckw-comment{display:flex;gap:10px;padding:12px 0;border-top:1px solid var(--ckw-line)}\n.ckw-comment b{font-size:13px}\n.ckw-comment p{margin:3px 0 0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px}\n.ckw-side{position:sticky;top:76px;display:flex;flex-direction:column;gap:12px;padding:14px;border-radius:12px;background:var(--ckw-card);box-shadow:var(--ckw-lift)}\n.ckw-upvote{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;border-radius:8px;border:1px solid var(--ckw-line);background:var(--ckw-bg);font-weight:600;font-size:14px;color:var(--ckw-fg)}\n.ckw-upvote b{margin-left:auto;font-variant-numeric:tabular-nums}\n.ckw-upvote:hover{border-color:var(--ckw-accent);color:var(--ckw-accent)}\n.ckw-upvote[aria-pressed=true]{background:var(--ckw-accent);border-color:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-facts{margin:0;display:flex;flex-direction:column;gap:10px;font-size:13px}\n.ckw-facts div{display:flex;justify-content:space-between;align-items:center;gap:8px}\n.ckw-facts dt{color:var(--ckw-fg3)}\n.ckw-facts dd{margin:0;color:var(--ckw-fg)}\n@media (max-width:760px){.ckw-detail-grid{grid-template-columns:1fr;gap:16px}.ckw-side{position:static;order:-1}}\n/* Changelog */\n.ckw-log{max-width:820px}\n.ckw-entry{display:grid;grid-template-columns:160px minmax(0,1fr);gap:24px;padding:20px 0;border-top:1px solid var(--ckw-line)}\n.ckw-entry:first-child{border-top:0;padding-top:4px}\n.ckw-entry time{font-size:13px;color:var(--ckw-fg3);padding-top:2px}\n.ckw-entry h3{font-size:17px;font-weight:650;margin:0 0 6px;text-wrap:balance}\n.ckw-entry p{margin:0;color:var(--ckw-fg2);white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.6}\n@media (max-width:640px){.ckw-entry{grid-template-columns:1fr;gap:4px}}\n/* Dialog */\n.ckw-scrim{position:fixed;inset:0;z-index:2147483002;background:rgba(0,0,0,.36);display:flex;align-items:center;justify-content:center;padding:16px;animation:ckw-fade .15s ease-out}\n.ckw-modal{width:100%;max-width:520px;max-height:calc(100dvh - 32px);overflow-y:auto;background:var(--ckw-bg);color:var(--ckw-fg);border-radius:14px;box-shadow:var(--ckw-shadow),0 0 0 1px var(--ckw-line);animation:ckw-in .18s ease-out}\n.ckw-modal-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 10px 4px 18px}\n.ckw-modal-head h2{margin:0;font-size:16px;font-weight:650}\n.ckw-modal-body{display:flex;flex-direction:column;gap:12px;padding:8px 18px 18px}\n@keyframes ckw-fade{from{opacity:0}}\n@media (max-width:520px){.ckw-scrim{align-items:flex-end;padding:0}.ckw-modal{max-width:none;border-radius:14px 14px 0 0;max-height:92dvh}}\n.ckw-pair{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n@media (max-width:480px){.ckw-pair{grid-template-columns:1fr}}\n.ckw-fine{margin:-4px 0 0;font-size:12px;color:var(--ckw-fg3);text-wrap:pretty}\n.ckw-opt-l{font-weight:500;color:var(--ckw-fg3)}\n.ckw-foot{text-align:center;font-size:12px;color:var(--ckw-fg3);margin:0;padding:0 16px 24px}\n.ckw-linkish{background:none;border:0;padding:0;color:var(--ckw-fg2);text-decoration:underline;font-size:12px}\n@media (max-width:720px){.ckw-top-row{gap:8px;padding:8px 12px}.ckw-nav{order:3;flex-basis:100%;overflow-x:auto;margin:0 -4px}.ckw-submit span{display:none}.ckw-submit{width:34px;padding:0}.ckw-searchbox[data-open] .ckw-search-input{width:120px}.ckw-top{margin-bottom:16px}.ckw-board.ckw-full>.ckw-body-wrap{padding:0 12px 40px}.ckw-post{padding:12px}.ckw-intro h1{font-size:20px}}\n/* Floating widget */\n.ckw-fab{position:fixed;z-index:2147483000;bottom:20px;display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 16px;border-radius:999px;border:0;background:var(--ckw-accent);color:var(--ckw-accent-ink);font-weight:600;font-size:14px;box-shadow:var(--ckw-shadow)}\n.ckw-fab[data-pos=bottom-right],.ckw-pop[data-pos=bottom-right]{right:20px}\n.ckw-fab[data-pos=bottom-left],.ckw-pop[data-pos=bottom-left]{left:20px}\n.ckw-pop{position:fixed;z-index:2147483001;bottom:70px;width:380px;max-width:calc(100vw - 24px);max-height:min(560px,calc(100vh - 90px));display:flex;flex-direction:column;background:var(--ckw-bg);border:1px solid var(--ckw-line);border-radius:12px;box-shadow:var(--ckw-shadow);overflow:hidden}\n.ckw-pop-head{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--ckw-line);font-weight:600}\n.ckw-pop-body{padding:12px;overflow-y:auto;flex:1}\n.ckw-pop-foot{padding:8px 12px;border-top:1px solid var(--ckw-line);display:flex;justify-content:space-between;align-items:center;font-size:13px}\n.ckw-pop-foot a{color:var(--ckw-accent);text-decoration:none;font-weight:500}\n.ckw-pop .ckw-list{border:0;border-radius:0}\n.ckw-pop .ckw-row{padding:8px 0}\n.ckw-pop .ckw-form{border:0;padding:0;margin:12px 0 0}\n@media (max-width:520px){.ckw-pop{left:0!important;right:0!important;bottom:0;width:100%;max-width:100%;border-radius:12px 12px 0 0;max-height:85vh}.ckw-fab{bottom:14px}.ckw-fab[data-pos=bottom-right]{right:14px}.ckw-fab[data-pos=bottom-left]{left:14px}}\n/* Messenger (messenger-ui.ts). Motion: one soft ease (.32,.72,0,1) for things that arrive, a quick ease-in for things that leave. */\n.ckw-msgr-fab{position:fixed;bottom:20px;height:52px;padding:0 20px 0 16px;gap:8px;font-size:15px;box-shadow:0 1px 2px rgba(16,18,24,.1),0 6px 20px rgba(16,18,24,.16);transition:transform .3s cubic-bezier(.32,.72,0,1),box-shadow .2s linear}\n.ckw-msgr-fab:hover{transform:scale(1.05);box-shadow:0 1px 2px rgba(16,18,24,.1),0 10px 28px rgba(16,18,24,.2)}\n.ckw-msgr-fab:active{transform:scale(.94);transition-duration:.1s}\n.ckw-msgr-round{width:56px;height:56px;padding:0;justify-content:center}\n.ckw-msgr-fab{border-radius:var(--ckw-r-fab)}\n.ckw-msgr-fab-ic{position:relative;display:block;width:20px;height:20px;flex:none}\n.ckw-msgr-round .ckw-msgr-fab-ic{width:27px;height:27px}\n.ckw-msgr-fab .ckw-cut{stroke:var(--ckw-accent)}\n.ckw-msgr-fab-i{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;transition:transform .38s cubic-bezier(.32,.72,0,1),opacity .2s linear}\n.ckw-msgr-fab-i .ckw-icon{width:auto;height:auto}\n.ckw-msgr-fab-i[data-i=x],.ckw-msgr-fab[data-open] .ckw-msgr-fab-i[data-i=chat]{opacity:0;transform:rotate(-90deg) scale(.4)}\n.ckw-msgr-fab[data-open] .ckw-msgr-fab-i[data-i=chat]{transform:rotate(90deg) scale(.4)}\n.ckw-msgr-fab[data-open] .ckw-msgr-fab-i[data-i=x]{opacity:1;transform:none}\n.ckw-msgr-fab-i[data-i=x] .ckw-icon{stroke-width:2.2}\n.ckw-msgr-count{position:absolute;top:-2px;right:-2px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:#ef4444;color:#fff;font-size:10.5px;font-weight:700;line-height:18px;text-align:center;box-shadow:0 0 0 2px var(--ckw-bg);font-variant-numeric:tabular-nums;animation:ckw-badge .4s cubic-bezier(.34,1.56,.64,1)}\n@keyframes ckw-badge{from{transform:scale(0)}}\n.ckw-msgr-av{width:36px;height:36px;border-radius:50%;flex:none;display:inline-flex;align-items:center;justify-content:center;background:var(--ckw-accent);color:var(--ckw-accent-ink);font-size:15px;font-weight:700;line-height:1}\n.ckw-msgr-av-sm{width:26px;height:26px;font-size:12px}\n.ckw-msgr-online{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ckw-fg2)}\n.ckw-msgr-online::before{content:\"\";width:7px;height:7px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 3px color-mix(in srgb,#22c55e 22%,transparent);flex:none}\n/* Floating card over the closed launcher: a new answer */\n.ckw-msgr-preview{position:fixed;z-index:2147483000;bottom:92px;width:320px;max-width:calc(100vw - 32px);transform-origin:bottom right;animation:ckw-rise .34s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-preview[data-pos=bottom-right]{right:20px}\n.ckw-msgr-preview[data-pos=bottom-left]{left:20px;transform-origin:bottom left}\n.ckw-msgr-preview[data-out]{animation:ckw-sink .16s cubic-bezier(.4,0,1,1) forwards;pointer-events:none}\n@keyframes ckw-rise{from{opacity:0;transform:translateY(10px) scale(.94)}}\n@keyframes ckw-sink{to{opacity:0;transform:translateY(6px) scale(.97)}}\n.ckw-msgr-preview-card{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;padding:14px 40px 14px 16px;border:0;border-radius:calc(var(--ckw-r-card) + 2px);background:var(--ckw-bg);box-shadow:var(--ckw-soft);transition:transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-preview-card:hover{transform:translateY(-2px)}\n.ckw-msgr-preview-main{display:flex;flex-direction:column;gap:2px;min-width:0}\n.ckw-msgr-preview-who{font-size:12px;font-weight:600;color:var(--ckw-fg3)}\n.ckw-msgr-preview-text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:pre-wrap;overflow-wrap:anywhere}\n.ckw-msgr-preview-x{position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:50%;border:0;background:transparent;color:var(--ckw-fg3);display:flex;align-items:center;justify-content:center;padding:0;transition:background-color .12s linear,color .12s linear}\n.ckw-msgr-preview-x:hover{background:var(--ckw-bg2);color:var(--ckw-fg)}\n/* The panel */\n.ckw-msgr{bottom:92px;width:400px;height:min(680px,calc(100vh - 112px));max-height:none;border:0;border-radius:var(--ckw-r-panel);box-shadow:var(--ckw-soft);transform-origin:bottom right;animation:ckw-msgr-in .42s cubic-bezier(.32,.72,0,1);transition:width .36s cubic-bezier(.32,.72,0,1),height .36s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr[data-pos=bottom-left]{transform-origin:bottom left}\n.ckw-msgr[data-wide]{width:680px;height:calc(100vh - 112px);max-height:860px}\n.ckw-msgr[data-still]{animation:none}\n.ckw-msgr[data-out]{animation:ckw-msgr-out .2s cubic-bezier(.4,0,1,1) forwards;pointer-events:none}\n@keyframes ckw-msgr-in{from{opacity:0;transform:translateY(20px) scale(.9)}}\n@keyframes ckw-msgr-out{to{opacity:0;transform:translateY(14px) scale(.94)}}\n.ckw-msgr-bar{position:relative;z-index:2;display:flex;align-items:center;gap:8px;padding:12px 12px 10px;background:var(--ckw-bg);flex:none;transition:background-color .25s linear,color .25s linear}\n.ckw-msgr-lead,.ckw-msgr-trail{display:flex;align-items:center;gap:2px;flex:1;min-width:0}\n.ckw-msgr-trail{justify-content:flex-end}\n.ckw-msgr-ib{width:34px;height:34px;padding:0;flex:none;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:transparent;color:var(--ckw-fg2);transition:background-color .12s linear,transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-ib:hover,.ckw-msgr-ib[aria-expanded=true]{background:var(--ckw-bg3);color:var(--ckw-fg)}\n.ckw-msgr-ib:active{transform:scale(.9)}\n.ckw-msgr-ib[aria-current=page]{color:var(--ckw-fg)}\n.ckw-msgr-x{display:none}\n.ckw-msgr-count-tab{top:-1px;right:-3px;min-width:0;width:8px;height:8px;padding:0;font-size:0;line-height:0;box-shadow:0 0 0 2px var(--ckw-bg)}\n.ckw-msgr-menu{position:absolute;z-index:3;top:52px;right:12px;min-width:200px;padding:6px;border-radius:14px;background:var(--ckw-bg);box-shadow:var(--ckw-float);display:flex;flex-direction:column;transform-origin:top right;animation:ckw-menu-in .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-menu[data-out]{animation:ckw-menu-out .12s cubic-bezier(.4,0,1,1) forwards}\n@keyframes ckw-menu-in{from{opacity:0;transform:translateY(-4px) scale(.94)}}\n@keyframes ckw-menu-out{to{opacity:0;transform:scale(.96)}}\n.ckw-msgr-menu-h{padding:6px 10px 4px;font-size:12px;font-weight:600;color:var(--ckw-fg3)}\n.ckw-msgr-menu-i{display:flex;align-items:center;gap:10px;height:36px;padding:0 10px;border:0;border-radius:9px;background:none;font-size:14px;text-align:left;color:var(--ckw-fg)}\n.ckw-msgr-menu-i:hover,.ckw-msgr-menu-i:focus-visible{background:var(--ckw-bg2)}\n.ckw-msgr-menu-i .ckw-icon{color:var(--ckw-fg2)}\n.ckw-msgr-body{display:flex;flex-direction:column;gap:12px;background:var(--ckw-bg);padding:4px 16px 16px;overscroll-behavior:contain;scrollbar-width:thin}\n.ckw-msgr-enter>*{animation:ckw-view .3s cubic-bezier(.32,.72,0,1) backwards}\n.ckw-msgr-enter>:nth-child(2){animation-delay:.03s}\n.ckw-msgr-enter>:nth-child(3){animation-delay:.06s}\n.ckw-msgr-enter>:nth-child(n+4){animation-delay:.09s}\n@keyframes ckw-view{from{opacity:0;transform:translateY(8px)}}\n/* Home */\n.ckw-msgr-hero{display:flex;flex-direction:column;gap:6px;padding:10px 4px 8px}\n.ckw-msgr-brand{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--ckw-fg2);min-width:0}\n.ckw-msgr-brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-msgr-hello{margin:14px 0 0;font-size:28px;font-weight:650;letter-spacing:-.03em;line-height:1.12;text-wrap:balance;overflow-wrap:anywhere}\n.ckw-msgr-card{position:relative;display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:14px 16px;border:0;border-radius:var(--ckw-r-card);background:var(--ckw-bg2);transition:background-color .15s linear,box-shadow .15s linear,transform .25s cubic-bezier(.32,.72,0,1)}\nbutton.ckw-msgr-card:hover{background:var(--ckw-bg3)}\n.ckw-msgr-card-col .ckw-msgr-search{background:var(--ckw-bg)}\n.ckw-msgr-card .ckw-msgr-art:hover{background:var(--ckw-bg3)}\nbutton.ckw-msgr-card:active{transform:scale(.985)}\n.ckw-msgr-card-col{flex-direction:column;align-items:stretch;gap:2px;padding:8px}\n.ckw-msgr-card-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}\n.ckw-msgr-card-main b{font-size:15px;font-weight:650}\n.ckw-msgr-card-sub{color:var(--ckw-fg2);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.ckw-msgr-card-label{font-size:12px;font-weight:600;color:var(--ckw-fg3)}\n.ckw-msgr-card-meta{font-size:12px;color:var(--ckw-fg3)}\n.ckw-msgr-recent{flex-direction:column;align-items:stretch;gap:10px}\n.ckw-msgr-recent-row{display:flex;align-items:center;gap:12px;min-width:0}\n.ckw-msgr-recent-text{color:var(--ckw-fg);font-size:14px}\n.ckw-msgr-card .ckw-icon{color:var(--ckw-fg3)}\n.ckw-msgr-go{width:34px;height:34px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--ckw-accent) 12%,transparent);transition:transform .25s cubic-bezier(.32,.72,0,1)}\nbutton.ckw-msgr-card:hover .ckw-msgr-go{transform:translateX(2px)}\n.ckw-msgr-card .ckw-msgr-go .ckw-icon{color:var(--ckw-accent)}\n.ckw-msgr-badge{width:8px;height:8px;flex:none;border-radius:50%;background:var(--ckw-danger);font-size:0}\n/* Search */\n.ckw-msgr-search{display:flex;align-items:center;gap:10px;height:46px;padding:0 14px;border:1px solid transparent;border-radius:var(--ckw-r-field);background:var(--ckw-bg2);color:var(--ckw-fg3);cursor:text;transition:border-color .15s linear,box-shadow .15s linear,background-color .15s linear}\n.ckw-msgr-card-col .ckw-msgr-search{margin-bottom:4px;height:42px}\n.ckw-msgr-search:focus-within{border-color:var(--ckw-accent);background:var(--ckw-bg);box-shadow:0 0 0 4px color-mix(in srgb,var(--ckw-accent) 16%,transparent);color:var(--ckw-accent)}\n.ckw-msgr-search-in{flex:1;min-width:0;border:0;background:transparent;outline:none;font-size:14.5px;color:var(--ckw-fg)}\n.ckw-root .ckw-msgr-search-in:focus-visible{outline:none}\n.ckw-msgr-search-in::placeholder{color:var(--ckw-fg3)}\n.ckw-msgr-search-in::-webkit-search-cancel-button{display:none}\n.ckw-msgr-art{display:flex;align-items:center;gap:8px;width:100%;text-align:left;padding:10px 8px;border:0;border-radius:10px;background:transparent;font-size:14px;transition:background-color .12s linear}\n.ckw-msgr-art:hover{background:var(--ckw-bg2)}\n.ckw-msgr-art-t{flex:1;min-width:0}\n.ckw-msgr-art .ckw-icon{color:var(--ckw-accent);transition:transform .25s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-art:hover .ckw-icon{transform:translateX(2px)}\n.ckw-msgr-skel{height:40px;margin:4px 0 0}\n/* Help */\n.ckw-msgr-updates{display:flex;flex-direction:column;gap:18px;padding:4px 2px 12px}\n.ckw-msgr-update{display:flex;flex-direction:column;gap:4px}\n.ckw-msgr-update+.ckw-msgr-update{padding-top:18px;border-top:1px solid var(--ckw-line)}\n.ckw-msgr-update-t{margin:0;font-size:15px;font-weight:650;letter-spacing:-.01em}\n.ckw-msgr-update-b{margin:2px 0 0;font-size:14px;line-height:1.55;color:var(--ckw-fg2);white-space:pre-wrap;overflow-wrap:anywhere}\n.ckw-msgr-help-h{margin:6px 0 2px;text-align:center;font-size:16px;font-weight:700;letter-spacing:-.01em}\n.ckw-msgr-hlist{display:flex;flex-direction:column;margin:0 -8px}\n.ckw-msgr-hrow{display:flex;align-items:center;gap:12px;width:100%;padding:12px;border:0;border-radius:14px;background:transparent;text-align:left;transition:background-color .12s linear}\n.ckw-msgr-hrow+.ckw-msgr-hrow{box-shadow:0 -1px 0 var(--ckw-line)}\n.ckw-msgr-hrow:hover,.ckw-msgr-hrow:hover+.ckw-msgr-hrow{box-shadow:none}\n.ckw-msgr-hrow:hover{background:var(--ckw-bg2)}\n.ckw-msgr-hrow-main{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}\n.ckw-msgr-hrow-main b{font-size:14.5px;font-weight:650}\n.ckw-msgr-hrow-sub{font-size:13px;color:var(--ckw-fg2);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.4}\n.ckw-msgr-hrow-meta{font-size:12px;color:var(--ckw-fg3)}\n.ckw-msgr-hrow .ckw-icon{color:var(--ckw-fg3);transition:transform .25s cubic-bezier(.32,.72,0,1),color .12s linear}\n.ckw-msgr-hrow:hover .ckw-icon{color:var(--ckw-fg);transform:translateX(2px)}\n.ckw-msgr-empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:28px 8px;text-align:center;color:var(--ckw-fg2)}\n.ckw-msgr-empty p{margin:0}\n.ckw-msgr-doc{display:flex;flex-direction:column;gap:6px;padding-top:4px}\n.ckw-msgr-doc-t{margin:0;font-size:20px;font-weight:700;letter-spacing:-.015em;line-height:1.3}\n.ckw-msgr-doc-c{margin:0;font-size:12px;color:var(--ckw-fg3)}\n.ckw-msgr-doc-b{margin-top:8px;font-size:14px;line-height:1.6;overflow-wrap:anywhere}\n.ckw-msgr-doc-b>*{margin:0 0 10px}\n.ckw-msgr-doc-b h2{font-size:16px;margin-top:16px}\n.ckw-msgr-doc-b h3{font-size:15px;margin-top:12px}\n.ckw-msgr-doc-b ul,.ckw-msgr-doc-b ol{padding-left:20px}\n.ckw-msgr-doc-b blockquote{border-left:3px solid var(--ckw-line);padding-left:10px;color:var(--ckw-fg2)}\n.ckw-msgr-doc-b pre{background:var(--ckw-bg2);border-radius:8px;padding:10px;overflow-x:auto;font-size:13px}\n.ckw-msgr-doc-b code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}\n.ckw-msgr-doc-b a{color:var(--ckw-accent)}\n.ckw-msgr-doc-b hr{border:0;border-top:1px solid var(--ckw-line)}\n.ckw-msgr-rate{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-top:8px;padding:12px;border-radius:12px;background:var(--ckw-bg2);font-size:13px;color:var(--ckw-fg2)}\n.ckw-msgr-rate-b{display:flex;gap:6px}\n.ckw-msgr-ask{margin-top:6px;width:100%;height:40px;border-radius:12px}\n/* Chat */\n.ckw-msgr-cite{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:7px 10px;border:1px solid var(--ckw-line);border-radius:12px;background:var(--ckw-bg);font-size:13px;text-align:left}\n.ckw-msgr-cite .ckw-icon{color:var(--ckw-accent)}\n.ckw-msgr-cite span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-msgs{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:12px}\n.ckw-msg{display:flex;flex-direction:column;align-items:flex-start;gap:4px;max-width:82%;transform-origin:bottom left}\n.ckw-msg[data-from=me]{align-self:flex-end;align-items:flex-end;transform-origin:bottom right}\n.ckw-msg[data-new]{animation:ckw-bub .4s cubic-bezier(.32,.72,0,1)}\n@keyframes ckw-bub{from{opacity:0;transform:translateY(10px) scale(.92)}}\n.ckw-bubble{padding:10px 14px;border-radius:var(--ckw-r-bubble) var(--ckw-r-bubble) var(--ckw-r-bubble) var(--ckw-r-tail);background:var(--ckw-bg3);white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;line-height:1.45;text-wrap:pretty}\n.ckw-msg[data-from=me] .ckw-bubble{background:var(--ckw-accent);color:var(--ckw-accent-ink);border-radius:var(--ckw-r-bubble) var(--ckw-r-bubble) var(--ckw-r-tail) var(--ckw-r-bubble)}\n.ckw-msg[aria-busy=true] .ckw-bubble{opacity:.7}\n.ckw-msg-meta{font-size:11px;color:var(--ckw-fg3);font-variant-numeric:tabular-nums;padding:0 6px}\n.ckw-msgr-sugg{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:auto;padding-top:12px}\n.ckw-msgr-sugg-b{max-width:100%;padding:9px 14px;border:0;border-radius:var(--ckw-r-card);background:var(--ckw-bg2);font-size:13.5px;text-align:left;color:var(--ckw-fg);transition:background-color .12s linear,color .12s linear,transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-sugg-b:hover{background:var(--ckw-bg3);color:var(--ckw-accent)}\n.ckw-msgr-sugg-b:active{transform:scale(.96)}\n.ckw-msgr-enter .ckw-msgr-sugg-b{animation:ckw-view .34s cubic-bezier(.32,.72,0,1) backwards}\n.ckw-msgr-enter .ckw-msgr-sugg-b:nth-child(2){animation-delay:.12s}\n.ckw-msgr-enter .ckw-msgr-sugg-b:nth-child(3){animation-delay:.18s}\n.ckw-msgr-note{margin:4px 0 0;text-align:center}\n.ckw-msgr-compose{display:flex;flex-direction:column;gap:8px;padding:4px 14px 14px;background:var(--ckw-bg);flex:none}\n.ckw-msgr-compose .ckw-input{border:0;border-radius:var(--ckw-r-field);background:var(--ckw-bg2);min-height:40px;padding:8px 16px}\n.ckw-root .ckw-msgr-compose .ckw-input:focus-visible{outline:none;background:var(--ckw-bg3)}\n.ckw-msgr-box{display:flex;flex-direction:column;align-items:stretch;gap:4px;padding:12px 8px 8px 16px;border:0;border-radius:calc(var(--ckw-r-card) + 4px);background:var(--ckw-bg2);box-shadow:0 0 0 1px color-mix(in srgb,var(--ckw-line) 70%,transparent);cursor:text;transition:background-color .15s linear,box-shadow .15s linear}\n.ckw-msgr-box:focus-within{background:var(--ckw-bg);box-shadow:0 0 0 1px var(--ckw-line),0 6px 18px rgba(16,18,24,.07)}\n.ckw-msgr-tools{display:flex;align-items:center;gap:2px;margin-left:-8px}\n.ckw-msgr-sp{flex:1}\n.ckw-msgr-input{flex:1;min-width:0;min-height:24px;max-height:140px;padding:2px 8px 2px 0;border:0;border-radius:0;background:transparent;resize:none;field-sizing:content;font-size:14.5px}\n.ckw-root .ckw-msgr-input:focus-visible{outline:none}\n.ckw-msgr-send{width:32px;height:32px;padding:0;flex:none;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:var(--ckw-accent);color:var(--ckw-accent-ink);transition:background-color .15s linear,color .15s linear,transform .25s cubic-bezier(.34,1.56,.64,1)}\n.ckw-msgr-send:not(:disabled):hover{transform:scale(1.08)}\n.ckw-msgr-send:not(:disabled):active{transform:scale(.9)}\n.ckw-msgr-send:disabled{background:var(--ckw-bg3);color:var(--ckw-fg3);cursor:default}\n/* Files: the paperclip in the field, picked files above it, sent ones in the bubbles, dropping onto the panel */\n.ckw-msgr-compose{position:relative}\n.ckw-msgr-clip{width:32px;height:32px;padding:0;flex:none;display:flex;align-items:center;justify-content:center;border:0;border-radius:calc(var(--ckw-r-field) - 4px);background:transparent;color:var(--ckw-fg3);transition:color .12s linear,background-color .12s linear,transform .2s cubic-bezier(.32,.72,0,1)}\n.ckw-msgr-clip:hover,.ckw-msgr-clip[aria-expanded=true]{color:var(--ckw-fg);background:color-mix(in srgb,var(--ckw-fg) 7%,transparent)}\n.ckw-msgr-clip:active{transform:scale(.9)}\n\n.ckw-msgr-amenu{top:auto;bottom:calc(100% - 6px);left:14px;right:auto;min-width:0;transform-origin:bottom left}\n.ckw-msgr-files{display:flex;flex-wrap:wrap;gap:10px;padding:6px 2px 0}\n.ckw-msgr-file{position:relative;width:56px;height:56px;border-radius:calc(var(--ckw-r-card) - 4px);background:var(--ckw-bg2);box-shadow:0 0 0 1px var(--ckw-line)}\n.ckw-msgr-file img{display:block;width:100%;height:100%;object-fit:cover;border-radius:inherit}\n.ckw-msgr-file[aria-busy=true] img,.ckw-msgr-file[aria-busy=true] .ckw-msgr-file-doc{opacity:.45}\n.ckw-msgr-file[aria-busy=true]::after{content:\"\";position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-9px 0 0 -9px;border:2px solid var(--ckw-fg2);border-right-color:transparent;border-radius:50%;animation:ckw-spin .8s linear infinite}\n@keyframes ckw-spin{to{transform:rotate(360deg)}}\n.ckw-msgr-file-doc{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;width:100%;height:100%;padding:4px;color:var(--ckw-fg2);font-size:10px;line-height:1.2}\n.ckw-msgr-file-doc span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ckw-msgr-file-x{position:absolute;top:-7px;right:-7px;width:20px;height:20px;padding:0;display:flex;align-items:center;justify-content:center;border:2px solid var(--ckw-bg);border-radius:50%;background:var(--ckw-fg);color:var(--ckw-bg)}\n.ckw-msgr-file-x .ckw-icon{width:10px;height:10px}\n.ckw-msg-files{display:flex;flex-wrap:wrap;gap:6px;max-width:100%}\n.ckw-msg[data-from=me] .ckw-msg-files{justify-content:flex-end}\n.ckw-msg-img{display:block;overflow:hidden;border-radius:var(--ckw-r-bubble);background:var(--ckw-bg3);box-shadow:0 0 0 1px var(--ckw-line)}\n.ckw-msg-img img{display:block;max-width:220px;max-height:200px;min-width:48px;min-height:48px;object-fit:cover}\n.ckw-msg-files a.ckw-msgr-cite{color:var(--ckw-fg);text-decoration:none}\n.ckw-msgr[data-drop]::after{content:\"Drop to attach\";position:absolute;inset:8px;z-index:5;display:flex;align-items:center;justify-content:center;border:2px dashed var(--ckw-accent);border-radius:calc(var(--ckw-r-panel) - 6px);background:color-mix(in srgb,var(--ckw-bg) 90%,transparent);color:var(--ckw-fg);font-size:15px;font-weight:600;pointer-events:none}\n/* Powered by */\n.ckw-msgr-powered{flex:none;display:block;padding:2px 0 10px;text-align:center;font-size:11.5px;color:var(--ckw-fg3);text-decoration:none;background:var(--ckw-bg)}\n.ckw-msgr-powered b{font-weight:650;color:var(--ckw-fg2)}\n.ckw-msgr-powered:hover b{color:var(--ckw-fg)}\n.ckw-msgr-compose:has(+.ckw-msgr-powered){padding-bottom:8px}\n.ckw-msgr-error{margin:0;font-size:12px;color:var(--ckw-danger)}\n.ckw-msgr .ckw-input[aria-invalid=true]{box-shadow:0 0 0 1px var(--ckw-danger)}\n/* The email asked of anonymous visitors: the box's first line, under a hairline the message follows */\n.ckw-root .ckw-msgr-box .ckw-input.ckw-msgr-email{min-height:0;height:26px;margin:-2px 8px 6px 0;padding:0 0 6px;border:0;border-radius:0;background:none;box-shadow:0 1px 0 var(--hu-border,var(--ckw-line));font-size:13px;color:var(--ckw-fg2)}\n.ckw-root .ckw-msgr-box .ckw-input.ckw-msgr-email:focus-visible{background:none;box-shadow:0 1px 0 var(--ckw-accent);color:var(--ckw-fg)}\n.ckw-root .ckw-msgr-box .ckw-input.ckw-msgr-email[aria-invalid=true]{box-shadow:0 1px 0 var(--ckw-danger)}\n/* The team's mark as a picture, the AI agent's face on its answers */\n.ckw-root .ckw-msgr-av-img{background:none;overflow:hidden}\n.ckw-msgr-av-img img{width:100%;height:100%;object-fit:cover;border-radius:inherit}\n.ckw-msg-face{width:16px;height:16px;margin:0 5px -3px 0;border-radius:50%;object-fit:cover}\n/* Bar middle, tab bar, Home's glow and \"Ask a question\" (Featurebase-like) */\n.ckw-msgr-mid{display:flex;align-items:center;justify-content:center;gap:10px;min-width:0;max-width:62%;flex:none}\n.ckw-msgr-mid b{font-size:15px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.ckw-msgr-mid-t{display:flex;flex-direction:column;gap:1px;min-width:0;line-height:1.25}\n.ckw-msgr-mid-t .ckw-msgr-online{font-size:11.5px;white-space:nowrap}\n.ckw-msgr-mid-t .ckw-msgr-online::before{width:6px;height:6px;box-shadow:none}\n.ckw-msgr-tabs{flex:none;display:flex;padding:6px 10px 4px;background:var(--ckw-bg);box-shadow:0 -1px 0 color-mix(in srgb,var(--ckw-line) 60%,transparent)}\n.ckw-msgr-tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 0 4px;border:0;border-radius:12px;background:none;color:var(--ckw-fg3);font-size:12px;font-weight:550;transition:color .15s linear}\n.ckw-msgr-tab:hover{color:var(--ckw-fg2)}\n.ckw-msgr-tab[aria-current=page]{color:var(--ckw-fg)}\n.ckw-msgr-tab-ic{position:relative;display:block;width:22px;height:22px;transition:transform .25s cubic-bezier(.34,1.56,.64,1)}\n.ckw-msgr-tab:active .ckw-msgr-tab-ic{transform:scale(.88)}\n.ckw-msgr-tab-ic>.ckw-icon{position:absolute;inset:0;transition:opacity .15s linear,transform .3s cubic-bezier(.34,1.56,.64,1)}\n.ckw-msgr-tab-ic>.ckw-icon+.ckw-icon{opacity:0;transform:scale(.75)}\n.ckw-msgr-tab[aria-current=page] .ckw-msgr-tab-ic>.ckw-icon:first-child{opacity:0}\n.ckw-msgr-tab[aria-current=page] .ckw-msgr-tab-ic>.ckw-icon+.ckw-icon{opacity:1;transform:none}\n.ckw-cut{stroke:var(--ckw-bg)}\n.ckw-root:not([data-header=color]) .ckw-msgr[data-view=home] :is(.ckw-msgr-bar,.ckw-msgr-body){background:transparent}\n.ckw-msgr-askq{display:flex;align-items:center;gap:8px;height:52px;margin:6px 0 4px;padding:0 7px 0 18px;border-radius:var(--ckw-r-field);background:var(--ckw-bg2);box-shadow:0 0 0 1px color-mix(in srgb,var(--ckw-line) 70%,transparent);transition:background-color .15s linear,box-shadow .15s linear}\n.ckw-msgr-askq:focus-within{background:var(--ckw-bg);box-shadow:0 0 0 1px var(--ckw-line),0 6px 18px rgba(16,18,24,.07)}\n.ckw-msgr-askq-in{flex:1;min-width:0;border:0;background:transparent;outline:none;font-size:15px;color:var(--ckw-fg)}\n.ckw-msgr-askq-in::placeholder{color:var(--ckw-fg3)}\n.ckw-root .ckw-msgr-askq-in:focus-visible{outline:none}\n.ckw-msgr-askq .ckw-msgr-send{width:38px;height:38px}\n.ckw-root[data-header=color] .ckw-msgr-askq{background:var(--ckw-card);box-shadow:var(--ckw-raise)}\n/* Home in the accent color (look: header \"color\"): the bar and the top in the accent, raised cards over its edge */\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-bar{background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-ib{color:color-mix(in srgb,var(--ckw-accent-ink) 80%,transparent)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-ib:hover,.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-ib[aria-expanded=true]{background:color-mix(in srgb,var(--ckw-accent-ink) 14%,transparent);color:var(--ckw-accent-ink)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-body,.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-powered{background:var(--ckw-bg2)}\n.ckw-root[data-header=color] .ckw-msgr[data-view=home] .ckw-msgr-body{scrollbar-width:none}\n.ckw-root[data-header=color] .ckw-msgr-hero{margin:-4px -16px 0;padding:14px 20px 64px;background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-root[data-header=color] .ckw-msgr-hero .ckw-msgr-brand,.ckw-root[data-header=color] .ckw-msgr-hero .ckw-msgr-online{color:color-mix(in srgb,var(--ckw-accent-ink) 82%,transparent)}\n.ckw-root[data-header=color] .ckw-msgr-hero .ckw-msgr-av{background:var(--ckw-accent-ink);color:var(--ckw-accent)}\n.ckw-root[data-header=color] .ckw-msgr-hero+*{margin-top:-58px}\n.ckw-root[data-header=color] .ckw-msgr-card{background:var(--ckw-card);box-shadow:var(--ckw-raise)}\n.ckw-root[data-header=color] button.ckw-msgr-card:hover{background:var(--ckw-card);transform:translateY(-1px)}\n.ckw-root[data-header=color] .ckw-msgr-card-col .ckw-msgr-search{background:var(--ckw-bg2)}\n.ckw-root[data-header=color] .ckw-msgr-card .ckw-msgr-art:hover{background:var(--ckw-bg2)}\n/* Where it sits: a corner, the middle of the top or bottom edge, or the middle of a side; panel and cards open from the launcher */\n.ckw-msgr-fab[data-pos$=left],.ckw-msgr[data-pos$=left],.ckw-msgr-preview[data-pos$=left]{left:20px;right:auto}\n.ckw-msgr-fab[data-pos$=right],.ckw-msgr[data-pos$=right],.ckw-msgr-preview[data-pos$=right]{right:20px;left:auto}\n.ckw-msgr-fab[data-pos$=center],.ckw-msgr[data-pos$=center],.ckw-msgr-preview[data-pos$=center]{left:50%;right:auto;translate:-50% 0}\n.ckw-msgr-fab[data-pos^=top]{top:20px;bottom:auto}\n.ckw-msgr[data-pos^=top],.ckw-msgr-preview[data-pos^=top]{top:92px;bottom:auto}\n.ckw-msgr-fab[data-pos^=middle],.ckw-msgr[data-pos^=middle],.ckw-msgr-preview[data-pos^=middle]{top:50%;bottom:auto;translate:0 -50%}\n.ckw-msgr[data-pos=middle-left],.ckw-msgr-preview[data-pos=middle-left]{left:92px}\n.ckw-msgr[data-pos=middle-right],.ckw-msgr-preview[data-pos=middle-right]{right:92px}\n.ckw-msgr[data-pos^=middle]{height:min(680px,calc(100vh - 40px))}\n.ckw-msgr[data-pos=top-right],.ckw-msgr-preview[data-pos=top-right]{transform-origin:top right}\n.ckw-msgr[data-pos=top-left],.ckw-msgr-preview[data-pos=top-left]{transform-origin:top left}\n.ckw-msgr[data-pos=top-center],.ckw-msgr-preview[data-pos=top-center]{transform-origin:top center}\n.ckw-msgr[data-pos=bottom-center],.ckw-msgr-preview[data-pos=bottom-center]{transform-origin:bottom center}\n.ckw-msgr[data-pos=middle-left],.ckw-msgr-preview[data-pos=middle-left]{transform-origin:center left}\n.ckw-msgr[data-pos=middle-right],.ckw-msgr-preview[data-pos=middle-right]{transform-origin:center right}\n@media (max-width:520px){.ckw-root:not([data-contained]) .ckw-msgr{top:0;translate:none}.ckw-msgr-fab[data-pos$=left]{left:14px}.ckw-msgr-fab[data-pos$=right]{right:14px}.ckw-msgr-fab[data-pos^=top]{top:14px}.ckw-msgr-preview[data-pos^=top]{top:84px}.ckw-msgr-preview[data-pos^=middle]{top:auto;bottom:20px;left:16px;right:16px;width:auto;translate:none}}\n/* Inside MRRocket's preview: placed in its frame, not the page */\n.ckw-root[data-contained]{position:absolute;inset:0;pointer-events:none;overflow:hidden}\n.ckw-root[data-contained]>*{position:absolute;pointer-events:auto}\n.ckw-root[data-contained] .ckw-msgr{height:min(680px,calc(100% - 112px));max-width:calc(100% - 40px)}\n.ckw-root[data-contained] .ckw-msgr[data-wide]{height:calc(100% - 112px)}\n.ckw-root[data-contained] .ckw-msgr[data-pos^=middle]{height:min(680px,calc(100% - 40px));max-width:calc(100% - 112px)}\n.ckw-root[data-contained] .ckw-msgr-preview[data-pos^=middle]{max-width:calc(100% - 112px)}\n@media (max-width:520px){.ckw-root:not([data-contained]) .ckw-msgr{width:100%;height:100dvh;bottom:0;border-radius:0;transform-origin:bottom center}.ckw-root:not([data-contained]) .ckw-msgr-x{display:flex}.ckw-msgr-preview{bottom:84px}}\n@media (prefers-reduced-motion:reduce){.ckw-msgr,.ckw-msgr[data-out],.ckw-msgr-preview,.ckw-msgr-menu,.ckw-msgr-count,.ckw-msg[data-new],.ckw-msgr-enter>*,.ckw-msgr-enter .ckw-msgr-sugg-b{animation:none}.ckw-msgr-fab,.ckw-msgr-fab-i,.ckw-msgr-tab-ic,.ckw-msgr-tab-ic>.ckw-icon,.ckw-msgr{transition:none}}\n/* The messenger in HeroUI v3's look (heroui.com, its free components): a soft gray ground, white surfaces with a hairline\n shadow, white fields, pill buttons and a pill tab switch, a 2px ring in the accent on focus. Its tokens (--hu-*) map onto\n the widget's own, inside the messenger only, so the other widgets keep theirs. */\n.ckw-root{--hu-bg:#fff;--hu-surface:#f4f4f5;--hu-default:#ececee;--hu-default-hover:#e4e4e7;--hu-segment:#fff;--hu-muted:#71717a;--hu-fg:#18181b;--hu-border:#e4e4e7;--hu-shadow:0 0 0 0 transparent;--hu-lift:0 1px 2px rgba(0,0,0,.08),0 0 1px rgba(0,0,0,.1);--hu-overlay:0 0 0 1px rgba(0,0,0,.05),0 2px 8px rgba(0,0,0,.05),0 18px 40px rgba(0,0,0,.1)}\n.ckw-root[data-theme=dark]{--hu-bg:#111113;--hu-surface:#1c1c1f;--hu-default:#26262a;--hu-default-hover:#2e2e33;--hu-segment:#3a3a40;--hu-muted:#a1a1aa;--hu-fg:#fafafa;--hu-border:#27272a;--hu-shadow:0 0 0 0 transparent;--hu-lift:0 0 0 1px rgba(255,255,255,.06);--hu-overlay:0 0 0 1px rgba(255,255,255,.08),0 18px 40px rgba(0,0,0,.55)}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto]{--hu-bg:#111113;--hu-surface:#1c1c1f;--hu-default:#26262a;--hu-default-hover:#2e2e33;--hu-segment:#3a3a40;--hu-muted:#a1a1aa;--hu-fg:#fafafa;--hu-border:#27272a;--hu-shadow:0 0 0 0 transparent;--hu-lift:0 0 0 1px rgba(255,255,255,.06);--hu-overlay:0 0 0 1px rgba(255,255,255,.08),0 18px 40px rgba(0,0,0,.55)}}\n.ckw-msgr,.ckw-msgr-preview{--ckw-bg:var(--hu-bg);--ckw-bg2:var(--hu-surface);--ckw-bg3:var(--hu-default);--ckw-card:var(--hu-surface);--ckw-fg:var(--hu-fg);--ckw-fg2:var(--hu-muted);--ckw-fg3:var(--hu-muted);--ckw-line:var(--hu-border);--ckw-soft:var(--hu-overlay);--ckw-raise:var(--hu-shadow)}\n.ckw-root .ckw-msgr-preview-card{background:var(--hu-surface)}\n.ckw-root .ckw-msgr-card,.ckw-root .ckw-msgr-sugg-b,.ckw-root .ckw-msgr-rate,.ckw-root .ckw-msgr-cite{background:var(--hu-surface);box-shadow:var(--hu-shadow);border:0}\n.ckw-root button.ckw-msgr-card:hover{background:var(--hu-default)}\n.ckw-root .ckw-msgr-card-col{padding:6px}\n.ckw-root .ckw-msgr-card .ckw-msgr-art:hover,.ckw-root .ckw-msgr-hrow:hover{background:var(--hu-default)}\n.ckw-root .ckw-msgr-hrow+.ckw-msgr-hrow{box-shadow:0 -1px 0 var(--hu-border)}\n.ckw-root .ckw-msgr-search,.ckw-root .ckw-msgr-askq,.ckw-root .ckw-msgr-box,.ckw-root .ckw-msgr-compose .ckw-input{background:var(--hu-surface);border:0;box-shadow:var(--hu-shadow)}\n.ckw-root .ckw-msgr-search:focus-within,.ckw-root .ckw-msgr-askq:focus-within,.ckw-root .ckw-msgr-box:focus-within,.ckw-root .ckw-msgr-compose .ckw-input:focus-visible{background:var(--hu-surface);box-shadow:0 0 0 1.5px color-mix(in srgb,var(--ckw-accent) 55%,transparent),0 0 0 5px color-mix(in srgb,var(--ckw-accent) 12%,transparent);color:var(--ckw-fg3)}\n.ckw-root .ckw-msgr-askq{height:48px;border-radius:24px}\n.ckw-root .ckw-msgr-box{border-radius:20px}\n.ckw-root .ckw-msgr-send{border-radius:999px}\n.ckw-root .ckw-msgr-send:disabled{background:var(--hu-default);color:var(--hu-muted)}\n.ckw-root .ckw-msgr-send:not(:disabled):hover{transform:none;filter:brightness(1.08)}\n.ckw-root .ckw-msgr-send:not(:disabled):active{transform:scale(.97)}\n.ckw-root .ckw-bubble{background:var(--hu-surface);box-shadow:var(--hu-shadow)}\n.ckw-root .ckw-msg[data-from=me] .ckw-bubble{box-shadow:none}\n.ckw-root .ckw-msgr-av{background:color-mix(in srgb,var(--ckw-accent) 16%,var(--hu-surface));color:var(--ckw-accent);font-weight:600}\n.ckw-root .ckw-msgr-ib:hover,.ckw-root .ckw-msgr-ib[aria-expanded=true]{background:var(--hu-default)}\n.ckw-root .ckw-msgr-menu{background:var(--hu-surface);box-shadow:var(--hu-overlay);border-radius:16px}\n.ckw-root .ckw-msgr-menu-i{border-radius:10px}\n.ckw-root .ckw-msgr-menu-i:hover,.ckw-root .ckw-msgr-menu-i:focus-visible{background:var(--hu-default)}\n.ckw-root .ckw-msgr .ckw-btn{height:36px;padding:0 16px;border:0;border-radius:999px;background:var(--hu-default);color:var(--hu-fg);font-size:14px;font-weight:500;box-shadow:none;transition:transform .25s cubic-bezier(.32,.72,0,1),background-color .1s linear}\n.ckw-root .ckw-msgr .ckw-btn:hover{background:var(--hu-default-hover);filter:none}\n.ckw-root .ckw-msgr .ckw-btn:active{transform:scale(.97)}\n.ckw-root .ckw-msgr .ckw-btn-primary{background:var(--ckw-accent);color:var(--ckw-accent-ink)}\n.ckw-root .ckw-msgr .ckw-btn-primary:hover{background:var(--ckw-accent);filter:brightness(1.08)}\n.ckw-root .ckw-msgr-sugg-b{border-radius:999px}\n.ckw-root .ckw-msgr-ask{height:40px;border-radius:999px}\n/* Home like Featurebase: the product's icon top left, \"Hi, Lukas 👋\" over the greeting in gray, a silk of the accent\n with drifting dots behind the top right (.ckw-msgr-sky, also drawn by MRRocket's phone preview) */\n.ckw-msgr-logo{display:flex;align-items:center;min-width:32px;height:32px;flex:none;margin-left:6px}\n.ckw-msgr-logo img{height:28px;width:auto;min-width:28px;max-width:132px;border-radius:8px;object-fit:contain}\n.ckw-root .ckw-msgr[data-view=home] .ckw-msgr-bar{padding-top:16px}\n.ckw-root .ckw-msgr[data-view=home] .ckw-msgr-body{position:relative;z-index:1;gap:10px;padding-top:0}\n.ckw-root .ckw-msgr-hero.ckw-msgr-hello{display:flex;flex-direction:column;gap:1px;margin:22px 0 10px;padding:0 4px;font-size:25px;font-weight:600;letter-spacing:-.028em;line-height:1.2;color:var(--hu-fg)}\n.ckw-msgr-hello-sub{color:var(--hu-muted);font-weight:500}\n.ckw-msgr-wave{display:inline-block;transform-origin:70% 75%;animation:ckw-wave 2.4s ease-in-out .6s 1 both}\n@keyframes ckw-wave{0%,60%,100%{transform:none}10%,30%{transform:rotate(14deg)}20%{transform:rotate(-8deg)}40%{transform:rotate(-4deg)}50%{transform:rotate(10deg)}}\n.ckw-root .ckw-msgr[data-view=home] .ckw-msgr-askq{margin:0 0 6px}\n.ckw-msgr-sky{position:absolute;z-index:0;top:0;left:0;right:0;height:250px;pointer-events:none;overflow:hidden;border-radius:inherit;-webkit-mask-image:linear-gradient(to bottom,#000 25%,transparent 92%);mask-image:linear-gradient(to bottom,#000 25%,transparent 92%)}\n.ckw-msgr-sky::before{content:\"\";position:absolute;top:-45%;right:-25%;width:115%;height:135%;background:radial-gradient(36% 40% at 62% 46%,color-mix(in srgb,var(--ckw-accent) 92%,#fff) 0%,transparent 70%),radial-gradient(32% 36% at 86% 24%,color-mix(in srgb,var(--ckw-glow2,var(--ckw-accent)) 70%,#fff) 0%,transparent 72%),radial-gradient(46% 30% at 36% 64%,color-mix(in srgb,var(--ckw-glow3,var(--ckw-glow2,var(--ckw-accent))) 50%,#fff) 0%,transparent 70%);filter:blur(20px);opacity:.75;animation:ckw-silk 16s cubic-bezier(.45,0,.55,1) infinite alternate}\n@keyframes ckw-silk{to{transform:translate(-7%,5%) rotate(8deg) scale(1.08)}}\n.ckw-msgr-sky::after{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,color-mix(in srgb,var(--ckw-accent) 85%,#fff) .9px,transparent 1.4px);background-size:5px 5px;-webkit-mask-image:linear-gradient(110deg,transparent 0%,#000 18%,transparent 34%,#000 52%,transparent 70%),radial-gradient(70% 85% at 88% 12%,#000 15%,transparent 75%);-webkit-mask-size:220% 100%,100% 100%;-webkit-mask-repeat:repeat-x,no-repeat;-webkit-mask-composite:source-in;mask-image:linear-gradient(110deg,transparent 0%,#000 18%,transparent 34%,#000 52%,transparent 70%),radial-gradient(70% 85% at 88% 12%,#000 15%,transparent 75%);mask-size:220% 100%,100% 100%;mask-repeat:repeat-x,no-repeat;mask-composite:intersect;opacity:.6;animation:ckw-dots 11s linear infinite}\n@keyframes ckw-dots{from{-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0}to{-webkit-mask-position:-220% 0,0 0;mask-position:-220% 0,0 0}}\n.ckw-root[data-theme=dark] .ckw-msgr-sky::before{opacity:.4}\n.ckw-root[data-theme=dark] .ckw-msgr-sky::after{opacity:.4}\n@media (prefers-color-scheme:dark){.ckw-root[data-theme=auto] .ckw-msgr-sky::before{opacity:.4}.ckw-root[data-theme=auto] .ckw-msgr-sky::after{opacity:.4}}\n.ckw-root[data-header=color] .ckw-msgr-sky{display:none}\n@media (prefers-reduced-motion:reduce){.ckw-msgr-sky::before,.ckw-msgr-sky::after,.ckw-msgr-wave{animation:none}}\n/* Home's latest message: one quiet row, the small mark, the words, who and when */\n.ckw-root .ckw-msgr-recent{padding:10px 12px;gap:0}\n.ckw-root .ckw-msgr-recent .ckw-msgr-recent-row{gap:10px}\n.ckw-root .ckw-msgr-recent .ckw-msgr-card-main{gap:1px}\n.ckw-root .ckw-msgr-recent-text{font-size:13.5px;font-weight:500}\n.ckw-root .ckw-msgr-recent .ckw-msgr-card-meta{font-size:11.5px}\n.ckw-msgr-chats{display:flex;flex-direction:column;gap:8px}\n.ckw-msgr-new{align-self:center;display:inline-flex;align-items:center;gap:8px;margin-top:4px}\n.ckw-msgr-all{display:inline-flex;align-items:center;justify-content:center;gap:4px;width:100%;padding:6px;border:0;background:none;color:var(--ckw-fg2);font-size:13px;font-weight:500;cursor:pointer}\n.ckw-msgr-all:hover{color:var(--ckw-fg)}\n/* The tab switch: HeroUI's Tabs, a gray pill with the current tab on a raised white one */\n.ckw-root .ckw-msgr-tabs{position:relative;z-index:1;margin:2px 12px 8px;padding:4px;gap:0;border-radius:999px;background:var(--hu-surface);box-shadow:none}\n.ckw-root .ckw-msgr-tab{flex-direction:row;justify-content:center;gap:7px;height:36px;padding:0 10px;border-radius:999px;color:var(--hu-muted);font-size:13.5px;font-weight:500;transition:color .15s ease,background-color .15s ease,box-shadow .15s ease,opacity .15s ease}\n.ckw-root .ckw-msgr-tabs[data-four]{border-radius:20px}\n.ckw-root .ckw-msgr-tabs[data-four] .ckw-msgr-tab{flex:1 1 0;min-width:0;flex-direction:column;gap:2px;height:50px;padding:0 2px;border-radius:16px;font-size:11.5px}\n.ckw-root .ckw-msgr-tab:not([aria-current=page]):hover{color:var(--hu-muted);opacity:.7}\n.ckw-root .ckw-msgr-tab[aria-current=page]{background:var(--hu-segment);color:var(--hu-fg);box-shadow:var(--hu-lift)}\n.ckw-root .ckw-msgr-tab-ic{width:18px;height:18px}\n.ckw-root .ckw-msgr-tab .ckw-cut{stroke:var(--hu-segment)}\n.ckw-root .ckw-msgr-count-tab{box-shadow:0 0 0 2px var(--hu-default)}\n.ckw-root .ckw-msgr-tab[aria-current=page] .ckw-msgr-count-tab{box-shadow:0 0 0 2px var(--hu-segment)}\n.ckw-root .ckw-msgr-powered{background:var(--hu-bg);padding-top:0}\n/* Survey */\n.ckw-survey{position:fixed;z-index:2147483000;left:20px;bottom:20px;width:360px;max-width:calc(100vw - 24px);background:var(--ckw-bg);border:1px solid var(--ckw-line);border-radius:12px;box-shadow:var(--ckw-shadow);padding:14px;animation:ckw-in .2s ease-out}\n@keyframes ckw-in{from{opacity:0;transform:translateY(8px)}}\n@media (max-width:520px){.ckw-survey{left:0;right:0;bottom:0;width:100%;max-width:100%;border-radius:12px 12px 0 0}}\n.ckw-sv-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}\n.ckw-dots{display:flex;gap:4px}\n.ckw-dot{width:6px;height:6px;border-radius:50%;background:var(--ckw-bg3)}\n.ckw-dot[data-on=true]{background:var(--ckw-accent)}\n.ckw-q{font-weight:600;font-size:15px;margin:0 0 2px;border:0;padding:0}\n.ckw-root .ckw-q:focus-visible{outline:none}\n.ckw-qd{color:var(--ckw-fg2);font-size:13px;margin:0 0 10px}\n.ckw-scale{display:flex;gap:4px;flex-wrap:wrap}\n.ckw-num{flex:1 1 0;min-width:26px;height:34px;border:1px solid var(--ckw-line);background:var(--ckw-bg);border-radius:8px;font-size:13px;font-weight:600;padding:0}\n.ckw-num:hover{border-color:var(--ckw-accent)}\n.ckw-num[aria-pressed=true]{background:var(--ckw-accent);color:var(--ckw-accent-ink);border-color:var(--ckw-accent)}\n.ckw-root .ckw-star{background:none;border:0;padding:2px;color:var(--ckw-bg3)}\n.ckw-root .ckw-star[data-on=true]{color:#f5a524}\n.ckw-star svg{width:28px;height:28px}\n.ckw-lh{display:flex;justify-content:space-between;color:var(--ckw-fg3);font-size:11px;margin-top:4px}\n.ckw-opts{display:flex;flex-direction:column;gap:6px}\n.ckw-opt{display:flex;gap:8px;align-items:center;border:1px solid var(--ckw-line);border-radius:8px;padding:7px 10px;background:var(--ckw-bg);cursor:pointer}\n.ckw-opt:has(input:checked){border-color:var(--ckw-accent);background:color-mix(in srgb,var(--ckw-accent) 8%,transparent)}\n.ckw-opt input{accent-color:var(--ckw-accent)}\n.ckw-sv-foot{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-top:12px}\n.ckw-thanks{text-align:center;padding:14px 0;display:flex;flex-direction:column;align-items:center;gap:8px}\n.ckw-tick{width:32px;height:32px;border-radius:50%;background:var(--ckw-accent);color:var(--ckw-accent-ink);display:flex;align-items:center;justify-content:center}\n`;\n\n/** Puts the stylesheet into the page once, however many widgets mount. */\nexport const injectStyles = () => {\n if (typeof document === \"undefined\" || document.getElementById(STYLE_ID)) return;\n const el = document.createElement(\"style\");\n el.id = STYLE_ID;\n el.textContent = CSS;\n document.head.appendChild(el);\n};\n"],"mappings":";AACO,IAAM,WAAW;AAGjB,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAumBZ,IAAM,eAAe,MAAM;AAC9B,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,QAAQ,EAAG;AAC1E,QAAM,KAAK,SAAS,cAAc,OAAO;AACzC,KAAG,KAAK;AACR,KAAG,cAAc;AACjB,WAAS,KAAK,YAAY,EAAE;AAChC;","names":[]}
package/dist/survey.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { useCallback, useEffect, useRef, useState } from "react";
5
5
  import { useApi } from "./api.js";
6
6
  import { useCtx } from "./context.js";
7
+ import { t, tf } from "./i18n.js";
7
8
  import { Check, Cross, Root, Star } from "./ui.js";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  var DISMISS_PREFIX = "ck_survey_";
@@ -45,18 +46,18 @@ var Question = ({ q, value, onChange, onEnter }) => {
45
46
  const stars = q.kind === "rating" && scale <= 5;
46
47
  return /* @__PURE__ */ jsxs("div", { children: [
47
48
  /* @__PURE__ */ jsx("div", { className: "ckw-scale", role: "group", "aria-label": q.title, children: items.map(
48
- (n) => stars ? /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-star", "data-on": typeof value === "number" && n <= value, "aria-pressed": value === n, "aria-label": `${n} of ${scale}`, onClick: () => onChange(n), children: /* @__PURE__ */ jsx(Star, {}) }, n) : /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-num", "aria-pressed": value === n, onClick: () => onChange(n), children: n }, n)
49
+ (n) => stars ? /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-star", "data-on": typeof value === "number" && n <= value, "aria-pressed": value === n, "aria-label": tf("{n} of {total}", { n, total: scale }), onClick: () => onChange(n), children: /* @__PURE__ */ jsx(Star, {}) }, n) : /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-num", "aria-pressed": value === n, onClick: () => onChange(n), children: n }, n)
49
50
  ) }),
50
51
  (q.low || q.high || q.kind === "nps") && /* @__PURE__ */ jsxs("div", { className: "ckw-lh", children: [
51
- /* @__PURE__ */ jsx("span", { children: q.low ?? (q.kind === "nps" ? "Not likely" : "") }),
52
- /* @__PURE__ */ jsx("span", { children: q.high ?? (q.kind === "nps" ? "Very likely" : "") })
52
+ /* @__PURE__ */ jsx("span", { children: q.low ?? (q.kind === "nps" ? t("Not likely") : "") }),
53
+ /* @__PURE__ */ jsx("span", { children: q.high ?? (q.kind === "nps" ? t("Very likely") : "") })
53
54
  ] })
54
55
  ] });
55
56
  }
56
57
  if (q.kind === "single" || q.kind === "multi") {
57
58
  const multi = q.kind === "multi";
58
59
  const picked = multi ? value ?? [] : [];
59
- return /* @__PURE__ */ jsx("div", { className: "ckw-opts", role: multi ? "group" : "radiogroup", "aria-label": q.title, children: (q.options ?? []).map((o) => /* @__PURE__ */ jsxs("label", { className: "ckw-opt", children: [
60
+ return /* @__PURE__ */ jsx("div", { className: "ckw-opts", role: multi ? "group" : "radiogroup", "aria-label": q.title, children: (q.options ?? []).map((o, i) => /* @__PURE__ */ jsxs("label", { className: "ckw-opt", children: [
60
61
  /* @__PURE__ */ jsx(
61
62
  "input",
62
63
  {
@@ -66,7 +67,7 @@ var Question = ({ q, value, onChange, onEnter }) => {
66
67
  onChange: () => onChange(multi ? picked.includes(o) ? picked.filter((x) => x !== o) : [...picked, o] : o)
67
68
  }
68
69
  ),
69
- /* @__PURE__ */ jsx("span", { children: o })
70
+ /* @__PURE__ */ jsx("span", { children: q.labels?.[i] || o })
70
71
  ] }, o)) });
71
72
  }
72
73
  return /* @__PURE__ */ jsx(
@@ -74,7 +75,7 @@ var Question = ({ q, value, onChange, onEnter }) => {
74
75
  {
75
76
  className: "ckw-textarea",
76
77
  "aria-label": q.title,
77
- placeholder: q.placeholder ?? "Type your answer",
78
+ placeholder: q.placeholder ?? t("Type your answer"),
78
79
  value: value ?? "",
79
80
  maxLength: 2e3,
80
81
  onChange: (e) => onChange(e.target.value),
@@ -114,8 +115,8 @@ var Card = ({ survey, onClose }) => {
114
115
  );
115
116
  useEffect(() => {
116
117
  if (!done) return;
117
- const t = window.setTimeout(onClose, 2500);
118
- return () => window.clearTimeout(t);
118
+ const t2 = window.setTimeout(onClose, 2500);
119
+ return () => window.clearTimeout(t2);
119
120
  }, [done, onClose]);
120
121
  const dismiss = useCallback(() => {
121
122
  if (Object.values(live.current).some(isAnswered)) void finish(false);
@@ -129,7 +130,7 @@ var Card = ({ survey, onClose }) => {
129
130
  }, [dismiss, done]);
130
131
  const next = async () => {
131
132
  if (q.required && !has) {
132
- setError("Please answer this question.");
133
+ setError(t("Please answer this question."));
133
134
  return;
134
135
  }
135
136
  setError("");
@@ -140,7 +141,7 @@ var Card = ({ survey, onClose }) => {
140
141
  if (done)
141
142
  return /* @__PURE__ */ jsxs("div", { className: "ckw-thanks", role: "status", children: [
142
143
  /* @__PURE__ */ jsx("span", { className: "ckw-tick", children: /* @__PURE__ */ jsx(Check, {}) }),
143
- /* @__PURE__ */ jsx("b", { children: survey.thanks || "Thanks for your feedback." })
144
+ /* @__PURE__ */ jsx("b", { children: survey.thanks || t("Thanks for your feedback.") })
144
145
  ] });
145
146
  return /* @__PURE__ */ jsxs(
146
147
  "form",
@@ -151,19 +152,22 @@ var Card = ({ survey, onClose }) => {
151
152
  },
152
153
  children: [
153
154
  /* @__PURE__ */ jsxs("div", { className: "ckw-sv-top", children: [
154
- /* @__PURE__ */ jsx("div", { className: "ckw-dots", role: "img", "aria-label": `Question ${step + 1} of ${survey.questions.length}`, children: survey.questions.map((x, i) => /* @__PURE__ */ jsx("span", { className: "ckw-dot", "data-on": i <= step }, x.key)) }),
155
- /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: dismiss, "aria-label": "Close survey", style: { height: 24, padding: "0 4px" }, children: /* @__PURE__ */ jsx(Cross, {}) })
155
+ /* @__PURE__ */ jsx("div", { className: "ckw-dots", role: "img", "aria-label": tf("Question {n} of {total}", { n: step + 1, total: survey.questions.length }), children: survey.questions.map((x, i) => /* @__PURE__ */ jsx("span", { className: "ckw-dot", "data-on": i <= step }, x.key)) }),
156
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: dismiss, "aria-label": t("Close survey"), style: { height: 24, padding: "0 4px" }, children: /* @__PURE__ */ jsx(Cross, {}) })
156
157
  ] }),
157
158
  /* @__PURE__ */ jsxs("h3", { className: "ckw-q", tabIndex: -1, ref: heading, children: [
158
159
  q.title,
159
- !q.required && /* @__PURE__ */ jsx("span", { className: "ckw-time", children: " optional" })
160
+ !q.required && /* @__PURE__ */ jsxs("span", { className: "ckw-time", children: [
161
+ " ",
162
+ t("optional")
163
+ ] })
160
164
  ] }),
161
165
  q.description && /* @__PURE__ */ jsx("p", { className: "ckw-qd", children: q.description }),
162
166
  /* @__PURE__ */ jsx(Question, { q, value: answers[q.key], onChange: (v) => (setAnswers((a) => ({ ...a, [q.key]: v })), setError("")), onEnter: () => void next() }),
163
167
  /* @__PURE__ */ jsx("div", { "aria-live": "polite", children: error && /* @__PURE__ */ jsx("p", { className: "ckw-qd", style: { color: "var(--ckw-danger)", margin: "8px 0 0" }, children: error }) }),
164
168
  /* @__PURE__ */ jsxs("div", { className: "ckw-sv-foot", children: [
165
169
  /* @__PURE__ */ jsx("span", {}),
166
- /* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", children: last ? "Send" : "Next" })
170
+ /* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", children: last ? t("Send") : t("Next") })
167
171
  ] })
168
172
  ]
169
173
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/survey.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { type SurveyAnswer, type SurveyDefinition, type SurveyQuestion, useApi } from \"./api\";\nimport { useCtx } from \"./context\";\nimport { Check, Cross, Root, Star } from \"./ui\";\n\nconst DISMISS_PREFIX = \"ck_survey_\";\n/** Surveys dismissed or answered during this page load. Only \"cookies\" mode also keeps them in localStorage. */\nconst dismissed = new Set<string>();\n\nconst remember = (id: string, persist: boolean) => {\n dismissed.add(id);\n if (!persist) return;\n try {\n localStorage.setItem(`${DISMISS_PREFIX}${id}`, \"1\");\n } catch {\n // Private mode: the card just may show again next visit.\n }\n};\n\nconst wasDismissed = (id: string, persist: boolean) => {\n if (dismissed.has(id)) return true;\n if (!persist) return false;\n try {\n return !!localStorage.getItem(`${DISMISS_PREFIX}${id}`);\n } catch {\n return false;\n }\n};\n\n/** Consent for storage was withdrawn: move the stored dismissals into memory for this page load and delete them. */\nexport const forgetStoredDismissals = () => {\n try {\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const key = localStorage.key(i);\n if (!key?.startsWith(DISMISS_PREFIX)) continue;\n dismissed.add(key.slice(DISMISS_PREFIX.length));\n localStorage.removeItem(key);\n }\n } catch {\n // No storage: nothing to delete.\n }\n};\n\nconst isAnswered = (a: SurveyAnswer | undefined) => (Array.isArray(a) ? a.length > 0 : typeof a === \"number\" ? true : !!a?.trim());\n\nconst Question = ({ q, value, onChange, onEnter }: { q: SurveyQuestion; value: SurveyAnswer | undefined; onChange: (v: SurveyAnswer) => void; onEnter: () => void }) => {\n if (q.kind === \"nps\" || q.kind === \"rating\") {\n const scale = q.kind === \"nps\" ? 11 : Math.min(Math.max(q.scale ?? 5, 2), 10);\n const start = q.kind === \"nps\" ? 0 : 1;\n const items = Array.from({ length: scale }, (_, i) => i + start);\n const stars = q.kind === \"rating\" && scale <= 5;\n return (\n <div>\n <div className=\"ckw-scale\" role=\"group\" aria-label={q.title}>\n {items.map((n) =>\n stars ? (\n <button key={n} type=\"button\" className=\"ckw-star\" data-on={typeof value === \"number\" && n <= value} aria-pressed={value === n} aria-label={`${n} of ${scale}`} onClick={() => onChange(n)}>\n <Star />\n </button>\n ) : (\n <button key={n} type=\"button\" className=\"ckw-num\" aria-pressed={value === n} onClick={() => onChange(n)}>\n {n}\n </button>\n ),\n )}\n </div>\n {(q.low || q.high || q.kind === \"nps\") && (\n <div className=\"ckw-lh\">\n <span>{q.low ?? (q.kind === \"nps\" ? \"Not likely\" : \"\")}</span>\n <span>{q.high ?? (q.kind === \"nps\" ? \"Very likely\" : \"\")}</span>\n </div>\n )}\n </div>\n );\n }\n if (q.kind === \"single\" || q.kind === \"multi\") {\n const multi = q.kind === \"multi\";\n const picked = multi ? ((value as string[] | undefined) ?? []) : [];\n return (\n <div className=\"ckw-opts\" role={multi ? \"group\" : \"radiogroup\"} aria-label={q.title}>\n {(q.options ?? []).map((o) => (\n <label className=\"ckw-opt\" key={o}>\n <input\n type={multi ? \"checkbox\" : \"radio\"}\n name={q.key}\n checked={multi ? picked.includes(o) : value === o}\n onChange={() => onChange(multi ? (picked.includes(o) ? picked.filter((x) => x !== o) : [...picked, o]) : o)}\n />\n <span>{o}</span>\n </label>\n ))}\n </div>\n );\n }\n return (\n <textarea\n className=\"ckw-textarea\"\n aria-label={q.title}\n placeholder={q.placeholder ?? \"Type your answer\"}\n value={(value as string | undefined) ?? \"\"}\n maxLength={2000}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={(e) => (e.metaKey || e.ctrlKey) && e.key === \"Enter\" && onEnter()}\n />\n );\n};\n\nconst Card = ({ survey, onClose }: { survey: SurveyDefinition; onClose: () => void }) => {\n const api = useApi();\n const persist = useCtx().effectiveConsent === \"cookies\";\n const [step, setStep] = useState(0);\n const [answers, setAnswers] = useState<Record<string, SurveyAnswer>>({});\n const [done, setDone] = useState(false);\n const [error, setError] = useState(\"\");\n const started = useRef(Date.now());\n const finished = useRef(false);\n const live = useRef(answers);\n live.current = answers;\n const heading = useRef<HTMLHeadingElement>(null);\n const q = survey.questions[step];\n const last = step === survey.questions.length - 1;\n const has = isAnswered(answers[q?.key]);\n\n useEffect(() => {\n api.seen(survey.id).catch(() => undefined);\n }, [api, survey.id]);\n useEffect(() => {\n heading.current?.focus();\n }, [step]);\n\n const finish = useCallback(\n async (completed: boolean) => {\n if (finished.current) return;\n finished.current = true;\n remember(survey.id, persist);\n api.respond(survey.id, { answers: live.current, completed, seconds: Math.round((Date.now() - started.current) / 1000) }).catch(() => undefined);\n },\n [api, survey.id, persist],\n );\n\n // After the thank-you screen the card closes by itself.\n useEffect(() => {\n if (!done) return;\n const t = window.setTimeout(onClose, 2500);\n return () => window.clearTimeout(t);\n }, [done, onClose]);\n\n const dismiss = useCallback(() => {\n // Partial answers still count, so nothing the visitor typed is lost.\n if (Object.values(live.current).some(isAnswered)) void finish(false);\n else remember(survey.id, persist);\n onClose();\n }, [finish, onClose, survey.id, persist]);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => e.key === \"Escape\" && !done && dismiss();\n document.addEventListener(\"keydown\", h);\n return () => document.removeEventListener(\"keydown\", h);\n }, [dismiss, done]);\n\n const next = async () => {\n if (q.required && !has) {\n setError(\"Please answer this question.\");\n return;\n }\n setError(\"\");\n if (!last) return setStep(step + 1);\n await finish(true);\n setDone(true);\n };\n\n if (done)\n return (\n <div className=\"ckw-thanks\" role=\"status\">\n <span className=\"ckw-tick\">\n <Check />\n </span>\n <b>{survey.thanks || \"Thanks for your feedback.\"}</b>\n </div>\n );\n\n return (\n <form\n onSubmit={(e) => {\n e.preventDefault();\n void next();\n }}\n >\n <div className=\"ckw-sv-top\">\n <div className=\"ckw-dots\" role=\"img\" aria-label={`Question ${step + 1} of ${survey.questions.length}`}>\n {survey.questions.map((x, i) => (\n <span className=\"ckw-dot\" key={x.key} data-on={i <= step} />\n ))}\n </div>\n <button type=\"button\" className=\"ckw-btn ckw-btn-ghost\" onClick={dismiss} aria-label=\"Close survey\" style={{ height: 24, padding: \"0 4px\" }}>\n <Cross />\n </button>\n </div>\n <h3 className=\"ckw-q\" tabIndex={-1} ref={heading}>\n {q.title}\n {!q.required && <span className=\"ckw-time\"> optional</span>}\n </h3>\n {q.description && <p className=\"ckw-qd\">{q.description}</p>}\n <Question q={q} value={answers[q.key]} onChange={(v) => (setAnswers((a) => ({ ...a, [q.key]: v })), setError(\"\"))} onEnter={() => void next()} />\n <div aria-live=\"polite\">\n {error && (\n <p className=\"ckw-qd\" style={{ color: \"var(--ckw-danger)\", margin: \"8px 0 0\" }}>\n {error}\n </p>\n )}\n </div>\n <div className=\"ckw-sv-foot\">\n <span />\n <button type=\"submit\" className=\"ckw-btn ckw-btn-primary\">\n {last ? \"Send\" : \"Next\"}\n </button>\n </div>\n </form>\n );\n};\n\n/** Asks the visitor the survey Cockpit picked for this page. Mounted by CockpitProvider unless `surveys={false}`. */\nexport const Survey = () => {\n const { embedded, distinctId, effectiveConsent } = useCtx();\n const api = useApi();\n const [survey, setSurvey] = useState<SurveyDefinition | null>(null);\n // Never inside Cockpit previews, never without consent, and not before the visitor id is known.\n const off = embedded || effectiveConsent === \"off\" || distinctId === \"anonymous\";\n const persist = effectiveConsent === \"cookies\";\n\n useEffect(() => {\n if (off) return;\n const ctl = new AbortController();\n const timer = window.setTimeout(() => {\n api.survey(window.location.href, ctl.signal)\n .then((r) => {\n const s = r.survey;\n if (!s || s.questions.length === 0 || wasDismissed(s.id, persist)) return;\n setSurvey(s);\n })\n .catch(() => undefined);\n }, 3000);\n return () => {\n window.clearTimeout(timer);\n ctl.abort();\n };\n }, [api, off, persist]);\n\n const close = useCallback(() => setSurvey(null), []);\n if (!survey || off) return null;\n return (\n <Root>\n <div className=\"ckw-survey\" role=\"dialog\" aria-label={survey.name}>\n <Card key={survey.id} survey={survey} onClose={close} />\n </div>\n </Root>\n );\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/survey.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { type SurveyAnswer, type SurveyDefinition, type SurveyQuestion, useApi } from \"./api\";\nimport { useCtx } from \"./context\";\nimport { t, tf } from \"./i18n\";\nimport { Check, Cross, Root, Star } from \"./ui\";\n\nconst DISMISS_PREFIX = \"ck_survey_\";\n/** Surveys dismissed or answered during this page load. Only \"cookies\" mode also keeps them in localStorage. */\nconst dismissed = new Set<string>();\n\nconst remember = (id: string, persist: boolean) => {\n dismissed.add(id);\n if (!persist) return;\n try {\n localStorage.setItem(`${DISMISS_PREFIX}${id}`, \"1\");\n } catch {\n // Private mode: the card just may show again next visit.\n }\n};\n\nconst wasDismissed = (id: string, persist: boolean) => {\n if (dismissed.has(id)) return true;\n if (!persist) return false;\n try {\n return !!localStorage.getItem(`${DISMISS_PREFIX}${id}`);\n } catch {\n return false;\n }\n};\n\n/** Consent for storage was withdrawn: move the stored dismissals into memory for this page load and delete them. */\nexport const forgetStoredDismissals = () => {\n try {\n for (let i = localStorage.length - 1; i >= 0; i--) {\n const key = localStorage.key(i);\n if (!key?.startsWith(DISMISS_PREFIX)) continue;\n dismissed.add(key.slice(DISMISS_PREFIX.length));\n localStorage.removeItem(key);\n }\n } catch {\n // No storage: nothing to delete.\n }\n};\n\nconst isAnswered = (a: SurveyAnswer | undefined) => (Array.isArray(a) ? a.length > 0 : typeof a === \"number\" ? true : !!a?.trim());\n\nconst Question = ({ q, value, onChange, onEnter }: { q: SurveyQuestion; value: SurveyAnswer | undefined; onChange: (v: SurveyAnswer) => void; onEnter: () => void }) => {\n if (q.kind === \"nps\" || q.kind === \"rating\") {\n const scale = q.kind === \"nps\" ? 11 : Math.min(Math.max(q.scale ?? 5, 2), 10);\n const start = q.kind === \"nps\" ? 0 : 1;\n const items = Array.from({ length: scale }, (_, i) => i + start);\n const stars = q.kind === \"rating\" && scale <= 5;\n return (\n <div>\n <div className=\"ckw-scale\" role=\"group\" aria-label={q.title}>\n {items.map((n) =>\n stars ? (\n <button key={n} type=\"button\" className=\"ckw-star\" data-on={typeof value === \"number\" && n <= value} aria-pressed={value === n} aria-label={tf(\"{n} of {total}\", { n, total: scale })} onClick={() => onChange(n)}>\n <Star />\n </button>\n ) : (\n <button key={n} type=\"button\" className=\"ckw-num\" aria-pressed={value === n} onClick={() => onChange(n)}>\n {n}\n </button>\n ),\n )}\n </div>\n {(q.low || q.high || q.kind === \"nps\") && (\n <div className=\"ckw-lh\">\n <span>{q.low ?? (q.kind === \"nps\" ? t(\"Not likely\") : \"\")}</span>\n <span>{q.high ?? (q.kind === \"nps\" ? t(\"Very likely\") : \"\")}</span>\n </div>\n )}\n </div>\n );\n }\n if (q.kind === \"single\" || q.kind === \"multi\") {\n const multi = q.kind === \"multi\";\n const picked = multi ? ((value as string[] | undefined) ?? []) : [];\n return (\n <div className=\"ckw-opts\" role={multi ? \"group\" : \"radiogroup\"} aria-label={q.title}>\n {(q.options ?? []).map((o, i) => (\n <label className=\"ckw-opt\" key={o}>\n <input\n type={multi ? \"checkbox\" : \"radio\"}\n name={q.key}\n checked={multi ? picked.includes(o) : value === o}\n onChange={() => onChange(multi ? (picked.includes(o) ? picked.filter((x) => x !== o) : [...picked, o]) : o)}\n />\n {/* The label in the visitor's language; what is recorded stays the option itself. */}\n <span>{q.labels?.[i] || o}</span>\n </label>\n ))}\n </div>\n );\n }\n return (\n <textarea\n className=\"ckw-textarea\"\n aria-label={q.title}\n placeholder={q.placeholder ?? t(\"Type your answer\")}\n value={(value as string | undefined) ?? \"\"}\n maxLength={2000}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={(e) => (e.metaKey || e.ctrlKey) && e.key === \"Enter\" && onEnter()}\n />\n );\n};\n\nconst Card = ({ survey, onClose }: { survey: SurveyDefinition; onClose: () => void }) => {\n const api = useApi();\n const persist = useCtx().effectiveConsent === \"cookies\";\n const [step, setStep] = useState(0);\n const [answers, setAnswers] = useState<Record<string, SurveyAnswer>>({});\n const [done, setDone] = useState(false);\n const [error, setError] = useState(\"\");\n const started = useRef(Date.now());\n const finished = useRef(false);\n const live = useRef(answers);\n live.current = answers;\n const heading = useRef<HTMLHeadingElement>(null);\n const q = survey.questions[step];\n const last = step === survey.questions.length - 1;\n const has = isAnswered(answers[q?.key]);\n\n useEffect(() => {\n api.seen(survey.id).catch(() => undefined);\n }, [api, survey.id]);\n useEffect(() => {\n heading.current?.focus();\n }, [step]);\n\n const finish = useCallback(\n async (completed: boolean) => {\n if (finished.current) return;\n finished.current = true;\n remember(survey.id, persist);\n api.respond(survey.id, { answers: live.current, completed, seconds: Math.round((Date.now() - started.current) / 1000) }).catch(() => undefined);\n },\n [api, survey.id, persist],\n );\n\n // After the thank-you screen the card closes by itself.\n useEffect(() => {\n if (!done) return;\n const t = window.setTimeout(onClose, 2500);\n return () => window.clearTimeout(t);\n }, [done, onClose]);\n\n const dismiss = useCallback(() => {\n // Partial answers still count, so nothing the visitor typed is lost.\n if (Object.values(live.current).some(isAnswered)) void finish(false);\n else remember(survey.id, persist);\n onClose();\n }, [finish, onClose, survey.id, persist]);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => e.key === \"Escape\" && !done && dismiss();\n document.addEventListener(\"keydown\", h);\n return () => document.removeEventListener(\"keydown\", h);\n }, [dismiss, done]);\n\n const next = async () => {\n if (q.required && !has) {\n setError(t(\"Please answer this question.\"));\n return;\n }\n setError(\"\");\n if (!last) return setStep(step + 1);\n await finish(true);\n setDone(true);\n };\n\n if (done)\n return (\n <div className=\"ckw-thanks\" role=\"status\">\n <span className=\"ckw-tick\">\n <Check />\n </span>\n <b>{survey.thanks || t(\"Thanks for your feedback.\")}</b>\n </div>\n );\n\n return (\n <form\n onSubmit={(e) => {\n e.preventDefault();\n void next();\n }}\n >\n <div className=\"ckw-sv-top\">\n <div className=\"ckw-dots\" role=\"img\" aria-label={tf(\"Question {n} of {total}\", { n: step + 1, total: survey.questions.length })}>\n {survey.questions.map((x, i) => (\n <span className=\"ckw-dot\" key={x.key} data-on={i <= step} />\n ))}\n </div>\n <button type=\"button\" className=\"ckw-btn ckw-btn-ghost\" onClick={dismiss} aria-label={t(\"Close survey\")} style={{ height: 24, padding: \"0 4px\" }}>\n <Cross />\n </button>\n </div>\n <h3 className=\"ckw-q\" tabIndex={-1} ref={heading}>\n {q.title}\n {!q.required && <span className=\"ckw-time\"> {t(\"optional\")}</span>}\n </h3>\n {q.description && <p className=\"ckw-qd\">{q.description}</p>}\n <Question q={q} value={answers[q.key]} onChange={(v) => (setAnswers((a) => ({ ...a, [q.key]: v })), setError(\"\"))} onEnter={() => void next()} />\n <div aria-live=\"polite\">\n {error && (\n <p className=\"ckw-qd\" style={{ color: \"var(--ckw-danger)\", margin: \"8px 0 0\" }}>\n {error}\n </p>\n )}\n </div>\n <div className=\"ckw-sv-foot\">\n <span />\n <button type=\"submit\" className=\"ckw-btn ckw-btn-primary\">\n {last ? t(\"Send\") : t(\"Next\")}\n </button>\n </div>\n </form>\n );\n};\n\n/** Asks the visitor the survey Cockpit picked for this page. Mounted by CockpitProvider unless `surveys={false}`. */\nexport const Survey = () => {\n const { embedded, distinctId, effectiveConsent } = useCtx();\n const api = useApi();\n const [survey, setSurvey] = useState<SurveyDefinition | null>(null);\n // Never inside Cockpit previews, never without consent, and not before the visitor id is known.\n const off = embedded || effectiveConsent === \"off\" || distinctId === \"anonymous\";\n const persist = effectiveConsent === \"cookies\";\n\n useEffect(() => {\n if (off) return;\n const ctl = new AbortController();\n const timer = window.setTimeout(() => {\n api.survey(window.location.href, ctl.signal)\n .then((r) => {\n const s = r.survey;\n if (!s || s.questions.length === 0 || wasDismissed(s.id, persist)) return;\n setSurvey(s);\n })\n .catch(() => undefined);\n }, 3000);\n return () => {\n window.clearTimeout(timer);\n ctl.abort();\n };\n }, [api, off, persist]);\n\n const close = useCallback(() => setSurvey(null), []);\n if (!survey || off) return null;\n return (\n <Root>\n <div className=\"ckw-survey\" role=\"dialog\" aria-label={survey.name}>\n <Card key={survey.id} survey={survey} onClose={close} />\n </div>\n </Root>\n );\n};\n"],"mappings":"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","names":["t"]}
package/dist/ui.d.ts CHANGED
@@ -20,6 +20,8 @@ export declare const Star: () => import("react").JSX.Element;
20
20
  export declare const StatusPill: ({ status }: {
21
21
  status: PostStatus;
22
22
  }) => import("react").JSX.Element;
23
+ /** "1 vote", "3 votes". */
24
+ export declare const votesWord: (n: number) => string;
23
25
  export declare const VoteButton: ({ post, onVote, small }: {
24
26
  post: FeedbackPost;
25
27
  onVote: (p: FeedbackPost) => void;
package/dist/ui.js CHANGED
@@ -3,11 +3,12 @@
3
3
  // src/ui.tsx
4
4
  import { useEffect, useRef } from "react";
5
5
  import { STATUS_LABEL } from "./api.js";
6
+ import { currentLocale, t, tf, wordsLang } from "./i18n.js";
6
7
  import { useStyles } from "./styles.js";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
9
  var Root = ({ theme = "auto", accent = "#3f76ff", className, children }) => {
9
10
  useStyles();
10
- return /* @__PURE__ */ jsx("div", { className: `ckw-root${className ? ` ${className}` : ""}`, "data-theme": theme, style: { ["--ckw-accent"]: accent }, children });
11
+ return /* @__PURE__ */ jsx("div", { className: `ckw-root${className ? ` ${className}` : ""}`, "data-theme": theme, lang: wordsLang(), style: { ["--ckw-accent"]: accent }, children });
11
12
  };
12
13
  var Svg = ({ children, size = 16 }) => /* @__PURE__ */ jsx("svg", { className: "ckw-icon", width: size, height: size, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children });
13
14
  var ChevronUp = () => /* @__PURE__ */ jsx(Svg, { children: /* @__PURE__ */ jsx("path", { d: "M3.5 10 8 5.5 12.5 10" }) });
@@ -26,13 +27,14 @@ var Sun = () => /* @__PURE__ */ jsxs(Svg, { children: [
26
27
  var Moon = () => /* @__PURE__ */ jsx(Svg, { children: /* @__PURE__ */ jsx("path", { d: "M13.5 9.5A5.5 5.5 0 0 1 6.5 2.5a5.5 5.5 0 1 0 7 7z" }) });
27
28
  var Star = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "m12 2.8 2.8 5.8 6.4.9-4.6 4.5 1.1 6.3L12 17.2l-5.7 3.1 1.1-6.3L2.8 9.5l6.4-.9z" }) });
28
29
  var StatusPill = ({ status }) => /* @__PURE__ */ jsx("span", { className: "ckw-pill", "data-s": status, children: STATUS_LABEL[status] ?? status });
30
+ var votesWord = (n) => n === 1 ? t("1 vote") : tf("{n} votes", { n });
29
31
  var VoteButton = ({ post, onVote, small }) => /* @__PURE__ */ jsxs(
30
32
  "button",
31
33
  {
32
34
  type: "button",
33
35
  className: `ckw-vote${small ? " ckw-vote-sm" : ""}`,
34
36
  "aria-pressed": post.voted,
35
- "aria-label": `${post.voted ? "Remove your vote from" : "Upvote"} ${post.title}. ${post.votes} votes`,
37
+ "aria-label": post.voted ? tf("Remove your vote from {title}. {votes}", { title: post.title, votes: votesWord(post.votes) }) : tf("Upvote {title}. {votes}", { title: post.title, votes: votesWord(post.votes) }),
36
38
  onClick: () => onVote(post),
37
39
  children: [
38
40
  /* @__PURE__ */ jsx(ChevronUp, {}),
@@ -41,14 +43,14 @@ var VoteButton = ({ post, onVote, small }) => /* @__PURE__ */ jsxs(
41
43
  }
42
44
  );
43
45
  var timeAgo = (iso) => {
44
- const t = new Date(iso).getTime();
45
- if (Number.isNaN(t)) return "";
46
- const d = Math.max(0, Date.now() - t) / 1e3;
47
- if (d < 60) return "just now";
48
- if (d < 3600) return `${Math.floor(d / 60)}m ago`;
49
- if (d < 86400) return `${Math.floor(d / 3600)}h ago`;
50
- if (d < 86400 * 30) return `${Math.floor(d / 86400)}d ago`;
51
- return new Date(iso).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
46
+ const at = new Date(iso).getTime();
47
+ if (Number.isNaN(at)) return "";
48
+ const d = Math.max(0, Date.now() - at) / 1e3;
49
+ if (d < 60) return t("just now");
50
+ if (d < 3600) return tf("{n}m ago", { n: Math.floor(d / 60) });
51
+ if (d < 86400) return tf("{n}h ago", { n: Math.floor(d / 3600) });
52
+ if (d < 86400 * 30) return tf("{n}d ago", { n: Math.floor(d / 86400) });
53
+ return new Date(iso).toLocaleDateString(currentLocale(), { month: "short", day: "numeric", year: "numeric" });
52
54
  };
53
55
  var useEscape = (onClose) => {
54
56
  const ref = useRef(onClose);
@@ -65,7 +67,7 @@ var similarPosts = (title, posts) => {
65
67
  if (mine.length === 0 || title.trim().length < 4) return [];
66
68
  return posts.map((p) => {
67
69
  const theirs = new Set(words(`${p.title} ${p.body}`.slice(0, 300)));
68
- const hit = mine.filter((w) => theirs.has(w) || [...theirs].some((t) => t.startsWith(w) || w.startsWith(t))).length;
70
+ const hit = mine.filter((w) => theirs.has(w) || [...theirs].some((t2) => t2.startsWith(w) || w.startsWith(t2))).length;
69
71
  return { p, score: hit / mine.length };
70
72
  }).filter((x) => x.score >= 0.5).sort((a, b) => b.score - a.score || b.p.votes - a.p.votes).slice(0, 3).map((x) => x.p);
71
73
  };
@@ -84,6 +86,7 @@ export {
84
86
  VoteButton,
85
87
  similarPosts,
86
88
  timeAgo,
87
- useEscape
89
+ useEscape,
90
+ votesWord
88
91
  };
89
92
  //# sourceMappingURL=ui.js.map