hotsheet 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,13 +63,19 @@ The loop stays tight because the AI always knows what to work on next.
63
63
  <img src="docs/demo-3.png" alt="Sidebar filtering by Bug category" width="900">
64
64
  </p>
65
65
 
66
- **Batch operations** — select multiple tickets to bulk-update category, priority, status, or Up Next.
66
+ **Column view** — switch to a kanban-style board grouped by status. Drag tickets between columns to change status, or drag onto sidebar items to set category, priority, or view.
67
+
68
+ <p align="center">
69
+ <img src="docs/demo-7.png" alt="Column view showing tickets organized by status in a kanban board" width="900">
70
+ </p>
71
+
72
+ **Batch operations** — select multiple tickets to bulk-update category, priority, status, or Up Next. Multi-select works in both list and column views.
67
73
 
68
74
  <p align="center">
69
75
  <img src="docs/demo-5.png" alt="Multiple tickets selected with the batch toolbar visible" width="900">
70
76
  </p>
71
77
 
72
- **Detail panel** — side or bottom orientation, resizable, with fields for title, details, attachments, and timestamped notes. Auto-shows when you select a ticket.
78
+ **Detail panel** — side or bottom orientation (toggle in the toolbar), resizable, with fields for title, details, attachments, and timestamped notes. Auto-shows when you select a ticket.
73
79
 
74
80
  <p align="center">
75
81
  <img src="docs/demo-6.png" alt="Detail panel in bottom orientation showing ticket details and notes" width="900">
@@ -78,12 +84,13 @@ The loop stays tight because the AI always knows what to work on next.
78
84
  **Also includes:**
79
85
  - **Five priority levels** — Highest to Lowest, sortable and filterable
80
86
  - **Up Next flag** — star tickets to add them to the AI worklist
87
+ - **Drag and drop** — drag tickets onto sidebar views to change category, priority, or status
81
88
  - **Search** — full-text search across ticket titles and details
82
- - **Keyboard-driven** — `Enter` to create, `Cmd+I/B/F/R/K/G` for categories, `Alt+1-5` for priority, `Cmd+D` for Up Next
89
+ - **Keyboard-driven** — `Enter` to create, `Cmd+I/B/F/R/K/G` for categories, `Alt+1-5` for priority, `Cmd+D` for Up Next, `Cmd+C` to copy
90
+ - **Copy for commits** — `Cmd+C` copies selected ticket info (number + title) for use in commit messages
83
91
  - **File attachments** — attach files to any ticket
84
92
  - **Markdown sync** — `worklist.md` and `open-tickets.md` auto-generated on every change
85
93
  - **Auto-cleanup** — configurable auto-deletion of old trash and verified items
86
- - **Settings** — detail panel position, cleanup intervals, all persisted
87
94
  - **Fully local** — embedded PostgreSQL (PGLite), no network calls, no accounts, no telemetry
88
95
 
89
96
  ---
@@ -189,6 +196,7 @@ hotsheet --data-dir ~/projects/my-app/.hotsheet
189
196
  | `Cmd+G` | Set category: Investigation |
190
197
  | `Alt+1-5` | Set priority (Highest to Lowest) |
191
198
  | `Cmd+D` | Toggle Up Next |
199
+ | `Cmd+C` | Copy ticket info (number + title) |
192
200
  | `Cmd+A` | Select all |
193
201
  | `Escape` | Clear selection / close |
194
202
 
