@siteping/widget 0.9.7 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/chunk-OTJZRTBK.js +1751 -0
- package/dist/chunk-OTJZRTBK.js.map +1 -0
- package/dist/de-32TXJQIE.js +2 -0
- package/dist/de-32TXJQIE.js.map +1 -0
- package/dist/es-GFAPKPTK.js +2 -0
- package/dist/es-GFAPKPTK.js.map +1 -0
- package/dist/fr-W2JZ3EUC.js +2 -0
- package/dist/fr-W2JZ3EUC.js.map +1 -0
- package/dist/index.global.js +377 -200
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +59 -1630
- package/dist/index.js.map +1 -1
- package/dist/it-GASU527B.js +2 -0
- package/dist/it-GASU527B.js.map +1 -0
- package/dist/panel-HDPPIATU.js +2 -0
- package/dist/panel-HDPPIATU.js.map +1 -0
- package/dist/pt-AYXM6FG4.js +2 -0
- package/dist/pt-AYXM6FG4.js.map +1 -0
- package/dist/react.d.ts +59 -0
- package/dist/react.js +1568 -0
- package/dist/react.js.map +1 -0
- package/dist/ru-5DW2JCKR.js +2 -0
- package/dist/ru-5DW2JCKR.js.map +1 -0
- package/dist/schema.d.ts +4 -0
- package/dist/siteping-core.d.ts +4 -1
- package/dist/types.d.ts +105 -0
- package/package.json +25 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dom-utils.ts","../src/icons.ts","../src/styles/theme.ts","../src/i18n/en.ts","../src/i18n/index.ts","../src/export-utils.ts","../src/panel-bulk.ts","../src/panel-detail.ts","../src/panel-sort.ts","../src/panel-stats.ts","../src/shortcuts.ts"],"names":["parseSvg","svgString","svg","attr","el","tag","attrs","element","key","value","setText","text","setButtonLoading","btn","snapshot","n","formatRelativeDate","isoString","locale","diff","seconds","rtf","minutes","hours","days","ICON_SITEPING","ICON_CHAT","ICON_ANNOTATE","ICON_EYE","ICON_EYE_OFF","ICON_CLOSE","ICON_SEARCH","ICON_CHECK","ICON_QUESTION","ICON_CHANGE","ICON_BUG","ICON_OTHER","ICON_LAYERS","ICON_DOT_OPEN","ICON_CHEVRON_DOWN","ICON_UNDO","ICON_TRASH","DEFAULT_ACCENT","HEX6_RE","HEX3_RE","HEX8_RE","normalizeHex","raw","short","darkenHex","hex","amount","r","g","b","prefersDark","resolveTheme","theme","buildThemeColors","accent","dark","getTypeColor","type","colors","getTypeBgColor","cssVariables","en","LOCALES","BUILTIN_LOCALES","loadLocale","lang","mod","dict","createT","getTypeLabel","t","ICON_EXPORT","ICON_CSV","ICON_JSON","EXPORT_CSS","CSV_COLUMNS","escapeCsvField","feedbacksToCsv","feedbacks","header","rows","fb","col","feedbacksToJson","downloadFile","content","filename","mimeType","blob","url","anchor","ExportButton","_colors","getFeedbacks","label","e","csvOption","jsonOption","iconSvg","labelText","onClick","option","iconWrap","labelEl","format","projectName","date","safeName","ICON_CHECKBOX","ICON_CHECKBOX_CHECKED","BULK_CSS","BulkActions","callbacks","actions","deselectBtn","feedbackId","wrapper","feedbackIds","checkbox","container","id","prevSelected","count","visible","resolve","del","resolveLabel","deleteLabel","isChecked","allSelected","escapedId","card","ids","restoreResolve","restoreDelete","ICON_ARROW_LEFT","ICON_MAP_PIN","ICON_LINK","ICON_USER","ICON_CALENDAR","ICON_MONITOR","ICON_CODE","ICON_CROSSHAIR","ICON_CHEVRON","ICON_TERMINAL","DETAIL_CSS","parseBrowser","ua","m","formatFullDate","extractPathname","isSafeImageUrl","truncate","str","max","hasDiagnostics","diagnostics","consoleLen","networkLen","formatDuration","ms","DetailView","backBtn","feedback","number","title","badge","sectionIndex","statusSection","messageSection","messageSectionTitle","messageBlock","screenshotSection","screenshotSectionTitle","img","metaSection","metaSectionTitle","annSection","annSectionTitle","annTitleText","diagSection","diagSectionTitle","diagTitleText","index","section","isResolved","sectionTitle","statusRow","pill","dot","pillLabel","span","deleteSpan","meta","pathname","name","email","resolvedDate","buildValue","row","ann","info","tagDisplay","gotoBtn","gotoLabel","diag","consoleEntries","networkEntries","errorCount","toggle","toggleLabel","leftRow","counts","consoleCount","networkCount","body","group","list","entry","item","level","msg","status","method","next","ICON_SORT","ICON_PAGE","TYPE_ORDER","sortFeedbacks","mode","sorted","a","typeA","typeB","statusA","statusB","truncatePath","path","maxLength","ellipsis","keep","groupFeedbacksByPage","groups","existing","createPageGroupHeader","pagePath","chevronWrap","pageIcon","pathEl","displayPath","countEl","isExpanded","PanelSortControls","onChange","sortIcon","sortLabel","groupIcon","groupLabel","options","opt","labelMap","SORT_CSS","STATS_CSS","PanelStats","itemOpen","dotOpen","labelOpen","itemResolved","dotResolved","labelResolved","itemBugs","dotBugs","labelBugs","progress","track","total","openCount","resolvedCount","bugCount","pct","progressText","ICON_KEYBOARD","getFocusedCardIndex","listContainer","cards","i","focusCardByIndex","clamped","target","SHORTCUT_DEFS","SHORTCUTS_CSS","ICON_CLOSE_SM","KeyboardShortcuts","root","active","handler","overlay","titleText","closeBtn","grid","def","keysWrap","sep","kbd","desc"],"mappings":"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AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;A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","file":"chunk-OTJZRTBK.js","sourcesContent":["/**\n * Safe DOM creation utilities.\n * All user content is set via textContent (never innerHTML).\n * SVG icons use a DOMParser for trusted static strings.\n */\n\n/**\n * Parse a trusted SVG string into an SVGElement.\n * Only use with hardcoded icon constants — never with user input.\n * Uses createContextualFragment for native document-context parsing\n * (DOMParser creates nodes in a foreign document that don't render in Shadow DOM).\n */\nexport function parseSvg(svgString: string): SVGSVGElement {\n const range = document.createRange();\n const fragment = range.createContextualFragment(svgString);\n const svg = fragment.firstElementChild;\n if (!svg || svg.nodeName.toLowerCase() !== \"svg\") {\n throw new Error(\"[siteping] Invalid SVG string\");\n }\n // Safety: strip any event handlers in case of accidental misuse\n for (const attr of [...svg.attributes]) {\n if (attr.name.startsWith(\"on\")) svg.removeAttribute(attr.name);\n }\n // Also strip from all descendants\n for (const el of svg.querySelectorAll(\"*\")) {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith(\"on\")) el.removeAttribute(attr.name);\n }\n }\n return svg as SVGSVGElement;\n}\n\n/** Create an element with optional class and style */\nexport function el(tag: string, attrs?: Record<string, string>): HTMLElement {\n const element = document.createElement(tag);\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (key === \"class\") {\n element.className = value;\n } else if (key === \"style\") {\n element.style.cssText = value;\n } else {\n element.setAttribute(key, value);\n }\n }\n }\n return element;\n}\n\n/** Set text content safely (no HTML injection possible) */\nexport function setText(element: HTMLElement | SVGElement, text: string): void {\n element.textContent = text;\n}\n\n/**\n * Replace a button's children with a small spinner and disable it.\n * Returns a `restore` callback that swaps the original content back and\n * re-enables the button. Used by every async button (delete, resolve, …)\n * to surface in-flight state without owning per-button state itself.\n *\n * Lives in dom-utils rather than panel-internal because both Panel and\n * BulkActions need identical behaviour.\n */\nexport function setButtonLoading(btn: HTMLButtonElement): () => void {\n const snapshot = Array.from(btn.childNodes).map((n) => n.cloneNode(true));\n btn.disabled = true;\n btn.replaceChildren(el(\"div\", { class: \"sp-spinner sp-spinner--sm\" }));\n return () => {\n btn.replaceChildren(...snapshot);\n btn.disabled = false;\n };\n}\n\n/** Format a relative date string using Intl.RelativeTimeFormat for locale support */\nexport function formatRelativeDate(isoString: string, locale = \"en\"): string {\n const diff = Date.now() - new Date(isoString).getTime();\n const seconds = Math.floor(diff / 1000);\n\n if (seconds < 60) {\n return new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" }).format(0, \"second\");\n }\n\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: \"always\", style: \"narrow\" });\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return rtf.format(-minutes, \"minute\");\n\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return rtf.format(-hours, \"hour\");\n\n const days = Math.floor(hours / 24);\n if (days < 7) return rtf.format(-days, \"day\");\n\n return new Date(isoString).toLocaleDateString(locale);\n}\n","/** SVG icon strings for the widget UI. Kept as template strings to avoid DOM parsing overhead. */\n\nexport const ICON_SITEPING = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/><circle cx=\"12\" cy=\"10\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"8\" cy=\"10\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"16\" cy=\"10\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>`;\n\nexport const ICON_CHAT = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`;\n\nexport const ICON_ANNOTATE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M9 3v18\"/></svg>`;\n\nexport const ICON_EYE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></svg>`;\n\nexport const ICON_EYE_OFF = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"/><path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"/><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"/></svg>`;\n\nexport const ICON_CLOSE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\n\nexport const ICON_SEARCH = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/></svg>`;\n\nexport const ICON_CHECK = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\nexport const ICON_QUESTION = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></svg>`;\n\nexport const ICON_CHANGE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/></svg>`;\n\nexport const ICON_BUG = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"8\" y=\"6\" width=\"8\" height=\"14\" rx=\"4\"/><path d=\"M19 9h2\"/><path d=\"M3 9h2\"/><path d=\"M19 13h2\"/><path d=\"M3 13h2\"/><path d=\"M19 17h2\"/><path d=\"M3 17h2\"/><path d=\"M10 2h4\"/></svg>`;\n\nexport const ICON_OTHER = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"1\"/><circle cx=\"19\" cy=\"12\" r=\"1\"/><circle cx=\"5\" cy=\"12\" r=\"1\"/></svg>`;\n\nexport const ICON_LAYERS = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polygon points=\"12 2 2 7 12 12 22 7 12 2\"/><polyline points=\"2 17 12 22 22 17\"/><polyline points=\"2 12 12 17 22 12\"/></svg>`;\n\nexport const ICON_DOT_OPEN = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><circle cx=\"12\" cy=\"12\" r=\"3\" fill=\"currentColor\" stroke=\"none\"/></svg>`;\n\nexport const ICON_CHEVRON_DOWN = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"6 9 12 15 18 9\"/></svg>`;\n\nexport const ICON_UNDO = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>`;\n\nexport const ICON_TRASH = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/></svg>`;\n","/** Color palette and glassmorphism tokens derived from the accent color */\nexport interface ThemeColors {\n accent: string;\n accentLight: string;\n accentDark: string;\n accentGlow: string;\n accentGradient: string;\n bg: string;\n bgHover: string;\n text: string;\n textSecondary: string;\n textTertiary: string;\n border: string;\n shadow: string;\n // Glass tokens\n glassBg: string;\n glassBgHeavy: string;\n glassBorder: string;\n glassBorderSubtle: string;\n // Feedback type colors\n typeQuestion: string;\n typeChange: string;\n typeBug: string;\n typeOther: string;\n // Soft type backgrounds (pastel)\n typeQuestionBg: string;\n typeChangeBg: string;\n typeBugBg: string;\n typeOtherBg: string;\n // Status filter colors\n statusOpen: string;\n statusOpenBg: string;\n statusResolved: string;\n statusResolvedBg: string;\n}\n\nconst DEFAULT_ACCENT = \"#0066ff\";\nconst HEX6_RE = /^#[0-9a-fA-F]{6}$/;\nconst HEX3_RE = /^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/;\nconst HEX8_RE = /^#[0-9a-fA-F]{8}$/;\n\n/**\n * Normalize an accent color to a 6-digit hex string.\n *\n * **Only hex formats are accepted:**\n * - `#RGB` (3-digit shorthand, expanded to 6-digit)\n * - `#RRGGBB` (standard 6-digit)\n * - `#RRGGBBAA` (8-digit with alpha, alpha is stripped)\n *\n * Any other CSS color format (named colors like `\"red\"`, `hsl()`, `rgb()`,\n * `oklch()`, etc.) is **not** supported and will fall back to the default\n * accent color with a console warning.\n */\nfunction normalizeHex(raw: string): string {\n if (HEX6_RE.test(raw)) return raw;\n const short = HEX3_RE.test(raw) ? raw.match(HEX3_RE) : null;\n if (short) return `#${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`;\n if (HEX8_RE.test(raw)) return raw.slice(0, 7);\n\n console.warn(\n `[siteping] Invalid accentColor \"${raw}\" — only hex colors (#RGB, #RRGGBB, #RRGGBBAA) are supported. Using default.`,\n );\n return DEFAULT_ACCENT;\n}\n\n/** Darken a hex color by a percentage (0-1) */\nfunction darkenHex(hex: string, amount: number): string {\n const r = Math.max(0, Math.round(parseInt(hex.slice(1, 3), 16) * (1 - amount)));\n const g = Math.max(0, Math.round(parseInt(hex.slice(3, 5), 16) * (1 - amount)));\n const b = Math.max(0, Math.round(parseInt(hex.slice(5, 7), 16) * (1 - amount)));\n return `#${r.toString(16).padStart(2, \"0\")}${g.toString(16).padStart(2, \"0\")}${b.toString(16).padStart(2, \"0\")}`;\n}\n\n/** Detect if user prefers dark mode via media query */\nfunction prefersDark(): boolean {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n}\n\n/** Resolve 'auto' theme to 'light' or 'dark' based on system preference */\nexport function resolveTheme(theme?: \"light\" | \"dark\" | \"auto\"): \"light\" | \"dark\" {\n if (theme === \"dark\") return \"dark\";\n if (theme === \"auto\") return prefersDark() ? \"dark\" : \"light\";\n return \"light\";\n}\n\nexport function buildThemeColors(accent: string = DEFAULT_ACCENT, theme?: \"light\" | \"dark\" | \"auto\"): ThemeColors {\n const hex = normalizeHex(accent);\n const dark = darkenHex(hex, 0.15);\n const resolved = resolveTheme(theme);\n\n if (resolved === \"dark\") {\n return {\n accent: hex,\n accentLight: hex + \"22\", // slightly more visible on dark bg\n accentDark: dark,\n accentGlow: hex + \"44\",\n accentGradient: `linear-gradient(135deg, ${hex}, ${dark})`,\n bg: \"#0f172a\",\n bgHover: \"#1e293b\",\n text: \"#f1f5f9\",\n textSecondary: \"#94a3b8\",\n textTertiary: \"#64748b\",\n border: \"#334155\",\n shadow: \"rgba(0, 0, 0, 0.3)\",\n // Glass tokens — dark frosted glass\n glassBg: \"rgba(15, 23, 42, 0.78)\",\n glassBgHeavy: \"rgba(15, 23, 42, 0.88)\",\n glassBorder: \"rgba(51, 65, 85, 0.5)\",\n glassBorderSubtle: \"rgba(51, 65, 85, 0.3)\",\n // Type colors stay vibrant on dark\n typeQuestion: \"#60a5fa\",\n typeChange: \"#fbbf24\",\n typeBug: \"#f87171\",\n typeOther: \"#94a3b8\",\n // Dark pastel backgrounds\n typeQuestionBg: \"rgba(59, 130, 246, 0.15)\",\n typeChangeBg: \"rgba(245, 158, 11, 0.15)\",\n typeBugBg: \"rgba(239, 68, 68, 0.15)\",\n typeOtherBg: \"rgba(100, 116, 139, 0.15)\",\n // Status colors — vivid green / cool gray on dark\n statusOpen: \"#4ade80\",\n statusOpenBg: \"rgba(74, 222, 128, 0.15)\",\n statusResolved: \"#94a3b8\",\n statusResolvedBg: \"rgba(148, 163, 184, 0.15)\",\n };\n }\n\n return {\n accent: hex,\n accentLight: hex + \"14\", // 8% opacity\n accentDark: dark,\n accentGlow: hex + \"33\", // 20% opacity\n accentGradient: `linear-gradient(135deg, ${hex}, ${dark})`,\n bg: \"#ffffff\",\n bgHover: \"#f8f9fb\",\n text: \"#0f172a\",\n textSecondary: \"#475569\",\n textTertiary: \"#64748b\",\n border: \"#e2e8f0\",\n shadow: \"rgba(0, 0, 0, 0.06)\",\n // Glass tokens\n glassBg: \"rgba(255, 255, 255, 0.72)\",\n glassBgHeavy: \"rgba(255, 255, 255, 0.85)\",\n glassBorder: \"rgba(255, 255, 255, 0.35)\",\n glassBorderSubtle: \"rgba(255, 255, 255, 0.18)\",\n // Vibrant type colors\n typeQuestion: \"#3b82f6\",\n typeChange: \"#b45309\",\n typeBug: \"#ef4444\",\n typeOther: \"#64748b\",\n // Pastel backgrounds\n typeQuestionBg: \"#eff6ff\",\n typeChangeBg: \"#fffbeb\",\n typeBugBg: \"#fef2f2\",\n typeOtherBg: \"#f8fafc\",\n // Status colors — saturated green / cool gray on light\n statusOpen: \"#16a34a\",\n statusOpenBg: \"#f0fdf4\",\n statusResolved: \"#64748b\",\n statusResolvedBg: \"#f1f5f9\",\n };\n}\n\nexport function getTypeColor(type: string, colors: ThemeColors): string {\n switch (type) {\n case \"question\":\n return colors.typeQuestion;\n case \"change\":\n return colors.typeChange;\n case \"bug\":\n return colors.typeBug;\n default:\n return colors.typeOther;\n }\n}\n\nexport function getTypeBgColor(type: string, colors: ThemeColors): string {\n switch (type) {\n case \"question\":\n return colors.typeQuestionBg;\n case \"change\":\n return colors.typeChangeBg;\n case \"bug\":\n return colors.typeBugBg;\n default:\n return colors.typeOtherBg;\n }\n}\n\nexport function cssVariables(colors: ThemeColors): string {\n return `\n --sp-accent: ${colors.accent};\n --sp-accent-light: ${colors.accentLight};\n --sp-accent-dark: ${colors.accentDark};\n --sp-accent-glow: ${colors.accentGlow};\n --sp-accent-gradient: ${colors.accentGradient};\n --sp-bg: ${colors.bg};\n --sp-bg-hover: ${colors.bgHover};\n --sp-text: ${colors.text};\n --sp-text-secondary: ${colors.textSecondary};\n --sp-text-tertiary: ${colors.textTertiary};\n --sp-border: ${colors.border};\n --sp-shadow: ${colors.shadow};\n --sp-glass-bg: ${colors.glassBg};\n --sp-glass-bg-heavy: ${colors.glassBgHeavy};\n --sp-glass-border: ${colors.glassBorder};\n --sp-glass-border-subtle: ${colors.glassBorderSubtle};\n --sp-type-question: ${colors.typeQuestion};\n --sp-type-change: ${colors.typeChange};\n --sp-type-bug: ${colors.typeBug};\n --sp-type-other: ${colors.typeOther};\n --sp-type-question-bg: ${colors.typeQuestionBg};\n --sp-type-change-bg: ${colors.typeChangeBg};\n --sp-type-bug-bg: ${colors.typeBugBg};\n --sp-type-other-bg: ${colors.typeOtherBg};\n --sp-radius: 12px;\n --sp-radius-lg: 16px;\n --sp-radius-xl: 20px;\n --sp-radius-full: 9999px;\n --sp-blur: 20px;\n --sp-blur-heavy: 32px;\n --sp-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);\n --sp-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.04);\n --sp-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.04);\n --sp-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.04);\n --sp-shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.12), 0 8px 16px rgba(0, 0, 0, 0.06);\n --sp-font: \"Inter\", system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n `;\n}\n","import type { Translations } from \"./types.js\";\n\nexport const en: Translations = {\n // Panel\n \"panel.title\": \"Feedbacks\",\n \"panel.ariaLabel\": \"Siteping feedback panel\",\n \"panel.feedbackList\": \"Feedback list\",\n \"panel.loading\": \"Loading feedbacks\",\n \"panel.close\": \"Close panel\",\n \"panel.deleteAll\": \"Delete all\",\n \"panel.deleteAllConfirmTitle\": \"Delete all\",\n \"panel.deleteAllConfirmMessage\": \"Delete all feedbacks for this project? This action cannot be undone.\",\n \"panel.search\": \"Search...\",\n \"panel.searchAria\": \"Search feedbacks\",\n \"panel.filterAll\": \"All\",\n \"panel.loadError\": \"Failed to load\",\n \"panel.retry\": \"Retry\",\n \"panel.empty\": \"No feedback yet\",\n \"panel.showMore\": \"Show more\",\n \"panel.showLess\": \"Show less\",\n \"panel.resolve\": \"Resolve\",\n \"panel.reopen\": \"Reopen\",\n \"panel.delete\": \"Delete\",\n \"panel.cancel\": \"Cancel\",\n \"panel.confirmDelete\": \"Delete\",\n \"panel.loadMore\": \"Load more ({remaining} remaining)\",\n\n // Status filter labels\n \"panel.statusAll\": \"All\",\n \"panel.statusOpen\": \"Open\",\n \"panel.statusResolved\": \"Resolved\",\n\n // Feedback type labels\n \"type.label\": \"Type\",\n \"type.question\": \"Question\",\n \"type.change\": \"Change\",\n \"type.bug\": \"Bug\",\n \"type.other\": \"Other\",\n\n // Status segmented control label\n \"status.label\": \"Status\",\n\n // Page scope segmented control\n \"scope.label\": \"Scope\",\n \"scope.thisPage\": \"This page\",\n \"scope.thisType\": \"This type\",\n \"scope.all\": \"All pages\",\n\n // FAB menu\n \"fab.aria\": \"Siteping \\u2014 Feedback menu\",\n \"fab.messages\": \"Messages\",\n \"fab.annotate\": \"Annotate\",\n \"fab.annotations\": \"Annotations\",\n\n // Annotator\n \"annotator.instruction\": \"Draw a rectangle on the area to comment\",\n \"annotator.cancel\": \"Cancel\",\n\n // Popup\n \"popup.ariaLabel\": \"Feedback form\",\n \"popup.placeholder\": \"Describe your feedback...\",\n \"popup.textareaAria\": \"Feedback message\",\n \"popup.submitHintMac\": \"\\u2318+Enter to send\",\n \"popup.submitHintOther\": \"Ctrl+Enter to send\",\n \"popup.cancel\": \"Cancel\",\n \"popup.submit\": \"Send\",\n\n // Identity modal\n \"identity.title\": \"Identify yourself\",\n \"identity.nameLabel\": \"Name\",\n \"identity.namePlaceholder\": \"Your name\",\n \"identity.emailLabel\": \"Email\",\n \"identity.emailPlaceholder\": \"your@email.com\",\n \"identity.cancel\": \"Cancel\",\n \"identity.submit\": \"Continue\",\n\n // Markers\n \"marker.approximate\": \"Approximate position (confidence: {confidence}%)\",\n \"marker.aria\": \"Feedback #{number}: {type} — {message}\",\n \"marker.count\": \"{count} feedback markers displayed\",\n\n // FAB badge\n \"fab.badge\": \"{count} unresolved feedbacks\",\n\n // Accessibility — screen reader announcements\n \"feedback.sent.confirmation\": \"Feedback sent successfully\",\n \"feedback.error.message\": \"Failed to send feedback\",\n \"feedback.deleted.confirmation\": \"Feedback deleted\",\n\n // Badge\n \"badge.count\": \"{count} unresolved feedbacks\",\n\n // Bulk actions toolbar\n \"bulk.selectAll\": \"Select all\",\n \"bulk.selected\": \"{count} selected\",\n \"bulk.resolve\": \"Resolve\",\n \"bulk.delete\": \"Delete\",\n \"bulk.deselect\": \"Deselect\",\n\n // Sort and group controls\n \"sort.newest\": \"Newest first\",\n \"sort.oldest\": \"Oldest first\",\n \"sort.byType\": \"By type\",\n \"sort.openFirst\": \"Open first\",\n \"sort.label\": \"Sort\",\n \"group.byPage\": \"By page\",\n \"group.feedbacks\": \"{count} feedbacks\",\n\n // Stats bar\n \"stats.open\": \"Open\",\n \"stats.resolved\": \"Resolved\",\n \"stats.bugs\": \"Bugs\",\n \"stats.progress\": \"{percent}% resolved\",\n\n // Detail view\n \"detail.back\": \"Back\",\n \"detail.title\": \"Feedback #{number}\",\n \"detail.status\": \"Status\",\n \"detail.message\": \"Message\",\n \"detail.screenshot\": \"Screenshot\",\n \"detail.screenshotAlt\": \"Screenshot of the annotated area\",\n \"detail.metadata\": \"Details\",\n \"detail.annotation\": \"Annotation\",\n \"detail.page\": \"Page\",\n \"detail.author\": \"Author\",\n \"detail.date\": \"Created\",\n \"detail.viewport\": \"Viewport\",\n \"detail.browser\": \"Browser\",\n \"detail.resolvedAt\": \"Resolved at\",\n \"detail.goToAnnotation\": \"Go to annotation\",\n \"detail.element\": \"Element\",\n \"detail.selector\": \"Selector\",\n \"detail.position\": \"Position\",\n \"detail.resolve\": \"Resolve\",\n \"detail.reopen\": \"Reopen\",\n \"detail.delete\": \"Delete\",\n \"detail.diagnostics\": \"Diagnostics\",\n \"detail.diagnostics.console\": \"Console\",\n \"detail.diagnostics.network\": \"Failed network\",\n \"detail.diagnostics.expand\": \"Show diagnostics\",\n \"detail.diagnostics.collapse\": \"Hide diagnostics\",\n \"detail.diagnostics.noEntries\": \"No entries\",\n\n // Keyboard shortcuts overlay\n \"shortcuts.title\": \"Keyboard shortcuts\",\n \"shortcuts.navigate\": \"Navigate feedbacks\",\n \"shortcuts.resolve\": \"Resolve / Reopen\",\n \"shortcuts.delete\": \"Delete\",\n \"shortcuts.search\": \"Focus search\",\n \"shortcuts.select\": \"Toggle selection\",\n \"shortcuts.help\": \"Show shortcuts\",\n \"shortcuts.close\": \"Close\",\n \"shortcuts.hint\": \"Keyboard shortcuts\",\n\n // Export controls\n \"export.label\": \"Export\",\n \"export.csv\": \"Export CSV\",\n \"export.json\": \"Export JSON\",\n};\n","import type { TFunction, Translations } from \"./types.js\";\n\nexport type { TFunction, Translations } from \"./types.js\";\n\n// `en` is bundled synchronously as the immediate fallback — every other\n// locale is dynamically imported on demand to keep the initial bundle small.\n// In practice the bundler emits one chunk per locale and only the resolved\n// one ships over the network when `loadLocale()` is called.\nimport { en } from \"./en.js\";\n\nconst LOCALES: Record<string, Translations> = { en };\n\n/** Built-in locales other than the synchronously-bundled English fallback. */\nconst BUILTIN_LOCALES = new Set([\"de\", \"es\", \"fr\", \"it\", \"pt\", \"ru\"]);\n\n/** Register a custom locale at runtime. */\nexport function registerLocale(code: string, translations: Translations): void {\n LOCALES[code] = translations;\n}\n\n/**\n * Dynamically import a built-in locale and register it. Returns the loaded\n * translations or `null` if the locale isn't a known built-in. Custom locales\n * registered via {@link registerLocale} bypass this loader — they are already\n * in the registry.\n */\nexport async function loadLocale(locale: string): Promise<Translations | null> {\n const lang = (locale.split(\"-\")[0] ?? locale).toLowerCase();\n if (LOCALES[lang]) return LOCALES[lang]; // already loaded (en, custom, or previously fetched)\n if (!BUILTIN_LOCALES.has(lang)) return null;\n // The static template means tsup/esbuild will create one chunk per locale\n // and only the requested one is fetched at runtime.\n let mod: { [k: string]: Translations };\n switch (lang) {\n case \"de\":\n mod = await import(\"./de.js\");\n break;\n case \"es\":\n mod = await import(\"./es.js\");\n break;\n case \"fr\":\n mod = await import(\"./fr.js\");\n break;\n case \"it\":\n mod = await import(\"./it.js\");\n break;\n case \"pt\":\n mod = await import(\"./pt.js\");\n break;\n case \"ru\":\n mod = await import(\"./ru.js\");\n break;\n default:\n return null;\n }\n const dict = mod[lang];\n if (!dict) return null;\n LOCALES[lang] = dict;\n return dict;\n}\n\n/**\n * Create a translation function for the given locale.\n *\n * Locale resolution: exact match > language prefix > English fallback.\n * Non-English built-in locales are lazy-loaded via {@link loadLocale} — call\n * `await loadLocale(locale)` at init if you want the panel to render in the\n * target language immediately. Otherwise the widget renders in English until\n * the dictionary lands, then `createT` returns the resolved dictionary.\n */\nexport function createT(locale: string): TFunction {\n const lang = (locale.split(\"-\")[0] ?? locale).toLowerCase();\n if (lang !== \"en\" && !LOCALES[lang] && !BUILTIN_LOCALES.has(lang)) {\n console.warn(`[siteping] Unknown locale \"${locale}\", falling back to \"en\"`);\n }\n // Read LOCALES at call time so `createT` returns up-to-date translations\n // after `loadLocale` has registered the dictionary asynchronously.\n return (key) => {\n const dict = LOCALES[lang] ?? LOCALES.en ?? ({} as Translations);\n return dict[key] ?? LOCALES.en?.[key] ?? key;\n };\n}\n\n/**\n * Returns the type label for a FeedbackType value.\n * Maps API enum values (english) to localized display labels.\n */\nexport function getTypeLabel(type: string, t: TFunction): string {\n switch (type) {\n case \"question\":\n return t(\"type.question\");\n case \"change\":\n return t(\"type.change\");\n case \"bug\":\n return t(\"type.bug\");\n case \"other\":\n return t(\"type.other\");\n default:\n return type;\n }\n}\n","import type { FeedbackResponse } from \"@siteping/core\";\nimport { el, parseSvg, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\n// ---------------------------------------------------------------------------\n// Icons\n// ---------------------------------------------------------------------------\n\nexport const ICON_EXPORT = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/></svg>`;\n\nconst ICON_CSV = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>`;\n\nconst ICON_JSON = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 3H6a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2 2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h2\"/><path d=\"M16 3h2a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2 2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2\"/></svg>`;\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nexport const EXPORT_CSS = `\n /* ============================\n Export Button & Menu\n ============================ */\n\n .sp-export-btn {\n padding: 5px 12px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: transparent;\n color: var(--sp-text-tertiary);\n font-family: var(--sp-font);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n position: relative;\n }\n\n .sp-export-btn svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-export-btn:hover {\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n background: var(--sp-accent-light);\n }\n\n .sp-export-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .sp-export-menu {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n min-width: 180px;\n padding: 4px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-lg);\n z-index: 10;\n opacity: 0;\n transform: translateY(-4px) scale(0.97);\n transition: opacity 0.15s ease, transform 0.15s ease;\n pointer-events: none;\n }\n\n .sp-export-menu--open {\n opacity: 1;\n transform: translateY(0) scale(1);\n pointer-events: auto;\n }\n\n .sp-export-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 16px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n text-align: left;\n }\n\n .sp-export-option:hover,\n .sp-export-option:focus-visible {\n background: var(--sp-accent-light);\n color: var(--sp-accent);\n }\n\n .sp-export-option-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .sp-export-option-icon svg {\n width: 16px;\n height: 16px;\n }\n\n .sp-export-option-label {\n flex: 1;\n }\n\n @media (forced-colors: active) {\n .sp-export-btn,\n .sp-export-option,\n .sp-export-menu {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-export-btn:focus-visible,\n .sp-export-option:focus-visible {\n outline: 3px solid Highlight !important;\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// CSV / JSON conversion\n// ---------------------------------------------------------------------------\n\nconst CSV_COLUMNS = [\n \"id\",\n \"type\",\n \"status\",\n \"message\",\n \"url\",\n \"authorName\",\n \"authorEmail\",\n \"createdAt\",\n \"resolvedAt\",\n \"viewport\",\n] as const;\n\n/** Escape a value for CSV: wrap in double-quotes if it contains commas, newlines, or quotes. */\nfunction escapeCsvField(value: string): string {\n if (value.includes('\"') || value.includes(\",\") || value.includes(\"\\n\") || value.includes(\"\\r\")) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\n/** Convert feedbacks to CSV string */\nexport function feedbacksToCsv(feedbacks: FeedbackResponse[]): string {\n const header = CSV_COLUMNS.join(\",\");\n const rows = feedbacks.map((fb) =>\n CSV_COLUMNS.map((col) => {\n const raw = fb[col];\n return escapeCsvField(raw == null ? \"\" : String(raw));\n }).join(\",\"),\n );\n return [header, ...rows].join(\"\\n\");\n}\n\n/** Convert feedbacks to formatted JSON string */\nexport function feedbacksToJson(feedbacks: FeedbackResponse[]): string {\n return JSON.stringify(feedbacks, null, 2);\n}\n\n// ---------------------------------------------------------------------------\n// Download helper\n// ---------------------------------------------------------------------------\n\n/** Trigger browser download of a string as file */\nexport function downloadFile(content: string, filename: string, mimeType: string): void {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = filename;\n anchor.style.display = \"none\";\n document.body.appendChild(anchor);\n anchor.click();\n // Clean up after a tick to ensure the download starts\n requestAnimationFrame(() => {\n URL.revokeObjectURL(url);\n anchor.remove();\n });\n}\n\n// ---------------------------------------------------------------------------\n// ExportButton component\n// ---------------------------------------------------------------------------\n\nexport class ExportButton {\n readonly element: HTMLElement;\n\n private menu: HTMLElement;\n private isOpen = false;\n private onDocumentClick: (e: MouseEvent) => void;\n\n constructor(\n _colors: ThemeColors,\n private readonly getFeedbacks: () => FeedbackResponse[],\n t: TFunction,\n ) {\n // Wrapper for relative positioning of the menu\n this.element = el(\"div\", { style: \"position: relative; display: inline-flex;\" });\n\n // Trigger button — matches .sp-btn-delete-all pill style\n const btn = document.createElement(\"button\");\n btn.className = \"sp-export-btn\";\n btn.setAttribute(\"aria-haspopup\", \"true\");\n btn.setAttribute(\"aria-expanded\", \"false\");\n btn.appendChild(parseSvg(ICON_EXPORT));\n const label = document.createElement(\"span\");\n setText(label, t(\"export.label\"));\n btn.appendChild(label);\n btn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggle();\n });\n\n // Dropdown menu\n this.menu = el(\"div\", { class: \"sp-export-menu\" });\n this.menu.setAttribute(\"role\", \"menu\");\n\n // CSV option\n const csvOption = this.createOption(ICON_CSV, t(\"export.csv\"), () => {\n this.exportAs(\"csv\");\n });\n\n // JSON option\n const jsonOption = this.createOption(ICON_JSON, t(\"export.json\"), () => {\n this.exportAs(\"json\");\n });\n\n this.menu.appendChild(csvOption);\n this.menu.appendChild(jsonOption);\n\n this.element.appendChild(btn);\n this.element.appendChild(this.menu);\n\n // Close on outside click\n this.onDocumentClick = (e: MouseEvent) => {\n if (this.isOpen && !this.element.contains(e.target as Node)) {\n this.close();\n }\n };\n document.addEventListener(\"click\", this.onDocumentClick, true);\n }\n\n private createOption(iconSvg: string, labelText: string, onClick: () => void): HTMLButtonElement {\n const option = document.createElement(\"button\");\n option.className = \"sp-export-option\";\n option.setAttribute(\"role\", \"menuitem\");\n\n const iconWrap = el(\"span\", { class: \"sp-export-option-icon\" });\n iconWrap.appendChild(parseSvg(iconSvg));\n\n const labelEl = el(\"span\", { class: \"sp-export-option-label\" });\n setText(labelEl, labelText);\n\n option.appendChild(iconWrap);\n option.appendChild(labelEl);\n\n option.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n onClick();\n this.close();\n });\n\n return option;\n }\n\n private toggle(): void {\n this.isOpen ? this.close() : this.open();\n }\n\n private open(): void {\n this.isOpen = true;\n this.menu.classList.add(\"sp-export-menu--open\");\n const btn = this.element.querySelector<HTMLButtonElement>(\".sp-export-btn\");\n btn?.setAttribute(\"aria-expanded\", \"true\");\n }\n\n private close(): void {\n this.isOpen = false;\n this.menu.classList.remove(\"sp-export-menu--open\");\n const btn = this.element.querySelector<HTMLButtonElement>(\".sp-export-btn\");\n btn?.setAttribute(\"aria-expanded\", \"false\");\n }\n\n private exportAs(format: \"csv\" | \"json\"): void {\n const feedbacks = this.getFeedbacks();\n if (feedbacks.length === 0) return;\n\n const projectName = feedbacks[0]?.projectName ?? \"feedbacks\";\n const date = new Date().toISOString().slice(0, 10);\n const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n\n if (format === \"csv\") {\n const content = feedbacksToCsv(feedbacks);\n downloadFile(content, `feedbacks-${safeName}-${date}.csv`, \"text/csv;charset=utf-8\");\n } else {\n const content = feedbacksToJson(feedbacks);\n downloadFile(content, `feedbacks-${safeName}-${date}.json`, \"application/json;charset=utf-8\");\n }\n }\n\n destroy(): void {\n document.removeEventListener(\"click\", this.onDocumentClick, true);\n this.element.remove();\n }\n}\n","/**\n * Bulk Actions system for the feedback panel.\n *\n * Allows multi-select on feedback cards with a floating action bar\n * for batch resolve/delete operations. Glassmorphism design with\n * spring animations and smooth transitions.\n */\n\nimport { el, parseSvg, setButtonLoading, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\n// ---------------------------------------------------------------------------\n// SVG Icons\n// ---------------------------------------------------------------------------\n\nexport const ICON_CHECKBOX = `<svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\"><rect x=\"1\" y=\"1\" width=\"16\" height=\"16\" rx=\"4\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>`;\n\nexport const ICON_CHECKBOX_CHECKED = `<svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\"><rect x=\"1\" y=\"1\" width=\"16\" height=\"16\" rx=\"4\" fill=\"url(#sp-cb-grad)\" stroke=\"none\"/><polyline points=\"5 9 8 12 13 6\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><defs><linearGradient id=\"sp-cb-grad\" x1=\"0\" y1=\"0\" x2=\"18\" y2=\"18\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0%\" stop-color=\"var(--sp-accent)\"/><stop offset=\"100%\" stop-color=\"var(--sp-accent-dark)\"/></linearGradient></defs></svg>`;\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nexport const BULK_CSS = `\n /* ============================\n Bulk Checkbox\n ============================ */\n\n .sp-bulk-checkbox {\n position: relative;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n cursor: pointer;\n border-radius: 4px;\n color: var(--sp-border);\n opacity: 0;\n transition: opacity 0.15s ease, color 0.15s ease, transform 0.15s ease;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .sp-bulk-checkbox svg {\n width: 16px;\n height: 16px;\n display: block;\n }\n\n .sp-bulk-checkbox:hover {\n color: var(--sp-accent);\n transform: scale(1.1);\n }\n\n .sp-bulk-checkbox--checked {\n color: var(--sp-accent);\n opacity: 1 !important;\n filter: drop-shadow(0 0 4px var(--sp-accent-glow));\n }\n\n /* Show checkboxes when hovering a card */\n .sp-card:hover .sp-bulk-checkbox {\n opacity: 1;\n }\n\n /* When any card has selection, show ALL checkboxes */\n .sp-list--has-selection .sp-bulk-checkbox {\n opacity: 1;\n }\n\n /* ============================\n Card Selected State\n ============================ */\n\n .sp-card--selected {\n border-left: 3px solid var(--sp-accent) !important;\n background: var(--sp-accent-light) !important;\n }\n\n .sp-card--selected:hover {\n background: var(--sp-accent-light) !important;\n }\n\n /* ============================\n Select All Bar\n ============================ */\n\n .sp-bulk-select-all {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n margin-bottom: 4px;\n border-radius: var(--sp-radius);\n background: transparent;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n user-select: none;\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n color: var(--sp-text-secondary);\n }\n\n .sp-bulk-select-all:hover {\n background: var(--sp-bg-hover);\n }\n\n /* Show select-all on list hover or when selections exist */\n .sp-list:hover .sp-bulk-select-all,\n .sp-list--has-selection .sp-bulk-select-all {\n opacity: 1;\n }\n\n .sp-bulk-select-all .sp-bulk-checkbox {\n opacity: 1;\n }\n\n /* ============================\n Floating Action Bar\n ============================ */\n\n @keyframes sp-bulk-bar-in {\n from {\n transform: translateY(100%) scale(0.95);\n opacity: 0;\n }\n to {\n transform: translateY(0) scale(1);\n opacity: 1;\n }\n }\n\n @keyframes sp-bulk-bar-out {\n from {\n transform: translateY(0) scale(1);\n opacity: 1;\n }\n to {\n transform: translateY(100%) scale(0.95);\n opacity: 0;\n }\n }\n\n .sp-bulk-bar {\n position: absolute;\n bottom: 16px;\n left: 16px;\n right: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 16px;\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xl);\n z-index: 10;\n pointer-events: none;\n opacity: 0;\n transform: translateY(100%) scale(0.95);\n transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),\n opacity 0.25s ease;\n font-family: var(--sp-font);\n }\n\n .sp-bulk-bar--visible {\n pointer-events: auto;\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n\n .sp-bulk-bar-count {\n font-size: 13px;\n font-weight: 600;\n color: var(--sp-text);\n white-space: nowrap;\n letter-spacing: -0.01em;\n }\n\n .sp-bulk-bar-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .sp-bulk-btn-resolve,\n .sp-bulk-btn-delete {\n padding: 7px 14px;\n border-radius: var(--sp-radius-full);\n border: 1.5px solid transparent;\n background: transparent;\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 5px;\n transition: all 0.2s ease;\n white-space: nowrap;\n }\n\n .sp-bulk-btn-resolve {\n color: #22c55e;\n border-color: #22c55e;\n }\n\n .sp-bulk-btn-resolve:hover {\n background: rgba(34, 197, 94, 0.1);\n box-shadow: 0 0 12px rgba(34, 197, 94, 0.15);\n }\n\n .sp-bulk-btn-resolve:active {\n transform: scale(0.96);\n transition-duration: 0.1s;\n }\n\n .sp-bulk-btn-delete {\n color: #ef4444;\n border-color: #ef4444;\n }\n\n .sp-bulk-btn-delete:hover {\n background: rgba(239, 68, 68, 0.1);\n box-shadow: 0 0 12px rgba(239, 68, 68, 0.15);\n }\n\n .sp-bulk-btn-delete:active {\n transform: scale(0.96);\n transition-duration: 0.1s;\n }\n\n .sp-bulk-btn-resolve:disabled,\n .sp-bulk-btn-delete:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .sp-bulk-btn-deselect {\n width: 28px;\n height: 28px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: transparent;\n color: var(--sp-text-tertiary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n flex-shrink: 0;\n padding: 0;\n }\n\n .sp-bulk-btn-deselect:hover {\n background: var(--sp-bg-hover);\n color: var(--sp-text);\n border-color: var(--sp-text-tertiary);\n }\n\n .sp-bulk-btn-deselect:active {\n transform: scale(0.92);\n transition-duration: 0.1s;\n }\n\n .sp-bulk-btn-deselect svg {\n width: 12px;\n height: 12px;\n }\n\n /* Spinner inside bulk bar buttons */\n .sp-bulk-btn-resolve .sp-spinner,\n .sp-bulk-btn-delete .sp-spinner {\n width: 14px;\n height: 14px;\n }\n\n /* ============================\n Forced Colors / High Contrast\n ============================ */\n\n @media (forced-colors: active) {\n .sp-bulk-checkbox,\n .sp-bulk-btn-resolve,\n .sp-bulk-btn-delete,\n .sp-bulk-btn-deselect,\n .sp-bulk-bar {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-bulk-checkbox--checked {\n background: Highlight !important;\n color: HighlightText !important;\n }\n\n .sp-card--selected {\n border-left: 4px solid Highlight !important;\n }\n }\n\n /* ============================\n Reduced Motion\n ============================ */\n\n @media (prefers-reduced-motion: reduce) {\n .sp-bulk-bar {\n transition-duration: 0.01ms !important;\n }\n\n .sp-bulk-checkbox {\n transition-duration: 0.01ms !important;\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Callbacks\n// ---------------------------------------------------------------------------\n\nexport interface BulkActionCallbacks {\n onResolve: (ids: string[]) => Promise<void>;\n onDelete: (ids: string[]) => Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// BulkActions Class\n// ---------------------------------------------------------------------------\n\nexport class BulkActions {\n /** The floating action bar element — append to panel root */\n readonly barElement: HTMLElement;\n\n private selected = new Set<string>();\n private checkboxMap = new Map<string, HTMLElement>();\n private countLabel: HTMLElement;\n private resolveBtn: HTMLButtonElement;\n private deleteBtn: HTMLButtonElement;\n private selectAllCheckbox: HTMLElement | null = null;\n private listContainer: HTMLElement | null = null;\n private isProcessing = false;\n private readonly t: TFunction;\n\n constructor(\n _colors: ThemeColors,\n private readonly callbacks: BulkActionCallbacks,\n t: TFunction,\n ) {\n this.t = t;\n // ----- Build floating bar -----\n this.barElement = el(\"div\", { class: \"sp-bulk-bar\" });\n this.barElement.setAttribute(\"role\", \"toolbar\");\n this.barElement.setAttribute(\"aria-label\", \"Bulk actions\");\n\n // Left: count label\n this.countLabel = el(\"span\", { class: \"sp-bulk-bar-count\" });\n setText(this.countLabel, this.t(\"bulk.selected\").replace(\"{count}\", \"0\"));\n\n // Right: action buttons\n const actions = el(\"div\", { class: \"sp-bulk-bar-actions\" });\n\n this.resolveBtn = document.createElement(\"button\");\n this.resolveBtn.className = \"sp-bulk-btn-resolve\";\n this.resolveBtn.type = \"button\";\n this.resolveBtn.addEventListener(\"click\", () => this.handleResolve());\n\n this.deleteBtn = document.createElement(\"button\");\n this.deleteBtn.className = \"sp-bulk-btn-delete\";\n this.deleteBtn.type = \"button\";\n this.deleteBtn.addEventListener(\"click\", () => this.handleDelete());\n\n const deselectBtn = document.createElement(\"button\");\n deselectBtn.className = \"sp-bulk-btn-deselect\";\n deselectBtn.type = \"button\";\n deselectBtn.setAttribute(\"aria-label\", this.t(\"bulk.deselect\"));\n deselectBtn.appendChild(\n parseSvg(\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`,\n ),\n );\n deselectBtn.addEventListener(\"click\", () => this.deselectAll());\n\n actions.appendChild(this.resolveBtn);\n actions.appendChild(this.deleteBtn);\n actions.appendChild(deselectBtn);\n\n this.barElement.appendChild(this.countLabel);\n this.barElement.appendChild(actions);\n\n // Initial button text\n this.updateButtonLabels();\n }\n\n /** Create a checkbox element for a card. Returns the checkbox wrapper. */\n createCheckbox(feedbackId: string): HTMLElement {\n const wrapper = el(\"div\", { class: \"sp-bulk-checkbox\" });\n wrapper.setAttribute(\"role\", \"checkbox\");\n wrapper.setAttribute(\"aria-checked\", \"false\");\n wrapper.setAttribute(\"tabindex\", \"0\");\n wrapper.setAttribute(\"aria-label\", `Select feedback ${feedbackId}`);\n\n // Render unchecked icon\n wrapper.appendChild(parseSvg(ICON_CHECKBOX));\n\n // Click handler\n wrapper.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggle(feedbackId);\n });\n\n // Keyboard: space/enter to toggle\n wrapper.addEventListener(\"keydown\", (e) => {\n if ((e as KeyboardEvent).key === \" \" || (e as KeyboardEvent).key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n this.toggle(feedbackId);\n }\n });\n\n this.checkboxMap.set(feedbackId, wrapper);\n return wrapper;\n }\n\n /**\n * Create a \"Select all\" bar element.\n * The caller should insert this at the top of the list container.\n */\n createSelectAllBar(feedbackIds: string[], label: string): HTMLElement {\n const wrapper = el(\"div\", { class: \"sp-bulk-select-all\" });\n\n const checkbox = el(\"div\", { class: \"sp-bulk-checkbox\" });\n checkbox.appendChild(parseSvg(ICON_CHECKBOX));\n this.selectAllCheckbox = checkbox;\n\n const labelEl = el(\"span\");\n setText(labelEl, label);\n\n wrapper.appendChild(checkbox);\n wrapper.appendChild(labelEl);\n\n wrapper.addEventListener(\"click\", () => {\n // If all selected, deselect; otherwise select all\n if (this.selected.size === feedbackIds.length && feedbackIds.length > 0) {\n this.deselectAll();\n } else {\n this.selectAll(feedbackIds);\n }\n });\n\n return wrapper;\n }\n\n /** Set the list container reference (for toggling .sp-list--has-selection) */\n setListContainer(container: HTMLElement): void {\n this.listContainer = container;\n }\n\n /** Toggle selection for a feedback */\n toggle(feedbackId: string): void {\n if (this.isProcessing) return;\n\n if (this.selected.has(feedbackId)) {\n this.selected.delete(feedbackId);\n } else {\n this.selected.add(feedbackId);\n }\n this.updateCheckbox(feedbackId);\n this.updateBar();\n this.updateSelectAllCheckbox();\n this.updateListSelectionClass();\n this.updateCardSelectedState(feedbackId);\n }\n\n /** Select all from the given list */\n selectAll(feedbackIds: string[]): void {\n if (this.isProcessing) return;\n\n for (const id of feedbackIds) {\n this.selected.add(id);\n this.updateCheckbox(id);\n this.updateCardSelectedState(id);\n }\n this.updateBar();\n this.updateSelectAllCheckbox();\n this.updateListSelectionClass();\n }\n\n /** Clear all selections */\n deselectAll(): void {\n const prevSelected = [...this.selected];\n this.selected.clear();\n for (const id of prevSelected) {\n this.updateCheckbox(id);\n this.updateCardSelectedState(id);\n }\n this.updateBar();\n this.updateSelectAllCheckbox();\n this.updateListSelectionClass();\n }\n\n /** Get currently selected IDs */\n get selectedIds(): string[] {\n return [...this.selected];\n }\n\n /** Get selection count */\n get count(): number {\n return this.selected.size;\n }\n\n /** Whether any items are selected */\n get hasSelection(): boolean {\n return this.selected.size > 0;\n }\n\n /** Reset state (e.g., after feedbacks reload) */\n reset(): void {\n this.selected.clear();\n this.checkboxMap.clear();\n this.selectAllCheckbox = null;\n\n this.isProcessing = false;\n this.updateBar();\n this.updateListSelectionClass();\n }\n\n /** Destroy / cleanup */\n destroy(): void {\n this.selected.clear();\n this.checkboxMap.clear();\n this.selectAllCheckbox = null;\n\n this.listContainer = null;\n this.barElement.remove();\n }\n\n // -----------------------------------------------------------------------\n // Private\n // -----------------------------------------------------------------------\n\n /** Update the bar visibility and counts */\n private updateBar(): void {\n const count = this.selected.size;\n const visible = count > 0;\n\n this.barElement.classList.toggle(\"sp-bulk-bar--visible\", visible);\n setText(this.countLabel, this.t(\"bulk.selected\").replace(\"{count}\", String(count)));\n this.updateButtonLabels();\n }\n\n private updateButtonLabels(): void {\n const count = this.selected.size;\n const resolve = this.t(\"bulk.resolve\");\n const del = this.t(\"bulk.delete\");\n\n // Resolve button\n this.resolveBtn.replaceChildren();\n const resolveLabel = document.createElement(\"span\");\n setText(resolveLabel, count > 0 ? `${resolve} ${count}` : resolve);\n this.resolveBtn.appendChild(resolveLabel);\n\n // Delete button\n this.deleteBtn.replaceChildren();\n const deleteLabel = document.createElement(\"span\");\n setText(deleteLabel, count > 0 ? `${del} ${count}` : del);\n this.deleteBtn.appendChild(deleteLabel);\n }\n\n private updateCheckbox(feedbackId: string): void {\n const checkbox = this.checkboxMap.get(feedbackId);\n if (!checkbox) return;\n\n const isChecked = this.selected.has(feedbackId);\n checkbox.classList.toggle(\"sp-bulk-checkbox--checked\", isChecked);\n checkbox.setAttribute(\"aria-checked\", String(isChecked));\n\n // Swap SVG icon\n checkbox.replaceChildren();\n checkbox.appendChild(parseSvg(isChecked ? ICON_CHECKBOX_CHECKED : ICON_CHECKBOX));\n }\n\n private updateSelectAllCheckbox(): void {\n if (!this.selectAllCheckbox) return;\n\n const allSelected = this.selected.size > 0 && this.selected.size === this.checkboxMap.size;\n this.selectAllCheckbox.classList.toggle(\"sp-bulk-checkbox--checked\", allSelected);\n this.selectAllCheckbox.setAttribute(\"aria-checked\", String(allSelected));\n\n this.selectAllCheckbox.replaceChildren();\n this.selectAllCheckbox.appendChild(parseSvg(allSelected ? ICON_CHECKBOX_CHECKED : ICON_CHECKBOX));\n }\n\n private updateListSelectionClass(): void {\n if (!this.listContainer) return;\n this.listContainer.classList.toggle(\"sp-list--has-selection\", this.selected.size > 0);\n }\n\n private updateCardSelectedState(feedbackId: string): void {\n if (!this.listContainer) return;\n const escapedId = CSS.escape(feedbackId);\n const card = this.listContainer.querySelector<HTMLElement>(`[data-feedback-id=\"${escapedId}\"]`);\n if (card) {\n card.classList.toggle(\"sp-card--selected\", this.selected.has(feedbackId));\n }\n }\n\n private async handleResolve(): Promise<void> {\n if (this.isProcessing || this.selected.size === 0) return;\n this.isProcessing = true;\n\n const ids = [...this.selected];\n const restoreResolve = setButtonLoading(this.resolveBtn);\n this.deleteBtn.disabled = true;\n\n try {\n await this.callbacks.onResolve(ids);\n this.reset();\n } catch {\n restoreResolve();\n this.deleteBtn.disabled = false;\n } finally {\n this.isProcessing = false;\n }\n }\n\n private async handleDelete(): Promise<void> {\n if (this.isProcessing || this.selected.size === 0) return;\n this.isProcessing = true;\n\n const ids = [...this.selected];\n const restoreDelete = setButtonLoading(this.deleteBtn);\n this.resolveBtn.disabled = true;\n\n try {\n await this.callbacks.onDelete(ids);\n this.reset();\n } catch {\n restoreDelete();\n this.resolveBtn.disabled = false;\n } finally {\n this.isProcessing = false;\n }\n }\n}\n","/**\n * Detail View for the feedback panel.\n *\n * Slides in from the right (panel-in-panel pattern) when a user clicks\n * a feedback card, showing full details: message, metadata, annotation\n * info, status actions, and a \"Go to annotation\" button.\n *\n * Glassmorphism design — frosted glass surfaces, staggered section\n * animations, accent gradients, premium micro-interactions.\n */\n\nimport type { FeedbackResponse } from \"@siteping/core\";\nimport { el, parseSvg, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { getTypeBgColor, getTypeColor, type ThemeColors } from \"./styles/theme.js\";\n\n// ---------------------------------------------------------------------------\n// SVG Icons\n// ---------------------------------------------------------------------------\n\nexport const ICON_ARROW_LEFT = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"/><polyline points=\"12 19 5 12 12 5\"/></svg>`;\n\nexport const ICON_MAP_PIN = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/></svg>`;\n\nexport const ICON_LINK = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`;\n\nexport const ICON_USER = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/></svg>`;\n\nexport const ICON_CALENDAR = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/></svg>`;\n\nexport const ICON_MONITOR = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"/><line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"/><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"/></svg>`;\n\nconst ICON_CHECK = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\nconst ICON_UNDO = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>`;\n\nconst ICON_TRASH = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/></svg>`;\n\nconst ICON_CODE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`;\n\nconst ICON_CROSSHAIR = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"22\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"6\" y1=\"12\" x2=\"2\" y2=\"12\"/><line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"2\"/><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"18\"/></svg>`;\n\nconst ICON_CHEVRON = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"9 18 15 12 9 6\"/></svg>`;\nconst ICON_TERMINAL = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"4 17 10 11 4 5\"/><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\"/></svg>`;\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nexport const DETAIL_CSS = /* css */ `\n /* ============================\n Detail View — Panel-in-Panel\n ============================ */\n\n .sp-detail {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n background: var(--sp-glass-bg);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n z-index: 20;\n transform: translateX(100%);\n transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform;\n overflow: hidden;\n }\n\n .sp-detail--visible {\n transform: translateX(0);\n }\n\n /* ---- Header ---- */\n\n .sp-detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n border-bottom: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n flex-shrink: 0;\n min-height: 64px;\n }\n\n .sp-detail-back {\n width: 40px;\n height: 40px;\n border-radius: var(--sp-radius);\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--sp-text-tertiary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n padding: 0;\n }\n\n .sp-detail-back:hover {\n background: var(--sp-bg-hover);\n color: var(--sp-text);\n }\n\n .sp-detail-back:active {\n transform: scale(0.92);\n transition-duration: 0.1s;\n }\n\n .sp-detail-back svg {\n width: 18px;\n height: 18px;\n }\n\n .sp-detail-title {\n font-size: 16px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .sp-detail-header .sp-badge {\n flex-shrink: 0;\n }\n\n /* ---- Content ---- */\n\n .sp-detail-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 0;\n }\n\n .sp-detail-content::-webkit-scrollbar {\n width: 6px;\n }\n\n .sp-detail-content::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .sp-detail-content::-webkit-scrollbar-thumb {\n background: var(--sp-border);\n border-radius: var(--sp-radius-full);\n }\n\n .sp-detail-content::-webkit-scrollbar-thumb:hover {\n background: var(--sp-text-tertiary);\n }\n\n /* ---- Section ---- */\n\n .sp-detail-section {\n padding: 20px 24px;\n border-bottom: 1px solid var(--sp-border);\n opacity: 0;\n transform: translateY(8px);\n animation: sp-detail-section-in 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n }\n\n @keyframes sp-detail-section-in {\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .sp-detail-section:last-child {\n border-bottom: none;\n }\n\n .sp-detail-section-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--sp-text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: 14px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .sp-detail-section-title svg {\n width: 14px;\n height: 14px;\n opacity: 0.6;\n }\n\n /* ---- Status + Actions Section ---- */\n\n .sp-detail-status {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 16px;\n }\n\n .sp-detail-status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 14px;\n border-radius: var(--sp-radius-full);\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n }\n\n .sp-detail-status-pill--open {\n background: rgba(34, 197, 94, 0.1);\n color: #22c55e;\n border: 1px solid rgba(34, 197, 94, 0.2);\n }\n\n .sp-detail-status-pill--resolved {\n background: rgba(156, 163, 175, 0.1);\n color: #9ca3af;\n border: 1px solid rgba(156, 163, 175, 0.2);\n }\n\n .sp-detail-status-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .sp-detail-actions {\n display: flex;\n gap: 8px;\n }\n\n .sp-detail-actions button {\n flex: 1;\n height: 40px;\n padding: 0 16px;\n border-radius: var(--sp-radius);\n font-family: var(--sp-font);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.2s ease;\n }\n\n .sp-detail-actions button svg {\n width: 15px;\n height: 15px;\n }\n\n .sp-detail-btn-resolve {\n border: 1.5px solid #22c55e;\n background: rgba(34, 197, 94, 0.06);\n color: #22c55e;\n }\n\n .sp-detail-btn-resolve:hover {\n background: rgba(34, 197, 94, 0.14);\n box-shadow: 0 0 16px rgba(34, 197, 94, 0.12);\n transform: translateY(-1px);\n }\n\n .sp-detail-btn-resolve:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-detail-btn-reopen {\n border: 1.5px solid var(--sp-accent);\n background: var(--sp-accent-light);\n color: var(--sp-accent);\n }\n\n .sp-detail-btn-reopen:hover {\n background: rgba(var(--sp-accent), 0.14);\n box-shadow: 0 0 16px var(--sp-accent-glow);\n transform: translateY(-1px);\n }\n\n .sp-detail-btn-reopen:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-detail-btn-delete {\n border: 1.5px solid #ef4444;\n background: rgba(239, 68, 68, 0.06);\n color: #ef4444;\n }\n\n .sp-detail-btn-delete:hover {\n background: rgba(239, 68, 68, 0.14);\n box-shadow: 0 0 16px rgba(239, 68, 68, 0.12);\n transform: translateY(-1px);\n }\n\n .sp-detail-btn-delete:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-detail-actions button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n transform: none;\n box-shadow: none;\n }\n\n /* ---- Message Section ---- */\n\n .sp-detail-message {\n font-size: 14px;\n line-height: 1.65;\n color: var(--sp-text);\n padding: 14px 16px;\n border-left: 3px solid var(--sp-accent);\n border-radius: 0 var(--sp-radius) var(--sp-radius) 0;\n background: var(--sp-glass-bg-heavy);\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n /* ---- Screenshot Section ---- */\n\n .sp-detail-screenshot {\n display: block;\n width: 100%;\n height: auto;\n max-height: 400px;\n object-fit: contain;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-glass-border);\n background: var(--sp-glass-bg-heavy);\n }\n\n /* ---- Metadata Section ---- */\n\n .sp-detail-meta {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .sp-detail-meta-row {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n }\n\n .sp-detail-meta-row svg {\n width: 14px;\n height: 14px;\n color: var(--sp-text-tertiary);\n flex-shrink: 0;\n margin-top: 1px;\n }\n\n .sp-detail-meta-content {\n flex: 1;\n min-width: 0;\n }\n\n .sp-detail-meta-label {\n font-size: 10px;\n font-weight: 600;\n color: var(--sp-text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n line-height: 1;\n margin-bottom: 4px;\n }\n\n .sp-detail-meta-value {\n font-size: 13px;\n line-height: 1.4;\n color: var(--sp-text);\n word-break: break-all;\n }\n\n .sp-detail-meta-value--mono {\n font-family: \"SF Mono\", \"Cascadia Code\", \"Fira Code\", \"Consolas\", monospace;\n font-size: 12px;\n background: var(--sp-glass-bg-heavy);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--sp-glass-border-subtle);\n }\n\n .sp-detail-meta-value--secondary {\n color: var(--sp-text-secondary);\n font-size: 12px;\n }\n\n /* ---- Annotation Section ---- */\n\n .sp-detail-annotation {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .sp-detail-annotation-info {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n border: 1px solid var(--sp-glass-border-subtle);\n }\n\n .sp-detail-annotation-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n }\n\n .sp-detail-annotation-row svg {\n width: 13px;\n height: 13px;\n color: var(--sp-text-tertiary);\n flex-shrink: 0;\n margin-top: 2px;\n }\n\n .sp-detail-annotation-label {\n font-size: 10px;\n font-weight: 600;\n color: var(--sp-text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n line-height: 1;\n margin-bottom: 3px;\n }\n\n .sp-detail-annotation-value {\n font-size: 12px;\n line-height: 1.4;\n color: var(--sp-text);\n word-break: break-all;\n }\n\n .sp-detail-annotation-value--mono {\n font-family: \"SF Mono\", \"Cascadia Code\", \"Fira Code\", \"Consolas\", monospace;\n font-size: 11px;\n background: var(--sp-bg-hover);\n padding: 2px 6px;\n border-radius: 4px;\n display: inline-block;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .sp-detail-btn-goto {\n width: 100%;\n height: 44px;\n padding: 0 20px;\n border-radius: var(--sp-radius);\n border: none;\n background: var(--sp-accent-gradient);\n color: #fff;\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: all 0.25s ease;\n box-shadow: 0 2px 12px var(--sp-accent-glow);\n }\n\n .sp-detail-btn-goto svg {\n width: 16px;\n height: 16px;\n }\n\n .sp-detail-btn-goto:hover {\n box-shadow: 0 4px 20px var(--sp-accent-glow);\n transform: translateY(-2px);\n }\n\n .sp-detail-btn-goto:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n /* ---- Forced Colors / High Contrast ---- */\n\n @media (forced-colors: active) {\n .sp-detail {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n }\n\n .sp-detail-back,\n .sp-detail-btn-goto,\n .sp-detail-btn-resolve,\n .sp-detail-btn-reopen,\n .sp-detail-btn-delete {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-detail-back:focus-visible,\n .sp-detail-btn-goto:focus-visible,\n .sp-detail-btn-resolve:focus-visible,\n .sp-detail-btn-reopen:focus-visible,\n .sp-detail-btn-delete:focus-visible {\n outline: 3px solid Highlight !important;\n }\n\n .sp-detail-status-pill {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-detail-message {\n border-left: 3px solid ButtonText !important;\n }\n }\n\n /* ---- Diagnostics Section ---- */\n\n .sp-detail-diag {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .sp-detail-diag-toggle {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 10px 12px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-glass-border-subtle);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n\n .sp-detail-diag-toggle:hover {\n background: var(--sp-bg-hover);\n }\n\n .sp-detail-diag-toggle svg {\n width: 12px;\n height: 12px;\n transition: transform 0.2s ease;\n }\n\n .sp-detail-diag-toggle[aria-expanded=\"true\"] svg {\n transform: rotate(90deg);\n }\n\n .sp-detail-diag-counts {\n display: inline-flex;\n gap: 6px;\n font-weight: 500;\n color: var(--sp-text-tertiary);\n }\n\n .sp-detail-diag-count {\n padding: 1px 7px;\n border-radius: var(--sp-radius-full);\n background: var(--sp-bg-hover);\n font-variant-numeric: tabular-nums;\n }\n\n .sp-detail-diag-count--errors {\n background: rgba(239, 68, 68, 0.14);\n color: #ef4444;\n }\n\n .sp-detail-diag-body {\n display: none;\n flex-direction: column;\n gap: 14px;\n }\n\n .sp-detail-diag-body--open {\n display: flex;\n }\n\n .sp-detail-diag-group-title {\n font-size: 10px;\n font-weight: 700;\n color: var(--sp-text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: 6px;\n }\n\n .sp-detail-diag-list {\n list-style: none;\n padding: 0;\n margin: 0;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-glass-border-subtle);\n background: var(--sp-glass-bg-heavy);\n max-height: 240px;\n overflow-y: auto;\n }\n\n .sp-detail-diag-list li {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 10px;\n border-bottom: 1px solid var(--sp-glass-border-subtle);\n font-family: \"SF Mono\", \"Cascadia Code\", \"Fira Code\", \"Consolas\", monospace;\n font-size: 11px;\n line-height: 1.45;\n color: var(--sp-text);\n }\n\n .sp-detail-diag-list li:last-child {\n border-bottom: none;\n }\n\n .sp-detail-diag-level {\n flex-shrink: 0;\n font-weight: 700;\n width: 44px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n font-size: 10px;\n }\n\n .sp-detail-diag-level--log {\n color: var(--sp-text-tertiary);\n }\n .sp-detail-diag-level--info {\n color: #3b82f6;\n }\n .sp-detail-diag-level--warn {\n color: #f59e0b;\n }\n .sp-detail-diag-level--error {\n color: #ef4444;\n }\n\n .sp-detail-diag-message {\n flex: 1;\n min-width: 0;\n word-break: break-word;\n white-space: pre-wrap;\n }\n\n .sp-detail-diag-net {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 8px;\n align-items: center;\n }\n\n .sp-detail-diag-net-status {\n flex-shrink: 0;\n font-weight: 700;\n color: #ef4444;\n min-width: 32px;\n text-align: right;\n font-variant-numeric: tabular-nums;\n }\n\n .sp-detail-diag-net-method {\n flex-shrink: 0;\n font-weight: 600;\n color: var(--sp-text-tertiary);\n min-width: 44px;\n }\n\n .sp-detail-diag-net-url {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--sp-text);\n }\n\n .sp-detail-diag-empty {\n padding: 12px;\n font-style: italic;\n font-size: 11px;\n color: var(--sp-text-tertiary);\n text-align: center;\n }\n\n /* ---- Reduced Motion ---- */\n\n @media (prefers-reduced-motion: reduce) {\n .sp-detail {\n transition-duration: 0.01ms !important;\n }\n\n .sp-detail-section {\n animation-duration: 0.01ms !important;\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Parse a userAgent string to extract the browser name and version. */\nfunction parseBrowser(ua: string): string {\n // Order matters: Edge includes \"Edg/\", Chrome includes \"Chrome/\", etc.\n if (/Edg\\//i.test(ua)) {\n const m = ua.match(/Edg\\/([\\d.]+)/);\n return m ? `Edge ${m[1]}` : \"Edge\";\n }\n if (/OPR\\//i.test(ua) || /Opera/i.test(ua)) {\n const m = ua.match(/OPR\\/([\\d.]+)/);\n return m ? `Opera ${m[1]}` : \"Opera\";\n }\n if (/Firefox\\//i.test(ua)) {\n const m = ua.match(/Firefox\\/([\\d.]+)/);\n return m ? `Firefox ${m[1]}` : \"Firefox\";\n }\n if (/Chrome\\//i.test(ua) && !/Chromium/i.test(ua)) {\n const m = ua.match(/Chrome\\/([\\d.]+)/);\n return m ? `Chrome ${m[1]}` : \"Chrome\";\n }\n if (/Safari\\//i.test(ua) && !/Chrome/i.test(ua)) {\n const m = ua.match(/Version\\/([\\d.]+)/);\n return m ? `Safari ${m[1]}` : \"Safari\";\n }\n return \"Unknown\";\n}\n\n/** Format an ISO date string to a full locale-aware date/time. */\nfunction formatFullDate(isoString: string, locale: string): string {\n try {\n const d = new Date(isoString);\n return d.toLocaleString(locale, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n } catch {\n return isoString;\n }\n}\n\n/** Extract the pathname from a URL string, falling back to the raw string. */\nfunction extractPathname(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return url;\n }\n}\n\n/**\n * Whitelist URL schemes that are safe to use as `<img src>`. Defends against\n * a buggy or compromised `ScreenshotStorage` (or DB) writing a `javascript:`,\n * `data:text/html`, or `data:image/svg+xml` URL — the latter can host\n * external `<image href>` references that exfiltrate IP/UA/Referer when the\n * panel renders. Browsers refuse to execute scripts via `<img>`, but the\n * fetch itself still happens for arbitrary URLs.\n */\nfunction isSafeImageUrl(url: string): boolean {\n // data:image/(jpeg|png|webp) is what the widget produces; SVG is excluded\n // because it can contain external references and is rarely a useful\n // screenshot format.\n if (/^data:image\\/(jpeg|png|webp);/i.test(url)) return true;\n // Remote URLs over https are accepted (S3, R2, etc.). http: is rejected\n // because the panel typically runs over https and mixed-content is blocked\n // anyway — surfacing the issue here is clearer than a silent network error.\n if (/^https:\\/\\//i.test(url)) return true;\n return false;\n}\n\n/** Truncate a string to a max length with ellipsis. */\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"\\u2026\";\n}\n\n/**\n * Whether a feedback carries a usable diagnostics payload. We only render the\n * section when at least one channel has entries; the section title alone with\n * two empty lists is just noise.\n */\nfunction hasDiagnostics(diagnostics: FeedbackResponse[\"diagnostics\"]): boolean {\n if (!diagnostics) return false;\n const consoleLen = Array.isArray(diagnostics.console) ? diagnostics.console.length : 0;\n const networkLen = Array.isArray(diagnostics.network) ? diagnostics.network.length : 0;\n return consoleLen > 0 || networkLen > 0;\n}\n\n/** Format a duration in ms as a compact \"123 ms\" / \"1.4 s\" string. */\nfunction formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return \"\\u2014\";\n if (ms < 1000) return `${Math.round(ms)} ms`;\n return `${(ms / 1000).toFixed(1)} s`;\n}\n\n// ---------------------------------------------------------------------------\n// Callbacks\n// ---------------------------------------------------------------------------\n\nexport interface DetailCallbacks {\n onBack: () => void;\n onResolve: (feedback: FeedbackResponse) => Promise<void>;\n onDelete: (feedback: FeedbackResponse) => Promise<void>;\n onGoToAnnotation: (feedback: FeedbackResponse) => void;\n}\n\n// ---------------------------------------------------------------------------\n// DetailView Class\n// ---------------------------------------------------------------------------\n\nexport class DetailView {\n readonly element: HTMLElement;\n\n private _isVisible = false;\n private currentFeedback: FeedbackResponse | null = null;\n private readonly content: HTMLElement;\n private readonly t: TFunction;\n private readonly locale: string;\n private resolveBtn: HTMLButtonElement | null = null;\n private deleteBtn: HTMLButtonElement | null = null;\n private isProcessing = false;\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly callbacks: DetailCallbacks,\n t: TFunction,\n locale: string,\n ) {\n this.t = t;\n this.locale = locale;\n\n // Root container\n this.element = el(\"div\", { class: \"sp-detail\" });\n this.element.setAttribute(\"role\", \"dialog\");\n this.element.setAttribute(\"aria-label\", \"Feedback detail\");\n this.element.setAttribute(\"aria-hidden\", \"true\");\n\n // Header (built once, title/badge updated on show())\n const header = el(\"div\", { class: \"sp-detail-header\" });\n\n const backBtn = document.createElement(\"button\");\n backBtn.type = \"button\";\n backBtn.className = \"sp-detail-back\";\n backBtn.setAttribute(\"aria-label\", this.t(\"detail.back\"));\n backBtn.appendChild(parseSvg(ICON_ARROW_LEFT));\n backBtn.addEventListener(\"click\", () => {\n this.hide();\n this.callbacks.onBack();\n });\n\n this.element.appendChild(header);\n header.appendChild(backBtn);\n\n // Title and badge are appended in show()\n\n // Scrollable content area\n this.content = el(\"div\", { class: \"sp-detail-content\" });\n this.element.appendChild(this.content);\n }\n\n /** Show the detail view for a specific feedback. */\n show(feedback: FeedbackResponse, number: number): void {\n this.currentFeedback = feedback;\n this.isProcessing = false;\n\n // ---- Update header ----\n const header = this.element.querySelector<HTMLElement>(\".sp-detail-header\");\n if (!header) return;\n // Remove old title/badge but keep the back button\n const backBtn = header.querySelector<HTMLElement>(\".sp-detail-back\");\n if (!backBtn) return;\n header.replaceChildren(backBtn);\n\n const title = el(\"span\", { class: \"sp-detail-title\" });\n setText(title, this.t(\"detail.title\").replace(\"{number}\", String(number)));\n header.appendChild(title);\n\n const badge = el(\"span\", { class: \"sp-badge\" });\n badge.style.background = getTypeBgColor(feedback.type, this.colors);\n badge.style.color = getTypeColor(feedback.type, this.colors);\n setText(badge, feedback.type);\n header.appendChild(badge);\n\n // ---- Build content sections ----\n this.content.replaceChildren();\n\n let sectionIndex = 0;\n\n // Section 1: Status + Actions\n const statusSection = this.buildSection(sectionIndex++);\n this.buildStatusActions(statusSection, feedback);\n this.content.appendChild(statusSection);\n\n // Section 2: Message\n const messageSection = this.buildSection(sectionIndex++);\n const messageSectionTitle = el(\"div\", { class: \"sp-detail-section-title\" });\n setText(messageSectionTitle, this.t(\"detail.message\"));\n messageSection.appendChild(messageSectionTitle);\n\n const messageBlock = el(\"div\", { class: \"sp-detail-message\" });\n messageBlock.style.borderLeftColor = getTypeColor(feedback.type, this.colors);\n setText(messageBlock, feedback.message);\n messageSection.appendChild(messageBlock);\n this.content.appendChild(messageSection);\n\n // Section 2b: Screenshot (when captured)\n if (feedback.screenshotUrl && isSafeImageUrl(feedback.screenshotUrl)) {\n const screenshotSection = this.buildSection(sectionIndex++);\n const screenshotSectionTitle = el(\"div\", { class: \"sp-detail-section-title\" });\n setText(screenshotSectionTitle, this.t(\"detail.screenshot\"));\n screenshotSection.appendChild(screenshotSectionTitle);\n\n const img = document.createElement(\"img\");\n img.className = \"sp-detail-screenshot\";\n img.src = feedback.screenshotUrl;\n img.alt = this.t(\"detail.screenshotAlt\");\n img.loading = \"lazy\";\n // Avoid leaking the panel viewer's referrer to the storage host —\n // a malicious or compromised storage URL could otherwise track which\n // operators view which feedbacks.\n img.referrerPolicy = \"no-referrer\";\n screenshotSection.appendChild(img);\n this.content.appendChild(screenshotSection);\n }\n\n // Section 3: Metadata\n const metaSection = this.buildSection(sectionIndex++);\n const metaSectionTitle = el(\"div\", { class: \"sp-detail-section-title\" });\n setText(metaSectionTitle, this.t(\"detail.metadata\"));\n metaSection.appendChild(metaSectionTitle);\n this.buildMetadata(metaSection, feedback);\n this.content.appendChild(metaSection);\n\n // Section 4: Annotation (if any)\n if (feedback.annotations.length > 0) {\n const annSection = this.buildSection(sectionIndex++);\n const annSectionTitle = el(\"div\", { class: \"sp-detail-section-title\" });\n annSectionTitle.appendChild(parseSvg(ICON_MAP_PIN));\n const annTitleText = el(\"span\");\n setText(annTitleText, this.t(\"detail.annotation\"));\n annSectionTitle.appendChild(annTitleText);\n annSection.appendChild(annSectionTitle);\n this.buildAnnotation(annSection, feedback);\n this.content.appendChild(annSection);\n }\n\n // Section 5: Diagnostics (only when present + non-empty).\n // Skipped silently when the widget was launched without capture, so legacy\n // records (and hosts who never opt in) never see an empty pane.\n if (hasDiagnostics(feedback.diagnostics)) {\n const diagSection = this.buildSection(sectionIndex++);\n const diagSectionTitle = el(\"div\", { class: \"sp-detail-section-title\" });\n diagSectionTitle.appendChild(parseSvg(ICON_TERMINAL));\n const diagTitleText = el(\"span\");\n setText(diagTitleText, this.t(\"detail.diagnostics\"));\n diagSectionTitle.appendChild(diagTitleText);\n diagSection.appendChild(diagSectionTitle);\n this.buildDiagnostics(diagSection, feedback);\n this.content.appendChild(diagSection);\n }\n\n // ---- Show with animation ----\n this._isVisible = true;\n this.element.setAttribute(\"aria-hidden\", \"false\");\n\n // Force reflow before adding visible class to trigger CSS transition\n void this.element.offsetHeight;\n this.element.classList.add(\"sp-detail--visible\");\n\n // Focus the back button for keyboard users\n requestAnimationFrame(() => {\n backBtn.focus();\n });\n }\n\n /** Hide the detail view with slide-out animation. */\n hide(): void {\n if (!this._isVisible) return;\n this._isVisible = false;\n this.element.classList.remove(\"sp-detail--visible\");\n this.element.setAttribute(\"aria-hidden\", \"true\");\n this.currentFeedback = null;\n this.resolveBtn = null;\n this.deleteBtn = null;\n }\n\n /** Whether the detail view is currently visible. */\n get isVisible(): boolean {\n return this._isVisible;\n }\n\n /** Cleanup all references. */\n destroy(): void {\n this.hide();\n this.element.remove();\n }\n\n // -----------------------------------------------------------------------\n // Private — Section builders\n // -----------------------------------------------------------------------\n\n /** Create a section element with stagger delay. */\n private buildSection(index: number): HTMLElement {\n const section = el(\"div\", { class: \"sp-detail-section\" });\n section.style.animationDelay = `${index * 40}ms`;\n return section;\n }\n\n /** Build Status pill + Resolve/Delete action buttons. */\n private buildStatusActions(container: HTMLElement, feedback: FeedbackResponse): void {\n const isResolved = feedback.status === \"resolved\";\n\n // Section title\n const sectionTitle = el(\"div\", { class: \"sp-detail-section-title\" });\n setText(sectionTitle, this.t(\"detail.status\"));\n container.appendChild(sectionTitle);\n\n // Status pill\n const statusRow = el(\"div\", { class: \"sp-detail-status\" });\n const pill = el(\"span\", {\n class: `sp-detail-status-pill ${isResolved ? \"sp-detail-status-pill--resolved\" : \"sp-detail-status-pill--open\"}`,\n });\n const dot = el(\"span\", { class: \"sp-detail-status-dot\" });\n dot.style.background = isResolved ? \"#9ca3af\" : \"#22c55e\";\n pill.appendChild(dot);\n const pillLabel = el(\"span\");\n setText(pillLabel, isResolved ? this.t(\"detail.reopen\") : this.t(\"detail.resolve\"));\n // Actually label the pill with Open/Resolved\n setText(pillLabel, isResolved ? \"Resolved\" : \"Open\");\n pill.appendChild(pillLabel);\n statusRow.appendChild(pill);\n container.appendChild(statusRow);\n\n // Action buttons\n const actions = el(\"div\", { class: \"sp-detail-actions\" });\n\n // Resolve / Reopen\n this.resolveBtn = document.createElement(\"button\");\n this.resolveBtn.type = \"button\";\n if (isResolved) {\n this.resolveBtn.className = \"sp-detail-btn-reopen\";\n this.resolveBtn.appendChild(parseSvg(ICON_UNDO));\n const span = document.createElement(\"span\");\n setText(span, this.t(\"detail.reopen\"));\n this.resolveBtn.appendChild(span);\n } else {\n this.resolveBtn.className = \"sp-detail-btn-resolve\";\n this.resolveBtn.appendChild(parseSvg(ICON_CHECK));\n const span = document.createElement(\"span\");\n setText(span, this.t(\"detail.resolve\"));\n this.resolveBtn.appendChild(span);\n }\n this.resolveBtn.addEventListener(\"click\", () => this.handleResolve());\n\n // Delete\n this.deleteBtn = document.createElement(\"button\");\n this.deleteBtn.type = \"button\";\n this.deleteBtn.className = \"sp-detail-btn-delete\";\n this.deleteBtn.appendChild(parseSvg(ICON_TRASH));\n const deleteSpan = document.createElement(\"span\");\n setText(deleteSpan, this.t(\"detail.delete\"));\n this.deleteBtn.appendChild(deleteSpan);\n this.deleteBtn.addEventListener(\"click\", () => this.handleDelete());\n\n actions.appendChild(this.resolveBtn);\n actions.appendChild(this.deleteBtn);\n container.appendChild(actions);\n }\n\n /** Build the metadata grid. */\n private buildMetadata(container: HTMLElement, feedback: FeedbackResponse): void {\n const meta = el(\"div\", { class: \"sp-detail-meta\" });\n\n // Page\n this.addMetaRow(meta, ICON_LINK, this.t(\"detail.page\"), () => {\n const value = el(\"div\", { class: \"sp-detail-meta-value\" });\n const pathname = extractPathname(feedback.url);\n setText(value, truncate(pathname, 60));\n value.title = feedback.url;\n return value;\n });\n\n // Author\n this.addMetaRow(meta, ICON_USER, this.t(\"detail.author\"), () => {\n const value = el(\"div\", { class: \"sp-detail-meta-value\" });\n const name = feedback.authorName || \"Anonymous\";\n const email = feedback.authorEmail;\n setText(value, email ? `${name} (${email})` : name);\n return value;\n });\n\n // Date\n this.addMetaRow(meta, ICON_CALENDAR, this.t(\"detail.date\"), () => {\n const value = el(\"div\", { class: \"sp-detail-meta-value\" });\n setText(value, formatFullDate(feedback.createdAt, this.locale.startsWith(\"fr\") ? \"fr\" : \"en\"));\n return value;\n });\n\n // Viewport\n this.addMetaRow(meta, ICON_MONITOR, this.t(\"detail.viewport\"), () => {\n const value = el(\"div\", { class: \"sp-detail-meta-value sp-detail-meta-value--mono\" });\n setText(value, feedback.viewport || \"Unknown\");\n return value;\n });\n\n // Browser\n this.addMetaRow(\n meta,\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/></svg>`,\n this.t(\"detail.browser\"),\n () => {\n const value = el(\"div\", { class: \"sp-detail-meta-value\" });\n setText(value, parseBrowser(feedback.userAgent));\n return value;\n },\n );\n\n // Resolved at (only if resolved)\n if (feedback.resolvedAt) {\n const resolvedDate = feedback.resolvedAt;\n this.addMetaRow(meta, ICON_CHECK, this.t(\"detail.resolvedAt\"), () => {\n const value = el(\"div\", { class: \"sp-detail-meta-value sp-detail-meta-value--secondary\" });\n setText(value, formatFullDate(resolvedDate, this.locale.startsWith(\"fr\") ? \"fr\" : \"en\"));\n return value;\n });\n }\n\n container.appendChild(meta);\n }\n\n /** Add a single metadata row with icon, label, and custom value element. */\n private addMetaRow(container: HTMLElement, iconSvg: string, label: string, buildValue: () => HTMLElement): void {\n const row = el(\"div\", { class: \"sp-detail-meta-row\" });\n row.appendChild(parseSvg(iconSvg));\n\n const content = el(\"div\", { class: \"sp-detail-meta-content\" });\n const labelEl = el(\"div\", { class: \"sp-detail-meta-label\" });\n setText(labelEl, label);\n content.appendChild(labelEl);\n content.appendChild(buildValue());\n\n row.appendChild(content);\n container.appendChild(row);\n }\n\n /** Build the annotation detail section. */\n private buildAnnotation(container: HTMLElement, feedback: FeedbackResponse): void {\n const ann = feedback.annotations[0];\n if (!ann) return;\n\n const wrapper = el(\"div\", { class: \"sp-detail-annotation\" });\n\n // Info card\n const info = el(\"div\", { class: \"sp-detail-annotation-info\" });\n\n // Element tag\n this.addAnnotationRow(info, ICON_CODE, this.t(\"detail.element\"), () => {\n const value = el(\"span\", { class: \"sp-detail-annotation-value sp-detail-annotation-value--mono\" });\n const tagDisplay = ann.elementId ? `<${ann.elementTag}#${ann.elementId}>` : `<${ann.elementTag}>`;\n setText(value, tagDisplay);\n return value;\n });\n\n // CSS selector\n this.addAnnotationRow(info, ICON_CROSSHAIR, this.t(\"detail.selector\"), () => {\n const value = el(\"span\", { class: \"sp-detail-annotation-value sp-detail-annotation-value--mono\" });\n setText(value, truncate(ann.cssSelector, 60));\n value.title = ann.cssSelector;\n return value;\n });\n\n // Position\n this.addAnnotationRow(info, ICON_MAP_PIN, this.t(\"detail.position\"), () => {\n const value = el(\"span\", { class: \"sp-detail-annotation-value\" });\n setText(\n value,\n `${ann.xPct.toFixed(1)}%, ${ann.yPct.toFixed(1)}%` +\n (ann.wPct > 0 || ann.hPct > 0 ? ` (${ann.wPct.toFixed(1)}% \\u00d7 ${ann.hPct.toFixed(1)}%)` : \"\"),\n );\n return value;\n });\n\n wrapper.appendChild(info);\n\n // \"Go to annotation\" button\n const gotoBtn = document.createElement(\"button\");\n gotoBtn.type = \"button\";\n gotoBtn.className = \"sp-detail-btn-goto\";\n gotoBtn.appendChild(parseSvg(ICON_MAP_PIN));\n const gotoLabel = document.createElement(\"span\");\n setText(gotoLabel, this.t(\"detail.goToAnnotation\"));\n gotoBtn.appendChild(gotoLabel);\n gotoBtn.addEventListener(\"click\", () => {\n if (this.currentFeedback) {\n this.callbacks.onGoToAnnotation(this.currentFeedback);\n }\n });\n\n wrapper.appendChild(gotoBtn);\n container.appendChild(wrapper);\n }\n\n /**\n * Build the collapsible Diagnostics section.\n *\n * Toggle expand/collapse via a single button; the body is hidden by default\n * to keep the detail view compact. Console entries get a colour-coded level\n * pill, network entries get a status/method/url row truncated to fit.\n */\n private buildDiagnostics(container: HTMLElement, feedback: FeedbackResponse): void {\n const diag = feedback.diagnostics;\n if (!diag) return;\n\n const consoleEntries = Array.isArray(diag.console) ? diag.console : [];\n const networkEntries = Array.isArray(diag.network) ? diag.network : [];\n const errorCount = consoleEntries.filter((e) => e.level === \"error\").length;\n\n const wrapper = el(\"div\", { class: \"sp-detail-diag\" });\n\n const toggle = document.createElement(\"button\");\n toggle.type = \"button\";\n toggle.className = \"sp-detail-diag-toggle\";\n toggle.setAttribute(\"aria-expanded\", \"false\");\n toggle.setAttribute(\"aria-label\", this.t(\"detail.diagnostics.expand\"));\n const toggleLabel = document.createElement(\"span\");\n const leftRow = document.createElement(\"span\");\n leftRow.style.display = \"inline-flex\";\n leftRow.style.alignItems = \"center\";\n leftRow.style.gap = \"8px\";\n leftRow.appendChild(parseSvg(ICON_CHEVRON));\n setText(toggleLabel, this.t(\"detail.diagnostics\"));\n leftRow.appendChild(toggleLabel);\n toggle.appendChild(leftRow);\n\n const counts = el(\"span\", { class: \"sp-detail-diag-counts\" });\n const consoleCount = el(\"span\", {\n class: `sp-detail-diag-count${errorCount > 0 ? \" sp-detail-diag-count--errors\" : \"\"}`,\n });\n setText(consoleCount, `${consoleEntries.length} console`);\n const networkCount = el(\"span\", {\n class: `sp-detail-diag-count${networkEntries.length > 0 ? \" sp-detail-diag-count--errors\" : \"\"}`,\n });\n setText(networkCount, `${networkEntries.length} net`);\n counts.appendChild(consoleCount);\n counts.appendChild(networkCount);\n toggle.appendChild(counts);\n\n const body = el(\"div\", { class: \"sp-detail-diag-body\" });\n\n // ---- Console group ----\n if (consoleEntries.length > 0) {\n const group = document.createElement(\"div\");\n const title = el(\"div\", { class: \"sp-detail-diag-group-title\" });\n setText(title, this.t(\"detail.diagnostics.console\"));\n group.appendChild(title);\n\n const list = document.createElement(\"ul\");\n list.className = \"sp-detail-diag-list\";\n for (const entry of consoleEntries) {\n const item = document.createElement(\"li\");\n const level = el(\"span\", {\n class: `sp-detail-diag-level sp-detail-diag-level--${entry.level}`,\n });\n setText(level, entry.level);\n const msg = el(\"span\", { class: \"sp-detail-diag-message\" });\n // Cap the rendered message length to keep the list readable.\n setText(msg, truncate(entry.message, 240));\n msg.title = entry.message;\n item.appendChild(level);\n item.appendChild(msg);\n list.appendChild(item);\n }\n group.appendChild(list);\n body.appendChild(group);\n }\n\n // ---- Network group ----\n if (networkEntries.length > 0) {\n const group = document.createElement(\"div\");\n const title = el(\"div\", { class: \"sp-detail-diag-group-title\" });\n setText(title, this.t(\"detail.diagnostics.network\"));\n group.appendChild(title);\n\n const list = document.createElement(\"ul\");\n list.className = \"sp-detail-diag-list\";\n for (const entry of networkEntries) {\n const item = document.createElement(\"li\");\n item.classList.add(\"sp-detail-diag-net\");\n const status = el(\"span\", { class: \"sp-detail-diag-net-status\" });\n setText(status, entry.status === 0 ? \"ERR\" : String(entry.status));\n const method = el(\"span\", { class: \"sp-detail-diag-net-method\" });\n setText(method, entry.method);\n const url = el(\"span\", { class: \"sp-detail-diag-net-url\" });\n setText(url, truncate(entry.url, 120));\n url.title = `${entry.url} — ${formatDuration(entry.durationMs)}`;\n item.appendChild(status);\n item.appendChild(method);\n item.appendChild(url);\n list.appendChild(item);\n }\n group.appendChild(list);\n body.appendChild(group);\n }\n\n toggle.addEventListener(\"click\", () => {\n const expanded = toggle.getAttribute(\"aria-expanded\") === \"true\";\n const next = !expanded;\n toggle.setAttribute(\"aria-expanded\", String(next));\n toggle.setAttribute(\n \"aria-label\",\n next ? this.t(\"detail.diagnostics.collapse\") : this.t(\"detail.diagnostics.expand\"),\n );\n body.classList.toggle(\"sp-detail-diag-body--open\", next);\n });\n\n wrapper.appendChild(toggle);\n wrapper.appendChild(body);\n container.appendChild(wrapper);\n }\n\n /** Add a single annotation info row. */\n private addAnnotationRow(\n container: HTMLElement,\n iconSvg: string,\n label: string,\n buildValue: () => HTMLElement,\n ): void {\n const row = el(\"div\", { class: \"sp-detail-annotation-row\" });\n row.appendChild(parseSvg(iconSvg));\n\n const content = el(\"div\", { class: \"sp-detail-meta-content\" });\n const labelEl = el(\"div\", { class: \"sp-detail-annotation-label\" });\n setText(labelEl, label);\n content.appendChild(labelEl);\n content.appendChild(buildValue());\n\n row.appendChild(content);\n container.appendChild(row);\n }\n\n // -----------------------------------------------------------------------\n // Private — Action handlers\n // -----------------------------------------------------------------------\n\n private async handleResolve(): Promise<void> {\n if (this.isProcessing || !this.currentFeedback) return;\n this.isProcessing = true;\n\n if (this.resolveBtn) this.setButtonLoading(this.resolveBtn);\n if (this.deleteBtn) this.deleteBtn.disabled = true;\n\n try {\n await this.callbacks.onResolve(this.currentFeedback);\n // The parent will call hide() or re-show with updated data\n } catch {\n // Restore buttons on error\n this.isProcessing = false;\n if (this.resolveBtn) this.restoreResolveBtn(this.currentFeedback);\n if (this.deleteBtn) this.deleteBtn.disabled = false;\n }\n }\n\n private async handleDelete(): Promise<void> {\n if (this.isProcessing || !this.currentFeedback) return;\n this.isProcessing = true;\n\n if (this.deleteBtn) this.setButtonLoading(this.deleteBtn);\n if (this.resolveBtn) this.resolveBtn.disabled = true;\n\n try {\n await this.callbacks.onDelete(this.currentFeedback);\n // The parent will call hide() after deletion\n } catch {\n this.isProcessing = false;\n if (this.deleteBtn) this.restoreDeleteBtn();\n if (this.resolveBtn) this.resolveBtn.disabled = false;\n }\n }\n\n private setButtonLoading(btn: HTMLButtonElement): void {\n btn.disabled = true;\n btn.replaceChildren(el(\"div\", { class: \"sp-spinner sp-spinner--sm\" }));\n }\n\n private restoreResolveBtn(feedback: FeedbackResponse): void {\n if (!this.resolveBtn) return;\n this.resolveBtn.disabled = false;\n this.resolveBtn.replaceChildren();\n\n const isResolved = feedback.status === \"resolved\";\n this.resolveBtn.appendChild(parseSvg(isResolved ? ICON_UNDO : ICON_CHECK));\n const span = document.createElement(\"span\");\n setText(span, isResolved ? this.t(\"detail.reopen\") : this.t(\"detail.resolve\"));\n this.resolveBtn.appendChild(span);\n }\n\n private restoreDeleteBtn(): void {\n if (!this.deleteBtn) return;\n this.deleteBtn.disabled = false;\n this.deleteBtn.replaceChildren();\n this.deleteBtn.appendChild(parseSvg(ICON_TRASH));\n const span = document.createElement(\"span\");\n setText(span, this.t(\"detail.delete\"));\n this.deleteBtn.appendChild(span);\n }\n}\n","/**\n * Sort and group-by-page controls for the feedback panel.\n *\n * Provides:\n * - Sort dropdown (newest, oldest, by-type, open-first)\n * - Group by page toggle (collapsible URL sections)\n * - Pure sort/group utility functions\n *\n * Glassmorphism design — glass surfaces, accent gradients,\n * smooth micro-interactions.\n */\n\nimport type { FeedbackResponse, FeedbackType } from \"@siteping/core\";\nimport { el, parseSvg, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type SortMode = \"newest\" | \"oldest\" | \"by-type\" | \"open-first\";\n\n// ---------------------------------------------------------------------------\n// SVG Icons\n// ---------------------------------------------------------------------------\n\nexport const ICON_SORT = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M11 5h10\"/><path d=\"M11 9h7\"/><path d=\"M11 13h4\"/><path d=\"M3 17l3 3 3-3\"/><path d=\"M6 18V4\"/></svg>`;\n\nexport const ICON_PAGE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/><polyline points=\"10 9 9 9 8 9\"/></svg>`;\n\nexport const ICON_CHEVRON = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"9 18 15 12 9 6\"/></svg>`;\n\n// ---------------------------------------------------------------------------\n// Sort utilities\n// ---------------------------------------------------------------------------\n\n/** Type priority for \"by-type\" sort: question, change, bug, other */\nconst TYPE_ORDER: Record<FeedbackType, number> = {\n question: 0,\n change: 1,\n bug: 2,\n other: 3,\n};\n\n/** Sort feedbacks according to the given mode. Returns a new array. */\nexport function sortFeedbacks(feedbacks: FeedbackResponse[], mode: SortMode): FeedbackResponse[] {\n const sorted = [...feedbacks];\n\n switch (mode) {\n case \"newest\":\n sorted.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n break;\n\n case \"oldest\":\n sorted.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());\n break;\n\n case \"by-type\":\n sorted.sort((a, b) => {\n const typeA = TYPE_ORDER[a.type] ?? 99;\n const typeB = TYPE_ORDER[b.type] ?? 99;\n if (typeA !== typeB) return typeA - typeB;\n // Within same type: newest first\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n break;\n\n case \"open-first\":\n sorted.sort((a, b) => {\n // Open (0) before resolved (1)\n const statusA = a.status === \"open\" ? 0 : 1;\n const statusB = b.status === \"open\" ? 0 : 1;\n if (statusA !== statusB) return statusA - statusB;\n // Within same status: newest first\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n break;\n }\n\n return sorted;\n}\n\n// ---------------------------------------------------------------------------\n// Group by page\n// ---------------------------------------------------------------------------\n\n/**\n * Extract the pathname from a full URL string.\n * Falls back to the raw string if URL parsing fails.\n */\nfunction extractPathname(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return url;\n }\n}\n\n/** Truncate a path string, keeping the beginning and end visible. */\nfunction truncatePath(path: string, maxLength: number): string {\n if (path.length <= maxLength) return path;\n const ellipsis = \"\\u2026\";\n const keep = Math.floor((maxLength - 1) / 2);\n return path.slice(0, keep) + ellipsis + path.slice(-keep);\n}\n\n/**\n * Group feedbacks by URL pathname.\n * Returns a Map sorted by feedback count descending (most feedbacks first).\n * Each group's feedbacks maintain their original order.\n */\nexport function groupFeedbacksByPage(feedbacks: FeedbackResponse[]): Map<string, FeedbackResponse[]> {\n const groups = new Map<string, FeedbackResponse[]>();\n\n for (const fb of feedbacks) {\n const path = extractPathname(fb.url);\n const existing = groups.get(path);\n if (existing) {\n existing.push(fb);\n } else {\n groups.set(path, [fb]);\n }\n }\n\n // Sort by count descending\n const sorted = new Map([...groups.entries()].sort((a, b) => b[1].length - a[1].length));\n\n return sorted;\n}\n\n// ---------------------------------------------------------------------------\n// Page group header\n// ---------------------------------------------------------------------------\n\n/**\n * Create a collapsible page group header element.\n * Click toggles the associated `.sp-group-content` sibling.\n */\nexport function createPageGroupHeader(pagePath: string, count: number, colors: ThemeColors): HTMLElement {\n const header = el(\"div\", { class: \"sp-group-header\" });\n header.setAttribute(\"role\", \"button\");\n header.setAttribute(\"tabindex\", \"0\");\n header.setAttribute(\"aria-expanded\", \"true\");\n header.style.borderBottomColor = colors.border;\n\n // Chevron\n const chevronWrap = el(\"span\", { class: \"sp-group-header-chevron\" });\n chevronWrap.appendChild(parseSvg(ICON_CHEVRON));\n header.appendChild(chevronWrap);\n\n // Page icon\n const pageIcon = el(\"span\", { class: \"sp-group-header-icon\" });\n pageIcon.appendChild(parseSvg(ICON_PAGE));\n header.appendChild(pageIcon);\n\n // Path\n const pathEl = el(\"span\", { class: \"sp-group-header-path\" });\n const displayPath = truncatePath(pagePath, 40);\n setText(pathEl, displayPath);\n if (pagePath.length > 40) {\n pathEl.title = pagePath;\n }\n header.appendChild(pathEl);\n\n // Count badge\n const countEl = el(\"span\", { class: \"sp-group-header-count\" });\n countEl.style.background = colors.accentLight;\n countEl.style.color = colors.accent;\n setText(countEl, String(count));\n header.appendChild(countEl);\n\n // Toggle behavior\n const toggle = () => {\n const isExpanded = header.getAttribute(\"aria-expanded\") === \"true\";\n header.setAttribute(\"aria-expanded\", String(!isExpanded));\n header.classList.toggle(\"sp-group-header--collapsed\", isExpanded);\n\n const content = header.nextElementSibling;\n if (content?.classList.contains(\"sp-group-content\")) {\n content.classList.toggle(\"sp-group-content--collapsed\", isExpanded);\n }\n };\n\n header.addEventListener(\"click\", toggle);\n header.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggle();\n }\n });\n\n return header;\n}\n\n// ---------------------------------------------------------------------------\n// PanelSortControls\n// ---------------------------------------------------------------------------\n\nexport class PanelSortControls {\n readonly element: HTMLElement;\n\n private _sortMode: SortMode = \"newest\";\n private _groupByPage = false;\n private menuEl: HTMLElement | null = null;\n private sortBtn: HTMLButtonElement;\n private groupToggle: HTMLButtonElement;\n private readonly t: TFunction;\n private readonly colors: ThemeColors;\n private readonly onChange: () => void;\n private outsideClickHandler: ((e: MouseEvent) => void) | null = null;\n\n constructor(colors: ThemeColors, onChange: () => void, t: TFunction) {\n this.colors = colors;\n this.onChange = onChange;\n this.t = t;\n\n this.element = el(\"div\", { class: \"sp-sort-controls\" });\n\n // Sort button\n this.sortBtn = document.createElement(\"button\");\n this.sortBtn.className = \"sp-sort-btn\";\n this.sortBtn.setAttribute(\"aria-haspopup\", \"listbox\");\n this.sortBtn.setAttribute(\"aria-expanded\", \"false\");\n this.sortBtn.setAttribute(\"aria-label\", this.t(\"sort.label\"));\n\n const sortIcon = parseSvg(ICON_SORT);\n this.sortBtn.appendChild(sortIcon);\n\n const sortLabel = el(\"span\", { class: \"sp-sort-btn-label\" });\n setText(sortLabel, this.t(\"sort.newest\"));\n this.sortBtn.appendChild(sortLabel);\n\n this.sortBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleMenu();\n });\n\n // Group by page toggle\n this.groupToggle = document.createElement(\"button\");\n this.groupToggle.className = \"sp-group-toggle\";\n this.groupToggle.setAttribute(\"aria-pressed\", \"false\");\n\n const groupIcon = parseSvg(ICON_PAGE);\n this.groupToggle.appendChild(groupIcon);\n\n const groupLabel = el(\"span\", { class: \"sp-group-toggle-label\" });\n setText(groupLabel, this.t(\"group.byPage\"));\n this.groupToggle.appendChild(groupLabel);\n\n this.groupToggle.addEventListener(\"click\", () => {\n this._groupByPage = !this._groupByPage;\n this.groupToggle.classList.toggle(\"sp-group-toggle--active\", this._groupByPage);\n this.groupToggle.setAttribute(\"aria-pressed\", String(this._groupByPage));\n this.onChange();\n });\n\n this.element.appendChild(this.sortBtn);\n this.element.appendChild(this.groupToggle);\n }\n\n get sortMode(): SortMode {\n return this._sortMode;\n }\n\n get groupByPage(): boolean {\n return this._groupByPage;\n }\n\n private toggleMenu(): void {\n if (this.menuEl) {\n this.closeMenu();\n return;\n }\n this.openMenu();\n }\n\n private openMenu(): void {\n this.menuEl = el(\"div\", { class: \"sp-sort-menu\" });\n this.menuEl.setAttribute(\"role\", \"listbox\");\n this.menuEl.setAttribute(\"aria-label\", this.t(\"sort.label\"));\n this.sortBtn.setAttribute(\"aria-expanded\", \"true\");\n\n const options: { mode: SortMode; label: string }[] = [\n { mode: \"newest\", label: this.t(\"sort.newest\") },\n { mode: \"oldest\", label: this.t(\"sort.oldest\") },\n { mode: \"by-type\", label: this.t(\"sort.byType\") },\n { mode: \"open-first\", label: this.t(\"sort.openFirst\") },\n ];\n\n for (const opt of options) {\n const item = document.createElement(\"button\");\n item.className = `sp-sort-option${opt.mode === this._sortMode ? \" sp-sort-option--active\" : \"\"}`;\n item.setAttribute(\"role\", \"option\");\n item.setAttribute(\"aria-selected\", String(opt.mode === this._sortMode));\n\n if (opt.mode === this._sortMode) {\n item.style.background = this.colors.accentLight;\n item.style.color = this.colors.accent;\n }\n\n setText(item, opt.label);\n\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this._sortMode = opt.mode;\n this.updateSortLabel();\n this.closeMenu();\n this.onChange();\n });\n\n this.menuEl.appendChild(item);\n }\n\n // Position relative to button\n this.element.appendChild(this.menuEl);\n\n // Close on outside click (next tick to avoid the current click)\n requestAnimationFrame(() => {\n this.outsideClickHandler = (e: MouseEvent) => {\n if (this.menuEl && !this.element.contains(e.target as Node)) {\n this.closeMenu();\n }\n };\n document.addEventListener(\"click\", this.outsideClickHandler, true);\n });\n\n // Close on Escape\n this.menuEl.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Escape\") {\n this.closeMenu();\n this.sortBtn.focus();\n }\n });\n }\n\n private closeMenu(): void {\n if (this.menuEl) {\n this.menuEl.remove();\n this.menuEl = null;\n }\n this.sortBtn.setAttribute(\"aria-expanded\", \"false\");\n if (this.outsideClickHandler) {\n document.removeEventListener(\"click\", this.outsideClickHandler, true);\n this.outsideClickHandler = null;\n }\n }\n\n private updateSortLabel(): void {\n const labelMap: Record<SortMode, string> = {\n newest: this.t(\"sort.newest\"),\n oldest: this.t(\"sort.oldest\"),\n \"by-type\": this.t(\"sort.byType\"),\n \"open-first\": this.t(\"sort.openFirst\"),\n };\n const label = this.sortBtn.querySelector(\".sp-sort-btn-label\");\n if (label) setText(label as HTMLElement, labelMap[this._sortMode]);\n }\n\n destroy(): void {\n this.closeMenu();\n }\n}\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nexport const SORT_CSS = `\n /* ============================\n Sort Controls Container\n ============================ */\n\n .sp-sort-controls {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n padding-top: 8px;\n border-top: 1px solid var(--sp-border);\n }\n\n /* ============================\n Sort Dropdown Button\n ============================ */\n\n .sp-sort-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n transition: all 0.2s ease;\n position: relative;\n }\n\n .sp-sort-btn svg {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n }\n\n .sp-sort-btn:hover {\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n background: var(--sp-accent-light);\n }\n\n .sp-sort-btn[aria-expanded=\"true\"] {\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n background: var(--sp-accent-light);\n }\n\n /* ============================\n Sort Floating Menu\n ============================ */\n\n .sp-sort-menu {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n min-width: 170px;\n padding: 4px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-md);\n z-index: 10;\n animation: sp-sort-menu-in 0.15s ease-out both;\n }\n\n @keyframes sp-sort-menu-in {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.97);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n /* ============================\n Sort Menu Option\n ============================ */\n\n .sp-sort-option {\n display: block;\n width: 100%;\n padding: 8px 12px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n }\n\n .sp-sort-option:hover {\n background: var(--sp-bg-hover);\n color: var(--sp-text);\n }\n\n .sp-sort-option--active {\n font-weight: 600;\n }\n\n .sp-sort-option--active:hover {\n background: var(--sp-accent-light);\n color: var(--sp-accent);\n }\n\n /* ============================\n Group by Page Toggle\n ============================ */\n\n .sp-group-toggle {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n transition: all 0.2s ease;\n }\n\n .sp-group-toggle svg {\n width: 13px;\n height: 13px;\n flex-shrink: 0;\n }\n\n .sp-group-toggle:hover {\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n background: var(--sp-accent-light);\n }\n\n .sp-group-toggle--active {\n background: var(--sp-accent-gradient);\n border-color: transparent;\n color: #fff;\n box-shadow: 0 2px 8px var(--sp-accent-glow);\n }\n\n .sp-group-toggle--active:hover {\n background: var(--sp-accent-gradient);\n border-color: transparent;\n color: #fff;\n }\n\n /* ============================\n Page Group Header\n ============================ */\n\n .sp-group-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--sp-accent-light);\n border-bottom: 1px solid var(--sp-border);\n cursor: pointer;\n user-select: none;\n position: sticky;\n top: 0;\n z-index: 2;\n transition: background 0.2s ease;\n }\n\n .sp-group-header:hover {\n background: var(--sp-bg-hover);\n }\n\n .sp-group-header:focus-visible {\n outline: 2px solid var(--sp-accent);\n outline-offset: -2px;\n }\n\n .sp-group-header-chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n transition: transform 0.2s ease;\n transform: rotate(90deg);\n }\n\n .sp-group-header-chevron svg {\n width: 12px;\n height: 12px;\n color: var(--sp-text-tertiary);\n }\n\n .sp-group-header--collapsed .sp-group-header-chevron {\n transform: rotate(0deg);\n }\n\n .sp-group-header-icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .sp-group-header-icon svg {\n width: 14px;\n height: 14px;\n color: var(--sp-text-tertiary);\n }\n\n .sp-group-header-path {\n font-size: 12px;\n font-weight: 600;\n color: var(--sp-text-secondary);\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .sp-group-header-count {\n font-size: 11px;\n font-weight: 700;\n padding: 1px 8px;\n border-radius: var(--sp-radius-full);\n flex-shrink: 0;\n font-variant-numeric: tabular-nums;\n }\n\n /* ============================\n Page Group Content\n ============================ */\n\n .sp-group-content {\n overflow: hidden;\n transition: max-height 0.25s ease, opacity 0.2s ease;\n max-height: 5000px;\n opacity: 1;\n }\n\n .sp-group-content--collapsed {\n max-height: 0;\n opacity: 0;\n pointer-events: none;\n }\n\n /* ============================\n Forced Colors / High Contrast\n ============================ */\n\n @media (forced-colors: active) {\n .sp-sort-btn,\n .sp-group-toggle,\n .sp-sort-option,\n .sp-group-header {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-sort-btn:focus-visible,\n .sp-group-toggle:focus-visible,\n .sp-sort-option:focus-visible,\n .sp-group-header:focus-visible {\n outline: 3px solid Highlight !important;\n }\n\n .sp-sort-menu {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n }\n }\n\n /* ============================\n Reduced Motion\n ============================ */\n\n @media (prefers-reduced-motion: reduce) {\n .sp-sort-menu {\n animation: none;\n }\n .sp-group-header-chevron {\n transition: none;\n }\n .sp-group-content {\n transition: none;\n }\n }\n`;\n","import type { FeedbackResponse } from \"@siteping/core\";\nimport { el, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nexport const STATS_CSS = /* css */ `\n .sp-stats-bar {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px 24px;\n border-bottom: 1px solid var(--sp-border);\n user-select: none;\n }\n\n .sp-stats-bar[hidden] {\n display: none;\n }\n\n .sp-stats-row {\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .sp-stats-item {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .sp-stats-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .sp-stats-value {\n font-size: 16px;\n font-weight: 600;\n line-height: 1;\n color: var(--sp-text);\n font-variant-numeric: tabular-nums;\n font-feature-settings: \"tnum\";\n transition: opacity 0.3s ease;\n }\n\n .sp-stats-label {\n font-size: 11px;\n line-height: 1;\n color: var(--sp-text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n .sp-stats-progress {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .sp-stats-progress-track {\n flex: 1;\n height: 4px;\n border-radius: 2px;\n background: var(--sp-border);\n overflow: hidden;\n }\n\n .sp-stats-progress-fill {\n height: 100%;\n border-radius: 2px;\n background: linear-gradient(90deg, var(--sp-accent), #22c55e);\n width: 0%;\n transition: width 0.5s ease;\n }\n\n .sp-stats-progress-label {\n font-size: 10px;\n line-height: 1;\n color: var(--sp-text-tertiary);\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n font-feature-settings: \"tnum\";\n min-width: 64px;\n text-align: right;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Compact statistics bar displayed between filters and the feedback list.\n * Shows open/resolved/bug counts and a resolved-percentage progress bar.\n */\nexport class PanelStats {\n readonly element: HTMLElement;\n\n private readonly valueOpen: HTMLElement;\n private readonly valueResolved: HTMLElement;\n private readonly valueBugs: HTMLElement;\n private readonly progressFill: HTMLElement;\n private readonly progressLabel: HTMLElement;\n private readonly t: TFunction;\n\n constructor(\n private readonly colors: ThemeColors,\n t: TFunction,\n ) {\n this.t = t;\n // Container\n this.element = el(\"div\", { class: \"sp-stats-bar\" });\n this.element.setAttribute(\"aria-label\", \"Feedback statistics\");\n this.element.hidden = true;\n\n // --- Stats row ---\n const row = el(\"div\", { class: \"sp-stats-row\" });\n\n // Open\n const itemOpen = el(\"div\", { class: \"sp-stats-item\" });\n const dotOpen = el(\"span\", { class: \"sp-stats-dot\" });\n dotOpen.style.background = \"#22c55e\";\n this.valueOpen = el(\"span\", { class: \"sp-stats-value\" });\n setText(this.valueOpen, \"0\");\n const labelOpen = el(\"span\", { class: \"sp-stats-label\" });\n setText(labelOpen, this.t(\"stats.open\"));\n itemOpen.appendChild(dotOpen);\n itemOpen.appendChild(this.valueOpen);\n itemOpen.appendChild(labelOpen);\n\n // Resolved\n const itemResolved = el(\"div\", { class: \"sp-stats-item\" });\n const dotResolved = el(\"span\", { class: \"sp-stats-dot\" });\n dotResolved.style.background = \"#9ca3af\";\n this.valueResolved = el(\"span\", { class: \"sp-stats-value\" });\n setText(this.valueResolved, \"0\");\n const labelResolved = el(\"span\", { class: \"sp-stats-label\" });\n setText(labelResolved, this.t(\"stats.resolved\"));\n itemResolved.appendChild(dotResolved);\n itemResolved.appendChild(this.valueResolved);\n itemResolved.appendChild(labelResolved);\n\n // Bugs\n const itemBugs = el(\"div\", { class: \"sp-stats-item\" });\n const dotBugs = el(\"span\", { class: \"sp-stats-dot\" });\n dotBugs.style.background = this.colors.typeBug;\n this.valueBugs = el(\"span\", { class: \"sp-stats-value\" });\n setText(this.valueBugs, \"0\");\n const labelBugs = el(\"span\", { class: \"sp-stats-label\" });\n setText(labelBugs, this.t(\"stats.bugs\"));\n itemBugs.appendChild(dotBugs);\n itemBugs.appendChild(this.valueBugs);\n itemBugs.appendChild(labelBugs);\n\n row.appendChild(itemOpen);\n row.appendChild(itemResolved);\n row.appendChild(itemBugs);\n\n // --- Progress bar ---\n const progress = el(\"div\", { class: \"sp-stats-progress\" });\n const track = el(\"div\", { class: \"sp-stats-progress-track\" });\n this.progressFill = el(\"div\", { class: \"sp-stats-progress-fill\" });\n track.appendChild(this.progressFill);\n this.progressLabel = el(\"span\", { class: \"sp-stats-progress-label\" });\n setText(this.progressLabel, \"\");\n progress.appendChild(track);\n progress.appendChild(this.progressLabel);\n\n this.element.appendChild(row);\n this.element.appendChild(progress);\n }\n\n /** Update stats from current feedbacks array + total count. */\n update(feedbacks: FeedbackResponse[], total: number): void {\n // Hide when there are no feedbacks at all\n if (total === 0) {\n this.element.hidden = true;\n return;\n }\n this.element.hidden = false;\n\n let openCount = 0;\n let resolvedCount = 0;\n let bugCount = 0;\n\n for (const fb of feedbacks) {\n if (fb.status === \"open\") openCount++;\n if (fb.status === \"resolved\") resolvedCount++;\n if (fb.type === \"bug\") bugCount++;\n }\n\n setText(this.valueOpen, String(openCount));\n setText(this.valueResolved, String(resolvedCount));\n setText(this.valueBugs, String(bugCount));\n\n // Percentage resolved (relative to visible feedbacks, not total)\n const visible = feedbacks.length;\n const pct = visible > 0 ? Math.round((resolvedCount / visible) * 100) : 0;\n\n // Animate fill width via rAF so the transition kicks in after the DOM update\n requestAnimationFrame(() => {\n this.progressFill.style.width = `${pct}%`;\n });\n\n const progressText = this.t(\"stats.progress\").replace(\"{percent}\", String(pct));\n setText(this.progressLabel, progressText);\n }\n}\n","/**\n * Keyboard shortcuts system for the feedback panel.\n *\n * Gmail/GitHub-style single-key shortcuts:\n * J/K — navigate cards, R — resolve, D — delete,\n * F or / — focus search, X — toggle select, ? — help overlay.\n *\n * Active only when the panel is open. Ignores keypresses inside\n * input/textarea elements. Uses a Map<string, handler> for O(1) lookup.\n */\n\nimport { el, parseSvg, setText } from \"./dom-utils.js\";\nimport type { TFunction, Translations } from \"./i18n/index.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\n// ---------------------------------------------------------------------------\n// Icon\n// ---------------------------------------------------------------------------\n\nexport const ICON_KEYBOARD = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\"/><path d=\"M6 8h.01\"/><path d=\"M10 8h.01\"/><path d=\"M14 8h.01\"/><path d=\"M18 8h.01\"/><path d=\"M6 12h.01\"/><path d=\"M18 12h.01\"/><path d=\"M8 16h8\"/></svg>`;\n\n// All translation keys are sourced from the central i18n dict via t().\ntype ShortcutsI18nKey = Extract<keyof Translations, `shortcuts.${string}`>;\n\n// ---------------------------------------------------------------------------\n// Callbacks\n// ---------------------------------------------------------------------------\n\nexport interface ShortcutCallbacks {\n onNavigate: (direction: \"up\" | \"down\") => void;\n onResolve: () => void;\n onDelete: () => void;\n onFocusSearch: () => void;\n onToggleSelect: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// Card focus helpers\n// ---------------------------------------------------------------------------\n\n/** Get the currently focused card index from the list container (-1 if none). */\nexport function getFocusedCardIndex(listContainer: HTMLElement): number {\n const cards = listContainer.querySelectorAll<HTMLElement>(\".sp-card\");\n for (let i = 0; i < cards.length; i++) {\n if (cards[i]?.classList.contains(\"sp-card--focused\")) return i;\n }\n return -1;\n}\n\n/** Focus a card by index in the list container. Clamps to valid range. */\nexport function focusCardByIndex(listContainer: HTMLElement, index: number): void {\n const cards = listContainer.querySelectorAll<HTMLElement>(\".sp-card\");\n if (cards.length === 0) return;\n\n // Remove previous focus\n for (const card of cards) {\n card.classList.remove(\"sp-card--focused\");\n }\n\n const clamped = Math.max(0, Math.min(index, cards.length - 1));\n const target = cards[clamped];\n if (!target) return;\n target.classList.add(\"sp-card--focused\");\n target.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\n target.focus({ preventScroll: true });\n}\n\n// ---------------------------------------------------------------------------\n// Shortcut definitions (used to build help grid)\n// ---------------------------------------------------------------------------\n\ninterface ShortcutDef {\n keys: string[];\n label: ShortcutsI18nKey;\n}\n\nconst SHORTCUT_DEFS: ShortcutDef[] = [\n { keys: [\"J\", \"K\"], label: \"shortcuts.navigate\" },\n { keys: [\"R\"], label: \"shortcuts.resolve\" },\n { keys: [\"D\"], label: \"shortcuts.delete\" },\n { keys: [\"F\", \"/\"], label: \"shortcuts.search\" },\n { keys: [\"X\"], label: \"shortcuts.select\" },\n { keys: [\"?\"], label: \"shortcuts.help\" },\n { keys: [\"Esc\"], label: \"shortcuts.close\" },\n];\n\n// ---------------------------------------------------------------------------\n// CSS\n// ---------------------------------------------------------------------------\n\nexport const SHORTCUTS_CSS = /* css */ `\n /* ---- Help overlay backdrop ---- */\n\n .sp-shortcuts-overlay {\n position: fixed;\n inset: 0;\n background: var(--sp-backdrop, rgba(15, 23, 42, 0.2));\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease;\n }\n\n .sp-shortcuts-overlay--visible {\n opacity: 1;\n pointer-events: auto;\n }\n\n /* ---- Glassmorphism card ---- */\n\n .sp-shortcuts-card {\n width: 380px;\n max-width: calc(100vw - 32px);\n padding: 24px 28px 20px;\n border-radius: 20px;\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xl);\n font-family: var(--sp-font);\n position: relative;\n transform: scale(0.92) translateY(8px);\n transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n .sp-shortcuts-overlay--visible .sp-shortcuts-card {\n transform: scale(1) translateY(0);\n }\n\n /* ---- Title row ---- */\n\n .sp-shortcuts-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 700;\n color: var(--sp-text);\n margin-bottom: 18px;\n }\n\n .sp-shortcuts-title svg {\n width: 18px;\n height: 18px;\n color: var(--sp-text-secondary);\n flex-shrink: 0;\n }\n\n /* ---- Close button ---- */\n\n .sp-shortcuts-close {\n position: absolute;\n top: 16px;\n right: 16px;\n width: 28px;\n height: 28px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--sp-text-tertiary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease, color 0.15s ease;\n }\n\n .sp-shortcuts-close:hover {\n background: var(--sp-bg-hover);\n color: var(--sp-text);\n }\n\n .sp-shortcuts-close svg {\n width: 14px;\n height: 14px;\n }\n\n /* ---- Two-column grid ---- */\n\n .sp-shortcuts-grid {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .sp-shortcuts-row {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .sp-shortcuts-keys {\n display: flex;\n align-items: center;\n gap: 4px;\n min-width: 80px;\n justify-content: flex-end;\n }\n\n .sp-shortcuts-separator {\n font-size: 11px;\n color: var(--sp-text-tertiary);\n user-select: none;\n }\n\n /* ---- Key badge (<kbd> styling) ---- */\n\n .sp-kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 28px;\n height: 26px;\n padding: 0 7px;\n border-radius: 6px;\n background: var(--sp-bg-hover);\n border: 1px solid var(--sp-border);\n box-shadow:\n inset 0 -1px 0 rgba(0, 0, 0, 0.08),\n 0 1px 2px rgba(0, 0, 0, 0.04);\n font-family: ui-monospace, \"SF Mono\", \"Cascadia Code\", \"Segoe UI Mono\", Menlo, monospace;\n font-size: 12px;\n font-weight: 600;\n color: var(--sp-text);\n text-align: center;\n line-height: 1;\n user-select: none;\n }\n\n /* ---- Description text ---- */\n\n .sp-shortcuts-desc {\n font-size: 13px;\n color: var(--sp-text-secondary);\n line-height: 1.3;\n }\n\n /* ---- Hint button (bottom-right of panel) ---- */\n\n .sp-shortcuts-hint {\n width: 24px;\n height: 24px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-bg-hover);\n color: var(--sp-text-tertiary);\n font-family: ui-monospace, \"SF Mono\", \"Cascadia Code\", \"Segoe UI Mono\", Menlo, monospace;\n font-size: 12px;\n font-weight: 700;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n position: absolute;\n bottom: 12px;\n right: 12px;\n }\n\n .sp-shortcuts-hint:hover {\n background: var(--sp-accent-light);\n color: var(--sp-accent);\n border-color: var(--sp-accent);\n }\n\n .sp-shortcuts-hint::after {\n content: attr(aria-label);\n position: absolute;\n bottom: calc(100% + 6px);\n right: 0;\n padding: 4px 8px;\n border-radius: 6px;\n background: var(--sp-glass-bg-heavy);\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-sm);\n font-family: var(--sp-font);\n font-size: 11px;\n font-weight: 500;\n color: var(--sp-text-secondary);\n white-space: nowrap;\n opacity: 0;\n pointer-events: none;\n transform: translateY(4px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n }\n\n .sp-shortcuts-hint:hover::after {\n opacity: 1;\n transform: translateY(0);\n }\n\n /* ---- Card focus highlight (navigation) ---- */\n\n .sp-card--focused {\n outline: 2px solid var(--sp-accent);\n outline-offset: -2px;\n border-radius: inherit;\n }\n\n /* ---- Reduced motion ---- */\n\n @media (prefers-reduced-motion: reduce) {\n .sp-shortcuts-overlay,\n .sp-shortcuts-card,\n .sp-shortcuts-close,\n .sp-shortcuts-hint,\n .sp-shortcuts-hint::after {\n transition-duration: 0.01ms !important;\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Close icon (small X) — reused from icons.ts pattern\n// ---------------------------------------------------------------------------\n\nconst ICON_CLOSE_SM = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\n\n// ---------------------------------------------------------------------------\n// KeyboardShortcuts\n// ---------------------------------------------------------------------------\n\nexport class KeyboardShortcuts {\n /** Help overlay element — append to shadow root. */\n readonly helpOverlay: HTMLElement;\n /** Small \"?\" hint button — append inside the panel. */\n readonly hintButton: HTMLButtonElement;\n\n private readonly keyMap: Map<string, () => void>;\n private readonly boundHandler: (e: KeyboardEvent) => void;\n private shadowRoot: ShadowRoot | HTMLElement | null = null;\n private enabled = false;\n private helpVisible = false;\n private destroyed = false;\n\n constructor(\n _colors: ThemeColors,\n callbacks: ShortcutCallbacks,\n private readonly t: TFunction,\n ) {\n // Build key map (O(1) dispatch)\n this.keyMap = new Map<string, () => void>([\n [\"j\", () => callbacks.onNavigate(\"down\")],\n [\"k\", () => callbacks.onNavigate(\"up\")],\n [\"r\", () => callbacks.onResolve()],\n [\"d\", () => callbacks.onDelete()],\n [\"f\", () => callbacks.onFocusSearch()],\n [\"/\", () => callbacks.onFocusSearch()],\n [\"x\", () => callbacks.onToggleSelect()],\n [\"?\", () => this.toggleHelp()],\n ]);\n\n // Build DOM\n this.helpOverlay = this.buildOverlay();\n this.hintButton = this.buildHintButton();\n\n // Bind handler once\n this.boundHandler = (e: KeyboardEvent) => this.handleKeydown(e);\n }\n\n // -------------------------------------------------------------------------\n // Public API\n // -------------------------------------------------------------------------\n\n /** Enable shortcuts. Provide the shadow root (or document) to attach the listener. */\n enable(root?: ShadowRoot | HTMLElement): void {\n if (this.destroyed || this.enabled) return;\n if (root) this.shadowRoot = root;\n const target = this.shadowRoot ?? document;\n target.addEventListener(\"keydown\", this.boundHandler as EventListener);\n this.enabled = true;\n }\n\n /** Disable shortcuts (call when panel closes). */\n disable(): void {\n if (!this.enabled) return;\n const target = this.shadowRoot ?? document;\n target.removeEventListener(\"keydown\", this.boundHandler as EventListener);\n this.enabled = false;\n // Also hide help if visible\n if (this.helpVisible) this.hideHelp();\n }\n\n /** Show/hide help overlay. */\n toggleHelp(): void {\n if (this.helpVisible) {\n this.hideHelp();\n } else {\n this.showHelp();\n }\n }\n\n /** Destroy and clean up all listeners. */\n destroy(): void {\n if (this.destroyed) return;\n this.disable();\n this.helpOverlay.remove();\n this.hintButton.remove();\n this.destroyed = true;\n }\n\n // -------------------------------------------------------------------------\n // Keyboard handler\n // -------------------------------------------------------------------------\n\n private handleKeydown(e: KeyboardEvent): void {\n // Escape closes help overlay only (panel close handled elsewhere)\n if (e.key === \"Escape\") {\n if (this.helpVisible) {\n e.preventDefault();\n e.stopPropagation();\n this.hideHelp();\n }\n return;\n }\n\n // If help overlay is open, block all other shortcuts\n if (this.helpVisible) return;\n\n // Ignore when focus is in an input, textarea, or contenteditable\n const active = e.composedPath()[0] as HTMLElement | undefined;\n if (active) {\n const tag = active.tagName?.toLowerCase();\n if (tag === \"input\" || tag === \"textarea\" || tag === \"select\") return;\n if (active.isContentEditable) return;\n }\n\n // Ignore modified keys (Ctrl, Alt, Meta) — except Shift for \"?\"\n if (e.ctrlKey || e.altKey || e.metaKey) return;\n\n const handler = this.keyMap.get(e.key);\n if (handler) {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }\n }\n\n // -------------------------------------------------------------------------\n // Help overlay visibility\n // -------------------------------------------------------------------------\n\n private showHelp(): void {\n this.helpVisible = true;\n this.helpOverlay.classList.add(\"sp-shortcuts-overlay--visible\");\n\n // Focus the close button for accessibility\n const closeBtn = this.helpOverlay.querySelector<HTMLButtonElement>(\".sp-shortcuts-close\");\n closeBtn?.focus();\n }\n\n private hideHelp(): void {\n this.helpVisible = false;\n this.helpOverlay.classList.remove(\"sp-shortcuts-overlay--visible\");\n }\n\n // -------------------------------------------------------------------------\n // DOM builders\n // -------------------------------------------------------------------------\n\n private buildOverlay(): HTMLElement {\n const overlay = el(\"div\", { class: \"sp-shortcuts-overlay\" });\n overlay.setAttribute(\"role\", \"dialog\");\n overlay.setAttribute(\"aria-modal\", \"true\");\n overlay.setAttribute(\"aria-label\", this.t(\"shortcuts.title\"));\n\n // Click backdrop to close\n overlay.addEventListener(\"click\", (e) => {\n if (e.target === overlay) this.hideHelp();\n });\n\n const card = el(\"div\", { class: \"sp-shortcuts-card\" });\n\n // Title\n const title = el(\"div\", { class: \"sp-shortcuts-title\" });\n title.appendChild(parseSvg(ICON_KEYBOARD));\n const titleText = el(\"span\");\n setText(titleText, this.t(\"shortcuts.title\"));\n title.appendChild(titleText);\n card.appendChild(title);\n\n // Close button\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"sp-shortcuts-close\";\n closeBtn.setAttribute(\"aria-label\", this.t(\"shortcuts.close\"));\n closeBtn.appendChild(parseSvg(ICON_CLOSE_SM));\n closeBtn.addEventListener(\"click\", () => this.hideHelp());\n card.appendChild(closeBtn);\n\n // Grid\n const grid = el(\"div\", { class: \"sp-shortcuts-grid\" });\n\n for (const def of SHORTCUT_DEFS) {\n const row = el(\"div\", { class: \"sp-shortcuts-row\" });\n\n const keysWrap = el(\"div\", { class: \"sp-shortcuts-keys\" });\n def.keys.forEach((key, i) => {\n if (i > 0) {\n const sep = el(\"span\", { class: \"sp-shortcuts-separator\" });\n setText(sep, \"/\");\n keysWrap.appendChild(sep);\n }\n const kbd = el(\"span\", { class: \"sp-kbd\" });\n setText(kbd, key);\n keysWrap.appendChild(kbd);\n });\n\n const desc = el(\"span\", { class: \"sp-shortcuts-desc\" });\n setText(desc, this.t(def.label));\n\n row.appendChild(keysWrap);\n row.appendChild(desc);\n grid.appendChild(row);\n }\n\n card.appendChild(grid);\n overlay.appendChild(card);\n\n return overlay;\n }\n\n private buildHintButton(): HTMLButtonElement {\n const btn = document.createElement(\"button\");\n btn.className = \"sp-shortcuts-hint\";\n btn.setAttribute(\"aria-label\", this.t(\"shortcuts.hint\"));\n setText(btn, \"?\");\n btn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleHelp();\n });\n return btn;\n }\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e={"panel.title":"Feedbacks","panel.ariaLabel":"Siteping-Feedback-Panel","panel.feedbackList":"Feedbackliste","panel.loading":"Feedbacks werden geladen","panel.close":"Panel schlie\xDFen","panel.deleteAll":"Alle l\xF6schen","panel.deleteAllConfirmTitle":"Alle l\xF6schen","panel.deleteAllConfirmMessage":"Alle Feedbacks f\xFCr dieses Projekt l\xF6schen? Diese Aktion kann nicht r\xFCckg\xE4ngig gemacht werden.","panel.search":"Suchen...","panel.searchAria":"Feedbacks suchen","panel.filterAll":"Alle","panel.loadError":"Laden fehlgeschlagen","panel.retry":"Erneut versuchen","panel.empty":"Noch kein Feedback","panel.showMore":"Mehr anzeigen","panel.showLess":"Weniger anzeigen","panel.resolve":"Erledigen","panel.reopen":"Wieder \xF6ffnen","panel.delete":"L\xF6schen","panel.cancel":"Abbrechen","panel.confirmDelete":"L\xF6schen","panel.loadMore":"Mehr laden ({remaining} verbleibend)","panel.statusAll":"Alle","panel.statusOpen":"Offen","panel.statusResolved":"Erledigt","type.label":"Typ","type.question":"Frage","type.change":"\xC4nderung","type.bug":"Fehler","type.other":"Sonstiges","status.label":"Status","scope.label":"Bereich","scope.thisPage":"Diese Seite","scope.thisType":"Dieser Typ","scope.all":"Alle Seiten","fab.aria":"Siteping \u2014 Feedback-Men\xFC","fab.messages":"Nachrichten","fab.annotate":"Kommentieren","fab.annotations":"Anmerkungen","annotator.instruction":"Zeichne ein Rechteck um den Bereich, den du kommentieren m\xF6chtest","annotator.cancel":"Abbrechen","popup.ariaLabel":"Feedbackformular","popup.placeholder":"Beschreibe dein Feedback...","popup.textareaAria":"Feedbacknachricht","popup.submitHintMac":"\u2318+Enter zum Senden","popup.submitHintOther":"Strg+Enter zum Senden","popup.cancel":"Abbrechen","popup.submit":"Senden","identity.title":"Identifiziere dich","identity.nameLabel":"Name","identity.namePlaceholder":"Dein Name","identity.emailLabel":"E-Mail","identity.emailPlaceholder":"deine@email.de","identity.cancel":"Abbrechen","identity.submit":"Fortfahren","marker.approximate":"Ungef\xE4hre Position (Konfidenz: {confidence}%)","marker.aria":"Feedback #{number}: {type} \u2014 {message}","marker.count":"{count} Feedback-Markierungen angezeigt","fab.badge":"{count} unerledigte Feedbacks","feedback.sent.confirmation":"Feedback erfolgreich gesendet","feedback.error.message":"Feedback konnte nicht gesendet werden","feedback.deleted.confirmation":"Feedback gel\xF6scht","badge.count":"{count} unerledigte Feedbacks","bulk.selectAll":"Alle ausw\xE4hlen","bulk.selected":"{count} ausgew\xE4hlt","bulk.resolve":"Erledigen","bulk.delete":"L\xF6schen","bulk.deselect":"Abw\xE4hlen","sort.newest":"Neueste zuerst","sort.oldest":"\xC4lteste zuerst","sort.byType":"Nach Typ","sort.openFirst":"Offene zuerst","sort.label":"Sortieren","group.byPage":"Nach Seite","group.feedbacks":"{count} Feedbacks","stats.open":"Offen","stats.resolved":"Erledigt","stats.bugs":"Fehler","stats.progress":"{percent}% erledigt","detail.back":"Zur\xFCck","detail.title":"Feedback #{number}","detail.status":"Status","detail.message":"Nachricht","detail.screenshot":"Screenshot","detail.screenshotAlt":"Screenshot des markierten Bereichs","detail.metadata":"Details","detail.annotation":"Anmerkung","detail.page":"Seite","detail.author":"Autor","detail.date":"Erstellt","detail.viewport":"Viewport","detail.browser":"Browser","detail.resolvedAt":"Erledigt am","detail.goToAnnotation":"Zur Anmerkung","detail.element":"Element","detail.selector":"Selektor","detail.position":"Position","detail.resolve":"Erledigen","detail.reopen":"Wieder \xF6ffnen","detail.delete":"L\xF6schen","detail.diagnostics":"Diagnose","detail.diagnostics.console":"Konsole","detail.diagnostics.network":"Fehlgeschlagenes Netzwerk","detail.diagnostics.expand":"Diagnose anzeigen","detail.diagnostics.collapse":"Diagnose ausblenden","detail.diagnostics.noEntries":"Keine Eintr\xE4ge","shortcuts.title":"Tastenk\xFCrzel","shortcuts.navigate":"Feedbacks navigieren","shortcuts.resolve":"Erledigen / Wieder \xF6ffnen","shortcuts.delete":"L\xF6schen","shortcuts.search":"Suche fokussieren","shortcuts.select":"Auswahl umschalten","shortcuts.help":"K\xFCrzel anzeigen","shortcuts.close":"Schlie\xDFen","shortcuts.hint":"Tastenk\xFCrzel","export.label":"Exportieren","export.csv":"CSV exportieren","export.json":"JSON exportieren"};export{e as de};//# sourceMappingURL=de-32TXJQIE.js.map
|
|
2
|
+
//# sourceMappingURL=de-32TXJQIE.js.map
|