@tawqi3i/pdf-viewer 0.1.0 → 0.1.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 +298 -73
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
# @tawqi3i/pdf-viewer
|
|
2
2
|
|
|
3
|
-
React PDF viewer and annotation SDK built on [GemBox PDF Viewer](https://www.gemboxsoftware.com/pdf-viewer).
|
|
3
|
+
A React PDF viewer and annotation SDK built on [GemBox PDF Viewer](https://www.gemboxsoftware.com/pdf-viewer) and [pdf-lib](https://pdf-lib.js.org/). Render PDFs, let users place text fields, stamps, and drawn signatures, then flatten them into the document or hand them to your own signing API.
|
|
4
|
+
|
|
5
|
+
- **`PdfAnnotator`** — a complete, drop-in workspace (viewer + toolbar + signature capture). You supply the behavior; it owns the UI.
|
|
6
|
+
- **`PdfViewer`** — a thin display-only wrapper when all you need is to show a PDF.
|
|
7
|
+
- **Building blocks** — `AnnotationLayer`, `AnnotationToolbar`, `SignatureModal`, `useAnnotations`, and PDF utilities to compose your own layout.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Table of contents
|
|
12
|
+
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Vite setup](#vite-setup)
|
|
15
|
+
- [Quick start](#quick-start)
|
|
16
|
+
- [Choosing a level](#choosing-a-level)
|
|
17
|
+
- [`PdfAnnotator`](#pdfannotator)
|
|
18
|
+
- [`PdfViewer`](#pdfviewer)
|
|
19
|
+
- [Building blocks](#building-blocks)
|
|
20
|
+
- [The annotation model](#the-annotation-model)
|
|
21
|
+
- [PDF utilities](#pdf-utilities)
|
|
22
|
+
- [A complete signing example](#a-complete-signing-example)
|
|
23
|
+
- [Theming](#theming)
|
|
24
|
+
- [GemBox license](#gembox-license)
|
|
25
|
+
- [Troubleshooting](#troubleshooting)
|
|
26
|
+
- [API reference](#api-reference)
|
|
27
|
+
|
|
28
|
+
---
|
|
4
29
|
|
|
5
30
|
## Installation
|
|
6
31
|
|
|
@@ -8,9 +33,11 @@ React PDF viewer and annotation SDK built on [GemBox PDF Viewer](https://www.gem
|
|
|
8
33
|
npm install @tawqi3i/pdf-viewer react react-dom
|
|
9
34
|
```
|
|
10
35
|
|
|
11
|
-
|
|
36
|
+
`react` and `react-dom` (v18 or v19) are peer dependencies. `@gembox/pdfviewer` and `pdf-lib` ship as dependencies of the SDK — you don't install them yourself.
|
|
37
|
+
|
|
38
|
+
## Vite setup
|
|
12
39
|
|
|
13
|
-
|
|
40
|
+
The viewer wraps GemBox's PDF engine, which needs a few build tweaks (a pdf.js UMD fix, Vue 3 compile-time flags, and a dependency-optimizer exclusion). The SDK ships a Vite plugin that applies all of them:
|
|
14
41
|
|
|
15
42
|
```js
|
|
16
43
|
// vite.config.js
|
|
@@ -23,110 +50,163 @@ export default defineConfig({
|
|
|
23
50
|
})
|
|
24
51
|
```
|
|
25
52
|
|
|
26
|
-
|
|
53
|
+
Then import the stylesheet once, at your app's entry point:
|
|
27
54
|
|
|
28
55
|
```js
|
|
56
|
+
// main.jsx
|
|
29
57
|
import '@tawqi3i/pdf-viewer/styles.css'
|
|
30
58
|
```
|
|
31
59
|
|
|
32
|
-
|
|
60
|
+
> **Not using Vite?** The plugin is Vite-specific. On other bundlers you must reproduce its effects yourself: define `__VUE_OPTIONS_API__`, `__VUE_PROD_DEVTOOLS__`, and `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__`, leave `@gembox/pdfviewer` un-transpiled, and ensure `window["pdfjs-dist/build/pdf"]` is set. See [`vite-plugin.js`](./vite-plugin.js) for the exact transforms.
|
|
33
61
|
|
|
34
|
-
|
|
62
|
+
## Quick start
|
|
35
63
|
|
|
36
64
|
```jsx
|
|
37
|
-
import { PdfAnnotator
|
|
65
|
+
import { PdfAnnotator } from '@tawqi3i/pdf-viewer'
|
|
66
|
+
import '@tawqi3i/pdf-viewer/styles.css'
|
|
38
67
|
|
|
39
|
-
function App() {
|
|
68
|
+
export default function App() {
|
|
40
69
|
return (
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
onSave={(file, annotations) => {/* download / persist */}}
|
|
45
|
-
onComplete={async (file, annotations) => {
|
|
46
|
-
// e.g. flatten annotations and send to your signing API.
|
|
47
|
-
// Throw to show an error snackbar; resolve to show success.
|
|
48
|
-
const data = await bakeAnnotationsToBase64(file, annotations)
|
|
49
|
-
await fetch('/api/envelopes/seal', {
|
|
50
|
-
method: 'POST',
|
|
51
|
-
headers: { 'Content-Type': 'application/json' },
|
|
52
|
-
body: JSON.stringify({ name: file.name, data }),
|
|
53
|
-
})
|
|
54
|
-
}}
|
|
55
|
-
/>
|
|
70
|
+
<div style={{ height: '100vh' }}>
|
|
71
|
+
<PdfAnnotator />
|
|
72
|
+
</div>
|
|
56
73
|
)
|
|
57
74
|
}
|
|
58
75
|
```
|
|
59
76
|
|
|
60
|
-
|
|
77
|
+
That gives you a working workspace: drag-and-drop or browse to open a PDF, place text/stamp/signature fields, and download a flattened copy from the Save button. Everything below is about wiring it to your own flows.
|
|
78
|
+
|
|
79
|
+
> `PdfAnnotator` fills its parent — always give it a sized container (`height: 100vh`, a flex cell with `min-height: 0`, etc.).
|
|
61
80
|
|
|
62
|
-
|
|
81
|
+
## Choosing a level
|
|
63
82
|
|
|
64
|
-
|
|
|
83
|
+
| You want to… | Use |
|
|
65
84
|
| --- | --- |
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
| Show a workspace where users annotate and you handle save/submit | **`PdfAnnotator`** |
|
|
86
|
+
| Just render a PDF (no annotation UI) | **`PdfViewer`** |
|
|
87
|
+
| Build a bespoke layout with your own toolbar/chrome | **Building blocks** + `useAnnotations` |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## `PdfAnnotator`
|
|
92
|
+
|
|
93
|
+
The turn-key component. It owns all annotation mechanics; your app injects behavior through callbacks and a `header` slot.
|
|
94
|
+
|
|
95
|
+
```jsx
|
|
96
|
+
import { PdfAnnotator, bakeAnnotationsToBase64 } from '@tawqi3i/pdf-viewer'
|
|
97
|
+
|
|
98
|
+
<PdfAnnotator
|
|
99
|
+
className="h-screen"
|
|
100
|
+
header={<img src="/logo.svg" alt="Acme" className="h-8" />}
|
|
101
|
+
onFileChange={(file) => console.log('opened', file?.name)}
|
|
102
|
+
onSave={(file, annotations) => {/* your download/persist logic */}}
|
|
103
|
+
onComplete={async (file, annotations) => {
|
|
104
|
+
// Throw to show an error toast; resolve to show success + clear fields.
|
|
105
|
+
const data = await bakeAnnotationsToBase64(file, annotations)
|
|
106
|
+
await fetch('/api/seal', {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: { 'Content-Type': 'application/json' },
|
|
109
|
+
body: JSON.stringify({ name: file.name, data }),
|
|
110
|
+
})
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### How the two actions differ
|
|
116
|
+
|
|
117
|
+
- **Save** (`onSave`) — always available; think "download / keep a copy." If you don't pass `onSave`, the built-in fallback bakes the placed fields into the PDF and downloads it.
|
|
118
|
+
- **Complete** (`onComplete`) — the primary submit action (seal an envelope, send for signing). The Complete button only renders when you pass `onComplete`, is disabled until there's at least one field with no unsigned text boxes, shows a sending spinner, and clears the fields on success. Errors thrown inside it surface as a toast.
|
|
119
|
+
|
|
120
|
+
### Controlled vs. uncontrolled document
|
|
121
|
+
|
|
122
|
+
- **Uncontrolled** — omit `fileBlob` and let users open files via the built-in drag-drop / browse UI.
|
|
123
|
+
- **Controlled** — pass `fileBlob` (e.g. a file you fetched from a URL). Internal uploads still sync back through `onFileChange`, so you can keep your own copy of the current file for `onSave`/`onComplete`.
|
|
124
|
+
|
|
125
|
+
### Common configurations
|
|
126
|
+
|
|
127
|
+
Display-only (no annotation UI, no upload chrome):
|
|
128
|
+
|
|
129
|
+
```jsx
|
|
130
|
+
<PdfAnnotator fileBlob={blob} readOnly allowFileUpload={false} />
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Remote-loaded document with a spinner and error surface:
|
|
134
|
+
|
|
135
|
+
```jsx
|
|
136
|
+
<PdfAnnotator
|
|
137
|
+
fileBlob={remoteFile} // set once your fetch resolves
|
|
138
|
+
loading={isFetching} // shows a spinner while null
|
|
139
|
+
errorMessage={fetchError} // shown in the empty state
|
|
140
|
+
documentTitle={`Document ${id}`}
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## `PdfViewer`
|
|
147
|
+
|
|
148
|
+
A memoized, display-only wrapper around GemBox. No annotation layer.
|
|
79
149
|
|
|
80
150
|
```jsx
|
|
81
151
|
import { PdfViewer } from '@tawqi3i/pdf-viewer'
|
|
82
152
|
|
|
83
153
|
<PdfViewer
|
|
84
|
-
fileBlob={blob}
|
|
154
|
+
fileBlob={blob} // or fileUrl="https://…/doc.pdf"
|
|
85
155
|
height="100%"
|
|
156
|
+
width="100%"
|
|
86
157
|
visibility={{ open: false, download: false, print: false }}
|
|
158
|
+
onLoad={() => console.log('rendered')}
|
|
87
159
|
onError={(err) => console.error(err)}
|
|
88
160
|
/>
|
|
89
161
|
```
|
|
90
162
|
|
|
163
|
+
`fileBlob` takes precedence over `fileUrl`. Changing either re-opens the document in place. `readOnly` is shorthand for hiding the open/download/print toolbar buttons.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
91
167
|
## Building blocks
|
|
92
168
|
|
|
93
|
-
For custom
|
|
169
|
+
For a custom layout, drive the state with `useAnnotations` and place the pieces yourself. The annotation overlay must live in the **same `position: relative` container** as the viewer — it locates GemBox's rendered pages by their `data-page-number` attributes and tracks them on every frame.
|
|
94
170
|
|
|
95
171
|
```jsx
|
|
96
172
|
import {
|
|
97
173
|
PdfViewer, AnnotationLayer, AnnotationToolbar, SignatureModal,
|
|
98
|
-
useAnnotations,
|
|
174
|
+
useAnnotations,
|
|
99
175
|
} from '@tawqi3i/pdf-viewer'
|
|
100
176
|
|
|
101
|
-
function
|
|
102
|
-
const
|
|
177
|
+
function Workspace({ blob }) {
|
|
178
|
+
const a = useAnnotations()
|
|
179
|
+
|
|
103
180
|
return (
|
|
104
181
|
<div className="relative h-full">
|
|
105
182
|
<PdfViewer fileBlob={blob} height="100%" />
|
|
183
|
+
|
|
106
184
|
<AnnotationLayer
|
|
107
|
-
annotations={
|
|
108
|
-
activeTool={
|
|
109
|
-
pendingSignature={
|
|
110
|
-
onPlace={
|
|
111
|
-
onDelete={
|
|
112
|
-
onMove={
|
|
113
|
-
onResize={
|
|
114
|
-
onTextChange={
|
|
185
|
+
annotations={a.annotations}
|
|
186
|
+
activeTool={a.activeTool}
|
|
187
|
+
pendingSignature={a.pendingSignature}
|
|
188
|
+
onPlace={a.handlePlace}
|
|
189
|
+
onDelete={a.handleDelete}
|
|
190
|
+
onMove={a.handleMove}
|
|
191
|
+
onResize={a.handleResize}
|
|
192
|
+
onTextChange={a.handleTextChange}
|
|
115
193
|
/>
|
|
194
|
+
|
|
116
195
|
<AnnotationToolbar
|
|
117
|
-
activeTool={
|
|
118
|
-
onToolSelect={
|
|
119
|
-
selectedStamp={
|
|
120
|
-
onStampSelect={
|
|
121
|
-
onUndo={
|
|
122
|
-
onClearAll={
|
|
196
|
+
activeTool={a.activeTool}
|
|
197
|
+
onToolSelect={a.handleToolSelect}
|
|
198
|
+
selectedStamp={a.selectedStamp}
|
|
199
|
+
onStampSelect={a.setSelectedStamp}
|
|
200
|
+
onUndo={a.handleUndo}
|
|
201
|
+
onClearAll={a.handleClearAll}
|
|
123
202
|
onSave={() => {/* … */}}
|
|
124
|
-
count={
|
|
203
|
+
count={a.annotations.length}
|
|
125
204
|
/>
|
|
126
|
-
|
|
205
|
+
|
|
206
|
+
{a.showSignatureModal && (
|
|
127
207
|
<SignatureModal
|
|
128
|
-
onConfirm={
|
|
129
|
-
onClose={() =>
|
|
208
|
+
onConfirm={a.handleSignatureConfirm}
|
|
209
|
+
onClose={() => a.setShowSignatureModal(false)}
|
|
130
210
|
/>
|
|
131
211
|
)}
|
|
132
212
|
</div>
|
|
@@ -134,29 +214,174 @@ function CustomWorkspace({ blob }) {
|
|
|
134
214
|
}
|
|
135
215
|
```
|
|
136
216
|
|
|
137
|
-
|
|
217
|
+
`useAnnotations({ stamps })` returns the full state machine — the annotation array, active tool, selected stamp, pending signature, every handler used above, a `reset()`, plus derived `unsignedCount` and a `hint` string. Escape-to-cancel is wired automatically.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## The annotation model
|
|
222
|
+
|
|
223
|
+
Every annotation stores **normalized** coordinates (0–1) relative to its page, so they stay correct at any zoom or page size:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
{
|
|
227
|
+
id: string,
|
|
228
|
+
type: 'text' | 'stamp' | 'Esig', // exported as TOOL.TEXT / TOOL.STAMP / TOOL.SIGNATURE
|
|
229
|
+
pageIndex: number, // 0-based
|
|
230
|
+
normX, normY, normW, normH: number,// fractions of page width/height, top-left origin
|
|
231
|
+
content?: string, // text annotations
|
|
232
|
+
stamp?: { id, label, color?, bg?, imageUrl? }, // stamp annotations
|
|
233
|
+
imageData?: string, // signature — PNG data URL
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Stamps come from `DEFAULT_STAMPS` (APPROVED / REJECTED / REVIEWED / VOID) unless you pass your own `stamps` array to `PdfAnnotator`, `AnnotationToolbar`, or `useAnnotations`. A stamp with an `imageUrl` renders as an image; otherwise it renders its `label` in `color` on `bg`.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## PDF utilities
|
|
242
|
+
|
|
243
|
+
```js
|
|
244
|
+
import {
|
|
245
|
+
bakeAnnotationsToBase64, // flatten annotations into the PDF → base64 string
|
|
246
|
+
annotationsToFields, // annotations → coordinate field objects (PDF points)
|
|
247
|
+
base64ToFile, // base64 → File
|
|
248
|
+
blobToBase64, // Blob → base64 (no data: prefix)
|
|
249
|
+
} from '@tawqi3i/pdf-viewer'
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Two strategies for submitting a signed document:
|
|
253
|
+
|
|
254
|
+
- **Bake it client-side** — `bakeAnnotationsToBase64(file, annotations)` draws the text, stamps, and signatures directly into the PDF with pdf-lib and returns base64. Send that to your backend as the final artifact.
|
|
255
|
+
- **Send coordinates** — `annotationsToFields(file, annotations)` returns `[{ top, left, width, height, pageNumber, type, value }]` in PDF points (top-left origin) for a backend that stamps the fields itself.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## A complete signing example
|
|
260
|
+
|
|
261
|
+
A real page that loads a PDF from a `?file_url=` query param, lets the user sign, seals it against an authenticated API, then swaps in the sealed document and enables download:
|
|
262
|
+
|
|
263
|
+
```jsx
|
|
264
|
+
import { useState, useCallback, useEffect } from 'react'
|
|
265
|
+
import {
|
|
266
|
+
PdfAnnotator, bakeAnnotationsToBase64, base64ToFile,
|
|
267
|
+
} from '@tawqi3i/pdf-viewer'
|
|
268
|
+
import '@tawqi3i/pdf-viewer/styles.css'
|
|
269
|
+
|
|
270
|
+
const qp = (k) => new URLSearchParams(window.location.search).get(k)
|
|
271
|
+
|
|
272
|
+
export default function SignPage({ token }) {
|
|
273
|
+
const [file, setFile] = useState(null)
|
|
274
|
+
const [error, setError] = useState(null)
|
|
275
|
+
const [envelopeId, setEnvelopeId] = useState(null)
|
|
276
|
+
|
|
277
|
+
// Load a remote PDF on mount if ?file_url= is present.
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
const url = qp('file_url')
|
|
280
|
+
if (!url) return
|
|
281
|
+
let cancelled = false
|
|
282
|
+
;(async () => {
|
|
283
|
+
try {
|
|
284
|
+
const res = await fetch(url)
|
|
285
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
|
286
|
+
const blob = await res.blob()
|
|
287
|
+
if (!cancelled) setFile(new File([blob], 'document.pdf', { type: 'application/pdf' }))
|
|
288
|
+
} catch (e) {
|
|
289
|
+
if (!cancelled) setError('Could not load the document.')
|
|
290
|
+
}
|
|
291
|
+
})()
|
|
292
|
+
return () => { cancelled = true }
|
|
293
|
+
}, [])
|
|
294
|
+
|
|
295
|
+
const handleComplete = useCallback(async (f, annotations) => {
|
|
296
|
+
const data = await bakeAnnotationsToBase64(f, annotations)
|
|
297
|
+
const res = await fetch('https://api.example.com/envelopes/seal', {
|
|
298
|
+
method: 'POST',
|
|
299
|
+
headers: {
|
|
300
|
+
'Content-Type': 'application/json',
|
|
301
|
+
Authorization: `Bearer ${token}`,
|
|
302
|
+
},
|
|
303
|
+
body: JSON.stringify({ name: f.name, data }),
|
|
304
|
+
})
|
|
305
|
+
if (!res.ok) throw new Error(`Seal failed (HTTP ${res.status})`)
|
|
306
|
+
const result = await res.json()
|
|
307
|
+
if (!result?.envelopeId) throw new Error('Envelope was not sealed.')
|
|
308
|
+
if (result.data) setFile(base64ToFile(result.data, f.name)) // show sealed copy
|
|
309
|
+
setEnvelopeId(result.envelopeId)
|
|
310
|
+
}, [token])
|
|
311
|
+
|
|
312
|
+
const handleSave = useCallback((f) => {
|
|
313
|
+
if (!envelopeId || !f) return
|
|
314
|
+
const url = URL.createObjectURL(f)
|
|
315
|
+
const a = document.createElement('a')
|
|
316
|
+
a.href = url
|
|
317
|
+
a.download = f.name
|
|
318
|
+
a.click()
|
|
319
|
+
URL.revokeObjectURL(url)
|
|
320
|
+
}, [envelopeId])
|
|
138
321
|
|
|
139
|
-
|
|
322
|
+
return (
|
|
323
|
+
<PdfAnnotator
|
|
324
|
+
className="h-screen"
|
|
325
|
+
fileBlob={file}
|
|
326
|
+
errorMessage={error}
|
|
327
|
+
isSigned={!!envelopeId}
|
|
328
|
+
saveAlwaysEnabled={!!envelopeId}
|
|
329
|
+
labels={{
|
|
330
|
+
completeSuccess: 'Envelope sealed successfully.',
|
|
331
|
+
completeErrorPrefix: 'Failed to seal: ',
|
|
332
|
+
}}
|
|
333
|
+
onFileChange={setFile}
|
|
334
|
+
onComplete={handleComplete}
|
|
335
|
+
onSave={handleSave}
|
|
336
|
+
/>
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
```
|
|
140
340
|
|
|
141
|
-
|
|
142
|
-
- `annotationsToFields(file, annotations)` — convert annotations to coordinate field objects (PDF points) for server-side placement.
|
|
143
|
-
- `base64ToFile(base64, filename)` / `blobToBase64(blob)` — conversion helpers.
|
|
341
|
+
---
|
|
144
342
|
|
|
145
343
|
## Theming
|
|
146
344
|
|
|
147
|
-
The stylesheet ships
|
|
345
|
+
The stylesheet ships the design tokens as CSS custom properties. Re-brand by overriding them anywhere after the import:
|
|
148
346
|
|
|
149
347
|
```css
|
|
150
348
|
:root {
|
|
151
349
|
--color-brand: #7c3aed;
|
|
152
350
|
--color-brand-dark: #5b21b6;
|
|
351
|
+
--color-brand-subtle: #ede9fe;
|
|
352
|
+
--font-sans: "Inter", system-ui, sans-serif;
|
|
153
353
|
}
|
|
154
354
|
```
|
|
155
355
|
|
|
156
|
-
The stylesheet contains no CSS reset/preflight
|
|
356
|
+
The stylesheet contains **no CSS reset / preflight**, so it won't touch your app's base styles. Full token list: `--color-brand[-dark|-light|-subtle]`, `--color-page`, `--color-surface[-muted]`, `--color-stroke`, `--color-ink[-muted|-disabled]`, `--color-danger[-dark]`, `--color-success[-dark]`, `--color-warning[-dark]`, `--font-sans`.
|
|
357
|
+
|
|
358
|
+
## GemBox license
|
|
359
|
+
|
|
360
|
+
The viewer runs on GemBox's free evaluation key by default (`"FREE-LIMITED-KEY"`), which shows a small watermark and has page limits. Pass a purchased key via the `licenseKey` prop on `PdfViewer` / `PdfAnnotator`. The key is set once, globally, on first render.
|
|
361
|
+
|
|
362
|
+
## Troubleshooting
|
|
363
|
+
|
|
364
|
+
**"Pdf.js needs to be referenced" / blank viewer.** The Vite plugin isn't applied. Add `tawqi3iPdfViewer()` to your `plugins` and restart the dev server (delete `node_modules/.vite` if it was cached).
|
|
365
|
+
|
|
366
|
+
**Components render unstyled.** You didn't import `@tawqi3i/pdf-viewer/styles.css`, or your bundler tree-shook it — import it at your entry point.
|
|
367
|
+
|
|
368
|
+
**Annotations drift from the page.** The `AnnotationLayer` must be a sibling of the viewer inside a `position: relative` container that wraps both. Don't put other positioned/scrolling elements between them.
|
|
369
|
+
|
|
370
|
+
**Two React copies / hook errors in a monorepo.** Ensure a single `react` instance (dedupe it in your bundler). `react`/`react-dom` are peer deps for this reason.
|
|
371
|
+
|
|
372
|
+
## API reference
|
|
373
|
+
|
|
374
|
+
Full TypeScript definitions ship with the package ([`index.d.ts`](./index.d.ts)) and power editor autocomplete. Public exports:
|
|
375
|
+
|
|
376
|
+
- **Components** — `PdfAnnotator`, `PdfViewer`, `AnnotationLayer`, `AnnotationItem`, `AnnotationToolbar`, `ToolBtn`, `SignatureModal`, `StampPicker`, `Snackbar`, `EmptyState`
|
|
377
|
+
- **Hook** — `useAnnotations`
|
|
378
|
+
- **Utilities** — `bakeAnnotationsToBase64`, `annotationsToFields`, `blobToBase64`, `base64ToFile`, `dataUrlToBytes`, `stripDataUrl`, `hexToRgb01`, `makeUuid`
|
|
379
|
+
- **Constants** — `TOOL`, `DEFAULT_STAMPS`, `SNACKBAR_VARIANTS`
|
|
380
|
+
- **DOM helpers** — `findPageElementAt`, `findPageElementByIndex`
|
|
381
|
+
- **Icons** — `PdfIcon`, `UploadIcon`, `CloseIcon`, `SaveIcon`, `SendIcon`, … (all inline SVG, accept `className`)
|
|
382
|
+
- **Vite plugin** — `@tawqi3i/pdf-viewer/vite`
|
|
383
|
+
- **Styles** — `@tawqi3i/pdf-viewer/styles.css`
|
|
157
384
|
|
|
158
|
-
##
|
|
385
|
+
## License
|
|
159
386
|
|
|
160
|
-
|
|
161
|
-
- `npm run build` — build the library to `dist/`
|
|
162
|
-
- `npm run dev:lib` — rebuild on change (for workspace consumers)
|
|
387
|
+
MIT
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:"Readex Pro", "Inter var", "Noto Sans Arabic", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-400:oklch(85.2% .199 91.936);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-black:900;--tracking-normal:0em;--tracking-widest:.1em;--leading-normal:1.5;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--color-brand:#0877d0;--color-brand-dark:#005a9e;--color-brand-light:#71afe5;--color-brand-subtle:#daebf8;--color-page:#edf0f6;--color-surface:#fff;--color-surface-muted:#f3f3f3;--color-stroke:#e2e8f0;--color-ink:#111827;--color-ink-muted:#6b7280;--color-ink-disabled:#959ca9;--color-danger:#f44336;--color-danger-dark:#b71c1c;--color-success:#4caf50;--color-success-dark:#388e3c;--color-warning:#ff9800;--color-warning-dark:#e65100}}@layer base,components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.-top-2\.5{top:calc(var(--spacing) * -2.5)}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.-right-1{right:calc(var(--spacing) * -1)}.-right-2\.5{right:calc(var(--spacing) * -2.5)}.right-3{right:calc(var(--spacing) * 3)}.right-6{right:calc(var(--spacing) * 6)}.right-11{right:calc(var(--spacing) * 11)}.-bottom-1{bottom:calc(var(--spacing) * -1)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:var(--spacing)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-4\.5{height:calc(var(--spacing) * 4.5)}.h-5{height:calc(var(--spacing) * 5)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-16{height:calc(var(--spacing) * 16)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-8{max-height:calc(var(--spacing) * 8)}.max-h-40{max-height:calc(var(--spacing) * 40)}.min-h-0{min-height:0}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-4\.5{width:calc(var(--spacing) * 4.5)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-16{width:calc(var(--spacing) * 16)}.w-32{width:calc(var(--spacing) * 32)}.w-64{width:calc(var(--spacing) * 64)}.w-80{width:calc(var(--spacing) * 80)}.w-130{width:calc(var(--spacing) * 130)}.w-full{width:100%}.w-px{width:1px}.max-w-80{max-width:calc(var(--spacing) * 80)}.max-w-\[95vw\]{max-width:95vw}.max-w-fit{max-width:fit-content}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.flex-1{flex:1}.flex-auto{flex:auto}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-105{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[3px\]{border-style:var(--tw-border-style);border-width:3px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-brand{border-color:var(--color-brand)}.border-brand-light\/40{border-color:#71afe566}@supports (color:color-mix(in lab,red,red)){.border-brand-light\/40{border-color:color-mix(in oklab,var(--color-brand-light) 40%,transparent)}}.border-danger\/30{border-color:#f443364d}@supports (color:color-mix(in lab,red,red)){.border-danger\/30{border-color:color-mix(in oklab,var(--color-danger) 30%,transparent)}}.border-stroke{border-color:var(--color-stroke)}.border-warning\/40{border-color:#ff980066}@supports (color:color-mix(in lab,red,red)){.border-warning\/40{border-color:color-mix(in oklab,var(--color-warning) 40%,transparent)}}.border-white{border-color:var(--color-white)}.border-yellow-400{border-color:var(--color-yellow-400)}.bg-brand{background-color:var(--color-brand)}.bg-brand-subtle{background-color:var(--color-brand-subtle)}.bg-danger{background-color:var(--color-danger)}.bg-danger\/10{background-color:#f443361a}@supports (color:color-mix(in lab,red,red)){.bg-danger\/10{background-color:color-mix(in oklab,var(--color-danger) 10%,transparent)}}.bg-ink\/40{background-color:#11182766}@supports (color:color-mix(in lab,red,red)){.bg-ink\/40{background-color:color-mix(in oklab,var(--color-ink) 40%,transparent)}}.bg-page{background-color:var(--color-page)}.bg-stroke{background-color:var(--color-stroke)}.bg-success{background-color:var(--color-success)}.bg-surface{background-color:var(--color-surface)}.bg-surface-muted{background-color:var(--color-surface-muted)}.bg-surface\/95{background-color:#fffffff2}@supports (color:color-mix(in lab,red,red)){.bg-surface\/95{background-color:color-mix(in oklab,var(--color-surface) 95%,transparent)}}.bg-warning\/15{background-color:#ff980026}@supports (color:color-mix(in lab,red,red)){.bg-warning\/15{background-color:color-mix(in oklab,var(--color-warning) 15%,transparent)}}.bg-yellow-50{background-color:var(--color-yellow-50)}.object-contain{object-fit:contain}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-12{padding:calc(var(--spacing) * 12)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-\[2\.5px\]{padding-block:2.5px}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.wrap-break-word{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#424242\]{color:#424242}.text-brand{color:var(--color-brand)}.text-danger{color:var(--color-danger)}.text-danger-dark{color:var(--color-danger-dark)}.text-ink{color:var(--color-ink)}.text-ink-disabled{color:var(--color-ink-disabled)}.text-ink-muted{color:var(--color-ink-muted)}.text-success{color:var(--color-success)}.text-warning-dark{color:var(--color-warning-dark)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-current{--tw-ring-color:currentcolor}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ring-offset-surface{--tw-ring-offset-color:var(--color-surface)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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{--tw-backdrop-blur:blur(8px);-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,)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-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,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-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-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:scale-\[1\.03\]:hover{scale:1.03}.hover\:border-brand:hover{border-color:var(--color-brand)}.hover\:border-ink-muted:hover{border-color:var(--color-ink-muted)}.hover\:bg-brand-dark:hover{background-color:var(--color-brand-dark)}.hover\:bg-brand-subtle:hover{background-color:var(--color-brand-subtle)}.hover\:bg-danger\/10:hover{background-color:#f443361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-danger\/10:hover{background-color:color-mix(in oklab,var(--color-danger) 10%,transparent)}}.hover\:bg-ink\/10:hover{background-color:#1118271a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-ink\/10:hover{background-color:color-mix(in oklab,var(--color-ink) 10%,transparent)}}.hover\:bg-success-dark:hover{background-color:var(--color-success-dark)}.hover\:bg-success\/10:hover{background-color:#4caf501a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-success\/10:hover{background-color:color-mix(in oklab,var(--color-success) 10%,transparent)}}.hover\:bg-surface-muted:hover{background-color:var(--color-surface-muted)}.hover\:text-brand:hover{color:var(--color-brand)}.hover\:text-brand-dark:hover{color:var(--color-brand-dark)}.hover\:text-danger:hover{color:var(--color-danger)}.hover\:text-ink:hover{color:var(--color-ink)}.hover\:text-success-dark:hover{color:var(--color-success-dark)}.hover\:opacity-100:hover{opacity:1}}.active\:bg-brand-dark:active{background-color:var(--color-brand-dark)}.active\:bg-success-dark:active{background-color:var(--color-success-dark)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-surface-muted:disabled{background-color:var(--color-surface-muted)}.disabled\:text-ink-disabled:disabled{color:var(--color-ink-disabled)}.disabled\:opacity-25:disabled{opacity:.25}.rtl\:right-auto:where(:dir(rtl),[dir=rtl],[dir=rtl] *){right:auto}.rtl\:left-6:where(:dir(rtl),[dir=rtl],[dir=rtl] *){left:calc(var(--spacing) * 6)}.rtl\:mr-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:0}.rtl\:ml-2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-left:calc(var(--spacing) * 2)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|
|
1
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:"Readex Pro", "Inter var", "Noto Sans Arabic", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-400:oklch(85.2% .199 91.936);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-black:900;--tracking-normal:0em;--tracking-widest:.1em;--leading-normal:1.5;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--color-brand:#0877d0;--color-brand-dark:#005a9e;--color-brand-light:#71afe5;--color-brand-subtle:#daebf8;--color-page:#edf0f6;--color-surface:#fff;--color-surface-muted:#f3f3f3;--color-stroke:#e2e8f0;--color-ink:#111827;--color-ink-muted:#6b7280;--color-ink-disabled:#959ca9;--color-danger:#f44336;--color-danger-dark:#b71c1c;--color-success:#4caf50;--color-success-dark:#388e3c;--color-warning:#ff9800;--color-warning-dark:#e65100}}@layer base,components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.-top-2\.5{top:calc(var(--spacing) * -2.5)}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.-right-1{right:calc(var(--spacing) * -1)}.-right-2\.5{right:calc(var(--spacing) * -2.5)}.right-3{right:calc(var(--spacing) * 3)}.right-6{right:calc(var(--spacing) * 6)}.right-11{right:calc(var(--spacing) * 11)}.-bottom-1{bottom:calc(var(--spacing) * -1)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:var(--spacing)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-4\.5{height:calc(var(--spacing) * 4.5)}.h-5{height:calc(var(--spacing) * 5)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-16{height:calc(var(--spacing) * 16)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-8{max-height:calc(var(--spacing) * 8)}.max-h-40{max-height:calc(var(--spacing) * 40)}.min-h-0{min-height:0}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-4\.5{width:calc(var(--spacing) * 4.5)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-16{width:calc(var(--spacing) * 16)}.w-32{width:calc(var(--spacing) * 32)}.w-64{width:calc(var(--spacing) * 64)}.w-80{width:calc(var(--spacing) * 80)}.w-130{width:calc(var(--spacing) * 130)}.w-full{width:100%}.w-px{width:1px}.max-w-80{max-width:calc(var(--spacing) * 80)}.max-w-\[95vw\]{max-width:95vw}.max-w-fit{max-width:fit-content}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.flex-1{flex:1}.flex-auto{flex:auto}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-105{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[3px\]{border-style:var(--tw-border-style);border-width:3px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-brand{border-color:var(--color-brand)}.border-brand-light\/40{border-color:#71afe566}@supports (color:color-mix(in lab,red,red)){.border-brand-light\/40{border-color:color-mix(in oklab,var(--color-brand-light) 40%,transparent)}}.border-danger\/30{border-color:#f443364d}@supports (color:color-mix(in lab,red,red)){.border-danger\/30{border-color:color-mix(in oklab,var(--color-danger) 30%,transparent)}}.border-stroke{border-color:var(--color-stroke)}.border-warning\/40{border-color:#ff980066}@supports (color:color-mix(in lab,red,red)){.border-warning\/40{border-color:color-mix(in oklab,var(--color-warning) 40%,transparent)}}.border-white{border-color:var(--color-white)}.border-yellow-400{border-color:var(--color-yellow-400)}.bg-brand{background-color:var(--color-brand)}.bg-brand-subtle{background-color:var(--color-brand-subtle)}.bg-danger{background-color:var(--color-danger)}.bg-danger\/10{background-color:#f443361a}@supports (color:color-mix(in lab,red,red)){.bg-danger\/10{background-color:color-mix(in oklab,var(--color-danger) 10%,transparent)}}.bg-ink\/40{background-color:#11182766}@supports (color:color-mix(in lab,red,red)){.bg-ink\/40{background-color:color-mix(in oklab,var(--color-ink) 40%,transparent)}}.bg-page{background-color:var(--color-page)}.bg-stroke{background-color:var(--color-stroke)}.bg-success{background-color:var(--color-success)}.bg-surface{background-color:var(--color-surface)}.bg-surface-muted{background-color:var(--color-surface-muted)}.bg-surface\/95{background-color:#fffffff2}@supports (color:color-mix(in lab,red,red)){.bg-surface\/95{background-color:color-mix(in oklab,var(--color-surface) 95%,transparent)}}.bg-warning\/15{background-color:#ff980026}@supports (color:color-mix(in lab,red,red)){.bg-warning\/15{background-color:color-mix(in oklab,var(--color-warning) 15%,transparent)}}.bg-yellow-50{background-color:var(--color-yellow-50)}.object-contain{object-fit:contain}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-12{padding:calc(var(--spacing) * 12)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-\[2\.5px\]{padding-block:2.5px}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.wrap-break-word{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#424242\]{color:#424242}.text-brand{color:var(--color-brand)}.text-danger{color:var(--color-danger)}.text-danger-dark{color:var(--color-danger-dark)}.text-ink{color:var(--color-ink)}.text-ink-disabled{color:var(--color-ink-disabled)}.text-ink-muted{color:var(--color-ink-muted)}.text-success{color:var(--color-success)}.text-warning-dark{color:var(--color-warning-dark)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-current{--tw-ring-color:currentcolor}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ring-offset-surface{--tw-ring-offset-color:var(--color-surface)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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{--tw-backdrop-blur:blur(8px);-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,)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-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,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-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-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:scale-\[1\.03\]:hover{scale:1.03}.hover\:border-brand:hover{border-color:var(--color-brand)}.hover\:border-ink-muted:hover{border-color:var(--color-ink-muted)}.hover\:bg-brand-dark:hover{background-color:var(--color-brand-dark)}.hover\:bg-brand-subtle:hover{background-color:var(--color-brand-subtle)}.hover\:bg-danger\/10:hover{background-color:#f443361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-danger\/10:hover{background-color:color-mix(in oklab,var(--color-danger) 10%,transparent)}}.hover\:bg-ink\/10:hover{background-color:#1118271a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-ink\/10:hover{background-color:color-mix(in oklab,var(--color-ink) 10%,transparent)}}.hover\:bg-success-dark:hover{background-color:var(--color-success-dark)}.hover\:bg-success\/10:hover{background-color:#4caf501a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-success\/10:hover{background-color:color-mix(in oklab,var(--color-success) 10%,transparent)}}.hover\:bg-surface-muted:hover{background-color:var(--color-surface-muted)}.hover\:text-brand:hover{color:var(--color-brand)}.hover\:text-brand-dark:hover{color:var(--color-brand-dark)}.hover\:text-danger:hover{color:var(--color-danger)}.hover\:text-ink:hover{color:var(--color-ink)}.hover\:text-success-dark:hover{color:var(--color-success-dark)}.hover\:opacity-100:hover{opacity:1}}.active\:bg-brand-dark:active{background-color:var(--color-brand-dark)}.active\:bg-success-dark:active{background-color:var(--color-success-dark)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-surface-muted:disabled{background-color:var(--color-surface-muted)}.disabled\:text-ink-disabled:disabled{color:var(--color-ink-disabled)}.disabled\:opacity-25:disabled{opacity:.25}.rtl\:right-auto:where(:dir(rtl),[dir=rtl],[dir=rtl] *){right:auto}.rtl\:left-6:where(:dir(rtl),[dir=rtl],[dir=rtl] *){left:calc(var(--spacing) * 6)}.rtl\:mr-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:0}.rtl\:ml-2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-left:calc(var(--spacing) * 2)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|
package/package.json
CHANGED