issue-sticker 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,41 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
## 개요
|
|
2
2
|
|
|
3
|
-
**IssueSticker**는 웹서비스에서 발견한 버그를 화면 위에서 바로 기록하는 도구입니다. 문제 지점을 클릭해 이슈를 남기면 스크린샷·네트워크 로그·콘솔 로그·화면 녹화가 함께 수집되어, 재현에 필요한 맥락이 빠짐없이 남습니다.
|
|
4
3
|
|
|
5
|
-
이
|
|
4
|
+
이 README는 `issue-sticker` SDK의 설치 방법과 공개 API 표면만 다룹니다.
|
|
6
5
|
|
|
7
|
-
## 문서
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
프로젝트 생성, 허용 도메인 등록, API key 발급, 제품별 운영 방식은 아래 가이드에서 확인하세요.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
| 가이드 | 내용 |
|
|
11
|
+
| ---------------------------------------------------------------- | --------------------------------------------- |
|
|
12
|
+
| [시작 준비](https://issuesticker.com/guide/products/setup) | 프로젝트 생성, 허용 도메인 등록, API key 발급 |
|
|
13
|
+
| [SDK Widget](https://issuesticker.com/guide/products/sdk) | 위젯 설치, 초기화, 운영 환경에서 켜는 조건 |
|
|
14
|
+
| [SDK Headless](https://issuesticker.com/guide/products/headless) | Headless 클라이언트 전체 레퍼런스 |
|
|
15
|
+
| [외부 연동](https://issuesticker.com/guide/integrations) | Jira·Notion 연결과 필드 동기화 |
|
|
16
|
+
| [FAQ](https://issuesticker.com/guide/faq) | 권한, 도메인, key, 필드 동기화 문제 해결 |
|
|
10
17
|
|
|
11
|
-
| 문서 | 내용 |
|
|
12
|
-
| ---------------------------------------------------------------- | ------------------------------------- |
|
|
13
|
-
| [시작 준비](https://issuesticker.com/guide/products/setup) | 프로젝트·허용 도메인·API key 발급 |
|
|
14
|
-
| [SDK Widget](https://issuesticker.com/guide/products/sdk) | 위젯 설치, 초기화, 운영에서 켜는 조건 |
|
|
15
|
-
| [SDK Headless](https://issuesticker.com/guide/products/headless) | Headless 클라이언트 전체 레퍼런스 |
|
|
16
|
-
| [외부 연동](https://issuesticker.com/guide/integrations) | Jira·Notion 연결과 필드 동기화 |
|
|
17
|
-
| [FAQ](https://issuesticker.com/guide/faq) | 권한·도메인·key·필드 동기화 문제 해결 |
|
|
18
18
|
|
|
19
19
|
## 설치
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
```bash
|
|
22
23
|
npm install issue-sticker
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
|
|
27
|
+
`issue-sticker/react`와 `issue-sticker/headless/react`를 사용하려면 연동하는 앱에 `react`, `react-dom` 18 또는 19가 설치되어 있어야 합니다.
|
|
28
|
+
|
|
26
29
|
|
|
27
30
|
## 엔트리포인트
|
|
28
31
|
|
|
32
|
+
|
|
29
33
|
| 경로 | 용도 |
|
|
30
34
|
| ------------------------------ | ----------------------------------------------------- |
|
|
31
|
-
| `issue-sticker/react` | 위젯 UI(FAB
|
|
32
|
-
| `issue-sticker/headless` | UI 없이 이슈
|
|
33
|
-
| `issue-sticker/headless/react` | Headless UI를 직접 만들 때 사용하는 최소 React
|
|
35
|
+
| `issue-sticker/react` | 위젯 UI(FAB, 이슈 폼, 마커)를 마운트하는 React 어댑터 |
|
|
36
|
+
| `issue-sticker/headless` | UI 없이 이슈 흐름을 구독하고 제어하는 컨트롤러 API |
|
|
37
|
+
| `issue-sticker/headless/react` | Headless UI를 직접 만들 때 사용하는 최소 React 헬퍼 |
|
|
38
|
+
|
|
34
39
|
|
|
35
40
|
패키지 루트(`issue-sticker`)와 `issue-sticker/runtime`은 공개 엔트리포인트가 아닙니다.
|
|
36
41
|
|
|
42
|
+
|
|
37
43
|
## 빠른 시작 — 위젯
|
|
38
44
|
|
|
45
|
+
|
|
39
46
|
```tsx
|
|
40
47
|
'use client'; // Next.js App Router
|
|
41
48
|
|
|
@@ -44,7 +51,7 @@ import { useIssueSticker } from 'issue-sticker/react';
|
|
|
44
51
|
function App() {
|
|
45
52
|
useIssueSticker({
|
|
46
53
|
apiKey: process.env.NEXT_PUBLIC_ISSUE_STICKER_SDK_KEY!,
|
|
47
|
-
user: { id: 'user-123', name: 'Hong Gildong' }, // 선택:
|
|
54
|
+
user: { id: 'user-123', name: 'Hong Gildong' }, // 선택: 작성자 식별
|
|
48
55
|
enabled: isStaging || isAdmin, // 선택: 노출 조건 (기본 true)
|
|
49
56
|
});
|
|
50
57
|
|
|
@@ -52,12 +59,21 @@ function App() {
|
|
|
52
59
|
}
|
|
53
60
|
```
|
|
54
61
|
|
|
55
|
-
앱 최상위에서 한 번만 호출하세요. 훅이 마운트 시 초기화하고 언마운트 시 정리합니다.
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
앱 최상위에서 한 번만 호출하세요.
|
|
64
|
+
훅은 마운트 시 SDK를 초기화하고, 언마운트 시 정리합니다.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
오른쪽 아래에 표시되는 FAB는 드래그로 위치를 옮길 수 있습니다.
|
|
68
|
+
FAB에서는 이슈 생성, 화면 녹화, 마커 표시 토글, 마커 기준 전환(생성 위치 기준 / 대상 요소 기준), 미표시 스티커 확인, 가이드 다시 보기, 멤버 로그인·로그아웃을 사용할 수 있습니다.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
이슈 생성 모드와 화면 녹화는 동시에 켤 수 없습니다.
|
|
72
|
+
|
|
58
73
|
|
|
59
74
|
## 빠른 시작 — Headless
|
|
60
75
|
|
|
76
|
+
|
|
61
77
|
```typescript
|
|
62
78
|
import { createIssueStickerHeadless } from 'issue-sticker/headless';
|
|
63
79
|
|
|
@@ -72,23 +88,35 @@ await client.initialize();
|
|
|
72
88
|
await client.refreshIssues();
|
|
73
89
|
```
|
|
74
90
|
|
|
75
|
-
|
|
91
|
+
|
|
92
|
+
현재 상태는 읽기 전용 snapshot으로 제공되며, 이슈 생성은 `startIssueCapture()`로 시작합니다.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
전체 메서드, snapshot 타입, 동적 필드 descriptor, 에러 코드는 [Headless 가이드](https://issuesticker.com/guide/products/headless)를 참고하세요.
|
|
96
|
+
|
|
76
97
|
|
|
77
98
|
## API — `issue-sticker/react`
|
|
78
99
|
|
|
100
|
+
|
|
79
101
|
### `useIssueSticker(config)`
|
|
80
102
|
|
|
81
|
-
|
|
103
|
+
|
|
104
|
+
React 훅입니다.
|
|
105
|
+
`apiKey` 또는 `enabled`가 바뀌면 위젯을 다시 초기화하고, `user`가 바뀌면 위젯은 유지한 채 설정만 갱신합니다.
|
|
106
|
+
|
|
82
107
|
|
|
83
108
|
### `IssueSticker`
|
|
84
109
|
|
|
110
|
+
|
|
85
111
|
훅을 사용할 수 없는 환경에서 직접 제어할 때 사용합니다.
|
|
86
112
|
|
|
87
|
-
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
113
|
+
|
|
114
|
+
| 메서드 | 설명 |
|
|
115
|
+
| --------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
116
|
+
| `init(config: SDKConfig)` | SDK를 초기화하고 위젯을 마운트합니다. 이미 초기화된 상태라면 설정을 갱신하고 위젯을 다시 마운트합니다 |
|
|
117
|
+
| `updateConfig(config: SDKConfig)` | 위젯을 유지한 채 설정만 교체합니다. 초기화 전이면 `init`과 동일하게 동작합니다 |
|
|
118
|
+
| `destroy()` | 위젯을 언마운트하고 SDK를 종료합니다 |
|
|
119
|
+
|
|
92
120
|
|
|
93
121
|
```typescript
|
|
94
122
|
import { IssueSticker } from 'issue-sticker/react';
|
|
@@ -96,58 +124,92 @@ import { IssueSticker } from 'issue-sticker/react';
|
|
|
96
124
|
IssueSticker.init({ apiKey: 'YOUR_API_KEY' });
|
|
97
125
|
```
|
|
98
126
|
|
|
99
|
-
|
|
127
|
+
|
|
128
|
+
이슈 생성·제출 흐름을 연동하는 앱에서 직접 구독하거나 제어해야 한다면 Headless 클라이언트를 사용하세요.
|
|
129
|
+
상태는 `subscribe()`로 구독하고, 캡처와 제출은 메서드로 제어할 수 있습니다.
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
자세한 내용은 [Headless 가이드](https://issuesticker.com/guide/products/headless)를 참고하세요.
|
|
133
|
+
|
|
100
134
|
|
|
101
135
|
### `SDKConfig`
|
|
102
136
|
|
|
103
|
-
| 속성 | 타입 | 필수 | 설명 |
|
|
104
|
-
| ----------------------- | ------------------------------------ | ---- | ------------------------------------------------------------------------------ |
|
|
105
|
-
| `apiKey` | `string` | Yes | [관리자 콘솔](https://app.issuesticker.com)에서 발급한 SDK API key |
|
|
106
|
-
| `user` | `SDKUser` | No | 호스트 앱의 사용자 정보. 전달하면 보고자가 기록되고 본인 이슈를 조회할 수 있다 |
|
|
107
|
-
| `onboarding` | `'off' \| 'onMount' \| 'onFABClick'` | No | 온보딩 가이드 트리거 (기본 `'onMount'`). `'off'`면 "가이드 다시 보기"도 숨긴다 |
|
|
108
|
-
| `screenshotCompression` | `{ useWebWorker?: boolean }` | No | 스크린샷 압축을 Web Worker에서 수행할지 여부 |
|
|
109
|
-
| `enabled` | `boolean` | No | 위젯 활성화 여부 (기본 `true`). `useIssueSticker` 전용 옵션 |
|
|
110
137
|
|
|
111
|
-
|
|
138
|
+
| 속성 | 타입 | 필수 | 설명 |
|
|
139
|
+
| ----------------------- | ------------------------------------ | ---- | ------------------------------------------------------------------------------------------- |
|
|
140
|
+
| `apiKey` | `string` | Yes | [관리자 콘솔](https://app.issuesticker.com)에서 발급한 SDK API key |
|
|
141
|
+
| `user` | `SDKUser` | No | 연동하는 앱의 사용자 정보. 전달하면 작성자가 기록되고 자신이 만든 이슈를 조회할 수 있습니다 |
|
|
142
|
+
| `onboarding` | `'off' \| 'onMount' \| 'onFABClick'` | No | 온보딩 가이드 트리거 (기본 `'onMount'`). `'off'`면 "가이드 다시 보기"도 숨깁니다 |
|
|
143
|
+
| `screenshotCompression` | `{ useWebWorker?: boolean }` | No | 스크린샷 압축을 Web Worker에서 수행할지 여부 |
|
|
144
|
+
| `enabled` | `boolean` | No | 위젯 활성화 여부 (기본 `true`). `useIssueSticker` 전용 옵션 |
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
`SDKUser`는 `id`, `name` 두 필드가 모두 필요합니다.
|
|
148
|
+
|
|
112
149
|
|
|
113
150
|
### 키보드 단축키
|
|
114
151
|
|
|
152
|
+
|
|
115
153
|
| 기능 | macOS | Windows·Linux |
|
|
116
154
|
| ------------------- | ----------- | ------------- |
|
|
117
155
|
| 이슈 생성 모드 토글 | `⌘⌥1` `⌃⌥1` | `Ctrl+Alt+1` |
|
|
118
156
|
| 화면 녹화 시작/중지 | `⌘⌥2` `⌃⌥2` | `Ctrl+Alt+2` |
|
|
119
157
|
| 이슈 생성 모드 종료 | `Esc` | `Esc` |
|
|
120
158
|
|
|
159
|
+
|
|
121
160
|
## 이슈에 담기는 정보
|
|
122
161
|
|
|
162
|
+
|
|
123
163
|
- 스크린샷 — 화면 전체와 클릭한 요소 영역 (클릭 직후 백그라운드에서 캡처)
|
|
124
164
|
- 화면 녹화 영상 — 녹화 모드로 생성한 경우
|
|
125
165
|
- 네트워크·콘솔 로그 — 각각 최근 50개, IssueSticker 자체 트래픽은 제외
|
|
126
166
|
- 브라우저·OS 정보, 발생 URL, 클릭한 요소의 CSS 선택자와 XPath
|
|
127
|
-
- 세션 리플레이 — 워크스페이스에서 사용할 수 있는 경우, 이슈 폼에서 첨부
|
|
167
|
+
- 세션 리플레이 — 워크스페이스에서 사용할 수 있는 경우, 이슈 폼에서 첨부 여부 선택
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
화면의 마커를 클릭하면 이슈 팝오버에서 제목과 설명을 수정하고, 이슈를 삭제하고, 코딩 에이전트에 붙여 넣을 LLM 프롬프트를 복사할 수 있습니다.
|
|
171
|
+
연동된 Jira·Notion 정보는 멤버로 로그인했을 때 함께 표시됩니다.
|
|
172
|
+
|
|
128
173
|
|
|
129
|
-
|
|
174
|
+
화면 녹화는 브라우저 `getDisplayMedia` API를 사용합니다.
|
|
175
|
+
녹화 중 페이지를 새로고침하거나 다른 페이지로 이동하면 녹화가 중단되고 데이터가 유실됩니다.
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
페이지 이동 중에도 끊기지 않는 녹화가 필요하면 [Chrome Extension](https://issuesticker.com/guide/products/extension)을 사용하세요.
|
|
130
179
|
|
|
131
|
-
화면 녹화는 브라우저 `getDisplayMedia` API를 사용하므로, 녹화 중 페이지를 새로고침하거나 다른 페이지로 이동하면 녹화가 중단되고 데이터가 유실됩니다. 페이지 이동에도 끊기지 않는 녹화가 필요하면 [Chrome Extension](https://issuesticker.com/guide/products/extension)을 사용하세요.
|
|
132
180
|
|
|
133
181
|
## 사용자 식별
|
|
134
182
|
|
|
135
|
-
|
|
183
|
+
|
|
184
|
+
| 모드 | 설정 | 이슈 조회 범위 |
|
|
136
185
|
| ----------- | ------------------- | ----------------------------------------------------- |
|
|
137
186
|
| 익명 | `user` 없이 초기화 | 조회 없음 (이번 세션에서 생성한 이슈만 화면에 표시됨) |
|
|
138
187
|
| 사용자 식별 | `user` 전달 | 해당 사용자가 생성한 이슈 |
|
|
139
188
|
| 멤버 | FAB의 "멤버 로그인" | 프로젝트의 모든 이슈 |
|
|
140
189
|
|
|
190
|
+
|
|
141
191
|
## 문제 해결
|
|
142
192
|
|
|
143
|
-
`Invalid hook call` 또는 `Cannot read properties of null (reading 'useRef')` 오류는 대부분 React 인스턴스가 중복으로 로드될 때 발생합니다. `npm ls react react-dom`으로 중복을 확인하고, Vite는 `resolve.dedupe: ['react', 'react-dom']`, Webpack/Next.js는 alias로 경로를 단일화하세요.
|
|
144
193
|
|
|
145
|
-
`
|
|
194
|
+
`Invalid hook call` 또는 `Cannot read properties of null (reading 'useRef')` 오류는 대부분 React 인스턴스가 중복으로 로드될 때 발생합니다.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
`npm ls react react-dom`으로 중복 설치 여부를 확인하세요.
|
|
198
|
+
Vite는 `resolve.dedupe: ['react', 'react-dom']`을 설정하고, Webpack·Next.js는 alias로 React 경로를 하나로 맞추면 됩니다.
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
`Missing "./react" specifier in "issue-sticker" package` 오류는 설치된 패키지가 오래된 경우에 발생합니다.
|
|
202
|
+
`node_modules`와 lockfile을 갱신한 뒤 다시 설치하세요.
|
|
203
|
+
|
|
146
204
|
|
|
147
205
|
그 밖의 문제는 [FAQ](https://issuesticker.com/guide/faq)를 참고하세요.
|
|
148
206
|
|
|
207
|
+
|
|
149
208
|
## 라이선스
|
|
150
209
|
|
|
210
|
+
|
|
151
211
|
Copyright (c) 2026 maana. All rights reserved.
|
|
152
212
|
|
|
153
|
-
|
|
213
|
+
|
|
214
|
+
이 소프트웨어는 maana의 독점 소유물입니다.
|
|
215
|
+
자세한 내용은 [LICENSE](./LICENSE) 파일을 참조하세요.
|
|
@@ -734,18 +734,14 @@ function normalizeUploadMimeType(mimeType, mediaType) {
|
|
|
734
734
|
const normalized = (_a = (mimeType || fallback).split(";", 1)[0]) == null ? void 0 : _a.trim().toLowerCase();
|
|
735
735
|
return normalized && normalized.length > 0 ? normalized : fallback;
|
|
736
736
|
}
|
|
737
|
-
async function
|
|
738
|
-
const
|
|
739
|
-
method,
|
|
737
|
+
async function directUploadToSignedUrl(signedUrl, file, contentType) {
|
|
738
|
+
const response = await fetch(signedUrl, {
|
|
739
|
+
method: "PUT",
|
|
740
740
|
headers: {
|
|
741
741
|
"Content-Type": contentType
|
|
742
742
|
},
|
|
743
743
|
body: file
|
|
744
744
|
});
|
|
745
|
-
let response = await uploadWithMethod("PUT");
|
|
746
|
-
if (response.status === 405 || response.status === 404) {
|
|
747
|
-
response = await uploadWithMethod("POST");
|
|
748
|
-
}
|
|
749
745
|
if (!response.ok) {
|
|
750
746
|
const body = await response.text().catch(() => "");
|
|
751
747
|
throw new DirectUploadError(
|
|
@@ -12211,48 +12207,56 @@ class NetworkCollector {
|
|
|
12211
12207
|
}
|
|
12212
12208
|
}
|
|
12213
12209
|
}
|
|
12210
|
+
function buildExternalUserPayload(user) {
|
|
12211
|
+
if (!user) return {};
|
|
12212
|
+
return {
|
|
12213
|
+
external_user_id: user.id,
|
|
12214
|
+
external_user_name: user.name
|
|
12215
|
+
};
|
|
12216
|
+
}
|
|
12214
12217
|
export {
|
|
12215
|
-
|
|
12216
|
-
|
|
12218
|
+
hideOthers as $,
|
|
12219
|
+
buildJiraIssueFields as A,
|
|
12217
12220
|
Button$1 as B,
|
|
12218
12221
|
ConsoleCollector as C,
|
|
12219
|
-
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
|
|
12223
|
-
|
|
12222
|
+
ChevronDown as D,
|
|
12223
|
+
Portal as E,
|
|
12224
|
+
Content2 as F,
|
|
12225
|
+
Check as G,
|
|
12226
|
+
DatePicker as H,
|
|
12224
12227
|
Input as I,
|
|
12225
|
-
|
|
12226
|
-
|
|
12228
|
+
getNotionPageMetadata as J,
|
|
12229
|
+
buildNotionFieldViews as K,
|
|
12227
12230
|
Label as L,
|
|
12228
|
-
|
|
12231
|
+
DirectUploadError as M,
|
|
12229
12232
|
NetworkCollector as N,
|
|
12230
|
-
|
|
12233
|
+
getRegisteredUploadId as O,
|
|
12231
12234
|
Popover as P,
|
|
12232
|
-
|
|
12235
|
+
getExposedJiraFields as Q,
|
|
12233
12236
|
Root2 as R,
|
|
12234
12237
|
ScreenRecordingController as S,
|
|
12235
12238
|
Trigger as T,
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
+
isJiraFieldExposed as U,
|
|
12240
|
+
getIntegrationFailureMessage as V,
|
|
12241
|
+
getPrimaryJiraMapping as W,
|
|
12239
12242
|
X,
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
+
createCollection as Y,
|
|
12244
|
+
useDirection as Z,
|
|
12245
|
+
ReactRemoveScroll as _,
|
|
12243
12246
|
uploadSignedMediaWithApi as a,
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12247
|
+
useFocusGuards as a0,
|
|
12248
|
+
FocusScope as a1,
|
|
12249
|
+
getPrimaryNotionMapping as a2,
|
|
12250
|
+
buttonVariants as a3,
|
|
12251
|
+
findElementBySelector as a4,
|
|
12252
|
+
findElementByXPath as a5,
|
|
12253
|
+
useOnboardingFlow as a6,
|
|
12254
|
+
useOnboardingTarget as a7,
|
|
12255
|
+
ONBOARDING_POPOVER_DATA_ATTR as a8,
|
|
12256
|
+
OnboardingProvider as a9,
|
|
12253
12257
|
normalizeJiraFieldId as b,
|
|
12254
12258
|
captureWithModernScreenshot as c,
|
|
12255
|
-
|
|
12259
|
+
directUploadToSignedUrl as d,
|
|
12256
12260
|
buildJiraCreateFields as e,
|
|
12257
12261
|
buildNotionCreateFields as f,
|
|
12258
12262
|
getElementPosition as g,
|
|
@@ -12261,18 +12265,18 @@ export {
|
|
|
12261
12265
|
filterExcludeServiceRelatedConsoleLogs as j,
|
|
12262
12266
|
compactNetworkLogsForTransport as k,
|
|
12263
12267
|
sanitizeString as l,
|
|
12264
|
-
|
|
12268
|
+
buildExternalUserPayload as m,
|
|
12265
12269
|
normalizeExposedJiraFields as n,
|
|
12266
|
-
|
|
12270
|
+
SessionReplayCaptureController as o,
|
|
12267
12271
|
preloadModernScreenshot as p,
|
|
12268
|
-
|
|
12269
|
-
|
|
12272
|
+
Select$1 as q,
|
|
12273
|
+
SelectTrigger as r,
|
|
12270
12274
|
syncExternalIssueIntegrations as s,
|
|
12271
|
-
|
|
12275
|
+
SelectValue as t,
|
|
12272
12276
|
uploadScreenshotDataUrls as u,
|
|
12273
|
-
|
|
12274
|
-
|
|
12275
|
-
|
|
12276
|
-
|
|
12277
|
-
|
|
12277
|
+
SelectContent as v,
|
|
12278
|
+
SelectItem as w,
|
|
12279
|
+
PopoverTrigger as x,
|
|
12280
|
+
PopoverContent as y,
|
|
12281
|
+
getJiraMetadata as z
|
|
12278
12282
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as uploadScreenshotDataUrls, a as uploadSignedMediaWithApi, d as
|
|
1
|
+
import { u as uploadScreenshotDataUrls, a as uploadSignedMediaWithApi, d as directUploadToSignedUrl, n as normalizeExposedJiraFields, b as normalizeJiraFieldId, g as getElementPosition, c as captureWithModernScreenshot, e as buildJiraCreateFields, f as buildNotionCreateFields, s as syncExternalIssueIntegrations, h as devLogger, C as ConsoleCollector, N as NetworkCollector, i as filterExcludeServiceRelatedLogs, j as filterExcludeServiceRelatedConsoleLogs, k as compactNetworkLogsForTransport, l as sanitizeString, m as buildExternalUserPayload, S as ScreenRecordingController, o as SessionReplayCaptureController, p as preloadModernScreenshot } from "./externalUserPayload-C2hxbvaU.js";
|
|
2
2
|
import "react/jsx-runtime";
|
|
3
3
|
import "react";
|
|
4
4
|
import "./createLucideIcon-B457EluY.js";
|
|
@@ -110,7 +110,7 @@ class HeadlessTransport {
|
|
|
110
110
|
method: "POST",
|
|
111
111
|
body
|
|
112
112
|
}),
|
|
113
|
-
directUpload:
|
|
113
|
+
directUpload: directUploadToSignedUrl
|
|
114
114
|
},
|
|
115
115
|
file,
|
|
116
116
|
mediaType
|
|
@@ -1236,7 +1236,6 @@ function buildIssueCreatePayload({
|
|
|
1236
1236
|
currentUrl,
|
|
1237
1237
|
userAgent
|
|
1238
1238
|
}) {
|
|
1239
|
-
var _a, _b;
|
|
1240
1239
|
return sanitizeString({
|
|
1241
1240
|
url: currentUrl,
|
|
1242
1241
|
title: draft.title.trim(),
|
|
@@ -1254,8 +1253,7 @@ function buildIssueCreatePayload({
|
|
|
1254
1253
|
tenant_id: auth.tenantId,
|
|
1255
1254
|
project_id: projectId,
|
|
1256
1255
|
account_id: auth.accountId ?? void 0,
|
|
1257
|
-
|
|
1258
|
-
external_user_name: ((_b = config.user) == null ? void 0 : _b.name) ?? null
|
|
1256
|
+
...buildExternalUserPayload(config.user)
|
|
1259
1257
|
});
|
|
1260
1258
|
}
|
|
1261
1259
|
async function submitHeadlessIssueDraft({
|
|
@@ -15,7 +15,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
|
|
|
15
15
|
}
|
|
16
16
|
});
|
|
17
17
|
var _focused, _cleanup, _setup, _a, _provider, _providerCalled, _b, _online, _cleanup2, _setup2, _c, _gcTimeout, _d, _queryType, _initialState, _revertState, _cache, _client, _retryer, _defaultOptions, _abortSignalConsumed, _Query_instances, isInitialPausedFetch_fn, dispatch_fn, _e, _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, _f, _client3, _observers, _mutationCache, _retryer2, _Mutation_instances, dispatch_fn2, _g, _mutations, _scopes, _mutationId, _h, _client4, _currentResult2, _currentMutation, _mutateOptions, _MutationObserver_instances, updateResult_fn, notify_fn2, _i, _queries, _j, _queryCache, _mutationCache2, _defaultOptions2, _queryDefaults, _mutationDefaults, _mountCount, _unsubscribeFocus, _unsubscribeOnline, _k, _l;
|
|
18
|
-
import { L as Label,
|
|
18
|
+
import { L as Label, q as Select, r as SelectTrigger, t as SelectValue, v as SelectContent, w as SelectItem, P as Popover, x as PopoverTrigger, I as Input, y as PopoverContent, e as buildJiraCreateFields, z as getJiraMetadata, A as buildJiraIssueFields, B as Button, R as Root2$2, T as Trigger$2, D as ChevronDown, E as Portal, F as Content2$1, G as Check, X as X$1, H as DatePicker, f as buildNotionCreateFields, J as getNotionPageMetadata, K as buildNotionFieldViews, c as captureWithModernScreenshot, d as directUploadToSignedUrl, M as DirectUploadError, a as uploadSignedMediaWithApi, l as sanitizeString, O as getRegisteredUploadId, h as devLogger, Q as getExposedJiraFields, U as isJiraFieldExposed, b as normalizeJiraFieldId, n as normalizeExposedJiraFields, C as ConsoleCollector, p as preloadModernScreenshot, N as NetworkCollector, u as uploadScreenshotDataUrls, i as filterExcludeServiceRelatedLogs, j as filterExcludeServiceRelatedConsoleLogs, k as compactNetworkLogsForTransport, g as getElementPosition, m as buildExternalUserPayload, s as syncExternalIssueIntegrations, V as getIntegrationFailureMessage, o as SessionReplayCaptureController, W as getPrimaryJiraMapping, Y as createCollection, Z as useDirection, _ as ReactRemoveScroll, $ as hideOthers, a0 as useFocusGuards, a1 as FocusScope, a2 as getPrimaryNotionMapping, a3 as buttonVariants, a4 as findElementBySelector, a5 as findElementByXPath, S as ScreenRecordingController, a6 as useOnboardingFlow, a7 as useOnboardingTarget, a8 as ONBOARDING_POPOVER_DATA_ATTR, a9 as OnboardingProvider } from "./externalUserPayload-C2hxbvaU.js";
|
|
19
19
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
20
20
|
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-B457EluY.js";
|
|
21
21
|
import { createRoot } from "react-dom/client";
|
|
@@ -63,6 +63,33 @@ function buildAdminIssueUrl(issueId, options) {
|
|
|
63
63
|
if (!adminBaseUrl) return null;
|
|
64
64
|
return new URL(`/issues/${encodeURIComponent(normalizedIssueId)}`, adminBaseUrl).toString();
|
|
65
65
|
}
|
|
66
|
+
const ISSUE_STICKER_HOST_ELEMENT_ID = "issue-sticker-host";
|
|
67
|
+
const ISSUE_STICKER_RUNTIME_OWNER_ATTRIBUTE = "data-issue-sticker-runtime";
|
|
68
|
+
const ISSUE_STICKER_EXTENSION_RUNTIME_READY_EVENT = "issue-sticker:extension-runtime-ready";
|
|
69
|
+
const ISSUE_STICKER_RUNTIME_OWNER = {
|
|
70
|
+
extension: "extension",
|
|
71
|
+
sdk: "sdk"
|
|
72
|
+
};
|
|
73
|
+
function resolveDocument(doc) {
|
|
74
|
+
return typeof document === "undefined" ? null : document;
|
|
75
|
+
}
|
|
76
|
+
function getIssueStickerRuntimeHost(doc) {
|
|
77
|
+
var _a2;
|
|
78
|
+
return ((_a2 = resolveDocument()) == null ? void 0 : _a2.getElementById(ISSUE_STICKER_HOST_ELEMENT_ID)) ?? null;
|
|
79
|
+
}
|
|
80
|
+
function getIssueStickerRuntimeOwner(element2) {
|
|
81
|
+
const owner = element2 == null ? void 0 : element2.getAttribute(ISSUE_STICKER_RUNTIME_OWNER_ATTRIBUTE);
|
|
82
|
+
if (owner === ISSUE_STICKER_RUNTIME_OWNER.extension || owner === ISSUE_STICKER_RUNTIME_OWNER.sdk) {
|
|
83
|
+
return owner;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
function markIssueStickerRuntimeHost(element2, owner) {
|
|
88
|
+
element2.setAttribute(ISSUE_STICKER_RUNTIME_OWNER_ATTRIBUTE, owner);
|
|
89
|
+
}
|
|
90
|
+
function isIssueStickerExtensionRuntimeActive(doc) {
|
|
91
|
+
return getIssueStickerRuntimeOwner(getIssueStickerRuntimeHost()) === ISSUE_STICKER_RUNTIME_OWNER.extension;
|
|
92
|
+
}
|
|
66
93
|
/**
|
|
67
94
|
* @license lucide-react v0.468.0 - ISC
|
|
68
95
|
*
|
|
@@ -624,6 +651,14 @@ function getTriggerLabel(options, selectedValues, placeholder, renderUnknownValu
|
|
|
624
651
|
}
|
|
625
652
|
return `${labels.slice(0, 2).join(", ")} +${labels.length - 2}`;
|
|
626
653
|
}
|
|
654
|
+
function eventHappenedInside(event, nodes) {
|
|
655
|
+
const target = event.target;
|
|
656
|
+
if (!(target instanceof Node)) {
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
const composedPath = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
660
|
+
return nodes.some((node2) => node2 && (node2.contains(target) || composedPath.includes(node2)));
|
|
661
|
+
}
|
|
627
662
|
function MultiSelect({
|
|
628
663
|
options,
|
|
629
664
|
value,
|
|
@@ -638,7 +673,24 @@ function MultiSelect({
|
|
|
638
673
|
renderUnknownValues = (values) => values
|
|
639
674
|
}) {
|
|
640
675
|
const [open, setOpen] = React.useState(false);
|
|
676
|
+
const triggerRef = React.useRef(null);
|
|
677
|
+
const contentRef = React.useRef(null);
|
|
641
678
|
const portalContainer = usePortalContainer();
|
|
679
|
+
React.useEffect(() => {
|
|
680
|
+
var _a2, _b2;
|
|
681
|
+
if (!open) {
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
const ownerDocument = ((_a2 = contentRef.current) == null ? void 0 : _a2.ownerDocument) ?? ((_b2 = triggerRef.current) == null ? void 0 : _b2.ownerDocument) ?? document;
|
|
685
|
+
const closeOnOutsideClick = (event) => {
|
|
686
|
+
if (eventHappenedInside(event, [triggerRef.current, contentRef.current])) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
setOpen(false);
|
|
690
|
+
};
|
|
691
|
+
ownerDocument.addEventListener("click", closeOnOutsideClick, true);
|
|
692
|
+
return () => ownerDocument.removeEventListener("click", closeOnOutsideClick, true);
|
|
693
|
+
}, [open]);
|
|
642
694
|
const emitChange = (next) => {
|
|
643
695
|
onValueChange == null ? void 0 : onValueChange(next);
|
|
644
696
|
onChange == null ? void 0 : onChange(next);
|
|
@@ -664,6 +716,7 @@ function MultiSelect({
|
|
|
664
716
|
/* @__PURE__ */ jsxs(
|
|
665
717
|
Trigger$2,
|
|
666
718
|
{
|
|
719
|
+
ref: triggerRef,
|
|
667
720
|
type: "button",
|
|
668
721
|
role: "combobox",
|
|
669
722
|
"aria-expanded": open,
|
|
@@ -686,6 +739,7 @@ function MultiSelect({
|
|
|
686
739
|
/* @__PURE__ */ jsx(Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
|
|
687
740
|
Content2$1,
|
|
688
741
|
{
|
|
742
|
+
ref: contentRef,
|
|
689
743
|
align: "start",
|
|
690
744
|
sideOffset: 6,
|
|
691
745
|
"data-testid": "multi-select-content",
|
|
@@ -5024,7 +5078,7 @@ async function uploadRequest(endpoint, formData, skipAuth = false) {
|
|
|
5024
5078
|
}
|
|
5025
5079
|
async function directUpload(signedUrl, file, contentType) {
|
|
5026
5080
|
try {
|
|
5027
|
-
await
|
|
5081
|
+
await directUploadToSignedUrl(signedUrl, file, contentType);
|
|
5028
5082
|
} catch (error) {
|
|
5029
5083
|
if (error instanceof ApiError) {
|
|
5030
5084
|
throw error;
|
|
@@ -5626,6 +5680,7 @@ const CACHE_DURATION_MS = 30 * 1e3;
|
|
|
5626
5680
|
const STICKER_PAGE_SIZE = 500;
|
|
5627
5681
|
const STICKER_FETCH_LIMIT = 2e3;
|
|
5628
5682
|
function getFilterKey(filters) {
|
|
5683
|
+
var _a2;
|
|
5629
5684
|
const normalizeArray = (value) => {
|
|
5630
5685
|
if (value === "all" || !value) return "all";
|
|
5631
5686
|
if (Array.isArray(value)) {
|
|
@@ -5633,17 +5688,40 @@ function getFilterKey(filters) {
|
|
|
5633
5688
|
}
|
|
5634
5689
|
return String(value);
|
|
5635
5690
|
};
|
|
5691
|
+
const normalizeRecord = (record) => {
|
|
5692
|
+
if (!record) return "";
|
|
5693
|
+
const entries = Object.entries(record).map(([k, v]) => [k, [...v].sort()]).sort(([a], [b]) => a.localeCompare(b));
|
|
5694
|
+
return JSON.stringify(entries);
|
|
5695
|
+
};
|
|
5636
5696
|
return JSON.stringify({
|
|
5637
5697
|
sdkMode: getSdkMode() || "public",
|
|
5638
5698
|
url: normalizeArray(filters.url),
|
|
5639
5699
|
projectId: filters.projectId || "all",
|
|
5640
|
-
externalUserId: filters.externalUserId || ""
|
|
5700
|
+
externalUserId: filters.externalUserId || "",
|
|
5701
|
+
search: ((_a2 = filters.search) == null ? void 0 : _a2.trim()) || "",
|
|
5702
|
+
dateFrom: filters.dateFrom || "",
|
|
5703
|
+
dateTo: filters.dateTo || "",
|
|
5704
|
+
page: filters.page ?? 0,
|
|
5705
|
+
pageSize: filters.pageSize ?? 0,
|
|
5706
|
+
custom: normalizeRecord(filters.customFieldValues),
|
|
5707
|
+
jira: normalizeRecord(filters.jiraFieldValues),
|
|
5708
|
+
notion: normalizeRecord(filters.notionFieldValues),
|
|
5709
|
+
sortOrder: filters.sortOrder || ""
|
|
5641
5710
|
});
|
|
5642
5711
|
}
|
|
5643
5712
|
function invalidateIssuesCache() {
|
|
5644
5713
|
issuesCache = null;
|
|
5645
5714
|
}
|
|
5646
|
-
function
|
|
5715
|
+
function recordToFilterArray(record, keyFieldName) {
|
|
5716
|
+
if (!record) return null;
|
|
5717
|
+
const entries = Object.entries(record).filter(([, values]) => values.length > 0);
|
|
5718
|
+
if (entries.length === 0) return null;
|
|
5719
|
+
return entries.map(
|
|
5720
|
+
([key, values]) => ({ [keyFieldName]: key, values })
|
|
5721
|
+
);
|
|
5722
|
+
}
|
|
5723
|
+
function buildFilterQueryParams(filters, options = {}) {
|
|
5724
|
+
var _a2;
|
|
5647
5725
|
const params = new URLSearchParams();
|
|
5648
5726
|
if (filters.projectId) {
|
|
5649
5727
|
params.set("project_id", filters.projectId);
|
|
@@ -5655,6 +5733,30 @@ function buildFilterQueryParams(filters) {
|
|
|
5655
5733
|
params.set("url", filters.url);
|
|
5656
5734
|
}
|
|
5657
5735
|
}
|
|
5736
|
+
if (options.includeListFilters) {
|
|
5737
|
+
const search2 = (_a2 = filters.search) == null ? void 0 : _a2.trim();
|
|
5738
|
+
if (search2) {
|
|
5739
|
+
params.set("search", search2);
|
|
5740
|
+
}
|
|
5741
|
+
if (filters.dateFrom) {
|
|
5742
|
+
params.set("date_from", filters.dateFrom);
|
|
5743
|
+
}
|
|
5744
|
+
if (filters.dateTo) {
|
|
5745
|
+
params.set("date_to", filters.dateTo);
|
|
5746
|
+
}
|
|
5747
|
+
const customArr = recordToFilterArray(filters.customFieldValues, "fieldDefinitionId");
|
|
5748
|
+
if (customArr) {
|
|
5749
|
+
params.set("custom_field_filters", JSON.stringify(customArr));
|
|
5750
|
+
}
|
|
5751
|
+
const jiraArr = recordToFilterArray(filters.jiraFieldValues, "fieldName");
|
|
5752
|
+
if (jiraArr) {
|
|
5753
|
+
params.set("jira_field_filters", JSON.stringify(jiraArr));
|
|
5754
|
+
}
|
|
5755
|
+
const notionArr = recordToFilterArray(filters.notionFieldValues, "fieldName");
|
|
5756
|
+
if (notionArr) {
|
|
5757
|
+
params.set("notion_field_filters", JSON.stringify(notionArr));
|
|
5758
|
+
}
|
|
5759
|
+
}
|
|
5658
5760
|
if (filters.externalUserId) {
|
|
5659
5761
|
params.set("external_user_id", filters.externalUserId);
|
|
5660
5762
|
}
|
|
@@ -5664,6 +5766,9 @@ function buildFilterQueryParams(filters) {
|
|
|
5664
5766
|
if (typeof filters.pageSize === "number" && filters.pageSize > 0) {
|
|
5665
5767
|
params.set("page_size", String(filters.pageSize));
|
|
5666
5768
|
}
|
|
5769
|
+
if (filters.sortOrder) {
|
|
5770
|
+
params.set("sort_order", filters.sortOrder);
|
|
5771
|
+
}
|
|
5667
5772
|
const queryString = params.toString();
|
|
5668
5773
|
return queryString ? `?${queryString}` : "";
|
|
5669
5774
|
}
|
|
@@ -5691,7 +5796,7 @@ const issueService = {
|
|
|
5691
5796
|
if (!options.forceRefresh && issuesCache && issuesCache.filterKey === filterKey && now2 - issuesCache.timestamp < CACHE_DURATION_MS) {
|
|
5692
5797
|
return issuesCache.data;
|
|
5693
5798
|
}
|
|
5694
|
-
const queryParams = buildFilterQueryParams(filters);
|
|
5799
|
+
const queryParams = buildFilterQueryParams(filters, { includeListFilters: true });
|
|
5695
5800
|
const { items: issues = [] } = await apiClient.get(
|
|
5696
5801
|
`${issuesEndpoint()}${queryParams}`
|
|
5697
5802
|
);
|
|
@@ -14993,7 +15098,7 @@ function useIssueSubmission({
|
|
|
14993
15098
|
const { createNotionPage } = useNotionIntegrationWithApi();
|
|
14994
15099
|
const createIssueMutation = useDebouncedMutation({
|
|
14995
15100
|
mutationFn: async (data) => {
|
|
14996
|
-
var _a2
|
|
15101
|
+
var _a2;
|
|
14997
15102
|
if (!data.title.trim()) {
|
|
14998
15103
|
throw new Error("제목을 입력해주세요.");
|
|
14999
15104
|
}
|
|
@@ -15051,8 +15156,7 @@ function useIssueSubmission({
|
|
|
15051
15156
|
tenant_id: authInfo.tenantId,
|
|
15052
15157
|
project_id: authInfo.projectId,
|
|
15053
15158
|
account_id: authInfo.accountId || void 0,
|
|
15054
|
-
|
|
15055
|
-
external_user_name: ((_c2 = SDKManager.getInstance().config.user) == null ? void 0 : _c2.name) ?? null
|
|
15159
|
+
...buildExternalUserPayload(SDKManager.getInstance().config.user)
|
|
15056
15160
|
};
|
|
15057
15161
|
if ((sessionReplay == null ? void 0 : sessionReplay.preferOn) && sessionReplay.canAttach) {
|
|
15058
15162
|
try {
|
|
@@ -36223,7 +36327,6 @@ function AuthGate() {
|
|
|
36223
36327
|
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-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;--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;--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))}.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;letter-spacing:.14em;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-\\[100vh\\]{height:100vh}.h-\\[18px\\]{height:18px}.h-\\[220px\\]{height:220px}.h-\\[22px\\]{height:22px}.h-\\[280px\\]{height:280px}.h-\\[30px\\]{height:30px}.h-\\[min\\(36vh\\,320px\\)\\]{height:min(36vh,320px)}.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-10{min-height:2.5rem}.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-12{width:3rem}.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-\\[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\\(420px\\,calc\\(100vw-32px\\)\\)\\]{width:min(420px,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-\\[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-\\[440px\\]{max-width:440px}.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 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}.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\\.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-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-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{border-color:var(--brand)}.border-brand-border{border-color:var(--brand-border)}.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{border-left-color:var(--brand)}.\\!bg-success-subtle{background-color:hsl(var(--success-subtle))!important}.bg-\\[hsl\\(202_52\\%_96\\%\\)\\]{--tw-bg-opacity: 1;background-color:hsl(202 52% 96% / var(--tw-bg-opacity, 1))}.bg-\\[hsl\\(34_82\\%_96\\%\\)\\]{--tw-bg-opacity: 1;background-color:hsl(34 82% 96% / var(--tw-bg-opacity, 1))}.bg-\\[hsl\\(3_68\\%_96\\%\\)\\]{--tw-bg-opacity: 1;background-color:hsl(3 68% 96% / var(--tw-bg-opacity, 1))}.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{background-color:var(--brand)}.bg-brand-subtle{background-color:var(--brand-subtle)}.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-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-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;letter-spacing:.03em}.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-\\[11px\\]{font-size:11px}.text-base{font-size:14px;line-height:21px;letter-spacing:-.006em}.text-lg{font-size:17px;line-height:25px;letter-spacing:-.012em}.text-sm{font-size:13px;line-height:19px;letter-spacing:-.004em}.text-xl{font-size:20px;line-height:29px;letter-spacing:-.018em}.text-xs{font-size:12px;line-height:16px;letter-spacing:.012em}.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}.tracking-\\[-0\\.01em\\]{letter-spacing:-.01em}.tracking-\\[-0\\.024em\\]{letter-spacing:-.024em}.tracking-\\[-0\\.028em\\]{letter-spacing:-.028em}.tracking-\\[-0\\.02em\\]{letter-spacing:-.02em}.tracking-\\[-0\\.036em\\]{letter-spacing:-.036em}.tracking-\\[0\\.14em\\]{letter-spacing:.14em}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-\\[hsl\\(145_5\\%_42\\%\\)\\]{--tw-text-opacity: 1;color:hsl(145 5% 42% / var(--tw-text-opacity, 1))}.text-brand{color:var(--brand)}.text-brand-fg{color:var(--brand-fg)}.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-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:var(--brand)}.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-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-color: var(--brand)}.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-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}.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;letter-spacing:-.004em}.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))}.last\\:border-b-0:last-child{border-bottom-width:0px}.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-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-success-subtle\\/80:hover{background-color:hsl(var(--success-subtle) / .8)}.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)}.hover\\:brightness-110:hover{--tw-brightness: brightness(1.1);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)}.focus\\:border-brand:focus{border-color:var(--brand)}.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-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)}.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.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{background-color:var(--brand)}.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-success-subtle{background-color:hsl(var(--success-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;letter-spacing:-.004em}.group.toast .group-\\[\\.toast\\]\\:text-xs{font-size:12px;line-height:16px;letter-spacing:.012em}.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)}.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]{background-color:var(--brand)}.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]{background-color:var(--brand)}.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]{color:var(--brand)}.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;letter-spacing:-.024em}.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)}}.\\[\\&\\>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-success [data-icon]{--tw-text-opacity: 1;color:hsl(var(--success) / 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))}';
|
|
36224
36328
|
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}";
|
|
36225
36329
|
const contentPageCSS = "body.issue-sticker-mode-active,body.issue-sticker-mode-active *{cursor: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}";
|
|
36226
|
-
const HOST_ELEMENT_ID = "issue-sticker-host";
|
|
36227
36330
|
const PAGE_STYLE_ID = "issue-sticker-page-style";
|
|
36228
36331
|
let root = null;
|
|
36229
36332
|
let mountContainer = null;
|
|
@@ -36236,14 +36339,18 @@ function renderWidget(config) {
|
|
|
36236
36339
|
);
|
|
36237
36340
|
}
|
|
36238
36341
|
function mountWidget(config) {
|
|
36239
|
-
|
|
36240
|
-
|
|
36342
|
+
if (isIssueStickerExtensionRuntimeActive()) {
|
|
36343
|
+
return;
|
|
36344
|
+
}
|
|
36345
|
+
const existingHost = document.getElementById(ISSUE_STICKER_HOST_ELEMENT_ID);
|
|
36346
|
+
if (root && mountContainer && existingHost) {
|
|
36241
36347
|
renderWidget(config);
|
|
36242
36348
|
return;
|
|
36243
36349
|
}
|
|
36244
|
-
|
|
36350
|
+
existingHost == null ? void 0 : existingHost.remove();
|
|
36245
36351
|
const hostElement = document.createElement("div");
|
|
36246
|
-
hostElement.id =
|
|
36352
|
+
hostElement.id = ISSUE_STICKER_HOST_ELEMENT_ID;
|
|
36353
|
+
markIssueStickerRuntimeHost(hostElement, ISSUE_STICKER_RUNTIME_OWNER.sdk);
|
|
36247
36354
|
hostElement.style.all = "initial";
|
|
36248
36355
|
hostElement.style.position = "fixed";
|
|
36249
36356
|
hostElement.style.top = "0";
|
|
@@ -36279,8 +36386,8 @@ function unmountWidget() {
|
|
|
36279
36386
|
root = null;
|
|
36280
36387
|
}
|
|
36281
36388
|
mountContainer = null;
|
|
36282
|
-
const host = document.getElementById(
|
|
36283
|
-
if (host) {
|
|
36389
|
+
const host = document.getElementById(ISSUE_STICKER_HOST_ELEMENT_ID);
|
|
36390
|
+
if (host && getIssueStickerRuntimeOwner(host) !== ISSUE_STICKER_RUNTIME_OWNER.extension) {
|
|
36284
36391
|
host.remove();
|
|
36285
36392
|
}
|
|
36286
36393
|
const pageStyle = document.getElementById(PAGE_STYLE_ID);
|
|
@@ -36290,7 +36397,19 @@ function unmountWidget() {
|
|
|
36290
36397
|
}
|
|
36291
36398
|
let pendingMountConfig = null;
|
|
36292
36399
|
let domReadyMountQueued = false;
|
|
36400
|
+
function destroySdkRuntime() {
|
|
36401
|
+
pendingMountConfig = null;
|
|
36402
|
+
unmountWidget();
|
|
36403
|
+
SDKManager.resetInstance();
|
|
36404
|
+
}
|
|
36405
|
+
function shouldDisableSdkRuntime() {
|
|
36406
|
+
return isIssueStickerExtensionRuntimeActive();
|
|
36407
|
+
}
|
|
36293
36408
|
function mountWidgetWhenReady(config) {
|
|
36409
|
+
if (shouldDisableSdkRuntime()) {
|
|
36410
|
+
destroySdkRuntime();
|
|
36411
|
+
return;
|
|
36412
|
+
}
|
|
36294
36413
|
pendingMountConfig = config;
|
|
36295
36414
|
if (document.readyState !== "loading") {
|
|
36296
36415
|
mountWidget(config);
|
|
@@ -36305,6 +36424,10 @@ function mountWidgetWhenReady(config) {
|
|
|
36305
36424
|
() => {
|
|
36306
36425
|
domReadyMountQueued = false;
|
|
36307
36426
|
if (pendingMountConfig) {
|
|
36427
|
+
if (shouldDisableSdkRuntime()) {
|
|
36428
|
+
destroySdkRuntime();
|
|
36429
|
+
return;
|
|
36430
|
+
}
|
|
36308
36431
|
mountWidget(pendingMountConfig);
|
|
36309
36432
|
}
|
|
36310
36433
|
},
|
|
@@ -36313,6 +36436,10 @@ function mountWidgetWhenReady(config) {
|
|
|
36313
36436
|
}
|
|
36314
36437
|
const IssueSticker = {
|
|
36315
36438
|
init(config) {
|
|
36439
|
+
if (shouldDisableSdkRuntime()) {
|
|
36440
|
+
destroySdkRuntime();
|
|
36441
|
+
return;
|
|
36442
|
+
}
|
|
36316
36443
|
const sdk = SDKManager.getInstance();
|
|
36317
36444
|
if (sdk.isInitialized()) {
|
|
36318
36445
|
sdk.updateConfig(config);
|
|
@@ -36327,6 +36454,10 @@ const IssueSticker = {
|
|
|
36327
36454
|
sdk.eventBus.emit("ready");
|
|
36328
36455
|
},
|
|
36329
36456
|
updateConfig(config) {
|
|
36457
|
+
if (shouldDisableSdkRuntime()) {
|
|
36458
|
+
destroySdkRuntime();
|
|
36459
|
+
return;
|
|
36460
|
+
}
|
|
36330
36461
|
const sdk = SDKManager.getInstance();
|
|
36331
36462
|
if (!sdk.isInitialized()) {
|
|
36332
36463
|
IssueSticker.init(config);
|
|
@@ -36336,9 +36467,7 @@ const IssueSticker = {
|
|
|
36336
36467
|
mountWidgetWhenReady(config);
|
|
36337
36468
|
},
|
|
36338
36469
|
destroy() {
|
|
36339
|
-
|
|
36340
|
-
unmountWidget();
|
|
36341
|
-
SDKManager.resetInstance();
|
|
36470
|
+
destroySdkRuntime();
|
|
36342
36471
|
},
|
|
36343
36472
|
on(event, callback) {
|
|
36344
36473
|
const sdk = SDKManager.getInstance();
|
|
@@ -36356,6 +36485,9 @@ const IssueSticker = {
|
|
|
36356
36485
|
}
|
|
36357
36486
|
}
|
|
36358
36487
|
};
|
|
36488
|
+
if (typeof window !== "undefined") {
|
|
36489
|
+
window.addEventListener(ISSUE_STICKER_EXTENSION_RUNTIME_READY_EVENT, destroySdkRuntime);
|
|
36490
|
+
}
|
|
36359
36491
|
const DESTROY_DELAY_MS = 300;
|
|
36360
36492
|
let activeConsumerCount = 0;
|
|
36361
36493
|
let destroyTimer = null;
|