issue-sticker 0.4.0 → 0.6.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.
@@ -15,14 +15,14 @@ var __privateWrapper = (obj, member, setter, getter) => ({
15
15
  }
16
16
  });
17
17
  var _focused, _cleanup, _setup, _b, _provider, _providerCalled, _c, _online, _cleanup2, _setup2, _d, _gcTimeout, _e, _queryType, _initialState, _revertState, _cache, _client, _retryer, _defaultOptions, _abortSignalConsumed, _Query_instances, isInitialPausedFetch_fn, dispatch_fn, _f, _client2, _currentQuery, _currentQueryInitialState, _currentResult, _currentResultState, _currentResultOptions, _currentThenable, _selectError, _selectFn, _selectResult, _lastQueryWithDefinedData, _staleTimeoutId, _refetchIntervalId, _currentRefetchInterval, _trackedProps, _QueryObserver_instances, executeFetch_fn, updateStaleTimeout_fn, computeRefetchInterval_fn, updateRefetchInterval_fn, updateTimers_fn, clearStaleTimeout_fn, clearRefetchInterval_fn, updateQuery_fn, notify_fn, _g, _client3, _observers, _mutationCache, _retryer2, _Mutation_instances, dispatch_fn2, _h, _mutations, _scopes, _mutationId, _i, _client4, _currentResult2, _currentMutation, _mutateOptions, _MutationObserver_instances, updateResult_fn, notify_fn2, _j, _queries, _k, _queryCache, _mutationCache2, _defaultOptions2, _queryDefaults, _mutationDefaults, _mountCount, _unsubscribeFocus, _unsubscribeOnline, _l, _m;
18
- import { A as trimLogBackupPayload, B as createSafeLogBackup, D as getLogBackupSessionId, N as NetworkCollector, C as ConsoleCollector, E as createIndexedDbLogBackup, e as buildJiraCreateFields, P as Popover, F as PopoverTrigger, I as Input, G as PopoverContent, L as Label, H as Select, J as SelectTrigger, K as SelectValue, M as SelectContent, O as SelectItem, Q as getJiraMetadata, R as buildJiraIssueFields, T as Button, U as Root2$2, V as Trigger$2, W as ChevronDown, X as Portal, Y as Content2$1, Z as Check, _ as X$1, $ as DatePicker, f as buildNotionCreateFields, a0 as getNotionPageMetadata, a1 as buildNotionFieldViews, c as captureWithModernScreenshot, p as pristineFetch, d as directUploadToSignedUrl, a2 as DirectUploadError, a as uploadSignedMediaWithApi, v as sanitizeString, a3 as getRegisteredUploadId, h as buildGuestOwnerQuery, j as devLogger, w as getCurrentPageUrl, a4 as subscribe, a5 as getSnapshot, a6 as toast, a7 as ChevronRight, a8 as getExposedJiraFields, a9 as isJiraFieldExposed, n as normalizeExposedJiraFields, y as preloadModernScreenshot, u as uploadScreenshotDataUrls, k as filterExcludeServiceRelatedLogs, l as filterExcludeServiceRelatedConsoleLogs, s as selectNetworkLogsForSubmit, m as compactNetworkLogsForTransport, o as CONSOLE_LOG_SUBMIT_LIMIT, g as getElementPosition, q as buildExternalUserPayload, r as shrinkNetworkLogsToFit, t as measureJsonBytes, i as buildIssueIntegrationsPayload, x as SessionReplayCaptureController, aa as getPrimaryJiraMapping, ab as createCollection, ac as useDirection, ad as ReactRemoveScroll, ae as hideOthers, af as useFocusGuards, ag as FocusScope, ah as getPrimaryNotionMapping, ai as buttonVariants, aj as findElementBySelector, ak as findElementByXPath, S as ScreenRecordingController, al as OnboardingProvider, am as useOnboardingTarget, an as useOnboardingFlow, ao as ISSUE_STICKER_HOST_ELEMENT_ID, ap as getIssueStickerRuntimeOwner, aq as ISSUE_STICKER_RUNTIME_OWNER, z as isIssueStickerExtensionRuntimeActive, ar as createRuntimeHostElement, as as attachHostTypingGuard, at as ISSUE_STICKER_EXTENSION_RUNTIME_READY_EVENT } from "./externalUserPayload-BVNl_35M.js";
18
+ import { A as trimLogBackupPayload, B as createSafeLogBackup, D as getLogBackupSessionId, N as NetworkCollector, C as ConsoleCollector, E as createIndexedDbLogBackup, e as buildJiraCreateFields, P as Popover, F as PopoverTrigger, G as Input, H as PopoverContent, L as Label, J as Select, K as SelectTrigger, M as SelectValue, O as SelectContent, Q as SelectItem, R as getJiraMetadata, T as buildJiraIssueFields, U as Button, V as Root2$2, W as Trigger$2, X as ChevronDown, Y as Portal, Z as Content2$1, _ as Check, $ as X$1, a0 as DatePicker, f as buildNotionCreateFields, a1 as getNotionPageMetadata, a2 as buildNotionFieldViews, c as captureWithModernScreenshot, p as pristineFetch, d as directUploadToSignedUrl, a3 as DirectUploadError, a4 as toast, a5 as getSnapshot, a6 as subscribe, a as uploadSignedMediaWithApi, v as sanitizeString, a7 as getRegisteredUploadId, h as buildGuestOwnerQuery, j as devLogger, w as getCurrentPageUrl, a8 as ChevronRight, a9 as ReactRemoveScroll, aa as hideOthers, ab as useFocusGuards, ac as FocusScope, ad as getExposedJiraFields, ae as isJiraFieldExposed, n as normalizeExposedJiraFields, y as preloadModernScreenshot, u as uploadScreenshotDataUrls, k as filterExcludeServiceRelatedLogs, l as filterExcludeServiceRelatedConsoleLogs, s as selectNetworkLogsForSubmit, m as compactNetworkLogsForTransport, o as CONSOLE_LOG_SUBMIT_LIMIT, g as getElementPosition, q as buildExternalUserPayload, r as shrinkNetworkLogsToFit, t as measureJsonBytes, i as buildIssueIntegrationsPayload, x as SessionReplayCaptureController, af as getPrimaryJiraMapping, ag as createCollection, ah as useDirection, ai as getPrimaryNotionMapping, aj as buttonVariants, ak as findElementBySelector, al as findElementByXPath, S as ScreenRecordingController, am as OnboardingProvider, an as useOnboardingTarget, ao as useOnboardingFlow, ap as ISSUE_STICKER_HOST_ELEMENT_ID, aq as getIssueStickerRuntimeOwner, ar as ISSUE_STICKER_RUNTIME_OWNER, z as isIssueStickerExtensionRuntimeActive, as as createRuntimeHostElement, at as attachHostTypingGuard, au as ISSUE_STICKER_EXTENSION_RUNTIME_READY_EVENT } from "./externalUserPayload-B7zThnol.js";
19
19
  import * as React from "react";
20
20
  import { useRef, useState, useEffect, useId, useLayoutEffect, useCallback, forwardRef, createElement, createContext, useContext, Component, Suspense, useInsertionEffect, useMemo, Children, isValidElement, Fragment as Fragment$1, useSyncExternalStore } from "react";
21
21
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
22
- import { c as createLucideIcon$1, b as usePortalContainer, a as cn$1, O as OVERLAY_LAYER, s as stopEscapePropagation, d as OVERLAY_LAYER_INDEX, e as useControllableState, P as Primitive, f as useId$1, g as composeEventHandlers, h as Presence, i as createContextScope, j as useComposedRefs$1, k as useLayoutEffect2, l as useCallbackRef, m as useDismissableLayerSurface, n as Portal$1, o as createSlot, D as DismissableLayer, p as PortalContainerProvider } from "./createLucideIcon-C0Ldhp96.js";
22
+ import { c as createLucideIcon$1, b as usePortalContainer, a as cn$1, O as OVERLAY_LAYER, s as stopEscapePropagation, d as OVERLAY_LAYER_INDEX, P as Presence, e as Primitive, f as composeEventHandlers, g as useDismissableLayerSurface, h as useComposedRefs$1, i as Portal$1, j as createContextScope, k as createSlot, D as DismissableLayer, l as useControllableState, m as useId$1, n as useLayoutEffect2, o as useCallbackRef, p as PortalContainerProvider } from "./createLucideIcon-BzRMP02h.js";
23
23
  import { createRoot } from "react-dom/client";
24
24
  import { createPortal } from "react-dom";
25
- import { T as TooltipProvider, a as Tooltip, b as TooltipTrigger, c as TooltipContent } from "./tooltip-CEc_RGfI.js";
25
+ import { T as TooltipProvider, a as Tooltip, b as TooltipTrigger, c as TooltipContent } from "./tooltip-B6UPO-U8.js";
26
26
  function readReleaseMarker() {
27
27
  try {
28
28
  const g = globalThis.__ISSUE_STICKER_RELEASE__;
@@ -167,9 +167,10 @@ function createCollectorSession(options = {}) {
167
167
  console: consoleCollector,
168
168
  backup,
169
169
  async start() {
170
+ var _a, _b2;
170
171
  network.start();
171
172
  consoleCollector.start();
172
- const navigationEntry = performanceApi == null ? void 0 : performanceApi.getEntriesByType("navigation")[0];
173
+ const navigationEntry = (_b2 = (_a = performanceApi == null ? void 0 : performanceApi.getEntriesByType) == null ? void 0 : _a.call(performanceApi, "navigation")) == null ? void 0 : _b2[0];
173
174
  const navigationLog = createNavigationLog(navigationEntry, (performanceApi == null ? void 0 : performanceApi.timeOrigin) ?? 0);
174
175
  if (navigationLog) network.ingest(navigationLog);
175
176
  stopResourceObserver = observeResourceLogs(
@@ -491,6 +492,16 @@ function AsyncSearchSelect({
491
492
  }
492
493
  );
493
494
  }
495
+ /**
496
+ * @license lucide-react v0.468.0 - ISC
497
+ *
498
+ * This source code is licensed under the ISC license.
499
+ * See the LICENSE file in the root directory of this source tree.
500
+ */
501
+ const ArrowUp = createLucideIcon$1("ArrowUp", [
502
+ ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
503
+ ["path", { d: "M12 19V5", key: "x0mq9r" }]
504
+ ]);
494
505
  /**
495
506
  * @license lucide-react v0.468.0 - ISC
496
507
  *
@@ -684,6 +695,22 @@ const MapPin = createLucideIcon$1("MapPin", [
684
695
  ],
685
696
  ["circle", { cx: "12", cy: "10", r: "3", key: "ilqhr7" }]
686
697
  ]);
698
+ /**
699
+ * @license lucide-react v0.468.0 - ISC
700
+ *
701
+ * This source code is licensed under the ISC license.
702
+ * See the LICENSE file in the root directory of this source tree.
703
+ */
704
+ const PenLine = createLucideIcon$1("PenLine", [
705
+ ["path", { d: "M12 20h9", key: "t2du7b" }],
706
+ [
707
+ "path",
708
+ {
709
+ d: "M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z",
710
+ key: "1ykcvy"
711
+ }
712
+ ]
713
+ ]);
687
714
  /**
688
715
  * @license lucide-react v0.468.0 - ISC
689
716
  *
@@ -696,6 +723,25 @@ const RefreshCw = createLucideIcon$1("RefreshCw", [
696
723
  ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
697
724
  ["path", { d: "M8 16H3v5", key: "1cv678" }]
698
725
  ]);
726
+ /**
727
+ * @license lucide-react v0.468.0 - ISC
728
+ *
729
+ * This source code is licensed under the ISC license.
730
+ * See the LICENSE file in the root directory of this source tree.
731
+ */
732
+ const Sparkles = createLucideIcon$1("Sparkles", [
733
+ [
734
+ "path",
735
+ {
736
+ d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
737
+ key: "4pj2yx"
738
+ }
739
+ ],
740
+ ["path", { d: "M20 3v4", key: "1olli1" }],
741
+ ["path", { d: "M22 5h-4", key: "1gvqau" }],
742
+ ["path", { d: "M4 17v2", key: "vumght" }],
743
+ ["path", { d: "M5 18H3", key: "zchphs" }]
744
+ ]);
699
745
  /**
700
746
  * @license lucide-react v0.468.0 - ISC
701
747
  *
@@ -1816,9 +1862,9 @@ var FocusManager = (_b = class extends Subscribable {
1816
1862
  }
1817
1863
  }
1818
1864
  onFocus() {
1819
- const isFocused = this.isFocused();
1865
+ const isFocused2 = this.isFocused();
1820
1866
  this.listeners.forEach((listener) => {
1821
- listener(isFocused);
1867
+ listener(isFocused2);
1822
1868
  });
1823
1869
  }
1824
1870
  isFocused() {
@@ -4537,9 +4583,10 @@ function useMutation(options, queryClient2) {
4537
4583
  return { ...result, mutate, mutateAsync: result.mutate };
4538
4584
  }
4539
4585
  const BODY_SCROLLBAR_WIDTH_CSS_VAR = "--issue-sticker-scrollbar-width";
4540
- const useIsomorphicLayoutEffect$1 = typeof window === "undefined" ? useEffect : useLayoutEffect;
4541
- function useDisableBodyScroll() {
4542
- useIsomorphicLayoutEffect$1(() => {
4586
+ const useIsomorphicLayoutEffect$2 = typeof window === "undefined" ? useEffect : useLayoutEffect;
4587
+ function useDisableBodyScroll(enabled = true) {
4588
+ useIsomorphicLayoutEffect$2(() => {
4589
+ if (!enabled) return;
4543
4590
  const body = document.body;
4544
4591
  const root2 = document.documentElement;
4545
4592
  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
@@ -4560,7 +4607,7 @@ function useDisableBodyScroll() {
4560
4607
  root2.style.removeProperty(BODY_SCROLLBAR_WIDTH_CSS_VAR);
4561
4608
  }
4562
4609
  };
4563
- }, []);
4610
+ }, [enabled]);
4564
4611
  }
4565
4612
  function useGuardedCallback(callback) {
4566
4613
  const guardRef = useRef(false);
@@ -5904,355 +5951,22 @@ function DefaultErrorFallback({ resetErrorBoundary }) {
5904
5951
  /* @__PURE__ */ jsx(Button, { variant: "outline", className: "mt-3", onClick: resetErrorBoundary, children: "다시 시도" })
5905
5952
  ] });
5906
5953
  }
