diff --git a/README.md b/README.md index ff7939e..49fabf1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # InvoiceShelf Tasks and Projects -The official Tasks, Projects and Time Tracking module for InvoiceShelf 3.x. It adds projects hung -off a customer, tasks that move across a configurable Kanban board, time recorded by hand or by a -running timer, and invoicing that turns unbilled hours into a draft invoice from wherever the -work is: a task, a selection of tasks, a whole project, or the unbilled time page. +The official Tasks, Projects and Time Tracking module for InvoiceShelf 3.x. It adds two sidebar +entries, Projects and Tasks, and builds invoicing the way Invoice Ninja does it: pick the work +(a task, a selection of tasks, or a whole project) and land on a draft invoice, rather than +picking a customer first and hunting for what to bill. The module is `AGPL-3.0-only`. @@ -16,17 +16,45 @@ The module is `AGPL-3.0-only`. ## What it adds - **Projects.** Name, optional customer, description, colour, status, default billable rate, - budget and due date. A project without a customer is internal and never reaches the billing - screen. -- **Tasks and a Kanban board.** Tasks belong to a project or stand alone against a customer, and - move across per-company task statuses with drag ordering. -- **Time tracking.** Manual time entries or a running timer, one per user per company, with a - header chip showing elapsed time. -- **Rate resolution.** Task rate, then the assignee's project rate, then the project default, then - the company default from module settings, written onto the time entry so a later rate change - never rewrites history. -- **Task to invoice.** Review unbilled billable entries, choose a grouping, and produce a draft - invoice through the host's own invoice endpoint. + budget and due date, reachable from its own sidebar entry. A project without a customer is + internal and never reaches the billing screens. +- **Tasks, with three views over one filter.** The Tasks screen is the module's sidebar root: a + view switcher moves between a sortable **List**, a **Board** with drag ordering across the + company's task statuses, and a **Week** timesheet, and the project, member and status filters + in the address bar survive every switch. A task also has its own page, with the time log + underneath it. +- **Time tracking, everywhere a task appears.** Start or stop a task's timer from its row in the + list, its card on the board, its own page, or the floating quick-start button that stays + reachable from any screen (it search-picks a task by name and starts or stops on it without + leaving the page you are on). Only one timer runs per user per company; starting a second one + offers to stop the first. A header chip shows the elapsed time and opens the running task. +- **The task time log.** A task's own page lists every interval logged against it, hand-entered + or from the timer: start, end, duration, description, billable, and who logged it. A row + already on an invoice is marked and its time, billable flag and task cannot change; its + description still can. +- **Rate resolution.** Task rate, then the assignee's project rate, then the project default, + then the company default from module settings, written onto the time entry so a later rate + change never rewrites history. +- **Invoicing from the work, not from a wizard.** "Invoice" on a task row, the bulk selection + bar, a task's own page, or a project's header prepares a draft invoice, one line per task, and + opens it on the host's own invoice edit screen, ready to review and send. A selection spanning + two customers or two currencies is refused with a clear message instead of guessing. The + **Unbilled time** page (linked from Reports and from the Projects header) answers the + month-end question across every project and customer at once, and is where a single entry can + still be left off an invoice on purpose. +- **Settings**, under **Company Settings → Tasks and Projects**: the default hourly rate, the + rounding increment and whether a stopped entry rounds to the nearest increment, up, or down, + the first day of the week, whether members see each other's time, whether creating a task + starts its creator's timer, whether an invoiced task locks against further edits, whether an + invoiced task drops off the board, and which parts of an invoice line an invoiced task writes + (a project heading, the task's own description, and each entry's date, time range, hours and + description). The module's own settings page under the module menu shows the current value of + every one of these next to a link to the form that edits them. +- **Abilities.** `view-project`, `create-project`, `edit-project` and `delete-project`; + `view-task`, `create-task`, `edit-task`, `delete-task` and `manage-task-status`; `view-own-time`, + `view-all-time` and `edit-all-time`; and `invoice-tasks`, which also requires the host's own + `create-invoice` and `edit-invoice` abilities, because invoicing a task ends on the host's + invoice edit page. See [`specs/tasks-projects.md`](../specs/tasks-projects.md) in the private specs repository for the full scope and data model. @@ -36,8 +64,9 @@ full scope and data model. 1. Sign in as a super administrator and open **Administration → Modules**. 2. Pair the application with the InvoiceShelf marketplace if it is not already paired, then install and enable **Tasks and Projects**. -3. Open **Company Settings → Tasks and Projects** to set the default hourly rate, rounding - increment, week start day, and whether non-owners may see other members' time. +3. Open **Company Settings → Tasks and Projects** to set the default hourly rate, the rounding + increment and direction, the first day of the week, who may see other members' time, and the + task and invoice-line behaviour described above. ## Disable and uninstall diff --git a/app/Application/InvoiceLineComposer.php b/app/Application/InvoiceLineComposer.php index c00b335..d6734c4 100644 --- a/app/Application/InvoiceLineComposer.php +++ b/app/Application/InvoiceLineComposer.php @@ -140,7 +140,8 @@ private function capped(array $heading, array $lines): string while ($kept !== []) { array_pop($kept); $dropped = count($lines) - count($kept); - $note = implode("\n", [...$heading, ...$kept, 'and '.$dropped.' more entries']); + $summary = 'and '.$dropped.' more '.($dropped === 1 ? 'entry' : 'entries'); + $note = implode("\n", [...$heading, ...$kept, $summary]); if (mb_strlen($note) <= self::MAX_LENGTH) { return $note; diff --git a/app/Support/ModuleRegistration.php b/app/Support/ModuleRegistration.php index 44e7c37..5fa910c 100644 --- a/app/Support/ModuleRegistration.php +++ b/app/Support/ModuleRegistration.php @@ -32,7 +32,7 @@ public static function register(string $modulePath): void */ private static function registerMenu(): void { - Registry::registerMenu('tasks-projects', [ + Registry::registerMenu('tasks-projects.projects', [ 'title' => 'tasksprojects::menu.projects', 'link' => '/admin/modules/tasks-projects/projects', 'icon' => 'FolderIcon', @@ -42,7 +42,7 @@ private static function registerMenu(): void 'priority' => 40, ]); - Registry::registerMenu('tasks-projects.tasks', [ + Registry::registerMenu('tasks-projects', [ 'title' => 'tasksprojects::menu.tasks', 'link' => '/admin/modules/tasks-projects', 'icon' => 'ClipboardDocumentListIcon', @@ -87,11 +87,7 @@ private static function settingsSchema(): array 'type' => FieldType::Select->value, 'label' => 'tasksprojects::settings.rounding_direction', 'default' => ModuleSettings::DEFAULT_ROUNDING_DIRECTION, - 'options' => [ - Rounding::NEAREST => 'tasksprojects::settings.rounding_nearest', - Rounding::UP => 'tasksprojects::settings.rounding_up', - Rounding::DOWN => 'tasksprojects::settings.rounding_down', - ], + 'options' => self::directionOptions(), ], [ 'key' => 'week_start', @@ -144,6 +140,24 @@ private static function switchField(string $key): array ]; } + /** + * The rounding directions, already in the reader's language. + * + * The host translates a field's label and a section's title, but hands a + * select's options to the form as they were registered, so an option that + * named a translation key would reach the screen as the key itself. + * + * @return array + */ + private static function directionOptions(): array + { + return [ + Rounding::NEAREST => __('tasksprojects::settings.rounding_nearest'), + Rounding::UP => __('tasksprojects::settings.rounding_up'), + Rounding::DOWN => __('tasksprojects::settings.rounding_down'), + ]; + } + /** @return array */ private static function roundingOptions(): array { diff --git a/dist/init.js b/dist/init.js index 6af062e..ea58e9b 100644 --- a/dist/init.js +++ b/dist/init.js @@ -174,7 +174,7 @@ var te = { class: "flex w-full items-center justify-between" }, ne = { class: "s mixed_selection: "One invoice covers one customer in one currency. Narrow the selection.", pending_stamp: "Finish marking the last invoice as billed before creating another one.", created: "Invoice {number} was created.", - stamped: "{count} time entries were marked as invoiced.", + stamped: "{count} time entry was marked as invoiced. | {count} time entries were marked as invoiced.", stamp_failed: "Unable to mark the time as invoiced.", stamp_failed_notice: "Invoice {number} was created, but its time is not marked as invoiced yet.", stamp_unmatched: "Invoice {number} was created, but its lines could not be matched back to the time behind them.", @@ -195,7 +195,7 @@ var te = { class: "flex w-full items-center justify-between" }, ne = { class: "s customer: { title: "Who has time waiting?", description: "Customers with billable time that has not reached an invoice yet.", - entries: "{count} entries", + entries: "{count} entry | {count} entries", empty_title: "Nothing to invoice", empty_description: "Billable time appears here once it has been logged against a task that belongs to a customer.", load_failed: "Unable to load the customers with unbilled time.", @@ -1307,7 +1307,7 @@ async function mr(e, t) { async function hr(e, t) { let { data: n } = await e.post(ir.bulkTasks, t); return { - updated: n?.updated ?? 0, + updated: n?.updated ?? [], failed: n?.failed ?? [] }; } @@ -2831,13 +2831,13 @@ var Xi = { class: "mt-4 flex flex-wrap items-end gap-3" }, Zi = { let t = l.task, n = t ? await lr(l.client, t.id, e) : await cr(l.client, e); u("saved", n); } catch (e) { - w.value = at(e), l.notify("error", H(e, re(e, "save_failed"))); + w.value = at(e), l.notify("error", re(e, "save_failed")); } finally { T.value = !1; } } function re(e, t) { - return gt(e) === "task_locked" ? d("tasks_projects.tasks.locked") : d(`tasks_projects.tasks.${t}`); + return gt(e) === "task_locked" ? d("tasks_projects.tasks.locked") : H(e, d(`tasks_projects.tasks.${t}`)); } async function ie() { let e = l.task; @@ -2846,7 +2846,7 @@ var Xi = { class: "mt-4 flex flex-wrap items-end gap-3" }, Zi = { try { await ur(l.client, e.id), u("deleted", e); } catch (e) { - l.notify("error", H(e, re(e, "delete_failed"))); + l.notify("error", re(e, "delete_failed")); } finally { O.value = !1; } @@ -3673,9 +3673,10 @@ var K = { try { let n = await hr(d.client, e); n.failed.length > 0 ? d.notify("warning", g("tasks_projects.tasks.bulk.partial", { - count: n.updated, - failed: n.failed.length - })) : n.updated === 0 ? d.notify("warning", g("tasks_projects.tasks.bulk.nothing")) : d.notify("success", g(`tasks_projects.tasks.bulk.${t}`, { count: n.updated })), ce(), V(), m("changed"); + count: n.updated.length, + failed: n.failed.length, + ids: n.failed.map((e) => `#${e.id}`).join(", ") + })) : n.updated.length === 0 ? d.notify("warning", g("tasks_projects.tasks.bulk.nothing")) : d.notify("success", g(`tasks_projects.tasks.bulk.${t}`, { count: n.updated.length })), ce(), V(), m("changed"); } catch (e) { d.notify("error", H(e, g("tasks_projects.tasks.bulk.failed"))); } finally { @@ -5062,10 +5063,10 @@ var Ks = { en: { tasks_projects: { change_status: "Move to", delete: "Delete", invoice: "Invoice", - delete_confirm: "Delete {count} tasks? Their time entries go with them.", - applied: "{count} tasks were updated.", - deleted: "{count} tasks were deleted.", - partial: "{count} tasks were updated, {failed} were refused.", + delete_confirm: "Delete {count} task? Its time entries go with it. | Delete {count} tasks? Their time entries go with them.", + applied: "{count} task was updated. | {count} tasks were updated.", + deleted: "{count} task was deleted. | {count} tasks were deleted.", + partial: "{count} task was updated, {failed} refused: {ids}. | {count} tasks were updated, {failed} refused: {ids}.", nothing: "No task was changed.", failed: "Unable to apply the change." }, @@ -5356,7 +5357,7 @@ var Ks = { en: { tasks_projects: { }), R = n({ get: () => P.value.find((e) => e.id === m.value?.task_status_id) ?? null, set: (e) => { - e !== null && oe(e); + e !== null && se(e); } }), z = n(() => M.busy), ee = n(() => j.value.invoiced === "uninvoiced"), te = n(() => j.value.invoiced === "invoiced" ? d("tasks_projects.tasks.already_invoiced") : d("tasks_projects.tasks.nothing_to_invoice")), ne = n(() => m.value?.priority ? d(`tasks_projects.tasks.priority.${m.value.priority.toLowerCase()}`) : null); E(A, () => void re()), E(et, () => void re(!0)), h(() => { @@ -5413,7 +5414,10 @@ var Ks = { en: { tasks_projects: { ...t }; } - async function oe(e) { + function oe(e, t) { + return gt(e) === "task_locked" ? d("tasks_projects.tasks.locked") : H(e, d(t)); + } + async function se(e) { let t = m.value; if (t === null || T.value || t.task_status_id === e.id) return; let n = t.task_status_id; @@ -5421,12 +5425,12 @@ var Ks = { en: { tasks_projects: { try { m.value = await lr(l.client, t.id, ae(t, { task_status_id: e.id })), l.notify("success", d("tasks_projects.tasks.detail.status_saved", { name: e.label })), V(); } catch (e) { - t.task_status_id = n, l.notify("error", H(e, gt(e) === "task_locked" ? d("tasks_projects.tasks.locked") : d("tasks_projects.tasks.detail.status_failed"))); + t.task_status_id = n, l.notify("error", oe(e, "tasks_projects.tasks.detail.status_failed")); } finally { T.value = !1; } } - async function se() { + async function ce() { let e = m.value; e !== null && ee.value && !z.value && await bt({ client: l.client, @@ -5435,20 +5439,20 @@ var Ks = { en: { tasks_projects: { t: d }, { taskIds: [e.id] }); } - function ce() { + function le() { p.push(W.tasks); } - function le(e) { + function ue(e) { k.value = !1, m.value = e, Qe(e), l.notify("success", d("tasks_projects.tasks.updated", { name: e.name })), V(); } - async function ue() { + async function de() { let e = m.value; if (!(e === null || O.value) && window.confirm(d("tasks_projects.tasks.delete_confirm", { name: e.name }))) { O.value = !0; try { - await ur(l.client, e.id), l.notify("success", d("tasks_projects.tasks.deleted", { name: e.name })), V(), ce(); + await ur(l.client, e.id), l.notify("success", d("tasks_projects.tasks.deleted", { name: e.name })), V(), le(); } catch (e) { - l.notify("error", H(e, gt(e) === "task_locked" ? d("tasks_projects.tasks.locked") : d("tasks_projects.tasks.delete_failed"))); + l.notify("error", oe(e, "tasks_projects.tasks.delete_failed")); } finally { O.value = !1; } @@ -5480,7 +5484,7 @@ var Ks = { en: { tasks_projects: { variant: "white", loading: z.value, disabled: !ee.value || z.value, - onClick: se + onClick: ce }, { left: D((e) => [z.value ? i("", !0) : (_(), r(b, { key: 0, @@ -5494,7 +5498,7 @@ var Ks = { en: { tasks_projects: { variant: "primary-outline", loading: O.value, disabled: O.value, - onClick: ue + onClick: de }, { default: D(() => [s(S(C(d)("tasks_projects.general.delete")), 1)]), _: 1 @@ -5614,8 +5618,8 @@ var Ks = { en: { tasks_projects: { members: v.value, projects: F.value, onClose: l[2] ||= (e) => k.value = !1, - onSaved: le, - onDeleted: ce + onSaved: ue, + onDeleted: le }, null, 8, [ "show", "client", @@ -7833,174 +7837,184 @@ function Mf(e) { } //#endregion //#region resources/js/components/QuickStartOverlay.vue?vue&type=script&setup=true&lang.ts -var Nf = { - key: 0, - class: "fixed right-6 bottom-20 z-40 flex flex-col items-end gap-3" -}, Pf = ["aria-label"], Ff = { class: "flex items-center justify-between border-b border-line-default px-4 py-3" }, If = { class: "text-sm font-semibold text-heading" }, Lf = ["aria-label"], Rf = { +var Nf = ["aria-label"], Pf = { class: "flex items-center justify-between border-b border-line-default px-4 py-3" }, Ff = { class: "text-sm font-semibold text-heading" }, If = ["aria-label"], Lf = { key: 0, class: "space-y-4 px-4 py-4" -}, zf = { class: "truncate text-sm font-medium text-heading" }, Bf = { class: "mt-1 text-2xl font-semibold tabular-nums text-primary-500" }, Vf = { +}, Rf = { class: "truncate text-sm font-medium text-heading" }, zf = { class: "mt-1 text-2xl font-semibold tabular-nums text-primary-500" }, Bf = { key: 0, class: "mt-1 text-xs text-muted" -}, Hf = { class: "flex items-center gap-2" }, Uf = { +}, Vf = { class: "flex items-center gap-2" }, Hf = { key: 1, class: "space-y-3 px-4 py-4" -}, Wf = { class: "block" }, Gf = { class: "sr-only" }, Kf = ["placeholder"], qf = { +}, Uf = { class: "block" }, Wf = { class: "sr-only" }, Gf = ["placeholder"], Kf = { key: 0, class: "text-xs text-muted" -}, Jf = { +}, qf = { key: 1, class: "max-h-48 space-y-1 overflow-y-auto" -}, Yf = ["onClick"], Xf = { +}, Jf = ["onClick"], Yf = { key: 2, class: "text-xs text-muted" -}, Zf = ["placeholder", "aria-label"], Qf = { class: "flex items-center justify-between" }, $f = ["title", "aria-label"], ep = { +}, Xf = ["placeholder", "aria-label"], Zf = { class: "flex items-center justify-between" }, Qf = ["title", "aria-label"], $f = { key: 0, class: "tabular-nums" -}, tp = 300, np = /* @__PURE__ */ l({ +}, ep = "[aria-label=\"Open AI Assistant\"]", tp = "/admin/settings", np = 300, rp = /* @__PURE__ */ l({ __name: "QuickStartOverlay", props: { client: { type: [Function, Object] }, notify: { type: Function }, - enabled: { type: Boolean } + enabled: { type: Boolean }, + router: {} }, emits: ["open-week"], setup(l, { emit: u }) { - let d = l, p = u, h = B(), g = y(!1), v = y(""), T = y([]), A = y(!1), j = y(null), M = y(""), N, P = n(() => ({ + let d = l, p = u, g = B(), v = y(!1), T = y(""), A = y([]), j = y(!1), M = y(null), N = y(""), P = y(window.location.pathname), F = y(!1), I, L, R = n(() => ({ notify: d.notify, - t: h - })), F = n(() => Ze(K.running?.task_id ?? null)), I = n(() => Na(K.elapsedSeconds)); + t: g + })), z = n(() => Ze(K.running?.task_id ?? null)), ee = n(() => Na(K.elapsedSeconds)), te = n(() => P.value.startsWith(tp)), ne = n(() => F.value ? "bottom-36" : "bottom-20"); + function re() { + F.value = Array.from(document.querySelectorAll(ep)).some((e) => window.getComputedStyle(e).position === "fixed"); + } E(() => d.enabled, (e) => { - e || z(); - }), E(g, (e) => { - e && K.running === null && L(); - }), E(v, () => { - clearTimeout(N), N = setTimeout(() => void L(), tp); - }), m(() => clearTimeout(N)); - async function L() { - A.value = !0; + e || oe(); + }), h(() => { + P.value = d.router.currentRoute.value.path, L = d.router.afterEach((e) => { + P.value = e.path, re(); + }), re(); + }), E(v, (e) => { + e && K.running === null && ie(); + }), E(T, () => { + clearTimeout(I), I = setTimeout(() => void ie(), np); + }), m(() => { + clearTimeout(I), L?.(); + }); + async function ie() { + j.value = !0; try { - let e = await Ve(d.client, v.value); - T.value = e, e.forEach(Qe); + let e = await Ve(d.client, T.value); + A.value = e, e.forEach(Qe); } catch (e) { - T.value = [], d.notify("error", H(e, h("tasks_projects.time.tasks_failed"))); + A.value = [], d.notify("error", H(e, g("tasks_projects.time.tasks_failed"))); } finally { - A.value = !1; + j.value = !1; } } - function R(e) { - j.value = e, Qe(e); + function ae(e) { + M.value = e, Qe(e); } - function z() { - g.value = !1, v.value = "", T.value = [], j.value = null, M.value = ""; + function oe() { + v.value = !1, T.value = "", A.value = [], M.value = null, N.value = ""; } - async function ee() { - let e = j.value; - e !== null && await K.start(d.client, e.id, M.value.trim() || null, P.value) !== null && (d.notify("success", h("tasks_projects.timer.started", { name: e.name })), z()); + async function se() { + let e = M.value; + e !== null && await K.start(d.client, e.id, N.value.trim() || null, R.value) !== null && (d.notify("success", g("tasks_projects.timer.started", { name: e.name })), oe()); } - async function te() { - let e = F.value, t = await K.stop(d.client, P.value); - t !== null && (d.notify("success", h("tasks_projects.timer.stopped", { + async function ce() { + let e = z.value, t = await K.stop(d.client, R.value); + t !== null && (d.notify("success", g("tasks_projects.timer.stopped", { name: e, duration: Pa(t.duration_minutes) - })), z()); + })), oe()); } - async function ne() { - window.confirm(h("tasks_projects.timer.discard_confirm")) && await K.discard(d.client, P.value) && (d.notify("success", h("tasks_projects.timer.discarded")), z()); + async function le() { + window.confirm(g("tasks_projects.timer.discard_confirm")) && await K.discard(d.client, R.value) && (d.notify("success", g("tasks_projects.timer.discarded")), oe()); } return (n, u) => { let d = x("BaseIcon"), m = x("BaseButton"); - return _(), r(t, { to: "body" }, [l.enabled ? (_(), a("div", Nf, [g.value ? (_(), a("section", { + return _(), r(t, { to: "body" }, [l.enabled && !te.value ? (_(), a("div", { + key: 0, + class: f(["fixed right-6 z-40 flex flex-col items-end gap-3", ne.value]) + }, [v.value ? (_(), a("section", { key: 0, class: "w-80 max-w-[calc(100vw-3rem)] rounded-xl border border-line-default bg-surface shadow-2xl", - "aria-label": C(h)("tasks_projects.timer.panel_title"), - onKeydown: k(z, ["esc"]) - }, [o("header", Ff, [o("h2", If, S(C(h)("tasks_projects.timer.panel_title")), 1), o("button", { + "aria-label": C(g)("tasks_projects.timer.panel_title"), + onKeydown: k(oe, ["esc"]) + }, [o("header", Pf, [o("h2", Ff, S(C(g)("tasks_projects.timer.panel_title")), 1), o("button", { type: "button", class: "rounded p-1 text-subtle hover:bg-hover hover:text-heading", - "aria-label": C(h)("tasks_projects.timer.close"), - onClick: z + "aria-label": C(g)("tasks_projects.timer.close"), + onClick: oe }, [c(d, { name: "XMarkIcon", class: "h-5 w-5" - })], 8, Lf)]), C(K).running === null ? (_(), a("div", Uf, [ - o("label", Wf, [o("span", Gf, S(C(h)("tasks_projects.timer.search_tasks")), 1), O(o("input", { - "onUpdate:modelValue": u[0] ||= (e) => v.value = e, + })], 8, If)]), C(K).running === null ? (_(), a("div", Hf, [ + o("label", Uf, [o("span", Wf, S(C(g)("tasks_projects.timer.search_tasks")), 1), O(o("input", { + "onUpdate:modelValue": u[0] ||= (e) => T.value = e, type: "search", autocomplete: "off", class: "w-full rounded-md border border-line-default bg-surface px-3 py-2 text-sm text-body outline-hidden focus:border-primary-400 focus:ring-1 focus:ring-primary-400", - placeholder: C(h)("tasks_projects.timer.search_tasks") - }, null, 8, Kf), [[w, v.value]])]), - A.value ? (_(), a("p", qf, S(C(h)("tasks_projects.general.search")), 1)) : T.value.length > 0 ? (_(), a("ul", Jf, [(_(!0), a(e, null, b(T.value, (e) => (_(), a("li", { key: e.id }, [o("button", { + placeholder: C(g)("tasks_projects.timer.search_tasks") + }, null, 8, Gf), [[w, T.value]])]), + j.value ? (_(), a("p", Kf, S(C(g)("tasks_projects.general.search")), 1)) : A.value.length > 0 ? (_(), a("ul", qf, [(_(!0), a(e, null, b(A.value, (e) => (_(), a("li", { key: e.id }, [o("button", { type: "button", - class: f(["w-full truncate rounded-md px-2 py-2 text-left text-sm hover:bg-hover", j.value?.id === e.id ? "bg-hover-strong font-medium text-heading" : "text-body"]), - onClick: (t) => R(e) - }, S(e.name), 11, Yf)]))), 128))])) : (_(), a("p", Xf, S(C(h)("tasks_projects.timer.no_tasks")), 1)), + class: f(["w-full truncate rounded-md px-2 py-2 text-left text-sm hover:bg-hover", M.value?.id === e.id ? "bg-hover-strong font-medium text-heading" : "text-body"]), + onClick: (t) => ae(e) + }, S(e.name), 11, Jf)]))), 128))])) : (_(), a("p", Yf, S(C(g)("tasks_projects.timer.no_tasks")), 1)), O(o("input", { - "onUpdate:modelValue": u[1] ||= (e) => M.value = e, + "onUpdate:modelValue": u[1] ||= (e) => N.value = e, type: "text", class: "w-full rounded-md border border-line-default bg-surface px-3 py-2 text-sm text-body outline-hidden focus:border-primary-400 focus:ring-1 focus:ring-primary-400", - placeholder: C(h)("tasks_projects.timer.description_placeholder"), - "aria-label": C(h)("tasks_projects.time.fields.description") - }, null, 8, Zf), [[w, M.value]]), - o("div", Qf, [o("button", { + placeholder: C(g)("tasks_projects.timer.description_placeholder"), + "aria-label": C(g)("tasks_projects.time.fields.description") + }, null, 8, Xf), [[w, N.value]]), + o("div", Zf, [o("button", { type: "button", class: "text-xs text-primary-500 hover:underline", onClick: u[2] ||= (e) => p("open-week") - }, S(C(h)("tasks_projects.timer.open_timesheet")), 1), c(m, { + }, S(C(g)("tasks_projects.timer.open_timesheet")), 1), c(m, { variant: "primary", - disabled: j.value === null || C(K).busy, - onClick: ee + disabled: M.value === null || C(K).busy, + onClick: se }, { left: D((e) => [c(d, { name: "PlayIcon", class: f(e.class) }, null, 8, ["class"])]), - default: D(() => [s(" " + S(C(h)("tasks_projects.timer.start")), 1)]), + default: D(() => [s(" " + S(C(g)("tasks_projects.timer.start")), 1)]), _: 1 }, 8, ["disabled"])]) - ])) : (_(), a("div", Rf, [o("div", null, [ - o("p", zf, S(F.value), 1), - o("p", Bf, S(I.value), 1), - C(K).running.description ? (_(), a("p", Vf, S(C(K).running.description), 1)) : i("", !0) - ]), o("div", Hf, [c(m, { + ])) : (_(), a("div", Lf, [o("div", null, [ + o("p", Rf, S(z.value), 1), + o("p", zf, S(ee.value), 1), + C(K).running.description ? (_(), a("p", Bf, S(C(K).running.description), 1)) : i("", !0) + ]), o("div", Vf, [c(m, { variant: "primary", disabled: C(K).busy, - onClick: te + onClick: ce }, { left: D((e) => [c(d, { name: "StopIcon", class: f(e.class) }, null, 8, ["class"])]), - default: D(() => [s(" " + S(C(h)("tasks_projects.timer.stop")), 1)]), + default: D(() => [s(" " + S(C(g)("tasks_projects.timer.stop")), 1)]), _: 1 }, 8, ["disabled"]), c(m, { variant: "primary-outline", disabled: C(K).busy, - onClick: ne + onClick: le }, { - default: D(() => [s(S(C(h)("tasks_projects.timer.discard")), 1)]), + default: D(() => [s(S(C(g)("tasks_projects.timer.discard")), 1)]), _: 1 - }, 8, ["disabled"])])]))], 40, Pf)) : i("", !0), o("button", { + }, 8, ["disabled"])])]))], 40, Nf)) : i("", !0), o("button", { type: "button", class: "flex items-center gap-2 rounded-full bg-btn-primary px-4 py-3 text-sm font-medium text-white shadow-lg hover:bg-btn-primary-hover", - title: C(h)("tasks_projects.timer.quick_start"), - "aria-label": C(h)("tasks_projects.timer.quick_start"), - onClick: u[3] ||= (e) => g.value = !g.value + title: C(g)("tasks_projects.timer.quick_start"), + "aria-label": C(g)("tasks_projects.timer.quick_start"), + onClick: u[3] ||= (e) => v.value = !v.value }, [c(d, { name: C(K).running === null ? "ClockIcon" : "StopIcon", class: "h-5 w-5 text-white" - }, null, 8, ["name"]), C(K).running === null ? i("", !0) : (_(), a("span", ep, S(I.value), 1))], 8, $f)])) : i("", !0)]); + }, null, 8, ["name"]), C(K).running === null ? i("", !0) : (_(), a("span", $f, S(ee.value), 1))], 8, Qf)], 2)) : i("", !0)]); }; } -}), rp = { +}), ip = { key: 0, class: "relative float-left m-0 ml-2" -}, ip = ["title"], ap = ["aria-label", "title"], op = { class: "font-medium tabular-nums" }, sp = [ +}, ap = ["title"], op = ["aria-label", "title"], sp = { class: "font-medium tabular-nums" }, cp = [ "disabled", "title", "aria-label" -], cp = /* @__PURE__ */ l({ +], lp = /* @__PURE__ */ l({ __name: "TimerChip", props: { client: { type: [Function, Object] }, @@ -8021,7 +8035,7 @@ var Nf = { } return (e, t) => { let n = x("BaseIcon"); - return C(K).running === null ? i("", !0) : (_(), a("li", rp, [o("div", { + return C(K).running === null ? i("", !0) : (_(), a("li", ip, [o("div", { class: "flex h-8 items-center gap-2 rounded-lg bg-white/20 px-2 text-sm text-white md:h-9 md:px-3", title: C(l)("tasks_projects.timer.running") }, [ @@ -8032,8 +8046,8 @@ var Nf = { "aria-label": C(l)("tasks_projects.timer.open_task"), title: C(l)("tasks_projects.timer.open_task"), onClick: t[0] ||= (e) => s("open") - }, S(u.value), 9, ap), - o("span", op, S(d.value), 1), + }, S(u.value), 9, op), + o("span", sp, S(d.value), 1), o("button", { type: "button", class: "rounded p-1 hover:bg-white/20 disabled:opacity-50", @@ -8044,11 +8058,11 @@ var Nf = { }, [c(n, { name: "StopIcon", class: "h-4 w-4 text-white" - })], 8, sp) - ], 8, ip)])); + })], 8, cp) + ], 8, ap)])); }; } -}), lp = { en: { tasks_projects: { +}), up = { en: { tasks_projects: { time: { title: "Time", my_time: "My time", @@ -8156,6 +8170,16 @@ var Nf = { general_title: "General", general_description: "The default hourly rate, the rounding increment, the first day of the week and who may see other members time.", open_module_settings: "Open module settings", + default_rate: "Default rate / hour", + week_start: "First day of the week", + weekday_0: "Sunday", + weekday_1: "Monday", + weekday_2: "Tuesday", + weekday_3: "Wednesday", + weekday_4: "Thursday", + weekday_5: "Friday", + weekday_6: "Saturday", + members_see_all_time: "Members see other members' time", behaviour_title: "Task behaviour", behaviour_description: "What happens when a task is created, invoiced or shown on the board. Change these in the module settings form.", rounding_direction: "Rounding", @@ -8163,7 +8187,7 @@ var Nf = { rounding_direction_up: "Up to the increment", rounding_direction_down: "Down to the increment", rounding_increment: "Increment", - rounding_increment_value: "{count} minutes", + rounding_increment_value: "{count} minute | {count} minutes", auto_start_tasks: "Start the timer on a new task", lock_invoiced_tasks: "Lock invoiced tasks", hide_invoiced_on_board: "Hide invoiced tasks on the board", @@ -8201,47 +8225,47 @@ var Nf = { reorder_failed: "Unable to save the new order.", forbidden: "Your role does not allow managing the board columns." } -} } }, up = { +} } }, dp = { key: 0, class: "text-sm text-muted" -}, dp = { key: 1 }, fp = { +}, fp = { key: 1 }, pp = { key: 0, class: "flex items-center gap-2 text-sm text-muted" -}, pp = { +}, mp = { key: 1, class: "text-sm text-muted" -}, mp = { +}, hp = { key: 2, class: "divide-y divide-line-light" -}, hp = { +}, gp = { key: 0, class: "space-y-3" -}, gp = { class: "flex flex-wrap items-center gap-2" }, _p = ["aria-label", "onClick"], vp = { class: "flex flex-wrap items-center gap-6" }, yp = { class: "flex items-center gap-2 text-sm text-body" }, bp = { class: "flex items-center gap-2 text-sm text-body" }, xp = { class: "flex gap-3" }, Sp = { +}, _p = { class: "flex flex-wrap items-center gap-2" }, vp = ["aria-label", "onClick"], yp = { class: "flex flex-wrap items-center gap-6" }, bp = { class: "flex items-center gap-2 text-sm text-body" }, xp = { class: "flex items-center gap-2 text-sm text-body" }, Sp = { class: "flex gap-3" }, Cp = { key: 1, class: "flex items-center gap-3" -}, Cp = { class: "min-w-0 flex-1 truncate text-sm font-medium text-heading" }, wp = { class: "flex items-center gap-1" }, Tp = [ +}, wp = { class: "min-w-0 flex-1 truncate text-sm font-medium text-heading" }, Tp = { class: "flex items-center gap-1" }, Ep = [ "disabled", "title", "aria-label", "onClick" -], Ep = [ +], Dp = [ "disabled", "title", "aria-label", "onClick" -], Dp = [ +], Op = [ "title", "aria-label", "onClick" -], Op = [ +], kp = [ "disabled", "title", "aria-label", "onClick" -], kp = { +], Ap = { key: 3, class: "mt-4 space-y-3 rounded-lg border border-line-default p-3" -}, Ap = { class: "flex flex-wrap items-center gap-2" }, jp = ["aria-label", "onClick"], Mp = { class: "flex flex-wrap items-center gap-6" }, Np = { class: "flex items-center gap-2 text-sm text-body" }, Pp = { class: "flex items-center gap-2 text-sm text-body" }, Fp = { class: "flex gap-3" }, Ip = /* @__PURE__ */ l({ +}, jp = { class: "flex flex-wrap items-center gap-2" }, Mp = ["aria-label", "onClick"], Np = { class: "flex flex-wrap items-center gap-6" }, Pp = { class: "flex items-center gap-2 text-sm text-body" }, Fp = { class: "flex items-center gap-2 text-sm text-body" }, Ip = { class: "flex gap-3" }, Lp = /* @__PURE__ */ l({ __name: "TaskStatusEditor", props: { client: { type: [Function, Object] }, @@ -8334,10 +8358,10 @@ var Nf = { } return (t, n) => { let l = x("BaseSpinner"), h = x("BaseInput"), v = x("BaseInputGroup"), y = x("BaseSwitch"), j = x("BaseButton"), F = x("BaseBadge"), z = x("BaseIcon"); - return _(), a("div", null, [w.value ? (_(), a("p", up, S(C(d)("tasks_projects.settings.forbidden")), 1)) : (_(), a("div", dp, [g.value ? (_(), a("div", fp, [c(l, { class: "h-4 w-4 text-primary-500" })])) : A.value ? (_(), a("p", pp, S(C(d)("tasks_projects.settings.no_statuses")), 1)) : (_(), a("ul", mp, [(_(!0), a(e, null, b(m.value, (t, l) => (_(), a("li", { + return _(), a("div", null, [w.value ? (_(), a("p", dp, S(C(d)("tasks_projects.settings.forbidden")), 1)) : (_(), a("div", fp, [g.value ? (_(), a("div", pp, [c(l, { class: "h-4 w-4 text-primary-500" })])) : A.value ? (_(), a("p", mp, S(C(d)("tasks_projects.settings.no_statuses")), 1)) : (_(), a("ul", hp, [(_(!0), a(e, null, b(m.value, (t, l) => (_(), a("li", { key: t.id, class: "py-3" - }, [E.value === t.id ? (_(), a("div", hp, [ + }, [E.value === t.id ? (_(), a("div", gp, [ c(v, { label: C(d)("tasks_projects.settings.status_name"), required: "" @@ -8351,30 +8375,30 @@ var Nf = { _: 1 }, 8, ["label"]), c(v, { label: C(d)("tasks_projects.settings.colour") }, { - default: D(() => [o("div", gp, [(_(), a(e, null, b(u, (e) => o("button", { + default: D(() => [o("div", _p, [(_(), a(e, null, b(u, (e) => o("button", { key: e, type: "button", class: f(["h-7 w-7 rounded-full border-2 transition", k.colour === e ? "border-heading" : "border-line-default"]), style: p({ backgroundColor: e }), "aria-label": e, onClick: (t) => k.colour = e - }, null, 14, _p)), 64)), o("button", { + }, null, 14, vp)), 64)), o("button", { type: "button", class: "rounded-md border border-line-default px-2 py-1 text-xs text-muted hover:bg-hover", onClick: n[1] ||= (e) => k.colour = "" }, S(C(d)("tasks_projects.settings.colour_none")), 1)])]), _: 1 }, 8, ["label"]), - o("div", vp, [o("label", yp, [c(y, { + o("div", yp, [o("label", bp, [c(y, { modelValue: k.is_default, "onUpdate:modelValue": n[2] ||= (e) => k.is_default = e, class: "flex" - }, null, 8, ["modelValue"]), s(" " + S(C(d)("tasks_projects.settings.is_default")), 1)]), o("label", bp, [c(y, { + }, null, 8, ["modelValue"]), s(" " + S(C(d)("tasks_projects.settings.is_default")), 1)]), o("label", xp, [c(y, { modelValue: k.is_closed, "onUpdate:modelValue": n[3] ||= (e) => k.is_closed = e, class: "flex" }, null, 8, ["modelValue"]), s(" " + S(C(d)("tasks_projects.settings.is_closed")), 1)])]), - o("div", xp, [c(j, { + o("div", Sp, [c(j, { variant: "primary", size: "sm", disabled: T.value, @@ -8390,12 +8414,12 @@ var Nf = { default: D(() => [s(S(C(d)("tasks_projects.general.cancel")), 1)]), _: 1 })]) - ])) : (_(), a("div", Sp, [ + ])) : (_(), a("div", Cp, [ o("span", { class: f(["inline-block h-3 w-3 shrink-0 rounded-full", t.colour ? "" : "bg-line-default"]), style: p(t.colour ? { backgroundColor: t.colour } : void 0) }, null, 6), - o("span", Cp, S(t.name), 1), + o("span", wp, S(t.name), 1), t.is_default ? (_(), r(F, { key: 0, class: "rounded-full bg-primary-50! text-primary-500!" @@ -8410,7 +8434,7 @@ var Nf = { default: D(() => [s(S(C(d)("tasks_projects.settings.is_closed")), 1)]), _: 1 })) : i("", !0), - o("div", wp, [ + o("div", Tp, [ o("button", { type: "button", class: "rounded p-1 text-subtle hover:bg-hover hover:text-heading disabled:opacity-40", @@ -8421,7 +8445,7 @@ var Nf = { }, [c(z, { name: "ChevronUpIcon", class: "h-4 w-4" - })], 8, Tp), + })], 8, Ep), o("button", { type: "button", class: "rounded p-1 text-subtle hover:bg-hover hover:text-heading disabled:opacity-40", @@ -8432,7 +8456,7 @@ var Nf = { }, [c(z, { name: "ChevronDownIcon", class: "h-4 w-4" - })], 8, Ep), + })], 8, Dp), o("button", { type: "button", class: "rounded p-1 text-subtle hover:bg-hover hover:text-heading", @@ -8442,7 +8466,7 @@ var Nf = { }, [c(z, { name: "PencilIcon", class: "h-4 w-4" - })], 8, Dp), + })], 8, Op), o("button", { type: "button", class: "rounded p-1 text-subtle hover:bg-hover hover:text-alert-error-text", @@ -8453,9 +8477,9 @@ var Nf = { }, [c(z, { name: "TrashIcon", class: "h-4 w-4" - })], 8, Op) + })], 8, kp) ]) - ]))]))), 128))])), O.value ? (_(), a("div", kp, [ + ]))]))), 128))])), O.value ? (_(), a("div", Ap, [ c(v, { label: C(d)("tasks_projects.settings.status_name"), required: "" @@ -8469,26 +8493,26 @@ var Nf = { _: 1 }, 8, ["label"]), c(v, { label: C(d)("tasks_projects.settings.colour") }, { - default: D(() => [o("div", Ap, [(_(), a(e, null, b(u, (e) => o("button", { + default: D(() => [o("div", jp, [(_(), a(e, null, b(u, (e) => o("button", { key: e, type: "button", class: f(["h-7 w-7 rounded-full border-2 transition", k.colour === e ? "border-heading" : "border-line-default"]), style: p({ backgroundColor: e }), "aria-label": e, onClick: (t) => k.colour = e - }, null, 14, jp)), 64))])]), + }, null, 14, Mp)), 64))])]), _: 1 }, 8, ["label"]), - o("div", Mp, [o("label", Np, [c(y, { + o("div", Np, [o("label", Pp, [c(y, { modelValue: k.is_default, "onUpdate:modelValue": n[5] ||= (e) => k.is_default = e, class: "flex" - }, null, 8, ["modelValue"]), s(" " + S(C(d)("tasks_projects.settings.is_default")), 1)]), o("label", Pp, [c(y, { + }, null, 8, ["modelValue"]), s(" " + S(C(d)("tasks_projects.settings.is_default")), 1)]), o("label", Fp, [c(y, { modelValue: k.is_closed, "onUpdate:modelValue": n[6] ||= (e) => k.is_closed = e, class: "flex" }, null, 8, ["modelValue"]), s(" " + S(C(d)("tasks_projects.settings.is_closed")), 1)])]), - o("div", Fp, [c(j, { + o("div", Ip, [c(j, { variant: "primary", size: "sm", disabled: T.value, @@ -8520,7 +8544,7 @@ var Nf = { }))]))]); }; } -}), Lp = { class: "space-y-6" }, Rp = { class: "divide-y divide-line-light" }, zp = { class: "text-sm text-muted" }, Bp = { class: "text-sm font-medium text-heading" }, Vp = { class: "divide-y divide-line-light" }, Hp = { class: "text-sm text-muted" }, Up = { class: "text-sm font-medium text-heading" }, Wp = /* @__PURE__ */ l({ +}), Rp = { class: "space-y-6" }, zp = { class: "divide-y divide-line-light" }, Bp = { class: "text-sm text-muted" }, Vp = { class: "text-sm font-medium text-heading" }, Hp = { class: "divide-y divide-line-light" }, Up = { class: "text-sm text-muted" }, Wp = { class: "text-sm font-medium text-heading" }, Gp = { class: "divide-y divide-line-light" }, Kp = { class: "text-sm text-muted" }, qp = { class: "text-sm font-medium text-heading" }, Jp = /* @__PURE__ */ l({ __name: "TimeSettingsPage", props: { client: { type: [Function, Object] }, @@ -8533,6 +8557,22 @@ var Nf = { return r(e ? "tasks_projects.settings.on" : "tasks_projects.settings.off"); } let u = n(() => [ + { + key: "default_rate", + label: r("tasks_projects.settings.default_rate"), + value: ot(i.value.default_rate) + }, + { + key: "week_start", + label: r("tasks_projects.settings.week_start"), + value: r(`tasks_projects.settings.weekday_${i.value.week_start}`) + }, + { + key: "members_see_all_time", + label: r("tasks_projects.settings.members_see_all_time"), + value: l(i.value.members_see_all_time) + } + ]), d = n(() => [ { key: "rounding_direction", label: r("tasks_projects.settings.rounding_direction"), @@ -8558,7 +8598,7 @@ var Nf = { label: r("tasks_projects.settings.hide_invoiced_on_board"), value: l(i.value.hide_invoiced_on_board) } - ]), d = n(() => [ + ]), p = n(() => [ "invoice_project_heading", "invoice_task_description", "invoice_entry_dates", @@ -8571,14 +8611,14 @@ var Nf = { value: l(i.value[e]) }))); return (n, i) => { - let l = x("BaseIcon"), p = x("BaseButton"), m = x("router-link"), h = x("BaseSettingCard"); - return _(), a("div", Lp, [ - c(h, { + let l = x("BaseIcon"), m = x("BaseButton"), h = x("router-link"), g = x("BaseSettingCard"); + return _(), a("div", Rp, [ + c(g, { title: C(r)("tasks_projects.settings.general_title"), description: C(r)("tasks_projects.settings.general_description") }, { - action: D(() => [c(m, { to: C(W).settings }, { - default: D(() => [c(p, { + action: D(() => [c(h, { to: C(W).settings }, { + default: D(() => [c(m, { variant: "primary-outline", size: "sm" }, { @@ -8591,33 +8631,37 @@ var Nf = { })]), _: 1 }, 8, ["to"])]), + default: D(() => [o("dl", zp, [(_(!0), a(e, null, b(u.value, (e) => (_(), a("div", { + key: e.key, + class: "flex justify-between gap-4 py-2.5" + }, [o("dt", Bp, S(e.label), 1), o("dd", Vp, S(e.value), 1)]))), 128))])]), _: 1 }, 8, ["title", "description"]), - c(h, { + c(g, { title: C(r)("tasks_projects.settings.behaviour_title"), description: C(r)("tasks_projects.settings.behaviour_description") }, { - default: D(() => [o("dl", Rp, [(_(!0), a(e, null, b(u.value, (e) => (_(), a("div", { + default: D(() => [o("dl", Hp, [(_(!0), a(e, null, b(d.value, (e) => (_(), a("div", { key: e.key, class: "flex justify-between gap-4 py-2.5" - }, [o("dt", zp, S(e.label), 1), o("dd", Bp, S(e.value), 1)]))), 128))])]), + }, [o("dt", Up, S(e.label), 1), o("dd", Wp, S(e.value), 1)]))), 128))])]), _: 1 }, 8, ["title", "description"]), - c(h, { + c(g, { title: C(r)("tasks_projects.settings.invoice_title"), description: C(r)("tasks_projects.settings.invoice_description") }, { - default: D(() => [o("dl", Vp, [(_(!0), a(e, null, b(d.value, (e) => (_(), a("div", { + default: D(() => [o("dl", Gp, [(_(!0), a(e, null, b(p.value, (e) => (_(), a("div", { key: e.key, class: "flex justify-between gap-4 py-2.5" - }, [o("dt", Hp, S(e.label), 1), o("dd", Up, S(e.value), 1)]))), 128))])]), + }, [o("dt", Kp, S(e.label), 1), o("dd", qp, S(e.value), 1)]))), 128))])]), _: 1 }, 8, ["title", "description"]), - c(h, { + c(g, { title: C(r)("tasks_projects.settings.statuses_title"), description: C(r)("tasks_projects.settings.statuses_description") }, { - default: D(() => [c(Ip, { + default: D(() => [c(Lp, { client: t.client, notify: t.notify }, null, 8, ["client", "notify"])]), @@ -8629,8 +8673,8 @@ var Nf = { }); //#endregion //#region resources/js/registrations/time.ts -function Gp(e) { - e.addMessages(lp); +function Yp(e) { + e.addMessages(up); let t = (t, n) => { e.notify(t, n); }, n = () => { @@ -8643,18 +8687,19 @@ function Gp(e) { id: `${U}.timer-chip`, priority: 30, visible: () => K.running !== null, - component: l({ setup: () => () => d(cp, { + component: l({ setup: () => () => d(lp, { client: e.client, notify: t, onOpen: r }) }) }), e.registerCompanyLayoutOverlay({ id: `${U}.quick-start`, - component: l({ setup: () => () => d(np, { + component: l({ setup: () => () => d(rp, { key: xa.companySession, client: e.client, notify: t, enabled: !xa.adminMode, + router: e.router, onOpenWeek: n }) }) }), e.registerCompanySettingsPage({ @@ -8663,28 +8708,28 @@ function Gp(e) { icon: "ClockIcon", path: U, priority: 70, - component: sn(e, Wp) + component: sn(e, Jp) }), e.on("bootstrap:completed", ({ adminMode: t }) => { - Kp(e, t); + Xp(e, t); }), e.on("company:changing", () => { - qp(); + Zp(); }), e.on("company:changed", ({ companyId: t }) => { - Kp(e, t === null); + Xp(e, t === null); }); } -async function Kp(e, t) { +async function Xp(e, t) { if (wa(t), t) { - qp(); + Zp(); return; } await Sa(e.client), await K.refresh(e.client); } -function qp() { +function Zp() { K.reset(), rt(), Ca(); } //#endregion //#region resources/js/init.ts window.InvoiceShelf.booting((e, t, n) => { - n.addMessages(j), jf(n), Xo(n), Gp(n), nr(n), Gs(n); + n.addMessages(j), jf(n), Xo(n), Yp(n), nr(n), Gs(n); }); //#endregion diff --git a/dist/style.css b/dist/style.css index 2639ee3..e490dec 100644 --- a/dist/style.css +++ b/dist/style.css @@ -1,3 +1,3 @@ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer utilities{.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.fixed{position:fixed}.relative{position:relative}.right-6{right:calc(var(--spacing,.25rem) * 6)}.bottom-20{bottom:calc(var(--spacing,.25rem) * 20)}.z-40{z-index:40}.float-left{float:left}.m-0{margin:0}.mt-0\.5{margin-top:calc(var(--spacing,.25rem) * .5)}.mt-1{margin-top:var(--spacing,.25rem)}.mt-2{margin-top:calc(var(--spacing,.25rem) * 2)}.mt-3{margin-top:calc(var(--spacing,.25rem) * 3)}.mt-4{margin-top:calc(var(--spacing,.25rem) * 4)}.mt-5{margin-top:calc(var(--spacing,.25rem) * 5)}.mt-6{margin-top:calc(var(--spacing,.25rem) * 6)}.mr-2{margin-right:calc(var(--spacing,.25rem) * 2)}.mr-3{margin-right:calc(var(--spacing,.25rem) * 3)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:var(--spacing,.25rem)}.mb-3{margin-bottom:calc(var(--spacing,.25rem) * 3)}.mb-4{margin-bottom:calc(var(--spacing,.25rem) * 4)}.ml-1{margin-left:var(--spacing,.25rem)}.ml-2{margin-left:calc(var(--spacing,.25rem) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing,.25rem) * 1.5)}.h-2{height:calc(var(--spacing,.25rem) * 2)}.h-2\.5{height:calc(var(--spacing,.25rem) * 2.5)}.h-3{height:calc(var(--spacing,.25rem) * 3)}.h-3\.5{height:calc(var(--spacing,.25rem) * 3.5)}.h-4{height:calc(var(--spacing,.25rem) * 4)}.h-5{height:calc(var(--spacing,.25rem) * 5)}.h-6{height:calc(var(--spacing,.25rem) * 6)}.h-7{height:calc(var(--spacing,.25rem) * 7)}.h-8{height:calc(var(--spacing,.25rem) * 8)}.h-16{height:calc(var(--spacing,.25rem) * 16)}.max-h-48{max-height:calc(var(--spacing,.25rem) * 48)}.min-h-20{min-height:calc(var(--spacing,.25rem) * 20)}.min-h-40{min-height:calc(var(--spacing,.25rem) * 40)}.w-1\.5{width:calc(var(--spacing,.25rem) * 1.5)}.w-2{width:calc(var(--spacing,.25rem) * 2)}.w-2\.5{width:calc(var(--spacing,.25rem) * 2.5)}.w-3{width:calc(var(--spacing,.25rem) * 3)}.w-3\.5{width:calc(var(--spacing,.25rem) * 3.5)}.w-4{width:calc(var(--spacing,.25rem) * 4)}.w-5{width:calc(var(--spacing,.25rem) * 5)}.w-6{width:calc(var(--spacing,.25rem) * 6)}.w-7{width:calc(var(--spacing,.25rem) * 7)}.w-8{width:calc(var(--spacing,.25rem) * 8)}.w-10{width:calc(var(--spacing,.25rem) * 10)}.w-16{width:calc(var(--spacing,.25rem) * 16)}.w-64{width:calc(var(--spacing,.25rem) * 64)}.w-80{width:calc(var(--spacing,.25rem) * 80)}.w-full{width:100%}.max-w-32{max-width:calc(var(--spacing,.25rem) * 32)}.max-w-64{max-width:calc(var(--spacing,.25rem) * 64)}.max-w-\[calc\(100vw-3rem\)\]{max-width:calc(100vw - 3rem)}.min-w-0{min-width:0}.min-w-44{min-width:calc(var(--spacing,.25rem) * 44)}.min-w-48{min-width:calc(var(--spacing,.25rem) * 48)}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-auto{table-layout:auto}.animate-pulse{animation:var(--animate-pulse,pulse 2s cubic-bezier(.4, 0, .6, 1) infinite)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing,.25rem)}.gap-1\.5{gap:calc(var(--spacing,.25rem) * 1.5)}.gap-2{gap:calc(var(--spacing,.25rem) * 2)}.gap-3{gap:calc(var(--spacing,.25rem) * 3)}.gap-4{gap:calc(var(--spacing,.25rem) * 4)}.gap-6{gap:calc(var(--spacing,.25rem) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing,.25rem) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing,.25rem) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing,.25rem) * 3) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing,.25rem) * 3) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-5>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing,.25rem) * 5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing,.25rem) * 5) * calc(1 - var(--tw-space-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-line-default>:not(:last-child)){border-color:var(--color-line-default)}:where(.divide-line-light>:not(:last-child)){border-color:var(--color-line-light)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg,.5rem)}.rounded-md{border-radius:var(--radius-md,.375rem)}.rounded-sm{border-radius:var(--radius-sm,.25rem)}.rounded-xl{border-radius:var(--radius-xl,.75rem)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-heading{border-color:var(--color-heading)}.border-line-default{border-color:var(--color-line-default)}.border-line-light{border-color:var(--color-line-light)}.border-line-strong{border-color:var(--color-line-strong)}.border-primary-200{border-color:var(--color-primary-200)}.border-primary-400{border-color:var(--color-primary-400)}.border-primary-500{border-color:var(--color-primary-500)}.border-status-yellow{border-color:var(--color-status-yellow)}.border-transparent{border-color:#0000}.bg-alert-error-bg{background-color:var(--color-alert-error-bg)}.bg-alert-success-bg\!{background-color:var(--color-alert-success-bg)!important}.bg-alert-warning-bg{background-color:var(--color-alert-warning-bg)}.bg-alert-warning-bg\!{background-color:var(--color-alert-warning-bg)!important}.bg-btn-primary{background-color:var(--color-btn-primary)}.bg-hover-strong{background-color:var(--color-hover-strong)}.bg-line-default{background-color:var(--color-line-default)}.bg-line-strong{background-color:var(--color-line-strong)}.bg-primary-50{background-color:var(--color-primary-50)}.bg-primary-50\!{background-color:var(--color-primary-50)!important}.bg-primary-500{background-color:var(--color-primary-500)}.bg-status-green{background-color:var(--color-status-green)}.bg-status-red{background-color:var(--color-status-red)}.bg-surface{background-color:var(--color-surface)}.bg-surface-secondary{background-color:var(--color-surface-secondary)}.bg-surface-tertiary{background-color:var(--color-surface-tertiary)}.bg-surface-tertiary\!{background-color:var(--color-surface-tertiary)!important}.bg-white{background-color:var(--color-white,#fff)}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\/20{background-color:color-mix(in oklab, var(--color-white,#fff) 20%, transparent)}}.p-1{padding:var(--spacing,.25rem)}.p-1\.5{padding:calc(var(--spacing,.25rem) * 1.5)}.p-2{padding:calc(var(--spacing,.25rem) * 2)}.p-3{padding:calc(var(--spacing,.25rem) * 3)}.p-5{padding:calc(var(--spacing,.25rem) * 5)}.px-1{padding-inline:var(--spacing,.25rem)}.px-1\.5{padding-inline:calc(var(--spacing,.25rem) * 1.5)}.px-2{padding-inline:calc(var(--spacing,.25rem) * 2)}.px-3{padding-inline:calc(var(--spacing,.25rem) * 3)}.px-4{padding-inline:calc(var(--spacing,.25rem) * 4)}.px-5{padding-inline:calc(var(--spacing,.25rem) * 5)}.px-6{padding-inline:calc(var(--spacing,.25rem) * 6)}.py-0\.5{padding-block:calc(var(--spacing,.25rem) * .5)}.py-1{padding-block:var(--spacing,.25rem)}.py-1\.5{padding-block:calc(var(--spacing,.25rem) * 1.5)}.py-2{padding-block:calc(var(--spacing,.25rem) * 2)}.py-2\.5{padding-block:calc(var(--spacing,.25rem) * 2.5)}.py-3{padding-block:calc(var(--spacing,.25rem) * 3)}.py-4{padding-block:calc(var(--spacing,.25rem) * 4)}.py-6{padding-block:calc(var(--spacing,.25rem) * 6)}.py-8{padding-block:calc(var(--spacing,.25rem) * 8)}.py-10{padding-block:calc(var(--spacing,.25rem) * 10)}.py-16{padding-block:calc(var(--spacing,.25rem) * 16)}.pt-2{padding-top:calc(var(--spacing,.25rem) * 2)}.pt-3{padding-top:calc(var(--spacing,.25rem) * 3)}.pb-2{padding-bottom:calc(var(--spacing,.25rem) * 2)}.pb-3{padding-bottom:calc(var(--spacing,.25rem) * 3)}.pb-4{padding-bottom:calc(var(--spacing,.25rem) * 4)}.pl-4{padding-left:calc(var(--spacing,.25rem) * 4)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-2xl{font-size:var(--text-2xl,1.5rem);line-height:var(--tw-leading,var(--text-2xl--line-height,calc(2 / 1.5)))}.text-base{font-size:var(--text-base,1rem);line-height:var(--tw-leading,var(--text-base--line-height,calc(1.5 / 1)))}.text-lg{font-size:var(--text-lg,1.125rem);line-height:var(--tw-leading,var(--text-lg--line-height,calc(1.75 / 1.125)))}.text-sm{font-size:var(--text-sm,.875rem);line-height:var(--tw-leading,var(--text-sm--line-height,calc(1.25 / .875)))}.text-xl{font-size:var(--text-xl,1.25rem);line-height:var(--tw-leading,var(--text-xl--line-height,calc(1.75 / 1.25)))}.text-xs{font-size:var(--text-xs,.75rem);line-height:var(--tw-leading,var(--text-xs--line-height,calc(1 / .75)))}.text-\[11px\]{font-size:11px}.leading-5{--tw-leading:calc(var(--spacing,.25rem) * 5);line-height:calc(var(--spacing,.25rem) * 5)}.font-medium{--tw-font-weight:var(--font-weight-medium,500);font-weight:var(--font-weight-medium,500)}.font-normal{--tw-font-weight:var(--font-weight-normal,400);font-weight:var(--font-weight-normal,400)}.font-semibold{--tw-font-weight:var(--font-weight-semibold,600);font-weight:var(--font-weight-semibold,600)}.tracking-wide{--tw-tracking:var(--tracking-wide,.025em);letter-spacing:var(--tracking-wide,.025em)}.tracking-wider{--tw-tracking:var(--tracking-wider,.05em);letter-spacing:var(--tracking-wider,.05em)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.text-alert-error-text{color:var(--color-alert-error-text)}.text-alert-success-text\!{color:var(--color-alert-success-text)!important}.text-alert-warning-text{color:var(--color-alert-warning-text)}.text-alert-warning-text\!{color:var(--color-alert-warning-text)!important}.text-body{color:var(--color-body)}.text-heading{color:var(--color-heading)}.text-muted{color:var(--color-muted)}.text-muted\!{color:var(--color-muted)!important}.text-primary-500{color:var(--color-primary-500)}.text-primary-500\!{color:var(--color-primary-500)!important}.text-primary-600{color:var(--color-primary-600)}.text-primary-700{color:var(--color-primary-700)}.text-status-green{color:var(--color-status-green)}.text-status-red{color:var(--color-status-red)}.text-subtle{color:var(--color-subtle)}.text-white{color:var(--color-white,#fff)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-40{opacity:.4}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s))}@media (hover:hover){.group-hover\:text-muted:is(:where(.group):hover *){color:var(--color-muted)}}.last\:border-r-0:last-child{border-right-style:var(--tw-border-style);border-right-width:0}@media (hover:hover){.hover\:border-line-strong:hover{border-color:var(--color-line-strong)}.hover\:border-primary-500:hover{border-color:var(--color-primary-500)}.hover\:bg-btn-primary-hover:hover{background-color:var(--color-btn-primary-hover)}.hover\:bg-hover:hover{background-color:var(--color-hover)}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab, var(--color-white,#fff) 20%, transparent)}}.hover\:text-alert-error-text:hover{color:var(--color-alert-error-text)}.hover\:text-body:hover{color:var(--color-body)}.hover\:text-heading:hover{color:var(--color-heading)}.hover\:text-primary-500:hover{color:var(--color-primary-500)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-primary-400:focus{border-color:var(--color-primary-400)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-primary-400:focus{--tw-ring-color:var(--color-primary-400)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media not all and (width>=40rem){.max-sm\:hidden{display:none}}@media (width>=40rem){.sm\:w-48{width:calc(var(--spacing,.25rem) * 48)}.sm\:w-56{width:calc(var(--spacing,.25rem) * 56)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (width>=48rem){.md\:h-9{height:calc(var(--spacing,.25rem) * 9)}.md\:px-3{padding-inline:calc(var(--spacing,.25rem) * 3)}}@media (width>=64rem){.lg\:mb-1{margin-bottom:var(--spacing,.25rem)}.lg\:block{display:block}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-end{align-items:flex-end}}@media (width>=80rem){.xl\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}} +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer utilities{.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.fixed{position:fixed}.relative{position:relative}.right-6{right:calc(var(--spacing,.25rem) * 6)}.bottom-20{bottom:calc(var(--spacing,.25rem) * 20)}.bottom-36{bottom:calc(var(--spacing,.25rem) * 36)}.z-40{z-index:40}.float-left{float:left}.m-0{margin:0}.mt-0\.5{margin-top:calc(var(--spacing,.25rem) * .5)}.mt-1{margin-top:var(--spacing,.25rem)}.mt-2{margin-top:calc(var(--spacing,.25rem) * 2)}.mt-3{margin-top:calc(var(--spacing,.25rem) * 3)}.mt-4{margin-top:calc(var(--spacing,.25rem) * 4)}.mt-5{margin-top:calc(var(--spacing,.25rem) * 5)}.mt-6{margin-top:calc(var(--spacing,.25rem) * 6)}.mr-2{margin-right:calc(var(--spacing,.25rem) * 2)}.mr-3{margin-right:calc(var(--spacing,.25rem) * 3)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:var(--spacing,.25rem)}.mb-3{margin-bottom:calc(var(--spacing,.25rem) * 3)}.mb-4{margin-bottom:calc(var(--spacing,.25rem) * 4)}.ml-1{margin-left:var(--spacing,.25rem)}.ml-2{margin-left:calc(var(--spacing,.25rem) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing,.25rem) * 1.5)}.h-2{height:calc(var(--spacing,.25rem) * 2)}.h-2\.5{height:calc(var(--spacing,.25rem) * 2.5)}.h-3{height:calc(var(--spacing,.25rem) * 3)}.h-3\.5{height:calc(var(--spacing,.25rem) * 3.5)}.h-4{height:calc(var(--spacing,.25rem) * 4)}.h-5{height:calc(var(--spacing,.25rem) * 5)}.h-6{height:calc(var(--spacing,.25rem) * 6)}.h-7{height:calc(var(--spacing,.25rem) * 7)}.h-8{height:calc(var(--spacing,.25rem) * 8)}.h-16{height:calc(var(--spacing,.25rem) * 16)}.max-h-48{max-height:calc(var(--spacing,.25rem) * 48)}.min-h-20{min-height:calc(var(--spacing,.25rem) * 20)}.min-h-40{min-height:calc(var(--spacing,.25rem) * 40)}.w-1\.5{width:calc(var(--spacing,.25rem) * 1.5)}.w-2{width:calc(var(--spacing,.25rem) * 2)}.w-2\.5{width:calc(var(--spacing,.25rem) * 2.5)}.w-3{width:calc(var(--spacing,.25rem) * 3)}.w-3\.5{width:calc(var(--spacing,.25rem) * 3.5)}.w-4{width:calc(var(--spacing,.25rem) * 4)}.w-5{width:calc(var(--spacing,.25rem) * 5)}.w-6{width:calc(var(--spacing,.25rem) * 6)}.w-7{width:calc(var(--spacing,.25rem) * 7)}.w-8{width:calc(var(--spacing,.25rem) * 8)}.w-10{width:calc(var(--spacing,.25rem) * 10)}.w-16{width:calc(var(--spacing,.25rem) * 16)}.w-64{width:calc(var(--spacing,.25rem) * 64)}.w-80{width:calc(var(--spacing,.25rem) * 80)}.w-full{width:100%}.max-w-32{max-width:calc(var(--spacing,.25rem) * 32)}.max-w-64{max-width:calc(var(--spacing,.25rem) * 64)}.max-w-\[calc\(100vw-3rem\)\]{max-width:calc(100vw - 3rem)}.min-w-0{min-width:0}.min-w-44{min-width:calc(var(--spacing,.25rem) * 44)}.min-w-48{min-width:calc(var(--spacing,.25rem) * 48)}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-auto{table-layout:auto}.animate-pulse{animation:var(--animate-pulse,pulse 2s cubic-bezier(.4, 0, .6, 1) infinite)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing,.25rem)}.gap-1\.5{gap:calc(var(--spacing,.25rem) * 1.5)}.gap-2{gap:calc(var(--spacing,.25rem) * 2)}.gap-3{gap:calc(var(--spacing,.25rem) * 3)}.gap-4{gap:calc(var(--spacing,.25rem) * 4)}.gap-6{gap:calc(var(--spacing,.25rem) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing,.25rem) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing,.25rem) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing,.25rem) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing,.25rem) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing,.25rem) * 3) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing,.25rem) * 3) * calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-5>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing,.25rem) * 5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing,.25rem) * 5) * calc(1 - var(--tw-space-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-line-default>:not(:last-child)){border-color:var(--color-line-default)}:where(.divide-line-light>:not(:last-child)){border-color:var(--color-line-light)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg,.5rem)}.rounded-md{border-radius:var(--radius-md,.375rem)}.rounded-sm{border-radius:var(--radius-sm,.25rem)}.rounded-xl{border-radius:var(--radius-xl,.75rem)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-heading{border-color:var(--color-heading)}.border-line-default{border-color:var(--color-line-default)}.border-line-light{border-color:var(--color-line-light)}.border-line-strong{border-color:var(--color-line-strong)}.border-primary-200{border-color:var(--color-primary-200)}.border-primary-400{border-color:var(--color-primary-400)}.border-primary-500{border-color:var(--color-primary-500)}.border-status-yellow{border-color:var(--color-status-yellow)}.border-transparent{border-color:#0000}.bg-alert-error-bg{background-color:var(--color-alert-error-bg)}.bg-alert-success-bg\!{background-color:var(--color-alert-success-bg)!important}.bg-alert-warning-bg{background-color:var(--color-alert-warning-bg)}.bg-alert-warning-bg\!{background-color:var(--color-alert-warning-bg)!important}.bg-btn-primary{background-color:var(--color-btn-primary)}.bg-hover-strong{background-color:var(--color-hover-strong)}.bg-line-default{background-color:var(--color-line-default)}.bg-line-strong{background-color:var(--color-line-strong)}.bg-primary-50{background-color:var(--color-primary-50)}.bg-primary-50\!{background-color:var(--color-primary-50)!important}.bg-primary-500{background-color:var(--color-primary-500)}.bg-status-green{background-color:var(--color-status-green)}.bg-status-red{background-color:var(--color-status-red)}.bg-surface{background-color:var(--color-surface)}.bg-surface-secondary{background-color:var(--color-surface-secondary)}.bg-surface-tertiary{background-color:var(--color-surface-tertiary)}.bg-surface-tertiary\!{background-color:var(--color-surface-tertiary)!important}.bg-white{background-color:var(--color-white,#fff)}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\/20{background-color:color-mix(in oklab, var(--color-white,#fff) 20%, transparent)}}.p-1{padding:var(--spacing,.25rem)}.p-1\.5{padding:calc(var(--spacing,.25rem) * 1.5)}.p-2{padding:calc(var(--spacing,.25rem) * 2)}.p-3{padding:calc(var(--spacing,.25rem) * 3)}.p-5{padding:calc(var(--spacing,.25rem) * 5)}.px-1{padding-inline:var(--spacing,.25rem)}.px-1\.5{padding-inline:calc(var(--spacing,.25rem) * 1.5)}.px-2{padding-inline:calc(var(--spacing,.25rem) * 2)}.px-3{padding-inline:calc(var(--spacing,.25rem) * 3)}.px-4{padding-inline:calc(var(--spacing,.25rem) * 4)}.px-5{padding-inline:calc(var(--spacing,.25rem) * 5)}.px-6{padding-inline:calc(var(--spacing,.25rem) * 6)}.py-0\.5{padding-block:calc(var(--spacing,.25rem) * .5)}.py-1{padding-block:var(--spacing,.25rem)}.py-1\.5{padding-block:calc(var(--spacing,.25rem) * 1.5)}.py-2{padding-block:calc(var(--spacing,.25rem) * 2)}.py-2\.5{padding-block:calc(var(--spacing,.25rem) * 2.5)}.py-3{padding-block:calc(var(--spacing,.25rem) * 3)}.py-4{padding-block:calc(var(--spacing,.25rem) * 4)}.py-6{padding-block:calc(var(--spacing,.25rem) * 6)}.py-8{padding-block:calc(var(--spacing,.25rem) * 8)}.py-10{padding-block:calc(var(--spacing,.25rem) * 10)}.py-16{padding-block:calc(var(--spacing,.25rem) * 16)}.pt-2{padding-top:calc(var(--spacing,.25rem) * 2)}.pt-3{padding-top:calc(var(--spacing,.25rem) * 3)}.pb-2{padding-bottom:calc(var(--spacing,.25rem) * 2)}.pb-3{padding-bottom:calc(var(--spacing,.25rem) * 3)}.pb-4{padding-bottom:calc(var(--spacing,.25rem) * 4)}.pl-4{padding-left:calc(var(--spacing,.25rem) * 4)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-2xl{font-size:var(--text-2xl,1.5rem);line-height:var(--tw-leading,var(--text-2xl--line-height,calc(2 / 1.5)))}.text-base{font-size:var(--text-base,1rem);line-height:var(--tw-leading,var(--text-base--line-height,calc(1.5 / 1)))}.text-lg{font-size:var(--text-lg,1.125rem);line-height:var(--tw-leading,var(--text-lg--line-height,calc(1.75 / 1.125)))}.text-sm{font-size:var(--text-sm,.875rem);line-height:var(--tw-leading,var(--text-sm--line-height,calc(1.25 / .875)))}.text-xl{font-size:var(--text-xl,1.25rem);line-height:var(--tw-leading,var(--text-xl--line-height,calc(1.75 / 1.25)))}.text-xs{font-size:var(--text-xs,.75rem);line-height:var(--tw-leading,var(--text-xs--line-height,calc(1 / .75)))}.text-\[11px\]{font-size:11px}.leading-5{--tw-leading:calc(var(--spacing,.25rem) * 5);line-height:calc(var(--spacing,.25rem) * 5)}.font-medium{--tw-font-weight:var(--font-weight-medium,500);font-weight:var(--font-weight-medium,500)}.font-normal{--tw-font-weight:var(--font-weight-normal,400);font-weight:var(--font-weight-normal,400)}.font-semibold{--tw-font-weight:var(--font-weight-semibold,600);font-weight:var(--font-weight-semibold,600)}.tracking-wide{--tw-tracking:var(--tracking-wide,.025em);letter-spacing:var(--tracking-wide,.025em)}.tracking-wider{--tw-tracking:var(--tracking-wider,.05em);letter-spacing:var(--tracking-wider,.05em)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.text-alert-error-text{color:var(--color-alert-error-text)}.text-alert-success-text\!{color:var(--color-alert-success-text)!important}.text-alert-warning-text{color:var(--color-alert-warning-text)}.text-alert-warning-text\!{color:var(--color-alert-warning-text)!important}.text-body{color:var(--color-body)}.text-heading{color:var(--color-heading)}.text-muted{color:var(--color-muted)}.text-muted\!{color:var(--color-muted)!important}.text-primary-500{color:var(--color-primary-500)}.text-primary-500\!{color:var(--color-primary-500)!important}.text-primary-600{color:var(--color-primary-600)}.text-primary-700{color:var(--color-primary-700)}.text-status-green{color:var(--color-status-green)}.text-status-red{color:var(--color-status-red)}.text-subtle{color:var(--color-subtle)}.text-white{color:var(--color-white,#fff)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-40{opacity:.4}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s))}@media (hover:hover){.group-hover\:text-muted:is(:where(.group):hover *){color:var(--color-muted)}}.last\:border-r-0:last-child{border-right-style:var(--tw-border-style);border-right-width:0}@media (hover:hover){.hover\:border-line-strong:hover{border-color:var(--color-line-strong)}.hover\:border-primary-500:hover{border-color:var(--color-primary-500)}.hover\:bg-btn-primary-hover:hover{background-color:var(--color-btn-primary-hover)}.hover\:bg-hover:hover{background-color:var(--color-hover)}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab, var(--color-white,#fff) 20%, transparent)}}.hover\:text-alert-error-text:hover{color:var(--color-alert-error-text)}.hover\:text-body:hover{color:var(--color-body)}.hover\:text-heading:hover{color:var(--color-heading)}.hover\:text-primary-500:hover{color:var(--color-primary-500)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-primary-400:focus{border-color:var(--color-primary-400)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-primary-400:focus{--tw-ring-color:var(--color-primary-400)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media not all and (width>=40rem){.max-sm\:hidden{display:none}}@media (width>=40rem){.sm\:w-48{width:calc(var(--spacing,.25rem) * 48)}.sm\:w-56{width:calc(var(--spacing,.25rem) * 56)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (width>=48rem){.md\:h-9{height:calc(var(--spacing,.25rem) * 9)}.md\:px-3{padding-inline:calc(var(--spacing,.25rem) * 3)}}@media (width>=64rem){.lg\:mb-1{margin-bottom:var(--spacing,.25rem)}.lg\:block{display:block}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-end{align-items:flex-end}}@media (width>=80rem){.xl\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}} /*$vite$:1*/ \ No newline at end of file diff --git a/resources/js/api/board.ts b/resources/js/api/board.ts index 7cc24f1..bdc9b14 100644 --- a/resources/js/api/board.ts +++ b/resources/js/api/board.ts @@ -141,7 +141,7 @@ export async function bulkTasks( ): Promise { const { data } = await client.post(BOARD_API.bulkTasks, input) - return { updated: data?.updated ?? 0, failed: data?.failed ?? [] } + return { updated: data?.updated ?? [], failed: data?.failed ?? [] } } /** diff --git a/resources/js/components/QuickStartOverlay.vue b/resources/js/components/QuickStartOverlay.vue index b3f15ac..3d09b08 100644 --- a/resources/js/components/QuickStartOverlay.vue +++ b/resources/js/components/QuickStartOverlay.vue @@ -1,6 +1,7 @@