package/dist/cli.js CHANGED
@@ -271,6 +271,8 @@ async function getTickets(filters = {}) {
271
271
  let paramIdx = 1;
272
272
  if (filters.status === "open") {
273
273
  conditions.push(`status != 'deleted' AND status != 'completed' AND status != 'verified'`);
274
+ } else if (filters.status === "non_verified") {
275
+ conditions.push(`status != 'deleted' AND status != 'verified'`);
274
276
  } else if (filters.status) {
275
277
  conditions.push(`status = $${paramIdx}`);
276
278
  values.push(filters.status);
@@ -481,7 +483,8 @@ var DEMO_SCENARIOS = [
481
483
  { id: 3, label: "Sidebar filtering \u2014 category view" },
482
484
  { id: 4, label: "AI worklist \u2014 Up Next tickets with notes" },
483
485
  { id: 5, label: "Batch operations \u2014 multi-select toolbar" },
484
- { id: 6, label: "Detail panel \u2014 bottom orientation with notes" }
486
+ { id: 6, label: "Detail panel \u2014 bottom orientation with notes" },
487
+ { id: 7, label: "Column view \u2014 kanban board by status" }
485
488
  ];
486
489
  function daysAgo(days) {
487
490
  const d = /* @__PURE__ */ new Date();
@@ -1087,13 +1090,129 @@ var SCENARIO_6 = [
1087
1090
  updated_ago: 8
1088
1091
  }
1089
1092
  ];
1093
+ var SCENARIO_7 = [
1094
+ {
1095
+ title: "Implement product search autocomplete",
1096
+ details: "Add typeahead suggestions to the search bar using the product name index. Show top 5 matches with thumbnails.",
1097
+ category: "feature",
1098
+ priority: "highest",
1099
+ status: "not_started",
1100
+ up_next: true,
1101
+ notes: "",
1102
+ days_ago: 2,
1103
+ updated_ago: 2
1104
+ },
1105
+ {
1106
+ title: "Fix broken password reset flow for SSO users",
1107
+ details: "SSO users who try to reset their password get a generic error. Should redirect them to their identity provider instead.",
1108
+ category: "bug",
1109
+ priority: "high",
1110
+ status: "not_started",
1111
+ up_next: true,
1112
+ notes: "",
1113
+ days_ago: 3,
1114
+ updated_ago: 3
1115
+ },
1116
+ {
1117
+ title: "Add support for gift cards at checkout",
1118
+ details: "Customers should be able to apply gift card codes during checkout. Support partial redemption and balance tracking.",
1119
+ category: "feature",
1120
+ priority: "default",
1121
+ status: "not_started",
1122
+ up_next: false,
1123
+ notes: "",
1124
+ days_ago: 5,
1125
+ updated_ago: 5
1126
+ },
1127
+ {
1128
+ title: "Investigate slow query on order history page",
1129
+ details: "The order history page takes 4+ seconds for users with 200+ orders. Profile the query and add proper indexing.",
1130
+ category: "investigation",
1131
+ priority: "high",
1132
+ status: "not_started",
1133
+ up_next: false,
1134
+ notes: "",
1135
+ days_ago: 4,
1136
+ updated_ago: 4
1137
+ },
1138
+ {
1139
+ title: "Refactor authentication middleware to support API keys",
1140
+ details: "Third-party integrations need API key auth in addition to session cookies. Extract auth into a strategy pattern.",
1141
+ category: "task",
1142
+ priority: "high",
1143
+ status: "started",
1144
+ up_next: true,
1145
+ notes: notesJson([{ text: "Created the AuthStrategy interface and migrated session auth to use it. Working on the API key strategy next.", days_ago: 0.5 }]),
1146
+ days_ago: 4,
1147
+ updated_ago: 0.5
1148
+ },
1149
+ {
1150
+ title: "Fix cart not clearing after successful checkout",
1151
+ details: "After a successful order placement, the cart retains all items. The clearCart() call is inside a catch block by mistake.",
1152
+ category: "bug",
1153
+ priority: "highest",
1154
+ status: "started",
1155
+ up_next: true,
1156
+ notes: notesJson([{ text: "Found the issue \u2014 clearCart() was moved into the catch block during a refactor. Fixing and adding a test.", days_ago: 0.3 }]),
1157
+ days_ago: 1,
1158
+ updated_ago: 0.3
1159
+ },
1160
+ {
1161
+ title: "Update shipping rate calculation for oversized items",
1162
+ details: "Dimensional weight pricing is required for packages over 1 cubic foot. Current flat-rate calculation undercharges.",
1163
+ category: "requirement_change",
1164
+ priority: "default",
1165
+ status: "started",
1166
+ up_next: false,
1167
+ notes: notesJson([{ text: "Implemented dim weight formula. Comparing rates against the carrier API to validate accuracy.", days_ago: 1 }]),
1168
+ days_ago: 6,
1169
+ updated_ago: 1
1170
+ },
1171
+ {
1172
+ title: "Add end-to-end tests for the checkout flow",
1173
+ details: "Write Playwright tests covering: add to cart, apply coupon, enter shipping, pay, and confirm. Cover happy path and key error cases.",
1174
+ category: "task",
1175
+ priority: "default",
1176
+ status: "completed",
1177
+ up_next: false,
1178
+ notes: notesJson([{ text: "Wrote 8 E2E tests covering the full checkout flow including coupon application and payment decline handling.", days_ago: 1 }]),
1179
+ days_ago: 8,
1180
+ updated_ago: 1,
1181
+ completed_ago: 1
1182
+ },
1183
+ {
1184
+ title: "Fix product image carousel swipe on mobile",
1185
+ details: "Swipe gestures on the product image carousel conflict with the browser back gesture. Use a swipe threshold to disambiguate.",
1186
+ category: "bug",
1187
+ priority: "default",
1188
+ status: "completed",
1189
+ up_next: false,
1190
+ notes: notesJson([{ text: "Added a 30px horizontal threshold before initiating carousel swipe. Tested on iOS Safari and Chrome Android.", days_ago: 2 }]),
1191
+ days_ago: 7,
1192
+ updated_ago: 2,
1193
+ completed_ago: 2
1194
+ },
1195
+ {
1196
+ title: "Set up log aggregation with structured JSON logging",
1197
+ details: "Replace console.log calls with a structured logger (pino). Send logs to a central aggregation service for search and alerting.",
1198
+ category: "task",
1199
+ priority: "low",
1200
+ status: "completed",
1201
+ up_next: false,
1202
+ notes: notesJson([{ text: "Replaced all console.log calls with pino. Configured log shipping to the aggregation service. Alert rules set for error-level logs.", days_ago: 3 }]),
1203
+ days_ago: 10,
1204
+ updated_ago: 3,
1205
+ completed_ago: 3
1206
+ }
1207
+ ];
1090
1208
  var SCENARIO_DATA = {
1091
1209
  1: SCENARIO_1,
1092
1210
  2: SCENARIO_2,
1093
1211
  3: SCENARIO_3,
1094
1212
  4: SCENARIO_4,
1095
1213
  5: SCENARIO_5,
1096
- 6: SCENARIO_6
1214
+ 6: SCENARIO_6,
1215
+ 7: SCENARIO_7
1097
1216
  };
1098
1217
  async function seedDemoData(scenario) {
1099
1218
  const db2 = await getDb();
@@ -1116,6 +1235,9 @@ async function seedDemoData(scenario) {
1116
1235
  await db2.query(`UPDATE settings SET value = 'bottom' WHERE key = 'detail_position'`);
1117
1236
  await db2.query(`UPDATE settings SET value = '280' WHERE key = 'detail_height'`);
1118
1237
  }
1238
+ if (scenario === 7) {
1239
+ await db2.query(`INSERT INTO settings (key, value) VALUES ('layout', 'columns') ON CONFLICT (key) DO UPDATE SET value = 'columns'`);
1240
+ }
1119
1241
  }
1120
1242
 
1121
1243
  // src/cli.ts
@@ -1235,15 +1357,19 @@ async function syncWorklist() {
1235
1357
  sections.push("");
1236
1358
  sections.push("## Workflow");
1237
1359
  sections.push("");
1238
- sections.push(`The Hot Sheet API is available at http://localhost:${port}/api. Use it to update ticket status as you work:`);
1360
+ sections.push(`The Hot Sheet API is available at http://localhost:${port}/api. **You MUST update ticket status** as you work \u2014 this is required, not optional.`);
1239
1361
  sections.push("");
1240
- sections.push('- **When you start working on a ticket**, set its status to "started":');
1241
- sections.push(` \`curl -X PATCH http://localhost:${port}/api/tickets/{id} -H "Content-Type: application/json" -d '{"status": "started"}'\``);
1362
+ sections.push('- **BEFORE starting work on a ticket**, set its status to "started":');
1363
+ sections.push(` \`curl -s -X PATCH http://localhost:${port}/api/tickets/{id} -H "Content-Type: application/json" -d '{"status": "started"}'\``);
1242
1364
  sections.push("");
1243
- sections.push('- **When you finish working on a ticket**, set its status to "completed" and add notes describing what was done:');
1244
- sections.push(` \`curl -X PATCH http://localhost:${port}/api/tickets/{id} -H "Content-Type: application/json" -d '{"status": "completed", "notes": "Description of work completed"}'\``);
1365
+ sections.push('- **AFTER completing work on a ticket**, set its status to "completed" and **include notes** describing what was done:');
1366
+ sections.push(` \`curl -s -X PATCH http://localhost:${port}/api/tickets/{id} -H "Content-Type: application/json" -d '{"status": "completed", "notes": "Describe the specific changes made"}'\``);
1245
1367
  sections.push("");
1246
- sections.push('Do NOT set tickets to "verified" \u2014 that status is reserved for human review.');
1368
+ sections.push("**IMPORTANT:**");
1369
+ sections.push('- Update status for EVERY ticket \u2014 "started" when you begin, "completed" when you finish.');
1370
+ sections.push('- The "notes" field is REQUIRED when completing a ticket. Describe the specific work done.');
1371
+ sections.push("- If an API call fails (e.g. connection refused, error response), log a visible warning to the user and continue your work. Do NOT silently skip status updates.");
1372
+ sections.push('- Do NOT set tickets to "verified" \u2014 that status is reserved for human review.');
1247
1373
  sections.push("");
1248
1374
  if (tickets.length === 0) {
1249
1375
  sections.push("No items in the Up Next list.");
@@ -1681,6 +1807,10 @@ pageRoutes.get("/", (c) => {
1681
1807
  /* @__PURE__ */ jsx("div", { className: "app-title", children: /* @__PURE__ */ jsx("h1", { children: "Hot Sheet" }) }),
1682
1808
  /* @__PURE__ */ jsx("div", { className: "header-controls", children: [
1683
1809
  /* @__PURE__ */ jsx("div", { className: "search-box", children: /* @__PURE__ */ jsx("input", { type: "text", id: "search-input", placeholder: "Search tickets..." }) }),
1810
+ /* @__PURE__ */ jsx("div", { className: "layout-toggle", id: "layout-toggle", children: [
1811
+ /* @__PURE__ */ jsx("button", { className: "layout-btn active", "data-layout": "list", title: "List view", children: raw('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>') }),
1812
+ /* @__PURE__ */ jsx("button", { className: "layout-btn", "data-layout": "columns", title: "Column view", children: raw('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="3" y="3" width="5" height="18" rx="1"/><rect x="10" y="3" width="5" height="18" rx="1"/><rect x="17" y="3" width="5" height="18" rx="1"/></svg>') })
1813
+ ] }),
1684
1814
  /* @__PURE__ */ jsx("div", { className: "sort-controls", children: /* @__PURE__ */ jsx("select", { id: "sort-select", children: [
1685
1815
  /* @__PURE__ */ jsx("option", { value: "created:desc", children: "Newest First" }),
1686
1816
  /* @__PURE__ */ jsx("option", { value: "created:asc", children: "Oldest First" }),
@@ -1688,6 +1818,10 @@ pageRoutes.get("/", (c) => {
1688
1818
  /* @__PURE__ */ jsx("option", { value: "category:asc", children: "Category" }),
1689
1819
  /* @__PURE__ */ jsx("option", { value: "status:asc", children: "Status" })
1690
1820
  ] }) }),
1821
+ /* @__PURE__ */ jsx("div", { className: "layout-toggle", id: "detail-position-toggle", children: [
1822
+ /* @__PURE__ */ jsx("button", { className: "layout-btn active", "data-position": "side", title: "Detail panel on side", children: raw('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="15" y1="3" x2="15" y2="21"/></svg>') }),
1823
+ /* @__PURE__ */ jsx("button", { className: "layout-btn", "data-position": "bottom", title: "Detail panel on bottom", children: raw('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="3" y1="15" x2="21" y2="15"/></svg>') })
1824
+ ] }),
1691
1825
  /* @__PURE__ */ jsx("button", { className: "settings-btn", id: "settings-btn", title: "Settings", children: raw("&#9881;") })
1692
1826
  ] })
1693
1827
  ] }),
@@ -1700,6 +1834,7 @@ pageRoutes.get("/", (c) => {
1700
1834
  /* @__PURE__ */ jsx("div", { className: "sidebar-section", children: [
1701
1835
  /* @__PURE__ */ jsx("div", { className: "sidebar-label", children: "Views" }),
1702
1836
  /* @__PURE__ */ jsx("button", { className: "sidebar-item active", "data-view": "all", children: "All Tickets" }),
1837
+ /* @__PURE__ */ jsx("button", { className: "sidebar-item", "data-view": "non-verified", children: "Non-Verified" }),
1703
1838
  /* @__PURE__ */ jsx("button", { className: "sidebar-item", "data-view": "up-next", children: "Up Next" }),
1704
1839
  /* @__PURE__ */ jsx("button", { className: "sidebar-item", "data-view": "open", children: "Open" }),
1705
1840
  /* @__PURE__ */ jsx("button", { className: "sidebar-item", "data-view": "completed", children: "Completed" }),
@@ -1883,13 +2018,6 @@ pageRoutes.get("/", (c) => {
1883
2018
  /* @__PURE__ */ jsx("button", { className: "detail-close", id: "settings-close", children: raw("&times;") })
1884
2019
  ] }),
1885
2020
  /* @__PURE__ */ jsx("div", { className: "settings-body", children: [
1886
- /* @__PURE__ */ jsx("div", { className: "settings-field", children: [
1887
- /* @__PURE__ */ jsx("label", { children: "Detail Panel Position" }),
1888
- /* @__PURE__ */ jsx("select", { id: "settings-detail-position", children: [
1889
- /* @__PURE__ */ jsx("option", { value: "side", children: "Side" }),
1890
- /* @__PURE__ */ jsx("option", { value: "bottom", children: "Bottom" })
1891
- ] })
1892
- ] }),
1893
2021
  /* @__PURE__ */ jsx("div", { className: "settings-field", children: [
1894
2022
  /* @__PURE__ */ jsx("label", { children: "Auto-clear trash after (days)" }),
1895
2023
  /* @__PURE__ */ jsx("input", { type: "number", id: "settings-trash-days", min: "1", value: "3" })
@@ -1955,6 +2083,7 @@ async function startServer(port2, dataDir2) {
1955
2083
  `);
1956
2084
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
1957
2085
  exec(`${openCmd} ${url}`);
2086
+ return actualPort;
1958
2087
  }
1959
2088
 
1960
2089
  // src/update-check.ts
@@ -2164,13 +2293,13 @@ async function main() {
2164
2293
  if (demo !== null) {
2165
2294
  await seedDemoData(demo);
2166
2295
  }
2167
- initMarkdownSync(dataDir2, port2);
2168
- scheduleAllSync();
2169
2296
  if (demo === null) {
2170
2297
  await cleanupAttachments();
2171
2298
  }
2172
2299
  console.log(` Data directory: ${dataDir2}`);
2173
- await startServer(port2, dataDir2);
2300
+ const actualPort = await startServer(port2, dataDir2);
2301
+ initMarkdownSync(dataDir2, actualPort);
2302
+ scheduleAllSync();
2174
2303
  }
2175
2304
  main().catch((err) => {
2176
2305
  console.error(err);
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{var le=Object.defineProperty;var de=(e,t,i)=>t in e?le(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var j=(e,t,i)=>de(e,typeof t!="symbol"?t+"":t,i);function F(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function V(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var h=class{constructor(t){j(this,"__html");this.__html=t}toString(){return this.__html}};function k(e){return new h(e)}var ce=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function D(e){return e==null||typeof e=="boolean"?"":e instanceof h?e.__html:typeof e=="string"?F(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(D).join(""):""}function ue(e,t){if(t==null||t===!1)return"";if(t===!0)return` ${e}`;let i=e==="className"?"class":e==="htmlFor"?"for":e,s;return t instanceof h?s=t.__html:typeof t=="number"?s=String(t):typeof t=="string"?s=V(t):s="",` ${i}="${s}"`}function l(e,t){if(typeof e=="function")return e(t);let{children:i,...s}=t,a=Object.entries(s).map(([d,r])=>ue(d,r)).join("");if(ce.has(e))return new h(`<${e}${a}>`);let o=i!=null?D(i):"";return new h(`<${e}${a}>${o}</${e}>`)}function L({children:e}){return new h(e!=null?D(e):"")}function y(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function W(e){document.getElementById("network-error-popup")?.remove();let t=y(l("div",{id:"network-error-popup",className:"error-popup",children:l("div",{className:"error-popup-content",children:[l("strong",{children:"Connection Error"}),l("p",{children:e}),l("button",{children:k("Dismiss")})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function c(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(i){throw W("Unable to reach the server. It may have been stopped."),i}}async function G(e,t){try{let i=new FormData;return i.append("file",t),(await fetch("/api"+e,{method:"POST",body:i})).json()}catch(i){throw W("Unable to reach the server. It may have been stopped."),i}}var pe={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",sortBy:"created",sortDir:"desc",search:"",settings:{...pe}},me={issue:"#6b7280",bug:"#ef4444",feature:"#22c55e",requirement_change:"#f97316",task:"#3b82f6",investigation:"#8b5cf6"},fe={issue:"ISS",bug:"BUG",feature:"FEA",requirement_change:"REQ",task:"TSK",investigation:"INV"},ye={highest:"\u2B06\u2B06",high:"\u2B06",default:"\u2014",low:"\u2B07",lowest:"\u2B07\u2B07"},ge={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},he={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:"svg"},Y='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-9.5 9.5-2-2"/></svg>';function b(e){return me[e]||"#6b7280"}function S(e){return fe[e]||"ISS"}function J(e){return ye[e]||"\u2014"}function A(e){return ge[e]||"#6b7280"}function X(e){return he[e]||"\u25CB"}function x(e){n.activeTicketId=e,ee(e)}function Q(){n.selectedIds.clear(),n.activeTicketId=null;let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function Z(){let e=n.view==="trash",t=document.getElementById("detail-panel"),i=document.getElementById("detail-resize-handle");if(n.selectedIds.size===1&&!e){let s=Array.from(n.selectedIds)[0];t.style.display="flex",i&&(i.style.display=""),n.activeTicketId!==s&&(n.activeTicketId=s,ee(s))}else n.activeTicketId!=null&&(n.activeTicketId=null),t.style.display="none",i&&(i.style.display="none")}async function ee(e){let t=await c(`/tickets/${e}`);if(n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details;let i=document.getElementById("detail-attachments");t.attachments.length>0?i.innerHTML=l(L,{children:t.attachments.map(r=>l("div",{className:"attachment-item",children:[l("span",{className:"attachment-name",children:r.original_filename}),l("button",{className:"attachment-delete","data-att-id":String(r.id),title:"Remove",children:k("&times;")})]}))}).toString():i.innerHTML="";let s=document.getElementById("detail-notes-section"),a=document.getElementById("detail-notes"),o=ve(t.notes);o.length>0?(s.style.display="",a.innerHTML=l(L,{children:o.map(r=>l("div",{className:"note-entry",children:[r.created_at?l("div",{className:"note-timestamp",children:new Date(r.created_at).toLocaleString()}):null,l("div",{className:"note-text",children:r.text})]}))}).toString()):(s.style.display="none",a.innerHTML="");let d=document.getElementById("detail-meta");d.innerHTML=l(L,{children:[l("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),l("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?l("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?l("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ve(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}async function te(){try{let e=await c("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function N(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function P(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function ne(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),i=document.getElementById("content-area"),s=!1;e.addEventListener("mousedown",a=>{a.preventDefault(),s=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",a=>{if(!s)return;let o=i.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let d=Math.max(150,Math.min(500,o.bottom-a.clientY));n.settings.detail_height=d,t.style.height=`${d}px`}else{let d=Math.max(250,Math.min(600,o.right-a.clientX));n.settings.detail_width=d,t.style.width=`${d}px`}}),document.addEventListener("mouseup",()=>{s&&(s=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?c("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):c("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function _(e,t){let i=t.getBoundingClientRect(),s=e.getBoundingClientRect(),a=window.innerWidth,o=window.innerHeight,d=i.left;d+s.width>a-8&&(d=i.right-s.width),d<8&&(d=8);let r=i.bottom+4;r+s.height>o-8&&(r=i.top-s.height-4),r<8&&(r=8),e.style.left=`${d}px`,e.style.top=`${r}px`}function H(e,t){let i=y(l("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(r=>l("button",{className:`dropdown-item${r.active?" active":""}`,"data-key":r.key,children:[r.color?l("span",{className:"dropdown-dot",style:`background-color:${r.color}`}):null,l("span",{className:"dropdown-label",children:r.label}),r.shortcut?l("kbd",{className:"dropdown-kbd",children:r.shortcut}):null]}))}));i.querySelectorAll(".dropdown-item").forEach((r,u)=>{r.addEventListener("click",()=>{t[u].action(),i.remove()})});function a(r){let u=t.find(p=>r.key.toLowerCase()===p.key.toLowerCase());u?(r.preventDefault(),r.stopPropagation(),u.action(),o()):r.key==="Escape"&&(r.preventDefault(),o())}function o(){i.remove(),document.removeEventListener("keydown",a,!0),document.removeEventListener("click",d)}function d(){o()}return document.addEventListener("keydown",a,!0),setTimeout(()=>{document.addEventListener("click",d)},0),i}function C(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var $=null,E=!1,I=null,R="",M=[{key:"i",value:"issue",label:"Issue"},{key:"b",value:"bug",label:"Bug"},{key:"f",value:"feature",label:"Feature"},{key:"r",value:"requirement_change",label:"Req Change"},{key:"k",value:"task",label:"Task"},{key:"g",value:"investigation",label:"Investigation"}],O=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function ke(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let i=t.dataset.id;return i!==void 0&&i!==""?parseInt(i,10):null}function be(e){e!=null&&(E=!0,e==="draft"?g():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),E=!1)}function f(){let e=n.view==="trash",t=ke(),i=null;if(t!=null&&t!=="draft"){let a=document.querySelector(`.ticket-row[data-id="${t}"] .ticket-title-input`);a&&(i=a.value)}let s=document.getElementById("ticket-list");s.innerHTML="",e||s.appendChild(Te()),e&&n.tickets.length===0&&s.appendChild(y(l("div",{className:"ticket-list-empty",children:"Trash is empty"})));for(let a of n.tickets)s.appendChild(e?Le(a):we(a));if(t!=null&&t!=="draft"&&i!=null){let a=document.querySelector(`.ticket-row[data-id="${t}"] .ticket-title-input`);a&&a.value!==i&&(a.value=i)}be(t),B(),te()}function Te(){let e=ae(),t=n.view.startsWith("category:"),i=y(l("div",{className:"ticket-row draft-row",children:[l("span",{className:"ticket-checkbox-spacer"}),l("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),l("span",{className:"ticket-category-badge draft-badge",style:`background-color:${b(e)}${t?"":";cursor:pointer;opacity:1"}`,children:S(e)}),l("span",{className:"ticket-number draft-number"}),l("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:R}),l("span",{className:"ticket-priority-indicator draft-placeholder"}),l("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let a=i.querySelector(".ticket-category-badge");a.addEventListener("click",o=>{o.stopPropagation(),Ie(a)})}let s=i.querySelector(".draft-input");return s.addEventListener("input",()=>{R=s.value}),s.addEventListener("keydown",async a=>{if(a.key==="Enter"&&s.value.trim()){a.preventDefault();let o=s.value.trim();R="",s.value="";let d=Ee();I&&!n.view.startsWith("category:")&&(d.category=I);let r=await c("/tickets",{method:"POST",body:{title:o,defaults:d}});r&&(n.selectedIds.clear(),n.selectedIds.add(r.id)),await m(),g()}else a.key==="ArrowDown"&&(a.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),i}function g(){document.querySelector(".draft-row .draft-input")?.focus()}function Ee(){let e=n.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function ae(){if(I)return I;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Ie(e){C();let i=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",s=ae(),a=H(e,M.map(o=>({label:o.label,key:o.key,shortcut:`${i}${o.key.toUpperCase()}`,color:b(o.value),active:s===o.value,action:()=>{I=o.value,f(),g()}})));document.body.appendChild(a),_(a,e),a.style.visibility=""}function we(e){let t=n.selectedIds.has(e.id),i=e.status==="completed"||e.status==="verified",s=e.status==="verified",a=y(l("div",{className:`ticket-row${t?" selected":""}${i?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("button",{className:`ticket-status-btn${s?" verified":""}`,title:e.status.replace("_"," "),children:s?k(Y):X(e.status)}),l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,title:e.category,children:S(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("input",{type:"text",className:"ticket-title-input",value:e.title}),l("span",{className:"ticket-priority-indicator",style:`color:${A(e.priority)}`,title:e.priority,children:J(e.priority)}),l("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));a.addEventListener("mousedown",p=>{(p.metaKey||p.ctrlKey||p.shiftKey)&&(p.preventDefault(),oe(p,e)&&p.stopPropagation())});let o=a.querySelector(".ticket-checkbox");o.addEventListener("click",p=>p.stopPropagation()),o.addEventListener("change",()=>{o.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,f()}),a.querySelector(".ticket-status-btn").addEventListener("click",p=>{p.stopPropagation(),He(e)});let d=a.querySelector(".ticket-category-badge");d.addEventListener("click",p=>{p.stopPropagation(),De(d,e)});let r=a.querySelector(".ticket-title-input");r.addEventListener("focus",()=>{E||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,q(),B())}),r.addEventListener("input",()=>{Be(e.id,{title:r.value})}),r.addEventListener("keydown",p=>{Se(p,e,r)});let u=a.querySelector(".ticket-priority-indicator");return u.addEventListener("click",p=>{p.stopPropagation(),Ae(u,e)}),a.querySelector(".ticket-star").addEventListener("click",p=>{p.stopPropagation(),Ce(e)}),a}function Le(e){let t=n.selectedIds.has(e.id),i=e.deleted_at?new Date(e.deleted_at):null,s=y(l("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,children:S(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),l("span",{className:"ticket-number",title:i?`Deleted: ${i.toLocaleString()}`:"",children:i?i.toLocaleDateString():""}),l("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));s.addEventListener("mousedown",o=>{(o.metaKey||o.ctrlKey||o.shiftKey)&&(o.preventDefault(),oe(o,e)&&o.stopPropagation())});let a=s.querySelector(".ticket-checkbox");return a.addEventListener("click",o=>o.stopPropagation()),a.addEventListener("change",()=>{a.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,f()}),s.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,q(),B())}),s.querySelector(".btn").addEventListener("click",async o=>{o.stopPropagation(),await c(`/tickets/${e.id}/restore`,{method:"POST"}),m()}),s}function oe(e,t){let i=e.metaKey||e.ctrlKey,s=e.shiftKey;if(i)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,f();else if(s&&n.lastClickedId!=null){let a=n.tickets.map(r=>r.id),o=a.indexOf(n.lastClickedId),d=a.indexOf(t.id);if(o!==-1&&d!==-1){let r=Math.min(o,d),u=Math.max(o,d);n.selectedIds.clear();for(let p=r;p<=u;p++)n.selectedIds.add(a[p])}f()}else return!1;return!0}function Se(e,t,i){if(e.key==="Enter")e.preventDefault(),g();else if(e.key==="Backspace"&&i.value==="")e.preventDefault(),Me(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),ie(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),ie(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),xe(t.id);else if(e.key==="ArrowUp")e.preventDefault(),_e(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&M.some(s=>s.key===e.key)){e.preventDefault();let s=M.find(a=>a.key===e.key);se(t,"category",s.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&O.some(s=>s.key===e.key)){e.preventDefault();let s=O.find(a=>a.key===e.key);se(t,"priority",s.value)}}function xe(e){let t=n.tickets.findIndex(i=>i.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function _e(e){let t=n.tickets.findIndex(i=>i.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():g()}function ie(e,t){let s=n.tickets.findIndex(d=>d.id===e)+t;if(s<0||s>=n.tickets.length)return;let a=n.tickets[s].id;n.selectedIds.add(e),n.selectedIds.has(a)?n.selectedIds.delete(e):n.selectedIds.add(a),E=!0,document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`)?.focus(),E=!1,q(),B()}async function He(e){let i={not_started:"started",started:"completed",completed:"verified",verified:"not_started"}[e.status]||"not_started",s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:i}});Object.assign(e,s),f()}async function Ce(e){if(!e.up_next&&(e.status==="completed"||e.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?"))return;let i=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:"not_started",up_next:!0}});Object.assign(e,i),f();return}let t=await c(`/tickets/${e.id}/up-next`,{method:"POST"});Object.assign(e,t),f()}async function se(e,t,i){let s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{[t]:i}});Object.assign(e,s),f()}async function Me(e){let t=n.tickets.findIndex(i=>i.id===e);if(await c(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(i=>i.id!==e),n.selectedIds.delete(e),f(),t>0&&n.tickets.length>0){let i=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[i].id}"] .ticket-title-input`)?.focus()}else g()}function Be(e,t){$&&clearTimeout($),$=setTimeout(()=>{c(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function De(e,t){C();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=H(e,M.map(o=>({label:o.label,key:o.key,shortcut:`${s}${o.key.toUpperCase()}`,color:b(o.value),active:t.category===o.value,action:async()=>{let d=await c(`/tickets/${t.id}`,{method:"PATCH",body:{category:o.value}});Object.assign(t,d),f()}})));document.body.appendChild(a),_(a,e),a.style.visibility=""}function Ae(e,t){C();let i=H(e,O.map(s=>({label:s.label,key:s.key,shortcut:`Alt+${s.key}`,color:A(s.value),active:t.priority===s.value,action:async()=>{let a=await c(`/tickets/${t.id}`,{method:"PATCH",body:{priority:s.value}});Object.assign(t,a),f()}})));document.body.appendChild(i),_(i,e),i.style.visibility=""}function q(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),i=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),i&&(i.checked=!0)):(e.classList.remove("selected"),i&&(i.checked=!1))})}function B(){let e=n.selectedIds.size,t=n.tickets.length,i=e>0,s=n.view==="trash",a=document.getElementById("batch-select-all");a.checked=t>0&&e===t,a.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=i?`${e} selected`:"";let o=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete"];for(let v of o){let w=document.getElementById(v);w.style.display=s?"none":"",s||(w.disabled=!i)}let d=document.getElementById("batch-restore"),r=document.getElementById("batch-empty-trash");if(s){let v=document.getElementById("batch-toolbar");d||(d=y(l("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),d.addEventListener("click",async()=>{await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),m()}),v.insertBefore(d,document.getElementById("batch-count"))),d.disabled=!i,d.style.display="",r||(r=y(l("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),r.addEventListener("click",async()=>{confirm("Permanently delete all items in trash? This cannot be undone.")&&(await c("/trash/empty",{method:"POST"}),n.selectedIds.clear(),m())}),v.insertBefore(r,document.getElementById("batch-count"))),r.disabled=t===0,r.style.display=""}else d&&(d.style.display="none"),r&&(r.style.display="none");let u=document.querySelector(".batch-star-icon"),p=document.getElementById("batch-upnext");if(!s&&u&&i){let v=n.tickets.filter(T=>n.selectedIds.has(T.id)),w=v.every(T=>T.up_next),re=v.every(T=>!T.up_next);w?(u.textContent="\u2605",p.classList.add("active"),p.classList.remove("mixed")):re?(u.textContent="\u2606",p.classList.remove("active","mixed")):(u.innerHTML=l("span",{className:"star-mixed-wrap",children:[l("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),p.classList.remove("active"),p.classList.add("mixed"))}else u&&(u.textContent="\u2606",p.classList.remove("active","mixed"));Z()}async function m(){let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="verified"?e.set("status","verified"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")&&e.set("priority",n.view.split(":")[1]),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await c(`/tickets${t?"?"+t:""}`),f()}async function Ne(){await Pe(),await m(),Oe(),qe(),Ke(),Ue(),ze(),Ve(),$e(),Re(),ne(),We(),document.addEventListener("hotsheet:render",()=>f()),g()}async function Pe(){try{let e=await c("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30)}catch{}N(n.settings.detail_position),P()}function $e(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close");document.getElementById("settings-btn").addEventListener("click",()=>{document.getElementById("settings-detail-position").value=n.settings.detail_position,document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex"}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",u=>{u.target===e&&(e.style.display="none")});let s=document.getElementById("settings-detail-position");s.addEventListener("change",()=>{n.settings.detail_position=s.value,N(n.settings.detail_position),P(),c("/settings",{method:"PATCH",body:{detail_position:s.value}})});let a=document.getElementById("settings-trash-days"),o=null;a.addEventListener("input",()=>{o&&clearTimeout(o),o=setTimeout(()=>{let u=Math.max(1,parseInt(a.value,10)||3);a.value=String(u),n.settings.trash_cleanup_days=u,c("/settings",{method:"PATCH",body:{trash_cleanup_days:String(u)}})},500)});let d=document.getElementById("settings-verified-days"),r=null;d.addEventListener("input",()=>{r&&clearTimeout(r),r=setTimeout(()=>{let u=Math.max(1,parseInt(d.value,10)||30);d.value=String(u),n.settings.verified_cleanup_days=u,c("/settings",{method:"PATCH",body:{verified_cleanup_days:String(u)}})},500)})}function Re(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),i=document.getElementById("copy-prompt-label"),s=document.getElementById("copy-prompt-icon"),a="";c("/worklist-info").then(o=>{a=o.prompt,e.style.display="",o.skillCreated&&console.log("Hot Sheet: Created /hotsheet skill in .claude/skills/hotsheet/")}),t.addEventListener("click",()=>{a!==""&&navigator.clipboard.writeText(a).then(()=>{i.textContent="Copied!",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{i.textContent="Copy AI prompt",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function Oe(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(i=>{i.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),m()})})}function qe(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,i]=e.value.split(":");n.sortBy=t,n.sortDir=i,m()})}var K=null;function Ke(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{K&&clearTimeout(K),K=setTimeout(()=>{n.search=e.value,m()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",m())})}function Ue(){let e=document.getElementById("batch-category");e.addEventListener("change",async()=>{e.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"category",value:e.value}}),e.value="",m())});let t=document.getElementById("batch-priority");t.addEventListener("change",async()=>{t.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"priority",value:t.value}}),t.value="",m())});let i=document.getElementById("batch-status");i.addEventListener("change",async()=>{i.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"status",value:i.value}}),i.value="",m())}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let s=n.tickets.filter(d=>n.selectedIds.has(d.id)),o=!s.every(d=>d.up_next);if(o){let d=s.filter(r=>r.status==="completed"||r.status==="verified");if(d.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;await c("/tickets/batch",{method:"POST",body:{ids:d.map(r=>r.id),action:"status",value:"not_started"}})}}await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:o}}),m()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let s=n.selectedIds.size;confirm(`Delete ${s} ticket(s)?`)&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"delete"}}),n.selectedIds.clear(),m())}),document.getElementById("batch-select-all").addEventListener("change",s=>{if(s.target.checked)for(let o of n.tickets)n.selectedIds.add(o.id);else n.selectedIds.clear();f()})}var U=null;function ze(){document.getElementById("detail-close").addEventListener("click",Q);let e=["detail-title","detail-details"];for(let i of e){let s=document.getElementById(i);s.addEventListener("input",()=>{U&&clearTimeout(U),U=setTimeout(()=>{if(n.activeTicketId==null)return;let a=i.replace("detail-","");c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:s.value}}).then(()=>{m()})},300)})}let t=["detail-category","detail-priority","detail-status"];for(let i of t){let s=document.getElementById(i);s.addEventListener("change",async()=>{if(n.activeTicketId==null)return;let a=i.replace("detail-","");await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:s.value}}),m()})}document.getElementById("detail-upnext").addEventListener("change",async()=>{if(n.activeTicketId==null)return;let i=n.tickets.find(a=>a.id===n.activeTicketId),s=document.getElementById("detail-upnext");if(s.checked&&i&&(i.status==="completed"||i.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?")){s.checked=!1;return}await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{status:"not_started",up_next:!0}})}else await c(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"});m(),x(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async i=>{let s=i.target,a=s.files?.[0];!a||n.activeTicketId==null||(await G(`/tickets/${n.activeTicketId}/attachments`,a),s.value="",x(n.activeTicketId),m())}),document.getElementById("detail-attachments").addEventListener("click",async i=>{let a=i.target.closest(".attachment-delete");if(a===null)return;let o=a.dataset.attId;o===void 0||o===""||(await c(`/attachments/${o}`,{method:"DELETE"}),n.activeTicketId!=null&&x(n.activeTicketId))})}function je(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function Fe(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let i=je(e.notes);if(i.length>0){t.push("");for(let s of i)t.push(`- ${s.text}`)}return t.join(`
2
- `)}function Ve(){document.addEventListener("keydown",e=>{let t=e.target.tagName,i=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",s=document.getElementById("settings-overlay");if(e.key==="Escape"&&s.style.display!=="none"){s.style.display="none";return}if(e.key==="Escape"){n.selectedIds.size>0&&(n.selectedIds.clear(),f());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!i){e.preventDefault(),n.selectedIds.clear();for(let a of n.tickets)n.selectedIds.add(a.id);f();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(n.selectedIds.size>0){e.preventDefault();let a=n.tickets.filter(r=>n.selectedIds.has(r.id)),d=!a.every(r=>r.up_next);if(d){let r=a.filter(u=>u.status==="completed"||u.status==="verified");if(r.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;c("/tickets/batch",{method:"POST",body:{ids:r.map(u=>u.id),action:"status",value:"not_started"}}).then(()=>c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:!0}})).then(()=>{m()});return}}c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:d}}).then(()=>{m()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&n.selectedIds.size>0){let a=window.getSelection();if(!a||a.isCollapsed||a.toString().trim()===""){e.preventDefault();let d=n.tickets.filter(r=>n.selectedIds.has(r.id)).map(Fe).join(`
1
+ "use strict";(()=>{var ye=Object.defineProperty;var ge=(e,t,s)=>t in e?ye(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var J=(e,t,s)=>ge(e,typeof t!="symbol"?t+"":t,s);function G(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Y(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var h=class{constructor(t){J(this,"__html");this.__html=t}toString(){return this.__html}};function k(e){return new h(e)}var ve=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function A(e){return e==null||typeof e=="boolean"?"":e instanceof h?e.__html:typeof e=="string"?G(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(A).join(""):""}function he(e,t){if(t==null||t===!1)return"";if(t===!0)return` ${e}`;let s=e==="className"?"class":e==="htmlFor"?"for":e,i;return t instanceof h?i=t.__html:typeof t=="number"?i=String(t):typeof t=="string"?i=Y(t):i="",` ${s}="${i}"`}function l(e,t){if(typeof e=="function")return e(t);let{children:s,...i}=t,a=Object.entries(i).map(([d,o])=>he(d,o)).join("");if(ve.has(e))return new h(`<${e}${a}>`);let r=s!=null?A(s):"";return new h(`<${e}${a}>${r}</${e}>`)}function x({children:e}){return new h(e!=null?A(e):"")}function g(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function X(e){document.getElementById("network-error-popup")?.remove();let t=g(l("div",{id:"network-error-popup",className:"error-popup",children:l("div",{className:"error-popup-content",children:[l("strong",{children:"Connection Error"}),l("p",{children:e}),l("button",{children:k("Dismiss")})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function c(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(s){throw X("Unable to reach the server. It may have been stopped."),s}}async function Q(e,t){try{let s=new FormData;return s.append("file",t),(await fetch("/api"+e,{method:"POST",body:s})).json()}catch(s){throw X("Unable to reach the server. It may have been stopped."),s}}var be={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...be}},ke={issue:"#6b7280",bug:"#ef4444",feature:"#22c55e",requirement_change:"#f97316",task:"#3b82f6",investigation:"#8b5cf6"},Te={issue:"ISS",bug:"BUG",feature:"FEA",requirement_change:"REQ",task:"TSK",investigation:"INV"},Ee={highest:"\u2B06\u2B06",high:"\u2B06",default:"\u2014",low:"\u2B07",lowest:"\u2B07\u2B07"},Ie={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},Le={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:"svg"},Z='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-9.5 9.5-2-2"/></svg>';function b(e){return ke[e]||"#6b7280"}function I(e){return Te[e]||"ISS"}function P(e){return Ee[e]||"\u2014"}function _(e){return Ie[e]||"#6b7280"}function ee(e){return Le[e]||"\u25CB"}function C(e){n.activeTicketId=e,se(e)}function te(){n.selectedIds.clear(),n.activeTicketId=null;let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function ne(){let e=n.view==="trash",t=document.getElementById("detail-panel"),s=document.getElementById("detail-resize-handle");if(n.selectedIds.size===1&&!e){let i=Array.from(n.selectedIds)[0];t.style.display="flex",s&&(s.style.display=""),n.activeTicketId!==i&&(n.activeTicketId=i,se(i))}else n.activeTicketId!=null&&(n.activeTicketId=null),t.style.display="none",s&&(s.style.display="none")}async function se(e){let t=await c(`/tickets/${e}`);if(n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details;let s=document.getElementById("detail-attachments");t.attachments.length>0?s.innerHTML=l(x,{children:t.attachments.map(o=>l("div",{className:"attachment-item",children:[l("span",{className:"attachment-name",children:o.original_filename}),l("button",{className:"attachment-delete","data-att-id":String(o.id),title:"Remove",children:k("&times;")})]}))}).toString():s.innerHTML="";let i=document.getElementById("detail-notes-section"),a=document.getElementById("detail-notes"),r=we(t.notes);r.length>0?(i.style.display="",a.innerHTML=l(x,{children:r.map(o=>l("div",{className:"note-entry",children:[o.created_at?l("div",{className:"note-timestamp",children:new Date(o.created_at).toLocaleString()}):null,l("div",{className:"note-text",children:o.text})]}))}).toString()):(i.style.display="none",a.innerHTML="");let d=document.getElementById("detail-meta");d.innerHTML=l(x,{children:[l("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),l("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?l("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?l("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function we(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}async function $(){try{let e=await c("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function O(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function R(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function ie(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),s=document.getElementById("content-area"),i=!1;e.addEventListener("mousedown",a=>{a.preventDefault(),i=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",a=>{if(!i)return;let r=s.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let d=Math.max(150,Math.min(500,r.bottom-a.clientY));n.settings.detail_height=d,t.style.height=`${d}px`}else{let d=Math.max(250,Math.min(600,r.right-a.clientX));n.settings.detail_width=d,t.style.width=`${d}px`}}),document.addEventListener("mouseup",()=>{i&&(i=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?c("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):c("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function H(e,t){let s=t.getBoundingClientRect(),i=e.getBoundingClientRect(),a=window.innerWidth,r=window.innerHeight,d=s.left;d+i.width>a-8&&(d=s.right-i.width),d<8&&(d=8);let o=s.bottom+4;o+i.height>r-8&&(o=s.top-i.height-4),o<8&&(o=8),e.style.left=`${d}px`,e.style.top=`${o}px`}function M(e,t){let s=g(l("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(o=>l("button",{className:`dropdown-item${o.active?" active":""}`,"data-key":o.key,children:[o.color?l("span",{className:"dropdown-dot",style:`background-color:${o.color}`}):null,l("span",{className:"dropdown-label",children:o.label}),o.shortcut?l("kbd",{className:"dropdown-kbd",children:o.shortcut}):null]}))}));s.querySelectorAll(".dropdown-item").forEach((o,m)=>{o.addEventListener("click",()=>{t[m].action(),s.remove()})});function a(o){let m=t.find(u=>o.key.toLowerCase()===u.key.toLowerCase());m?(o.preventDefault(),o.stopPropagation(),m.action(),r()):o.key==="Escape"&&(o.preventDefault(),r())}function r(){s.remove(),document.removeEventListener("keydown",a,!0),document.removeEventListener("click",d)}function d(){r()}return document.addEventListener("keydown",a,!0),setTimeout(()=>{document.addEventListener("click",d)},0),s}function B(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var q=null,L=!1,w=null,U="",N=[{key:"i",value:"issue",label:"Issue"},{key:"b",value:"bug",label:"Bug"},{key:"f",value:"feature",label:"Feature"},{key:"r",value:"requirement_change",label:"Req Change"},{key:"k",value:"task",label:"Task"},{key:"g",value:"investigation",label:"Investigation"}],K=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function Se(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let s=t.dataset.id;return s!==void 0&&s!==""?parseInt(s,10):null}function xe(e){e!=null&&(L=!0,e==="draft"?v():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),L=!1)}function D(){let e=n.view;return e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="up-next"&&e!=="open"}function _e(){return n.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:n.view==="non-verified"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"}]:[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"},{status:"verified",label:"Verified"}]}function f(){if(n.layout==="columns"&&D()){Ce();return}let e=n.view==="trash",t=Se(),s=null;if(t!=null&&t!=="draft"){let a=document.querySelector(`.ticket-row[data-id="${t}"] .ticket-title-input`);a&&(s=a.value)}let i=document.getElementById("ticket-list");i.innerHTML="",i.classList.remove("ticket-list-columns"),e||i.appendChild(re()),e&&n.tickets.length===0&&i.appendChild(g(l("div",{className:"ticket-list-empty",children:"Trash is empty"})));for(let a of n.tickets)i.appendChild(e?Ae(a):De(a));if(t!=null&&t!=="draft"&&s!=null){let a=document.querySelector(`.ticket-row[data-id="${t}"] .ticket-title-input`);a&&a.value!==s&&(a.value=s)}xe(t),T(),$()}function Ce(){let e=document.getElementById("ticket-list");e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(re());let t=_e(),s=g(l("div",{className:"columns-container"}));for(let i of t){let a=n.tickets.filter(o=>o.status===i.status),r=g(l("div",{className:"column","data-status":i.status,children:[l("div",{className:"column-header",children:[l("span",{className:"column-title",children:i.label}),l("span",{className:"column-count",children:String(a.length)})]}),l("div",{className:"column-body"})]})),d=r.querySelector(".column-body");for(let o of a)d.appendChild(He(o));d.addEventListener("dragover",o=>{o.preventDefault(),o.dataTransfer.dropEffect="move",r.classList.add("column-drop-target")}),d.addEventListener("dragleave",o=>{let m=o.relatedTarget;(!m||!d.contains(m))&&r.classList.remove("column-drop-target")}),d.addEventListener("drop",o=>{o.preventDefault(),r.classList.remove("column-drop-target");let m=o.dataTransfer.getData("application/hotsheet-tickets");if(!m)return;let u=JSON.parse(m);c("/tickets/batch",{method:"POST",body:{ids:u,action:"status",value:i.status}}).then(()=>{p()})}),s.appendChild(r)}e.appendChild(s),T(),$()}function He(e){let t=n.selectedIds.has(e.id),s=g(l("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[l("div",{className:"column-card-header",children:[l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,children:I(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("span",{className:"ticket-priority-indicator",style:`color:${_(e.priority)}`,children:P(e.priority)}),l("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}),l("div",{className:"column-card-title",children:e.title})]})),i=s.querySelector(".ticket-priority-indicator");return i.addEventListener("click",a=>{a.stopPropagation(),ue(i,e)}),s.querySelector(".ticket-star").addEventListener("click",a=>{a.stopPropagation(),ce(e)}),s.draggable=!0,s.addEventListener("dragstart",a=>{let r;n.selectedIds.has(e.id)&&n.selectedIds.size>1?r=Array.from(n.selectedIds):r=[e.id],a.dataTransfer.setData("application/hotsheet-tickets",JSON.stringify(r)),a.dataTransfer.effectAllowed="move"}),s.addEventListener("click",a=>{if(a.metaKey||a.ctrlKey)n.selectedIds.has(e.id)?n.selectedIds.delete(e.id):n.selectedIds.add(e.id),n.lastClickedId=e.id;else if(a.shiftKey&&n.lastClickedId!=null){let r=n.tickets.map(m=>m.id),d=r.indexOf(n.lastClickedId),o=r.indexOf(e.id);if(d!==-1&&o!==-1){let m=Math.min(d,o),u=Math.max(d,o);n.selectedIds.clear();for(let y=m;y<=u;y++)n.selectedIds.add(r[y])}}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id;Me(),T()}),s}function Me(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);n.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function re(){let e=le(),t=n.view.startsWith("category:"),s=g(l("div",{className:"ticket-row draft-row",children:[l("span",{className:"ticket-checkbox-spacer"}),l("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),l("span",{className:"ticket-category-badge draft-badge",style:`background-color:${b(e)}${t?"":";cursor:pointer;opacity:1"}`,children:I(e)}),l("span",{className:"ticket-number draft-number"}),l("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:U}),l("span",{className:"ticket-priority-indicator draft-placeholder"}),l("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let a=s.querySelector(".ticket-category-badge");a.addEventListener("click",r=>{r.stopPropagation(),Ne(a)})}let i=s.querySelector(".draft-input");return i.addEventListener("input",()=>{U=i.value}),i.addEventListener("keydown",async a=>{if(a.key==="Enter"&&i.value.trim()){a.preventDefault();let r=i.value.trim();U="",i.value="";let d=Be();w&&!n.view.startsWith("category:")&&(d.category=w);let o=await c("/tickets",{method:"POST",body:{title:r,defaults:d}});o&&(n.selectedIds.clear(),n.selectedIds.add(o.id)),await p(),v()}else a.key==="ArrowDown"&&(a.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),s}function v(){document.querySelector(".draft-row .draft-input")?.focus()}function Be(){let e=n.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function le(){if(w)return w;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Ne(e){B();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",i=le(),a=M(e,N.map(r=>({label:r.label,key:r.key,shortcut:`${s}${r.key.toUpperCase()}`,color:b(r.value),active:i===r.value,action:()=>{w=r.value,f(),v()}})));document.body.appendChild(a),H(a,e),a.style.visibility=""}function De(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",i=e.status==="verified",a=g(l("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("button",{className:`ticket-status-btn${i?" verified":""}`,title:e.status.replace("_"," "),children:i?k(Z):ee(e.status)}),l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,title:e.category,children:I(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("input",{type:"text",className:"ticket-title-input",value:e.title}),l("span",{className:"ticket-priority-indicator",style:`color:${_(e.priority)}`,title:e.priority,children:P(e.priority)}),l("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));a.addEventListener("mousedown",u=>{let y=u.target;y.tagName!=="INPUT"&&y.tagName!=="BUTTON"&&(a.draggable=!0)}),a.addEventListener("mouseup",()=>{a.draggable=!1}),a.addEventListener("dragend",()=>{a.draggable=!1}),a.addEventListener("dragstart",u=>{let y;n.selectedIds.has(e.id)&&n.selectedIds.size>1?y=Array.from(n.selectedIds):y=[e.id],u.dataTransfer.setData("application/hotsheet-tickets",JSON.stringify(y)),u.dataTransfer.effectAllowed="move"}),a.addEventListener("mousedown",u=>{(u.metaKey||u.ctrlKey||u.shiftKey)&&(u.preventDefault(),de(u,e)&&u.stopPropagation())});let r=a.querySelector(".ticket-checkbox");r.addEventListener("click",u=>u.stopPropagation()),r.addEventListener("change",()=>{r.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,f()}),a.querySelector(".ticket-status-btn").addEventListener("click",u=>{u.stopPropagation(),Re(e)});let d=a.querySelector(".ticket-category-badge");d.addEventListener("click",u=>{u.stopPropagation(),Ke(d,e)});let o=a.querySelector(".ticket-title-input");o.addEventListener("focus",()=>{L||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,z(),T())}),o.addEventListener("input",()=>{Ue(e.id,{title:o.value})}),o.addEventListener("keydown",u=>{Pe(u,e,o)});let m=a.querySelector(".ticket-priority-indicator");return m.addEventListener("click",u=>{u.stopPropagation(),ue(m,e)}),a.querySelector(".ticket-star").addEventListener("click",u=>{u.stopPropagation(),ce(e)}),a}function Ae(e){let t=n.selectedIds.has(e.id),s=e.deleted_at?new Date(e.deleted_at):null,i=g(l("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,children:I(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),l("span",{className:"ticket-number",title:s?`Deleted: ${s.toLocaleString()}`:"",children:s?s.toLocaleDateString():""}),l("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));i.addEventListener("mousedown",r=>{(r.metaKey||r.ctrlKey||r.shiftKey)&&(r.preventDefault(),de(r,e)&&r.stopPropagation())});let a=i.querySelector(".ticket-checkbox");return a.addEventListener("click",r=>r.stopPropagation()),a.addEventListener("change",()=>{a.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,f()}),i.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,z(),T())}),i.querySelector(".btn").addEventListener("click",async r=>{r.stopPropagation(),await c(`/tickets/${e.id}/restore`,{method:"POST"}),p()}),i}function de(e,t){let s=e.metaKey||e.ctrlKey,i=e.shiftKey;if(s)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,f();else if(i&&n.lastClickedId!=null){let a=n.tickets.map(o=>o.id),r=a.indexOf(n.lastClickedId),d=a.indexOf(t.id);if(r!==-1&&d!==-1){let o=Math.min(r,d),m=Math.max(r,d);n.selectedIds.clear();for(let u=o;u<=m;u++)n.selectedIds.add(a[u])}f()}else return!1;return!0}function Pe(e,t,s){if(e.key==="Enter")e.preventDefault(),v();else if(e.key==="Backspace"&&s.value==="")e.preventDefault(),qe(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),ae(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),ae(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),$e(t.id);else if(e.key==="ArrowUp")e.preventDefault(),Oe(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&N.some(i=>i.key===e.key)){e.preventDefault();let i=N.find(a=>a.key===e.key);oe(t,"category",i.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&K.some(i=>i.key===e.key)){e.preventDefault();let i=K.find(a=>a.key===e.key);oe(t,"priority",i.value)}}function $e(e){let t=n.tickets.findIndex(s=>s.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function Oe(e){let t=n.tickets.findIndex(s=>s.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():v()}function ae(e,t){let i=n.tickets.findIndex(d=>d.id===e)+t;if(i<0||i>=n.tickets.length)return;let a=n.tickets[i].id;n.selectedIds.add(e),n.selectedIds.has(a)?n.selectedIds.delete(e):n.selectedIds.add(a),L=!0,document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`)?.focus(),L=!1,z(),T()}async function Re(e){let s={not_started:"started",started:"completed",completed:"verified",verified:"not_started"}[e.status]||"not_started",i=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:s}});Object.assign(e,i),f()}async function ce(e){if(!e.up_next&&(e.status==="completed"||e.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?"))return;let s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:"not_started",up_next:!0}});Object.assign(e,s),f();return}let t=await c(`/tickets/${e.id}/up-next`,{method:"POST"});Object.assign(e,t),f()}async function oe(e,t,s){let i=await c(`/tickets/${e.id}`,{method:"PATCH",body:{[t]:s}});Object.assign(e,i),f()}async function qe(e){let t=n.tickets.findIndex(s=>s.id===e);if(await c(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(s=>s.id!==e),n.selectedIds.delete(e),f(),t>0&&n.tickets.length>0){let s=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[s].id}"] .ticket-title-input`)?.focus()}else v()}function Ue(e,t){q&&clearTimeout(q),q=setTimeout(()=>{c(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Ke(e,t){B();let i=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=M(e,N.map(r=>({label:r.label,key:r.key,shortcut:`${i}${r.key.toUpperCase()}`,color:b(r.value),active:t.category===r.value,action:async()=>{let d=await c(`/tickets/${t.id}`,{method:"PATCH",body:{category:r.value}});Object.assign(t,d),f()}})));document.body.appendChild(a),H(a,e),a.style.visibility=""}function ue(e,t){B();let s=M(e,K.map(i=>({label:i.label,key:i.key,shortcut:`Alt+${i.key}`,color:_(i.value),active:t.priority===i.value,action:async()=>{let a=await c(`/tickets/${t.id}`,{method:"PATCH",body:{priority:i.value}});Object.assign(t,a),f()}})));document.body.appendChild(s),H(s,e),s.style.visibility=""}function z(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),s=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),s&&(s.checked=!0)):(e.classList.remove("selected"),s&&(s.checked=!1))})}function T(){let e=n.selectedIds.size,t=n.tickets.length,s=e>0,i=n.view==="trash",a=document.getElementById("batch-select-all");a.checked=t>0&&e===t,a.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=s?`${e} selected`:"";let r=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete"];for(let y of r){let S=document.getElementById(y);S.style.display=i?"none":"",i||(S.disabled=!s)}let d=document.getElementById("batch-restore"),o=document.getElementById("batch-empty-trash");if(i){let y=document.getElementById("batch-toolbar");d||(d=g(l("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),d.addEventListener("click",async()=>{await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),p()}),y.insertBefore(d,document.getElementById("batch-count"))),d.disabled=!s,d.style.display="",o||(o=g(l("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),o.addEventListener("click",async()=>{confirm("Permanently delete all items in trash? This cannot be undone.")&&(await c("/trash/empty",{method:"POST"}),n.selectedIds.clear(),p())}),y.insertBefore(o,document.getElementById("batch-count"))),o.disabled=t===0,o.style.display=""}else d&&(d.style.display="none"),o&&(o.style.display="none");let m=document.querySelector(".batch-star-icon"),u=document.getElementById("batch-upnext");if(!i&&m&&s){let y=n.tickets.filter(E=>n.selectedIds.has(E.id)),S=y.every(E=>E.up_next),fe=y.every(E=>!E.up_next);S?(m.textContent="\u2605",u.classList.add("active"),u.classList.remove("mixed")):fe?(m.textContent="\u2606",u.classList.remove("active","mixed")):(m.innerHTML=l("span",{className:"star-mixed-wrap",children:[l("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),u.classList.remove("active"),u.classList.add("mixed"))}else m&&(m.textContent="\u2606",u.classList.remove("active","mixed"));ne()}async function p(){let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="non-verified"?e.set("status","non_verified"):n.view==="verified"?e.set("status","verified"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")&&e.set("priority",n.view.split(":")[1]),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await c(`/tickets${t?"?"+t:""}`),f()}async function ze(){await Ve(),await p(),Ye(),We(),Je(),Xe(),Qe(),Ze(),et(),st(),Fe(),je(),ie(),it(),document.addEventListener("hotsheet:render",()=>f()),v()}async function Ve(){try{let e=await c("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(n.layout=e.layout)}catch{}O(n.settings.detail_position),R()}function Fe(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close");document.getElementById("settings-btn").addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex"}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",o=>{o.target===e&&(e.style.display="none")});let i=document.getElementById("settings-trash-days"),a=null;i.addEventListener("input",()=>{a&&clearTimeout(a),a=setTimeout(()=>{let o=Math.max(1,parseInt(i.value,10)||3);i.value=String(o),n.settings.trash_cleanup_days=o,c("/settings",{method:"PATCH",body:{trash_cleanup_days:String(o)}})},500)});let r=document.getElementById("settings-verified-days"),d=null;r.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let o=Math.max(1,parseInt(r.value,10)||30);r.value=String(o),n.settings.verified_cleanup_days=o,c("/settings",{method:"PATCH",body:{verified_cleanup_days:String(o)}})},500)})}function je(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),s=document.getElementById("copy-prompt-label"),i=document.getElementById("copy-prompt-icon"),a="";c("/worklist-info").then(r=>{a=r.prompt,e.style.display="",r.skillCreated&&console.log("Hot Sheet: Created /hotsheet skill in .claude/skills/hotsheet/")}),t.addEventListener("click",()=>{a!==""&&navigator.clipboard.writeText(a).then(()=>{s.textContent="Copied!",i.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{s.textContent="Copy AI prompt",i.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function W(){let e=document.getElementById("layout-toggle"),t=D(),s=e.querySelector('[data-layout="columns"]');s.disabled=!t,s.style.opacity=t?"":"0.3";let i=n.layout==="columns"&&!t?"list":n.layout;e.querySelectorAll(".layout-btn").forEach(a=>{a.classList.toggle("active",a.dataset.layout===i)})}function We(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.layout;s==="columns"&&!D()||(n.layout=s,W(),f(),c("/settings",{method:"PATCH",body:{layout:s}}))})}),W()}function me(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===n.settings.detail_position)})}function Je(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.position;n.settings.detail_position=s,O(s),R(),me(),c("/settings",{method:"PATCH",body:{detail_position:s}})})}),me()}function pe(e){return e==="up-next"?{action:"up_next",value:!0}:e==="open"?{action:"status",value:"not_started"}:e==="completed"?{action:"status",value:"completed"}:e==="verified"?{action:"status",value:"verified"}:e==="trash"?{action:"delete",value:null}:e.startsWith("category:")?{action:"category",value:e.split(":")[1]}:e.startsWith("priority:")?{action:"priority",value:e.split(":")[1]}:null}async function Ge(e,t){let s=pe(e);s&&(s.action==="delete"?await c("/tickets/batch",{method:"POST",body:{ids:t,action:"delete"}}):await c("/tickets/batch",{method:"POST",body:{ids:t,action:s.action,value:s.value}}),p())}function Ye(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(i=>{i.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),W(),p()});let s=t.dataset.view;pe(s)&&(t.addEventListener("dragover",i=>{i.preventDefault(),i.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",i=>{i.preventDefault(),t.classList.remove("drop-target");let a=i.dataTransfer.getData("application/hotsheet-tickets");if(!a)return;let r=JSON.parse(a);Ge(s,r)}))})}function Xe(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,s]=e.value.split(":");n.sortBy=t,n.sortDir=s,p()})}var V=null;function Qe(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{V&&clearTimeout(V),V=setTimeout(()=>{n.search=e.value,p()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",p())})}function Ze(){let e=document.getElementById("batch-category");e.addEventListener("change",async()=>{e.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"category",value:e.value}}),e.value="",p())});let t=document.getElementById("batch-priority");t.addEventListener("change",async()=>{t.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"priority",value:t.value}}),t.value="",p())});let s=document.getElementById("batch-status");s.addEventListener("change",async()=>{s.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"status",value:s.value}}),s.value="",p())}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let i=n.tickets.filter(d=>n.selectedIds.has(d.id)),r=!i.every(d=>d.up_next);if(r){let d=i.filter(o=>o.status==="completed"||o.status==="verified");if(d.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;await c("/tickets/batch",{method:"POST",body:{ids:d.map(o=>o.id),action:"status",value:"not_started"}})}}await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:r}}),p()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let i=n.selectedIds.size;confirm(`Delete ${i} ticket(s)?`)&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"delete"}}),n.selectedIds.clear(),p())}),document.getElementById("batch-select-all").addEventListener("change",i=>{if(i.target.checked)for(let r of n.tickets)n.selectedIds.add(r.id);else n.selectedIds.clear();f()})}var F=null;function et(){document.getElementById("detail-close").addEventListener("click",te);let e=["detail-title","detail-details"];for(let s of e){let i=document.getElementById(s);i.addEventListener("input",()=>{F&&clearTimeout(F),F=setTimeout(()=>{if(n.activeTicketId==null)return;let a=s.replace("detail-","");c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:i.value}}).then(()=>{p()})},300)})}let t=["detail-category","detail-priority","detail-status"];for(let s of t){let i=document.getElementById(s);i.addEventListener("change",async()=>{if(n.activeTicketId==null)return;let a=s.replace("detail-","");await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:i.value}}),p()})}document.getElementById("detail-upnext").addEventListener("change",async()=>{if(n.activeTicketId==null)return;let s=n.tickets.find(a=>a.id===n.activeTicketId),i=document.getElementById("detail-upnext");if(i.checked&&s&&(s.status==="completed"||s.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?")){i.checked=!1;return}await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{status:"not_started",up_next:!0}})}else await c(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"});p(),C(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async s=>{let i=s.target,a=i.files?.[0];!a||n.activeTicketId==null||(await Q(`/tickets/${n.activeTicketId}/attachments`,a),i.value="",C(n.activeTicketId),p())}),document.getElementById("detail-attachments").addEventListener("click",async s=>{let a=s.target.closest(".attachment-delete");if(a===null)return;let r=a.dataset.attId;r===void 0||r===""||(await c(`/attachments/${r}`,{method:"DELETE"}),n.activeTicketId!=null&&C(n.activeTicketId))})}function tt(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function nt(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let s=tt(e.notes);if(s.length>0){t.push("");for(let i of s)t.push(`- ${i.text}`)}return t.join(`
2
+ `)}function st(){document.addEventListener("keydown",e=>{let t=e.target.tagName,s=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",i=document.getElementById("settings-overlay");if(e.key==="Escape"&&i.style.display!=="none"){i.style.display="none";return}if(e.key==="Escape"){n.selectedIds.size>0&&(n.selectedIds.clear(),f());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!s){e.preventDefault(),n.selectedIds.clear();for(let a of n.tickets)n.selectedIds.add(a.id);f();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(n.selectedIds.size>0){e.preventDefault();let a=n.tickets.filter(o=>n.selectedIds.has(o.id)),d=!a.every(o=>o.up_next);if(d){let o=a.filter(m=>m.status==="completed"||m.status==="verified");if(o.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;c("/tickets/batch",{method:"POST",body:{ids:o.map(m=>m.id),action:"status",value:"not_started"}}).then(()=>c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:!0}})).then(()=>{p()});return}}c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:d}}).then(()=>{p()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&n.selectedIds.size>0){let a=window.getSelection();if(!a||a.isCollapsed||a.toString().trim()===""){e.preventDefault();let d=n.tickets.filter(o=>n.selectedIds.has(o.id)).map(nt).join(`
3
3
 
4
- `);navigator.clipboard.writeText(d);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),g();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!i){e.preventDefault(),g();return}})}var z=0;function We(){async function e(){try{let t=await c(`/poll?version=${z}`);t.version>z&&(z=t.version,m())}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}Ne();})();
4
+ `);navigator.clipboard.writeText(d);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),v();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!s){e.preventDefault(),v();return}})}var j=0;function it(){async function e(){try{let t=await c(`/poll?version=${j}`);t.version>j&&(j=t.version,p())}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}ze();})();
@@ -1 +1 @@
1
- *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}:root{--bg: #ffffff;--bg-secondary: #f9fafb;--bg-hover: #f3f4f6;--bg-selected: #eff6ff;--border: #e5e7eb;--text: #111827;--text-secondary: #6b7280;--text-muted: #9ca3af;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--star: #eab308;--radius: 6px;--shadow: 0 1px 3px rgba(0,0,0,0.08)}html,body{height:100%;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:14px;line-height:1.5;color:var(--text);background:var(--bg)}button{cursor:pointer;border:none;background:none;font:inherit;color:inherit}input,select,textarea{font:inherit;color:inherit}.app{display:flex;flex-direction:column;height:100vh}.app-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;border-bottom:1px solid var(--border);background:var(--bg);gap:16px;flex-shrink:0}.app-header h1{font-size:18px;font-weight:700;white-space:nowrap}.header-controls{display:flex;align-items:center;gap:12px;flex:1;max-width:500px}.search-box{flex:1}.search-box input{width:100%;padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-secondary);outline:none}.search-box input:focus{border-color:var(--accent);background:var(--bg)}.sort-controls select{padding:6px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);cursor:pointer}.settings-btn{font-size:18px;color:var(--text-muted);padding:4px;border-radius:var(--radius);flex-shrink:0}.settings-btn:hover{color:var(--text);background:var(--bg-hover)}.app-body{display:flex;flex:1;overflow:hidden}.content-area{flex:1;display:flex;overflow:hidden;min-width:0}.content-area.detail-side{flex-direction:row}.content-area.detail-bottom{flex-direction:column}.sidebar{width:180px;border-right:1px solid var(--border);background:var(--bg-secondary);overflow-y:auto;flex-shrink:0;padding:8px 0}.sidebar-copy-prompt{padding:8px 10px 4px}.copy-prompt-btn{display:flex;align-items:center;gap:6px;width:100%;padding:6px 8px;font-size:12px;color:var(--text-secondary);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all .15s}.copy-prompt-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--bg-selected)}.copy-prompt-icon{display:flex;align-items:center;flex-shrink:0}.sidebar-section{margin-bottom:8px}.sidebar-label{padding:8px 16px 4px;font-size:11px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px}.sidebar-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 16px;text-align:left;font-size:13px;color:var(--text-secondary);border-radius:0}.sidebar-item:hover{background:var(--bg-hover);color:var(--text)}.sidebar-item.active{background:var(--bg-selected);color:var(--accent);font-weight:500}.cat-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.sidebar-stats{padding:12px 16px;font-size:12px;color:var(--text-muted);border-top:1px solid var(--border);margin-top:8px}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;min-height:0}.batch-toolbar{display:flex;align-items:center;gap:8px;padding:6px 16px 6px 19px;background:var(--bg-secondary);border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap;min-height:36px}.batch-toolbar select:disabled,.batch-toolbar .btn:disabled{opacity:.4;cursor:default;pointer-events:none}.batch-toolbar select{padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px}.batch-select-all{width:14px;height:14px;cursor:pointer;accent-color:var(--accent);flex-shrink:0}.batch-star-btn{font-size:16px;color:var(--text-muted);padding:2px 6px;border-radius:var(--radius);line-height:1}.batch-star-btn:hover:not(:disabled){color:var(--star);background:var(--bg-hover)}.batch-star-btn.active{color:var(--star)}.batch-star-btn.mixed{color:var(--star)}.batch-star-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.star-mixed-wrap{position:relative;display:inline-block}.star-mixed-fill{position:absolute;left:0;top:0;overflow:hidden;width:50%}.batch-delete-btn.btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px;border:none;background:none}.batch-count{font-size:12px;color:var(--text-muted);margin-left:auto;white-space:nowrap}.btn{padding:4px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;cursor:pointer}.btn:hover{background:var(--bg-hover)}.btn-sm{padding:3px 8px;font-size:11px}.btn-danger{color:var(--danger)}.btn-danger:hover:not(:disabled){background:#fef2f2}.ticket-list{flex:1;overflow-y:auto;padding:4px 0}.ticket-list-empty,.ticket-list-loading{padding:40px 20px;text-align:center;color:var(--text-muted);font-size:14px}.ticket-row{display:flex;align-items:center;gap:8px;padding:4px 16px;border-bottom:1px solid rgba(0,0,0,0);border-left:3px solid rgba(0,0,0,0);min-height:36px}.ticket-row:hover{background:var(--bg-hover)}.ticket-row.selected{background:var(--bg-selected)}.ticket-row.completed .ticket-title-input{text-decoration:line-through;color:var(--text-muted)}.ticket-row.up-next{border-left:3px solid var(--star)}.ticket-checkbox{flex-shrink:0;width:14px;height:14px;cursor:pointer;accent-color:var(--accent)}.ticket-status-btn{flex-shrink:0;width:20px;height:20px;font-size:14px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:var(--text-secondary)}.ticket-status-btn:hover{background:var(--bg-hover)}.ticket-status-btn.verified{color:#22c55e}.ticket-category-badge{flex-shrink:0;width:4em;padding:1px 0;border-radius:3px;font-size:10px;font-weight:600;color:#fff;text-transform:uppercase;text-align:center;cursor:pointer;letter-spacing:.3px}.ticket-category-badge:hover{opacity:.85}.ticket-number{flex-shrink:0;font-size:11px;color:var(--text-muted);font-family:"SF Mono",Monaco,"Cascadia Code",monospace;min-width:5em}.ticket-title-input{flex:1;border:none;background:rgba(0,0,0,0);padding:2px 0;outline:none;min-width:0}.ticket-title-input:focus{border-bottom:1px solid var(--accent)}.ticket-title-input::placeholder{color:var(--text-muted)}.ticket-priority-indicator{flex-shrink:0;font-size:12px;cursor:pointer;padding:2px 4px;border-radius:3px;min-width:24px;text-align:center}.ticket-priority-indicator:hover{background:var(--bg-hover)}.ticket-star{flex-shrink:0;font-size:16px;color:var(--text-muted);padding:0}.ticket-star.active{color:var(--star)}.ticket-star:hover{color:var(--star)}.trash-row .trash-title{flex:1;color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trash-row .btn{flex-shrink:0}.draft-row{border-bottom:1px dashed var(--border) !important;background:var(--bg-secondary)}.draft-row:hover{background:var(--bg-secondary)}.draft-row .draft-placeholder{opacity:.35;pointer-events:none}.draft-row .draft-badge{opacity:.35}.draft-row .draft-input::placeholder{color:var(--text-muted);font-style:italic}.ticket-checkbox-spacer{width:14px;flex-shrink:0}.detail-resize-handle{flex-shrink:0;background:rgba(0,0,0,0);position:relative;z-index:10}.detail-resize-handle:hover,.detail-resize-handle:active{background:var(--accent);opacity:.3}.detail-side .detail-resize-handle{width:4px;cursor:col-resize}.detail-bottom .detail-resize-handle{height:4px;cursor:row-resize}.detail-panel{border-left:1px solid var(--border);background:var(--bg);flex-shrink:0;display:flex;flex-direction:column;overflow:hidden}.detail-side .detail-panel{width:360px;border-left:1px solid var(--border);border-top:none}.detail-bottom .detail-panel{height:300px;width:auto;border-left:none;border-top:1px solid var(--border)}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600}.detail-ticket-number{font-family:"SF Mono",Monaco,"Cascadia Code",monospace;font-size:13px;color:var(--accent)}.detail-close{font-size:20px;color:var(--text-muted);padding:0 4px}.detail-close:hover{color:var(--text)}.detail-body{flex:1;overflow-y:auto;padding:16px}.detail-fields-row{display:contents}.detail-bottom .detail-body{display:flex;flex-wrap:wrap;gap:0 16px;align-content:flex-start}.detail-bottom .detail-body .detail-fields-row{display:flex;gap:16px;width:100%}.detail-bottom .detail-body .detail-fields-row .detail-field{flex:1;min-width:0}.detail-bottom .detail-body .detail-field-full{width:100%;flex-basis:100%}.detail-field{margin-bottom:16px}.detail-field label{display:block;font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.detail-field input[type=text],.detail-field textarea,.detail-field select{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.detail-field input[type=text]:focus,.detail-field textarea:focus,.detail-field select:focus{border-color:var(--accent)}.detail-field textarea{resize:vertical;min-height:80px}.detail-upnext-label{display:flex !important;align-items:center;gap:8px;cursor:pointer;font-size:14px !important;font-weight:400 !important;color:var(--text) !important}.detail-upnext-label input[type=checkbox]{width:auto;accent-color:var(--star)}.detail-attachments{margin-bottom:8px}.attachment-item{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--bg-secondary);border-radius:var(--radius);margin-bottom:4px;font-size:12px}.attachment-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-delete{color:var(--text-muted);font-size:16px;padding:0 4px;cursor:pointer;border:none;background:none}.attachment-delete:hover{color:var(--danger)}.upload-btn{cursor:pointer;display:inline-flex;align-items:center;gap:4px;margin-top:4px}.detail-meta{padding-top:12px;border-top:1px solid var(--border);font-size:11px;color:var(--text-muted)}.detail-meta div{margin-bottom:2px}.dropdown-menu{position:fixed;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:4px 0;min-width:140px}.dropdown-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 12px;text-align:left;font-size:13px;text-transform:capitalize}.dropdown-item:hover{background:var(--bg-hover)}.dropdown-item.active{color:var(--accent);font-weight:500}.dropdown-label{flex:1}.dropdown-kbd{font-size:11px;color:var(--text-muted);padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg-secondary);font-family:inherit;flex-shrink:0}.dropdown-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.settings-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.settings-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:380px;max-width:90vw}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}.settings-header h2{font-size:16px;font-weight:600}.settings-body{padding:20px}.settings-field{margin-bottom:16px}.settings-field:last-child{margin-bottom:0}.settings-field label{display:block;font-size:13px;font-weight:500;color:var(--text-secondary);margin-bottom:6px}.settings-field select,.settings-field input[type=number]{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.settings-field select:focus,.settings-field input[type=number]:focus{border-color:var(--accent)}.app-footer{display:flex;align-items:center;justify-content:space-between;padding:6px 20px;border-top:1px solid var(--border);background:var(--bg-secondary);font-size:12px;color:var(--text-muted);flex-shrink:0}.keyboard-hints{display:flex;gap:16px}.keyboard-hints kbd{display:inline-block;padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg);font-family:inherit;font-size:11px}.status-bar{font-size:12px}@media(max-width: 768px){.sidebar{width:140px}.detail-side .detail-panel{width:280px}.keyboard-hints{display:none}}@media(max-width: 600px){.sidebar{display:none}}.error-popup{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:3000}.error-popup-content{background:var(--bg);border:1px solid var(--danger);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);padding:24px;max-width:360px;text-align:center}.error-popup-content strong{display:block;font-size:16px;margin-bottom:8px;color:var(--danger)}.error-popup-content p{font-size:14px;color:var(--text-secondary);margin-bottom:16px}.error-popup-content button{padding:6px 16px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:13px;cursor:pointer}.error-popup-content button:hover{background:var(--bg-hover)}.detail-notes{display:flex;flex-direction:column;gap:8px}.note-entry{padding:8px 10px;background:var(--bg-secondary);border-radius:var(--radius);border-left:3px solid var(--accent)}.note-timestamp{font-size:11px;color:var(--text-muted);margin-bottom:2px}.note-text{font-size:13px;color:var(--text);white-space:pre-wrap}
1
+ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}:root{--bg: #ffffff;--bg-secondary: #f9fafb;--bg-hover: #f3f4f6;--bg-selected: #eff6ff;--border: #e5e7eb;--text: #111827;--text-secondary: #6b7280;--text-muted: #9ca3af;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--star: #eab308;--radius: 6px;--shadow: 0 1px 3px rgba(0,0,0,0.08)}html,body{height:100%;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:14px;line-height:1.5;color:var(--text);background:var(--bg)}button{cursor:pointer;border:none;background:none;font:inherit;color:inherit}input,select,textarea{font:inherit;color:inherit}.app{display:flex;flex-direction:column;height:100vh}.app-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;border-bottom:1px solid var(--border);background:var(--bg);gap:16px;flex-shrink:0}.app-header h1{font-size:18px;font-weight:700;white-space:nowrap}.header-controls{display:flex;align-items:center;gap:12px;flex:1;max-width:500px}.search-box{flex:1}.search-box input{width:100%;padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-secondary);outline:none}.search-box input:focus{border-color:var(--accent);background:var(--bg)}.layout-toggle{display:flex;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;flex-shrink:0}.layout-btn{display:flex;align-items:center;justify-content:center;padding:4px 8px;color:var(--text-secondary);background:var(--bg);border:none;border-right:1px solid var(--border);cursor:pointer}.layout-btn:last-child{border-right:none}.layout-btn:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.layout-btn.active{background:var(--bg-selected);color:var(--accent)}.layout-btn:disabled{cursor:default}.sort-controls select{padding:6px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);cursor:pointer}.settings-btn{font-size:18px;color:var(--text-muted);padding:4px;border-radius:var(--radius);flex-shrink:0}.settings-btn:hover{color:var(--text);background:var(--bg-hover)}.app-body{display:flex;flex:1;overflow:hidden}.content-area{flex:1;display:flex;overflow:hidden;min-width:0}.content-area.detail-side{flex-direction:row}.content-area.detail-bottom{flex-direction:column}.sidebar{width:180px;border-right:1px solid var(--border);background:var(--bg-secondary);overflow-y:auto;flex-shrink:0;padding:8px 0}.sidebar-copy-prompt{padding:8px 10px 4px}.copy-prompt-btn{display:flex;align-items:center;gap:6px;width:100%;padding:6px 8px;font-size:12px;color:var(--text-secondary);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all .15s}.copy-prompt-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--bg-selected)}.copy-prompt-icon{display:flex;align-items:center;flex-shrink:0}.sidebar-section{margin-bottom:8px}.sidebar-label{padding:8px 16px 4px;font-size:11px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px}.sidebar-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 16px;text-align:left;font-size:13px;color:var(--text-secondary);border-radius:0}.sidebar-item:hover{background:var(--bg-hover);color:var(--text)}.sidebar-item.active{background:var(--bg-selected);color:var(--accent);font-weight:500}.sidebar-item.drop-target{background:var(--bg-selected);color:var(--accent);outline:2px dashed var(--accent);outline-offset:-2px}.cat-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.sidebar-stats{padding:12px 16px;font-size:12px;color:var(--text-muted);border-top:1px solid var(--border);margin-top:8px}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;min-height:0}.batch-toolbar{display:flex;align-items:center;gap:8px;padding:6px 16px 6px 19px;background:var(--bg-secondary);border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap;min-height:36px}.batch-toolbar select:disabled,.batch-toolbar .btn:disabled{opacity:.4;cursor:default;pointer-events:none}.batch-toolbar select{padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px}.batch-select-all{width:14px;height:14px;cursor:pointer;accent-color:var(--accent);flex-shrink:0}.batch-star-btn{font-size:16px;color:var(--text-muted);padding:2px 6px;border-radius:var(--radius);line-height:1}.batch-star-btn:hover:not(:disabled){color:var(--star);background:var(--bg-hover)}.batch-star-btn.active{color:var(--star)}.batch-star-btn.mixed{color:var(--star)}.batch-star-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.star-mixed-wrap{position:relative;display:inline-block}.star-mixed-fill{position:absolute;left:0;top:0;overflow:hidden;width:50%}.batch-delete-btn.btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px;border:none;background:none}.batch-count{font-size:12px;color:var(--text-muted);margin-left:auto;white-space:nowrap}.btn{padding:4px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;cursor:pointer}.btn:hover{background:var(--bg-hover)}.btn-sm{padding:3px 8px;font-size:11px}.btn-danger{color:var(--danger)}.btn-danger:hover:not(:disabled){background:#fef2f2}.ticket-list{flex:1;overflow-y:auto;padding:4px 0}.ticket-list-empty,.ticket-list-loading{padding:40px 20px;text-align:center;color:var(--text-muted);font-size:14px}.ticket-row{display:flex;align-items:center;gap:8px;padding:4px 16px;border-bottom:1px solid rgba(0,0,0,0);border-left:3px solid rgba(0,0,0,0);min-height:36px}.ticket-row:hover{background:var(--bg-hover)}.ticket-row.selected{background:var(--bg-selected)}.ticket-row.completed .ticket-title-input{text-decoration:line-through;color:var(--text-muted)}.ticket-row.up-next{border-left:3px solid var(--star)}.ticket-checkbox{flex-shrink:0;width:14px;height:14px;cursor:pointer;accent-color:var(--accent)}.ticket-status-btn{flex-shrink:0;width:20px;height:20px;font-size:14px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:var(--text-secondary)}.ticket-status-btn:hover{background:var(--bg-hover)}.ticket-status-btn.verified{color:#22c55e}.ticket-category-badge{flex-shrink:0;width:4em;padding:1px 0;border-radius:3px;font-size:10px;font-weight:600;color:#fff;text-transform:uppercase;text-align:center;cursor:pointer;letter-spacing:.3px}.ticket-category-badge:hover{opacity:.85}.ticket-number{flex-shrink:0;font-size:11px;color:var(--text-muted);font-family:"SF Mono",Monaco,"Cascadia Code",monospace;min-width:5em}.ticket-title-input{flex:1;border:none;background:rgba(0,0,0,0);padding:2px 0;outline:none;min-width:0}.ticket-title-input:focus{border-bottom:1px solid var(--accent)}.ticket-title-input::placeholder{color:var(--text-muted)}.ticket-priority-indicator{flex-shrink:0;font-size:12px;cursor:pointer;padding:2px 4px;border-radius:3px;min-width:24px;text-align:center}.ticket-priority-indicator:hover{background:var(--bg-hover)}.ticket-star{flex-shrink:0;font-size:16px;color:var(--text-muted);padding:0}.ticket-star.active{color:var(--star)}.ticket-star:hover{color:var(--star)}.trash-row .trash-title{flex:1;color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trash-row .btn{flex-shrink:0}.draft-row{border-bottom:1px dashed var(--border) !important;background:var(--bg-secondary)}.draft-row:hover{background:var(--bg-secondary)}.draft-row .draft-placeholder{opacity:.35;pointer-events:none}.draft-row .draft-badge{opacity:.35}.draft-row .draft-input::placeholder{color:var(--text-muted);font-style:italic}.ticket-checkbox-spacer{width:14px;flex-shrink:0}.detail-resize-handle{flex-shrink:0;background:rgba(0,0,0,0);position:relative;z-index:10}.detail-resize-handle:hover,.detail-resize-handle:active{background:var(--accent);opacity:.3}.detail-side .detail-resize-handle{width:4px;cursor:col-resize}.detail-bottom .detail-resize-handle{height:4px;cursor:row-resize}.detail-panel{border-left:1px solid var(--border);background:var(--bg);flex-shrink:0;display:flex;flex-direction:column;overflow:hidden}.detail-side .detail-panel{width:360px;border-left:1px solid var(--border);border-top:none}.detail-bottom .detail-panel{height:300px;width:auto;border-left:none;border-top:1px solid var(--border)}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600}.detail-ticket-number{font-family:"SF Mono",Monaco,"Cascadia Code",monospace;font-size:13px;color:var(--accent)}.detail-close{font-size:20px;color:var(--text-muted);padding:0 4px}.detail-close:hover{color:var(--text)}.detail-body{flex:1;overflow-y:auto;padding:16px}.detail-fields-row{display:contents}.detail-bottom .detail-body{display:flex;flex-wrap:wrap;gap:0 16px;align-content:flex-start}.detail-bottom .detail-body .detail-fields-row{display:flex;gap:16px;width:100%}.detail-bottom .detail-body .detail-fields-row .detail-field{flex:1;min-width:0}.detail-bottom .detail-body .detail-field-full{width:100%;flex-basis:100%}.detail-field{margin-bottom:16px}.detail-field label{display:block;font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.detail-field input[type=text],.detail-field textarea,.detail-field select{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.detail-field input[type=text]:focus,.detail-field textarea:focus,.detail-field select:focus{border-color:var(--accent)}.detail-field textarea{resize:vertical;min-height:80px}.detail-upnext-label{display:flex !important;align-items:center;gap:8px;cursor:pointer;font-size:14px !important;font-weight:400 !important;color:var(--text) !important}.detail-upnext-label input[type=checkbox]{width:auto;accent-color:var(--star)}.detail-attachments{margin-bottom:8px}.attachment-item{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--bg-secondary);border-radius:var(--radius);margin-bottom:4px;font-size:12px}.attachment-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-delete{color:var(--text-muted);font-size:16px;padding:0 4px;cursor:pointer;border:none;background:none}.attachment-delete:hover{color:var(--danger)}.upload-btn{cursor:pointer;display:inline-flex;align-items:center;gap:4px;margin-top:4px}.detail-meta{padding-top:12px;border-top:1px solid var(--border);font-size:11px;color:var(--text-muted)}.detail-meta div{margin-bottom:2px}.dropdown-menu{position:fixed;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:4px 0;min-width:140px}.dropdown-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 12px;text-align:left;font-size:13px;text-transform:capitalize}.dropdown-item:hover{background:var(--bg-hover)}.dropdown-item.active{color:var(--accent);font-weight:500}.dropdown-label{flex:1}.dropdown-kbd{font-size:11px;color:var(--text-muted);padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg-secondary);font-family:inherit;flex-shrink:0}.dropdown-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.settings-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.settings-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:380px;max-width:90vw}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}.settings-header h2{font-size:16px;font-weight:600}.settings-body{padding:20px}.settings-field{margin-bottom:16px}.settings-field:last-child{margin-bottom:0}.settings-field label{display:block;font-size:13px;font-weight:500;color:var(--text-secondary);margin-bottom:6px}.settings-field select,.settings-field input[type=number]{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.settings-field select:focus,.settings-field input[type=number]:focus{border-color:var(--accent)}.app-footer{display:flex;align-items:center;justify-content:space-between;padding:6px 20px;border-top:1px solid var(--border);background:var(--bg-secondary);font-size:12px;color:var(--text-muted);flex-shrink:0}.keyboard-hints{display:flex;gap:16px}.keyboard-hints kbd{display:inline-block;padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg);font-family:inherit;font-size:11px}.status-bar{font-size:12px}.ticket-list-columns{display:flex;flex-direction:column;overflow:hidden}.ticket-list-columns .draft-row{flex-shrink:0}.columns-container{display:flex;flex:1;gap:1px;background:var(--border);overflow-x:auto;min-height:0}.column{flex:1;min-width:180px;display:flex;flex-direction:column;background:var(--bg-secondary);overflow:hidden}.column.column-drop-target{background:var(--bg-selected)}.column.column-drop-target .column-body{outline:2px dashed var(--accent);outline-offset:-2px}.column-header{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;font-size:12px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.3px;border-bottom:1px solid var(--border);background:var(--bg);flex-shrink:0}.column-count{font-size:11px;font-weight:500;color:var(--text-muted);background:var(--bg-secondary);padding:1px 6px;border-radius:10px}.column-body{flex:1;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:6px}.column-card{padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:grab;box-shadow:var(--shadow)}.column-card:hover{border-color:var(--accent)}.column-card.selected{border-color:var(--accent);background:var(--bg-selected)}.column-card.up-next{border-left:3px solid var(--star)}.column-card:active{cursor:grabbing}.column-card-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.column-card-title{font-size:13px;line-height:1.4;word-break:break-word}@media(max-width: 768px){.sidebar{width:140px}.detail-side .detail-panel{width:280px}.keyboard-hints{display:none}}@media(max-width: 600px){.sidebar{display:none}}.error-popup{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:3000}.error-popup-content{background:var(--bg);border:1px solid var(--danger);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);padding:24px;max-width:360px;text-align:center}.error-popup-content strong{display:block;font-size:16px;margin-bottom:8px;color:var(--danger)}.error-popup-content p{font-size:14px;color:var(--text-secondary);margin-bottom:16px}.error-popup-content button{padding:6px 16px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:13px;cursor:pointer}.error-popup-content button:hover{background:var(--bg-hover)}.detail-notes{display:flex;flex-direction:column;gap:8px}.note-entry{padding:8px 10px;background:var(--bg-secondary);border-radius:var(--radius);border-left:3px solid var(--accent)}.note-timestamp{font-size:11px;color:var(--text-muted);margin-bottom:2px}.note-text{font-size:13px;color:var(--text);white-space:pre-wrap}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hotsheet",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "A lightweight local project management tool. Create, categorize, and prioritize tickets with a fast bullet-list interface, then export an Up Next worklist for AI tools.",
5
5
  "type": "module",
6
6
  "license": "MIT",