5907
- function QueryBoundary({ children, onError, loadingFallback }) {
5908
- const ErrorFallback = onError ?? DefaultErrorFallback;
5909
- return /* @__PURE__ */ jsx(QueryErrorResetBoundary, { children: ({ reset }) => /* @__PURE__ */ jsx(m, { FallbackComponent: ErrorFallback, onReset: reset, children: /* @__PURE__ */ jsx(Suspense, { fallback: loadingFallback ?? /* @__PURE__ */ jsx(Skeleton, {}), children }) }) });
5910
- }
5911
- async function uploadSignedMedia(file, mediaType, issueId) {
5912
- return uploadSignedMediaWithApi(
5913
- {
5914
- post: (endpoint, body) => apiClient.post(endpoint, body),
5915
- directUpload
5916
- },
5917
- file,
5918
- mediaType,
5919
- { issueId }
5920
- );
5921
- }
5922
- function issuesEndpoint() {
5923
- return "/api/sdk/issues";
5924
- }
5925
- function guestOwnerQuery() {
5926
- var _a;
5927
- const mode = getSdkMode();
5928
- if (mode !== "public") return "";
5929
- return buildGuestOwnerQuery(mode, (_a = SDKManager.getInstance().config.user) == null ? void 0 : _a.id);
5930
- }
5931
- let issuesCache = null;
5932
- const CACHE_DURATION_MS = 30 * 1e3;
5933
- const STICKER_PAGE_SIZE = 500;
5934
- const STICKER_FETCH_LIMIT = 2e3;
5935
- function getFilterKey(filters) {
5936
- var _a;
5937
- const normalizeArray = (value) => {
5938
- if (value === "all" || !value) return "all";
5939
- if (Array.isArray(value)) {
5940
- return value.length === 0 ? "all" : [...value].sort().join(",");
5941
- }
5942
- return String(value);
5943
- };
5944
- const normalizeRecord = (record) => {
5945
- if (!record) return "";
5946
- const entries = Object.entries(record).map(([k, v]) => [k, [...v].sort()]).sort(([a], [b]) => a.localeCompare(b));
5947
- return JSON.stringify(entries);
5948
- };
5949
- return JSON.stringify({
5950
- sdkMode: getSdkMode() || "public",
5951
- url: normalizeArray(filters.url),
5952
- projectId: filters.projectId || "all",
5953
- externalUserId: filters.externalUserId || "",
5954
- search: ((_a = filters.search) == null ? void 0 : _a.trim()) || "",
5955
- dateFrom: filters.dateFrom || "",
5956
- dateTo: filters.dateTo || "",
5957
- page: filters.page ?? 0,
5958
- pageSize: filters.pageSize ?? 0,
5959
- custom: normalizeRecord(filters.customFieldValues),
5960
- jira: normalizeRecord(filters.jiraFieldValues),
5961
- notion: normalizeRecord(filters.notionFieldValues),
5962
- sortOrder: filters.sortOrder || ""
5963
- });
5964
- }
5965
- function invalidateIssuesCache() {
5966
- issuesCache = null;
5967
- }
5968
- function recordToFilterArray(record, keyFieldName) {
5969
- if (!record) return null;
5970
- const entries = Object.entries(record).filter(([, values]) => values.length > 0);
5971
- if (entries.length === 0) return null;
5972
- return entries.map(
5973
- ([key, values]) => ({ [keyFieldName]: key, values })
5974
- );
5975
- }
5976
- function buildFilterQueryParams(filters, options = {}) {
5977
- var _a;
5978
- const params = new URLSearchParams();
5979
- if (filters.projectId) {
5980
- params.set("project_id", filters.projectId);
5981
- }
5982
- if (filters.url && filters.url !== "all") {
5983
- if (Array.isArray(filters.url) && filters.url.length > 0) {
5984
- params.set("url", filters.url.join(","));
5985
- } else if (typeof filters.url === "string") {
5986
- params.set("url", filters.url);
5987
- }
5988
- }
5989
- if (options.includeListFilters) {
5990
- const search2 = (_a = filters.search) == null ? void 0 : _a.trim();
5991
- if (search2) {
5992
- params.set("search", search2);
5993
- }
5994
- if (filters.dateFrom) {
5995
- params.set("date_from", filters.dateFrom);
5996
- }
5997
- if (filters.dateTo) {
5998
- params.set("date_to", filters.dateTo);
5999
- }
6000
- const customArr = recordToFilterArray(filters.customFieldValues, "fieldDefinitionId");
6001
- if (customArr) {
6002
- params.set("custom_field_filters", JSON.stringify(customArr));
6003
- }
6004
- const jiraArr = recordToFilterArray(filters.jiraFieldValues, "fieldName");
6005
- if (jiraArr) {
6006
- params.set("jira_field_filters", JSON.stringify(jiraArr));
6007
- }
6008
- const notionArr = recordToFilterArray(filters.notionFieldValues, "fieldName");
6009
- if (notionArr) {
6010
- params.set("notion_field_filters", JSON.stringify(notionArr));
6011
- }
6012
- }
6013
- if (filters.externalUserId) {
6014
- params.set("external_user_id", filters.externalUserId);
6015
- }
6016
- if (typeof filters.page === "number" && filters.page > 0) {
6017
- params.set("page", String(filters.page));
6018
- }
6019
- if (typeof filters.pageSize === "number" && filters.pageSize > 0) {
6020
- params.set("page_size", String(filters.pageSize));
6021
- }
6022
- if (filters.sortOrder) {
6023
- params.set("sort_order", filters.sortOrder);
6024
- }
6025
- const queryString = params.toString();
6026
- return queryString ? `?${queryString}` : "";
6027
- }
6028
- const issueService = {
6029
- async createIssue(issueData) {
6030
- const sanitizedData = sanitizeString(issueData);
6031
- const screenshotUploadIds = (sanitizedData.screenshot || []).map((url) => getRegisteredUploadId(url, "screenshot")).filter((id2) => typeof id2 === "string" && id2.length > 0);
6032
- const videoUploadId = sanitizedData.video ? getRegisteredUploadId(sanitizedData.video, "video") : void 0;
6033
- if (screenshotUploadIds.length > 0) {
6034
- sanitizedData.screenshot_upload_ids = screenshotUploadIds;
6035
- }
6036
- if (videoUploadId) {
6037
- sanitizedData.video_upload_id = videoUploadId;
6038
- }
6039
- const issue = await apiClient.post(issuesEndpoint(), sanitizedData);
6040
- invalidateIssuesCache();
6041
- return issue;
6042
- },
6043
- async getIssues(filters = {}, options = {}) {
6044
- if (!filters.projectId) {
6045
- throw new Error("프로젝트 ID가 필요합니다. 로그인 상태를 확인해주세요.");
6046
- }
6047
- const filterKey = getFilterKey(filters);
6048
- const now2 = Date.now();
6049
- if (!options.forceRefresh && issuesCache && issuesCache.filterKey === filterKey && now2 - issuesCache.timestamp < CACHE_DURATION_MS) {
6050
- return issuesCache.data;
6051
- }
6052
- const queryParams = buildFilterQueryParams(filters, { includeListFilters: true });
6053
- const { items: issues = [] } = await apiClient.get(
6054
- `${issuesEndpoint()}${queryParams}`
6055
- );
6056
- issuesCache = {
6057
- data: issues,
6058
- timestamp: now2,
6059
- filterKey
6060
- };
6061
- return issues;
6062
- },
6063
- async getIssueStickers(filters = {}, options = {}) {
6064
- var _a, _b2;
6065
- if (!filters.projectId) {
6066
- throw new Error("프로젝트 ID가 필요합니다. 로그인 상태를 확인해주세요.");
6067
- }
6068
- const filterKey = `${getFilterKey(filters)}:stickers`;
6069
- const now2 = Date.now();
6070
- if (!options.forceRefresh && issuesCache && issuesCache.filterKey === filterKey && now2 - issuesCache.timestamp < CACHE_DURATION_MS) {
6071
- return issuesCache.data;
6072
- }
6073
- const issues = [];
6074
- let page = 1;
6075
- let hasMore = true;
6076
- while (hasMore && issues.length <= STICKER_FETCH_LIMIT) {
6077
- const response = await apiClient.getResponse(
6078
- `${issuesEndpoint()}/stickers${buildFilterQueryParams({
6079
- ...filters,
6080
- page,
6081
- pageSize: STICKER_PAGE_SIZE
6082
- })}`
6083
- );
6084
- const pageItems = ((_a = response.data) == null ? void 0 : _a.items) ?? [];
6085
- issues.push(...pageItems);
6086
- hasMore = Boolean((_b2 = response.data) == null ? void 0 : _b2.hasMore) && pageItems.length > 0;
6087
- page += 1;
6088
- }
6089
- issuesCache = {
6090
- data: issues,
6091
- timestamp: now2,
6092
- filterKey
6093
- };
6094
- return issues;
6095
- },
6096
- invalidateCache() {
6097
- invalidateIssuesCache();
6098
- },
6099
- // 계약 정본: 백엔드 GET /api/sdk/issues/:id 는 back#101부터 읽기-시점-스크럽된
6100
- // llm_prompt 를 상세 응답에 포함한다(목록 응답에는 없음) — 스코프를 이 반환 타입에만 한정한다.
6101
- async getIssue(id2) {
6102
- return apiClient.get(
6103
- `${issuesEndpoint()}/${id2}${guestOwnerQuery()}`
6104
- );
6105
- },
6106
- async updateIssue(id2, updates) {
6107
- const sanitizedUpdates = sanitizeString(updates);
6108
- const issue = await apiClient.put(
6109
- `${issuesEndpoint()}/${id2}${guestOwnerQuery()}`,
6110
- sanitizedUpdates
6111
- );
6112
- invalidateIssuesCache();
6113
- return issue;
6114
- },
6115
- async deleteIssue(id2, options) {
6116
- const endpoint = `${issuesEndpoint()}/${id2}${guestOwnerQuery()}`;
6117
- if (options == null ? void 0 : options.deleteExternal) {
6118
- await apiClient.delete(endpoint, {
6119
- body: { deleteExternal: true }
6120
- });
6121
- } else {
6122
- await apiClient.delete(endpoint);
6123
- }
6124
- invalidateIssuesCache();
6125
- }
6126
- };
6127
- async function loadIssuesFromServer(url, projectId, externalUserId, options = {}) {
6128
- if (!projectId) return [];
6129
- try {
6130
- return await issueService.getIssueStickers(
6131
- {
6132
- url,
6133
- projectId,
6134
- ...externalUserId ? { externalUserId } : {}
6135
- },
6136
- options
6137
- ) || [];
6138
- } catch (error) {
6139
- devLogger.error("useIssues", "Failed to load issues:", error);
6140
- return [];
6141
- }
6142
- }
6143
- const contentProjectIdQueryKey = ["contentProjectId"];
6144
- const contentIssuesQueryRoot = ["contentIssues"];
6145
- function contentIssuesQueryKey({
6146
- currentUrl,
6147
- projectId,
6148
- isMember,
6149
- externalUserId
6150
- }) {
6151
- return [...contentIssuesQueryRoot, currentUrl, projectId, isMember, externalUserId];
6152
- }
6153
- function fetchContentIssues({
6154
- currentUrl,
6155
- projectId,
6156
- isMember,
6157
- externalUserId,
6158
- forceRefresh
6159
- }) {
6160
- return loadIssuesFromServer(currentUrl, projectId, isMember ? void 0 : externalUserId, {
6161
- forceRefresh
6162
- });
6163
- }
6164
- function useIssues(currentUrl) {
6165
- var _a;
6166
- const { isMember } = useAuthContext();
6167
- const config = SDKManager.getInstance().config;
6168
- const sessionIssuesRef = useRef([]);
6169
- const projectIdQuery = useSuspenseQuery({
6170
- queryKey: contentProjectIdQueryKey,
6171
- queryFn: async () => {
6172
- const accountInfo = await getAccountInfo();
6173
- return (accountInfo == null ? void 0 : accountInfo.projectId) ?? null;
6174
- }
6175
- });
6176
- const projectId = projectIdQuery.data;
6177
- const { data: serverIssues = [] } = useSuspenseQuery({
6178
- queryKey: contentIssuesQueryKey({
6179
- currentUrl,
6180
- projectId,
6181
- isMember,
6182
- externalUserId: (_a = config.user) == null ? void 0 : _a.id
6183
- }),
6184
- queryFn: () => {
6185
- var _a2;
6186
- return fetchContentIssues({
6187
- currentUrl,
6188
- projectId,
6189
- isMember,
6190
- externalUserId: (_a2 = config.user) == null ? void 0 : _a2.id
6191
- });
6192
- }
5954
+ let reloadToastId = null;
5955
+ function showReloadToast() {
5956
+ if (reloadToastId && getSnapshot().some((t) => t.id === reloadToastId)) return;
5957
+ reloadToastId = toast.error("이슈 정보를 불러오지 못했습니다. 페이지를 새로고침해주세요.", {
5958
+ // 사용자가 새로고침하거나 닫을 때까지 남긴다.
5959
+ duration: 0,
5960
+ action: { label: "새로고침", onClick: () => window.location.reload() }
6193
5961
  });
6194
- const issues = !isMember && !config.user ? [...serverIssues, ...sessionIssuesRef.current] : serverIssues;
6195
- const addSessionIssue = useCallback((issue) => {
6196
- sessionIssuesRef.current = [...sessionIssuesRef.current, issue];
6197
- }, []);
6198
- const loadIssues = useCallback(async () => {
6199
- issueService.invalidateCache();
6200
- await Promise.all([
6201
- queryClient.invalidateQueries({ queryKey: contentIssuesQueryRoot }),
6202
- queryClient.invalidateQueries({ queryKey: contentProjectIdQueryKey })
6203
- ]);
6204
- }, []);
6205
- return {
6206
- issues,
6207
- loadIssues,
6208
- addSessionIssue
6209
- };
6210
5962
  }
6211
- function readCurrentUrl() {
6212
- return getCurrentPageUrl();
5963
+ function OverlayErrorFallback() {
5964
+ useEffect(showReloadToast, []);
5965
+ return null;
6213
5966
  }
6214
- function usePrefetchContentIssues() {
6215
- const { isAuthenticated, isLoading, isMember, projectId, accountId, token } = useAuthContext();
6216
- const lastFetchKeyRef = useRef(null);
6217
- useEffect(() => {
6218
- var _a;
6219
- if (isLoading || !isAuthenticated || !projectId) {
6220
- return;
6221
- }
6222
- const currentUrl = readCurrentUrl();
6223
- const externalUserId = (_a = SDKManager.getInstance().config.user) == null ? void 0 : _a.id;
6224
- const fetchKey = [
6225
- currentUrl,
6226
- projectId,
6227
- isMember ? "member" : "public",
6228
- accountId ?? "",
6229
- token ?? "",
6230
- externalUserId ?? ""
6231
- ].join("|");
6232
- if (lastFetchKeyRef.current === fetchKey) {
6233
- return;
6234
- }
6235
- lastFetchKeyRef.current = fetchKey;
6236
- queryClient.setQueryData(contentProjectIdQueryKey, projectId);
6237
- void queryClient.fetchQuery({
6238
- queryKey: contentIssuesQueryKey({
6239
- currentUrl,
6240
- projectId,
6241
- isMember,
6242
- externalUserId
6243
- }),
6244
- queryFn: () => fetchContentIssues({
6245
- currentUrl,
6246
- projectId,
6247
- isMember,
6248
- externalUserId,
6249
- forceRefresh: true
6250
- }),
6251
- staleTime: 0
6252
- }).catch((error) => {
6253
- devLogger.error("usePrefetchContentIssues", "Failed to prefetch issues:", error);
6254
- });
6255
- }, [accountId, isAuthenticated, isLoading, isMember, projectId, token]);
5967
+ function QueryBoundary({ children, onError, loadingFallback }) {
5968
+ const ErrorFallback = onError ?? DefaultErrorFallback;
5969
+ return /* @__PURE__ */ jsx(QueryErrorResetBoundary, { children: ({ reset }) => /* @__PURE__ */ jsx(m, { FallbackComponent: ErrorFallback, onReset: reset, children: /* @__PURE__ */ jsx(Suspense, { fallback: loadingFallback ?? /* @__PURE__ */ jsx(Skeleton, {}), children }) }) });
6256
5970
  }
6257
5971
  const LayoutGroupContext = createContext({});
6258
5972
  function useConstant(init) {
@@ -6263,7 +5977,7 @@ function useConstant(init) {
6263
5977
  return ref.current;
6264
5978
  }
6265
5979
  const isBrowser$1 = typeof window !== "undefined";
6266
- const useIsomorphicLayoutEffect = isBrowser$1 ? useLayoutEffect : useEffect;
5980
+ const useIsomorphicLayoutEffect$1 = isBrowser$1 ? useLayoutEffect : useEffect;
6267
5981
  const PresenceContext = /* @__PURE__ */ createContext(null);
6268
5982
  function addUniqueItem(arr, item) {
6269
5983
  if (arr.indexOf(item) === -1)
@@ -12530,7 +12244,7 @@ const PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, p
12530
12244
  const id2 = useId();
12531
12245
  const isPresentRef = useRef(isPresent);
12532
12246
  const onExitCompleteRef = useRef(onExitComplete);
12533
- useIsomorphicLayoutEffect(() => {
12247
+ useIsomorphicLayoutEffect$1(() => {
12534
12248
  isPresentRef.current = isPresent;
12535
12249
  onExitCompleteRef.current = onExitComplete;
12536
12250
  });
@@ -12608,7 +12322,7 @@ const AnimatePresence = ({ children, custom, initial = true, onExitComplete, pre
12608
12322
  const exitingComponents = useRef(/* @__PURE__ */ new Set());
12609
12323
  const [diffedChildren, setDiffedChildren] = useState(presentChildren);
12610
12324
  const [renderedChildren, setRenderedChildren] = useState(presentChildren);
12611
- useIsomorphicLayoutEffect(() => {
12325
+ useIsomorphicLayoutEffect$1(() => {
12612
12326
  isInitialRender.current = false;
12613
12327
  pendingPresentChildren.current = presentChildren;
12614
12328
  for (let i = 0; i < renderedChildren.length; i++) {
@@ -13061,7 +12775,7 @@ function useVisualElement(Component2, visualState, props, createVisualElement, P
13061
12775
  });
13062
12776
  const optimisedAppearId = props[optimizedAppearDataAttribute];
13063
12777
  const wantsHandoff = useRef(Boolean(optimisedAppearId) && typeof window !== "undefined" && !((_a = window.MotionHandoffIsComplete) == null ? void 0 : _a.call(window, optimisedAppearId)) && ((_b2 = window.MotionHasOptimisedAnimation) == null ? void 0 : _b2.call(window, optimisedAppearId)));
13064
- useIsomorphicLayoutEffect(() => {
12778
+ useIsomorphicLayoutEffect$1(() => {
13065
12779
  hasMountedOnce.current = true;
13066
12780
  if (!visualElement)
13067
12781
  return;
@@ -14391,6 +14105,11 @@ const featureBundle = {
14391
14105
  ...layout
14392
14106
  };
14393
14107
  const motion$1 = /* @__PURE__ */ createMotionProxy(featureBundle, createDomVisualElement);
14108
+ function useReducedMotion() {
14109
+ !hasReducedMotionListener.current && initPrefersReducedMotion();
14110
+ const [shouldReduceMotion] = useState(prefersReducedMotion.current);
14111
+ return shouldReduceMotion;
14112
+ }
14394
14113
  const motion = motion$1;
14395
14114
  const TYPE_STYLES = {
14396
14115
  default: {
@@ -14504,6 +14223,407 @@ function ToastContainer({ position: position2 = "top-right" }) {
14504
14223
  if (typeof document === "undefined") return null;
14505
14224
  return createPortal(content2, portalContainer ?? document.body);
14506
14225
  }
14226
+ const POLL_INTERVAL_MS = 3e3;
14227
+ const MAX_POLLS = 10;
14228
+ function isGeneratingStatus(status) {
14229
+ return status === "pending" || status === "processing";
14230
+ }
14231
+ function useGenerationPolling({
14232
+ status,
14233
+ onRefetch,
14234
+ maxPolls = MAX_POLLS,
14235
+ intervalMs = POLL_INTERVAL_MS,
14236
+ restartKey
14237
+ }) {
14238
+ const refetchRef = useRef(onRefetch);
14239
+ refetchRef.current = onRefetch;
14240
+ useEffect(() => {
14241
+ if (status !== "pending" && status !== "processing") return;
14242
+ let polls = 0;
14243
+ const timer = setInterval(() => {
14244
+ polls += 1;
14245
+ refetchRef.current();
14246
+ if (polls >= maxPolls) clearInterval(timer);
14247
+ }, intervalMs);
14248
+ return () => clearInterval(timer);
14249
+ }, [status, restartKey, maxPolls, intervalMs]);
14250
+ }
14251
+ function useIssueListGenerationPolling({
14252
+ issues,
14253
+ onRefetch
14254
+ }) {
14255
+ const generatingIds = issues.filter((issue) => isGeneratingStatus(issue.generation_status)).map((issue) => issue.id).sort().join(",");
14256
+ useGenerationPolling({
14257
+ status: generatingIds ? "pending" : null,
14258
+ restartKey: generatingIds,
14259
+ onRefetch
14260
+ });
14261
+ }
14262
+ async function uploadSignedMedia(file, mediaType, issueId) {
14263
+ return uploadSignedMediaWithApi(
14264
+ {
14265
+ post: (endpoint, body) => apiClient.post(endpoint, body),
14266
+ directUpload
14267
+ },
14268
+ file,
14269
+ mediaType,
14270
+ { issueId }
14271
+ );
14272
+ }
14273
+ function issuesEndpoint() {
14274
+ return "/api/sdk/issues";
14275
+ }
14276
+ function guestOwnerQuery() {
14277
+ var _a;
14278
+ const mode = getSdkMode();
14279
+ if (mode !== "public") return "";
14280
+ return buildGuestOwnerQuery(mode, (_a = SDKManager.getInstance().config.user) == null ? void 0 : _a.id);
14281
+ }
14282
+ let issuesCache = null;
14283
+ const CACHE_DURATION_MS = 30 * 1e3;
14284
+ const STICKER_PAGE_SIZE = 500;
14285
+ const STICKER_FETCH_LIMIT = 2e3;
14286
+ function getFilterKey(filters) {
14287
+ var _a;
14288
+ const normalizeArray = (value) => {
14289
+ if (value === "all" || !value) return "all";
14290
+ if (Array.isArray(value)) {
14291
+ return value.length === 0 ? "all" : [...value].sort().join(",");
14292
+ }
14293
+ return String(value);
14294
+ };
14295
+ const normalizeRecord = (record) => {
14296
+ if (!record) return "";
14297
+ const entries = Object.entries(record).map(([k, v]) => [k, [...v].sort()]).sort(([a], [b]) => a.localeCompare(b));
14298
+ return JSON.stringify(entries);
14299
+ };
14300
+ return JSON.stringify({
14301
+ sdkMode: getSdkMode() || "public",
14302
+ url: normalizeArray(filters.url),
14303
+ projectId: filters.projectId || "all",
14304
+ externalUserId: filters.externalUserId || "",
14305
+ search: ((_a = filters.search) == null ? void 0 : _a.trim()) || "",
14306
+ dateFrom: filters.dateFrom || "",
14307
+ dateTo: filters.dateTo || "",
14308
+ page: filters.page ?? 0,
14309
+ pageSize: filters.pageSize ?? 0,
14310
+ custom: normalizeRecord(filters.customFieldValues),
14311
+ jira: normalizeRecord(filters.jiraFieldValues),
14312
+ notion: normalizeRecord(filters.notionFieldValues),
14313
+ sortOrder: filters.sortOrder || ""
14314
+ });
14315
+ }
14316
+ function invalidateIssuesCache() {
14317
+ issuesCache = null;
14318
+ }
14319
+ function recordToFilterArray(record, keyFieldName) {
14320
+ if (!record) return null;
14321
+ const entries = Object.entries(record).filter(([, values]) => values.length > 0);
14322
+ if (entries.length === 0) return null;
14323
+ return entries.map(
14324
+ ([key, values]) => ({ [keyFieldName]: key, values })
14325
+ );
14326
+ }
14327
+ function buildFilterQueryParams(filters, options = {}) {
14328
+ var _a;
14329
+ const params = new URLSearchParams();
14330
+ if (filters.projectId) {
14331
+ params.set("project_id", filters.projectId);
14332
+ }
14333
+ if (filters.url && filters.url !== "all") {
14334
+ if (Array.isArray(filters.url) && filters.url.length > 0) {
14335
+ params.set("url", filters.url.join(","));
14336
+ } else if (typeof filters.url === "string") {
14337
+ params.set("url", filters.url);
14338
+ }
14339
+ }
14340
+ if (options.includeListFilters) {
14341
+ const search2 = (_a = filters.search) == null ? void 0 : _a.trim();
14342
+ if (search2) {
14343
+ params.set("search", search2);
14344
+ }
14345
+ if (filters.dateFrom) {
14346
+ params.set("date_from", filters.dateFrom);
14347
+ }
14348
+ if (filters.dateTo) {
14349
+ params.set("date_to", filters.dateTo);
14350
+ }
14351
+ const customArr = recordToFilterArray(filters.customFieldValues, "fieldDefinitionId");
14352
+ if (customArr) {
14353
+ params.set("custom_field_filters", JSON.stringify(customArr));
14354
+ }
14355
+ const jiraArr = recordToFilterArray(filters.jiraFieldValues, "fieldName");
14356
+ if (jiraArr) {
14357
+ params.set("jira_field_filters", JSON.stringify(jiraArr));
14358
+ }
14359
+ const notionArr = recordToFilterArray(filters.notionFieldValues, "fieldName");
14360
+ if (notionArr) {
14361
+ params.set("notion_field_filters", JSON.stringify(notionArr));
14362
+ }
14363
+ }
14364
+ if (filters.externalUserId) {
14365
+ params.set("external_user_id", filters.externalUserId);
14366
+ }
14367
+ if (typeof filters.page === "number" && filters.page > 0) {
14368
+ params.set("page", String(filters.page));
14369
+ }
14370
+ if (typeof filters.pageSize === "number" && filters.pageSize > 0) {
14371
+ params.set("page_size", String(filters.pageSize));
14372
+ }
14373
+ if (filters.sortOrder) {
14374
+ params.set("sort_order", filters.sortOrder);
14375
+ }
14376
+ const queryString = params.toString();
14377
+ return queryString ? `?${queryString}` : "";
14378
+ }
14379
+ const issueService = {
14380
+ async createIssue(issueData) {
14381
+ const sanitizedData = sanitizeString(issueData);
14382
+ const screenshotUploadIds = (sanitizedData.screenshot || []).map((url) => getRegisteredUploadId(url, "screenshot")).filter((id2) => typeof id2 === "string" && id2.length > 0);
14383
+ const videoUploadId = sanitizedData.video ? getRegisteredUploadId(sanitizedData.video, "video") : void 0;
14384
+ if (screenshotUploadIds.length > 0) {
14385
+ sanitizedData.screenshot_upload_ids = screenshotUploadIds;
14386
+ }
14387
+ if (videoUploadId) {
14388
+ sanitizedData.video_upload_id = videoUploadId;
14389
+ }
14390
+ const issue = await apiClient.post(issuesEndpoint(), sanitizedData);
14391
+ invalidateIssuesCache();
14392
+ return issue;
14393
+ },
14394
+ async getIssues(filters = {}, options = {}) {
14395
+ if (!filters.projectId) {
14396
+ throw new Error("프로젝트 ID가 필요합니다. 로그인 상태를 확인해주세요.");
14397
+ }
14398
+ const filterKey = getFilterKey(filters);
14399
+ const now2 = Date.now();
14400
+ if (!options.forceRefresh && issuesCache && issuesCache.filterKey === filterKey && now2 - issuesCache.timestamp < CACHE_DURATION_MS) {
14401
+ return issuesCache.data;
14402
+ }
14403
+ const queryParams = buildFilterQueryParams(filters, { includeListFilters: true });
14404
+ const { items: issues = [] } = await apiClient.get(
14405
+ `${issuesEndpoint()}${queryParams}`
14406
+ );
14407
+ issuesCache = {
14408
+ data: issues,
14409
+ timestamp: now2,
14410
+ filterKey
14411
+ };
14412
+ return issues;
14413
+ },
14414
+ async getIssueStickers(filters = {}, options = {}) {
14415
+ var _a, _b2;
14416
+ if (!filters.projectId) {
14417
+ throw new Error("프로젝트 ID가 필요합니다. 로그인 상태를 확인해주세요.");
14418
+ }
14419
+ const filterKey = `${getFilterKey(filters)}:stickers`;
14420
+ const now2 = Date.now();
14421
+ if (!options.forceRefresh && issuesCache && issuesCache.filterKey === filterKey && now2 - issuesCache.timestamp < CACHE_DURATION_MS) {
14422
+ return issuesCache.data;
14423
+ }
14424
+ const issues = [];
14425
+ let page = 1;
14426
+ let hasMore = true;
14427
+ while (hasMore && issues.length <= STICKER_FETCH_LIMIT) {
14428
+ const response = await apiClient.getResponse(
14429
+ `${issuesEndpoint()}/stickers${buildFilterQueryParams({
14430
+ ...filters,
14431
+ page,
14432
+ pageSize: STICKER_PAGE_SIZE
14433
+ })}`
14434
+ );
14435
+ const pageItems = ((_a = response.data) == null ? void 0 : _a.items) ?? [];
14436
+ issues.push(...pageItems);
14437
+ hasMore = Boolean((_b2 = response.data) == null ? void 0 : _b2.hasMore) && pageItems.length > 0;
14438
+ page += 1;
14439
+ }
14440
+ issuesCache = {
14441
+ data: issues,
14442
+ timestamp: now2,
14443
+ filterKey
14444
+ };
14445
+ return issues;
14446
+ },
14447
+ invalidateCache() {
14448
+ invalidateIssuesCache();
14449
+ },
14450
+ // 계약 정본: 백엔드 GET /api/sdk/issues/:id 는 back#101부터 읽기-시점-스크럽된
14451
+ // llm_prompt 를 상세 응답에 포함한다(목록 응답에는 없음) — 스코프를 이 반환 타입에만 한정한다.
14452
+ async getIssue(id2) {
14453
+ return apiClient.get(
14454
+ `${issuesEndpoint()}/${id2}${guestOwnerQuery()}`
14455
+ );
14456
+ },
14457
+ async updateIssue(id2, updates) {
14458
+ const sanitizedUpdates = sanitizeString(updates);
14459
+ const issue = await apiClient.put(
14460
+ `${issuesEndpoint()}/${id2}${guestOwnerQuery()}`,
14461
+ sanitizedUpdates
14462
+ );
14463
+ invalidateIssuesCache();
14464
+ return issue;
14465
+ },
14466
+ /**
14467
+ * 재생성. 스펙상 세 표면 모두에서 되고 역할과 무관하다 — 게이트는 역할이 아니라
14468
+ * 그 이슈에 접근할 수 있는지다(백엔드가 판정한다).
14469
+ *
14470
+ * 응답으로 갱신된 이슈가 오지만 상태는 다시 pending 이다. 호출부는 응답을
14471
+ * 그대로 쓰지 말고 폴링으로 이어받아야 한다.
14472
+ */
14473
+ async regenerateIssue(id2) {
14474
+ const issue = await apiClient.post(
14475
+ `${issuesEndpoint()}/${encodeURIComponent(id2)}/regenerate${guestOwnerQuery()}`,
14476
+ {}
14477
+ );
14478
+ invalidateIssuesCache();
14479
+ return issue;
14480
+ },
14481
+ async deleteIssue(id2, options) {
14482
+ const endpoint = `${issuesEndpoint()}/${id2}${guestOwnerQuery()}`;
14483
+ if (options == null ? void 0 : options.deleteExternal) {
14484
+ await apiClient.delete(endpoint, {
14485
+ body: { deleteExternal: true }
14486
+ });
14487
+ } else {
14488
+ await apiClient.delete(endpoint);
14489
+ }
14490
+ invalidateIssuesCache();
14491
+ }
14492
+ };
14493
+ async function loadIssuesFromServer(url, projectId, externalUserId, options = {}) {
14494
+ if (!projectId) return [];
14495
+ try {
14496
+ return await issueService.getIssueStickers(
14497
+ {
14498
+ url,
14499
+ projectId,
14500
+ ...externalUserId ? { externalUserId } : {}
14501
+ },
14502
+ options
14503
+ ) || [];
14504
+ } catch (error) {
14505
+ devLogger.error("useIssues", "Failed to load issues:", error);
14506
+ return [];
14507
+ }
14508
+ }
14509
+ const contentProjectIdQueryKey = ["contentProjectId"];
14510
+ const contentIssuesQueryRoot = ["contentIssues"];
14511
+ function contentIssuesQueryKey({
14512
+ currentUrl,
14513
+ projectId,
14514
+ isMember,
14515
+ externalUserId
14516
+ }) {
14517
+ return [...contentIssuesQueryRoot, currentUrl, projectId, isMember, externalUserId];
14518
+ }
14519
+ function fetchContentIssues({
14520
+ currentUrl,
14521
+ projectId,
14522
+ isMember,
14523
+ externalUserId,
14524
+ forceRefresh
14525
+ }) {
14526
+ return loadIssuesFromServer(currentUrl, projectId, isMember ? void 0 : externalUserId, {
14527
+ forceRefresh
14528
+ });
14529
+ }
14530
+ function useIssues(currentUrl) {
14531
+ var _a;
14532
+ const { isMember } = useAuthContext();
14533
+ const config = SDKManager.getInstance().config;
14534
+ const sessionIssuesRef = useRef([]);
14535
+ const projectIdQuery = useSuspenseQuery({
14536
+ queryKey: contentProjectIdQueryKey,
14537
+ queryFn: async () => {
14538
+ const accountInfo = await getAccountInfo();
14539
+ return (accountInfo == null ? void 0 : accountInfo.projectId) ?? null;
14540
+ }
14541
+ });
14542
+ const projectId = projectIdQuery.data;
14543
+ const { data: serverIssues = [] } = useSuspenseQuery({
14544
+ queryKey: contentIssuesQueryKey({
14545
+ currentUrl,
14546
+ projectId,
14547
+ isMember,
14548
+ externalUserId: (_a = config.user) == null ? void 0 : _a.id
14549
+ }),
14550
+ queryFn: () => {
14551
+ var _a2;
14552
+ return fetchContentIssues({
14553
+ currentUrl,
14554
+ projectId,
14555
+ isMember,
14556
+ externalUserId: (_a2 = config.user) == null ? void 0 : _a2.id
14557
+ });
14558
+ }
14559
+ });
14560
+ const issues = !isMember && !config.user ? [...serverIssues, ...sessionIssuesRef.current] : serverIssues;
14561
+ const addSessionIssue = useCallback((issue) => {
14562
+ sessionIssuesRef.current = [...sessionIssuesRef.current, issue];
14563
+ }, []);
14564
+ const loadIssues = useCallback(async () => {
14565
+ issueService.invalidateCache();
14566
+ await Promise.all([
14567
+ queryClient.invalidateQueries({ queryKey: contentIssuesQueryRoot }),
14568
+ queryClient.invalidateQueries({ queryKey: contentProjectIdQueryKey })
14569
+ ]);
14570
+ }, []);
14571
+ useIssueListGenerationPolling({
14572
+ issues: serverIssues,
14573
+ onRefetch: () => void loadIssues()
14574
+ });
14575
+ return {
14576
+ issues,
14577
+ loadIssues,
14578
+ addSessionIssue
14579
+ };
14580
+ }
14581
+ function readCurrentUrl() {
14582
+ return getCurrentPageUrl();
14583
+ }
14584
+ function usePrefetchContentIssues() {
14585
+ const { isAuthenticated, isLoading, isMember, projectId, accountId, token } = useAuthContext();
14586
+ const lastFetchKeyRef = useRef(null);
14587
+ useEffect(() => {
14588
+ var _a;
14589
+ if (isLoading || !isAuthenticated || !projectId) {
14590
+ return;
14591
+ }
14592
+ const currentUrl = readCurrentUrl();
14593
+ const externalUserId = (_a = SDKManager.getInstance().config.user) == null ? void 0 : _a.id;
14594
+ const fetchKey = [
14595
+ currentUrl,
14596
+ projectId,
14597
+ isMember ? "member" : "public",
14598
+ accountId ?? "",
14599
+ token ?? "",
14600
+ externalUserId ?? ""
14601
+ ].join("|");
14602
+ if (lastFetchKeyRef.current === fetchKey) {
14603
+ return;
14604
+ }
14605
+ lastFetchKeyRef.current = fetchKey;
14606
+ queryClient.setQueryData(contentProjectIdQueryKey, projectId);
14607
+ void queryClient.fetchQuery({
14608
+ queryKey: contentIssuesQueryKey({
14609
+ currentUrl,
14610
+ projectId,
14611
+ isMember,
14612
+ externalUserId
14613
+ }),
14614
+ queryFn: () => fetchContentIssues({
14615
+ currentUrl,
14616
+ projectId,
14617
+ isMember,
14618
+ externalUserId,
14619
+ forceRefresh: true
14620
+ }),
14621
+ staleTime: 0
14622
+ }).catch((error) => {
14623
+ devLogger.error("usePrefetchContentIssues", "Failed to prefetch issues:", error);
14624
+ });
14625
+ }, [accountId, isAuthenticated, isLoading, isMember, projectId, token]);
14626
+ }
14507
14627
  function UnrenderedStickerDialog({
14508
14628
  open,
14509
14629
  items,
@@ -14587,6 +14707,74 @@ function UnrenderedStickerDialog({
14587
14707
  }
14588
14708
  );
14589
14709
  }
14710
+ function getDeepActiveElement(root2 = document) {
14711
+ var _a;
14712
+ let active = root2.activeElement;
14713
+ while ((_a = active == null ? void 0 : active.shadowRoot) == null ? void 0 : _a.activeElement) {
14714
+ active = active.shadowRoot.activeElement;
14715
+ }
14716
+ return active;
14717
+ }
14718
+ const FOCUSABLE_SELECTOR = [
14719
+ "a[href]",
14720
+ "button:not([disabled])",
14721
+ "input:not([disabled])",
14722
+ "select:not([disabled])",
14723
+ "textarea:not([disabled])",
14724
+ '[tabindex]:not([tabindex="-1"])'
14725
+ ].join(",");
14726
+ function isVisible(element2, container) {
14727
+ if (getComputedStyle(element2).visibility === "hidden") return false;
14728
+ let node2 = element2;
14729
+ while (node2) {
14730
+ if (getComputedStyle(node2).display === "none") return false;
14731
+ if (node2 === container) break;
14732
+ node2 = node2.parentElement;
14733
+ }
14734
+ return true;
14735
+ }
14736
+ function tabbables(container) {
14737
+ return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
14738
+ (element2) => element2.tabIndex >= 0 && isVisible(element2, container)
14739
+ );
14740
+ }
14741
+ function useOverlayFocus({
14742
+ enabled,
14743
+ container,
14744
+ initialFocusRef,
14745
+ initialFocus = "first"
14746
+ }) {
14747
+ useEffect(() => {
14748
+ if (!enabled || !container) return;
14749
+ const restoreTo = getDeepActiveElement();
14750
+ const target = (initialFocusRef == null ? void 0 : initialFocusRef.current) ?? (initialFocus === "container" ? container : tabbables(container)[0] ?? container);
14751
+ target.focus({ preventScroll: true });
14752
+ const handleKeyDown = (event) => {
14753
+ if (event.key !== "Tab") return;
14754
+ const items = tabbables(container);
14755
+ const first = items[0];
14756
+ const last = items[items.length - 1];
14757
+ if (!first || !last) {
14758
+ event.preventDefault();
14759
+ return;
14760
+ }
14761
+ const active = getDeepActiveElement();
14762
+ const outside = !active || !container.contains(active);
14763
+ if (!event.shiftKey && (outside || active === last)) {
14764
+ event.preventDefault();
14765
+ first.focus({ preventScroll: true });
14766
+ } else if (event.shiftKey && (outside || active === first)) {
14767
+ event.preventDefault();
14768
+ last.focus({ preventScroll: true });
14769
+ }
14770
+ };
14771
+ container.addEventListener("keydown", handleKeyDown);
14772
+ return () => {
14773
+ container.removeEventListener("keydown", handleKeyDown);
14774
+ if (restoreTo == null ? void 0 : restoreTo.isConnected) restoreTo.focus({ preventScroll: true });
14775
+ };
14776
+ }, [enabled, container, initialFocusRef, initialFocus]);
14777
+ }
14590
14778
  function OverlayShell({
14591
14779
  open,
14592
14780
  children,
@@ -14598,6 +14786,8 @@ function OverlayShell({
14598
14786
  }) {
14599
14787
  const onCloseRef = useRef(onClose);
14600
14788
  onCloseRef.current = onClose;
14789
+ const [shell, setShell] = useState(null);
14790
+ useOverlayFocus({ enabled: open, container: shell, initialFocus: "container" });
14601
14791
  useEffect(() => {
14602
14792
  if (!open) return;
14603
14793
  const handleKeyDown = (e) => {
@@ -14632,12 +14822,14 @@ function OverlayShell({
14632
14822
  children: /* @__PURE__ */ jsx(
14633
14823
  motion.div,
14634
14824
  {
14825
+ ref: setShell,
14826
+ tabIndex: -1,
14635
14827
  initial: { opacity: 0, y: 12, scale: 0.98 },
14636
14828
  animate: { opacity: 1, y: 0, scale: 1 },
14637
14829
  exit: { opacity: 0, y: 8, scale: 0.98 },
14638
14830
  transition: { duration: 0.2, ease: [0.34, 1.2, 0.64, 1] },
14639
14831
  className: cn$1(
14640
- "issue-overlay-shell flex w-full flex-col overflow-hidden",
14832
+ "issue-overlay-shell flex w-full flex-col overflow-hidden focus:outline-none",
14641
14833
  shellClassName
14642
14834
  ),
14643
14835
  onClick: (e) => e.stopPropagation(),
@@ -14649,6 +14841,670 @@ function OverlayShell({
14649
14841
  "overlay-backdrop"
14650
14842
  ) : null });
14651
14843
  }
14844
+ const ISSUE_DRAFT_DISABLED_MESSAGE = "지금은 AI 작성을 사용할 수 없습니다. 제목과 설명을 직접 작성해주세요.";
14845
+ const LABEL = "기대한 동작";
14846
+ const PLACEHOLDER = "예: 할인 쿠폰을 적용하면 결제 금액에서 즉시 차감되어야 합니다";
14847
+ const SWITCH_TO_MANUAL = "직접 작성";
14848
+ const SUBMIT = "보내기";
14849
+ const MAX_INPUT_HEIGHT = 160;
14850
+ const FOCUS_RETRY_BUDGET_MS = 1e3;
14851
+ function isFocused(node2) {
14852
+ const root2 = node2.getRootNode();
14853
+ return root2 instanceof ShadowRoot ? root2.activeElement === node2 : document.activeElement === node2;
14854
+ }
14855
+ function IssueIntentBubble({
14856
+ value,
14857
+ onChange,
14858
+ onSubmit,
14859
+ onSwitchToManual,
14860
+ submitting = false,
14861
+ error = null
14862
+ }) {
14863
+ const inputRef = useRef(null);
14864
+ const canSubmit = !submitting && value.trim().length > 0;
14865
+ useEffect(() => {
14866
+ const node2 = inputRef.current;
14867
+ if (!node2) return;
14868
+ const deadline = Date.now() + FOCUS_RETRY_BUDGET_MS;
14869
+ let frame2 = 0;
14870
+ let abandoned = false;
14871
+ const abandon = () => {
14872
+ abandoned = true;
14873
+ };
14874
+ const attempt = () => {
14875
+ frame2 = 0;
14876
+ if (abandoned || isFocused(node2)) return;
14877
+ node2.focus({ preventScroll: true });
14878
+ if (isFocused(node2) || Date.now() >= deadline) return;
14879
+ frame2 = requestAnimationFrame(attempt);
14880
+ };
14881
+ window.addEventListener("pointerdown", abandon, { capture: true });
14882
+ window.addEventListener("keydown", abandon, { capture: true });
14883
+ attempt();
14884
+ return () => {
14885
+ window.removeEventListener("pointerdown", abandon, { capture: true });
14886
+ window.removeEventListener("keydown", abandon, { capture: true });
14887
+ if (frame2) cancelAnimationFrame(frame2);
14888
+ };
14889
+ }, []);
14890
+ useLayoutEffect(() => {
14891
+ const node2 = inputRef.current;
14892
+ if (!node2) return;
14893
+ node2.style.height = "auto";
14894
+ node2.style.height = `${Math.min(node2.scrollHeight, MAX_INPUT_HEIGHT)}px`;
14895
+ }, [value]);
14896
+ return (
14897
+ /*
14898
+ * 테두리는 포커스일 때만 브랜드 색으로 간다. 이 리포의 입력 컨트롤 관례가 그렇다
14899
+ * (ui/input.tsx, ui/textarea.tsx: 평소 border-line-subtle, 포커스에 line-focus).
14900
+ * `line-focus` 는 `--border-focus` = 브랜드 색상값이다(tokens.css).
14901
+ *
14902
+ * 관례는 `focus-visible:outline-line-focus` 지만 여기서는 border 로 바꾼다.
14903
+ * outline 은 border 상자 바깥에 그려지는데 말풍선 상자가 `overflow-hidden`
14904
+ * (IssueIntentBubbleAnchor)이라 잘린다. focus 가 아니라 focus-within 인 것은
14905
+ * 테두리가 카드에 있고 실제로 포커스를 받는 것은 그 안의 textarea 이기 때문이다.
14906
+ */
14907
+ /* @__PURE__ */ jsxs(
14908
+ "div",
14909
+ {
14910
+ className: `${ISSUE_STICKER_REPORT_FORM_CLASS} w-80 space-y-1.5 rounded-md border border-line-subtle bg-surface-1 p-1.5 transition-colors duration-fast ease-out focus-within:border-line-focus`,
14911
+ children: [
14912
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-1.5", children: [
14913
+ /* @__PURE__ */ jsx(
14914
+ "textarea",
14915
+ {
14916
+ ref: inputRef,
14917
+ "aria-label": LABEL,
14918
+ rows: 1,
14919
+ className: "max-h-40 flex-1 resize-none overflow-y-auto bg-transparent px-1.5 py-1 text-sm text-text-primary outline-none placeholder:text-text-tertiary disabled:opacity-50",
14920
+ placeholder: PLACEHOLDER,
14921
+ value,
14922
+ disabled: submitting,
14923
+ onChange: (event) => onChange(event.target.value)
14924
+ }
14925
+ ),
14926
+ /* @__PURE__ */ jsx(
14927
+ "button",
14928
+ {
14929
+ type: "button",
14930
+ "aria-label": SUBMIT,
14931
+ className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-brand text-brand-fg disabled:opacity-50",
14932
+ disabled: !canSubmit,
14933
+ onClick: () => canSubmit && onSubmit(),
14934
+ children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4" })
14935
+ }
14936
+ )
14937
+ ] }),
14938
+ error ? /* @__PURE__ */ jsx("p", { className: "text-xs text-danger", children: error }) : null,
14939
+ /* @__PURE__ */ jsxs(Button, { type: "button", variant: "secondary", size: "sm", onClick: onSwitchToManual, children: [
14940
+ /* @__PURE__ */ jsx(PenLine, { className: "h-3.5 w-3.5" }),
14941
+ SWITCH_TO_MANUAL
14942
+ ] })
14943
+ ]
14944
+ }
14945
+ )
14946
+ );
14947
+ }
14948
+ var DIALOG_NAME = "Dialog";
14949
+ var [createDialogContext] = createContextScope(DIALOG_NAME);
14950
+ var [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);
14951
+ var Dialog$1 = (props) => {
14952
+ const {
14953
+ __scopeDialog,
14954
+ children,
14955
+ open: openProp,
14956
+ defaultOpen,
14957
+ onOpenChange,
14958
+ modal = true
14959
+ } = props;
14960
+ const triggerRef = React.useRef(null);
14961
+ const contentRef = React.useRef(null);
14962
+ const [open, setOpen] = useControllableState({
14963
+ prop: openProp,
14964
+ defaultProp: defaultOpen ?? false,
14965
+ onChange: onOpenChange,
14966
+ caller: DIALOG_NAME
14967
+ });
14968
+ return /* @__PURE__ */ jsx(
14969
+ DialogProvider,
14970
+ {
14971
+ scope: __scopeDialog,
14972
+ triggerRef,
14973
+ contentRef,
14974
+ contentId: useId$1(),
14975
+ titleId: useId$1(),
14976
+ descriptionId: useId$1(),
14977
+ open,
14978
+ onOpenChange: setOpen,
14979
+ onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
14980
+ modal,
14981
+ children
14982
+ }
14983
+ );
14984
+ };
14985
+ Dialog$1.displayName = DIALOG_NAME;
14986
+ var TRIGGER_NAME$3 = "DialogTrigger";
14987
+ var DialogTrigger = React.forwardRef(
14988
+ (props, forwardedRef) => {
14989
+ const { __scopeDialog, ...triggerProps } = props;
14990
+ const context = useDialogContext(TRIGGER_NAME$3, __scopeDialog);
14991
+ const composedTriggerRef = useComposedRefs$1(forwardedRef, context.triggerRef);
14992
+ return /* @__PURE__ */ jsx(
14993
+ Primitive.button,
14994
+ {
14995
+ type: "button",
14996
+ "aria-haspopup": "dialog",
14997
+ "aria-expanded": context.open,
14998
+ "aria-controls": context.open ? context.contentId : void 0,
14999
+ "data-state": getState$2(context.open),
15000
+ ...triggerProps,
15001
+ ref: composedTriggerRef,
15002
+ onClick: composeEventHandlers(props.onClick, context.onOpenToggle)
15003
+ }
15004
+ );
15005
+ }
15006
+ );
15007
+ DialogTrigger.displayName = TRIGGER_NAME$3;
15008
+ var PORTAL_NAME = "DialogPortal";
15009
+ var [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {
15010
+ forceMount: void 0
15011
+ });
15012
+ var DialogPortal$1 = (props) => {
15013
+ const { __scopeDialog, forceMount, children, container } = props;
15014
+ const context = useDialogContext(PORTAL_NAME, __scopeDialog);
15015
+ return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Portal$1, { asChild: true, container, children: child }) })) });
15016
+ };
15017
+ DialogPortal$1.displayName = PORTAL_NAME;
15018
+ var OVERLAY_NAME = "DialogOverlay";
15019
+ var DialogOverlay$1 = React.forwardRef(
15020
+ (props, forwardedRef) => {
15021
+ const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);
15022
+ const { forceMount = portalContext.forceMount, ...overlayProps } = props;
15023
+ const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);
15024
+ return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;
15025
+ }
15026
+ );
15027
+ DialogOverlay$1.displayName = OVERLAY_NAME;
15028
+ var Slot = createSlot("DialogOverlay.RemoveScroll");
15029
+ var DialogOverlayImpl = React.forwardRef(
15030
+ (props, forwardedRef) => {
15031
+ const { __scopeDialog, ...overlayProps } = props;
15032
+ const context = useDialogContext(OVERLAY_NAME, __scopeDialog);
15033
+ const registerDismissableSurface = useDismissableLayerSurface();
15034
+ const composedRefs = useComposedRefs$1(forwardedRef, registerDismissableSurface);
15035
+ return (
15036
+ // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`
15037
+ // ie. when `Overlay` and `Content` are siblings
15038
+ /* @__PURE__ */ jsx(ReactRemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(
15039
+ Primitive.div,
15040
+ {
15041
+ "data-state": getState$2(context.open),
15042
+ ...overlayProps,
15043
+ ref: composedRefs,
15044
+ style: { pointerEvents: "auto", ...overlayProps.style }
15045
+ }
15046
+ ) })
15047
+ );
15048
+ }
15049
+ );
15050
+ var CONTENT_NAME$3 = "DialogContent";
15051
+ var DialogContent$1 = React.forwardRef(
15052
+ (props, forwardedRef) => {
15053
+ const portalContext = usePortalContext(CONTENT_NAME$3, props.__scopeDialog);
15054
+ const { forceMount = portalContext.forceMount, ...contentProps } = props;
15055
+ const context = useDialogContext(CONTENT_NAME$3, props.__scopeDialog);
15056
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });
15057
+ }
15058
+ );
15059
+ DialogContent$1.displayName = CONTENT_NAME$3;
15060
+ var DialogContentModal = React.forwardRef(
15061
+ (props, forwardedRef) => {
15062
+ const context = useDialogContext(CONTENT_NAME$3, props.__scopeDialog);
15063
+ const contentRef = React.useRef(null);
15064
+ const composedRefs = useComposedRefs$1(forwardedRef, context.contentRef, contentRef);
15065
+ React.useEffect(() => {
15066
+ const content2 = contentRef.current;
15067
+ if (content2) return hideOthers(content2);
15068
+ }, []);
15069
+ return /* @__PURE__ */ jsx(
15070
+ DialogContentImpl,
15071
+ {
15072
+ ...props,
15073
+ ref: composedRefs,
15074
+ trapFocus: context.open,
15075
+ disableOutsidePointerEvents: context.open,
15076
+ onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
15077
+ var _a;
15078
+ event.preventDefault();
15079
+ (_a = context.triggerRef.current) == null ? void 0 : _a.focus();
15080
+ }),
15081
+ onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
15082
+ const originalEvent = event.detail.originalEvent;
15083
+ const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
15084
+ const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
15085
+ if (isRightClick) event.preventDefault();
15086
+ }),
15087
+ onFocusOutside: composeEventHandlers(
15088
+ props.onFocusOutside,
15089
+ (event) => event.preventDefault()
15090
+ )
15091
+ }
15092
+ );
15093
+ }
15094
+ );
15095
+ var DialogContentNonModal = React.forwardRef(
15096
+ (props, forwardedRef) => {
15097
+ const context = useDialogContext(CONTENT_NAME$3, props.__scopeDialog);
15098
+ const hasInteractedOutsideRef = React.useRef(false);
15099
+ const hasPointerDownOutsideRef = React.useRef(false);
15100
+ return /* @__PURE__ */ jsx(
15101
+ DialogContentImpl,
15102
+ {
15103
+ ...props,
15104
+ ref: forwardedRef,
15105
+ trapFocus: false,
15106
+ disableOutsidePointerEvents: false,
15107
+ onCloseAutoFocus: (event) => {
15108
+ var _a, _b2;
15109
+ (_a = props.onCloseAutoFocus) == null ? void 0 : _a.call(props, event);
15110
+ if (!event.defaultPrevented) {
15111
+ if (!hasInteractedOutsideRef.current) (_b2 = context.triggerRef.current) == null ? void 0 : _b2.focus();
15112
+ event.preventDefault();
15113
+ }
15114
+ hasInteractedOutsideRef.current = false;
15115
+ hasPointerDownOutsideRef.current = false;
15116
+ },
15117
+ onInteractOutside: (event) => {
15118
+ var _a, _b2;
15119
+ (_a = props.onInteractOutside) == null ? void 0 : _a.call(props, event);
15120
+ if (!event.defaultPrevented) {
15121
+ hasInteractedOutsideRef.current = true;
15122
+ if (event.detail.originalEvent.type === "pointerdown") {
15123
+ hasPointerDownOutsideRef.current = true;
15124
+ }
15125
+ }
15126
+ const target = event.target;
15127
+ const targetIsTrigger = (_b2 = context.triggerRef.current) == null ? void 0 : _b2.contains(target);
15128
+ if (targetIsTrigger) event.preventDefault();
15129
+ if (event.detail.originalEvent.type === "focusin" && hasPointerDownOutsideRef.current) {
15130
+ event.preventDefault();
15131
+ }
15132
+ }
15133
+ }
15134
+ );
15135
+ }
15136
+ );
15137
+ var DialogContentImpl = React.forwardRef(
15138
+ (props, forwardedRef) => {
15139
+ const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;
15140
+ const context = useDialogContext(CONTENT_NAME$3, __scopeDialog);
15141
+ useFocusGuards();
15142
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
15143
+ FocusScope,
15144
+ {
15145
+ asChild: true,
15146
+ loop: true,
15147
+ trapped: trapFocus,
15148
+ onMountAutoFocus: onOpenAutoFocus,
15149
+ onUnmountAutoFocus: onCloseAutoFocus,
15150
+ children: /* @__PURE__ */ jsx(
15151
+ DismissableLayer,
15152
+ {
15153
+ role: "dialog",
15154
+ id: context.contentId,
15155
+ "aria-describedby": context.descriptionId,
15156
+ "aria-labelledby": context.titleId,
15157
+ "data-state": getState$2(context.open),
15158
+ ...contentProps,
15159
+ ref: forwardedRef,
15160
+ deferPointerDownOutside: true,
15161
+ onDismiss: () => context.onOpenChange(false)
15162
+ }
15163
+ )
15164
+ }
15165
+ ) });
15166
+ }
15167
+ );
15168
+ var TITLE_NAME = "DialogTitle";
15169
+ var DialogTitle$1 = React.forwardRef(
15170
+ (props, forwardedRef) => {
15171
+ const { __scopeDialog, ...titleProps } = props;
15172
+ const context = useDialogContext(TITLE_NAME, __scopeDialog);
15173
+ return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });
15174
+ }
15175
+ );
15176
+ DialogTitle$1.displayName = TITLE_NAME;
15177
+ var DESCRIPTION_NAME = "DialogDescription";
15178
+ var DialogDescription$1 = React.forwardRef(
15179
+ (props, forwardedRef) => {
15180
+ const { __scopeDialog, ...descriptionProps } = props;
15181
+ const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);
15182
+ return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });
15183
+ }
15184
+ );
15185
+ DialogDescription$1.displayName = DESCRIPTION_NAME;
15186
+ var CLOSE_NAME = "DialogClose";
15187
+ var DialogClose$1 = React.forwardRef(
15188
+ (props, forwardedRef) => {
15189
+ const { __scopeDialog, ...closeProps } = props;
15190
+ const context = useDialogContext(CLOSE_NAME, __scopeDialog);
15191
+ return /* @__PURE__ */ jsx(
15192
+ Primitive.button,
15193
+ {
15194
+ type: "button",
15195
+ ...closeProps,
15196
+ ref: forwardedRef,
15197
+ onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))
15198
+ }
15199
+ );
15200
+ }
15201
+ );
15202
+ DialogClose$1.displayName = CLOSE_NAME;
15203
+ function getState$2(open) {
15204
+ return open ? "open" : "closed";
15205
+ }
15206
+ const Dialog = Dialog$1;
15207
+ const DialogClose = DialogClose$1;
15208
+ const DialogPortal = ({ children }) => {
15209
+ const portalContainer = usePortalContainer();
15210
+ return /* @__PURE__ */ jsx(DialogPortal$1, { container: portalContainer, children });
15211
+ };
15212
+ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
15213
+ DialogOverlay$1,
15214
+ {
15215
+ ref,
15216
+ className: cn$1(
15217
+ `fixed inset-0 ${OVERLAY_LAYER.dialogOverlay} bg-black/24`,
15218
+ "data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out",
15219
+ "motion-reduce:animate-none",
15220
+ className
15221
+ ),
15222
+ ...props
15223
+ }
15224
+ ));
15225
+ DialogOverlay.displayName = DialogOverlay$1.displayName;
15226
+ const DialogContent = React.forwardRef(
15227
+ ({
15228
+ className,
15229
+ children,
15230
+ hideCloseButton = false,
15231
+ initialFocusRef,
15232
+ onEscapeKeyDown,
15233
+ onOpenAutoFocus,
15234
+ onCloseAutoFocus,
15235
+ style,
15236
+ ...props
15237
+ }, ref) => {
15238
+ const [content2, setContent] = React.useState(null);
15239
+ const composedRef = React.useCallback(
15240
+ (node2) => {
15241
+ setContent(node2);
15242
+ if (typeof ref === "function") ref(node2);
15243
+ else if (ref) ref.current = node2;
15244
+ },
15245
+ [ref]
15246
+ );
15247
+ useOverlayFocus({ enabled: true, container: content2, initialFocusRef });
15248
+ return /* @__PURE__ */ jsxs(DialogPortal, { children: [
15249
+ /* @__PURE__ */ jsx(DialogOverlay, {}),
15250
+ /* @__PURE__ */ jsxs(
15251
+ DialogContent$1,
15252
+ {
15253
+ ref: composedRef,
15254
+ onEscapeKeyDown: stopEscapePropagation(onEscapeKeyDown),
15255
+ onOpenAutoFocus: (event) => {
15256
+ onOpenAutoFocus == null ? void 0 : onOpenAutoFocus(event);
15257
+ event.preventDefault();
15258
+ },
15259
+ onCloseAutoFocus: (event) => {
15260
+ onCloseAutoFocus == null ? void 0 : onCloseAutoFocus(event);
15261
+ event.preventDefault();
15262
+ },
15263
+ style: {
15264
+ left: `calc(50% - (var(${BODY_SCROLLBAR_WIDTH_CSS_VAR}, 0px) / 2))`,
15265
+ ...style
15266
+ },
15267
+ className: cn$1(
15268
+ `panel-shell fixed left-[50%] top-[50%] ${OVERLAY_LAYER.dialogContent} grid w-full max-w-[36rem] translate-x-[-50%] translate-y-[-50%] gap-5 rounded-2xl p-7 shadow-lg`,
15269
+ "focus:outline-none",
15270
+ "data-[state=open]:animate-dialog-in data-[state=closed]:animate-dialog-out",
15271
+ "motion-reduce:animate-none",
15272
+ className
15273
+ ),
15274
+ ...props,
15275
+ children: [
15276
+ children,
15277
+ !hideCloseButton ? /* @__PURE__ */ jsxs(
15278
+ DialogClose$1,
15279
+ {
15280
+ className: cn$1(
15281
+ "absolute right-4 top-4 rounded-md border border-transparent bg-surface-2 p-1.5 text-text-tertiary",
15282
+ "transition-colors duration-fast",
15283
+ "hover:border-line-subtle hover:bg-surface-3 hover:text-text-primary",
15284
+ "focus-visible:outline-none focus-visible:shadow-focus"
15285
+ ),
15286
+ children: [
15287
+ /* @__PURE__ */ jsx(X$1, { className: "h-4 w-4" }),
15288
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "닫기" })
15289
+ ]
15290
+ }
15291
+ ) : null
15292
+ ]
15293
+ }
15294
+ )
15295
+ ] });
15296
+ }
15297
+ );
15298
+ DialogContent.displayName = DialogContent$1.displayName;
15299
+ const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn$1("flex flex-col space-y-2 text-left", className), ...props });
15300
+ const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
15301
+ DialogTitle$1,
15302
+ {
15303
+ ref,
15304
+ className: cn$1("text-lg font-semibold text-text-primary", className),
15305
+ ...props
15306
+ }
15307
+ ));
15308
+ DialogTitle.displayName = DialogTitle$1.displayName;
15309
+ const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
15310
+ DialogDescription$1,
15311
+ {
15312
+ ref,
15313
+ className: cn$1("text-sm leading-relaxed text-text-secondary", className),
15314
+ ...props
15315
+ }
15316
+ ));
15317
+ DialogDescription.displayName = DialogDescription$1.displayName;
15318
+ const VIEWPORT_MARGIN = 12;
15319
+ const PREVIEW_STICKER_SIZE = 32;
15320
+ const STICKER_GAP = 8;
15321
+ const BUBBLE_OFFSET = PREVIEW_STICKER_SIZE / 2 + STICKER_GAP;
15322
+ const DISCARD_MESSAGE = "지금 닫으면 작성 중인 내용이 사라집니다. 닫으시겠습니까?";
15323
+ const DISCARD_CANCEL = "취소";
15324
+ const DISCARD_CONFIRM = "닫기";
15325
+ function clampBubblePosition(x, y, width, height, viewportWidth, viewportHeight, margin = VIEWPORT_MARGIN) {
15326
+ const maxLeft = Math.max(margin, viewportWidth - width - margin);
15327
+ const maxTop = Math.max(margin, viewportHeight - height - margin);
15328
+ return {
15329
+ left: Math.min(Math.max(x, margin), maxLeft),
15330
+ top: Math.min(Math.max(y, margin), maxTop)
15331
+ };
15332
+ }
15333
+ function resolveBubbleLayout(stickerLeft, stickerTop, width, height, viewportWidth, viewportHeight, margin = VIEWPORT_MARGIN) {
15334
+ const rightLeft = stickerLeft + BUBBLE_OFFSET;
15335
+ const leftLeft = stickerLeft - BUBBLE_OFFSET - width;
15336
+ const side = rightLeft + width <= viewportWidth - margin ? "right" : leftLeft >= margin ? "left" : "right";
15337
+ const { left, top } = clampBubblePosition(
15338
+ side === "right" ? rightLeft : leftLeft,
15339
+ stickerTop - PREVIEW_STICKER_SIZE / 2,
15340
+ width,
15341
+ height,
15342
+ viewportWidth,
15343
+ viewportHeight,
15344
+ margin
15345
+ );
15346
+ return { left, top, side };
15347
+ }
15348
+ function IssueIntentBubbleAnchor({
15349
+ x,
15350
+ y,
15351
+ children,
15352
+ onClose,
15353
+ dirty = false,
15354
+ open = true,
15355
+ onExitComplete
15356
+ }) {
15357
+ const contentRef = useRef(null);
15358
+ const onCloseRef = useRef(onClose);
15359
+ onCloseRef.current = onClose;
15360
+ const dirtyRef = useRef(dirty);
15361
+ dirtyRef.current = dirty;
15362
+ const [confirmingDiscard, setConfirmingDiscard] = useState(false);
15363
+ const discardCancelRef = useRef(null);
15364
+ const confirmingDiscardRef = useRef(confirmingDiscard);
15365
+ confirmingDiscardRef.current = confirmingDiscard;
15366
+ const [layout2, setLayout] = useState(null);
15367
+ const reduceMotion = useReducedMotion();
15368
+ useLayoutEffect(() => {
15369
+ let frame2 = 0;
15370
+ const apply = () => {
15371
+ frame2 = 0;
15372
+ const node2 = contentRef.current;
15373
+ if (!node2) return;
15374
+ const { width, height } = node2.getBoundingClientRect();
15375
+ const stickerLeft = x - window.scrollX;
15376
+ const stickerTop = y - window.scrollY;
15377
+ const placement = resolveBubbleLayout(
15378
+ stickerLeft,
15379
+ stickerTop,
15380
+ width,
15381
+ height,
15382
+ window.innerWidth,
15383
+ window.innerHeight
15384
+ );
15385
+ setLayout({
15386
+ stickerLeft,
15387
+ stickerTop,
15388
+ bubbleTop: placement.top,
15389
+ // 왼쪽에 열 때는 right 를 고정해야 너비가 스티커 쪽으로 자란다.
15390
+ bubbleLeft: placement.side === "right" ? placement.left : null,
15391
+ bubbleRight: placement.side === "right" ? null : window.innerWidth - (placement.left + width)
15392
+ });
15393
+ };
15394
+ const schedule = () => {
15395
+ if (frame2) return;
15396
+ frame2 = window.requestAnimationFrame(apply);
15397
+ };
15398
+ apply();
15399
+ window.addEventListener("scroll", schedule, { capture: true, passive: true });
15400
+ window.addEventListener("resize", schedule, { passive: true });
15401
+ let contentObserver = null;
15402
+ if (contentRef.current && typeof ResizeObserver !== "undefined") {
15403
+ contentObserver = new ResizeObserver(schedule);
15404
+ contentObserver.observe(contentRef.current);
15405
+ }
15406
+ return () => {
15407
+ window.removeEventListener("scroll", schedule, { capture: true });
15408
+ window.removeEventListener("resize", schedule);
15409
+ contentObserver == null ? void 0 : contentObserver.disconnect();
15410
+ if (frame2) window.cancelAnimationFrame(frame2);
15411
+ };
15412
+ }, [x, y]);
15413
+ useEffect(() => {
15414
+ const handleKeyDown = (event) => {
15415
+ if (event.key !== "Escape") return;
15416
+ event.preventDefault();
15417
+ if (confirmingDiscardRef.current) return;
15418
+ if (dirtyRef.current) {
15419
+ setConfirmingDiscard(true);
15420
+ return;
15421
+ }
15422
+ onCloseRef.current();
15423
+ };
15424
+ window.addEventListener("keydown", handleKeyDown, { capture: true });
15425
+ return () => window.removeEventListener("keydown", handleKeyDown, { capture: true });
15426
+ }, []);
15427
+ useDisableBodyScroll(confirmingDiscard);
15428
+ const visibility = layout2 ? "visible" : "hidden";
15429
+ const stickerTransition = reduceMotion ? { duration: 0 } : { duration: 0.18, ease: [0.34, 1.2, 0.64, 1] };
15430
+ const bubbleTransition = reduceMotion ? { duration: 0 } : { duration: 0.22, ease: [0.34, 1.2, 0.64, 1] };
15431
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
15432
+ /* @__PURE__ */ jsx(AnimatePresence, { onExitComplete, children: open ? [
15433
+ /* @__PURE__ */ jsx(
15434
+ motion.div,
15435
+ {
15436
+ "data-issue-sticker-preview": "",
15437
+ "aria-hidden": "true",
15438
+ className: `pointer-events-none fixed ${OVERLAY_LAYER.shell} flex h-8 w-8 items-center justify-center rounded-full border border-white/80 bg-brand text-sm font-black leading-none text-white`,
15439
+ style: {
15440
+ left: (layout2 == null ? void 0 : layout2.stickerLeft) ?? x,
15441
+ top: (layout2 == null ? void 0 : layout2.stickerTop) ?? y,
15442
+ visibility
15443
+ },
15444
+ initial: { opacity: 0, scale: 0.5, x: "-50%", y: "-50%" },
15445
+ animate: { opacity: 1, scale: 1, x: "-50%", y: "-50%" },
15446
+ exit: { opacity: 0, scale: 0.5, x: "-50%", y: "-50%" },
15447
+ transition: stickerTransition,
15448
+ children: "!"
15449
+ },
15450
+ "preview-sticker"
15451
+ ),
15452
+ /* @__PURE__ */ jsx(
15453
+ motion.div,
15454
+ {
15455
+ "data-issue-sticker-bubble": "",
15456
+ className: `pointer-events-auto fixed overflow-hidden ${OVERLAY_LAYER.shell}`,
15457
+ style: {
15458
+ left: (layout2 == null ? void 0 : layout2.bubbleLeft) ?? void 0,
15459
+ right: (layout2 == null ? void 0 : layout2.bubbleRight) ?? void 0,
15460
+ top: (layout2 == null ? void 0 : layout2.bubbleTop) ?? y
15461
+ },
15462
+ initial: { width: 0, height: 0, opacity: 0 },
15463
+ animate: layout2 ? { width: "auto", height: "auto", opacity: 1 } : { width: 0, height: 0, opacity: 0 },
15464
+ exit: { width: 0, height: 0, opacity: 0 },
15465
+ transition: bubbleTransition,
15466
+ children: /* @__PURE__ */ jsx("div", { ref: contentRef, className: "w-max", children })
15467
+ },
15468
+ "bubble"
15469
+ )
15470
+ ] : null }),
15471
+ /* @__PURE__ */ jsx(
15472
+ Dialog,
15473
+ {
15474
+ open: confirmingDiscard,
15475
+ onOpenChange: (nextOpen) => {
15476
+ if (!nextOpen) setConfirmingDiscard(false);
15477
+ },
15478
+ children: /* @__PURE__ */ jsxs(
15479
+ DialogContent,
15480
+ {
15481
+ hideCloseButton: true,
15482
+ initialFocusRef: discardCancelRef,
15483
+ "aria-describedby": void 0,
15484
+ className: "w-[calc(100vw-32px)] max-w-[360px] gap-4 rounded-md p-5",
15485
+ children: [
15486
+ /* @__PURE__ */ jsx(DialogTitle, { className: "text-sm font-normal leading-relaxed", children: DISCARD_MESSAGE }),
15487
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
15488
+ /* @__PURE__ */ jsx(
15489
+ Button,
15490
+ {
15491
+ ref: discardCancelRef,
15492
+ type: "button",
15493
+ variant: "secondary",
15494
+ size: "sm",
15495
+ onClick: () => setConfirmingDiscard(false),
15496
+ children: DISCARD_CANCEL
15497
+ }
15498
+ ),
15499
+ /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: () => onClose(), children: DISCARD_CONFIRM })
15500
+ ] })
15501
+ ]
15502
+ }
15503
+ )
15504
+ }
15505
+ )
15506
+ ] });
15507
+ }
14652
15508
  function useProject() {
14653
15509
  const auth = useAuthContext();
14654
15510
  return {
@@ -14831,6 +15687,12 @@ function useJiraConnectNudge(projectId, enabled) {
14831
15687
  function useIssueFormState({ initialDescription } = {}) {
14832
15688
  const [title, setTitle] = useState("");
14833
15689
  const [description, setDescription] = useState(initialDescription || "");
15690
+ const [mode, setMode] = useState("ai");
15691
+ const [renderedMode, setRenderedMode] = useState("ai");
15692
+ const [intent, setIntent] = useState("");
15693
+ const modeRef = useRef(mode);
15694
+ modeRef.current = mode;
15695
+ const finishModeTransition = useCallback(() => setRenderedMode(modeRef.current), []);
14834
15696
  useEffect(() => {
14835
15697
  if (initialDescription !== void 0) {
14836
15698
  setDescription(initialDescription);
@@ -14840,7 +15702,13 @@ function useIssueFormState({ initialDescription } = {}) {
14840
15702
  title,
14841
15703
  description,
14842
15704
  setTitle,
14843
- setDescription
15705
+ setDescription,
15706
+ mode,
15707
+ setMode,
15708
+ renderedMode,
15709
+ finishModeTransition,
15710
+ intent,
15711
+ setIntent
14844
15712
  };
14845
15713
  }
14846
15714
  function useDebouncedMutation({
@@ -14979,6 +15847,12 @@ const SCREENSHOT_EXCLUDE_SELECTORS = [
14979
15847
  '[data-issue-sticker-capture-ignore="true"]',
14980
15848
  "#issue-sticker-host"
14981
15849
  ];
15850
+ const CAPTURE_START_DELAY_MS = 300;
15851
+ function waitForFormOpen() {
15852
+ return new Promise((resolve) => {
15853
+ setTimeout(resolve, CAPTURE_START_DELAY_MS);
15854
+ });
15855
+ }
14982
15856
  function useClickPosition(isCreatingIssueRef, recordedVideoFile) {
14983
15857
  const [clickPosition, setClickPosition] = useState(null);
14984
15858
  const clickPositionRef = useRef(null);
@@ -15052,6 +15926,7 @@ function useClickPosition(isCreatingIssueRef, recordedVideoFile) {
15052
15926
  }, [recordedVideoFile]);
15053
15927
  useEffect(() => {
15054
15928
  const captureScreenshotsInBackground = async (position2) => {
15929
+ await waitForFormOpen();
15055
15930
  const [fullScreenshotDataUrl, elementScreenshotDataUrl] = await pauseNetworkLogCollectionWhile(
15056
15931
  () => Promise.all([
15057
15932
  captureScreenshot({ excludeSelectors: SCREENSHOT_EXCLUDE_SELECTORS }),
@@ -15213,6 +16088,14 @@ async function uploadSessionReplay(snapshot) {
15213
16088
  return null;
15214
16089
  }
15215
16090
  }
16091
+ function assertSubmittable(data) {
16092
+ var _a, _b2, _c2;
16093
+ const hasIntent = Boolean((_a = data.intent) == null ? void 0 : _a.trim());
16094
+ const hasManual = Boolean((_b2 = data.title) == null ? void 0 : _b2.trim()) && Boolean((_c2 = data.description) == null ? void 0 : _c2.trim());
16095
+ if (!hasIntent && !hasManual) {
16096
+ throw new Error("제목과 설명을 입력하거나 기대한 동작을 적어주세요.");
16097
+ }
16098
+ }
15216
16099
  function useIssueSubmission({
15217
16100
  position: position2,
15218
16101
  onSubmit,
@@ -15232,13 +16115,8 @@ function useIssueSubmission({
15232
16115
  const { upload: uploadVideo2 } = useVideoUpload();
15233
16116
  const createIssueMutation = useDebouncedMutation({
15234
16117
  mutationFn: async (data) => {
15235
- var _a, _b2;
15236
- if (!data.title.trim()) {
15237
- throw new Error("제목을 입력해주세요.");
15238
- }
15239
- if (!data.description.trim()) {
15240
- throw new Error("설명을 입력해주세요.");
15241
- }
16118
+ var _a, _b2, _c2, _d2, _e2, _f2;
16119
+ assertSubmittable(data);
15242
16120
  let screenshotUrls;
15243
16121
  let videoUrl;
15244
16122
  if (data.videoFile) {
@@ -15272,8 +16150,9 @@ function useIssueSubmission({
15272
16150
  const currentUrl = getCurrentPageUrl();
15273
16151
  const issueData = {
15274
16152
  url: currentUrl,
15275
- title: data.title.trim(),
15276
- description: data.description.trim(),
16153
+ title: ((_b2 = data.title) == null ? void 0 : _b2.trim()) || void 0,
16154
+ description: ((_c2 = data.description) == null ? void 0 : _c2.trim()) || void 0,
16155
+ intent: ((_d2 = data.intent) == null ? void 0 : _d2.trim()) || void 0,
15277
16156
  position: {
15278
16157
  x: data.position.x,
15279
16158
  y: data.position.y,
@@ -15294,10 +16173,10 @@ function useIssueSubmission({
15294
16173
  // 비어 있는 값은 보내지 않는다 — 저장해봐야 값 없음과 같고 요청만 커진다.
15295
16174
  custom_field_values: Object.entries(customFieldValues ?? {}).filter(([, value]) => value !== null && value !== void 0 && value !== "").map(([field_definition_id, value]) => ({ field_definition_id, value }))
15296
16175
  };
15297
- if (((_b2 = issueData.custom_field_values) == null ? void 0 : _b2.length) === 0) {
16176
+ if (((_e2 = issueData.custom_field_values) == null ? void 0 : _e2.length) === 0) {
15298
16177
  delete issueData.custom_field_values;
15299
16178
  }
15300
- if ((sessionReplay == null ? void 0 : sessionReplay.preferOn) && sessionReplay.canAttach) {
16179
+ if (sessionReplay == null ? void 0 : sessionReplay.canAttach) {
15301
16180
  try {
15302
16181
  const snapshot = await sessionReplay.takeSnapshot();
15303
16182
  if (snapshot) {
@@ -15336,6 +16215,9 @@ function useIssueSubmission({
15336
16215
  toast.error(getIntegrationFailureMessage(service));
15337
16216
  }
15338
16217
  failedServicesRef.current = createdIssue.failed_services ?? [];
16218
+ if (((_f2 = data.intent) == null ? void 0 : _f2.trim()) && createdIssue.generation_status === "skipped") {
16219
+ toast.warning(ISSUE_DRAFT_DISABLED_MESSAGE);
16220
+ }
15339
16221
  return createdIssue;
15340
16222
  },
15341
16223
  onSuccess: (createdIssue) => {
@@ -15352,11 +16234,12 @@ function useIssueSubmission({
15352
16234
  }
15353
16235
  });
15354
16236
  const doSubmit = useCallback(
15355
- async (title, description) => {
16237
+ async ({ title, description, intent }) => {
15356
16238
  failedServicesRef.current = [];
15357
16239
  await createIssueMutation.mutateAsync({
15358
16240
  title,
15359
16241
  description,
16242
+ intent,
15360
16243
  position: position2,
15361
16244
  jiraFields,
15362
16245
  notionFields,
@@ -15390,12 +16273,6 @@ function useSessionReplayController() {
15390
16273
  controller.destroy();
15391
16274
  };
15392
16275
  }, [controller]);
15393
- const setPreferOn = useCallback(
15394
- (next) => {
15395
- controller.setEnabled(next);
15396
- },
15397
- [controller]
15398
- );
15399
16276
  const takeSnapshot = useCallback(async () => {
15400
16277
  return controller.takeSnapshot();
15401
16278
  }, [controller]);
@@ -15404,8 +16281,6 @@ function useSessionReplayController() {
15404
16281
  return {
15405
16282
  available: snapshot.available,
15406
16283
  canAttach: snapshot.canAttach,
15407
- preferOn: snapshot.enabled,
15408
- setPreferOn,
15409
16284
  takeSnapshot,
15410
16285
  markReportStart,
15411
16286
  clearReportStart
@@ -15414,9 +16289,6 @@ function useSessionReplayController() {
15414
16289
  const DISABLED_CONTROLLER = {
15415
16290
  available: false,
15416
16291
  canAttach: false,
15417
- preferOn: false,
15418
- setPreferOn: () => {
15419
- },
15420
16292
  takeSnapshot: async () => null,
15421
16293
  markReportStart: () => {
15422
16294
  },
@@ -15737,12 +16609,7 @@ function IssueFormCustomFields({
15737
16609
  queryKey: ["customFieldDefinitions", projectId],
15738
16610
  queryFn: () => fetchCustomFieldDefinitions(projectId)
15739
16611
  });
15740
- const defaultsAppliedRef = useRef(false);
15741
- useEffect(() => {
15742
- if (defaultsAppliedRef.current || fields.length === 0) return;
15743
- defaultsAppliedRef.current = true;
15744
- onDefaultsResolved(getCustomFieldDefaultValues(fields));
15745
- }, [fields, onDefaultsResolved]);
16612
+ useCustomFieldDefaults(fields, onDefaultsResolved);
15746
16613
  return /* @__PURE__ */ jsx(
15747
16614
  CustomFieldsSection,
15748
16615
  {
@@ -15754,12 +16621,57 @@ function IssueFormCustomFields({
15754
16621
  }
15755
16622
  );
15756
16623
  }
16624
+ function useCustomFieldDefaults(fields, onDefaultsResolved) {
16625
+ const defaultsAppliedRef = useRef(false);
16626
+ useEffect(() => {
16627
+ if (defaultsAppliedRef.current || fields.length === 0) return;
16628
+ defaultsAppliedRef.current = true;
16629
+ onDefaultsResolved(getCustomFieldDefaultValues(fields));
16630
+ }, [fields, onDefaultsResolved]);
16631
+ }
16632
+ function IssueFormCustomFieldDefaults({
16633
+ projectId,
16634
+ onDefaultsResolved
16635
+ }) {
16636
+ const { data: fields } = useQuery({
16637
+ queryKey: ["customFieldDefinitions", projectId],
16638
+ queryFn: () => fetchCustomFieldDefinitions(projectId)
16639
+ });
16640
+ useCustomFieldDefaults(fields ?? [], onDefaultsResolved);
16641
+ return null;
16642
+ }
16643
+ const useIsomorphicLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
15757
16644
  const Textarea = React.forwardRef(
15758
- ({ className, ...props }, ref) => {
16645
+ ({ className, autoGrow, ...props }, ref) => {
16646
+ const innerRef = React.useRef(null);
16647
+ React.useImperativeHandle(ref, () => innerRef.current);
16648
+ const grow = React.useCallback(() => {
16649
+ const element2 = innerRef.current;
16650
+ if (!element2) return;
16651
+ const style = getComputedStyle(element2);
16652
+ const borders = (parseFloat(style.borderTopWidth) || 0) + (parseFloat(style.borderBottomWidth) || 0);
16653
+ element2.style.height = "0px";
16654
+ element2.style.height = `${element2.scrollHeight + borders}px`;
16655
+ }, []);
16656
+ useIsomorphicLayoutEffect(() => {
16657
+ if (autoGrow) grow();
16658
+ });
16659
+ useIsomorphicLayoutEffect(() => {
16660
+ const element2 = innerRef.current;
16661
+ if (!autoGrow || !element2 || typeof ResizeObserver === "undefined") return;
16662
+ let lastWidth = element2.clientWidth;
16663
+ const observer2 = new ResizeObserver(() => {
16664
+ if (element2.clientWidth === lastWidth) return;
16665
+ lastWidth = element2.clientWidth;
16666
+ grow();
16667
+ });
16668
+ observer2.observe(element2);
16669
+ return () => observer2.disconnect();
16670
+ }, [autoGrow, grow]);
15759
16671
  return /* @__PURE__ */ jsx(
15760
16672
  "textarea",
15761
16673
  {
15762
- ref,
16674
+ ref: innerRef,
15763
16675
  className: cn$1(
15764
16676
  "flex min-h-[108px] w-full rounded-md border border-line-subtle bg-surface-1 px-4 py-3 text-sm text-text-primary",
15765
16677
  "transition-[border-color,outline-color,box-shadow,background-color,transform] duration-fast ease-out",
@@ -15768,6 +16680,7 @@ const Textarea = React.forwardRef(
15768
16680
  "focus-visible:border-transparent focus-visible:outline-line-focus focus-visible:bg-surface-1",
15769
16681
  "disabled:cursor-not-allowed disabled:opacity-50",
15770
16682
  "resize-y",
16683
+ autoGrow && "min-h-0 resize-none overflow-hidden",
15771
16684
  className
15772
16685
  ),
15773
16686
  ...props
@@ -15803,12 +16716,55 @@ function IssueFormDescriptionField({
15803
16716
  function IssueFormError({ error }) {
15804
16717
  return /* @__PURE__ */ jsx("div", { className: "rounded-[18px] border border-danger/20 bg-danger-subtle px-4 py-3 text-sm text-danger", children: error });
15805
16718
  }
15806
- function IssueFormHeader({ title, onClose }) {
16719
+ const SWITCH_TO_AI = "AI 작성으로 돌아가기";
16720
+ function IssueFormHeader({ title, onClose, onSwitchToAi }) {
15807
16721
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4", children: [
15808
16722
  /* @__PURE__ */ jsx("h2", { className: "m-0 text-lg font-semibold text-text-primary", children: title }),
15809
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: onClose, "aria-label": "닫기", children: /* @__PURE__ */ jsx(X$1, { className: "h-4 w-4" }) })
16723
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
16724
+ onSwitchToAi ? /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 240, skipDelayDuration: 120, disableHoverableContent: true, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
16725
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
16726
+ Button,
16727
+ {
16728
+ type: "button",
16729
+ variant: "ghost",
16730
+ size: "icon",
16731
+ onClick: onSwitchToAi,
16732
+ "aria-label": SWITCH_TO_AI,
16733
+ children: /* @__PURE__ */ jsx(Sparkles, { className: "h-4 w-4" })
16734
+ }
16735
+ ) }),
16736
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", sideOffset: 10, children: SWITCH_TO_AI })
16737
+ ] }) }) : null,
16738
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: onClose, "aria-label": "닫기", children: /* @__PURE__ */ jsx(X$1, { className: "h-4 w-4" }) })
16739
+ ] })
15810
16740
  ] });
15811
16741
  }
16742
+ function useDraftCapability() {
16743
+ const { data } = useQuery({
16744
+ queryKey: ["issueDraftCapability"],
16745
+ queryFn: () => apiClient.get("/api/sdk/issues/capabilities/draft")
16746
+ });
16747
+ const capability = data == null ? void 0 : data.draft.canGenerateDraft;
16748
+ return {
16749
+ /** 응답을 실제로 받았을 때만 true. 조회 전·실패·null 응답에서는 false다. */
16750
+ resolved: Boolean(capability),
16751
+ enabled: (capability == null ? void 0 : capability.enabled) ?? true
16752
+ };
16753
+ }
16754
+ function IssueFormDraftCapabilityGate({
16755
+ onResolved
16756
+ }) {
16757
+ const { resolved, enabled } = useDraftCapability();
16758
+ useEffect(() => {
16759
+ if (!resolved) {
16760
+ return;
16761
+ }
16762
+ onResolved({
16763
+ disabledReason: enabled ? null : ISSUE_DRAFT_DISABLED_MESSAGE
16764
+ });
16765
+ }, [resolved, enabled, onResolved]);
16766
+ return null;
16767
+ }
15812
16768
  function useJiraFieldSearchConfig(projectId) {
15813
16769
  return useMemo(
15814
16770
  () => createJiraFieldSearchConfig(
@@ -15845,13 +16801,7 @@ function IssueFormJiraFields({
15845
16801
  const { getAuthInfo } = useAuthInfo();
15846
16802
  const { fields: fieldDefinitions, exposedFields } = useJiraIntegrationFields(integrationId);
15847
16803
  const getSearchConfig = useJiraFieldSearchConfig(getAuthInfo().projectId);
15848
- const appliedForRef = useRef(null);
15849
- useEffect(() => {
15850
- if (!onDefaultsResolved) return;
15851
- if (appliedForRef.current === integrationId) return;
15852
- appliedForRef.current = integrationId;
15853
- onDefaultsResolved(getJiraFieldDefaultValues(exposedFields, fieldDefinitions));
15854
- }, [integrationId, exposedFields, fieldDefinitions, onDefaultsResolved]);
16804
+ useJiraFieldDefaults(integrationId, exposedFields, fieldDefinitions, onDefaultsResolved);
15855
16805
  return /* @__PURE__ */ jsx(
15856
16806
  JiraFormFieldsSection,
15857
16807
  {
@@ -15864,6 +16814,36 @@ function IssueFormJiraFields({
15864
16814
  }
15865
16815
  );
15866
16816
  }
16817
+ function useJiraFieldDefaults(integrationId, exposedFields, fieldDefinitions, onDefaultsResolved, ready = true) {
16818
+ const appliedForRef = useRef(null);
16819
+ useEffect(() => {
16820
+ if (!onDefaultsResolved || !ready) return;
16821
+ if (appliedForRef.current === integrationId) return;
16822
+ appliedForRef.current = integrationId;
16823
+ onDefaultsResolved(getJiraFieldDefaultValues(exposedFields, fieldDefinitions));
16824
+ }, [integrationId, exposedFields, fieldDefinitions, onDefaultsResolved, ready]);
16825
+ }
16826
+ function IssueFormJiraFieldDefaults({
16827
+ integrationId,
16828
+ onDefaultsResolved
16829
+ }) {
16830
+ const { data } = useQuery({
16831
+ queryKey: ["jiraIntegrationFields", integrationId],
16832
+ queryFn: () => jiraService.loadIntegrationFields(integrationId)
16833
+ });
16834
+ useEffect(() => {
16835
+ if (!data) return;
16836
+ jiraService.updateExposedFields(integrationId, data.exposedFields);
16837
+ }, [data, integrationId]);
16838
+ useJiraFieldDefaults(
16839
+ integrationId,
16840
+ data == null ? void 0 : data.exposedFields,
16841
+ data == null ? void 0 : data.fields,
16842
+ onDefaultsResolved,
16843
+ Boolean(data)
16844
+ );
16845
+ return null;
16846
+ }
15867
16847
  function JiraConnectNudge({ onConnect, isConnecting }) {
15868
16848
  return /* @__PURE__ */ jsx("div", { className: "rounded-[18px] border border-warning/20 bg-warning-subtle px-4 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
15869
16849
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
@@ -15940,83 +16920,14 @@ function IssueFormTitleField({
15940
16920
  )
15941
16921
  ] });
15942
16922
  }
15943
- function switchTrackClassName(checked) {
15944
- return cn$1(
15945
- "relative inline-flex h-[22px] w-[38px] shrink-0 items-center rounded-full",
15946
- "transition-colors duration-fast ease-out",
15947
- checked ? "bg-brand" : "bg-line"
15948
- );
15949
- }
15950
- function switchThumbClassName(checked) {
15951
- return cn$1(
15952
- "pointer-events-none block h-[18px] w-[18px] rounded-full bg-surface-1 shadow-sm",
15953
- "transition-transform duration-fast ease-out",
15954
- checked ? "translate-x-[18px]" : "translate-x-[2px]"
15955
- );
15956
- }
15957
- const Switch = React.forwardRef(
15958
- ({ checked, onCheckedChange, disabled = false, id: id2, className, ...aria2 }, ref) => /* @__PURE__ */ jsx(
15959
- "button",
15960
- {
15961
- ref,
15962
- id: id2,
15963
- type: "button",
15964
- role: "switch",
15965
- "aria-checked": checked,
15966
- disabled,
15967
- onClick: () => onCheckedChange(!checked),
15968
- className: cn$1(
15969
- switchTrackClassName(checked),
15970
- "outline-none",
15971
- "focus-visible:shadow-focus",
15972
- "disabled:cursor-not-allowed disabled:opacity-50",
15973
- className
15974
- ),
15975
- ...aria2,
15976
- children: /* @__PURE__ */ jsx("span", { className: switchThumbClassName(checked) })
15977
- }
15978
- )
15979
- );
15980
- Switch.displayName = "Switch";
15981
- function SessionReplayAttachToggle({
16923
+ function SessionReplayLimitNotice({
15982
16924
  available,
15983
- canAttach,
15984
- preferOn,
15985
- onPreferOnChange
16925
+ canAttach
15986
16926
  }) {
15987
- if (!available) {
16927
+ if (!available || canAttach) {
15988
16928
  return null;
15989
16929
  }
15990
- return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 border-b border-line-subtle pb-3", children: [
15991
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
15992
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
15993
- /* @__PURE__ */ jsx(Label, { htmlFor: "session-replay-attach", children: "세션 리플레이 첨부" }),
15994
- /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
15995
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
15996
- "button",
15997
- {
15998
- type: "button",
15999
- "aria-label": "세션 리플레이 첨부 안내",
16000
- className: "text-text-tertiary",
16001
- children: /* @__PURE__ */ jsx(CircleHelp, { className: "h-3.5 w-3.5" })
16002
- }
16003
- ) }),
16004
- /* @__PURE__ */ jsx(TooltipContent, { className: "max-w-[240px] whitespace-normal", children: "제출 직전 최근 2분 화면 조작을 함께 기록합니다. 입력값·민감 텍스트는 자동으로 마스킹됩니다." })
16005
- ] }) })
16006
- ] }),
16007
- /* @__PURE__ */ jsx(
16008
- Switch,
16009
- {
16010
- id: "session-replay-attach",
16011
- checked: canAttach && preferOn,
16012
- disabled: !canAttach,
16013
- onCheckedChange: onPreferOnChange,
16014
- "aria-label": "세션 리플레이 첨부"
16015
- }
16016
- )
16017
- ] }),
16018
- !canAttach ? /* @__PURE__ */ jsx("p", { className: "text-xs text-warning", children: "이번 달 리플레이 한도를 모두 사용했습니다. 다음 달에 한도가 초기화되거나, 플랜을 업그레이드하면 다시 첨부할 수 있습니다." }) : null
16019
- ] });
16930
+ return /* @__PURE__ */ jsx("p", { className: "text-xs text-warning", children: "이번 달 리플레이 한도를 모두 사용했습니다. 다음 달에 한도가 초기화되거나, 플랜을 업그레이드하면 다시 첨부할 수 있습니다." });
16020
16931
  }
16021
16932
  function IssueForm({
16022
16933
  position: position2,
@@ -16038,6 +16949,19 @@ function IssueForm({
16038
16949
  const [jiraFields, setJiraFields] = useState(
16039
16950
  {}
16040
16951
  );
16952
+ const [draftDisabledReason, setDraftDisabledReason] = useState(null);
16953
+ const intentRef = useRef(formState.intent);
16954
+ intentRef.current = formState.intent;
16955
+ const setFormMode = formState.setMode;
16956
+ const handleDraftCapabilityResolved = useCallback(
16957
+ ({ disabledReason }) => {
16958
+ setDraftDisabledReason(disabledReason);
16959
+ if (disabledReason && intentRef.current.trim().length === 0) {
16960
+ setFormMode("manual");
16961
+ }
16962
+ },
16963
+ [setFormMode]
16964
+ );
16041
16965
  const [notionFields, setNotionFields] = useState({});
16042
16966
  const [customFieldValues, setCustomFieldValues] = useState({});
16043
16967
  const { selectedProjectId } = useProject();
@@ -16059,6 +16983,10 @@ function IssueForm({
16059
16983
  const issueSubmission = useIssueSubmission({
16060
16984
  position: position2,
16061
16985
  onSubmit: (hasIntegrationFailure) => {
16986
+ if (formState.mode === "ai") {
16987
+ onSubmit(hasIntegrationFailure);
16988
+ return;
16989
+ }
16062
16990
  submitSucceededRef.current = true;
16063
16991
  hadIntegrationFailureRef.current = hasIntegrationFailure;
16064
16992
  setIsOpen(false);
@@ -16071,8 +16999,9 @@ function IssueForm({
16071
16999
  videoFile: position2.videoFile,
16072
17000
  sessionReplay
16073
17001
  });
16074
- useDisableBodyScroll();
17002
+ useDisableBodyScroll(formState.mode !== "ai");
16075
17003
  useEffect(() => {
17004
+ if (formState.mode === "ai") return;
16076
17005
  const handleKeyDown = (e) => {
16077
17006
  const path2 = e.composedPath();
16078
17007
  const actualTarget = path2.find(
@@ -16099,22 +17028,86 @@ function IssueForm({
16099
17028
  };
16100
17029
  window.addEventListener("keydown", handleKeyDown, { passive: false });
16101
17030
  return () => window.removeEventListener("keydown", handleKeyDown);
16102
- }, []);
17031
+ }, [formState.mode]);
17032
+ const submitCurrentMode = async () => {
17033
+ if (formState.mode === "ai") {
17034
+ await issueSubmission.submitIssue({ intent: formState.intent });
17035
+ } else {
17036
+ await issueSubmission.submitIssue({
17037
+ title: formState.title,
17038
+ description: formState.description
17039
+ });
17040
+ }
17041
+ };
16103
17042
  const handleSubmit = async (e) => {
16104
17043
  e.preventDefault();
16105
17044
  e.stopPropagation();
16106
- await issueSubmission.submitIssue(formState.title, formState.description);
17045
+ await submitCurrentMode();
16107
17046
  };
16108
- const handleClose = () => setIsOpen(false);
17047
+ const handleClose = () => {
17048
+ if (formState.mode === "ai") {
17049
+ onCancel();
17050
+ return;
17051
+ }
17052
+ setIsOpen(false);
17053
+ };
17054
+ if (formState.renderedMode === "ai") {
17055
+ return createPortal(
17056
+ /* @__PURE__ */ jsxs(
17057
+ IssueIntentBubbleAnchor,
17058
+ {
17059
+ x: position2.x,
17060
+ y: position2.y,
17061
+ onClose: handleClose,
17062
+ dirty: formState.intent.trim().length > 0,
17063
+ open: formState.mode === "ai",
17064
+ onExitComplete: formState.finishModeTransition,
17065
+ children: [
17066
+ showJiraFields ? /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: null, onError: () => null, children: /* @__PURE__ */ jsx(
17067
+ IssueFormJiraFieldDefaults,
17068
+ {
17069
+ integrationId: jiraIntegrationId,
17070
+ onDefaultsResolved: (defaults) => setJiraFields((current) => ({ ...defaults, ...current }))
17071
+ }
17072
+ ) }) : null,
17073
+ showCustomFields ? /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: null, onError: () => null, children: /* @__PURE__ */ jsx(
17074
+ IssueFormCustomFieldDefaults,
17075
+ {
17076
+ projectId: selectedProjectId,
17077
+ onDefaultsResolved: (defaults) => setCustomFieldValues((current) => ({ ...defaults, ...current }))
17078
+ }
17079
+ ) }) : null,
17080
+ /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: null, onError: () => null, children: /* @__PURE__ */ jsx(IssueFormDraftCapabilityGate, { onResolved: handleDraftCapabilityResolved }) }),
17081
+ /* @__PURE__ */ jsx(
17082
+ IssueIntentBubble,
17083
+ {
17084
+ value: formState.intent,
17085
+ onChange: formState.setIntent,
17086
+ onSubmit: () => void submitCurrentMode(),
17087
+ onSwitchToManual: () => formState.setMode("manual"),
17088
+ submitting: issueSubmission.isSubmitting,
17089
+ error: issueSubmission.error
17090
+ }
17091
+ )
17092
+ ]
17093
+ }
17094
+ ),
17095
+ getPortalContainer()
17096
+ );
17097
+ }
16109
17098
  return createPortal(
16110
17099
  /* @__PURE__ */ jsx(
16111
17100
  OverlayShell,
16112
17101
  {
16113
- open: isOpen,
17102
+ open: isOpen && formState.mode === "manual",
16114
17103
  shellClassName: "h-auto max-h-[min(80vh,640px)] max-w-[480px]",
16115
17104
  closeOnBackdropClick: false,
16116
17105
  onClose: handleClose,
16117
17106
  onExitComplete: () => {
17107
+ if (formState.mode === "ai") {
17108
+ formState.finishModeTransition();
17109
+ return;
17110
+ }
16118
17111
  if (submitSucceededRef.current) {
16119
17112
  onSubmit(hadIntegrationFailureRef.current);
16120
17113
  } else {
@@ -16127,19 +17120,24 @@ function IssueForm({
16127
17120
  className: `${ISSUE_STICKER_REPORT_FORM_CLASS} flex min-h-0 flex-1 flex-col`,
16128
17121
  onSubmit: handleSubmit,
16129
17122
  children: [
16130
- /* @__PURE__ */ jsx("div", { className: "border-b border-line-subtle px-4 py-3", children: /* @__PURE__ */ jsx(IssueFormHeader, { title: "이슈 생성", onClose: handleClose }) }),
17123
+ /* @__PURE__ */ jsx("div", { className: "border-b border-line-subtle px-4 py-3", children: /* @__PURE__ */ jsx(
17124
+ IssueFormHeader,
17125
+ {
17126
+ title: "이슈 생성",
17127
+ onClose: handleClose,
17128
+ onSwitchToAi: draftDisabledReason ? void 0 : () => formState.setMode("ai")
17129
+ }
17130
+ ) }),
16131
17131
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-h-0 space-y-3 overflow-y-auto px-4 py-3", children: [
17132
+ issueSubmission.error && /* @__PURE__ */ jsx(IssueFormError, { error: issueSubmission.error }),
16132
17133
  hasJiraIntegration && jiraConnect.needsConnect ? /* @__PURE__ */ jsx(JiraConnectNudge, { onConnect: () => void jiraConnect.connect() }) : null,
16133
- /* @__PURE__ */ jsx(
16134
- SessionReplayAttachToggle,
17134
+ isMember ? /* @__PURE__ */ jsx(
17135
+ SessionReplayLimitNotice,
16135
17136
  {
16136
17137
  available: sessionReplay.available,
16137
- canAttach: sessionReplay.canAttach,
16138
- preferOn: sessionReplay.preferOn,
16139
- onPreferOnChange: sessionReplay.setPreferOn
17138
+ canAttach: sessionReplay.canAttach
16140
17139
  }
16141
- ),
16142
- issueSubmission.error && /* @__PURE__ */ jsx(IssueFormError, { error: issueSubmission.error }),
17140
+ ) : null,
16143
17141
  /* @__PURE__ */ jsx(
16144
17142
  IssueFormTitleField,
16145
17143
  {
@@ -16156,6 +17154,7 @@ function IssueForm({
16156
17154
  disabled: issueSubmission.isSubmitting
16157
17155
  }
16158
17156
  ),
17157
+ draftDisabledReason ? /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: draftDisabledReason }) : null,
16159
17158
  showIntegrationSkeleton ? /* @__PURE__ */ jsx(IntegrationFieldsSkeleton, {}) : null,
16160
17159
  showJiraFields ? /* @__PURE__ */ jsx(
16161
17160
  QueryBoundary,
@@ -16324,7 +17323,7 @@ var Collapsible = React.forwardRef(
16324
17323
  children: /* @__PURE__ */ jsx(
16325
17324
  Primitive.div,
16326
17325
  {
16327
- "data-state": getState$2(open),
17326
+ "data-state": getState$1(open),
16328
17327
  "data-disabled": disabled ? "" : void 0,
16329
17328
  ...collapsibleProps,
16330
17329
  ref: forwardedRef
@@ -16335,18 +17334,18 @@ var Collapsible = React.forwardRef(
16335
17334
  }
16336
17335
  );
16337
17336
  Collapsible.displayName = COLLAPSIBLE_NAME;
16338
- var TRIGGER_NAME$3 = "CollapsibleTrigger";
17337
+ var TRIGGER_NAME$2 = "CollapsibleTrigger";
16339
17338
  var CollapsibleTrigger = React.forwardRef(
16340
17339
  (props, forwardedRef) => {
16341
17340
  const { __scopeCollapsible, ...triggerProps } = props;
16342
- const context = useCollapsibleContext(TRIGGER_NAME$3, __scopeCollapsible);
17341
+ const context = useCollapsibleContext(TRIGGER_NAME$2, __scopeCollapsible);
16343
17342
  return /* @__PURE__ */ jsx(
16344
17343
  Primitive.button,
16345
17344
  {
16346
17345
  type: "button",
16347
17346
  "aria-controls": context.open ? context.contentId : void 0,
16348
17347
  "aria-expanded": context.open || false,
16349
- "data-state": getState$2(context.open),
17348
+ "data-state": getState$1(context.open),
16350
17349
  "data-disabled": context.disabled ? "" : void 0,
16351
17350
  disabled: context.disabled,
16352
17351
  ...triggerProps,
@@ -16356,19 +17355,19 @@ var CollapsibleTrigger = React.forwardRef(
16356
17355
  );
16357
17356
  }
16358
17357
  );
16359
- CollapsibleTrigger.displayName = TRIGGER_NAME$3;
16360
- var CONTENT_NAME$3 = "CollapsibleContent";
17358
+ CollapsibleTrigger.displayName = TRIGGER_NAME$2;
17359
+ var CONTENT_NAME$2 = "CollapsibleContent";
16361
17360
  var CollapsibleContent = React.forwardRef(
16362
17361
  (props, forwardedRef) => {
16363
17362
  const { forceMount, ...contentProps } = props;
16364
- const context = useCollapsibleContext(CONTENT_NAME$3, props.__scopeCollapsible);
17363
+ const context = useCollapsibleContext(CONTENT_NAME$2, props.__scopeCollapsible);
16365
17364
  return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: ({ present }) => /* @__PURE__ */ jsx(CollapsibleContentImpl, { ...contentProps, ref: forwardedRef, present }) });
16366
17365
  }
16367
17366
  );
16368
- CollapsibleContent.displayName = CONTENT_NAME$3;
17367
+ CollapsibleContent.displayName = CONTENT_NAME$2;
16369
17368
  var CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {
16370
17369
  const { __scopeCollapsible, present, children, ...contentProps } = props;
16371
- const context = useCollapsibleContext(CONTENT_NAME$3, __scopeCollapsible);
17370
+ const context = useCollapsibleContext(CONTENT_NAME$2, __scopeCollapsible);
16372
17371
  const [isPresent, setIsPresent] = React.useState(present);
16373
17372
  const ref = React.useRef(null);
16374
17373
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
@@ -16405,7 +17404,7 @@ var CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {
16405
17404
  return /* @__PURE__ */ jsx(
16406
17405
  Primitive.div,
16407
17406
  {
16408
- "data-state": getState$2(context.open),
17407
+ "data-state": getState$1(context.open),
16409
17408
  "data-disabled": context.disabled ? "" : void 0,
16410
17409
  id: context.contentId,
16411
17410
  hidden: !isOpen,
@@ -16420,7 +17419,7 @@ var CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {
16420
17419
  }
16421
17420
  );
16422
17421
  });
16423
- function getState$2(open) {
17422
+ function getState$1(open) {
16424
17423
  return open ? "open" : "closed";
16425
17424
  }
16426
17425
  var Root$1 = Collapsible;
@@ -16626,7 +17625,7 @@ var AccordionItem$1 = React.forwardRef(
16626
17625
  Root$1,
16627
17626
  {
16628
17627
  "data-orientation": accordionContext.orientation,
16629
- "data-state": getState$1(open),
17628
+ "data-state": getState(open),
16630
17629
  ...collapsibleScope,
16631
17630
  ...accordionItemProps,
16632
17631
  ref: forwardedRef,
@@ -16656,7 +17655,7 @@ var AccordionHeader = React.forwardRef(
16656
17655
  Primitive.h3,
16657
17656
  {
16658
17657
  "data-orientation": accordionContext.orientation,
16659
- "data-state": getState$1(itemContext.open),
17658
+ "data-state": getState(itemContext.open),
16660
17659
  "data-disabled": itemContext.disabled ? "" : void 0,
16661
17660
  ...headerProps,
16662
17661
  ref: forwardedRef
@@ -16665,13 +17664,13 @@ var AccordionHeader = React.forwardRef(
16665
17664
  }
16666
17665
  );
16667
17666
  AccordionHeader.displayName = HEADER_NAME;
16668
- var TRIGGER_NAME$2 = "AccordionTrigger";
17667
+ var TRIGGER_NAME$1 = "AccordionTrigger";
16669
17668
  var AccordionTrigger$1 = React.forwardRef(
16670
17669
  (props, forwardedRef) => {
16671
17670
  const { __scopeAccordion, ...triggerProps } = props;
16672
17671
  const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion);
16673
- const itemContext = useAccordionItemContext(TRIGGER_NAME$2, __scopeAccordion);
16674
- const collapsibleContext = useAccordionCollapsibleContext(TRIGGER_NAME$2, __scopeAccordion);
17672
+ const itemContext = useAccordionItemContext(TRIGGER_NAME$1, __scopeAccordion);
17673
+ const collapsibleContext = useAccordionCollapsibleContext(TRIGGER_NAME$1, __scopeAccordion);
16675
17674
  const collapsibleScope = useCollapsibleScope(__scopeAccordion);
16676
17675
  return /* @__PURE__ */ jsx(Collection$1.ItemSlot, { scope: __scopeAccordion, children: /* @__PURE__ */ jsx(
16677
17676
  Trigger$1,
@@ -16686,13 +17685,13 @@ var AccordionTrigger$1 = React.forwardRef(
16686
17685
  ) });
16687
17686
  }
16688
17687
  );
16689
- AccordionTrigger$1.displayName = TRIGGER_NAME$2;
16690
- var CONTENT_NAME$2 = "AccordionContent";
17688
+ AccordionTrigger$1.displayName = TRIGGER_NAME$1;
17689
+ var CONTENT_NAME$1 = "AccordionContent";
16691
17690
  var AccordionContent$1 = React.forwardRef(
16692
17691
  (props, forwardedRef) => {
16693
17692
  const { __scopeAccordion, ...contentProps } = props;
16694
17693
  const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion);
16695
- const itemContext = useAccordionItemContext(CONTENT_NAME$2, __scopeAccordion);
17694
+ const itemContext = useAccordionItemContext(CONTENT_NAME$1, __scopeAccordion);
16696
17695
  const collapsibleScope = useCollapsibleScope(__scopeAccordion);
16697
17696
  return /* @__PURE__ */ jsx(
16698
17697
  Content$1,
@@ -16712,8 +17711,8 @@ var AccordionContent$1 = React.forwardRef(
16712
17711
  );
16713
17712
  }
16714
17713
  );
16715
- AccordionContent$1.displayName = CONTENT_NAME$2;
16716
- function getState$1(open) {
17714
+ AccordionContent$1.displayName = CONTENT_NAME$1;
17715
+ function getState(open) {
16717
17716
  return open ? "open" : "closed";
16718
17717
  }
16719
17718
  var Root2$1 = Accordion$1;
@@ -17458,11 +18457,11 @@ var TabsList$1 = React.forwardRef(
17458
18457
  }
17459
18458
  );
17460
18459
  TabsList$1.displayName = TAB_LIST_NAME;
17461
- var TRIGGER_NAME$1 = "TabsTrigger";
18460
+ var TRIGGER_NAME = "TabsTrigger";
17462
18461
  var TabsTrigger$1 = React.forwardRef(
17463
18462
  (props, forwardedRef) => {
17464
18463
  const { __scopeTabs, value, disabled = false, ...triggerProps } = props;
17465
- const context = useTabsContext(TRIGGER_NAME$1, __scopeTabs);
18464
+ const context = useTabsContext(TRIGGER_NAME, __scopeTabs);
17466
18465
  const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
17467
18466
  const triggerId = makeTriggerId(context.baseId, value);
17468
18467
  const contentId = makeContentId(context.baseId, value);
@@ -17509,12 +18508,12 @@ var TabsTrigger$1 = React.forwardRef(
17509
18508
  );
17510
18509
  }
17511
18510
  );
17512
- TabsTrigger$1.displayName = TRIGGER_NAME$1;
17513
- var CONTENT_NAME$1 = "TabsContent";
18511
+ TabsTrigger$1.displayName = TRIGGER_NAME;
18512
+ var CONTENT_NAME = "TabsContent";
17514
18513
  var TabsContent$1 = React.forwardRef(
17515
18514
  (props, forwardedRef) => {
17516
18515
  const { __scopeTabs, value, forceMount, children, ...contentProps } = props;
17517
- const context = useTabsContext(CONTENT_NAME$1, __scopeTabs);
18516
+ const context = useTabsContext(CONTENT_NAME, __scopeTabs);
17518
18517
  const triggerId = makeTriggerId(context.baseId, value);
17519
18518
  const contentId = makeContentId(context.baseId, value);
17520
18519
  const isSelected = value === context.value;
@@ -17544,7 +18543,7 @@ var TabsContent$1 = React.forwardRef(
17544
18543
  ) });
17545
18544
  }
17546
18545
  );
17547
- TabsContent$1.displayName = CONTENT_NAME$1;
18546
+ TabsContent$1.displayName = CONTENT_NAME;
17548
18547
  function makeTriggerId(baseId, value) {
17549
18548
  return `${baseId}-trigger-${value}`;
17550
18549
  }
@@ -32944,343 +33943,6 @@ function IssueDescription({
32944
33943
  error ? /* @__PURE__ */ jsx("p", { className: "text-xs text-danger", children: error }) : null
32945
33944
  ] });
32946
33945
  }
32947
- var DIALOG_NAME = "Dialog";
32948
- var [createDialogContext] = createContextScope(DIALOG_NAME);
32949
- var [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);
32950
- var Dialog$1 = (props) => {
32951
- const {
32952
- __scopeDialog,
32953
- children,
32954
- open: openProp,
32955
- defaultOpen,
32956
- onOpenChange,
32957
- modal = true
32958
- } = props;
32959
- const triggerRef = React.useRef(null);
32960
- const contentRef = React.useRef(null);
32961
- const [open, setOpen] = useControllableState({
32962
- prop: openProp,
32963
- defaultProp: defaultOpen ?? false,
32964
- onChange: onOpenChange,
32965
- caller: DIALOG_NAME
32966
- });
32967
- return /* @__PURE__ */ jsx(
32968
- DialogProvider,
32969
- {
32970
- scope: __scopeDialog,
32971
- triggerRef,
32972
- contentRef,
32973
- contentId: useId$1(),
32974
- titleId: useId$1(),
32975
- descriptionId: useId$1(),
32976
- open,
32977
- onOpenChange: setOpen,
32978
- onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
32979
- modal,
32980
- children
32981
- }
32982
- );
32983
- };
32984
- Dialog$1.displayName = DIALOG_NAME;
32985
- var TRIGGER_NAME = "DialogTrigger";
32986
- var DialogTrigger = React.forwardRef(
32987
- (props, forwardedRef) => {
32988
- const { __scopeDialog, ...triggerProps } = props;
32989
- const context = useDialogContext(TRIGGER_NAME, __scopeDialog);
32990
- const composedTriggerRef = useComposedRefs$1(forwardedRef, context.triggerRef);
32991
- return /* @__PURE__ */ jsx(
32992
- Primitive.button,
32993
- {
32994
- type: "button",
32995
- "aria-haspopup": "dialog",
32996
- "aria-expanded": context.open,
32997
- "aria-controls": context.open ? context.contentId : void 0,
32998
- "data-state": getState(context.open),
32999
- ...triggerProps,
33000
- ref: composedTriggerRef,
33001
- onClick: composeEventHandlers(props.onClick, context.onOpenToggle)
33002
- }
33003
- );
33004
- }
33005
- );
33006
- DialogTrigger.displayName = TRIGGER_NAME;
33007
- var PORTAL_NAME = "DialogPortal";
33008
- var [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {
33009
- forceMount: void 0
33010
- });
33011
- var DialogPortal$1 = (props) => {
33012
- const { __scopeDialog, forceMount, children, container } = props;
33013
- const context = useDialogContext(PORTAL_NAME, __scopeDialog);
33014
- return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Portal$1, { asChild: true, container, children: child }) })) });
33015
- };
33016
- DialogPortal$1.displayName = PORTAL_NAME;
33017
- var OVERLAY_NAME = "DialogOverlay";
33018
- var DialogOverlay$1 = React.forwardRef(
33019
- (props, forwardedRef) => {
33020
- const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);
33021
- const { forceMount = portalContext.forceMount, ...overlayProps } = props;
33022
- const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);
33023
- return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;
33024
- }
33025
- );
33026
- DialogOverlay$1.displayName = OVERLAY_NAME;
33027
- var Slot = createSlot("DialogOverlay.RemoveScroll");
33028
- var DialogOverlayImpl = React.forwardRef(
33029
- (props, forwardedRef) => {
33030
- const { __scopeDialog, ...overlayProps } = props;
33031
- const context = useDialogContext(OVERLAY_NAME, __scopeDialog);
33032
- const registerDismissableSurface = useDismissableLayerSurface();
33033
- const composedRefs = useComposedRefs$1(forwardedRef, registerDismissableSurface);
33034
- return (
33035
- // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`
33036
- // ie. when `Overlay` and `Content` are siblings
33037
- /* @__PURE__ */ jsx(ReactRemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(
33038
- Primitive.div,
33039
- {
33040
- "data-state": getState(context.open),
33041
- ...overlayProps,
33042
- ref: composedRefs,
33043
- style: { pointerEvents: "auto", ...overlayProps.style }
33044
- }
33045
- ) })
33046
- );
33047
- }
33048
- );
33049
- var CONTENT_NAME = "DialogContent";
33050
- var DialogContent$1 = React.forwardRef(
33051
- (props, forwardedRef) => {
33052
- const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);
33053
- const { forceMount = portalContext.forceMount, ...contentProps } = props;
33054
- const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);
33055
- return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });
33056
- }
33057
- );
33058
- DialogContent$1.displayName = CONTENT_NAME;
33059
- var DialogContentModal = React.forwardRef(
33060
- (props, forwardedRef) => {
33061
- const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);
33062
- const contentRef = React.useRef(null);
33063
- const composedRefs = useComposedRefs$1(forwardedRef, context.contentRef, contentRef);
33064
- React.useEffect(() => {
33065
- const content2 = contentRef.current;
33066
- if (content2) return hideOthers(content2);
33067
- }, []);
33068
- return /* @__PURE__ */ jsx(
33069
- DialogContentImpl,
33070
- {
33071
- ...props,
33072
- ref: composedRefs,
33073
- trapFocus: context.open,
33074
- disableOutsidePointerEvents: context.open,
33075
- onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
33076
- var _a;
33077
- event.preventDefault();
33078
- (_a = context.triggerRef.current) == null ? void 0 : _a.focus();
33079
- }),
33080
- onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
33081
- const originalEvent = event.detail.originalEvent;
33082
- const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
33083
- const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
33084
- if (isRightClick) event.preventDefault();
33085
- }),
33086
- onFocusOutside: composeEventHandlers(
33087
- props.onFocusOutside,
33088
- (event) => event.preventDefault()
33089
- )
33090
- }
33091
- );
33092
- }
33093
- );
33094
- var DialogContentNonModal = React.forwardRef(
33095
- (props, forwardedRef) => {
33096
- const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);
33097
- const hasInteractedOutsideRef = React.useRef(false);
33098
- const hasPointerDownOutsideRef = React.useRef(false);
33099
- return /* @__PURE__ */ jsx(
33100
- DialogContentImpl,
33101
- {
33102
- ...props,
33103
- ref: forwardedRef,
33104
- trapFocus: false,
33105
- disableOutsidePointerEvents: false,
33106
- onCloseAutoFocus: (event) => {
33107
- var _a, _b2;
33108
- (_a = props.onCloseAutoFocus) == null ? void 0 : _a.call(props, event);
33109
- if (!event.defaultPrevented) {
33110
- if (!hasInteractedOutsideRef.current) (_b2 = context.triggerRef.current) == null ? void 0 : _b2.focus();
33111
- event.preventDefault();
33112
- }
33113
- hasInteractedOutsideRef.current = false;
33114
- hasPointerDownOutsideRef.current = false;
33115
- },
33116
- onInteractOutside: (event) => {
33117
- var _a, _b2;
33118
- (_a = props.onInteractOutside) == null ? void 0 : _a.call(props, event);
33119
- if (!event.defaultPrevented) {
33120
- hasInteractedOutsideRef.current = true;
33121
- if (event.detail.originalEvent.type === "pointerdown") {
33122
- hasPointerDownOutsideRef.current = true;
33123
- }
33124
- }
33125
- const target = event.target;
33126
- const targetIsTrigger = (_b2 = context.triggerRef.current) == null ? void 0 : _b2.contains(target);
33127
- if (targetIsTrigger) event.preventDefault();
33128
- if (event.detail.originalEvent.type === "focusin" && hasPointerDownOutsideRef.current) {
33129
- event.preventDefault();
33130
- }
33131
- }
33132
- }
33133
- );
33134
- }
33135
- );
33136
- var DialogContentImpl = React.forwardRef(
33137
- (props, forwardedRef) => {
33138
- const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;
33139
- const context = useDialogContext(CONTENT_NAME, __scopeDialog);
33140
- useFocusGuards();
33141
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
33142
- FocusScope,
33143
- {
33144
- asChild: true,
33145
- loop: true,
33146
- trapped: trapFocus,
33147
- onMountAutoFocus: onOpenAutoFocus,
33148
- onUnmountAutoFocus: onCloseAutoFocus,
33149
- children: /* @__PURE__ */ jsx(
33150
- DismissableLayer,
33151
- {
33152
- role: "dialog",
33153
- id: context.contentId,
33154
- "aria-describedby": context.descriptionId,
33155
- "aria-labelledby": context.titleId,
33156
- "data-state": getState(context.open),
33157
- ...contentProps,
33158
- ref: forwardedRef,
33159
- deferPointerDownOutside: true,
33160
- onDismiss: () => context.onOpenChange(false)
33161
- }
33162
- )
33163
- }
33164
- ) });
33165
- }
33166
- );
33167
- var TITLE_NAME = "DialogTitle";
33168
- var DialogTitle$1 = React.forwardRef(
33169
- (props, forwardedRef) => {
33170
- const { __scopeDialog, ...titleProps } = props;
33171
- const context = useDialogContext(TITLE_NAME, __scopeDialog);
33172
- return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });
33173
- }
33174
- );
33175
- DialogTitle$1.displayName = TITLE_NAME;
33176
- var DESCRIPTION_NAME = "DialogDescription";
33177
- var DialogDescription$1 = React.forwardRef(
33178
- (props, forwardedRef) => {
33179
- const { __scopeDialog, ...descriptionProps } = props;
33180
- const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);
33181
- return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });
33182
- }
33183
- );
33184
- DialogDescription$1.displayName = DESCRIPTION_NAME;
33185
- var CLOSE_NAME = "DialogClose";
33186
- var DialogClose$1 = React.forwardRef(
33187
- (props, forwardedRef) => {
33188
- const { __scopeDialog, ...closeProps } = props;
33189
- const context = useDialogContext(CLOSE_NAME, __scopeDialog);
33190
- return /* @__PURE__ */ jsx(
33191
- Primitive.button,
33192
- {
33193
- type: "button",
33194
- ...closeProps,
33195
- ref: forwardedRef,
33196
- onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))
33197
- }
33198
- );
33199
- }
33200
- );
33201
- DialogClose$1.displayName = CLOSE_NAME;
33202
- function getState(open) {
33203
- return open ? "open" : "closed";
33204
- }
33205
- const Dialog = Dialog$1;
33206
- const DialogClose = DialogClose$1;
33207
- const DialogPortal = ({ children }) => {
33208
- const portalContainer = usePortalContainer();
33209
- return /* @__PURE__ */ jsx(DialogPortal$1, { container: portalContainer, children });
33210
- };
33211
- const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33212
- DialogOverlay$1,
33213
- {
33214
- ref,
33215
- className: cn$1(
33216
- `fixed inset-0 ${OVERLAY_LAYER.dialogOverlay} bg-black/24`,
33217
- "data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out",
33218
- "motion-reduce:animate-none",
33219
- className
33220
- ),
33221
- ...props
33222
- }
33223
- ));
33224
- DialogOverlay.displayName = DialogOverlay$1.displayName;
33225
- const DialogContent = React.forwardRef(({ className, children, hideCloseButton = false, onEscapeKeyDown, style, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
33226
- /* @__PURE__ */ jsx(DialogOverlay, {}),
33227
- /* @__PURE__ */ jsxs(
33228
- DialogContent$1,
33229
- {
33230
- ref,
33231
- onEscapeKeyDown: stopEscapePropagation(onEscapeKeyDown),
33232
- style: {
33233
- left: `calc(50% - (var(${BODY_SCROLLBAR_WIDTH_CSS_VAR}, 0px) / 2))`,
33234
- ...style
33235
- },
33236
- className: cn$1(
33237
- `panel-shell fixed left-[50%] top-[50%] ${OVERLAY_LAYER.dialogContent} grid w-full max-w-[36rem] translate-x-[-50%] translate-y-[-50%] gap-5 rounded-2xl p-7 shadow-lg`,
33238
- "data-[state=open]:animate-dialog-in data-[state=closed]:animate-dialog-out",
33239
- "motion-reduce:animate-none",
33240
- className
33241
- ),
33242
- ...props,
33243
- children: [
33244
- children,
33245
- !hideCloseButton ? /* @__PURE__ */ jsxs(
33246
- DialogClose$1,
33247
- {
33248
- className: cn$1(
33249
- "absolute right-4 top-4 rounded-md border border-transparent bg-surface-2 p-1.5 text-text-tertiary",
33250
- "transition-colors duration-fast",
33251
- "hover:border-line-subtle hover:bg-surface-3 hover:text-text-primary",
33252
- "focus-visible:outline-none focus-visible:shadow-focus"
33253
- ),
33254
- children: [
33255
- /* @__PURE__ */ jsx(X$1, { className: "h-4 w-4" }),
33256
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "닫기" })
33257
- ]
33258
- }
33259
- ) : null
33260
- ]
33261
- }
33262
- )
33263
- ] }));
33264
- DialogContent.displayName = DialogContent$1.displayName;
33265
- const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn$1("flex flex-col space-y-2 text-left", className), ...props });
33266
- const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33267
- DialogTitle$1,
33268
- {
33269
- ref,
33270
- className: cn$1("text-lg font-semibold text-text-primary", className),
33271
- ...props
33272
- }
33273
- ));
33274
- DialogTitle.displayName = DialogTitle$1.displayName;
33275
- const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33276
- DialogDescription$1,
33277
- {
33278
- ref,
33279
- className: cn$1("text-sm leading-relaxed text-text-secondary", className),
33280
- ...props
33281
- }
33282
- ));
33283
- DialogDescription.displayName = DialogDescription$1.displayName;
33284
33946
  function getServiceDisplayName(serviceType) {
33285
33947
  switch (serviceType) {
33286
33948
  case "JIRA":
@@ -33470,13 +34132,78 @@ function IssueDeleteActions({
33470
34132
  }
33471
34133
  );
33472
34134
  }
34135
+ function IssueGenerationFailure$1({
34136
+ isRegenerating,
34137
+ regenerate
34138
+ }) {
34139
+ const handleClick = async () => {
34140
+ const success = await regenerate();
34141
+ if (!success) {
34142
+ toast.error("재생성에 실패했습니다. 잠시 후 다시 시도해주세요.");
34143
+ }
34144
+ };
34145
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 text-sm", children: [
34146
+ /* @__PURE__ */ jsx("span", { className: "text-danger", children: "제목과 설명을 생성하지 못했습니다. 입력한 내용은 그대로 남아 있습니다." }),
34147
+ /* @__PURE__ */ jsx(
34148
+ Button,
34149
+ {
34150
+ type: "button",
34151
+ variant: "outline",
34152
+ size: "sm",
34153
+ onClick: handleClick,
34154
+ disabled: isRegenerating,
34155
+ children: "다시 생성"
34156
+ }
34157
+ )
34158
+ ] });
34159
+ }
34160
+ function useRegenerateIssue(issueId, onUpdated) {
34161
+ const [isRegenerating, setIsRegenerating] = useState(false);
34162
+ const regenerate = useCallback(async () => {
34163
+ setIsRegenerating(true);
34164
+ try {
34165
+ await issueService.regenerateIssue(issueId);
34166
+ applyIssueMutationEffects(issueId);
34167
+ onUpdated == null ? void 0 : onUpdated();
34168
+ return true;
34169
+ } catch {
34170
+ return false;
34171
+ } finally {
34172
+ setIsRegenerating(false);
34173
+ }
34174
+ }, [issueId, onUpdated]);
34175
+ return { isRegenerating, regenerate };
34176
+ }
34177
+ function IssueGenerationFailure({
34178
+ issueId,
34179
+ onUpdated
34180
+ }) {
34181
+ const { isRegenerating, regenerate } = useRegenerateIssue(issueId, onUpdated);
34182
+ return /* @__PURE__ */ jsx(IssueGenerationFailure$1, { isRegenerating, regenerate });
34183
+ }
34184
+ function IssueGenerationBadge({ status }) {
34185
+ if (status === "pending" || status === "processing") {
34186
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5 rounded-md bg-warning-subtle px-2 py-0.5 text-2xs font-medium text-warning", children: [
34187
+ /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-md bg-warning" }),
34188
+ "제목 생성 중"
34189
+ ] });
34190
+ }
34191
+ if (status === "failed") {
34192
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5 rounded-md bg-danger-subtle px-2 py-0.5 text-2xs font-medium text-danger", children: [
34193
+ /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-md bg-danger" }),
34194
+ "제목 생성 실패"
34195
+ ] });
34196
+ }
34197
+ return null;
34198
+ }
33473
34199
  function IssueHeader({
33474
34200
  issueId,
33475
34201
  title,
33476
34202
  adminIssueUrl,
33477
34203
  onClose,
33478
34204
  onUpdated,
33479
- readOnly = false
34205
+ readOnly = false,
34206
+ generationStatus
33480
34207
  }) {
33481
34208
  const [draftTitle, setDraftTitle] = useState(title);
33482
34209
  const [isEditing, setIsEditing] = useState(false);
@@ -33532,6 +34259,7 @@ function IssueHeader({
33532
34259
  }
33533
34260
  ) : /* @__PURE__ */ jsxs("div", { className: "flex max-w-full min-w-0 items-center gap-1", children: [
33534
34261
  /* @__PURE__ */ jsx("h2", { className: "m-0 min-w-0 max-w-[28rem] truncate text-xl font-semibold text-text-primary", children: title }),
34262
+ /* @__PURE__ */ jsx(IssueGenerationBadge, { status: generationStatus }),
33535
34263
  !readOnly ? /* @__PURE__ */ jsx(
33536
34264
  Button,
33537
34265
  {
@@ -34493,7 +35221,7 @@ function IssuePopover({ issueId, onClose, onUpdate }) {
34493
35221
  const { isMember } = useAuthContext();
34494
35222
  const canWriteContent = canWriteIssueContent(isMember, (_a = SDKManager.getInstance().config.user) == null ? void 0 : _a.id);
34495
35223
  const { selectedProjectId } = useProject();
34496
- const { data: issue } = useSuspenseQuery({
35224
+ const { data: issue, refetch } = useSuspenseQuery({
34497
35225
  queryKey: ["issue", issueId, selectedProjectId],
34498
35226
  queryFn: async () => {
34499
35227
  const issueData = await issueService.getIssue(issueId);
@@ -34501,6 +35229,7 @@ function IssuePopover({ issueId, onClose, onUpdate }) {
34501
35229
  }
34502
35230
  });
34503
35231
  const adminIssueUrl = getAdminIssueUrl(issue.id);
35232
+ useGenerationPolling({ status: issue.generation_status, onRefetch: refetch });
34504
35233
  useDisableBodyScroll();
34505
35234
  const mapping = getPrimaryJiraMapping(issue);
34506
35235
  const meta = getJiraMetadata(mapping);
@@ -34534,10 +35263,12 @@ function IssuePopover({ issueId, onClose, onUpdate }) {
34534
35263
  adminIssueUrl,
34535
35264
  onClose: handleClose,
34536
35265
  onUpdated: onUpdate,
34537
- readOnly: !canWriteContent
35266
+ readOnly: !canWriteContent,
35267
+ generationStatus: issue.generation_status
34538
35268
  }
34539
35269
  ) }),
34540
35270
  /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-4 py-3", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
35271
+ issue.generation_status === "failed" ? /* @__PURE__ */ jsx(IssueGenerationFailure, { issueId: issue.id, onUpdated: onUpdate }) : null,
34541
35272
  /* @__PURE__ */ jsx(
34542
35273
  IssueDescription,
34543
35274
  {
@@ -34975,6 +35706,63 @@ function getExpandedClusterStack(cluster, metrics = getWindowMetrics()) {
34975
35706
  function getCurrentStickerDocumentMetrics() {
34976
35707
  return getWindowMetrics();
34977
35708
  }
35709
+ const STICKER_PALETTE_WHITE = "#FFFFFF";
35710
+ const STICKER_PALETTE_INK = "#111827";
35711
+ const STICKER_PALETTE = {
35712
+ slate: { bg: "#475569", fg: STICKER_PALETTE_WHITE },
35713
+ blue: { bg: "#1D4ED8", fg: STICKER_PALETTE_WHITE },
35714
+ teal: { bg: "#0F766E", fg: STICKER_PALETTE_WHITE },
35715
+ green: { bg: "#15803D", fg: STICKER_PALETTE_WHITE },
35716
+ amber: { bg: "#B45309", fg: STICKER_PALETTE_WHITE },
35717
+ red: { bg: "#DC2626", fg: STICKER_PALETTE_WHITE },
35718
+ pink: { bg: "#BE185D", fg: STICKER_PALETTE_WHITE },
35719
+ violet: { bg: "#6D28D9", fg: STICKER_PALETTE_WHITE },
35720
+ orange: { bg: "#F97316", fg: STICKER_PALETTE_INK },
35721
+ yellow: { bg: "#FACC15", fg: STICKER_PALETTE_INK },
35722
+ indigo: { bg: "#4338CA", fg: STICKER_PALETTE_WHITE },
35723
+ cyan: { bg: "#22D3EE", fg: STICKER_PALETTE_INK }
35724
+ };
35725
+ const STICKER_PALETTE_ORDER = Object.keys(STICKER_PALETTE);
35726
+ function getEntry(name2) {
35727
+ if (!name2) return null;
35728
+ return STICKER_PALETTE[name2] ?? null;
35729
+ }
35730
+ function getStickerColor(name2) {
35731
+ var _a;
35732
+ return ((_a = getEntry(name2)) == null ? void 0 : _a.bg) ?? null;
35733
+ }
35734
+ function getStickerForeground(name2) {
35735
+ var _a;
35736
+ return ((_a = getEntry(name2)) == null ? void 0 : _a.fg) ?? null;
35737
+ }
35738
+ const MAX_CLUSTER_BANDS = 4;
35739
+ function getClusterColorNames(members) {
35740
+ var _a;
35741
+ const present = /* @__PURE__ */ new Set();
35742
+ for (const member of members) {
35743
+ const color2 = (_a = member.design) == null ? void 0 : _a.color;
35744
+ if (color2 && getStickerColor(color2)) {
35745
+ present.add(color2);
35746
+ }
35747
+ }
35748
+ return STICKER_PALETTE_ORDER.filter((name2) => present.has(name2)).slice(
35749
+ 0,
35750
+ MAX_CLUSTER_BANDS
35751
+ );
35752
+ }
35753
+ function buildClusterBackground(colorNames) {
35754
+ const hexes = colorNames.map((name2) => getStickerColor(name2)).filter((hex2) => Boolean(hex2));
35755
+ if (hexes.length === 0) return null;
35756
+ if (hexes.length === 1) return hexes[0] ?? null;
35757
+ const step = 100 / hexes.length;
35758
+ const round = (value) => Number.parseFloat(value.toFixed(2)).toString();
35759
+ const stops = hexes.map((hex2, index2) => {
35760
+ const from = index2 === 0 ? "0" : `${round(step * index2)}%`;
35761
+ const to = index2 === hexes.length - 1 ? "100%" : `${round(step * (index2 + 1))}%`;
35762
+ return `${hex2} ${from} ${to}`;
35763
+ });
35764
+ return `linear-gradient(135deg, ${stops.join(", ")})`;
35765
+ }
34978
35766
  const STICKER_MAX_WIDTH = 480;
34979
35767
  const STICKER_NON_TEXT_WIDTH = 72;
34980
35768
  function getEstimatedTextWidth(title) {
@@ -34988,12 +35776,15 @@ function getEstimatedTextWidth(title) {
34988
35776
  return width + 7;
34989
35777
  }, 0);
34990
35778
  }
34991
- function getEstimatedExpandedWidth(title) {
35779
+ const STICKER_BADGE_GAP = 36;
35780
+ function getEstimatedExpandedWidth(title, badge) {
35781
+ const badgeWidth = badge ? getEstimatedTextWidth(badge) + STICKER_BADGE_GAP : 0;
34992
35782
  return Math.min(
34993
- Math.max(getEstimatedTextWidth(title) + STICKER_NON_TEXT_WIDTH, 112),
35783
+ Math.max(getEstimatedTextWidth(title) + STICKER_NON_TEXT_WIDTH + badgeWidth, 112),
34994
35784
  STICKER_MAX_WIDTH
34995
35785
  );
34996
35786
  }
35787
+ const GENERATING_LABEL = "제목 생성 중";
34997
35788
  function IssueSticker$1({
34998
35789
  issue,
34999
35790
  isPopoverOpen,
@@ -35002,30 +35793,49 @@ function IssueSticker$1({
35002
35793
  clusterCount,
35003
35794
  onClusterClick,
35004
35795
  clusterStackAnimation,
35005
- clusterStackIndex = 0
35796
+ clusterStackIndex = 0,
35797
+ clusterColorNames,
35798
+ alwaysExpanded = false,
35799
+ ariaLabel
35006
35800
  }) {
35801
+ var _a, _b2, _c2;
35007
35802
  const position2 = documentPosition;
35008
- const expandedWidth = getEstimatedExpandedWidth(issue.title);
35803
+ const resolvedClusterCount = clusterCount ?? 0;
35804
+ const isCluster = resolvedClusterCount > 1;
35805
+ const clusterBackground = isCluster ? buildClusterBackground(clusterColorNames ?? []) : null;
35806
+ const generating = isGeneratingStatus(issue.generation_status) && !isCluster;
35807
+ const visibleTitle = isCluster ? `스티커 ${resolvedClusterCount}개 펼치기` : generating ? GENERATING_LABEL : issue.title;
35808
+ const badgeLabel = isCluster || generating ? null : ((_a = issue.design) == null ? void 0 : _a.label) ?? null;
35809
+ const designColor = isCluster || generating ? null : getStickerColor((_b2 = issue.design) == null ? void 0 : _b2.color);
35810
+ const designForeground = designColor ? getStickerForeground((_c2 = issue.design) == null ? void 0 : _c2.color) : null;
35811
+ const expandedWidth = getEstimatedExpandedWidth(visibleTitle, badgeLabel);
35009
35812
  const viewportWidth = typeof window === "undefined" ? Number.POSITIVE_INFINITY : window.innerWidth;
35010
35813
  const scrollX = typeof window === "undefined" ? 0 : window.scrollX || window.pageXOffset || 0;
35011
35814
  const viewportX = position2.x - scrollX;
35012
- const shouldExpandLeft = viewportX + expandedWidth > viewportWidth - 12;
35815
+ const shouldExpandLeft = !alwaysExpanded && viewportX + expandedWidth > viewportWidth - 12;
35013
35816
  const expandSide = shouldExpandLeft ? "left" : "right";
35014
- const style = {
35817
+ const style = alwaysExpanded ? { position: "relative" } : {
35015
35818
  position: "absolute",
35016
35819
  left: `${position2.x}px`,
35017
35820
  top: `${position2.y}px`,
35018
35821
  transform: shouldExpandLeft ? "translate3d(calc(-100% + 16px), -50%, 0)" : "translate3d(-16px, -50%, 0)"
35019
35822
  };
35020
35823
  const wrapperClassName = isPopoverOpen ? "z-[10001]" : "z-[9999] hover:z-[10001] focus-within:z-[10001]";
35021
- const resolvedClusterCount = clusterCount ?? 0;
35022
- const isCluster = resolvedClusterCount > 1;
35023
- const buttonClassName = `issue-sticker-marker issue-marker-breathe group flex h-8 w-max cursor-pointer items-center overflow-hidden rounded-full border text-white shadow-lg outline-none transition-[max-width,box-shadow,background-color,border-color,transform,opacity] duration-[var(--issue-marker-expand-duration)] ease-out focus-visible:ring-4 ${isCluster ? "max-w-8 border-white/80 bg-brand shadow-lg ring-2 ring-brand-subtle hover:max-w-[160px] hover:bg-brand-hover hover:shadow-xl focus-visible:max-w-[160px] focus-visible:ring-brand-subtle" : "max-w-8 border-white/80 bg-brand hover:max-w-[480px] hover:bg-brand-hover hover:shadow-xl focus-visible:max-w-[480px] focus-visible:ring-brand-subtle"} ${shouldExpandLeft ? "flex-row-reverse" : ""} ${isPopoverOpen ? "shadow-xl ring-4 ring-brand-subtle" : ""}`;
35024
- const visibleTitle = isCluster ? `스티커 ${resolvedClusterCount}개 펼치기` : issue.title;
35025
- const buttonStyle = clusterStackAnimation ? {
35026
- animation: clusterStackAnimation === "enter" ? "issue-sticker-cluster-sticker-enter 240ms cubic-bezier(0.34, 1.2, 0.64, 1) both" : "issue-sticker-cluster-sticker-exit 220ms ease-in both",
35027
- animationDelay: clusterStackAnimation === "enter" ? `${clusterStackIndex * 24}ms` : void 0
35028
- } : void 0;
35824
+ const colorClassName = designColor ? "" : "bg-brand hover:bg-brand-hover";
35825
+ const expandClassName = alwaysExpanded ? "max-w-[480px]" : "max-w-8 hover:max-w-[480px] hover:shadow-xl focus-visible:max-w-[480px]";
35826
+ const buttonClassName = `issue-sticker-marker ${generating || alwaysExpanded ? "" : "issue-marker-breathe"} group flex h-8 w-max cursor-pointer items-center overflow-hidden rounded-full border text-white shadow-lg outline-none transition-[max-width,box-shadow,background-color,border-color,transform,opacity] duration-[var(--issue-marker-expand-duration)] ease-out focus-visible:ring-4 ${isCluster ? `max-w-8 border-white/80 ${clusterBackground ? "" : "bg-brand hover:bg-brand-hover"} shadow-lg ring-2 ring-brand-subtle hover:max-w-[160px] hover:shadow-xl focus-visible:max-w-[160px] focus-visible:ring-brand-subtle` : `${expandClassName} ${colorClassName} focus-visible:ring-brand-subtle ${generating ? "border-dashed border-white/70" : "border-white/80"}`} ${shouldExpandLeft ? "flex-row-reverse" : ""} ${isPopoverOpen ? "shadow-xl ring-4 ring-brand-subtle" : ""}`;
35827
+ const backgroundStyle = clusterBackground ? clusterBackground.startsWith("linear-gradient") ? { background: clusterBackground } : { backgroundColor: clusterBackground } : designColor ? { backgroundColor: designColor } : {};
35828
+ const buttonStyle = {
35829
+ ...backgroundStyle,
35830
+ // 밝은 배경(노랑·주황·하늘)은 흰 글씨로 대비가 안 나온다. 팔레트가 정한 글씨색을
35831
+ // inline 으로 얹어 text-white 클래스를 덮는다.
35832
+ ...designForeground ? { color: designForeground } : {},
35833
+ ["--issue-sticker-expanded-width"]: `${expandedWidth}px`,
35834
+ ...clusterStackAnimation ? {
35835
+ animation: clusterStackAnimation === "enter" ? "issue-sticker-cluster-sticker-enter 240ms cubic-bezier(0.34, 1.2, 0.64, 1) both" : "issue-sticker-cluster-sticker-exit 220ms ease-in both",
35836
+ animationDelay: clusterStackAnimation === "enter" ? `${clusterStackIndex * 24}ms` : void 0
35837
+ } : {}
35838
+ };
35029
35839
  const handleClick = () => {
35030
35840
  if (isCluster) {
35031
35841
  onClusterClick == null ? void 0 : onClusterClick();
@@ -35043,23 +35853,31 @@ function IssueSticker$1({
35043
35853
  "data-cluster-count": isCluster ? resolvedClusterCount : void 0,
35044
35854
  "data-expand-side": expandSide,
35045
35855
  onClick: handleClick,
35046
- "aria-label": isCluster ? `겹친 스티커 ${resolvedClusterCount}개 펼치기` : `이슈 열기: ${issue.title}`,
35856
+ "aria-label": ariaLabel ?? (isCluster ? `겹친 스티커 ${resolvedClusterCount}개 펼치기` : `이슈 열기: ${visibleTitle}`),
35047
35857
  children: [
35048
35858
  /* @__PURE__ */ jsx(
35049
35859
  "span",
35050
35860
  {
35051
- className: "flex h-8 w-8 shrink-0 items-center justify-center text-sm font-black leading-none",
35861
+ className: "flex aspect-square h-full shrink-0 items-center justify-center text-sm font-black leading-none",
35052
35862
  "aria-hidden": "true",
35053
- children: isCluster ? `+${resolvedClusterCount}` : "!"
35863
+ children: isCluster ? `+${resolvedClusterCount}` : generating ? /* @__PURE__ */ jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : "!"
35054
35864
  }
35055
35865
  ),
35056
35866
  /* @__PURE__ */ jsx(
35057
35867
  "span",
35058
35868
  {
35059
- className: `min-w-0 max-w-[428px] flex-1 truncate whitespace-nowrap text-xs font-semibold leading-none opacity-0 transition-[opacity,transform] duration-[var(--issue-marker-expand-duration)] ease-out group-hover:translate-x-0 group-hover:opacity-100 group-focus-visible:translate-x-0 group-focus-visible:opacity-100 ${shouldExpandLeft ? "translate-x-1 pl-3 text-right" : "-translate-x-1 pr-3 text-left"}`,
35869
+ className: `min-w-0 max-w-[428px] flex-1 truncate whitespace-nowrap text-xs font-semibold leading-none transition-[opacity,transform] duration-[var(--issue-marker-expand-duration)] ease-out ${alwaysExpanded ? "translate-x-0 opacity-100" : "opacity-0 group-hover:translate-x-0 group-hover:opacity-100 group-focus-visible:translate-x-0 group-focus-visible:opacity-100"} ${shouldExpandLeft ? `${alwaysExpanded ? "" : "translate-x-1"} pl-3 text-right` : `${alwaysExpanded ? "" : "-translate-x-1"} pr-3 text-left`}`,
35060
35870
  children: visibleTitle
35061
35871
  }
35062
- )
35872
+ ),
35873
+ badgeLabel ? /* @__PURE__ */ jsx(
35874
+ "span",
35875
+ {
35876
+ "data-sticker-badge": "",
35877
+ className: `mx-3 shrink-0 whitespace-nowrap rounded-sm px-1.5 py-0.5 text-[10px] font-bold leading-none transition-opacity duration-[var(--issue-marker-expand-duration)] ease-out ${designForeground === STICKER_PALETTE_INK ? "bg-black/10" : "bg-white/25"} ${alwaysExpanded ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100"}`,
35878
+ children: badgeLabel
35879
+ }
35880
+ ) : null
35063
35881
  ]
35064
35882
  }
35065
35883
  ) });
@@ -35310,7 +36128,10 @@ function IssueStickersContainer$1({
35310
36128
  isPopoverOpen: false,
35311
36129
  onStickerClick,
35312
36130
  clusterCount: cluster.placements.length,
35313
- onClusterClick: () => openCluster(cluster.id)
36131
+ onClusterClick: () => openCluster(cluster.id),
36132
+ clusterColorNames: getClusterColorNames(
36133
+ cluster.placements.map((placement) => placement.issue)
36134
+ )
35314
36135
  },
35315
36136
  cluster.id
35316
36137
  );
@@ -37150,7 +37971,6 @@ function ContentAppWrapper({
37150
37971
  onBeforeStart: handleBeforeOnboardingStart,
37151
37972
  isCreatingIssueFlow: isCreatingIssue || clickPosition !== null,
37152
37973
  children: [
37153
- /* @__PURE__ */ jsx(ToastContainer, { position: "top-right" }),
37154
37974
  fabEnabled && /* @__PURE__ */ jsx(
37155
37975
  SdkToolbar,
37156
37976
  {
@@ -37172,7 +37992,7 @@ function ContentAppWrapper({
37172
37992
  onMenuOpenChange: setMoreMenuOpen
37173
37993
  }
37174
37994
  ),
37175
- /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), children: /* @__PURE__ */ jsx(
37995
+ /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), onError: OverlayErrorFallback, children: /* @__PURE__ */ jsx(
37176
37996
  IssueStickersContainer,
37177
37997
  {
37178
37998
  issues,
@@ -37194,7 +38014,7 @@ function ContentAppWrapper({
37194
38014
  renderMode
37195
38015
  }
37196
38016
  ),
37197
- openPopoverIssueId && isExtensionEnabled && /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), children: /* @__PURE__ */ jsx(
38017
+ openPopoverIssueId && isExtensionEnabled && /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), onError: OverlayErrorFallback, children: /* @__PURE__ */ jsx(
37198
38018
  IssuePopover,
37199
38019
  {
37200
38020
  issueId: openPopoverIssueId,
@@ -37202,7 +38022,7 @@ function ContentAppWrapper({
37202
38022
  onUpdate: loadIssues
37203
38023
  }
37204
38024
  ) }),
37205
- clickPosition && isExtensionEnabled && /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), children: /* @__PURE__ */ jsx(
38025
+ clickPosition && isExtensionEnabled && /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), onError: OverlayErrorFallback, children: /* @__PURE__ */ jsx(
37206
38026
  IssueForm,
37207
38027
  {
37208
38028
  position: clickPosition,
@@ -37247,18 +38067,21 @@ function AuthGate() {
37247
38067
  if (!isAuthenticated) {
37248
38068
  return null;
37249
38069
  }
37250
- return /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), children: /* @__PURE__ */ jsx(
37251
- ContentAppWrapper,
37252
- {
37253
- fabEnabled,
37254
- toolbar: sdk.config.toolbar,
37255
- onboarding
37256
- }
37257
- ) });
38070
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
38071
+ /* @__PURE__ */ jsx(ToastContainer, { position: "top-right" }),
38072
+ /* @__PURE__ */ jsx(QueryBoundary, { loadingFallback: /* @__PURE__ */ jsx(Fragment, {}), onError: OverlayErrorFallback, children: /* @__PURE__ */ jsx(
38073
+ ContentAppWrapper,
38074
+ {
38075
+ fabEnabled,
38076
+ toolbar: sdk.config.toolbar,
38077
+ onboarding
38078
+ }
38079
+ ) })
38080
+ ] });
37258
38081
  }
37259
- const globalsCSS = `:root,:host{color-scheme:light;--brand-h: 150;--brand-s: 100%;--brand-l: 34%;--brand-hsl: var(--brand-h) var(--brand-s) var(--brand-l);--brand: hsl(var(--brand-hsl));--brand-hover: hsl(var(--brand-h) calc(var(--brand-s) + 3%) calc(var(--brand-l) - 4%));--brand-active: hsl(var(--brand-h) calc(var(--brand-s) + 2%) calc(var(--brand-l) - 8%));--brand-subtle: hsl(var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .14);--brand-border: hsl(var(--brand-h) calc(var(--brand-s) + 8%) calc(var(--brand-l) + 8%) / .34);--brand-fg: hsl(0 0% 100%);--brand-ring: hsl(var(--brand-h) calc(var(--brand-s) + 12%) calc(var(--brand-l) + 10%) / .22);--font-sans: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;--font-display: var(--font-sans);--font-mono: var(--font-sans);--surface-0: 0 0% 99%;--surface-1: 0 0% 100%;--surface-2: 144 8% 96%;--surface-3: 144 6% 93%;--surface-inset: 144 6% 95%;--overlay-backdrop: hsl(0 0% 0% / .24);--overlay-backdrop-strong: hsl(0 0% 0% / .48);--text-primary: 150 10% 12%;--text-secondary: 148 6% 36%;--text-tertiary: 145 5% 42%;--text-disabled: 145 4% 70%;--text-inverse: 0 0% 100%;--border-subtle: 144 8% 91%;--border-default: 144 6% 85%;--border-strong: 144 5% 72%;--border-focus: var(--brand-h) var(--brand-s) var(--brand-l);--success: var(--brand-h) var(--brand-s) var(--brand-l);--success-subtle: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .14;--success-surface: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .24;--warning: 34 82% 52%;--warning-subtle: 34 82% 52% / .14;--danger: 3 68% 56%;--danger-subtle: 3 68% 56% / .12;--info: 202 52% 44%;--info-subtle: 202 52% 44% / .12;--accent-terra: 13 52% 47%;--accent-terra-subtle: 13 52% 47% / .1;--accent-terra-deep: 13 48% 44%;--accent-blue: 213 86% 56%;--accent-blue-subtle: 213 92% 56% / .12;--accent-blue-deep: 216 78% 40%;--accent-blue-border: 213 86% 62% / .36;--accent-cream: 38 52% 88%;--accent-cream-warm: 40 56% 95%;--accent-cream-deep: 38 48% 82%;--accent-highlight: 55 96% 70%;--accent-ink: 32 13% 11%;--radius-xs: 4px;--radius-sm: 8px;--radius-md: 12px;--radius-lg: 16px;--radius-xl: 20px;--radius-2xl: 24px;--radius-pill: 9999px;--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / .04);--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / .06), 0 1px 2px -1px hsl(0 0% 0% / .06);--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / .06), 0 2px 4px -2px hsl(0 0% 0% / .04);--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / .06), 0 4px 6px -4px hsl(0 0% 0% / .04);--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / .06), 0 8px 10px -6px hsl(0 0% 0% / .04);--shadow-focus: 0 0 0 3px var(--brand-ring);--shadow-inset: inset 0 1px 2px 0 hsl(0 0% 0% / .04);--shadow-brand: 0 2px 8px hsl(var(--brand-h) calc(var(--brand-s) - 60%) calc(var(--brand-l) - 14%) / .24), 0 6px 20px hsl(var(--brand-h) calc(var(--brand-s) - 70%) calc(var(--brand-l) - 19%) / .16);--duration-instant: 90ms;--duration-fast: .16s;--duration-base: .26s;--duration-out: .18s;--duration-slow: .36s;--ease-out: cubic-bezier(.23, 1, .32, 1);--ease-in-out: cubic-bezier(.45, 0, .15, 1);--ease-spring: cubic-bezier(.18, .94, .32, 1.08);--grid-line: 0 0% 92%}.dark,:host(.dark){color-scheme:dark;--brand-l: 34%;--brand-fg: hsl(0 0% 100%);--surface-0: 150 8% 7%;--surface-1: 150 6% 10%;--surface-2: 150 5% 14%;--surface-3: 150 4% 18%;--surface-inset: 150 6% 6%;--overlay-backdrop: hsl(0 0% 0% / .56);--overlay-backdrop-strong: hsl(0 0% 0% / .8);--text-primary: 40 16% 93%;--text-secondary: 36 8% 68%;--text-tertiary: 34 6% 50%;--text-disabled: 30 5% 34%;--text-inverse: 150 8% 10%;--border-subtle: 150 6% 16%;--border-default: 150 5% 22%;--border-strong: 150 4% 34%;--success: var(--brand-h) var(--brand-s) var(--brand-l);--success-subtle: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .14;--success-surface: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .24;--warning: 34 82% 62%;--danger: 2 70% 64%;--info: 202 54% 62%;--accent-terra: 13 56% 62%;--accent-terra-subtle: 13 56% 62% / .14;--accent-terra-deep: 13 52% 56%;--accent-blue: 210 92% 68%;--accent-blue-subtle: 210 92% 68% / .18;--accent-blue-deep: 209 100% 78%;--accent-blue-border: 210 92% 72% / .44;--accent-cream: 38 30% 26%;--accent-cream-warm: 38 22% 18%;--accent-cream-deep: 38 26% 32%;--accent-highlight: 55 96% 70%;--accent-ink: 32 13% 8%;--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / .2);--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / .3), 0 1px 2px -1px hsl(0 0% 0% / .24);--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / .34), 0 2px 4px -2px hsl(0 0% 0% / .2);--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / .38), 0 4px 6px -4px hsl(0 0% 0% / .24);--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / .44), 0 8px 10px -6px hsl(0 0% 0% / .28);--shadow-inset: inset 0 1px 2px 0 hsl(0 0% 0% / .16);--shadow-brand: 0 2px 8px hsl(var(--brand-h) calc(var(--brand-s) - 60%) calc(var(--brand-l) - 24%) / .44), 0 6px 20px hsl(0 0% 0% / .32);--grid-line: 150 6% 14%}*{border-color:hsl(var(--border-default))}html{font-family:var(--font-sans),ui-sans-serif,system-ui,-apple-system,sans-serif;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-feature-settings:"cv11","ss01","ss03";background-color:hsl(var(--surface-0))}body{margin:0;min-height:100vh;color:hsl(var(--text-primary));background-color:hsl(var(--surface-0))}::-moz-selection{background-color:hsl(var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 16%) / .22);color:hsl(var(--text-primary))}::selection{background-color:hsl(var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 16%) / .22);color:hsl(var(--text-primary))}code,kbd,samp,pre{font-family:var(--font-mono),ui-monospace,SFMono-Regular,Menlo,monospace;font-feature-settings:"ss01","ss02","cv11"}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:hsl(var(--border-strong) / .52);border-radius:var(--radius-pill);border:2px solid transparent;background-clip:padding-box}::-webkit-scrollbar-thumb:hover{background:hsl(var(--border-strong) / .9);background-clip:padding-box;border:2px solid transparent}.app-canvas,.grid-canvas{background-color:hsl(var(--surface-0))}.onboarding-canvas{--surface-0: var(--brand-h) var(--brand-s) var(--brand-l);--surface-1: 0 0% 100%;--surface-2: var(--brand-h) 62% 28%;--surface-3: var(--brand-h) 60% 25%;--surface-inset: var(--brand-h) 62% 28%;--text-primary: 0 0% 100%;--text-secondary: var(--brand-h) 46% 90%;--text-tertiary: var(--brand-h) 34% 84%;--text-disabled: var(--brand-h) 20% 72%;--border-subtle: var(--brand-h) 44% 52%;--border-default: var(--brand-h) 40% 58%;--border-strong: var(--brand-h) 36% 70%;--border-focus: 0 0% 100%;--brand-hsl: 0 0% 100%;--brand: hsl(var(--brand-hsl));--brand-hover: hsl(var(--brand-h) 24% 94%);--brand-active: hsl(var(--brand-h) 20% 88%);--brand-fg: hsl(var(--brand-h) var(--brand-s) 24%);--brand-ring: hsl(0 0% 100% / .4);--danger: 6 96% 86%;--danger-subtle: 6 96% 86% / .18;--warning: 42 96% 82%;--warning-subtle: 42 96% 82% / .18}.onboarding-canvas .bg-surface-1,.onboarding-canvas input,.onboarding-canvas textarea,.onboarding-canvas [role=combobox]{--text-primary: 150 10% 12%;--text-secondary: 148 6% 36%;--text-tertiary: 145 5% 42%;--surface-2: 144 8% 96%;--border-subtle: 144 8% 91%;--border-default: 144 6% 85%}@keyframes onboarding-step-in{0%{opacity:0;transform:translate(96px)}to{opacity:1;transform:translate(0)}}.onboarding-step-in{animation:onboarding-step-in var(--duration-slow) var(--ease-out) forwards}@keyframes onboarding-enter-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.onboarding-enter{position:fixed;top:0;right:0;bottom:0;left:0;overflow-x:hidden;overflow-y:auto;animation:onboarding-enter-up var(--duration-base) var(--ease-out) forwards}@keyframes onboarding-confetti-x{0%{transform:translate(0)}to{transform:translate(var(--confetti-x))}}@keyframes onboarding-confetti-y{0%{transform:translateY(0);animation-timing-function:cubic-bezier(.12,.66,.32,1)}42%{transform:translateY(var(--confetti-lift));animation-timing-function:cubic-bezier(.58,0,.86,.32)}to{transform:translateY(var(--confetti-drop))}}@keyframes onboarding-confetti-piece{0%{opacity:0;transform:scale(.7) rotate(0)}6%{opacity:1}72%{opacity:1}to{opacity:0;transform:scale(1) rotate(var(--confetti-spin))}}.onboarding-confetti-x,.onboarding-confetti-y,.onboarding-confetti-piece{--confetti-duration: 1.9s;animation-duration:var(--confetti-duration);animation-delay:var(--confetti-delay, 0ms);animation-fill-mode:both}.onboarding-confetti-x{animation-name:onboarding-confetti-x;animation-timing-function:cubic-bezier(.08,.62,.3,1)}.onboarding-confetti-y{animation-name:onboarding-confetti-y;animation-timing-function:linear}.onboarding-confetti-piece{width:var(--confetti-size);height:var(--confetti-size);border-radius:var(--radius-pill) var(--radius-xs) var(--radius-pill) var(--radius-pill);animation-name:onboarding-confetti-piece;animation-timing-function:linear}@media(prefers-reduced-motion:reduce){.onboarding-confetti-x,.onboarding-confetti-y,.onboarding-confetti-piece{animation:none;opacity:0}}body:has(.onboarding-canvas){background-color:hsl(var(--brand-h) var(--brand-s) var(--brand-l))}.panel-shell,.surface-shell{border:1px solid hsl(var(--border-subtle));border-radius:var(--radius-xl);background:hsl(var(--surface-1));box-shadow:var(--shadow-sm)}.panel-shell-muted,.surface-shell-muted{background:hsl(var(--surface-2));box-shadow:var(--shadow-xs)}.panel-shell-subtle{border:1px solid hsl(var(--border-subtle));border-radius:var(--radius-lg);background:hsl(var(--surface-1));box-shadow:var(--shadow-xs)}.panel-shell-elevated{border:1px solid hsl(var(--border-default));border-radius:var(--radius-xl);background:hsl(var(--surface-1));box-shadow:var(--shadow-md)}.utility-chip,.floating-chip{display:inline-flex;align-items:center;gap:.5rem;border:1px solid hsl(var(--border-default));border-radius:var(--radius-pill);background:hsl(var(--surface-1));box-shadow:var(--shadow-xs)}.hairline{border-bottom:1px solid hsl(var(--border-subtle))}.mono-label{font-family:var(--font-mono),ui-monospace,monospace;font-size:11px;text-transform:uppercase;color:hsl(var(--text-tertiary))}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans),ui-sans-serif,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono),ui-monospace,SFMono-Regular,Menlo,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root,:host{--font-sans: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;--font-mono: var(--font-sans);--issue-marker-expand-duration: .52s;--surface-0: 0 0% 99%;--surface-1: 0 0% 100%;--surface-2: 144 8% 96%;--surface-3: 144 6% 93%;--surface-inset: 144 6% 95%;--overlay-backdrop: hsl(0 0% 0% / .24);--overlay-backdrop-strong: hsl(0 0% 0% / .48);--text-primary: 150 10% 12%;--text-secondary: 148 6% 36%;--text-tertiary: 145 5% 52%;--text-disabled: 145 4% 70%;--border-subtle: 144 8% 91%;--border-default: 144 6% 85%;--border-strong: 144 5% 72%;--grid-line: 0 0% 92%;--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / .04);--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / .06), 0 1px 2px -1px hsl(0 0% 0% / .06);--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / .06), 0 2px 4px -2px hsl(0 0% 0% / .04);--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / .06), 0 4px 6px -4px hsl(0 0% 0% / .04);--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / .06), 0 8px 10px -6px hsl(0 0% 0% / .04);--shadow-focus: 0 0 0 4px var(--brand-ring);--shadow-inset: inset 0 1px 2px 0 hsl(0 0% 0% / .04)}*{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}#issue-sticker-shadow-root{background-color:transparent;--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\\!visible{visibility:visible!important}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{left:0;right:0}.inset-x-1{left:.25rem;right:.25rem}.inset-y-0{top:0;bottom:0}.-bottom-px{bottom:-1px}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.bottom-6{bottom:1.5rem}.left-0{left:0}.left-1\\/2{left:50%}.left-2{left:.5rem}.left-4{left:1rem}.left-\\[50\\%\\]{left:50%}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-5{right:1.25rem}.right-6{right:1.5rem}.top-0{top:0}.top-1{top:.25rem}.top-1\\/2{top:50%}.top-2{top:.5rem}.top-3{top:.75rem}.top-4{top:1rem}.top-5{top:1.25rem}.top-\\[50\\%\\]{top:50%}.top-\\[calc\\(\\(3\\.5rem-1\\.75rem\\)\\/2\\)\\]{top:.875rem}.top-full{top:100%}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-\\[1000000\\]{z-index:1000000}.z-\\[1000003\\]{z-index:1000003}.z-\\[1000004\\]{z-index:1000004}.z-\\[1000005\\]{z-index:1000005}.z-\\[1000006\\]{z-index:1000006}.z-\\[1000007\\]{z-index:1000007}.z-\\[1000008\\]{z-index:1000008}.z-\\[1000010\\]{z-index:1000010}.z-\\[1000011\\]{z-index:1000011}.z-\\[10001\\]{z-index:10001}.z-\\[999999\\]{z-index:999999}.z-\\[9999\\]{z-index:9999}.m-0{margin:0}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-2\\.5{margin-top:.625rem;margin-bottom:.625rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mb-0\\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-5{margin-bottom:1.25rem}.ml-0\\.5{margin-left:.125rem}.ml-4{margin-left:1rem}.mr-1\\.5{margin-right:.375rem}.mt-0{margin-top:0}.mt-0\\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.\\!h-auto{height:auto!important}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-2{height:.5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-3\\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\\[1\\.4rem\\]{height:1.4rem}.h-\\[100vh\\]{height:100vh}.h-\\[18px\\]{height:18px}.h-\\[220px\\]{height:220px}.h-\\[22px\\]{height:22px}.h-\\[30px\\]{height:30px}.h-\\[min\\(36vh\\,320px\\)\\]{height:min(36vh,320px)}.h-\\[min\\(480px\\,calc\\(100vh-64px\\)\\)\\]{height:min(480px,calc(100vh - 64px))}.h-\\[min\\(54vh\\,520px\\)\\]{height:min(54vh,520px)}.h-\\[min\\(560px\\,calc\\(100vh-32px\\)\\)\\]{height:min(560px,calc(100vh - 32px))}.h-\\[var\\(--radix-select-trigger-height\\)\\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.max-h-24{max-height:6rem}.max-h-56{max-height:14rem}.max-h-96{max-height:24rem}.max-h-\\[150px\\]{max-height:150px}.max-h-\\[220px\\]{max-height:220px}.max-h-\\[320px\\]{max-height:320px}.max-h-\\[420px\\]{max-height:420px}.max-h-\\[90vh\\]{max-height:90vh}.max-h-\\[calc\\(100vh-3rem\\)\\]{max-height:calc(100vh - 3rem)}.max-h-\\[min\\(80vh\\,640px\\)\\]{max-height:min(80vh,640px)}.min-h-0{min-height:0px}.min-h-11{min-height:2.75rem}.min-h-\\[108px\\]{min-height:108px}.min-h-\\[120px\\]{min-height:120px}.min-h-\\[140px\\]{min-height:140px}.min-h-\\[220px\\]{min-height:220px}.w-0\\.5{width:.125rem}.w-1{width:.25rem}.w-1\\/2{width:50%}.w-10{width:2.5rem}.w-14{width:3.5rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\\[1\\.4rem\\]{width:1.4rem}.w-\\[18px\\]{width:18px}.w-\\[21rem\\]{width:21rem}.w-\\[22rem\\]{width:22rem}.w-\\[30px\\]{width:30px}.w-\\[38px\\]{width:38px}.w-\\[calc\\(100vw-32px\\)\\]{width:calc(100vw - 32px)}.w-\\[min\\(560px\\,calc\\(100vw-32px\\)\\)\\]{width:min(560px,calc(100vw - 32px))}.w-\\[var\\(--radix-popover-trigger-width\\)\\]{width:var(--radix-popover-trigger-width)}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.min-w-0{min-width:0px}.min-w-9{min-width:2.25rem}.min-w-\\[12rem\\]{min-width:12rem}.min-w-\\[200px\\]{min-width:200px}.min-w-\\[var\\(--radix-popover-trigger-width\\)\\]{min-width:var(--radix-popover-trigger-width)}.min-w-\\[var\\(--radix-select-trigger-width\\)\\]{min-width:var(--radix-select-trigger-width)}.max-w-8{max-width:2rem}.max-w-\\[120px\\]{max-width:120px}.max-w-\\[160px\\]{max-width:160px}.max-w-\\[240px\\]{max-width:240px}.max-w-\\[280px\\]{max-width:280px}.max-w-\\[28rem\\]{max-width:28rem}.max-w-\\[300px\\]{max-width:300px}.max-w-\\[360px\\]{max-width:360px}.max-w-\\[36rem\\]{max-width:36rem}.max-w-\\[400px\\]{max-width:400px}.max-w-\\[420px\\]{max-width:420px}.max-w-\\[428px\\]{max-width:428px}.max-w-\\[480px\\]{max-width:480px}.max-w-\\[62ch\\]{max-width:62ch}.max-w-\\[640px\\]{max-width:640px}.max-w-\\[70ch\\]{max-width:70ch}.max-w-\\[90vw\\]{max-width:90vw}.max-w-\\[960px\\]{max-width:960px}.max-w-\\[calc\\(100vw-24px\\)\\]{max-width:calc(100vw - 24px)}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.-translate-x-1{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-1\\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\\[-50\\%\\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\\[18px\\]{--tw-translate-x: 18px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\\[2px\\]{--tw-translate-x: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\\[-50\\%\\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes pulse-ring{0%,to{box-shadow:0 0 0 0 var(--brand-ring)}50%{box-shadow:0 0 0 8px transparent}}.animate-pulse-ring{animation:pulse-ring 1.8s var(--ease-in-out) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.resize{resize:both}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.content-center{align-content:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-3\\.5{gap:.875rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-line-subtle>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-divide-opacity, 1))}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.\\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\\[18px\\]{border-radius:18px}.rounded-\\[20px\\]{border-radius:20px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-b-md{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-t-0{border-top-width:0px}.border-\\[hsl\\(144_8\\%_91\\%\\)\\]{--tw-border-opacity: 1;border-color:hsl(144 8% 91% / var(--tw-border-opacity, 1))}.border-brand{--tw-border-opacity: 1;border-color:hsl(var(--brand-hsl) / var(--tw-border-opacity, 1))}.border-brand-border{border-color:var(--brand-border)}.border-brand\\/30{border-color:hsl(var(--brand-hsl) / .3)}.border-brand\\/40{border-color:hsl(var(--brand-hsl) / .4)}.border-danger\\/20{border-color:hsl(var(--danger) / .2)}.border-danger\\/30{border-color:hsl(var(--danger) / .3)}.border-info\\/20{border-color:hsl(var(--info) / .2)}.border-info\\/30{border-color:hsl(var(--info) / .3)}.border-line{--tw-border-opacity: 1;border-color:hsl(var(--border-default) / var(--tw-border-opacity, 1))}.border-line-strong{--tw-border-opacity: 1;border-color:hsl(var(--border-strong) / var(--tw-border-opacity, 1))}.border-line-subtle{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}.border-line-subtle\\/50{border-color:hsl(var(--border-subtle) / .5)}.border-line-subtle\\/90{border-color:hsl(var(--border-subtle) / .9)}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-success{--tw-border-opacity: 1;border-color:hsl(var(--success) / var(--tw-border-opacity, 1))}.border-success\\/20{border-color:hsl(var(--success) / .2)}.border-success\\/30{border-color:hsl(var(--success) / .3)}.border-text-primary{--tw-border-opacity: 1;border-color:hsl(var(--text-primary) / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-warning\\/20{border-color:hsl(var(--warning) / .2)}.border-warning\\/30{border-color:hsl(var(--warning) / .3)}.border-white\\/70{border-color:#ffffffb3}.border-white\\/80{border-color:#fffc}.border-white\\/90{border-color:#ffffffe6}.border-l-brand{--tw-border-opacity: 1;border-left-color:hsl(var(--brand-hsl) / var(--tw-border-opacity, 1))}.\\!bg-success-surface{background-color:hsl(var(--success-surface))!important}.bg-\\[var\\(--overlay-backdrop-strong\\)\\]{background-color:var(--overlay-backdrop-strong)}.bg-black\\/10{background-color:#0000001a}.bg-black\\/40{background-color:#0006}.bg-black\\/80{background-color:#000c}.bg-brand{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.bg-brand-subtle{background-color:var(--brand-subtle)}.bg-brand\\/10{background-color:hsl(var(--brand-hsl) / .1)}.bg-brand\\/5{background-color:hsl(var(--brand-hsl) / .05)}.bg-danger-subtle{background-color:hsl(var(--danger-subtle))}.bg-danger\\/10{background-color:hsl(var(--danger) / .1)}.bg-info-subtle{background-color:hsl(var(--info-subtle))}.bg-line{--tw-bg-opacity: 1;background-color:hsl(var(--border-default) / var(--tw-bg-opacity, 1))}.bg-line-subtle{--tw-bg-opacity: 1;background-color:hsl(var(--border-subtle) / var(--tw-bg-opacity, 1))}.bg-success{--tw-bg-opacity: 1;background-color:hsl(var(--success) / var(--tw-bg-opacity, 1))}.bg-success-subtle{background-color:hsl(var(--success-subtle))}.bg-success-surface{background-color:hsl(var(--success-surface))}.bg-surface-0{--tw-bg-opacity: 1;background-color:hsl(var(--surface-0) / var(--tw-bg-opacity, 1))}.bg-surface-1{--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.bg-surface-2{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.bg-surface-3{--tw-bg-opacity: 1;background-color:hsl(var(--surface-3) / var(--tw-bg-opacity, 1))}.bg-surface-inset{--tw-bg-opacity: 1;background-color:hsl(var(--surface-inset) / var(--tw-bg-opacity, 1))}.bg-text-primary{--tw-bg-opacity: 1;background-color:hsl(var(--text-primary) / var(--tw-bg-opacity, 1))}.bg-text-tertiary{--tw-bg-opacity: 1;background-color:hsl(var(--text-tertiary) / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-warning-subtle{background-color:hsl(var(--warning-subtle))}.bg-warning\\/10{background-color:hsl(var(--warning) / .1)}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\\/10{background-color:#ffffff1a}.fill-text-primary{fill:hsl(var(--text-primary) / 1)}.stroke-\\[3\\]{stroke-width:3}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.\\!p-0{padding:0!important}.p-0{padding:0}.p-0\\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-3\\.5{padding:.875rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.p-8{padding:2rem}.p-\\[18px\\]{padding:18px}.px-0{padding-left:0;padding-right:0}.px-1\\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-9{padding-left:2.25rem;padding-right:2.25rem}.py-0\\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-3\\.5{padding-top:.875rem;padding-bottom:.875rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-1{padding-bottom:.25rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-8{padding-left:2rem}.pr-10{padding-right:2.5rem}.pr-3{padding-right:.75rem}.pr-4{padding-right:1rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2\\.5{padding-top:.625rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.font-display{font-family:var(--font-display),ui-sans-serif,system-ui,sans-serif}.font-mono{font-family:var(--font-mono),ui-monospace,SFMono-Regular,Menlo,monospace}.font-sans{font-family:var(--font-sans),ui-sans-serif,system-ui,sans-serif}.text-2xs{font-size:10.5px;line-height:14px}.text-\\[0\\.72rem\\]{font-size:.72rem}.text-\\[1\\.45rem\\]{font-size:1.45rem}.text-\\[1\\.75rem\\]{font-size:1.75rem}.text-\\[10px\\]{font-size:10px}.text-base{font-size:14px;line-height:21px}.text-lg{font-size:17px;line-height:25px}.text-sm{font-size:13px;line-height:19px}.text-xl{font-size:20px;line-height:29px}.text-xs{font-size:12px;line-height:16px}.font-black{font-weight:900}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.italic{font-style:italic}.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)}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-8{line-height:2rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.text-\\[hsl\\(145_5\\%_42\\%\\)\\]{--tw-text-opacity: 1;color:hsl(145 5% 42% / var(--tw-text-opacity, 1))}.text-brand{--tw-text-opacity: 1;color:hsl(var(--brand-hsl) / var(--tw-text-opacity, 1))}.text-brand-fg{color:var(--brand-fg)}.text-brand\\/50{color:hsl(var(--brand-hsl) / .5)}.text-danger{--tw-text-opacity: 1;color:hsl(var(--danger) / var(--tw-text-opacity, 1))}.text-danger\\/80{color:hsl(var(--danger) / .8)}.text-info{--tw-text-opacity: 1;color:hsl(var(--info) / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-success{--tw-text-opacity: 1;color:hsl(var(--success) / var(--tw-text-opacity, 1))}.text-text-disabled{--tw-text-opacity: 1;color:hsl(var(--text-disabled) / var(--tw-text-opacity, 1))}.text-text-inverse{--tw-text-opacity: 1;color:hsl(var(--text-inverse) / var(--tw-text-opacity, 1))}.text-text-primary{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.text-text-secondary{--tw-text-opacity: 1;color:hsl(var(--text-secondary) / var(--tw-text-opacity, 1))}.text-text-tertiary{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.text-transparent{color:transparent}.text-warning{--tw-text-opacity: 1;color:hsl(var(--warning) / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\\/90{color:#ffffffe6}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.accent-brand{accent-color:hsl(var(--brand-hsl) / 1)}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.\\!shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\\[0_24px_70px_-28px_rgba\\(16\\,24\\,18\\,0\\.45\\)\\]{--tw-shadow: 0 24px 70px -28px rgba(16,24,18,.45);--tw-shadow-colored: 0 24px 70px -28px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: var(--shadow-lg);--tw-shadow-colored: var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: var(--shadow-md);--tw-shadow-colored: var(--shadow-md);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: var(--shadow-sm);--tw-shadow-colored: var(--shadow-sm);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: var(--shadow-xl);--tw-shadow-colored: var(--shadow-xl);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xs{--tw-shadow: var(--shadow-xs);--tw-shadow-colored: var(--shadow-xs);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.outline-2{outline-width:2px}.outline-offset-0{outline-offset:0px}.outline-transparent{outline-color:transparent}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-4{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-brand{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--brand-hsl) / var(--tw-ring-opacity, 1))}.ring-brand-subtle{--tw-ring-color: var(--brand-subtle)}.blur{--tw-blur: blur(8px);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)}.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)}.backdrop-blur-\\[2px\\]{--tw-backdrop-blur: blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,border-color\\,color\\,box-shadow\\]{transition-property:background-color,border-color,color,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\,border-color\\,box-shadow\\,opacity\\]{transition-property:background-color,color,border-color,box-shadow,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\,border-color\\,box-shadow\\]{transition-property:background-color,color,border-color,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\,box-shadow\\]{transition-property:background-color,color,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\]{transition-property:background-color,color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[border-color\\,box-shadow\\,background-color\\]{transition-property:border-color,box-shadow,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[border-color\\,outline-color\\,box-shadow\\,background-color\\,transform\\]{transition-property:border-color,outline-color,box-shadow,background-color,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[max-width\\,box-shadow\\,background-color\\,border-color\\,transform\\,opacity\\]{transition-property:max-width,box-shadow,background-color,border-color,transform,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[max-width\\]{transition-property:max-width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[opacity\\,transform\\]{transition-property:opacity,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.duration-\\[var\\(--issue-marker-expand-duration\\)\\]{transition-duration:var(--issue-marker-expand-duration)}.duration-fast{transition-duration:var(--duration-fast)}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:var(--ease-in-out)}.ease-out{transition-timing-function:var(--ease-out)}@keyframes float-gentle{0%,to{transform:translateY(0)}50%{transform:translateY(-2px)}}@keyframes toast-slide{0%{opacity:0;transform:translateY(-14px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes gradient-shift{0%,to{background-position:0% 50%}50%{background-position:100% 50%}}.issue-overlay-shell{border:1px solid hsl(var(--border-subtle));border-radius:var(--radius-lg);background:hsl(var(--surface-1));box-shadow:var(--shadow-md)}.issue-marker-breathe{animation:float-gentle 4.8s var(--ease-in-out) infinite}.issue-marker-breathe:hover,.issue-marker-breathe:focus-visible,.issue-marker-breathe:focus-within{animation-play-state:paused}.marker\\:text-text-tertiary *::marker{color:hsl(var(--text-tertiary))}.marker\\:text-text-tertiary::marker{color:hsl(var(--text-tertiary))}.file\\:border-0::file-selector-button{border-width:0px}.file\\:bg-transparent::file-selector-button{background-color:transparent}.file\\:text-sm::file-selector-button{font-size:13px;line-height:19px}.file\\:font-medium::file-selector-button{font-weight:500}.file\\:text-text-primary::file-selector-button{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.placeholder\\:text-text-tertiary::-moz-placeholder{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.placeholder\\:text-text-tertiary::placeholder{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.focus-within\\:z-\\[10001\\]:focus-within{z-index:10001}.hover\\:z-\\[10001\\]:hover{z-index:10001}.hover\\:max-w-\\[160px\\]:hover{max-width:160px}.hover\\:max-w-\\[480px\\]:hover{max-width:480px}.hover\\:border-line:hover{--tw-border-opacity: 1;border-color:hsl(var(--border-default) / var(--tw-border-opacity, 1))}.hover\\:border-line-strong:hover{--tw-border-opacity: 1;border-color:hsl(var(--border-strong) / var(--tw-border-opacity, 1))}.hover\\:border-line-subtle:hover{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}.hover\\:bg-\\[hsl\\(144_8\\%_96\\%\\)\\]:hover{--tw-bg-opacity: 1;background-color:hsl(144 8% 96% / var(--tw-bg-opacity, 1))}.hover\\:bg-blue-500:hover{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.hover\\:bg-brand-hover:hover{background-color:var(--brand-hover)}.hover\\:bg-brand\\/40:hover{background-color:hsl(var(--brand-hsl) / .4)}.hover\\:bg-danger-subtle:hover{background-color:hsl(var(--danger-subtle))}.hover\\:bg-danger\\/10:hover{background-color:hsl(var(--danger) / .1)}.hover\\:bg-slate-100:hover{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.hover\\:bg-slate-50:hover{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.hover\\:bg-surface-2:hover{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.hover\\:bg-surface-2\\/60:hover{background-color:hsl(var(--surface-2) / .6)}.hover\\:bg-surface-3:hover{--tw-bg-opacity: 1;background-color:hsl(var(--surface-3) / var(--tw-bg-opacity, 1))}.hover\\:bg-surface-inset:hover{--tw-bg-opacity: 1;background-color:hsl(var(--surface-inset) / var(--tw-bg-opacity, 1))}.hover\\:bg-transparent:hover{background-color:transparent}.hover\\:bg-white\\/20:hover{background-color:#fff3}.hover\\:text-\\[hsl\\(150_10\\%_12\\%\\)\\]:hover{--tw-text-opacity: 1;color:hsl(150 10% 12% / var(--tw-text-opacity, 1))}.hover\\:text-brand-hover:hover{color:var(--brand-hover)}.hover\\:text-danger:hover{--tw-text-opacity: 1;color:hsl(var(--danger) / var(--tw-text-opacity, 1))}.hover\\:text-slate-900:hover{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.hover\\:text-text-primary:hover{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.hover\\:text-text-secondary:hover{--tw-text-opacity: 1;color:hsl(var(--text-secondary) / var(--tw-text-opacity, 1))}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-90:hover{opacity:.9}.hover\\:shadow-xl:hover{--tw-shadow: var(--shadow-xl);--tw-shadow-colored: var(--shadow-xl);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\\:border-brand:focus{--tw-border-opacity: 1;border-color:hsl(var(--brand-hsl) / var(--tw-border-opacity, 1))}.focus\\:bg-surface-2:focus{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.focus\\:text-text-primary:focus{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:max-w-\\[160px\\]:focus-visible{max-width:160px}.focus-visible\\:max-w-\\[480px\\]:focus-visible{max-width:480px}.focus-visible\\:border-line-focus:focus-visible{--tw-border-opacity: 1;border-color:hsl(var(--border-focus) / var(--tw-border-opacity, 1))}.focus-visible\\:border-transparent:focus-visible{border-color:transparent}.focus-visible\\:bg-slate-50:focus-visible{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.focus-visible\\:bg-surface-1:focus-visible{--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.focus-visible\\:bg-surface-2:focus-visible{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.focus-visible\\:text-text-primary:focus-visible{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.focus-visible\\:shadow-focus:focus-visible{--tw-shadow: var(--shadow-focus);--tw-shadow-colored: var(--shadow-focus);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus-visible\\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:outline-line-focus:focus-visible{outline-color:hsl(var(--border-focus) / 1)}.focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-4:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-brand-subtle:focus-visible{--tw-ring-color: var(--brand-subtle)}.focus-visible\\:ring-white\\/40:focus-visible{--tw-ring-color: rgb(255 255 255 / .4)}.active\\:bg-brand-active:active{background-color:var(--brand-active)}.active\\:bg-brand\\/60:active{background-color:hsl(var(--brand-hsl) / .6)}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\\:opacity-100{opacity:1}.group:focus-visible .group-focus-visible\\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:focus-visible .group-focus-visible\\:opacity-100{opacity:1}.group.toaster .group-\\[\\.toaster\\]\\:isolate{isolation:isolate}.group.toast .group-\\[\\.toast\\]\\:rounded-md,.group.toaster .group-\\[\\.toaster\\]\\:rounded-md{border-radius:var(--radius-md)}.group.toaster .group-\\[\\.toaster\\]\\:border{border-width:1px}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-danger\\/30{border-color:hsl(var(--danger) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-info\\/30{border-color:hsl(var(--info) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-success\\/30{border-color:hsl(var(--success) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-warning\\/30{border-color:hsl(var(--warning) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:border-line-subtle{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}.group.toast .group-\\[\\.toast\\]\\:bg-brand{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.group.toast .group-\\[\\.toast\\]\\:bg-surface-2{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-danger-subtle{background-color:hsl(var(--danger-subtle))!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-info-subtle{background-color:hsl(var(--info-subtle))!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-success-surface{background-color:hsl(var(--success-surface))!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-warning-subtle{background-color:hsl(var(--warning-subtle))!important}.group.toaster .group-\\[\\.toaster\\]\\:bg-surface-1{--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:px-4{padding-left:1rem;padding-right:1rem}.group.toaster .group-\\[\\.toaster\\]\\:py-3{padding-top:.75rem;padding-bottom:.75rem}.group.toast .group-\\[\\.toast\\]\\:text-sm{font-size:13px;line-height:19px}.group.toast .group-\\[\\.toast\\]\\:text-xs{font-size:12px;line-height:16px}.group.toast .group-\\[\\.toast\\]\\:font-medium{font-weight:500}.group.toast .group-\\[\\.toast\\]\\:text-brand-fg{color:var(--brand-fg)}.group.toast .group-\\[\\.toast\\]\\:text-text-primary{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.group.toast .group-\\[\\.toast\\]\\:text-text-secondary{--tw-text-opacity: 1;color:hsl(var(--text-secondary) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:text-text-primary{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:shadow-sm{--tw-shadow: var(--shadow-sm);--tw-shadow-colored: var(--shadow-sm);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.group.toaster .group-\\[\\.toaster\\]\\:before\\:absolute:before{content:var(--tw-content);position:absolute}.group.toaster .group-\\[\\.toaster\\]\\:before\\:inset-0:before{content:var(--tw-content);top:0;right:0;bottom:0;left:0}.group.toaster .group-\\[\\.toaster\\]\\:before\\:-z-10:before{content:var(--tw-content);z-index:-10}.group.toaster .group-\\[\\.toaster\\]\\:before\\:rounded-md:before{content:var(--tw-content);border-radius:var(--radius-md)}.group.toaster .group-\\[\\.toaster\\]\\:before\\:bg-surface-1:before{content:var(--tw-content);--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:before\\:content-\\[\\'\\'\\]:before{--tw-content: "";content:var(--tw-content)}.peer:focus-visible~.peer-focus-visible\\:shadow-focus{--tw-shadow: var(--shadow-focus);--tw-shadow-colored: var(--shadow-focus);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.peer:disabled~.peer-disabled\\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\\:opacity-60{opacity:.6}.aria-disabled\\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\\:opacity-40[aria-disabled=true]{opacity:.4}.data-\\[disabled\\]\\:pointer-events-none[data-disabled]{pointer-events:none}@keyframes dialog-out{0%{opacity:1;transform:translate(-50%,-50%) scale(1)}to{opacity:0;transform:translate(-50%,calc(-50% + 8px)) scale(.985)}}.data-\\[state\\=closed\\]\\:animate-dialog-out[data-state=closed]{animation:dialog-out var(--duration-out) var(--ease-out) forwards}@keyframes fade-out{0%{opacity:1}to{opacity:0}}.data-\\[state\\=closed\\]\\:animate-fade-out[data-state=closed]{animation:fade-out var(--duration-out) var(--ease-out) forwards}@keyframes scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.97)}}.data-\\[state\\=closed\\]\\:animate-scale-out[data-state=closed]{animation:scale-out var(--duration-out) var(--ease-out) forwards}@keyframes sheet-out-left{0%{transform:translate(0)}to{transform:translate(-100%);opacity:.6}}.data-\\[state\\=closed\\]\\:animate-sheet-out-left[data-state=closed]{animation:sheet-out-left var(--duration-base) var(--ease-out) forwards}@keyframes sheet-out-right{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:.6}}.data-\\[state\\=closed\\]\\:animate-sheet-out-right[data-state=closed]{animation:sheet-out-right var(--duration-base) var(--ease-out) forwards}.data-\\[state\\=delayed-open\\]\\:animate-scale-in[data-state=delayed-open]{animation:scale-in var(--duration-base) var(--ease-out) forwards}@keyframes dialog-in{0%{opacity:0;transform:translate(-50%,calc(-50% + 12px)) scale(.985)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.data-\\[state\\=open\\]\\:animate-dialog-in[data-state=open]{animation:dialog-in var(--duration-base) var(--ease-out) forwards}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.data-\\[state\\=open\\]\\:animate-fade-in[data-state=open]{animation:fade-in var(--duration-base) var(--ease-out) forwards}@keyframes scale-in{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}.data-\\[state\\=open\\]\\:animate-scale-in[data-state=open]{animation:scale-in var(--duration-base) var(--ease-out) forwards}@keyframes sheet-in-left{0%{transform:translate(-100%);opacity:.6}to{transform:translate(0);opacity:1}}.data-\\[state\\=open\\]\\:animate-sheet-in-left[data-state=open]{animation:sheet-in-left var(--duration-base) var(--ease-out) forwards}@keyframes sheet-in-right{0%{transform:translate(100%);opacity:.6}to{transform:translate(0)}}.data-\\[state\\=open\\]\\:animate-sheet-in-right[data-state=open]{animation:sheet-in-right var(--duration-base) var(--ease-out) forwards}.data-\\[range-end\\=true\\]\\:rounded-md[data-range-end=true]{border-radius:var(--radius-md)}.data-\\[range-middle\\=true\\]\\:rounded-none[data-range-middle=true]{border-radius:0}.data-\\[range-start\\=true\\]\\:rounded-md[data-range-start=true]{border-radius:var(--radius-md)}.data-\\[state\\=open\\]\\:border-line-focus[data-state=open]{--tw-border-opacity: 1;border-color:hsl(var(--border-focus) / var(--tw-border-opacity, 1))}.data-\\[highlighted\\]\\:bg-surface-2[data-highlighted]{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.data-\\[range-end\\=true\\]\\:bg-brand[data-range-end=true]{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.data-\\[range-middle\\=true\\]\\:bg-transparent[data-range-middle=true]{background-color:transparent}.data-\\[range-start\\=true\\]\\:bg-brand[data-range-start=true],.data-\\[selected-single\\=true\\]\\:bg-brand[data-selected-single=true]{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.data-\\[state\\=selected\\]\\:bg-brand-subtle[data-state=selected]{background-color:var(--brand-subtle)}.data-\\[today\\=true\\]\\:font-semibold[data-today=true]{font-weight:600}.data-\\[highlighted\\]\\:text-text-primary[data-highlighted]{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.data-\\[placeholder\\]\\:text-text-tertiary[data-placeholder]{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.data-\\[range-end\\=true\\]\\:text-brand-fg[data-range-end=true]{color:var(--brand-fg)}.data-\\[range-middle\\=true\\]\\:text-text-primary[data-range-middle=true]{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.data-\\[range-start\\=true\\]\\:text-brand-fg[data-range-start=true],.data-\\[selected-single\\=true\\]\\:text-brand-fg[data-selected-single=true]{color:var(--brand-fg)}.data-\\[state\\=active\\]\\:text-text-primary[data-state=active],.data-\\[state\\=checked\\]\\:text-text-primary[data-state=checked]{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.data-\\[today\\=true\\]\\:text-brand[data-today=true]{--tw-text-opacity: 1;color:hsl(var(--brand-hsl) / var(--tw-text-opacity, 1))}.data-\\[disabled\\]\\:opacity-50[data-disabled]{opacity:.5}.data-\\[state\\=open\\]\\:shadow-focus[data-state=open]{--tw-shadow: var(--shadow-focus);--tw-shadow-colored: var(--shadow-focus);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\\[range-end\\=true\\]\\:hover\\:bg-brand-hover:hover[data-range-end=true],.data-\\[range-start\\=true\\]\\:hover\\:bg-brand-hover:hover[data-range-start=true],.data-\\[selected-single\\=true\\]\\:hover\\:bg-brand-hover:hover[data-selected-single=true]{background-color:var(--brand-hover)}.data-\\[range-end\\=true\\]\\:hover\\:text-brand-fg:hover[data-range-end=true],.data-\\[range-start\\=true\\]\\:hover\\:text-brand-fg:hover[data-range-start=true],.data-\\[selected-single\\=true\\]\\:hover\\:text-brand-fg:hover[data-selected-single=true]{color:var(--brand-fg)}@media(prefers-reduced-motion:reduce){.motion-reduce\\:animate-none{animation:none}}@media(min-width:640px){.sm\\:flex-row{flex-direction:row}.sm\\:items-start{align-items:flex-start}.sm\\:items-center{align-items:center}.sm\\:justify-end{justify-content:flex-end}.sm\\:justify-between{justify-content:space-between}.sm\\:gap-2\\.5{gap:.625rem}.sm\\:p-5{padding:1.25rem}.sm\\:p-6{padding:1.5rem}.sm\\:text-2xl{font-size:26px;line-height:34px}.sm\\:text-\\[2\\.1rem\\]{font-size:2.1rem}}@media(min-width:768px){.md\\:flex{display:flex}.md\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\\:grid-cols-\\[minmax\\(0\\,1fr\\)_minmax\\(260px\\,340px\\)\\]{grid-template-columns:minmax(0,1fr) minmax(260px,340px)}}.\\[\\&\\>\\*\\:not\\(summary\\)\\]\\:pl-4>*:not(summary){padding-left:1rem}.\\[\\&\\>span\\]\\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\\[\\&\\>tr\\]\\:last\\:border-b-0:last-child>tr{border-bottom-width:0px}.\\[\\&\\[data-state\\=open\\]\\>span\\[data-chevron\\]\\]\\:rotate-180[data-state=open]>span[data-chevron]{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-danger [data-icon]{--tw-text-opacity: 1;color:hsl(var(--danger) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-info [data-icon]{--tw-text-opacity: 1;color:hsl(var(--info) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-success [data-icon]{--tw-text-opacity: 1;color:hsl(var(--success) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-warning [data-icon]{--tw-text-opacity: 1;color:hsl(var(--warning) / var(--tw-text-opacity, 1))}.\\[\\&_tr\\]\\:border-b tr{border-bottom-width:1px}.\\[\\&_tr\\]\\:border-line-subtle tr{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}`;
38082
+ const globalsCSS = `:root,:host{color-scheme:light;--brand-h: 150;--brand-s: 100%;--brand-l: 34%;--brand-hsl: var(--brand-h) var(--brand-s) var(--brand-l);--brand: hsl(var(--brand-hsl));--brand-hover: hsl(var(--brand-h) calc(var(--brand-s) + 3%) calc(var(--brand-l) - 4%));--brand-active: hsl(var(--brand-h) calc(var(--brand-s) + 2%) calc(var(--brand-l) - 8%));--brand-subtle: hsl(var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .14);--brand-border: hsl(var(--brand-h) calc(var(--brand-s) + 8%) calc(var(--brand-l) + 8%) / .34);--brand-fg: hsl(0 0% 100%);--brand-ring: hsl(var(--brand-h) calc(var(--brand-s) + 12%) calc(var(--brand-l) + 10%) / .22);--font-sans: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;--font-display: var(--font-sans);--font-mono: var(--font-sans);--surface-0: 0 0% 99%;--surface-1: 0 0% 100%;--surface-2: 144 8% 96%;--surface-3: 144 6% 93%;--surface-inset: 144 6% 95%;--overlay-backdrop: hsl(0 0% 0% / .24);--overlay-backdrop-strong: hsl(0 0% 0% / .48);--text-primary: 150 10% 12%;--text-secondary: 148 6% 36%;--text-tertiary: 145 5% 42%;--text-disabled: 145 4% 70%;--text-inverse: 0 0% 100%;--border-subtle: 144 8% 91%;--border-default: 144 6% 85%;--border-strong: 144 5% 72%;--border-focus: var(--brand-h) var(--brand-s) var(--brand-l);--success: var(--brand-h) var(--brand-s) var(--brand-l);--success-subtle: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .14;--success-surface: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .24;--warning: 34 82% 52%;--warning-subtle: 34 82% 52% / .14;--danger: 3 68% 56%;--danger-subtle: 3 68% 56% / .12;--info: 202 52% 44%;--info-subtle: 202 52% 44% / .12;--accent-terra: 13 52% 47%;--accent-terra-subtle: 13 52% 47% / .1;--accent-terra-deep: 13 48% 44%;--accent-blue: 213 86% 56%;--accent-blue-subtle: 213 92% 56% / .12;--accent-blue-deep: 216 78% 40%;--accent-blue-border: 213 86% 62% / .36;--accent-cream: 38 52% 88%;--accent-cream-warm: 40 56% 95%;--accent-cream-deep: 38 48% 82%;--accent-highlight: 55 96% 70%;--accent-ink: 32 13% 11%;--radius-xs: 4px;--radius-sm: 8px;--radius-md: 12px;--radius-lg: 16px;--radius-xl: 20px;--radius-2xl: 24px;--radius-pill: 9999px;--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / .04);--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / .06), 0 1px 2px -1px hsl(0 0% 0% / .06);--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / .06), 0 2px 4px -2px hsl(0 0% 0% / .04);--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / .06), 0 4px 6px -4px hsl(0 0% 0% / .04);--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / .06), 0 8px 10px -6px hsl(0 0% 0% / .04);--shadow-focus: 0 0 0 3px var(--brand-ring);--shadow-inset: inset 0 1px 2px 0 hsl(0 0% 0% / .04);--shadow-brand: 0 2px 8px hsl(var(--brand-h) calc(var(--brand-s) - 60%) calc(var(--brand-l) - 14%) / .24), 0 6px 20px hsl(var(--brand-h) calc(var(--brand-s) - 70%) calc(var(--brand-l) - 19%) / .16);--duration-instant: 90ms;--duration-fast: .16s;--duration-base: .26s;--duration-out: .18s;--duration-slow: .36s;--ease-out: cubic-bezier(.23, 1, .32, 1);--ease-in-out: cubic-bezier(.45, 0, .15, 1);--ease-spring: cubic-bezier(.18, .94, .32, 1.08);--grid-line: 0 0% 92%}.dark,:host(.dark){color-scheme:dark;--brand-l: 34%;--brand-fg: hsl(0 0% 100%);--surface-0: 150 8% 7%;--surface-1: 150 6% 10%;--surface-2: 150 5% 14%;--surface-3: 150 4% 18%;--surface-inset: 150 6% 6%;--overlay-backdrop: hsl(0 0% 0% / .56);--overlay-backdrop-strong: hsl(0 0% 0% / .8);--text-primary: 40 16% 93%;--text-secondary: 36 8% 68%;--text-tertiary: 34 6% 50%;--text-disabled: 30 5% 34%;--text-inverse: 150 8% 10%;--border-subtle: 150 6% 16%;--border-default: 150 5% 22%;--border-strong: 150 4% 34%;--success: var(--brand-h) var(--brand-s) var(--brand-l);--success-subtle: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .14;--success-surface: var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 14%) / .24;--warning: 34 82% 62%;--danger: 2 70% 64%;--info: 202 54% 62%;--accent-terra: 13 56% 62%;--accent-terra-subtle: 13 56% 62% / .14;--accent-terra-deep: 13 52% 56%;--accent-blue: 210 92% 68%;--accent-blue-subtle: 210 92% 68% / .18;--accent-blue-deep: 209 100% 78%;--accent-blue-border: 210 92% 72% / .44;--accent-cream: 38 30% 26%;--accent-cream-warm: 38 22% 18%;--accent-cream-deep: 38 26% 32%;--accent-highlight: 55 96% 70%;--accent-ink: 32 13% 8%;--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / .2);--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / .3), 0 1px 2px -1px hsl(0 0% 0% / .24);--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / .34), 0 2px 4px -2px hsl(0 0% 0% / .2);--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / .38), 0 4px 6px -4px hsl(0 0% 0% / .24);--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / .44), 0 8px 10px -6px hsl(0 0% 0% / .28);--shadow-inset: inset 0 1px 2px 0 hsl(0 0% 0% / .16);--shadow-brand: 0 2px 8px hsl(var(--brand-h) calc(var(--brand-s) - 60%) calc(var(--brand-l) - 24%) / .44), 0 6px 20px hsl(0 0% 0% / .32);--grid-line: 150 6% 14%}*{border-color:hsl(var(--border-default))}html{font-family:var(--font-sans),ui-sans-serif,system-ui,-apple-system,sans-serif;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-feature-settings:"cv11","ss01","ss03";background-color:hsl(var(--surface-0))}body{margin:0;min-height:100vh;color:hsl(var(--text-primary));background-color:hsl(var(--surface-0))}::-moz-selection{background-color:hsl(var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 16%) / .22);color:hsl(var(--text-primary))}::selection{background-color:hsl(var(--brand-h) calc(var(--brand-s) + 6%) calc(var(--brand-l) + 16%) / .22);color:hsl(var(--text-primary))}code,kbd,samp,pre{font-family:var(--font-mono),ui-monospace,SFMono-Regular,Menlo,monospace;font-feature-settings:"ss01","ss02","cv11"}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:hsl(var(--border-strong) / .52);border-radius:var(--radius-pill);border:2px solid transparent;background-clip:padding-box}::-webkit-scrollbar-thumb:hover{background:hsl(var(--border-strong) / .9);background-clip:padding-box;border:2px solid transparent}.app-canvas,.grid-canvas{background-color:hsl(var(--surface-0))}.onboarding-canvas{--surface-0: var(--brand-h) var(--brand-s) var(--brand-l);--surface-1: 0 0% 100%;--surface-2: var(--brand-h) 62% 28%;--surface-3: var(--brand-h) 60% 25%;--surface-inset: var(--brand-h) 62% 28%;--text-primary: 0 0% 100%;--text-secondary: var(--brand-h) 46% 90%;--text-tertiary: var(--brand-h) 34% 84%;--text-disabled: var(--brand-h) 20% 72%;--border-subtle: var(--brand-h) 44% 52%;--border-default: var(--brand-h) 40% 58%;--border-strong: var(--brand-h) 36% 70%;--border-focus: 0 0% 100%;--brand-hsl: 0 0% 100%;--brand: hsl(var(--brand-hsl));--brand-hover: hsl(var(--brand-h) 24% 94%);--brand-active: hsl(var(--brand-h) 20% 88%);--brand-fg: hsl(var(--brand-h) var(--brand-s) 24%);--brand-ring: hsl(0 0% 100% / .4);--danger: 6 96% 86%;--danger-subtle: 6 96% 86% / .18;--warning: 42 96% 82%;--warning-subtle: 42 96% 82% / .18}.onboarding-canvas .bg-surface-1,.onboarding-canvas input,.onboarding-canvas textarea,.onboarding-canvas [role=combobox]{--text-primary: 150 10% 12%;--text-secondary: 148 6% 36%;--text-tertiary: 145 5% 42%;--surface-2: 144 8% 96%;--surface-inset: 144 6% 95%;--border-subtle: 144 8% 91%;--border-default: 144 6% 85%;--brand-hsl: var(--brand-h) var(--brand-s) var(--brand-l);--brand: hsl(var(--brand-hsl));--brand-hover: hsl(var(--brand-h) calc(var(--brand-s) + 3%) calc(var(--brand-l) - 4%));--brand-active: hsl(var(--brand-h) calc(var(--brand-s) + 2%) calc(var(--brand-l) - 8%));--brand-fg: hsl(0 0% 100%);--brand-ring: hsl(var(--brand-h) calc(var(--brand-s) + 12%) calc(var(--brand-l) + 10%) / .22)}@keyframes onboarding-step-in{0%{opacity:0;transform:translate(96px)}to{opacity:1;transform:translate(0)}}.onboarding-step-in{animation:onboarding-step-in var(--duration-slow) var(--ease-out) forwards}@keyframes onboarding-enter-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.onboarding-enter{position:fixed;top:0;right:0;bottom:0;left:0;overflow-x:hidden;overflow-y:auto;animation:onboarding-enter-up var(--duration-base) var(--ease-out) forwards}@keyframes onboarding-confetti-x{0%{transform:translate(0)}to{transform:translate(var(--confetti-x))}}@keyframes onboarding-confetti-y{0%{transform:translateY(0);animation-timing-function:cubic-bezier(.12,.66,.32,1)}42%{transform:translateY(var(--confetti-lift));animation-timing-function:cubic-bezier(.58,0,.86,.32)}to{transform:translateY(var(--confetti-drop))}}@keyframes onboarding-confetti-piece{0%{opacity:0;transform:scale(.7) rotate(0)}6%{opacity:1}72%{opacity:1}to{opacity:0;transform:scale(1) rotate(var(--confetti-spin))}}.onboarding-confetti-x,.onboarding-confetti-y,.onboarding-confetti-piece{--confetti-duration: 1.9s;animation-duration:var(--confetti-duration);animation-delay:var(--confetti-delay, 0ms);animation-fill-mode:both}.onboarding-confetti-x{animation-name:onboarding-confetti-x;animation-timing-function:cubic-bezier(.08,.62,.3,1)}.onboarding-confetti-y{animation-name:onboarding-confetti-y;animation-timing-function:linear}.onboarding-confetti-piece{width:var(--confetti-size);height:var(--confetti-size);border-radius:var(--radius-pill) var(--radius-xs) var(--radius-pill) var(--radius-pill);animation-name:onboarding-confetti-piece;animation-timing-function:linear}@media(prefers-reduced-motion:reduce){.onboarding-confetti-x,.onboarding-confetti-y,.onboarding-confetti-piece{animation:none;opacity:0}}body:has(.onboarding-canvas){background-color:hsl(var(--brand-h) var(--brand-s) var(--brand-l))}.panel-shell,.surface-shell{border:1px solid hsl(var(--border-subtle));border-radius:var(--radius-xl);background:hsl(var(--surface-1));box-shadow:var(--shadow-sm)}.panel-shell-muted,.surface-shell-muted{background:hsl(var(--surface-2));box-shadow:var(--shadow-xs)}.panel-shell-subtle{border:1px solid hsl(var(--border-subtle));border-radius:var(--radius-lg);background:hsl(var(--surface-1));box-shadow:var(--shadow-xs)}.panel-shell-elevated{border:1px solid hsl(var(--border-default));border-radius:var(--radius-xl);background:hsl(var(--surface-1));box-shadow:var(--shadow-md)}.utility-chip,.floating-chip{display:inline-flex;align-items:center;gap:.5rem;border:1px solid hsl(var(--border-default));border-radius:var(--radius-pill);background:hsl(var(--surface-1));box-shadow:var(--shadow-xs)}.hairline{border-bottom:1px solid hsl(var(--border-subtle))}.mono-label{font-family:var(--font-mono),ui-monospace,monospace;font-size:11px;text-transform:uppercase;color:hsl(var(--text-tertiary))}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans),ui-sans-serif,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono),ui-monospace,SFMono-Regular,Menlo,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root,:host{--font-sans: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;--font-mono: var(--font-sans);--issue-marker-expand-duration: .52s;--surface-0: 0 0% 99%;--surface-1: 0 0% 100%;--surface-2: 144 8% 96%;--surface-3: 144 6% 93%;--surface-inset: 144 6% 95%;--overlay-backdrop: hsl(0 0% 0% / .24);--overlay-backdrop-strong: hsl(0 0% 0% / .48);--text-primary: 150 10% 12%;--text-secondary: 148 6% 36%;--text-tertiary: 145 5% 52%;--text-disabled: 145 4% 70%;--border-subtle: 144 8% 91%;--border-default: 144 6% 85%;--border-strong: 144 5% 72%;--grid-line: 0 0% 92%;--shadow-xs: 0 1px 2px 0 hsl(0 0% 0% / .04);--shadow-sm: 0 1px 3px 0 hsl(0 0% 0% / .06), 0 1px 2px -1px hsl(0 0% 0% / .06);--shadow-md: 0 4px 6px -1px hsl(0 0% 0% / .06), 0 2px 4px -2px hsl(0 0% 0% / .04);--shadow-lg: 0 10px 15px -3px hsl(0 0% 0% / .06), 0 4px 6px -4px hsl(0 0% 0% / .04);--shadow-xl: 0 20px 25px -5px hsl(0 0% 0% / .06), 0 8px 10px -6px hsl(0 0% 0% / .04);--shadow-focus: 0 0 0 4px var(--brand-ring);--shadow-inset: inset 0 1px 2px 0 hsl(0 0% 0% / .04)}*{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}#issue-sticker-shadow-root{background-color:transparent;--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.\\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\\!container{max-width:1536px!important}.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\\!visible{visibility:visible!important}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{left:0;right:0}.inset-x-1{left:.25rem;right:.25rem}.inset-y-0{top:0;bottom:0}.-bottom-px{bottom:-1px}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.bottom-6{bottom:1.5rem}.left-0{left:0}.left-1\\/2{left:50%}.left-2{left:.5rem}.left-4{left:1rem}.left-\\[50\\%\\]{left:50%}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-5{right:1.25rem}.right-6{right:1.5rem}.top-0{top:0}.top-1{top:.25rem}.top-1\\/2{top:50%}.top-2{top:.5rem}.top-3{top:.75rem}.top-4{top:1rem}.top-5{top:1.25rem}.top-\\[50\\%\\]{top:50%}.top-\\[calc\\(\\(3\\.5rem-1\\.75rem\\)\\/2\\)\\]{top:.875rem}.top-full{top:100%}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-\\[1000000\\]{z-index:1000000}.z-\\[1000003\\]{z-index:1000003}.z-\\[1000004\\]{z-index:1000004}.z-\\[1000005\\]{z-index:1000005}.z-\\[1000006\\]{z-index:1000006}.z-\\[1000007\\]{z-index:1000007}.z-\\[1000008\\]{z-index:1000008}.z-\\[1000010\\]{z-index:1000010}.z-\\[1000011\\]{z-index:1000011}.z-\\[10001\\]{z-index:10001}.z-\\[999999\\]{z-index:999999}.z-\\[9999\\]{z-index:9999}.m-0{margin:0}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-2\\.5{margin-top:.625rem;margin-bottom:.625rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mb-0\\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-5{margin-bottom:1.25rem}.ml-0\\.5{margin-left:.125rem}.ml-4{margin-left:1rem}.mr-1\\.5{margin-right:.375rem}.mt-0{margin-top:0}.mt-0\\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.\\!h-auto{height:auto!important}.h-1\\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-2{height:.5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-3\\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\\[1\\.4rem\\]{height:1.4rem}.h-\\[100vh\\]{height:100vh}.h-\\[18px\\]{height:18px}.h-\\[220px\\]{height:220px}.h-\\[22px\\]{height:22px}.h-\\[30px\\]{height:30px}.h-\\[min\\(36vh\\,320px\\)\\]{height:min(36vh,320px)}.h-\\[min\\(480px\\,calc\\(100vh-64px\\)\\)\\]{height:min(480px,calc(100vh - 64px))}.h-\\[min\\(54vh\\,520px\\)\\]{height:min(54vh,520px)}.h-\\[min\\(560px\\,calc\\(100vh-32px\\)\\)\\]{height:min(560px,calc(100vh - 32px))}.h-\\[var\\(--radix-select-trigger-height\\)\\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.max-h-24{max-height:6rem}.max-h-40{max-height:10rem}.max-h-56{max-height:14rem}.max-h-96{max-height:24rem}.max-h-\\[150px\\]{max-height:150px}.max-h-\\[220px\\]{max-height:220px}.max-h-\\[320px\\]{max-height:320px}.max-h-\\[420px\\]{max-height:420px}.max-h-\\[90vh\\]{max-height:90vh}.max-h-\\[calc\\(100vh-3rem\\)\\]{max-height:calc(100vh - 3rem)}.max-h-\\[min\\(80vh\\,640px\\)\\]{max-height:min(80vh,640px)}.min-h-0{min-height:0px}.min-h-11{min-height:2.75rem}.min-h-\\[108px\\]{min-height:108px}.min-h-\\[120px\\]{min-height:120px}.min-h-\\[140px\\]{min-height:140px}.min-h-\\[220px\\]{min-height:220px}.w-0\\.5{width:.125rem}.w-1{width:.25rem}.w-1\\.5{width:.375rem}.w-1\\/2{width:50%}.w-10{width:2.5rem}.w-14{width:3.5rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\\[1\\.4rem\\]{width:1.4rem}.w-\\[18px\\]{width:18px}.w-\\[21rem\\]{width:21rem}.w-\\[22rem\\]{width:22rem}.w-\\[30px\\]{width:30px}.w-\\[38px\\]{width:38px}.w-\\[calc\\(100vw-32px\\)\\]{width:calc(100vw - 32px)}.w-\\[min\\(560px\\,calc\\(100vw-32px\\)\\)\\]{width:min(560px,calc(100vw - 32px))}.w-\\[var\\(--radix-popover-trigger-width\\)\\]{width:var(--radix-popover-trigger-width)}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.min-w-0{min-width:0px}.min-w-9{min-width:2.25rem}.min-w-\\[12rem\\]{min-width:12rem}.min-w-\\[200px\\]{min-width:200px}.min-w-\\[var\\(--radix-popover-trigger-width\\)\\]{min-width:var(--radix-popover-trigger-width)}.min-w-\\[var\\(--radix-select-trigger-width\\)\\]{min-width:var(--radix-select-trigger-width)}.max-w-8{max-width:2rem}.max-w-\\[120px\\]{max-width:120px}.max-w-\\[160px\\]{max-width:160px}.max-w-\\[280px\\]{max-width:280px}.max-w-\\[28rem\\]{max-width:28rem}.max-w-\\[300px\\]{max-width:300px}.max-w-\\[360px\\]{max-width:360px}.max-w-\\[36rem\\]{max-width:36rem}.max-w-\\[400px\\]{max-width:400px}.max-w-\\[420px\\]{max-width:420px}.max-w-\\[428px\\]{max-width:428px}.max-w-\\[480px\\]{max-width:480px}.max-w-\\[62ch\\]{max-width:62ch}.max-w-\\[640px\\]{max-width:640px}.max-w-\\[70ch\\]{max-width:70ch}.max-w-\\[90vw\\]{max-width:90vw}.max-w-\\[960px\\]{max-width:960px}.max-w-\\[calc\\(100vw-24px\\)\\]{max-width:calc(100vw - 24px)}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.-translate-x-1{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-1\\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\\[-50\\%\\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\\[18px\\]{--tw-translate-x: 18px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\\[2px\\]{--tw-translate-x: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\\[-50\\%\\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes pulse-ring{0%,to{box-shadow:0 0 0 0 var(--brand-ring)}50%{box-shadow:0 0 0 8px transparent}}.animate-pulse-ring{animation:pulse-ring 1.8s var(--ease-in-out) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.resize{resize:both}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.content-center{align-content:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-3\\.5{gap:.875rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-line-subtle>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-divide-opacity, 1))}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.\\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\\[18px\\]{border-radius:18px}.rounded-\\[20px\\]{border-radius:20px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-b-md{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-t-0{border-top-width:0px}.border-dashed{border-style:dashed}.border-\\[hsl\\(144_8\\%_91\\%\\)\\]{--tw-border-opacity: 1;border-color:hsl(144 8% 91% / var(--tw-border-opacity, 1))}.border-brand{--tw-border-opacity: 1;border-color:hsl(var(--brand-hsl) / var(--tw-border-opacity, 1))}.border-brand-border{border-color:var(--brand-border)}.border-brand\\/30{border-color:hsl(var(--brand-hsl) / .3)}.border-brand\\/40{border-color:hsl(var(--brand-hsl) / .4)}.border-danger\\/20{border-color:hsl(var(--danger) / .2)}.border-danger\\/30{border-color:hsl(var(--danger) / .3)}.border-info\\/20{border-color:hsl(var(--info) / .2)}.border-info\\/30{border-color:hsl(var(--info) / .3)}.border-line{--tw-border-opacity: 1;border-color:hsl(var(--border-default) / var(--tw-border-opacity, 1))}.border-line-focus{--tw-border-opacity: 1;border-color:hsl(var(--border-focus) / var(--tw-border-opacity, 1))}.border-line-strong{--tw-border-opacity: 1;border-color:hsl(var(--border-strong) / var(--tw-border-opacity, 1))}.border-line-subtle{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}.border-line-subtle\\/50{border-color:hsl(var(--border-subtle) / .5)}.border-line-subtle\\/90{border-color:hsl(var(--border-subtle) / .9)}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-success{--tw-border-opacity: 1;border-color:hsl(var(--success) / var(--tw-border-opacity, 1))}.border-success\\/20{border-color:hsl(var(--success) / .2)}.border-success\\/30{border-color:hsl(var(--success) / .3)}.border-text-primary{--tw-border-opacity: 1;border-color:hsl(var(--text-primary) / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-warning\\/20{border-color:hsl(var(--warning) / .2)}.border-warning\\/30{border-color:hsl(var(--warning) / .3)}.border-white\\/70{border-color:#ffffffb3}.border-white\\/80{border-color:#fffc}.border-white\\/90{border-color:#ffffffe6}.border-l-brand{--tw-border-opacity: 1;border-left-color:hsl(var(--brand-hsl) / var(--tw-border-opacity, 1))}.\\!bg-success-surface{background-color:hsl(var(--success-surface))!important}.bg-\\[var\\(--overlay-backdrop-strong\\)\\]{background-color:var(--overlay-backdrop-strong)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\\/10{background-color:#0000001a}.bg-black\\/40{background-color:#0006}.bg-black\\/80{background-color:#000c}.bg-brand{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.bg-brand-subtle{background-color:var(--brand-subtle)}.bg-brand\\/10{background-color:hsl(var(--brand-hsl) / .1)}.bg-brand\\/5{background-color:hsl(var(--brand-hsl) / .05)}.bg-danger{--tw-bg-opacity: 1;background-color:hsl(var(--danger) / var(--tw-bg-opacity, 1))}.bg-danger-subtle{background-color:hsl(var(--danger-subtle))}.bg-danger\\/10{background-color:hsl(var(--danger) / .1)}.bg-info-subtle{background-color:hsl(var(--info-subtle))}.bg-line{--tw-bg-opacity: 1;background-color:hsl(var(--border-default) / var(--tw-bg-opacity, 1))}.bg-line-subtle{--tw-bg-opacity: 1;background-color:hsl(var(--border-subtle) / var(--tw-bg-opacity, 1))}.bg-success{--tw-bg-opacity: 1;background-color:hsl(var(--success) / var(--tw-bg-opacity, 1))}.bg-success-subtle{background-color:hsl(var(--success-subtle))}.bg-success-surface{background-color:hsl(var(--success-surface))}.bg-surface-0{--tw-bg-opacity: 1;background-color:hsl(var(--surface-0) / var(--tw-bg-opacity, 1))}.bg-surface-1{--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.bg-surface-2{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.bg-surface-3{--tw-bg-opacity: 1;background-color:hsl(var(--surface-3) / var(--tw-bg-opacity, 1))}.bg-surface-inset{--tw-bg-opacity: 1;background-color:hsl(var(--surface-inset) / var(--tw-bg-opacity, 1))}.bg-text-primary{--tw-bg-opacity: 1;background-color:hsl(var(--text-primary) / var(--tw-bg-opacity, 1))}.bg-text-tertiary{--tw-bg-opacity: 1;background-color:hsl(var(--text-tertiary) / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-warning{--tw-bg-opacity: 1;background-color:hsl(var(--warning) / var(--tw-bg-opacity, 1))}.bg-warning-subtle{background-color:hsl(var(--warning-subtle))}.bg-warning\\/10{background-color:hsl(var(--warning) / .1)}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\\/10{background-color:#ffffff1a}.bg-white\\/25{background-color:#ffffff40}.fill-text-primary{fill:hsl(var(--text-primary) / 1)}.stroke-\\[3\\]{stroke-width:3}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.\\!p-0{padding:0!important}.p-0{padding:0}.p-0\\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-3\\.5{padding:.875rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.p-8{padding:2rem}.p-\\[18px\\]{padding:18px}.px-0{padding-left:0;padding-right:0}.px-1\\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-9{padding-left:2.25rem;padding-right:2.25rem}.py-0\\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-3\\.5{padding-top:.875rem;padding-bottom:.875rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-1{padding-bottom:.25rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-8{padding-left:2rem}.pr-10{padding-right:2.5rem}.pr-3{padding-right:.75rem}.pr-4{padding-right:1rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2\\.5{padding-top:.625rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.font-display{font-family:var(--font-display),ui-sans-serif,system-ui,sans-serif}.font-mono{font-family:var(--font-mono),ui-monospace,SFMono-Regular,Menlo,monospace}.font-sans{font-family:var(--font-sans),ui-sans-serif,system-ui,sans-serif}.text-2xs{font-size:clamp(10.5px,10.19px + .082vw,11.5px);line-height:1.333}.text-\\[0\\.72rem\\]{font-size:.72rem}.text-\\[1\\.45rem\\]{font-size:1.45rem}.text-\\[1\\.75rem\\]{font-size:1.75rem}.text-\\[10px\\]{font-size:10px}.text-base{font-size:clamp(14px,13.39px + .163vw,16px);line-height:1.5}.text-lg{font-size:clamp(17px,16.39px + .163vw,19px);line-height:1.471}.text-sm{font-size:clamp(13px,12.54px + .122vw,14.5px);line-height:1.462}.text-xl{font-size:clamp(20px,19.08px + .245vw,23px);line-height:1.45}.text-xs{font-size:clamp(12px,11.69px + .082vw,13px);line-height:1.333}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.italic{font-style:italic}.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)}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-8{line-height:2rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.text-\\[hsl\\(145_5\\%_42\\%\\)\\]{--tw-text-opacity: 1;color:hsl(145 5% 42% / var(--tw-text-opacity, 1))}.text-brand{--tw-text-opacity: 1;color:hsl(var(--brand-hsl) / var(--tw-text-opacity, 1))}.text-brand-fg{color:var(--brand-fg)}.text-brand\\/50{color:hsl(var(--brand-hsl) / .5)}.text-danger{--tw-text-opacity: 1;color:hsl(var(--danger) / var(--tw-text-opacity, 1))}.text-danger\\/80{color:hsl(var(--danger) / .8)}.text-info{--tw-text-opacity: 1;color:hsl(var(--info) / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-success{--tw-text-opacity: 1;color:hsl(var(--success) / var(--tw-text-opacity, 1))}.text-text-disabled{--tw-text-opacity: 1;color:hsl(var(--text-disabled) / var(--tw-text-opacity, 1))}.text-text-inverse{--tw-text-opacity: 1;color:hsl(var(--text-inverse) / var(--tw-text-opacity, 1))}.text-text-primary{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.text-text-secondary{--tw-text-opacity: 1;color:hsl(var(--text-secondary) / var(--tw-text-opacity, 1))}.text-text-tertiary{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.text-transparent{color:transparent}.text-warning{--tw-text-opacity: 1;color:hsl(var(--warning) / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\\/90{color:#ffffffe6}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.accent-brand{accent-color:hsl(var(--brand-hsl) / 1)}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.\\!shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\\[0_24px_70px_-28px_rgba\\(16\\,24\\,18\\,0\\.45\\)\\]{--tw-shadow: 0 24px 70px -28px rgba(16,24,18,.45);--tw-shadow-colored: 0 24px 70px -28px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: var(--shadow-lg);--tw-shadow-colored: var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: var(--shadow-md);--tw-shadow-colored: var(--shadow-md);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: var(--shadow-sm);--tw-shadow-colored: var(--shadow-sm);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: var(--shadow-xl);--tw-shadow-colored: var(--shadow-xl);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xs{--tw-shadow: var(--shadow-xs);--tw-shadow-colored: var(--shadow-xs);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.outline-2{outline-width:2px}.outline-offset-0{outline-offset:0px}.outline-transparent{outline-color:transparent}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-4{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-brand{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--brand-hsl) / var(--tw-ring-opacity, 1))}.ring-brand-subtle{--tw-ring-color: var(--brand-subtle)}.blur{--tw-blur: blur(8px);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)}.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)}.backdrop-blur-\\[2px\\]{--tw-backdrop-blur: blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,border-color\\,color\\,box-shadow\\]{transition-property:background-color,border-color,color,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\,border-color\\,box-shadow\\,opacity\\]{transition-property:background-color,color,border-color,box-shadow,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\,border-color\\,box-shadow\\]{transition-property:background-color,color,border-color,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\,box-shadow\\]{transition-property:background-color,color,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[background-color\\,color\\]{transition-property:background-color,color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[border-color\\,box-shadow\\,background-color\\]{transition-property:border-color,box-shadow,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[border-color\\,outline-color\\,box-shadow\\,background-color\\,transform\\]{transition-property:border-color,outline-color,box-shadow,background-color,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[max-width\\,box-shadow\\,background-color\\,border-color\\,transform\\,opacity\\]{transition-property:max-width,box-shadow,background-color,border-color,transform,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[max-width\\]{transition-property:max-width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\\[opacity\\,transform\\]{transition-property:opacity,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.duration-\\[var\\(--issue-marker-expand-duration\\)\\]{transition-duration:var(--issue-marker-expand-duration)}.duration-fast{transition-duration:var(--duration-fast)}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:var(--ease-in-out)}.ease-out{transition-timing-function:var(--ease-out)}@keyframes float-gentle{0%,to{transform:translateY(0)}50%{transform:translateY(-2px)}}@keyframes toast-slide{0%{opacity:0;transform:translateY(-14px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes gradient-shift{0%,to{background-position:0% 50%}50%{background-position:100% 50%}}.issue-overlay-shell{border:1px solid hsl(var(--border-subtle));border-radius:var(--radius-lg);background:hsl(var(--surface-1));box-shadow:var(--shadow-md)}.issue-marker-breathe{animation:float-gentle 4.8s var(--ease-in-out) infinite}.issue-marker-breathe:hover,.issue-marker-breathe:focus-visible,.issue-marker-breathe:focus-within{animation-play-state:paused}.marker\\:text-text-tertiary *::marker{color:hsl(var(--text-tertiary))}.marker\\:text-text-tertiary::marker{color:hsl(var(--text-tertiary))}.file\\:border-0::file-selector-button{border-width:0px}.file\\:bg-transparent::file-selector-button{background-color:transparent}.file\\:text-sm::file-selector-button{font-size:clamp(13px,12.54px + .122vw,14.5px);line-height:1.462}.file\\:font-medium::file-selector-button{font-weight:500}.file\\:text-text-primary::file-selector-button{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.placeholder\\:text-text-tertiary::-moz-placeholder{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.placeholder\\:text-text-tertiary::placeholder{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.focus-within\\:z-\\[10001\\]:focus-within{z-index:10001}.focus-within\\:border-line-focus:focus-within{--tw-border-opacity: 1;border-color:hsl(var(--border-focus) / var(--tw-border-opacity, 1))}.hover\\:z-\\[10001\\]:hover{z-index:10001}.hover\\:max-w-\\[160px\\]:hover{max-width:160px}.hover\\:max-w-\\[480px\\]:hover{max-width:480px}.hover\\:border-line:hover{--tw-border-opacity: 1;border-color:hsl(var(--border-default) / var(--tw-border-opacity, 1))}.hover\\:border-line-strong:hover{--tw-border-opacity: 1;border-color:hsl(var(--border-strong) / var(--tw-border-opacity, 1))}.hover\\:border-line-subtle:hover{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}.hover\\:bg-\\[hsl\\(144_8\\%_96\\%\\)\\]:hover{--tw-bg-opacity: 1;background-color:hsl(144 8% 96% / var(--tw-bg-opacity, 1))}.hover\\:bg-blue-500:hover{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.hover\\:bg-brand-hover:hover{background-color:var(--brand-hover)}.hover\\:bg-brand\\/40:hover{background-color:hsl(var(--brand-hsl) / .4)}.hover\\:bg-danger-subtle:hover{background-color:hsl(var(--danger-subtle))}.hover\\:bg-danger\\/10:hover{background-color:hsl(var(--danger) / .1)}.hover\\:bg-slate-100:hover{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.hover\\:bg-slate-50:hover{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.hover\\:bg-surface-2:hover{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.hover\\:bg-surface-2\\/60:hover{background-color:hsl(var(--surface-2) / .6)}.hover\\:bg-surface-3:hover{--tw-bg-opacity: 1;background-color:hsl(var(--surface-3) / var(--tw-bg-opacity, 1))}.hover\\:bg-surface-inset:hover{--tw-bg-opacity: 1;background-color:hsl(var(--surface-inset) / var(--tw-bg-opacity, 1))}.hover\\:bg-transparent:hover{background-color:transparent}.hover\\:bg-white\\/20:hover{background-color:#fff3}.hover\\:text-\\[hsl\\(150_10\\%_12\\%\\)\\]:hover{--tw-text-opacity: 1;color:hsl(150 10% 12% / var(--tw-text-opacity, 1))}.hover\\:text-brand-hover:hover{color:var(--brand-hover)}.hover\\:text-danger:hover{--tw-text-opacity: 1;color:hsl(var(--danger) / var(--tw-text-opacity, 1))}.hover\\:text-slate-900:hover{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.hover\\:text-text-primary:hover{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.hover\\:text-text-secondary:hover{--tw-text-opacity: 1;color:hsl(var(--text-secondary) / var(--tw-text-opacity, 1))}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-90:hover{opacity:.9}.hover\\:shadow-xl:hover{--tw-shadow: var(--shadow-xl);--tw-shadow-colored: var(--shadow-xl);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\\:border-brand:focus{--tw-border-opacity: 1;border-color:hsl(var(--brand-hsl) / var(--tw-border-opacity, 1))}.focus\\:bg-surface-2:focus{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.focus\\:text-text-primary:focus{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:max-w-\\[160px\\]:focus-visible{max-width:160px}.focus-visible\\:max-w-\\[480px\\]:focus-visible{max-width:480px}.focus-visible\\:border-line-focus:focus-visible{--tw-border-opacity: 1;border-color:hsl(var(--border-focus) / var(--tw-border-opacity, 1))}.focus-visible\\:border-transparent:focus-visible{border-color:transparent}.focus-visible\\:bg-slate-50:focus-visible{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.focus-visible\\:bg-surface-1:focus-visible{--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.focus-visible\\:bg-surface-2:focus-visible{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.focus-visible\\:text-text-primary:focus-visible{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.focus-visible\\:shadow-focus:focus-visible{--tw-shadow: var(--shadow-focus);--tw-shadow-colored: var(--shadow-focus);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus-visible\\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:outline-line-focus:focus-visible{outline-color:hsl(var(--border-focus) / 1)}.focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-4:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-brand-subtle:focus-visible{--tw-ring-color: var(--brand-subtle)}.focus-visible\\:ring-white\\/40:focus-visible{--tw-ring-color: rgb(255 255 255 / .4)}.active\\:bg-brand-active:active{background-color:var(--brand-active)}.active\\:bg-brand\\/60:active{background-color:hsl(var(--brand-hsl) / .6)}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\\:opacity-100{opacity:1}.group:focus-visible .group-focus-visible\\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:focus-visible .group-focus-visible\\:opacity-100{opacity:1}.group.toaster .group-\\[\\.toaster\\]\\:isolate{isolation:isolate}.group.toast .group-\\[\\.toast\\]\\:rounded-md,.group.toaster .group-\\[\\.toaster\\]\\:rounded-md{border-radius:var(--radius-md)}.group.toaster .group-\\[\\.toaster\\]\\:border{border-width:1px}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-danger\\/30{border-color:hsl(var(--danger) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-info\\/30{border-color:hsl(var(--info) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-success\\/30{border-color:hsl(var(--success) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!border-warning\\/30{border-color:hsl(var(--warning) / .3)!important}.group.toaster .group-\\[\\.toaster\\]\\:border-line-subtle{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}.group.toast .group-\\[\\.toast\\]\\:bg-brand{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.group.toast .group-\\[\\.toast\\]\\:bg-surface-2{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-danger-subtle{background-color:hsl(var(--danger-subtle))!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-info-subtle{background-color:hsl(var(--info-subtle))!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-success-surface{background-color:hsl(var(--success-surface))!important}.group.toaster .group-\\[\\.toaster\\]\\:\\!bg-warning-subtle{background-color:hsl(var(--warning-subtle))!important}.group.toaster .group-\\[\\.toaster\\]\\:bg-surface-1{--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:px-4{padding-left:1rem;padding-right:1rem}.group.toaster .group-\\[\\.toaster\\]\\:py-3{padding-top:.75rem;padding-bottom:.75rem}.group.toast .group-\\[\\.toast\\]\\:text-sm{font-size:clamp(13px,12.54px + .122vw,14.5px);line-height:1.462}.group.toast .group-\\[\\.toast\\]\\:text-xs{font-size:clamp(12px,11.69px + .082vw,13px);line-height:1.333}.group.toast .group-\\[\\.toast\\]\\:font-medium{font-weight:500}.group.toast .group-\\[\\.toast\\]\\:text-brand-fg{color:var(--brand-fg)}.group.toast .group-\\[\\.toast\\]\\:text-text-primary{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.group.toast .group-\\[\\.toast\\]\\:text-text-secondary{--tw-text-opacity: 1;color:hsl(var(--text-secondary) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:text-text-primary{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:shadow-sm{--tw-shadow: var(--shadow-sm);--tw-shadow-colored: var(--shadow-sm);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.group.toaster .group-\\[\\.toaster\\]\\:before\\:absolute:before{content:var(--tw-content);position:absolute}.group.toaster .group-\\[\\.toaster\\]\\:before\\:inset-0:before{content:var(--tw-content);top:0;right:0;bottom:0;left:0}.group.toaster .group-\\[\\.toaster\\]\\:before\\:-z-10:before{content:var(--tw-content);z-index:-10}.group.toaster .group-\\[\\.toaster\\]\\:before\\:rounded-md:before{content:var(--tw-content);border-radius:var(--radius-md)}.group.toaster .group-\\[\\.toaster\\]\\:before\\:bg-surface-1:before{content:var(--tw-content);--tw-bg-opacity: 1;background-color:hsl(var(--surface-1) / var(--tw-bg-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:before\\:content-\\[\\'\\'\\]:before{--tw-content: "";content:var(--tw-content)}.peer:focus-visible~.peer-focus-visible\\:shadow-focus{--tw-shadow: var(--shadow-focus);--tw-shadow-colored: var(--shadow-focus);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.peer:disabled~.peer-disabled\\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\\:opacity-60{opacity:.6}.aria-disabled\\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\\:opacity-40[aria-disabled=true]{opacity:.4}.data-\\[disabled\\]\\:pointer-events-none[data-disabled]{pointer-events:none}@keyframes dialog-out{0%{opacity:1;transform:translate(-50%,-50%) scale(1)}to{opacity:0;transform:translate(-50%,calc(-50% + 8px)) scale(.985)}}.data-\\[state\\=closed\\]\\:animate-dialog-out[data-state=closed]{animation:dialog-out var(--duration-out) var(--ease-out) forwards}@keyframes fade-out{0%{opacity:1}to{opacity:0}}.data-\\[state\\=closed\\]\\:animate-fade-out[data-state=closed]{animation:fade-out var(--duration-out) var(--ease-out) forwards}@keyframes scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.97)}}.data-\\[state\\=closed\\]\\:animate-scale-out[data-state=closed]{animation:scale-out var(--duration-out) var(--ease-out) forwards}@keyframes sheet-out-left{0%{transform:translate(0)}to{transform:translate(-100%);opacity:.6}}.data-\\[state\\=closed\\]\\:animate-sheet-out-left[data-state=closed]{animation:sheet-out-left var(--duration-base) var(--ease-out) forwards}@keyframes sheet-out-right{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:.6}}.data-\\[state\\=closed\\]\\:animate-sheet-out-right[data-state=closed]{animation:sheet-out-right var(--duration-base) var(--ease-out) forwards}.data-\\[state\\=delayed-open\\]\\:animate-scale-in[data-state=delayed-open]{animation:scale-in var(--duration-base) var(--ease-out) forwards}@keyframes dialog-in{0%{opacity:0;transform:translate(-50%,calc(-50% + 12px)) scale(.985)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.data-\\[state\\=open\\]\\:animate-dialog-in[data-state=open]{animation:dialog-in var(--duration-base) var(--ease-out) forwards}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.data-\\[state\\=open\\]\\:animate-fade-in[data-state=open]{animation:fade-in var(--duration-base) var(--ease-out) forwards}@keyframes scale-in{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}.data-\\[state\\=open\\]\\:animate-scale-in[data-state=open]{animation:scale-in var(--duration-base) var(--ease-out) forwards}@keyframes sheet-in-left{0%{transform:translate(-100%);opacity:.6}to{transform:translate(0);opacity:1}}.data-\\[state\\=open\\]\\:animate-sheet-in-left[data-state=open]{animation:sheet-in-left var(--duration-base) var(--ease-out) forwards}@keyframes sheet-in-right{0%{transform:translate(100%);opacity:.6}to{transform:translate(0)}}.data-\\[state\\=open\\]\\:animate-sheet-in-right[data-state=open]{animation:sheet-in-right var(--duration-base) var(--ease-out) forwards}.data-\\[range-end\\=true\\]\\:rounded-md[data-range-end=true]{border-radius:var(--radius-md)}.data-\\[range-middle\\=true\\]\\:rounded-none[data-range-middle=true]{border-radius:0}.data-\\[range-start\\=true\\]\\:rounded-md[data-range-start=true]{border-radius:var(--radius-md)}.data-\\[state\\=open\\]\\:border-line-focus[data-state=open]{--tw-border-opacity: 1;border-color:hsl(var(--border-focus) / var(--tw-border-opacity, 1))}.data-\\[highlighted\\]\\:bg-surface-2[data-highlighted]{--tw-bg-opacity: 1;background-color:hsl(var(--surface-2) / var(--tw-bg-opacity, 1))}.data-\\[range-end\\=true\\]\\:bg-brand[data-range-end=true]{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.data-\\[range-middle\\=true\\]\\:bg-transparent[data-range-middle=true]{background-color:transparent}.data-\\[range-start\\=true\\]\\:bg-brand[data-range-start=true],.data-\\[selected-single\\=true\\]\\:bg-brand[data-selected-single=true]{--tw-bg-opacity: 1;background-color:hsl(var(--brand-hsl) / var(--tw-bg-opacity, 1))}.data-\\[state\\=selected\\]\\:bg-brand-subtle[data-state=selected]{background-color:var(--brand-subtle)}.data-\\[today\\=true\\]\\:font-semibold[data-today=true]{font-weight:600}.data-\\[highlighted\\]\\:text-text-primary[data-highlighted]{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.data-\\[placeholder\\]\\:text-text-tertiary[data-placeholder]{--tw-text-opacity: 1;color:hsl(var(--text-tertiary) / var(--tw-text-opacity, 1))}.data-\\[range-end\\=true\\]\\:text-brand-fg[data-range-end=true]{color:var(--brand-fg)}.data-\\[range-middle\\=true\\]\\:text-text-primary[data-range-middle=true]{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.data-\\[range-start\\=true\\]\\:text-brand-fg[data-range-start=true],.data-\\[selected-single\\=true\\]\\:text-brand-fg[data-selected-single=true]{color:var(--brand-fg)}.data-\\[state\\=active\\]\\:text-text-primary[data-state=active],.data-\\[state\\=checked\\]\\:text-text-primary[data-state=checked]{--tw-text-opacity: 1;color:hsl(var(--text-primary) / var(--tw-text-opacity, 1))}.data-\\[today\\=true\\]\\:text-brand[data-today=true]{--tw-text-opacity: 1;color:hsl(var(--brand-hsl) / var(--tw-text-opacity, 1))}.data-\\[disabled\\]\\:opacity-50[data-disabled]{opacity:.5}.data-\\[state\\=open\\]\\:shadow-focus[data-state=open]{--tw-shadow: var(--shadow-focus);--tw-shadow-colored: var(--shadow-focus);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\\[range-end\\=true\\]\\:hover\\:bg-brand-hover:hover[data-range-end=true],.data-\\[range-start\\=true\\]\\:hover\\:bg-brand-hover:hover[data-range-start=true],.data-\\[selected-single\\=true\\]\\:hover\\:bg-brand-hover:hover[data-selected-single=true]{background-color:var(--brand-hover)}.data-\\[range-end\\=true\\]\\:hover\\:text-brand-fg:hover[data-range-end=true],.data-\\[range-start\\=true\\]\\:hover\\:text-brand-fg:hover[data-range-start=true],.data-\\[selected-single\\=true\\]\\:hover\\:text-brand-fg:hover[data-selected-single=true]{color:var(--brand-fg)}@media(prefers-reduced-motion:reduce){.motion-reduce\\:animate-none{animation:none}}@media(min-width:640px){.sm\\:flex-row{flex-direction:row}.sm\\:items-start{align-items:flex-start}.sm\\:items-center{align-items:center}.sm\\:justify-end{justify-content:flex-end}.sm\\:justify-between{justify-content:space-between}.sm\\:gap-2\\.5{gap:.625rem}.sm\\:p-5{padding:1.25rem}.sm\\:p-6{padding:1.5rem}.sm\\:text-2xl{font-size:clamp(26px,24.78px + .327vw,30px);line-height:1.308}.sm\\:text-\\[2\\.1rem\\]{font-size:2.1rem}}@media(min-width:768px){.md\\:flex{display:flex}.md\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\\:grid-cols-\\[minmax\\(0\\,1fr\\)_minmax\\(260px\\,340px\\)\\]{grid-template-columns:minmax(0,1fr) minmax(260px,340px)}}.\\[\\&\\>\\*\\:not\\(summary\\)\\]\\:pl-4>*:not(summary){padding-left:1rem}.\\[\\&\\>span\\]\\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\\[\\&\\>tr\\]\\:last\\:border-b-0:last-child>tr{border-bottom-width:0px}.\\[\\&\\[data-state\\=open\\]\\>span\\[data-chevron\\]\\]\\:rotate-180[data-state=open]>span[data-chevron]{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-danger [data-icon]{--tw-text-opacity: 1;color:hsl(var(--danger) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-info [data-icon]{--tw-text-opacity: 1;color:hsl(var(--info) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-success [data-icon]{--tw-text-opacity: 1;color:hsl(var(--success) / var(--tw-text-opacity, 1))}.group.toaster .group-\\[\\.toaster\\]\\:\\[\\&_\\[data-icon\\]\\]\\:text-warning [data-icon]{--tw-text-opacity: 1;color:hsl(var(--warning) / var(--tw-text-opacity, 1))}.\\[\\&_tr\\]\\:border-b tr{border-bottom-width:1px}.\\[\\&_tr\\]\\:border-line-subtle tr{--tw-border-opacity: 1;border-color:hsl(var(--border-subtle) / var(--tw-border-opacity, 1))}`;
37260
38083
  const sdkShadowCSS = ".issue-sticker-marker{pointer-events:auto}@keyframes highlight-pulse{0%,to{transform:scale(1);box-shadow:var(--shadow-md)}50%{transform:scale(1.3);box-shadow:var(--shadow-focus),var(--shadow-lg)}}.issue-sticker-marker.highlight-animation{animation:highlight-pulse .7s ease-in-out 3}";
37261
- const contentPageCSS = `body.issue-sticker-mode-active,body.issue-sticker-mode-active *{cursor:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M3 29 C3 22 3 20 3 15 a12 12 0 0 1 12-12 h2 a12 12 0 0 1 12 12 a12 12 0 0 1-12 12 H12 Z' fill='%2300AD57' stroke='%23ffffff' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E") 3 29,crosshair!important}body.issue-sticker-mode-active .issue-sticker-marker{cursor:default!important}body.issue-sticker-mode-active button,body.issue-sticker-mode-active a,body.issue-sticker-mode-active input,body.issue-sticker-mode-active textarea,body.issue-sticker-mode-active select{cursor:pointer!important}.issue-sticker-mode-highlight{outline:2px solid hsl(160 64% 34%)!important;outline-offset:2px!important;background-color:#1f8e691f!important;transition:outline .1s ease,background-color .1s ease!important}`;
38084
+ const contentPageCSS = `body.issue-sticker-mode-active,body.issue-sticker-mode-active *{cursor:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M3 29 C3 22 3 20 3 15 a12 12 0 0 1 12-12 h2 a12 12 0 0 1 12 12 a12 12 0 0 1-12 12 H12 Z' fill='%231C221F' stroke='%23ffffff' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E") 3 29,crosshair!important}body.issue-sticker-mode-active .issue-sticker-marker{cursor:default!important}body.issue-sticker-mode-active button,body.issue-sticker-mode-active a,body.issue-sticker-mode-active input,body.issue-sticker-mode-active textarea,body.issue-sticker-mode-active select{cursor:pointer!important}.issue-sticker-mode-highlight{outline:2px solid hsl(160 64% 34%)!important;outline-offset:2px!important;background-color:#1f8e691f!important;transition:outline .1s ease,background-color .1s ease!important}`;
37262
38085
  const PAGE_STYLE_ID = "issue-sticker-page-style";
37263
38086
  let root = null;
37264
38087
  let mountContainer = null;