@teriusu/rich-editor 0.9.9 → 0.9.11
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PdfBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/PdfBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,UAAU,EAAmB,MAAM,cAAc,CAAC;AAKnE,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"PdfBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/PdfBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,UAAU,EAAmB,MAAM,cAAc,CAAC;AAKnE,eAAO,MAAM,QAAQ,sBAwnBnB,CAAC"}
|
|
@@ -151,45 +151,58 @@ export const PdfBlock = TiptapNode.create({
|
|
|
151
151
|
...patch,
|
|
152
152
|
}));
|
|
153
153
|
};
|
|
154
|
-
|
|
154
|
+
/*
|
|
155
|
+
* ── 배율 프리셋 ────────────────────────────────────────────────────
|
|
156
|
+
*
|
|
157
|
+
* ⚠️ 이 칩들은 한때 **칼럼 대비 비율**(`width: 50%`)을 썼다. 그게 틀린 축이었다.
|
|
158
|
+
* 저자가 고르는 건 "칼럼의 절반"이 아니라 "이 정도 크기로 보였으면"인데, 칼럼 폭은
|
|
159
|
+
* 화면마다 다르다 — 문제 편집 화면은 1378px 이지만 코딩 패널 안에서는 훨씬 좁고,
|
|
160
|
+
* 거기서 같은 50% 는 절반 이하로 줄어든다. 저장된 값이 **보는 곳마다 다른 크기**가
|
|
161
|
+
* 된다는 뜻이다. (손잡이 드래그는 원래부터 px 로 저장하고 있었으니 한 문서 안에
|
|
162
|
+
* 두 체계가 섞여 있기도 했다.)
|
|
163
|
+
*
|
|
164
|
+
* 기준은 **PDF 본문 글자가 화면에서 몇 px 로 그려지느냐**다 — 그게 곧 읽히느냐다.
|
|
165
|
+
* pdf.js 는 배율 1 에서 1 PDF 단위 = 1 CSS px 이라 그대로 환산된다:
|
|
166
|
+
*
|
|
167
|
+
* 배율 A4 세로 폭 10pt 본문 쓸모
|
|
168
|
+
* 50% 298px 5px 썸네일(읽기 불가)
|
|
169
|
+
* 75% 446px 7.5px 도표 파악 · 가로형 슬라이드는 읽힘
|
|
170
|
+
* 100% 595px 10px 읽을 수 있음(작음) — 기준점
|
|
171
|
+
* 150% 893px 15px 편하게 읽음
|
|
172
|
+
*
|
|
173
|
+
* 배율은 **페이지 원본 크기 기준**이라 방향·용지 크기를 알아서 반영한다. 같은 칩이
|
|
174
|
+
* 세로형에는 595px, 가로형에는 842px 을 준다 — 글자 크기가 같으니 맞는 결과다.
|
|
175
|
+
* (폭 기준이던 시절 세로형이 부당하게 커 보이던 것이 이래서였다.)
|
|
176
|
+
*
|
|
177
|
+
* ⚠️ `폭맞춤`(칼럼 채우기)은 **일부러 뺐다.** 1378px 칼럼에서 세로형에 걸면 배율
|
|
178
|
+
* 231%, 높이 1950px 로 화면 밖으로 나간다 — 저자 의도가 아니라 우연히 나오는 값이다.
|
|
179
|
+
*/
|
|
155
180
|
const PRESET_IDLE = "pdf-preset";
|
|
156
181
|
const PRESET_ACTIVE = "pdf-preset is-active";
|
|
182
|
+
const ZOOMS = [0.5, 0.75, 1, 1.5];
|
|
157
183
|
const presetButtons = [];
|
|
184
|
+
/** 페이지 원본 폭(CSS px). PDF 를 읽기 전에는 모른다. */
|
|
185
|
+
let naturalWidth = 0;
|
|
186
|
+
/** 배율 → 저장할 px. 원본 폭을 아직 모르면 `null`. */
|
|
187
|
+
const zoomToWidth = (zoom) => naturalWidth > 0 ? `${Math.round(naturalWidth * zoom)}px` : null;
|
|
158
188
|
if (editor.isEditable) {
|
|
159
189
|
/*
|
|
160
|
-
* ⚠️ 프리셋은 **문서에 저장되는
|
|
161
|
-
* 성격이 달라(저장됨 vs 그때뿐) 구분선으로 갈라
|
|
162
|
-
* 확대되겠지" 로 읽힌다.
|
|
190
|
+
* ⚠️ 프리셋은 **문서에 저장되는 크기**이지 보기 상태가 아니다. 옆의 다운로드·새 탭과
|
|
191
|
+
* 성격이 달라(저장됨 vs 그때뿐) 구분선으로 갈라 둔다.
|
|
163
192
|
*/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
* 페이지 높이 = 폭 × 비율이고, A4 는 세로형 1.41 / 가로형 0.71 이다.
|
|
167
|
-
* 정올 실측(본문 칼럼 1378px, 뷰포트 1221px, 상단 고정물 113px → 쓸 높이 1108px):
|
|
168
|
-
*
|
|
169
|
-
* 폭 세로형 높이 가로형 높이
|
|
170
|
-
* 100% 1950 (화면 밖) 974 (들어감)
|
|
171
|
-
* 75% 1462 (화면 밖) 730 (들어감)
|
|
172
|
-
* 50% 975 (딱 맞음) 487
|
|
173
|
-
* 25% 487 243
|
|
174
|
-
*
|
|
175
|
-
* 즉 **세로형의 50% 가 가로형의 100% 와 같은 화면 높이**다 — 두 방향을 한 사다리로
|
|
176
|
-
* 덮으려면 "절반" 단이 반드시 있어야 한다.
|
|
177
|
-
*
|
|
178
|
-
* 25% 는 한때 "글자를 못 읽어 고를 이유가 없다"고 뺐다가 되살렸다. 그 판단은
|
|
179
|
-
* **읽는 단만 상정한 것**이었다. 25% 는 읽는 단이 아니라 **썸네일 단**이다 —
|
|
180
|
-
* 세로형에서 487px 이면 문단 사이에 끼워도 글 흐름을 안 끊고, 자세히 볼 땐
|
|
181
|
-
* `새 탭에서 열기` 가 받는다.
|
|
182
|
-
*/
|
|
183
|
-
for (const value of ["25%", "50%", "75%", "100%"]) {
|
|
193
|
+
for (const zoom of ZOOMS) {
|
|
194
|
+
const label = `${zoom * 100}%`;
|
|
184
195
|
const btn = document.createElement("button");
|
|
185
196
|
btn.type = "button";
|
|
186
197
|
btn.className = PRESET_IDLE;
|
|
187
|
-
btn.title =
|
|
188
|
-
btn.textContent =
|
|
198
|
+
btn.title = `페이지 원본 크기의 ${label}`;
|
|
199
|
+
btn.textContent = label;
|
|
200
|
+
// 원본 폭을 알기 전(로딩 중)에는 누를 수 없다 — 계산할 근거가 없다.
|
|
201
|
+
btn.disabled = true;
|
|
189
202
|
/*
|
|
190
203
|
* ⚠️ `mousedown` 에서 기본 동작을 막는다. 안 막으면 브라우저가 여기서 텍스트 선택을
|
|
191
|
-
* 시작하고, 곧바로 `setAttrs` 가 NodeView 를 다시 그리면서 그 선택이
|
|
192
|
-
* 번져
|
|
204
|
+
* 시작하고, 곧바로 `setAttrs` 가 NodeView 를 다시 그리면서 그 선택이 **조작부 전체**로
|
|
205
|
+
* 번져 칩·버튼이 통째로 파랗게 칠해졌다(사용자 지적).
|
|
193
206
|
* 클릭 자체는 `click` 에서 처리하므로 동작에는 영향이 없다.
|
|
194
207
|
*/
|
|
195
208
|
btn.addEventListener("mousedown", (e) => {
|
|
@@ -199,20 +212,32 @@ export const PdfBlock = TiptapNode.create({
|
|
|
199
212
|
btn.addEventListener("click", (e) => {
|
|
200
213
|
e.preventDefault();
|
|
201
214
|
e.stopPropagation();
|
|
202
|
-
|
|
215
|
+
const next = zoomToWidth(zoom);
|
|
216
|
+
if (next)
|
|
217
|
+
setAttrs({ width: next });
|
|
203
218
|
});
|
|
204
219
|
endCluster.appendChild(btn);
|
|
205
|
-
presetButtons.push({
|
|
220
|
+
presetButtons.push({ zoom, el: btn });
|
|
206
221
|
}
|
|
207
222
|
const divider = document.createElement("div");
|
|
208
223
|
divider.className = "pdf-divider";
|
|
209
224
|
endCluster.appendChild(divider);
|
|
210
225
|
}
|
|
211
|
-
/**
|
|
226
|
+
/**
|
|
227
|
+
* 현재 `width` 와 같은 프리셋을 눌린 상태로 만든다.
|
|
228
|
+
*
|
|
229
|
+
* ⚠️ 문자열 비교로는 안 된다. 저장값이 `"893px"` 처럼 계산된 px 라 반올림 오차가
|
|
230
|
+
* 있고, 손잡이로 끌면 아무 px 이나 들어온다. 1px 여유로 견준다.
|
|
231
|
+
* 옛 문서의 `"50%"` 같은 값은 어느 칩과도 안 맞는다 — **그대로 두는 게 맞다.**
|
|
232
|
+
* 저자가 다시 고를 때까지 예전 크기로 렌더되고, 스키마는 건드리지 않는다.
|
|
233
|
+
*/
|
|
212
234
|
const syncPresets = (width) => {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
235
|
+
const px = width?.endsWith("px") ? Number.parseFloat(width) : NaN;
|
|
236
|
+
for (const { zoom, el } of presetButtons) {
|
|
237
|
+
const target = naturalWidth > 0 ? naturalWidth * zoom : NaN;
|
|
238
|
+
const on = Number.isFinite(px) && Math.abs(px - target) <= 1;
|
|
239
|
+
el.className = on ? PRESET_ACTIVE : PRESET_IDLE;
|
|
240
|
+
el.setAttribute("aria-pressed", on ? "true" : "false");
|
|
216
241
|
}
|
|
217
242
|
};
|
|
218
243
|
syncPresets(node.attrs.width ?? null);
|
|
@@ -450,6 +475,19 @@ export const PdfBlock = TiptapNode.create({
|
|
|
450
475
|
if (destroyed)
|
|
451
476
|
return;
|
|
452
477
|
totalPages = pdfDoc.numPages;
|
|
478
|
+
/*
|
|
479
|
+
* 배율 프리셋의 기준점 — **1쪽의 원본 폭**. pdf.js 는 배율 1 에서
|
|
480
|
+
* 1 PDF 단위 = 1 CSS px 이므로 이 값이 곧 "원본 크기"다.
|
|
481
|
+
* 쪽마다 크기가 다른 문서가 있지만, 저자가 블록 크기를 고르는 기준은 하나여야
|
|
482
|
+
* 하므로 1쪽으로 고정한다(넘길 때마다 블록이 들썩이면 안 된다).
|
|
483
|
+
*/
|
|
484
|
+
const firstPage = await pdfDoc.getPage(1);
|
|
485
|
+
if (destroyed)
|
|
486
|
+
return;
|
|
487
|
+
naturalWidth = firstPage.getViewport({ scale: 1 }).width;
|
|
488
|
+
for (const { el } of presetButtons)
|
|
489
|
+
el.disabled = false;
|
|
490
|
+
syncPresets(currentNode.attrs.width ?? null);
|
|
453
491
|
statusDiv.style.display = "none";
|
|
454
492
|
canvas.style.display = "";
|
|
455
493
|
// \uD55C \uC7A5\uC9DC\uB9AC\uC5D4 \uB118\uAE40 \uC870\uC791\uC744 \uC544\uC608 \uBD99\uC774\uC9C0 \uC54A\uB294\uB2E4 \u2014 \uB204\uB97C \uC218 \uC5C6\uB294 \uBC84\uD2BC\uC740 \uC18C\uC74C\uC774\uB2E4.
|
|
@@ -518,11 +556,24 @@ export const PdfBlock = TiptapNode.create({
|
|
|
518
556
|
if (updatedNode.type.name !== "pdfBlock")
|
|
519
557
|
return false;
|
|
520
558
|
const newWidth = updatedNode.attrs.width;
|
|
521
|
-
|
|
559
|
+
const changed = newWidth !== currentNode.attrs.width;
|
|
560
|
+
if (changed)
|
|
522
561
|
dom.style.width = newWidth || "";
|
|
523
|
-
}
|
|
524
562
|
currentNode = updatedNode;
|
|
525
563
|
syncPresets(newWidth ?? null);
|
|
564
|
+
/*
|
|
565
|
+
* ⚠️ **크기가 바뀌면 여기서 직접 다시 그린다.** 예전엔 `ResizeObserver` 가
|
|
566
|
+
* 알아서 잡아 주길 기대했는데, 그건 크기를 **누가 바꿨는지 모를 때**를 위한
|
|
567
|
+
* 장치다. 프리셋 클릭·드래그 커밋은 새 폭을 이미 알고 들어오는 경로이므로
|
|
568
|
+
* 관찰자를 한 바퀴 돌 이유가 없다.
|
|
569
|
+
*
|
|
570
|
+
* 실제로 이것 때문에 프리셋이 조용히 반쪽만 동작했다 — 블록 폭은 595px 로
|
|
571
|
+
* 줄었는데 캔버스는 1376px 그대로였다. (자동화 탭은 `visibilityState: hidden`
|
|
572
|
+
* 이라 `ResizeObserver` 콜백이 아예 안 와서 오래 못 잡은 증상이기도 하다.)
|
|
573
|
+
* `frame.clientWidth` 는 읽는 순간 레이아웃을 강제하므로 새 폭이 바로 잡힌다.
|
|
574
|
+
*/
|
|
575
|
+
if (changed)
|
|
576
|
+
renderPage();
|
|
526
577
|
return true;
|
|
527
578
|
},
|
|
528
579
|
// 이름 입력칸 위의 이벤트는 ProseMirror 가 가로채면 안 된다(CardBlock 과 같은 방식).
|
|
@@ -530,8 +581,15 @@ export const PdfBlock = TiptapNode.create({
|
|
|
530
581
|
const target = event.target;
|
|
531
582
|
return target instanceof Element && !!target.closest("[data-pdf-control]");
|
|
532
583
|
},
|
|
533
|
-
|
|
534
|
-
|
|
584
|
+
/*
|
|
585
|
+
* ⚠️ 여기 `selectNode`/`deselectNode` 를 빈 함수로 두면 안 된다.
|
|
586
|
+
*
|
|
587
|
+
* ProseMirror 는 이 훅이 **있으면** "노드뷰가 알아서 표시하겠다"로 보고
|
|
588
|
+
* `ProseMirror-selectednode` 클래스를 **아예 붙이지 않는다.** 빈 함수라도 마찬가지라,
|
|
589
|
+
* 선택 표시를 CSS 로 아무리 써도 매칭될 선택자가 생기지 않는다 — 편집 중 PDF 를
|
|
590
|
+
* 클릭해도 아무 표시가 없던 이유가 이것이었다(사용자 지적).
|
|
591
|
+
* 훅을 아예 두지 않으면 클래스 관리는 ProseMirror 가 한다.
|
|
592
|
+
*/
|
|
535
593
|
destroy: () => {
|
|
536
594
|
destroyed = true;
|
|
537
595
|
clearTimeout(resizeTimeout);
|
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
import { describe, it, expect, afterEach } from 'vitest';
|
|
1
|
+
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { Editor } from '@tiptap/core';
|
|
4
4
|
import StarterKit from '@tiptap/starter-kit';
|
|
5
5
|
import { PdfBlock } from './PdfBlock';
|
|
6
|
+
/**
|
|
7
|
+
* pdf.js 를 세워 둔다. 배율 프리셋은 **페이지 원본 폭**을 알아야 값을 계산하므로,
|
|
8
|
+
* 문서를 못 읽으면 그 경로 자체를 테스트할 수 없다. 기본은 A4 세로 3쪽이고,
|
|
9
|
+
* 방향에 따른 차이를 보려고 `PAGE` 를 바꿀 수 있게 뒀다(`vi.hoisted` — `vi.mock` 이
|
|
10
|
+
* 파일 맨 위로 끌어올려져서 보통 `const` 는 아직 초기화 전이다).
|
|
11
|
+
*/
|
|
12
|
+
const PAGE = vi.hoisted(() => ({ w: 595.28, h: 841.89 }));
|
|
13
|
+
const A4_WIDTH = 595.28;
|
|
14
|
+
const A4_LANDSCAPE_WIDTH = 841.89;
|
|
15
|
+
vi.mock('../utils/pdf', () => ({
|
|
16
|
+
getPdfJs: async () => ({
|
|
17
|
+
getDocument: () => ({
|
|
18
|
+
promise: Promise.resolve({
|
|
19
|
+
numPages: 3,
|
|
20
|
+
getPage: async () => ({
|
|
21
|
+
getViewport: ({ scale }) => ({
|
|
22
|
+
width: PAGE.w * scale,
|
|
23
|
+
height: PAGE.h * scale
|
|
24
|
+
}),
|
|
25
|
+
render: () => ({ promise: Promise.resolve() })
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
}));
|
|
6
31
|
describe('PdfBlock extension', () => {
|
|
7
32
|
let editor;
|
|
8
33
|
function createEditor(content = '<p></p>') {
|
|
@@ -105,11 +130,32 @@ describe('PdfBlock extension', () => {
|
|
|
105
130
|
const kinds = [...frame.children].map((c) => c.tagName === 'CANVAS' ? 'canvas' : c.className);
|
|
106
131
|
expect(kinds).toEqual(['canvas', 'pdf-status', 'pdf-overlay']);
|
|
107
132
|
});
|
|
108
|
-
|
|
133
|
+
/** 프리셋이 눌릴 수 있을 때까지 — 원본 폭을 읽어야 활성화된다. */
|
|
134
|
+
async function mountLoaded(html = PDF_HTML, editable = true) {
|
|
135
|
+
const m = mount(html, editable);
|
|
136
|
+
for (let i = 0; i < 50; i++) {
|
|
137
|
+
const b = m.overlay.querySelector('.pdf-preset');
|
|
138
|
+
if (b && !b.disabled)
|
|
139
|
+
break;
|
|
140
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
141
|
+
}
|
|
142
|
+
return m;
|
|
143
|
+
}
|
|
144
|
+
it('gives editors the zoom presets and delete', () => {
|
|
109
145
|
const { overlay } = mount();
|
|
110
|
-
expect([...overlay.querySelectorAll('.pdf-preset')].map((b) => b.textContent)).toEqual(['
|
|
146
|
+
expect([...overlay.querySelectorAll('.pdf-preset')].map((b) => b.textContent)).toEqual(['50%', '75%', '100%', '150%']);
|
|
111
147
|
expect(overlay.querySelector('.pdf-ctl-danger')).toBeTruthy();
|
|
112
148
|
});
|
|
149
|
+
/*
|
|
150
|
+
* ⚠️ 배율은 **페이지 원본 폭에서 계산**하므로 문서를 읽기 전에는 누를 값이 없다.
|
|
151
|
+
* 활성인 채로 두면 클릭이 조용히 아무 일도 안 하는 버튼이 된다.
|
|
152
|
+
*/
|
|
153
|
+
it('keeps the presets disabled until the page size is known', async () => {
|
|
154
|
+
const { overlay } = mount();
|
|
155
|
+
expect([...overlay.querySelectorAll('.pdf-preset')].every((b) => b.disabled)).toBe(true);
|
|
156
|
+
await mountLoaded();
|
|
157
|
+
expect([...editor.view.dom.querySelectorAll('.pdf-preset')].every((b) => !b.disabled)).toBe(true);
|
|
158
|
+
});
|
|
113
159
|
it('hides authoring controls from readers but keeps the file actions', () => {
|
|
114
160
|
const { overlay } = mount(PDF_HTML, false);
|
|
115
161
|
// 저장되는 문서 속성을 읽는 사람이 건드릴 자리는 없다.
|
|
@@ -132,21 +178,117 @@ describe('PdfBlock extension', () => {
|
|
|
132
178
|
editor.destroy();
|
|
133
179
|
}
|
|
134
180
|
});
|
|
135
|
-
|
|
136
|
-
|
|
181
|
+
/*
|
|
182
|
+
* 저장값은 **칼럼 대비 비율이 아니라 px** 이다. 같은 칩이 어느 화면에서든 같은
|
|
183
|
+
* 글자 크기를 주려면 페이지 원본 크기에서 계산해야 한다.
|
|
184
|
+
*/
|
|
185
|
+
it('stores an absolute width computed from the page size', async () => {
|
|
186
|
+
const { overlay } = await mountLoaded();
|
|
187
|
+
const click = (label) => [...overlay.querySelectorAll('.pdf-preset')].find((b) => b.textContent === label).click();
|
|
188
|
+
const width = () => editor
|
|
189
|
+
.getJSON()
|
|
190
|
+
.content?.find((n) => n.type === 'pdfBlock')
|
|
191
|
+
?.attrs?.width;
|
|
192
|
+
click('100%');
|
|
193
|
+
expect(width()).toBe(`${Math.round(A4_WIDTH)}px`);
|
|
194
|
+
click('50%');
|
|
195
|
+
expect(width()).toBe(`${Math.round(A4_WIDTH * 0.5)}px`);
|
|
196
|
+
click('150%');
|
|
197
|
+
expect(width()).toBe(`${Math.round(A4_WIDTH * 1.5)}px`);
|
|
198
|
+
});
|
|
199
|
+
/*
|
|
200
|
+
* ⚠️ 폭이 바뀌면 **캔버스도 그 폭으로 다시 그려져야** 한다. 예전엔 이걸
|
|
201
|
+
* `ResizeObserver` 에만 맡겨 뒀는데, 그러면 크기를 이미 아는 경로(프리셋 클릭)까지
|
|
202
|
+
* 관찰자를 한 바퀴 돌아야 한다. 실제로 블록만 595px 로 줄고 캔버스는 1376px 로
|
|
203
|
+
* 남는 반쪽 동작이 나왔다.
|
|
204
|
+
*
|
|
205
|
+
* 브라우저에서는 이 증상이 **자동화 탭이 `hidden` 이라 관찰자 콜백이 아예 안 오는
|
|
206
|
+
* 것**과 구분되지 않았다. 그래서 렌더가 즉시 끝나는 여기서 판정한다.
|
|
207
|
+
*/
|
|
208
|
+
it('redraws the canvas on a width change without waiting for an observer', async () => {
|
|
209
|
+
const { overlay } = await mountLoaded();
|
|
210
|
+
const frame = editor.view.dom.querySelector('.pdf-frame');
|
|
211
|
+
const canvas = frame.querySelector('canvas');
|
|
212
|
+
// happy-dom 에는 레이아웃이 없다 — 판이 보고할 폭을 직접 정해 준다.
|
|
213
|
+
let available = 1378;
|
|
214
|
+
Object.defineProperty(frame, 'clientWidth', { get: () => available });
|
|
215
|
+
const click = (label) => [...overlay.querySelectorAll('.pdf-preset')].find((b) => b.textContent === label).click();
|
|
216
|
+
available = Math.round(A4_WIDTH * 0.5);
|
|
217
|
+
click('50%');
|
|
218
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
219
|
+
expect(Number.parseFloat(canvas.style.width)).toBeCloseTo(available, 0);
|
|
220
|
+
available = Math.round(A4_WIDTH * 1.5);
|
|
221
|
+
click('150%');
|
|
222
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
223
|
+
expect(Number.parseFloat(canvas.style.width)).toBeCloseTo(available, 0);
|
|
224
|
+
});
|
|
225
|
+
/*
|
|
226
|
+
* 배율의 요점 — **같은 칩이 방향에 따라 다른 폭을 준다.** 글자 크기가 같아야 하므로
|
|
227
|
+
* 맞는 결과다. 폭 기준이던 시절엔 세로형이 부당하게 커 보였다(같은 50% 인데 세로형
|
|
228
|
+
* 높이는 가로형의 두 배였다).
|
|
229
|
+
*/
|
|
230
|
+
it('gives portrait and landscape different widths at the same zoom', async () => {
|
|
231
|
+
const at100 = async () => {
|
|
232
|
+
const { overlay } = await mountLoaded();
|
|
233
|
+
[...overlay.querySelectorAll('.pdf-preset')].find((b) => b.textContent === '100%').click();
|
|
234
|
+
const w = editor
|
|
235
|
+
.getJSON()
|
|
236
|
+
.content?.find((n) => n.type === 'pdfBlock')
|
|
237
|
+
?.attrs?.width;
|
|
238
|
+
editor.destroy();
|
|
239
|
+
return w;
|
|
240
|
+
};
|
|
241
|
+
PAGE.w = A4_WIDTH;
|
|
242
|
+
PAGE.h = A4_LANDSCAPE_WIDTH;
|
|
243
|
+
expect(await at100()).toBe(`${Math.round(A4_WIDTH)}px`);
|
|
244
|
+
PAGE.w = A4_LANDSCAPE_WIDTH;
|
|
245
|
+
PAGE.h = A4_WIDTH;
|
|
246
|
+
expect(await at100()).toBe(`${Math.round(A4_LANDSCAPE_WIDTH)}px`);
|
|
247
|
+
PAGE.w = A4_WIDTH;
|
|
248
|
+
PAGE.h = A4_LANDSCAPE_WIDTH;
|
|
249
|
+
});
|
|
250
|
+
/*
|
|
251
|
+
* ⚠️ **`selectNode`/`deselectNode` 훅을 두면 안 된다.** ProseMirror 는 그 훅이 있으면
|
|
252
|
+
* "노드뷰가 알아서 표시한다"고 보고 `ProseMirror-selectednode` 클래스를 **아예 안
|
|
253
|
+
* 붙인다.** 빈 함수여도 마찬가지라, 선택 테두리를 CSS 로 써도 매칭될 선택자가 생기지
|
|
254
|
+
* 않는다 — 편집 중 PDF 를 클릭해도 아무 표시가 없던 이유였다(사용자 지적).
|
|
255
|
+
*/
|
|
256
|
+
it('lets ProseMirror mark the block as selected', async () => {
|
|
257
|
+
await mountLoaded();
|
|
258
|
+
editor.commands.setNodeSelection(0);
|
|
259
|
+
const dom = editor.view.dom.querySelector('[data-type="pdfBlock"]');
|
|
260
|
+
expect(dom?.classList.contains('ProseMirror-selectednode')).toBe(true);
|
|
261
|
+
});
|
|
262
|
+
/* 그 클래스에 실제로 브랜드색 테두리가 걸려 있어야 의미가 있다. */
|
|
263
|
+
it('rings the selected media blocks in the brand colour', () => {
|
|
264
|
+
const css = readFileSync('src/styles/editor.css', 'utf-8');
|
|
265
|
+
const rule = css.match(/\.tiptap\[contenteditable='true'\] img\.ProseMirror-selectednode[^{]*\{[^}]*\}/)?.[0] ?? '';
|
|
266
|
+
expect(rule).toContain('var(--primary)');
|
|
267
|
+
expect(rule).toContain('outline');
|
|
268
|
+
// PDF·영상도 같은 규칙에 들어 있어야 한다.
|
|
269
|
+
for (const type of ['pdfBlock', 'mbusVideo', 'videoEmbed']) {
|
|
270
|
+
expect(rule).toContain(`[data-type='${type}'].ProseMirror-selectednode`);
|
|
271
|
+
}
|
|
272
|
+
// 예전 하이라이트는 이것들을 제외해야 두 겹이 되지 않는다.
|
|
273
|
+
const legacy = css.match(/\.ProseMirror-selectednode:not\(img\)[^{]*\{/)?.[0] ?? '';
|
|
274
|
+
expect(legacy).toContain(":not([data-type='pdfBlock'])");
|
|
275
|
+
});
|
|
276
|
+
it('marks the preset matching the stored width', async () => {
|
|
277
|
+
const { overlay } = await mountLoaded(`<div data-pdf-src="https://example.com/doc.pdf" data-pdf-width="${Math.round(A4_WIDTH * 0.75)}px"></div>`);
|
|
137
278
|
const active = overlay.querySelector('.pdf-preset.is-active');
|
|
138
279
|
expect(active?.textContent).toBe('75%');
|
|
139
280
|
expect(active?.getAttribute('aria-pressed')).toBe('true');
|
|
140
281
|
});
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
expect(
|
|
282
|
+
/*
|
|
283
|
+
* ⚠️ 옛 문서는 `"50%"` 를 들고 있다. 어느 칩과도 안 맞는 게 맞고 — 값을 손대면
|
|
284
|
+
* 열었다 저장하는 것만으로 저자가 정한 크기가 바뀐다. 렌더는 그대로 돼야 한다.
|
|
285
|
+
*/
|
|
286
|
+
it('leaves a legacy percentage alone', async () => {
|
|
287
|
+
const { overlay } = await mountLoaded('<div data-pdf-src="https://example.com/doc.pdf" data-pdf-width="50%"></div>');
|
|
288
|
+
expect(overlay.querySelector('.pdf-preset.is-active')).toBeNull();
|
|
289
|
+
expect(editor.getHTML()).toContain('data-pdf-width="50%"');
|
|
290
|
+
expect(editor.view.dom.querySelector('[data-type="pdfBlock"]')
|
|
291
|
+
.style.width).toBe('50%');
|
|
150
292
|
});
|
|
151
293
|
it('removes the block when delete is clicked', () => {
|
|
152
294
|
const { overlay } = mount();
|
package/dist/styles/editor.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.top-full{top:100%}.z-30{z-index:30}.z-50{z-index:50}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.\!table{display:table!important}.table{display:table}.grid{display:grid}.hidden{display:none}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-px{height:1px}.min-h-\[52px\]{min-height:52px}.w-10{width:2.5rem}.w-\[360px\]{width:360px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-\[96px\]{min-width:96px}.max-w-\[90vw\]{max-width:90vw}.flex-shrink{flex-shrink:1}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(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)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(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}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.resize{resize:both}.columns-2{-moz-columns:2;column-count:2}.columns-3{-moz-columns:3;column-count:3}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:var(--radius-md,4px)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius-xl,8px)}.rounded-md{border-radius:var(--radius-md,6px)}.rounded-xl{border-radius:var(--radius-2xl,12px)}.rounded-t-xl{border-top-left-radius:var(--radius-2xl,12px);border-top-right-radius:var(--radius-2xl,12px)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-border{border-color:var(--border)}.bg-background{background-color:var(--background)}.bg-black\/40{background-color:rgba(0,0,0,.4)}.bg-border{background-color:var(--border)}.bg-popover{background-color:var(--popover)}.bg-transparent{background-color:transparent}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.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-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[11px\]{font-size:11px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-destructive{color:var(--destructive)}.text-muted-foreground{color:var(--muted-foreground)}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.shadow-lg{--tw-shadow:var(--shadow-dropdown,0 10px 15px -3px rgba(0,0,0,.1));--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color)}.shadow-lg,.shadow-xl{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-popup,0 20px 25px -5px rgba(0,0,0,.1));--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,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-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}.hce-editor-wrapper{overflow:visible!important}.hce-color-divider{border-top:1px solid var(--border)}.bubble-toolbar-container button,.hce-editor-wrapper button,.slash-menu button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;cursor:pointer;box-sizing:border-box}.bubble-toolbar-container button:disabled,.hce-editor-wrapper button:disabled,.slash-menu button:disabled{cursor:default}.bubble-toolbar-container .hce-btn-primary,.hce-editor-wrapper .hce-btn-primary,.slash-menu .hce-btn-primary{background-color:var(--primary);color:var(--primary-foreground,#fff)}.tiptap{font-size:1.0625rem;line-height:1.8;color:var(--foreground);padding:1.5rem}.tiptap>*+*{margin-top:.25em}.tiptap [data-type=column]>:first-child,.tiptap [data-type=detailsContent]>:first-child,.tiptap blockquote>:first-child,.tiptap li>:first-child,.tiptap td>:first-child,.tiptap th>:first-child,.tiptap>:first-child{margin-top:0}.tiptap [data-type=column]>:last-child,.tiptap [data-type=detailsContent]>:last-child,.tiptap blockquote>:last-child,.tiptap li>:last-child,.tiptap td>:last-child,.tiptap th>:last-child,.tiptap>:last-child{margin-bottom:0}.tiptap p{margin:.5em 0!important;line-height:1.5}.tiptap p:first-child{margin-top:0!important}.tiptap p:last-child{margin-bottom:0!important}.tiptap p:empty,.tiptap p:has(>br:only-child){min-height:1.5em}.tiptap h1,.tiptap h2,.tiptap h3,.tiptap li,.tiptap p{white-space:pre-wrap}.tiptap h1{font-size:2rem;font-weight:700;margin:1.5em 0 .5em;line-height:1.25}.tiptap h2{font-size:1.5rem;font-weight:600;margin:1.2em 0 .4em;line-height:1.3}.tiptap h3{font-size:1.25rem;font-weight:600;margin:1em 0 .3em;line-height:1.35}.tiptap ul{list-style:disc}.tiptap ol,.tiptap ul{padding-left:1.5em;margin:.5em 0}.tiptap ol{list-style:decimal}.tiptap ul ul{list-style:circle}.tiptap ul ul ul{list-style:square}.tiptap ol ol{list-style:lower-alpha}.tiptap ol ol ol{list-style:lower-roman}.tiptap li{margin:.4em 0;line-height:1.7}.tiptap li>p{margin:0!important;line-height:inherit!important}.tiptap ul[data-type=taskList]{list-style:none;padding-left:0}.tiptap ul[data-type=taskList] li{display:flex;align-items:baseline;gap:.5rem;margin:.3em 0;line-height:1.7;list-style:none;list-style-type:none}.tiptap ul[data-type=taskList] li>label{flex-shrink:0;display:flex;align-items:center;height:1.5em}.tiptap ul[data-type=taskList] li>label input[type=checkbox]{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:1.1em;height:1.1em;margin:0;padding:0;cursor:pointer;background-color:var(--background,#fff);border:1.5px solid var(--border);border-radius:4px;transition:background-color .12s ease,border-color .12s ease,box-shadow .12s ease;display:inline-block;vertical-align:middle;flex-shrink:0}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:hover{border-color:var(--muted-foreground)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--background,#fff),0 0 0 4px var(--primary)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:checked{background-color:var(--primary);border-color:var(--primary);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' viewBox='0 0 16 16'%3E%3Cpath d='m3.5 8.5 3 3 6-6.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.tiptap ul[data-type=taskList] li>div{flex:1}.tiptap ul[data-type=taskList] li[data-checked=true]>div{text-decoration:line-through;opacity:.6}.tiptap blockquote{border-left:3px solid var(--border);padding:.5rem 1rem;margin:.75em 0;color:var(--muted-foreground);font-style:italic}.tiptap hr{border:none;border-top:2px solid color-mix(in srgb,var(--foreground) 38%,transparent);margin:1.5em 0}.tiptap code{background:var(--muted);border-radius:4px;padding:.15em .35em;font-size:.9em}.tiptap pre{background:#282c34;color:#abb2bf;border-radius:8px;padding:1em;margin:.75em 0;overflow-x:auto;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:1em;line-height:1.6}.tiptap pre code{background:none;padding:0;border-radius:0;color:#abb2bf;font-size:inherit}.tiptap pre code .hljs-keyword,.tiptap pre code .hljs-operator{color:#c678dd}.tiptap pre code .hljs-addition,.tiptap pre code .hljs-doctag,.tiptap pre code .hljs-regexp,.tiptap pre code .hljs-string{color:#98c379}.tiptap pre code .hljs-attr,.tiptap pre code .hljs-number,.tiptap pre code .hljs-selector-class,.tiptap pre code .hljs-template-variable,.tiptap pre code .hljs-type,.tiptap pre code .hljs-variable{color:#d19a66}.tiptap pre code .hljs-function,.tiptap pre code .hljs-section,.tiptap pre code .hljs-title,.tiptap pre code .hljs-title.class_{color:#61aeee}.tiptap pre code .hljs-params,.tiptap pre code .hljs-punctuation{color:#abb2bf}.tiptap pre code .hljs-comment,.tiptap pre code .hljs-quote{color:#5c6370;font-style:italic}.tiptap pre code .hljs-built_in,.tiptap pre code .hljs-formula{color:#e6c07b}.tiptap pre code .hljs-meta,.tiptap pre code .hljs-meta .hljs-keyword{color:#61aeee}.tiptap pre code .hljs-meta .hljs-string{color:#98c379}.tiptap pre code .hljs-attribute,.tiptap pre code .hljs-deletion,.tiptap pre code .hljs-name,.tiptap pre code .hljs-property,.tiptap pre code .hljs-selector-tag,.tiptap pre code .hljs-subst,.tiptap pre code .hljs-tag{color:#e06c75}.tiptap pre code .hljs-literal{color:#56b6c2}.tiptap pre code .hljs-selector-attr,.tiptap pre code .hljs-selector-id,.tiptap pre code .hljs-selector-pseudo{color:#61aeee}.tiptap pre code .hljs-link{color:#61aeee;text-decoration:underline}.tiptap pre code .hljs-bullet,.tiptap pre code .hljs-symbol{color:#61aeee}.tiptap pre code .hljs-emphasis{font-style:italic}.tiptap pre code .hljs-strong{font-weight:700}.tiptap img{max-width:100%;height:auto;margin:.75em 0;cursor:pointer;transition:box-shadow .15s}.tiptap [data-type=pdfBlock].ProseMirror-selectednode>div,.tiptap img{border-radius:8px}.pdf-frame{position:relative;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:8px;background:var(--muted)}.pdf-frame canvas{display:block;max-width:100%;border-radius:7px}.pdf-overlay{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .15s ease;-moz-user-select:none;user-select:none;-webkit-user-select:none}.pdf-overlay .pdf-page-input{-moz-user-select:text;user-select:text;-webkit-user-select:text}.pdf-frame:hover .pdf-overlay,.pdf-overlay:focus-within,[data-type=pdfBlock].ProseMirror-selectednode .pdf-overlay{opacity:1}@media (hover:none){.pdf-overlay{opacity:1}}@media (prefers-reduced-motion:reduce){.pdf-overlay{transition:none}}.pdf-cluster{position:absolute;display:flex;align-items:center;gap:1px;padding:2px;border-radius:999px;background:rgba(24,24,27,.52);backdrop-filter:blur(12px) saturate(1.2);border:1px solid hsla(0,0%,100%,.1);box-shadow:0 2px 8px rgba(0,0,0,.18);color:#fff;pointer-events:auto;max-width:calc(100% - 16px);transition:background-color .15s ease}.pdf-cluster:hover{background:rgba(24,24,27,.72)}.pdf-cluster-end{top:6px;right:6px}.pdf-cluster-page{bottom:6px;left:50%;transform:translateX(-50%)}.pdf-nav-rail{position:sticky;top:0;height:100vh;max-height:100%;pointer-events:none}.pdf-nav{position:absolute;top:50%;transform:translateY(-50%);pointer-events:auto}.pdf-nav-prev{left:12px}.pdf-nav-next{right:12px}.pdf-overlay .pdf-ctl,.pdf-overlay .pdf-page,.pdf-overlay .pdf-preset{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:0;background:transparent;color:hsla(0,0%,100%,.72);font-family:inherit;cursor:pointer;border-radius:999px;transition:background-color .12s,color .12s}.pdf-overlay .pdf-ctl{width:22px;height:22px;flex:none}.pdf-overlay .pdf-ctl svg{width:13px;height:13px}.pdf-overlay .pdf-ctl:hover,.pdf-overlay .pdf-page:hover,.pdf-overlay .pdf-preset:hover{background:hsla(0,0%,100%,.16);color:#fff}.pdf-overlay .pdf-ctl:disabled{opacity:.35;cursor:default;background:transparent}.pdf-overlay .pdf-ctl-danger:hover{background:hsla(0,91%,71%,.26);color:#fff}.pdf-overlay .pdf-ctl:focus-visible,.pdf-overlay .pdf-page-input:focus-visible,.pdf-overlay .pdf-page:focus-visible,.pdf-overlay .pdf-preset:focus-visible{outline:2px solid hsla(0,0%,100%,.8);outline-offset:1px}.pdf-overlay .pdf-preset{height:20px;padding:0 6px;font-size:10px;line-height:1;font-variant-numeric:tabular-nums;flex:none}.pdf-overlay .pdf-preset.is-active,.pdf-overlay .pdf-preset.is-active:hover{background:hsla(0,0%,100%,.22);color:#fff}.pdf-overlay .pdf-page{height:20px;padding:0 8px;font-size:11px;line-height:1;font-variant-numeric:tabular-nums}.pdf-overlay .pdf-nav{width:28px;height:28px;background:rgba(24,24,27,.52);border-color:hsla(0,0%,100%,.1);box-shadow:0 2px 8px rgba(0,0,0,.18)}.pdf-overlay .pdf-nav svg{width:15px;height:15px}.pdf-overlay .pdf-nav:hover{background:rgba(24,24,27,.78);color:#fff}.pdf-overlay .pdf-nav:disabled{opacity:.5;background:rgba(24,24,27,.38)}.pdf-divider{flex:none;width:1px;align-self:stretch;margin:2px;background:hsla(0,0%,100%,.18)}.pdf-overlay .pdf-page-input{box-sizing:border-box;height:20px;width:44px;padding:0 5px;font-size:11px;text-align:center;font-variant-numeric:tabular-nums;background:hsla(0,0%,100%,.14);border:1px solid hsla(0,0%,100%,.22);color:#fff;border-radius:999px;font-family:inherit;outline:none;transition:background-color .12s,border-color .12s}.pdf-overlay .pdf-page-input:focus{background:hsla(0,0%,100%,.22);border-color:hsla(0,0%,100%,.45)}.pdf-status{display:flex;align-items:center;justify-content:center;gap:8px;padding:2.5rem 1rem;font-size:.875rem;color:var(--muted-foreground);text-align:center}.tiptap a{color:var(--primary);text-decoration:underline;text-underline-offset:2px}.tiptap a:hover{opacity:.8}.tiptap mark{background-color:#fef08a;border-radius:2px;padding:.05em .1em}.tiptap [data-type=details]{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;display:grid;grid-template-columns:30px 1fr;align-items:start;transition:background .12s}.tiptap [data-type=details]:hover{background:var(--muted)}.tiptap [data-type=details]>button{background:none;border:none;cursor:pointer;padding:0;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;color:var(--muted-foreground);border-radius:4px;transition:transform .2s,color .15s,background-color .15s;flex-shrink:0;margin-top:14px;margin-left:4px}.tiptap [data-type=details]>button:hover{background:color-mix(in srgb,var(--foreground) 8%,transparent)}.tiptap [data-type=details]>button:after{content:"";display:block;width:0;height:0;border-left:7px solid;border-top:5.5px solid transparent;border-bottom:5.5px solid transparent;margin-left:2px}.tiptap [data-type=details]:hover>button{color:var(--foreground)}.tiptap [data-type=details].is-open>button{transform:rotate(90deg)}.tiptap [data-type=details]>div{flex:1;min-width:0}.tiptap [data-type=details] summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 0;display:block;border-bottom:1px solid transparent;transition:border-color .15s}.tiptap [data-type=details].is-open>div>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap [data-type=details] summary[data-level="1"],.tiptap details summary[data-level="1"]{font-size:2rem;font-weight:700;line-height:1.25}.tiptap [data-type=details] summary[data-level="2"],.tiptap details summary[data-level="2"]{font-size:1.5rem;font-weight:600;line-height:1.3}.tiptap [data-type=details] summary[data-level="3"],.tiptap details summary[data-level="3"]{font-size:1.25rem;font-weight:600;line-height:1.35}.tiptap [data-type=details]:has(>div>summary[data-level="1"])>button{margin-top:19px}.tiptap [data-type=details]:has(>div>summary[data-level="2"])>button{margin-top:15px}.tiptap [data-type=details]:has(>div>summary[data-level="3"])>button{margin-top:13px}.tiptap [data-type=detailsContent]{padding:8px 8px 8px 0;border-left:none}.tiptap [data-type=detailsContent][hidden]{display:none}.tiptap details{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;transition:background .12s}.tiptap details:hover{background:var(--muted)}.tiptap details summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 26px;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-bottom:1px solid transparent;position:relative;list-style:none;transition:border-color .15s}.tiptap details[open]>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap details summary::-webkit-details-marker{display:none}.tiptap details summary::marker{content:""}.tiptap details summary:before{content:"";position:absolute;left:8px;top:50%;width:0;height:0;border-left:7px solid var(--muted-foreground);border-top:5.5px solid transparent;border-bottom:5.5px solid transparent;transform:translateY(-50%);transition:transform .2s,border-left-color .15s}.tiptap details:hover summary:before{border-left-color:var(--foreground)}.tiptap details[open]>summary:before{transform:translateY(-50%) rotate(90deg)}.tiptap details[open]>:not(summary){margin-top:8px;padding-left:26px;padding-right:8px}.tiptap table{border-collapse:collapse;margin:1em 0;table-layout:fixed;border:2px solid var(--border);max-width:100%}.tiptap .tableWrapper{overflow-x:auto;max-width:100%}.tiptap td,.tiptap th{border:1px solid var(--border);padding:.6em .8em;min-width:60px;vertical-align:middle;position:relative;box-sizing:border-box;overflow:hidden;word-break:break-word;line-height:1.5}.tiptap th{background:var(--muted);font-weight:600;text-align:left}.tiptap td{background:var(--background)}.tiptap .selectedCell:after{content:"";position:absolute;inset:0;background:var(--primary);opacity:.12;pointer-events:none;z-index:1}.tiptap .column-resize-handle{position:absolute;right:-3px;top:-1px;bottom:-1px;width:6px;background:var(--primary);opacity:0;cursor:col-resize;z-index:20;border-radius:2px;transition:opacity .15s}.tiptap table:hover .column-resize-handle{opacity:.4}.tiptap .column-resize-handle:hover{opacity:1}.tiptap.resize-cursor{cursor:col-resize}.tableWrapper{overflow-x:auto;overflow-y:hidden;margin:1em 0;max-width:100%;padding-right:4px}.tiptap table .grip-column,.tiptap table .grip-row,.tiptap table .grip-table{display:none!important}.tiptap .is-empty:before{content:attr(data-placeholder);float:left;color:var(--muted-foreground);opacity:.5;pointer-events:none;height:0}.tiptap h1.is-empty:before{font-size:2rem;font-weight:700}.tiptap h2.is-empty:before{font-size:1.5rem;font-weight:600}.tiptap h3.is-empty:before{font-size:1.25rem;font-weight:600}.ProseMirror-gapcursor{display:none;pointer-events:none;position:relative}.ProseMirror-gapcursor:after{content:"";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid var(--foreground);animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.ProseMirror-dropcursor{border-top:2px solid var(--primary);margin:-1px 0}.tiptap ::-moz-selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.tiptap ::selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.ProseMirror-noderangeselection ::-moz-selection{background:transparent}.ProseMirror-noderangeselection ::selection{background:transparent}.ProseMirror-noderangeselection *{caret-color:transparent}.ProseMirror-selectednode,.ProseMirror-selectednoderange{position:relative}.ProseMirror-selectednode:not(img):not([data-type=pdfBlock]):before,.ProseMirror-selectednoderange:not([data-type=pdfBlock]):before{content:"";position:absolute;inset:-.25rem;background-color:color-mix(in srgb,var(--primary) 10%,transparent);border:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:.5rem;pointer-events:none;z-index:-1}.hce-table-bubble{z-index:var(--hce-menu-z,100)}.bubble-toolbar-container{position:absolute;top:0;left:0;width:-moz-max-content;width:max-content;z-index:calc(var(--hce-menu-z, 100) + 1)}.hce-toolbar:has(.absolute)~.bubble-toolbar-container,.hce-toolbar:has(.absolute)~.hce-table-bubble{display:none}.hce-menu-surface{background-color:var(--hce-menu-surface,#333)}.hce-floating-panel{background-color:color-mix(in srgb,var(--foreground) 8%,var(--popover,var(--background,#fff)));border:1px solid color-mix(in srgb,var(--foreground) 18%,var(--border));box-shadow:0 8px 24px color-mix(in srgb,var(--foreground) 16%,transparent),0 2px 6px color-mix(in srgb,var(--foreground) 10%,transparent)}.hce-floating-plus{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;border:1px solid var(--border);background:var(--background);color:var(--muted-foreground);cursor:pointer;transition:all .15s}.hce-floating-plus:hover{color:var(--foreground);border-color:var(--foreground);background:var(--muted)}.hce-drag-handle{display:flex;align-items:center;gap:2px}.hce-drag-handle__plus{display:flex;align-items:center;justify-content:center;padding:4px;border-radius:4px;border:none;background:transparent;color:var(--muted-foreground);opacity:.5;cursor:pointer;transition:opacity .15s,background-color .15s}.hce-drag-handle__plus:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip{display:flex;align-items:center;justify-content:center;padding:2px;border-radius:4px;color:var(--muted-foreground);opacity:.5;cursor:grab;transition:opacity .15s,background-color .15s}.hce-drag-handle__grip:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip:active{cursor:grabbing}.tiptap div[data-type=columns]{display:grid;gap:16px;margin:1em 0}.tiptap div[data-type=columns][data-columns="2"]{grid-template-columns:1fr 1fr}.tiptap div[data-type=columns][data-columns="3"]{grid-template-columns:1fr 1fr 1fr}.tiptap div[data-type=column]{min-width:0;padding:4px 6px;border:1px dashed var(--border);border-radius:8px}.tiptap[contenteditable=true] div[data-type=column]:focus-within{border-color:var(--primary);border-style:solid}.tiptap div[data-type=columns].ProseMirror-selectednode{outline:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:8px}@media (max-width:640px){.tiptap div[data-type=columns]{grid-template-columns:1fr!important}}.hce-table-btn-wrap{position:relative;display:inline-flex}.hce-table-btn-tooltip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:6px;padding:4px 8px;font-size:11px;line-height:1.2;white-space:nowrap;color:#fff;background:#1e293b;border-radius:6px;pointer-events:none;opacity:0;transition:opacity .15s;z-index:60}.hce-table-btn-wrap:hover .hce-table-btn-tooltip{opacity:1}.hce-table-btn-wrap.hce-tooltip-off:hover .hce-table-btn-tooltip{opacity:0}.tiptap math-inline,math-inline.math-node{display:inline-block;vertical-align:baseline}.tiptap math-display,math-display.math-node{display:block;margin:.9em 0;text-align:center}.math-node,.tiptap .math-node{font-size:.95em}.tiptap math-inline.math-node .katex,math-inline.math-node .katex{font-size:1.0285em}.tiptap[contenteditable=true] .math-node{cursor:pointer;border-radius:4px;transition:background-color .12s}.tiptap[contenteditable=true] .math-node:hover{background-color:color-mix(in srgb,var(--primary) 10%,transparent)}.tiptap .math-node.ProseMirror-selectednode{background-color:color-mix(in srgb,var(--primary) 18%,transparent);outline:1px solid color-mix(in srgb,var(--primary) 45%,transparent)}.tiptap .math-node.empty-math .math-placeholder{font-size:.85em;padding:0 .35em;color:var(--muted-foreground);border:1px dashed var(--border);border-radius:4px}.math-node .math-error,.tiptap .math-error{color:#dc2626;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.hce-card-frame,.tiptap [data-type=card]{position:relative}.hce-card-frame{box-sizing:border-box;width:100%;margin:12px 0;padding:26px 30px;display:flex;flex-direction:column;justify-content:center;gap:12px;overflow:hidden;border:1px solid hsla(0,0%,100%,.52);border-radius:8px;box-shadow:inset 0 0 0 1px hsla(0,0%,100%,.28),0 8px 24px rgba(15,23,42,.08);overflow-wrap:anywhere;isolation:isolate}.hce-card-frame:before{content:"";position:absolute;inset:0;z-index:0;background:linear-gradient(90deg,hsla(0,0%,100%,.14),hsla(0,0%,100%,.04) 48%,rgba(15,23,42,.08));pointer-events:none}.hce-card-content{position:relative;z-index:1;box-sizing:border-box;width:100%;max-height:100%;min-height:0;padding:18px 20px;display:flex;flex-direction:column;gap:10px;overflow:hidden;border:1px solid hsla(0,0%,100%,.56);border-radius:8px;background:hsla(0,0%,100%,.82);color:#111827;box-shadow:0 14px 42px rgba(15,23,42,.12),inset 0 1px 0 hsla(0,0%,100%,.52);backdrop-filter:blur(18px) saturate(1.16);-webkit-backdrop-filter:blur(18px) saturate(1.16)}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.hce-card-content{background:hsla(0,0%,100%,.9)}}.hce-card-header{flex:0 0 auto}.hce-card-title{margin:0;font-size:1.65rem;font-weight:700;line-height:1.18;color:#111827}.hce-card-title[hidden]{display:none}.hce-card-title-input{box-sizing:border-box;width:100%;padding:8px 12px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.7);color:#111827;font:inherit;font-size:1.15rem;font-weight:700;outline:none}.hce-card-title-input:focus{border-color:var(--primary,#3382f2)}.hce-card-body{flex:1 1 auto;min-height:0;overflow:auto;font-size:1rem;line-height:1.55;color:#111827}.hce-card-body>p:first-child{margin-top:0}.hce-card-body>p:last-child{margin-bottom:0}.hce-card-bg-button{position:absolute;top:8px;right:8px;z-index:3;padding:4px 10px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.86);color:#111827;font-size:.8125rem;line-height:1.4;cursor:pointer}.hce-card-bg-button:hover{background:#fff}@media (max-width:640px){.hce-card-frame{padding:18px}.hce-card-content{padding:14px 16px}.hce-card-title{font-size:1.35rem}}.hce-active{background-color:color-mix(in srgb,var(--primary) 12%,transparent);color:var(--primary)}.hce-active:hover{background-color:color-mix(in srgb,var(--primary) 18%,transparent)}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:scale-105:hover,.hover\:scale-110:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-red-300:hover{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.hover\:opacity-90:hover{opacity:.9}.focus\:border-primary:focus{border-color:var(--primary)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--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)}
|
|
1
|
+
.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.top-full{top:100%}.z-30{z-index:30}.z-50{z-index:50}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.\!table{display:table!important}.table{display:table}.grid{display:grid}.hidden{display:none}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-px{height:1px}.min-h-\[52px\]{min-height:52px}.w-10{width:2.5rem}.w-\[360px\]{width:360px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-\[96px\]{min-width:96px}.max-w-\[90vw\]{max-width:90vw}.flex-shrink{flex-shrink:1}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(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)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(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}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.resize{resize:both}.columns-2{-moz-columns:2;column-count:2}.columns-3{-moz-columns:3;column-count:3}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:var(--radius-md,4px)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius-xl,8px)}.rounded-md{border-radius:var(--radius-md,6px)}.rounded-xl{border-radius:var(--radius-2xl,12px)}.rounded-t-xl{border-top-left-radius:var(--radius-2xl,12px);border-top-right-radius:var(--radius-2xl,12px)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-border{border-color:var(--border)}.bg-background{background-color:var(--background)}.bg-black\/40{background-color:rgba(0,0,0,.4)}.bg-border{background-color:var(--border)}.bg-popover{background-color:var(--popover)}.bg-transparent{background-color:transparent}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.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-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[11px\]{font-size:11px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-destructive{color:var(--destructive)}.text-muted-foreground{color:var(--muted-foreground)}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.shadow-lg{--tw-shadow:var(--shadow-dropdown,0 10px 15px -3px rgba(0,0,0,.1));--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color)}.shadow-lg,.shadow-xl{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-popup,0 20px 25px -5px rgba(0,0,0,.1));--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,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-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}.hce-editor-wrapper{overflow:visible!important}.hce-color-divider{border-top:1px solid var(--border)}.bubble-toolbar-container button,.hce-editor-wrapper button,.slash-menu button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;cursor:pointer;box-sizing:border-box}.bubble-toolbar-container button:disabled,.hce-editor-wrapper button:disabled,.slash-menu button:disabled{cursor:default}.bubble-toolbar-container .hce-btn-primary,.hce-editor-wrapper .hce-btn-primary,.slash-menu .hce-btn-primary{background-color:var(--primary);color:var(--primary-foreground,#fff)}.tiptap{font-size:1.0625rem;line-height:1.8;color:var(--foreground);padding:1.5rem}.tiptap>*+*{margin-top:.25em}.tiptap [data-type=column]>:first-child,.tiptap [data-type=detailsContent]>:first-child,.tiptap blockquote>:first-child,.tiptap li>:first-child,.tiptap td>:first-child,.tiptap th>:first-child,.tiptap>:first-child{margin-top:0}.tiptap [data-type=column]>:last-child,.tiptap [data-type=detailsContent]>:last-child,.tiptap blockquote>:last-child,.tiptap li>:last-child,.tiptap td>:last-child,.tiptap th>:last-child,.tiptap>:last-child{margin-bottom:0}.tiptap p{margin:.5em 0!important;line-height:1.5}.tiptap p:first-child{margin-top:0!important}.tiptap p:last-child{margin-bottom:0!important}.tiptap p:empty,.tiptap p:has(>br:only-child){min-height:1.5em}.tiptap h1,.tiptap h2,.tiptap h3,.tiptap li,.tiptap p{white-space:pre-wrap}.tiptap h1{font-size:2rem;font-weight:700;margin:1.5em 0 .5em;line-height:1.25}.tiptap h2{font-size:1.5rem;font-weight:600;margin:1.2em 0 .4em;line-height:1.3}.tiptap h3{font-size:1.25rem;font-weight:600;margin:1em 0 .3em;line-height:1.35}.tiptap ul{list-style:disc}.tiptap ol,.tiptap ul{padding-left:1.5em;margin:.5em 0}.tiptap ol{list-style:decimal}.tiptap ul ul{list-style:circle}.tiptap ul ul ul{list-style:square}.tiptap ol ol{list-style:lower-alpha}.tiptap ol ol ol{list-style:lower-roman}.tiptap li{margin:.4em 0;line-height:1.7}.tiptap li>p{margin:0!important;line-height:inherit!important}.tiptap ul[data-type=taskList]{list-style:none;padding-left:0}.tiptap ul[data-type=taskList] li{display:flex;align-items:baseline;gap:.5rem;margin:.3em 0;line-height:1.7;list-style:none;list-style-type:none}.tiptap ul[data-type=taskList] li>label{flex-shrink:0;display:flex;align-items:center;height:1.5em}.tiptap ul[data-type=taskList] li>label input[type=checkbox]{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:1.1em;height:1.1em;margin:0;padding:0;cursor:pointer;background-color:var(--background,#fff);border:1.5px solid var(--border);border-radius:4px;transition:background-color .12s ease,border-color .12s ease,box-shadow .12s ease;display:inline-block;vertical-align:middle;flex-shrink:0}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:hover{border-color:var(--muted-foreground)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--background,#fff),0 0 0 4px var(--primary)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:checked{background-color:var(--primary);border-color:var(--primary);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' viewBox='0 0 16 16'%3E%3Cpath d='m3.5 8.5 3 3 6-6.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.tiptap ul[data-type=taskList] li>div{flex:1}.tiptap ul[data-type=taskList] li[data-checked=true]>div{text-decoration:line-through;opacity:.6}.tiptap blockquote{border-left:3px solid var(--border);padding:.5rem 1rem;margin:.75em 0;color:var(--muted-foreground);font-style:italic}.tiptap hr{border:none;border-top:2px solid color-mix(in srgb,var(--foreground) 38%,transparent);margin:1.5em 0}.tiptap code{background:var(--muted);border-radius:4px;padding:.15em .35em;font-size:.9em}.tiptap pre{background:#282c34;color:#abb2bf;border-radius:8px;padding:1em;margin:.75em 0;overflow-x:auto;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:1em;line-height:1.6}.tiptap pre code{background:none;padding:0;border-radius:0;color:#abb2bf;font-size:inherit}.tiptap pre code .hljs-keyword,.tiptap pre code .hljs-operator{color:#c678dd}.tiptap pre code .hljs-addition,.tiptap pre code .hljs-doctag,.tiptap pre code .hljs-regexp,.tiptap pre code .hljs-string{color:#98c379}.tiptap pre code .hljs-attr,.tiptap pre code .hljs-number,.tiptap pre code .hljs-selector-class,.tiptap pre code .hljs-template-variable,.tiptap pre code .hljs-type,.tiptap pre code .hljs-variable{color:#d19a66}.tiptap pre code .hljs-function,.tiptap pre code .hljs-section,.tiptap pre code .hljs-title,.tiptap pre code .hljs-title.class_{color:#61aeee}.tiptap pre code .hljs-params,.tiptap pre code .hljs-punctuation{color:#abb2bf}.tiptap pre code .hljs-comment,.tiptap pre code .hljs-quote{color:#5c6370;font-style:italic}.tiptap pre code .hljs-built_in,.tiptap pre code .hljs-formula{color:#e6c07b}.tiptap pre code .hljs-meta,.tiptap pre code .hljs-meta .hljs-keyword{color:#61aeee}.tiptap pre code .hljs-meta .hljs-string{color:#98c379}.tiptap pre code .hljs-attribute,.tiptap pre code .hljs-deletion,.tiptap pre code .hljs-name,.tiptap pre code .hljs-property,.tiptap pre code .hljs-selector-tag,.tiptap pre code .hljs-subst,.tiptap pre code .hljs-tag{color:#e06c75}.tiptap pre code .hljs-literal{color:#56b6c2}.tiptap pre code .hljs-selector-attr,.tiptap pre code .hljs-selector-id,.tiptap pre code .hljs-selector-pseudo{color:#61aeee}.tiptap pre code .hljs-link{color:#61aeee;text-decoration:underline}.tiptap pre code .hljs-bullet,.tiptap pre code .hljs-symbol{color:#61aeee}.tiptap pre code .hljs-emphasis{font-style:italic}.tiptap pre code .hljs-strong{font-weight:700}.tiptap img{max-width:100%;height:auto;border-radius:8px;margin:.75em 0;cursor:pointer;transition:box-shadow .15s}.pdf-frame{position:relative;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:8px;background:var(--muted)}.pdf-frame canvas{display:block;max-width:100%;border-radius:7px}.pdf-overlay{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .15s ease;-moz-user-select:none;user-select:none;-webkit-user-select:none}.pdf-overlay .pdf-page-input{-moz-user-select:text;user-select:text;-webkit-user-select:text}.pdf-frame:hover .pdf-overlay,.pdf-overlay:focus-within,[data-type=pdfBlock].ProseMirror-selectednode .pdf-overlay{opacity:1}@media (hover:none){.pdf-overlay{opacity:1}}@media (prefers-reduced-motion:reduce){.pdf-overlay{transition:none}}.pdf-cluster{position:absolute;display:flex;align-items:center;gap:1px;padding:2px;border-radius:999px;background:rgba(24,24,27,.52);backdrop-filter:blur(12px) saturate(1.2);border:1px solid hsla(0,0%,100%,.1);box-shadow:0 2px 8px rgba(0,0,0,.18);color:#fff;pointer-events:auto;max-width:calc(100% - 16px);transition:background-color .15s ease}.pdf-cluster:hover{background:rgba(24,24,27,.72)}.pdf-cluster-end{top:6px;right:6px}.pdf-cluster-page{bottom:6px;left:50%;transform:translateX(-50%)}.pdf-nav-rail{position:sticky;top:0;height:100vh;max-height:100%;pointer-events:none}.pdf-nav{position:absolute;top:50%;transform:translateY(-50%);pointer-events:auto}.pdf-nav-prev{left:12px}.pdf-nav-next{right:12px}.pdf-overlay .pdf-ctl,.pdf-overlay .pdf-page,.pdf-overlay .pdf-preset{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:0;background:transparent;color:hsla(0,0%,100%,.72);font-family:inherit;cursor:pointer;border-radius:999px;transition:background-color .12s,color .12s}.pdf-overlay .pdf-ctl{width:22px;height:22px;flex:none}.pdf-overlay .pdf-ctl svg{width:13px;height:13px}.pdf-overlay .pdf-ctl:hover,.pdf-overlay .pdf-page:hover,.pdf-overlay .pdf-preset:hover{background:hsla(0,0%,100%,.16);color:#fff}.pdf-overlay .pdf-ctl:disabled{opacity:.35;cursor:default;background:transparent}.pdf-overlay .pdf-ctl-danger:hover{background:hsla(0,91%,71%,.26);color:#fff}.pdf-overlay .pdf-ctl:focus-visible,.pdf-overlay .pdf-page-input:focus-visible,.pdf-overlay .pdf-page:focus-visible,.pdf-overlay .pdf-preset:focus-visible{outline:2px solid hsla(0,0%,100%,.8);outline-offset:1px}.pdf-overlay .pdf-preset{height:20px;padding:0 6px;font-size:10px;line-height:1;font-variant-numeric:tabular-nums;flex:none}.pdf-overlay .pdf-preset.is-active,.pdf-overlay .pdf-preset.is-active:hover{background:hsla(0,0%,100%,.22);color:#fff}.pdf-overlay .pdf-page{height:20px;padding:0 8px;font-size:11px;line-height:1;font-variant-numeric:tabular-nums}.pdf-overlay .pdf-nav{width:28px;height:28px;background:rgba(24,24,27,.52);border-color:hsla(0,0%,100%,.1);box-shadow:0 2px 8px rgba(0,0,0,.18)}.pdf-overlay .pdf-nav svg{width:15px;height:15px}.pdf-overlay .pdf-nav:hover{background:rgba(24,24,27,.78);color:#fff}.pdf-overlay .pdf-nav:disabled{opacity:.5;background:rgba(24,24,27,.38)}.pdf-divider{flex:none;width:1px;align-self:stretch;margin:2px;background:hsla(0,0%,100%,.18)}.pdf-overlay .pdf-page-input{box-sizing:border-box;height:20px;width:44px;padding:0 5px;font-size:11px;text-align:center;font-variant-numeric:tabular-nums;background:hsla(0,0%,100%,.14);border:1px solid hsla(0,0%,100%,.22);color:#fff;border-radius:999px;font-family:inherit;outline:none;transition:background-color .12s,border-color .12s}.pdf-overlay .pdf-page-input:focus{background:hsla(0,0%,100%,.22);border-color:hsla(0,0%,100%,.45)}.pdf-status{display:flex;align-items:center;justify-content:center;gap:8px;padding:2.5rem 1rem;font-size:.875rem;color:var(--muted-foreground);text-align:center}.tiptap a{color:var(--primary);text-decoration:underline;text-underline-offset:2px}.tiptap a:hover{opacity:.8}.tiptap mark{background-color:#fef08a;border-radius:2px;padding:.05em .1em}.tiptap [data-type=details]{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;display:grid;grid-template-columns:30px 1fr;align-items:start;transition:background .12s}.tiptap [data-type=details]:hover{background:var(--muted)}.tiptap [data-type=details]>button{background:none;border:none;cursor:pointer;padding:0;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;color:var(--muted-foreground);border-radius:4px;transition:transform .2s,color .15s,background-color .15s;flex-shrink:0;margin-top:14px;margin-left:4px}.tiptap [data-type=details]>button:hover{background:color-mix(in srgb,var(--foreground) 8%,transparent)}.tiptap [data-type=details]>button:after{content:"";display:block;width:0;height:0;border-left:7px solid;border-top:5.5px solid transparent;border-bottom:5.5px solid transparent;margin-left:2px}.tiptap [data-type=details]:hover>button{color:var(--foreground)}.tiptap [data-type=details].is-open>button{transform:rotate(90deg)}.tiptap [data-type=details]>div{flex:1;min-width:0}.tiptap [data-type=details] summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 0;display:block;border-bottom:1px solid transparent;transition:border-color .15s}.tiptap [data-type=details].is-open>div>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap [data-type=details] summary[data-level="1"],.tiptap details summary[data-level="1"]{font-size:2rem;font-weight:700;line-height:1.25}.tiptap [data-type=details] summary[data-level="2"],.tiptap details summary[data-level="2"]{font-size:1.5rem;font-weight:600;line-height:1.3}.tiptap [data-type=details] summary[data-level="3"],.tiptap details summary[data-level="3"]{font-size:1.25rem;font-weight:600;line-height:1.35}.tiptap [data-type=details]:has(>div>summary[data-level="1"])>button{margin-top:19px}.tiptap [data-type=details]:has(>div>summary[data-level="2"])>button{margin-top:15px}.tiptap [data-type=details]:has(>div>summary[data-level="3"])>button{margin-top:13px}.tiptap [data-type=detailsContent]{padding:8px 8px 8px 0;border-left:none}.tiptap [data-type=detailsContent][hidden]{display:none}.tiptap details{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;transition:background .12s}.tiptap details:hover{background:var(--muted)}.tiptap details summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 26px;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-bottom:1px solid transparent;position:relative;list-style:none;transition:border-color .15s}.tiptap details[open]>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap details summary::-webkit-details-marker{display:none}.tiptap details summary::marker{content:""}.tiptap details summary:before{content:"";position:absolute;left:8px;top:50%;width:0;height:0;border-left:7px solid var(--muted-foreground);border-top:5.5px solid transparent;border-bottom:5.5px solid transparent;transform:translateY(-50%);transition:transform .2s,border-left-color .15s}.tiptap details:hover summary:before{border-left-color:var(--foreground)}.tiptap details[open]>summary:before{transform:translateY(-50%) rotate(90deg)}.tiptap details[open]>:not(summary){margin-top:8px;padding-left:26px;padding-right:8px}.tiptap table{border-collapse:collapse;margin:1em 0;table-layout:fixed;border:2px solid var(--border);max-width:100%}.tiptap .tableWrapper{overflow-x:auto;max-width:100%}.tiptap td,.tiptap th{border:1px solid var(--border);padding:.6em .8em;min-width:60px;vertical-align:middle;position:relative;box-sizing:border-box;overflow:hidden;word-break:break-word;line-height:1.5}.tiptap th{background:var(--muted);font-weight:600;text-align:left}.tiptap td{background:var(--background)}.tiptap .selectedCell:after{content:"";position:absolute;inset:0;background:var(--primary);opacity:.12;pointer-events:none;z-index:1}.tiptap .column-resize-handle{position:absolute;right:-3px;top:-1px;bottom:-1px;width:6px;background:var(--primary);opacity:0;cursor:col-resize;z-index:20;border-radius:2px;transition:opacity .15s}.tiptap table:hover .column-resize-handle{opacity:.4}.tiptap .column-resize-handle:hover{opacity:1}.tiptap.resize-cursor{cursor:col-resize}.tableWrapper{overflow-x:auto;overflow-y:hidden;margin:1em 0;max-width:100%;padding-right:4px}.tiptap table .grip-column,.tiptap table .grip-row,.tiptap table .grip-table{display:none!important}.tiptap .is-empty:before{content:attr(data-placeholder);float:left;color:var(--muted-foreground);opacity:.5;pointer-events:none;height:0}.tiptap h1.is-empty:before{font-size:2rem;font-weight:700}.tiptap h2.is-empty:before{font-size:1.5rem;font-weight:600}.tiptap h3.is-empty:before{font-size:1.25rem;font-weight:600}.ProseMirror-gapcursor{display:none;pointer-events:none;position:relative}.ProseMirror-gapcursor:after{content:"";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid var(--foreground);animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.ProseMirror-dropcursor{border-top:2px solid var(--primary);margin:-1px 0}.tiptap ::-moz-selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.tiptap ::selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.ProseMirror-noderangeselection ::-moz-selection{background:transparent}.ProseMirror-noderangeselection ::selection{background:transparent}.ProseMirror-noderangeselection *{caret-color:transparent}.ProseMirror-selectednode,.ProseMirror-selectednoderange{position:relative}.ProseMirror-selectednode:not(img):not([data-type=pdfBlock]):not([data-type=mbusVideo]):not([data-type=videoEmbed]):before,.ProseMirror-selectednoderange:not([data-type=pdfBlock]):not([data-type=mbusVideo]):not([data-type=videoEmbed]):before{content:"";position:absolute;inset:-.25rem;background-color:color-mix(in srgb,var(--primary) 10%,transparent);border:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:.5rem;pointer-events:none;z-index:-1}.tiptap[contenteditable=true] [data-type=mbusVideo].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=pdfBlock].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=videoEmbed].ProseMirror-selectednode,.tiptap[contenteditable=true] img.ProseMirror-selectednode{outline:1px solid var(--primary);outline-offset:2px;border-radius:8px}.hce-table-bubble{z-index:var(--hce-menu-z,100)}.bubble-toolbar-container{position:absolute;top:0;left:0;width:-moz-max-content;width:max-content;z-index:calc(var(--hce-menu-z, 100) + 1)}.hce-toolbar:has(.absolute)~.bubble-toolbar-container,.hce-toolbar:has(.absolute)~.hce-table-bubble{display:none}.hce-menu-surface{background-color:var(--hce-menu-surface,#333)}.hce-floating-panel{background-color:color-mix(in srgb,var(--foreground) 8%,var(--popover,var(--background,#fff)));border:1px solid color-mix(in srgb,var(--foreground) 18%,var(--border));box-shadow:0 8px 24px color-mix(in srgb,var(--foreground) 16%,transparent),0 2px 6px color-mix(in srgb,var(--foreground) 10%,transparent)}.hce-floating-plus{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;border:1px solid var(--border);background:var(--background);color:var(--muted-foreground);cursor:pointer;transition:all .15s}.hce-floating-plus:hover{color:var(--foreground);border-color:var(--foreground);background:var(--muted)}.hce-drag-handle{display:flex;align-items:center;gap:2px}.hce-drag-handle__plus{display:flex;align-items:center;justify-content:center;padding:4px;border-radius:4px;border:none;background:transparent;color:var(--muted-foreground);opacity:.5;cursor:pointer;transition:opacity .15s,background-color .15s}.hce-drag-handle__plus:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip{display:flex;align-items:center;justify-content:center;padding:2px;border-radius:4px;color:var(--muted-foreground);opacity:.5;cursor:grab;transition:opacity .15s,background-color .15s}.hce-drag-handle__grip:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip:active{cursor:grabbing}.tiptap div[data-type=columns]{display:grid;gap:16px;margin:1em 0}.tiptap div[data-type=columns][data-columns="2"]{grid-template-columns:1fr 1fr}.tiptap div[data-type=columns][data-columns="3"]{grid-template-columns:1fr 1fr 1fr}.tiptap div[data-type=column]{min-width:0;padding:4px 6px;border:1px dashed var(--border);border-radius:8px}.tiptap[contenteditable=true] div[data-type=column]:focus-within{border-color:var(--primary);border-style:solid}.tiptap div[data-type=columns].ProseMirror-selectednode{outline:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:8px}@media (max-width:640px){.tiptap div[data-type=columns]{grid-template-columns:1fr!important}}.hce-table-btn-wrap{position:relative;display:inline-flex}.hce-table-btn-tooltip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:6px;padding:4px 8px;font-size:11px;line-height:1.2;white-space:nowrap;color:#fff;background:#1e293b;border-radius:6px;pointer-events:none;opacity:0;transition:opacity .15s;z-index:60}.hce-table-btn-wrap:hover .hce-table-btn-tooltip{opacity:1}.hce-table-btn-wrap.hce-tooltip-off:hover .hce-table-btn-tooltip{opacity:0}.tiptap math-inline,math-inline.math-node{display:inline-block;vertical-align:baseline}.tiptap math-display,math-display.math-node{display:block;margin:.9em 0;text-align:center}.math-node,.tiptap .math-node{font-size:.95em}.tiptap math-inline.math-node .katex,math-inline.math-node .katex{font-size:1.0285em}.tiptap[contenteditable=true] .math-node{cursor:pointer;border-radius:4px;transition:background-color .12s}.tiptap[contenteditable=true] .math-node:hover{background-color:color-mix(in srgb,var(--primary) 10%,transparent)}.tiptap .math-node.ProseMirror-selectednode{background-color:color-mix(in srgb,var(--primary) 18%,transparent);outline:1px solid color-mix(in srgb,var(--primary) 45%,transparent)}.tiptap .math-node.empty-math .math-placeholder{font-size:.85em;padding:0 .35em;color:var(--muted-foreground);border:1px dashed var(--border);border-radius:4px}.math-node .math-error,.tiptap .math-error{color:#dc2626;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.hce-card-frame,.tiptap [data-type=card]{position:relative}.hce-card-frame{box-sizing:border-box;width:100%;margin:12px 0;padding:26px 30px;display:flex;flex-direction:column;justify-content:center;gap:12px;overflow:hidden;border:1px solid hsla(0,0%,100%,.52);border-radius:8px;box-shadow:inset 0 0 0 1px hsla(0,0%,100%,.28),0 8px 24px rgba(15,23,42,.08);overflow-wrap:anywhere;isolation:isolate}.hce-card-frame:before{content:"";position:absolute;inset:0;z-index:0;background:linear-gradient(90deg,hsla(0,0%,100%,.14),hsla(0,0%,100%,.04) 48%,rgba(15,23,42,.08));pointer-events:none}.hce-card-content{position:relative;z-index:1;box-sizing:border-box;width:100%;max-height:100%;min-height:0;padding:18px 20px;display:flex;flex-direction:column;gap:10px;overflow:hidden;border:1px solid hsla(0,0%,100%,.56);border-radius:8px;background:hsla(0,0%,100%,.82);color:#111827;box-shadow:0 14px 42px rgba(15,23,42,.12),inset 0 1px 0 hsla(0,0%,100%,.52);backdrop-filter:blur(18px) saturate(1.16);-webkit-backdrop-filter:blur(18px) saturate(1.16)}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.hce-card-content{background:hsla(0,0%,100%,.9)}}.hce-card-header{flex:0 0 auto}.hce-card-title{margin:0;font-size:1.65rem;font-weight:700;line-height:1.18;color:#111827}.hce-card-title[hidden]{display:none}.hce-card-title-input{box-sizing:border-box;width:100%;padding:8px 12px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.7);color:#111827;font:inherit;font-size:1.15rem;font-weight:700;outline:none}.hce-card-title-input:focus{border-color:var(--primary,#3382f2)}.hce-card-body{flex:1 1 auto;min-height:0;overflow:auto;font-size:1rem;line-height:1.55;color:#111827}.hce-card-body>p:first-child{margin-top:0}.hce-card-body>p:last-child{margin-bottom:0}.hce-card-bg-button{position:absolute;top:8px;right:8px;z-index:3;padding:4px 10px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.86);color:#111827;font-size:.8125rem;line-height:1.4;cursor:pointer}.hce-card-bg-button:hover{background:#fff}@media (max-width:640px){.hce-card-frame{padding:18px}.hce-card-content{padding:14px 16px}.hce-card-title{font-size:1.35rem}}.hce-active{background-color:color-mix(in srgb,var(--primary) 12%,transparent);color:var(--primary)}.hce-active:hover{background-color:color-mix(in srgb,var(--primary) 18%,transparent)}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:scale-105:hover,.hover\:scale-110:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-red-300:hover{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.hover\:opacity-90:hover{opacity:.9}.focus\:border-primary:focus{border-color:var(--primary)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--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)}
|